summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2002-09-03 21:06:01 -0700
committerPaul Mackerras <paulus@au1.ibm.com>2002-09-03 21:06:01 -0700
commite42e97d63b46995f3f0d073cae433e4eb87ff5de (patch)
tree99e52f2693381323775f33e182f3e8b03154d5bc
parent863032a9e5cd5e8a340cc1f44faa11589719b103 (diff)
Fix IO-APIC edge IRQ handling. IRQ_INPROGRESS was cleared spuriously
if a new edge happened while we were still processing the previous one. Then, if a _third_ edge came in, it would actually cause a reentrant irq handler invocation, because the original INPROGRESS bit was now lost. This was actually seen on IDE in PIO mode.
-rw-r--r--arch/i386/kernel/irq.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index b283b5c0c8b1..ac767766b6d7 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -380,8 +380,9 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs)
break;
desc->status &= ~IRQ_PENDING;
}
-out:
desc->status &= ~IRQ_INPROGRESS;
+
+out:
/*
* The ->end() handler has to deal with interrupts which got
* disabled while the handler was running.
@@ -768,7 +769,7 @@ int setup_irq(unsigned int irq, struct irqaction * new)
if (!shared) {
desc->depth = 0;
- desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
+ desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
desc->handler->startup(irq);
}
spin_unlock_irqrestore(&desc->lock,flags);