Skip to content

Commit 6d9d6ab

Browse files
Kuwano-sanmiquelraynal
authored andcommitted
mtd: spinand: Introduce a way to avoid raw access
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. In such devices, the on-die ECC engine ops returns error to I/O request in raw mode. Checking and marking BBM need to be cared as special case, by adding fallback mechanism that tries read/write OOB with ECC enabled. Signed-off-by: Takahiro Kuwano <[email protected]> Signed-off-by: Miquel Raynal <[email protected]>
1 parent c685877 commit 6d9d6ab

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

drivers/mtd/nand/spi/core.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,9 @@ static int spinand_ondie_ecc_prepare_io_req(struct nand_device *nand,
294294
struct spinand_device *spinand = nand_to_spinand(nand);
295295
bool enable = (req->mode != MTD_OPS_RAW);
296296

297+
if (!enable && spinand->flags & SPINAND_NO_RAW_ACCESS)
298+
return -EOPNOTSUPP;
299+
297300
memset(spinand->oobbuf, 0xff, nanddev_per_page_oobsize(nand));
298301

299302
/* Only enable or disable the engine */
@@ -901,9 +904,17 @@ static bool spinand_isbad(struct nand_device *nand, const struct nand_pos *pos)
901904
.oobbuf.in = marker,
902905
.mode = MTD_OPS_RAW,
903906
};
907+
int ret;
904908

905909
spinand_select_target(spinand, pos->target);
906-
spinand_read_page(spinand, &req);
910+
911+
ret = spinand_read_page(spinand, &req);
912+
if (ret == -EOPNOTSUPP) {
913+
/* Retry with ECC in case raw access is not supported */
914+
req.mode = MTD_OPS_PLACE_OOB;
915+
spinand_read_page(spinand, &req);
916+
}
917+
907918
if (marker[0] != 0xff || marker[1] != 0xff)
908919
return true;
909920

@@ -942,7 +953,14 @@ static int spinand_markbad(struct nand_device *nand, const struct nand_pos *pos)
942953
if (ret)
943954
return ret;
944955

945-
return spinand_write_page(spinand, &req);
956+
ret = spinand_write_page(spinand, &req);
957+
if (ret == -EOPNOTSUPP) {
958+
/* Retry with ECC in case raw access is not supported */
959+
req.mode = MTD_OPS_PLACE_OOB;
960+
ret = spinand_write_page(spinand, &req);
961+
}
962+
963+
return ret;
946964
}
947965

948966
static int spinand_mtd_block_markbad(struct mtd_info *mtd, loff_t offs)

include/linux/mtd/spinand.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ struct spinand_ecc_info {
314314
#define SPINAND_HAS_CR_FEAT_BIT BIT(1)
315315
#define SPINAND_HAS_PROG_PLANE_SELECT_BIT BIT(2)
316316
#define SPINAND_HAS_READ_PLANE_SELECT_BIT BIT(3)
317+
#define SPINAND_NO_RAW_ACCESS BIT(4)
317318

318319
/**
319320
* struct spinand_ondie_ecc_conf - private SPI-NAND on-die ECC engine structure

0 commit comments

Comments
 (0)