e7e2e798a1a36e350917f2cc33793440b111b76a
[openwrt/staging/linusw.git] /
1 From 25f815f66a141436df8a4c45e5d2765272aea2ac Mon Sep 17 00:00:00 2001
2 From: Boris Brezillon <boris.brezillon@free-electrons.com>
3 Date: Thu, 30 Nov 2017 18:01:30 +0100
4 Subject: [PATCH 5/7] mtd: nand: force drivers to explicitly send READ/PROG
5 commands
6
7 The core currently send the READ0 and SEQIN+PAGEPROG commands in
8 nand_do_read/write_ops(). This is inconsistent with
9 ->read/write_oob[_raw]() hooks behavior which are expected to send
10 these commands.
11
12 There's already a flag (NAND_ECC_CUSTOM_PAGE_ACCESS) to inform the core
13 that a specific controller wants to send the READ/SEQIN+PAGEPROG
14 commands on its own, but it's an opt-in flag, and existing drivers are
15 unlikely to be updated to pass it.
16
17 Moreover, some controllers cannot dissociate the READ/PAGEPROG commands
18 from the associated data transfer and ECC engine activation, and
19 developers have to hack things in their ->cmdfunc() implementation to
20 handle such complex cases, or have to accept the perf penalty of sending
21 twice the same command.
22 To address this problem we are planning on adding a new interface which
23 is passed all information about a NAND operation (including the amount
24 of data to transfer) and replacing all calls to ->cmdfunc() to calls to
25 this new ->exec_op() hook. But, in order to do that, we need to have all
26 ->cmdfunc() calls placed near their associated ->read/write_buf/byte()
27 calls.
28
29 Modify the core and relevant drivers to make NAND_ECC_CUSTOM_PAGE_ACCESS
30 the default case, and remove this flag.
31
32 Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
33 [miquel.raynal@free-electrons.com: tested, fixed and rebased on nand/next]
34 Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
35 Acked-by: Masahiro Yamada <yamada.masahiro@socionext.com>
36 ---
37 drivers/mtd/nand/qcom_nandc.c | 11 +++++++++++
38 1 file changed, 11 insertions(+)
39
40 --- a/drivers/mtd/nand/qcom_nandc.c
41 +++ b/drivers/mtd/nand/qcom_nandc.c
42 @@ -1725,6 +1725,7 @@ static int qcom_nandc_read_page(struct m
43 u8 *data_buf, *oob_buf = NULL;
44 int ret;
45
46 + nand_read_page_op(chip, page, 0, NULL, 0);
47 data_buf = buf;
48 oob_buf = oob_required ? chip->oob_poi : NULL;
49
50 @@ -1750,6 +1751,7 @@ static int qcom_nandc_read_page_raw(stru
51 int i, ret;
52 int read_loc;
53
54 + nand_read_page_op(chip, page, 0, NULL, 0);
55 data_buf = buf;
56 oob_buf = chip->oob_poi;
57
58 @@ -1850,6 +1852,8 @@ static int qcom_nandc_write_page(struct
59 u8 *data_buf, *oob_buf;
60 int i, ret;
61
62 + nand_prog_page_begin_op(chip, page, 0, NULL, 0);
63 +
64 clear_read_regs(nandc);
65 clear_bam_transaction(nandc);
66
67 @@ -1902,6 +1906,9 @@ static int qcom_nandc_write_page(struct
68
69 free_descs(nandc);
70
71 + if (!ret)
72 + ret = nand_prog_page_end_op(chip);
73 +
74 return ret;
75 }
76
77 @@ -1916,6 +1923,7 @@ static int qcom_nandc_write_page_raw(str
78 u8 *data_buf, *oob_buf;
79 int i, ret;
80
81 + nand_prog_page_begin_op(chip, page, 0, NULL, 0);
82 clear_read_regs(nandc);
83 clear_bam_transaction(nandc);
84
85 @@ -1970,6 +1978,9 @@ static int qcom_nandc_write_page_raw(str
86
87 free_descs(nandc);
88
89 + if (!ret)
90 + ret = nand_prog_page_end_op(chip);
91 +
92 return ret;
93 }
94