From 7a4bd3568f114d5936a3a6836cf1448e1ffa1651 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 13 Aug 2004 17:11:05 -0400 Subject: [PATCH] [ACPI] Enter ACPI mode earlier Fixes two common boot failures due to buggy SMM BIOS code SMP boot crash if SMI_CMD=ACPI written from CPU1 http://bugzilla.kernel.org/show_bug.cgi?id=2941 laptop crash due to LAPIC timer before SMI_CMD=ACPI http://bugzilla.kernel.org/show_bug.cgi?id=1269 --- arch/i386/kernel/dmi_scan.c | 44 ------------------------------------- drivers/acpi/bus.c | 38 +++++++++++++++++++++++++++----- drivers/acpi/osl.c | 10 +++++++++ init/main.c | 7 ++++++ 4 files changed, 49 insertions(+), 50 deletions(-) diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c index aafc78898f93e..d899a5ab138f8 100644 --- a/arch/i386/kernel/dmi_scan.c +++ b/arch/i386/kernel/dmi_scan.c @@ -309,26 +309,6 @@ static __init int apm_likes_to_melt(struct dmi_blacklist *d) return 0; } -/* - * Some machines, usually laptops, can't handle an enabled local APIC. - * The symptoms include hangs or reboots when suspending or resuming, - * attaching or detaching the power cord, or entering BIOS setup screens - * through magic key sequences. - */ -static int __init local_apic_kills_bios(struct dmi_blacklist *d) -{ -#ifdef CONFIG_X86_LOCAL_APIC - extern int enable_local_apic; - if (enable_local_apic == 0) { - enable_local_apic = -1; - printk(KERN_WARNING "%s with broken BIOS detected. " - "Refusing to enable the local APIC.\n", - d->ident); - } -#endif - return 0; -} - /* * Don't access SMBus on IBM systems which get corrupted eeproms */ @@ -794,30 +774,6 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={ /* Machines which have problems handling enabled local APICs */ - { local_apic_kills_bios, "Dell Inspiron", { - MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), - MATCH(DMI_PRODUCT_NAME, "Inspiron"), - NO_MATCH, NO_MATCH - } }, - - { local_apic_kills_bios, "Dell Latitude", { - MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), - MATCH(DMI_PRODUCT_NAME, "Latitude"), - NO_MATCH, NO_MATCH - } }, - - { local_apic_kills_bios, "IBM Thinkpad T20", { - MATCH(DMI_BOARD_VENDOR, "IBM"), - MATCH(DMI_BOARD_NAME, "264741U"), - NO_MATCH, NO_MATCH - } }, - - { local_apic_kills_bios, "ASUS L3C", { - MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), - MATCH(DMI_BOARD_NAME, "P4_L3C"), - NO_MATCH, NO_MATCH - } }, - { broken_acpi_Sx, "ASUS K7V-RM", { /* Bad ACPI Sx table */ MATCH(DMI_BIOS_VERSION,"ASUS K7V-RM ACPI BIOS Revision 1003A"), MATCH(DMI_BOARD_NAME, ""), diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 51362331a5f6e..c99c4e54e09fc 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -590,10 +590,9 @@ acpi_bus_init_irq (void) } -static int __init -acpi_bus_init (void) +void __init +acpi_early_init (void) { - int result = 0; acpi_status status = AE_OK; struct acpi_buffer buffer = {sizeof(acpi_fadt), &acpi_fadt}; @@ -617,7 +616,7 @@ acpi_bus_init (void) status = acpi_get_table(ACPI_TABLE_FADT, 1, &buffer); if (ACPI_FAILURE(status)) { printk(KERN_ERR PREFIX "Unable to get the FADT\n"); - goto error1; + goto error0; } #ifdef CONFIG_X86 @@ -640,12 +639,40 @@ acpi_bus_init (void) } #endif - status = acpi_enable_subsystem(ACPI_FULL_INITIALIZATION); + status = acpi_enable_subsystem(~(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE)); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Unable to enable ACPI\n"); + goto error0; + } + + return; + +error0: + disable_acpi(); + return; +} + +static int __init +acpi_bus_init (void) +{ + int result = 0; + acpi_status status = AE_OK; + extern acpi_status acpi_os_initialize1(void); + + ACPI_FUNCTION_TRACE("acpi_bus_init"); + + status = acpi_os_initialize1(); + + status = acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE); if (ACPI_FAILURE(status)) { printk(KERN_ERR PREFIX "Unable to start the ACPI Interpreter\n"); goto error1; } + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Unable to initialize ACPI OS objects\n"); + goto error1; + } #ifdef CONFIG_ACPI_EC /* * ACPI 2.0 requires the EC driver to be loaded and work before @@ -693,7 +720,6 @@ acpi_bus_init (void) /* Mimic structured exception handling */ error1: acpi_terminate(); -error0: return_VALUE(-ENODEV); } diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index a045753abdc45..22e7094bbe083 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -70,6 +70,12 @@ static struct workqueue_struct *kacpid_wq; acpi_status acpi_os_initialize(void) +{ + return AE_OK; +} + +acpi_status +acpi_os_initialize1(void) { /* * Initialize PCI configuration space access, as we'll need to access @@ -470,6 +476,8 @@ acpi_os_read_pci_configuration (struct acpi_pci_id *pci_id, u32 reg, void *value return AE_ERROR; } + BUG_ON(!raw_pci_ops); + result = raw_pci_ops->read(pci_id->segment, pci_id->bus, PCI_DEVFN(pci_id->device, pci_id->function), reg, size, value); @@ -496,6 +504,8 @@ acpi_os_write_pci_configuration (struct acpi_pci_id *pci_id, u32 reg, acpi_integ return AE_ERROR; } + BUG_ON(!raw_pci_ops); + result = raw_pci_ops->write(pci_id->segment, pci_id->bus, PCI_DEVFN(pci_id->device, pci_id->function), reg, size, value); diff --git a/init/main.c b/init/main.c index 613aaaba89f8f..329c1a9ca024b 100644 --- a/init/main.c +++ b/init/main.c @@ -91,6 +91,11 @@ extern void free_initmem(void); extern void populate_rootfs(void); extern void driver_init(void); extern void prepare_namespace(void); +#ifdef CONFIG_ACPI +extern void acpi_early_init(void); +#else +static inline acpi_early_init() { } +#endif #ifdef CONFIG_TC extern void tc_init(void); @@ -482,6 +487,8 @@ asmlinkage void __init start_kernel(void) #endif check_bugs(); + acpi_early_init(); /* before LAPIC and SMP init */ + /* * We count on the initial thread going ok * Like idlers init is an unlocked kernel thread, which will -- 2.53.0