entry-macro.S 4.8 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
2
 * arch/arm/plat-omap/include/mach/entry-macro.S
L
Linus Torvalds 已提交
3 4 5
 *
 * Low-level IRQ helper macros for OMAP-based platforms
 *
6 7 8
 * Copyright (C) 2009 Texas Instruments
 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
 *
L
Linus Torvalds 已提交
9 10 11 12
 * 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.
 */
13 14 15
#include <mach/hardware.h>
#include <mach/io.h>
#include <mach/irqs.h>
16
#include <asm/hardware/gic.h>
L
Linus Torvalds 已提交
17

18 19
#if defined(CONFIG_ARCH_OMAP1)

20
#if (defined(CONFIG_ARCH_OMAP730)||defined(CONFIG_ARCH_OMAP850)) && \
21
	(defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX))
22 23
#error "FIXME: OMAP7XX doesn't support multiple-OMAP"
#elif defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
24
#define INT_IH2_IRQ		INT_7XX_IH2_IRQ
25 26 27 28 29 30 31 32 33
#elif defined(CONFIG_ARCH_OMAP15XX)
#define INT_IH2_IRQ		INT_1510_IH2_IRQ
#elif defined(CONFIG_ARCH_OMAP16XX)
#define INT_IH2_IRQ		INT_1610_IH2_IRQ
#else
#warning "IH2 IRQ defaulted"
#define INT_IH2_IRQ		INT_1510_IH2_IRQ
#endif

L
Linus Torvalds 已提交
34 35 36
 		.macro	disable_fiq
		.endm

37 38 39 40 41 42
		.macro  get_irqnr_preamble, base, tmp
		.endm

		.macro  arch_ret_to_user, tmp1, tmp2
		.endm

L
Linus Torvalds 已提交
43
		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
44
		ldr	\base, =OMAP1_IO_ADDRESS(OMAP_IH1_BASE)
L
Linus Torvalds 已提交
45 46 47 48 49 50 51 52 53 54 55
		ldr	\irqnr, [\base, #IRQ_ITR_REG_OFFSET]
		ldr	\tmp, [\base, #IRQ_MIR_REG_OFFSET]
		mov	\irqstat, #0xffffffff
		bic	\tmp, \irqstat, \tmp
		tst	\irqnr, \tmp
		beq	1510f

		ldr	\irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET]
		cmp	\irqnr, #0
		ldreq	\irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
		cmpeq	\irqnr, #INT_IH2_IRQ
56
		ldreq	\base, =OMAP1_IO_ADDRESS(OMAP_IH2_BASE)
L
Linus Torvalds 已提交
57 58 59 60 61
		ldreq	\irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
		addeqs	\irqnr, \irqnr, #32
1510:
		.endm

62
#endif
63 64
#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
			defined(CONFIG_ARCH_OMAP4)
65

66
#include <mach/omap24xx.h>
67
#include <mach/omap34xx.h>
68 69 70

/* REVISIT: This should be set dynamically if CONFIG_MULTI_OMAP2 is selected */
#if defined(CONFIG_ARCH_OMAP2420) || defined(CONFIG_ARCH_OMAP2430)
71
#define OMAP2_VA_IC_BASE		OMAP2_IO_ADDRESS(OMAP24XX_IC_BASE)
72
#elif defined(CONFIG_ARCH_OMAP34XX)
73
#define OMAP2_VA_IC_BASE		OMAP2_IO_ADDRESS(OMAP34XX_IC_BASE)
74
#endif
75 76 77
#if defined(CONFIG_ARCH_OMAP4)
#include <mach/omap44xx.h>
#endif
78 79
#define INTCPS_SIR_IRQ_OFFSET	0x0040		/* Active interrupt offset */
#define	ACTIVEIRQ_MASK		0x7f		/* Active interrupt bits */
80 81 82 83

		.macro	disable_fiq
		.endm

84 85 86 87 88 89
		.macro  get_irqnr_preamble, base, tmp
		.endm

		.macro  arch_ret_to_user, tmp1, tmp2
		.endm

90
#ifndef CONFIG_ARCH_OMAP4
91
		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
92
		ldr	\base, =OMAP2_VA_IC_BASE
93 94 95 96 97 98 99 100 101
		ldr	\irqnr, [\base, #0x98] /* IRQ pending reg 1 */
		cmp	\irqnr, #0x0
		bne	2222f
		ldr	\irqnr, [\base, #0xb8] /* IRQ pending reg 2 */
		cmp	\irqnr, #0x0
		bne	2222f
		ldr	\irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
		cmp	\irqnr, #0x0
2222:
102
		ldrne	\irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
103
		and	\irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */
104 105

		.endm
106
#else
107 108
#define OMAP44XX_VA_GIC_CPU_BASE	OMAP2_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE)

109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
		/*
		 * 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
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168

		/* 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
169
#endif
170 171 172 173 174

		.macro	irq_prio_table
		.endm

#endif