From 705aa98535fecbc116d02ae6a2d5819fc36c1f7e Mon Sep 17 00:00:00 2001 From: Wang Dongsheng Date: Wed, 30 Apr 2014 00:48:23 +0800 Subject: powerpc/cpu-hotplug: fix cpu re-online failed issue 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. Tested on P4080ds, T1042rdb_pi, T4240qds, B4860qds. root@p4080ds:/usr/etc# echo 0 > /sys/devices/system/cpu/cpu7/online Cannot set affinity for irq 467 root@p4080ds:/usr/etc# root@p4080ds:/usr/etc# echo 1 > /sys/devices/system/cpu/cpu7/online smp_85xx_kick_cpu: timeout waiting for core 7 to reset smp: failed starting cpu 7 (rc -2) Signed-off-by: Wang Dongsheng Signed-off-by: Chenhui Zhao Reviewed-on: http://git.am.freescale.net:8181/11356 Tested-by: Review Code-CDREVIEW Reviewed-by: Yang Li Reviewed-by: Jose Rivera Change-Id: Ib300dffe28b2436fe44431286ff707124402204d Reviewed-on: http://git.am.freescale.net:8181/11648 diff --git a/arch/powerpc/include/asm/fsl_pm.h b/arch/powerpc/include/asm/fsl_pm.h index bcdc018..742cf22 100644 --- a/arch/powerpc/include/asm/fsl_pm.h +++ b/arch/powerpc/include/asm/fsl_pm.h @@ -50,6 +50,14 @@ extern void fsl_dp_enter_low(void __iomem *ccsr_base, void __iomem *dcsr_base, void __iomem *pld_base, int pld_flag); extern void fsl_booke_deep_sleep_resume(void); +/* + * RCPM definition + */ +#define RCPM_V1 1 +#define RCPM_V2 2 + +unsigned long get_rcpm_version(void); + void set_pm_suspend_state(suspend_state_t state); suspend_state_t pm_suspend_state(void); diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 521ca17..a65c5d3 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -363,6 +363,17 @@ static int smp_85xx_kick_cpu(int nr) out_be32(&spin_table->addr_l, 0); flush_spin_table(spin_table); +#ifdef CONFIG_PPC_E500MC + /* + * 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. + */ + if (get_rcpm_version() == RCPM_V1 && + qoriq_pm_ops->cpu_exit_state) + qoriq_pm_ops->cpu_exit_state(nr, qoriq_cpu_die_state); +#endif + /* * We don't set the BPTR register here since it already points * to the boot page properly. diff --git a/arch/powerpc/sysdev/fsl_rcpm.c b/arch/powerpc/sysdev/fsl_rcpm.c index 4f888f1..a21235c 100644 --- a/arch/powerpc/sysdev/fsl_rcpm.c +++ b/arch/powerpc/sysdev/fsl_rcpm.c @@ -20,13 +20,11 @@ #include #include -#define RCPM_V1 1 -#define RCPM_V2 2 - const struct fsl_pm_ops *qoriq_pm_ops; static struct ccsr_rcpm_v1 __iomem *rcpm_v1_regs; static struct ccsr_rcpm_v2 __iomem *rcpm_v2_regs; +static unsigned long rcpm_version; static void rcpm_v1_irq_mask(int cpu) { @@ -292,6 +290,11 @@ static const struct of_device_id rcpm_matches[] = { {}, }; +unsigned long get_rcpm_version(void) +{ + return rcpm_version; +} + int fsl_rcpm_init(void) { struct device_node *np; @@ -309,7 +312,9 @@ int fsl_rcpm_init(void) if (!base) return -ENOMEM; - switch ((unsigned long)match->data) { + rcpm_version = (unsigned long)match->data; + + switch (rcpm_version) { case RCPM_V1: rcpm_v1_regs = base; qoriq_pm_ops = &qoriq_rcpm_v1_ops; -- cgit v0.10.2