Commit 532a37cf authored by Kyungmin Park's avatar Kyungmin Park Committed by Linus Torvalds

[PATCH] mtd onenand driver: reduce stack usage

Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 20ba89a3
...@@ -940,7 +940,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, ...@@ -940,7 +940,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
u_char *eccbuf, struct nand_oobinfo *oobsel) u_char *eccbuf, struct nand_oobinfo *oobsel)
{ {
struct onenand_chip *this = mtd->priv; struct onenand_chip *this = mtd->priv;
unsigned char buffer[MAX_ONENAND_PAGESIZE], *pbuf; unsigned char *pbuf;
size_t total_len, len; size_t total_len, len;
int i, written = 0; int i, written = 0;
int ret = 0; int ret = 0;
...@@ -975,7 +975,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, ...@@ -975,7 +975,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
/* Loop until all keve's data has been written */ /* Loop until all keve's data has been written */
len = 0; len = 0;
while (count) { while (count) {
pbuf = buffer; pbuf = this->page_buf;
/* /*
* If the given tuple is >= pagesize then * If the given tuple is >= pagesize then
* write it out from the iov * write it out from the iov
...@@ -995,7 +995,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, ...@@ -995,7 +995,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
int cnt = 0, thislen; int cnt = 0, thislen;
while (cnt < mtd->oobblock) { while (cnt < mtd->oobblock) {
thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len); thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len);
memcpy(buffer + cnt, vecs->iov_base + len, thislen); memcpy(this->page_buf + cnt, vecs->iov_base + len, thislen);
cnt += thislen; cnt += thislen;
len += thislen; len += thislen;
...@@ -1519,6 +1519,18 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) ...@@ -1519,6 +1519,18 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
this->read_bufferram = onenand_sync_read_bufferram; this->read_bufferram = onenand_sync_read_bufferram;
} }
/* Allocate buffers, if necessary */
if (!this->page_buf) {
size_t len;
len = mtd->oobblock + mtd->oobsize;
this->page_buf = kmalloc(len, GFP_KERNEL);
if (!this->page_buf) {
printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
return -ENOMEM;
}
this->options |= ONENAND_PAGEBUF_ALLOC;
}
this->state = FL_READY; this->state = FL_READY;
init_waitqueue_head(&this->wq); init_waitqueue_head(&this->wq);
spin_lock_init(&this->chip_lock); spin_lock_init(&this->chip_lock);
...@@ -1580,12 +1592,21 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) ...@@ -1580,12 +1592,21 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
*/ */
void onenand_release(struct mtd_info *mtd) void onenand_release(struct mtd_info *mtd)
{ {
struct onenand_chip *this = mtd->priv;
#ifdef CONFIG_MTD_PARTITIONS #ifdef CONFIG_MTD_PARTITIONS
/* Deregister partitions */ /* Deregister partitions */
del_mtd_partitions (mtd); del_mtd_partitions (mtd);
#endif #endif
/* Deregister the device */ /* Deregister the device */
del_mtd_device (mtd); del_mtd_device (mtd);
/* Free bad block table memory, if allocated */
if (this->bbm)
kfree(this->bbm);
/* Buffer allocated by onenand_scan */
if (this->options & ONENAND_PAGEBUF_ALLOC)
kfree(this->page_buf);
} }
EXPORT_SYMBOL_GPL(onenand_scan); EXPORT_SYMBOL_GPL(onenand_scan);
......
...@@ -118,10 +118,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr ...@@ -118,10 +118,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
*/ */
static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
{ {
unsigned char data_buf[MAX_ONENAND_PAGESIZE]; struct onenand_chip *this = mtd->priv;
bd->options &= ~NAND_BBT_SCANEMPTY; bd->options &= ~NAND_BBT_SCANEMPTY;
return create_bbt(mtd, data_buf, bd, -1); return create_bbt(mtd, this->page_buf, bd, -1);
} }
/** /**
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include <linux/mtd/bbm.h> #include <linux/mtd/bbm.h>
#define MAX_BUFFERRAM 2 #define MAX_BUFFERRAM 2
#define MAX_ONENAND_PAGESIZE (2048 + 64)
/* Scan and identify a OneNAND device */ /* Scan and identify a OneNAND device */
extern int onenand_scan(struct mtd_info *mtd, int max_chips); extern int onenand_scan(struct mtd_info *mtd, int max_chips);
...@@ -110,6 +109,7 @@ struct onenand_chip { ...@@ -110,6 +109,7 @@ struct onenand_chip {
spinlock_t chip_lock; spinlock_t chip_lock;
wait_queue_head_t wq; wait_queue_head_t wq;
onenand_state_t state; onenand_state_t state;
unsigned char *page_buf;
struct nand_oobinfo *autooob; struct nand_oobinfo *autooob;
...@@ -134,7 +134,7 @@ struct onenand_chip { ...@@ -134,7 +134,7 @@ struct onenand_chip {
* Options bits * Options bits
*/ */
#define ONENAND_CONT_LOCK (0x0001) #define ONENAND_CONT_LOCK (0x0001)
#define ONENAND_PAGEBUF_ALLOC (0x1000)
/* /*
* OneNAND Flash Manufacturer ID Codes * OneNAND Flash Manufacturer ID Codes
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment