aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/onenand
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/onenand')
-rw-r--r--drivers/mtd/onenand/onenand_base.c51
1 files changed, 36 insertions, 15 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 7d194cfdb873..45bc1433b28d 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -921,17 +921,22 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int col
921 * 921 *
922 * OneNAND read out-of-band data from the spare area 922 * OneNAND read out-of-band data from the spare area
923 */ 923 */
924static int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len, 924static int onenand_do_read_oob(struct mtd_info *mtd, loff_t from,
925 size_t *retlen, u_char *buf, mtd_oob_mode_t mode) 925 struct mtd_oob_ops *ops)
926{ 926{
927 struct onenand_chip *this = mtd->priv; 927 struct onenand_chip *this = mtd->priv;
928 int read = 0, thislen, column, oobsize; 928 int read = 0, thislen, column, oobsize;
929 size_t len = ops->ooblen;
930 mtd_oob_mode_t mode = ops->mode;
931 u_char *buf = ops->oobbuf;
929 int ret = 0; 932 int ret = 0;
930 933
934 from += ops->ooboffs;
935
931 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); 936 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
932 937
933 /* Initialize return length value */ 938 /* Initialize return length value */
934 *retlen = 0; 939 ops->oobretlen = 0;
935 940
936 if (mode == MTD_OOB_AUTO) 941 if (mode == MTD_OOB_AUTO)
937 oobsize = this->ecclayout->oobavail; 942 oobsize = this->ecclayout->oobavail;
@@ -997,7 +1002,7 @@ static int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
997 /* Deselect and wake up anyone waiting on the device */ 1002 /* Deselect and wake up anyone waiting on the device */
998 onenand_release_device(mtd); 1003 onenand_release_device(mtd);
999 1004
1000 *retlen = read; 1005 ops->oobretlen = read;
1001 return ret; 1006 return ret;
1002} 1007}
1003 1008
@@ -1019,8 +1024,7 @@ static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
1019 default: 1024 default:
1020 return -EINVAL; 1025 return -EINVAL;
1021 } 1026 }
1022 return onenand_do_read_oob(mtd, from + ops->ooboffs, ops->ooblen, 1027 return onenand_do_read_oob(mtd, from, ops);
1023 &ops->oobretlen, ops->oobbuf, ops->mode);
1024} 1028}
1025 1029
1026/** 1030/**
@@ -1370,18 +1374,23 @@ static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
1370 * 1374 *
1371 * OneNAND write out-of-band 1375 * OneNAND write out-of-band
1372 */ 1376 */
1373static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len, 1377static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to,
1374 size_t *retlen, const u_char *buf, mtd_oob_mode_t mode) 1378 struct mtd_oob_ops *ops)
1375{ 1379{
1376 struct onenand_chip *this = mtd->priv; 1380 struct onenand_chip *this = mtd->priv;
1377 int column, ret = 0, oobsize; 1381 int column, ret = 0, oobsize;
1378 int written = 0; 1382 int written = 0;
1379 u_char *oobbuf; 1383 u_char *oobbuf;
1384 size_t len = ops->ooblen;
1385 const u_char *buf = ops->oobbuf;
1386 mtd_oob_mode_t mode = ops->mode;
1387
1388 to += ops->ooboffs;
1380 1389
1381 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); 1390 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
1382 1391
1383 /* Initialize retlen, in case of early exit */ 1392 /* Initialize retlen, in case of early exit */
1384 *retlen = 0; 1393 ops->oobretlen = 0;
1385 1394
1386 if (mode == MTD_OOB_AUTO) 1395 if (mode == MTD_OOB_AUTO)
1387 oobsize = this->ecclayout->oobavail; 1396 oobsize = this->ecclayout->oobavail;
@@ -1464,7 +1473,7 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1464 /* Deselect and wake up anyone waiting on the device */ 1473 /* Deselect and wake up anyone waiting on the device */
1465 onenand_release_device(mtd); 1474 onenand_release_device(mtd);
1466 1475
1467 *retlen = written; 1476 ops->oobretlen = written;
1468 1477
1469 return ret; 1478 return ret;
1470} 1479}
@@ -1487,8 +1496,7 @@ static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
1487 default: 1496 default:
1488 return -EINVAL; 1497 return -EINVAL;
1489 } 1498 }
1490 return onenand_do_write_oob(mtd, to + ops->ooboffs, ops->ooblen, 1499 return onenand_do_write_oob(mtd, to, ops);
1491 &ops->oobretlen, ops->oobbuf, ops->mode);
1492} 1500}
1493 1501
1494/** 1502/**
@@ -1646,7 +1654,12 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
1646 struct onenand_chip *this = mtd->priv; 1654 struct onenand_chip *this = mtd->priv;
1647 struct bbm_info *bbm = this->bbm; 1655 struct bbm_info *bbm = this->bbm;
1648 u_char buf[2] = {0, 0}; 1656 u_char buf[2] = {0, 0};
1649 size_t retlen; 1657 struct mtd_oob_ops ops = {
1658 .mode = MTD_OOB_PLACE,
1659 .ooblen = 2,
1660 .oobbuf = buf,
1661 .ooboffs = 0,
1662 };
1650 int block; 1663 int block;
1651 1664
1652 /* Get block number */ 1665 /* Get block number */
@@ -1656,7 +1669,7 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
1656 1669
1657 /* We write two bytes, so we dont have to mess with 16 bit access */ 1670 /* We write two bytes, so we dont have to mess with 16 bit access */
1658 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01); 1671 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
1659 return onenand_do_write_oob(mtd, ofs , 2, &retlen, buf, MTD_OOB_PLACE); 1672 return onenand_do_write_oob(mtd, ofs, &ops);
1660} 1673}
1661 1674
1662/** 1675/**
@@ -1945,13 +1958,21 @@ static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len,
1945 size_t *retlen, u_char *buf) 1958 size_t *retlen, u_char *buf)
1946{ 1959{
1947 struct onenand_chip *this = mtd->priv; 1960 struct onenand_chip *this = mtd->priv;
1961 struct mtd_oob_ops ops = {
1962 .mode = MTD_OOB_PLACE,
1963 .ooblen = len,
1964 .oobbuf = buf,
1965 .ooboffs = 0,
1966 };
1948 int ret; 1967 int ret;
1949 1968
1950 /* Enter OTP access mode */ 1969 /* Enter OTP access mode */
1951 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); 1970 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
1952 this->wait(mtd, FL_OTPING); 1971 this->wait(mtd, FL_OTPING);
1953 1972
1954 ret = onenand_do_write_oob(mtd, from, len, retlen, buf, MTD_OOB_PLACE); 1973 ret = onenand_do_write_oob(mtd, from, &ops);
1974
1975 *retlen = ops.oobretlen;
1955 1976
1956 /* Exit OTP access mode */ 1977 /* Exit OTP access mode */
1957 this->command(mtd, ONENAND_CMD_RESET, 0, 0); 1978 this->command(mtd, ONENAND_CMD_RESET, 0, 0);