111-mtd-add-support-for-nand-partitions.patch 39 KB

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