Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b4b2917c authored by Peter Watkins's avatar Peter Watkins Committed by Ralf Baechle
Browse files

[MIPS] Add smp_call_function_single()



In the other archs, there is more factoring of smp call code, and more care
in the use of get_cpu(). That can be a follow-up MIPS patch.

Signed-off-by: default avatarPeter Watkins <pwatkins@sicortex.com>
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 185bcd17
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -194,6 +194,61 @@ void smp_call_function_interrupt(void)
	}
}

int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
			     int retry, int wait)
{
	struct call_data_struct data;
	int me;

	/*
	 * Can die spectacularly if this CPU isn't yet marked online
	 */
	if (!cpu_online(cpu))
		return 0;

	me = get_cpu();
	BUG_ON(!cpu_online(me));

	if (cpu == me) {
		local_irq_disable();
		func(info);
		local_irq_enable();
		put_cpu();
		return 0;
	}

	/* Can deadlock when called with interrupts disabled */
	WARN_ON(irqs_disabled());

	data.func = func;
	data.info = info;
	atomic_set(&data.started, 0);
	data.wait = wait;
	if (wait)
		atomic_set(&data.finished, 0);

	spin_lock(&smp_call_lock);
	call_data = &data;
	smp_mb();

	/* Send a message to the other CPU */
	core_send_ipi(cpu, SMP_CALL_FUNCTION);

	/* Wait for response */
	/* FIXME: lock-up detection, backtrace on lock-up */
	while (atomic_read(&data.started) != 1)
		barrier();

	if (wait)
		while (atomic_read(&data.finished) != 1)
			barrier();
	call_data = NULL;
	spin_unlock(&smp_call_lock);

	put_cpu();
	return 0;
}

static void stop_this_cpu(void *dummy)
{
	/*