Re: [PATCH v1] i2c: i2c-core-base: Modify the maximum idr id for i2c adapter

From: Riwen Lu
Date: Tue Jan 10 2023 - 03:41:40 EST


在 2023/1/9 23:13, Wolfram Sang 写道:
On Fri, Dec 16, 2022 at 10:07:51AM +0800, Riwen Lu wrote:
From: Riwen Lu <luriwen@xxxxxxxxxx>

Change the maximum idr ID to INT_MAX for i2c adapter.
This fix the following adding i2c adapter error while the idr with
adap->nr has been allocated by other i2c driver, and find a proper ID

How did this happen that another i2c driver could get this? Were you
able to follow the code paths that lead to this situation?

Yes, it's happened in Phytium(Arm64) platform with MWV207 GPU.

1. The MWV207 GPU driver has registered I2C adapter, and allocated idr id 0-6 with i2c_adapter_idr.

# cd /sys/class/i2c-adapter/i2c-0/
# ls
i2c-0 i2c-1 i2c-2 i2c-3 i2c-4 i2c-5 i2c-6
# cd i2c-0/
# ls
delete_device device i2c-dev name new_device power subsystem uevent
# cat name
MWV207_I2C_0

2. The BIOS's ACPI DSDT has declared I2C device with _UID 0 as following:

Device (I2C0)
{
Name (_HID, "PHYT0038") // _HID: Hardware ID
Name (_UID, Zero) // _UID: Unique ID
Name (_CRS, ResourceTemplate ()
{
Memory32Fixed (ReadWrite,
0x28014000,
0x00001000,
)
Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
{
0x0000007C,
}
})

...
}

The Phytium i2c driver would register the i2c adapter with idr id 0 by calling function i2c_add_numbered_adapter(adap). Then, function idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1, GFP_KERNEL); allocate the idr failed because idr id adap->nr(It equal to _UID) has been allocated by MWV207 GPU, and print the following error:

couldn't get idr
i2c-phytium-platform PHYT0038:00: fail to add adapter: -16

This patch can solve the problem.
for it.
[ 357.620685][ 3] [ T3655] ------------[ cut here ]------------
[ 357.626544][ 3] [ T3655] couldn't get idr

Signed-off-by: Riwen Lu <luriwen@xxxxxxxxxx>
---
drivers/i2c/i2c-core-base.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 7539b0740351..c2982861057a 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -1535,11 +1535,12 @@ static int __i2c_add_numbered_adapter(struct i2c_adapter *adap)
int id;
mutex_lock(&core_lock);
- id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1, GFP_KERNEL);
+ id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, 0, GFP_KERNEL);
mutex_unlock(&core_lock);
if (WARN(id < 0, "couldn't get idr"))
return id == -ENOSPC ? -EBUSY : id;
+ adap->nr = id;
return i2c_register_adapter(adap);
}
--
2.25.1