File: /usr/src/linux/arch/cris/kernel/irq.c
1 /* $Id: irq.c,v 1.17 2001/07/25 16:08:01 bjornw Exp $
2 *
3 * linux/arch/cris/kernel/irq.c
4 *
5 * Copyright (c) 2000,2001 Axis Communications AB
6 *
7 * Authors: Bjorn Wesen (bjornw@axis.com)
8 *
9 * This file contains the code used by various IRQ handling routines:
10 * asking for different IRQ's should be done through these routines
11 * instead of just grabbing them. Thus setups with different IRQ numbers
12 * shouldn't result in any weird surprises, and installing new handlers
13 * should be easier.
14 *
15 * Notice Linux/CRIS: these routines do not care about SMP
16 *
17 */
18
19 /*
20 * IRQ's are in fact implemented a bit like signal handlers for the kernel.
21 * Naturally it's not a 1:1 relation, but there are similarities.
22 */
23
24 #include <linux/config.h>
25 #include <linux/ptrace.h>
26 #include <linux/errno.h>
27 #include <linux/kernel_stat.h>
28 #include <linux/signal.h>
29 #include <linux/sched.h>
30 #include <linux/ioport.h>
31 #include <linux/interrupt.h>
32 #include <linux/timex.h>
33 #include <linux/slab.h>
34 #include <linux/random.h>
35 #include <linux/init.h>
36
37 #include <asm/system.h>
38 #include <asm/io.h>
39 #include <asm/irq.h>
40 #include <asm/bitops.h>
41
42 #include <asm/svinto.h>
43
44 char *hw_bp_msg = "BP 0x%x\n";
45
46 static inline void
47 mask_irq(unsigned int irq_nr)
48 {
49 *R_VECT_MASK_CLR = 1 << irq_nr;
50 }
51
52 static inline void
53 unmask_irq(unsigned int irq_nr)
54 {
55 *R_VECT_MASK_SET = 1 << irq_nr;
56 }
57
58 void
59 disable_irq(unsigned int irq_nr)
60 {
61 unsigned long flags;
62
63 save_flags(flags);
64 cli();
65 mask_irq(irq_nr);
66 restore_flags(flags);
67 }
68
69 void
70 enable_irq(unsigned int irq_nr)
71 {
72 unsigned long flags;
73 save_flags(flags);
74 cli();
75 unmask_irq(irq_nr);
76 restore_flags(flags);
77 }
78
79 unsigned long
80 probe_irq_on()
81 {
82 return 0;
83 }
84
85 int
86 probe_irq_off(unsigned long x)
87 {
88 return 0;
89 }
90
91 irqvectptr irq_shortcuts[NR_IRQS]; /* vector of shortcut jumps after the irq prologue */
92
93 /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is
94 * global just so that the kernel gdb can use it.
95 */
96
97 void
98 set_int_vector(int n, irqvectptr addr, irqvectptr saddr)
99 {
100 /* remember the shortcut entry point, after the prologue */
101
102 irq_shortcuts[n] = saddr;
103
104 etrax_irv->v[n + 0x20] = (irqvectptr)addr;
105 }
106
107 /* the breakpoint vector is obviously not made just like the normal irq handlers
108 * but needs to contain _code_ to jump to addr.
109 *
110 * the BREAK n instruction jumps to IBR + n * 8
111 */
112
113 void
114 set_break_vector(int n, irqvectptr addr)
115 {
116 unsigned short *jinstr = (unsigned short *)&etrax_irv->v[n*2];
117 unsigned long *jaddr = (unsigned long *)(jinstr + 1);
118
119 /* if you don't know what this does, do not touch it! */
120
121 *jinstr = 0x0d3f;
122 *jaddr = (unsigned long)addr;
123
124 /* 00000026 <clrlop+1a> 3f0d82000000 jump 0x82 */
125 }
126
127
128 /*
129 * This builds up the IRQ handler stubs using some ugly macros in irq.h
130 *
131 * These macros create the low-level assembly IRQ routines that do all
132 * the operations that are needed. They are also written to be fast - and to
133 * disable interrupts as little as humanly possible.
134 *
135 */
136
137 /* IRQ0 and 1 are special traps */
138 void hwbreakpoint(void);
139 void IRQ1_interrupt(void);
140 BUILD_IRQ(2, 0x04) /* the timer interrupt */
141 BUILD_IRQ(3, 0x08)
142 BUILD_IRQ(4, 0x10)
143 BUILD_IRQ(5, 0x20)
144 BUILD_IRQ(6, 0x40)
145 BUILD_IRQ(7, 0x80)
146 BUILD_IRQ(8, 0x100)
147 BUILD_IRQ(9, 0x200)
148 BUILD_IRQ(10, 0x400)
149 BUILD_IRQ(11, 0x800)
150 BUILD_IRQ(12, 0x1000)
151 BUILD_IRQ(13, 0x2000)
152 void mmu_bus_fault(void); /* IRQ 14 is the bus fault interrupt */
153 void multiple_interrupt(void); /* IRQ 15 is the multiple IRQ interrupt */
154 BUILD_IRQ(16, 0x10000)
155 BUILD_IRQ(17, 0x20000)
156 BUILD_IRQ(18, 0x40000)
157 BUILD_IRQ(19, 0x80000)
158 BUILD_IRQ(20, 0x100000)
159 BUILD_IRQ(21, 0x200000)
160 BUILD_IRQ(22, 0x400000)
161 BUILD_IRQ(23, 0x800000)
162 BUILD_IRQ(24, 0x1000000)
163 BUILD_IRQ(25, 0x2000000)
164 /* IRQ 26-30 are reserved */
165 BUILD_IRQ(31, 0x80000000)
166
167 /*
168 * Pointers to the low-level handlers
169 */
170
171 static void (*interrupt[NR_IRQS])(void) = {
172 NULL, NULL, IRQ2_interrupt, IRQ3_interrupt,
173 IRQ4_interrupt, IRQ5_interrupt, IRQ6_interrupt, IRQ7_interrupt,
174 IRQ8_interrupt, IRQ9_interrupt, IRQ10_interrupt, IRQ11_interrupt,
175 IRQ12_interrupt, IRQ13_interrupt, NULL, NULL,
176 IRQ16_interrupt, IRQ17_interrupt, IRQ18_interrupt, IRQ19_interrupt,
177 IRQ20_interrupt, IRQ21_interrupt, IRQ22_interrupt, IRQ23_interrupt,
178 IRQ24_interrupt, IRQ25_interrupt, NULL, NULL, NULL, NULL, NULL,
179 IRQ31_interrupt
180 };
181
182 static void (*sinterrupt[NR_IRQS])(void) = {
183 NULL, NULL, sIRQ2_interrupt, sIRQ3_interrupt,
184 sIRQ4_interrupt, sIRQ5_interrupt, sIRQ6_interrupt, sIRQ7_interrupt,
185 sIRQ8_interrupt, sIRQ9_interrupt, sIRQ10_interrupt, sIRQ11_interrupt,
186 sIRQ12_interrupt, sIRQ13_interrupt, NULL, NULL,
187 sIRQ16_interrupt, sIRQ17_interrupt, sIRQ18_interrupt, sIRQ19_interrupt,
188 sIRQ20_interrupt, sIRQ21_interrupt, sIRQ22_interrupt, sIRQ23_interrupt,
189 sIRQ24_interrupt, sIRQ25_interrupt, NULL, NULL, NULL, NULL, NULL,
190 sIRQ31_interrupt
191 };
192
193 static void (*bad_interrupt[NR_IRQS])(void) = {
194 NULL, NULL,
195 NULL, bad_IRQ3_interrupt,
196 bad_IRQ4_interrupt, bad_IRQ5_interrupt,
197 bad_IRQ6_interrupt, bad_IRQ7_interrupt,
198 bad_IRQ8_interrupt, bad_IRQ9_interrupt,
199 bad_IRQ10_interrupt, bad_IRQ11_interrupt,
200 bad_IRQ12_interrupt, bad_IRQ13_interrupt,
201 NULL, NULL,
202 bad_IRQ16_interrupt, bad_IRQ17_interrupt,
203 bad_IRQ18_interrupt, bad_IRQ19_interrupt,
204 bad_IRQ20_interrupt, bad_IRQ21_interrupt,
205 bad_IRQ22_interrupt, bad_IRQ23_interrupt,
206 bad_IRQ24_interrupt, bad_IRQ25_interrupt,
207 NULL, NULL, NULL, NULL, NULL,
208 bad_IRQ31_interrupt
209 };
210
211 /*
212 * Initial irq handlers.
213 */
214
215 static struct irqaction *irq_action[NR_IRQS] = {
216 NULL, NULL, NULL, NULL,
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 };
225
226 int get_irq_list(char *buf)
227 {
228 int i, len = 0;
229 struct irqaction * action;
230
231 for (i = 0; i < NR_IRQS; i++) {
232 action = irq_action[i];
233 if (!action)
234 continue;
235 len += sprintf(buf+len, "%2d: %10u %c %s",
236 i, kstat.irqs[0][i],
237 (action->flags & SA_INTERRUPT) ? '+' : ' ',
238 action->name);
239 for (action = action->next; action; action = action->next) {
240 len += sprintf(buf+len, ",%s %s",
241 (action->flags & SA_INTERRUPT) ? " +" : "",
242 action->name);
243 }
244 len += sprintf(buf+len, "\n");
245 }
246 return len;
247 }
248
249 /* called by the assembler IRQ entry functions defined in irq.h
250 * to dispatch the interrupts to registred handlers
251 * interrupts are disabled upon entry - depending on if the
252 * interrupt was registred with SA_INTERRUPT or not, interrupts
253 * are re-enabled or not.
254 */
255
256 asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
257 {
258 struct irqaction *action;
259 int do_random, cpu;
260
261 cpu = smp_processor_id();
262 irq_enter(cpu);
263 kstat.irqs[cpu][irq]++;
264
265 action = irq_action[irq];
266 if (action) {
267 if (!(action->flags & SA_INTERRUPT))
268 __sti();
269 action = irq_action[irq];
270 do_random = 0;
271 do {
272 do_random |= action->flags;
273 action->handler(irq, action->dev_id, regs);
274 action = action->next;
275 } while (action);
276 if (do_random & SA_SAMPLE_RANDOM)
277 add_interrupt_randomness(irq);
278 __cli();
279 }
280 irq_exit(cpu);
281
282 if (softirq_pending(cpu))
283 do_softirq();
284
285 /* unmasking and bottom half handling is done magically for us. */
286 }
287
288 /* this function links in a handler into the chain of handlers for the
289 given irq, and if the irq has never been registred, the appropriate
290 handler is entered into the interrupt vector
291 */
292
293 int setup_etrax_irq(int irq, struct irqaction * new)
294 {
295 int shared = 0;
296 struct irqaction *old, **p;
297 unsigned long flags;
298
299 p = irq_action + irq;
300 if ((old = *p) != NULL) {
301 /* Can't share interrupts unless both agree to */
302 if (!(old->flags & new->flags & SA_SHIRQ))
303 return -EBUSY;
304
305 /* Can't share interrupts unless both are same type */
306 if ((old->flags ^ new->flags) & SA_INTERRUPT)
307 return -EBUSY;
308
309 /* add new interrupt at end of irq queue */
310 do {
311 p = &old->next;
312 old = *p;
313 } while (old);
314 shared = 1;
315 }
316
317 if (new->flags & SA_SAMPLE_RANDOM)
318 rand_initialize_irq(irq);
319
320 save_flags(flags);
321 cli();
322 *p = new;
323
324 if (!shared) {
325 /* if the irq wasn't registred before, enter it into the vector table
326 and unmask it physically
327 */
328 set_int_vector(irq, interrupt[irq], sinterrupt[irq]);
329 unmask_irq(irq);
330 }
331
332 restore_flags(flags);
333 return 0;
334 }
335
336 /* this function is called by a driver to register an irq handler
337 Valid flags:
338 SA_INTERRUPT -> it's a fast interrupt, handler called with irq disabled and
339 no signal checking etc is performed upon exit
340 SA_SHIRQ -> the interrupt can be shared between different handlers, the handler
341 is required to check if the irq was "aimed" at it explicitely
342 SA_RANDOM -> the interrupt will add to the random generators entropy
343 */
344
345 int request_irq(unsigned int irq,
346 void (*handler)(int, void *, struct pt_regs *),
347 unsigned long irqflags,
348 const char * devname,
349 void *dev_id)
350 {
351 int retval;
352 struct irqaction * action;
353
354 /* interrupts 0 and 1 are hardware breakpoint and NMI and we can't support
355 these yet. interrupt 15 is the multiple irq, it's special. */
356
357 if(irq < 2 || irq == 15 || irq >= NR_IRQS)
358 return -EINVAL;
359
360 if(!handler)
361 return -EINVAL;
362
363 /* allocate and fill in a handler structure and setup the irq */
364
365 action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
366 if (!action)
367 return -ENOMEM;
368
369 action->handler = handler;
370 action->flags = irqflags;
371 action->mask = 0;
372 action->name = devname;
373 action->next = NULL;
374 action->dev_id = dev_id;
375
376 retval = setup_etrax_irq(irq, action);
377
378 if (retval)
379 kfree(action);
380 return retval;
381 }
382
383 void free_irq(unsigned int irq, void *dev_id)
384 {
385 struct irqaction * action, **p;
386 unsigned long flags;
387
388 if (irq >= NR_IRQS) {
389 printk("Trying to free IRQ%d\n",irq);
390 return;
391 }
392 for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
393 if (action->dev_id != dev_id)
394 continue;
395
396 /* Found it - now free it */
397 save_flags(flags);
398 cli();
399 *p = action->next;
400 if (!irq_action[irq]) {
401 mask_irq(irq);
402 set_int_vector(irq, bad_interrupt[irq], 0);
403 }
404 restore_flags(flags);
405 kfree(action);
406 return;
407 }
408 printk("Trying to free free IRQ%d\n",irq);
409 }
410
411 void weird_irq(void)
412 {
413 __asm__("di");
414 printk("weird irq\n");
415 while(1);
416 }
417
418 /* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks and
419 setting the irq vector table to point to bad_interrupt ptrs.
420 */
421
422 void system_call(void); /* from entry.S */
423 void do_sigtrap(void); /* from entry.S */
424 void gdb_handle_breakpoint(void); /* from entry.S */
425
426 void __init
427 init_IRQ(void)
428 {
429 int i;
430
431 /* clear all interrupt masks */
432
433 #ifndef CONFIG_SVINTO_SIM
434 *R_IRQ_MASK0_CLR = 0xffffffff;
435 *R_IRQ_MASK1_CLR = 0xffffffff;
436 *R_IRQ_MASK2_CLR = 0xffffffff;
437 #endif
438
439 *R_VECT_MASK_CLR = 0xffffffff;
440
441 /* clear the shortcut entry points */
442
443 for(i = 0; i < NR_IRQS; i++)
444 irq_shortcuts[i] = NULL;
445
446 for (i = 0; i < 256; i++)
447 etrax_irv->v[i] = weird_irq;
448
449 /* the entries in the break vector contain actual code to be
450 executed by the associated break handler, rather than just a jump
451 address. therefore we need to setup a default breakpoint handler
452 for all breakpoints */
453
454 for (i = 0; i < 16; i++)
455 set_break_vector(i, do_sigtrap);
456
457 /* set all etrax irq's to the bad handlers */
458 for (i = 2; i < NR_IRQS; i++)
459 set_int_vector(i, bad_interrupt[i], 0);
460
461 /* except IRQ 15 which is the multiple-IRQ handler on Etrax100 */
462
463 set_int_vector(15, multiple_interrupt, 0);
464
465 /* 0 and 1 which are special breakpoint/NMI traps */
466
467 set_int_vector(0, hwbreakpoint, 0);
468 set_int_vector(1, IRQ1_interrupt, 0);
469
470 /* and irq 14 which is the mmu bus fault handler */
471
472 set_int_vector(14, mmu_bus_fault, 0);
473
474 /* setup the system-call trap, which is reached by BREAK 13 */
475
476 set_break_vector(13, system_call);
477
478 /* setup a breakpoint handler for debugging used for both user and
479 kernel mode debugging (which is why it is not inside an ifdef
480 CONFIG_ETRAX_KGDB) */
481 set_break_vector(8, gdb_handle_breakpoint);
482
483 #ifdef CONFIG_ETRAX_KGDB
484 /* setup kgdb if its enabled, and break into the debugger */
485 kgdb_init();
486 breakpoint();
487 #endif
488
489 }
490
491 #if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
492 /* Used by other archs to show/control IRQ steering during SMP */
493 void __init
494 init_irq_proc(void)
495 {
496 }
497 #endif
498