2 * linux/arch/cris/kernel/irq.c
4 * Copyright (c) 2000, 2001, 2002, 2003 Axis Communications AB
6 * Authors: Bjorn Wesen (bjornw@axis.com)
8 * This file contains the code used by various IRQ handling routines:
9 * asking for different IRQ's should be done through these routines
10 * instead of just grabbing them. Thus setups with different IRQ numbers
11 * shouldn't result in any weird surprises, and installing new handlers
14 * Notice Linux/CRIS: these routines do not care about SMP
19 * IRQ's are in fact implemented a bit like signal handlers for the kernel.
20 * Naturally it's not a 1:1 relation, but there are similarities.
23 #include <linux/config.h>
24 #include <linux/ptrace.h>
25 #include <linux/errno.h>
26 #include <linux/kernel_stat.h>
27 #include <linux/signal.h>
28 #include <linux/sched.h>
29 #include <linux/ioport.h>
30 #include <linux/interrupt.h>
31 #include <linux/timex.h>
32 #include <linux/slab.h>
33 #include <linux/random.h>
34 #include <linux/init.h>
36 #include <asm/system.h>
39 #include <asm/bitops.h>
41 #include <asm/svinto.h>
43 char *hw_bp_msg = "BP 0x%x\n";
46 mask_irq(unsigned int irq_nr)
48 *R_VECT_MASK_CLR = 1 << irq_nr;
52 unmask_irq(unsigned int irq_nr)
54 *R_VECT_MASK_SET = 1 << irq_nr;
58 disable_irq(unsigned int irq_nr)
69 enable_irq(unsigned int irq_nr)
86 probe_irq_off(unsigned long x)
91 /* vector of shortcut jumps after the irq prologue */
92 irqvectptr irq_shortcuts[NR_IRQS];
94 /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is
95 * global just so that the kernel gdb can use it.
99 set_int_vector(int n, irqvectptr addr, irqvectptr saddr)
101 /* remember the shortcut entry point, after the prologue */
103 irq_shortcuts[n] = saddr;
105 etrax_irv->v[n + 0x20] = (irqvectptr)addr;
108 /* the breakpoint vector is obviously not made just like the normal irq
109 * handlers but needs to contain _code_ to jump to addr.
111 * the BREAK n instruction jumps to IBR + n * 8
115 set_break_vector(int n, irqvectptr addr)
117 unsigned short *jinstr = (unsigned short *)&etrax_irv->v[n*2];
118 unsigned long *jaddr = (unsigned long *)(jinstr + 1);
120 /* if you don't know what this does, do not touch it! */
123 *jaddr = (unsigned long)addr;
125 /* 00000026 <clrlop+1a> 3f0d82000000 jump 0x82 */
130 * This builds up the IRQ handler stubs using some ugly macros in irq.h
132 * These macros create the low-level assembly IRQ routines that do all
133 * the operations that are needed. They are also written to be fast - and to
134 * disable interrupts as little as humanly possible.
138 /* IRQ0 and 1 are special traps */
139 void hwbreakpoint(void);
140 void IRQ1_interrupt(void);
141 BUILD_TIMER_IRQ(2, 0x04) /* the timer interrupt is somewhat special */
151 BUILD_IRQ(12, 0x1000)
152 BUILD_IRQ(13, 0x2000)
153 void mmu_bus_fault(void); /* IRQ 14 is the bus fault interrupt */
154 void multiple_interrupt(void); /* IRQ 15 is the multiple IRQ interrupt */
155 BUILD_IRQ(16, 0x10000)
156 BUILD_IRQ(17, 0x20000)
157 BUILD_IRQ(18, 0x40000)
158 BUILD_IRQ(19, 0x80000)
159 BUILD_IRQ(20, 0x100000)
160 BUILD_IRQ(21, 0x200000)
161 BUILD_IRQ(22, 0x400000)
162 BUILD_IRQ(23, 0x800000)
163 BUILD_IRQ(24, 0x1000000)
164 BUILD_IRQ(25, 0x2000000)
165 /* IRQ 26-30 are reserved */
166 BUILD_IRQ(31, 0x80000000)
169 * Pointers to the low-level handlers
172 static void (*interrupt[NR_IRQS])(void) = {
173 NULL, NULL, IRQ2_interrupt, IRQ3_interrupt,
174 IRQ4_interrupt, IRQ5_interrupt, IRQ6_interrupt, IRQ7_interrupt,
175 IRQ8_interrupt, IRQ9_interrupt, IRQ10_interrupt, IRQ11_interrupt,
176 IRQ12_interrupt, IRQ13_interrupt, NULL, NULL,
177 IRQ16_interrupt, IRQ17_interrupt, IRQ18_interrupt, IRQ19_interrupt,
178 IRQ20_interrupt, IRQ21_interrupt, IRQ22_interrupt, IRQ23_interrupt,
179 IRQ24_interrupt, IRQ25_interrupt, NULL, NULL, NULL, NULL, NULL,
183 static void (*sinterrupt[NR_IRQS])(void) = {
184 NULL, NULL, sIRQ2_interrupt, sIRQ3_interrupt,
185 sIRQ4_interrupt, sIRQ5_interrupt, sIRQ6_interrupt, sIRQ7_interrupt,
186 sIRQ8_interrupt, sIRQ9_interrupt, sIRQ10_interrupt, sIRQ11_interrupt,
187 sIRQ12_interrupt, sIRQ13_interrupt, NULL, NULL,
188 sIRQ16_interrupt, sIRQ17_interrupt, sIRQ18_interrupt, sIRQ19_interrupt,
189 sIRQ20_interrupt, sIRQ21_interrupt, sIRQ22_interrupt, sIRQ23_interrupt,
190 sIRQ24_interrupt, sIRQ25_interrupt, NULL, NULL, NULL, NULL, NULL,
194 static void (*bad_interrupt[NR_IRQS])(void) = {
196 NULL, bad_IRQ3_interrupt,
197 bad_IRQ4_interrupt, bad_IRQ5_interrupt,
198 bad_IRQ6_interrupt, bad_IRQ7_interrupt,
199 bad_IRQ8_interrupt, bad_IRQ9_interrupt,
200 bad_IRQ10_interrupt, bad_IRQ11_interrupt,
201 bad_IRQ12_interrupt, bad_IRQ13_interrupt,
203 bad_IRQ16_interrupt, bad_IRQ17_interrupt,
204 bad_IRQ18_interrupt, bad_IRQ19_interrupt,
205 bad_IRQ20_interrupt, bad_IRQ21_interrupt,
206 bad_IRQ22_interrupt, bad_IRQ23_interrupt,
207 bad_IRQ24_interrupt, bad_IRQ25_interrupt,
208 NULL, NULL, NULL, NULL, NULL,
213 * Initial irq handlers.
216 static struct irqaction *irq_action[NR_IRQS] = {
217 NULL, NULL, NULL, NULL,
218 NULL, NULL, NULL, NULL,
219 NULL, NULL, NULL, NULL,
220 NULL, NULL, NULL, NULL,
221 NULL, NULL, NULL, NULL,
222 NULL, NULL, NULL, NULL,
223 NULL, NULL, NULL, NULL,
224 NULL, NULL, NULL, NULL
227 int get_irq_list(char *buf)
230 struct irqaction * action;
232 for (i = 0; i < NR_IRQS; i++) {
233 action = irq_action[i];
236 len += sprintf(buf+len, "%2d: %10u %c %s",
238 (action->flags & SA_INTERRUPT) ? '+' : ' ',
240 for (action = action->next; action; action = action->next) {
241 len += sprintf(buf+len, ",%s %s",
242 (action->flags & SA_INTERRUPT) ? " +" : "",
245 len += sprintf(buf+len, "\n");
250 /* called by the assembler IRQ entry functions defined in irq.h
251 * to dispatch the interrupts to registred handlers
252 * interrupts are disabled upon entry - depending on if the
253 * interrupt was registred with SA_INTERRUPT or not, interrupts
254 * are re-enabled or not.
257 asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
259 struct irqaction *action;
262 cpu = smp_processor_id();
264 kstat.irqs[cpu][irq]++;
266 action = irq_action[irq];
268 if (!(action->flags & SA_INTERRUPT))
270 action = irq_action[irq];
273 do_random |= action->flags;
274 action->handler(irq, action->dev_id, regs);
275 action = action->next;
277 if (do_random & SA_SAMPLE_RANDOM)
278 add_interrupt_randomness(irq);
283 if (softirq_pending(cpu))
286 /* unmasking and bottom half handling is done magically for us. */
289 /* this function links in a handler into the chain of handlers for the
290 * given irq, and if the irq has never been registred, the appropriate
291 * handler is entered into the interrupt vector
294 int setup_etrax_irq(int irq, struct irqaction * new)
297 struct irqaction *old, **p;
300 p = irq_action + irq;
301 if ((old = *p) != NULL) {
302 /* Can't share interrupts unless both agree to */
303 if (!(old->flags & new->flags & SA_SHIRQ))
306 /* Can't share interrupts unless both are same type */
307 if ((old->flags ^ new->flags) & SA_INTERRUPT)
310 /* add new interrupt at end of irq queue */
318 if (new->flags & SA_SAMPLE_RANDOM)
319 rand_initialize_irq(irq);
326 /* if the irq wasn't registred before, enter it into the vector
327 * table and unmask it physically
329 set_int_vector(irq, interrupt[irq], sinterrupt[irq]);
333 restore_flags(flags);
337 /* this function is called by a driver to register an irq handler
339 * SA_INTERRUPT: it's a fast interrupt, handler called with irq disabled and
340 * no signal checking etc is performed upon exit
341 * SA_SHIRQ: the interrupt can be shared between different handlers, the
342 * handler is required to check if the irq was "aimed" at it
344 * SA_RANDOM: the interrupt will add to the random generators entropy
347 int request_irq(unsigned int irq,
348 void (*handler)(int, void *, struct pt_regs *),
349 unsigned long irqflags,
350 const char * devname,
354 struct irqaction * action;
356 /* interrupts 0 and 1 are hardware breakpoint and NMI and we can't
357 * support these yet. interrupt 15 is the multiple irq, it's special.
360 if(irq < 2 || irq == 15 || irq >= NR_IRQS)
366 /* allocate and fill in a handler structure and setup the irq */
368 action = kmalloc(sizeof *action, GFP_KERNEL);
372 action->handler = handler;
373 action->flags = irqflags;
375 action->name = devname;
377 action->dev_id = dev_id;
379 retval = setup_etrax_irq(irq, action);
386 void free_irq(unsigned int irq, void *dev_id)
388 struct irqaction * action, **p;
391 if (irq >= NR_IRQS) {
392 printk("Trying to free IRQ%d\n",irq);
395 for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
396 if (action->dev_id != dev_id)
399 /* Found it - now free it */
403 if (!irq_action[irq]) {
405 set_int_vector(irq, bad_interrupt[irq], 0);
407 restore_flags(flags);
411 printk("Trying to free free IRQ%d\n",irq);
417 printk("weird irq\n");
421 /* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks
422 * and setting the irq vector table to point to bad_interrupt ptrs.
425 void system_call(void); /* from entry.S */
426 void do_sigtrap(void); /* from entry.S */
427 void gdb_handle_breakpoint(void); /* from entry.S */
434 /* clear all interrupt masks */
436 #ifndef CONFIG_SVINTO_SIM
437 *R_IRQ_MASK0_CLR = 0xffffffff;
438 *R_IRQ_MASK1_CLR = 0xffffffff;
439 *R_IRQ_MASK2_CLR = 0xffffffff;
442 *R_VECT_MASK_CLR = 0xffffffff;
444 /* clear the shortcut entry points */
446 for(i = 0; i < NR_IRQS; i++)
447 irq_shortcuts[i] = NULL;
449 for (i = 0; i < 256; i++)
450 etrax_irv->v[i] = weird_irq;
452 /* the entries in the break vector contain actual code to be
453 * executed by the associated break handler, rather than just a jump
454 * address. therefore we need to setup a default breakpoint handler
455 * for all breakpoints
458 for (i = 0; i < 16; i++)
459 set_break_vector(i, do_sigtrap);
461 /* set all etrax irq's to the bad handlers */
462 for (i = 2; i < NR_IRQS; i++)
463 set_int_vector(i, bad_interrupt[i], 0);
465 /* except IRQ 15 which is the multiple-IRQ handler on Etrax100 */
467 set_int_vector(15, multiple_interrupt, 0);
469 /* 0 and 1 which are special breakpoint/NMI traps */
471 set_int_vector(0, hwbreakpoint, 0);
472 set_int_vector(1, IRQ1_interrupt, 0);
474 /* and irq 14 which is the mmu bus fault handler */
476 set_int_vector(14, mmu_bus_fault, 0);
478 /* setup the system-call trap, which is reached by BREAK 13 */
480 set_break_vector(13, system_call);
482 /* setup a breakpoint handler for debugging used for both user and
483 * kernel mode debugging (which is why it is not inside an ifdef
486 set_break_vector(8, gdb_handle_breakpoint);
488 #ifdef CONFIG_ETRAX_KGDB
489 /* setup kgdb if its enabled, and break into the debugger */
495 #if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
496 /* Used by other archs to show/control IRQ steering during SMP */