]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux...
authorDavid Woodhouse <David.Woodhouse@intel.com>
Sat, 30 Oct 2010 11:35:11 +0000 (12:35 +0100)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Sat, 30 Oct 2010 11:35:11 +0000 (12:35 +0100)
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>
1  2 
arch/powerpc/Kconfig
drivers/mtd/chips/cfi_cmdset_0002.c
drivers/mtd/devices/m25p80.c
drivers/mtd/maps/Kconfig
drivers/mtd/maps/pcmciamtd.c
drivers/mtd/mtd_blkdevs.c
drivers/mtd/mtdchar.c
drivers/mtd/nand/omap2.c
fs/jffs2/fs.c

diff --combined arch/powerpc/Kconfig
index 44df1bac970131a12ec2ce5c121f50c54d6bc82a,4b1e521d966f0facaf7d1b70be55ebaf83df3954..29158913a66bff468bb14b742a83e93712694418
@@@ -138,6 -138,7 +138,7 @@@ config PP
        select HAVE_OPROFILE
        select HAVE_SYSCALL_WRAPPERS if PPC64
        select GENERIC_ATOMIC64 if PPC32
+       select HAVE_IRQ_WORK
        select HAVE_PERF_EVENTS
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64
@@@ -687,12 -688,9 +688,12 @@@ config 4xx_SO
        bool
  
  config FSL_LBC
 -      bool
 +      bool "Freescale Local Bus support"
 +      depends on FSL_SOC
        help
 -        Freescale Localbus support
 +        Enables reporting of errors from the Freescale local bus
 +        controller.  Also contains some common code used by
 +        drivers for specific local bus peripherals.
  
  config FSL_GTM
        bool
index 288fc2ea8494d97f3f2f653f9667ad71ee475a58,ba29d2f0ffd77dc6b42bfa55acdcbf0bf97aacea..3b8e32d87977a3c5536e8af83e58795891adaa51
@@@ -291,23 -291,6 +291,23 @@@ static void fixup_sst39vf_rev_b(struct 
  
        cfi->addr_unlock1 = 0x555;
        cfi->addr_unlock2 = 0x2AA;
 +
 +      cfi->sector_erase_cmd = CMD(0x50);
 +}
 +
 +static void fixup_sst38vf640x_sectorsize(struct mtd_info *mtd, void *param)
 +{
 +      struct map_info *map = mtd->priv;
 +      struct cfi_private *cfi = map->fldrv_priv;
 +
 +      fixup_sst39vf_rev_b(mtd, param);
 +
 +      /*
 +       * CFI reports 1024 sectors (0x03ff+1) of 64KBytes (0x0100*256) where
 +       * it should report a size of 8KBytes (0x0020*256).
 +       */
 +      cfi->cfiq->EraseRegionInfo[0] = 0x002003ff;
 +      pr_warning("%s: Bad 38VF640x CFI data; adjusting sector size from 64 to 8KiB\n", mtd->name);
  }
  
  static void fixup_s29gl064n_sectors(struct mtd_info *mtd, void *param)
@@@ -334,14 -317,14 +334,14 @@@ static void fixup_s29gl032n_sectors(str
  
  /* Used to fix CFI-Tables of chips without Extended Query Tables */
  static struct cfi_fixup cfi_nopri_fixup_table[] = {
 -      { CFI_MFR_SST, 0x234A, fixup_sst39vf, NULL, }, // SST39VF1602
 -      { CFI_MFR_SST, 0x234B, fixup_sst39vf, NULL, }, // SST39VF1601
 -      { CFI_MFR_SST, 0x235A, fixup_sst39vf, NULL, }, // SST39VF3202
 -      { CFI_MFR_SST, 0x235B, fixup_sst39vf, NULL, }, // SST39VF3201
 -      { CFI_MFR_SST, 0x235C, fixup_sst39vf_rev_b, NULL, }, // SST39VF3202B
 -      { CFI_MFR_SST, 0x235D, fixup_sst39vf_rev_b, NULL, }, // SST39VF3201B
 -      { CFI_MFR_SST, 0x236C, fixup_sst39vf_rev_b, NULL, }, // SST39VF6402B
 -      { CFI_MFR_SST, 0x236D, fixup_sst39vf_rev_b, NULL, }, // SST39VF6401B
 +      { CFI_MFR_SST, 0x234A, fixup_sst39vf, NULL, }, /* SST39VF1602 */
 +      { CFI_MFR_SST, 0x234B, fixup_sst39vf, NULL, }, /* SST39VF1601 */
 +      { CFI_MFR_SST, 0x235A, fixup_sst39vf, NULL, }, /* SST39VF3202 */
 +      { CFI_MFR_SST, 0x235B, fixup_sst39vf, NULL, }, /* SST39VF3201 */
 +      { CFI_MFR_SST, 0x235C, fixup_sst39vf_rev_b, NULL, }, /* SST39VF3202B */
 +      { CFI_MFR_SST, 0x235D, fixup_sst39vf_rev_b, NULL, }, /* SST39VF3201B */
 +      { CFI_MFR_SST, 0x236C, fixup_sst39vf_rev_b, NULL, }, /* SST39VF6402B */
 +      { CFI_MFR_SST, 0x236D, fixup_sst39vf_rev_b, NULL, }, /* SST39VF6401B */
        { 0, 0, NULL, NULL }
  };
  
@@@ -361,10 -344,6 +361,10 @@@ static struct cfi_fixup cfi_fixup_table
        { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, },
        { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, },
        { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, },
 +      { CFI_MFR_SST, 0x536A, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6402 */
 +      { CFI_MFR_SST, 0x536B, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6401 */
 +      { CFI_MFR_SST, 0x536C, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6404 */
 +      { CFI_MFR_SST, 0x536D, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6403 */
  #if !FORCE_WORD_WRITE
        { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, },
  #endif
@@@ -395,13 -374,6 +395,13 @@@ static void cfi_fixup_major_minor(struc
        if (cfi->mfr == CFI_MFR_SAMSUNG && cfi->id == 0x257e &&
            extp->MajorVersion == '0')
                extp->MajorVersion = '1';
 +      /*
 +       * SST 38VF640x chips report major=0xFF / minor=0xFF.
 +       */
 +      if (cfi->mfr == CFI_MFR_SST && (cfi->id >> 4) == 0x0536) {
 +              extp->MajorVersion = '1';
 +              extp->MinorVersion = '0';
 +      }
  }
  
  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' ||
@@@ -573,6 -545,15 +573,6 @@@ static struct mtd_info *cfi_amdstd_setu
                printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);
                goto setup_err;
        }
 -#if 0
 -      // debug
 -      for (i=0; i<mtd->numeraseregions;i++){
 -              printk("%d: offset=0x%x,size=0x%x,blocks=%d\n",
 -                     i,mtd->eraseregions[i].offset,
 -                     mtd->eraseregions[i].erasesize,
 -                     mtd->eraseregions[i].numblocks);
 -      }
 -#endif
  
        __module_get(THIS_MODULE);
        register_reboot_notifier(&mtd->reboot_notifier);
@@@ -693,7 -674,7 +693,7 @@@ static int get_chip(struct map_info *ma
                                 * there was an error (so leave the erase
                                 * routine to recover from it) or we trying to
                                 * use the erase-in-progress sector. */
 -                              map_write(map, CMD(0x30), chip->in_progress_block_addr);
 +                              map_write(map, cfi->sector_erase_cmd, chip->in_progress_block_addr);
                                chip->state = FL_ERASING;
                                chip->oldstate = FL_READY;
                                printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__);
@@@ -746,7 -727,7 +746,7 @@@ static void put_chip(struct map_info *m
        switch(chip->oldstate) {
        case FL_ERASING:
                chip->state = chip->oldstate;
 -              map_write(map, CMD(0x30), chip->in_progress_block_addr);
 +              map_write(map, cfi->sector_erase_cmd, chip->in_progress_block_addr);
                chip->oldstate = FL_READY;
                chip->state = FL_ERASING;
                break;
@@@ -889,7 -870,7 +889,7 @@@ static void __xipram xip_udelay(struct 
                        local_irq_disable();
  
                        /* Resume the write or erase operation */
 -                      map_write(map, CMD(0x30), adr);
 +                      map_write(map, cfi->sector_erase_cmd, adr);
                        chip->state = oldstate;
                        start = xip_currtime();
                } else if (usec >= 1000000/HZ) {
@@@ -1044,6 -1025,9 +1044,6 @@@ static inline int do_read_secsi_onechip
        mutex_lock(&chip->mutex);
  
        if (chip->state != FL_READY){
 -#if 0
 -              printk(KERN_DEBUG "Waiting for chip to read, status = %d\n", chip->state);
 -#endif
                set_current_state(TASK_UNINTERRUPTIBLE);
                add_wait_queue(&chip->wq, &wait);
  
  
                schedule();
                remove_wait_queue(&chip->wq, &wait);
 -#if 0
 -              if(signal_pending(current))
 -                      return -EINTR;
 -#endif
                timeo = jiffies + HZ;
  
                goto retry;
@@@ -1258,6 -1246,9 +1258,6 @@@ static int cfi_amdstd_write_words(struc
                mutex_lock(&cfi->chips[chipnum].mutex);
  
                if (cfi->chips[chipnum].state != FL_READY) {
 -#if 0
 -                      printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", cfi->chips[chipnum].state);
 -#endif
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&cfi->chips[chipnum].wq, &wait);
  
  
                        schedule();
                        remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
 -#if 0
 -                      if(signal_pending(current))
 -                              return -EINTR;
 -#endif
                        goto retry;
                }
  
                mutex_lock(&cfi->chips[chipnum].mutex);
  
                if (cfi->chips[chipnum].state != FL_READY) {
 -#if 0
 -                      printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", cfi->chips[chipnum].state);
 -#endif
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&cfi->chips[chipnum].wq, &wait);
  
  
                        schedule();
                        remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
 -#if 0
 -                      if(signal_pending(current))
 -                              return -EINTR;
 -#endif
                        goto retry1;
                }
  
@@@ -1394,6 -1396,7 +1394,6 @@@ static int __xipram do_write_buffer(str
  
        cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
        cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
 -      //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
  
        /* Write Buffer Load */
        map_write(map, CMD(0x25), cmd_adr);
@@@ -1672,7 -1675,7 +1672,7 @@@ static int __xipram do_erase_oneblock(s
        cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
        cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
        cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
 -      map_write(map, CMD(0x30), adr);
 +      map_write(map, cfi->sector_erase_cmd, adr);
  
        chip->state = FL_ERASING;
        chip->erase_suspended = 0;
index 7e0edd40ad4149f7c6653ffdc17fa102eef0102c,ea22520c0406ed6a7c7a3537ee7ce64adf558481..669d2b7e36bb758fd5b41ceab37bf29c95ad7fca
@@@ -661,14 -661,11 +661,14 @@@ static const struct spi_device_id m25p_
        { "s25sl008a",  INFO(0x010213,      0,  64 * 1024,  16, 0) },
        { "s25sl016a",  INFO(0x010214,      0,  64 * 1024,  32, 0) },
        { "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64, 0) },
 +      { "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, SECT_4K) },
        { "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128, 0) },
        { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
        { "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
        { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, 0) },
        { "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, 0) },
 +      { "s25fl016k",  INFO(0xef4015,      0,  64 * 1024,  32, SECT_4K) },
 +      { "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128, SECT_4K) },
  
        /* SST -- large erase sizes are "overlays", "sectors" are 4K */
        { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8, SECT_4K) },
        { "w25x32", INFO(0xef3016, 0, 64 * 1024,  64, SECT_4K) },
        { "w25q32", INFO(0xef4016, 0, 64 * 1024,  64, SECT_4K) },
        { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
 +      { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
  
        /* Catalyst / On Semiconductor -- non-JEDEC */
        { "cat25c11", CAT25_INFO(  16, 8, 16, 1) },
@@@ -928,6 -924,13 +928,13 @@@ static int __devinit m25p_probe(struct 
                        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 --combined drivers/mtd/maps/Kconfig
index e5eb65cfb3eb9d7c77ff70854c2420fa67b1dbc3,962212628f6e3400ec171646c04139b6920cd9be..a0dd7bba9481ce1e3480ffe0ee55902994653731
@@@ -172,7 -172,7 +172,7 @@@ config MTD_OCTAGO
          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"
@@@ -251,15 -251,6 +251,15 @@@ config MTD_NETte
        help
          Support for flash chips on NETtel/SecureEdge/SnapGear boards.
  
 +config MTD_BCM963XX
 +        tristate "Map driver for Broadcom BCM963xx boards"
 +        depends on BCM63XX
 +      select MTD_MAP_BANK_WIDTH_2
 +      select MTD_CFI_I1
 +        help
 +        Support for parsing CFE image tag and creating MTD partitions on
 +        Broadcom BCM63xx boards.
 +
  config MTD_DILNETPC
        tristate "CFI Flash device mapped on DIL/Net PC"
        depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN
@@@ -293,7 -284,7 +293,7 @@@ config MTD_TQM8XX
          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"
index 86c74685eb7b0b3e812e150f1f196e26df064ab0,57a1acfe22c4a2df13903e42918b14ac47f875a4..91702294839942e8c225ed3f3176011a489d2d61
@@@ -16,7 -16,6 +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 +100,7 @@@ MODULE_PARM_DESC(mem_type, "Set Memory 
  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 +315,19 @@@ static void pcmciamtd_set_vpp(struct ma
  {
        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 +470,12 @@@ static void card_settings(struct pcmcia
  }
  
  
- /* 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;
  
         * 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);
  
        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);
        }
        dev_info(&dev->p_dev->dev, "mtd%d: %s\n", mtd->index, mtd->name);
        return 0;
 -
 -      dev_err(&dev->p_dev->dev, "CS Error, exiting\n");
 -      pcmciamtd_release(link);
 -      return -ENODEV;
  }
  
  
@@@ -676,12 -666,6 +662,6 @@@ static int pcmciamtd_resume(struct pcmc
  }
  
  
- /* 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;
  }
  
  
- /* 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;
        dev->p_dev = link;
        link->priv = dev;
  
-       link->conf.Attributes = 0;
-       link->conf.IntType = INT_MEMORY;
        return pcmciamtd_config(link);
  }
  
@@@ -753,9 -729,7 +725,7 @@@ static struct pcmcia_device_id pcmciamt
  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,
  
  static int __init init_pcmciamtd(void)
  {
-       info(DRIVER_DESC);
        if(bankwidth && bankwidth != 1 && bankwidth != 2) {
                info("bad bankwidth (%d), using default", bankwidth);
                bankwidth = 2;
index 63790e975d204087feee6675a1deb1c68f3c6b1f,50ab431b24ebafd456269061ac7a6873c152a57d..f9329794f3b554936f13fda170ddb0d16eb9bc57
@@@ -29,7 -29,6 +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 +37,7 @@@
  
  #include "mtdcore.h"
  
+ static DEFINE_MUTEX(mtd_blkdevs_mutex);
  static LIST_HEAD(blktrans_majors);
  static DEFINE_MUTEX(blktrans_ref_mutex);
  
@@@ -133,10 -133,6 +133,10 @@@ static int mtd_blktrans_thread(void *ar
  
                if (!req && !(req = blk_fetch_request(rq))) {
                        set_current_state(TASK_INTERRUPTIBLE);
 +
 +                      if (kthread_should_stop())
 +                              set_current_state(TASK_RUNNING);
 +
                        spin_unlock_irq(rq->queue_lock);
                        schedule();
                        spin_lock_irq(rq->queue_lock);
@@@ -180,53 -176,54 +180,57 @@@ static void mtd_blktrans_request(struc
  static int blktrans_open(struct block_device *bdev, fmode_t mode)
  {
        struct mtd_blktrans_dev *dev = blktrans_dev_get(bdev->bd_disk);
 -      int ret;
 +      int ret = 0;
  
        if (!dev)
                return -ERESTARTSYS; /* FIXME: busy loop! -arnd*/
  
+       mutex_lock(&mtd_blkdevs_mutex);
        mutex_lock(&dev->lock);
  
 -      if (!dev->mtd) {
 -              ret = -ENXIO;
 +      if (dev->open++)
                goto unlock;
 -      }
  
 -      ret = !dev->open++ && dev->tr->open ? dev->tr->open(dev) : 0;
 +      kref_get(&dev->ref);
 +      __module_get(dev->tr->owner);
 +
 +      if (dev->mtd) {
 +              ret = dev->tr->open ? dev->tr->open(dev) : 0;
 +              __get_mtd_device(dev->mtd);
 +      }
  
 -      /* Take another reference on the device so it won't go away till
 -              last release */
 -      if (!ret)
 -              kref_get(&dev->ref);
  unlock:
        mutex_unlock(&dev->lock);
        blktrans_dev_put(dev);
+       mutex_unlock(&mtd_blkdevs_mutex);
        return ret;
  }
  
  static int blktrans_release(struct gendisk *disk, fmode_t mode)
  {
        struct mtd_blktrans_dev *dev = blktrans_dev_get(disk);
 -      int ret = -ENXIO;
 +      int ret = 0;
  
        if (!dev)
                return ret;
  
+       mutex_lock(&mtd_blkdevs_mutex);
        mutex_lock(&dev->lock);
  
 -      /* Release one reference, we sure its not the last one here*/
 -      kref_put(&dev->ref, blktrans_dev_release);
 -
 -      if (!dev->mtd)
 +      if (--dev->open)
                goto unlock;
  
 -      ret = !--dev->open && dev->tr->release ? dev->tr->release(dev) : 0;
 +      kref_put(&dev->ref, blktrans_dev_release);
 +      module_put(dev->tr->owner);
 +
 +      if (dev->mtd) {
 +              ret = dev->tr->release ? dev->tr->release(dev) : 0;
 +              __put_mtd_device(dev->mtd);
 +      }
  unlock:
        mutex_unlock(&dev->lock);
        blktrans_dev_put(dev);
+       mutex_unlock(&mtd_blkdevs_mutex);
        return ret;
  }
  
@@@ -259,6 -256,7 +263,7 @@@ static int blktrans_ioctl(struct block_
        if (!dev)
                return ret;
  
+       mutex_lock(&mtd_blkdevs_mutex);
        mutex_lock(&dev->lock);
  
        if (!dev->mtd)
        }
  unlock:
        mutex_unlock(&dev->lock);
+       mutex_unlock(&mtd_blkdevs_mutex);
        blktrans_dev_put(dev);
        return ret;
  }
@@@ -386,6 -385,9 +392,6 @@@ int add_mtd_blktrans_dev(struct mtd_blk
  
        gd->queue = new->rq;
  
 -      __get_mtd_device(new->mtd);
 -      __module_get(tr->owner);
 -
        /* Create processing thread */
        /* TODO: workqueue ? */
        new->thread = kthread_run(mtd_blktrans_thread, new,
        }
        return 0;
  error4:
 -      module_put(tr->owner);
 -      __put_mtd_device(new->mtd);
        blk_cleanup_queue(new->rq);
  error3:
        put_disk(new->disk);
@@@ -444,15 -448,17 +450,15 @@@ int del_mtd_blktrans_dev(struct mtd_blk
        blk_start_queue(old->rq);
        spin_unlock_irqrestore(&old->queue_lock, flags);
  
 -      /* Ask trans driver for release to the mtd device */
 +      /* If the device is currently open, tell trans driver to close it,
 +              then put mtd device, and don't touch it again */
        mutex_lock(&old->lock);
 -      if (old->open && old->tr->release) {
 -              old->tr->release(old);
 -              old->open = 0;
 +      if (old->open) {
 +              if (old->tr->release)
 +                      old->tr->release(old);
 +              __put_mtd_device(old->mtd);
        }
  
 -      __put_mtd_device(old->mtd);
 -      module_put(old->tr->owner);
 -
 -      /* At that point, we don't touch the mtd anymore */
        old->mtd = NULL;
  
        mutex_unlock(&old->lock);
@@@ -502,16 -508,13 +508,16 @@@ int register_mtd_blktrans(struct mtd_bl
        mutex_lock(&mtd_table_mutex);
  
        ret = register_blkdev(tr->major, tr->name);
 -      if (ret) {
 +      if (ret < 0) {
                printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n",
                       tr->name, tr->major, ret);
                mutex_unlock(&mtd_table_mutex);
                return ret;
        }
  
 +      if (ret)
 +              tr->major = ret;
 +
        tr->blkshift = ffs(tr->blksize) - 1;
  
        INIT_LIST_HEAD(&tr->devs);
diff --combined drivers/mtd/mtdchar.c
index b7ed09c579031fed9c77d2cbdca1035f3a3d5ba9,5ef45487b65f01c261222b35d5fd6ecc548bea7e..3eff1e562ad3c96ca168432b829d8dca5f36abea
  #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>
 -
 +#include <linux/blkpg.h>
  #include <linux/mtd/mtd.h>
 +#include <linux/mtd/partitions.h>
  #include <linux/mtd/map.h>
  
  #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 -91,7 +92,7 @@@ static int mtd_open(struct inode *inode
        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)) {
        file->private_data = mfi;
  
  out:
-       unlock_kernel();
+       mutex_unlock(&mtd_mutex);
        return ret;
  } /* mtd_open */
  
@@@ -478,78 -478,6 +479,78 @@@ static int mtd_do_readoob(struct mtd_in
        return ret;
  }
  
 +/*
 + * Copies (and truncates, if necessary) data from the larger struct,
 + * nand_ecclayout, to the smaller, deprecated layout struct,
 + * nand_ecclayout_user. This is necessary only to suppport the deprecated
 + * API ioctl ECCGETLAYOUT while allowing all new functionality to use
 + * nand_ecclayout flexibly (i.e. the struct may change size in new
 + * releases without requiring major rewrites).
 + */
 +static int shrink_ecclayout(const struct nand_ecclayout *from,
 +              struct nand_ecclayout_user *to)
 +{
 +      int i;
 +
 +      if (!from || !to)
 +              return -EINVAL;
 +
 +      memset(to, 0, sizeof(*to));
 +
 +      to->eccbytes = min((int)from->eccbytes, MTD_MAX_ECCPOS_ENTRIES);
 +      for (i = 0; i < to->eccbytes; i++)
 +              to->eccpos[i] = from->eccpos[i];
 +
 +      for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++) {
 +              if (from->oobfree[i].length == 0 &&
 +                              from->oobfree[i].offset == 0)
 +                      break;
 +              to->oobavail += from->oobfree[i].length;
 +              to->oobfree[i] = from->oobfree[i];
 +      }
 +
 +      return 0;
 +}
 +
 +#ifdef CONFIG_MTD_PARTITIONS
 +static int mtd_blkpg_ioctl(struct mtd_info *mtd,
 +                         struct blkpg_ioctl_arg __user *arg)
 +{
 +      struct blkpg_ioctl_arg a;
 +      struct blkpg_partition p;
 +
 +      if (!capable(CAP_SYS_ADMIN))
 +              return -EPERM;
 +
 +      /* Only master mtd device must be used to control partitions */
 +      if (!mtd_is_master(mtd))
 +              return -EINVAL;
 +
 +      if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg)))
 +              return -EFAULT;
 +
 +      if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
 +              return -EFAULT;
 +
 +      switch (a.op) {
 +      case BLKPG_ADD_PARTITION:
 +
 +              return mtd_add_partition(mtd, p.devname, p.start, p.length);
 +
 +      case BLKPG_DEL_PARTITION:
 +
 +              if (p.pno < 0)
 +                      return -EINVAL;
 +
 +              return mtd_del_partition(mtd, p.pno);
 +
 +      default:
 +              return -EINVAL;
 +      }
 +}
 +#endif
 +
 +
  static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
  {
        struct mtd_file_info *mfi = file->private_data;
                if (get_user(ur_idx, &(ur->regionindex)))
                        return -EFAULT;
  
 +              if (ur_idx >= mtd->numeraseregions)
 +                      return -EINVAL;
 +
                kr = &(mtd->eraseregions[ur_idx]);
  
                if (put_user(kr->offset, &(ur->offset))
        }
  #endif
  
 +      /* This ioctl is being deprecated - it truncates the ecc layout */
        case ECCGETLAYOUT:
        {
 +              struct nand_ecclayout_user *usrlay;
 +
                if (!mtd->ecclayout)
                        return -EOPNOTSUPP;
  
 -              if (copy_to_user(argp, mtd->ecclayout,
 -                               sizeof(struct nand_ecclayout)))
 -                      return -EFAULT;
 +              usrlay = kmalloc(sizeof(*usrlay), GFP_KERNEL);
 +              if (!usrlay)
 +                      return -ENOMEM;
 +
 +              shrink_ecclayout(mtd->ecclayout, usrlay);
 +
 +              if (copy_to_user(argp, usrlay, sizeof(*usrlay)))
 +                      ret = -EFAULT;
 +              kfree(usrlay);
                break;
        }
  
                break;
        }
  
 +#ifdef CONFIG_MTD_PARTITIONS
 +      case BLKPG:
 +      {
 +              ret = mtd_blkpg_ioctl(mtd,
 +                    (struct blkpg_ioctl_arg __user *)arg);
 +              break;
 +      }
 +
 +      case BLKRRPART:
 +      {
 +              /* No reread partition feature. Just return ok */
 +              ret = 0;
 +              break;
 +      }
 +#endif
 +
        default:
                ret = -ENOTTY;
        }
@@@ -967,9 -867,9 +968,9 @@@ static long mtd_unlocked_ioctl(struct f
  {
        int ret;
  
-       lock_kernel();
+       mutex_lock(&mtd_mutex);
        ret = mtd_ioctl(file, cmd, arg);
-       unlock_kernel();
+       mutex_unlock(&mtd_mutex);
  
        return ret;
  }
@@@ -993,7 -893,7 +994,7 @@@ static long mtd_compat_ioctl(struct fil
        void __user *argp = compat_ptr(arg);
        int ret = 0;
  
-       lock_kernel();
+       mutex_lock(&mtd_mutex);
  
        switch (cmd) {
        case MEMWRITEOOB32:
                ret = mtd_ioctl(file, cmd, (unsigned long)argp);
        }
  
-       unlock_kernel();
+       mutex_unlock(&mtd_mutex);
  
        return ret;
  }
@@@ -1134,7 -1034,7 +1135,7 @@@ static int mtd_inodefs_get_sb(struct fi
                                 const char *dev_name, void *data,
                                 struct vfsmount *mnt)
  {
 -        return get_sb_pseudo(fs_type, "mtd_inode:", NULL, MTD_INODE_FS_MAGIC,
 +      return get_sb_pseudo(fs_type, "mtd_inode:", NULL, MTD_INODE_FS_MAGIC,
                               mnt);
  }
  
diff --combined drivers/mtd/nand/omap2.c
index 439e80d78edd5ec12e27052dfa86eb2b33459296,513e0a76a4a73866d52bba8151e43556a3b30a54..cd41c58b5bbd50f8ed905a1a6da71dedc5cfca7e
@@@ -111,11 -111,11 +111,11 @@@ static int use_dma = 1
  module_param(use_dma, bool, 0);
  MODULE_PARM_DESC(use_dma, "enable/disable use of DMA");
  #else
 -const int use_dma;
 +static const int use_dma;
  #endif
  #else
  const int use_prefetch;
 -const int use_dma;
 +static const int use_dma;
  #endif
  
  struct omap_nand_info {
@@@ -413,7 -413,7 +413,7 @@@ static inline int omap_nand_dma_transfe
                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 --combined fs/jffs2/fs.c
index 2701b372da78eeb5f18054bc931a10c6d26ccaff,d9beb06e6fcaf55c7fdc2f46367ce2f280bff859..e896e67767eb9e10515f37a7608fd7bdcc2d330d
@@@ -21,7 -21,6 +21,6 @@@
  #include <linux/vmalloc.h>
  #include <linux/vfs.h>
  #include <linux/crc32.h>
- #include <linux/smp_lock.h>
  #include "nodelist.h"
  
  static int jffs2_flash_setup(struct jffs2_sb_info *c);
@@@ -391,7 -390,6 +390,6 @@@ int jffs2_remount_fs (struct super_bloc
           This also catches the case where it was stopped and this
           is just a remount to restart it.
           Flush the writebuffer, if neccecary, else we loose it */
-       lock_kernel();
        if (!(sb->s_flags & MS_RDONLY)) {
                jffs2_stop_garbage_collect_thread(c);
                mutex_lock(&c->alloc_sem);
                jffs2_start_garbage_collect_thread(c);
  
        *flags |= MS_NOATIME;
-       unlock_kernel();
        return 0;
  }
  
@@@ -478,25 -474,6 +474,25 @@@ struct inode *jffs2_new_inode (struct i
        return inode;
  }
  
 +static int calculate_inocache_hashsize(uint32_t flash_size)
 +{
 +      /*
 +       * Pick a inocache hash size based on the size of the medium.
 +       * Count how many megabytes we're dealing with, apply a hashsize twice
 +       * that size, but rounding down to the usual big powers of 2. And keep
 +       * to sensible bounds.
 +       */
 +
 +      int size_mb = flash_size / 1024 / 1024;
 +      int hashsize = (size_mb * 2) & ~0x3f;
 +
 +      if (hashsize < INOCACHE_HASHSIZE_MIN)
 +              return INOCACHE_HASHSIZE_MIN;
 +      if (hashsize > INOCACHE_HASHSIZE_MAX)
 +              return INOCACHE_HASHSIZE_MAX;
 +
 +      return hashsize;
 +}
  
  int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
  {
        if (ret)
                return ret;
  
 -      c->inocache_list = kcalloc(INOCACHE_HASHSIZE, sizeof(struct jffs2_inode_cache *), GFP_KERNEL);
 +      c->inocache_hashsize = calculate_inocache_hashsize(c->flash_size);
 +      c->inocache_list = kcalloc(c->inocache_hashsize, sizeof(struct jffs2_inode_cache *), GFP_KERNEL);
        if (!c->inocache_list) {
                ret = -ENOMEM;
                goto out_wbuf;