MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / arch / nios2nommu / kernel / irq.c
blobf1b23472bbb7fbe7a48841f0f0c344b044c5ba8b
1 /*
2 * linux/arch/$(ARCH)/irq.c -- general exception handling code
4 * Cloned from Linux/m68k.
6 * No original Copyright holder listed,
7 * Probabily original (C) Roman Zippel (assigned DJD, 1999)
9 * Copyright 1999-2000 D. Jeff Dionne, <jeff@rt-control.com>
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file COPYING in the main directory of this archive
13 * for more details.
16 #include <linux/types.h>
17 #include <linux/module.h>
18 #include <linux/sched.h>
19 #include <linux/kernel_stat.h>
20 #include <linux/errno.h>
21 #include <linux/init.h>
22 #include <linux/seq_file.h>
24 #include <asm/system.h>
25 #include <asm/irq.h>
26 #include <asm/page.h>
27 #include <asm/nios.h>
28 #include <asm/hardirq.h>
30 /* table for system interrupt handlers */
31 irq_hand_t irq_list[NR_IRQS];
33 /* The number of spurious interrupts */
34 volatile unsigned int num_spurious;
36 #define NUM_IRQ_NODES 16
37 static irq_node_t nodes[NUM_IRQ_NODES];
39 void __init init_irq_proc(void)
41 /* Insert /proc/irq driver here */
44 static irqreturn_t default_irq_handler(int irq, void *ptr)
46 #if 1
47 printk(KERN_INFO "%s(%d): default irq handler vec=%d [0x%x]\n",
48 __FILE__, __LINE__, irq, irq);
49 #endif
50 disable_irq(irq);
51 return(IRQ_NONE);
55 * void init_IRQ(void)
57 * Parameters: None
59 * Returns: Nothing
61 * This function should be called during kernel startup to initialize
62 * the IRQ handling routines.
65 void __init init_IRQ(void)
67 int i;
69 for (i = 0; i < NR_IRQS; i++) {
70 irq_list[i].handler = default_irq_handler;
71 irq_list[i].flags = IRQ_FLG_STD;
72 irq_list[i].dev_id = NULL;
73 irq_list[i].devname = NULL;
76 for (i = 0; i < NUM_IRQ_NODES; i++)
77 nodes[i].handler = NULL;
79 /* turn off all interrupts */
80 clrimr(0);
82 #ifdef DEBUG
83 printk("init_IRQ done\n");
84 #endif
87 irq_node_t *new_irq_node(void)
89 irq_node_t *node;
90 short i;
92 for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--)
93 if (!node->handler)
94 return node;
96 printk (KERN_INFO "new_irq_node: out of nodes\n");
97 return NULL;
100 int request_irq(unsigned int irq,
101 irq_handler_t handler,
102 unsigned long flags,
103 const char *devname,
104 void *dev_id)
106 if (irq >= NR_IRQS) {
107 printk (KERN_ERR "%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname);
108 return -ENXIO;
111 if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
112 if (irq_list[irq].flags & IRQ_FLG_LOCK) {
113 printk(KERN_ERR "%s: IRQ %d from %s is not replaceable\n",
114 __FUNCTION__, irq, irq_list[irq].devname);
115 return -EBUSY;
117 if (flags & IRQ_FLG_REPLACE) {
118 printk(KERN_ERR "%s: %s can't replace IRQ %d from %s\n",
119 __FUNCTION__, devname, irq, irq_list[irq].devname);
120 return -EBUSY;
123 irq_list[irq].handler = handler;
124 irq_list[irq].flags = flags;
125 irq_list[irq].dev_id = dev_id;
126 irq_list[irq].devname = devname;
128 setimr(1<<irq);
130 return 0;
133 void free_irq(unsigned int irq, void *dev_id)
135 if (irq >= NR_IRQS) {
136 printk (KERN_ERR "%s: Unknown IRQ %d\n", __FUNCTION__, irq);
137 return;
140 if (irq_list[irq].dev_id != dev_id)
141 printk(KERN_ERR "%s: Removing probably wrong IRQ %d from %s\n",
142 __FUNCTION__, irq, irq_list[irq].devname);
144 irq_list[irq].handler = default_irq_handler;
145 irq_list[irq].flags = IRQ_FLG_STD;
146 irq_list[irq].dev_id = NULL;
147 irq_list[irq].devname = NULL;
149 clrimr(~(1<<irq));
152 /* usually not useful in embedded systems */
153 unsigned long probe_irq_on (void)
155 return 0;
158 int probe_irq_off (unsigned long irqs)
160 return 0;
163 void enable_irq(unsigned int irq)
165 setimr(1<<irq);
168 void disable_irq(unsigned int irq)
170 clrimr(~(1<<irq));
173 int show_interrupts(struct seq_file *p, void *v)
175 int i = *(loff_t *) v;
177 if (i == 0) {
178 seq_printf(p, " : %10u spurious\n", num_spurious);
181 if ((i < NR_IRQS) && (!(irq_list[i].flags & IRQ_FLG_STD))) {
182 seq_printf(p, "%3d: %10u ", i, kstat_cpu(0).irqs[i]);
183 if (irq_list[i].flags & IRQ_FLG_LOCK)
184 seq_printf(p, "L ");
185 else
186 seq_printf(p, " ");
187 seq_printf(p, "%s\n", irq_list[i].devname);
190 return 0;
193 #ifdef CONFIG_PREEMPT_TIMES
194 extern void latency_cause(int,int);
195 #else
196 #define latency_cause(a, b)
197 #endif
198 asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
201 /* give the machine specific code a crack at it first */
202 irq_enter();
203 kstat_cpu(0).irqs[vec]++;
204 latency_cause(-99,~vec);
206 if (irq_list[vec].handler) {
207 if ((irq_list[vec].handler(vec, irq_list[vec].dev_id))==IRQ_NONE)
209 } else
210 #ifdef DEBUG
212 printk(KERN_ERR "No interrupt handler for level %ld\n", vec);
213 //// asm("trap 5");
215 #else
216 #if 1
217 printk(KERN_ERR "Ignoring interrupt %ld: no handler\n", vec);
218 #else
219 panic("No interrupt handler for level %ld\n", vec);
220 #endif
221 #endif
223 irq_exit();
226 int get_irq_list(char *buf)
228 int i, len = 0;
230 /* autovector interrupts */
231 for (i = 0; i < NR_IRQS; i++) {
232 if (irq_list[i].handler) {
233 len += sprintf(buf+len, "auto %2d: %10u ", i,
234 i ? kstat_cpu(0).irqs[i] : num_spurious);
235 if (irq_list[i].flags & IRQ_FLG_LOCK)
236 len += sprintf(buf+len, "L ");
237 else
238 len += sprintf(buf+len, " ");
239 len += sprintf(buf+len, "%s\n", irq_list[i].devname);
242 return len;
244 EXPORT_SYMBOL(request_irq);
245 EXPORT_SYMBOL(free_irq);