Re: [PATCH v4 07/24] dmaengine: dw-edma: Centralize LL doorbell decisions
Frank Li <[email protected]> Wed, 29 Jul 2026 11:01:47 -0500
| Newsgroups | org.kernel.vger.dmaengine,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <amoj6zAcRocJbbCY@SMW015318> |
On Wed, Jul 29, 2026 at 11:30:19PM +0900, Koichiro Den wrote: > LL fill currently rings the doorbell every time. A running eDMA or HDMA > channel follows entries whose CB matches CCS without another kick. A > channel stopped at a CB mismatch needs one. > > Move that decision to dw_edma_core_ch_maybe_doorbell(). It rings only > for a BUSY LL channel with pending entries, no EDMA_REQ_STOP or > EDMA_REQ_PAUSE. The BUSY check prevents EDMA_REQ_STOP completion from > restarting terminated work. > > issue_pending() still publishes LL entries only from IDLE. A later patch > allows live appends. Non-LL channels are unchanged. > > Signed-off-by: Koichiro Den <[email protected]> > --- Reviewed-by: Frank Li <[email protected]> > Changes in v4: > - No changes. > > drivers/dma/dw-edma/dw-edma-core.c | 16 ++++++++++++++-- > 1 file changed, 14 insertions(+), 2 deletions(-) > > diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c > index b419ff2becf9..c036510dabcb 100644 > --- a/drivers/dma/dw-edma/dw-edma-core.c > +++ b/drivers/dma/dw-edma/dw-edma-core.c > @@ -167,8 +167,6 @@ static void dw_edma_core_ll_start(struct dw_edma_desc *desc) > > desc->done_burst = desc->start_burst; > desc->start_burst = i; > - > - dw_edma_core_ch_doorbell(chan); > } > > static void dw_edma_core_start(struct dw_edma_desc *desc) > @@ -249,6 +247,16 @@ static void dw_edma_finish_termination(struct dw_edma_chan *chan) > chan->status = EDMA_ST_IDLE; > } > > +/* Must be called with vc.lock held. */ > +static void dw_edma_core_ch_maybe_doorbell(struct dw_edma_chan *chan) > +{ > + if (chan->non_ll || chan->request != EDMA_REQ_NONE || > + chan->status != EDMA_ST_BUSY || !dw_edma_ll_pending(chan)) > + return; > + > + dw_edma_core_ch_doorbell(chan); > +} > + > static void dw_edma_device_caps(struct dma_chan *dchan, > struct dma_slave_caps *caps) > { > @@ -374,6 +382,7 @@ static int dw_edma_device_resume(struct dma_chan *dchan) > chan->status = EDMA_ST_BUSY; > if (!dw_edma_start_transfer(chan)) > chan->status = EDMA_ST_IDLE; > + dw_edma_core_ch_maybe_doorbell(chan); > } > > return err; > @@ -420,6 +429,7 @@ static void dw_edma_device_issue_pending(struct dma_chan *dchan) > chan->status == EDMA_ST_IDLE) { > chan->status = EDMA_ST_BUSY; > dw_edma_start_transfer(chan); > + dw_edma_core_ch_maybe_doorbell(chan); > } > spin_unlock_irqrestore(&chan->vc.lock, flags); > } > @@ -733,6 +743,8 @@ static void dw_edma_done_interrupt(struct dw_edma_chan *chan) > default: > break; > } > + dw_edma_core_ch_maybe_doorbell(chan); > + > spin_unlock_irqrestore(&chan->vc.lock, flags); > } > > -- > 2.51.0 >