diff options
Diffstat (limited to 'arch/mips/include/asm/i8259.h')
-rw-r--r-- | arch/mips/include/asm/i8259.h | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/arch/mips/include/asm/i8259.h b/arch/mips/include/asm/i8259.h new file mode 100644 index 000000000000..8572a2d90484 --- /dev/null +++ b/arch/mips/include/asm/i8259.h | |||
@@ -0,0 +1,86 @@ | |||
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 | #include <irq.h> | ||
22 | |||
23 | /* i8259A PIC registers */ | ||
24 | #define PIC_MASTER_CMD 0x20 | ||
25 | #define PIC_MASTER_IMR 0x21 | ||
26 | #define PIC_MASTER_ISR PIC_MASTER_CMD | ||
27 | #define PIC_MASTER_POLL PIC_MASTER_ISR | ||
28 | #define PIC_MASTER_OCW3 PIC_MASTER_ISR | ||
29 | #define PIC_SLAVE_CMD 0xa0 | ||
30 | #define PIC_SLAVE_IMR 0xa1 | ||
31 | |||
32 | /* i8259A PIC related value */ | ||
33 | #define PIC_CASCADE_IR 2 | ||
34 | #define MASTER_ICW4_DEFAULT 0x01 | ||
35 | #define SLAVE_ICW4_DEFAULT 0x01 | ||
36 | #define PIC_ICW4_AEOI 2 | ||
37 | |||
38 | extern spinlock_t i8259A_lock; | ||
39 | |||
40 | extern int i8259A_irq_pending(unsigned int irq); | ||
41 | extern void make_8259A_irq(unsigned int irq); | ||
42 | |||
43 | extern void init_i8259_irqs(void); | ||
44 | |||
45 | /* | ||
46 | * Do the traditional i8259 interrupt polling thing. This is for the few | ||
47 | * cases where no better interrupt acknowledge method is available and we | ||
48 | * absolutely must touch the i8259. | ||
49 | */ | ||
50 | static inline int i8259_irq(void) | ||
51 | { | ||
52 | int irq; | ||
53 | |||
54 | spin_lock(&i8259A_lock); | ||
55 | |||
56 | /* Perform an interrupt acknowledge cycle on controller 1. */ | ||
57 | outb(0x0C, PIC_MASTER_CMD); /* prepare for poll */ | ||
58 | irq = inb(PIC_MASTER_CMD) & 7; | ||
59 | if (irq == PIC_CASCADE_IR) { | ||
60 | /* | ||
61 | * Interrupt is cascaded so perform interrupt | ||
62 | * acknowledge on controller 2. | ||
63 | */ | ||
64 | outb(0x0C, PIC_SLAVE_CMD); /* prepare for poll */ | ||
65 | irq = (inb(PIC_SLAVE_CMD) & 7) + 8; | ||
66 | } | ||
67 | |||
68 | if (unlikely(irq == 7)) { | ||
69 | /* | ||
70 | * This may be a spurious interrupt. | ||
71 | * | ||
72 | * Read the interrupt status register (ISR). If the most | ||
73 | * significant bit is not set then there is no valid | ||
74 | * interrupt. | ||
75 | */ | ||
76 | outb(0x0B, PIC_MASTER_ISR); /* ISR register */ | ||
77 | if(~inb(PIC_MASTER_ISR) & 0x80) | ||
78 | irq = -1; | ||
79 | } | ||
80 | |||
81 | spin_unlock(&i8259A_lock); | ||
82 | |||
83 | return likely(irq >= 0) ? irq + I8259A_IRQ_BASE : irq; | ||
84 | } | ||
85 | |||
86 | #endif /* _ASM_I8259_H */ | ||