Ralf, Here is take 2. [MIPS] add smp_call_function_single (take 2) signed-off-by: Stephane Eranian <eranian@xxxxxxxxxx> signed-off-by: Phil Mucci <mucci@xxxxxxxxxx> diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index be7362b..d47234c 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -193,6 +193,53 @@ 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 = smp_processor_id(); + + /* + * Can die spectacularly if this CPU isn't yet marked online + */ + BUG_ON(!cpu_online(me)); + if (cpu == me) { + WARN_ON(1); + return -EBUSY; + } + + /* 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; + 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); + + return 0; +} +EXPORT_SYMBOL(smp_call_function_single); + static void stop_this_cpu(void *dummy) { /*