aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/kernel/apic.c20
-rw-r--r--include/asm-i386/apicdef.h1
2 files changed, 21 insertions, 0 deletions
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index eb5279d23b7f..3fff3c62d57a 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -415,6 +415,7 @@ void __init init_bsp_APIC(void)
415void __devinit setup_local_APIC(void) 415void __devinit setup_local_APIC(void)
416{ 416{
417 unsigned long oldvalue, value, ver, maxlvt; 417 unsigned long oldvalue, value, ver, maxlvt;
418 int i, j;
418 419
419 /* Pound the ESR really hard over the head with a big hammer - mbligh */ 420 /* Pound the ESR really hard over the head with a big hammer - mbligh */
420 if (esr_disable) { 421 if (esr_disable) {
@@ -452,6 +453,25 @@ void __devinit setup_local_APIC(void)
452 apic_write_around(APIC_TASKPRI, value); 453 apic_write_around(APIC_TASKPRI, value);
453 454
454 /* 455 /*
456 * After a crash, we no longer service the interrupts and a pending
457 * interrupt from previous kernel might still have ISR bit set.
458 *
459 * Most probably by now CPU has serviced that pending interrupt and
460 * it might not have done the ack_APIC_irq() because it thought,
461 * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it
462 * does not clear the ISR bit and cpu thinks it has already serivced
463 * the interrupt. Hence a vector might get locked. It was noticed
464 * for timer irq (vector 0x31). Issue an extra EOI to clear ISR.
465 */
466 for (i = APIC_ISR_NR - 1; i >= 0; i--) {
467 value = apic_read(APIC_ISR + i*0x10);
468 for (j = 31; j >= 0; j--) {
469 if (value & (1<<j))
470 ack_APIC_irq();
471 }
472 }
473
474 /*
455 * Now that we are all set up, enable the APIC 475 * Now that we are all set up, enable the APIC
456 */ 476 */
457 value = apic_read(APIC_SPIV); 477 value = apic_read(APIC_SPIV);
diff --git a/include/asm-i386/apicdef.h b/include/asm-i386/apicdef.h
index 03185cef8e0a..5e4a35af2921 100644
--- a/include/asm-i386/apicdef.h
+++ b/include/asm-i386/apicdef.h
@@ -37,6 +37,7 @@
37#define APIC_SPIV_FOCUS_DISABLED (1<<9) 37#define APIC_SPIV_FOCUS_DISABLED (1<<9)
38#define APIC_SPIV_APIC_ENABLED (1<<8) 38#define APIC_SPIV_APIC_ENABLED (1<<8)
39#define APIC_ISR 0x100 39#define APIC_ISR 0x100
40#define APIC_ISR_NR 0x8 /* Number of 32 bit ISR registers. */
40#define APIC_TMR 0x180 41#define APIC_TMR 0x180
41#define APIC_IRR 0x200 42#define APIC_IRR 0x200
42#define APIC_ESR 0x280 43#define APIC_ESR 0x280