aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/i2c-core.c
diff options
context:
space:
mode:
authorWolfram Sang <wsa+renesas@sang-engineering.com>2015-05-19 15:04:40 -0400
committerWolfram Sang <wsa@the-dreams.de>2015-08-24 08:05:14 -0400
commitb4e2f6ac1281cd3e066919cc762eef4924e9fcc5 (patch)
tree206dacd75e61cebc7c5e0e91b4de73b4e656ce84 /drivers/i2c/i2c-core.c
parentc4019b7040eaf88f440ce5212e055a4f19b1b541 (diff)
i2c: apply DT flags when probing
Check for slave and 10-bit flags when probing and mark the client when found. Improve the address validity check, too Tested-by: Andrey Danin <danindrey@mail.ru> Acked-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r--drivers/i2c/i2c-core.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 4ffe06451081..7b18f31bf6c6 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -27,6 +27,7 @@
27 I2C slave support (c) 2014 by Wolfram Sang <wsa@sang-engineering.com> 27 I2C slave support (c) 2014 by Wolfram Sang <wsa@sang-engineering.com>
28 */ 28 */
29 29
30#include <dt-bindings/i2c/i2c.h>
30#include <linux/module.h> 31#include <linux/module.h>
31#include <linux/kernel.h> 32#include <linux/kernel.h>
32#include <linux/delay.h> 33#include <linux/delay.h>
@@ -1288,7 +1289,8 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
1288 struct i2c_client *result; 1289 struct i2c_client *result;
1289 struct i2c_board_info info = {}; 1290 struct i2c_board_info info = {};
1290 struct dev_archdata dev_ad = {}; 1291 struct dev_archdata dev_ad = {};
1291 const __be32 *addr; 1292 const __be32 *addr_be;
1293 u32 addr;
1292 int len; 1294 int len;
1293 1295
1294 dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name); 1296 dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
@@ -1299,20 +1301,31 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
1299 return ERR_PTR(-EINVAL); 1301 return ERR_PTR(-EINVAL);
1300 } 1302 }
1301 1303
1302 addr = of_get_property(node, "reg", &len); 1304 addr_be = of_get_property(node, "reg", &len);
1303 if (!addr || (len < sizeof(*addr))) { 1305 if (!addr_be || (len < sizeof(*addr_be))) {
1304 dev_err(&adap->dev, "of_i2c: invalid reg on %s\n", 1306 dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
1305 node->full_name); 1307 node->full_name);
1306 return ERR_PTR(-EINVAL); 1308 return ERR_PTR(-EINVAL);
1307 } 1309 }
1308 1310
1309 info.addr = be32_to_cpup(addr); 1311 addr = be32_to_cpup(addr_be);
1310 if (info.addr > (1 << 10) - 1) { 1312 if (addr & I2C_TEN_BIT_ADDRESS) {
1313 addr &= ~I2C_TEN_BIT_ADDRESS;
1314 info.flags |= I2C_CLIENT_TEN;
1315 }
1316
1317 if (addr & I2C_OWN_SLAVE_ADDRESS) {
1318 addr &= ~I2C_OWN_SLAVE_ADDRESS;
1319 info.flags |= I2C_CLIENT_SLAVE;
1320 }
1321
1322 if (i2c_check_addr_validity(addr, info.flags)) {
1311 dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n", 1323 dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
1312 info.addr, node->full_name); 1324 info.addr, node->full_name);
1313 return ERR_PTR(-EINVAL); 1325 return ERR_PTR(-EINVAL);
1314 } 1326 }
1315 1327
1328 info.addr = addr;
1316 info.of_node = of_node_get(node); 1329 info.of_node = of_node_get(node);
1317 info.archdata = &dev_ad; 1330 info.archdata = &dev_ad;
1318 1331