aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--arch/mips/include/asm/gic.h35
-rw-r--r--arch/mips/include/asm/mips-boards/maltaint.h14
-rw-r--r--arch/mips/include/asm/mips-boards/sead3int.h13
-rw-r--r--arch/mips/kernel/cevt-gic.c3
-rw-r--r--arch/mips/mti-malta/malta-int.c189
-rw-r--r--arch/mips/mti-sead3/sead3-ehci.c8
-rw-r--r--arch/mips/mti-sead3/sead3-int.c28
-rw-r--r--arch/mips/mti-sead3/sead3-net.c14
-rw-r--r--arch/mips/mti-sead3/sead3-platform.c18
-rw-r--r--drivers/irqchip/irq-mips-gic.c201
10 files changed, 198 insertions, 325 deletions
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h
index efcf4dec1229..cfbf907ebfa5 100644
--- a/arch/mips/include/asm/gic.h
+++ b/arch/mips/include/asm/gic.h
@@ -316,31 +316,6 @@
316 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \ 316 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \
317 GIC_SH_MAP_TO_VPE_REG_BIT(vpe)) 317 GIC_SH_MAP_TO_VPE_REG_BIT(vpe))
318 318
319/*
320 * Interrupt Meta-data specification. The ipiflag helps
321 * in building ipi_map.
322 */
323struct gic_intr_map {
324 unsigned int cpunum; /* Directed to this CPU */
325#define GIC_UNUSED 0xdead /* Dummy data */
326 unsigned int pin; /* Directed to this Pin */
327 unsigned int polarity; /* Polarity : +/- */
328 unsigned int trigtype; /* Trigger : Edge/Levl */
329 unsigned int flags; /* Misc flags */
330#define GIC_FLAG_TRANSPARENT 0x01
331};
332
333/*
334 * This is only used in EIC mode. This helps to figure out which
335 * shared interrupts we need to process when we get a vector interrupt.
336 */
337#define GIC_MAX_SHARED_INTR 0x5
338struct gic_shared_intr_map {
339 unsigned int num_shared_intr;
340 unsigned int intr_list[GIC_MAX_SHARED_INTR];
341 unsigned int local_intr_mask;
342};
343
344/* GIC nomenclature for Core Interrupt Pins. */ 319/* GIC nomenclature for Core Interrupt Pins. */
345#define GIC_CPU_INT0 0 /* Core Interrupt 2 */ 320#define GIC_CPU_INT0 0 /* Core Interrupt 2 */
346#define GIC_CPU_INT1 1 /* . */ 321#define GIC_CPU_INT1 1 /* . */
@@ -349,6 +324,9 @@ struct gic_shared_intr_map {
349#define GIC_CPU_INT4 4 /* . */ 324#define GIC_CPU_INT4 4 /* . */
350#define GIC_CPU_INT5 5 /* Core Interrupt 7 */ 325#define GIC_CPU_INT5 5 /* Core Interrupt 7 */
351 326
327/* Add 2 to convert GIC CPU pin to core interrupt */
328#define GIC_CPU_PIN_OFFSET 2
329
352/* Local GIC interrupts. */ 330/* Local GIC interrupts. */
353#define GIC_INT_TMR (GIC_CPU_INT5) 331#define GIC_INT_TMR (GIC_CPU_INT5)
354#define GIC_INT_PERFCTR (GIC_CPU_INT5) 332#define GIC_INT_PERFCTR (GIC_CPU_INT5)
@@ -365,13 +343,12 @@ struct gic_shared_intr_map {
365extern unsigned int gic_present; 343extern unsigned int gic_present;
366extern unsigned int gic_frequency; 344extern unsigned int gic_frequency;
367extern unsigned long _gic_base; 345extern unsigned long _gic_base;
368extern unsigned int gic_irq_base;
369extern unsigned int gic_irq_flags[]; 346extern unsigned int gic_irq_flags[];
370extern struct gic_shared_intr_map gic_shared_intr_map[]; 347extern unsigned int gic_cpu_pin;
371 348
372extern void gic_init(unsigned long gic_base_addr, 349extern void gic_init(unsigned long gic_base_addr,
373 unsigned long gic_addrspace_size, struct gic_intr_map *intrmap, 350 unsigned long gic_addrspace_size, unsigned int cpu_vec,
374 unsigned int intrmap_size, unsigned int irqbase); 351 unsigned int irqbase);
375extern void gic_clocksource_init(unsigned int); 352extern void gic_clocksource_init(unsigned int);
376extern unsigned int gic_compare_int (void); 353extern unsigned int gic_compare_int (void);
377extern cycle_t gic_read_count(void); 354extern cycle_t gic_read_count(void);
diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h
index d741628e3397..bdd6f392f160 100644
--- a/arch/mips/include/asm/mips-boards/maltaint.h
+++ b/arch/mips/include/asm/mips-boards/maltaint.h
@@ -20,11 +20,10 @@
20#define MIPSCPU_INT_SW1 1 20#define MIPSCPU_INT_SW1 1
21#define MIPSCPU_INT_MB0 2 21#define MIPSCPU_INT_MB0 2
22#define MIPSCPU_INT_I8259A MIPSCPU_INT_MB0 22#define MIPSCPU_INT_I8259A MIPSCPU_INT_MB0
23#define MIPSCPU_INT_GIC MIPSCPU_INT_MB0 /* GIC chained interrupt */
23#define MIPSCPU_INT_MB1 3 24#define MIPSCPU_INT_MB1 3
24#define MIPSCPU_INT_SMI MIPSCPU_INT_MB1 25#define MIPSCPU_INT_SMI MIPSCPU_INT_MB1
25#define MIPSCPU_INT_IPI0 MIPSCPU_INT_MB1 /* GIC IPI */
26#define MIPSCPU_INT_MB2 4 26#define MIPSCPU_INT_MB2 4
27#define MIPSCPU_INT_IPI1 MIPSCPU_INT_MB2 /* GIC IPI */
28#define MIPSCPU_INT_MB3 5 27#define MIPSCPU_INT_MB3 5
29#define MIPSCPU_INT_COREHI MIPSCPU_INT_MB3 28#define MIPSCPU_INT_COREHI MIPSCPU_INT_MB3
30#define MIPSCPU_INT_MB4 6 29#define MIPSCPU_INT_MB4 6
@@ -61,14 +60,7 @@
61#define MSC01E_INT_PERFCTR 10 60#define MSC01E_INT_PERFCTR 10
62#define MSC01E_INT_CPUCTR 11 61#define MSC01E_INT_CPUCTR 11
63 62
64/* External Interrupts used for IPI */ 63/* GIC external interrupts */
65#define GIC_IPI_EXT_INTR_RESCHED_VPE0 16 64#define GIC_INT_I8259A 3
66#define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17
67#define GIC_IPI_EXT_INTR_RESCHED_VPE1 18
68#define GIC_IPI_EXT_INTR_CALLFNC_VPE1 19
69#define GIC_IPI_EXT_INTR_RESCHED_VPE2 20
70#define GIC_IPI_EXT_INTR_CALLFNC_VPE2 21
71#define GIC_IPI_EXT_INTR_RESCHED_VPE3 22
72#define GIC_IPI_EXT_INTR_CALLFNC_VPE3 23
73 65
74#endif /* !(_MIPS_MALTAINT_H) */ 66#endif /* !(_MIPS_MALTAINT_H) */
diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h
index 11ebec94f807..a2e0095440fe 100644
--- a/arch/mips/include/asm/mips-boards/sead3int.h
+++ b/arch/mips/include/asm/mips-boards/sead3int.h
@@ -14,4 +14,17 @@
14#define GIC_BASE_ADDR 0x1b1c0000 14#define GIC_BASE_ADDR 0x1b1c0000
15#define GIC_ADDRSPACE_SZ (128 * 1024) 15#define GIC_ADDRSPACE_SZ (128 * 1024)
16 16
17/* CPU interrupt offsets */
18#define CPU_INT_GIC 2
19#define CPU_INT_EHCI 2
20#define CPU_INT_UART0 4
21#define CPU_INT_UART1 4
22#define CPU_INT_NET 6
23
24/* GIC interrupt offsets */
25#define GIC_INT_NET 0
26#define GIC_INT_UART1 2
27#define GIC_INT_UART0 3
28#define GIC_INT_EHCI 5
29
17#endif /* !(_MIPS_SEAD3INT_H) */ 30#endif /* !(_MIPS_SEAD3INT_H) */
diff --git a/arch/mips/kernel/cevt-gic.c b/arch/mips/kernel/cevt-gic.c
index 6093716980b9..a90bd4c81c7d 100644
--- a/arch/mips/kernel/cevt-gic.c
+++ b/arch/mips/kernel/cevt-gic.c
@@ -91,7 +91,8 @@ int gic_clockevent_init(void)
91 91
92 clockevents_register_device(cd); 92 clockevents_register_device(cd);
93 93
94 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_MAP), 0x80000002); 94 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_MAP),
95 GIC_MAP_TO_PIN_MSK | gic_cpu_pin);
95 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), GIC_VPE_SMASK_CMP_MSK); 96 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), GIC_VPE_SMASK_CMP_MSK);
96 97
97 if (gic_timer_irq_installed) 98 if (gic_timer_irq_installed)
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)
diff --git a/arch/mips/mti-sead3/sead3-ehci.c b/arch/mips/mti-sead3/sead3-ehci.c
index 772fc056a92d..4ddaa0fd5804 100644
--- a/arch/mips/mti-sead3/sead3-ehci.c
+++ b/arch/mips/mti-sead3/sead3-ehci.c
@@ -10,6 +10,9 @@
10#include <linux/dma-mapping.h> 10#include <linux/dma-mapping.h>
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12 12
13#include <asm/gic.h>
14#include <asm/mips-boards/sead3int.h>
15
13struct resource ehci_resources[] = { 16struct resource ehci_resources[] = {
14 { 17 {
15 .start = 0x1b200000, 18 .start = 0x1b200000,
@@ -17,7 +20,6 @@ struct resource ehci_resources[] = {
17 .flags = IORESOURCE_MEM 20 .flags = IORESOURCE_MEM
18 }, 21 },
19 { 22 {
20 .start = MIPS_CPU_IRQ_BASE + 2,
21 .flags = IORESOURCE_IRQ 23 .flags = IORESOURCE_IRQ
22 } 24 }
23}; 25};
@@ -37,6 +39,10 @@ static struct platform_device ehci_device = {
37 39
38static int __init ehci_init(void) 40static int __init ehci_init(void)
39{ 41{
42 if (gic_present)
43 ehci_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_EHCI;
44 else
45 ehci_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_EHCI;
40 return platform_device_register(&ehci_device); 46 return platform_device_register(&ehci_device);
41} 47}
42 48
diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c
index 8f3634281ed9..cb06cd954a13 100644
--- a/arch/mips/mti-sead3/sead3-int.c
+++ b/arch/mips/mti-sead3/sead3-int.c
@@ -22,30 +22,6 @@
22 22
23static unsigned long sead3_config_reg; 23static unsigned long sead3_config_reg;
24 24
25/*
26 * This table defines the setup for each external GIC interrupt. It is
27 * indexed by interrupt number.
28 */
29#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK
30static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
31 { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
32 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
33 { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
34 { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
35 { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
36 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
37 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
38 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
39 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
40 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
41 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
42 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
43 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
44 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
45 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
46 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
47};
48
49asmlinkage void plat_irq_dispatch(void) 25asmlinkage void plat_irq_dispatch(void)
50{ 26{
51 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; 27 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
@@ -81,7 +57,7 @@ void __init arch_init_irq(void)
81 (current_cpu_data.options & MIPS_CPU_VEIC) ? "on" : "off"); 57 (current_cpu_data.options & MIPS_CPU_VEIC) ? "on" : "off");
82 58
83 if (gic_present) 59 if (gic_present)
84 gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, 60 gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, CPU_INT_GIC,
85 ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); 61 MIPS_GIC_IRQ_BASE);
86} 62}
87 63
diff --git a/arch/mips/mti-sead3/sead3-net.c b/arch/mips/mti-sead3/sead3-net.c
index dd11e7eb771c..c9f728a41bdb 100644
--- a/arch/mips/mti-sead3/sead3-net.c
+++ b/arch/mips/mti-sead3/sead3-net.c
@@ -10,6 +10,9 @@
10#include <linux/platform_device.h> 10#include <linux/platform_device.h>
11#include <linux/smsc911x.h> 11#include <linux/smsc911x.h>
12 12
13#include <asm/gic.h>
14#include <asm/mips-boards/sead3int.h>
15
13static struct smsc911x_platform_config sead3_smsc911x_data = { 16static struct smsc911x_platform_config sead3_smsc911x_data = {
14 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, 17 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
15 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, 18 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
@@ -17,14 +20,13 @@ static struct smsc911x_platform_config sead3_smsc911x_data = {
17 .phy_interface = PHY_INTERFACE_MODE_MII, 20 .phy_interface = PHY_INTERFACE_MODE_MII,
18}; 21};
19 22
20struct resource sead3_net_resourcess[] = { 23struct resource sead3_net_resources[] = {
21 { 24 {
22 .start = 0x1f010000, 25 .start = 0x1f010000,
23 .end = 0x1f01ffff, 26 .end = 0x1f01ffff,
24 .flags = IORESOURCE_MEM 27 .flags = IORESOURCE_MEM
25 }, 28 },
26 { 29 {
27 .start = MIPS_CPU_IRQ_BASE + 6,
28 .flags = IORESOURCE_IRQ 30 .flags = IORESOURCE_IRQ
29 } 31 }
30}; 32};
@@ -35,12 +37,16 @@ static struct platform_device sead3_net_device = {
35 .dev = { 37 .dev = {
36 .platform_data = &sead3_smsc911x_data, 38 .platform_data = &sead3_smsc911x_data,
37 }, 39 },
38 .num_resources = ARRAY_SIZE(sead3_net_resourcess), 40 .num_resources = ARRAY_SIZE(sead3_net_resources),
39 .resource = sead3_net_resourcess 41 .resource = sead3_net_resources
40}; 42};
41 43
42static int __init sead3_net_init(void) 44static int __init sead3_net_init(void)
43{ 45{
46 if (gic_present)
47 sead3_net_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_NET;
48 else
49 sead3_net_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_NET;
44 return platform_device_register(&sead3_net_device); 50 return platform_device_register(&sead3_net_device);
45} 51}
46 52
diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c
index 6c3b33dbed18..d9661eb6fd6d 100644
--- a/arch/mips/mti-sead3/sead3-platform.c
+++ b/arch/mips/mti-sead3/sead3-platform.c
@@ -9,10 +9,13 @@
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/serial_8250.h> 10#include <linux/serial_8250.h>
11 11
12#define UART(base, int) \ 12#include <asm/gic.h>
13#include <asm/mips-boards/sead3int.h>
14
15#define UART(base) \
13{ \ 16{ \
14 .mapbase = base, \ 17 .mapbase = base, \
15 .irq = int, \ 18 .irq = -1, \
16 .uartclk = 14745600, \ 19 .uartclk = 14745600, \
17 .iotype = UPIO_MEM32, \ 20 .iotype = UPIO_MEM32, \
18 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \ 21 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \
@@ -20,8 +23,8 @@
20} 23}
21 24
22static struct plat_serial8250_port uart8250_data[] = { 25static struct plat_serial8250_port uart8250_data[] = {
23 UART(0x1f000900, MIPS_CPU_IRQ_BASE + 4), /* ttyS0 = USB */ 26 UART(0x1f000900), /* ttyS0 = USB */
24 UART(0x1f000800, MIPS_CPU_IRQ_BASE + 4), /* ttyS1 = RS232 */ 27 UART(0x1f000800), /* ttyS1 = RS232 */
25 { }, 28 { },
26}; 29};
27 30
@@ -35,6 +38,13 @@ static struct platform_device uart8250_device = {
35 38
36static int __init uart8250_init(void) 39static int __init uart8250_init(void)
37{ 40{
41 if (gic_present) {
42 uart8250_data[0].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART0;
43 uart8250_data[1].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART1;
44 } else {
45 uart8250_data[0].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART0;
46 uart8250_data[1].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART1;
47 }
38 return platform_device_register(&uart8250_device); 48 return platform_device_register(&uart8250_device);
39} 49}
40 50
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 79ab99781534..633a34639388 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -8,6 +8,8 @@
8 */ 8 */
9#include <linux/bitmap.h> 9#include <linux/bitmap.h>
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/interrupt.h>
12#include <linux/sched.h>
11#include <linux/smp.h> 13#include <linux/smp.h>
12#include <linux/irq.h> 14#include <linux/irq.h>
13#include <linux/clocksource.h> 15#include <linux/clocksource.h>
@@ -22,11 +24,8 @@
22unsigned int gic_frequency; 24unsigned int gic_frequency;
23unsigned int gic_present; 25unsigned int gic_present;
24unsigned long _gic_base; 26unsigned long _gic_base;
25unsigned int gic_irq_base;
26unsigned int gic_irq_flags[GIC_NUM_INTRS]; 27unsigned int gic_irq_flags[GIC_NUM_INTRS];
27 28unsigned int gic_cpu_pin;
28/* The index into this array is the vector # of the interrupt. */
29struct gic_shared_intr_map gic_shared_intr_map[GIC_NUM_INTRS];
30 29
31struct gic_pcpu_mask { 30struct gic_pcpu_mask {
32 DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS); 31 DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS);
@@ -46,6 +45,8 @@ static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
46static DEFINE_SPINLOCK(gic_lock); 45static DEFINE_SPINLOCK(gic_lock);
47static struct irq_domain *gic_irq_domain; 46static struct irq_domain *gic_irq_domain;
48 47
48static void __gic_irq_dispatch(void);
49
49#if defined(CONFIG_CSRC_GIC) || defined(CONFIG_CEVT_GIC) 50#if defined(CONFIG_CSRC_GIC) || defined(CONFIG_CEVT_GIC)
50cycle_t gic_read_count(void) 51cycle_t gic_read_count(void)
51{ 52{
@@ -117,21 +118,6 @@ void gic_send_ipi(unsigned int intr)
117 GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr); 118 GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr);
118} 119}
119 120
120static void gic_eic_irq_dispatch(void)
121{
122 unsigned int cause = read_c0_cause();
123 int irq;
124
125 irq = (cause & ST0_IM) >> STATUSB_IP2;
126 if (irq == 0)
127 irq = -1;
128
129 if (irq >= 0)
130 do_IRQ(gic_irq_base + irq);
131 else
132 spurious_interrupt();
133}
134
135static void __init vpe_local_setup(unsigned int numvpes) 121static void __init vpe_local_setup(unsigned int numvpes)
136{ 122{
137 unsigned long timer_intr = GIC_INT_TMR; 123 unsigned long timer_intr = GIC_INT_TMR;
@@ -166,16 +152,15 @@ static void __init vpe_local_setup(unsigned int numvpes)
166 GIC_MAP_TO_PIN_MSK | timer_intr); 152 GIC_MAP_TO_PIN_MSK | timer_intr);
167 if (cpu_has_veic) { 153 if (cpu_has_veic) {
168 set_vi_handler(timer_intr + GIC_PIN_TO_VEC_OFFSET, 154 set_vi_handler(timer_intr + GIC_PIN_TO_VEC_OFFSET,
169 gic_eic_irq_dispatch); 155 __gic_irq_dispatch);
170 gic_shared_intr_map[timer_intr + GIC_PIN_TO_VEC_OFFSET].local_intr_mask |= GIC_VPE_RMASK_TIMER_MSK;
171 } 156 }
172 157
173 if (vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK) 158 if (vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK)
174 GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP), 159 GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP),
175 GIC_MAP_TO_PIN_MSK | perf_intr); 160 GIC_MAP_TO_PIN_MSK | perf_intr);
176 if (cpu_has_veic) { 161 if (cpu_has_veic) {
177 set_vi_handler(perf_intr + GIC_PIN_TO_VEC_OFFSET, gic_eic_irq_dispatch); 162 set_vi_handler(perf_intr + GIC_PIN_TO_VEC_OFFSET,
178 gic_shared_intr_map[perf_intr + GIC_PIN_TO_VEC_OFFSET].local_intr_mask |= GIC_VPE_RMASK_PERFCNT_MSK; 163 __gic_irq_dispatch);
179 } 164 }
180 } 165 }
181} 166}
@@ -343,64 +328,100 @@ static struct irq_chip gic_irq_controller = {
343#endif 328#endif
344}; 329};
345 330
346static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, 331static void __gic_irq_dispatch(void)
347 unsigned int pin, unsigned int polarity, unsigned int trigtype,
348 unsigned int flags)
349{ 332{
350 struct gic_shared_intr_map *map_ptr; 333 unsigned int intr, virq;
351 int i;
352
353 /* Setup Intr to Pin mapping */
354 if (pin & GIC_MAP_TO_NMI_MSK) {
355 int i;
356 334
357 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin); 335 while ((intr = gic_get_int()) != GIC_NUM_INTRS) {
358 /* FIXME: hack to route NMI to all cpu's */ 336 virq = irq_linear_revmap(gic_irq_domain, intr);
359 for (i = 0; i < NR_CPUS; i += 32) { 337 do_IRQ(virq);
360 GICWRITE(GIC_REG_ADDR(SHARED,
361 GIC_SH_MAP_TO_VPE_REG_OFF(intr, i)),
362 0xffffffff);
363 }
364 } else {
365 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)),
366 GIC_MAP_TO_PIN_MSK | pin);
367 /* Setup Intr to CPU mapping */
368 GIC_SH_MAP_TO_VPE_SMASK(intr, cpu);
369 if (cpu_has_veic) {
370 set_vi_handler(pin + GIC_PIN_TO_VEC_OFFSET,
371 gic_eic_irq_dispatch);
372 map_ptr = &gic_shared_intr_map[pin + GIC_PIN_TO_VEC_OFFSET];
373 if (map_ptr->num_shared_intr >= GIC_MAX_SHARED_INTR)
374 BUG();
375 map_ptr->intr_list[map_ptr->num_shared_intr++] = intr;
376 }
377 } 338 }
339}
378 340
379 /* Setup Intr Polarity */ 341static void gic_irq_dispatch(unsigned int irq, struct irq_desc *desc)
380 GIC_SET_POLARITY(intr, polarity); 342{
343 __gic_irq_dispatch();
344}
345
346#ifdef CONFIG_MIPS_GIC_IPI
347static int gic_resched_int_base;
348static int gic_call_int_base;
349
350unsigned int plat_ipi_resched_int_xlate(unsigned int cpu)
351{
352 return gic_resched_int_base + cpu;
353}
381 354
382 /* Setup Intr Trigger Type */ 355unsigned int plat_ipi_call_int_xlate(unsigned int cpu)
383 GIC_SET_TRIGGER(intr, trigtype); 356{
357 return gic_call_int_base + cpu;
358}
384 359
385 /* Init Intr Masks */ 360static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
386 GIC_CLR_INTR_MASK(intr); 361{
362 scheduler_ipi();
363
364 return IRQ_HANDLED;
365}
366
367static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
368{
369 smp_call_function_interrupt();
370
371 return IRQ_HANDLED;
372}
387 373
388 /* Initialise per-cpu Interrupt software masks */ 374static struct irqaction irq_resched = {
375 .handler = ipi_resched_interrupt,
376 .flags = IRQF_PERCPU,
377 .name = "IPI resched"
378};
379
380static struct irqaction irq_call = {
381 .handler = ipi_call_interrupt,
382 .flags = IRQF_PERCPU,
383 .name = "IPI call"
384};
385
386static __init void gic_ipi_init_one(unsigned int intr, int cpu,
387 struct irqaction *action)
388{
389 int virq = irq_create_mapping(gic_irq_domain, intr);
390 int i;
391
392 GIC_SH_MAP_TO_VPE_SMASK(intr, cpu);
389 for (i = 0; i < NR_CPUS; i++) 393 for (i = 0; i < NR_CPUS; i++)
390 clear_bit(intr, pcpu_masks[i].pcpu_mask); 394 clear_bit(intr, pcpu_masks[i].pcpu_mask);
391 set_bit(intr, pcpu_masks[cpu].pcpu_mask); 395 set_bit(intr, pcpu_masks[cpu].pcpu_mask);
392 396
393 if ((flags & GIC_FLAG_TRANSPARENT) && (cpu_has_veic == 0)) 397 irq_set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
394 GIC_SET_INTR_MASK(intr); 398
395 if (trigtype == GIC_TRIG_EDGE) 399 irq_set_handler(virq, handle_percpu_irq);
396 gic_irq_flags[intr] |= GIC_TRIG_EDGE; 400 setup_irq(virq, action);
397} 401}
398 402
399static void __init gic_basic_init(int numintrs, int numvpes, 403static __init void gic_ipi_init(void)
400 struct gic_intr_map *intrmap, int mapsize)
401{ 404{
402 unsigned int i, cpu; 405 int i;
403 unsigned int pin_offset = 0; 406
407 /* Use last 2 * NR_CPUS interrupts as IPIs */
408 gic_resched_int_base = GIC_NUM_INTRS - nr_cpu_ids;
409 gic_call_int_base = gic_resched_int_base - nr_cpu_ids;
410
411 for (i = 0; i < nr_cpu_ids; i++) {
412 gic_ipi_init_one(gic_call_int_base + i, i, &irq_call);
413 gic_ipi_init_one(gic_resched_int_base + i, i, &irq_resched);
414 }
415}
416#else
417static inline void gic_ipi_init(void)
418{
419}
420#endif
421
422static void __init gic_basic_init(int numintrs, int numvpes)
423{
424 unsigned int i;
404 425
405 board_bind_eic_interrupt = &gic_bind_eic_interrupt; 426 board_bind_eic_interrupt = &gic_bind_eic_interrupt;
406 427
@@ -409,31 +430,8 @@ static void __init gic_basic_init(int numintrs, int numvpes,
409 GIC_SET_POLARITY(i, GIC_POL_POS); 430 GIC_SET_POLARITY(i, GIC_POL_POS);
410 GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL); 431 GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL);
411 GIC_CLR_INTR_MASK(i); 432 GIC_CLR_INTR_MASK(i);
412 if (i < GIC_NUM_INTRS) { 433 if (i < GIC_NUM_INTRS)
413 gic_irq_flags[i] = 0; 434 gic_irq_flags[i] = 0;
414 gic_shared_intr_map[i].num_shared_intr = 0;
415 gic_shared_intr_map[i].local_intr_mask = 0;
416 }
417 }
418
419 /*
420 * In EIC mode, the HW_INT# is offset by (2-1). Need to subtract
421 * one because the GIC will add one (since 0=no intr).
422 */
423 if (cpu_has_veic)
424 pin_offset = (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET);
425
426 /* Setup specifics */
427 for (i = 0; i < mapsize; i++) {
428 cpu = intrmap[i].cpunum;
429 if (cpu == GIC_UNUSED)
430 continue;
431 gic_setup_intr(i,
432 intrmap[i].cpunum,
433 intrmap[i].pin + pin_offset,
434 intrmap[i].polarity,
435 intrmap[i].trigtype,
436 intrmap[i].flags);
437 } 435 }
438 436
439 vpe_local_setup(numvpes); 437 vpe_local_setup(numvpes);
@@ -448,7 +446,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
448 446
449 spin_lock_irqsave(&gic_lock, flags); 447 spin_lock_irqsave(&gic_lock, flags);
450 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(hw)), 448 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(hw)),
451 GIC_MAP_TO_PIN_MSK | 0); 449 GIC_MAP_TO_PIN_MSK | gic_cpu_pin);
452 /* Map to VPE 0 by default */ 450 /* Map to VPE 0 by default */
453 GIC_SH_MAP_TO_VPE_SMASK(hw, 0); 451 GIC_SH_MAP_TO_VPE_SMASK(hw, 0);
454 set_bit(hw, pcpu_masks[0].pcpu_mask); 452 set_bit(hw, pcpu_masks[0].pcpu_mask);
@@ -463,8 +461,7 @@ static struct irq_domain_ops gic_irq_domain_ops = {
463}; 461};
464 462
465void __init gic_init(unsigned long gic_base_addr, 463void __init gic_init(unsigned long gic_base_addr,
466 unsigned long gic_addrspace_size, 464 unsigned long gic_addrspace_size, unsigned int cpu_vec,
467 struct gic_intr_map *intr_map, unsigned int intr_map_size,
468 unsigned int irqbase) 465 unsigned int irqbase)
469{ 466{
470 unsigned int gicconfig; 467 unsigned int gicconfig;
@@ -472,7 +469,6 @@ void __init gic_init(unsigned long gic_base_addr,
472 469
473 _gic_base = (unsigned long) ioremap_nocache(gic_base_addr, 470 _gic_base = (unsigned long) ioremap_nocache(gic_base_addr,
474 gic_addrspace_size); 471 gic_addrspace_size);
475 gic_irq_base = irqbase;
476 472
477 GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); 473 GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
478 numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> 474 numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >>
@@ -483,10 +479,23 @@ void __init gic_init(unsigned long gic_base_addr,
483 GIC_SH_CONFIG_NUMVPES_SHF; 479 GIC_SH_CONFIG_NUMVPES_SHF;
484 numvpes = numvpes + 1; 480 numvpes = numvpes + 1;
485 481
482 if (cpu_has_veic) {
483 /* Always use vector 1 in EIC mode */
484 gic_cpu_pin = 0;
485 set_vi_handler(gic_cpu_pin + GIC_PIN_TO_VEC_OFFSET,
486 __gic_irq_dispatch);
487 } else {
488 gic_cpu_pin = cpu_vec - GIC_CPU_PIN_OFFSET;
489 irq_set_chained_handler(MIPS_CPU_IRQ_BASE + cpu_vec,
490 gic_irq_dispatch);
491 }
492
486 gic_irq_domain = irq_domain_add_simple(NULL, GIC_NUM_INTRS, irqbase, 493 gic_irq_domain = irq_domain_add_simple(NULL, GIC_NUM_INTRS, irqbase,
487 &gic_irq_domain_ops, NULL); 494 &gic_irq_domain_ops, NULL);
488 if (!gic_irq_domain) 495 if (!gic_irq_domain)
489 panic("Failed to add GIC IRQ domain"); 496 panic("Failed to add GIC IRQ domain");
490 497
491 gic_basic_init(numintrs, numvpes, intr_map, intr_map_size); 498 gic_basic_init(numintrs, numvpes);
499
500 gic_ipi_init();
492} 501}