summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoichiro Den <den@valinux.co.jp>2026-08-21 02:34:35 +0900
committerVinod Koul <vkoul@kernel.org>2026-09-09 19:06:51 +0530
commit8d249a120ce615804edab065ef4d157dbc92125f (patch)
tree628220d670abc1374e495ed4b5d83592356b23e9
parent9a8d4965cd9f4fe736cdf1f2c35f802ef36125f5 (diff)
downloadlinux-next-8d249a120ce615804edab065ef4d157dbc92125f.tar.gz
linux-next-8d249a120ce615804edab065ef4d157dbc92125f.zip
dmaengine: dw-edma: Dispatch DONE interrupts by channel request
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 <Frank.Li@nxp.com> Signed-off-by: Koichiro Den <den@valinux.co.jp> Link: https://patch.msgid.link/20260820173439.2004068-7-den@valinux.co.jp Signed-off-by: Vinod Koul <vkoul@kernel.org>
-rw-r--r--drivers/dma/dw-edma/dw-edma-core.c56
1 files 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 ab8e343f0196..3c1f3f728875 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);
}