[PATCH 4/7] ARM i.MX irq: Allow runtime decision between AVIC and TZIC
Uwe Kleine-König
u.kleine-koenig at pengutronix.de
Fri Nov 5 06:37:33 EDT 2010
On Fri, Nov 05, 2010 at 10:46:08AM +0100, Sascha Hauer wrote:
> 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;
Is avic_base still needed?
> + 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;
ditto for tzic_base.
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
More information about the linux-arm-kernel
mailing list