diff mbox series

[4/7] mtd/spinand: sync core spinand code with linux-5.10.118

Message ID 20221006031501.110290-4-mikhail.kshevetskiy@iopsys.eu
State Needs Review / ACK, archived
Delegated to: Dario Binacchi
Headers show
Series [1/7] mtd: replace name of 'rfree' field with 'free' in struct mtd_ooblayout_ops to better match it's description | expand

Commit Message

Mikhail Kshevetskiy Oct. 6, 2022, 3:14 a.m. UTC
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>

Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
---
 drivers/mtd/nand/spi/core.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)
diff mbox series

Patch

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index e42c061049..d0c7d82010 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -326,6 +326,13 @@  static int spinand_write_to_cache_op(struct spinand_device *spinand,
 	u16 column = 0;
 	int ret;
 
+	/*
+	 * Looks like PROGRAM LOAD (AKA write cache) does not necessarily reset
+	 * the cache content to 0xFF (depends on vendor implementation), so we
+	 * must fill the page cache entirely even if we only want to program
+	 * the data portion of the page, otherwise we might corrupt the BBM or
+	 * user data previously programmed in OOB area.
+	 */
 	memset(spinand->databuf, 0xff,
 	       nanddev_page_size(nand) +
 	       nanddev_per_page_oobsize(nand));
@@ -598,12 +605,12 @@  static int spinand_mtd_read(struct mtd_info *mtd, loff_t from,
 		if (ret == -EBADMSG) {
 			ecc_failed = true;
 			mtd->ecc_stats.failed++;
-			ret = 0;
 		} else {
 			mtd->ecc_stats.corrected += ret;
 			max_bitflips = max_t(unsigned int, max_bitflips, ret);
 		}
 
+		ret = 0;
 		ops->retlen += iter.req.datalen;
 		ops->oobretlen += iter.req.ooblen;
 	}
@@ -669,16 +676,9 @@  static bool spinand_isbad(struct nand_device *nand, const struct nand_pos *pos)
 		.oobbuf.in = marker,
 		.mode = MTD_OPS_RAW,
 	};
-	int ret;
-
-	ret = spinand_select_target(spinand, pos->target);
-	if (ret)
-		return ret;
-
-	ret = spinand_read_page(spinand, &req, false);
-	if (ret)
-		return ret;
 
+	spinand_select_target(spinand, pos->target);
+	spinand_read_page(spinand, &req, false);
 	if (marker[0] != 0xff || marker[1] != 0xff)
 		return true;
 
@@ -722,6 +722,10 @@  static int spinand_markbad(struct nand_device *nand, const struct nand_pos *pos)
 	if (ret)
 		return ret;
 
+	ret = spinand_write_enable_op(spinand);
+	if (ret)
+		return ret;
+
 	return spinand_write_page(spinand, &req);
 }