diff options
author | Kyungmin Park <kyungmin.park@samsung.com> | 2006-05-12 17:02:31 +0300 |
---|---|---|
committer | Jarkko Lavinen <lavinen@pentafluge.infradead.org> | 2006-05-12 15:35:45 +0100 |
commit | 9c01f87db183403a4f603fe5180c57b82b54b4a1 (patch) | |
tree | 74da95f8e772be1130296a1bfb31302f89737769 | |
parent | 628bee6593107c466e28462f58c5fd5cd4163c7c (diff) | |
download | op-kernel-dev-9c01f87db183403a4f603fe5180c57b82b54b4a1.zip op-kernel-dev-9c01f87db183403a4f603fe5180c57b82b54b4a1.tar.gz |
OneNAND: handle byte access on BufferRAM
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
-rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 38 | ||||
-rw-r--r-- | include/linux/mtd/onenand.h | 3 |
2 files changed, 41 insertions, 0 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index d6c13f7..1439c9f 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 7419b5f..22322c8 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 */ |