0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/init.h>
0012 #include <linux/kernel_stat.h>
0013 #include <linux/types.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/irq.h>
0016 #include <linux/bitops.h>
0017 #include <linux/kernel.h>
0018 #include <linux/mm.h>
0019 #include <linux/random.h>
0020 #include <linux/sched.h>
0021 #include <linux/sched/debug.h>
0022
0023 #include <asm/irq_cpu.h>
0024 #include <asm/mipsregs.h>
0025 #include <asm/signal.h>
0026 #include <asm/time.h>
0027 #include <asm/ip32/crime.h>
0028 #include <asm/ip32/mace.h>
0029 #include <asm/ip32/ip32_ints.h>
0030
0031
0032 static inline void flush_crime_bus(void)
0033 {
0034 crime->control;
0035 }
0036
0037 static inline void flush_mace_bus(void)
0038 {
0039 mace->perif.ctrl.misc;
0040 }
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 extern irqreturn_t crime_memerr_intr(int irq, void *dev_id);
0112 extern irqreturn_t crime_cpuerr_intr(int irq, void *dev_id);
0113
0114
0115
0116
0117
0118
0119 static uint64_t crime_mask;
0120
0121 static inline void crime_enable_irq(struct irq_data *d)
0122 {
0123 unsigned int bit = d->irq - CRIME_IRQ_BASE;
0124
0125 crime_mask |= 1 << bit;
0126 crime->imask = crime_mask;
0127 }
0128
0129 static inline void crime_disable_irq(struct irq_data *d)
0130 {
0131 unsigned int bit = d->irq - CRIME_IRQ_BASE;
0132
0133 crime_mask &= ~(1 << bit);
0134 crime->imask = crime_mask;
0135 flush_crime_bus();
0136 }
0137
0138 static struct irq_chip crime_level_interrupt = {
0139 .name = "IP32 CRIME",
0140 .irq_mask = crime_disable_irq,
0141 .irq_unmask = crime_enable_irq,
0142 };
0143
0144 static void crime_edge_mask_and_ack_irq(struct irq_data *d)
0145 {
0146 unsigned int bit = d->irq - CRIME_IRQ_BASE;
0147 uint64_t crime_int;
0148
0149
0150 crime_int = crime->hard_int;
0151 crime_int &= ~(1 << bit);
0152 crime->hard_int = crime_int;
0153
0154 crime_disable_irq(d);
0155 }
0156
0157 static struct irq_chip crime_edge_interrupt = {
0158 .name = "IP32 CRIME",
0159 .irq_ack = crime_edge_mask_and_ack_irq,
0160 .irq_mask = crime_disable_irq,
0161 .irq_mask_ack = crime_edge_mask_and_ack_irq,
0162 .irq_unmask = crime_enable_irq,
0163 };
0164
0165
0166
0167
0168
0169
0170
0171 static unsigned long macepci_mask;
0172
0173 static void enable_macepci_irq(struct irq_data *d)
0174 {
0175 macepci_mask |= MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
0176 mace->pci.control = macepci_mask;
0177 crime_mask |= 1 << (d->irq - CRIME_IRQ_BASE);
0178 crime->imask = crime_mask;
0179 }
0180
0181 static void disable_macepci_irq(struct irq_data *d)
0182 {
0183 crime_mask &= ~(1 << (d->irq - CRIME_IRQ_BASE));
0184 crime->imask = crime_mask;
0185 flush_crime_bus();
0186 macepci_mask &= ~MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
0187 mace->pci.control = macepci_mask;
0188 flush_mace_bus();
0189 }
0190
0191 static struct irq_chip ip32_macepci_interrupt = {
0192 .name = "IP32 MACE PCI",
0193 .irq_mask = disable_macepci_irq,
0194 .irq_unmask = enable_macepci_irq,
0195 };
0196
0197
0198
0199
0200
0201 #define MACEISA_AUDIO_INT (MACEISA_AUDIO_SW_INT | \
0202 MACEISA_AUDIO_SC_INT | \
0203 MACEISA_AUDIO1_DMAT_INT | \
0204 MACEISA_AUDIO1_OF_INT | \
0205 MACEISA_AUDIO2_DMAT_INT | \
0206 MACEISA_AUDIO2_MERR_INT | \
0207 MACEISA_AUDIO3_DMAT_INT | \
0208 MACEISA_AUDIO3_MERR_INT)
0209 #define MACEISA_MISC_INT (MACEISA_RTC_INT | \
0210 MACEISA_KEYB_INT | \
0211 MACEISA_KEYB_POLL_INT | \
0212 MACEISA_MOUSE_INT | \
0213 MACEISA_MOUSE_POLL_INT | \
0214 MACEISA_TIMER0_INT | \
0215 MACEISA_TIMER1_INT | \
0216 MACEISA_TIMER2_INT)
0217 #define MACEISA_SUPERIO_INT (MACEISA_PARALLEL_INT | \
0218 MACEISA_PAR_CTXA_INT | \
0219 MACEISA_PAR_CTXB_INT | \
0220 MACEISA_PAR_MERR_INT | \
0221 MACEISA_SERIAL1_INT | \
0222 MACEISA_SERIAL1_TDMAT_INT | \
0223 MACEISA_SERIAL1_TDMAPR_INT | \
0224 MACEISA_SERIAL1_TDMAME_INT | \
0225 MACEISA_SERIAL1_RDMAT_INT | \
0226 MACEISA_SERIAL1_RDMAOR_INT | \
0227 MACEISA_SERIAL2_INT | \
0228 MACEISA_SERIAL2_TDMAT_INT | \
0229 MACEISA_SERIAL2_TDMAPR_INT | \
0230 MACEISA_SERIAL2_TDMAME_INT | \
0231 MACEISA_SERIAL2_RDMAT_INT | \
0232 MACEISA_SERIAL2_RDMAOR_INT)
0233
0234 static unsigned long maceisa_mask;
0235
0236 static void enable_maceisa_irq(struct irq_data *d)
0237 {
0238 unsigned int crime_int = 0;
0239
0240 pr_debug("maceisa enable: %u\n", d->irq);
0241
0242 switch (d->irq) {
0243 case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
0244 crime_int = MACE_AUDIO_INT;
0245 break;
0246 case MACEISA_RTC_IRQ ... MACEISA_TIMER2_IRQ:
0247 crime_int = MACE_MISC_INT;
0248 break;
0249 case MACEISA_PARALLEL_IRQ ... MACEISA_SERIAL2_RDMAOR_IRQ:
0250 crime_int = MACE_SUPERIO_INT;
0251 break;
0252 }
0253 pr_debug("crime_int %08x enabled\n", crime_int);
0254 crime_mask |= crime_int;
0255 crime->imask = crime_mask;
0256 maceisa_mask |= 1 << (d->irq - MACEISA_AUDIO_SW_IRQ);
0257 mace->perif.ctrl.imask = maceisa_mask;
0258 }
0259
0260 static void disable_maceisa_irq(struct irq_data *d)
0261 {
0262 unsigned int crime_int = 0;
0263
0264 maceisa_mask &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ));
0265 if (!(maceisa_mask & MACEISA_AUDIO_INT))
0266 crime_int |= MACE_AUDIO_INT;
0267 if (!(maceisa_mask & MACEISA_MISC_INT))
0268 crime_int |= MACE_MISC_INT;
0269 if (!(maceisa_mask & MACEISA_SUPERIO_INT))
0270 crime_int |= MACE_SUPERIO_INT;
0271 crime_mask &= ~crime_int;
0272 crime->imask = crime_mask;
0273 flush_crime_bus();
0274 mace->perif.ctrl.imask = maceisa_mask;
0275 flush_mace_bus();
0276 }
0277
0278 static void mask_and_ack_maceisa_irq(struct irq_data *d)
0279 {
0280 unsigned long mace_int;
0281
0282
0283 mace_int = mace->perif.ctrl.istat;
0284 mace_int &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ));
0285 mace->perif.ctrl.istat = mace_int;
0286
0287 disable_maceisa_irq(d);
0288 }
0289
0290 static struct irq_chip ip32_maceisa_level_interrupt = {
0291 .name = "IP32 MACE ISA",
0292 .irq_mask = disable_maceisa_irq,
0293 .irq_unmask = enable_maceisa_irq,
0294 };
0295
0296 static struct irq_chip ip32_maceisa_edge_interrupt = {
0297 .name = "IP32 MACE ISA",
0298 .irq_ack = mask_and_ack_maceisa_irq,
0299 .irq_mask = disable_maceisa_irq,
0300 .irq_mask_ack = mask_and_ack_maceisa_irq,
0301 .irq_unmask = enable_maceisa_irq,
0302 };
0303
0304
0305
0306
0307
0308 static void enable_mace_irq(struct irq_data *d)
0309 {
0310 unsigned int bit = d->irq - CRIME_IRQ_BASE;
0311
0312 crime_mask |= (1 << bit);
0313 crime->imask = crime_mask;
0314 }
0315
0316 static void disable_mace_irq(struct irq_data *d)
0317 {
0318 unsigned int bit = d->irq - CRIME_IRQ_BASE;
0319
0320 crime_mask &= ~(1 << bit);
0321 crime->imask = crime_mask;
0322 flush_crime_bus();
0323 }
0324
0325 static struct irq_chip ip32_mace_interrupt = {
0326 .name = "IP32 MACE",
0327 .irq_mask = disable_mace_irq,
0328 .irq_unmask = enable_mace_irq,
0329 };
0330
0331 static void ip32_unknown_interrupt(void)
0332 {
0333 printk("Unknown interrupt occurred!\n");
0334 printk("cp0_status: %08x\n", read_c0_status());
0335 printk("cp0_cause: %08x\n", read_c0_cause());
0336 printk("CRIME intr mask: %016lx\n", crime->imask);
0337 printk("CRIME intr status: %016lx\n", crime->istat);
0338 printk("CRIME hardware intr register: %016lx\n", crime->hard_int);
0339 printk("MACE ISA intr mask: %08lx\n", mace->perif.ctrl.imask);
0340 printk("MACE ISA intr status: %08lx\n", mace->perif.ctrl.istat);
0341 printk("MACE PCI control register: %08x\n", mace->pci.control);
0342
0343 printk("Register dump:\n");
0344 show_regs(get_irq_regs());
0345
0346 printk("Please mail this report to linux-mips@vger.kernel.org\n");
0347 printk("Spinning...");
0348 while(1) ;
0349 }
0350
0351
0352
0353 static void ip32_irq0(void)
0354 {
0355 uint64_t crime_int;
0356 int irq = 0;
0357
0358
0359
0360
0361
0362
0363 BUILD_BUG_ON(CRIME_VICE_IRQ - MACE_VID_IN1_IRQ != 31);
0364 BUILD_BUG_ON(MACEISA_SERIAL2_RDMAOR_IRQ - MACEISA_AUDIO_SW_IRQ != 31);
0365
0366 crime_int = crime->istat & crime_mask;
0367
0368
0369 if (unlikely(crime_int == 0))
0370 return;
0371
0372 irq = MACE_VID_IN1_IRQ + __ffs(crime_int);
0373
0374 if (crime_int & CRIME_MACEISA_INT_MASK) {
0375 unsigned long mace_int = mace->perif.ctrl.istat;
0376 irq = __ffs(mace_int & maceisa_mask) + MACEISA_AUDIO_SW_IRQ;
0377 }
0378
0379 pr_debug("*irq %u*\n", irq);
0380 do_IRQ(irq);
0381 }
0382
0383 static void ip32_irq1(void)
0384 {
0385 ip32_unknown_interrupt();
0386 }
0387
0388 static void ip32_irq2(void)
0389 {
0390 ip32_unknown_interrupt();
0391 }
0392
0393 static void ip32_irq3(void)
0394 {
0395 ip32_unknown_interrupt();
0396 }
0397
0398 static void ip32_irq4(void)
0399 {
0400 ip32_unknown_interrupt();
0401 }
0402
0403 static void ip32_irq5(void)
0404 {
0405 do_IRQ(MIPS_CPU_IRQ_BASE + 7);
0406 }
0407
0408 asmlinkage void plat_irq_dispatch(void)
0409 {
0410 unsigned int pending = read_c0_status() & read_c0_cause();
0411
0412 if (likely(pending & IE_IRQ0))
0413 ip32_irq0();
0414 else if (unlikely(pending & IE_IRQ1))
0415 ip32_irq1();
0416 else if (unlikely(pending & IE_IRQ2))
0417 ip32_irq2();
0418 else if (unlikely(pending & IE_IRQ3))
0419 ip32_irq3();
0420 else if (unlikely(pending & IE_IRQ4))
0421 ip32_irq4();
0422 else if (likely(pending & IE_IRQ5))
0423 ip32_irq5();
0424 }
0425
0426 void __init arch_init_irq(void)
0427 {
0428 unsigned int irq;
0429
0430
0431
0432 crime->imask = 0;
0433 crime->hard_int = 0;
0434 crime->soft_int = 0;
0435 mace->perif.ctrl.istat = 0;
0436 mace->perif.ctrl.imask = 0;
0437
0438 mips_cpu_irq_init();
0439 for (irq = CRIME_IRQ_BASE; irq <= IP32_IRQ_MAX; irq++) {
0440 switch (irq) {
0441 case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ:
0442 irq_set_chip_and_handler_name(irq,
0443 &ip32_mace_interrupt,
0444 handle_level_irq,
0445 "level");
0446 break;
0447
0448 case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ:
0449 irq_set_chip_and_handler_name(irq,
0450 &ip32_macepci_interrupt,
0451 handle_level_irq,
0452 "level");
0453 break;
0454
0455 case CRIME_CPUERR_IRQ:
0456 case CRIME_MEMERR_IRQ:
0457 irq_set_chip_and_handler_name(irq,
0458 &crime_level_interrupt,
0459 handle_level_irq,
0460 "level");
0461 break;
0462
0463 case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ:
0464 case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ:
0465 case CRIME_SOFT0_IRQ ... CRIME_SOFT2_IRQ:
0466 case CRIME_VICE_IRQ:
0467 irq_set_chip_and_handler_name(irq,
0468 &crime_edge_interrupt,
0469 handle_edge_irq,
0470 "edge");
0471 break;
0472
0473 case MACEISA_PARALLEL_IRQ:
0474 case MACEISA_SERIAL1_TDMAPR_IRQ:
0475 case MACEISA_SERIAL2_TDMAPR_IRQ:
0476 irq_set_chip_and_handler_name(irq,
0477 &ip32_maceisa_edge_interrupt,
0478 handle_edge_irq,
0479 "edge");
0480 break;
0481
0482 default:
0483 irq_set_chip_and_handler_name(irq,
0484 &ip32_maceisa_level_interrupt,
0485 handle_level_irq,
0486 "level");
0487 break;
0488 }
0489 }
0490 if (request_irq(CRIME_MEMERR_IRQ, crime_memerr_intr, 0,
0491 "CRIME memory error", NULL))
0492 pr_err("Failed to register CRIME memory error interrupt\n");
0493 if (request_irq(CRIME_CPUERR_IRQ, crime_cpuerr_intr, 0,
0494 "CRIME CPU error", NULL))
0495 pr_err("Failed to register CRIME CPU error interrupt\n");
0496
0497 #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
0498 change_c0_status(ST0_IM, ALLINTS);
0499 }