[PATCH v2] spi: sunplus-sp7021: fix clock prepare leak in system sleep suspend

From: zhaofeng2

Date: Tue Nov 10 2026 - 21:43:26 EST


From: Zhao Feng <zhaofeng2@xxxxxxxxxxxxxxxxxxxx>

sp7021_spi_controller_resume() enables the controller clock with
clk_prepare_enable(), but the matching suspend callback
sp7021_spi_controller_suspend() only asserts the reset line and never
disables/unprepares the clock. Every system sleep suspend/resume cycle
therefore leaks one clock prepare/enable reference, leaving the clock
usage count permanently unbalanced.

Add the missing clk_disable_unprepare() to the suspend callback, and
reorder resume to enable the clock before deasserting reset, so the IP
is never live while its clock is stopped; this matches the probe()
ordering (devm_clk_get_enabled() before reset_control_deassert()).

Fixes: f62ca4e2a863 ("spi: Add spi driver for Sunplus SP7021")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Zhao Feng <zhaofeng2@xxxxxxxxxxxxxxxxxxxx>
---
v1 -> v2: Assert reset before disabling the clock in suspend, and
enable the clock before deasserting reset in resume, per Mark Brown's
review, so the IP is not left running without a clock (nor live while
the clock is stopped).

Verified against current upstream master; the probe path has been
converted to devm_clk_get_enabled() upstream but the suspend/resume
asymmetry is unchanged. Not runtime-tested (no SP7021 hardware).

drivers/spi/spi-sunplus-sp7021.c | 16 ++++++++++++----
1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-sunplus-sp7021.c b/drivers/spi/spi-sunplus-sp7021.c
--- a/drivers/spi/spi-sunplus-sp7021.c
+++ b/drivers/spi/spi-sunplus-sp7021.c
@@ -507,17 +507,27 @@
{
struct spi_controller *ctlr = dev_get_drvdata(dev);
struct sp7021_spi_ctlr *pspim = spi_controller_get_devdata(ctlr);
-
- return reset_control_assert(pspim->rstc);
+ int ret;
+
+ ret = reset_control_assert(pspim->rstc);
+ clk_disable_unprepare(pspim->spi_clk);
+
+ return ret;
}

static int sp7021_spi_controller_resume(struct device *dev)
{
struct spi_controller *ctlr = dev_get_drvdata(dev);
struct sp7021_spi_ctlr *pspim = spi_controller_get_devdata(ctlr);
+ int ret;
+
+ ret = clk_prepare_enable(pspim->spi_clk);
+ if (ret)
+ return ret;

reset_control_deassert(pspim->rstc);
- return clk_prepare_enable(pspim->spi_clk);
+
+ return 0;
}

static int sp7021_spi_runtime_suspend(struct device *dev)