aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/onenand/onenand_base.c192
-rw-r--r--drivers/mtd/onenand/onenand_bbt.c3
-rw-r--r--include/linux/mtd/onenand.h3
3 files changed, 124 insertions, 74 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 63ca61b83bf5..2da6bb26353e 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -192,8 +192,6 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
192 struct onenand_chip *this = mtd->priv; 192 struct onenand_chip *this = mtd->priv;
193 int value, readcmd = 0, block_cmd = 0; 193 int value, readcmd = 0, block_cmd = 0;
194 int block, page; 194 int block, page;
195 /* Now we use page size operation */
196 int sectors = 4, count = 4;
197 195
198 /* Address translation */ 196 /* Address translation */
199 switch (cmd) { 197 switch (cmd) {
@@ -245,6 +243,8 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
245 } 243 }
246 244
247 if (page != -1) { 245 if (page != -1) {
246 /* Now we use page size operation */
247 int sectors = 4, count = 4;
248 int dataram; 248 int dataram;
249 249
250 switch (cmd) { 250 switch (cmd) {
@@ -298,7 +298,7 @@ static int onenand_wait(struct mtd_info *mtd, int state)
298 unsigned long timeout; 298 unsigned long timeout;
299 unsigned int flags = ONENAND_INT_MASTER; 299 unsigned int flags = ONENAND_INT_MASTER;
300 unsigned int interrupt = 0; 300 unsigned int interrupt = 0;
301 unsigned int ctrl, ecc; 301 unsigned int ctrl;
302 302
303 /* The 20 msec is enough */ 303 /* The 20 msec is enough */
304 timeout = jiffies + msecs_to_jiffies(20); 304 timeout = jiffies + msecs_to_jiffies(20);
@@ -310,7 +310,6 @@ static int onenand_wait(struct mtd_info *mtd, int state)
310 310
311 if (state != FL_READING) 311 if (state != FL_READING)
312 cond_resched(); 312 cond_resched();
313 touch_softlockup_watchdog();
314 } 313 }
315 /* To get correct interrupt status in timeout case */ 314 /* To get correct interrupt status in timeout case */
316 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); 315 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
@@ -318,24 +317,20 @@ static int onenand_wait(struct mtd_info *mtd, int state)
318 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); 317 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
319 318
320 if (ctrl & ONENAND_CTRL_ERROR) { 319 if (ctrl & ONENAND_CTRL_ERROR) {
321 /* It maybe occur at initial bad block */
322 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl); 320 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl);
323 /* Clear other interrupt bits for preventing ECC error */ 321 if (ctrl & ONENAND_CTRL_LOCK)
324 interrupt &= ONENAND_INT_MASTER; 322 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error.\n");
325 } 323 return ctrl;
326
327 if (ctrl & ONENAND_CTRL_LOCK) {
328 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error = 0x%04x\n", ctrl);
329 return -EACCES;
330 } 324 }
331 325
332 if (interrupt & ONENAND_INT_READ) { 326 if (interrupt & ONENAND_INT_READ) {
333 ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); 327 int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
334 if (ecc) { 328 if (ecc) {
335 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x\n", ecc); 329 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x\n", ecc);
336 if (ecc & ONENAND_ECC_2BIT_ALL) 330 if (ecc & ONENAND_ECC_2BIT_ALL) {
337 mtd->ecc_stats.failed++; 331 mtd->ecc_stats.failed++;
338 else if (ecc & ONENAND_ECC_1BIT_ALL) 332 return ecc;
333 } else if (ecc & ONENAND_ECC_1BIT_ALL)
339 mtd->ecc_stats.corrected++; 334 mtd->ecc_stats.corrected++;
340 } 335 }
341 } 336 }
@@ -372,9 +367,6 @@ static int onenand_interrupt_wait(struct mtd_info *mtd, int state)
372{ 367{
373 struct onenand_chip *this = mtd->priv; 368 struct onenand_chip *this = mtd->priv;
374 369
375 /* To prevent soft lockup */
376 touch_softlockup_watchdog();
377
378 wait_for_completion(&this->complete); 370 wait_for_completion(&this->complete);
379 371
380 return onenand_wait(mtd, state); 372 return onenand_wait(mtd, state);
@@ -395,9 +387,6 @@ static int onenand_try_interrupt_wait(struct mtd_info *mtd, int state)
395 /* We use interrupt wait first */ 387 /* We use interrupt wait first */
396 this->wait = onenand_interrupt_wait; 388 this->wait = onenand_interrupt_wait;
397 389
398 /* To prevent soft lockup */
399 touch_softlockup_watchdog();
400
401 timeout = msecs_to_jiffies(100); 390 timeout = msecs_to_jiffies(100);
402 remain = wait_for_completion_timeout(&this->complete, timeout); 391 remain = wait_for_completion_timeout(&this->complete, timeout);
403 if (!remain) { 392 if (!remain) {
@@ -721,7 +710,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
721 struct mtd_ecc_stats stats; 710 struct mtd_ecc_stats stats;
722 int read = 0, column; 711 int read = 0, column;
723 int thislen; 712 int thislen;
724 int ret = 0; 713 int ret = 0, boundary = 0;
725 714
726 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); 715 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
727 716
@@ -738,38 +727,60 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
738 /* TODO handling oob */ 727 /* TODO handling oob */
739 728
740 stats = mtd->ecc_stats; 729 stats = mtd->ecc_stats;
741 while (read < len) {
742 thislen = min_t(int, mtd->writesize, len - read);
743
744 column = from & (mtd->writesize - 1);
745 if (column + thislen > mtd->writesize)
746 thislen = mtd->writesize - column;
747
748 if (!onenand_check_bufferram(mtd, from)) {
749 this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);
750
751 ret = this->wait(mtd, FL_READING);
752 /* First copy data and check return value for ECC handling */
753 onenand_update_bufferram(mtd, from, 1);
754 }
755
756 this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
757
758 read += thislen;
759 730
760 if (read == len) 731 /* Read-while-load method */
761 break; 732
733 /* Do first load to bufferRAM */
734 if (read < len) {
735 if (!onenand_check_bufferram(mtd, from)) {
736 this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);
737 ret = this->wait(mtd, FL_READING);
738 onenand_update_bufferram(mtd, from, !ret);
739 }
740 }
741
742 thislen = min_t(int, mtd->writesize, len - read);
743 column = from & (mtd->writesize - 1);
744 if (column + thislen > mtd->writesize)
745 thislen = mtd->writesize - column;
746
747 while (!ret) {
748 /* If there is more to load then start next load */
749 from += thislen;
750 if (read + thislen < len) {
751 this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);
752 /*
753 * Chip boundary handling in DDP
754 * Now we issued chip 1 read and pointed chip 1
755 * bufferam so we have to point chip 0 bufferam.
756 */
757 if (this->device_id & ONENAND_DEVICE_IS_DDP &&
758 unlikely(from == (this->chipsize >> 1))) {
759 this->write_word(0, this->base + ONENAND_REG_START_ADDRESS2);
760 boundary = 1;
761 } else
762 boundary = 0;
763 ONENAND_SET_PREV_BUFFERRAM(this);
764 }
765 /* While load is going, read from last bufferRAM */
766 this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
767 /* See if we are done */
768 read += thislen;
769 if (read == len)
770 break;
771 /* Set up for next read from bufferRAM */
772 if (unlikely(boundary))
773 this->write_word(0x8000, this->base + ONENAND_REG_START_ADDRESS2);
774 ONENAND_SET_NEXT_BUFFERRAM(this);
775 buf += thislen;
776 thislen = min_t(int, mtd->writesize, len - read);
777 column = 0;
778 cond_resched();
779 /* Now wait for load */
780 ret = this->wait(mtd, FL_READING);
781 onenand_update_bufferram(mtd, from, !ret);
782 }
762 783
763 if (ret) {
764 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: read failed = %d\n", ret);
765 goto out;
766 }
767
768 from += thislen;
769 buf += thislen;
770 }
771
772out:
773 /* Deselect and wake up anyone waiting on the device */ 784 /* Deselect and wake up anyone waiting on the device */
774 onenand_release_device(mtd); 785 onenand_release_device(mtd);
775 786
@@ -783,6 +794,9 @@ out:
783 if (mtd->ecc_stats.failed - stats.failed) 794 if (mtd->ecc_stats.failed - stats.failed)
784 return -EBADMSG; 795 return -EBADMSG;
785 796
797 if (ret)
798 return ret;
799
786 return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0; 800 return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
787} 801}
788 802
@@ -820,6 +834,8 @@ int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
820 column = from & (mtd->oobsize - 1); 834 column = from & (mtd->oobsize - 1);
821 835
822 while (read < len) { 836 while (read < len) {
837 cond_resched();
838
823 thislen = mtd->oobsize - column; 839 thislen = mtd->oobsize - column;
824 thislen = min_t(int, thislen, len); 840 thislen = min_t(int, thislen, len);
825 841
@@ -832,16 +848,16 @@ int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
832 848
833 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen); 849 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
834 850
851 if (ret) {
852 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = 0x%x\n", ret);
853 goto out;
854 }
855
835 read += thislen; 856 read += thislen;
836 857
837 if (read == len) 858 if (read == len)
838 break; 859 break;
839 860
840 if (ret) {
841 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = %d\n", ret);
842 goto out;
843 }
844
845 buf += thislen; 861 buf += thislen;
846 862
847 /* Read more? */ 863 /* Read more? */
@@ -919,6 +935,10 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr)
919 void __iomem *dataram0, *dataram1; 935 void __iomem *dataram0, *dataram1;
920 int ret = 0; 936 int ret = 0;
921 937
938 /* In partial page write, just skip it */
939 if ((addr & (mtd->writesize - 1)) != 0)
940 return 0;
941
922 this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize); 942 this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);
923 943
924 ret = this->wait(mtd, FL_READING); 944 ret = this->wait(mtd, FL_READING);
@@ -941,7 +961,7 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr)
941#define onenand_verify_oob(...) (0) 961#define onenand_verify_oob(...) (0)
942#endif 962#endif
943 963
944#define NOTALIGNED(x) ((x & (mtd->writesize - 1)) != 0) 964#define NOTALIGNED(x) ((x & (this->subpagesize - 1)) != 0)
945 965
946/** 966/**
947 * onenand_write - [MTD Interface] write buffer to FLASH 967 * onenand_write - [MTD Interface] write buffer to FLASH
@@ -959,6 +979,7 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
959 struct onenand_chip *this = mtd->priv; 979 struct onenand_chip *this = mtd->priv;
960 int written = 0; 980 int written = 0;
961 int ret = 0; 981 int ret = 0;
982 int column, subpage;
962 983
963 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); 984 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
964 985
@@ -977,45 +998,63 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
977 return -EINVAL; 998 return -EINVAL;
978 } 999 }
979 1000
1001 column = to & (mtd->writesize - 1);
1002 subpage = column || (len & (mtd->writesize - 1));
1003
980 /* Grab the lock and see if the device is available */ 1004 /* Grab the lock and see if the device is available */
981 onenand_get_device(mtd, FL_WRITING); 1005 onenand_get_device(mtd, FL_WRITING);
982 1006
983 /* Loop until all data write */ 1007 /* Loop until all data write */
984 while (written < len) { 1008 while (written < len) {
985 int thislen = min_t(int, mtd->writesize, len - written); 1009 int bytes = mtd->writesize;
986 1010 int thislen = min_t(int, bytes, len - written);
987 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->writesize); 1011 u_char *wbuf = (u_char *) buf;
1012
1013 cond_resched();
1014
1015 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, bytes);
1016
1017 /* Partial page write */
1018 if (subpage) {
1019 bytes = min_t(int, bytes - column, (int) len);
1020 memset(this->page_buf, 0xff, mtd->writesize);
1021 memcpy(this->page_buf + column, buf, bytes);
1022 wbuf = this->page_buf;
1023 /* Even though partial write, we need page size */
1024 thislen = mtd->writesize;
1025 }
988 1026
989 this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen); 1027 this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, thislen);
990 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize); 1028 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
991 1029
992 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize); 1030 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
993 1031
994 onenand_update_bufferram(mtd, to, 1); 1032 /* In partial page write we don't update bufferram */
1033 onenand_update_bufferram(mtd, to, !subpage);
995 1034
996 ret = this->wait(mtd, FL_WRITING); 1035 ret = this->wait(mtd, FL_WRITING);
997 if (ret) { 1036 if (ret) {
998 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret); 1037 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret);
999 goto out; 1038 break;
1000 } 1039 }
1001 1040
1002 written += thislen;
1003
1004 /* Only check verify write turn on */ 1041 /* Only check verify write turn on */
1005 ret = onenand_verify_page(mtd, (u_char *) buf, to); 1042 ret = onenand_verify_page(mtd, (u_char *) wbuf, to);
1006 if (ret) { 1043 if (ret) {
1007 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret); 1044 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret);
1008 goto out; 1045 break;
1009 } 1046 }
1010 1047
1048 written += thislen;
1049
1011 if (written == len) 1050 if (written == len)
1012 break; 1051 break;
1013 1052
1053 column = 0;
1014 to += thislen; 1054 to += thislen;
1015 buf += thislen; 1055 buf += thislen;
1016 } 1056 }
1017 1057
1018out:
1019 /* Deselect and wake up anyone waiting on the device */ 1058 /* Deselect and wake up anyone waiting on the device */
1020 onenand_release_device(mtd); 1059 onenand_release_device(mtd);
1021 1060
@@ -1059,6 +1098,8 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1059 while (written < len) { 1098 while (written < len) {
1060 int thislen = min_t(int, mtd->oobsize, len - written); 1099 int thislen = min_t(int, mtd->oobsize, len - written);
1061 1100
1101 cond_resched();
1102
1062 column = to & (mtd->oobsize - 1); 1103 column = to & (mtd->oobsize - 1);
1063 1104
1064 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize); 1105 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
@@ -1186,6 +1227,7 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1186 instr->state = MTD_ERASING; 1227 instr->state = MTD_ERASING;
1187 1228
1188 while (len) { 1229 while (len) {
1230 cond_resched();
1189 1231
1190 /* Check if we have a bad block, we do not erase bad blocks */ 1232 /* Check if we have a bad block, we do not erase bad blocks */
1191 if (onenand_block_checkbad(mtd, addr, 0, 0)) { 1233 if (onenand_block_checkbad(mtd, addr, 0, 0)) {
@@ -1199,10 +1241,7 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1199 ret = this->wait(mtd, FL_ERASING); 1241 ret = this->wait(mtd, FL_ERASING);
1200 /* Check, if it is write protected */ 1242 /* Check, if it is write protected */
1201 if (ret) { 1243 if (ret) {
1202 if (ret == -EPERM) 1244 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));
1203 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Device is write protected!!!\n");
1204 else
1205 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));
1206 instr->state = MTD_ERASE_FAILED; 1245 instr->state = MTD_ERASE_FAILED;
1207 instr->fail_addr = addr; 1246 instr->fail_addr = addr;
1208 goto erase_exit; 1247 goto erase_exit;
@@ -2029,23 +2068,30 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
2029 init_waitqueue_head(&this->wq); 2068 init_waitqueue_head(&this->wq);
2030 spin_lock_init(&this->chip_lock); 2069 spin_lock_init(&this->chip_lock);
2031 2070
2071 /*
2072 * Allow subpage writes up to oobsize.
2073 */
2032 switch (mtd->oobsize) { 2074 switch (mtd->oobsize) {
2033 case 64: 2075 case 64:
2034 this->ecclayout = &onenand_oob_64; 2076 this->ecclayout = &onenand_oob_64;
2077 mtd->subpage_sft = 2;
2035 break; 2078 break;
2036 2079
2037 case 32: 2080 case 32:
2038 this->ecclayout = &onenand_oob_32; 2081 this->ecclayout = &onenand_oob_32;
2082 mtd->subpage_sft = 1;
2039 break; 2083 break;
2040 2084
2041 default: 2085 default:
2042 printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n", 2086 printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",
2043 mtd->oobsize); 2087 mtd->oobsize);
2088 mtd->subpage_sft = 0;
2044 /* To prevent kernel oops */ 2089 /* To prevent kernel oops */
2045 this->ecclayout = &onenand_oob_32; 2090 this->ecclayout = &onenand_oob_32;
2046 break; 2091 break;
2047 } 2092 }
2048 2093
2094 this->subpagesize = mtd->writesize >> mtd->subpage_sft;
2049 mtd->ecclayout = this->ecclayout; 2095 mtd->ecclayout = this->ecclayout;
2050 2096
2051 /* Fill in remaining MTD driver data */ 2097 /* Fill in remaining MTD driver data */
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
index 6cceeca40567..98f8fd1c6375 100644
--- a/drivers/mtd/onenand/onenand_bbt.c
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -93,7 +93,8 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
93 ret = onenand_do_read_oob(mtd, from + j * mtd->writesize + bd->offs, 93 ret = onenand_do_read_oob(mtd, from + j * mtd->writesize + bd->offs,
94 readlen, &retlen, &buf[0]); 94 readlen, &retlen, &buf[0]);
95 95
96 if (ret) 96 /* If it is a initial bad block, just ignore it */
97 if (ret && !(ret & ONENAND_CTRL_LOAD))
97 return ret; 98 return ret;
98 99
99 if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) { 100 if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index 62ca0f429822..f775a7af3890 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -88,6 +88,7 @@ struct onenand_bufferram {
88 * operation is in progress 88 * operation is in progress
89 * @state: [INTERN] the current state of the OneNAND device 89 * @state: [INTERN] the current state of the OneNAND device
90 * @page_buf: data buffer 90 * @page_buf: data buffer
91 * @subpagesize: [INTERN] holds the subpagesize
91 * @ecclayout: [REPLACEABLE] the default ecc placement scheme 92 * @ecclayout: [REPLACEABLE] the default ecc placement scheme
92 * @bbm: [REPLACEABLE] pointer to Bad Block Management 93 * @bbm: [REPLACEABLE] pointer to Bad Block Management
93 * @priv: [OPTIONAL] pointer to private chip date 94 * @priv: [OPTIONAL] pointer to private chip date
@@ -128,6 +129,7 @@ struct onenand_chip {
128 onenand_state_t state; 129 onenand_state_t state;
129 unsigned char *page_buf; 130 unsigned char *page_buf;
130 131
132 int subpagesize;
131 struct nand_ecclayout *ecclayout; 133 struct nand_ecclayout *ecclayout;
132 134
133 void *bbm; 135 void *bbm;
@@ -141,6 +143,7 @@ struct onenand_chip {
141#define ONENAND_CURRENT_BUFFERRAM(this) (this->bufferram_index) 143#define ONENAND_CURRENT_BUFFERRAM(this) (this->bufferram_index)
142#define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1) 144#define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1)
143#define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1) 145#define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1)
146#define ONENAND_SET_PREV_BUFFERRAM(this) (this->bufferram_index ^= 1)
144 147
145#define ONENAND_GET_SYS_CFG1(this) \ 148#define ONENAND_GET_SYS_CFG1(this) \
146 (this->read_word(this->base + ONENAND_REG_SYS_CFG1)) 149 (this->read_word(this->base + ONENAND_REG_SYS_CFG1))