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>
This commit is contained in:
committed by
Jagan Teki
parent
0be8ab1f16
commit
aba0bcd7bd
@@ -806,7 +806,8 @@ static int read_bar(struct spi_nor *nor, const struct flash_info *info)
|
|||||||
#endif
|
#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)
|
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_ADDR(nor->addr_width, addr, 0),
|
||||||
SPI_MEM_OP_NO_DUMMY,
|
SPI_MEM_OP_NO_DUMMY,
|
||||||
SPI_MEM_OP_NO_DATA);
|
SPI_MEM_OP_NO_DATA);
|
||||||
|
int ret;
|
||||||
|
|
||||||
spi_nor_setup_op(nor, &op, nor->write_proto);
|
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
|
* Default implementation, if driver doesn't have a specialized HW
|
||||||
* control
|
* 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);
|
write_enable(nor);
|
||||||
|
|
||||||
ret = spi_nor_erase_sector(nor, addr);
|
ret = spi_nor_erase_sector(nor, addr);
|
||||||
if (ret)
|
if (ret < 0)
|
||||||
goto erase_err;
|
goto erase_err;
|
||||||
|
|
||||||
addr += mtd->erasesize;
|
addr += ret;
|
||||||
len -= mtd->erasesize;
|
len -= ret;
|
||||||
|
|
||||||
ret = spi_nor_wait_till_ready(nor);
|
ret = spi_nor_wait_till_ready(nor);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|||||||
Reference in New Issue
Block a user