diff options
author | Graf Yang <graf.yang@analog.com> | 2009-12-28 06:13:51 -0500 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2010-03-09 00:30:48 -0500 |
commit | 0b39db28b953945232719e7ff6fb802aa8a2be5f (patch) | |
tree | c35193b07e9413ed6b5436aa79e24b0f22627082 /arch/blackfin/mach-common/smp.c | |
parent | 0d152c27e336b5fd777da7dd3e814617e7305afd (diff) |
Blackfin: SMP: add PM/CPU hotplug support
Signed-off-by: Graf Yang <graf.yang@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/mach-common/smp.c')
-rw-r--r-- | arch/blackfin/mach-common/smp.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index b343ab3764a1..efc47ffd066d 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c | |||
@@ -344,8 +344,11 @@ void smp_send_stop(void) | |||
344 | 344 | ||
345 | int __cpuinit __cpu_up(unsigned int cpu) | 345 | int __cpuinit __cpu_up(unsigned int cpu) |
346 | { | 346 | { |
347 | struct task_struct *idle; | ||
348 | int ret; | 347 | int ret; |
348 | static struct task_struct *idle; | ||
349 | |||
350 | if (idle) | ||
351 | free_task(idle); | ||
349 | 352 | ||
350 | idle = fork_idle(cpu); | 353 | idle = fork_idle(cpu); |
351 | if (IS_ERR(idle)) { | 354 | if (IS_ERR(idle)) { |
@@ -354,7 +357,6 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
354 | } | 357 | } |
355 | 358 | ||
356 | secondary_stack = task_stack_page(idle) + THREAD_SIZE; | 359 | secondary_stack = task_stack_page(idle) + THREAD_SIZE; |
357 | smp_wmb(); | ||
358 | 360 | ||
359 | ret = platform_boot_secondary(cpu, idle); | 361 | ret = platform_boot_secondary(cpu, idle); |
360 | 362 | ||
@@ -413,7 +415,6 @@ void __cpuinit secondary_start_kernel(void) | |||
413 | atomic_inc(&mm->mm_users); | 415 | atomic_inc(&mm->mm_users); |
414 | atomic_inc(&mm->mm_count); | 416 | atomic_inc(&mm->mm_count); |
415 | current->active_mm = mm; | 417 | current->active_mm = mm; |
416 | BUG_ON(current->mm); /* Can't be, but better be safe than sorry. */ | ||
417 | 418 | ||
418 | preempt_disable(); | 419 | preempt_disable(); |
419 | 420 | ||
@@ -495,3 +496,34 @@ void resync_core_dcache(void) | |||
495 | } | 496 | } |
496 | EXPORT_SYMBOL(resync_core_dcache); | 497 | EXPORT_SYMBOL(resync_core_dcache); |
497 | #endif | 498 | #endif |
499 | |||
500 | #ifdef CONFIG_HOTPLUG_CPU | ||
501 | int __cpuexit __cpu_disable(void) | ||
502 | { | ||
503 | unsigned int cpu = smp_processor_id(); | ||
504 | |||
505 | if (cpu == 0) | ||
506 | return -EPERM; | ||
507 | |||
508 | set_cpu_online(cpu, false); | ||
509 | return 0; | ||
510 | } | ||
511 | |||
512 | static DECLARE_COMPLETION(cpu_killed); | ||
513 | |||
514 | int __cpuexit __cpu_die(unsigned int cpu) | ||
515 | { | ||
516 | return wait_for_completion_timeout(&cpu_killed, 5000); | ||
517 | } | ||
518 | |||
519 | void cpu_die(void) | ||
520 | { | ||
521 | complete(&cpu_killed); | ||
522 | |||
523 | atomic_dec(&init_mm.mm_users); | ||
524 | atomic_dec(&init_mm.mm_count); | ||
525 | |||
526 | local_irq_disable(); | ||
527 | platform_cpu_die(); | ||
528 | } | ||
529 | #endif | ||