by Align with word(16-bit) size as done in Linux in - onenand_read_bufferram - onenand_sync_read_bufferram - onenand_write_bufferram
Signed-off-by: Wolfgang Denk <[EMAIL PROTECTED]> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <[EMAIL PROTECTED]> Cc: Kyungmin Park <[EMAIL PROTECTED]> diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 174384e..d888e48 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -20,19 +20,6 @@ #include <asm/io.h> #include <asm/errno.h> -/* It should access 16-bit instead of 8-bit */ -static inline void *memcpy(void *dst, const void *src, unsigned int len) -{ - void *ret = dst; - short *d = dst; - const short *s = src; - - len >>= 1; - while (len-- > 0) - *d++ = *s++; - return ret; -} - static const unsigned char ffchars[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 */ @@ -358,6 +345,17 @@ static int onenand_read_bufferram(struct mtd_info *mtd, int area, bufferram = this->base + area; bufferram += onenand_bufferram_offset(mtd, area); + if (ONENAND_CHECK_BYTE_ACCESS(count)) { + unsigned short word; + + /* Align with word(16-bit) size */ + count--; + + /* Read word and save byte */ + word = this->read_word(bufferram + offset + count); + buffer[count] = (word & 0xff); + } + memcpy(buffer, bufferram + offset, count); return 0; @@ -385,6 +383,17 @@ static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area, this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ); + if (ONENAND_CHECK_BYTE_ACCESS(count)) { + unsigned short word; + + /* Align with word(16-bit) size */ + count--; + + /* Read word and save byte */ + word = this->read_word(bufferram + offset + count); + buffer[count] = (word & 0xff); + } + memcpy(buffer, bufferram + offset, count); this->mmcontrol(mtd, 0); @@ -412,6 +421,22 @@ static int onenand_write_bufferram(struct mtd_info *mtd, int area, bufferram = this->base + area; bufferram += onenand_bufferram_offset(mtd, area); + if (ONENAND_CHECK_BYTE_ACCESS(count)) { + unsigned short word; + int byte_offset; + + /* Align with word(16-bit) size */ + count--; + + /* Calculate byte access offset */ + byte_offset = offset + count; + + /* Read word and save byte */ + word = this->read_word(bufferram + byte_offset); + word = (word & ~0xff) | buffer[count]; + this->write_word(word, bufferram + byte_offset); + } + memcpy(bufferram + offset, buffer, count); return 0; diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index 4b0c2df..e959de4 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h @@ -119,6 +119,9 @@ struct onenand_chip { #define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1) #define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1) +/* Check byte access in OneNAND */ +#define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1) + /* * Options bits */ -- 1.5.4.5 ------------------------------------------------------------------------- This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2. http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone _______________________________________________ U-Boot-Users mailing list U-Boot-Users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/u-boot-users