Commit 9fd049927ccba1c1d0343239b82f28c4e07fb95d
1 parent
4f0ddcb020
Exists in
master
and in
7 other branches
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>
Showing 6 changed files with 46 additions and 28 deletions Side-by-side Diff
drivers/i2c/busses/i2c-cpm.c
... | ... | @@ -652,6 +652,7 @@ |
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) { |
... | ... | @@ -679,7 +680,7 @@ |
679 | 680 | /* |
680 | 681 | * register OF I2C devices |
681 | 682 | */ |
682 | - of_register_i2c_devices(&cpm->adap, ofdev->dev.of_node); | |
683 | + of_i2c_register_devices(&cpm->adap); | |
683 | 684 | |
684 | 685 | return 0; |
685 | 686 | out_shut: |
drivers/i2c/busses/i2c-ibm_iic.c
... | ... | @@ -745,6 +745,7 @@ |
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; |
... | ... | @@ -761,7 +762,7 @@ |
761 | 762 | dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); |
762 | 763 | |
763 | 764 | /* Now register all the child nodes */ |
764 | - of_register_i2c_devices(adap, np); | |
765 | + of_i2c_register_devices(adap); | |
765 | 766 | |
766 | 767 | return 0; |
767 | 768 |
drivers/i2c/busses/i2c-mpc.c
... | ... | @@ -600,13 +600,14 @@ |
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 |
drivers/of/Kconfig
drivers/of/of_i2c.c
... | ... | @@ -14,57 +14,65 @@ |
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); | |
38 | 49 | continue; |
39 | 50 | } |
40 | 51 | |
41 | - info.irq = irq_of_parse_and_map(node, 0); | |
42 | - | |
43 | 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); | |
56 | + continue; | |
57 | + } | |
44 | 58 | |
45 | - info.of_node = node; | |
59 | + info.irq = irq_of_parse_and_map(node, 0); | |
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 | { |
include/linux/of_i2c.h
... | ... | @@ -12,13 +12,20 @@ |
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 */ |