diff options
| author | Boris Brezillon <boris.brezillon@free-electrons.com> | 2017-11-30 18:01:30 +0100 |
|---|---|---|
| committer | Boris Brezillon <boris.brezillon@free-electrons.com> | 2017-12-14 13:34:17 +0100 |
| commit | 25f815f66a141436df8a4c45e5d2765272aea2ac (patch) | |
| tree | c218dcaa4440f1cfbc62efbf67a1d80b72c5a4e1 /drivers/mtd/nand/mtk_nand.c | |
| parent | 97d90da8a886949f09bb4754843fb0b504956ad2 (diff) | |
mtd: nand: force drivers to explicitly send READ/PROG commands
The core currently send the READ0 and SEQIN+PAGEPROG commands in
nand_do_read/write_ops(). This is inconsistent with
->read/write_oob[_raw]() hooks behavior which are expected to send
these commands.
There's already a flag (NAND_ECC_CUSTOM_PAGE_ACCESS) to inform the core
that a specific controller wants to send the READ/SEQIN+PAGEPROG
commands on its own, but it's an opt-in flag, and existing drivers are
unlikely to be updated to pass it.
Moreover, some controllers cannot dissociate the READ/PAGEPROG commands
from the associated data transfer and ECC engine activation, and
developers have to hack things in their ->cmdfunc() implementation to
handle such complex cases, or have to accept the perf penalty of sending
twice the same command.
To address this problem we are planning on adding a new interface which
is passed all information about a NAND operation (including the amount
of data to transfer) and replacing all calls to ->cmdfunc() to calls to
this new ->exec_op() hook. But, in order to do that, we need to have all
->cmdfunc() calls placed near their associated ->read/write_buf/byte()
calls.
Modify the core and relevant drivers to make NAND_ECC_CUSTOM_PAGE_ACCESS
the default case, and remove this flag.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
[miquel.raynal@free-electrons.com: tested, fixed and rebased on nand/next]
Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
Acked-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Diffstat (limited to 'drivers/mtd/nand/mtk_nand.c')
| -rw-r--r-- | drivers/mtd/nand/mtk_nand.c | 22 |
1 files changed, 8 insertions, 14 deletions
diff --git a/drivers/mtd/nand/mtk_nand.c b/drivers/mtd/nand/mtk_nand.c index 9c4adaf9331b..5d76be451596 100644 --- a/drivers/mtd/nand/mtk_nand.c +++ b/drivers/mtd/nand/mtk_nand.c @@ -761,6 +761,8 @@ static int mtk_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip, u32 reg; int ret; + nand_prog_page_begin_op(chip, page, 0, NULL, 0); + if (!raw) { /* OOB => FDM: from register, ECC: from HW */ reg = nfi_readw(nfc, NFI_CNFG) | CNFG_AUTO_FMT_EN; @@ -794,7 +796,10 @@ static int mtk_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip, if (!raw) mtk_ecc_disable(nfc->ecc); - return ret; + if (ret) + return ret; + + return nand_prog_page_end_op(chip); } static int mtk_nfc_write_page_hwecc(struct mtd_info *mtd, @@ -832,15 +837,7 @@ static int mtk_nfc_write_subpage_hwecc(struct mtd_info *mtd, static int mtk_nfc_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip, int page) { - int ret; - - nand_prog_page_begin_op(chip, page, 0, NULL, 0); - - ret = mtk_nfc_write_page_raw(mtd, chip, NULL, 1, page); - if (ret < 0) - return -EIO; - - return nand_prog_page_end_op(chip); + return mtk_nfc_write_page_raw(mtd, chip, NULL, 1, page); } static int mtk_nfc_update_ecc_stats(struct mtd_info *mtd, u8 *buf, u32 sectors) @@ -889,8 +886,7 @@ static int mtk_nfc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, len = sectors * chip->ecc.size + (raw ? sectors * spare : 0); buf = bufpoi + start * chip->ecc.size; - if (column != 0) - nand_change_read_column_op(chip, column, NULL, 0, false); + nand_read_page_op(chip, page, column, NULL, 0); addr = dma_map_single(nfc->dev, buf, len, DMA_FROM_DEVICE); rc = dma_mapping_error(nfc->dev, addr); @@ -1013,8 +1009,6 @@ static int mtk_nfc_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, static int mtk_nfc_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip, int page) { - nand_read_page_op(chip, page, 0, NULL, 0); - return mtk_nfc_read_page_raw(mtd, chip, NULL, 1, page); } |
