[PATCH v3 3/5] ASoC: fsl_asrc/fsl_easrc: move DMA params into pair/context struct
[email protected] Tue, 4 Aug 2026 18:02:16 +0800
| Newsgroups | gmane.linux.ports.ppc.embedded,gmane.linux.sound,gmane.linux.drivers.devicetree,gmane.linux.ports.arm.kernel,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Shengjiu Wang <[email protected]> The shared dma_params_tx/rx fields in struct fsl_asrc were a single instance written by every concurrent fsl_asrc_dma_hw_params() call. With multiple DAIs registered (one per pair/context), parallel stream open+hw_params races would corrupt addr and maxburst for all active streams. Fix by moving dma_params into struct fsl_asrc_pair so each pair owns its own copy. Initialise them in fsl_asrc_dma_startup() where the pair is allocated, which makes the per-DAI probe callbacks in fsl_asrc.c and fsl_easrc.c redundant; remove those as well. Signed-off-by: Shengjiu Wang <[email protected]> --- sound/soc/fsl/fsl_asrc.c | 11 ----------- sound/soc/fsl/fsl_asrc_common.h | 7 +++---- sound/soc/fsl/fsl_asrc_dma.c | 14 ++++++++++++++ sound/soc/fsl/fsl_easrc.c | 11 ----------- 4 files changed, 17 insertions(+), 26 deletions(-) diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index df4817ae91b1..2755ee57c6a1 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -781,18 +781,7 @@ static int fsl_asrc_dai_trigger(struct snd_pcm_substream *substream, int cmd, return 0; } -static int fsl_asrc_dai_probe(struct snd_soc_dai *dai) -{ - struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai); - - snd_soc_dai_init_dma_data(dai, &asrc->dma_params_tx, - &asrc->dma_params_rx); - - return 0; -} - static const struct snd_soc_dai_ops fsl_asrc_dai_ops = { - .probe = fsl_asrc_dai_probe, .startup = fsl_asrc_dai_startup, .hw_params = fsl_asrc_dai_hw_params, .hw_free = fsl_asrc_dai_hw_free, diff --git a/sound/soc/fsl/fsl_asrc_common.h b/sound/soc/fsl/fsl_asrc_common.h index c8a1a2b5915d..4e6b00cb5d63 100644 --- a/sound/soc/fsl/fsl_asrc_common.h +++ b/sound/soc/fsl/fsl_asrc_common.h @@ -53,6 +53,7 @@ struct fsl_asrc_m2m_cap { * @dma_data: private dma data * @pos: hardware pointer position * @req_dma_chan: flag to release dev_to_dev chan + * @dma_params: DMA parameters for transmit/receive channel * @private: pair private area * @complete: dma task complete * @sample_format: format of m2m @@ -76,6 +77,8 @@ struct fsl_asrc_pair { unsigned int pos; bool req_dma_chan; + struct snd_dmaengine_dai_dma_data dma_params; + void *private; /* used for m2m */ @@ -92,8 +95,6 @@ struct fsl_asrc_pair { /** * fsl_asrc: ASRC common data * - * @dma_params_rx: DMA parameters for receive channel - * @dma_params_tx: DMA parameters for transmit channel * @pdev: platform device pointer * @regmap: regmap handler * @paddr: physical address to the base address of registers @@ -128,8 +129,6 @@ struct fsl_asrc_pair { * @private: private data structure */ struct fsl_asrc { - struct snd_dmaengine_dai_dma_data dma_params_rx; - struct snd_dmaengine_dai_dma_data dma_params_tx; struct platform_device *pdev; struct regmap *regmap; unsigned long paddr; diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c index 38f2b7c63133..64d66420e7ad 100644 --- a/sound/soc/fsl/fsl_asrc_dma.c +++ b/sound/soc/fsl/fsl_asrc_dma.c @@ -390,6 +390,20 @@ static int fsl_asrc_dma_startup(struct snd_soc_component *component, runtime->private_data = pair; + /* + * Point the cpu DAI dma_data at the per-pair params so that + * concurrent hw_params calls on different pairs each write to + * their own struct and do not race on addr/maxburst. Use the + * per-direction setters so that a concurrent open of the other + * direction on the same DAI does not NULL out its pointer. + */ + if (tx) + snd_soc_dai_dma_data_set_playback(snd_soc_rtd_to_cpu(rtd, 0), + &pair->dma_params); + else + snd_soc_dai_dma_data_set_capture(snd_soc_rtd_to_cpu(rtd, 0), + &pair->dma_params); + /* Request a dummy pair, which will be released later. * Request pair function needs channel num as input, for this * dummy pair, we just request "1" channel temporarily. diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c index bb9e036c7937..f1249da0658c 100644 --- a/sound/soc/fsl/fsl_easrc.c +++ b/sound/soc/fsl/fsl_easrc.c @@ -1582,18 +1582,7 @@ static int fsl_easrc_hw_free(struct snd_pcm_substream *substream, return 0; } -static int fsl_easrc_dai_probe(struct snd_soc_dai *cpu_dai) -{ - struct fsl_asrc *easrc = dev_get_drvdata(cpu_dai->dev); - - snd_soc_dai_init_dma_data(cpu_dai, - &easrc->dma_params_tx, - &easrc->dma_params_rx); - return 0; -} - static const struct snd_soc_dai_ops fsl_easrc_dai_ops = { - .probe = fsl_easrc_dai_probe, .startup = fsl_easrc_startup, .trigger = fsl_easrc_trigger, .hw_params = fsl_easrc_hw_params, -- 2.34.1