From nobody Sat Jun 13 02:07:30 2026 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B19A13FB07B for ; Mon, 11 May 2026 13:57:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778507863; cv=none; b=VC+UowHEvHZ8zQ/A5fSBHLCNCQbpLJOF8aegOnuQYpgKS/91nAw8J7Eznlhw8gdm0vN3ScZu0MlHQafYLk8gSwCt4Hc1maSx5xiJjywabfFA2P0c7xLWbwVNL/z3dz4F/x2SwNGAPMgO0oeHFa3b9lp/qpVKAOHFDJ+4AEa/UzI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778507863; c=relaxed/simple; bh=TTOWz8Rwz6R/AoUygX6CuUgz/Loy/Gjy0Murw9mcRE8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kFwelNM9rUrEFB5xnayD3Ej9nYqWn3FgK9HuI+c9ohInnuikpHtP6WCL9I1XAvISE9cQYnjneTqK3+8wnmSfgcVxG4d8Dij76J7KrDiKFo8KCTjWFMuWj1w37bOB8w5cj1zTMkAFzpDaSc32VcfjlPRGc0sXyzsx4DNUbXwY3I8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=Y8DTJXq3; arc=none smtp.client-ip=185.171.202.116 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="Y8DTJXq3" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 398C8C5E156; Mon, 11 May 2026 13:58:16 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id AB08460646; Mon, 11 May 2026 13:57:26 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 7843611AF9DE7; Mon, 11 May 2026 15:57:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1778507846; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=M5ztov0b8WvwMIKtX2cRHVD8ljEx4EZvGs/HJQVKG9M=; b=Y8DTJXq3aTJC488SKwM/4HFz+lCkksYc+FCsmLBgPN9yVpckAav6En632wC/xU37k+bPkN ty6Ttcb7HtDqUsfbggHfT76jcIrPamtIcrSEul0KicTHMr43q4EqOTcj/oHWgSJkjYvMFV zomRRPDeBUD1HsDxQSqqadw0lM5zDKGI37PWfG3mZlmsjvkl2FX6i6yzC9RzibQGRgPHQi yFqCE7d1UHHpLUkALiJ2UiYBgj+fK2Zw0NhDOYiW1lebx304beSVLgpIx4D0YvTleoVHfs hnxSWsSmYZBPQ7ASqNYgvbVogFbEUaLHSpBy9LgJbO0XdO493wj8c2bHIntMDA== From: =?utf-8?q?Beno=C3=AEt_Monin?= Date: Mon, 11 May 2026 15:57:19 +0200 Subject: [PATCH v3 1/2] dmaengine: fsl-edma: Implement device_prep_peripheral_dma_vec Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260511-fsl-edma-dyn-sg-v3-1-98a181775dae@bootlin.com> References: <20260511-fsl-edma-dyn-sg-v3-0-98a181775dae@bootlin.com> In-Reply-To: <20260511-fsl-edma-dyn-sg-v3-0-98a181775dae@bootlin.com> To: Frank Li , Vinod Koul Cc: Thomas Petazzoni , Frank Li , imx@lists.linux.dev, dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Beno=C3=AEt_Monin?= X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 Add implementation of .device_prep_peripheral_dma_vec() callback to setup a scatter/gather DMA transfer from an array of dma_vec structures. Setup a cyclic transfer if the DMA_PREP_REPEAT flag is set. Signed-off-by: Beno=C3=AEt Monin Reviewed-by: Frank Li --- drivers/dma/fsl-edma-common.c | 109 ++++++++++++++++++++++++++++++++++++++= ++++ drivers/dma/fsl-edma-common.h | 4 ++ drivers/dma/fsl-edma-main.c | 2 + 3 files changed, 115 insertions(+) diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c index bb7531c456df..c10190164926 100644 --- a/drivers/dma/fsl-edma-common.c +++ b/drivers/dma/fsl-edma-common.c @@ -673,6 +673,115 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyc= lic( return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags); } =20 +struct dma_async_tx_descriptor * +fsl_edma_prep_peripheral_dma_vec(struct dma_chan *chan, const struct dma_v= ec *vecs, + size_t nb, enum dma_transfer_direction direction, + unsigned long flags) +{ + struct fsl_edma_chan *fsl_chan =3D to_fsl_edma_chan(chan); + dma_addr_t src_addr, dst_addr, last_sg; + struct fsl_edma_desc *fsl_desc; + u16 soff, doff, iter; + u32 nbytes; + int i; + + if (!is_slave_direction(direction)) + return NULL; + + if (!fsl_edma_prep_slave_dma(fsl_chan, direction)) + return NULL; + + fsl_desc =3D fsl_edma_alloc_desc(fsl_chan, nb); + if (!fsl_desc) + return NULL; + fsl_desc->iscyclic =3D flags & DMA_PREP_REPEAT; + fsl_desc->dirn =3D direction; + + if (direction =3D=3D DMA_MEM_TO_DEV) { + if (!fsl_chan->cfg.src_addr_width) + fsl_chan->cfg.src_addr_width =3D fsl_chan->cfg.dst_addr_width; + fsl_chan->attr =3D + fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width, + fsl_chan->cfg.dst_addr_width); + nbytes =3D fsl_chan->cfg.dst_addr_width * fsl_chan->cfg.dst_maxburst; + } else { + if (!fsl_chan->cfg.dst_addr_width) + fsl_chan->cfg.dst_addr_width =3D fsl_chan->cfg.src_addr_width; + fsl_chan->attr =3D + fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width, + fsl_chan->cfg.dst_addr_width); + nbytes =3D fsl_chan->cfg.src_addr_width * fsl_chan->cfg.src_maxburst; + } + + for (i =3D 0; i < nb; i++) { + if (direction =3D=3D DMA_MEM_TO_DEV) { + src_addr =3D vecs[i].addr; + dst_addr =3D fsl_chan->dma_dev_addr; + soff =3D fsl_chan->cfg.dst_addr_width; + doff =3D 0; + } else if (direction =3D=3D DMA_DEV_TO_MEM) { + src_addr =3D fsl_chan->dma_dev_addr; + dst_addr =3D vecs[i].addr; + soff =3D 0; + doff =3D fsl_chan->cfg.src_addr_width; + } else { + /* DMA_DEV_TO_DEV */ + src_addr =3D fsl_chan->cfg.src_addr; + dst_addr =3D fsl_chan->cfg.dst_addr; + soff =3D 0; + doff =3D 0; + } + + /* + * Choose the suitable burst length if dma_vec length is not + * multiple of burst length so that the whole transfer length is + * multiple of minor loop(burst length). + */ + if (vecs[i].len % nbytes) { + u32 width =3D (direction =3D=3D DMA_DEV_TO_MEM) ? doff : soff; + u32 burst =3D (direction =3D=3D DMA_DEV_TO_MEM) ? + fsl_chan->cfg.src_maxburst : + fsl_chan->cfg.dst_maxburst; + int j; + + for (j =3D burst; j > 1; j--) { + if (!(vecs[i].len % (j * width))) { + nbytes =3D j * width; + break; + } + } + /* Set burst size as 1 if there's no suitable one */ + if (j =3D=3D 1) + nbytes =3D width; + } + + iter =3D vecs[i].len / nbytes; + if (i < nb - 1) { + last_sg =3D fsl_desc->tcd[(i + 1)].ptcd; + fsl_edma_fill_tcd(fsl_chan, fsl_desc->tcd[i].vtcd, src_addr, + dst_addr, fsl_chan->attr, soff, + nbytes, 0, iter, iter, doff, last_sg, + false, false, true); + } else { + if (fsl_desc->iscyclic) { + last_sg =3D fsl_desc->tcd[0].ptcd; + fsl_edma_fill_tcd(fsl_chan, fsl_desc->tcd[i].vtcd, src_addr, + dst_addr, fsl_chan->attr, soff, + nbytes, 0, iter, iter, doff, last_sg, + true, false, true); + } else { + last_sg =3D 0; + fsl_edma_fill_tcd(fsl_chan, fsl_desc->tcd[i].vtcd, src_addr, + dst_addr, fsl_chan->attr, soff, + nbytes, 0, iter, iter, doff, last_sg, + true, true, false); + } + } + } + + return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags); +} + struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg( struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction direction, diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h index 205a96489094..0d028048701d 100644 --- a/drivers/dma/fsl-edma-common.h +++ b/drivers/dma/fsl-edma-common.h @@ -496,6 +496,10 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cycl= ic( struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len, size_t period_len, enum dma_transfer_direction direction, unsigned long flags); +struct dma_async_tx_descriptor *fsl_edma_prep_peripheral_dma_vec( + struct dma_chan *chan, const struct dma_vec *vecs, + size_t nb, enum dma_transfer_direction direction, + unsigned long flags); struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg( struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction direction, diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c index 36155ab1602a..6693b4270a1a 100644 --- a/drivers/dma/fsl-edma-main.c +++ b/drivers/dma/fsl-edma-main.c @@ -841,6 +841,8 @@ static int fsl_edma_probe(struct platform_device *pdev) fsl_edma->dma_dev.device_free_chan_resources =3D fsl_edma_free_chan_resources; fsl_edma->dma_dev.device_tx_status =3D fsl_edma_tx_status; + fsl_edma->dma_dev.device_prep_peripheral_dma_vec + =3D fsl_edma_prep_peripheral_dma_vec; fsl_edma->dma_dev.device_prep_slave_sg =3D fsl_edma_prep_slave_sg; fsl_edma->dma_dev.device_prep_dma_cyclic =3D fsl_edma_prep_dma_cyclic; fsl_edma->dma_dev.device_prep_dma_memcpy =3D fsl_edma_prep_memcpy; --=20 2.54.0 From nobody Sat Jun 13 02:07:30 2026 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B63FC3FBED1; Mon, 11 May 2026 13:57:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778507862; cv=none; b=fpxIKVTd3hUj/7OPuwbOT49YZ9ak/2wnduedshNrkUn2s7x0+zN9AX3qMfP4J1dlrjNwOQqlqsAoU5yDKtEzTF3UqL33bvrMGs3ll/Lqa/lUjMqUeVUUKKuH9A8syUKnCqdGb5EilbsEJ90sIwf3baqc+MPSM9ttS4CR+yRBSv4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778507862; c=relaxed/simple; bh=zC2ID6l8GFBR4BwqI17VFWdO/ilVRuNe2iMT31YrZko=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=m/7K0tE9iPBufQ5GrParACHA+b/a3aDTbmwrkaCXnxbTOO9bgqOM2BDTfudYDGcT13sFEtLtl4Zcv8ZgYaLYjHJJrnt/EKxg1sLhU+1JdxtZiziGFF4qVE0JW4iAH3Ox6e8EpKi6GLWdcmN5sJSzB3+SMfmolKzL5a+zqK8PFic= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=ZEiFWH4s; arc=none smtp.client-ip=185.171.202.116 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="ZEiFWH4s" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 26E58C5E157; Mon, 11 May 2026 13:58:17 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 9882160646; Mon, 11 May 2026 13:57:27 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 64ED311AF9DE3; Mon, 11 May 2026 15:57:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1778507847; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=DZJQYNOuRsWLR9PD9/2j37j4WivCD7wFTOz83ku666g=; b=ZEiFWH4sHQTRT8m8N0k6tThuYFmm0q66cxYnIe0fLpPnouwdbJnDAuavG3MTjQugQ9ppSp Ov7RLdPyVbS0vnAny26t1jEYoxtA11zFEMNTU/Jh8QlwiL+H4KEXA8Yx2KZCJKYYeoLQmt lAtgrjHhr7H1FZfan0OahLmN+BnuF0hj6Wkbj3EnBJxE9XWRPqQBM4EWMUhP46GHTQVL+T YcITbEtQeGVFoezm8FyDzjIzevDDjdXDCzsTd8FF1xDdOSOmGc2L5zGeHq9wJgmLQBzvgM 77kt4R5jH1jAVZvSGfQGllfcBxK1qX2glgZvCV1wBmBdySdQLZZMRxPSdPPCJg== From: =?utf-8?q?Beno=C3=AEt_Monin?= Date: Mon, 11 May 2026 15:57:20 +0200 Subject: [PATCH v3 2/2] dmaengine: fsl-edma: Support dynamic scatter/gather chaining Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260511-fsl-edma-dyn-sg-v3-2-98a181775dae@bootlin.com> References: <20260511-fsl-edma-dyn-sg-v3-0-98a181775dae@bootlin.com> In-Reply-To: <20260511-fsl-edma-dyn-sg-v3-0-98a181775dae@bootlin.com> To: Frank Li , Vinod Koul Cc: Thomas Petazzoni , Frank Li , imx@lists.linux.dev, dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Beno=C3=AEt_Monin?= X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 Implement dynamic linking of scatter/gather transfers to enable chaining multiple DMA descriptors without stopping the channel. This avoids waiting for the channel to go idle if there is another transaction already issued. Add fsl_edma_link_sg() to dynamically link the last TCD of a previously submitted descriptor to the first TCD of a new descriptor by setting the scatter/gather address and the E_SG flag, and keeping the channel active by clearing the DREQ bit. Linking is done when the transaction is submitted by fsl_edma_tx_submit(). To do so, the .tx_submit() callback is overridden for non-cyclic transactions prepared by fsl_edma_prep_peripheral_dma_vec() and fsl_edma_prep_slave_sg(). This ensures that transactions are linked in the order they are submitted. Update fsl_edma_xfer_desc() to avoid re-initializing the hardware when a transfer is already in progress, allowing seamless chaining of descriptors. Modify the transfer completion handler to check the DONE flag in the channel CSR before marking the transfer complete. Since this flag is only available on SoC with the split registers layout, we only link transactions for DMA controllers flagged with FSL_EDMA_DRV_SPLIT_REG. Add trace event for scatter/gather linking operations. Signed-off-by: Beno=C3=AEt Monin --- drivers/dma/fsl-edma-common.c | 90 +++++++++++++++++++++++++++++++++++++++= ---- drivers/dma/fsl-edma-trace.h | 5 +++ 2 files changed, 88 insertions(+), 7 deletions(-) diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c index c10190164926..b83d1b91dca2 100644 --- a/drivers/dma/fsl-edma-common.c +++ b/drivers/dma/fsl-edma-common.c @@ -58,7 +58,10 @@ void fsl_edma_tx_chan_handler(struct fsl_edma_chan *fsl_= chan) list_del(&fsl_chan->edesc->vdesc.node); vchan_cookie_complete(&fsl_chan->edesc->vdesc); fsl_chan->edesc =3D NULL; - fsl_chan->status =3D DMA_COMPLETE; + if (!(fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_SPLIT_REG) || + (edma_readl_chreg(fsl_chan, ch_csr) & EDMA_V3_CH_CSR_DONE)) { + fsl_chan->status =3D DMA_COMPLETE; + } } else { vchan_cyclic_callback(&fsl_chan->edesc->vdesc); } @@ -673,6 +676,68 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cycl= ic( return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags); } =20 +static void fsl_edma_link_sg(struct fsl_edma_chan *fsl_chan, struct fsl_ed= ma_desc *fsl_desc) +{ + u32 flags =3D fsl_edma_drvflags(fsl_chan); + struct fsl_edma_hw_tcd *last_tcd; + struct fsl_edma_desc *prev_desc; + struct virt_dma_desc *vdesc; + u16 csr; + + lockdep_assert_held(&fsl_chan->vchan.lock); + + if (!(flags & FSL_EDMA_DRV_SPLIT_REG)) + return; + + vdesc =3D list_last_entry_or_null(&fsl_chan->vchan.desc_issued, + struct virt_dma_desc, node); + if (!vdesc) + vdesc =3D list_last_entry_or_null(&fsl_chan->vchan.desc_submitted, + struct virt_dma_desc, node); + if (!vdesc) + return; + + prev_desc =3D to_fsl_edma_desc(vdesc); + last_tcd =3D prev_desc->tcd[prev_desc->n_tcds - 1].vtcd; + + csr =3D fsl_edma_get_tcd_to_cpu(fsl_chan, last_tcd, csr); + if (!(csr & EDMA_TCD_CSR_D_REQ)) + return; + + fsl_edma_set_tcd_to_le(fsl_chan, last_tcd, fsl_desc->tcd[0].ptcd, dlast_s= ga); + + csr &=3D ~EDMA_TCD_CSR_D_REQ; + csr |=3D EDMA_TCD_CSR_E_SG; + fsl_edma_set_tcd_to_le(fsl_chan, last_tcd, csr, csr); + + if (prev_desc =3D=3D fsl_chan->edesc && prev_desc->n_tcds =3D=3D 1) { + if (flags & FSL_EDMA_DRV_CLEAR_DONE_E_SG) + edma_writel_chreg(fsl_chan, edma_readl_chreg(fsl_chan, ch_csr), ch_csr); + + edma_cp_tcd_to_reg(fsl_chan, last_tcd, dlast_sga); + edma_cp_tcd_to_reg(fsl_chan, last_tcd, csr); + } + + trace_edma_link_sg(fsl_chan, last_tcd); +} + +static dma_cookie_t fsl_edma_tx_submit(struct dma_async_tx_descriptor *tx) +{ + struct virt_dma_desc *vd =3D container_of(tx, struct virt_dma_desc, tx); + struct fsl_edma_chan *fsl_chan =3D to_fsl_edma_chan(tx->chan); + struct fsl_edma_desc *fsl_desc =3D to_fsl_edma_desc(vd); + struct virt_dma_chan *vc =3D to_virt_chan(tx->chan); + dma_cookie_t cookie; + + guard(spinlock_irqsave)(&fsl_chan->vchan.lock); + + fsl_edma_link_sg(fsl_chan, fsl_desc); + cookie =3D dma_cookie_assign(tx); + list_move_tail(&vd->node, &vc->desc_submitted); + + return cookie; +} + struct dma_async_tx_descriptor * fsl_edma_prep_peripheral_dma_vec(struct dma_chan *chan, const struct dma_v= ec *vecs, size_t nb, enum dma_transfer_direction direction, @@ -680,6 +745,7 @@ fsl_edma_prep_peripheral_dma_vec(struct dma_chan *chan,= const struct dma_vec *ve { struct fsl_edma_chan *fsl_chan =3D to_fsl_edma_chan(chan); dma_addr_t src_addr, dst_addr, last_sg; + struct dma_async_tx_descriptor *tx; struct fsl_edma_desc *fsl_desc; u16 soff, doff, iter; u32 nbytes; @@ -779,7 +845,10 @@ fsl_edma_prep_peripheral_dma_vec(struct dma_chan *chan= , const struct dma_vec *ve } } =20 - return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags); + tx =3D vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags); + if (!fsl_desc->iscyclic) + tx->tx_submit =3D fsl_edma_tx_submit; + return tx; } =20 struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg( @@ -788,9 +857,10 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg( unsigned long flags, void *context) { struct fsl_edma_chan *fsl_chan =3D to_fsl_edma_chan(chan); + dma_addr_t src_addr, dst_addr, last_sg; + struct dma_async_tx_descriptor *tx; struct fsl_edma_desc *fsl_desc; struct scatterlist *sg; - dma_addr_t src_addr, dst_addr, last_sg; u16 soff, doff, iter; u32 nbytes; int i; @@ -882,7 +952,10 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg( } } =20 - return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags); + tx =3D vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags); + tx->tx_submit =3D fsl_edma_tx_submit; + + return tx; } =20 struct dma_async_tx_descriptor *fsl_edma_prep_memcpy(struct dma_chan *chan, @@ -924,9 +997,12 @@ void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan) if (!vdesc) return; fsl_chan->edesc =3D to_fsl_edma_desc(vdesc); - fsl_edma_set_tcd_regs(fsl_chan, fsl_chan->edesc->tcd[0].vtcd); - fsl_edma_enable_request(fsl_chan); - fsl_chan->status =3D DMA_IN_PROGRESS; + + if (fsl_chan->status !=3D DMA_IN_PROGRESS) { + fsl_edma_set_tcd_regs(fsl_chan, fsl_chan->edesc->tcd[0].vtcd); + fsl_edma_enable_request(fsl_chan); + fsl_chan->status =3D DMA_IN_PROGRESS; + } } =20 void fsl_edma_issue_pending(struct dma_chan *chan) diff --git a/drivers/dma/fsl-edma-trace.h b/drivers/dma/fsl-edma-trace.h index d3541301a247..ac319d2dbb90 100644 --- a/drivers/dma/fsl-edma-trace.h +++ b/drivers/dma/fsl-edma-trace.h @@ -119,6 +119,11 @@ DEFINE_EVENT(edma_log_tcd, edma_fill_tcd, TP_ARGS(chan, tcd) ); =20 +DEFINE_EVENT(edma_log_tcd, edma_link_sg, + TP_PROTO(struct fsl_edma_chan *chan, void *tcd), + TP_ARGS(chan, tcd) +); + #endif =20 /* this part must be outside header guard */ --=20 2.54.0