diff options
author | 2014-10-03 16:28:27 +0100 | |
---|---|---|
committer | 2014-11-04 13:29:38 +0000 | |
commit | 5063e25a302e6a83f6590d9a06bd5f6400b17430 (patch) | |
tree | bd6aafd28fb65ea19cd1535fd9a53263b42a68c0 /drivers/of/fdt.c | |
parent | of: introduce of_property_read_s32 (diff) | |
download | linux-5063e25a302e6a83f6590d9a06bd5f6400b17430.tar.gz linux-5063e25a302e6a83f6590d9a06bd5f6400b17430.tar.bz2 linux-5063e25a302e6a83f6590d9a06bd5f6400b17430.zip |
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, * @mem: Memory chunk to use for allocating device nodes and properties * @p: pointer to node in flat tree * @dad: Parent struct device_node - * @allnextpp: pointer to ->allnext from last allocated device_node * @fpsize: Size of the node path up at the current depth. */ static void * unflatten_dt_node(void *blob, void *mem, int *poffset, struct device_node *dad, - struct device_node ***allnextpp, - unsigned long fpsize) + struct device_node **nodepp, + unsigned long fpsize, + bool dryrun) { const __be32 *p; struct device_node *np; @@ -200,7 +200,7 @@ static void * unflatten_dt_node(void *blob, np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl, __alignof__(struct device_node)); - if (allnextpp) { + if (!dryrun) { char *fn; of_node_init(np); np->full_name = fn = ((char *)np) + sizeof(*np); @@ -222,8 +222,6 @@ static void * unflatten_dt_node(void *blob, memcpy(fn, pathp, l); prev_pp = &np->properties; - **allnextpp = np; - *allnextpp = &np->allnext; if (dad != NULL) { np->parent = dad; /* we temporarily use the next field as `last_child'*/ @@ -254,7 +252,7 @@ static void * unflatten_dt_node(void *blob, has_name = 1; pp = unflatten_dt_alloc(&mem, sizeof(struct property), __alignof__(struct property)); - if (allnextpp) { + if (!dryrun) { /* We accept flattened tree phandles either in * ePAPR-style "phandle" properties, or the * legacy "linux,phandle" properties. If both @@ -296,7 +294,7 @@ static void * unflatten_dt_node(void *blob, sz = (pa - ps) + 1; pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz, __alignof__(struct property)); - if (allnextpp) { + if (!dryrun) { pp->name = "name"; pp->length = sz; pp->value = pp + 1; @@ -308,7 +306,7 @@ static void * unflatten_dt_node(void *blob, (char *)pp->value); } } - if (allnextpp) { + if (!dryrun) { *prev_pp = NULL; np->name = of_get_property(np, "name", NULL); np->type = of_get_property(np, "device_type", NULL); @@ -324,11 +322,13 @@ static void * unflatten_dt_node(void *blob, if (depth < 0) depth = 0; while (*poffset > 0 && depth > old_depth) - mem = unflatten_dt_node(blob, mem, poffset, np, allnextpp, - fpsize); + mem = unflatten_dt_node(blob, mem, poffset, np, NULL, + fpsize, dryrun); if (*poffset < 0 && *poffset != -FDT_ERR_NOTFOUND) pr_err("unflatten: error %d processing FDT\n", *poffset); + if (nodepp) + *nodepp = np; return mem; } @@ -352,7 +352,6 @@ static void __unflatten_device_tree(void *blob, unsigned long size; int start; void *mem; - struct device_node **allnextp = mynodes; pr_debug(" -> unflatten_device_tree()\n"); @@ -373,7 +372,7 @@ static void __unflatten_device_tree(void *blob, /* First pass, scan for size */ start = 0; - size = (unsigned long)unflatten_dt_node(blob, NULL, &start, NULL, NULL, 0); + size = (unsigned long)unflatten_dt_node(blob, NULL, &start, NULL, NULL, 0, true); size = ALIGN(size, 4); pr_debug(" size is %lx, allocating...\n", size); @@ -388,11 +387,10 @@ static void __unflatten_device_tree(void *blob, /* Second pass, do actual unflattening */ start = 0; - unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0); + unflatten_dt_node(blob, mem, &start, NULL, mynodes, 0, false); if (be32_to_cpup(mem + size) != 0xdeadbeef) pr_warning("End of tree marker overwritten: %08x\n", be32_to_cpup(mem + size)); - *allnextp = NULL; pr_debug(" <- unflatten_device_tree()\n"); } @@ -1041,7 +1039,7 @@ bool __init early_init_dt_scan(void *params) */ void __init unflatten_device_tree(void) { - __unflatten_device_tree(initial_boot_params, &of_allnodes, + __unflatten_device_tree(initial_boot_params, &of_root, early_init_dt_alloc_memory_arch); /* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */ |