These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / of / fdt.c
index d91f721..655f79d 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/initrd.h>
 #include <linux/memblock.h>
+#include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
 #include <linux/of_reserved_mem.h>
@@ -164,11 +165,14 @@ static void *unflatten_dt_alloc(void **mem, unsigned long size,
  * unflatten_dt_node - Alloc and populate a device_node from the flat tree
  * @blob: The parent device tree blob
  * @mem: Memory chunk to use for allocating device nodes and properties
- * @p: pointer to node in flat tree
+ * @poffset: pointer to node in flat tree
  * @dad: Parent struct device_node
+ * @nodepp: The device_node tree created by the call
  * @fpsize: Size of the node path up at the current depth.
+ * @dryrun: If true, do not allocate device nodes but still calculate needed
+ * memory size
  */
-static void * unflatten_dt_node(void *blob,
+static void * unflatten_dt_node(const void *blob,
                                void *mem,
                                int *poffset,
                                struct device_node *dad,
@@ -181,7 +185,7 @@ static void * unflatten_dt_node(void *blob,
        struct property *pp, **prev_pp = NULL;
        const char *pathp;
        unsigned int l, allocl;
-       static int depth = 0;
+       static int depth;
        int old_depth;
        int offset;
        int has_name = 0;
@@ -378,7 +382,7 @@ static void * unflatten_dt_node(void *blob,
  * @dt_alloc: An allocator that provides a virtual address to memory
  * for the resulting tree
  */
-static void __unflatten_device_tree(void *blob,
+static void __unflatten_device_tree(const void *blob,
                             struct device_node **mynodes,
                             void * (*dt_alloc)(u64 size, u64 align))
 {
@@ -433,6 +437,8 @@ static void *kernel_tree_alloc(u64 size, u64 align)
        return kzalloc(size, GFP_KERNEL);
 }
 
+static DEFINE_MUTEX(of_fdt_unflatten_mutex);
+
 /**
  * of_fdt_unflatten_tree - create tree of device_nodes from flat blob
  *
@@ -441,10 +447,12 @@ static void *kernel_tree_alloc(u64 size, u64 align)
  * pointers of the nodes so the normal device-tree walking functions
  * can be used.
  */
-void of_fdt_unflatten_tree(unsigned long *blob,
+void of_fdt_unflatten_tree(const unsigned long *blob,
                        struct device_node **mynodes)
 {
+       mutex_lock(&of_fdt_unflatten_mutex);
        __unflatten_device_tree(blob, mynodes, &kernel_tree_alloc);
+       mutex_unlock(&of_fdt_unflatten_mutex);
 }
 EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree);
 
@@ -580,11 +588,6 @@ void __init early_init_fdt_scan_reserved_mem(void)
        if (!initial_boot_params)
                return;
 
-       /* Reserve the dtb region */
-       early_init_dt_reserve_memory_arch(__pa(initial_boot_params),
-                                         fdt_totalsize(initial_boot_params),
-                                         0);
-
        /* Process header /memreserve/ fields */
        for (n = 0; ; n++) {
                fdt_get_mem_rsv(initial_boot_params, n, &base, &size);
@@ -597,6 +600,20 @@ void __init early_init_fdt_scan_reserved_mem(void)
        fdt_init_reserved_mem();
 }
 
+/**
+ * early_init_fdt_reserve_self() - reserve the memory used by the FDT blob
+ */
+void __init early_init_fdt_reserve_self(void)
+{
+       if (!initial_boot_params)
+               return;
+
+       /* Reserve the dtb region */
+       early_init_dt_reserve_memory_arch(__pa(initial_boot_params),
+                                         fdt_totalsize(initial_boot_params),
+                                         0);
+}
+
 /**
  * of_scan_flat_dt - scan flattened tree blob and call callback on each.
  * @it: callback function
@@ -801,20 +818,24 @@ static int __init early_init_dt_scan_chosen_serial(void)
        if (!p || !l)
                return -ENOENT;
 
+       /* Remove console options if present */
+       l = strchrnul(p, ':') - p;
+
        /* Get the node specified by stdout-path */
-       offset = fdt_path_offset(fdt, p);
+       offset = fdt_path_offset_namelen(fdt, p, l);
        if (offset < 0)
                return -ENODEV;
 
        while (match->compatible[0]) {
-               unsigned long addr;
+               u64 addr;
+
                if (fdt_node_check_compatible(fdt, offset, match->compatible)) {
                        match++;
                        continue;
                }
 
                addr = fdt_translate_address(fdt, offset);
-               if (!addr)
+               if (addr == OF_BAD_ADDR)
                        return -ENXIO;
 
                of_setup_earlycon(addr, match->data);
@@ -1017,13 +1038,24 @@ void * __init __weak early_init_dt_alloc_memory_arch(u64 size, u64 align)
        return __va(memblock_alloc(size, align));
 }
 #else
+void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+       WARN_ON(1);
+}
+
 int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
                                        phys_addr_t size, bool nomap)
 {
-       pr_err("Reserved memory not supported, ignoring range 0x%pa - 0x%pa%s\n",
+       pr_err("Reserved memory not supported, ignoring range %pa - %pa%s\n",
                  &base, &size, nomap ? " (nomap)" : "");
        return -ENOSYS;
 }
+
+void * __init __weak early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+       WARN_ON(1);
+       return NULL;
+}
 #endif
 
 bool __init early_init_dt_verify(void *params)