[PATCH 4/7] ARM i.MX irq: Allow runtime decision between AVIC and TZIC

Sascha Hauer s.hauer at pengutronix.de
Fri Nov 5 05:46:08 EDT 2010


As we are on a path to support more different i.MX SoCs in a single
binary we have to able to support both AVIC and TZIC in a single
binary. This patch only introduces overhead when both controllers
are needed.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/plat-mxc/avic.c                     |    2 +
 arch/arm/plat-mxc/cpu.c                      |    3 +
 arch/arm/plat-mxc/include/mach/entry-macro.S |   66 ++++++++++++++++----------
 arch/arm/plat-mxc/include/mach/mxc.h         |    8 +++
 arch/arm/plat-mxc/tzic.c                     |    3 +
 5 files changed, 57 insertions(+), 25 deletions(-)

diff --git a/arch/arm/plat-mxc/avic.c b/arch/arm/plat-mxc/avic.c
index 7331f2a..1cb464a 100644
--- a/arch/arm/plat-mxc/avic.c
+++ b/arch/arm/plat-mxc/avic.c
@@ -118,6 +118,8 @@ void __init mxc_init_irq(void __iomem *irqbase)
 	int i;
 
 	avic_base = irqbase;
+	mxc_irq_base = irqbase;
+	mxc_irq_controller_type = MXC_IRQ_TYPE_AVIC;
 
 	/* put the AVIC into the reset value with
 	 * all interrupts disabled
diff --git a/arch/arm/plat-mxc/cpu.c b/arch/arm/plat-mxc/cpu.c
index 386e0d5..dc14a1c 100644
--- a/arch/arm/plat-mxc/cpu.c
+++ b/arch/arm/plat-mxc/cpu.c
@@ -9,3 +9,6 @@ void mxc_set_cpu_type(unsigned int type)
 	__mxc_cpu_type = type;
 }
 
+void __iomem *mxc_irq_base;
+int mxc_irq_controller_type;
+
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
index aeb0869..a7dd008 100644
--- a/arch/arm/plat-mxc/include/mach/entry-macro.S
+++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
@@ -18,40 +18,18 @@
 	.endm
 
 	.macro  get_irqnr_preamble, base, tmp
-#ifndef CONFIG_MXC_TZIC
-	ldr	\base, =avic_base
+	ldr	\base, =mxc_irq_base
 	ldr	\base, [\base]
 #ifdef CONFIG_MXC_IRQ_PRIOR
 	ldr	r4, [\base, #AVIC_NIMASK]
 #endif
-#elif defined CONFIG_MXC_TZIC
-	ldr	\base, =tzic_base
-	ldr	\base, [\base]
-#endif /* CONFIG_MXC_TZIC */
 	.endm
 
 	.macro  arch_ret_to_user, tmp1, tmp2
 	.endm
 
-	@ this macro checks which interrupt occured
-	@ and returns its number in irqnr
-	@ and returns if an interrupt occured in irqstat
-	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-#ifndef CONFIG_MXC_TZIC
-	@ Load offset & priority of the highest priority
-	@ interrupt pending from AVIC_NIVECSR
-	ldr	\irqstat, [\base, #0x40]
-	@ Shift to get the decoded IRQ number, using ASR so
-	@ 'no interrupt pending' becomes 0xffffffff
-	mov	\irqnr, \irqstat, asr #16
-	@ set zero flag if IRQ + 1 == 0
-	adds	\tmp, \irqnr, #1
-#ifdef CONFIG_MXC_IRQ_PRIOR
-	bicne	\tmp, \irqstat, #0xFFFFFFE0
-	strne	\tmp, [\base, #AVIC_NIMASK]
-	streq	r4, [\base, #AVIC_NIMASK]
-#endif
-#elif defined CONFIG_MXC_TZIC
+	.macro	tzic_get_irqnr_and_base, irqnr, irqstat, base, tmp
+
 	@ Load offset & priority of the highest priority
 	@ interrupt pending.
 	@ 0xD80 is HIPND0 register
@@ -76,6 +54,44 @@
 	mov  \irqnr, #0
 2002:
 	movs \irqnr, \irqnr
+	.endm
+
+	.macro	avic_get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+	@ Load offset & priority of the highest priority
+	@ interrupt pending from AVIC_NIVECSR
+	ldr	\irqstat, [\base, #0x40]
+	@ Shift to get the decoded IRQ number, using ASR so
+	@ 'no interrupt pending' becomes 0xffffffff
+	mov	\irqnr, \irqstat, asr #16
+	@ set zero flag if IRQ + 1 == 0
+	adds	\tmp, \irqnr, #1
+#ifdef CONFIG_MXC_IRQ_PRIOR
+	bicne	\tmp, \irqstat, #0xFFFFFFE0
+	strne	\tmp, [\base, #AVIC_NIMASK]
+	streq	r4, [\base, #AVIC_NIMASK]
+#endif
+	.endm
+
+	.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+#if defined CONFIG_MXC_TZIC && defined CONFIG_MXC_AVIC
+	ldr	\tmp, =mxc_irq_controller_type
+	ldr	\tmp, [\tmp]
+	cmp	\tmp, #MXC_IRQ_TYPE_AVIC
+	beq	3001f
+
+	tzic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
+	b	3002f
+3001:
+	avic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
+3002:
+
+#elif defined CONFIG_MXC_TZIC
+	tzic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
+#elif defined CONFIG_MXC_AVIC
+	avic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
+#else
+#error no tzic and no avic?
 #endif
 	.endm
 
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index a42c720..3432b78 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -154,4 +154,12 @@ extern struct cpu_op *(*get_cpu_op)(int *op);
 #define cpu_is_mx3()	(cpu_is_mx31() || cpu_is_mx35() || cpu_is_mxc91231())
 #define cpu_is_mx2()	(cpu_is_mx21() || cpu_is_mx27())
 
+#ifndef __ASSEMBLY__
+extern int mxc_irq_controller_type;
+extern void __iomem *mxc_irq_base;
+#endif
+
+#define MXC_IRQ_TYPE_AVIC	1
+#define MXC_IRQ_TYPE_TZIC	2
+
 #endif /*  __ASM_ARCH_MXC_H__ */
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
index 3703ab2..f2179b1 100644
--- a/arch/arm/plat-mxc/tzic.c
+++ b/arch/arm/plat-mxc/tzic.c
@@ -122,6 +122,9 @@ void __init tzic_init_irq(void __iomem *irqbase)
 	int i;
 
 	tzic_base = irqbase;
+	mxc_irq_base = irqbase;
+	mxc_irq_controller_type = MXC_IRQ_TYPE_TZIC;
+
 	/* put the TZIC into the reset value with
 	 * all interrupts disabled
 	 */
-- 
1.7.2.3




More information about the linux-arm-kernel mailing list