* [PATCH v2 1/3] mtd: spi-nor: core: Add the ->ready() hook
@ 2021-04-16 7:31 yaliang.wang
2021-04-16 7:31 ` [PATCH v2 2/3] mtd: spi-nor: core: reuse spi_nor_clear_sr and spi_nor_read_sr functions yaliang.wang
2021-04-16 7:31 ` [PATCH v2 3/3] mtd: spi-nor: core: move Spansion checking ready codes into spansion.c yaliang.wang
0 siblings, 2 replies; 3+ messages in thread
From: yaliang.wang @ 2021-04-16 7:31 UTC (permalink / raw)
To: tudor.ambarus, miquel.raynal, richard, vigneshr, nicolas.ferre,
alexandre.belloni, ludovic.desroches
Cc: linux-mtd, Takahiro Kuwano, Pratyush Yadav, Yaliang Wang
From: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
This hook can be used for SPI NOR flashes that do not support default
status read method.
Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Signed-off-by: Yaliang Wang <Yaliang.Wang@windriver.com>
---
Changes in v2:
- Totally reuse the patch Takahiro made [1], this patch is introduced
as the base of the following patches.
[1]http://lists.infradead.org/pipermail/linux-mtd/2021-March/085741.html
drivers/mtd/spi-nor/core.c | 8 +++++---
drivers/mtd/spi-nor/core.h | 2 ++
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 0522304f52fa..5de72322ae32 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -785,12 +785,13 @@ static int spi_nor_fsr_ready(struct spi_nor *nor)
}
/**
- * spi_nor_ready() - Query the flash to see if it is ready for new commands.
+ * spi_nor_default_ready() - Query the flash to see if it is ready for new
+ * commands.
* @nor: pointer to 'struct spi_nor'.
*
* Return: 1 if ready, 0 if not ready, -errno on errors.
*/
-static int spi_nor_ready(struct spi_nor *nor)
+static int spi_nor_default_ready(struct spi_nor *nor)
{
int sr, fsr;
@@ -826,7 +827,7 @@ static int spi_nor_wait_till_ready_with_timeout(struct spi_nor *nor,
if (time_after_eq(jiffies, deadline))
timeout = 1;
- ret = spi_nor_ready(nor);
+ ret = nor->params->ready(nor);
if (ret < 0)
return ret;
if (ret)
@@ -2920,6 +2921,7 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
params->quad_enable = spi_nor_sr2_bit1_quad_enable;
params->set_4byte_addr_mode = spansion_set_4byte_addr_mode;
params->setup = spi_nor_default_setup;
+ params->ready = spi_nor_default_ready;
/* Default to 16-bit Write Status (01h) Command */
nor->flags |= SNOR_F_HAS_16BIT_SR;
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 4a3f7f150b5d..cf265044b543 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -218,6 +218,7 @@ struct spi_nor_locking_ops {
* flashes that have peculiarities to the SPI NOR standard
* e.g. different opcodes, specific address calculation,
* page size, etc.
+ * @ready: checks if the SPI NOR flash is ready.
* @locking_ops: SPI NOR locking methods.
*/
struct spi_nor_flash_parameter {
@@ -238,6 +239,7 @@ struct spi_nor_flash_parameter {
int (*set_4byte_addr_mode)(struct spi_nor *nor, bool enable);
u32 (*convert_addr)(struct spi_nor *nor, u32 addr);
int (*setup)(struct spi_nor *nor, const struct spi_nor_hwcaps *hwcaps);
+ int (*ready)(struct spi_nor *nor);
const struct spi_nor_locking_ops *locking_ops;
};
--
2.25.1
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v2 2/3] mtd: spi-nor: core: reuse spi_nor_clear_sr and spi_nor_read_sr functions
2021-04-16 7:31 [PATCH v2 1/3] mtd: spi-nor: core: Add the ->ready() hook yaliang.wang
@ 2021-04-16 7:31 ` yaliang.wang
2021-04-16 7:31 ` [PATCH v2 3/3] mtd: spi-nor: core: move Spansion checking ready codes into spansion.c yaliang.wang
1 sibling, 0 replies; 3+ messages in thread
From: yaliang.wang @ 2021-04-16 7:31 UTC (permalink / raw)
To: tudor.ambarus, miquel.raynal, richard, vigneshr, nicolas.ferre,
alexandre.belloni, ludovic.desroches
Cc: linux-mtd, Yaliang Wang
From: Yaliang Wang <Yaliang.Wang@windriver.com>
spi_nor_clear_fsr() and spi_nor_read_fsr() two functions are almost the
same with the functions spi_nor_clear_sr() and spi_nor_read_sr(), with
little change, the last two functions' codes can be reused, and can be
easily expanded to other manufacturers or chips.
Also, rename spi_nor_clear_sr() as spi_nor_clear_status()
spi_nor_read_sr() as spi_nor_read_status(), because they no longer just
deal with a specific register now, they deal with one type of registers.
Signed-off-by: Yaliang Wang <Yaliang.Wang@windriver.com>
---
New in v2:
- Also reuse spi_nor_read_sr() codes.
Changes in v2:
- Rename spi_nor_read_sr() to spi_nor_read_status()
- Rename spi_nor_clear_sr() to spi_nor_clear_status()
drivers/mtd/spi-nor/atmel.c | 4 +-
drivers/mtd/spi-nor/core.c | 119 ++++++++----------------------------
drivers/mtd/spi-nor/core.h | 2 +-
3 files changed, 28 insertions(+), 97 deletions(-)
diff --git a/drivers/mtd/spi-nor/atmel.c b/drivers/mtd/spi-nor/atmel.c
index 1fea5cab492c..769299d06f78 100644
--- a/drivers/mtd/spi-nor/atmel.c
+++ b/drivers/mtd/spi-nor/atmel.c
@@ -76,7 +76,7 @@ static int atmel_set_global_protection(struct spi_nor *nor, loff_t ofs,
if (ofs || len != nor->params->size)
return -EINVAL;
- ret = spi_nor_read_sr(nor, nor->bouncebuf);
+ ret = spi_nor_read_status(nor, SPINOR_OP_RDSR, nor->bouncebuf);
if (ret)
return ret;
@@ -133,7 +133,7 @@ static int atmel_is_global_protected(struct spi_nor *nor, loff_t ofs, uint64_t l
if (ofs >= nor->params->size || (ofs + len) > nor->params->size)
return -EINVAL;
- ret = spi_nor_read_sr(nor, nor->bouncebuf);
+ ret = spi_nor_read_status(nor, SPINOR_OP_RDSR, nor->bouncebuf);
if (ret)
return ret;
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 5de72322ae32..0e7fcbc4136f 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -370,23 +370,24 @@ int spi_nor_write_disable(struct spi_nor *nor)
}
/**
- * spi_nor_read_sr() - Read the Status Register.
+ * spi_nor_read_status() - Read the chip status.
* @nor: pointer to 'struct spi_nor'.
- * @sr: pointer to a DMA-able buffer where the value of the
+ * @opcode: the SPI command op code to get the chip status
+ * @st: pointer to a DMA-able buffer where the value of the
* Status Register will be written. Should be at least 2 bytes.
*
* Return: 0 on success, -errno otherwise.
*/
-int spi_nor_read_sr(struct spi_nor *nor, u8 *sr)
+int spi_nor_read_status(struct spi_nor *nor, u8 opcode, u8 *st)
{
int ret;
if (nor->spimem) {
struct spi_mem_op op =
- SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR, 0),
+ SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0),
SPI_MEM_OP_NO_ADDR,
SPI_MEM_OP_NO_DUMMY,
- SPI_MEM_OP_DATA_IN(1, sr, 0));
+ SPI_MEM_OP_DATA_IN(1, st, 0));
if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) {
op.addr.nbytes = nor->params->rdsr_addr_nbytes;
@@ -402,56 +403,12 @@ int spi_nor_read_sr(struct spi_nor *nor, u8 *sr)
ret = spi_mem_exec_op(nor->spimem, &op);
} else {
- ret = spi_nor_controller_ops_read_reg(nor, SPINOR_OP_RDSR, sr,
+ ret = spi_nor_controller_ops_read_reg(nor, opcode, st,
1);
}
if (ret)
- dev_dbg(nor->dev, "error %d reading SR\n", ret);
-
- return ret;
-}
-
-/**
- * spi_nor_read_fsr() - Read the Flag Status Register.
- * @nor: pointer to 'struct spi_nor'
- * @fsr: pointer to a DMA-able buffer where the value of the
- * Flag Status Register will be written. Should be at least 2
- * bytes.
- *
- * Return: 0 on success, -errno otherwise.
- */
-static int spi_nor_read_fsr(struct spi_nor *nor, u8 *fsr)
-{
- int ret;
-
- if (nor->spimem) {
- struct spi_mem_op op =
- SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDFSR, 0),
- SPI_MEM_OP_NO_ADDR,
- SPI_MEM_OP_NO_DUMMY,
- SPI_MEM_OP_DATA_IN(1, fsr, 0));
-
- if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) {
- op.addr.nbytes = nor->params->rdsr_addr_nbytes;
- op.dummy.nbytes = nor->params->rdsr_dummy;
- /*
- * We don't want to read only one byte in DTR mode. So,
- * read 2 and then discard the second byte.
- */
- op.data.nbytes = 2;
- }
-
- spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-
- ret = spi_mem_exec_op(nor->spimem, &op);
- } else {
- ret = spi_nor_controller_ops_read_reg(nor, SPINOR_OP_RDFSR, fsr,
- 1);
- }
-
- if (ret)
- dev_dbg(nor->dev, "error %d reading FSR\n", ret);
+ dev_dbg(nor->dev, "error %d reading status\n", ret);
return ret;
}
@@ -650,16 +607,17 @@ static int spi_nor_xsr_ready(struct spi_nor *nor)
}
/**
- * spi_nor_clear_sr() - Clear the Status Register.
+ * spi_nor_clear_status() - Clear the chip's abnormal status.
* @nor: pointer to 'struct spi_nor'.
+ * @opcode: the SPI command op code to clear the obnormal status.
*/
-static void spi_nor_clear_sr(struct spi_nor *nor)
+static void spi_nor_clear_status(struct spi_nor *nor, u8 opcode)
{
int ret;
if (nor->spimem) {
struct spi_mem_op op =
- SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLSR, 0),
+ SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0),
SPI_MEM_OP_NO_ADDR,
SPI_MEM_OP_NO_DUMMY,
SPI_MEM_OP_NO_DATA);
@@ -668,12 +626,12 @@ static void spi_nor_clear_sr(struct spi_nor *nor)
ret = spi_mem_exec_op(nor->spimem, &op);
} else {
- ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLSR,
+ ret = spi_nor_controller_ops_write_reg(nor, opcode,
NULL, 0);
}
if (ret)
- dev_dbg(nor->dev, "error %d clearing SR\n", ret);
+ dev_dbg(nor->dev, "error %d clearing status\n", ret);
}
/**
@@ -685,7 +643,7 @@ static void spi_nor_clear_sr(struct spi_nor *nor)
*/
static int spi_nor_sr_ready(struct spi_nor *nor)
{
- int ret = spi_nor_read_sr(nor, nor->bouncebuf);
+ int ret = spi_nor_read_status(nor, SPINOR_OP_RDSR, nor->bouncebuf);
if (ret)
return ret;
@@ -697,7 +655,7 @@ static int spi_nor_sr_ready(struct spi_nor *nor)
else
dev_err(nor->dev, "Programming Error occurred\n");
- spi_nor_clear_sr(nor);
+ spi_nor_clear_status(nor, SPINOR_OP_CLSR);
/*
* WEL bit remains set to one when an erase or page program
@@ -715,33 +673,6 @@ static int spi_nor_sr_ready(struct spi_nor *nor)
return !(nor->bouncebuf[0] & SR_WIP);
}
-/**
- * spi_nor_clear_fsr() - Clear the Flag Status Register.
- * @nor: pointer to 'struct spi_nor'.
- */
-static void spi_nor_clear_fsr(struct spi_nor *nor)
-{
- int ret;
-
- if (nor->spimem) {
- struct spi_mem_op op =
- SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLFSR, 0),
- SPI_MEM_OP_NO_ADDR,
- SPI_MEM_OP_NO_DUMMY,
- SPI_MEM_OP_NO_DATA);
-
- spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-
- ret = spi_mem_exec_op(nor->spimem, &op);
- } else {
- ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLFSR,
- NULL, 0);
- }
-
- if (ret)
- dev_dbg(nor->dev, "error %d clearing FSR\n", ret);
-}
-
/**
* spi_nor_fsr_ready() - Query the Flag Status Register to see if the flash is
* ready for new commands.
@@ -751,7 +682,7 @@ static void spi_nor_clear_fsr(struct spi_nor *nor)
*/
static int spi_nor_fsr_ready(struct spi_nor *nor)
{
- int ret = spi_nor_read_fsr(nor, nor->bouncebuf);
+ int ret = spi_nor_read_status(nor, SPINOR_OP_RDFSR, nor->bouncebuf);
if (ret)
return ret;
@@ -766,7 +697,7 @@ static int spi_nor_fsr_ready(struct spi_nor *nor)
dev_err(nor->dev,
"Attempted to modify a protected sector.\n");
- spi_nor_clear_fsr(nor);
+ spi_nor_clear_status(nor, SPINOR_OP_CLFSR);
/*
* WEL bit remains set to one when an erase or page program
@@ -948,7 +879,7 @@ static int spi_nor_write_sr1_and_check(struct spi_nor *nor, u8 sr1)
if (ret)
return ret;
- ret = spi_nor_read_sr(nor, nor->bouncebuf);
+ ret = spi_nor_read_status(nor, SPINOR_OP_RDSR, nor->bouncebuf);
if (ret)
return ret;
@@ -1042,7 +973,7 @@ static int spi_nor_write_16bit_cr_and_check(struct spi_nor *nor, u8 cr)
u8 sr_written;
/* Keep the current value of the Status Register 1. */
- ret = spi_nor_read_sr(nor, sr_cr);
+ ret = spi_nor_read_status(nor, SPINOR_OP_RDSR, sr_cr);
if (ret)
return ret;
@@ -1054,7 +985,7 @@ static int spi_nor_write_16bit_cr_and_check(struct spi_nor *nor, u8 cr)
sr_written = sr_cr[0];
- ret = spi_nor_read_sr(nor, sr_cr);
+ ret = spi_nor_read_status(nor, SPINOR_OP_RDSR, sr_cr);
if (ret)
return ret;
@@ -1878,7 +1809,7 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
bool use_top;
- ret = spi_nor_read_sr(nor, nor->bouncebuf);
+ ret = spi_nor_read_status(nor, SPINOR_OP_RDSR, nor->bouncebuf);
if (ret)
return ret;
@@ -1963,7 +1894,7 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
bool use_top;
- ret = spi_nor_read_sr(nor, nor->bouncebuf);
+ ret = spi_nor_read_status(nor, SPINOR_OP_RDSR, nor->bouncebuf);
if (ret)
return ret;
@@ -2040,7 +1971,7 @@ static int spi_nor_sr_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len)
{
int ret;
- ret = spi_nor_read_sr(nor, nor->bouncebuf);
+ ret = spi_nor_read_status(nor, SPINOR_OP_RDSR, nor->bouncebuf);
if (ret)
return ret;
@@ -2111,7 +2042,7 @@ int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor)
{
int ret;
- ret = spi_nor_read_sr(nor, nor->bouncebuf);
+ ret = spi_nor_read_status(nor, SPINOR_OP_RDSR, nor->bouncebuf);
if (ret)
return ret;
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index cf265044b543..02c12e04811d 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -442,7 +442,7 @@ void spi_nor_unlock_and_unprep(struct spi_nor *nor);
int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor);
int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor);
int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor);
-int spi_nor_read_sr(struct spi_nor *nor, u8 *sr);
+int spi_nor_read_status(struct spi_nor *nor, u8 opcode, u8 *st);
int spi_nor_read_cr(struct spi_nor *nor, u8 *cr);
int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len);
int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 sr1);
--
2.25.1
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v2 3/3] mtd: spi-nor: core: move Spansion checking ready codes into spansion.c
2021-04-16 7:31 [PATCH v2 1/3] mtd: spi-nor: core: Add the ->ready() hook yaliang.wang
2021-04-16 7:31 ` [PATCH v2 2/3] mtd: spi-nor: core: reuse spi_nor_clear_sr and spi_nor_read_sr functions yaliang.wang
@ 2021-04-16 7:31 ` yaliang.wang
1 sibling, 0 replies; 3+ messages in thread
From: yaliang.wang @ 2021-04-16 7:31 UTC (permalink / raw)
To: tudor.ambarus, miquel.raynal, richard, vigneshr, nicolas.ferre,
alexandre.belloni, ludovic.desroches
Cc: linux-mtd, Yaliang Wang
From: Yaliang Wang <Yaliang.Wang@windriver.com>
For historical reasons, Many manufacturer codes exist in the core, to
make the core a more dedicated place, this commit clear the
Spansion-specific checking SR ready codes out of the core.
Signed-off-by: Yaliang Wang <Yaliang.Wang@windriver.com>
---
Changes in v2:
- Rename spansion_sr_ready() to spansion_status_ready()
drivers/mtd/spi-nor/core.c | 26 +-----------------
drivers/mtd/spi-nor/core.h | 2 +-
drivers/mtd/spi-nor/spansion.c | 48 ++++++++++++++++++++++++++++++++++
include/linux/mtd/spi-nor.h | 1 -
4 files changed, 50 insertions(+), 27 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 0e7fcbc4136f..2a0dc8778bc6 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -611,7 +611,7 @@ static int spi_nor_xsr_ready(struct spi_nor *nor)
* @nor: pointer to 'struct spi_nor'.
* @opcode: the SPI command op code to clear the obnormal status.
*/
-static void spi_nor_clear_status(struct spi_nor *nor, u8 opcode)
+void spi_nor_clear_status(struct spi_nor *nor, u8 opcode)
{
int ret;
@@ -648,28 +648,6 @@ static int spi_nor_sr_ready(struct spi_nor *nor)
if (ret)
return ret;
- if (nor->flags & SNOR_F_USE_CLSR &&
- nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
- if (nor->bouncebuf[0] & SR_E_ERR)
- dev_err(nor->dev, "Erase Error occurred\n");
- else
- dev_err(nor->dev, "Programming Error occurred\n");
-
- spi_nor_clear_status(nor, SPINOR_OP_CLSR);
-
- /*
- * WEL bit remains set to one when an erase or page program
- * error occurs. Issue a Write Disable command to protect
- * against inadvertent writes that can possibly corrupt the
- * contents of the memory.
- */
- ret = spi_nor_write_disable(nor);
- if (ret)
- return ret;
-
- return -EIO;
- }
-
return !(nor->bouncebuf[0] & SR_WIP);
}
@@ -3445,8 +3423,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
if (info->flags & NO_CHIP_ERASE)
nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
- if (info->flags & USE_CLSR)
- nor->flags |= SNOR_F_USE_CLSR;
if (info->flags & SPI_NOR_SWP_IS_VOLATILE)
nor->flags |= SNOR_F_SWP_IS_VOLATILE;
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 02c12e04811d..3c047c9ef372 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -16,7 +16,6 @@ enum spi_nor_option_flags {
SNOR_F_HAS_SR_TB = BIT(1),
SNOR_F_NO_OP_CHIP_ERASE = BIT(2),
SNOR_F_READY_XSR_RDY = BIT(3),
- SNOR_F_USE_CLSR = BIT(4),
SNOR_F_BROKEN_RESET = BIT(5),
SNOR_F_4B_OPCODES = BIT(6),
SNOR_F_HAS_4BAIT = BIT(7),
@@ -446,6 +445,7 @@ int spi_nor_read_status(struct spi_nor *nor, u8 opcode, u8 *st);
int spi_nor_read_cr(struct spi_nor *nor, u8 *cr);
int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len);
int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 sr1);
+void spi_nor_clear_status(struct spi_nor *nor, u8 opcode);
int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr);
ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len,
diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
index b0c5521c1e27..824aaa4ff536 100644
--- a/drivers/mtd/spi-nor/spansion.c
+++ b/drivers/mtd/spi-nor/spansion.c
@@ -18,6 +18,48 @@
#define SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN 0x3
#define SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS 0
#define SPINOR_OP_CYPRESS_RD_FAST 0xee
+#define SPINOR_OP_SPANSION_CLSR 0x30
+
+/**
+ * spansion_status_ready() - Spansion specific method for querying the flash to
+ * see if it is ready for new commands.
+ * @nor: pointer to 'struct spi_nor'.
+ *
+ * Return: 1 if ready, 0 if not ready, -errno on errors.
+ */
+static int spansion_status_ready(struct spi_nor *nor)
+{
+ u8 *st = nor->bouncebuf;
+ int ret;
+
+ ret = spi_nor_read_status(nor, st);
+ if (ret)
+ return ret;
+
+ if (nor->info->flags & USE_CLSR &&
+ nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
+ if (nor->bouncebuf[0] & SR_E_ERR)
+ dev_err(nor->dev, "Erase Error occurred\n");
+ else
+ dev_err(nor->dev, "Programming Error occurred\n");
+
+ spi_nor_clear_status(nor, SPINOR_OP_SPANSION_CLSR);
+
+ /*
+ * WEL bit remains set to one when an erase or page program
+ * error occurs. Issue a Write Disable command to protect
+ * against inadvertent writes that can possibly corrupt the
+ * contents of the memory.
+ */
+ ret = spi_nor_write_disable(nor);
+ if (ret)
+ return ret;
+
+ return -EIO;
+ }
+
+ return !(st[0] & SR_WIP);
+}
/**
* spi_nor_cypress_octal_dtr_enable() - Enable octal DTR on Cypress flashes.
@@ -289,8 +331,14 @@ static void spansion_post_sfdp_fixups(struct spi_nor *nor)
nor->mtd.erasesize = nor->info->sector_size;
}
+static void spansion_default_init(struct spi_nor *nor)
+{
+ nor->params->ready = spansion_status_ready;
+}
+
static const struct spi_nor_fixups spansion_fixups = {
.post_sfdp = spansion_post_sfdp_fixups,
+ .default_init = spansion_default_init,
};
const struct spi_nor_manufacturer spi_nor_spansion = {
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index a0d572855444..87e03943ba94 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -101,7 +101,6 @@
/* Used for Spansion flashes only. */
#define SPINOR_OP_BRWR 0x17 /* Bank register write */
-#define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */
/* Used for Micron flashes only. */
#define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */
--
2.25.1
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-04-16 7:51 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-16 7:31 [PATCH v2 1/3] mtd: spi-nor: core: Add the ->ready() hook yaliang.wang
2021-04-16 7:31 ` [PATCH v2 2/3] mtd: spi-nor: core: reuse spi_nor_clear_sr and spi_nor_read_sr functions yaliang.wang
2021-04-16 7:31 ` [PATCH v2 3/3] mtd: spi-nor: core: move Spansion checking ready codes into spansion.c yaliang.wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).