[PATCH] drm/stm/ltdc: Fix clock cleanup error handling

From: Hongling Zeng

Date: Sun Jul 12 2026 - 21:48:59 EST


When clk_prepare_enable() fails for bus_clk or lvds_clk, the previously
prepared clocks are not cleaned up, leading to resource leaks.

In ltdc_resume():
- If bus_clk preparation fails, pixel_clk remains prepared
- If lvds_clk preparation fails, both pixel_clk and bus_clk remain prepared

In ltdc_load():
- If bus_clk preparation fails, pixel_clk remains prepared

Fix this by adding proper error handling to ensure all prepared clocks
are disabled and unprepared when a subsequent clock preparation fails.

Fixes: df61c776657f ("drm/stm: add sleep power management")
Fixes: d80667642b0f ("drm/stm: ltdc: support new hardware version for STM32MP25 SoC")
Fixes: b7243862f82a ("drm/stm: ltdc: handle lvds pixel clock")
Signed-off-by: Hongling Zeng <zenghongling@xxxxxxxxxx>
---
drivers/gpu/drm/stm/ltdc.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 95fcfa48d8be..ead9e87bd719 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -1907,16 +1907,25 @@ int ltdc_resume(struct drm_device *ddev)
ret = clk_prepare_enable(ldev->bus_clk);
if (ret) {
drm_err(ddev, "failed to enable bus clock (%d)\n", ret);
- return ret;
+ goto err_pixel;
}
}

if (ldev->lvds_clk) {
ret = clk_prepare_enable(ldev->lvds_clk);
- if (ret)
+ if (ret) {
drm_err(ddev, "failed to prepare lvds clock\n");
+ goto err_bus;
+ }
}

+ return 0;
+
+err_bus:
+ if (ldev->bus_clk)
+ clk_disable_unprepare(ldev->bus_clk);
+err_pixel:
+ clk_disable_unprepare(ldev->pixel_clk);
return ret;
}

@@ -1962,7 +1971,7 @@ int ltdc_load(struct drm_device *ddev)
ret = clk_prepare_enable(ldev->bus_clk);
if (ret) {
drm_err(ddev, "Unable to prepare bus clock\n");
- return ret;
+ goto err;
}
}

--
2.25.1