diff options
-rw-r--r-- | drivers/mtd/nand/atmel_nand.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index c9183866a163..1669d2726222 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -723,6 +723,7 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf, | |||
723 | struct atmel_nand_host *host = nand_chip->priv; | 723 | struct atmel_nand_host *host = nand_chip->priv; |
724 | int i, err_nbr, eccbytes; | 724 | int i, err_nbr, eccbytes; |
725 | uint8_t *buf_pos; | 725 | uint8_t *buf_pos; |
726 | int total_err = 0; | ||
726 | 727 | ||
727 | eccbytes = nand_chip->ecc.bytes; | 728 | eccbytes = nand_chip->ecc.bytes; |
728 | for (i = 0; i < eccbytes; i++) | 729 | for (i = 0; i < eccbytes; i++) |
@@ -750,12 +751,13 @@ normal_check: | |||
750 | pmecc_correct_data(mtd, buf_pos, ecc, i, | 751 | pmecc_correct_data(mtd, buf_pos, ecc, i, |
751 | host->pmecc_bytes_per_sector, err_nbr); | 752 | host->pmecc_bytes_per_sector, err_nbr); |
752 | mtd->ecc_stats.corrected += err_nbr; | 753 | mtd->ecc_stats.corrected += err_nbr; |
754 | total_err += err_nbr; | ||
753 | } | 755 | } |
754 | } | 756 | } |
755 | pmecc_stat >>= 1; | 757 | pmecc_stat >>= 1; |
756 | } | 758 | } |
757 | 759 | ||
758 | return 0; | 760 | return total_err; |
759 | } | 761 | } |
760 | 762 | ||
761 | static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, | 763 | static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, |
@@ -767,6 +769,7 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, | |||
767 | uint32_t *eccpos = chip->ecc.layout->eccpos; | 769 | uint32_t *eccpos = chip->ecc.layout->eccpos; |
768 | uint32_t stat; | 770 | uint32_t stat; |
769 | unsigned long end_time; | 771 | unsigned long end_time; |
772 | int bitflips = 0; | ||
770 | 773 | ||
771 | pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST); | 774 | pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST); |
772 | pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE); | 775 | pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE); |
@@ -789,11 +792,14 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, | |||
789 | } | 792 | } |
790 | 793 | ||
791 | stat = pmecc_readl_relaxed(host->ecc, ISR); | 794 | stat = pmecc_readl_relaxed(host->ecc, ISR); |
792 | if (stat != 0) | 795 | if (stat != 0) { |
793 | if (pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]) != 0) | 796 | bitflips = pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]); |
794 | return -EIO; | 797 | if (bitflips < 0) |
798 | /* uncorrectable errors */ | ||
799 | return 0; | ||
800 | } | ||
795 | 801 | ||
796 | return 0; | 802 | return bitflips; |
797 | } | 803 | } |
798 | 804 | ||
799 | static int atmel_nand_pmecc_write_page(struct mtd_info *mtd, | 805 | static int atmel_nand_pmecc_write_page(struct mtd_info *mtd, |