On Fri, Dec 12, 2025 at 05:24:50PM -0500, Frank Li wrote:
> The current descriptor layout is:
>
> struct dw_edma_desc *desc
> └─ chunk list
> └─ burst[]
>
> Creating a DMA descriptor requires at least two kzalloc() calls because
> each chunk is allocated as a linked-list node. Since the number of bursts
> is already known when the descriptor is created, this linked-list layer is
> unnecessary.
>
> Move the burst array directly into struct dw_edma_desc and remove the
> struct dw_edma_chunk layer entirely.
>
> Use start_burst and done_burst to track the current bursts, which current
> are in the DMA link list.
>
> Signed-off-by: Frank Li <[email protected]>
> ---
> drivers/dma/dw-edma/dw-edma-core.c | 130
> ++++++++++++-------------------------
> drivers/dma/dw-edma/dw-edma-core.h | 24 ++++---
> 2 files changed, 57 insertions(+), 97 deletions(-)
>
[...]
> static struct dma_async_tx_descriptor *
> @@ -551,8 +499,14 @@ static void dw_hdma_set_callback_result(struct
> virt_dma_desc *vd,
> return;
>
> desc = vd2dw_edma_desc(vd);
> - if (desc)
> - residue = desc->alloc_sz - desc->xfer_sz;
> + residue = desc->alloc_sz;
Now you dereference desc without checking for NULL.
> +
> + if (desc) {
> + if (result == DMA_TRANS_NOERROR)
> + residue -= desc->burst[desc->start_burst - 1].xfer_sz;
> + else if (desc->done_burst)
> + residue -= desc->burst[desc->done_burst - 1].xfer_sz;
> + }
>
> res = &vd->tx_result;
> res->result = result;
> @@ -571,7 +525,7 @@ static void dw_edma_done_interrupt(struct dw_edma_chan
> *chan)
> switch (chan->request) {
> case EDMA_REQ_NONE:
> desc = vd2dw_edma_desc(vd);
> - if (!desc->chunks_alloc) {
> + if (desc->start_burst >= desc->nburst) {
> dw_hdma_set_callback_result(vd,
> DMA_TRANS_NOERROR);
> list_del(&vd->node);
> @@ -936,7 +890,7 @@ int dw_edma_probe(struct dw_edma_chip *chip)
> goto err_irq_free;
>
> /* Turn debugfs on */
> - dw_edma_core_debugfs_on(dw);
> + //dw_edma_core_debugfs_on(dw);
debug code?
>
> chip->dw = dw;
>
> diff --git a/drivers/dma/dw-edma/dw-edma-core.h
> b/drivers/dma/dw-edma/dw-edma-core.h
> index
> 1930c3bce2bf33fdfbf4e8d99002483a4565faed..ba83c42dee5224dccdf34cec6481e9404a607702
> 100644
> --- a/drivers/dma/dw-edma/dw-edma-core.h
> +++ b/drivers/dma/dw-edma/dw-edma-core.h
> @@ -46,15 +46,8 @@ struct dw_edma_burst {
> u64 sar;
> u64 dar;
> u32 sz;
> -};
> -
> -struct dw_edma_chunk {
> - struct list_head list;
> - struct dw_edma_chan *chan;
> - u8 cb;
> + /* precalulate summary of previous burst total size */
> u32 xfer_sz;
> - u32 nburst;
> - struct dw_edma_burst burst[] __counted_by(nburst);
> };
>
> struct dw_edma_desc {
> @@ -66,6 +59,12 @@ struct dw_edma_desc {
>
> u32 alloc_sz;
> u32 xfer_sz;
> +
> + u32 done_burst;
> + u32 start_burst;
> + u8 cb;
> + u32 nburst;
> + struct dw_edma_burst burst[] __counted_by(nburst);
> };
>
> struct dw_edma_chan {
> @@ -126,7 +125,6 @@ struct dw_edma_core_ops {
> void (*ll_link)(struct dw_edma_chan *chan, u32 idx, bool cb, u64 addr);
> void (*ch_doorbell)(struct dw_edma_chan *chan);
> void (*ch_enable)(struct dw_edma_chan *chan);
> -
> void (*ch_config)(struct dw_edma_chan *chan);
> void (*debugfs_on)(struct dw_edma *dw);
> };
> @@ -166,6 +164,14 @@ struct dw_edma_chan *dchan2dw_edma_chan(struct dma_chan
> *dchan)
> return vc2dw_edma_chan(to_virt_chan(dchan));
> }
>
> +static inline u64 dw_edma_core_get_ll_paddr(struct dw_edma_chan *chan)
No need of inline.
- Mani
--
மணிவண்ணன் சதாசிவம்