This source file includes following definitions.
- disable_irq
- enable_irq
- get_irq_list
- do_IRQ
- do_fast_IRQ
- request_irq
- free_irq
- no_action
- 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
23
24
25
26
27 #include <linux/ptrace.h>
28 #include <linux/errno.h>
29 #include <linux/kernel_stat.h>
30 #include <linux/signal.h>
31 #include <linux/sched.h>
32 #include <linux/types.h>
33 #include <linux/interrupt.h>
34 #include <linux/timex.h>
35 #include <linux/malloc.h>
36 #include <linux/random.h>
37
38 #include <asm/bitops.h>
39 #include <asm/bootinfo.h>
40 #include <asm/io.h>
41 #include <asm/irq.h>
42 #include <asm/jazz.h>
43 #include <asm/mipsregs.h>
44 #include <asm/system.h>
45
46 #define TIMER_IRQ 0
47
48 unsigned char cache_21 = 0xff;
49 unsigned char cache_A1 = 0xff;
50
51 unsigned long spurious_count = 0;
52
53 void disable_irq(unsigned int irq_nr)
54 {
55 unsigned long flags;
56 unsigned char mask;
57
58 mask = 1 << (irq_nr & 7);
59 save_flags(flags);
60 if (irq_nr < 8) {
61 cli();
62 cache_21 |= mask;
63 outb(cache_21,0x21);
64 restore_flags(flags);
65 return;
66 }
67 cli();
68 cache_A1 |= mask;
69 outb(cache_A1,0xA1);
70 restore_flags(flags);
71 }
72
73 void enable_irq(unsigned int irq_nr)
74 {
75 unsigned long flags;
76 unsigned char mask;
77
78 mask = ~(1 << (irq_nr & 7));
79 save_flags(flags);
80 if (irq_nr < 8) {
81 cli();
82 cache_21 &= mask;
83 outb(cache_21,0x21);
84 restore_flags(flags);
85 return;
86 }
87 cli();
88 cache_A1 &= mask;
89 outb(cache_A1,0xA1);
90 restore_flags(flags);
91 }
92
93
94
95
96
97 extern void interrupt(void);
98 extern void fast_interrupt(void);
99 extern void bad_interrupt(void);
100
101
102
103
104 static struct irqaction timer_irq = { NULL, 0, 0, NULL, NULL, NULL};
105 static struct irqaction cascade_irq = { NULL, 0, 0, NULL, NULL, NULL};
106 static struct irqaction math_irq = { NULL, 0, 0, NULL, NULL, NULL};
107
108 static struct irqaction *irq_action[16] = {
109 NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL,
110 NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL
111 };
112
113 int get_irq_list(char *buf)
114 {
115 int i, len = 0;
116 struct irqaction * action;
117
118 for (i = 0 ; i < 16 ; i++) {
119 action = *(i + irq_action);
120 if (!action)
121 continue;
122 len += sprintf(buf+len, "%2d: %8d %c %s",
123 i, kstat.interrupts[i],
124 (action->flags & SA_INTERRUPT) ? '+' : ' ',
125 action->name);
126 for (action=action->next; action; action = action->next) {
127 len += sprintf(buf+len, ",%s %s",
128 (action->flags & SA_INTERRUPT) ? " +" : "",
129 action->name);
130 }
131 len += sprintf(buf+len, "\n");
132 }
133 return len;
134 }
135
136
137
138
139
140
141
142
143 asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
144 {
145 struct irqaction * action = *(irq + irq_action);
146
147 kstat.interrupts[irq]++;
148 if (action->flags & SA_SAMPLE_RANDOM)
149 add_interrupt_randomness(irq);
150 while (action) {
151 action->handler(irq, action->dev_id, regs);
152 action = action->next;
153 }
154 }
155
156
157
158
159
160
161 asmlinkage void do_fast_IRQ(int irq)
162 {
163 struct irqaction * action = *(irq + irq_action);
164
165 kstat.interrupts[irq]++;
166 if (action->flags & SA_SAMPLE_RANDOM)
167 add_interrupt_randomness(irq);
168 while (action) {
169 action->handler(irq, action->dev_id, NULL);
170 action = action->next;
171 }
172 }
173
174 #define SA_PROBE SA_ONESHOT
175
176 int request_irq(unsigned int irq,
177 void (*handler)(int, void *, struct pt_regs *),
178 unsigned long irqflags,
179 const char * devname,
180 void *dev_id)
181 {
182 struct irqaction * action, *tmp = NULL;
183 unsigned long flags;
184
185 if (irq > 15)
186 return -EINVAL;
187 if (!handler)
188 return -EINVAL;
189 action = *(irq + irq_action);
190 if (action) {
191 if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) {
192 for (tmp = action; tmp->next; tmp = tmp->next);
193 } else {
194 return -EBUSY;
195 }
196 if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) {
197 printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq);
198 return -EBUSY;
199 }
200 }
201 if (irqflags & SA_SAMPLE_RANDOM)
202 rand_initialize_irq(irq);
203 save_flags(flags);
204 cli();
205 if (irq == 2)
206 action = &cascade_irq;
207 else if (irq == 13)
208 action = &math_irq;
209 else if (irq == TIMER_IRQ)
210 action = &timer_irq;
211 else
212 action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
213
214 if (!action) {
215 restore_flags(flags);
216 return -ENOMEM;
217 }
218
219 action->handler = handler;
220 action->flags = irqflags;
221 action->mask = 0;
222 action->name = devname;
223 action->next = NULL;
224 action->dev_id = dev_id;
225
226 if (tmp) {
227 tmp->next = action;
228 } else {
229 *(irq + irq_action) = action;
230 if (!(action->flags & SA_PROBE)) {
231
232
233
234 if (action->flags & SA_INTERRUPT)
235 set_int_vector(irq,fast_interrupt);
236 else
237 set_int_vector(irq,interrupt);
238 }
239 if (irq < 8) {
240 cache_21 &= ~(1<<irq);
241 outb(cache_21,0x21);
242 } else {
243 cache_21 &= ~(1<<2);
244 cache_A1 &= ~(1<<(irq-8));
245 outb(cache_21,0x21);
246 outb(cache_A1,0xA1);
247 }
248 }
249 restore_flags(flags);
250 return 0;
251 }
252
253 void free_irq(unsigned int irq, void *dev_id)
254 {
255 struct irqaction * action = *(irq + irq_action);
256 struct irqaction * tmp = NULL;
257 unsigned long flags;
258
259 if (irq > 15) {
260 printk("Trying to free IRQ%d\n",irq);
261 return;
262 }
263 if (!action->handler) {
264 printk("Trying to free free IRQ%d\n",irq);
265 return;
266 }
267 if (dev_id) {
268 for (; action; action = action->next) {
269 if (action->dev_id == dev_id) break;
270 tmp = action;
271 }
272 if (!action) {
273 printk("Trying to free free shared IRQ%d\n",irq);
274 return;
275 }
276 } else if (action->flags & SA_SHIRQ) {
277 printk("Trying to free shared IRQ%d with NULL device ID\n", irq);
278 return;
279 }
280 save_flags(flags);
281 cli();
282 if (action && tmp) {
283 tmp->next = action->next;
284 } else {
285 *(irq + irq_action) = action->next;
286 }
287
288 if ((irq == 2) || (irq == 13) | (irq == TIMER_IRQ))
289 memset(action, 0, sizeof(struct irqaction));
290 else
291 kfree_s(action, sizeof(struct irqaction));
292
293 if (!(*(irq + irq_action))) {
294 if (irq < 8) {
295 cache_21 |= 1 << irq;
296 outb(cache_21,0x21);
297 } else {
298 cache_A1 |= 1 << (irq-8);
299 outb(cache_A1,0xA1);
300 }
301 set_int_vector(irq,bad_interrupt);
302 }
303 restore_flags(flags);
304 }
305
306 static void no_action(int cpl, void *dev_id, struct pt_regs * regs) { }
307
308 unsigned long probe_irq_on (void)
309 {
310 unsigned int i, irqs = 0, irqmask;
311 unsigned long delay;
312
313
314 for (i = 15; i > 0; i--) {
315 if (!request_irq(i, no_action, SA_PROBE, "probe", NULL)) {
316 enable_irq(i);
317 irqs |= (1 << i);
318 }
319 }
320
321
322 for (delay = jiffies + 2; delay > jiffies; );
323
324
325 irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21;
326 for (i = 15; i > 0; i--) {
327 if (irqs & (1 << i) & irqmask) {
328 irqs ^= (1 << i);
329 free_irq(i, NULL);
330 }
331 }
332 #ifdef DEBUG
333 printk("probe_irq_on: irqs=0x%04x irqmask=0x%04x\n", irqs, irqmask);
334 #endif
335 return irqs;
336 }
337
338 int probe_irq_off (unsigned long irqs)
339 {
340 unsigned int i, irqmask;
341
342 irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21;
343 for (i = 15; i > 0; i--) {
344 if (irqs & (1 << i)) {
345 free_irq(i, NULL);
346 }
347 }
348 #ifdef DEBUG
349 printk("probe_irq_off: irqs=0x%04x irqmask=0x%04x\n", irqs, irqmask);
350 #endif
351 irqs &= irqmask;
352 if (!irqs)
353 return 0;
354 i = ffz(~irqs);
355 if (irqs != (irqs & (1 << i)))
356 i = -i;
357 return i;
358 }
359
360 void init_IRQ(void)
361 {
362 int i;
363
364 switch (boot_info.machtype) {
365 case MACH_MIPS_MAGNUM_4000:
366 case MACH_ACER_PICA_61:
367 r4030_write_reg16(JAZZ_IO_IRQ_ENABLE,
368 JAZZ_IE_ETHERNET |
369 JAZZ_IE_SERIAL1 |
370 JAZZ_IE_SERIAL2 |
371 JAZZ_IE_PARALLEL |
372 JAZZ_IE_FLOPPY);
373 r4030_read_reg16(JAZZ_IO_IRQ_SOURCE);
374 set_cp0_status(ST0_IM, IE_IRQ4 | IE_IRQ1);
375
376 r4030_write_reg32(JAZZ_TIMER_INTERVAL, 9);
377 break;
378 case MACH_DESKSTATION_TYNE:
379
380 outb_p(0x34,0x43);
381 outb_p(LATCH & 0xff , 0x40);
382 outb(LATCH >> 8 , 0x40);
383
384 if (request_irq(2, no_action, SA_INTERRUPT, "cascade", NULL))
385 printk("Unable to get IRQ2 for cascade\n");
386 break;
387 default:
388 panic("Unknown machtype in init_IRQ");
389 }
390
391 for (i = 0; i < 16 ; i++)
392 set_int_vector(i, bad_interrupt);
393
394
395 for (i = 0; i < 32; i++) {
396 bh_base[i].routine = NULL;
397 bh_base[i].data = NULL;
398 }
399 bh_active = 0;
400 intr_count = 0;
401 }