aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2011-03-28 10:13:24 -0400
committerThomas Gleixner <tglx@linutronix.de>2011-03-28 10:55:11 -0400
commit0521c8fbb3da45c2a58cd551ca6e9644983f6028 (patch)
treed2ed3452a75f1d3ff516cd02c86f4371db81e06e
parent32f4125ebffee4f3c4dbc6a437fc656129eb9e60 (diff)
genirq: Provide edge_eoi flow handler
This is a replacment for the cell flow handler which is in the way of cleanups. Must be selected to avoid general bloat. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--include/linux/irq.h1
-rw-r--r--kernel/irq/Kconfig4
-rw-r--r--kernel/irq/chip.c45
3 files changed, 50 insertions, 0 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 18aacccb0fae..44ebca745789 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -423,6 +423,7 @@ extern irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action);
423extern void handle_level_irq(unsigned int irq, struct irq_desc *desc); 423extern void handle_level_irq(unsigned int irq, struct irq_desc *desc);
424extern void handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc); 424extern void handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc);
425extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc); 425extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc);
426extern void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc);
426extern void handle_simple_irq(unsigned int irq, struct irq_desc *desc); 427extern void handle_simple_irq(unsigned int irq, struct irq_desc *desc);
427extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc); 428extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc);
428extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc); 429extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc);
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
index 00f2c037267a..72606ba10b14 100644
--- a/kernel/irq/Kconfig
+++ b/kernel/irq/Kconfig
@@ -51,6 +51,10 @@ config HARDIRQS_SW_RESEND
51config IRQ_PREFLOW_FASTEOI 51config IRQ_PREFLOW_FASTEOI
52 bool 52 bool
53 53
54# Edge style eoi based handler (cell)
55config IRQ_EDGE_EOI_HANDLER
56 bool
57
54# Support forced irq threading 58# Support forced irq threading
55config IRQ_FORCED_THREADING 59config IRQ_FORCED_THREADING
56 bool 60 bool
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index e00bdc56269f..451d1e81c15c 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -604,6 +604,51 @@ out_unlock:
604 raw_spin_unlock(&desc->lock); 604 raw_spin_unlock(&desc->lock);
605} 605}
606 606
607#ifdef CONFIG_IRQ_EDGE_EOI_HANDLER
608/**
609 * handle_edge_eoi_irq - edge eoi type IRQ handler
610 * @irq: the interrupt number
611 * @desc: the interrupt description structure for this irq
612 *
613 * Similar as the above handle_edge_irq, but using eoi and w/o the
614 * mask/unmask logic.
615 */
616void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc)
617{
618 struct irq_chip *chip = irq_desc_get_chip(desc);
619
620 raw_spin_lock(&desc->lock);
621
622 desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
623 /*
624 * If we're currently running this IRQ, or its disabled,
625 * we shouldn't process the IRQ. Mark it pending, handle
626 * the necessary masking and go out
627 */
628 if (unlikely(irqd_irq_disabled(&desc->irq_data) ||
629 irqd_irq_inprogress(&desc->irq_data) || !desc->action)) {
630 if (!irq_check_poll(desc)) {
631 desc->istate |= IRQS_PENDING;
632 goto out_eoi;
633 }
634 }
635 kstat_incr_irqs_this_cpu(irq, desc);
636
637 do {
638 if (unlikely(!desc->action))
639 goto out_eoi;
640
641 handle_irq_event(desc);
642
643 } while ((desc->istate & IRQS_PENDING) &&
644 !irqd_irq_disabled(&desc->irq_data));
645
646out_unlock:
647 chip->irq_eoi(&desc->irq_data);
648 raw_spin_unlock(&desc->lock);
649}
650#endif
651
607/** 652/**
608 * handle_percpu_irq - Per CPU local irq handler 653 * handle_percpu_irq - Per CPU local irq handler
609 * @irq: the interrupt number 654 * @irq: the interrupt number