diff options
author | Yeasah Pell <yeasah@comrex.com> | 2009-07-01 11:11:35 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2009-09-19 16:13:08 -0400 |
commit | 223cf6c3b517cf6ef040cafe45af89f3b8adba74 (patch) | |
tree | 36e48701a76b54985c5d543a1b72cdb56c87f7ae /drivers/mtd/nand/pxa3xx_nand.c | |
parent | 71b7d0d90d536ae4e70929cc59a1a9f6ba457c6c (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/nand/pxa3xx_nand.c')
-rw-r--r-- | drivers/mtd/nand/pxa3xx_nand.c | 17 |
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 | ||
107 | enum { | 108 | enum { |
@@ -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; |