]> bbs.cooldavid.org Git - net-next-2.6.git/blame - arch/sparc/kernel/irq.c
[SOUND] CS4231 SBus: Two fixes.
[net-next-2.6.git] / arch / sparc / kernel / irq.c
CommitLineData
1da177e4
LT
1/* $Id: irq.c,v 1.114 2001/12/11 04:55:51 davem Exp $
2 * arch/sparc/kernel/irq.c: Interrupt request handling routines. On the
d1a78c32 3 * Sparc the IRQs are basically 'cast in stone'
1da177e4
LT
4 * and you are supposed to probe the prom's device
5 * node trees to find out who's got which IRQ.
6 *
7 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
8 * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
9 * Copyright (C) 1995,2002 Pete A. Zaitcev (zaitcev@yahoo.com)
10 * Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk)
11 * Copyright (C) 1998-2000 Anton Blanchard (anton@samba.org)
12 */
13
1da177e4
LT
14#include <linux/module.h>
15#include <linux/sched.h>
16#include <linux/ptrace.h>
17#include <linux/errno.h>
18#include <linux/linkage.h>
19#include <linux/kernel_stat.h>
20#include <linux/signal.h>
21#include <linux/sched.h>
22#include <linux/interrupt.h>
23#include <linux/slab.h>
24#include <linux/random.h>
25#include <linux/init.h>
26#include <linux/smp.h>
1da177e4
LT
27#include <linux/delay.h>
28#include <linux/threads.h>
29#include <linux/spinlock.h>
30#include <linux/seq_file.h>
31
32#include <asm/ptrace.h>
33#include <asm/processor.h>
34#include <asm/system.h>
35#include <asm/psr.h>
36#include <asm/smp.h>
37#include <asm/vaddrs.h>
38#include <asm/timer.h>
39#include <asm/openprom.h>
40#include <asm/oplib.h>
41#include <asm/traps.h>
42#include <asm/irq.h>
43#include <asm/io.h>
44#include <asm/pgalloc.h>
45#include <asm/pgtable.h>
46#include <asm/pcic.h>
47#include <asm/cacheflush.h>
0d84438d 48#include <asm/irq_regs.h>
1da177e4 49
32231a66
AV
50#include "irq.h"
51
1da177e4
LT
52#ifdef CONFIG_SMP
53#define SMP_NOP2 "nop; nop;\n\t"
54#define SMP_NOP3 "nop; nop; nop;\n\t"
55#else
56#define SMP_NOP2
57#define SMP_NOP3
58#endif /* SMP */
59unsigned long __local_irq_save(void)
60{
61 unsigned long retval;
62 unsigned long tmp;
63
64 __asm__ __volatile__(
65 "rd %%psr, %0\n\t"
66 SMP_NOP3 /* Sun4m + Cypress + SMP bug */
67 "or %0, %2, %1\n\t"
68 "wr %1, 0, %%psr\n\t"
69 "nop; nop; nop\n"
70 : "=&r" (retval), "=r" (tmp)
71 : "i" (PSR_PIL)
72 : "memory");
73
74 return retval;
75}
76
77void local_irq_enable(void)
78{
79 unsigned long tmp;
80
81 __asm__ __volatile__(
82 "rd %%psr, %0\n\t"
83 SMP_NOP3 /* Sun4m + Cypress + SMP bug */
84 "andn %0, %1, %0\n\t"
85 "wr %0, 0, %%psr\n\t"
86 "nop; nop; nop\n"
87 : "=&r" (tmp)
88 : "i" (PSR_PIL)
89 : "memory");
90}
91
92void local_irq_restore(unsigned long old_psr)
93{
94 unsigned long tmp;
95
96 __asm__ __volatile__(
97 "rd %%psr, %0\n\t"
98 "and %2, %1, %2\n\t"
99 SMP_NOP2 /* Sun4m + Cypress + SMP bug */
100 "andn %0, %1, %0\n\t"
101 "wr %0, %2, %%psr\n\t"
102 "nop; nop; nop\n"
103 : "=&r" (tmp)
104 : "i" (PSR_PIL), "r" (old_psr)
105 : "memory");
106}
107
108EXPORT_SYMBOL(__local_irq_save);
109EXPORT_SYMBOL(local_irq_enable);
110EXPORT_SYMBOL(local_irq_restore);
111
112/*
113 * Dave Redman (djhr@tadpole.co.uk)
114 *
115 * IRQ numbers.. These are no longer restricted to 15..
116 *
117 * this is done to enable SBUS cards and onboard IO to be masked
118 * correctly. using the interrupt level isn't good enough.
119 *
120 * For example:
121 * A device interrupting at sbus level6 and the Floppy both come in
122 * at IRQ11, but enabling and disabling them requires writing to
123 * different bits in the SLAVIO/SEC.
124 *
125 * As a result of these changes sun4m machines could now support
126 * directed CPU interrupts using the existing enable/disable irq code
127 * with tweaks.
128 *
129 */
130
131static void irq_panic(void)
132{
133 extern char *cputypval;
134 prom_printf("machine: %s doesn't have irq handlers defined!\n",cputypval);
135 prom_halt();
136}
137
40220c1a
DH
138void (*sparc_init_timers)(irq_handler_t ) =
139 (void (*)(irq_handler_t )) irq_panic;
1da177e4
LT
140
141/*
142 * Dave Redman (djhr@tadpole.co.uk)
143 *
144 * There used to be extern calls and hard coded values here.. very sucky!
145 * instead, because some of the devices attach very early, I do something
146 * equally sucky but at least we'll never try to free statically allocated
147 * space or call kmalloc before kmalloc_init :(.
148 *
149 * In fact it's the timer10 that attaches first.. then timer14
150 * then kmalloc_init is called.. then the tty interrupts attach.
151 * hmmm....
152 *
153 */
154#define MAX_STATIC_ALLOC 4
155struct irqaction static_irqaction[MAX_STATIC_ALLOC];
156int static_irq_count;
157
a54123e2
BB
158struct {
159 struct irqaction *action;
160 int flags;
161} sparc_irq[NR_IRQS];
162#define SPARC_IRQ_INPROGRESS 1
1da177e4
LT
163
164/* Used to protect the IRQ action lists */
165DEFINE_SPINLOCK(irq_action_lock);
166
167int show_interrupts(struct seq_file *p, void *v)
168{
169 int i = *(loff_t *) v;
170 struct irqaction * action;
171 unsigned long flags;
172#ifdef CONFIG_SMP
173 int j;
174#endif
175
176 if (sparc_cpu_model == sun4d) {
177 extern int show_sun4d_interrupts(struct seq_file *, void *);
178
179 return show_sun4d_interrupts(p, v);
180 }
181 spin_lock_irqsave(&irq_action_lock, flags);
182 if (i < NR_IRQS) {
a54123e2 183 action = sparc_irq[i].action;
1da177e4
LT
184 if (!action)
185 goto out_unlock;
186 seq_printf(p, "%3d: ", i);
187#ifndef CONFIG_SMP
188 seq_printf(p, "%10u ", kstat_irqs(i));
189#else
394e3902
AM
190 for_each_online_cpu(j) {
191 seq_printf(p, "%10u ",
a54123e2 192 kstat_cpu(j).irqs[i]);
1da177e4
LT
193 }
194#endif
195 seq_printf(p, " %c %s",
67413202 196 (action->flags & IRQF_DISABLED) ? '+' : ' ',
1da177e4
LT
197 action->name);
198 for (action=action->next; action; action = action->next) {
199 seq_printf(p, ",%s %s",
67413202 200 (action->flags & IRQF_DISABLED) ? " +" : "",
1da177e4
LT
201 action->name);
202 }
203 seq_putc(p, '\n');
204 }
205out_unlock:
206 spin_unlock_irqrestore(&irq_action_lock, flags);
207 return 0;
208}
209
210void free_irq(unsigned int irq, void *dev_id)
211{
212 struct irqaction * action;
a54123e2 213 struct irqaction **actionp;
1da177e4
LT
214 unsigned long flags;
215 unsigned int cpu_irq;
216
217 if (sparc_cpu_model == sun4d) {
218 extern void sun4d_free_irq(unsigned int, void *);
219
220 sun4d_free_irq(irq, dev_id);
221 return;
222 }
223 cpu_irq = irq & (NR_IRQS - 1);
224 if (cpu_irq > 14) { /* 14 irq levels on the sparc */
225 printk("Trying to free bogus IRQ %d\n", irq);
226 return;
227 }
228
229 spin_lock_irqsave(&irq_action_lock, flags);
230
a54123e2
BB
231 actionp = &sparc_irq[cpu_irq].action;
232 action = *actionp;
1da177e4
LT
233
234 if (!action->handler) {
235 printk("Trying to free free IRQ%d\n",irq);
236 goto out_unlock;
237 }
238 if (dev_id) {
239 for (; action; action = action->next) {
240 if (action->dev_id == dev_id)
241 break;
a54123e2 242 actionp = &action->next;
1da177e4
LT
243 }
244 if (!action) {
245 printk("Trying to free free shared IRQ%d\n",irq);
246 goto out_unlock;
247 }
67413202 248 } else if (action->flags & IRQF_SHARED) {
1da177e4
LT
249 printk("Trying to free shared IRQ%d with NULL device ID\n", irq);
250 goto out_unlock;
251 }
252 if (action->flags & SA_STATIC_ALLOC)
253 {
254 /* This interrupt is marked as specially allocated
255 * so it is a bad idea to free it.
256 */
257 printk("Attempt to free statically allocated IRQ%d (%s)\n",
258 irq, action->name);
259 goto out_unlock;
260 }
a54123e2
BB
261
262 *actionp = action->next;
1da177e4
LT
263
264 spin_unlock_irqrestore(&irq_action_lock, flags);
265
266 synchronize_irq(irq);
267
268 spin_lock_irqsave(&irq_action_lock, flags);
269
270 kfree(action);
271
a54123e2 272 if (!sparc_irq[cpu_irq].action)
0f516813 273 __disable_irq(irq);
1da177e4
LT
274
275out_unlock:
276 spin_unlock_irqrestore(&irq_action_lock, flags);
277}
278
279EXPORT_SYMBOL(free_irq);
280
281/*
282 * This is called when we want to synchronize with
283 * interrupts. We may for example tell a device to
284 * stop sending interrupts: but to make sure there
285 * are no interrupts that are executing on another
286 * CPU we need to call this function.
287 */
288#ifdef CONFIG_SMP
289void synchronize_irq(unsigned int irq)
290{
a54123e2
BB
291 unsigned int cpu_irq;
292
293 cpu_irq = irq & (NR_IRQS - 1);
294 while (sparc_irq[cpu_irq].flags & SPARC_IRQ_INPROGRESS)
295 cpu_relax();
1da177e4
LT
296}
297#endif /* SMP */
298
299void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs)
300{
301 int i;
302 struct irqaction * action;
303 unsigned int cpu_irq;
304
305 cpu_irq = irq & (NR_IRQS - 1);
a54123e2 306 action = sparc_irq[cpu_irq].action;
1da177e4
LT
307
308 printk("IO device interrupt, irq = %d\n", irq);
309 printk("PC = %08lx NPC = %08lx FP=%08lx\n", regs->pc,
310 regs->npc, regs->u_regs[14]);
311 if (action) {
312 printk("Expecting: ");
313 for (i = 0; i < 16; i++)
314 if (action->handler)
315 printk("[%s:%d:0x%x] ", action->name,
316 (int) i, (unsigned int) action->handler);
317 }
318 printk("AIEEE\n");
319 panic("bogus interrupt received");
320}
321
322void handler_irq(int irq, struct pt_regs * regs)
323{
0d84438d 324 struct pt_regs *old_regs;
1da177e4
LT
325 struct irqaction * action;
326 int cpu = smp_processor_id();
327#ifdef CONFIG_SMP
328 extern void smp4m_irq_rotate(int cpu);
329#endif
330
0d84438d 331 old_regs = set_irq_regs(regs);
1da177e4
LT
332 irq_enter();
333 disable_pil_irq(irq);
334#ifdef CONFIG_SMP
d1a78c32 335 /* Only rotate on lower priority IRQs (scsi, ethernet, etc.). */
198c167c 336 if((sparc_cpu_model==sun4m) && (irq < 10))
1da177e4
LT
337 smp4m_irq_rotate(cpu);
338#endif
a54123e2
BB
339 action = sparc_irq[irq].action;
340 sparc_irq[irq].flags |= SPARC_IRQ_INPROGRESS;
1da177e4
LT
341 kstat_cpu(cpu).irqs[irq]++;
342 do {
343 if (!action || !action->handler)
344 unexpected_irq(irq, NULL, regs);
0d84438d 345 action->handler(irq, action->dev_id);
1da177e4
LT
346 action = action->next;
347 } while (action);
a54123e2 348 sparc_irq[irq].flags &= ~SPARC_IRQ_INPROGRESS;
1da177e4
LT
349 enable_pil_irq(irq);
350 irq_exit();
0d84438d 351 set_irq_regs(old_regs);
1da177e4
LT
352}
353
354#ifdef CONFIG_BLK_DEV_FD
f6d7b8a7 355extern void floppy_interrupt(int irq, void *dev_id);
1da177e4
LT
356
357void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs)
358{
0d84438d 359 struct pt_regs *old_regs;
1da177e4
LT
360 int cpu = smp_processor_id();
361
0d84438d 362 old_regs = set_irq_regs(regs);
1da177e4
LT
363 disable_pil_irq(irq);
364 irq_enter();
365 kstat_cpu(cpu).irqs[irq]++;
0d84438d 366 floppy_interrupt(irq, dev_id);
1da177e4
LT
367 irq_exit();
368 enable_pil_irq(irq);
0d84438d 369 set_irq_regs(old_regs);
1da177e4
LT
370 // XXX Eek, it's totally changed with preempt_count() and such
371 // if (softirq_pending(cpu))
372 // do_softirq();
373}
374#endif
375
d1a78c32 376/* Fast IRQs on the Sparc can only have one routine attached to them,
1da177e4
LT
377 * thus no sharing possible.
378 */
379int request_fast_irq(unsigned int irq,
40220c1a 380 irq_handler_t handler,
1da177e4
LT
381 unsigned long irqflags, const char *devname)
382{
383 struct irqaction *action;
384 unsigned long flags;
385 unsigned int cpu_irq;
386 int ret;
387#ifdef CONFIG_SMP
388 struct tt_entry *trap_table;
389 extern struct tt_entry trapbase_cpu1, trapbase_cpu2, trapbase_cpu3;
390#endif
391
392 cpu_irq = irq & (NR_IRQS - 1);
393 if(cpu_irq > 14) {
394 ret = -EINVAL;
395 goto out;
396 }
397 if(!handler) {
398 ret = -EINVAL;
399 goto out;
400 }
401
402 spin_lock_irqsave(&irq_action_lock, flags);
403
a54123e2 404 action = sparc_irq[cpu_irq].action;
1da177e4 405 if(action) {
67413202 406 if(action->flags & IRQF_SHARED)
1da177e4 407 panic("Trying to register fast irq when already shared.\n");
67413202 408 if(irqflags & IRQF_SHARED)
1da177e4
LT
409 panic("Trying to register fast irq as shared.\n");
410
411 /* Anyway, someone already owns it so cannot be made fast. */
412 printk("request_fast_irq: Trying to register yet already owned.\n");
413 ret = -EBUSY;
414 goto out_unlock;
415 }
416
417 /* If this is flagged as statically allocated then we use our
418 * private struct which is never freed.
419 */
420 if (irqflags & SA_STATIC_ALLOC) {
421 if (static_irq_count < MAX_STATIC_ALLOC)
422 action = &static_irqaction[static_irq_count++];
423 else
424 printk("Fast IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n",
425 irq, devname);
426 }
427
428 if (action == NULL)
5cbded58 429 action = kmalloc(sizeof(struct irqaction),
1da177e4
LT
430 GFP_ATOMIC);
431
432 if (!action) {
433 ret = -ENOMEM;
434 goto out_unlock;
435 }
436
437 /* Dork with trap table if we get this far. */
438#define INSTANTIATE(table) \
439 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_one = SPARC_RD_PSR_L0; \
440 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_two = \
441 SPARC_BRANCH((unsigned long) handler, \
442 (unsigned long) &table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_two);\
443 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_three = SPARC_RD_WIM_L3; \
444 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP;
445
446 INSTANTIATE(sparc_ttable)
447#ifdef CONFIG_SMP
448 trap_table = &trapbase_cpu1; INSTANTIATE(trap_table)
449 trap_table = &trapbase_cpu2; INSTANTIATE(trap_table)
450 trap_table = &trapbase_cpu3; INSTANTIATE(trap_table)
451#endif
452#undef INSTANTIATE
453 /*
454 * XXX Correct thing whould be to flush only I- and D-cache lines
455 * which contain the handler in question. But as of time of the
456 * writing we have no CPU-neutral interface to fine-grained flushes.
457 */
458 flush_cache_all();
459
460 action->handler = handler;
461 action->flags = irqflags;
462 cpus_clear(action->mask);
463 action->name = devname;
464 action->dev_id = NULL;
465 action->next = NULL;
466
a54123e2 467 sparc_irq[cpu_irq].action = action;
1da177e4 468
0f516813 469 __enable_irq(irq);
1da177e4
LT
470
471 ret = 0;
472out_unlock:
473 spin_unlock_irqrestore(&irq_action_lock, flags);
474out:
475 return ret;
476}
477
478int request_irq(unsigned int irq,
40220c1a 479 irq_handler_t handler,
1da177e4
LT
480 unsigned long irqflags, const char * devname, void *dev_id)
481{
a54123e2 482 struct irqaction * action, **actionp;
1da177e4
LT
483 unsigned long flags;
484 unsigned int cpu_irq;
485 int ret;
486
487 if (sparc_cpu_model == sun4d) {
488 extern int sun4d_request_irq(unsigned int,
40220c1a 489 irq_handler_t ,
1da177e4
LT
490 unsigned long, const char *, void *);
491 return sun4d_request_irq(irq, handler, irqflags, devname, dev_id);
492 }
493 cpu_irq = irq & (NR_IRQS - 1);
494 if(cpu_irq > 14) {
495 ret = -EINVAL;
496 goto out;
497 }
498 if (!handler) {
499 ret = -EINVAL;
500 goto out;
501 }
502
503 spin_lock_irqsave(&irq_action_lock, flags);
504
a54123e2
BB
505 actionp = &sparc_irq[cpu_irq].action;
506 action = *actionp;
1da177e4 507 if (action) {
67413202 508 if (!(action->flags & IRQF_SHARED) || !(irqflags & IRQF_SHARED)) {
1da177e4
LT
509 ret = -EBUSY;
510 goto out_unlock;
511 }
67413202 512 if ((action->flags & IRQF_DISABLED) != (irqflags & IRQF_DISABLED)) {
1da177e4
LT
513 printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq);
514 ret = -EBUSY;
515 goto out_unlock;
a54123e2
BB
516 }
517 for ( ; action; action = *actionp)
518 actionp = &action->next;
1da177e4
LT
519 }
520
521 /* If this is flagged as statically allocated then we use our
522 * private struct which is never freed.
523 */
524 if (irqflags & SA_STATIC_ALLOC) {
525 if (static_irq_count < MAX_STATIC_ALLOC)
526 action = &static_irqaction[static_irq_count++];
527 else
528 printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n", irq, devname);
529 }
530
531 if (action == NULL)
5cbded58 532 action = kmalloc(sizeof(struct irqaction),
1da177e4
LT
533 GFP_ATOMIC);
534
535 if (!action) {
536 ret = -ENOMEM;
537 goto out_unlock;
538 }
539
540 action->handler = handler;
541 action->flags = irqflags;
542 cpus_clear(action->mask);
543 action->name = devname;
544 action->next = NULL;
545 action->dev_id = dev_id;
546
a54123e2 547 *actionp = action;
1da177e4 548
0f516813 549 __enable_irq(irq);
1da177e4
LT
550
551 ret = 0;
552out_unlock:
553 spin_unlock_irqrestore(&irq_action_lock, flags);
554out:
555 return ret;
556}
557
558EXPORT_SYMBOL(request_irq);
559
0f516813
AV
560void disable_irq_nosync(unsigned int irq)
561{
562 return __disable_irq(irq);
563}
564EXPORT_SYMBOL(disable_irq_nosync);
565
566void disable_irq(unsigned int irq)
567{
568 return __disable_irq(irq);
569}
570EXPORT_SYMBOL(disable_irq);
571
572void enable_irq(unsigned int irq)
573{
574 return __enable_irq(irq);
575}
576
577EXPORT_SYMBOL(enable_irq);
578
1da177e4
LT
579/* We really don't need these at all on the Sparc. We only have
580 * stubs here because they are exported to modules.
581 */
582unsigned long probe_irq_on(void)
583{
584 return 0;
585}
586
587EXPORT_SYMBOL(probe_irq_on);
588
589int probe_irq_off(unsigned long mask)
590{
591 return 0;
592}
593
594EXPORT_SYMBOL(probe_irq_off);
595
596/* djhr
597 * This could probably be made indirect too and assigned in the CPU
598 * bits of the code. That would be much nicer I think and would also
599 * fit in with the idea of being able to tune your kernel for your machine
600 * by removing unrequired machine and device support.
601 *
602 */
603
604void __init init_IRQ(void)
605{
606 extern void sun4c_init_IRQ( void );
607 extern void sun4m_init_IRQ( void );
608 extern void sun4d_init_IRQ( void );
609
610 switch(sparc_cpu_model) {
611 case sun4c:
612 case sun4:
613 sun4c_init_IRQ();
614 break;
615
616 case sun4m:
617#ifdef CONFIG_PCI
618 pcic_probe();
619 if (pcic_present()) {
620 sun4m_pci_init_IRQ();
621 break;
622 }
623#endif
624 sun4m_init_IRQ();
625 break;
626
627 case sun4d:
628 sun4d_init_IRQ();
629 break;
630
631 default:
d1a78c32 632 prom_printf("Cannot initialize IRQs on this Sun machine...");
1da177e4
LT
633 break;
634 }
635 btfixup();
636}
637
638void init_irq_proc(void)
639{
640 /* For now, nothing... */
641}