Commit da59f180 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mtd/fixes-for-4.20-rc5' of git://git.infradead.org/linux-mtd

Pull mtd fixes from Boris Brezillon:
 "NAND fix:
   - Fix BBT cache allocation done in nanddev_bbt_init()

  SPI NOR fixes:
   - Fix the erase type selection logic"

* tag 'mtd/fixes-for-4.20-rc5' of git://git.infradead.org/linux-mtd:
  mtd: nand: Fix memory allocation in nanddev_bbt_init()
  mtd: spi-nor: fix erase_type array to indicate current map conf
parents b1286ed7 40b41289
...@@ -27,7 +27,8 @@ int nanddev_bbt_init(struct nand_device *nand) ...@@ -27,7 +27,8 @@ int nanddev_bbt_init(struct nand_device *nand)
unsigned int nwords = DIV_ROUND_UP(nblocks * bits_per_block, unsigned int nwords = DIV_ROUND_UP(nblocks * bits_per_block,
BITS_PER_LONG); BITS_PER_LONG);
nand->bbt.cache = kzalloc(nwords, GFP_KERNEL); nand->bbt.cache = kcalloc(nwords, sizeof(*nand->bbt.cache),
GFP_KERNEL);
if (!nand->bbt.cache) if (!nand->bbt.cache)
return -ENOMEM; return -ENOMEM;
......
...@@ -2995,12 +2995,13 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, ...@@ -2995,12 +2995,13 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
const u32 *smpt) const u32 *smpt)
{ {
struct spi_nor_erase_map *map = &nor->erase_map; struct spi_nor_erase_map *map = &nor->erase_map;
const struct spi_nor_erase_type *erase = map->erase_type; struct spi_nor_erase_type *erase = map->erase_type;
struct spi_nor_erase_region *region; struct spi_nor_erase_region *region;
u64 offset; u64 offset;
u32 region_count; u32 region_count;
int i, j; int i, j;
u8 erase_type, uniform_erase_type; u8 uniform_erase_type, save_uniform_erase_type;
u8 erase_type, regions_erase_type;
region_count = SMPT_MAP_REGION_COUNT(*smpt); region_count = SMPT_MAP_REGION_COUNT(*smpt);
/* /*
...@@ -3014,6 +3015,7 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, ...@@ -3014,6 +3015,7 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
map->regions = region; map->regions = region;
uniform_erase_type = 0xff; uniform_erase_type = 0xff;
regions_erase_type = 0;
offset = 0; offset = 0;
/* Populate regions. */ /* Populate regions. */
for (i = 0; i < region_count; i++) { for (i = 0; i < region_count; i++) {
...@@ -3030,13 +3032,38 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor, ...@@ -3030,13 +3032,38 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
*/ */
uniform_erase_type &= erase_type; uniform_erase_type &= erase_type;
/*
* regions_erase_type mask will indicate all the erase types
* supported in this configuration map.
*/
regions_erase_type |= erase_type;
offset = (region[i].offset & ~SNOR_ERASE_FLAGS_MASK) + offset = (region[i].offset & ~SNOR_ERASE_FLAGS_MASK) +
region[i].size; region[i].size;
} }
save_uniform_erase_type = map->uniform_erase_type;
map->uniform_erase_type = spi_nor_sort_erase_mask(map, map->uniform_erase_type = spi_nor_sort_erase_mask(map,
uniform_erase_type); uniform_erase_type);
if (!regions_erase_type) {
/*
* Roll back to the previous uniform_erase_type mask, SMPT is
* broken.
*/
map->uniform_erase_type = save_uniform_erase_type;
return -EINVAL;
}
/*
* BFPT advertises all the erase types supported by all the possible
* map configurations. Mask out the erase types that are not supported
* by the current map configuration.
*/
for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++)
if (!(regions_erase_type & BIT(erase[i].idx)))
spi_nor_set_erase_type(&erase[i], 0, 0xFF);
spi_nor_region_mark_end(&region[i - 1]); spi_nor_region_mark_end(&region[i - 1]);
return 0; return 0;
......
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