summaryrefslogtreecommitdiff
path: root/drivers/mtd/nand/fsl_elbc_nand.c
diff options
context:
space:
mode:
authorMike Dunn <mikedunn@newsguy.com>2012-04-25 19:06:09 (GMT)
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-05-14 04:12:06 (GMT)
commit3f91e94f7f511de74c0d2abe08672ccdbdd1961c (patch)
treed33e95596bbebc824a1331c83951a25d2118fd36 /drivers/mtd/nand/fsl_elbc_nand.c
parentd062d4ede877fcd2ecc4c6262abad09a6f32950a (diff)
downloadlinux-3f91e94f7f511de74c0d2abe08672ccdbdd1961c.tar.xz
mtd: nand: read_page() returns max_bitflips
The ecc.read_page() method for nand drivers is changed to return the maximum number of bitflips that were corrected on any one region covering an ecc step, This patch doesn't change what the nand code returns to mtd. This v2 includes the change to the fsl_ifc_nand driver requested by Scott¹. ¹ http://lists.infradead.org/pipermail/linux-mtd/2012-April/040883.html Signed-off-by: Mike Dunn <mikedunn@newsguy.com> Acked-by (freescale changes): Scott Wood <scottwood@freescale.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/nand/fsl_elbc_nand.c')
-rw-r--r--drivers/mtd/nand/fsl_elbc_nand.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 80b5264..8638b5e 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -75,6 +75,7 @@ struct fsl_elbc_fcm_ctrl {
unsigned int use_mdr; /* Non zero if the MDR is to be set */
unsigned int oob; /* Non zero if operating on OOB data */
unsigned int counter; /* counter for the initializations */
+ unsigned int max_bitflips; /* Saved during READ0 cmd */
};
/* These map to the positions used by the FCM hardware ECC generator */
@@ -253,6 +254,8 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
if (chip->ecc.mode != NAND_ECC_HW)
return 0;
+ elbc_fcm_ctrl->max_bitflips = 0;
+
if (elbc_fcm_ctrl->read_bytes == mtd->writesize + mtd->oobsize) {
uint32_t lteccr = in_be32(&lbc->lteccr);
/*
@@ -262,11 +265,16 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
* bits 28-31 are uncorrectable errors, marked elsewhere.
* for small page nand only 1 bit is used.
* if the ELBC doesn't have the lteccr register it reads 0
+ * FIXME: 4 bits can be corrected on NANDs with 2k pages, so
+ * count the number of sub-pages with bitflips and update
+ * ecc_stats.corrected accordingly.
*/
if (lteccr & 0x000F000F)
out_be32(&lbc->lteccr, 0x000F000F); /* clear lteccr */
- if (lteccr & 0x000F0000)
+ if (lteccr & 0x000F0000) {
mtd->ecc_stats.corrected++;
+ elbc_fcm_ctrl->max_bitflips = 1;
+ }
}
return 0;
@@ -743,13 +751,17 @@ static int fsl_elbc_read_page(struct mtd_info *mtd,
uint8_t *buf,
int page)
{
+ struct fsl_elbc_mtd *priv = chip->priv;
+ struct fsl_lbc_ctrl *ctrl = priv->ctrl;
+ struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand;
+
fsl_elbc_read_buf(mtd, buf, mtd->writesize);
fsl_elbc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
if (fsl_elbc_wait(mtd, chip) & NAND_STATUS_FAIL)
mtd->ecc_stats.failed++;
- return 0;
+ return elbc_fcm_ctrl->max_bitflips;
}
/* ECC will be calculated automatically, and errors will be detected in
@@ -814,11 +826,6 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
chip->ecc.size = 512;
chip->ecc.bytes = 3;
chip->ecc.strength = 1;
- /*
- * FIXME: can hardware ecc correct 4 bitflips if page size is
- * 2k? Then does hardware report number of corrections for this
- * case? If so, ecc_stats reporting needs to be fixed as well.
- */
} else {
/* otherwise fall back to default software ECC */
chip->ecc.mode = NAND_ECC_SOFT;