1 /*
2 * linux/arch/cris/kernel/irq.c
3 *
4 * Copyright (c) 2000, 2001, 2002, 2003 Axis Communications AB
5 *
6 * Authors: Bjorn Wesen (bjornw@axis.com)
7 *
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
12 * should be easier.
13 *
14 * Notice Linux/CRIS: these routines do not care about SMP
15 *
16 */
17
18 /*
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.
21 */
22
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>
35
36 #include <asm/system.h>
37 #include <asm/io.h>
38 #include <asm/irq.h>
39 #include <asm/bitops.h>
40
41 #include <asm/svinto.h>
42
43 char *hw_bp_msg = "BP 0x%x\n";
44
45 static inline void
mask_irq(unsigned int irq_nr)46 mask_irq(unsigned int irq_nr)
47 {
48 *R_VECT_MASK_CLR = 1 << irq_nr;
49 }
50
51 static inline void
unmask_irq(unsigned int irq_nr)52 unmask_irq(unsigned int irq_nr)
53 {
54 *R_VECT_MASK_SET = 1 << irq_nr;
55 }
56
57 void
disable_irq(unsigned int irq_nr)58 disable_irq(unsigned int irq_nr)
59 {
60 unsigned long flags;
61
62 save_flags(flags);
63 cli();
64 mask_irq(irq_nr);
65 restore_flags(flags);
66 }
67
68 void
enable_irq(unsigned int irq_nr)69 enable_irq(unsigned int irq_nr)
70 {
71 unsigned long flags;
72
73 save_flags(flags);
74 cli();
75 unmask_irq(irq_nr);
76 restore_flags(flags);
77 }
78
79 unsigned long
probe_irq_on()80 probe_irq_on()
81 {
82 return 0;
83 }
84
85 int
probe_irq_off(unsigned long x)86 probe_irq_off(unsigned long x)
87 {
88 return 0;
89 }
90
91 /* vector of shortcut jumps after the irq prologue */
92 irqvectptr irq_shortcuts[NR_IRQS];
93
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.
96 */
97
98 void
set_int_vector(int n,irqvectptr addr,irqvectptr saddr)99 set_int_vector(int n, irqvectptr addr, irqvectptr saddr)
100 {
101 /* remember the shortcut entry point, after the prologue */
102
103 irq_shortcuts[n] = saddr;
104
105 etrax_irv->v[n + 0x20] = (irqvectptr)addr;
106 }
107
108 /* the breakpoint vector is obviously not made just like the normal irq
109 * handlers but needs to contain _code_ to jump to addr.
110 *
111 * the BREAK n instruction jumps to IBR + n * 8
112 */
113
114 void
set_break_vector(int n,irqvectptr addr)115 set_break_vector(int n, irqvectptr addr)
116 {
117 unsigned short *jinstr = (unsigned short *)&etrax_irv->v[n*2];
118 unsigned long *jaddr = (unsigned long *)(jinstr + 1);
119
120 /* if you don't know what this does, do not touch it! */
121
122 *jinstr = 0x0d3f;
123 *jaddr = (unsigned long)addr;
124
125 /* 00000026 <clrlop+1a> 3f0d82000000 jump 0x82 */
126 }
127
128
129 /*
130 * This builds up the IRQ handler stubs using some ugly macros in irq.h
131 *
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.
135 *
136 */
137
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 */
142 BUILD_IRQ(3, 0x08)
143 BUILD_IRQ(4, 0x10)
144 BUILD_IRQ(5, 0x20)
145 BUILD_IRQ(6, 0x40)
146 BUILD_IRQ(7, 0x80)
147 BUILD_IRQ(8, 0x100)
148 BUILD_IRQ(9, 0x200)
149 BUILD_IRQ(10, 0x400)
150 BUILD_IRQ(11, 0x800)
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)
167
168 /*
169 * Pointers to the low-level handlers
170 */
171
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,
180 IRQ31_interrupt
181 };
182
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,
191 sIRQ31_interrupt
192 };
193
194 static void (*bad_interrupt[NR_IRQS])(void) = {
195 NULL, NULL,
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,
202 NULL, NULL,
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,
209 bad_IRQ31_interrupt
210 };
211
212 /*
213 * Initial irq handlers.
214 */
215
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
225 };
226
get_irq_list(char * buf)227 int get_irq_list(char *buf)
228 {
229 int i, len = 0;
230 struct irqaction * action;
231
232 for (i = 0; i < NR_IRQS; i++) {
233 action = irq_action[i];
234 if (!action)
235 continue;
236 len += sprintf(buf+len, "%2d: %10u %c %s",
237 i, kstat.irqs[0][i],
238 (action->flags & SA_INTERRUPT) ? '+' : ' ',
239 action->name);
240 for (action = action->next; action; action = action->next) {
241 len += sprintf(buf+len, ",%s %s",
242 (action->flags & SA_INTERRUPT) ? " +" : "",
243 action->name);
244 }
245 len += sprintf(buf+len, "\n");
246 }
247 return len;
248 }
249
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.
255 */
256
do_IRQ(int irq,struct pt_regs * regs)257 asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
258 {
259 struct irqaction *action;
260 int do_random, cpu;
261
262 cpu = smp_processor_id();
263 irq_enter(cpu);
264 kstat.irqs[cpu][irq]++;
265
266 action = irq_action[irq];
267 if (action) {
268 if (!(action->flags & SA_INTERRUPT))
269 __sti();
270 action = irq_action[irq];
271 do_random = 0;
272 do {
273 do_random |= action->flags;
274 action->handler(irq, action->dev_id, regs);
275 action = action->next;
276 } while (action);
277 if (do_random & SA_SAMPLE_RANDOM)
278 add_interrupt_randomness(irq);
279 __cli();
280 }
281 irq_exit(cpu);
282
283 if (softirq_pending(cpu))
284 do_softirq();
285
286 /* unmasking and bottom half handling is done magically for us. */
287 }
288
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
292 */
293
setup_etrax_irq(int irq,struct irqaction * new)294 int setup_etrax_irq(int irq, struct irqaction * new)
295 {
296 int shared = 0;
297 struct irqaction *old, **p;
298 unsigned long flags;
299
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))
304 return -EBUSY;
305
306 /* Can't share interrupts unless both are same type */
307 if ((old->flags ^ new->flags) & SA_INTERRUPT)
308 return -EBUSY;
309
310 /* add new interrupt at end of irq queue */
311 do {
312 p = &old->next;
313 old = *p;
314 } while (old);
315 shared = 1;
316 }
317
318 if (new->flags & SA_SAMPLE_RANDOM)
319 rand_initialize_irq(irq);
320
321 save_flags(flags);
322 cli();
323 *p = new;
324
325 if (!shared) {
326 /* if the irq wasn't registred before, enter it into the vector
327 * table and unmask it physically
328 */
329 set_int_vector(irq, interrupt[irq], sinterrupt[irq]);
330 unmask_irq(irq);
331 }
332
333 restore_flags(flags);
334 return 0;
335 }
336
337 /* this function is called by a driver to register an irq handler
338 * Valid flags:
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
343 * explicitely
344 * SA_RANDOM: the interrupt will add to the random generators entropy
345 */
346
request_irq(unsigned int irq,void (* handler)(int,void *,struct pt_regs *),unsigned long irqflags,const char * devname,void * dev_id)347 int request_irq(unsigned int irq,
348 void (*handler)(int, void *, struct pt_regs *),
349 unsigned long irqflags,
350 const char * devname,
351 void *dev_id)
352 {
353 int retval;
354 struct irqaction * action;
355
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.
358 */
359
360 if(irq < 2 || irq == 15 || irq >= NR_IRQS)
361 return -EINVAL;
362
363 if(!handler)
364 return -EINVAL;
365
366 /* allocate and fill in a handler structure and setup the irq */
367
368 action = kmalloc(sizeof *action, GFP_KERNEL);
369 if (!action)
370 return -ENOMEM;
371
372 action->handler = handler;
373 action->flags = irqflags;
374 action->mask = 0;
375 action->name = devname;
376 action->next = NULL;
377 action->dev_id = dev_id;
378
379 retval = setup_etrax_irq(irq, action);
380
381 if (retval)
382 kfree(action);
383 return retval;
384 }
385
free_irq(unsigned int irq,void * dev_id)386 void free_irq(unsigned int irq, void *dev_id)
387 {
388 struct irqaction * action, **p;
389 unsigned long flags;
390
391 if (irq >= NR_IRQS) {
392 printk("Trying to free IRQ%d\n",irq);
393 return;
394 }
395 for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
396 if (action->dev_id != dev_id)
397 continue;
398
399 /* Found it - now free it */
400 save_flags(flags);
401 cli();
402 *p = action->next;
403 if (!irq_action[irq]) {
404 mask_irq(irq);
405 set_int_vector(irq, bad_interrupt[irq], 0);
406 }
407 restore_flags(flags);
408 kfree(action);
409 return;
410 }
411 printk("Trying to free free IRQ%d\n",irq);
412 }
413
weird_irq(void)414 void weird_irq(void)
415 {
416 __asm__("di");
417 printk("weird irq\n");
418 while(1);
419 }
420
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.
423 */
424
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 */
428
429 void __init
init_IRQ(void)430 init_IRQ(void)
431 {
432 int i;
433
434 /* clear all interrupt masks */
435
436 #ifndef CONFIG_SVINTO_SIM
437 *R_IRQ_MASK0_CLR = 0xffffffff;
438 *R_IRQ_MASK1_CLR = 0xffffffff;
439 *R_IRQ_MASK2_CLR = 0xffffffff;
440 #endif
441
442 *R_VECT_MASK_CLR = 0xffffffff;
443
444 /* clear the shortcut entry points */
445
446 for(i = 0; i < NR_IRQS; i++)
447 irq_shortcuts[i] = NULL;
448
449 for (i = 0; i < 256; i++)
450 etrax_irv->v[i] = weird_irq;
451
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
456 */
457
458 for (i = 0; i < 16; i++)
459 set_break_vector(i, do_sigtrap);
460
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);
464
465 /* except IRQ 15 which is the multiple-IRQ handler on Etrax100 */
466
467 set_int_vector(15, multiple_interrupt, 0);
468
469 /* 0 and 1 which are special breakpoint/NMI traps */
470
471 set_int_vector(0, hwbreakpoint, 0);
472 set_int_vector(1, IRQ1_interrupt, 0);
473
474 /* and irq 14 which is the mmu bus fault handler */
475
476 set_int_vector(14, mmu_bus_fault, 0);
477
478 /* setup the system-call trap, which is reached by BREAK 13 */
479
480 set_break_vector(13, system_call);
481
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
484 * CONFIG_ETRAX_KGDB)
485 */
486 set_break_vector(8, gdb_handle_breakpoint);
487
488 #ifdef CONFIG_ETRAX_KGDB
489 /* setup kgdb if its enabled, and break into the debugger */
490 kgdb_init();
491 breakpoint();
492 #endif
493 }
494
495 #if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
496 /* Used by other archs to show/control IRQ steering during SMP */
497 void __init
init_irq_proc(void)498 init_irq_proc(void)
499 {
500 }
501 #endif
502