Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
[linux-2.6] / include / asm-mips / i8259.h
1 /*
2  *      include/asm-mips/i8259.h
3  *
4  *      i8259A interrupt definitions.
5  *
6  *      Copyright (C) 2003  Maciej W. Rozycki
7  *      Copyright (C) 2003  Ralf Baechle <ralf@linux-mips.org>
8  *
9  *      This program is free software; you can redistribute it and/or
10  *      modify it under the terms of the GNU General Public License
11  *      as published by the Free Software Foundation; either version
12  *      2 of the License, or (at your option) any later version.
13  */
14 #ifndef _ASM_I8259_H
15 #define _ASM_I8259_H
16
17 #include <linux/compiler.h>
18 #include <linux/spinlock.h>
19
20 #include <asm/io.h>
21
22 extern spinlock_t i8259A_lock;
23
24 extern void init_i8259_irqs(void);
25
26 /*
27  * Do the traditional i8259 interrupt polling thing.  This is for the few
28  * cases where no better interrupt acknowledge method is available and we
29  * absolutely must touch the i8259.
30  */
31 static inline int i8259_irq(void)
32 {
33         int irq;
34
35         spin_lock(&i8259A_lock);
36
37         /* Perform an interrupt acknowledge cycle on controller 1. */
38         outb(0x0C, 0x20);               /* prepare for poll */
39         irq = inb(0x20) & 7;
40         if (irq == 2) {
41                 /*
42                  * Interrupt is cascaded so perform interrupt
43                  * acknowledge on controller 2.
44                  */
45                 outb(0x0C, 0xA0);               /* prepare for poll */
46                 irq = (inb(0xA0) & 7) + 8;
47         }
48
49         if (unlikely(irq == 7)) {
50                 /*
51                  * This may be a spurious interrupt.
52                  *
53                  * Read the interrupt status register (ISR). If the most
54                  * significant bit is not set then there is no valid
55                  * interrupt.
56                  */
57                 outb(0x0B, 0x20);               /* ISR register */
58                 if(~inb(0x20) & 0x80)
59                         irq = -1;
60         }
61
62         spin_unlock(&i8259A_lock);
63
64         return irq;
65 }
66
67 #endif /* _ASM_I8259_H */