diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c index 4f8f7db6c3d3..4f09fdd40905 100644 --- a/sound/soc/qcom/qdsp6/q6asm-dai.c +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c @@ -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;