kernel: update 4.1 to 4.1.5
[openwrt.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   */