[U-Boot] [PATCH 08/18] sf: share read generic algorithm

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


This patch splits the generic algorithm to read 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 .read 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 .read hook and create a spi_flash_read() wrapper.

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

diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 592c23cd4ce1..569863a31684 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -223,6 +223,10 @@ int spi_flash_write_alg(struct spi_flash *flash, u32 offset, size_t len,
 int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
 		size_t len, void *data);
 
+typedef int (*spi_flash_read_fn)(struct spi_flash *, u32, size_t, void *);
+int spi_flash_read_alg(struct spi_flash *flash, u32 offset, size_t len,
+		void *data, spi_flash_read_fn read_fn);
+
 #ifdef CONFIG_SPI_FLASH_MTD
 int spi_flash_mtd_register(struct spi_flash *flash);
 void spi_flash_mtd_unregister(void);
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 3c8224c2b084..4be99ea0b424 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -473,11 +473,10 @@ void __weak spi_flash_copy_mmap(void *data, void *offset, size_t len)
 	memcpy(data, offset, len);
 }
 
-int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
-		size_t len, void *data)
+int spi_flash_read_alg(struct spi_flash *flash, u32 offset, size_t len,
+		       void *data, spi_flash_read_fn read_fn)
 {
 	struct spi_slave *spi = flash->spi;
-	u8 *cmd, cmdsz;
 	u32 remain_len, read_len, read_addr;
 	int bank_sel = 0;
 	int ret = -1;
@@ -496,15 +495,6 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
 		goto release;
 	}
 
-	cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte;
-	cmd = calloc(1, cmdsz);
-	if (!cmd) {
-		debug("SF: Failed to allocate cmd\n");
-		ret = -ENOMEM;
-		goto release;
-	}
-
-	cmd[0] = flash->read_cmd;
 	while (len) {
 		read_addr = offset;
 
@@ -525,9 +515,7 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
 		else
 			read_len = remain_len;
 
-		spi_flash_addr(read_addr, cmd);
-
-		ret = spi_flash_cmd_read(spi, cmd, cmdsz, data, read_len);
+		ret = read_fn(flash, read_addr, read_len, data);
 		if (ret < 0) {
 			debug("SF: read failed\n");
 			break;
@@ -538,14 +526,40 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
 		data += read_len;
 	}
 
-	free(cmd);
-
 release:
 	spi_release_bus(spi);
 
 	return ret;
 }
 
+static int spi_flash_read_impl(struct spi_flash *flash, u32 offset,
+			       size_t len, void *buf)
+{
+	struct spi_slave *spi = flash->spi;
+	u8 *cmd;
+	size_t cmdsz;
+	int ret;
+
+	cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte;
+	cmd = calloc(1, cmdsz);
+	if (!cmd) {
+		debug("SF: Failed to allocate cmd\n");
+		return -ENOMEM;
+	}
+
+	cmd[0] = flash->read_cmd;
+	spi_flash_addr(offset, cmd);
+	ret = spi_flash_cmd_read(spi, cmd, cmdsz, buf, len);
+	free(cmd);
+	return ret;
+}
+
+int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
+		size_t len, void *buf)
+{
+	return spi_flash_read_alg(flash, offset, len, buf, spi_flash_read_impl);
+}
+
 #ifdef CONFIG_SPI_FLASH_SST
 static int sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf)
 {
-- 
1.8.2.2



More information about the U-Boot mailing list