]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ARM: rockchip: keep reset control around
authorHeiko Stuebner <heiko@sntech.de>
Thu, 21 May 2026 21:09:15 +0000 (23:09 +0200)
committerHeiko Stuebner <heiko@sntech.de>
Tue, 26 May 2026 21:20:39 +0000 (23:20 +0200)
Do not put the reset control, retain exclusive control over it.
After turning on a CPU, the corresponding reset line must stay
deasserted.

This also avoids calling reset_control_put() before workqueues
are operational.

Fixes: 78ebbff6d1a0 ("reset: handle removing supplier before consumers")
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Tested-by: Steven Price <steven.price@arm.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patch.msgid.link/20260521210915.2331176-1-heiko@sntech.de
arch/arm/mach-rockchip/platsmp.c

index f432d22bfed8444267b31236d2b0cbed25c23f6a..f659d894bfae4570df22b1599fd03d78c524da01 100644 (file)
@@ -34,6 +34,7 @@ static int ncores;
 
 static struct regmap *pmu;
 static int has_pmu = true;
+static struct reset_control *cpu_rstc[4];
 
 static int pmu_power_domain_is_on(int pd)
 {
@@ -64,9 +65,11 @@ static struct reset_control *rockchip_get_core_reset(int cpu)
 static int pmu_set_power_domain(int pd, bool on)
 {
        u32 val = (on) ? 0 : BIT(pd);
-       struct reset_control *rstc = rockchip_get_core_reset(pd);
+       struct reset_control *rstc;
        int ret;
 
+       rstc = pd < ARRAY_SIZE(cpu_rstc) ? cpu_rstc[pd] : ERR_PTR(-EINVAL);
+
        if (IS_ERR(rstc) && read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) {
                pr_err("%s: could not get reset control for core %d\n",
                       __func__, pd);
@@ -100,11 +103,8 @@ static int pmu_set_power_domain(int pd, bool on)
                }
        }
 
-       if (!IS_ERR(rstc)) {
-               if (on)
-                       reset_control_deassert(rstc);
-               reset_control_put(rstc);
-       }
+       if (!IS_ERR(rstc) && on)
+               reset_control_deassert(rstc);
 
        return 0;
 }
@@ -312,6 +312,10 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus)
                ncores = ((l2ctlr >> 24) & 0x3) + 1;
        }
 
+       /* Collect cpu core reset control for each core */
+       for (i = 0; i < ncores; i++)
+               cpu_rstc[i] = rockchip_get_core_reset(i);
+
        /* Make sure that all cores except the first are really off */
        for (i = 1; i < ncores; i++)
                pmu_set_power_domain(0 + i, false);