Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2005, Intec Automation Inc.
0004  * Copyright (C) 2014, Freescale Semiconductor, Inc.
0005  */
0006 
0007 #include <linux/mtd/spi-nor.h>
0008 
0009 #include "core.h"
0010 
0011 /* flash_info mfr_flag. Used to clear sticky prorietary SR bits. */
0012 #define USE_CLSR    BIT(0)
0013 
0014 #define SPINOR_OP_CLSR      0x30    /* Clear status register 1 */
0015 #define SPINOR_OP_RD_ANY_REG            0x65    /* Read any register */
0016 #define SPINOR_OP_WR_ANY_REG            0x71    /* Write any register */
0017 #define SPINOR_REG_CYPRESS_CFR1V        0x00800002
0018 #define SPINOR_REG_CYPRESS_CFR1V_QUAD_EN    BIT(1)  /* Quad Enable */
0019 #define SPINOR_REG_CYPRESS_CFR2V        0x00800003
0020 #define SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24   0xb
0021 #define SPINOR_REG_CYPRESS_CFR3V        0x00800004
0022 #define SPINOR_REG_CYPRESS_CFR3V_PGSZ       BIT(4) /* Page size. */
0023 #define SPINOR_REG_CYPRESS_CFR5V        0x00800006
0024 #define SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN 0x3
0025 #define SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS 0
0026 #define SPINOR_OP_CYPRESS_RD_FAST       0xee
0027 
0028 /* Cypress SPI NOR flash operations. */
0029 #define CYPRESS_NOR_WR_ANY_REG_OP(naddr, addr, ndata, buf)      \
0030     SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 0),     \
0031            SPI_MEM_OP_ADDR(naddr, addr, 0),         \
0032            SPI_MEM_OP_NO_DUMMY,                 \
0033            SPI_MEM_OP_DATA_OUT(ndata, buf, 0))
0034 
0035 #define CYPRESS_NOR_RD_ANY_REG_OP(naddr, addr, buf)         \
0036     SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 0),     \
0037            SPI_MEM_OP_ADDR(naddr, addr, 0),         \
0038            SPI_MEM_OP_NO_DUMMY,                 \
0039            SPI_MEM_OP_DATA_IN(1, buf, 0))
0040 
0041 #define SPANSION_CLSR_OP                        \
0042     SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLSR, 0),           \
0043            SPI_MEM_OP_NO_ADDR,                  \
0044            SPI_MEM_OP_NO_DUMMY,                 \
0045            SPI_MEM_OP_NO_DATA)
0046 
0047 static int cypress_nor_octal_dtr_en(struct spi_nor *nor)
0048 {
0049     struct spi_mem_op op;
0050     u8 *buf = nor->bouncebuf;
0051     int ret;
0052 
0053     /* Use 24 dummy cycles for memory array reads. */
0054     *buf = SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24;
0055     op = (struct spi_mem_op)
0056         CYPRESS_NOR_WR_ANY_REG_OP(3, SPINOR_REG_CYPRESS_CFR2V, 1, buf);
0057 
0058     ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
0059     if (ret)
0060         return ret;
0061 
0062     nor->read_dummy = 24;
0063 
0064     /* Set the octal and DTR enable bits. */
0065     buf[0] = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN;
0066     op = (struct spi_mem_op)
0067         CYPRESS_NOR_WR_ANY_REG_OP(3, SPINOR_REG_CYPRESS_CFR5V, 1, buf);
0068 
0069     ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
0070     if (ret)
0071         return ret;
0072 
0073     /* Read flash ID to make sure the switch was successful. */
0074     ret = spi_nor_read_id(nor, 4, 3, buf, SNOR_PROTO_8_8_8_DTR);
0075     if (ret) {
0076         dev_dbg(nor->dev, "error %d reading JEDEC ID after enabling 8D-8D-8D mode\n", ret);
0077         return ret;
0078     }
0079 
0080     if (memcmp(buf, nor->info->id, nor->info->id_len))
0081         return -EINVAL;
0082 
0083     return 0;
0084 }
0085 
0086 static int cypress_nor_octal_dtr_dis(struct spi_nor *nor)
0087 {
0088     struct spi_mem_op op;
0089     u8 *buf = nor->bouncebuf;
0090     int ret;
0091 
0092     /*
0093      * The register is 1-byte wide, but 1-byte transactions are not allowed
0094      * in 8D-8D-8D mode. Since there is no register at the next location,
0095      * just initialize the value to 0 and let the transaction go on.
0096      */
0097     buf[0] = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS;
0098     buf[1] = 0;
0099     op = (struct spi_mem_op)
0100         CYPRESS_NOR_WR_ANY_REG_OP(4, SPINOR_REG_CYPRESS_CFR5V, 2, buf);
0101     ret = spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR);
0102     if (ret)
0103         return ret;
0104 
0105     /* Read flash ID to make sure the switch was successful. */
0106     ret = spi_nor_read_id(nor, 0, 0, buf, SNOR_PROTO_1_1_1);
0107     if (ret) {
0108         dev_dbg(nor->dev, "error %d reading JEDEC ID after disabling 8D-8D-8D mode\n", ret);
0109         return ret;
0110     }
0111 
0112     if (memcmp(buf, nor->info->id, nor->info->id_len))
0113         return -EINVAL;
0114 
0115     return 0;
0116 }
0117 
0118 /**
0119  * cypress_nor_quad_enable_volatile() - enable Quad I/O mode in volatile
0120  *                                      register.
0121  * @nor:    pointer to a 'struct spi_nor'
0122  *
0123  * It is recommended to update volatile registers in the field application due
0124  * to a risk of the non-volatile registers corruption by power interrupt. This
0125  * function sets Quad Enable bit in CFR1 volatile. If users set the Quad Enable
0126  * bit in the CFR1 non-volatile in advance (typically by a Flash programmer
0127  * before mounting Flash on PCB), the Quad Enable bit in the CFR1 volatile is
0128  * also set during Flash power-up.
0129  *
0130  * Return: 0 on success, -errno otherwise.
0131  */
0132 static int cypress_nor_quad_enable_volatile(struct spi_nor *nor)
0133 {
0134     struct spi_mem_op op;
0135     u8 addr_mode_nbytes = nor->params->addr_mode_nbytes;
0136     u8 cfr1v_written;
0137     int ret;
0138 
0139     op = (struct spi_mem_op)
0140         CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes,
0141                       SPINOR_REG_CYPRESS_CFR1V,
0142                       nor->bouncebuf);
0143 
0144     ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
0145     if (ret)
0146         return ret;
0147 
0148     if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR1V_QUAD_EN)
0149         return 0;
0150 
0151     /* Update the Quad Enable bit. */
0152     nor->bouncebuf[0] |= SPINOR_REG_CYPRESS_CFR1V_QUAD_EN;
0153     op = (struct spi_mem_op)
0154         CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes,
0155                       SPINOR_REG_CYPRESS_CFR1V, 1,
0156                       nor->bouncebuf);
0157     ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
0158     if (ret)
0159         return ret;
0160 
0161     cfr1v_written = nor->bouncebuf[0];
0162 
0163     /* Read back and check it. */
0164     op = (struct spi_mem_op)
0165         CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes,
0166                       SPINOR_REG_CYPRESS_CFR1V,
0167                       nor->bouncebuf);
0168     ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
0169     if (ret)
0170         return ret;
0171 
0172     if (nor->bouncebuf[0] != cfr1v_written) {
0173         dev_err(nor->dev, "CFR1: Read back test failed\n");
0174         return -EIO;
0175     }
0176 
0177     return 0;
0178 }
0179 
0180 /**
0181  * cypress_nor_set_page_size() - Set page size which corresponds to the flash
0182  *                               configuration.
0183  * @nor:    pointer to a 'struct spi_nor'
0184  *
0185  * The BFPT table advertises a 512B or 256B page size depending on part but the
0186  * page size is actually configurable (with the default being 256B). Read from
0187  * CFR3V[4] and set the correct size.
0188  *
0189  * Return: 0 on success, -errno otherwise.
0190  */
0191 static int cypress_nor_set_page_size(struct spi_nor *nor)
0192 {
0193     struct spi_mem_op op =
0194         CYPRESS_NOR_RD_ANY_REG_OP(3, SPINOR_REG_CYPRESS_CFR3V,
0195                       nor->bouncebuf);
0196     int ret;
0197 
0198     ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
0199     if (ret)
0200         return ret;
0201 
0202     if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR3V_PGSZ)
0203         nor->params->page_size = 512;
0204     else
0205         nor->params->page_size = 256;
0206 
0207     return 0;
0208 }
0209 
0210 static int
0211 s25hx_t_post_bfpt_fixup(struct spi_nor *nor,
0212             const struct sfdp_parameter_header *bfpt_header,
0213             const struct sfdp_bfpt *bfpt)
0214 {
0215     /* Replace Quad Enable with volatile version */
0216     nor->params->quad_enable = cypress_nor_quad_enable_volatile;
0217 
0218     return cypress_nor_set_page_size(nor);
0219 }
0220 
0221 static void s25hx_t_post_sfdp_fixup(struct spi_nor *nor)
0222 {
0223     struct spi_nor_erase_type *erase_type =
0224                     nor->params->erase_map.erase_type;
0225     unsigned int i;
0226 
0227     /*
0228      * In some parts, 3byte erase opcodes are advertised by 4BAIT.
0229      * Convert them to 4byte erase opcodes.
0230      */
0231     for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) {
0232         switch (erase_type[i].opcode) {
0233         case SPINOR_OP_SE:
0234             erase_type[i].opcode = SPINOR_OP_SE_4B;
0235             break;
0236         case SPINOR_OP_BE_4K:
0237             erase_type[i].opcode = SPINOR_OP_BE_4K_4B;
0238             break;
0239         default:
0240             break;
0241         }
0242     }
0243 }
0244 
0245 static void s25hx_t_late_init(struct spi_nor *nor)
0246 {
0247     struct spi_nor_flash_parameter *params = nor->params;
0248 
0249     /* Fast Read 4B requires mode cycles */
0250     params->reads[SNOR_CMD_READ_FAST].num_mode_clocks = 8;
0251 
0252     /* The writesize should be ECC data unit size */
0253     params->writesize = 16;
0254 }
0255 
0256 static struct spi_nor_fixups s25hx_t_fixups = {
0257     .post_bfpt = s25hx_t_post_bfpt_fixup,
0258     .post_sfdp = s25hx_t_post_sfdp_fixup,
0259     .late_init = s25hx_t_late_init,
0260 };
0261 
0262 /**
0263  * cypress_nor_octal_dtr_enable() - Enable octal DTR on Cypress flashes.
0264  * @nor:        pointer to a 'struct spi_nor'
0265  * @enable:              whether to enable or disable Octal DTR
0266  *
0267  * This also sets the memory access latency cycles to 24 to allow the flash to
0268  * run at up to 200MHz.
0269  *
0270  * Return: 0 on success, -errno otherwise.
0271  */
0272 static int cypress_nor_octal_dtr_enable(struct spi_nor *nor, bool enable)
0273 {
0274     return enable ? cypress_nor_octal_dtr_en(nor) :
0275             cypress_nor_octal_dtr_dis(nor);
0276 }
0277 
0278 static void s28hs512t_default_init(struct spi_nor *nor)
0279 {
0280     nor->params->octal_dtr_enable = cypress_nor_octal_dtr_enable;
0281     nor->params->writesize = 16;
0282 }
0283 
0284 static void s28hs512t_post_sfdp_fixup(struct spi_nor *nor)
0285 {
0286     /*
0287      * On older versions of the flash the xSPI Profile 1.0 table has the
0288      * 8D-8D-8D Fast Read opcode as 0x00. But it actually should be 0xEE.
0289      */
0290     if (nor->params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode == 0)
0291         nor->params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode =
0292             SPINOR_OP_CYPRESS_RD_FAST;
0293 
0294     /* This flash is also missing the 4-byte Page Program opcode bit. */
0295     spi_nor_set_pp_settings(&nor->params->page_programs[SNOR_CMD_PP],
0296                 SPINOR_OP_PP_4B, SNOR_PROTO_1_1_1);
0297     /*
0298      * Since xSPI Page Program opcode is backward compatible with
0299      * Legacy SPI, use Legacy SPI opcode there as well.
0300      */
0301     spi_nor_set_pp_settings(&nor->params->page_programs[SNOR_CMD_PP_8_8_8_DTR],
0302                 SPINOR_OP_PP_4B, SNOR_PROTO_8_8_8_DTR);
0303 
0304     /*
0305      * The xSPI Profile 1.0 table advertises the number of additional
0306      * address bytes needed for Read Status Register command as 0 but the
0307      * actual value for that is 4.
0308      */
0309     nor->params->rdsr_addr_nbytes = 4;
0310 }
0311 
0312 static int s28hs512t_post_bfpt_fixup(struct spi_nor *nor,
0313                      const struct sfdp_parameter_header *bfpt_header,
0314                      const struct sfdp_bfpt *bfpt)
0315 {
0316     return cypress_nor_set_page_size(nor);
0317 }
0318 
0319 static const struct spi_nor_fixups s28hs512t_fixups = {
0320     .default_init = s28hs512t_default_init,
0321     .post_sfdp = s28hs512t_post_sfdp_fixup,
0322     .post_bfpt = s28hs512t_post_bfpt_fixup,
0323 };
0324 
0325 static int
0326 s25fs_s_nor_post_bfpt_fixups(struct spi_nor *nor,
0327                  const struct sfdp_parameter_header *bfpt_header,
0328                  const struct sfdp_bfpt *bfpt)
0329 {
0330     /*
0331      * The S25FS-S chip family reports 512-byte pages in BFPT but
0332      * in reality the write buffer still wraps at the safe default
0333      * of 256 bytes.  Overwrite the page size advertised by BFPT
0334      * to get the writes working.
0335      */
0336     nor->params->page_size = 256;
0337 
0338     return 0;
0339 }
0340 
0341 static const struct spi_nor_fixups s25fs_s_nor_fixups = {
0342     .post_bfpt = s25fs_s_nor_post_bfpt_fixups,
0343 };
0344 
0345 static const struct flash_info spansion_nor_parts[] = {
0346     /* Spansion/Cypress -- single (large) sector size only, at least
0347      * for the chips listed here (without boot sectors).
0348      */
0349     { "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64)
0350         NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
0351     { "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128)
0352         NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
0353     { "s25fl128s0", INFO6(0x012018, 0x4d0080, 256 * 1024, 64)
0354         NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
0355         MFR_FLAGS(USE_CLSR)
0356     },
0357     { "s25fl128s1", INFO6(0x012018, 0x4d0180, 64 * 1024, 256)
0358         NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
0359         MFR_FLAGS(USE_CLSR)
0360     },
0361     { "s25fl256s0", INFO6(0x010219, 0x4d0080, 256 * 1024, 128)
0362         NO_SFDP_FLAGS(SPI_NOR_SKIP_SFDP | SPI_NOR_DUAL_READ |
0363                   SPI_NOR_QUAD_READ)
0364         MFR_FLAGS(USE_CLSR)
0365     },
0366     { "s25fl256s1", INFO6(0x010219, 0x4d0180, 64 * 1024, 512)
0367         NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
0368         MFR_FLAGS(USE_CLSR)
0369     },
0370     { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256)
0371         FLAGS(SPI_NOR_HAS_LOCK)
0372         NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
0373         MFR_FLAGS(USE_CLSR)
0374     },
0375     { "s25fs128s1", INFO6(0x012018, 0x4d0181, 64 * 1024, 256)
0376         NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
0377         MFR_FLAGS(USE_CLSR)
0378         .fixups = &s25fs_s_nor_fixups, },
0379     { "s25fs256s0", INFO6(0x010219, 0x4d0081, 256 * 1024, 128)
0380         NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
0381         MFR_FLAGS(USE_CLSR)
0382     },
0383     { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512)
0384         NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
0385         MFR_FLAGS(USE_CLSR)
0386     },
0387     { "s25fs512s",  INFO6(0x010220, 0x4d0081, 256 * 1024, 256)
0388         NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
0389         MFR_FLAGS(USE_CLSR)
0390         .fixups = &s25fs_s_nor_fixups, },
0391     { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64) },
0392     { "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256) },
0393     { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64)
0394         NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
0395         MFR_FLAGS(USE_CLSR)
0396     },
0397     { "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256)
0398         NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
0399         MFR_FLAGS(USE_CLSR)
0400     },
0401     { "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8) },
0402     { "s25sl008a",  INFO(0x010213,      0,  64 * 1024,  16) },
0403     { "s25sl016a",  INFO(0x010214,      0,  64 * 1024,  32) },
0404     { "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64) },
0405     { "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128) },
0406     { "s25fl004k",  INFO(0xef4013,      0,  64 * 1024,   8)
0407         NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
0408                   SPI_NOR_QUAD_READ) },
0409     { "s25fl008k",  INFO(0xef4014,      0,  64 * 1024,  16)
0410         NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
0411                   SPI_NOR_QUAD_READ) },
0412     { "s25fl016k",  INFO(0xef4015,      0,  64 * 1024,  32)
0413         NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
0414                   SPI_NOR_QUAD_READ) },
0415     { "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128)
0416         NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
0417                   SPI_NOR_QUAD_READ) },
0418     { "s25fl116k",  INFO(0x014015,      0,  64 * 1024,  32)
0419         NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
0420                   SPI_NOR_QUAD_READ) },
0421     { "s25fl132k",  INFO(0x014016,      0,  64 * 1024,  64)
0422         NO_SFDP_FLAGS(SECT_4K) },
0423     { "s25fl164k",  INFO(0x014017,      0,  64 * 1024, 128)
0424         NO_SFDP_FLAGS(SECT_4K) },
0425     { "s25fl204k",  INFO(0x014013,      0,  64 * 1024,   8)
0426         NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
0427     { "s25fl208k",  INFO(0x014014,      0,  64 * 1024,  16)
0428         NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
0429     { "s25fl064l",  INFO(0x016017,      0,  64 * 1024, 128)
0430         NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
0431         FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
0432     { "s25fl128l",  INFO(0x016018,      0,  64 * 1024, 256)
0433         NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
0434         FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
0435     { "s25fl256l",  INFO(0x016019,      0,  64 * 1024, 512)
0436         NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
0437         FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
0438     { "s25hl512t",  INFO6(0x342a1a, 0x0f0390, 256 * 1024, 256)
0439         PARSE_SFDP
0440         MFR_FLAGS(USE_CLSR)
0441         .fixups = &s25hx_t_fixups },
0442     { "s25hl01gt",  INFO6(0x342a1b, 0x0f0390, 256 * 1024, 512)
0443         PARSE_SFDP
0444         MFR_FLAGS(USE_CLSR)
0445         .fixups = &s25hx_t_fixups },
0446     { "s25hs512t",  INFO6(0x342b1a, 0x0f0390, 256 * 1024, 256)
0447         PARSE_SFDP
0448         MFR_FLAGS(USE_CLSR)
0449         .fixups = &s25hx_t_fixups },
0450     { "s25hs01gt",  INFO6(0x342b1b, 0x0f0390, 256 * 1024, 512)
0451         PARSE_SFDP
0452         MFR_FLAGS(USE_CLSR)
0453         .fixups = &s25hx_t_fixups },
0454     { "cy15x104q",  INFO6(0x042cc2, 0x7f7f7f, 512 * 1024, 1)
0455         FLAGS(SPI_NOR_NO_ERASE) },
0456     { "s28hs512t",   INFO(0x345b1a,      0, 256 * 1024, 256)
0457         NO_SFDP_FLAGS(SECT_4K | SPI_NOR_OCTAL_DTR_READ |
0458                   SPI_NOR_OCTAL_DTR_PP)
0459         .fixups = &s28hs512t_fixups,
0460     },
0461 };
0462 
0463 /**
0464  * spansion_nor_clear_sr() - Clear the Status Register.
0465  * @nor:    pointer to 'struct spi_nor'.
0466  */
0467 static void spansion_nor_clear_sr(struct spi_nor *nor)
0468 {
0469     int ret;
0470 
0471     if (nor->spimem) {
0472         struct spi_mem_op op = SPANSION_CLSR_OP;
0473 
0474         spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
0475 
0476         ret = spi_mem_exec_op(nor->spimem, &op);
0477     } else {
0478         ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLSR,
0479                                NULL, 0);
0480     }
0481 
0482     if (ret)
0483         dev_dbg(nor->dev, "error %d clearing SR\n", ret);
0484 }
0485 
0486 /**
0487  * spansion_nor_sr_ready_and_clear() - Query the Status Register to see if the
0488  * flash is ready for new commands and clear it if there are any errors.
0489  * @nor:    pointer to 'struct spi_nor'.
0490  *
0491  * Return: 1 if ready, 0 if not ready, -errno on errors.
0492  */
0493 static int spansion_nor_sr_ready_and_clear(struct spi_nor *nor)
0494 {
0495     int ret;
0496 
0497     ret = spi_nor_read_sr(nor, nor->bouncebuf);
0498     if (ret)
0499         return ret;
0500 
0501     if (nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
0502         if (nor->bouncebuf[0] & SR_E_ERR)
0503             dev_err(nor->dev, "Erase Error occurred\n");
0504         else
0505             dev_err(nor->dev, "Programming Error occurred\n");
0506 
0507         spansion_nor_clear_sr(nor);
0508 
0509         /*
0510          * WEL bit remains set to one when an erase or page program
0511          * error occurs. Issue a Write Disable command to protect
0512          * against inadvertent writes that can possibly corrupt the
0513          * contents of the memory.
0514          */
0515         ret = spi_nor_write_disable(nor);
0516         if (ret)
0517             return ret;
0518 
0519         return -EIO;
0520     }
0521 
0522     return !(nor->bouncebuf[0] & SR_WIP);
0523 }
0524 
0525 static void spansion_nor_late_init(struct spi_nor *nor)
0526 {
0527     if (nor->params->size > SZ_16M) {
0528         nor->flags |= SNOR_F_4B_OPCODES;
0529         /* No small sector erase for 4-byte command set */
0530         nor->erase_opcode = SPINOR_OP_SE;
0531         nor->mtd.erasesize = nor->info->sector_size;
0532     }
0533 
0534     if (nor->info->mfr_flags & USE_CLSR)
0535         nor->params->ready = spansion_nor_sr_ready_and_clear;
0536 }
0537 
0538 static const struct spi_nor_fixups spansion_nor_fixups = {
0539     .late_init = spansion_nor_late_init,
0540 };
0541 
0542 const struct spi_nor_manufacturer spi_nor_spansion = {
0543     .name = "spansion",
0544     .parts = spansion_nor_parts,
0545     .nparts = ARRAY_SIZE(spansion_nor_parts),
0546     .fixups = &spansion_nor_fixups,
0547 };