Skip to content

Commit

Permalink
mtd: spinand: Move ECC related definitions earlier in the driver
Browse files Browse the repository at this point in the history
Prepare the creation of a SPI-NAND on-die ECC engine by gathering the
ECC-related code earlier enough in the core to avoid the need for
forward declarations.

The next step is to actually create that engine by implementing the
generic ECC interface.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20200930154109.3922-3-miquel.raynal@bootlin.com
  • Loading branch information
Miquel Raynal committed Dec 10, 2020
1 parent 93afb10 commit 55a1a71
Showing 1 changed file with 53 additions and 53 deletions.
106 changes: 53 additions & 53 deletions drivers/mtd/nand/spi/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,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 nanddev_get_ecc_conf(nand)->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,
.free = 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);
Expand Down Expand Up @@ -402,35 +455,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 nanddev_get_ecc_conf(nand)->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)
Expand Down Expand Up @@ -965,30 +989,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,
.free = spinand_noecc_ooblayout_free,
};

static int spinand_init(struct spinand_device *spinand)
{
struct device *dev = &spinand->spimem->spi->dev;
Expand Down

0 comments on commit 55a1a71

Please sign in to comment.