aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/of_i2c.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-05 18:57:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-05 18:57:35 -0400
commit03c0c29aff7e56b722eb6c47eace222b140d0377 (patch)
tree47267a19b523159cf36a050ef3c35f4dbdb33016 /drivers/of/of_i2c.c
parentc60c6a96b7bb0f1f8bb635fdfcf5b592aaf062b4 (diff)
parent7fb8f881c54beb05dd4d2c947dada1c636581d87 (diff)
Merge branch 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6
* 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6: (63 commits) of/platform: Register of_platform_drivers with an "of:" prefix of/address: Clean up function declarations of/spi: call of_register_spi_devices() from spi core code of: Provide default of_node_to_nid() implementation. of/device: Make of_device_make_bus_id() usable by other code. of/irq: Fix endian issues in parsing interrupt specifiers of: Fix phandle endian issues of/flattree: fix of_flat_dt_is_compatible() to match the full compatible string of: remove of_default_bus_ids of: make of_find_device_by_node generic microblaze: remove references to of_device and to_of_device sparc: remove references to of_device and to_of_device powerpc: remove references to of_device and to_of_device of/device: Replace of_device with platform_device in includes and core code of/device: Protect against binding of_platform_drivers to non-OF devices of: remove asm/of_device.h of: remove asm/of_platform.h of/platform: remove all of_bus_type and of_platform_bus_type references of: Merge of_platform_bus_type with platform_bus_type drivercore/of: Add OF style matching to platform bus ... Fix up trivial conflicts in arch/microblaze/kernel/Makefile due to just some obj-y removals by the devicetree branch, while the microblaze updates added a new file.
Diffstat (limited to 'drivers/of/of_i2c.c')
-rw-r--r--drivers/of/of_i2c.c50
1 files changed, 29 insertions, 21 deletions
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
index ab6522c8e4fe..0a694debd226 100644
--- a/drivers/of/of_i2c.c
+++ b/drivers/of/of_i2c.c
@@ -14,57 +14,65 @@
14#include <linux/i2c.h> 14#include <linux/i2c.h>
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/of_i2c.h> 16#include <linux/of_i2c.h>
17#include <linux/of_irq.h>
17#include <linux/module.h> 18#include <linux/module.h>
18 19
19void of_register_i2c_devices(struct i2c_adapter *adap, 20void of_i2c_register_devices(struct i2c_adapter *adap)
20 struct device_node *adap_node)
21{ 21{
22 void *result; 22 void *result;
23 struct device_node *node; 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 struct i2c_board_info info = {}; 32 struct i2c_board_info info = {};
27 struct dev_archdata dev_ad = {}; 33 struct dev_archdata dev_ad = {};
28 const __be32 *addr; 34 const __be32 *addr;
29 int len; 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 continue; 42 continue;
43 }
33 44
34 addr = of_get_property(node, "reg", &len); 45 addr = of_get_property(node, "reg", &len);
35 if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) { 46 if (!addr || (len < sizeof(int))) {
36 printk(KERN_ERR 47 dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
37 "of-i2c: invalid i2c device entry\n"); 48 node->full_name);
38 continue; 49 continue;
39 } 50 }
40 51
41 info.irq = irq_of_parse_and_map(node, 0);
42
43 info.addr = be32_to_cpup(addr); 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 info.archdata = &dev_ad; 61 info.archdata = &dev_ad;
47 62
48 request_module("%s", info.type); 63 request_module("%s", info.type);
49 64
50 result = i2c_new_device(adap, &info); 65 result = i2c_new_device(adap, &info);
51 if (result == NULL) { 66 if (result == NULL) {
52 printk(KERN_ERR 67 dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
53 "of-i2c: Failed to load driver for %s\n", 68 node->full_name);
54 info.type); 69 of_node_put(node);
55 irq_dispose_mapping(info.irq); 70 irq_dispose_mapping(info.irq);
56 continue; 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}
67EXPORT_SYMBOL(of_register_i2c_devices); 75EXPORT_SYMBOL(of_i2c_register_devices);
68 76
69static int of_dev_node_match(struct device *dev, void *data) 77static int of_dev_node_match(struct device *dev, void *data)
70{ 78{