summaryrefslogtreecommitdiffstats
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/maps/Kconfig2
-rw-r--r--drivers/mtd/maps/pcmciamtd.c121
-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
6 files changed, 85 insertions, 107 deletions
diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
index f9db52f..04f864d 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;
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 452ccd5..b9b77cf 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -62,7 +62,7 @@ config MTD_PHYSMAP_BANKWIDTH
config MTD_SUN_UFLASH
tristate "Sun Microsystems userflash support"
- depends on (SPARC32 || SPARC64) && MTD_CFI
+ depends on SPARC && MTD_CFI
help
This provides a 'mapping' driver which supports the way in
which user-programmable flash chips are connected on various
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index af24216..f0f8916 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -66,9 +66,6 @@ struct pcmciamtd_dev {
};
-static dev_info_t dev_info = "pcmciamtd";
-static dev_link_t *dev_list;
-
/* Module parameters */
/* 2 = do 16-bit transfers, 1 = do 8-bit transfers */
@@ -691,55 +688,21 @@ static void pcmciamtd_config(dev_link_t *link)
}
-/* The card status event handler. Mostly, this schedules other
- * stuff to run after an event is received. A CARD_REMOVAL event
- * also sets some flags to discourage the driver from trying
- * to talk to the card any more.
- */
+static int pcmciamtd_suspend(struct pcmcia_device *dev)
+{
+ DEBUG(2, "EVENT_PM_RESUME");
+
+ /* get_lock(link); */
+
+ return 0;
+}
-static int pcmciamtd_event(event_t event, int priority,
- event_callback_args_t *args)
+static int pcmciamtd_resume(struct pcmcia_device *dev)
{
- dev_link_t *link = args->client_data;
-
- DEBUG(1, "event=0x%06x", event);
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- DEBUG(2, "EVENT_CARD_REMOVAL");
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- struct pcmciamtd_dev *dev = link->priv;
- if(dev->mtd_info) {
- del_mtd_device(dev->mtd_info);
- info("mtd%d: Removed", dev->mtd_info->index);
- }
- pcmciamtd_release(link);
- }
- break;
- case CS_EVENT_CARD_INSERTION:
- DEBUG(2, "EVENT_CARD_INSERTION");
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- pcmciamtd_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
- DEBUG(2, "EVENT_PM_SUSPEND");
- link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
- DEBUG(2, "EVENT_RESET_PHYSICAL");
- /* get_lock(link); */
- break;
- case CS_EVENT_PM_RESUME:
- DEBUG(2, "EVENT_PM_RESUME");
- link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
- DEBUG(2, "EVENT_CARD_RESET");
- /* free_lock(link); */
- break;
- default:
- DEBUG(2, "Unknown event %d", event);
- }
+ DEBUG(2, "EVENT_PM_SUSPEND");
+
+ /* free_lock(link); */
+
return 0;
}
@@ -750,23 +713,21 @@ static int pcmciamtd_event(event_t event, int priority,
* when the device is released.
*/
-static void pcmciamtd_detach(dev_link_t *link)
+static void pcmciamtd_detach(struct pcmcia_device *p_dev)
{
+ dev_link_t *link = dev_to_instance(p_dev);
+
DEBUG(3, "link=0x%p", link);
if(link->state & DEV_CONFIG) {
- pcmciamtd_release(link);
- }
+ struct pcmciamtd_dev *dev = link->priv;
+ if(dev->mtd_info) {
+ del_mtd_device(dev->mtd_info);
+ info("mtd%d: Removed", dev->mtd_info->index);
+ }
- if (link->handle) {
- int ret;
- DEBUG(2, "Deregistering with card services");
- ret = pcmcia_deregister_client(link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
+ pcmciamtd_release(link);
}
-
- link->state |= DEV_STALE_LINK;
}
@@ -775,16 +736,14 @@ static void pcmciamtd_detach(dev_link_t *link)
* with Card Services.
*/
-static dev_link_t *pcmciamtd_attach(void)
+static int pcmciamtd_attach(struct pcmcia_device *p_dev)
{
struct pcmciamtd_dev *dev;
dev_link_t *link;
- client_reg_t client_reg;
- int ret;
/* Create new memory card device */
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev) return NULL;
+ if (!dev) return -ENOMEM;
DEBUG(1, "dev=0x%p", dev);
memset(dev, 0, sizeof(*dev));
@@ -794,22 +753,14 @@ static dev_link_t *pcmciamtd_attach(void)
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY;
- link->next = dev_list;
- dev_list = link;
-
- /* Register with Card Services */
- client_reg.dev_info = &dev_info;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- DEBUG(2, "Calling RegisterClient");
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != 0) {
- cs_error(link->handle, RegisterClient, ret);
- pcmciamtd_detach(link);
- return NULL;
- }
- DEBUG(2, "link = %p", link);
- return link;
+ link->next = NULL;
+ link->handle = p_dev;
+ p_dev->instance = link;
+
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ pcmciamtd_config(link);
+
+ return 0;
}
static struct pcmcia_device_id pcmciamtd_ids[] = {
@@ -843,11 +794,12 @@ static struct pcmcia_driver pcmciamtd_driver = {
.drv = {
.name = "pcmciamtd"
},
- .attach = pcmciamtd_attach,
- .event = pcmciamtd_event,
- .detach = pcmciamtd_detach,
+ .probe = pcmciamtd_attach,
+ .remove = pcmciamtd_detach,
.owner = THIS_MODULE,
.id_table = pcmciamtd_ids,
+ .suspend = pcmciamtd_suspend,
+ .resume = pcmciamtd_resume,
};
@@ -875,7 +827,6 @@ static void __exit exit_pcmciamtd(void)
{
DEBUG(1, DRIVER_DESC " unloading");
pcmcia_unregister_driver(&pcmciamtd_driver);
- BUG_ON(dev_list != NULL);
}
module_init(init_pcmciamtd);
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
index 48cce43..45c077d 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 <linux/device.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h>
#include <linux/mtd/partitions.h>
@@ -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;
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index f67d5d6..a53a73f 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;
@@ -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))
@@ -1346,7 +1348,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 +1358,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);
}
/**
@@ -1513,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);
@@ -1574,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 f40190f..4510d33 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);
}
/**
OpenPOWER on IntegriCloud