summaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorZhang Zhuoyu <Zhuoyu.Zhang@freescale.com>2014-10-10 16:02:36 (GMT)
committerMatthew Weigel <Matthew.Weigel@freescale.com>2014-12-11 18:39:02 (GMT)
commit563356332542fed0435f511d68eb592f9c3f1d0d (patch)
treefb0980b1c24afebaef8e179d0302c0c0a7ae69c0 /arch/powerpc/platforms
parentbcfc0b3673656149bc26d120ff774bfdacba952e (diff)
downloadlinux-fsl-qoriq-563356332542fed0435f511d68eb592f9c3f1d0d.tar.xz
Fix e6500-based platform CPU hotplug issue
Fix thread 1 of core 0 online issue. Besides, put offline thread into PW10 state, give it a chance to enter PW20 state when threads of the same core are in PW10 state. Signed-off-by: Zhang Zhuoyu <Zhuoyu.Zhang@freescale.com> Change-Id: I9018c4499f02b79f2ec684798c54bf3cfe6723de Reviewed-on: http://git.am.freescale.net:8181/21206 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Yang Li <LeoLi@freescale.com>
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/85xx/smp.c57
-rw-r--r--arch/powerpc/platforms/85xx/smp.h2
2 files changed, 43 insertions, 16 deletions
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index a65c5d3..5b12f4b 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -48,8 +48,6 @@ static int tb_req;
static int tb_valid;
static u32 cur_booting_core;
-extern void fsl_enable_threads(void);
-
/* specify the cpu PM state when cpu dies, PH15/NAP is the default */
int qoriq_cpu_die_state = E500_PM_PH15;
@@ -212,11 +210,8 @@ static void __cpuinit smp_85xx_mach_cpu_die(void)
if (cur_cpu_spec && cur_cpu_spec->cpu_flush_caches)
cur_cpu_spec->cpu_flush_caches();
- if (is_core_down(cpu))
+ if (qoriq_pm_ops->cpu_enter_state)
qoriq_pm_ops->cpu_enter_state(cpu, qoriq_cpu_die_state);
-
- while (1)
- ;
}
#else
@@ -291,15 +286,33 @@ static int smp_85xx_kick_cpu(int nr)
if (cpu_online(cpu_first_thread_sibling(nr))) {
local_irq_save(flags);
- /*
- * In cpu hotplug case, Thread 1 of Core 0 must
- * start by calling fsl_enable_threads(). Thread 1
- * of other cores can be started by Thread 0
- * after reset.
- */
- if (nr == 1 && system_state == SYSTEM_RUNNING)
- fsl_enable_threads();
-
+#ifdef CONFIG_PPC_E500MC
+ if (system_state == SYSTEM_RUNNING) {
+ /*
+ * In cpu hotplug case, Thread 1 of Core0
+ * must start by Thread0 of Core0 calling
+ * fsl_enable_threads().
+ */
+ if (nr == 1) {
+ if (get_cpu() == boot_cpuid)
+ fsl_enable_threads(&ret);
+ else
+ work_on_cpu(boot_cpuid,
+ fsl_enable_threads, NULL);
+ }
+
+ /*
+ * Thread 1 of other cores can be waken up from
+ * low-power state when Thread 0 is online,
+ * or restart by Thread 0 after core reset.
+ */
+ if (!strcmp(cur_cpu_spec->cpu_name, "e6500"))
+ arch_send_call_function_single_ipi(nr);
+
+ if (qoriq_pm_ops->irq_unmask)
+ qoriq_pm_ops->irq_unmask(nr);
+ }
+#endif
smp_generic_kick_cpu(nr);
generic_set_cpu_up(nr);
@@ -365,6 +378,13 @@ static int smp_85xx_kick_cpu(int nr)
#ifdef CONFIG_PPC_E500MC
/*
+ * For e6500-based platform, wake up core from
+ * low-power state before reset core.
+ */
+ if (!strcmp(cur_cpu_spec->cpu_name, "e6500"))
+ arch_send_call_function_single_ipi(nr);
+
+ /*
* Errata-A-006568. If SOC-rcpm is V1, we need enable
* cpu first, T4240rev2 and later Soc has been fixed.
* But before this errata is still needed.
@@ -606,8 +626,13 @@ void __init mpc85xx_smp_init(void)
#ifdef CONFIG_HOTPLUG_CPU
ppc_md.cpu_die = smp_85xx_mach_cpu_die;
#endif
+ /*
+ * For e6500-based platform, put thread into PW10 state gives
+ * it a chance to enter PW20 state when threads of the same
+ * core are in PW10 state.
+ */
if (!strcmp(cur_cpu_spec->cpu_name, "e6500"))
- qoriq_cpu_die_state = E500_PM_PH20;
+ qoriq_cpu_die_state = E500_PM_PW10;
}
smp_ops = &smp_85xx_ops;
diff --git a/arch/powerpc/platforms/85xx/smp.h b/arch/powerpc/platforms/85xx/smp.h
index e2b4493..8983009 100644
--- a/arch/powerpc/platforms/85xx/smp.h
+++ b/arch/powerpc/platforms/85xx/smp.h
@@ -12,4 +12,6 @@ static inline void mpc85xx_smp_init(void)
}
#endif
+extern long fsl_enable_threads(void *);
+
#endif /* not POWERPC_85XX_SMP_H_ */