From b694331cfb2ec3bc2225a0ea9fddbb7e24d81c37 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 20 May 2015 09:01:21 -0700 Subject: ARM: omap1: Switch to use MULTI_IRQ This allows us to get a bit further with SPARSE_IRQ and MULTIARCH support. Note that we now also rename omap_irq_flags to omap_l2_irq as that's the omap_irq_flags naming is confusing. It just contains the interrupt number for the l2 irq. Cc: Aaro Koskinen Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/irq.c | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'arch/arm/mach-omap1/irq.c') diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c index 3651b17aeb10..567fba35bd94 100644 --- a/arch/arm/mach-omap1/irq.c +++ b/arch/arm/mach-omap1/irq.c @@ -43,6 +43,7 @@ #include #include +#include #include #include "soc.h" @@ -61,7 +62,7 @@ struct omap_irq_bank { unsigned long wake_enable; }; -u32 omap_irq_flags; +static u32 omap_l2_irq; static unsigned int irq_bank_count; static struct omap_irq_bank *irq_banks; static struct irq_domain *domain; @@ -140,6 +141,36 @@ static struct omap_irq_bank omap1610_irq_banks[] = { }; #endif +asmlinkage void __exception_irq_entry omap1_handle_irq(struct pt_regs *regs) +{ + void __iomem *l1 = irq_banks[0].va; + void __iomem *l2 = irq_banks[1].va; + u32 irqnr; + + do { + irqnr = readl_relaxed(l1 + IRQ_ITR_REG_OFFSET); + irqnr &= ~(readl_relaxed(l1 + IRQ_MIR_REG_OFFSET) & 0xffffffff); + if (!irqnr) + break; + + irqnr = readl_relaxed(l1 + IRQ_SIR_FIQ_REG_OFFSET); + if (irqnr) + goto irq; + + irqnr = readl_relaxed(l1 + IRQ_SIR_IRQ_REG_OFFSET); + if (irqnr == omap_l2_irq) { + irqnr = readl_relaxed(l2 + IRQ_SIR_IRQ_REG_OFFSET); + if (irqnr) + irqnr += 32; + } +irq: + if (irqnr) + handle_domain_irq(domain, irqnr, regs); + else + break; + } while (irqnr); +} + static __init void omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) { @@ -167,26 +198,22 @@ void __init omap1_init_irq(void) #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) if (cpu_is_omap7xx()) { - omap_irq_flags = INT_7XX_IH2_IRQ; irq_banks = omap7xx_irq_banks; irq_bank_count = ARRAY_SIZE(omap7xx_irq_banks); } #endif #ifdef CONFIG_ARCH_OMAP15XX if (cpu_is_omap1510()) { - omap_irq_flags = INT_1510_IH2_IRQ; irq_banks = omap1510_irq_banks; irq_bank_count = ARRAY_SIZE(omap1510_irq_banks); } if (cpu_is_omap310()) { - omap_irq_flags = INT_1510_IH2_IRQ; irq_banks = omap310_irq_banks; irq_bank_count = ARRAY_SIZE(omap310_irq_banks); } #endif #if defined(CONFIG_ARCH_OMAP16XX) if (cpu_is_omap16xx()) { - omap_irq_flags = INT_1510_IH2_IRQ; irq_banks = omap1610_irq_banks; irq_bank_count = ARRAY_SIZE(omap1610_irq_banks); } @@ -205,6 +232,7 @@ void __init omap1_init_irq(void) pr_warn("Couldn't allocate IRQ numbers\n"); irq_base = 0; } + omap_l2_irq = cpu_is_omap7xx() ? irq_base + 1 : irq_base; domain = irq_domain_add_legacy(NULL, nr_irqs, irq_base, 0, &irq_domain_simple_ops, NULL); @@ -239,7 +267,7 @@ void __init omap1_init_irq(void) } /* Unmask level 2 handler */ - d = irq_get_irq_data(omap_irq_flags); + d = irq_get_irq_data(irq_find_mapping(domain, omap_l2_irq)); if (d) { ct = irq_data_get_chip_type(d); ct->chip.irq_unmask(d); -- cgit