summaryrefslogtreecommitdiff
path: root/drivers/mtd/spi-nor/spansion.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/spi-nor/spansion.c')
-rw-r--r--drivers/mtd/spi-nor/spansion.c460
1 files changed, 396 insertions, 64 deletions
diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
index 12a256c0ef4c..15f9a80c10b9 100644
--- a/drivers/mtd/spi-nor/spansion.c
+++ b/drivers/mtd/spi-nor/spansion.c
@@ -14,13 +14,26 @@
#define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */
#define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */
#define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */
-#define SPINOR_REG_CYPRESS_CFR1V 0x00800002
+#define SPINOR_REG_CYPRESS_VREG 0x00800000
+#define SPINOR_REG_CYPRESS_STR1 0x0
+#define SPINOR_REG_CYPRESS_STR1V \
+ (SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_STR1)
+#define SPINOR_REG_CYPRESS_CFR1 0x2
+#define SPINOR_REG_CYPRESS_CFR1V \
+ (SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_CFR1)
#define SPINOR_REG_CYPRESS_CFR1_QUAD_EN BIT(1) /* Quad Enable */
-#define SPINOR_REG_CYPRESS_CFR2V 0x00800003
+#define SPINOR_REG_CYPRESS_CFR2 0x3
+#define SPINOR_REG_CYPRESS_CFR2V \
+ (SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_CFR2)
#define SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24 0xb
-#define SPINOR_REG_CYPRESS_CFR3V 0x00800004
+#define SPINOR_REG_CYPRESS_CFR2_ADRBYT BIT(7)
+#define SPINOR_REG_CYPRESS_CFR3 0x4
+#define SPINOR_REG_CYPRESS_CFR3V \
+ (SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_CFR3)
#define SPINOR_REG_CYPRESS_CFR3_PGSZ BIT(4) /* Page size. */
-#define SPINOR_REG_CYPRESS_CFR5V 0x00800006
+#define SPINOR_REG_CYPRESS_CFR5 0x6
+#define SPINOR_REG_CYPRESS_CFR5V \
+ (SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_CFR5)
#define SPINOR_REG_CYPRESS_CFR5_BIT6 BIT(6)
#define SPINOR_REG_CYPRESS_CFR5_DDR BIT(1)
#define SPINOR_REG_CYPRESS_CFR5_OPI BIT(0)
@@ -29,6 +42,7 @@
SPINOR_REG_CYPRESS_CFR5_OPI)
#define SPINOR_REG_CYPRESS_CFR5_OCT_DTR_DS SPINOR_REG_CYPRESS_CFR5_BIT6
#define SPINOR_OP_CYPRESS_RD_FAST 0xee
+#define SPINOR_REG_CYPRESS_ARCFN 0x00000006
/* Cypress SPI NOR flash operations. */
#define CYPRESS_NOR_WR_ANY_REG_OP(naddr, addr, ndata, buf) \
@@ -37,10 +51,10 @@
SPI_MEM_OP_NO_DUMMY, \
SPI_MEM_OP_DATA_OUT(ndata, buf, 0))
-#define CYPRESS_NOR_RD_ANY_REG_OP(naddr, addr, buf) \
+#define CYPRESS_NOR_RD_ANY_REG_OP(naddr, addr, ndummy, buf) \
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 0), \
SPI_MEM_OP_ADDR(naddr, addr, 0), \
- SPI_MEM_OP_NO_DUMMY, \
+ SPI_MEM_OP_DUMMY(ndummy, 0), \
SPI_MEM_OP_DATA_IN(1, buf, 0))
#define SPANSION_CLSR_OP \
@@ -49,6 +63,84 @@
SPI_MEM_OP_NO_DUMMY, \
SPI_MEM_OP_NO_DATA)
+/**
+ * spansion_nor_clear_sr() - Clear the Status Register.
+ * @nor: pointer to 'struct spi_nor'.
+ */
+static void spansion_nor_clear_sr(struct spi_nor *nor)
+{
+ int ret;
+
+ if (nor->spimem) {
+ struct spi_mem_op op = SPANSION_CLSR_OP;
+
+ spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
+
+ ret = spi_mem_exec_op(nor->spimem, &op);
+ } else {
+ ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLSR,
+ NULL, 0);
+ }
+
+ if (ret)
+ dev_dbg(nor->dev, "error %d clearing SR\n", ret);
+}
+
+static int cypress_nor_sr_ready_and_clear_reg(struct spi_nor *nor, u64 addr)
+{
+ struct spi_mem_op op =
+ CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes, addr,
+ 0, nor->bouncebuf);
+ int ret;
+
+ ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
+ if (ret)
+ return ret;
+
+ if (nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
+ if (nor->bouncebuf[0] & SR_E_ERR)
+ dev_err(nor->dev, "Erase Error occurred\n");
+ else
+ dev_err(nor->dev, "Programming Error occurred\n");
+
+ spansion_nor_clear_sr(nor);
+
+ ret = spi_nor_write_disable(nor);
+ if (ret)
+ return ret;
+
+ return -EIO;
+ }
+
+ return !(nor->bouncebuf[0] & SR_WIP);
+}
+/**
+ * cypress_nor_sr_ready_and_clear() - Query the Status Register of each die by
+ * using Read Any Register command to see if the whole flash is ready for new
+ * commands and clear it if there are any errors.
+ * @nor: pointer to 'struct spi_nor'.
+ *
+ * Return: 1 if ready, 0 if not ready, -errno on errors.
+ */
+static int cypress_nor_sr_ready_and_clear(struct spi_nor *nor)
+{
+ struct spi_nor_flash_parameter *params = nor->params;
+ u64 addr;
+ int ret;
+ u8 i;
+
+ for (i = 0; i < params->n_dice; i++) {
+ addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_STR1;
+ ret = cypress_nor_sr_ready_and_clear_reg(nor, addr);
+ if (ret < 0)
+ return ret;
+ else if (ret == 0)
+ return 0;
+ }
+
+ return 1;
+}
+
static int cypress_nor_octal_dtr_en(struct spi_nor *nor)
{
struct spi_mem_op op;
@@ -125,21 +217,7 @@ static int cypress_nor_octal_dtr_dis(struct spi_nor *nor)
return 0;
}
-/**
- * cypress_nor_quad_enable_volatile() - enable Quad I/O mode in volatile
- * register.
- * @nor: pointer to a 'struct spi_nor'
- *
- * It is recommended to update volatile registers in the field application due
- * to a risk of the non-volatile registers corruption by power interrupt. This
- * function sets Quad Enable bit in CFR1 volatile. If users set the Quad Enable
- * bit in the CFR1 non-volatile in advance (typically by a Flash programmer
- * before mounting Flash on PCB), the Quad Enable bit in the CFR1 volatile is
- * also set during Flash power-up.
- *
- * Return: 0 on success, -errno otherwise.
- */
-static int cypress_nor_quad_enable_volatile(struct spi_nor *nor)
+static int cypress_nor_quad_enable_volatile_reg(struct spi_nor *nor, u64 addr)
{
struct spi_mem_op op;
u8 addr_mode_nbytes = nor->params->addr_mode_nbytes;
@@ -147,8 +225,7 @@ static int cypress_nor_quad_enable_volatile(struct spi_nor *nor)
int ret;
op = (struct spi_mem_op)
- CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes,
- SPINOR_REG_CYPRESS_CFR1V,
+ CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, addr, 0,
nor->bouncebuf);
ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
@@ -161,8 +238,7 @@ static int cypress_nor_quad_enable_volatile(struct spi_nor *nor)
/* Update the Quad Enable bit. */
nor->bouncebuf[0] |= SPINOR_REG_CYPRESS_CFR1_QUAD_EN;
op = (struct spi_mem_op)
- CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes,
- SPINOR_REG_CYPRESS_CFR1V, 1,
+ CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, addr, 1,
nor->bouncebuf);
ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
if (ret)
@@ -172,8 +248,7 @@ static int cypress_nor_quad_enable_volatile(struct spi_nor *nor)
/* Read back and check it. */
op = (struct spi_mem_op)
- CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes,
- SPINOR_REG_CYPRESS_CFR1V,
+ CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, addr, 0,
nor->bouncebuf);
ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
if (ret)
@@ -188,21 +263,156 @@ static int cypress_nor_quad_enable_volatile(struct spi_nor *nor)
}
/**
- * cypress_nor_set_page_size() - Set page size which corresponds to the flash
- * configuration.
+ * cypress_nor_quad_enable_volatile() - enable Quad I/O mode in volatile
+ * register.
* @nor: pointer to a 'struct spi_nor'
*
- * The BFPT table advertises a 512B or 256B page size depending on part but the
- * page size is actually configurable (with the default being 256B). Read from
- * CFR3V[4] and set the correct size.
+ * It is recommended to update volatile registers in the field application due
+ * to a risk of the non-volatile registers corruption by power interrupt. This
+ * function sets Quad Enable bit in CFR1 volatile. If users set the Quad Enable
+ * bit in the CFR1 non-volatile in advance (typically by a Flash programmer
+ * before mounting Flash on PCB), the Quad Enable bit in the CFR1 volatile is
+ * also set during Flash power-up.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int cypress_nor_quad_enable_volatile(struct spi_nor *nor)
+{
+ struct spi_nor_flash_parameter *params = nor->params;
+ u64 addr;
+ u8 i;
+ int ret;
+
+ if (!params->n_dice)
+ return cypress_nor_quad_enable_volatile_reg(nor,
+ SPINOR_REG_CYPRESS_CFR1V);
+
+ for (i = 0; i < params->n_dice; i++) {
+ addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR1;
+ ret = cypress_nor_quad_enable_volatile_reg(nor, addr);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * cypress_nor_determine_addr_mode_by_sr1() - Determine current address mode
+ * (3 or 4-byte) by querying status
+ * register 1 (SR1).
+ * @nor: pointer to a 'struct spi_nor'
+ * @addr_mode: ponter to a buffer where we return the determined
+ * address mode.
+ *
+ * This function tries to determine current address mode by comparing SR1 value
+ * from RDSR1(no address), RDAR(3-byte address), and RDAR(4-byte address).
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int cypress_nor_determine_addr_mode_by_sr1(struct spi_nor *nor,
+ u8 *addr_mode)
+{
+ struct spi_mem_op op =
+ CYPRESS_NOR_RD_ANY_REG_OP(3, SPINOR_REG_CYPRESS_STR1V, 0,
+ nor->bouncebuf);
+ bool is3byte, is4byte;
+ int ret;
+
+ ret = spi_nor_read_sr(nor, &nor->bouncebuf[1]);
+ if (ret)
+ return ret;
+
+ ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
+ if (ret)
+ return ret;
+
+ is3byte = (nor->bouncebuf[0] == nor->bouncebuf[1]);
+
+ op = (struct spi_mem_op)
+ CYPRESS_NOR_RD_ANY_REG_OP(4, SPINOR_REG_CYPRESS_STR1V, 0,
+ nor->bouncebuf);
+ ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
+ if (ret)
+ return ret;
+
+ is4byte = (nor->bouncebuf[0] == nor->bouncebuf[1]);
+
+ if (is3byte == is4byte)
+ return -EIO;
+ if (is3byte)
+ *addr_mode = 3;
+ else
+ *addr_mode = 4;
+
+ return 0;
+}
+
+/**
+ * cypress_nor_set_addr_mode_nbytes() - Set the number of address bytes mode of
+ * current address mode.
+ * @nor: pointer to a 'struct spi_nor'
+ *
+ * Determine current address mode by reading SR1 with different methods, then
+ * query CFR2V[7] to confirm. If determination is failed, force enter to 4-byte
+ * address mode.
*
* Return: 0 on success, -errno otherwise.
*/
-static int cypress_nor_set_page_size(struct spi_nor *nor)
+static int cypress_nor_set_addr_mode_nbytes(struct spi_nor *nor)
+{
+ struct spi_mem_op op;
+ u8 addr_mode;
+ int ret;
+
+ /*
+ * Read SR1 by RDSR1 and RDAR(3- AND 4-byte addr). Use write enable
+ * that sets bit-1 in SR1.
+ */
+ ret = spi_nor_write_enable(nor);
+ if (ret)
+ return ret;
+ ret = cypress_nor_determine_addr_mode_by_sr1(nor, &addr_mode);
+ if (ret) {
+ ret = spi_nor_set_4byte_addr_mode(nor, true);
+ if (ret)
+ return ret;
+ return spi_nor_write_disable(nor);
+ }
+ ret = spi_nor_write_disable(nor);
+ if (ret)
+ return ret;
+
+ /*
+ * Query CFR2V and make sure no contradiction between determined address
+ * mode and CFR2V[7].
+ */
+ op = (struct spi_mem_op)
+ CYPRESS_NOR_RD_ANY_REG_OP(addr_mode, SPINOR_REG_CYPRESS_CFR2V,
+ 0, nor->bouncebuf);
+ ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
+ if (ret)
+ return ret;
+
+ if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR2_ADRBYT) {
+ if (addr_mode != 4)
+ return spi_nor_set_4byte_addr_mode(nor, true);
+ } else {
+ if (addr_mode != 3)
+ return spi_nor_set_4byte_addr_mode(nor, true);
+ }
+
+ nor->params->addr_nbytes = addr_mode;
+ nor->params->addr_mode_nbytes = addr_mode;
+
+ return 0;
+}
+
+static int cypress_nor_get_page_size_single_chip(struct spi_nor *nor)
{
struct spi_mem_op op =
CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes,
- SPINOR_REG_CYPRESS_CFR3V,
+ SPINOR_REG_CYPRESS_CFR3V, 0,
nor->bouncebuf);
int ret;
@@ -218,18 +428,135 @@ static int cypress_nor_set_page_size(struct spi_nor *nor)
return 0;
}
+
+static int cypress_nor_get_page_size_mcp(struct spi_nor *nor)
+{
+ struct spi_mem_op op =
+ CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes,
+ 0, 0, nor->bouncebuf);
+ struct spi_nor_flash_parameter *params = nor->params;
+ int ret;
+ u8 i;
+
+ /*
+ * Use the minimum common page size configuration. Programming 256-byte
+ * under 512-byte page size configuration is safe.
+ */
+ params->page_size = 256;
+ for (i = 0; i < params->n_dice; i++) {
+ op.addr.val = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR3;
+
+ ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
+ if (ret)
+ return ret;
+
+ if (!(nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR3_PGSZ))
+ return 0;
+ }
+
+ params->page_size = 512;
+
+ return 0;
+}
+
+/**
+ * cypress_nor_get_page_size() - Get flash page size configuration.
+ * @nor: pointer to a 'struct spi_nor'
+ *
+ * The BFPT table advertises a 512B or 256B page size depending on part but the
+ * page size is actually configurable (with the default being 256B). Read from
+ * CFR3V[4] and set the correct size.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int cypress_nor_get_page_size(struct spi_nor *nor)
+{
+ if (nor->params->n_dice)
+ return cypress_nor_get_page_size_mcp(nor);
+ return cypress_nor_get_page_size_single_chip(nor);
+}
+
+static void cypress_nor_ecc_init(struct spi_nor *nor)
+{
+ /*
+ * Programming is supported only in 16-byte ECC data unit granularity.
+ * Byte-programming, bit-walking, or multiple program operations to the
+ * same ECC data unit without an erase are not allowed.
+ */
+ nor->params->writesize = 16;
+ nor->flags |= SNOR_F_ECC;
+}
+
+static int
+s25fs256t_post_bfpt_fixup(struct spi_nor *nor,
+ const struct sfdp_parameter_header *bfpt_header,
+ const struct sfdp_bfpt *bfpt)
+{
+ struct spi_mem_op op;
+ int ret;
+
+ ret = cypress_nor_set_addr_mode_nbytes(nor);
+ if (ret)
+ return ret;
+
+ /* Read Architecture Configuration Register (ARCFN) */
+ op = (struct spi_mem_op)
+ CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes,
+ SPINOR_REG_CYPRESS_ARCFN, 1,
+ nor->bouncebuf);
+ ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
+ if (ret)
+ return ret;
+
+ /* ARCFN value must be 0 if uniform sector is selected */
+ if (nor->bouncebuf[0])
+ return -ENODEV;
+
+ return cypress_nor_get_page_size(nor);
+}
+
+static int s25fs256t_post_sfdp_fixup(struct spi_nor *nor)
+{
+ struct spi_nor_flash_parameter *params = nor->params;
+
+ /* PP_1_1_4_4B is supported but missing in 4BAIT. */
+ params->hwcaps.mask |= SNOR_HWCAPS_PP_1_1_4;
+ spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_1_1_4],
+ SPINOR_OP_PP_1_1_4_4B,
+ SNOR_PROTO_1_1_4);
+
+ return 0;
+}
+
+static void s25fs256t_late_init(struct spi_nor *nor)
+{
+ cypress_nor_ecc_init(nor);
+}
+
+static struct spi_nor_fixups s25fs256t_fixups = {
+ .post_bfpt = s25fs256t_post_bfpt_fixup,
+ .post_sfdp = s25fs256t_post_sfdp_fixup,
+ .late_init = s25fs256t_late_init,
+};
+
static int
s25hx_t_post_bfpt_fixup(struct spi_nor *nor,
const struct sfdp_parameter_header *bfpt_header,
const struct sfdp_bfpt *bfpt)
{
+ int ret;
+
+ ret = cypress_nor_set_addr_mode_nbytes(nor);
+ if (ret)
+ return ret;
+
/* Replace Quad Enable with volatile version */
nor->params->quad_enable = cypress_nor_quad_enable_volatile;
- return cypress_nor_set_page_size(nor);
+ return 0;
}
-static void s25hx_t_post_sfdp_fixup(struct spi_nor *nor)
+static int s25hx_t_post_sfdp_fixup(struct spi_nor *nor)
{
struct spi_nor_erase_type *erase_type =
nor->params->erase_map.erase_type;
@@ -251,6 +578,12 @@ static void s25hx_t_post_sfdp_fixup(struct spi_nor *nor)
break;
}
}
+
+ /* The 2 Gb parts duplicate info and advertise 4 dice instead of 2. */
+ if (nor->params->size == SZ_256M)
+ nor->params->n_dice = 2;
+
+ return cypress_nor_get_page_size(nor);
}
static void s25hx_t_late_init(struct spi_nor *nor)
@@ -260,8 +593,11 @@ static void s25hx_t_late_init(struct spi_nor *nor)
/* Fast Read 4B requires mode cycles */
params->reads[SNOR_CMD_READ_FAST].num_mode_clocks = 8;
- /* The writesize should be ECC data unit size */
- params->writesize = 16;
+ cypress_nor_ecc_init(nor);
+
+ /* Replace ready() with multi die version */
+ if (params->n_dice)
+ params->ready = cypress_nor_sr_ready_and_clear;
}
static struct spi_nor_fixups s25hx_t_fixups = {
@@ -286,7 +622,7 @@ static int cypress_nor_octal_dtr_enable(struct spi_nor *nor, bool enable)
cypress_nor_octal_dtr_dis(nor);
}
-static void s28hx_t_post_sfdp_fixup(struct spi_nor *nor)
+static int s28hx_t_post_sfdp_fixup(struct spi_nor *nor)
{
/*
* On older versions of the flash the xSPI Profile 1.0 table has the
@@ -312,19 +648,27 @@ static void s28hx_t_post_sfdp_fixup(struct spi_nor *nor)
* actual value for that is 4.
*/
nor->params->rdsr_addr_nbytes = 4;
+
+ return cypress_nor_get_page_size(nor);
}
static int s28hx_t_post_bfpt_fixup(struct spi_nor *nor,
const struct sfdp_parameter_header *bfpt_header,
const struct sfdp_bfpt *bfpt)
{
- return cypress_nor_set_page_size(nor);
+ int ret;
+
+ ret = cypress_nor_set_addr_mode_nbytes(nor);
+ if (ret)
+ return ret;
+
+ return 0;
}
static void s28hx_t_late_init(struct spi_nor *nor)
{
nor->params->octal_dtr_enable = cypress_nor_octal_dtr_enable;
- nor->params->writesize = 16;
+ cypress_nor_ecc_init(nor);
}
static const struct spi_nor_fixups s28hx_t_fixups = {
@@ -446,6 +790,9 @@ static const struct flash_info spansion_nor_parts[] = {
{ "s25fl256l", INFO(0x016019, 0, 64 * 1024, 512)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
+ { "s25fs256t", INFO6(0x342b19, 0x0f0890, 0, 0)
+ PARSE_SFDP
+ .fixups = &s25fs256t_fixups },
{ "s25hl512t", INFO6(0x342a1a, 0x0f0390, 256 * 1024, 256)
PARSE_SFDP
MFR_FLAGS(USE_CLSR)
@@ -454,6 +801,10 @@ static const struct flash_info spansion_nor_parts[] = {
PARSE_SFDP
MFR_FLAGS(USE_CLSR)
.fixups = &s25hx_t_fixups },
+ { "s25hl02gt", INFO6(0x342a1c, 0x0f0090, 0, 0)
+ PARSE_SFDP
+ FLAGS(NO_CHIP_ERASE)
+ .fixups = &s25hx_t_fixups },
{ "s25hs512t", INFO6(0x342b1a, 0x0f0390, 256 * 1024, 256)
PARSE_SFDP
MFR_FLAGS(USE_CLSR)
@@ -462,6 +813,10 @@ static const struct flash_info spansion_nor_parts[] = {
PARSE_SFDP
MFR_FLAGS(USE_CLSR)
.fixups = &s25hx_t_fixups },
+ { "s25hs02gt", INFO6(0x342b1c, 0x0f0090, 0, 0)
+ PARSE_SFDP
+ FLAGS(NO_CHIP_ERASE)
+ .fixups = &s25hx_t_fixups },
{ "cy15x104q", INFO6(0x042cc2, 0x7f7f7f, 512 * 1024, 1)
FLAGS(SPI_NOR_NO_ERASE) },
{ "s28hl512t", INFO(0x345a1a, 0, 256 * 1024, 256)
@@ -483,29 +838,6 @@ static const struct flash_info spansion_nor_parts[] = {
};
/**
- * spansion_nor_clear_sr() - Clear the Status Register.
- * @nor: pointer to 'struct spi_nor'.
- */
-static void spansion_nor_clear_sr(struct spi_nor *nor)
-{
- int ret;
-
- if (nor->spimem) {
- struct spi_mem_op op = SPANSION_CLSR_OP;
-
- spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-
- ret = spi_mem_exec_op(nor->spimem, &op);
- } else {
- ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLSR,
- NULL, 0);
- }
-
- if (ret)
- dev_dbg(nor->dev, "error %d clearing SR\n", ret);
-}
-
-/**
* spansion_nor_sr_ready_and_clear() - Query the Status Register to see if the
* flash is ready for new commands and clear it if there are any errors.
* @nor: pointer to 'struct spi_nor'.