diff options
author | Bean Huo (beanhuo) <beanhuo@micron.com> | 2017-12-04 13:34:47 +0100 |
---|---|---|
committer | Cyrille Pitchen <cyrille.pitchen@wedev4u.fr> | 2017-12-13 00:36:00 +0100 |
commit | 20ccb993f29bd6ad17699dd0b349db086e3ca719 (patch) | |
tree | 973615108d678dc46e483299d4ed856dc925c145 /drivers/mtd/spi-nor | |
parent | dt-bindings: mtd: fsl-quadspi: Pass the qspi clock names (diff) | |
download | linux-20ccb993f29bd6ad17699dd0b349db086e3ca719.tar.xz linux-20ccb993f29bd6ad17699dd0b349db086e3ca719.zip |
mtd: spi-nor: check FSR error bits for Micron memories
For Micron spi nor device, when erase/program operation
fails, especially the failure results from intending to
modify protected space, spi-nor upper layers still get
the return which shows the operation succeeds. This is
because current spi_nor_fsr_ready() only uses FSR bit.7
(flag status register) to check device whether ready.
This patch fixes this issue by checking relevant error
bits in FSR.
The FSR is a powerful tool to investigate the status of
device, checking information regarding what the memory is
actually doing and detecting possible error conditions.
Signed-off-by: beanhuo <beanhuo@micron.com>
Signed-off-by: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>
Diffstat (limited to 'drivers/mtd/spi-nor')
-rw-r--r-- | drivers/mtd/spi-nor/spi-nor.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 7139ad6ada4e..07d040ff574b 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -330,8 +330,22 @@ static inline int spi_nor_fsr_ready(struct spi_nor *nor) int fsr = read_fsr(nor); if (fsr < 0) return fsr; - else - return fsr & FSR_READY; + + if (fsr & (FSR_E_ERR | FSR_P_ERR)) { + if (fsr & FSR_E_ERR) + dev_err(nor->dev, "Erase operation failed.\n"); + else + dev_err(nor->dev, "Program operation failed.\n"); + + if (fsr & FSR_PT_ERR) + dev_err(nor->dev, + "Attempted to modify a protected sector.\n"); + + nor->write_reg(nor, SPINOR_OP_CLFSR, NULL, 0); + return -EIO; + } + + return fsr & FSR_READY; } static int spi_nor_ready(struct spi_nor *nor) |