Pull bugzilla-5452 into release branch
[pandora-kernel.git] / arch / i386 / kernel / setup.c
index 5f58f8c..dd6b0e3 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/initrd.h>
 #include <linux/bootmem.h>
 #include <linux/seq_file.h>
+#include <linux/platform_device.h>
 #include <linux/console.h>
 #include <linux/mca.h>
 #include <linux/root_dev.h>
@@ -46,6 +47,7 @@
 #include <linux/kexec.h>
 #include <linux/crash_dump.h>
 #include <linux/dmi.h>
+#include <linux/pfn.h>
 
 #include <video/edid.h>
 
@@ -961,6 +963,38 @@ efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
        return 0;
 }
 
+ /*
+  * This function checks if the entire range <start,end> is mapped with type.
+  *
+  * Note: this function only works correct if the e820 table is sorted and
+  * not-overlapping, which is the case
+  */
+int __init
+e820_all_mapped(unsigned long s, unsigned long e, unsigned type)
+{
+       u64 start = s;
+       u64 end = e;
+       int i;
+       for (i = 0; i < e820.nr_map; i++) {
+               struct e820entry *ei = &e820.map[i];
+               if (type && ei->type != type)
+                       continue;
+               /* is the region (part) in overlap with the current region ?*/
+               if (ei->addr >= end || ei->addr + ei->size <= start)
+                       continue;
+               /* if the region is at the beginning of <start,end> we move
+                * start to the end of the region since it's ok until there
+                */
+               if (ei->addr <= start)
+                       start = ei->addr + ei->size;
+               /* if start is now at or beyond end, we're done, full
+                * coverage */
+               if (start >= end)
+                       return 1; /* we're done */
+       }
+       return 0;
+}
+
 /*
  * Find the highest page frame number we have available
  */
@@ -1058,10 +1092,10 @@ static int __init
 free_available_memory(unsigned long start, unsigned long end, void *arg)
 {
        /* check max_low_pfn */
-       if (start >= ((max_low_pfn + 1) << PAGE_SHIFT))
+       if (start >= (max_low_pfn << PAGE_SHIFT))
                return 0;
-       if (end >= ((max_low_pfn + 1) << PAGE_SHIFT))
-               end = (max_low_pfn + 1) << PAGE_SHIFT;
+       if (end >= (max_low_pfn << PAGE_SHIFT))
+               end = max_low_pfn << PAGE_SHIFT;
        if (start < end)
                free_bootmem(start, end - start);
 
@@ -1288,7 +1322,7 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
                struct resource *res;
                if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
                        continue;
-               res = alloc_bootmem_low(sizeof(struct resource));
+               res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
                switch (e820.map[i].type) {
                case E820_RAM:  res->name = "System RAM"; break;
                case E820_ACPI: res->name = "ACPI Tables"; break;
@@ -1316,13 +1350,15 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
 
 /*
  * Request address space for all standard resources
+ *
+ * This is called just before pcibios_init(), which is also a
+ * subsys_initcall, but is linked in later (in arch/i386/pci/common.c).
  */
-static void __init register_memory(void)
+static int __init request_standard_resources(void)
 {
-       unsigned long gapstart, gapsize, round;
-       unsigned long long last;
-       int           i;
+       int i;
 
+       printk("Setting up standard PCI resources\n");
        if (efi_enabled)
                efi_initialize_iomem_resources(&code_resource, &data_resource);
        else
@@ -1334,6 +1370,16 @@ static void __init register_memory(void)
        /* request I/O space for devices used on all i[345]86 PCs */
        for (i = 0; i < STANDARD_IO_RESOURCES; i++)
                request_resource(&ioport_resource, &standard_io_resources[i]);
+       return 0;
+}
+
+subsys_initcall(request_standard_resources);
+
+static void __init register_memory(void)
+{
+       unsigned long gapstart, gapsize, round;
+       unsigned long long last;
+       int i;
 
        /*
         * Search for the bigest gap in the low 32 bits of the e820
@@ -1459,6 +1505,16 @@ void __init setup_arch(char **cmdline_p)
 
        parse_cmdline_early(cmdline_p);
 
+#ifdef CONFIG_EARLY_PRINTK
+       {
+               char *s = strstr(*cmdline_p, "earlyprintk=");
+               if (s) {
+                       setup_early_printk(strchr(s, '=') + 1);
+                       printk("early console enabled\n");
+               }
+       }
+#endif
+
        max_low_pfn = setup_memory();
 
        /*
@@ -1483,19 +1539,6 @@ void __init setup_arch(char **cmdline_p)
         * NOTE: at this point the bootmem allocator is fully available.
         */
 
-#ifdef CONFIG_EARLY_PRINTK
-       {
-               char *s = strstr(*cmdline_p, "earlyprintk=");
-               if (s) {
-                       extern void setup_early_printk(char *);
-
-                       setup_early_printk(strchr(s, '=') + 1);
-                       printk("early console enabled\n");
-               }
-       }
-#endif
-
-
        dmi_scan_machine();
 
 #ifdef CONFIG_X86_GENERICARCH
@@ -1504,15 +1547,18 @@ void __init setup_arch(char **cmdline_p)
        if (efi_enabled)
                efi_map_memmap();
 
-#ifdef CONFIG_X86_IO_APIC
-       check_acpi_pci();       /* Checks more than just ACPI actually */
-#endif
-
 #ifdef CONFIG_ACPI
        /*
         * Parse the ACPI tables for possible boot-time SMP configuration.
         */
        acpi_boot_table_init();
+#endif
+
+#ifdef CONFIG_X86_IO_APIC
+       check_acpi_pci();       /* Checks more than just ACPI actually */
+#endif
+
+#ifdef CONFIG_ACPI
        acpi_boot_init();
 
 #if defined(CONFIG_SMP) && defined(CONFIG_X86_PC)
@@ -1539,6 +1585,23 @@ void __init setup_arch(char **cmdline_p)
 #endif
 }
 
+static __init int add_pcspkr(void)
+{
+       struct platform_device *pd;
+       int ret;
+
+       pd = platform_device_alloc("pcspkr", -1);
+       if (!pd)
+               return -ENOMEM;
+
+       ret = platform_device_add(pd);
+       if (ret)
+               platform_device_put(pd);
+
+       return ret;
+}
+device_initcall(add_pcspkr);
+
 #include "setup_arch_post.h"
 /*
  * Local Variables: