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

Commit fdbad98d authored by Josh Wu's avatar Josh Wu Committed by David Woodhouse
Browse files

mtd: nand: teach write_page and write_page_raw return an error code



There is an implemention of hardware ECC write page function which may return an
error indication.
For instance, using Atmel HW PMECC to write one page into a nand flash, the hardware
engine will compute the BCH ecc code for this page. so we need read a the
status register to theck whether the ecc code is generated.
But we cannot assume the status register always can be ready, for example,
incorrect hardware configuration or hardware issue, in such case we need
write_page() to return a error code.

Since the definition of 'write_page' function in struct nand_ecc_ctrl is 'void'.
So this patch will:
  1. add return 'int' value for 'write_page' function.
  2. to be consitent, add return 'int' value for 'write_page_raw' fuctions too.
  3. add code to test the return value, and if negative, indicate an
  error happend when write page with ECC.
  4. fix the compile warning in all impacted nand flash driver.

Note: I couldn't compile-test all of these easily, as some had ARCH dependencies.

Signed-off-by: default avatarJosh Wu <josh.wu@atmel.com>
Signed-off-by: default avatarArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 3dfe41a4
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@
/* ---- Private Function Prototypes -------------------------------------- */
static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
	struct nand_chip *chip, uint8_t *buf, int oob_required, int page);
static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd,
static int bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd,
	struct nand_chip *chip, const uint8_t *buf, int oob_required);

/* ---- Private Variables ------------------------------------------------ */
@@ -194,7 +194,7 @@ static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
*  @oob_required:	must write chip->oob_poi to OOB
*
***************************************************************************/
static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd,
static int bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd,
	struct nand_chip *chip, const uint8_t *buf, int oob_required)
{
	int sectorIdx = 0;
@@ -214,4 +214,6 @@ static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd,
	}

	bcm_umi_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize);

	return 0;
}
+4 −2
Original line number Diff line number Diff line
@@ -566,11 +566,13 @@ static int bf5xx_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip
	return 0;
}

static void bf5xx_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
		const uint8_t *buf, int oob_required)
static int bf5xx_nand_write_page_raw(struct mtd_info *mtd,
		struct nand_chip *chip,	const uint8_t *buf, int oob_required)
{
	bf5xx_nand_write_buf(mtd, buf, mtd->writesize);
	bf5xx_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize);

	return 0;
}

/*
+8 −3
Original line number Diff line number Diff line
@@ -520,7 +520,7 @@ static struct nand_bbt_descr cafe_bbt_mirror_descr_512 = {
};


static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd,
static int cafe_nand_write_page_lowlevel(struct mtd_info *mtd,
					  struct nand_chip *chip,
					  const uint8_t *buf, int oob_required)
{
@@ -531,6 +531,8 @@ static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd,

	/* Set up ECC autogeneration */
	cafe->ctl2 |= (1<<30);

	return 0;
}

static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
@@ -542,9 +544,12 @@ static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
	chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);

	if (unlikely(raw))
		chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
		status = chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
	else
		chip->ecc.write_page(mtd, chip, buf, oob_required);
		status = chip->ecc.write_page(mtd, chip, buf, oob_required);

	if (status < 0)
		return status;

	/*
	 * Cached progamming disabled for now, Not sure if its worth the
+7 −5
Original line number Diff line number Diff line
@@ -1028,7 +1028,7 @@ static void denali_setup_dma(struct denali_nand_info *denali, int op)

/* writes a page. user specifies type, and this function handles the
 * configuration details. */
static void write_page(struct mtd_info *mtd, struct nand_chip *chip,
static int write_page(struct mtd_info *mtd, struct nand_chip *chip,
			const uint8_t *buf, bool raw_xfer)
{
	struct denali_nand_info *denali = mtd_to_denali(mtd);
@@ -1078,6 +1078,8 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip,

	denali_enable_dma(denali, false);
	dma_sync_single_for_cpu(denali->dev, addr, size, DMA_TO_DEVICE);

	return 0;
}

/* NAND core entry points */
@@ -1086,24 +1088,24 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip,
 * writing a page with ECC or without is similar, all the work is done
 * by write_page above.
 * */
static void denali_write_page(struct mtd_info *mtd, struct nand_chip *chip,
static int denali_write_page(struct mtd_info *mtd, struct nand_chip *chip,
				const uint8_t *buf, int oob_required)
{
	/* for regular page writes, we let HW handle all the ECC
	 * data written to the device. */
	write_page(mtd, chip, buf, false);
	return write_page(mtd, chip, buf, false);
}

/* This is the callback that the NAND core calls to write a page without ECC.
 * raw access is similar to ECC page writes, so all the work is done in the
 * write_page() function above.
 */
static void denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
static int denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
					const uint8_t *buf, int oob_required)
{
	/* for raw page writes, we want to disable ECC and simply write
	   whatever data is in the buffer. */
	write_page(mtd, chip, buf, true);
	return write_page(mtd, chip, buf, true);
}

static int denali_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
+5 −3
Original line number Diff line number Diff line
@@ -898,7 +898,7 @@ static void docg4_erase_block(struct mtd_info *mtd, int page)
	write_nop(docptr);
}

static void write_page(struct mtd_info *mtd, struct nand_chip *nand,
static int write_page(struct mtd_info *mtd, struct nand_chip *nand,
		       const uint8_t *buf, bool use_ecc)
{
	struct docg4_priv *doc = nand->priv;
@@ -950,15 +950,17 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *nand,
	write_nop(docptr);
	writew(0, docptr + DOC_DATAEND);
	write_nop(docptr);

	return 0;
}

static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
static int docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
				 const uint8_t *buf, int oob_required)
{
	return write_page(mtd, nand, buf, false);
}

static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
static int docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
			     const uint8_t *buf, int oob_required)
{
	return write_page(mtd, nand, buf, true);
Loading