OSDN Git Service

Merge branch 'devicetree/arm-next' of git://git.secretlab.ca/git/linux-2.6 into devel...
authorRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 24 May 2011 23:08:17 +0000 (00:08 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 24 May 2011 23:08:17 +0000 (00:08 +0100)
17 files changed:
Documentation/arm/Booting
Documentation/devicetree/booting-without-of.txt
arch/arm/Kconfig
arch/arm/include/asm/mach/arch.h
arch/arm/include/asm/prom.h [new file with mode: 0644]
arch/arm/include/asm/setup.h
arch/arm/kernel/Makefile
arch/arm/kernel/devtree.c [new file with mode: 0644]
arch/arm/kernel/head-common.S
arch/arm/kernel/head.S
arch/arm/kernel/setup.c
arch/arm/mm/init.c
arch/microblaze/kernel/prom.c
arch/mips/include/asm/prom.h
arch/mips/kernel/prom.c
arch/powerpc/kernel/prom.c
drivers/of/fdt.c

index 7685029..4e686a2 100644 (file)
@@ -65,13 +65,19 @@ looks at the connected hardware is beyond the scope of this document.
 The boot loader must ultimately be able to provide a MACH_TYPE_xxx
 value to the kernel. (see linux/arch/arm/tools/mach-types).
 
-
-4. Setup the kernel tagged list
--------------------------------
+4. Setup boot data
+------------------
 
 Existing boot loaders:         OPTIONAL, HIGHLY RECOMMENDED
 New boot loaders:              MANDATORY
 
+The boot loader must provide either a tagged list or a dtb image for
+passing configuration data to the kernel.  The physical address of the
+boot data is passed to the kernel in register r2.
+
+4a. Setup the kernel tagged list
+--------------------------------
+
 The boot loader must create and initialise the kernel tagged list.
 A valid tagged list starts with ATAG_CORE and ends with ATAG_NONE.
 The ATAG_CORE tag may or may not be empty.  An empty ATAG_CORE tag
@@ -101,6 +107,24 @@ The tagged list must be placed in a region of memory where neither
 the kernel decompressor nor initrd 'bootp' program will overwrite
 it.  The recommended placement is in the first 16KiB of RAM.
 
+4b. Setup the device tree
+-------------------------
+
+The boot loader must load a device tree image (dtb) into system ram
+at a 64bit aligned address and initialize it with the boot data.  The
+dtb format is documented in Documentation/devicetree/booting-without-of.txt.
+The kernel will look for the dtb magic value of 0xd00dfeed at the dtb
+physical address to determine if a dtb has been passed instead of a
+tagged list.
+
+The boot loader must pass at a minimum the size and location of the
+system memory, and the root filesystem location.  The dtb must be
+placed in a region of memory where the kernel decompressor will not
+overwrite it.  The recommended placement is in the first 16KiB of RAM
+with the caveat that it may not be located at physical address 0 since
+the kernel interprets a value of 0 in r2 to mean neither a tagged list
+nor a dtb were passed.
+
 5. Calling the kernel image
 ---------------------------
 
@@ -125,7 +149,8 @@ In either case, the following conditions must be met:
 - CPU register settings
   r0 = 0,
   r1 = machine type number discovered in (3) above.
-  r2 = physical address of tagged list in system RAM.
+  r2 = physical address of tagged list in system RAM, or
+       physical address of device tree block (dtb) in system RAM
 
 - CPU mode
   All forms of interrupts must be disabled (IRQs and FIQs)
index 50619a0..7c1329d 100644 (file)
@@ -12,8 +12,9 @@ Table of Contents
 =================
 
   I - Introduction
-    1) Entry point for arch/powerpc
-    2) Entry point for arch/x86
+    1) Entry point for arch/arm
+    2) Entry point for arch/powerpc
+    3) Entry point for arch/x86
 
   II - The DT block format
     1) Header
@@ -148,7 +149,46 @@ upgrades without significantly impacting the kernel code or cluttering
 it with special cases.
 
 
-1) Entry point for arch/powerpc
+1) Entry point for arch/arm
+---------------------------
+
+   There is one single entry point to the kernel, at the start
+   of the kernel image. That entry point supports two calling
+   conventions.  A summary of the interface is described here.  A full
+   description of the boot requirements is documented in
+   Documentation/arm/Booting
+
+        a) ATAGS interface.  Minimal information is passed from firmware
+        to the kernel with a tagged list of predefined parameters.
+
+                r0 : 0
+
+                r1 : Machine type number
+
+                r2 : Physical address of tagged list in system RAM
+
+        b) Entry with a flattened device-tree block.  Firmware loads the
+        physical address of the flattened device tree block (dtb) into r2,
+        r1 is not used, but it is considered good practise to use a valid
+        machine number as described in Documentation/arm/Booting.
+
+                r0 : 0
+
+                r1 : Valid machine type number.  When using a device tree,
+                a single machine type number will often be assigned to
+                represent a class or family of SoCs.
+
+                r2 : physical pointer to the device-tree block
+                (defined in chapter II) in RAM.  Device tree can be located
+                anywhere in system RAM, but it should be aligned on a 64 bit
+                boundary.
+
+   The kernel will differentiate between ATAGS and device tree booting by
+   reading the memory pointed to by r2 and looking for either the flattened
+   device tree block magic value (0xd00dfeed) or the ATAG_CORE value at
+   offset 0x4 from r2 (0x54410001).
+
+2) Entry point for arch/powerpc
 -------------------------------
 
    There is one single entry point to the kernel, at the start
@@ -226,7 +266,7 @@ it with special cases.
   cannot support both configurations with Book E and configurations
   with classic Powerpc architectures.
 
-2) Entry point for arch/x86
+3) Entry point for arch/x86
 -------------------------------
 
   There is one single 32bit entry point to the kernel at code32_start,
index 7275009..3bc1a58 100644 (file)
@@ -1683,6 +1683,13 @@ endmenu
 
 menu "Boot options"
 
+config USE_OF
+       bool "Flattened Device Tree support"
+       select OF
+       select OF_EARLY_FLATTREE
+       help
+         Include support for flattened device tree machine descriptions.
+
 # Compressed boot loader in ROM.  Yes, we really want to ask about
 # TEXT and BSS so we preserve their values in the config files.
 config ZBOOT_ROM_TEXT
index bf13b81..946f4d7 100644 (file)
@@ -18,6 +18,8 @@ struct machine_desc {
        unsigned int            nr;             /* architecture number  */
        const char              *name;          /* architecture name    */
        unsigned long           boot_params;    /* tagged list          */
+       const char              **dt_compat;    /* array of device tree
+                                                * 'compatible' strings */
 
        unsigned int            nr_irqs;        /* number of IRQs */
 
@@ -48,6 +50,13 @@ struct machine_desc {
 extern struct machine_desc *machine_desc;
 
 /*
+ * Machine type table - also only accessible during boot
+ */
+extern struct machine_desc __arch_info_begin[], __arch_info_end[];
+#define for_each_machine_desc(p)                       \
+       for (p = __arch_info_begin; p < __arch_info_end; p++)
+
+/*
  * Set of macros to define architecture features.  This is built into
  * a table by the linker.
  */
diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h
new file mode 100644 (file)
index 0000000..11b8708
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  arch/arm/include/asm/prom.h
+ *
+ *  Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef __ASMARM_PROM_H
+#define __ASMARM_PROM_H
+
+#ifdef CONFIG_OF
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+static inline void irq_dispose_mapping(unsigned int virq)
+{
+       return;
+}
+
+extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys);
+extern void arm_dt_memblock_reserve(void);
+
+#else /* CONFIG_OF */
+
+static inline struct machine_desc *setup_machine_fdt(unsigned int dt_phys)
+{
+       return NULL;
+}
+
+static inline void arm_dt_memblock_reserve(void) { }
+
+#endif /* CONFIG_OF */
+#endif /* ASMARM_PROM_H */
index 95176af..ee2ad8a 100644 (file)
@@ -217,6 +217,10 @@ extern struct meminfo meminfo;
 #define bank_phys_end(bank)    ((bank)->start + (bank)->size)
 #define bank_phys_size(bank)   (bank)->size
 
+extern int arm_add_memory(phys_addr_t start, unsigned long size);
+extern void early_print(const char *str, ...);
+extern void dump_machine_table(void);
+
 #endif  /*  __KERNEL__  */
 
 #endif
index 8d95446..908c78c 100644 (file)
@@ -44,6 +44,7 @@ obj-$(CONFIG_ARM_THUMBEE)     += thumbee.o
 obj-$(CONFIG_KGDB)             += kgdb.o
 obj-$(CONFIG_ARM_UNWIND)       += unwind.o
 obj-$(CONFIG_HAVE_TCM)         += tcm.o
+obj-$(CONFIG_OF)               += devtree.o
 obj-$(CONFIG_CRASH_DUMP)       += crash_dump.o
 obj-$(CONFIG_SWP_EMULATE)      += swp_emulate.o
 CFLAGS_swp_emulate.o           := -Wa,-march=armv7-a
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
new file mode 100644 (file)
index 0000000..a701e42
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ *  linux/arch/arm/kernel/devtree.c
+ *
+ *  Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+       arm_add_memory(base, size);
+}
+
+void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+       return alloc_bootmem_align(size, align);
+}
+
+void __init arm_dt_memblock_reserve(void)
+{
+       u64 *reserve_map, base, size;
+
+       if (!initial_boot_params)
+               return;
+
+       /* Reserve the dtb region */
+       memblock_reserve(virt_to_phys(initial_boot_params),
+                        be32_to_cpu(initial_boot_params->totalsize));
+
+       /*
+        * Process the reserve map.  This will probably overlap the initrd
+        * and dtb locations which are already reserved, but overlaping
+        * doesn't hurt anything
+        */
+       reserve_map = ((void*)initial_boot_params) +
+                       be32_to_cpu(initial_boot_params->off_mem_rsvmap);
+       while (1) {
+               base = be64_to_cpup(reserve_map++);
+               size = be64_to_cpup(reserve_map++);
+               if (!size)
+                       break;
+               memblock_reserve(base, size);
+       }
+}
+
+/**
+ * setup_machine_fdt - Machine setup when an dtb was passed to the kernel
+ * @dt_phys: physical address of dt blob
+ *
+ * If a dtb was passed to the kernel in r2, then use it to choose the
+ * correct machine_desc and to setup the system.
+ */
+struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
+{
+       struct boot_param_header *devtree;
+       struct machine_desc *mdesc, *mdesc_best = NULL;
+       unsigned int score, mdesc_score = ~1;
+       unsigned long dt_root;
+       const char *model;
+
+       devtree = phys_to_virt(dt_phys);
+
+       /* check device tree validity */
+       if (be32_to_cpu(devtree->magic) != OF_DT_HEADER)
+               return NULL;
+
+       /* Search the mdescs for the 'best' compatible value match */
+       initial_boot_params = devtree;
+       dt_root = of_get_flat_dt_root();
+       for_each_machine_desc(mdesc) {
+               score = of_flat_dt_match(dt_root, mdesc->dt_compat);
+               if (score > 0 && score < mdesc_score) {
+                       mdesc_best = mdesc;
+                       mdesc_score = score;
+               }
+       }
+       if (!mdesc_best) {
+               const char *prop;
+               long size;
+
+               early_print("\nError: unrecognized/unsupported "
+                           "device tree compatible list:\n[ ");
+
+               prop = of_get_flat_dt_prop(dt_root, "compatible", &size);
+               while (size > 0) {
+                       early_print("'%s' ", prop);
+                       size -= strlen(prop) + 1;
+                       prop += strlen(prop) + 1;
+               }
+               early_print("]\n\n");
+
+               dump_machine_table(); /* does not return */
+       }
+
+       model = of_get_flat_dt_prop(dt_root, "model", NULL);
+       if (!model)
+               model = of_get_flat_dt_prop(dt_root, "compatible", NULL);
+       if (!model)
+               model = "<unknown>";
+       pr_info("Machine: %s, model: %s\n", mdesc_best->name, model);
+
+       /* Retrieve various information from the /chosen node */
+       of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
+       /* Initialize {size,address}-cells info */
+       of_scan_flat_dt(early_init_dt_scan_root, NULL);
+       /* Setup memory, calling early_init_dt_add_memory_arch */
+       of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+
+       /* Change machine number to match the mdesc we're using */
+       __machine_arch_type = mdesc_best->nr;
+
+       return mdesc_best;
+}
+
+/**
+ * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq#
+ *
+ * Currently the mapping mechanism is trivial; simple flat hwirq numbers are
+ * mapped 1:1 onto Linux irq numbers.  Cascaded irq controllers are not
+ * supported.
+ */
+unsigned int irq_create_of_mapping(struct device_node *controller,
+                                  const u32 *intspec, unsigned int intsize)
+{
+       return intspec[0];
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
index c84b57d..854bd22 100644 (file)
 #define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
 #define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2)
 
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define OF_DT_MAGIC 0xd00dfeed
+#else
+#define OF_DT_MAGIC 0xedfe0dd0 /* 0xd00dfeed in big-endian */
+#endif
+
 /*
  * Exception handling.  Something went wrong and we can't proceed.  We
  * ought to tell the user, but since we don't have any guarantee that
 
 /* Determine validity of the r2 atags pointer.  The heuristic requires
  * that the pointer be aligned, in the first 16k of physical RAM and
- * that the ATAG_CORE marker is first and present.  Future revisions
+ * that the ATAG_CORE marker is first and present.  If CONFIG_OF_FLATTREE
+ * is selected, then it will also accept a dtb pointer.  Future revisions
  * of this function may be more lenient with the physical address and
  * may also be able to move the ATAGS block if necessary.
  *
  * Returns:
- *  r2 either valid atags pointer, or zero
+ *  r2 either valid atags pointer, valid dtb pointer, or zero
  *  r5, r6 corrupted
  */
 __vet_atags:
        tst     r2, #0x3                        @ aligned?
        bne     1f
 
-       ldr     r5, [r2, #0]                    @ is first tag ATAG_CORE?
-       cmp     r5, #ATAG_CORE_SIZE
+       ldr     r5, [r2, #0]
+#ifdef CONFIG_OF_FLATTREE
+       ldr     r6, =OF_DT_MAGIC                @ is it a DTB?
+       cmp     r5, r6
+       beq     2f
+#endif
+       cmp     r5, #ATAG_CORE_SIZE             @ is first tag ATAG_CORE?
        cmpne   r5, #ATAG_CORE_SIZE_EMPTY
        bne     1f
        ldr     r5, [r2, #4]
@@ -49,7 +61,7 @@ __vet_atags:
        cmp     r5, r6
        bne     1f
 
-       mov     pc, lr                          @ atag pointer is ok
+2:     mov     pc, lr                          @ atag/dtb pointer is ok
 
 1:     mov     r2, #0
        mov     pc, lr
@@ -61,7 +73,7 @@ ENDPROC(__vet_atags)
  *
  *  r0  = cp#15 control register
  *  r1  = machine ID
- *  r2  = atags pointer
+ *  r2  = atags/dtb pointer
  *  r9  = processor ID
  */
        __INIT
index c9173cf..a5e5c5b 100644 (file)
@@ -59,7 +59,7 @@
  *
  * This is normally called from the decompressor code.  The requirements
  * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
- * r1 = machine nr, r2 = atags pointer.
+ * r1 = machine nr, r2 = atags or dtb pointer.
  *
  * This code is mostly position independent, so if you link the kernel at
  * 0xc0008000, you call this at __pa(0xc0008000).
@@ -91,7 +91,7 @@ ENTRY(stext)
 #endif
 
        /*
-        * r1 = machine no, r2 = atags,
+        * r1 = machine no, r2 = atags or dtb,
         * r8 = phys_offset, r9 = cpuid, r10 = procinfo
         */
        bl      __vet_atags
@@ -339,7 +339,7 @@ __secondary_data:
  *
  *  r0  = cp#15 control register
  *  r1  = machine ID
- *  r2  = atags pointer
+ *  r2  = atags or dtb pointer
  *  r4  = page table pointer
  *  r9  = processor ID
  *  r13 = *virtual* address to jump to upon completion
@@ -376,7 +376,7 @@ ENDPROC(__enable_mmu)
  *
  *  r0  = cp#15 control register
  *  r1  = machine ID
- *  r2  = atags pointer
+ *  r2  = atags or dtb pointer
  *  r9  = processor ID
  *  r13 = *virtual* address to jump to upon completion
  *
index 6dce209..ed11fb0 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/screen_info.h>
 #include <linux/init.h>
 #include <linux/kexec.h>
+#include <linux/of_fdt.h>
 #include <linux/crash_dump.h>
 #include <linux/root_dev.h>
 #include <linux/cpu.h>
@@ -42,6 +43,7 @@
 #include <asm/cachetype.h>
 #include <asm/tlbflush.h>
 
+#include <asm/prom.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
@@ -309,7 +311,7 @@ static void __init cacheid_init(void)
  */
 extern struct proc_info_list *lookup_processor_type(unsigned int);
 
-static void __init early_print(const char *str, ...)
+void __init early_print(const char *str, ...)
 {
        extern void printascii(const char *);
        char buf[256];
@@ -439,25 +441,12 @@ void cpu_init(void)
            : "r14");
 }
 
-static struct machine_desc * __init setup_machine(unsigned int nr)
+void __init dump_machine_table(void)
 {
-       extern struct machine_desc __arch_info_begin[], __arch_info_end[];
        struct machine_desc *p;
 
-       /*
-        * locate machine in the list of supported machines.
-        */
-       for (p = __arch_info_begin; p < __arch_info_end; p++)
-               if (nr == p->nr) {
-                       printk("Machine: %s\n", p->name);
-                       return p;
-               }
-
-       early_print("\n"
-               "Error: unrecognized/unsupported machine ID (r1 = 0x%08x).\n\n"
-               "Available machine support:\n\nID (hex)\tNAME\n", nr);
-
-       for (p = __arch_info_begin; p < __arch_info_end; p++)
+       early_print("Available machine support:\n\nID (hex)\tNAME\n");
+       for_each_machine_desc(p)
                early_print("%08x\t%s\n", p->nr, p->name);
 
        early_print("\nPlease check your kernel config and/or bootloader.\n");
@@ -466,7 +455,7 @@ static struct machine_desc * __init setup_machine(unsigned int nr)
                /* can't use cpu_relax() here as it may require MMU setup */;
 }
 
-static int __init arm_add_memory(phys_addr_t start, unsigned long size)
+int __init arm_add_memory(phys_addr_t start, unsigned long size)
 {
        struct membank *bank = &meminfo.bank[meminfo.nr_banks];
 
@@ -801,23 +790,29 @@ static void __init squash_mem_tags(struct tag *tag)
                        tag->hdr.tag = ATAG_NONE;
 }
 
-void __init setup_arch(char **cmdline_p)
+static struct machine_desc * __init setup_machine_tags(unsigned int nr)
 {
        struct tag *tags = (struct tag *)&init_tags;
-       struct machine_desc *mdesc;
+       struct machine_desc *mdesc = NULL, *p;
        char *from = default_command_line;
 
        init_tags.mem.start = PHYS_OFFSET;
 
-       unwind_init();
-
-       setup_processor();
-       mdesc = setup_machine(machine_arch_type);
-       machine_desc = mdesc;
-       machine_name = mdesc->name;
+       /*
+        * locate machine in the list of supported machines.
+        */
+       for_each_machine_desc(p)
+               if (nr == p->nr) {
+                       printk("Machine: %s\n", p->name);
+                       mdesc = p;
+                       break;
+               }
 
-       if (mdesc->soft_reboot)
-               reboot_setup("s");
+       if (!mdesc) {
+               early_print("\nError: unrecognized/unsupported machine ID"
+                       " (r1 = 0x%08x).\n\n", nr);
+               dump_machine_table(); /* does not return */
+       }
 
        if (__atags_pointer)
                tags = phys_to_virt(__atags_pointer);
@@ -849,8 +844,17 @@ void __init setup_arch(char **cmdline_p)
        if (tags->hdr.tag != ATAG_CORE)
                convert_to_tag_list(tags);
 #endif
-       if (tags->hdr.tag != ATAG_CORE)
+
+       if (tags->hdr.tag != ATAG_CORE) {
+#if defined(CONFIG_OF)
+               /*
+                * If CONFIG_OF is set, then assume this is a reasonably
+                * modern system that should pass boot parameters
+                */
+               early_print("Warning: Neither atags nor dtb found\n");
+#endif
                tags = (struct tag *)&init_tags;
+       }
 
        if (mdesc->fixup)
                mdesc->fixup(mdesc, tags, &from, &meminfo);
@@ -862,14 +866,34 @@ void __init setup_arch(char **cmdline_p)
                parse_tags(tags);
        }
 
+       /* parse_early_param needs a boot_command_line */
+       strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
+
+       return mdesc;
+}
+
+
+void __init setup_arch(char **cmdline_p)
+{
+       struct machine_desc *mdesc;
+
+       unwind_init();
+
+       setup_processor();
+       mdesc = setup_machine_fdt(__atags_pointer);
+       if (!mdesc)
+               mdesc = setup_machine_tags(machine_arch_type);
+       machine_desc = mdesc;
+       machine_name = mdesc->name;
+
+       if (mdesc->soft_reboot)
+               reboot_setup("s");
+
        init_mm.start_code = (unsigned long) _text;
        init_mm.end_code   = (unsigned long) _etext;
        init_mm.end_data   = (unsigned long) _edata;
        init_mm.brk        = (unsigned long) _end;
 
-       /* parse_early_param needs a boot_command_line */
-       strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
-
        /* populate cmd_line too for later use, preserving boot_command_line */
        strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
        *cmdline_p = cmd_line;
@@ -881,6 +905,8 @@ void __init setup_arch(char **cmdline_p)
        paging_init(mdesc);
        request_standard_resources(mdesc);
 
+       unflatten_device_tree();
+
 #ifdef CONFIG_SMP
        if (is_smp())
                smp_init_cpus();
index 76f82ae..7517672 100644 (file)
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 #include <linux/initrd.h>
+#include <linux/of_fdt.h>
 #include <linux/highmem.h>
 #include <linux/gfp.h>
 #include <linux/memblock.h>
 #include <linux/sort.h>
 
 #include <asm/mach-types.h>
+#include <asm/prom.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/sizes.h>
@@ -71,6 +73,14 @@ static int __init parse_tag_initrd2(const struct tag *tag)
 
 __tagtable(ATAG_INITRD2, parse_tag_initrd2);
 
+#ifdef CONFIG_OF_FLATTREE
+void __init early_init_dt_setup_initrd_arch(unsigned long start, unsigned long end)
+{
+       phys_initrd_start = start;
+       phys_initrd_size = end - start;
+}
+#endif /* CONFIG_OF_FLATTREE */
+
 /*
  * This keeps memory configuration data used by a couple memory
  * initialization functions, as well as show_mem() for the skipping
@@ -334,6 +344,7 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
 #endif
 
        arm_mm_memblock_reserve();
+       arm_dt_memblock_reserve();
 
        /* reserve any platform specific memblock areas */
        if (mdesc->reserve)
index 00ee90f..b15cc21 100644 (file)
@@ -130,7 +130,7 @@ void __init early_init_devtree(void *params)
         * device-tree, including the platform type, initrd location and
         * size, TCE reserve, and more ...
         */
-       of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
+       of_scan_flat_dt(early_init_dt_scan_chosen, cmd_line);
 
        /* Scan memory nodes and rebuild MEMBLOCKs */
        memblock_init();
index f29b862..857d9b7 100644 (file)
@@ -14,9 +14,6 @@
 #ifdef CONFIG_OF
 #include <asm/bootinfo.h>
 
-/* which is compatible with the flattened device tree (FDT) */
-#define cmd_line arcs_cmdline
-
 extern int early_init_dt_scan_memory_arch(unsigned long node,
        const char *uname, int depth, void *data);
 
index a19811e..5b7eade 100644 (file)
@@ -83,7 +83,8 @@ void __init early_init_devtree(void *params)
         * device-tree, including the platform type, initrd location and
         * size, and more ...
         */
-       of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
+       of_scan_flat_dt(early_init_dt_scan_chosen, arcs_cmdline);
+
 
        /* Scan memory nodes */
        of_scan_flat_dt(early_init_dt_scan_root, NULL);
index 48aeb55..f2c906b 100644 (file)
@@ -694,7 +694,7 @@ void __init early_init_devtree(void *params)
         * device-tree, including the platform type, initrd location and
         * size, TCE reserve, and more ...
         */
-       of_scan_flat_dt(early_init_dt_scan_chosen_ppc, NULL);
+       of_scan_flat_dt(early_init_dt_scan_chosen_ppc, cmd_line);
 
        /* Scan memory nodes and rebuild MEMBLOCKs */
        memblock_init();
index 8b63a69..65200af 100644 (file)
@@ -670,7 +670,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 
        pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
 
-       if (depth != 1 ||
+       if (depth != 1 || !data ||
            (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
                return 0;
 
@@ -679,16 +679,16 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
        /* Retrieve command line */
        p = of_get_flat_dt_prop(node, "bootargs", &l);
        if (p != NULL && l > 0)
-               strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE));
+               strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE));
 
 #ifdef CONFIG_CMDLINE
 #ifndef CONFIG_CMDLINE_FORCE
        if (p == NULL || l == 0 || (l == 1 && (*p) == 0))
 #endif
-               strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+               strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
 #endif /* CONFIG_CMDLINE */
 
-       pr_debug("Command line is: %s\n", cmd_line);
+       pr_debug("Command line is: %s\n", (char*)data);
 
        /* break now */
        return 1;