aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/kernel/smp.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 04bbbd8d91a..73b0dab0266 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -194,6 +194,61 @@ void smp_call_function_interrupt(void)
194 } 194 }
195} 195}
196 196
197int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
198 int retry, int wait)
199{
200 struct call_data_struct data;
201 int me;
202
203 /*
204 * Can die spectacularly if this CPU isn't yet marked online
205 */
206 if (!cpu_online(cpu))
207 return 0;
208
209 me = get_cpu();
210 BUG_ON(!cpu_online(me));
211
212 if (cpu == me) {
213 local_irq_disable();
214 func(info);
215 local_irq_enable();
216 put_cpu();
217 return 0;
218 }
219
220 /* Can deadlock when called with interrupts disabled */
221 WARN_ON(irqs_disabled());
222
223 data.func = func;
224 data.info = info;
225 atomic_set(&data.started, 0);
226 data.wait = wait;
227 if (wait)
228 atomic_set(&data.finished, 0);
229
230 spin_lock(&smp_call_lock);
231 call_data = &data;
232 smp_mb();
233
234 /* Send a message to the other CPU */
235 core_send_ipi(cpu, SMP_CALL_FUNCTION);
236
237 /* Wait for response */
238 /* FIXME: lock-up detection, backtrace on lock-up */
239 while (atomic_read(&data.started) != 1)
240 barrier();
241
242 if (wait)
243 while (atomic_read(&data.finished) != 1)
244 barrier();
245 call_data = NULL;
246 spin_unlock(&smp_call_lock);
247
248 put_cpu();
249 return 0;
250}
251
197static void stop_this_cpu(void *dummy) 252static void stop_this_cpu(void *dummy)
198{ 253{
199 /* 254 /*