diff options
Diffstat (limited to 'arch/mips/sgi-ip32/ip32-irq.c')
-rw-r--r-- | arch/mips/sgi-ip32/ip32-irq.c | 128 |
1 files changed, 77 insertions, 51 deletions
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index 7e8094f617bf..aab17ddd2f30 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c | |||
@@ -40,13 +40,6 @@ static void inline flush_mace_bus(void) | |||
40 | mace->perif.ctrl.misc; | 40 | mace->perif.ctrl.misc; |
41 | } | 41 | } |
42 | 42 | ||
43 | #undef DEBUG_IRQ | ||
44 | #ifdef DEBUG_IRQ | ||
45 | #define DBG(x...) printk(x) | ||
46 | #else | ||
47 | #define DBG(x...) | ||
48 | #endif | ||
49 | |||
50 | /* | 43 | /* |
51 | * O2 irq map | 44 | * O2 irq map |
52 | * | 45 | * |
@@ -125,6 +118,7 @@ struct irqaction memerr_irq = { | |||
125 | .mask = CPU_MASK_NONE, | 118 | .mask = CPU_MASK_NONE, |
126 | .name = "CRIME memory error", | 119 | .name = "CRIME memory error", |
127 | }; | 120 | }; |
121 | |||
128 | struct irqaction cpuerr_irq = { | 122 | struct irqaction cpuerr_irq = { |
129 | .handler = crime_cpuerr_intr, | 123 | .handler = crime_cpuerr_intr, |
130 | .flags = IRQF_DISABLED, | 124 | .flags = IRQF_DISABLED, |
@@ -139,46 +133,70 @@ struct irqaction cpuerr_irq = { | |||
139 | 133 | ||
140 | static uint64_t crime_mask; | 134 | static uint64_t crime_mask; |
141 | 135 | ||
142 | static void enable_crime_irq(unsigned int irq) | 136 | static inline void crime_enable_irq(unsigned int irq) |
143 | { | 137 | { |
144 | crime_mask |= 1 << (irq - 1); | 138 | unsigned int bit = irq - CRIME_IRQ_BASE; |
139 | |||
140 | crime_mask |= 1 << bit; | ||
145 | crime->imask = crime_mask; | 141 | crime->imask = crime_mask; |
146 | } | 142 | } |
147 | 143 | ||
148 | static void disable_crime_irq(unsigned int irq) | 144 | static inline void crime_disable_irq(unsigned int irq) |
149 | { | 145 | { |
150 | crime_mask &= ~(1 << (irq - 1)); | 146 | unsigned int bit = irq - CRIME_IRQ_BASE; |
147 | |||
148 | crime_mask &= ~(1 << bit); | ||
151 | crime->imask = crime_mask; | 149 | crime->imask = crime_mask; |
152 | flush_crime_bus(); | 150 | flush_crime_bus(); |
153 | } | 151 | } |
154 | 152 | ||
155 | static void mask_and_ack_crime_irq(unsigned int irq) | 153 | static void crime_level_mask_and_ack_irq(unsigned int irq) |
154 | { | ||
155 | crime_disable_irq(irq); | ||
156 | } | ||
157 | |||
158 | static void crime_level_end_irq(unsigned int irq) | ||
159 | { | ||
160 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | ||
161 | crime_enable_irq(irq); | ||
162 | } | ||
163 | |||
164 | static struct irq_chip crime_level_interrupt = { | ||
165 | .name = "IP32 CRIME", | ||
166 | .ack = crime_level_mask_and_ack_irq, | ||
167 | .mask = crime_disable_irq, | ||
168 | .mask_ack = crime_level_mask_and_ack_irq, | ||
169 | .unmask = crime_enable_irq, | ||
170 | .end = crime_level_end_irq, | ||
171 | }; | ||
172 | |||
173 | static void crime_edge_mask_and_ack_irq(unsigned int irq) | ||
156 | { | 174 | { |
175 | unsigned int bit = irq - CRIME_IRQ_BASE; | ||
176 | uint64_t crime_int; | ||
177 | |||
157 | /* Edge triggered interrupts must be cleared. */ | 178 | /* Edge triggered interrupts must be cleared. */ |
158 | if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ) | 179 | |
159 | || (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ) | 180 | crime_int = crime->hard_int; |
160 | || (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) { | 181 | crime_int &= ~(1 << bit); |
161 | uint64_t crime_int; | 182 | crime->hard_int = crime_int; |
162 | crime_int = crime->hard_int; | 183 | |
163 | crime_int &= ~(1 << (irq - 1)); | 184 | crime_disable_irq(irq); |
164 | crime->hard_int = crime_int; | ||
165 | } | ||
166 | disable_crime_irq(irq); | ||
167 | } | 185 | } |
168 | 186 | ||
169 | static void end_crime_irq(unsigned int irq) | 187 | static void crime_edge_end_irq(unsigned int irq) |
170 | { | 188 | { |
171 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | 189 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) |
172 | enable_crime_irq(irq); | 190 | crime_enable_irq(irq); |
173 | } | 191 | } |
174 | 192 | ||
175 | static struct irq_chip ip32_crime_interrupt = { | 193 | static struct irq_chip crime_edge_interrupt = { |
176 | .name = "IP32 CRIME", | 194 | .name = "IP32 CRIME", |
177 | .ack = mask_and_ack_crime_irq, | 195 | .ack = crime_edge_mask_and_ack_irq, |
178 | .mask = disable_crime_irq, | 196 | .mask = crime_disable_irq, |
179 | .mask_ack = mask_and_ack_crime_irq, | 197 | .mask_ack = crime_edge_mask_and_ack_irq, |
180 | .unmask = enable_crime_irq, | 198 | .unmask = crime_enable_irq, |
181 | .end = end_crime_irq, | 199 | .end = crime_edge_end_irq, |
182 | }; | 200 | }; |
183 | 201 | ||
184 | /* | 202 | /* |
@@ -265,7 +283,7 @@ static void enable_maceisa_irq(unsigned int irq) | |||
265 | { | 283 | { |
266 | unsigned int crime_int = 0; | 284 | unsigned int crime_int = 0; |
267 | 285 | ||
268 | DBG("maceisa enable: %u\n", irq); | 286 | pr_debug("maceisa enable: %u\n", irq); |
269 | 287 | ||
270 | switch (irq) { | 288 | switch (irq) { |
271 | case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ: | 289 | case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ: |
@@ -278,7 +296,7 @@ static void enable_maceisa_irq(unsigned int irq) | |||
278 | crime_int = MACE_SUPERIO_INT; | 296 | crime_int = MACE_SUPERIO_INT; |
279 | break; | 297 | break; |
280 | } | 298 | } |
281 | DBG("crime_int %08x enabled\n", crime_int); | 299 | pr_debug("crime_int %08x enabled\n", crime_int); |
282 | crime_mask |= crime_int; | 300 | crime_mask |= crime_int; |
283 | crime->imask = crime_mask; | 301 | crime->imask = crime_mask; |
284 | maceisa_mask |= 1 << (irq - 33); | 302 | maceisa_mask |= 1 << (irq - 33); |
@@ -290,11 +308,11 @@ static void disable_maceisa_irq(unsigned int irq) | |||
290 | unsigned int crime_int = 0; | 308 | unsigned int crime_int = 0; |
291 | 309 | ||
292 | maceisa_mask &= ~(1 << (irq - 33)); | 310 | maceisa_mask &= ~(1 << (irq - 33)); |
293 | if(!(maceisa_mask & MACEISA_AUDIO_INT)) | 311 | if (!(maceisa_mask & MACEISA_AUDIO_INT)) |
294 | crime_int |= MACE_AUDIO_INT; | 312 | crime_int |= MACE_AUDIO_INT; |
295 | if(!(maceisa_mask & MACEISA_MISC_INT)) | 313 | if (!(maceisa_mask & MACEISA_MISC_INT)) |
296 | crime_int |= MACE_MISC_INT; | 314 | crime_int |= MACE_MISC_INT; |
297 | if(!(maceisa_mask & MACEISA_SUPERIO_INT)) | 315 | if (!(maceisa_mask & MACEISA_SUPERIO_INT)) |
298 | crime_int |= MACE_SUPERIO_INT; | 316 | crime_int |= MACE_SUPERIO_INT; |
299 | crime_mask &= ~crime_int; | 317 | crime_mask &= ~crime_int; |
300 | crime->imask = crime_mask; | 318 | crime->imask = crime_mask; |
@@ -327,12 +345,12 @@ static void end_maceisa_irq(unsigned irq) | |||
327 | } | 345 | } |
328 | 346 | ||
329 | static struct irq_chip ip32_maceisa_interrupt = { | 347 | static struct irq_chip ip32_maceisa_interrupt = { |
330 | .name = "IP32 MACE ISA", | 348 | .name = "IP32 MACE ISA", |
331 | .ack = mask_and_ack_maceisa_irq, | 349 | .ack = mask_and_ack_maceisa_irq, |
332 | .mask = disable_maceisa_irq, | 350 | .mask = disable_maceisa_irq, |
333 | .mask_ack = mask_and_ack_maceisa_irq, | 351 | .mask_ack = mask_and_ack_maceisa_irq, |
334 | .unmask = enable_maceisa_irq, | 352 | .unmask = enable_maceisa_irq, |
335 | .end = end_maceisa_irq, | 353 | .end = end_maceisa_irq, |
336 | }; | 354 | }; |
337 | 355 | ||
338 | /* This is used for regular non-ISA, non-PCI MACE interrupts. That means | 356 | /* This is used for regular non-ISA, non-PCI MACE interrupts. That means |
@@ -411,7 +429,7 @@ static void ip32_irq0(void) | |||
411 | irq = __ffs(mace_int & maceisa_mask) + MACEISA_AUDIO_SW_IRQ; | 429 | irq = __ffs(mace_int & maceisa_mask) + MACEISA_AUDIO_SW_IRQ; |
412 | } | 430 | } |
413 | 431 | ||
414 | DBG("*irq %u*\n", irq); | 432 | pr_debug("*irq %u*\n", irq); |
415 | do_IRQ(irq); | 433 | do_IRQ(irq); |
416 | } | 434 | } |
417 | 435 | ||
@@ -472,23 +490,31 @@ void __init arch_init_irq(void) | |||
472 | 490 | ||
473 | mips_cpu_irq_init(); | 491 | mips_cpu_irq_init(); |
474 | for (irq = MIPS_CPU_IRQ_BASE + 8; irq <= IP32_IRQ_MAX; irq++) { | 492 | for (irq = MIPS_CPU_IRQ_BASE + 8; irq <= IP32_IRQ_MAX; irq++) { |
475 | struct irq_chip *chip; | ||
476 | |||
477 | switch (irq) { | 493 | switch (irq) { |
478 | case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ: | 494 | case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ: |
479 | chip = &ip32_mace_interrupt; | 495 | set_irq_chip(irq, &ip32_mace_interrupt); |
480 | break; | 496 | break; |
481 | case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ: | 497 | case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ: |
482 | chip = &ip32_macepci_interrupt; | 498 | set_irq_chip(irq, &ip32_macepci_interrupt); |
499 | break; | ||
500 | case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ: | ||
501 | set_irq_chip(irq, &crime_edge_interrupt); | ||
502 | break; | ||
503 | case CRIME_CPUERR_IRQ: | ||
504 | case CRIME_MEMERR_IRQ: | ||
505 | set_irq_chip(irq, &crime_level_interrupt); | ||
483 | break; | 506 | break; |
484 | case CRIME_GBE0_IRQ ... CRIME_VICE_IRQ: | 507 | case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ: |
485 | chip = &ip32_crime_interrupt; | 508 | case CRIME_SOFT0_IRQ ... CRIME_SOFT2_IRQ: |
509 | set_irq_chip(irq, &crime_edge_interrupt); | ||
510 | break; | ||
511 | case CRIME_VICE_IRQ: | ||
512 | set_irq_chip(irq, &crime_edge_interrupt); | ||
486 | break; | 513 | break; |
487 | default: | 514 | default: |
488 | chip = &ip32_maceisa_interrupt; | 515 | set_irq_chip(irq, &ip32_maceisa_interrupt); |
516 | break; | ||
489 | } | 517 | } |
490 | |||
491 | set_irq_chip(irq, chip); | ||
492 | } | 518 | } |
493 | setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); | 519 | setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); |
494 | setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); | 520 | setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); |