Commit 50c8af4cf98fd97d6779f244215154e4c89699c7

Authored by Stephen Warren
Committed by Rob Herring
1 parent be193249b4

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>

Showing 2 changed files with 26 additions and 7 deletions Side-by-side Diff

... ... @@ -594,27 +594,35 @@
594 594 EXPORT_SYMBOL(of_match_node);
595 595  
596 596 /**
597   - * of_find_matching_node - Find a node based on an of_device_id match
598   - * table.
  597 + * of_find_matching_node_and_match - Find a node based on an of_device_id
  598 + * match table.
599 599 * @from: The node to start searching from or NULL, the node
600 600 * you pass will not be searched, only the next one
601 601 * will; typically, you pass what the previous call
602 602 * returned. of_node_put() will be called on it
603 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 606 * Returns a node pointer with refcount incremented, use
606 607 * of_node_put() on it when done.
607 608 */
608   -struct device_node *of_find_matching_node(struct device_node *from,
609   - const struct of_device_id *matches)
  609 +struct device_node *of_find_matching_node_and_match(struct device_node *from,
  610 + const struct of_device_id *matches,
  611 + const struct of_device_id **match)
610 612 {
611 613 struct device_node *np;
612 614  
  615 + if (match)
  616 + *match = NULL;
  617 +
613 618 read_lock(&devtree_lock);
614 619 np = from ? from->allnext : allnodes;
615 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 624 break;
  625 + }
618 626 }
619 627 of_node_put(from);
620 628 read_unlock(&devtree_lock);
... ... @@ -179,11 +179,22 @@
179 179 #define for_each_compatible_node(dn, type, compatible) \
180 180 for (dn = of_find_compatible_node(NULL, type, compatible); dn; \
181 181 dn = of_find_compatible_node(dn, type, compatible))
182   -extern struct device_node *of_find_matching_node(struct device_node *from,
183   - const struct of_device_id *matches);
  182 +extern struct device_node *of_find_matching_node_and_match(
  183 + struct device_node *from,
  184 + const struct of_device_id *matches,
  185 + const struct of_device_id **match);
  186 +static 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 192 #define for_each_matching_node(dn, matches) \
185 193 for (dn = of_find_matching_node(NULL, matches); dn; \
186 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))
187 198 extern struct device_node *of_find_node_by_path(const char *path);
188 199 extern struct device_node *of_find_node_by_phandle(phandle handle);
189 200 extern struct device_node *of_get_parent(const struct device_node *node);