diff options
| author | Stephen Neuendorffer <stephen.neuendorffer@xilinx.com> | 2010-11-18 15:54:59 -0800 | 
|---|---|---|
| committer | Grant Likely <grant.likely@secretlab.ca> | 2010-12-29 16:53:45 -0700 | 
| commit | 9706a36e35c4ce04f28a62cfe1205b4e3b0dd13c (patch) | |
| tree | 12f378664e5fa9fe560b281fa56214772df3f6ab | |
| parent | e6ce1324e4f08b0d984340201a125806dae0e9a6 (diff) | |
| download | olio-linux-3.10-9706a36e35c4ce04f28a62cfe1205b4e3b0dd13c.tar.xz olio-linux-3.10-9706a36e35c4ce04f28a62cfe1205b4e3b0dd13c.zip  | |
of/flattree: Add non-boottime device tree functions
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.
V2:
- functions have of_fdt_* names
- removed find_flat_dt_string
- blob argument is first
Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
| -rw-r--r-- | drivers/of/fdt.c | 133 | ||||
| -rw-r--r-- | 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 2ebacf14e7d..10eab21076e 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; +		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_OF_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 7bbf5b32843..70c5b736f0a 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;  |