]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mtd: spi-nor: core: get rid of SNOR_LAST_REGION flag
authorTakahiro Kuwano <Takahiro.Kuwano@infineon.com>
Tue, 20 Feb 2024 08:34:07 +0000 (17:34 +0900)
committerTudor Ambarus <tudor.ambarus@linaro.org>
Mon, 26 Feb 2024 11:17:43 +0000 (13:17 +0200)
Introduce n_regions in spi_nor_erase_map structure and remove
SNOR_LAST_REGION flag. Loop logics that depend on the flag are also
reworked to use n_regions as loop condition.

Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
Suggested-by: Tudor Ambarus <tudor.ambarus@linaro.org>
Suggested-by: Michael Walle <mwalle@kernel.org>
Reviewed-by: Michael Walle <mwalle@kernel.org>
Link: https://lore.kernel.org/r/eded84294bd81e966d6f423e578fc2cfb9a4a5b6.1708404584.git.Takahiro.Kuwano@infineon.com
[ta: update spi_nor_init_erase_cmd_list() and break the for loop sooner.]
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
drivers/mtd/spi-nor/core.c
drivers/mtd/spi-nor/core.h
drivers/mtd/spi-nor/debugfs.c
drivers/mtd/spi-nor/sfdp.c

index d526e555e7b3bbc2085eff1a2da524f5b562c7ca..8dcfb8649f017f4f9cc4df8c225e11ffa69db54a 100644 (file)
@@ -1573,52 +1573,6 @@ spi_nor_find_best_erase_type(const struct spi_nor_erase_map *map,
        return NULL;
 }
 
-static u64 spi_nor_region_is_last(const struct spi_nor_erase_region *region)
-{
-       return region->flags & SNOR_LAST_REGION;
-}
-
-/**
- * spi_nor_region_next() - get the next spi nor region
- * @region:    pointer to a structure that describes a SPI NOR erase region
- *
- * Return: the next spi nor region or NULL if last region.
- */
-struct spi_nor_erase_region *
-spi_nor_region_next(struct spi_nor_erase_region *region)
-{
-       if (spi_nor_region_is_last(region))
-               return NULL;
-       region++;
-       return region;
-}
-
-/**
- * spi_nor_find_erase_region() - find the region of the serial flash memory in
- *                              which the offset fits
- * @map:       the erase map of the SPI NOR
- * @addr:      offset in the serial flash memory
- *
- * Return: a pointer to the spi_nor_erase_region struct, ERR_PTR(-errno)
- *        otherwise.
- */
-static struct spi_nor_erase_region *
-spi_nor_find_erase_region(const struct spi_nor_erase_map *map, u64 addr)
-{
-       struct spi_nor_erase_region *region = map->regions;
-       u64 region_end = region->offset + region->size;
-
-       while (addr < region->offset || addr >= region_end) {
-               region = spi_nor_region_next(region);
-               if (!region)
-                       return ERR_PTR(-EINVAL);
-
-               region_end = region->offset + region->size;
-       }
-
-       return region;
-}
-
 /**
  * spi_nor_init_erase_cmd() - initialize an erase command
  * @region:    pointer to a structure that describes a SPI NOR erase region
@@ -1685,44 +1639,36 @@ static int spi_nor_init_erase_cmd_list(struct spi_nor *nor,
        struct spi_nor_erase_region *region;
        struct spi_nor_erase_command *cmd = NULL;
        u64 region_end;
+       unsigned int i;
        int ret = -EINVAL;
 
-       region = spi_nor_find_erase_region(map, addr);
-       if (IS_ERR(region))
-               return PTR_ERR(region);
-
-       region_end = region->offset + region->size;
+       for (i = 0; i < map->n_regions && len; i++) {
+               region = &map->regions[i];
+               region_end = region->offset + region->size;
 
-       while (len) {
-               erase = spi_nor_find_best_erase_type(map, region, addr, len);
-               if (!erase)
-                       goto destroy_erase_cmd_list;
-
-               if (prev_erase != erase ||
-                   erase->size != cmd->size ||
-                   region->flags & SNOR_OVERLAID_REGION) {
-                       cmd = spi_nor_init_erase_cmd(region, erase);
-                       if (IS_ERR(cmd)) {
-                               ret = PTR_ERR(cmd);
+               while (len && addr >= region->offset && addr < region_end) {
+                       erase = spi_nor_find_best_erase_type(map, region, addr,
+                                                            len);
+                       if (!erase)
                                goto destroy_erase_cmd_list;
-                       }
-
-                       list_add_tail(&cmd->list, erase_list);
-               } else {
-                       cmd->count++;
-               }
 
-               addr += cmd->size;
-               len -= cmd->size;
+                       if (prev_erase != erase || erase->size != cmd->size ||
+                           region->flags & SNOR_OVERLAID_REGION) {
+                               cmd = spi_nor_init_erase_cmd(region, erase);
+                               if (IS_ERR(cmd)) {
+                                       ret = PTR_ERR(cmd);
+                                       goto destroy_erase_cmd_list;
+                               }
+
+                               list_add_tail(&cmd->list, erase_list);
+                       } else {
+                               cmd->count++;
+                       }
 
-               if (len && addr >= region_end) {
-                       region = spi_nor_region_next(region);
-                       if (!region)
-                               goto destroy_erase_cmd_list;
-                       region_end = region->offset + region->size;
+                       len -= cmd->size;
+                       addr += cmd->size;
+                       prev_erase = erase;
                }
-
-               prev_erase = erase;
        }
 
        return 0;
@@ -2463,8 +2409,8 @@ void spi_nor_init_uniform_erase_map(struct spi_nor_erase_map *map,
        map->uniform_region.offset = 0;
        map->uniform_region.size = flash_size;
        map->uniform_region.erase_mask = erase_mask;
-       map->uniform_region.flags = SNOR_LAST_REGION;
        map->regions = &map->uniform_region;
+       map->n_regions = 1;
 }
 
 int spi_nor_post_bfpt_fixups(struct spi_nor *nor,
index f68ae2fc4a1fe29164c9ada4a430654d8262ebcf..38be40a4647b590347daa48c0b4767502fbf5043 100644 (file)
@@ -245,8 +245,7 @@ struct spi_nor_erase_command {
  *                     inside this region. The erase types are sorted in
  *                     ascending order with the smallest Erase Type size being
  *                     at BIT(0).
- * @flags:             flags to determine if this region is overlaid, if this
- *                     region is the last in the SPI NOR flash memory
+ * @flags:             flags to determine if this region is overlaid.
  */
 struct spi_nor_erase_region {
        u64             offset;
@@ -257,8 +256,7 @@ struct spi_nor_erase_region {
 
 #define SNOR_ERASE_TYPE_MAX    4
 
-#define SNOR_LAST_REGION       BIT(0)
-#define SNOR_OVERLAID_REGION   BIT(1)
+#define SNOR_OVERLAID_REGION   BIT(0)
 
 /**
  * struct spi_nor_erase_map - Structure to describe the SPI NOR erase map
@@ -271,11 +269,13 @@ struct spi_nor_erase_region {
  *                     The erase types are sorted in ascending order, with the
  *                     smallest Erase Type size being the first member in the
  *                     erase_type array.
+ * @n_regions:         number of erase regions.
  */
 struct spi_nor_erase_map {
        struct spi_nor_erase_region     *regions;
        struct spi_nor_erase_region     uniform_region;
        struct spi_nor_erase_type       erase_type[SNOR_ERASE_TYPE_MAX];
+       unsigned int                    n_regions;
 };
 
 /**
@@ -667,8 +667,6 @@ void spi_nor_set_pp_settings(struct spi_nor_pp_command *pp, u8 opcode,
 void spi_nor_set_erase_type(struct spi_nor_erase_type *erase, u32 size,
                            u8 opcode);
 void spi_nor_mask_erase_type(struct spi_nor_erase_type *erase);
-struct spi_nor_erase_region *
-spi_nor_region_next(struct spi_nor_erase_region *region);
 void spi_nor_init_uniform_erase_map(struct spi_nor_erase_map *map,
                                    u8 erase_mask, u64 flash_size);
 
index d20bbb531a880e705b214c46aedb995b58c4fffa..db050a1f1f3732a6bc4b99809ccb977b645d1524 100644 (file)
@@ -78,10 +78,10 @@ static int spi_nor_params_show(struct seq_file *s, void *data)
        struct spi_nor *nor = s->private;
        struct spi_nor_flash_parameter *params = nor->params;
        struct spi_nor_erase_map *erase_map = &params->erase_map;
-       struct spi_nor_erase_region *region;
+       struct spi_nor_erase_region *region = erase_map->regions;
        const struct flash_info *info = nor->info;
        char buf[16], *str;
-       int i;
+       unsigned int i;
 
        seq_printf(s, "name\t\t%s\n", info->name);
        seq_printf(s, "id\t\t%*ph\n", SPI_NOR_MAX_ID_LEN, nor->id);
@@ -144,13 +144,11 @@ static int spi_nor_params_show(struct seq_file *s, void *data)
        seq_puts(s, "\nsector map\n");
        seq_puts(s, " region (in hex)   | erase mask | flags\n");
        seq_puts(s, " ------------------+------------+----------\n");
-       for (region = erase_map->regions;
-            region;
-            region = spi_nor_region_next(region)) {
-               u64 start = region->offset;
-               u64 end = start + region->size - 1;
-               u8 erase_mask = region->erase_mask;
-               u8 flags = region->flags;
+       for (i = 0; i < erase_map->n_regions; i++) {
+               u64 start = region[i].offset;
+               u64 end = start + region[i].size - 1;
+               u8 erase_mask = region[i].erase_mask;
+               u8 flags = region[i].flags;
 
                seq_printf(s, " %08llx-%08llx |     [%c%c%c%c] | %s\n",
                           start, end,
index 3cf1db6e4026d862f585889fd0574a8b3d33dea4..8d83580207d51b40214922a7bb63972a090334eb 100644 (file)
@@ -390,15 +390,14 @@ static void spi_nor_regions_sort_erase_types(struct spi_nor_erase_map *map)
 {
        struct spi_nor_erase_region *region = map->regions;
        u8 sorted_erase_mask;
+       unsigned int i;
 
-       while (region) {
-               sorted_erase_mask = spi_nor_sort_erase_mask(map,
-                                                           region->erase_mask);
+       for (i = 0; i < map->n_regions; i++) {
+               sorted_erase_mask =
+                       spi_nor_sort_erase_mask(map, region[i].erase_mask);
 
                /* Overwrite erase mask. */
-               region->erase_mask = sorted_erase_mask;
-
-               region = spi_nor_region_next(region);
+               region[i].erase_mask = sorted_erase_mask;
        }
 }
 
@@ -801,11 +800,6 @@ out:
        return ret;
 }
 
-static void spi_nor_region_mark_end(struct spi_nor_erase_region *region)
-{
-       region->flags |= SNOR_LAST_REGION;
-}
-
 static void spi_nor_region_mark_overlay(struct spi_nor_erase_region *region)
 {
        region->flags |= SNOR_OVERLAID_REGION;
@@ -863,6 +857,7 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
        if (!region)
                return -ENOMEM;
        map->regions = region;
+       map->n_regions = region_count;
 
        uniform_erase_type = 0xff;
        regions_erase_type = 0;
@@ -891,7 +886,6 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
 
                offset = region[i].offset + region[i].size;
        }
-       spi_nor_region_mark_end(&region[i - 1]);
 
        save_uniform_erase_type = map->uniform_region.erase_mask;
        map->uniform_region.erase_mask =