@@ -10,6 +10,7 @@
#define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */
#define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */
+#define SPINOR_REG_CYPRESS_STR1V 0x00800000
#define SPINOR_REG_CYPRESS_CFR1V 0x00800002
#define SPINOR_REG_CYPRESS_CFR1V_QUAD_EN BIT(1) /* Quad Enable */
#define SPINOR_REG_CYPRESS_CFR2V 0x00800003
@@ -183,6 +184,51 @@ static int spansion_quad_enable_volatile(struct spi_nor *nor, u8 reg_dummy,
return 0;
}
+/**
+ * spansion_mdp_ready() - Query the Status Register via Read Any Register
+ * command for multi-die package parts that do not
+ * support default RDSR(05h)
+ * @nor: pointer to 'struct spi_nor'.
+ * @reg_dummy: number of dummy cycles for register read
+ * @die_size: size of each die to determine the number of dies
+ *
+ * Return: 1 if ready, 0 if not ready, -errno on errors.
+ */
+static int spansion_mdp_ready(struct spi_nor *nor, u8 reg_dummy, u32 die_size)
+{
+ int ret;
+ u32 base;
+ u8 sr;
+
+ for (base = 0; base < nor->params->size; base += die_size) {
+ ret = spansion_read_any_reg(nor,
+ base + SPINOR_REG_CYPRESS_STR1V,
+ reg_dummy, &sr);
+ if (ret)
+ return ret;
+
+ if (sr & (SR_E_ERR | SR_P_ERR)) {
+ if (sr & SR_E_ERR)
+ dev_err(nor->dev, "Erase Error occurred\n");
+ else
+ dev_err(nor->dev, "Programming Error occurred\n");
+
+ spi_nor_clear_sr(nor);
+
+ ret = spi_nor_write_disable(nor);
+ if (ret)
+ return ret;
+
+ return -EIO;
+ }
+
+ if (sr & SR_WIP)
+ return 0;
+ }
+
+ return 1;
+}
+
/**
* spi_nor_cypress_octal_dtr_enable() - Enable octal DTR on Cypress flashes.
* @nor: pointer to a 'struct spi_nor'