diff options
author | Thomas Bogendoerfer <tsbogend@alpha.franken.de> | 2007-11-23 14:34:16 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2007-11-26 12:26:14 -0500 |
commit | 68de4803726224a7cfe09c8052f0ce5e532c6847 (patch) | |
tree | 2f6a9595768f75d417c30d1966012845d477f1ad /arch/mips | |
parent | cce335ae47e231398269fb05fa48e0e9cbf289e0 (diff) |
[MIPS] IP22: Fix broken EISA interrupt setup by switching to generic i8259
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/Kconfig | 1 | ||||
-rw-r--r-- | arch/mips/sgi-ip22/ip22-eisa.c | 134 |
2 files changed, 3 insertions, 132 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 4c6ba7b30a68..455bd1f560aa 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -401,6 +401,7 @@ config SGI_IP22 | |||
401 | select DMA_NONCOHERENT | 401 | select DMA_NONCOHERENT |
402 | select HW_HAS_EISA | 402 | select HW_HAS_EISA |
403 | select I8253 | 403 | select I8253 |
404 | select I8259 | ||
404 | select IP22_CPU_SCACHE | 405 | select IP22_CPU_SCACHE |
405 | select IRQ_CPU | 406 | select IRQ_CPU |
406 | select GENERIC_ISA_DMA_SUPPORT_BROKEN | 407 | select GENERIC_ISA_DMA_SUPPORT_BROKEN |
diff --git a/arch/mips/sgi-ip22/ip22-eisa.c b/arch/mips/sgi-ip22/ip22-eisa.c index 26854fb11e7c..1617241d2737 100644 --- a/arch/mips/sgi-ip22/ip22-eisa.c +++ b/arch/mips/sgi-ip22/ip22-eisa.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <asm/sgi/ioc.h> | 36 | #include <asm/sgi/ioc.h> |
37 | #include <asm/sgi/mc.h> | 37 | #include <asm/sgi/mc.h> |
38 | #include <asm/sgi/ip22.h> | 38 | #include <asm/sgi/ip22.h> |
39 | #include <asm/i8259.h> | ||
39 | 40 | ||
40 | /* I2 has four EISA slots. */ | 41 | /* I2 has four EISA slots. */ |
41 | #define IP22_EISA_MAX_SLOTS 4 | 42 | #define IP22_EISA_MAX_SLOTS 4 |
@@ -93,126 +94,11 @@ static irqreturn_t ip22_eisa_intr(int irq, void *dev_id) | |||
93 | return IRQ_NONE; | 94 | return IRQ_NONE; |
94 | } | 95 | } |
95 | 96 | ||
96 | static void enable_eisa1_irq(unsigned int irq) | ||
97 | { | ||
98 | u8 mask; | ||
99 | |||
100 | mask = inb(EISA_INT1_MASK); | ||
101 | mask &= ~((u8) (1 << irq)); | ||
102 | outb(mask, EISA_INT1_MASK); | ||
103 | } | ||
104 | |||
105 | static unsigned int startup_eisa1_irq(unsigned int irq) | ||
106 | { | ||
107 | u8 edge; | ||
108 | |||
109 | /* Only use edge interrupts for EISA */ | ||
110 | |||
111 | edge = inb(EISA_INT1_EDGE_LEVEL); | ||
112 | edge &= ~((u8) (1 << irq)); | ||
113 | outb(edge, EISA_INT1_EDGE_LEVEL); | ||
114 | |||
115 | enable_eisa1_irq(irq); | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static void disable_eisa1_irq(unsigned int irq) | ||
120 | { | ||
121 | u8 mask; | ||
122 | |||
123 | mask = inb(EISA_INT1_MASK); | ||
124 | mask |= ((u8) (1 << irq)); | ||
125 | outb(mask, EISA_INT1_MASK); | ||
126 | } | ||
127 | |||
128 | static void mask_and_ack_eisa1_irq(unsigned int irq) | ||
129 | { | ||
130 | disable_eisa1_irq(irq); | ||
131 | |||
132 | outb(0x20, EISA_INT1_CTRL); | ||
133 | } | ||
134 | |||
135 | static void end_eisa1_irq(unsigned int irq) | ||
136 | { | ||
137 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | ||
138 | enable_eisa1_irq(irq); | ||
139 | } | ||
140 | |||
141 | static struct irq_chip ip22_eisa1_irq_type = { | ||
142 | .name = "IP22 EISA", | ||
143 | .startup = startup_eisa1_irq, | ||
144 | .ack = mask_and_ack_eisa1_irq, | ||
145 | .mask = disable_eisa1_irq, | ||
146 | .mask_ack = mask_and_ack_eisa1_irq, | ||
147 | .unmask = enable_eisa1_irq, | ||
148 | .end = end_eisa1_irq, | ||
149 | }; | ||
150 | |||
151 | static void enable_eisa2_irq(unsigned int irq) | ||
152 | { | ||
153 | u8 mask; | ||
154 | |||
155 | mask = inb(EISA_INT2_MASK); | ||
156 | mask &= ~((u8) (1 << (irq - 8))); | ||
157 | outb(mask, EISA_INT2_MASK); | ||
158 | } | ||
159 | |||
160 | static unsigned int startup_eisa2_irq(unsigned int irq) | ||
161 | { | ||
162 | u8 edge; | ||
163 | |||
164 | /* Only use edge interrupts for EISA */ | ||
165 | |||
166 | edge = inb(EISA_INT2_EDGE_LEVEL); | ||
167 | edge &= ~((u8) (1 << (irq - 8))); | ||
168 | outb(edge, EISA_INT2_EDGE_LEVEL); | ||
169 | |||
170 | enable_eisa2_irq(irq); | ||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | static void disable_eisa2_irq(unsigned int irq) | ||
175 | { | ||
176 | u8 mask; | ||
177 | |||
178 | mask = inb(EISA_INT2_MASK); | ||
179 | mask |= ((u8) (1 << (irq - 8))); | ||
180 | outb(mask, EISA_INT2_MASK); | ||
181 | } | ||
182 | |||
183 | static void mask_and_ack_eisa2_irq(unsigned int irq) | ||
184 | { | ||
185 | disable_eisa2_irq(irq); | ||
186 | |||
187 | outb(0x20, EISA_INT2_CTRL); | ||
188 | } | ||
189 | |||
190 | static void end_eisa2_irq(unsigned int irq) | ||
191 | { | ||
192 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | ||
193 | enable_eisa2_irq(irq); | ||
194 | } | ||
195 | |||
196 | static struct irq_chip ip22_eisa2_irq_type = { | ||
197 | .name = "IP22 EISA", | ||
198 | .startup = startup_eisa2_irq, | ||
199 | .ack = mask_and_ack_eisa2_irq, | ||
200 | .mask = disable_eisa2_irq, | ||
201 | .mask_ack = mask_and_ack_eisa2_irq, | ||
202 | .unmask = enable_eisa2_irq, | ||
203 | .end = end_eisa2_irq, | ||
204 | }; | ||
205 | |||
206 | static struct irqaction eisa_action = { | 97 | static struct irqaction eisa_action = { |
207 | .handler = ip22_eisa_intr, | 98 | .handler = ip22_eisa_intr, |
208 | .name = "EISA", | 99 | .name = "EISA", |
209 | }; | 100 | }; |
210 | 101 | ||
211 | static struct irqaction cascade_action = { | ||
212 | .handler = no_action, | ||
213 | .name = "EISA cascade", | ||
214 | }; | ||
215 | |||
216 | int __init ip22_eisa_init(void) | 102 | int __init ip22_eisa_init(void) |
217 | { | 103 | { |
218 | int i, c; | 104 | int i, c; |
@@ -248,29 +134,13 @@ int __init ip22_eisa_init(void) | |||
248 | outb(1, EISA_EXT_NMI_RESET_CTRL); | 134 | outb(1, EISA_EXT_NMI_RESET_CTRL); |
249 | udelay(50); /* Wait long enough for the dust to settle */ | 135 | udelay(50); /* Wait long enough for the dust to settle */ |
250 | outb(0, EISA_EXT_NMI_RESET_CTRL); | 136 | outb(0, EISA_EXT_NMI_RESET_CTRL); |
251 | outb(0x11, EISA_INT1_CTRL); | ||
252 | outb(0x11, EISA_INT2_CTRL); | ||
253 | outb(0, EISA_INT1_MASK); | ||
254 | outb(8, EISA_INT2_MASK); | ||
255 | outb(4, EISA_INT1_MASK); | ||
256 | outb(2, EISA_INT2_MASK); | ||
257 | outb(1, EISA_INT1_MASK); | ||
258 | outb(1, EISA_INT2_MASK); | ||
259 | outb(0xfb, EISA_INT1_MASK); | ||
260 | outb(0xff, EISA_INT2_MASK); | ||
261 | outb(0, EISA_DMA2_WRITE_SINGLE); | 137 | outb(0, EISA_DMA2_WRITE_SINGLE); |
262 | 138 | ||
263 | for (i = SGINT_EISA; i < (SGINT_EISA + EISA_MAX_IRQ); i++) { | 139 | init_i8259_irqs(); |
264 | if (i < (SGINT_EISA + 8)) | ||
265 | set_irq_chip(i, &ip22_eisa1_irq_type); | ||
266 | else | ||
267 | set_irq_chip(i, &ip22_eisa2_irq_type); | ||
268 | } | ||
269 | 140 | ||
270 | /* Cannot use request_irq because of kmalloc not being ready at such | 141 | /* Cannot use request_irq because of kmalloc not being ready at such |
271 | * an early stage. Yes, I've been bitten... */ | 142 | * an early stage. Yes, I've been bitten... */ |
272 | setup_irq(SGI_EISA_IRQ, &eisa_action); | 143 | setup_irq(SGI_EISA_IRQ, &eisa_action); |
273 | setup_irq(SGINT_EISA + 2, &cascade_action); | ||
274 | 144 | ||
275 | EISA_bus = 1; | 145 | EISA_bus = 1; |
276 | return 0; | 146 | return 0; |