On Thu, Nov 18, 2010 at 03:54:59PM -0800, Stephen Neuendorffer wrote: > In preparation for providing run-time handling of device trees, factor > out some of the basic functions so that they take an arbitrary blob, > rather than relying on the single boot-time tree. > > Signed-off-by: Stephen Neuendorffer <stephen.neuendorf...@xilinx.com>
Thanks. Merged, but one comment below. Please fix with a followup patch. g. > > -- > > V2: functions have of_fdt_* names > removed find_flat_dt_string > blob argument is first > --- > drivers/of/fdt.c | 133 ++++++++++++++++++++++++++++------------------- > include/linux/of_fdt.h | 11 ++++ > 2 files changed, 90 insertions(+), 54 deletions(-) > > diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c > index 4d71b29..190e26c 100644 > --- a/drivers/of/fdt.c > +++ b/drivers/of/fdt.c > @@ -22,6 +22,82 @@ > > #include <asm/page.h> > > +char *of_fdt_get_string(struct boot_param_header *blob, u32 offset) > +{ > + return ((char *)blob) + > + be32_to_cpu(blob->off_dt_strings) + offset; > +} > + > +/** > + * of_fdt_get_property - Given a node in the given flat blob, return > + * the property ptr > + */ > +void *of_fdt_get_property(struct boot_param_header *blob, > + unsigned long node, const char *name, > + unsigned long *size) > +{ > + unsigned long p = node; > + > + do { > + u32 tag = be32_to_cpup((__be32 *)p); > + u32 sz, noff; > + const char *nstr; > + > + p += 4; > + if (tag == OF_DT_NOP) > + continue; > + if (tag != OF_DT_PROP) > + return NULL; > + > + sz = be32_to_cpup((__be32 *)p); > + noff = be32_to_cpup((__be32 *)(p + 4)); > + p += 8; > + if (be32_to_cpu(blob->version) < 0x10) > + p = ALIGN(p, sz >= 8 ? 8 : 4); > + > + nstr = of_fdt_get_string(blob, noff); > + if (nstr == NULL) { > + pr_warning("Can't find property index name !\n"); > + return NULL; > + } > + if (strcmp(name, nstr) == 0) { > + if (size) > + *size = sz; > + return (void *)p; > + } > + p += sz; > + p = ALIGN(p, 4); > + } while (1); > +} > + > +/** > + * of_fdt_is_compatible - Return true if given node from the given blob has > + * compat in its compatible list > + * @blob: A device tree blob > + * @node: node to test > + * @compat: compatible string to compare with compatible list. > + */ > +int of_fdt_is_compatible(struct boot_param_header *blob, > + unsigned long node, const char *compat) > +{ > + const char *cp; > + unsigned long cplen, l; > + > + cp = of_fdt_get_property(blob, node, "compatible", &cplen); > + if (cp == NULL) > + return 0; > + while (cplen > 0) { > + if (of_compat_cmp(cp, compat, strlen(compat)) == 0) > + return 1; Need to verify that strlen(cp) + 1 is not larger than cplen. Otherwise cplen could wrap around and the loop won't terminate because cplen is an unsigned long. > + l = strlen(cp) + 1; > + cp += l; > + cplen -= l; > + } > + > + return 0; > +} > + > +/* Everything below here references initial_boot_params directly. */ > int __initdata dt_root_addr_cells; > int __initdata dt_root_size_cells; > > @@ -29,12 +105,6 @@ struct boot_param_header *initial_boot_params; > > #ifdef CONFIG_EARLY_FLATTREE > > -char *find_flat_dt_string(u32 offset) > -{ > - return ((char *)initial_boot_params) + > - be32_to_cpu(initial_boot_params->off_dt_strings) + offset; > -} > - > /** > * of_scan_flat_dt - scan flattened tree blob and call callback on each. > * @it: callback function > @@ -123,38 +193,7 @@ unsigned long __init of_get_flat_dt_root(void) > void *__init of_get_flat_dt_prop(unsigned long node, const char *name, > unsigned long *size) > { > - unsigned long p = node; > - > - do { > - u32 tag = be32_to_cpup((__be32 *)p); > - u32 sz, noff; > - const char *nstr; > - > - p += 4; > - if (tag == OF_DT_NOP) > - continue; > - if (tag != OF_DT_PROP) > - return NULL; > - > - sz = be32_to_cpup((__be32 *)p); > - noff = be32_to_cpup((__be32 *)(p + 4)); > - p += 8; > - if (be32_to_cpu(initial_boot_params->version) < 0x10) > - p = ALIGN(p, sz >= 8 ? 8 : 4); > - > - nstr = find_flat_dt_string(noff); > - if (nstr == NULL) { > - pr_warning("Can't find property index name !\n"); > - return NULL; > - } > - if (strcmp(name, nstr) == 0) { > - if (size) > - *size = sz; > - return (void *)p; > - } > - p += sz; > - p = ALIGN(p, 4); > - } while (1); > + return of_fdt_get_property(initial_boot_params, node, name, size); > } > > /** > @@ -164,21 +203,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, > const char *name, > */ > int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) > { > - const char *cp; > - unsigned long cplen, l; > - > - cp = of_get_flat_dt_prop(node, "compatible", &cplen); > - if (cp == NULL) > - return 0; > - while (cplen > 0) { > - if (of_compat_cmp(cp, compat, strlen(compat)) == 0) > - return 1; > - l = strlen(cp) + 1; > - cp += l; > - cplen -= l; > - } > - > - return 0; > + return of_fdt_is_compatible(initial_boot_params, node, compat); > } > > static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long > size, > @@ -303,7 +328,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem, > if (be32_to_cpu(initial_boot_params->version) < 0x10) > *p = ALIGN(*p, sz >= 8 ? 8 : 4); > > - pname = find_flat_dt_string(noff); > + pname = of_fdt_get_string(initial_boot_params, noff); > if (pname == NULL) { > pr_info("Can't find property name in list !\n"); > break; > diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h > index 7bbf5b3..70c5b73 100644 > --- a/include/linux/of_fdt.h > +++ b/include/linux/of_fdt.h > @@ -58,6 +58,17 @@ struct boot_param_header { > }; > > #if defined(CONFIG_OF_FLATTREE) > + > +/* For scanning an arbitrary device-tree at any time */ > +extern char *of_fdt_get_string(struct boot_param_header *blob, u32 offset); > +extern void *of_fdt_get_property(struct boot_param_header *blob, > + unsigned long node, > + const char *name, > + unsigned long *size); > +extern int of_fdt_is_compatible(struct boot_param_header *blob, > + unsigned long node, > + const char *compat); > + > /* TBD: Temporary export of fdt globals - remove when code fully merged */ > extern int __initdata dt_root_addr_cells; > extern int __initdata dt_root_size_cells; > -- > 1.5.6.6 > > > > This email and any attachments are intended for the sole use of the named > recipient(s) and contain(s) confidential information that may be proprietary, > privileged or copyrighted under applicable law. If you are not the intended > recipient, do not read, copy, or forward this email message or any > attachments. Delete this email message and any attachments immediately. > > _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev