diff options
| author | Kyungmin Park <kyungmin.park@samsung.com> | 2007-02-01 19:29:36 -0500 |
|---|---|---|
| committer | Kyungmin Park <kyungmin.park@samsung.com> | 2007-02-01 19:29:36 -0500 |
| commit | abf3c0f23df6686a984efc8fae7277fcdaffaa32 (patch) | |
| tree | 201f8fe3ecdb62e5aceba15f00a3bdb13da9e683 | |
| parent | 4f4fad27aceb87621d40f3068b94b5b11fc0127b (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.c | 47 | ||||
| -rw-r--r-- | include/linux/mtd/onenand.h | 8 |
2 files changed, 25 insertions, 30 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index eb94d94964..9f4fe73bc1 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, | |||
| 577 | static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr) | 577 | static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr) |
| 578 | { | 578 | { |
| 579 | struct onenand_chip *this = mtd->priv; | 579 | struct onenand_chip *this = mtd->priv; |
| 580 | int block, page; | 580 | int blockpage; |
| 581 | int i; | 581 | unsigned int i; |
| 582 | 582 | ||
| 583 | block = (int) (addr >> this->erase_shift); | 583 | blockpage = (int) (addr >> this->page_shift); |
| 584 | page = (int) (addr >> this->page_shift) & this->page_mask; | ||
| 585 | 584 | ||
| 585 | /* Is there valid data? */ | ||
| 586 | i = ONENAND_CURRENT_BUFFERRAM(this); | 586 | i = ONENAND_CURRENT_BUFFERRAM(this); |
| 587 | if (this->bufferram[i].blockpage == blockpage) | ||
| 588 | return 1; | ||
| 587 | 589 | ||
| 588 | /* Is there valid data? */ | 590 | /* Check another BufferRAM */ |
| 589 | if (this->bufferram[i].block == block && | 591 | i = ONENAND_NEXT_BUFFERRAM(this); |
| 590 | this->bufferram[i].page == page && | 592 | if (this->bufferram[i].blockpage == blockpage) { |
| 591 | this->bufferram[i].valid) | 593 | ONENAND_SET_NEXT_BUFFERRAM(this); |
| 592 | return 1; | 594 | return 1; |
| 595 | } | ||
| 593 | 596 | ||
| 594 | return 0; | 597 | return 0; |
| 595 | } | 598 | } |
| @@ -602,30 +605,26 @@ static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr) | |||
| 602 | * | 605 | * |
| 603 | * Update BufferRAM information | 606 | * Update BufferRAM information |
| 604 | */ | 607 | */ |
| 605 | static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr, | 608 | static void onenand_update_bufferram(struct mtd_info *mtd, loff_t addr, |
| 606 | int valid) | 609 | int valid) |
| 607 | { | 610 | { |
| 608 | struct onenand_chip *this = mtd->priv; | 611 | struct onenand_chip *this = mtd->priv; |
| 609 | int block, page; | 612 | int blockpage; |
| 610 | int i; | 613 | unsigned int i; |
| 611 | 614 | ||
| 612 | block = (int) (addr >> this->erase_shift); | 615 | blockpage = (int) (addr >> this->page_shift); |
| 613 | page = (int) (addr >> this->page_shift) & this->page_mask; | ||
| 614 | 616 | ||
| 615 | /* Invalidate BufferRAM */ | 617 | /* Invalidate another BufferRAM */ |
| 616 | for (i = 0; i < MAX_BUFFERRAM; i++) { | 618 | i = ONENAND_NEXT_BUFFERRAM(this); |
| 617 | if (this->bufferram[i].block == block && | 619 | if (this->bufferram[i].blockpage == blockpage) { |
| 618 | this->bufferram[i].page == page) | 620 | this->bufferram[i].blockpage = -1; |
| 619 | this->bufferram[i].valid = 0; | ||
| 620 | } | ||
| 621 | 621 | ||
| 622 | /* Update BufferRAM */ | 622 | /* Update BufferRAM */ |
| 623 | i = ONENAND_CURRENT_BUFFERRAM(this); | 623 | i = ONENAND_CURRENT_BUFFERRAM(this); |
| 624 | this->bufferram[i].block = block; | 624 | if (valid) |
| 625 | this->bufferram[i].page = page; | 625 | this->bufferram[i].blockpage = blockpage; |
| 626 | this->bufferram[i].valid = valid; | 626 | else |
| 627 | 627 | this->bufferram[i].blockpage = -1; | |
| 628 | return 0; | ||
| 629 | } | 628 | } |
| 630 | 629 | ||
| 631 | /** | 630 | /** |
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index a5e6c4bf7a..d8af8a95e5 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h | |||
| @@ -42,14 +42,10 @@ typedef enum { | |||
| 42 | 42 | ||
| 43 | /** | 43 | /** |
| 44 | * struct onenand_bufferram - OneNAND BufferRAM Data | 44 | * struct onenand_bufferram - OneNAND BufferRAM Data |
| 45 | * @block: block address in BufferRAM | 45 | * @blockpage: block & page address in BufferRAM |
| 46 | * @page: page address in BufferRAM | ||
| 47 | * @valid: valid flag | ||
| 48 | */ | 46 | */ |
| 49 | struct onenand_bufferram { | 47 | struct onenand_bufferram { |
| 50 | int block; | 48 | int blockpage; |
| 51 | int page; | ||
| 52 | int valid; | ||
| 53 | }; | 49 | }; |
| 54 | 50 | ||
| 55 | /** | 51 | /** |
