aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/onenand
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-06-20 20:46:21 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-06-20 20:46:21 -0400
commit70ac4385a13f78bc478f26d317511893741b05bd (patch)
treedafc7f3018295fc4ee00339889e4f35d5b9d7743 /drivers/mtd/onenand
parentd59bf96cdde5b874a57bfd1425faa45da915d0b7 (diff)
parent077e98945db7e54a9865b5f29a1f02f531eca414 (diff)
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
Conflicts: include/linux/nfs_fs.h Fixed up conflict with kernel header updates.
Diffstat (limited to 'drivers/mtd/onenand')
-rw-r--r--drivers/mtd/onenand/Kconfig14
-rw-r--r--drivers/mtd/onenand/onenand_base.c718
-rw-r--r--drivers/mtd/onenand/onenand_bbt.c9
3 files changed, 499 insertions, 242 deletions
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
index 126ff6bf63d5..5930a03736d7 100644
--- a/drivers/mtd/onenand/Kconfig
+++ b/drivers/mtd/onenand/Kconfig
@@ -29,6 +29,20 @@ config MTD_ONENAND_GENERIC
29 help 29 help
30 Support for OneNAND flash via platform device driver. 30 Support for OneNAND flash via platform device driver.
31 31
32config MTD_ONENAND_OTP
33 bool "OneNAND OTP Support"
34 depends on MTD_ONENAND
35 help
36 One Block of the NAND Flash Array memory is reserved as
37 a One-Time Programmable Block memory area.
38 Also, 1st Block of NAND Flash Array can be used as OTP.
39
40 The OTP block can be read, programmed and locked using the same
41 operations as any other NAND Flash Array memory block.
42 OTP block cannot be erased.
43
44 OTP block is fully-guaranteed to be a valid block.
45
32config MTD_ONENAND_SYNC_READ 46config MTD_ONENAND_SYNC_READ
33 bool "OneNAND Sync. Burst Read Support" 47 bool "OneNAND Sync. Burst Read Support"
34 depends on ARCH_OMAP 48 depends on ARCH_OMAP
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index a53a73fc2a5a..84ec40d25438 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -23,8 +23,7 @@
23/** 23/**
24 * onenand_oob_64 - oob info for large (2KB) page 24 * onenand_oob_64 - oob info for large (2KB) page
25 */ 25 */
26static struct nand_oobinfo onenand_oob_64 = { 26static struct nand_ecclayout onenand_oob_64 = {
27 .useecc = MTD_NANDECC_AUTOPLACE,
28 .eccbytes = 20, 27 .eccbytes = 20,
29 .eccpos = { 28 .eccpos = {
30 8, 9, 10, 11, 12, 29 8, 9, 10, 11, 12,
@@ -34,14 +33,14 @@ static struct nand_oobinfo onenand_oob_64 = {
34 }, 33 },
35 .oobfree = { 34 .oobfree = {
36 {2, 3}, {14, 2}, {18, 3}, {30, 2}, 35 {2, 3}, {14, 2}, {18, 3}, {30, 2},
37 {24, 3}, {46, 2}, {40, 3}, {62, 2} } 36 {34, 3}, {46, 2}, {50, 3}, {62, 2}
37 }
38}; 38};
39 39
40/** 40/**
41 * onenand_oob_32 - oob info for middle (1KB) page 41 * onenand_oob_32 - oob info for middle (1KB) page
42 */ 42 */
43static struct nand_oobinfo onenand_oob_32 = { 43static struct nand_ecclayout onenand_oob_32 = {
44 .useecc = MTD_NANDECC_AUTOPLACE,
45 .eccbytes = 10, 44 .eccbytes = 10,
46 .eccpos = { 45 .eccpos = {
47 8, 9, 10, 11, 12, 46 8, 9, 10, 11, 12,
@@ -190,7 +189,7 @@ static int onenand_buffer_address(int dataram1, int sectors, int count)
190static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t len) 189static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t len)
191{ 190{
192 struct onenand_chip *this = mtd->priv; 191 struct onenand_chip *this = mtd->priv;
193 int value, readcmd = 0; 192 int value, readcmd = 0, block_cmd = 0;
194 int block, page; 193 int block, page;
195 /* Now we use page size operation */ 194 /* Now we use page size operation */
196 int sectors = 4, count = 4; 195 int sectors = 4, count = 4;
@@ -206,6 +205,8 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
206 205
207 case ONENAND_CMD_ERASE: 206 case ONENAND_CMD_ERASE:
208 case ONENAND_CMD_BUFFERRAM: 207 case ONENAND_CMD_BUFFERRAM:
208 case ONENAND_CMD_OTP_ACCESS:
209 block_cmd = 1;
209 block = (int) (addr >> this->erase_shift); 210 block = (int) (addr >> this->erase_shift);
210 page = -1; 211 page = -1;
211 break; 212 break;
@@ -233,6 +234,12 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
233 /* Write 'DFS, FBA' of Flash */ 234 /* Write 'DFS, FBA' of Flash */
234 value = onenand_block_address(this, block); 235 value = onenand_block_address(this, block);
235 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); 236 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
237
238 if (block_cmd) {
239 /* Select DataRAM for DDP */
240 value = onenand_bufferram_address(this, block);
241 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
242 }
236 } 243 }
237 244
238 if (page != -1) { 245 if (page != -1) {
@@ -301,6 +308,7 @@ static int onenand_wait(struct mtd_info *mtd, int state)
301 308
302 if (state != FL_READING) 309 if (state != FL_READING)
303 cond_resched(); 310 cond_resched();
311 touch_softlockup_watchdog();
304 } 312 }
305 /* To get correct interrupt status in timeout case */ 313 /* To get correct interrupt status in timeout case */
306 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); 314 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
@@ -344,7 +352,7 @@ static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
344 352
345 if (ONENAND_CURRENT_BUFFERRAM(this)) { 353 if (ONENAND_CURRENT_BUFFERRAM(this)) {
346 if (area == ONENAND_DATARAM) 354 if (area == ONENAND_DATARAM)
347 return mtd->oobblock; 355 return mtd->writesize;
348 if (area == ONENAND_SPARERAM) 356 if (area == ONENAND_SPARERAM)
349 return mtd->oobsize; 357 return mtd->oobsize;
350 } 358 }
@@ -372,6 +380,17 @@ static int onenand_read_bufferram(struct mtd_info *mtd, int area,
372 380
373 bufferram += onenand_bufferram_offset(mtd, area); 381 bufferram += onenand_bufferram_offset(mtd, area);
374 382
383 if (ONENAND_CHECK_BYTE_ACCESS(count)) {
384 unsigned short word;
385
386 /* Align with word(16-bit) size */
387 count--;
388
389 /* Read word and save byte */
390 word = this->read_word(bufferram + offset + count);
391 buffer[count] = (word & 0xff);
392 }
393
375 memcpy(buffer, bufferram + offset, count); 394 memcpy(buffer, bufferram + offset, count);
376 395
377 return 0; 396 return 0;
@@ -399,6 +418,17 @@ static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
399 418
400 this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ); 419 this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
401 420
421 if (ONENAND_CHECK_BYTE_ACCESS(count)) {
422 unsigned short word;
423
424 /* Align with word(16-bit) size */
425 count--;
426
427 /* Read word and save byte */
428 word = this->read_word(bufferram + offset + count);
429 buffer[count] = (word & 0xff);
430 }
431
402 memcpy(buffer, bufferram + offset, count); 432 memcpy(buffer, bufferram + offset, count);
403 433
404 this->mmcontrol(mtd, 0); 434 this->mmcontrol(mtd, 0);
@@ -426,6 +456,22 @@ static int onenand_write_bufferram(struct mtd_info *mtd, int area,
426 456
427 bufferram += onenand_bufferram_offset(mtd, area); 457 bufferram += onenand_bufferram_offset(mtd, area);
428 458
459 if (ONENAND_CHECK_BYTE_ACCESS(count)) {
460 unsigned short word;
461 int byte_offset;
462
463 /* Align with word(16-bit) size */
464 count--;
465
466 /* Calculate byte access offset */
467 byte_offset = offset + count;
468
469 /* Read word and save byte */
470 word = this->read_word(bufferram + byte_offset);
471 word = (word & ~0xff) | buffer[count];
472 this->write_word(word, bufferram + byte_offset);
473 }
474
429 memcpy(bufferram + offset, buffer, count); 475 memcpy(bufferram + offset, buffer, count);
430 476
431 return 0; 477 return 0;
@@ -549,31 +595,28 @@ static void onenand_release_device(struct mtd_info *mtd)
549} 595}
550 596
551/** 597/**
552 * onenand_read_ecc - [MTD Interface] Read data with ECC 598 * onenand_read - [MTD Interface] Read data from flash
553 * @param mtd MTD device structure 599 * @param mtd MTD device structure
554 * @param from offset to read from 600 * @param from offset to read from
555 * @param len number of bytes to read 601 * @param len number of bytes to read
556 * @param retlen pointer to variable to store the number of read bytes 602 * @param retlen pointer to variable to store the number of read bytes
557 * @param buf the databuffer to put data 603 * @param buf the databuffer to put data
558 * @param oob_buf filesystem supplied oob data buffer
559 * @param oobsel oob selection structure
560 * 604 *
561 * OneNAND read with ECC 605 * Read with ecc
562 */ 606*/
563static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, 607static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
564 size_t *retlen, u_char *buf, 608 size_t *retlen, u_char *buf)
565 u_char *oob_buf, struct nand_oobinfo *oobsel)
566{ 609{
567 struct onenand_chip *this = mtd->priv; 610 struct onenand_chip *this = mtd->priv;
568 int read = 0, column; 611 int read = 0, column;
569 int thislen; 612 int thislen;
570 int ret = 0; 613 int ret = 0;
571 614
572 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); 615 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
573 616
574 /* Do not allow reads past end of device */ 617 /* Do not allow reads past end of device */
575 if ((from + len) > mtd->size) { 618 if ((from + len) > mtd->size) {
576 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: Attempt read beyond end of device\n"); 619 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: Attempt read beyond end of device\n");
577 *retlen = 0; 620 *retlen = 0;
578 return -EINVAL; 621 return -EINVAL;
579 } 622 }
@@ -584,14 +627,14 @@ static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
584 /* TODO handling oob */ 627 /* TODO handling oob */
585 628
586 while (read < len) { 629 while (read < len) {
587 thislen = min_t(int, mtd->oobblock, len - read); 630 thislen = min_t(int, mtd->writesize, len - read);
588 631
589 column = from & (mtd->oobblock - 1); 632 column = from & (mtd->writesize - 1);
590 if (column + thislen > mtd->oobblock) 633 if (column + thislen > mtd->writesize)
591 thislen = mtd->oobblock - column; 634 thislen = mtd->writesize - column;
592 635
593 if (!onenand_check_bufferram(mtd, from)) { 636 if (!onenand_check_bufferram(mtd, from)) {
594 this->command(mtd, ONENAND_CMD_READ, from, mtd->oobblock); 637 this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);
595 638
596 ret = this->wait(mtd, FL_READING); 639 ret = this->wait(mtd, FL_READING);
597 /* First copy data and check return value for ECC handling */ 640 /* First copy data and check return value for ECC handling */
@@ -606,7 +649,7 @@ static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
606 break; 649 break;
607 650
608 if (ret) { 651 if (ret) {
609 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: read failed = %d\n", ret); 652 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: read failed = %d\n", ret);
610 goto out; 653 goto out;
611 } 654 }
612 655
@@ -628,23 +671,7 @@ out:
628} 671}
629 672
630/** 673/**
631 * onenand_read - [MTD Interface] MTD compability function for onenand_read_ecc 674 * onenand_do_read_oob - [MTD Interface] OneNAND read out-of-band
632 * @param mtd MTD device structure
633 * @param from offset to read from
634 * @param len number of bytes to read
635 * @param retlen pointer to variable to store the number of read bytes
636 * @param buf the databuffer to put data
637 *
638 * This function simply calls onenand_read_ecc with oob buffer and oobsel = NULL
639*/
640static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
641 size_t *retlen, u_char *buf)
642{
643 return onenand_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
644}
645
646/**
647 * onenand_read_oob - [MTD Interface] OneNAND read out-of-band
648 * @param mtd MTD device structure 675 * @param mtd MTD device structure
649 * @param from offset to read from 676 * @param from offset to read from
650 * @param len number of bytes to read 677 * @param len number of bytes to read
@@ -653,8 +680,8 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
653 * 680 *
654 * OneNAND read out-of-band data from the spare area 681 * OneNAND read out-of-band data from the spare area
655 */ 682 */
656static int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len, 683int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
657 size_t *retlen, u_char *buf) 684 size_t *retlen, u_char *buf)
658{ 685{
659 struct onenand_chip *this = mtd->priv; 686 struct onenand_chip *this = mtd->priv;
660 int read = 0, thislen, column; 687 int read = 0, thislen, column;
@@ -704,7 +731,7 @@ static int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
704 /* Read more? */ 731 /* Read more? */
705 if (read < len) { 732 if (read < len) {
706 /* Page size */ 733 /* Page size */
707 from += mtd->oobblock; 734 from += mtd->writesize;
708 column = 0; 735 column = 0;
709 } 736 }
710 } 737 }
@@ -717,8 +744,53 @@ out:
717 return ret; 744 return ret;
718} 745}
719 746
747/**
748 * onenand_read_oob - [MTD Interface] NAND write data and/or out-of-band
749 * @mtd: MTD device structure
750 * @from: offset to read from
751 * @ops: oob operation description structure
752 */
753static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
754 struct mtd_oob_ops *ops)
755{
756 BUG_ON(ops->mode != MTD_OOB_PLACE);
757
758 return onenand_do_read_oob(mtd, from + ops->ooboffs, ops->len,
759 &ops->retlen, ops->oobbuf);
760}
761
720#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE 762#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
721/** 763/**
764 * onenand_verify_oob - [GENERIC] verify the oob contents after a write
765 * @param mtd MTD device structure
766 * @param buf the databuffer to verify
767 * @param to offset to read from
768 * @param len number of bytes to read and compare
769 *
770 */
771static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to, int len)
772{
773 struct onenand_chip *this = mtd->priv;
774 char *readp = this->page_buf;
775 int column = to & (mtd->oobsize - 1);
776 int status, i;
777
778 this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize);
779 onenand_update_bufferram(mtd, to, 0);
780 status = this->wait(mtd, FL_READING);
781 if (status)
782 return status;
783
784 this->read_bufferram(mtd, ONENAND_SPARERAM, readp, column, len);
785
786 for(i = 0; i < len; i++)
787 if (buf[i] != 0xFF && buf[i] != readp[i])
788 return -EBADMSG;
789
790 return 0;
791}
792
793/**
722 * onenand_verify_page - [GENERIC] verify the chip contents after a write 794 * onenand_verify_page - [GENERIC] verify the chip contents after a write
723 * @param mtd MTD device structure 795 * @param mtd MTD device structure
724 * @param buf the databuffer to verify 796 * @param buf the databuffer to verify
@@ -731,7 +803,7 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr)
731 void __iomem *dataram0, *dataram1; 803 void __iomem *dataram0, *dataram1;
732 int ret = 0; 804 int ret = 0;
733 805
734 this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock); 806 this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);
735 807
736 ret = this->wait(mtd, FL_READING); 808 ret = this->wait(mtd, FL_READING);
737 if (ret) 809 if (ret)
@@ -741,53 +813,51 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr)
741 813
742 /* Check, if the two dataram areas are same */ 814 /* Check, if the two dataram areas are same */
743 dataram0 = this->base + ONENAND_DATARAM; 815 dataram0 = this->base + ONENAND_DATARAM;
744 dataram1 = dataram0 + mtd->oobblock; 816 dataram1 = dataram0 + mtd->writesize;
745 817
746 if (memcmp(dataram0, dataram1, mtd->oobblock)) 818 if (memcmp(dataram0, dataram1, mtd->writesize))
747 return -EBADMSG; 819 return -EBADMSG;
748 820
749 return 0; 821 return 0;
750} 822}
751#else 823#else
752#define onenand_verify_page(...) (0) 824#define onenand_verify_page(...) (0)
825#define onenand_verify_oob(...) (0)
753#endif 826#endif
754 827
755#define NOTALIGNED(x) ((x & (mtd->oobblock - 1)) != 0) 828#define NOTALIGNED(x) ((x & (mtd->writesize - 1)) != 0)
756 829
757/** 830/**
758 * onenand_write_ecc - [MTD Interface] OneNAND write with ECC 831 * onenand_write - [MTD Interface] write buffer to FLASH
759 * @param mtd MTD device structure 832 * @param mtd MTD device structure
760 * @param to offset to write to 833 * @param to offset to write to
761 * @param len number of bytes to write 834 * @param len number of bytes to write
762 * @param retlen pointer to variable to store the number of written bytes 835 * @param retlen pointer to variable to store the number of written bytes
763 * @param buf the data to write 836 * @param buf the data to write
764 * @param eccbuf filesystem supplied oob data buffer
765 * @param oobsel oob selection structure
766 * 837 *
767 * OneNAND write with ECC 838 * Write with ECC
768 */ 839 */
769static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, 840static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
770 size_t *retlen, const u_char *buf, 841 size_t *retlen, const u_char *buf)
771 u_char *eccbuf, struct nand_oobinfo *oobsel)
772{ 842{
773 struct onenand_chip *this = mtd->priv; 843 struct onenand_chip *this = mtd->priv;
774 int written = 0; 844 int written = 0;
775 int ret = 0; 845 int ret = 0;
776 846
777 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); 847 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
778 848
779 /* Initialize retlen, in case of early exit */ 849 /* Initialize retlen, in case of early exit */
780 *retlen = 0; 850 *retlen = 0;
781 851
782 /* Do not allow writes past end of device */ 852 /* Do not allow writes past end of device */
783 if (unlikely((to + len) > mtd->size)) { 853 if (unlikely((to + len) > mtd->size)) {
784 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt write to past end of device\n"); 854 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: Attempt write to past end of device\n");
785 return -EINVAL; 855 return -EINVAL;
786 } 856 }
787 857
788 /* Reject writes, which are not page aligned */ 858 /* Reject writes, which are not page aligned */
789 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) { 859 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
790 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt to write not page aligned data\n"); 860 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: Attempt to write not page aligned data\n");
791 return -EINVAL; 861 return -EINVAL;
792 } 862 }
793 863
@@ -796,20 +866,20 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
796 866
797 /* Loop until all data write */ 867 /* Loop until all data write */
798 while (written < len) { 868 while (written < len) {
799 int thislen = min_t(int, mtd->oobblock, len - written); 869 int thislen = min_t(int, mtd->writesize, len - written);
800 870
801 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock); 871 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->writesize);
802 872
803 this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen); 873 this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);
804 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize); 874 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
805 875
806 this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock); 876 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
807 877
808 onenand_update_bufferram(mtd, to, 1); 878 onenand_update_bufferram(mtd, to, 1);
809 879
810 ret = this->wait(mtd, FL_WRITING); 880 ret = this->wait(mtd, FL_WRITING);
811 if (ret) { 881 if (ret) {
812 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: write filaed %d\n", ret); 882 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret);
813 goto out; 883 goto out;
814 } 884 }
815 885
@@ -818,7 +888,7 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
818 /* Only check verify write turn on */ 888 /* Only check verify write turn on */
819 ret = onenand_verify_page(mtd, (u_char *) buf, to); 889 ret = onenand_verify_page(mtd, (u_char *) buf, to);
820 if (ret) { 890 if (ret) {
821 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: verify failed %d\n", ret); 891 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret);
822 goto out; 892 goto out;
823 } 893 }
824 894
@@ -839,24 +909,7 @@ out:
839} 909}
840 910
841/** 911/**
842 * onenand_write - [MTD Interface] compability function for onenand_write_ecc 912 * onenand_do_write_oob - [Internal] OneNAND write out-of-band
843 * @param mtd MTD device structure
844 * @param to offset to write to
845 * @param len number of bytes to write
846 * @param retlen pointer to variable to store the number of written bytes
847 * @param buf the data to write
848 *
849 * This function simply calls onenand_write_ecc
850 * with oob buffer and oobsel = NULL
851 */
852static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
853 size_t *retlen, const u_char *buf)
854{
855 return onenand_write_ecc(mtd, to, len, retlen, buf, NULL, NULL);
856}
857
858/**
859 * onenand_write_oob - [MTD Interface] OneNAND write out-of-band
860 * @param mtd MTD device structure 913 * @param mtd MTD device structure
861 * @param to offset to write to 914 * @param to offset to write to
862 * @param len number of bytes to write 915 * @param len number of bytes to write
@@ -865,11 +918,11 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
865 * 918 *
866 * OneNAND write out-of-band 919 * OneNAND write out-of-band
867 */ 920 */
868static int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, 921static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
869 size_t *retlen, const u_char *buf) 922 size_t *retlen, const u_char *buf)
870{ 923{
871 struct onenand_chip *this = mtd->priv; 924 struct onenand_chip *this = mtd->priv;
872 int column, status; 925 int column, ret = 0;
873 int written = 0; 926 int written = 0;
874 927
875 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); 928 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
@@ -894,16 +947,27 @@ static int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
894 947
895 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize); 948 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
896 949
897 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize); 950 /* We send data to spare ram with oobsize
898 this->write_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen); 951 * to prevent byte access */
952 memset(this->page_buf, 0xff, mtd->oobsize);
953 memcpy(this->page_buf + column, buf, thislen);
954 this->write_bufferram(mtd, ONENAND_SPARERAM, this->page_buf, 0, mtd->oobsize);
899 955
900 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize); 956 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
901 957
902 onenand_update_bufferram(mtd, to, 0); 958 onenand_update_bufferram(mtd, to, 0);
903 959
904 status = this->wait(mtd, FL_WRITING); 960 ret = this->wait(mtd, FL_WRITING);
905 if (status) 961 if (ret) {
962 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: write filaed %d\n", ret);
963 goto out;
964 }
965
966 ret = onenand_verify_oob(mtd, buf, to, thislen);
967 if (ret) {
968 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: verify failed %d\n", ret);
906 goto out; 969 goto out;
970 }
907 971
908 written += thislen; 972 written += thislen;
909 973
@@ -920,145 +984,22 @@ out:
920 984
921 *retlen = written; 985 *retlen = written;
922 986
923 return 0; 987 return ret;
924} 988}
925 989
926/** 990/**
927 * onenand_writev_ecc - [MTD Interface] write with iovec with ecc 991 * onenand_write_oob - [MTD Interface] NAND write data and/or out-of-band
928 * @param mtd MTD device structure 992 * @mtd: MTD device structure
929 * @param vecs the iovectors to write 993 * @from: offset to read from
930 * @param count number of vectors 994 * @ops: oob operation description structure
931 * @param to offset to write to
932 * @param retlen pointer to variable to store the number of written bytes
933 * @param eccbuf filesystem supplied oob data buffer
934 * @param oobsel oob selection structure
935 *
936 * OneNAND write with iovec with ecc
937 */ 995 */
938static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, 996static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
939 unsigned long count, loff_t to, size_t *retlen, 997 struct mtd_oob_ops *ops)
940 u_char *eccbuf, struct nand_oobinfo *oobsel)
941{ 998{
942 struct onenand_chip *this = mtd->priv; 999 BUG_ON(ops->mode != MTD_OOB_PLACE);
943 unsigned char *pbuf;
944 size_t total_len, len;
945 int i, written = 0;
946 int ret = 0;
947
948 /* Preset written len for early exit */
949 *retlen = 0;
950
951 /* Calculate total length of data */
952 total_len = 0;
953 for (i = 0; i < count; i++)
954 total_len += vecs[i].iov_len;
955
956 DEBUG(MTD_DEBUG_LEVEL3, "onenand_writev_ecc: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
957
958 /* Do not allow write past end of the device */
959 if (unlikely((to + total_len) > mtd->size)) {
960 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempted write past end of device\n");
961 return -EINVAL;
962 }
963
964 /* Reject writes, which are not page aligned */
965 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(total_len))) {
966 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempt to write not page aligned data\n");
967 return -EINVAL;
968 }
969
970 /* Grab the lock and see if the device is available */
971 onenand_get_device(mtd, FL_WRITING);
972
973 /* TODO handling oob */
974
975 /* Loop until all keve's data has been written */
976 len = 0;
977 while (count) {
978 pbuf = this->page_buf;
979 /*
980 * If the given tuple is >= pagesize then
981 * write it out from the iov
982 */
983 if ((vecs->iov_len - len) >= mtd->oobblock) {
984 pbuf = vecs->iov_base + len;
985
986 len += mtd->oobblock;
987
988 /* Check, if we have to switch to the next tuple */
989 if (len >= (int) vecs->iov_len) {
990 vecs++;
991 len = 0;
992 count--;
993 }
994 } else {
995 int cnt = 0, thislen;
996 while (cnt < mtd->oobblock) {
997 thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len);
998 memcpy(this->page_buf + cnt, vecs->iov_base + len, thislen);
999 cnt += thislen;
1000 len += thislen;
1001
1002 /* Check, if we have to switch to the next tuple */
1003 if (len >= (int) vecs->iov_len) {
1004 vecs++;
1005 len = 0;
1006 count--;
1007 }
1008 }
1009 }
1010
1011 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
1012 1000
1013 this->write_bufferram(mtd, ONENAND_DATARAM, pbuf, 0, mtd->oobblock); 1001 return onenand_do_write_oob(mtd, to + ops->ooboffs, ops->len,
1014 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize); 1002 &ops->retlen, ops->oobbuf);
1015
1016 this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
1017
1018 onenand_update_bufferram(mtd, to, 1);
1019
1020 ret = this->wait(mtd, FL_WRITING);
1021 if (ret) {
1022 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: write failed %d\n", ret);
1023 goto out;
1024 }
1025
1026
1027 /* Only check verify write turn on */
1028 ret = onenand_verify_page(mtd, (u_char *) pbuf, to);
1029 if (ret) {
1030 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: verify failed %d\n", ret);
1031 goto out;
1032 }
1033
1034 written += mtd->oobblock;
1035
1036 to += mtd->oobblock;
1037 }
1038
1039out:
1040 /* Deselect and wakt up anyone waiting on the device */
1041 onenand_release_device(mtd);
1042
1043 *retlen = written;
1044
1045 return 0;
1046}
1047
1048/**
1049 * onenand_writev - [MTD Interface] compabilty function for onenand_writev_ecc
1050 * @param mtd MTD device structure
1051 * @param vecs the iovectors to write
1052 * @param count number of vectors
1053 * @param to offset to write to
1054 * @param retlen pointer to variable to store the number of written bytes
1055 *
1056 * OneNAND write with kvec. This just calls the ecc function
1057 */
1058static int onenand_writev(struct mtd_info *mtd, const struct kvec *vecs,
1059 unsigned long count, loff_t to, size_t *retlen)
1060{
1061 return onenand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL);
1062} 1003}
1063 1004
1064/** 1005/**
@@ -1227,7 +1168,7 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
1227 1168
1228 /* We write two bytes, so we dont have to mess with 16 bit access */ 1169 /* We write two bytes, so we dont have to mess with 16 bit access */
1229 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01); 1170 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
1230 return mtd->write_oob(mtd, ofs , 2, &retlen, buf); 1171 return onenand_do_write_oob(mtd, ofs , 2, &retlen, buf);
1231} 1172}
1232 1173
1233/** 1174/**
@@ -1324,6 +1265,304 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1324 return 0; 1265 return 0;
1325} 1266}
1326 1267
1268#ifdef CONFIG_MTD_ONENAND_OTP
1269
1270/* Interal OTP operation */
1271typedef int (*otp_op_t)(struct mtd_info *mtd, loff_t form, size_t len,
1272 size_t *retlen, u_char *buf);
1273
1274/**
1275 * do_otp_read - [DEFAULT] Read OTP block area
1276 * @param mtd MTD device structure
1277 * @param from The offset to read
1278 * @param len number of bytes to read
1279 * @param retlen pointer to variable to store the number of readbytes
1280 * @param buf the databuffer to put/get data
1281 *
1282 * Read OTP block area.
1283 */
1284static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len,
1285 size_t *retlen, u_char *buf)
1286{
1287 struct onenand_chip *this = mtd->priv;
1288 int ret;
1289
1290 /* Enter OTP access mode */
1291 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
1292 this->wait(mtd, FL_OTPING);
1293
1294 ret = mtd->read(mtd, from, len, retlen, buf);
1295
1296 /* Exit OTP access mode */
1297 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
1298 this->wait(mtd, FL_RESETING);
1299
1300 return ret;
1301}
1302
1303/**
1304 * do_otp_write - [DEFAULT] Write OTP block area
1305 * @param mtd MTD device structure
1306 * @param from The offset to write
1307 * @param len number of bytes to write
1308 * @param retlen pointer to variable to store the number of write bytes
1309 * @param buf the databuffer to put/get data
1310 *
1311 * Write OTP block area.
1312 */
1313static int do_otp_write(struct mtd_info *mtd, loff_t from, size_t len,
1314 size_t *retlen, u_char *buf)
1315{
1316 struct onenand_chip *this = mtd->priv;
1317 unsigned char *pbuf = buf;
1318 int ret;
1319
1320 /* Force buffer page aligned */
1321 if (len < mtd->writesize) {
1322 memcpy(this->page_buf, buf, len);
1323 memset(this->page_buf + len, 0xff, mtd->writesize - len);
1324 pbuf = this->page_buf;
1325 len = mtd->writesize;
1326 }
1327
1328 /* Enter OTP access mode */
1329 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
1330 this->wait(mtd, FL_OTPING);
1331
1332 ret = mtd->write(mtd, from, len, retlen, pbuf);
1333
1334 /* Exit OTP access mode */
1335 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
1336 this->wait(mtd, FL_RESETING);
1337
1338 return ret;
1339}
1340
1341/**
1342 * do_otp_lock - [DEFAULT] Lock OTP block area
1343 * @param mtd MTD device structure
1344 * @param from The offset to lock
1345 * @param len number of bytes to lock
1346 * @param retlen pointer to variable to store the number of lock bytes
1347 * @param buf the databuffer to put/get data
1348 *
1349 * Lock OTP block area.
1350 */
1351static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len,
1352 size_t *retlen, u_char *buf)
1353{
1354 struct onenand_chip *this = mtd->priv;
1355 int ret;
1356
1357 /* Enter OTP access mode */
1358 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
1359 this->wait(mtd, FL_OTPING);
1360
1361 ret = onenand_do_write_oob(mtd, from, len, retlen, buf);
1362
1363 /* Exit OTP access mode */
1364 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
1365 this->wait(mtd, FL_RESETING);
1366
1367 return ret;
1368}
1369
1370/**
1371 * onenand_otp_walk - [DEFAULT] Handle OTP operation
1372 * @param mtd MTD device structure
1373 * @param from The offset to read/write
1374 * @param len number of bytes to read/write
1375 * @param retlen pointer to variable to store the number of read bytes
1376 * @param buf the databuffer to put/get data
1377 * @param action do given action
1378 * @param mode specify user and factory
1379 *
1380 * Handle OTP operation.
1381 */
1382static int onenand_otp_walk(struct mtd_info *mtd, loff_t from, size_t len,
1383 size_t *retlen, u_char *buf,
1384 otp_op_t action, int mode)
1385{
1386 struct onenand_chip *this = mtd->priv;
1387 int otp_pages;
1388 int density;
1389 int ret = 0;
1390
1391 *retlen = 0;
1392
1393 density = this->device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
1394 if (density < ONENAND_DEVICE_DENSITY_512Mb)
1395 otp_pages = 20;
1396 else
1397 otp_pages = 10;
1398
1399 if (mode == MTD_OTP_FACTORY) {
1400 from += mtd->writesize * otp_pages;
1401 otp_pages = 64 - otp_pages;
1402 }
1403
1404 /* Check User/Factory boundary */
1405 if (((mtd->writesize * otp_pages) - (from + len)) < 0)
1406 return 0;
1407
1408 while (len > 0 && otp_pages > 0) {
1409 if (!action) { /* OTP Info functions */
1410 struct otp_info *otpinfo;
1411
1412 len -= sizeof(struct otp_info);
1413 if (len <= 0)
1414 return -ENOSPC;
1415
1416 otpinfo = (struct otp_info *) buf;
1417 otpinfo->start = from;
1418 otpinfo->length = mtd->writesize;
1419 otpinfo->locked = 0;
1420
1421 from += mtd->writesize;
1422 buf += sizeof(struct otp_info);
1423 *retlen += sizeof(struct otp_info);
1424 } else {
1425 size_t tmp_retlen;
1426 int size = len;
1427
1428 ret = action(mtd, from, len, &tmp_retlen, buf);
1429
1430 buf += size;
1431 len -= size;
1432 *retlen += size;
1433
1434 if (ret < 0)
1435 return ret;
1436 }
1437 otp_pages--;
1438 }
1439
1440 return 0;
1441}
1442
1443/**
1444 * onenand_get_fact_prot_info - [MTD Interface] Read factory OTP info
1445 * @param mtd MTD device structure
1446 * @param buf the databuffer to put/get data
1447 * @param len number of bytes to read
1448 *
1449 * Read factory OTP info.
1450 */
1451static int onenand_get_fact_prot_info(struct mtd_info *mtd,
1452 struct otp_info *buf, size_t len)
1453{
1454 size_t retlen;
1455 int ret;
1456
1457 ret = onenand_otp_walk(mtd, 0, len, &retlen, (u_char *) buf, NULL, MTD_OTP_FACTORY);
1458
1459 return ret ? : retlen;
1460}
1461
1462/**
1463 * onenand_read_fact_prot_reg - [MTD Interface] Read factory OTP area
1464 * @param mtd MTD device structure
1465 * @param from The offset to read
1466 * @param len number of bytes to read
1467 * @param retlen pointer to variable to store the number of read bytes
1468 * @param buf the databuffer to put/get data
1469 *
1470 * Read factory OTP area.
1471 */
1472static int onenand_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
1473 size_t len, size_t *retlen, u_char *buf)
1474{
1475 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_read, MTD_OTP_FACTORY);
1476}
1477
1478/**
1479 * onenand_get_user_prot_info - [MTD Interface] Read user OTP info
1480 * @param mtd MTD device structure
1481 * @param buf the databuffer to put/get data
1482 * @param len number of bytes to read
1483 *
1484 * Read user OTP info.
1485 */
1486static int onenand_get_user_prot_info(struct mtd_info *mtd,
1487 struct otp_info *buf, size_t len)
1488{
1489 size_t retlen;
1490 int ret;
1491
1492 ret = onenand_otp_walk(mtd, 0, len, &retlen, (u_char *) buf, NULL, MTD_OTP_USER);
1493
1494 return ret ? : retlen;
1495}
1496
1497/**
1498 * onenand_read_user_prot_reg - [MTD Interface] Read user OTP area
1499 * @param mtd MTD device structure
1500 * @param from The offset to read
1501 * @param len number of bytes to read
1502 * @param retlen pointer to variable to store the number of read bytes
1503 * @param buf the databuffer to put/get data
1504 *
1505 * Read user OTP area.
1506 */
1507static int onenand_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
1508 size_t len, size_t *retlen, u_char *buf)
1509{
1510 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_read, MTD_OTP_USER);
1511}
1512
1513/**
1514 * onenand_write_user_prot_reg - [MTD Interface] Write user OTP area
1515 * @param mtd MTD device structure
1516 * @param from The offset to write
1517 * @param len number of bytes to write
1518 * @param retlen pointer to variable to store the number of write bytes
1519 * @param buf the databuffer to put/get data
1520 *
1521 * Write user OTP area.
1522 */
1523static int onenand_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
1524 size_t len, size_t *retlen, u_char *buf)
1525{
1526 return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write, MTD_OTP_USER);
1527}
1528
1529/**
1530 * onenand_lock_user_prot_reg - [MTD Interface] Lock user OTP area
1531 * @param mtd MTD device structure
1532 * @param from The offset to lock
1533 * @param len number of bytes to unlock
1534 *
1535 * Write lock mark on spare area in page 0 in OTP block
1536 */
1537static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
1538 size_t len)
1539{
1540 unsigned char oob_buf[64];
1541 size_t retlen;
1542 int ret;
1543
1544 memset(oob_buf, 0xff, mtd->oobsize);
1545 /*
1546 * Note: OTP lock operation
1547 * OTP block : 0xXXFC
1548 * 1st block : 0xXXF3 (If chip support)
1549 * Both : 0xXXF0 (If chip support)
1550 */
1551 oob_buf[ONENAND_OTP_LOCK_OFFSET] = 0xFC;
1552
1553 /*
1554 * Write lock mark to 8th word of sector0 of page0 of the spare0.
1555 * We write 16 bytes spare area instead of 2 bytes.
1556 */
1557 from = 0;
1558 len = 16;
1559
1560 ret = onenand_otp_walk(mtd, from, len, &retlen, oob_buf, do_otp_lock, MTD_OTP_USER);
1561
1562 return ret ? : retlen;
1563}
1564#endif /* CONFIG_MTD_ONENAND_OTP */
1565
1327/** 1566/**
1328 * onenand_print_device_info - Print device ID 1567 * onenand_print_device_info - Print device ID
1329 * @param device device ID 1568 * @param device device ID
@@ -1423,15 +1662,15 @@ static int onenand_probe(struct mtd_info *mtd)
1423 1662
1424 /* OneNAND page size & block size */ 1663 /* OneNAND page size & block size */
1425 /* The data buffer size is equal to page size */ 1664 /* The data buffer size is equal to page size */
1426 mtd->oobblock = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE); 1665 mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
1427 mtd->oobsize = mtd->oobblock >> 5; 1666 mtd->oobsize = mtd->writesize >> 5;
1428 /* Pagers per block is always 64 in OneNAND */ 1667 /* Pagers per block is always 64 in OneNAND */
1429 mtd->erasesize = mtd->oobblock << 6; 1668 mtd->erasesize = mtd->writesize << 6;
1430 1669
1431 this->erase_shift = ffs(mtd->erasesize) - 1; 1670 this->erase_shift = ffs(mtd->erasesize) - 1;
1432 this->page_shift = ffs(mtd->oobblock) - 1; 1671 this->page_shift = ffs(mtd->writesize) - 1;
1433 this->ppb_shift = (this->erase_shift - this->page_shift); 1672 this->ppb_shift = (this->erase_shift - this->page_shift);
1434 this->page_mask = (mtd->erasesize / mtd->oobblock) - 1; 1673 this->page_mask = (mtd->erasesize / mtd->writesize) - 1;
1435 1674
1436 /* REVIST: Multichip handling */ 1675 /* REVIST: Multichip handling */
1437 1676
@@ -1475,7 +1714,6 @@ static void onenand_resume(struct mtd_info *mtd)
1475 "in suspended state\n"); 1714 "in suspended state\n");
1476} 1715}
1477 1716
1478
1479/** 1717/**
1480 * onenand_scan - [OneNAND Interface] Scan for the OneNAND device 1718 * onenand_scan - [OneNAND Interface] Scan for the OneNAND device
1481 * @param mtd MTD device structure 1719 * @param mtd MTD device structure
@@ -1522,7 +1760,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
1522 /* Allocate buffers, if necessary */ 1760 /* Allocate buffers, if necessary */
1523 if (!this->page_buf) { 1761 if (!this->page_buf) {
1524 size_t len; 1762 size_t len;
1525 len = mtd->oobblock + mtd->oobsize; 1763 len = mtd->writesize + mtd->oobsize;
1526 this->page_buf = kmalloc(len, GFP_KERNEL); 1764 this->page_buf = kmalloc(len, GFP_KERNEL);
1527 if (!this->page_buf) { 1765 if (!this->page_buf) {
1528 printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n"); 1766 printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
@@ -1537,40 +1775,42 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
1537 1775
1538 switch (mtd->oobsize) { 1776 switch (mtd->oobsize) {
1539 case 64: 1777 case 64:
1540 this->autooob = &onenand_oob_64; 1778 this->ecclayout = &onenand_oob_64;
1541 break; 1779 break;
1542 1780
1543 case 32: 1781 case 32:
1544 this->autooob = &onenand_oob_32; 1782 this->ecclayout = &onenand_oob_32;
1545 break; 1783 break;
1546 1784
1547 default: 1785 default:
1548 printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n", 1786 printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",
1549 mtd->oobsize); 1787 mtd->oobsize);
1550 /* To prevent kernel oops */ 1788 /* To prevent kernel oops */
1551 this->autooob = &onenand_oob_32; 1789 this->ecclayout = &onenand_oob_32;
1552 break; 1790 break;
1553 } 1791 }
1554 1792
1555 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo)); 1793 mtd->ecclayout = this->ecclayout;
1556 1794
1557 /* Fill in remaining MTD driver data */ 1795 /* Fill in remaining MTD driver data */
1558 mtd->type = MTD_NANDFLASH; 1796 mtd->type = MTD_NANDFLASH;
1559 mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC; 1797 mtd->flags = MTD_CAP_NANDFLASH;
1560 mtd->ecctype = MTD_ECC_SW; 1798 mtd->ecctype = MTD_ECC_SW;
1561 mtd->erase = onenand_erase; 1799 mtd->erase = onenand_erase;
1562 mtd->point = NULL; 1800 mtd->point = NULL;
1563 mtd->unpoint = NULL; 1801 mtd->unpoint = NULL;
1564 mtd->read = onenand_read; 1802 mtd->read = onenand_read;
1565 mtd->write = onenand_write; 1803 mtd->write = onenand_write;
1566 mtd->read_ecc = onenand_read_ecc;
1567 mtd->write_ecc = onenand_write_ecc;
1568 mtd->read_oob = onenand_read_oob; 1804 mtd->read_oob = onenand_read_oob;
1569 mtd->write_oob = onenand_write_oob; 1805 mtd->write_oob = onenand_write_oob;
1570 mtd->readv = NULL; 1806#ifdef CONFIG_MTD_ONENAND_OTP
1571 mtd->readv_ecc = NULL; 1807 mtd->get_fact_prot_info = onenand_get_fact_prot_info;
1572 mtd->writev = onenand_writev; 1808 mtd->read_fact_prot_reg = onenand_read_fact_prot_reg;
1573 mtd->writev_ecc = onenand_writev_ecc; 1809 mtd->get_user_prot_info = onenand_get_user_prot_info;
1810 mtd->read_user_prot_reg = onenand_read_user_prot_reg;
1811 mtd->write_user_prot_reg = onenand_write_user_prot_reg;
1812 mtd->lock_user_prot_reg = onenand_lock_user_prot_reg;
1813#endif
1574 mtd->sync = onenand_sync; 1814 mtd->sync = onenand_sync;
1575 mtd->lock = NULL; 1815 mtd->lock = NULL;
1576 mtd->unlock = onenand_unlock; 1816 mtd->unlock = onenand_unlock;
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
index 4510d3361eaa..1b00dac3d7d6 100644
--- a/drivers/mtd/onenand/onenand_bbt.c
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -17,6 +17,9 @@
17#include <linux/mtd/onenand.h> 17#include <linux/mtd/onenand.h>
18#include <linux/mtd/compatmac.h> 18#include <linux/mtd/compatmac.h>
19 19
20extern int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
21 size_t *retlen, u_char *buf);
22
20/** 23/**
21 * check_short_pattern - [GENERIC] check if a pattern is in the buffer 24 * check_short_pattern - [GENERIC] check if a pattern is in the buffer
22 * @param buf the buffer to search 25 * @param buf the buffer to search
@@ -87,13 +90,13 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
87 90
88 /* No need to read pages fully, 91 /* No need to read pages fully,
89 * just read required OOB bytes */ 92 * just read required OOB bytes */
90 ret = mtd->read_oob(mtd, from + j * mtd->oobblock + bd->offs, 93 ret = onenand_do_read_oob(mtd, from + j * mtd->writesize + bd->offs,
91 readlen, &retlen, &buf[0]); 94 readlen, &retlen, &buf[0]);
92 95
93 if (ret) 96 if (ret)
94 return ret; 97 return ret;
95 98
96 if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { 99 if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
97 bbm->bbt[i >> 3] |= 0x03 << (i & 0x6); 100 bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
98 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 101 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
99 i >> 1, (unsigned int) from); 102 i >> 1, (unsigned int) from);