[PATCH 2/2] ASoC: img: img-spdif-in: Fix clock leak on probe failure

From: phucduc . bui

Date: Wed Oct 28 2026 - 06:48:26 EST


From: bui duc phuc <phucduc.bui@xxxxxxxxx>

The error path of img_spdif_in_probe() only suspends the device by hand
when runtime PM is not enabled, and otherwise relies on the asynchronous
suspend request queued by pm_runtime_put(). The pm_runtime_disable()
call that follows cancels that request if it is still pending, leaving
the sys clock enabled. This happens in particular when the reset
control lookup returns -EPROBE_DEFER.

Disable runtime PM first and then suspend the device by hand if it is
not suspended, as img_spdif_in_dev_remove() does. On the -EPROBE_DEFER
path, call pm_runtime_put_noidle() directly and drop the err_pm_put
label, as there is no point in queuing a suspend request that gets
cancelled right away.

Signed-off-by: bui duc phuc <phucduc.bui@xxxxxxxxx>
---
sound/soc/img/img-spdif-in.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/sound/soc/img/img-spdif-in.c b/sound/soc/img/img-spdif-in.c
index b630644f20cc..d60eb1da4ecd 100644
--- a/sound/soc/img/img-spdif-in.c
+++ b/sound/soc/img/img-spdif-in.c
@@ -722,7 +722,8 @@ static int img_spdif_in_probe(struct platform_device *pdev)
if (IS_ERR(rst)) {
if (PTR_ERR(rst) == -EPROBE_DEFER) {
ret = -EPROBE_DEFER;
- goto err_pm_put;
+ pm_runtime_put_noidle(&pdev->dev);
+ goto err_suspend;
}
dev_dbg(dev, "No top level reset found\n");
img_spdif_in_writel(spdif, IMG_SPDIF_IN_SOFT_RESET_MASK,
@@ -763,11 +764,13 @@ static int img_spdif_in_probe(struct platform_device *pdev)

return 0;

-err_pm_put:
- pm_runtime_put(&pdev->dev);
err_suspend:
- if (!pm_runtime_enabled(&pdev->dev))
+ pm_runtime_disable(&pdev->dev);
+ if (!pm_runtime_status_suspended(&pdev->dev))
img_spdif_in_runtime_suspend(&pdev->dev);
+
+ return ret;
+
err_pm_disable:
pm_runtime_disable(&pdev->dev);

--
2.43.0