From 75ef233975589d9a8c88bc8822a7c725c71ff650 Mon Sep 17 00:00:00 2001 From: Felix Gu Date: Wed, 6 May 2026 19:29:02 +0800 Subject: [PATCH 1/2] soc: microchip: mpfs-sys-controller: fix resource leak on probe error In mpfs_sys_controller_probe(), when device_get_match_data() returns NULL, it returns -EINVAL directly without freeing the mbox channel or the allocated sys_controller memory, causing a resource leak. Fixes: 63b5305ad84d ("soc: microchip: mpfs-sys-controller: add support for pic64gx") Signed-off-by: Felix Gu Signed-off-by: Conor Dooley --- drivers/soc/microchip/mpfs-sys-controller.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/soc/microchip/mpfs-sys-controller.c b/drivers/soc/microchip/mpfs-sys-controller.c index 92d1142a59e6..0400a01b2338 100644 --- a/drivers/soc/microchip/mpfs-sys-controller.c +++ b/drivers/soc/microchip/mpfs-sys-controller.c @@ -158,8 +158,8 @@ no_flash: of_data = (struct mpfs_syscon_config *) device_get_match_data(dev); if (!of_data) { - dev_err(dev, "Error getting match data\n"); - return -EINVAL; + ret = dev_err_probe(dev, -EINVAL, "Error getting match data\n"); + goto out_free_channel; } for (i = 0; i < of_data->nb_subdevs; i++) { @@ -173,6 +173,8 @@ no_flash: return 0; +out_free_channel: + mbox_free_channel(sys_controller->chan); out_free: kfree(sys_controller); return ret; From 6fc5666aa576c6c3bec256fa31d72653210319d5 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 21 May 2026 23:09:15 +0200 Subject: [PATCH 2/2] ARM: rockchip: keep reset control around 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 Tested-by: Steven Price Signed-off-by: Heiko Stuebner Link: https://patch.msgid.link/20260521210915.2331176-1-heiko@sntech.de --- arch/arm/mach-rockchip/platsmp.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c index f432d22bfed8..f659d894bfae 100644 --- a/arch/arm/mach-rockchip/platsmp.c +++ b/arch/arm/mach-rockchip/platsmp.c @@ -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);