aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-27 23:03:22 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-27 23:03:22 -0400
commit66e4f8c076f8803e83879d986a7803a918b2129e (patch)
tree8d32c210b0c2304a55c9333e71a76d43755a4ab3
parent349101da8e1f8e5eb1476b02823da80495224485 (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>
-rw-r--r--arch/sparc/include/asm/smp_32.h25
-rw-r--r--arch/sparc/kernel/sun4d_smp.c16
-rw-r--r--arch/sparc/kernel/sun4m_smp.c12
3 files changed, 33 insertions, 20 deletions
diff --git a/arch/sparc/include/asm/smp_32.h b/arch/sparc/include/asm/smp_32.h
index 7201752cf934..a8180e546a48 100644
--- a/arch/sparc/include/asm/smp_32.h
+++ b/arch/sparc/include/asm/smp_32.h
@@ -50,27 +50,24 @@ struct seq_file;
50void smp_bogo(struct seq_file *); 50void smp_bogo(struct seq_file *);
51void smp_info(struct seq_file *); 51void smp_info(struct seq_file *);
52 52
53BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) 53BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, cpumask_t, unsigned long, unsigned long, unsigned long, unsigned long)
54BTFIXUPDEF_CALL(int, __hard_smp_processor_id, void) 54BTFIXUPDEF_CALL(int, __hard_smp_processor_id, void)
55BTFIXUPDEF_BLACKBOX(hard_smp_processor_id) 55BTFIXUPDEF_BLACKBOX(hard_smp_processor_id)
56BTFIXUPDEF_BLACKBOX(load_current) 56BTFIXUPDEF_BLACKBOX(load_current)
57 57
58#define smp_cross_call(func,arg1,arg2,arg3,arg4,arg5) BTFIXUP_CALL(smp_cross_call)(func,arg1,arg2,arg3,arg4,arg5) 58#define smp_cross_call(func,mask,arg1,arg2,arg3,arg4) BTFIXUP_CALL(smp_cross_call)(func,mask,arg1,arg2,arg3,arg4)
59 59
60static inline void xc0(smpfunc_t func) { smp_cross_call(func, 0, 0, 0, 0, 0); } 60static inline void xc0(smpfunc_t func) { smp_cross_call(func, cpu_online_map, 0, 0, 0, 0); }
61static inline void xc1(smpfunc_t func, unsigned long arg1) 61static inline void xc1(smpfunc_t func, unsigned long arg1)
62{ smp_cross_call(func, arg1, 0, 0, 0, 0); } 62{ smp_cross_call(func, cpu_online_map, arg1, 0, 0, 0); }
63static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2) 63static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
64{ smp_cross_call(func, arg1, arg2, 0, 0, 0); } 64{ smp_cross_call(func, cpu_online_map, arg1, arg2, 0, 0); }
65static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2, 65static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
66 unsigned long arg3) 66 unsigned long arg3)
67{ smp_cross_call(func, arg1, arg2, arg3, 0, 0); } 67{ smp_cross_call(func, cpu_online_map, arg1, arg2, arg3, 0); }
68static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2, 68static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
69 unsigned long arg3, unsigned long arg4) 69 unsigned long arg3, unsigned long arg4)
70{ smp_cross_call(func, arg1, arg2, arg3, arg4, 0); } 70{ smp_cross_call(func, cpu_online_map, arg1, arg2, arg3, arg4); }
71static inline void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg2,
72 unsigned long arg3, unsigned long arg4, unsigned long arg5)
73{ smp_cross_call(func, arg1, arg2, arg3, arg4, arg5); }
74 71
75static inline int smp_call_function(void (*func)(void *info), void *info, int wait) 72static inline int smp_call_function(void (*func)(void *info), void *info, int wait)
76{ 73{
@@ -78,6 +75,14 @@ static inline int smp_call_function(void (*func)(void *info), void *info, int wa
78 return 0; 75 return 0;
79} 76}
80 77
78static inline int smp_call_function_single(int cpuid, void (*func) (void *info),
79 void *info, int wait)
80{
81 smp_cross_call((smpfunc_t)func, cpumask_of_cpu(cpuid),
82 (unsigned long) info, 0, 0, 0);
83 return 0;
84}
85
81static inline int cpu_logical_map(int cpu) 86static inline int cpu_logical_map(int cpu)
82{ 87{
83 return cpu; 88 return cpu;
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 {
262static DEFINE_SPINLOCK(cross_call_lock); 262static 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. */
265void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, 265static 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);
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index 406ac1abc83a..a14a76ac7f36 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -244,9 +244,9 @@ static struct smp_funcall {
244static DEFINE_SPINLOCK(cross_call_lock); 244static DEFINE_SPINLOCK(cross_call_lock);
245 245
246/* Cross calls must be serialized, at least currently. */ 246/* Cross calls must be serialized, at least currently. */
247static void smp4m_cross_call(smpfunc_t func, unsigned long arg1, 247static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
248 unsigned long arg2, unsigned long arg3, 248 unsigned long arg2, unsigned long arg3,
249 unsigned long arg4, unsigned long arg5) 249 unsigned long arg4)
250{ 250{
251 register int ncpus = SUN4M_NCPUS; 251 register int ncpus = SUN4M_NCPUS;
252 unsigned long flags; 252 unsigned long flags;
@@ -259,14 +259,14 @@ static void smp4m_cross_call(smpfunc_t func, unsigned long arg1,
259 ccall_info.arg2 = arg2; 259 ccall_info.arg2 = arg2;
260 ccall_info.arg3 = arg3; 260 ccall_info.arg3 = arg3;
261 ccall_info.arg4 = arg4; 261 ccall_info.arg4 = arg4;
262 ccall_info.arg5 = arg5; 262 ccall_info.arg5 = 0;
263 263
264 /* Init receive/complete mapping, plus fire the IPI's off. */ 264 /* Init receive/complete mapping, plus fire the IPI's off. */
265 { 265 {
266 cpumask_t mask = cpu_online_map;
267 register int i; 266 register int i;
268 267
269 cpu_clear(smp_processor_id(), mask); 268 cpu_clear(smp_processor_id(), mask);
269 cpus_and(mask, cpu_online_map, mask);
270 for(i = 0; i < ncpus; i++) { 270 for(i = 0; i < ncpus; i++) {
271 if (cpu_isset(i, mask)) { 271 if (cpu_isset(i, mask)) {
272 ccall_info.processors_in[i] = 0; 272 ccall_info.processors_in[i] = 0;
@@ -284,12 +284,16 @@ static void smp4m_cross_call(smpfunc_t func, unsigned long arg1,
284 284
285 i = 0; 285 i = 0;
286 do { 286 do {
287 if (!cpu_isset(i, mask))
288 continue;
287 while(!ccall_info.processors_in[i]) 289 while(!ccall_info.processors_in[i])
288 barrier(); 290 barrier();
289 } while(++i < ncpus); 291 } while(++i < ncpus);
290 292
291 i = 0; 293 i = 0;
292 do { 294 do {
295 if (!cpu_isset(i, mask))
296 continue;
293 while(!ccall_info.processors_out[i]) 297 while(!ccall_info.processors_out[i])
294 barrier(); 298 barrier();
295 } while(++i < ncpus); 299 } while(++i < ncpus);