aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2012-11-20 18:12:20 -0500
committerRob Herring <rob.herring@calxeda.com>2012-11-20 23:58:55 -0500
commit50c8af4cf98fd97d6779f244215154e4c89699c7 (patch)
tree9690d810d1eef4b5dc8a26824dc699bbb4d54f44
parentbe193249b4178158c0f697cb452b2bbf0cb16361 (diff)
of: introduce for_each_matching_node_and_match()
The following pattern of code is tempting: for_each_matching_node(np, table) { match = of_match_node(table, np); However, this results in iterating over table twice; the second time inside of_match_node(). The implementation of for_each_matching_node() already found the match, so this is redundant. Invent new function of_find_matching_node_and_match() and macro for_each_matching_node_and_match() to remove the double iteration, thus transforming the above code to: for_each_matching_node_and_match(np, table, &match) Signed-off-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
-rw-r--r--drivers/of/base.c18
-rw-r--r--include/linux/of.h15
2 files changed, 26 insertions, 7 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index f564e3107b3..0ceb26a1605 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -594,27 +594,35 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches,
594EXPORT_SYMBOL(of_match_node); 594EXPORT_SYMBOL(of_match_node);
595 595
596/** 596/**
597 * of_find_matching_node - Find a node based on an of_device_id match 597 * of_find_matching_node_and_match - Find a node based on an of_device_id
598 * table. 598 * match table.
599 * @from: The node to start searching from or NULL, the node 599 * @from: The node to start searching from or NULL, the node
600 * you pass will not be searched, only the next one 600 * you pass will not be searched, only the next one
601 * will; typically, you pass what the previous call 601 * will; typically, you pass what the previous call
602 * returned. of_node_put() will be called on it 602 * returned. of_node_put() will be called on it
603 * @matches: array of of device match structures to search in 603 * @matches: array of of device match structures to search in
604 * @match Updated to point at the matches entry which matched
604 * 605 *
605 * Returns a node pointer with refcount incremented, use 606 * Returns a node pointer with refcount incremented, use
606 * of_node_put() on it when done. 607 * of_node_put() on it when done.
607 */ 608 */
608struct device_node *of_find_matching_node(struct device_node *from, 609struct device_node *of_find_matching_node_and_match(struct device_node *from,
609 const struct of_device_id *matches) 610 const struct of_device_id *matches,
611 const struct of_device_id **match)
610{ 612{
611 struct device_node *np; 613 struct device_node *np;
612 614
615 if (match)
616 *match = NULL;
617
613 read_lock(&devtree_lock); 618 read_lock(&devtree_lock);
614 np = from ? from->allnext : allnodes; 619 np = from ? from->allnext : allnodes;
615 for (; np; np = np->allnext) { 620 for (; np; np = np->allnext) {
616 if (of_match_node(matches, np) && of_node_get(np)) 621 if (of_match_node(matches, np) && of_node_get(np)) {
622 if (match)
623 *match = matches;
617 break; 624 break;
625 }
618 } 626 }
619 of_node_put(from); 627 of_node_put(from);
620 read_unlock(&devtree_lock); 628 read_unlock(&devtree_lock);
diff --git a/include/linux/of.h b/include/linux/of.h
index ab1af0e1465..13e0aacb4d9 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -179,11 +179,22 @@ extern struct device_node *of_find_compatible_node(struct device_node *from,
179#define for_each_compatible_node(dn, type, compatible) \ 179#define for_each_compatible_node(dn, type, compatible) \
180 for (dn = of_find_compatible_node(NULL, type, compatible); dn; \ 180 for (dn = of_find_compatible_node(NULL, type, compatible); dn; \
181 dn = of_find_compatible_node(dn, type, compatible)) 181 dn = of_find_compatible_node(dn, type, compatible))
182extern struct device_node *of_find_matching_node(struct device_node *from, 182extern struct device_node *of_find_matching_node_and_match(
183 const struct of_device_id *matches); 183 struct device_node *from,
184 const struct of_device_id *matches,
185 const struct of_device_id **match);
186static inline struct device_node *of_find_matching_node(
187 struct device_node *from,
188 const struct of_device_id *matches)
189{
190 return of_find_matching_node_and_match(from, matches, NULL);
191}
184#define for_each_matching_node(dn, matches) \ 192#define for_each_matching_node(dn, matches) \
185 for (dn = of_find_matching_node(NULL, matches); dn; \ 193 for (dn = of_find_matching_node(NULL, matches); dn; \
186 dn = of_find_matching_node(dn, matches)) 194 dn = of_find_matching_node(dn, matches))
195#define for_each_matching_node_and_match(dn, matches, match) \
196 for (dn = of_find_matching_node_and_match(NULL, matches, match); \
197 dn; dn = of_find_matching_node_and_match(dn, matches, match))
187extern struct device_node *of_find_node_by_path(const char *path); 198extern struct device_node *of_find_node_by_path(const char *path);
188extern struct device_node *of_find_node_by_phandle(phandle handle); 199extern struct device_node *of_find_node_by_phandle(phandle handle);
189extern struct device_node *of_get_parent(const struct device_node *node); 200extern struct device_node *of_get_parent(const struct device_node *node);