diff options
Diffstat (limited to 'drivers/mtd/devices')
-rw-r--r-- | drivers/mtd/devices/block2mtd.c | 7 | ||||
-rw-r--r-- | drivers/mtd/devices/docg3.c | 56 | ||||
-rw-r--r-- | drivers/mtd/devices/m25p80.c | 5 | ||||
-rw-r--r-- | drivers/mtd/devices/spear_smi.c | 14 |
4 files changed, 47 insertions, 35 deletions
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index a4a80b742e6..681e2ee0f2d 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -52,8 +52,6 @@ static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len) while (pages) { page = page_read(mapping, index); - if (!page) - return -ENOMEM; if (IS_ERR(page)) return PTR_ERR(page); @@ -112,8 +110,6 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len, len = len - cpylen; page = page_read(dev->blkdev->bd_inode->i_mapping, index); - if (!page) - return -ENOMEM; if (IS_ERR(page)) return PTR_ERR(page); @@ -148,8 +144,6 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf, len = len - cpylen; page = page_read(mapping, index); - if (!page) - return -ENOMEM; if (IS_ERR(page)) return PTR_ERR(page); @@ -271,7 +265,6 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) dev->mtd.flags = MTD_CAP_RAM; dev->mtd._erase = block2mtd_erase; dev->mtd._write = block2mtd_write; - dev->mtd._writev = mtd_writev; dev->mtd._sync = block2mtd_sync; dev->mtd._read = block2mtd_read; dev->mtd.priv = dev; diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 8272c02668d..f70854d728f 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -227,7 +227,7 @@ static void doc_read_data_area(struct docg3 *docg3, void *buf, int len, u8 data8, *dst8; doc_dbg("doc_read_data_area(buf=%p, len=%d)\n", buf, len); - cdr = len & 0x3; + cdr = len & 0x1; len4 = len - cdr; if (first) @@ -383,7 +383,7 @@ static void doc_set_device_id(struct docg3 *docg3, int id) * leveling counters are stored. To access this last area of 4 bytes, a special * mode must be input to the flash ASIC. * - * Returns 0 if no error occured, -EIO else. + * Returns 0 if no error occurred, -EIO else. */ static int doc_set_extra_page_mode(struct docg3 *docg3) { @@ -681,7 +681,7 @@ out: * - one read of 512 bytes at offset 0 * - one read of 512 bytes at offset 512 + 16 * - * Returns 0 if successful, -EIO if a read error occured. + * Returns 0 if successful, -EIO if a read error occurred. */ static int doc_read_page_prepare(struct docg3 *docg3, int block0, int block1, int page, int offset) @@ -732,12 +732,24 @@ err: * @len: the number of bytes to be read (must be a multiple of 4) * @buf: the buffer to be filled in (or NULL is forget bytes) * @first: 1 if first time read, DOC_READADDRESS should be set + * @last_odd: 1 if last read ended up on an odd byte + * + * Reads bytes from a prepared page. There is a trickery here : if the last read + * ended up on an odd offset in the 1024 bytes double page, ie. between the 2 + * planes, the first byte must be read apart. If a word (16bit) read was used, + * the read would return the byte of plane 2 as low *and* high endian, which + * will mess the read. * */ static int doc_read_page_getbytes(struct docg3 *docg3, int len, u_char *buf, - int first) + int first, int last_odd) { - doc_read_data_area(docg3, buf, len, first); + if (last_odd && len > 0) { + doc_read_data_area(docg3, buf, 1, first); + doc_read_data_area(docg3, buf ? buf + 1 : buf, len - 1, 0); + } else { + doc_read_data_area(docg3, buf, len, first); + } doc_delay(docg3, 2); return len; } @@ -839,7 +851,7 @@ static void calc_block_sector(loff_t from, int *block0, int *block1, int *page, * * Reads flash memory OOB area of pages. * - * Returns 0 if read successfull, of -EIO, -EINVAL if an error occured + * Returns 0 if read successful, of -EIO, -EINVAL if an error occurred */ static int doc_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) @@ -850,6 +862,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, u8 *buf = ops->datbuf; size_t len, ooblen, nbdata, nboob; u8 hwecc[DOC_ECC_BCH_SIZE], eccconf1; + int max_bitflips = 0; if (buf) len = ops->len; @@ -876,7 +889,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, ret = 0; skip = from % DOC_LAYOUT_PAGE_SIZE; mutex_lock(&docg3->cascade->lock); - while (!ret && (len > 0 || ooblen > 0)) { + while (ret >= 0 && (len > 0 || ooblen > 0)) { calc_block_sector(from - skip, &block0, &block1, &page, &ofs, docg3->reliable); nbdata = min_t(size_t, len, DOC_LAYOUT_PAGE_SIZE - skip); @@ -887,20 +900,20 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, ret = doc_read_page_ecc_init(docg3, DOC_ECC_BCH_TOTAL_BYTES); if (ret < 0) goto err_in_read; - ret = doc_read_page_getbytes(docg3, skip, NULL, 1); + ret = doc_read_page_getbytes(docg3, skip, NULL, 1, 0); if (ret < skip) goto err_in_read; - ret = doc_read_page_getbytes(docg3, nbdata, buf, 0); + ret = doc_read_page_getbytes(docg3, nbdata, buf, 0, skip % 2); if (ret < nbdata) goto err_in_read; doc_read_page_getbytes(docg3, DOC_LAYOUT_PAGE_SIZE - nbdata - skip, - NULL, 0); - ret = doc_read_page_getbytes(docg3, nboob, oobbuf, 0); + NULL, 0, (skip + nbdata) % 2); + ret = doc_read_page_getbytes(docg3, nboob, oobbuf, 0, 0); if (ret < nboob) goto err_in_read; doc_read_page_getbytes(docg3, DOC_LAYOUT_OOB_SIZE - nboob, - NULL, 0); + NULL, 0, nboob % 2); doc_get_bch_hw_ecc(docg3, hwecc); eccconf1 = doc_register_readb(docg3, DOC_ECCCONF1); @@ -936,7 +949,8 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, } if (ret > 0) { mtd->ecc_stats.corrected += ret; - ret = -EUCLEAN; + max_bitflips = max(max_bitflips, ret); + ret = max_bitflips; } } @@ -971,7 +985,7 @@ err_in_read: * Reads flash memory pages. This function does not read the OOB chunk, but only * the page data. * - * Returns 0 if read successfull, of -EIO, -EINVAL if an error occured + * Returns 0 if read successful, of -EIO, -EINVAL if an error occurred */ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) @@ -1004,7 +1018,7 @@ static int doc_reload_bbt(struct docg3 *docg3) DOC_LAYOUT_PAGE_SIZE); if (!ret) doc_read_page_getbytes(docg3, DOC_LAYOUT_PAGE_SIZE, - buf, 1); + buf, 1, 0); buf += DOC_LAYOUT_PAGE_SIZE; } doc_read_page_finish(docg3); @@ -1064,10 +1078,10 @@ static int doc_get_erase_count(struct docg3 *docg3, loff_t from) ret = doc_reset_seq(docg3); if (!ret) ret = doc_read_page_prepare(docg3, block0, block1, page, - ofs + DOC_LAYOUT_WEAR_OFFSET); + ofs + DOC_LAYOUT_WEAR_OFFSET, 0); if (!ret) ret = doc_read_page_getbytes(docg3, DOC_LAYOUT_WEAR_SIZE, - buf, 1); + buf, 1, 0); doc_read_page_finish(docg3); if (ret || (buf[0] != DOC_ERASE_MARK) || (buf[2] != DOC_ERASE_MARK)) @@ -1109,7 +1123,7 @@ static int doc_get_op_status(struct docg3 *docg3) * Wait for the chip to be ready again after erase or write operation, and check * erase/write status. * - * Returns 0 if erase successfull, -EIO if erase/write issue, -ETIMEOUT if + * Returns 0 if erase successful, -EIO if erase/write issue, -ETIMEOUT if * timeout */ static int doc_write_erase_wait_status(struct docg3 *docg3) @@ -1186,7 +1200,7 @@ static int doc_erase_block(struct docg3 *docg3, int block0, int block1) * Erase a bunch of contiguous blocks, by pairs, as a "mtd" page of 1024 is * split into 2 pages of 512 bytes on 2 contiguous blocks. * - * Returns 0 if erase successful, -EINVAL if adressing error, -EIO if erase + * Returns 0 if erase successful, -EINVAL if addressing error, -EIO if erase * issue */ static int doc_erase(struct mtd_info *mtd, struct erase_info *info) @@ -1397,7 +1411,7 @@ static int doc_backup_oob(struct docg3 *docg3, loff_t to, * Or provide data without OOB, and then a all zeroed OOB will be used (ECC will * still be filled in if asked for). * - * Returns 0 is successfull, EINVAL if length is not 14 bytes + * Returns 0 is successful, EINVAL if length is not 14 bytes */ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, struct mtd_oob_ops *ops) @@ -1945,7 +1959,7 @@ static void doc_release_device(struct mtd_info *mtd) * docg3_resume - Awakens docg3 floor * @pdev: platfrom device * - * Returns 0 (always successfull) + * Returns 0 (always successful) */ static int docg3_resume(struct platform_device *pdev) { diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 1924d247c1c..5d0d68c3fe2 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -639,12 +639,16 @@ static const struct spi_device_id m25p_ids[] = { { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, + /* Everspin */ + { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2) }, + /* Intel/Numonyx -- xxxs33b */ { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) }, { "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) }, { "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) }, /* Macronix */ + { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) }, { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, @@ -728,6 +732,7 @@ static const struct spi_device_id m25p_ids[] = { { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) }, { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, + { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, /* Catalyst / On Semiconductor -- non-JEDEC */ { "cat25c11", CAT25_INFO( 16, 8, 16, 1) }, diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index 797d43cd355..67960362681 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -990,9 +990,9 @@ static int __devinit spear_smi_probe(struct platform_device *pdev) goto err_clk; } - ret = clk_enable(dev->clk); + ret = clk_prepare_enable(dev->clk); if (ret) - goto err_clk_enable; + goto err_clk_prepare_enable; ret = request_irq(irq, spear_smi_int_handler, 0, pdev->name, dev); if (ret) { @@ -1020,8 +1020,8 @@ err_bank_setup: free_irq(irq, dev); platform_set_drvdata(pdev, NULL); err_irq: - clk_disable(dev->clk); -err_clk_enable: + clk_disable_unprepare(dev->clk); +err_clk_prepare_enable: clk_put(dev->clk); err_clk: iounmap(dev->io_base); @@ -1074,7 +1074,7 @@ static int __devexit spear_smi_remove(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); free_irq(irq, dev); - clk_disable(dev->clk); + clk_disable_unprepare(dev->clk); clk_put(dev->clk); iounmap(dev->io_base); kfree(dev); @@ -1091,7 +1091,7 @@ int spear_smi_suspend(struct platform_device *pdev, pm_message_t state) struct spear_smi *dev = platform_get_drvdata(pdev); if (dev && dev->clk) - clk_disable(dev->clk); + clk_disable_unprepare(dev->clk); return 0; } @@ -1102,7 +1102,7 @@ int spear_smi_resume(struct platform_device *pdev) int ret = -EPERM; if (dev && dev->clk) - ret = clk_enable(dev->clk); + ret = clk_prepare_enable(dev->clk); if (!ret) spear_smi_hw_init(dev); |