diff options
Diffstat (limited to 'drivers/mtd/spi-nor')
-rw-r--r-- | drivers/mtd/spi-nor/macronix.c | 73 | ||||
-rw-r--r-- | drivers/mtd/spi-nor/micron-st.c | 8 | ||||
-rw-r--r-- | drivers/mtd/spi-nor/spansion.c | 35 | ||||
-rw-r--r-- | drivers/mtd/spi-nor/swp.c | 19 | ||||
-rw-r--r-- | drivers/mtd/spi-nor/sysfs.c | 2 |
5 files changed, 85 insertions, 52 deletions
diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c index 55644a3cd88c..e97f5cbd9aad 100644 --- a/drivers/mtd/spi-nor/macronix.c +++ b/drivers/mtd/spi-nor/macronix.c @@ -58,6 +58,31 @@ macronix_qpp4b_post_sfdp_fixups(struct spi_nor *nor) return 0; } +static int +mx25l3255e_late_init_fixups(struct spi_nor *nor) +{ + struct spi_nor_flash_parameter *params = nor->params; + + /* + * SFDP of MX25L3255E is JESD216, which does not include the Quad + * Enable bit Requirement in BFPT. As a result, during BFPT parsing, + * the quad_enable method is not set to spi_nor_sr1_bit6_quad_enable. + * Therefore, it is necessary to correct this setting by late_init. + */ + params->quad_enable = spi_nor_sr1_bit6_quad_enable; + + /* + * In addition, MX25L3255E also supports 1-4-4 page program in 3-byte + * address mode. However, since the 3-byte address 1-4-4 page program + * is not defined in SFDP, it needs to be configured in late_init. + */ + params->hwcaps.mask |= SNOR_HWCAPS_PP_1_4_4; + spi_nor_set_pp_settings(¶ms->page_programs[SNOR_CMD_PP_1_4_4], + SPINOR_OP_PP_1_4_4, SNOR_PROTO_1_4_4); + + return 0; +} + static const struct spi_nor_fixups mx25l25635_fixups = { .post_bfpt = mx25l25635_post_bfpt_fixups, .post_sfdp = macronix_qpp4b_post_sfdp_fixups, @@ -67,6 +92,10 @@ static const struct spi_nor_fixups macronix_qpp4b_fixups = { .post_sfdp = macronix_qpp4b_post_sfdp_fixups, }; +static const struct spi_nor_fixups mx25l3255e_fixups = { + .late_init = mx25l3255e_late_init_fixups, +}; + static const struct flash_info macronix_nor_parts[] = { { .id = SNOR_ID(0xc2, 0x20, 0x10), @@ -88,10 +117,8 @@ static const struct flash_info macronix_nor_parts[] = { .name = "mx25l8005", .size = SZ_1M, }, { + /* MX25L1606E */ .id = SNOR_ID(0xc2, 0x20, 0x15), - .name = "mx25l1606e", - .size = SZ_2M, - .no_sfdp_flags = SECT_4K, }, { .id = SNOR_ID(0xc2, 0x20, 0x16), .name = "mx25l3205d", @@ -103,29 +130,21 @@ static const struct flash_info macronix_nor_parts[] = { .size = SZ_8M, .no_sfdp_flags = SECT_4K, }, { + /* MX25L12805D */ .id = SNOR_ID(0xc2, 0x20, 0x18), - .name = "mx25l12805d", - .size = SZ_16M, .flags = SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP, - .no_sfdp_flags = SECT_4K, }, { + /* MX25L25635E, MX25L25645G */ .id = SNOR_ID(0xc2, 0x20, 0x19), - .name = "mx25l25635e", - .size = SZ_32M, - .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, .fixups = &mx25l25635_fixups }, { + /* MX66L51235F */ .id = SNOR_ID(0xc2, 0x20, 0x1a), - .name = "mx66l51235f", - .size = SZ_64M, - .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, .fixup_flags = SPI_NOR_4B_OPCODES, .fixups = ¯onix_qpp4b_fixups, }, { + /* MX66L1G45G */ .id = SNOR_ID(0xc2, 0x20, 0x1b), - .name = "mx66l1g45g", - .size = SZ_128M, - .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, .fixups = ¯onix_qpp4b_fixups, }, { /* MX66L2G45G */ @@ -167,29 +186,16 @@ static const struct flash_info macronix_nor_parts[] = { .size = SZ_16M, .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, }, { + /* MX25U51245G */ .id = SNOR_ID(0xc2, 0x25, 0x3a), - .name = "mx25u51245g", - .size = SZ_64M, - .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, - .fixup_flags = SPI_NOR_4B_OPCODES, - .fixups = ¯onix_qpp4b_fixups, - }, { - .id = SNOR_ID(0xc2, 0x25, 0x3a), - .name = "mx66u51235f", - .size = SZ_64M, - .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, - .fixup_flags = SPI_NOR_4B_OPCODES, .fixups = ¯onix_qpp4b_fixups, }, { /* MX66U1G45G */ .id = SNOR_ID(0xc2, 0x25, 0x3b), .fixups = ¯onix_qpp4b_fixups, }, { + /* MX66U2G45G */ .id = SNOR_ID(0xc2, 0x25, 0x3c), - .name = "mx66u2g45g", - .size = SZ_256M, - .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, - .fixup_flags = SPI_NOR_4B_OPCODES, .fixups = ¯onix_qpp4b_fixups, }, { .id = SNOR_ID(0xc2, 0x26, 0x18), @@ -215,15 +221,14 @@ static const struct flash_info macronix_nor_parts[] = { .size = SZ_4M, .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, }, { + /* MX25UW51245G */ .id = SNOR_ID(0xc2, 0x81, 0x3a), - .name = "mx25uw51245g", .n_banks = 4, .flags = SPI_NOR_RWW, }, { + /* MX25L3255E */ .id = SNOR_ID(0xc2, 0x9e, 0x16), - .name = "mx25l3255e", - .size = SZ_4M, - .no_sfdp_flags = SECT_4K, + .fixups = &mx25l3255e_fixups, }, /* * This spares us of adding new flash entries for flashes that can be diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c index e6bab2d00c92..187239ccd549 100644 --- a/drivers/mtd/spi-nor/micron-st.c +++ b/drivers/mtd/spi-nor/micron-st.c @@ -189,7 +189,7 @@ static int mt25qu512a_post_bfpt_fixup(struct spi_nor *nor, return 0; } -static struct spi_nor_fixups mt25qu512a_fixups = { +static const struct spi_nor_fixups mt25qu512a_fixups = { .post_bfpt = mt25qu512a_post_bfpt_fixup, }; @@ -225,15 +225,15 @@ static int st_nor_two_die_late_init(struct spi_nor *nor) return spi_nor_set_4byte_addr_mode(nor, true); } -static struct spi_nor_fixups n25q00_fixups = { +static const struct spi_nor_fixups n25q00_fixups = { .late_init = st_nor_four_die_late_init, }; -static struct spi_nor_fixups mt25q01_fixups = { +static const struct spi_nor_fixups mt25q01_fixups = { .late_init = st_nor_two_die_late_init, }; -static struct spi_nor_fixups mt25q02_fixups = { +static const struct spi_nor_fixups mt25q02_fixups = { .late_init = st_nor_four_die_late_init, }; diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c index bf08dbf5e742..a0296c871634 100644 --- a/drivers/mtd/spi-nor/spansion.c +++ b/drivers/mtd/spi-nor/spansion.c @@ -17,6 +17,7 @@ #define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */ #define SPINOR_OP_CLPEF 0x82 /* Clear program/erase failure flags */ +#define SPINOR_OP_CYPRESS_EX4B 0xB8 /* Exit 4-byte address mode */ #define SPINOR_OP_CYPRESS_DIE_ERASE 0x61 /* Chip (die) erase */ #define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */ #define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */ @@ -58,6 +59,13 @@ SPI_MEM_OP_DUMMY(ndummy, 0), \ SPI_MEM_OP_DATA_IN(1, buf, 0)) +#define CYPRESS_NOR_EN4B_EX4B_OP(enable) \ + SPI_MEM_OP(SPI_MEM_OP_CMD(enable ? SPINOR_OP_EN4B : \ + SPINOR_OP_CYPRESS_EX4B, 0), \ + SPI_MEM_OP_NO_ADDR, \ + SPI_MEM_OP_NO_DUMMY, \ + SPI_MEM_OP_NO_DATA) + #define SPANSION_OP(opcode) \ SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), \ SPI_MEM_OP_NO_ADDR, \ @@ -356,6 +364,20 @@ static int cypress_nor_quad_enable_volatile(struct spi_nor *nor) return 0; } +static int cypress_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable) +{ + int ret; + struct spi_mem_op op = CYPRESS_NOR_EN4B_EX4B_OP(enable); + + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); + + ret = spi_mem_exec_op(nor->spimem, &op); + if (ret) + dev_dbg(nor->dev, "error %d setting 4-byte mode\n", ret); + + return ret; +} + /** * cypress_nor_determine_addr_mode_by_sr1() - Determine current address mode * (3 or 4-byte) by querying status @@ -526,6 +548,9 @@ s25fs256t_post_bfpt_fixup(struct spi_nor *nor, struct spi_mem_op op; int ret; + /* Assign 4-byte address mode method that is not determined in BFPT */ + nor->params->set_4byte_addr_mode = cypress_nor_set_4byte_addr_mode; + ret = cypress_nor_set_addr_mode_nbytes(nor); if (ret) return ret; @@ -578,7 +603,7 @@ static int s25fs256t_late_init(struct spi_nor *nor) return 0; } -static struct spi_nor_fixups s25fs256t_fixups = { +static const struct spi_nor_fixups s25fs256t_fixups = { .post_bfpt = s25fs256t_post_bfpt_fixup, .post_sfdp = s25fs256t_post_sfdp_fixup, .late_init = s25fs256t_late_init, @@ -591,6 +616,9 @@ s25hx_t_post_bfpt_fixup(struct spi_nor *nor, { int ret; + /* Assign 4-byte address mode method that is not determined in BFPT */ + nor->params->set_4byte_addr_mode = cypress_nor_set_4byte_addr_mode; + ret = cypress_nor_set_addr_mode_nbytes(nor); if (ret) return ret; @@ -650,7 +678,7 @@ static int s25hx_t_late_init(struct spi_nor *nor) return 0; } -static struct spi_nor_fixups s25hx_t_fixups = { +static const struct spi_nor_fixups s25hx_t_fixups = { .post_bfpt = s25hx_t_post_bfpt_fixup, .post_sfdp = s25hx_t_post_sfdp_fixup, .late_init = s25hx_t_late_init, @@ -718,6 +746,9 @@ static int s28hx_t_post_bfpt_fixup(struct spi_nor *nor, const struct sfdp_parameter_header *bfpt_header, const struct sfdp_bfpt *bfpt) { + /* Assign 4-byte address mode method that is not determined in BFPT */ + nor->params->set_4byte_addr_mode = cypress_nor_set_4byte_addr_mode; + return cypress_nor_set_addr_mode_nbytes(nor); } diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c index 9c9328478d8a..9b07f83aeac7 100644 --- a/drivers/mtd/spi-nor/swp.c +++ b/drivers/mtd/spi-nor/swp.c @@ -56,7 +56,6 @@ static u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor) static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs, u64 *len) { - struct mtd_info *mtd = &nor->mtd; u64 min_prot_len; u8 mask = spi_nor_get_sr_bp_mask(nor); u8 tb_mask = spi_nor_get_sr_tb_mask(nor); @@ -77,13 +76,13 @@ static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs, min_prot_len = spi_nor_get_min_prot_length_sr(nor); *len = min_prot_len << (bp - 1); - if (*len > mtd->size) - *len = mtd->size; + if (*len > nor->params->size) + *len = nor->params->size; if (nor->flags & SNOR_F_HAS_SR_TB && sr & tb_mask) *ofs = 0; else - *ofs = mtd->size - *len; + *ofs = nor->params->size - *len; } /* @@ -158,7 +157,6 @@ static bool spi_nor_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, u64 len, */ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len) { - struct mtd_info *mtd = &nor->mtd; u64 min_prot_len; int ret, status_old, status_new; u8 mask = spi_nor_get_sr_bp_mask(nor); @@ -183,7 +181,7 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len) can_be_bottom = false; /* If anything above us is unlocked, we can't use 'top' protection */ - if (!spi_nor_is_locked_sr(nor, ofs + len, mtd->size - (ofs + len), + if (!spi_nor_is_locked_sr(nor, ofs + len, nor->params->size - (ofs + len), status_old)) can_be_top = false; @@ -195,11 +193,11 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len) /* lock_len: length of region that should end up locked */ if (use_top) - lock_len = mtd->size - ofs; + lock_len = nor->params->size - ofs; else lock_len = ofs + len; - if (lock_len == mtd->size) { + if (lock_len == nor->params->size) { val = mask; } else { min_prot_len = spi_nor_get_min_prot_length_sr(nor); @@ -248,7 +246,6 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, u64 len) */ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len) { - struct mtd_info *mtd = &nor->mtd; u64 min_prot_len; int ret, status_old, status_new; u8 mask = spi_nor_get_sr_bp_mask(nor); @@ -273,7 +270,7 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len) can_be_top = false; /* If anything above us is locked, we can't use 'bottom' protection */ - if (!spi_nor_is_unlocked_sr(nor, ofs + len, mtd->size - (ofs + len), + if (!spi_nor_is_unlocked_sr(nor, ofs + len, nor->params->size - (ofs + len), status_old)) can_be_bottom = false; @@ -285,7 +282,7 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, u64 len) /* lock_len: length of region that should remain locked */ if (use_top) - lock_len = mtd->size - (ofs + len); + lock_len = nor->params->size - (ofs + len); else lock_len = ofs; diff --git a/drivers/mtd/spi-nor/sysfs.c b/drivers/mtd/spi-nor/sysfs.c index 4f12ff755df0..643513ee891b 100644 --- a/drivers/mtd/spi-nor/sysfs.c +++ b/drivers/mtd/spi-nor/sysfs.c @@ -104,7 +104,7 @@ static const struct attribute_group spi_nor_sysfs_group = { .is_visible = spi_nor_sysfs_is_visible, .is_bin_visible = spi_nor_sysfs_is_bin_visible, .attrs = spi_nor_sysfs_entries, - .bin_attrs_new = spi_nor_sysfs_bin_entries, + .bin_attrs = spi_nor_sysfs_bin_entries, }; const struct attribute_group *spi_nor_sysfs_groups[] = { |