aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/io_apic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/io_apic.c')
-rw-r--r--arch/i386/kernel/io_apic.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 3c2b3bdfc807..fc81c8cddd22 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -1636,12 +1636,43 @@ static void __init enable_IO_APIC(void)
1636 */ 1636 */
1637void disable_IO_APIC(void) 1637void disable_IO_APIC(void)
1638{ 1638{
1639 int pin;
1639 /* 1640 /*
1640 * Clear the IO-APIC before rebooting: 1641 * Clear the IO-APIC before rebooting:
1641 */ 1642 */
1642 clear_IO_APIC(); 1643 clear_IO_APIC();
1643 1644
1644 disconnect_bsp_APIC(); 1645 /*
1646 * If the i82559 is routed through an IOAPIC
1647 * Put that IOAPIC in virtual wire mode
1648 * so legacy interrups can be delivered.
1649 */
1650 pin = find_isa_irq_pin(0, mp_ExtINT);
1651 if (pin != -1) {
1652 struct IO_APIC_route_entry entry;
1653 unsigned long flags;
1654
1655 memset(&entry, 0, sizeof(entry));
1656 entry.mask = 0; /* Enabled */
1657 entry.trigger = 0; /* Edge */
1658 entry.irr = 0;
1659 entry.polarity = 0; /* High */
1660 entry.delivery_status = 0;
1661 entry.dest_mode = 0; /* Physical */
1662 entry.delivery_mode = 7; /* ExtInt */
1663 entry.vector = 0;
1664 entry.dest.physical.physical_dest = 0;
1665
1666
1667 /*
1668 * Add it to the IO-APIC irq-routing table:
1669 */
1670 spin_lock_irqsave(&ioapic_lock, flags);
1671 io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
1672 io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
1673 spin_unlock_irqrestore(&ioapic_lock, flags);
1674 }
1675 disconnect_bsp_APIC(pin != -1);
1645} 1676}
1646 1677
1647/* 1678/*