From: Maciej W. Rozycki Date: Tue, 1 Jul 2008 00:11:35 +0000 (+0100) Subject: x86, ioapic, acpi: add a knob to disable IRQ 0 through I/O APIC X-Git-Tag: v2.6.27-rc1~1102^2~249^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=471694ea6c6ccdf7131354f1d698d4d83a605293;p=profile%2Fivi%2Fkernel-x86-ivi.git 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 Cc: Len Brown Cc: Matthew Garrett Cc: "Rafael J. Wysocki" Signed-off-by: Ingo Molnar --- diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 91bb9a9..92a5426 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -83,6 +83,8 @@ int acpi_lapic; int acpi_ioapic; int acpi_strict; +static int disable_irq0_through_ioapic __initdata; + u8 acpi_sci_flags __initdata; int acpi_sci_override_gsi __initdata; 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) int pin; struct mp_config_intsrc mp_irq; + /* Skip the 8254 timer interrupt (IRQ 0) if requested. */ + if (bus_irq == 0 && disable_irq0_through_ioapic) + return; + /* * Convert 'gsi' to 'ioapic.pin'. */ @@ -1058,6 +1064,10 @@ void __init mp_config_acpi_legacy_irqs(void) for (i = 0; i < 16; i++) { int idx; + /* Skip the 8254 timer interrupt (IRQ 0) if requested. */ + if (i == 0 && disable_irq0_through_ioapic) + continue; + for (idx = 0; idx < mp_irq_entries; idx++) { struct mp_config_intsrc *irq = mp_irqs + idx;