Skip to content

Commit 50c8af4

Browse files
nvswarrenRob Herring
authored andcommitted
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>
1 parent be19324 commit 50c8af4

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

drivers/of/base.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -594,27 +594,35 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches,
594594
EXPORT_SYMBOL(of_match_node);
595595

596596
/**
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.
599599
* @from: The node to start searching from or NULL, the node
600600
* you pass will not be searched, only the next one
601601
* will; typically, you pass what the previous call
602602
* returned. of_node_put() will be called on it
603603
* @matches: array of of device match structures to search in
604+
* @match Updated to point at the matches entry which matched
604605
*
605606
* Returns a node pointer with refcount incremented, use
606607
* of_node_put() on it when done.
607608
*/
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)
610612
{
611613
struct device_node *np;
612614

615+
if (match)
616+
*match = NULL;
617+
613618
read_lock(&devtree_lock);
614619
np = from ? from->allnext : allnodes;
615620
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;
617624
break;
625+
}
618626
}
619627
of_node_put(from);
620628
read_unlock(&devtree_lock);

include/linux/of.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,22 @@ extern struct device_node *of_find_compatible_node(struct device_node *from,
179179
#define for_each_compatible_node(dn, type, compatible) \
180180
for (dn = of_find_compatible_node(NULL, type, compatible); dn; \
181181
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+
}
184192
#define for_each_matching_node(dn, matches) \
185193
for (dn = of_find_matching_node(NULL, matches); dn; \
186194
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))
187198
extern struct device_node *of_find_node_by_path(const char *path);
188199
extern struct device_node *of_find_node_by_phandle(phandle handle);
189200
extern struct device_node *of_get_parent(const struct device_node *node);

0 commit comments

Comments
 (0)