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 18aacccb0fa..44ebca74578 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 00f2c037267..72606ba10b1 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 e00bdc56269..451d1e81c15 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 |
