Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Bean Huo (beanhuo) and committed by
Cyrille Pitchen
20ccb993 6d17969c

+21 -3
+16 -2
drivers/mtd/spi-nor/spi-nor.c
··· 330 330 int fsr = read_fsr(nor); 331 331 if (fsr < 0) 332 332 return fsr; 333 - else 334 - return fsr & FSR_READY; 333 + 334 + if (fsr & (FSR_E_ERR | FSR_P_ERR)) { 335 + if (fsr & FSR_E_ERR) 336 + dev_err(nor->dev, "Erase operation failed.\n"); 337 + else 338 + dev_err(nor->dev, "Program operation failed.\n"); 339 + 340 + if (fsr & FSR_PT_ERR) 341 + dev_err(nor->dev, 342 + "Attempted to modify a protected sector.\n"); 343 + 344 + nor->write_reg(nor, SPINOR_OP_CLFSR, NULL, 0); 345 + return -EIO; 346 + } 347 + 348 + return fsr & FSR_READY; 335 349 } 336 350 337 351 static int spi_nor_ready(struct spi_nor *nor)
+5 -1
include/linux/mtd/spi-nor.h
··· 61 61 #define SPINOR_OP_RDSFDP 0x5a /* Read SFDP */ 62 62 #define SPINOR_OP_RDCR 0x35 /* Read configuration register */ 63 63 #define SPINOR_OP_RDFSR 0x70 /* Read flag status register */ 64 + #define SPINOR_OP_CLFSR 0x50 /* Clear flag status register */ 64 65 65 66 /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */ 66 67 #define SPINOR_OP_READ_4B 0x13 /* Read data bytes (low frequency) */ ··· 131 130 #define EVCR_QUAD_EN_MICRON BIT(7) /* Micron Quad I/O */ 132 131 133 132 /* Flag Status Register bits */ 134 - #define FSR_READY BIT(7) 133 + #define FSR_READY BIT(7) /* Device status, 0 = Busy, 1 = Ready */ 134 + #define FSR_E_ERR BIT(5) /* Erase operation status */ 135 + #define FSR_P_ERR BIT(4) /* Program operation status */ 136 + #define FSR_PT_ERR BIT(1) /* Protection error bit */ 135 137 136 138 /* Configuration Register bits. */ 137 139 #define CR_QUAD_EN_SPAN BIT(1) /* Spansion Quad I/O */