x86/reboot: Add reboot quirk for Certec BPC600
[pandora-kernel.git] / arch / x86 / kernel / reboot.c
index 9242436..c6f8c2e 100644 (file)
@@ -124,7 +124,7 @@ __setup("reboot=", reboot_setup);
  */
 
 /*
- * Some machines require the "reboot=b"  commandline option,
+ * Some machines require the "reboot=b" or "reboot=k"  commandline options,
  * this quirk makes that automatic.
  */
 static int __init set_bios_reboot(const struct dmi_system_id *d)
@@ -136,6 +136,15 @@ static int __init set_bios_reboot(const struct dmi_system_id *d)
        return 0;
 }
 
+static int __init set_kbd_reboot(const struct dmi_system_id *d)
+{
+       if (reboot_type != BOOT_KBD) {
+               reboot_type = BOOT_KBD;
+               printk(KERN_INFO "%s series board detected. Selecting KBD-method for reboot.\n", d->ident);
+       }
+       return 0;
+}
+
 static struct dmi_system_id __initdata reboot_dmi_table[] = {
        {       /* Handle problems with rebooting on Dell E520's */
                .callback = set_bios_reboot,
@@ -270,14 +279,6 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "VGN-Z540N"),
                },
        },
-       {       /* Handle problems with rebooting on CompuLab SBC-FITPC2 */
-               .callback = set_bios_reboot,
-               .ident = "CompuLab SBC-FITPC2",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "CompuLab"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"),
-               },
-       },
        {       /* Handle problems with rebooting on ASUS P4S800 */
                .callback = set_bios_reboot,
                .ident = "ASUS P4S800",
@@ -286,16 +287,8 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "P4S800"),
                },
        },
-       {       /* Handle problems with rebooting on VersaLogic Menlow boards */
-               .callback = set_bios_reboot,
-               .ident = "VersaLogic Menlow based board",
-               .matches = {
-                       DMI_MATCH(DMI_BOARD_VENDOR, "VersaLogic Corporation"),
-                       DMI_MATCH(DMI_BOARD_NAME, "VersaLogic Menlow board"),
-               },
-       },
        { /* Handle reboot issue on Acer Aspire one */
-               .callback = set_bios_reboot,
+               .callback = set_kbd_reboot,
                .ident = "Acer Aspire One A110",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
@@ -419,6 +412,15 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"),
                },
        },
+       /* Certec */
+       {       /* Handle problems with rebooting on Certec BPC600 */
+               .callback = set_pci_reboot,
+               .ident = "Certec BPC600",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Certec"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "BPC600"),
+               },
+       },
        {       /* Handle problems with rebooting on the Latitude E6320. */
                .callback = set_pci_reboot,
                .ident = "Dell Latitude E6320",
@@ -427,6 +429,14 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6320"),
                },
        },
+       {       /* Handle problems with rebooting on the Latitude E5410. */
+               .callback = set_pci_reboot,
+               .ident = "Dell Latitude E5410",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5410"),
+               },
+       },
        {       /* Handle problems with rebooting on the Latitude E5420. */
                .callback = set_pci_reboot,
                .ident = "Dell Latitude E5420",
@@ -443,6 +453,54 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6420"),
                },
        },
+       {       /* Handle problems with rebooting on the OptiPlex 990. */
+               .callback = set_pci_reboot,
+               .ident = "Dell OptiPlex 990",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"),
+               },
+       },
+       {       /* Handle problems with rebooting on the Precision M6600. */
+               .callback = set_pci_reboot,
+               .ident = "Dell Precision M6600",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"),
+               },
+       },
+       {       /* Handle problems with rebooting on the Dell PowerEdge C6100. */
+               .callback = set_pci_reboot,
+               .ident = "Dell PowerEdge C6100",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "C6100"),
+               },
+       },
+       {       /* Handle problems with rebooting on the Precision M6600. */
+               .callback = set_pci_reboot,
+               .ident = "Dell OptiPlex 990",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"),
+               },
+       },
+       {       /* Handle problems with rebooting on the Dell PowerEdge C6100. */
+               .callback = set_pci_reboot,
+               .ident = "Dell PowerEdge C6100",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "C6100"),
+               },
+       },
+       {       /* Some C6100 machines were shipped with vendor being 'Dell'. */
+               .callback = set_pci_reboot,
+               .ident = "Dell PowerEdge C6100",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "C6100"),
+               },
+       },
        { }
 };
 
@@ -464,7 +522,7 @@ static inline void kb_wait(void)
        }
 }
 
-static void vmxoff_nmi(int cpu, struct die_args *args)
+static void vmxoff_nmi(int cpu, struct pt_regs *regs)
 {
        cpu_emergency_vmxoff();
 }
@@ -578,7 +636,7 @@ static void native_machine_emergency_restart(void)
                        break;
 
                case BOOT_EFI:
-                       if (efi_enabled)
+                       if (efi_enabled(EFI_RUNTIME_SERVICES))
                                efi.reset_system(reboot_mode ?
                                                 EFI_RESET_WARM :
                                                 EFI_RESET_COLD,
@@ -611,6 +669,13 @@ void native_machine_shutdown(void)
 
        /* The boot cpu is always logical cpu 0 */
        int reboot_cpu_id = 0;
+#endif
+
+#ifdef CONFIG_X86_IO_APIC
+       disable_IO_APIC();
+#endif
+
+#ifdef CONFIG_SMP
 
 #ifdef CONFIG_X86_32
        /* See if there has been given a command line override */
@@ -634,10 +699,6 @@ void native_machine_shutdown(void)
 
        lapic_shutdown();
 
-#ifdef CONFIG_X86_IO_APIC
-       disable_IO_APIC();
-#endif
-
 #ifdef CONFIG_HPET_TIMER
        hpet_disable();
 #endif
@@ -736,14 +797,10 @@ static nmi_shootdown_cb shootdown_callback;
 
 static atomic_t waiting_for_crash_ipi;
 
-static int crash_nmi_callback(struct notifier_block *self,
-                       unsigned long val, void *data)
+static int crash_nmi_callback(unsigned int val, struct pt_regs *regs)
 {
        int cpu;
 
-       if (val != DIE_NMI)
-               return NOTIFY_OK;
-
        cpu = raw_smp_processor_id();
 
        /* Don't do anything if this handler is invoked on crashing cpu.
@@ -751,10 +808,10 @@ static int crash_nmi_callback(struct notifier_block *self,
         * an NMI if system was initially booted with nmi_watchdog parameter.
         */
        if (cpu == crashing_cpu)
-               return NOTIFY_STOP;
+               return NMI_HANDLED;
        local_irq_disable();
 
-       shootdown_callback(cpu, (struct die_args *)data);
+       shootdown_callback(cpu, regs);
 
        atomic_dec(&waiting_for_crash_ipi);
        /* Assume hlt works */
@@ -762,7 +819,7 @@ static int crash_nmi_callback(struct notifier_block *self,
        for (;;)
                cpu_relax();
 
-       return 1;
+       return NMI_HANDLED;
 }
 
 static void smp_send_nmi_allbutself(void)
@@ -770,12 +827,6 @@ static void smp_send_nmi_allbutself(void)
        apic->send_IPI_allbutself(NMI_VECTOR);
 }
 
-static struct notifier_block crash_nmi_nb = {
-       .notifier_call = crash_nmi_callback,
-       /* we want to be the first one called */
-       .priority = NMI_LOCAL_HIGH_PRIOR+1,
-};
-
 /* Halt all other CPUs, calling the specified function on each of them
  *
  * This function can be used to halt all other CPUs on crash
@@ -794,7 +845,8 @@ void nmi_shootdown_cpus(nmi_shootdown_cb callback)
 
        atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
        /* Would it be better to replace the trap vector here? */
-       if (register_die_notifier(&crash_nmi_nb))
+       if (register_nmi_handler(NMI_LOCAL, crash_nmi_callback,
+                                NMI_FLAG_FIRST, "crash"))
                return;         /* return what? */
        /* Ensure the new callback function is set before sending
         * out the NMI