Rework OF i2c support code
Subsystems (5)
cover Rework OF i2c support code
The following series reworks the of_i2c support code so that i2c drivers can be matched to devices using the struct device_driver of_match table, and so that i2c devices described in a device tree node will be transparently registered if the i2c adapter of_node pointer is set.
The OF hooks used in the second patch are entirely compiled out when CONFIG_OF is not set.
---
Ben, these changes probably should go through my devicetree branch. They are currently sitting in the following branch, and I'll move it over to next-devicetree in a week or so if I don't receive any objections (it can always come out again if there are, but I want the test coverage).
git://git.secretlab.ca/git/linux-2.6 test-devicetree
Grant Likely (2):
of/i2c: Generalize OF support
i2c: Add OF-style registration and binding
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/of/Kconfig | 2 +- drivers/of/of_i2c.c | 44 ++++++++++++++++++++++++-------------- include/linux/of_i2c.h | 13 +++++++++-- 7 files changed, 51 insertions(+), 29 deletions(-)
PATCH 1/2 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 | 44 ++++++++++++++++++++++++-------------- include/linux/of_i2c.h | 13 +++++++++-- 6 files changed, 45 insertions(+), 23 deletions(-)
drivers/i2c/busses/i2c-cpm.c +2 -1
@@ -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
@@ -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
@@ -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
@@ -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 +28 -16
87 lines not on this page · raw message
include/linux/of_i2c.h +10 -3
@@ -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 */
Re: [PATCH 1/2] of/i2c: Generalize OF support
Hi Grant,
looks good to me in general. A few questions:
Quoted 152 lines · Grant Likely
This patch cleans up the i2c OF support code to make it selectable by all architectures and allow for automatic registration of i2c devices.
Signed-off-by Grant Likely <grant.likely-s3s/[email protected]>--- 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 | 44 ++++++++++++++++++++++++-------------- include/linux/of_i2c.h | 13 +++++++++-- 6 files changed, 45 insertions(+), 23 deletions(-)drivers/i2c/busses/i2c-cpm.c +2
-1@@ -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@@ -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@@ -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@@ -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 accessorsdrivers/of/of_i2c.c +24
-9@@ -14,34 +14,49 @@#include <linux/i2c.h> #include <linux/of.h> #include <linux/of_i2c.h> +#include <linux/of_irq.h> #include <linux/module.h> -void of_register_i2c_devices (struct i2c_adapter *adap, -struct device_node *adap_node) +void of_i2c_register_devices (struct i2c_adapter *adap) {void *result;struct device_node *node; -for_each_child_of_node (adap_node, node) { +/* Only register child devices if the adapter has a node pointer set */ +if (!adap->dev.of_node) +return ; + +dev_dbg (&adap->dev,"of_i2c: walking child nodes\n" ); + +for_each_child_of_node (adap->dev.of_node, node) {struct i2c_board_info info = {};struct dev_archdata dev_ad = {};const __be32 *addr;int len; -if (of_modalias_node (node, info.type,sizeof (info.type)) <0 ) +dev_dbg (&adap->dev,"of_i2c: register %s\n" , node->full_name); + +if (of_modalias_node (node, info.type,sizeof (info.type)) <0 ) { +dev_err (&adap->dev,"of_i2c: modalias failure on %s\n" , + node->full_name);continue ; + } addr =of_get_property (node,"reg" , &len); -if (!addr || len <sizeof (int ) || *addr > (1 <<10 ) -1 ) { -printk (KERN_ERR -"of-i2c: invalid i2c device entry\n" ); +if (!addr || (len <sizeof (int ))) { +dev_err (&adap->dev,"of_i2c: invalid reg on %s\n" , + node->full_name);continue ; } - info.irq =irq_of_parse_and_map (node,0 ); - info.addr =be32_to_cpup (addr); +if (info.addr > (1 <<10 ) -1 ) { +dev_err (&adap->dev,"of_i2c: invalid addr=%x on %s\n" , + info.addr, node->full_name); +continue ; + } + info.irq =irq_of_parse_and_map (node,0 ); info.of_node = node; info.archdata = &dev_ad;
drivers/of/of_i2c.c void of_register_i2c_devices(struct i2c_adapter *adap, · line 55
Quoted 7 lines
drivers/of/of_i2c.c +0
-4@@ -49,10 +64,8 @@ void of_register_i2c_devices(struct i2c_adapter *adap, result =i2c_new_device (adap, &info);if (result ==NULL ) { -printk (KERN_ERR -"of-i2c: Failed to load driver for %s\n" , - info.type); -irq_dispose_mapping (info.irq);
Why is the dispose removed?
Quoted 15 lines
drivers/of/of_i2c.c +3
-1+dev_err (&adap->dev,"of_i2c: Failure registering %s\n" , + node->full_name);continue ; }@@ -64,7 +77,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap,of_node_get (node); } } -EXPORT_SYMBOL (of_register_i2c_devices); +EXPORT_SYMBOL (of_i2c_register_devices);static int of_dev_node_match (struct device *dev,void *data) {
drivers/of/of_i2c.c struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) · line 92
Quoted 6 lines
drivers/of/of_i2c.c +1
-2@@ -76,8 +89,7 @@ struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) {struct device *dev; - dev =bus_find_device (&i2c_bus_type,NULL , node, - of_dev_node_match); + dev =bus_find_device (&i2c_bus_type,NULL , node, of_dev_node_match);
This change looks unrelated to me; where was this changed?
Quoted 35 lines
drivers/of/of_i2c.c +0
-0if (!dev)return NULL ;include/linux/of_i2c.h +10
-4@@ -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 */ --To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 2 lines
Pengutronix e.K. | Wolfram Sang | Industrial Linux Solutions | http://www.pengutronix.de/ |
_______________________________________________
devicetree-discuss mailing list devicetree-discuss-uLR06cmDAlY/[email protected]
https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 1/2] of/i2c: Generalize OF support
Quoted 18 lines · Wolfram Sang
Hi Grant,
looks good to me in general. A few questions:
Quoted 13 lines · Grant Likely
This patch cleans up the i2c OF support code to make it selectable by all architectures and allow for automatic registration of i2c devices.
Signed-off-by Grant Likely <grant.likely-s3s/[email protected]>---
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 | 44 ++++++++++++++++++++++++--------------include/linux/of_i2c.h| 13 +++++++++--6 files changed, 45 insertions(+), 23 deletions(-)
Hi Wolfram, thanks for the review. Replies below.
Quoted 10 lines
drivers/of/of_i2c.c void of_register_i2c_devices(struct i2c_adapter *adap, · line 55
Quoted 8 lines
drivers/of/of_i2c.c +0
-4@@ -49,10 +64,8 @@ void of_register_i2c_devices(struct i2c_adapter *adap, result = i2c_new_device(adap, &info); if (result == NULL) { - printk(KERN_ERR - "of-i2c: Failed to load driver for %s\n", - info.type); - irq_dispose_mapping(info.irq);Why is the dispose removed?
Hmmm... That looks like a mistake. I'll add it back.
Quoted 19 lines
Quoted 19 lines
drivers/of/of_i2c.c +3
-1+ dev_err(&adap->dev, "of_i2c: Failure registering %s\n", + node->full_name); continue; }@@ -64,7 +77,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap, of_node_get(node); } } -EXPORT_SYMBOL (of_register_i2c_devices); +EXPORT_SYMBOL (of_i2c_register_devices); static int of_dev_node_match(struct device *dev, void *data) {@@ -76,8 +89,7 @@ struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) { struct device *dev;
Quoted 5 lines
drivers/of/of_i2c.c struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) · line 92
Quoted 3 lines
drivers/of/of_i2c.c +1
-2- dev = bus_find_device(&i2c_bus_type, NULL, node, - of_dev_node_match); + dev = bus_find_device(&i2c_bus_type, NULL, node, of_dev_node_match);This change looks unrelated to me; where was this changed?
You're right; unrelated whitespace damage. I'll remove.
g.
PATCH 2/2 i2c: Add OF-style registration and binding
In reply to Grant LikelyThis 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
@@ -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
@@ -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
@@ -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
@@ -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,