aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/fdt.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2014-10-03 11:28:27 -0400
committerGrant Likely <grant.likely@linaro.org>2014-11-04 08:29:38 -0500
commit5063e25a302e6a83f6590d9a06bd5f6400b17430 (patch)
treebd6aafd28fb65ea19cd1535fd9a53263b42a68c0 /drivers/of/fdt.c
parente7a00e4210e4cc980e3ba67ec7301af54061d14b (diff)
of: Eliminate of_allnodes list
The device tree structure is composed of two lists; the 'allnodes' list which is a singly linked list containing every node in the tree, and the child->parent structure where each parent node has a singly linked list of children. All of the data in the allnodes list can be easily reproduced with the parent-child lists, so of_allnodes is actually unnecessary. Remove it entirely which saves a bit of memory and simplifies the data structure quite a lot. Signed-off-by: Grant Likely <grant.likely@linaro.org> Cc: Rob Herring <robh@kernel.org> Cc: Gaurav Minocha <gaurav.minocha.os@gmail.com> Cc: Pantelis Antoniou <pantelis@pantelis.antoniou@konsulko.com>
Diffstat (limited to 'drivers/of/fdt.c')
-rw-r--r--drivers/of/fdt.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index d1ffca8b34ea..1d30b9f96466 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -145,15 +145,15 @@ static void *unflatten_dt_alloc(void **mem, unsigned long size,
145 * @mem: Memory chunk to use for allocating device nodes and properties 145 * @mem: Memory chunk to use for allocating device nodes and properties
146 * @p: pointer to node in flat tree 146 * @p: pointer to node in flat tree
147 * @dad: Parent struct device_node 147 * @dad: Parent struct device_node
148 * @allnextpp: pointer to ->allnext from last allocated device_node
149 * @fpsize: Size of the node path up at the current depth. 148 * @fpsize: Size of the node path up at the current depth.
150 */ 149 */
151static void * unflatten_dt_node(void *blob, 150static void * unflatten_dt_node(void *blob,
152 void *mem, 151 void *mem,
153 int *poffset, 152 int *poffset,
154 struct device_node *dad, 153 struct device_node *dad,
155 struct device_node ***allnextpp, 154 struct device_node **nodepp,
156 unsigned long fpsize) 155 unsigned long fpsize,
156 bool dryrun)
157{ 157{
158 const __be32 *p; 158 const __be32 *p;
159 struct device_node *np; 159 struct device_node *np;
@@ -200,7 +200,7 @@ static void * unflatten_dt_node(void *blob,
200 200
201 np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl, 201 np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
202 __alignof__(struct device_node)); 202 __alignof__(struct device_node));
203 if (allnextpp) { 203 if (!dryrun) {
204 char *fn; 204 char *fn;
205 of_node_init(np); 205 of_node_init(np);
206 np->full_name = fn = ((char *)np) + sizeof(*np); 206 np->full_name = fn = ((char *)np) + sizeof(*np);
@@ -222,8 +222,6 @@ static void * unflatten_dt_node(void *blob,
222 memcpy(fn, pathp, l); 222 memcpy(fn, pathp, l);
223 223
224 prev_pp = &np->properties; 224 prev_pp = &np->properties;
225 **allnextpp = np;
226 *allnextpp = &np->allnext;
227 if (dad != NULL) { 225 if (dad != NULL) {
228 np->parent = dad; 226 np->parent = dad;
229 /* we temporarily use the next field as `last_child'*/ 227 /* we temporarily use the next field as `last_child'*/
@@ -254,7 +252,7 @@ static void * unflatten_dt_node(void *blob,
254 has_name = 1; 252 has_name = 1;
255 pp = unflatten_dt_alloc(&mem, sizeof(struct property), 253 pp = unflatten_dt_alloc(&mem, sizeof(struct property),
256 __alignof__(struct property)); 254 __alignof__(struct property));
257 if (allnextpp) { 255 if (!dryrun) {
258 /* We accept flattened tree phandles either in 256 /* We accept flattened tree phandles either in
259 * ePAPR-style "phandle" properties, or the 257 * ePAPR-style "phandle" properties, or the
260 * legacy "linux,phandle" properties. If both 258 * legacy "linux,phandle" properties. If both
@@ -296,7 +294,7 @@ static void * unflatten_dt_node(void *blob,
296 sz = (pa - ps) + 1; 294 sz = (pa - ps) + 1;
297 pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz, 295 pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
298 __alignof__(struct property)); 296 __alignof__(struct property));
299 if (allnextpp) { 297 if (!dryrun) {
300 pp->name = "name"; 298 pp->name = "name";
301 pp->length = sz; 299 pp->length = sz;
302 pp->value = pp + 1; 300 pp->value = pp + 1;
@@ -308,7 +306,7 @@ static void * unflatten_dt_node(void *blob,
308 (char *)pp->value); 306 (char *)pp->value);
309 } 307 }
310 } 308 }
311 if (allnextpp) { 309 if (!dryrun) {
312 *prev_pp = NULL; 310 *prev_pp = NULL;
313 np->name = of_get_property(np, "name", NULL); 311 np->name = of_get_property(np, "name", NULL);
314 np->type = of_get_property(np, "device_type", NULL); 312 np->type = of_get_property(np, "device_type", NULL);
@@ -324,11 +322,13 @@ static void * unflatten_dt_node(void *blob,
324 if (depth < 0) 322 if (depth < 0)
325 depth = 0; 323 depth = 0;
326 while (*poffset > 0 && depth > old_depth) 324 while (*poffset > 0 && depth > old_depth)
327 mem = unflatten_dt_node(blob, mem, poffset, np, allnextpp, 325 mem = unflatten_dt_node(blob, mem, poffset, np, NULL,
328 fpsize); 326 fpsize, dryrun);
329 327
330 if (*poffset < 0 && *poffset != -FDT_ERR_NOTFOUND) 328 if (*poffset < 0 && *poffset != -FDT_ERR_NOTFOUND)
331 pr_err("unflatten: error %d processing FDT\n", *poffset); 329 pr_err("unflatten: error %d processing FDT\n", *poffset);
330 if (nodepp)
331 *nodepp = np;
332 332
333 return mem; 333 return mem;
334} 334}
@@ -352,7 +352,6 @@ static void __unflatten_device_tree(void *blob,
352 unsigned long size; 352 unsigned long size;
353 int start; 353 int start;
354 void *mem; 354 void *mem;
355 struct device_node **allnextp = mynodes;
356 355
357 pr_debug(" -> unflatten_device_tree()\n"); 356 pr_debug(" -> unflatten_device_tree()\n");
358 357
@@ -373,7 +372,7 @@ static void __unflatten_device_tree(void *blob,
373 372
374 /* First pass, scan for size */ 373 /* First pass, scan for size */
375 start = 0; 374 start = 0;
376 size = (unsigned long)unflatten_dt_node(blob, NULL, &start, NULL, NULL, 0); 375 size = (unsigned long)unflatten_dt_node(blob, NULL, &start, NULL, NULL, 0, true);
377 size = ALIGN(size, 4); 376 size = ALIGN(size, 4);
378 377
379 pr_debug(" size is %lx, allocating...\n", size); 378 pr_debug(" size is %lx, allocating...\n", size);
@@ -388,11 +387,10 @@ static void __unflatten_device_tree(void *blob,
388 387
389 /* Second pass, do actual unflattening */ 388 /* Second pass, do actual unflattening */
390 start = 0; 389 start = 0;
391 unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0); 390 unflatten_dt_node(blob, mem, &start, NULL, mynodes, 0, false);
392 if (be32_to_cpup(mem + size) != 0xdeadbeef) 391 if (be32_to_cpup(mem + size) != 0xdeadbeef)
393 pr_warning("End of tree marker overwritten: %08x\n", 392 pr_warning("End of tree marker overwritten: %08x\n",
394 be32_to_cpup(mem + size)); 393 be32_to_cpup(mem + size));
395 *allnextp = NULL;
396 394
397 pr_debug(" <- unflatten_device_tree()\n"); 395 pr_debug(" <- unflatten_device_tree()\n");
398} 396}
@@ -1041,7 +1039,7 @@ bool __init early_init_dt_scan(void *params)
1041 */ 1039 */
1042void __init unflatten_device_tree(void) 1040void __init unflatten_device_tree(void)
1043{ 1041{
1044 __unflatten_device_tree(initial_boot_params, &of_allnodes, 1042 __unflatten_device_tree(initial_boot_params, &of_root,
1045 early_init_dt_alloc_memory_arch); 1043 early_init_dt_alloc_memory_arch);
1046 1044
1047 /* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */ 1045 /* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */