[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20260128-dma_ll_comlib-v1-4-1b1fa2c671f9@nxp.com>
Date: Wed, 28 Jan 2026 13:05:23 -0500
From: Frank Li <Frank.Li@....com>
To: Vinod Koul <vkoul@...nel.org>
Cc: linux-kernel@...r.kernel.org, dmaengine@...r.kernel.org,
imx@...ts.linux.dev, joy.zou@....com, Frank Li <Frank.Li@....com>
Subject: [PATCH RFC 04/12] dmaengine: fsl-edma: Use common dma_ll_desc in
vchan
Use the common dma_ll_desc structure in the virtual channel implementation
to prepare for adding more shared APIs to the DMA link-list library.
No functional change.
Signed-off-by: Frank Li <Frank.Li@....com>
---
drivers/dma/fsl-edma-common.c | 95 ++++++++++++++++++++++---------------------
drivers/dma/fsl-edma-common.h | 20 +--------
2 files changed, 50 insertions(+), 65 deletions(-)
diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
index 61387c4edc910c8a806cc2c6f0fee2e690424bac..17a8e28037f5e61d4aafbd7f32bde407ecc01a4d 100644
--- a/drivers/dma/fsl-edma-common.c
+++ b/drivers/dma/fsl-edma-common.c
@@ -223,14 +223,14 @@ static unsigned int fsl_edma_get_tcd_attr(enum dma_slave_buswidth src_addr_width
void fsl_edma_free_desc(struct virt_dma_desc *vdesc)
{
- struct fsl_edma_desc *fsl_desc;
+ struct dma_ll_desc *fsl_desc;
int i;
- fsl_desc = to_fsl_edma_desc(vdesc);
- for (i = 0; i < fsl_desc->n_tcds; i++)
- dma_pool_free(to_fsl_edma_chan(vdesc->tx.chan)->tcd_pool,
- fsl_desc->tcd[i].vtcd,
- fsl_desc->tcd[i].ptcd);
+ fsl_desc = to_dma_ll_desc(vdesc);
+ for (i = 0; i < fsl_desc->n_its; i++)
+ dma_pool_free(to_virt_chan(vdesc->tx.chan)->ll.pool,
+ fsl_desc->its[i].vaddr,
+ fsl_desc->its[i].paddr);
kfree(fsl_desc);
}
@@ -342,19 +342,19 @@ int fsl_edma_slave_config(struct dma_chan *chan,
static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan,
struct virt_dma_desc *vdesc, bool in_progress)
{
- struct fsl_edma_desc *edesc = fsl_chan->edesc;
- enum dma_transfer_direction dir = edesc->dirn;
+ struct dma_ll_desc *edesc = fsl_chan->edesc;
+ enum dma_transfer_direction dir = edesc->dir;
dma_addr_t cur_addr, dma_addr, old_addr;
size_t len, size;
u32 nbytes = 0;
int i;
/* calculate the total size in this desc */
- for (len = i = 0; i < fsl_chan->edesc->n_tcds; i++) {
- nbytes = fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->tcd[i].vtcd, nbytes);
+ for (len = i = 0; i < fsl_chan->edesc->n_its; i++) {
+ nbytes = fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->its[i].vaddr, nbytes);
if (nbytes & (EDMA_V3_TCD_NBYTES_DMLOE | EDMA_V3_TCD_NBYTES_SMLOE))
nbytes = EDMA_V3_TCD_NBYTES_MLOFF_NBYTES(nbytes);
- len += nbytes * fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->tcd[i].vtcd, biter);
+ len += nbytes * fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->its[i].vaddr, biter);
}
if (!in_progress)
@@ -372,17 +372,17 @@ static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan,
} while (upper_32_bits(cur_addr) != upper_32_bits(old_addr));
/* figure out the finished and calculate the residue */
- for (i = 0; i < fsl_chan->edesc->n_tcds; i++) {
- nbytes = fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->tcd[i].vtcd, nbytes);
+ for (i = 0; i < fsl_chan->edesc->n_its; i++) {
+ nbytes = fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->its[i].vaddr, nbytes);
if (nbytes & (EDMA_V3_TCD_NBYTES_DMLOE | EDMA_V3_TCD_NBYTES_SMLOE))
nbytes = EDMA_V3_TCD_NBYTES_MLOFF_NBYTES(nbytes);
- size = nbytes * fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->tcd[i].vtcd, biter);
+ size = nbytes * fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->its[i].vaddr, biter);
if (dir == DMA_MEM_TO_DEV)
- dma_addr = fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->tcd[i].vtcd, saddr);
+ dma_addr = fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->its[i].vaddr, saddr);
else
- dma_addr = fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->tcd[i].vtcd, daddr);
+ dma_addr = fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->its[i].vaddr, daddr);
len -= size;
if (cur_addr >= dma_addr && cur_addr < dma_addr + size) {
@@ -546,29 +546,30 @@ void fsl_edma_fill_tcd(struct fsl_edma_chan *fsl_chan,
trace_edma_fill_tcd(fsl_chan, tcd);
}
-static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan,
- int sg_len)
+static struct dma_ll_desc *
+fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan, int sg_len)
{
- struct fsl_edma_desc *fsl_desc;
+ struct dma_ll_desc *fsl_desc;
int i;
- fsl_desc = kzalloc(struct_size(fsl_desc, tcd, sg_len), GFP_NOWAIT);
+ fsl_desc = kzalloc(struct_size(fsl_desc, its, sg_len), GFP_NOWAIT);
if (!fsl_desc)
return NULL;
- fsl_desc->n_tcds = sg_len;
+ fsl_desc->n_its = sg_len;
for (i = 0; i < sg_len; i++) {
- fsl_desc->tcd[i].vtcd = dma_pool_alloc(fsl_chan->tcd_pool,
- GFP_NOWAIT, &fsl_desc->tcd[i].ptcd);
- if (!fsl_desc->tcd[i].vtcd)
+ fsl_desc->its[i].vaddr = dma_pool_alloc(fsl_chan->vchan.ll.pool,
+ GFP_NOWAIT,
+ &fsl_desc->its[i].paddr);
+ if (!fsl_desc->its[i].vaddr)
goto err;
}
return fsl_desc;
err:
while (--i >= 0)
- dma_pool_free(fsl_chan->tcd_pool, fsl_desc->tcd[i].vtcd,
- fsl_desc->tcd[i].ptcd);
+ dma_pool_free(fsl_chan->vchan.ll.pool, fsl_desc->its[i].vaddr,
+ fsl_desc->its[i].paddr);
kfree(fsl_desc);
return NULL;
}
@@ -580,7 +581,7 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
{
struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
struct dma_slave_config *cfg = &chan->config;
- struct fsl_edma_desc *fsl_desc;
+ struct dma_ll_desc *fsl_desc;
dma_addr_t dma_buf_next;
bool major_int = true;
int sg_len, i;
@@ -599,7 +600,7 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
if (!fsl_desc)
return NULL;
fsl_desc->iscyclic = true;
- fsl_desc->dirn = direction;
+ fsl_desc->dir = direction;
dma_buf_next = dma_addr;
if (direction == DMA_MEM_TO_DEV) {
@@ -625,7 +626,7 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
dma_buf_next = dma_addr;
/* get next sg's physical address */
- last_sg = fsl_desc->tcd[(i + 1) % sg_len].ptcd;
+ last_sg = fsl_desc->its[(i + 1) % sg_len].paddr;
if (direction == DMA_MEM_TO_DEV) {
src_addr = dma_buf_next;
@@ -649,7 +650,7 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
major_int = false;
}
- fsl_edma_fill_tcd(fsl_chan, fsl_desc->tcd[i].vtcd, src_addr, dst_addr,
+ fsl_edma_fill_tcd(fsl_chan, fsl_desc->its[i].vaddr, src_addr, dst_addr,
fsl_chan->attr, soff, nbytes, 0, iter,
iter, doff, last_sg, major_int, false, true);
dma_buf_next += period_len;
@@ -665,7 +666,7 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
{
struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
struct dma_slave_config *cfg = &chan->config;
- struct fsl_edma_desc *fsl_desc;
+ struct dma_ll_desc *fsl_desc;
struct scatterlist *sg;
dma_addr_t src_addr, dst_addr, last_sg;
u16 soff, doff, iter;
@@ -682,7 +683,7 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
if (!fsl_desc)
return NULL;
fsl_desc->iscyclic = false;
- fsl_desc->dirn = direction;
+ fsl_desc->dir = direction;
if (direction == DMA_MEM_TO_DEV) {
if (!cfg->src_addr_width)
@@ -745,14 +746,14 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
}
iter = sg_dma_len(sg) / nbytes;
if (i < sg_len - 1) {
- last_sg = fsl_desc->tcd[(i + 1)].ptcd;
- fsl_edma_fill_tcd(fsl_chan, fsl_desc->tcd[i].vtcd, src_addr,
+ last_sg = fsl_desc->its[(i + 1)].paddr;
+ fsl_edma_fill_tcd(fsl_chan, fsl_desc->its[i].vaddr, src_addr,
dst_addr, fsl_chan->attr, soff,
nbytes, 0, iter, iter, doff, last_sg,
false, false, true);
} else {
last_sg = 0;
- fsl_edma_fill_tcd(fsl_chan, fsl_desc->tcd[i].vtcd, src_addr,
+ fsl_edma_fill_tcd(fsl_chan, fsl_desc->its[i].vaddr, src_addr,
dst_addr, fsl_chan->attr, soff,
nbytes, 0, iter, iter, doff, last_sg,
true, true, false);
@@ -767,7 +768,7 @@ struct dma_async_tx_descriptor *fsl_edma_prep_memcpy(struct dma_chan *chan,
size_t len, unsigned long flags)
{
struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
- struct fsl_edma_desc *fsl_desc;
+ struct dma_ll_desc *fsl_desc;
u32 src_bus_width, dst_bus_width;
src_bus_width = min_t(u32, DMA_SLAVE_BUSWIDTH_32_BYTES, 1 << (ffs(dma_src) - 1));
@@ -783,10 +784,10 @@ struct dma_async_tx_descriptor *fsl_edma_prep_memcpy(struct dma_chan *chan,
fsl_chan->is_remote = true;
/* To match with copy_align and max_seg_size so 1 tcd is enough */
- fsl_edma_fill_tcd(fsl_chan, fsl_desc->tcd[0].vtcd, dma_src, dma_dst,
- fsl_edma_get_tcd_attr(src_bus_width, dst_bus_width),
- src_bus_width, len, 0, 1, 1, dst_bus_width, 0, true,
- true, false);
+ fsl_edma_fill_tcd(fsl_chan, fsl_desc->its[0].vaddr, dma_src, dma_dst,
+ fsl_edma_get_tcd_attr(src_bus_width, dst_bus_width),
+ src_bus_width, len, 0, 1, 1, dst_bus_width, 0, true,
+ true, false);
return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags);
}
@@ -800,8 +801,8 @@ void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan)
vdesc = vchan_next_desc(&fsl_chan->vchan);
if (!vdesc)
return;
- fsl_chan->edesc = to_fsl_edma_desc(vdesc);
- fsl_edma_set_tcd_regs(fsl_chan, fsl_chan->edesc->tcd[0].vtcd);
+ fsl_chan->edesc = to_dma_ll_desc(vdesc);
+ fsl_edma_set_tcd_regs(fsl_chan, fsl_chan->edesc->its[0].vaddr);
fsl_edma_enable_request(fsl_chan);
fsl_chan->status = DMA_IN_PROGRESS;
}
@@ -855,7 +856,8 @@ int fsl_edma_alloc_chan_resources(struct dma_chan *chan)
if (ret)
return ret;
- fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
+ fsl_chan->vchan.ll.pool =
+ dma_pool_create("tcd_pool", chan->device->dev,
fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_TCD64 ?
sizeof(struct fsl_edma_hw_tcd64) : sizeof(struct fsl_edma_hw_tcd),
32, 0);
@@ -880,7 +882,8 @@ int fsl_edma_alloc_chan_resources(struct dma_chan *chan)
if (fsl_chan->txirq)
free_irq(fsl_chan->txirq, fsl_chan);
err_txirq:
- dma_pool_destroy(fsl_chan->tcd_pool);
+ dma_pool_destroy(fsl_chan->vchan.ll.pool);
+ clk_disable_unprepare(fsl_chan->clk);
return ret;
}
@@ -907,8 +910,8 @@ void fsl_edma_free_chan_resources(struct dma_chan *chan)
free_irq(fsl_chan->errirq, fsl_chan);
vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
- dma_pool_destroy(fsl_chan->tcd_pool);
- fsl_chan->tcd_pool = NULL;
+ dma_pool_destroy(fsl_chan->vchan.ll.pool);
+ fsl_chan->vchan.ll.pool = NULL;
fsl_chan->is_sw = false;
fsl_chan->srcid = 0;
fsl_chan->is_remote = false;
diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h
index a0d83ad783f7a53caab93d280c6e40f63b8e9e5c..56d219d57b852e0769cbead11fadac89913747e2 100644
--- a/drivers/dma/fsl-edma-common.h
+++ b/drivers/dma/fsl-edma-common.h
@@ -155,17 +155,12 @@ struct edma_regs {
void __iomem *errl;
};
-struct fsl_edma_sw_tcd {
- dma_addr_t ptcd;
- void *vtcd;
-};
-
struct fsl_edma_chan {
struct virt_dma_chan vchan;
enum dma_status status;
enum fsl_edma_pm_state pm_state;
struct fsl_edma_engine *edma;
- struct fsl_edma_desc *edesc;
+ struct dma_ll_desc *edesc;
u32 attr;
bool is_sw;
struct dma_pool *tcd_pool;
@@ -194,14 +189,6 @@ struct fsl_edma_chan {
bool is_multi_fifo;
};
-struct fsl_edma_desc {
- struct virt_dma_desc vdesc;
- bool iscyclic;
- enum dma_transfer_direction dirn;
- unsigned int n_tcds;
- struct fsl_edma_sw_tcd tcd[];
-};
-
#define FSL_EDMA_DRV_HAS_DMACLK BIT(0)
#define FSL_EDMA_DRV_MUX_SWAP BIT(1)
#define FSL_EDMA_DRV_CONFIG32 BIT(2)
@@ -468,11 +455,6 @@ static inline struct fsl_edma_chan *to_fsl_edma_chan(struct dma_chan *chan)
return container_of(chan, struct fsl_edma_chan, vchan.chan);
}
-static inline struct fsl_edma_desc *to_fsl_edma_desc(struct virt_dma_desc *vd)
-{
- return container_of(vd, struct fsl_edma_desc, vdesc);
-}
-
static inline void fsl_edma_err_chan_handler(struct fsl_edma_chan *fsl_chan)
{
fsl_chan->status = DMA_ERROR;
--
2.34.1
Powered by blists - more mailing lists