summaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common/smp.c
diff options
context:
space:
mode:
authorGraf Yang <graf.yang@analog.com>2009-12-28 12:13:51 +0100
committerMike Frysinger <vapier@gentoo.org>2010-03-09 06:30:48 +0100
commit0b39db28b953945232719e7ff6fb802aa8a2be5f (patch)
treec35193b07e9413ed6b5436aa79e24b0f22627082 /arch/blackfin/mach-common/smp.c
parentBlackfin: SMP: make core timers per-cpu clock events for HRT (diff)
downloadlinux-0b39db28b953945232719e7ff6fb802aa8a2be5f.tar.xz
linux-0b39db28b953945232719e7ff6fb802aa8a2be5f.zip
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.c38
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)
int __cpuinit __cpu_up(unsigned int cpu)
{
- struct task_struct *idle;
int ret;
+ static struct task_struct *idle;
+
+ if (idle)
+ free_task(idle);
idle = fork_idle(cpu);
if (IS_ERR(idle)) {
@@ -354,7 +357,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
}
secondary_stack = task_stack_page(idle) + THREAD_SIZE;
- smp_wmb();
ret = platform_boot_secondary(cpu, idle);
@@ -413,7 +415,6 @@ void __cpuinit secondary_start_kernel(void)
atomic_inc(&mm->mm_users);
atomic_inc(&mm->mm_count);
current->active_mm = mm;
- BUG_ON(current->mm); /* Can't be, but better be safe than sorry. */
preempt_disable();
@@ -495,3 +496,34 @@ void resync_core_dcache(void)
}
EXPORT_SYMBOL(resync_core_dcache);
#endif
+
+#ifdef CONFIG_HOTPLUG_CPU
+int __cpuexit __cpu_disable(void)
+{
+ unsigned int cpu = smp_processor_id();
+
+ if (cpu == 0)
+ return -EPERM;
+
+ set_cpu_online(cpu, false);
+ return 0;
+}
+
+static DECLARE_COMPLETION(cpu_killed);
+
+int __cpuexit __cpu_die(unsigned int cpu)
+{
+ return wait_for_completion_timeout(&cpu_killed, 5000);
+}
+
+void cpu_die(void)
+{
+ complete(&cpu_killed);
+
+ atomic_dec(&init_mm.mm_users);
+ atomic_dec(&init_mm.mm_count);
+
+ local_irq_disable();
+ platform_cpu_die();
+}
+#endif