Re: [PATCH v3 06/24] dmaengine: dw-edma: Dispatch DONE interrupts by channel request

From: Frank Li

Date: Mon Jul 27 2026 - 15:16:10 EST


On Tue, Jul 28, 2026 at 02:03:05AM +0900, Koichiro Den wrote:
> Prepare for LL progress reclamation, which can complete and remove the
> last issued descriptor before DONE request handling runs. STOP and PAUSE
> still have state to update even when no descriptor remains.
>
> Move the request switch outside the descriptor check, and look up a
> descriptor only in the cases that need one. Keep this non-functional
> reordering separate from progress accounting.
>
> No functional change.
>
> Signed-off-by: Koichiro Den <den@xxxxxxxxxxxxx>
> ---

Reviewed-by: Frank Li <Frank.Li@xxxxxxx>


> Changes in v3:
> - Explain that this reordering prepares for LL progress reclamation.
> (Frank)
>
> drivers/dma/dw-edma/dw-edma-core.c | 56 ++++++++++++++++--------------
> 1 file changed, 29 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
> index 6e7d1f7c20f9..b419ff2becf9 100644
> --- a/drivers/dma/dw-edma/dw-edma-core.c
> +++ b/drivers/dma/dw-edma/dw-edma-core.c
> @@ -697,39 +697,41 @@ 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_done = chan->ll_head;
> - }
> + switch (chan->request) {
> + case EDMA_REQ_NONE:
> + case EDMA_REQ_PAUSE:
> + vd = vchan_next_desc(&chan->vc);
> + if (!vd)
> + break;
>
> - if (chan->request == EDMA_REQ_PAUSE) {
> - chan->request = EDMA_REQ_NONE;
> - chan->status = EDMA_ST_PAUSE;
> - break;
> - }
> + 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_done = chan->ll_head;
> + }
>
> - /* Continue transferring if there are remaining chunks or issued requests.
> - */
> - chan->status = dw_edma_start_transfer(chan) ? EDMA_ST_BUSY : EDMA_ST_IDLE;
> + if (chan->request == EDMA_REQ_PAUSE) {
> + chan->request = EDMA_REQ_NONE;
> + chan->status = EDMA_ST_PAUSE;
> break;
> + }
>
> - case EDMA_REQ_STOP:
> - dw_edma_finish_termination(chan);
> - break;
> + chan->status = dw_edma_start_transfer(chan) ? EDMA_ST_BUSY : EDMA_ST_IDLE;
> + break;
>
> - default:
> + case EDMA_REQ_STOP:
> + vd = vchan_next_desc(&chan->vc);
> + if (!vd)
> break;
> - }
> +
> + dw_edma_finish_termination(chan);
> + break;
> +
> + default:
> + break;
> }
> spin_unlock_irqrestore(&chan->vc.lock, flags);
> }
> --
> 2.51.0
>