aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of
diff options
context:
space:
mode:
authorStephen Neuendorffer <stephen.neuendorffer@xilinx.com>2010-11-18 18:54:59 -0500
committerGrant Likely <grant.likely@secretlab.ca>2010-12-29 18:53:45 -0500
commit9706a36e35c4ce04f28a62cfe1205b4e3b0dd13c (patch)
tree12f378664e5fa9fe560b281fa56214772df3f6ab /drivers/of
parente6ce1324e4f08b0d984340201a125806dae0e9a6 (diff)
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>
Diffstat (limited to 'drivers/of')
-rw-r--r--drivers/of/fdt.c133
1 files changed, 79 insertions, 54 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 2ebacf14e7de..10eab21076ea 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -22,6 +22,82 @@
22 22
23#include <asm/page.h> 23#include <asm/page.h>
24 24
25char *of_fdt_get_string(struct boot_param_header *blob, u32 offset)
26{
27 return ((char *)blob) +
28 be32_to_cpu(blob->off_dt_strings) + offset;
29}
30
31/**
32 * of_fdt_get_property - Given a node in the given flat blob, return
33 * the property ptr
34 */
35void *of_fdt_get_property(struct boot_param_header *blob,
36 unsigned long node, const char *name,
37 unsigned long *size)
38{
39 unsigned long p = node;
40
41 do {
42 u32 tag = be32_to_cpup((__be32 *)p);
43 u32 sz, noff;
44 const char *nstr;
45
46 p += 4;
47 if (tag == OF_DT_NOP)
48 continue;
49 if (tag != OF_DT_PROP)
50 return NULL;
51
52 sz = be32_to_cpup((__be32 *)p);
53 noff = be32_to_cpup((__be32 *)(p + 4));
54 p += 8;
55 if (be32_to_cpu(blob->version) < 0x10)
56 p = ALIGN(p, sz >= 8 ? 8 : 4);
57
58 nstr = of_fdt_get_string(blob, noff);
59 if (nstr == NULL) {
60 pr_warning("Can't find property index name !\n");
61 return NULL;
62 }
63 if (strcmp(name, nstr) == 0) {
64 if (size)
65 *size = sz;
66 return (void *)p;
67 }
68 p += sz;
69 p = ALIGN(p, 4);
70 } while (1);
71}
72
73/**
74 * of_fdt_is_compatible - Return true if given node from the given blob has
75 * compat in its compatible list
76 * @blob: A device tree blob
77 * @node: node to test
78 * @compat: compatible string to compare with compatible list.
79 */
80int of_fdt_is_compatible(struct boot_param_header *blob,
81 unsigned long node, const char *compat)
82{
83 const char *cp;
84 unsigned long cplen, l;
85
86 cp = of_fdt_get_property(blob, node, "compatible", &cplen);
87 if (cp == NULL)
88 return 0;
89 while (cplen > 0) {
90 if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
91 return 1;
92 l = strlen(cp) + 1;
93 cp += l;
94 cplen -= l;
95 }
96
97 return 0;
98}
99
100/* Everything below here references initial_boot_params directly. */
25int __initdata dt_root_addr_cells; 101int __initdata dt_root_addr_cells;
26int __initdata dt_root_size_cells; 102int __initdata dt_root_size_cells;
27 103
@@ -29,12 +105,6 @@ struct boot_param_header *initial_boot_params;
29 105
30#ifdef CONFIG_OF_EARLY_FLATTREE 106#ifdef CONFIG_OF_EARLY_FLATTREE
31 107
32char *find_flat_dt_string(u32 offset)
33{
34 return ((char *)initial_boot_params) +
35 be32_to_cpu(initial_boot_params->off_dt_strings) + offset;
36}
37
38/** 108/**
39 * of_scan_flat_dt - scan flattened tree blob and call callback on each. 109 * of_scan_flat_dt - scan flattened tree blob and call callback on each.
40 * @it: callback function 110 * @it: callback function
@@ -123,38 +193,7 @@ unsigned long __init of_get_flat_dt_root(void)
123void *__init of_get_flat_dt_prop(unsigned long node, const char *name, 193void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
124 unsigned long *size) 194 unsigned long *size)
125{ 195{
126 unsigned long p = node; 196 return of_fdt_get_property(initial_boot_params, node, name, size);
127
128 do {
129 u32 tag = be32_to_cpup((__be32 *)p);
130 u32 sz, noff;
131 const char *nstr;
132
133 p += 4;
134 if (tag == OF_DT_NOP)
135 continue;
136 if (tag != OF_DT_PROP)
137 return NULL;
138
139 sz = be32_to_cpup((__be32 *)p);
140 noff = be32_to_cpup((__be32 *)(p + 4));
141 p += 8;
142 if (be32_to_cpu(initial_boot_params->version) < 0x10)
143 p = ALIGN(p, sz >= 8 ? 8 : 4);
144
145 nstr = find_flat_dt_string(noff);
146 if (nstr == NULL) {
147 pr_warning("Can't find property index name !\n");
148 return NULL;
149 }
150 if (strcmp(name, nstr) == 0) {
151 if (size)
152 *size = sz;
153 return (void *)p;
154 }
155 p += sz;
156 p = ALIGN(p, 4);
157 } while (1);
158} 197}
159 198
160/** 199/**
@@ -164,21 +203,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
164 */ 203 */
165int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) 204int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
166{ 205{
167 const char *cp; 206 return of_fdt_is_compatible(initial_boot_params, node, compat);
168 unsigned long cplen, l;
169
170 cp = of_get_flat_dt_prop(node, "compatible", &cplen);
171 if (cp == NULL)
172 return 0;
173 while (cplen > 0) {
174 if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
175 return 1;
176 l = strlen(cp) + 1;
177 cp += l;
178 cplen -= l;
179 }
180
181 return 0;
182} 207}
183 208
184static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, 209static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
@@ -303,7 +328,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
303 if (be32_to_cpu(initial_boot_params->version) < 0x10) 328 if (be32_to_cpu(initial_boot_params->version) < 0x10)
304 *p = ALIGN(*p, sz >= 8 ? 8 : 4); 329 *p = ALIGN(*p, sz >= 8 ? 8 : 4);
305 330
306 pname = find_flat_dt_string(noff); 331 pname = of_fdt_get_string(initial_boot_params, noff);
307 if (pname == NULL) { 332 if (pname == NULL) {
308 pr_info("Can't find property name in list !\n"); 333 pr_info("Can't find property name in list !\n");
309 break; 334 break;