summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>2023-01-10 12:58:39 +0100
committerDario Binacchi <dario.binacchi@amarulasolutions.com>2023-10-13 10:49:07 +0200
commit2572470c8935d18ca4ddb8f65465e9b48f41e1e3 (patch)
tree7a7f8a0248769d56a8aa90e2c2994d71492e4379
parentb20913e3cbc81daa2463c1bd812e568181f6a60a (diff)
mtd/spinand: sync core spinand code with linux-5.10.118
This brings us closer to the current Linux kernel implementation of the spinand core and makes backporting features and fixes easier. This does not include the latest kernel implementation as this would require a substantial amount of extra work due to the missing ECC engine abstraction layer in U-Boot. Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu> Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de> (add commit message) Link: https://lore.kernel.org/all/20230110115843.391630-2-frieder@fris.de Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
-rw-r--r--drivers/mtd/nand/spi/core.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 597125c6a3e..b3f21ba0229 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -327,6 +327,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));
@@ -599,12 +606,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;
}
@@ -670,16 +677,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;
@@ -723,6 +723,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);
}