diff options
Diffstat (limited to 'drivers/i2c/i2c-core-of.c')
-rw-r--r-- | drivers/i2c/i2c-core-of.c | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c index c405270a98b4..6cb7ad608bcd 100644 --- a/drivers/i2c/i2c-core-of.c +++ b/drivers/i2c/i2c-core-of.c | |||
@@ -22,53 +22,64 @@ | |||
22 | 22 | ||
23 | #include "i2c-core.h" | 23 | #include "i2c-core.h" |
24 | 24 | ||
25 | static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, | 25 | int of_i2c_get_board_info(struct device *dev, struct device_node *node, |
26 | struct device_node *node) | 26 | struct i2c_board_info *info) |
27 | { | 27 | { |
28 | struct i2c_client *client; | ||
29 | struct i2c_board_info info = {}; | ||
30 | struct dev_archdata dev_ad = {}; | ||
31 | u32 addr; | 28 | u32 addr; |
32 | int ret; | 29 | int ret; |
33 | 30 | ||
34 | dev_dbg(&adap->dev, "of_i2c: register %pOF\n", node); | 31 | memset(info, 0, sizeof(*info)); |
35 | 32 | ||
36 | if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { | 33 | if (of_modalias_node(node, info->type, sizeof(info->type)) < 0) { |
37 | dev_err(&adap->dev, "of_i2c: modalias failure on %pOF\n", | 34 | dev_err(dev, "of_i2c: modalias failure on %pOF\n", node); |
38 | node); | 35 | return -EINVAL; |
39 | return ERR_PTR(-EINVAL); | ||
40 | } | 36 | } |
41 | 37 | ||
42 | ret = of_property_read_u32(node, "reg", &addr); | 38 | ret = of_property_read_u32(node, "reg", &addr); |
43 | if (ret) { | 39 | if (ret) { |
44 | dev_err(&adap->dev, "of_i2c: invalid reg on %pOF\n", node); | 40 | dev_err(dev, "of_i2c: invalid reg on %pOF\n", node); |
45 | return ERR_PTR(ret); | 41 | return ret; |
46 | } | 42 | } |
47 | 43 | ||
48 | if (addr & I2C_TEN_BIT_ADDRESS) { | 44 | if (addr & I2C_TEN_BIT_ADDRESS) { |
49 | addr &= ~I2C_TEN_BIT_ADDRESS; | 45 | addr &= ~I2C_TEN_BIT_ADDRESS; |
50 | info.flags |= I2C_CLIENT_TEN; | 46 | info->flags |= I2C_CLIENT_TEN; |
51 | } | 47 | } |
52 | 48 | ||
53 | if (addr & I2C_OWN_SLAVE_ADDRESS) { | 49 | if (addr & I2C_OWN_SLAVE_ADDRESS) { |
54 | addr &= ~I2C_OWN_SLAVE_ADDRESS; | 50 | addr &= ~I2C_OWN_SLAVE_ADDRESS; |
55 | info.flags |= I2C_CLIENT_SLAVE; | 51 | info->flags |= I2C_CLIENT_SLAVE; |
56 | } | 52 | } |
57 | 53 | ||
58 | info.addr = addr; | 54 | info->addr = addr; |
59 | info.archdata = &dev_ad; | 55 | info->of_node = node; |
60 | info.of_node = of_node_get(node); | ||
61 | 56 | ||
62 | if (of_property_read_bool(node, "host-notify")) | 57 | if (of_property_read_bool(node, "host-notify")) |
63 | info.flags |= I2C_CLIENT_HOST_NOTIFY; | 58 | info->flags |= I2C_CLIENT_HOST_NOTIFY; |
64 | 59 | ||
65 | if (of_get_property(node, "wakeup-source", NULL)) | 60 | if (of_get_property(node, "wakeup-source", NULL)) |
66 | info.flags |= I2C_CLIENT_WAKE; | 61 | info->flags |= I2C_CLIENT_WAKE; |
62 | |||
63 | return 0; | ||
64 | } | ||
65 | EXPORT_SYMBOL_GPL(of_i2c_get_board_info); | ||
66 | |||
67 | static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, | ||
68 | struct device_node *node) | ||
69 | { | ||
70 | struct i2c_client *client; | ||
71 | struct i2c_board_info info; | ||
72 | int ret; | ||
73 | |||
74 | dev_dbg(&adap->dev, "of_i2c: register %pOF\n", node); | ||
75 | |||
76 | ret = of_i2c_get_board_info(&adap->dev, node, &info); | ||
77 | if (ret) | ||
78 | return ERR_PTR(ret); | ||
67 | 79 | ||
68 | client = i2c_new_device(adap, &info); | 80 | client = i2c_new_device(adap, &info); |
69 | if (!client) { | 81 | if (!client) { |
70 | dev_err(&adap->dev, "of_i2c: Failure registering %pOF\n", node); | 82 | dev_err(&adap->dev, "of_i2c: Failure registering %pOF\n", node); |
71 | of_node_put(node); | ||
72 | return ERR_PTR(-EINVAL); | 83 | return ERR_PTR(-EINVAL); |
73 | } | 84 | } |
74 | return client; | 85 | return client; |