diff options
author | Stephen Neuendorffer <stephen.neuendorffer@xilinx.com> | 2010-11-18 18:55:00 -0500 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-12-29 18:53:55 -0500 |
commit | a40d6c4cf12d87980c10b230df435d0f56adc40b (patch) | |
tree | 0e0ce85229e37f78fae2347df301d576f2517ef5 /drivers/of | |
parent | 9706a36e35c4ce04f28a62cfe1205b4e3b0dd13c (diff) |
of/flattree: Refactor unflatten_dt_node
unflatten_dt_node is a helper function that does most of the work to
convert a device tree blob into tree of device nodes. This code
now uses a passed-in blob instead of using the single boot-time blob,
allowing it to be called in more contexts.
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.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 10eab21076ea..cf74e546faf2 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
@@ -206,7 +206,7 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) | |||
206 | return of_fdt_is_compatible(initial_boot_params, node, compat); | 206 | return of_fdt_is_compatible(initial_boot_params, node, compat); |
207 | } | 207 | } |
208 | 208 | ||
209 | static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, | 209 | static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size, |
210 | unsigned long align) | 210 | unsigned long align) |
211 | { | 211 | { |
212 | void *res; | 212 | void *res; |
@@ -220,16 +220,18 @@ static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, | |||
220 | 220 | ||
221 | /** | 221 | /** |
222 | * unflatten_dt_node - Alloc and populate a device_node from the flat tree | 222 | * unflatten_dt_node - Alloc and populate a device_node from the flat tree |
223 | * @blob: The parent device tree blob | ||
223 | * @p: pointer to node in flat tree | 224 | * @p: pointer to node in flat tree |
224 | * @dad: Parent struct device_node | 225 | * @dad: Parent struct device_node |
225 | * @allnextpp: pointer to ->allnext from last allocated device_node | 226 | * @allnextpp: pointer to ->allnext from last allocated device_node |
226 | * @fpsize: Size of the node path up at the current depth. | 227 | * @fpsize: Size of the node path up at the current depth. |
227 | */ | 228 | */ |
228 | unsigned long __init unflatten_dt_node(unsigned long mem, | 229 | unsigned long unflatten_dt_node(struct boot_param_header *blob, |
229 | unsigned long *p, | 230 | unsigned long mem, |
230 | struct device_node *dad, | 231 | unsigned long *p, |
231 | struct device_node ***allnextpp, | 232 | struct device_node *dad, |
232 | unsigned long fpsize) | 233 | struct device_node ***allnextpp, |
234 | unsigned long fpsize) | ||
233 | { | 235 | { |
234 | struct device_node *np; | 236 | struct device_node *np; |
235 | struct property *pp, **prev_pp = NULL; | 237 | struct property *pp, **prev_pp = NULL; |
@@ -325,10 +327,10 @@ unsigned long __init unflatten_dt_node(unsigned long mem, | |||
325 | sz = be32_to_cpup((__be32 *)(*p)); | 327 | sz = be32_to_cpup((__be32 *)(*p)); |
326 | noff = be32_to_cpup((__be32 *)((*p) + 4)); | 328 | noff = be32_to_cpup((__be32 *)((*p) + 4)); |
327 | *p += 8; | 329 | *p += 8; |
328 | if (be32_to_cpu(initial_boot_params->version) < 0x10) | 330 | if (be32_to_cpu(blob->version) < 0x10) |
329 | *p = ALIGN(*p, sz >= 8 ? 8 : 4); | 331 | *p = ALIGN(*p, sz >= 8 ? 8 : 4); |
330 | 332 | ||
331 | pname = of_fdt_get_string(initial_boot_params, noff); | 333 | pname = of_fdt_get_string(blob, noff); |
332 | if (pname == NULL) { | 334 | if (pname == NULL) { |
333 | pr_info("Can't find property name in list !\n"); | 335 | pr_info("Can't find property name in list !\n"); |
334 | break; | 336 | break; |
@@ -407,7 +409,8 @@ unsigned long __init unflatten_dt_node(unsigned long mem, | |||
407 | if (tag == OF_DT_NOP) | 409 | if (tag == OF_DT_NOP) |
408 | *p += 4; | 410 | *p += 4; |
409 | else | 411 | else |
410 | mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize); | 412 | mem = unflatten_dt_node(blob, mem, p, np, allnextpp, |
413 | fpsize); | ||
411 | tag = be32_to_cpup((__be32 *)(*p)); | 414 | tag = be32_to_cpup((__be32 *)(*p)); |
412 | } | 415 | } |
413 | if (tag != OF_DT_END_NODE) { | 416 | if (tag != OF_DT_END_NODE) { |
@@ -599,7 +602,8 @@ void __init unflatten_device_tree(void) | |||
599 | /* First pass, scan for size */ | 602 | /* First pass, scan for size */ |
600 | start = ((unsigned long)initial_boot_params) + | 603 | start = ((unsigned long)initial_boot_params) + |
601 | be32_to_cpu(initial_boot_params->off_dt_struct); | 604 | be32_to_cpu(initial_boot_params->off_dt_struct); |
602 | size = unflatten_dt_node(0, &start, NULL, NULL, 0); | 605 | size = unflatten_dt_node(initial_boot_params, 0, &start, |
606 | NULL, NULL, 0); | ||
603 | size = (size | 3) + 1; | 607 | size = (size | 3) + 1; |
604 | 608 | ||
605 | pr_debug(" size is %lx, allocating...\n", size); | 609 | pr_debug(" size is %lx, allocating...\n", size); |
@@ -616,7 +620,8 @@ void __init unflatten_device_tree(void) | |||
616 | /* Second pass, do actual unflattening */ | 620 | /* Second pass, do actual unflattening */ |
617 | start = ((unsigned long)initial_boot_params) + | 621 | start = ((unsigned long)initial_boot_params) + |
618 | be32_to_cpu(initial_boot_params->off_dt_struct); | 622 | be32_to_cpu(initial_boot_params->off_dt_struct); |
619 | unflatten_dt_node(mem, &start, NULL, &allnextp, 0); | 623 | unflatten_dt_node(initial_boot_params, mem, &start, |
624 | NULL, &allnextp, 0); | ||
620 | if (be32_to_cpup((__be32 *)start) != OF_DT_END) | 625 | if (be32_to_cpup((__be32 *)start) != OF_DT_END) |
621 | pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start)); | 626 | pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start)); |
622 | if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef) | 627 | if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef) |