From ff6ee101584c17c4f30ca48d75e2910c49d0b0ff Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Tue, 1 Mar 2016 14:11:52 +0100 Subject: [PATCH] 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 Reported-by: Herve Codina Reviewed-by: Herve Codina Tested-by: Herve Codina --- drivers/mtd/nand/atmel_nand.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 20cbaab..0b5da72 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, uint8_t *buf_pos; int max_bitflips = 0; - /* If can correct bitfilps from erased page, do the normal check */ - if (host->caps->pmecc_correct_erase_page) - goto normal_check; - - for (i = 0; i < nand_chip->ecc.total; i++) - if (ecc[i] != 0xff) - goto normal_check; - /* Erased page, return OK */ - return 0; - -normal_check: for (i = 0; i < nand_chip->ecc.steps; i++) { err_nbr = 0; if (pmecc_stat & 0x1) { @@ -884,16 +873,30 @@ normal_check: pmecc_get_sigma(mtd); err_nbr = pmecc_err_location(mtd); - if (err_nbr == -1) { + if (err_nbr >= 0) { + pmecc_correct_data(mtd, buf_pos, ecc, i, + nand_chip->ecc.bytes, + err_nbr); + } else if (!host->caps->pmecc_correct_erase_page) { + u8 *ecc_pos = ecc + (i * nand_chip->ecc.bytes); + + /* Try to detect erased pages */ + err_nbr = nand_check_erased_ecc_chunk(buf_pos, + host->pmecc_sector_size, + ecc_pos, + nand_chip->ecc.bytes, + NULL, 0, + nand_chip->ecc.strength); + } + + if (err_nbr < 0) { dev_err(host->dev, "PMECC: Too many errors\n"); mtd->ecc_stats.failed++; return -EIO; - } else { - pmecc_correct_data(mtd, buf_pos, ecc, i, - nand_chip->ecc.bytes, err_nbr); - mtd->ecc_stats.corrected += err_nbr; - max_bitflips = max_t(int, max_bitflips, err_nbr); } + + mtd->ecc_stats.corrected += err_nbr; + max_bitflips = max_t(int, max_bitflips, err_nbr); } pmecc_stat >>= 1; } -- 2.7.4