Commit 42a859daaf6af4d234fcf964a421666d5cca3f6a

Authored by Ludovic Desroches
Committed by Nicolas Ferre
1 parent f25b00be60

ARM: at91: aic can use fast eoi handler type

The Advanced Interrupt Controller allows us to use the fast EOI handler type.
It lets us remove the Atmel specific workaround into arch/arm/kernel/irq.c
used to indicate to the AIC the end of the interrupt treatment.

Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>

Showing 4 changed files with 17 additions and 24 deletions Side-by-side Diff

arch/arm/kernel/irq.c
... ... @@ -40,13 +40,6 @@
40 40 #include <asm/mach/irq.h>
41 41 #include <asm/mach/time.h>
42 42  
43   -/*
44   - * No architecture-specific irq_finish function defined in arm/arch/irqs.h.
45   - */
46   -#ifndef irq_finish
47   -#define irq_finish(irq) do { } while (0)
48   -#endif
49   -
50 43 unsigned long irq_err_count;
51 44  
52 45 int arch_show_interrupts(struct seq_file *p, int prec)
... ... @@ -84,9 +77,6 @@
84 77 } else {
85 78 generic_handle_irq(irq);
86 79 }
87   -
88   - /* AT91 specific workaround */
89   - irq_finish(irq);
90 80  
91 81 irq_exit();
92 82 set_irq_regs(old_regs);
arch/arm/mach-at91/gpio.c
... ... @@ -26,6 +26,8 @@
26 26 #include <linux/of_irq.h>
27 27 #include <linux/of_gpio.h>
28 28  
  29 +#include <asm/mach/irq.h>
  30 +
29 31 #include <mach/hardware.h>
30 32 #include <mach/at91_pio.h>
31 33  
32 34  
33 35  
... ... @@ -585,15 +587,14 @@
585 587  
586 588 static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
587 589 {
  590 + struct irq_chip *chip = irq_desc_get_chip(desc);
588 591 struct irq_data *idata = irq_desc_get_irq_data(desc);
589   - struct irq_chip *chip = irq_data_get_irq_chip(idata);
590 592 struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata);
591 593 void __iomem *pio = at91_gpio->regbase;
592 594 unsigned long isr;
593 595 int n;
594 596  
595   - /* temporarily mask (level sensitive) parent IRQ */
596   - chip->irq_ack(idata);
  597 + chained_irq_enter(chip, desc);
597 598 for (;;) {
598 599 /* Reading ISR acks pending (edge triggered) GPIO interrupts.
599 600 * When there none are pending, we're finished unless we need
... ... @@ -614,7 +615,7 @@
614 615 n = find_next_bit(&isr, BITS_PER_LONG, n + 1);
615 616 }
616 617 }
617   - chip->irq_unmask(idata);
  618 + chained_irq_exit(chip, desc);
618 619 /* now it may re-trigger */
619 620 }
620 621  
arch/arm/mach-at91/include/mach/irqs.h
... ... @@ -28,13 +28,6 @@
28 28  
29 29  
30 30 /*
31   - * Acknowledge interrupt with AIC after interrupt has been handled.
32   - * (by kernel/irq.c)
33   - */
34   -#define irq_finish(irq) do { at91_aic_write(AT91_AIC_EOICR, 0); } while (0)
35   -
36   -
37   -/*
38 31 * IRQ interrupt symbols are the AT91xxx_ID_* symbols
39 32 * for IRQs handled directly through the AIC, or else the AT91_PIN_*
40 33 * symbols in gpio.h for ones handled indirectly as GPIOs.
arch/arm/mach-at91/irq.c
... ... @@ -55,6 +55,15 @@
55 55 at91_aic_write(AT91_AIC_IECR, 1 << d->hwirq);
56 56 }
57 57  
  58 +static void at91_aic_eoi(struct irq_data *d)
  59 +{
  60 + /*
  61 + * Mark end-of-interrupt on AIC, the controller doesn't care about
  62 + * the value written. Moreover it's a write-only register.
  63 + */
  64 + at91_aic_write(AT91_AIC_EOICR, 0);
  65 +}
  66 +
58 67 unsigned int at91_extern_irq;
59 68  
60 69 #define is_extern_irq(hwirq) ((1 << (hwirq)) & at91_extern_irq)
61 70  
... ... @@ -128,11 +137,11 @@
128 137  
129 138 static struct irq_chip at91_aic_chip = {
130 139 .name = "AIC",
131   - .irq_ack = at91_aic_mask_irq,
132 140 .irq_mask = at91_aic_mask_irq,
133 141 .irq_unmask = at91_aic_unmask_irq,
134 142 .irq_set_type = at91_aic_set_type,
135 143 .irq_set_wake = at91_aic_set_wake,
  144 + .irq_eoi = at91_aic_eoi,
136 145 };
137 146  
138 147 static void __init at91_aic_hw_init(unsigned int spu_vector)
... ... @@ -171,7 +180,7 @@
171 180 /* Active Low interrupt, without priority */
172 181 at91_aic_write(AT91_AIC_SMR(hw), AT91_AIC_SRCTYPE_LOW);
173 182  
174   - irq_set_chip_and_handler(virq, &at91_aic_chip, handle_level_irq);
  183 + irq_set_chip_and_handler(virq, &at91_aic_chip, handle_fasteoi_irq);
175 184 set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
176 185  
177 186 return 0;
... ... @@ -238,7 +247,7 @@
238 247 /* Active Low interrupt, with the specified priority */
239 248 at91_aic_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]);
240 249  
241   - irq_set_chip_and_handler(i, &at91_aic_chip, handle_level_irq);
  250 + irq_set_chip_and_handler(i, &at91_aic_chip, handle_fasteoi_irq);
242 251 set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
243 252 }
244 253