[v2] ARM: exynos: Fix infinite loops on CPU powerup failure

Message ID 20190326140359.4927-1-m.szyprowski@samsung.com
State New
Headers show
Series
  • [v2] ARM: exynos: Fix infinite loops on CPU powerup failure
Related show

Commit Message

Marek Szyprowski March 26, 2019, 2:03 p.m.
Add timeout to infinite loops during the CPU powerup procedures. It
is better to report an error instead of busylooping for infinite time
in case of failure.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

---
 arch/arm/mach-exynos/mcpm-exynos.c | 13 ++++++++++++-
 arch/arm/mach-exynos/platsmp.c     |  9 ++++++++-
 2 files changed, 20 insertions(+), 2 deletions(-)

-- 
2.17.1

Patch

diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
index 72bc035bedbe..9a681b421ae1 100644
--- a/arch/arm/mach-exynos/mcpm-exynos.c
+++ b/arch/arm/mach-exynos/mcpm-exynos.c
@@ -75,14 +75,25 @@  static int exynos_cpu_powerup(unsigned int cpu, unsigned int cluster)
 		 */
 		if (cluster &&
 		    cluster == MPIDR_AFFINITY_LEVEL(cpu_logical_map(0), 1)) {
+			unsigned int timeout = 16;
+
 			/*
 			 * Before we reset the Little cores, we should wait
 			 * the SPARE2 register is set to 1 because the init
 			 * codes of the iROM will set the register after
 			 * initialization.
 			 */
-			while (!pmu_raw_readl(S5P_PMU_SPARE2))
+			while (timeout && !pmu_raw_readl(S5P_PMU_SPARE2)) {
+				timeout--;
 				udelay(10);
+			}
+
+			if (timeout == 0) {
+				pr_err("cpu %u cluster %u powerup failed\n",
+				       cpu, cluster);
+				exynos_cpu_power_down(cpunr);
+				return -ETIMEDOUT;
+			}
 
 			pmu_raw_writel(EXYNOS5420_KFC_CORE_RESET(cpu),
 					EXYNOS_SWRESET);
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index abcac6164233..0cbbae8bf1f8 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -214,13 +214,20 @@  static inline void __iomem *cpu_boot_reg(int cpu)
  */
 void exynos_core_restart(u32 core_id)
 {
+	unsigned int timeout = 16;
 	u32 val;
 
 	if (!of_machine_is_compatible("samsung,exynos3250"))
 		return;
 
-	while (!pmu_raw_readl(S5P_PMU_SPARE2))
+	while (timeout && !pmu_raw_readl(S5P_PMU_SPARE2)) {
+		timeout--;
 		udelay(10);
+	}
+	if (timeout == 0) {
+		pr_err("cpu core %u restart failed\n", core_id);
+		return;
+	}
 	udelay(10);
 
 	val = pmu_raw_readl(EXYNOS_ARM_CORE_STATUS(core_id));