diff options
| -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 30a8ce6d3e6..6ea520ae241 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; |
