Re: [PATCH v4 07/24] dmaengine: dw-edma: Centralize LL doorbell decisions

From: Frank Li

Date: Wed Jul 29 2026 - 13:37:19 EST


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 <den@xxxxxxxxxxxxx>
> ---

Reviewed-by: Frank Li <Frank.Li@xxxxxxx>

> 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
>