diff options
author | Maciej W. Rozycki <macro@linux-mips.org> | 2008-06-30 20:11:35 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-08 05:10:32 -0400 |
commit | 471694ea6c6ccdf7131354f1d698d4d83a605293 (patch) | |
tree | b2fbc18e8236fd5074250157eacf0bca84fe8be2 /arch/x86/kernel/acpi/boot.c | |
parent | bad48f4b313a756ccde454c25c14c828e2fd5819 (diff) |
x86, ioapic, acpi: add a knob to disable IRQ 0 through I/O APIC
As discovered recently some systems exhibit problems when the 8254 timer
IRQ is routed through the I/O APIC. These problems do not affect the
timer IRQ itself and therefore cannot be detected when the correctness of
operation of the interrupt is verified in check_timer(). Therefore the
I/O APIC path of the timer IRQ has to be disabled entirely.
This is a change that lets platforms ask for the timer IRQ not to be
registered in the I/O APIC interrupt tables. The local APIC and ExtINTA
paths are unaffected. This request is only taken into account for ACPI
platforms as MP table systems seem unaffected so far.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Cc: Len Brown <lenb@kernel.org>
Cc: Matthew Garrett <mjg59@srcf.ucam.org>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/acpi/boot.c')
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 91bb9a99338d..92a542653956 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -83,6 +83,8 @@ int acpi_lapic; | |||
83 | int acpi_ioapic; | 83 | int acpi_ioapic; |
84 | int acpi_strict; | 84 | int acpi_strict; |
85 | 85 | ||
86 | static int disable_irq0_through_ioapic __initdata; | ||
87 | |||
86 | u8 acpi_sci_flags __initdata; | 88 | u8 acpi_sci_flags __initdata; |
87 | int acpi_sci_override_gsi __initdata; | 89 | int acpi_sci_override_gsi __initdata; |
88 | int acpi_skip_timer_override __initdata; | 90 | int acpi_skip_timer_override __initdata; |
@@ -992,6 +994,10 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) | |||
992 | int pin; | 994 | int pin; |
993 | struct mp_config_intsrc mp_irq; | 995 | struct mp_config_intsrc mp_irq; |
994 | 996 | ||
997 | /* Skip the 8254 timer interrupt (IRQ 0) if requested. */ | ||
998 | if (bus_irq == 0 && disable_irq0_through_ioapic) | ||
999 | return; | ||
1000 | |||
995 | /* | 1001 | /* |
996 | * Convert 'gsi' to 'ioapic.pin'. | 1002 | * Convert 'gsi' to 'ioapic.pin'. |
997 | */ | 1003 | */ |
@@ -1058,6 +1064,10 @@ void __init mp_config_acpi_legacy_irqs(void) | |||
1058 | for (i = 0; i < 16; i++) { | 1064 | for (i = 0; i < 16; i++) { |
1059 | int idx; | 1065 | int idx; |
1060 | 1066 | ||
1067 | /* Skip the 8254 timer interrupt (IRQ 0) if requested. */ | ||
1068 | if (i == 0 && disable_irq0_through_ioapic) | ||
1069 | continue; | ||
1070 | |||
1061 | for (idx = 0; idx < mp_irq_entries; idx++) { | 1071 | for (idx = 0; idx < mp_irq_entries; idx++) { |
1062 | struct mp_config_intsrc *irq = mp_irqs + idx; | 1072 | struct mp_config_intsrc *irq = mp_irqs + idx; |
1063 | 1073 | ||