From c64b23a583fb987e93528033bf6033918cbaf105 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 2 Jul 2024 21:54:47 +0200 Subject: [PATCH 1/2] i2c: Include device name in check i2c_check_addr_busy() Signed-off-by: Heiner Kallweit --- drivers/i2c/i2c-core-base.c | 50 ++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 49fdcb3eb..a6c2974b9 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -779,55 +779,67 @@ int i2c_check_7bit_addr_validity_strict(unsigned short addr) return 0; } -static int __i2c_check_addr_busy(struct device *dev, void *addrp) +static int __i2c_check_addr_busy(struct device *dev, void *data) { struct i2c_client *client = i2c_verify_client(dev); - int addr = *(int *)addrp; + struct i2c_client *cl = data; + + if (client && i2c_encode_flags_to_addr(client) == cl->addr) { + if (strcmp(client->name, cl->name)) + return -EBUSY; + else + /* + * If we find a device with the same name on the address, + * then assume we have been instantiated by other means already + */ + return -EEXIST; + } - if (client && i2c_encode_flags_to_addr(client) == addr) - return -EBUSY; return 0; } /* walk up mux tree */ -static int i2c_check_mux_parents(struct i2c_adapter *adapter, int addr) +static int i2c_check_mux_parents(struct i2c_adapter *adapter, struct i2c_client *cl) { struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter); int result; - result = device_for_each_child(&adapter->dev, &addr, - __i2c_check_addr_busy); + result = device_for_each_child(&adapter->dev, cl, __i2c_check_addr_busy); if (!result && parent) - result = i2c_check_mux_parents(parent, addr); + result = i2c_check_mux_parents(parent, cl); return result; } /* recurse down mux tree */ -static int i2c_check_mux_children(struct device *dev, void *addrp) +static int i2c_check_mux_children(struct device *dev, void *cl) { int result; if (dev->type == &i2c_adapter_type) - result = device_for_each_child(dev, addrp, - i2c_check_mux_children); + result = device_for_each_child(dev, cl, i2c_check_mux_children); else - result = __i2c_check_addr_busy(dev, addrp); + result = __i2c_check_addr_busy(dev, cl); return result; } -static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr) +static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr, const char *name) { struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter); + struct i2c_client cl = {}; int result = 0; + cl.addr = addr; + if (name) + strscpy(cl.name, name, sizeof(cl.name)); + if (parent) - result = i2c_check_mux_parents(parent, addr); + result = i2c_check_mux_parents(parent, &cl); if (!result) - result = device_for_each_child(&adapter->dev, &addr, + result = device_for_each_child(&adapter->dev, &cl, i2c_check_mux_children); return result; @@ -963,7 +975,9 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf } /* Check for address business */ - status = i2c_check_addr_busy(adap, i2c_encode_flags_to_addr(client)); + status = i2c_check_addr_busy(adap, i2c_encode_flags_to_addr(client), client->name); + if (status == -EEXIST) + goto out_err_silent; if (status) goto out_err; @@ -2444,7 +2458,7 @@ static int i2c_detect_address(struct i2c_client *temp_client, } /* Skip if already in use (7 bit, no need to encode flags) */ - if (i2c_check_addr_busy(adapter, addr)) + if (i2c_check_addr_busy(adapter, addr, NULL)) return 0; /* Make sure there is something at this address */ @@ -2559,7 +2573,7 @@ i2c_new_scanned_device(struct i2c_adapter *adap, } /* Check address availability (7 bit, no need to encode flags) */ - if (i2c_check_addr_busy(adap, addr_list[i])) { + if (i2c_check_addr_busy(adap, addr_list[i], NULL)) { dev_dbg(&adap->dev, "Address 0x%02x already in use, not probing\n", addr_list[i]); -- 2.45.2