Skip to content

Commit f6e1138

Browse files
Srinivas-Kandagatlagregkh
authored andcommitted
ASoC: q6apm-lpass-dai: close graph on prepare errors
[ Upstream commit be1fae6 ] 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 <srinivas.kandagatla@linaro.org> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Tested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> # X13s Link: https://lore.kernel.org/r/20240613-q6apm-fixes-v1-1-d88953675ab3@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org> Stable-dep-of: 68f27f7 ("ASoC: qcom: q6apm-lpass-dais: Fix NULL pointer dereference if source graph failed") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 09ff1b1 commit f6e1138

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
@@ -109,14 +109,17 @@ static void q6apm_lpass_dai_shutdown(struct snd_pcm_substream *substream, struct
109109
struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
110110
int rc;
111111

112-
if (!dai_data->is_port_started[dai->id])
113-
return;
114-
rc = q6apm_graph_stop(dai_data->graph[dai->id]);
115-
if (rc < 0)
116-
dev_err(dai->dev, "fail to close APM port (%d)\n", rc);
112+
if (dai_data->is_port_started[dai->id]) {
113+
rc = q6apm_graph_stop(dai_data->graph[dai->id]);
114+
dai_data->is_port_started[dai->id] = false;
115+
if (rc < 0)
116+
dev_err(dai->dev, "fail to close APM port (%d)\n", rc);
117+
}
117118

118-
q6apm_graph_close(dai_data->graph[dai->id]);
119-
dai_data->is_port_started[dai->id] = false;
119+
if (dai_data->graph[dai->id]) {
120+
q6apm_graph_close(dai_data->graph[dai->id]);
121+
dai_data->graph[dai->id] = NULL;
122+
}
120123
}
121124

122125
static int q6apm_lpass_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
@@ -131,8 +134,10 @@ static int q6apm_lpass_dai_prepare(struct snd_pcm_substream *substream, struct s
131134
q6apm_graph_stop(dai_data->graph[dai->id]);
132135
dai_data->is_port_started[dai->id] = false;
133136

134-
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
137+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
135138
q6apm_graph_close(dai_data->graph[dai->id]);
139+
dai_data->graph[dai->id] = NULL;
140+
}
136141
}
137142

138143
/**
@@ -151,26 +156,29 @@ static int q6apm_lpass_dai_prepare(struct snd_pcm_substream *substream, struct s
151156

152157
cfg->direction = substream->stream;
153158
rc = q6apm_graph_media_format_pcm(dai_data->graph[dai->id], cfg);
154-
155159
if (rc) {
156160
dev_err(dai->dev, "Failed to set media format %d\n", rc);
157-
return rc;
161+
goto err;
158162
}
159163

160164
rc = q6apm_graph_prepare(dai_data->graph[dai->id]);
161165
if (rc) {
162166
dev_err(dai->dev, "Failed to prepare Graph %d\n", rc);
163-
return rc;
167+
goto err;
164168
}
165169

166170
rc = q6apm_graph_start(dai_data->graph[dai->id]);
167171
if (rc < 0) {
168172
dev_err(dai->dev, "fail to start APM port %x\n", dai->id);
169-
return rc;
173+
goto err;
170174
}
171175
dai_data->is_port_started[dai->id] = true;
172176

173177
return 0;
178+
err:
179+
q6apm_graph_close(dai_data->graph[dai->id]);
180+
dai_data->graph[dai->id] = NULL;
181+
return rc;
174182
}
175183

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

0 commit comments

Comments
 (0)