aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/onenand/onenand_base.c27
-rw-r--r--drivers/mtd/onenand/onenand_bbt.c4
-rw-r--r--include/linux/mtd/onenand.h4
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 */
1581void onenand_release(struct mtd_info *mtd) 1593void 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
1591EXPORT_SYMBOL_GPL(onenand_scan); 1612EXPORT_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 */
119static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) 119static 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 */
23extern int onenand_scan(struct mtd_info *mtd, int max_chips); 22extern 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