MIPS: GIC: Send IPIs using the GIC
authorSteven J. Hill <Steven.Hill@imgtec.com>
Wed, 9 Oct 2013 15:47:23 +0000 (16:47 +0100)
committerRalf Baechle <ralf@linux-mips.org>
Wed, 22 Jan 2014 19:18:57 +0000 (20:18 +0100)
If GIC is present, then use it to send IPIs between the cores.
Using GIC for IPIs is simpler and is usable for multicore
systems compared to the existing way of doing IPIs where all VPEs
had to be disabled for another VPE to access the Cause register
in one of the TCs and enable all the VPEs back.

Signed-off-by: Steven J. Hill <Steven.Hill@imgtec.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Signed-off-by: John Crispin <blogic@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/6040/

arch/mips/kernel/smp-mt.c

index 35f8d22d56a9535f8637295c1b05b1f5e130b53d..0fb8cefc9114b299fd5ed3b73ef3da86abf4da8e 100644 (file)
@@ -113,12 +113,39 @@ static void __init smvp_tc_init(unsigned int tc, unsigned int mvpconf0)
        write_tc_c0_tchalt(TCHALT_H);
 }
 
+#ifdef CONFIG_IRQ_GIC
+static void mp_send_ipi_single(int cpu, unsigned int action)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+
+       switch (action) {
+       case SMP_CALL_FUNCTION:
+               gic_send_ipi(plat_ipi_call_int_xlate(cpu));
+               break;
+
+       case SMP_RESCHEDULE_YOURSELF:
+               gic_send_ipi(plat_ipi_resched_int_xlate(cpu));
+               break;
+       }
+
+       local_irq_restore(flags);
+}
+#endif
+
 static void vsmp_send_ipi_single(int cpu, unsigned int action)
 {
        int i;
        unsigned long flags;
        int vpflags;
 
+#ifdef CONFIG_IRQ_GIC
+       if (gic_present) {
+               mp_send_ipi_single(cpu, action);
+               return;
+       }
+#endif
        local_irq_save(flags);
 
        vpflags = dvpe();       /* can't access the other CPU's registers whilst MVPE enabled */