Re: [PATCH v2 07/19] dmaengine: dw-edma: Dispatch DONE interrupts by channel request
From: Frank Li
Date: Thu Jul 23 2026 - 13:07:28 EST
On Thu, Jul 23, 2026 at 05:41:38PM +0900, Koichiro Den wrote:
Subject:
Check channel request firstly at DONE channel interrupts ?
> Handle the channel request first in the DONE interrupt path, then look
> at the issued descriptor list only in the cases that need it.
>
> This keeps the existing behavior, including the current STOP and PAUSE
> handling when no issued descriptor is present.
Need descript why need this change?
Frank
>
> No functional change intended.
>
> Signed-off-by: Koichiro Den <den@xxxxxxxxxxxxx>
> ---
> Changes in v2:
> - Limit this patch to request dispatch with no functional change;
> move LL progress and empty-issued-list handling to later patches.
>
> drivers/dma/dw-edma/dw-edma-core.c | 60 +++++++++++++++---------------
> 1 file changed, 31 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
> index 29f78405e9fb..fa104af4146e 100644
> --- a/drivers/dma/dw-edma/dw-edma-core.c
> +++ b/drivers/dma/dw-edma/dw-edma-core.c
> @@ -682,41 +682,43 @@ static void dw_edma_done_interrupt(struct dw_edma_chan *chan)
> return;
> }
>
> - vd = vchan_next_desc(&chan->vc);
> - if (vd) {
> - switch (chan->request) {
> - case EDMA_REQ_NONE:
> - case EDMA_REQ_PAUSE:
> - desc = vd2dw_edma_desc(vd);
> - if (desc->start_burst >= desc->nburst) {
> - dw_hdma_set_callback_result(vd,
> - DMA_TRANS_NOERROR);
> - list_del(&vd->node);
> - vchan_cookie_complete(vd);
> - if (!chan->non_ll)
> - chan->ll_end = chan->ll_head;
> - }
> -
> - if (chan->request == EDMA_REQ_PAUSE) {
> - chan->request = EDMA_REQ_NONE;
> - chan->status = EDMA_ST_PAUSE;
> - break;
> - }
> -
> - /* Continue transferring if there are remaining chunks or issued requests.
> - */
> - chan->status = dw_edma_start_transfer(chan) ? EDMA_ST_BUSY : EDMA_ST_IDLE;
> + switch (chan->request) {
> + case EDMA_REQ_NONE:
> + case EDMA_REQ_PAUSE:
> + vd = vchan_next_desc(&chan->vc);
> + if (!vd)
> break;
>
> - case EDMA_REQ_STOP:
> - dw_edma_terminate_all_descs(chan);
> + desc = vd2dw_edma_desc(vd);
> + if (desc->start_burst >= desc->nburst) {
> + dw_hdma_set_callback_result(vd, DMA_TRANS_NOERROR);
> + list_del(&vd->node);
> + vchan_cookie_complete(vd);
> + if (!chan->non_ll)
> + chan->ll_end = chan->ll_head;
> + }
> +
> + if (chan->request == EDMA_REQ_PAUSE) {
> chan->request = EDMA_REQ_NONE;
> - chan->status = EDMA_ST_IDLE;
> + chan->status = EDMA_ST_PAUSE;
> break;
> + }
>
> - default:
> + chan->status = dw_edma_start_transfer(chan) ? EDMA_ST_BUSY : EDMA_ST_IDLE;
> + break;
> +
> + case EDMA_REQ_STOP:
> + vd = vchan_next_desc(&chan->vc);
> + if (!vd)
> break;
> - }
> +
> + dw_edma_terminate_all_descs(chan);
> + chan->request = EDMA_REQ_NONE;
> + chan->status = EDMA_ST_IDLE;
> + break;
> +
> + default:
> + break;
> }
> spin_unlock_irqrestore(&chan->vc.lock, flags);
> }
> --
> 2.51.0
>