diff options
author | David S. Miller <davem@davemloft.net> | 2008-08-27 23:03:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-08-27 23:03:22 -0400 |
commit | 66e4f8c076f8803e83879d986a7803a918b2129e (patch) | |
tree | 8d32c210b0c2304a55c9333e71a76d43755a4ab3 /arch/sparc/kernel/sun4d_smp.c | |
parent | 349101da8e1f8e5eb1476b02823da80495224485 (diff) |
sparc32: Implement smp_call_function_single().
Reported by Stephen Rothwell.
Needed to fix the build when CONFIG_RELAY is enabled.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel/sun4d_smp.c')
-rw-r--r-- | arch/sparc/kernel/sun4d_smp.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index dfde77ff0848..69596402a500 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c | |||
@@ -262,8 +262,9 @@ static struct smp_funcall { | |||
262 | static DEFINE_SPINLOCK(cross_call_lock); | 262 | static DEFINE_SPINLOCK(cross_call_lock); |
263 | 263 | ||
264 | /* Cross calls must be serialized, at least currently. */ | 264 | /* Cross calls must be serialized, at least currently. */ |
265 | void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, | 265 | static void smp4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, |
266 | unsigned long arg3, unsigned long arg4, unsigned long arg5) | 266 | unsigned long arg2, unsigned long arg3, |
267 | unsigned long arg4) | ||
267 | { | 268 | { |
268 | if(smp_processors_ready) { | 269 | if(smp_processors_ready) { |
269 | register int high = smp_highest_cpu; | 270 | register int high = smp_highest_cpu; |
@@ -278,7 +279,7 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, | |||
278 | register unsigned long a2 asm("i2") = arg2; | 279 | register unsigned long a2 asm("i2") = arg2; |
279 | register unsigned long a3 asm("i3") = arg3; | 280 | register unsigned long a3 asm("i3") = arg3; |
280 | register unsigned long a4 asm("i4") = arg4; | 281 | register unsigned long a4 asm("i4") = arg4; |
281 | register unsigned long a5 asm("i5") = arg5; | 282 | register unsigned long a5 asm("i5") = 0; |
282 | 283 | ||
283 | __asm__ __volatile__( | 284 | __asm__ __volatile__( |
284 | "std %0, [%6]\n\t" | 285 | "std %0, [%6]\n\t" |
@@ -290,11 +291,10 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, | |||
290 | 291 | ||
291 | /* Init receive/complete mapping, plus fire the IPI's off. */ | 292 | /* Init receive/complete mapping, plus fire the IPI's off. */ |
292 | { | 293 | { |
293 | cpumask_t mask; | ||
294 | register int i; | 294 | register int i; |
295 | 295 | ||
296 | mask = cpumask_of_cpu(hard_smp4d_processor_id()); | 296 | cpu_clear(smp_processor_id(), mask); |
297 | cpus_andnot(mask, cpu_online_map, mask); | 297 | cpus_and(mask, cpu_online_map, mask); |
298 | for(i = 0; i <= high; i++) { | 298 | for(i = 0; i <= high; i++) { |
299 | if (cpu_isset(i, mask)) { | 299 | if (cpu_isset(i, mask)) { |
300 | ccall_info.processors_in[i] = 0; | 300 | ccall_info.processors_in[i] = 0; |
@@ -309,12 +309,16 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, | |||
309 | 309 | ||
310 | i = 0; | 310 | i = 0; |
311 | do { | 311 | do { |
312 | if (!cpu_isset(i, mask)) | ||
313 | continue; | ||
312 | while(!ccall_info.processors_in[i]) | 314 | while(!ccall_info.processors_in[i]) |
313 | barrier(); | 315 | barrier(); |
314 | } while(++i <= high); | 316 | } while(++i <= high); |
315 | 317 | ||
316 | i = 0; | 318 | i = 0; |
317 | do { | 319 | do { |
320 | if (!cpu_isset(i, mask)) | ||
321 | continue; | ||
318 | while(!ccall_info.processors_out[i]) | 322 | while(!ccall_info.processors_out[i]) |
319 | barrier(); | 323 | barrier(); |
320 | } while(++i <= high); | 324 | } while(++i <= high); |