Re: [PATCH v2 07/19] dmaengine: dw-edma: Dispatch DONE interrupts by channel request
Frank Li <[email protected]>
| Newsgroups | org.kernel.vger.dmaengine,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <amJH_IknotEHF5Nr@SMW015318> |
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? Frank > > No functional change intended. > > Signed-off-by: Koichiro Den <[email protected]> > --- > 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 >