x86: Add quirk to make Apple MacBook5,2 use reboot=pci

The latest Apple MacBook (MacBook5,2) doesn't reboot successfully
under Linux; neither the EFI reboot method nor the default method
using the keyboard controller works (the system just hangs and doesn't
reset).  However, the method using the "PCI reset register" at 0xcf9
does work.

This adds a quirk to detect this machine via DMI and force the
reboot_type to BOOT_CF9.  With this it reboots successfully without
requiring a command-line option.  Note that the EFI code forces
reboot_type to BOOT_EFI when the machine is booted via EFI, but this
overrides that since the core_initcall runs after the EFI
initialization code.

Signed-off-by: Paul Mackerras <paulus@samba.org>
LKML-Reference: <19062.56420.501516.316181@cargo.ozlabs.ibm.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
Paul Mackerras 2009-08-03 22:47:32 +10:00 committed by H. Peter Anvin
parent 8523acfe40
commit 6c6c51e4cc
1 changed files with 33 additions and 1 deletions

View File

@ -3,6 +3,7 @@
#include <linux/init.h>
#include <linux/pm.h>
#include <linux/efi.h>
#include <linux/dmi.h>
#include <acpi/reboot.h>
#include <asm/io.h>
#include <asm/apic.h>
@ -17,7 +18,6 @@
#include <asm/cpu.h>
#ifdef CONFIG_X86_32
# include <linux/dmi.h>
# include <linux/ctype.h>
# include <linux/mc146818rtc.h>
#else
@ -404,6 +404,38 @@ EXPORT_SYMBOL(machine_real_restart);
#endif /* CONFIG_X86_32 */
/*
* Apple MacBook5,2 (2009 MacBook) needs reboot=p
*/
static int __init set_pci_reboot(const struct dmi_system_id *d)
{
if (reboot_type != BOOT_CF9) {
reboot_type = BOOT_CF9;
printk(KERN_INFO "%s series board detected. "
"Selecting PCI-method for reboots.\n", d->ident);
}
return 0;
}
static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
{ /* Handle problems with rebooting on Apple MacBook5,2 */
.callback = set_pci_reboot,
.ident = "Apple MacBook",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,2"),
},
},
{ }
};
static int __init pci_reboot_init(void)
{
dmi_check_system(pci_reboot_dmi_table);
return 0;
}
core_initcall(pci_reboot_init);
static inline void kb_wait(void)
{
int i;