Commit 594473bf authored by Len Brown's avatar Len Brown

[ACPI] acpi_boot_init() cleanup suggested by Matt Wilcox

HPET doesn't depend on IOAPIC
parent 02e711d3
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/mpspec.h> #include <asm/mpspec.h>
#if defined (CONFIG_X86_LOCAL_APIC) #ifdef CONFIG_X86_LOCAL_APIC
#include <mach_apic.h> #include <mach_apic.h>
#include <mach_mpparse.h> #include <mach_mpparse.h>
#include <asm/io_apic.h> #include <asm/io_apic.h>
...@@ -49,11 +49,19 @@ int acpi_lapic; ...@@ -49,11 +49,19 @@ int acpi_lapic;
int acpi_ioapic; int acpi_ioapic;
int acpi_strict; int acpi_strict;
#ifdef CONFIG_X86_LOCAL_APIC
static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
#endif
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Boot-time Configuration Boot-time Configuration
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
enum acpi_irq_model_id acpi_irq_model; /*
* The default interrupt routing model is PIC (8259). This gets
* overriden if IOAPICs are enumerated (below).
*/
enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
/* /*
* Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
...@@ -97,10 +105,6 @@ char *__acpi_map_table(unsigned long phys, unsigned long size) ...@@ -97,10 +105,6 @@ char *__acpi_map_table(unsigned long phys, unsigned long size)
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
static int __init static int __init
acpi_parse_madt ( acpi_parse_madt (
unsigned long phys_addr, unsigned long phys_addr,
...@@ -117,11 +121,12 @@ acpi_parse_madt ( ...@@ -117,11 +121,12 @@ acpi_parse_madt (
return -ENODEV; return -ENODEV;
} }
if (madt->lapic_address) if (madt->lapic_address) {
acpi_lapic_addr = (u64) madt->lapic_address; acpi_lapic_addr = (u64) madt->lapic_address;
printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n", printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n",
madt->lapic_address); madt->lapic_address);
}
acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id); acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id);
...@@ -247,7 +252,7 @@ acpi_parse_nmi_src ( ...@@ -247,7 +252,7 @@ acpi_parse_nmi_src (
return 0; return 0;
} }
#endif /*CONFIG_X86_IO_APIC*/ #endif /* CONFIG_X86_IO_APIC */
#ifdef CONFIG_ACPI_BUS #ifdef CONFIG_ACPI_BUS
/* /*
...@@ -387,122 +392,61 @@ acpi_find_rsdp (void) ...@@ -387,122 +392,61 @@ acpi_find_rsdp (void)
return rsdp_phys; return rsdp_phys;
} }
#ifdef CONFIG_X86_LOCAL_APIC
/* /*
* acpi_boot_init() * Parse LAPIC entries in MADT
* called from setup_arch(), always. * returns 0 on success, < 0 on error
* 1. maps ACPI tables for later use
* 2. enumerates lapics
* 3. enumerates io-apics
*
* side effects:
* acpi_lapic = 1 if LAPIC found
* acpi_ioapic = 1 if IOAPIC found
* if (acpi_lapic && acpi_ioapic) smp_found_config = 1;
* if acpi_blacklisted() acpi_disabled = 1;
* acpi_irq_model=...
* ...
*
* return value: (currently ignored)
* 0: success
* !0: failure
*/ */
static int __init
int __init acpi_parse_madt_lapic_entries(void)
acpi_boot_init (void)
{ {
int result = 0; int count;
if (acpi_disabled && !acpi_ht)
return 1;
/*
* The default interrupt routing model is PIC (8259). This gets
* overriden if IOAPICs are enumerated (below).
*/
acpi_irq_model = ACPI_IRQ_MODEL_PIC;
/* /*
* Initialize the ACPI boot-time table parser.
*/
result = acpi_table_init();
if (result) {
acpi_disabled = 1;
return result;
}
result = acpi_blacklisted();
if (result) {
printk(KERN_WARNING PREFIX "BIOS listed in blacklist, disabling ACPI support\n");
acpi_disabled = 1;
return result;
}
#ifdef CONFIG_X86_LOCAL_APIC
/*
* MADT
* ----
* Parse the Multiple APIC Description Table (MADT), if exists.
* Note that this table provides platform SMP configuration
* information -- the successor to MPS tables.
*/
result = acpi_table_parse(ACPI_APIC, acpi_parse_madt);
if (!result) {
return 0;
}
else if (result < 0) {
printk(KERN_ERR PREFIX "Error parsing MADT\n");
return result;
}
else if (result > 1)
printk(KERN_WARNING PREFIX "Multiple MADT tables exist\n");
/*
* Local APIC
* ----------
* Note that the LAPIC address is obtained from the MADT (32-bit value) * Note that the LAPIC address is obtained from the MADT (32-bit value)
* and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
*/ */
result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0); count = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0);
if (result < 0) { if (count < 0) {
printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
return result; return count;
} }
mp_register_lapic_address(acpi_lapic_addr); mp_register_lapic_address(acpi_lapic_addr);
result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic, count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic,
MAX_APICS); MAX_APICS);
if (!result) { if (!count) {
printk(KERN_ERR PREFIX "No LAPIC entries present\n"); printk(KERN_ERR PREFIX "No LAPIC entries present\n");
/* TBD: Cleanup to allow fallback to MPS */ /* TBD: Cleanup to allow fallback to MPS */
return -ENODEV; return -ENODEV;
} }
else if (result < 0) { else if (count < 0) {
printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");
/* TBD: Cleanup to allow fallback to MPS */ /* TBD: Cleanup to allow fallback to MPS */
return result; return count;
} }
result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0); count = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0);
if (result < 0) { if (count < 0) {
printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
/* TBD: Cleanup to allow fallback to MPS */ /* TBD: Cleanup to allow fallback to MPS */
return result; return count;
} }
return 0;
acpi_lapic = 1; }
#endif /* CONFIG_X86_LOCAL_APIC */
#endif /*CONFIG_X86_LOCAL_APIC*/
#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER) #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER)
/*
/* * Parse IOAPIC related entries in MADT
* I/O APIC * returns 0 on success, < 0 on error
* -------- */
*/ static int __init
acpi_parse_madt_ioapic_entries(void)
{
int count;
/* /*
* ACPI interpreter is required to complete interrupt setup, * ACPI interpreter is required to complete interrupt setup,
...@@ -511,7 +455,7 @@ acpi_boot_init (void) ...@@ -511,7 +455,7 @@ acpi_boot_init (void)
* otherwise the system will stay in PIC mode * otherwise the system will stay in PIC mode
*/ */
if (acpi_disabled || acpi_noirq) { if (acpi_disabled || acpi_noirq) {
return 1; return -ENODEV;
} }
/* /*
...@@ -520,54 +464,140 @@ acpi_boot_init (void) ...@@ -520,54 +464,140 @@ acpi_boot_init (void)
if (ioapic_setup_disabled()) { if (ioapic_setup_disabled()) {
printk(KERN_INFO PREFIX "Skipping IOAPIC probe " printk(KERN_INFO PREFIX "Skipping IOAPIC probe "
"due to 'noapic' option.\n"); "due to 'noapic' option.\n");
return 1; return -ENODEV;
} }
result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS); count = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS);
if (!result) { if (!count) {
printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
return -ENODEV; return -ENODEV;
} }
else if (result < 0) { else if (count < 0) {
printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n"); printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n");
return result; return count;
} }
/* Build a default routing table for legacy (ISA) interrupts. */ /* Build a default routing table for legacy (ISA) interrupts. */
mp_config_acpi_legacy_irqs(); mp_config_acpi_legacy_irqs();
result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS); count = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS);
if (result < 0) { if (count < 0) {
printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
/* TBD: Cleanup to allow fallback to MPS */ /* TBD: Cleanup to allow fallback to MPS */
return result; return count;
} }
result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, NR_IRQ_VECTORS); count = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, NR_IRQ_VECTORS);
if (result < 0) { if (count < 0) {
printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
/* TBD: Cleanup to allow fallback to MPS */ /* TBD: Cleanup to allow fallback to MPS */
return result; return count;
} }
acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; return 0;
}
acpi_irq_balance_set(NULL); #else
static inline int acpi_parse_madt_ioapic_entries(void)
acpi_ioapic = 1; {
return -1;
}
#endif /* !(CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER) */
#endif /* CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER */
static void __init
acpi_process_madt(void)
{
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
if (acpi_lapic && acpi_ioapic) { int count, error;
smp_found_config = 1;
clustered_apic_check(); count = acpi_table_parse(ACPI_APIC, acpi_parse_madt);
if (count == 1) {
/*
* Parse MADT LAPIC entries
*/
error = acpi_parse_madt_lapic_entries();
if (!error) {
acpi_lapic = 1;
/*
* Parse MADT IO-APIC entries
*/
error = acpi_parse_madt_ioapic_entries();
if (!error) {
acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
acpi_irq_balance_set(NULL);
acpi_ioapic = 1;
smp_found_config = 1;
clustered_apic_check();
}
}
} }
#endif #endif
return;
}
/*
* acpi_boot_init()
* called from setup_arch(), always.
* 1. checksums all tables
* 2. enumerates lapics
* 3. enumerates io-apics
*
* side effects:
* acpi_lapic = 1 if LAPIC found
* acpi_ioapic = 1 if IOAPIC found
* if (acpi_lapic && acpi_ioapic) smp_found_config = 1;
* if acpi_blacklisted() acpi_disabled = 1;
* acpi_irq_model=...
* ...
*
* return value: (currently ignored)
* 0: success
* !0: failure
*/
int __init
acpi_boot_init (void)
{
int error;
/*
* If acpi_disabled, bail out
* One exception: acpi=ht continues far enough to enumerate LAPICs
*/
if (acpi_disabled && !acpi_ht)
return 1;
/*
* Initialize the ACPI boot-time table parser.
*/
error = acpi_table_init();
if (error) {
acpi_disabled = 1;
return error;
}
/*
* blacklist may disable ACPI entirely
*/
error = acpi_blacklisted();
if (error) {
printk(KERN_WARNING PREFIX "BIOS listed in blacklist, disabling ACPI support\n");
acpi_disabled = 1;
return error;
}
/*
* Process the Multiple APIC Description Table (MADT), if present
*/
acpi_process_madt();
#ifdef CONFIG_HPET_TIMER #ifdef CONFIG_HPET_TIMER
acpi_table_parse(ACPI_HPET, acpi_parse_hpet); (void) acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
#endif #endif
return 0; return 0;
} }
...@@ -550,6 +550,14 @@ acpi_table_get_sdt ( ...@@ -550,6 +550,14 @@ acpi_table_get_sdt (
return 0; return 0;
} }
/*
* acpi_table_init()
*
* find RSDP, find and checksum SDT/XSDT.
* checksum all tables, print SDT/XSDT
*
* result: sdt_entry[] is initialized
*/
int __init int __init
acpi_table_init (void) acpi_table_init (void)
......
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