diff options
Diffstat (limited to 'arch/arm/plat-omap/include/mach/entry-macro.S')
| -rw-r--r-- | arch/arm/plat-omap/include/mach/entry-macro.S | 83 | 
1 files changed, 78 insertions, 5 deletions
diff --git a/arch/arm/plat-omap/include/mach/entry-macro.S b/arch/arm/plat-omap/include/mach/entry-macro.S index 2276f89671d..56426ed45ef 100644 --- a/arch/arm/plat-omap/include/mach/entry-macro.S +++ b/arch/arm/plat-omap/include/mach/entry-macro.S @@ -3,6 +3,9 @@   *   * Low-level IRQ helper macros for OMAP-based platforms   * + * Copyright (C) 2009 Texas Instruments + * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> + *   * This file is licensed under  the terms of the GNU General Public   * License version 2. This program is licensed "as is" without any   * warranty of any kind, whether express or implied. @@ -10,6 +13,7 @@  #include <mach/hardware.h>  #include <mach/io.h>  #include <mach/irqs.h> +#include <asm/hardware/gic.h>  #if defined(CONFIG_ARCH_OMAP1) @@ -56,15 +60,21 @@  		.endm  #endif -#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) +#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ +			defined(CONFIG_ARCH_OMAP4) -#if defined(CONFIG_ARCH_OMAP24XX)  #include <mach/omap24xx.h> -#endif -#if defined(CONFIG_ARCH_OMAP34XX)  #include <mach/omap34xx.h> -#endif +/* REVISIT: This should be set dynamically if CONFIG_MULTI_OMAP2 is selected */ +#if defined(CONFIG_ARCH_OMAP2420) || defined(CONFIG_ARCH_OMAP2430) +#define OMAP2_VA_IC_BASE		IO_ADDRESS(OMAP24XX_IC_BASE) +#elif defined(CONFIG_ARCH_OMAP34XX) +#define OMAP2_VA_IC_BASE		IO_ADDRESS(OMAP34XX_IC_BASE) +#endif +#if defined(CONFIG_ARCH_OMAP4) +#include <mach/omap44xx.h> +#endif  #define INTCPS_SIR_IRQ_OFFSET	0x0040		/* Active interrupt offset */  #define	ACTIVEIRQ_MASK		0x7f		/* Active interrupt bits */ @@ -77,6 +87,7 @@  		.macro  arch_ret_to_user, tmp1, tmp2  		.endm +#ifndef CONFIG_ARCH_OMAP4  		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp  		ldr	\base, =OMAP2_VA_IC_BASE  		ldr	\irqnr, [\base, #0x98] /* IRQ pending reg 1 */ @@ -92,6 +103,68 @@  		and	\irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */  		.endm +#else +		/* +		 * The interrupt numbering scheme is defined in the +		 * interrupt controller spec.  To wit: +		 * +		 * Interrupts 0-15 are IPI +		 * 16-28 are reserved +		 * 29-31 are local.  We allow 30 to be used for the watchdog. +		 * 32-1020 are global +		 * 1021-1022 are reserved +		 * 1023 is "spurious" (no interrupt) +		 * +		 * For now, we ignore all local interrupts so only return an +		 * interrupt if it's between 30 and 1020.  The test_for_ipi +		 * routine below will pick up on IPIs. +		 * A simple read from the controller will tell us the number +		 * of the highest priority enabled interrupt. +		 * We then just need to check whether it is in the +		 * valid range for an IRQ (30-1020 inclusive). +		 */ +		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp +		ldr     \base, =OMAP44XX_VA_GIC_CPU_BASE +		ldr     \irqstat, [\base, #GIC_CPU_INTACK] + +		ldr     \tmp, =1021 + +		bic     \irqnr, \irqstat, #0x1c00 + +		cmp     \irqnr, #29 +		cmpcc   \irqnr, \irqnr +		cmpne   \irqnr, \tmp +		cmpcs   \irqnr, \irqnr +		.endm + +		/* We assume that irqstat (the raw value of the IRQ acknowledge +		 * register) is preserved from the macro above. +		 * If there is an IPI, we immediately signal end of interrupt +		 * on the controller, since this requires the original irqstat +		 * value which we won't easily be able to recreate later. +		 */ + +		.macro test_for_ipi, irqnr, irqstat, base, tmp +		bic	\irqnr, \irqstat, #0x1c00 +		cmp	\irqnr, #16 +		it	cc +		strcc	\irqstat, [\base, #GIC_CPU_EOI] +		it	cs +		cmpcs	\irqnr, \irqnr +		.endm + +		/* As above, this assumes that irqstat and base are preserved */ + +		.macro test_for_ltirq, irqnr, irqstat, base, tmp +		bic	\irqnr, \irqstat, #0x1c00 +		mov 	\tmp, #0 +		cmp	\irqnr, #29 +		itt	eq +		moveq	\tmp, #1 +		streq	\irqstat, [\base, #GIC_CPU_EOI] +		cmp	\tmp, #0 +		.endm +#endif  		.macro	irq_prio_table  		.endm  |