[PATCH] Add flag status during SPI Flash write

Insop Song insop.song at cohere.net
Tue Jun 4 06:55:19 CEST 2013


Add spi_flash_cmd_wait_program() to align with existing code structure
Use existing spi_flash_cmd_poll_bit to check flag status for program is don=
e
Update spi_flash_cmd_poll_bit() so that it can check against check_bit inst=
ead of zero

Tested SPI flash: STMicro's N25Q512A

Signed-off-by: Insop Song <insop.song at cohere.net>
---
 drivers/mtd/spi/spi_flash.c          |   25 +++++++++++++++++++++----
 drivers/mtd/spi/spi_flash_internal.h |   10 +++++++++-
 2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 00aece9..4240e9d 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -83,6 +83,10 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u=
32 offset,
 		return ret;
 	}
=20
+	ret =3D spi_flash_cmd_wait_program(flash, SPI_FLASH_PROG_TIMEOUT);
+	if (ret)
+		return ret;
+
 	cmd[0] =3D CMD_PAGE_PROGRAM;
 	for (actual =3D 0; actual < len; actual +=3D chunk_len) {
 		chunk_len =3D min(len - actual, page_size - byte_addr);
@@ -107,6 +111,13 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash,=
 u32 offset,
 			break;
 		}
=20
+		/*
+		 * check flag status for program is done
+		 */
+		ret =3D spi_flash_cmd_wait_program(flash, SPI_FLASH_PROG_TIMEOUT);
+		if (ret)
+			break;
+
 		ret =3D spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
 		if (ret)
 			break;
@@ -148,7 +159,7 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u3=
2 offset,
 }
=20
 int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout,
-			   u8 cmd, u8 poll_bit)
+			   u8 cmd, u8 poll_bit, u8 check_bit)
 {
 	struct spi_slave *spi =3D flash->spi;
 	unsigned long timebase;
@@ -169,14 +180,14 @@ int spi_flash_cmd_poll_bit(struct spi_flash *flash, u=
nsigned long timeout,
 		if (ret)
 			return -1;
=20
-		if ((status & poll_bit) =3D=3D 0)
+		if ((status & poll_bit) =3D=3D check_bit)
 			break;
=20
 	} while (get_timer(timebase) < timeout);
=20
 	spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
=20
-	if ((status & poll_bit) =3D=3D 0)
+	if ((status & poll_bit) =3D=3D check_bit)
 		return 0;
=20
 	/* Timed out */
@@ -187,7 +198,13 @@ int spi_flash_cmd_poll_bit(struct spi_flash *flash, un=
signed long timeout,
 int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeou=
t)
 {
 	return spi_flash_cmd_poll_bit(flash, timeout,
-		CMD_READ_STATUS, STATUS_WIP);
+		CMD_READ_STATUS, STATUS_WIP, 0);
+}
+
+int spi_flash_cmd_wait_program(struct spi_flash *flash, unsigned long time=
out)
+{
+	return spi_flash_cmd_poll_bit(flash, timeout,
+		CMD_READ_FLAG_STATUS, STATUS_PEC, STATUS_PEC);
 }
=20
 int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len)
diff --git a/drivers/mtd/spi/spi_flash_internal.h b/drivers/mtd/spi/spi_fla=
sh_internal.h
index 141cfa8..670a722 100644
--- a/drivers/mtd/spi/spi_flash_internal.h
+++ b/drivers/mtd/spi/spi_flash_internal.h
@@ -22,6 +22,7 @@
 #define CMD_PAGE_PROGRAM		0x02
 #define CMD_WRITE_DISABLE		0x04
 #define CMD_READ_STATUS			0x05
+#define CMD_READ_FLAG_STATUS	0x70
 #define CMD_WRITE_ENABLE		0x06
 #define CMD_ERASE_4K			0x20
 #define CMD_ERASE_32K			0x52
@@ -30,6 +31,7 @@
=20
 /* Common status */
 #define STATUS_WIP			0x01
+#define STATUS_PEC			0x80	/* program or erase controller */
=20
 /* Send a single-byte command to the device and read the response */
 int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t le=
n);
@@ -86,7 +88,7 @@ int spi_flash_read_common(struct spi_flash *flash, const =
u8 *cmd,
=20
 /* Send a command to the device and wait for some bit to clear itself. */
 int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout,
-			   u8 cmd, u8 poll_bit);
+			   u8 cmd, u8 poll_bit, u8 check_bit);
=20
 /*
  * Send the read status command to the device and wait for the wip
@@ -94,6 +96,12 @@ int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsi=
gned long timeout,
  */
 int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeou=
t);
=20
+/*
+ * Send the read flag status command to the device and wait for the progra=
m
+ * is done and ready
+ */
+int spi_flash_cmd_wait_program(struct spi_flash *flash, unsigned long time=
out);
+
 /* Erase sectors. */
 int spi_flash_cmd_erase(struct spi_flash *flash, u32 offset, size_t len);
=20
--=20
1.7.9.5


More information about the U-Boot mailing list