more changes on original files
[linux-2.4.git] / kernel / irq.c
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
46 mask_irq(unsigned int irq_nr)
47 {
48         *R_VECT_MASK_CLR = 1 << irq_nr;
49 }
50
51 static inline void
52 unmask_irq(unsigned int irq_nr)
53 {
54         *R_VECT_MASK_SET = 1 << irq_nr;
55 }
56
57 void
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
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
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 /* 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
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
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
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
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
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
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
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
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
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
498 init_irq_proc(void)
499 {
500 }
501 #endif