[PATCH 8/8] x86: I/O APIC: Timer through 8259A second-chance
From: Maciej W. Rozycki
Date: Wed May 21 2008 - 17:14:11 EST
Some systems incorrectly report the ExtINTA pin of the I/O APIC as the
genuine target of the timer interrupt. Here is a change that copies timer
pin information found to the other pin if one has been found only. This
way both a direct and a through-8259A route is tested with the pin letting
these problematic systems work well enough.
Signed-off-by: Maciej W. Rozycki <macro@xxxxxxxxxxxxxx>
---
patch-2.6.26-rc1-20080505-timer-pins-0
diff -up --recursive --new-file linux-2.6.26-rc1-20080505.macro/arch/x86/kernel/io_apic_32.c linux-2.6.26-rc1-20080505/arch/x86/kernel/io_apic_32.c
--- linux-2.6.26-rc1-20080505.macro/arch/x86/kernel/io_apic_32.c 2008-05-21 18:52:36.000000000 +0000
+++ linux-2.6.26-rc1-20080505/arch/x86/kernel/io_apic_32.c 2008-05-21 18:52:36.000000000 +0000
@@ -2166,6 +2166,21 @@ static inline void __init check_timer(vo
printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
vector, apic1, pin1, apic2, pin2);
+ /*
+ * Some BIOS writers are clueless and report the ExtINTA
+ * I/O APIC input from the cascaded 8259A as the timer
+ * interrupt input. So just in case, if only one pin
+ * was found above, try it both directly and through the
+ * 8259A. --macro
+ */
+ if (pin1 == -1) {
+ pin1 = pin2;
+ apic1 = apic2;
+ } else if (pin2 == -1) {
+ pin2 = pin1;
+ apic2 = apic1;
+ }
+
if (pin1 != -1) {
/*
* Ok, does IRQ0 through the IOAPIC work?
@@ -2196,7 +2211,7 @@ static inline void __init check_timer(vo
if (timer_irq_works()) {
printk("works.\n");
timer_through_8259 = 1;
- if (pin1 != -1)
+ if (pin2 != pin1 || apic2 != apic1)
replace_pin_at_irq(0, apic1, pin1, apic2, pin2);
else
add_pin_to_irq(0, apic2, pin2);
diff -up --recursive --new-file linux-2.6.26-rc1-20080505.macro/arch/x86/kernel/io_apic_64.c linux-2.6.26-rc1-20080505/arch/x86/kernel/io_apic_64.c
--- linux-2.6.26-rc1-20080505.macro/arch/x86/kernel/io_apic_64.c 2008-05-18 00:24:43.000000000 +0000
+++ linux-2.6.26-rc1-20080505/arch/x86/kernel/io_apic_64.c 2008-05-18 00:24:43.000000000 +0000
@@ -1669,6 +1669,21 @@ static inline void __init check_timer(vo
apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
cfg->vector, apic1, pin1, apic2, pin2);
+ /*
+ * Some BIOS writers are clueless and report the ExtINTA
+ * I/O APIC input from the cascaded 8259A as the timer
+ * interrupt input. So just in case, if only one pin
+ * was found above, try it both directly and through the
+ * 8259A. --macro
+ */
+ if (pin1 == -1) {
+ pin1 = pin2;
+ apic1 = apic2;
+ } else if (pin2 == -1) {
+ pin2 = pin1;
+ apic2 = apic1;
+ }
+
if (pin1 != -1) {
/*
* Ok, does IRQ0 through the IOAPIC work?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/