aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand
diff options
context:
space:
mode:
authorMike Dunn <mikedunn@newsguy.com>2012-04-25 15:06:09 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-05-14 00:12:06 -0400
commit3f91e94f7f511de74c0d2abe08672ccdbdd1961c (patch)
treed33e95596bbebc824a1331c83951a25d2118fd36 /drivers/mtd/nand
parentd062d4ede877fcd2ecc4c6262abad09a6f32950a (diff)
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')
-rw-r--r--drivers/mtd/nand/atmel_nand.c9
-rw-r--r--drivers/mtd/nand/bcm_umi_bch.c4
-rw-r--r--drivers/mtd/nand/cafe_nand.c4
-rw-r--r--drivers/mtd/nand/denali.c10
-rw-r--r--drivers/mtd/nand/docg4.c5
-rw-r--r--drivers/mtd/nand/fsl_elbc_nand.c21
-rw-r--r--drivers/mtd/nand/fsl_ifc_nand.c9
-rw-r--r--drivers/mtd/nand/fsmc_nand.c9
-rw-r--r--drivers/mtd/nand/nand_base.c47
-rw-r--r--drivers/mtd/nand/sh_flctl.c2
10 files changed, 82 insertions, 38 deletions
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 2165576a1c67..9a7876e8de42 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -335,6 +335,7 @@ static int atmel_nand_read_page(struct mtd_info *mtd,
335 uint8_t *oob = chip->oob_poi; 335 uint8_t *oob = chip->oob_poi;
336 uint8_t *ecc_pos; 336 uint8_t *ecc_pos;
337 int stat; 337 int stat;
338 unsigned int max_bitflips = 0;
338 339
339 /* 340 /*
340 * Errata: ALE is incorrectly wired up to the ECC controller 341 * Errata: ALE is incorrectly wired up to the ECC controller
@@ -371,10 +372,12 @@ static int atmel_nand_read_page(struct mtd_info *mtd,
371 /* check if there's an error */ 372 /* check if there's an error */
372 stat = chip->ecc.correct(mtd, p, oob, NULL); 373 stat = chip->ecc.correct(mtd, p, oob, NULL);
373 374
374 if (stat < 0) 375 if (stat < 0) {
375 mtd->ecc_stats.failed++; 376 mtd->ecc_stats.failed++;
376 else 377 } else {
377 mtd->ecc_stats.corrected += stat; 378 mtd->ecc_stats.corrected += stat;
379 max_bitflips = max_t(unsigned int, max_bitflips, stat);
380 }
378 381
379 /* get back to oob start (end of page) */ 382 /* get back to oob start (end of page) */
380 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1); 383 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
@@ -382,7 +385,7 @@ static int atmel_nand_read_page(struct mtd_info *mtd,
382 /* read the oob */ 385 /* read the oob */
383 chip->read_buf(mtd, oob, mtd->oobsize); 386 chip->read_buf(mtd, oob, mtd->oobsize);
384 387
385 return 0; 388 return max_bitflips;
386} 389}
387 390
388/* 391/*
diff --git a/drivers/mtd/nand/bcm_umi_bch.c b/drivers/mtd/nand/bcm_umi_bch.c
index a930666d0687..f8472b49567a 100644
--- a/drivers/mtd/nand/bcm_umi_bch.c
+++ b/drivers/mtd/nand/bcm_umi_bch.c
@@ -116,6 +116,7 @@ static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
116 uint8_t eccCalc[NAND_ECC_NUM_BYTES]; 116 uint8_t eccCalc[NAND_ECC_NUM_BYTES];
117 int sectorOobSize = mtd->oobsize / eccsteps; 117 int sectorOobSize = mtd->oobsize / eccsteps;
118 int stat; 118 int stat;
119 unsigned int max_bitflips = 0;
119 120
120 for (sectorIdx = 0; sectorIdx < eccsteps; 121 for (sectorIdx = 0; sectorIdx < eccsteps;
121 sectorIdx++, datap += eccsize) { 122 sectorIdx++, datap += eccsize) {
@@ -177,9 +178,10 @@ static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
177 } 178 }
178#endif 179#endif
179 mtd->ecc_stats.corrected += stat; 180 mtd->ecc_stats.corrected += stat;
181 max_bitflips = max_t(unsigned int, max_bitflips, stat);
180 } 182 }
181 } 183 }
182 return 0; 184 return max_bitflips;
183} 185}
184 186
185/**************************************************************************** 187/****************************************************************************
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
index 2973d97bd529..886ff3a064c2 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/cafe_nand.c
@@ -383,6 +383,7 @@ static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
383 uint8_t *buf, int page) 383 uint8_t *buf, int page)
384{ 384{
385 struct cafe_priv *cafe = mtd->priv; 385 struct cafe_priv *cafe = mtd->priv;
386 unsigned int max_bitflips = 0;
386 387
387 cafe_dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n", 388 cafe_dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n",
388 cafe_readl(cafe, NAND_ECC_RESULT), 389 cafe_readl(cafe, NAND_ECC_RESULT),
@@ -449,10 +450,11 @@ static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
449 } else { 450 } else {
450 dev_dbg(&cafe->pdev->dev, "Corrected %d symbol errors\n", n); 451 dev_dbg(&cafe->pdev->dev, "Corrected %d symbol errors\n", n);
451 mtd->ecc_stats.corrected += n; 452 mtd->ecc_stats.corrected += n;
453 max_bitflips = max_t(unsigned int, max_bitflips, n);
452 } 454 }
453 } 455 }
454 456
455 return 0; 457 return max_bitflips;
456} 458}
457 459
458static struct nand_ecclayout cafe_oobinfo_2048 = { 460static struct nand_ecclayout cafe_oobinfo_2048 = {
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index a1048c7c5d2c..1b346474dba8 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -924,9 +924,10 @@ bool is_erased(uint8_t *buf, int len)
924#define ECC_LAST_ERR(x) ((x) & ERR_CORRECTION_INFO__LAST_ERR_INFO) 924#define ECC_LAST_ERR(x) ((x) & ERR_CORRECTION_INFO__LAST_ERR_INFO)
925 925
926static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, 926static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf,
927 uint32_t irq_status) 927 uint32_t irq_status, unsigned int *max_bitflips)
928{ 928{
929 bool check_erased_page = false; 929 bool check_erased_page = false;
930 unsigned int bitflips = 0;
930 931
931 if (irq_status & INTR_STATUS__ECC_ERR) { 932 if (irq_status & INTR_STATUS__ECC_ERR) {
932 /* read the ECC errors. we'll ignore them for now */ 933 /* read the ECC errors. we'll ignore them for now */
@@ -965,6 +966,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf,
965 /* correct the ECC error */ 966 /* correct the ECC error */
966 buf[offset] ^= err_correction_value; 967 buf[offset] ^= err_correction_value;
967 denali->mtd.ecc_stats.corrected++; 968 denali->mtd.ecc_stats.corrected++;
969 bitflips++;
968 } 970 }
969 } else { 971 } else {
970 /* if the error is not correctable, need to 972 /* if the error is not correctable, need to
@@ -984,6 +986,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf,
984 clear_interrupts(denali); 986 clear_interrupts(denali);
985 denali_set_intr_modes(denali, true); 987 denali_set_intr_modes(denali, true);
986 } 988 }
989 *max_bitflips = bitflips;
987 return check_erased_page; 990 return check_erased_page;
988} 991}
989 992
@@ -1121,6 +1124,7 @@ static int denali_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
1121static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, 1124static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
1122 uint8_t *buf, int page) 1125 uint8_t *buf, int page)
1123{ 1126{
1127 unsigned int max_bitflips;
1124 struct denali_nand_info *denali = mtd_to_denali(mtd); 1128 struct denali_nand_info *denali = mtd_to_denali(mtd);
1125 1129
1126 dma_addr_t addr = denali->buf.dma_buf; 1130 dma_addr_t addr = denali->buf.dma_buf;
@@ -1153,7 +1157,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
1153 1157
1154 memcpy(buf, denali->buf.buf, mtd->writesize); 1158 memcpy(buf, denali->buf.buf, mtd->writesize);
1155 1159
1156 check_erased_page = handle_ecc(denali, buf, irq_status); 1160 check_erased_page = handle_ecc(denali, buf, irq_status, &max_bitflips);
1157 denali_enable_dma(denali, false); 1161 denali_enable_dma(denali, false);
1158 1162
1159 if (check_erased_page) { 1163 if (check_erased_page) {
@@ -1167,7 +1171,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
1167 denali->mtd.ecc_stats.failed++; 1171 denali->mtd.ecc_stats.failed++;
1168 } 1172 }
1169 } 1173 }
1170 return 0; 1174 return max_bitflips;
1171} 1175}
1172 1176
1173static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, 1177static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
index b08202664543..8e7da0170a2b 100644
--- a/drivers/mtd/nand/docg4.c
+++ b/drivers/mtd/nand/docg4.c
@@ -720,6 +720,7 @@ static int read_page(struct mtd_info *mtd, struct nand_chip *nand,
720 struct docg4_priv *doc = nand->priv; 720 struct docg4_priv *doc = nand->priv;
721 void __iomem *docptr = doc->virtadr; 721 void __iomem *docptr = doc->virtadr;
722 uint16_t status, edc_err, *buf16; 722 uint16_t status, edc_err, *buf16;
723 int bits_corrected = 0;
723 724
724 dev_dbg(doc->dev, "%s: page %08x\n", __func__, page); 725 dev_dbg(doc->dev, "%s: page %08x\n", __func__, page);
725 726
@@ -772,7 +773,7 @@ static int read_page(struct mtd_info *mtd, struct nand_chip *nand,
772 773
773 /* If bitflips are reported, attempt to correct with ecc */ 774 /* If bitflips are reported, attempt to correct with ecc */
774 if (edc_err & DOC_ECCCONF1_BCH_SYNDROM_ERR) { 775 if (edc_err & DOC_ECCCONF1_BCH_SYNDROM_ERR) {
775 int bits_corrected = correct_data(mtd, buf, page); 776 bits_corrected = correct_data(mtd, buf, page);
776 if (bits_corrected == -EBADMSG) 777 if (bits_corrected == -EBADMSG)
777 mtd->ecc_stats.failed++; 778 mtd->ecc_stats.failed++;
778 else 779 else
@@ -781,7 +782,7 @@ static int read_page(struct mtd_info *mtd, struct nand_chip *nand,
781 } 782 }
782 783
783 writew(0, docptr + DOC_DATAEND); 784 writew(0, docptr + DOC_DATAEND);
784 return 0; 785 return bits_corrected;
785} 786}
786 787
787 788
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 80b5264f0a32..8638b5e734cc 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 {
75 unsigned int use_mdr; /* Non zero if the MDR is to be set */ 75 unsigned int use_mdr; /* Non zero if the MDR is to be set */
76 unsigned int oob; /* Non zero if operating on OOB data */ 76 unsigned int oob; /* Non zero if operating on OOB data */
77 unsigned int counter; /* counter for the initializations */ 77 unsigned int counter; /* counter for the initializations */
78 unsigned int max_bitflips; /* Saved during READ0 cmd */
78}; 79};
79 80
80/* These map to the positions used by the FCM hardware ECC generator */ 81/* 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)
253 if (chip->ecc.mode != NAND_ECC_HW) 254 if (chip->ecc.mode != NAND_ECC_HW)
254 return 0; 255 return 0;
255 256
257 elbc_fcm_ctrl->max_bitflips = 0;
258
256 if (elbc_fcm_ctrl->read_bytes == mtd->writesize + mtd->oobsize) { 259 if (elbc_fcm_ctrl->read_bytes == mtd->writesize + mtd->oobsize) {
257 uint32_t lteccr = in_be32(&lbc->lteccr); 260 uint32_t lteccr = in_be32(&lbc->lteccr);
258 /* 261 /*
@@ -262,11 +265,16 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
262 * bits 28-31 are uncorrectable errors, marked elsewhere. 265 * bits 28-31 are uncorrectable errors, marked elsewhere.
263 * for small page nand only 1 bit is used. 266 * for small page nand only 1 bit is used.
264 * if the ELBC doesn't have the lteccr register it reads 0 267 * if the ELBC doesn't have the lteccr register it reads 0
268 * FIXME: 4 bits can be corrected on NANDs with 2k pages, so
269 * count the number of sub-pages with bitflips and update
270 * ecc_stats.corrected accordingly.
265 */ 271 */
266 if (lteccr & 0x000F000F) 272 if (lteccr & 0x000F000F)
267 out_be32(&lbc->lteccr, 0x000F000F); /* clear lteccr */ 273 out_be32(&lbc->lteccr, 0x000F000F); /* clear lteccr */
268 if (lteccr & 0x000F0000) 274 if (lteccr & 0x000F0000) {
269 mtd->ecc_stats.corrected++; 275 mtd->ecc_stats.corrected++;
276 elbc_fcm_ctrl->max_bitflips = 1;
277 }
270 } 278 }
271 279
272 return 0; 280 return 0;
@@ -743,13 +751,17 @@ static int fsl_elbc_read_page(struct mtd_info *mtd,
743 uint8_t *buf, 751 uint8_t *buf,
744 int page) 752 int page)
745{ 753{
754 struct fsl_elbc_mtd *priv = chip->priv;
755 struct fsl_lbc_ctrl *ctrl = priv->ctrl;
756 struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand;
757
746 fsl_elbc_read_buf(mtd, buf, mtd->writesize); 758 fsl_elbc_read_buf(mtd, buf, mtd->writesize);
747 fsl_elbc_read_buf(mtd, chip->oob_poi, mtd->oobsize); 759 fsl_elbc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
748 760
749 if (fsl_elbc_wait(mtd, chip) & NAND_STATUS_FAIL) 761 if (fsl_elbc_wait(mtd, chip) & NAND_STATUS_FAIL)
750 mtd->ecc_stats.failed++; 762 mtd->ecc_stats.failed++;
751 763
752 return 0; 764 return elbc_fcm_ctrl->max_bitflips;
753} 765}
754 766
755/* ECC will be calculated automatically, and errors will be detected in 767/* 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)
814 chip->ecc.size = 512; 826 chip->ecc.size = 512;
815 chip->ecc.bytes = 3; 827 chip->ecc.bytes = 3;
816 chip->ecc.strength = 1; 828 chip->ecc.strength = 1;
817 /*
818 * FIXME: can hardware ecc correct 4 bitflips if page size is
819 * 2k? Then does hardware report number of corrections for this
820 * case? If so, ecc_stats reporting needs to be fixed as well.
821 */
822 } else { 829 } else {
823 /* otherwise fall back to default software ECC */ 830 /* otherwise fall back to default software ECC */
824 chip->ecc.mode = NAND_ECC_SOFT; 831 chip->ecc.mode = NAND_ECC_SOFT;
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index 872cc9605291..0adde9670418 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -63,6 +63,7 @@ struct fsl_ifc_nand_ctrl {
63 unsigned int oob; /* Non zero if operating on OOB data */ 63 unsigned int oob; /* Non zero if operating on OOB data */
64 unsigned int eccread; /* Non zero for a full-page ECC read */ 64 unsigned int eccread; /* Non zero for a full-page ECC read */
65 unsigned int counter; /* counter for the initializations */ 65 unsigned int counter; /* counter for the initializations */
66 unsigned int max_bitflips; /* Saved during READ0 cmd */
66}; 67};
67 68
68static struct fsl_ifc_nand_ctrl *ifc_nand_ctrl; 69static struct fsl_ifc_nand_ctrl *ifc_nand_ctrl;
@@ -262,6 +263,8 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
262 if (ctrl->nand_stat & IFC_NAND_EVTER_STAT_WPER) 263 if (ctrl->nand_stat & IFC_NAND_EVTER_STAT_WPER)
263 dev_err(priv->dev, "NAND Flash Write Protect Error\n"); 264 dev_err(priv->dev, "NAND Flash Write Protect Error\n");
264 265
266 nctrl->max_bitflips = 0;
267
265 if (nctrl->eccread) { 268 if (nctrl->eccread) {
266 int errors; 269 int errors;
267 int bufnum = nctrl->page & priv->bufnum_mask; 270 int bufnum = nctrl->page & priv->bufnum_mask;
@@ -290,6 +293,9 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
290 } 293 }
291 294
292 mtd->ecc_stats.corrected += errors; 295 mtd->ecc_stats.corrected += errors;
296 nctrl->max_bitflips = max_t(unsigned int,
297 nctrl->max_bitflips,
298 errors);
293 } 299 }
294 300
295 nctrl->eccread = 0; 301 nctrl->eccread = 0;
@@ -698,6 +704,7 @@ static int fsl_ifc_read_page(struct mtd_info *mtd,
698{ 704{
699 struct fsl_ifc_mtd *priv = chip->priv; 705 struct fsl_ifc_mtd *priv = chip->priv;
700 struct fsl_ifc_ctrl *ctrl = priv->ctrl; 706 struct fsl_ifc_ctrl *ctrl = priv->ctrl;
707 struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl;
701 708
702 fsl_ifc_read_buf(mtd, buf, mtd->writesize); 709 fsl_ifc_read_buf(mtd, buf, mtd->writesize);
703 fsl_ifc_read_buf(mtd, chip->oob_poi, mtd->oobsize); 710 fsl_ifc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -708,7 +715,7 @@ static int fsl_ifc_read_page(struct mtd_info *mtd,
708 if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC) 715 if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC)
709 mtd->ecc_stats.failed++; 716 mtd->ecc_stats.failed++;
710 717
711 return 0; 718 return nctrl->max_bitflips;
712} 719}
713 720
714/* ECC will be calculated automatically, and errors will be detected in 721/* ECC will be calculated automatically, and errors will be detected in
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index 9d7f4171e077..6bf59fdde263 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -720,6 +720,7 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
720 */ 720 */
721 uint16_t ecc_oob[7]; 721 uint16_t ecc_oob[7];
722 uint8_t *oob = (uint8_t *)&ecc_oob[0]; 722 uint8_t *oob = (uint8_t *)&ecc_oob[0];
723 unsigned int max_bitflips = 0;
723 724
724 for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) { 725 for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) {
725 chip->cmdfunc(mtd, NAND_CMD_READ0, s * eccsize, page); 726 chip->cmdfunc(mtd, NAND_CMD_READ0, s * eccsize, page);
@@ -748,13 +749,15 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
748 chip->ecc.calculate(mtd, p, &ecc_calc[i]); 749 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
749 750
750 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); 751 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
751 if (stat < 0) 752 if (stat < 0) {
752 mtd->ecc_stats.failed++; 753 mtd->ecc_stats.failed++;
753 else 754 } else {
754 mtd->ecc_stats.corrected += stat; 755 mtd->ecc_stats.corrected += stat;
756 max_bitflips = max_t(unsigned int, max_bitflips, stat);
757 }
755 } 758 }
756 759
757 return 0; 760 return max_bitflips;
758} 761}
759 762
760/* 763/*
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 671f228d4c7c..8718eaf8269f 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1138,6 +1138,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
1138 uint8_t *ecc_calc = chip->buffers->ecccalc; 1138 uint8_t *ecc_calc = chip->buffers->ecccalc;
1139 uint8_t *ecc_code = chip->buffers->ecccode; 1139 uint8_t *ecc_code = chip->buffers->ecccode;
1140 uint32_t *eccpos = chip->ecc.layout->eccpos; 1140 uint32_t *eccpos = chip->ecc.layout->eccpos;
1141 unsigned int max_bitflips = 0;
1141 1142
1142 chip->ecc.read_page_raw(mtd, chip, buf, page); 1143 chip->ecc.read_page_raw(mtd, chip, buf, page);
1143 1144
@@ -1154,12 +1155,14 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
1154 int stat; 1155 int stat;
1155 1156
1156 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); 1157 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
1157 if (stat < 0) 1158 if (stat < 0) {
1158 mtd->ecc_stats.failed++; 1159 mtd->ecc_stats.failed++;
1159 else 1160 } else {
1160 mtd->ecc_stats.corrected += stat; 1161 mtd->ecc_stats.corrected += stat;
1162 max_bitflips = max_t(unsigned int, max_bitflips, stat);
1163 }
1161 } 1164 }
1162 return 0; 1165 return max_bitflips;
1163} 1166}
1164 1167
1165/** 1168/**
@@ -1180,6 +1183,7 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
1180 int datafrag_len, eccfrag_len, aligned_len, aligned_pos; 1183 int datafrag_len, eccfrag_len, aligned_len, aligned_pos;
1181 int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1; 1184 int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1;
1182 int index = 0; 1185 int index = 0;
1186 unsigned int max_bitflips = 0;
1183 1187
1184 /* Column address within the page aligned to ECC size (256bytes) */ 1188 /* Column address within the page aligned to ECC size (256bytes) */
1185 start_step = data_offs / chip->ecc.size; 1189 start_step = data_offs / chip->ecc.size;
@@ -1244,12 +1248,14 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
1244 1248
1245 stat = chip->ecc.correct(mtd, p, 1249 stat = chip->ecc.correct(mtd, p,
1246 &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]); 1250 &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
1247 if (stat < 0) 1251 if (stat < 0) {
1248 mtd->ecc_stats.failed++; 1252 mtd->ecc_stats.failed++;
1249 else 1253 } else {
1250 mtd->ecc_stats.corrected += stat; 1254 mtd->ecc_stats.corrected += stat;
1255 max_bitflips = max_t(unsigned int, max_bitflips, stat);
1256 }
1251 } 1257 }
1252 return 0; 1258 return max_bitflips;
1253} 1259}
1254 1260
1255/** 1261/**
@@ -1271,6 +1277,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
1271 uint8_t *ecc_calc = chip->buffers->ecccalc; 1277 uint8_t *ecc_calc = chip->buffers->ecccalc;
1272 uint8_t *ecc_code = chip->buffers->ecccode; 1278 uint8_t *ecc_code = chip->buffers->ecccode;
1273 uint32_t *eccpos = chip->ecc.layout->eccpos; 1279 uint32_t *eccpos = chip->ecc.layout->eccpos;
1280 unsigned int max_bitflips = 0;
1274 1281
1275 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { 1282 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
1276 chip->ecc.hwctl(mtd, NAND_ECC_READ); 1283 chip->ecc.hwctl(mtd, NAND_ECC_READ);
@@ -1289,12 +1296,14 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
1289 int stat; 1296 int stat;
1290 1297
1291 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); 1298 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
1292 if (stat < 0) 1299 if (stat < 0) {
1293 mtd->ecc_stats.failed++; 1300 mtd->ecc_stats.failed++;
1294 else 1301 } else {
1295 mtd->ecc_stats.corrected += stat; 1302 mtd->ecc_stats.corrected += stat;
1303 max_bitflips = max_t(unsigned int, max_bitflips, stat);
1304 }
1296 } 1305 }
1297 return 0; 1306 return max_bitflips;
1298} 1307}
1299 1308
1300/** 1309/**
@@ -1320,6 +1329,7 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
1320 uint8_t *ecc_code = chip->buffers->ecccode; 1329 uint8_t *ecc_code = chip->buffers->ecccode;
1321 uint32_t *eccpos = chip->ecc.layout->eccpos; 1330 uint32_t *eccpos = chip->ecc.layout->eccpos;
1322 uint8_t *ecc_calc = chip->buffers->ecccalc; 1331 uint8_t *ecc_calc = chip->buffers->ecccalc;
1332 unsigned int max_bitflips = 0;
1323 1333
1324 /* Read the OOB area first */ 1334 /* Read the OOB area first */
1325 chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); 1335 chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
@@ -1337,12 +1347,14 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
1337 chip->ecc.calculate(mtd, p, &ecc_calc[i]); 1347 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
1338 1348
1339 stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL); 1349 stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL);
1340 if (stat < 0) 1350 if (stat < 0) {
1341 mtd->ecc_stats.failed++; 1351 mtd->ecc_stats.failed++;
1342 else 1352 } else {
1343 mtd->ecc_stats.corrected += stat; 1353 mtd->ecc_stats.corrected += stat;
1354 max_bitflips = max_t(unsigned int, max_bitflips, stat);
1355 }
1344 } 1356 }
1345 return 0; 1357 return max_bitflips;
1346} 1358}
1347 1359
1348/** 1360/**
@@ -1363,6 +1375,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
1363 int eccsteps = chip->ecc.steps; 1375 int eccsteps = chip->ecc.steps;
1364 uint8_t *p = buf; 1376 uint8_t *p = buf;
1365 uint8_t *oob = chip->oob_poi; 1377 uint8_t *oob = chip->oob_poi;
1378 unsigned int max_bitflips = 0;
1366 1379
1367 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { 1380 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
1368 int stat; 1381 int stat;
@@ -1379,10 +1392,12 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
1379 chip->read_buf(mtd, oob, eccbytes); 1392 chip->read_buf(mtd, oob, eccbytes);
1380 stat = chip->ecc.correct(mtd, p, oob, NULL); 1393 stat = chip->ecc.correct(mtd, p, oob, NULL);
1381 1394
1382 if (stat < 0) 1395 if (stat < 0) {
1383 mtd->ecc_stats.failed++; 1396 mtd->ecc_stats.failed++;
1384 else 1397 } else {
1385 mtd->ecc_stats.corrected += stat; 1398 mtd->ecc_stats.corrected += stat;
1399 max_bitflips = max_t(unsigned int, max_bitflips, stat);
1400 }
1386 1401
1387 oob += eccbytes; 1402 oob += eccbytes;
1388 1403
@@ -1397,7 +1412,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
1397 if (i) 1412 if (i)
1398 chip->read_buf(mtd, oob, i); 1413 chip->read_buf(mtd, oob, i);
1399 1414
1400 return 0; 1415 return max_bitflips;
1401} 1416}
1402 1417
1403/** 1418/**
@@ -1588,7 +1603,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1588 if (oob) 1603 if (oob)
1589 ops->oobretlen = ops->ooblen - oobreadlen; 1604 ops->oobretlen = ops->ooblen - oobreadlen;
1590 1605
1591 if (ret) 1606 if (ret < 0)
1592 return ret; 1607 return ret;
1593 1608
1594 if (mtd->ecc_stats.failed - stats.failed) 1609 if (mtd->ecc_stats.failed - stats.failed)
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index e9b2b260de3a..4ea3e20169ba 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -359,7 +359,7 @@ static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
359 if (flctl->hwecc_cant_correct[i]) 359 if (flctl->hwecc_cant_correct[i])
360 mtd->ecc_stats.failed++; 360 mtd->ecc_stats.failed++;
361 else 361 else
362 mtd->ecc_stats.corrected += 0; 362 mtd->ecc_stats.corrected += 0; /* FIXME */
363 } 363 }
364 364
365 return 0; 365 return 0;