2 * Copyright (C) 2001 MontaVista Software Inc.
3 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
4 * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
6 * linux/arch/mips/vr4181/common/irq.c
7 * Completely re-written to use the new irq.c
9 * Credits to Bradley D. LaRonde and Michael Klar for writing the original
10 * irq.c file which was derived from the common irq.c file.
12 * This file is subject to the terms and conditions of the GNU General Public
13 * License. See the file "COPYING" in the main directory of this archive
16 #include <linux/types.h>
17 #include <linux/init.h>
18 #include <linux/kernel_stat.h>
19 #include <linux/signal.h>
20 #include <linux/sched.h>
21 #include <linux/interrupt.h>
22 #include <linux/slab.h>
23 #include <linux/random.h>
26 #include <asm/mipsregs.h>
27 #include <asm/gdb-stub.h>
29 #include <asm/vr4181/vr4181.h>
34 * We essentially have three irq controllers, CPU, system, and gpio.
36 * CPU irq controller is taken care by arch/mips/kernel/irq_cpu.c and
37 * CONFIG_IRQ_CPU config option.
39 * We here provide sys_irq and gpio_irq controller code.
42 static int sys_irq_base
;
43 static int gpio_irq_base
;
45 /* ---------------------- sys irq ------------------------ */
47 sys_irq_enable(unsigned int irq
)
51 *VR4181_MSYSINT1REG
|= (u16
)(1 << irq
);
54 *VR4181_MSYSINT2REG
|= (u16
)(1 << irq
);
59 sys_irq_disable(unsigned int irq
)
63 *VR4181_MSYSINT1REG
&= ~((u16
)(1 << irq
));
66 *VR4181_MSYSINT2REG
&= ~((u16
)(1 << irq
));
72 sys_irq_startup(unsigned int irq
)
78 #define sys_irq_shutdown sys_irq_disable
79 #define sys_irq_ack sys_irq_disable
82 sys_irq_end(unsigned int irq
)
84 if(!(irq_desc
[irq
].status
& (IRQ_DISABLED
| IRQ_INPROGRESS
)))
88 static hw_irq_controller sys_irq_controller
= {
96 NULL
/* no affinity stuff for UP */
99 /* ---------------------- gpio irq ------------------------ */
100 /* gpio irq lines use reverse logic */
102 gpio_irq_enable(unsigned int irq
)
104 irq
-= gpio_irq_base
;
105 *VR4181_GPINTMSK
&= ~((u16
)(1 << irq
));
109 gpio_irq_disable(unsigned int irq
)
111 irq
-= gpio_irq_base
;
112 *VR4181_GPINTMSK
|= (u16
)(1 << irq
);
116 gpio_irq_startup(unsigned int irq
)
118 gpio_irq_enable(irq
);
120 irq
-= gpio_irq_base
;
121 *VR4181_GPINTEN
|= (u16
)(1 << irq
);
127 gpio_irq_shutdown(unsigned int irq
)
129 gpio_irq_disable(irq
);
131 irq
-= gpio_irq_base
;
132 *VR4181_GPINTEN
&= ~((u16
)(1 << irq
));
136 gpio_irq_ack(unsigned int irq
)
141 gpio_irq_disable(irq
);
143 /* we clear interrupt if it is edge triggered */
144 irq
-= gpio_irq_base
;
146 irqtype
= *VR4181_GPINTTYPL
;
147 irqshift
= 2 << (irq
*2);
149 irqtype
= *VR4181_GPINTTYPH
;
150 irqshift
= 2 << ((irq
-8)*2);
152 if ( ! (irqtype
& irqshift
) ) {
153 *VR4181_GPINTSTAT
= (u16
) (1 << irq
);
158 gpio_irq_end(unsigned int irq
)
160 if(!(irq_desc
[irq
].status
& (IRQ_DISABLED
| IRQ_INPROGRESS
)))
161 gpio_irq_enable(irq
);
164 static hw_irq_controller gpio_irq_controller
= {
172 NULL
/* no affinity stuff for UP */
175 /* --------------------- IRQ init stuff ---------------------- */
177 extern asmlinkage
void vr4181_handle_irq(void);
178 extern void breakpoint(void);
179 extern int setup_irq(unsigned int irq
, struct irqaction
*irqaction
);
180 extern void mips_cpu_irq_init(u32 irq_base
);
182 static struct irqaction cascade
=
183 { no_action
, SA_INTERRUPT
, CPU_MASK_NONE
, "cascade", NULL
, NULL
};
184 static struct irqaction reserved
=
185 { no_action
, SA_INTERRUPT
, CPU_MASK_NONE
, "cascade", NULL
, NULL
};
187 void __init
arch_init_irq(void)
191 set_except_vector(0, vr4181_handle_irq
);
194 mips_cpu_irq_init(VR4181_CPU_IRQ_BASE
);
197 sys_irq_base
= VR4181_SYS_IRQ_BASE
;
198 for (i
=sys_irq_base
; i
< sys_irq_base
+ VR4181_NUM_SYS_IRQ
; i
++) {
199 irq_desc
[i
].status
= IRQ_DISABLED
;
200 irq_desc
[i
].action
= NULL
;
201 irq_desc
[i
].depth
= 1;
202 irq_desc
[i
].handler
= &sys_irq_controller
;
206 gpio_irq_base
= VR4181_GPIO_IRQ_BASE
;
207 for (i
=gpio_irq_base
; i
< gpio_irq_base
+ VR4181_NUM_GPIO_IRQ
; i
++) {
208 irq_desc
[i
].status
= IRQ_DISABLED
;
209 irq_desc
[i
].action
= NULL
;
210 irq_desc
[i
].depth
= 1;
211 irq_desc
[i
].handler
= &gpio_irq_controller
;
214 /* Default all ICU IRQs to off ... */
215 *VR4181_MSYSINT1REG
= 0;
216 *VR4181_MSYSINT2REG
= 0;
218 /* We initialize the level 2 ICU registers to all bits disabled. */
219 *VR4181_MPIUINTREG
= 0;
220 *VR4181_MAIUINTREG
= 0;
221 *VR4181_MKIUINTREG
= 0;
223 /* disable all GPIO intrs */
224 *VR4181_GPINTMSK
= 0xffff;
226 /* vector handler. What these do is register the IRQ as non-sharable */
227 setup_irq(VR4181_IRQ_INT0
, &cascade
);
228 setup_irq(VR4181_IRQ_GIU
, &cascade
);
231 * RTC interrupts are interesting. They have two destinations.
232 * One is at sys irq controller, and the other is at CPU IP3 and IP4.
233 * RTC timer is used as system timer.
234 * We enable them here, but timer routine will register later
237 setup_irq(VR4181_IRQ_RTCL1
, &reserved
);
238 setup_irq(VR4181_IRQ_RTCL2
, &reserved
);