summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/spi/spi-nor-core.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 2c3116ee530..83d7fe44ee1 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -903,6 +903,30 @@ static int read_bar(struct spi_nor *nor, const struct flash_info *info)
}
#endif
+/**
+ * spi_nor_erase_chip() - Erase the entire flash memory.
+ * @nor: pointer to 'struct spi_nor'.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_erase_chip(struct spi_nor *nor)
+{
+ struct spi_mem_op op =
+ SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CHIP_ERASE, 0),
+ SPI_MEM_OP_NO_ADDR,
+ SPI_MEM_OP_NO_DUMMY,
+ SPI_MEM_OP_NO_DATA);
+ int ret;
+
+ spi_nor_setup_op(nor, &op, nor->write_proto);
+
+ ret = spi_mem_exec_op(nor->spi, &op);
+ if (ret)
+ return ret;
+
+ return nor->mtd.size;
+}
+
/*
* Initiate the erasure of a single sector. Returns the number of bytes erased
* on success, a negative error code on error.
@@ -974,7 +998,12 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
if (ret < 0)
goto erase_err;
- ret = spi_nor_erase_sector(nor, addr);
+ if (len == mtd->size &&
+ !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) {
+ ret = spi_nor_erase_chip(nor);
+ } else {
+ ret = spi_nor_erase_sector(nor, addr);
+ }
if (ret < 0)
goto erase_err;