1 /* $Id: irq.c,v 1.20 2004/01/13 05:52:11 kkojima Exp $ 2 * 3 * linux/arch/sh/kernel/irq.c 4 * 5 * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar 6 * 7 * 8 * SuperH version: Copyright (C) 1999 Niibe Yutaka 9 */ 10 11 /* 12 * IRQs are in fact implemented a bit like signal handlers for the kernel. 13 * Naturally it's not a 1:1 relation, but there are similarities. 14 */ 15 16 #include <linux/config.h> 17 #include <linux/module.h> 18 #include <linux/ptrace.h> 19 #include <linux/errno.h> 20 #include <linux/kernel_stat.h> 21 #include <linux/signal.h> 22 #include <linux/sched.h> 23 #include <linux/ioport.h> 24 #include <linux/interrupt.h> 25 #include <linux/timex.h> 26 #include <linux/mm.h> 27 #include <linux/slab.h> 28 #include <linux/random.h> 29 #include <linux/smp.h> 30 #include <linux/smp_lock.h> 31 #include <linux/init.h> 32 #include <linux/seq_file.h> 33 #include <linux/kallsyms.h> 34 #include <linux/bitops.h> 35 36 #include <asm/system.h> 37 #include <asm/io.h> 38 #include <asm/pgalloc.h> 39 #include <asm/delay.h> 40 #include <asm/irq.h> 41 #include <linux/irq.h> 42 43 44 /* 45 * 'what should we do if we get a hw irq event on an illegal vector'. 46 * each architecture has to answer this themselves, it doesn't deserve 47 * a generic callback i think. 48 */ 49 void ack_bad_irq(unsigned int irq) 50 { 51 printk("unexpected IRQ trap at vector %02x\n", irq); 52 } 53 54 #if defined(CONFIG_PROC_FS) 55 int show_interrupts(struct seq_file *p, void *v) 56 { 57 int i = *(loff_t *) v, j; 58 struct irqaction * action; 59 unsigned long flags; 60 61 if (i == 0) { 62 seq_puts(p, " "); 63 for (j=0; j<NR_CPUS; j++) 64 if (cpu_online(j)) 65 seq_printf(p, "CPU%d ",j); 66 seq_putc(p, '\n'); 67 } 68 69 if (i < ACTUAL_NR_IRQS) { 70 spin_lock_irqsave(&irq_desc[i].lock, flags); 71 action = irq_desc[i].action; 72 if (!action) 73 goto unlock; 74 seq_printf(p, "%3d: ",i); 75 seq_printf(p, "%10u ", kstat_irqs(i)); 76 seq_printf(p, " %14s", irq_desc[i].handler->typename); 77 seq_printf(p, " %s", action->name); 78 79 for (action=action->next; action; action = action->next) 80 seq_printf(p, ", %s", action->name); 81 seq_putc(p, '\n'); 82 unlock: 83 spin_unlock_irqrestore(&irq_desc[i].lock, flags); 84 } 85 return 0; 86 } 87 #endif 88 89 asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, 90 unsigned long r6, unsigned long r7, 91 struct pt_regs regs) 92 { 93 int irq; 94 95 irq_enter(); 96 asm volatile("stc r2_bank, %0\n\t" 97 "shlr2 %0\n\t" 98 "shlr2 %0\n\t" 99 "shlr %0\n\t" 100 "add #-16, %0\n\t" 101 :"=z" (irq)); 102 irq = irq_demux(irq); 103 __do_IRQ(irq, ®s); 104 irq_exit(); 105 return 1; 106 } 107