aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyungmin Park <kyungmin.park@samsung.com>2006-05-12 10:02:31 -0400
committerJarkko Lavinen <lavinen@pentafluge.infradead.org>2006-05-12 10:35:45 -0400
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,
373 373
374 bufferram += onenand_bufferram_offset(mtd, area); 374 bufferram += onenand_bufferram_offset(mtd, area);
375 375
376 if (ONENAND_CHECK_BYTE_ACCESS(count)) {
377 unsigned short word;
378
379 /* Align with word(16-bit) size */
380 count--;
381
382 /* Read word and save byte */
383 word = this->read_word(bufferram + offset + count);
384 buffer[count] = (word & 0xff);
385 }
386
376 memcpy(buffer, bufferram + offset, count); 387 memcpy(buffer, bufferram + offset, count);
377 388
378 return 0; 389 return 0;
@@ -400,6 +411,17 @@ static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
400 411
401 this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ); 412 this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
402 413
414 if (ONENAND_CHECK_BYTE_ACCESS(count)) {
415 unsigned short word;
416
417 /* Align with word(16-bit) size */
418 count--;
419
420 /* Read word and save byte */
421 word = this->read_word(bufferram + offset + count);
422 buffer[count] = (word & 0xff);
423 }
424
403 memcpy(buffer, bufferram + offset, count); 425 memcpy(buffer, bufferram + offset, count);
404 426
405 this->mmcontrol(mtd, 0); 427 this->mmcontrol(mtd, 0);
@@ -427,6 +449,22 @@ static int onenand_write_bufferram(struct mtd_info *mtd, int area,
427 449
428 bufferram += onenand_bufferram_offset(mtd, area); 450 bufferram += onenand_bufferram_offset(mtd, area);
429 451
452 if (ONENAND_CHECK_BYTE_ACCESS(count)) {
453 unsigned short word;
454 int byte_offset;
455
456 /* Align with word(16-bit) size */
457 count--;
458
459 /* Calculate byte access offset */
460 byte_offset = offset + count;
461
462 /* Read word and save byte */
463 word = this->read_word(bufferram + byte_offset);
464 word = (word & ~0xff) | buffer[count];
465 this->write_word(word, bufferram + byte_offset);
466 }
467
430 memcpy(bufferram + offset, buffer, count); 468 memcpy(bufferram + offset, buffer, count);
431 469
432 return 0; 470 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 {
130#define ONENAND_SET_SYS_CFG1(v, this) \ 130#define ONENAND_SET_SYS_CFG1(v, this) \
131 (this->write_word(v, this->base + ONENAND_REG_SYS_CFG1)) 131 (this->write_word(v, this->base + ONENAND_REG_SYS_CFG1))
132 132
133/* Check byte access in OneNAND */
134#define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1)
135
133/* 136/*
134 * Options bits 137 * Options bits
135 */ 138 */