diff options
author | Josh Wu <josh.wu@atmel.com> | 2012-11-27 05:50:31 -0500 |
---|---|---|
committer | Artem Bityutskiy <artem.bityutskiy@linux.intel.com> | 2012-12-03 09:36:53 -0500 |
commit | c0c70d9ee6569150ff6a10f9d3c50c63c917e3a1 (patch) | |
tree | 6af5ba5479e3ce83da9438679e3a096b6d4c9195 /drivers/mtd | |
parent | 070c32223ae8a724a190ea769104ea41567e3673 (diff) |
mtd: at91: atmel_nand: return bit flips for the PMECC read_page()
This patch fix pmecc's read_page() to return maximum number of bitflips, 0 if uncorrectable.
In the commit: 3f91e94f7f511de74c0d2abe08672ccdbdd1961c ("mtd: nand: read_page() returns max_bitflips ()"),
The ecc.read_page() is changed to return the maximum number of bitflips.
And when meet uncorrectable bitflips it needs to return 0.
See the comment in nand.h:
* @read_page: function to read a page according to the ECC generator
* requirements; returns maximum number of bitflips corrected in
* any single ECC step, 0 if bitflips uncorrectable, -EIO hw error
Signed-off-by: Josh Wu <josh.wu@atmel.com>
Reviewed-by: Mike Dunn <mikedunn@newsguy.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Diffstat (limited to 'drivers/mtd')
-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, |