This source file includes following definitions.
- disable_irq
- enable_irq
- get_irq_list
- free_irq
- handle_nmi
- unexpected_irq
- handler_irq
- do_IRQ
- do_sparc_timer
- do_fast_IRQ
- request_irq
- probe_irq_on
- probe_irq_off
- init_IRQ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <linux/config.h>
23 #include <linux/ptrace.h>
24 #include <linux/errno.h>
25 #include <linux/linkage.h>
26 #include <linux/kernel_stat.h>
27 #include <linux/signal.h>
28 #include <linux/sched.h>
29 #include <linux/interrupt.h>
30 #include <asm/ptrace.h>
31 #include <asm/system.h>
32 #include <asm/psr.h>
33 #include <asm/vaddrs.h>
34 #include <asm/clock.h>
35 #include <asm/openprom.h>
36
37 #define DEBUG_IRQ
38
39 void disable_irq(unsigned int irq_nr)
40 {
41 unsigned long flags;
42 unsigned char *int_reg;
43
44 save_flags(flags);
45 cli();
46
47
48
49
50
51 int_reg = (unsigned char *) IRQ_ENA_ADR;
52
53 switch(irq_nr)
54 {
55 case 1:
56 *int_reg = ((*int_reg) & (~(0x02)));
57 break;
58 case 4:
59 *int_reg = ((*int_reg) & (~(0x04)));
60 break;
61 case 6:
62 *int_reg = ((*int_reg) & (~(0x08)));
63 break;
64 case 8:
65 *int_reg = ((*int_reg) & (~(0x10)));
66 break;
67 case 10:
68 *int_reg = ((*int_reg) & (~(0x20)));
69 break;
70 case 14:
71 *int_reg = ((*int_reg) & (~(0x80)));
72 break;
73 default:
74 printk("AIEEE, Illegal interrupt disable requested irq=%d\n",
75 (int) irq_nr);
76 break;
77 };
78
79 restore_flags(flags);
80 return;
81 }
82
83 void enable_irq(unsigned int irq_nr)
84 {
85 unsigned long flags;
86 unsigned char *int_reg;
87
88 save_flags(flags);
89 cli();
90
91
92
93
94
95 int_reg = (unsigned char *) IRQ_ENA_ADR;
96
97 #ifdef DEBUG_IRQ
98 printk(" --- Enabling IRQ level %d ---\n", irq_nr);
99 #endif
100
101 switch(irq_nr)
102 {
103 case 1:
104 *int_reg = ((*int_reg) | 0x02);
105 break;
106 case 4:
107 *int_reg = ((*int_reg) | 0x04);
108 break;
109 case 6:
110 *int_reg = ((*int_reg) | 0x08);
111 break;
112 case 8:
113 *int_reg = ((*int_reg) | 0x10);
114 break;
115 case 10:
116 *int_reg = ((*int_reg) | 0x20);
117 break;
118 case 14:
119 *int_reg = ((*int_reg) | 0x80);
120 break;
121 default:
122 printk("AIEEE, Illegal interrupt enable requested irq=%d\n",
123 (int) irq_nr);
124 break;
125 };
126
127 restore_flags(flags);
128
129 return;
130 }
131
132
133
134
135 struct irqaction {
136 void (*handler)(int, struct pt_regs *);
137 unsigned long flags;
138 unsigned long mask;
139 const char *name;
140 };
141
142 static struct irqaction irq_action[16] = {
143 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
144 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
145 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
146 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
147 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
148 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
149 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
150 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }
151 };
152
153
154 int get_irq_list(char *buf)
155 {
156 int i, len = 0;
157 struct irqaction * action = irq_action;
158
159 for (i = 0 ; i < 16 ; i++, action++) {
160 if (!action->handler)
161 continue;
162 len += sprintf(buf+len, "%2d: %8d %c %s\n",
163 i, kstat.interrupts[i],
164 (action->flags & SA_INTERRUPT) ? '+' : ' ',
165 action->name);
166 }
167 return len;
168 }
169
170 void free_irq(unsigned int irq)
171 {
172 struct irqaction * action = irq + irq_action;
173 unsigned long flags;
174
175 if (irq > 14) {
176 printk("Trying to free IRQ %d\n", irq);
177 return;
178 }
179 if (!action->handler) {
180 printk("Trying to free free IRQ%d\n", irq);
181 return;
182 }
183 save_flags(flags);
184 cli();
185 disable_irq(irq);
186 action->handler = NULL;
187 action->flags = 0;
188 action->mask = 0;
189 action->name = NULL;
190 restore_flags(flags);
191 }
192
193 #if 0
194 static void handle_nmi(struct pt_regs * regs)
195 {
196 printk("NMI, probably due to bus-parity error.\n");
197 printk("PC=%08lx, SP=%08lx\n", regs->pc, regs->sp);
198 }
199 #endif
200
201 void unexpected_irq(int irq, struct pt_regs * regs)
202 {
203 int i;
204
205 printk("IO device interrupt, irq = %d\n", irq);
206 printk("PC = %08lx NPC = %08lx SP=%08lx\n", regs->pc,
207 regs->npc, regs->sp);
208 printk("Expecting: ");
209 for (i = 0; i < 16; i++)
210 if (irq_action[i].handler)
211 printk("[%s:%d] ", irq_action[i].name, i);
212 printk("AIEEE\n");
213 }
214
215 static inline void handler_irq(int irq, struct pt_regs * regs)
216 {
217 struct irqaction * action = irq + irq_action;
218
219 if (!action->handler) {
220 unexpected_irq(irq, regs);
221 return;
222 }
223 action->handler(irq, regs);
224 }
225
226
227
228
229
230
231
232
233 asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
234 {
235 struct irqaction *action = irq + irq_action;
236
237 kstat.interrupts[irq]++;
238 action->handler(irq, regs);
239 return;
240 }
241
242
243
244
245
246
247
248 asmlinkage void do_sparc_timer(int irq, struct pt_regs * regs)
249 {
250 struct irqaction *action = irq + irq_action;
251 register volatile int clear;
252
253 kstat.interrupts[irq]++;
254
255
256
257
258 clear = TIMER_STRUCT->timer_limit14;
259
260 action->handler(irq, regs);
261 return;
262 }
263
264
265
266
267
268
269 asmlinkage void do_fast_IRQ(int irq)
270 {
271 kstat.interrupts[irq]++;
272 printk("Got FAST_IRQ number %04lx\n", (long unsigned int) irq);
273 return;
274 }
275
276 extern int first_descent;
277 extern void probe_clock(int);
278
279 int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
280 unsigned long irqflags, const char * devname)
281 {
282 struct irqaction *action;
283 unsigned long flags;
284
285 if(irq > 14)
286 return -EINVAL;
287
288 if(irq == 0)
289 {
290 irq = 14;
291 probe_clock(first_descent);
292 }
293
294 action = irq + irq_action;
295
296 if(action->handler)
297 return -EBUSY;
298
299 if(!handler)
300 return -EINVAL;
301
302 save_flags(flags);
303
304 cli();
305
306 action->handler = handler;
307 action->flags = irqflags;
308 action->mask = 0;
309 action->name = devname;
310
311 enable_irq(irq);
312
313 restore_flags(flags);
314
315 return 0;
316 }
317
318 unsigned int probe_irq_on (void)
319 {
320 unsigned int irqs = 0;
321
322 return irqs;
323 }
324
325 int probe_irq_off (unsigned int irqs)
326 {
327 unsigned int i = 0;
328
329 return i;
330 }
331
332 void init_IRQ(void)
333 {
334 return;
335 }