[PATCH] ASoC: samsung: i2s: Fix runtime PM usage count leak on failed trigger

From: Xiangwu Lai

Date: Mon Nov 02 2026 - 20:31:51 EST


i2s_trigger() calls pm_runtime_get_sync() when the stream is started,
but if config_setup() fails it returns -EINVAL directly without
dropping the reference. The matching pm_runtime_put() only runs in
the STOP path.

Neither the ASoC core nor the PCM core will issue a compensating
TRIGGER_STOP for the DAI whose trigger callback failed, so the usage
count stays incremented and the I2S device, together with its clocks,
can never runtime suspend afterwards. Each failed stream start adds
another reference.

Drop the runtime PM reference before returning the error. The put()
must happen outside the scoped_guard() section because it may sleep.

Fixes: dc938ddb5628 ("ASoC: samsung: i2s: Ensure proper runtime PM state of I2S device")
Signed-off-by: Xiangwu Lai <laixiangwu@xxxxxxxxxxxxxxxxxxxx>
---
sound/soc/samsung/i2s.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 442e70b10..30a188f54 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -936,7 +936,7 @@ static int i2s_trigger(struct snd_pcm_substream *substream,

scoped_guard(spinlock_irqsave, &priv->lock) {
if (config_setup(i2s))
- return -EINVAL;
+ goto err_put;

if (priv->fixup_late)
priv->fixup_late(substream, dai);
@@ -964,6 +964,10 @@ static int i2s_trigger(struct snd_pcm_substream *substream,
}

return 0;
+
+err_put:
+ pm_runtime_put(dai->dev);
+ return -EINVAL;
}

static int i2s_set_clkdiv(struct snd_soc_dai *dai,