[U-Boot] [PATCH 3/4] sf: unify erase functions

Mike Frysinger vapier at gentoo.org
Mon Jan 10 08:20:13 CET 2011


Signed-off-by: Mike Frysinger <vapier at gentoo.org>
---
 drivers/mtd/spi/eon.c                |   55 ++---------------------------
 drivers/mtd/spi/macronix.c           |   60 ++------------------------------
 drivers/mtd/spi/spansion.c           |   57 ++-----------------------------
 drivers/mtd/spi/spi_flash.c          |   58 +++++++++++++++++++++++++++++++
 drivers/mtd/spi/spi_flash_internal.h |    5 +++
 drivers/mtd/spi/sst.c                |   63 ++--------------------------------
 drivers/mtd/spi/stmicro.c            |   59 ++------------------------------
 drivers/mtd/spi/winbond.c            |   61 ++-------------------------------
 8 files changed, 83 insertions(+), 335 deletions(-)

diff --git a/drivers/mtd/spi/eon.c b/drivers/mtd/spi/eon.c
index 4af1e06..0c0b05f 100644
--- a/drivers/mtd/spi/eon.c
+++ b/drivers/mtd/spi/eon.c
@@ -141,58 +141,11 @@ static int eon_write(struct spi_flash *flash,
 
 int eon_erase(struct spi_flash *flash, u32 offset, size_t len)
 {
-	/* block erase */
 	struct eon_spi_flash *eon = to_eon_spi_flash(flash);
-	unsigned long block_size;
-	size_t actual;
-	int ret;
-	u8 cmd[4];
-
-
-	block_size = eon->params->page_size * eon->params->pages_per_sector
-	       * eon->params->sectors_per_block;
-
-	if (offset % block_size || len % block_size) {
-		debug("SF: Erase offset/length not multiple of block size\n");
-		return -1;
-	}
-
-	len /= block_size;
-	cmd[0] = CMD_EN25Q128_BE;
-	cmd[2] = 0x00;
-	cmd[3] = 0x00;
-
-	ret = spi_claim_bus(flash->spi);
-	if (ret) {
-		debug("SF: Unable to claim SPI bus\n");
-		return ret;
-	}
-
-	ret = 0;
-	for (actual = 0; actual < len; actual++) {
-		cmd[1] = (offset / block_size) + actual;
-		ret = spi_flash_cmd(flash->spi, CMD_EN25Q128_WREN, NULL, 0);
-		if (ret < 0) {
-			debug("SF: Enabling Write failed\n");
-			break;
-		}
-
-		ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
-		if (ret < 0) {
-			debug("SF: EON page erase failed\n");
-			break;
-		}
-
-		ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
-		if (ret)
-			break;
-	}
-
-	debug("SF: EON: Successfully erased %u bytes @ 0x%x\n",
-	      len * block_size, offset);
-
-	spi_release_bus(flash->spi);
-	return ret;
+	return spi_flash_cmd_erase(flash, CMD_EN25Q128_BE,
+		eon->params->page_size * eon->params->pages_per_sector *
+			eon->params->sectors_per_block;
+		offset, len);
 }
 
 struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode)
diff --git a/drivers/mtd/spi/macronix.c b/drivers/mtd/spi/macronix.c
index 291fd17..573e1db 100644
--- a/drivers/mtd/spi/macronix.c
+++ b/drivers/mtd/spi/macronix.c
@@ -198,62 +198,10 @@ static int macronix_write(struct spi_flash *flash,
 int macronix_erase(struct spi_flash *flash, u32 offset, size_t len)
 {
 	struct macronix_spi_flash *mcx = to_macronix_spi_flash(flash);
-	unsigned long sector_size;
-	size_t actual;
-	int ret;
-	u8 cmd[4];
-
-	/*
-	 * This function currently uses sector erase only.
-	 * probably speed things up by using bulk erase
-	 * when possible.
-	 */
-
-	sector_size = mcx->params->page_size * mcx->params->pages_per_sector
-			* mcx->params->sectors_per_block;
-
-	if (offset % sector_size || len % sector_size) {
-		debug("SF: Erase offset/length not multiple of sector size\n");
-		return -1;
-	}
-
-	len /= sector_size;
-	cmd[0] = CMD_MX25XX_BE;
-	cmd[2] = 0x00;
-	cmd[3] = 0x00;
-
-	ret = spi_claim_bus(flash->spi);
-	if (ret) {
-		debug("SF: Unable to claim SPI bus\n");
-		return ret;
-	}
-
-	ret = 0;
-	for (actual = 0; actual < len; actual++) {
-		cmd[1] = (offset / sector_size) + actual;
-
-		ret = spi_flash_cmd(flash->spi, CMD_MX25XX_WREN, NULL, 0);
-		if (ret < 0) {
-			debug("SF: Enabling Write failed\n");
-			break;
-		}
-
-		ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
-		if (ret < 0) {
-			debug("SF: Macronix page erase failed\n");
-			break;
-		}
-
-		ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
-		if (ret)
-			break;
-	}
-
-	debug("SF: Macronix: Successfully erased %u bytes @ 0x%x\n",
-	      len * sector_size, offset);
-
-	spi_release_bus(flash->spi);
-	return ret;
+	return spi_flash_cmd_erase(flash, CMD_MX25XX_BE,
+		mcx->params->page_size * mcx->params->pages_per_sector *
+			mcx->params->sectors_per_block,
+		offset, len);
 }
 
 struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
diff --git a/drivers/mtd/spi/spansion.c b/drivers/mtd/spi/spansion.c
index d0f03ff..be4fc67 100644
--- a/drivers/mtd/spi/spansion.c
+++ b/drivers/mtd/spi/spansion.c
@@ -223,60 +223,9 @@ static int spansion_write(struct spi_flash *flash,
 int spansion_erase(struct spi_flash *flash, u32 offset, size_t len)
 {
 	struct spansion_spi_flash *spsn = to_spansion_spi_flash(flash);
-	unsigned long sector_size;
-	size_t actual;
-	int ret;
-	u8 cmd[4];
-
-	/*
-	 * This function currently uses sector erase only.
-	 * probably speed things up by using bulk erase
-	 * when possible.
-	 */
-
-	sector_size = spsn->params->page_size * spsn->params->pages_per_sector;
-
-	if (offset % sector_size || len % sector_size) {
-		debug("SF: Erase offset/length not multiple of sector size\n");
-		return -1;
-	}
-
-	cmd[0] = CMD_S25FLXX_SE;
-	cmd[2] = 0x00;
-	cmd[3] = 0x00;
-
-	ret = spi_claim_bus(flash->spi);
-	if (ret) {
-		debug("SF: Unable to claim SPI bus\n");
-		return ret;
-	}
-
-	ret = 0;
-	for (actual = 0; actual < len; actual += sector_size) {
-		cmd[1] = (offset + actual) >> 16;
-
-		ret = spi_flash_cmd(flash->spi, CMD_S25FLXX_WREN, NULL, 0);
-		if (ret < 0) {
-			debug("SF: Enabling Write failed\n");
-			break;
-		}
-
-		ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
-		if (ret < 0) {
-			debug("SF: SPANSION page erase failed\n");
-			break;
-		}
-
-		ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
-		if (ret)
-			break;
-	}
-
-	debug("SF: SPANSION: Successfully erased %u bytes @ 0x%x\n",
-	      len, offset);
-
-	spi_release_bus(flash->spi);
-	return ret;
+	return spi_flash_cmd_erase(flash, CMD_S25FLXX_SE,
+		spsn->params->page_size * spsn->params->pages_per_sector,
+		offset, len);
 }
 
 struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode)
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index e483ce4..ca4bbb2 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -14,6 +14,14 @@
 
 #include "spi_flash_internal.h"
 
+static void spi_flash_addr(u32 addr, u8 *cmd)
+{
+	/* cmd[0] is actual command */
+	cmd[1] = addr >> 16;
+	cmd[2] = addr >> 8;
+	cmd[3] = addr >> 0;
+}
+
 static int spi_flash_read_write(struct spi_slave *spi,
 				const u8 *cmd, size_t cmd_len,
 				const u8 *data_out, u8 *data_in,
@@ -110,6 +118,56 @@ int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
 		CMD_READ_STATUS, STATUS_WIP);
 }
 
+int spi_flash_cmd_erase(struct spi_flash *flash, u8 erase_cmd,
+			u32 erase_size, u32 offset, size_t len)
+{
+	u32 start, end;
+	int ret;
+	u8 cmd[4];
+
+	if (offset % erase_size || len % erase_size) {
+		debug("SF: Erase offset/length not multiple of erase size\n");
+		return -1;
+	}
+
+	ret = spi_claim_bus(flash->spi);
+	if (ret) {
+		debug("SF: Unable to claim SPI bus\n");
+		return ret;
+	}
+
+	cmd[0] = erase_cmd;
+	start = offset;
+	end = start + len;
+
+	while (offset < end) {
+		spi_flash_addr(offset, cmd);
+		offset += erase_size;
+
+		debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
+		      cmd[2], cmd[3], offset);
+
+		ret = spi_flash_cmd(flash->spi, CMD_WRITE_ENABLE, NULL, 0);
+		if (ret)
+			goto out;
+
+		ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), NULL, 0);
+		if (ret)
+			goto out;
+
+		ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
+		if (ret)
+			goto out;
+	}
+
+	debug("SF: Successfully erased %lu bytes @ %#x\n",
+	      len * erase_size, start);
+
+ out:
+	spi_release_bus(flash->spi);
+	return ret;
+}
+
 /*
  * The following table holds all device probe functions
  *
diff --git a/drivers/mtd/spi/spi_flash_internal.h b/drivers/mtd/spi/spi_flash_internal.h
index 440c044..114b634 100644
--- a/drivers/mtd/spi/spi_flash_internal.h
+++ b/drivers/mtd/spi/spi_flash_internal.h
@@ -20,6 +20,7 @@
 #define CMD_READ_ARRAY_LEGACY		0xe8
 
 #define CMD_READ_STATUS			0x05
+#define CMD_WRITE_ENABLE		0x06
 
 /* Common status */
 #define STATUS_WIP			0x01
@@ -58,6 +59,10 @@ int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout,
  */
 int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout);
 
+/* Erase sectors. */
+int spi_flash_cmd_erase(struct spi_flash *flash, u8 erase_cmd,
+			u32 erase_size, u32 offset, size_t len);
+
 /* Manufacturer-specific probe functions */
 struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode);
 struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode);
diff --git a/drivers/mtd/spi/sst.c b/drivers/mtd/spi/sst.c
index 4a82f8a..d550550 100644
--- a/drivers/mtd/spi/sst.c
+++ b/drivers/mtd/spi/sst.c
@@ -212,67 +212,10 @@ sst_write(struct spi_flash *flash, u32 offset, size_t len, const void *buf)
 	return ret;
 }
 
-int
-sst_erase(struct spi_flash *flash, u32 offset, size_t len)
+int sst_erase(struct spi_flash *flash, u32 offset, size_t len)
 {
-	unsigned long sector_size;
-	u32 start, end;
-	int ret;
-	u8 cmd[4];
-
-	/*
-	 * This function currently uses sector erase only.
-	 * Probably speed things up by using bulk erase
-	 * when possible.
-	 */
-
-	sector_size = SST_SECTOR_SIZE;
-
-	if (offset % sector_size) {
-		debug("SF: Erase offset not multiple of sector size\n");
-		return -1;
-	}
-
-	ret = spi_claim_bus(flash->spi);
-	if (ret) {
-		debug("SF: Unable to claim SPI bus\n");
-		return ret;
-	}
-
-	cmd[0] = CMD_SST_SE;
-	cmd[3] = 0;
-	start = offset;
-	end = start + len;
-
-	ret = 0;
-	while (offset < end) {
-		cmd[1] = offset >> 16;
-		cmd[2] = offset >> 8;
-		offset += sector_size;
-
-		debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
-		      cmd[2], cmd[3], offset);
-
-		ret = sst_enable_writing(flash);
-		if (ret)
-			break;
-
-		ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), NULL, 0);
-		if (ret) {
-			debug("SF: sst page erase failed\n");
-			break;
-		}
-
-		ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
-		if (ret)
-			break;
-	}
-
-	debug("SF: sst: Successfully erased %lu bytes @ 0x%x\n",
-	      len * sector_size, start);
-
-	spi_release_bus(flash->spi);
-	return ret;
+	return spi_flash_cmd_erase(flash, CMD_SST_SE, SST_SECTOR_SIZE,
+		offset, len);
 }
 
 static int
diff --git a/drivers/mtd/spi/stmicro.c b/drivers/mtd/spi/stmicro.c
index 02da8b2..494005c 100644
--- a/drivers/mtd/spi/stmicro.c
+++ b/drivers/mtd/spi/stmicro.c
@@ -220,62 +220,9 @@ static int stmicro_write(struct spi_flash *flash,
 int stmicro_erase(struct spi_flash *flash, u32 offset, size_t len)
 {
 	struct stmicro_spi_flash *stm = to_stmicro_spi_flash(flash);
-	unsigned long sector_size;
-	size_t actual;
-	int ret;
-	u8 cmd[4];
-
-	/*
-	 * This function currently uses sector erase only.
-	 * probably speed things up by using bulk erase
-	 * when possible.
-	 */
-
-	sector_size = stm->params->page_size * stm->params->pages_per_sector;
-
-	if (offset % sector_size || len % sector_size) {
-		debug("SF: Erase offset/length not multiple of sector size\n");
-		return -1;
-	}
-
-	len /= sector_size;
-	cmd[0] = CMD_M25PXX_SE;
-	cmd[2] = 0x00;
-	cmd[3] = 0x00;
-
-	ret = spi_claim_bus(flash->spi);
-	if (ret) {
-		debug("SF: Unable to claim SPI bus\n");
-		return ret;
-	}
-
-	ret = 0;
-	for (actual = 0; actual < len; actual++) {
-		cmd[1] = offset >> 16;
-		offset += sector_size;
-
-		ret = spi_flash_cmd(flash->spi, CMD_M25PXX_WREN, NULL, 0);
-		if (ret < 0) {
-			debug("SF: Enabling Write failed\n");
-			break;
-		}
-
-		ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
-		if (ret < 0) {
-			debug("SF: STMicro page erase failed\n");
-			break;
-		}
-
-		ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
-		if (ret)
-			break;
-	}
-
-	debug("SF: STMicro: Successfully erased %u bytes @ 0x%x\n",
-	      len * sector_size, offset);
-
-	spi_release_bus(flash->spi);
-	return ret;
+	return spi_flash_cmd_erase(flash, CMD_M25PXX_SE,
+		stm->params->page_size * stm->params->pages_per_sector,
+		offset, len);
 }
 
 struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode)
diff --git a/drivers/mtd/spi/winbond.c b/drivers/mtd/spi/winbond.c
index d8c1cb1..8470a82 100644
--- a/drivers/mtd/spi/winbond.c
+++ b/drivers/mtd/spi/winbond.c
@@ -211,64 +211,9 @@ out:
 int winbond_erase(struct spi_flash *flash, u32 offset, size_t len)
 {
 	struct winbond_spi_flash *stm = to_winbond_spi_flash(flash);
-	unsigned long sector_size;
-	unsigned int page_shift;
-	size_t actual;
-	int ret;
-	u8 cmd[4];
-
-	/*
-	 * This function currently uses sector erase only.
-	 * probably speed things up by using bulk erase
-	 * when possible.
-	 */
-
-	page_shift = stm->params->l2_page_size;
-	sector_size = (1 << page_shift) * stm->params->pages_per_sector;
-
-	if (offset % sector_size || len % sector_size) {
-		debug("SF: Erase offset/length not multiple of sector size\n");
-		return -1;
-	}
-
-	len /= sector_size;
-	cmd[0] = CMD_W25_SE;
-
-	ret = spi_claim_bus(flash->spi);
-	if (ret) {
-		debug("SF: Unable to claim SPI bus\n");
-		return ret;
-	}
-
-	for (actual = 0; actual < len; actual++) {
-		winbond_build_address(stm, &cmd[1], offset + actual * sector_size);
-		printf("Erase: %02x %02x %02x %02x\n",
-				cmd[0], cmd[1], cmd[2], cmd[3]);
-
-		ret = spi_flash_cmd(flash->spi, CMD_W25_WREN, NULL, 0);
-		if (ret < 0) {
-			debug("SF: Enabling Write failed\n");
-			goto out;
-		}
-
-		ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
-		if (ret < 0) {
-			debug("SF: Winbond sector erase failed\n");
-			goto out;
-		}
-
-		ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
-		if (ret)
-			goto out;
-	}
-
-	debug("SF: Winbond: Successfully erased %u bytes @ 0x%x\n",
-			len * sector_size, offset);
-	ret = 0;
-
-out:
-	spi_release_bus(flash->spi);
-	return ret;
+	return spi_flash_cmd_erase(flash, CMD_W25_SE,
+		(1 << stm->params->l2_page_size) * stm->params->pages_per_sector,
+		offset, len);
 }
 
 struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
-- 
1.7.4.rc1



More information about the U-Boot mailing list