1 /* $Id: irq.c,v 1.15 1999/02/25 21:50:49 tsbogend Exp $
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
7 * Code to handle x86 style IRQs plus some generic interrupt stuff.
9 * Copyright (C) 1992 Linus Torvalds
10 * Copyright (C) 1994, 1995, 1996, 1997, 1998 Ralf Baechle
12 #include <linux/errno.h>
13 #include <linux/init.h>
14 #include <linux/kernel_stat.h>
15 #include <linux/module.h>
16 #include <linux/signal.h>
17 #include <linux/sched.h>
18 #include <linux/types.h>
19 #include <linux/interrupt.h>
20 #include <linux/ioport.h>
21 #include <linux/timex.h>
22 #include <linux/malloc.h>
23 #include <linux/random.h>
25 #include <asm/bitops.h>
26 #include <asm/bootinfo.h>
29 #include <asm/mipsregs.h>
30 #include <asm/system.h>
34 * This contains the irq mask for both 8259A irq controllers, it's an
35 * int so we can deal with the third PIC in some systems like the RM300.
36 * (XXX This is broken for big endian.)
38 static unsigned int cached_irq_mask
= 0xffff;
40 #define __byte(x,y) (((unsigned char *)&(y))[x])
41 #define __word(x,y) (((unsigned short *)&(y))[x])
42 #define __long(x,y) (((unsigned int *)&(y))[x])
44 #define cached_21 (__byte(0,cached_irq_mask))
45 #define cached_A1 (__byte(1,cached_irq_mask))
47 unsigned int local_bh_count
[NR_CPUS
];
48 unsigned int local_irq_count
[NR_CPUS
];
49 unsigned long spurious_count
= 0;
52 * (un)mask_irq, disable_irq() and enable_irq() only handle (E)ISA and
53 * PCI devices. Other onboard hardware needs specific routines.
55 static inline void mask_irq(unsigned int irq
)
57 cached_irq_mask
|= 1 << irq
;
59 outb(cached_A1
, 0xa1);
61 outb(cached_21
, 0x21);
65 static inline void unmask_irq(unsigned int irq
)
67 cached_irq_mask
&= ~(1 << irq
);
69 outb(cached_A1
, 0xa1);
71 outb(cached_21
, 0x21);
75 void disable_irq(unsigned int irq_nr
)
84 void enable_irq(unsigned int irq_nr
)
92 static struct irqaction
*irq_action
[NR_IRQS
] = {
93 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
94 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
95 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
96 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
97 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
98 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
99 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
100 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
103 int get_irq_list(char *buf
)
106 struct irqaction
* action
;
108 for (i
= 0 ; i
< 32 ; i
++) {
109 action
= irq_action
[i
];
112 len
+= sprintf(buf
+len
, "%2d: %8d %c %s",
114 (action
->flags
& SA_INTERRUPT
) ? '+' : ' ',
116 for (action
=action
->next
; action
; action
= action
->next
) {
117 len
+= sprintf(buf
+len
, ",%s %s",
118 (action
->flags
& SA_INTERRUPT
) ? " +" : "",
121 len
+= sprintf(buf
+len
, "\n");
126 atomic_t __mips_bh_counter
;
128 static inline void i8259_mask_and_ack_irq(int irq
)
130 cached_irq_mask
|= 1 << irq
;
134 outb(cached_A1
, 0xa1);
135 outb(0x62, 0x20); /* Specific EOI to cascade */
139 outb(cached_21
, 0x21);
144 asmlinkage
void i8259_do_irq(int irq
, struct pt_regs
*regs
)
146 struct irqaction
*action
;
149 cpu
= smp_processor_id();
155 i8259_mask_and_ack_irq(irq
);
157 kstat
.irqs
[cpu
][irq
]++;
159 action
= *(irq
+ irq_action
);
163 if (!(action
->flags
& SA_INTERRUPT
))
165 action
= *(irq
+ irq_action
);
168 do_random
|= action
->flags
;
169 action
->handler(irq
, action
->dev_id
, regs
);
170 action
= action
->next
;
172 if (do_random
& SA_SAMPLE_RANDOM
)
173 add_interrupt_randomness(irq
);
182 * do_IRQ handles IRQ's that have been installed without the
183 * SA_INTERRUPT flag: it uses the full signal-handling return
184 * and runs with other interrupts enabled. All relatively slow
185 * IRQ's should use this format: notably the keyboard/timer
188 asmlinkage
void do_IRQ(int irq
, struct pt_regs
* regs
)
190 struct irqaction
*action
;
193 cpu
= smp_processor_id();
195 kstat
.irqs
[cpu
][irq
]++;
197 action
= *(irq
+ irq_action
);
199 if (!(action
->flags
& SA_INTERRUPT
))
201 action
= *(irq
+ irq_action
);
204 do_random
|= action
->flags
;
205 action
->handler(irq
, action
->dev_id
, regs
);
206 action
= action
->next
;
208 if (do_random
& SA_SAMPLE_RANDOM
)
209 add_interrupt_randomness(irq
);
214 /* unmasking and bottom half handling is done magically for us. */
217 int i8259_setup_irq(int irq
, struct irqaction
* new)
220 struct irqaction
*old
, **p
;
223 p
= irq_action
+ irq
;
224 if ((old
= *p
) != NULL
) {
225 /* Can't share interrupts unless both agree to */
226 if (!(old
->flags
& new->flags
& SA_SHIRQ
))
229 /* Can't share interrupts unless both are same type */
230 if ((old
->flags
^ new->flags
) & SA_INTERRUPT
)
233 /* add new interrupt at end of irq queue */
241 if (new->flags
& SA_SAMPLE_RANDOM
)
242 rand_initialize_irq(irq
);
250 restore_flags(flags
);
255 * Request_interrupt and free_interrupt ``sort of'' handle interrupts of
256 * non i8259 devices. They will have to be replaced by architecture
257 * specific variants. For now we still use this as broken as it is because
258 * it used to work ...
260 int request_irq(unsigned int irq
,
261 void (*handler
)(int, void *, struct pt_regs
*),
262 unsigned long irqflags
, const char * devname
, void *dev_id
)
265 struct irqaction
* action
;
272 action
= (struct irqaction
*)kmalloc(sizeof(struct irqaction
), GFP_KERNEL
);
276 action
->handler
= handler
;
277 action
->flags
= irqflags
;
279 action
->name
= devname
;
281 action
->dev_id
= dev_id
;
283 retval
= i8259_setup_irq(irq
, action
);
290 void free_irq(unsigned int irq
, void *dev_id
)
292 struct irqaction
* action
, **p
;
296 printk("Trying to free IRQ%d\n",irq
);
299 for (p
= irq
+ irq_action
; (action
= *p
) != NULL
; p
= &action
->next
) {
300 if (action
->dev_id
!= dev_id
)
303 /* Found it - now free it */
306 if (!irq
[irq_action
])
308 restore_flags(flags
);
312 printk("Trying to free free IRQ%d\n",irq
);
315 unsigned long probe_irq_on (void)
317 unsigned int i
, irqs
= 0;
320 /* first, enable any unassigned (E)ISA irqs */
321 for (i
= 15; i
> 0; i
--) {
322 if (!irq_action
[i
]) {
328 /* wait for spurious interrupts to mask themselves out again */
329 for (delay
= jiffies
+ HZ
/10; time_before(jiffies
, delay
); )
330 /* about 100ms delay */;
332 /* now filter out any obviously spurious interrupts */
333 return irqs
& ~cached_irq_mask
;
336 int probe_irq_off (unsigned long irqs
)
341 printk("probe_irq_off: irqs=0x%04x irqmask=0x%04x\n", irqs
, irqmask
);
343 irqs
&= cached_irq_mask
;
347 if (irqs
!= (irqs
& (1 << i
)))
352 int (*irq_cannonicalize
)(int irq
);
354 static int i8259_irq_cannonicalize(int irq
)
356 return ((irq
== 2) ? 9 : irq
);
359 __initfunc(static void i8259_init(void))
361 /* Init master interrupt controller */
362 outb(0x11, 0x20); /* Start init sequence */
363 outb(0x00, 0x21); /* Vector base */
364 outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
365 outb(0x01, 0x21); /* Select 8086 mode */
366 outb(0xff, 0x21); /* Mask all */
368 /* Init slave interrupt controller */
369 outb(0x11, 0xa0); /* Start init sequence */
370 outb(0x08, 0xa1); /* Vector base */
371 outb(0x02, 0xa1); /* edge triggered, Cascade (slave) on IRQ2 */
372 outb(0x01, 0xa1); /* Select 8086 mode */
373 outb(0xff, 0xa1); /* Mask all */
375 outb(cached_A1
, 0xa1);
376 outb(cached_21
, 0x21);
379 __initfunc(void init_IRQ(void))
381 irq_cannonicalize
= i8259_irq_cannonicalize
;
386 EXPORT_SYMBOL(irq_cannonicalize
);