Commit 50c8af4c authored by Stephen Warren's avatar Stephen Warren Committed by Rob Herring

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: default avatarStephen Warren <swarren@nvidia.com>
Signed-off-by: default avatarRob Herring <rob.herring@calxeda.com>
parent be193249
...@@ -594,28 +594,36 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches, ...@@ -594,28 +594,36 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches,
EXPORT_SYMBOL(of_match_node); EXPORT_SYMBOL(of_match_node);
/** /**
* of_find_matching_node - Find a node based on an of_device_id match * of_find_matching_node_and_match - Find a node based on an of_device_id
* table. * match table.
* @from: The node to start searching from or NULL, the node * @from: The node to start searching from or NULL, the node
* you pass will not be searched, only the next one * you pass will not be searched, only the next one
* will; typically, you pass what the previous call * will; typically, you pass what the previous call
* returned. of_node_put() will be called on it * returned. of_node_put() will be called on it
* @matches: array of of device match structures to search in * @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 * Returns a node pointer with refcount incremented, use
* of_node_put() on it when done. * of_node_put() on it when done.
*/ */
struct device_node *of_find_matching_node(struct device_node *from, struct device_node *of_find_matching_node_and_match(struct device_node *from,
const struct of_device_id *matches) const struct of_device_id *matches,
const struct of_device_id **match)
{ {
struct device_node *np; struct device_node *np;
if (match)
*match = NULL;
read_lock(&devtree_lock); read_lock(&devtree_lock);
np = from ? from->allnext : allnodes; np = from ? from->allnext : allnodes;
for (; np; np = np->allnext) { 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; break;
} }
}
of_node_put(from); of_node_put(from);
read_unlock(&devtree_lock); read_unlock(&devtree_lock);
return np; return np;
......
...@@ -179,11 +179,22 @@ extern struct device_node *of_find_compatible_node(struct device_node *from, ...@@ -179,11 +179,22 @@ extern struct device_node *of_find_compatible_node(struct device_node *from,
#define for_each_compatible_node(dn, type, compatible) \ #define for_each_compatible_node(dn, type, compatible) \
for (dn = of_find_compatible_node(NULL, type, compatible); dn; \ for (dn = of_find_compatible_node(NULL, type, compatible); dn; \
dn = of_find_compatible_node(dn, type, compatible)) dn = of_find_compatible_node(dn, type, compatible))
extern struct device_node *of_find_matching_node(struct device_node *from, extern struct device_node *of_find_matching_node_and_match(
const struct of_device_id *matches); struct device_node *from,
const struct of_device_id *matches,
const struct of_device_id **match);
static inline struct device_node *of_find_matching_node(
struct device_node *from,
const struct of_device_id *matches)
{
return of_find_matching_node_and_match(from, matches, NULL);
}
#define for_each_matching_node(dn, matches) \ #define for_each_matching_node(dn, matches) \
for (dn = of_find_matching_node(NULL, matches); dn; \ for (dn = of_find_matching_node(NULL, matches); dn; \
dn = of_find_matching_node(dn, matches)) dn = of_find_matching_node(dn, matches))
#define for_each_matching_node_and_match(dn, matches, match) \
for (dn = of_find_matching_node_and_match(NULL, matches, match); \
dn; dn = of_find_matching_node_and_match(dn, matches, match))
extern struct device_node *of_find_node_by_path(const char *path); extern struct device_node *of_find_node_by_path(const char *path);
extern struct device_node *of_find_node_by_phandle(phandle handle); extern struct device_node *of_find_node_by_phandle(phandle handle);
extern struct device_node *of_get_parent(const struct device_node *node); extern struct device_node *of_get_parent(const struct device_node *node);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment