diff options
author | Ludovic Desroches <ludovic.desroches@atmel.com> | 2012-05-25 08:11:51 -0400 |
---|---|---|
committer | Nicolas Ferre <nicolas.ferre@atmel.com> | 2012-07-02 08:26:57 -0400 |
commit | 42a859daaf6af4d234fcf964a421666d5cca3f6a (patch) | |
tree | a025e57314554a8547b1afd782c7982631298adb | |
parent | f25b00be60ab3865308a89437af66b277b04f53e (diff) |
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>
-rw-r--r-- | arch/arm/kernel/irq.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-at91/gpio.c | 9 | ||||
-rw-r--r-- | arch/arm/mach-at91/include/mach/irqs.h | 7 | ||||
-rw-r--r-- | arch/arm/mach-at91/irq.c | 15 |
4 files changed, 17 insertions, 24 deletions
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 8349d4e97e2b..16cedb42c0c3 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c | |||
@@ -40,13 +40,6 @@ | |||
40 | #include <asm/mach/irq.h> | 40 | #include <asm/mach/irq.h> |
41 | #include <asm/mach/time.h> | 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 | unsigned long irq_err_count; | 43 | unsigned long irq_err_count; |
51 | 44 | ||
52 | int arch_show_interrupts(struct seq_file *p, int prec) | 45 | int arch_show_interrupts(struct seq_file *p, int prec) |
@@ -85,9 +78,6 @@ void handle_IRQ(unsigned int irq, struct pt_regs *regs) | |||
85 | generic_handle_irq(irq); | 78 | generic_handle_irq(irq); |
86 | } | 79 | } |
87 | 80 | ||
88 | /* AT91 specific workaround */ | ||
89 | irq_finish(irq); | ||
90 | |||
91 | irq_exit(); | 81 | irq_exit(); |
92 | set_irq_regs(old_regs); | 82 | set_irq_regs(old_regs); |
93 | } | 83 | } |
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 325837a264c9..be42cf0e74bd 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/of_irq.h> | 26 | #include <linux/of_irq.h> |
27 | #include <linux/of_gpio.h> | 27 | #include <linux/of_gpio.h> |
28 | 28 | ||
29 | #include <asm/mach/irq.h> | ||
30 | |||
29 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
30 | #include <mach/at91_pio.h> | 32 | #include <mach/at91_pio.h> |
31 | 33 | ||
@@ -585,15 +587,14 @@ static struct irq_chip gpio_irqchip = { | |||
585 | 587 | ||
586 | static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | 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 | struct irq_data *idata = irq_desc_get_irq_data(desc); | 591 | struct irq_data *idata = irq_desc_get_irq_data(desc); |
589 | struct irq_chip *chip = irq_data_get_irq_chip(idata); | ||
590 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); | 592 | struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); |
591 | void __iomem *pio = at91_gpio->regbase; | 593 | void __iomem *pio = at91_gpio->regbase; |
592 | unsigned long isr; | 594 | unsigned long isr; |
593 | int n; | 595 | int n; |
594 | 596 | ||
595 | /* temporarily mask (level sensitive) parent IRQ */ | 597 | chained_irq_enter(chip, desc); |
596 | chip->irq_ack(idata); | ||
597 | for (;;) { | 598 | for (;;) { |
598 | /* Reading ISR acks pending (edge triggered) GPIO interrupts. | 599 | /* Reading ISR acks pending (edge triggered) GPIO interrupts. |
599 | * When there none are pending, we're finished unless we need | 600 | * When there none are pending, we're finished unless we need |
@@ -614,7 +615,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
614 | n = find_next_bit(&isr, BITS_PER_LONG, n + 1); | 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 | /* now it may re-trigger */ | 619 | /* now it may re-trigger */ |
619 | } | 620 | } |
620 | 621 | ||
diff --git a/arch/arm/mach-at91/include/mach/irqs.h b/arch/arm/mach-at91/include/mach/irqs.h index ac8b7dfc85ef..2d510ee6ac03 100644 --- a/arch/arm/mach-at91/include/mach/irqs.h +++ b/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 | * IRQ interrupt symbols are the AT91xxx_ID_* symbols | 31 | * IRQ interrupt symbols are the AT91xxx_ID_* symbols |
39 | * for IRQs handled directly through the AIC, or else the AT91_PIN_* | 32 | * for IRQs handled directly through the AIC, or else the AT91_PIN_* |
40 | * symbols in gpio.h for ones handled indirectly as GPIOs. | 33 | * symbols in gpio.h for ones handled indirectly as GPIOs. |
diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c index cfcfcbe36269..2d5d4c88a527 100644 --- a/arch/arm/mach-at91/irq.c +++ b/arch/arm/mach-at91/irq.c | |||
@@ -55,6 +55,15 @@ static void at91_aic_unmask_irq(struct irq_data *d) | |||
55 | at91_aic_write(AT91_AIC_IECR, 1 << d->hwirq); | 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 | unsigned int at91_extern_irq; | 67 | unsigned int at91_extern_irq; |
59 | 68 | ||
60 | #define is_extern_irq(hwirq) ((1 << (hwirq)) & at91_extern_irq) | 69 | #define is_extern_irq(hwirq) ((1 << (hwirq)) & at91_extern_irq) |
@@ -128,11 +137,11 @@ void at91_irq_resume(void) | |||
128 | 137 | ||
129 | static struct irq_chip at91_aic_chip = { | 138 | static struct irq_chip at91_aic_chip = { |
130 | .name = "AIC", | 139 | .name = "AIC", |
131 | .irq_ack = at91_aic_mask_irq, | ||
132 | .irq_mask = at91_aic_mask_irq, | 140 | .irq_mask = at91_aic_mask_irq, |
133 | .irq_unmask = at91_aic_unmask_irq, | 141 | .irq_unmask = at91_aic_unmask_irq, |
134 | .irq_set_type = at91_aic_set_type, | 142 | .irq_set_type = at91_aic_set_type, |
135 | .irq_set_wake = at91_aic_set_wake, | 143 | .irq_set_wake = at91_aic_set_wake, |
144 | .irq_eoi = at91_aic_eoi, | ||
136 | }; | 145 | }; |
137 | 146 | ||
138 | static void __init at91_aic_hw_init(unsigned int spu_vector) | 147 | static void __init at91_aic_hw_init(unsigned int spu_vector) |
@@ -171,7 +180,7 @@ static int at91_aic_irq_map(struct irq_domain *h, unsigned int virq, | |||
171 | /* Active Low interrupt, without priority */ | 180 | /* Active Low interrupt, without priority */ |
172 | at91_aic_write(AT91_AIC_SMR(hw), AT91_AIC_SRCTYPE_LOW); | 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 | set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); | 184 | set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); |
176 | 185 | ||
177 | return 0; | 186 | return 0; |
@@ -238,7 +247,7 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS]) | |||
238 | /* Active Low interrupt, with the specified priority */ | 247 | /* Active Low interrupt, with the specified priority */ |
239 | at91_aic_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); | 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 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); | 251 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); |
243 | } | 252 | } |
244 | 253 | ||