summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyungmin Park <kyungmin.park@samsung.com>2007-02-02 09:29:36 +0900
committerKyungmin Park <kyungmin.park@samsung.com>2007-02-02 09:29:36 +0900
commitabf3c0f23df6686a984efc8fae7277fcdaffaa32 (patch)
tree201f8fe3ecdb62e5aceba15f00a3bdb13da9e683
parent4f4fad27aceb87621d40f3068b94b5b11fc0127b (diff)
[MTD] OneNAND: Reduce internal BufferRAM operations
It use blockpage instead of a pair (block, page). It can also cover a small chunk access. 0x00, 0x20, 0x40 and so on. And in JFFS2 behavior, sometimes it reads two pages alternatively. e.g., It first reads A page, B page and A page. So we check another bufferram to find requested page. Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
-rw-r--r--drivers/mtd/onenand/onenand_base.c47
-rw-r--r--include/linux/mtd/onenand.h8
2 files changed, 25 insertions, 30 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index eb94d9496446..9f4fe73bc129 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -577,19 +577,22 @@ static int onenand_write_bufferram(struct mtd_info *mtd, int area,
static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
{
struct onenand_chip *this = mtd->priv;
- int block, page;
- int i;
+ int blockpage;
+ unsigned int i;
- block = (int) (addr >> this->erase_shift);
- page = (int) (addr >> this->page_shift) & this->page_mask;
+ blockpage = (int) (addr >> this->page_shift);
+ /* Is there valid data? */
i = ONENAND_CURRENT_BUFFERRAM(this);
+ if (this->bufferram[i].blockpage == blockpage)
+ return 1;
- /* Is there valid data? */
- if (this->bufferram[i].block == block &&
- this->bufferram[i].page == page &&
- this->bufferram[i].valid)
+ /* Check another BufferRAM */
+ i = ONENAND_NEXT_BUFFERRAM(this);
+ if (this->bufferram[i].blockpage == blockpage) {
+ ONENAND_SET_NEXT_BUFFERRAM(this);
return 1;
+ }
return 0;
}
@@ -602,30 +605,26 @@ static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
*
* Update BufferRAM information
*/
-static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
+static void onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
int valid)
{
struct onenand_chip *this = mtd->priv;
- int block, page;
- int i;
+ int blockpage;
+ unsigned int i;
- block = (int) (addr >> this->erase_shift);
- page = (int) (addr >> this->page_shift) & this->page_mask;
+ blockpage = (int) (addr >> this->page_shift);
- /* Invalidate BufferRAM */
- for (i = 0; i < MAX_BUFFERRAM; i++) {
- if (this->bufferram[i].block == block &&
- this->bufferram[i].page == page)
- this->bufferram[i].valid = 0;
- }
+ /* Invalidate another BufferRAM */
+ i = ONENAND_NEXT_BUFFERRAM(this);
+ if (this->bufferram[i].blockpage == blockpage) {
+ this->bufferram[i].blockpage = -1;
/* Update BufferRAM */
i = ONENAND_CURRENT_BUFFERRAM(this);
- this->bufferram[i].block = block;
- this->bufferram[i].page = page;
- this->bufferram[i].valid = valid;
-
- return 0;
+ if (valid)
+ this->bufferram[i].blockpage = blockpage;
+ else
+ this->bufferram[i].blockpage = -1;
}
/**
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index a5e6c4bf7af3..d8af8a95e58d 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -42,14 +42,10 @@ typedef enum {
/**
* struct onenand_bufferram - OneNAND BufferRAM Data
- * @block: block address in BufferRAM
- * @page: page address in BufferRAM
- * @valid: valid flag
+ * @blockpage: block & page address in BufferRAM
*/
struct onenand_bufferram {
- int block;
- int page;
- int valid;
+ int blockpage;
};
/**