[U-Boot] [PATCH 06/18] sf: share erase generic algorithm

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


This patch splits the generic algorithm to erase pages/sectors 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 .erase 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 .erase hook and create a spi_flash_erase() wrapper.

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

diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index e2a4449dbf40..3c6bac3464f8 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -169,6 +169,10 @@ int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len,
 /* Flash erase(sectors) operation, support all possible erase commands */
 int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len);
 
+typedef int (*spi_flash_erase_fn)(struct spi_flash *, u32);
+int spi_flash_erase_alg(struct spi_flash *flash, u32 offset, size_t len,
+			spi_flash_erase_fn erase_fn);
+
 /* Lock stmicro spi flash region */
 int stm_lock(struct spi_flash *flash, u32 ofs, size_t len);
 
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 6f30ff6f8d7c..20b8c31c09e0 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -281,11 +281,11 @@ int spi_flash_update_reg(struct spi_flash *flash, u8 opcode,
 	return 0;
 }
 
-int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
+int spi_flash_erase_alg(struct spi_flash *flash, u32 offset, size_t len,
+			spi_flash_erase_fn erase_fn)
 {
 	struct spi_slave *spi = flash->spi;
 	u32 erase_size, erase_addr;
-	u8 cmd[SPI_FLASH_CMD_LEN];
 	int ret = -1;
 
 	erase_size = flash->erase_size;
@@ -309,7 +309,6 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
 		}
 	}
 
-	cmd[0] = flash->erase_cmd;
 	while (len) {
 		erase_addr = offset;
 
@@ -328,12 +327,8 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
 			break;
 		}
 
-		spi_flash_addr(erase_addr, cmd);
-
-		debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
-		      cmd[2], cmd[3], erase_addr);
-
-		ret = spi_flash_cmd_write(spi, cmd, sizeof(cmd), NULL, 0);
+		debug("SF: erase %2x %06x\n", flash->erase_cmd, erase_addr);
+		ret = erase_fn(flash, erase_addr);
 		if (ret < 0) {
 			debug("SF: erase failed\n");
 			break;
@@ -356,6 +351,21 @@ release:
 	return ret;
 }
 
+static int spi_flash_erase_impl(struct spi_flash *flash, u32 offset)
+{
+	struct spi_slave *spi = flash->spi;
+	u8 cmd[SPI_FLASH_CMD_LEN];
+
+	cmd[0] = flash->erase_cmd;
+	spi_flash_addr(offset, cmd);
+	return spi_flash_cmd_write(spi, cmd, sizeof(cmd), NULL, 0);
+}
+
+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)
 {
-- 
1.8.2.2



More information about the U-Boot mailing list