[PATCH linux dev-4.7] drivers: fsi: i2c: Fixup probe to allow multiple engines

Christopher Bostic cbostic at linux.vnet.ibm.com
Fri Feb 24 01:30:04 AEDT 2017


Looks good.


Reviewed-by: Christopher Bostic <cbostic at linux.vnet.ibm.com>


On 2/22/17 10:06 PM, Joel Stanley wrote:
> On Thu, Feb 23, 2017 at 10:32 AM, Eddie James
> <eajames at linux.vnet.ibm.com> wrote:
>> From: "Edward A. James" <eajames at us.ibm.com>
>>
>> Getting duplicate sysfs when probe a second I2C engine off second proc.
>> So use ida API to get unique bus numbers. Also change sysfs interface:
>> /dev/i2cfsi00 -> /dev/i2cfsi1.00
>>
>> Signed-off-by: Edward A. James <eajames at us.ibm.com>
> Acked-by: Joel Stanley <joel at jms.id.au>
>
> Will merge once Chris has taken a look.
>
> Cheers,
>
> Joel
>
>> ---
>>   drivers/fsi/i2c/iic-fsi.c  | 21 ++++++++++++++++-----
>>   drivers/fsi/i2c/iic-int.h  |  4 +++-
>>   drivers/fsi/i2c/iic-mstr.c |  3 ++-
>>   3 files changed, 21 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/fsi/i2c/iic-fsi.c b/drivers/fsi/i2c/iic-fsi.c
>> index 6ae411f..1f85e91 100644
>> --- a/drivers/fsi/i2c/iic-fsi.c
>> +++ b/drivers/fsi/i2c/iic-fsi.c
>> @@ -19,6 +19,7 @@
>>   /*
>>    * This file contains the architecture independent IIC FSI code.
>>    */
>> +#include <linux/idr.h>
>>   #include <linux/init.h>
>>   #include <linux/module.h>
>>   #include <linux/kernel.h>
>> @@ -36,7 +37,10 @@
>>   struct class* iic_fsi_class = 0;
>>   dev_t iic_devnum_start = 0;
>>
>> -static const char iic_fsi_version[] = "3.1";
>> +static const char iic_fsi_version[] = "3.2";
>> +
>> +static DEFINE_IDA(iic_ida);
>> +static DEFINE_IDA(iic_port_ida);
>>
>>   int iic_fsi_probe(struct device *dev);
>>   int iic_fsi_remove(struct device *dev);
>> @@ -185,7 +189,7 @@ int iic_add_ports(iic_eng_t* eng, uint64_t ports)
>>          int bus_num = 0;
>>          unsigned long flags;
>>          iic_bus_t* new_bus = 0;
>> -       int minor = 0;
>> +       int minor;
>>          char name[64];
>>          int rc = 0;
>>
>> @@ -202,6 +206,7 @@ int iic_add_ports(iic_eng_t* eng, uint64_t ports)
>>                  if(!(ports_left & 0x1))
>>                          continue;
>>
>> +               minor = ida_simple_get(&iic_port_ida, 0, INT_MAX, GFP_KERNEL);
>>
>>                  if( minor < 0 ) {
>>                          IFLDe(1, "bb_get_minor %d", minor);
>> @@ -209,7 +214,7 @@ int iic_add_ports(iic_eng_t* eng, uint64_t ports)
>>                          goto exit;
>>                  }
>>
>> -               sprintf(name, "i2cfsi%02d", bus_num);
>> +               sprintf(name, "i2cfsi%d.%02d", eng->idx, bus_num);
>>
>>                  /* results in hotplug event for each master bus */
>>                  new_bus = iic_create_bus(iic_fsi_class, eng,
>> @@ -219,6 +224,7 @@ int iic_add_ports(iic_eng_t* eng, uint64_t ports)
>>                  {
>>                          IFLDe(1, "iic_create_bus failed on eng %d", eng->id);
>>                          rc = -ENODEV;
>> +                       ida_simple_remove(&iic_port_ida, minor);
>>                          goto exit;
>>                  }
>>
>> @@ -235,6 +241,7 @@ int iic_add_ports(iic_eng_t* eng, uint64_t ports)
>>                           */
>>                          rc = -ENODEV;
>>                          iic_delete_bus(iic_fsi_class, new_bus);
>> +                       ida_simple_remove(&iic_port_ida, minor);
>>                          spin_unlock_irqrestore(&eng->lock, flags);
>>                          goto exit;
>>                  }
>> @@ -245,8 +252,6 @@ int iic_add_ports(iic_eng_t* eng, uint64_t ports)
>>                          eng->enabled |= 0x1ULL << bus_num;
>>                  }
>>                  spin_unlock_irqrestore(&eng->lock, flags);
>> -
>> -               minor++;
>>          }
>>
>>   exit:
>> @@ -282,6 +287,7 @@ int iic_del_ports(iic_eng_t* eng, uint64_t ports)
>>                          /* found a match, remove it */
>>                          *p_abusp = abusp->next;
>>                          eng->enabled &= ~(0x1ULL << abusp->port);
>> +                       ida_simple_remove(&iic_port_ida, abusp->idx);
>>                          iic_delete_bus(iic_fsi_class, abusp);
>>                  }
>>                  else
>> @@ -326,6 +332,7 @@ int iic_fsi_probe(struct device *dev)
>>          iic_init_eng(eng);
>>          set_bit(IIC_ENG_BLOCK, &eng->flags); //block until resumed
>>          eng->id = 0x00F5112C;
>> +       eng->idx = ida_simple_get(&iic_ida, 1, INT_MAX, GFP_KERNEL);
>>          IFLDi(1, "PROBE    eng[%08x]\n", eng->id);
>>          eng->ra = &fsi_reg_access;
>>          IFLDd(1, "vaddr=%#08lx\n", eng->base);
>> @@ -367,6 +374,9 @@ error:
>>                  iic_del_ports(eng, new_ports);
>>                  if(eng)
>>                  {
>> +                       if (eng->idx > 0)
>> +                               ida_simple_remove(&iic_ida, eng->idx);
>> +
>>                          kfree(eng);
>>                  }
>>          }
>> @@ -409,6 +419,7 @@ int iic_fsi_remove(struct device* dev)
>>          /* Clean up device files immediately, don't wait for ref count */
>>          iic_del_ports(eng, IIC_FSI_PORTS);
>>          /* cleans up engine and bus structures if ref count is zero */
>> +       ida_simple_remove(&iic_ida, eng->idx);
>>          kfree(eng);
>>
>>   error:
>> diff --git a/drivers/fsi/i2c/iic-int.h b/drivers/fsi/i2c/iic-int.h
>> index 65b336f..26ea7eb 100644
>> --- a/drivers/fsi/i2c/iic-int.h
>> +++ b/drivers/fsi/i2c/iic-int.h
>> @@ -253,12 +253,14 @@ struct iic_eng
>>       unsigned long trace_sz;            //number of trace entries
>>       atomic_t xfr_num;                  //index to current trace entry
>>       uint64_t enabled;
>> +    int idx;                           // ida number
>>   };
>>
>>   struct iic_bus
>>   {
>>       unsigned char port;                        //the port number of this bus
>>       unsigned long bus_id;              //Unique ID for this bus
>> +    int idx;                           // ida number
>>       struct cdev cdev;
>>       struct device* class_dev;
>>       dev_t devnum;
>> @@ -312,7 +314,7 @@ int iic_eng_ops_is_vaild(struct iic_eng_ops *ops);
>>   iic_bus_t*  iic_create_bus(struct class* classp, iic_eng_t* eng,
>>                                             dev_t devnum, char* name,
>>                                             unsigned char port,
>> -                                          unsigned long bus_id);
>> +                                          int bus_id);
>>   void iic_delete_bus(struct class* classp, iic_bus_t* bus);
>>   void iic_register_bus(iic_bus_t * bus, unsigned long type);
>>   void iic_unregister_bus(iic_bus_t * bus, unsigned long type);
>> diff --git a/drivers/fsi/i2c/iic-mstr.c b/drivers/fsi/i2c/iic-mstr.c
>> index a12cf7fc..f968c20 100644
>> --- a/drivers/fsi/i2c/iic-mstr.c
>> +++ b/drivers/fsi/i2c/iic-mstr.c
>> @@ -2114,7 +2114,7 @@ void iic_ffdc_q_unlocked(int scope, void* data)
>>   #define IIC_BUS_MAX_FFDC 4
>>   iic_bus_t*  iic_create_bus(struct class* classp, iic_eng_t* eng,
>>                             dev_t devnum, char* name, unsigned char port,
>> -                          unsigned long bus_id)
>> +                          int bus_id)
>>   {
>>          int rc = 0;
>>          iic_bus_t* bus = 0;
>> @@ -2133,6 +2133,7 @@ iic_bus_t*  iic_create_bus(struct class* classp, iic_eng_t* eng,
>>          memset(bus, 0, sizeof(iic_bus_t));
>>          bus->port = port;
>>          bus->bus_id = bus_id;
>> +       bus->idx = bus_id;
>>          bus->eng = eng;
>>          bus->devnum = devnum;
>>          bus->i2c_hz = 400000;
>> --
>> 1.8.3.1
>>



More information about the openbmc mailing list