[PATCH v4 06/24] dmaengine: dw-edma: Dispatch DONE interrupts by channel request
Koichiro Den <[email protected]> Wed, 29 Jul 2026 23:30:18 +0900
| Newsgroups | org.kernel.vger.dmaengine,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Prepare for a later patch that reclaims LL progress before request handling and can remove the last issued descriptor. Move the request switch outside the common descriptor check. Keep the existing per-request descriptor checks for now. That later patch removes them when STOP/PAUSE handling becomes independent of the descriptor list. No functional change. Reviewed-by: Frank Li <[email protected]> Signed-off-by: Koichiro Den <[email protected]> --- Changes in v4: - Clarify that descriptor-independent STOP/PAUSE handling is added with LL progress reclamation later, not by this prep patch. (Sashiko) 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