diff options
| author | Kyungmin Park <kmpark@infradead.org> | 2008-08-13 09:11:02 +0900 | 
|---|---|---|
| committer | Scott Wood <scottwood@freescale.com> | 2008-08-13 11:00:19 -0500 | 
| commit | d438d50848e9425286e5fb0493e0affb5a0b1e1b (patch) | |
| tree | 49406f77ad245aca8e1e21b98f2d3216c2a3f774 | |
| parent | 8641ff266ae6638da201747c239fd39ba34c4958 (diff) | |
| download | olio-uboot-2014.01-d438d50848e9425286e5fb0493e0affb5a0b1e1b.tar.xz olio-uboot-2014.01-d438d50848e9425286e5fb0493e0affb5a0b1e1b.zip | |
Fix OneNAND build break
Since page size field is changed from oobblock to writesize. But OneNAND is not updated.
- fix bufferram management at erase operation
This patch includes the NAND/OneNAND state filed too.
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Scott Wood <scottwood@freescale.com>
| -rw-r--r-- | common/env_onenand.c | 10 | ||||
| -rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 131 | ||||
| -rw-r--r-- | drivers/mtd/onenand/onenand_bbt.c | 4 | ||||
| -rw-r--r-- | include/linux/mtd/mtd.h | 16 | ||||
| -rw-r--r-- | include/linux/mtd/nand.h | 16 | ||||
| -rw-r--r-- | include/linux/mtd/nand_legacy.h | 12 | ||||
| -rw-r--r-- | include/linux/mtd/onenand.h | 19 | 
7 files changed, 122 insertions, 86 deletions
| diff --git a/common/env_onenand.c b/common/env_onenand.c index dbd0883fa..d5c907c6f 100644 --- a/common/env_onenand.c +++ b/common/env_onenand.c @@ -40,7 +40,7 @@ extern struct onenand_chip onenand_chip;  /* References to names in env_common.c */  extern uchar default_environment[]; -#define ONENAND_ENV_SIZE(mtd)	(mtd.oobblock - ENV_HEADER_SIZE) +#define ONENAND_ENV_SIZE(mtd)	(mtd.writesize - ENV_HEADER_SIZE)  char *env_name_spec = "OneNAND"; @@ -68,12 +68,12 @@ void env_relocate_spec(void)  	env_addr = CFG_ENV_ADDR;  	/* Check OneNAND exist */ -	if (onenand_mtd.oobblock) +	if (onenand_mtd.writesize)  		/* Ignore read fail */ -		onenand_read(&onenand_mtd, env_addr, onenand_mtd.oobblock, +		onenand_read(&onenand_mtd, env_addr, onenand_mtd.writesize,  			     &retlen, (u_char *) env_ptr);  	else -		onenand_mtd.oobblock = MAX_ONENAND_PAGESIZE; +		onenand_mtd.writesize = MAX_ONENAND_PAGESIZE;  	if (crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd)) !=  	    env_ptr->crc) @@ -109,7 +109,7 @@ int saveenv(void)  	env_ptr->crc =  	    crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd)); -	if (onenand_write(&onenand_mtd, env_addr, onenand_mtd.oobblock, &retlen, +	if (onenand_write(&onenand_mtd, env_addr, onenand_mtd.writesize, &retlen,  	     (u_char *) env_ptr)) {  		printf("OneNAND: write failed at 0x%08x\n", instr.addr);  		return 2; diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index ded1706ab..eaa48f948 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -331,7 +331,7 @@ static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)  	if (ONENAND_CURRENT_BUFFERRAM(this)) {  		if (area == ONENAND_DATARAM) -			return mtd->oobblock; +			return mtd->writesize;  		if (area == ONENAND_SPARERAM)  			return mtd->oobsize;  	} @@ -482,6 +482,30 @@ static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,  }  /** + * onenand_invalidate_bufferram - [GENERIC] Invalidate BufferRAM information + * @param mtd           MTD data structure + * @param addr          start address to invalidate + * @param len           length to invalidate + * + * Invalidate BufferRAM information + */ +static void onenand_invalidate_bufferram(struct mtd_info *mtd, loff_t addr, +                                         unsigned int len) +{ +	struct onenand_chip *this = mtd->priv; +	int i; +	loff_t end_addr = addr + len; + +	/* Invalidate BufferRAM */ +	for (i = 0; i < MAX_BUFFERRAM; i++) { +		loff_t buf_addr = this->bufferram[i].block << this->erase_shift; + +		if (buf_addr >= addr && buf_addr < end_addr) +			this->bufferram[i].valid = 0; +	} +} + +/**   * onenand_get_device - [GENERIC] Get chip for selected access   * @param mtd		MTD device structure   * @param new_state	the state which is requested @@ -541,15 +565,15 @@ static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,  	onenand_get_device(mtd, FL_READING);  	while (read < len) { -		thislen = min_t(int, mtd->oobblock, len - read); +		thislen = min_t(int, mtd->writesize, len - read); -		column = from & (mtd->oobblock - 1); -		if (column + thislen > mtd->oobblock) -			thislen = mtd->oobblock - column; +		column = from & (mtd->writesize - 1); +		if (column + thislen > mtd->writesize) +			thislen = mtd->writesize - column;  		if (!onenand_check_bufferram(mtd, from)) {  			this->command(mtd, ONENAND_CMD_READ, from, -				      mtd->oobblock); +				      mtd->writesize);  			ret = this->wait(mtd, FL_READING);  			/* First copy data and check return value for ECC handling */  			onenand_update_bufferram(mtd, from, 1); @@ -664,7 +688,7 @@ int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,  		/* Read more? */  		if (read < len) {  			/* Page size */ -			from += mtd->oobblock; +			from += mtd->writesize;  			column = 0;  		}  	} @@ -691,7 +715,7 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,  	void __iomem *dataram0, *dataram1;  	int ret = 0; -	this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock); +	this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);  	ret = this->wait(mtd, FL_READING);  	if (ret) @@ -701,9 +725,9 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,  	/* Check, if the two dataram areas are same */  	dataram0 = this->base + ONENAND_DATARAM; -	dataram1 = dataram0 + mtd->oobblock; +	dataram1 = dataram0 + mtd->writesize; -	if (memcmp(dataram0, dataram1, mtd->oobblock)) +	if (memcmp(dataram0, dataram1, mtd->writesize))  		return -EBADMSG;  	return 0; @@ -712,7 +736,7 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,  #define onenand_verify_page(...)	(0)  #endif -#define NOTALIGNED(x)	((x & (mtd->oobblock - 1)) != 0) +#define NOTALIGNED(x)	((x & (mtd->writesize - 1)) != 0)  /**   * onenand_write_ecc - [MTD Interface] OneNAND write with ECC @@ -760,15 +784,15 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,  	/* Loop until all data write */  	while (written < len) { -		int thislen = min_t(int, mtd->oobblock, len - written); +		int thislen = min_t(int, mtd->writesize, len - written); -		this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock); +		this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->writesize);  		this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);  		this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0,  				      mtd->oobsize); -		this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock); +		this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);  		onenand_update_bufferram(mtd, to, 1); @@ -893,6 +917,25 @@ int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,  }  /** + * onenand_block_isbad_nolock - [GENERIC] Check if a block is marked bad + * @param mtd		MTD device structure + * @param ofs		offset from device start + * @param allowbbt	1, if its allowed to access the bbt area + * + * Check, if the block is bad, Either by reading the bad block table or + * calling of the scan function. + */ +static int onenand_block_isbad_nolock(struct mtd_info *mtd, loff_t ofs, int allowbbt) +{ +	struct onenand_chip *this = mtd->priv; +	struct bbm_info *bbm = this->bbm; + +	/* Return info from the table */ +	return bbm->isbad_bbt(mtd, ofs, allowbbt); +} + + +/**   * onenand_erase - [MTD Interface] erase block(s)   * @param mtd		MTD device structure   * @param instr		erase instruction @@ -950,6 +993,8 @@ int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)  		this->command(mtd, ONENAND_CMD_ERASE, addr, block_size); +		onenand_invalidate_bufferram(mtd, addr, block_size); +  		ret = this->wait(mtd, FL_ERASING);  		/* Check, if it is write protected */  		if (ret) { @@ -1005,30 +1050,45 @@ void onenand_sync(struct mtd_info *mtd)   * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad   * @param mtd		MTD device structure   * @param ofs		offset relative to mtd start + * + * Check whether the block is bad   */  int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)  { -	/* -	 * TODO -	 * 1. Bad block table (BBT) -	 *   -> using NAND BBT to support JFFS2 -	 * 2. Bad block management (BBM) -	 *   -> bad block replace scheme -	 * -	 * Currently we do nothing -	 */ -	return 0; +	int ret; + +	/* Check for invalid offset */ +	if (ofs > mtd->size) +		return -EINVAL; + +	onenand_get_device(mtd, FL_READING); +	ret = onenand_block_isbad_nolock(mtd,ofs, 0); +	onenand_release_device(mtd); +	return ret;  }  /**   * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad   * @param mtd		MTD device structure   * @param ofs		offset relative to mtd start + * + * Mark the block as bad   */  int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)  { -	/* see above */ -	return 0; +	struct onenand_chip *this = mtd->priv; +	int ret; + +	ret = onenand_block_isbad(mtd, ofs); +	if (ret) { +		/* If it was bad already, return success and do nothing */ +		if (ret > 0) +			return 0; +		return ret; +	} + +	ret = this->block_markbad(mtd, ofs); +	return ret;  }  /** @@ -1184,10 +1244,8 @@ static int onenand_probe(struct mtd_info *mtd)  	/* Reset OneNAND to read default register values */  	this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM); -	{ -		int i; -		for (i = 0; i < 10000; i++) ; -	} +	/* Wait reset */ +	this->wait(mtd, FL_RESETING);  	/* Read manufacturer and device IDs from Register */  	maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID); @@ -1212,16 +1270,16 @@ static int onenand_probe(struct mtd_info *mtd)  	/* OneNAND page size & block size */  	/* The data buffer size is equal to page size */ -	mtd->oobblock = +	mtd->writesize =  	    this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE); -	mtd->oobsize = mtd->oobblock >> 5; +	mtd->oobsize = mtd->writesize >> 5;  	/* Pagers per block is always 64 in OneNAND */ -	mtd->erasesize = mtd->oobblock << 6; +	mtd->erasesize = mtd->writesize << 6;  	this->erase_shift = ffs(mtd->erasesize) - 1; -	this->page_shift = ffs(mtd->oobblock) - 1; +	this->page_shift = ffs(mtd->writesize) - 1;  	this->ppb_shift = (this->erase_shift - this->page_shift); -	this->page_mask = (mtd->erasesize / mtd->oobblock) - 1; +	this->page_mask = (mtd->erasesize / mtd->writesize) - 1;  	/* REVIST: Multichip handling */ @@ -1240,11 +1298,10 @@ static int onenand_probe(struct mtd_info *mtd)  		this->options |= ONENAND_CONT_LOCK;  	} +	mtd->flags = MTD_CAP_NANDFLASH;  	mtd->erase = onenand_erase;  	mtd->read = onenand_read;  	mtd->write = onenand_write; -	mtd->read_ecc = onenand_read_ecc; -	mtd->write_ecc = onenand_write_ecc;  	mtd->read_oob = onenand_read_oob;  	mtd->write_oob = onenand_write_oob;  	mtd->sync = onenand_sync; diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c index 87344ab65..318d877bf 100644 --- a/drivers/mtd/onenand/onenand_bbt.c +++ b/drivers/mtd/onenand/onenand_bbt.c @@ -97,7 +97,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,  			/* No need to read pages fully,  			 * just read required OOB bytes */  			ret = onenand_read_oob(mtd, -					     from + j * mtd->oobblock + +					     from + j * mtd->writesize +  					     bd->offs, readlen, &retlen,  					     &buf[0]); @@ -107,7 +107,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,  			}  			if (check_short_pattern -			    (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { +			    (&buf[j * scanlen], scanlen, mtd->writesize, bd)) {  				bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);  				printk(KERN_WARNING  				       "Bad eraseblock %d at 0x%08x\n", i >> 1, diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 8e0dc00f7..14815c219 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -22,6 +22,22 @@  #define MTD_ERASE_DONE          0x08  #define MTD_ERASE_FAILED        0x10 +/* + * Enumeration for NAND/OneNAND flash chip state + */ +enum { +	FL_READY, +	FL_READING, +	FL_WRITING, +	FL_ERASING, +	FL_SYNCING, +	FL_CACHEDPRG, +	FL_RESETING, +	FL_UNLOCKING, +	FL_LOCKING, +	FL_PM_SUSPENDED, +}; +  /* If the erase fails, fail_addr might indicate exactly which block failed.  If     fail_addr = 0xffffffff, the failure was not at the device level or was not     specific to any particular block. */ diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 2993a89e1..7ac72de95 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -213,20 +213,6 @@ typedef enum {  #define NAND_CI_CHIPNR_MSK	0x03  #define NAND_CI_CELLTYPE_MSK	0x0C -/* - * nand_state_t - chip states - * Enumeration for NAND flash chip state - */ -typedef enum { -	FL_READY, -	FL_READING, -	FL_WRITING, -	FL_ERASING, -	FL_SYNCING, -	FL_CACHEDPRG, -	FL_PM_SUSPENDED, -} nand_state_t; -  /* Keep gcc happy */  struct nand_chip; @@ -416,7 +402,7 @@ struct nand_chip {  	uint8_t		cellinfo;  	int		badblockpos; -	nand_state_t	state; +	int 		state;  	uint8_t		*oob_poi;  	struct nand_hw_control  *controller; diff --git a/include/linux/mtd/nand_legacy.h b/include/linux/mtd/nand_legacy.h index b05e7267e..bb66e4547 100644 --- a/include/linux/mtd/nand_legacy.h +++ b/include/linux/mtd/nand_legacy.h @@ -55,18 +55,6 @@  #define NAND_CMD_RESET		0xff  /* - * Enumeration for NAND flash chip state - */ -typedef enum { -	FL_READY, -	FL_READING, -	FL_WRITING, -	FL_ERASING, -	FL_SYNCING -} nand_state_t; - - -/*   * NAND Private Flash Chip Data   *   * Structure overview: diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index 4b0c2dfaa..8a0fd0de9 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h @@ -17,6 +17,7 @@  /* Note: The header order is impoertant */  #include <onenand_uboot.h> +#include <linux/mtd/compat.h>  #include <linux/mtd/bbm.h>  #define MAX_BUFFERRAM		2 @@ -28,20 +29,6 @@ extern int onenand_scan (struct mtd_info *mtd, int max_chips);  extern void onenand_release (struct mtd_info *mtd);  /** - * onenand_state_t - chip states - * Enumeration for OneNAND flash chip state - */ -typedef enum { -	FL_READY, -	FL_READING, -	FL_WRITING, -	FL_ERASING, -	FL_SYNCING, -	FL_UNLOCKING, -	FL_LOCKING, -} onenand_state_t; - -/**   * struct onenand_bufferram - OneNAND BufferRAM Data   * @param block		block address in BufferRAM   * @param page		page address in BufferRAM @@ -103,10 +90,12 @@ struct onenand_chip {  	unsigned short (*read_word) (void __iomem * addr);  	void (*write_word) (unsigned short value, void __iomem * addr);  	void (*mmcontrol) (struct mtd_info * mtd, int sync_read); +	int (*block_markbad)(struct mtd_info *mtd, loff_t ofs); +	int (*scan_bbt)(struct mtd_info *mtd);  	spinlock_t chip_lock;  	wait_queue_head_t wq; -	onenand_state_t state; +	int state;  	struct nand_oobinfo *autooob; |