Message ID | 2743c30c538d24a0befee055bd6e0fcd746d0e82.1226550015.git.michael@ellerman.id.au (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
From: Michael Ellerman <michael@ellerman.id.au> Date: Thu, 13 Nov 2008 15:20:35 +1100 (EST) > + np = from ? from->allnext : allnodes; > + for (; np; np = np->allnext) { > + for (pp = np->properties; pp != 0; pp = pp->next) { > + if (of_prop_cmp(pp->name, prop_name) == 0) { > + goto out; > + } > + } > + } We're starting to duplicate a lot of code in this file. Perhaps split out the locked section of of_find_proeprty() into a __of_find_property() and use that here and in of_find_property() as well? staitc struct property *__of_find_property(const struct device_node *np, const char *name, int *lenp) { struct property *pp; for (pp = np->properties; pp != 0; pp = pp->next) { if (of_prop_cmp(pp->name, name) == 0) { if (lenp != 0) *lenp = pp->length; break; } } return pp; } struct property *of_find_property(const struct device_node *np, const char *name, int *lenp) { struct property *pp; if (!np) return NULL; read_lock(&devtree_lock); pp = __of_find_property(np, name, lenp); read_unlock(&devtree_lock); return pp; } EXPORT_SYMBOL(of_find_property);
On Wed, 2008-11-12 at 22:46 -0800, David Miller wrote: > From: Michael Ellerman <michael@ellerman.id.au> > Date: Thu, 13 Nov 2008 15:20:35 +1100 (EST) > > > + np = from ? from->allnext : allnodes; > > + for (; np; np = np->allnext) { > > + for (pp = np->properties; pp != 0; pp = pp->next) { > > + if (of_prop_cmp(pp->name, prop_name) == 0) { > > + goto out; > > + } > > + } > > + } > > We're starting to duplicate a lot of code in this file. Agreed. > Perhaps split out the locked section of of_find_proeprty() into > a __of_find_property() and use that here and in of_find_property() > as well? Yeah I thought about it, but decided it wasn't worth it. But I'll try it and see how the sizes end up. cheers
On Thu, 2008-11-13 at 17:49 +1100, Michael Ellerman wrote: > On Wed, 2008-11-12 at 22:46 -0800, David Miller wrote: > > From: Michael Ellerman <michael@ellerman.id.au> > > Date: Thu, 13 Nov 2008 15:20:35 +1100 (EST) > > > > > + np = from ? from->allnext : allnodes; > > > + for (; np; np = np->allnext) { > > > + for (pp = np->properties; pp != 0; pp = pp->next) { > > > + if (of_prop_cmp(pp->name, prop_name) == 0) { > > > + goto out; > > > + } > > > + } > > > + } > > > > We're starting to duplicate a lot of code in this file. > > Agreed. > > > Perhaps split out the locked section of of_find_proeprty() into > > a __of_find_property() and use that here and in of_find_property() > > as well? > > Yeah I thought about it, but decided it wasn't worth it. But I'll try it > and see how the sizes end up. With my compiler (4.3.1) it just gets inlined and actually makes the text 8 bytes larger. We might be using different CFLAGs to sparc though. I didn't think it made the source significantly clearer to split out the of_find_property() logic, especially seeing as we don't need the lenp behaviour in of_find_node_with_property(). cheers
From: Michael Ellerman <michael@ellerman.id.au> Date: Thu, 13 Nov 2008 18:11:43 +1100 > With my compiler (4.3.1) it just gets inlined and actually makes the > text 8 bytes larger. We might be using different CFLAGs to sparc though. > > I didn't think it made the source significantly clearer to split out the > of_find_property() logic, especially seeing as we don't need the lenp > behaviour in of_find_node_with_property(). Fair enough.
diff --git a/drivers/of/base.c b/drivers/of/base.c index 7c79e94..0c3dcd0 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -329,6 +329,40 @@ struct device_node *of_find_compatible_node(struct device_node *from, EXPORT_SYMBOL(of_find_compatible_node); /** + * of_find_node_with_property - Find a node which has a property with + * the given name. + * @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 + * @prop_name: The name of the property to look for. + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_with_property(struct device_node *from, + const char *prop_name) +{ + struct device_node *np; + struct property *pp; + + read_lock(&devtree_lock); + np = from ? from->allnext : allnodes; + for (; np; np = np->allnext) { + for (pp = np->properties; pp != 0; pp = pp->next) { + if (of_prop_cmp(pp->name, prop_name) == 0) { + goto out; + } + } + } +out: + of_node_put(from); + read_unlock(&devtree_lock); + return np; +} +EXPORT_SYMBOL(of_find_node_with_property); + +/** * of_match_node - Tell if an device_node has a matching of_match structure * @matches: array of of device match structures to search in * @node: the of device structure to match against diff --git a/include/linux/of.h b/include/linux/of.h index e2488f5..6a7efa2 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -57,6 +57,12 @@ extern struct device_node *of_get_next_child(const struct device_node *node, for (child = of_get_next_child(parent, NULL); child != NULL; \ child = of_get_next_child(parent, child)) +extern struct device_node *of_find_node_with_property( + struct device_node *from, const char *prop_name); +#define for_each_node_with_property(dn, prop_name) \ + for (dn = of_find_node_with_property(NULL, prop_name); dn; \ + dn = of_find_node_with_property(dn, prop_name)) + extern struct property *of_find_property(const struct device_node *np, const char *name, int *lenp);
This commit adds a routine for finding a device node which has a certain property, the contents of the property are not taken into account, merely the presence or absence of the property. Based on that routine, we add a for_each_ macro for iterating over all nodes that have a certain property. Signed-off-by: Michael Ellerman <michael@ellerman.id.au> --- drivers/of/base.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/of.h | 6 ++++++ 2 files changed, 40 insertions(+), 0 deletions(-)