1
/*====================================================================
2
* Project: Board Support Package (BSP)
4
* Function: Handling of IRQ interrupts on Intel XScale PXA255
6
* Copyright HighTec EDV-Systeme GmbH 1982-2006
7
*====================================================================*/
9
#include "pxa255regs.h"
12
#define IRQ_MAX_NUM ISR_MAX+1 /* first and second level */
13
#define IRQ_MAX_HW_NUM ISR_MAX_HW+1 /* first level only */
15
/* IRQ dispatcher table for ISRs */
16
static PFV irqVector[IRQ_MAX_NUM];
18
static void IrqGPIOHandler(void);
21
* Priority resolution table
22
* Index with a bit mask and you get the highest priority in the mask
23
* which is set in the mask. Least significant bit is highest priority.
25
static const unsigned char unmapTbl[] =
27
0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
28
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
29
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
30
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
31
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
32
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
33
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
34
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
35
7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
36
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
37
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
38
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
39
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
40
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
41
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
42
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
46
/*---------------------------------------------------------------------
48
Purpose: Initialization of IRQ handling
51
---------------------------------------------------------------------*/
56
*ICMR = 0; /* disable all interrupts */
57
*ICLR = 0; /* all mapped to IRQ */
59
/* clear all GPIO edge register */
66
/* reset edge flags */
71
*ICCR = 1; /* only enabled IRQs can wake up */
73
/* Clear the interrupt vector table */
74
for (i = 0; i < IRQ_MAX_NUM; ++i)
76
irqVector[i] = (PFV) 0;
79
/* Install dispatcher for GPIO[80:2] IRQs */
80
irqVector[GPIO_INT_ID] = IrqGPIOHandler;
83
/*---------------------------------------------------------------------
85
Purpose: enable IRQ for an IRQ interrupt
86
Arguments: int irqNum - number of IRQ interrupt
88
---------------------------------------------------------------------*/
89
void IrqEnable(int irqNum)
91
if ((irqNum < IRQ_MAX_HW_NUM) && (irqNum >= ISR_MIN))
93
*ICMR |= (1 << irqNum);
97
/*---------------------------------------------------------------------
99
Purpose: disable IRQ for an IRQ interrupt
100
Arguments: int irqNum - number of IRQ interrupt
102
---------------------------------------------------------------------*/
103
void IrqDisable(int irqNum)
105
if ((irqNum < IRQ_MAX_HW_NUM) && (irqNum >= ISR_MIN))
107
*ICMR &= ~(1 << irqNum);
111
/*---------------------------------------------------------------------
113
Purpose: Install a service handler for an IRQ interrupt
114
Arguments: int irqNum - number of IRQ interrupt
115
PFV isrProc - pointer to service routine
116
Return: PFV - pointer to old service routine
117
---------------------------------------------------------------------*/
118
PFV IrqInstall(int irqNum, PFV isrProc)
122
if (irqNum < ISR_MIN || IRQ_MAX_NUM <= irqNum)
127
oldIsr = irqVector[irqNum];
128
irqVector[irqNum] = isrProc;
130
if (irqNum < IRQ_MAX_HW_NUM)
134
else if (irqNum >= GPIO2_INT_ID)
136
IrqEnable(GPIO_INT_ID);
142
/*---------------------------------------------------------------------
144
Purpose: Set edge type for GPIO IRQ interrupts
145
This must be done before installing handler routine.
146
Arguments: int irqNum - number of GPIO IRQ interrupt
147
int edge - egde type (falling or rising or both)
149
---------------------------------------------------------------------*/
150
void IrqSetEdge(int irqNum, int edge)
152
if ( irqNum == GPIO0_INT_ID
153
|| irqNum == GPIO1_INT_ID
154
|| (irqNum >= GPIO2_INT_ID && irqNum <= GPIO80_INT_ID))
158
if (irqNum >= GPIO2_INT_ID)
160
IrqDisable(GPIO_INT_ID);
161
index = irqNum - GPIO2_INT_ID + 2;
165
index = irqNum - GPIO0_INT_ID;
169
/* set pin as GPIO input */
172
*GPDR2 &= ~(1 << bit);
175
*GAFR2_U &= ~(3 << (2*(bit-16)));
179
*GAFR2_L &= ~(3 << (2*bit));
182
else if (index >= 32)
184
*GPDR1 &= ~(1 << bit);
187
*GAFR1_U &= ~(3 << (2*(bit-16)));
191
*GAFR1_L &= ~(3 << (2*bit));
196
*GPDR0 &= ~(1 << bit);
199
*GAFR0_U &= ~(3 << (2*(bit-16)));
203
*GAFR0_L &= ~(3 << (2*bit));
207
/* reset edge detect status */
212
else if (index >= 32)
222
if (edge & GPIO_FALLING_EDGE)
226
*GFER2 |= (1 << bit);
228
else if (index >= 32)
230
*GFER1 |= (1 << bit);
234
*GFER0 |= (1 << bit);
237
if (edge & GPIO_RISING_EDGE)
241
*GRER2 |= (1 << bit);
243
else if (index >= 32)
245
*GRER1 |= (1 << bit);
249
*GRER0 |= (1 << bit);
255
/*---------------------------------------------------------------------
256
Function: IrqGPIOHandler
257
Purpose: dispatcher for GPIO IRQ interrupts
260
---------------------------------------------------------------------*/
261
static void IrqGPIOHandler(void)
263
unsigned int i, gedr, spurious;
266
while (gedr = (*GEDR0 & ~3), gedr != 0)
268
spurious = gedr & ~(*GFER0 | *GRER0);
278
for (i = 2; i < 32; ++i)
282
isr = irqVector[i+32];
292
while (gedr = (*GEDR1), gedr != 0)
294
spurious = gedr & ~(*GFER1 | *GRER1);
304
for (i = 0; i < 32; ++i)
308
isr = irqVector[i+64];
318
while (gedr = (*GEDR2), gedr != 0)
320
spurious = gedr & ~(*GFER2 | *GRER2);
330
for (i = 0; i < 32; ++i)
334
isr = irqVector[i+96];
345
/*---------------------------------------------------------------------
347
Purpose: dispatcher for IRQ interrupts
350
---------------------------------------------------------------------*/
351
void IrqHandler(void)
353
unsigned int rq, rq1;
356
rq = *ICIP; /* read pending IRQs */
358
/* splitting in 4 bytes (size of unmapTbl) */
362
isr = irqVector[unmapTbl[rq1]];
374
isr = irqVector[unmapTbl[rq1]+8];
386
isr = irqVector[unmapTbl[rq1]+16];
397
isr = irqVector[unmapTbl[rq]+24];