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
[email protected]
https://lists.sourceforge.net/lists/listinfo/u-boot-users