diff options
| author | Koichiro Den <den@valinux.co.jp> | 2026-08-21 02:34:35 +0900 |
|---|---|---|
| committer | Vinod Koul <vkoul@kernel.org> | 2026-09-09 19:06:51 +0530 |
| commit | 8d249a120ce615804edab065ef4d157dbc92125f (patch) | |
| tree | 628220d670abc1374e495ed4b5d83592356b23e9 | |
| parent | 9a8d4965cd9f4fe736cdf1f2c35f802ef36125f5 (diff) | |
| download | linux-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.c | 56 |
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); } |
