[PATCH v4 09/24] mtd: spinand: more refactoring
Frieder Schrempf
frieder.schrempf at kontron.de
Tue Aug 12 11:45:35 CEST 2025
Suggestion for subject:
mtd: spinand: Refactor ECC/OOB functions
Am 09.08.25 um 03:04 schrieb Mikhail Kshevetskiy:
> changes:
> * Move spinand_check_ecc_status(), spinand_noecc_ooblayout_ecc(),
> spinand_noecc_ooblayout_free() and spinand_noecc_ooblayout close
> to each other.
> * some code formatting
> * remove comments not present in linux driver
>
> This make code more close to linux-6.10 kernel driver
Nitpick: "This aligns the code with Linux 6.10."
With the subject line improved:
Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
>
> Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy at iopsys.eu>
> ---
> drivers/mtd/nand/spi/core.c | 115 +++++++++++++++++-------------------
> 1 file changed, 55 insertions(+), 60 deletions(-)
>
> diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
> index df59d3d23ce..a6353b37e7f 100644
> --- a/drivers/mtd/nand/spi/core.c
> +++ b/drivers/mtd/nand/spi/core.c
> @@ -222,6 +222,59 @@ static int spinand_ecc_enable(struct spinand_device *spinand,
> enable ? CFG_ECC_ENABLE : 0);
> }
>
> +static int spinand_check_ecc_status(struct spinand_device *spinand, u8 status)
> +{
> + struct nand_device *nand = spinand_to_nand(spinand);
> +
> + if (spinand->eccinfo.get_status)
> + return spinand->eccinfo.get_status(spinand, status);
> +
> + switch (status & STATUS_ECC_MASK) {
> + case STATUS_ECC_NO_BITFLIPS:
> + return 0;
> +
> + case STATUS_ECC_HAS_BITFLIPS:
> + /*
> + * We have no way to know exactly how many bitflips have been
> + * fixed, so let's return the maximum possible value so that
> + * wear-leveling layers move the data immediately.
> + */
> + return nand->eccreq.strength;
> +
> + case STATUS_ECC_UNCOR_ERROR:
> + return -EBADMSG;
> +
> + default:
> + break;
> + }
> +
> + return -EINVAL;
> +}
> +
> +static int spinand_noecc_ooblayout_ecc(struct mtd_info *mtd, int section,
> + struct mtd_oob_region *region)
> +{
> + return -ERANGE;
> +}
> +
> +static int spinand_noecc_ooblayout_free(struct mtd_info *mtd, int section,
> + struct mtd_oob_region *region)
> +{
> + if (section)
> + return -ERANGE;
> +
> + /* Reserve 2 bytes for the BBM. */
> + region->offset = 2;
> + region->length = 62;
> +
> + return 0;
> +}
> +
> +static const struct mtd_ooblayout_ops spinand_noecc_ooblayout = {
> + .ecc = spinand_noecc_ooblayout_ecc,
> + .rfree = spinand_noecc_ooblayout_free,
> +};
> +
> static int spinand_write_enable_op(struct spinand_device *spinand)
> {
> struct spi_mem_op op = SPINAND_WR_EN_DIS_OP(true);
> @@ -413,9 +466,8 @@ out:
> static int spinand_read_id_op(struct spinand_device *spinand, u8 naddr,
> u8 ndummy, u8 *buf)
> {
> - struct spi_mem_op op = SPINAND_READID_OP(naddr, ndummy,
> - spinand->scratchbuf,
> - SPINAND_MAX_ID_LEN);
> + struct spi_mem_op op = SPINAND_READID_OP(
> + naddr, ndummy, spinand->scratchbuf, SPINAND_MAX_ID_LEN);
> int ret;
>
> ret = spi_mem_exec_op(spinand->slave, &op);
> @@ -445,35 +497,6 @@ static int spinand_lock_block(struct spinand_device *spinand, u8 lock)
> return spinand_write_reg_op(spinand, REG_BLOCK_LOCK, lock);
> }
>
> -static int spinand_check_ecc_status(struct spinand_device *spinand, u8 status)
> -{
> - struct nand_device *nand = spinand_to_nand(spinand);
> -
> - if (spinand->eccinfo.get_status)
> - return spinand->eccinfo.get_status(spinand, status);
> -
> - switch (status & STATUS_ECC_MASK) {
> - case STATUS_ECC_NO_BITFLIPS:
> - return 0;
> -
> - case STATUS_ECC_HAS_BITFLIPS:
> - /*
> - * We have no way to know exactly how many bitflips have been
> - * fixed, so let's return the maximum possible value so that
> - * wear-leveling layers move the data immediately.
> - */
> - return nand->eccreq.strength;
> -
> - case STATUS_ECC_UNCOR_ERROR:
> - return -EBADMSG;
> -
> - default:
> - break;
> - }
> -
> - return -EINVAL;
> -}
> -
> static int spinand_read_page(struct spinand_device *spinand,
> const struct nand_page_io_req *req,
> bool ecc_enabled)
> @@ -1074,30 +1097,6 @@ static int spinand_detect(struct spinand_device *spinand)
> return 0;
> }
>
> -static int spinand_noecc_ooblayout_ecc(struct mtd_info *mtd, int section,
> - struct mtd_oob_region *region)
> -{
> - return -ERANGE;
> -}
> -
> -static int spinand_noecc_ooblayout_free(struct mtd_info *mtd, int section,
> - struct mtd_oob_region *region)
> -{
> - if (section)
> - return -ERANGE;
> -
> - /* Reserve 2 bytes for the BBM. */
> - region->offset = 2;
> - region->length = 62;
> -
> - return 0;
> -}
> -
> -static const struct mtd_ooblayout_ops spinand_noecc_ooblayout = {
> - .ecc = spinand_noecc_ooblayout_ecc,
> - .rfree = spinand_noecc_ooblayout_free,
> -};
> -
> static int spinand_init_flash(struct spinand_device *spinand)
> {
> struct udevice *dev = spinand->slave->dev;
> @@ -1187,10 +1186,6 @@ static int spinand_init(struct spinand_device *spinand)
> if (ret)
> goto err_manuf_cleanup;
>
> - /*
> - * Right now, we don't support ECC, so let the whole oob
> - * area is available for user.
> - */
> mtd->_read_oob = spinand_mtd_read;
> mtd->_write_oob = spinand_mtd_write;
> mtd->_block_isbad = spinand_mtd_block_isbad;
More information about the U-Boot
mailing list