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
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>
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
)
47 printk(KERN_INFO
"%s(%d): default irq handler vec=%d [0x%x]\n",
48 __FILE__
, __LINE__
, irq
, irq
);
61 * This function should be called during kernel startup to initialize
62 * the IRQ handling routines.
65 void __init
init_IRQ(void)
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 */
83 printk("init_IRQ done\n");
87 irq_node_t
*new_irq_node(void)
92 for (node
= nodes
, i
= NUM_IRQ_NODES
-1; i
>= 0; node
++, i
--)
96 printk (KERN_INFO
"new_irq_node: out of nodes\n");
100 int request_irq(unsigned int irq
,
101 irq_handler_t handler
,
106 if (irq
>= NR_IRQS
) {
107 printk (KERN_ERR
"%s: Unknown IRQ %d from %s\n", __FUNCTION__
, irq
, devname
);
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
);
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
);
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
;
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
);
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
;
152 /* usually not useful in embedded systems */
153 unsigned long probe_irq_on (void)
158 int probe_irq_off (unsigned long irqs
)
163 void enable_irq(unsigned int irq
)
168 void disable_irq(unsigned int irq
)
173 int show_interrupts(struct seq_file
*p
, void *v
)
175 int i
= *(loff_t
*) v
;
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
)
187 seq_printf(p
, "%s\n", irq_list
[i
].devname
);
193 #ifdef CONFIG_PREEMPT_TIMES
194 extern void latency_cause(int,int);
196 #define latency_cause(a, b)
198 asmlinkage
void process_int(unsigned long vec
, struct pt_regs
*fp
)
201 /* give the machine specific code a crack at it first */
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
)
212 printk(KERN_ERR
"No interrupt handler for level %ld\n", vec
);
217 printk(KERN_ERR
"Ignoring interrupt %ld: no handler\n", vec
);
219 panic("No interrupt handler for level %ld\n", vec
);
226 int get_irq_list(char *buf
)
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 ");
238 len
+= sprintf(buf
+len
, " ");
239 len
+= sprintf(buf
+len
, "%s\n", irq_list
[i
].devname
);
244 EXPORT_SYMBOL(request_irq
);
245 EXPORT_SYMBOL(free_irq
);