diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-28 16:54:33 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-28 16:54:33 -0800 |
commit | 3c92ec8ae91ecf59d88c798301833d7cf83f2179 (patch) | |
tree | 08a38cd3523c42bd49882f17cd501fd879e7ca1c /drivers/of/base.c | |
parent | c4c9f0183b7c4e97836e8fecbb67898b06c47e78 (diff) | |
parent | ca9153a3a2a7556d091dfe080e42b0e67881fff6 (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (144 commits)
powerpc/44x: Support 16K/64K base page sizes on 44x
powerpc: Force memory size to be a multiple of PAGE_SIZE
powerpc/32: Wire up the trampoline code for kdump
powerpc/32: Add the ability for a classic ppc kernel to be loaded at 32M
powerpc/32: Allow __ioremap on RAM addresses for kdump kernel
powerpc/32: Setup OF properties for kdump
powerpc/32/kdump: Implement crash_setup_regs() using ppc_save_regs()
powerpc: Prepare xmon_save_regs for use with kdump
powerpc: Remove default kexec/crash_kernel ops assignments
powerpc: Make default kexec/crash_kernel ops implicit
powerpc: Setup OF properties for ppc32 kexec
powerpc/pseries: Fix cpu hotplug
powerpc: Fix KVM build on ppc440
powerpc/cell: add QPACE as a separate Cell platform
powerpc/cell: fix build breakage with CONFIG_SPUFS disabled
powerpc/mpc5200: fix error paths in PSC UART probe function
powerpc/mpc5200: add rts/cts handling in PSC UART driver
powerpc/mpc5200: Make PSC UART driver update serial errors counters
powerpc/mpc5200: Remove obsolete code from mpc5200 MDIO driver
powerpc/mpc5200: Add MDMA/UDMA support to MPC5200 ATA driver
...
Fix trivial conflict in drivers/char/Makefile as per Paul's directions
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 7c79e94a35ea..cd17092b82bd 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: |