aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-02-09 07:36:22 -0500
committerDavid Woodhouse <dwmw2@infradead.org>2007-02-09 07:36:22 -0500
commitc1f1625860847b57a0450a28d112423c2af675ff (patch)
tree2390866229b7d0eeb61166e77b153c8d3c70ee3a
parent552a8278d0becd671274af56a11ee601e585387a (diff)
parentcde36b37d6fa5ebc8c95461a972c379185626b2c (diff)
Merge branch 'master' of git://git.infradead.org/~kmpark/onenand-mtd-2.6
-rw-r--r--drivers/mtd/onenand/onenand_base.c572
-rw-r--r--drivers/mtd/onenand/onenand_bbt.c27
-rw-r--r--include/linux/mtd/bbm.h7
-rw-r--r--include/linux/mtd/onenand.h15
-rw-r--r--include/linux/mtd/onenand_regs.h7
5 files changed, 446 insertions, 182 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 2da6bb26353e..779327b845d1 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/mtd/onenand/onenand_base.c 2 * linux/drivers/mtd/onenand/onenand_base.c
3 * 3 *
4 * Copyright (C) 2005-2006 Samsung Electronics 4 * Copyright (C) 2005-2007 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com> 5 * Kyungmin Park <kyungmin.park@samsung.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -94,16 +94,9 @@ static void onenand_writew(unsigned short value, void __iomem *addr)
94 */ 94 */
95static int onenand_block_address(struct onenand_chip *this, int block) 95static int onenand_block_address(struct onenand_chip *this, int block)
96{ 96{
97 if (this->device_id & ONENAND_DEVICE_IS_DDP) { 97 /* Device Flash Core select, NAND Flash Block Address */
98 /* Device Flash Core select, NAND Flash Block Address */ 98 if (block & this->density_mask)
99 int dfs = 0; 99 return ONENAND_DDP_CHIP1 | (block ^ this->density_mask);
100
101 if (block & this->density_mask)
102 dfs = 1;
103
104 return (dfs << ONENAND_DDP_SHIFT) |
105 (block & (this->density_mask - 1));
106 }
107 100
108 return block; 101 return block;
109} 102}
@@ -118,17 +111,11 @@ static int onenand_block_address(struct onenand_chip *this, int block)
118 */ 111 */
119static int onenand_bufferram_address(struct onenand_chip *this, int block) 112static int onenand_bufferram_address(struct onenand_chip *this, int block)
120{ 113{
121 if (this->device_id & ONENAND_DEVICE_IS_DDP) { 114 /* Device BufferRAM Select */
122 /* Device BufferRAM Select */ 115 if (block & this->density_mask)
123 int dbs = 0; 116 return ONENAND_DDP_CHIP1;
124
125 if (block & this->density_mask)
126 dbs = 1;
127 117
128 return (dbs << ONENAND_DDP_SHIFT); 118 return ONENAND_DDP_CHIP0;
129 }
130
131 return 0;
132} 119}
133 120
134/** 121/**
@@ -317,22 +304,25 @@ static int onenand_wait(struct mtd_info *mtd, int state)
317 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); 304 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
318 305
319 if (ctrl & ONENAND_CTRL_ERROR) { 306 if (ctrl & ONENAND_CTRL_ERROR) {
320 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl); 307 printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n", ctrl);
321 if (ctrl & ONENAND_CTRL_LOCK) 308 if (ctrl & ONENAND_CTRL_LOCK)
322 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error.\n"); 309 printk(KERN_ERR "onenand_wait: it's locked error.\n");
323 return ctrl; 310 return ctrl;
324 } 311 }
325 312
326 if (interrupt & ONENAND_INT_READ) { 313 if (interrupt & ONENAND_INT_READ) {
327 int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); 314 int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
328 if (ecc) { 315 if (ecc) {
329 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x\n", ecc); 316 printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc);
330 if (ecc & ONENAND_ECC_2BIT_ALL) { 317 if (ecc & ONENAND_ECC_2BIT_ALL) {
331 mtd->ecc_stats.failed++; 318 mtd->ecc_stats.failed++;
332 return ecc; 319 return ecc;
333 } else if (ecc & ONENAND_ECC_1BIT_ALL) 320 } else if (ecc & ONENAND_ECC_1BIT_ALL)
334 mtd->ecc_stats.corrected++; 321 mtd->ecc_stats.corrected++;
335 } 322 }
323 } else if (state == FL_READING) {
324 printk(KERN_ERR "onenand_wait: read timeout! ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt);
325 return -EIO;
336 } 326 }
337 327
338 return 0; 328 return 0;
@@ -587,22 +577,32 @@ static int onenand_write_bufferram(struct mtd_info *mtd, int area,
587static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr) 577static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
588{ 578{
589 struct onenand_chip *this = mtd->priv; 579 struct onenand_chip *this = mtd->priv;
590 int block, page; 580 int blockpage, found = 0;
591 int i; 581 unsigned int i;
592 582
593 block = (int) (addr >> this->erase_shift); 583 blockpage = (int) (addr >> this->page_shift);
594 page = (int) (addr >> this->page_shift);
595 page &= this->page_mask;
596 584
585 /* Is there valid data? */
597 i = ONENAND_CURRENT_BUFFERRAM(this); 586 i = ONENAND_CURRENT_BUFFERRAM(this);
587 if (this->bufferram[i].blockpage == blockpage)
588 found = 1;
589 else {
590 /* Check another BufferRAM */
591 i = ONENAND_NEXT_BUFFERRAM(this);
592 if (this->bufferram[i].blockpage == blockpage) {
593 ONENAND_SET_NEXT_BUFFERRAM(this);
594 found = 1;
595 }
596 }
598 597
599 /* Is there valid data? */ 598 if (found && ONENAND_IS_DDP(this)) {
600 if (this->bufferram[i].block == block && 599 /* Select DataRAM for DDP */
601 this->bufferram[i].page == page && 600 int block = (int) (addr >> this->erase_shift);
602 this->bufferram[i].valid) 601 int value = onenand_bufferram_address(this, block);
603 return 1; 602 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
603 }
604 604
605 return 0; 605 return found;
606} 606}
607 607
608/** 608/**
@@ -613,31 +613,26 @@ static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
613 * 613 *
614 * Update BufferRAM information 614 * Update BufferRAM information
615 */ 615 */
616static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr, 616static void onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
617 int valid) 617 int valid)
618{ 618{
619 struct onenand_chip *this = mtd->priv; 619 struct onenand_chip *this = mtd->priv;
620 int block, page; 620 int blockpage;
621 int i; 621 unsigned int i;
622 622
623 block = (int) (addr >> this->erase_shift); 623 blockpage = (int) (addr >> this->page_shift);
624 page = (int) (addr >> this->page_shift);
625 page &= this->page_mask;
626 624
627 /* Invalidate BufferRAM */ 625 /* Invalidate another BufferRAM */
628 for (i = 0; i < MAX_BUFFERRAM; i++) { 626 i = ONENAND_NEXT_BUFFERRAM(this);
629 if (this->bufferram[i].block == block && 627 if (this->bufferram[i].blockpage == blockpage)
630 this->bufferram[i].page == page) 628 this->bufferram[i].blockpage = -1;
631 this->bufferram[i].valid = 0;
632 }
633 629
634 /* Update BufferRAM */ 630 /* Update BufferRAM */
635 i = ONENAND_CURRENT_BUFFERRAM(this); 631 i = ONENAND_CURRENT_BUFFERRAM(this);
636 this->bufferram[i].block = block; 632 if (valid)
637 this->bufferram[i].page = page; 633 this->bufferram[i].blockpage = blockpage;
638 this->bufferram[i].valid = valid; 634 else
639 635 this->bufferram[i].blockpage = -1;
640 return 0;
641} 636}
642 637
643/** 638/**
@@ -716,7 +711,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
716 711
717 /* Do not allow reads past end of device */ 712 /* Do not allow reads past end of device */
718 if ((from + len) > mtd->size) { 713 if ((from + len) > mtd->size) {
719 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: Attempt read beyond end of device\n"); 714 printk(KERN_ERR "onenand_read: Attempt read beyond end of device\n");
720 *retlen = 0; 715 *retlen = 0;
721 return -EINVAL; 716 return -EINVAL;
722 } 717 }
@@ -724,8 +719,6 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
724 /* Grab the lock and see if the device is available */ 719 /* Grab the lock and see if the device is available */
725 onenand_get_device(mtd, FL_READING); 720 onenand_get_device(mtd, FL_READING);
726 721
727 /* TODO handling oob */
728
729 stats = mtd->ecc_stats; 722 stats = mtd->ecc_stats;
730 723
731 /* Read-while-load method */ 724 /* Read-while-load method */
@@ -754,9 +747,9 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
754 * Now we issued chip 1 read and pointed chip 1 747 * Now we issued chip 1 read and pointed chip 1
755 * bufferam so we have to point chip 0 bufferam. 748 * bufferam so we have to point chip 0 bufferam.
756 */ 749 */
757 if (this->device_id & ONENAND_DEVICE_IS_DDP && 750 if (ONENAND_IS_DDP(this) &&
758 unlikely(from == (this->chipsize >> 1))) { 751 unlikely(from == (this->chipsize >> 1))) {
759 this->write_word(0, this->base + ONENAND_REG_START_ADDRESS2); 752 this->write_word(ONENAND_DDP_CHIP0, this->base + ONENAND_REG_START_ADDRESS2);
760 boundary = 1; 753 boundary = 1;
761 } else 754 } else
762 boundary = 0; 755 boundary = 0;
@@ -770,7 +763,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
770 break; 763 break;
771 /* Set up for next read from bufferRAM */ 764 /* Set up for next read from bufferRAM */
772 if (unlikely(boundary)) 765 if (unlikely(boundary))
773 this->write_word(0x8000, this->base + ONENAND_REG_START_ADDRESS2); 766 this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2);
774 ONENAND_SET_NEXT_BUFFERRAM(this); 767 ONENAND_SET_NEXT_BUFFERRAM(this);
775 buf += thislen; 768 buf += thislen;
776 thislen = min_t(int, mtd->writesize, len - read); 769 thislen = min_t(int, mtd->writesize, len - read);
@@ -801,20 +794,59 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
801} 794}
802 795
803/** 796/**
797 * onenand_transfer_auto_oob - [Internal] oob auto-placement transfer
798 * @param mtd MTD device structure
799 * @param buf destination address
800 * @param column oob offset to read from
801 * @param thislen oob length to read
802 */
803static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int column,
804 int thislen)
805{
806 struct onenand_chip *this = mtd->priv;
807 struct nand_oobfree *free;
808 int readcol = column;
809 int readend = column + thislen;
810 int lastgap = 0;
811 uint8_t *oob_buf = this->page_buf + mtd->writesize;
812
813 for (free = this->ecclayout->oobfree; free->length; ++free) {
814 if (readcol >= lastgap)
815 readcol += free->offset - lastgap;
816 if (readend >= lastgap)
817 readend += free->offset - lastgap;
818 lastgap = free->offset + free->length;
819 }
820 this->read_bufferram(mtd, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
821 for (free = this->ecclayout->oobfree; free->length; ++free) {
822 int free_end = free->offset + free->length;
823 if (free->offset < readend && free_end > readcol) {
824 int st = max_t(int,free->offset,readcol);
825 int ed = min_t(int,free_end,readend);
826 int n = ed - st;
827 memcpy(buf, oob_buf + st, n);
828 buf += n;
829 }
830 }
831 return 0;
832}
833
834/**
804 * onenand_do_read_oob - [MTD Interface] OneNAND read out-of-band 835 * onenand_do_read_oob - [MTD Interface] OneNAND read out-of-band
805 * @param mtd MTD device structure 836 * @param mtd MTD device structure
806 * @param from offset to read from 837 * @param from offset to read from
807 * @param len number of bytes to read 838 * @param len number of bytes to read
808 * @param retlen pointer to variable to store the number of read bytes 839 * @param retlen pointer to variable to store the number of read bytes
809 * @param buf the databuffer to put data 840 * @param buf the databuffer to put data
841 * @param mode operation mode
810 * 842 *
811 * OneNAND read out-of-band data from the spare area 843 * OneNAND read out-of-band data from the spare area
812 */ 844 */
813int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len, 845static int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
814 size_t *retlen, u_char *buf) 846 size_t *retlen, u_char *buf, mtd_oob_mode_t mode)
815{ 847{
816 struct onenand_chip *this = mtd->priv; 848 struct onenand_chip *this = mtd->priv;
817 int read = 0, thislen, column; 849 int read = 0, thislen, column, oobsize;
818 int ret = 0; 850 int ret = 0;
819 851
820 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); 852 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
@@ -822,21 +854,33 @@ int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
822 /* Initialize return length value */ 854 /* Initialize return length value */
823 *retlen = 0; 855 *retlen = 0;
824 856
857 if (mode == MTD_OOB_AUTO)
858 oobsize = this->ecclayout->oobavail;
859 else
860 oobsize = mtd->oobsize;
861
862 column = from & (mtd->oobsize - 1);
863
864 if (unlikely(column >= oobsize)) {
865 printk(KERN_ERR "onenand_read_oob: Attempted to start read outside oob\n");
866 return -EINVAL;
867 }
868
825 /* Do not allow reads past end of device */ 869 /* Do not allow reads past end of device */
826 if (unlikely((from + len) > mtd->size)) { 870 if (unlikely(from >= mtd->size ||
827 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: Attempt read beyond end of device\n"); 871 column + len > ((mtd->size >> this->page_shift) -
872 (from >> this->page_shift)) * oobsize)) {
873 printk(KERN_ERR "onenand_read_oob: Attempted to read beyond end of device\n");
828 return -EINVAL; 874 return -EINVAL;
829 } 875 }
830 876
831 /* Grab the lock and see if the device is available */ 877 /* Grab the lock and see if the device is available */
832 onenand_get_device(mtd, FL_READING); 878 onenand_get_device(mtd, FL_READING);
833 879
834 column = from & (mtd->oobsize - 1);
835
836 while (read < len) { 880 while (read < len) {
837 cond_resched(); 881 cond_resched();
838 882
839 thislen = mtd->oobsize - column; 883 thislen = oobsize - column;
840 thislen = min_t(int, thislen, len); 884 thislen = min_t(int, thislen, len);
841 885
842 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize); 886 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
@@ -846,11 +890,14 @@ int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
846 ret = this->wait(mtd, FL_READING); 890 ret = this->wait(mtd, FL_READING);
847 /* First copy data and check return value for ECC handling */ 891 /* First copy data and check return value for ECC handling */
848 892
849 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen); 893 if (mode == MTD_OOB_AUTO)
894 onenand_transfer_auto_oob(mtd, buf, column, thislen);
895 else
896 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
850 897
851 if (ret) { 898 if (ret) {
852 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = 0x%x\n", ret); 899 printk(KERN_ERR "onenand_read_oob: read failed = 0x%x\n", ret);
853 goto out; 900 break;
854 } 901 }
855 902
856 read += thislen; 903 read += thislen;
@@ -868,7 +915,6 @@ int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
868 } 915 }
869 } 916 }
870 917
871out:
872 /* Deselect and wake up anyone waiting on the device */ 918 /* Deselect and wake up anyone waiting on the device */
873 onenand_release_device(mtd); 919 onenand_release_device(mtd);
874 920
@@ -885,10 +931,132 @@ out:
885static int onenand_read_oob(struct mtd_info *mtd, loff_t from, 931static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
886 struct mtd_oob_ops *ops) 932 struct mtd_oob_ops *ops)
887{ 933{
888 BUG_ON(ops->mode != MTD_OOB_PLACE); 934 switch (ops->mode) {
889 935 case MTD_OOB_PLACE:
936 case MTD_OOB_AUTO:
937 break;
938 case MTD_OOB_RAW:
939 /* Not implemented yet */
940 default:
941 return -EINVAL;
942 }
890 return onenand_do_read_oob(mtd, from + ops->ooboffs, ops->ooblen, 943 return onenand_do_read_oob(mtd, from + ops->ooboffs, ops->ooblen,
891 &ops->oobretlen, ops->oobbuf); 944 &ops->oobretlen, ops->oobbuf, ops->mode);
945}
946
947/**
948 * onenand_bbt_wait - [DEFAULT] wait until the command is done
949 * @param mtd MTD device structure
950 * @param state state to select the max. timeout value
951 *
952 * Wait for command done.
953 */
954static int onenand_bbt_wait(struct mtd_info *mtd, int state)
955{
956 struct onenand_chip *this = mtd->priv;
957 unsigned long timeout;
958 unsigned int interrupt;
959 unsigned int ctrl;
960
961 /* The 20 msec is enough */
962 timeout = jiffies + msecs_to_jiffies(20);
963 while (time_before(jiffies, timeout)) {
964 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
965 if (interrupt & ONENAND_INT_MASTER)
966 break;
967 }
968 /* To get correct interrupt status in timeout case */
969 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
970 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
971
972 if (ctrl & ONENAND_CTRL_ERROR) {
973 printk(KERN_DEBUG "onenand_bbt_wait: controller error = 0x%04x\n", ctrl);
974 /* Initial bad block case */
975 if (ctrl & ONENAND_CTRL_LOAD)
976 return ONENAND_BBT_READ_ERROR;
977 return ONENAND_BBT_READ_FATAL_ERROR;
978 }
979
980 if (interrupt & ONENAND_INT_READ) {
981 int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
982 if (ecc & ONENAND_ECC_2BIT_ALL)
983 return ONENAND_BBT_READ_ERROR;
984 } else {
985 printk(KERN_ERR "onenand_bbt_wait: read timeout!"
986 "ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt);
987 return ONENAND_BBT_READ_FATAL_ERROR;
988 }
989
990 return 0;
991}
992
993/**
994 * onenand_bbt_read_oob - [MTD Interface] OneNAND read out-of-band for bbt scan
995 * @param mtd MTD device structure
996 * @param from offset to read from
997 * @param @ops oob operation description structure
998 *
999 * OneNAND read out-of-band data from the spare area for bbt scan
1000 */
1001int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
1002 struct mtd_oob_ops *ops)
1003{
1004 struct onenand_chip *this = mtd->priv;
1005 int read = 0, thislen, column;
1006 int ret = 0;
1007 size_t len = ops->ooblen;
1008 u_char *buf = ops->oobbuf;
1009
1010 DEBUG(MTD_DEBUG_LEVEL3, "onenand_bbt_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, len);
1011
1012 /* Initialize return value */
1013 ops->oobretlen = 0;
1014
1015 /* Do not allow reads past end of device */
1016 if (unlikely((from + len) > mtd->size)) {
1017 printk(KERN_ERR "onenand_bbt_read_oob: Attempt read beyond end of device\n");
1018 return ONENAND_BBT_READ_FATAL_ERROR;
1019 }
1020
1021 /* Grab the lock and see if the device is available */
1022 onenand_get_device(mtd, FL_READING);
1023
1024 column = from & (mtd->oobsize - 1);
1025
1026 while (read < len) {
1027 cond_resched();
1028
1029 thislen = mtd->oobsize - column;
1030 thislen = min_t(int, thislen, len);
1031
1032 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
1033
1034 onenand_update_bufferram(mtd, from, 0);
1035
1036 ret = onenand_bbt_wait(mtd, FL_READING);
1037 if (ret)
1038 break;
1039
1040 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
1041 read += thislen;
1042 if (read == len)
1043 break;
1044
1045 buf += thislen;
1046
1047 /* Read more? */
1048 if (read < len) {
1049 /* Update Page size */
1050 from += mtd->writesize;
1051 column = 0;
1052 }
1053 }
1054
1055 /* Deselect and wake up anyone waiting on the device */
1056 onenand_release_device(mtd);
1057
1058 ops->oobretlen = read;
1059 return ret;
892} 1060}
893 1061
894#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE 1062#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
@@ -897,14 +1065,12 @@ static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
897 * @param mtd MTD device structure 1065 * @param mtd MTD device structure
898 * @param buf the databuffer to verify 1066 * @param buf the databuffer to verify
899 * @param to offset to read from 1067 * @param to offset to read from
900 * @param len number of bytes to read and compare
901 * 1068 *
902 */ 1069 */
903static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to, int len) 1070static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to)
904{ 1071{
905 struct onenand_chip *this = mtd->priv; 1072 struct onenand_chip *this = mtd->priv;
906 char *readp = this->page_buf; 1073 char *readp = this->page_buf + mtd->writesize;
907 int column = to & (mtd->oobsize - 1);
908 int status, i; 1074 int status, i;
909 1075
910 this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize); 1076 this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize);
@@ -913,9 +1079,8 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to
913 if (status) 1079 if (status)
914 return status; 1080 return status;
915 1081
916 this->read_bufferram(mtd, ONENAND_SPARERAM, readp, column, len); 1082 this->read_bufferram(mtd, ONENAND_SPARERAM, readp, 0, mtd->oobsize);
917 1083 for(i = 0; i < mtd->oobsize; i++)
918 for(i = 0; i < len; i++)
919 if (buf[i] != 0xFF && buf[i] != readp[i]) 1084 if (buf[i] != 0xFF && buf[i] != readp[i])
920 return -EBADMSG; 1085 return -EBADMSG;
921 1086
@@ -923,41 +1088,51 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to
923} 1088}
924 1089
925/** 1090/**
926 * onenand_verify_page - [GENERIC] verify the chip contents after a write 1091 * onenand_verify - [GENERIC] verify the chip contents after a write
927 * @param mtd MTD device structure 1092 * @param mtd MTD device structure
928 * @param buf the databuffer to verify 1093 * @param buf the databuffer to verify
1094 * @param addr offset to read from
1095 * @param len number of bytes to read and compare
929 * 1096 *
930 * Check DataRAM area directly
931 */ 1097 */
932static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr) 1098static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr, size_t len)
933{ 1099{
934 struct onenand_chip *this = mtd->priv; 1100 struct onenand_chip *this = mtd->priv;
935 void __iomem *dataram0, *dataram1; 1101 void __iomem *dataram;
936 int ret = 0; 1102 int ret = 0;
1103 int thislen, column;
937 1104
938 /* In partial page write, just skip it */ 1105 while (len != 0) {
939 if ((addr & (mtd->writesize - 1)) != 0) 1106 thislen = min_t(int, mtd->writesize, len);
940 return 0; 1107 column = addr & (mtd->writesize - 1);
1108 if (column + thislen > mtd->writesize)
1109 thislen = mtd->writesize - column;
941 1110
942 this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize); 1111 this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);
943 1112
944 ret = this->wait(mtd, FL_READING); 1113 onenand_update_bufferram(mtd, addr, 0);
945 if (ret) 1114
946 return ret; 1115 ret = this->wait(mtd, FL_READING);
1116 if (ret)
1117 return ret;
947 1118
948 onenand_update_bufferram(mtd, addr, 1); 1119 onenand_update_bufferram(mtd, addr, 1);
949 1120
950 /* Check, if the two dataram areas are same */ 1121 dataram = this->base + ONENAND_DATARAM;
951 dataram0 = this->base + ONENAND_DATARAM; 1122 dataram += onenand_bufferram_offset(mtd, ONENAND_DATARAM);
952 dataram1 = dataram0 + mtd->writesize;
953 1123
954 if (memcmp(dataram0, dataram1, mtd->writesize)) 1124 if (memcmp(buf, dataram + column, thislen))
955 return -EBADMSG; 1125 return -EBADMSG;
1126
1127 len -= thislen;
1128 buf += thislen;
1129 addr += thislen;
1130 }
956 1131
957 return 0; 1132 return 0;
958} 1133}
959#else 1134#else
960#define onenand_verify_page(...) (0) 1135#define onenand_verify(...) (0)
961#define onenand_verify_oob(...) (0) 1136#define onenand_verify_oob(...) (0)
962#endif 1137#endif
963 1138
@@ -988,60 +1163,57 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
988 1163
989 /* Do not allow writes past end of device */ 1164 /* Do not allow writes past end of device */
990 if (unlikely((to + len) > mtd->size)) { 1165 if (unlikely((to + len) > mtd->size)) {
991 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: Attempt write to past end of device\n"); 1166 printk(KERN_ERR "onenand_write: Attempt write to past end of device\n");
992 return -EINVAL; 1167 return -EINVAL;
993 } 1168 }
994 1169
995 /* Reject writes, which are not page aligned */ 1170 /* Reject writes, which are not page aligned */
996 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) { 1171 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
997 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: Attempt to write not page aligned data\n"); 1172 printk(KERN_ERR "onenand_write: Attempt to write not page aligned data\n");
998 return -EINVAL; 1173 return -EINVAL;
999 } 1174 }
1000 1175
1001 column = to & (mtd->writesize - 1); 1176 column = to & (mtd->writesize - 1);
1002 subpage = column || (len & (mtd->writesize - 1));
1003 1177
1004 /* Grab the lock and see if the device is available */ 1178 /* Grab the lock and see if the device is available */
1005 onenand_get_device(mtd, FL_WRITING); 1179 onenand_get_device(mtd, FL_WRITING);
1006 1180
1007 /* Loop until all data write */ 1181 /* Loop until all data write */
1008 while (written < len) { 1182 while (written < len) {
1009 int bytes = mtd->writesize; 1183 int thislen = min_t(int, mtd->writesize - column, len - written);
1010 int thislen = min_t(int, bytes, len - written);
1011 u_char *wbuf = (u_char *) buf; 1184 u_char *wbuf = (u_char *) buf;
1012 1185
1013 cond_resched(); 1186 cond_resched();
1014 1187
1015 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, bytes); 1188 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
1016 1189
1017 /* Partial page write */ 1190 /* Partial page write */
1191 subpage = thislen < mtd->writesize;
1018 if (subpage) { 1192 if (subpage) {
1019 bytes = min_t(int, bytes - column, (int) len);
1020 memset(this->page_buf, 0xff, mtd->writesize); 1193 memset(this->page_buf, 0xff, mtd->writesize);
1021 memcpy(this->page_buf + column, buf, bytes); 1194 memcpy(this->page_buf + column, buf, thislen);
1022 wbuf = this->page_buf; 1195 wbuf = this->page_buf;
1023 /* Even though partial write, we need page size */
1024 thislen = mtd->writesize;
1025 } 1196 }
1026 1197
1027 this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, thislen); 1198 this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
1028 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize); 1199 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
1029 1200
1030 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize); 1201 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
1031 1202
1203 ret = this->wait(mtd, FL_WRITING);
1204
1032 /* In partial page write we don't update bufferram */ 1205 /* In partial page write we don't update bufferram */
1033 onenand_update_bufferram(mtd, to, !subpage); 1206 onenand_update_bufferram(mtd, to, !ret && !subpage);
1034 1207
1035 ret = this->wait(mtd, FL_WRITING);
1036 if (ret) { 1208 if (ret) {
1037 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret); 1209 printk(KERN_ERR "onenand_write: write filaed %d\n", ret);
1038 break; 1210 break;
1039 } 1211 }
1040 1212
1041 /* Only check verify write turn on */ 1213 /* Only check verify write turn on */
1042 ret = onenand_verify_page(mtd, (u_char *) wbuf, to); 1214 ret = onenand_verify(mtd, (u_char *) wbuf, to, thislen);
1043 if (ret) { 1215 if (ret) {
1044 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret); 1216 printk(KERN_ERR "onenand_write: verify failed %d\n", ret);
1045 break; 1217 break;
1046 } 1218 }
1047 1219
@@ -1064,20 +1236,58 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
1064} 1236}
1065 1237
1066/** 1238/**
1239 * onenand_fill_auto_oob - [Internal] oob auto-placement transfer
1240 * @param mtd MTD device structure
1241 * @param oob_buf oob buffer
1242 * @param buf source address
1243 * @param column oob offset to write to
1244 * @param thislen oob length to write
1245 */
1246static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
1247 const u_char *buf, int column, int thislen)
1248{
1249 struct onenand_chip *this = mtd->priv;
1250 struct nand_oobfree *free;
1251 int writecol = column;
1252 int writeend = column + thislen;
1253 int lastgap = 0;
1254
1255 for (free = this->ecclayout->oobfree; free->length; ++free) {
1256 if (writecol >= lastgap)
1257 writecol += free->offset - lastgap;
1258 if (writeend >= lastgap)
1259 writeend += free->offset - lastgap;
1260 lastgap = free->offset + free->length;
1261 }
1262 for (free = this->ecclayout->oobfree; free->length; ++free) {
1263 int free_end = free->offset + free->length;
1264 if (free->offset < writeend && free_end > writecol) {
1265 int st = max_t(int,free->offset,writecol);
1266 int ed = min_t(int,free_end,writeend);
1267 int n = ed - st;
1268 memcpy(oob_buf + st, buf, n);
1269 buf += n;
1270 }
1271 }
1272 return 0;
1273}
1274
1275/**
1067 * onenand_do_write_oob - [Internal] OneNAND write out-of-band 1276 * onenand_do_write_oob - [Internal] OneNAND write out-of-band
1068 * @param mtd MTD device structure 1277 * @param mtd MTD device structure
1069 * @param to offset to write to 1278 * @param to offset to write to
1070 * @param len number of bytes to write 1279 * @param len number of bytes to write
1071 * @param retlen pointer to variable to store the number of written bytes 1280 * @param retlen pointer to variable to store the number of written bytes
1072 * @param buf the data to write 1281 * @param buf the data to write
1282 * @param mode operation mode
1073 * 1283 *
1074 * OneNAND write out-of-band 1284 * OneNAND write out-of-band
1075 */ 1285 */
1076static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len, 1286static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1077 size_t *retlen, const u_char *buf) 1287 size_t *retlen, const u_char *buf, mtd_oob_mode_t mode)
1078{ 1288{
1079 struct onenand_chip *this = mtd->priv; 1289 struct onenand_chip *this = mtd->priv;
1080 int column, ret = 0; 1290 int column, ret = 0, oobsize;
1081 int written = 0; 1291 int written = 0;
1082 1292
1083 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); 1293 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
@@ -1085,9 +1295,30 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1085 /* Initialize retlen, in case of early exit */ 1295 /* Initialize retlen, in case of early exit */
1086 *retlen = 0; 1296 *retlen = 0;
1087 1297
1088 /* Do not allow writes past end of device */ 1298 if (mode == MTD_OOB_AUTO)
1089 if (unlikely((to + len) > mtd->size)) { 1299 oobsize = this->ecclayout->oobavail;
1090 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: Attempt write to past end of device\n"); 1300 else
1301 oobsize = mtd->oobsize;
1302
1303 column = to & (mtd->oobsize - 1);
1304
1305 if (unlikely(column >= oobsize)) {
1306 printk(KERN_ERR "onenand_write_oob: Attempted to start write outside oob\n");
1307 return -EINVAL;
1308 }
1309
1310 /* For compatibility with NAND: Do not allow write past end of page */
1311 if (column + len > oobsize) {
1312 printk(KERN_ERR "onenand_write_oob: "
1313 "Attempt to write past end of page\n");
1314 return -EINVAL;
1315 }
1316
1317 /* Do not allow reads past end of device */
1318 if (unlikely(to >= mtd->size ||
1319 column + len > ((mtd->size >> this->page_shift) -
1320 (to >> this->page_shift)) * oobsize)) {
1321 printk(KERN_ERR "onenand_write_oob: Attempted to write past end of device\n");
1091 return -EINVAL; 1322 return -EINVAL;
1092 } 1323 }
1093 1324
@@ -1096,18 +1327,19 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1096 1327
1097 /* Loop until all data write */ 1328 /* Loop until all data write */
1098 while (written < len) { 1329 while (written < len) {
1099 int thislen = min_t(int, mtd->oobsize, len - written); 1330 int thislen = min_t(int, oobsize, len - written);
1100 1331
1101 cond_resched(); 1332 cond_resched();
1102 1333
1103 column = to & (mtd->oobsize - 1);
1104
1105 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize); 1334 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
1106 1335
1107 /* We send data to spare ram with oobsize 1336 /* We send data to spare ram with oobsize
1108 * to prevent byte access */ 1337 * to prevent byte access */
1109 memset(this->page_buf, 0xff, mtd->oobsize); 1338 memset(this->page_buf, 0xff, mtd->oobsize);
1110 memcpy(this->page_buf + column, buf, thislen); 1339 if (mode == MTD_OOB_AUTO)
1340 onenand_fill_auto_oob(mtd, this->page_buf, buf, column, thislen);
1341 else
1342 memcpy(this->page_buf + column, buf, thislen);
1111 this->write_bufferram(mtd, ONENAND_SPARERAM, this->page_buf, 0, mtd->oobsize); 1343 this->write_bufferram(mtd, ONENAND_SPARERAM, this->page_buf, 0, mtd->oobsize);
1112 1344
1113 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize); 1345 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
@@ -1116,26 +1348,25 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1116 1348
1117 ret = this->wait(mtd, FL_WRITING); 1349 ret = this->wait(mtd, FL_WRITING);
1118 if (ret) { 1350 if (ret) {
1119 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: write filaed %d\n", ret); 1351 printk(KERN_ERR "onenand_write_oob: write failed %d\n", ret);
1120 goto out; 1352 break;
1121 } 1353 }
1122 1354
1123 ret = onenand_verify_oob(mtd, buf, to, thislen); 1355 ret = onenand_verify_oob(mtd, this->page_buf, to);
1124 if (ret) { 1356 if (ret) {
1125 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: verify failed %d\n", ret); 1357 printk(KERN_ERR "onenand_write_oob: verify failed %d\n", ret);
1126 goto out; 1358 break;
1127 } 1359 }
1128 1360
1129 written += thislen; 1361 written += thislen;
1130
1131 if (written == len) 1362 if (written == len)
1132 break; 1363 break;
1133 1364
1134 to += thislen; 1365 to += mtd->writesize;
1135 buf += thislen; 1366 buf += thislen;
1367 column = 0;
1136 } 1368 }
1137 1369
1138out:
1139 /* Deselect and wake up anyone waiting on the device */ 1370 /* Deselect and wake up anyone waiting on the device */
1140 onenand_release_device(mtd); 1371 onenand_release_device(mtd);
1141 1372
@@ -1153,10 +1384,17 @@ out:
1153static int onenand_write_oob(struct mtd_info *mtd, loff_t to, 1384static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
1154 struct mtd_oob_ops *ops) 1385 struct mtd_oob_ops *ops)
1155{ 1386{
1156 BUG_ON(ops->mode != MTD_OOB_PLACE); 1387 switch (ops->mode) {
1157 1388 case MTD_OOB_PLACE:
1389 case MTD_OOB_AUTO:
1390 break;
1391 case MTD_OOB_RAW:
1392 /* Not implemented yet */
1393 default:
1394 return -EINVAL;
1395 }
1158 return onenand_do_write_oob(mtd, to + ops->ooboffs, ops->ooblen, 1396 return onenand_do_write_oob(mtd, to + ops->ooboffs, ops->ooblen,
1159 &ops->oobretlen, ops->oobbuf); 1397 &ops->oobretlen, ops->oobbuf, ops->mode);
1160} 1398}
1161 1399
1162/** 1400/**
@@ -1199,19 +1437,19 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1199 1437
1200 /* Start address must align on block boundary */ 1438 /* Start address must align on block boundary */
1201 if (unlikely(instr->addr & (block_size - 1))) { 1439 if (unlikely(instr->addr & (block_size - 1))) {
1202 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Unaligned address\n"); 1440 printk(KERN_ERR "onenand_erase: Unaligned address\n");
1203 return -EINVAL; 1441 return -EINVAL;
1204 } 1442 }
1205 1443
1206 /* Length must align on block boundary */ 1444 /* Length must align on block boundary */
1207 if (unlikely(instr->len & (block_size - 1))) { 1445 if (unlikely(instr->len & (block_size - 1))) {
1208 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Length not block aligned\n"); 1446 printk(KERN_ERR "onenand_erase: Length not block aligned\n");
1209 return -EINVAL; 1447 return -EINVAL;
1210 } 1448 }
1211 1449
1212 /* Do not allow erase past end of device */ 1450 /* Do not allow erase past end of device */
1213 if (unlikely((instr->len + instr->addr) > mtd->size)) { 1451 if (unlikely((instr->len + instr->addr) > mtd->size)) {
1214 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Erase past end of device\n"); 1452 printk(KERN_ERR "onenand_erase: Erase past end of device\n");
1215 return -EINVAL; 1453 return -EINVAL;
1216 } 1454 }
1217 1455
@@ -1241,7 +1479,7 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1241 ret = this->wait(mtd, FL_ERASING); 1479 ret = this->wait(mtd, FL_ERASING);
1242 /* Check, if it is write protected */ 1480 /* Check, if it is write protected */
1243 if (ret) { 1481 if (ret) {
1244 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift)); 1482 printk(KERN_ERR "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));
1245 instr->state = MTD_ERASE_FAILED; 1483 instr->state = MTD_ERASE_FAILED;
1246 instr->fail_addr = addr; 1484 instr->fail_addr = addr;
1247 goto erase_exit; 1485 goto erase_exit;
@@ -1322,7 +1560,7 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
1322 1560
1323 /* We write two bytes, so we dont have to mess with 16 bit access */ 1561 /* We write two bytes, so we dont have to mess with 16 bit access */
1324 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01); 1562 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
1325 return onenand_do_write_oob(mtd, ofs , 2, &retlen, buf); 1563 return onenand_do_write_oob(mtd, ofs , 2, &retlen, buf, MTD_OOB_PLACE);
1326} 1564}
1327 1565
1328/** 1566/**
@@ -1491,6 +1729,8 @@ static int onenand_unlock_all(struct mtd_info *mtd)
1491 struct onenand_chip *this = mtd->priv; 1729 struct onenand_chip *this = mtd->priv;
1492 1730
1493 if (this->options & ONENAND_HAS_UNLOCK_ALL) { 1731 if (this->options & ONENAND_HAS_UNLOCK_ALL) {
1732 /* Set start block address */
1733 this->write_word(0, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1494 /* Write unlock command */ 1734 /* Write unlock command */
1495 this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0); 1735 this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
1496 1736
@@ -1503,13 +1743,10 @@ static int onenand_unlock_all(struct mtd_info *mtd)
1503 continue; 1743 continue;
1504 1744
1505 /* Workaround for all block unlock in DDP */ 1745 /* Workaround for all block unlock in DDP */
1506 if (this->device_id & ONENAND_DEVICE_IS_DDP) { 1746 if (ONENAND_IS_DDP(this)) {
1507 loff_t ofs;
1508 size_t len;
1509
1510 /* 1st block on another chip */ 1747 /* 1st block on another chip */
1511 ofs = this->chipsize >> 1; 1748 loff_t ofs = this->chipsize >> 1;
1512 len = 1 << this->erase_shift; 1749 size_t len = mtd->erasesize;
1513 1750
1514 onenand_unlock(mtd, ofs, len); 1751 onenand_unlock(mtd, ofs, len);
1515 } 1752 }
@@ -1617,7 +1854,7 @@ static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len,
1617 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); 1854 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
1618 this->wait(mtd, FL_OTPING); 1855 this->wait(mtd, FL_OTPING);
1619 1856
1620 ret = onenand_do_write_oob(mtd, from, len, retlen, buf); 1857 ret = onenand_do_write_oob(mtd, from, len, retlen, buf, MTD_OOB_PLACE);
1621 1858
1622 /* Exit OTP access mode */ 1859 /* Exit OTP access mode */
1623 this->command(mtd, ONENAND_CMD_RESET, 0, 0); 1860 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
@@ -1823,12 +2060,13 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
1823#endif /* CONFIG_MTD_ONENAND_OTP */ 2060#endif /* CONFIG_MTD_ONENAND_OTP */
1824 2061
1825/** 2062/**
1826 * onenand_lock_scheme - Check and set OneNAND lock scheme 2063 * onenand_check_features - Check and set OneNAND features
1827 * @param mtd MTD data structure 2064 * @param mtd MTD data structure
1828 * 2065 *
1829 * Check and set OneNAND lock scheme 2066 * Check and set OneNAND features
2067 * - lock scheme
1830 */ 2068 */
1831static void onenand_lock_scheme(struct mtd_info *mtd) 2069static void onenand_check_features(struct mtd_info *mtd)
1832{ 2070{
1833 struct onenand_chip *this = mtd->priv; 2071 struct onenand_chip *this = mtd->priv;
1834 unsigned int density, process; 2072 unsigned int density, process;
@@ -1961,26 +2199,28 @@ static int onenand_probe(struct mtd_info *mtd)
1961 density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT; 2199 density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
1962 this->chipsize = (16 << density) << 20; 2200 this->chipsize = (16 << density) << 20;
1963 /* Set density mask. it is used for DDP */ 2201 /* Set density mask. it is used for DDP */
1964 this->density_mask = (1 << (density + 6)); 2202 if (ONENAND_IS_DDP(this))
2203 this->density_mask = (1 << (density + 6));
2204 else
2205 this->density_mask = 0;
1965 2206
1966 /* OneNAND page size & block size */ 2207 /* OneNAND page size & block size */
1967 /* The data buffer size is equal to page size */ 2208 /* The data buffer size is equal to page size */
1968 mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE); 2209 mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
1969 mtd->oobsize = mtd->writesize >> 5; 2210 mtd->oobsize = mtd->writesize >> 5;
1970 /* Pagers per block is always 64 in OneNAND */ 2211 /* Pages per a block are always 64 in OneNAND */
1971 mtd->erasesize = mtd->writesize << 6; 2212 mtd->erasesize = mtd->writesize << 6;
1972 2213
1973 this->erase_shift = ffs(mtd->erasesize) - 1; 2214 this->erase_shift = ffs(mtd->erasesize) - 1;
1974 this->page_shift = ffs(mtd->writesize) - 1; 2215 this->page_shift = ffs(mtd->writesize) - 1;
1975 this->ppb_shift = (this->erase_shift - this->page_shift); 2216 this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1;
1976 this->page_mask = (mtd->erasesize / mtd->writesize) - 1;
1977 2217
1978 /* REVIST: Multichip handling */ 2218 /* REVIST: Multichip handling */
1979 2219
1980 mtd->size = this->chipsize; 2220 mtd->size = this->chipsize;
1981 2221
1982 /* Check OneNAND lock scheme */ 2222 /* Check OneNAND features */
1983 onenand_lock_scheme(mtd); 2223 onenand_check_features(mtd);
1984 2224
1985 return 0; 2225 return 0;
1986} 2226}
@@ -2021,6 +2261,7 @@ static void onenand_resume(struct mtd_info *mtd)
2021 */ 2261 */
2022int onenand_scan(struct mtd_info *mtd, int maxchips) 2262int onenand_scan(struct mtd_info *mtd, int maxchips)
2023{ 2263{
2264 int i;
2024 struct onenand_chip *this = mtd->priv; 2265 struct onenand_chip *this = mtd->priv;
2025 2266
2026 if (!this->read_word) 2267 if (!this->read_word)
@@ -2092,6 +2333,16 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
2092 } 2333 }
2093 2334
2094 this->subpagesize = mtd->writesize >> mtd->subpage_sft; 2335 this->subpagesize = mtd->writesize >> mtd->subpage_sft;
2336
2337 /*
2338 * The number of bytes available for a client to place data into
2339 * the out of band area
2340 */
2341 this->ecclayout->oobavail = 0;
2342 for (i = 0; this->ecclayout->oobfree[i].length; i++)
2343 this->ecclayout->oobavail +=
2344 this->ecclayout->oobfree[i].length;
2345
2095 mtd->ecclayout = this->ecclayout; 2346 mtd->ecclayout = this->ecclayout;
2096 2347
2097 /* Fill in remaining MTD driver data */ 2348 /* Fill in remaining MTD driver data */
@@ -2144,8 +2395,11 @@ void onenand_release(struct mtd_info *mtd)
2144 del_mtd_device (mtd); 2395 del_mtd_device (mtd);
2145 2396
2146 /* Free bad block table memory, if allocated */ 2397 /* Free bad block table memory, if allocated */
2147 if (this->bbm) 2398 if (this->bbm) {
2399 struct bbm_info *bbm = this->bbm;
2400 kfree(bbm->bbt);
2148 kfree(this->bbm); 2401 kfree(this->bbm);
2402 }
2149 /* Buffer allocated by onenand_scan */ 2403 /* Buffer allocated by onenand_scan */
2150 if (this->options & ONENAND_PAGEBUF_ALLOC) 2404 if (this->options & ONENAND_PAGEBUF_ALLOC)
2151 kfree(this->page_buf); 2405 kfree(this->page_buf);
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
index 98f8fd1c6375..aecdd50a1781 100644
--- a/drivers/mtd/onenand/onenand_bbt.c
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -17,8 +17,8 @@
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, 20extern int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
21 size_t *retlen, u_char *buf); 21 struct mtd_oob_ops *ops);
22 22
23/** 23/**
24 * 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
@@ -65,10 +65,11 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
65 int startblock; 65 int startblock;
66 loff_t from; 66 loff_t from;
67 size_t readlen, ooblen; 67 size_t readlen, ooblen;
68 struct mtd_oob_ops ops;
68 69
69 printk(KERN_INFO "Scanning device for bad blocks\n"); 70 printk(KERN_INFO "Scanning device for bad blocks\n");
70 71
71 len = 1; 72 len = 2;
72 73
73 /* We need only read few bytes from the OOB area */ 74 /* We need only read few bytes from the OOB area */
74 scanlen = ooblen = 0; 75 scanlen = ooblen = 0;
@@ -82,22 +83,24 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
82 startblock = 0; 83 startblock = 0;
83 from = 0; 84 from = 0;
84 85
86 ops.mode = MTD_OOB_PLACE;
87 ops.ooblen = readlen;
88 ops.oobbuf = buf;
89 ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
90
85 for (i = startblock; i < numblocks; ) { 91 for (i = startblock; i < numblocks; ) {
86 int ret; 92 int ret;
87 93
88 for (j = 0; j < len; j++) { 94 for (j = 0; j < len; j++) {
89 size_t retlen;
90
91 /* No need to read pages fully, 95 /* No need to read pages fully,
92 * just read required OOB bytes */ 96 * just read required OOB bytes */
93 ret = onenand_do_read_oob(mtd, from + j * mtd->writesize + bd->offs, 97 ret = onenand_bbt_read_oob(mtd, from + j * mtd->writesize + bd->offs, &ops);
94 readlen, &retlen, &buf[0]);
95 98
96 /* If it is a initial bad block, just ignore it */ 99 /* If it is a initial bad block, just ignore it */
97 if (ret && !(ret & ONENAND_CTRL_LOAD)) 100 if (ret == ONENAND_BBT_READ_FATAL_ERROR)
98 return ret; 101 return -EIO;
99 102
100 if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) { 103 if (ret || check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
101 bbm->bbt[i >> 3] |= 0x03 << (i & 0x6); 104 bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
102 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 105 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
103 i >> 1, (unsigned int) from); 106 i >> 1, (unsigned int) from);
@@ -168,8 +171,8 @@ static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
168 * marked good / bad blocks and writes the bad block table(s) to 171 * marked good / bad blocks and writes the bad block table(s) to
169 * the selected place. 172 * the selected place.
170 * 173 *
171 * The bad block table memory is allocated here. It must be freed 174 * The bad block table memory is allocated here. It is freed
172 * by calling the onenand_free_bbt function. 175 * by the onenand_release function.
173 * 176 *
174 */ 177 */
175int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) 178int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
index 1221b7c44158..fff8c53e5434 100644
--- a/include/linux/mtd/bbm.h
+++ b/include/linux/mtd/bbm.h
@@ -92,6 +92,13 @@ struct nand_bbt_descr {
92 */ 92 */
93#define ONENAND_BADBLOCK_POS 0 93#define ONENAND_BADBLOCK_POS 0
94 94
95/*
96 * Bad block scanning errors
97 */
98#define ONENAND_BBT_READ_ERROR 1
99#define ONENAND_BBT_READ_ECC_ERROR 2
100#define ONENAND_BBT_READ_FATAL_ERROR 4
101
95/** 102/**
96 * struct bbm_info - [GENERIC] Bad Block Table data structure 103 * struct bbm_info - [GENERIC] Bad Block Table data structure
97 * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry 104 * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index f775a7af3890..d8af8a95e58d 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/include/linux/mtd/onenand.h 2 * linux/include/linux/mtd/onenand.h
3 * 3 *
4 * Copyright (C) 2005-2006 Samsung Electronics 4 * Copyright (C) 2005-2007 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com> 5 * Kyungmin Park <kyungmin.park@samsung.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -42,14 +42,10 @@ typedef enum {
42 42
43/** 43/**
44 * struct onenand_bufferram - OneNAND BufferRAM Data 44 * struct onenand_bufferram - OneNAND BufferRAM Data
45 * @block: block address in BufferRAM 45 * @blockpage: block & page address in BufferRAM
46 * @page: page address in BufferRAM
47 * @valid: valid flag
48 */ 46 */
49struct onenand_bufferram { 47struct onenand_bufferram {
50 int block; 48 int blockpage;
51 int page;
52 int valid;
53}; 49};
54 50
55/** 51/**
@@ -63,7 +59,6 @@ struct onenand_bufferram {
63 * partly be set to inform onenand_scan about 59 * partly be set to inform onenand_scan about
64 * @erase_shift: [INTERN] number of address bits in a block 60 * @erase_shift: [INTERN] number of address bits in a block
65 * @page_shift: [INTERN] number of address bits in a page 61 * @page_shift: [INTERN] number of address bits in a page
66 * @ppb_shift: [INTERN] number of address bits in a pages per block
67 * @page_mask: [INTERN] a page per block mask 62 * @page_mask: [INTERN] a page per block mask
68 * @bufferram_index: [INTERN] BufferRAM index 63 * @bufferram_index: [INTERN] BufferRAM index
69 * @bufferram: [INTERN] BufferRAM info 64 * @bufferram: [INTERN] BufferRAM info
@@ -103,7 +98,6 @@ struct onenand_chip {
103 98
104 unsigned int erase_shift; 99 unsigned int erase_shift;
105 unsigned int page_shift; 100 unsigned int page_shift;
106 unsigned int ppb_shift; /* Pages per block shift */
107 unsigned int page_mask; 101 unsigned int page_mask;
108 102
109 unsigned int bufferram_index; 103 unsigned int bufferram_index;
@@ -150,6 +144,9 @@ struct onenand_chip {
150#define ONENAND_SET_SYS_CFG1(v, this) \ 144#define ONENAND_SET_SYS_CFG1(v, this) \
151 (this->write_word(v, this->base + ONENAND_REG_SYS_CFG1)) 145 (this->write_word(v, this->base + ONENAND_REG_SYS_CFG1))
152 146
147#define ONENAND_IS_DDP(this) \
148 (this->device_id & ONENAND_DEVICE_IS_DDP)
149
153/* Check byte access in OneNAND */ 150/* Check byte access in OneNAND */
154#define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1) 151#define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1)
155 152
diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h
index e31c8f5d4271..af94719890e7 100644
--- a/include/linux/mtd/onenand_regs.h
+++ b/include/linux/mtd/onenand_regs.h
@@ -3,7 +3,8 @@
3 * 3 *
4 * OneNAND Register header file 4 * OneNAND Register header file
5 * 5 *
6 * Copyright (C) 2005-2006 Samsung Electronics 6 * Copyright (C) 2005-2007 Samsung Electronics
7 * Kyungmin Park <kyungmin.park@samsung.com>
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
@@ -80,9 +81,11 @@
80#define ONENAND_VERSION_PROCESS_SHIFT (8) 81#define ONENAND_VERSION_PROCESS_SHIFT (8)
81 82
82/* 83/*
83 * Start Address 1 F100h (R/W) 84 * Start Address 1 F100h (R/W) & Start Address 2 F101h (R/W)
84 */ 85 */
85#define ONENAND_DDP_SHIFT (15) 86#define ONENAND_DDP_SHIFT (15)
87#define ONENAND_DDP_CHIP0 (0)
88#define ONENAND_DDP_CHIP1 (1 << ONENAND_DDP_SHIFT)
86 89
87/* 90/*
88 * Start Address 8 F107h (R/W) 91 * Start Address 8 F107h (R/W)