aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/onenand/onenand_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/onenand/onenand_base.c')
-rw-r--r--drivers/mtd/onenand/onenand_base.c170
1 files changed, 95 insertions, 75 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 40d8d6ff626b..85a97198bee3 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -333,12 +333,14 @@ static int onenand_wait(struct mtd_info *mtd, int state)
333 if (interrupt & ONENAND_INT_READ) { 333 if (interrupt & ONENAND_INT_READ) {
334 int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); 334 int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
335 if (ecc) { 335 if (ecc) {
336 printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc);
337 if (ecc & ONENAND_ECC_2BIT_ALL) { 336 if (ecc & ONENAND_ECC_2BIT_ALL) {
337 printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc);
338 mtd->ecc_stats.failed++; 338 mtd->ecc_stats.failed++;
339 return ecc; 339 return ecc;
340 } else if (ecc & ONENAND_ECC_1BIT_ALL) 340 } else if (ecc & ONENAND_ECC_1BIT_ALL) {
341 printk(KERN_INFO "onenand_wait: correctable ECC error = 0x%04x\n", ecc);
341 mtd->ecc_stats.corrected++; 342 mtd->ecc_stats.corrected++;
343 }
342 } 344 }
343 } else if (state == FL_READING) { 345 } else if (state == FL_READING) {
344 printk(KERN_ERR "onenand_wait: read timeout! ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt); 346 printk(KERN_ERR "onenand_wait: read timeout! ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt);
@@ -805,14 +807,14 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int col
805} 807}
806 808
807/** 809/**
808 * onenand_read_ops - [OneNAND Interface] OneNAND read main and/or out-of-band 810 * onenand_read_ops_nolock - [OneNAND Interface] OneNAND read main and/or out-of-band
809 * @param mtd MTD device structure 811 * @param mtd MTD device structure
810 * @param from offset to read from 812 * @param from offset to read from
811 * @param ops: oob operation description structure 813 * @param ops: oob operation description structure
812 * 814 *
813 * OneNAND read main and/or out-of-band data 815 * OneNAND read main and/or out-of-band data
814 */ 816 */
815static int onenand_read_ops(struct mtd_info *mtd, loff_t from, 817static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
816 struct mtd_oob_ops *ops) 818 struct mtd_oob_ops *ops)
817{ 819{
818 struct onenand_chip *this = mtd->priv; 820 struct onenand_chip *this = mtd->priv;
@@ -826,7 +828,7 @@ static int onenand_read_ops(struct mtd_info *mtd, loff_t from,
826 int ret = 0, boundary = 0; 828 int ret = 0, boundary = 0;
827 int writesize = this->writesize; 829 int writesize = this->writesize;
828 830
829 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ops: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); 831 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ops_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
830 832
831 if (ops->mode == MTD_OOB_AUTO) 833 if (ops->mode == MTD_OOB_AUTO)
832 oobsize = this->ecclayout->oobavail; 834 oobsize = this->ecclayout->oobavail;
@@ -837,15 +839,12 @@ static int onenand_read_ops(struct mtd_info *mtd, loff_t from,
837 839
838 /* Do not allow reads past end of device */ 840 /* Do not allow reads past end of device */
839 if ((from + len) > mtd->size) { 841 if ((from + len) > mtd->size) {
840 printk(KERN_ERR "onenand_read_ops: Attempt read beyond end of device\n"); 842 printk(KERN_ERR "onenand_read_ops_nolock: Attempt read beyond end of device\n");
841 ops->retlen = 0; 843 ops->retlen = 0;
842 ops->oobretlen = 0; 844 ops->oobretlen = 0;
843 return -EINVAL; 845 return -EINVAL;
844 } 846 }
845 847
846 /* Grab the lock and see if the device is available */
847 onenand_get_device(mtd, FL_READING);
848
849 stats = mtd->ecc_stats; 848 stats = mtd->ecc_stats;
850 849
851 /* Read-while-load method */ 850 /* Read-while-load method */
@@ -916,9 +915,6 @@ static int onenand_read_ops(struct mtd_info *mtd, loff_t from,
916 onenand_update_bufferram(mtd, from, !ret); 915 onenand_update_bufferram(mtd, from, !ret);
917 } 916 }
918 917
919 /* Deselect and wake up anyone waiting on the device */
920 onenand_release_device(mtd);
921
922 /* 918 /*
923 * Return success, if no ECC failures, else -EBADMSG 919 * Return success, if no ECC failures, else -EBADMSG
924 * fs driver will take care of that, because 920 * fs driver will take care of that, because
@@ -937,14 +933,14 @@ static int onenand_read_ops(struct mtd_info *mtd, loff_t from,
937} 933}
938 934
939/** 935/**
940 * onenand_do_read_oob - [MTD Interface] OneNAND read out-of-band 936 * onenand_read_oob_nolock - [MTD Interface] OneNAND read out-of-band
941 * @param mtd MTD device structure 937 * @param mtd MTD device structure
942 * @param from offset to read from 938 * @param from offset to read from
943 * @param ops: oob operation description structure 939 * @param ops: oob operation description structure
944 * 940 *
945 * OneNAND read out-of-band data from the spare area 941 * OneNAND read out-of-band data from the spare area
946 */ 942 */
947static int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, 943static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
948 struct mtd_oob_ops *ops) 944 struct mtd_oob_ops *ops)
949{ 945{
950 struct onenand_chip *this = mtd->priv; 946 struct onenand_chip *this = mtd->priv;
@@ -956,7 +952,7 @@ static int onenand_do_read_oob(struct mtd_info *mtd, loff_t from,
956 952
957 from += ops->ooboffs; 953 from += ops->ooboffs;
958 954
959 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); 955 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
960 956
961 /* Initialize return length value */ 957 /* Initialize return length value */
962 ops->oobretlen = 0; 958 ops->oobretlen = 0;
@@ -969,7 +965,7 @@ static int onenand_do_read_oob(struct mtd_info *mtd, loff_t from,
969 column = from & (mtd->oobsize - 1); 965 column = from & (mtd->oobsize - 1);
970 966
971 if (unlikely(column >= oobsize)) { 967 if (unlikely(column >= oobsize)) {
972 printk(KERN_ERR "onenand_read_oob: Attempted to start read outside oob\n"); 968 printk(KERN_ERR "onenand_read_oob_nolock: Attempted to start read outside oob\n");
973 return -EINVAL; 969 return -EINVAL;
974 } 970 }
975 971
@@ -977,13 +973,10 @@ static int onenand_do_read_oob(struct mtd_info *mtd, loff_t from,
977 if (unlikely(from >= mtd->size || 973 if (unlikely(from >= mtd->size ||
978 column + len > ((mtd->size >> this->page_shift) - 974 column + len > ((mtd->size >> this->page_shift) -
979 (from >> this->page_shift)) * oobsize)) { 975 (from >> this->page_shift)) * oobsize)) {
980 printk(KERN_ERR "onenand_read_oob: Attempted to read beyond end of device\n"); 976 printk(KERN_ERR "onenand_read_oob_nolock: Attempted to read beyond end of device\n");
981 return -EINVAL; 977 return -EINVAL;
982 } 978 }
983 979
984 /* Grab the lock and see if the device is available */
985 onenand_get_device(mtd, FL_READING);
986
987 while (read < len) { 980 while (read < len) {
988 cond_resched(); 981 cond_resched();
989 982
@@ -1003,7 +996,7 @@ static int onenand_do_read_oob(struct mtd_info *mtd, loff_t from,
1003 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen); 996 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
1004 997
1005 if (ret) { 998 if (ret) {
1006 printk(KERN_ERR "onenand_read_oob: read failed = 0x%x\n", ret); 999 printk(KERN_ERR "onenand_read_oob_nolock: read failed = 0x%x\n", ret);
1007 break; 1000 break;
1008 } 1001 }
1009 1002
@@ -1022,9 +1015,6 @@ static int onenand_do_read_oob(struct mtd_info *mtd, loff_t from,
1022 } 1015 }
1023 } 1016 }
1024 1017
1025 /* Deselect and wake up anyone waiting on the device */
1026 onenand_release_device(mtd);
1027
1028 ops->oobretlen = read; 1018 ops->oobretlen = read;
1029 return ret; 1019 return ret;
1030} 1020}
@@ -1050,9 +1040,11 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
1050 }; 1040 };
1051 int ret; 1041 int ret;
1052 1042
1053 ret = onenand_read_ops(mtd, from, &ops); 1043 onenand_get_device(mtd, FL_READING);
1054 *retlen = ops.retlen; 1044 ret = onenand_read_ops_nolock(mtd, from, &ops);
1045 onenand_release_device(mtd);
1055 1046
1047 *retlen = ops.retlen;
1056 return ret; 1048 return ret;
1057} 1049}
1058 1050
@@ -1067,6 +1059,8 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
1067static int onenand_read_oob(struct mtd_info *mtd, loff_t from, 1059static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
1068 struct mtd_oob_ops *ops) 1060 struct mtd_oob_ops *ops)
1069{ 1061{
1062 int ret;
1063
1070 switch (ops->mode) { 1064 switch (ops->mode) {
1071 case MTD_OOB_PLACE: 1065 case MTD_OOB_PLACE:
1072 case MTD_OOB_AUTO: 1066 case MTD_OOB_AUTO:
@@ -1077,10 +1071,14 @@ static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
1077 return -EINVAL; 1071 return -EINVAL;
1078 } 1072 }
1079 1073
1074 onenand_get_device(mtd, FL_READING);
1080 if (ops->datbuf) 1075 if (ops->datbuf)
1081 return onenand_read_ops(mtd, from, ops); 1076 ret = onenand_read_ops_nolock(mtd, from, ops);
1077 else
1078 ret = onenand_read_oob_nolock(mtd, from, ops);
1079 onenand_release_device(mtd);
1082 1080
1083 return onenand_do_read_oob(mtd, from, ops); 1081 return ret;
1084} 1082}
1085 1083
1086/** 1084/**
@@ -1317,14 +1315,14 @@ static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
1317} 1315}
1318 1316
1319/** 1317/**
1320 * onenand_write_ops - [OneNAND Interface] write main and/or out-of-band 1318 * onenand_write_ops_nolock - [OneNAND Interface] write main and/or out-of-band
1321 * @param mtd MTD device structure 1319 * @param mtd MTD device structure
1322 * @param to offset to write to 1320 * @param to offset to write to
1323 * @param ops oob operation description structure 1321 * @param ops oob operation description structure
1324 * 1322 *
1325 * Write main and/or oob with ECC 1323 * Write main and/or oob with ECC
1326 */ 1324 */
1327static int onenand_write_ops(struct mtd_info *mtd, loff_t to, 1325static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
1328 struct mtd_oob_ops *ops) 1326 struct mtd_oob_ops *ops)
1329{ 1327{
1330 struct onenand_chip *this = mtd->priv; 1328 struct onenand_chip *this = mtd->priv;
@@ -1337,7 +1335,7 @@ static int onenand_write_ops(struct mtd_info *mtd, loff_t to,
1337 u_char *oobbuf; 1335 u_char *oobbuf;
1338 int ret = 0; 1336 int ret = 0;
1339 1337
1340 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); 1338 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ops_nolock: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
1341 1339
1342 /* Initialize retlen, in case of early exit */ 1340 /* Initialize retlen, in case of early exit */
1343 ops->retlen = 0; 1341 ops->retlen = 0;
@@ -1345,13 +1343,13 @@ static int onenand_write_ops(struct mtd_info *mtd, loff_t to,
1345 1343
1346 /* Do not allow writes past end of device */ 1344 /* Do not allow writes past end of device */
1347 if (unlikely((to + len) > mtd->size)) { 1345 if (unlikely((to + len) > mtd->size)) {
1348 printk(KERN_ERR "onenand_write: Attempt write to past end of device\n"); 1346 printk(KERN_ERR "onenand_write_ops_nolock: Attempt write to past end of device\n");
1349 return -EINVAL; 1347 return -EINVAL;
1350 } 1348 }
1351 1349
1352 /* Reject writes, which are not page aligned */ 1350 /* Reject writes, which are not page aligned */
1353 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) { 1351 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
1354 printk(KERN_ERR "onenand_write: Attempt to write not page aligned data\n"); 1352 printk(KERN_ERR "onenand_write_ops_nolock: Attempt to write not page aligned data\n");
1355 return -EINVAL; 1353 return -EINVAL;
1356 } 1354 }
1357 1355
@@ -1364,9 +1362,6 @@ static int onenand_write_ops(struct mtd_info *mtd, loff_t to,
1364 1362
1365 column = to & (mtd->writesize - 1); 1363 column = to & (mtd->writesize - 1);
1366 1364
1367 /* Grab the lock and see if the device is available */
1368 onenand_get_device(mtd, FL_WRITING);
1369
1370 /* Loop until all data write */ 1365 /* Loop until all data write */
1371 while (written < len) { 1366 while (written < len) {
1372 u_char *wbuf = (u_char *) buf; 1367 u_char *wbuf = (u_char *) buf;
@@ -1419,14 +1414,14 @@ static int onenand_write_ops(struct mtd_info *mtd, loff_t to,
1419 } 1414 }
1420 1415
1421 if (ret) { 1416 if (ret) {
1422 printk(KERN_ERR "onenand_write: write filaed %d\n", ret); 1417 printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
1423 break; 1418 break;
1424 } 1419 }
1425 1420
1426 /* Only check verify write turn on */ 1421 /* Only check verify write turn on */
1427 ret = onenand_verify(mtd, (u_char *) wbuf, to, thislen); 1422 ret = onenand_verify(mtd, (u_char *) wbuf, to, thislen);
1428 if (ret) { 1423 if (ret) {
1429 printk(KERN_ERR "onenand_write: verify failed %d\n", ret); 1424 printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
1430 break; 1425 break;
1431 } 1426 }
1432 1427
@@ -1450,7 +1445,7 @@ static int onenand_write_ops(struct mtd_info *mtd, loff_t to,
1450 1445
1451 1446
1452/** 1447/**
1453 * onenand_do_write_oob - [Internal] OneNAND write out-of-band 1448 * onenand_write_oob_nolock - [Internal] OneNAND write out-of-band
1454 * @param mtd MTD device structure 1449 * @param mtd MTD device structure
1455 * @param to offset to write to 1450 * @param to offset to write to
1456 * @param len number of bytes to write 1451 * @param len number of bytes to write
@@ -1460,8 +1455,8 @@ static int onenand_write_ops(struct mtd_info *mtd, loff_t to,
1460 * 1455 *
1461 * OneNAND write out-of-band 1456 * OneNAND write out-of-band
1462 */ 1457 */
1463static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, 1458static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
1464 struct mtd_oob_ops *ops) 1459 struct mtd_oob_ops *ops)
1465{ 1460{
1466 struct onenand_chip *this = mtd->priv; 1461 struct onenand_chip *this = mtd->priv;
1467 int column, ret = 0, oobsize; 1462 int column, ret = 0, oobsize;
@@ -1473,7 +1468,7 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to,
1473 1468
1474 to += ops->ooboffs; 1469 to += ops->ooboffs;
1475 1470
1476 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); 1471 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob_nolock: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
1477 1472
1478 /* Initialize retlen, in case of early exit */ 1473 /* Initialize retlen, in case of early exit */
1479 ops->oobretlen = 0; 1474 ops->oobretlen = 0;
@@ -1486,13 +1481,13 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to,
1486 column = to & (mtd->oobsize - 1); 1481 column = to & (mtd->oobsize - 1);
1487 1482
1488 if (unlikely(column >= oobsize)) { 1483 if (unlikely(column >= oobsize)) {
1489 printk(KERN_ERR "onenand_write_oob: Attempted to start write outside oob\n"); 1484 printk(KERN_ERR "onenand_write_oob_nolock: Attempted to start write outside oob\n");
1490 return -EINVAL; 1485 return -EINVAL;
1491 } 1486 }
1492 1487
1493 /* For compatibility with NAND: Do not allow write past end of page */ 1488 /* For compatibility with NAND: Do not allow write past end of page */
1494 if (unlikely(column + len > oobsize)) { 1489 if (unlikely(column + len > oobsize)) {
1495 printk(KERN_ERR "onenand_write_oob: " 1490 printk(KERN_ERR "onenand_write_oob_nolock: "
1496 "Attempt to write past end of page\n"); 1491 "Attempt to write past end of page\n");
1497 return -EINVAL; 1492 return -EINVAL;
1498 } 1493 }
@@ -1501,13 +1496,10 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to,
1501 if (unlikely(to >= mtd->size || 1496 if (unlikely(to >= mtd->size ||
1502 column + len > ((mtd->size >> this->page_shift) - 1497 column + len > ((mtd->size >> this->page_shift) -
1503 (to >> this->page_shift)) * oobsize)) { 1498 (to >> this->page_shift)) * oobsize)) {
1504 printk(KERN_ERR "onenand_write_oob: Attempted to write past end of device\n"); 1499 printk(KERN_ERR "onenand_write_oob_nolock: Attempted to write past end of device\n");
1505 return -EINVAL; 1500 return -EINVAL;
1506 } 1501 }
1507 1502
1508 /* Grab the lock and see if the device is available */
1509 onenand_get_device(mtd, FL_WRITING);
1510
1511 oobbuf = this->oob_buf; 1503 oobbuf = this->oob_buf;
1512 1504
1513 /* Loop until all data write */ 1505 /* Loop until all data write */
@@ -1537,13 +1529,13 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to,
1537 1529
1538 ret = this->wait(mtd, FL_WRITING); 1530 ret = this->wait(mtd, FL_WRITING);
1539 if (ret) { 1531 if (ret) {
1540 printk(KERN_ERR "onenand_write_oob: write failed %d\n", ret); 1532 printk(KERN_ERR "onenand_write_oob_nolock: write failed %d\n", ret);
1541 break; 1533 break;
1542 } 1534 }
1543 1535
1544 ret = onenand_verify_oob(mtd, oobbuf, to); 1536 ret = onenand_verify_oob(mtd, oobbuf, to);
1545 if (ret) { 1537 if (ret) {
1546 printk(KERN_ERR "onenand_write_oob: verify failed %d\n", ret); 1538 printk(KERN_ERR "onenand_write_oob_nolock: verify failed %d\n", ret);
1547 break; 1539 break;
1548 } 1540 }
1549 1541
@@ -1556,9 +1548,6 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to,
1556 column = 0; 1548 column = 0;
1557 } 1549 }
1558 1550
1559 /* Deselect and wake up anyone waiting on the device */
1560 onenand_release_device(mtd);
1561
1562 ops->oobretlen = written; 1551 ops->oobretlen = written;
1563 1552
1564 return ret; 1553 return ret;
@@ -1585,9 +1574,11 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
1585 }; 1574 };
1586 int ret; 1575 int ret;
1587 1576
1588 ret = onenand_write_ops(mtd, to, &ops); 1577 onenand_get_device(mtd, FL_WRITING);
1589 *retlen = ops.retlen; 1578 ret = onenand_write_ops_nolock(mtd, to, &ops);
1579 onenand_release_device(mtd);
1590 1580
1581 *retlen = ops.retlen;
1591 return ret; 1582 return ret;
1592} 1583}
1593 1584
@@ -1600,6 +1591,8 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
1600static int onenand_write_oob(struct mtd_info *mtd, loff_t to, 1591static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
1601 struct mtd_oob_ops *ops) 1592 struct mtd_oob_ops *ops)
1602{ 1593{
1594 int ret;
1595
1603 switch (ops->mode) { 1596 switch (ops->mode) {
1604 case MTD_OOB_PLACE: 1597 case MTD_OOB_PLACE:
1605 case MTD_OOB_AUTO: 1598 case MTD_OOB_AUTO:
@@ -1610,23 +1603,26 @@ static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
1610 return -EINVAL; 1603 return -EINVAL;
1611 } 1604 }
1612 1605
1606 onenand_get_device(mtd, FL_WRITING);
1613 if (ops->datbuf) 1607 if (ops->datbuf)
1614 return onenand_write_ops(mtd, to, ops); 1608 ret = onenand_write_ops_nolock(mtd, to, ops);
1609 else
1610 ret = onenand_write_oob_nolock(mtd, to, ops);
1611 onenand_release_device(mtd);
1615 1612
1616 return onenand_do_write_oob(mtd, to, ops); 1613 return ret;
1617} 1614}
1618 1615
1619/** 1616/**
1620 * onenand_block_checkbad - [GENERIC] Check if a block is marked bad 1617 * onenand_block_isbad_nolock - [GENERIC] Check if a block is marked bad
1621 * @param mtd MTD device structure 1618 * @param mtd MTD device structure
1622 * @param ofs offset from device start 1619 * @param ofs offset from device start
1623 * @param getchip 0, if the chip is already selected
1624 * @param allowbbt 1, if its allowed to access the bbt area 1620 * @param allowbbt 1, if its allowed to access the bbt area
1625 * 1621 *
1626 * Check, if the block is bad. Either by reading the bad block table or 1622 * Check, if the block is bad. Either by reading the bad block table or
1627 * calling of the scan function. 1623 * calling of the scan function.
1628 */ 1624 */
1629static int onenand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt) 1625static int onenand_block_isbad_nolock(struct mtd_info *mtd, loff_t ofs, int allowbbt)
1630{ 1626{
1631 struct onenand_chip *this = mtd->priv; 1627 struct onenand_chip *this = mtd->priv;
1632 struct bbm_info *bbm = this->bbm; 1628 struct bbm_info *bbm = this->bbm;
@@ -1687,7 +1683,7 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1687 cond_resched(); 1683 cond_resched();
1688 1684
1689 /* Check if we have a bad block, we do not erase bad blocks */ 1685 /* Check if we have a bad block, we do not erase bad blocks */
1690 if (onenand_block_checkbad(mtd, addr, 0, 0)) { 1686 if (onenand_block_isbad_nolock(mtd, addr, 0)) {
1691 printk (KERN_WARNING "onenand_erase: attempt to erase a bad block at addr 0x%08x\n", (unsigned int) addr); 1687 printk (KERN_WARNING "onenand_erase: attempt to erase a bad block at addr 0x%08x\n", (unsigned int) addr);
1692 instr->state = MTD_ERASE_FAILED; 1688 instr->state = MTD_ERASE_FAILED;
1693 goto erase_exit; 1689 goto erase_exit;
@@ -1751,11 +1747,16 @@ static void onenand_sync(struct mtd_info *mtd)
1751 */ 1747 */
1752static int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs) 1748static int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
1753{ 1749{
1750 int ret;
1751
1754 /* Check for invalid offset */ 1752 /* Check for invalid offset */
1755 if (ofs > mtd->size) 1753 if (ofs > mtd->size)
1756 return -EINVAL; 1754 return -EINVAL;
1757 1755
1758 return onenand_block_checkbad(mtd, ofs, 1, 0); 1756 onenand_get_device(mtd, FL_READING);
1757 ret = onenand_block_isbad_nolock(mtd, ofs, 0);
1758 onenand_release_device(mtd);
1759 return ret;
1759} 1760}
1760 1761
1761/** 1762/**
@@ -1786,7 +1787,7 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
1786 1787
1787 /* We write two bytes, so we dont have to mess with 16 bit access */ 1788 /* We write two bytes, so we dont have to mess with 16 bit access */
1788 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01); 1789 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
1789 return onenand_do_write_oob(mtd, ofs, &ops); 1790 return onenand_write_oob_nolock(mtd, ofs, &ops);
1790} 1791}
1791 1792
1792/** 1793/**
@@ -1809,7 +1810,10 @@ static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
1809 return ret; 1810 return ret;
1810 } 1811 }
1811 1812
1812 return this->block_markbad(mtd, ofs); 1813 onenand_get_device(mtd, FL_WRITING);
1814 ret = this->block_markbad(mtd, ofs);
1815 onenand_release_device(mtd);
1816 return ret;
1813} 1817}
1814 1818
1815/** 1819/**
@@ -2008,13 +2012,19 @@ static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len,
2008 size_t *retlen, u_char *buf) 2012 size_t *retlen, u_char *buf)
2009{ 2013{
2010 struct onenand_chip *this = mtd->priv; 2014 struct onenand_chip *this = mtd->priv;
2015 struct mtd_oob_ops ops = {
2016 .len = len,
2017 .ooblen = 0,
2018 .datbuf = buf,
2019 .oobbuf = NULL,
2020 };
2011 int ret; 2021 int ret;
2012 2022
2013 /* Enter OTP access mode */ 2023 /* Enter OTP access mode */
2014 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); 2024 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
2015 this->wait(mtd, FL_OTPING); 2025 this->wait(mtd, FL_OTPING);
2016 2026
2017 ret = mtd->read(mtd, from, len, retlen, buf); 2027 ret = onenand_read_ops_nolock(mtd, from, &ops);
2018 2028
2019 /* Exit OTP access mode */ 2029 /* Exit OTP access mode */
2020 this->command(mtd, ONENAND_CMD_RESET, 0, 0); 2030 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
@@ -2026,19 +2036,20 @@ static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len,
2026/** 2036/**
2027 * do_otp_write - [DEFAULT] Write OTP block area 2037 * do_otp_write - [DEFAULT] Write OTP block area
2028 * @param mtd MTD device structure 2038 * @param mtd MTD device structure
2029 * @param from The offset to write 2039 * @param to The offset to write
2030 * @param len number of bytes to write 2040 * @param len number of bytes to write
2031 * @param retlen pointer to variable to store the number of write bytes 2041 * @param retlen pointer to variable to store the number of write bytes
2032 * @param buf the databuffer to put/get data 2042 * @param buf the databuffer to put/get data
2033 * 2043 *
2034 * Write OTP block area. 2044 * Write OTP block area.
2035 */ 2045 */
2036static int do_otp_write(struct mtd_info *mtd, loff_t from, size_t len, 2046static int do_otp_write(struct mtd_info *mtd, loff_t to, size_t len,
2037 size_t *retlen, u_char *buf) 2047 size_t *retlen, u_char *buf)
2038{ 2048{
2039 struct onenand_chip *this = mtd->priv; 2049 struct onenand_chip *this = mtd->priv;
2040 unsigned char *pbuf = buf; 2050 unsigned char *pbuf = buf;
2041 int ret; 2051 int ret;
2052 struct mtd_oob_ops ops;
2042 2053
2043 /* Force buffer page aligned */ 2054 /* Force buffer page aligned */
2044 if (len < mtd->writesize) { 2055 if (len < mtd->writesize) {
@@ -2052,7 +2063,12 @@ static int do_otp_write(struct mtd_info *mtd, loff_t from, size_t len,
2052 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); 2063 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
2053 this->wait(mtd, FL_OTPING); 2064 this->wait(mtd, FL_OTPING);
2054 2065
2055 ret = mtd->write(mtd, from, len, retlen, pbuf); 2066 ops.len = len;
2067 ops.ooblen = 0;
2068 ops.databuf = pbuf;
2069 ops.oobbuf = NULL;
2070 ret = onenand_write_ops_nolock(mtd, to, &ops);
2071 *retlen = ops.retlen;
2056 2072
2057 /* Exit OTP access mode */ 2073 /* Exit OTP access mode */
2058 this->command(mtd, ONENAND_CMD_RESET, 0, 0); 2074 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
@@ -2087,7 +2103,7 @@ static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len,
2087 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); 2103 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
2088 this->wait(mtd, FL_OTPING); 2104 this->wait(mtd, FL_OTPING);
2089 2105
2090 ret = onenand_do_write_oob(mtd, from, &ops); 2106 ret = onenand_write_oob_nolock(mtd, from, &ops);
2091 2107
2092 *retlen = ops.oobretlen; 2108 *retlen = ops.oobretlen;
2093 2109
@@ -2136,13 +2152,16 @@ static int onenand_otp_walk(struct mtd_info *mtd, loff_t from, size_t len,
2136 if (((mtd->writesize * otp_pages) - (from + len)) < 0) 2152 if (((mtd->writesize * otp_pages) - (from + len)) < 0)
2137 return 0; 2153 return 0;
2138 2154
2155 onenand_get_device(mtd, FL_OTPING);
2139 while (len > 0 && otp_pages > 0) { 2156 while (len > 0 && otp_pages > 0) {
2140 if (!action) { /* OTP Info functions */ 2157 if (!action) { /* OTP Info functions */
2141 struct otp_info *otpinfo; 2158 struct otp_info *otpinfo;
2142 2159
2143 len -= sizeof(struct otp_info); 2160 len -= sizeof(struct otp_info);
2144 if (len <= 0) 2161 if (len <= 0) {
2145 return -ENOSPC; 2162 ret = -ENOSPC;
2163 break;
2164 }
2146 2165
2147 otpinfo = (struct otp_info *) buf; 2166 otpinfo = (struct otp_info *) buf;
2148 otpinfo->start = from; 2167 otpinfo->start = from;
@@ -2162,13 +2181,14 @@ static int onenand_otp_walk(struct mtd_info *mtd, loff_t from, size_t len,
2162 len -= size; 2181 len -= size;
2163 *retlen += size; 2182 *retlen += size;
2164 2183
2165 if (ret < 0) 2184 if (ret)
2166 return ret; 2185 break;
2167 } 2186 }
2168 otp_pages--; 2187 otp_pages--;
2169 } 2188 }
2189 onenand_release_device(mtd);
2170 2190
2171 return 0; 2191 return ret;
2172} 2192}
2173 2193
2174/** 2194/**
@@ -2364,7 +2384,7 @@ static void onenand_print_device_info(int device, int version)
2364 (16 << density), 2384 (16 << density),
2365 vcc ? "2.65/3.3" : "1.8", 2385 vcc ? "2.65/3.3" : "1.8",
2366 device); 2386 device);
2367 printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version); 2387 printk(KERN_INFO "OneNAND version = 0x%04x\n", version);
2368} 2388}
2369 2389
2370static const struct onenand_manufacturers onenand_manuf_ids[] = { 2390static const struct onenand_manufacturers onenand_manuf_ids[] = {