From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail1.bemta14.messagelabs.com ([193.109.254.119]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aakq4-000105-PS for linux-mtd@lists.infradead.org; Tue, 01 Mar 2016 13:59:54 +0000 Subject: Re: [PATCH] mtd: nand: atmel: correct bitflips in erased pages for pre-sama5d4 SoCs To: Boris Brezillon , David Woodhouse , Brian Norris , "linux-mtd@lists.infradead.org" References: <1456837912-2577-1-git-send-email-boris.brezillon@free-electrons.com> CC: Nicolas Ferre , Jean-Christophe Plagniol-Villard , Alexandre Belloni , Wenyou Yang , Josh Wu From: Herve Codina Message-ID: <56D5A018.70507@celad.com> Date: Tue, 1 Mar 2016 14:58:48 +0100 MIME-Version: 1.0 In-Reply-To: <1456837912-2577-1-git-send-email-boris.brezillon@free-electrons.com> Content-Type: text/plain; charset="windows-1252" Content-Transfer-Encoding: 8bit List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Le 01/03/2016 14:11, Boris Brezillon a écrit : > 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 For testing purpose on my system, this patch and dependencies were backported to 3.12.52 and succesfully tested using a sama5d3 with a Micron MT29F16G08ABACAWP nand flash. > --- > 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; > } >