Commit da59f180 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -27,7 +27,8 @@ int nanddev_bbt_init(struct nand_device *nand)
	unsigned int nwords = DIV_ROUND_UP(nblocks * bits_per_block,
					   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)
		return -ENOMEM;

+29 −2
Original line number Diff line number Diff line
@@ -2995,12 +2995,13 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
					      const u32 *smpt)
{
	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;
	u64 offset;
	u32 region_count;
	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);
	/*
@@ -3014,6 +3015,7 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
	map->regions = region;

	uniform_erase_type = 0xff;
	regions_erase_type = 0;
	offset = 0;
	/* Populate regions. */
	for (i = 0; i < region_count; i++) {
@@ -3030,13 +3032,38 @@ static int spi_nor_init_non_uniform_erase_map(struct spi_nor *nor,
		 */
		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) +
			 region[i].size;
	}

	save_uniform_erase_type = map->uniform_erase_type;
	map->uniform_erase_type = spi_nor_sort_erase_mask(map,
							  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]);

	return 0;