summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyungmin Park <kyungmin.park@samsung.com>2006-05-12 17:02:31 +0300
committerJarkko Lavinen <lavinen@pentafluge.infradead.org>2006-05-12 15:35:45 +0100
commit9c01f87db183403a4f603fe5180c57b82b54b4a1 (patch)
tree74da95f8e772be1130296a1bfb31302f89737769
parent628bee6593107c466e28462f58c5fd5cd4163c7c (diff)
OneNAND: handle byte access on BufferRAM
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
-rw-r--r--drivers/mtd/onenand/onenand_base.c38
-rw-r--r--include/linux/mtd/onenand.h3
2 files changed, 41 insertions, 0 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index d6c13f7ae5a1..1439c9fa1d23 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -373,6 +373,17 @@ static int onenand_read_bufferram(struct mtd_info *mtd, int 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;
@@ -400,6 +411,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);
@@ -427,6 +449,22 @@ static int onenand_write_bufferram(struct mtd_info *mtd, int 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 7419b5fab133..22322c8a7729 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -130,6 +130,9 @@ struct onenand_chip {
#define ONENAND_SET_SYS_CFG1(v, this) \
(this->write_word(v, this->base + ONENAND_REG_SYS_CFG1))
+/* Check byte access in OneNAND */
+#define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1)
+
/*
* Options bits
*/