]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.19.22/mtd-spinand-handle-the-case-where-program-load-does-not-reset-the-cache.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.19.22 / mtd-spinand-handle-the-case-where-program-load-does-not-reset-the-cache.patch
1 From 13c15e07eedf26092054c8c71f2f47edb8388310 Mon Sep 17 00:00:00 2001
2 From: Boris Brezillon <bbrezillon@kernel.org>
3 Date: Thu, 24 Jan 2019 15:20:07 +0100
4 Subject: mtd: spinand: Handle the case where PROGRAM LOAD does not reset the cache
5
6 From: Boris Brezillon <bbrezillon@kernel.org>
7
8 commit 13c15e07eedf26092054c8c71f2f47edb8388310 upstream.
9
10 Looks like PROGRAM LOAD (AKA write cache) does not necessarily reset
11 the cache content to 0xFF (depends on vendor implementation), so we
12 must fill the page cache entirely even if we only want to program the
13 data portion of the page, otherwise we might corrupt the BBM or user
14 data previously programmed in OOB area.
15
16 Fixes: 7529df465248 ("mtd: nand: Add core infrastructure to support SPI NANDs")
17 Reported-by: Stefan Roese <sr@denx.de>
18 Cc: <stable@vger.kernel.org>
19 Signed-off-by: Boris Brezillon <bbrezillon@kernel.org>
20 Tested-by: Stefan Roese <sr@denx.de>
21 Reviewed-by: Stefan Roese <sr@denx.de>
22 Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
23 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24
25 ---
26 drivers/mtd/nand/spi/core.c | 42 ++++++++++++++++++++----------------------
27 1 file changed, 20 insertions(+), 22 deletions(-)
28
29 --- a/drivers/mtd/nand/spi/core.c
30 +++ b/drivers/mtd/nand/spi/core.c
31 @@ -304,24 +304,30 @@ static int spinand_write_to_cache_op(str
32 struct nand_device *nand = spinand_to_nand(spinand);
33 struct mtd_info *mtd = nanddev_to_mtd(nand);
34 struct nand_page_io_req adjreq = *req;
35 - unsigned int nbytes = 0;
36 - void *buf = NULL;
37 + void *buf = spinand->databuf;
38 + unsigned int nbytes;
39 u16 column = 0;
40 int ret;
41
42 - memset(spinand->databuf, 0xff,
43 - nanddev_page_size(nand) +
44 - nanddev_per_page_oobsize(nand));
45 + /*
46 + * Looks like PROGRAM LOAD (AKA write cache) does not necessarily reset
47 + * the cache content to 0xFF (depends on vendor implementation), so we
48 + * must fill the page cache entirely even if we only want to program
49 + * the data portion of the page, otherwise we might corrupt the BBM or
50 + * user data previously programmed in OOB area.
51 + */
52 + nbytes = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand);
53 + memset(spinand->databuf, 0xff, nbytes);
54 + adjreq.dataoffs = 0;
55 + adjreq.datalen = nanddev_page_size(nand);
56 + adjreq.databuf.out = spinand->databuf;
57 + adjreq.ooblen = nanddev_per_page_oobsize(nand);
58 + adjreq.ooboffs = 0;
59 + adjreq.oobbuf.out = spinand->oobbuf;
60
61 - if (req->datalen) {
62 + if (req->datalen)
63 memcpy(spinand->databuf + req->dataoffs, req->databuf.out,
64 req->datalen);
65 - adjreq.dataoffs = 0;
66 - adjreq.datalen = nanddev_page_size(nand);
67 - adjreq.databuf.out = spinand->databuf;
68 - nbytes = adjreq.datalen;
69 - buf = spinand->databuf;
70 - }
71
72 if (req->ooblen) {
73 if (req->mode == MTD_OPS_AUTO_OOB)
74 @@ -332,14 +338,6 @@ static int spinand_write_to_cache_op(str
75 else
76 memcpy(spinand->oobbuf + req->ooboffs, req->oobbuf.out,
77 req->ooblen);
78 -
79 - adjreq.ooblen = nanddev_per_page_oobsize(nand);
80 - adjreq.ooboffs = 0;
81 - nbytes += nanddev_per_page_oobsize(nand);
82 - if (!buf) {
83 - buf = spinand->oobbuf;
84 - column = nanddev_page_size(nand);
85 - }
86 }
87
88 spinand_cache_op_adjust_colum(spinand, &adjreq, &column);
89 @@ -370,8 +368,8 @@ static int spinand_write_to_cache_op(str
90
91 /*
92 * We need to use the RANDOM LOAD CACHE operation if there's
93 - * more than one iteration, because the LOAD operation resets
94 - * the cache to 0xff.
95 + * more than one iteration, because the LOAD operation might
96 + * reset the cache to 0xff.
97 */
98 if (nbytes) {
99 column = op.addr.val;