Commit 381b26f0 authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] Workaround "_BBN 0" BIOS bug

enhance "pci=noacpi" to skip ACPI PCI configuration and interrupt config
add "acpi=noirq" to skip just ACPI interrupt config (David Shaohua Li)
http://bugzilla.kernel.org/show_bug.cgi?id=1662
parent f7e2224a
......@@ -91,13 +91,14 @@ running once the system is up.
acpi= [HW,ACPI] Advanced Configuration and Power Interface
Format: { force | off | ht | strict }
force -- enables ACPI for systems with default off
off -- disabled ACPI for systems with default on
force -- enable ACPI if default was off
off -- disable ACPI if default was on
noirq -- do not use ACPI for IRQ routing
ht -- run only enough ACPI to enable Hyper Threading
strict -- Be less tolerant of platforms that are not
strictly ACPI specification compliant.
See also Documentation/pm.txt.
See also Documentation/pm.txt, pci=noacpi
acpi_sleep= [HW,ACPI] Sleep options
Format: { s3_bios, s3_mode }
......@@ -831,7 +832,8 @@ running once the system is up.
and Omnibook XE3 notebooks. This will
have no effect if ACPI IRQ routing is
enabled.
noacpi [IA-32] Do not use ACPI for IRQ routing.
noacpi [IA-32] Do not use ACPI for IRQ routing
or for PCI scanning.
pcmv= [HW,PCMCIA] BadgePAD 4
......
......@@ -53,7 +53,13 @@ static inline int ioapic_setup_disabled(void) { return 0; }
#define PREFIX "ACPI: "
#ifdef CONFIG_ACPI_PCI
int acpi_noirq __initdata; /* skip ACPI IRQ initialization */
int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */
#else
int acpi_noirq __initdata = 1;
int acpi_pci_disabled __initdata = 1;
#endif
int acpi_ht __initdata = 1; /* enable HT */
int acpi_lapic;
......
......@@ -531,12 +531,18 @@ static __init __attribute__((unused)) int force_acpi_ht(struct dmi_blacklist *d)
#endif
#ifdef CONFIG_ACPI_PCI
static __init int disable_acpi_irq(struct dmi_blacklist *d)
{
printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n", d->ident);
acpi_noirq_set();
return 0;
}
static __init int disable_acpi_pci(struct dmi_blacklist *d)
{
printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", d->ident);
acpi_noirq_set();
acpi_disable_pci();
return 0;
}
}
#endif
/*
......@@ -951,13 +957,21 @@ static __initdata struct dmi_blacklist dmi_blacklist[]={
* Boxes that need ACPI PCI IRQ routing disabled
*/
{ disable_acpi_pci, "ASUS A7V", {
{ disable_acpi_irq, "ASUS A7V", {
MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
MATCH(DMI_BOARD_NAME, "<A7V>"),
/* newer BIOS, Revision 1011, does work */
MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"),
NO_MATCH }},
/*
* Boxes that need ACPI PCI IRQ routing and PCI scan disabled
*/
{ disable_acpi_pci, "ASUS PR-DLS", { /* _BBN 0 bug */
MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
MATCH(DMI_BOARD_NAME, "PR-DLS"),
MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"),
MATCH(DMI_BIOS_DATE, "03/21/2003") }},
#endif
{ NULL, }
......
......@@ -596,9 +596,13 @@ static void __init parse_cmdline_early (char ** cmdline_p)
disable_acpi();
acpi_ht = 1;
}
/* "pci=noacpi" disables ACPI interrupt routing */
/* "pci=noacpi" disable ACPI IRQ routing and PCI scan */
else if (!memcmp(from, "pci=noacpi", 10)) {
acpi_disable_pci();
}
/* "acpi=noirq" disables ACPI interrupt routing */
else if (!memcmp(from, "acpi=noirq", 10)) {
acpi_noirq_set();
}
......
......@@ -64,8 +64,8 @@ struct cpuinfo_x86 boot_cpu_data;
unsigned long mmu_cr4_features;
EXPORT_SYMBOL_GPL(mmu_cr4_features);
int acpi_disabled = 0;
int acpi_disabled;
EXPORT_SYMBOL(acpi_disabled);
#ifdef CONFIG_ACPI_BOOT
extern int __initdata acpi_ht;
extern acpi_interrupt_flags acpi_sci_flags;
......@@ -217,7 +217,7 @@ static __init void parse_cmdline_early (char ** cmdline_p)
#ifdef CONFIG_ACPI_BOOT
/* "acpi=off" disables both ACPI table parsing and interpreter init */
if (!memcmp(from, "acpi=off", 8))
acpi_disabled = 1;
disable_acpi();
if (!memcmp(from, "acpi=force", 10)) {
/* add later when we do DMI horrors: */
......@@ -231,7 +231,9 @@ static __init void parse_cmdline_early (char ** cmdline_p)
acpi_ht = 1;
}
else if (!memcmp(from, "pci=noacpi", 10))
acpi_noirq_set();
acpi_disable_pci();
else if (!memcmp(from, "acpi=noirq", 10))
acpi_noirq_set();
else if (!memcmp(from, "acpi_sci=edge", 13))
acpi_sci_flags.trigger = 1;
......
......@@ -793,7 +793,7 @@ static int __init acpi_pci_link_init (void)
{
ACPI_FUNCTION_TRACE("acpi_pci_link_init");
if (acpi_disabled)
if (acpi_pci_disabled)
return_VALUE(0);
acpi_link.count = 0;
......
......@@ -119,6 +119,7 @@ acpi_pci_root_add (
{
int result = 0;
struct acpi_pci_root *root = NULL;
struct acpi_pci_root *tmp;
acpi_status status = AE_OK;
unsigned long value = 0;
acpi_handle handle = NULL;
......@@ -186,6 +187,13 @@ acpi_pci_root_add (
goto end;
}
/* Some systems have wrong _BBN */
list_for_each_entry(tmp, &acpi_pci_roots, node) {
if ((tmp->id.segment == root->id.segment)
&& (tmp->id.bus == root->id.bus))
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Wrong _BBN value, please reboot and using option 'pci=noacpi'\n"));
}
/*
* Device & Function
* -----------------
......@@ -272,7 +280,7 @@ static int __init acpi_pci_root_init (void)
{
ACPI_FUNCTION_TRACE("acpi_pci_root_init");
if (acpi_disabled)
if (acpi_pci_disabled)
return_VALUE(0);
/* DEBUG:
......
......@@ -109,7 +109,14 @@ extern int acpi_noirq;
extern int acpi_strict;
extern int acpi_disabled;
extern int acpi_ht;
static inline void disable_acpi(void) { acpi_disabled = 1; acpi_ht = 0; }
extern int acpi_pci_disabled;
static inline void disable_acpi(void)
{
acpi_disabled = 1;
acpi_ht = 0;
acpi_pci_disabled = 1;
acpi_noirq = 1;
}
/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
#define FIX_ACPI_PAGES 4
......@@ -143,9 +150,15 @@ static inline void disable_ioapic_setup(void)
#ifdef CONFIG_ACPI_PCI
static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
static inline void acpi_disable_pci(void)
{
acpi_pci_disabled = 1;
acpi_noirq_set();
}
extern int acpi_irq_balance_set(char *str);
#else
static inline void acpi_noirq_set(void) { }
static inline void acpi_disable_pci(void) { }
static inline int acpi_irq_balance_set(char *str) { return 0; }
#endif
......
......@@ -89,6 +89,7 @@ ia64_acpi_release_global_lock (unsigned int *lock)
((Acq) = ia64_acpi_release_global_lock((unsigned int *) GLptr))
#define acpi_disabled 0 /* ACPI always enabled on IA64 */
#define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */
#define acpi_strict 1 /* no ACPI spec workarounds on IA64 */
static inline void disable_acpi(void) { }
......
......@@ -106,8 +106,15 @@ extern int acpi_ioapic;
extern int acpi_noirq;
extern int acpi_strict;
extern int acpi_disabled;
extern int acpi_pci_disabled;
extern int acpi_ht;
static inline void disable_acpi(void) { acpi_disabled = 1; acpi_ht = 0; }
static inline void disable_acpi(void)
{
acpi_disabled = 1;
acpi_ht = 0;
acpi_pci_disabled = 1;
acpi_noirq = 1;
}
/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
#define FIX_ACPI_PAGES 4
......@@ -121,9 +128,15 @@ extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq);
#ifdef CONFIG_ACPI_PCI
static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
static inline void acpi_disable_pci(void)
{
acpi_pci_disabled = 1;
acpi_noirq_set();
}
extern int acpi_irq_balance_set(char *str);
#else
static inline void acpi_noirq_set(void) { }
static inline void acpi_disable_pci(void) { }
static inline int acpi_irq_balance_set(char *str) { return 0; }
#endif
......@@ -144,6 +157,7 @@ extern void acpi_reserve_bootmem(void);
#define boot_cpu_physical_apicid boot_cpu_id
extern int acpi_disabled;
extern int acpi_pci_disabled;
#define dmi_broken (0)
#define BROKEN_ACPI_Sx 0x0001
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment