Commit b451f5be authored by Miquel Raynal's avatar Miquel Raynal
Browse files

mtd: rawnand: Give the possibility to verify a read operation is supported



This can be used to discriminate between two path in the parameter
page detection: use data_in cycles (like before) if supported, use the
CHANGE READ COLUMN command otherwise.

Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: default avatarBoris Brezillon <boris.brezillon@collabora.com>
Link: https://lore.kernel.org/linux-mtd/20200507105241.14299-9-miquel.raynal@bootlin.com
parent 93037025
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -694,7 +694,7 @@ static int fsmc_read_page_hwecc(struct nand_chip *chip, u8 *buf,
	for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) {
		nand_read_page_op(chip, page, s * eccsize, NULL, 0);
		chip->ecc.hwctl(chip, NAND_ECC_READ);
		ret = nand_read_data_op(chip, p, eccsize, false);
		ret = nand_read_data_op(chip, p, eccsize, false, false);
		if (ret)
			return ret;

+2 −2
Original line number Diff line number Diff line
@@ -1224,12 +1224,12 @@ static int marvell_nfc_hw_ecc_bch_read_page_raw(struct nand_chip *chip, u8 *buf,

		/* Read spare bytes */
		nand_read_data_op(chip, oob + (lt->spare_bytes * chunk),
				  spare_len, false);
				  spare_len, false, false);

		/* Read ECC bytes */
		nand_read_data_op(chip, oob + ecc_offset +
				  (ALIGN(lt->ecc_bytes, 32) * chunk),
				  ecc_len, false);
				  ecc_len, false, false);
	}

	return 0;
+29 −19
Original line number Diff line number Diff line
@@ -740,7 +740,8 @@ int nand_soft_waitrdy(struct nand_chip *chip, unsigned long timeout_ms)
	 */
	timeout_ms = jiffies + msecs_to_jiffies(timeout_ms) + 1;
	do {
		ret = nand_read_data_op(chip, &status, sizeof(status), true);
		ret = nand_read_data_op(chip, &status, sizeof(status), true,
					false);
		if (ret)
			break;

@@ -820,7 +821,7 @@ void panic_nand_wait(struct nand_chip *chip, unsigned long timeo)
			u8 status;

			ret = nand_read_data_op(chip, &status, sizeof(status),
						true);
						true, false);
			if (ret)
				return;

@@ -1918,6 +1919,8 @@ EXPORT_SYMBOL_GPL(nand_reset_op);
 * @buf: buffer used to store the data
 * @len: length of the buffer
 * @force_8bit: force 8-bit bus access
 * @check_only: do not actually run the command, only checks if the
 *              controller driver supports it
 *
 * This function does a raw data read on the bus. Usually used after launching
 * another NAND operation like nand_read_page_op().
@@ -1926,7 +1929,7 @@ EXPORT_SYMBOL_GPL(nand_reset_op);
 * Returns 0 on success, a negative error code otherwise.
 */
int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len,
		      bool force_8bit)
		      bool force_8bit, bool check_only)
{
	if (!len || !buf)
		return -EINVAL;
@@ -1939,9 +1942,15 @@ int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len,

		instrs[0].ctx.data.force_8bit = force_8bit;

		if (check_only)
			return nand_check_op(chip, &op);

		return nand_exec_op(chip, &op);
	}

	if (check_only)
		return 0;

	if (force_8bit) {
		u8 *p = buf;
		unsigned int i;
@@ -2670,7 +2679,7 @@ int nand_read_page_raw(struct nand_chip *chip, uint8_t *buf, int oob_required,

	if (oob_required) {
		ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize,
					false);
					false, false);
		if (ret)
			return ret;
	}
@@ -2702,7 +2711,7 @@ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf,
		return ret;

	for (steps = chip->ecc.steps; steps > 0; steps--) {
		ret = nand_read_data_op(chip, buf, eccsize, false);
		ret = nand_read_data_op(chip, buf, eccsize, false, false);
		if (ret)
			return ret;

@@ -2710,14 +2719,14 @@ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf,

		if (chip->ecc.prepad) {
			ret = nand_read_data_op(chip, oob, chip->ecc.prepad,
						false);
						false, false);
			if (ret)
				return ret;

			oob += chip->ecc.prepad;
		}

		ret = nand_read_data_op(chip, oob, eccbytes, false);
		ret = nand_read_data_op(chip, oob, eccbytes, false, false);
		if (ret)
			return ret;

@@ -2725,7 +2734,7 @@ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf,

		if (chip->ecc.postpad) {
			ret = nand_read_data_op(chip, oob, chip->ecc.postpad,
						false);
						false, false);
			if (ret)
				return ret;

@@ -2735,7 +2744,7 @@ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf,

	size = mtd->oobsize - (oob - chip->oob_poi);
	if (size) {
		ret = nand_read_data_op(chip, oob, size, false);
		ret = nand_read_data_op(chip, oob, size, false, false);
		if (ret)
			return ret;
	}
@@ -2928,14 +2937,15 @@ static int nand_read_page_hwecc(struct nand_chip *chip, uint8_t *buf,
	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
		chip->ecc.hwctl(chip, NAND_ECC_READ);

		ret = nand_read_data_op(chip, p, eccsize, false);
		ret = nand_read_data_op(chip, p, eccsize, false, false);
		if (ret)
			return ret;

		chip->ecc.calculate(chip, p, &ecc_calc[i]);
	}

	ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize, false);
	ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize, false,
				false);
	if (ret)
		return ret;

@@ -3014,7 +3024,7 @@ static int nand_read_page_hwecc_oob_first(struct nand_chip *chip, uint8_t *buf,

		chip->ecc.hwctl(chip, NAND_ECC_READ);

		ret = nand_read_data_op(chip, p, eccsize, false);
		ret = nand_read_data_op(chip, p, eccsize, false, false);
		if (ret)
			return ret;

@@ -3071,13 +3081,13 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf,

		chip->ecc.hwctl(chip, NAND_ECC_READ);

		ret = nand_read_data_op(chip, p, eccsize, false);
		ret = nand_read_data_op(chip, p, eccsize, false, false);
		if (ret)
			return ret;

		if (chip->ecc.prepad) {
			ret = nand_read_data_op(chip, oob, chip->ecc.prepad,
						false);
						false, false);
			if (ret)
				return ret;

@@ -3086,7 +3096,7 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf,

		chip->ecc.hwctl(chip, NAND_ECC_READSYN);

		ret = nand_read_data_op(chip, oob, eccbytes, false);
		ret = nand_read_data_op(chip, oob, eccbytes, false, false);
		if (ret)
			return ret;

@@ -3096,7 +3106,7 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf,

		if (chip->ecc.postpad) {
			ret = nand_read_data_op(chip, oob, chip->ecc.postpad,
						false);
						false, false);
			if (ret)
				return ret;

@@ -3124,7 +3134,7 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf,
	/* Calculate remaining oob bytes */
	i = mtd->oobsize - (oob - chip->oob_poi);
	if (i) {
		ret = nand_read_data_op(chip, oob, i, false);
		ret = nand_read_data_op(chip, oob, i, false, false);
		if (ret)
			return ret;
	}
@@ -3426,7 +3436,7 @@ static int nand_read_oob_syndrome(struct nand_chip *chip, int page)
			sndrnd = 1;
		toread = min_t(int, length, chunk);

		ret = nand_read_data_op(chip, bufpoi, toread, false);
		ret = nand_read_data_op(chip, bufpoi, toread, false, false);
		if (ret)
			return ret;

@@ -3434,7 +3444,7 @@ static int nand_read_oob_syndrome(struct nand_chip *chip, int page)
		length -= toread;
	}
	if (length > 0) {
		ret = nand_read_data_op(chip, bufpoi, length, false);
		ret = nand_read_data_op(chip, bufpoi, length, false, false);
		if (ret)
			return ret;
	}
+1 −1
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ int nand_jedec_detect(struct nand_chip *chip)
	}

	for (i = 0; i < JEDEC_PARAM_PAGES; i++) {
		ret = nand_read_data_op(chip, p, sizeof(*p), true);
		ret = nand_read_data_op(chip, p, sizeof(*p), true, false);
		if (ret) {
			ret = 0;
			goto free_jedec_param_page;
+5 −3
Original line number Diff line number Diff line
@@ -225,7 +225,8 @@ static void nand_wait_status_ready(struct nand_chip *chip, unsigned long timeo)
	do {
		u8 status;

		ret = nand_read_data_op(chip, &status, sizeof(status), true);
		ret = nand_read_data_op(chip, &status, sizeof(status), true,
					false);
		if (ret)
			return;

@@ -552,7 +553,8 @@ static int nand_wait(struct nand_chip *chip)
					break;
			} else {
				ret = nand_read_data_op(chip, &status,
							sizeof(status), true);
							sizeof(status), true,
							false);
				if (ret)
					return ret;

@@ -563,7 +565,7 @@ static int nand_wait(struct nand_chip *chip)
		} while (time_before(jiffies, timeo));
	}

	ret = nand_read_data_op(chip, &status, sizeof(status), true);
	ret = nand_read_data_op(chip, &status, sizeof(status), true, false);
	if (ret)
		return ret;

Loading