[PATCH] ARM: OMAP2+: irq: Increase no of supported interrupts to 128

Vaibhav Hiremath hvaibhav at ti.com
Tue May 8 10:17:59 EDT 2012


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 at ti.com>
Signed-off-by: Afzal Mohammed <afzal at ti.com>
Cc: Tony Lindgren <tony at atomide.com>
Cc: Kevin Hilman <khilman at ti.com>
Cc: Paul Walmsley <paul at pwsan.com>
---
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




More information about the linux-arm-kernel mailing list