aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/fdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of/fdt.c')
-rw-r--r--drivers/of/fdt.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 6852ecf6d1e1..43d236cbc17b 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -9,6 +9,8 @@
9 * version 2 as published by the Free Software Foundation. 9 * version 2 as published by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/kernel.h>
13#include <linux/lmb.h>
12#include <linux/of.h> 14#include <linux/of.h>
13#include <linux/of_fdt.h> 15#include <linux/of_fdt.h>
14 16
@@ -366,3 +368,53 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
366 *p += 4; 368 *p += 4;
367 return mem; 369 return mem;
368} 370}
371
372/**
373 * unflatten_device_tree - create tree of device_nodes from flat blob
374 *
375 * unflattens the device-tree passed by the firmware, creating the
376 * tree of struct device_node. It also fills the "name" and "type"
377 * pointers of the nodes so the normal device-tree walking functions
378 * can be used.
379 */
380void __init unflatten_device_tree(void)
381{
382 unsigned long start, mem, size;
383 struct device_node **allnextp = &allnodes;
384
385 pr_debug(" -> unflatten_device_tree()\n");
386
387 /* First pass, scan for size */
388 start = ((unsigned long)initial_boot_params) +
389 initial_boot_params->off_dt_struct;
390 size = unflatten_dt_node(0, &start, NULL, NULL, 0);
391 size = (size | 3) + 1;
392
393 pr_debug(" size is %lx, allocating...\n", size);
394
395 /* Allocate memory for the expanded device tree */
396 mem = lmb_alloc(size + 4, __alignof__(struct device_node));
397 mem = (unsigned long) __va(mem);
398
399 ((u32 *)mem)[size / 4] = 0xdeadbeef;
400
401 pr_debug(" unflattening %lx...\n", mem);
402
403 /* Second pass, do actual unflattening */
404 start = ((unsigned long)initial_boot_params) +
405 initial_boot_params->off_dt_struct;
406 unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
407 if (*((u32 *)start) != OF_DT_END)
408 pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
409 if (((u32 *)mem)[size / 4] != 0xdeadbeef)
410 pr_warning("End of tree marker overwritten: %08x\n",
411 ((u32 *)mem)[size / 4]);
412 *allnextp = NULL;
413
414 /* Get pointer to OF "/chosen" node for use everywhere */
415 of_chosen = of_find_node_by_path("/chosen");
416 if (of_chosen == NULL)
417 of_chosen = of_find_node_by_path("/chosen@0");
418
419 pr_debug(" <- unflatten_device_tree()\n");
420}