sf: unify status polling for ready bit
All of the spi flash drivers implement the status register polling for detecting the device ready state, so unify them all in a new helper function -- spi_flash_wait_ready. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
This commit is contained in:
parent
000044d8bf
commit
6163045bcd
|
@ -113,35 +113,8 @@ static const struct atmel_spi_flash_params atmel_spi_flash_table[] = {
|
||||||
|
|
||||||
static int at45_wait_ready(struct spi_flash *flash, unsigned long timeout)
|
static int at45_wait_ready(struct spi_flash *flash, unsigned long timeout)
|
||||||
{
|
{
|
||||||
struct spi_slave *spi = flash->spi;
|
return spi_flash_cmd_poll_bit(flash, timeout,
|
||||||
unsigned long timebase;
|
CMD_AT45_READ_STATUS, AT45_STATUS_READY);
|
||||||
int ret;
|
|
||||||
u8 cmd = CMD_AT45_READ_STATUS;
|
|
||||||
u8 status;
|
|
||||||
|
|
||||||
timebase = get_timer(0);
|
|
||||||
|
|
||||||
ret = spi_xfer(spi, 8, &cmd, NULL, SPI_XFER_BEGIN);
|
|
||||||
if (ret)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
do {
|
|
||||||
ret = spi_xfer(spi, 8, NULL, &status, 0);
|
|
||||||
if (ret)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (status & AT45_STATUS_READY)
|
|
||||||
break;
|
|
||||||
} while (get_timer(timebase) < timeout);
|
|
||||||
|
|
||||||
/* Deactivate CS */
|
|
||||||
spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
|
|
||||||
|
|
||||||
if (status & AT45_STATUS_READY)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Timed out */
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
|
|
||||||
#define EON_ID_EN25Q128 0x18
|
#define EON_ID_EN25Q128 0x18
|
||||||
|
|
||||||
#define EON_SR_WIP (1 << 0) /* Write-in-Progress */
|
|
||||||
|
|
||||||
struct eon_spi_flash_params {
|
struct eon_spi_flash_params {
|
||||||
u8 idcode1;
|
u8 idcode1;
|
||||||
u16 page_size;
|
u16 page_size;
|
||||||
|
@ -58,40 +56,6 @@ static const struct eon_spi_flash_params eon_spi_flash_table[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int eon_wait_ready(struct spi_flash *flash, unsigned long timeout)
|
|
||||||
{
|
|
||||||
struct spi_slave *spi = flash->spi;
|
|
||||||
unsigned long timebase;
|
|
||||||
int ret;
|
|
||||||
u8 cmd = CMD_EN25Q128_RDSR;
|
|
||||||
u8 status;
|
|
||||||
|
|
||||||
ret = spi_xfer(spi, 8, &cmd, NULL, SPI_XFER_BEGIN);
|
|
||||||
if (ret) {
|
|
||||||
debug("SF: Failed to send command %02x: %d\n", cmd, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
timebase = get_timer(0);
|
|
||||||
do {
|
|
||||||
ret = spi_xfer(spi, 8, NULL, &status, 0);
|
|
||||||
if (ret)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if ((status & EON_SR_WIP) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
} while (get_timer(timebase) < timeout);
|
|
||||||
|
|
||||||
spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
|
|
||||||
|
|
||||||
if ((status & EON_SR_WIP) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Timed out */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int eon_read_fast(struct spi_flash *flash,
|
static int eon_read_fast(struct spi_flash *flash,
|
||||||
u32 offset, size_t len, void *buf)
|
u32 offset, size_t len, void *buf)
|
||||||
{
|
{
|
||||||
|
@ -160,11 +124,9 @@ static int eon_write(struct spi_flash *flash,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = eon_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
|
ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
|
||||||
if (ret < 0) {
|
if (ret)
|
||||||
debug("SF: EON page programming timed out\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
page_addr++;
|
page_addr++;
|
||||||
byte_addr = 0;
|
byte_addr = 0;
|
||||||
|
@ -221,12 +183,10 @@ int eon_erase(struct spi_flash *flash, u32 offset, size_t len)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = eon_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
|
ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
|
||||||
if (ret < 0) {
|
if (ret)
|
||||||
debug("SF: EON page erase timed out\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
debug("SF: EON: Successfully erased %u bytes @ 0x%x\n",
|
debug("SF: EON: Successfully erased %u bytes @ 0x%x\n",
|
||||||
len * block_size, offset);
|
len * block_size, offset);
|
||||||
|
|
|
@ -49,8 +49,6 @@
|
||||||
#define CMD_MX25XX_DP 0xb9 /* Deep Power-down */
|
#define CMD_MX25XX_DP 0xb9 /* Deep Power-down */
|
||||||
#define CMD_MX25XX_RES 0xab /* Release from DP, and Read Signature */
|
#define CMD_MX25XX_RES 0xab /* Release from DP, and Read Signature */
|
||||||
|
|
||||||
#define MACRONIX_SR_WIP (1 << 0) /* Write-in-Progress */
|
|
||||||
|
|
||||||
struct macronix_spi_flash_params {
|
struct macronix_spi_flash_params {
|
||||||
u16 idcode;
|
u16 idcode;
|
||||||
u16 page_size;
|
u16 page_size;
|
||||||
|
@ -114,40 +112,6 @@ static const struct macronix_spi_flash_params macronix_spi_flash_table[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int macronix_wait_ready(struct spi_flash *flash, unsigned long timeout)
|
|
||||||
{
|
|
||||||
struct spi_slave *spi = flash->spi;
|
|
||||||
unsigned long timebase;
|
|
||||||
int ret;
|
|
||||||
u8 status;
|
|
||||||
u8 cmd = CMD_MX25XX_RDSR;
|
|
||||||
|
|
||||||
ret = spi_xfer(spi, 8, &cmd, NULL, SPI_XFER_BEGIN);
|
|
||||||
if (ret) {
|
|
||||||
debug("SF: Failed to send command %02x: %d\n", cmd, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
timebase = get_timer(0);
|
|
||||||
do {
|
|
||||||
ret = spi_xfer(spi, 8, NULL, &status, 0);
|
|
||||||
if (ret)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if ((status & MACRONIX_SR_WIP) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
} while (get_timer(timebase) < timeout);
|
|
||||||
|
|
||||||
spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
|
|
||||||
|
|
||||||
if ((status & MACRONIX_SR_WIP) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Timed out */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int macronix_read_fast(struct spi_flash *flash,
|
static int macronix_read_fast(struct spi_flash *flash,
|
||||||
u32 offset, size_t len, void *buf)
|
u32 offset, size_t len, void *buf)
|
||||||
{
|
{
|
||||||
|
@ -216,11 +180,9 @@ static int macronix_write(struct spi_flash *flash,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = macronix_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
|
ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
|
||||||
if (ret < 0) {
|
if (ret)
|
||||||
debug("SF: Macronix page programming timed out\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
page_addr++;
|
page_addr++;
|
||||||
byte_addr = 0;
|
byte_addr = 0;
|
||||||
|
@ -282,12 +244,10 @@ int macronix_erase(struct spi_flash *flash, u32 offset, size_t len)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = macronix_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
|
ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
|
||||||
if (ret < 0) {
|
if (ret)
|
||||||
debug("SF: Macronix page erase timed out\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
debug("SF: Macronix: Successfully erased %u bytes @ 0x%x\n",
|
debug("SF: Macronix: Successfully erased %u bytes @ 0x%x\n",
|
||||||
len * sector_size, offset);
|
len * sector_size, offset);
|
||||||
|
|
|
@ -54,8 +54,6 @@
|
||||||
#define SPSN_EXT_ID_S25FL128P_64KB 0x0301
|
#define SPSN_EXT_ID_S25FL128P_64KB 0x0301
|
||||||
#define SPSN_EXT_ID_S25FL032P 0x4d00
|
#define SPSN_EXT_ID_S25FL032P 0x4d00
|
||||||
|
|
||||||
#define SPANSION_SR_WIP (1 << 0) /* Write-in-Progress */
|
|
||||||
|
|
||||||
struct spansion_spi_flash_params {
|
struct spansion_spi_flash_params {
|
||||||
u16 idcode1;
|
u16 idcode1;
|
||||||
u16 idcode2;
|
u16 idcode2;
|
||||||
|
@ -135,32 +133,6 @@ static const struct spansion_spi_flash_params spansion_spi_flash_table[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int spansion_wait_ready(struct spi_flash *flash, unsigned long timeout)
|
|
||||||
{
|
|
||||||
struct spi_slave *spi = flash->spi;
|
|
||||||
unsigned long timebase;
|
|
||||||
int ret;
|
|
||||||
u8 status;
|
|
||||||
|
|
||||||
timebase = get_timer(0);
|
|
||||||
do {
|
|
||||||
ret = spi_flash_cmd(spi, CMD_S25FLXX_RDSR, &status, sizeof(status));
|
|
||||||
if (ret)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if ((status & SPANSION_SR_WIP) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
} while (get_timer(timebase) < timeout);
|
|
||||||
|
|
||||||
|
|
||||||
if ((status & SPANSION_SR_WIP) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Timed out */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int spansion_read_fast(struct spi_flash *flash,
|
static int spansion_read_fast(struct spi_flash *flash,
|
||||||
u32 offset, size_t len, void *buf)
|
u32 offset, size_t len, void *buf)
|
||||||
{
|
{
|
||||||
|
@ -233,11 +205,9 @@ static int spansion_write(struct spi_flash *flash,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = spansion_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
|
ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
|
||||||
if (ret < 0) {
|
if (ret)
|
||||||
debug("SF: SPANSION page programming timed out\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
page_addr++;
|
page_addr++;
|
||||||
byte_addr = 0;
|
byte_addr = 0;
|
||||||
|
@ -297,13 +267,10 @@ int spansion_erase(struct spi_flash *flash, u32 offset, size_t len)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Up to 2 seconds */
|
ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
|
||||||
ret = spansion_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
|
if (ret)
|
||||||
if (ret < 0) {
|
|
||||||
debug("SF: SPANSION page erase timed out\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
debug("SF: SPANSION: Successfully erased %u bytes @ 0x%x\n",
|
debug("SF: SPANSION: Successfully erased %u bytes @ 0x%x\n",
|
||||||
len, offset);
|
len, offset);
|
||||||
|
|
|
@ -69,6 +69,47 @@ int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int spi_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout,
|
||||||
|
u8 cmd, u8 poll_bit)
|
||||||
|
{
|
||||||
|
struct spi_slave *spi = flash->spi;
|
||||||
|
unsigned long timebase;
|
||||||
|
int ret;
|
||||||
|
u8 status;
|
||||||
|
|
||||||
|
ret = spi_xfer(spi, 8, &cmd, NULL, SPI_XFER_BEGIN);
|
||||||
|
if (ret) {
|
||||||
|
debug("SF: Failed to send command %02x: %d\n", cmd, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
timebase = get_timer(0);
|
||||||
|
do {
|
||||||
|
ret = spi_xfer(spi, 8, NULL, &status, 0);
|
||||||
|
if (ret)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if ((status & poll_bit) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
} while (get_timer(timebase) < timeout);
|
||||||
|
|
||||||
|
spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
|
||||||
|
|
||||||
|
if ((status & poll_bit) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Timed out */
|
||||||
|
debug("SF: time out!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
|
||||||
|
{
|
||||||
|
return spi_flash_cmd_poll_bit(flash, timeout,
|
||||||
|
CMD_READ_STATUS, STATUS_WIP);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following table holds all device probe functions
|
* The following table holds all device probe functions
|
||||||
*
|
*
|
||||||
|
|
|
@ -19,6 +19,11 @@
|
||||||
#define CMD_READ_ARRAY_FAST 0x0b
|
#define CMD_READ_ARRAY_FAST 0x0b
|
||||||
#define CMD_READ_ARRAY_LEGACY 0xe8
|
#define CMD_READ_ARRAY_LEGACY 0xe8
|
||||||
|
|
||||||
|
#define CMD_READ_STATUS 0x05
|
||||||
|
|
||||||
|
/* Common status */
|
||||||
|
#define STATUS_WIP 0x01
|
||||||
|
|
||||||
/* Send a single-byte command to the device and read the response */
|
/* 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 len);
|
int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len);
|
||||||
|
|
||||||
|
@ -43,6 +48,16 @@ int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len,
|
||||||
int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd,
|
int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd,
|
||||||
size_t cmd_len, void *data, size_t data_len);
|
size_t cmd_len, void *data, size_t data_len);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send the read status command to the device and wait for the wip
|
||||||
|
* (write-in-progress) bit to clear itself.
|
||||||
|
*/
|
||||||
|
int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout);
|
||||||
|
|
||||||
/* Manufacturer-specific probe functions */
|
/* Manufacturer-specific probe functions */
|
||||||
struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode);
|
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);
|
struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode);
|
||||||
|
|
|
@ -89,41 +89,6 @@ static const struct sst_spi_flash_params sst_spi_flash_table[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
|
||||||
sst_wait_ready(struct spi_flash *flash, unsigned long timeout)
|
|
||||||
{
|
|
||||||
struct spi_slave *spi = flash->spi;
|
|
||||||
unsigned long timebase;
|
|
||||||
int ret;
|
|
||||||
u8 byte = CMD_SST_RDSR;
|
|
||||||
|
|
||||||
ret = spi_xfer(spi, sizeof(byte) * 8, &byte, NULL, SPI_XFER_BEGIN);
|
|
||||||
if (ret) {
|
|
||||||
debug("SF: Failed to send command %02x: %d\n", byte, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
timebase = get_timer(0);
|
|
||||||
do {
|
|
||||||
ret = spi_xfer(spi, sizeof(byte) * 8, NULL, &byte, 0);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ((byte & SST_SR_WIP) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
} while (get_timer(timebase) < timeout);
|
|
||||||
|
|
||||||
spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
|
|
||||||
|
|
||||||
if (!ret && (byte & SST_SR_WIP) != 0)
|
|
||||||
ret = -1;
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
debug("SF: sst wait for ready timed out\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sst_enable_writing(struct spi_flash *flash)
|
sst_enable_writing(struct spi_flash *flash)
|
||||||
{
|
{
|
||||||
|
@ -177,7 +142,7 @@ sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return sst_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
|
return spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -224,7 +189,7 @@ sst_write(struct spi_flash *flash, u32 offset, size_t len, const void *buf)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sst_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
|
ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -298,7 +263,7 @@ sst_erase(struct spi_flash *flash, u32 offset, size_t len)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sst_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
|
ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,8 +55,6 @@
|
||||||
#define STM_ID_M25P80 0x14
|
#define STM_ID_M25P80 0x14
|
||||||
#define STM_ID_M25P128 0x18
|
#define STM_ID_M25P128 0x18
|
||||||
|
|
||||||
#define STMICRO_SR_WIP (1 << 0) /* Write-in-Progress */
|
|
||||||
|
|
||||||
struct stmicro_spi_flash_params {
|
struct stmicro_spi_flash_params {
|
||||||
u8 idcode1;
|
u8 idcode1;
|
||||||
u16 page_size;
|
u16 page_size;
|
||||||
|
@ -136,40 +134,6 @@ static const struct stmicro_spi_flash_params stmicro_spi_flash_table[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int stmicro_wait_ready(struct spi_flash *flash, unsigned long timeout)
|
|
||||||
{
|
|
||||||
struct spi_slave *spi = flash->spi;
|
|
||||||
unsigned long timebase;
|
|
||||||
int ret;
|
|
||||||
u8 cmd = CMD_M25PXX_RDSR;
|
|
||||||
u8 status;
|
|
||||||
|
|
||||||
ret = spi_xfer(spi, 8, &cmd, NULL, SPI_XFER_BEGIN);
|
|
||||||
if (ret) {
|
|
||||||
debug("SF: Failed to send command %02x: %d\n", cmd, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
timebase = get_timer(0);
|
|
||||||
do {
|
|
||||||
ret = spi_xfer(spi, 8, NULL, &status, 0);
|
|
||||||
if (ret)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if ((status & STMICRO_SR_WIP) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
} while (get_timer(timebase) < timeout);
|
|
||||||
|
|
||||||
spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
|
|
||||||
|
|
||||||
if ((status & STMICRO_SR_WIP) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Timed out */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stmicro_read_fast(struct spi_flash *flash,
|
static int stmicro_read_fast(struct spi_flash *flash,
|
||||||
u32 offset, size_t len, void *buf)
|
u32 offset, size_t len, void *buf)
|
||||||
{
|
{
|
||||||
|
@ -238,11 +202,9 @@ static int stmicro_write(struct spi_flash *flash,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = stmicro_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
|
ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
|
||||||
if (ret < 0) {
|
if (ret)
|
||||||
debug("SF: STMicro page programming timed out\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
page_addr++;
|
page_addr++;
|
||||||
byte_addr = 0;
|
byte_addr = 0;
|
||||||
|
@ -304,12 +266,10 @@ int stmicro_erase(struct spi_flash *flash, u32 offset, size_t len)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = stmicro_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
|
ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
|
||||||
if (ret < 0) {
|
if (ret)
|
||||||
debug("SF: STMicro page erase timed out\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
debug("SF: STMicro: Successfully erased %u bytes @ 0x%x\n",
|
debug("SF: STMicro: Successfully erased %u bytes @ 0x%x\n",
|
||||||
len * sector_size, offset);
|
len * sector_size, offset);
|
||||||
|
|
|
@ -24,8 +24,6 @@
|
||||||
#define CMD_W25_DP 0xb9 /* Deep Power-down */
|
#define CMD_W25_DP 0xb9 /* Deep Power-down */
|
||||||
#define CMD_W25_RES 0xab /* Release from DP, and Read Signature */
|
#define CMD_W25_RES 0xab /* Release from DP, and Read Signature */
|
||||||
|
|
||||||
#define WINBOND_SR_WIP (1 << 0) /* Write-in-Progress */
|
|
||||||
|
|
||||||
struct winbond_spi_flash_params {
|
struct winbond_spi_flash_params {
|
||||||
uint16_t id;
|
uint16_t id;
|
||||||
/* Log2 of page size in power-of-two mode */
|
/* Log2 of page size in power-of-two mode */
|
||||||
|
@ -107,43 +105,6 @@ static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int winbond_wait_ready(struct spi_flash *flash, unsigned long timeout)
|
|
||||||
{
|
|
||||||
struct spi_slave *spi = flash->spi;
|
|
||||||
unsigned long timebase;
|
|
||||||
int ret;
|
|
||||||
u8 status;
|
|
||||||
u8 cmd[4] = { CMD_W25_RDSR, 0xff, 0xff, 0xff };
|
|
||||||
|
|
||||||
ret = spi_xfer(spi, 32, &cmd[0], NULL, SPI_XFER_BEGIN);
|
|
||||||
if (ret) {
|
|
||||||
debug("SF: Failed to send command %02x: %d\n", cmd, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
timebase = get_timer(0);
|
|
||||||
do {
|
|
||||||
ret = spi_xfer(spi, 8, NULL, &status, 0);
|
|
||||||
if (ret) {
|
|
||||||
debug("SF: Failed to get status for cmd %02x: %d\n", cmd, ret);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((status & WINBOND_SR_WIP) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
} while (get_timer(timebase) < timeout);
|
|
||||||
|
|
||||||
spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
|
|
||||||
|
|
||||||
if ((status & WINBOND_SR_WIP) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
debug("SF: Timed out on command %02x: %d\n", cmd, ret);
|
|
||||||
/* Timed out */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Assemble the address part of a command for Winbond devices in
|
* Assemble the address part of a command for Winbond devices in
|
||||||
* non-power-of-two page size mode.
|
* non-power-of-two page size mode.
|
||||||
|
@ -230,11 +191,9 @@ static int winbond_write(struct spi_flash *flash,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = winbond_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
|
ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
|
||||||
if (ret < 0) {
|
if (ret)
|
||||||
debug("SF: Winbond page programming timed out\n");
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
page_addr++;
|
page_addr++;
|
||||||
byte_addr = 0;
|
byte_addr = 0;
|
||||||
|
@ -298,12 +257,10 @@ int winbond_erase(struct spi_flash *flash, u32 offset, size_t len)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = winbond_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
|
ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
|
||||||
if (ret < 0) {
|
if (ret)
|
||||||
debug("SF: Winbond sector erase timed out\n");
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
debug("SF: Winbond: Successfully erased %u bytes @ 0x%x\n",
|
debug("SF: Winbond: Successfully erased %u bytes @ 0x%x\n",
|
||||||
len * sector_size, offset);
|
len * sector_size, offset);
|
||||||
|
|
Loading…
Reference in New Issue