diff options
Diffstat (limited to 'arch/i386/kernel/io_apic.c')
-rw-r--r-- | arch/i386/kernel/io_apic.c | 58 |
1 files changed, 46 insertions, 12 deletions
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 7a324e8b86f9..6578f40bd501 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -31,12 +31,13 @@ | |||
31 | #include <linux/mc146818rtc.h> | 31 | #include <linux/mc146818rtc.h> |
32 | #include <linux/compiler.h> | 32 | #include <linux/compiler.h> |
33 | #include <linux/acpi.h> | 33 | #include <linux/acpi.h> |
34 | 34 | #include <linux/module.h> | |
35 | #include <linux/sysdev.h> | 35 | #include <linux/sysdev.h> |
36 | #include <asm/io.h> | 36 | #include <asm/io.h> |
37 | #include <asm/smp.h> | 37 | #include <asm/smp.h> |
38 | #include <asm/desc.h> | 38 | #include <asm/desc.h> |
39 | #include <asm/timer.h> | 39 | #include <asm/timer.h> |
40 | #include <asm/i8259.h> | ||
40 | 41 | ||
41 | #include <mach_apic.h> | 42 | #include <mach_apic.h> |
42 | 43 | ||
@@ -573,12 +574,14 @@ static int balanced_irq(void *unused) | |||
573 | for ( ; ; ) { | 574 | for ( ; ; ) { |
574 | set_current_state(TASK_INTERRUPTIBLE); | 575 | set_current_state(TASK_INTERRUPTIBLE); |
575 | time_remaining = schedule_timeout(time_remaining); | 576 | time_remaining = schedule_timeout(time_remaining); |
576 | try_to_freeze(PF_FREEZE); | 577 | try_to_freeze(); |
577 | if (time_after(jiffies, | 578 | if (time_after(jiffies, |
578 | prev_balance_time+balanced_irq_interval)) { | 579 | prev_balance_time+balanced_irq_interval)) { |
580 | preempt_disable(); | ||
579 | do_irq_balance(); | 581 | do_irq_balance(); |
580 | prev_balance_time = jiffies; | 582 | prev_balance_time = jiffies; |
581 | time_remaining = balanced_irq_interval; | 583 | time_remaining = balanced_irq_interval; |
584 | preempt_enable(); | ||
582 | } | 585 | } |
583 | } | 586 | } |
584 | return 0; | 587 | return 0; |
@@ -630,10 +633,8 @@ static int __init balanced_irq_init(void) | |||
630 | printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); | 633 | printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); |
631 | failed: | 634 | failed: |
632 | for (i = 0; i < NR_CPUS; i++) { | 635 | for (i = 0; i < NR_CPUS; i++) { |
633 | if(irq_cpu_data[i].irq_delta) | 636 | kfree(irq_cpu_data[i].irq_delta); |
634 | kfree(irq_cpu_data[i].irq_delta); | 637 | kfree(irq_cpu_data[i].last_irq); |
635 | if(irq_cpu_data[i].last_irq) | ||
636 | kfree(irq_cpu_data[i].last_irq); | ||
637 | } | 638 | } |
638 | return 0; | 639 | return 0; |
639 | } | 640 | } |
@@ -812,6 +813,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) | |||
812 | } | 813 | } |
813 | return best_guess; | 814 | return best_guess; |
814 | } | 815 | } |
816 | EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector); | ||
815 | 817 | ||
816 | /* | 818 | /* |
817 | * This function currently is only a helper for the i386 smp boot process where | 819 | * This function currently is only a helper for the i386 smp boot process where |
@@ -1565,7 +1567,6 @@ void print_all_local_APICs (void) | |||
1565 | 1567 | ||
1566 | void /*__init*/ print_PIC(void) | 1568 | void /*__init*/ print_PIC(void) |
1567 | { | 1569 | { |
1568 | extern spinlock_t i8259A_lock; | ||
1569 | unsigned int v; | 1570 | unsigned int v; |
1570 | unsigned long flags; | 1571 | unsigned long flags; |
1571 | 1572 | ||
@@ -1633,12 +1634,43 @@ static void __init enable_IO_APIC(void) | |||
1633 | */ | 1634 | */ |
1634 | void disable_IO_APIC(void) | 1635 | void disable_IO_APIC(void) |
1635 | { | 1636 | { |
1637 | int pin; | ||
1636 | /* | 1638 | /* |
1637 | * Clear the IO-APIC before rebooting: | 1639 | * Clear the IO-APIC before rebooting: |
1638 | */ | 1640 | */ |
1639 | clear_IO_APIC(); | 1641 | clear_IO_APIC(); |
1640 | 1642 | ||
1641 | disconnect_bsp_APIC(); | 1643 | /* |
1644 | * If the i82559 is routed through an IOAPIC | ||
1645 | * Put that IOAPIC in virtual wire mode | ||
1646 | * so legacy interrups can be delivered. | ||
1647 | */ | ||
1648 | pin = find_isa_irq_pin(0, mp_ExtINT); | ||
1649 | if (pin != -1) { | ||
1650 | struct IO_APIC_route_entry entry; | ||
1651 | unsigned long flags; | ||
1652 | |||
1653 | memset(&entry, 0, sizeof(entry)); | ||
1654 | entry.mask = 0; /* Enabled */ | ||
1655 | entry.trigger = 0; /* Edge */ | ||
1656 | entry.irr = 0; | ||
1657 | entry.polarity = 0; /* High */ | ||
1658 | entry.delivery_status = 0; | ||
1659 | entry.dest_mode = 0; /* Physical */ | ||
1660 | entry.delivery_mode = 7; /* ExtInt */ | ||
1661 | entry.vector = 0; | ||
1662 | entry.dest.physical.physical_dest = 0; | ||
1663 | |||
1664 | |||
1665 | /* | ||
1666 | * Add it to the IO-APIC irq-routing table: | ||
1667 | */ | ||
1668 | spin_lock_irqsave(&ioapic_lock, flags); | ||
1669 | io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1)); | ||
1670 | io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0)); | ||
1671 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
1672 | } | ||
1673 | disconnect_bsp_APIC(pin != -1); | ||
1642 | } | 1674 | } |
1643 | 1675 | ||
1644 | /* | 1676 | /* |
@@ -1659,6 +1691,12 @@ static void __init setup_ioapic_ids_from_mpc(void) | |||
1659 | unsigned long flags; | 1691 | unsigned long flags; |
1660 | 1692 | ||
1661 | /* | 1693 | /* |
1694 | * Don't check I/O APIC IDs for xAPIC systems. They have | ||
1695 | * no meaning without the serial APIC bus. | ||
1696 | */ | ||
1697 | if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && boot_cpu_data.x86 < 15)) | ||
1698 | return; | ||
1699 | /* | ||
1662 | * This is broken; anything with a real cpu count has to | 1700 | * This is broken; anything with a real cpu count has to |
1663 | * circumvent this idiocy regardless. | 1701 | * circumvent this idiocy regardless. |
1664 | */ | 1702 | */ |
@@ -1684,10 +1722,6 @@ static void __init setup_ioapic_ids_from_mpc(void) | |||
1684 | mp_ioapics[apic].mpc_apicid = reg_00.bits.ID; | 1722 | mp_ioapics[apic].mpc_apicid = reg_00.bits.ID; |
1685 | } | 1723 | } |
1686 | 1724 | ||
1687 | /* Don't check I/O APIC IDs for some xAPIC systems. They have | ||
1688 | * no meaning without the serial APIC bus. */ | ||
1689 | if (NO_IOAPIC_CHECK) | ||
1690 | continue; | ||
1691 | /* | 1725 | /* |
1692 | * Sanity check, is the ID really free? Every APIC in a | 1726 | * Sanity check, is the ID really free? Every APIC in a |
1693 | * system must have a unique ID or we get lots of nice | 1727 | * system must have a unique ID or we get lots of nice |