mtd: nand: add 'oob_required' argument to NAND {read,write}_page interfaces
New NAND controllers can perform read/write via HW engines which don't expose
OOB data in their DMA mode. To reflect this, we should rework the nand_chip /
nand_ecc_ctrl interfaces that assume that drivers will always read/write OOB
data in the nand_chip.oob_poi buffer. A better interface includes a boolean
argument that explicitly tells the callee when OOB data is requested by the
calling layer (for reading/writing to/from nand_chip.oob_poi).
This patch adds the 'oob_required' parameter to each relevant {read,write}_page
interface; all 'oob_required' parameters are left unused for now. The next
patch will set the parameter properly in the nand_base.c callers, and follow-up
patches will make use of 'oob_required' in some of the callee functions.
Note that currently, there is no harm in ignoring the 'oob_required' parameter
and *always* utilizing nand_chip.oob_poi, but there can be
performance/complexity/design benefits from avoiding filling oob_poi in the
common case. I will try to implement this for some drivers which can be ported
easily.
Note: I couldn't compile-test all of these easily, as some had ARCH
dependencies.
[dwmw2: Merge later 1/0 vs. true/false cleanup]
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Reviewed-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
Acked-by: Jiandong Zheng <jdzheng@broadcom.com>
Acked-by: Mike Dunn <mikedunn@newsguy.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
	
	
This commit is contained in:
		
					parent
					
						
							
								b4f7aa84d6
							
						
					
				
			
			
				commit
				
					
						1fbb938dff
					
				
			
		
					 15 changed files with 90 additions and 72 deletions
				
			
		| 
						 | 
					@ -324,9 +324,10 @@ static int atmel_nand_calculate(struct mtd_info *mtd,
 | 
				
			||||||
 * mtd:        mtd info structure
 | 
					 * mtd:        mtd info structure
 | 
				
			||||||
 * chip:       nand chip info structure
 | 
					 * chip:       nand chip info structure
 | 
				
			||||||
 * buf:        buffer to store read data
 | 
					 * buf:        buffer to store read data
 | 
				
			||||||
 | 
					 * oob_required:    caller expects OOB data read to chip->oob_poi
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int atmel_nand_read_page(struct mtd_info *mtd,
 | 
					static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
		struct nand_chip *chip, uint8_t *buf, int page)
 | 
									uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int eccsize = chip->ecc.size;
 | 
						int eccsize = chip->ecc.size;
 | 
				
			||||||
	int eccbytes = chip->ecc.bytes;
 | 
						int eccbytes = chip->ecc.bytes;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,9 +22,9 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ---- Private Function Prototypes -------------------------------------- */
 | 
					/* ---- Private Function Prototypes -------------------------------------- */
 | 
				
			||||||
static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
 | 
					static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
 | 
				
			||||||
	struct nand_chip *chip, uint8_t *buf, int page);
 | 
						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 void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd,
 | 
				
			||||||
	struct nand_chip *chip, const uint8_t *buf);
 | 
						struct nand_chip *chip, const uint8_t *buf, int oob_required);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ---- Private Variables ------------------------------------------------ */
 | 
					/* ---- Private Variables ------------------------------------------------ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -103,11 +103,12 @@ static struct nand_ecclayout nand_hw_eccoob_4096 = {
 | 
				
			||||||
*  @mtd:	mtd info structure
 | 
					*  @mtd:	mtd info structure
 | 
				
			||||||
*  @chip:	nand chip info structure
 | 
					*  @chip:	nand chip info structure
 | 
				
			||||||
*  @buf:	buffer to store read data
 | 
					*  @buf:	buffer to store read data
 | 
				
			||||||
 | 
					*  @oob_required:	caller expects OOB data read to chip->oob_poi
 | 
				
			||||||
*
 | 
					*
 | 
				
			||||||
***************************************************************************/
 | 
					***************************************************************************/
 | 
				
			||||||
static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
 | 
					static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
 | 
				
			||||||
				       struct nand_chip *chip, uint8_t * buf,
 | 
									       struct nand_chip *chip, uint8_t * buf,
 | 
				
			||||||
						 int page)
 | 
									       int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int sectorIdx = 0;
 | 
						int sectorIdx = 0;
 | 
				
			||||||
	int eccsize = chip->ecc.size;
 | 
						int eccsize = chip->ecc.size;
 | 
				
			||||||
| 
						 | 
					@ -190,10 +191,11 @@ static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
 | 
				
			||||||
*  @mtd:	mtd info structure
 | 
					*  @mtd:	mtd info structure
 | 
				
			||||||
*  @chip:	nand chip info structure
 | 
					*  @chip:	nand chip info structure
 | 
				
			||||||
*  @buf:	data buffer
 | 
					*  @buf:	data buffer
 | 
				
			||||||
 | 
					*  @oob_required:	must write chip->oob_poi to OOB
 | 
				
			||||||
*
 | 
					*
 | 
				
			||||||
***************************************************************************/
 | 
					***************************************************************************/
 | 
				
			||||||
static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd,
 | 
					static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd,
 | 
				
			||||||
	struct nand_chip *chip, const uint8_t *buf)
 | 
						struct nand_chip *chip, const uint8_t *buf, int oob_required)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int sectorIdx = 0;
 | 
						int sectorIdx = 0;
 | 
				
			||||||
	int eccsize = chip->ecc.size;
 | 
						int eccsize = chip->ecc.size;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -341,7 +341,7 @@ static int bcm_umi_nand_verify_buf(struct mtd_info *mtd, const u_char * buf,
 | 
				
			||||||
	 * for MLC parts which may have permanently stuck bits.
 | 
						 * for MLC parts which may have permanently stuck bits.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	struct nand_chip *chip = mtd->priv;
 | 
						struct nand_chip *chip = mtd->priv;
 | 
				
			||||||
	int ret = chip->ecc.read_page(mtd, chip, readbackbuf, 0);
 | 
						int ret = chip->ecc.read_page(mtd, chip, readbackbuf, 0, 0);
 | 
				
			||||||
	if (ret < 0)
 | 
						if (ret < 0)
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EFAULT;
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -558,7 +558,7 @@ static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int bf5xx_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static int bf5xx_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
		uint8_t *buf, int page)
 | 
							uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	bf5xx_nand_read_buf(mtd, buf, mtd->writesize);
 | 
						bf5xx_nand_read_buf(mtd, buf, mtd->writesize);
 | 
				
			||||||
	bf5xx_nand_read_buf(mtd, chip->oob_poi, mtd->oobsize);
 | 
						bf5xx_nand_read_buf(mtd, chip->oob_poi, mtd->oobsize);
 | 
				
			||||||
| 
						 | 
					@ -567,7 +567,7 @@ static int bf5xx_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void bf5xx_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static void bf5xx_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
		const uint8_t *buf)
 | 
							const uint8_t *buf, int oob_required)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	bf5xx_nand_write_buf(mtd, buf, mtd->writesize);
 | 
						bf5xx_nand_write_buf(mtd, buf, mtd->writesize);
 | 
				
			||||||
	bf5xx_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize);
 | 
						bf5xx_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -375,12 +375,13 @@ static int cafe_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
 * @mtd:	mtd info structure
 | 
					 * @mtd:	mtd info structure
 | 
				
			||||||
 * @chip:	nand chip info structure
 | 
					 * @chip:	nand chip info structure
 | 
				
			||||||
 * @buf:	buffer to store read data
 | 
					 * @buf:	buffer to store read data
 | 
				
			||||||
 | 
					 * @oob_required:	caller expects OOB data read to chip->oob_poi
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * The hw generator calculates the error syndrome automatically. Therefor
 | 
					 * The hw generator calculates the error syndrome automatically. Therefor
 | 
				
			||||||
 * we need a special oob layout and handling.
 | 
					 * we need a special oob layout and handling.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
			       uint8_t *buf, int page)
 | 
								       uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct cafe_priv *cafe = mtd->priv;
 | 
						struct cafe_priv *cafe = mtd->priv;
 | 
				
			||||||
	unsigned int max_bitflips = 0;
 | 
						unsigned int max_bitflips = 0;
 | 
				
			||||||
| 
						 | 
					@ -520,7 +521,8 @@ static struct nand_bbt_descr cafe_bbt_mirror_descr_512 = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd,
 | 
					static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd,
 | 
				
			||||||
					  struct nand_chip *chip, const uint8_t *buf)
 | 
										  struct nand_chip *chip,
 | 
				
			||||||
 | 
										  const uint8_t *buf, int oob_required)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct cafe_priv *cafe = mtd->priv;
 | 
						struct cafe_priv *cafe = mtd->priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -532,16 +534,17 @@ static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
				const uint8_t *buf, int page, int cached, int raw)
 | 
									const uint8_t *buf, int oob_required, int page,
 | 
				
			||||||
 | 
									int cached, int raw)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int status;
 | 
						int status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
 | 
						chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (unlikely(raw))
 | 
						if (unlikely(raw))
 | 
				
			||||||
		chip->ecc.write_page_raw(mtd, chip, buf);
 | 
							chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		chip->ecc.write_page(mtd, chip, buf);
 | 
							chip->ecc.write_page(mtd, chip, buf, oob_required);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Cached progamming disabled for now, Not sure if its worth the
 | 
						 * Cached progamming disabled for now, Not sure if its worth the
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1087,7 +1087,7 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
 * by write_page above.
 | 
					 * by write_page above.
 | 
				
			||||||
 * */
 | 
					 * */
 | 
				
			||||||
static void denali_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static void denali_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
				const uint8_t *buf)
 | 
									const uint8_t *buf, int oob_required)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* for regular page writes, we let HW handle all the ECC
 | 
						/* for regular page writes, we let HW handle all the ECC
 | 
				
			||||||
	 * data written to the device. */
 | 
						 * data written to the device. */
 | 
				
			||||||
| 
						 | 
					@ -1099,7 +1099,7 @@ static void denali_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
 * write_page() function above.
 | 
					 * write_page() function above.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static void denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
					const uint8_t *buf)
 | 
										const uint8_t *buf, int oob_required)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* for raw page writes, we want to disable ECC and simply write
 | 
						/* for raw page writes, we want to disable ECC and simply write
 | 
				
			||||||
	   whatever data is in the buffer. */
 | 
						   whatever data is in the buffer. */
 | 
				
			||||||
| 
						 | 
					@ -1122,7 +1122,7 @@ static int denali_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
			    uint8_t *buf, int page)
 | 
								    uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned int max_bitflips;
 | 
						unsigned int max_bitflips;
 | 
				
			||||||
	struct denali_nand_info *denali = mtd_to_denali(mtd);
 | 
						struct denali_nand_info *denali = mtd_to_denali(mtd);
 | 
				
			||||||
| 
						 | 
					@ -1175,7 +1175,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
				uint8_t *buf, int page)
 | 
									uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct denali_nand_info *denali = mtd_to_denali(mtd);
 | 
						struct denali_nand_info *denali = mtd_to_denali(mtd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -787,13 +787,13 @@ static int read_page(struct mtd_info *mtd, struct nand_chip *nand,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int docg4_read_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
 | 
					static int docg4_read_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
 | 
				
			||||||
			       uint8_t *buf, int page)
 | 
								       uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return read_page(mtd, nand, buf, page, false);
 | 
						return read_page(mtd, nand, buf, page, false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand,
 | 
					static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand,
 | 
				
			||||||
			   uint8_t *buf, int page)
 | 
								   uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return read_page(mtd, nand, buf, page, true);
 | 
						return read_page(mtd, nand, buf, page, true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -953,13 +953,13 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *nand,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
 | 
					static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
 | 
				
			||||||
				 const uint8_t *buf)
 | 
									 const uint8_t *buf, int oob_required)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return write_page(mtd, nand, buf, false);
 | 
						return write_page(mtd, nand, buf, false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
 | 
					static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
 | 
				
			||||||
			     const uint8_t *buf)
 | 
								     const uint8_t *buf, int oob_required)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return write_page(mtd, nand, buf, true);
 | 
						return write_page(mtd, nand, buf, true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1003,7 +1003,7 @@ static int __init read_factory_bbt(struct mtd_info *mtd)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	read_page_prologue(mtd, g4_addr);
 | 
						read_page_prologue(mtd, g4_addr);
 | 
				
			||||||
	status = docg4_read_page(mtd, nand, buf, DOCG4_FACTORY_BBT_PAGE);
 | 
						status = docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE);
 | 
				
			||||||
	if (status)
 | 
						if (status)
 | 
				
			||||||
		goto exit;
 | 
							goto exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1080,7 +1080,7 @@ static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* write first page of block */
 | 
						/* write first page of block */
 | 
				
			||||||
	write_page_prologue(mtd, g4_addr);
 | 
						write_page_prologue(mtd, g4_addr);
 | 
				
			||||||
	docg4_write_page(mtd, nand, buf);
 | 
						docg4_write_page(mtd, nand, buf, 1);
 | 
				
			||||||
	ret = pageprog(mtd);
 | 
						ret = pageprog(mtd);
 | 
				
			||||||
	if (!ret)
 | 
						if (!ret)
 | 
				
			||||||
		mtd->ecc_stats.badblocks++;
 | 
							mtd->ecc_stats.badblocks++;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -746,10 +746,8 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fsl_elbc_read_page(struct mtd_info *mtd,
 | 
					static int fsl_elbc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
                              struct nand_chip *chip,
 | 
								      uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
			      uint8_t *buf,
 | 
					 | 
				
			||||||
			      int page)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct fsl_elbc_mtd *priv = chip->priv;
 | 
						struct fsl_elbc_mtd *priv = chip->priv;
 | 
				
			||||||
	struct fsl_lbc_ctrl *ctrl = priv->ctrl;
 | 
						struct fsl_lbc_ctrl *ctrl = priv->ctrl;
 | 
				
			||||||
| 
						 | 
					@ -767,9 +765,8 @@ static int fsl_elbc_read_page(struct mtd_info *mtd,
 | 
				
			||||||
/* ECC will be calculated automatically, and errors will be detected in
 | 
					/* ECC will be calculated automatically, and errors will be detected in
 | 
				
			||||||
 * waitfunc.
 | 
					 * waitfunc.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void fsl_elbc_write_page(struct mtd_info *mtd,
 | 
					static void fsl_elbc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
                                struct nand_chip *chip,
 | 
									const uint8_t *buf, int oob_required)
 | 
				
			||||||
                                const uint8_t *buf)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	fsl_elbc_write_buf(mtd, buf, mtd->writesize);
 | 
						fsl_elbc_write_buf(mtd, buf, mtd->writesize);
 | 
				
			||||||
	fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
 | 
						fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -698,9 +698,8 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip)
 | 
				
			||||||
	return nand_fsr | NAND_STATUS_WP;
 | 
						return nand_fsr | NAND_STATUS_WP;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int fsl_ifc_read_page(struct mtd_info *mtd,
 | 
					static int fsl_ifc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
			      struct nand_chip *chip,
 | 
								     uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
			      uint8_t *buf, int page)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct fsl_ifc_mtd *priv = chip->priv;
 | 
						struct fsl_ifc_mtd *priv = chip->priv;
 | 
				
			||||||
	struct fsl_ifc_ctrl *ctrl = priv->ctrl;
 | 
						struct fsl_ifc_ctrl *ctrl = priv->ctrl;
 | 
				
			||||||
| 
						 | 
					@ -721,9 +720,8 @@ static int fsl_ifc_read_page(struct mtd_info *mtd,
 | 
				
			||||||
/* ECC will be calculated automatically, and errors will be detected in
 | 
					/* ECC will be calculated automatically, and errors will be detected in
 | 
				
			||||||
 * waitfunc.
 | 
					 * waitfunc.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void fsl_ifc_write_page(struct mtd_info *mtd,
 | 
					static void fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
				struct nand_chip *chip,
 | 
								       const uint8_t *buf, int oob_required)
 | 
				
			||||||
				const uint8_t *buf)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	fsl_ifc_write_buf(mtd, buf, mtd->writesize);
 | 
						fsl_ifc_write_buf(mtd, buf, mtd->writesize);
 | 
				
			||||||
	fsl_ifc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
 | 
						fsl_ifc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -692,6 +692,7 @@ static void fsmc_write_buf_dma(struct mtd_info *mtd, const uint8_t *buf,
 | 
				
			||||||
 * @mtd:	mtd info structure
 | 
					 * @mtd:	mtd info structure
 | 
				
			||||||
 * @chip:	nand chip info structure
 | 
					 * @chip:	nand chip info structure
 | 
				
			||||||
 * @buf:	buffer to store read data
 | 
					 * @buf:	buffer to store read data
 | 
				
			||||||
 | 
					 * @oob_required:	caller expects OOB data read to chip->oob_poi
 | 
				
			||||||
 * @page:	page number to read
 | 
					 * @page:	page number to read
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This routine is needed for fsmc version 8 as reading from NAND chip has to be
 | 
					 * This routine is needed for fsmc version 8 as reading from NAND chip has to be
 | 
				
			||||||
| 
						 | 
					@ -701,7 +702,7 @@ static void fsmc_write_buf_dma(struct mtd_info *mtd, const uint8_t *buf,
 | 
				
			||||||
 * max of 8 bits)
 | 
					 * max of 8 bits)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
				 uint8_t *buf, int page)
 | 
									 uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct fsmc_nand_data *host = container_of(mtd,
 | 
						struct fsmc_nand_data *host = container_of(mtd,
 | 
				
			||||||
					struct fsmc_nand_data, mtd);
 | 
										struct fsmc_nand_data, mtd);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -842,7 +842,7 @@ static void block_mark_swapping(struct gpmi_nand_data *this,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
				uint8_t *buf, int page)
 | 
									uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct gpmi_nand_data *this = chip->priv;
 | 
						struct gpmi_nand_data *this = chip->priv;
 | 
				
			||||||
	struct bch_geometry *nfc_geo = &this->bch_geometry;
 | 
						struct bch_geometry *nfc_geo = &this->bch_geometry;
 | 
				
			||||||
| 
						 | 
					@ -928,8 +928,8 @@ exit_nfc:
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void gpmi_ecc_write_page(struct mtd_info *mtd,
 | 
					static void gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
				struct nand_chip *chip, const uint8_t *buf)
 | 
									const uint8_t *buf, int oob_required)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct gpmi_nand_data *this = chip->priv;
 | 
						struct gpmi_nand_data *this = chip->priv;
 | 
				
			||||||
	struct bch_geometry *nfc_geo = &this->bch_geometry;
 | 
						struct bch_geometry *nfc_geo = &this->bch_geometry;
 | 
				
			||||||
| 
						 | 
					@ -1309,7 +1309,7 @@ static int mx23_write_transcription_stamp(struct gpmi_nand_data *this)
 | 
				
			||||||
		/* Write the first page of the current stride. */
 | 
							/* Write the first page of the current stride. */
 | 
				
			||||||
		dev_dbg(dev, "Writing an NCB fingerprint in page 0x%x\n", page);
 | 
							dev_dbg(dev, "Writing an NCB fingerprint in page 0x%x\n", page);
 | 
				
			||||||
		chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
 | 
							chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
 | 
				
			||||||
		chip->ecc.write_page_raw(mtd, chip, buffer);
 | 
							chip->ecc.write_page_raw(mtd, chip, buffer, 0);
 | 
				
			||||||
		chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
 | 
							chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Wait for the write to finish. */
 | 
							/* Wait for the write to finish. */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1066,12 +1066,13 @@ EXPORT_SYMBOL(nand_lock);
 | 
				
			||||||
 * @mtd: mtd info structure
 | 
					 * @mtd: mtd info structure
 | 
				
			||||||
 * @chip: nand chip info structure
 | 
					 * @chip: nand chip info structure
 | 
				
			||||||
 * @buf: buffer to store read data
 | 
					 * @buf: buffer to store read data
 | 
				
			||||||
 | 
					 * @oob_required: caller requires OOB data read to chip->oob_poi
 | 
				
			||||||
 * @page: page number to read
 | 
					 * @page: page number to read
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Not for syndrome calculating ECC controllers, which use a special oob layout.
 | 
					 * Not for syndrome calculating ECC controllers, which use a special oob layout.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
			      uint8_t *buf, int page)
 | 
								      uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	chip->read_buf(mtd, buf, mtd->writesize);
 | 
						chip->read_buf(mtd, buf, mtd->writesize);
 | 
				
			||||||
	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 | 
						chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 | 
				
			||||||
| 
						 | 
					@ -1083,13 +1084,14 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
 * @mtd: mtd info structure
 | 
					 * @mtd: mtd info structure
 | 
				
			||||||
 * @chip: nand chip info structure
 | 
					 * @chip: nand chip info structure
 | 
				
			||||||
 * @buf: buffer to store read data
 | 
					 * @buf: buffer to store read data
 | 
				
			||||||
 | 
					 * @oob_required: caller requires OOB data read to chip->oob_poi
 | 
				
			||||||
 * @page: page number to read
 | 
					 * @page: page number to read
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * We need a special oob layout and handling even when OOB isn't used.
 | 
					 * We need a special oob layout and handling even when OOB isn't used.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
 | 
					static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
 | 
				
			||||||
					struct nand_chip *chip,
 | 
									       struct nand_chip *chip, uint8_t *buf,
 | 
				
			||||||
					uint8_t *buf, int page)
 | 
									       int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int eccsize = chip->ecc.size;
 | 
						int eccsize = chip->ecc.size;
 | 
				
			||||||
	int eccbytes = chip->ecc.bytes;
 | 
						int eccbytes = chip->ecc.bytes;
 | 
				
			||||||
| 
						 | 
					@ -1126,10 +1128,11 @@ static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
 | 
				
			||||||
 * @mtd: mtd info structure
 | 
					 * @mtd: mtd info structure
 | 
				
			||||||
 * @chip: nand chip info structure
 | 
					 * @chip: nand chip info structure
 | 
				
			||||||
 * @buf: buffer to store read data
 | 
					 * @buf: buffer to store read data
 | 
				
			||||||
 | 
					 * @oob_required: caller requires OOB data read to chip->oob_poi
 | 
				
			||||||
 * @page: page number to read
 | 
					 * @page: page number to read
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
				uint8_t *buf, int page)
 | 
									uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, eccsize = chip->ecc.size;
 | 
						int i, eccsize = chip->ecc.size;
 | 
				
			||||||
	int eccbytes = chip->ecc.bytes;
 | 
						int eccbytes = chip->ecc.bytes;
 | 
				
			||||||
| 
						 | 
					@ -1140,7 +1143,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
	uint32_t *eccpos = chip->ecc.layout->eccpos;
 | 
						uint32_t *eccpos = chip->ecc.layout->eccpos;
 | 
				
			||||||
	unsigned int max_bitflips = 0;
 | 
						unsigned int max_bitflips = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chip->ecc.read_page_raw(mtd, chip, buf, page);
 | 
						chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
 | 
						for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
 | 
				
			||||||
		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 | 
							chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 | 
				
			||||||
| 
						 | 
					@ -1263,12 +1266,13 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
 * @mtd: mtd info structure
 | 
					 * @mtd: mtd info structure
 | 
				
			||||||
 * @chip: nand chip info structure
 | 
					 * @chip: nand chip info structure
 | 
				
			||||||
 * @buf: buffer to store read data
 | 
					 * @buf: buffer to store read data
 | 
				
			||||||
 | 
					 * @oob_required: caller requires OOB data read to chip->oob_poi
 | 
				
			||||||
 * @page: page number to read
 | 
					 * @page: page number to read
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Not for syndrome calculating ECC controllers which need a special oob layout.
 | 
					 * Not for syndrome calculating ECC controllers which need a special oob layout.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
				uint8_t *buf, int page)
 | 
									uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, eccsize = chip->ecc.size;
 | 
						int i, eccsize = chip->ecc.size;
 | 
				
			||||||
	int eccbytes = chip->ecc.bytes;
 | 
						int eccbytes = chip->ecc.bytes;
 | 
				
			||||||
| 
						 | 
					@ -1311,6 +1315,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
 * @mtd: mtd info structure
 | 
					 * @mtd: mtd info structure
 | 
				
			||||||
 * @chip: nand chip info structure
 | 
					 * @chip: nand chip info structure
 | 
				
			||||||
 * @buf: buffer to store read data
 | 
					 * @buf: buffer to store read data
 | 
				
			||||||
 | 
					 * @oob_required: caller requires OOB data read to chip->oob_poi
 | 
				
			||||||
 * @page: page number to read
 | 
					 * @page: page number to read
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Hardware ECC for large page chips, require OOB to be read first. For this
 | 
					 * Hardware ECC for large page chips, require OOB to be read first. For this
 | 
				
			||||||
| 
						 | 
					@ -1320,7 +1325,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
 * the data area, by overwriting the NAND manufacturer bad block markings.
 | 
					 * the data area, by overwriting the NAND manufacturer bad block markings.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 | 
					static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 | 
				
			||||||
	struct nand_chip *chip, uint8_t *buf, int page)
 | 
						struct nand_chip *chip, uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, eccsize = chip->ecc.size;
 | 
						int i, eccsize = chip->ecc.size;
 | 
				
			||||||
	int eccbytes = chip->ecc.bytes;
 | 
						int eccbytes = chip->ecc.bytes;
 | 
				
			||||||
| 
						 | 
					@ -1362,13 +1367,14 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 | 
				
			||||||
 * @mtd: mtd info structure
 | 
					 * @mtd: mtd info structure
 | 
				
			||||||
 * @chip: nand chip info structure
 | 
					 * @chip: nand chip info structure
 | 
				
			||||||
 * @buf: buffer to store read data
 | 
					 * @buf: buffer to store read data
 | 
				
			||||||
 | 
					 * @oob_required: caller requires OOB data read to chip->oob_poi
 | 
				
			||||||
 * @page: page number to read
 | 
					 * @page: page number to read
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * The hw generator calculates the error syndrome automatically. Therefore we
 | 
					 * The hw generator calculates the error syndrome automatically. Therefore we
 | 
				
			||||||
 * need a special oob layout and handling.
 | 
					 * need a special oob layout and handling.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
				   uint8_t *buf, int page)
 | 
									   uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, eccsize = chip->ecc.size;
 | 
						int i, eccsize = chip->ecc.size;
 | 
				
			||||||
	int eccbytes = chip->ecc.bytes;
 | 
						int eccbytes = chip->ecc.bytes;
 | 
				
			||||||
| 
						 | 
					@ -1514,14 +1520,14 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 | 
				
			||||||
			 * the read methods return max bitflips per ecc step.
 | 
								 * the read methods return max bitflips per ecc step.
 | 
				
			||||||
			 */
 | 
								 */
 | 
				
			||||||
			if (unlikely(ops->mode == MTD_OPS_RAW))
 | 
								if (unlikely(ops->mode == MTD_OPS_RAW))
 | 
				
			||||||
				ret = chip->ecc.read_page_raw(mtd, chip,
 | 
									ret = chip->ecc.read_page_raw(mtd, chip, bufpoi,
 | 
				
			||||||
							      bufpoi, page);
 | 
												      1, page);
 | 
				
			||||||
			else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob)
 | 
								else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob)
 | 
				
			||||||
				ret = chip->ecc.read_subpage(mtd, chip,
 | 
									ret = chip->ecc.read_subpage(mtd, chip,
 | 
				
			||||||
							col, bytes, bufpoi);
 | 
												col, bytes, bufpoi);
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				ret = chip->ecc.read_page(mtd, chip, bufpoi,
 | 
									ret = chip->ecc.read_page(mtd, chip, bufpoi,
 | 
				
			||||||
							  page);
 | 
												  1, page);
 | 
				
			||||||
			if (ret < 0) {
 | 
								if (ret < 0) {
 | 
				
			||||||
				if (!aligned)
 | 
									if (!aligned)
 | 
				
			||||||
					/* Invalidate page cache */
 | 
										/* Invalidate page cache */
 | 
				
			||||||
| 
						 | 
					@ -1913,11 +1919,12 @@ out:
 | 
				
			||||||
 * @mtd: mtd info structure
 | 
					 * @mtd: mtd info structure
 | 
				
			||||||
 * @chip: nand chip info structure
 | 
					 * @chip: nand chip info structure
 | 
				
			||||||
 * @buf: data buffer
 | 
					 * @buf: data buffer
 | 
				
			||||||
 | 
					 * @oob_required: must write chip->oob_poi to OOB
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Not for syndrome calculating ECC controllers, which use a special oob layout.
 | 
					 * Not for syndrome calculating ECC controllers, which use a special oob layout.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
				const uint8_t *buf)
 | 
									const uint8_t *buf, int oob_required)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	chip->write_buf(mtd, buf, mtd->writesize);
 | 
						chip->write_buf(mtd, buf, mtd->writesize);
 | 
				
			||||||
	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
 | 
						chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
 | 
				
			||||||
| 
						 | 
					@ -1928,12 +1935,13 @@ static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
 * @mtd: mtd info structure
 | 
					 * @mtd: mtd info structure
 | 
				
			||||||
 * @chip: nand chip info structure
 | 
					 * @chip: nand chip info structure
 | 
				
			||||||
 * @buf: data buffer
 | 
					 * @buf: data buffer
 | 
				
			||||||
 | 
					 * @oob_required: must write chip->oob_poi to OOB
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * We need a special oob layout and handling even when ECC isn't checked.
 | 
					 * We need a special oob layout and handling even when ECC isn't checked.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void nand_write_page_raw_syndrome(struct mtd_info *mtd,
 | 
					static void nand_write_page_raw_syndrome(struct mtd_info *mtd,
 | 
				
			||||||
					struct nand_chip *chip,
 | 
										struct nand_chip *chip,
 | 
				
			||||||
					const uint8_t *buf)
 | 
										const uint8_t *buf, int oob_required)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int eccsize = chip->ecc.size;
 | 
						int eccsize = chip->ecc.size;
 | 
				
			||||||
	int eccbytes = chip->ecc.bytes;
 | 
						int eccbytes = chip->ecc.bytes;
 | 
				
			||||||
| 
						 | 
					@ -1967,9 +1975,10 @@ static void nand_write_page_raw_syndrome(struct mtd_info *mtd,
 | 
				
			||||||
 * @mtd: mtd info structure
 | 
					 * @mtd: mtd info structure
 | 
				
			||||||
 * @chip: nand chip info structure
 | 
					 * @chip: nand chip info structure
 | 
				
			||||||
 * @buf: data buffer
 | 
					 * @buf: data buffer
 | 
				
			||||||
 | 
					 * @oob_required: must write chip->oob_poi to OOB
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
				  const uint8_t *buf)
 | 
									  const uint8_t *buf, int oob_required)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, eccsize = chip->ecc.size;
 | 
						int i, eccsize = chip->ecc.size;
 | 
				
			||||||
	int eccbytes = chip->ecc.bytes;
 | 
						int eccbytes = chip->ecc.bytes;
 | 
				
			||||||
| 
						 | 
					@ -1985,7 +1994,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
	for (i = 0; i < chip->ecc.total; i++)
 | 
						for (i = 0; i < chip->ecc.total; i++)
 | 
				
			||||||
		chip->oob_poi[eccpos[i]] = ecc_calc[i];
 | 
							chip->oob_poi[eccpos[i]] = ecc_calc[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chip->ecc.write_page_raw(mtd, chip, buf);
 | 
						chip->ecc.write_page_raw(mtd, chip, buf, 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -1993,9 +2002,10 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
 * @mtd: mtd info structure
 | 
					 * @mtd: mtd info structure
 | 
				
			||||||
 * @chip: nand chip info structure
 | 
					 * @chip: nand chip info structure
 | 
				
			||||||
 * @buf: data buffer
 | 
					 * @buf: data buffer
 | 
				
			||||||
 | 
					 * @oob_required: must write chip->oob_poi to OOB
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
				  const uint8_t *buf)
 | 
									  const uint8_t *buf, int oob_required)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, eccsize = chip->ecc.size;
 | 
						int i, eccsize = chip->ecc.size;
 | 
				
			||||||
	int eccbytes = chip->ecc.bytes;
 | 
						int eccbytes = chip->ecc.bytes;
 | 
				
			||||||
| 
						 | 
					@ -2021,12 +2031,14 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
 * @mtd: mtd info structure
 | 
					 * @mtd: mtd info structure
 | 
				
			||||||
 * @chip: nand chip info structure
 | 
					 * @chip: nand chip info structure
 | 
				
			||||||
 * @buf: data buffer
 | 
					 * @buf: data buffer
 | 
				
			||||||
 | 
					 * @oob_required: must write chip->oob_poi to OOB
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * The hw generator calculates the error syndrome automatically. Therefore we
 | 
					 * The hw generator calculates the error syndrome automatically. Therefore we
 | 
				
			||||||
 * need a special oob layout and handling.
 | 
					 * need a special oob layout and handling.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void nand_write_page_syndrome(struct mtd_info *mtd,
 | 
					static void nand_write_page_syndrome(struct mtd_info *mtd,
 | 
				
			||||||
				    struct nand_chip *chip, const uint8_t *buf)
 | 
									    struct nand_chip *chip,
 | 
				
			||||||
 | 
									    const uint8_t *buf, int oob_required)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, eccsize = chip->ecc.size;
 | 
						int i, eccsize = chip->ecc.size;
 | 
				
			||||||
	int eccbytes = chip->ecc.bytes;
 | 
						int eccbytes = chip->ecc.bytes;
 | 
				
			||||||
| 
						 | 
					@ -2065,21 +2077,23 @@ static void nand_write_page_syndrome(struct mtd_info *mtd,
 | 
				
			||||||
 * @mtd: MTD device structure
 | 
					 * @mtd: MTD device structure
 | 
				
			||||||
 * @chip: NAND chip descriptor
 | 
					 * @chip: NAND chip descriptor
 | 
				
			||||||
 * @buf: the data to write
 | 
					 * @buf: the data to write
 | 
				
			||||||
 | 
					 * @oob_required: must write chip->oob_poi to OOB
 | 
				
			||||||
 * @page: page number to write
 | 
					 * @page: page number to write
 | 
				
			||||||
 * @cached: cached programming
 | 
					 * @cached: cached programming
 | 
				
			||||||
 * @raw: use _raw version of write_page
 | 
					 * @raw: use _raw version of write_page
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
			   const uint8_t *buf, int page, int cached, int raw)
 | 
								   const uint8_t *buf, int oob_required, int page,
 | 
				
			||||||
 | 
								   int cached, int raw)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int status;
 | 
						int status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
 | 
						chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (unlikely(raw))
 | 
						if (unlikely(raw))
 | 
				
			||||||
		chip->ecc.write_page_raw(mtd, chip, buf);
 | 
							chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		chip->ecc.write_page(mtd, chip, buf);
 | 
							chip->ecc.write_page(mtd, chip, buf, oob_required);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Cached progamming disabled for now. Not sure if it's worth the
 | 
						 * Cached progamming disabled for now. Not sure if it's worth the
 | 
				
			||||||
| 
						 | 
					@ -2261,7 +2275,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
 | 
				
			||||||
			memset(chip->oob_poi, 0xff, mtd->oobsize);
 | 
								memset(chip->oob_poi, 0xff, mtd->oobsize);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ret = chip->write_page(mtd, chip, wbuf, page, cached,
 | 
							ret = chip->write_page(mtd, chip, wbuf, 1, page, cached,
 | 
				
			||||||
				       (ops->mode == MTD_OPS_RAW));
 | 
									       (ops->mode == MTD_OPS_RAW));
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -682,14 +682,15 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
 | 
					static void pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
 | 
				
			||||||
		struct nand_chip *chip, const uint8_t *buf)
 | 
							struct nand_chip *chip, const uint8_t *buf, int oob_required)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	chip->write_buf(mtd, buf, mtd->writesize);
 | 
						chip->write_buf(mtd, buf, mtd->writesize);
 | 
				
			||||||
	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
 | 
						chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
 | 
					static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
 | 
				
			||||||
		struct nand_chip *chip, uint8_t *buf, int page)
 | 
							struct nand_chip *chip, uint8_t *buf, int oob_required,
 | 
				
			||||||
 | 
							int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pxa3xx_nand_host *host = mtd->priv;
 | 
						struct pxa3xx_nand_host *host = mtd->priv;
 | 
				
			||||||
	struct pxa3xx_nand_info *info = host->info_data;
 | 
						struct pxa3xx_nand_info *info = host->info_data;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -344,7 +344,7 @@ static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_va
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
				uint8_t *buf, int page)
 | 
									uint8_t *buf, int oob_required, int page)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, eccsize = chip->ecc.size;
 | 
						int i, eccsize = chip->ecc.size;
 | 
				
			||||||
	int eccbytes = chip->ecc.bytes;
 | 
						int eccbytes = chip->ecc.bytes;
 | 
				
			||||||
| 
						 | 
					@ -366,7 +366,7 @@ static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
					static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
				   const uint8_t *buf)
 | 
									   const uint8_t *buf, int oob_required)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, eccsize = chip->ecc.size;
 | 
						int i, eccsize = chip->ecc.size;
 | 
				
			||||||
	int eccbytes = chip->ecc.bytes;
 | 
						int eccbytes = chip->ecc.bytes;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -360,15 +360,15 @@ struct nand_ecc_ctrl {
 | 
				
			||||||
	int (*correct)(struct mtd_info *mtd, uint8_t *dat, uint8_t *read_ecc,
 | 
						int (*correct)(struct mtd_info *mtd, uint8_t *dat, uint8_t *read_ecc,
 | 
				
			||||||
			uint8_t *calc_ecc);
 | 
								uint8_t *calc_ecc);
 | 
				
			||||||
	int (*read_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
 | 
						int (*read_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
			uint8_t *buf, int page);
 | 
								uint8_t *buf, int oob_required, int page);
 | 
				
			||||||
	void (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
 | 
						void (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
			const uint8_t *buf);
 | 
								const uint8_t *buf, int oob_required);
 | 
				
			||||||
	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
 | 
						int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
			uint8_t *buf, int page);
 | 
								uint8_t *buf, int oob_required, int page);
 | 
				
			||||||
	int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
 | 
						int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
			uint32_t offs, uint32_t len, uint8_t *buf);
 | 
								uint32_t offs, uint32_t len, uint8_t *buf);
 | 
				
			||||||
	void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
 | 
						void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
			const uint8_t *buf);
 | 
								const uint8_t *buf, int oob_required);
 | 
				
			||||||
	int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
 | 
						int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
			int page);
 | 
								int page);
 | 
				
			||||||
	int (*read_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
 | 
						int (*read_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
| 
						 | 
					@ -504,7 +504,8 @@ struct nand_chip {
 | 
				
			||||||
	int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state,
 | 
						int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state,
 | 
				
			||||||
			int status, int page);
 | 
								int status, int page);
 | 
				
			||||||
	int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
 | 
						int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
 | 
				
			||||||
			const uint8_t *buf, int page, int cached, int raw);
 | 
								const uint8_t *buf, int oob_required, int page,
 | 
				
			||||||
 | 
								int cached, int raw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int chip_delay;
 | 
						int chip_delay;
 | 
				
			||||||
	unsigned int options;
 | 
						unsigned int options;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue