summaryrefslogtreecommitdiff
path: root/drivers/soundwire
diff options
context:
space:
mode:
authorKrzysztof Kozlowski <krzysztof.kozlowski@linaro.org>2023-11-28 17:56:38 +0100
committerMark Brown <broonie@kernel.org>2023-11-29 18:53:25 +0000
commit15c7fab0e0477d7d7185eac574ca43c15b59b015 (patch)
tree681365789a2a48917ea9a40f752601a08432b5bc /drivers/soundwire
parentd32bac9cb09cce4dc3131ec5d0b6ba3c277502ac (diff)
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 <krzysztof.kozlowski@linaro.org> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20231128165638.757665-2-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/soundwire')
-rw-r--r--drivers/soundwire/qcom.c33
1 files changed, 1 insertions, 32 deletions
diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c
index a1e2d6c98186..8076d40407d4 100644
--- a/drivers/soundwire/qcom.c
+++ b/drivers/soundwire/qcom.c
@@ -1265,10 +1265,7 @@ static int qcom_swrm_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dai->dev);
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct sdw_stream_runtime *sruntime;
- struct snd_soc_dai *codec_dai;
- int ret, i;
+ int ret;
ret = pm_runtime_get_sync(ctrl->dev);
if (ret < 0 && ret != -EACCES) {
@@ -1279,33 +1276,7 @@ static int qcom_swrm_startup(struct snd_pcm_substream *substream,
return ret;
}
- sruntime = sdw_alloc_stream(dai->name);
- if (!sruntime) {
- ret = -ENOMEM;
- goto err_alloc;
- }
-
- ctrl->sruntime[dai->id] = sruntime;
-
- for_each_rtd_codec_dais(rtd, i, codec_dai) {
- ret = snd_soc_dai_set_stream(codec_dai, sruntime,
- substream->stream);
- if (ret < 0 && ret != -ENOTSUPP) {
- dev_err(dai->dev, "Failed to set sdw stream on %s\n",
- codec_dai->name);
- goto err_set_stream;
- }
- }
-
return 0;
-
-err_set_stream:
- sdw_release_stream(sruntime);
-err_alloc:
- pm_runtime_mark_last_busy(ctrl->dev);
- pm_runtime_put_autosuspend(ctrl->dev);
-
- return ret;
}
static void qcom_swrm_shutdown(struct snd_pcm_substream *substream,
@@ -1314,8 +1285,6 @@ static void qcom_swrm_shutdown(struct snd_pcm_substream *substream,
struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dai->dev);
swrm_wait_for_wr_fifo_done(ctrl);
- sdw_release_stream(ctrl->sruntime[dai->id]);
- ctrl->sruntime[dai->id] = NULL;
pm_runtime_mark_last_busy(ctrl->dev);
pm_runtime_put_autosuspend(ctrl->dev);