linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH linux-next v2 0/2] follow up fix patch for dynamic burst
@ 2017-05-23 14:35 jiada_wang
  2017-05-23 14:35 ` [PATCH linux-next v2 1/2] spi: imx: only allow dynamic burst in PIO mode jiada_wang
  2017-05-23 14:35 ` [PATCH linux-next v2 2/2] spi: imx: don't manipulate trasnfer buffer directly jiada_wang
  0 siblings, 2 replies; 3+ messages in thread
From: jiada_wang @ 2017-05-23 14:35 UTC (permalink / raw)
  To: broonie; +Cc: linux-spi, linux-kernel, Jiada Wang

From: Jiada Wang <jiada_wang@mentor.com>

v1:
only allow to use dynamic burst in PIO mode, to address the issue
reported by Fabio

v2:
add one more patch to avoid direct manipulation of tx_buf,
to address the issue reported by Sascha

Jiada Wang (2):
  spi: imx: only allow dynamic burst in PIO mode
  spi: imx: don't manipulate trasnfer buffer directly

 drivers/spi/spi-imx.c | 84 ++++++++++++++++++++++++---------------------------
 1 file changed, 39 insertions(+), 45 deletions(-)

-- 
2.7.4

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

* [PATCH linux-next v2 1/2] spi: imx: only allow dynamic burst in PIO mode
  2017-05-23 14:35 [PATCH linux-next v2 0/2] follow up fix patch for dynamic burst jiada_wang
@ 2017-05-23 14:35 ` jiada_wang
  2017-05-23 14:35 ` [PATCH linux-next v2 2/2] spi: imx: don't manipulate trasnfer buffer directly jiada_wang
  1 sibling, 0 replies; 3+ messages in thread
From: jiada_wang @ 2017-05-23 14:35 UTC (permalink / raw)
  To: broonie; +Cc: linux-spi, linux-kernel, Jiada Wang

From: Jiada Wang <jiada_wang@mentor.com>

Currently only PIO mode supports dynamic burst length adjust,
in DMA mode, bpw (bytes per word) value still has to be used
as burst length, other wise transfer issue will be caused.

This patch avoid using dynamic burst in DMA mode by set
reset dynamic_burst when DMA mode is used.

Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
Reported-and-tested-by: Fabio Estevam <fabio.estevam@nxp.com>
---
 drivers/spi/spi-imx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 19b30cf..2768e64 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -242,6 +242,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
 		return false;
 
 	spi_imx->wml = i;
+	spi_imx->dynamic_burst = 0;
 
 	return true;
 }
-- 
2.7.4

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

* [PATCH linux-next v2 2/2] spi: imx: don't manipulate trasnfer buffer directly
  2017-05-23 14:35 [PATCH linux-next v2 0/2] follow up fix patch for dynamic burst jiada_wang
  2017-05-23 14:35 ` [PATCH linux-next v2 1/2] spi: imx: only allow dynamic burst in PIO mode jiada_wang
@ 2017-05-23 14:35 ` jiada_wang
  1 sibling, 0 replies; 3+ messages in thread
From: jiada_wang @ 2017-05-23 14:35 UTC (permalink / raw)
  To: broonie; +Cc: linux-spi, linux-kernel, Jiada Wang

From: Jiada Wang <jiada_wang@mentor.com>

Previously spi_imx_u32_swap_u8() and spi_imx_u32_swap_u16() directly
manipulate const tx buffer by explicit cast from const void* to u32*,
this is not valid.

This patch by swap 32 bits data one by one before write to register,
and swap received 32 bits data one by one before save to receive
buffer to avoid direct manipulation of transfer buffer.

Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
Reported-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/spi/spi-imx.c | 83 +++++++++++++++++++++++----------------------------
 1 file changed, 38 insertions(+), 45 deletions(-)

diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 2768e64..4144228 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -285,38 +285,38 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
 #define MX51_ECSPI_TESTREG	0x20
 #define MX51_ECSPI_TESTREG_LBC	BIT(31)
 
-static void spi_imx_u32_swap_u8(struct spi_transfer *transfer, u32 *buf)
+static u32 spi_imx_u32_swap_u16(u32 val)
 {
-	int i;
+	u32 data = val;
+	u16 *temp = (u16 *)&data;
 
-	if (!buf)
-		return;
+	*temp = cpu_to_be16(*temp);
+	*(temp + 1) = cpu_to_be16(*(temp + 1));
 
-	for (i = 0; i < transfer->len / 4; i++)
-		*(buf + i) = cpu_to_be32(*(buf + i));
+	data = cpu_to_be32(data);
+
+	return data;
 }
 
-static void spi_imx_u32_swap_u16(struct spi_transfer *transfer, u32 *buf)
+static void spi_imx_buf_rx_swap_u32(struct spi_imx_data *spi_imx)
 {
-	int i;
-
-	if (!buf)
-		return;
-
-	for (i = 0; i < transfer->len / 4; i++) {
-		u16 *temp = (u16 *)buf;
+	unsigned int val = readl(spi_imx->base + MXC_CSPIRXDATA);
 
-		*(temp + i * 2) = cpu_to_be16(*(temp + i * 2));
-		*(temp + i * 2 + 1) = cpu_to_be16(*(temp + i * 2 + 1));
+	if (spi_imx->rx_buf) {
+		if (spi_imx->bpw_w == 1)
+			val = cpu_to_be32(val);
+		else if (spi_imx->bpw_w == 2)
+			val = spi_imx_u32_swap_u16(val);
 
-		*(buf + i) = cpu_to_be32(*(buf + i));
+		*(u32 *)spi_imx->rx_buf = val;
+		spi_imx->rx_buf += sizeof(u32);
 	}
 }
 
 static void spi_imx_buf_rx_swap(struct spi_imx_data *spi_imx)
 {
 	if (!spi_imx->bpw_rx) {
-		spi_imx_buf_rx_u32(spi_imx);
+		spi_imx_buf_rx_swap_u32(spi_imx);
 		return;
 	}
 
@@ -326,6 +326,24 @@ static void spi_imx_buf_rx_swap(struct spi_imx_data *spi_imx)
 		spi_imx_buf_rx_u16(spi_imx);
 }
 
+static void spi_imx_buf_tx_swap_u32(struct spi_imx_data *spi_imx)
+{
+	u32 val = 0;
+
+	if (spi_imx->tx_buf) {
+		val = *(u32 *)spi_imx->tx_buf;
+		spi_imx->tx_buf += sizeof(u32);
+	}
+
+	spi_imx->count -= sizeof(u32);
+	if (spi_imx->bpw_w == 1)
+		val = cpu_to_be32(val);
+	else if (spi_imx->bpw_w == 2)
+		val = spi_imx_u32_swap_u16(val);
+
+	writel(val, spi_imx->base + MXC_CSPITXDATA);
+}
+
 static void spi_imx_buf_tx_swap(struct spi_imx_data *spi_imx)
 {
 	u32 ctrl, val;
@@ -346,7 +364,7 @@ static void spi_imx_buf_tx_swap(struct spi_imx_data *spi_imx)
 	}
 
 	if (spi_imx->count >= sizeof(u32)) {
-		spi_imx_buf_tx_u32(spi_imx);
+		spi_imx_buf_tx_swap_u32(spi_imx);
 		return;
 	}
 
@@ -1212,18 +1230,6 @@ static int spi_imx_pio_transfer(struct spi_device *spi,
 		else
 			spi_imx->count_index = spi_imx->count % sizeof(u32);
 
-		switch (spi_imx->bpw_w) {
-		case 1:
-			spi_imx_u32_swap_u8(transfer,
-					    (u32 *)transfer->tx_buf);
-			break;
-		case 2:
-			spi_imx_u32_swap_u16(transfer,
-					     (u32 *)transfer->tx_buf);
-			break;
-		default:
-			break;
-		}
 	}
 
 	reinit_completion(&spi_imx->xfer_done);
@@ -1242,21 +1248,8 @@ static int spi_imx_pio_transfer(struct spi_device *spi,
 		return -ETIMEDOUT;
 	}
 
-	if (spi_imx->dynamic_burst) {
-		switch (spi_imx->bpw_w) {
-		case 1:
-			spi_imx_u32_swap_u8(transfer,
-					    (u32 *)transfer->rx_buf);
-			break;
-		case 2:
-			spi_imx_u32_swap_u16(transfer,
-					     (u32 *)transfer->rx_buf);
-			break;
-		default:
-			break;
-		}
+	if (spi_imx->dynamic_burst)
 		spi_imx->dynamic_burst = 0;
-	}
 
 	return transfer->len;
 }
-- 
2.7.4

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

end of thread, other threads:[~2017-05-23 14:35 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-23 14:35 [PATCH linux-next v2 0/2] follow up fix patch for dynamic burst jiada_wang
2017-05-23 14:35 ` [PATCH linux-next v2 1/2] spi: imx: only allow dynamic burst in PIO mode jiada_wang
2017-05-23 14:35 ` [PATCH linux-next v2 2/2] spi: imx: don't manipulate trasnfer buffer directly jiada_wang

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