diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-31 23:41:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-31 23:41:53 -0400 |
commit | d6dd9e93c7531fa31370e27d053a3940d8d662fb (patch) | |
tree | afab573031b3f0b9bbe5e417a890f7cae09a7224 /arch/mips/kernel/smp.c | |
parent | dd9cd6d4351076c78bb8c0f9146d1904b481fdbb (diff) | |
parent | b4b2917cc8babe8eaf4bc133bca31b11ed7dac13 (diff) |
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (50 commits)
[MIPS] Add smp_call_function_single()
[MIPS] thread_info.h: kmalloc + memset conversion to kzalloc
[MIPS] Kexec: Fix several 64-bit bugs.
[MIPS] Kexec: Fix several warnings.
[MIPS] DDB5477: Remove support
[MIPS] Fulong: Remove unneeded header file
[MIPS] Cobalt: Enable UART on RaQ1
[MIPS] Remove unused GROUP_TOSHIBA_NAMES
[MIPS] remove some duplicate includes
[MIPS] Oprofile: Fix rm9000 performance counter handler
[MIPS] Use -Werror on subdirectories which build cleanly.
[MIPS] Yosemite: Fix warning.
[MIPS] PMON: Fix cpustart declaration.
[MIPS] Yosemite: Only build ll_ht_smp_irq_handler() if HYPERTRANSPORT.
[MIPS] Yosemite: Fix build error due to undeclared titan_mailbox_irq().
[MIPS] Yosemite: Don't declare titan_mailbox_irq() as asmlinkage.
[MIPS] Yosemite: Fix warnings in i2c-yoesmite by deleting the unused code.
[MIPS] Delete unused arch/mips/gt64120/common/
[MIPS] Fix build warning in unaligned load/store emulator.
[MIPS] IP32: Don't ignore request_irq's return value.
...
Diffstat (limited to 'arch/mips/kernel/smp.c')
-rw-r--r-- | arch/mips/kernel/smp.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 04bbbd8d91ab..73b0dab02668 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 | ||
197 | int 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 | |||
197 | static void stop_this_cpu(void *dummy) | 252 | static void stop_this_cpu(void *dummy) |
198 | { | 253 | { |
199 | /* | 254 | /* |