aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mti-malta
diff options
context:
space:
mode:
authorChris Dearman <chris@mips.com>2009-07-10 04:54:09 -0400
committerRalf Baechle <ralf@linux-mips.org>2009-11-02 06:00:06 -0500
commit7098f748283b4c056cca9c284c476b03f004ca12 (patch)
tree51d3f09abeabfe27dff3351a212b8c8a976ebba4 /arch/mips/mti-malta
parent2ee0a42961c942c6a2fb70700ef4e25c0acf5fca (diff)
MIPS: GIC: Random fixes and enhancements.
Signed-off-by: Chris Dearman <chris@mips.com> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mti-malta')
-rw-r--r--arch/mips/mti-malta/malta-int.c101
-rw-r--r--arch/mips/mti-malta/malta-pci.c14
2 files changed, 69 insertions, 46 deletions
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index e568d0da060e..377a925e8cc6 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -379,32 +379,32 @@ static msc_irqmap_t __initdata msc_eicirqmap[] = {
379 379
380static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); 380static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap);
381 381
382#if defined(CONFIG_MIPS_MT_SMP)
383/* 382/*
384 * This GIC specific tabular array defines the association between External 383 * This GIC specific tabular array defines the association between External
385 * Interrupts and CPUs/Core Interrupts. The nature of the External 384 * Interrupts and CPUs/Core Interrupts. The nature of the External
386 * Interrupts is also defined here - polarity/trigger. 385 * Interrupts is also defined here - polarity/trigger.
387 */ 386 */
387
388#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK
388static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { 389static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
389 { GIC_EXT_INTR(0), X, X, X, X, 0 }, 390 { X, X, X, X, 0 },
390 { GIC_EXT_INTR(1), X, X, X, X, 0 }, 391 { X, X, X, X, 0 },
391 { GIC_EXT_INTR(2), X, X, X, X, 0 }, 392 { X, X, X, X, 0 },
392 { GIC_EXT_INTR(3), 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, 393 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
393 { GIC_EXT_INTR(4), 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, 394 { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
394 { GIC_EXT_INTR(5), 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, 395 { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
395 { GIC_EXT_INTR(6), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, 396 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
396 { GIC_EXT_INTR(7), 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, 397 { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
397 { GIC_EXT_INTR(8), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, 398 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
398 { GIC_EXT_INTR(9), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, 399 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
399 { GIC_EXT_INTR(10), X, X, X, X, 0 }, 400 { X, X, X, X, 0 },
400 { GIC_EXT_INTR(11), X, X, X, X, 0 }, 401 { X, X, X, X, 0 },
401 { GIC_EXT_INTR(12), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, 402 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
402 { GIC_EXT_INTR(13), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, 403 { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
403 { GIC_EXT_INTR(14), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, 404 { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
404 { GIC_EXT_INTR(15), X, X, X, X, 0 }, 405 { X, X, X, X, 0 },
405/* This is the end of the general interrupts now we do IPI ones */ 406 /* The remainder of this table is initialised by fill_ipi_map */
406}; 407};
407#endif
408 408
409/* 409/*
410 * GCMP needs to be detected before any SMP initialisation 410 * GCMP needs to be detected before any SMP initialisation
@@ -419,20 +419,35 @@ int __init gcmp_probe(unsigned long addr, unsigned long size)
419 gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR; 419 gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR;
420 420
421 if (gcmp_present) 421 if (gcmp_present)
422 printk(KERN_DEBUG "GCMP present\n"); 422 pr_debug("GCMP present\n");
423 return gcmp_present; 423 return gcmp_present;
424} 424}
425 425
426/* Return the number of IOCU's present */
427int __init gcmp_niocu(void)
428{
429 return gcmp_present ?
430 (GCMPGCB(GC) & GCMP_GCB_GC_NUMIOCU_MSK) >> GCMP_GCB_GC_NUMIOCU_SHF :
431 0;
432}
433
434/* Set GCMP region attributes */
435void __init gcmp_setregion(int region, unsigned long base,
436 unsigned long mask, int type)
437{
438 GCMPGCBn(CMxBASE, region) = base;
439 GCMPGCBn(CMxMASK, region) = mask | type;
440}
441
426#if defined(CONFIG_MIPS_MT_SMP) 442#if defined(CONFIG_MIPS_MT_SMP)
427static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) 443static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin)
428{ 444{
429 int intr = baseintr + cpu; 445 int intr = baseintr + cpu;
430 gic_intr_map[intr].intrnum = GIC_EXT_INTR(intr);
431 gic_intr_map[intr].cpunum = cpu; 446 gic_intr_map[intr].cpunum = cpu;
432 gic_intr_map[intr].pin = cpupin; 447 gic_intr_map[intr].pin = cpupin;
433 gic_intr_map[intr].polarity = GIC_POL_POS; 448 gic_intr_map[intr].polarity = GIC_POL_POS;
434 gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; 449 gic_intr_map[intr].trigtype = GIC_TRIG_EDGE;
435 gic_intr_map[intr].ipiflag = 1; 450 gic_intr_map[intr].flags = GIC_FLAG_IPI;
436 ipi_map[cpu] |= (1 << (cpupin + 2)); 451 ipi_map[cpu] |= (1 << (cpupin + 2));
437} 452}
438 453
@@ -447,6 +462,12 @@ static void __init fill_ipi_map(void)
447} 462}
448#endif 463#endif
449 464
465void __init arch_init_ipiirq(int irq, struct irqaction *action)
466{
467 setup_irq(irq, action);
468 set_irq_handler(irq, handle_percpu_irq);
469}
470
450void __init arch_init_irq(void) 471void __init arch_init_irq(void)
451{ 472{
452 init_i8259_irqs(); 473 init_i8259_irqs();
@@ -463,7 +484,7 @@ void __init arch_init_irq(void)
463 MSC01_SC_CFG_GICPRES_MSK) >> MSC01_SC_CFG_GICPRES_SHF; 484 MSC01_SC_CFG_GICPRES_MSK) >> MSC01_SC_CFG_GICPRES_SHF;
464 } 485 }
465 if (gic_present) 486 if (gic_present)
466 printk(KERN_DEBUG "GIC present\n"); 487 pr_debug("GIC present\n");
467 488
468 switch (mips_revision_sconid) { 489 switch (mips_revision_sconid) {
469 case MIPS_REVISION_SCON_SOCIT: 490 case MIPS_REVISION_SCON_SOCIT:
@@ -526,16 +547,16 @@ void __init arch_init_irq(void)
526 &corehi_irqaction); 547 &corehi_irqaction);
527 } 548 }
528 549
529#if defined(CONFIG_MIPS_MT_SMP)
530 if (gic_present) { 550 if (gic_present) {
531 /* FIXME */ 551 /* FIXME */
532 int i; 552 int i;
533 553#if defined(CONFIG_MIPS_MT_SMP)
534 gic_call_int_base = GIC_NUM_INTRS - NR_CPUS; 554 gic_call_int_base = GIC_NUM_INTRS - NR_CPUS;
535 gic_resched_int_base = gic_call_int_base - NR_CPUS; 555 gic_resched_int_base = gic_call_int_base - NR_CPUS;
536
537 fill_ipi_map(); 556 fill_ipi_map();
538 gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); 557#endif
558 gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map,
559 ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE);
539 if (!gcmp_present) { 560 if (!gcmp_present) {
540 /* Enable the GIC */ 561 /* Enable the GIC */
541 i = REG(_msc01_biu_base, MSC01_SC_CFG); 562 i = REG(_msc01_biu_base, MSC01_SC_CFG);
@@ -543,7 +564,7 @@ void __init arch_init_irq(void)
543 (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); 564 (i | (0x1 << MSC01_SC_CFG_GICENA_SHF));
544 pr_debug("GIC Enabled\n"); 565 pr_debug("GIC Enabled\n");
545 } 566 }
546 567#if defined(CONFIG_MIPS_MT_SMP)
547 /* set up ipi interrupts */ 568 /* set up ipi interrupts */
548 if (cpu_has_vint) { 569 if (cpu_has_vint) {
549 set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch); 570 set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch);
@@ -556,16 +577,14 @@ void __init arch_init_irq(void)
556 write_c0_status(0x1100dc00); 577 write_c0_status(0x1100dc00);
557 printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status()); 578 printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status());
558 for (i = 0; i < NR_CPUS; i++) { 579 for (i = 0; i < NR_CPUS; i++) {
559 setup_irq(MIPS_GIC_IRQ_BASE + 580 arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
560 GIC_RESCHED_INT(i), &irq_resched); 581 GIC_RESCHED_INT(i), &irq_resched);
561 setup_irq(MIPS_GIC_IRQ_BASE + 582 arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
562 GIC_CALL_INT(i), &irq_call); 583 GIC_CALL_INT(i), &irq_call);
563 set_irq_handler(MIPS_GIC_IRQ_BASE +
564 GIC_RESCHED_INT(i), handle_percpu_irq);
565 set_irq_handler(MIPS_GIC_IRQ_BASE +
566 GIC_CALL_INT(i), handle_percpu_irq);
567 } 584 }
585#endif
568 } else { 586 } else {
587#if defined(CONFIG_MIPS_MT_SMP)
569 /* set up ipi interrupts */ 588 /* set up ipi interrupts */
570 if (cpu_has_veic) { 589 if (cpu_has_veic) {
571 set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch); 590 set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch);
@@ -580,14 +599,10 @@ void __init arch_init_irq(void)
580 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ; 599 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
581 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ; 600 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ;
582 } 601 }
583 602 arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched);
584 setup_irq(cpu_ipi_resched_irq, &irq_resched); 603 arch_init_ipiirq(cpu_ipi_call_irq, &irq_call);
585 setup_irq(cpu_ipi_call_irq, &irq_call);
586
587 set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq);
588 set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq);
589 }
590#endif 604#endif
605 }
591} 606}
592 607
593void malta_be_init(void) 608void malta_be_init(void)
diff --git a/arch/mips/mti-malta/malta-pci.c b/arch/mips/mti-malta/malta-pci.c
index efdb4f66ffcf..2fbfa1a8c3a9 100644
--- a/arch/mips/mti-malta/malta-pci.c
+++ b/arch/mips/mti-malta/malta-pci.c
@@ -27,7 +27,7 @@
27#include <linux/init.h> 27#include <linux/init.h>
28 28
29#include <asm/gt64120.h> 29#include <asm/gt64120.h>
30 30#include <asm/gcmpregs.h>
31#include <asm/mips-boards/generic.h> 31#include <asm/mips-boards/generic.h>
32#include <asm/mips-boards/bonito64.h> 32#include <asm/mips-boards/bonito64.h>
33#include <asm/mips-boards/msc01_pci.h> 33#include <asm/mips-boards/msc01_pci.h>
@@ -201,7 +201,11 @@ void __init mips_pcibios_init(void)
201 msc_mem_resource.start = start & mask; 201 msc_mem_resource.start = start & mask;
202 msc_mem_resource.end = (start & mask) | ~mask; 202 msc_mem_resource.end = (start & mask) | ~mask;
203 msc_controller.mem_offset = (start & mask) - (map & mask); 203 msc_controller.mem_offset = (start & mask) - (map & mask);
204 204#ifdef CONFIG_MIPS_CMP
205 if (gcmp_niocu())
206 gcmp_setregion(0, start, mask,
207 GCMP_GCB_GCMPB_CMDEFTGT_IOCU1);
208#endif
205 MSC_READ(MSC01_PCI_SC2PIOBASL, start); 209 MSC_READ(MSC01_PCI_SC2PIOBASL, start);
206 MSC_READ(MSC01_PCI_SC2PIOMSKL, mask); 210 MSC_READ(MSC01_PCI_SC2PIOMSKL, mask);
207 MSC_READ(MSC01_PCI_SC2PIOMAPL, map); 211 MSC_READ(MSC01_PCI_SC2PIOMAPL, map);
@@ -209,7 +213,11 @@ void __init mips_pcibios_init(void)
209 msc_io_resource.end = (map & mask) | ~mask; 213 msc_io_resource.end = (map & mask) | ~mask;
210 msc_controller.io_offset = 0; 214 msc_controller.io_offset = 0;
211 ioport_resource.end = ~mask; 215 ioport_resource.end = ~mask;
212 216#ifdef CONFIG_MIPS_CMP
217 if (gcmp_niocu())
218 gcmp_setregion(1, start, mask,
219 GCMP_GCB_GCMPB_CMDEFTGT_IOCU1);
220#endif
213 /* If ranges overlap I/O takes precedence. */ 221 /* If ranges overlap I/O takes precedence. */
214 start = start & mask; 222 start = start & mask;
215 end = start | ~mask; 223 end = start | ~mask;