diff options
author | Boris Brezillon <boris.brezillon@free-electrons.com> | 2016-03-04 18:09:21 +0100 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@free-electrons.com> | 2016-04-19 22:05:46 +0200 |
commit | 828dec153044805506cc2b8e39cb3f62d5f76a12 (patch) | |
tree | 0513fc769d8357aea014e107da57cfc23877e11a | |
parent | cc6822fb756b5080ca127fef1a89f35558bd2610 (diff) | |
download | op-kernel-dev-828dec153044805506cc2b8e39cb3f62d5f76a12.zip op-kernel-dev-828dec153044805506cc2b8e39cb3f62d5f76a12.tar.gz |
mtd: nand: sunxi: make OOB retrieval optional
sunxi_nfc_hw_ecc_read_chunk() always retrieves the ECC and protected free
bytes, no matter if the user really asked for it or not. This can take a
non negligible amount of time, especially on NAND chips exposing large OOB
areas (> 1KB). Make it optional.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
-rw-r--r-- | drivers/mtd/nand/sunxi_nand.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index c20bf59..b710532 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c @@ -868,7 +868,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd, u8 *oob, int oob_off, int *cur_off, unsigned int *max_bitflips, - bool bbm, int page) + bool bbm, bool oob_required, int page) { struct nand_chip *nand = mtd_to_nand(mtd); struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); @@ -900,7 +900,8 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd, *cur_off = oob_off + ecc->bytes + 4; - ret = sunxi_nfc_hw_ecc_correct(mtd, data, oob, 0, &erased); + ret = sunxi_nfc_hw_ecc_correct(mtd, data, oob_required ? oob : NULL, 0, + &erased); if (erased) return 1; @@ -928,12 +929,14 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd, } else { memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size); - nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1); - sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4, - true, page); + if (oob_required) { + nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1); + sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4, + true, page); - sunxi_nfc_hw_ecc_get_prot_oob_bytes(mtd, oob, 0, - bbm, page); + sunxi_nfc_hw_ecc_get_prot_oob_bytes(mtd, oob, 0, + bbm, page); + } } sunxi_nfc_hw_ecc_update_stats(mtd, max_bitflips, ret); @@ -1047,7 +1050,7 @@ static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd, ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob, oob_off + mtd->writesize, &cur_off, &max_bitflips, - !i, page); + !i, oob_required, page); if (ret < 0) return ret; else if (ret) @@ -1085,8 +1088,8 @@ static int sunxi_nfc_hw_ecc_read_subpage(struct mtd_info *mtd, ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob, oob_off + mtd->writesize, - &cur_off, &max_bitflips, - !i, page); + &cur_off, &max_bitflips, !i, + false, page); if (ret < 0) return ret; } @@ -1148,7 +1151,9 @@ static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd, ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob, oob_off, &cur_off, - &max_bitflips, !i, page); + &max_bitflips, !i, + oob_required, + page); if (ret < 0) return ret; else if (ret) |