diff options
author | Marc Gonzalez <marc_gonzalez@sigmadesigns.com> | 2016-11-15 04:56:20 -0500 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@free-electrons.com> | 2016-11-19 03:43:07 -0500 |
commit | 3371d663bb4579f1b2003a92162edd6d90edd089 (patch) | |
tree | 47cd2dccf4aa4b54d0cfb3658ad16cd332f65be8 /drivers/mtd | |
parent | fc80f21a11156dd01c5ef14153e6f9e1291ccb82 (diff) |
mtd: nand: Support controllers with custom page
If your controller already sends the required NAND commands when
reading or writing a page, then the framework is not supposed to
send READ0 and SEQIN/PAGEPROG respectively.
Signed-off-by: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 4d099d4f442c..96d242e2fe34 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -1961,7 +1961,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
1961 | __func__, buf); | 1961 | __func__, buf); |
1962 | 1962 | ||
1963 | read_retry: | 1963 | read_retry: |
1964 | chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); | 1964 | if (nand_standard_page_accessors(&chip->ecc)) |
1965 | chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); | ||
1965 | 1966 | ||
1966 | /* | 1967 | /* |
1967 | * Now read the page into the buffer. Absent an error, | 1968 | * Now read the page into the buffer. Absent an error, |
@@ -2649,7 +2650,8 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
2649 | else | 2650 | else |
2650 | subpage = 0; | 2651 | subpage = 0; |
2651 | 2652 | ||
2652 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); | 2653 | if (nand_standard_page_accessors(&chip->ecc)) |
2654 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); | ||
2653 | 2655 | ||
2654 | if (unlikely(raw)) | 2656 | if (unlikely(raw)) |
2655 | status = chip->ecc.write_page_raw(mtd, chip, buf, | 2657 | status = chip->ecc.write_page_raw(mtd, chip, buf, |
@@ -2672,7 +2674,8 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
2672 | 2674 | ||
2673 | if (!cached || !NAND_HAS_CACHEPROG(chip)) { | 2675 | if (!cached || !NAND_HAS_CACHEPROG(chip)) { |
2674 | 2676 | ||
2675 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); | 2677 | if (nand_standard_page_accessors(&chip->ecc)) |
2678 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); | ||
2676 | status = chip->waitfunc(mtd, chip); | 2679 | status = chip->waitfunc(mtd, chip); |
2677 | /* | 2680 | /* |
2678 | * See if operation failed and additional status checks are | 2681 | * See if operation failed and additional status checks are |
@@ -4511,6 +4514,26 @@ static bool nand_ecc_strength_good(struct mtd_info *mtd) | |||
4511 | return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds; | 4514 | return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds; |
4512 | } | 4515 | } |
4513 | 4516 | ||
4517 | static bool invalid_ecc_page_accessors(struct nand_chip *chip) | ||
4518 | { | ||
4519 | struct nand_ecc_ctrl *ecc = &chip->ecc; | ||
4520 | |||
4521 | if (nand_standard_page_accessors(ecc)) | ||
4522 | return false; | ||
4523 | |||
4524 | /* | ||
4525 | * NAND_ECC_CUSTOM_PAGE_ACCESS flag is set, make sure the NAND | ||
4526 | * controller driver implements all the page accessors because | ||
4527 | * default helpers are not suitable when the core does not | ||
4528 | * send the READ0/PAGEPROG commands. | ||
4529 | */ | ||
4530 | return (!ecc->read_page || !ecc->write_page || | ||
4531 | !ecc->read_page_raw || !ecc->write_page_raw || | ||
4532 | (NAND_HAS_SUBPAGE_READ(chip) && !ecc->read_subpage) || | ||
4533 | (NAND_HAS_SUBPAGE_WRITE(chip) && !ecc->write_subpage && | ||
4534 | ecc->hwctl && ecc->calculate)); | ||
4535 | } | ||
4536 | |||
4514 | /** | 4537 | /** |
4515 | * nand_scan_tail - [NAND Interface] Scan for the NAND device | 4538 | * nand_scan_tail - [NAND Interface] Scan for the NAND device |
4516 | * @mtd: MTD device structure | 4539 | * @mtd: MTD device structure |
@@ -4531,6 +4554,11 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
4531 | !(chip->bbt_options & NAND_BBT_USE_FLASH))) | 4554 | !(chip->bbt_options & NAND_BBT_USE_FLASH))) |
4532 | return -EINVAL; | 4555 | return -EINVAL; |
4533 | 4556 | ||
4557 | if (invalid_ecc_page_accessors(chip)) { | ||
4558 | pr_err("Invalid ECC page accessors setup\n"); | ||
4559 | return -EINVAL; | ||
4560 | } | ||
4561 | |||
4534 | if (!(chip->options & NAND_OWN_BUFFERS)) { | 4562 | if (!(chip->options & NAND_OWN_BUFFERS)) { |
4535 | nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize | 4563 | nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize |
4536 | + mtd->oobsize * 3, GFP_KERNEL); | 4564 | + mtd->oobsize * 3, GFP_KERNEL); |