diff options
author | Pantelis Antoniou <pantelis.antoniou@konsulko.com> | 2014-10-28 16:36:02 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@linaro.org> | 2014-11-25 10:35:16 -0500 |
commit | a430a3455f2c48995e06b359a82a1109a419e9ef (patch) | |
tree | d35963abe215351d959090c8c8ef98b113a754c4 /drivers/i2c/i2c-core.c | |
parent | 177d271cf3171bb6826ee5189f67dc1f7d34f1da (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.c | 97 |
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) |
1371 | static void of_i2c_register_devices(struct i2c_adapter *adap) | 1372 | static 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)) | 1423 | static 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 | ||
1430 | static int of_dev_node_match(struct device *dev, void *data) | 1437 | static int of_dev_node_match(struct device *dev, void *data) |