Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42a859da authored by Ludovic Desroches's avatar Ludovic Desroches Committed by Nicolas Ferre
Browse files

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: default avatarLudovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent f25b00be
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -40,13 +40,6 @@
#include <asm/mach/irq.h>
#include <asm/mach/time.h>

/*
 * 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);
}
+5 −4
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@
#include <linux/of_irq.h>
#include <linux/of_gpio.h>

#include <asm/mach/irq.h>

#include <mach/hardware.h>
#include <mach/at91_pio.h>

@@ -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 */
}

+0 −7
Original line number Diff line number Diff line
@@ -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_*
+12 −3
Original line number Diff line number Diff line
@@ -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);
	}