diff options
author | 2014-08-29 13:46:08 +0200 | |
---|---|---|
committer | 2014-09-01 13:48:36 +0200 | |
commit | c3d7acd0273edf0ee50ccf85167acd7ae0759eda (patch) | |
tree | 933f3a5cdd177962ef68d7f62f55dd6c72750631 /kernel/irq | |
parent | genirq: Avoid double loop on suspend (diff) | |
download | linux-c3d7acd0273edf0ee50ccf85167acd7ae0759eda.tar.gz linux-c3d7acd0273edf0ee50ccf85167acd7ae0759eda.tar.bz2 linux-c3d7acd0273edf0ee50ccf85167acd7ae0759eda.zip |
genirq: Distangle edge handler entry
If the interrupt is disabled or has no action, then we should not call
the poll check. Separate the checks.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'kernel/irq')
-rw-r--r-- | kernel/irq/chip.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index a2b28a2fd7b1..f10c2e58a786 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -540,19 +540,29 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc) raw_spin_lock(&desc->lock); desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); + /* - * If we're currently running this IRQ, or its disabled, - * we shouldn't process the IRQ. Mark it pending, handle - * the necessary masking and go out + * If the handler is currently running, mark it pending, + * handle the necessary masking and go out */ - if (unlikely(irqd_irq_disabled(&desc->irq_data) || - irqd_irq_inprogress(&desc->irq_data) || !desc->action)) { + if (unlikely(irqd_irq_inprogress(&desc->irq_data))) { if (!irq_check_poll(desc)) { desc->istate |= IRQS_PENDING; mask_ack_irq(desc); goto out_unlock; } } + + /* + * If its disabled or no action available then mask it and get + * out of here. + */ + if (irqd_irq_disabled(&desc->irq_data) || !desc->action) { + desc->istate |= IRQS_PENDING; + mask_ack_irq(desc); + goto out_unlock; + } + kstat_incr_irqs_this_cpu(irq, desc); /* Start handling the irq */ @@ -601,18 +611,27 @@ void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc) raw_spin_lock(&desc->lock); desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); + /* - * If we're currently running this IRQ, or its disabled, - * we shouldn't process the IRQ. Mark it pending, handle - * the necessary masking and go out + * If the handler is currently running, mark it pending, + * handle the necessary masking and go out */ - if (unlikely(irqd_irq_disabled(&desc->irq_data) || - irqd_irq_inprogress(&desc->irq_data) || !desc->action)) { + if (unlikely(irqd_irq_inprogress(&desc->irq_data))) { if (!irq_check_poll(desc)) { desc->istate |= IRQS_PENDING; goto out_eoi; } } + + /* + * If its disabled or no action available then mask it and get + * out of here. + */ + if (irqd_irq_disabled(&desc->irq_data) || !desc->action) { + desc->istate |= IRQS_PENDING; + goto out_eoi; + } + kstat_incr_irqs_this_cpu(irq, desc); do { |