Skip to content

Commit 15c7fab

Browse files
krzkbroonie
authored andcommitted
ASoC: qcom: Move Soundwire runtime stream alloc to soundcards
Currently the Qualcomm Soundwire controller in its DAI startup op allocates the Soundwire stream runtime. This works fine for existing designs, but has limitations for stream runtimes with multiple controllers, like upcoming Qualcomm X1E80100 SoC with four WSA8840 speakers on two Soundwire controllers. When two Soundwire controllers are added to sound card codecs, Soundwire startup() is called twice, one for each Soundwire controller, and second execution overwrites what was set before. During shutdown() this causes double free. It is expected to have only one Soundwire stream runtime, thus it should be allocated from SoC soundcard context startup(), not from each Soundwire startup(). Such way will properly handle both cases: one and two Soundwire controllers in the stream runtime. Signed-off-by: Krzysztof Kozlowski <[email protected]> Reviewed-by: Pierre-Louis Bossart <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent d32bac9 commit 15c7fab

File tree

3 files changed

+28
-33
lines changed

3 files changed

+28
-33
lines changed

drivers/soundwire/qcom.c

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,10 +1265,7 @@ static int qcom_swrm_startup(struct snd_pcm_substream *substream,
12651265
struct snd_soc_dai *dai)
12661266
{
12671267
struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dai->dev);
1268-
struct snd_soc_pcm_runtime *rtd = substream->private_data;
1269-
struct sdw_stream_runtime *sruntime;
1270-
struct snd_soc_dai *codec_dai;
1271-
int ret, i;
1268+
int ret;
12721269

12731270
ret = pm_runtime_get_sync(ctrl->dev);
12741271
if (ret < 0 && ret != -EACCES) {
@@ -1279,33 +1276,7 @@ static int qcom_swrm_startup(struct snd_pcm_substream *substream,
12791276
return ret;
12801277
}
12811278

1282-
sruntime = sdw_alloc_stream(dai->name);
1283-
if (!sruntime) {
1284-
ret = -ENOMEM;
1285-
goto err_alloc;
1286-
}
1287-
1288-
ctrl->sruntime[dai->id] = sruntime;
1289-
1290-
for_each_rtd_codec_dais(rtd, i, codec_dai) {
1291-
ret = snd_soc_dai_set_stream(codec_dai, sruntime,
1292-
substream->stream);
1293-
if (ret < 0 && ret != -ENOTSUPP) {
1294-
dev_err(dai->dev, "Failed to set sdw stream on %s\n",
1295-
codec_dai->name);
1296-
goto err_set_stream;
1297-
}
1298-
}
1299-
13001279
return 0;
1301-
1302-
err_set_stream:
1303-
sdw_release_stream(sruntime);
1304-
err_alloc:
1305-
pm_runtime_mark_last_busy(ctrl->dev);
1306-
pm_runtime_put_autosuspend(ctrl->dev);
1307-
1308-
return ret;
13091280
}
13101281

13111282
static void qcom_swrm_shutdown(struct snd_pcm_substream *substream,
@@ -1314,8 +1285,6 @@ static void qcom_swrm_shutdown(struct snd_pcm_substream *substream,
13141285
struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dai->dev);
13151286

13161287
swrm_wait_for_wr_fifo_done(ctrl);
1317-
sdw_release_stream(ctrl->sruntime[dai->id]);
1318-
ctrl->sruntime[dai->id] = NULL;
13191288
pm_runtime_mark_last_busy(ctrl->dev);
13201289
pm_runtime_put_autosuspend(ctrl->dev);
13211290

sound/soc/qcom/sc8280xp.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@ static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
3131
return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup);
3232
}
3333

34+
static void sc8280xp_snd_shutdown(struct snd_pcm_substream *substream)
35+
{
36+
struct snd_soc_pcm_runtime *rtd = substream->private_data;
37+
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
38+
struct sc8280xp_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
39+
struct sdw_stream_runtime *sruntime = pdata->sruntime[cpu_dai->id];
40+
41+
pdata->sruntime[cpu_dai->id] = NULL;
42+
sdw_release_stream(sruntime);
43+
}
44+
3445
static int sc8280xp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
3546
struct snd_pcm_hw_params *params)
3647
{
@@ -91,6 +102,8 @@ static int sc8280xp_snd_hw_free(struct snd_pcm_substream *substream)
91102
}
92103

93104
static const struct snd_soc_ops sc8280xp_be_ops = {
105+
.startup = qcom_snd_sdw_startup,
106+
.shutdown = sc8280xp_snd_shutdown,
94107
.hw_params = sc8280xp_snd_hw_params,
95108
.hw_free = sc8280xp_snd_hw_free,
96109
.prepare = sc8280xp_snd_prepare,

sound/soc/qcom/sm8250.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,19 @@ static int sm8250_snd_startup(struct snd_pcm_substream *substream)
6666
default:
6767
break;
6868
}
69-
return 0;
69+
70+
return qcom_snd_sdw_startup(substream);
71+
}
72+
73+
static void sm2450_snd_shutdown(struct snd_pcm_substream *substream)
74+
{
75+
struct snd_soc_pcm_runtime *rtd = substream->private_data;
76+
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
77+
struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
78+
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
79+
80+
data->sruntime[cpu_dai->id] = NULL;
81+
sdw_release_stream(sruntime);
7082
}
7183

7284
static int sm8250_snd_hw_params(struct snd_pcm_substream *substream,
@@ -103,6 +115,7 @@ static int sm8250_snd_hw_free(struct snd_pcm_substream *substream)
103115

104116
static const struct snd_soc_ops sm8250_be_ops = {
105117
.startup = sm8250_snd_startup,
118+
.shutdown = sm2450_snd_shutdown,
106119
.hw_params = sm8250_snd_hw_params,
107120
.hw_free = sm8250_snd_hw_free,
108121
.prepare = sm8250_snd_prepare,

0 commit comments

Comments
 (0)