diff options
| author | Stefan Roese <sr@denx.de> | 2008-12-02 11:06:47 +0100 | 
|---|---|---|
| committer | Scott Wood <scottwood@freescale.com> | 2009-01-23 10:32:48 -0600 | 
| commit | 1ae39862044ebb1e682234b51f94421e3f871d6a (patch) | |
| tree | bc16379a4c30fcac163991fdb20b3dfbe9c48f6d | |
| parent | 1714f51a2009baaecf3d4f6e3bd8c4e93a8d3f23 (diff) | |
| download | olio-uboot-2014.01-1ae39862044ebb1e682234b51f94421e3f871d6a.tar.xz olio-uboot-2014.01-1ae39862044ebb1e682234b51f94421e3f871d6a.zip  | |
OneNAND: Additional sync with 2.6.27
- Add subpage write support
- Add onenand_oob_64/32 ecclayout
This has been missing and without it UBI has some incompatibilies issues
with the current (>= 2.6.27) Linux kernel version. vid_hdr_offset is
placed differently (2048 instead of 512) without this fix.
Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Scott Wood <scottwood@freescale.com>
| -rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 72 | ||||
| -rw-r--r-- | include/linux/mtd/onenand.h | 1 | 
2 files changed, 72 insertions, 1 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index dcc969ff7..d482437a4 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -36,6 +36,35 @@ static inline void *memcpy_16(void *dst, const void *src, unsigned int len)  	return ret;  } +/** + * onenand_oob_64 - oob info for large (2KB) page + */ +static struct nand_ecclayout onenand_oob_64 = { +	.eccbytes	= 20, +	.eccpos		= { +		8, 9, 10, 11, 12, +		24, 25, 26, 27, 28, +		40, 41, 42, 43, 44, +		56, 57, 58, 59, 60, +		}, +	.oobfree	= { +		{2, 3}, {14, 2}, {18, 3}, {30, 2}, +		{34, 3}, {46, 2}, {50, 3}, {62, 2} +	} +}; + +/** + * onenand_oob_32 - oob info for middle (1KB) page + */ +static struct nand_ecclayout onenand_oob_32 = { +	.eccbytes	= 10, +	.eccpos		= { +		8, 9, 10, 11, 12, +		24, 25, 26, 27, 28, +		}, +	.oobfree	= { {2, 3}, {14, 2}, {18, 3}, {30, 2} } +}; +  static const unsigned char ffchars[] = {  	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,	/* 16 */ @@ -1079,7 +1108,7 @@ static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr,  #define onenand_verify_oob(...)         (0)  #endif -#define NOTALIGNED(x)	((x & (mtd->writesize - 1)) != 0) +#define NOTALIGNED(x)	((x & (this->subpagesize - 1)) != 0)  /**   * onenand_fill_auto_oob - [Internal] oob auto-placement transfer @@ -2058,6 +2087,7 @@ static int onenand_probe(struct mtd_info *mtd)   */  int onenand_scan(struct mtd_info *mtd, int maxchips)  { +	int i;  	struct onenand_chip *this = mtd->priv;  	if (!this->read_word) @@ -2115,6 +2145,46 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)  		this->options |= ONENAND_OOBBUF_ALLOC;  	} +	this->state = FL_READY; + +	/* +	 * Allow subpage writes up to oobsize. +	 */ +	switch (mtd->oobsize) { +	case 64: +		this->ecclayout = &onenand_oob_64; +		mtd->subpage_sft = 2; +		break; + +	case 32: +		this->ecclayout = &onenand_oob_32; +		mtd->subpage_sft = 1; +		break; + +	default: +		printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n", +			mtd->oobsize); +		mtd->subpage_sft = 0; +		/* To prevent kernel oops */ +		this->ecclayout = &onenand_oob_32; +		break; +	} + +	this->subpagesize = mtd->writesize >> mtd->subpage_sft; + +	/* +	 * The number of bytes available for a client to place data into +	 * the out of band area +	 */ +	this->ecclayout->oobavail = 0; +	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && +	    this->ecclayout->oobfree[i].length; i++) +		this->ecclayout->oobavail += +			this->ecclayout->oobfree[i].length; +	mtd->oobavail = this->ecclayout->oobavail; + +	mtd->ecclayout = this->ecclayout; +  	/* Unlock whole block */  	onenand_unlock_all(mtd); diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index 7547e96e7..2597e347b 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h @@ -107,6 +107,7 @@ struct onenand_chip {  	unsigned char		*oob_buf;  	struct nand_oobinfo *autooob; +	int			subpagesize;  	struct nand_ecclayout	*ecclayout;  	void *bbm;  |