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

Merge tag 'mtd/fixes-for-6.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux

Pull MTD fixes from Miquel Raynal:
 "In the raw NAND subsystem, the major fix prevents using cached reads
  with devices not supporting it. There was two bug reports about this.

  Apart from that, three drivers (pl353, arasan and marvell) could
  sometimes hide page program failures due to their their own program
  page helper not being fully compliant with the specification (many
  drivers use the default helpers shared by the core). Adding a missing
  check prevents these situation.

  Finally, the Qualcomm driver had a broken error path.

  In the SPI-NAND subsystem one Micron device used a wrong bitmak
  reporting possibly corrupted ECC status.

  Finally, the physmap-core got stripped from its map_rom fallback by
  mistake, this feature is added back"

* tag 'mtd/fixes-for-6.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux:
  mtd: rawnand: Ensure the nand chip supports cached reads
  mtd: rawnand: qcom: Unmap the right resource upon probe failure
  mtd: rawnand: pl353: Ensure program page operations are successful
  mtd: rawnand: arasan: Ensure program page operations are successful
  mtd: spinand: micron: correct bitmask for ecc status
  mtd: physmap-core: Restore map_rom fallback
  mtd: rawnand: marvell: Ensure program page operations are successful
parents 7da6c042 f6ca3fb6
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -551,6 +551,17 @@ static int physmap_flash_probe(struct platform_device *dev)
		if (info->probe_type) {
			info->mtds[i] = do_map_probe(info->probe_type,
						     &info->maps[i]);

			/* Fall back to mapping region as ROM */
			if (!info->mtds[i] && IS_ENABLED(CONFIG_MTD_ROM) &&
			    strcmp(info->probe_type, "map_rom")) {
				dev_warn(&dev->dev,
					 "map_probe() failed for type %s\n",
					 info->probe_type);

				info->mtds[i] = do_map_probe("map_rom",
							     &info->maps[i]);
			}
		} else {
			int j;

+14 −2
Original line number Diff line number Diff line
@@ -515,6 +515,7 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
	struct mtd_info *mtd = nand_to_mtd(chip);
	unsigned int len = mtd->writesize + (oob_required ? mtd->oobsize : 0);
	dma_addr_t dma_addr;
	u8 status;
	int ret;
	struct anfc_op nfc_op = {
		.pkt_reg =
@@ -561,10 +562,21 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
	}

	/* Spare data is not protected */
	if (oob_required)
	if (oob_required) {
		ret = nand_write_oob_std(chip, page);
		if (ret)
			return ret;
	}

	/* Check write status on the chip side */
	ret = nand_status_op(chip, &status);
	if (ret)
		return ret;

	if (status & NAND_STATUS_FAIL)
		return -EIO;

	return 0;
}

static int anfc_sel_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
+22 −1
Original line number Diff line number Diff line
@@ -1165,6 +1165,7 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip,
		.ndcb[2] = NDCB2_ADDR5_PAGE(page),
	};
	unsigned int oob_bytes = lt->spare_bytes + (raw ? lt->ecc_bytes : 0);
	u8 status;
	int ret;

	/* NFCv2 needs more information about the operation being executed */
@@ -1198,7 +1199,18 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip,

	ret = marvell_nfc_wait_op(chip,
				  PSEC_TO_MSEC(sdr->tPROG_max));
	if (ret)
		return ret;

	/* Check write status on the chip side */
	ret = nand_status_op(chip, &status);
	if (ret)
		return ret;

	if (status & NAND_STATUS_FAIL)
		return -EIO;

	return 0;
}

static int marvell_nfc_hw_ecc_hmg_write_page_raw(struct nand_chip *chip,
@@ -1627,6 +1639,7 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip,
	int data_len = lt->data_bytes;
	int spare_len = lt->spare_bytes;
	int chunk, ret;
	u8 status;

	marvell_nfc_select_target(chip, chip->cur_cs);

@@ -1663,6 +1676,14 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip,
	if (ret)
		return ret;

	/* Check write status on the chip side */
	ret = nand_status_op(chip, &status);
	if (ret)
		return ret;

	if (status & NAND_STATUS_FAIL)
		return -EIO;

	return 0;
}

+3 −0
Original line number Diff line number Diff line
@@ -5110,6 +5110,9 @@ static void rawnand_check_cont_read_support(struct nand_chip *chip)
{
	struct mtd_info *mtd = nand_to_mtd(chip);

	if (!chip->parameters.supports_read_cache)
		return;

	if (chip->read_retries)
		return;

+3 −0
Original line number Diff line number Diff line
@@ -94,6 +94,9 @@ int nand_jedec_detect(struct nand_chip *chip)
		goto free_jedec_param_page;
	}

	if (p->opt_cmd[0] & JEDEC_OPT_CMD_READ_CACHE)
		chip->parameters.supports_read_cache = true;

	memorg->pagesize = le32_to_cpu(p->byte_per_page);
	mtd->writesize = memorg->pagesize;

Loading