Merge git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86
[firefly-linux-kernel-4.4.55.git] / arch / x86 / kernel / io_apic_32.c
index 6bb80ea5f4eecbdee2206a1b04cd07278f0924e0..6cf27319a91c3938b457e6b2eb94e2f5d3c35464 100644 (file)
@@ -2166,6 +2166,10 @@ static inline void __init check_timer(void)
 {
        int apic1, pin1, apic2, pin2;
        int vector;
+       unsigned int ver;
+
+       ver = apic_read(APIC_LVR);
+       ver = GET_APIC_VERSION(ver);
 
        /*
         * get/set the timer IRQ vector:
@@ -2179,11 +2183,15 @@ static inline void __init check_timer(void)
         * mode for the 8259A whenever interrupts are routed
         * 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.
+        * disabled in the local APIC.  Finally timer interrupts
+        * need to be acknowledged manually in the 8259A for
+        * timer_interrupt() and for the i82489DX when using
+        * the NMI watchdog.
         */
        apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
        init_8259A(1);
-       timer_ack = 1;
+       timer_ack = !cpu_has_tsc;
+       timer_ack |= (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
        if (timer_over_8254 > 0)
                enable_8259A_irq(0);