]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/mm/init.c
[ARM] move initrd code from kernel/setup.c to mm/init.c
[linux-2.6-omap-h63xx.git] / arch / arm / mm / init.c
index e6352946dde020e04c3461b2f074972592b74710..c70fb1d18903388b10e3f216b604235343164142 100644 (file)
 #include "mm.h"
 
 extern void _text, _etext, __data_start, _end, __init_begin, __init_end;
-extern unsigned long phys_initrd_start;
-extern unsigned long phys_initrd_size;
+
+static unsigned long phys_initrd_start __initdata = 0;
+static unsigned long phys_initrd_size __initdata = 0;
+
+static void __init early_initrd(char **p)
+{
+       unsigned long start, size;
+
+       start = memparse(*p, p);
+       if (**p == ',') {
+               size = memparse((*p) + 1, p);
+
+               phys_initrd_start = start;
+               phys_initrd_size = size;
+       }
+}
+__early_param("initrd=", early_initrd);
+
+static int __init parse_tag_initrd(const struct tag *tag)
+{
+       printk(KERN_WARNING "ATAG_INITRD is deprecated; "
+               "please update your bootloader.\n");
+       phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
+       phys_initrd_size = tag->u.initrd.size;
+       return 0;
+}
+
+__tagtable(ATAG_INITRD, parse_tag_initrd);
+
+static int __init parse_tag_initrd2(const struct tag *tag)
+{
+       phys_initrd_start = tag->u.initrd.start;
+       phys_initrd_size = tag->u.initrd.size;
+       return 0;
+}
+
+__tagtable(ATAG_INITRD2, parse_tag_initrd2);
 
 /*
  * This is used to pass memory configuration data from paging_init
@@ -156,9 +191,9 @@ static int __init check_initrd(struct meminfo *mi)
        }
 
        if (initrd_node == -1) {
-               printk(KERN_ERR "initrd (0x%08lx - 0x%08lx) extends beyond "
+               printk(KERN_ERR "INITRD: 0x%08lx+0x%08lx extends beyond "
                       "physical memory - disabling initrd\n",
-                      phys_initrd_start, end);
+                      phys_initrd_start, phys_initrd_size);
                phys_initrd_start = phys_initrd_size = 0;
        }
 #endif
@@ -239,24 +274,32 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi)
        reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
                             boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
 
+       /*
+        * Reserve any special node zero regions.
+        */
+       if (node == 0)
+               reserve_node_zero(pgdat);
+
 #ifdef CONFIG_BLK_DEV_INITRD
        /*
         * If the initrd is in this node, reserve its memory.
         */
        if (node == initrd_node) {
-               reserve_bootmem_node(pgdat, phys_initrd_start,
-                                    phys_initrd_size, BOOTMEM_DEFAULT);
-               initrd_start = __phys_to_virt(phys_initrd_start);
-               initrd_end = initrd_start + phys_initrd_size;
+               int res = reserve_bootmem_node(pgdat, phys_initrd_start,
+                                    phys_initrd_size, BOOTMEM_EXCLUSIVE);
+
+               if (res == 0) {
+                       initrd_start = __phys_to_virt(phys_initrd_start);
+                       initrd_end = initrd_start + phys_initrd_size;
+               } else {
+                       printk(KERN_ERR
+                               "INITRD: 0x%08lx+0x%08lx overlaps in-use "
+                               "memory region - disabling initrd\n",
+                               phys_initrd_start, phys_initrd_size);
+               }
        }
 #endif
 
-       /*
-        * Finally, reserve any node zero regions.
-        */
-       if (node == 0)
-               reserve_node_zero(pgdat);
-
        /*
         * initialise the zones within this node.
         */