diff options
author | Miquel Raynal <miquel.raynal@bootlin.com> | 2021-12-31 15:31:23 +0300 |
---|---|---|
committer | Miquel Raynal <miquel.raynal@bootlin.com> | 2021-12-31 15:31:34 +0300 |
commit | 9ce47e43a0f088653aa25ca465836a84114e0940 (patch) | |
tree | b7de3c49e9ca311cfe417e513a9b77d656c13b63 /drivers/mtd/nand/raw/nand_base.c | |
parent | bee387131abe02f43da0ba784446ed4c0dd06dbb (diff) | |
parent | 2997e4871621bc56d3c19b447355091dafb6e505 (diff) | |
download | linux-9ce47e43a0f088653aa25ca465836a84114e0940.tar.xz |
Merge tag 'nand/for-5.17' into mtd/next
Raw NAND core:
* Export nand_read_page_hwecc_oob_first()
GPMC memory controller for OMAP2 NAND controller:
* GPMC:
- Add support for AM64 SoC and allow build on K3 platforms
- Use a compatible match table when checking for NAND controller
- Use platform_get_irq() to get the interrupt
Raw NAND controller drivers:
* OMAP2 NAND controller:
- Document the missing 'rb-gpios' DT property
- Drop unused variable
- Fix force_8bit flag behaviour for DMA mode
- Move to exec_op interface
- Use platform_get_irq() to get the interrupt
* Renesas:
- Add new NAND controller driver with its bindings and MAINTAINERS entry
* Onenand:
- Remove redundant variable ooblen
* MPC5121:
- Remove unused variable in ads5121_select_chip()
* GPMI:
- Add ERR007117 protection for nfc_apply_timings
- Remove explicit default gpmi clock setting for i.MX6
- Use platform_get_irq_byname() to get the interrupt
- Remove unneeded variable
* Ingenic:
- JZ4740 needs 'oob_first' read page function
* Davinci:
- Rewrite function description
- Avoid duplicated page read
- Don't calculate ECC when reading page
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Diffstat (limited to 'drivers/mtd/nand/raw/nand_base.c')
-rw-r--r-- | drivers/mtd/nand/raw/nand_base.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index b3a9bc08b4bb..9f48b4e71a11 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -3164,6 +3164,73 @@ static int nand_read_page_hwecc(struct nand_chip *chip, uint8_t *buf, } /** + * nand_read_page_hwecc_oob_first - Hardware ECC page read with ECC + * data read from OOB area + * @chip: nand chip info structure + * @buf: buffer to store read data + * @oob_required: caller requires OOB data read to chip->oob_poi + * @page: page number to read + * + * Hardware ECC for large page chips, which requires the ECC data to be + * extracted from the OOB before the actual data is read. + */ +int nand_read_page_hwecc_oob_first(struct nand_chip *chip, uint8_t *buf, + int oob_required, int page) +{ + struct mtd_info *mtd = nand_to_mtd(chip); + int i, eccsize = chip->ecc.size, ret; + int eccbytes = chip->ecc.bytes; + int eccsteps = chip->ecc.steps; + uint8_t *p = buf; + uint8_t *ecc_code = chip->ecc.code_buf; + unsigned int max_bitflips = 0; + + /* Read the OOB area first */ + ret = nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize); + if (ret) + return ret; + + /* Move read cursor to start of page */ + ret = nand_change_read_column_op(chip, 0, NULL, 0, false); + if (ret) + return ret; + + ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0, + chip->ecc.total); + if (ret) + return ret; + + for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { + int stat; + + chip->ecc.hwctl(chip, NAND_ECC_READ); + + ret = nand_read_data_op(chip, p, eccsize, false, false); + if (ret) + return ret; + + stat = chip->ecc.correct(chip, p, &ecc_code[i], NULL); + if (stat == -EBADMSG && + (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { + /* check for empty pages with bitflips */ + stat = nand_check_erased_ecc_chunk(p, eccsize, + &ecc_code[i], + eccbytes, NULL, 0, + chip->ecc.strength); + } + + if (stat < 0) { + mtd->ecc_stats.failed++; + } else { + mtd->ecc_stats.corrected += stat; + max_bitflips = max_t(unsigned int, max_bitflips, stat); + } + } + return max_bitflips; +} +EXPORT_SYMBOL_GPL(nand_read_page_hwecc_oob_first); + +/** * nand_read_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page read * @chip: nand chip info structure * @buf: buffer to store read data |