With addition to TI81XX, AM33XX family of devices, the number of interrupts supported has increased to 128, compared to 96. The current implementation for irq handling is hardcoded to use 96 interrupts (with 3 register-sets to handle), this patch cleanups the code, to increase maximum number of interrupts support to 128, with dynamic detection of no of registers required for handling all interrupts. Signed-off-by: Vaibhav Hiremath <hvaibhav@xxxxxx> Signed-off-by: Afzal Mohammed <afzal@xxxxxx> Cc: Tony Lindgren <tony@xxxxxxxxxxx> Cc: Kevin Hilman <khilman@xxxxxx> Cc: Paul Walmsley <paul@xxxxxxxxx> --- Ideally, we should use dynamic allocation to allocate memory for registers/arrays, may be too much cleanup for this patch, so as of now restricting to minimal changes to fit devices like, am33xx/ti81xx. arch/arm/mach-omap2/irq.c | 47 +++++++++++++++---------------- arch/arm/plat-omap/include/plat/irqs.h | 7 +++- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index 80f3ced..ea5aed9 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -58,10 +58,12 @@ static struct omap_irq_bank { void __iomem *base_reg; unsigned int nr_irqs; + unsigned int nr_regs_req; } __attribute__ ((aligned(4))) irq_banks[] = { { /* MPU INTC */ .nr_irqs = 96, + .nr_regs_req = 3, }, }; @@ -73,8 +75,8 @@ struct omap3_intc_regs { u32 protection; u32 idle; u32 threshold; - u32 ilr[INTCPS_NR_IRQS]; - u32 mir[INTCPS_NR_MIR_REGS]; + u32 ilr[INTCPS_MAX_NR_IRQS]; + u32 mir[INTCPS_MAX_NR_REGS_REQ]; }; /* INTC bank register get/set */ @@ -182,6 +184,7 @@ static void __init omap_init_irq(u32 base, int nr_irqs, struct omap_irq_bank *bank = irq_banks + i; bank->nr_irqs = nr_irqs; + bank->nr_regs_req = 0; /* Static mapping, never released */ bank->base_reg = ioremap(base, SZ_4K); @@ -192,8 +195,10 @@ static void __init omap_init_irq(u32 base, int nr_irqs, omap_irq_bank_init_one(bank); - for (j = 0; j < bank->nr_irqs; j += 32) + for (j = 0; j < bank->nr_irqs; j += 32) { omap_alloc_gc(bank->base_reg + j, j + irq_base, 32); + bank->nr_regs_req++; + } nr_of_irqs += bank->nr_irqs; nr_banks++; @@ -218,25 +223,19 @@ void __init ti81xx_init_irq(void) omap_init_irq(OMAP34XX_IC_BASE, 128, NULL); } -static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs) +static inline void omap_intc_handle_irq(void __iomem *base_addr, + unsigned int no_regs_req, struct pt_regs *regs) { - u32 irqnr; + u32 irqnr = 0; do { - irqnr = readl_relaxed(base_addr + 0x98); - if (irqnr) - goto out; - - irqnr = readl_relaxed(base_addr + 0xb8); - if (irqnr) - goto out; + int i = 0; - irqnr = readl_relaxed(base_addr + 0xd8); -#ifdef CONFIG_SOC_OMAPTI816X - if (irqnr) - goto out; - irqnr = readl_relaxed(base_addr + 0xf8); -#endif + for (i = 0; i < no_regs_req; i++) { + irqnr = readl_relaxed(base_addr + 0x98 + (0x20 * i)); + if (irqnr) + goto out; + } out: if (!irqnr) @@ -255,7 +254,7 @@ out: asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs) { void __iomem *base_addr = OMAP2_IRQ_BASE; - omap_intc_handle_irq(base_addr, regs); + omap_intc_handle_irq(base_addr, irq_banks[0].nr_regs_req, regs); } int __init omap_intc_of_init(struct device_node *node, @@ -296,10 +295,10 @@ void omap_intc_save_context(void) intc_bank_read_reg(bank, INTC_IDLE); intc_context[ind].threshold = intc_bank_read_reg(bank, INTC_THRESHOLD); - for (i = 0; i < INTCPS_NR_IRQS; i++) + for (i = 0; i < bank->nr_irqs; i++) intc_context[ind].ilr[i] = intc_bank_read_reg(bank, (0x100 + 0x4*i)); - for (i = 0; i < INTCPS_NR_MIR_REGS; i++) + for (i = 0; i < bank->nr_regs_req; i++) intc_context[ind].mir[i] = intc_bank_read_reg(&irq_banks[0], INTC_MIR0 + (0x20 * i)); @@ -322,10 +321,10 @@ void omap_intc_restore_context(void) bank, INTC_IDLE); intc_bank_write_reg(intc_context[ind].threshold, bank, INTC_THRESHOLD); - for (i = 0; i < INTCPS_NR_IRQS; i++) + for (i = 0; i < bank->nr_irqs; i++) intc_bank_write_reg(intc_context[ind].ilr[i], bank, (0x100 + 0x4*i)); - for (i = 0; i < INTCPS_NR_MIR_REGS; i++) + for (i = 0; i < bank->nr_regs_req; i++) intc_bank_write_reg(intc_context[ind].mir[i], &irq_banks[0], INTC_MIR0 + (0x20 * i)); } @@ -356,6 +355,6 @@ void omap3_intc_resume_idle(void) asmlinkage void __exception_irq_entry omap3_intc_handle_irq(struct pt_regs *regs) { void __iomem *base_addr = OMAP3_IRQ_BASE; - omap_intc_handle_irq(base_addr, regs); + omap_intc_handle_irq(base_addr, irq_banks[0].nr_regs_req, regs); } #endif /* CONFIG_ARCH_OMAP3 */ diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h index 37bbbbb..8e1b6ae 100644 --- a/arch/arm/plat-omap/include/plat/irqs.h +++ b/arch/arm/plat-omap/include/plat/irqs.h @@ -441,8 +441,11 @@ #define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32)) -#define INTCPS_NR_MIR_REGS 3 -#define INTCPS_NR_IRQS 96 +/* + * Max from AM33XX device + */ +#define INTCPS_MAX_NR_REGS_REQ 4 +#define INTCPS_MAX_NR_IRQS 128 #include <mach/hardware.h> -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html