aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq/chip.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2007-02-16 04:28:24 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-16 11:14:00 -0500
commit76d2160147f43f982dfe881404cfde9fd0a9da21 (patch)
tree5140d838f64e8494abd4942b4e2ddf2ddee69046 /kernel/irq/chip.c
parent1f2ea0837dbc263ce2a2512c4e73c83df68a6a55 (diff)
[PATCH] genirq: do not mask interrupts by default
Never mask interrupts immediately upon request. Disabling interrupts in high-performance codepaths is rare, and on the other hand this change could recover lost edges (or even other types of lost interrupts) by conservatively only masking interrupts after they happen. (NOTE: with this change the highlevel irq-disable code still soft-disables this IRQ line - and if such an interrupt happens then the IRQ flow handler keeps the IRQ masked.) Mark i8529A controllers as 'never loses an edge'. Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/irq/chip.c')
-rw-r--r--kernel/irq/chip.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 475e8a71bcdc..76a9106a0bf4 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -230,10 +230,6 @@ static void default_enable(unsigned int irq)
230 */ 230 */
231static void default_disable(unsigned int irq) 231static void default_disable(unsigned int irq)
232{ 232{
233 struct irq_desc *desc = irq_desc + irq;
234
235 if (!(desc->status & IRQ_DELAYED_DISABLE))
236 desc->chip->mask(irq);
237} 233}
238 234
239/* 235/*
@@ -298,13 +294,18 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc)
298 294
299 if (unlikely(desc->status & IRQ_INPROGRESS)) 295 if (unlikely(desc->status & IRQ_INPROGRESS))
300 goto out_unlock; 296 goto out_unlock;
301 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
302 kstat_cpu(cpu).irqs[irq]++; 297 kstat_cpu(cpu).irqs[irq]++;
303 298
304 action = desc->action; 299 action = desc->action;
305 if (unlikely(!action || (desc->status & IRQ_DISABLED))) 300 if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
301 if (desc->chip->mask)
302 desc->chip->mask(irq);
303 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
304 desc->status |= IRQ_PENDING;
306 goto out_unlock; 305 goto out_unlock;
306 }
307 307
308 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING | IRQ_PENDING);
308 desc->status |= IRQ_INPROGRESS; 309 desc->status |= IRQ_INPROGRESS;
309 spin_unlock(&desc->lock); 310 spin_unlock(&desc->lock);
310 311
@@ -396,11 +397,13 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
396 397
397 /* 398 /*
398 * If its disabled or no action available 399 * If its disabled or no action available
399 * keep it masked and get out of here 400 * then mask it and get out of here:
400 */ 401 */
401 action = desc->action; 402 action = desc->action;
402 if (unlikely(!action || (desc->status & IRQ_DISABLED))) { 403 if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
403 desc->status |= IRQ_PENDING; 404 desc->status |= IRQ_PENDING;
405 if (desc->chip->mask)
406 desc->chip->mask(irq);
404 goto out; 407 goto out;
405 } 408 }
406 409