aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/sgi-ip32/ip32-irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/sgi-ip32/ip32-irq.c')
-rw-r--r--arch/mips/sgi-ip32/ip32-irq.c128
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
128struct irqaction cpuerr_irq = { 122struct 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
140static uint64_t crime_mask; 134static uint64_t crime_mask;
141 135
142static void enable_crime_irq(unsigned int irq) 136static 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
148static void disable_crime_irq(unsigned int irq) 144static 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
155static void mask_and_ack_crime_irq(unsigned int irq) 153static void crime_level_mask_and_ack_irq(unsigned int irq)
154{
155 crime_disable_irq(irq);
156}
157
158static 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
164static 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
173static 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
169static void end_crime_irq(unsigned int irq) 187static 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
175static struct irq_chip ip32_crime_interrupt = { 193static 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
329static struct irq_chip ip32_maceisa_interrupt = { 347static 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);