diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/io_apic_64.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c index f06f5b4fb35f..40aa041b2987 100644 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c | |||
@@ -360,6 +360,26 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin) | |||
360 | entry->pin = pin; | 360 | entry->pin = pin; |
361 | } | 361 | } |
362 | 362 | ||
363 | /* | ||
364 | * Reroute an IRQ to a different pin. | ||
365 | */ | ||
366 | static void __init replace_pin_at_irq(unsigned int irq, | ||
367 | int oldapic, int oldpin, | ||
368 | int newapic, int newpin) | ||
369 | { | ||
370 | struct irq_pin_list *entry = irq_2_pin + irq; | ||
371 | |||
372 | while (1) { | ||
373 | if (entry->apic == oldapic && entry->pin == oldpin) { | ||
374 | entry->apic = newapic; | ||
375 | entry->pin = newpin; | ||
376 | } | ||
377 | if (!entry->next) | ||
378 | break; | ||
379 | entry = irq_2_pin + entry->next; | ||
380 | } | ||
381 | } | ||
382 | |||
363 | 383 | ||
364 | #define DO_ACTION(name,R,ACTION, FINAL) \ | 384 | #define DO_ACTION(name,R,ACTION, FINAL) \ |
365 | \ | 385 | \ |
@@ -1680,6 +1700,11 @@ static inline void __init check_timer(void) | |||
1680 | apic2 = apic1; | 1700 | apic2 = apic1; |
1681 | } | 1701 | } |
1682 | 1702 | ||
1703 | replace_pin_at_irq(0, 0, 0, apic1, pin1); | ||
1704 | apic1 = 0; | ||
1705 | pin1 = 0; | ||
1706 | setup_timer_IRQ0_pin(apic1, pin1, cfg->vector); | ||
1707 | |||
1683 | if (pin1 != -1) { | 1708 | if (pin1 != -1) { |
1684 | /* | 1709 | /* |
1685 | * Ok, does IRQ0 through the IOAPIC work? | 1710 | * Ok, does IRQ0 through the IOAPIC work? |
@@ -1712,10 +1737,9 @@ static inline void __init check_timer(void) | |||
1712 | /* | 1737 | /* |
1713 | * legacy devices should be connected to IO APIC #0 | 1738 | * legacy devices should be connected to IO APIC #0 |
1714 | */ | 1739 | */ |
1715 | /* replace_pin_at_irq(0, apic1, pin1, apic2, pin2); */ | 1740 | replace_pin_at_irq(0, apic1, pin1, apic2, pin2); |
1716 | setup_timer_IRQ0_pin(apic2, pin2, cfg->vector); | 1741 | setup_timer_IRQ0_pin(apic2, pin2, cfg->vector); |
1717 | unmask_IO_APIC_irq(0); | 1742 | unmask_IO_APIC_irq(0); |
1718 | clear_IO_APIC_pin(apic2, pin2); | ||
1719 | enable_8259A_irq(0); | 1743 | enable_8259A_irq(0); |
1720 | if (timer_irq_works()) { | 1744 | if (timer_irq_works()) { |
1721 | apic_printk(APIC_VERBOSE," works.\n"); | 1745 | apic_printk(APIC_VERBOSE," works.\n"); |