diff options
| -rw-r--r-- | arch/sh/Kconfig | 1 | ||||
| -rw-r--r-- | arch/sh/kernel/smp.c | 48 | ||||
| -rw-r--r-- | include/asm-sh/smp.h | 14 |
3 files changed, 13 insertions, 50 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 9a854c8e5274..3e7384f4619c 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
| @@ -688,6 +688,7 @@ config CRASH_DUMP | |||
| 688 | config SMP | 688 | config SMP |
| 689 | bool "Symmetric multi-processing support" | 689 | bool "Symmetric multi-processing support" |
| 690 | depends on SYS_SUPPORTS_SMP | 690 | depends on SYS_SUPPORTS_SMP |
| 691 | select USE_GENERIC_SMP_HELPERS | ||
| 691 | ---help--- | 692 | ---help--- |
| 692 | This enables support for systems with more than one CPU. If you have | 693 | This enables support for systems with more than one CPU. If you have |
| 693 | a system with only one CPU, like most personal computers, say N. If | 694 | a system with only one CPU, like most personal computers, say N. If |
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 5d039d168f57..2ed8dceb297b 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c | |||
| @@ -36,13 +36,6 @@ EXPORT_SYMBOL(cpu_possible_map); | |||
| 36 | cpumask_t cpu_online_map; | 36 | cpumask_t cpu_online_map; |
| 37 | EXPORT_SYMBOL(cpu_online_map); | 37 | EXPORT_SYMBOL(cpu_online_map); |
| 38 | 38 | ||
| 39 | static atomic_t cpus_booted = ATOMIC_INIT(0); | ||
| 40 | |||
| 41 | /* | ||
| 42 | * Run specified function on a particular processor. | ||
| 43 | */ | ||
| 44 | void __smp_call_function(unsigned int cpu); | ||
| 45 | |||
| 46 | static inline void __init smp_store_cpu_info(unsigned int cpu) | 39 | static inline void __init smp_store_cpu_info(unsigned int cpu) |
| 47 | { | 40 | { |
| 48 | struct sh_cpuinfo *c = cpu_data + cpu; | 41 | struct sh_cpuinfo *c = cpu_data + cpu; |
| @@ -178,42 +171,17 @@ void smp_send_stop(void) | |||
| 178 | smp_call_function(stop_this_cpu, 0, 1, 0); | 171 | smp_call_function(stop_this_cpu, 0, 1, 0); |
| 179 | } | 172 | } |
| 180 | 173 | ||
| 181 | struct smp_fn_call_struct smp_fn_call = { | 174 | void arch_send_call_function_ipi(cpumask_t mask) |
| 182 | .lock = __SPIN_LOCK_UNLOCKED(smp_fn_call.lock), | ||
| 183 | .finished = ATOMIC_INIT(0), | ||
| 184 | }; | ||
| 185 | |||
| 186 | /* | ||
| 187 | * The caller of this wants the passed function to run on every cpu. If wait | ||
| 188 | * is set, wait until all cpus have finished the function before returning. | ||
| 189 | * The lock is here to protect the call structure. | ||
| 190 | * You must not call this function with disabled interrupts or from a | ||
| 191 | * hardware interrupt handler or from a bottom half handler. | ||
| 192 | */ | ||
| 193 | int smp_call_function(void (*func)(void *info), void *info, int retry, int wait) | ||
| 194 | { | 175 | { |
| 195 | unsigned int nr_cpus = atomic_read(&cpus_booted); | 176 | int cpu; |
| 196 | int i; | ||
| 197 | |||
| 198 | /* Can deadlock when called with interrupts disabled */ | ||
| 199 | WARN_ON(irqs_disabled()); | ||
| 200 | |||
| 201 | spin_lock(&smp_fn_call.lock); | ||
| 202 | |||
| 203 | atomic_set(&smp_fn_call.finished, 0); | ||
| 204 | smp_fn_call.fn = func; | ||
| 205 | smp_fn_call.data = info; | ||
| 206 | |||
| 207 | for (i = 0; i < nr_cpus; i++) | ||
| 208 | if (i != smp_processor_id()) | ||
| 209 | plat_send_ipi(i, SMP_MSG_FUNCTION); | ||
| 210 | |||
| 211 | if (wait) | ||
| 212 | while (atomic_read(&smp_fn_call.finished) != (nr_cpus - 1)); | ||
| 213 | 177 | ||
| 214 | spin_unlock(&smp_fn_call.lock); | 178 | for_each_cpu_mask(cpu, mask) |
| 179 | plat_send_ipi(cpu, SMP_MSG_FUNCTION); | ||
| 180 | } | ||
| 215 | 181 | ||
| 216 | return 0; | 182 | void arch_send_call_function_single_ipi(int cpu) |
| 183 | { | ||
| 184 | plat_send_ipi(cpu, SMP_MSG_FUNCTION_SINGLE); | ||
| 217 | } | 185 | } |
| 218 | 186 | ||
| 219 | /* Not really SMP stuff ... */ | 187 | /* Not really SMP stuff ... */ |
diff --git a/include/asm-sh/smp.h b/include/asm-sh/smp.h index 9c8d34b07ebf..593343cd26ee 100644 --- a/include/asm-sh/smp.h +++ b/include/asm-sh/smp.h | |||
| @@ -26,18 +26,10 @@ extern int __cpu_logical_map[NR_CPUS]; | |||
| 26 | 26 | ||
| 27 | #define NO_PROC_ID (-1) | 27 | #define NO_PROC_ID (-1) |
| 28 | 28 | ||
| 29 | struct smp_fn_call_struct { | ||
| 30 | spinlock_t lock; | ||
| 31 | atomic_t finished; | ||
| 32 | void (*fn)(void *); | ||
| 33 | void *data; | ||
| 34 | }; | ||
| 35 | |||
| 36 | extern struct smp_fn_call_struct smp_fn_call; | ||
| 37 | |||
| 38 | #define SMP_MSG_FUNCTION 0 | 29 | #define SMP_MSG_FUNCTION 0 |
| 39 | #define SMP_MSG_RESCHEDULE 1 | 30 | #define SMP_MSG_RESCHEDULE 1 |
| 40 | #define SMP_MSG_NR 2 | 31 | #define SMP_MSG_FUNCTION_SINGLE 2 |
| 32 | #define SMP_MSG_NR 3 | ||
| 41 | 33 | ||
| 42 | void plat_smp_setup(void); | 34 | void plat_smp_setup(void); |
| 43 | void plat_prepare_cpus(unsigned int max_cpus); | 35 | void plat_prepare_cpus(unsigned int max_cpus); |
| @@ -46,6 +38,8 @@ void plat_start_cpu(unsigned int cpu, unsigned long entry_point); | |||
| 46 | void plat_send_ipi(unsigned int cpu, unsigned int message); | 38 | void plat_send_ipi(unsigned int cpu, unsigned int message); |
| 47 | int plat_register_ipi_handler(unsigned int message, | 39 | int plat_register_ipi_handler(unsigned int message, |
| 48 | void (*handler)(void *), void *arg); | 40 | void (*handler)(void *), void *arg); |
| 41 | extern void arch_send_call_function_single_ipi(int cpu); | ||
| 42 | extern void arch_send_call_function_ipi(cpumask_t mask); | ||
| 49 | 43 | ||
| 50 | #else | 44 | #else |
| 51 | 45 | ||
