File: /usr/src/linux/arch/mips/kernel/old-irq.c
1 /*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Code to handle x86 style IRQs plus some generic interrupt stuff.
7 *
8 * Copyright (C) 1992 Linus Torvalds
9 * Copyright (C) 1994 - 2001 Ralf Baechle
10 *
11 * Old rotten IRQ code. To be killed as soon as everybody had converted or
12 * in 2.5.0, whatever comes first.
13 */
14 #include <linux/config.h>
15 #include <linux/errno.h>
16 #include <linux/init.h>
17 #include <linux/kernel_stat.h>
18 #include <linux/module.h>
19 #include <linux/signal.h>
20 #include <linux/sched.h>
21 #include <linux/types.h>
22 #include <linux/interrupt.h>
23 #include <linux/ioport.h>
24 #include <linux/timex.h>
25 #include <linux/slab.h>
26 #include <linux/random.h>
27
28 #include <asm/bitops.h>
29 #include <asm/bootinfo.h>
30 #include <asm/io.h>
31 #include <asm/irq.h>
32 #include <asm/mipsregs.h>
33 #include <asm/system.h>
34 #include <asm/nile4.h>
35
36 /*
37 * The board specific setup routine sets irq_setup to point to a board
38 * specific setup routine.
39 */
40 void (*irq_setup)(void);
41
42 /*
43 * Linux has a controller-independent x86 interrupt architecture.
44 * every controller has a 'controller-template', that is used
45 * by the main code to do the right thing. Each driver-visible
46 * interrupt source is transparently wired to the apropriate
47 * controller. Thus drivers need not be aware of the
48 * interrupt-controller.
49 *
50 * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
51 * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
52 * (IO-APICs assumed to be messaging to Pentium local-APICs)
53 *
54 * the code is designed to be easily extended with new/different
55 * interrupt controllers, without having to do assembly magic.
56 */
57
58 /*
59 * This contains the irq mask for both 8259A irq controllers, it's an
60 * int so we can deal with the third PIC in some systems like the RM300.
61 * (XXX This is broken for big endian.)
62 */
63 static unsigned int cached_irq_mask = 0xffff;
64
65 #define __byte(x,y) (((unsigned char *)&(y))[x])
66 #define __word(x,y) (((unsigned short *)&(y))[x])
67 #define __long(x,y) (((unsigned int *)&(y))[x])
68
69 #define cached_21 (__byte(0,cached_irq_mask))
70 #define cached_A1 (__byte(1,cached_irq_mask))
71
72 unsigned long spurious_count = 0;
73
74 /*
75 * (un)mask_irq, disable_irq() and enable_irq() only handle (E)ISA and
76 * PCI devices. Other onboard hardware needs specific routines.
77 */
78 static inline void mask_irq(unsigned int irq)
79 {
80 cached_irq_mask |= 1 << irq;
81 if (irq & 8) {
82 outb(cached_A1, 0xa1);
83 } else {
84 outb(cached_21, 0x21);
85 }
86 }
87
88 static inline void unmask_irq(unsigned int irq)
89 {
90 cached_irq_mask &= ~(1 << irq);
91 if (irq & 8) {
92 outb(cached_A1, 0xa1);
93 } else {
94 outb(cached_21, 0x21);
95 }
96 }
97
98 void i8259_disable_irq(unsigned int irq_nr)
99 {
100 unsigned long flags;
101
102 save_and_cli(flags);
103 mask_irq(irq_nr);
104 restore_flags(flags);
105 }
106
107 void i8259_enable_irq(unsigned int irq_nr)
108 {
109 unsigned long flags;
110 save_and_cli(flags);
111 unmask_irq(irq_nr);
112 restore_flags(flags);
113 }
114
115 static struct irqaction *irq_action[NR_IRQS] = {
116 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
117 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
118 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
119 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
120 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
121 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
122 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
123 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
124 };
125
126 int get_irq_list(char *buf)
127 {
128 int i, len = 0;
129 struct irqaction * action;
130
131 for (i = 0 ; i < 32 ; i++) {
132 action = irq_action[i];
133 if (!action)
134 continue;
135 len += sprintf(buf+len, "%2d: %8d %c %s",
136 i, kstat.irqs[0][i],
137 (action->flags & SA_INTERRUPT) ? '+' : ' ',
138 action->name);
139 for (action=action->next; action; action = action->next) {
140 len += sprintf(buf+len, ",%s %s",
141 (action->flags & SA_INTERRUPT) ? " +" : "",
142 action->name);
143 }
144 len += sprintf(buf+len, "\n");
145 }
146 return len;
147 }
148
149 static inline void i8259_mask_and_ack_irq(int irq)
150 {
151 cached_irq_mask |= 1 << irq;
152
153 if (irq & 8) {
154 inb(0xa1);
155 outb(cached_A1, 0xa1);
156 outb(0x62, 0x20); /* Specific EOI to cascade */
157 outb(0x20, 0xa0);
158 } else {
159 inb(0x21);
160 outb(cached_21, 0x21);
161 outb(0x20, 0x20);
162 }
163 }
164
165 asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs)
166 {
167 struct irqaction *action;
168 int do_random, cpu;
169
170 cpu = smp_processor_id();
171 irq_enter(cpu, irq);
172
173 if (irq >= 16)
174 goto out;
175
176 i8259_mask_and_ack_irq(irq);
177
178 kstat.irqs[cpu][irq]++;
179
180 action = *(irq + irq_action);
181 if (!action)
182 goto out;
183
184 if (!(action->flags & SA_INTERRUPT))
185 __sti();
186 action = *(irq + irq_action);
187 do_random = 0;
188 do {
189 do_random |= action->flags;
190 action->handler(irq, action->dev_id, regs);
191 action = action->next;
192 } while (action);
193 if (do_random & SA_SAMPLE_RANDOM)
194 add_interrupt_randomness(irq);
195 __cli();
196 unmask_irq (irq);
197
198 out:
199 irq_exit(cpu, irq);
200 }
201
202 /*
203 * do_IRQ handles IRQ's that have been installed without the
204 * SA_INTERRUPT flag: it uses the full signal-handling return
205 * and runs with other interrupts enabled. All relatively slow
206 * IRQ's should use this format: notably the keyboard/timer
207 * routines.
208 */
209 asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
210 {
211 struct irqaction *action;
212 int do_random, cpu;
213
214 cpu = smp_processor_id();
215 irq_enter(cpu, irq);
216 kstat.irqs[cpu][irq]++;
217
218 action = *(irq + irq_action);
219 if (action) {
220 if (!(action->flags & SA_INTERRUPT))
221 __sti();
222 action = *(irq + irq_action);
223 do_random = 0;
224 do {
225 do_random |= action->flags;
226 action->handler(irq, action->dev_id, regs);
227 action = action->next;
228 } while (action);
229 if (do_random & SA_SAMPLE_RANDOM)
230 add_interrupt_randomness(irq);
231 __cli();
232 }
233 irq_exit(cpu, irq);
234
235 if (softirq_pending(cpu))
236 do_softirq();
237
238 /* unmasking and bottom half handling is done magically for us. */
239 }
240
241 int i8259_setup_irq(int irq, struct irqaction * new)
242 {
243 int shared = 0;
244 struct irqaction *old, **p;
245 unsigned long flags;
246
247 p = irq_action + irq;
248 if ((old = *p) != NULL) {
249 /* Can't share interrupts unless both agree to */
250 if (!(old->flags & new->flags & SA_SHIRQ))
251 return -EBUSY;
252
253 /* Can't share interrupts unless both are same type */
254 if ((old->flags ^ new->flags) & SA_INTERRUPT)
255 return -EBUSY;
256
257 /* add new interrupt at end of irq queue */
258 do {
259 p = &old->next;
260 old = *p;
261 } while (old);
262 shared = 1;
263 }
264
265 if (new->flags & SA_SAMPLE_RANDOM)
266 rand_initialize_irq(irq);
267
268 save_and_cli(flags);
269 *p = new;
270
271 if (!shared) {
272 if (is_i8259_irq(irq))
273 unmask_irq(irq);
274 #if (defined(CONFIG_DDB5074) || defined(CONFIG_DDB5476))
275 else
276 nile4_enable_irq(irq_to_nile4(irq));
277 #endif
278 }
279 restore_flags(flags);
280 return 0;
281 }
282
283 /*
284 * Request_interrupt and free_interrupt ``sort of'' handle interrupts of
285 * non i8259 devices. They will have to be replaced by architecture
286 * specific variants. For now we still use this as broken as it is because
287 * it used to work ...
288 */
289 int request_irq(unsigned int irq,
290 void (*handler)(int, void *, struct pt_regs *),
291 unsigned long irqflags, const char * devname, void *dev_id)
292 {
293 int retval;
294 struct irqaction * action;
295
296 if (irq >= 32)
297 return -EINVAL;
298 if (!handler)
299 return -EINVAL;
300
301 action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
302 if (!action)
303 return -ENOMEM;
304
305 action->handler = handler;
306 action->flags = irqflags;
307 action->mask = 0;
308 action->name = devname;
309 action->next = NULL;
310 action->dev_id = dev_id;
311
312 retval = i8259_setup_irq(irq, action);
313
314 if (retval)
315 kfree(action);
316 return retval;
317 }
318
319 void free_irq(unsigned int irq, void *dev_id)
320 {
321 struct irqaction * action, **p;
322 unsigned long flags;
323
324 if (irq > 31) {
325 printk("Trying to free IRQ%d\n",irq);
326 return;
327 }
328 for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
329 if (action->dev_id != dev_id)
330 continue;
331
332 /* Found it - now free it */
333 save_and_cli(flags);
334 *p = action->next;
335 if (!irq[irq_action])
336 mask_irq(irq);
337 restore_flags(flags);
338 kfree(action);
339 return;
340 }
341 printk("Trying to free free IRQ%d\n",irq);
342 }
343
344 unsigned long probe_irq_on (void)
345 {
346 unsigned int i, irqs = 0;
347 unsigned long delay;
348
349 /* first, enable any unassigned (E)ISA irqs */
350 for (i = 15; i > 0; i--) {
351 if (!irq_action[i]) {
352 i8259_enable_irq(i);
353 irqs |= (1 << i);
354 }
355 }
356
357 /* wait for spurious interrupts to mask themselves out again */
358 for (delay = jiffies + HZ/10; time_before(jiffies, delay); )
359 /* about 100ms delay */;
360
361 /* now filter out any obviously spurious interrupts */
362 return irqs & ~cached_irq_mask;
363 }
364
365 int probe_irq_off (unsigned long irqs)
366 {
367 unsigned int i;
368
369 #ifdef DEBUG
370 printk("probe_irq_off: irqs=0x%04x irqmask=0x%04x\n", irqs, irqmask);
371 #endif
372 irqs &= cached_irq_mask;
373 if (!irqs)
374 return 0;
375 i = ffz(~irqs);
376 if (irqs != (irqs & (1 << i)))
377 i = -i;
378 return i;
379 }
380
381 void __init i8259_init(void)
382 {
383 /* Init master interrupt controller */
384 outb(0x11, 0x20); /* Start init sequence */
385 outb(0x00, 0x21); /* Vector base */
386 outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
387 outb(0x01, 0x21); /* Select 8086 mode */
388 outb(0xff, 0x21); /* Mask all */
389
390 /* Init slave interrupt controller */
391 outb(0x11, 0xa0); /* Start init sequence */
392 outb(0x08, 0xa1); /* Vector base */
393 outb(0x02, 0xa1); /* edge triggered, Cascade (slave) on IRQ2 */
394 outb(0x01, 0xa1); /* Select 8086 mode */
395 outb(0xff, 0xa1); /* Mask all */
396
397 outb(cached_A1, 0xa1);
398 outb(cached_21, 0x21);
399 }
400
401 void __init init_IRQ(void)
402 {
403 /* i8259_init(); */
404 irq_setup();
405 }
406