Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 97d90da8 authored by Boris Brezillon's avatar Boris Brezillon
Browse files

mtd: nand: provide several helpers to do common NAND operations



This is part of the process of removing direct calls to ->cmdfunc()
outside of the core in order to introduce a better interface to execute
NAND operations.

Here we provide several helpers and make use of them to remove all
direct calls to ->cmdfunc(). This way, we can easily modify those
helpers to make use of the new ->exec_op() interface when available.

Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
[miquel.raynal@free-electrons.com: rebased and fixed some conflicts]
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@free-electrons.com>
Acked-by: default avatarMasahiro Yamada <yamada.masahiro@socionext.com>
parent eb94555e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1000,7 +1000,7 @@ static int atmel_hsmc_nand_pmecc_read_pg(struct nand_chip *chip, u8 *buf,
	 * to the non-optimized one.
	 */
	if (nand->activecs->rb.type != ATMEL_NAND_NATIVE_RB) {
		chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
		nand_read_page_op(chip, page, 0, NULL, 0);

		return atmel_nand_pmecc_read_pg(chip, buf, oob_required, page,
						raw);
+4 −5
Original line number Diff line number Diff line
@@ -1071,7 +1071,7 @@ static void brcmnand_wp(struct mtd_info *mtd, int wp)
			return;

		brcmnand_set_wp(ctrl, wp);
		chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
		nand_status_op(chip, NULL);
		/* NAND_STATUS_WP 0x00 = protected, 0x80 = not protected */
		ret = bcmnand_ctrl_poll_status(ctrl,
					       NAND_CTRL_RDY |
@@ -1453,7 +1453,7 @@ static uint8_t brcmnand_read_byte(struct mtd_info *mtd)

		/* At FC_BYTES boundary, switch to next column */
		if (host->last_byte > 0 && offs == 0)
			chip->cmdfunc(mtd, NAND_CMD_RNDOUT, addr, -1);
			nand_change_read_column_op(chip, addr, NULL, 0, false);

		ret = ctrl->flash_cache[offs];
		break;
@@ -1689,7 +1689,7 @@ static int brcmstb_nand_verify_erased_page(struct mtd_info *mtd,
	sas = mtd->oobsize / chip->ecc.steps;

	/* read without ecc for verification */
	chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
	nand_read_page_op(chip, page, 0, NULL, 0);
	ret = chip->ecc.read_page_raw(mtd, chip, buf, true, page);
	if (ret)
		return ret;
@@ -2369,12 +2369,11 @@ static int brcmnand_resume(struct device *dev)

	list_for_each_entry(host, &ctrl->host_list, node) {
		struct nand_chip *chip = &host->chip;
		struct mtd_info *mtd = nand_to_mtd(chip);

		brcmnand_save_restore_cs_config(host, 1);

		/* Reset the chip, required by some chips after power-up */
		chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
		nand_reset_op(chip);
	}

	return 0;
+3 −11
Original line number Diff line number Diff line
@@ -353,23 +353,15 @@ static void cafe_nand_bug(struct mtd_info *mtd)
static int cafe_nand_write_oob(struct mtd_info *mtd,
			       struct nand_chip *chip, int page)
{
	int status = 0;

	chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
	status = chip->waitfunc(mtd, chip);

	return status & NAND_STATUS_FAIL ? -EIO : 0;
	return nand_prog_page_op(chip, page, mtd->writesize, chip->oob_poi,
				 mtd->oobsize);
}

/* Don't use -- use nand_read_oob_std for now */
static int cafe_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
			      int page)
{
	chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
	return 0;
	return nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
}
/**
 * cafe_nand_read_page_syndrome - [REPLACEABLE] hardware ecc syndrome based page read
+18 −19
Original line number Diff line number Diff line
@@ -645,8 +645,6 @@ static void denali_oob_xfer(struct mtd_info *mtd, struct nand_chip *chip,
			    int page, int write)
{
	struct denali_nand_info *denali = mtd_to_denali(mtd);
	unsigned int start_cmd = write ? NAND_CMD_SEQIN : NAND_CMD_READ0;
	unsigned int rnd_cmd = write ? NAND_CMD_RNDIN : NAND_CMD_RNDOUT;
	int writesize = mtd->writesize;
	int oobsize = mtd->oobsize;
	uint8_t *bufpoi = chip->oob_poi;
@@ -658,11 +656,11 @@ static void denali_oob_xfer(struct mtd_info *mtd, struct nand_chip *chip,
	int i, pos, len;

	/* BBM at the beginning of the OOB area */
	chip->cmdfunc(mtd, start_cmd, writesize, page);
	if (write)
		chip->write_buf(mtd, bufpoi, oob_skip);
		nand_prog_page_begin_op(chip, page, writesize, bufpoi,
					oob_skip);
	else
		chip->read_buf(mtd, bufpoi, oob_skip);
		nand_read_page_op(chip, page, writesize, bufpoi, oob_skip);
	bufpoi += oob_skip;

	/* OOB ECC */
@@ -675,30 +673,35 @@ static void denali_oob_xfer(struct mtd_info *mtd, struct nand_chip *chip,
		else if (pos + len > writesize)
			len = writesize - pos;

		chip->cmdfunc(mtd, rnd_cmd, pos, -1);
		if (write)
			chip->write_buf(mtd, bufpoi, len);
			nand_change_write_column_op(chip, pos, bufpoi, len,
						    false);
		else
			chip->read_buf(mtd, bufpoi, len);
			nand_change_read_column_op(chip, pos, bufpoi, len,
						   false);
		bufpoi += len;
		if (len < ecc_bytes) {
			len = ecc_bytes - len;
			chip->cmdfunc(mtd, rnd_cmd, writesize + oob_skip, -1);
			if (write)
				chip->write_buf(mtd, bufpoi, len);
				nand_change_write_column_op(chip, writesize +
							    oob_skip, bufpoi,
							    len, false);
			else
				chip->read_buf(mtd, bufpoi, len);
				nand_change_read_column_op(chip, writesize +
							   oob_skip, bufpoi,
							   len, false);
			bufpoi += len;
		}
	}

	/* OOB free */
	len = oobsize - (bufpoi - chip->oob_poi);
	chip->cmdfunc(mtd, rnd_cmd, size - len, -1);
	if (write)
		chip->write_buf(mtd, bufpoi, len);
		nand_change_write_column_op(chip, size - len, bufpoi, len,
					    false);
	else
		chip->read_buf(mtd, bufpoi, len);
		nand_change_read_column_op(chip, size - len, bufpoi, len,
					   false);
}

static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
@@ -788,16 +791,12 @@ static int denali_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
			    int page)
{
	struct denali_nand_info *denali = mtd_to_denali(mtd);
	int status;

	denali_reset_irq(denali);

	denali_oob_xfer(mtd, chip, page, 1);

	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
	status = chip->waitfunc(mtd, chip);

	return status & NAND_STATUS_FAIL ? -EIO : 0;
	return nand_prog_page_end_op(chip);
}

static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
+2 −2
Original line number Diff line number Diff line
@@ -448,7 +448,7 @@ static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this)
	int status;

	DoC_WaitReady(doc);
	this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
	nand_status_op(this, NULL);
	DoC_WaitReady(doc);
	status = (int)this->read_byte(mtd);

@@ -595,7 +595,7 @@ static void doc2001plus_select_chip(struct mtd_info *mtd, int chip)

	/* Assert ChipEnable and deassert WriteProtect */
	WriteDOC((DOC_FLASH_CE), docptr, Mplus_FlashSelect);
	this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
	nand_reset_op(this);

	doc->curchip = chip;
	doc->curfloor = floor;
Loading