diff options
author | Chris Dearman <chris@mips.com> | 2009-07-10 04:54:09 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2009-11-02 06:00:06 -0500 |
commit | 7098f748283b4c056cca9c284c476b03f004ca12 (patch) | |
tree | 51d3f09abeabfe27dff3351a212b8c8a976ebba4 /arch/mips/mti-malta | |
parent | 2ee0a42961c942c6a2fb70700ef4e25c0acf5fca (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.c | 101 | ||||
-rw-r--r-- | arch/mips/mti-malta/malta-pci.c | 14 |
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 | ||
380 | static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); | 380 | static 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 | ||
388 | static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { | 389 | static 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 */ | ||
427 | int __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 */ | ||
435 | void __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) |
427 | static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) | 443 | static 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 | ||
465 | void __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 | |||
450 | void __init arch_init_irq(void) | 471 | void __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 | ||
593 | void malta_be_init(void) | 608 | void 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; |