aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorYeasah Pell <yeasah@comrex.com>2009-07-01 11:11:35 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-09-19 16:13:08 -0400
commit223cf6c3b517cf6ef040cafe45af89f3b8adba74 (patch)
tree36e48701a76b54985c5d543a1b72cdb56c87f7ae /drivers/mtd
parent71b7d0d90d536ae4e70929cc59a1a9f6ba457c6c (diff)
mtd: pxa3xx_nand: add single-bit error corrections reporting
Acked-by: Eric Miao <eric.y.miao@gmail.com> Signed-off-by: Yeasah Pell <yeasah@comrex.com> Signed-off-by: Mike Rapoport <mike@compulab.co.il> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 30a8ce6d3e69..6ea520ae2410 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -102,6 +102,7 @@ enum {
102 ERR_SENDCMD = -2, 102 ERR_SENDCMD = -2,
103 ERR_DBERR = -3, 103 ERR_DBERR = -3,
104 ERR_BBERR = -4, 104 ERR_BBERR = -4,
105 ERR_SBERR = -5,
105}; 106};
106 107
107enum { 108enum {
@@ -564,11 +565,13 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
564 565
565 status = nand_readl(info, NDSR); 566 status = nand_readl(info, NDSR);
566 567
567 if (status & (NDSR_RDDREQ | NDSR_DBERR)) { 568 if (status & (NDSR_RDDREQ | NDSR_DBERR | NDSR_SBERR)) {
568 if (status & NDSR_DBERR) 569 if (status & NDSR_DBERR)
569 info->retcode = ERR_DBERR; 570 info->retcode = ERR_DBERR;
571 else if (status & NDSR_SBERR)
572 info->retcode = ERR_SBERR;
570 573
571 disable_int(info, NDSR_RDDREQ | NDSR_DBERR); 574 disable_int(info, NDSR_RDDREQ | NDSR_DBERR | NDSR_SBERR);
572 575
573 if (info->use_dma) { 576 if (info->use_dma) {
574 info->state = STATE_DMA_READING; 577 info->state = STATE_DMA_READING;
@@ -670,7 +673,7 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
670 if (prepare_read_prog_cmd(info, cmdset->read1, column, page_addr)) 673 if (prepare_read_prog_cmd(info, cmdset->read1, column, page_addr))
671 break; 674 break;
672 675
673 pxa3xx_nand_do_cmd(info, NDSR_RDDREQ | NDSR_DBERR); 676 pxa3xx_nand_do_cmd(info, NDSR_RDDREQ | NDSR_DBERR | NDSR_SBERR);
674 677
675 /* We only are OOB, so if the data has error, does not matter */ 678 /* We only are OOB, so if the data has error, does not matter */
676 if (info->retcode == ERR_DBERR) 679 if (info->retcode == ERR_DBERR)
@@ -687,7 +690,7 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
687 if (prepare_read_prog_cmd(info, cmdset->read1, column, page_addr)) 690 if (prepare_read_prog_cmd(info, cmdset->read1, column, page_addr))
688 break; 691 break;
689 692
690 pxa3xx_nand_do_cmd(info, NDSR_RDDREQ | NDSR_DBERR); 693 pxa3xx_nand_do_cmd(info, NDSR_RDDREQ | NDSR_DBERR | NDSR_SBERR);
691 694
692 if (info->retcode == ERR_DBERR) { 695 if (info->retcode == ERR_DBERR) {
693 /* for blank page (all 0xff), HW will calculate its ECC as 696 /* for blank page (all 0xff), HW will calculate its ECC as
@@ -861,8 +864,12 @@ static int pxa3xx_nand_ecc_correct(struct mtd_info *mtd,
861 * consider it as a ecc error which will tell the caller the 864 * consider it as a ecc error which will tell the caller the
862 * read fail We have distinguish all the errors, but the 865 * read fail We have distinguish all the errors, but the
863 * nand_read_ecc only check this function return value 866 * nand_read_ecc only check this function return value
867 *
868 * Corrected (single-bit) errors must also be noted.
864 */ 869 */
865 if (info->retcode != ERR_NONE) 870 if (info->retcode == ERR_SBERR)
871 return 1;
872 else if (info->retcode != ERR_NONE)
866 return -1; 873 return -1;
867 874
868 return 0; 875 return 0;