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

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>

authored by

Wolfram Sang and committed by
Wolfram Sang
b4e2f6ac c4019b70

+18 -5
+18 -5
drivers/i2c/i2c-core.c
··· 27 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 31 #include <linux/module.h> 31 32 #include <linux/kernel.h> 32 33 #include <linux/delay.h> ··· 1289 1288 struct i2c_client *result; 1290 1289 struct i2c_board_info info = {}; 1291 1290 struct dev_archdata dev_ad = {}; 1292 - const __be32 *addr; 1291 + const __be32 *addr_be; 1292 + u32 addr; 1293 1293 int len; 1294 1294 1295 1295 dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name); ··· 1301 1299 return ERR_PTR(-EINVAL); 1302 1300 } 1303 1301 1304 - addr = of_get_property(node, "reg", &len); 1305 - if (!addr || (len < sizeof(*addr))) { 1302 + addr_be = of_get_property(node, "reg", &len); 1303 + if (!addr_be || (len < sizeof(*addr_be))) { 1306 1304 dev_err(&adap->dev, "of_i2c: invalid reg on %s\n", 1307 1305 node->full_name); 1308 1306 return ERR_PTR(-EINVAL); 1309 1307 } 1310 1308 1311 - info.addr = be32_to_cpup(addr); 1312 - if (info.addr > (1 << 10) - 1) { 1309 + addr = be32_to_cpup(addr_be); 1310 + if (addr & I2C_TEN_BIT_ADDRESS) { 1311 + addr &= ~I2C_TEN_BIT_ADDRESS; 1312 + info.flags |= I2C_CLIENT_TEN; 1313 + } 1314 + 1315 + if (addr & I2C_OWN_SLAVE_ADDRESS) { 1316 + addr &= ~I2C_OWN_SLAVE_ADDRESS; 1317 + info.flags |= I2C_CLIENT_SLAVE; 1318 + } 1319 + 1320 + if (i2c_check_addr_validity(addr, info.flags)) { 1313 1321 dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n", 1314 1322 info.addr, node->full_name); 1315 1323 return ERR_PTR(-EINVAL); 1316 1324 } 1317 1325 1326 + info.addr = addr; 1318 1327 info.of_node = of_node_get(node); 1319 1328 info.archdata = &dev_ad; 1320 1329