summaryrefslogtreecommitdiff
path: root/drivers/of
diff options
context:
space:
mode:
authorRob Herring <rob.herring@calxeda.com>2013-08-26 11:22:45 -0500
committerRob Herring <rob.herring@calxeda.com>2013-10-09 11:38:03 -0500
commita8bf7527a2e17ccf1366e67f6ac728327ca34c40 (patch)
tree5454fe053edb11d610d0fd35f4abeff88e076705 /drivers/of
parentbbf28b505ac2dd923b9051ca5031cf87bf7c40cc (diff)
of: create unflatten_and_copy_device_tree
Several architectures using DT support built-in dtb's in the init section. These platforms need to copy the dtb from init since the strings are referenced after unflattening. Every arch has their own copying routine which do the same thing. Create a common function, unflatten_and_copy_device_tree, to copy the dtb when unflattening the dtb. Signed-off-by: Rob Herring <rob.herring@calxeda.com> Acked-by: Grant Likely <grant.likely@linaro.org>
Diffstat (limited to 'drivers/of')
-rw-r--r--drivers/of/fdt.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 229dd9d69e18..51776166d2b0 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -802,6 +802,30 @@ void __init unflatten_device_tree(void)
of_alias_scan(early_init_dt_alloc_memory_arch);
}
+/**
+ * unflatten_and_copy_device_tree - copy and create tree of device_nodes from flat blob
+ *
+ * Copies and unflattens the device-tree passed by the firmware, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used. This should only be used when the FDT memory has not been
+ * reserved such is the case when the FDT is built-in to the kernel init
+ * section. If the FDT memory is reserved already then unflatten_device_tree
+ * should be used instead.
+ */
+void __init unflatten_and_copy_device_tree(void)
+{
+ int size = __be32_to_cpu(initial_boot_params->totalsize);
+ void *dt = early_init_dt_alloc_memory_arch(size,
+ __alignof__(struct boot_param_header));
+
+ if (dt) {
+ memcpy(dt, initial_boot_params, size);
+ initial_boot_params = dt;
+ }
+ unflatten_device_tree();
+}
+
#endif /* CONFIG_OF_EARLY_FLATTREE */
/* Feed entire flattened device tree into the random pool */