aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/i2c-core.c
diff options
context:
space:
mode:
authorPantelis Antoniou <pantelis.antoniou@konsulko.com>2014-10-28 16:36:02 -0400
committerGrant Likely <grant.likely@linaro.org>2014-11-25 10:35:16 -0500
commita430a3455f2c48995e06b359a82a1109a419e9ef (patch)
treed35963abe215351d959090c8c8ef98b113a754c4 /drivers/i2c/i2c-core.c
parent177d271cf3171bb6826ee5189f67dc1f7d34f1da (diff)
i2c/of: Factor out Devicetree registration code
Dynamically inserting i2c client device nodes requires the use of a single device registration method. Factor out the loop body of of_i2c_register_devices() so that it can be called for individual device_nodes instead of for all the children of a node. Note: The diff of this commit looks far more complicated than it actually is due the indentation being changed for a large block of code. When viewed using the diff -w flag to ignore whitespace changes it can be seen that the change is actually quite simple. Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> [grant.likely: Made new function static and removed changes to header] Signed-off-by: Grant Likely <grant.likely@linaro.org> Reviewed-by: Wolfram Sang <wsa@the-dreams.de> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-i2c@vger.kernel.org
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r--drivers/i2c/i2c-core.c97
1 files changed, 52 insertions, 45 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index f43b4e11647a..15ba6185dba5 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -49,6 +49,7 @@
49#include <linux/acpi.h> 49#include <linux/acpi.h>
50#include <linux/jump_label.h> 50#include <linux/jump_label.h>
51#include <asm/uaccess.h> 51#include <asm/uaccess.h>
52#include <linux/err.h>
52 53
53#include "i2c-core.h" 54#include "i2c-core.h"
54 55
@@ -1368,63 +1369,69 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
1368/* OF support code */ 1369/* OF support code */
1369 1370
1370#if IS_ENABLED(CONFIG_OF) 1371#if IS_ENABLED(CONFIG_OF)
1371static void of_i2c_register_devices(struct i2c_adapter *adap) 1372static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
1373 struct device_node *node)
1372{ 1374{
1373 void *result; 1375 struct i2c_client *result;
1374 struct device_node *node; 1376 struct i2c_board_info info = {};
1377 struct dev_archdata dev_ad = {};
1378 const __be32 *addr;
1379 int len;
1375 1380
1376 /* Only register child devices if the adapter has a node pointer set */ 1381 dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
1377 if (!adap->dev.of_node)
1378 return;
1379 1382
1380 dev_dbg(&adap->dev, "of_i2c: walking child nodes\n"); 1383 if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
1384 dev_err(&adap->dev, "of_i2c: modalias failure on %s\n",
1385 node->full_name);
1386 return ERR_PTR(-EINVAL);
1387 }
1381 1388
1382 for_each_available_child_of_node(adap->dev.of_node, node) { 1389 addr = of_get_property(node, "reg", &len);
1383 struct i2c_board_info info = {}; 1390 if (!addr || (len < sizeof(int))) {
1384 struct dev_archdata dev_ad = {}; 1391 dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
1385 const __be32 *addr; 1392 node->full_name);
1386 int len; 1393 return ERR_PTR(-EINVAL);
1394 }
1387 1395
1388 dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name); 1396 info.addr = be32_to_cpup(addr);
1397 if (info.addr > (1 << 10) - 1) {
1398 dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
1399 info.addr, node->full_name);
1400 return ERR_PTR(-EINVAL);
1401 }
1389 1402
1390 if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { 1403 info.irq = irq_of_parse_and_map(node, 0);
1391 dev_err(&adap->dev, "of_i2c: modalias failure on %s\n", 1404 info.of_node = of_node_get(node);
1392 node->full_name); 1405 info.archdata = &dev_ad;
1393 continue;
1394 }
1395 1406
1396 addr = of_get_property(node, "reg", &len); 1407 if (of_get_property(node, "wakeup-source", NULL))
1397 if (!addr || (len < sizeof(int))) { 1408 info.flags |= I2C_CLIENT_WAKE;
1398 dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
1399 node->full_name);
1400 continue;
1401 }
1402 1409
1403 info.addr = be32_to_cpup(addr); 1410 request_module("%s%s", I2C_MODULE_PREFIX, info.type);
1404 if (info.addr > (1 << 10) - 1) {
1405 dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
1406 info.addr, node->full_name);
1407 continue;
1408 }
1409 1411
1410 info.irq = irq_of_parse_and_map(node, 0); 1412 result = i2c_new_device(adap, &info);
1411 info.of_node = of_node_get(node); 1413 if (result == NULL) {
1412 info.archdata = &dev_ad; 1414 dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
1415 node->full_name);
1416 of_node_put(node);
1417 irq_dispose_mapping(info.irq);
1418 return ERR_PTR(-EINVAL);
1419 }
1420 return result;
1421}
1413 1422
1414 if (of_get_property(node, "wakeup-source", NULL)) 1423static void of_i2c_register_devices(struct i2c_adapter *adap)
1415 info.flags |= I2C_CLIENT_WAKE; 1424{
1425 struct device_node *node;
1416 1426
1417 request_module("%s%s", I2C_MODULE_PREFIX, info.type); 1427 /* Only register child devices if the adapter has a node pointer set */
1428 if (!adap->dev.of_node)
1429 return;
1418 1430
1419 result = i2c_new_device(adap, &info); 1431 dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
1420 if (result == NULL) { 1432
1421 dev_err(&adap->dev, "of_i2c: Failure registering %s\n", 1433 for_each_available_child_of_node(adap->dev.of_node, node)
1422 node->full_name); 1434 of_i2c_register_device(adap, node);
1423 of_node_put(node);
1424 irq_dispose_mapping(info.irq);
1425 continue;
1426 }
1427 }
1428} 1435}
1429 1436
1430static int of_dev_node_match(struct device *dev, void *data) 1437static int of_dev_node_match(struct device *dev, void *data)