Re: [PATCH v3 06/24] dmaengine: dw-edma: Dispatch DONE interrupts by channel request
Frank Li <[email protected]> Mon, 27 Jul 2026 15:11:07 -0400
| Newsgroups | org.kernel.vger.dmaengine,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <ametS1SV9Z3bPEWy@lizhi-Precision-Tower-5810> |
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 <[email protected]> > --- Reviewed-by: Frank Li <[email protected]> > 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 >