Commit 50c8af4cf98fd97d6779f244215154e4c89699c7
Committed by
Rob Herring
1 parent
be193249b4
Exists in
master
and in
20 other branches
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
drivers/of/base.c
... | ... | @@ -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); |
include/linux/of.h
... | ... | @@ -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); |