Skip to contentSkip to conversation

Automatically register i2c devices from the device tree

PATCH New Grant Likely 1 participant 4 messages Jun 24, 2010

Subsystems (9)
lore
Share & tools
lore
#0 lore raw

cover Automatically register i2c devices from the device tree

The following series adds automatic registration of i2c devices from OF device tree data. If the i2c bus has the of_node pointer set, then it will use that node pointer as the parent for a set of i2c devices and automatically register the child nodes as new i2c devices.

When CONFIG_OF is not set, the of i2c hooks become empty stubs.

---

Grant Likely (3):
of/i2c: Generalize OF support
i2c: Add OF-style registration and binding
of: refactor of_modalias_node() and remove explicit match table.

 arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c |    6 ++
 drivers/i2c/busses/i2c-cpm.c                   |    6 --
 drivers/i2c/busses/i2c-ibm_iic.c               |    4 --
 drivers/i2c/busses/i2c-mpc.c                   |    2 -
 drivers/i2c/i2c-core.c                         |    9 +++
 drivers/mmc/host/mmc_spi.c                     |    8 +++
 drivers/of/Kconfig                             |    2 -
 drivers/of/base.c                              |   64 +++---------------------
 drivers/of/of_i2c.c                            |   50 +++++++++++--------
 include/linux/of_i2c.h                         |   13 ++++-
 10 files changed, 75 insertions(+), 89 deletions(-)
#1 lore raw

PATCH 1/3 of/i2c: Generalize OF support

This patch cleans up the i2c OF support code to make it selectable by all architectures and allow for automatic registration of i2c devices.

---
 drivers/i2c/busses/i2c-cpm.c     |    3 ++
 drivers/i2c/busses/i2c-ibm_iic.c |    3 ++
 drivers/i2c/busses/i2c-mpc.c     |    3 ++
 drivers/of/Kconfig               |    2 +-
 drivers/of/of_i2c.c              |   50 ++++++++++++++++++++++----------------
 include/linux/of_i2c.h           |   13 ++++++++--
 6 files changed, 46 insertions(+), 28 deletions(-)
drivers/i2c/busses/i2c-cpm.c +2 -1
index b02b453..03ae62e 100644
@@ -652,6 +652,7 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev,
 	cpm->adap = cpm_ops;
 	i2c_set_adapdata(&cpm->adap, cpm);
 	cpm->adap.dev.parent = &ofdev->dev;
+	cpm->adap.dev.of_node = of_node_get(ofdev->dev.of_node);
 
 	result = cpm_i2c_setup(cpm);
 	if (result) {
@@ -679,7 +680,7 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev,
 	/*
 	 * register OF I2C devices
 	 */
-	of_register_i2c_devices(&cpm->adap, ofdev->dev.of_node);
+	of_i2c_register_devices(&cpm->adap);
 
 	return 0;
 out_shut:
drivers/i2c/busses/i2c-ibm_iic.c +2 -1
index bf34413..d964121 100644
@@ -745,6 +745,7 @@ static int __devinit iic_probe(struct of_device *ofdev,
 	/* Register it with i2c layer */
 	adap = &dev->adap;
 	adap->dev.parent = &ofdev->dev;
+	adap->dev.of_node = of_node_get(np);
 	strlcpy(adap->name, "IBM IIC", sizeof(adap->name));
 	i2c_set_adapdata(adap, dev);
 	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
@@ -761,7 +762,7 @@ static int __devinit iic_probe(struct of_device *ofdev,
 		 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
 
 	/* Now register all the child nodes */
-	of_register_i2c_devices(adap, np);
+	of_i2c_register_devices(adap);
 
 	return 0;
 
drivers/i2c/busses/i2c-mpc.c +2 -1
index df00eb1..d2e26d2 100644
@@ -600,13 +600,14 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
 	i2c->adap = mpc_ops;
 	i2c_set_adapdata(&i2c->adap, i2c);
 	i2c->adap.dev.parent = &op->dev;
+	i2c->adap.dev.of_node = of_node_get(op->dev.of_node);
 
 	result = i2c_add_adapter(&i2c->adap);
 	if (result < 0) {
 		dev_err(i2c->dev, "failed to add adapter\n");
 		goto fail_add;
 	}
-	of_register_i2c_devices(&i2c->adap, op->dev.of_node);
+	of_i2c_register_devices(&i2c->adap);
 
 	return result;
 
drivers/of/Kconfig +1 -1
index 097f42a..80dd631 100644
@@ -26,7 +26,7 @@ config OF_GPIO
 
 config OF_I2C
 	def_tristate I2C
-	depends on (PPC_OF || MICROBLAZE) && I2C
+	depends on OF && !SPARC && I2C
 	help
 	  OpenFirmware I2C accessors
 
drivers/of/of_i2c.c +29 -21

86 lines not on this page · raw message

include/linux/of_i2c.h +10 -3
index 34974b5..0efe8d4 100644
@@ -12,12 +12,19 @@
 #ifndef __LINUX_OF_I2C_H
 #define __LINUX_OF_I2C_H
 
+#if defined(CONFIG_OF_I2C) || defined(CONFIG_OF_I2C_MODULE)
 #include <linux/i2c.h>
 
-void of_register_i2c_devices(struct i2c_adapter *adap,
-			     struct device_node *adap_node);
+extern void of_i2c_register_devices(struct i2c_adapter *adap);
 
 /* must call put_device() when done with returned i2c_client device */
-struct i2c_client *of_find_i2c_device_by_node(struct device_node *node);
+extern struct i2c_client *of_find_i2c_device_by_node(struct device_node *node);
+
+#else
+static inline void of_i2c_register_devices(struct i2c_adapter *adap)
+{
+	return;
+}
+#endif /* CONFIG_OF_I2C */
 
 #endif /* __LINUX_OF_I2C_H */
#2 lore raw

PATCH 2/3 i2c: Add OF-style registration and binding

In reply to Grant Likely

This patch adds OF hooks to the i2c core so that devices can automatically be registered based on device tree data.

---
 drivers/i2c/busses/i2c-cpm.c     |    5 -----
 drivers/i2c/busses/i2c-ibm_iic.c |    3 ---
 drivers/i2c/busses/i2c-mpc.c     |    1 -
 drivers/i2c/i2c-core.c           |    9 +++++++++
 4 files changed, 9 insertions(+), 9 deletions(-)
drivers/i2c/busses/i2c-cpm.c +0 -5
index 03ae62e..e591de1 100644
@@ -677,11 +677,6 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev,
 	dev_dbg(&ofdev->dev, "hw routines for %s registered.\n",
 		cpm->adap.name);
 
-	/*
-	 * register OF I2C devices
-	 */
-	of_i2c_register_devices(&cpm->adap);
-
 	return 0;
 out_shut:
 	cpm_i2c_shutdown(cpm);
drivers/i2c/busses/i2c-ibm_iic.c +0 -3
index d964121..1168d61 100644
@@ -761,9 +761,6 @@ static int __devinit iic_probe(struct of_device *ofdev,
 	dev_info(&ofdev->dev, "using %s mode\n",
 		 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
 
-	/* Now register all the child nodes */
-	of_i2c_register_devices(adap);
-
 	return 0;
 
 error_cleanup:
drivers/i2c/busses/i2c-mpc.c +0 -1
index d2e26d2..9f7fef8 100644
@@ -607,7 +607,6 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
 		dev_err(i2c->dev, "failed to add adapter\n");
 		goto fail_add;
 	}
-	of_i2c_register_devices(&i2c->adap);
 
 	return result;
 
drivers/i2c/i2c-core.c +9 -0
index 1cca263..5588ac1 100644
@@ -30,6 +30,8 @@
 #include <linux/init.h>
 #include <linux/idr.h>
 #include <linux/mutex.h>
+#include <linux/of_i2c.h>
+#include <linux/of_device.h>
 #include <linux/completion.h>
 #include <linux/hardirq.h>
 #include <linux/irqflags.h>
@@ -70,6 +72,10 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
 	if (!client)
 		return 0;
 
+	/* Attempt an OF style match */
+	if (of_driver_match_device(dev, drv))
+		return 1;
+
 	driver = to_i2c_driver(drv);
 	/* match on an id table if there is one */
 	if (driver->id_table)
@@ -790,6 +796,9 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
 	if (adap->nr < __i2c_first_dynamic_bus_num)
 		i2c_scan_static_board_info(adap);
 
+	/* Register devices from the device tree */
+	of_i2c_register_devices(adap);
+
 	/* Notify drivers */
 	mutex_lock(&core_lock);
 	dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap,
#3 lore raw

PATCH 3/3 of: refactor of_modalias_node() and remove explicit match table.

In reply to Grant Likely

This patch tightens up the behaviour of of_modalias_node() to be more predicatable and to eliminate the explicit of_modalias_tablep[] that is currently used to override the first entry in the compatible list of a device. The override table was needed originally because spi and i2c drivers had no way to do of-style matching. Now that all devices can have an of_node pointer, and all drivers can have an of_match_table, the explicit override table is no longer needed because each driver can specify its own OF-style match data.

The mpc8349emitx-mcu driver is modified to explicitly specify the correct device to bind against.

---
 arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c |    6 ++
 drivers/mmc/host/mmc_spi.c                     |    8 +++
 drivers/of/base.c                              |   64 +++---------------------
 3 files changed, 23 insertions(+), 55 deletions(-)
arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +6 -0
index 59b0ed1..70798ac 100644
@@ -160,10 +160,16 @@ static const struct i2c_device_id mcu_ids[] = {
 };
 MODULE_DEVICE_TABLE(i2c, mcu_ids);
 
+static struct of_device_id mcu_of_match_table[] __devinitdata = {
+	{ .compatible = "fsl,mcu-mpc8349emitx", },
+	{ },
+};
+
 static struct i2c_driver mcu_driver = {
 	.driver = {
 		.name = "mcu-mpc8349emitx",
 		.owner = THIS_MODULE,
+		.of_match_table = mcu_of_match_table,
 	},
 	.probe = mcu_probe,
 	.remove	= __devexit_p(mcu_remove),
drivers/mmc/host/mmc_spi.c +8 -0
index ad847a2..7b0f3ef 100644
@@ -1533,12 +1533,20 @@ static int __devexit mmc_spi_remove(struct spi_device *spi)
 	return 0;
 }
 
+#if defined(CONFIG_OF)
+static struct of_device_id mmc_spi_of_match_table[] __devinitdata = {
+	{ .compatible = "mmc-spi-slot", },
+};
+#endif
 
 static struct spi_driver mmc_spi_driver = {
 	.driver = {
 		.name =		"mmc_spi",
 		.bus =		&spi_bus_type,
 		.owner =	THIS_MODULE,
+#if defined(CONFIG_OF)
+		.of_match_table = mmc_spi_of_match_table,
+#endif
 	},
 	.probe =	mmc_spi_probe,
 	.remove =	__devexit_p(mmc_spi_remove),
drivers/of/base.c +9 -55

83 lines not on this page · raw message