From: Andi Kleen <ak@muc.de>

Suggested by Ingo Molnar.

Drop APIC level workaround for old IO-APICs on x86-64 because it is a
significant part of interrupt handling time.  x86-64 only runs on modern
chipsets that probably don't have this bug.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/arch/x86_64/kernel/io_apic.c |   62 -----------------------------------
 1 files changed, 62 deletions(-)

diff -puN arch/x86_64/kernel/io_apic.c~drop-old-apic-workaround-on-x86-64 arch/x86_64/kernel/io_apic.c
--- 25/arch/x86_64/kernel/io_apic.c~drop-old-apic-workaround-on-x86-64	Tue Oct  5 14:13:13 2004
+++ 25-akpm/arch/x86_64/kernel/io_apic.c	Tue Oct  5 14:13:13 2004
@@ -41,10 +41,6 @@
 
 int sis_apic_bug; /* not actually supported, dummy for compile */
 
-#undef APIC_LOCKUP_DEBUG
-
-#define APIC_LOCKUP_DEBUG
-
 static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED;
 
 /*
@@ -131,10 +127,6 @@ DO_ACTION( __mask,             0, |= 0x0
 						/* mask = 1 */
 DO_ACTION( __unmask,           0, &= 0xfffeffff, )
 						/* mask = 0 */
-DO_ACTION( __mask_and_edge,    0, = (reg & 0xffff7fff) | 0x00010000, )
-						/* mask = 1, trigger = 0 */
-DO_ACTION( __unmask_and_level, 0, = (reg & 0xfffeffff) | 0x00008000, )
-						/* mask = 0, trigger = 1 */
 
 static void mask_IO_APIC_irq (unsigned int irq)
 {
@@ -1343,61 +1335,7 @@ static unsigned int startup_level_ioapic
 
 static void end_level_ioapic_irq (unsigned int irq)
 {
-	unsigned long v;
-	int i;
-
-/*
- * It appears there is an erratum which affects at least version 0x11
- * of I/O APIC (that's the 82093AA and cores integrated into various
- * chipsets).  Under certain conditions a level-triggered interrupt is
- * erroneously delivered as edge-triggered one but the respective IRR
- * bit gets set nevertheless.  As a result the I/O unit expects an EOI
- * message but it will never arrive and further interrupts are blocked
- * from the source.  The exact reason is so far unknown, but the
- * phenomenon was observed when two consecutive interrupt requests
- * from a given source get delivered to the same CPU and the source is
- * temporarily disabled in between.
- *
- * A workaround is to simulate an EOI message manually.  We achieve it
- * by setting the trigger mode to edge and then to level when the edge
- * trigger mode gets detected in the TMR of a local APIC for a
- * level-triggered interrupt.  We mask the source for the time of the
- * operation to prevent an edge-triggered interrupt escaping meanwhile.
- * The idea is from Manfred Spraul.  --macro
- */
-	i = IO_APIC_VECTOR(irq);
-	v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
-
 	ack_APIC_irq();
-
-	if (!(v & (1 << (i & 0x1f)))) {
-#ifdef APIC_LOCKUP_DEBUG
-		struct irq_pin_list *entry;
-#endif
-
-#ifdef APIC_MISMATCH_DEBUG
-		atomic_inc(&irq_mis_count);
-#endif
-		spin_lock(&ioapic_lock);
-		__mask_and_edge_IO_APIC_irq(irq);
-#ifdef APIC_LOCKUP_DEBUG
-		for (entry = irq_2_pin + irq;;) {
-			unsigned int reg;
-
-			if (entry->pin == -1)
-				break;
-			reg = io_apic_read(entry->apic, 0x10 + entry->pin * 2);
-			if (reg & 0x00004000)
-				printk(KERN_CRIT "Aieee!!!  Remote IRR"
-					" still set after unlock!\n");
-			if (!entry->next)
-				break;
-			entry = irq_2_pin + entry->next;
-		}
-#endif
-		__unmask_and_level_IO_APIC_irq(irq);
-		spin_unlock(&ioapic_lock);
-	}
 }
 
 static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
_