Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
authorDavid Woodhouse <David.Woodhouse@intel.com>
Mon, 10 May 2010 13:32:46 +0000 (14:32 +0100)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Mon, 10 May 2010 13:32:46 +0000 (14:32 +0100)
Conflicts:
drivers/mtd/mtdcore.c

Pull in the bdi fixes and ARM platform changes that other outstanding
patches depend on.

21 files changed:
1  2 
MAINTAINERS
drivers/mtd/Makefile
drivers/mtd/devices/block2mtd.c
drivers/mtd/devices/sst25l.c
drivers/mtd/lpddr/lpddr_cmds.c
drivers/mtd/maps/bfin-async-flash.c
drivers/mtd/maps/physmap_of.c
drivers/mtd/maps/pismo.c
drivers/mtd/mtdcore.c
drivers/mtd/mtdsuper.c
drivers/mtd/nand/bcm_umi_nand.c
drivers/mtd/nand/cafe_nand.c
drivers/mtd/nand/davinci_nand.c
drivers/mtd/nand/fsl_upm.c
drivers/mtd/nand/nomadik_nand.c
drivers/mtd/nand/omap2.c
drivers/mtd/nand/orion_nand.c
drivers/mtd/nand/pxa3xx_nand.c
drivers/mtd/nand/sh_flctl.c
drivers/mtd/nand/tmio_nand.c
drivers/mtd/onenand/omap2.c

diff --combined MAINTAINERS
@@@ -485,8 -485,8 +485,8 @@@ S: Maintaine
  F:    drivers/input/mouse/bcm5974.c
  
  APPLE SMC DRIVER
- M:    Nicolas Boichat <nicolas@boichat.ch>
- L:    mactel-linux-devel@lists.sourceforge.net
+ M:    Henrik Rydberg <rydberg@euromail.se>
+ L:    lm-sensors@lm-sensors.org
  S:    Maintained
  F:    drivers/hwmon/applesmc.c
  
@@@ -797,12 -797,12 +797,12 @@@ M:      Michael Petchkovsky <mkpetch@interno
  S:    Maintained
  
  ARM/NOMADIK ARCHITECTURE
- M:     Alessandro Rubini <rubini@unipv.it>
- M:     STEricsson <STEricsson_nomadik_linux@list.st.com>
- L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
- S:     Maintained
- F:     arch/arm/mach-nomadik/
- F:     arch/arm/plat-nomadik/
+ M:    Alessandro Rubini <rubini@unipv.it>
+ M:    STEricsson <STEricsson_nomadik_linux@list.st.com>
+ L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+ S:    Maintained
+ F:    arch/arm/mach-nomadik/
+ F:    arch/arm/plat-nomadik/
  
  ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
  M:    Nelson Castillo <arhuaco@freaks-unidos.net>
@@@ -971,6 -971,16 +971,16 @@@ L:       linux-arm-kernel@lists.infradead.or
  W:    http://www.mcuos.com
  S:    Maintained
  
+ ARM/U300 MACHINE SUPPORT
+ M:    Linus Walleij <linus.walleij@stericsson.com>
+ L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+ S:    Supported
+ F:    arch/arm/mach-u300/
+ F:    drivers/i2c/busses/i2c-stu300.c
+ F:    drivers/rtc/rtc-coh901331.c
+ F:    drivers/watchdog/coh901327_wdt.c
+ F:    drivers/dma/coh901318*
  ARM/U8500 ARM ARCHITECTURE
  M:    Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@@ -1443,7 -1453,7 +1453,7 @@@ F:      arch/powerpc/platforms/cell
  
  CEPH DISTRIBUTED FILE SYSTEM CLIENT
  M:    Sage Weil <sage@newdream.net>
- L:    ceph-devel@lists.sourceforge.net
+ L:    ceph-devel@vger.kernel.org
  W:    http://ceph.newdream.net/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git
  S:    Supported
@@@ -1926,17 -1936,17 +1936,17 @@@ F:   drivers/scsi/dpt
  F:    drivers/scsi/dpt/
  
  DRBD DRIVER
- P:     Philipp Reisner
- P:     Lars Ellenberg
- M:     drbd-dev@lists.linbit.com
- L:     drbd-user@lists.linbit.com
- W:     http://www.drbd.org
- T:     git git://git.drbd.org/linux-2.6-drbd.git drbd
- T:     git git://git.drbd.org/drbd-8.3.git
- S:     Supported
- F:     drivers/block/drbd/
- F:     lib/lru_cache.c
- F:     Documentation/blockdev/drbd/
+ P:    Philipp Reisner
+ P:    Lars Ellenberg
+ M:    drbd-dev@lists.linbit.com
+ L:    drbd-user@lists.linbit.com
+ W:    http://www.drbd.org
+ T:    git git://git.drbd.org/linux-2.6-drbd.git drbd
+ T:    git git://git.drbd.org/drbd-8.3.git
+ S:    Supported
+ F:    drivers/block/drbd/
+ F:    lib/lru_cache.c
+ F:    Documentation/blockdev/drbd/
  
  DRIVER CORE, KOBJECTS, AND SYSFS
  M:    Greg Kroah-Hartman <gregkh@suse.de>
@@@ -1950,7 -1960,7 +1960,7 @@@ F:      lib/kobj
  
  DRM DRIVERS
  M:    David Airlie <airlied@linux.ie>
- L:    dri-devel@lists.sourceforge.net
+ L:    dri-devel@lists.freedesktop.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6.git
  S:    Maintained
  F:    drivers/gpu/drm/
@@@ -2474,12 -2484,6 +2484,6 @@@ L:     linuxppc-dev@ozlabs.or
  S:    Odd Fixes
  F:    drivers/char/hvc_*
  
- VIRTIO CONSOLE DRIVER
- M:    Amit Shah <amit.shah@redhat.com>
- L:    virtualization@lists.linux-foundation.org
- S:    Maintained
- F:    drivers/char/virtio_console.c
  iSCSI BOOT FIRMWARE TABLE (iBFT) DRIVER
  M:    Peter Jones <pjones@redhat.com>
  M:    Konrad Rzeszutek Wilk <konrad@kernel.org>
@@@ -3083,6 -3087,7 +3087,7 @@@ F:      include/scsi/*iscsi
  ISDN SUBSYSTEM
  M:    Karsten Keil <isdn@linux-pingi.de>
  L:    isdn4linux@listserv.isdn4linux.de (subscribers-only)
+ L:    netdev@vger.kernel.org
  W:    http://www.isdn4linux.de
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/kkeil/isdn-2.6.git
  S:    Maintained
@@@ -3269,6 -3274,16 +3274,16 @@@ S:    Maintaine
  F:    include/linux/kexec.h
  F:    kernel/kexec.c
  
+ KEYS/KEYRINGS:
+ M:    David Howells <dhowells@redhat.com>
+ L:    keyrings@linux-nfs.org
+ S:    Maintained
+ F:    Documentation/keys.txt
+ F:    include/linux/key.h
+ F:    include/linux/key-type.h
+ F:    include/keys/
+ F:    security/keys/
  KGDB
  M:    Jason Wessel <jason.wessel@windriver.com>
  L:    kgdb-bugreport@lists.sourceforge.net
@@@ -3518,8 -3533,8 +3533,8 @@@ F:      drivers/scsi/sym53c8xx_2
  LTP (Linux Test Project)
  M:    Rishikesh K Rajak <risrajak@linux.vnet.ibm.com>
  M:    Garrett Cooper <yanegomi@gmail.com>
- M:     Mike Frysinger <vapier@gentoo.org>
- M:     Subrata Modak <subrata@linux.vnet.ibm.com>
+ M:    Mike Frysinger <vapier@gentoo.org>
+ M:    Subrata Modak <subrata@linux.vnet.ibm.com>
  L:    ltp-list@lists.sourceforge.net (subscribers-only)
  W:    http://ltp.sourceforge.net/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/galak/ltp.git
@@@ -4467,17 -4482,17 +4482,17 @@@ S:   Maintaine
  F:    drivers/ata/sata_promise.*
  
  PS3 NETWORK SUPPORT
- M:    Geoff Levand <geoffrey.levand@am.sony.com>
+ M:    Geoff Levand <geoff@infradead.org>
  L:    netdev@vger.kernel.org
  L:    cbe-oss-dev@ozlabs.org
- S:    Supported
+ S:    Maintained
  F:    drivers/net/ps3_gelic_net.*
  
  PS3 PLATFORM SUPPORT
- M:    Geoff Levand <geoffrey.levand@am.sony.com>
+ M:    Geoff Levand <geoff@infradead.org>
  L:    linuxppc-dev@ozlabs.org
  L:    cbe-oss-dev@ozlabs.org
- S:    Supported
+ S:    Maintained
  F:    arch/powerpc/boot/ps3*
  F:    arch/powerpc/include/asm/lv1call.h
  F:    arch/powerpc/include/asm/ps3*.h
@@@ -4701,12 -4716,6 +4716,12 @@@ S:    Maintaine
  F:    Documentation/rfkill.txt
  F:    net/rfkill/
  
 +RICOH SMARTMEDIA/XD DRIVER
 +M:    Maxim Levitsky <maximlevitsky@gmail.com>
 +S:    Maintained
 +F:    drivers/mtd/nand/r822.c
 +F:    drivers/mtd/nand/r822.h
 +
  RISCOM8 DRIVER
  S:    Orphan
  F:    Documentation/serial/riscom8.txt
@@@ -4782,12 -4791,11 +4797,11 @@@ F:   drivers/s390/crypto
  
  S390 ZFCP DRIVER
  M:    Christof Schmitt <christof.schmitt@de.ibm.com>
- M:    Martin Peschke <mp3@de.ibm.com>
+ M:    Swen Schillig <swen@vnet.ibm.com>
  M:    linux390@de.ibm.com
  L:    linux-s390@vger.kernel.org
  W:    http://www.ibm.com/developerworks/linux/linux390/
  S:    Supported
- F:    Documentation/s390/zfcpdump.txt
  F:    drivers/s390/scsi/zfcp_*
  
  S390 IUCV NETWORK LAYER
@@@ -5429,7 -5437,6 +5443,6 @@@ S:      Maintaine
  F:    sound/soc/codecs/twl4030*
  
  TIPC NETWORK LAYER
- M:    Per Liden <per.liden@ericsson.com>
  M:    Jon Maloy <jon.maloy@ericsson.com>
  M:    Allan Stephens <allan.stephens@windriver.com>
  L:    tipc-discussion@lists.sourceforge.net
@@@ -5967,6 -5974,13 +5980,13 @@@ S:    Maintaine
  F:    Documentation/filesystems/vfat.txt
  F:    fs/fat/
  
+ VIRTIO CONSOLE DRIVER
+ M:    Amit Shah <amit.shah@redhat.com>
+ L:    virtualization@lists.linux-foundation.org
+ S:    Maintained
+ F:    drivers/char/virtio_console.c
+ F:    include/linux/virtio_console.h
  VIRTIO HOST (VHOST)
  M:    "Michael S. Tsirkin" <mst@redhat.com>
  L:    kvm@vger.kernel.org
@@@ -6207,7 -6221,7 +6227,7 @@@ F:      arch/x86
  X86 PLATFORM DRIVERS
  M:    Matthew Garrett <mjg@redhat.com>
  L:    platform-driver-x86@vger.kernel.org
- T:      git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git
  S:    Maintained
  F:    drivers/platform/x86
  
diff --combined drivers/mtd/Makefile
@@@ -4,7 -4,7 +4,7 @@@
  
  # Core functionality.
  obj-$(CONFIG_MTD)             += mtd.o
- mtd-y                         := mtdcore.o mtdsuper.o mtdbdi.o
+ mtd-y                         := mtdcore.o mtdsuper.o
  mtd-$(CONFIG_MTD_PARTITIONS)  += mtdpart.o
  
  obj-$(CONFIG_MTD_CONCAT)      += mtdconcat.o
@@@ -24,7 -24,6 +24,7 @@@ obj-$(CONFIG_NFTL)            += nftl.
  obj-$(CONFIG_INFTL)           += inftl.o
  obj-$(CONFIG_RFD_FTL)         += rfd_ftl.o
  obj-$(CONFIG_SSFDC)           += ssfdc.o
 +obj-$(CONFIG_SM_FTL)          += sm_ftl.o
  obj-$(CONFIG_MTD_OOPS)                += mtdoops.o
  
  nftl-objs             := nftlcore.o nftlmount.o
@@@ -17,6 -17,7 +17,7 @@@
  #include <linux/buffer_head.h>
  #include <linux/mutex.h>
  #include <linux/mount.h>
+ #include <linux/slab.h>
  
  #define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
  #define INFO(fmt, args...) printk(KERN_INFO "block2mtd: " fmt "\n" , ## args)
@@@ -275,10 -276,12 +276,10 @@@ static struct block2mtd_dev *add_device
  
        /* Setup the MTD structure */
        /* make the name contain the block device in */
 -      name = kmalloc(sizeof("block2mtd: ") + strlen(devname) + 1,
 -                      GFP_KERNEL);
 +      name = kasprintf(GFP_KERNEL, "block2mtd: %s", devname);
        if (!name)
                goto devinit_err;
  
 -      sprintf(name, "block2mtd: %s", devname);
        dev->mtd.name = name;
  
        dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
@@@ -20,6 -20,7 +20,7 @@@
  #include <linux/device.h>
  #include <linux/mutex.h>
  #include <linux/interrupt.h>
+ #include <linux/slab.h>
  #include <linux/sched.h>
  
  #include <linux/mtd/mtd.h>
@@@ -410,6 -411,17 +411,6 @@@ static int __init sst25l_probe(struct s
              flash->mtd.erasesize, flash->mtd.erasesize / 1024,
              flash->mtd.numeraseregions);
  
 -      if (flash->mtd.numeraseregions)
 -              for (i = 0; i < flash->mtd.numeraseregions; i++)
 -                      DEBUG(MTD_DEBUG_LEVEL2,
 -                            "mtd.eraseregions[%d] = { .offset = 0x%llx, "
 -                            ".erasesize = 0x%.8x (%uKiB), "
 -                            ".numblocks = %d }\n",
 -                            i, (long long)flash->mtd.eraseregions[i].offset,
 -                            flash->mtd.eraseregions[i].erasesize,
 -                            flash->mtd.eraseregions[i].erasesize / 1024,
 -                            flash->mtd.eraseregions[i].numblocks);
 -
        if (mtd_has_partitions()) {
                struct mtd_partition *parts = NULL;
                int nr_parts = 0;
@@@ -26,6 -26,7 +26,7 @@@
   */
  #include <linux/mtd/pfow.h>
  #include <linux/mtd/qinfo.h>
+ #include <linux/slab.h>
  
  static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len,
                                        size_t *retlen, u_char *buf);
@@@ -106,7 -107,8 +107,7 @@@ struct mtd_info *lpddr_cmdset(struct ma
                        /* those should be reset too since
                           they create memory references. */
                        init_waitqueue_head(&chip->wq);
 -                      spin_lock_init(&chip->_spinlock);
 -                      chip->mutex = &chip->_spinlock;
 +                      mutex_init(&chip->mutex);
                        chip++;
                }
        }
@@@ -142,7 -144,7 +143,7 @@@ static int wait_for_ready(struct map_in
                }
  
                /* OK Still waiting. Drop the lock, wait a while and retry. */
 -              spin_unlock(chip->mutex);
 +              mutex_unlock(&chip->mutex);
                if (sleep_time >= 1000000/HZ) {
                        /*
                         * Half of the normal delay still remaining
                        cond_resched();
                        timeo--;
                }
 -              spin_lock(chip->mutex);
 +              mutex_lock(&chip->mutex);
  
                while (chip->state != chip_state) {
                        /* Someone's suspended the operation: sleep */
                        DECLARE_WAITQUEUE(wait, current);
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&chip->wq, &wait);
 -                      spin_unlock(chip->mutex);
 +                      mutex_unlock(&chip->mutex);
                        schedule();
                        remove_wait_queue(&chip->wq, &wait);
 -                      spin_lock(chip->mutex);
 +                      mutex_lock(&chip->mutex);
                }
                if (chip->erase_suspended || chip->write_suspended)  {
                        /* Suspend has occured while sleep: reset timeout */
@@@ -228,20 -230,20 +229,20 @@@ static int get_chip(struct map_info *ma
                         * it'll happily send us to sleep.  In any case, when
                         * get_chip returns success we're clear to go ahead.
                         */
 -                      ret = spin_trylock(contender->mutex);
 +                      ret = mutex_trylock(&contender->mutex);
                        spin_unlock(&shared->lock);
                        if (!ret)
                                goto retry;
 -                      spin_unlock(chip->mutex);
 +                      mutex_unlock(&chip->mutex);
                        ret = chip_ready(map, contender, mode);
 -                      spin_lock(chip->mutex);
 +                      mutex_lock(&chip->mutex);
  
                        if (ret == -EAGAIN) {
 -                              spin_unlock(contender->mutex);
 +                              mutex_unlock(&contender->mutex);
                                goto retry;
                        }
                        if (ret) {
 -                              spin_unlock(contender->mutex);
 +                              mutex_unlock(&contender->mutex);
                                return ret;
                        }
                        spin_lock(&shared->lock);
                         * state. Put contender and retry. */
                        if (chip->state == FL_SYNCING) {
                                put_chip(map, contender);
 -                              spin_unlock(contender->mutex);
 +                              mutex_unlock(&contender->mutex);
                                goto retry;
                        }
 -                      spin_unlock(contender->mutex);
 +                      mutex_unlock(&contender->mutex);
                }
  
                /* Check if we have suspended erase on this chip.
                        spin_unlock(&shared->lock);
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&chip->wq, &wait);
 -                      spin_unlock(chip->mutex);
 +                      mutex_unlock(&chip->mutex);
                        schedule();
                        remove_wait_queue(&chip->wq, &wait);
 -                      spin_lock(chip->mutex);
 +                      mutex_lock(&chip->mutex);
                        goto retry;
                }
  
@@@ -335,10 -337,10 +336,10 @@@ static int chip_ready(struct map_info *
  sleep:
                set_current_state(TASK_UNINTERRUPTIBLE);
                add_wait_queue(&chip->wq, &wait);
 -              spin_unlock(chip->mutex);
 +              mutex_unlock(&chip->mutex);
                schedule();
                remove_wait_queue(&chip->wq, &wait);
 -              spin_lock(chip->mutex);
 +              mutex_lock(&chip->mutex);
                return -EAGAIN;
        }
  }
@@@ -354,12 -356,12 +355,12 @@@ static void put_chip(struct map_info *m
                        if (shared->writing && shared->writing != chip) {
                                /* give back the ownership */
                                struct flchip *loaner = shared->writing;
 -                              spin_lock(loaner->mutex);
 +                              mutex_lock(&loaner->mutex);
                                spin_unlock(&shared->lock);
 -                              spin_unlock(chip->mutex);
 +                              mutex_unlock(&chip->mutex);
                                put_chip(map, loaner);
 -                              spin_lock(chip->mutex);
 -                              spin_unlock(loaner->mutex);
 +                              mutex_lock(&chip->mutex);
 +                              mutex_unlock(&loaner->mutex);
                                wake_up(&chip->wq);
                                return;
                        }
@@@ -412,10 -414,10 +413,10 @@@ int do_write_buffer(struct map_info *ma
  
        wbufsize = 1 << lpddr->qinfo->BufSizeShift;
  
 -      spin_lock(chip->mutex);
 +      mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, FL_WRITING);
        if (ret) {
 -              spin_unlock(chip->mutex);
 +              mutex_unlock(&chip->mutex);
                return ret;
        }
        /* Figure out the number of words to write */
        }
  
   out: put_chip(map, chip);
 -      spin_unlock(chip->mutex);
 +      mutex_unlock(&chip->mutex);
        return ret;
  }
  
@@@ -488,10 -490,10 +489,10 @@@ int do_erase_oneblock(struct mtd_info *
        struct flchip *chip = &lpddr->chips[chipnum];
        int ret;
  
 -      spin_lock(chip->mutex);
 +      mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, FL_ERASING);
        if (ret) {
 -              spin_unlock(chip->mutex);
 +              mutex_unlock(&chip->mutex);
                return ret;
        }
        send_pfow_command(map, LPDDR_BLOCK_ERASE, adr, 0, NULL);
                goto out;
        }
   out: put_chip(map, chip);
 -      spin_unlock(chip->mutex);
 +      mutex_unlock(&chip->mutex);
        return ret;
  }
  
@@@ -516,10 -518,10 +517,10 @@@ static int lpddr_read(struct mtd_info *
        struct flchip *chip = &lpddr->chips[chipnum];
        int ret = 0;
  
 -      spin_lock(chip->mutex);
 +      mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, FL_READY);
        if (ret) {
 -              spin_unlock(chip->mutex);
 +              mutex_unlock(&chip->mutex);
                return ret;
        }
  
        *retlen = len;
  
        put_chip(map, chip);
 -      spin_unlock(chip->mutex);
 +      mutex_unlock(&chip->mutex);
        return ret;
  }
  
@@@ -567,9 -569,9 +568,9 @@@ static int lpddr_point(struct mtd_info 
                else
                        thislen = len;
                /* get the chip */
 -              spin_lock(chip->mutex);
 +              mutex_lock(&chip->mutex);
                ret = get_chip(map, chip, FL_POINT);
 -              spin_unlock(chip->mutex);
 +              mutex_unlock(&chip->mutex);
                if (ret)
                        break;
  
@@@ -609,7 -611,7 +610,7 @@@ static void lpddr_unpoint (struct mtd_i
                else
                        thislen = len;
  
 -              spin_lock(chip->mutex);
 +              mutex_lock(&chip->mutex);
                if (chip->state == FL_POINT) {
                        chip->ref_point_counter--;
                        if (chip->ref_point_counter == 0)
                                        "pointed region\n", map->name);
  
                put_chip(map, chip);
 -              spin_unlock(chip->mutex);
 +              mutex_unlock(&chip->mutex);
  
                len -= thislen;
                ofs = 0;
@@@ -725,10 -727,10 +726,10 @@@ int do_xxlock(struct mtd_info *mtd, lof
        int chipnum = adr >> lpddr->chipshift;
        struct flchip *chip = &lpddr->chips[chipnum];
  
 -      spin_lock(chip->mutex);
 +      mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, FL_LOCKING);
        if (ret) {
 -              spin_unlock(chip->mutex);
 +              mutex_unlock(&chip->mutex);
                return ret;
        }
  
                goto out;
        }
  out:  put_chip(map, chip);
 -      spin_unlock(chip->mutex);
 +      mutex_unlock(&chip->mutex);
        return ret;
  }
  
@@@ -769,10 -771,10 +770,10 @@@ int word_program(struct map_info *map, 
        int chipnum = adr >> lpddr->chipshift;
        struct flchip *chip = &lpddr->chips[chipnum];
  
 -      spin_lock(chip->mutex);
 +      mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, FL_WRITING);
        if (ret) {
 -              spin_unlock(chip->mutex);
 +              mutex_unlock(&chip->mutex);
                return ret;
        }
  
        }
  
  out:  put_chip(map, chip);
 -      spin_unlock(chip->mutex);
 +      mutex_unlock(&chip->mutex);
        return ret;
  }
  
@@@ -22,6 -22,7 +22,7 @@@
  #include <linux/mtd/partitions.h>
  #include <linux/mtd/physmap.h>
  #include <linux/platform_device.h>
+ #include <linux/slab.h>
  #include <linux/types.h>
  
  #include <asm/blackfin.h>
@@@ -69,7 -70,7 +70,7 @@@ static void switch_back(struct async_st
        local_irq_restore(state->irq_flags);
  }
  
 -static map_word bfin_read(struct map_info *map, unsigned long ofs)
 +static map_word bfin_flash_read(struct map_info *map, unsigned long ofs)
  {
        struct async_state *state = (struct async_state *)map->map_priv_1;
        uint16_t word;
@@@ -85,7 -86,7 +86,7 @@@
        return test;
  }
  
 -static void bfin_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
 +static void bfin_flash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
  {
        struct async_state *state = (struct async_state *)map->map_priv_1;
  
@@@ -96,7 -97,7 +97,7 @@@
        switch_back(state);
  }
  
 -static void bfin_write(struct map_info *map, map_word d1, unsigned long ofs)
 +static void bfin_flash_write(struct map_info *map, map_word d1, unsigned long ofs)
  {
        struct async_state *state = (struct async_state *)map->map_priv_1;
        uint16_t d;
        switch_back(state);
  }
  
 -static void bfin_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
 +static void bfin_flash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
  {
        struct async_state *state = (struct async_state *)map->map_priv_1;
  
@@@ -140,10 -141,10 +141,10 @@@ static int __devinit bfin_flash_probe(s
                return -ENOMEM;
  
        state->map.name       = DRIVER_NAME;
 -      state->map.read       = bfin_read;
 -      state->map.copy_from  = bfin_copy_from;
 -      state->map.write      = bfin_write;
 -      state->map.copy_to    = bfin_copy_to;
 +      state->map.read       = bfin_flash_read;
 +      state->map.copy_from  = bfin_flash_copy_from;
 +      state->map.write      = bfin_flash_write;
 +      state->map.copy_to    = bfin_flash_copy_to;
        state->map.bankwidth  = pdata->width;
        state->map.size       = memory->end - memory->start + 1;
        state->map.virt       = (void __iomem *)memory->start;
@@@ -23,6 -23,7 +23,7 @@@
  #include <linux/mtd/concat.h>
  #include <linux/of.h>
  #include <linux/of_platform.h>
+ #include <linux/slab.h>
  
  struct of_flash_list {
        struct mtd_info *mtd;
@@@ -217,7 -218,7 +218,7 @@@ static int __devinit of_flash_probe(str
  
        dev_set_drvdata(&dev->dev, info);
  
 -      mtd_list = kzalloc(sizeof(struct mtd_info) * count, GFP_KERNEL);
 +      mtd_list = kzalloc(sizeof(*mtd_list) * count, GFP_KERNEL);
        if (!mtd_list)
                goto err_flash_remove;
  
diff --combined drivers/mtd/maps/pismo.c
@@@ -10,6 -10,7 +10,7 @@@
  #include <linux/init.h>
  #include <linux/module.h>
  #include <linux/i2c.h>
+ #include <linux/slab.h>
  #include <linux/platform_device.h>
  #include <linux/spinlock.h>
  #include <linux/mutex.h>
@@@ -233,7 -234,6 +234,7 @@@ static int __devexit pismo_remove(struc
        /* FIXME: set_vpp needs saner arguments */
        pismo_setvpp_remove_fix(pismo);
  
 +      i2c_set_clientdata(client, NULL);
        kfree(pismo);
  
        return 0;
@@@ -272,7 -272,7 +273,7 @@@ static int __devinit pismo_probe(struc
        ret = pismo_eeprom_read(client, &eeprom, 0, sizeof(eeprom));
        if (ret < 0) {
                dev_err(&client->dev, "error reading EEPROM: %d\n", ret);
 -              return ret;
 +              goto exit_free;
        }
  
        dev_info(&client->dev, "%.15s board found\n", eeprom.board);
                                      pdata->cs_addrs[i]);
  
        return 0;
 +
 + exit_free:
 +      i2c_set_clientdata(client, NULL);
 +      kfree(pismo);
 +      return ret;
  }
  
  static const struct i2c_device_id pismo_id[] = {
diff --combined drivers/mtd/mtdcore.c
@@@ -2,12 -2,14 +2,14 @@@
   * Core registration and callback routines for MTD
   * drivers and users.
   *
+  * bdi bits are:
+  * Copyright Â© 2006 Red Hat, Inc. All Rights Reserved.
+  * Written by David Howells (dhowells@redhat.com)
   */
  
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/ptrace.h>
- #include <linux/slab.h>
  #include <linux/string.h>
  #include <linux/timer.h>
  #include <linux/major.h>
  #include <linux/init.h>
  #include <linux/mtd/compatmac.h>
  #include <linux/proc_fs.h>
 +#include <linux/idr.h>
+ #include <linux/backing-dev.h>
  
  #include <linux/mtd/mtd.h>
- #include "internal.h"
  
  #include "mtdcore.h"
+ /*
+  * backing device capabilities for non-mappable devices (such as NAND flash)
+  * - permits private mappings, copies are taken of the data
+  */
+ struct backing_dev_info mtd_bdi_unmappable = {
+       .capabilities   = BDI_CAP_MAP_COPY,
+ };
+ /*
+  * backing device capabilities for R/O mappable devices (such as ROM)
+  * - permits private mappings, copies are taken of the data
+  * - permits non-writable shared mappings
+  */
+ struct backing_dev_info mtd_bdi_ro_mappable = {
+       .capabilities   = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
+                          BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP),
+ };
+ /*
+  * backing device capabilities for writable mappable devices (such as RAM)
+  * - permits private mappings, copies are taken of the data
+  * - permits non-writable shared mappings
+  */
+ struct backing_dev_info mtd_bdi_rw_mappable = {
+       .capabilities   = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
+                          BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP |
+                          BDI_CAP_WRITE_MAP),
+ };
  
  static int mtd_cls_suspend(struct device *dev, pm_message_t state);
  static int mtd_cls_resume(struct device *dev);
@@@ -34,18 -63,13 +64,18 @@@ static struct class mtd_class = 
        .resume = mtd_cls_resume,
  };
  
 +static DEFINE_IDR(mtd_idr);
 +
  /* These are exported solely for the purpose of mtd_blkdevs.c. You
     should not use them for _anything_ else */
  DEFINE_MUTEX(mtd_table_mutex);
 -struct mtd_info *mtd_table[MAX_MTD_DEVICES];
 -
  EXPORT_SYMBOL_GPL(mtd_table_mutex);
 -EXPORT_SYMBOL_GPL(mtd_table);
 +
 +struct mtd_info *__mtd_next_device(int i)
 +{
 +      return idr_get_next(&mtd_idr, &i);
 +}
 +EXPORT_SYMBOL_GPL(__mtd_next_device);
  
  static LIST_HEAD(mtd_notifiers);
  
@@@ -241,13 -265,13 +271,13 @@@ static struct device_type mtd_devtype 
   *    Add a device to the list of MTD devices present in the system, and
   *    notify each currently active MTD 'user' of its arrival. Returns
   *    zero on success or 1 on failure, which currently will only happen
 - *    if the number of present devices exceeds MAX_MTD_DEVICES (i.e. 16)
 - *    or there's a sysfs error.
 + *    if there is insufficient memory or a sysfs error.
   */
  
  int add_mtd_device(struct mtd_info *mtd)
  {
 -      int i;
 +      struct mtd_notifier *not;
 +      int i, error;
  
        if (!mtd->backing_dev_info) {
                switch (mtd->type) {
        BUG_ON(mtd->writesize == 0);
        mutex_lock(&mtd_table_mutex);
  
 -      for (i=0; i < MAX_MTD_DEVICES; i++)
 -              if (!mtd_table[i]) {
 -                      struct mtd_notifier *not;
 -
 -                      mtd_table[i] = mtd;
 -                      mtd->index = i;
 -                      mtd->usecount = 0;
 -
 -                      if (is_power_of_2(mtd->erasesize))
 -                              mtd->erasesize_shift = ffs(mtd->erasesize) - 1;
 -                      else
 -                              mtd->erasesize_shift = 0;
 -
 -                      if (is_power_of_2(mtd->writesize))
 -                              mtd->writesize_shift = ffs(mtd->writesize) - 1;
 -                      else
 -                              mtd->writesize_shift = 0;
 -
 -                      mtd->erasesize_mask = (1 << mtd->erasesize_shift) - 1;
 -                      mtd->writesize_mask = (1 << mtd->writesize_shift) - 1;
 -
 -                      /* Some chips always power up locked. Unlock them now */
 -                      if ((mtd->flags & MTD_WRITEABLE)
 -                          && (mtd->flags & MTD_POWERUP_LOCK) && mtd->unlock) {
 -                              if (mtd->unlock(mtd, 0, mtd->size))
 -                                      printk(KERN_WARNING
 -                                             "%s: unlock failed, "
 -                                             "writes may not work\n",
 -                                             mtd->name);
 -                      }
 +      do {
 +              if (!idr_pre_get(&mtd_idr, GFP_KERNEL))
 +                      goto fail_locked;
 +              error = idr_get_new(&mtd_idr, mtd, &i);
 +      } while (error == -EAGAIN);
  
 -                      /* Caller should have set dev.parent to match the
 -                       * physical device.
 -                       */
 -                      mtd->dev.type = &mtd_devtype;
 -                      mtd->dev.class = &mtd_class;
 -                      mtd->dev.devt = MTD_DEVT(i);
 -                      dev_set_name(&mtd->dev, "mtd%d", i);
 -                      dev_set_drvdata(&mtd->dev, mtd);
 -                      if (device_register(&mtd->dev) != 0) {
 -                              mtd_table[i] = NULL;
 -                              break;
 -                      }
 +      if (error)
 +              goto fail_locked;
  
 -                      if (MTD_DEVT(i))
 -                              device_create(&mtd_class, mtd->dev.parent,
 -                                              MTD_DEVT(i) + 1,
 -                                              NULL, "mtd%dro", i);
 -
 -                      DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name);
 -                      /* No need to get a refcount on the module containing
 -                         the notifier, since we hold the mtd_table_mutex */
 -                      list_for_each_entry(not, &mtd_notifiers, list)
 -                              not->add(mtd);
 -
 -                      mutex_unlock(&mtd_table_mutex);
 -                      /* We _know_ we aren't being removed, because
 -                         our caller is still holding us here. So none
 -                         of this try_ nonsense, and no bitching about it
 -                         either. :) */
 -                      __module_get(THIS_MODULE);
 -                      return 0;
 -              }
 +      mtd->index = i;
 +      mtd->usecount = 0;
 +
 +      if (is_power_of_2(mtd->erasesize))
 +              mtd->erasesize_shift = ffs(mtd->erasesize) - 1;
 +      else
 +              mtd->erasesize_shift = 0;
 +
 +      if (is_power_of_2(mtd->writesize))
 +              mtd->writesize_shift = ffs(mtd->writesize) - 1;
 +      else
 +              mtd->writesize_shift = 0;
 +
 +      mtd->erasesize_mask = (1 << mtd->erasesize_shift) - 1;
 +      mtd->writesize_mask = (1 << mtd->writesize_shift) - 1;
 +
 +      /* Some chips always power up locked. Unlock them now */
 +      if ((mtd->flags & MTD_WRITEABLE)
 +          && (mtd->flags & MTD_POWERUP_LOCK) && mtd->unlock) {
 +              if (mtd->unlock(mtd, 0, mtd->size))
 +                      printk(KERN_WARNING
 +                             "%s: unlock failed, writes may not work\n",
 +                             mtd->name);
 +      }
 +
 +      /* Caller should have set dev.parent to match the
 +       * physical device.
 +       */
 +      mtd->dev.type = &mtd_devtype;
 +      mtd->dev.class = &mtd_class;
 +      mtd->dev.devt = MTD_DEVT(i);
 +      dev_set_name(&mtd->dev, "mtd%d", i);
 +      dev_set_drvdata(&mtd->dev, mtd);
 +      if (device_register(&mtd->dev) != 0)
 +              goto fail_added;
 +
 +      if (MTD_DEVT(i))
 +              device_create(&mtd_class, mtd->dev.parent,
 +                            MTD_DEVT(i) + 1,
 +                            NULL, "mtd%dro", i);
 +
 +      DEBUG(0, "mtd: Giving out device %d to %s\n", i, mtd->name);
 +      /* No need to get a refcount on the module containing
 +         the notifier, since we hold the mtd_table_mutex */
 +      list_for_each_entry(not, &mtd_notifiers, list)
 +              not->add(mtd);
 +
 +      mutex_unlock(&mtd_table_mutex);
 +      /* We _know_ we aren't being removed, because
 +         our caller is still holding us here. So none
 +         of this try_ nonsense, and no bitching about it
 +         either. :) */
 +      __module_get(THIS_MODULE);
 +      return 0;
  
 +fail_added:
 +      idr_remove(&mtd_idr, i);
 +fail_locked:
        mutex_unlock(&mtd_table_mutex);
        return 1;
  }
  int del_mtd_device (struct mtd_info *mtd)
  {
        int ret;
 +      struct mtd_notifier *not;
  
        mutex_lock(&mtd_table_mutex);
  
 -      if (mtd_table[mtd->index] != mtd) {
 +      if (idr_find(&mtd_idr, mtd->index) != mtd) {
                ret = -ENODEV;
 -      } else if (mtd->usecount) {
 +              goto out_error;
 +      }
 +
 +      /* No need to get a refcount on the module containing
 +              the notifier, since we hold the mtd_table_mutex */
 +      list_for_each_entry(not, &mtd_notifiers, list)
 +              not->remove(mtd);
 +
 +      if (mtd->usecount) {
                printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n",
                       mtd->index, mtd->name, mtd->usecount);
                ret = -EBUSY;
        } else {
 -              struct mtd_notifier *not;
 -
                device_unregister(&mtd->dev);
  
 -              /* No need to get a refcount on the module containing
 -                 the notifier, since we hold the mtd_table_mutex */
 -              list_for_each_entry(not, &mtd_notifiers, list)
 -                      not->remove(mtd);
 -
 -              mtd_table[mtd->index] = NULL;
 +              idr_remove(&mtd_idr, mtd->index);
  
                module_put(THIS_MODULE);
                ret = 0;
        }
  
 +out_error:
        mutex_unlock(&mtd_table_mutex);
        return ret;
  }
  
  void register_mtd_user (struct mtd_notifier *new)
  {
 -      int i;
 +      struct mtd_info *mtd;
  
        mutex_lock(&mtd_table_mutex);
  
  
        __module_get(THIS_MODULE);
  
 -      for (i=0; i< MAX_MTD_DEVICES; i++)
 -              if (mtd_table[i])
 -                      new->add(mtd_table[i]);
 +      mtd_for_each_device(mtd)
 +              new->add(mtd);
  
        mutex_unlock(&mtd_table_mutex);
  }
  
  int unregister_mtd_user (struct mtd_notifier *old)
  {
 -      int i;
 +      struct mtd_info *mtd;
  
        mutex_lock(&mtd_table_mutex);
  
        module_put(THIS_MODULE);
  
 -      for (i=0; i< MAX_MTD_DEVICES; i++)
 -              if (mtd_table[i])
 -                      old->remove(mtd_table[i]);
 +      mtd_for_each_device(mtd)
 +              old->remove(mtd);
  
        list_del(&old->list);
        mutex_unlock(&mtd_table_mutex);
  
  struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
  {
 -      struct mtd_info *ret = NULL;
 -      int i, err = -ENODEV;
 +      struct mtd_info *ret = NULL, *other;
 +      int err = -ENODEV;
  
        mutex_lock(&mtd_table_mutex);
  
        if (num == -1) {
 -              for (i=0; i< MAX_MTD_DEVICES; i++)
 -                      if (mtd_table[i] == mtd)
 -                              ret = mtd_table[i];
 -      } else if (num >= 0 && num < MAX_MTD_DEVICES) {
 -              ret = mtd_table[num];
 +              mtd_for_each_device(other) {
 +                      if (other == mtd) {
 +                              ret = mtd;
 +                              break;
 +                      }
 +              }
 +      } else if (num >= 0) {
 +              ret = idr_find(&mtd_idr, num);
                if (mtd && mtd != ret)
                        ret = NULL;
        }
  
 -      if (!ret)
 -              goto out_unlock;
 -
 -      if (!try_module_get(ret->owner))
 -              goto out_unlock;
 -
 -      if (ret->get_device) {
 -              err = ret->get_device(ret);
 -              if (err)
 -                      goto out_put;
 +      if (!ret) {
 +              ret = ERR_PTR(err);
 +              goto out;
        }
  
 -      ret->usecount++;
 +      err = __get_mtd_device(ret);
 +      if (err)
 +              ret = ERR_PTR(err);
 +out:
        mutex_unlock(&mtd_table_mutex);
        return ret;
 +}
  
 -out_put:
 -      module_put(ret->owner);
 -out_unlock:
 -      mutex_unlock(&mtd_table_mutex);
 -      return ERR_PTR(err);
 +
 +int __get_mtd_device(struct mtd_info *mtd)
 +{
 +      int err;
 +
 +      if (!try_module_get(mtd->owner))
 +              return -ENODEV;
 +
 +      if (mtd->get_device) {
 +
 +              err = mtd->get_device(mtd);
 +
 +              if (err) {
 +                      module_put(mtd->owner);
 +                      return err;
 +              }
 +      }
 +      mtd->usecount++;
 +      return 0;
  }
  
  /**
  
  struct mtd_info *get_mtd_device_nm(const char *name)
  {
 -      int i, err = -ENODEV;
 -      struct mtd_info *mtd = NULL;
 +      int err = -ENODEV;
 +      struct mtd_info *mtd = NULL, *other;
  
        mutex_lock(&mtd_table_mutex);
  
 -      for (i = 0; i < MAX_MTD_DEVICES; i++) {
 -              if (mtd_table[i] && !strcmp(name, mtd_table[i]->name)) {
 -                      mtd = mtd_table[i];
 +      mtd_for_each_device(other) {
 +              if (!strcmp(name, other->name)) {
 +                      mtd = other;
                        break;
                }
        }
@@@ -548,19 -554,14 +578,19 @@@ out_unlock
  
  void put_mtd_device(struct mtd_info *mtd)
  {
 -      int c;
 -
        mutex_lock(&mtd_table_mutex);
 -      c = --mtd->usecount;
 +      __put_mtd_device(mtd);
 +      mutex_unlock(&mtd_table_mutex);
 +
 +}
 +
 +void __put_mtd_device(struct mtd_info *mtd)
 +{
 +      --mtd->usecount;
 +      BUG_ON(mtd->usecount < 0);
 +
        if (mtd->put_device)
                mtd->put_device(mtd);
 -      mutex_unlock(&mtd_table_mutex);
 -      BUG_ON(c < 0);
  
        module_put(mtd->owner);
  }
@@@ -598,9 -599,7 +628,9 @@@ EXPORT_SYMBOL_GPL(add_mtd_device)
  EXPORT_SYMBOL_GPL(del_mtd_device);
  EXPORT_SYMBOL_GPL(get_mtd_device);
  EXPORT_SYMBOL_GPL(get_mtd_device_nm);
 +EXPORT_SYMBOL_GPL(__get_mtd_device);
  EXPORT_SYMBOL_GPL(put_mtd_device);
 +EXPORT_SYMBOL_GPL(__put_mtd_device);
  EXPORT_SYMBOL_GPL(register_mtd_user);
  EXPORT_SYMBOL_GPL(unregister_mtd_user);
  EXPORT_SYMBOL_GPL(default_mtd_writev);
  
  static struct proc_dir_entry *proc_mtd;
  
 -static inline int mtd_proc_info (char *buf, int i)
 +static inline int mtd_proc_info(char *buf, struct mtd_info *this)
  {
 -      struct mtd_info *this = mtd_table[i];
 -
 -      if (!this)
 -              return 0;
 -
 -      return sprintf(buf, "mtd%d: %8.8llx %8.8x \"%s\"\n", i,
 +      return sprintf(buf, "mtd%d: %8.8llx %8.8x \"%s\"\n", this->index,
                       (unsigned long long)this->size,
                       this->erasesize, this->name);
  }
  static int mtd_read_proc (char *page, char **start, off_t off, int count,
                          int *eof, void *data_unused)
  {
 -      int len, l, i;
 +      struct mtd_info *mtd;
 +      int len, l;
          off_t   begin = 0;
  
        mutex_lock(&mtd_table_mutex);
  
        len = sprintf(page, "dev:    size   erasesize  name\n");
 -        for (i=0; i< MAX_MTD_DEVICES; i++) {
 -
 -                l = mtd_proc_info(page + len, i);
 +      mtd_for_each_device(mtd) {
 +              l = mtd_proc_info(page + len, mtd);
                  len += l;
                  if (len+begin > off+count)
                          goto done;
@@@ -655,20 -659,55 +685,55 @@@ done
  /*====================================================================*/
  /* Init code */
  
+ static int __init mtd_bdi_init(struct backing_dev_info *bdi, const char *name)
+ {
+       int ret;
+       ret = bdi_init(bdi);
+       if (!ret)
+               ret = bdi_register(bdi, NULL, name);
+       if (ret)
+               bdi_destroy(bdi);
+       return ret;
+ }
  static int __init init_mtd(void)
  {
        int ret;
        ret = class_register(&mtd_class);
+       if (ret)
+               goto err_reg;
+       ret = mtd_bdi_init(&mtd_bdi_unmappable, "mtd-unmap");
+       if (ret)
+               goto err_bdi1;
+       ret = mtd_bdi_init(&mtd_bdi_ro_mappable, "mtd-romap");
+       if (ret)
+               goto err_bdi2;
+       ret = mtd_bdi_init(&mtd_bdi_rw_mappable, "mtd-rwmap");
+       if (ret)
+               goto err_bdi3;
  
-       if (ret) {
-               pr_err("Error registering mtd class: %d\n", ret);
-               return ret;
-       }
  #ifdef CONFIG_PROC_FS
        if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
                proc_mtd->read_proc = mtd_read_proc;
  #endif /* CONFIG_PROC_FS */
        return 0;
+ err_bdi3:
+       bdi_destroy(&mtd_bdi_ro_mappable);
+ err_bdi2:
+       bdi_destroy(&mtd_bdi_unmappable);
+ err_bdi1:
+       class_unregister(&mtd_class);
+ err_reg:
+       pr_err("Error registering mtd class or bdi: %d\n", ret);
+       return ret;
  }
  
  static void __exit cleanup_mtd(void)
                remove_proc_entry( "mtd", NULL);
  #endif /* CONFIG_PROC_FS */
        class_unregister(&mtd_class);
+       bdi_destroy(&mtd_bdi_unmappable);
+       bdi_destroy(&mtd_bdi_ro_mappable);
+       bdi_destroy(&mtd_bdi_rw_mappable);
  }
  
  module_init(init_mtd);
diff --combined drivers/mtd/mtdsuper.c
@@@ -13,6 -13,7 +13,7 @@@
  #include <linux/mtd/super.h>
  #include <linux/namei.h>
  #include <linux/ctype.h>
+ #include <linux/slab.h>
  
  /*
   * compare superblocks to see if they're equivalent
@@@ -44,6 -45,7 +45,7 @@@ static int get_sb_mtd_set(struct super_
  
        sb->s_mtd = mtd;
        sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+       sb->s_bdi = mtd->backing_dev_info;
        return 0;
  }
  
@@@ -150,12 -152,18 +152,12 @@@ int get_sb_mtd(struct file_system_type 
                        DEBUG(1, "MTDSB: mtd:%%s, name \"%s\"\n",
                              dev_name + 4);
  
 -                      for (mtdnr = 0; mtdnr < MAX_MTD_DEVICES; mtdnr++) {
 -                              mtd = get_mtd_device(NULL, mtdnr);
 -                              if (!IS_ERR(mtd)) {
 -                                      if (!strcmp(mtd->name, dev_name + 4))
 -                                              return get_sb_mtd_aux(
 -                                                      fs_type, flags,
 -                                                      dev_name, data, mtd,
 -                                                      fill_super, mnt);
 -
 -                                      put_mtd_device(mtd);
 -                              }
 -                      }
 +                      mtd = get_mtd_device_nm(dev_name + 4);
 +                      if (!IS_ERR(mtd))
 +                              return get_sb_mtd_aux(
 +                                      fs_type, flags,
 +                                      dev_name, data, mtd,
 +                                      fill_super, mnt);
  
                        printk(KERN_NOTICE "MTD:"
                               " MTD device with name \"%s\" not found.\n",
  *****************************************************************************/
  
  /* ---- Include Files ---------------------------------------------------- */
 -#include <linux/version.h>
  #include <linux/module.h>
  #include <linux/types.h>
  #include <linux/init.h>
  #include <linux/kernel.h>
+ #include <linux/slab.h>
  #include <linux/string.h>
  #include <linux/ioport.h>
  #include <linux/device.h>
@@@ -445,7 -447,7 +446,7 @@@ static int __devinit bcm_umi_nand_probe
         * layout we'll be using.
         */
  
 -      err = nand_scan_ident(board_mtd, 1);
 +      err = nand_scan_ident(board_mtd, 1, NULL);
        if (err) {
                printk(KERN_ERR "nand_scan failed: %d\n", err);
                iounmap(bcm_umi_io_base);
@@@ -20,6 -20,7 +20,7 @@@
  #include <linux/delay.h>
  #include <linux/interrupt.h>
  #include <linux/dma-mapping.h>
+ #include <linux/slab.h>
  #include <asm/io.h>
  
  #define CAFE_NAND_CTRL1               0x00
@@@ -761,7 -762,7 +762,7 @@@ static int __devinit cafe_nand_probe(st
                cafe_readl(cafe, GLOBAL_CTRL), cafe_readl(cafe, GLOBAL_IRQ_MASK));
  
        /* Scan to find existence of the device */
 -      if (nand_scan_ident(mtd, 2)) {
 +      if (nand_scan_ident(mtd, 2, NULL)) {
                err = -ENXIO;
                goto out_irq;
        }
@@@ -848,7 -849,7 +849,7 @@@ static void __devexit cafe_nand_remove(
        kfree(mtd);
  }
  
 -static struct pci_device_id cafe_nand_tbl[] = {
 +static const struct pci_device_id cafe_nand_tbl[] = {
        { PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_88ALP01_NAND,
          PCI_ANY_ID, PCI_ANY_ID },
        { }
@@@ -32,6 -32,7 +32,7 @@@
  #include <linux/io.h>
  #include <linux/mtd/nand.h>
  #include <linux/mtd/partitions.h>
+ #include <linux/slab.h>
  
  #include <mach/nand.h>
  
@@@ -566,8 -567,8 +567,8 @@@ static int __init nand_davinci_probe(st
                goto err_nomem;
        }
  
 -      vaddr = ioremap(res1->start, res1->end - res1->start);
 -      base = ioremap(res2->start, res2->end - res2->start);
 +      vaddr = ioremap(res1->start, resource_size(res1));
 +      base = ioremap(res2->start, resource_size(res2));
        if (!vaddr || !base) {
                dev_err(&pdev->dev, "ioremap failed\n");
                ret = -EINVAL;
        spin_unlock_irq(&davinci_nand_lock);
  
        /* Scan to find existence of the device(s) */
 -      ret = nand_scan_ident(&info->mtd, pdata->mask_chipsel ? 2 : 1);
 +      ret = nand_scan_ident(&info->mtd, pdata->mask_chipsel ? 2 : 1, NULL);
        if (ret < 0) {
                dev_dbg(&pdev->dev, "no NAND chip(s) found\n");
                goto err_scan;
@@@ -21,6 -21,7 +21,7 @@@
  #include <linux/of_platform.h>
  #include <linux/of_gpio.h>
  #include <linux/io.h>
+ #include <linux/slab.h>
  #include <asm/fsl_lbc.h>
  
  #define FSL_UPM_WAIT_RUN_PATTERN  0x1
@@@ -48,10 -49,7 +49,10 @@@ struct fsl_upm_nand 
        uint32_t wait_flags;
  };
  
 -#define to_fsl_upm_nand(mtd) container_of(mtd, struct fsl_upm_nand, mtd)
 +static inline struct fsl_upm_nand *to_fsl_upm_nand(struct mtd_info *mtdinfo)
 +{
 +      return container_of(mtdinfo, struct fsl_upm_nand, mtd);
 +}
  
  static int fun_chip_ready(struct mtd_info *mtd)
  {
@@@ -305,7 -303,7 +306,7 @@@ static int __devinit fun_probe(struct o
                                  FSL_UPM_WAIT_WRITE_BYTE;
  
        fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start,
 -                                          io_res.end - io_res.start + 1);
 +                                          resource_size(&io_res));
        if (!fun->io_base) {
                ret = -ENOMEM;
                goto err2;
@@@ -352,7 -350,7 +353,7 @@@ static int __devexit fun_remove(struct 
        return 0;
  }
  
 -static struct of_device_id of_fun_match[] = {
 +static const struct of_device_id of_fun_match[] = {
        { .compatible = "fsl,upm-nand" },
        {},
  };
@@@ -30,6 -30,7 +30,7 @@@
  #include <linux/platform_device.h>
  #include <linux/mtd/partitions.h>
  #include <linux/io.h>
+ #include <linux/slab.h>
  #include <mach/nand.h>
  #include <mach/fsmc.h>
  
@@@ -104,21 -105,21 +105,21 @@@ static int nomadik_nand_probe(struct pl
                ret = -EIO;
                goto err_unmap;
        }
 -      host->addr_va = ioremap(res->start, res->end - res->start + 1);
 +      host->addr_va = ioremap(res->start, resource_size(res));
  
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data");
        if (!res) {
                ret = -EIO;
                goto err_unmap;
        }
 -      host->data_va = ioremap(res->start, res->end - res->start + 1);
 +      host->data_va = ioremap(res->start, resource_size(res));
  
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_cmd");
        if (!res) {
                ret = -EIO;
                goto err_unmap;
        }
 -      host->cmd_va = ioremap(res->start, res->end - res->start + 1);
 +      host->cmd_va = ioremap(res->start, resource_size(res));
  
        if (!host->addr_va || !host->data_va || !host->cmd_va) {
                ret = -ENOMEM;
diff --combined drivers/mtd/nand/omap2.c
@@@ -17,6 -17,7 +17,7 @@@
  #include <linux/mtd/nand.h>
  #include <linux/mtd/partitions.h>
  #include <linux/io.h>
+ #include <linux/slab.h>
  
  #include <plat/dma.h>
  #include <plat/gpmc.h>
@@@ -291,14 -292,11 +292,14 @@@ static void omap_read_buf_pref(struct m
        u32 *p = (u32 *)buf;
  
        /* take care of subpage reads */
 -      for (; len % 4 != 0; ) {
 -              *buf++ = __raw_readb(info->nand.IO_ADDR_R);
 -              len--;
 +      if (len % 4) {
 +              if (info->nand.options & NAND_BUSWIDTH_16)
 +                      omap_read_buf16(mtd, buf, len % 4);
 +              else
 +                      omap_read_buf8(mtd, buf, len % 4);
 +              p = (u32 *) (buf + len % 4);
 +              len -= len % 4;
        }
 -      p = (u32 *) buf;
  
        /* configure and start prefetch transfer */
        ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0);
@@@ -504,7 -502,7 +505,7 @@@ static void omap_write_buf_dma_pref(str
                omap_write_buf_pref(mtd, buf, len);
        else
                /* start transfer in DMA mode */
 -              omap_nand_dma_transfer(mtd, buf, len, 0x1);
 +              omap_nand_dma_transfer(mtd, (u_char *) buf, len, 0x1);
  }
  
  /**
@@@ -1030,8 -1028,7 +1031,8 @@@ out_free_info
  static int omap_nand_remove(struct platform_device *pdev)
  {
        struct mtd_info *mtd = platform_get_drvdata(pdev);
 -      struct omap_nand_info *info = mtd->priv;
 +      struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 +                                                      mtd);
  
        platform_set_drvdata(pdev, NULL);
        if (use_dma)
@@@ -60,7 -60,13 +60,13 @@@ static void orion_nand_read_buf(struct 
        }
        buf64 = (uint64_t *)buf;
        while (i < len/8) {
-               uint64_t x;
+               /*
+                * Since GCC has no proper constraint (PR 43518)
+                * force x variable to r2/r3 registers as ldrd instruction
+                * requires first register to be even.
+                */
+               register uint64_t x asm ("r2");
                asm volatile ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base));
                buf64[i++] = x;
        }
@@@ -74,7 -80,6 +80,7 @@@ static int __init orion_nand_probe(stru
        struct mtd_info *mtd;
        struct nand_chip *nc;
        struct orion_nand_data *board;
 +      struct resource *res;
        void __iomem *io_base;
        int ret = 0;
  #ifdef CONFIG_MTD_PARTITIONS
        }
        mtd = (struct mtd_info *)(nc + 1);
  
 -      io_base = ioremap(pdev->resource[0].start,
 -                      pdev->resource[0].end - pdev->resource[0].start + 1);
 +      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 +      if (!res) {
 +              ret = -ENODEV;
 +              goto no_res;
 +      }
 +
 +      io_base = ioremap(res->start, resource_size(res));
        if (!io_base) {
                printk(KERN_ERR "orion_nand: ioremap failed\n");
                ret = -EIO;
@@@ -21,6 -21,7 +21,7 @@@
  #include <linux/mtd/partitions.h>
  #include <linux/io.h>
  #include <linux/irq.h>
+ #include <linux/slab.h>
  
  #include <mach/dma.h>
  #include <plat/pxa3xx_nand.h>
@@@ -1319,17 -1320,6 +1320,17 @@@ static int pxa3xx_nand_probe(struct pla
                goto fail_free_irq;
        }
  
 +      if (mtd_has_cmdlinepart()) {
 +              static const char *probes[] = { "cmdlinepart", NULL };
 +              struct mtd_partition *parts;
 +              int nr_parts;
 +
 +              nr_parts = parse_mtd_partitions(mtd, probes, &parts, 0);
 +
 +              if (nr_parts)
 +                      return add_mtd_partitions(mtd, parts, nr_parts);
 +      }
 +
        return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts);
  
  fail_free_irq:
@@@ -26,6 -26,7 +26,7 @@@
  #include <linux/delay.h>
  #include <linux/io.h>
  #include <linux/platform_device.h>
+ #include <linux/slab.h>
  
  #include <linux/mtd/mtd.h>
  #include <linux/mtd/nand.h>
@@@ -854,7 -855,7 +855,7 @@@ static int __devinit flctl_probe(struc
                nand->read_word = flctl_read_word;
        }
  
 -      ret = nand_scan_ident(flctl_mtd, 1);
 +      ret = nand_scan_ident(flctl_mtd, 1, NULL);
        if (ret)
                goto err;
  
@@@ -37,6 -37,7 +37,7 @@@
  #include <linux/mtd/nand.h>
  #include <linux/mtd/nand_ecc.h>
  #include <linux/mtd/partitions.h>
+ #include <linux/slab.h>
  
  /*--------------------------------------------------------------------------*/
  
@@@ -318,7 -319,7 +319,7 @@@ static int tmio_nand_correct_data(struc
  
  static int tmio_hw_init(struct platform_device *dev, struct tmio_nand *tmio)
  {
 -      struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
 +      struct mfd_cell *cell = dev_get_platdata(&dev->dev);
        int ret;
  
        if (cell->enable) {
  
  static void tmio_hw_stop(struct platform_device *dev, struct tmio_nand *tmio)
  {
 -      struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
 +      struct mfd_cell *cell = dev_get_platdata(&dev->dev);
  
        tmio_iowrite8(FCR_MODE_POWER_OFF, tmio->fcr + FCR_MODE);
        if (cell->disable)
  
  static int tmio_probe(struct platform_device *dev)
  {
 -      struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
 +      struct mfd_cell *cell = dev_get_platdata(&dev->dev);
        struct tmio_nand_data *data = cell->driver_data;
        struct resource *fcr = platform_get_resource(dev,
                        IORESOURCE_MEM, 0);
        mtd->priv = nand_chip;
        mtd->name = "tmio-nand";
  
 -      tmio->ccr = ioremap(ccr->start, ccr->end - ccr->start + 1);
 +      tmio->ccr = ioremap(ccr->start, resource_size(ccr));
        if (!tmio->ccr) {
                retval = -EIO;
                goto err_iomap_ccr;
        }
  
        tmio->fcr_base = fcr->start & 0xfffff;
 -      tmio->fcr = ioremap(fcr->start, fcr->end - fcr->start + 1);
 +      tmio->fcr = ioremap(fcr->start, resource_size(fcr));
        if (!tmio->fcr) {
                retval = -EIO;
                goto err_iomap_fcr;
@@@ -515,7 -516,7 +516,7 @@@ static int tmio_remove(struct platform_
  #ifdef CONFIG_PM
  static int tmio_suspend(struct platform_device *dev, pm_message_t state)
  {
 -      struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
 +      struct mfd_cell *cell = dev_get_platdata(&dev->dev);
  
        if (cell->suspend)
                cell->suspend(dev);
  
  static int tmio_resume(struct platform_device *dev)
  {
 -      struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
 +      struct mfd_cell *cell = dev_get_platdata(&dev->dev);
  
        /* FIXME - is this required or merely another attack of the broken
         * SHARP platform? Looks suspicious.
@@@ -34,6 -34,7 +34,7 @@@
  #include <linux/delay.h>
  #include <linux/dma-mapping.h>
  #include <linux/io.h>
+ #include <linux/slab.h>
  
  #include <asm/mach/flash.h>
  #include <plat/gpmc.h>
@@@ -308,7 -309,7 +309,7 @@@ static int omap3_onenand_read_bufferram
                goto out_copy;
  
        /* panic_write() may be in an interrupt context */
 -      if (in_interrupt())
 +      if (in_interrupt() || oops_in_progress)
                goto out_copy;
  
        if (buf >= high_memory) {
@@@ -385,7 -386,7 +386,7 @@@ static int omap3_onenand_write_bufferra
                goto out_copy;
  
        /* panic_write() may be in an interrupt context */
 -      if (in_interrupt())
 +      if (in_interrupt() || oops_in_progress)
                goto out_copy;
  
        if (buf >= high_memory) {
  
        dma_src = dma_map_single(&c->pdev->dev, buf, count, DMA_TO_DEVICE);
        dma_dst = c->phys_base + bram_offset;
 -      if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
 +      if (dma_mapping_error(&c->pdev->dev, dma_src)) {
                dev_err(&c->pdev->dev,
                        "Couldn't DMA map a %d byte buffer\n",
                        count);
                if (*done)
                        break;
  
 -      dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_TO_DEVICE);
 +      dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
  
        if (!*done) {
                dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
@@@ -520,7 -521,7 +521,7 @@@ static int omap2_onenand_write_bufferra
        dma_src = dma_map_single(&c->pdev->dev, (void *) buffer, count,
                                 DMA_TO_DEVICE);
        dma_dst = c->phys_base + bram_offset;
 -      if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
 +      if (dma_mapping_error(&c->pdev->dev, dma_src)) {
                dev_err(&c->pdev->dev,
                        "Couldn't DMA map a %d byte buffer\n",
                        count);
        omap_start_dma(c->dma_channel);
        wait_for_completion(&c->dma_done);
  
 -      dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_TO_DEVICE);
 +      dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
  
        return 0;
  }