summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2012-11-20 16:12:20 -0700
committerRob Herring <rob.herring@calxeda.com>2012-11-20 22:58:55 -0600
commit50c8af4cf98fd97d6779f244215154e4c89699c7 (patch)
tree9690d810d1eef4b5dc8a26824dc699bbb4d54f44 /drivers
parentbe193249b4178158c0f697cb452b2bbf0cb16361 (diff)
downloadlinux-50c8af4cf98fd97d6779f244215154e4c89699c7.tar.bz2
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/of/base.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index f564e3107b3e..0ceb26a16050 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,
EXPORT_SYMBOL(of_match_node);
/**
- * of_find_matching_node - Find a node based on an of_device_id match
- * table.
+ * of_find_matching_node_and_match - Find a node based on an of_device_id
+ * match table.
* @from: The node to start searching from or NULL, the node
* you pass will not be searched, only the next one
* will; typically, you pass what the previous call
* returned. of_node_put() will be called on it
* @matches: array of of device match structures to search in
+ * @match Updated to point at the matches entry which matched
*
* Returns a node pointer with refcount incremented, use
* of_node_put() on it when done.
*/
-struct device_node *of_find_matching_node(struct device_node *from,
- const struct of_device_id *matches)
+struct device_node *of_find_matching_node_and_match(struct device_node *from,
+ const struct of_device_id *matches,
+ const struct of_device_id **match)
{
struct device_node *np;
+ if (match)
+ *match = NULL;
+
read_lock(&devtree_lock);
np = from ? from->allnext : allnodes;
for (; np; np = np->allnext) {
- if (of_match_node(matches, np) && of_node_get(np))
+ if (of_match_node(matches, np) && of_node_get(np)) {
+ if (match)
+ *match = matches;
break;
+ }
}
of_node_put(from);
read_unlock(&devtree_lock);