diff options
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/devices/blkmtd.c | 8 | ||||
-rw-r--r-- | drivers/mtd/onenand/generic.c | 4 | ||||
-rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 53 | ||||
-rw-r--r-- | drivers/mtd/onenand/onenand_bbt.c | 4 |
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 | ||
1347 | static const struct onenand_manufacturers onenand_manuf_ids[] = { | 1349 | static 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 | */ |
1358 | static int onenand_check_maf(int manuf) | 1359 | static 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 | */ |
1575 | void onenand_release(struct mtd_info *mtd) | 1593 | void 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 | ||
1585 | 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 | /** |