summaryrefslogtreecommitdiffstats
path: root/arch/mips/mti-malta
diff options
context:
space:
mode:
authorAndrew Bresticker <abrestic@chromium.org>2014-09-18 17:47:24 -0400
committerRalf Baechle <ralf@linux-mips.org>2014-11-24 01:44:56 -0500
commit18743d2781d01d34d132f952a2e16353ccb4c3de (patch)
tree42df699518d3b44c08ef49fa3d893dc38d8ddc5e /arch/mips/mti-malta
parentc49581a4dfaade3a483f3db85581a2cdb6bb85a0 (diff)
irqchip: mips-gic: Stop using per-platform mapping tables
Now that the GIC properly uses IRQ domains, kill off the per-platform routing tables that were used to make the GIC appear transparent. This includes: - removing the mapping tables and the support for applying them, - moving GIC IPI support to the GIC driver, - properly routing the i8259 through the GIC on Malta, and - updating IRQ assignments on SEAD-3 when the GIC is present. Platforms no longer will pass an interrupt mapping table to gic_init. Instead, they will pass the CPU interrupt vector (2 - 7) that they expect the GIC to route interrupts to. Note that in EIC mode this value is ignored and all GIC interrupts are routed to EIC vector 1. Signed-off-by: Andrew Bresticker <abrestic@chromium.org> Acked-by: Jason Cooper <jason@lakedaemon.net> Reviewed-by: Qais Yousef <qais.yousef@imgtec.com> Tested-by: Qais Yousef <qais.yousef@imgtec.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Jeffrey Deans <jeffrey.deans@imgtec.com> Cc: Markos Chandras <markos.chandras@imgtec.com> Cc: Paul Burton <paul.burton@imgtec.com> Cc: Jonas Gorski <jogo@openwrt.org> Cc: John Crispin <blogic@openwrt.org> Cc: David Daney <ddaney.cavm@gmail.com> Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/7816/ 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.c189
1 files changed, 36 insertions, 153 deletions
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index e56563c6f89e..3b3bc1d9ebf9 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -38,14 +38,9 @@
38#include <asm/rtlx.h> 38#include <asm/rtlx.h>
39 39
40static unsigned long _msc01_biu_base; 40static unsigned long _msc01_biu_base;
41static unsigned int ipi_map[NR_CPUS];
42 41
43static DEFINE_RAW_SPINLOCK(mips_irq_lock); 42static DEFINE_RAW_SPINLOCK(mips_irq_lock);
44 43
45#ifdef CONFIG_MIPS_GIC_IPI
46DECLARE_BITMAP(ipi_ints, GIC_NUM_INTRS);
47#endif
48
49static inline int mips_pcibios_iack(void) 44static inline int mips_pcibios_iack(void)
50{ 45{
51 int irq; 46 int irq;
@@ -127,24 +122,10 @@ static void malta_hw0_irqdispatch(void)
127#endif 122#endif
128} 123}
129 124
130static void malta_ipi_irqdispatch(void) 125static irqreturn_t i8259_handler(int irq, void *dev_id)
131{ 126{
132#ifdef CONFIG_MIPS_GIC_IPI 127 malta_hw0_irqdispatch();
133 unsigned long irq; 128 return IRQ_HANDLED;
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} 129}
149 130
150static void corehi_irqdispatch(void) 131static void corehi_irqdispatch(void)
@@ -203,6 +184,12 @@ static void corehi_irqdispatch(void)
203 die("CoreHi interrupt", regs); 184 die("CoreHi interrupt", regs);
204} 185}
205 186
187static irqreturn_t corehi_handler(int irq, void *dev_id)
188{
189 corehi_irqdispatch();
190 return IRQ_HANDLED;
191}
192
206static inline int clz(unsigned long x) 193static inline int clz(unsigned long x)
207{ 194{
208 __asm__( 195 __asm__(
@@ -286,10 +273,9 @@ asmlinkage void plat_irq_dispatch(void)
286 273
287 irq = irq_ffs(pending); 274 irq = irq_ffs(pending);
288 275
289 if (irq == MIPSCPU_INT_I8259A) 276 /* HACK: GIC doesn't properly dispatch local interrupts yet */
290 malta_hw0_irqdispatch(); 277 if (gic_present && irq == MIPSCPU_INT_GIC && gic_compare_int())
291 else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()])) 278 do_IRQ(MIPS_GIC_IRQ_BASE);
292 malta_ipi_irqdispatch();
293 else 279 else
294 do_IRQ(MIPS_CPU_IRQ_BASE + irq); 280 do_IRQ(MIPS_CPU_IRQ_BASE + irq);
295} 281}
@@ -312,13 +298,6 @@ static void ipi_call_dispatch(void)
312 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); 298 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ);
313} 299}
314 300
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
322static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) 301static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
323{ 302{
324#ifdef CONFIG_MIPS_VPE_APSP_API_CMP 303#ifdef CONFIG_MIPS_VPE_APSP_API_CMP
@@ -349,31 +328,16 @@ static struct irqaction irq_call = {
349 .flags = IRQF_PERCPU, 328 .flags = IRQF_PERCPU,
350 .name = "IPI_call" 329 .name = "IPI_call"
351}; 330};
352#endif /* CONFIG_MIPS_GIC_IPI */ 331#endif /* CONFIG_MIPS_MT_SMP */
353
354static int gic_resched_int_base;
355static 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
359unsigned int plat_ipi_call_int_xlate(unsigned int cpu)
360{
361 return GIC_CALL_INT(cpu);
362}
363
364unsigned int plat_ipi_resched_int_xlate(unsigned int cpu)
365{
366 return GIC_RESCHED_INT(cpu);
367}
368 332
369static struct irqaction i8259irq = { 333static struct irqaction i8259irq = {
370 .handler = no_action, 334 .handler = i8259_handler,
371 .name = "XT-PIC cascade", 335 .name = "XT-PIC cascade",
372 .flags = IRQF_NO_THREAD, 336 .flags = IRQF_NO_THREAD,
373}; 337};
374 338
375static struct irqaction corehi_irqaction = { 339static struct irqaction corehi_irqaction = {
376 .handler = no_action, 340 .handler = corehi_handler,
377 .name = "CoreHi", 341 .name = "CoreHi",
378 .flags = IRQF_NO_THREAD, 342 .flags = IRQF_NO_THREAD,
379}; 343};
@@ -399,60 +363,6 @@ static msc_irqmap_t msc_eicirqmap[] __initdata = {
399 363
400static int msc_nr_eicirqs __initdata = ARRAY_SIZE(msc_eicirqmap); 364static int msc_nr_eicirqs __initdata = ARRAY_SIZE(msc_eicirqmap);
401 365
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
411static 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
433static 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
445static 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
456void __init arch_init_ipiirq(int irq, struct irqaction *action) 366void __init arch_init_ipiirq(int irq, struct irqaction *action)
457{ 367{
458 setup_irq(irq, action); 368 setup_irq(irq, action);
@@ -461,6 +371,8 @@ void __init arch_init_ipiirq(int irq, struct irqaction *action)
461 371
462void __init arch_init_irq(void) 372void __init arch_init_irq(void)
463{ 373{
374 int corehi_irq, i8259_irq;
375
464 init_i8259_irqs(); 376 init_i8259_irqs();
465 377
466 if (!cpu_has_veic) 378 if (!cpu_has_veic)
@@ -507,34 +419,11 @@ void __init arch_init_irq(void)
507 msc_nr_irqs); 419 msc_nr_irqs);
508 } 420 }
509 421
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) { 422 if (gic_present) {
528 /* FIXME */
529 int i; 423 int i;
530#if defined(CONFIG_MIPS_GIC_IPI) 424
531 gic_call_int_base = GIC_NUM_INTRS - 425 gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, MIPSCPU_INT_GIC,
532 (NR_CPUS - nr_cpu_ids) * 2 - nr_cpu_ids; 426 MIPS_GIC_IRQ_BASE);
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()) { 427 if (!mips_cm_present()) {
539 /* Enable the GIC */ 428 /* Enable the GIC */
540 i = REG(_msc01_biu_base, MSC01_SC_CFG); 429 i = REG(_msc01_biu_base, MSC01_SC_CFG);
@@ -542,28 +431,8 @@ void __init arch_init_irq(void)
542 (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); 431 (i | (0x1 << MSC01_SC_CFG_GICENA_SHF));
543 pr_debug("GIC Enabled\n"); 432 pr_debug("GIC Enabled\n");
544 } 433 }
545#if defined(CONFIG_MIPS_GIC_IPI) 434 i8259_irq = MIPS_GIC_IRQ_BASE + GIC_INT_I8259A;
546 /* set up ipi interrupts */ 435 corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI;
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 { 436 } else {
568#if defined(CONFIG_MIPS_MT_SMP) 437#if defined(CONFIG_MIPS_MT_SMP)
569 /* set up ipi interrupts */ 438 /* set up ipi interrupts */
@@ -587,7 +456,21 @@ void __init arch_init_irq(void)
587 arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched); 456 arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched);
588 arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); 457 arch_init_ipiirq(cpu_ipi_call_irq, &irq_call);
589#endif 458#endif
459 if (cpu_has_veic) {
460 set_vi_handler(MSC01E_INT_I8259A,
461 malta_hw0_irqdispatch);
462 set_vi_handler(MSC01E_INT_COREHI,
463 corehi_irqdispatch);
464 i8259_irq = MSC01E_INT_BASE + MSC01E_INT_I8259A;
465 corehi_irq = MSC01E_INT_BASE + MSC01E_INT_COREHI;
466 } else {
467 i8259_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_I8259A;
468 corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI;
469 }
590 } 470 }
471
472 setup_irq(i8259_irq, &i8259irq);
473 setup_irq(corehi_irq, &corehi_irqaction);
591} 474}
592 475
593void malta_be_init(void) 476void malta_be_init(void)