[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