mtd: spinand: Move ECC related definitions earlier in the driver
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
This commit is contained in:
parent
93afb10e22
commit
55a1a71a7f
@ -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);
|
||||
@ -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)
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user