[PATCH v4 3/5] ASoC: fsl_asrc/fsl_easrc: move DMA params into pair/context struct

Frank Li Frank.li at oss.nxp.com
Thu Aug 13 09:52:17 PDT 2026


On Thu, Aug 13, 2026 at 03:00:18PM +0800, shengjiu.wang at oss.nxp.com wrote:
> From: Shengjiu Wang <shengjiu.wang at nxp.com>
>
> 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 <shengjiu.wang at nxp.com>
> ---

Reviewed-by: Frank Li <Frank.Li at nxp.com>

>  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 2f662bdf14d0..15f2dccc3584 100644
> --- a/sound/soc/fsl/fsl_asrc_dma.c
> +++ b/sound/soc/fsl/fsl_asrc_dma.c
> @@ -392,6 +392,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 77c5009cc01f..d23ee482924b 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
>
>



More information about the linux-arm-kernel mailing list