diff options
Diffstat (limited to 'arch/i386/kernel/io_apic.c')
-rw-r--r-- | arch/i386/kernel/io_apic.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 08540bc4ba3e..35eb8e29c485 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -573,12 +573,14 @@ static int balanced_irq(void *unused) | |||
573 | for ( ; ; ) { | 573 | for ( ; ; ) { |
574 | set_current_state(TASK_INTERRUPTIBLE); | 574 | set_current_state(TASK_INTERRUPTIBLE); |
575 | time_remaining = schedule_timeout(time_remaining); | 575 | time_remaining = schedule_timeout(time_remaining); |
576 | try_to_freeze(PF_FREEZE); | 576 | try_to_freeze(); |
577 | if (time_after(jiffies, | 577 | if (time_after(jiffies, |
578 | prev_balance_time+balanced_irq_interval)) { | 578 | prev_balance_time+balanced_irq_interval)) { |
579 | preempt_disable(); | ||
579 | do_irq_balance(); | 580 | do_irq_balance(); |
580 | prev_balance_time = jiffies; | 581 | prev_balance_time = jiffies; |
581 | time_remaining = balanced_irq_interval; | 582 | time_remaining = balanced_irq_interval; |
583 | preempt_enable(); | ||
582 | } | 584 | } |
583 | } | 585 | } |
584 | return 0; | 586 | return 0; |
@@ -630,10 +632,8 @@ static int __init balanced_irq_init(void) | |||
630 | printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); | 632 | printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); |
631 | failed: | 633 | failed: |
632 | for (i = 0; i < NR_CPUS; i++) { | 634 | for (i = 0; i < NR_CPUS; i++) { |
633 | if(irq_cpu_data[i].irq_delta) | 635 | kfree(irq_cpu_data[i].irq_delta); |
634 | kfree(irq_cpu_data[i].irq_delta); | 636 | kfree(irq_cpu_data[i].last_irq); |
635 | if(irq_cpu_data[i].last_irq) | ||
636 | kfree(irq_cpu_data[i].last_irq); | ||
637 | } | 637 | } |
638 | return 0; | 638 | return 0; |
639 | } | 639 | } |
@@ -1634,12 +1634,43 @@ static void __init enable_IO_APIC(void) | |||
1634 | */ | 1634 | */ |
1635 | void disable_IO_APIC(void) | 1635 | void disable_IO_APIC(void) |
1636 | { | 1636 | { |
1637 | int pin; | ||
1637 | /* | 1638 | /* |
1638 | * Clear the IO-APIC before rebooting: | 1639 | * Clear the IO-APIC before rebooting: |
1639 | */ | 1640 | */ |
1640 | clear_IO_APIC(); | 1641 | clear_IO_APIC(); |
1641 | 1642 | ||
1642 | 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); | ||
1643 | } | 1674 | } |
1644 | 1675 | ||
1645 | /* | 1676 | /* |