kernel: update kernel 3.18 to version 3.18.23
[openwrt/staging/chunkeey.git] / target / linux / sunxi / patches-4.1 / 111-mtd-add-support-for-nand-partitions.patch
1 From a95cc309cf74eed3fc457dec3dcc44d9bf79e0e6 Mon Sep 17 00:00:00 2001
2 From: Boris BREZILLON <boris.brezillon@free-electrons.com>
3 Date: Mon, 28 Jul 2014 15:01:15 +0200
4 Subject: [PATCH] mtd: nand: Add support for NAND partitions
5
6 Add support for NAND partitions, and indirectly for per partition ECC
7 config, and also per partiton random seed support for the upcoming
8 randomizer support.
9
10 This is necessary to be able to use different ECC / randomizer settings for
11 the parts of the NAND which are read directly by a bootrom (which has a
12 fixed ECC / random seed setting) and the generic data part of the NAND for
13 which we often want a stronger ECC and / or random seed.
14
15 Provide helper functions to add/delete/allocate nand partitions.
16 NAND core code now make use of the partition specific nand_ecc_ctrl struct
17 (if available) when doing read/write operations.
18
19 Signed-off-by: Boris BREZILLON <boris.brezillon@free-electrons.com>
20 Signed-off-by: Hans de Goede <hdegoede@redhat.com>
21 ---
22 drivers/mtd/nand/Kconfig | 4 +
23 drivers/mtd/nand/Makefile | 2 +
24 drivers/mtd/nand/nand_base.c | 712 +++++++++++++++++++++++++++++++++++--------
25 drivers/mtd/nand/nand_bch.c | 16 +-
26 drivers/mtd/nand/nand_ecc.c | 4 +-
27 include/linux/mtd/nand.h | 38 +++
28 6 files changed, 635 insertions(+), 141 deletions(-)
29
30 --- a/drivers/mtd/nand/Kconfig
31 +++ b/drivers/mtd/nand/Kconfig
32 @@ -22,6 +22,10 @@ menuconfig MTD_NAND
33
34 if MTD_NAND
35
36 +config MTD_OF_NAND_PARTS
37 + tristate
38 + default n
39 +
40 config MTD_NAND_BCH
41 tristate
42 select BCH
43 --- a/drivers/mtd/nand/Makefile
44 +++ b/drivers/mtd/nand/Makefile
45 @@ -53,4 +53,6 @@ obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) +=
46 obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_nand.o
47 obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o
48
49 +obj-$(CONFIG_MTD_OF_NAND_PARTS) += ofnandpart.o
50 +
51 nand-objs := nand_base.o nand_bbt.o nand_timings.o
52 --- a/drivers/mtd/nand/nand_base.c
53 +++ b/drivers/mtd/nand/nand_base.c
54 @@ -1134,26 +1134,26 @@ static int nand_read_page_raw_syndrome(s
55 struct nand_chip *chip, uint8_t *buf,
56 int oob_required, int page)
57 {
58 - int eccsize = chip->ecc.size;
59 - int eccbytes = chip->ecc.bytes;
60 + int eccsize = chip->cur_ecc->size;
61 + int eccbytes = chip->cur_ecc->bytes;
62 uint8_t *oob = chip->oob_poi;
63 int steps, size;
64
65 - for (steps = chip->ecc.steps; steps > 0; steps--) {
66 + for (steps = chip->cur_ecc->steps; steps > 0; steps--) {
67 chip->read_buf(mtd, buf, eccsize);
68 buf += eccsize;
69
70 - if (chip->ecc.prepad) {
71 - chip->read_buf(mtd, oob, chip->ecc.prepad);
72 - oob += chip->ecc.prepad;
73 + if (chip->cur_ecc->prepad) {
74 + chip->read_buf(mtd, oob, chip->cur_ecc->prepad);
75 + oob += chip->cur_ecc->prepad;
76 }
77
78 chip->read_buf(mtd, oob, eccbytes);
79 oob += eccbytes;
80
81 - if (chip->ecc.postpad) {
82 - chip->read_buf(mtd, oob, chip->ecc.postpad);
83 - oob += chip->ecc.postpad;
84 + if (chip->cur_ecc->postpad) {
85 + chip->read_buf(mtd, oob, chip->cur_ecc->postpad);
86 + oob += chip->cur_ecc->postpad;
87 }
88 }
89
90 @@ -1175,30 +1175,31 @@ static int nand_read_page_raw_syndrome(s
91 static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
92 uint8_t *buf, int oob_required, int page)
93 {
94 - int i, eccsize = chip->ecc.size;
95 - int eccbytes = chip->ecc.bytes;
96 - int eccsteps = chip->ecc.steps;
97 + int i, eccsize = chip->cur_ecc->size;
98 + int eccbytes = chip->cur_ecc->bytes;
99 + int eccsteps = chip->cur_ecc->steps;
100 uint8_t *p = buf;
101 uint8_t *ecc_calc = chip->buffers->ecccalc;
102 uint8_t *ecc_code = chip->buffers->ecccode;
103 - uint32_t *eccpos = chip->ecc.layout->eccpos;
104 + uint32_t *eccpos = chip->cur_ecc->layout->eccpos;
105 unsigned int max_bitflips = 0;
106
107 - chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
108 + chip->cur_ecc->read_page_raw(mtd, chip, buf, 1, page);
109
110 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
111 - chip->ecc.calculate(mtd, p, &ecc_calc[i]);
112 + chip->cur_ecc->calculate(mtd, p, &ecc_calc[i]);
113
114 - for (i = 0; i < chip->ecc.total; i++)
115 + for (i = 0; i < chip->cur_ecc->total; i++)
116 ecc_code[i] = chip->oob_poi[eccpos[i]];
117
118 - eccsteps = chip->ecc.steps;
119 + eccsteps = chip->cur_ecc->steps;
120 p = buf;
121
122 for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
123 int stat;
124
125 - stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
126 + stat = chip->cur_ecc->correct(mtd, p, &ecc_code[i],
127 + &ecc_calc[i]);
128 if (stat < 0) {
129 mtd->ecc_stats.failed++;
130 } else {
131 @@ -1223,7 +1224,7 @@ static int nand_read_subpage(struct mtd_
132 int page)
133 {
134 int start_step, end_step, num_steps;
135 - uint32_t *eccpos = chip->ecc.layout->eccpos;
136 + uint32_t *eccpos = chip->cur_ecc->layout->eccpos;
137 uint8_t *p;
138 int data_col_addr, i, gaps = 0;
139 int datafrag_len, eccfrag_len, aligned_len, aligned_pos;
140 @@ -1232,16 +1233,16 @@ static int nand_read_subpage(struct mtd_
141 unsigned int max_bitflips = 0;
142
143 /* Column address within the page aligned to ECC size (256bytes) */
144 - start_step = data_offs / chip->ecc.size;
145 - end_step = (data_offs + readlen - 1) / chip->ecc.size;
146 + start_step = data_offs / chip->cur_ecc->size;
147 + end_step = (data_offs + readlen - 1) / chip->cur_ecc->size;
148 num_steps = end_step - start_step + 1;
149 - index = start_step * chip->ecc.bytes;
150 + index = start_step * chip->cur_ecc->bytes;
151
152 /* Data size aligned to ECC ecc.size */
153 - datafrag_len = num_steps * chip->ecc.size;
154 - eccfrag_len = num_steps * chip->ecc.bytes;
155 + datafrag_len = num_steps * chip->cur_ecc->size;
156 + eccfrag_len = num_steps * chip->cur_ecc->bytes;
157
158 - data_col_addr = start_step * chip->ecc.size;
159 + data_col_addr = start_step * chip->cur_ecc->size;
160 /* If we read not a page aligned data */
161 if (data_col_addr != 0)
162 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_col_addr, -1);
163 @@ -1250,8 +1251,9 @@ static int nand_read_subpage(struct mtd_
164 chip->read_buf(mtd, p, datafrag_len);
165
166 /* Calculate ECC */
167 - for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size)
168 - chip->ecc.calculate(mtd, p, &chip->buffers->ecccalc[i]);
169 + for (i = 0; i < eccfrag_len;
170 + i += chip->cur_ecc->bytes, p += chip->cur_ecc->size)
171 + chip->cur_ecc->calculate(mtd, p, &chip->buffers->ecccalc[i]);
172
173 /*
174 * The performance is faster if we position offsets according to
175 @@ -1275,7 +1277,8 @@ static int nand_read_subpage(struct mtd_
176 aligned_len = eccfrag_len;
177 if (eccpos[index] & (busw - 1))
178 aligned_len++;
179 - if (eccpos[index + (num_steps * chip->ecc.bytes)] & (busw - 1))
180 + if (eccpos[index + (num_steps * chip->cur_ecc->bytes)] &
181 + (busw - 1))
182 aligned_len++;
183
184 chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
185 @@ -1287,11 +1290,13 @@ static int nand_read_subpage(struct mtd_
186 chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + index]];
187
188 p = bufpoi + data_col_addr;
189 - for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) {
190 + for (i = 0; i < eccfrag_len;
191 + i += chip->cur_ecc->bytes, p += chip->cur_ecc->size) {
192 int stat;
193
194 - stat = chip->ecc.correct(mtd, p,
195 - &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
196 + stat = chip->cur_ecc->correct(mtd, p,
197 + &chip->buffers->ecccode[i],
198 + &chip->buffers->ecccalc[i]);
199 if (stat < 0) {
200 mtd->ecc_stats.failed++;
201 } else {
202 @@ -1315,32 +1320,33 @@ static int nand_read_subpage(struct mtd_
203 static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
204 uint8_t *buf, int oob_required, int page)
205 {
206 - int i, eccsize = chip->ecc.size;
207 - int eccbytes = chip->ecc.bytes;
208 - int eccsteps = chip->ecc.steps;
209 + int i, eccsize = chip->cur_ecc->size;
210 + int eccbytes = chip->cur_ecc->bytes;
211 + int eccsteps = chip->cur_ecc->steps;
212 uint8_t *p = buf;
213 uint8_t *ecc_calc = chip->buffers->ecccalc;
214 uint8_t *ecc_code = chip->buffers->ecccode;
215 - uint32_t *eccpos = chip->ecc.layout->eccpos;
216 + uint32_t *eccpos = chip->cur_ecc->layout->eccpos;
217 unsigned int max_bitflips = 0;
218
219 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
220 - chip->ecc.hwctl(mtd, NAND_ECC_READ);
221 + chip->cur_ecc->hwctl(mtd, NAND_ECC_READ);
222 chip->read_buf(mtd, p, eccsize);
223 - chip->ecc.calculate(mtd, p, &ecc_calc[i]);
224 + chip->cur_ecc->calculate(mtd, p, &ecc_calc[i]);
225 }
226 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
227
228 - for (i = 0; i < chip->ecc.total; i++)
229 + for (i = 0; i < chip->cur_ecc->total; i++)
230 ecc_code[i] = chip->oob_poi[eccpos[i]];
231
232 - eccsteps = chip->ecc.steps;
233 + eccsteps = chip->cur_ecc->steps;
234 p = buf;
235
236 for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
237 int stat;
238
239 - stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
240 + stat = chip->cur_ecc->correct(mtd, p, &ecc_code[i],
241 + &ecc_calc[i]);
242 if (stat < 0) {
243 mtd->ecc_stats.failed++;
244 } else {
245 @@ -1368,12 +1374,12 @@ static int nand_read_page_hwecc(struct m
246 static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
247 struct nand_chip *chip, uint8_t *buf, int oob_required, int page)
248 {
249 - int i, eccsize = chip->ecc.size;
250 - int eccbytes = chip->ecc.bytes;
251 - int eccsteps = chip->ecc.steps;
252 + int i, eccsize = chip->cur_ecc->size;
253 + int eccbytes = chip->cur_ecc->bytes;
254 + int eccsteps = chip->cur_ecc->steps;
255 uint8_t *p = buf;
256 uint8_t *ecc_code = chip->buffers->ecccode;
257 - uint32_t *eccpos = chip->ecc.layout->eccpos;
258 + uint32_t *eccpos = chip->cur_ecc->layout->eccpos;
259 uint8_t *ecc_calc = chip->buffers->ecccalc;
260 unsigned int max_bitflips = 0;
261
262 @@ -1382,17 +1388,17 @@ static int nand_read_page_hwecc_oob_firs
263 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
264 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
265
266 - for (i = 0; i < chip->ecc.total; i++)
267 + for (i = 0; i < chip->cur_ecc->total; i++)
268 ecc_code[i] = chip->oob_poi[eccpos[i]];
269
270 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
271 int stat;
272
273 - chip->ecc.hwctl(mtd, NAND_ECC_READ);
274 + chip->cur_ecc->hwctl(mtd, NAND_ECC_READ);
275 chip->read_buf(mtd, p, eccsize);
276 - chip->ecc.calculate(mtd, p, &ecc_calc[i]);
277 + chip->cur_ecc->calculate(mtd, p, &ecc_calc[i]);
278
279 - stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL);
280 + stat = chip->cur_ecc->correct(mtd, p, &ecc_code[i], NULL);
281 if (stat < 0) {
282 mtd->ecc_stats.failed++;
283 } else {
284 @@ -1417,9 +1423,9 @@ static int nand_read_page_hwecc_oob_firs
285 static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
286 uint8_t *buf, int oob_required, int page)
287 {
288 - int i, eccsize = chip->ecc.size;
289 - int eccbytes = chip->ecc.bytes;
290 - int eccsteps = chip->ecc.steps;
291 + int i, eccsize = chip->cur_ecc->size;
292 + int eccbytes = chip->cur_ecc->bytes;
293 + int eccsteps = chip->cur_ecc->steps;
294 uint8_t *p = buf;
295 uint8_t *oob = chip->oob_poi;
296 unsigned int max_bitflips = 0;
297 @@ -1427,17 +1433,17 @@ static int nand_read_page_syndrome(struc
298 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
299 int stat;
300
301 - chip->ecc.hwctl(mtd, NAND_ECC_READ);
302 + chip->cur_ecc->hwctl(mtd, NAND_ECC_READ);
303 chip->read_buf(mtd, p, eccsize);
304
305 - if (chip->ecc.prepad) {
306 - chip->read_buf(mtd, oob, chip->ecc.prepad);
307 - oob += chip->ecc.prepad;
308 + if (chip->cur_ecc->prepad) {
309 + chip->read_buf(mtd, oob, chip->cur_ecc->prepad);
310 + oob += chip->cur_ecc->prepad;
311 }
312
313 - chip->ecc.hwctl(mtd, NAND_ECC_READSYN);
314 + chip->cur_ecc->hwctl(mtd, NAND_ECC_READSYN);
315 chip->read_buf(mtd, oob, eccbytes);
316 - stat = chip->ecc.correct(mtd, p, oob, NULL);
317 + stat = chip->cur_ecc->correct(mtd, p, oob, NULL);
318
319 if (stat < 0) {
320 mtd->ecc_stats.failed++;
321 @@ -1448,9 +1454,9 @@ static int nand_read_page_syndrome(struc
322
323 oob += eccbytes;
324
325 - if (chip->ecc.postpad) {
326 - chip->read_buf(mtd, oob, chip->ecc.postpad);
327 - oob += chip->ecc.postpad;
328 + if (chip->cur_ecc->postpad) {
329 + chip->read_buf(mtd, oob, chip->cur_ecc->postpad);
330 + oob += chip->cur_ecc->postpad;
331 }
332 }
333
334 @@ -1480,7 +1486,7 @@ static uint8_t *nand_transfer_oob(struct
335 return oob + len;
336
337 case MTD_OPS_AUTO_OOB: {
338 - struct nand_oobfree *free = chip->ecc.layout->oobfree;
339 + struct nand_oobfree *free = chip->cur_ecc->layout->oobfree;
340 uint32_t boffs = 0, roffs = ops->ooboffs;
341 size_t bytes = 0;
342
343 @@ -1600,17 +1606,21 @@ read_retry:
344 * the read methods return max bitflips per ecc step.
345 */
346 if (unlikely(ops->mode == MTD_OPS_RAW))
347 - ret = chip->ecc.read_page_raw(mtd, chip, bufpoi,
348 - oob_required,
349 - page);
350 + ret = chip->cur_ecc->read_page_raw(mtd, chip,
351 + bufpoi,
352 + oob_required,
353 + page);
354 else if (!aligned && NAND_HAS_SUBPAGE_READ(chip) &&
355 !oob)
356 - ret = chip->ecc.read_subpage(mtd, chip,
357 - col, bytes, bufpoi,
358 - page);
359 + ret = chip->cur_ecc->read_subpage(mtd, chip,
360 + col, bytes,
361 + bufpoi,
362 + page);
363 else
364 - ret = chip->ecc.read_page(mtd, chip, bufpoi,
365 - oob_required, page);
366 + ret = chip->cur_ecc->read_page(mtd, chip,
367 + bufpoi,
368 + oob_required,
369 + page);
370 if (ret < 0) {
371 if (use_bufpoi)
372 /* Invalidate page cache */
373 @@ -1746,6 +1756,39 @@ static int nand_read(struct mtd_info *mt
374 }
375
376 /**
377 + * nand_part_read - [MTD Interface] MTD compatibility function for nand_do_read_ecc
378 + * @mtd: MTD device structure
379 + * @from: offset to read from
380 + * @len: number of bytes to read
381 + * @retlen: pointer to variable to store the number of read bytes
382 + * @buf: the databuffer to put data
383 + *
384 + * Get hold of the chip and call nand_do_read.
385 + */
386 +static int nand_part_read(struct mtd_info *mtd, loff_t from, size_t len,
387 + size_t *retlen, uint8_t *buf)
388 +{
389 + struct nand_chip *chip = mtd->priv;
390 + struct nand_part *part = to_nand_part(mtd);
391 + struct mtd_oob_ops ops;
392 + int ret;
393 +
394 + from += part->offset;
395 + nand_get_device(part->master, FL_READING);
396 + if (part->ecc)
397 + chip->cur_ecc = part->ecc;
398 + ops.len = len;
399 + ops.datbuf = buf;
400 + ops.oobbuf = NULL;
401 + ops.mode = MTD_OPS_PLACE_OOB;
402 + ret = nand_do_read_ops(part->master, from, &ops);
403 + *retlen = ops.retlen;
404 + chip->cur_ecc = &chip->ecc;
405 + nand_release_device(part->master);
406 + return ret;
407 +}
408 +
409 +/**
410 * nand_read_oob_std - [REPLACEABLE] the most common OOB data read function
411 * @mtd: mtd info structure
412 * @chip: nand chip info structure
413 @@ -1770,13 +1813,14 @@ static int nand_read_oob_syndrome(struct
414 int page)
415 {
416 int length = mtd->oobsize;
417 - int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
418 - int eccsize = chip->ecc.size;
419 + int chunk = chip->cur_ecc->bytes + chip->cur_ecc->prepad +
420 + chip->cur_ecc->postpad;
421 + int eccsize = chip->cur_ecc->size;
422 uint8_t *bufpoi = chip->oob_poi;
423 int i, toread, sndrnd = 0, pos;
424
425 - chip->cmdfunc(mtd, NAND_CMD_READ0, chip->ecc.size, page);
426 - for (i = 0; i < chip->ecc.steps; i++) {
427 + chip->cmdfunc(mtd, NAND_CMD_READ0, chip->cur_ecc->size, page);
428 + for (i = 0; i < chip->cur_ecc->steps; i++) {
429 if (sndrnd) {
430 pos = eccsize + i * (eccsize + chunk);
431 if (mtd->writesize > 512)
432 @@ -1829,9 +1873,10 @@ static int nand_write_oob_std(struct mtd
433 static int nand_write_oob_syndrome(struct mtd_info *mtd,
434 struct nand_chip *chip, int page)
435 {
436 - int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
437 - int eccsize = chip->ecc.size, length = mtd->oobsize;
438 - int i, len, pos, status = 0, sndcmd = 0, steps = chip->ecc.steps;
439 + int chunk = chip->cur_ecc->bytes + chip->cur_ecc->prepad +
440 + chip->cur_ecc->postpad;
441 + int eccsize = chip->cur_ecc->size, length = mtd->oobsize;
442 + int i, len, pos, status = 0, sndcmd = 0, steps = chip->cur_ecc->steps;
443 const uint8_t *bufpoi = chip->oob_poi;
444
445 /*
446 @@ -1839,7 +1884,7 @@ static int nand_write_oob_syndrome(struc
447 * or
448 * data-pad-ecc-pad-data-pad .... ecc-pad-oob
449 */
450 - if (!chip->ecc.prepad && !chip->ecc.postpad) {
451 + if (!chip->cur_ecc->prepad && !chip->cur_ecc->postpad) {
452 pos = steps * (eccsize + chunk);
453 steps = 0;
454 } else
455 @@ -1903,7 +1948,7 @@ static int nand_do_read_oob(struct mtd_i
456 stats = mtd->ecc_stats;
457
458 if (ops->mode == MTD_OPS_AUTO_OOB)
459 - len = chip->ecc.layout->oobavail;
460 + len = chip->cur_ecc->layout->oobavail;
461 else
462 len = mtd->oobsize;
463
464 @@ -1931,9 +1976,9 @@ static int nand_do_read_oob(struct mtd_i
465
466 while (1) {
467 if (ops->mode == MTD_OPS_RAW)
468 - ret = chip->ecc.read_oob_raw(mtd, chip, page);
469 + ret = chip->cur_ecc->read_oob_raw(mtd, chip, page);
470 else
471 - ret = chip->ecc.read_oob(mtd, chip, page);
472 + ret = chip->cur_ecc->read_oob(mtd, chip, page);
473
474 if (ret < 0)
475 break;
476 @@ -2021,6 +2066,56 @@ out:
477 return ret;
478 }
479
480 +/**
481 + * nand_part_read_oob - [MTD Interface] NAND read data and/or out-of-band
482 + * @mtd: MTD device structure
483 + * @from: offset to read from
484 + * @ops: oob operation description structure
485 + *
486 + * NAND read data and/or out-of-band data.
487 + */
488 +static int nand_part_read_oob(struct mtd_info *mtd, loff_t from,
489 + struct mtd_oob_ops *ops)
490 +{
491 + struct nand_chip *chip = mtd->priv;
492 + struct nand_part *part = to_nand_part(mtd);
493 + int ret = -ENOTSUPP;
494 +
495 + ops->retlen = 0;
496 +
497 + /* Do not allow reads past end of device */
498 + if (ops->datbuf && (from + ops->len) > mtd->size) {
499 + pr_debug("%s: attempt to read beyond end of device\n",
500 + __func__);
501 + return -EINVAL;
502 + }
503 +
504 + from += part->offset;
505 + nand_get_device(part->master, FL_READING);
506 + if (part->ecc)
507 + chip->cur_ecc = part->ecc;
508 +
509 + switch (ops->mode) {
510 + case MTD_OPS_PLACE_OOB:
511 + case MTD_OPS_AUTO_OOB:
512 + case MTD_OPS_RAW:
513 + break;
514 +
515 + default:
516 + goto out;
517 + }
518 +
519 + if (!ops->datbuf)
520 + ret = nand_do_read_oob(part->master, from, ops);
521 + else
522 + ret = nand_do_read_ops(part->master, from, ops);
523 +
524 +out:
525 + chip->cur_ecc = &chip->ecc;
526 + nand_release_device(part->master);
527 + return ret;
528 +}
529 +
530
531 /**
532 * nand_write_page_raw - [INTERN] raw page write function
533 @@ -2054,26 +2149,26 @@ static int nand_write_page_raw_syndrome(
534 struct nand_chip *chip,
535 const uint8_t *buf, int oob_required)
536 {
537 - int eccsize = chip->ecc.size;
538 - int eccbytes = chip->ecc.bytes;
539 + int eccsize = chip->cur_ecc->size;
540 + int eccbytes = chip->cur_ecc->bytes;
541 uint8_t *oob = chip->oob_poi;
542 int steps, size;
543
544 - for (steps = chip->ecc.steps; steps > 0; steps--) {
545 + for (steps = chip->cur_ecc->steps; steps > 0; steps--) {
546 chip->write_buf(mtd, buf, eccsize);
547 buf += eccsize;
548
549 - if (chip->ecc.prepad) {
550 - chip->write_buf(mtd, oob, chip->ecc.prepad);
551 - oob += chip->ecc.prepad;
552 + if (chip->cur_ecc->prepad) {
553 + chip->write_buf(mtd, oob, chip->cur_ecc->prepad);
554 + oob += chip->cur_ecc->prepad;
555 }
556
557 chip->write_buf(mtd, oob, eccbytes);
558 oob += eccbytes;
559
560 - if (chip->ecc.postpad) {
561 - chip->write_buf(mtd, oob, chip->ecc.postpad);
562 - oob += chip->ecc.postpad;
563 + if (chip->cur_ecc->postpad) {
564 + chip->write_buf(mtd, oob, chip->cur_ecc->postpad);
565 + oob += chip->cur_ecc->postpad;
566 }
567 }
568
569 @@ -2093,21 +2188,21 @@ static int nand_write_page_raw_syndrome(
570 static int nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
571 const uint8_t *buf, int oob_required)
572 {
573 - int i, eccsize = chip->ecc.size;
574 - int eccbytes = chip->ecc.bytes;
575 - int eccsteps = chip->ecc.steps;
576 + int i, eccsize = chip->cur_ecc->size;
577 + int eccbytes = chip->cur_ecc->bytes;
578 + int eccsteps = chip->cur_ecc->steps;
579 uint8_t *ecc_calc = chip->buffers->ecccalc;
580 const uint8_t *p = buf;
581 - uint32_t *eccpos = chip->ecc.layout->eccpos;
582 + uint32_t *eccpos = chip->cur_ecc->layout->eccpos;
583
584 /* Software ECC calculation */
585 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
586 - chip->ecc.calculate(mtd, p, &ecc_calc[i]);
587 + chip->cur_ecc->calculate(mtd, p, &ecc_calc[i]);
588
589 - for (i = 0; i < chip->ecc.total; i++)
590 + for (i = 0; i < chip->cur_ecc->total; i++)
591 chip->oob_poi[eccpos[i]] = ecc_calc[i];
592
593 - return chip->ecc.write_page_raw(mtd, chip, buf, 1);
594 + return chip->cur_ecc->write_page_raw(mtd, chip, buf, 1);
595 }
596
597 /**
598 @@ -2120,20 +2215,20 @@ static int nand_write_page_swecc(struct
599 static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
600 const uint8_t *buf, int oob_required)
601 {
602 - int i, eccsize = chip->ecc.size;
603 - int eccbytes = chip->ecc.bytes;
604 - int eccsteps = chip->ecc.steps;
605 + int i, eccsize = chip->cur_ecc->size;
606 + int eccbytes = chip->cur_ecc->bytes;
607 + int eccsteps = chip->cur_ecc->steps;
608 uint8_t *ecc_calc = chip->buffers->ecccalc;
609 const uint8_t *p = buf;
610 - uint32_t *eccpos = chip->ecc.layout->eccpos;
611 + uint32_t *eccpos = chip->cur_ecc->layout->eccpos;
612
613 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
614 - chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
615 + chip->cur_ecc->hwctl(mtd, NAND_ECC_WRITE);
616 chip->write_buf(mtd, p, eccsize);
617 - chip->ecc.calculate(mtd, p, &ecc_calc[i]);
618 + chip->cur_ecc->calculate(mtd, p, &ecc_calc[i]);
619 }
620
621 - for (i = 0; i < chip->ecc.total; i++)
622 + for (i = 0; i < chip->cur_ecc->total; i++)
623 chip->oob_poi[eccpos[i]] = ecc_calc[i];
624
625 chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
626 @@ -2158,10 +2253,10 @@ static int nand_write_subpage_hwecc(stru
627 {
628 uint8_t *oob_buf = chip->oob_poi;
629 uint8_t *ecc_calc = chip->buffers->ecccalc;
630 - int ecc_size = chip->ecc.size;
631 - int ecc_bytes = chip->ecc.bytes;
632 - int ecc_steps = chip->ecc.steps;
633 - uint32_t *eccpos = chip->ecc.layout->eccpos;
634 + int ecc_size = chip->cur_ecc->size;
635 + int ecc_bytes = chip->cur_ecc->bytes;
636 + int ecc_steps = chip->cur_ecc->steps;
637 + uint32_t *eccpos = chip->cur_ecc->layout->eccpos;
638 uint32_t start_step = offset / ecc_size;
639 uint32_t end_step = (offset + data_len - 1) / ecc_size;
640 int oob_bytes = mtd->oobsize / ecc_steps;
641 @@ -2169,7 +2264,7 @@ static int nand_write_subpage_hwecc(stru
642
643 for (step = 0; step < ecc_steps; step++) {
644 /* configure controller for WRITE access */
645 - chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
646 + chip->cur_ecc->hwctl(mtd, NAND_ECC_WRITE);
647
648 /* write data (untouched subpages already masked by 0xFF) */
649 chip->write_buf(mtd, buf, ecc_size);
650 @@ -2178,7 +2273,7 @@ static int nand_write_subpage_hwecc(stru
651 if ((step < start_step) || (step > end_step))
652 memset(ecc_calc, 0xff, ecc_bytes);
653 else
654 - chip->ecc.calculate(mtd, buf, ecc_calc);
655 + chip->cur_ecc->calculate(mtd, buf, ecc_calc);
656
657 /* mask OOB of un-touched subpages by padding 0xFF */
658 /* if oob_required, preserve OOB metadata of written subpage */
659 @@ -2193,7 +2288,7 @@ static int nand_write_subpage_hwecc(stru
660 /* copy calculated ECC for whole page to chip->buffer->oob */
661 /* this include masked-value(0xFF) for unwritten subpages */
662 ecc_calc = chip->buffers->ecccalc;
663 - for (i = 0; i < chip->ecc.total; i++)
664 + for (i = 0; i < chip->cur_ecc->total; i++)
665 chip->oob_poi[eccpos[i]] = ecc_calc[i];
666
667 /* write OOB buffer to NAND device */
668 @@ -2217,29 +2312,29 @@ static int nand_write_page_syndrome(stru
669 struct nand_chip *chip,
670 const uint8_t *buf, int oob_required)
671 {
672 - int i, eccsize = chip->ecc.size;
673 - int eccbytes = chip->ecc.bytes;
674 - int eccsteps = chip->ecc.steps;
675 + int i, eccsize = chip->cur_ecc->size;
676 + int eccbytes = chip->cur_ecc->bytes;
677 + int eccsteps = chip->cur_ecc->steps;
678 const uint8_t *p = buf;
679 uint8_t *oob = chip->oob_poi;
680
681 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
682
683 - chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
684 + chip->cur_ecc->hwctl(mtd, NAND_ECC_WRITE);
685 chip->write_buf(mtd, p, eccsize);
686
687 - if (chip->ecc.prepad) {
688 - chip->write_buf(mtd, oob, chip->ecc.prepad);
689 - oob += chip->ecc.prepad;
690 + if (chip->cur_ecc->prepad) {
691 + chip->write_buf(mtd, oob, chip->cur_ecc->prepad);
692 + oob += chip->cur_ecc->prepad;
693 }
694
695 - chip->ecc.calculate(mtd, p, oob);
696 + chip->cur_ecc->calculate(mtd, p, oob);
697 chip->write_buf(mtd, oob, eccbytes);
698 oob += eccbytes;
699
700 - if (chip->ecc.postpad) {
701 - chip->write_buf(mtd, oob, chip->ecc.postpad);
702 - oob += chip->ecc.postpad;
703 + if (chip->cur_ecc->postpad) {
704 + chip->write_buf(mtd, oob, chip->cur_ecc->postpad);
705 + oob += chip->cur_ecc->postpad;
706 }
707 }
708
709 @@ -2270,7 +2365,7 @@ static int nand_write_page(struct mtd_in
710 int status, subpage;
711
712 if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
713 - chip->ecc.write_subpage)
714 + chip->cur_ecc->write_subpage)
715 subpage = offset || (data_len < mtd->writesize);
716 else
717 subpage = 0;
718 @@ -2278,13 +2373,15 @@ static int nand_write_page(struct mtd_in
719 chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
720
721 if (unlikely(raw))
722 - status = chip->ecc.write_page_raw(mtd, chip, buf,
723 - oob_required);
724 + status = chip->cur_ecc->write_page_raw(mtd, chip, buf,
725 + oob_required);
726 else if (subpage)
727 - status = chip->ecc.write_subpage(mtd, chip, offset, data_len,
728 - buf, oob_required);
729 + status = chip->cur_ecc->write_subpage(mtd, chip, offset,
730 + data_len, buf,
731 + oob_required);
732 else
733 - status = chip->ecc.write_page(mtd, chip, buf, oob_required);
734 + status = chip->cur_ecc->write_page(mtd, chip, buf,
735 + oob_required);
736
737 if (status < 0)
738 return status;
739 @@ -2343,7 +2440,7 @@ static uint8_t *nand_fill_oob(struct mtd
740 return oob + len;
741
742 case MTD_OPS_AUTO_OOB: {
743 - struct nand_oobfree *free = chip->ecc.layout->oobfree;
744 + struct nand_oobfree *free = chip->cur_ecc->layout->oobfree;
745 uint32_t boffs = 0, woffs = ops->ooboffs;
746 size_t bytes = 0;
747
748 @@ -2539,6 +2636,46 @@ static int panic_nand_write(struct mtd_i
749 }
750
751 /**
752 + * panic_nand_part_write - [MTD Interface] NAND write with ECC
753 + * @mtd: MTD device structure
754 + * @to: offset to write to
755 + * @len: number of bytes to write
756 + * @retlen: pointer to variable to store the number of written bytes
757 + * @buf: the data to write
758 + *
759 + * NAND write with ECC. Used when performing writes in interrupt context, this
760 + * may for example be called by mtdoops when writing an oops while in panic.
761 + */
762 +static int panic_nand_part_write(struct mtd_info *mtd, loff_t to, size_t len,
763 + size_t *retlen, const uint8_t *buf)
764 +{
765 + struct nand_chip *chip = mtd->priv;
766 + struct nand_part *part = to_nand_part(mtd);
767 + struct mtd_oob_ops ops;
768 + int ret;
769 +
770 + to += part->offset;
771 + /* Wait for the device to get ready */
772 + panic_nand_wait(part->master, chip, 400);
773 +
774 + /* Grab the device */
775 + panic_nand_get_device(chip, part->master, FL_WRITING);
776 + if (part->ecc)
777 + chip->cur_ecc = part->ecc;
778 +
779 + ops.len = len;
780 + ops.datbuf = (uint8_t *)buf;
781 + ops.oobbuf = NULL;
782 + ops.mode = MTD_OPS_PLACE_OOB;
783 +
784 + ret = nand_do_write_ops(part->master, to, &ops);
785 +
786 + chip->cur_ecc = &chip->ecc;
787 + *retlen = ops.retlen;
788 + return ret;
789 +}
790 +
791 +/**
792 * nand_write - [MTD Interface] NAND write with ECC
793 * @mtd: MTD device structure
794 * @to: offset to write to
795 @@ -2566,6 +2703,39 @@ static int nand_write(struct mtd_info *m
796 }
797
798 /**
799 + * nand_part_write - [MTD Interface] NAND write with ECC
800 + * @mtd: MTD device structure
801 + * @to: offset to write to
802 + * @len: number of bytes to write
803 + * @retlen: pointer to variable to store the number of written bytes
804 + * @buf: the data to write
805 + *
806 + * NAND write with ECC.
807 + */
808 +static int nand_part_write(struct mtd_info *mtd, loff_t to, size_t len,
809 + size_t *retlen, const uint8_t *buf)
810 +{
811 + struct nand_chip *chip = mtd->priv;
812 + struct nand_part *part = to_nand_part(mtd);
813 + struct mtd_oob_ops ops;
814 + int ret;
815 +
816 + to += part->offset;
817 + nand_get_device(part->master, FL_WRITING);
818 + if (part->ecc)
819 + chip->cur_ecc = part->ecc;
820 + ops.len = len;
821 + ops.datbuf = (uint8_t *)buf;
822 + ops.oobbuf = NULL;
823 + ops.mode = MTD_OPS_PLACE_OOB;
824 + ret = nand_do_write_ops(part->master, to, &ops);
825 + *retlen = ops.retlen;
826 + chip->cur_ecc = &chip->ecc;
827 + nand_release_device(part->master);
828 + return ret;
829 +}
830 +
831 +/**
832 * nand_do_write_oob - [MTD Interface] NAND write out-of-band
833 * @mtd: MTD device structure
834 * @to: offset to write to
835 @@ -2583,7 +2753,7 @@ static int nand_do_write_oob(struct mtd_
836 __func__, (unsigned int)to, (int)ops->ooblen);
837
838 if (ops->mode == MTD_OPS_AUTO_OOB)
839 - len = chip->ecc.layout->oobavail;
840 + len = chip->cur_ecc->layout->oobavail;
841 else
842 len = mtd->oobsize;
843
844 @@ -2637,9 +2807,11 @@ static int nand_do_write_oob(struct mtd_
845 nand_fill_oob(mtd, ops->oobbuf, ops->ooblen, ops);
846
847 if (ops->mode == MTD_OPS_RAW)
848 - status = chip->ecc.write_oob_raw(mtd, chip, page & chip->pagemask);
849 + status = chip->cur_ecc->write_oob_raw(mtd, chip,
850 + page & chip->pagemask);
851 else
852 - status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
853 + status = chip->cur_ecc->write_oob(mtd, chip,
854 + page & chip->pagemask);
855
856 chip->select_chip(mtd, -1);
857
858 @@ -2694,6 +2866,54 @@ out:
859 }
860
861 /**
862 + * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band
863 + * @mtd: MTD device structure
864 + * @to: offset to write to
865 + * @ops: oob operation description structure
866 + */
867 +static int nand_part_write_oob(struct mtd_info *mtd, loff_t to,
868 + struct mtd_oob_ops *ops)
869 +{
870 + struct nand_chip *chip = mtd->priv;
871 + struct nand_part *part = to_nand_part(mtd);
872 + int ret = -ENOTSUPP;
873 +
874 + ops->retlen = 0;
875 +
876 + /* Do not allow writes past end of device */
877 + if (ops->datbuf && (to + ops->len) > mtd->size) {
878 + pr_debug("%s: attempt to write beyond end of device\n",
879 + __func__);
880 + return -EINVAL;
881 + }
882 +
883 + to += part->offset;
884 + nand_get_device(part->master, FL_WRITING);
885 + if (part->ecc)
886 + chip->cur_ecc = part->ecc;
887 +
888 + switch (ops->mode) {
889 + case MTD_OPS_PLACE_OOB:
890 + case MTD_OPS_AUTO_OOB:
891 + case MTD_OPS_RAW:
892 + break;
893 +
894 + default:
895 + goto out;
896 + }
897 +
898 + if (!ops->datbuf)
899 + ret = nand_do_write_oob(part->master, to, ops);
900 + else
901 + ret = nand_do_write_ops(part->master, to, ops);
902 +
903 +out:
904 + chip->cur_ecc = &chip->ecc;
905 + nand_release_device(part->master);
906 + return ret;
907 +}
908 +
909 +/**
910 * single_erase - [GENERIC] NAND standard block erase command function
911 * @mtd: MTD device structure
912 * @page: the page address of the block which will be erased
913 @@ -2723,6 +2943,29 @@ static int nand_erase(struct mtd_info *m
914 }
915
916 /**
917 + * nand_part_erase - [MTD Interface] erase partition block(s)
918 + * @mtd: MTD device structure
919 + * @instr: erase instruction
920 + *
921 + * Erase one ore more blocks.
922 + */
923 +static int nand_part_erase(struct mtd_info *mtd, struct erase_info *instr)
924 +{
925 + struct nand_part *part = to_nand_part(mtd);
926 + int ret;
927 +
928 + instr->addr += part->offset;
929 + ret = nand_erase_nand(part->master, instr, 0);
930 + if (ret) {
931 + if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
932 + instr->fail_addr -= part->offset;
933 + instr->addr -= part->offset;
934 + }
935 +
936 + return ret;
937 +}
938 +
939 +/**
940 * nand_erase_nand - [INTERN] erase block(s)
941 * @mtd: MTD device structure
942 * @instr: erase instruction
943 @@ -2864,6 +3107,18 @@ static int nand_block_isbad(struct mtd_i
944 }
945
946 /**
947 + * nand_part_block_isbad - [MTD Interface] Check if block at offset is bad
948 + * @mtd: MTD device structure
949 + * @offs: offset relative to mtd start
950 + */
951 +static int nand_part_block_isbad(struct mtd_info *mtd, loff_t offs)
952 +{
953 + struct nand_part *part = to_nand_part(mtd);
954 +
955 + return nand_block_checkbad(part->master, part->offset + offs, 1, 0);
956 +}
957 +
958 +/**
959 * nand_block_markbad - [MTD Interface] Mark block at the given offset as bad
960 * @mtd: MTD device structure
961 * @ofs: offset relative to mtd start
962 @@ -2884,6 +3139,33 @@ static int nand_block_markbad(struct mtd
963 }
964
965 /**
966 + * nand_part_block_markbad - [MTD Interface] Mark block at the given offset as
967 + * bad
968 + * @mtd: MTD device structure
969 + * @ofs: offset relative to mtd start
970 + */
971 +static int nand_part_block_markbad(struct mtd_info *mtd, loff_t ofs)
972 +{
973 + struct nand_part *part = to_nand_part(mtd);
974 + int ret;
975 +
976 + ofs += part->offset;
977 + ret = nand_block_isbad(part->master, ofs);
978 + if (ret) {
979 + /* If it was bad already, return success and do nothing */
980 + if (ret > 0)
981 + return 0;
982 + return ret;
983 + }
984 +
985 + ret = nand_block_markbad_lowlevel(part->master, ofs);
986 + if (!ret)
987 + mtd->ecc_stats.badblocks++;
988 +
989 + return ret;
990 +}
991 +
992 +/**
993 * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
994 * @mtd: MTD device structure
995 * @chip: nand chip info structure
996 @@ -4099,6 +4381,169 @@ static int nand_ecc_ctrl_init(struct mtd
997 }
998
999 /**
1000 + * nand_add_partition - [NAND Interface] Add a NAND partition to a NAND device
1001 + * @master: MTD device structure representing the NAND device
1002 + * @part: NAND partition to add to the NAND device
1003 + *
1004 + * Adds a NAND partition to a NAND device.
1005 + * The NAND partition cannot overlap with another existing partition.
1006 + *
1007 + * Returns zero in case of success and a negative error code in case of failure.
1008 + */
1009 +int nand_add_partition(struct mtd_info *master, struct nand_part *part)
1010 +{
1011 + struct nand_chip *chip = master->priv;
1012 + struct mtd_info *mtd = &part->mtd;
1013 + struct nand_ecc_ctrl *ecc = part->ecc;
1014 + struct nand_part *pos;
1015 + bool inserted = false;
1016 + int ret;
1017 +
1018 + /* set up the MTD object for this partition */
1019 + mtd->type = master->type;
1020 + mtd->flags = master->flags & ~mtd->flags;
1021 + mtd->writesize = master->writesize;
1022 + mtd->writebufsize = master->writebufsize;
1023 + mtd->oobsize = master->oobsize;
1024 + mtd->oobavail = master->oobavail;
1025 + mtd->subpage_sft = master->subpage_sft;
1026 + mtd->erasesize = master->erasesize;
1027 +
1028 + mtd->priv = chip;
1029 + mtd->owner = master->owner;
1030 + mtd->backing_dev_info = master->backing_dev_info;
1031 +
1032 + mtd->dev.parent = master->dev.parent;
1033 +
1034 + if (ecc) {
1035 + ret = nand_ecc_ctrl_init(mtd, ecc);
1036 + if (ret)
1037 + return ret;
1038 + } else {
1039 + ecc = &chip->ecc;
1040 + }
1041 +
1042 + mtd->_erase = nand_part_erase;
1043 + mtd->_point = NULL;
1044 + mtd->_unpoint = NULL;
1045 + mtd->_read = nand_part_read;
1046 + mtd->_write = nand_part_write;
1047 + mtd->_panic_write = panic_nand_part_write;
1048 + mtd->_read_oob = nand_part_read_oob;
1049 + mtd->_write_oob = nand_part_write_oob;
1050 + mtd->_sync = nand_sync;
1051 + mtd->_lock = NULL;
1052 + mtd->_unlock = NULL;
1053 + mtd->_suspend = nand_suspend;
1054 + mtd->_resume = nand_resume;
1055 + mtd->_block_isbad = nand_part_block_isbad;
1056 + mtd->_block_markbad = nand_part_block_markbad;
1057 +
1058 + /* propagate ecc info to mtd_info */
1059 + mtd->ecclayout = ecc->layout;
1060 + mtd->ecc_strength = ecc->strength;
1061 + mtd->ecc_step_size = ecc->size;
1062 + /*
1063 + * Initialize bitflip_threshold to its default prior scan_bbt() call.
1064 + * scan_bbt() might invoke mtd_read(), thus bitflip_threshold must be
1065 + * properly set.
1066 + */
1067 + if (!mtd->bitflip_threshold)
1068 + mtd->bitflip_threshold = mtd->ecc_strength;
1069 +
1070 + part->master = master;
1071 +
1072 + mutex_lock(&chip->part_lock);
1073 + list_for_each_entry(pos, &chip->partitions, node) {
1074 + if (part->offset >= pos->offset + pos->mtd.size) {
1075 + continue;
1076 + } else if (part->offset + mtd->size > pos->offset) {
1077 + ret = -EINVAL;
1078 + goto out;
1079 + }
1080 +
1081 + list_add(&part->node, pos->node.prev);
1082 + inserted = true;
1083 + break;
1084 + }
1085 +
1086 + if (!inserted)
1087 + list_add_tail(&part->node, &chip->partitions);
1088 +
1089 + ret = mtd_device_register(mtd, NULL, 0);
1090 + if (ret) {
1091 + list_del(&part->node);
1092 + goto out;
1093 + }
1094 +
1095 + if (master->_block_isbad) {
1096 + uint64_t offs = 0;
1097 +
1098 + while (offs < mtd->size) {
1099 + if (mtd_block_isreserved(master, offs + part->offset))
1100 + mtd->ecc_stats.bbtblocks++;
1101 + else if (mtd_block_isbad(master, offs + part->offset))
1102 + mtd->ecc_stats.badblocks++;
1103 + offs += mtd->erasesize;
1104 + }
1105 + }
1106 +
1107 +out:
1108 + mutex_unlock(&chip->part_lock);
1109 + return ret;
1110 +}
1111 +EXPORT_SYMBOL(nand_add_partition);
1112 +
1113 +/**
1114 + * nand_del_partition - [NAND Interface] Delete a NAND part from a NAND dev
1115 + * @part: NAND partition to delete
1116 + *
1117 + * Deletes a NAND partition from a NAND device.
1118 + */
1119 +void nand_del_partition(struct nand_part *part)
1120 +{
1121 + struct nand_chip *chip = part->mtd.priv;
1122 +
1123 + mutex_lock(&chip->part_lock);
1124 + mtd_device_unregister(&part->mtd);
1125 + list_del(&part->node);
1126 + mutex_unlock(&chip->part_lock);
1127 +
1128 + if (part->ecc && part->ecc->mode == NAND_ECC_SOFT_BCH)
1129 + nand_bch_free((struct nand_bch_control *)part->ecc->priv);
1130 +
1131 + if (part->release)
1132 + part->release(part);
1133 +}
1134 +EXPORT_SYMBOL(nand_del_partition);
1135 +
1136 +/*
1137 + * NAND part release function. Used by nandpart_alloc as its release function.
1138 + */
1139 +static void nandpart_release(struct nand_part *part)
1140 +{
1141 + kfree(part);
1142 +}
1143 +
1144 +/**
1145 + * nandpart_alloc - [NAND Interface] Allocate a NAND part struct
1146 + *
1147 + * Allocate a NAND partition and assign the nandpart release function.
1148 + * This nand_part struct must be filled before passing it to the
1149 + * nand_add_partition function.
1150 + */
1151 +struct nand_part *nandpart_alloc(void)
1152 +{
1153 + struct nand_part *part = kzalloc(sizeof(*part), GFP_KERNEL);
1154 + if (!part)
1155 + return ERR_PTR(-ENOMEM);
1156 + part->release = nandpart_release;
1157 +
1158 + return part;
1159 +}
1160 +EXPORT_SYMBOL(nandpart_alloc);
1161 +
1162 +/**
1163 * nand_scan_tail - [NAND Interface] Scan for the NAND device
1164 * @mtd: MTD device structure
1165 *
1166 @@ -4146,6 +4591,11 @@ int nand_scan_tail(struct mtd_info *mtd)
1167 return ret;
1168 }
1169
1170 + INIT_LIST_HEAD(&chip->partitions);
1171 + mutex_init(&chip->part_lock);
1172 +
1173 + chip->cur_ecc = &chip->ecc;
1174 +
1175 /* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
1176 if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && nand_is_slc(chip)) {
1177 switch (ecc->steps) {
1178 --- a/drivers/mtd/nand/nand_bch.c
1179 +++ b/drivers/mtd/nand/nand_bch.c
1180 @@ -53,14 +53,14 @@ int nand_bch_calculate_ecc(struct mtd_in
1181 unsigned char *code)
1182 {
1183 const struct nand_chip *chip = mtd->priv;
1184 - struct nand_bch_control *nbc = chip->ecc.priv;
1185 + struct nand_bch_control *nbc = chip->cur_ecc->priv;
1186 unsigned int i;
1187
1188 - memset(code, 0, chip->ecc.bytes);
1189 - encode_bch(nbc->bch, buf, chip->ecc.size, code);
1190 + memset(code, 0, chip->cur_ecc->bytes);
1191 + encode_bch(nbc->bch, buf, chip->cur_ecc->size, code);
1192
1193 /* apply mask so that an erased page is a valid codeword */
1194 - for (i = 0; i < chip->ecc.bytes; i++)
1195 + for (i = 0; i < chip->cur_ecc->bytes; i++)
1196 code[i] ^= nbc->eccmask[i];
1197
1198 return 0;
1199 @@ -80,15 +80,15 @@ int nand_bch_correct_data(struct mtd_inf
1200 unsigned char *read_ecc, unsigned char *calc_ecc)
1201 {
1202 const struct nand_chip *chip = mtd->priv;
1203 - struct nand_bch_control *nbc = chip->ecc.priv;
1204 + struct nand_bch_control *nbc = chip->cur_ecc->priv;
1205 unsigned int *errloc = nbc->errloc;
1206 int i, count;
1207
1208 - count = decode_bch(nbc->bch, NULL, chip->ecc.size, read_ecc, calc_ecc,
1209 - NULL, errloc);
1210 + count = decode_bch(nbc->bch, NULL, chip->cur_ecc->size, read_ecc,
1211 + calc_ecc, NULL, errloc);
1212 if (count > 0) {
1213 for (i = 0; i < count; i++) {
1214 - if (errloc[i] < (chip->ecc.size*8))
1215 + if (errloc[i] < (chip->cur_ecc->size*8))
1216 /* error is located in data, correct it */
1217 buf[errloc[i] >> 3] ^= (1 << (errloc[i] & 7));
1218 /* else error in ecc, no action needed */
1219 --- a/drivers/mtd/nand/nand_ecc.c
1220 +++ b/drivers/mtd/nand/nand_ecc.c
1221 @@ -424,7 +424,7 @@ int nand_calculate_ecc(struct mtd_info *
1222 unsigned char *code)
1223 {
1224 __nand_calculate_ecc(buf,
1225 - ((struct nand_chip *)mtd->priv)->ecc.size, code);
1226 + ((struct nand_chip *)mtd->priv)->cur_ecc->size, code);
1227
1228 return 0;
1229 }
1230 @@ -524,7 +524,7 @@ int nand_correct_data(struct mtd_info *m
1231 unsigned char *read_ecc, unsigned char *calc_ecc)
1232 {
1233 return __nand_correct_data(buf, read_ecc, calc_ecc,
1234 - ((struct nand_chip *)mtd->priv)->ecc.size);
1235 + ((struct nand_chip *)mtd->priv)->cur_ecc->size);
1236 }
1237 EXPORT_SYMBOL(nand_correct_data);
1238
1239 --- a/include/linux/mtd/nand.h
1240 +++ b/include/linux/mtd/nand.h
1241 @@ -708,6 +708,7 @@ struct nand_chip {
1242 struct nand_hw_control *controller;
1243
1244 struct nand_ecc_ctrl ecc;
1245 + struct nand_ecc_ctrl *cur_ecc;
1246 struct nand_buffers *buffers;
1247 struct nand_hw_control hwcontrol;
1248
1249 @@ -717,9 +718,46 @@ struct nand_chip {
1250
1251 struct nand_bbt_descr *badblock_pattern;
1252
1253 + struct list_head partitions;
1254 + struct mutex part_lock;
1255 +
1256 void *priv;
1257 };
1258
1259 +/**
1260 + * struct nand_part - NAND partition structure
1261 + * @node: list node used to attach the partition to its NAND dev
1262 + * @mtd: MTD partiton info
1263 + * @master: MTD device representing the NAND chip
1264 + * @offset: partition offset
1265 + * @ecc: partition specific ECC struct
1266 + * @release: function used to release this nand_part struct
1267 + *
1268 + * NAND partitions work as standard MTD partitions except it can override
1269 + * NAND chip ECC handling.
1270 + * This is particularly useful for SoCs that need specific ECC configs to boot
1271 + * from NAND while these ECC configs do not fit the NAND chip ECC requirements.
1272 + */
1273 +struct nand_part {
1274 + struct list_head node;
1275 + struct mtd_info mtd;
1276 + struct mtd_info *master;
1277 + uint64_t offset;
1278 + struct nand_ecc_ctrl *ecc;
1279 + void (*release)(struct nand_part *part);
1280 +};
1281 +
1282 +static inline struct nand_part *to_nand_part(struct mtd_info *mtd)
1283 +{
1284 + return container_of(mtd, struct nand_part, mtd);
1285 +}
1286 +
1287 +int nand_add_partition(struct mtd_info *master, struct nand_part *part);
1288 +
1289 +void nand_del_partition(struct nand_part *part);
1290 +
1291 +struct nand_part *nandpart_alloc(void);
1292 +
1293 /*
1294 * NAND Flash Manufacturer ID Codes
1295 */