diff options
Diffstat (limited to 'drivers/mtd/nand/nand_micron.c')
| -rw-r--r-- | drivers/mtd/nand/nand_micron.c | 83 | 
1 files changed, 32 insertions, 51 deletions
diff --git a/drivers/mtd/nand/nand_micron.c b/drivers/mtd/nand/nand_micron.c index abf6a3c376e8..02e109ae73f1 100644 --- a/drivers/mtd/nand/nand_micron.c +++ b/drivers/mtd/nand/nand_micron.c @@ -117,16 +117,28 @@ micron_nand_read_page_on_die_ecc(struct mtd_info *mtd, struct nand_chip *chip,  				 uint8_t *buf, int oob_required,  				 int page)  { -	int status; -	int max_bitflips = 0; +	u8 status; +	int ret, max_bitflips = 0; -	micron_nand_on_die_ecc_setup(chip, true); +	ret = micron_nand_on_die_ecc_setup(chip, true); +	if (ret) +		return ret; + +	ret = nand_read_page_op(chip, page, 0, NULL, 0); +	if (ret) +		goto out; + +	ret = nand_status_op(chip, &status); +	if (ret) +		goto out; + +	ret = nand_exit_status_op(chip); +	if (ret) +		goto out; -	chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); -	chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); -	status = chip->read_byte(mtd);  	if (status & NAND_STATUS_FAIL)  		mtd->ecc_stats.failed++; +  	/*  	 * The internal ECC doesn't tell us the number of bitflips  	 * that have been corrected, but tells us if it recommends to @@ -137,13 +149,15 @@ micron_nand_read_page_on_die_ecc(struct mtd_info *mtd, struct nand_chip *chip,  	else if (status & NAND_STATUS_WRITE_RECOMMENDED)  		max_bitflips = chip->ecc.strength; -	chip->cmdfunc(mtd, NAND_CMD_READ0, -1, -1); - -	nand_read_page_raw(mtd, chip, buf, oob_required, page); +	ret = nand_read_data_op(chip, buf, mtd->writesize, false); +	if (!ret && oob_required) +		ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize, +					false); +out:  	micron_nand_on_die_ecc_setup(chip, false); -	return max_bitflips; +	return ret ? ret : max_bitflips;  }  static int @@ -151,46 +165,16 @@ micron_nand_write_page_on_die_ecc(struct mtd_info *mtd, struct nand_chip *chip,  				  const uint8_t *buf, int oob_required,  				  int page)  { -	int status; - -	micron_nand_on_die_ecc_setup(chip, true); +	int ret; -	chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); -	nand_write_page_raw(mtd, chip, buf, oob_required, page); -	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); -	status = chip->waitfunc(mtd, chip); +	ret = micron_nand_on_die_ecc_setup(chip, true); +	if (ret) +		return ret; +	ret = nand_write_page_raw(mtd, chip, buf, oob_required, page);  	micron_nand_on_die_ecc_setup(chip, false); -	return status & NAND_STATUS_FAIL ? -EIO : 0; -} - -static int -micron_nand_read_page_raw_on_die_ecc(struct mtd_info *mtd, -				     struct nand_chip *chip, -				     uint8_t *buf, int oob_required, -				     int page) -{ -	chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); -	nand_read_page_raw(mtd, chip, buf, oob_required, page); - -	return 0; -} - -static int -micron_nand_write_page_raw_on_die_ecc(struct mtd_info *mtd, -				      struct nand_chip *chip, -				      const uint8_t *buf, int oob_required, -				      int page) -{ -	int status; - -	chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); -	nand_write_page_raw(mtd, chip, buf, oob_required, page); -	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); -	status = chip->waitfunc(mtd, chip); - -	return status & NAND_STATUS_FAIL ? -EIO : 0; +	return ret;  }  enum { @@ -285,17 +269,14 @@ static int micron_nand_init(struct nand_chip *chip)  			return -EINVAL;  		} -		chip->ecc.options = NAND_ECC_CUSTOM_PAGE_ACCESS;  		chip->ecc.bytes = 8;  		chip->ecc.size = 512;  		chip->ecc.strength = 4;  		chip->ecc.algo = NAND_ECC_BCH;  		chip->ecc.read_page = micron_nand_read_page_on_die_ecc;  		chip->ecc.write_page = micron_nand_write_page_on_die_ecc; -		chip->ecc.read_page_raw = -			micron_nand_read_page_raw_on_die_ecc; -		chip->ecc.write_page_raw = -			micron_nand_write_page_raw_on_die_ecc; +		chip->ecc.read_page_raw = nand_read_page_raw; +		chip->ecc.write_page_raw = nand_write_page_raw;  		mtd_set_ooblayout(mtd, µn_nand_on_die_ooblayout_ops);  	}  | 
