Skip to content

Commit 0e16423

Browse files
Kuwano-sanambarus
authored andcommitted
mtd: spi-nor: core: rework struct spi_nor_erase_region
Encoding bitmask flags into offset worsen the code readability. The erase type mask and flags should be stored in dedicated members. Also, erase_map.uniform_erase_type can be removed as it is redundant. Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com> Suggested-by: Michael Walle <mwalle@kernel.org> Reviewed-by: Michael Walle <mwalle@kernel.org> Link: https://lore.kernel.org/r/8e5e9e4081ed9f16ea9dce30693304a4b54d19b1.1708404584.git.Takahiro.Kuwano@infineon.com [ta: remove spi_nor_region_end()] Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
1 parent a956502 commit 0e16423

File tree

4 files changed

+46
-67
lines changed

4 files changed

+46
-67
lines changed

drivers/mtd/spi-nor/core.c

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,7 @@ static u8 spi_nor_convert_3to4_erase(u8 opcode)
11581158

11591159
static bool spi_nor_has_uniform_erase(const struct spi_nor *nor)
11601160
{
1161-
return !!nor->params->erase_map.uniform_erase_type;
1161+
return !!nor->params->erase_map.uniform_region.erase_mask;
11621162
}
11631163

11641164
static void spi_nor_set_4byte_opcodes(struct spi_nor *nor)
@@ -1542,23 +1542,22 @@ spi_nor_find_best_erase_type(const struct spi_nor_erase_map *map,
15421542
const struct spi_nor_erase_type *erase;
15431543
u32 rem;
15441544
int i;
1545-
u8 erase_mask = region->offset & SNOR_ERASE_TYPE_MASK;
15461545

15471546
/*
15481547
* Erase types are ordered by size, with the smallest erase type at
15491548
* index 0.
15501549
*/
15511550
for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) {
15521551
/* Does the erase region support the tested erase type? */
1553-
if (!(erase_mask & BIT(i)))
1552+
if (!(region->erase_mask & BIT(i)))
15541553
continue;
15551554

15561555
erase = &map->erase_type[i];
15571556
if (!erase->size)
15581557
continue;
15591558

15601559
/* Alignment is not mandatory for overlaid regions */
1561-
if (region->offset & SNOR_OVERLAID_REGION &&
1560+
if (region->flags & SNOR_OVERLAID_REGION &&
15621561
region->size <= len)
15631562
return erase;
15641563

@@ -1576,12 +1575,7 @@ spi_nor_find_best_erase_type(const struct spi_nor_erase_map *map,
15761575

15771576
static u64 spi_nor_region_is_last(const struct spi_nor_erase_region *region)
15781577
{
1579-
return region->offset & SNOR_LAST_REGION;
1580-
}
1581-
1582-
static u64 spi_nor_region_end(const struct spi_nor_erase_region *region)
1583-
{
1584-
return (region->offset & ~SNOR_ERASE_FLAGS_MASK) + region->size;
1578+
return region->flags & SNOR_LAST_REGION;
15851579
}
15861580

15871581
/**
@@ -1612,16 +1606,14 @@ static struct spi_nor_erase_region *
16121606
spi_nor_find_erase_region(const struct spi_nor_erase_map *map, u64 addr)
16131607
{
16141608
struct spi_nor_erase_region *region = map->regions;
1615-
u64 region_start = region->offset & ~SNOR_ERASE_FLAGS_MASK;
1616-
u64 region_end = region_start + region->size;
1609+
u64 region_end = region->offset + region->size;
16171610

1618-
while (addr < region_start || addr >= region_end) {
1611+
while (addr < region->offset || addr >= region_end) {
16191612
region = spi_nor_region_next(region);
16201613
if (!region)
16211614
return ERR_PTR(-EINVAL);
16221615

1623-
region_start = region->offset & ~SNOR_ERASE_FLAGS_MASK;
1624-
region_end = region_start + region->size;
1616+
region_end = region->offset + region->size;
16251617
}
16261618

16271619
return region;
@@ -1649,7 +1641,7 @@ spi_nor_init_erase_cmd(const struct spi_nor_erase_region *region,
16491641
cmd->opcode = erase->opcode;
16501642
cmd->count = 1;
16511643

1652-
if (region->offset & SNOR_OVERLAID_REGION)
1644+
if (region->flags & SNOR_OVERLAID_REGION)
16531645
cmd->size = region->size;
16541646
else
16551647
cmd->size = erase->size;
@@ -1699,7 +1691,7 @@ static int spi_nor_init_erase_cmd_list(struct spi_nor *nor,
16991691
if (IS_ERR(region))
17001692
return PTR_ERR(region);
17011693

1702-
region_end = spi_nor_region_end(region);
1694+
region_end = region->offset + region->size;
17031695

17041696
while (len) {
17051697
erase = spi_nor_find_best_erase_type(map, region, addr, len);
@@ -1708,7 +1700,7 @@ static int spi_nor_init_erase_cmd_list(struct spi_nor *nor,
17081700

17091701
if (prev_erase != erase ||
17101702
erase->size != cmd->size ||
1711-
region->offset & SNOR_OVERLAID_REGION) {
1703+
region->flags & SNOR_OVERLAID_REGION) {
17121704
cmd = spi_nor_init_erase_cmd(region, erase);
17131705
if (IS_ERR(cmd)) {
17141706
ret = PTR_ERR(cmd);
@@ -1727,7 +1719,7 @@ static int spi_nor_init_erase_cmd_list(struct spi_nor *nor,
17271719
region = spi_nor_region_next(region);
17281720
if (!region)
17291721
goto destroy_erase_cmd_list;
1730-
region_end = spi_nor_region_end(region);
1722+
region_end = region->offset + region->size;
17311723
}
17321724

17331725
prev_erase = erase;
@@ -2468,12 +2460,11 @@ void spi_nor_mask_erase_type(struct spi_nor_erase_type *erase)
24682460
void spi_nor_init_uniform_erase_map(struct spi_nor_erase_map *map,
24692461
u8 erase_mask, u64 flash_size)
24702462
{
2471-
/* Offset 0 with erase_mask and SNOR_LAST_REGION bit set */
2472-
map->uniform_region.offset = (erase_mask & SNOR_ERASE_TYPE_MASK) |
2473-
SNOR_LAST_REGION;
2463+
map->uniform_region.offset = 0;
24742464
map->uniform_region.size = flash_size;
2465+
map->uniform_region.erase_mask = erase_mask;
2466+
map->uniform_region.flags = SNOR_LAST_REGION;
24752467
map->regions = &map->uniform_region;
2476-
map->uniform_erase_type = erase_mask;
24772468
}
24782469

24792470
int spi_nor_post_bfpt_fixups(struct spi_nor *nor,
@@ -2560,7 +2551,7 @@ spi_nor_select_uniform_erase(struct spi_nor_erase_map *map)
25602551
{
25612552
const struct spi_nor_erase_type *tested_erase, *erase = NULL;
25622553
int i;
2563-
u8 uniform_erase_type = map->uniform_erase_type;
2554+
u8 uniform_erase_type = map->uniform_region.erase_mask;
25642555

25652556
/*
25662557
* Search for the biggest erase size, except for when compiled
@@ -2599,8 +2590,7 @@ spi_nor_select_uniform_erase(struct spi_nor_erase_map *map)
25992590
return NULL;
26002591

26012592
/* Disable all other Sector Erase commands. */
2602-
map->uniform_erase_type &= ~SNOR_ERASE_TYPE_MASK;
2603-
map->uniform_erase_type |= BIT(erase - map->erase_type);
2593+
map->uniform_region.erase_mask = BIT(erase - map->erase_type);
26042594
return erase;
26052595
}
26062596

drivers/mtd/spi-nor/core.h

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -240,27 +240,25 @@ struct spi_nor_erase_command {
240240
/**
241241
* struct spi_nor_erase_region - Structure to describe a SPI NOR erase region
242242
* @offset: the offset in the data array of erase region start.
243-
* LSB bits are used as a bitmask encoding flags to
244-
* determine if this region is overlaid, if this region is
245-
* the last in the SPI NOR flash memory and to indicate
246-
* all the supported erase commands inside this region.
247-
* The erase types are sorted in ascending order with the
248-
* smallest Erase Type size being at BIT(0).
249243
* @size: the size of the region in bytes.
244+
* @erase_mask: bitmask to indicate all the supported erase commands
245+
* inside this region. The erase types are sorted in
246+
* ascending order with the smallest Erase Type size being
247+
* at BIT(0).
248+
* @flags: flags to determine if this region is overlaid, if this
249+
* region is the last in the SPI NOR flash memory
250250
*/
251251
struct spi_nor_erase_region {
252252
u64 offset;
253253
u64 size;
254+
u8 erase_mask;
255+
u8 flags;
254256
};
255257

256258
#define SNOR_ERASE_TYPE_MAX 4
257-
#define SNOR_ERASE_TYPE_MASK GENMASK_ULL(SNOR_ERASE_TYPE_MAX - 1, 0)
258259

259-
#define SNOR_LAST_REGION BIT(4)
260-
#define SNOR_OVERLAID_REGION BIT(5)
261-
262-
#define SNOR_ERASE_FLAGS_MAX 6
263-
#define SNOR_ERASE_FLAGS_MASK GENMASK_ULL(SNOR_ERASE_FLAGS_MAX - 1, 0)
260+
#define SNOR_LAST_REGION BIT(0)
261+
#define SNOR_OVERLAID_REGION BIT(1)
264262

265263
/**
266264
* struct spi_nor_erase_map - Structure to describe the SPI NOR erase map
@@ -273,17 +271,11 @@ struct spi_nor_erase_region {
273271
* The erase types are sorted in ascending order, with the
274272
* smallest Erase Type size being the first member in the
275273
* erase_type array.
276-
* @uniform_erase_type: bitmask encoding erase types that can erase the
277-
* entire memory. This member is completed at init by
278-
* uniform and non-uniform SPI NOR flash memories if they
279-
* support at least one erase type that can erase the
280-
* entire memory.
281274
*/
282275
struct spi_nor_erase_map {
283276
struct spi_nor_erase_region *regions;
284277
struct spi_nor_erase_region uniform_region;
285278
struct spi_nor_erase_type erase_type[SNOR_ERASE_TYPE_MAX];
286-
u8 uniform_erase_type;
287279
};
288280

289281
/**

drivers/mtd/spi-nor/debugfs.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,16 +147,17 @@ static int spi_nor_params_show(struct seq_file *s, void *data)
147147
for (region = erase_map->regions;
148148
region;
149149
region = spi_nor_region_next(region)) {
150-
u64 start = region->offset & ~SNOR_ERASE_FLAGS_MASK;
151-
u64 flags = region->offset & SNOR_ERASE_FLAGS_MASK;
150+
u64 start = region->offset;
152151
u64 end = start + region->size - 1;
152+
u8 erase_mask = region->erase_mask;
153+
u8 flags = region->flags;
153154

154155
seq_printf(s, " %08llx-%08llx | [%c%c%c%c] | %s\n",
155156
start, end,
156-
flags & BIT(0) ? '0' : ' ',
157-
flags & BIT(1) ? '1' : ' ',
158-
flags & BIT(2) ? '2' : ' ',
159-
flags & BIT(3) ? '3' : ' ',
157+
erase_mask & BIT(0) ? '0' : ' ',
158+
erase_mask & BIT(1) ? '1' : ' ',
159+
erase_mask & BIT(2) ? '2' : ' ',
160+
erase_mask & BIT(3) ? '3' : ' ',
160161
flags & SNOR_OVERLAID_REGION ? "overlaid" : "");
161162
}
162163

drivers/mtd/spi-nor/sfdp.c

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -389,17 +389,14 @@ static u8 spi_nor_sort_erase_mask(struct spi_nor_erase_map *map, u8 erase_mask)
389389
static void spi_nor_regions_sort_erase_types(struct spi_nor_erase_map *map)
390390
{
391391
struct spi_nor_erase_region *region = map->regions;
392-
u8 region_erase_mask, sorted_erase_mask;
392+
u8 sorted_erase_mask;
393393

394394
while (region) {
395-
region_erase_mask = region->offset & SNOR_ERASE_TYPE_MASK;
396-
397395
sorted_erase_mask = spi_nor_sort_erase_mask(map,
398-
region_erase_mask);
396+
region->erase_mask);
399397

400398
/* Overwrite erase mask. */
401-
region->offset = (region->offset & ~SNOR_ERASE_TYPE_MASK) |
402-
sorted_erase_mask;
399+
region->erase_mask = sorted_erase_mask;
403400

404401
region = spi_nor_region_next(region);
405402
}
@@ -554,8 +551,6 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
554551
* selecting the uniform erase.
555552
*/
556553
spi_nor_regions_sort_erase_types(map);
557-
map->uniform_erase_type = map->uniform_region.offset &
558-
SNOR_ERASE_TYPE_MASK;
559554

560555
/* Stop here if not JESD216 rev A or later. */
561556
if (bfpt_header->length == BFPT_DWORD_MAX_JESD216)
@@ -808,12 +803,12 @@ static const u32 *spi_nor_get_map_in_use(struct spi_nor *nor, const u32 *smpt,
808803

809804
static void spi_nor_region_mark_end(struct spi_nor_erase_region *region)
810805
{
811-
region->offset |= SNOR_LAST_REGION;
806+
region->flags |= SNOR_LAST_REGION;
812807
}
813808

814809
static void spi_nor_region_mark_overlay(struct spi_nor_erase_region *region)
815810
{
816-
region->offset |= SNOR_OVERLAID_REGION;
811+
region->flags |= SNOR_OVERLAID_REGION;
817812
}
818813

819814
/**
@@ -875,9 +870,10 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
875870
/* Populate regions. */
876871
for (i = 0; i < region_count; i++) {
877872
j = i + 1; /* index for the region dword */
873+
region[i].offset = offset;
878874
region[i].size = SMPT_MAP_REGION_SIZE(smpt[j]);
879875
erase_type = SMPT_MAP_REGION_ERASE_TYPE(smpt[j]);
880-
region[i].offset = offset | erase_type;
876+
region[i].erase_mask = erase_type;
881877

882878
spi_nor_region_check_overlay(&region[i], erase, erase_type);
883879

@@ -893,21 +889,21 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
893889
*/
894890
regions_erase_type |= erase_type;
895891

896-
offset = (region[i].offset & ~SNOR_ERASE_FLAGS_MASK) +
897-
region[i].size;
892+
offset = region[i].offset + region[i].size;
898893
}
899894
spi_nor_region_mark_end(&region[i - 1]);
900895

901-
save_uniform_erase_type = map->uniform_erase_type;
902-
map->uniform_erase_type = spi_nor_sort_erase_mask(map,
903-
uniform_erase_type);
896+
save_uniform_erase_type = map->uniform_region.erase_mask;
897+
map->uniform_region.erase_mask =
898+
spi_nor_sort_erase_mask(map,
899+
uniform_erase_type);
904900

905901
if (!regions_erase_type) {
906902
/*
907903
* Roll back to the previous uniform_erase_type mask, SMPT is
908904
* broken.
909905
*/
910-
map->uniform_erase_type = save_uniform_erase_type;
906+
map->uniform_region.erase_mask = save_uniform_erase_type;
911907
return -EINVAL;
912908
}
913909

0 commit comments

Comments
 (0)