1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Carsten Langgaard, carstenl@mips.com 7 * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc. 8 * Copyright (C) 2001 Ralf Baechle 9 * Copyright (C) 2013 Imagination Technologies Ltd. 10 * 11 * Routines for generic manipulation of the interrupts found on the MIPS 12 * Malta board. The interrupt controller is located in the South Bridge 13 * a PIIX4 device with two internal 82C95 interrupt controllers. 14 */ 15 #include <linux/init.h> 16 #include <linux/irq.h> 17 #include <linux/sched.h> 18 #include <linux/smp.h> 19 #include <linux/interrupt.h> 20 #include <linux/io.h> 21 #include <linux/kernel_stat.h> 22 #include <linux/kernel.h> 23 #include <linux/random.h> 24 25 #include <asm/traps.h> 26 #include <asm/i8259.h> 27 #include <asm/irq_cpu.h> 28 #include <asm/irq_regs.h> 29 #include <asm/mips-cm.h> 30 #include <asm/mips-boards/malta.h> 31 #include <asm/mips-boards/maltaint.h> 32 #include <asm/gt64120.h> 33 #include <asm/mips-boards/generic.h> 34 #include <asm/mips-boards/msc01_pci.h> 35 #include <asm/msc01_ic.h> 36 #include <asm/gic.h> 37 #include <asm/setup.h> 38 #include <asm/rtlx.h> 39 40 static unsigned long _msc01_biu_base; 41 static unsigned int ipi_map[NR_CPUS]; 42 43 static DEFINE_RAW_SPINLOCK(mips_irq_lock); 44 45 #ifdef CONFIG_MIPS_GIC_IPI 46 DECLARE_BITMAP(ipi_ints, GIC_NUM_INTRS); 47 #endif 48 49 static inline int mips_pcibios_iack(void) 50 { 51 int irq; 52 53 /* 54 * Determine highest priority pending interrupt by performing 55 * a PCI Interrupt Acknowledge cycle. 56 */ 57 switch (mips_revision_sconid) { 58 case MIPS_REVISION_SCON_SOCIT: 59 case MIPS_REVISION_SCON_ROCIT: 60 case MIPS_REVISION_SCON_SOCITSC: 61 case MIPS_REVISION_SCON_SOCITSCP: 62 MSC_READ(MSC01_PCI_IACK, irq); 63 irq &= 0xff; 64 break; 65 case MIPS_REVISION_SCON_GT64120: 66 irq = GT_READ(GT_PCI0_IACK_OFS); 67 irq &= 0xff; 68 break; 69 case MIPS_REVISION_SCON_BONITO: 70 /* The following will generate a PCI IACK cycle on the 71 * Bonito controller. It's a little bit kludgy, but it 72 * was the easiest way to implement it in hardware at 73 * the given time. 74 */ 75 BONITO_PCIMAP_CFG = 0x20000; 76 77 /* Flush Bonito register block */ 78 (void) BONITO_PCIMAP_CFG; 79 iob(); /* sync */ 80 81 irq = __raw_readl((u32 *)_pcictrl_bonito_pcicfg); 82 iob(); /* sync */ 83 irq &= 0xff; 84 BONITO_PCIMAP_CFG = 0; 85 break; 86 default: 87 pr_emerg("Unknown system controller.\n"); 88 return -1; 89 } 90 return irq; 91 } 92 93 static inline int get_int(void) 94 { 95 unsigned long flags; 96 int irq; 97 raw_spin_lock_irqsave(&mips_irq_lock, flags); 98 99 irq = mips_pcibios_iack(); 100 101 /* 102 * The only way we can decide if an interrupt is spurious 103 * is by checking the 8259 registers. This needs a spinlock 104 * on an SMP system, so leave it up to the generic code... 105 */ 106 107 raw_spin_unlock_irqrestore(&mips_irq_lock, flags); 108 109 return irq; 110 } 111 112 static void malta_hw0_irqdispatch(void) 113 { 114 int irq; 115 116 irq = get_int(); 117 if (irq < 0) { 118 /* interrupt has already been cleared */ 119 return; 120 } 121 122 do_IRQ(MALTA_INT_BASE + irq); 123 124 #ifdef CONFIG_MIPS_VPE_APSP_API_MT 125 if (aprp_hook) 126 aprp_hook(); 127 #endif 128 } 129 130 static void malta_ipi_irqdispatch(void) 131 { 132 #ifdef CONFIG_MIPS_GIC_IPI 133 unsigned long irq; 134 DECLARE_BITMAP(pending, GIC_NUM_INTRS); 135 136 gic_get_int_mask(pending, ipi_ints); 137 138 irq = find_first_bit(pending, GIC_NUM_INTRS); 139 140 while (irq < GIC_NUM_INTRS) { 141 do_IRQ(MIPS_GIC_IRQ_BASE + irq); 142 143 irq = find_next_bit(pending, GIC_NUM_INTRS, irq + 1); 144 } 145 #endif 146 if (gic_compare_int()) 147 do_IRQ(MIPS_GIC_IRQ_BASE); 148 } 149 150 static void corehi_irqdispatch(void) 151 { 152 unsigned int intedge, intsteer, pcicmd, pcibadaddr; 153 unsigned int pcimstat, intisr, inten, intpol; 154 unsigned int intrcause, datalo, datahi; 155 struct pt_regs *regs = get_irq_regs(); 156 157 pr_emerg("CoreHI interrupt, shouldn't happen, we die here!\n"); 158 pr_emerg("epc : %08lx\nStatus: %08lx\n" 159 "Cause : %08lx\nbadVaddr : %08lx\n", 160 regs->cp0_epc, regs->cp0_status, 161 regs->cp0_cause, regs->cp0_badvaddr); 162 163 /* Read all the registers and then print them as there is a 164 problem with interspersed printk's upsetting the Bonito controller. 165 Do it for the others too. 166 */ 167 168 switch (mips_revision_sconid) { 169 case MIPS_REVISION_SCON_SOCIT: 170 case MIPS_REVISION_SCON_ROCIT: 171 case MIPS_REVISION_SCON_SOCITSC: 172 case MIPS_REVISION_SCON_SOCITSCP: 173 ll_msc_irq(); 174 break; 175 case MIPS_REVISION_SCON_GT64120: 176 intrcause = GT_READ(GT_INTRCAUSE_OFS); 177 datalo = GT_READ(GT_CPUERR_ADDRLO_OFS); 178 datahi = GT_READ(GT_CPUERR_ADDRHI_OFS); 179 pr_emerg("GT_INTRCAUSE = %08x\n", intrcause); 180 pr_emerg("GT_CPUERR_ADDR = %02x%08x\n", 181 datahi, datalo); 182 break; 183 case MIPS_REVISION_SCON_BONITO: 184 pcibadaddr = BONITO_PCIBADADDR; 185 pcimstat = BONITO_PCIMSTAT; 186 intisr = BONITO_INTISR; 187 inten = BONITO_INTEN; 188 intpol = BONITO_INTPOL; 189 intedge = BONITO_INTEDGE; 190 intsteer = BONITO_INTSTEER; 191 pcicmd = BONITO_PCICMD; 192 pr_emerg("BONITO_INTISR = %08x\n", intisr); 193 pr_emerg("BONITO_INTEN = %08x\n", inten); 194 pr_emerg("BONITO_INTPOL = %08x\n", intpol); 195 pr_emerg("BONITO_INTEDGE = %08x\n", intedge); 196 pr_emerg("BONITO_INTSTEER = %08x\n", intsteer); 197 pr_emerg("BONITO_PCICMD = %08x\n", pcicmd); 198 pr_emerg("BONITO_PCIBADADDR = %08x\n", pcibadaddr); 199 pr_emerg("BONITO_PCIMSTAT = %08x\n", pcimstat); 200 break; 201 } 202 203 die("CoreHi interrupt", regs); 204 } 205 206 static inline int clz(unsigned long x) 207 { 208 __asm__( 209 " .set push \n" 210 " .set mips32 \n" 211 " clz %0, %1 \n" 212 " .set pop \n" 213 : "=r" (x) 214 : "r" (x)); 215 216 return x; 217 } 218 219 /* 220 * Version of ffs that only looks at bits 12..15. 221 */ 222 static inline unsigned int irq_ffs(unsigned int pending) 223 { 224 #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) 225 return -clz(pending) + 31 - CAUSEB_IP; 226 #else 227 unsigned int a0 = 7; 228 unsigned int t0; 229 230 t0 = pending & 0xf000; 231 t0 = t0 < 1; 232 t0 = t0 << 2; 233 a0 = a0 - t0; 234 pending = pending << t0; 235 236 t0 = pending & 0xc000; 237 t0 = t0 < 1; 238 t0 = t0 << 1; 239 a0 = a0 - t0; 240 pending = pending << t0; 241 242 t0 = pending & 0x8000; 243 t0 = t0 < 1; 244 /* t0 = t0 << 2; */ 245 a0 = a0 - t0; 246 /* pending = pending << t0; */ 247 248 return a0; 249 #endif 250 } 251 252 /* 253 * IRQs on the Malta board look basically (barring software IRQs which we 254 * don't use at all and all external interrupt sources are combined together 255 * on hardware interrupt 0 (MIPS IRQ 2)) like: 256 * 257 * MIPS IRQ Source 258 * -------- ------ 259 * 0 Software (ignored) 260 * 1 Software (ignored) 261 * 2 Combined hardware interrupt (hw0) 262 * 3 Hardware (ignored) 263 * 4 Hardware (ignored) 264 * 5 Hardware (ignored) 265 * 6 Hardware (ignored) 266 * 7 R4k timer (what we use) 267 * 268 * We handle the IRQ according to _our_ priority which is: 269 * 270 * Highest ---- R4k Timer 271 * Lowest ---- Combined hardware interrupt 272 * 273 * then we just return, if multiple IRQs are pending then we will just take 274 * another exception, big deal. 275 */ 276 277 asmlinkage void plat_irq_dispatch(void) 278 { 279 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; 280 int irq; 281 282 if (unlikely(!pending)) { 283 spurious_interrupt(); 284 return; 285 } 286 287 irq = irq_ffs(pending); 288 289 if (irq == MIPSCPU_INT_I8259A) 290 malta_hw0_irqdispatch(); 291 else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()])) 292 malta_ipi_irqdispatch(); 293 else 294 do_IRQ(MIPS_CPU_IRQ_BASE + irq); 295 } 296 297 #ifdef CONFIG_MIPS_MT_SMP 298 299 #define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */ 300 #define C_RESCHED C_SW0 301 #define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for resched */ 302 #define C_CALL C_SW1 303 static int cpu_ipi_resched_irq, cpu_ipi_call_irq; 304 305 static void ipi_resched_dispatch(void) 306 { 307 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ); 308 } 309 310 static void ipi_call_dispatch(void) 311 { 312 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); 313 } 314 315 #endif /* CONFIG_MIPS_MT_SMP */ 316 317 #ifdef CONFIG_MIPS_GIC_IPI 318 319 #define GIC_MIPS_CPU_IPI_RESCHED_IRQ 3 320 #define GIC_MIPS_CPU_IPI_CALL_IRQ 4 321 322 static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) 323 { 324 #ifdef CONFIG_MIPS_VPE_APSP_API_CMP 325 if (aprp_hook) 326 aprp_hook(); 327 #endif 328 329 scheduler_ipi(); 330 331 return IRQ_HANDLED; 332 } 333 334 static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) 335 { 336 smp_call_function_interrupt(); 337 338 return IRQ_HANDLED; 339 } 340 341 static struct irqaction irq_resched = { 342 .handler = ipi_resched_interrupt, 343 .flags = IRQF_PERCPU, 344 .name = "IPI_resched" 345 }; 346 347 static struct irqaction irq_call = { 348 .handler = ipi_call_interrupt, 349 .flags = IRQF_PERCPU, 350 .name = "IPI_call" 351 }; 352 #endif /* CONFIG_MIPS_GIC_IPI */ 353 354 static int gic_resched_int_base; 355 static int gic_call_int_base; 356 #define GIC_RESCHED_INT(cpu) (gic_resched_int_base+(cpu)) 357 #define GIC_CALL_INT(cpu) (gic_call_int_base+(cpu)) 358 359 unsigned int plat_ipi_call_int_xlate(unsigned int cpu) 360 { 361 return GIC_CALL_INT(cpu); 362 } 363 364 unsigned int plat_ipi_resched_int_xlate(unsigned int cpu) 365 { 366 return GIC_RESCHED_INT(cpu); 367 } 368 369 static struct irqaction i8259irq = { 370 .handler = no_action, 371 .name = "XT-PIC cascade", 372 .flags = IRQF_NO_THREAD, 373 }; 374 375 static struct irqaction corehi_irqaction = { 376 .handler = no_action, 377 .name = "CoreHi", 378 .flags = IRQF_NO_THREAD, 379 }; 380 381 static msc_irqmap_t msc_irqmap[] __initdata = { 382 {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0}, 383 {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0}, 384 }; 385 static int msc_nr_irqs __initdata = ARRAY_SIZE(msc_irqmap); 386 387 static msc_irqmap_t msc_eicirqmap[] __initdata = { 388 {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0}, 389 {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0}, 390 {MSC01E_INT_I8259A, MSC01_IRQ_LEVEL, 0}, 391 {MSC01E_INT_SMI, MSC01_IRQ_LEVEL, 0}, 392 {MSC01E_INT_COREHI, MSC01_IRQ_LEVEL, 0}, 393 {MSC01E_INT_CORELO, MSC01_IRQ_LEVEL, 0}, 394 {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0}, 395 {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0}, 396 {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0}, 397 {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0} 398 }; 399 400 static int msc_nr_eicirqs __initdata = ARRAY_SIZE(msc_eicirqmap); 401 402 /* 403 * This GIC specific tabular array defines the association between External 404 * Interrupts and CPUs/Core Interrupts. The nature of the External 405 * Interrupts is also defined here - polarity/trigger. 406 */ 407 408 #define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK 409 #define X GIC_UNUSED 410 411 static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { 412 { X, X, X, X, 0 }, 413 { X, X, X, X, 0 }, 414 { X, X, X, X, 0 }, 415 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 416 { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 417 { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 418 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 419 { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 420 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 421 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 422 { X, X, X, X, 0 }, 423 { X, X, X, X, 0 }, 424 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 425 { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 426 { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, 427 { X, X, X, X, 0 }, 428 /* The remainder of this table is initialised by fill_ipi_map */ 429 }; 430 #undef X 431 432 #ifdef CONFIG_MIPS_GIC_IPI 433 static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) 434 { 435 int intr = baseintr + cpu; 436 gic_intr_map[intr].cpunum = cpu; 437 gic_intr_map[intr].pin = cpupin; 438 gic_intr_map[intr].polarity = GIC_POL_POS; 439 gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; 440 gic_intr_map[intr].flags = 0; 441 ipi_map[cpu] |= (1 << (cpupin + 2)); 442 bitmap_set(ipi_ints, intr, 1); 443 } 444 445 static void __init fill_ipi_map(void) 446 { 447 int cpu; 448 449 for (cpu = 0; cpu < nr_cpu_ids; cpu++) { 450 fill_ipi_map1(gic_resched_int_base, cpu, GIC_CPU_INT1); 451 fill_ipi_map1(gic_call_int_base, cpu, GIC_CPU_INT2); 452 } 453 } 454 #endif 455 456 void __init arch_init_ipiirq(int irq, struct irqaction *action) 457 { 458 setup_irq(irq, action); 459 irq_set_handler(irq, handle_percpu_irq); 460 } 461 462 void __init arch_init_irq(void) 463 { 464 init_i8259_irqs(); 465 466 if (!cpu_has_veic) 467 mips_cpu_irq_init(); 468 469 if (mips_cm_present()) { 470 write_gcr_gic_base(GIC_BASE_ADDR | CM_GCR_GIC_BASE_GICEN_MSK); 471 gic_present = 1; 472 } else { 473 if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) { 474 _msc01_biu_base = (unsigned long) 475 ioremap_nocache(MSC01_BIU_REG_BASE, 476 MSC01_BIU_ADDRSPACE_SZ); 477 gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) & 478 MSC01_SC_CFG_GICPRES_MSK) >> 479 MSC01_SC_CFG_GICPRES_SHF; 480 } 481 } 482 if (gic_present) 483 pr_debug("GIC present\n"); 484 485 switch (mips_revision_sconid) { 486 case MIPS_REVISION_SCON_SOCIT: 487 case MIPS_REVISION_SCON_ROCIT: 488 if (cpu_has_veic) 489 init_msc_irqs(MIPS_MSC01_IC_REG_BASE, 490 MSC01E_INT_BASE, msc_eicirqmap, 491 msc_nr_eicirqs); 492 else 493 init_msc_irqs(MIPS_MSC01_IC_REG_BASE, 494 MSC01C_INT_BASE, msc_irqmap, 495 msc_nr_irqs); 496 break; 497 498 case MIPS_REVISION_SCON_SOCITSC: 499 case MIPS_REVISION_SCON_SOCITSCP: 500 if (cpu_has_veic) 501 init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, 502 MSC01E_INT_BASE, msc_eicirqmap, 503 msc_nr_eicirqs); 504 else 505 init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, 506 MSC01C_INT_BASE, msc_irqmap, 507 msc_nr_irqs); 508 } 509 510 if (cpu_has_veic) { 511 set_vi_handler(MSC01E_INT_I8259A, malta_hw0_irqdispatch); 512 set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); 513 setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq); 514 setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction); 515 } else if (cpu_has_vint) { 516 set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); 517 set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch); 518 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); 519 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, 520 &corehi_irqaction); 521 } else { 522 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); 523 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, 524 &corehi_irqaction); 525 } 526 527 if (gic_present) { 528 /* FIXME */ 529 int i; 530 #if defined(CONFIG_MIPS_GIC_IPI) 531 gic_call_int_base = GIC_NUM_INTRS - 532 (NR_CPUS - nr_cpu_ids) * 2 - nr_cpu_ids; 533 gic_resched_int_base = gic_call_int_base - nr_cpu_ids; 534 fill_ipi_map(); 535 #endif 536 gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, 537 ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); 538 if (!mips_cm_present()) { 539 /* Enable the GIC */ 540 i = REG(_msc01_biu_base, MSC01_SC_CFG); 541 REG(_msc01_biu_base, MSC01_SC_CFG) = 542 (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); 543 pr_debug("GIC Enabled\n"); 544 } 545 #if defined(CONFIG_MIPS_GIC_IPI) 546 /* set up ipi interrupts */ 547 if (cpu_has_vint) { 548 set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch); 549 set_vi_handler(MIPSCPU_INT_IPI1, malta_ipi_irqdispatch); 550 } 551 /* Argh.. this really needs sorting out.. */ 552 pr_info("CPU%d: status register was %08x\n", 553 smp_processor_id(), read_c0_status()); 554 write_c0_status(read_c0_status() | STATUSF_IP3 | STATUSF_IP4); 555 pr_info("CPU%d: status register now %08x\n", 556 smp_processor_id(), read_c0_status()); 557 write_c0_status(0x1100dc00); 558 pr_info("CPU%d: status register frc %08x\n", 559 smp_processor_id(), read_c0_status()); 560 for (i = 0; i < nr_cpu_ids; i++) { 561 arch_init_ipiirq(MIPS_GIC_IRQ_BASE + 562 GIC_RESCHED_INT(i), &irq_resched); 563 arch_init_ipiirq(MIPS_GIC_IRQ_BASE + 564 GIC_CALL_INT(i), &irq_call); 565 } 566 #endif 567 } else { 568 #if defined(CONFIG_MIPS_MT_SMP) 569 /* set up ipi interrupts */ 570 if (cpu_has_veic) { 571 set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch); 572 set_vi_handler (MSC01E_INT_SW1, ipi_call_dispatch); 573 cpu_ipi_resched_irq = MSC01E_INT_SW0; 574 cpu_ipi_call_irq = MSC01E_INT_SW1; 575 } else { 576 if (cpu_has_vint) { 577 set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, 578 ipi_resched_dispatch); 579 set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, 580 ipi_call_dispatch); 581 } 582 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + 583 MIPS_CPU_IPI_RESCHED_IRQ; 584 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + 585 MIPS_CPU_IPI_CALL_IRQ; 586 } 587 arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched); 588 arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); 589 #endif 590 } 591 } 592 593 void malta_be_init(void) 594 { 595 /* Could change CM error mask register. */ 596 } 597 598 599 static char *tr[8] = { 600 "mem", "gcr", "gic", "mmio", 601 "0x04", "0x05", "0x06", "0x07" 602 }; 603 604 static char *mcmd[32] = { 605 [0x00] = "0x00", 606 [0x01] = "Legacy Write", 607 [0x02] = "Legacy Read", 608 [0x03] = "0x03", 609 [0x04] = "0x04", 610 [0x05] = "0x05", 611 [0x06] = "0x06", 612 [0x07] = "0x07", 613 [0x08] = "Coherent Read Own", 614 [0x09] = "Coherent Read Share", 615 [0x0a] = "Coherent Read Discard", 616 [0x0b] = "Coherent Ready Share Always", 617 [0x0c] = "Coherent Upgrade", 618 [0x0d] = "Coherent Writeback", 619 [0x0e] = "0x0e", 620 [0x0f] = "0x0f", 621 [0x10] = "Coherent Copyback", 622 [0x11] = "Coherent Copyback Invalidate", 623 [0x12] = "Coherent Invalidate", 624 [0x13] = "Coherent Write Invalidate", 625 [0x14] = "Coherent Completion Sync", 626 [0x15] = "0x15", 627 [0x16] = "0x16", 628 [0x17] = "0x17", 629 [0x18] = "0x18", 630 [0x19] = "0x19", 631 [0x1a] = "0x1a", 632 [0x1b] = "0x1b", 633 [0x1c] = "0x1c", 634 [0x1d] = "0x1d", 635 [0x1e] = "0x1e", 636 [0x1f] = "0x1f" 637 }; 638 639 static char *core[8] = { 640 "Invalid/OK", "Invalid/Data", 641 "Shared/OK", "Shared/Data", 642 "Modified/OK", "Modified/Data", 643 "Exclusive/OK", "Exclusive/Data" 644 }; 645 646 static char *causes[32] = { 647 "None", "GC_WR_ERR", "GC_RD_ERR", "COH_WR_ERR", 648 "COH_RD_ERR", "MMIO_WR_ERR", "MMIO_RD_ERR", "0x07", 649 "0x08", "0x09", "0x0a", "0x0b", 650 "0x0c", "0x0d", "0x0e", "0x0f", 651 "0x10", "0x11", "0x12", "0x13", 652 "0x14", "0x15", "0x16", "INTVN_WR_ERR", 653 "INTVN_RD_ERR", "0x19", "0x1a", "0x1b", 654 "0x1c", "0x1d", "0x1e", "0x1f" 655 }; 656 657 int malta_be_handler(struct pt_regs *regs, int is_fixup) 658 { 659 /* This duplicates the handling in do_be which seems wrong */ 660 int retval = is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL; 661 662 if (mips_cm_present()) { 663 unsigned long cm_error = read_gcr_error_cause(); 664 unsigned long cm_addr = read_gcr_error_addr(); 665 unsigned long cm_other = read_gcr_error_mult(); 666 unsigned long cause, ocause; 667 char buf[256]; 668 669 cause = cm_error & CM_GCR_ERROR_CAUSE_ERRTYPE_MSK; 670 if (cause != 0) { 671 cause >>= CM_GCR_ERROR_CAUSE_ERRTYPE_SHF; 672 if (cause < 16) { 673 unsigned long cca_bits = (cm_error >> 15) & 7; 674 unsigned long tr_bits = (cm_error >> 12) & 7; 675 unsigned long cmd_bits = (cm_error >> 7) & 0x1f; 676 unsigned long stag_bits = (cm_error >> 3) & 15; 677 unsigned long sport_bits = (cm_error >> 0) & 7; 678 679 snprintf(buf, sizeof(buf), 680 "CCA=%lu TR=%s MCmd=%s STag=%lu " 681 "SPort=%lu\n", 682 cca_bits, tr[tr_bits], mcmd[cmd_bits], 683 stag_bits, sport_bits); 684 } else { 685 /* glob state & sresp together */ 686 unsigned long c3_bits = (cm_error >> 18) & 7; 687 unsigned long c2_bits = (cm_error >> 15) & 7; 688 unsigned long c1_bits = (cm_error >> 12) & 7; 689 unsigned long c0_bits = (cm_error >> 9) & 7; 690 unsigned long sc_bit = (cm_error >> 8) & 1; 691 unsigned long cmd_bits = (cm_error >> 3) & 0x1f; 692 unsigned long sport_bits = (cm_error >> 0) & 7; 693 snprintf(buf, sizeof(buf), 694 "C3=%s C2=%s C1=%s C0=%s SC=%s " 695 "MCmd=%s SPort=%lu\n", 696 core[c3_bits], core[c2_bits], 697 core[c1_bits], core[c0_bits], 698 sc_bit ? "True" : "False", 699 mcmd[cmd_bits], sport_bits); 700 } 701 702 ocause = (cm_other & CM_GCR_ERROR_MULT_ERR2ND_MSK) >> 703 CM_GCR_ERROR_MULT_ERR2ND_SHF; 704 705 pr_err("CM_ERROR=%08lx %s <%s>\n", cm_error, 706 causes[cause], buf); 707 pr_err("CM_ADDR =%08lx\n", cm_addr); 708 pr_err("CM_OTHER=%08lx %s\n", cm_other, causes[ocause]); 709 710 /* reprime cause register */ 711 write_gcr_error_cause(0); 712 } 713 } 714 715 return retval; 716 } 717 718 void gic_enable_interrupt(int irq_vec) 719 { 720 GIC_SET_INTR_MASK(irq_vec); 721 } 722 723 void gic_disable_interrupt(int irq_vec) 724 { 725 GIC_CLR_INTR_MASK(irq_vec); 726 } 727 728 void gic_irq_ack(struct irq_data *d) 729 { 730 int irq = (d->irq - gic_irq_base); 731 732 GIC_CLR_INTR_MASK(irq); 733 734 if (gic_irq_flags[irq] & GIC_TRIG_EDGE) 735 GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); 736 } 737 738 void gic_finish_irq(struct irq_data *d) 739 { 740 /* Enable interrupts. */ 741 GIC_SET_INTR_MASK(d->irq - gic_irq_base); 742 } 743 744 void __init gic_platform_init(int irqs, struct irq_chip *irq_controller) 745 { 746 int i; 747 748 for (i = gic_irq_base; i < (gic_irq_base + irqs); i++) 749 irq_set_chip(i, irq_controller); 750 } 751