aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/devices/blkmtd.c8
-rw-r--r--drivers/mtd/onenand/generic.c4
-rw-r--r--drivers/mtd/onenand/onenand_base.c53
-rw-r--r--drivers/mtd/onenand/onenand_bbt.c4
4 files changed, 48 insertions, 21 deletions
diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
index f9db52f6bf00..04f864d238db 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
113 ClearPageUptodate(page); 113 ClearPageUptodate(page);
114 SetPageError(page); 114 SetPageError(page);
115 } 115 }
116 ClearPageDirty(page); 116 clear_page_dirty(page);
117 unlock_page(page); 117 unlock_page(page);
118 page_cache_release(page); 118 page_cache_release(page);
119 } while (bvec >= bio->bi_io_vec); 119 } 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,
289 BUG(); 289 BUG();
290 } 290 }
291 memcpy(page_address(page)+offset, buf, start_len); 291 memcpy(page_address(page)+offset, buf, start_len);
292 SetPageDirty(page); 292 set_page_dirty(page);
293 SetPageUptodate(page); 293 SetPageUptodate(page);
294 buf += start_len; 294 buf += start_len;
295 thislen = start_len; 295 thislen = start_len;
@@ -336,7 +336,7 @@ static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to,
336 } 336 }
337 pagenr++; 337 pagenr++;
338 pagecnt--; 338 pagecnt--;
339 SetPageDirty(page); 339 set_page_dirty(page);
340 SetPageUptodate(page); 340 SetPageUptodate(page);
341 pagesc--; 341 pagesc--;
342 thislen += PAGE_SIZE; 342 thislen += PAGE_SIZE;
@@ -357,7 +357,7 @@ static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to,
357 BUG(); 357 BUG();
358 } 358 }
359 memcpy(page_address(page), buf, end_len); 359 memcpy(page_address(page), buf, end_len);
360 SetPageDirty(page); 360 set_page_dirty(page);
361 SetPageUptodate(page); 361 SetPageUptodate(page);
362 DEBUG(3, "blkmtd: write: writing out partial end\n"); 362 DEBUG(3, "blkmtd: write: writing out partial end\n");
363 thislen += end_len; 363 thislen += end_len;
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
index 48cce431f89f..45c077d0f063 100644
--- a/drivers/mtd/onenand/generic.c
+++ b/drivers/mtd/onenand/generic.c
@@ -12,9 +12,9 @@
12 * This is a device driver for the OneNAND flash for generic boards. 12 * This is a device driver for the OneNAND flash for generic boards.
13 */ 13 */
14 14
15#include <linux/device.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/mtd/mtd.h> 18#include <linux/mtd/mtd.h>
19#include <linux/mtd/onenand.h> 19#include <linux/mtd/onenand.h>
20#include <linux/mtd/partitions.h> 20#include <linux/mtd/partitions.h>
@@ -39,7 +39,7 @@ static int __devinit generic_onenand_probe(struct device *dev)
39{ 39{
40 struct onenand_info *info; 40 struct onenand_info *info;
41 struct platform_device *pdev = to_platform_device(dev); 41 struct platform_device *pdev = to_platform_device(dev);
42 struct onenand_platform_data *pdata = pdev->dev.platform_data; 42 struct flash_platform_data *pdata = pdev->dev.platform_data;
43 struct resource *res = pdev->resource; 43 struct resource *res = pdev->resource;
44 unsigned long size = res->end - res->start + 1; 44 unsigned long size = res->end - res->start + 1;
45 int err; 45 int err;
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index f67d5d6eb9a6..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
@@ -1296,6 +1296,12 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1296 1296
1297 /* Block lock scheme */ 1297 /* Block lock scheme */
1298 for (block = start; block < end; block++) { 1298 for (block = start; block < end; block++) {
1299 /* Set block address */
1300 value = onenand_block_address(this, block);
1301 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
1302 /* Select DataRAM for DDP */
1303 value = onenand_bufferram_address(this, block);
1304 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
1299 /* Set start block address */ 1305 /* Set start block address */
1300 this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS); 1306 this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1301 /* Write unlock command */ 1307 /* Write unlock command */
@@ -1309,10 +1315,6 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1309 & ONENAND_CTRL_ONGO) 1315 & ONENAND_CTRL_ONGO)
1310 continue; 1316 continue;
1311 1317
1312 /* Set block address for read block status */
1313 value = onenand_block_address(this, block);
1314 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
1315
1316 /* Check lock status */ 1318 /* Check lock status */
1317 status = this->read_word(this->base + ONENAND_REG_WP_STATUS); 1319 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1318 if (!(status & ONENAND_WP_US)) 1320 if (!(status & ONENAND_WP_US))
@@ -1346,7 +1348,6 @@ static void onenand_print_device_info(int device)
1346 1348
1347static const struct onenand_manufacturers onenand_manuf_ids[] = { 1349static const struct onenand_manufacturers onenand_manuf_ids[] = {
1348 {ONENAND_MFR_SAMSUNG, "Samsung"}, 1350 {ONENAND_MFR_SAMSUNG, "Samsung"},
1349 {ONENAND_MFR_UNKNOWN, "Unknown"}
1350}; 1351};
1351 1352
1352/** 1353/**
@@ -1357,17 +1358,22 @@ static const struct onenand_manufacturers onenand_manuf_ids[] = {
1357 */ 1358 */
1358static int onenand_check_maf(int manuf) 1359static int onenand_check_maf(int manuf)
1359{ 1360{
1361 int size = ARRAY_SIZE(onenand_manuf_ids);
1362 char *name;
1360 int i; 1363 int i;
1361 1364
1362 for (i = 0; onenand_manuf_ids[i].id; i++) { 1365 for (i = 0; i < size; i++)
1363 if (manuf == onenand_manuf_ids[i].id) 1366 if (manuf == onenand_manuf_ids[i].id)
1364 break; 1367 break;
1365 }
1366 1368
1367 printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", 1369 if (i < size)
1368 onenand_manuf_ids[i].name, manuf); 1370 name = onenand_manuf_ids[i].name;
1371 else
1372 name = "Unknown";
1373
1374 printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", name, manuf);
1369 1375
1370 return (i != ONENAND_MFR_UNKNOWN); 1376 return (i == size);
1371} 1377}
1372 1378
1373/** 1379/**
@@ -1513,6 +1519,18 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
1513 this->read_bufferram = onenand_sync_read_bufferram; 1519 this->read_bufferram = onenand_sync_read_bufferram;
1514 } 1520 }
1515 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
1516 this->state = FL_READY; 1534 this->state = FL_READY;
1517 init_waitqueue_head(&this->wq); 1535 init_waitqueue_head(&this->wq);
1518 spin_lock_init(&this->chip_lock); 1536 spin_lock_init(&this->chip_lock);
@@ -1574,12 +1592,21 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
1574 */ 1592 */
1575void onenand_release(struct mtd_info *mtd) 1593void onenand_release(struct mtd_info *mtd)
1576{ 1594{
1595 struct onenand_chip *this = mtd->priv;
1596
1577#ifdef CONFIG_MTD_PARTITIONS 1597#ifdef CONFIG_MTD_PARTITIONS
1578 /* Deregister partitions */ 1598 /* Deregister partitions */
1579 del_mtd_partitions (mtd); 1599 del_mtd_partitions (mtd);
1580#endif 1600#endif
1581 /* Deregister the device */ 1601 /* Deregister the device */
1582 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);
1583} 1610}
1584 1611
1585EXPORT_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/**