From 3fe968f167975d10c639f03c4934f05a29da73c0 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 12 Dec 2005 00:36:59 -0800 Subject: [PATCH] blkmtd: use clear_page_dirty() SetPageDirty() and ClearPageDirty() are low-level thing which filesystems shouldn't be using. They bypass dirty page accounting. Cc: David Woodhouse Acked-by: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mtd/devices/blkmtd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c index f9db52f6bf0..04f864d238d 100644 --- a/drivers/mtd/devices/blkmtd.c +++ b/drivers/mtd/devices/blkmtd.c @@ -113,7 +113,7 @@ static int bi_write_complete(struct bio *bio, unsigned int bytes_done, int error ClearPageUptodate(page); SetPageError(page); } - ClearPageDirty(page); + clear_page_dirty(page); unlock_page(page); page_cache_release(page); } while (bvec >= bio->bi_io_vec); @@ -289,7 +289,7 @@ static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to, BUG(); } memcpy(page_address(page)+offset, buf, start_len); - SetPageDirty(page); + set_page_dirty(page); SetPageUptodate(page); buf += start_len; thislen = start_len; @@ -336,7 +336,7 @@ static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to, } pagenr++; pagecnt--; - SetPageDirty(page); + set_page_dirty(page); SetPageUptodate(page); pagesc--; thislen += PAGE_SIZE; @@ -357,7 +357,7 @@ static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to, BUG(); } memcpy(page_address(page), buf, end_len); - SetPageDirty(page); + set_page_dirty(page); SetPageUptodate(page); DEBUG(3, "blkmtd: write: writing out partial end\n"); thislen += end_len; -- cgit v1.2.3 From 37b1cc3910f7976369fc0ed55068a686e92555e6 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Fri, 16 Dec 2005 11:17:29 +0900 Subject: [PATCH] mtd onenand driver: check correct manufacturer This (and the three subsequent patches) is working well on OMAP H4 with 2.6.15-rc4 kernel and passes the LTP fs test. Signed-off-by: Linus Torvalds --- drivers/mtd/onenand/onenand_base.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index f67d5d6eb9a..33d6f5c2e05 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -1346,7 +1346,6 @@ static void onenand_print_device_info(int device) static const struct onenand_manufacturers onenand_manuf_ids[] = { {ONENAND_MFR_SAMSUNG, "Samsung"}, - {ONENAND_MFR_UNKNOWN, "Unknown"} }; /** @@ -1357,17 +1356,22 @@ static const struct onenand_manufacturers onenand_manuf_ids[] = { */ static int onenand_check_maf(int manuf) { + int size = ARRAY_SIZE(onenand_manuf_ids); + char *name; int i; - for (i = 0; onenand_manuf_ids[i].id; i++) { + for (i = 0; i < size; i++) if (manuf == onenand_manuf_ids[i].id) break; - } - printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", - onenand_manuf_ids[i].name, manuf); + if (i < size) + name = onenand_manuf_ids[i].name; + else + name = "Unknown"; + + printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", name, manuf); - return (i != ONENAND_MFR_UNKNOWN); + return (i == size); } /** -- cgit v1.2.3 From 20ba89a3614bbc5d111fd74375e14c577859b2a3 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Fri, 16 Dec 2005 11:17:29 +0900 Subject: [PATCH] mtd onenand driver: fix unlock problem in DDP --- drivers/mtd/onenand/onenand_base.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 33d6f5c2e05..d57afbaaedc 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -1296,6 +1296,12 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) /* Block lock scheme */ for (block = start; block < end; block++) { + /* Set block address */ + value = onenand_block_address(this, block); + this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); + /* Select DataRAM for DDP */ + value = onenand_bufferram_address(this, block); + this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); /* Set start block address */ this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS); /* Write unlock command */ @@ -1309,10 +1315,6 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) & ONENAND_CTRL_ONGO) continue; - /* Set block address for read block status */ - value = onenand_block_address(this, block); - this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); - /* Check lock status */ status = this->read_word(this->base + ONENAND_REG_WP_STATUS); if (!(status & ONENAND_WP_US)) -- cgit v1.2.3 From 532a37cf8d05dd1aa5631be836036204b0d2b4a1 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Fri, 16 Dec 2005 11:17:29 +0900 Subject: [PATCH] mtd onenand driver: reduce stack usage Signed-off-by: Linus Torvalds --- drivers/mtd/onenand/onenand_base.c | 27 ++++++++++++++++++++++++--- drivers/mtd/onenand/onenand_bbt.c | 4 ++-- 2 files changed, 26 insertions(+), 5 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index d57afbaaedc..a53a73fc2a5 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, u_char *eccbuf, struct nand_oobinfo *oobsel) { struct onenand_chip *this = mtd->priv; - unsigned char buffer[MAX_ONENAND_PAGESIZE], *pbuf; + unsigned char *pbuf; size_t total_len, len; int i, written = 0; int ret = 0; @@ -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 */ len = 0; while (count) { - pbuf = buffer; + pbuf = this->page_buf; /* * If the given tuple is >= pagesize then * write it out from the iov @@ -995,7 +995,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, int cnt = 0, thislen; while (cnt < mtd->oobblock) { 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; len += thislen; @@ -1519,6 +1519,18 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) 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; init_waitqueue_head(&this->wq); spin_lock_init(&this->chip_lock); @@ -1580,12 +1592,21 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) */ void onenand_release(struct mtd_info *mtd) { + struct onenand_chip *this = mtd->priv; + #ifdef CONFIG_MTD_PARTITIONS /* Deregister partitions */ del_mtd_partitions (mtd); #endif /* Deregister the device */ 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); diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c index f40190f499e..4510d3361ea 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 */ 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; - return create_bbt(mtd, data_buf, bd, -1); + return create_bbt(mtd, this->page_buf, bd, -1); } /** -- cgit v1.2.3 From 27f4e0834746196f219e3e030ca71ffd3b176483 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Fri, 16 Dec 2005 11:17:29 +0900 Subject: [PATCH] mtd onenand driver: use platform_device.h instead device.h Signed-off-by: Linus Torvalds --- drivers/mtd/onenand/generic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c index 48cce431f89..45c077d0f06 100644 --- a/drivers/mtd/onenand/generic.c +++ b/drivers/mtd/onenand/generic.c @@ -12,9 +12,9 @@ * This is a device driver for the OneNAND flash for generic boards. */ -#include #include #include +#include #include #include #include @@ -39,7 +39,7 @@ static int __devinit generic_onenand_probe(struct device *dev) { struct onenand_info *info; struct platform_device *pdev = to_platform_device(dev); - struct onenand_platform_data *pdata = pdev->dev.platform_data; + struct flash_platform_data *pdata = pdev->dev.platform_data; struct resource *res = pdev->resource; unsigned long size = res->end - res->start + 1; int err; -- cgit v1.2.3