[PATCH 4/8] spi: atcspi200: Fix double stop call and simplify transfer loop

Leo Yu-Chi Liang ycliang at andestech.com
Fri Apr 17 04:21:00 CEST 2026


- Remove duplicate atcspi200_hw_stop() call after the while loop;
  the stop inside the loop already handles the final chunk
- Simplify the CHUNK_SIZE=1 transfer logic: since CHUNK_SIZE was
  always 1, remove the constant and inline its value, eliminating
  dead num_bytes/rf_cnt/rx_bytes variables
- Simplify atcspi200_rx_byte() to void (return value was unused)
- Add clarifying comment on the multi-chunk address increment

Fixes: b41e12e73b2 ("spi: Add SPI driver for Andestech ATCSPI200 controller")
Signed-off-by: Leo Yu-Chi Liang <ycliang at andestech.com>
---
 drivers/spi/atcspi200_spi.c | 41 ++++++++++++-------------------------
 1 file changed, 13 insertions(+), 28 deletions(-)

diff --git a/drivers/spi/atcspi200_spi.c b/drivers/spi/atcspi200_spi.c
index 38345a88260..0e7f7b83081 100644
--- a/drivers/spi/atcspi200_spi.c
+++ b/drivers/spi/atcspi200_spi.c
@@ -18,7 +18,6 @@
 #include <linux/bitops.h>
 
 #define MAX_TRANSFER_LEN	512
-#define CHUNK_SIZE		1
 #define SPI_TIMEOUT_MS		1000
 #define SPI_DEF_SRC_CLK		100000000
 #define SPI_DEF_MAX_CLK		40000000
@@ -188,26 +187,22 @@ static void atcspi200_tx_byte(struct atcspi200_priv *priv, const void *dout)
 	atcspi200_write(priv, ATCSPI200_REG_DATA, *(u8 *)dout);
 }
 
-static int atcspi200_rx_byte(struct atcspi200_priv *priv, void *din,
-			     unsigned int bytes)
+static void atcspi200_rx_byte(struct atcspi200_priv *priv, void *din)
 {
 	*(u8 *)din = (u8)atcspi200_read(priv, ATCSPI200_REG_DATA);
-	return bytes;
 }
 
 static int atcspi200_hw_xfer(struct atcspi200_priv *priv,
 			     unsigned int bitlen, const void *data_out,
 			     void *data_in, unsigned long flags)
 {
-	unsigned int event, rx_bytes;
+	unsigned int event;
 	const void *dout = NULL;
 	void *din = NULL;
 	int num_blks, num_chunks, max_tran_len, tran_len;
-	int num_bytes;
 	u8 *cmd_buf = priv->cmd_buf;
 	size_t cmd_len = priv->cmd_len;
 	unsigned long data_len = bitlen / 8;
-	int rf_cnt;
 	int ret = 0;
 	unsigned long start;
 
@@ -250,10 +245,7 @@ static int atcspi200_hw_xfer(struct atcspi200_priv *priv,
 	while (num_chunks--) {
 		tran_len = min((size_t)data_len, (size_t)max_tran_len);
 		priv->tran_len = tran_len;
-		num_blks = DIV_ROUND_UP(tran_len, CHUNK_SIZE);
-		num_bytes = tran_len % CHUNK_SIZE;
-		if (num_bytes == 0)
-			num_bytes = CHUNK_SIZE;
+		num_blks = tran_len;
 		start = get_timer(0);
 		atcspi200_hw_start(priv);
 
@@ -267,30 +259,24 @@ static int atcspi200_hw_xfer(struct atcspi200_priv *priv,
 
 			if ((event & TXEPTY) && data_out) {
 				atcspi200_tx_byte(priv, dout);
-				num_blks -= CHUNK_SIZE;
-				dout += CHUNK_SIZE;
+				num_blks--;
+				dout++;
 			}
 
 			if ((event & RXFVE_MASK) && data_in) {
-				rf_cnt = FIELD_GET(RXFVE_MASK, event);
-				if (rf_cnt >= CHUNK_SIZE)
-					rx_bytes = CHUNK_SIZE;
-				else if (num_blks == 1 &&
-					 rf_cnt == num_bytes)
-					rx_bytes = num_bytes;
-				else
-					continue;
-
-				if (atcspi200_rx_byte(priv, din, rx_bytes) ==
-				    rx_bytes) {
-					num_blks -= CHUNK_SIZE;
-					din = (unsigned char *)din + rx_bytes;
-				}
+				atcspi200_rx_byte(priv, din);
+				num_blks--;
+				din = (unsigned char *)din + 1;
 			}
 		}
 
 		data_len -= tran_len;
 		if (data_len) {
+			/*
+			 * Increment SPI NOR read address in cmd buffer
+			 * for multi-chunk transfers (3-byte big-endian
+			 * address at cmd_buf[1..3]).
+			 */
 			priv->cmd_buf[1] += ((tran_len >> 16) & 0xff);
 			priv->cmd_buf[2] += ((tran_len >> 8) & 0xff);
 			priv->cmd_buf[3] += (tran_len & 0xff);
@@ -298,7 +284,6 @@ static int atcspi200_hw_xfer(struct atcspi200_priv *priv,
 		}
 		ret = atcspi200_hw_stop(priv);
 	}
-	ret = atcspi200_hw_stop(priv);
 
 	return ret;
 }
-- 
2.34.1



More information about the U-Boot mailing list