Commit 9b6bb07e authored by Michael Walle's avatar Michael Walle Committed by Tudor Ambarus

mtd: spi-nor: push 4k SE handling into spi_nor_select_uniform_erase()

4k sector erase sizes are only a thing with uniform erase types. Push
the "we want 4k erase sizes" handling into spi_nor_select_uniform_erase().

One might wonder why the former sector_size isn't used anymore. It is
because we either search for the largest erase size or if selected
through kconfig, the 4k erase size. Now, why is that correct? For this,
we have to differentiate between (1) flashes with SFDP and (2) without
SFDP. For (1), we just set one (or two if SECT_4K is set) erase types
and wanted_size is exactly one of these.

For (2) things are a bit more complicated. For flashes which we don't
have in our flash_info database, the generic driver is used and
sector_size was already 0, which in turn selected the largest erase
size. For flashes which had SFDP and an entry in flash_info, sector_size
was always the largest sector and thus the largest erase type.
Signed-off-by: default avatarMichael Walle <mwalle@kernel.org>
Link: https://lore.kernel.org/r/20230807-mtd-flash-info-db-rework-v3-9-e60548861b10@kernel.orgSigned-off-by: default avatarTudor Ambarus <tudor.ambarus@linaro.org>
parent e255a791
...@@ -2512,13 +2512,6 @@ static int spi_nor_select_pp(struct spi_nor *nor, ...@@ -2512,13 +2512,6 @@ static int spi_nor_select_pp(struct spi_nor *nor,
/** /**
* spi_nor_select_uniform_erase() - select optimum uniform erase type * spi_nor_select_uniform_erase() - select optimum uniform erase type
* @map: the erase map of the SPI NOR * @map: the erase map of the SPI NOR
* @wanted_size: the erase type size to search for. Contains the value of
* info->sector_size, the "small sector" size in case
* CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is defined or 0 if
* there is no information about the sector size. The
* latter is the case if the flash parameters are parsed
* solely by SFDP, then the largest supported erase type
* is selected.
* *
* Once the optimum uniform sector erase command is found, disable all the * Once the optimum uniform sector erase command is found, disable all the
* other. * other.
...@@ -2526,13 +2519,16 @@ static int spi_nor_select_pp(struct spi_nor *nor, ...@@ -2526,13 +2519,16 @@ static int spi_nor_select_pp(struct spi_nor *nor,
* Return: pointer to erase type on success, NULL otherwise. * Return: pointer to erase type on success, NULL otherwise.
*/ */
static const struct spi_nor_erase_type * static const struct spi_nor_erase_type *
spi_nor_select_uniform_erase(struct spi_nor_erase_map *map, spi_nor_select_uniform_erase(struct spi_nor_erase_map *map)
const u32 wanted_size)
{ {
const struct spi_nor_erase_type *tested_erase, *erase = NULL; const struct spi_nor_erase_type *tested_erase, *erase = NULL;
int i; int i;
u8 uniform_erase_type = map->uniform_erase_type; u8 uniform_erase_type = map->uniform_erase_type;
/*
* Search for the biggest erase size, except for when compiled
* to use 4k erases.
*/
for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) { for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) {
if (!(uniform_erase_type & BIT(i))) if (!(uniform_erase_type & BIT(i)))
continue; continue;
...@@ -2544,10 +2540,11 @@ spi_nor_select_uniform_erase(struct spi_nor_erase_map *map, ...@@ -2544,10 +2540,11 @@ spi_nor_select_uniform_erase(struct spi_nor_erase_map *map,
continue; continue;
/* /*
* If the current erase size is the one, stop here: * If the current erase size is the 4k one, stop here,
* we have found the right uniform Sector Erase command. * we have found the right uniform Sector Erase command.
*/ */
if (tested_erase->size == wanted_size) { if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_4K_SECTORS) &&
tested_erase->size == SZ_4K) {
erase = tested_erase; erase = tested_erase;
break; break;
} }
...@@ -2575,7 +2572,6 @@ static int spi_nor_select_erase(struct spi_nor *nor) ...@@ -2575,7 +2572,6 @@ static int spi_nor_select_erase(struct spi_nor *nor)
struct spi_nor_erase_map *map = &nor->params->erase_map; struct spi_nor_erase_map *map = &nor->params->erase_map;
const struct spi_nor_erase_type *erase = NULL; const struct spi_nor_erase_type *erase = NULL;
struct mtd_info *mtd = &nor->mtd; struct mtd_info *mtd = &nor->mtd;
u32 wanted_size = nor->info->sector_size;
int i; int i;
/* /*
...@@ -2586,13 +2582,8 @@ static int spi_nor_select_erase(struct spi_nor *nor) ...@@ -2586,13 +2582,8 @@ static int spi_nor_select_erase(struct spi_nor *nor)
* manage the SPI flash memory as uniform with a single erase sector * manage the SPI flash memory as uniform with a single erase sector
* size, when possible. * size, when possible.
*/ */
#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
/* prefer "small sector" erase if possible */
wanted_size = 4096u;
#endif
if (spi_nor_has_uniform_erase(nor)) { if (spi_nor_has_uniform_erase(nor)) {
erase = spi_nor_select_uniform_erase(map, wanted_size); erase = spi_nor_select_uniform_erase(map);
if (!erase) if (!erase)
return -EINVAL; return -EINVAL;
nor->erase_opcode = erase->opcode; nor->erase_opcode = erase->opcode;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment