[PATCH 3/3] i2c: implement detect callback

Ahmad Fatoum a.fatoum at pengutronix.de
Mon Jan 16 05:36:39 PST 2023


of_device_ensure_probed will call device::detect on the I2C adapter,
so it can detect its children node, in case they were not probed before.
This can happen if the nodes were added dynamically via device tree
fixup or overlay. Implement a detect callback to support this.

To keep existing behavior, we call this detect callback unconditionally
while newly registering the adapter.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 drivers/i2c/i2c.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/i2c.c b/drivers/i2c/i2c.c
index 3b5e68618dff..7e1cea49f3b6 100644
--- a/drivers/i2c/i2c.c
+++ b/drivers/i2c/i2c.c
@@ -420,10 +420,6 @@ static void of_i2c_register_devices(struct i2c_adapter *adap)
 {
 	struct device_node *n;
 
-	/* Only register child devices if the adapter has a node pointer set */
-	if (!IS_ENABLED(CONFIG_OFDEVICE) || !adap->dev.of_node)
-		return;
-
 	for_each_available_child_of_node(adap->dev.of_node, n) {
 		struct i2c_board_info info = {};
 		struct i2c_client *result;
@@ -475,6 +471,20 @@ int of_i2c_register_devices_by_node(struct device_node *node)
 	return 0;
 }
 
+static int i2c_bus_detect(struct device *dev)
+{
+	struct i2c_adapter *adap;
+
+	list_for_each_entry(adap, &i2c_adapter_list, list) {
+		if (dev != adap->dev.parent)
+			continue;
+		of_i2c_register_devices(adap);
+		break;
+	}
+
+	return 0;
+}
+
 /**
  * i2c_new_dummy - return a new i2c device bound to a dummy driver
  * @adapter: the adapter managing the device
@@ -686,6 +696,7 @@ EXPORT_SYMBOL_GPL(i2c_parse_fw_timings);
  */
 int i2c_add_numbered_adapter(struct i2c_adapter *adapter)
 {
+	struct device *hw_dev;
 	int ret;
 
 	if (adapter->nr < 0) {
@@ -712,7 +723,12 @@ int i2c_add_numbered_adapter(struct i2c_adapter *adapter)
 	/* populate children from any i2c device tables */
 	scan_boardinfo(adapter);
 
-	of_i2c_register_devices(adapter);
+	hw_dev = adapter->dev.parent;
+	if (hw_dev && dev_of_node(hw_dev)) {
+		if (!hw_dev->detect)
+			hw_dev->detect = i2c_bus_detect;
+		i2c_bus_detect(hw_dev);
+	}
 
 	return 0;
 }
-- 
2.30.2




More information about the barebox mailing list