Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/cooloney...
[sfrench/cifs-2.6.git] / arch / ia64 / hp / common / sba_iommu.c
index c1dca226b479ef1be7ca1e605529b0a899cdaf9d..e980e7aa2306eb52ddc51632b48d97d892157704 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/efi.h>
 #include <linux/nodemask.h>
 #include <linux/bitops.h>         /* hweight64() */
+#include <linux/crash_dump.h>
 
 #include <asm/delay.h>         /* ia64_get_itc() */
 #include <asm/io.h>
@@ -43,6 +44,8 @@
 
 #include <asm/acpi-ext.h>
 
+extern int swiotlb_late_init_with_default_size (size_t size);
+
 #define PFX "IOC: "
 
 /*
@@ -2012,9 +2015,14 @@ acpi_sba_ioc_add(struct acpi_device *device)
        return 0;
 }
 
+static const struct acpi_device_id hp_ioc_iommu_device_ids[] = {
+       {"HWP0001", 0},
+       {"HWP0004", 0},
+       {"", 0},
+};
 static struct acpi_driver acpi_sba_ioc_driver = {
        .name           = "IOC IOMMU Driver",
-       .ids            = "HWP0001,HWP0004",
+       .ids            = hp_ioc_iommu_device_ids,
        .ops            = {
                .add    = acpi_sba_ioc_add,
        },
@@ -2026,11 +2034,24 @@ sba_init(void)
        if (!ia64_platform_is("hpzx1") && !ia64_platform_is("hpzx1_swiotlb"))
                return 0;
 
+#if defined(CONFIG_IA64_GENERIC) && defined(CONFIG_CRASH_DUMP)
+       /* If we are booting a kdump kernel, the sba_iommu will
+        * cause devices that were not shutdown properly to MCA
+        * as soon as they are turned back on.  Our only option for
+        * a successful kdump kernel boot is to use the swiotlb.
+        */
+       if (elfcorehdr_addr < ELFCORE_ADDR_MAX) {
+               if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
+                       panic("Unable to initialize software I/O TLB:"
+                                 " Try machvec=dig boot option");
+               machvec_init("dig");
+               return 0;
+       }
+#endif
+
        acpi_bus_register_driver(&acpi_sba_ioc_driver);
        if (!ioc_list) {
 #ifdef CONFIG_IA64_GENERIC
-               extern int swiotlb_late_init_with_default_size (size_t size);
-
                /*
                 * If we didn't find something sba_iommu can claim, we
                 * need to setup the swiotlb and switch to the dig machvec.