diff options
Diffstat (limited to 'arch/mips/sgi-ip32/ip32-irq.c')
-rw-r--r-- | arch/mips/sgi-ip32/ip32-irq.c | 134 |
1 files changed, 42 insertions, 92 deletions
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index eb40824b172a..e0a3ce4a8d48 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c | |||
@@ -130,70 +130,48 @@ static struct irqaction cpuerr_irq = { | |||
130 | 130 | ||
131 | static uint64_t crime_mask; | 131 | static uint64_t crime_mask; |
132 | 132 | ||
133 | static inline void crime_enable_irq(unsigned int irq) | 133 | static inline void crime_enable_irq(struct irq_data *d) |
134 | { | 134 | { |
135 | unsigned int bit = irq - CRIME_IRQ_BASE; | 135 | unsigned int bit = d->irq - CRIME_IRQ_BASE; |
136 | 136 | ||
137 | crime_mask |= 1 << bit; | 137 | crime_mask |= 1 << bit; |
138 | crime->imask = crime_mask; | 138 | crime->imask = crime_mask; |
139 | } | 139 | } |
140 | 140 | ||
141 | static inline void crime_disable_irq(unsigned int irq) | 141 | static inline void crime_disable_irq(struct irq_data *d) |
142 | { | 142 | { |
143 | unsigned int bit = irq - CRIME_IRQ_BASE; | 143 | unsigned int bit = d->irq - CRIME_IRQ_BASE; |
144 | 144 | ||
145 | crime_mask &= ~(1 << bit); | 145 | crime_mask &= ~(1 << bit); |
146 | crime->imask = crime_mask; | 146 | crime->imask = crime_mask; |
147 | flush_crime_bus(); | 147 | flush_crime_bus(); |
148 | } | 148 | } |
149 | 149 | ||
150 | static void crime_level_mask_and_ack_irq(unsigned int irq) | ||
151 | { | ||
152 | crime_disable_irq(irq); | ||
153 | } | ||
154 | |||
155 | static void crime_level_end_irq(unsigned int irq) | ||
156 | { | ||
157 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | ||
158 | crime_enable_irq(irq); | ||
159 | } | ||
160 | |||
161 | static struct irq_chip crime_level_interrupt = { | 150 | static struct irq_chip crime_level_interrupt = { |
162 | .name = "IP32 CRIME", | 151 | .name = "IP32 CRIME", |
163 | .ack = crime_level_mask_and_ack_irq, | 152 | .irq_mask = crime_disable_irq, |
164 | .mask = crime_disable_irq, | 153 | .irq_unmask = crime_enable_irq, |
165 | .mask_ack = crime_level_mask_and_ack_irq, | ||
166 | .unmask = crime_enable_irq, | ||
167 | .end = crime_level_end_irq, | ||
168 | }; | 154 | }; |
169 | 155 | ||
170 | static void crime_edge_mask_and_ack_irq(unsigned int irq) | 156 | static void crime_edge_mask_and_ack_irq(struct irq_data *d) |
171 | { | 157 | { |
172 | unsigned int bit = irq - CRIME_IRQ_BASE; | 158 | unsigned int bit = d->irq - CRIME_IRQ_BASE; |
173 | uint64_t crime_int; | 159 | uint64_t crime_int; |
174 | 160 | ||
175 | /* Edge triggered interrupts must be cleared. */ | 161 | /* Edge triggered interrupts must be cleared. */ |
176 | |||
177 | crime_int = crime->hard_int; | 162 | crime_int = crime->hard_int; |
178 | crime_int &= ~(1 << bit); | 163 | crime_int &= ~(1 << bit); |
179 | crime->hard_int = crime_int; | 164 | crime->hard_int = crime_int; |
180 | 165 | ||
181 | crime_disable_irq(irq); | 166 | crime_disable_irq(d); |
182 | } | ||
183 | |||
184 | static void crime_edge_end_irq(unsigned int irq) | ||
185 | { | ||
186 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | ||
187 | crime_enable_irq(irq); | ||
188 | } | 167 | } |
189 | 168 | ||
190 | static struct irq_chip crime_edge_interrupt = { | 169 | static struct irq_chip crime_edge_interrupt = { |
191 | .name = "IP32 CRIME", | 170 | .name = "IP32 CRIME", |
192 | .ack = crime_edge_mask_and_ack_irq, | 171 | .irq_ack = crime_edge_mask_and_ack_irq, |
193 | .mask = crime_disable_irq, | 172 | .irq_mask = crime_disable_irq, |
194 | .mask_ack = crime_edge_mask_and_ack_irq, | 173 | .irq_mask_ack = crime_edge_mask_and_ack_irq, |
195 | .unmask = crime_enable_irq, | 174 | .irq_unmask = crime_enable_irq, |
196 | .end = crime_edge_end_irq, | ||
197 | }; | 175 | }; |
198 | 176 | ||
199 | /* | 177 | /* |
@@ -204,37 +182,28 @@ static struct irq_chip crime_edge_interrupt = { | |||
204 | 182 | ||
205 | static unsigned long macepci_mask; | 183 | static unsigned long macepci_mask; |
206 | 184 | ||
207 | static void enable_macepci_irq(unsigned int irq) | 185 | static void enable_macepci_irq(struct irq_data *d) |
208 | { | 186 | { |
209 | macepci_mask |= MACEPCI_CONTROL_INT(irq - MACEPCI_SCSI0_IRQ); | 187 | macepci_mask |= MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ); |
210 | mace->pci.control = macepci_mask; | 188 | mace->pci.control = macepci_mask; |
211 | crime_mask |= 1 << (irq - CRIME_IRQ_BASE); | 189 | crime_mask |= 1 << (d->irq - CRIME_IRQ_BASE); |
212 | crime->imask = crime_mask; | 190 | crime->imask = crime_mask; |
213 | } | 191 | } |
214 | 192 | ||
215 | static void disable_macepci_irq(unsigned int irq) | 193 | static void disable_macepci_irq(struct irq_data *d) |
216 | { | 194 | { |
217 | crime_mask &= ~(1 << (irq - CRIME_IRQ_BASE)); | 195 | crime_mask &= ~(1 << (d->irq - CRIME_IRQ_BASE)); |
218 | crime->imask = crime_mask; | 196 | crime->imask = crime_mask; |
219 | flush_crime_bus(); | 197 | flush_crime_bus(); |
220 | macepci_mask &= ~MACEPCI_CONTROL_INT(irq - MACEPCI_SCSI0_IRQ); | 198 | macepci_mask &= ~MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ); |
221 | mace->pci.control = macepci_mask; | 199 | mace->pci.control = macepci_mask; |
222 | flush_mace_bus(); | 200 | flush_mace_bus(); |
223 | } | 201 | } |
224 | 202 | ||
225 | static void end_macepci_irq(unsigned int irq) | ||
226 | { | ||
227 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
228 | enable_macepci_irq(irq); | ||
229 | } | ||
230 | |||
231 | static struct irq_chip ip32_macepci_interrupt = { | 203 | static struct irq_chip ip32_macepci_interrupt = { |
232 | .name = "IP32 MACE PCI", | 204 | .name = "IP32 MACE PCI", |
233 | .ack = disable_macepci_irq, | 205 | .irq_mask = disable_macepci_irq, |
234 | .mask = disable_macepci_irq, | 206 | .irq_unmask = enable_macepci_irq, |
235 | .mask_ack = disable_macepci_irq, | ||
236 | .unmask = enable_macepci_irq, | ||
237 | .end = end_macepci_irq, | ||
238 | }; | 207 | }; |
239 | 208 | ||
240 | /* This is used for MACE ISA interrupts. That means bits 4-6 in the | 209 | /* This is used for MACE ISA interrupts. That means bits 4-6 in the |
@@ -276,13 +245,13 @@ static struct irq_chip ip32_macepci_interrupt = { | |||
276 | 245 | ||
277 | static unsigned long maceisa_mask; | 246 | static unsigned long maceisa_mask; |
278 | 247 | ||
279 | static void enable_maceisa_irq(unsigned int irq) | 248 | static void enable_maceisa_irq(struct irq_data *d) |
280 | { | 249 | { |
281 | unsigned int crime_int = 0; | 250 | unsigned int crime_int = 0; |
282 | 251 | ||
283 | pr_debug("maceisa enable: %u\n", irq); | 252 | pr_debug("maceisa enable: %u\n", d->irq); |
284 | 253 | ||
285 | switch (irq) { | 254 | switch (d->irq) { |
286 | case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ: | 255 | case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ: |
287 | crime_int = MACE_AUDIO_INT; | 256 | crime_int = MACE_AUDIO_INT; |
288 | break; | 257 | break; |
@@ -296,15 +265,15 @@ static void enable_maceisa_irq(unsigned int irq) | |||
296 | pr_debug("crime_int %08x enabled\n", crime_int); | 265 | pr_debug("crime_int %08x enabled\n", crime_int); |
297 | crime_mask |= crime_int; | 266 | crime_mask |= crime_int; |
298 | crime->imask = crime_mask; | 267 | crime->imask = crime_mask; |
299 | maceisa_mask |= 1 << (irq - MACEISA_AUDIO_SW_IRQ); | 268 | maceisa_mask |= 1 << (d->irq - MACEISA_AUDIO_SW_IRQ); |
300 | mace->perif.ctrl.imask = maceisa_mask; | 269 | mace->perif.ctrl.imask = maceisa_mask; |
301 | } | 270 | } |
302 | 271 | ||
303 | static void disable_maceisa_irq(unsigned int irq) | 272 | static void disable_maceisa_irq(struct irq_data *d) |
304 | { | 273 | { |
305 | unsigned int crime_int = 0; | 274 | unsigned int crime_int = 0; |
306 | 275 | ||
307 | maceisa_mask &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ)); | 276 | maceisa_mask &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ)); |
308 | if (!(maceisa_mask & MACEISA_AUDIO_INT)) | 277 | if (!(maceisa_mask & MACEISA_AUDIO_INT)) |
309 | crime_int |= MACE_AUDIO_INT; | 278 | crime_int |= MACE_AUDIO_INT; |
310 | if (!(maceisa_mask & MACEISA_MISC_INT)) | 279 | if (!(maceisa_mask & MACEISA_MISC_INT)) |
@@ -318,76 +287,57 @@ static void disable_maceisa_irq(unsigned int irq) | |||
318 | flush_mace_bus(); | 287 | flush_mace_bus(); |
319 | } | 288 | } |
320 | 289 | ||
321 | static void mask_and_ack_maceisa_irq(unsigned int irq) | 290 | static void mask_and_ack_maceisa_irq(struct irq_data *d) |
322 | { | 291 | { |
323 | unsigned long mace_int; | 292 | unsigned long mace_int; |
324 | 293 | ||
325 | /* edge triggered */ | 294 | /* edge triggered */ |
326 | mace_int = mace->perif.ctrl.istat; | 295 | mace_int = mace->perif.ctrl.istat; |
327 | mace_int &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ)); | 296 | mace_int &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ)); |
328 | mace->perif.ctrl.istat = mace_int; | 297 | mace->perif.ctrl.istat = mace_int; |
329 | 298 | ||
330 | disable_maceisa_irq(irq); | 299 | disable_maceisa_irq(d); |
331 | } | ||
332 | |||
333 | static void end_maceisa_irq(unsigned irq) | ||
334 | { | ||
335 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | ||
336 | enable_maceisa_irq(irq); | ||
337 | } | 300 | } |
338 | 301 | ||
339 | static struct irq_chip ip32_maceisa_level_interrupt = { | 302 | static struct irq_chip ip32_maceisa_level_interrupt = { |
340 | .name = "IP32 MACE ISA", | 303 | .name = "IP32 MACE ISA", |
341 | .ack = disable_maceisa_irq, | 304 | .irq_mask = disable_maceisa_irq, |
342 | .mask = disable_maceisa_irq, | 305 | .irq_unmask = enable_maceisa_irq, |
343 | .mask_ack = disable_maceisa_irq, | ||
344 | .unmask = enable_maceisa_irq, | ||
345 | .end = end_maceisa_irq, | ||
346 | }; | 306 | }; |
347 | 307 | ||
348 | static struct irq_chip ip32_maceisa_edge_interrupt = { | 308 | static struct irq_chip ip32_maceisa_edge_interrupt = { |
349 | .name = "IP32 MACE ISA", | 309 | .name = "IP32 MACE ISA", |
350 | .ack = mask_and_ack_maceisa_irq, | 310 | .irq_ack = mask_and_ack_maceisa_irq, |
351 | .mask = disable_maceisa_irq, | 311 | .irq_mask = disable_maceisa_irq, |
352 | .mask_ack = mask_and_ack_maceisa_irq, | 312 | .irq_mask_ack = mask_and_ack_maceisa_irq, |
353 | .unmask = enable_maceisa_irq, | 313 | .irq_unmask = enable_maceisa_irq, |
354 | .end = end_maceisa_irq, | ||
355 | }; | 314 | }; |
356 | 315 | ||
357 | /* This is used for regular non-ISA, non-PCI MACE interrupts. That means | 316 | /* This is used for regular non-ISA, non-PCI MACE interrupts. That means |
358 | * bits 0-3 and 7 in the CRIME register. | 317 | * bits 0-3 and 7 in the CRIME register. |
359 | */ | 318 | */ |
360 | 319 | ||
361 | static void enable_mace_irq(unsigned int irq) | 320 | static void enable_mace_irq(struct irq_data *d) |
362 | { | 321 | { |
363 | unsigned int bit = irq - CRIME_IRQ_BASE; | 322 | unsigned int bit = d->irq - CRIME_IRQ_BASE; |
364 | 323 | ||
365 | crime_mask |= (1 << bit); | 324 | crime_mask |= (1 << bit); |
366 | crime->imask = crime_mask; | 325 | crime->imask = crime_mask; |
367 | } | 326 | } |
368 | 327 | ||
369 | static void disable_mace_irq(unsigned int irq) | 328 | static void disable_mace_irq(struct irq_data *d) |
370 | { | 329 | { |
371 | unsigned int bit = irq - CRIME_IRQ_BASE; | 330 | unsigned int bit = d->irq - CRIME_IRQ_BASE; |
372 | 331 | ||
373 | crime_mask &= ~(1 << bit); | 332 | crime_mask &= ~(1 << bit); |
374 | crime->imask = crime_mask; | 333 | crime->imask = crime_mask; |
375 | flush_crime_bus(); | 334 | flush_crime_bus(); |
376 | } | 335 | } |
377 | 336 | ||
378 | static void end_mace_irq(unsigned int irq) | ||
379 | { | ||
380 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
381 | enable_mace_irq(irq); | ||
382 | } | ||
383 | |||
384 | static struct irq_chip ip32_mace_interrupt = { | 337 | static struct irq_chip ip32_mace_interrupt = { |
385 | .name = "IP32 MACE", | 338 | .name = "IP32 MACE", |
386 | .ack = disable_mace_irq, | 339 | .irq_mask = disable_mace_irq, |
387 | .mask = disable_mace_irq, | 340 | .irq_unmask = enable_mace_irq, |
388 | .mask_ack = disable_mace_irq, | ||
389 | .unmask = enable_mace_irq, | ||
390 | .end = end_mace_irq, | ||
391 | }; | 341 | }; |
392 | 342 | ||
393 | static void ip32_unknown_interrupt(void) | 343 | static void ip32_unknown_interrupt(void) |