[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: Peter Watkins <pwatkins@sicortex.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
Peter Watkins 2007-07-30 18:01:29 -04:00 committed by Ralf Baechle
parent 185bcd17a5
commit b4b2917cc8
1 changed files with 55 additions and 0 deletions

View File

@ -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)
{
/*