diff options
-rw-r--r-- | include/linux/irq.h | 1 | ||||
-rw-r--r-- | kernel/irq/Kconfig | 4 | ||||
-rw-r--r-- | kernel/irq/chip.c | 45 |
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); | |||
423 | extern void handle_level_irq(unsigned int irq, struct irq_desc *desc); | 423 | extern void handle_level_irq(unsigned int irq, struct irq_desc *desc); |
424 | extern void handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc); | 424 | extern void handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc); |
425 | extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc); | 425 | extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc); |
426 | extern void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc); | ||
426 | extern void handle_simple_irq(unsigned int irq, struct irq_desc *desc); | 427 | extern void handle_simple_irq(unsigned int irq, struct irq_desc *desc); |
427 | extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc); | 428 | extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc); |
428 | extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc); | 429 | extern 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 | |||
51 | config IRQ_PREFLOW_FASTEOI | 51 | config IRQ_PREFLOW_FASTEOI |
52 | bool | 52 | bool |
53 | 53 | ||
54 | # Edge style eoi based handler (cell) | ||
55 | config IRQ_EDGE_EOI_HANDLER | ||
56 | bool | ||
57 | |||
54 | # Support forced irq threading | 58 | # Support forced irq threading |
55 | config IRQ_FORCED_THREADING | 59 | config 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 | */ | ||
616 | void 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 | |||
646 | out_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 |