[PATCH v2] i2c: fsi: Create busses for all ports
Eddie James
eajames at linux.ibm.com
Fri Jun 7 07:38:29 AEST 2019
On 6/6/19 6:52 AM, Oliver O'Halloran wrote:
> Currently we only create an I2C bus for the ports listed in the
> device-tree for that master. There's no real reason for this since
> we can discover the number of ports the master supports by looking
> at the port_max field of the status register.
>
> This patch re-works the bus add logic so that we always create buses
> for each port, unless the bus is marked as unavailable in the DT. This
> is useful since it ensures that all the buses provided by the CFAM I2C
> master are accessible to debug tools.
Thanks Oliver.
Reviewed-by: Eddie James <eajames at linux.ibm.com>
>
> Cc: Eddie James <eajames at linux.vnet.ibm.com>
> Signed-off-by: Oliver O'Halloran <oohall at gmail.com>
> ---
> v2: Fixed off-by-one when calulating the number of ports.
> Compile fixes.
> ---
> drivers/i2c/busses/i2c-fsi.c | 32 +++++++++++++++++++++++++++-----
> 1 file changed, 27 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-fsi.c b/drivers/i2c/busses/i2c-fsi.c
> index 1e2be2219a60..da5eb3960def 100644
> --- a/drivers/i2c/busses/i2c-fsi.c
> +++ b/drivers/i2c/busses/i2c-fsi.c
> @@ -658,13 +658,29 @@ static const struct i2c_algorithm fsi_i2c_algorithm = {
> .functionality = fsi_i2c_functionality,
> };
>
> +static struct device_node *fsi_i2c_find_port_of_node(struct device_node *fsi,
> + int port)
> +{
> + struct device_node *np;
> + u32 port_no;
> + int rc;
> +
> + for_each_child_of_node(fsi, np) {
> + rc = of_property_read_u32(np, "reg", &port_no);
> + if (!rc && port_no == port)
> + return np;
> + }
> +
> + return NULL;
> +}
> +
> static int fsi_i2c_probe(struct device *dev)
> {
> struct fsi_i2c_master *i2c;
> struct fsi_i2c_port *port;
> struct device_node *np;
> + u32 port_no, ports, stat;
> int rc;
> - u32 port_no;
>
> i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
> if (!i2c)
> @@ -678,10 +694,16 @@ static int fsi_i2c_probe(struct device *dev)
> if (rc)
> return rc;
>
> - /* Add adapter for each i2c port of the master. */
> - for_each_available_child_of_node(dev->of_node, np) {
> - rc = of_property_read_u32(np, "reg", &port_no);
> - if (rc || port_no > USHRT_MAX)
> + rc = fsi_i2c_read_reg(i2c->fsi, I2C_FSI_STAT, &stat);
> + if (rc)
> + return rc;
> +
> + ports = FIELD_GET(I2C_STAT_MAX_PORT, stat) + 1;
> + dev_dbg(dev, "I2C master has %d ports\n", ports);
> +
> + for (port_no = 0; port_no < ports; port_no++) {
> + np = fsi_i2c_find_port_of_node(dev->of_node, port_no);
> + if (np && !of_device_is_available(np))
> continue;
>
> port = kzalloc(sizeof(*port), GFP_KERNEL);
More information about the openbmc
mailing list