diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2010-10-30 12:35:11 +0100 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2010-10-30 12:35:11 +0100 |
commit | 67577927e8d7a1f4b09b4992df640eadc6aacb36 (patch) | |
tree | 2e9efe6b5745965faf0dcc084d4613d9356263f9 /drivers/mtd | |
parent | 6fe4c590313133ebd5dadb769031489ff178ece1 (diff) | |
parent | 51f00a471ce8f359627dd99aeac322947a0e491b (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Conflicts:
drivers/mtd/mtd_blkdevs.c
Merge Grant's device-tree bits so that we can apply the subsequent fixes.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/chips/cfi_cmdset_0002.c | 4 | ||||
-rw-r--r-- | drivers/mtd/devices/lart.c | 2 | ||||
-rw-r--r-- | drivers/mtd/devices/m25p80.c | 7 | ||||
-rw-r--r-- | drivers/mtd/ftl.c | 2 | ||||
-rw-r--r-- | drivers/mtd/maps/Kconfig | 4 | ||||
-rw-r--r-- | drivers/mtd/maps/pcmciamtd.c | 102 | ||||
-rw-r--r-- | drivers/mtd/mtd_blkdevs.c | 8 | ||||
-rw-r--r-- | drivers/mtd/mtdchar.c | 15 | ||||
-rw-r--r-- | drivers/mtd/nand/cafe_nand.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/mxc_nand.c | 92 | ||||
-rw-r--r-- | drivers/mtd/nand/omap2.c | 2 | ||||
-rw-r--r-- | drivers/mtd/ubi/Kconfig | 17 | ||||
-rw-r--r-- | drivers/mtd/ubi/Kconfig.debug | 29 | ||||
-rw-r--r-- | drivers/mtd/ubi/build.c | 6 | ||||
-rw-r--r-- | drivers/mtd/ubi/cdev.c | 1 | ||||
-rw-r--r-- | drivers/mtd/ubi/debug.h | 4 | ||||
-rw-r--r-- | drivers/mtd/ubi/eba.c | 10 | ||||
-rw-r--r-- | drivers/mtd/ubi/io.c | 138 | ||||
-rw-r--r-- | drivers/mtd/ubi/misc.c | 19 | ||||
-rw-r--r-- | drivers/mtd/ubi/scan.c | 387 | ||||
-rw-r--r-- | drivers/mtd/ubi/scan.h | 19 | ||||
-rw-r--r-- | drivers/mtd/ubi/ubi.h | 29 | ||||
-rw-r--r-- | drivers/mtd/ubi/vmt.c | 6 | ||||
-rw-r--r-- | drivers/mtd/ubi/vtbl.c | 10 | ||||
-rw-r--r-- | drivers/mtd/ubi/wl.c | 31 |
25 files changed, 568 insertions, 378 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 288fc2ea849..3b8e32d8797 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -446,8 +446,8 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) /* * Valid primary extension versions are: 1.0, 1.1, 1.2, 1.3, 1.4 - * see: http://www.amd.com/us-en/assets/content_type/DownloadableAssets/cfi_r20.pdf, page 19 - * http://www.amd.com/us-en/assets/content_type/DownloadableAssets/cfi_100_20011201.pdf + * see: http://cs.ozerki.net/zap/pub/axim-x5/docs/cfi_r20.pdf, page 19 + * http://www.spansion.com/Support/AppNotes/cfi_100_20011201.pdf * http://www.spansion.com/Support/Datasheets/s29ws-p_00_a12_e.pdf */ if (extp->MajorVersion != '1' || diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index f4359fe7150..caf604167f0 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c @@ -17,7 +17,7 @@ * - January 2000 * * [2] MTD internal API documentation - * - http://www.linux-mtd.infradead.org/tech/ + * - http://www.linux-mtd.infradead.org/ * * Limitations: * diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 7e0edd40ad4..669d2b7e36b 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -928,6 +928,13 @@ static int __devinit m25p_probe(struct spi_device *spi) nr_parts = data->nr_parts; } +#ifdef CONFIG_OF + if (nr_parts <= 0 && spi->dev.of_node) { + nr_parts = of_mtd_parse_partitions(&spi->dev, + spi->dev.of_node, &parts); + } +#endif + if (nr_parts > 0) { for (i = 0; i < nr_parts; i++) { DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = " diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index 4d6a64c387e..037b399df3f 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c @@ -51,7 +51,7 @@ Use of the FTL format for non-PCMCIA applications may be an infringement of these patents. For additional information, - contact M-Systems (http://www.m-sys.com) directly. + contact M-Systems directly. M-Systems since acquired by Sandisk. ======================================================================*/ #include <linux/mtd/blktrans.h> diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index e5eb65cfb3e..a0dd7bba948 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -172,7 +172,7 @@ config MTD_OCTAGON This provides a 'mapping' driver which supports the way in which the flash chips are connected in the Octagon-5066 Single Board Computer. More information on the board is available at - <http://www.octagonsystems.com/CPUpages/5066.html>. + <http://www.octagonsystems.com/products/5066.aspx>. config MTD_VMAX tristate "JEDEC Flash device mapped on Tempustech VMAX SBC301" @@ -293,7 +293,7 @@ config MTD_TQM8XXL chips, currently uses AMD one. This 'mapping' driver supports that arrangement, allowing the CFI probe and command set driver code to communicate with the chips on the TQM8xxL board. More at - <http://www.denx.de/embedded-ppc-en.html>. + <http://www.denx.de/wiki/PPCEmbedded/>. config MTD_RPXLITE tristate "CFI Flash device mapped on RPX Lite or CLLF" diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index 86c74685eb7..91702294839 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -16,7 +16,6 @@ #include <asm/io.h> #include <asm/system.h> -#include <pcmcia/cs.h> #include <pcmcia/cistpl.h> #include <pcmcia/ds.h> @@ -101,7 +100,7 @@ MODULE_PARM_DESC(mem_type, "Set Memory type (0=Flash, 1=RAM, 2=ROM, default=0)") static caddr_t remap_window(struct map_info *map, unsigned long to) { struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1; - window_handle_t win = (window_handle_t)map->map_priv_2; + struct resource *win = (struct resource *) map->map_priv_2; unsigned int offset; int ret; @@ -316,30 +315,19 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on) { struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1; struct pcmcia_device *link = dev->p_dev; - modconf_t mod; - int ret; - - mod.Attributes = CONF_VPP1_CHANGE_VALID | CONF_VPP2_CHANGE_VALID; - mod.Vcc = 0; - mod.Vpp1 = mod.Vpp2 = on ? dev->vpp : 0; DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp); - ret = pcmcia_modify_configuration(link, &mod); + pcmcia_fixup_vpp(link, on ? dev->vpp : 0); } -/* After a card is removed, pcmciamtd_release() will unregister the - * device, and release the PCMCIA configuration. If the device is - * still open, this will be postponed until it is closed. - */ - static void pcmciamtd_release(struct pcmcia_device *link) { struct pcmciamtd_dev *dev = link->priv; DEBUG(3, "link = 0x%p", link); - if (link->win) { + if (link->resource[2]->end) { if(dev->win_base) { iounmap(dev->win_base); dev->win_base = NULL; @@ -482,18 +470,12 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *p_dev } -/* pcmciamtd_config() is scheduled to run after a CARD_INSERTION event - * is received, to configure the PCMCIA socket, and to make the - * MTD device available to the system. - */ - static int pcmciamtd_config(struct pcmcia_device *link) { struct pcmciamtd_dev *dev = link->priv; struct mtd_info *mtd = NULL; - win_req_t req; int ret; - int i; + int i, j = 0; static char *probes[] = { "jedec_probe", "cfi_probe" }; int new_name = 0; @@ -520,28 +502,34 @@ static int pcmciamtd_config(struct pcmcia_device *link) * smaller windows until we succeed */ - req.Attributes = WIN_MEMORY_TYPE_CM | WIN_ENABLE; - req.Attributes |= (dev->pcmcia_map.bankwidth == 1) ? WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16; - req.Base = 0; - req.AccessSpeed = mem_speed; - link->win = (window_handle_t)link; - req.Size = (force_size) ? force_size << 20 : MAX_PCMCIA_ADDR; + link->resource[2]->flags |= WIN_MEMORY_TYPE_CM | WIN_ENABLE; + link->resource[2]->flags |= (dev->pcmcia_map.bankwidth == 1) ? + WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16; + link->resource[2]->start = 0; + link->resource[2]->end = (force_size) ? force_size << 20 : + MAX_PCMCIA_ADDR; dev->win_size = 0; do { int ret; - DEBUG(2, "requesting window with size = %dKiB memspeed = %d", - req.Size >> 10, req.AccessSpeed); - ret = pcmcia_request_window(link, &req, &link->win); + DEBUG(2, "requesting window with size = %luKiB memspeed = %d", + (unsigned long) resource_size(link->resource[2]) >> 10, + mem_speed); + ret = pcmcia_request_window(link, link->resource[2], mem_speed); DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size); if(ret) { - req.Size >>= 1; + j++; + link->resource[2]->start = 0; + link->resource[2]->end = (force_size) ? + force_size << 20 : MAX_PCMCIA_ADDR; + link->resource[2]->end >>= j; } else { - DEBUG(2, "Got window of size %dKiB", req.Size >> 10); - dev->win_size = req.Size; + DEBUG(2, "Got window of size %luKiB", (unsigned long) + resource_size(link->resource[2]) >> 10); + dev->win_size = resource_size(link->resource[2]); break; } - } while(req.Size >= 0x1000); + } while (link->resource[2]->end >= 0x1000); DEBUG(2, "dev->win_size = %d", dev->win_size); @@ -553,33 +541,31 @@ static int pcmciamtd_config(struct pcmcia_device *link) DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10); /* Get write protect status */ - DEBUG(2, "window handle = 0x%8.8lx", (unsigned long)link->win); - dev->win_base = ioremap(req.Base, req.Size); + dev->win_base = ioremap(link->resource[2]->start, + resource_size(link->resource[2])); if(!dev->win_base) { - dev_err(&dev->p_dev->dev, "ioremap(%lu, %u) failed\n", - req.Base, req.Size); + dev_err(&dev->p_dev->dev, "ioremap(%pR) failed\n", + link->resource[2]); pcmciamtd_release(link); return -ENODEV; } - DEBUG(1, "mapped window dev = %p req.base = 0x%lx base = %p size = 0x%x", - dev, req.Base, dev->win_base, req.Size); + DEBUG(1, "mapped window dev = %p @ %pR, base = %p", + dev, link->resource[2], dev->win_base); dev->offset = 0; dev->pcmcia_map.map_priv_1 = (unsigned long)dev; - dev->pcmcia_map.map_priv_2 = (unsigned long)link->win; + dev->pcmcia_map.map_priv_2 = (unsigned long)link->resource[2]; dev->vpp = (vpp) ? vpp : link->socket->socket.Vpp; - link->conf.Attributes = 0; if(setvpp == 2) { - link->conf.Vpp = dev->vpp; + link->vpp = dev->vpp; } else { - link->conf.Vpp = 0; + link->vpp = 0; } - link->conf.IntType = INT_MEMORY; - link->conf.ConfigIndex = 0; + link->config_index = 0; DEBUG(2, "Setting Configuration"); - ret = pcmcia_request_configuration(link, &link->conf); + ret = pcmcia_enable_device(link); if (ret != 0) { if (dev->win_base) { iounmap(dev->win_base); @@ -676,12 +662,6 @@ static int pcmciamtd_resume(struct pcmcia_device *dev) } -/* This deletes a driver "instance". The device is de-registered - * with Card Services. If it has been released, all local data - * structures are freed. Otherwise, the structures will be freed - * when the device is released. - */ - static void pcmciamtd_detach(struct pcmcia_device *link) { struct pcmciamtd_dev *dev = link->priv; @@ -699,11 +679,6 @@ static void pcmciamtd_detach(struct pcmcia_device *link) } -/* pcmciamtd_attach() creates an "instance" of the driver, allocating - * local data structures for one device. The device is registered - * with Card Services. - */ - static int pcmciamtd_probe(struct pcmcia_device *link) { struct pcmciamtd_dev *dev; @@ -716,9 +691,6 @@ static int pcmciamtd_probe(struct pcmcia_device *link) dev->p_dev = link; link->priv = dev; - link->conf.Attributes = 0; - link->conf.IntType = INT_MEMORY; - return pcmciamtd_config(link); } @@ -753,9 +725,7 @@ static struct pcmcia_device_id pcmciamtd_ids[] = { MODULE_DEVICE_TABLE(pcmcia, pcmciamtd_ids); static struct pcmcia_driver pcmciamtd_driver = { - .drv = { - .name = "pcmciamtd" - }, + .name = "pcmciamtd", .probe = pcmciamtd_probe, .remove = pcmciamtd_detach, .owner = THIS_MODULE, @@ -767,8 +737,6 @@ static struct pcmcia_driver pcmciamtd_driver = { static int __init init_pcmciamtd(void) { - info(DRIVER_DESC); - if(bankwidth && bankwidth != 1 && bankwidth != 2) { info("bad bankwidth (%d), using default", bankwidth); bankwidth = 2; diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 63790e975d2..f9329794f3b 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -29,7 +29,6 @@ #include <linux/blkdev.h> #include <linux/blkpg.h> #include <linux/spinlock.h> -#include <linux/smp_lock.h> #include <linux/hdreg.h> #include <linux/init.h> #include <linux/mutex.h> @@ -38,6 +37,7 @@ #include "mtdcore.h" +static DEFINE_MUTEX(mtd_blkdevs_mutex); static LIST_HEAD(blktrans_majors); static DEFINE_MUTEX(blktrans_ref_mutex); @@ -185,6 +185,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode) if (!dev) return -ERESTARTSYS; /* FIXME: busy loop! -arnd*/ + mutex_lock(&mtd_blkdevs_mutex); mutex_lock(&dev->lock); if (dev->open++) @@ -201,6 +202,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode) unlock: mutex_unlock(&dev->lock); blktrans_dev_put(dev); + mutex_unlock(&mtd_blkdevs_mutex); return ret; } @@ -212,6 +214,7 @@ static int blktrans_release(struct gendisk *disk, fmode_t mode) if (!dev) return ret; + mutex_lock(&mtd_blkdevs_mutex); mutex_lock(&dev->lock); if (--dev->open) @@ -227,6 +230,7 @@ static int blktrans_release(struct gendisk *disk, fmode_t mode) unlock: mutex_unlock(&dev->lock); blktrans_dev_put(dev); + mutex_unlock(&mtd_blkdevs_mutex); return ret; } @@ -259,6 +263,7 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode, if (!dev) return ret; + mutex_lock(&mtd_blkdevs_mutex); mutex_lock(&dev->lock); if (!dev->mtd) @@ -273,6 +278,7 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode, } unlock: mutex_unlock(&dev->lock); + mutex_unlock(&mtd_blkdevs_mutex); blktrans_dev_put(dev); return ret; } diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index b7ed09c5790..3eff1e562ad 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -26,7 +26,7 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/sched.h> -#include <linux/smp_lock.h> +#include <linux/mutex.h> #include <linux/backing-dev.h> #include <linux/compat.h> #include <linux/mount.h> @@ -38,6 +38,7 @@ #include <asm/uaccess.h> #define MTD_INODE_FS_MAGIC 0x11307854 +static DEFINE_MUTEX(mtd_mutex); static struct vfsmount *mtd_inode_mnt __read_mostly; /* @@ -91,7 +92,7 @@ static int mtd_open(struct inode *inode, struct file *file) if ((file->f_mode & FMODE_WRITE) && (minor & 1)) return -EACCES; - lock_kernel(); + mutex_lock(&mtd_mutex); mtd = get_mtd_device(NULL, devnum); if (IS_ERR(mtd)) { @@ -139,7 +140,7 @@ static int mtd_open(struct inode *inode, struct file *file) file->private_data = mfi; out: - unlock_kernel(); + mutex_unlock(&mtd_mutex); return ret; } /* mtd_open */ @@ -967,9 +968,9 @@ static long mtd_unlocked_ioctl(struct file *file, u_int cmd, u_long arg) { int ret; - lock_kernel(); + mutex_lock(&mtd_mutex); ret = mtd_ioctl(file, cmd, arg); - unlock_kernel(); + mutex_unlock(&mtd_mutex); return ret; } @@ -993,7 +994,7 @@ static long mtd_compat_ioctl(struct file *file, unsigned int cmd, void __user *argp = compat_ptr(arg); int ret = 0; - lock_kernel(); + mutex_lock(&mtd_mutex); switch (cmd) { case MEMWRITEOOB32: @@ -1028,7 +1029,7 @@ static long mtd_compat_ioctl(struct file *file, unsigned int cmd, ret = mtd_ioctl(file, cmd, (unsigned long)argp); } - unlock_kernel(); + mutex_unlock(&mtd_mutex); return ret; } diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index db1dfc5a1b1..e06c8983978 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c @@ -2,7 +2,7 @@ * Driver for One Laptop Per Child ‘CAFÉ’ controller, aka Marvell 88ALP01 * * The data sheet for this device can be found at: - * http://www.marvell.com/products/pcconn/88ALP01.jsp + * http://wiki.laptop.org/go/Datasheets * * Copyright © 2006 Red Hat, Inc. * Copyright © 2006 David Woodhouse <dwmw2@infradead.org> diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index b2828e84d24..214b03afdd4 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -30,6 +30,8 @@ #include <linux/clk.h> #include <linux/err.h> #include <linux/io.h> +#include <linux/irq.h> +#include <linux/completion.h> #include <asm/mach/flash.h> #include <mach/mxc_nand.h> @@ -151,7 +153,7 @@ struct mxc_nand_host { int irq; int eccsize; - wait_queue_head_t irq_waitq; + struct completion op_completion; uint8_t *data_buf; unsigned int buf_start; @@ -164,6 +166,7 @@ struct mxc_nand_host { void (*send_read_id)(struct mxc_nand_host *); uint16_t (*get_dev_status)(struct mxc_nand_host *); int (*check_int)(struct mxc_nand_host *); + void (*irq_control)(struct mxc_nand_host *, int); }; /* OOB placement block for use with hardware ecc generation */ @@ -216,9 +219,12 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) { struct mxc_nand_host *host = dev_id; - disable_irq_nosync(irq); + if (!host->check_int(host)) + return IRQ_NONE; - wake_up(&host->irq_waitq); + host->irq_control(host, 0); + + complete(&host->op_completion); return IRQ_HANDLED; } @@ -245,11 +251,54 @@ static int check_int_v1_v2(struct mxc_nand_host *host) if (!(tmp & NFC_V1_V2_CONFIG2_INT)) return 0; - writew(tmp & ~NFC_V1_V2_CONFIG2_INT, NFC_V1_V2_CONFIG2); + if (!cpu_is_mx21()) + writew(tmp & ~NFC_V1_V2_CONFIG2_INT, NFC_V1_V2_CONFIG2); return 1; } +/* + * It has been observed that the i.MX21 cannot read the CONFIG2:INT bit + * if interrupts are masked (CONFIG1:INT_MSK is set). To handle this, the + * driver can enable/disable the irq line rather than simply masking the + * interrupts. + */ +static void irq_control_mx21(struct mxc_nand_host *host, int activate) +{ + if (activate) + enable_irq(host->irq); + else + disable_irq_nosync(host->irq); +} + +static void irq_control_v1_v2(struct mxc_nand_host *host, int activate) +{ + uint16_t tmp; + + tmp = readw(NFC_V1_V2_CONFIG1); + + if (activate) + tmp &= ~NFC_V1_V2_CONFIG1_INT_MSK; + else + tmp |= NFC_V1_V2_CONFIG1_INT_MSK; + + writew(tmp, NFC_V1_V2_CONFIG1); +} + +static void irq_control_v3(struct mxc_nand_host *host, int activate) +{ + uint32_t tmp; + + tmp = readl(NFC_V3_CONFIG2); + + if (activate) + tmp &= ~NFC_V3_CONFIG2_INT_MSK; + else + tmp |= NFC_V3_CONFIG2_INT_MSK; + + writel(tmp, NFC_V3_CONFIG2); +} + /* This function polls the NANDFC to wait for the basic operation to * complete by checking the INT bit of config2 register. */ @@ -259,10 +308,9 @@ static void wait_op_done(struct mxc_nand_host *host, int useirq) if (useirq) { if (!host->check_int(host)) { - - enable_irq(host->irq); - - wait_event(host->irq_waitq, host->check_int(host)); + INIT_COMPLETION(host->op_completion); + host->irq_control(host, 1); + wait_for_completion(&host->op_completion); } } else { while (max_retries-- > 0) { @@ -799,6 +847,7 @@ static void preset_v3(struct mtd_info *mtd) NFC_V3_CONFIG2_2CMD_PHASES | NFC_V3_CONFIG2_SPAS(mtd->oobsize >> 1) | NFC_V3_CONFIG2_ST_CMD(0x70) | + NFC_V3_CONFIG2_INT_MSK | NFC_V3_CONFIG2_NUM_ADDR_PHASE0; if (chip->ecc.mode == NAND_ECC_HW) @@ -1024,6 +1073,10 @@ static int __init mxcnd_probe(struct platform_device *pdev) host->send_read_id = send_read_id_v1_v2; host->get_dev_status = get_dev_status_v1_v2; host->check_int = check_int_v1_v2; + if (cpu_is_mx21()) + host->irq_control = irq_control_mx21; + else + host->irq_control = irq_control_v1_v2; } if (nfc_is_v21()) { @@ -1062,6 +1115,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) host->send_read_id = send_read_id_v3; host->check_int = check_int_v3; host->get_dev_status = get_dev_status_v3; + host->irq_control = irq_control_v3; oob_smallpage = &nandv2_hw_eccoob_smallpage; oob_largepage = &nandv2_hw_eccoob_largepage; } else @@ -1093,14 +1147,34 @@ static int __init mxcnd_probe(struct platform_device *pdev) this->options |= NAND_USE_FLASH_BBT; } - init_waitqueue_head(&host->irq_waitq); + init_completion(&host->op_completion); host->irq = platform_get_irq(pdev, 0); + /* + * mask the interrupt. For i.MX21 explicitely call + * irq_control_v1_v2 to use the mask bit. We can't call + * disable_irq_nosync() for an interrupt we do not own yet. + */ + if (cpu_is_mx21()) + irq_control_v1_v2(host, 0); + else + host->irq_control(host, 0); + err = request_irq(host->irq, mxc_nfc_irq, IRQF_DISABLED, DRIVER_NAME, host); if (err) goto eirq; + host->irq_control(host, 0); + + /* + * Now that the interrupt is disabled make sure the interrupt + * mask bit is cleared on i.MX21. Otherwise we can't read + * the interrupt status bit on this machine. + */ + if (cpu_is_mx21()) + irq_control_v1_v2(host, 1); + /* first scan to find the device and get the page size */ if (nand_scan_ident(mtd, 1, NULL)) { err = -ENXIO; diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 439e80d78ed..cd41c58b5bb 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -413,7 +413,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, prefetch_status = gpmc_read_status(GPMC_PREFETCH_COUNT); } while (prefetch_status); /* disable and stop the PFPW engine */ - gpmc_prefetch_reset(); + gpmc_prefetch_reset(info->gpmc_cs); dma_unmap_single(&info->pdev->dev, dma_addr, len, dir); return 0; diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig index f702a163d8d..3cf193fb5e0 100644 --- a/drivers/mtd/ubi/Kconfig +++ b/drivers/mtd/ubi/Kconfig @@ -1,9 +1,5 @@ -menu "UBI - Unsorted block images" - depends on MTD - -config MTD_UBI - tristate "Enable UBI" - depends on MTD +menuconfig MTD_UBI + tristate "Enable UBI - Unsorted block images" select CRC32 help UBI is a software layer above MTD layer which admits of LVM-like @@ -12,11 +8,12 @@ config MTD_UBI capabilities. Please, consult the MTD web site for more details (www.linux-mtd.infradead.org). +if MTD_UBI + config MTD_UBI_WL_THRESHOLD int "UBI wear-leveling threshold" default 4096 range 2 65536 - depends on MTD_UBI help This parameter defines the maximum difference between the highest erase counter value and the lowest erase counter value of eraseblocks @@ -34,7 +31,6 @@ config MTD_UBI_BEB_RESERVE int "Percentage of reserved eraseblocks for bad eraseblocks handling" default 1 range 0 25 - depends on MTD_UBI help If the MTD device admits of bad eraseblocks (e.g. NAND flash), UBI reserves some amount of physical eraseblocks to handle new bad @@ -48,8 +44,6 @@ config MTD_UBI_BEB_RESERVE config MTD_UBI_GLUEBI tristate "MTD devices emulation driver (gluebi)" - default n - depends on MTD_UBI help This option enables gluebi - an additional driver which emulates MTD devices on top of UBI volumes: for each UBI volumes an MTD device is @@ -59,4 +53,5 @@ config MTD_UBI_GLUEBI software. source "drivers/mtd/ubi/Kconfig.debug" -endmenu + +endif # MTD_UBI diff --git a/drivers/mtd/ubi/Kconfig.debug b/drivers/mtd/ubi/Kconfig.debug index 61f6e5e4045..fad4adc0fe2 100644 --- a/drivers/mtd/ubi/Kconfig.debug +++ b/drivers/mtd/ubi/Kconfig.debug @@ -1,94 +1,73 @@ comment "UBI debugging options" - depends on MTD_UBI config MTD_UBI_DEBUG bool "UBI debugging" depends on SYSFS - depends on MTD_UBI select DEBUG_FS select KALLSYMS_ALL if KALLSYMS && DEBUG_KERNEL help This option enables UBI debugging. +if MTD_UBI_DEBUG + config MTD_UBI_DEBUG_MSG bool "UBI debugging messages" - depends on MTD_UBI_DEBUG - default n help This option enables UBI debugging messages. config MTD_UBI_DEBUG_PARANOID bool "Extra self-checks" - default n - depends on MTD_UBI_DEBUG help This option enables extra checks in UBI code. Note this slows UBI down significantly. config MTD_UBI_DEBUG_DISABLE_BGT bool "Do not enable the UBI background thread" - depends on MTD_UBI_DEBUG - default n help This option switches the background thread off by default. The thread may be also be enabled/disabled via UBI sysfs. config MTD_UBI_DEBUG_EMULATE_BITFLIPS bool "Emulate flash bit-flips" - depends on MTD_UBI_DEBUG - default n help This option emulates bit-flips with probability 1/50, which in turn causes scrubbing. Useful for debugging and stressing UBI. config MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES bool "Emulate flash write failures" - depends on MTD_UBI_DEBUG - default n help This option emulates write failures with probability 1/100. Useful for debugging and testing how UBI handlines errors. config MTD_UBI_DEBUG_EMULATE_ERASE_FAILURES bool "Emulate flash erase failures" - depends on MTD_UBI_DEBUG - default n help This option emulates erase failures with probability 1/100. Useful for debugging and testing how UBI handlines errors. -menu "Additional UBI debugging messages" - depends on MTD_UBI_DEBUG +comment "Additional UBI debugging messages" config MTD_UBI_DEBUG_MSG_BLD bool "Additional UBI initialization and build messages" - default n - depends on MTD_UBI_DEBUG help This option enables detailed UBI initialization and device build debugging messages. config MTD_UBI_DEBUG_MSG_EBA bool "Eraseblock association unit messages" - default n - depends on MTD_UBI_DEBUG help This option enables debugging messages from the UBI eraseblock association unit. config MTD_UBI_DEBUG_MSG_WL bool "Wear-leveling unit messages" - default n - depends on MTD_UBI_DEBUG help This option enables debugging messages from the UBI wear-leveling unit. config MTD_UBI_DEBUG_MSG_IO bool "Input/output unit messages" - default n - depends on MTD_UBI_DEBUG help This option enables debugging messages from the UBI input/output unit. -endmenu # UBI debugging messages +endif # MTD_UBI_DEBUG diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 78ae89488a4..5ebe280225d 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -95,8 +95,8 @@ DEFINE_MUTEX(ubi_devices_mutex); static DEFINE_SPINLOCK(ubi_devices_lock); /* "Show" method for files in '/<sysfs>/class/ubi/' */ -static ssize_t ubi_version_show(struct class *class, struct class_attribute *attr, - char *buf) +static ssize_t ubi_version_show(struct class *class, + struct class_attribute *attr, char *buf) { return sprintf(buf, "%d\n", UBI_VERSION); } @@ -591,6 +591,7 @@ static int attach_by_scanning(struct ubi_device *ubi) ubi->bad_peb_count = si->bad_peb_count; ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count; + ubi->corr_peb_count = si->corr_peb_count; ubi->max_ec = si->max_ec; ubi->mean_ec = si->mean_ec; ubi_msg("max. sequence number: %llu", si->max_sqnum); @@ -972,6 +973,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20); ubi_msg("number of good PEBs: %d", ubi->good_peb_count); ubi_msg("number of bad PEBs: %d", ubi->bad_peb_count); + ubi_msg("number of corrupted PEBs: %d", ubi->corr_peb_count); ubi_msg("max. allowed volumes: %d", ubi->vtbl_slots); ubi_msg("wear-leveling threshold: %d", CONFIG_MTD_UBI_WL_THRESHOLD); ubi_msg("number of internal volumes: %d", UBI_INT_VOL_COUNT); diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 3d2d1a69e9a..af9fb0ff821 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -1100,4 +1100,5 @@ const struct file_operations ubi_ctrl_cdev_operations = { .owner = THIS_MODULE, .unlocked_ioctl = ctrl_cdev_ioctl, .compat_ioctl = ctrl_cdev_compat_ioctl, + .llseek = noop_llseek, }; diff --git a/drivers/mtd/ubi/deb |