Merge branch 'for_paulus' of master.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc
[cascardo/linux.git] / arch / i386 / kernel / setup.c
index 2d87829..80cb3b2 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,36 @@ 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 start, unsigned long end, unsigned type)
+{
+       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 +1090,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);
 
@@ -1286,9 +1318,7 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
        probe_roms();
        for (i = 0; i < e820.nr_map; i++) {
                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 +1346,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 +1366,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
@@ -1536,6 +1578,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: