Skip to content

Commit be1fae6

Browse files
Srinivas-Kandagatlabroonie
authored andcommitted
ASoC: q6apm-lpass-dai: close graph on prepare errors
There is an issue around with error handling and graph management with the exising code, none of the error paths close the graph, which result in leaving the loaded graph in dsp, however the driver thinks otherwise. This can have a nasty side effect specially when we try to load the same graph to dsp, dsp returns error which leaves the board with no sound and requires restart. Fix this by properly closing the graph when we hit errors between open and close. Fixes: 30ad723 ("ASoC: qdsp6: audioreach: add q6apm lpass dai support") Signed-off-by: Srinivas Kandagatla <[email protected]> Reviewed-by: Dmitry Baryshkov <[email protected]> Tested-by: Dmitry Baryshkov <[email protected]> # X13s Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 8af4986 commit be1fae6

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

sound/soc/qcom/qdsp6/q6apm-lpass-dais.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,17 @@ static void q6apm_lpass_dai_shutdown(struct snd_pcm_substream *substream, struct
141141
struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
142142
int rc;
143143

144-
if (!dai_data->is_port_started[dai->id])
145-
return;
146-
rc = q6apm_graph_stop(dai_data->graph[dai->id]);
147-
if (rc < 0)
148-
dev_err(dai->dev, "fail to close APM port (%d)\n", rc);
144+
if (dai_data->is_port_started[dai->id]) {
145+
rc = q6apm_graph_stop(dai_data->graph[dai->id]);
146+
dai_data->is_port_started[dai->id] = false;
147+
if (rc < 0)
148+
dev_err(dai->dev, "fail to close APM port (%d)\n", rc);
149+
}
149150

150-
q6apm_graph_close(dai_data->graph[dai->id]);
151-
dai_data->is_port_started[dai->id] = false;
151+
if (dai_data->graph[dai->id]) {
152+
q6apm_graph_close(dai_data->graph[dai->id]);
153+
dai_data->graph[dai->id] = NULL;
154+
}
152155
}
153156

154157
static int q6apm_lpass_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
@@ -163,8 +166,10 @@ static int q6apm_lpass_dai_prepare(struct snd_pcm_substream *substream, struct s
163166
q6apm_graph_stop(dai_data->graph[dai->id]);
164167
dai_data->is_port_started[dai->id] = false;
165168

166-
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
169+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
167170
q6apm_graph_close(dai_data->graph[dai->id]);
171+
dai_data->graph[dai->id] = NULL;
172+
}
168173
}
169174

170175
/**
@@ -183,26 +188,29 @@ static int q6apm_lpass_dai_prepare(struct snd_pcm_substream *substream, struct s
183188

184189
cfg->direction = substream->stream;
185190
rc = q6apm_graph_media_format_pcm(dai_data->graph[dai->id], cfg);
186-
187191
if (rc) {
188192
dev_err(dai->dev, "Failed to set media format %d\n", rc);
189-
return rc;
193+
goto err;
190194
}
191195

192196
rc = q6apm_graph_prepare(dai_data->graph[dai->id]);
193197
if (rc) {
194198
dev_err(dai->dev, "Failed to prepare Graph %d\n", rc);
195-
return rc;
199+
goto err;
196200
}
197201

198202
rc = q6apm_graph_start(dai_data->graph[dai->id]);
199203
if (rc < 0) {
200204
dev_err(dai->dev, "fail to start APM port %x\n", dai->id);
201-
return rc;
205+
goto err;
202206
}
203207
dai_data->is_port_started[dai->id] = true;
204208

205209
return 0;
210+
err:
211+
q6apm_graph_close(dai_data->graph[dai->id]);
212+
dai_data->graph[dai->id] = NULL;
213+
return rc;
206214
}
207215

208216
static int q6apm_lpass_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)

0 commit comments

Comments
 (0)