linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] dmaengine: stm32-dma: some corner case fixes
@ 2021-10-11  9:42 Amelie Delaunay
  2021-10-11  9:42 ` [PATCH 1/3] dmaengine: stm32-dma: mark pending descriptor complete in terminate_all Amelie Delaunay
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Amelie Delaunay @ 2021-10-11  9:42 UTC (permalink / raw)
  To: Vinod Koul, Maxime Coquelin, Alexandre Torgue
  Cc: dmaengine, linux-stm32, linux-arm-kernel, linux-kernel,
	Amelie Delaunay, Pierre-Yves Mordret

This patchset brings some fixes to STM32 DMA driver.
It fixes undefined behaviour of STM32 DMA controller when an unaligned address
is used.
It also prevents accidental repeated completion using dma_cookie_complete() in
terminate_all().

Amelie Delaunay (3):
  dmaengine: stm32-dma: mark pending descriptor complete in
    terminate_all
  dmaengine: stm32-dma: fix stm32_dma_get_max_width
  dmaengine: stm32-dma: fix burst in case of unaligned memory address

 drivers/dma/stm32-dma.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] dmaengine: stm32-dma: mark pending descriptor complete in terminate_all
  2021-10-11  9:42 [PATCH 0/3] dmaengine: stm32-dma: some corner case fixes Amelie Delaunay
@ 2021-10-11  9:42 ` Amelie Delaunay
  2021-10-11  9:42 ` [PATCH 2/3] dmaengine: stm32-dma: fix stm32_dma_get_max_width Amelie Delaunay
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Amelie Delaunay @ 2021-10-11  9:42 UTC (permalink / raw)
  To: Vinod Koul, Maxime Coquelin, Alexandre Torgue
  Cc: dmaengine, linux-stm32, linux-arm-kernel, linux-kernel,
	Amelie Delaunay, Pierre-Yves Mordret

To prevent accidental repeated completion, mark pending descriptor
complete in terminate_all. It can be the case when terminate_all is called
while no end of transfer interrupt occurs.

Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
---
 drivers/dma/stm32-dma.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c
index 9063c727962e..a5ccf3fa95e0 100644
--- a/drivers/dma/stm32-dma.c
+++ b/drivers/dma/stm32-dma.c
@@ -497,6 +497,7 @@ static int stm32_dma_terminate_all(struct dma_chan *c)
 	spin_lock_irqsave(&chan->vchan.lock, flags);
 
 	if (chan->desc) {
+		dma_cookie_complete(&chan->desc->vdesc.tx);
 		vchan_terminate_vdesc(&chan->desc->vdesc);
 		if (chan->busy)
 			stm32_dma_stop(chan);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] dmaengine: stm32-dma: fix stm32_dma_get_max_width
  2021-10-11  9:42 [PATCH 0/3] dmaengine: stm32-dma: some corner case fixes Amelie Delaunay
  2021-10-11  9:42 ` [PATCH 1/3] dmaengine: stm32-dma: mark pending descriptor complete in terminate_all Amelie Delaunay
@ 2021-10-11  9:42 ` Amelie Delaunay
  2021-10-11  9:42 ` [PATCH 3/3] dmaengine: stm32-dma: fix burst in case of unaligned memory address Amelie Delaunay
  2021-10-18  6:43 ` [PATCH 0/3] dmaengine: stm32-dma: some corner case fixes Vinod Koul
  3 siblings, 0 replies; 5+ messages in thread
From: Amelie Delaunay @ 2021-10-11  9:42 UTC (permalink / raw)
  To: Vinod Koul, Maxime Coquelin, Alexandre Torgue
  Cc: dmaengine, linux-stm32, linux-arm-kernel, linux-kernel,
	Amelie Delaunay, Pierre-Yves Mordret

buf_addr parameter of stm32_dma_set_xfer_param function is a dma_addr_t.
We only need to check the remainder of buf_addr/max_width, so, no need to
use do_div and extra u64 addr. Use '%' instead.

Fixes: e0ebdbdcb42a ("dmaengine: stm32-dma: take address into account when computing max width")
Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
---
 drivers/dma/stm32-dma.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c
index a5ccf3fa95e0..6e4ef44941ef 100644
--- a/drivers/dma/stm32-dma.c
+++ b/drivers/dma/stm32-dma.c
@@ -270,7 +270,6 @@ static enum dma_slave_buswidth stm32_dma_get_max_width(u32 buf_len,
 						       u32 threshold)
 {
 	enum dma_slave_buswidth max_width;
-	u64 addr = buf_addr;
 
 	if (threshold == STM32_DMA_FIFO_THRESHOLD_FULL)
 		max_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
@@ -281,7 +280,7 @@ static enum dma_slave_buswidth stm32_dma_get_max_width(u32 buf_len,
 	       max_width > DMA_SLAVE_BUSWIDTH_1_BYTE)
 		max_width = max_width >> 1;
 
-	if (do_div(addr, max_width))
+	if (buf_addr % max_width)
 		max_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
 
 	return max_width;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] dmaengine: stm32-dma: fix burst in case of unaligned memory address
  2021-10-11  9:42 [PATCH 0/3] dmaengine: stm32-dma: some corner case fixes Amelie Delaunay
  2021-10-11  9:42 ` [PATCH 1/3] dmaengine: stm32-dma: mark pending descriptor complete in terminate_all Amelie Delaunay
  2021-10-11  9:42 ` [PATCH 2/3] dmaengine: stm32-dma: fix stm32_dma_get_max_width Amelie Delaunay
@ 2021-10-11  9:42 ` Amelie Delaunay
  2021-10-18  6:43 ` [PATCH 0/3] dmaengine: stm32-dma: some corner case fixes Vinod Koul
  3 siblings, 0 replies; 5+ messages in thread
From: Amelie Delaunay @ 2021-10-11  9:42 UTC (permalink / raw)
  To: Vinod Koul, Maxime Coquelin, Alexandre Torgue
  Cc: dmaengine, linux-stm32, linux-arm-kernel, linux-kernel,
	Amelie Delaunay, Pierre-Yves Mordret

Theorically, address pointers used by STM32 DMA must be chosen so as to
ensure that all transfers within a burst block are aligned on the address
boundary equal to the size of the transfer.
If this is always the case for peripheral addresses on STM32, it is not for
memory addresses if the user doesn't respect this alignment constraint.
To avoid a weird behavior of the DMA controller in this case (no error
triggered but data are not transferred as expected), force no burst.

Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
---
 drivers/dma/stm32-dma.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c
index 6e4ef44941ef..2283c500f4ce 100644
--- a/drivers/dma/stm32-dma.c
+++ b/drivers/dma/stm32-dma.c
@@ -753,8 +753,14 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
 		if (src_bus_width < 0)
 			return src_bus_width;
 
-		/* Set memory burst size */
-		src_maxburst = STM32_DMA_MAX_BURST;
+		/*
+		 * Set memory burst size - burst not possible if address is not aligned on
+		 * the address boundary equal to the size of the transfer
+		 */
+		if (buf_addr % buf_len)
+			src_maxburst = 1;
+		else
+			src_maxburst = STM32_DMA_MAX_BURST;
 		src_best_burst = stm32_dma_get_best_burst(buf_len,
 							  src_maxburst,
 							  fifoth,
@@ -803,8 +809,14 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
 		if (dst_bus_width < 0)
 			return dst_bus_width;
 
-		/* Set memory burst size */
-		dst_maxburst = STM32_DMA_MAX_BURST;
+		/*
+		 * Set memory burst size - burst not possible if address is not aligned on
+		 * the address boundary equal to the size of the transfer
+		 */
+		if (buf_addr % buf_len)
+			dst_maxburst = 1;
+		else
+			dst_maxburst = STM32_DMA_MAX_BURST;
 		dst_best_burst = stm32_dma_get_best_burst(buf_len,
 							  dst_maxburst,
 							  fifoth,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/3] dmaengine: stm32-dma: some corner case fixes
  2021-10-11  9:42 [PATCH 0/3] dmaengine: stm32-dma: some corner case fixes Amelie Delaunay
                   ` (2 preceding siblings ...)
  2021-10-11  9:42 ` [PATCH 3/3] dmaengine: stm32-dma: fix burst in case of unaligned memory address Amelie Delaunay
@ 2021-10-18  6:43 ` Vinod Koul
  3 siblings, 0 replies; 5+ messages in thread
From: Vinod Koul @ 2021-10-18  6:43 UTC (permalink / raw)
  To: Amelie Delaunay
  Cc: Maxime Coquelin, Alexandre Torgue, dmaengine, linux-stm32,
	linux-arm-kernel, linux-kernel, Pierre-Yves Mordret

On 11-10-21, 11:42, Amelie Delaunay wrote:
> This patchset brings some fixes to STM32 DMA driver.
> It fixes undefined behaviour of STM32 DMA controller when an unaligned address
> is used.
> It also prevents accidental repeated completion using dma_cookie_complete() in
> terminate_all().

Applied, thanks

-- 
~Vinod

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-10-18  6:43 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-11  9:42 [PATCH 0/3] dmaengine: stm32-dma: some corner case fixes Amelie Delaunay
2021-10-11  9:42 ` [PATCH 1/3] dmaengine: stm32-dma: mark pending descriptor complete in terminate_all Amelie Delaunay
2021-10-11  9:42 ` [PATCH 2/3] dmaengine: stm32-dma: fix stm32_dma_get_max_width Amelie Delaunay
2021-10-11  9:42 ` [PATCH 3/3] dmaengine: stm32-dma: fix burst in case of unaligned memory address Amelie Delaunay
2021-10-18  6:43 ` [PATCH 0/3] dmaengine: stm32-dma: some corner case fixes Vinod Koul

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).