aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/nand/nand_base.c56
-rw-r--r--include/linux/mtd/nand.h6
2 files changed, 58 insertions, 4 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 94fe4f5dad3b..052e3ad82687 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1410,6 +1410,30 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
1410} 1410}
1411 1411
1412/** 1412/**
1413 * nand_setup_read_retry - [INTERN] Set the READ RETRY mode
1414 * @mtd: MTD device structure
1415 * @retry_mode: the retry mode to use
1416 *
1417 * Some vendors supply a special command to shift the Vt threshold, to be used
1418 * when there are too many bitflips in a page (i.e., ECC error). After setting
1419 * a new threshold, the host should retry reading the page.
1420 */
1421static int nand_setup_read_retry(struct mtd_info *mtd, int retry_mode)
1422{
1423 struct nand_chip *chip = mtd->priv;
1424
1425 pr_debug("setting READ RETRY mode %d\n", retry_mode);
1426
1427 if (retry_mode >= chip->read_retries)
1428 return -EINVAL;
1429
1430 if (!chip->setup_read_retry)
1431 return -EOPNOTSUPP;
1432
1433 return chip->setup_read_retry(mtd, retry_mode);
1434}
1435
1436/**
1413 * nand_do_read_ops - [INTERN] Read data with ECC 1437 * nand_do_read_ops - [INTERN] Read data with ECC
1414 * @mtd: MTD device structure 1438 * @mtd: MTD device structure
1415 * @from: offset to read from 1439 * @from: offset to read from
@@ -1430,6 +1454,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1430 1454
1431 uint8_t *bufpoi, *oob, *buf; 1455 uint8_t *bufpoi, *oob, *buf;
1432 unsigned int max_bitflips = 0; 1456 unsigned int max_bitflips = 0;
1457 int retry_mode = 0;
1433 bool ecc_fail = false; 1458 bool ecc_fail = false;
1434 1459
1435 chipnr = (int)(from >> chip->chip_shift); 1460 chipnr = (int)(from >> chip->chip_shift);
@@ -1454,6 +1479,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1454 if (realpage != chip->pagebuf || oob) { 1479 if (realpage != chip->pagebuf || oob) {
1455 bufpoi = aligned ? buf : chip->buffers->databuf; 1480 bufpoi = aligned ? buf : chip->buffers->databuf;
1456 1481
1482read_retry:
1457 chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); 1483 chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
1458 1484
1459 /* 1485 /*
@@ -1494,8 +1520,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1494 memcpy(buf, chip->buffers->databuf + col, bytes); 1520 memcpy(buf, chip->buffers->databuf + col, bytes);
1495 } 1521 }
1496 1522
1497 buf += bytes;
1498
1499 if (unlikely(oob)) { 1523 if (unlikely(oob)) {
1500 int toread = min(oobreadlen, max_oobsize); 1524 int toread = min(oobreadlen, max_oobsize);
1501 1525
@@ -1514,8 +1538,24 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1514 nand_wait_ready(mtd); 1538 nand_wait_ready(mtd);
1515 } 1539 }
1516 1540
1517 if (mtd->ecc_stats.failed - ecc_failures) 1541 if (mtd->ecc_stats.failed - ecc_failures) {
1518 ecc_fail = true; 1542 if (retry_mode + 1 <= chip->read_retries) {
1543 retry_mode++;
1544 ret = nand_setup_read_retry(mtd,
1545 retry_mode);
1546 if (ret < 0)
1547 break;
1548
1549 /* Reset failures; retry */
1550 mtd->ecc_stats.failed = ecc_failures;
1551 goto read_retry;
1552 } else {
1553 /* No more retry modes; real failure */
1554 ecc_fail = true;
1555 }
1556 }
1557
1558 buf += bytes;
1519 } else { 1559 } else {
1520 memcpy(buf, chip->buffers->databuf + col, bytes); 1560 memcpy(buf, chip->buffers->databuf + col, bytes);
1521 buf += bytes; 1561 buf += bytes;
@@ -1525,6 +1565,14 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1525 1565
1526 readlen -= bytes; 1566 readlen -= bytes;
1527 1567
1568 /* Reset to retry mode 0 */
1569 if (retry_mode) {
1570 ret = nand_setup_read_retry(mtd, 0);
1571 if (ret < 0)
1572 break;
1573 retry_mode = 0;
1574 }
1575
1528 if (!readlen) 1576 if (!readlen)
1529 break; 1577 break;
1530 1578
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 309009b7764b..7fd717010ee2 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -472,6 +472,8 @@ struct nand_buffers {
472 * commands to the chip. 472 * commands to the chip.
473 * @waitfunc: [REPLACEABLE] hardwarespecific function for wait on 473 * @waitfunc: [REPLACEABLE] hardwarespecific function for wait on
474 * ready. 474 * ready.
475 * @setup_read_retry: [FLASHSPECIFIC] flash (vendor) specific function for
476 * setting the read-retry mode. Mostly needed for MLC NAND.
475 * @ecc: [BOARDSPECIFIC] ECC control structure 477 * @ecc: [BOARDSPECIFIC] ECC control structure
476 * @buffers: buffer structure for read/write 478 * @buffers: buffer structure for read/write
477 * @hwcontrol: platform-specific hardware control structure 479 * @hwcontrol: platform-specific hardware control structure
@@ -518,6 +520,7 @@ struct nand_buffers {
518 * non 0 if ONFI supported. 520 * non 0 if ONFI supported.
519 * @onfi_params: [INTERN] holds the ONFI page parameter when ONFI is 521 * @onfi_params: [INTERN] holds the ONFI page parameter when ONFI is
520 * supported, 0 otherwise. 522 * supported, 0 otherwise.
523 * @read_retries: [INTERN] the number of read retry modes supported
521 * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand 524 * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
522 * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand 525 * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
523 * @bbt: [INTERN] bad block table pointer 526 * @bbt: [INTERN] bad block table pointer
@@ -565,6 +568,7 @@ struct nand_chip {
565 int feature_addr, uint8_t *subfeature_para); 568 int feature_addr, uint8_t *subfeature_para);
566 int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip, 569 int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip,
567 int feature_addr, uint8_t *subfeature_para); 570 int feature_addr, uint8_t *subfeature_para);
571 int (*setup_read_retry)(struct mtd_info *mtd, int retry_mode);
568 572
569 int chip_delay; 573 int chip_delay;
570 unsigned int options; 574 unsigned int options;
@@ -589,6 +593,8 @@ struct nand_chip {
589 int onfi_version; 593 int onfi_version;
590 struct nand_onfi_params onfi_params; 594 struct nand_onfi_params onfi_params;
591 595
596 int read_retries;
597
592 flstate_t state; 598 flstate_t state;
593 599
594 uint8_t *oob_poi; 600 uint8_t *oob_poi;