Re: [PATCH v2 07/19] dmaengine: dw-edma: Dispatch DONE interrupts by channel request

From: Koichiro Den

Date: Fri Jul 24 2026 - 00:52:59 EST


On Thu, Jul 23, 2026 at 11:57:32AM -0500, Frank Li wrote:
> 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?

This is a prep, non-functional change for patch 9. Patch 9 first invokes
dw_edma_ll_consume_progress(), which may complete and remove the last issued
descriptor. Even then, the switch still has work to do for each request state,
so it can no longer be guarded by 'if (vd)'.

I split this reordering (non-functional change) out only to keep the functional
diff in patch 9 readable and easier to review.

Best regards,
Koichiro

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