diff options
author | Grant Likely <grant.likely@linaro.org> | 2014-10-03 11:28:27 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@linaro.org> | 2014-11-04 08:29:38 -0500 |
commit | 5063e25a302e6a83f6590d9a06bd5f6400b17430 (patch) | |
tree | bd6aafd28fb65ea19cd1535fd9a53263b42a68c0 /drivers/of/fdt.c | |
parent | e7a00e4210e4cc980e3ba67ec7301af54061d14b (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.c | 30 |
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 | */ |
151 | static void * unflatten_dt_node(void *blob, | 150 | static 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 | */ |
1042 | void __init unflatten_device_tree(void) | 1040 | void __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 */ |