summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/of/fdt.c24
-rw-r--r--include/linux/of_fdt.h2
2 files changed, 26 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 */
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index a478c62a2aab..58c28a8cc257 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -118,9 +118,11 @@ extern int early_init_dt_scan_root(unsigned long node, const char *uname,
/* Other Prototypes */
extern void unflatten_device_tree(void);
+extern void unflatten_and_copy_device_tree(void);
extern void early_init_devtree(void *);
#else /* CONFIG_OF_FLATTREE */
static inline void unflatten_device_tree(void) {}
+static inline void unflatten_and_copy_device_tree(void) {}
#endif /* CONFIG_OF_FLATTREE */
#endif /* __ASSEMBLY__ */