aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Roedel <jroedel@suse.de>2016-04-04 11:49:18 -0400
committerRob Herring <robh@kernel.org>2016-04-19 18:25:13 -0400
commitcd209b412c8a5d632b51af1e45576f0d00b8105f (patch)
tree72164b609b058fe318f0f7dcd6d87d08f05ae842
parent74e1fbb1375a3ede3e17da22911761ce9bc8f53f (diff)
of: Move phandle walking to of_phandle_iterator_next()
Move the code to walk over the phandles out of the loop in __of_parse_phandle_with_args() to a separate function that just works with the iterator handle: of_phandle_iterator_next(). Signed-off-by: Joerg Roedel <jroedel@suse.de> Signed-off-by: Rob Herring <robh@kernel.org>
-rw-r--r--drivers/of/base.c130
-rw-r--r--include/linux/of.h7
2 files changed, 81 insertions, 56 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 1c6f43b5737d..69286ec206f7 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1465,6 +1465,75 @@ int of_phandle_iterator_init(struct of_phandle_iterator *it,
1465 return 0; 1465 return 0;
1466} 1466}
1467 1467
1468int of_phandle_iterator_next(struct of_phandle_iterator *it)
1469{
1470 uint32_t count = 0;
1471
1472 if (it->node) {
1473 of_node_put(it->node);
1474 it->node = NULL;
1475 }
1476
1477 if (!it->cur || it->phandle_end >= it->list_end)
1478 return -ENOENT;
1479
1480 it->cur = it->phandle_end;
1481
1482 /* If phandle is 0, then it is an empty entry with no arguments. */
1483 it->phandle = be32_to_cpup(it->cur++);
1484
1485 if (it->phandle) {
1486
1487 /*
1488 * Find the provider node and parse the #*-cells property to
1489 * determine the argument length.
1490 */
1491 it->node = of_find_node_by_phandle(it->phandle);
1492
1493 if (it->cells_name) {
1494 if (!it->node) {
1495 pr_err("%s: could not find phandle\n",
1496 it->parent->full_name);
1497 goto err;
1498 }
1499
1500 if (of_property_read_u32(it->node, it->cells_name,
1501 &count)) {
1502 pr_err("%s: could not get %s for %s\n",
1503 it->parent->full_name,
1504 it->cells_name,
1505 it->node->full_name);
1506 goto err;
1507 }
1508 } else {
1509 count = it->cell_count;
1510 }
1511
1512 /*
1513 * Make sure that the arguments actually fit in the remaining
1514 * property data length
1515 */
1516 if (it->cur + count > it->list_end) {
1517 pr_err("%s: arguments longer than property\n",
1518 it->parent->full_name);
1519 goto err;
1520 }
1521 }
1522
1523 it->phandle_end = it->cur + count;
1524 it->cur_count = count;
1525
1526 return 0;
1527
1528err:
1529 if (it->node) {
1530 of_node_put(it->node);
1531 it->node = NULL;
1532 }
1533
1534 return -EINVAL;
1535}
1536
1468static int __of_parse_phandle_with_args(const struct device_node *np, 1537static int __of_parse_phandle_with_args(const struct device_node *np,
1469 const char *list_name, 1538 const char *list_name,
1470 const char *cells_name, 1539 const char *cells_name,
@@ -1480,59 +1549,9 @@ static int __of_parse_phandle_with_args(const struct device_node *np,
1480 return rc; 1549 return rc;
1481 1550
1482 /* Loop over the phandles until all the requested entry is found */ 1551 /* Loop over the phandles until all the requested entry is found */
1483 while (it.cur < it.list_end) { 1552 while ((rc = of_phandle_iterator_next(&it)) == 0) {
1484 rc = -EINVAL;
1485 it.cur_count = 0;
1486
1487 /*
1488 * If phandle is 0, then it is an empty entry with no
1489 * arguments. Skip forward to the next entry.
1490 */
1491 it.phandle = be32_to_cpup(it.cur++);
1492 if (it.phandle) {
1493 /*
1494 * Find the provider node and parse the #*-cells
1495 * property to determine the argument length.
1496 *
1497 * This is not needed if the cell count is hard-coded
1498 * (i.e. cells_name not set, but cell_count is set),
1499 * except when we're going to return the found node
1500 * below.
1501 */
1502 if (it.cells_name || cur_index == index) {
1503 it.node = of_find_node_by_phandle(it.phandle);
1504 if (!it.node) {
1505 pr_err("%s: could not find phandle\n",
1506 it.parent->full_name);
1507 goto err;
1508 }
1509 }
1510
1511 if (it.cells_name) {
1512 if (of_property_read_u32(it.node, it.cells_name,
1513 &it.cur_count)) {
1514 pr_err("%s: could not get %s for %s\n",
1515 it.parent->full_name, it.cells_name,
1516 it.node->full_name);
1517 goto err;
1518 }
1519 } else {
1520 it.cur_count = it.cell_count;
1521 }
1522
1523 /*
1524 * Make sure that the arguments actually fit in the
1525 * remaining property data length
1526 */
1527 if (it.cur + it.cur_count > it.list_end) {
1528 pr_err("%s: arguments longer than property\n",
1529 it.parent->full_name);
1530 goto err;
1531 }
1532 }
1533
1534 /* 1553 /*
1535 * All of the error cases above bail out of the loop, so at 1554 * All of the error cases bail out of the loop, so at
1536 * this point, the parsing is successful. If the requested 1555 * this point, the parsing is successful. If the requested
1537 * index matches, then fill the out_args structure and return, 1556 * index matches, then fill the out_args structure and return,
1538 * or return -ENOENT for an empty entry. 1557 * or return -ENOENT for an empty entry.
@@ -1558,9 +1577,6 @@ static int __of_parse_phandle_with_args(const struct device_node *np,
1558 return 0; 1577 return 0;
1559 } 1578 }
1560 1579
1561 of_node_put(it.node);
1562 it.node = NULL;
1563 it.cur += it.cur_count;
1564 cur_index++; 1580 cur_index++;
1565 } 1581 }
1566 1582
@@ -1570,7 +1586,9 @@ static int __of_parse_phandle_with_args(const struct device_node *np,
1570 * -EINVAL : parsing error on data 1586 * -EINVAL : parsing error on data
1571 * [1..n] : Number of phandle (count mode; when index = -1) 1587 * [1..n] : Number of phandle (count mode; when index = -1)
1572 */ 1588 */
1573 rc = index < 0 ? cur_index : -ENOENT; 1589 if (rc == -ENOENT && index < 0)
1590 rc = cur_index;
1591
1574 err: 1592 err:
1575 if (it.node) 1593 if (it.node)
1576 of_node_put(it.node); 1594 of_node_put(it.node);
diff --git a/include/linux/of.h b/include/linux/of.h
index 0f187dbb890b..1f5e108f6716 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -358,6 +358,8 @@ extern int of_phandle_iterator_init(struct of_phandle_iterator *it,
358 const char *cells_name, 358 const char *cells_name,
359 int cell_count); 359 int cell_count);
360 360
361extern int of_phandle_iterator_next(struct of_phandle_iterator *it);
362
361extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)); 363extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align));
362extern int of_alias_get_id(struct device_node *np, const char *stem); 364extern int of_alias_get_id(struct device_node *np, const char *stem);
363extern int of_alias_get_highest_id(const char *stem); 365extern int of_alias_get_highest_id(const char *stem);
@@ -641,6 +643,11 @@ static inline int of_phandle_iterator_init(struct of_phandle_iterator *it,
641 return -ENOSYS; 643 return -ENOSYS;
642} 644}
643 645
646static inline int of_phandle_iterator_next(struct of_phandle_iterator *it)
647{
648 return -ENOSYS;
649}
650
644static inline int of_alias_get_id(struct device_node *np, const char *stem) 651static inline int of_alias_get_id(struct device_node *np, const char *stem)
645{ 652{
646 return -ENOSYS; 653 return -ENOSYS;