Merge git://git.infradead.org/mtd-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 21 May 2010 14:25:43 +0000 (07:25 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 21 May 2010 14:25:43 +0000 (07:25 -0700)
* git://git.infradead.org/mtd-2.6: (154 commits)
  mtd: cfi_cmdset_0002: use AMD standard command-set with Winbond flash chips
  mtd: cfi_cmdset_0002: Fix MODULE_ALIAS and linkage for new 0701 commandset ID
  mtd: mxc_nand: Remove duplicate NAND_CMD_RESET case value
  mtd: update gfp/slab.h includes
  jffs2: Stop triggering block erases from jffs2_write_super()
  jffs2: Rename jffs2_erase_pending_trigger() to jffs2_dirty_trigger()
  jffs2: Use jffs2_garbage_collect_trigger() to trigger pending erases
  jffs2: Require jffs2_garbage_collect_trigger() to be called with lock held
  jffs2: Wake GC thread when there are blocks to be erased
  jffs2: Erase pending blocks in GC pass, avoid invalid -EIO return
  jffs2: Add 'work_done' return value from jffs2_erase_pending_blocks()
  mtd: mtdchar: Do not corrupt backing device of device node inode
  mtd/maps/pcmciamtd: Fix printk format for ssize_t in debug messages
  drivers/mtd: Use kmemdup
  mtd: cfi_cmdset_0002: Fix argument order in bootloc warning
  mtd: nand: add Toshiba TC58NVG0 device ID
  pcmciamtd: add another ID
  pcmciamtd: coding style cleanups
  pcmciamtd: fixing obvious errors
  mtd: chips: add SST39WF160x NOR-flashes
  ...

Trivial conflicts due to dev_node removal in drivers/mtd/maps/pcmciamtd.c

117 files changed:
MAINTAINERS
arch/arm/mach-ep93xx/include/mach/ts72xx.h
arch/arm/mach-ep93xx/ts72xx.c
arch/arm/mach-kirkwood/common.c
arch/arm/mach-kirkwood/common.h
arch/arm/plat-orion/include/plat/orion_nand.h
drivers/mtd/Kconfig
drivers/mtd/Makefile
drivers/mtd/chips/cfi_cmdset_0001.c
drivers/mtd/chips/cfi_cmdset_0002.c
drivers/mtd/chips/cfi_cmdset_0020.c
drivers/mtd/chips/cfi_probe.c
drivers/mtd/chips/cfi_util.c
drivers/mtd/chips/fwh_lock.h
drivers/mtd/chips/gen_probe.c
drivers/mtd/chips/jedec_probe.c
drivers/mtd/devices/Makefile
drivers/mtd/devices/block2mtd.c
drivers/mtd/devices/pmc551.c
drivers/mtd/devices/sst25l.c
drivers/mtd/ftl.c
drivers/mtd/inftlcore.c
drivers/mtd/inftlmount.c
drivers/mtd/lpddr/lpddr_cmds.c
drivers/mtd/lpddr/qinfo_probe.c
drivers/mtd/maps/Kconfig
drivers/mtd/maps/bfin-async-flash.c
drivers/mtd/maps/ceiva.c
drivers/mtd/maps/ixp2000.c
drivers/mtd/maps/ixp4xx.c
drivers/mtd/maps/pcmciamtd.c
drivers/mtd/maps/physmap.c
drivers/mtd/maps/physmap_of.c
drivers/mtd/maps/pismo.c
drivers/mtd/maps/pxa2xx-flash.c
drivers/mtd/mtd_blkdevs.c
drivers/mtd/mtdblock.c
drivers/mtd/mtdblock_ro.c
drivers/mtd/mtdchar.c
drivers/mtd/mtdconcat.c
drivers/mtd/mtdcore.c
drivers/mtd/mtdcore.h
drivers/mtd/mtdoops.c
drivers/mtd/mtdsuper.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/Makefile
drivers/mtd/nand/alauda.c
drivers/mtd/nand/atmel_nand.c
drivers/mtd/nand/au1550nd.c
drivers/mtd/nand/bcm_umi_nand.c
drivers/mtd/nand/bf5xx_nand.c
drivers/mtd/nand/cafe_nand.c
drivers/mtd/nand/davinci_nand.c
drivers/mtd/nand/denali.c [new file with mode: 0644]
drivers/mtd/nand/denali.h [new file with mode: 0644]
drivers/mtd/nand/fsl_elbc_nand.c
drivers/mtd/nand/fsl_upm.c
drivers/mtd/nand/gpio.c
drivers/mtd/nand/mpc5121_nfc.c [new file with mode: 0644]
drivers/mtd/nand/mxc_nand.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_bbt.c
drivers/mtd/nand/nand_bcm_umi.h
drivers/mtd/nand/nand_ids.c
drivers/mtd/nand/nandsim.c
drivers/mtd/nand/nomadik_nand.c
drivers/mtd/nand/nuc900_nand.c [moved from drivers/mtd/nand/w90p910_nand.c with 63% similarity]
drivers/mtd/nand/omap2.c
drivers/mtd/nand/orion_nand.c
drivers/mtd/nand/pasemi_nand.c
drivers/mtd/nand/pxa3xx_nand.c
drivers/mtd/nand/r852.c [new file with mode: 0644]
drivers/mtd/nand/r852.h [new file with mode: 0644]
drivers/mtd/nand/s3c2410.c
drivers/mtd/nand/sh_flctl.c
drivers/mtd/nand/sm_common.c [new file with mode: 0644]
drivers/mtd/nand/sm_common.h [new file with mode: 0644]
drivers/mtd/nand/socrates_nand.c
drivers/mtd/nand/tmio_nand.c
drivers/mtd/nand/ts7250.c [deleted file]
drivers/mtd/nand/txx9ndfmc.c
drivers/mtd/nftlcore.c
drivers/mtd/onenand/Kconfig
drivers/mtd/onenand/Makefile
drivers/mtd/onenand/omap2.c
drivers/mtd/onenand/onenand_base.c
drivers/mtd/onenand/samsung.c [new file with mode: 0644]
drivers/mtd/rfd_ftl.c
drivers/mtd/sm_ftl.c [new file with mode: 0644]
drivers/mtd/sm_ftl.h [new file with mode: 0644]
drivers/mtd/ssfdc.c
drivers/mtd/tests/mtd_pagetest.c
drivers/mtd/tests/mtd_readtest.c
drivers/mtd/tests/mtd_speedtest.c
drivers/mtd/tests/mtd_stresstest.c
drivers/mtd/tests/mtd_subpagetest.c
fs/jffs2/background.c
fs/jffs2/erase.c
fs/jffs2/fs.c
fs/jffs2/gc.c
fs/jffs2/nodelist.h
fs/jffs2/nodemgmt.c
fs/jffs2/os-linux.h
fs/jffs2/scan.c
fs/jffs2/super.c
fs/jffs2/wbuf.c
include/linux/jffs2.h
include/linux/mtd/blktrans.h
include/linux/mtd/cfi.h
include/linux/mtd/flashchip.h
include/linux/mtd/map.h
include/linux/mtd/mtd.h
include/linux/mtd/mtdram.h
include/linux/mtd/nand.h
include/linux/mtd/onenand.h
include/linux/mtd/sh_flctl.h
lib/idr.c

index 601ede3..a31a717 100644 (file)
@@ -4762,6 +4762,12 @@ S:       Maintained
 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
index 93107d8..0eabec6 100644 (file)
@@ -9,9 +9,6 @@
  * febff000    22000000        4K      model number register
  * febfe000    22400000        4K      options register
  * febfd000    22800000        4K      options register #2
- * febfc000    [67]0000000     4K      NAND data register
- * febfb000    [67]0400000     4K      NAND control register
- * febfa000    [67]0800000     4K      NAND busy register
  * febf9000    10800000        4K      TS-5620 RTC index register
  * febf8000    11700000        4K      TS-5620 RTC data register
  */
 #define TS72XX_OPTIONS2_TS9420_BOOT    0x02
 
 
-#define TS72XX_NAND1_DATA_PHYS_BASE    0x60000000
-#define TS72XX_NAND2_DATA_PHYS_BASE    0x70000000
-#define TS72XX_NAND_DATA_VIRT_BASE     0xfebfc000
-#define TS72XX_NAND_DATA_SIZE          0x00001000
-
-#define TS72XX_NAND1_CONTROL_PHYS_BASE 0x60400000
-#define TS72XX_NAND2_CONTROL_PHYS_BASE 0x70400000
-#define TS72XX_NAND_CONTROL_VIRT_BASE  0xfebfb000
-#define TS72XX_NAND_CONTROL_SIZE       0x00001000
-
-#define TS72XX_NAND1_BUSY_PHYS_BASE    0x60800000
-#define TS72XX_NAND2_BUSY_PHYS_BASE    0x70800000
-#define TS72XX_NAND_BUSY_VIRT_BASE     0xfebfa000
-#define TS72XX_NAND_BUSY_SIZE          0x00001000
-
-
 #define TS72XX_RTC_INDEX_VIRT_BASE     0xfebf9000
 #define TS72XX_RTC_INDEX_PHYS_BASE     0x10800000
 #define TS72XX_RTC_INDEX_SIZE          0x00001000
index 9553031..ae7319e 100644 (file)
  * your option) any later version.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/m48t86.h>
 #include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
 
 #include <mach/hardware.h>
 #include <mach/ts72xx.h>
@@ -54,92 +58,162 @@ static struct map_desc ts72xx_io_desc[] __initdata = {
        }
 };
 
-static struct map_desc ts72xx_nand_io_desc[] __initdata = {
-       {
-               .virtual        = TS72XX_NAND_DATA_VIRT_BASE,
-               .pfn            = __phys_to_pfn(TS72XX_NAND1_DATA_PHYS_BASE),
-               .length         = TS72XX_NAND_DATA_SIZE,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = TS72XX_NAND_CONTROL_VIRT_BASE,
-               .pfn            = __phys_to_pfn(TS72XX_NAND1_CONTROL_PHYS_BASE),
-               .length         = TS72XX_NAND_CONTROL_SIZE,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = TS72XX_NAND_BUSY_VIRT_BASE,
-               .pfn            = __phys_to_pfn(TS72XX_NAND1_BUSY_PHYS_BASE),
-               .length         = TS72XX_NAND_BUSY_SIZE,
-               .type           = MT_DEVICE,
+static void __init ts72xx_map_io(void)
+{
+       ep93xx_map_io();
+       iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc));
+}
+
+
+/*************************************************************************
+ * NAND flash
+ *************************************************************************/
+#define TS72XX_NAND_CONTROL_ADDR_LINE  22      /* 0xN0400000 */
+#define TS72XX_NAND_BUSY_ADDR_LINE     23      /* 0xN0800000 */
+
+static void ts72xx_nand_hwcontrol(struct mtd_info *mtd,
+                                 int cmd, unsigned int ctrl)
+{
+       struct nand_chip *chip = mtd->priv;
+
+       if (ctrl & NAND_CTRL_CHANGE) {
+               void __iomem *addr = chip->IO_ADDR_R;
+               unsigned char bits;
+
+               addr += (1 << TS72XX_NAND_CONTROL_ADDR_LINE);
+
+               bits = __raw_readb(addr) & ~0x07;
+               bits |= (ctrl & NAND_NCE) << 2; /* bit 0 -> bit 2 */
+               bits |= (ctrl & NAND_CLE);      /* bit 1 -> bit 1 */
+               bits |= (ctrl & NAND_ALE) >> 2; /* bit 2 -> bit 0 */
+
+               __raw_writeb(bits, addr);
        }
-};
 
-static struct map_desc ts72xx_alternate_nand_io_desc[] __initdata = {
+       if (cmd != NAND_CMD_NONE)
+               __raw_writeb(cmd, chip->IO_ADDR_W);
+}
+
+static int ts72xx_nand_device_ready(struct mtd_info *mtd)
+{
+       struct nand_chip *chip = mtd->priv;
+       void __iomem *addr = chip->IO_ADDR_R;
+
+       addr += (1 << TS72XX_NAND_BUSY_ADDR_LINE);
+
+       return !!(__raw_readb(addr) & 0x20);
+}
+
+static const char *ts72xx_nand_part_probes[] = { "cmdlinepart", NULL };
+
+#define TS72XX_BOOTROM_PART_SIZE       (SZ_16K)
+#define TS72XX_REDBOOT_PART_SIZE       (SZ_2M + SZ_1M)
+
+static struct mtd_partition ts72xx_nand_parts[] = {
        {
-               .virtual        = TS72XX_NAND_DATA_VIRT_BASE,
-               .pfn            = __phys_to_pfn(TS72XX_NAND2_DATA_PHYS_BASE),
-               .length         = TS72XX_NAND_DATA_SIZE,
-               .type           = MT_DEVICE,
+               .name           = "TS-BOOTROM",
+               .offset         = 0,
+               .size           = TS72XX_BOOTROM_PART_SIZE,
+               .mask_flags     = MTD_WRITEABLE,        /* force read-only */
        }, {
-               .virtual        = TS72XX_NAND_CONTROL_VIRT_BASE,
-               .pfn            = __phys_to_pfn(TS72XX_NAND2_CONTROL_PHYS_BASE),
-               .length         = TS72XX_NAND_CONTROL_SIZE,
-               .type           = MT_DEVICE,
+               .name           = "Linux",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 0,                    /* filled in later */
        }, {
-               .virtual        = TS72XX_NAND_BUSY_VIRT_BASE,
-               .pfn            = __phys_to_pfn(TS72XX_NAND2_BUSY_PHYS_BASE),
-               .length         = TS72XX_NAND_BUSY_SIZE,
-               .type           = MT_DEVICE,
-       }
+               .name           = "RedBoot",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = MTDPART_SIZ_FULL,
+               .mask_flags     = MTD_WRITEABLE,        /* force read-only */
+       },
 };
 
-static void __init ts72xx_map_io(void)
+static void ts72xx_nand_set_parts(uint64_t size,
+                                 struct platform_nand_chip *chip)
 {
-       ep93xx_map_io();
-       iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc));
+       /* Factory TS-72xx boards only come with 32MiB or 128MiB NAND options */
+       if (size == SZ_32M || size == SZ_128M) {
+               /* Set the "Linux" partition size */
+               ts72xx_nand_parts[1].size = size - TS72XX_REDBOOT_PART_SIZE;
 
-       /*
-        * The TS-7200 has NOR flash, the other models have NAND flash.
-        */
-       if (!board_is_ts7200()) {
-               if (is_ts9420_installed()) {
-                       iotable_init(ts72xx_alternate_nand_io_desc,
-                               ARRAY_SIZE(ts72xx_alternate_nand_io_desc));
-               } else {
-                       iotable_init(ts72xx_nand_io_desc,
-                               ARRAY_SIZE(ts72xx_nand_io_desc));
-               }
+               chip->partitions = ts72xx_nand_parts;
+               chip->nr_partitions = ARRAY_SIZE(ts72xx_nand_parts);
+       } else {
+               pr_warning("Unknown nand disk size:%lluMiB\n", size >> 20);
        }
 }
 
+static struct platform_nand_data ts72xx_nand_data = {
+       .chip = {
+               .nr_chips       = 1,
+               .chip_offset    = 0,
+               .chip_delay     = 15,
+               .part_probe_types = ts72xx_nand_part_probes,
+               .set_parts      = ts72xx_nand_set_parts,
+       },
+       .ctrl = {
+               .cmd_ctrl       = ts72xx_nand_hwcontrol,
+               .dev_ready      = ts72xx_nand_device_ready,
+       },
+};
+
+static struct resource ts72xx_nand_resource[] = {
+       {
+               .start          = 0,                    /* filled in later */
+               .end            = 0,                    /* filled in later */
+               .flags          = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device ts72xx_nand_flash = {
+       .name                   = "gen_nand",
+       .id                     = -1,
+       .dev.platform_data      = &ts72xx_nand_data,
+       .resource               = ts72xx_nand_resource,
+       .num_resources          = ARRAY_SIZE(ts72xx_nand_resource),
+};
+
+
 /*************************************************************************
  * NOR flash (TS-7200 only)
  *************************************************************************/
-static struct physmap_flash_data ts72xx_flash_data = {
+static struct physmap_flash_data ts72xx_nor_data = {
        .width          = 2,
 };
 
-static struct resource ts72xx_flash_resource = {
+static struct resource ts72xx_nor_resource = {
        .start          = EP93XX_CS6_PHYS_BASE,
        .end            = EP93XX_CS6_PHYS_BASE + SZ_16M - 1,
        .flags          = IORESOURCE_MEM,
 };
 
-static struct platform_device ts72xx_flash = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev            = {
-               .platform_data  = &ts72xx_flash_data,
-       },
-       .num_resources  = 1,
-       .resource       = &ts72xx_flash_resource,
+static struct platform_device ts72xx_nor_flash = {
+       .name                   = "physmap-flash",
+       .id                     = 0,
+       .dev.platform_data      = &ts72xx_nor_data,
+       .resource               = &ts72xx_nor_resource,
+       .num_resources          = 1,
 };
 
 static void __init ts72xx_register_flash(void)
 {
-       if (board_is_ts7200())
-               platform_device_register(&ts72xx_flash);
+       if (board_is_ts7200()) {
+               platform_device_register(&ts72xx_nor_flash);
+       } else {
+               resource_size_t start;
+
+               if (is_ts9420_installed())
+                       start = EP93XX_CS7_PHYS_BASE;
+               else
+                       start = EP93XX_CS6_PHYS_BASE;
+
+               ts72xx_nand_resource[0].start = start;
+               ts72xx_nand_resource[0].end = start + SZ_16M - 1;
+
+               platform_device_register(&ts72xx_nand_flash);
+       }
 }
 
+
 static unsigned char ts72xx_rtc_readbyte(unsigned long addr)
 {
        __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
index f759ca2..6072eaa 100644 (file)
@@ -305,6 +305,15 @@ void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts,
        platform_device_register(&kirkwood_nand_flash);
 }
 
+void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts,
+                                  int (*dev_ready)(struct mtd_info *))
+{
+       kirkwood_clk_ctrl |= CGC_RUNIT;
+       kirkwood_nand_data.parts = parts;
+       kirkwood_nand_data.nr_parts = nr_parts;
+       kirkwood_nand_data.dev_ready = dev_ready;
+       platform_device_register(&kirkwood_nand_flash);
+}
 
 /*****************************************************************************
  * SoC RTC
index d7de434..05e8a8a 100644 (file)
@@ -16,6 +16,7 @@ struct mv643xx_eth_platform_data;
 struct mv_sata_platform_data;
 struct mvsdio_platform_data;
 struct mtd_partition;
+struct mtd_info;
 
 /*
  * Basic Kirkwood init functions used early by machine-setup.
@@ -41,6 +42,7 @@ void kirkwood_i2c_init(void);
 void kirkwood_uart0_init(void);
 void kirkwood_uart1_init(void);
 void kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, int delay);
+void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, int (*dev_ready)(struct mtd_info *));
 
 extern int kirkwood_tclk;
 extern struct sys_timer kirkwood_timer;
index d6a4cfa..9f3c180 100644 (file)
@@ -14,6 +14,7 @@
  */
 struct orion_nand_data {
        struct mtd_partition *parts;
+       int (*dev_ready)(struct mtd_info *mtd);
        u32 nr_parts;
        u8 ale;         /* address line number connected to ALE */
        u8 cle;         /* address line number connected to CLE */
index ecf90f5..f8210bf 100644 (file)
@@ -304,6 +304,19 @@ config SSFDC
          This enables read only access to SmartMedia formatted NAND
          flash. You can mount it with FAT file system.
 
+
+config SM_FTL
+       tristate "SmartMedia/xD new translation layer"
+       depends on EXPERIMENTAL && BLOCK
+       select MTD_BLKDEVS
+       select MTD_NAND_ECC
+       help
+         This enables new and very EXPERMENTAL support for SmartMedia/xD
+         FTL (Flash translation layer).
+         Write support isn't yet well tested, therefore this code IS likely to
+         eat your card, so please don't use it together with valuable data.
+         Use readonly driver (CONFIG_SSFDC) instead.
+
 config MTD_OOPS
        tristate "Log panic/oops to an MTD buffer"
        depends on MTD
index 4521b1e..760abc5 100644 (file)
@@ -24,6 +24,7 @@ obj-$(CONFIG_NFTL)            += nftl.o
 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
index 5fbf29e..62f3ea9 100644 (file)
@@ -615,10 +615,8 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
        return mtd;
 
  setup_err:
-       if(mtd) {
-               kfree(mtd->eraseregions);
-               kfree(mtd);
-       }
+       kfree(mtd->eraseregions);
+       kfree(mtd);
        kfree(cfi->cmdset_priv);
        return NULL;
 }
@@ -727,8 +725,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
                                /* 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++;
                        }
                }
@@ -774,9 +771,9 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
                        if (chip->priv && map_word_andequal(map, status, status_PWS, status_PWS))
                                break;
 
-                       spin_unlock(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        cfi_udelay(1);
-                       spin_lock(chip->mutex);
+                       mutex_lock(&chip->mutex);
                        /* Someone else might have been playing with it. */
                        return -EAGAIN;
                }
@@ -823,9 +820,9 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
                                return -EIO;
                        }
 
-                       spin_unlock(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        cfi_udelay(1);
-                       spin_lock(chip->mutex);
+                       mutex_lock(&chip->mutex);
                        /* Nobody will touch it while it's in state FL_ERASE_SUSPENDING.
                           So we can just loop here. */
                }
@@ -852,10 +849,10 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
        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;
        }
 }
@@ -901,20 +898,20 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                         * 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, contender->start, 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);
@@ -923,10 +920,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                         * in FL_SYNCING state. Put contender and retry. */
                        if (chip->state == FL_SYNCING) {
                                put_chip(map, contender, contender->start);
-                               spin_unlock(contender->mutex);
+                               mutex_unlock(&contender->mutex);
                                goto retry;
                        }
-                       spin_unlock(contender->mutex);
+                       mutex_unlock(&contender->mutex);
                }
 
                /* Check if we already have suspended erase
@@ -936,10 +933,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                        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;
                }
 
@@ -969,12 +966,12 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
                        if (shared->writing && shared->writing != chip) {
                                /* give back ownership to who we loaned it from */
                                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, loaner->start);
-                               spin_lock(chip->mutex);
-                               spin_unlock(loaner->mutex);
+                               mutex_lock(&chip->mutex);
+                               mutex_unlock(&loaner->mutex);
                                wake_up(&chip->wq);
                                return;
                        }
@@ -1144,7 +1141,7 @@ static int __xipram xip_wait_for_operation(
                        (void) map_read(map, adr);
                        xip_iprefetch();
                        local_irq_enable();
-                       spin_unlock(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        xip_iprefetch();
                        cond_resched();
 
@@ -1154,15 +1151,15 @@ static int __xipram xip_wait_for_operation(
                         * a suspended erase state.  If so let's wait
                         * until it's done.
                         */
-                       spin_lock(chip->mutex);
+                       mutex_lock(&chip->mutex);
                        while (chip->state != newstate) {
                                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);
                        }
                        /* Disallow XIP again */
                        local_irq_disable();
@@ -1218,10 +1215,10 @@ static int inval_cache_and_wait_for_operation(
        int chip_state = chip->state;
        unsigned int timeo, sleep_time, reset_timeo;
 
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        if (inval_len)
                INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len);
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
 
        timeo = chip_op_time_max;
        if (!timeo)
@@ -1241,7 +1238,7 @@ static int inval_cache_and_wait_for_operation(
                }
 
                /* 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
@@ -1256,17 +1253,17 @@ static int inval_cache_and_wait_for_operation(
                        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_state == FL_ERASING)  {
                        /* Erase suspend occured while sleep: reset timeout */
@@ -1302,7 +1299,7 @@ static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t a
        /* Ensure cmd read/writes are aligned. */
        cmd_addr = adr & ~(map_bankwidth(map)-1);
 
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
 
        ret = get_chip(map, chip, cmd_addr, FL_POINT);
 
@@ -1313,7 +1310,7 @@ static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t a
                chip->state = FL_POINT;
                chip->ref_point_counter++;
        }
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
 
        return ret;
 }
@@ -1398,7 +1395,7 @@ static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
                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)
@@ -1407,7 +1404,7 @@ static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
                        printk(KERN_ERR "%s: Warning: unpoint called on non pointed region\n", map->name); /* Should this give an error? */
 
                put_chip(map, chip, chip->start);
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
 
                len -= thislen;
                ofs = 0;
@@ -1426,10 +1423,10 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
        /* Ensure cmd read/writes are aligned. */
        cmd_addr = adr & ~(map_bankwidth(map)-1);
 
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, cmd_addr, FL_READY);
        if (ret) {
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
                return ret;
        }
 
@@ -1443,7 +1440,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
 
        put_chip(map, chip, cmd_addr);
 
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return 0;
 }
 
@@ -1506,10 +1503,10 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
                return -EINVAL;
        }
 
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, adr, mode);
        if (ret) {
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
                return ret;
        }
 
@@ -1555,7 +1552,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
 
        xip_enable(map, chip, adr);
  out:  put_chip(map, chip, adr);
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return ret;
 }
 
@@ -1664,10 +1661,10 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
        /* Let's determine this according to the interleave only once */
        write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0xe8) : CMD(0xe9);
 
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, cmd_adr, FL_WRITING);
        if (ret) {
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
                return ret;
        }
 
@@ -1798,7 +1795,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
 
        xip_enable(map, chip, cmd_adr);
  out:  put_chip(map, chip, cmd_adr);
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return ret;
 }
 
@@ -1877,10 +1874,10 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
        adr += chip->start;
 
  retry:
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, adr, FL_ERASING);
        if (ret) {
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
                return ret;
        }
 
@@ -1936,7 +1933,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
                } else if (chipstatus & 0x20 && retries--) {
                        printk(KERN_DEBUG "block erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus);
                        put_chip(map, chip, adr);
-                       spin_unlock(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        goto retry;
                } else {
                        printk(KERN_ERR "%s: block erase failed at 0x%08lx (status 0x%lx)\n", map->name, adr, chipstatus);
@@ -1948,7 +1945,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
 
        xip_enable(map, chip, adr);
  out:  put_chip(map, chip, adr);
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return ret;
 }
 
@@ -1981,7 +1978,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
        for (i=0; !ret && i<cfi->numchips; i++) {
                chip = &cfi->chips[i];
 
-               spin_lock(chip->mutex);
+               mutex_lock(&chip->mutex);
                ret = get_chip(map, chip, chip->start, FL_SYNCING);
 
                if (!ret) {
@@ -1992,7 +1989,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
                         * with the chip now anyway.
                         */
                }
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
        }
 
        /* Unlock the chips again */
@@ -2000,14 +1997,14 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
        for (i--; i >=0; i--) {
                chip = &cfi->chips[i];
 
-               spin_lock(chip->mutex);
+               mutex_lock(&chip->mutex);
 
                if (chip->state == FL_SYNCING) {
                        chip->state = chip->oldstate;
                        chip->oldstate = FL_READY;
                        wake_up(&chip->wq);
                }
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
        }
 }
 
@@ -2053,10 +2050,10 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
 
        adr += chip->start;
 
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, adr, FL_LOCKING);
        if (ret) {
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
                return ret;
        }
 
@@ -2090,7 +2087,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
 
        xip_enable(map, chip, adr);
 out:   put_chip(map, chip, adr);
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return ret;
 }
 
@@ -2155,10 +2152,10 @@ do_otp_read(struct map_info *map, struct flchip *chip, u_long offset,
        struct cfi_private *cfi = map->fldrv_priv;
        int ret;
 
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, chip->start, FL_JEDEC_QUERY);
        if (ret) {
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
                return ret;
        }
 
@@ -2177,7 +2174,7 @@ do_otp_read(struct map_info *map, struct flchip *chip, u_long offset,
        INVALIDATE_CACHED_RANGE(map, chip->start + offset, size);
 
        put_chip(map, chip, chip->start);
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return 0;
 }
 
@@ -2452,7 +2449,7 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
        for (i=0; !ret && i<cfi->numchips; i++) {
                chip = &cfi->chips[i];
 
-               spin_lock(chip->mutex);
+               mutex_lock(&chip->mutex);
 
                switch (chip->state) {
                case FL_READY:
@@ -2484,7 +2481,7 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
                case FL_PM_SUSPENDED:
                        break;
                }
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
        }
 
        /* Unlock the chips again */
@@ -2493,7 +2490,7 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
                for (i--; i >=0; i--) {
                        chip = &cfi->chips[i];
 
-                       spin_lock(chip->mutex);
+                       mutex_lock(&chip->mutex);
 
                        if (chip->state == FL_PM_SUSPENDED) {
                                /* No need to force it into a known state here,
@@ -2503,7 +2500,7 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
                                chip->oldstate = FL_READY;
                                wake_up(&chip->wq);
                        }
-                       spin_unlock(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                }
        }
 
@@ -2544,7 +2541,7 @@ static void cfi_intelext_resume(struct mtd_info *mtd)
 
                chip = &cfi->chips[i];
 
-               spin_lock(chip->mutex);
+               mutex_lock(&chip->mutex);
 
                /* Go to known state. Chip may have been power cycled */
                if (chip->state == FL_PM_SUSPENDED) {
@@ -2553,7 +2550,7 @@ static void cfi_intelext_resume(struct mtd_info *mtd)
                        wake_up(&chip->wq);
                }
 
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
        }
 
        if ((mtd->flags & MTD_POWERUP_LOCK)
@@ -2573,14 +2570,14 @@ static int cfi_intelext_reset(struct mtd_info *mtd)
                /* force the completion of any ongoing operation
                   and switch to array mode so any bootloader in
                   flash is accessible for soft reboot. */
-               spin_lock(chip->mutex);
+               mutex_lock(&chip->mutex);
                ret = get_chip(map, chip, chip->start, FL_SHUTDOWN);
                if (!ret) {
                        map_write(map, CMD(0xff), chip->start);
                        chip->state = FL_SHUTDOWN;
                        put_chip(map, chip, chip->start);
                }
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
        }
 
        return 0;
index f3600e8..d81079e 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/reboot.h>
 #include <linux/mtd/compatmac.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/mtd.h>
 
 #define MAX_WORD_RETRIES 3
 
-#define MANUFACTURER_AMD       0x0001
-#define MANUFACTURER_ATMEL     0x001F
-#define MANUFACTURER_MACRONIX  0x00C2
-#define MANUFACTURER_SST       0x00BF
 #define SST49LF004B            0x0060
 #define SST49LF040B            0x0050
 #define SST49LF008A            0x005a
@@ -60,6 +57,7 @@ static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *);
 static void cfi_amdstd_sync (struct mtd_info *);
 static int cfi_amdstd_suspend (struct mtd_info *);
 static void cfi_amdstd_resume (struct mtd_info *);
+static int cfi_amdstd_reboot(struct notifier_block *, unsigned long, void *);
 static int cfi_amdstd_secsi_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 
 static void cfi_amdstd_destroy(struct mtd_info *);
@@ -168,7 +166,7 @@ static void fixup_amd_bootblock(struct mtd_info *mtd, void* param)
                         * This reduces the risk of false detection due to
                         * the 8-bit device ID.
                         */
-                       (cfi->mfr == MANUFACTURER_MACRONIX)) {
+                       (cfi->mfr == CFI_MFR_MACRONIX)) {
                        DEBUG(MTD_DEBUG_LEVEL1,
                                "%s: Macronix MX29LV400C with bottom boot block"
                                " detected\n", map->name);
@@ -260,6 +258,42 @@ static void fixup_use_atmel_lock(struct mtd_info *mtd, void *param)
        mtd->flags |= MTD_POWERUP_LOCK;
 }
 
+static void fixup_old_sst_eraseregion(struct mtd_info *mtd)
+{
+       struct map_info *map = mtd->priv;
+       struct cfi_private *cfi = map->fldrv_priv;
+
+       /*
+        * These flashes report two seperate eraseblock regions based on the
+        * sector_erase-size and block_erase-size, although they both operate on the
+        * same memory. This is not allowed according to CFI, so we just pick the
+        * sector_erase-size.
+        */
+       cfi->cfiq->NumEraseRegions = 1;
+}
+
+static void fixup_sst39vf(struct mtd_info *mtd, void *param)
+{
+       struct map_info *map = mtd->priv;
+       struct cfi_private *cfi = map->fldrv_priv;
+
+       fixup_old_sst_eraseregion(mtd);
+
+       cfi->addr_unlock1 = 0x5555;
+       cfi->addr_unlock2 = 0x2AAA;
+}
+
+static void fixup_sst39vf_rev_b(struct mtd_info *mtd, void *param)
+{
+       struct map_info *map = mtd->priv;
+       struct cfi_private *cfi = map->fldrv_priv;
+
+       fixup_old_sst_eraseregion(mtd);
+
+       cfi->addr_unlock1 = 0x555;
+       cfi->addr_unlock2 = 0x2AA;
+}
+
 static void fixup_s29gl064n_sectors(struct mtd_info *mtd, void *param)
 {
        struct map_info *map = mtd->priv;
@@ -282,11 +316,24 @@ static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param)
        }
 }
 
+/* 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
+       { 0, 0, NULL, NULL }
+};
+
 static struct cfi_fixup cfi_fixup_table[] = {
        { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
 #ifdef AMD_BOOTLOC_BUG
        { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL },
-       { MANUFACTURER_MACRONIX, CFI_ID_ANY, fixup_amd_bootblock, NULL },
+       { CFI_MFR_MACRONIX, CFI_ID_ANY, fixup_amd_bootblock, NULL },
 #endif
        { CFI_MFR_AMD, 0x0050, fixup_use_secsi, NULL, },
        { CFI_MFR_AMD, 0x0053, fixup_use_secsi, NULL, },
@@ -304,9 +351,9 @@ static struct cfi_fixup cfi_fixup_table[] = {
        { 0, 0, NULL, NULL }
 };
 static struct cfi_fixup jedec_fixup_table[] = {
-       { MANUFACTURER_SST, SST49LF004B, fixup_use_fwh_lock, NULL, },
-       { MANUFACTURER_SST, SST49LF040B, fixup_use_fwh_lock, NULL, },
-       { MANUFACTURER_SST, SST49LF008A, fixup_use_fwh_lock, NULL, },
+       { CFI_MFR_SST, SST49LF004B, fixup_use_fwh_lock, NULL, },
+       { CFI_MFR_SST, SST49LF040B, fixup_use_fwh_lock, NULL, },
+       { CFI_MFR_SST, SST49LF008A, fixup_use_fwh_lock, NULL, },
        { 0, 0, NULL, NULL }
 };
 
@@ -355,67 +402,72 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
        mtd->name    = map->name;
        mtd->writesize = 1;
 
+       mtd->reboot_notifier.notifier_call = cfi_amdstd_reboot;
+
        if (cfi->cfi_mode==CFI_MODE_CFI){
                unsigned char bootloc;
-               /*
-                * It's a real CFI chip, not one for which the probe
-                * routine faked a CFI structure. So we read the feature
-                * table from it.
-                */
                __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
                struct cfi_pri_amdstd *extp;
 
                extp = (struct cfi_pri_amdstd*)cfi_read_pri(map, adr, sizeof(*extp), "Amd/Fujitsu");
-               if (!extp) {
-                       kfree(mtd);
-                       return NULL;
-               }
-
-               cfi_fixup_major_minor(cfi, extp);
-
-               if (extp->MajorVersion != '1' ||
-                   (extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
-                       printk(KERN_ERR "  Unknown Amd/Fujitsu Extended Query "
-                              "version %c.%c.\n",  extp->MajorVersion,
-                              extp->MinorVersion);
-                       kfree(extp);
-                       kfree(mtd);
-                       return NULL;
-               }
+               if (extp) {
+                       /*
+                        * It's a real CFI chip, not one for which the probe
+                        * routine faked a CFI structure.
+                        */
+                       cfi_fixup_major_minor(cfi, extp);
+
+                       if (extp->MajorVersion != '1' ||
+                           (extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
+                               printk(KERN_ERR "  Unknown Amd/Fujitsu Extended Query "
+                                      "version %c.%c.\n",  extp->MajorVersion,
+                                      extp->MinorVersion);
+                               kfree(extp);
+                               kfree(mtd);
+                               return NULL;
+                       }
 
-               /* Install our own private info structure */
-               cfi->cmdset_priv = extp;
+                       /* Install our own private info structure */
+                       cfi->cmdset_priv = extp;
 
-               /* Apply cfi device specific fixups */
-               cfi_fixup(mtd, cfi_fixup_table);
+                       /* Apply cfi device specific fixups */
+                       cfi_fixup(mtd, cfi_fixup_table);
 
 #ifdef DEBUG_CFI_FEATURES
-               /* Tell the user about it in lots of lovely detail */
-               cfi_tell_features(extp);
+                       /* Tell the user about it in lots of lovely detail */
+                       cfi_tell_features(extp);
 #endif
 
-               bootloc = extp->TopBottom;
-               if ((bootloc != 2) && (bootloc != 3)) {
-                       printk(KERN_WARNING "%s: CFI does not contain boot "
-                              "bank location. Assuming top.\n", map->name);
-                       bootloc = 2;
-               }
+                       bootloc = extp->TopBottom;
+                       if ((bootloc < 2) || (bootloc > 5)) {
+                               printk(KERN_WARNING "%s: CFI contains unrecognised boot "
+                                      "bank location (%d). Assuming bottom.\n",
+                                      map->name, bootloc);
+                               bootloc = 2;
+                       }
 
-               if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) {
-                       printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name);
+                       if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) {
+                               printk(KERN_WARNING "%s: Swapping erase regions for top-boot CFI table.\n", map->name);
 
-                       for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) {
-                               int j = (cfi->cfiq->NumEraseRegions-1)-i;
-                               __u32 swap;
+                               for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) {
+                                       int j = (cfi->cfiq->NumEraseRegions-1)-i;
+                                       __u32 swap;
 
-                               swap = cfi->cfiq->EraseRegionInfo[i];
-                               cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j];
-                               cfi->cfiq->EraseRegionInfo[j] = swap;
+                                       swap = cfi->cfiq->EraseRegionInfo[i];
+                                       cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j];
+                                       cfi->cfiq->EraseRegionInfo[j] = swap;
+                               }
                        }
+                       /* Set the default CFI lock/unlock addresses */
+                       cfi->addr_unlock1 = 0x555;
+                       cfi->addr_unlock2 = 0x2aa;
+               }
+               cfi_fixup(mtd, cfi_nopri_fixup_table);
+
+               if (!cfi->addr_unlock1 || !cfi->addr_unlock2) {
+                       kfree(mtd);
+                       return NULL;
                }
-               /* Set the default CFI lock/unlock addresses */
-               cfi->addr_unlock1 = 0x555;
-               cfi->addr_unlock2 = 0x2aa;
 
        } /* CFI mode */
        else if (cfi->cfi_mode == CFI_MODE_JEDEC) {
@@ -437,7 +489,11 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
 
        return cfi_amdstd_setup(mtd);
 }
+struct mtd_info *cfi_cmdset_0006(struct map_info *map, int primary) __attribute__((alias("cfi_cmdset_0002")));
+struct mtd_info *cfi_cmdset_0701(struct map_info *map, int primary) __attribute__((alias("cfi_cmdset_0002")));
 EXPORT_SYMBOL_GPL(cfi_cmdset_0002);
+EXPORT_SYMBOL_GPL(cfi_cmdset_0006);
+EXPORT_SYMBOL_GPL(cfi_cmdset_0701);
 
 static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
 {
@@ -491,13 +547,12 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
 #endif
 
        __module_get(THIS_MODULE);
+       register_reboot_notifier(&mtd->reboot_notifier);
        return mtd;
 
  setup_err:
-       if(mtd) {
-               kfree(mtd->eraseregions);
-               kfree(mtd);
-       }
+       kfree(mtd->eraseregions);
+       kfree(mtd);
        kfree(cfi->cmdset_priv);
        kfree(cfi->cfiq);
        return NULL;
@@ -571,9 +626,9 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                                printk(KERN_ERR "Waiting for chip to be ready timed out.\n");
                                return -EIO;
                        }
-                       spin_unlock(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        cfi_udelay(1);
-                       spin_lock(chip->mutex);
+                       mutex_lock(&chip->mutex);
                        /* Someone else might have been playing with it. */
                        goto retry;
                }
@@ -617,9 +672,9 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                                return -EIO;
                        }
 
-                       spin_unlock(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        cfi_udelay(1);
-                       spin_lock(chip->mutex);
+                       mutex_lock(&chip->mutex);
                        /* Nobody will touch it while it's in state FL_ERASE_SUSPENDING.
                           So we can just loop here. */
                }
@@ -634,6 +689,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                chip->state = FL_READY;
                return 0;
 
+       case FL_SHUTDOWN:
+               /* The machine is rebooting */
+               return -EIO;
+
        case FL_POINT:
                /* Only if there's no operation suspended... */
                if (mode == FL_READY && chip->oldstate == FL_READY)
@@ -643,10 +702,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
        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);
                goto resettime;
        }
 }
@@ -778,7 +837,7 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
                        (void) map_read(map, adr);
                        xip_iprefetch();
                        local_irq_enable();
-                       spin_unlock(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        xip_iprefetch();
                        cond_resched();
 
@@ -788,15 +847,15 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
                         * a suspended erase state.  If so let's wait
                         * until it's done.
                         */
-                       spin_lock(chip->mutex);
+                       mutex_lock(&chip->mutex);
                        while (chip->state != FL_XIP_WHILE_ERASING) {
                                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);
                        }
                        /* Disallow XIP again */
                        local_irq_disable();
@@ -858,17 +917,17 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
 
 #define UDELAY(map, chip, adr, usec)  \
 do {  \
-       spin_unlock(chip->mutex);  \
+       mutex_unlock(&chip->mutex);  \
        cfi_udelay(usec);  \
-       spin_lock(chip->mutex);  \
+       mutex_lock(&chip->mutex);  \
 } while (0)
 
 #define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec)  \
 do {  \
-       spin_unlock(chip->mutex);  \
+       mutex_unlock(&chip->mutex);  \
        INVALIDATE_CACHED_RANGE(map, adr, len);  \
        cfi_udelay(usec);  \
-       spin_lock(chip->mutex);  \
+       mutex_lock(&chip->mutex);  \
 } while (0)
 
 #endif
@@ -884,10 +943,10 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
        /* Ensure cmd read/writes are aligned. */
        cmd_addr = adr & ~(map_bankwidth(map)-1);
 
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, cmd_addr, FL_READY);
        if (ret) {
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
                return ret;
        }
 
@@ -900,7 +959,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
 
        put_chip(map, chip, cmd_addr);
 
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return 0;
 }
 
@@ -954,7 +1013,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
        struct cfi_private *cfi = map->fldrv_priv;
 
  retry:
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
 
        if (chip->state != FL_READY){
 #if 0
@@ -963,7 +1022,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
                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);
@@ -992,7 +1051,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
        cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
 
        wake_up(&chip->wq);
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
 
        return 0;
 }
@@ -1061,10 +1120,10 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
 
        adr += chip->start;
 
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, adr, FL_WRITING);
        if (ret) {
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
                return ret;
        }
 
@@ -1107,11 +1166,11 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
 
                        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);
                        timeo = jiffies + (HZ / 2); /* FIXME */
-                       spin_lock(chip->mutex);
+                       mutex_lock(&chip->mutex);
                        continue;
                }
 
@@ -1143,7 +1202,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
  op_done:
        chip->state = FL_READY;
        put_chip(map, chip, adr);
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
 
        return ret;
 }
@@ -1175,7 +1234,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
                map_word tmp_buf;
 
  retry:
-               spin_lock(cfi->chips[chipnum].mutex);
+               mutex_lock(&cfi->chips[chipnum].mutex);
 
                if (cfi->chips[chipnum].state != FL_READY) {
 #if 0
@@ -1184,7 +1243,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&cfi->chips[chipnum].wq, &wait);
 
-                       spin_unlock(cfi->chips[chipnum].mutex);
+                       mutex_unlock(&cfi->chips[chipnum].mutex);
 
                        schedule();
                        remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
@@ -1198,7 +1257,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
                /* Load 'tmp_buf' with old contents of flash */
                tmp_buf = map_read(map, bus_ofs+chipstart);
 
-               spin_unlock(cfi->chips[chipnum].mutex);
+               mutex_unlock(&cfi->chips[chipnum].mutex);
 
                /* Number of bytes to copy from buffer */
                n = min_t(int, len, map_bankwidth(map)-i);
@@ -1253,7 +1312,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
                map_word tmp_buf;
 
  retry1:
-               spin_lock(cfi->chips[chipnum].mutex);
+               mutex_lock(&cfi->chips[chipnum].mutex);
 
                if (cfi->chips[chipnum].state != FL_READY) {
 #if 0
@@ -1262,7 +1321,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&cfi->chips[chipnum].wq, &wait);
 
-                       spin_unlock(cfi->chips[chipnum].mutex);
+                       mutex_unlock(&cfi->chips[chipnum].mutex);
 
                        schedule();
                        remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
@@ -1275,7 +1334,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
 
                tmp_buf = map_read(map, ofs + chipstart);
 
-               spin_unlock(cfi->chips[chipnum].mutex);
+               mutex_unlock(&cfi->chips[chipnum].mutex);
 
                tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len);
 
@@ -1310,10 +1369,10 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
        adr += chip->start;
        cmd_adr = adr;
 
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, adr, FL_WRITING);
        if (ret) {
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
                return ret;
        }
 
@@ -1368,11 +1427,11 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
 
                        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);
                        timeo = jiffies + (HZ / 2); /* FIXME */
-                       spin_lock(chip->mutex);
+                       mutex_lock(&chip->mutex);
                        continue;
                }
 
@@ -1400,7 +1459,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
  op_done:
        chip->state = FL_READY;
        put_chip(map, chip, adr);
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
 
        return ret;
 }
@@ -1500,10 +1559,10 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
 
        adr = cfi->addr_unlock1;
 
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, adr, FL_WRITING);
        if (ret) {
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
                return ret;
        }
 
@@ -1536,10 +1595,10 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
                        /* Someone's suspended the erase. 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);
                        continue;
                }
                if (chip->erase_suspended) {
@@ -1573,7 +1632,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
        chip->state = FL_READY;
        xip_enable(map, chip, adr);
        put_chip(map, chip, adr);
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
 
        return ret;
 }
@@ -1588,10 +1647,10 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
 
        adr += chip->start;
 
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, adr, FL_ERASING);
        if (ret) {
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
                return ret;
        }
 
@@ -1624,10 +1683,10 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
                        /* Someone's suspended the erase. 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);
                        continue;
                }
                if (chip->erase_suspended) {
@@ -1663,7 +1722,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
 
        chip->state = FL_READY;
        put_chip(map, chip, adr);
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return ret;
 }
 
@@ -1715,7 +1774,7 @@ static int do_atmel_lock(struct map_info *map, struct flchip *chip,
        struct cfi_private *cfi = map->fldrv_priv;
        int ret;
 
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, adr + chip->start, FL_LOCKING);
        if (ret)
                goto out_unlock;
@@ -1741,7 +1800,7 @@ static int do_atmel_lock(struct map_info *map, struct flchip *chip,
        ret = 0;
 
 out_unlock:
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return ret;
 }
 
@@ -1751,7 +1810,7 @@ static int do_atmel_unlock(struct map_info *map, struct flchip *chip,
        struct cfi_private *cfi = map->fldrv_priv;
        int ret;
 
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, adr + chip->start, FL_UNLOCKING);
        if (ret)
                goto out_unlock;
@@ -1769,7 +1828,7 @@ static int do_atmel_unlock(struct map_info *map, struct flchip *chip,
        ret = 0;
 
 out_unlock:
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return ret;
 }
 
@@ -1797,7 +1856,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
                chip = &cfi->chips[i];
 
        retry:
-               spin_lock(chip->mutex);
+               mutex_lock(&chip->mutex);
 
                switch(chip->state) {
                case FL_READY:
@@ -1811,7 +1870,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
                         * with the chip now anyway.
                         */
                case FL_SYNCING:
-                       spin_unlock(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        break;
 
                default:
@@ -1819,7 +1878,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&chip->wq, &wait);
 
-                       spin_unlock(chip->mutex);
+                       mutex_unlock(&chip->mutex);
 
                        schedule();
 
@@ -1834,13 +1893,13 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
        for (i--; i >=0; i--) {
                chip = &cfi->chips[i];
 
-               spin_lock(chip->mutex);
+               mutex_lock(&chip->mutex);
 
                if (chip->state == FL_SYNCING) {
                        chip->state = chip->oldstate;
                        wake_up(&chip->wq);
                }
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
        }
 }
 
@@ -1856,7 +1915,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
        for (i=0; !ret && i<cfi->numchips; i++) {
                chip = &cfi->chips[i];
 
-               spin_lock(chip->mutex);
+               mutex_lock(&chip->mutex);
 
                switch(chip->state) {
                case FL_READY:
@@ -1876,7 +1935,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
                        ret = -EAGAIN;
                        break;
                }
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
        }
 
        /* Unlock the chips again */
@@ -1885,13 +1944,13 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
                for (i--; i >=0; i--) {
                        chip = &cfi->chips[i];
 
-                       spin_lock(chip->mutex);
+                       mutex_lock(&chip->mutex);
 
                        if (chip->state == FL_PM_SUSPENDED) {
                                chip->state = chip->oldstate;
                                wake_up(&chip->wq);
                        }
-                       spin_unlock(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                }
        }
 
@@ -1910,7 +1969,7 @@ static void cfi_amdstd_resume(struct mtd_info *mtd)
 
                chip = &cfi->chips[i];
 
-               spin_lock(chip->mutex);
+               mutex_lock(&chip->mutex);
 
                if (chip->state == FL_PM_SUSPENDED) {
                        chip->state = FL_READY;
@@ -1920,15 +1979,62 @@ static void cfi_amdstd_resume(struct mtd_info *mtd)
                else
                        printk(KERN_ERR "Argh. Chip not in PM_SUSPENDED state upon resume()\n");
 
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
        }
 }
 
+
+/*
+ * Ensure that the flash device is put back into read array mode before
+ * unloading the driver or rebooting.  On some systems, rebooting while
+ * the flash is in query/program/erase mode will prevent the CPU from
+ * fetching the bootloader code, requiring a hard reset or power cycle.
+ */
+static int cfi_amdstd_reset(struct mtd_info *mtd)
+{
+       struct map_info *map = mtd->priv;
+       struct cfi_private *cfi = map->fldrv_priv;
+       int i, ret;
+       struct flchip *chip;
+
+       for (i = 0; i < cfi->numchips; i++) {
+
+               chip = &cfi->chips[i];
+
+               mutex_lock(&chip->mutex);
+
+               ret = get_chip(map, chip, chip->start, FL_SHUTDOWN);
+               if (!ret) {
+                       map_write(map, CMD(0xF0), chip->start);
+                       chip->state = FL_SHUTDOWN;
+                       put_chip(map, chip, chip->start);
+               }
+
+               mutex_unlock(&chip->mutex);
+       }
+
+       return 0;
+}
+
+
+static int cfi_amdstd_reboot(struct notifier_block *nb, unsigned long val,
+                              void *v)
+{
+       struct mtd_info *mtd;
+
+       mtd = container_of(nb, struct mtd_info, reboot_notifier);
+       cfi_amdstd_reset(mtd);
+       return NOTIFY_DONE;
+}
+
+
 static void cfi_amdstd_destroy(struct mtd_info *mtd)
 {
        struct map_info *map = mtd->priv;
        struct cfi_private *cfi = map->fldrv_priv;
 
+       cfi_amdstd_reset(mtd);
+       unregister_reboot_notifier(&mtd->reboot_notifier);
        kfree(cfi->cmdset_priv);
        kfree(cfi->cfiq);
        kfree(cfi);
@@ -1938,3 +2044,5 @@ static void cfi_amdstd_destroy(struct mtd_info *mtd)
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Crossnet Co. <info@crossnet.co.jp> et al.");
 MODULE_DESCRIPTION("MTD chip driver for AMD/Fujitsu flash chips");
+MODULE_ALIAS("cfi_cmdset_0006");
+MODULE_ALIAS("cfi_cmdset_0701");
index 0667a67..e54e8c1 100644 (file)
@@ -265,7 +265,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
 
        timeo = jiffies + HZ;
  retry:
-       spin_lock_bh(chip->mutex);
+       mutex_lock(&chip->mutex);
 
        /* Check that the chip's ready to talk to us.
         * If it's in FL_ERASING state, suspend it and make it talk now.
@@ -296,15 +296,15 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
                                /* make sure we're in 'read status' mode */
                                map_write(map, CMD(0x70), cmd_addr);
                                chip->state = FL_ERASING;
-                               spin_unlock_bh(chip->mutex);
+                               mutex_unlock(&chip->mutex);
                                printk(KERN_ERR "Chip not ready after erase "
                                       "suspended: status = 0x%lx\n", status.x[0]);
                                return -EIO;
                        }
 
-                       spin_unlock_bh(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        cfi_udelay(1);
-                       spin_lock_bh(chip->mutex);
+                       mutex_lock(&chip->mutex);
                }
 
                suspended = 1;
@@ -335,13 +335,13 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
 
                /* Urgh. Chip not yet ready to talk to us. */
                if (time_after(jiffies, timeo)) {
-                       spin_unlock_bh(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        printk(KERN_ERR "waiting for chip to be ready timed out in read. WSM status = %lx\n", status.x[0]);
                        return -EIO;
                }
 
                /* Latency issues. Drop the lock, wait a while and retry */
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
                cfi_udelay(1);
                goto retry;
 
@@ -351,7 +351,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
                   someone changes the status */
                set_current_state(TASK_UNINTERRUPTIBLE);
                add_wait_queue(&chip->wq, &wait);
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
                schedule();
                remove_wait_queue(&chip->wq, &wait);
                timeo = jiffies + HZ;
@@ -376,7 +376,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
        }
 
        wake_up(&chip->wq);
-       spin_unlock_bh(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return 0;
 }
 
@@ -445,7 +445,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
 #ifdef DEBUG_CFI_FEATURES
        printk("%s: chip->state[%d]\n", __func__, chip->state);
 #endif
-       spin_lock_bh(chip->mutex);
+       mutex_lock(&chip->mutex);
 
        /* Check that the chip's ready to talk to us.
         * Later, we can actually think about interrupting it
@@ -470,14 +470,14 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
                        break;
                /* Urgh. Chip not yet ready to talk to us. */
                if (time_after(jiffies, timeo)) {
-                       spin_unlock_bh(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                         printk(KERN_ERR "waiting for chip to be ready timed out in buffer write Xstatus = %lx, status = %lx\n",
                                status.x[0], map_read(map, cmd_adr).x[0]);
                        return -EIO;
                }
 
                /* Latency issues. Drop the lock, wait a while and retry */
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
                cfi_udelay(1);
                goto retry;
 
@@ -486,7 +486,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
                   someone changes the status */
                set_current_state(TASK_UNINTERRUPTIBLE);
                add_wait_queue(&chip->wq, &wait);
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
                schedule();
                remove_wait_queue(&chip->wq, &wait);
                timeo = jiffies + HZ;
@@ -503,16 +503,16 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
                if (map_word_andequal(map, status, status_OK, status_OK))
                        break;
 
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
                cfi_udelay(1);
-               spin_lock_bh(chip->mutex);
+               mutex_lock(&chip->mutex);
 
                if (++z > 100) {
                        /* Argh. Not ready for write to buffer */
                        DISABLE_VPP(map);
                         map_write(map, CMD(0x70), cmd_adr);
                        chip->state = FL_STATUS;
-                       spin_unlock_bh(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        printk(KERN_ERR "Chip not ready for buffer write. Xstatus = %lx\n", status.x[0]);
                        return -EIO;
                }
@@ -532,9 +532,9 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
        map_write(map, CMD(0xd0), cmd_adr);
        chip->state = FL_WRITING;
 
-       spin_unlock_bh(chip->mutex);
+       mutex_unlock(&chip->mutex);
        cfi_udelay(chip->buffer_write_time);
-       spin_lock_bh(chip->mutex);
+       mutex_lock(&chip->mutex);
 
        timeo = jiffies + (HZ/2);
        z = 0;
@@ -543,11 +543,11 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
                        /* Someone's suspended the write. Sleep */
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&chip->wq, &wait);
-                       spin_unlock_bh(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        schedule();
                        remove_wait_queue(&chip->wq, &wait);
                        timeo = jiffies + (HZ / 2); /* FIXME */
-                       spin_lock_bh(chip->mutex);
+                       mutex_lock(&chip->mutex);
                        continue;
                }
 
@@ -563,16 +563,16 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
                         map_write(map, CMD(0x70), adr);
                        chip->state = FL_STATUS;
                        DISABLE_VPP(map);
-                       spin_unlock_bh(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n");
                        return -EIO;
                }
 
                /* Latency issues. Drop the lock, wait a while and retry */
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
                cfi_udelay(1);
                z++;
-               spin_lock_bh(chip->mutex);
+               mutex_lock(&chip->mutex);
        }
        if (!z) {
                chip->buffer_write_time--;
@@ -596,11 +596,11 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
                /* put back into read status register mode */
                map_write(map, CMD(0x70), adr);
                wake_up(&chip->wq);
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
                return map_word_bitsset(map, status, CMD(0x02)) ? -EROFS : -EIO;
        }
        wake_up(&chip->wq);
-       spin_unlock_bh(chip->mutex);
+       mutex_unlock(&chip->mutex);
 
         return 0;
 }
@@ -749,7 +749,7 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
 
        timeo = jiffies + HZ;
 retry:
-       spin_lock_bh(chip->mutex);
+       mutex_lock(&chip->mutex);
 
        /* Check that the chip's ready to talk to us. */
        switch (chip->state) {
@@ -766,13 +766,13 @@ retry:
 
                /* Urgh. Chip not yet ready to talk to us. */
                if (time_after(jiffies, timeo)) {
-                       spin_unlock_bh(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        printk(KERN_ERR "waiting for chip to be ready timed out in erase\n");
                        return -EIO;
                }
 
                /* Latency issues. Drop the lock, wait a while and retry */
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
                cfi_udelay(1);
                goto retry;
 
@@ -781,7 +781,7 @@ retry:
                   someone changes the status */
                set_current_state(TASK_UNINTERRUPTIBLE);
                add_wait_queue(&chip->wq, &wait);
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
                schedule();
                remove_wait_queue(&chip->wq, &wait);
                timeo = jiffies + HZ;
@@ -797,9 +797,9 @@ retry:
        map_write(map, CMD(0xD0), adr);
        chip->state = FL_ERASING;
 
-       spin_unlock_bh(chip->mutex);
+       mutex_unlock(&chip->mutex);
        msleep(1000);
-       spin_lock_bh(chip->mutex);
+       mutex_lock(&chip->mutex);
 
        /* FIXME. Use a timer to check this, and return immediately. */
        /* Once the state machine's known to be working I'll do that */
@@ -810,11 +810,11 @@ retry:
                        /* Someone's suspended the erase. Sleep */
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&chip->wq, &wait);
-                       spin_unlock_bh(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        schedule();
                        remove_wait_queue(&chip->wq, &wait);
                        timeo = jiffies + (HZ*20); /* FIXME */
-                       spin_lock_bh(chip->mutex);
+                       mutex_lock(&chip->mutex);
                        continue;
                }
 
@@ -828,14 +828,14 @@ retry:
                        chip->state = FL_STATUS;
                        printk(KERN_ERR "waiting for erase to complete timed out. Xstatus = %lx, status = %lx.\n", status.x[0], map_read(map, adr).x[0]);
                        DISABLE_VPP(map);
-                       spin_unlock_bh(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        return -EIO;
                }
 
                /* Latency issues. Drop the lock, wait a while and retry */
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
                cfi_udelay(1);
-               spin_lock_bh(chip->mutex);
+               mutex_lock(&chip->mutex);
        }
 
        DISABLE_VPP(map);
@@ -878,7 +878,7 @@ retry:
                                printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x. Retrying...\n", adr, chipstatus);
                                timeo = jiffies + HZ;
                                chip->state = FL_STATUS;
-                               spin_unlock_bh(chip->mutex);
+                               mutex_unlock(&chip->mutex);
                                goto retry;
                        }
                        printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x\n", adr, chipstatus);
@@ -887,7 +887,7 @@ retry:
        }
 
        wake_up(&chip->wq);
-       spin_unlock_bh(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return ret;
 }
 
@@ -995,7 +995,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
                chip = &cfi->chips[i];
 
        retry:
-               spin_lock_bh(chip->mutex);
+               mutex_lock(&chip->mutex);
 
                switch(chip->state) {
                case FL_READY:
@@ -1009,7 +1009,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
                         * with the chip now anyway.
                         */
                case FL_SYNCING:
-                       spin_unlock_bh(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        break;
 
                default:
@@ -1017,7 +1017,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&chip->wq, &wait);
 
-                       spin_unlock_bh(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        schedule();
                        remove_wait_queue(&chip->wq, &wait);
 
@@ -1030,13 +1030,13 @@ static void cfi_staa_sync (struct mtd_info *mtd)
        for (i--; i >=0; i--) {
                chip = &cfi->chips[i];
 
-               spin_lock_bh(chip->mutex);
+               mutex_lock(&chip->mutex);
 
                if (chip->state == FL_SYNCING) {
                        chip->state = chip->oldstate;
                        wake_up(&chip->wq);
                }
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
        }
 }
 
@@ -1054,7 +1054,7 @@ static inline int do_lock_oneblock(struct map_info *map, struct flchip *chip, un
 
        timeo = jiffies + HZ;
 retry:
-       spin_lock_bh(chip->mutex);
+       mutex_lock(&chip->mutex);
 
        /* Check that the chip's ready to talk to us. */
        switch (chip->state) {
@@ -1071,13 +1071,13 @@ retry:
 
                /* Urgh. Chip not yet ready to talk to us. */
                if (time_after(jiffies, timeo)) {
-                       spin_unlock_bh(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        printk(KERN_ERR "waiting for chip to be ready timed out in lock\n");
                        return -EIO;
                }
 
                /* Latency issues. Drop the lock, wait a while and retry */
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
                cfi_udelay(1);
                goto retry;
 
@@ -1086,7 +1086,7 @@ retry:
                   someone changes the status */
                set_current_state(TASK_UNINTERRUPTIBLE);
                add_wait_queue(&chip->wq, &wait);
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
                schedule();
                remove_wait_queue(&chip->wq, &wait);
                timeo = jiffies + HZ;
@@ -1098,9 +1098,9 @@ retry:
        map_write(map, CMD(0x01), adr);
        chip->state = FL_LOCKING;
 
-       spin_unlock_bh(chip->mutex);
+       mutex_unlock(&chip->mutex);
        msleep(1000);
-       spin_lock_bh(chip->mutex);
+       mutex_lock(&chip->mutex);
 
        /* FIXME. Use a timer to check this, and return immediately. */
        /* Once the state machine's known to be working I'll do that */
@@ -1118,21 +1118,21 @@ retry:
                        chip->state = FL_STATUS;
                        printk(KERN_ERR "waiting for lock to complete timed out. Xstatus = %lx, status = %lx.\n", status.x[0], map_read(map, adr).x[0]);
                        DISABLE_VPP(map);
-                       spin_unlock_bh(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        return -EIO;
                }
 
                /* Latency issues. Drop the lock, wait a while and retry */
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
                cfi_udelay(1);
-               spin_lock_bh(chip->mutex);
+               mutex_lock(&chip->mutex);
        }
 
        /* Done and happy. */
        chip->state = FL_STATUS;
        DISABLE_VPP(map);
        wake_up(&chip->wq);
-       spin_unlock_bh(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return 0;
 }
 static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
@@ -1203,7 +1203,7 @@ static inline int do_unlock_oneblock(struct map_info *map, struct flchip *chip,
 
        timeo = jiffies + HZ;
 retry:
-       spin_lock_bh(chip->mutex);
+       mutex_lock(&chip->mutex);
 
        /* Check that the chip's ready to talk to us. */
        switch (chip->state) {
@@ -1220,13 +1220,13 @@ retry:
 
                /* Urgh. Chip not yet ready to talk to us. */
                if (time_after(jiffies, timeo)) {
-                       spin_unlock_bh(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        printk(KERN_ERR "waiting for chip to be ready timed out in unlock\n");
                        return -EIO;
                }
 
                /* Latency issues. Drop the lock, wait a while and retry */
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
                cfi_udelay(1);
                goto retry;
 
@@ -1235,7 +1235,7 @@ retry:
                   someone changes the status */
                set_current_state(TASK_UNINTERRUPTIBLE);
                add_wait_queue(&chip->wq, &wait);
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
                schedule();
                remove_wait_queue(&chip->wq, &wait);
                timeo = jiffies + HZ;
@@ -1247,9 +1247,9 @@ retry:
        map_write(map, CMD(0xD0), adr);
        chip->state = FL_UNLOCKING;
 
-       spin_unlock_bh(chip->mutex);
+       mutex_unlock(&chip->mutex);
        msleep(1000);
-       spin_lock_bh(chip->mutex);
+       mutex_lock(&chip->mutex);
 
        /* FIXME. Use a timer to check this, and return immediately. */
        /* Once the state machine's known to be working I'll do that */
@@ -1267,21 +1267,21 @@ retry:
                        chip->state = FL_STATUS;
                        printk(KERN_ERR "waiting for unlock to complete timed out. Xstatus = %lx, status = %lx.\n", status.x[0], map_read(map, adr).x[0]);
                        DISABLE_VPP(map);
-                       spin_unlock_bh(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                        return -EIO;
                }
 
                /* Latency issues. Drop the unlock, wait a while and retry */
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
                cfi_udelay(1);
-               spin_lock_bh(chip->mutex);
+               mutex_lock(&chip->mutex);
        }
 
        /* Done and happy. */
        chip->state = FL_STATUS;
        DISABLE_VPP(map);
        wake_up(&chip->wq);
-       spin_unlock_bh(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return 0;
 }
 static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
@@ -1334,7 +1334,7 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
        for (i=0; !ret && i<cfi->numchips; i++) {
                chip = &cfi->chips[i];
 
-               spin_lock_bh(chip->mutex);
+               mutex_lock(&chip->mutex);
 
                switch(chip->state) {
                case FL_READY:
@@ -1354,7 +1354,7 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
                        ret = -EAGAIN;
                        break;
                }
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
        }
 
        /* Unlock the chips again */
@@ -1363,7 +1363,7 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
                for (i--; i >=0; i--) {
                        chip = &cfi->chips[i];
 
-                       spin_lock_bh(chip->mutex);
+                       mutex_lock(&chip->mutex);
 
                        if (chip->state == FL_PM_SUSPENDED) {
                                /* No need to force it into a known state here,
@@ -1372,7 +1372,7 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
                                chip->state = chip->oldstate;
                                wake_up(&chip->wq);
                        }
-                       spin_unlock_bh(chip->mutex);
+                       mutex_unlock(&chip->mutex);
                }
        }
 
@@ -1390,7 +1390,7 @@ static void cfi_staa_resume(struct mtd_info *mtd)
 
                chip = &cfi->chips[i];
 
-               spin_lock_bh(chip->mutex);
+               mutex_lock(&chip->mutex);
 
                /* Go to known state. Chip may have been power cycled */
                if (chip->state == FL_PM_SUSPENDED) {
@@ -1399,7 +1399,7 @@ static void cfi_staa_resume(struct mtd_info *mtd)
                        wake_up(&chip->wq);
                }
 
-               spin_unlock_bh(chip->mutex);
+               mutex_unlock(&chip->mutex);
        }
 }
 
index e63e674..b2acd32 100644 (file)
@@ -158,6 +158,7 @@ static int __xipram cfi_chip_setup(struct map_info *map,
        __u32 base = 0;
        int num_erase_regions = cfi_read_query(map, base + (0x10 + 28)*ofs_factor);
        int i;
+       int addr_unlock1 = 0x555, addr_unlock2 = 0x2AA;
 
        xip_enable(base, map, cfi);
 #ifdef DEBUG_CFI
@@ -181,29 +182,6 @@ static int __xipram cfi_chip_setup(struct map_info *map,
        for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++)
                ((unsigned char *)cfi->cfiq)[i] = cfi_read_query(map,base + (0x10 + i)*ofs_factor);
 
-       /* Note we put the device back into Read Mode BEFORE going into Auto
-        * Select Mode, as some devices support nesting of modes, others
-        * don't. This way should always work.
-        * On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and
-        * so should be treated as nops or illegal (and so put the device
-        * back into Read Mode, which is a nop in this case).
-        */
-       cfi_send_gen_cmd(0xf0,     0, base, map, cfi, cfi->device_type, NULL);
-       cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
-       cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
-       cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
-       cfi->mfr = cfi_read_query16(map, base);
-       cfi->id = cfi_read_query16(map, base + ofs_factor);
-
-       /* Get AMD/Spansion extended JEDEC ID */
-       if (cfi->mfr == CFI_MFR_AMD && (cfi->id & 0xff) == 0x7e)
-               cfi->id = cfi_read_query(map, base + 0xe * ofs_factor) << 8 |
-                         cfi_read_query(map, base + 0xf * ofs_factor);
-
-       /* Put it back into Read Mode */
-       cfi_qry_mode_off(base, map, cfi);
-       xip_allowed(base, map);
-
        /* Do any necessary byteswapping */
        cfi->cfiq->P_ID = le16_to_cpu(cfi->cfiq->P_ID);
 
@@ -228,6 +206,35 @@ static int __xipram cfi_chip_setup(struct map_info *map,
 #endif
        }
 
+       if (cfi->cfiq->P_ID == P_ID_SST_OLD) {
+               addr_unlock1 = 0x5555;
+               addr_unlock2 = 0x2AAA;
+       }
+
+       /*
+        * Note we put the device back into Read Mode BEFORE going into Auto
+        * Select Mode, as some devices support nesting of modes, others
+        * don't. This way should always work.
+        * On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and
+        * so should be treated as nops or illegal (and so put the device
+        * back into Read Mode, which is a nop in this case).
+        */
+       cfi_send_gen_cmd(0xf0,     0, base, map, cfi, cfi->device_type, NULL);
+       cfi_send_gen_cmd(0xaa, addr_unlock1, base, map, cfi, cfi->device_type, NULL);
+       cfi_send_gen_cmd(0x55, addr_unlock2, base, map, cfi, cfi->device_type, NULL);
+       cfi_send_gen_cmd(0x90, addr_unlock1, base, map, cfi, cfi->device_type, NULL);
+       cfi->mfr = cfi_read_query16(map, base);
+       cfi->id = cfi_read_query16(map, base + ofs_factor);
+
+       /* Get AMD/Spansion extended JEDEC ID */
+       if (cfi->mfr == CFI_MFR_AMD && (cfi->id & 0xff) == 0x7e)
+               cfi->id = cfi_read_query(map, base + 0xe * ofs_factor) << 8 |
+                         cfi_read_query(map, base + 0xf * ofs_factor);
+
+       /* Put it back into Read Mode */
+       cfi_qry_mode_off(base, map, cfi);
+       xip_allowed(base, map);
+
        printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
               map->name, cfi->interleave, cfi->device_type*8, base,
               map->bankwidth*8);
@@ -269,6 +276,9 @@ static char *vendorname(__u16 vendor)
        case P_ID_SST_PAGE:
                return "SST Page Write";
 
+       case P_ID_SST_OLD:
+               return "SST 39VF160x/39VF320x";
+
        case P_ID_INTEL_PERFORMANCE:
                return "Intel Performance Code";
 
index ca584d0..d7c2c67 100644 (file)
@@ -104,10 +104,11 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n
        int i;
        struct cfi_extquery *extp = NULL;
 
-       printk(" %s Extended Query Table at 0x%4.4X\n", name, adr);
        if (!adr)
                goto out;
 
+       printk(KERN_INFO "%s Extended Query Table at 0x%4.4X\n", name, adr);
+
        extp = kmalloc(size, GFP_KERNEL);
        if (!extp) {
                printk(KERN_ERR "Failed to allocate memory\n");
index 57e0e4e..d180649 100644 (file)
@@ -58,10 +58,10 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
         * to flash memory - that means that we don't have to check status
         * and timeout.
         */
-       spin_lock(chip->mutex);
+       mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, adr, FL_LOCKING);
        if (ret) {
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
                return ret;
        }
 
@@ -72,7 +72,7 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
        /* Done and happy. */
        chip->state = chip->oldstate;
        put_chip(map, chip, adr);
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return 0;
 }
 
index e2dc964..3b9a284 100644 (file)
@@ -155,8 +155,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
                        pchip->start = (i << cfi.chipshift);
                        pchip->state = FL_READY;
                        init_waitqueue_head(&pchip->wq);
-                       spin_lock_init(&pchip->_spinlock);
-                       pchip->mutex = &pchip->_spinlock;
+                       mutex_init(&pchip->mutex);
                }
        }
 
@@ -242,17 +241,19 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
                /* We need these for the !CONFIG_MODULES case,
                   because symbol_get() doesn't work there */
 #ifdef CONFIG_MTD_CFI_INTELEXT
-       case 0x0001:
-       case 0x0003:
-       case 0x0200:
+       case P_ID_INTEL_EXT:
+       case P_ID_INTEL_STD:
+       case P_ID_INTEL_PERFORMANCE:
                return cfi_cmdset_0001(map, primary);
 #endif
 #ifdef CONFIG_MTD_CFI_AMDSTD
-       case 0x0002:
+       case P_ID_AMD_STD:
+       case P_ID_SST_OLD:
+       case P_ID_WINBOND:
                return cfi_cmdset_0002(map, primary);
 #endif
 #ifdef CONFIG_MTD_CFI_STAA
-        case 0x0020:
+        case P_ID_ST_ADV:
                return cfi_cmdset_0020(map, primary);
 #endif
        default:
index 8db1148..d72a5fb 100644 (file)
 #include <linux/mtd/cfi.h>
 #include <linux/mtd/gen_probe.h>
 
-/* Manufacturers */
-#define MANUFACTURER_AMD       0x0001
-#define MANUFACTURER_ATMEL     0x001f
-#define MANUFACTURER_EON       0x001c
-#define MANUFACTURER_FUJITSU   0x0004
-#define MANUFACTURER_HYUNDAI   0x00AD
-#define MANUFACTURER_INTEL     0x0089
-#define MANUFACTURER_MACRONIX  0x00C2
-#define MANUFACTURER_NEC       0x0010
-#define MANUFACTURER_PMC       0x009D
-#define MANUFACTURER_SHARP     0x00b0
-#define MANUFACTURER_SST       0x00BF
-#define MANUFACTURER_ST                0x0020
-#define MANUFACTURER_TOSHIBA   0x0098
-#define MANUFACTURER_WINBOND   0x00da
-#define CONTINUATION_CODE      0x007f
-
-
 /* AMD */
 #define AM29DL800BB    0x22CB
 #define AM29DL800BT    0x224A
 #define SST39LF160     0x2782
 #define SST39VF1601    0x234b
 #define SST39VF3201    0x235b
+#define SST39WF1601    0x274b
+#define SST39WF1602    0x274a
 #define SST39LF512     0x00D4
 #define SST39LF010     0x00D5
 #define SST39LF020     0x00D6
@@ -309,7 +293,7 @@ struct amd_flash_info {
  */
 static const struct amd_flash_info jedec_table[] = {
        {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29F032B,
                .name           = "AMD AM29F032B",
                .uaddr          = MTD_UADDR_0x0555_0x02AA,
@@ -321,7 +305,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,64)
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29LV160DT,
                .name           = "AMD AM29LV160DT",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -336,7 +320,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1)
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29LV160DB,
                .name           = "AMD AM29LV160DB",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -351,7 +335,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,31)
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29LV400BB,
                .name           = "AMD AM29LV400BB",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -366,7 +350,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,7)
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29LV400BT,
                .name           = "AMD AM29LV400BT",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -381,7 +365,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1)
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29LV800BB,
                .name           = "AMD AM29LV800BB",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -397,7 +381,7 @@ static const struct amd_flash_info jedec_table[] = {
                }
        }, {
 /* add DL */
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29DL800BB,
                .name           = "AMD AM29DL800BB",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -414,7 +398,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,14)
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29DL800BT,
                .name           = "AMD AM29DL800BT",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -431,7 +415,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1)
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29F800BB,
                .name           = "AMD AM29F800BB",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -446,7 +430,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,15),
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29LV800BT,
                .name           = "AMD AM29LV800BT",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -461,7 +445,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1)
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29F800BT,
                .name           = "AMD AM29F800BT",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -476,7 +460,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1)
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29F017D,
                .name           = "AMD AM29F017D",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -488,7 +472,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,32),
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29F016D,
                .name           = "AMD AM29F016D",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -500,7 +484,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,32),
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29F080,
                .name           = "AMD AM29F080",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -512,7 +496,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,16),
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29F040,
                .name           = "AMD AM29F040",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -524,7 +508,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,8),
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29LV040B,
                .name           = "AMD AM29LV040B",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -536,7 +520,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,8),
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29F002T,
                .name           = "AMD AM29F002T",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -551,7 +535,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1),
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29SL800DT,
                .name           = "AMD AM29SL800DT",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -566,7 +550,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1),
                }
        }, {
-               .mfr_id         = MANUFACTURER_AMD,
+               .mfr_id         = CFI_MFR_AMD,
                .dev_id         = AM29SL800DB,
                .name           = "AMD AM29SL800DB",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -581,7 +565,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,15),
                }
        }, {
-               .mfr_id         = MANUFACTURER_ATMEL,
+               .mfr_id         = CFI_MFR_ATMEL,
                .dev_id         = AT49BV512,
                .name           = "Atmel AT49BV512",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -593,7 +577,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,1)
                }
        }, {
-               .mfr_id         = MANUFACTURER_ATMEL,
+               .mfr_id         = CFI_MFR_ATMEL,
                .dev_id         = AT29LV512,
                .name           = "Atmel AT29LV512",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -606,7 +590,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x80,256)
                }
        }, {
-               .mfr_id         = MANUFACTURER_ATMEL,
+               .mfr_id         = CFI_MFR_ATMEL,
                .dev_id         = AT49BV16X,
                .name           = "Atmel AT49BV16X",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -619,7 +603,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,31)
                }
        }, {
-               .mfr_id         = MANUFACTURER_ATMEL,
+               .mfr_id         = CFI_MFR_ATMEL,
                .dev_id         = AT49BV16XT,
                .name           = "Atmel AT49BV16XT",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -632,7 +616,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x02000,8)
                }
        }, {
-               .mfr_id         = MANUFACTURER_ATMEL,
+               .mfr_id         = CFI_MFR_ATMEL,
                .dev_id         = AT49BV32X,
                .name           = "Atmel AT49BV32X",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -645,7 +629,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,63)
                }
        }, {
-               .mfr_id         = MANUFACTURER_ATMEL,
+               .mfr_id         = CFI_MFR_ATMEL,
                .dev_id         = AT49BV32XT,
                .name           = "Atmel AT49BV32XT",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -658,7 +642,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x02000,8)
                }
        }, {
-               .mfr_id         = MANUFACTURER_EON,
+               .mfr_id         = CFI_MFR_EON,
                .dev_id         = EN29SL800BT,
                .name           = "Eon EN29SL800BT",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -673,7 +657,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1),
                }
        }, {
-               .mfr_id         = MANUFACTURER_EON,
+               .mfr_id         = CFI_MFR_EON,
                .dev_id         = EN29SL800BB,
                .name           = "Eon EN29SL800BB",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -688,7 +672,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,15),
                }
        }, {
-               .mfr_id         = MANUFACTURER_FUJITSU,
+               .mfr_id         = CFI_MFR_FUJITSU,
                .dev_id         = MBM29F040C,
                .name           = "Fujitsu MBM29F040C",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -700,7 +684,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,8)
                }
        }, {
-               .mfr_id         = MANUFACTURER_FUJITSU,
+               .mfr_id         = CFI_MFR_FUJITSU,
                .dev_id         = MBM29F800BA,
                .name           = "Fujitsu MBM29F800BA",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -715,7 +699,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,15),
                }
        }, {
-               .mfr_id         = MANUFACTURER_FUJITSU,
+               .mfr_id         = CFI_MFR_FUJITSU,
                .dev_id         = MBM29LV650UE,
                .name           = "Fujitsu MBM29LV650UE",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -727,7 +711,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,128)
                }
        }, {
-               .mfr_id         = MANUFACTURER_FUJITSU,
+               .mfr_id         = CFI_MFR_FUJITSU,
                .dev_id         = MBM29LV320TE,
                .name           = "Fujitsu MBM29LV320TE",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -740,7 +724,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x02000,8)
                }
        }, {
-               .mfr_id         = MANUFACTURER_FUJITSU,
+               .mfr_id         = CFI_MFR_FUJITSU,
                .dev_id         = MBM29LV320BE,
                .name           = "Fujitsu MBM29LV320BE",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -753,7 +737,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,63)
                }
        }, {
-               .mfr_id         = MANUFACTURER_FUJITSU,
+               .mfr_id         = CFI_MFR_FUJITSU,
                .dev_id         = MBM29LV160TE,
                .name           = "Fujitsu MBM29LV160TE",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -768,7 +752,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1)
                }
        }, {
-               .mfr_id         = MANUFACTURER_FUJITSU,
+               .mfr_id         = CFI_MFR_FUJITSU,
                .dev_id         = MBM29LV160BE,
                .name           = "Fujitsu MBM29LV160BE",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -783,7 +767,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,31)
                }
        }, {
-               .mfr_id         = MANUFACTURER_FUJITSU,
+               .mfr_id         = CFI_MFR_FUJITSU,
                .dev_id         = MBM29LV800BA,
                .name           = "Fujitsu MBM29LV800BA",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -798,7 +782,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,15)
                }
        }, {
-               .mfr_id         = MANUFACTURER_FUJITSU,
+               .mfr_id         = CFI_MFR_FUJITSU,
                .dev_id         = MBM29LV800TA,
                .name           = "Fujitsu MBM29LV800TA",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -813,7 +797,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1)
                }
        }, {
-               .mfr_id         = MANUFACTURER_FUJITSU,
+               .mfr_id         = CFI_MFR_FUJITSU,
                .dev_id         = MBM29LV400BC,
                .name           = "Fujitsu MBM29LV400BC",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -828,7 +812,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,7)
                }
        }, {
-               .mfr_id         = MANUFACTURER_FUJITSU,
+               .mfr_id         = CFI_MFR_FUJITSU,
                .dev_id         = MBM29LV400TC,
                .name           = "Fujitsu MBM29LV400TC",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -843,7 +827,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1)
                }
        }, {
-               .mfr_id         = MANUFACTURER_HYUNDAI,
+               .mfr_id         = CFI_MFR_HYUNDAI,
                .dev_id         = HY29F002T,
                .name           = "Hyundai HY29F002T",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -858,7 +842,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F004B3B,
                .name           = "Intel 28F004B3B",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -871,7 +855,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000, 7),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F004B3T,
                .name           = "Intel 28F004B3T",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -884,7 +868,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x02000, 8),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F400B3B,
                .name           = "Intel 28F400B3B",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -897,7 +881,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000, 7),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F400B3T,
                .name           = "Intel 28F400B3T",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -910,7 +894,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x02000, 8),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F008B3B,
                .name           = "Intel 28F008B3B",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -923,7 +907,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000, 15),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F008B3T,
                .name           = "Intel 28F008B3T",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -936,7 +920,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x02000, 8),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F008S5,
                .name           = "Intel 28F008S5",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -948,7 +932,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,16),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F016S5,
                .name           = "Intel 28F016S5",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -960,7 +944,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,32),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F008SA,
                .name           = "Intel 28F008SA",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -972,7 +956,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000, 16),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F800B3B,
                .name           = "Intel 28F800B3B",
                .devtypes       = CFI_DEVICETYPE_X16,
@@ -985,7 +969,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000, 15),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F800B3T,
                .name           = "Intel 28F800B3T",
                .devtypes       = CFI_DEVICETYPE_X16,
@@ -998,7 +982,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x02000, 8),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F016B3B,
                .name           = "Intel 28F016B3B",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1011,7 +995,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000, 31),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F016S3,
                .name           = "Intel I28F016S3",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1023,7 +1007,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000, 32),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F016B3T,
                .name           = "Intel 28F016B3T",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1036,7 +1020,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x02000, 8),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F160B3B,
                .name           = "Intel 28F160B3B",
                .devtypes       = CFI_DEVICETYPE_X16,
@@ -1049,7 +1033,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000, 31),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F160B3T,
                .name           = "Intel 28F160B3T",
                .devtypes       = CFI_DEVICETYPE_X16,
@@ -1062,7 +1046,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x02000, 8),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F320B3B,
                .name           = "Intel 28F320B3B",
                .devtypes       = CFI_DEVICETYPE_X16,
@@ -1075,7 +1059,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000, 63),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F320B3T,
                .name           = "Intel 28F320B3T",
                .devtypes       = CFI_DEVICETYPE_X16,
@@ -1088,7 +1072,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x02000, 8),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F640B3B,
                .name           = "Intel 28F640B3B",
                .devtypes       = CFI_DEVICETYPE_X16,
@@ -1101,7 +1085,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000, 127),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F640B3T,
                .name           = "Intel 28F640B3T",
                .devtypes       = CFI_DEVICETYPE_X16,
@@ -1114,7 +1098,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x02000, 8),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I28F640C3B,
                .name           = "Intel 28F640C3B",
                .devtypes       = CFI_DEVICETYPE_X16,
@@ -1127,7 +1111,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000, 127),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I82802AB,
                .name           = "Intel 82802AB",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1139,7 +1123,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,8),
                }
        }, {
-               .mfr_id         = MANUFACTURER_INTEL,
+               .mfr_id         = CFI_MFR_INTEL,
                .dev_id         = I82802AC,
                .name           = "Intel 82802AC",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1151,7 +1135,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,16),
                }
        }, {
-               .mfr_id         = MANUFACTURER_MACRONIX,
+               .mfr_id         = CFI_MFR_MACRONIX,
                .dev_id         = MX29LV040C,
                .name           = "Macronix MX29LV040C",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1163,7 +1147,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,8),
                }
        }, {
-               .mfr_id         = MANUFACTURER_MACRONIX,
+               .mfr_id         = CFI_MFR_MACRONIX,
                .dev_id         = MX29LV160T,
                .name           = "MXIC MX29LV160T",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -1178,7 +1162,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1)
                }
        }, {
-               .mfr_id         = MANUFACTURER_NEC,
+               .mfr_id         = CFI_MFR_NEC,
                .dev_id         = UPD29F064115,
                .name           = "NEC uPD29F064115",
                .devtypes       = CFI_DEVICETYPE_X16,
@@ -1192,7 +1176,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x2000,8),
                }
        }, {
-               .mfr_id         = MANUFACTURER_MACRONIX,
+               .mfr_id         = CFI_MFR_MACRONIX,
                .dev_id         = MX29LV160B,
                .name           = "MXIC MX29LV160B",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -1207,7 +1191,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,31)
                }
        }, {
-               .mfr_id         = MANUFACTURER_MACRONIX,
+               .mfr_id         = CFI_MFR_MACRONIX,
                .dev_id         = MX29F040,
                .name           = "Macronix MX29F040",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1219,7 +1203,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,8),
                }
        }, {
-               .mfr_id         = MANUFACTURER_MACRONIX,
+               .mfr_id         = CFI_MFR_MACRONIX,
                .dev_id         = MX29F016,
                .name           = "Macronix MX29F016",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1231,7 +1215,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,32),
                }
        }, {
-               .mfr_id         = MANUFACTURER_MACRONIX,
+               .mfr_id         = CFI_MFR_MACRONIX,
                .dev_id         = MX29F004T,
                .name           = "Macronix MX29F004T",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1246,7 +1230,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1),
                }
        }, {
-               .mfr_id         = MANUFACTURER_MACRONIX,
+               .mfr_id         = CFI_MFR_MACRONIX,
                .dev_id         = MX29F004B,
                .name           = "Macronix MX29F004B",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1261,7 +1245,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,7),
                }
        }, {
-               .mfr_id         = MANUFACTURER_MACRONIX,
+               .mfr_id         = CFI_MFR_MACRONIX,
                .dev_id         = MX29F002T,
                .name           = "Macronix MX29F002T",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1276,7 +1260,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1),
                }
        }, {
-               .mfr_id         = MANUFACTURER_PMC,
+               .mfr_id         = CFI_MFR_PMC,
                .dev_id         = PM49FL002,
                .name           = "PMC Pm49FL002",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1288,7 +1272,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO( 0x01000, 64 )
                }
        }, {
-               .mfr_id         = MANUFACTURER_PMC,
+               .mfr_id         = CFI_MFR_PMC,
                .dev_id         = PM49FL004,
                .name           = "PMC Pm49FL004",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1300,7 +1284,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO( 0x01000, 128 )
                }
        }, {
-               .mfr_id         = MANUFACTURER_PMC,
+               .mfr_id         = CFI_MFR_PMC,
                .dev_id         = PM49FL008,
                .name           = "PMC Pm49FL008",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1312,7 +1296,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO( 0x01000, 256 )
                }
        }, {
-               .mfr_id         = MANUFACTURER_SHARP,
+               .mfr_id         = CFI_MFR_SHARP,
                .dev_id         = LH28F640BF,
                .name           = "LH28F640BF",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1324,7 +1308,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x40000,16),
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,
+               .mfr_id         = CFI_MFR_SST,
                .dev_id         = SST39LF512,
                .name           = "SST 39LF512",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1336,7 +1320,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x01000,16),
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,
+               .mfr_id         = CFI_MFR_SST,
                .dev_id         = SST39LF010,
                .name           = "SST 39LF010",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1348,8 +1332,8 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x01000,32),
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,
-               .dev_id         = SST29EE020,
+               .mfr_id         = CFI_MFR_SST,
+               .dev_id         = SST29EE020,
                .name           = "SST 29EE020",
                .devtypes       = CFI_DEVICETYPE_X8,
                .uaddr          = MTD_UADDR_0x5555_0x2AAA,
@@ -1359,9 +1343,9 @@ static const struct amd_flash_info jedec_table[] = {
                .regions = {ERASEINFO(0x01000,64),
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,
+               .mfr_id         = CFI_MFR_SST,
                .dev_id         = SST29LE020,
-               .name           = "SST 29LE020",
+               .name           = "SST 29LE020",
                .devtypes       = CFI_DEVICETYPE_X8,
                .uaddr          = MTD_UADDR_0x5555_0x2AAA,
                .dev_size       = SIZE_256KiB,
@@ -1370,7 +1354,7 @@ static const struct amd_flash_info jedec_table[] = {
                .regions = {ERASEINFO(0x01000,64),
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,
+               .mfr_id         = CFI_MFR_SST,
                .dev_id         = SST39LF020,
                .name           = "SST 39LF020",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1382,7 +1366,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x01000,64),
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,
+               .mfr_id         = CFI_MFR_SST,
                .dev_id         = SST39LF040,
                .name           = "SST 39LF040",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1394,7 +1378,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x01000,128),
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,
+               .mfr_id         = CFI_MFR_SST,
                .dev_id         = SST39SF010A,
                .name           = "SST 39SF010A",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1406,7 +1390,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x01000,32),
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,
+               .mfr_id         = CFI_MFR_SST,
                .dev_id         = SST39SF020A,
                .name           = "SST 39SF020A",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1418,7 +1402,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x01000,64),
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,
+               .mfr_id         = CFI_MFR_SST,
                .dev_id         = SST39SF040,
                .name           = "SST 39SF040",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1430,7 +1414,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x01000,128),
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,
+               .mfr_id         = CFI_MFR_SST,
                .dev_id         = SST49LF040B,
                .name           = "SST 49LF040B",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1443,7 +1427,7 @@ static const struct amd_flash_info jedec_table[] = {
                }
        }, {
 
-               .mfr_id         = MANUFACTURER_SST,
+               .mfr_id         = CFI_MFR_SST,
                .dev_id         = SST49LF004B,
                .name           = "SST 49LF004B",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1455,7 +1439,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x01000,128),
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,
+               .mfr_id         = CFI_MFR_SST,
                .dev_id         = SST49LF008A,
                .name           = "SST 49LF008A",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1467,7 +1451,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x01000,256),
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,
+               .mfr_id         = CFI_MFR_SST,
                .dev_id         = SST49LF030A,
                .name           = "SST 49LF030A",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1479,7 +1463,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x01000,96),
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,
+               .mfr_id         = CFI_MFR_SST,
                .dev_id         = SST49LF040A,
                .name           = "SST 49LF040A",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1491,7 +1475,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x01000,128),
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,
+               .mfr_id         = CFI_MFR_SST,
                .dev_id         = SST49LF080A,
                .name           = "SST 49LF080A",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1503,7 +1487,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x01000,256),
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,     /* should be CFI */
+               .mfr_id         = CFI_MFR_SST,     /* should be CFI */
                .dev_id         = SST39LF160,
                .name           = "SST 39LF160",
                .devtypes       = CFI_DEVICETYPE_X16,
@@ -1516,7 +1500,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x1000,256)
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,     /* should be CFI */
+               .mfr_id         = CFI_MFR_SST,     /* should be CFI */
                .dev_id         = SST39VF1601,
                .name           = "SST 39VF1601",
                .devtypes       = CFI_DEVICETYPE_X16,
@@ -1529,7 +1513,35 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x1000,256)
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,     /* should be CFI */
+               /* CFI is broken: reports AMD_STD, but needs custom uaddr */
+               .mfr_id         = CFI_MFR_SST,
+               .dev_id         = SST39WF1601,
+               .name           = "SST 39WF1601",
+               .devtypes       = CFI_DEVICETYPE_X16,
+               .uaddr          = MTD_UADDR_0xAAAA_0x5555,
+               .dev_size       = SIZE_2MiB,
+               .cmd_set        = P_ID_AMD_STD,
+               .nr_regions     = 2,
+               .regions        = {
+                       ERASEINFO(0x1000,256),
+                       ERASEINFO(0x1000,256)
+               }
+       }, {
+               /* CFI is broken: reports AMD_STD, but needs custom uaddr */
+               .mfr_id         = CFI_MFR_SST,
+               .dev_id         = SST39WF1602,
+               .name           = "SST 39WF1602",
+               .devtypes       = CFI_DEVICETYPE_X16,
+               .uaddr          = MTD_UADDR_0xAAAA_0x5555,
+               .dev_size       = SIZE_2MiB,
+               .cmd_set        = P_ID_AMD_STD,
+               .nr_regions     = 2,
+               .regions        = {
+                       ERASEINFO(0x1000,256),
+                       ERASEINFO(0x1000,256)
+               }
+       }, {
+               .mfr_id         = CFI_MFR_SST,     /* should be CFI */
                .dev_id         = SST39VF3201,
                .name           = "SST 39VF3201",
                .devtypes       = CFI_DEVICETYPE_X16,
@@ -1544,7 +1556,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x1000,256)
                }
        }, {
-               .mfr_id         = MANUFACTURER_SST,
+               .mfr_id         = CFI_MFR_SST,
                .dev_id         = SST36VF3203,
                .name           = "SST 36VF3203",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -1556,7 +1568,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,64),
                }
        }, {
-               .mfr_id         = MANUFACTURER_ST,
+               .mfr_id         = CFI_MFR_ST,
                .dev_id         = M29F800AB,
                .name           = "ST M29F800AB",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -1571,7 +1583,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,15),
                }
        }, {
-               .mfr_id         = MANUFACTURER_ST,      /* FIXME - CFI device? */
+               .mfr_id         = CFI_MFR_ST,   /* FIXME - CFI device? */
                .dev_id         = M29W800DT,
                .name           = "ST M29W800DT",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -1586,7 +1598,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1)
                }
        }, {
-               .mfr_id         = MANUFACTURER_ST,      /* FIXME - CFI device? */
+               .mfr_id         = CFI_MFR_ST,   /* FIXME - CFI device? */
                .dev_id         = M29W800DB,
                .name           = "ST M29W800DB",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -1601,7 +1613,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,15)
                }
        },  {
-               .mfr_id         = MANUFACTURER_ST,
+               .mfr_id         = CFI_MFR_ST,
                .dev_id         = M29W400DT,
                .name           = "ST M29W400DT",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -1616,7 +1628,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,1)
                }
        }, {
-               .mfr_id         = MANUFACTURER_ST,
+               .mfr_id         = CFI_MFR_ST,
                .dev_id         = M29W400DB,
                .name           = "ST M29W400DB",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -1631,7 +1643,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,7)
                }
        }, {
-               .mfr_id         = MANUFACTURER_ST,      /* FIXME - CFI device? */
+               .mfr_id         = CFI_MFR_ST,   /* FIXME - CFI device? */
                .dev_id         = M29W160DT,
                .name           = "ST M29W160DT",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -1646,7 +1658,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1)
                }
        }, {
-               .mfr_id         = MANUFACTURER_ST,      /* FIXME - CFI device? */
+               .mfr_id         = CFI_MFR_ST,   /* FIXME - CFI device? */
                .dev_id         = M29W160DB,
                .name           = "ST M29W160DB",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -1661,7 +1673,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,31)
                }
        }, {
-               .mfr_id         = MANUFACTURER_ST,
+               .mfr_id         = CFI_MFR_ST,
                .dev_id         = M29W040B,
                .name           = "ST M29W040B",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1673,7 +1685,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,8),
                }
        }, {
-               .mfr_id         = MANUFACTURER_ST,
+               .mfr_id         = CFI_MFR_ST,
                .dev_id         = M50FW040,
                .name           = "ST M50FW040",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1685,7 +1697,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,8),
                }
        }, {
-               .mfr_id         = MANUFACTURER_ST,
+               .mfr_id         = CFI_MFR_ST,
                .dev_id         = M50FW080,
                .name           = "ST M50FW080",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1697,7 +1709,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,16),
                }
        }, {
-               .mfr_id         = MANUFACTURER_ST,
+               .mfr_id         = CFI_MFR_ST,
                .dev_id         = M50FW016,
                .name           = "ST M50FW016",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1709,7 +1721,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,32),
                }
        }, {
-               .mfr_id         = MANUFACTURER_ST,
+               .mfr_id         = CFI_MFR_ST,
                .dev_id         = M50LPW080,
                .name           = "ST M50LPW080",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1721,7 +1733,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,16),
                },
        }, {
-               .mfr_id         = MANUFACTURER_ST,
+               .mfr_id         = CFI_MFR_ST,
                .dev_id         = M50FLW080A,
                .name           = "ST M50FLW080A",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1736,7 +1748,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x1000,16),
                }
        }, {
-               .mfr_id         = MANUFACTURER_ST,
+               .mfr_id         = CFI_MFR_ST,
                .dev_id         = M50FLW080B,
                .name           = "ST M50FLW080B",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1751,7 +1763,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x1000,16),
                }
        }, {
-               .mfr_id         = 0xff00 | MANUFACTURER_ST,
+               .mfr_id         = 0xff00 | CFI_MFR_ST,
                .dev_id         = 0xff00 | PSD4256G6V,
                .name           = "ST PSD4256G6V",
                .devtypes       = CFI_DEVICETYPE_X16,
@@ -1763,7 +1775,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,16),
                }
        }, {
-               .mfr_id         = MANUFACTURER_TOSHIBA,
+               .mfr_id         = CFI_MFR_TOSHIBA,
                .dev_id         = TC58FVT160,
                .name           = "Toshiba TC58FVT160",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -1778,7 +1790,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x04000,1)
                }
        }, {
-               .mfr_id         = MANUFACTURER_TOSHIBA,
+               .mfr_id         = CFI_MFR_TOSHIBA,
                .dev_id         = TC58FVB160,
                .name           = "Toshiba TC58FVB160",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -1793,7 +1805,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,31)
                }
        }, {
-               .mfr_id         = MANUFACTURER_TOSHIBA,
+               .mfr_id         = CFI_MFR_TOSHIBA,
                .dev_id         = TC58FVB321,
                .name           = "Toshiba TC58FVB321",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -1806,7 +1818,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,63)
                }
        }, {
-               .mfr_id         = MANUFACTURER_TOSHIBA,
+               .mfr_id         = CFI_MFR_TOSHIBA,
                .dev_id         = TC58FVT321,
                .name           = "Toshiba TC58FVT321",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -1819,7 +1831,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x02000,8)
                }
        }, {
-               .mfr_id         = MANUFACTURER_TOSHIBA,
+               .mfr_id         = CFI_MFR_TOSHIBA,
                .dev_id         = TC58FVB641,
                .name           = "Toshiba TC58FVB641",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -1832,7 +1844,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x10000,127)
                }
        }, {
-               .mfr_id         = MANUFACTURER_TOSHIBA,
+               .mfr_id         = CFI_MFR_TOSHIBA,
                .dev_id         = TC58FVT641,
                .name           = "Toshiba TC58FVT641",
                .devtypes       = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,
@@ -1845,7 +1857,7 @@ static const struct amd_flash_info jedec_table[] = {
                        ERASEINFO(0x02000,8)
                }
        }, {
-               .mfr_id         = MANUFACTURER_WINBOND,
+               .mfr_id         = CFI_MFR_WINBOND,
                .dev_id         = W49V002A,
                .name           = "Winbond W49V002A",
                .devtypes       = CFI_DEVICETYPE_X8,
@@ -1878,7 +1890,7 @@ static inline u32 jedec_read_mfr(struct map_info *map, uint32_t base,
                mask = (1 << (cfi->device_type * 8)) - 1;
                result = map_read(map, base + ofs);
                bank++;
-       } while ((result.x[0] & mask) == CONTINUATION_CODE);
+       } while ((result.x[0] & mask) == CFI_MFR_CONTINUATION);
 
        return result.x[0] & mask;
 }
@@ -1969,7 +1981,7 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
        p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1 / p_cfi->device_type;
        p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2 / p_cfi->device_type;
 
-       return 1;       /* ok */
+       return 1;       /* ok */
 }
 
 
index ab5c9b9..f3226b1 100644 (file)
@@ -1,5 +1,5 @@
 #
-# linux/drivers/devices/Makefile
+# linux/drivers/mtd/devices/Makefile
 #
 
 obj-$(CONFIG_MTD_DOC2000)      += doc2000.o
index ce64240..9365186 100644 (file)
@@ -276,12 +276,10 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
 
        /* 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;
index d2fd550..fc8ea0a 100644 (file)
@@ -668,7 +668,7 @@ static int __init init_pmc551(void)
 {
        struct pci_dev *PCI_Device = NULL;
        struct mypriv *priv;
-       int count, found = 0;
+       int found = 0;
        struct mtd_info *mtd;
        u32 length = 0;
 
@@ -695,7 +695,7 @@ static int __init init_pmc551(void)
        /*
         * PCU-bus chipset probe.
         */
-       for (count = 0; count < MAX_MTD_DEVICES; count++) {
+       for (;;) {
 
                if ((PCI_Device = pci_get_device(PCI_VENDOR_ID_V3_SEMI,
                                                  PCI_DEVICE_ID_V3_SEMI_V370PDC,
index fe17054..ab5d8cd 100644 (file)
@@ -73,15 +73,25 @@ static struct flash_info __initdata sst25l_flash_info[] = {
 
 static int sst25l_status(struct sst25l_flash *flash, int *status)
 {
-       unsigned char command, response;
+       struct spi_message m;
+       struct spi_transfer t;
+       unsigned char cmd_resp[2];
        int err;
 
-       command = SST25L_CMD_RDSR;
-       err = spi_write_then_read(flash->spi, &command, 1, &response, 1);
+       spi_message_init(&m);
+       memset(&t, 0, sizeof(struct spi_transfer));
+
+       cmd_resp[0] = SST25L_CMD_RDSR;
+       cmd_resp[1] = 0xff;
+       t.tx_buf = cmd_resp;
+       t.rx_buf = cmd_resp;
+       t.len = sizeof(cmd_resp);
+       spi_message_add_tail(&t, &m);
+       err = spi_sync(flash->spi, &m);
        if (err < 0)
                return err;
 
-       *status = response;
+       *status = cmd_resp[1];
        return 0;
 }
 
@@ -328,33 +338,32 @@ out:
 static struct flash_info *__init sst25l_match_device(struct spi_device *spi)
 {
        struct flash_info *flash_info = NULL;
-       unsigned char command[4], response;
+       struct spi_message m;
+       struct spi_transfer t;
+       unsigned char cmd_resp[6];
        int i, err;
        uint16_t id;
 
-       command[0] = SST25L_CMD_READ_ID;
-       command[1] = 0;
-       command[2] = 0;
-       command[3] = 0;
-       err = spi_write_then_read(spi, command, sizeof(command), &response, 1);
+       spi_message_init(&m);
+       memset(&t, 0, sizeof(struct spi_transfer));
+
+       cmd_resp[0] = SST25L_CMD_READ_ID;
+       cmd_resp[1] = 0;
+       cmd_resp[2] = 0;
+       cmd_resp[3] = 0;
+       cmd_resp[4] = 0xff;
+       cmd_resp[5] = 0xff;
+       t.tx_buf = cmd_resp;
+       t.rx_buf = cmd_resp;
+       t.len = sizeof(cmd_resp);
+       spi_message_add_tail(&t, &m);
+       err = spi_sync(spi, &m);
        if (err < 0) {
-               dev_err(&spi->dev, "error reading device id msb\n");
+               dev_err(&spi->dev, "error reading device id\n");
                return NULL;
        }
 
-       id = response << 8;
-
-       command[0] = SST25L_CMD_READ_ID;
-       command[1] = 0;
-       command[2] = 0;
-       command[3] = 1;
-       err = spi_write_then_read(spi, command, sizeof(command), &response, 1);
-       if (err < 0) {
-               dev_err(&spi->dev, "error reading device id lsb\n");
-               return NULL;
-       }
-
-       id |= response;
+       id = (cmd_resp[4] << 8) | cmd_resp[5];
 
        for (i = 0; i < ARRAY_SIZE(sst25l_flash_info); i++)
                if (sst25l_flash_info[i].device_id == id)
@@ -411,17 +420,6 @@ static int __init sst25l_probe(struct spi_device *spi)
              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;
index e56d6b4..62da9eb 100644 (file)
@@ -1082,7 +1082,6 @@ static void ftl_remove_dev(struct mtd_blktrans_dev *dev)
 {
        del_mtd_blktrans_dev(dev);
        ftl_freepart((partition_t *)dev);
-       kfree(dev);
 }
 
 static struct mtd_blktrans_ops ftl_tr = {
index 8aca552..015a7fe 100644 (file)
@@ -139,7 +139,6 @@ static void inftl_remove_dev(struct mtd_blktrans_dev *dev)
 
        kfree(inftl->PUtable);
        kfree(inftl->VUtable);
-       kfree(inftl);
 }
 
 /*
index 32e82ae..8f988d7 100644 (file)
@@ -100,9 +100,10 @@ static int find_boot_record(struct INFTLrecord *inftl)
                }
 
                /* To be safer with BIOS, also use erase mark as discriminant */
-               if ((ret = inftl_read_oob(mtd, block * inftl->EraseSize +
-                                         SECTORSIZE + 8, 8, &retlen,
-                                         (char *)&h1) < 0)) {
+               ret = inftl_read_oob(mtd,
+                                    block * inftl->EraseSize + SECTORSIZE + 8,
+                                    8, &retlen,(char *)&h1);
+               if (ret < 0) {
                        printk(KERN_WARNING "INFTL: ANAND header found at "
                                "0x%x in mtd%d, but OOB data read failed "
                                "(err %d)\n", block * inftl->EraseSize,
index a73ee12..fece5be 100644 (file)
@@ -107,8 +107,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map)
                        /* 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++;
                }
        }
@@ -144,7 +143,7 @@ static int wait_for_ready(struct map_info *map, struct flchip *chip,
                }
 
                /* 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
@@ -159,17 +158,17 @@ static int wait_for_ready(struct map_info *map, struct flchip *chip,
                        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 */
@@ -230,20 +229,20 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
                         * 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);
@@ -252,10 +251,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
                         * 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.
@@ -265,10 +264,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
                        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;
                }
 
@@ -337,10 +336,10 @@ static int chip_ready(struct map_info *map, struct flchip *chip, int mode)
 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;
        }
 }
@@ -356,12 +355,12 @@ static void put_chip(struct map_info *map, struct flchip *chip)
                        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;
                        }
@@ -414,10 +413,10 @@ int do_write_buffer(struct map_info *map, struct flchip *chip,
 
        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 */
@@ -478,7 +477,7 @@ int do_write_buffer(struct map_info *map, struct flchip *chip,
        }
 
  out:  put_chip(map, chip);
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return ret;
 }
 
@@ -490,10 +489,10 @@ int do_erase_oneblock(struct mtd_info *mtd, loff_t adr)
        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);
@@ -505,7 +504,7 @@ int do_erase_oneblock(struct mtd_info *mtd, loff_t adr)
                goto out;
        }
  out:  put_chip(map, chip);
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return ret;
 }
 
@@ -518,10 +517,10 @@ static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len,
        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;
        }
 
@@ -529,7 +528,7 @@ static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len,
        *retlen = len;
 
        put_chip(map, chip);
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return ret;
 }
 
@@ -569,9 +568,9 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len,
                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;
 
@@ -611,7 +610,7 @@ static void lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len)
                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)
@@ -621,7 +620,7 @@ static void lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len)
                                        "pointed region\n", map->name);
 
                put_chip(map, chip);
-               spin_unlock(chip->mutex);
+               mutex_unlock(&chip->mutex);
 
                len -= thislen;
                ofs = 0;
@@ -727,10 +726,10 @@ int do_xxlock(struct mtd_info *mtd, loff_t adr, uint32_t len, int thunk)
        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;
        }
 
@@ -750,7 +749,7 @@ int do_xxlock(struct mtd_info *mtd, loff_t adr, uint32_t len, int thunk)
                goto out;
        }
 out:   put_chip(map, chip);
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return ret;
 }
 
@@ -771,10 +770,10 @@ int word_program(struct map_info *map, loff_t adr, uint32_t curval)
        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;
        }
 
@@ -788,7 +787,7 @@ int word_program(struct map_info *map, loff_t adr, uint32_t curval)
        }
 
 out:   put_chip(map, chip);
-       spin_unlock(chip->mutex);
+       mutex_unlock(&chip->mutex);
        return ret;
 }
 
index 79bf40f..dbfe17b 100644 (file)
@@ -134,13 +134,12 @@ out:
 static int lpddr_chip_setup(struct map_info *map, struct lpddr_private *lpddr)
 {
 
-       lpddr->qinfo = kmalloc(sizeof(struct qinfo_chip), GFP_KERNEL);
+       lpddr->qinfo = kzalloc(sizeof(struct qinfo_chip), GFP_KERNEL);
        if (!lpddr->qinfo) {
                printk(KERN_WARNING "%s: no memory for LPDDR qinfo structure\n",
                                map->name);
                return 0;
        }
-       memset(lpddr->qinfo, 0, sizeof(struct qinfo_chip));
 
        /* Get the ManuID */
        lpddr->ManufactId = CMDVAL(map_read(map, map->pfow_base + PFOW_MANUFACTURER_ID));
@@ -185,13 +184,11 @@ static struct lpddr_private *lpddr_probe_chip(struct map_info *map)
        lpddr.numchips = 1;
 
        numvirtchips = lpddr.numchips * lpddr.qinfo->HWPartsNum;
-       retlpddr = kmalloc(sizeof(struct lpddr_private) +
+       retlpddr = kzalloc(sizeof(struct lpddr_private) +
                        numvirtchips * sizeof(struct flchip), GFP_KERNEL);
        if (!retlpddr)
                return NULL;
 
-       memset(retlpddr, 0, sizeof(struct lpddr_private) +
-                               numvirtchips * sizeof(struct flchip));
        memcpy(retlpddr, &lpddr, sizeof(struct lpddr_private));
 
        retlpddr->numchips = numvirtchips;
index aa2807d..f22bc9f 100644 (file)
@@ -435,7 +435,7 @@ config MTD_PCI
 
 config MTD_PCMCIA
        tristate "PCMCIA MTD driver"
-       depends on PCMCIA && MTD_COMPLEX_MAPPINGS && BROKEN
+       depends on PCMCIA && MTD_COMPLEX_MAPPINGS
        help
          Map driver for accessing PCMCIA linear flash memory cards. These
          cards are usually around 4-16MiB in size. This does not include
index c0fd99b..85dd181 100644 (file)
@@ -70,7 +70,7 @@ static void switch_back(struct async_state *state)
        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;
@@ -86,7 +86,7 @@ static map_word bfin_read(struct map_info *map, unsigned long ofs)
        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;
 
@@ -97,7 +97,7 @@ static void bfin_copy_from(struct map_info *map, void *to, unsigned long from, s
        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;
@@ -112,7 +112,7 @@ static void bfin_write(struct map_info *map, map_word d1, unsigned long ofs)
        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;
 
@@ -141,10 +141,10 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev)
                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;
index d41f347..c09f4f5 100644 (file)
@@ -253,7 +253,7 @@ static void __exit clps_destroy_mtd(struct clps_info *clps, struct mtd_info *mtd
 
 static int __init clps_setup_flash(void)
 {
-       int nr;
+       int nr = 0;
 
 #ifdef CONFIG_ARCH_CEIVA
        if (machine_is_ceiva()) {
index 1bdf0ee..9639d83 100644 (file)
@@ -165,12 +165,11 @@ static int ixp2000_flash_probe(struct platform_device *dev)
                return -EIO;
        }
 
-       info = kmalloc(sizeof(struct ixp2000_flash_info), GFP_KERNEL);
+       info = kzalloc(sizeof(struct ixp2000_flash_info), GFP_KERNEL);
        if(!info) {
                err = -ENOMEM;
                goto Error;
        }
-       memset(info, 0, sizeof(struct ixp2000_flash_info));
 
        platform_set_drvdata(dev, info);
 
index 7b05152..e0a5e04 100644 (file)
@@ -107,8 +107,8 @@ static void ixp4xx_copy_from(struct map_info *map, void *to,
                return;
 
        if (from & 1) {
-               *dest++ = BYTE1(flash_read16(src));
-                src++;
+               *dest++ = BYTE1(flash_read16(src-1));
+               src++;
                --len;
        }
 
@@ -196,12 +196,11 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
                        return err;
        }
 
-       info = kmalloc(sizeof(struct ixp4xx_flash_info), GFP_KERNEL);
+       info = kzalloc(sizeof(struct ixp4xx_flash_info), GFP_KERNEL);
        if(!info) {
                err = -ENOMEM;
                goto Error;
        }
-       memset(info, 0, sizeof(struct ixp4xx_flash_info));
 
        platform_set_drvdata(dev, info);
 
index 87b2b8f..e699e6a 100644 (file)
@@ -40,10 +40,7 @@ MODULE_PARM_DESC(debug, "Set Debug Level 0=quiet, 5=noisy");
 static const int debug = 0;
 #endif
 
-#define err(format, arg...) printk(KERN_ERR "pcmciamtd: " format "\n" , ## arg)
 #define info(format, arg...) printk(KERN_INFO "pcmciamtd: " format "\n" , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "pcmciamtd: " format "\n" , ## arg)
-
 
 #define DRIVER_DESC    "PCMCIA Flash memory card driver"
 
@@ -99,7 +96,9 @@ module_param(mem_type, int, 0);
 MODULE_PARM_DESC(mem_type, "Set Memory type (0=Flash, 1=RAM, 2=ROM, default=0)");
 
 
-/* read/write{8,16} copy_{from,to} routines with window remapping to access whole card */
+/* read/write{8,16} copy_{from,to} routines with window remapping
+ * to access whole card
+ */
 static caddr_t remap_window(struct map_info *map, unsigned long to)
 {
        struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
@@ -136,7 +135,7 @@ static map_word pcmcia_read8_remap(struct map_info *map, unsigned long ofs)
                return d;
 
        d.x[0] = readb(addr);
-       DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02x", ofs, addr, d.x[0]);
+       DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02lx", ofs, addr, d.x[0]);
        return d;
 }
 
@@ -151,7 +150,7 @@ static map_word pcmcia_read16_remap(struct map_info *map, unsigned long ofs)
                return d;
 
        d.x[0] = readw(addr);
-       DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04x", ofs, addr, d.x[0]);
+       DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04lx", ofs, addr, d.x[0]);
        return d;
 }
 
@@ -161,7 +160,7 @@ static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long
        struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
        unsigned long win_size = dev->win_size;
 
-       DEBUG(3, "to = %p from = %lu len = %u", to, from, len);
+       DEBUG(3, "to = %p from = %lu len = %zd", to, from, len);
        while(len) {
                int toread = win_size - (from & (win_size-1));
                caddr_t addr;
@@ -189,7 +188,7 @@ static void pcmcia_write8_remap(struct map_info *map, map_word d, unsigned long
        if(!addr)
                return;
 
-       DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%02x", adr, addr, d.x[0]);
+       DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%02lx", adr, addr, d.x[0]);
        writeb(d.x[0], addr);
 }
 
@@ -200,7 +199,7 @@ static void pcmcia_write16_remap(struct map_info *map, map_word d, unsigned long
        if(!addr)
                return;
 
-       DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%04x", adr, addr, d.x[0]);
+       DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%04lx", adr, addr, d.x[0]);
        writew(d.x[0], addr);
 }
 
@@ -210,7 +209,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v
        struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
        unsigned long win_size = dev->win_size;
 
-       DEBUG(3, "to = %lu from = %p len = %u", to, from, len);
+       DEBUG(3, "to = %lu from = %p len = %zd", to, from, len);
        while(len) {
                int towrite = win_size - (to & (win_size-1));
                caddr_t addr;
@@ -244,7 +243,8 @@ static map_word pcmcia_read8(struct map_info *map, unsigned long ofs)
                return d;
 
        d.x[0] = readb(win_base + ofs);
-       DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02x", ofs, win_base + ofs, d.x[0]);
+       DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02lx",
+             ofs, win_base + ofs, d.x[0]);
        return d;
 }
 
@@ -258,7 +258,8 @@ static map_word pcmcia_read16(struct map_info *map, unsigned long ofs)
                return d;
 
        d.x[0] = readw(win_base + ofs);
-       DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04x", ofs, win_base + ofs, d.x[0]);
+       DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04lx",
+             ofs, win_base + ofs, d.x[0]);
        return d;
 }
 
@@ -270,32 +271,34 @@ static void pcmcia_copy_from(struct map_info *map, void *to, unsigned long from,
        if(DEV_REMOVED(map))
                return;
 
-       DEBUG(3, "to = %p from = %lu len = %u", to, from, len);
+       DEBUG(3, "to = %p from = %lu len = %zd", to, from, len);
        memcpy_fromio(to, win_base + from, len);
 }
 
 
-static void pcmcia_write8(struct map_info *map, u8 d, unsigned long adr)
+static void pcmcia_write8(struct map_info *map, map_word d, unsigned long adr)
 {
        caddr_t win_base = (caddr_t)map->map_priv_2;
 
        if(DEV_REMOVED(map))
                return;
 
-       DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%02x", adr, win_base + adr, d);
-       writeb(d, win_base + adr);
+       DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%02lx",
+             adr, win_base + adr, d.x[0]);
+       writeb(d.x[0], win_base + adr);
 }
 
 
-static void pcmcia_write16(struct map_info *map, u16 d, unsigned long adr)
+static void pcmcia_write16(struct map_info *map, map_word d, unsigned long adr)
 {
        caddr_t win_base = (caddr_t)map->map_priv_2;
 
        if(DEV_REMOVED(map))
                return;
 
-       DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%04x", adr, win_base + adr, d);
-       writew(d, win_base + adr);
+       DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%04lx",
+             adr, win_base + adr, d.x[0]);
+       writew(d.x[0], win_base + adr);
 }
 
 
@@ -306,7 +309,7 @@ static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *f
        if(DEV_REMOVED(map))
                return;
 
-       DEBUG(3, "to = %lu from = %p len = %u", to, from, len);
+       DEBUG(3, "to = %lu from = %p len = %zd", to, from, len);
        memcpy_toio(win_base + to, from, len);
 }
 
@@ -375,7 +378,8 @@ static int pcmciamtd_cistpl_jedec(struct pcmcia_device *p_dev,
        if (!pcmcia_parse_tuple(tuple, &parse)) {
                cistpl_jedec_t *t = &parse.jedec;
                for (i = 0; i < t->nid; i++)
-                       DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info);
+                       DEBUG(2, "JEDEC: 0x%02x 0x%02x",
+                             t->id[i].mfr, t->id[i].info);
        }
        return -ENOSPC;
 }
@@ -431,7 +435,7 @@ static int pcmciamtd_cistpl_geo(struct pcmcia_device *p_dev,
 }
 
 
-static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name)
+static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *p_dev, int *new_name)
 {
        int i;
 
@@ -476,7 +480,8 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link,
        }
 
        DEBUG(1, "Device: Size: %lu Width:%d Name: %s",
-             dev->pcmcia_map.size, dev->pcmcia_map.bankwidth << 3, dev->mtd_name);
+             dev->pcmcia_map.size,
+             dev->pcmcia_map.bankwidth << 3, dev->mtd_name);
 }
 
 
@@ -489,7 +494,6 @@ static int pcmciamtd_config(struct pcmcia_device *link)
 {
        struct pcmciamtd_dev *dev = link->priv;
        struct mtd_info *mtd = NULL;
-       cs_status_t status;
        win_req_t req;
        int ret;
        int i;
@@ -513,9 +517,11 @@ static int pcmciamtd_config(struct pcmcia_device *link)
        if(setvpp == 1)
                dev->pcmcia_map.set_vpp = pcmciamtd_set_vpp;
 
-       /* Request a memory window for PCMCIA. Some architeures can map windows upto the maximum
-          that PCMCIA can support (64MiB) - this is ideal and we aim for a window the size of the
-          whole card - otherwise we try smaller windows until we succeed */
+       /* Request a memory window for PCMCIA. Some architeures can map windows
+        * upto the maximum that PCMCIA can support (64MiB) - this is ideal and
+        * we aim for a window the size of the whole card - otherwise we try
+        * 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;
@@ -543,7 +549,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
        DEBUG(2, "dev->win_size = %d", dev->win_size);
 
        if(!dev->win_size) {
-               err("Cant allocate memory window");
+               dev_err(&dev->p_dev->dev, "Cannot allocate memory window\n");
                pcmciamtd_release(link);
                return -ENODEV;
        }
@@ -553,7 +559,8 @@ static int pcmciamtd_config(struct pcmcia_device *link)
        DEBUG(2, "window handle = 0x%8.8lx", (unsigned long)link->win);
        dev->win_base = ioremap(req.Base, req.Size);
        if(!dev->win_base) {
-               err("ioremap(%lu, %u) failed", req.Base, req.Size);
+               dev_err(&dev->p_dev->dev, "ioremap(%lu, %u) failed\n",
+                       req.Base, req.Size);
                pcmciamtd_release(link);
                return -ENODEV;
        }
@@ -564,7 +571,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
        dev->pcmcia_map.map_priv_1 = (unsigned long)dev;
        dev->pcmcia_map.map_priv_2 = (unsigned long)link->win;
 
-       dev->vpp = (vpp) ? vpp : link->socket.socket.Vpp;
+       dev->vpp = (vpp) ? vpp : link->socket->socket.Vpp;
        link->conf.Attributes = 0;
        if(setvpp == 2) {
                link->conf.Vpp = dev->vpp;
@@ -600,7 +607,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
        }
 
        if(!mtd) {
-               DEBUG(1, "Cant find an MTD");
+               DEBUG(1, "Can not find an MTD");
                pcmciamtd_release(link);
                return -ENODEV;
        }
@@ -611,8 +618,9 @@ static int pcmciamtd_config(struct pcmcia_device *link)
        if(new_name) {
                int size = 0;
                char unit = ' ';
-               /* Since we are using a default name, make it better by adding in the
-                  size */
+               /* Since we are using a default name, make it better by adding
+                * in the size
+                */
                if(mtd->size < 1048576) { /* <1MiB in size, show size in KiB */
                        size = mtd->size >> 10;
                        unit = 'K';
@@ -642,15 +650,15 @@ static int pcmciamtd_config(struct pcmcia_device *link)
        if(add_mtd_device(mtd)) {
                map_destroy(mtd);
                dev->mtd_info = NULL;
-               err("Couldnt register MTD device");
+               dev_err(&dev->p_dev->dev,
+                       "Could not register the MTD device\n");
                pcmciamtd_release(link);
                return -ENODEV;
        }
-       info("mtd%d: %s", mtd->index, mtd->name);
+       dev_info(&dev->p_dev->dev, "mtd%d: %s\n", mtd->index, mtd->name);
        return 0;
 
- failed:
-       err("CS Error, exiting");
+       dev_err(&dev->p_dev->dev, "CS Error, exiting\n");
        pcmciamtd_release(link);
        return -ENODEV;
 }
@@ -689,8 +697,9 @@ static void pcmciamtd_detach(struct pcmcia_device *link)
 
        if(dev->mtd_info) {
                del_mtd_device(dev->mtd_info);
+               dev_info(&dev->p_dev->dev, "mtd%d: Removing\n",
+                        dev->mtd_info->index);
                map_destroy(dev->mtd_info);
-               info("mtd%d: Removed", dev->mtd_info->index);
        }
 
        pcmciamtd_release(link);
@@ -734,8 +743,11 @@ static struct pcmcia_device_id pcmciamtd_ids[] = {
        PCMCIA_DEVICE_PROD_ID12("intel", "VALUE SERIES 100 ", 0x40ade711, 0xdf8506d8),
        PCMCIA_DEVICE_PROD_ID12("KINGMAX TECHNOLOGY INC.", "SRAM 256K Bytes", 0x54d0c69c, 0xad12c29c),
        PCMCIA_DEVICE_PROD_ID12("Maxtor", "MAXFL MobileMax Flash Memory Card", 0xb68968c8, 0x2dfb47b0),
+       PCMCIA_DEVICE_PROD_ID123("M-Systems", "M-SYS Flash Memory Card", "(c) M-Systems", 0x7ed2ad87, 0x675dc3fb, 0x7aef3965),
+       PCMCIA_DEVICE_PROD_ID12("PRETEC", "  2MB SRAM CARD", 0xebf91155, 0x805360ca),
        PCMCIA_DEVICE_PROD_ID12("SEIKO EPSON", "WWB101EN20", 0xf9876baf, 0xad0b207b),
        PCMCIA_DEVICE_PROD_ID12("SEIKO EPSON", "WWB513EN20", 0xf9876baf, 0xe8d884ad),
+       PCMCIA_DEVICE_PROD_ID12("SMART Modular Technologies", " 4MB FLASH Card", 0x96fd8277, 0x737a5b05),
        PCMCIA_DEVICE_PROD_ID12("Starfish, Inc.", "REX-3000", 0x05ddca47, 0xe7d67bca),
        PCMCIA_DEVICE_PROD_ID12("Starfish, Inc.", "REX-4100", 0x05ddca47, 0x7bc32944),
        /* the following was commented out in pcmcia-cs-3.2.7 */
index d9603f7..426461a 100644 (file)
@@ -264,8 +264,11 @@ static int __init physmap_init(void)
 
        err = platform_driver_register(&physmap_flash_driver);
 #ifdef CONFIG_MTD_PHYSMAP_COMPAT
-       if (err == 0)
-               platform_device_register(&physmap_flash);
+       if (err == 0) {
+               err = platform_device_register(&physmap_flash);
+               if (err)
+                       platform_driver_unregister(&physmap_flash_driver);
+       }
 #endif
 
        return err;
index 101ee6e..36dbcee 100644 (file)
@@ -173,12 +173,53 @@ static struct mtd_info * __devinit obsolete_probe(struct of_device *dev,
        }
 }
 
+#ifdef CONFIG_MTD_PARTITIONS
+/* When partitions are set we look for a linux,part-probe property which
+   specifies the list of partition probers to use. If none is given then the
+   default is use. These take precedence over other device tree
+   information. */
+static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot", NULL };
+static const char ** __devinit of_get_probes(struct device_node *dp)
+{
+       const char *cp;
+       int cplen;
+       unsigned int l;
+       unsigned int count;
+       const char **res;
+
+       cp = of_get_property(dp, "linux,part-probe", &cplen);
+       if (cp == NULL)
+               return part_probe_types_def;
+
+       count = 0;
+       for (l = 0; l != cplen; l++)
+               if (cp[l] == 0)
+                       count++;
+
+       res = kzalloc((count + 1)*sizeof(*res), GFP_KERNEL);
+       count = 0;
+       while (cplen > 0) {
+               res[count] = cp;
+               l = strlen(cp) + 1;
+               cp += l;
+               cplen -= l;
+               count++;
+       }
+       return res;
+}
+
+static void __devinit of_free_probes(const char **probes)
+{
+       if (probes != part_probe_types_def)
+               kfree(probes);
+}
+#endif
+
 static int __devinit of_flash_probe(struct of_device *dev,
                                    const struct of_device_id *match)
 {
 #ifdef CONFIG_MTD_PARTITIONS
-       static const char *part_probe_types[]
-               = { "cmdlinepart", "RedBoot", NULL };
+       const char **part_probe_types;
 #endif
        struct device_node *dp = dev->node;
        struct resource res;
@@ -218,7 +259,7 @@ static int __devinit of_flash_probe(struct of_device *dev,
 
        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;
 
@@ -307,12 +348,14 @@ static int __devinit of_flash_probe(struct of_device *dev,
                goto err_out;
 
 #ifdef CONFIG_MTD_PARTITIONS
-       /* First look for RedBoot table or partitions on the command
-        * line, these take precedence over device tree information */
+       part_probe_types = of_get_probes(dp);
        err = parse_mtd_partitions(info->cmtd, part_probe_types,
                                   &info->parts, 0);
-       if (err < 0)
+       if (err < 0) {
+               of_free_probes(part_probe_types);
                return err;
+       }
+       of_free_probes(part_probe_types);
 
 #ifdef CONFIG_MTD_OF_PARTS
        if (err == 0) {
index 60c068d..eb476b7 100644 (file)
@@ -234,6 +234,7 @@ static int __devexit pismo_remove(struct i2c_client *client)
        /* FIXME: set_vpp needs saner arguments */
        pismo_setvpp_remove_fix(pismo);
 
+       i2c_set_clientdata(client, NULL);
        kfree(pismo);
 
        return 0;
@@ -272,7 +273,7 @@ static int __devinit pismo_probe(struct i2c_client *client,
        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);
@@ -283,6 +284,11 @@ static int __devinit pismo_probe(struct i2c_client *client,
                                      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[] = {
index 91dc633..dd90880 100644 (file)
@@ -63,11 +63,10 @@ static int __init pxa2xx_flash_probe(struct platform_device *pdev)
        if (!res)
                return -ENODEV;
 
-       info = kmalloc(sizeof(struct pxa2xx_flash_info), GFP_KERNEL);
+       info = kzalloc(sizeof(struct pxa2xx_flash_info), GFP_KERNEL);
        if (!info)
                return -ENOMEM;
 
-       memset(info, 0, sizeof(struct pxa2xx_flash_info));
        info->map.name = (char *) flash->name;
        info->map.bankwidth = flash->width;
        info->map.phys = res->start;
index c82e09b..03e19c1 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/blkdev.h>
 #include <linux/blkpg.h>
-#include <linux/freezer.h>
 #include <linux/spinlock.h>
 #include <linux/hdreg.h>
 #include <linux/init.h>
 #include "mtdcore.h"
 
 static LIST_HEAD(blktrans_majors);
+static DEFINE_MUTEX(blktrans_ref_mutex);
+
+void blktrans_dev_release(struct kref *kref)
+{
+       struct mtd_blktrans_dev *dev =
+               container_of(kref, struct mtd_blktrans_dev, ref);
+
+       dev->disk->private_data = NULL;
+       blk_cleanup_queue(dev->rq);
+       put_disk(dev->disk);
+       list_del(&dev->list);
+       kfree(dev);
+}
+
+static struct mtd_blktrans_dev *blktrans_dev_get(struct gendisk *disk)
+{
+       struct mtd_blktrans_dev *dev;
+
+       mutex_lock(&blktrans_ref_mutex);
+       dev = disk->private_data;
+
+       if (!dev)
+               goto unlock;
+       kref_get(&dev->ref);
+unlock:
+       mutex_unlock(&blktrans_ref_mutex);
+       return dev;
+}
+
+void blktrans_dev_put(struct mtd_blktrans_dev *dev)
+{
+       mutex_lock(&blktrans_ref_mutex);
+       kref_put(&dev->ref, blktrans_dev_release);
+       mutex_unlock(&blktrans_ref_mutex);
+}
 
-struct mtd_blkcore_priv {
-       struct task_struct *thread;
-       struct request_queue *rq;
-       spinlock_t queue_lock;
-};
 
 static int do_blktrans_request(struct mtd_blktrans_ops *tr,
                               struct mtd_blktrans_dev *dev,
@@ -61,7 +90,6 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
                                return -EIO;
                rq_flush_dcache_pages(req);
                return 0;
-
        case WRITE:
                if (!tr->writesect)
                        return -EIO;
@@ -71,7 +99,6 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
                        if (tr->writesect(dev, block, buf))
                                return -EIO;
                return 0;
-
        default:
                printk(KERN_NOTICE "Unknown request %u\n", rq_data_dir(req));
                return -EIO;
@@ -80,14 +107,13 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
 
 static int mtd_blktrans_thread(void *arg)
 {
-       struct mtd_blktrans_ops *tr = arg;
-       struct request_queue *rq = tr->blkcore_priv->rq;
+       struct mtd_blktrans_dev *dev = arg;
+       struct request_queue *rq = dev->rq;
        struct request *req = NULL;
 
        spin_lock_irq(rq->queue_lock);
 
        while (!kthread_should_stop()) {
-               struct mtd_blktrans_dev *dev;
                int res;
 
                if (!req && !(req = blk_fetch_request(rq))) {
@@ -98,13 +124,10 @@ static int mtd_blktrans_thread(void *arg)
                        continue;
                }
 
-               dev = req->rq_disk->private_data;
-               tr = dev->tr;
-
                spin_unlock_irq(rq->queue_lock);
 
                mutex_lock(&dev->lock);
-               res = do_blktrans_request(tr, dev, req);
+               res = do_blktrans_request(dev->tr, dev, req);
                mutex_unlock(&dev->lock);
 
                spin_lock_irq(rq->queue_lock);
@@ -123,81 +146,112 @@ static int mtd_blktrans_thread(void *arg)
 
 static void mtd_blktrans_request(struct request_queue *rq)
 {
-       struct mtd_blktrans_ops *tr = rq->queuedata;
-       wake_up_process(tr->blkcore_priv->thread);
-}
+       struct mtd_blktrans_dev *dev;
+       struct request *req = NULL;
+
+       dev = rq->queuedata;
 
+       if (!dev)
+               while ((req = blk_fetch_request(rq)) != NULL)
+                       __blk_end_request_all(req, -ENODEV);
+       else
+               wake_up_process(dev->thread);
+}
 
 static int blktrans_open(struct block_device *bdev, fmode_t mode)
 {
-       struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data;
-       struct mtd_blktrans_ops *tr = dev->tr;
-       int ret = -ENODEV;
-
-       if (!get_mtd_device(NULL, dev->mtd->index))
-               goto out;
-
-       if (!try_module_get(tr->owner))
-               goto out_tr;
-
-       /* FIXME: Locking. A hot pluggable device can go away
-          (del_mtd_device can be called for it) without its module
-          being unloaded. */
-       dev->mtd->usecount++;
-
-       ret = 0;
-       if (tr->open && (ret = tr->open(dev))) {
-               dev->mtd->usecount--;
-               put_mtd_device(dev->mtd);
-       out_tr:
-               module_put(tr->owner);
+       struct mtd_blktrans_dev *dev = blktrans_dev_get(bdev->bd_disk);
+       int ret;
+
+       if (!dev)
+               return -ERESTARTSYS;
+
+       mutex_lock(&dev->lock);
+
+       if (!dev->mtd) {
+               ret = -ENXIO;
+               goto unlock;
        }
- out:
+
+       ret = !dev->open++ && dev->tr->open ? dev->tr->open(dev) : 0;
+
+       /* 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);
        return ret;
 }
 
 static int blktrans_release(struct gendisk *disk, fmode_t mode)
 {
-       struct mtd_blktrans_dev *dev = disk->private_data;
-       struct mtd_blktrans_ops *tr = dev->tr;
-       int ret = 0;
+       struct mtd_blktrans_dev *dev = blktrans_dev_get(disk);
+       int ret = -ENXIO;
 
-       if (tr->release)
-               ret = tr->release(dev);
+       if (!dev)
+               return ret;
 
-       if (!ret) {
-               dev->mtd->usecount--;
-               put_mtd_device(dev->mtd);
-               module_put(tr->owner);
-       }
+       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)
+               goto unlock;
+
+       ret = !--dev->open && dev->tr->release ? dev->tr->release(dev) : 0;
+unlock:
+       mutex_unlock(&dev->lock);
+       blktrans_dev_put(dev);
        return ret;
 }
 
 static int blktrans_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
-       struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data;
+       struct mtd_blktrans_dev *dev = blktrans_dev_get(bdev->bd_disk);
+       int ret = -ENXIO;
+
+       if (!dev)
+               return ret;
+
+       mutex_lock(&dev->lock);
+
+       if (!dev->mtd)
+               goto unlock;
 
-       if (dev->tr->getgeo)
-               return dev->tr->getgeo(dev, geo);
-       return -ENOTTY;
+       ret = dev->tr->getgeo ? dev->tr->getgeo(dev, geo) : 0;
+unlock:
+       mutex_unlock(&dev->lock);
+       blktrans_dev_put(dev);
+       return ret;
 }
 
 static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
                              unsigned int cmd, unsigned long arg)
 {
-       struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data;
-       struct mtd_blktrans_ops *tr = dev->tr;
+       struct mtd_blktrans_dev *dev = blktrans_dev_get(bdev->bd_disk);
+       int ret = -ENXIO;
+
+       if (!dev)
+               return ret;
+
+       mutex_lock(&dev->lock);
+
+       if (!dev->mtd)
+               goto unlock;
 
        switch (cmd) {
        case BLKFLSBUF:
-               if (tr->flush)
-                       return tr->flush(dev);
-               /* The core code did the work, we had nothing to do. */
-               return 0;
+               ret = dev->tr->flush ? dev->tr->flush(dev) : 0;
        default:
-               return -ENOTTY;
+               ret = -ENOTTY;
        }
+unlock:
+       mutex_unlock(&dev->lock);
+       blktrans_dev_put(dev);
+       return ret;
 }
 
 static const struct block_device_operations mtd_blktrans_ops = {
@@ -214,12 +268,14 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
        struct mtd_blktrans_dev *d;
        int last_devnum = -1;
        struct gendisk *gd;
+       int ret;
 
        if (mutex_trylock(&mtd_table_mutex)) {
                mutex_unlock(&mtd_table_mutex);
                BUG();
        }
 
+       mutex_lock(&blktrans_ref_mutex);
        list_for_each_entry(d, &tr->devs, list) {
                if (new->devnum == -1) {
                        /* Use first free number */
@@ -231,6 +287,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
                        }
                } else if (d->devnum == new->devnum) {
                        /* Required number taken */
+                       mutex_unlock(&blktrans_ref_mutex);
                        return -EBUSY;
                } else if (d->devnum > new->devnum) {
                        /* Required number was free */
@@ -239,24 +296,38 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
                }
                last_devnum = d->devnum;
        }
+
+       ret = -EBUSY;
        if (new->devnum == -1)
                new->devnum = last_devnum+1;
 
-       if ((new->devnum << tr->part_bits) > 256) {
-               return -EBUSY;
+       /* Check that the device and any partitions will get valid
+        * minor numbers and that the disk naming code below can cope
+        * with this number. */
+       if (new->devnum > (MINORMASK >> tr->part_bits) ||
+           (tr->part_bits && new->devnum >= 27 * 26)) {
+               mutex_unlock(&blktrans_ref_mutex);
+               goto error1;
        }
 
        list_add_tail(&new->list, &tr->devs);
  added:
+       mutex_unlock(&blktrans_ref_mutex);
+
        mutex_init(&new->lock);
+       kref_init(&new->ref);
        if (!tr->writesect)
                new->readonly = 1;
 
+       /* Create gendisk */
+       ret = -ENOMEM;
        gd = alloc_disk(1 << tr->part_bits);
-       if (!gd) {
-               list_del(&new->list);
-               return -ENOMEM;
-       }
+
+       if (!gd)
+               goto error2;
+
+       new->disk = gd;
+       gd->private_data = new;
        gd->major = tr->major;
        gd->first_minor = (new->devnum) << tr->part_bits;
        gd->fops = &mtd_blktrans_ops;
@@ -274,13 +345,35 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
                snprintf(gd->disk_name, sizeof(gd->disk_name),
                         "%s%d", tr->name, new->devnum);
 
-       /* 2.5 has capacity in units of 512 bytes while still
-          having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */
        set_capacity(gd, (new->size * tr->blksize) >> 9);
 
-       gd->private_data = new;
-       new->blkcore_priv = gd;
-       gd->queue = tr->blkcore_priv->rq;
+       /* Create the request queue */
+       spin_lock_init(&new->queue_lock);
+       new->rq = blk_init_queue(mtd_blktrans_request, &new->queue_lock);
+
+       if (!new->rq)
+               goto error3;
+
+       new->rq->queuedata = new;
+       blk_queue_logical_block_size(new->rq, tr->blksize);
+
+       if (tr->discard)
+               queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
+                                       new->rq);
+
+       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,
+                       "%s%d", tr->name, new->mtd->index);
+       if (IS_ERR(new->thread)) {
+               ret = PTR_ERR(new->thread);
+               goto error4;
+       }
        gd->driverfs_dev = &new->mtd->dev;
 
        if (new->readonly)
@@ -288,21 +381,65 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 
        add_disk(gd);
 
+       if (new->disk_attributes) {
+               ret = sysfs_create_group(&disk_to_dev(gd)->kobj,
+                                       new->disk_attributes);
+               WARN_ON(ret);
+       }
        return 0;
+error4:
+       module_put(tr->owner);
+       __put_mtd_device(new->mtd);
+       blk_cleanup_queue(new->rq);
+error3:
+       put_disk(new->disk);
+error2:
+       list_del(&new->list);
+error1:
+       kfree(new);
+       return ret;
 }
 
 int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
 {
+       unsigned long flags;
+
        if (mutex_trylock(&mtd_table_mutex)) {
                mutex_unlock(&mtd_table_mutex);
                BUG();
        }
 
-       list_del(&old->list);
+       /* Stop new requests to arrive */
+       del_gendisk(old->disk);
+
+       if (old->disk_attributes)
+               sysfs_remove_group(&disk_to_dev(old->disk)->kobj,
+                                               old->disk_attributes);
+
+       /* Stop the thread */
+       kthread_stop(old->thread);
+
+       /* Kill current requests */
+       spin_lock_irqsave(&old->queue_lock, flags);
+       old->rq->queuedata = NULL;
+       blk_start_queue(old->rq);
+       spin_unlock_irqrestore(&old->queue_lock, flags);
+
+       /* Ask trans driver for release to the mtd device */
+       mutex_lock(&old->lock);
+       if (old->open && old->tr->release) {
+               old->tr->release(old);
+               old->open = 0;
+       }
+
+       __put_mtd_device(old->mtd);
+       module_put(old->tr->owner);
 
-       del_gendisk(old->blkcore_priv);
-       put_disk(old->blkcore_priv);
+       /* At that point, we don't touch the mtd anymore */
+       old->mtd = NULL;
 
+       mutex_unlock(&old->lock);
+       blktrans_dev_put(old);
        return 0;
 }
 
@@ -335,7 +472,8 @@ static struct mtd_notifier blktrans_notifier = {
 
 int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
 {
-       int ret, i;
+       struct mtd_info *mtd;
+       int ret;
 
        /* Register the notifier if/when the first device type is
           registered, to prevent the link/init ordering from fucking
@@ -343,9 +481,6 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
        if (!blktrans_notifier.list.next)
                register_mtd_user(&blktrans_notifier);
 
-       tr->blkcore_priv = kzalloc(sizeof(*tr->blkcore_priv), GFP_KERNEL);
-       if (!tr->blkcore_priv)
-               return -ENOMEM;
 
        mutex_lock(&mtd_table_mutex);
 
@@ -353,49 +488,20 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
        if (ret) {
                printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n",
                       tr->name, tr->major, ret);
-               kfree(tr->blkcore_priv);
                mutex_unlock(&mtd_table_mutex);
                return ret;
        }
-       spin_lock_init(&tr->blkcore_priv->queue_lock);
-
-       tr->blkcore_priv->rq = blk_init_queue(mtd_blktrans_request, &tr->blkcore_priv->queue_lock);
-       if (!tr->blkcore_priv->rq) {
-               unregister_blkdev(tr->major, tr->name);
-               kfree(tr->blkcore_priv);
-               mutex_unlock(&mtd_table_mutex);
-               return -ENOMEM;
-       }
-
-       tr->blkcore_priv->rq->queuedata = tr;
-       blk_queue_logical_block_size(tr->blkcore_priv->rq, tr->blksize);
-       if (tr->discard)
-               queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
-                                       tr->blkcore_priv->rq);
 
        tr->blkshift = ffs(tr->blksize) - 1;
 
-       tr->blkcore_priv->thread = kthread_run(mtd_blktrans_thread, tr,
-                       "%sd", tr->name);
-       if (IS_ERR(tr->blkcore_priv->thread)) {
-               ret = PTR_ERR(tr->blkcore_priv->thread);
-               blk_cleanup_queue(tr->blkcore_priv->rq);
-               unregister_blkdev(tr->major, tr->name);
-               kfree(tr->blkcore_priv);
-               mutex_unlock(&mtd_table_mutex);
-               return ret;
-       }
-
        INIT_LIST_HEAD(&tr->devs);
        list_add(&tr->list, &blktrans_majors);
 
-       for (i=0; i<MAX_MTD_DEVICES; i++) {
-               if (mtd_table[i] && mtd_table[i]->type != MTD_ABSENT)
-                       tr->add_mtd(tr, mtd_table[i]);
-       }
+       mtd_for_each_device(mtd)
+               if (mtd->type != MTD_ABSENT)
+                       tr->add_mtd(tr, mtd);
 
        mutex_unlock(&mtd_table_mutex);
-
        return 0;
 }
 
@@ -405,22 +511,15 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
 
        mutex_lock(&mtd_table_mutex);
 
-       /* Clean up the kernel thread */
-       kthread_stop(tr->blkcore_priv->thread);
-
        /* Remove it from the list of active majors */
        list_del(&tr->list);
 
        list_for_each_entry_safe(dev, next, &tr->devs, list)
                tr->remove_dev(dev);
 
-       b