[PATCH v10 10/19] dmaengine: ti: k3-udma: refactor resource setup functions

Vignesh Raghavendra vigneshr at ti.com
Mon Sep 28 01:39:34 PDT 2026


> The implementation of setup_resources, bcdma_setup_resources and
> pktdma_setup_resources is largely shared between all K3 UDMA variants
> with the only major difference being SCI resources setup. So,
> - Move the functions to k3-udma-common.c.
> - Split SCI resource setup for bcdma and pktdma into separate functions
>   in variant specific driver (k3-udma.c).
> - Add function pointers for setup_sci_resources in udma_dev and call
>   them as part of the actual resource setup implementations in
>   k3-udma-common.c to retain the existing functionality.
> - Also since setup_resources call udma_setup_resources which is not
>   required for all K3 UDMA variants, Add a function pointer in udma_dev
>   and use that to call udma_setup_resources.
> - Rename setup_resources to k3_udma_setup_resources to avoid polluting
>   global kernel namespace with generic symbol.
> 
> This refactor improves code reuse and maintainability across multiple
> variants.
> 
> No functional changes intended.
> 
> Signed-off-by: Sai Sree Kartheek Adivi <s-adivi at ti.com>
>
> diff --git a/drivers/dma/ti/k3-udma-common.c b/drivers/dma/ti/k3-udma-common.c
> index 34f8eab9ddb5..d0afbab01786 100644
> --- a/drivers/dma/ti/k3-udma-common.c
> +++ b/drivers/dma/ti/k3-udma-common.c
> @@ -8,7 +8,9 @@
>  #include <linux/dmaengine.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/dmapool.h>
> +#include <linux/of.h>
>  #include <linux/platform_device.h>
> +#include <linux/soc/ti/ti_sci_inta_msi.h>
>  #include <linux/soc/ti/k3-ringacc.h>
>  
>  #include "k3-udma.h"
> @@ -2334,5 +2336,203 @@ void bcdma_free_bchan_resources(struct udma_chan *uc)
>  }
>  EXPORT_SYMBOL_GPL(bcdma_free_bchan_resources);
>  
> +static int bcdma_setup_resources(struct udma_dev *ud)
> +{
> +	int ret;
> +	struct device *dev = ud->dev;
> +	u32 cap;
> +
> +	/* Set up the throughput level start indexes */
> +	cap = udma_read(ud->mmrs[MMR_GCFG], 0x2c);
> +	if (BCDMA_CAP3_UBCHAN_CNT(cap)) {
> +		ud->bchan_tpl.levels = 3;
> +		ud->bchan_tpl.start_idx[1] = BCDMA_CAP3_UBCHAN_CNT(cap);
> +		ud->bchan_tpl.start_idx[0] = BCDMA_CAP3_HBCHAN_CNT(cap);
> +	} else if (BCDMA_CAP3_HBCHAN_CNT(cap)) {
> +		ud->bchan_tpl.levels = 2;
> +		ud->bchan_tpl.start_idx[0] = BCDMA_CAP3_HBCHAN_CNT(cap);
> +	} else {
> +		ud->bchan_tpl.levels = 1;
> +	}
> +
> +	cap = udma_read(ud->mmrs[MMR_GCFG], 0x30);
> +	if (BCDMA_CAP4_URCHAN_CNT(cap)) {
> +		ud->rchan_tpl.levels = 3;
> +		ud->rchan_tpl.start_idx[1] = BCDMA_CAP4_URCHAN_CNT(cap);
> +		ud->rchan_tpl.start_idx[0] = BCDMA_CAP4_HRCHAN_CNT(cap);
> +	} else if (BCDMA_CAP4_HRCHAN_CNT(cap)) {
> +		ud->rchan_tpl.levels = 2;
> +		ud->rchan_tpl.start_idx[0] = BCDMA_CAP4_HRCHAN_CNT(cap);
> +	} else {
> +		ud->rchan_tpl.levels = 1;
> +	}
> +
> +	if (BCDMA_CAP4_UTCHAN_CNT(cap)) {
> +		ud->tchan_tpl.levels = 3;
> +		ud->tchan_tpl.start_idx[1] = BCDMA_CAP4_UTCHAN_CNT(cap);
> +		ud->tchan_tpl.start_idx[0] = BCDMA_CAP4_HTCHAN_CNT(cap);
> +	} else if (BCDMA_CAP4_HTCHAN_CNT(cap)) {
> +		ud->tchan_tpl.levels = 2;
> +		ud->tchan_tpl.start_idx[0] = BCDMA_CAP4_HTCHAN_CNT(cap);
> +	} else {
> +		ud->tchan_tpl.levels = 1;
> +	}
> +
> +	ud->bchan_map = devm_bitmap_zalloc(dev, ud->bchan_cnt, GFP_KERNEL);
> +	ud->bchans = devm_kcalloc(dev, ud->bchan_cnt, sizeof(*ud->bchans),
> +				  GFP_KERNEL);
> +	ud->tchan_map = devm_bitmap_zalloc(dev, ud->tchan_cnt, GFP_KERNEL);
> +	ud->tchans = devm_kcalloc(dev, ud->tchan_cnt, sizeof(*ud->tchans),
> +				  GFP_KERNEL);
> +	ud->rchan_map = devm_bitmap_zalloc(dev, ud->rchan_cnt, GFP_KERNEL);
> +	ud->rchans = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rchans),
> +				  GFP_KERNEL);
> +	/* BCDMA do not really have flows, but the driver expect it */
> +	ud->rflow_in_use = devm_kcalloc(dev, BITS_TO_LONGS(ud->rchan_cnt),
> +					sizeof(unsigned long),
> +					GFP_KERNEL);
> +	ud->rflows = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rflows),
> +				  GFP_KERNEL);
> +
> +	if (!ud->bchan_map || !ud->tchan_map || !ud->rchan_map ||
> +	    !ud->rflow_in_use || !ud->bchans || !ud->tchans || !ud->rchans ||
> +	    !ud->rflows)
> +		return -ENOMEM;
> +
> +	if (ud->bcdma_setup_sci_resources) {
> +		ret = ud->bcdma_setup_sci_resources(ud);
> +		if (ret)
> +			return ret;
> +	}

This needs to fail if ud->bcdma_setup_sci_resources is NULL for K3_UDMA_V1

> +
> +	return 0;
> +}
> +
> +static int pktdma_setup_resources(struct udma_dev *ud)
> +{
> +	int ret;
> +	struct device *dev = ud->dev;
> +	u32 cap3;
> +
> +	/* Set up the throughput level start indexes */
> +	cap3 = udma_read(ud->mmrs[MMR_GCFG], 0x2c);
> +	if (UDMA_CAP3_UCHAN_CNT(cap3)) {
> +		ud->tchan_tpl.levels = 3;
> +		ud->tchan_tpl.start_idx[1] = UDMA_CAP3_UCHAN_CNT(cap3);
> +		ud->tchan_tpl.start_idx[0] = UDMA_CAP3_HCHAN_CNT(cap3);
> +	} else if (UDMA_CAP3_HCHAN_CNT(cap3)) {
> +		ud->tchan_tpl.levels = 2;
> +		ud->tchan_tpl.start_idx[0] = UDMA_CAP3_HCHAN_CNT(cap3);
> +	} else {
> +		ud->tchan_tpl.levels = 1;
> +	}
> +
> +	ud->rchan_tpl.levels = ud->tchan_tpl.levels;
> +	ud->rchan_tpl.start_idx[0] = ud->tchan_tpl.start_idx[0];
> +	ud->rchan_tpl.start_idx[1] = ud->tchan_tpl.start_idx[1];
> +
> +	ud->tchan_map = devm_bitmap_zalloc(dev, ud->tchan_cnt, GFP_KERNEL);
> +	ud->tchans = devm_kcalloc(dev, ud->tchan_cnt, sizeof(*ud->tchans),
> +				  GFP_KERNEL);
> +	ud->rchan_map = devm_bitmap_zalloc(dev, ud->rchan_cnt, GFP_KERNEL);
> +	ud->rchans = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rchans),
> +				  GFP_KERNEL);
> +	ud->rflow_in_use = devm_kcalloc(dev, BITS_TO_LONGS(ud->rflow_cnt),
> +					sizeof(unsigned long),
> +					GFP_KERNEL);
> +	ud->rflows = devm_kcalloc(dev, ud->rflow_cnt, sizeof(*ud->rflows),
> +				  GFP_KERNEL);
> +	ud->tflow_map = devm_bitmap_zalloc(dev, ud->tflow_cnt, GFP_KERNEL);
> +
> +	if (!ud->tchan_map || !ud->rchan_map || !ud->tflow_map || !ud->tchans ||
> +	    !ud->rchans || !ud->rflows || !ud->rflow_in_use)
> +		return -ENOMEM;
> +
> +	if (ud->pktdma_setup_sci_resources) {
> +		ret = ud->pktdma_setup_sci_resources(ud);
> +		if (ret)
> +			return ret;
> +	}

This needs to fail if ud->bcdma_setup_sci_resources is NULL for K3_UDMA_V1

-- 
Vignesh




More information about the linux-arm-kernel mailing list