]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
mtd: spi-nor: check FSR error bits for Micron memories
authorBean Huo (beanhuo) <beanhuo@micron.com>
Mon, 4 Dec 2017 12:34:47 +0000 (12:34 +0000)
committerCyrille Pitchen <cyrille.pitchen@wedev4u.fr>
Tue, 12 Dec 2017 23:36:00 +0000 (00:36 +0100)
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>
drivers/mtd/spi-nor/spi-nor.c
include/linux/mtd/spi-nor.h

index 7139ad6ada4e3c0d0fdda0242792b9035b319801..07d040ff574ba3f08545e751501b203c77e3e6fe 100644 (file)
@@ -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)
index d0c66a0975cfa442a97c64d96323206d03aa605d..c0836cca52807aa5ce7e2100e93bc7cdd99ece49 100644 (file)
@@ -61,6 +61,7 @@
 #define SPINOR_OP_RDSFDP       0x5a    /* Read SFDP */
 #define SPINOR_OP_RDCR         0x35    /* Read configuration register */
 #define SPINOR_OP_RDFSR                0x70    /* Read flag status register */
+#define SPINOR_OP_CLFSR                0x50    /* Clear flag status register */
 
 /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
 #define SPINOR_OP_READ_4B      0x13    /* Read data bytes (low frequency) */
 #define EVCR_QUAD_EN_MICRON    BIT(7)  /* Micron Quad I/O */
 
 /* Flag Status Register bits */
-#define FSR_READY              BIT(7)
+#define FSR_READY              BIT(7)  /* Device status, 0 = Busy, 1 = Ready */
+#define FSR_E_ERR              BIT(5)  /* Erase operation status */
+#define FSR_P_ERR              BIT(4)  /* Program operation status */
+#define FSR_PT_ERR             BIT(1)  /* Protection error bit */
 
 /* Configuration Register bits. */
 #define CR_QUAD_EN_SPAN                BIT(1)  /* Spansion Quad I/O */