summaryrefslogtreecommitdiff
path: root/drivers/mtd
diff options
context:
space:
mode:
authorPratyush Yadav <p.yadav@ti.com>2021-06-25 22:17:26 +0300
committerJagan Teki <jagan@amarulasolutions.com>2021-06-28 09:35:38 +0300
commitaba0bcd7bda494d7fe9c82e581db9791ce41e2f3 (patch)
treed9ab3d4ddd58485112c888851371ed2508690c74 /drivers/mtd
parent0be8ab1f166844d53477387dc9a1184161ef44ef (diff)
downloadu-boot-aba0bcd7bda494d7fe9c82e581db9791ce41e2f3.tar.xz
mtd: spi-nor-core: allow truncated erases
On devices with non-uniform sector sizes like Spansion S25 or S28 family of flashes the sector under erase does not necessarily have to be mtd->erasesize bytes long. For example, on S28 flashes the first 128 KiB region is composed of 32 4 KiB sectors, then a 128 KiB sector, and then 256 KiB sectors till the end. Let the flash-specific erase functions erase less than the requested length in case of the 4 or 128 KiB sectors and report the number of bytes erased back to the calling function. Signed-off-by: Pratyush Yadav <p.yadav@ti.com> Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/spi/spi-nor-core.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 3bf9404490..ece4bc9e84 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -806,7 +806,8 @@ static int read_bar(struct spi_nor *nor, const struct flash_info *info)
#endif
/*
- * Initiate the erasure of a single sector
+ * Initiate the erasure of a single sector. Returns the number of bytes erased
+ * on success, a negative error code on error.
*/
static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
{
@@ -815,6 +816,7 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
SPI_MEM_OP_ADDR(nor->addr_width, addr, 0),
SPI_MEM_OP_NO_DUMMY,
SPI_MEM_OP_NO_DATA);
+ int ret;
spi_nor_setup_op(nor, &op, nor->write_proto);
@@ -825,7 +827,11 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
* Default implementation, if driver doesn't have a specialized HW
* control
*/
- return spi_mem_exec_op(nor->spi, &op);
+ ret = spi_mem_exec_op(nor->spi, &op);
+ if (ret)
+ return ret;
+
+ return nor->mtd.erasesize;
}
/*
@@ -861,11 +867,11 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
write_enable(nor);
ret = spi_nor_erase_sector(nor, addr);
- if (ret)
+ if (ret < 0)
goto erase_err;
- addr += mtd->erasesize;
- len -= mtd->erasesize;
+ addr += ret;
+ len -= ret;
ret = spi_nor_wait_till_ready(nor);
if (ret)