Re: [Re-send: PATCH i2c-next 5/6] i2c: mux: mlxcpld: Extend driver to support word address space devices

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi!

Wolfram, question for you below!

On 2021-01-12 00:24, Vadim Pasternak wrote:
> Hi Peter,
> 
>> -----Original Message-----
>> From: Peter Rosin <peda@xxxxxxxxxx>
>> Sent: Monday, January 11, 2021 11:23 PM
>> To: Vadim Pasternak <vadimp@xxxxxxxxxx>; wsa@xxxxxxxxxxxxx
>> Cc: linux-i2c@xxxxxxxxxxxxxxx
>> Subject: Re: [Re-send: PATCH i2c-next 5/6] i2c: mux: mlxcpld: Extend driver to
>> support word address space devices
>>
>> Hi!
>>
>> On 2021-01-11 19:11, Vadim Pasternak wrote:
>>> Hi Peter,
>>>
>>>> -----Original Message-----
>>>> From: Peter Rosin <peda@xxxxxxxxxx>
>>>> Sent: Friday, January 08, 2021 10:02 AM
>>>> To: Vadim Pasternak <vadimp@xxxxxxxxxx>; wsa@xxxxxxxxxxxxx
>>>> Cc: linux-i2c@xxxxxxxxxxxxxxx
>>>> Subject: Re: [Re-send: PATCH i2c-next 5/6] i2c: mux: mlxcpld: Extend
>>>> driver to support word address space devices
>>>>
>>>> Hi!
>>>>
>>>> On 2021-01-07 21:43, Vadim Pasternak wrote:
>>>>> Hi Peter,
>>>>>
>>>>> Thank you very much for review.
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Peter Rosin <peda@xxxxxxxxxx>
>>>>>> Sent: Thursday, January 07, 2021 12:04 PM
>>>>>> To: Vadim Pasternak <vadimp@xxxxxxxxxx>; wsa@xxxxxxxxxxxxx
>>>>>> Cc: linux-i2c@xxxxxxxxxxxxxxx
>>>>>> Subject: Re: [Re-send: PATCH i2c-next 5/6] i2c: mux: mlxcpld:
>>>>>> Extend driver to support word address space devices
>>>>>>
>>>>>> Hi!
>>>>>>
>>>>>> Again, sorry for the late review.
>>>>>>
>>>>>> On 2020-11-18 15:44, Vadim Pasternak wrote:
>>>>>>> Extend driver to allow I2C routing control through CPLD devices
>>>>>>> with word address space. Till now only CPLD devices with byte
>>>>>>> address space have been supported.
>>>>>>>
>>>>>>> Signed-off-by: Vadim Pasternak <vadimp@xxxxxxxxxx>
>>>>>>> Reviewed-by: Michael Shych <michaelsh@xxxxxxxxxx>
>>>>>>> ---
>>>>>>>  drivers/i2c/muxes/i2c-mux-mlxcpld.c   | 57
>>>>>> +++++++++++++++++++++++++++--------
>>>>>>>  include/linux/platform_data/mlxcpld.h |  2 ++
>>>>>>>  2 files changed, 47 insertions(+), 12 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/i2c/muxes/i2c-mux-mlxcpld.c
>>>>>>> b/drivers/i2c/muxes/i2c-mux-mlxcpld.c
>>>>>>> index 6bb8caecf8e8..c76180919fc3 100644
>>>>>>> --- a/drivers/i2c/muxes/i2c-mux-mlxcpld.c
>>>>>>> +++ b/drivers/i2c/muxes/i2c-mux-mlxcpld.c
>>>>>>> @@ -21,11 +21,13 @@
>>>>>>>   * @last_chan - last register value
>>>>>>>   * @client - I2C device client
>>>>>>>   * @pdata: platform data
>>>>>>> + * @sel_buf: I2C message buffer for mux select 16 bits
>>>>>>> + transactions
>>>>>>>   */
>>>>>>>  struct mlxcpld_mux {
>>>>>>>  	u8 last_chan;
>>>>>>>  	struct i2c_client *client;
>>>>>>>  	struct mlxcpld_mux_plat_data pdata;
>>>>>>> +	u8 sel_buf[3];
>>>>>>
>>>>>> I think it's a mistake to have this buffer here. I'd rather create
>>>>>> a buffer on the stack in mlxcpld_mux_reg_write() and fill it with
>>>>>> values for
>>>> every xfer.
>>>>>> Sure, I bet there are external locks that prevent any clobbering of
>>>>>> the buffer, but it's so small that it really can be on the stack.
>>>>>>
>>>>>>>  };
>>>>>>>
>>>>>>>  /* MUX logic description.
>>>>>>> @@ -60,26 +62,42 @@ struct mlxcpld_mux {
>>>>>>>   * for this as they will try to lock adapter a second time.
>>>>>>>   */
>>>>>>>  static int mlxcpld_mux_reg_write(struct i2c_adapter *adap,
>>>>>>> -				 struct mlxcpld_mux *mux, u8 val)
>>>>>>> +				 struct mlxcpld_mux *mux, int chan)
>>>>>>>  {
>>>>>>>  	struct i2c_client *client = mux->client;
>>>>>>> -	union i2c_smbus_data data = { .byte = val };
>>>>>>> -
>>>>>>> -	return __i2c_smbus_xfer(adap, client->addr, client->flags,
>>>>>>> -				I2C_SMBUS_WRITE, mux-
>>>>>>> pdata.sel_reg_addr,
>>>>>>> -				I2C_SMBUS_BYTE_DATA, &data);
>>>>>>> +	union i2c_smbus_data data;
>>>>>>> +	struct i2c_msg msg;
>>>>>>> +
>>>>>>> +	switch (mux->pdata.reg_size) {
>>>>>>> +	case 1:
>>>>>>> +		data.byte = (chan < 0) ? 0 : chan;
>>>>>>> +		return __i2c_smbus_xfer(adap, client->addr, client->flags,
>>>>>>> +					I2C_SMBUS_WRITE,
>>>>>>> +					mux->pdata.sel_reg_addr,
>>>>>>> +					I2C_SMBUS_BYTE_DATA, &data);
>>>>>>> +	case 2:
>>>>>>> +		mux->sel_buf[mux->pdata.reg_size] = (chan < 0) ? 0 :
>>>>>>> +						    mux-
>>>>>>> pdata.adap_ids[chan];
>>>>>>
>>>>>> I get the feeling that you are desperatly trying to get some
>>>>>> specific numbering in user space.
>>>>>>
>>>>>> The adapter id is one thing.
>>>>>> The mux channel is one thing.
>>>>>> The value in the register is one thing.
>>>>>>
>>>>>> Often, it can make things easier with an easy mapping between the
>>>>>> latter two, but you program the system global I2C adapter id into
>>>>>> the channel selection register of the mux. That is problematic. Just don't.
>>>>>
>>>>> OK, I will explain what I am trying to get.
>>>>> This is not something related to the user space.
>>>>>
>>>>> I want to access some device, located on a line card, which is replaceable.
>>>>> This is for modular system, which can be equipped with the different
>>>>> type of line cards.
>>>>>
>>>>> I have mux selector register in line card CPLD, which is located at
>>>>> some offset in CPLD register space, f.e. 0x25dc. On other systems it
>>>>> could
>>>> different offset.
>>>>>
>>>>> For this line card type in pdata.adap_ids[] channels mapping looks like:
>>>>> {
>>>>> 	0x04, 0x05, 0x06, 0x07, 0x08, 0x10, 0x20, 0x21, 0x22, 0x23, 0x40, 0x41,
>>>>> 	0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d,
>>>>> 	0x4e, 0x4f
>>>>> };
>>>>> Ids from 0x01 - 0x0f are used for access to devices like  voltage
>>>>> regulators,
>>>> hotswap,
>>>>> 	EEPROMs, iio, etcetera.
>>>>> Ids from 0x10 are used for FPGAs.
>>>>> Ids from 0x20 are used for gearboxes.
>>>>> Ids from 0x40 are used for QSFP.
>>>>> On other line card type it could be different device tree, but it
>>>>> still will follow the same convention.
>>>>>
>>>>> CPLD is connected to some upper adapter at address 0x32, and device
>>>>> on line card is connected to adapter = base_nr * slot +
>> pdata.adap_ids[channel].
>>>>> For example, base_nr is 100, slot, at which line card is inserted
>>>>> is 1, channel 0 will be be configured for adapter 104.
>>>>>
>>>>> And access will be as below:
>>>>> cat /sys/bus/i2c/devices/104-0062/hwmon/hwmon5/in1_input
>>>>> 11750
>>>>>
>>>>>              cat-17623   [004] .... 1152583.810824: i2c_write: i2c-1 #0 a=032
>> f=0000
>>>> l=3 [25-dc-04]
>>>>>              cat-17623   [004] .... 1152583.811276: i2c_result: i2c-1 n=1 ret=1
>>>>>              cat-17623   [004] .... 1152583.811281: i2c_write: i2c-1 #0 a=062
>> f=0000
>>>> l=1 [88]
>>>>>              cat-17623   [004] .... 1152583.811281: i2c_read: i2c-1 #1 a=062
>> f=0001
>>>> l=2
>>>>>              cat-17623   [004] .... 1152583.811700: i2c_reply: i2c-1 #1 a=062
>> f=0001
>>>> l=2 [2f-f0]
>>>>>              cat-17623   [004] .... 1152583.811700: i2c_result: i2c-1 n=2 ret=2
>>>>>              cat-17623   [004] .... 1152583.811704: i2c_write: i2c-1 #0 a=032
>> f=0000
>>>> l=3 [25-dc-00]
>>>>>
>>>>> When the same line card is inserted for example at slot 3, the
>>>>> adapter, to which this device is connected will be 304.
>>>>
>>>> Yes, I think I get it. You are however not introducing base_nr until
>>>> 6/6, so at this point the code makes no sense. But even after 6/6
>>>> with base_nr in place, I suggest the following:
>>>>
>>>> - The adap_ids array is for forceing the system global adapter id.
>>>> Leave this variable
>>>>   alone and let it continue to do what it does, and only that. Or...
>>>> - Since you stated somewhere that there are no users of this drivers,
>>>> I'd be happy to just
>>>>   see the adap_ids variable deleted, i.e. I see no need to force the adapter
>> id.
>>>> - Instead of reusing adap_ids, intruduce a new "channel" array and
>>>> fill it with the same
>>>>   values that you provide in adap_ids, and then have the driver feed
>>>> them to the 3rd arg
>>>>   of i2c_mux_add_adapter(), i.e. chan_id.
>>>>
>>>> Would that work for you? Or do you somehow depend on predictable
>>>> adapter ids?
>>>
>>> I can drop adap_id[]s, use chan_ids[] instead and modify loop for
>>> adding Adapters like:
>>> 	for (num = 0; num < pdata->num_adaps; num++) {;
>>> 		err = i2c_mux_add_adapter(muxc, pdata->base_nr + num,
>>> 					  pdata->chan_ids[num], 0);
>>> 		if (err)
>>> 			goto virt_reg_failed;
>>> 	}
>>>
>>> In such way I can keep convention for adapters numbering for card in
>>> slot 'n', nrs will be:
>>> Form 100 * n + 1 - for voltage  regulators, hotswap, EEPROMs, iio, ...
>>> From 100 *n + 16 - for FPGAs.
>>> From 100 * n + 32 - for gearboxes.
>>> From 100 * n + 64 - for QSFP.
>>>
>>> Would it be OK?
>>
>> What convention are you talking about? What makes it interesting to force
>> specific adapter IDs? I just don't see the point. I would do
>>
>> 		err = i2c_mux_add_adapter(muxc, 0, pdata->chan_ids[num],
>> 0);
>>
>> and let the adapted ID be whatever the I2C core makes up.
>>
>> What's wrong with that?
> 
> The motivation it to provide support for new modular systems which
> could be equipped with the different types of replaceable line cards
> and management board.
> 
> The line cards could be of different types and could have different
> I2C topolgy:
> - Line cards with 16x100Gbe QSFP28 Ethernet ports.
> - Line cards with 8x200Gbe QSFP28 Ethernet ports.
> - Line cards with 4x400Gbe QSFP-DD Ethernet ports.
> - Smart cards equipped with Nvidia ARM CPU for offloading and for fast
>   access to the storage (EBoF).
> - Fabric InfiniBand cards for inter-connection.
> 
> The first version of modular system will be equipped with 8 slots.
> 
> With no enforcement, for example, it could be the next bus assignments:
> - if system is booted with empty slot number one, and with line card at slot
>   number 2, i2c devices i2c-{n1} - i2c-{n2} will be created for line card at the slot 2.
> - if system is booted with line cards at slot 1 and at slot 2, devices i2c-{n1} - i2c-{n2}
>   this time will be associated with line card at slot 1, while i2c-{n2+1} - i2c-{n2*2} will
>   be associated with line card at slot 2.
> - line cards could are removed and then re-inserted in some random order, and it'll
>   also could change bus indexes for line card inserted at the same slot.   
> 
> It'll make a big challenge for any user application, which wants to use /dev/i2c-{x}.
> 
> With enforcement I can avoid this situation.
> So, for fixed system it would be fine to have base_nr equal zero, but for modular
> I'd like to have base_nr = f(slot), f.e. 100 * slot.

My confusion stems from your response to my note "I get the feeling that you are
desperatly trying to get some specific numbering in user space", when you said:

	OK, I will explain what I am trying to get.
	This is not something related to the user space.

So, you had me confused. :-)

Wolfram, is there a better way to get something stable for user space to
interact with? Is there maybe a way to do this with aliases or something?
Setting up an ad-hoc scheme for forcing the adapter IDs feels a bit outdated.

>> Trying to force specific adapater IDs risks failure whenever any of those IDs
>> happen to be taken, and you have no way of preallocating some range the I2C
>> core should not use. The only way to do what you do is to select some high
>> enough ID range and hope for the best. But what if someone else does the
>> same thing? It's just a slippery slope. So, why?
> 
> Yes, it could happen with fixed system, but in this case I expect base_nr to be
> zero and IDs will be allocated just from free pool.
> But for modular system availability of specific IDs could be granted.

With your latest suggested code, setting base_nr to zero will not trigger
allocation from the free pool. Well, the first channel would be, but
that's ... not practical.

Cheers,
Peter

> Otherwise I'll have IDs reordering, each time when some devices are removed/
> inserted.




[Index of Archives]     [Linux GPIO]     [Linux SPI]     [Linux Hardward Monitoring]     [LM Sensors]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux