Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>

+47 -29
+2 -1
drivers/i2c/busses/i2c-cpm.c
··· 652 652 cpm->adap = cpm_ops; 653 653 i2c_set_adapdata(&cpm->adap, cpm); 654 654 cpm->adap.dev.parent = &ofdev->dev; 655 + cpm->adap.dev.of_node = of_node_get(ofdev->dev.of_node); 655 656 656 657 result = cpm_i2c_setup(cpm); 657 658 if (result) { ··· 680 679 /* 681 680 * register OF I2C devices 682 681 */ 683 - of_register_i2c_devices(&cpm->adap, ofdev->dev.of_node); 682 + of_i2c_register_devices(&cpm->adap); 684 683 685 684 return 0; 686 685 out_shut:
+2 -1
drivers/i2c/busses/i2c-ibm_iic.c
··· 745 745 /* Register it with i2c layer */ 746 746 adap = &dev->adap; 747 747 adap->dev.parent = &ofdev->dev; 748 + adap->dev.of_node = of_node_get(np); 748 749 strlcpy(adap->name, "IBM IIC", sizeof(adap->name)); 749 750 i2c_set_adapdata(adap, dev); 750 751 adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; ··· 762 761 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); 763 762 764 763 /* Now register all the child nodes */ 765 - of_register_i2c_devices(adap, np); 764 + of_i2c_register_devices(adap); 766 765 767 766 return 0; 768 767
+2 -1
drivers/i2c/busses/i2c-mpc.c
··· 600 600 i2c->adap = mpc_ops; 601 601 i2c_set_adapdata(&i2c->adap, i2c); 602 602 i2c->adap.dev.parent = &op->dev; 603 + i2c->adap.dev.of_node = of_node_get(op->dev.of_node); 603 604 604 605 result = i2c_add_adapter(&i2c->adap); 605 606 if (result < 0) { 606 607 dev_err(i2c->dev, "failed to add adapter\n"); 607 608 goto fail_add; 608 609 } 609 - of_register_i2c_devices(&i2c->adap, op->dev.of_node); 610 + of_i2c_register_devices(&i2c->adap); 610 611 611 612 return result; 612 613
+1 -1
drivers/of/Kconfig
··· 26 26 27 27 config OF_I2C 28 28 def_tristate I2C 29 - depends on (PPC_OF || MICROBLAZE) && I2C 29 + depends on OF && !SPARC && I2C 30 30 help 31 31 OpenFirmware I2C accessors 32 32
+30 -22
drivers/of/of_i2c.c
··· 14 14 #include <linux/i2c.h> 15 15 #include <linux/of.h> 16 16 #include <linux/of_i2c.h> 17 + #include <linux/of_irq.h> 17 18 #include <linux/module.h> 18 19 19 - void of_register_i2c_devices(struct i2c_adapter *adap, 20 - struct device_node *adap_node) 20 + void of_i2c_register_devices(struct i2c_adapter *adap) 21 21 { 22 22 void *result; 23 23 struct device_node *node; 24 24 25 - for_each_child_of_node(adap_node, node) { 25 + /* Only register child devices if the adapter has a node pointer set */ 26 + if (!adap->dev.of_node) 27 + return; 28 + 29 + dev_dbg(&adap->dev, "of_i2c: walking child nodes\n"); 30 + 31 + for_each_child_of_node(adap->dev.of_node, node) { 26 32 struct i2c_board_info info = {}; 27 33 struct dev_archdata dev_ad = {}; 28 34 const __be32 *addr; 29 35 int len; 30 36 31 - if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) 37 + dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name); 38 + 39 + if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { 40 + dev_err(&adap->dev, "of_i2c: modalias failure on %s\n", 41 + node->full_name); 32 42 continue; 43 + } 33 44 34 45 addr = of_get_property(node, "reg", &len); 35 - if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) { 36 - printk(KERN_ERR 37 - "of-i2c: invalid i2c device entry\n"); 46 + if (!addr || (len < sizeof(int))) { 47 + dev_err(&adap->dev, "of_i2c: invalid reg on %s\n", 48 + node->full_name); 49 + continue; 50 + } 51 + 52 + info.addr = be32_to_cpup(addr); 53 + if (info.addr > (1 << 10) - 1) { 54 + dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n", 55 + info.addr, node->full_name); 38 56 continue; 39 57 } 40 58 41 59 info.irq = irq_of_parse_and_map(node, 0); 42 - 43 - info.addr = be32_to_cpup(addr); 44 - 45 - info.of_node = node; 60 + info.of_node = of_node_get(node); 46 61 info.archdata = &dev_ad; 47 62 48 63 request_module("%s", info.type); 49 64 50 65 result = i2c_new_device(adap, &info); 51 66 if (result == NULL) { 52 - printk(KERN_ERR 53 - "of-i2c: Failed to load driver for %s\n", 54 - info.type); 67 + dev_err(&adap->dev, "of_i2c: Failure registering %s\n", 68 + node->full_name); 69 + of_node_put(node); 55 70 irq_dispose_mapping(info.irq); 56 71 continue; 57 72 } 58 - 59 - /* 60 - * Get the node to not lose the dev_archdata->of_node. 61 - * Currently there is no way to put it back, as well as no 62 - * of_unregister_i2c_devices() call. 63 - */ 64 - of_node_get(node); 65 73 } 66 74 } 67 - EXPORT_SYMBOL(of_register_i2c_devices); 75 + EXPORT_SYMBOL(of_i2c_register_devices); 68 76 69 77 static int of_dev_node_match(struct device *dev, void *data) 70 78 {
+10 -3
include/linux/of_i2c.h
··· 12 12 #ifndef __LINUX_OF_I2C_H 13 13 #define __LINUX_OF_I2C_H 14 14 15 + #if defined(CONFIG_OF_I2C) || defined(CONFIG_OF_I2C_MODULE) 15 16 #include <linux/i2c.h> 16 17 17 - void of_register_i2c_devices(struct i2c_adapter *adap, 18 - struct device_node *adap_node); 18 + extern void of_i2c_register_devices(struct i2c_adapter *adap); 19 19 20 20 /* must call put_device() when done with returned i2c_client device */ 21 - struct i2c_client *of_find_i2c_device_by_node(struct device_node *node); 21 + extern struct i2c_client *of_find_i2c_device_by_node(struct device_node *node); 22 + 23 + #else 24 + static inline void of_i2c_register_devices(struct i2c_adapter *adap) 25 + { 26 + return; 27 + } 28 + #endif /* CONFIG_OF_I2C */ 22 29 23 30 #endif /* __LINUX_OF_I2C_H */