From: Ludovic Desroches Date: Fri, 25 May 2012 12:11:51 +0000 (+0200) Subject: ARM: at91: aic can use fast eoi handler type X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=42a859daaf6af4d234fcf964a421666d5cca3f6a;p=~shefty%2Frdma-dev.git 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 Signed-off-by: Will Deacon --- diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 8349d4e97e2..16cedb42c0c 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -40,13 +40,6 @@ #include #include -/* - * No architecture-specific irq_finish function defined in arm/arch/irqs.h. - */ -#ifndef irq_finish -#define irq_finish(irq) do { } while (0) -#endif - unsigned long irq_err_count; int arch_show_interrupts(struct seq_file *p, int prec) @@ -85,9 +78,6 @@ void handle_IRQ(unsigned int irq, struct pt_regs *regs) generic_handle_irq(irq); } - /* AT91 specific workaround */ - irq_finish(irq); - irq_exit(); set_irq_regs(old_regs); } diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 325837a264c..be42cf0e74b 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -26,6 +26,8 @@ #include #include +#include + #include #include @@ -585,15 +587,14 @@ static struct irq_chip gpio_irqchip = { static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) { + struct irq_chip *chip = irq_desc_get_chip(desc); struct irq_data *idata = irq_desc_get_irq_data(desc); - struct irq_chip *chip = irq_data_get_irq_chip(idata); struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); void __iomem *pio = at91_gpio->regbase; unsigned long isr; int n; - /* temporarily mask (level sensitive) parent IRQ */ - chip->irq_ack(idata); + chained_irq_enter(chip, desc); for (;;) { /* Reading ISR acks pending (edge triggered) GPIO interrupts. * 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) n = find_next_bit(&isr, BITS_PER_LONG, n + 1); } } - chip->irq_unmask(idata); + chained_irq_exit(chip, desc); /* now it may re-trigger */ } diff --git a/arch/arm/mach-at91/include/mach/irqs.h b/arch/arm/mach-at91/include/mach/irqs.h index ac8b7dfc85e..2d510ee6ac0 100644 --- a/arch/arm/mach-at91/include/mach/irqs.h +++ b/arch/arm/mach-at91/include/mach/irqs.h @@ -27,13 +27,6 @@ #define NR_AIC_IRQS 32 -/* - * Acknowledge interrupt with AIC after interrupt has been handled. - * (by kernel/irq.c) - */ -#define irq_finish(irq) do { at91_aic_write(AT91_AIC_EOICR, 0); } while (0) - - /* * IRQ interrupt symbols are the AT91xxx_ID_* symbols * for IRQs handled directly through the AIC, or else the AT91_PIN_* diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c index cfcfcbe3626..2d5d4c88a52 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) at91_aic_write(AT91_AIC_IECR, 1 << d->hwirq); } +static void at91_aic_eoi(struct irq_data *d) +{ + /* + * Mark end-of-interrupt on AIC, the controller doesn't care about + * the value written. Moreover it's a write-only register. + */ + at91_aic_write(AT91_AIC_EOICR, 0); +} + unsigned int at91_extern_irq; #define is_extern_irq(hwirq) ((1 << (hwirq)) & at91_extern_irq) @@ -128,11 +137,11 @@ void at91_irq_resume(void) static struct irq_chip at91_aic_chip = { .name = "AIC", - .irq_ack = at91_aic_mask_irq, .irq_mask = at91_aic_mask_irq, .irq_unmask = at91_aic_unmask_irq, .irq_set_type = at91_aic_set_type, .irq_set_wake = at91_aic_set_wake, + .irq_eoi = at91_aic_eoi, }; 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, /* Active Low interrupt, without priority */ at91_aic_write(AT91_AIC_SMR(hw), AT91_AIC_SRCTYPE_LOW); - irq_set_chip_and_handler(virq, &at91_aic_chip, handle_level_irq); + irq_set_chip_and_handler(virq, &at91_aic_chip, handle_fasteoi_irq); set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); return 0; @@ -238,7 +247,7 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS]) /* Active Low interrupt, with the specified priority */ at91_aic_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); - irq_set_chip_and_handler(i, &at91_aic_chip, handle_level_irq); + irq_set_chip_and_handler(i, &at91_aic_chip, handle_fasteoi_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); }