diff options
| -rw-r--r-- | arch/sparc/include/asm/smp_32.h | 25 | ||||
| -rw-r--r-- | arch/sparc/kernel/sun4d_smp.c | 16 | ||||
| -rw-r--r-- | arch/sparc/kernel/sun4m_smp.c | 12 |
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; | |||
| 50 | void smp_bogo(struct seq_file *); | 50 | void smp_bogo(struct seq_file *); |
| 51 | void smp_info(struct seq_file *); | 51 | void smp_info(struct seq_file *); |
| 52 | 52 | ||
| 53 | BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) | 53 | BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, cpumask_t, unsigned long, unsigned long, unsigned long, unsigned long) |
| 54 | BTFIXUPDEF_CALL(int, __hard_smp_processor_id, void) | 54 | BTFIXUPDEF_CALL(int, __hard_smp_processor_id, void) |
| 55 | BTFIXUPDEF_BLACKBOX(hard_smp_processor_id) | 55 | BTFIXUPDEF_BLACKBOX(hard_smp_processor_id) |
| 56 | BTFIXUPDEF_BLACKBOX(load_current) | 56 | BTFIXUPDEF_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 | ||
| 60 | static inline void xc0(smpfunc_t func) { smp_cross_call(func, 0, 0, 0, 0, 0); } | 60 | static inline void xc0(smpfunc_t func) { smp_cross_call(func, cpu_online_map, 0, 0, 0, 0); } |
| 61 | static inline void xc1(smpfunc_t func, unsigned long arg1) | 61 | static 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); } |
| 63 | static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2) | 63 | static 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); } |
| 65 | static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2, | 65 | static 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); } |
| 68 | static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2, | 68 | static 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); } |
| 71 | static 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 | ||
| 75 | static inline int smp_call_function(void (*func)(void *info), void *info, int wait) | 72 | static 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 | ||
| 78 | static 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 | |||
| 81 | static inline int cpu_logical_map(int cpu) | 86 | static 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 { | |||
| 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); |
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 { | |||
| 244 | static DEFINE_SPINLOCK(cross_call_lock); | 244 | static 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. */ |
| 247 | static void smp4m_cross_call(smpfunc_t func, unsigned long arg1, | 247 | static 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); |
