ASoC: qcom: q6asm-dai: fix error handling

Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com> says:

Here is the set of patches, that fixes one of the isssue reported by
Richard Acayan, while doing fix for the reported issue, found various
other issues in the existing code.

This set contains some of those cleanups along with few trivial coding
style patches which looked uncomfortable to read.

Patch 1 should be enough to fix the issue reported.

Tested this is on UNO-Q.

Link: https://patch.msgid.link/20260518092347.3446946-1-srinivas.kandagatla@oss.qualcomm.com
This commit is contained in:
Mark Brown 2026-05-25 13:46:48 +01:00
commit 500eb0203c
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -186,12 +186,10 @@ static void event_handler(uint32_t opcode, uint32_t token,
case ASM_CLIENT_EVENT_CMD_RUN_DONE:
break;
case ASM_CLIENT_EVENT_CMD_EOS_DONE:
prtd->state = Q6ASM_STREAM_STOPPED;
break;
case ASM_CLIENT_EVENT_DATA_WRITE_DONE: {
case ASM_CLIENT_EVENT_DATA_WRITE_DONE:
snd_pcm_period_elapsed(substream);
break;
}
case ASM_CLIENT_EVENT_DATA_READ_DONE:
snd_pcm_period_elapsed(substream);
if (prtd->state == Q6ASM_STREAM_RUNNING)
@ -227,9 +225,19 @@ static int q6asm_dai_prepare(struct snd_soc_component *component,
/* rate and channels are sent to audio driver */
if (prtd->state == Q6ASM_STREAM_RUNNING) {
/* clear the previous setup if any */
q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE);
q6asm_unmap_memory_regions(substream->stream,
prtd->audio_client);
ret = q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE);
if (ret < 0) {
dev_err(dev, "Failed to close q6asm stream %d\n", prtd->stream_id);
return ret;
}
ret = q6asm_unmap_memory_regions(substream->stream, prtd->audio_client);
if (ret < 0) {
dev_err(dev, "Failed to unmap memory regions for q6asm stream %d\n",
prtd->stream_id);
return ret;
}
q6routing_stream_close(soc_prtd->dai_link->id,
substream->stream);
prtd->state = Q6ASM_STREAM_STOPPED;
@ -297,8 +305,6 @@ static int q6asm_dai_prepare(struct snd_soc_component *component,
q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE);
open_err:
q6asm_unmap_memory_regions(substream->stream, prtd->audio_client);
q6asm_audio_client_free(prtd->audio_client);
prtd->audio_client = NULL;
return ret;
}
@ -341,7 +347,6 @@ static int q6asm_dai_trigger(struct snd_soc_component *component,
0, 0, 0);
break;
case SNDRV_PCM_TRIGGER_STOP:
prtd->state = Q6ASM_STREAM_STOPPED;
ret = q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id,
CMD_EOS);
break;
@ -378,7 +383,7 @@ static int q6asm_dai_open(struct snd_soc_component *component,
return -EINVAL;
}
prtd = kzalloc_obj(struct q6asm_dai_rtd);
prtd = kzalloc_obj(*prtd);
if (prtd == NULL)
return -ENOMEM;
@ -457,12 +462,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;
}
@ -555,8 +560,6 @@ static void compress_event_handler(uint32_t opcode, uint32_t token,
snd_compr_drain_notify(prtd->cstream);
prtd->notify_on_drain = false;
} else {
prtd->state = Q6ASM_STREAM_STOPPED;
}
break;
@ -674,7 +677,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) {
@ -682,11 +685,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;
}
@ -916,7 +919,7 @@ static int q6asm_dai_compr_set_params(struct snd_soc_component *component,
prtd->session_id, dir);
if (ret) {
dev_err(dev, "Stream reg failed ret:%d\n", ret);
goto q6_err;
goto routing_err;
}
ret = __q6asm_dai_compr_set_codec_params(component, stream,
@ -942,11 +945,11 @@ static int q6asm_dai_compr_set_params(struct snd_soc_component *component,
return 0;
q6_err:
q6routing_stream_close(rtd->dai_link->id, dir);
routing_err:
q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE);
open_err:
q6asm_audio_client_free(prtd->audio_client);
prtd->audio_client = NULL;
return ret;
}
@ -1014,7 +1017,6 @@ static int q6asm_dai_compr_trigger(struct snd_soc_component *component,
0, 0, 0);
break;
case SNDRV_PCM_TRIGGER_STOP:
prtd->state = Q6ASM_STREAM_STOPPED;
ret = q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id,
CMD_EOS);
break;