summaryrefslogtreecommitdiffstats
path: root/include/asm-arm/arch-s3c2410/entry-macro.S
blob: b7d4d7f4422d97dbcc08c47cd383f2a33c6eee3d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
 * include/asm-arm/arch-s3c2410/entry-macro.S
 *
 * Low-level IRQ helper macros for S3C2410-based platforms
 *
 * 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.

 * Modifications:
 *     10-Mar-2005 LCVR  Changed S3C2410_VA to S3C24XX_VA
 */


	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp

		mov	\tmp, #S3C24XX_VA_IRQ
		ldr	\irqnr, [ \tmp, #0x14 ]		@ get irq no
30000:
		teq	\irqnr, #4
		teqne	\irqnr, #5
		beq	1002f				@ external irq reg

		@ debug check to see if interrupt reported is the same
		@ as the offset....

		teq	\irqnr, #0
		beq	20002f
		ldr	\irqstat, [ \tmp, #0x10 ]	@ INTPND
		mov	\irqstat, \irqstat, lsr \irqnr
		tst	\irqstat, #1
		bne	20002f

		/* debug/warning if we get an invalud response from the
		 * INTOFFSET register */
#if 1
		stmfd	r13!, { r0 - r4 , r8-r12, r14 }
		ldr	r1,	[ \tmp, #0x14 ]		@ INTOFFSET
		ldr	r2,	[ \tmp, #0x10 ]		@ INTPND
		ldr	r3,	[ \tmp, #0x00 ]		@ SRCPND
		adr	r0, 20003f
		bl	printk
		b	20004f

20003:
		.ascii	"<7>irq: err - bad offset %d, intpnd=%08x, srcpnd=%08x\n"
		.byte	0
		.align	4
20004:
		mov	r1, #1
		mov	\tmp, #S3C24XX_VA_IRQ
		ldmfd	r13!, { r0 - r4 , r8-r12, r14 }
#endif

		@ try working out interrupt number for ourselves
		mov	\irqnr, #0
		ldr	\irqstat, [ \tmp, #0x10 ]	@ INTPND
10021:
		movs	\irqstat, \irqstat, lsr#1
		bcs	30000b		@ try and re-start the proccess
		add	\irqnr, \irqnr, #1
		cmp	\irqnr, #32
		ble	10021b

		@ found no interrupt, set Z flag and leave
		movs	\irqnr, #0
		b	1001f

20005:
20002:		@ exit
		@ we base the s3c2410x interrupts at 16 and above to allow
		@ isa peripherals to have their standard interrupts, also
		@ ensure that Z flag is un-set on exit

		@ note, we cannot be sure if we get IRQ_EINT0 (0) that
		@ there is simply no interrupt pending, so in all other
		@ cases we jump to say we have found something, otherwise
		@ we check to see if the interrupt really is assrted
		adds	\irqnr, \irqnr, #IRQ_EINT0
		teq	\irqnr, #IRQ_EINT0
		bne	1001f				@ exit
		ldr	\irqstat, [ \tmp, #0x10 ]	@ INTPND
		teq	\irqstat, #0
		moveq	\irqnr, #0
		b	1001f

		@ we get here from no main or external interrupts pending
1002:
		add	\tmp, \tmp, #S3C24XX_VA_GPIO - S3C24XX_VA_IRQ
		ldr	\irqstat, [ \tmp, # 0xa8 ]	@ EXTINTPEND
		ldr	\irqnr, [ \tmp, # 0xa4 ]	@ EXTINTMASK

		bic	\irqstat, \irqstat, \irqnr	@ clear masked irqs

		mov	\irqnr, #IRQ_EINT4		@ start extint nos
		mov	\irqstat, \irqstat, lsr#4	@ ignore bottom 4 bits
10021:
		movs	\irqstat, \irqstat, lsr#1
		bcs	1004f
		add	\irqnr, \irqnr, #1
		cmp	\irqnr, #IRQ_EINT23
		ble	10021b

		@ found no interrupt, set Z flag and leave
		movs	\irqnr, #0

1004:		@ ensure Z flag clear in case our MOVS shifted out the last bit
		teq	\irqnr, #0
1001:
		@ exit irq routine
		.endm


		/* currently don't need an disable_fiq macro */

		.macro	disable_fiq
		.endm