]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ASoC: qcom: q6asm-dai: close stream only when running
authorSrinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
Mon, 18 May 2026 09:23:44 +0000 (09:23 +0000)
committerMark Brown <broonie@kernel.org>
Mon, 25 May 2026 12:46:44 +0000 (13:46 +0100)
q6asm_dai_close() and q6asm_dai_compr_free() currently issue CMD_CLOSE
whenever prtd->state is non-zero.

After prepare() closes an existing stream, the state is updated to
Q6ASM_STREAM_STOPPED. Since this state is also non-zero, the close and
free paths can send CMD_CLOSE again for a stream that has already been
closed.

Restrict CMD_CLOSE to the Q6ASM_STREAM_RUNNING state so the command is
sent only when the ASM stream is still active.

Fixes: 2a9e92d371db ("ASoC: qdsp6: q6asm: Add q6asm dai driver")
Cc: Stable@vger.kernel.org
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
Link: https://patch.msgid.link/20260518092347.3446946-3-srinivas.kandagatla@oss.qualcomm.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/qcom/qdsp6/q6asm-dai.c

index 56f0d8913904d6d3ce81ed1e71dfab5842b9f958..ef86b5b9a951aba40f6f196ac7bab413ae1d9098 100644 (file)
@@ -455,12 +455,12 @@ static int q6asm_dai_close(struct snd_soc_component *component,
        struct q6asm_dai_rtd *prtd = runtime->private_data;
 
        if (prtd->audio_client) {
-               if (prtd->state)
+               if (prtd->state == Q6ASM_STREAM_RUNNING) {
                        q6asm_cmd(prtd->audio_client, prtd->stream_id,
                                  CMD_CLOSE);
-
-               q6asm_unmap_memory_regions(substream->stream,
+                       q6asm_unmap_memory_regions(substream->stream,
                                           prtd->audio_client);
+               }
                q6asm_audio_client_free(prtd->audio_client);
                prtd->audio_client = NULL;
        }
@@ -670,7 +670,7 @@ static int q6asm_dai_compr_free(struct snd_soc_component *component,
        struct snd_soc_pcm_runtime *rtd = stream->private_data;
 
        if (prtd->audio_client) {
-               if (prtd->state) {
+               if (prtd->state == Q6ASM_STREAM_RUNNING) {
                        q6asm_cmd(prtd->audio_client, prtd->stream_id,
                                  CMD_CLOSE);
                        if (prtd->next_track_stream_id) {
@@ -678,11 +678,11 @@ static int q6asm_dai_compr_free(struct snd_soc_component *component,
                                          prtd->next_track_stream_id,
                                          CMD_CLOSE);
                        }
-               }
 
-               snd_dma_free_pages(&prtd->dma_buffer);
-               q6asm_unmap_memory_regions(stream->direction,
+                       q6asm_unmap_memory_regions(stream->direction,
                                           prtd->audio_client);
+               }
+               snd_dma_free_pages(&prtd->dma_buffer);
                q6asm_audio_client_free(prtd->audio_client);
                prtd->audio_client = NULL;
        }