summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Brezillon <boris.brezillon@free-electrons.com>2016-03-01 08:11:52 -0500
committerBoris Brezillon <boris.brezillon@free-electrons.com>2016-04-19 16:04:50 -0400
commitff6ee101584c17c4f30ca48d75e2910c49d0b0ff (patch)
tree0c6471fc6c8e6e4d890a1d4679888867b284fb21
parent8ae6bcd1dcea249591b4165bd7f795c4868bc531 (diff)
mtd: nand: atmel: correct bitflips in erased pages for pre-sama5d4 SoCs
New atmel SoCs are able to fix bitflips in erased pages, but old ones are still impacted by this problem. Use nand_check_erased_ecc_chunk() to handle this case. Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Reported-by: Herve Codina <herve.CODINA@celad.com> Reviewed-by: Herve Codina <herve.CODINA@celad.com> Tested-by: Herve Codina <herve.CODINA@celad.com>
-rw-r--r--drivers/mtd/nand/atmel_nand.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 20cbaabb2959..0b5da7271440 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -863,17 +863,6 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf,
863 uint8_t *buf_pos; 863 uint8_t *buf_pos;
864 int max_bitflips = 0; 864 int max_bitflips = 0;
865 865
866 /* If can correct bitfilps from erased page, do the normal check */
867 if (host->caps->pmecc_correct_erase_page)
868 goto normal_check;
869
870 for (i = 0; i < nand_chip->ecc.total; i++)
871 if (ecc[i] != 0xff)
872 goto normal_check;
873 /* Erased page, return OK */
874 return 0;
875
876normal_check:
877 for (i = 0; i < nand_chip->ecc.steps; i++) { 866 for (i = 0; i < nand_chip->ecc.steps; i++) {
878 err_nbr = 0; 867 err_nbr = 0;
879 if (pmecc_stat & 0x1) { 868 if (pmecc_stat & 0x1) {
@@ -884,16 +873,30 @@ normal_check:
884 pmecc_get_sigma(mtd); 873 pmecc_get_sigma(mtd);
885 874
886 err_nbr = pmecc_err_location(mtd); 875 err_nbr = pmecc_err_location(mtd);
887 if (err_nbr == -1) { 876 if (err_nbr >= 0) {
877 pmecc_correct_data(mtd, buf_pos, ecc, i,
878 nand_chip->ecc.bytes,
879 err_nbr);
880 } else if (!host->caps->pmecc_correct_erase_page) {
881 u8 *ecc_pos = ecc + (i * nand_chip->ecc.bytes);
882
883 /* Try to detect erased pages */
884 err_nbr = nand_check_erased_ecc_chunk(buf_pos,
885 host->pmecc_sector_size,
886 ecc_pos,
887 nand_chip->ecc.bytes,
888 NULL, 0,
889 nand_chip->ecc.strength);
890 }
891
892 if (err_nbr < 0) {
888 dev_err(host->dev, "PMECC: Too many errors\n"); 893 dev_err(host->dev, "PMECC: Too many errors\n");
889 mtd->ecc_stats.failed++; 894 mtd->ecc_stats.failed++;
890 return -EIO; 895 return -EIO;
891 } else {
892 pmecc_correct_data(mtd, buf_pos, ecc, i,
893 nand_chip->ecc.bytes, err_nbr);
894 mtd->ecc_stats.corrected += err_nbr;
895 max_bitflips = max_t(int, max_bitflips, err_nbr);
896 } 896 }
897
898 mtd->ecc_stats.corrected += err_nbr;
899 max_bitflips = max_t(int, max_bitflips, err_nbr);
897 } 900 }
898 pmecc_stat >>= 1; 901 pmecc_stat >>= 1;
899 } 902 }