Commit d11d5794 authored by Maciej W. Rozycki's avatar Maciej W. Rozycki Committed by Ingo Molnar

x86: I/O APIC: AEOI timer acknowledgement clean-ups

The code that used to be in do_slow_gettimeoffset() that relied on the
IRR bit of the master 8259A PIC for IRQ0 to check the state of the output
timer 0 of the PIT is no longer there.  As a result, there is no need to
use the POLL command to acknowledge the timer interrupt in the "8259A
Virtual Wire", except for the NMI watchdog when the i82489DX APIC is used
(this is because this particular APIC treats NMIs as level-triggered and
keeping the input asserted would keep motherboard NMI sources held off for
too long).  Remove the unneeded bits and adjust comments accordingly.
Signed-off-by: default avatarMaciej W. Rozycki <macro@linux-mips.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent a0176e24
...@@ -2146,19 +2146,17 @@ static inline void __init check_timer(void) ...@@ -2146,19 +2146,17 @@ static inline void __init check_timer(void)
set_intr_gate(vector, interrupt[0]); set_intr_gate(vector, interrupt[0]);
/* /*
* Subtle, code in do_timer_interrupt() expects an AEOI * As IRQ0 is to be enabled in the 8259A, the virtual
* mode for the 8259A whenever interrupts are routed * wire has to be disabled in the local APIC. Also
* through I/O APICs. Also IRQ0 has to be enabled in * timer interrupts need to be acknowledged manually in
* the 8259A which implies the virtual wire has to be * the 8259A for the i82489DX when using the NMI
* disabled in the local APIC. Finally timer interrupts * watchdog as that APIC treats NMIs as level-triggered.
* need to be acknowledged manually in the 8259A for * The AEOI mode will finish them in the 8259A
* timer_interrupt() and for the i82489DX when using * automatically.
* the NMI watchdog.
*/ */
apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
init_8259A(1); init_8259A(1);
timer_ack = !cpu_has_tsc; timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
timer_ack |= (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
if (timer_over_8254 > 0) if (timer_over_8254 > 0)
enable_8259A_irq(0); enable_8259A_irq(0);
...@@ -2219,6 +2217,7 @@ static inline void __init check_timer(void) ...@@ -2219,6 +2217,7 @@ static inline void __init check_timer(void)
printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n"); printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
nmi_watchdog = 0; nmi_watchdog = 0;
} }
timer_ack = 0;
printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
...@@ -2237,7 +2236,6 @@ static inline void __init check_timer(void) ...@@ -2237,7 +2236,6 @@ static inline void __init check_timer(void)
printk(KERN_INFO "...trying to set up timer as ExtINT IRQ..."); printk(KERN_INFO "...trying to set up timer as ExtINT IRQ...");
timer_ack = 0;
init_8259A(0); init_8259A(0);
make_8259A_irq(0); make_8259A_irq(0);
apic_write_around(APIC_LVT0, APIC_DM_EXTINT); apic_write_around(APIC_LVT0, APIC_DM_EXTINT);
......
...@@ -1669,11 +1669,8 @@ static inline void __init check_timer(void) ...@@ -1669,11 +1669,8 @@ static inline void __init check_timer(void)
assign_irq_vector(0, TARGET_CPUS); assign_irq_vector(0, TARGET_CPUS);
/* /*
* Subtle, code in do_timer_interrupt() expects an AEOI * As IRQ0 is to be enabled in the 8259A, the virtual
* mode for the 8259A whenever interrupts are routed * wire has to be disabled in the local APIC.
* through I/O APICs. Also IRQ0 has to be enabled in
* the 8259A which implies the virtual wire has to be
* disabled in the local APIC.
*/ */
apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
init_8259A(1); init_8259A(1);
......
...@@ -131,7 +131,7 @@ int __init check_nmi_watchdog(void) ...@@ -131,7 +131,7 @@ int __init check_nmi_watchdog(void)
kfree(prev_nmi_count); kfree(prev_nmi_count);
return 0; return 0;
error: error:
timer_ack = !cpu_has_tsc; timer_ack = 0;
return -1; return -1;
} }
......
...@@ -84,8 +84,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) ...@@ -84,8 +84,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
if (timer_ack) { if (timer_ack) {
/* /*
* Subtle, when I/O APICs are used we have to ack timer IRQ * Subtle, when I/O APICs are used we have to ack timer IRQ
* manually to reset the IRR bit for do_slow_gettimeoffset(). * manually to deassert NMI lines for the watchdog if run
* This will also deassert NMI lines for the watchdog if run
* on an 82489DX-based system. * on an 82489DX-based system.
*/ */
spin_lock(&i8259A_lock); spin_lock(&i8259A_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment