diff options
author | Zhang Zhuoyu <Zhuoyu.Zhang@freescale.com> | 2014-10-10 16:02:36 (GMT) |
---|---|---|
committer | Matthew Weigel <Matthew.Weigel@freescale.com> | 2014-12-11 18:39:02 (GMT) |
commit | 563356332542fed0435f511d68eb592f9c3f1d0d (patch) | |
tree | fb0980b1c24afebaef8e179d0302c0c0a7ae69c0 /arch/powerpc/platforms | |
parent | bcfc0b3673656149bc26d120ff774bfdacba952e (diff) | |
download | linux-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.c | 57 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/smp.h | 2 |
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_ */ |