03dcb07554a848c2f432f9947e43c915411ed788
[openwrt/staging/stintel.git] /
1 commit 97d90da8a886949f09bb4754843fb0b504956ad2
2 Author: Boris Brezillon <boris.brezillon@free-electrons.com>
3 Date: Thu Nov 30 18:01:29 2017 +0100
4
5 mtd: nand: provide several helpers to do common NAND operations
6
7 This is part of the process of removing direct calls to ->cmdfunc()
8 outside of the core in order to introduce a better interface to execute
9 NAND operations.
10
11 Here we provide several helpers and make use of them to remove all
12 direct calls to ->cmdfunc(). This way, we can easily modify those
13 helpers to make use of the new ->exec_op() interface when available.
14
15 Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
16 [miquel.raynal@free-electrons.com: rebased and fixed some conflicts]
17 Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
18 Acked-by: Masahiro Yamada <yamada.masahiro@socionext.com>
19
20 --- a/drivers/mtd/nand/nand_base.c
21 +++ b/drivers/mtd/nand/nand_base.c
22 @@ -561,14 +561,19 @@ static int nand_block_markbad_lowlevel(s
23 static int nand_check_wp(struct mtd_info *mtd)
24 {
25 struct nand_chip *chip = mtd_to_nand(mtd);
26 + u8 status;
27 + int ret;
28
29 /* Broken xD cards report WP despite being writable */
30 if (chip->options & NAND_BROKEN_XD)
31 return 0;
32
33 /* Check the WP bit */
34 - chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
35 - return (chip->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
36 + ret = nand_status_op(chip, &status);
37 + if (ret)
38 + return ret;
39 +
40 + return status & NAND_STATUS_WP ? 0 : 1;
41 }
42
43 /**
44 @@ -667,10 +672,17 @@ EXPORT_SYMBOL_GPL(nand_wait_ready);
45 static void nand_wait_status_ready(struct mtd_info *mtd, unsigned long timeo)
46 {
47 register struct nand_chip *chip = mtd_to_nand(mtd);
48 + int ret;
49
50 timeo = jiffies + msecs_to_jiffies(timeo);
51 do {
52 - if ((chip->read_byte(mtd) & NAND_STATUS_READY))
53 + u8 status;
54 +
55 + ret = nand_read_data_op(chip, &status, sizeof(status), true);
56 + if (ret)
57 + return;
58 +
59 + if (status & NAND_STATUS_READY)
60 break;
61 touch_softlockup_watchdog();
62 } while (time_before(jiffies, timeo));
63 @@ -1021,7 +1033,15 @@ static void panic_nand_wait(struct mtd_i
64 if (chip->dev_ready(mtd))
65 break;
66 } else {
67 - if (chip->read_byte(mtd) & NAND_STATUS_READY)
68 + int ret;
69 + u8 status;
70 +
71 + ret = nand_read_data_op(chip, &status, sizeof(status),
72 + true);
73 + if (ret)
74 + return;
75 +
76 + if (status & NAND_STATUS_READY)
77 break;
78 }
79 mdelay(1);
80 @@ -1038,8 +1058,9 @@ static void panic_nand_wait(struct mtd_i
81 static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
82 {
83
84 - int status;
85 unsigned long timeo = 400;
86 + u8 status;
87 + int ret;
88
89 /*
90 * Apply this short delay always to ensure that we do wait tWB in any
91 @@ -1047,7 +1068,9 @@ static int nand_wait(struct mtd_info *mt
92 */
93 ndelay(100);
94
95 - chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
96 + ret = nand_status_op(chip, NULL);
97 + if (ret)
98 + return ret;
99
100 if (in_interrupt() || oops_in_progress)
101 panic_nand_wait(mtd, chip, timeo);
102 @@ -1058,14 +1081,22 @@ static int nand_wait(struct mtd_info *mt
103 if (chip->dev_ready(mtd))
104 break;
105 } else {
106 - if (chip->read_byte(mtd) & NAND_STATUS_READY)
107 + ret = nand_read_data_op(chip, &status,
108 + sizeof(status), true);
109 + if (ret)
110 + return ret;
111 +
112 + if (status & NAND_STATUS_READY)
113 break;
114 }
115 cond_resched();
116 } while (time_before(jiffies, timeo));
117 }
118
119 - status = (int)chip->read_byte(mtd);
120 + ret = nand_read_data_op(chip, &status, sizeof(status), true);
121 + if (ret)
122 + return ret;
123 +
124 /* This can happen if in case of timeout or buggy dev_ready */
125 WARN_ON(!(status & NAND_STATUS_READY));
126 return status;
127 @@ -1220,6 +1251,516 @@ static void nand_release_data_interface(
128 }
129
130 /**
131 + * nand_read_page_op - Do a READ PAGE operation
132 + * @chip: The NAND chip
133 + * @page: page to read
134 + * @offset_in_page: offset within the page
135 + * @buf: buffer used to store the data
136 + * @len: length of the buffer
137 + *
138 + * This function issues a READ PAGE operation.
139 + * This function does not select/unselect the CS line.
140 + *
141 + * Returns 0 on success, a negative error code otherwise.
142 + */
143 +int nand_read_page_op(struct nand_chip *chip, unsigned int page,
144 + unsigned int offset_in_page, void *buf, unsigned int len)
145 +{
146 + struct mtd_info *mtd = nand_to_mtd(chip);
147 +
148 + if (len && !buf)
149 + return -EINVAL;
150 +
151 + if (offset_in_page + len > mtd->writesize + mtd->oobsize)
152 + return -EINVAL;
153 +
154 + chip->cmdfunc(mtd, NAND_CMD_READ0, offset_in_page, page);
155 + if (len)
156 + chip->read_buf(mtd, buf, len);
157 +
158 + return 0;
159 +}
160 +EXPORT_SYMBOL_GPL(nand_read_page_op);
161 +
162 +/**
163 + * nand_read_param_page_op - Do a READ PARAMETER PAGE operation
164 + * @chip: The NAND chip
165 + * @page: parameter page to read
166 + * @buf: buffer used to store the data
167 + * @len: length of the buffer
168 + *
169 + * This function issues a READ PARAMETER PAGE operation.
170 + * This function does not select/unselect the CS line.
171 + *
172 + * Returns 0 on success, a negative error code otherwise.
173 + */
174 +static int nand_read_param_page_op(struct nand_chip *chip, u8 page, void *buf,
175 + unsigned int len)
176 +{
177 + struct mtd_info *mtd = nand_to_mtd(chip);
178 + unsigned int i;
179 + u8 *p = buf;
180 +
181 + if (len && !buf)
182 + return -EINVAL;
183 +
184 + chip->cmdfunc(mtd, NAND_CMD_PARAM, page, -1);
185 + for (i = 0; i < len; i++)
186 + p[i] = chip->read_byte(mtd);
187 +
188 + return 0;
189 +}
190 +
191 +/**
192 + * nand_change_read_column_op - Do a CHANGE READ COLUMN operation
193 + * @chip: The NAND chip
194 + * @offset_in_page: offset within the page
195 + * @buf: buffer used to store the data
196 + * @len: length of the buffer
197 + * @force_8bit: force 8-bit bus access
198 + *
199 + * This function issues a CHANGE READ COLUMN operation.
200 + * This function does not select/unselect the CS line.
201 + *
202 + * Returns 0 on success, a negative error code otherwise.
203 + */
204 +int nand_change_read_column_op(struct nand_chip *chip,
205 + unsigned int offset_in_page, void *buf,
206 + unsigned int len, bool force_8bit)
207 +{
208 + struct mtd_info *mtd = nand_to_mtd(chip);
209 +
210 + if (len && !buf)
211 + return -EINVAL;
212 +
213 + if (offset_in_page + len > mtd->writesize + mtd->oobsize)
214 + return -EINVAL;
215 +
216 + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, offset_in_page, -1);
217 + if (len)
218 + chip->read_buf(mtd, buf, len);
219 +
220 + return 0;
221 +}
222 +EXPORT_SYMBOL_GPL(nand_change_read_column_op);
223 +
224 +/**
225 + * nand_read_oob_op - Do a READ OOB operation
226 + * @chip: The NAND chip
227 + * @page: page to read
228 + * @offset_in_oob: offset within the OOB area
229 + * @buf: buffer used to store the data
230 + * @len: length of the buffer
231 + *
232 + * This function issues a READ OOB operation.
233 + * This function does not select/unselect the CS line.
234 + *
235 + * Returns 0 on success, a negative error code otherwise.
236 + */
237 +int nand_read_oob_op(struct nand_chip *chip, unsigned int page,
238 + unsigned int offset_in_oob, void *buf, unsigned int len)
239 +{
240 + struct mtd_info *mtd = nand_to_mtd(chip);
241 +
242 + if (len && !buf)
243 + return -EINVAL;
244 +
245 + if (offset_in_oob + len > mtd->oobsize)
246 + return -EINVAL;
247 +
248 + chip->cmdfunc(mtd, NAND_CMD_READOOB, offset_in_oob, page);
249 + if (len)
250 + chip->read_buf(mtd, buf, len);
251 +
252 + return 0;
253 +}
254 +EXPORT_SYMBOL_GPL(nand_read_oob_op);
255 +
256 +/**
257 + * nand_prog_page_begin_op - starts a PROG PAGE operation
258 + * @chip: The NAND chip
259 + * @page: page to write
260 + * @offset_in_page: offset within the page
261 + * @buf: buffer containing the data to write to the page
262 + * @len: length of the buffer
263 + *
264 + * This function issues the first half of a PROG PAGE operation.
265 + * This function does not select/unselect the CS line.
266 + *
267 + * Returns 0 on success, a negative error code otherwise.
268 + */
269 +int nand_prog_page_begin_op(struct nand_chip *chip, unsigned int page,
270 + unsigned int offset_in_page, const void *buf,
271 + unsigned int len)
272 +{
273 + struct mtd_info *mtd = nand_to_mtd(chip);
274 +
275 + if (len && !buf)
276 + return -EINVAL;
277 +
278 + if (offset_in_page + len > mtd->writesize + mtd->oobsize)
279 + return -EINVAL;
280 +
281 + chip->cmdfunc(mtd, NAND_CMD_SEQIN, offset_in_page, page);
282 +
283 + if (buf)
284 + chip->write_buf(mtd, buf, len);
285 +
286 + return 0;
287 +}
288 +EXPORT_SYMBOL_GPL(nand_prog_page_begin_op);
289 +
290 +/**
291 + * nand_prog_page_end_op - ends a PROG PAGE operation
292 + * @chip: The NAND chip
293 + *
294 + * This function issues the second half of a PROG PAGE operation.
295 + * This function does not select/unselect the CS line.
296 + *
297 + * Returns 0 on success, a negative error code otherwise.
298 + */
299 +int nand_prog_page_end_op(struct nand_chip *chip)
300 +{
301 + struct mtd_info *mtd = nand_to_mtd(chip);
302 + int status;
303 +
304 + chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
305 +
306 + status = chip->waitfunc(mtd, chip);
307 + if (status & NAND_STATUS_FAIL)
308 + return -EIO;
309 +
310 + return 0;
311 +}
312 +EXPORT_SYMBOL_GPL(nand_prog_page_end_op);
313 +
314 +/**
315 + * nand_prog_page_op - Do a full PROG PAGE operation
316 + * @chip: The NAND chip
317 + * @page: page to write
318 + * @offset_in_page: offset within the page
319 + * @buf: buffer containing the data to write to the page
320 + * @len: length of the buffer
321 + *
322 + * This function issues a full PROG PAGE operation.
323 + * This function does not select/unselect the CS line.
324 + *
325 + * Returns 0 on success, a negative error code otherwise.
326 + */
327 +int nand_prog_page_op(struct nand_chip *chip, unsigned int page,
328 + unsigned int offset_in_page, const void *buf,
329 + unsigned int len)
330 +{
331 + struct mtd_info *mtd = nand_to_mtd(chip);
332 + int status;
333 +
334 + if (!len || !buf)
335 + return -EINVAL;
336 +
337 + if (offset_in_page + len > mtd->writesize + mtd->oobsize)
338 + return -EINVAL;
339 +
340 + chip->cmdfunc(mtd, NAND_CMD_SEQIN, offset_in_page, page);
341 + chip->write_buf(mtd, buf, len);
342 + chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
343 +
344 + status = chip->waitfunc(mtd, chip);
345 + if (status & NAND_STATUS_FAIL)
346 + return -EIO;
347 +
348 + return 0;
349 +}
350 +EXPORT_SYMBOL_GPL(nand_prog_page_op);
351 +
352 +/**
353 + * nand_change_write_column_op - Do a CHANGE WRITE COLUMN operation
354 + * @chip: The NAND chip
355 + * @offset_in_page: offset within the page
356 + * @buf: buffer containing the data to send to the NAND
357 + * @len: length of the buffer
358 + * @force_8bit: force 8-bit bus access
359 + *
360 + * This function issues a CHANGE WRITE COLUMN operation.
361 + * This function does not select/unselect the CS line.
362 + *
363 + * Returns 0 on success, a negative error code otherwise.
364 + */
365 +int nand_change_write_column_op(struct nand_chip *chip,
366 + unsigned int offset_in_page,
367 + const void *buf, unsigned int len,
368 + bool force_8bit)
369 +{
370 + struct mtd_info *mtd = nand_to_mtd(chip);
371 +
372 + if (len && !buf)
373 + return -EINVAL;
374 +
375 + if (offset_in_page + len > mtd->writesize + mtd->oobsize)
376 + return -EINVAL;
377 +
378 + chip->cmdfunc(mtd, NAND_CMD_RNDIN, offset_in_page, -1);
379 + if (len)
380 + chip->write_buf(mtd, buf, len);
381 +
382 + return 0;
383 +}
384 +EXPORT_SYMBOL_GPL(nand_change_write_column_op);
385 +
386 +/**
387 + * nand_readid_op - Do a READID operation
388 + * @chip: The NAND chip
389 + * @addr: address cycle to pass after the READID command
390 + * @buf: buffer used to store the ID
391 + * @len: length of the buffer
392 + *
393 + * This function sends a READID command and reads back the ID returned by the
394 + * NAND.
395 + * This function does not select/unselect the CS line.
396 + *
397 + * Returns 0 on success, a negative error code otherwise.
398 + */
399 +int nand_readid_op(struct nand_chip *chip, u8 addr, void *buf,
400 + unsigned int len)
401 +{
402 + struct mtd_info *mtd = nand_to_mtd(chip);
403 + unsigned int i;
404 + u8 *id = buf;
405 +
406 + if (len && !buf)
407 + return -EINVAL;
408 +
409 + chip->cmdfunc(mtd, NAND_CMD_READID, addr, -1);
410 +
411 + for (i = 0; i < len; i++)
412 + id[i] = chip->read_byte(mtd);
413 +
414 + return 0;
415 +}
416 +EXPORT_SYMBOL_GPL(nand_readid_op);
417 +
418 +/**
419 + * nand_status_op - Do a STATUS operation
420 + * @chip: The NAND chip
421 + * @status: out variable to store the NAND status
422 + *
423 + * This function sends a STATUS command and reads back the status returned by
424 + * the NAND.
425 + * This function does not select/unselect the CS line.
426 + *
427 + * Returns 0 on success, a negative error code otherwise.
428 + */
429 +int nand_status_op(struct nand_chip *chip, u8 *status)
430 +{
431 + struct mtd_info *mtd = nand_to_mtd(chip);
432 +
433 + chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
434 + if (status)
435 + *status = chip->read_byte(mtd);
436 +
437 + return 0;
438 +}
439 +EXPORT_SYMBOL_GPL(nand_status_op);
440 +
441 +/**
442 + * nand_exit_status_op - Exit a STATUS operation
443 + * @chip: The NAND chip
444 + *
445 + * This function sends a READ0 command to cancel the effect of the STATUS
446 + * command to avoid reading only the status until a new read command is sent.
447 + *
448 + * This function does not select/unselect the CS line.
449 + *
450 + * Returns 0 on success, a negative error code otherwise.
451 + */
452 +int nand_exit_status_op(struct nand_chip *chip)
453 +{
454 + struct mtd_info *mtd = nand_to_mtd(chip);
455 +
456 + chip->cmdfunc(mtd, NAND_CMD_READ0, -1, -1);
457 +
458 + return 0;
459 +}
460 +EXPORT_SYMBOL_GPL(nand_exit_status_op);
461 +
462 +/**
463 + * nand_erase_op - Do an erase operation
464 + * @chip: The NAND chip
465 + * @eraseblock: block to erase
466 + *
467 + * This function sends an ERASE command and waits for the NAND to be ready
468 + * before returning.
469 + * This function does not select/unselect the CS line.
470 + *
471 + * Returns 0 on success, a negative error code otherwise.
472 + */
473 +int nand_erase_op(struct nand_chip *chip, unsigned int eraseblock)
474 +{
475 + struct mtd_info *mtd = nand_to_mtd(chip);
476 + unsigned int page = eraseblock <<
477 + (chip->phys_erase_shift - chip->page_shift);
478 + int status;
479 +
480 + chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
481 + chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
482 +
483 + status = chip->waitfunc(mtd, chip);
484 + if (status < 0)
485 + return status;
486 +
487 + if (status & NAND_STATUS_FAIL)
488 + return -EIO;
489 +
490 + return 0;
491 +}
492 +EXPORT_SYMBOL_GPL(nand_erase_op);
493 +
494 +/**
495 + * nand_set_features_op - Do a SET FEATURES operation
496 + * @chip: The NAND chip
497 + * @feature: feature id
498 + * @data: 4 bytes of data
499 + *
500 + * This function sends a SET FEATURES command and waits for the NAND to be
501 + * ready before returning.
502 + * This function does not select/unselect the CS line.
503 + *
504 + * Returns 0 on success, a negative error code otherwise.
505 + */
506 +static int nand_set_features_op(struct nand_chip *chip, u8 feature,
507 + const void *data)
508 +{
509 + struct mtd_info *mtd = nand_to_mtd(chip);
510 + const u8 *params = data;
511 + int i, status;
512 +
513 + chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, feature, -1);
514 + for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
515 + chip->write_byte(mtd, params[i]);
516 +
517 + status = chip->waitfunc(mtd, chip);
518 + if (status & NAND_STATUS_FAIL)
519 + return -EIO;
520 +
521 + return 0;
522 +}
523 +
524 +/**
525 + * nand_get_features_op - Do a GET FEATURES operation
526 + * @chip: The NAND chip
527 + * @feature: feature id
528 + * @data: 4 bytes of data
529 + *
530 + * This function sends a GET FEATURES command and waits for the NAND to be
531 + * ready before returning.
532 + * This function does not select/unselect the CS line.
533 + *
534 + * Returns 0 on success, a negative error code otherwise.
535 + */
536 +static int nand_get_features_op(struct nand_chip *chip, u8 feature,
537 + void *data)
538 +{
539 + struct mtd_info *mtd = nand_to_mtd(chip);
540 + u8 *params = data;
541 + int i;
542 +
543 + chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, feature, -1);
544 + for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
545 + params[i] = chip->read_byte(mtd);
546 +
547 + return 0;
548 +}
549 +
550 +/**
551 + * nand_reset_op - Do a reset operation
552 + * @chip: The NAND chip
553 + *
554 + * This function sends a RESET command and waits for the NAND to be ready
555 + * before returning.
556 + * This function does not select/unselect the CS line.
557 + *
558 + * Returns 0 on success, a negative error code otherwise.
559 + */
560 +int nand_reset_op(struct nand_chip *chip)
561 +{
562 + struct mtd_info *mtd = nand_to_mtd(chip);
563 +
564 + chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
565 +
566 + return 0;
567 +}
568 +EXPORT_SYMBOL_GPL(nand_reset_op);
569 +
570 +/**
571 + * nand_read_data_op - Read data from the NAND
572 + * @chip: The NAND chip
573 + * @buf: buffer used to store the data
574 + * @len: length of the buffer
575 + * @force_8bit: force 8-bit bus access
576 + *
577 + * This function does a raw data read on the bus. Usually used after launching
578 + * another NAND operation like nand_read_page_op().
579 + * This function does not select/unselect the CS line.
580 + *
581 + * Returns 0 on success, a negative error code otherwise.
582 + */
583 +int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len,
584 + bool force_8bit)
585 +{
586 + struct mtd_info *mtd = nand_to_mtd(chip);
587 +
588 + if (!len || !buf)
589 + return -EINVAL;
590 +
591 + if (force_8bit) {
592 + u8 *p = buf;
593 + unsigned int i;
594 +
595 + for (i = 0; i < len; i++)
596 + p[i] = chip->read_byte(mtd);
597 + } else {
598 + chip->read_buf(mtd, buf, len);
599 + }
600 +
601 + return 0;
602 +}
603 +EXPORT_SYMBOL_GPL(nand_read_data_op);
604 +
605 +/**
606 + * nand_write_data_op - Write data from the NAND
607 + * @chip: The NAND chip
608 + * @buf: buffer containing the data to send on the bus
609 + * @len: length of the buffer
610 + * @force_8bit: force 8-bit bus access
611 + *
612 + * This function does a raw data write on the bus. Usually used after launching
613 + * another NAND operation like nand_write_page_begin_op().
614 + * This function does not select/unselect the CS line.
615 + *
616 + * Returns 0 on success, a negative error code otherwise.
617 + */
618 +int nand_write_data_op(struct nand_chip *chip, const void *buf,
619 + unsigned int len, bool force_8bit)
620 +{
621 + struct mtd_info *mtd = nand_to_mtd(chip);
622 +
623 + if (!len || !buf)
624 + return -EINVAL;
625 +
626 + if (force_8bit) {
627 + const u8 *p = buf;
628 + unsigned int i;
629 +
630 + for (i = 0; i < len; i++)
631 + chip->write_byte(mtd, p[i]);
632 + } else {
633 + chip->write_buf(mtd, buf, len);
634 + }
635 +
636 + return 0;
637 +}
638 +EXPORT_SYMBOL_GPL(nand_write_data_op);
639 +
640 +/**
641 * nand_reset - Reset and initialize a NAND device
642 * @chip: The NAND chip
643 * @chipnr: Internal die id
644 @@ -1240,8 +1781,10 @@ int nand_reset(struct nand_chip *chip, i
645 * interface settings, hence this weird ->select_chip() dance.
646 */
647 chip->select_chip(mtd, chipnr);
648 - chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
649 + ret = nand_reset_op(chip);
650 chip->select_chip(mtd, -1);
651 + if (ret)
652 + return ret;
653
654 chip->select_chip(mtd, chipnr);
655 ret = nand_setup_data_interface(chip, chipnr);
656 @@ -1397,9 +1940,19 @@ EXPORT_SYMBOL(nand_check_erased_ecc_chun
657 int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
658 uint8_t *buf, int oob_required, int page)
659 {
660 - chip->read_buf(mtd, buf, mtd->writesize);
661 - if (oob_required)
662 - chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
663 + int ret;
664 +
665 + ret = nand_read_data_op(chip, buf, mtd->writesize, false);
666 + if (ret)
667 + return ret;
668 +
669 + if (oob_required) {
670 + ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize,
671 + false);
672 + if (ret)
673 + return ret;
674 + }
675 +
676 return 0;
677 }
678 EXPORT_SYMBOL(nand_read_page_raw);
679 @@ -1421,29 +1974,46 @@ static int nand_read_page_raw_syndrome(s
680 int eccsize = chip->ecc.size;
681 int eccbytes = chip->ecc.bytes;
682 uint8_t *oob = chip->oob_poi;
683 - int steps, size;
684 + int steps, size, ret;
685
686 for (steps = chip->ecc.steps; steps > 0; steps--) {
687 - chip->read_buf(mtd, buf, eccsize);
688 + ret = nand_read_data_op(chip, buf, eccsize, false);
689 + if (ret)
690 + return ret;
691 +
692 buf += eccsize;
693
694 if (chip->ecc.prepad) {
695 - chip->read_buf(mtd, oob, chip->ecc.prepad);
696 + ret = nand_read_data_op(chip, oob, chip->ecc.prepad,
697 + false);
698 + if (ret)
699 + return ret;
700 +
701 oob += chip->ecc.prepad;
702 }
703
704 - chip->read_buf(mtd, oob, eccbytes);
705 + ret = nand_read_data_op(chip, oob, eccbytes, false);
706 + if (ret)
707 + return ret;
708 +
709 oob += eccbytes;
710
711 if (chip->ecc.postpad) {
712 - chip->read_buf(mtd, oob, chip->ecc.postpad);
713 + ret = nand_read_data_op(chip, oob, chip->ecc.postpad,
714 + false);
715 + if (ret)
716 + return ret;
717 +
718 oob += chip->ecc.postpad;
719 }
720 }
721
722 size = mtd->oobsize - (oob - chip->oob_poi);
723 - if (size)
724 - chip->read_buf(mtd, oob, size);
725 + if (size) {
726 + ret = nand_read_data_op(chip, oob, size, false);
727 + if (ret)
728 + return ret;
729 + }
730
731 return 0;
732 }
733 @@ -1532,7 +2102,9 @@ static int nand_read_subpage(struct mtd_
734 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_col_addr, -1);
735
736 p = bufpoi + data_col_addr;
737 - chip->read_buf(mtd, p, datafrag_len);
738 + ret = nand_read_data_op(chip, p, datafrag_len, false);
739 + if (ret)
740 + return ret;
741
742 /* Calculate ECC */
743 for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size)
744 @@ -1550,8 +2122,11 @@ static int nand_read_subpage(struct mtd_
745 gaps = 1;
746
747 if (gaps) {
748 - chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
749 - chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
750 + ret = nand_change_read_column_op(chip, mtd->writesize,
751 + chip->oob_poi, mtd->oobsize,
752 + false);
753 + if (ret)
754 + return ret;
755 } else {
756 /*
757 * Send the command to read the particular ECC bytes take care
758 @@ -1565,9 +2140,12 @@ static int nand_read_subpage(struct mtd_
759 (busw - 1))
760 aligned_len++;
761
762 - chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
763 - mtd->writesize + aligned_pos, -1);
764 - chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len);
765 + ret = nand_change_read_column_op(chip,
766 + mtd->writesize + aligned_pos,
767 + &chip->oob_poi[aligned_pos],
768 + aligned_len, false);
769 + if (ret)
770 + return ret;
771 }
772
773 ret = mtd_ooblayout_get_eccbytes(mtd, chip->buffers->ecccode,
774 @@ -1624,10 +2202,17 @@ static int nand_read_page_hwecc(struct m
775
776 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
777 chip->ecc.hwctl(mtd, NAND_ECC_READ);
778 - chip->read_buf(mtd, p, eccsize);
779 +
780 + ret = nand_read_data_op(chip, p, eccsize, false);
781 + if (ret)
782 + return ret;
783 +
784 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
785 }
786 - chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
787 +
788 + ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize, false);
789 + if (ret)
790 + return ret;
791
792 ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
793 chip->ecc.total);
794 @@ -1686,9 +2271,13 @@ static int nand_read_page_hwecc_oob_firs
795 unsigned int max_bitflips = 0;
796
797 /* Read the OOB area first */
798 - chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
799 - chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
800 - chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
801 + ret = nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
802 + if (ret)
803 + return ret;
804 +
805 + ret = nand_read_page_op(chip, page, 0, NULL, 0);
806 + if (ret)
807 + return ret;
808
809 ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
810 chip->ecc.total);
811 @@ -1699,7 +2288,11 @@ static int nand_read_page_hwecc_oob_firs
812 int stat;
813
814 chip->ecc.hwctl(mtd, NAND_ECC_READ);
815 - chip->read_buf(mtd, p, eccsize);
816 +
817 + ret = nand_read_data_op(chip, p, eccsize, false);
818 + if (ret)
819 + return ret;
820 +
821 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
822
823 stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL);
824 @@ -1736,7 +2329,7 @@ static int nand_read_page_hwecc_oob_firs
825 static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
826 uint8_t *buf, int oob_required, int page)
827 {
828 - int i, eccsize = chip->ecc.size;
829 + int ret, i, eccsize = chip->ecc.size;
830 int eccbytes = chip->ecc.bytes;
831 int eccsteps = chip->ecc.steps;
832 int eccpadbytes = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
833 @@ -1748,21 +2341,36 @@ static int nand_read_page_syndrome(struc
834 int stat;
835
836 chip->ecc.hwctl(mtd, NAND_ECC_READ);
837 - chip->read_buf(mtd, p, eccsize);
838 +
839 + ret = nand_read_data_op(chip, p, eccsize, false);
840 + if (ret)
841 + return ret;
842
843 if (chip->ecc.prepad) {
844 - chip->read_buf(mtd, oob, chip->ecc.prepad);
845 + ret = nand_read_data_op(chip, oob, chip->ecc.prepad,
846 + false);
847 + if (ret)
848 + return ret;
849 +
850 oob += chip->ecc.prepad;
851 }
852
853 chip->ecc.hwctl(mtd, NAND_ECC_READSYN);
854 - chip->read_buf(mtd, oob, eccbytes);
855 +
856 + ret = nand_read_data_op(chip, oob, eccbytes, false);
857 + if (ret)
858 + return ret;
859 +
860 stat = chip->ecc.correct(mtd, p, oob, NULL);
861
862 oob += eccbytes;
863
864 if (chip->ecc.postpad) {
865 - chip->read_buf(mtd, oob, chip->ecc.postpad);
866 + ret = nand_read_data_op(chip, oob, chip->ecc.postpad,
867 + false);
868 + if (ret)
869 + return ret;
870 +
871 oob += chip->ecc.postpad;
872 }
873
874 @@ -1786,8 +2394,11 @@ static int nand_read_page_syndrome(struc
875
876 /* Calculate remaining oob bytes */
877 i = mtd->oobsize - (oob - chip->oob_poi);
878 - if (i)
879 - chip->read_buf(mtd, oob, i);
880 + if (i) {
881 + ret = nand_read_data_op(chip, oob, i, false);
882 + if (ret)
883 + return ret;
884 + }
885
886 return max_bitflips;
887 }
888 @@ -1908,8 +2519,11 @@ static int nand_do_read_ops(struct mtd_i
889 __func__, buf);
890
891 read_retry:
892 - if (nand_standard_page_accessors(&chip->ecc))
893 - chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
894 + if (nand_standard_page_accessors(&chip->ecc)) {
895 + ret = nand_read_page_op(chip, page, 0, NULL, 0);
896 + if (ret)
897 + break;
898 + }
899
900 /*
901 * Now read the page into the buffer. Absent an error,
902 @@ -2068,9 +2682,7 @@ static int nand_read(struct mtd_info *mt
903 */
904 int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip, int page)
905 {
906 - chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
907 - chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
908 - return 0;
909 + return nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
910 }
911 EXPORT_SYMBOL(nand_read_oob_std);
912
913 @@ -2088,25 +2700,43 @@ int nand_read_oob_syndrome(struct mtd_in
914 int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
915 int eccsize = chip->ecc.size;
916 uint8_t *bufpoi = chip->oob_poi;
917 - int i, toread, sndrnd = 0, pos;
918 + int i, toread, sndrnd = 0, pos, ret;
919 +
920 + ret = nand_read_page_op(chip, page, chip->ecc.size, NULL, 0);
921 + if (ret)
922 + return ret;
923
924 - chip->cmdfunc(mtd, NAND_CMD_READ0, chip->ecc.size, page);
925 for (i = 0; i < chip->ecc.steps; i++) {
926 if (sndrnd) {
927 + int ret;
928 +
929 pos = eccsize + i * (eccsize + chunk);
930 if (mtd->writesize > 512)
931 - chip->cmdfunc(mtd, NAND_CMD_RNDOUT, pos, -1);
932 + ret = nand_change_read_column_op(chip, pos,
933 + NULL, 0,
934 + false);
935 else
936 - chip->cmdfunc(mtd, NAND_CMD_READ0, pos, page);
937 + ret = nand_read_page_op(chip, page, pos, NULL,
938 + 0);
939 +
940 + if (ret)
941 + return ret;
942 } else
943 sndrnd = 1;
944 toread = min_t(int, length, chunk);
945 - chip->read_buf(mtd, bufpoi, toread);
946 +
947 + ret = nand_read_data_op(chip, bufpoi, toread, false);
948 + if (ret)
949 + return ret;
950 +
951 bufpoi += toread;
952 length -= toread;
953 }
954 - if (length > 0)
955 - chip->read_buf(mtd, bufpoi, length);
956 + if (length > 0) {
957 + ret = nand_read_data_op(chip, bufpoi, length, false);
958 + if (ret)
959 + return ret;
960 + }
961
962 return 0;
963 }
964 @@ -2120,18 +2750,8 @@ EXPORT_SYMBOL(nand_read_oob_syndrome);
965 */
966 int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip, int page)
967 {
968 - int status = 0;
969 - const uint8_t *buf = chip->oob_poi;
970 - int length = mtd->oobsize;
971 -
972 - chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
973 - chip->write_buf(mtd, buf, length);
974 - /* Send command to program the OOB data */
975 - chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
976 -
977 - status = chip->waitfunc(mtd, chip);
978 -
979 - return status & NAND_STATUS_FAIL ? -EIO : 0;
980 + return nand_prog_page_op(chip, page, mtd->writesize, chip->oob_poi,
981 + mtd->oobsize);
982 }
983 EXPORT_SYMBOL(nand_write_oob_std);
984
985 @@ -2147,7 +2767,7 @@ int nand_write_oob_syndrome(struct mtd_i
986 {
987 int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
988 int eccsize = chip->ecc.size, length = mtd->oobsize;
989 - int i, len, pos, status = 0, sndcmd = 0, steps = chip->ecc.steps;
990 + int ret, i, len, pos, sndcmd = 0, steps = chip->ecc.steps;
991 const uint8_t *bufpoi = chip->oob_poi;
992
993 /*
994 @@ -2161,7 +2781,10 @@ int nand_write_oob_syndrome(struct mtd_i
995 } else
996 pos = eccsize;
997
998 - chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page);
999 + ret = nand_prog_page_begin_op(chip, page, pos, NULL, 0);
1000 + if (ret)
1001 + return ret;
1002 +
1003 for (i = 0; i < steps; i++) {
1004 if (sndcmd) {
1005 if (mtd->writesize <= 512) {
1006 @@ -2170,28 +2793,40 @@ int nand_write_oob_syndrome(struct mtd_i
1007 len = eccsize;
1008 while (len > 0) {
1009 int num = min_t(int, len, 4);
1010 - chip->write_buf(mtd, (uint8_t *)&fill,
1011 - num);
1012 +
1013 + ret = nand_write_data_op(chip, &fill,
1014 + num, false);
1015 + if (ret)
1016 + return ret;
1017 +
1018 len -= num;
1019 }
1020 } else {
1021 pos = eccsize + i * (eccsize + chunk);
1022 - chip->cmdfunc(mtd, NAND_CMD_RNDIN, pos, -1);
1023 + ret = nand_change_write_column_op(chip, pos,
1024 + NULL, 0,
1025 + false);
1026 + if (ret)
1027 + return ret;
1028 }
1029 } else
1030 sndcmd = 1;
1031 len = min_t(int, length, chunk);
1032 - chip->write_buf(mtd, bufpoi, len);
1033 +
1034 + ret = nand_write_data_op(chip, bufpoi, len, false);
1035 + if (ret)
1036 + return ret;
1037 +
1038 bufpoi += len;
1039 length -= len;
1040 }
1041 - if (length > 0)
1042 - chip->write_buf(mtd, bufpoi, length);
1043 -
1044 - chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1045 - status = chip->waitfunc(mtd, chip);
1046 + if (length > 0) {
1047 + ret = nand_write_data_op(chip, bufpoi, length, false);
1048 + if (ret)
1049 + return ret;
1050 + }
1051
1052 - return status & NAND_STATUS_FAIL ? -EIO : 0;
1053 + return nand_prog_page_end_op(chip);
1054 }
1055 EXPORT_SYMBOL(nand_write_oob_syndrome);
1056
1057 @@ -2346,9 +2981,18 @@ static int nand_read_oob(struct mtd_info
1058 int nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
1059 const uint8_t *buf, int oob_required, int page)
1060 {
1061 - chip->write_buf(mtd, buf, mtd->writesize);
1062 - if (oob_required)
1063 - chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
1064 + int ret;
1065 +
1066 + ret = nand_write_data_op(chip, buf, mtd->writesize, false);
1067 + if (ret)
1068 + return ret;
1069 +
1070 + if (oob_required) {
1071 + ret = nand_write_data_op(chip, chip->oob_poi, mtd->oobsize,
1072 + false);
1073 + if (ret)
1074 + return ret;
1075 + }
1076
1077 return 0;
1078 }
1079 @@ -2372,29 +3016,46 @@ static int nand_write_page_raw_syndrome(
1080 int eccsize = chip->ecc.size;
1081 int eccbytes = chip->ecc.bytes;
1082 uint8_t *oob = chip->oob_poi;
1083 - int steps, size;
1084 + int steps, size, ret;
1085
1086 for (steps = chip->ecc.steps; steps > 0; steps--) {
1087 - chip->write_buf(mtd, buf, eccsize);
1088 + ret = nand_write_data_op(chip, buf, eccsize, false);
1089 + if (ret)
1090 + return ret;
1091 +
1092 buf += eccsize;
1093
1094 if (chip->ecc.prepad) {
1095 - chip->write_buf(mtd, oob, chip->ecc.prepad);
1096 + ret = nand_write_data_op(chip, oob, chip->ecc.prepad,
1097 + false);
1098 + if (ret)
1099 + return ret;
1100 +
1101 oob += chip->ecc.prepad;
1102 }
1103
1104 - chip->write_buf(mtd, oob, eccbytes);
1105 + ret = nand_write_data_op(chip, oob, eccbytes, false);
1106 + if (ret)
1107 + return ret;
1108 +
1109 oob += eccbytes;
1110
1111 if (chip->ecc.postpad) {
1112 - chip->write_buf(mtd, oob, chip->ecc.postpad);
1113 + ret = nand_write_data_op(chip, oob, chip->ecc.postpad,
1114 + false);
1115 + if (ret)
1116 + return ret;
1117 +
1118 oob += chip->ecc.postpad;
1119 }
1120 }
1121
1122 size = mtd->oobsize - (oob - chip->oob_poi);
1123 - if (size)
1124 - chip->write_buf(mtd, oob, size);
1125 + if (size) {
1126 + ret = nand_write_data_op(chip, oob, size, false);
1127 + if (ret)
1128 + return ret;
1129 + }
1130
1131 return 0;
1132 }
1133 @@ -2448,7 +3109,11 @@ static int nand_write_page_hwecc(struct
1134
1135 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
1136 chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
1137 - chip->write_buf(mtd, p, eccsize);
1138 +
1139 + ret = nand_write_data_op(chip, p, eccsize, false);
1140 + if (ret)
1141 + return ret;
1142 +
1143 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
1144 }
1145
1146 @@ -2457,7 +3122,9 @@ static int nand_write_page_hwecc(struct
1147 if (ret)
1148 return ret;
1149
1150 - chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
1151 + ret = nand_write_data_op(chip, chip->oob_poi, mtd->oobsize, false);
1152 + if (ret)
1153 + return ret;
1154
1155 return 0;
1156 }
1157 @@ -2493,7 +3160,9 @@ static int nand_write_subpage_hwecc(stru
1158 chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
1159
1160 /* write data (untouched subpages already masked by 0xFF) */
1161 - chip->write_buf(mtd, buf, ecc_size);
1162 + ret = nand_write_data_op(chip, buf, ecc_size, false);
1163 + if (ret)
1164 + return ret;
1165
1166 /* mask ECC of un-touched subpages by padding 0xFF */
1167 if ((step < start_step) || (step > end_step))
1168 @@ -2520,7 +3189,9 @@ static int nand_write_subpage_hwecc(stru
1169 return ret;
1170
1171 /* write OOB buffer to NAND device */
1172 - chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
1173 + ret = nand_write_data_op(chip, chip->oob_poi, mtd->oobsize, false);
1174 + if (ret)
1175 + return ret;
1176
1177 return 0;
1178 }
1179 @@ -2547,31 +3218,49 @@ static int nand_write_page_syndrome(stru
1180 int eccsteps = chip->ecc.steps;
1181 const uint8_t *p = buf;
1182 uint8_t *oob = chip->oob_poi;
1183 + int ret;
1184
1185 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
1186 -
1187 chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
1188 - chip->write_buf(mtd, p, eccsize);
1189 +
1190 + ret = nand_write_data_op(chip, p, eccsize, false);
1191 + if (ret)
1192 + return ret;
1193
1194 if (chip->ecc.prepad) {
1195 - chip->write_buf(mtd, oob, chip->ecc.prepad);
1196 + ret = nand_write_data_op(chip, oob, chip->ecc.prepad,
1197 + false);
1198 + if (ret)
1199 + return ret;
1200 +
1201 oob += chip->ecc.prepad;
1202 }
1203
1204 chip->ecc.calculate(mtd, p, oob);
1205 - chip->write_buf(mtd, oob, eccbytes);
1206 +
1207 + ret = nand_write_data_op(chip, oob, eccbytes, false);
1208 + if (ret)
1209 + return ret;
1210 +
1211 oob += eccbytes;
1212
1213 if (chip->ecc.postpad) {
1214 - chip->write_buf(mtd, oob, chip->ecc.postpad);
1215 + ret = nand_write_data_op(chip, oob, chip->ecc.postpad,
1216 + false);
1217 + if (ret)
1218 + return ret;
1219 +
1220 oob += chip->ecc.postpad;
1221 }
1222 }
1223
1224 /* Calculate remaining oob bytes */
1225 i = mtd->oobsize - (oob - chip->oob_poi);
1226 - if (i)
1227 - chip->write_buf(mtd, oob, i);
1228 + if (i) {
1229 + ret = nand_write_data_op(chip, oob, i, false);
1230 + if (ret)
1231 + return ret;
1232 + }
1233
1234 return 0;
1235 }
1236 @@ -2599,8 +3288,11 @@ static int nand_write_page(struct mtd_in
1237 else
1238 subpage = 0;
1239
1240 - if (nand_standard_page_accessors(&chip->ecc))
1241 - chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
1242 + if (nand_standard_page_accessors(&chip->ecc)) {
1243 + status = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
1244 + if (status)
1245 + return status;
1246 + }
1247
1248 if (unlikely(raw))
1249 status = chip->ecc.write_page_raw(mtd, chip, buf,
1250 @@ -2615,13 +3307,8 @@ static int nand_write_page(struct mtd_in
1251 if (status < 0)
1252 return status;
1253
1254 - if (nand_standard_page_accessors(&chip->ecc)) {
1255 - chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1256 -
1257 - status = chip->waitfunc(mtd, chip);
1258 - if (status & NAND_STATUS_FAIL)
1259 - return -EIO;
1260 - }
1261 + if (nand_standard_page_accessors(&chip->ecc))
1262 + return nand_prog_page_end_op(chip);
1263
1264 return 0;
1265 }
1266 @@ -2994,17 +3681,12 @@ out:
1267 static int single_erase(struct mtd_info *mtd, int page)
1268 {
1269 struct nand_chip *chip = mtd_to_nand(mtd);
1270 - int status;
1271 + unsigned int eraseblock;
1272
1273 /* Send commands to erase a block */
1274 - chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
1275 - chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
1276 -
1277 - status = chip->waitfunc(mtd, chip);
1278 - if (status < 0)
1279 - return status;
1280 + eraseblock = page >> (chip->phys_erase_shift - chip->page_shift);
1281
1282 - return status & NAND_STATUS_FAIL ? -EIO : 0;
1283 + return nand_erase_op(chip, eraseblock);
1284 }
1285
1286 /**
1287 @@ -3231,22 +3913,12 @@ static int nand_max_bad_blocks(struct mt
1288 static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip,
1289 int addr, uint8_t *subfeature_param)
1290 {
1291 - int status;
1292 - int i;
1293 -
1294 if (!chip->onfi_version ||
1295 !(le16_to_cpu(chip->onfi_params.opt_cmd)
1296 & ONFI_OPT_CMD_SET_GET_FEATURES))
1297 return -EINVAL;
1298
1299 - chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, addr, -1);
1300 - for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
1301 - chip->write_byte(mtd, subfeature_param[i]);
1302 -
1303 - status = chip->waitfunc(mtd, chip);
1304 - if (status & NAND_STATUS_FAIL)
1305 - return -EIO;
1306 - return 0;
1307 + return nand_set_features_op(chip, addr, subfeature_param);
1308 }
1309
1310 /**
1311 @@ -3259,17 +3931,12 @@ static int nand_onfi_set_features(struct
1312 static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,
1313 int addr, uint8_t *subfeature_param)
1314 {
1315 - int i;
1316 -
1317 if (!chip->onfi_version ||
1318 !(le16_to_cpu(chip->onfi_params.opt_cmd)
1319 & ONFI_OPT_CMD_SET_GET_FEATURES))
1320 return -EINVAL;
1321
1322 - chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, addr, -1);
1323 - for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
1324 - *subfeature_param++ = chip->read_byte(mtd);
1325 - return 0;
1326 + return nand_get_features_op(chip, addr, subfeature_param);
1327 }
1328
1329 /**
1330 @@ -3412,12 +4079,11 @@ static u16 onfi_crc16(u16 crc, u8 const
1331 static int nand_flash_detect_ext_param_page(struct nand_chip *chip,
1332 struct nand_onfi_params *p)
1333 {
1334 - struct mtd_info *mtd = nand_to_mtd(chip);
1335 struct onfi_ext_param_page *ep;
1336 struct onfi_ext_section *s;
1337 struct onfi_ext_ecc_info *ecc;
1338 uint8_t *cursor;
1339 - int ret = -EINVAL;
1340 + int ret;
1341 int len;
1342 int i;
1343
1344 @@ -3427,14 +4093,18 @@ static int nand_flash_detect_ext_param_p
1345 return -ENOMEM;
1346
1347 /* Send our own NAND_CMD_PARAM. */
1348 - chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
1349 + ret = nand_read_param_page_op(chip, 0, NULL, 0);
1350 + if (ret)
1351 + goto ext_out;
1352
1353 /* Use the Change Read Column command to skip the ONFI param pages. */
1354 - chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
1355 - sizeof(*p) * p->num_of_param_pages , -1);
1356 + ret = nand_change_read_column_op(chip,
1357 + sizeof(*p) * p->num_of_param_pages,
1358 + ep, len, true);
1359 + if (ret)
1360 + goto ext_out;
1361
1362 - /* Read out the Extended Parameter Page. */
1363 - chip->read_buf(mtd, (uint8_t *)ep, len);
1364 + ret = -EINVAL;
1365 if ((onfi_crc16(ONFI_CRC_BASE, ((uint8_t *)ep) + 2, len - 2)
1366 != le16_to_cpu(ep->crc))) {
1367 pr_debug("fail in the CRC.\n");
1368 @@ -3487,19 +4157,23 @@ static int nand_flash_detect_onfi(struct
1369 {
1370 struct mtd_info *mtd = nand_to_mtd(chip);
1371 struct nand_onfi_params *p = &chip->onfi_params;
1372 - int i, j;
1373 - int val;
1374 + char id[4];
1375 + int i, ret, val;
1376
1377 /* Try ONFI for unknown chip or LP */
1378 - chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
1379 - if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
1380 - chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I')
1381 + ret = nand_readid_op(chip, 0x20, id, sizeof(id));
1382 + if (ret || strncmp(id, "ONFI", 4))
1383 + return 0;
1384 +
1385 + ret = nand_read_param_page_op(chip, 0, NULL, 0);
1386 + if (ret)
1387 return 0;
1388
1389 - chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
1390 for (i = 0; i < 3; i++) {
1391 - for (j = 0; j < sizeof(*p); j++)
1392 - ((uint8_t *)p)[j] = chip->read_byte(mtd);
1393 + ret = nand_read_data_op(chip, p, sizeof(*p), true);
1394 + if (ret)
1395 + return 0;
1396 +
1397 if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
1398 le16_to_cpu(p->crc)) {
1399 break;
1400 @@ -3590,20 +4264,22 @@ static int nand_flash_detect_jedec(struc
1401 struct mtd_info *mtd = nand_to_mtd(chip);
1402 struct nand_jedec_params *p = &chip->jedec_params;
1403 struct jedec_ecc_info *ecc;
1404 - int val;
1405 - int i, j;
1406 + char id[5];
1407 + int i, val, ret;
1408
1409 /* Try JEDEC for unknown chip or LP */
1410 - chip->cmdfunc(mtd, NAND_CMD_READID, 0x40, -1);
1411 - if (chip->read_byte(mtd) != 'J' || chip->read_byte(mtd) != 'E' ||
1412 - chip->read_byte(mtd) != 'D' || chip->read_byte(mtd) != 'E' ||
1413 - chip->read_byte(mtd) != 'C')
1414 + ret = nand_readid_op(chip, 0x40, id, sizeof(id));
1415 + if (ret || strncmp(id, "JEDEC", sizeof(id)))
1416 + return 0;
1417 +
1418 + ret = nand_read_param_page_op(chip, 0x40, NULL, 0);
1419 + if (ret)
1420 return 0;
1421
1422 - chip->cmdfunc(mtd, NAND_CMD_PARAM, 0x40, -1);
1423 for (i = 0; i < 3; i++) {
1424 - for (j = 0; j < sizeof(*p); j++)
1425 - ((uint8_t *)p)[j] = chip->read_byte(mtd);
1426 + ret = nand_read_data_op(chip, p, sizeof(*p), true);
1427 + if (ret)
1428 + return 0;
1429
1430 if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 510) ==
1431 le16_to_cpu(p->crc))
1432 @@ -3882,8 +4558,7 @@ static int nand_detect(struct nand_chip
1433 {
1434 const struct nand_manufacturer *manufacturer;
1435 struct mtd_info *mtd = nand_to_mtd(chip);
1436 - int busw;
1437 - int i;
1438 + int busw, ret;
1439 u8 *id_data = chip->id.data;
1440 u8 maf_id, dev_id;
1441
1442 @@ -3891,17 +4566,21 @@ static int nand_detect(struct nand_chip
1443 * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)
1444 * after power-up.
1445 */
1446 - nand_reset(chip, 0);
1447 + ret = nand_reset(chip, 0);
1448 + if (ret)
1449 + return ret;
1450
1451 /* Select the device */
1452 chip->select_chip(mtd, 0);
1453
1454 /* Send the command for reading device ID */
1455 - chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
1456 + ret = nand_readid_op(chip, 0, id_data, 2);
1457 + if (ret)
1458 + return ret;
1459
1460 /* Read manufacturer and device IDs */
1461 - maf_id = chip->read_byte(mtd);
1462 - dev_id = chip->read_byte(mtd);
1463 + maf_id = id_data[0];
1464 + dev_id = id_data[1];
1465
1466 /*
1467 * Try again to make sure, as some systems the bus-hold or other
1468 @@ -3910,11 +4589,10 @@ static int nand_detect(struct nand_chip
1469 * not match, ignore the device completely.
1470 */
1471
1472 - chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
1473 -
1474 /* Read entire ID string */
1475 - for (i = 0; i < ARRAY_SIZE(chip->id.data); i++)
1476 - id_data[i] = chip->read_byte(mtd);
1477 + ret = nand_readid_op(chip, 0, id_data, sizeof(chip->id.data));
1478 + if (ret)
1479 + return ret;
1480
1481 if (id_data[0] != maf_id || id_data[1] != dev_id) {
1482 pr_info("second ID read did not match %02x,%02x against %02x,%02x\n",
1483 @@ -4238,15 +4916,16 @@ int nand_scan_ident(struct mtd_info *mtd
1484
1485 /* Check for a chip array */
1486 for (i = 1; i < maxchips; i++) {
1487 + u8 id[2];
1488 +
1489 /* See comment in nand_get_flash_type for reset */
1490 nand_reset(chip, i);
1491
1492 chip->select_chip(mtd, i);
1493 /* Send the command for reading device ID */
1494 - chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
1495 + nand_readid_op(chip, 0, id, sizeof(id));
1496 /* Read manufacturer and device IDs */
1497 - if (nand_maf_id != chip->read_byte(mtd) ||
1498 - nand_dev_id != chip->read_byte(mtd)) {
1499 + if (nand_maf_id != id[0] || nand_dev_id != id[1]) {
1500 chip->select_chip(mtd, -1);
1501 break;
1502 }
1503 --- a/drivers/mtd/nand/qcom_nandc.c
1504 +++ b/drivers/mtd/nand/qcom_nandc.c
1505 @@ -1990,7 +1990,7 @@ static int qcom_nandc_write_oob(struct m
1506 struct nand_ecc_ctrl *ecc = &chip->ecc;
1507 u8 *oob = chip->oob_poi;
1508 int data_size, oob_size;
1509 - int ret, status = 0;
1510 + int ret;
1511
1512 host->use_ecc = true;
1513
1514 @@ -2027,11 +2027,7 @@ static int qcom_nandc_write_oob(struct m
1515 return -EIO;
1516 }
1517
1518 - chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1519 -
1520 - status = chip->waitfunc(mtd, chip);
1521 -
1522 - return status & NAND_STATUS_FAIL ? -EIO : 0;
1523 + return nand_prog_page_end_op(chip);
1524 }
1525
1526 static int qcom_nandc_block_bad(struct mtd_info *mtd, loff_t ofs)
1527 @@ -2081,7 +2077,7 @@ static int qcom_nandc_block_markbad(stru
1528 struct qcom_nand_host *host = to_qcom_nand_host(chip);
1529 struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
1530 struct nand_ecc_ctrl *ecc = &chip->ecc;
1531 - int page, ret, status = 0;
1532 + int page, ret;
1533
1534 clear_read_regs(nandc);
1535 clear_bam_transaction(nandc);
1536 @@ -2114,11 +2110,7 @@ static int qcom_nandc_block_markbad(stru
1537 return -EIO;
1538 }
1539
1540 - chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1541 -
1542 - status = chip->waitfunc(mtd, chip);
1543 -
1544 - return status & NAND_STATUS_FAIL ? -EIO : 0;
1545 + return nand_prog_page_end_op(chip);
1546 }
1547
1548 /*
1549 --- a/include/linux/mtd/rawnand.h
1550 +++ b/include/linux/mtd/rawnand.h
1551 @@ -1313,6 +1313,35 @@ int nand_write_page_raw(struct mtd_info
1552 /* Reset and initialize a NAND device */
1553 int nand_reset(struct nand_chip *chip, int chipnr);
1554
1555 +/* NAND operation helpers */
1556 +int nand_reset_op(struct nand_chip *chip);
1557 +int nand_readid_op(struct nand_chip *chip, u8 addr, void *buf,
1558 + unsigned int len);
1559 +int nand_status_op(struct nand_chip *chip, u8 *status);
1560 +int nand_exit_status_op(struct nand_chip *chip);
1561 +int nand_erase_op(struct nand_chip *chip, unsigned int eraseblock);
1562 +int nand_read_page_op(struct nand_chip *chip, unsigned int page,
1563 + unsigned int offset_in_page, void *buf, unsigned int len);
1564 +int nand_change_read_column_op(struct nand_chip *chip,
1565 + unsigned int offset_in_page, void *buf,
1566 + unsigned int len, bool force_8bit);
1567 +int nand_read_oob_op(struct nand_chip *chip, unsigned int page,
1568 + unsigned int offset_in_page, void *buf, unsigned int len);
1569 +int nand_prog_page_begin_op(struct nand_chip *chip, unsigned int page,
1570 + unsigned int offset_in_page, const void *buf,
1571 + unsigned int len);
1572 +int nand_prog_page_end_op(struct nand_chip *chip);
1573 +int nand_prog_page_op(struct nand_chip *chip, unsigned int page,
1574 + unsigned int offset_in_page, const void *buf,
1575 + unsigned int len);
1576 +int nand_change_write_column_op(struct nand_chip *chip,
1577 + unsigned int offset_in_page, const void *buf,
1578 + unsigned int len, bool force_8bit);
1579 +int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len,
1580 + bool force_8bit);
1581 +int nand_write_data_op(struct nand_chip *chip, const void *buf,
1582 + unsigned int len, bool force_8bit);
1583 +
1584 /* Free resources held by the NAND device */
1585 void nand_cleanup(struct nand_chip *chip);
1586