[U-Boot] [PATCH 07/18] sf: share write generic algorithm

Cyrille Pitchen cyrille.pitchen at atmel.com
Tue Mar 15 19:12:29 CET 2016


This patch splits the generic algorithm to write data from the
actual implementation which is specific to each UCLASS_SPI_FLASH driver.

For now, the sf_probe.c driver is the only instance of this driver class
using this generic algorithm but other driver instances are to come.
This patch will ease their implementation.

Please note that the sf_dataflash.c driver has its own implementation of
the .write hook (of the struct dm_spi_flash_ops) which is not compatible
with this generic algorithm. This is why we can't simply change the
prototype of .write hook and create a spi_flash_write() wrapper.

Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
---
 drivers/mtd/spi/sf_internal.h |  5 +++++
 drivers/mtd/spi/spi_flash.c   | 34 ++++++++++++++++++++++++----------
 2 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 3c6bac3464f8..592c23cd4ce1 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -214,6 +214,11 @@ int spi_flash_update_reg(struct spi_flash *flash, u8 opcode, size_t len,
 int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
 		size_t len, const void *buf);
 
+typedef int (*spi_flash_write_fn)(struct spi_flash *, u32, size_t,
+				  const void *);
+int spi_flash_write_alg(struct spi_flash *flash, u32 offset, size_t len,
+			const void *buf, spi_flash_write_fn write_fn);
+
 /* Flash read operation, support all possible read commands */
 int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
 		size_t len, void *data);
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 20b8c31c09e0..3c8224c2b084 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -366,14 +366,13 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
 	return spi_flash_erase_alg(flash, offset, len, spi_flash_erase_impl);
 }
 
-int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
-		size_t len, const void *buf)
+int spi_flash_write_alg(struct spi_flash *flash, u32 offset, size_t len,
+			const void *buf, spi_flash_write_fn write_fn)
 {
 	struct spi_slave *spi = flash->spi;
 	unsigned long byte_addr, page_size;
 	u32 write_addr;
 	size_t chunk_len, actual;
-	u8 cmd[SPI_FLASH_CMD_LEN];
 	int ret = -1;
 
 	page_size = flash->page_size;
@@ -393,7 +392,6 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
 		}
 	}
 
-	cmd[0] = flash->write_cmd;
 	for (actual = 0; actual < len; actual += chunk_len) {
 		write_addr = offset;
 
@@ -419,13 +417,10 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
 			break;
 		}
 
-		spi_flash_addr(write_addr, cmd);
-
-		debug("SF: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
-		      buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
+		debug("SF: 0x%p => cmd = { 0x%02x 0x%06x } chunk_len = %zu\n",
+		      buf + actual, flash->write_cmd, write_addr, chunk_len);
 
-		ret = spi_flash_cmd_write(spi, cmd, sizeof(cmd),
-					  buf + actual, chunk_len);
+		ret = write_fn(flash, write_addr, chunk_len, buf + actual);
 		if (ret < 0) {
 			debug("SF: write failed\n");
 			break;
@@ -446,6 +441,25 @@ release:
 	return ret;
 }
 
+static int spi_flash_write_impl(struct spi_flash *flash, u32 offset,
+				size_t len, const void *buf)
+{
+	struct spi_slave *spi = flash->spi;
+	u8 cmd[SPI_FLASH_CMD_LEN];
+	size_t cmdsz = sizeof(cmd);
+
+	cmd[0] = flash->write_cmd;
+	spi_flash_addr(offset, cmd);
+	return spi_flash_cmd_write(spi, cmd, cmdsz, buf, len);
+}
+
+int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
+			    size_t len, const void *buf)
+{
+	return spi_flash_write_alg(flash, offset, len, buf,
+				   spi_flash_write_impl);
+}
+
 /*
  * TODO: remove the weak after all the other spi_flash_copy_mmap
  * implementations removed from drivers
-- 
1.8.2.2



More information about the U-Boot mailing list