diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2002-09-03 21:06:01 -0700 |
|---|---|---|
| committer | Paul Mackerras <paulus@au1.ibm.com> | 2002-09-03 21:06:01 -0700 |
| commit | e42e97d63b46995f3f0d073cae433e4eb87ff5de (patch) | |
| tree | 99e52f2693381323775f33e182f3e8b03154d5bc | |
| parent | 863032a9e5cd5e8a340cc1f44faa11589719b103 (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.c | 5 |
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); |
