aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/spi-nor
diff options
context:
space:
mode:
authorBean Huo (beanhuo) <beanhuo@micron.com>2017-12-04 12:34:47 +0000
committerCyrille Pitchen <cyrille.pitchen@wedev4u.fr>2017-12-13 00:36:00 +0100
commit20ccb993f29bd6ad17699dd0b349db086e3ca719 (patch)
tree973615108d678dc46e483299d4ed856dc925c145 /drivers/mtd/spi-nor
parentdt-bindings: mtd: fsl-quadspi: Pass the qspi clock names (diff)
downloadlinux-dev-20ccb993f29bd6ad17699dd0b349db086e3ca719.tar.xz
linux-dev-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.c18
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)