Re: [PATCH v3 06/24] dmaengine: dw-edma: Dispatch DONE interrupts by channel request

Frank Li <[email protected]> Mon, 27 Jul 2026 15:11:07 -0400
Newsgroups org.kernel.vger.dmaengine,org.kernel.vger.linux-kernel
Message-ID <ametS1SV9Z3bPEWy@lizhi-Precision-Tower-5810>
On Tue, Jul 28, 2026 at 02:03:05AM +0900, Koichiro Den wrote:
> Prepare for LL progress reclamation, which can complete and remove the
> last issued descriptor before DONE request handling runs. STOP and PAUSE
> still have state to update even when no descriptor remains.
>
> Move the request switch outside the descriptor check, and look up a
> descriptor only in the cases that need one. Keep this non-functional
> reordering separate from progress accounting.
>
> No functional change.
>
> Signed-off-by: Koichiro Den <[email protected]>
> ---

Reviewed-by: Frank Li <[email protected]>


> Changes in v3:
>   - Explain that this reordering prepares for LL progress reclamation.
>     (Frank)
>
>  drivers/dma/dw-edma/dw-edma-core.c | 56 ++++++++++++++++--------------
>  1 file 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 6e7d1f7c20f9..b419ff2becf9 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);
>  }
> --
> 2.51.0
>