[PATCH 4/5] soundwire: cadence: allocate/free dma_data in set_sdw_stream

From: Bard Liao
Date: Tue Jun 23 2020 - 05:18:05 EST


From: Pierre-Louis Bossart <pierre-louis.bossart@xxxxxxxxxxxxxxx>

The current memory allocation is somewhat strange: the dma_data is
allocated in set_sdw_stream, but released in the intel DAI
shutdown. This no longer works with the multi-cpu implementation,
since the dma_data is released in the dai shutdown which takes place
before the dailink shutdown.

Move to a more symmetric allocation where the dma_data is allocated
with non-NULL SoundWire stream, and conversely released when a NULL
stream is provided - for consistency with the stream startup and
shutdown operations.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@xxxxxxxxxxxxxxx>
Signed-off-by: Bard Liao <yung-chuan.liao@xxxxxxxxxxxxxxx>
---
drivers/soundwire/cadence_master.c | 52 ++++++++++++++++++++++--------
1 file changed, 38 insertions(+), 14 deletions(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index 5c0df066bfc6..24eafe0aa1c3 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -1439,25 +1439,49 @@ int cdns_set_sdw_stream(struct snd_soc_dai *dai,
struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
struct sdw_cdns_dma_data *dma;

- dma = kzalloc(sizeof(*dma), GFP_KERNEL);
- if (!dma)
- return -ENOMEM;
+ if (stream) {
+ /* first paranoia check */
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK)
+ dma = dai->playback_dma_data;
+ else
+ dma = dai->capture_dma_data;

- if (pcm)
- dma->stream_type = SDW_STREAM_PCM;
- else
- dma->stream_type = SDW_STREAM_PDM;
+ if (dma) {
+ dev_err(dai->dev,
+ "dma_data already allocated for dai %s\n",
+ dai->name);
+ return -EINVAL;
+ }

- dma->bus = &cdns->bus;
- dma->link_id = cdns->instance;
+ /* allocate and set dma info */
+ dma = kzalloc(sizeof(*dma), GFP_KERNEL);
+ if (!dma)
+ return -ENOMEM;

- dma->stream = stream;
+ if (pcm)
+ dma->stream_type = SDW_STREAM_PCM;
+ else
+ dma->stream_type = SDW_STREAM_PDM;

- if (direction == SNDRV_PCM_STREAM_PLAYBACK)
- dai->playback_dma_data = dma;
- else
- dai->capture_dma_data = dma;
+ dma->bus = &cdns->bus;
+ dma->link_id = cdns->instance;

+ dma->stream = stream;
+
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK)
+ dai->playback_dma_data = dma;
+ else
+ dai->capture_dma_data = dma;
+ } else {
+ /* for NULL stream we release allocated dma_data */
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ kfree(dai->playback_dma_data);
+ dai->playback_dma_data = NULL;
+ } else {
+ kfree(dai->capture_dma_data);
+ dai->capture_dma_data = NULL;
+ }
+ }
return 0;
}
EXPORT_SYMBOL(cdns_set_sdw_stream);
--
2.17.1