[PATCH 1/2] mtd: spinand: Introduce a way to avoid raw access

tkuw584924 at gmail.com tkuw584924 at gmail.com
Wed Oct 30 19:21:54 PDT 2024


From: Takahiro Kuwano <Takahiro.Kuwano at infineon.com>

SkyHigh spinand device has ECC enable bit in configuration register but
it must be always enabled. If ECC is disabled, read and write ops
results in undetermined state. For such devices, a way to avoid raw
access is needed.

Introduce SPINAND_NO_RAW_ACCESS flag to advertise the device does not
support raw access. Read and write page in raw mode for the device
returns error.

Checking and marking BBM need to be performed with ECC enabled to read
and write the BBM correctly.

Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano at infineon.com>
---
 drivers/mtd/nand/spi/core.c | 12 ++++++++++++
 include/linux/mtd/spinand.h |  1 +
 2 files changed, 13 insertions(+)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 4d76f9f71a0e..de04f6e7ce1e 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -608,6 +608,9 @@ static int spinand_read_page(struct spinand_device *spinand,
 	u8 status;
 	int ret;
 
+	if (req->mode == MTD_OPS_RAW && spinand->flags & SPINAND_NO_RAW_ACCESS)
+		return -ENOTSUPP;
+
 	ret = nand_ecc_prepare_io_req(nand, (struct nand_page_io_req *)req);
 	if (ret)
 		return ret;
@@ -639,6 +642,9 @@ static int spinand_write_page(struct spinand_device *spinand,
 	u8 status;
 	int ret;
 
+	if (req->mode == MTD_OPS_RAW && spinand->flags & SPINAND_NO_RAW_ACCESS)
+		return -ENOTSUPP;
+
 	ret = nand_ecc_prepare_io_req(nand, (struct nand_page_io_req *)req);
 	if (ret)
 		return ret;
@@ -902,6 +908,9 @@ static bool spinand_isbad(struct nand_device *nand, const struct nand_pos *pos)
 		.mode = MTD_OPS_RAW,
 	};
 
+	if (spinand->flags & SPINAND_NO_RAW_ACCESS)
+		req.mode = MTD_OPS_PLACE_OOB;
+
 	spinand_select_target(spinand, pos->target);
 	spinand_read_page(spinand, &req);
 	if (marker[0] != 0xff || marker[1] != 0xff)
@@ -938,6 +947,9 @@ static int spinand_markbad(struct nand_device *nand, const struct nand_pos *pos)
 	};
 	int ret;
 
+	if (spinand->flags & SPINAND_NO_RAW_ACCESS)
+		req.mode = MTD_OPS_PLACE_OOB;
+
 	ret = spinand_select_target(spinand, pos->target);
 	if (ret)
 		return ret;
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 702e5fb13dae..5cf11005b41a 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -314,6 +314,7 @@ struct spinand_ecc_info {
 #define SPINAND_HAS_CR_FEAT_BIT		BIT(1)
 #define SPINAND_HAS_PROG_PLANE_SELECT_BIT		BIT(2)
 #define SPINAND_HAS_READ_PLANE_SELECT_BIT		BIT(3)
+#define SPINAND_NO_RAW_ACCESS				BIT(4)
 
 /**
  * struct spinand_ondie_ecc_conf - private SPI-NAND on-die ECC engine structure
-- 
2.34.1




More information about the linux-mtd mailing list