/* * Broadcast handler for MT7621 VPE0, VPE1, VPE2 and VPE3 dummy clockevent device. * This function is registered in arch/mips/kernel/cevt-r4k.c. * * The function is in timer irq context. */ void ra_systick_event_broadcast(const struct cpumask *mask) { u32 reg; int i; unsigned long flags; /* * Mailbox design. * * The IPI VPE sender writes the signal bit to RALINK_TESTSTAT register. * So the receiver VPEs can judge "ipi_call" or "broadcast" event by * RALINK_TESTSTAT register when receiving ipi_call interrupt. * * Using spin_lock() to prevent other VPEs from accessing RALINK_TESTSTAT * register at the same time. */ spin_lock_irqsave(&ra_teststat_lock, flags); reg = (*((volatile u32 *)(RALINK_TESTSTAT))); for_each_cpu(i, mask) reg |= ((0x1UL) << i); (*((volatile u32 *)(RALINK_TESTSTAT))) = reg; spin_unlock_irqrestore(&ra_teststat_lock, flags); #ifdef CONFIG_MIPS_MT_SMP /* send IPI to other VPEs, using "ipi_call" GIC(60~63), MIPS int#2 */ for_each_cpu(i, mask) gic_send_ipi(plat_ipi_call_int_xlate(i)); #endif }
void gic_send_ipi_single(int cpu, unsigned int action) { unsigned long flags; unsigned int intr; pr_debug("CPU%d: %s cpu %d action %u status %08x\n", smp_processor_id(), __func__, cpu, action, read_c0_status()); local_irq_save(flags); switch (action) { case SMP_CALL_FUNCTION: intr = plat_ipi_call_int_xlate(cpu); break; case SMP_RESCHEDULE_YOURSELF: intr = plat_ipi_resched_int_xlate(cpu); break; default: BUG(); } gic_send_ipi(intr); local_irq_restore(flags); }