How to Check E_ERR/P_ERR Status Errors in the Linux MTD SPI Driver – KBA220225

Version 2

    Version: **


    Translation - Japanese: Linux MTD SPIドライバでE_ERR/P_ERRステータス エラーを確認する方法– KBA220225- Community Translated (JA)



    How do I add flash program/erase failure status checking to the Linux SPI MTD SPI Driver?



    The Linux master code doesn’t check for program/erase failure of SPI driver. The following steps will add this error-checking feature to the driver


    1. Add E_ERR and P_ERR bit field definitions to SPI driver for FL-S and FS-S (in case of FL-L, use Status Register 2 instead of Status Register 1):

    • Open include/linux/mtd/spi-nor.h
    • Find Status Register bits definitions and replace the following:

              #define SR_TB BIT(5) /* Top/Bottom protect */




              #define SR_E_ERR BIT(5) /* Erase error occurred */

              #define SR_P_ERR BIT(6) /* Programming error occurred */

    • Find Flash opcodes section and add Clear Status Register opcode

              #define SPINOR_OP_CLSR 0x30 /* Clear status register */


    2. Add E_ERR and P_ERR status bit checking to the Status Ready checking subroutine:

    • Open drivers/mtd/spi-nor/spi-nor.c
    • Add clear_sr() subroutine


              * Clear status register

              * Returns negative if error occurred.


              static inline int clear_sr(struct spi_nor *nor)


                   return nor->write_reg(nor, SPINOR_OP_CLSR, NULL, 0);


    • Add a user notification subroutine when erase or program failure happens, for example, user_error_handler()
    • Find static inline int spi_nor_sr_ready(struct spi_nor *nor)
    • Modify the code from:


                     int sr = read_sr(nor);

                             if (sr < 0)

                             return sr;



                             return !(sr & SR_WIP);



                             int sr = read_sr(nor);

                             if (sr < 0)

                                  return sr;

                             else if ((sr & SR_E_ERR) || (sr & SR_P_ERR))






                            return !(sr & SR_WIP);