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

From: Vignesh Raghavendra

Date: Mon Sep 28 2026 - 04:41:07 EST


> 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@xxxxxx>
>
> 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