diff options
| -rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 27 | ||||
| -rw-r--r-- | drivers/mtd/onenand/onenand_bbt.c | 4 | ||||
| -rw-r--r-- | include/linux/mtd/onenand.h | 4 |
3 files changed, 28 insertions, 7 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index d57afbaaedc4..a53a73fc2a5a 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c | |||
| @@ -940,7 +940,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, | |||
| 940 | u_char *eccbuf, struct nand_oobinfo *oobsel) | 940 | u_char *eccbuf, struct nand_oobinfo *oobsel) |
| 941 | { | 941 | { |
| 942 | struct onenand_chip *this = mtd->priv; | 942 | struct onenand_chip *this = mtd->priv; |
| 943 | unsigned char buffer[MAX_ONENAND_PAGESIZE], *pbuf; | 943 | unsigned char *pbuf; |
| 944 | size_t total_len, len; | 944 | size_t total_len, len; |
| 945 | int i, written = 0; | 945 | int i, written = 0; |
| 946 | int ret = 0; | 946 | int ret = 0; |
| @@ -975,7 +975,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, | |||
| 975 | /* Loop until all keve's data has been written */ | 975 | /* Loop until all keve's data has been written */ |
| 976 | len = 0; | 976 | len = 0; |
| 977 | while (count) { | 977 | while (count) { |
| 978 | pbuf = buffer; | 978 | pbuf = this->page_buf; |
| 979 | /* | 979 | /* |
| 980 | * If the given tuple is >= pagesize then | 980 | * If the given tuple is >= pagesize then |
| 981 | * write it out from the iov | 981 | * write it out from the iov |
| @@ -995,7 +995,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, | |||
| 995 | int cnt = 0, thislen; | 995 | int cnt = 0, thislen; |
| 996 | while (cnt < mtd->oobblock) { | 996 | while (cnt < mtd->oobblock) { |
| 997 | thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len); | 997 | thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len); |
| 998 | memcpy(buffer + cnt, vecs->iov_base + len, thislen); | 998 | memcpy(this->page_buf + cnt, vecs->iov_base + len, thislen); |
| 999 | cnt += thislen; | 999 | cnt += thislen; |
| 1000 | len += thislen; | 1000 | len += thislen; |
| 1001 | 1001 | ||
| @@ -1519,6 +1519,18 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) | |||
| 1519 | this->read_bufferram = onenand_sync_read_bufferram; | 1519 | this->read_bufferram = onenand_sync_read_bufferram; |
| 1520 | } | 1520 | } |
| 1521 | 1521 | ||
| 1522 | /* Allocate buffers, if necessary */ | ||
| 1523 | if (!this->page_buf) { | ||
| 1524 | size_t len; | ||
| 1525 | len = mtd->oobblock + mtd->oobsize; | ||
| 1526 | this->page_buf = kmalloc(len, GFP_KERNEL); | ||
| 1527 | if (!this->page_buf) { | ||
| 1528 | printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n"); | ||
| 1529 | return -ENOMEM; | ||
| 1530 | } | ||
| 1531 | this->options |= ONENAND_PAGEBUF_ALLOC; | ||
| 1532 | } | ||
| 1533 | |||
| 1522 | this->state = FL_READY; | 1534 | this->state = FL_READY; |
| 1523 | init_waitqueue_head(&this->wq); | 1535 | init_waitqueue_head(&this->wq); |
| 1524 | spin_lock_init(&this->chip_lock); | 1536 | spin_lock_init(&this->chip_lock); |
| @@ -1580,12 +1592,21 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) | |||
| 1580 | */ | 1592 | */ |
| 1581 | void onenand_release(struct mtd_info *mtd) | 1593 | void onenand_release(struct mtd_info *mtd) |
| 1582 | { | 1594 | { |
| 1595 | struct onenand_chip *this = mtd->priv; | ||
| 1596 | |||
| 1583 | #ifdef CONFIG_MTD_PARTITIONS | 1597 | #ifdef CONFIG_MTD_PARTITIONS |
| 1584 | /* Deregister partitions */ | 1598 | /* Deregister partitions */ |
| 1585 | del_mtd_partitions (mtd); | 1599 | del_mtd_partitions (mtd); |
| 1586 | #endif | 1600 | #endif |
| 1587 | /* Deregister the device */ | 1601 | /* Deregister the device */ |
| 1588 | del_mtd_device (mtd); | 1602 | del_mtd_device (mtd); |
| 1603 | |||
| 1604 | /* Free bad block table memory, if allocated */ | ||
| 1605 | if (this->bbm) | ||
| 1606 | kfree(this->bbm); | ||
| 1607 | /* Buffer allocated by onenand_scan */ | ||
| 1608 | if (this->options & ONENAND_PAGEBUF_ALLOC) | ||
| 1609 | kfree(this->page_buf); | ||
| 1589 | } | 1610 | } |
| 1590 | 1611 | ||
| 1591 | EXPORT_SYMBOL_GPL(onenand_scan); | 1612 | EXPORT_SYMBOL_GPL(onenand_scan); |
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c index f40190f499e1..4510d3361eaa 100644 --- a/drivers/mtd/onenand/onenand_bbt.c +++ b/drivers/mtd/onenand/onenand_bbt.c | |||
| @@ -118,10 +118,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr | |||
| 118 | */ | 118 | */ |
| 119 | static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) | 119 | static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) |
| 120 | { | 120 | { |
| 121 | unsigned char data_buf[MAX_ONENAND_PAGESIZE]; | 121 | struct onenand_chip *this = mtd->priv; |
| 122 | 122 | ||
| 123 | bd->options &= ~NAND_BBT_SCANEMPTY; | 123 | bd->options &= ~NAND_BBT_SCANEMPTY; |
| 124 | return create_bbt(mtd, data_buf, bd, -1); | 124 | return create_bbt(mtd, this->page_buf, bd, -1); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | /** | 127 | /** |
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index 53423d3b43bf..7419b5fab133 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | #include <linux/mtd/bbm.h> | 17 | #include <linux/mtd/bbm.h> |
| 18 | 18 | ||
| 19 | #define MAX_BUFFERRAM 2 | 19 | #define MAX_BUFFERRAM 2 |
| 20 | #define MAX_ONENAND_PAGESIZE (2048 + 64) | ||
| 21 | 20 | ||
| 22 | /* Scan and identify a OneNAND device */ | 21 | /* Scan and identify a OneNAND device */ |
| 23 | extern int onenand_scan(struct mtd_info *mtd, int max_chips); | 22 | extern int onenand_scan(struct mtd_info *mtd, int max_chips); |
| @@ -110,6 +109,7 @@ struct onenand_chip { | |||
| 110 | spinlock_t chip_lock; | 109 | spinlock_t chip_lock; |
| 111 | wait_queue_head_t wq; | 110 | wait_queue_head_t wq; |
| 112 | onenand_state_t state; | 111 | onenand_state_t state; |
| 112 | unsigned char *page_buf; | ||
| 113 | 113 | ||
| 114 | struct nand_oobinfo *autooob; | 114 | struct nand_oobinfo *autooob; |
| 115 | 115 | ||
| @@ -134,7 +134,7 @@ struct onenand_chip { | |||
| 134 | * Options bits | 134 | * Options bits |
| 135 | */ | 135 | */ |
| 136 | #define ONENAND_CONT_LOCK (0x0001) | 136 | #define ONENAND_CONT_LOCK (0x0001) |
| 137 | 137 | #define ONENAND_PAGEBUF_ALLOC (0x1000) | |
| 138 | 138 | ||
| 139 | /* | 139 | /* |
| 140 | * OneNAND Flash Manufacturer ID Codes | 140 | * OneNAND Flash Manufacturer ID Codes |
