Messages in this thread Patch in this message | | | From | Richard Weinberger <> | Subject | [PATCH 2/3] mtd: nand: Add support for raw access when using on-die ECC | Date | Wed, 25 Mar 2015 15:02:30 +0100 |
| |
Implementing raw access for on-die ECC mode is a bit beautiless because we have to disable on-die ECC before sending the NAND read command and re-enable it again at all locations where raw access can happen. If the kernel was built without on-die ECC support or the current ECC mode is not on-die these operations are no-ops.
Signed-off-by: Richard Weinberger <richard@nod.at> --- drivers/mtd/nand/nand_base.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-)
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 92e7ed7..b42f556 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -1589,16 +1589,21 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, __func__, buf); read_retry: + if (unlikely(ops->mode == MTD_OPS_RAW)) + nand_setup_on_die_ecc_micron(mtd, 0); + chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); /* * Now read the page into the buffer. Absent an error, * the read methods return max bitflips per ecc step. */ - if (unlikely(ops->mode == MTD_OPS_RAW)) + if (unlikely(ops->mode == MTD_OPS_RAW)) { ret = chip->ecc.read_page_raw(mtd, chip, bufpoi, oob_required, page); + nand_setup_on_die_ecc_micron(mtd, 1); + } else if (!aligned && NAND_HAS_SUBPAGE_READ(chip) && !oob) ret = chip->ecc.read_subpage(mtd, chip, @@ -1926,9 +1931,11 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, page = realpage & chip->pagemask; while (1) { - if (ops->mode == MTD_OPS_RAW) + if (ops->mode == MTD_OPS_RAW) { + nand_setup_on_die_ecc_micron(mtd, 0); ret = chip->ecc.read_oob_raw(mtd, chip, page); - else + nand_setup_on_die_ecc_micron(mtd, 1); + } else ret = chip->ecc.read_oob(mtd, chip, page); if (ret < 0) @@ -2271,6 +2278,9 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, else subpage = 0; + if (unlikely(raw)) + nand_setup_on_die_ecc_micron(mtd, 0); + chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); if (unlikely(raw)) @@ -2283,7 +2293,7 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, status = chip->ecc.write_page(mtd, chip, buf, oob_required); if (status < 0) - return status; + goto out; /* * Cached progamming disabled for now. Not sure if it's worth the @@ -2303,14 +2313,22 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, status = chip->errstat(mtd, chip, FL_WRITING, status, page); - if (status & NAND_STATUS_FAIL) - return -EIO; + if (status & NAND_STATUS_FAIL) { + status = -EIO; + goto out; + } } else { chip->cmdfunc(mtd, NAND_CMD_CACHEDPROG, -1, -1); status = chip->waitfunc(mtd, chip); } - return 0; + status = 0; + +out: + if (unlikely(raw)) + nand_setup_on_die_ecc_micron(mtd, 1); + + return status; } /** @@ -2632,9 +2650,11 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, nand_fill_oob(mtd, ops->oobbuf, ops->ooblen, ops); - if (ops->mode == MTD_OPS_RAW) + if (ops->mode == MTD_OPS_RAW) { + nand_setup_on_die_ecc_micron(mtd, 0); status = chip->ecc.write_oob_raw(mtd, chip, page & chip->pagemask); - else + nand_setup_on_die_ecc_micron(mtd, 1); + } else status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); chip->select_chip(mtd, -1); -- 2.3.4
| |