diff options
author | merge <null@invalid> | 2009-01-22 13:55:32 +0000 |
---|---|---|
committer | Andy Green <agreen@octopus.localdomain> | 2009-01-22 13:55:32 +0000 |
commit | aa6f5ffbdba45aa8e19e5048648fc6c7b25376d3 (patch) | |
tree | fbb786d0ac6f8a774fd834e9ce951197e60fbffa /drivers/of/base.c | |
parent | f2d78193eae5dccd3d588d2c8ea0866efc368332 (diff) |
MERGE-via-pending-tracking-hist-MERGE-via-stable-tracking-MERGE-via-mokopatches-tracking-fix-stray-endmenu-patch-1232632040-1232632141
pending-tracking-hist top was MERGE-via-stable-tracking-MERGE-via-mokopatches-tracking-fix-stray-endmenu-patch-1232632040-1232632141 / fdf777a63bcb59e0dfd78bfe2c6242e01f6d4eb9 ... parent commitmessage:
From: merge <null@invalid>
MERGE-via-stable-tracking-hist-MERGE-via-mokopatches-tracking-fix-stray-endmenu-patch-1232632040
stable-tracking-hist top was MERGE-via-mokopatches-tracking-fix-stray-endmenu-patch-1232632040 / 90463bfd2d5a3c8b52f6e6d71024a00e052b0ced ... parent commitmessage:
From: merge <null@invalid>
MERGE-via-mokopatches-tracking-hist-fix-stray-endmenu-patch
mokopatches-tracking-hist top was fix-stray-endmenu-patch / 3630e0be570de8057e7f8d2fe501ed353cdf34e6 ... parent commitmessage:
From: Andy Green <andy@openmoko.com>
fix-stray-endmenu.patch
Signed-off-by: Andy Green <andy@openmoko.com>
Diffstat (limited to 'drivers/of/base.c')
-rw-r--r-- | drivers/of/base.c | 68 |
1 files changed, 55 insertions, 13 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c index 7c79e94a35e..cd17092b82b 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -329,6 +329,41 @@ 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) { + of_node_get(np); + 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 @@ -464,8 +499,8 @@ EXPORT_SYMBOL_GPL(of_modalias_node); * @list_name: property name that contains a list * @cells_name: property name that specifies phandles' arguments count * @index: index of a phandle to parse out - * @out_node: pointer to device_node struct pointer (will be filled) - * @out_args: pointer to arguments pointer (will be filled) + * @out_node: optional pointer to device_node struct pointer (will be filled) + * @out_args: optional pointer to arguments pointer (will be filled) * * This function is useful to parse lists of phandles and their arguments. * Returns 0 on success and fills out_node and out_args, on error returns @@ -499,7 +534,7 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name, int size; int cur_index = 0; struct device_node *node = NULL; - const void *args; + const void *args = NULL; list = of_get_property(np, list_name, &size); if (!list) { @@ -512,14 +547,12 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name, const u32 *cells; const phandle *phandle; - phandle = list; - args = list + 1; + phandle = list++; + args = list; /* one cell hole in the list = <>; */ - if (!*phandle) { - list++; + if (!*phandle) goto next; - } node = of_find_node_by_phandle(*phandle); if (!node) { @@ -535,8 +568,7 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name, goto err1; } - /* Next phandle is at offset of one phandle cell + #cells */ - list += 1 + *cells; + list += *cells; if (list > list_end) { pr_debug("%s: insufficient arguments length\n", np->full_name); @@ -548,16 +580,26 @@ next: of_node_put(node); node = NULL; + args = NULL; cur_index++; } if (!node) { - ret = -ENOENT; + /* + * args w/o node indicates that the loop above has stopped at + * the 'hole' cell. Report this differently. + */ + if (args) + ret = -EEXIST; + else + ret = -ENOENT; goto err0; } - *out_node = node; - *out_args = args; + if (out_node) + *out_node = node; + if (out_args) + *out_args = args; return 0; err1: |