Merge tag 'for-linus-20130509' of git://git.infradead.org/linux-mtd
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 9 May 2013 17:15:46 +0000 (10:15 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 9 May 2013 17:15:46 +0000 (10:15 -0700)
Pull MTD update from David Woodhouse:

 - Lots of cleanups from Artem, including deletion of some obsolete
   drivers

 - Support partitions larger than 4GiB in device tree

 - Support for new SPI chips

* tag 'for-linus-20130509' of git://git.infradead.org/linux-mtd: (83 commits)
  mtd: omap2: Use module_platform_driver()
  mtd: bf5xx_nand: Use module_platform_driver()
  mtd: denali_dt: Remove redundant use of of_match_ptr
  mtd: denali_dt: Change return value to fix smatch warning
  mtd: denali_dt: Use module_platform_driver()
  mtd: denali_dt: Fix incorrect error check
  mtd: nand: subpage write support for hardware based ECC schemes
  mtd: omap2: use msecs_to_jiffies()
  mtd: nand_ids: use size macros
  mtd: nand_ids: improve LEGACY_ID_NAND macro a bit
  mtd: add 4 Toshiba nand chips for the full-id case
  mtd: add the support to parse out the full-id nand type
  mtd: add new fields to nand_flash_dev{}
  mtd: sh_flctl: Use of_match_ptr() macro
  mtd: gpio: Use of_match_ptr() macro
  mtd: gpio: Use devm_kzalloc()
  mtd: davinci_nand: Use of_match_ptr()
  mtd: dataflash: Use of_match_ptr() macro
  mtd: remove h720x flash support
  mtd: onenand: remove OneNAND simulator
  ...

89 files changed:
Documentation/ABI/testing/sysfs-class-mtd
Documentation/devicetree/bindings/mtd/partition.txt
arch/arm/mach-pxa/Kconfig
arch/cris/Kconfig
arch/cris/arch-v32/drivers/Kconfig
drivers/bcma/driver_mips.c
drivers/mtd/Kconfig
drivers/mtd/Makefile
drivers/mtd/chips/Kconfig
drivers/mtd/devices/Kconfig
drivers/mtd/devices/Makefile
drivers/mtd/devices/bcm47xxsflash.c
drivers/mtd/devices/bcm47xxsflash.h
drivers/mtd/devices/doc2000.c [deleted file]
drivers/mtd/devices/doc2001.c [deleted file]
drivers/mtd/devices/doc2001plus.c [deleted file]
drivers/mtd/devices/docecc.c [deleted file]
drivers/mtd/devices/docg3.c
drivers/mtd/devices/docprobe.c [deleted file]
drivers/mtd/devices/elm.c
drivers/mtd/devices/m25p80.c
drivers/mtd/devices/mtd_dataflash.c
drivers/mtd/maps/Kconfig
drivers/mtd/maps/Makefile
drivers/mtd/maps/bfin-async-flash.c
drivers/mtd/maps/ck804xrom.c
drivers/mtd/maps/dbox2-flash.c [deleted file]
drivers/mtd/maps/dc21285.c
drivers/mtd/maps/dilnetpc.c [deleted file]
drivers/mtd/maps/dmv182.c [deleted file]
drivers/mtd/maps/gpio-addr-flash.c
drivers/mtd/maps/h720x-flash.c [deleted file]
drivers/mtd/maps/impa7.c
drivers/mtd/maps/intel_vr_nor.c
drivers/mtd/maps/ixp2000.c [deleted file]
drivers/mtd/maps/ixp4xx.c
drivers/mtd/maps/lantiq-flash.c
drivers/mtd/maps/mbx860.c [deleted file]
drivers/mtd/maps/pci.c
drivers/mtd/maps/physmap.c
drivers/mtd/maps/physmap_of.c
drivers/mtd/maps/plat-ram.c
drivers/mtd/maps/pxa2xx-flash.c
drivers/mtd/maps/rbtx4939-flash.c
drivers/mtd/maps/rpxlite.c [deleted file]
drivers/mtd/maps/sa1100-flash.c
drivers/mtd/maps/solutionengine.c
drivers/mtd/maps/tqm8xxl.c [deleted file]
drivers/mtd/maps/tsunami_flash.c
drivers/mtd/mtdchar.c
drivers/mtd/mtdcore.c
drivers/mtd/mtdcore.h
drivers/mtd/mtdpart.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/Makefile
drivers/mtd/nand/atmel_nand.c
drivers/mtd/nand/bf5xx_nand.c
drivers/mtd/nand/cafe_nand.c
drivers/mtd/nand/davinci_nand.c
drivers/mtd/nand/denali_dt.c
drivers/mtd/nand/docg4.c
drivers/mtd/nand/fsmc_nand.c
drivers/mtd/nand/gpio.c
drivers/mtd/nand/h1910.c [deleted file]
drivers/mtd/nand/lpc32xx_mlc.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_bbt.c
drivers/mtd/nand/nand_ids.c
drivers/mtd/nand/nandsim.c
drivers/mtd/nand/nuc900_nand.c
drivers/mtd/nand/omap2.c
drivers/mtd/nand/orion_nand.c
drivers/mtd/nand/ppchameleonevb.c [deleted file]
drivers/mtd/nand/pxa3xx_nand.c
drivers/mtd/nand/rtc_from4.c [deleted file]
drivers/mtd/nand/sh_flctl.c
drivers/mtd/nand/sm_common.c
drivers/mtd/nand/txx9ndfmc.c
drivers/mtd/ofpart.c
drivers/mtd/onenand/Kconfig
drivers/mtd/onenand/Makefile
drivers/mtd/onenand/omap2.c
drivers/mtd/onenand/onenand_sim.c [deleted file]
drivers/ssb/driver_mipscore.c
include/linux/mtd/mtd.h
include/linux/mtd/nand.h
include/linux/mtd/physmap.h
include/linux/mtd/plat-ram.h
include/linux/platform_data/elm.h

index 938ef71e2035e7c04203c7b65d2a120dbd96944a..3105644b3bfc45f27371765246f6d1deda46549b 100644 (file)
@@ -14,8 +14,7 @@ Description:
                The /sys/class/mtd/mtd{0,1,2,3,...} directories correspond
                to each /dev/mtdX character device.  These may represent
                physical/simulated flash devices, partitions on a flash
-               device, or concatenated flash devices.  They exist regardless
-               of whether CONFIG_MTD_CHAR is actually enabled.
+               device, or concatenated flash devices.
 
 What:          /sys/class/mtd/mtdXro/
 Date:          April 2009
@@ -23,8 +22,7 @@ KernelVersion:        2.6.29
 Contact:       linux-mtd@lists.infradead.org
 Description:
                These directories provide the corresponding read-only device
-               nodes for /sys/class/mtd/mtdX/ .  They are only created
-               (for the benefit of udev) if CONFIG_MTD_CHAR is enabled.
+               nodes for /sys/class/mtd/mtdX/ .
 
 What:          /sys/class/mtd/mtdX/dev
 Date:          April 2009
index 6e1f61f1e789699082d7eef9d893a03280f2c039..9315ac96b49b224665b674f1d0109805aaf0c9a8 100644 (file)
@@ -5,8 +5,12 @@ on platforms which have strong conventions about which portions of a flash are
 used for what purposes, but which don't use an on-flash partition table such
 as RedBoot.
 
-#address-cells & #size-cells must both be present in the mtd device and be
-equal to 1.
+#address-cells & #size-cells must both be present in the mtd device. There are
+two valid values for both:
+<1>: for partitions that require a single 32-bit cell to represent their
+     size/address (aka the value is below 4 GiB)
+<2>: for partitions that require two 32-bit cells to represent their
+     size/address (aka the value is 4 GiB or greater).
 
 Required properties:
 - reg : The partition's offset and size within the mtd bank.
@@ -36,3 +40,31 @@ flash@0 {
                reg = <0x0100000 0x200000>;
        };
 };
+
+flash@1 {
+       #address-cells = <1>;
+       #size-cells = <2>;
+
+       /* a 4 GiB partition */
+       partition@0 {
+               label = "filesystem";
+               reg = <0x00000000 0x1 0x00000000>;
+       };
+};
+
+flash@2 {
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       /* an 8 GiB partition */
+       partition@0 {
+               label = "filesystem #1";
+               reg = <0x0 0x00000000 0x2 0x00000000>;
+       };
+
+       /* a 4 GiB partition */
+       partition@200000000 {
+               label = "filesystem #2";
+               reg = <0x2 0x00000000 0x1 0x00000000>;
+       };
+};
index 9075461999c11d31d67af317e3de806666ba987f..96100dbf5a2e8353e9fad34ded41ec5e83dda7ad 100644 (file)
@@ -162,7 +162,6 @@ config MACH_XCEP
        select MTD
        select MTD_CFI
        select MTD_CFI_INTELEXT
-       select MTD_CHAR
        select MTD_PHYSMAP
        select PXA25x
        select SMC91X
index 06dd026533e3b758b68091bc0a8c754b3084f0da..8769a9045a543995c137f02f9bfc92bf3ce0da36 100644 (file)
@@ -264,7 +264,6 @@ config ETRAX_AXISFLASHMAP
        select MTD_CFI
        select MTD_CFI_AMDSTD
        select MTD_JEDECPROBE if ETRAX_ARCH_V32
-       select MTD_CHAR
        select MTD_BLOCK
        select MTD_COMPLEX_MAPPINGS
        help
index af4a486dadcd8437ba7160b1852664a04888cedb..c55971a40c34e8433faa9fc70d12566feed21045 100644 (file)
@@ -404,7 +404,6 @@ config ETRAX_AXISFLASHMAP
        select MTD_CFI
        select MTD_CFI_AMDSTD
        select MTD_JEDECPROBE
-       select MTD_CHAR
        select MTD_BLOCK
        select MTD_COMPLEX_MAPPINGS
        help
index 9a7f0e3ab5a33fbb012a5c2f74145cc47c346dcd..11115bbe115cb120c778b4818d1e14a05f2e012e 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/serial_reg.h>
 #include <linux/time.h>
 
-static const char *part_probes[] = { "bcm47xxpart", NULL };
+static const char * const part_probes[] = { "bcm47xxpart", NULL };
 
 static struct physmap_flash_data bcma_pflash_data = {
        .part_probe_types       = part_probes,
index 557bec599f4f6741255a3f6c16f6aff0c6d4585b..5fab4e6e83013c033c01d2465b4f25c756f39dce 100644 (file)
@@ -157,19 +157,6 @@ config MTD_BCM47XX_PARTS
 
 comment "User Modules And Translation Layers"
 
-config MTD_CHAR
-       tristate "Direct char device access to MTD devices"
-       help
-         This provides a character device for each MTD device present in
-         the system, allowing the user to read and write directly to the
-         memory chips, and also use ioctl() to obtain information about
-         the device, or to erase parts of it.
-
-config HAVE_MTD_OTP
-       bool
-       help
-         Enable access to OTP regions using MTD_CHAR.
-
 config MTD_BLKDEVS
        tristate "Common interface to block layer for MTD 'translation layers'"
        depends on BLOCK
index 18a38e55b2f0fec9cc3eb7466cf51568862e7d70..4cfb31e6c966ad37d1384d59ccd12d572961ea93 100644 (file)
@@ -4,7 +4,7 @@
 
 # Core functionality.
 obj-$(CONFIG_MTD)              += mtd.o
-mtd-y                          := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o
+mtd-y                          := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o mtdchar.o
 
 obj-$(CONFIG_MTD_OF_PARTS)     += ofpart.o
 obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
@@ -15,7 +15,6 @@ obj-$(CONFIG_MTD_BCM63XX_PARTS)       += bcm63xxpart.o
 obj-$(CONFIG_MTD_BCM47XX_PARTS)        += bcm47xxpart.o
 
 # 'Users' - code which presents functionality to userspace.
-obj-$(CONFIG_MTD_CHAR)         += mtdchar.o
 obj-$(CONFIG_MTD_BLKDEVS)      += mtd_blkdevs.o
 obj-$(CONFIG_MTD_BLOCK)                += mtdblock.o
 obj-$(CONFIG_MTD_BLOCK_RO)     += mtdblock_ro.o
index c219e3d098d9d1572584fed1613aa52f627e9014..e4696b37f3deca35ccca51be33c8ff3181606c58 100644 (file)
@@ -146,7 +146,6 @@ config MTD_CFI_I8
 config MTD_OTP
        bool "Protection Registers aka one-time programmable (OTP) bits"
        depends on MTD_CFI_ADV_OPTIONS
-       select HAVE_MTD_OTP
        default n
        help
          This enables support for reading, writing and locking so called
index 12311f506ca15385c8e325cfb511ccff28b3351a..2a4d55e4b3628b7437fb82d7d51a929c92cf79e2 100644 (file)
@@ -71,7 +71,6 @@ config MTD_DATAFLASH_WRITE_VERIFY
 config MTD_DATAFLASH_OTP
        bool "DataFlash OTP support (Security Register)"
        depends on MTD_DATAFLASH
-       select HAVE_MTD_OTP
        help
          Newer DataFlash chips (revisions C and D) support 128 bytes of
          one-time-programmable (OTP) data.  The first half may be written
@@ -205,69 +204,6 @@ config MTD_BLOCK2MTD
 
 comment "Disk-On-Chip Device Drivers"
 
-config MTD_DOC2000
-       tristate "M-Systems Disk-On-Chip 2000 and Millennium (DEPRECATED)"
-       depends on MTD_NAND
-       select MTD_DOCPROBE
-       select MTD_NAND_IDS
-       ---help---
-         This provides an MTD device driver for the M-Systems DiskOnChip
-         2000 and Millennium devices.  Originally designed for the DiskOnChip
-         2000, it also now includes support for the DiskOnChip Millennium.
-         If you have problems with this driver and the DiskOnChip Millennium,
-         you may wish to try the alternative Millennium driver below. To use
-         the alternative driver, you will need to undefine DOC_SINGLE_DRIVER
-         in the <file:drivers/mtd/devices/docprobe.c> source code.
-
-         If you use this device, you probably also want to enable the NFTL
-         'NAND Flash Translation Layer' option below, which is used to
-         emulate a block device by using a kind of file system on the flash
-         chips.
-
-         NOTE: This driver is deprecated and will probably be removed soon.
-         Please try the new DiskOnChip driver under "NAND Flash Device
-         Drivers".
-
-config MTD_DOC2001
-       tristate "M-Systems Disk-On-Chip Millennium-only alternative driver (DEPRECATED)"
-       depends on MTD_NAND
-       select MTD_DOCPROBE
-       select MTD_NAND_IDS
-       ---help---
-         This provides an alternative MTD device driver for the M-Systems
-         DiskOnChip Millennium devices.  Use this if you have problems with
-         the combined DiskOnChip 2000 and Millennium driver above.  To get
-         the DiskOnChip probe code to load and use this driver instead of
-         the other one, you will need to undefine DOC_SINGLE_DRIVER near
-         the beginning of <file:drivers/mtd/devices/docprobe.c>.
-
-         If you use this device, you probably also want to enable the NFTL
-         'NAND Flash Translation Layer' option below, which is used to
-         emulate a block device by using a kind of file system on the flash
-         chips.
-
-         NOTE: This driver is deprecated and will probably be removed soon.
-         Please try the new DiskOnChip driver under "NAND Flash Device
-         Drivers".
-
-config MTD_DOC2001PLUS
-       tristate "M-Systems Disk-On-Chip Millennium Plus"
-       depends on MTD_NAND
-       select MTD_DOCPROBE
-       select MTD_NAND_IDS
-       ---help---
-         This provides an MTD device driver for the M-Systems DiskOnChip
-         Millennium Plus devices.
-
-         If you use this device, you probably also want to enable the INFTL
-         'Inverse NAND Flash Translation Layer' option below, which is used
-         to emulate a block device by using a kind of file system on the
-         flash chips.
-
-         NOTE: This driver will soon be replaced by the new DiskOnChip driver
-         under "NAND Flash Device Drivers" (currently that driver does not
-         support all Millennium Plus devices).
-
 config MTD_DOCG3
        tristate "M-Systems Disk-On-Chip G3"
        select BCH
index 369a1943ca259e6106caafeb43f04a4ca1f862fb..d83bd73096f67d916525371a5f51a3dec933877f 100644 (file)
@@ -2,12 +2,7 @@
 # linux/drivers/mtd/devices/Makefile
 #
 
-obj-$(CONFIG_MTD_DOC2000)      += doc2000.o
-obj-$(CONFIG_MTD_DOC2001)      += doc2001.o
-obj-$(CONFIG_MTD_DOC2001PLUS)  += doc2001plus.o
 obj-$(CONFIG_MTD_DOCG3)                += docg3.o
-obj-$(CONFIG_MTD_DOCPROBE)     += docprobe.o
-obj-$(CONFIG_MTD_DOCECC)       += docecc.o
 obj-$(CONFIG_MTD_SLRAM)                += slram.o
 obj-$(CONFIG_MTD_PHRAM)                += phram.o
 obj-$(CONFIG_MTD_PMC551)       += pmc551.o
index 95266285acb16554fdfef090812cc6840b940d1a..18e7761137a33037a21aa61585e20d98f47b172e 100644 (file)
@@ -10,7 +10,7 @@
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Serial flash driver for BCMA bus");
 
-static const char *probes[] = { "bcm47xxpart", NULL };
+static const char * const probes[] = { "bcm47xxpart", NULL };
 
 static int bcm47xxsflash_read(struct mtd_info *mtd, loff_t from, size_t len,
                              size_t *retlen, u_char *buf)
@@ -61,6 +61,17 @@ static int bcm47xxsflash_bcma_probe(struct platform_device *pdev)
        }
        sflash->priv = b47s;
 
+       b47s->bcma_cc = container_of(sflash, struct bcma_drv_cc, sflash);
+
+       switch (b47s->bcma_cc->capabilities & BCMA_CC_CAP_FLASHT) {
+       case BCMA_CC_FLASHT_STSER:
+               b47s->type = BCM47XXSFLASH_TYPE_ST;
+               break;
+       case BCMA_CC_FLASHT_ATSER:
+               b47s->type = BCM47XXSFLASH_TYPE_ATMEL;
+               break;
+       }
+
        b47s->window = sflash->window;
        b47s->blocksize = sflash->blocksize;
        b47s->numblocks = sflash->numblocks;
index ebf6f710e23c0ada24b3de883db29acf0be6c7ec..f22f8c46dfc059566ae8cd4fcf4c90f810a7fd2a 100644 (file)
@@ -3,7 +3,66 @@
 
 #include <linux/mtd/mtd.h>
 
+/* Used for ST flashes only. */
+#define OPCODE_ST_WREN         0x0006          /* Write Enable */
+#define OPCODE_ST_WRDIS                0x0004          /* Write Disable */
+#define OPCODE_ST_RDSR         0x0105          /* Read Status Register */
+#define OPCODE_ST_WRSR         0x0101          /* Write Status Register */
+#define OPCODE_ST_READ         0x0303          /* Read Data Bytes */
+#define OPCODE_ST_PP           0x0302          /* Page Program */
+#define OPCODE_ST_SE           0x02d8          /* Sector Erase */
+#define OPCODE_ST_BE           0x00c7          /* Bulk Erase */
+#define OPCODE_ST_DP           0x00b9          /* Deep Power-down */
+#define OPCODE_ST_RES          0x03ab          /* Read Electronic Signature */
+#define OPCODE_ST_CSA          0x1000          /* Keep chip select asserted */
+#define OPCODE_ST_SSE          0x0220          /* Sub-sector Erase */
+
+/* Used for Atmel flashes only. */
+#define OPCODE_AT_READ                         0x07e8
+#define OPCODE_AT_PAGE_READ                    0x07d2
+#define OPCODE_AT_STATUS                       0x01d7
+#define OPCODE_AT_BUF1_WRITE                   0x0384
+#define OPCODE_AT_BUF2_WRITE                   0x0387
+#define OPCODE_AT_BUF1_ERASE_PROGRAM           0x0283
+#define OPCODE_AT_BUF2_ERASE_PROGRAM           0x0286
+#define OPCODE_AT_BUF1_PROGRAM                 0x0288
+#define OPCODE_AT_BUF2_PROGRAM                 0x0289
+#define OPCODE_AT_PAGE_ERASE                   0x0281
+#define OPCODE_AT_BLOCK_ERASE                  0x0250
+#define OPCODE_AT_BUF1_WRITE_ERASE_PROGRAM     0x0382
+#define OPCODE_AT_BUF2_WRITE_ERASE_PROGRAM     0x0385
+#define OPCODE_AT_BUF1_LOAD                    0x0253
+#define OPCODE_AT_BUF2_LOAD                    0x0255
+#define OPCODE_AT_BUF1_COMPARE                 0x0260
+#define OPCODE_AT_BUF2_COMPARE                 0x0261
+#define OPCODE_AT_BUF1_REPROGRAM               0x0258
+#define OPCODE_AT_BUF2_REPROGRAM               0x0259
+
+/* Status register bits for ST flashes */
+#define SR_ST_WIP              0x01            /* Write In Progress */
+#define SR_ST_WEL              0x02            /* Write Enable Latch */
+#define SR_ST_BP_MASK          0x1c            /* Block Protect */
+#define SR_ST_BP_SHIFT         2
+#define SR_ST_SRWD             0x80            /* Status Register Write Disable */
+
+/* Status register bits for Atmel flashes */
+#define SR_AT_READY            0x80
+#define SR_AT_MISMATCH         0x40
+#define SR_AT_ID_MASK          0x38
+#define SR_AT_ID_SHIFT         3
+
+struct bcma_drv_cc;
+
+enum bcm47xxsflash_type {
+       BCM47XXSFLASH_TYPE_ATMEL,
+       BCM47XXSFLASH_TYPE_ST,
+};
+
 struct bcm47xxsflash {
+       struct bcma_drv_cc *bcma_cc;
+
+       enum bcm47xxsflash_type type;
+
        u32 window;
        u32 blocksize;
        u16 numblocks;
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
deleted file mode 100644 (file)
index a4eb8b5..0000000
+++ /dev/null
@@ -1,1178 +0,0 @@
-
-/*
- * Linux driver for Disk-On-Chip 2000 and Millennium
- * (c) 1999 Machine Vision Holdings, Inc.
- * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/bitops.h>
-#include <linux/mutex.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/doc2000.h>
-
-#define DOC_SUPPORT_2000
-#define DOC_SUPPORT_2000TSOP
-#define DOC_SUPPORT_MILLENNIUM
-
-#ifdef DOC_SUPPORT_2000
-#define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k)
-#else
-#define DoC_is_2000(doc) (0)
-#endif
-
-#if defined(DOC_SUPPORT_2000TSOP) || defined(DOC_SUPPORT_MILLENNIUM)
-#define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil)
-#else
-#define DoC_is_Millennium(doc) (0)
-#endif
-
-/* #define ECC_DEBUG */
-
-/* I have no idea why some DoC chips can not use memcpy_from|to_io().
- * This may be due to the different revisions of the ASIC controller built-in or
- * simplily a QA/Bug issue. Who knows ?? If you have trouble, please uncomment
- * this:
- #undef USE_MEMCPY
-*/
-
-static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
-                   size_t *retlen, u_char *buf);
-static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
-                    size_t *retlen, const u_char *buf);
-static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
-                       struct mtd_oob_ops *ops);
-static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
-                        struct mtd_oob_ops *ops);
-static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
-                        size_t *retlen, const u_char *buf);
-static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
-
-static struct mtd_info *doc2klist = NULL;
-
-/* Perform the required delay cycles by reading from the appropriate register */
-static void DoC_Delay(struct DiskOnChip *doc, unsigned short cycles)
-{
-       volatile char dummy;
-       int i;
-
-       for (i = 0; i < cycles; i++) {
-               if (DoC_is_Millennium(doc))
-                       dummy = ReadDOC(doc->virtadr, NOP);
-               else
-                       dummy = ReadDOC(doc->virtadr, DOCStatus);
-       }
-
-}
-
-/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
-static int _DoC_WaitReady(struct DiskOnChip *doc)
-{
-       void __iomem *docptr = doc->virtadr;
-       unsigned long timeo = jiffies + (HZ * 10);
-
-       pr_debug("_DoC_WaitReady called for out-of-line wait\n");
-
-       /* Out-of-line routine to wait for chip response */
-       while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
-               /* issue 2 read from NOP register after reading from CDSNControl register
-               see Software Requirement 11.4 item 2. */
-               DoC_Delay(doc, 2);
-
-               if (time_after(jiffies, timeo)) {
-                       pr_debug("_DoC_WaitReady timed out.\n");
-                       return -EIO;
-               }
-               udelay(1);
-               cond_resched();
-       }
-
-       return 0;
-}
-
-static inline int DoC_WaitReady(struct DiskOnChip *doc)
-{
-       void __iomem *docptr = doc->virtadr;
-
-       /* This is inline, to optimise the common case, where it's ready instantly */
-       int ret = 0;
-
-       /* 4 read form NOP register should be issued in prior to the read from CDSNControl
-          see Software Requirement 11.4 item 2. */
-       DoC_Delay(doc, 4);
-
-       if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
-               /* Call the out-of-line routine to wait */
-               ret = _DoC_WaitReady(doc);
-
-       /* issue 2 read from NOP register after reading from CDSNControl register
-          see Software Requirement 11.4 item 2. */
-       DoC_Delay(doc, 2);
-
-       return ret;
-}
-
-/* DoC_Command: Send a flash command to the flash chip through the CDSN Slow IO register to
-   bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
-   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
-
-static int DoC_Command(struct DiskOnChip *doc, unsigned char command,
-                             unsigned char xtraflags)
-{
-       void __iomem *docptr = doc->virtadr;
-
-       if (DoC_is_2000(doc))
-               xtraflags |= CDSN_CTRL_FLASH_IO;
-
-       /* Assert the CLE (Command Latch Enable) line to the flash chip */
-       WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl);
-       DoC_Delay(doc, 4);      /* Software requirement 11.4.3 for Millennium */
-
-       if (DoC_is_Millennium(doc))
-               WriteDOC(command, docptr, CDSNSlowIO);
-
-       /* Send the command */
-       WriteDOC_(command, docptr, doc->ioreg);
-       if (DoC_is_Millennium(doc))
-               WriteDOC(command, docptr, WritePipeTerm);
-
-       /* Lower the CLE line */
-       WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
-       DoC_Delay(doc, 4);      /* Software requirement 11.4.3 for Millennium */
-
-       /* Wait for the chip to respond - Software requirement 11.4.1 (extended for any command) */
-       return DoC_WaitReady(doc);
-}
-
-/* DoC_Address: Set the current address for the flash chip through the CDSN Slow IO register to
-   bypass the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
-   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
-
-static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs,
-                      unsigned char xtraflags1, unsigned char xtraflags2)
-{
-       int i;
-       void __iomem *docptr = doc->virtadr;
-
-       if (DoC_is_2000(doc))
-               xtraflags1 |= CDSN_CTRL_FLASH_IO;
-
-       /* Assert the ALE (Address Latch Enable) line to the flash chip */
-       WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl);
-
-       DoC_Delay(doc, 4);      /* Software requirement 11.4.3 for Millennium */
-
-       /* Send the address */
-       /* Devices with 256-byte page are addressed as:
-          Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
-          * there is no device on the market with page256
-          and more than 24 bits.
-          Devices with 512-byte page are addressed as:
-          Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
-          * 25-31 is sent only if the chip support it.
-          * bit 8 changes the read command to be sent
-          (NAND_CMD_READ0 or NAND_CMD_READ1).
-        */
-
-       if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) {
-               if (DoC_is_Millennium(doc))
-                       WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
-               WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
-       }
-
-       if (doc->page256) {
-               ofs = ofs >> 8;
-       } else {
-               ofs = ofs >> 9;
-       }
-
-       if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) {
-               for (i = 0; i < doc->pageadrlen; i++, ofs = ofs >> 8) {
-                       if (DoC_is_Millennium(doc))
-                               WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
-                       WriteDOC_(ofs & 0xff, docptr, doc->ioreg);
-               }
-       }
-
-       if (DoC_is_Millennium(doc))
-               WriteDOC(ofs & 0xff, docptr, WritePipeTerm);
-
-       DoC_Delay(doc, 2);      /* Needed for some slow flash chips. mf. */
-
-       /* FIXME: The SlowIO's for millennium could be replaced by
-          a single WritePipeTerm here. mf. */
-
-       /* Lower the ALE line */
-       WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr,
-                CDSNControl);
-
-       DoC_Delay(doc, 4);      /* Software requirement 11.4.3 for Millennium */
-
-       /* Wait for the chip to respond - Software requirement 11.4.1 */
-       return DoC_WaitReady(doc);
-}
-
-/* Read a buffer from DoC, taking care of Millennium odditys */
-static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len)
-{
-       volatile int dummy;
-       int modulus = 0xffff;
-       void __iomem *docptr = doc->virtadr;
-       int i;
-
-       if (len <= 0)
-               return;
-
-       if (DoC_is_Millennium(doc)) {
-               /* Read the data via the internal pipeline through CDSN IO register,
-                  see Pipelined Read Operations 11.3 */
-               dummy = ReadDOC(docptr, ReadPipeInit);
-
-               /* Millennium should use the LastDataRead register - Pipeline Reads */
-               len--;
-
-               /* This is needed for correctly ECC calculation */
-               modulus = 0xff;
-       }
-
-       for (i = 0; i < len; i++)
-               buf[i] = ReadDOC_(docptr, doc->ioreg + (i & modulus));
-
-       if (DoC_is_Millennium(doc)) {
-               buf[i] = ReadDOC(docptr, LastDataRead);
-       }
-}
-
-/* Write a buffer to DoC, taking care of Millennium odditys */
-static void DoC_WriteBuf(struct DiskOnChip *doc, const u_char * buf, int len)
-{
-       void __iomem *docptr = doc->virtadr;
-       int i;
-
-       if (len <= 0)
-               return;
-
-       for (i = 0; i < len; i++)
-               WriteDOC_(buf[i], docptr, doc->ioreg + i);
-
-       if (DoC_is_Millennium(doc)) {
-               WriteDOC(0x00, docptr, WritePipeTerm);
-       }
-}
-
-
-/* DoC_SelectChip: Select a given flash chip within the current floor */
-
-static inline int DoC_SelectChip(struct DiskOnChip *doc, int chip)
-{
-       void __iomem *docptr = doc->virtadr;
-
-       /* Software requirement 11.4.4 before writing DeviceSelect */
-       /* Deassert the CE line to eliminate glitches on the FCE# outputs */
-       WriteDOC(CDSN_CTRL_WP, docptr, CDSNControl);
-       DoC_Delay(doc, 4);      /* Software requirement 11.4.3 for Millennium */
-
-       /* Select the individual flash chip requested */
-       WriteDOC(chip, docptr, CDSNDeviceSelect);
-       DoC_Delay(doc, 4);
-
-       /* Reassert the CE line */
-       WriteDOC(CDSN_CTRL_CE | CDSN_CTRL_FLASH_IO | CDSN_CTRL_WP, docptr,
-                CDSNControl);
-       DoC_Delay(doc, 4);      /* Software requirement 11.4.3 for Millennium */
-
-       /* Wait for it to be ready */
-       return DoC_WaitReady(doc);
-}
-
-/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
-
-static inline int DoC_SelectFloor(struct DiskOnChip *doc, int floor)
-{
-       void __iomem *docptr = doc->virtadr;
-
-       /* Select the floor (bank) of chips required */
-       WriteDOC(floor, docptr, FloorSelect);
-
-       /* Wait for the chip to be ready */
-       return DoC_WaitReady(doc);
-}
-
-/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
-
-static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
-{
-       int mfr, id, i, j;
-       volatile char dummy;
-
-       /* Page in the required floor/chip */
-       DoC_SelectFloor(doc, floor);
-       DoC_SelectChip(doc, chip);
-
-       /* Reset the chip */
-       if (DoC_Command(doc, NAND_CMD_RESET, CDSN_CTRL_WP)) {
-               pr_debug("DoC_Command (reset) for %d,%d returned true\n",
-                     floor, chip);
-               return 0;
-       }
-
-
-       /* Read the NAND chip ID: 1. Send ReadID command */
-       if (DoC_Command(doc, NAND_CMD_READID, CDSN_CTRL_WP)) {
-               pr_debug("DoC_Command (ReadID) for %d,%d returned true\n",
-                     floor, chip);
-               return 0;
-       }
-
-       /* Read the NAND chip ID: 2. Send address byte zero */
-       DoC_Address(doc, ADDR_COLUMN, 0, CDSN_CTRL_WP, 0);
-
-       /* Read the manufacturer and device id codes from the device */
-
-       if (DoC_is_Millennium(doc)) {
-               DoC_Delay(doc, 2);
-               dummy = ReadDOC(doc->virtadr, ReadPipeInit);
-               mfr = ReadDOC(doc->virtadr, LastDataRead);
-
-               DoC_Delay(doc, 2);
-               dummy = ReadDOC(doc->virtadr, ReadPipeInit);
-               id = ReadDOC(doc->virtadr, LastDataRead);
-       } else {
-               /* CDSN Slow IO register see Software Req 11.4 item 5. */
-               dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
-               DoC_Delay(doc, 2);
-               mfr = ReadDOC_(doc->virtadr, doc->ioreg);
-
-               /* CDSN Slow IO register see Software Req 11.4 item 5. */
-               dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
-               DoC_Delay(doc, 2);
-               id = ReadDOC_(doc->virtadr, doc->ioreg);
-       }
-
-       /* No response - return failure */
-       if (mfr == 0xff || mfr == 0)
-               return 0;
-
-       /* Check it's the same as the first chip we identified.
-        * M-Systems say that any given DiskOnChip device should only
-        * contain _one_ type of flash part, although that's not a
-        * hardware restriction. */
-       if (doc->mfr) {
-               if (doc->mfr == mfr && doc->id == id)
-                       return 1;       /* This is the same as the first */
-               else
-                       printk(KERN_WARNING
-                              "Flash chip at floor %d, chip %d is different:\n",
-                              floor, chip);
-       }
-
-       /* Print and store the manufacturer and ID codes. */
-       for (i = 0; nand_flash_ids[i].name != NULL; i++) {
-               if (id == nand_flash_ids[i].id) {
-                       /* Try to identify manufacturer */
-                       for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
-                               if (nand_manuf_ids[j].id == mfr)
-                                       break;
-                       }
-                       printk(KERN_INFO
-                              "Flash chip found: Manufacturer ID: %2.2X, "
-                              "Chip ID: %2.2X (%s:%s)\n", mfr, id,
-                              nand_manuf_ids[j].name, nand_flash_ids[i].name);
-                       if (!doc->mfr) {
-                               doc->mfr = mfr;
-                               doc->id = id;
-                               doc->chipshift =
-                                       ffs((nand_flash_ids[i].chipsize << 20)) - 1;
-                               doc->page256 = (nand_flash_ids[i].pagesize == 256) ? 1 : 0;
-                               doc->pageadrlen = doc->chipshift > 25 ? 3 : 2;
-                               doc->erasesize =
-                                   nand_flash_ids[i].erasesize;
-                               return 1;
-                       }
-                       return 0;
-               }
-       }
-
-
-       /* We haven't fully identified the chip. Print as much as we know. */
-       printk(KERN_WARNING "Unknown flash chip found: %2.2X %2.2X\n",
-              id, mfr);
-
-       printk(KERN_WARNING "Please report to dwmw2@infradead.org\n");
-       return 0;
-}
-
-/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
-
-static void DoC_ScanChips(struct DiskOnChip *this, int maxchips)
-{
-       int floor, chip;
-       int numchips[MAX_FLOORS];
-       int ret = 1;
-
-       this->numchips = 0;
-       this->mfr = 0;
-       this->id = 0;
-
-       /* For each floor, find the number of valid chips it contains */
-       for (floor = 0; floor < MAX_FLOORS; floor++) {
-               ret = 1;
-               numchips[floor] = 0;
-               for (chip = 0; chip < maxchips && ret != 0; chip++) {
-
-                       ret = DoC_IdentChip(this, floor, chip);
-                       if (ret) {
-                               numchips[floor]++;
-                               this->numchips++;
-                       }
-               }
-       }
-
-       /* If there are none at all that we recognise, bail */
-       if (!this->numchips) {
-               printk(KERN_NOTICE "No flash chips recognised.\n");
-               return;
-       }
-
-       /* Allocate an array to hold the information for each chip */
-       this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL);
-       if (!this->chips) {
-               printk(KERN_NOTICE "No memory for allocating chip info structures\n");
-               return;
-       }
-
-       ret = 0;
-
-       /* Fill out the chip array with {floor, chipno} for each
-        * detected chip in the device. */
-       for (floor = 0; floor < MAX_FLOORS; floor++) {
-               for (chip = 0; chip < numchips[floor]; chip++) {
-                       this->chips[ret].floor = floor;
-                       this->chips[ret].chip = chip;
-                       this->chips[ret].curadr = 0;
-                       this->chips[ret].curmode = 0x50;
-                       ret++;
-               }
-       }
-
-       /* Calculate and print the total size of the device */
-       this->totlen = this->numchips * (1 << this->chipshift);
-
-       printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld MiB\n",
-              this->numchips, this->totlen >> 20);
-}
-
-static int DoC2k_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
-{
-       int tmp1, tmp2, retval;
-       if (doc1->physadr == doc2->physadr)
-               return 1;
-
-       /* Use the alias resolution register which was set aside for this
-        * purpose. If it's value is the same on both chips, they might
-        * be the same chip, and we write to one and check for a change in
-        * the other. It's unclear if this register is usuable in the
-        * DoC 2000 (it's in the Millennium docs), but it seems to work. */
-       tmp1 = ReadDOC(doc1->virtadr, AliasResolution);
-       tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
-       if (tmp1 != tmp2)
-               return 0;
-
-       WriteDOC((tmp1 + 1) % 0xff, doc1->virtadr, AliasResolution);
-       tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
-       if (tmp2 == (tmp1 + 1) % 0xff)
-               retval = 1;
-       else
-               retval = 0;
-
-       /* Restore register contents.  May not be necessary, but do it just to
-        * be safe. */
-       WriteDOC(tmp1, doc1->virtadr, AliasResolution);
-
-       return retval;
-}
-
-/* This routine is found from the docprobe code by symbol_get(),
- * which will bump the use count of this module. */
-void DoC2k_init(struct mtd_info *mtd)
-{
-       struct DiskOnChip *this = mtd->priv;
-       struct DiskOnChip *old = NULL;
-       int maxchips;
-
-       /* We must avoid being called twice for the same device. */
-
-       if (doc2klist)
-               old = doc2klist->priv;
-
-       while (old) {
-               if (DoC2k_is_alias(old, this)) {
-                       printk(KERN_NOTICE
-                              "Ignoring DiskOnChip 2000 at 0x%lX - already configured\n",
-                              this->physadr);
-                       iounmap(this->virtadr);
-                       kfree(mtd);
-                       return;
-               }
-               if (old->nextdoc)
-                       old = old->nextdoc->priv;
-               else
-                       old = NULL;
-       }
-
-
-       switch (this->ChipID) {
-       case DOC_ChipID_Doc2kTSOP:
-               mtd->name = "DiskOnChip 2000 TSOP";
-               this->ioreg = DoC_Mil_CDSN_IO;
-               /* Pretend it's a Millennium */
-               this->ChipID = DOC_ChipID_DocMil;
-               maxchips = MAX_CHIPS;
-               break;
-       case DOC_ChipID_Doc2k:
-               mtd->name = "DiskOnChip 2000";
-               this->ioreg = DoC_2k_CDSN_IO;
-               maxchips = MAX_CHIPS;
-               break;
-       case DOC_ChipID_DocMil:
-               mtd->name = "DiskOnChip Millennium";
-               this->ioreg = DoC_Mil_CDSN_IO;
-               maxchips = MAX_CHIPS_MIL;
-               break;
-       default:
-               printk("Unknown ChipID 0x%02x\n", this->ChipID);
-               kfree(mtd);
-               iounmap(this->virtadr);
-               return;
-       }
-
-       printk(KERN_NOTICE "%s found at address 0x%lX\n", mtd->name,
-              this->physadr);
-
-       mtd->type = MTD_NANDFLASH;
-       mtd->flags = MTD_CAP_NANDFLASH;
-       mtd->writebufsize = mtd->writesize = 512;
-       mtd->oobsize = 16;
-       mtd->ecc_strength = 2;
-       mtd->owner = THIS_MODULE;
-       mtd->_erase = doc_erase;
-       mtd->_read = doc_read;
-       mtd->_write = doc_write;
-       mtd->_read_oob = doc_read_oob;
-       mtd->_write_oob = doc_write_oob;
-       this->curfloor = -1;
-       this->curchip = -1;
-       mutex_init(&this->lock);
-
-       /* Ident all the chips present. */
-       DoC_ScanChips(this, maxchips);
-
-       if (!this->totlen) {
-               kfree(mtd);
-               iounmap(this->virtadr);
-       } else {
-               this->nextdoc = doc2klist;
-               doc2klist = mtd;
-               mtd->size = this->totlen;
-               mtd->erasesize = this->erasesize;
-               mtd_device_register(mtd, NULL, 0);
-               return;
-       }
-}
-EXPORT_SYMBOL_GPL(DoC2k_init);
-
-static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
-                   size_t * retlen, u_char * buf)
-{
-       struct DiskOnChip *this = mtd->priv;
-       void __iomem *docptr = this->virtadr;
-       struct Nand *mychip;
-       unsigned char syndrome[6], eccbuf[6];
-       volatile char dummy;
-       int i, len256 = 0, ret=0;
-       size_t left = len;
-
-       mutex_lock(&this->lock);
-       while (left) {
-               len = left;
-
-               /* Don't allow a single read to cross a 512-byte block boundary */
-               if (from + len > ((from | 0x1ff) + 1))
-                       len = ((from | 0x1ff) + 1) - from;
-
-               /* The ECC will not be calculated correctly if less than 512 is read */
-               if (len != 0x200)
-                       printk(KERN_WARNING
-                              "ECC needs a full sector read (adr: %lx size %lx)\n",
-                              (long) from, (long) len);
-
-               /* printk("DoC_Read (adr: %lx size %lx)\n", (long) from, (long) len); */
-
-
-               /* Find the chip which is to be used and select it */
-               mychip = &this->chips[from >> (this->chipshift)];
-
-               if (this->curfloor != mychip->floor) {
-                       DoC_SelectFloor(this, mychip->floor);
-                       DoC_SelectChip(this, mychip->chip);
-               } else if (this->curchip != mychip->chip) {
-                       DoC_SelectChip(this, mychip->chip);
-               }
-
-               this->curfloor = mychip->floor;
-               this->curchip = mychip->chip;
-
-               DoC_Command(this,
-                           (!this->page256
-                            && (from & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
-                           CDSN_CTRL_WP);
-               DoC_Address(this, ADDR_COLUMN_PAGE, from, CDSN_CTRL_WP,
-                           CDSN_CTRL_ECC_IO);
-
-               /* Prime the ECC engine */
-               WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
-               WriteDOC(DOC_ECC_EN, docptr, ECCConf);
-
-               /* treat crossing 256-byte sector for 2M x 8bits devices */
-               if (this->page256 && from + len > (from | 0xff) + 1) {
-                       len256 = (from | 0xff) + 1 - from;
-                       DoC_ReadBuf(this, buf, len256);
-
-                       DoC_Command(this, NAND_CMD_READ0, CDSN_CTRL_WP);
-                       DoC_Address(this, ADDR_COLUMN_PAGE, from + len256,
-                                   CDSN_CTRL_WP, CDSN_CTRL_ECC_IO);
-               }
-
-               DoC_ReadBuf(this, &buf[len256], len - len256);
-
-               /* Let the caller know we completed it */
-               *retlen += len;
-
-               /* Read the ECC data through the DiskOnChip ECC logic */
-               /* Note: this will work even with 2M x 8bit devices as   */
-               /*       they have 8 bytes of OOB per 256 page. mf.      */
-               DoC_ReadBuf(this, eccbuf, 6);
-
-               /* Flush the pipeline */
-               if (DoC_is_Millennium(this)) {
-                       dummy = ReadDOC(docptr, ECCConf);
-                       dummy = ReadDOC(docptr, ECCConf);
-                       i = ReadDOC(docptr, ECCConf);
-               } else {
-                       dummy = ReadDOC(docptr, 2k_ECCStatus);
-                       dummy = ReadDOC(docptr, 2k_ECCStatus);
-                       i = ReadDOC(docptr, 2k_ECCStatus);
-               }
-
-               /* Check the ECC Status */
-               if (i & 0x80) {
-                       int nb_errors;
-                       /* There was an ECC error */
-#ifdef ECC_DEBUG
-                       printk(KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (long)from);
-#endif
-                       /* Read the ECC syndrome through the DiskOnChip ECC
-                          logic.  These syndrome will be all ZERO when there
-                          is no error */
-                       for (i = 0; i < 6; i++) {
-                               syndrome[i] =
-                                       ReadDOC(docptr, ECCSyndrome0 + i);
-                       }
-                       nb_errors = doc_decode_ecc(buf, syndrome);
-
-#ifdef ECC_DEBUG
-                       printk(KERN_ERR "Errors corrected: %x\n", nb_errors);
-#endif
-                       if (nb_errors < 0) {
-                               /* We return error, but have actually done the
-                                  read. Not that this can be told to
-                                  user-space, via sys_read(), but at least
-                                  MTD-aware stuff can know about it by
-                                  checking *retlen */
-                               ret = -EIO;
-                       }
-               }
-
-#ifdef PSYCHO_DEBUG
-               printk(KERN_DEBUG "ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
-                      (long)from, eccbuf[0], eccbuf[1], eccbuf[2],
-                      eccbuf[3], eccbuf[4], eccbuf[5]);
-#endif
-
-               /* disable the ECC engine */
-               WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
-
-               /* according to 11.4.1, we need to wait for the busy line
-                * drop if we read to the end of the page.  */
-               if(0 == ((from + len) & 0x1ff))
-               {
-                   DoC_WaitReady(this);
-               }
-
-               from += len;
-               left -= len;
-               buf += len;
-       }
-
-       mutex_unlock(&this->lock);
-
-       return ret;
-}
-
-static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
-                    size_t * retlen, const u_char * buf)
-{
-       struct DiskOnChip *this = mtd->priv;
-       int di; /* Yes, DI is a hangover from when I was disassembling the binary driver */
-       void __iomem *docptr = this->virtadr;
-       unsigned char eccbuf[6];
-       volatile char dummy;
-       int len256 = 0;
-       struct Nand *mychip;
-       size_t left = len;
-       int status;
-
-       mutex_lock(&this->lock);
-       while (left) {
-               len = left;
-
-               /* Don't allow a single write to cross a 512-byte block boundary */
-               if (to + len > ((to | 0x1ff) + 1))
-                       len = ((to | 0x1ff) + 1) - to;
-
-               /* The ECC will not be calculated correctly if less than 512 is written */
-/* DBB-
-               if (len != 0x200 && eccbuf)
-                       printk(KERN_WARNING
-                              "ECC needs a full sector write (adr: %lx size %lx)\n",
-                              (long) to, (long) len);
-   -DBB */
-
-               /* printk("DoC_Write (adr: %lx size %lx)\n", (long) to, (long) len); */
-
-               /* Find the chip which is to be used and select it */
-               mychip = &this->chips[to >> (this->chipshift)];
-
-               if (this->curfloor != mychip->floor) {
-                       DoC_SelectFloor(this, mychip->floor);
-                       DoC_SelectChip(this, mychip->chip);
-               } else if (this->curchip != mychip->chip) {
-                       DoC_SelectChip(this, mychip->chip);
-               }
-
-               this->curfloor = mychip->floor;
-               this->curchip = mychip->chip;
-
-               /* Set device to main plane of flash */
-               DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
-               DoC_Command(this,
-                           (!this->page256
-                            && (to & 0x100)) ? NAND_CMD_READ1 : NAND_CMD_READ0,
-                           CDSN_CTRL_WP);
-
-               DoC_Command(this, NAND_CMD_SEQIN, 0);
-               DoC_Address(this, ADDR_COLUMN_PAGE, to, 0, CDSN_CTRL_ECC_IO);
-
-               /* Prime the ECC engine */
-               WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
-               WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
-
-               /* treat crossing 256-byte sector for 2M x 8bits devices */
-               if (this->page256 && to + len > (to | 0xff) + 1) {
-                       len256 = (to | 0xff) + 1 - to;
-                       DoC_WriteBuf(this, buf, len256);
-
-                       DoC_Command(this, NAND_CMD_PAGEPROG, 0);
-
-                       DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
-                       /* There's an implicit DoC_WaitReady() in DoC_Command */
-
-                       dummy = ReadDOC(docptr, CDSNSlowIO);
-                       DoC_Delay(this, 2);
-
-                       if (ReadDOC_(docptr, this->ioreg) & 1) {
-                               printk(KERN_ERR "Error programming flash\n");
-                               /* Error in programming */
-                               *retlen = 0;
-                               mutex_unlock(&this->lock);
-                               return -EIO;
-                       }
-
-                       DoC_Command(this, NAND_CMD_SEQIN, 0);
-                       DoC_Address(this, ADDR_COLUMN_PAGE, to + len256, 0,
-                                   CDSN_CTRL_ECC_IO);
-               }
-
-               DoC_WriteBuf(this, &buf[len256], len - len256);
-
-               WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_CE, docptr, CDSNControl);
-
-               if (DoC_is_Millennium(this)) {
-                       WriteDOC(0, docptr, NOP);
-                       WriteDOC(0, docptr, NOP);
-                       WriteDOC(0, docptr, NOP);
-               } else {
-                       WriteDOC_(0, docptr, this->ioreg);
-                       WriteDOC_(0, docptr, this->ioreg);
-                       WriteDOC_(0, docptr, this->ioreg);
-               }
-
-               WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_FLASH_IO | CDSN_CTRL_CE, docptr,
-                        CDSNControl);
-
-               /* Read the ECC data through the DiskOnChip ECC logic */
-               for (di = 0; di < 6; di++) {
-                       eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
-               }
-
-               /* Reset the ECC engine */
-               WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
-
-#ifdef PSYCHO_DEBUG
-               printk
-                       ("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
-                        (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
-                        eccbuf[4], eccbuf[5]);
-#endif
-               DoC_Command(this, NAND_CMD_PAGEPROG, 0);
-
-               DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
-               /* There's an implicit DoC_WaitReady() in DoC_Command */
-
-               if (DoC_is_Millennium(this)) {
-                       ReadDOC(docptr, ReadPipeInit);
-                       status = ReadDOC(docptr, LastDataRead);
-               } else {
-                       dummy = ReadDOC(docptr, CDSNSlowIO);
-                       DoC_Delay(this, 2);
-                       status = ReadDOC_(docptr, this->ioreg);
-               }
-
-               if (status & 1) {
-                       printk(KERN_ERR "Error programming flash\n");
-                       /* Error in programming */
-                       *retlen = 0;
-                       mutex_unlock(&this->lock);
-                       return -EIO;
-               }
-
-               /* Let the caller know we completed it */
-               *retlen += len;
-
-               {
-                       unsigned char x[8];
-                       size_t dummy;
-                       int ret;
-
-                       /* Write the ECC data to flash */
-                       for (di=0; di<6; di++)
-                               x[di] = eccbuf[di];
-
-                       x[6]=0x55;
-                       x[7]=0x55;
-
-                       ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x);
-                       if (ret) {
-                               mutex_unlock(&this->lock);
-                               return ret;
-                       }
-               }
-
-               to += len;
-               left -= len;
-               buf += len;
-       }
-
-       mutex_unlock(&this->lock);
-       return 0;
-}
-
-static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
-                       struct mtd_oob_ops *ops)
-{
-       struct DiskOnChip *this = mtd->priv;
-       int len256 = 0, ret;
-       struct Nand *mychip;
-       uint8_t *buf = ops->oobbuf;
-       size_t len = ops->len;
-
-       BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
-
-       ofs += ops->ooboffs;
-
-       mutex_lock(&this->lock);
-
-       mychip = &this->chips[ofs >> this->chipshift];
-
-       if (this->curfloor != mychip->floor) {
-               DoC_SelectFloor(this, mychip->floor);
-               DoC_SelectChip(this, mychip->chip);
-       } else if (this->curchip != mychip->chip) {
-               DoC_SelectChip(this, mychip->chip);
-       }
-       this->curfloor = mychip->floor;
-       this->curchip = mychip->chip;
-
-       /* update address for 2M x 8bit devices. OOB starts on the second */
-       /* page to maintain compatibility with doc_read_ecc. */
-       if (this->page256) {
-               if (!(ofs & 0x8))
-                       ofs += 0x100;
-               else
-                       ofs -= 0x8;
-       }
-
-       DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
-       DoC_Address(this, ADDR_COLUMN_PAGE, ofs, CDSN_CTRL_WP, 0);
-
-       /* treat crossing 8-byte OOB data for 2M x 8bit devices */
-       /* Note: datasheet says it should automaticaly wrap to the */
-       /*       next OOB block, but it didn't work here. mf.      */
-       if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
-               len256 = (ofs | 0x7) + 1 - ofs;
-               DoC_ReadBuf(this, buf, len256);
-
-               DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
-               DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff),
-                           CDSN_CTRL_WP, 0);
-       }
-
-       DoC_ReadBuf(this, &buf[len256], len - len256);
-
-       ops->retlen = len;
-       /* Reading the full OOB data drops us off of the end of the page,
-         * causing the flash device to go into busy mode, so we need
-         * to wait until ready 11.4.1 and Toshiba TC58256FT docs */
-
-       ret = DoC_WaitReady(this);
-
-       mutex_unlock(&this->lock);
-       return ret;
-
-}
-
-static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
-                               size_t * retlen, const u_char * buf)
-{
-       struct DiskOnChip *this = mtd->priv;
-       int len256 = 0;
-       void __iomem *docptr = this->virtadr;
-       struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-       volatile int dummy;
-       int status;
-
-       //      printk("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",(long)ofs, len,
-       //   buf[0], buf[1], buf[2], buf[3], buf[8], buf[9], buf[14],buf[15]);
-
-       /* Find the chip which is to be used and select it */
-       if (this->curfloor != mychip->floor) {
-               DoC_SelectFloor(this, mychip->floor);
-               DoC_SelectChip(this, mychip->chip);
-       } else if (this->curchip != mychip->chip) {
-               DoC_SelectChip(this, mychip->chip);
-       }
-       this->curfloor = mychip->floor;
-       this->curchip = mychip->chip;
-
-       /* disable the ECC engine */
-       WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
-       WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
-
-       /* Reset the chip, see Software Requirement 11.4 item 1. */
-       DoC_Command(this, NAND_CMD_RESET, CDSN_CTRL_WP);
-
-       /* issue the Read2 command to set the pointer to the Spare Data Area. */
-       DoC_Command(this, NAND_CMD_READOOB, CDSN_CTRL_WP);
-
-       /* update address for 2M x 8bit devices. OOB starts on the second */
-       /* page to maintain compatibility with doc_read_ecc. */
-       if (this->page256) {
-               if (!(ofs & 0x8))
-                       ofs += 0x100;
-               else
-                       ofs -= 0x8;
-       }
-
-       /* issue the Serial Data In command to initial the Page Program process */
-       DoC_Command(this, NAND_CMD_SEQIN, 0);
-       DoC_Address(this, ADDR_COLUMN_PAGE, ofs, 0, 0);
-
-       /* treat crossing 8-byte OOB data for 2M x 8bit devices */
-       /* Note: datasheet says it should automaticaly wrap to the */
-       /*       next OOB block, but it didn't work here. mf.      */
-       if (this->page256 && ofs + len > (ofs | 0x7) + 1) {
-               len256 = (ofs | 0x7) + 1 - ofs;
-               DoC_WriteBuf(this, buf, len256);
-
-               DoC_Command(this, NAND_CMD_PAGEPROG, 0);
-               DoC_Command(this, NAND_CMD_STATUS, 0);
-               /* DoC_WaitReady() is implicit in DoC_Command */
-
-               if (DoC_is_Millennium(this)) {
-                       ReadDOC(docptr, ReadPipeInit);
-                       status = ReadDOC(docptr, LastDataRead);
-               } else {
-                       dummy = ReadDOC(docptr, CDSNSlowIO);
-                       DoC_Delay(this, 2);
-                       status = ReadDOC_(docptr, this->ioreg);
-               }
-
-               if (status & 1) {
-                       printk(KERN_ERR "Error programming oob data\n");
-                       /* There was an error */
-                       *retlen = 0;
-                       return -EIO;
-               }
-               DoC_Command(this, NAND_CMD_SEQIN, 0);
-               DoC_Address(this, ADDR_COLUMN_PAGE, ofs & (~0x1ff), 0, 0);
-       }
-
-       DoC_WriteBuf(this, &buf[len256], len - len256);
-
-       DoC_Command(this, NAND_CMD_PAGEPROG, 0);
-       DoC_Command(this, NAND_CMD_STATUS, 0);
-       /* DoC_WaitReady() is implicit in DoC_Command */
-
-       if (DoC_is_Millennium(this)) {
-               ReadDOC(docptr, ReadPipeInit);
-               status = ReadDOC(docptr, LastDataRead);
-       } else {
-               dummy = ReadDOC(docptr, CDSNSlowIO);
-               DoC_Delay(this, 2);
-               status = ReadDOC_(docptr, this->ioreg);
-       }
-
-       if (status & 1) {
-               printk(KERN_ERR "Error programming oob data\n");
-               /* There was an error */
-               *retlen = 0;
-               return -EIO;
-       }
-
-       *retlen = len;
-       return 0;
-
-}
-
-static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
-                        struct mtd_oob_ops *ops)
-{
-       struct DiskOnChip *this = mtd->priv;
-       int ret;
-
-       BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
-
-       mutex_lock(&this->lock);
-       ret = doc_write_oob_nolock(mtd, ofs + ops->ooboffs, ops->len,
-                                  &ops->retlen, ops->oobbuf);
-
-       mutex_unlock(&this->lock);
-       return ret;
-}
-
-static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
-{
-       struct DiskOnChip *this = mtd->priv;
-       __u32 ofs = instr->addr;
-       __u32 len = instr->len;
-       volatile int dummy;
-       void __iomem *docptr = this->virtadr;
-       struct Nand *mychip;
-       int status;
-
-       mutex_lock(&this->lock);
-
-       if (ofs & (mtd->erasesize-1) || len & (mtd->erasesize-1)) {
-               mutex_unlock(&this->lock);
-               return -EINVAL;
-       }
-
-       instr->state = MTD_ERASING;
-
-       /* FIXME: Do this in the background. Use timers or schedule_task() */
-       while(len) {
-               mychip = &this->chips[ofs >> this->chipshift];
-
-               if (this->curfloor != mychip->floor) {
-                       DoC_SelectFloor(this, mychip->floor);
-                       DoC_SelectChip(this, mychip->chip);
-               } else if (this->curchip != mychip->chip) {
-                       DoC_SelectChip(this, mychip->chip);
-               }
-               this->curfloor = mychip->floor;
-               this->curchip = mychip->chip;
-
-               DoC_Command(this, NAND_CMD_ERASE1, 0);
-               DoC_Address(this, ADDR_PAGE, ofs, 0, 0);
-               DoC_Command(this, NAND_CMD_ERASE2, 0);
-
-               DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
-
-               if (DoC_is_Millennium(this)) {
-                       ReadDOC(docptr, ReadPipeInit);
-                       status = ReadDOC(docptr, LastDataRead);
-               } else {
-                       dummy = ReadDOC(docptr, CDSNSlowIO);
-                       DoC_Delay(this, 2);
-                       status = ReadDOC_(docptr, this->ioreg);
-               }
-
-               if (status & 1) {
-                       printk(KERN_ERR "Error erasing at 0x%x\n", ofs);
-                       /* There was an error */
-                       instr->state = MTD_ERASE_FAILED;
-                       goto callback;
-               }
-               ofs += mtd->erasesize;
-               len -= mtd->erasesize;
-       }
-       instr->state = MTD_ERASE_DONE;
-
- callback:
-       mtd_erase_callback(instr);
-
-       mutex_unlock(&this->lock);
-       return 0;
-}
-
-
-/****************************************************************************
- *
- * Module stuff
- *
- ****************************************************************************/
-
-static void __exit cleanup_doc2000(void)
-{
-       struct mtd_info *mtd;
-       struct DiskOnChip *this;
-
-       while ((mtd = doc2klist)) {
-               this = mtd->priv;
-               doc2klist = this->nextdoc;
-
-               mtd_device_unregister(mtd);
-
-               iounmap(this->virtadr);
-               kfree(this->chips);
-               kfree(mtd);
-       }
-}
-
-module_exit(cleanup_doc2000);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
-MODULE_DESCRIPTION("MTD driver for DiskOnChip 2000 and Millennium");
-
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
deleted file mode 100644 (file)
index f692795..0000000
+++ /dev/null
@@ -1,824 +0,0 @@
-
-/*
- * Linux driver for Disk-On-Chip Millennium
- * (c) 1999 Machine Vision Holdings, Inc.
- * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/bitops.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/doc2000.h>
-
-/* #define ECC_DEBUG */
-
-/* I have no idea why some DoC chips can not use memcop_form|to_io().
- * This may be due to the different revisions of the ASIC controller built-in or
- * simplily a QA/Bug issue. Who knows ?? If you have trouble, please uncomment
- * this:*/
-#undef USE_MEMCPY
-
-static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
-                   size_t *retlen, u_char *buf);
-static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
-                    size_t *retlen, const u_char *buf);
-static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
-                       struct mtd_oob_ops *ops);
-static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
-                        struct mtd_oob_ops *ops);
-static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
-
-static struct mtd_info *docmillist = NULL;
-
-/* Perform the required delay cycles by reading from the NOP register */
-static void DoC_Delay(void __iomem * docptr, unsigned short cycles)
-{
-       volatile char dummy;
-       int i;
-
-       for (i = 0; i < cycles; i++)
-               dummy = ReadDOC(docptr, NOP);
-}
-
-/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
-static int _DoC_WaitReady(void __iomem * docptr)
-{
-       unsigned short c = 0xffff;
-
-       pr_debug("_DoC_WaitReady called for out-of-line wait\n");
-
-       /* Out-of-line routine to wait for chip response */
-       while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B) && --c)
-               ;
-
-       if (c == 0)
-               pr_debug("_DoC_WaitReady timed out.\n");
-
-       return (c == 0);
-}
-
-static inline int DoC_WaitReady(void __iomem * docptr)
-{
-       /* This is inline, to optimise the common case, where it's ready instantly */
-       int ret = 0;
-
-       /* 4 read form NOP register should be issued in prior to the read from CDSNControl
-          see Software Requirement 11.4 item 2. */
-       DoC_Delay(docptr, 4);
-
-       if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
-               /* Call the out-of-line routine to wait */
-               ret = _DoC_WaitReady(docptr);
-
-       /* issue 2 read from NOP register after reading from CDSNControl register
-          see Software Requirement 11.4 item 2. */
-       DoC_Delay(docptr, 2);
-
-       return ret;
-}
-
-/* DoC_Command: Send a flash command to the flash chip through the CDSN IO register
-   with the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
-   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
-
-static void DoC_Command(void __iomem * docptr, unsigned char command,
-                              unsigned char xtraflags)
-{
-       /* Assert the CLE (Command Latch Enable) line to the flash chip */
-       WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl);
-       DoC_Delay(docptr, 4);
-
-       /* Send the command */
-       WriteDOC(command, docptr, Mil_CDSN_IO);
-       WriteDOC(0x00, docptr, WritePipeTerm);
-
-       /* Lower the CLE line */
-       WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
-       DoC_Delay(docptr, 4);
-}
-
-/* DoC_Address: Set the current address for the flash chip through the CDSN IO register
-   with the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
-   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
-
-static inline void DoC_Address(void __iomem * docptr, int numbytes, unsigned long ofs,
-                              unsigned char xtraflags1, unsigned char xtraflags2)
-{
-       /* Assert the ALE (Address Latch Enable) line to the flash chip */
-       WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl);
-       DoC_Delay(docptr, 4);
-
-       /* Send the address */
-       switch (numbytes)
-           {
-           case 1:
-                   /* Send single byte, bits 0-7. */
-                   WriteDOC(ofs & 0xff, docptr, Mil_CDSN_IO);
-                   WriteDOC(0x00, docptr, WritePipeTerm);
-                   break;
-           case 2:
-                   /* Send bits 9-16 followed by 17-23 */
-                   WriteDOC((ofs >> 9)  & 0xff, docptr, Mil_CDSN_IO);
-                   WriteDOC((ofs >> 17) & 0xff, docptr, Mil_CDSN_IO);
-                   WriteDOC(0x00, docptr, WritePipeTerm);
-               break;
-           case 3:
-                   /* Send 0-7, 9-16, then 17-23 */
-                   WriteDOC(ofs & 0xff, docptr, Mil_CDSN_IO);
-                   WriteDOC((ofs >> 9)  & 0xff, docptr, Mil_CDSN_IO);
-                   WriteDOC((ofs >> 17) & 0xff, docptr, Mil_CDSN_IO);
-                   WriteDOC(0x00, docptr, WritePipeTerm);
-               break;
-           default:
-               return;
-           }
-
-       /* Lower the ALE line */
-       WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr, CDSNControl);
-       DoC_Delay(docptr, 4);
-}
-
-/* DoC_SelectChip: Select a given flash chip within the current floor */
-static int DoC_SelectChip(void __iomem * docptr, int chip)
-{
-       /* Select the individual flash chip requested */
-       WriteDOC(chip, docptr, CDSNDeviceSelect);
-       DoC_Delay(docptr, 4);
-
-       /* Wait for it to be ready */
-       return DoC_WaitReady(docptr);
-}
-
-/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
-static int DoC_SelectFloor(void __iomem * docptr, int floor)
-{
-       /* Select the floor (bank) of chips required */
-       WriteDOC(floor, docptr, FloorSelect);
-
-       /* Wait for the chip to be ready */
-       return DoC_WaitReady(docptr);
-}
-
-/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
-static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
-{
-       int mfr, id, i, j;
-       volatile char dummy;
-
-       /* Page in the required floor/chip
-          FIXME: is this supported by Millennium ?? */
-       DoC_SelectFloor(doc->virtadr, floor);
-       DoC_SelectChip(doc->virtadr, chip);
-
-       /* Reset the chip, see Software Requirement 11.4 item 1. */
-       DoC_Command(doc->virtadr, NAND_CMD_RESET, CDSN_CTRL_WP);
-       DoC_WaitReady(doc->virtadr);
-
-       /* Read the NAND chip ID: 1. Send ReadID command */
-       DoC_Command(doc->virtadr, NAND_CMD_READID, CDSN_CTRL_WP);
-
-       /* Read the NAND chip ID: 2. Send address byte zero */
-       DoC_Address(doc->virtadr, 1, 0x00, CDSN_CTRL_WP, 0x00);
-
-       /* Read the manufacturer and device id codes of the flash device through
-          CDSN IO register see Software Requirement 11.4 item 5.*/
-       dummy = ReadDOC(doc->virtadr, ReadPipeInit);
-       DoC_Delay(doc->virtadr, 2);
-       mfr = ReadDOC(doc->virtadr, Mil_CDSN_IO);
-
-       DoC_Delay(doc->virtadr, 2);
-       id  = ReadDOC(doc->virtadr, Mil_CDSN_IO);
-       dummy = ReadDOC(doc->virtadr, LastDataRead);
-
-       /* No response - return failure */
-       if (mfr == 0xff || mfr == 0)
-               return 0;
-
-       /* FIXME: to deal with multi-flash on multi-Millennium case more carefully */
-       for (i = 0; nand_flash_ids[i].name != NULL; i++) {
-               if ( id == nand_flash_ids[i].id) {
-                       /* Try to identify manufacturer */
-                       for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
-                               if (nand_manuf_ids[j].id == mfr)
-                                       break;
-                       }
-                       printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, "
-                              "Chip ID: %2.2X (%s:%s)\n",
-                              mfr, id, nand_manuf_ids[j].name, nand_flash_ids[i].name);
-                       doc->mfr = mfr;
-                       doc->id = id;
-                       doc->chipshift = ffs((nand_flash_ids[i].chipsize << 20)) - 1;
-                       break;
-               }
-       }
-
-       if (nand_flash_ids[i].name == NULL)
-               return 0;
-       else
-               return 1;
-}
-
-/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
-static void DoC_ScanChips(struct DiskOnChip *this)
-{
-       int floor, chip;
-       int numchips[MAX_FLOORS_MIL];
-       int ret;
-
-       this->numchips = 0;
-       this->mfr = 0;
-       this->id = 0;
-
-       /* For each floor, find the number of valid chips it contains */
-       for (floor = 0,ret = 1; floor < MAX_FLOORS_MIL; floor++) {
-               numchips[floor] = 0;
-               for (chip = 0; chip < MAX_CHIPS_MIL && ret != 0; chip++) {
-                       ret = DoC_IdentChip(this, floor, chip);
-                       if (ret) {
-                               numchips[floor]++;
-                               this->numchips++;
-                       }
-               }
-       }
-       /* If there are none at all that we recognise, bail */
-       if (!this->numchips) {
-               printk("No flash chips recognised.\n");
-               return;
-       }
-
-       /* Allocate an array to hold the information for each chip */
-       this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL);
-       if (!this->chips){
-               printk("No memory for allocating chip info structures\n");
-               return;
-       }
-
-       /* Fill out the chip array with {floor, chipno} for each
-        * detected chip in the device. */
-       for (floor = 0, ret = 0; floor < MAX_FLOORS_MIL; floor++) {
-               for (chip = 0 ; chip < numchips[floor] ; chip++) {
-                       this->chips[ret].floor = floor;
-                       this->chips[ret].chip = chip;
-                       this->chips[ret].curadr = 0;
-                       this->chips[ret].curmode = 0x50;
-                       ret++;
-               }
-       }
-
-       /* Calculate and print the total size of the device */
-       this->totlen = this->numchips * (1 << this->chipshift);
-       printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld MiB\n",
-              this->numchips ,this->totlen >> 20);
-}
-
-static int DoCMil_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
-{
-       int tmp1, tmp2, retval;
-
-       if (doc1->physadr == doc2->physadr)
-               return 1;
-
-       /* Use the alias resolution register which was set aside for this
-        * purpose. If it's value is the same on both chips, they might
-        * be the same chip, and we write to one and check for a change in
-        * the other. It's unclear if this register is usuable in the
-        * DoC 2000 (it's in the Millenium docs), but it seems to work. */
-       tmp1 = ReadDOC(doc1->virtadr, AliasResolution);
-       tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
-       if (tmp1 != tmp2)
-               return 0;
-
-       WriteDOC((tmp1+1) % 0xff, doc1->virtadr, AliasResolution);
-       tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
-       if (tmp2 == (tmp1+1) % 0xff)
-               retval = 1;
-       else
-               retval = 0;
-
-       /* Restore register contents.  May not be necessary, but do it just to
-        * be safe. */
-       WriteDOC(tmp1, doc1->virtadr, AliasResolution);
-
-       return retval;
-}
-
-/* This routine is found from the docprobe code by symbol_get(),
- * which will bump the use count of this module. */
-void DoCMil_init(struct mtd_info *mtd)
-{
-       struct DiskOnChip *this = mtd->priv;
-       struct DiskOnChip *old = NULL;
-
-       /* We must avoid being called twice for the same device. */
-       if (docmillist)
-               old = docmillist->priv;
-
-       while (old) {
-               if (DoCMil_is_alias(this, old)) {
-                       printk(KERN_NOTICE "Ignoring DiskOnChip Millennium at "
-                              "0x%lX - already configured\n", this->physadr);
-                       iounmap(this->virtadr);
-                       kfree(mtd);
-                       return;
-               }
-               if (old->nextdoc)
-                       old = old->nextdoc->priv;
-               else
-                       old = NULL;
-       }
-
-       mtd->name = "DiskOnChip Millennium";
-       printk(KERN_NOTICE "DiskOnChip Millennium found at address 0x%lX\n",
-              this->physadr);
-
-       mtd->type = MTD_NANDFLASH;
-       mtd->flags = MTD_CAP_NANDFLASH;
-
-       /* FIXME: erase size is not always 8KiB */
-       mtd->erasesize = 0x2000;
-       mtd->writebufsize = mtd->writesize = 512;
-       mtd->oobsize = 16;
-       mtd->ecc_strength = 2;
-       mtd->owner = THIS_MODULE;
-       mtd->_erase = doc_erase;
-       mtd->_read = doc_read;
-       mtd->_write = doc_write;
-       mtd->_read_oob = doc_read_oob;
-       mtd->_write_oob = doc_write_oob;
-       this->curfloor = -1;
-       this->curchip = -1;
-
-       /* Ident all the chips present. */
-       DoC_ScanChips(this);
-
-       if (!this->totlen) {
-               kfree(mtd);
-               iounmap(this->virtadr);
-       } else {
-               this->nextdoc = docmillist;
-               docmillist = mtd;
-               mtd->size  = this->totlen;
-               mtd_device_register(mtd, NULL, 0);
-               return;
-       }
-}
-EXPORT_SYMBOL_GPL(DoCMil_init);
-
-static int doc_read (struct mtd_info *mtd, loff_t from, size_t len,
-                    size_t *retlen, u_char *buf)
-{
-       int i, ret;
-       volatile char dummy;
-       unsigned char syndrome[6], eccbuf[6];
-       struct DiskOnChip *this = mtd->priv;
-       void __iomem *docptr = this->virtadr;
-       struct Nand *mychip = &this->chips[from >> (this->chipshift)];
-
-       /* Don't allow a single read to cross a 512-byte block boundary */
-       if (from + len > ((from | 0x1ff) + 1))
-               len = ((from | 0x1ff) + 1) - from;
-
-       /* Find the chip which is to be used and select it */
-       if (this->curfloor != mychip->floor) {
-               DoC_SelectFloor(docptr, mychip->floor);
-               DoC_SelectChip(docptr, mychip->chip);
-       } else if (this->curchip != mychip->chip) {
-               DoC_SelectChip(docptr, mychip->chip);
-       }
-       this->curfloor = mychip->floor;
-       this->curchip = mychip->chip;
-
-       /* issue the Read0 or Read1 command depend on which half of the page
-          we are accessing. Polling the Flash Ready bit after issue 3 bytes
-          address in Sequence Read Mode, see Software Requirement 11.4 item 1.*/
-       DoC_Command(docptr, (from >> 8) & 1, CDSN_CTRL_WP);
-       DoC_Address(docptr, 3, from, CDSN_CTRL_WP, 0x00);
-       DoC_WaitReady(docptr);
-
-       /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
-       WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
-       WriteDOC (DOC_ECC_EN, docptr, ECCConf);
-
-       /* Read the data via the internal pipeline through CDSN IO register,
-          see Pipelined Read Operations 11.3 */
-       dummy = ReadDOC(docptr, ReadPipeInit);
-#ifndef USE_MEMCPY
-       for (i = 0; i < len-1; i++) {
-               /* N.B. you have to increase the source address in this way or the
-                  ECC logic will not work properly */
-               buf[i] = ReadDOC(docptr, Mil_CDSN_IO + (i & 0xff));
-       }
-#else
-       memcpy_fromio(buf, docptr + DoC_Mil_CDSN_IO, len - 1);
-#endif
-       buf[len - 1] = ReadDOC(docptr, LastDataRead);
-
-       /* Let the caller know we completed it */
-       *retlen = len;
-        ret = 0;
-
-       /* Read the ECC data from Spare Data Area,
-          see Reed-Solomon EDC/ECC 11.1 */
-       dummy = ReadDOC(docptr, ReadPipeInit);
-#ifndef USE_MEMCPY
-       for (i = 0; i < 5; i++) {
-               /* N.B. you have to increase the source address in this way or the
-                  ECC logic will not work properly */
-               eccbuf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
-       }
-#else
-       memcpy_fromio(eccbuf, docptr + DoC_Mil_CDSN_IO, 5);
-#endif
-       eccbuf[5] = ReadDOC(docptr, LastDataRead);
-
-       /* Flush the pipeline */
-       dummy = ReadDOC(docptr, ECCConf);
-       dummy = ReadDOC(docptr, ECCConf);
-
-       /* Check the ECC Status */
-       if (ReadDOC(docptr, ECCConf) & 0x80) {
-               int nb_errors;
-               /* There was an ECC error */
-#ifdef ECC_DEBUG
-               printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
-#endif
-               /* Read the ECC syndrome through the DiskOnChip ECC logic.
-                  These syndrome will be all ZERO when there is no error */
-               for (i = 0; i < 6; i++) {
-                       syndrome[i] = ReadDOC(docptr, ECCSyndrome0 + i);
-               }
-               nb_errors = doc_decode_ecc(buf, syndrome);
-#ifdef ECC_DEBUG
-               printk("ECC Errors corrected: %x\n", nb_errors);
-#endif
-               if (nb_errors < 0) {
-                       /* We return error, but have actually done the read. Not that
-                          this can be told to user-space, via sys_read(), but at least
-                          MTD-aware stuff can know about it by checking *retlen */
-                       ret = -EIO;
-               }
-       }
-
-#ifdef PSYCHO_DEBUG
-       printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
-              (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
-              eccbuf[4], eccbuf[5]);
-#endif
-
-       /* disable the ECC engine */
-       WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
-
-       return ret;
-}
-
-static int doc_write (struct mtd_info *mtd, loff_t to, size_t len,
-                     size_t *retlen, const u_char *buf)
-{
-       int i,ret = 0;
-       char eccbuf[6];
-       volatile char dummy;
-       struct DiskOnChip *this = mtd->priv;
-       void __iomem *docptr = this->virtadr;
-       struct Nand *mychip = &this->chips[to >> (this->chipshift)];
-
-#if 0
-       /* Don't allow a single write to cross a 512-byte block boundary */
-       if (to + len > ( (to | 0x1ff) + 1))
-               len = ((to | 0x1ff) + 1) - to;
-#else
-       /* Don't allow writes which aren't exactly one block */
-       if (to & 0x1ff || len != 0x200)
-               return -EINVAL;
-#endif
-
-       /* Find the chip which is to be used and select it */
-       if (this->curfloor != mychip->floor) {
-               DoC_SelectFloor(docptr, mychip->floor);
-               DoC_SelectChip(docptr, mychip->chip);
-       } else if (this->curchip != mychip->chip) {
-               DoC_SelectChip(docptr, mychip->chip);
-       }
-       this->curfloor = mychip->floor;
-       this->curchip = mychip->chip;
-
-       /* Reset the chip, see Software Requirement 11.4 item 1. */
-       DoC_Command(docptr, NAND_CMD_RESET, 0x00);
-       DoC_WaitReady(docptr);
-       /* Set device to main plane of flash */
-       DoC_Command(docptr, NAND_CMD_READ0, 0x00);
-
-       /* issue the Serial Data In command to initial the Page Program process */
-       DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
-       DoC_Address(docptr, 3, to, 0x00, 0x00);
-       DoC_WaitReady(docptr);
-
-       /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
-       WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
-       WriteDOC (DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
-
-       /* Write the data via the internal pipeline through CDSN IO register,
-          see Pipelined Write Operations 11.2 */
-#ifndef USE_MEMCPY
-       for (i = 0; i < len; i++) {
-               /* N.B. you have to increase the source address in this way or the
-                  ECC logic will not work properly */
-               WriteDOC(buf[i], docptr, Mil_CDSN_IO + i);
-       }
-#else
-       memcpy_toio(docptr + DoC_Mil_CDSN_IO, buf, len);
-#endif
-       WriteDOC(0x00, docptr, WritePipeTerm);
-
-       /* Write ECC data to flash, the ECC info is generated by the DiskOnChip ECC logic
-          see Reed-Solomon EDC/ECC 11.1 */
-       WriteDOC(0, docptr, NOP);
-       WriteDOC(0, docptr, NOP);
-       WriteDOC(0, docptr, NOP);
-
-       /* Read the ECC data through the DiskOnChip ECC logic */
-       for (i = 0; i < 6; i++) {
-               eccbuf[i] = ReadDOC(docptr, ECCSyndrome0 + i);
-       }
-
-       /* ignore the ECC engine */
-       WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
-
-#ifndef USE_MEMCPY
-       /* Write the ECC data to flash */
-       for (i = 0; i < 6; i++) {
-               /* N.B. you have to increase the source address in this way or the
-                  ECC logic will not work properly */
-               WriteDOC(eccbuf[i], docptr, Mil_CDSN_IO + i);
-       }
-#else
-       memcpy_toio(docptr + DoC_Mil_CDSN_IO, eccbuf, 6);
-#endif
-
-       /* write the block status BLOCK_USED (0x5555) at the end of ECC data
-          FIXME: this is only a hack for programming the IPL area for LinuxBIOS
-          and should be replace with proper codes in user space utilities */
-       WriteDOC(0x55, docptr, Mil_CDSN_IO);
-       WriteDOC(0x55, docptr, Mil_CDSN_IO + 1);
-
-       WriteDOC(0x00, docptr, WritePipeTerm);
-
-#ifdef PSYCHO_DEBUG
-       printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
-              (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
-              eccbuf[4], eccbuf[5]);
-#endif
-
-       /* Commit the Page Program command and wait for ready
-          see Software Requirement 11.4 item 1.*/
-       DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
-       DoC_WaitReady(docptr);
-
-       /* Read the status of the flash device through CDSN IO register
-          see Software Requirement 11.4 item 5.*/
-       DoC_Command(docptr, NAND_CMD_STATUS, CDSN_CTRL_WP);
-       dummy = ReadDOC(docptr, ReadPipeInit);
-       DoC_Delay(docptr, 2);
-       if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
-               printk("Error programming flash\n");
-               /* Error in programming
-                  FIXME: implement Bad Block Replacement (in nftl.c ??) */
-               ret = -EIO;
-       }
-       dummy = ReadDOC(docptr, LastDataRead);
-
-       /* Let the caller know we completed it */
-       *retlen = len;
-
-       return ret;
-}
-
-static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
-                       struct mtd_oob_ops *ops)
-{
-#ifndef USE_MEMCPY
-       int i;
-#endif
-       volatile char dummy;
-       struct DiskOnChip *this = mtd->priv;
-       void __iomem *docptr = this->virtadr;
-       struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-       uint8_t *buf = ops->oobbuf;
-       size_t len = ops->len;
-
-       BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
-
-       ofs += ops->ooboffs;
-
-       /* Find the chip which is to be used and select it */
-       if (this->curfloor != mychip->floor) {
-               DoC_SelectFloor(docptr, mychip->floor);
-               DoC_SelectChip(docptr, mychip->chip);
-       } else if (this->curchip != mychip->chip) {
-               DoC_SelectChip(docptr, mychip->chip);
-       }
-       this->curfloor = mychip->floor;
-       this->curchip = mychip->chip;
-
-       /* disable the ECC engine */
-       WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
-       WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
-
-       /* issue the Read2 command to set the pointer to the Spare Data Area.
-          Polling the Flash Ready bit after issue 3 bytes address in
-          Sequence Read Mode, see Software Requirement 11.4 item 1.*/
-       DoC_Command(docptr, NAND_CMD_READOOB, CDSN_CTRL_WP);
-       DoC_Address(docptr, 3, ofs, CDSN_CTRL_WP, 0x00);
-       DoC_WaitReady(docptr);
-
-       /* Read the data out via the internal pipeline through CDSN IO register,
-          see Pipelined Read Operations 11.3 */
-       dummy = ReadDOC(docptr, ReadPipeInit);
-#ifndef USE_MEMCPY
-       for (i = 0; i < len-1; i++) {
-               /* N.B. you have to increase the source address in this way or the
-                  ECC logic will not work properly */
-               buf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
-       }
-#else
-       memcpy_fromio(buf, docptr + DoC_Mil_CDSN_IO, len - 1);
-#endif
-       buf[len - 1] = ReadDOC(docptr, LastDataRead);
-
-       ops->retlen = len;
-
-       return 0;
-}
-
-static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
-                        struct mtd_oob_ops *ops)
-{
-#ifndef USE_MEMCPY
-       int i;
-#endif
-       volatile char dummy;
-       int ret = 0;
-       struct DiskOnChip *this = mtd->priv;
-       void __iomem *docptr = this->virtadr;
-       struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-       uint8_t *buf = ops->oobbuf;
-       size_t len = ops->len;
-
-       BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
-
-       ofs += ops->ooboffs;
-
-       /* Find the chip which is to be used and select it */
-       if (this->curfloor != mychip->floor) {
-               DoC_SelectFloor(docptr, mychip->floor);
-               DoC_SelectChip(docptr, mychip->chip);
-       } else if (this->curchip != mychip->chip) {
-               DoC_SelectChip(docptr, mychip->chip);
-       }
-       this->curfloor = mychip->floor;
-       this->curchip = mychip->chip;
-
-       /* disable the ECC engine */
-       WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
-       WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
-
-       /* Reset the chip, see Software Requirement 11.4 item 1. */
-       DoC_Command(docptr, NAND_CMD_RESET, CDSN_CTRL_WP);
-       DoC_WaitReady(docptr);
-       /* issue the Read2 command to set the pointer to the Spare Data Area. */
-       DoC_Command(docptr, NAND_CMD_READOOB, CDSN_CTRL_WP);
-
-       /* issue the Serial Data In command to initial the Page Program process */
-       DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
-       DoC_Address(docptr, 3, ofs, 0x00, 0x00);
-
-       /* Write the data via the internal pipeline through CDSN IO register,
-          see Pipelined Write Operations 11.2 */
-#ifndef USE_MEMCPY
-       for (i = 0; i < len; i++) {
-               /* N.B. you have to increase the source address in this way or the
-                  ECC logic will not work properly */
-               WriteDOC(buf[i], docptr, Mil_CDSN_IO + i);
-       }
-#else
-       memcpy_toio(docptr + DoC_Mil_CDSN_IO, buf, len);
-#endif
-       WriteDOC(0x00, docptr, WritePipeTerm);
-
-       /* Commit the Page Program command and wait for ready
-          see Software Requirement 11.4 item 1.*/
-       DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
-       DoC_WaitReady(docptr);
-
-       /* Read the status of the flash device through CDSN IO register
-          see Software Requirement 11.4 item 5.*/
-       DoC_Command(docptr, NAND_CMD_STATUS, 0x00);
-       dummy = ReadDOC(docptr, ReadPipeInit);
-       DoC_Delay(docptr, 2);
-       if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
-               printk("Error programming oob data\n");
-               /* FIXME: implement Bad Block Replacement (in nftl.c ??) */
-               ops->retlen = 0;
-               ret = -EIO;
-       }
-       dummy = ReadDOC(docptr, LastDataRead);
-
-       ops->retlen = len;
-
-       return ret;
-}
-
-int doc_erase (struct mtd_info *mtd, struct erase_info *instr)
-{
-       volatile char dummy;
-       struct DiskOnChip *this = mtd->priv;
-       __u32 ofs = instr->addr;
-       __u32 len = instr->len;
-       void __iomem *docptr = this->virtadr;
-       struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-
-       if (len != mtd->erasesize)
-               printk(KERN_WARNING "Erase not right size (%x != %x)n",
-                      len, mtd->erasesize);
-
-       /* Find the chip which is to be used and select it */
-       if (this->curfloor != mychip->floor) {
-               DoC_SelectFloor(docptr, mychip->floor);
-               DoC_SelectChip(docptr, mychip->chip);
-       } else if (this->curchip != mychip->chip) {
-               DoC_SelectChip(docptr, mychip->chip);
-       }
-       this->curfloor = mychip->floor;
-       this->curchip = mychip->chip;
-
-       instr->state = MTD_ERASE_PENDING;
-
-       /* issue the Erase Setup command */
-       DoC_Command(docptr, NAND_CMD_ERASE1, 0x00);
-       DoC_Address(docptr, 2, ofs, 0x00, 0x00);
-
-       /* Commit the Erase Start command and wait for ready
-          see Software Requirement 11.4 item 1.*/
-       DoC_Command(docptr, NAND_CMD_ERASE2, 0x00);
-       DoC_WaitReady(docptr);
-
-       instr->state = MTD_ERASING;
-
-       /* Read the status of the flash device through CDSN IO register
-          see Software Requirement 11.4 item 5.
-          FIXME: it seems that we are not wait long enough, some blocks are not
-          erased fully */
-       DoC_Command(docptr, NAND_CMD_STATUS, CDSN_CTRL_WP);
-       dummy = ReadDOC(docptr, ReadPipeInit);
-       DoC_Delay(docptr, 2);
-       if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
-               printk("Error Erasing at 0x%x\n", ofs);
-               /* There was an error
-                  FIXME: implement Bad Block Replacement (in nftl.c ??) */
-               instr->state = MTD_ERASE_FAILED;
-       } else
-               instr->state = MTD_ERASE_DONE;
-       dummy = ReadDOC(docptr, LastDataRead);
-
-       mtd_erase_callback(instr);
-
-       return 0;
-}
-
-/****************************************************************************
- *
- * Module stuff
- *
- ****************************************************************************/
-
-static void __exit cleanup_doc2001(void)
-{
-       struct mtd_info *mtd;
-       struct DiskOnChip *this;
-
-       while ((mtd=docmillist)) {
-               this = mtd->priv;
-               docmillist = this->nextdoc;
-
-               mtd_device_unregister(mtd);
-
-               iounmap(this->virtadr);
-               kfree(this->chips);
-               kfree(mtd);
-       }
-}
-
-module_exit(cleanup_doc2001);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
-MODULE_DESCRIPTION("Alternative driver for DiskOnChip Millennium");
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
deleted file mode 100644 (file)
index 4f2220a..0000000
+++ /dev/null
@@ -1,1080 +0,0 @@
-/*
- * Linux driver for Disk-On-Chip Millennium Plus
- *
- * (c) 2002-2003 Greg Ungerer <gerg@snapgear.com>
- * (c) 2002-2003 SnapGear Inc
- * (c) 1999 Machine Vision Holdings, Inc.
- * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
- *
- * Released under GPL
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/bitops.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/doc2000.h>
-
-/* #define ECC_DEBUG */
-
-/* I have no idea why some DoC chips can not use memcop_form|to_io().
- * This may be due to the different revisions of the ASIC controller built-in or
- * simplily a QA/Bug issue. Who knows ?? If you have trouble, please uncomment
- * this:*/
-#undef USE_MEMCPY
-
-static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
-               size_t *retlen, u_char *buf);
-static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
-               size_t *retlen, const u_char *buf);
-static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
-                       struct mtd_oob_ops *ops);
-static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
-                        struct mtd_oob_ops *ops);
-static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
-
-static struct mtd_info *docmilpluslist = NULL;
-
-
-/* Perform the required delay cycles by writing to the NOP register */
-static void DoC_Delay(void __iomem * docptr, int cycles)
-{
-       int i;
-
-       for (i = 0; (i < cycles); i++)
-               WriteDOC(0, docptr, Mplus_NOP);
-}
-
-#define        CDSN_CTRL_FR_B_MASK     (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1)
-
-/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
-static int _DoC_WaitReady(void __iomem * docptr)
-{
-       unsigned int c = 0xffff;
-
-       pr_debug("_DoC_WaitReady called for out-of-line wait\n");
-
-       /* Out-of-line routine to wait for chip response */
-       while (((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) && --c)
-               ;
-
-       if (c == 0)
-               pr_debug("_DoC_WaitReady timed out.\n");
-
-       return (c == 0);
-}
-
-static inline int DoC_WaitReady(void __iomem * docptr)
-{
-       /* This is inline, to optimise the common case, where it's ready instantly */
-       int ret = 0;
-
-       /* read form NOP register should be issued prior to the read from CDSNControl
-          see Software Requirement 11.4 item 2. */
-       DoC_Delay(docptr, 4);
-
-       if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK)
-               /* Call the out-of-line routine to wait */
-               ret = _DoC_WaitReady(docptr);
-
-       return ret;
-}
-
-/* For some reason the Millennium Plus seems to occasionally put itself
- * into reset mode. For me this happens randomly, with no pattern that I
- * can detect. M-systems suggest always check this on any block level
- * operation and setting to normal mode if in reset mode.
- */
-static inline void DoC_CheckASIC(void __iomem * docptr)
-{
-       /* Make sure the DoC is in normal mode */
-       if ((ReadDOC(docptr, Mplus_DOCControl) & DOC_MODE_NORMAL) == 0) {
-               WriteDOC((DOC_MODE_NORMAL | DOC_MODE_MDWREN), docptr, Mplus_DOCControl);
-               WriteDOC(~(DOC_MODE_NORMAL | DOC_MODE_MDWREN), docptr, Mplus_CtrlConfirm);
-       }
-}
-
-/* DoC_Command: Send a flash command to the flash chip through the Flash
- * command register. Need 2 Write Pipeline Terminates to complete send.
- */
-static void DoC_Command(void __iomem * docptr, unsigned char command,
-                              unsigned char xtraflags)
-{
-       WriteDOC(command, docptr, Mplus_FlashCmd);
-       WriteDOC(command, docptr, Mplus_WritePipeTerm);
-       WriteDOC(command, docptr, Mplus_WritePipeTerm);
-}
-
-/* DoC_Address: Set the current address for the flash chip through the Flash
- * Address register. Need 2 Write Pipeline Terminates to complete send.
- */
-static inline void DoC_Address(struct DiskOnChip *doc, int numbytes,
-                              unsigned long ofs, unsigned char xtraflags1,
-                              unsigned char xtraflags2)
-{
-       void __iomem * docptr = doc->virtadr;
-
-       /* Allow for possible Mill Plus internal flash interleaving */
-       ofs >>= doc->interleave;
-
-       switch (numbytes) {
-       case 1:
-               /* Send single byte, bits 0-7. */
-               WriteDOC(ofs & 0xff, docptr, Mplus_FlashAddress);
-               break;
-       case 2:
-               /* Send bits 9-16 followed by 17-23 */
-               WriteDOC((ofs >> 9)  & 0xff, docptr, Mplus_FlashAddress);
-               WriteDOC((ofs >> 17) & 0xff, docptr, Mplus_FlashAddress);
-               break;
-       case 3:
-               /* Send 0-7, 9-16, then 17-23 */
-               WriteDOC(ofs & 0xff, docptr, Mplus_FlashAddress);
-               WriteDOC((ofs >> 9)  & 0xff, docptr, Mplus_FlashAddress);
-               WriteDOC((ofs >> 17) & 0xff, docptr, Mplus_FlashAddress);
-               break;
-       default:
-               return;
-       }
-
-       WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-       WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-}
-
-/* DoC_SelectChip: Select a given flash chip within the current floor */
-static int DoC_SelectChip(void __iomem * docptr, int chip)
-{
-       /* No choice for flash chip on Millennium Plus */
-       return 0;
-}
-
-/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
-static int DoC_SelectFloor(void __iomem * docptr, int floor)
-{
-       WriteDOC((floor & 0x3), docptr, Mplus_DeviceSelect);
-       return 0;
-}
-
-/*
- * Translate the given offset into the appropriate command and offset.
- * This does the mapping using the 16bit interleave layout defined by
- * M-Systems, and looks like this for a sector pair:
- *  +-----------+-------+-------+-------+--------------+---------+-----------+
- *  | 0 --- 511 |512-517|518-519|520-521| 522 --- 1033 |1034-1039|1040 - 1055|
- *  +-----------+-------+-------+-------+--------------+---------+-----------+
- *  | Data 0    | ECC 0 |Flags0 |Flags1 | Data 1       |ECC 1    | OOB 1 + 2 |
- *  +-----------+-------+-------+-------+--------------+---------+-----------+
- */
-/* FIXME: This lives in INFTL not here. Other users of flash devices
-   may not want it */
-static unsigned int DoC_GetDataOffset(struct mtd_info *mtd, loff_t *from)
-{
-       struct DiskOnChip *this = mtd->priv;
-
-       if (this->interleave) {
-               unsigned int ofs = *from & 0x3ff;
-               unsigned int cmd;
-
-               if (ofs < 512) {
-                       cmd = NAND_CMD_READ0;
-                       ofs &= 0x1ff;
-               } else if (ofs < 1014) {
-                       cmd = NAND_CMD_READ1;
-                       ofs = (ofs & 0x1ff) + 10;
-               } else {
-                       cmd = NAND_CMD_READOOB;
-                       ofs = ofs - 1014;
-               }
-
-               *from = (*from & ~0x3ff) | ofs;
-               return cmd;
-       } else {
-               /* No interleave */
-               if ((*from) & 0x100)
-                       return NAND_CMD_READ1;
-               return NAND_CMD_READ0;
-       }
-}
-
-static unsigned int DoC_GetECCOffset(struct mtd_info *mtd, loff_t *from)
-{
-       unsigned int ofs, cmd;
-
-       if (*from & 0x200) {
-               cmd = NAND_CMD_READOOB;
-               ofs = 10 + (*from & 0xf);
-       } else {
-               cmd = NAND_CMD_READ1;
-               ofs = (*from & 0xf);
-       }
-
-       *from = (*from & ~0x3ff) | ofs;
-       return cmd;
-}
-
-static unsigned int DoC_GetFlagsOffset(struct mtd_info *mtd, loff_t *from)
-{
-       unsigned int ofs, cmd;
-
-       cmd = NAND_CMD_READ1;
-       ofs = (*from & 0x200) ? 8 : 6;
-       *from = (*from & ~0x3ff) | ofs;
-       return cmd;
-}
-
-static unsigned int DoC_GetHdrOffset(struct mtd_info *mtd, loff_t *from)
-{
-       unsigned int ofs, cmd;
-
-       cmd = NAND_CMD_READOOB;
-       ofs = (*from & 0x200) ? 24 : 16;
-       *from = (*from & ~0x3ff) | ofs;
-       return cmd;
-}
-
-static inline void MemReadDOC(void __iomem * docptr, unsigned char *buf, int len)
-{
-#ifndef USE_MEMCPY
-       int i;
-       for (i = 0; i < len; i++)
-               buf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
-#else
-       memcpy_fromio(buf, docptr + DoC_Mil_CDSN_IO, len);
-#endif
-}
-
-static inline void MemWriteDOC(void __iomem * docptr, unsigned char *buf, int len)
-{
-#ifndef USE_MEMCPY
-       int i;
-       for (i = 0; i < len; i++)
-               WriteDOC(buf[i], docptr, Mil_CDSN_IO + i);
-#else
-       memcpy_toio(docptr + DoC_Mil_CDSN_IO, buf, len);
-#endif
-}
-
-/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
-static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
-{
-       int mfr, id, i, j;
-       volatile char dummy;
-       void __iomem * docptr = doc->virtadr;
-
-       /* Page in the required floor/chip */
-       DoC_SelectFloor(docptr, floor);
-       DoC_SelectChip(docptr, chip);
-
-       /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-       WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);
-
-       /* Reset the chip, see Software Requirement 11.4 item 1. */
-       DoC_Command(docptr, NAND_CMD_RESET, 0);
-       DoC_WaitReady(docptr);
-
-       /* Read the NAND chip ID: 1. Send ReadID command */
-       DoC_Command(docptr, NAND_CMD_READID, 0);
-
-       /* Read the NAND chip ID: 2. Send address byte zero */
-       DoC_Address(doc, 1, 0x00, 0, 0x00);
-
-       WriteDOC(0, docptr, Mplus_FlashControl);
-       DoC_WaitReady(docptr);
-
-       /* Read the manufacturer and device id codes of the flash device through
-          CDSN IO register see Software Requirement 11.4 item 5.*/
-       dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-       dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-
-       mfr = ReadDOC(docptr, Mil_CDSN_IO);
-       if (doc->interleave)
-               dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */
-
-       id  = ReadDOC(docptr, Mil_CDSN_IO);
-       if (doc->interleave)
-               dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */
-
-       dummy = ReadDOC(docptr, Mplus_LastDataRead);
-       dummy = ReadDOC(docptr, Mplus_LastDataRead);
-
-       /* Disable flash internally */
-       WriteDOC(0, docptr, Mplus_FlashSelect);
-
-       /* No response - return failure */
-       if (mfr == 0xff || mfr == 0)
-               return 0;
-
-       for (i = 0; nand_flash_ids[i].name != NULL; i++) {
-               if (id == nand_flash_ids[i].id) {
-                       /* Try to identify manufacturer */
-                       for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
-                               if (nand_manuf_ids[j].id == mfr)
-                                       break;
-                       }
-                       printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, "
-                              "Chip ID: %2.2X (%s:%s)\n", mfr, id,
-                              nand_manuf_ids[j].name, nand_flash_ids[i].name);
-                       doc->mfr = mfr;
-                       doc->id = id;
-                       doc->chipshift = ffs((nand_flash_ids[i].chipsize << 20)) - 1;
-                       doc->erasesize = nand_flash_ids[i].erasesize << doc->interleave;
-                       break;
-               }
-       }
-
-       if (nand_flash_ids[i].name == NULL)
-               return 0;
-       return 1;
-}
-
-/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
-static void DoC_ScanChips(struct DiskOnChip *this)
-{
-       int floor, chip;
-       int numchips[MAX_FLOORS_MPLUS];
-       int ret;
-
-       this->numchips = 0;
-       this->mfr = 0;
-       this->id = 0;
-
-       /* Work out the intended interleave setting */
-       this->interleave = 0;
-       if (this->ChipID == DOC_ChipID_DocMilPlus32)
-               this->interleave = 1;
-
-       /* Check the ASIC agrees */
-       if ( (this->interleave << 2) !=
-            (ReadDOC(this->virtadr, Mplus_Configuration) & 4)) {
-               u_char conf = ReadDOC(this->virtadr, Mplus_Configuration);
-               printk(KERN_NOTICE "Setting DiskOnChip Millennium Plus interleave to %s\n",
-                      this->interleave?"on (16-bit)":"off (8-bit)");
-               conf ^= 4;
-               WriteDOC(conf, this->virtadr, Mplus_Configuration);
-       }
-
-       /* For each floor, find the number of valid chips it contains */
-       for (floor = 0,ret = 1; floor < MAX_FLOORS_MPLUS; floor++) {
-               numchips[floor] = 0;
-               for (chip = 0; chip < MAX_CHIPS_MPLUS && ret != 0; chip++) {
-                       ret = DoC_IdentChip(this, floor, chip);
-                       if (ret) {
-                               numchips[floor]++;
-                               this->numchips++;
-                       }
-               }
-       }
-       /* If there are none at all that we recognise, bail */
-       if (!this->numchips) {
-               printk("No flash chips recognised.\n");
-               return;
-       }
-
-       /* Allocate an array to hold the information for each chip */
-       this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL);
-       if (!this->chips){
-               printk("MTD: No memory for allocating chip info structures\n");
-               return;
-       }
-
-       /* Fill out the chip array with {floor, chipno} for each
-        * detected chip in the device. */
-       for (floor = 0, ret = 0; floor < MAX_FLOORS_MPLUS; floor++) {
-               for (chip = 0 ; chip < numchips[floor] ; chip++) {
-                       this->chips[ret].floor = floor;
-                       this->chips[ret].chip = chip;
-                       this->chips[ret].curadr = 0;
-                       this->chips[ret].curmode = 0x50;
-                       ret++;
-               }
-       }
-
-       /* Calculate and print the total size of the device */
-       this->totlen = this->numchips * (1 << this->chipshift);
-       printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld MiB\n",
-              this->numchips ,this->totlen >> 20);
-}
-
-static int DoCMilPlus_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
-{
-       int tmp1, tmp2, retval;
-
-       if (doc1->physadr == doc2->physadr)
-               return 1;
-
-       /* Use the alias resolution register which was set aside for this
-        * purpose. If it's value is the same on both chips, they might
-        * be the same chip, and we write to one and check for a change in
-        * the other. It's unclear if this register is usuable in the
-        * DoC 2000 (it's in the Millennium docs), but it seems to work. */
-       tmp1 = ReadDOC(doc1->virtadr, Mplus_AliasResolution);
-       tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
-       if (tmp1 != tmp2)
-               return 0;
-
-       WriteDOC((tmp1+1) % 0xff, doc1->virtadr, Mplus_AliasResolution);
-       tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
-       if (tmp2 == (tmp1+1) % 0xff)
-               retval = 1;
-       else
-               retval = 0;
-
-       /* Restore register contents.  May not be necessary, but do it just to
-        * be safe. */
-       WriteDOC(tmp1, doc1->virtadr, Mplus_AliasResolution);
-
-       return retval;
-}
-
-/* This routine is found from the docprobe code by symbol_get(),
- * which will bump the use count of this module. */
-void DoCMilPlus_init(struct mtd_info *mtd)
-{
-       struct DiskOnChip *this = mtd->priv;
-       struct DiskOnChip *old = NULL;
-
-       /* We must avoid being called twice for the same device. */
-       if (docmilpluslist)
-               old = docmilpluslist->priv;
-
-       while (old) {
-               if (DoCMilPlus_is_alias(this, old)) {
-                       printk(KERN_NOTICE "Ignoring DiskOnChip Millennium "
-                               "Plus at 0x%lX - already configured\n",
-                               this->physadr);
-                       iounmap(this->virtadr);
-                       kfree(mtd);
-                       return;
-               }
-               if (old->nextdoc)
-                       old = old->nextdoc->priv;
-               else
-                       old = NULL;
-       }
-
-       mtd->name = "DiskOnChip Millennium Plus";
-       printk(KERN_NOTICE "DiskOnChip Millennium Plus found at "
-               "address 0x%lX\n", this->physadr);
-
-       mtd->type = MTD_NANDFLASH;
-       mtd->flags = MTD_CAP_NANDFLASH;
-       mtd->writebufsize = mtd->writesize = 512;
-       mtd->oobsize = 16;
-       mtd->ecc_strength = 2;
-       mtd->owner = THIS_MODULE;
-       mtd->_erase = doc_erase;
-       mtd->_read = doc_read;
-       mtd->_write = doc_write;
-       mtd->_read_oob = doc_read_oob;
-       mtd->_write_oob = doc_write_oob;
-       this->curfloor = -1;
-       this->curchip = -1;
-
-       /* Ident all the chips present. */
-       DoC_ScanChips(this);
-
-       if (!this->totlen) {
-               kfree(mtd);
-               iounmap(this->virtadr);
-       } else {
-               this->nextdoc = docmilpluslist;
-               docmilpluslist = mtd;
-               mtd->size  = this->totlen;
-               mtd->erasesize = this->erasesize;
-               mtd_device_register(mtd, NULL, 0);
-               return;
-       }
-}
-EXPORT_SYMBOL_GPL(DoCMilPlus_init);
-
-#if 0
-static int doc_dumpblk(struct mtd_info *mtd, loff_t from)
-{
-       int i;
-       loff_t fofs;
-       struct DiskOnChip *this = mtd->priv;
-       void __iomem * docptr = this->virtadr;
-       struct Nand *mychip = &this->chips[from >> (this->chipshift)];
-       unsigned char *bp, buf[1056];
-       char c[32];
-
-       from &= ~0x3ff;
-
-       /* Don't allow read past end of device */
-       if (from >= this->totlen)
-               return -EINVAL;
-
-       DoC_CheckASIC(docptr);
-
-       /* Find the chip which is to be used and select it */
-       if (this->curfloor != mychip->floor) {
-               DoC_SelectFloor(docptr, mychip->floor);
-               DoC_SelectChip(docptr, mychip->chip);
-       } else if (this->curchip != mychip->chip) {
-               DoC_SelectChip(docptr, mychip->chip);
-       }
-       this->curfloor = mychip->floor;
-       this->curchip = mychip->chip;
-
-       /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-       WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);
-
-       /* Reset the chip, see Software Requirement 11.4 item 1. */
-       DoC_Command(docptr, NAND_CMD_RESET, 0);
-       DoC_WaitReady(docptr);
-
-       fofs = from;
-       DoC_Command(docptr, DoC_GetDataOffset(mtd, &fofs), 0);
-       DoC_Address(this, 3, fofs, 0, 0x00);
-       WriteDOC(0, docptr, Mplus_FlashControl);
-       DoC_WaitReady(docptr);
-
-       /* disable the ECC engine */
-       WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-
-       ReadDOC(docptr, Mplus_ReadPipeInit);
-       ReadDOC(docptr, Mplus_ReadPipeInit);
-
-       /* Read the data via the internal pipeline through CDSN IO
-          register, see Pipelined Read Operations 11.3 */
-       MemReadDOC(docptr, buf, 1054);
-       buf[1054] = ReadDOC(docptr, Mplus_LastDataRead);
-       buf[1055] = ReadDOC(docptr, Mplus_LastDataRead);
-
-       memset(&c[0], 0, sizeof(c));
-       printk("DUMP OFFSET=%x:\n", (int)from);
-
-        for (i = 0, bp = &buf[0]; (i < 1056); i++) {
-                if ((i % 16) == 0)
-                        printk("%08x: ", i);
-                printk(" %02x", *bp);
-                c[(i & 0xf)] = ((*bp >= 0x20) && (*bp <= 0x7f)) ? *bp : '.';
-                bp++;
-                if (((i + 1) % 16) == 0)
-                        printk("    %s\n", c);
-        }
-       printk("\n");
-
-       /* Disable flash internally */
-       WriteDOC(0, docptr, Mplus_FlashSelect);
-
-       return 0;
-}
-#endif
-
-static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
-                   size_t *retlen, u_char *buf)
-{
-       int ret, i;
-       volatile char dummy;
-       loff_t fofs;
-       unsigned char syndrome[6], eccbuf[6];
-       struct DiskOnChip *this = mtd->priv;
-       void __iomem * docptr = this->virtadr;
-       struct Nand *mychip = &this->chips[from >> (this->chipshift)];
-
-       /* Don't allow a single read to cross a 512-byte block boundary */
-       if (from + len > ((from | 0x1ff) + 1))
-               len = ((from | 0x1ff) + 1) - from;
-
-       DoC_CheckASIC(docptr);
-
-       /* Find the chip which is to be used and select it */
-       if (this->curfloor != mychip->floor) {
-               DoC_SelectFloor(docptr, mychip->floor);
-               DoC_SelectChip(docptr, mychip->chip);
-       } else if (this->curchip != mychip->chip) {
-               DoC_SelectChip(docptr, mychip->chip);
-       }
-       this->curfloor = mychip->floor;
-       this->curchip = mychip->chip;
-
-       /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-       WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);
-
-       /* Reset the chip, see Software Requirement 11.4 item 1. */
-       DoC_Command(docptr, NAND_CMD_RESET, 0);
-       DoC_WaitReady(docptr);
-
-       fofs = from;
-       DoC_Command(docptr, DoC_GetDataOffset(mtd, &fofs), 0);
-       DoC_Address(this, 3, fofs, 0, 0x00);
-       WriteDOC(0, docptr, Mplus_FlashControl);
-       DoC_WaitReady(docptr);
-
-       /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
-       WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-       WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);
-
-       /* Let the caller know we completed it */
-       *retlen = len;
-       ret = 0;
-
-       ReadDOC(docptr, Mplus_ReadPipeInit);
-       ReadDOC(docptr, Mplus_ReadPipeInit);
-
-       /* Read the data via the internal pipeline through CDSN IO
-          register, see Pipelined Read Operations 11.3 */
-       MemReadDOC(docptr, buf, len);
-
-       /* Read the ECC data following raw data */
-       MemReadDOC(docptr, eccbuf, 4);
-       eccbuf[4] = ReadDOC(docptr, Mplus_LastDataRead);
-       eccbuf[5] = ReadDOC(docptr, Mplus_LastDataRead);
-
-       /* Flush the pipeline */
-       dummy = ReadDOC(docptr, Mplus_ECCConf);
-       dummy = ReadDOC(docptr, Mplus_ECCConf);
-
-       /* Check the ECC Status */
-       if (ReadDOC(docptr, Mplus_ECCConf) & 0x80) {
-               int nb_errors;
-               /* There was an ECC error */
-#ifdef ECC_DEBUG
-               printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
-#endif
-               /* Read the ECC syndrome through the DiskOnChip ECC logic.
-                  These syndrome will be all ZERO when there is no error */
-               for (i = 0; i < 6; i++)
-                       syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
-
-               nb_errors = doc_decode_ecc(buf, syndrome);
-#ifdef ECC_DEBUG
-               printk("ECC Errors corrected: %x\n", nb_errors);
-#endif
-               if (nb_errors < 0) {
-                       /* We return error, but have actually done the
-                          read. Not that this can be told to user-space, via
-                          sys_read(), but at least MTD-aware stuff can know
-                          about it by checking *retlen */
-#ifdef ECC_DEBUG
-                       printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n",
-                               __FILE__, __LINE__, (int)from);
-                       printk("        syndrome= %*phC\n", 6, syndrome);
-                       printk("        eccbuf= %*phC\n", 6, eccbuf);
-#endif
-                               ret = -EIO;
-               }
-       }
-
-#ifdef PSYCHO_DEBUG
-       printk("ECC DATA at %lx: %*ph\n", (long)from, 6, eccbuf);
-#endif
-       /* disable the ECC engine */
-       WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf);
-
-       /* Disable flash internally */
-       WriteDOC(0, docptr, Mplus_FlashSelect);
-
-       return ret;
-}
-
-static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
-                    size_t *retlen, const u_char *buf)
-{
-       int i, before, ret = 0;
-       loff_t fto;
-       volatile char dummy;
-       char eccbuf[6];
-       struct DiskOnChip *this = mtd->priv;
-       void __iomem * docptr = this->virtadr;
-       struct Nand *mychip = &this->chips[to >> (this->chipshift)];
-
-       /* Don't allow writes which aren't exactly one block (512 bytes) */
-       if ((to & 0x1ff) || (len != 0x200))
-               return -EINVAL;
-
-       /* Determine position of OOB flags, before or after data */
-       before = (this->interleave && (to & 0x200));
-
-       DoC_CheckASIC(docptr);
-
-       /* Find the chip which is to be used and select it */
-       if (this->curfloor != mychip->floor) {
-               DoC_SelectFloor(docptr, mychip->floor);
-               DoC_SelectChip(docptr, mychip->chip);
-       } else if (this->curchip != mychip->chip) {
-               DoC_SelectChip(docptr, mychip->chip);
-       }
-       this->curfloor = mychip->floor;
-       this->curchip = mychip->chip;
-
-       /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-       WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);
-
-       /* Reset the chip, see Software Requirement 11.4 item 1. */
-       DoC_Command(docptr, NAND_CMD_RESET, 0);
-       DoC_WaitReady(docptr);
-
-       /* Set device to appropriate plane of flash */
-       fto = to;
-       WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd);
-
-       /* On interleaved devices the flags for 2nd half 512 are before data */
-       if (before)
-               fto -= 2;
-
-       /* issue the Serial Data In command to initial the Page Program process */
-       DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
-       DoC_Address(this, 3, fto, 0x00, 0x00);
-
-       /* Disable the ECC engine */
-       WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-
-       if (before) {
-               /* Write the block status BLOCK_USED (0x5555) */
-               WriteDOC(0x55, docptr, Mil_CDSN_IO);
-               WriteDOC(0x55, docptr, Mil_CDSN_IO);
-       }
-
-       /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
-       WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);
-
-       MemWriteDOC(docptr, (unsigned char *) buf, len);
-
-       /* Write ECC data to flash, the ECC info is generated by
-          the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */
-       DoC_Delay(docptr, 3);
-
-       /* Read the ECC data through the DiskOnChip ECC logic */
-       for (i = 0; i < 6; i++)
-               eccbuf[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
-
-       /* disable the ECC engine */
-       WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
-
-       /* Write the ECC data to flash */
-       MemWriteDOC(docptr, eccbuf, 6);
-
-       if (!before) {
-               /* Write the block status BLOCK_USED (0x5555) */
-               WriteDOC(0x55, docptr, Mil_CDSN_IO+6);
-               WriteDOC(0x55, docptr, Mil_CDSN_IO+7);
-       }
-
-#ifdef PSYCHO_DEBUG
-       printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
-              (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
-              eccbuf[4], eccbuf[5]);
-#endif
-
-       WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-       WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-
-       /* Commit the Page Program command and wait for ready
-          see Software Requirement 11.4 item 1.*/
-       DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
-       DoC_WaitReady(docptr);
-
-       /* Read the status of the flash device through CDSN IO register
-          see Software Requirement 11.4 item 5.*/
-       DoC_Command(docptr, NAND_CMD_STATUS, 0);
-       dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-       dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-       DoC_Delay(docptr, 2);
-       if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
-               printk("MTD: Error 0x%x programming at 0x%x\n", dummy, (int)to);
-               /* Error in programming
-                  FIXME: implement Bad Block Replacement (in nftl.c ??) */
-               ret = -EIO;
-       }
-       dummy = ReadDOC(docptr, Mplus_LastDataRead);
-
-       /* Disable flash internally */
-       WriteDOC(0, docptr, Mplus_FlashSelect);
-
-       /* Let the caller know we completed it */
-       *retlen = len;
-
-       return ret;
-}
-
-static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
-                       struct mtd_oob_ops *ops)
-{
-       loff_t fofs, base;
-       struct DiskOnChip *this = mtd->priv;
-       void __iomem * docptr = this->virtadr;
-       struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-       size_t i, size, got, want;
-       uint8_t *buf = ops->oobbuf;
-       size_t len = ops->len;
-
-       BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
-
-       ofs += ops->ooboffs;
-
-       DoC_CheckASIC(docptr);
-
-       /* Find the chip which is to be used and select it */
-       if (this->curfloor != mychip->floor) {
-               DoC_SelectFloor(docptr, mychip->floor);
-               DoC_SelectChip(docptr, mychip->chip);
-       } else if (this->curchip != mychip->chip) {
-               DoC_SelectChip(docptr, mychip->chip);
-       }
-       this->curfloor = mychip->floor;
-       this->curchip = mychip->chip;
-
-       /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-       WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);
-
-       /* disable the ECC engine */
-       WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-       DoC_WaitReady(docptr);
-
-       /* Maximum of 16 bytes in the OOB region, so limit read to that */
-       if (len > 16)
-               len = 16;
-       got = 0;
-       want = len;
-
-       for (i = 0; ((i < 3) && (want > 0)); i++) {
-               /* Figure out which region we are accessing... */
-               fofs = ofs;
-               base = ofs & 0xf;
-               if (!this->interleave) {
-                       DoC_Command(docptr, NAND_CMD_READOOB, 0);
-                       size = 16 - base;
-               } else if (base < 6) {
-                       DoC_Command(docptr, DoC_GetECCOffset(mtd, &fofs), 0);
-                       size = 6 - base;
-               } else if (base < 8) {
-                       DoC_Command(docptr, DoC_GetFlagsOffset(mtd, &fofs), 0);
-                       size = 8 - base;
-               } else {
-                       DoC_Command(docptr, DoC_GetHdrOffset(mtd, &fofs), 0);
-                       size = 16 - base;
-               }
-               if (size > want)
-                       size = want;
-
-               /* Issue read command */
-               DoC_Address(this, 3, fofs, 0, 0x00);
-               WriteDOC(0, docptr, Mplus_FlashControl);
-               DoC_WaitReady(docptr);
-
-               ReadDOC(docptr, Mplus_ReadPipeInit);
-               ReadDOC(docptr, Mplus_ReadPipeInit);
-               MemReadDOC(docptr, &buf[got], size - 2);
-               buf[got + size - 2] = ReadDOC(docptr, Mplus_LastDataRead);
-               buf[got + size - 1] = ReadDOC(docptr, Mplus_LastDataRead);
-
-               ofs += size;
-               got += size;
-               want -= size;
-       }
-
-       /* Disable flash internally */
-       WriteDOC(0, docptr, Mplus_FlashSelect);
-
-       ops->retlen = len;
-       return 0;
-}
-
-static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
-                        struct mtd_oob_ops *ops)
-{
-       volatile char dummy;
-       loff_t fofs, base;
-       struct DiskOnChip *this = mtd->priv;
-       void __iomem * docptr = this->virtadr;
-       struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-       size_t i, size, got, want;
-       int ret = 0;
-       uint8_t *buf = ops->oobbuf;
-       size_t len = ops->len;
-
-       BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
-
-       ofs += ops->ooboffs;
-
-       DoC_CheckASIC(docptr);
-
-       /* Find the chip which is to be used and select it */
-       if (this->curfloor != mychip->floor) {
-               DoC_SelectFloor(docptr, mychip->floor);
-               DoC_SelectChip(docptr, mychip->chip);
-       } else if (this->curchip != mychip->chip) {
-               DoC_SelectChip(docptr, mychip->chip);
-       }
-       this->curfloor = mychip->floor;
-       this->curchip = mychip->chip;
-
-       /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-       WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);
-
-
-       /* Maximum of 16 bytes in the OOB region, so limit write to that */
-       if (len > 16)
-               len = 16;
-       got = 0;
-       want = len;
-
-       for (i = 0; ((i < 3) && (want > 0)); i++) {
-               /* Reset the chip, see Software Requirement 11.4 item 1. */
-               DoC_Command(docptr, NAND_CMD_RESET, 0);
-               DoC_WaitReady(docptr);
-
-               /* Figure out which region we are accessing... */
-               fofs = ofs;
-               base = ofs & 0x0f;
-               if (!this->interleave) {
-                       WriteDOC(NAND_CMD_READOOB, docptr, Mplus_FlashCmd);
-                       size = 16 - base;
-               } else if (base < 6) {
-                       WriteDOC(DoC_GetECCOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
-                       size = 6 - base;
-               } else if (base < 8) {
-                       WriteDOC(DoC_GetFlagsOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
-                       size = 8 - base;
-               } else {
-                       WriteDOC(DoC_GetHdrOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
-                       size = 16 - base;
-               }
-               if (size > want)
-                       size = want;
-
-               /* Issue the Serial Data In command to initial the Page Program process */
-               DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
-               DoC_Address(this, 3, fofs, 0, 0x00);
-
-               /* Disable the ECC engine */
-               WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-
-               /* Write the data via the internal pipeline through CDSN IO
-                  register, see Pipelined Write Operations 11.2 */
-               MemWriteDOC(docptr, (unsigned char *) &buf[got], size);
-               WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-               WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-
-               /* Commit the Page Program command and wait for ready
-                  see Software Requirement 11.4 item 1.*/
-               DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
-               DoC_WaitReady(docptr);
-
-               /* Read the status of the flash device through CDSN IO register
-                  see Software Requirement 11.4 item 5.*/
-               DoC_Command(docptr, NAND_CMD_STATUS, 0x00);
-               dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-               dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-               DoC_Delay(docptr, 2);
-               if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
-                       printk("MTD: Error 0x%x programming oob at 0x%x\n",
-                               dummy, (int)ofs);
-                       /* FIXME: implement Bad Block Replacement */
-                       ops->retlen = 0;
-                       ret = -EIO;
-               }
-               dummy = ReadDOC(docptr, Mplus_LastDataRead);
-
-               ofs += size;
-               got += size;
-               want -= size;
-       }
-
-       /* Disable flash internally */
-       WriteDOC(0, docptr, Mplus_FlashSelect);
-
-       ops->retlen = len;
-       return ret;
-}
-
-int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
-{
-       volatile char dummy;
-       struct DiskOnChip *this = mtd->priv;
-       __u32 ofs = instr->addr;
-       __u32 len = instr->len;
-       void __iomem * docptr = this->virtadr;
-       struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-
-       DoC_CheckASIC(docptr);
-
-       if (len != mtd->erasesize)
-               printk(KERN_WARNING "MTD: Erase not right size (%x != %x)n",
-                      len, mtd->erasesize);
-
-       /* Find the chip which is to be used and select it */
-       if (this->curfloor != mychip->floor) {
-               DoC_SelectFloor(docptr, mychip->floor);
-               DoC_SelectChip(docptr, mychip->chip);
-       } else if (this->curchip != mychip->chip) {
-               DoC_SelectChip(docptr, mychip->chip);
-       }
-       this->curfloor = mychip->floor;
-       this->curchip = mychip->chip;
-
-       instr->state = MTD_ERASE_PENDING;
-
-       /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-       WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);
-
-       DoC_Command(docptr, NAND_CMD_RESET, 0x00);
-       DoC_WaitReady(docptr);
-
-       DoC_Command(docptr, NAND_CMD_ERASE1, 0);
-       DoC_Address(this, 2, ofs, 0, 0x00);
-       DoC_Command(docptr, NAND_CMD_ERASE2, 0);
-       DoC_WaitReady(docptr);
-       instr->state = MTD_ERASING;
-
-       /* Read the status of the flash device through CDSN IO register
-          see Software Requirement 11.4 item 5. */
-       DoC_Command(docptr, NAND_CMD_STATUS, 0);
-       dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-       dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-       if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
-               printk("MTD: Error 0x%x erasing at 0x%x\n", dummy, ofs);
-               /* FIXME: implement Bad Block Replacement (in nftl.c ??) */
-               instr->state = MTD_ERASE_FAILED;
-       } else {
-               instr->state = MTD_ERASE_DONE;
-       }
-       dummy = ReadDOC(docptr, Mplus_LastDataRead);
-
-       /* Disable flash internally */
-       WriteDOC(0, docptr, Mplus_FlashSelect);
-
-       mtd_erase_callback(instr);
-
-       return 0;
-}
-
-/****************************************************************************
- *
- * Module stuff
- *
- ****************************************************************************/
-
-static void __exit cleanup_doc2001plus(void)
-{
-       struct mtd_info *mtd;
-       struct DiskOnChip *this;
-
-       while ((mtd=docmilpluslist)) {
-               this = mtd->priv;
-               docmilpluslist = this->nextdoc;
-
-               mtd_device_unregister(mtd);
-
-               iounmap(this->virtadr);
-               kfree(this->chips);
-               kfree(mtd);
-       }
-}
-
-module_exit(cleanup_doc2001plus);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com> et al.");
-MODULE_DESCRIPTION("Driver for DiskOnChip Millennium Plus");
diff --git a/drivers/mtd/devices/docecc.c b/drivers/mtd/devices/docecc.c
deleted file mode 100644 (file)
index 4a1c39b..0000000
+++ /dev/null
@@ -1,521 +0,0 @@
-/*
- * ECC algorithm for M-systems disk on chip. We use the excellent Reed
- * Solmon code of Phil Karn (karn@ka9q.ampr.org) available under the
- * GNU GPL License. The rest is simply to convert the disk on chip
- * syndrome into a standard syndome.
- *
- * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
- * Copyright (C) 2000 Netgem S.A.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/types.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/doc2000.h>
-
-#define DEBUG_ECC 0
-/* need to undef it (from asm/termbits.h) */
-#undef B0
-
-#define MM 10 /* Symbol size in bits */
-#define KK (1023-4) /* Number of data symbols per block */
-#define B0 510 /* First root of generator polynomial, alpha form */
-#define PRIM 1 /* power of alpha used to generate roots of generator poly */
-#define        NN ((1 << MM) - 1)
-
-typedef unsigned short dtype;
-
-/* 1+x^3+x^10 */
-static const int Pp[MM+1] = { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
-
-/* This defines the type used to store an element of the Galois Field
- * used by the code. Make sure this is something larger than a char if
- * if anything larger than GF(256) is used.
- *
- * Note: unsigned char will work up to GF(256) but int seems to run
- * faster on the Pentium.
- */
-typedef int gf;
-
-/* No legal value in index form represents zero, so
- * we need a special value for this purpose
- */
-#define A0     (NN)
-
-/* Compute x % NN, where NN is 2**MM - 1,
- * without a slow divide
- */
-static inline gf
-modnn(int x)
-{
-  while (x >= NN) {
-    x -= NN;
-    x = (x >> MM) + (x & NN);
-  }
-  return x;
-}
-
-#define        CLEAR(a,n) {\
-int ci;\
-for(ci=(n)-1;ci >=0;ci--)\
-(a)[ci] = 0;\
-}
-
-#define        COPY(a,b,n) {\
-int ci;\
-for(ci=(n)-1;ci >=0;ci--)\
-(a)[ci] = (b)[ci];\
-}
-
-#define        COPYDOWN(a,b,n) {\
-int ci;\
-for(ci=(n)-1;ci >=0;ci--)\
-(a)[ci] = (b)[ci];\
-}
-
-#define Ldec 1
-
-/* generate GF(2**m) from the irreducible polynomial p(X) in Pp[0]..Pp[m]
-   lookup tables:  index->polynomial form   alpha_to[] contains j=alpha**i;
-                   polynomial form -> index form  index_of[j=alpha**i] = i
-   alpha=2 is the primitive element of GF(2**m)
-   HARI's COMMENT: (4/13/94) alpha_to[] can be used as follows:
-        Let @ represent the primitive element commonly called "alpha" that
-   is the root of the primitive polynomial p(x). Then in GF(2^m), for any
-   0 <= i <= 2^m-2,
-        @^i = a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1)
-   where the binary vector (a(0),a(1),a(2),...,a(m-1)) is the representation
-   of the integer "alpha_to[i]" with a(0) being the LSB and a(m-1) the MSB. Thus for
-   example the polynomial representation of @^5 would be given by the binary
-   representation of the integer "alpha_to[5]".
-                   Similarly, index_of[] can be used as follows:
-        As above, let @ represent the primitive element of GF(2^m) that is
-   the root of the primitive polynomial p(x). In order to find the power
-   of @ (alpha) that has the polynomial representation
-        a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1)
-   we consider the integer "i" whose binary representation with a(0) being LSB
-   and a(m-1) MSB is (a(0),a(1),...,a(m-1)) and locate the entry
-   "index_of[i]". Now, @^index_of[i] is that element whose polynomial
-    representation is (a(0),a(1),a(2),...,a(m-1)).
-   NOTE:
-        The element alpha_to[2^m-1] = 0 always signifying that the
-   representation of "@^infinity" = 0 is (0,0,0,...,0).
-        Similarly, the element index_of[0] = A0 always signifying
-   that the power of alpha which has the polynomial representation
-   (0,0,...,0) is "infinity".
-
-*/
-
-static void
-generate_gf(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1])
-{
-  register int i, mask;
-
-  mask = 1;
-  Alpha_to[MM] = 0;
-  for (i = 0; i < MM; i++) {
-    Alpha_to[i] = mask;
-    Index_of[Alpha_to[i]] = i;
-    /* If Pp[i] == 1 then, term @^i occurs in poly-repr of @^MM */
-    if (Pp[i] != 0)
-      Alpha_to[MM] ^= mask;    /* Bit-wise EXOR operation */
-    mask <<= 1;        /* single left-shift */
-  }
-  Index_of[Alpha_to[MM]] = MM;
-  /*
-   * Have obtained poly-repr of @^MM. Poly-repr of @^(i+1) is given by
-   * poly-repr of @^i shifted left one-bit and accounting for any @^MM
-   * term that may occur when poly-repr of @^i is shifted.
-   */
-  mask >>= 1;
-  for (i = MM + 1; i < NN; i++) {
-    if (Alpha_to[i - 1] >= mask)
-      Alpha_to[i] = Alpha_to[MM] ^ ((Alpha_to[i - 1] ^ mask) << 1);
-    else
-      Alpha_to[i] = Alpha_to[i - 1] << 1;
-    Index_of[Alpha_to[i]] = i;
-  }
-  Index_of[0] = A0;
-  Alpha_to[NN] = 0;
-}
-
-/*
- * Performs ERRORS+ERASURES decoding of RS codes. bb[] is the content
- * of the feedback shift register after having processed the data and
- * the ECC.
- *
- * Return number of symbols corrected, or -1 if codeword is illegal
- * or uncorrectable. If eras_pos is non-null, the detected error locations
- * are written back. NOTE! This array must be at least NN-KK elements long.
- * The corrected data are written in eras_val[]. They must be xor with the data
- * to retrieve the correct data : data[erase_pos[i]] ^= erase_val[i] .
- *
- * First "no_eras" erasures are declared by the calling program. Then, the
- * maximum # of errors correctable is t_after_eras = floor((NN-KK-no_eras)/2).
- * If the number of channel errors is not greater than "t_after_eras" the
- * transmitted codeword will be recovered. Details of algorithm can be found
- * in R. Blahut's "Theory ... of Error-Correcting Codes".
-
- * Warning: the eras_pos[] array must not contain duplicate entries; decoder failure
- * will result. The decoder *could* check for this condition, but it would involve
- * extra time on every decoding operation.
- * */
-static int
-eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
-            gf bb[NN - KK + 1], gf eras_val[NN-KK], int eras_pos[NN-KK],
-            int no_eras)
-{
-  int deg_lambda, el, deg_omega;
-  int i, j, r,k;
-  gf u,q,tmp,num1,num2,den,discr_r;
-  gf lambda[NN-KK + 1], s[NN-KK + 1];  /* Err+Eras Locator poly
-                                        * and syndrome poly */
-  gf b[NN-KK + 1], t[NN-KK + 1], omega[NN-KK + 1];
-  gf root[NN-KK], reg[NN-KK + 1], loc[NN-KK];
-  int syn_error, count;
-
-  syn_error = 0;
-  for(i=0;i<NN-KK;i++)
-      syn_error |= bb[i];
-
-  if (!syn_error) {
-    /* if remainder is zero, data[] is a codeword and there are no
-     * errors to correct. So return data[] unmodified
-     */
-    count = 0;
-    goto finish;
-  }
-
-  for(i=1;i<=NN-KK;i++){
-    s[i] = bb[0];
-  }
-  for(j=1;j<NN-KK;j++){
-    if(bb[j] == 0)
-      continue;
-    tmp = Index_of[bb[j]];
-
-    for(i=1;i<=NN-KK;i++)
-      s[i] ^= Alpha_to[modnn(tmp + (B0+i-1)*PRIM*j)];
-  }
-
-  /* undo the feedback register implicit multiplication and convert
-     syndromes to index form */
-
-  for(i=1;i<=NN-KK;i++) {
-      tmp = Index_of[s[i]];
-      if (tmp != A0)
-          tmp = modnn(tmp + 2 * KK * (B0+i-1)*PRIM);
-      s[i] = tmp;
-  }
-
-  CLEAR(&lambda[1],NN-KK);
-  lambda[0] = 1;
-
-  if (no_eras > 0) {
-    /* Init lambda to be the erasure locator polynomial */
-    lambda[1] = Alpha_to[modnn(PRIM * eras_pos[0])];
-    for (i = 1; i < no_eras; i++) {
-      u = modnn(PRIM*eras_pos[i]);
-      for (j = i+1; j > 0; j--) {
-       tmp = Index_of[lambda[j - 1]];
-       if(tmp != A0)
-         lambda[j] ^= Alpha_to[modnn(u + tmp)];
-      }
-    }
-#if DEBUG_ECC >= 1
-    /* Test code that verifies the erasure locator polynomial just constructed
-       Needed only for decoder debugging. */
-
-    /* find roots of the erasure location polynomial */
-    for(i=1;i<=no_eras;i++)
-      reg[i] = Index_of[lambda[i]];
-    count = 0;
-    for (i = 1,k=NN-Ldec; i <= NN; i++,k = modnn(NN+k-Ldec)) {
-      q = 1;
-      for (j = 1; j <= no_eras; j++)
-       if (reg[j] != A0) {
-         reg[j] = modnn(reg[j] + j);
-         q ^= Alpha_to[reg[j]];
-       }
-      if (q != 0)
-       continue;
-      /* store root and error location number indices */
-      root[count] = i;
-      loc[count] = k;
-      count++;
-    }
-    if (count != no_eras) {
-      printf("\n lambda(x) is WRONG\n");
-      count = -1;
-      goto finish;
-    }
-#if DEBUG_ECC >= 2
-    printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n");
-    for (i = 0; i < count; i++)
-      printf("%d ", loc[i]);
-    printf("\n");
-#endif
-#endif
-  }
-  for(i=0;i<NN-KK+1;i++)
-    b[i] = Index_of[lambda[i]];
-
-  /*
-   * Begin Berlekamp-Massey algorithm to determine error+erasure
-   * locator polynomial
-   */
-  r = no_eras;
-  el = no_eras;
-  while (++r <= NN-KK) {       /* r is the step number */
-    /* Compute discrepancy at the r-th step in poly-form */
-    discr_r = 0;
-    for (i = 0; i < r; i++){
-      if ((lambda[i] != 0) && (s[r - i] != A0)) {
-       discr_r ^= Alpha_to[modnn(Index_of[lambda[i]] + s[r - i])];
-      }
-    }
-    discr_r = Index_of[discr_r];       /* Index form */
-    if (discr_r == A0) {
-      /* 2 lines below: B(x) <-- x*B(x) */
-      COPYDOWN(&b[1],b,NN-KK);
-      b[0] = A0;
-    } else {
-      /* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */
-      t[0] = lambda[0];
-      for (i = 0 ; i < NN-KK; i++) {
-       if(b[i] != A0)
-         t[i+1] = lambda[i+1] ^ Alpha_to[modnn(discr_r + b[i])];
-       else
-         t[i+1] = lambda[i+1];
-      }
-      if (2 * el <= r + no_eras - 1) {
-       el = r + no_eras - el;
-       /*
-        * 2 lines below: B(x) <-- inv(discr_r) *
-        * lambda(x)
-        */
-       for (i = 0; i <= NN-KK; i++)
-         b[i] = (lambda[i] == 0) ? A0 : modnn(Index_of[lambda[i]] - discr_r + NN);
-      } else {
-       /* 2 lines below: B(x) <-- x*B(x) */
-       COPYDOWN(&b[1],b,NN-KK);
-       b[0] = A0;
-      }
-      COPY(lambda,t,NN-KK+1);
-    }
-  }
-
-  /* Convert lambda to index form and compute deg(lambda(x)) */
-  deg_lambda = 0;
-  for(i=0;i<NN-KK+1;i++){
-    lambda[i] = Index_of[lambda[i]];
-    if(lambda[i] != A0)
-      deg_lambda = i;
-  }
-  /*
-   * Find roots of the error+erasure locator polynomial by Chien
-   * Search
-   */
-  COPY(&reg[1],&lambda[1],NN-KK);
-  count = 0;           /* Number of roots of lambda(x) */
-  for (i = 1,k=NN-Ldec; i <= NN; i++,k = modnn(NN+k-Ldec)) {
-    q = 1;
-    for (j = deg_lambda; j > 0; j--){
-      if (reg[j] != A0) {
-       reg[j] = modnn(reg[j] + j);
-       q ^= Alpha_to[reg[j]];
-      }
-    }
-    if (q != 0)
-      continue;
-    /* store root (index-form) and error location number */
-    root[count] = i;
-    loc[count] = k;
-    /* If we've already found max possible roots,
-     * abort the search to save time
-     */
-    if(++count == deg_lambda)
-      break;
-  }
-  if (deg_lambda != count) {
-    /*
-     * deg(lambda) unequal to number of roots => uncorrectable
-     * error detected
-     */
-    count = -1;
-    goto finish;
-  }
-  /*
-   * Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo
-   * x**(NN-KK)). in index form. Also find deg(omega).
-   */
-  deg_omega = 0;
-  for (i = 0; i < NN-KK;i++){
-    tmp = 0;
-    j = (deg_lambda < i) ? deg_lambda : i;
-    for(;j >= 0; j--){
-      if ((s[i + 1 - j] != A0) && (lambda[j] != A0))
-       tmp ^= Alpha_to[modnn(s[i + 1 - j] + lambda[j])];
-    }
-    if(tmp != 0)
-      deg_omega = i;
-    omega[i] = Index_of[tmp];
-  }
-  omega[NN-KK] = A0;
-
-  /*
-   * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
-   * inv(X(l))**(B0-1) and den = lambda_pr(inv(X(l))) all in poly-form
-   */
-  for (j = count-1; j >=0; j--) {
-    num1 = 0;
-    for (i = deg_omega; i >= 0; i--) {
-      if (omega[i] != A0)
-       num1  ^= Alpha_to[modnn(omega[i] + i * root[j])];
-    }
-    num2 = Alpha_to[modnn(root[j] * (B0 - 1) + NN)];
-    den = 0;
-
-    /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
-    for (i = min(deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) {
-      if(lambda[i+1] != A0)
-       den ^= Alpha_to[modnn(lambda[i+1] + i * root[j])];
-    }
-    if (den == 0) {
-#if DEBUG_ECC >= 1
-      printf("\n ERROR: denominator = 0\n");
-#endif
-      /* Convert to dual- basis */
-      count = -1;
-      goto finish;
-    }
-    /* Apply error to data */
-    if (num1 != 0) {
-        eras_val[j] = Alpha_to[modnn(Index_of[num1] + Index_of[num2] + NN - Index_of[den])];
-    } else {
-        eras_val[j] = 0;
-    }
-  }
- finish:
-  for(i=0;i<count;i++)
-      eras_pos[i] = loc[i];
-  return count;
-}
-
-/***************************************************************************/
-/* The DOC specific code begins here */
-
-#define SECTOR_SIZE 512
-/* The sector bytes are packed into NB_DATA MM bits words */
-#define NB_DATA (((SECTOR_SIZE + 1) * 8 + 6) / MM)
-
-/*
- * Correct the errors in 'sector[]' by using 'ecc1[]' which is the
- * content of the feedback shift register applyied to the sector and
- * the ECC. Return the number of errors corrected (and correct them in
- * sector), or -1 if error
- */
-int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
-{
-    int parity, i, nb_errors;
-    gf bb[NN - KK + 1];
-    gf error_val[NN-KK];
-    int error_pos[NN-KK], pos, bitpos, index, val;
-    dtype *Alpha_to, *Index_of;
-
-    /* init log and exp tables here to save memory. However, it is slower */
-    Alpha_to = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL);
-    if (!Alpha_to)
-        return -1;
-
-    Index_of = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL);
-    if (!Index_of) {
-        kfree(Alpha_to);
-        return -1;
-    }
-
-    generate_gf(Alpha_to, Index_of);
-
-    parity = ecc1[1];
-
-    bb[0] =  (ecc1[4] & 0xff) | ((ecc1[5] & 0x03) << 8);
-    bb[1] = ((ecc1[5] & 0xfc) >> 2) | ((ecc1[2] & 0x0f) << 6);
-    bb[2] = ((ecc1[2] & 0xf0) >> 4) | ((ecc1[3] & 0x3f) << 4);
-    bb[3] = ((ecc1[3] & 0xc0) >> 6) | ((ecc1[0] & 0xff) << 2);
-
-    nb_errors = eras_dec_rs(Alpha_to, Index_of, bb,
-                            error_val, error_pos, 0);
-    if (nb_errors <= 0)
-        goto the_end;
-
-    /* correct the errors */
-    for(i=0;i<nb_errors;i++) {
-        pos = error_pos[i];
-        if (pos >= NB_DATA && pos < KK) {
-            nb_errors = -1;
-            goto the_end;
-        }
-        if (pos < NB_DATA) {
-            /* extract bit position (MSB first) */
-            pos = 10 * (NB_DATA - 1 - pos) - 6;
-            /* now correct the following 10 bits. At most two bytes
-               can be modified since pos is even */
-            index = (pos >> 3) ^ 1;
-            bitpos = pos & 7;
-            if ((index >= 0 && index < SECTOR_SIZE) ||
-                index == (SECTOR_SIZE + 1)) {
-                val = error_val[i] >> (2 + bitpos);
-                parity ^= val;
-                if (index < SECTOR_SIZE)
-                    sector[index] ^= val;
-            }
-            index = ((pos >> 3) + 1) ^ 1;
-            bitpos = (bitpos + 10) & 7;
-            if (bitpos == 0)
-                bitpos = 8;
-            if ((index >= 0 && index < SECTOR_SIZE) ||
-                index == (SECTOR_SIZE + 1)) {
-                val = error_val[i] << (8 - bitpos);
-                parity ^= val;
-                if (index < SECTOR_SIZE)
-                    sector[index] ^= val;
-            }
-        }
-    }
-
-    /* use parity to test extra errors */
-    if ((parity & 0xff) != 0)
-        nb_errors = -1;
-
- the_end:
-    kfree(Alpha_to);
-    kfree(Index_of);
-    return nb_errors;
-}
-
-EXPORT_SYMBOL_GPL(doc_decode_ecc);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Fabrice Bellard <fabrice.bellard@netgem.com>");
-MODULE_DESCRIPTION("ECC code for correcting errors detected by DiskOnChip 2000 and Millennium ECC hardware");
index 8510ccb9c6f00a450ed58cea115dd33d8070f749..3e1b0a0ef4dba22e559b74e603ebe1bf90f389cb 100644 (file)
@@ -123,7 +123,7 @@ static inline void doc_flash_address(struct docg3 *docg3, u8 addr)
        doc_writeb(docg3, addr, DOC_FLASHADDRESS);
 }
 
-static char const *part_probes[] = { "cmdlinepart", "saftlpart", NULL };
+static char const * const part_probes[] = { "cmdlinepart", "saftlpart", NULL };
 
 static int doc_register_readb(struct docg3 *docg3, int reg)
 {
@@ -2144,18 +2144,7 @@ static struct platform_driver g3_driver = {
        .remove         = __exit_p(docg3_release),
 };
 
-static int __init docg3_init(void)
-{
-       return platform_driver_probe(&g3_driver, docg3_probe);
-}
-module_init(docg3_init);
-
-
-static void __exit docg3_exit(void)
-{
-       platform_driver_unregister(&g3_driver);
-}
-module_exit(docg3_exit);
+module_platform_driver_probe(g3_driver, docg3_probe);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
diff --git a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c
deleted file mode 100644 (file)
index 88b3fd3..0000000
+++ /dev/null
@@ -1,325 +0,0 @@
-
-/* Linux driver for Disk-On-Chip devices                       */
-/* Probe routines common to all DoC devices                    */
-/* (C) 1999 Machine Vision Holdings, Inc.                      */
-/* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>         */
-
-
-/* DOC_PASSIVE_PROBE:
-   In order to ensure that the BIOS checksum is correct at boot time, and
-   hence that the onboard BIOS extension gets executed, the DiskOnChip
-   goes into reset mode when it is read sequentially: all registers
-   return 0xff until the chip is woken up again by writing to the
-   DOCControl register.
-
-   Unfortunately, this means that the probe for the DiskOnChip is unsafe,
-   because one of the first things it does is write to where it thinks
-   the DOCControl register should be - which may well be shared memory
-   for another device. I've had machines which lock up when this is
-   attempted. Hence the possibility to do a passive probe, which will fail
-   to detect a chip in reset mode, but is at least guaranteed not to lock
-   the machine.
-
-   If you have this problem, uncomment the following line:
-#define DOC_PASSIVE_PROBE
-*/
-
-
-/* DOC_SINGLE_DRIVER:
-   Millennium driver has been merged into DOC2000 driver.
-
-   The old Millennium-only driver has been retained just in case there
-   are problems with the new code. If the combined driver doesn't work
-   for you, you can try the old one by undefining DOC_SINGLE_DRIVER
-   below and also enabling it in your configuration. If this fixes the
-   problems, please send a report to the MTD mailing list at
-   <linux-mtd@lists.infradead.org>.
-*/
-#define DOC_SINGLE_DRIVER
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/types.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/doc2000.h>
-
-
-static unsigned long doc_config_location = CONFIG_MTD_DOCPROBE_ADDRESS;
-module_param(doc_config_location, ulong, 0);
-MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe for DiskOnChip");
-
-static unsigned long __initdata doc_locations[] = {
-#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
-#ifdef CONFIG_MTD_DOCPROBE_HIGH
-       0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
-       0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
-       0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
-       0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
-       0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
-#else /*  CONFIG_MTD_DOCPROBE_HIGH */
-       0xc8000, 0xca000, 0xcc000, 0xce000,
-       0xd0000, 0xd2000, 0xd4000, 0xd6000,
-       0xd8000, 0xda000, 0xdc000, 0xde000,
-       0xe0000, 0xe2000, 0xe4000, 0xe6000,
-       0xe8000, 0xea000, 0xec000, 0xee000,
-#endif /*  CONFIG_MTD_DOCPROBE_HIGH */
-#endif
-       0xffffffff };
-
-/* doccheck: Probe a given memory window to see if there's a DiskOnChip present */
-
-static inline int __init doccheck(void __iomem *potential, unsigned long physadr)
-{
-       void __iomem *window=potential;
-       unsigned char tmp, tmpb, tmpc, ChipID;
-#ifndef DOC_PASSIVE_PROBE
-       unsigned char tmp2;
-#endif
-
-       /* Routine copied from the Linux DOC driver */
-
-#ifdef CONFIG_MTD_DOCPROBE_55AA
-       /* Check for 0x55 0xAA signature at beginning of window,
-          this is no longer true once we remove the IPL (for Millennium */
-       if (ReadDOC(window, Sig1) != 0x55 || ReadDOC(window, Sig2) != 0xaa)
-               return 0;
-#endif /* CONFIG_MTD_DOCPROBE_55AA */
-
-#ifndef DOC_PASSIVE_PROBE
-       /* It's not possible to cleanly detect the DiskOnChip - the
-        * bootup procedure will put the device into reset mode, and
-        * it's not possible to talk to it without actually writing
-        * to the DOCControl register. So we store the current contents
-        * of the DOCControl register's location, in case we later decide
-        * that it's not a DiskOnChip, and want to put it back how we
-        * found it.
-        */
-       tmp2 = ReadDOC(window, DOCControl);
-
-       /* Reset the DiskOnChip ASIC */
-       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
-                window, DOCControl);
-       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
-                window, DOCControl);
-
-       /* Enable the DiskOnChip ASIC */
-       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
-                window, DOCControl);
-       WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
-                window, DOCControl);
-#endif /* !DOC_PASSIVE_PROBE */
-
-       /* We need to read the ChipID register four times. For some
-          newer DiskOnChip 2000 units, the first three reads will
-          return the DiskOnChip Millennium ident. Don't ask. */
-       ChipID = ReadDOC(window, ChipID);
-
-       switch (ChipID) {
-       case DOC_ChipID_Doc2k:
-               /* Check the TOGGLE bit in the ECC register */
-               tmp  = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
-               tmpb = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
-               tmpc = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
-               if (tmp != tmpb && tmp == tmpc)
-                               return ChipID;
-               break;
-
-       case DOC_ChipID_DocMil:
-               /* Check for the new 2000 with Millennium ASIC */
-               ReadDOC(window, ChipID);
-               ReadDOC(window, ChipID);
-               if (ReadDOC(window, ChipID) != DOC_ChipID_DocMil)
-                       ChipID = DOC_ChipID_Doc2kTSOP;
-
-               /* Check the TOGGLE bit in the ECC register */
-               tmp  = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
-               tmpb = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
-               tmpc = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
-               if (tmp != tmpb && tmp == tmpc)
-                               return ChipID;
-               break;
-
-       case DOC_ChipID_DocMilPlus16:
-       case DOC_ChipID_DocMilPlus32:
-       case 0:
-               /* Possible Millennium+, need to do more checks */
-#ifndef DOC_PASSIVE_PROBE
-               /* Possibly release from power down mode */
-               for (tmp = 0; (tmp < 4); tmp++)
-                       ReadDOC(window, Mplus_Power);
-
-               /* Reset the DiskOnChip ASIC */
-               tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
-                       DOC_MODE_BDECT;
-               WriteDOC(tmp, window, Mplus_DOCControl);
-               WriteDOC(~tmp, window, Mplus_CtrlConfirm);
-
-               mdelay(1);
-               /* Enable the DiskOnChip ASIC */
-               tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
-                       DOC_MODE_BDECT;
-               WriteDOC(tmp, window, Mplus_DOCControl);
-               WriteDOC(~tmp, window, Mplus_CtrlConfirm);
-               mdelay(1);
-#endif /* !DOC_PASSIVE_PROBE */
-
-               ChipID = ReadDOC(window, ChipID);
-
-               switch (ChipID) {
-               case DOC_ChipID_DocMilPlus16:
-               case DOC_ChipID_DocMilPlus32:
-                       /* Check the TOGGLE bit in the toggle register */
-                       tmp  = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT;
-                       tmpb = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT;
-                       tmpc = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT;
-                       if (tmp != tmpb && tmp == tmpc)
-                                       return ChipID;
-               default:
-                       break;
-               }
-               /* FALL TRHU */
-
-       default:
-
-#ifdef CONFIG_MTD_DOCPROBE_55AA
-               printk(KERN_DEBUG "Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n",
-                      ChipID, physadr);
-#endif
-#ifndef DOC_PASSIVE_PROBE
-               /* Put back the contents of the DOCControl register, in case it's not
-                * actually a DiskOnChip.
-                */
-               WriteDOC(tmp2, window, DOCControl);
-#endif
-               return 0;
-       }
-
-       printk(KERN_WARNING "DiskOnChip failed TOGGLE test, dropping.\n");
-
-#ifndef DOC_PASSIVE_PROBE
-       /* Put back the contents of the DOCControl register: it's not a DiskOnChip */
-       WriteDOC(tmp2, window, DOCControl);
-#endif
-       return 0;
-}
-
-static int docfound;
-
-extern void DoC2k_init(struct mtd_info *);
-extern void DoCMil_init(struct mtd_info *);
-extern void DoCMilPlus_init(struct mtd_info *);
-
-static void __init DoC_Probe(unsigned long physadr)
-{
-       void __iomem *docptr;
-       struct DiskOnChip *this;
-       struct mtd_info *mtd;
-       int ChipID;
-       char namebuf[15];
-       char *name = namebuf;
-       void (*initroutine)(struct mtd_info *) = NULL;
-
-       docptr = ioremap(physadr, DOC_IOREMAP_LEN);
-
-       if (!docptr)
-               return;
-
-       if ((ChipID = doccheck(docptr, physadr))) {
-               if (ChipID == DOC_ChipID_Doc2kTSOP) {
-                       /* Remove this at your own peril. The hardware driver works but nothing prevents you from erasing bad blocks */
-                       printk(KERN_NOTICE "Refusing to drive DiskOnChip 2000 TSOP until Bad Block Table is correctly supported by INFTL\n");
-                       iounmap(docptr);
-                       return;
-               }
-               docfound = 1;
-               mtd = kzalloc(sizeof(struct DiskOnChip) + sizeof(struct mtd_info), GFP_KERNEL);
-               if (!mtd) {
-                       printk(KERN_WARNING "Cannot allocate memory for data structures. Dropping.\n");
-                       iounmap(docptr);
-                       return;
-               }
-
-               this = (struct DiskOnChip *)(&mtd[1]);
-               mtd->priv = this;
-               this->virtadr = docptr;
-               this->physadr = physadr;
-               this->ChipID = ChipID;
-               sprintf(namebuf, "with ChipID %2.2X", ChipID);
-
-               switch(ChipID) {
-               case DOC_ChipID_Doc2kTSOP:
-                       name="2000 TSOP";
-                       initroutine = symbol_request(DoC2k_init);
-                       break;
-
-               case DOC_ChipID_Doc2k:
-                       name="2000";
-                       initroutine = symbol_request(DoC2k_init);
-                       break;
-
-               case DOC_ChipID_DocMil:
-                       name="Millennium";
-#ifdef DOC_SINGLE_DRIVER
-                       initroutine = symbol_request(DoC2k_init);
-#else
-                       initroutine = symbol_request(DoCMil_init);
-#endif /* DOC_SINGLE_DRIVER */
-                       break;
-
-               case DOC_ChipID_DocMilPlus16:
-               case DOC_ChipID_DocMilPlus32:
-                       name="MillenniumPlus";
-                       initroutine = symbol_request(DoCMilPlus_init);
-                       break;
-               }
-
-               if (initroutine) {
-                       (*initroutine)(mtd);
-                       symbol_put_addr(initroutine);
-                       return;
-               }
-               printk(KERN_NOTICE "Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr);
-               kfree(mtd);
-       }
-       iounmap(docptr);
-}
-
-
-/****************************************************************************
- *
- * Module stuff
- *
- ****************************************************************************/
-
-static int __init init_doc(void)
-{
-       int i;
-
-       if (doc_config_location) {
-               printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location);
-               DoC_Probe(doc_config_location);
-       } else {
-               for (i=0; (doc_locations[i] != 0xffffffff); i++) {
-                       DoC_Probe(doc_locations[i]);
-               }
-       }
-       /* No banner message any more. Print a message if no DiskOnChip
-          found, so the user knows we at least tried. */
-       if (!docfound)
-               printk(KERN_INFO "No recognised DiskOnChip devices found\n");
-       return -EAGAIN;
-}
-
-module_init(init_doc);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("Probe code for DiskOnChip 2000 and Millennium devices");
-
index 2ec5da9ee24826a0790399e24cb6271891889cf8..dccef9fdc1f276269566bcc4ba03ae6e7a87111d 100644 (file)
@@ -81,14 +81,21 @@ static u32 elm_read_reg(struct elm_info *info, int offset)
  * @dev:       ELM device
  * @bch_type:  Type of BCH ecc
  */
-void elm_config(struct device *dev, enum bch_ecc bch_type)
+int elm_config(struct device *dev, enum bch_ecc bch_type)
 {
        u32 reg_val;
        struct elm_info *info = dev_get_drvdata(dev);
 
+       if (!info) {
+               dev_err(dev, "Unable to configure elm - device not probed?\n");
+               return -ENODEV;
+       }
+
        reg_val = (bch_type & ECC_BCH_LEVEL_MASK) | (ELM_ECC_SIZE << 16);
        elm_write_reg(info, ELM_LOCATION_CONFIG, reg_val);
        info->bch_type = bch_type;
+
+       return 0;
 }
 EXPORT_SYMBOL(elm_config);
 
index 5b6b0728be21b0f4c3a7ddee475f3d02ce8f3d52..2f3d2a5ff349a174dc0f473f07c67f477f0139c4 100644 (file)
@@ -681,6 +681,7 @@ struct flash_info {
        u16             flags;
 #define        SECT_4K         0x01            /* OPCODE_BE_4K works uniformly */
 #define        M25P_NO_ERASE   0x02            /* No erase command needed */
+#define        SST_WRITE       0x04            /* use SST byte programming */
 };
 
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)     \
@@ -728,6 +729,7 @@ static const struct spi_device_id m25p_ids[] = {
        { "en25q32b", INFO(0x1c3016, 0, 64 * 1024,  64, 0) },
        { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
        { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
+       { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) },
 
        /* Everspin */
        { "mr25h256", CAT25_INFO(  32 * 1024, 1, 256, 2) },
@@ -740,7 +742,6 @@ static const struct spi_device_id m25p_ids[] = {
        { "160s33b",  INFO(0x898911, 0, 64 * 1024,  32, 0) },
        { "320s33b",  INFO(0x898912, 0, 64 * 1024,  64, 0) },
        { "640s33b",  INFO(0x898913, 0, 64 * 1024, 128, 0) },
-       { "n25q064",  INFO(0x20ba17, 0, 64 * 1024, 128, 0) },
 
        /* Macronix */
        { "mx25l2005a",  INFO(0xc22012, 0, 64 * 1024,   4, SECT_4K) },
@@ -753,8 +754,10 @@ static const struct spi_device_id m25p_ids[] = {
        { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
        { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
        { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
+       { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) },
 
        /* Micron */
+       { "n25q064",  INFO(0x20ba17, 0, 64 * 1024, 128, 0) },
        { "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
        { "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
        { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
@@ -781,14 +784,15 @@ static const struct spi_device_id m25p_ids[] = {
        { "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128, SECT_4K) },
 
        /* SST -- large erase sizes are "overlays", "sectors" are 4K */
-       { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8, SECT_4K) },
-       { "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K) },
-       { "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K) },
-       { "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K) },
-       { "sst25wf512",  INFO(0xbf2501, 0, 64 * 1024,  1, SECT_4K) },
-       { "sst25wf010",  INFO(0xbf2502, 0, 64 * 1024,  2, SECT_4K) },
-       { "sst25wf020",  INFO(0xbf2503, 0, 64 * 1024,  4, SECT_4K) },
-       { "sst25wf040",  INFO(0xbf2504, 0, 64 * 1024,  8, SECT_4K) },
+       { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
+       { "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
+       { "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) },
+       { "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) },
+       { "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128, SECT_4K) },
+       { "sst25wf512",  INFO(0xbf2501, 0, 64 * 1024,  1, SECT_4K | SST_WRITE) },
+       { "sst25wf010",  INFO(0xbf2502, 0, 64 * 1024,  2, SECT_4K | SST_WRITE) },
+       { "sst25wf020",  INFO(0xbf2503, 0, 64 * 1024,  4, SECT_4K | SST_WRITE) },
+       { "sst25wf040",  INFO(0xbf2504, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
 
        /* ST Microelectronics -- newer production may have feature updates */
        { "m25p05",  INFO(0x202010,  0,  32 * 1024,   2, 0) },
@@ -838,6 +842,7 @@ static const struct spi_device_id m25p_ids[] = {
        { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
        { "w25q80", INFO(0xef5014, 0, 64 * 1024,  16, SECT_4K) },
        { "w25q80bl", INFO(0xef4014, 0, 64 * 1024,  16, SECT_4K) },
+       { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
        { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) },
 
        /* Catalyst / On Semiconductor -- non-JEDEC */
@@ -1000,7 +1005,7 @@ static int m25p_probe(struct spi_device *spi)
        }
 
        /* sst flash chips use AAI word program */
-       if (JEDEC_MFR(info->jedec_id) == CFI_MFR_SST)
+       if (info->flags & SST_WRITE)
                flash->mtd._write = sst_write;
        else
                flash->mtd._write = m25p80_write;
index 945c9f7623499fb3798314e508ad65779755b863..28779b6dfcd98fc6c8b2ed5b49800d898fee7e81 100644 (file)
@@ -105,8 +105,6 @@ static const struct of_device_id dataflash_dt_ids[] = {
        { .compatible = "atmel,dataflash", },
        { /* sentinel */ }
 };
-#else
-#define dataflash_dt_ids NULL
 #endif
 
 /* ......................................................................... */
@@ -914,7 +912,7 @@ static struct spi_driver dataflash_driver = {
        .driver = {
                .name           = "mtd_dataflash",
                .owner          = THIS_MODULE,
-               .of_match_table = dataflash_dt_ids,
+               .of_match_table = of_match_ptr(dataflash_dt_ids),
        },
 
        .probe          = dataflash_probe,
index c26938382f6488992828d211781b06d84ecde5e3..bed9d58d5741246f58bafe178851e8faf42744e2 100644 (file)
@@ -249,22 +249,6 @@ config MTD_LANTIQ
        help
          Support for NOR flash attached to the Lantiq SoC's External Bus Unit.
 
-config MTD_DILNETPC
-       tristate "CFI Flash device mapped on DIL/Net PC"
-       depends on X86 && MTD_CFI_INTELEXT && BROKEN
-       help
-         MTD map driver for SSV DIL/Net PC Boards "DNP" and "ADNP".
-         For details, see <http://www.ssv-embedded.de/ssv/pc104/p169.htm>
-         and <http://www.ssv-embedded.de/ssv/pc104/p170.htm>
-
-config MTD_DILNETPC_BOOTSIZE
-       hex "Size of DIL/Net PC flash boot partition"
-       depends on MTD_DILNETPC
-       default "0x80000"
-       help
-         The amount of space taken up by the kernel or Etherboot
-         on the DIL/Net PC flash chips.
-
 config MTD_L440GX
        tristate "BIOS flash chip on Intel L440GX boards"
        depends on X86 && MTD_JEDECPROBE
@@ -274,42 +258,6 @@ config MTD_L440GX
 
          BE VERY CAREFUL.
 
-config MTD_TQM8XXL
-       tristate "CFI Flash device mapped on TQM8XXL"
-       depends on MTD_CFI && TQM8xxL
-       help
-         The TQM8xxL PowerPC board has up to two banks of CFI-compliant
-         chips, currently uses AMD one. This 'mapping' driver supports
-         that arrangement, allowing the CFI probe and command set driver
-         code to communicate with the chips on the TQM8xxL board. More at
-         <http://www.denx.de/wiki/PPCEmbedded/>.
-
-config MTD_RPXLITE
-       tristate "CFI Flash device mapped on RPX Lite or CLLF"
-       depends on MTD_CFI && (RPXCLASSIC || RPXLITE)
-       help
-         The RPXLite PowerPC board has CFI-compliant chips mapped in
-         a strange sparse mapping. This 'mapping' driver supports that
-         arrangement, allowing the CFI probe and command set driver code
-         to communicate with the chips on the RPXLite board. More at
-         <http://www.embeddedplanet.com/>.
-
-config MTD_MBX860
-       tristate "System flash on MBX860 board"
-       depends on MTD_CFI && MBX
-       help
-         This enables access routines for the flash chips on the Motorola
-         MBX860 board. If you have one of these boards and would like
-         to use the flash chips on it, say 'Y'.
-
-config MTD_DBOX2
-       tristate "CFI Flash device mapped on D-Box2"
-       depends on DBOX2 && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD
-       help
-         This enables access routines for the flash chips on the Nokia/Sagem
-         D-Box 2 board. If you have one of these boards and would like to use
-         the flash chips on it, say 'Y'.
-
 config MTD_CFI_FLAGADM
        tristate "CFI Flash device mapping on FlagaDM"
        depends on 8xx && MTD_CFI
@@ -349,15 +297,6 @@ config MTD_IXP4XX
          IXDP425 and Coyote. If you have an IXP4xx based board and
          would like to use the flash chips on it, say 'Y'.
 
-config MTD_IXP2000
-       tristate "CFI Flash device mapped on Intel IXP2000 based systems"
-       depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP2000
-       help
-         This enables MTD access to flash devices on platforms based
-         on Intel's IXP2000 family of network processors. If you have an
-         IXP2000 based board and would like to use the flash chips on it,
-         say 'Y'.
-
 config MTD_AUTCPU12
        bool "NV-RAM mapping AUTCPU12 board"
        depends on ARCH_AUTCPU12
@@ -372,13 +311,6 @@ config MTD_IMPA7
          This enables access to the NOR Flash on the impA7 board of
          implementa GmbH. If you have such a board, say 'Y' here.
 
-config MTD_H720X
-       tristate "Hynix evaluation board mappings"
-       depends on MTD_CFI && ( ARCH_H7201 || ARCH_H7202 )
-       help
-         This enables access to the flash chips on the Hynix evaluation boards.
-         If you have such a board, say 'Y'.
-
 # This needs CFI or JEDEC, depending on the cards found.
 config MTD_PCI
        tristate "PCI MTD driver"
@@ -433,15 +365,6 @@ config MTD_UCLINUX
        help
          Map driver to support image based filesystems for uClinux.
 
-config MTD_DMV182
-        tristate "Map driver for Dy-4 SVME/DMV-182 board."
-        depends on DMV182
-       select MTD_MAP_BANK_WIDTH_32
-       select MTD_CFI_I8
-       select MTD_CFI_AMDSTD
-        help
-          Map driver for Dy-4 SVME/DMV-182 board.
-
 config MTD_INTEL_VR_NOR
        tristate "NOR flash on Intel Vermilion Range Expansion Bus CS0"
        depends on PCI
index 4ded28711bc11a0b53789d74c49c5e0842729ce3..395a12444048e6f2c7fbaa64d028be488551e187 100644 (file)
@@ -9,7 +9,6 @@ endif
 # Chip mappings
 obj-$(CONFIG_MTD_CFI_FLAGADM)  += cfi_flagadm.o
 obj-$(CONFIG_MTD_DC21285)      += dc21285.o
-obj-$(CONFIG_MTD_DILNETPC)     += dilnetpc.o
 obj-$(CONFIG_MTD_L440GX)       += l440gx.o
 obj-$(CONFIG_MTD_AMD76XROM)    += amd76xrom.o
 obj-$(CONFIG_MTD_ESB2ROM)      += esb2rom.o
@@ -17,15 +16,12 @@ obj-$(CONFIG_MTD_ICHXROM)   += ichxrom.o
 obj-$(CONFIG_MTD_CK804XROM)    += ck804xrom.o
 obj-$(CONFIG_MTD_TSUNAMI)      += tsunami_flash.o
 obj-$(CONFIG_MTD_PXA2XX)       += pxa2xx-flash.o
-obj-$(CONFIG_MTD_MBX860)       += mbx860.o
 obj-$(CONFIG_MTD_OCTAGON)      += octagon-5066.o
 obj-$(CONFIG_MTD_PHYSMAP)      += physmap.o
 obj-$(CONFIG_MTD_PHYSMAP_OF)   += physmap_of.o
 obj-$(CONFIG_MTD_PISMO)                += pismo.o
 obj-$(CONFIG_MTD_PMC_MSP_EVM)   += pmcmsp-flash.o
 obj-$(CONFIG_MTD_PCMCIA)       += pcmciamtd.o
-obj-$(CONFIG_MTD_RPXLITE)      += rpxlite.o
-obj-$(CONFIG_MTD_TQM8XXL)      += tqm8xxl.o
 obj-$(CONFIG_MTD_SA1100)       += sa1100-flash.o
 obj-$(CONFIG_MTD_SBC_GXX)      += sbc_gxx.o
 obj-$(CONFIG_MTD_SC520CDP)     += sc520cdp.o
@@ -34,7 +30,6 @@ obj-$(CONFIG_MTD_TS5500)      += ts5500_flash.o
 obj-$(CONFIG_MTD_SUN_UFLASH)   += sun_uflash.o
 obj-$(CONFIG_MTD_VMAX)         += vmax301.o
 obj-$(CONFIG_MTD_SCx200_DOCFLASH)+= scx200_docflash.o
-obj-$(CONFIG_MTD_DBOX2)                += dbox2-flash.o
 obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
 obj-$(CONFIG_MTD_PCI)          += pci.o
 obj-$(CONFIG_MTD_AUTCPU12)     += autcpu12-nvram.o
@@ -42,10 +37,7 @@ obj-$(CONFIG_MTD_IMPA7)              += impa7.o
 obj-$(CONFIG_MTD_UCLINUX)      += uclinux.o
 obj-$(CONFIG_MTD_NETtel)       += nettel.o
 obj-$(CONFIG_MTD_SCB2_FLASH)   += scb2_flash.o
-obj-$(CONFIG_MTD_H720X)                += h720x-flash.o
 obj-$(CONFIG_MTD_IXP4XX)       += ixp4xx.o
-obj-$(CONFIG_MTD_IXP2000)      += ixp2000.o
-obj-$(CONFIG_MTD_DMV182)       += dmv182.o
 obj-$(CONFIG_MTD_PLATRAM)      += plat-ram.o
 obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o
 obj-$(CONFIG_MTD_BFIN_ASYNC)   += bfin-async-flash.o
index f833edfaab79f7119f28a811ea6abd56318f90b3..319b04a6c9d1f6a0ccc5c565c977740d63babaa9 100644 (file)
@@ -122,7 +122,8 @@ static void bfin_flash_copy_to(struct map_info *map, unsigned long to, const voi
        switch_back(state);
 }
 
-static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
+static const char * const part_probe_types[] = {
+       "cmdlinepart", "RedBoot", NULL };
 
 static int bfin_flash_probe(struct platform_device *pdev)
 {
index 586a1c77e48a7f29a6459e11387ad4d76c412383..0455166f05faeaf364252bf0ddd39ba1fa24931b 100644 (file)
@@ -308,8 +308,7 @@ static int ck804xrom_init_one(struct pci_dev *pdev,
 
  out:
        /* Free any left over map structures */
-       if (map)
-               kfree(map);
+       kfree(map);
 
        /* See if I have any map structures */
        if (list_empty(&window->maps)) {
diff --git a/drivers/mtd/maps/dbox2-flash.c b/drivers/mtd/maps/dbox2-flash.c
deleted file mode 100644 (file)
index 85bdece..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * D-Box 2 flash driver
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <linux/errno.h>
-
-/* partition_info gives details on the logical partitions that the split the
- * single flash device into. If the size if zero we use up to the end of the
- * device. */
-static struct mtd_partition partition_info[]= {
-       {
-       .name           = "BR bootloader",
-       .size           = 128 * 1024,
-       .offset         = 0,
-       .mask_flags     = MTD_WRITEABLE
-       },
-       {
-       .name           = "FLFS (U-Boot)",
-       .size           = 128 * 1024,
-       .offset         = MTDPART_OFS_APPEND,
-       .mask_flags     = 0
-       },
-       {
-       .name           = "Root (SquashFS)",
-       .size           = 7040 * 1024,
-       .offset         = MTDPART_OFS_APPEND,
-       .mask_flags     = 0
-       },
-       {
-       .name           = "var (JFFS2)",
-       .size           = 896 * 1024,
-       .offset         = MTDPART_OFS_APPEND,
-       .mask_flags     = 0
-       },
-       {
-       .name           = "Flash without bootloader",
-       .size           = MTDPART_SIZ_FULL,
-       .offset         = 128 * 1024,
-       .mask_flags     = 0
-       },
-       {
-       .name           = "Complete Flash",
-       .size           = MTDPART_SIZ_FULL,
-       .offset         = 0,
-       .mask_flags     = MTD_WRITEABLE
-       }
-};
-
-#define NUM_PARTITIONS ARRAY_SIZE(partition_info)
-
-#define WINDOW_ADDR 0x10000000
-#define WINDOW_SIZE 0x800000
-
-static struct mtd_info *mymtd;
-
-
-struct map_info dbox2_flash_map = {
-       .name           = "D-Box 2 flash memory",
-       .size           = WINDOW_SIZE,
-       .bankwidth      = 4,
-       .phys           = WINDOW_ADDR,
-};
-
-static int __init init_dbox2_flash(void)
-{
-               printk(KERN_NOTICE "D-Box 2 flash driver (size->0x%X mem->0x%X)\n", WINDOW_SIZE, WINDOW_ADDR);
-       dbox2_flash_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
-
-       if (!dbox2_flash_map.virt) {
-               printk("Failed to ioremap\n");
-               return -EIO;
-       }
-       simple_map_init(&dbox2_flash_map);
-
-       // Probe for dual Intel 28F320 or dual AMD
-       mymtd = do_map_probe("cfi_probe", &dbox2_flash_map);
-       if (!mymtd) {
-           // Probe for single Intel 28F640
-           dbox2_flash_map.bankwidth = 2;
-
-           mymtd = do_map_probe("cfi_probe", &dbox2_flash_map);
-       }
-
-       if (mymtd) {
-               mymtd->owner = THIS_MODULE;
-
-                /* Create MTD devices for each partition. */
-               mtd_device_register(mymtd, partition_info, NUM_PARTITIONS);
-
-               return 0;
-       }
-
-       iounmap((void *)dbox2_flash_map.virt);
-       return -ENXIO;
-}
-
-static void __exit cleanup_dbox2_flash(void)
-{
-       if (mymtd) {
-               mtd_device_unregister(mymtd);
-               map_destroy(mymtd);
-       }
-       if (dbox2_flash_map.virt) {
-               iounmap((void *)dbox2_flash_map.virt);
-               dbox2_flash_map.virt = 0;
-       }
-}
-
-module_init(init_dbox2_flash);
-module_exit(cleanup_dbox2_flash);
-
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>, Bastian Blank <waldi@tuxbox.org>, Alexander Wild <wild@te-elektronik.com>");
-MODULE_DESCRIPTION("MTD map driver for D-Box 2 board");
index 080f06053bd449d51467f3ab294acfe05289ed34..f8a7dd14cee0cc7a8b6767f0ef281ea95dd89149 100644 (file)
@@ -143,9 +143,8 @@ static struct map_info dc21285_map = {
        .copy_from = dc21285_copy_from,
 };
 
-
 /* Partition stuff */
-static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
+static const char * const probes[] = { "RedBoot", "cmdlinepart", NULL };
 
 static int __init init_dc21285(void)
 {
diff --git a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c
deleted file mode 100644 (file)
index 3e393f0..0000000
+++ /dev/null
@@ -1,496 +0,0 @@
-/* dilnetpc.c -- MTD map driver for SSV DIL/Net PC Boards "DNP" and "ADNP"
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems
- * featuring the AMD Elan SC410 processor. There are two variants of this
- * board: DNP/1486 and ADNP/1486. The DNP version has 2 megs of flash
- * ROM (Intel 28F016S3) and 8 megs of DRAM, the ADNP version has 4 megs
- * flash and 16 megs of RAM.
- * For details, see http://www.ssv-embedded.de/ssv/pc104/p169.htm
- * and http://www.ssv-embedded.de/ssv/pc104/p170.htm
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/string.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/concat.h>
-
-#include <asm/io.h>
-
-/*
-** The DIL/NetPC keeps its BIOS in two distinct flash blocks.
-** Destroying any of these blocks transforms the DNPC into
-** a paperweight (albeit not a very useful one, considering
-** it only weighs a few grams).
-**
-** Therefore, the BIOS blocks must never be erased or written to
-** except by people who know exactly what they are doing (e.g.
-** to install a BIOS update). These partitions are marked read-only
-** by default, but can be made read/write by undefining
-** DNPC_BIOS_BLOCKS_WRITEPROTECTED:
-*/
-#define DNPC_BIOS_BLOCKS_WRITEPROTECTED
-
-/*
-** The ID string (in ROM) is checked to determine whether we
-** are running on a DNP/1486 or ADNP/1486
-*/
-#define BIOSID_BASE    0x000fe100
-
-#define ID_DNPC        "DNP1486"
-#define ID_ADNP        "ADNP1486"
-
-/*
-** Address where the flash should appear in CPU space
-*/
-#define FLASH_BASE     0x2000000
-
-/*
-** Chip Setup and Control (CSC) indexed register space
-*/
-#define CSC_INDEX      0x22
-#define CSC_DATA       0x23
-
-#define CSC_MMSWAR     0x30    /* MMS window C-F attributes register */
-#define CSC_MMSWDSR    0x31    /* MMS window C-F device select register */
-
-#define CSC_RBWR       0xa7    /* GPIO Read-Back/Write Register B */
-
-#define CSC_CR         0xd0    /* internal I/O device disable/Echo */
-                               /* Z-bus/configuration register */
-
-#define CSC_PCCMDCR    0xf1    /* PC card mode and DMA control register */
-
-
-/*
-** PC Card indexed register space:
-*/
-
-#define PCC_INDEX      0x3e0
-#define PCC_DATA       0x3e1
-
-#define PCC_AWER_B             0x46    /* Socket B Address Window enable register */
-#define PCC_MWSAR_1_Lo 0x58    /* memory window 1 start address low register */
-#define PCC_MWSAR_1_Hi 0x59    /* memory window 1 start address high register */
-#define PCC_MWEAR_1_Lo 0x5A    /* memory window 1 stop address low register */
-#define PCC_MWEAR_1_Hi 0x5B    /* memory window 1 stop address high register */
-#define PCC_MWAOR_1_Lo 0x5C    /* memory window 1 address offset low register */
-#define PCC_MWAOR_1_Hi 0x5D    /* memory window 1 address offset high register */
-
-
-/*
-** Access to SC4x0's Chip Setup and Control (CSC)
-** and PC Card (PCC) indexed registers:
-*/
-static inline void setcsc(int reg, unsigned char data)
-{
-       outb(reg, CSC_INDEX);
-       outb(data, CSC_DATA);
-}
-
-static inline unsigned char getcsc(int reg)
-{
-       outb(reg, CSC_INDEX);
-       return(inb(CSC_DATA));
-}
-
-static inline void setpcc(int reg, unsigned char data)
-{
-       outb(reg, PCC_INDEX);
-       outb(data, PCC_DATA);
-}
-
-static inline unsigned char getpcc(int reg)
-{
-       outb(reg, PCC_INDEX);
-       return(inb(PCC_DATA));
-}
-
-
-/*
-************************************************************
-** Enable access to DIL/NetPC's flash by mapping it into
-** the SC4x0's MMS Window C.
-************************************************************
-*/
-static void dnpc_map_flash(unsigned long flash_base, unsigned long flash_size)
-{
-       unsigned long flash_end = flash_base + flash_size - 1;
-
-       /*
-       ** enable setup of MMS windows C-F:
-       */
-       /* - enable PC Card indexed register space */
-       setcsc(CSC_CR, getcsc(CSC_CR) | 0x2);
-       /* - set PC Card controller to operate in standard mode */
-       setcsc(CSC_PCCMDCR, getcsc(CSC_PCCMDCR) & ~1);
-
-       /*
-       ** Program base address and end address of window
-       ** where the flash ROM should appear in CPU address space
-       */
-       setpcc(PCC_MWSAR_1_Lo, (flash_base >> 12) & 0xff);
-       setpcc(PCC_MWSAR_1_Hi, (flash_base >> 20) & 0x3f);
-       setpcc(PCC_MWEAR_1_Lo, (flash_end >> 12) & 0xff);
-       setpcc(PCC_MWEAR_1_Hi, (flash_end >> 20) & 0x3f);
-
-       /* program offset of first flash location to appear in this window (0) */
-       setpcc(PCC_MWAOR_1_Lo, ((0 - flash_base) >> 12) & 0xff);
-       setpcc(PCC_MWAOR_1_Hi, ((0 - flash_base)>> 20) & 0x3f);
-
-       /* set attributes for MMS window C: non-cacheable, write-enabled */
-       setcsc(CSC_MMSWAR, getcsc(CSC_MMSWAR) & ~0x11);
-
-       /* select physical device ROMCS0 (i.e. flash) for MMS Window C */
-       setcsc(CSC_MMSWDSR, getcsc(CSC_MMSWDSR) & ~0x03);
-
-       /* enable memory window 1 */
-       setpcc(PCC_AWER_B, getpcc(PCC_AWER_B) | 0x02);
-
-       /* now disable PC Card indexed register space again */
-       setcsc(CSC_CR, getcsc(CSC_CR) & ~0x2);
-}
-
-
-/*
-************************************************************
-** Disable access to DIL/NetPC's flash by mapping it into
-** the SC4x0's MMS Window C.
-************************************************************
-*/
-static void dnpc_unmap_flash(void)
-{
-       /* - enable PC Card indexed register space */
-       setcsc(CSC_CR, getcsc(CSC_CR) | 0x2);
-
-       /* disable memory window 1 */
-       setpcc(PCC_AWER_B, getpcc(PCC_AWER_B) & ~0x02);
-
-       /* now disable PC Card indexed register space again */
-       setcsc(CSC_CR, getcsc(CSC_CR) & ~0x2);
-}
-
-
-
-/*
-************************************************************
-** Enable/Disable VPP to write to flash
-************************************************************
-*/
-
-static DEFINE_SPINLOCK(dnpc_spin);
-static int        vpp_counter = 0;
-/*
-** This is what has to be done for the DNP board ..
-*/
-static void dnp_set_vpp(struct map_info *not_used, int on)
-{
-       spin_lock_irq(&dnpc_spin);
-
-       if (on)
-       {
-               if(++vpp_counter == 1)
-                       setcsc(CSC_RBWR, getcsc(CSC_RBWR) & ~0x4);
-       }
-       else
-       {
-               if(--vpp_counter == 0)
-                       setcsc(CSC_RBWR, getcsc(CSC_RBWR) | 0x4);
-               else
-                       BUG_ON(vpp_counter < 0);
-       }
-       spin_unlock_irq(&dnpc_spin);
-}
-
-/*
-** .. and this the ADNP version:
-*/
-static void adnp_set_vpp(struct map_info *not_used, int on)
-{
-       spin_lock_irq(&dnpc_spin);
-
-       if (on)
-       {
-               if(++vpp_counter == 1)
-                       setcsc(CSC_RBWR, getcsc(CSC_RBWR) & ~0x8);
-       }
-       else
-       {
-               if(--vpp_counter == 0)
-                       setcsc(CSC_RBWR, getcsc(CSC_RBWR) | 0x8);
-               else
-                       BUG_ON(vpp_counter < 0);
-       }
-       spin_unlock_irq(&dnpc_spin);
-}
-
-
-
-#define DNP_WINDOW_SIZE                0x00200000      /*  DNP flash size is 2MiB  */
-#define ADNP_WINDOW_SIZE       0x00400000      /* ADNP flash size is 4MiB */
-#define WINDOW_ADDR            FLASH_BASE
-
-static struct map_info dnpc_map = {
-       .name = "ADNP Flash Bank",
-       .size = ADNP_WINDOW_SIZE,
-       .bankwidth = 1,
-       .set_vpp = adnp_set_vpp,
-       .phys = WINDOW_ADDR
-};
-
-/*
-** The layout of the flash is somewhat "strange":
-**
-** 1.  960 KiB (15 blocks) : Space for ROM Bootloader and user data
-** 2.   64 KiB (1 block)   : System BIOS
-** 3.  960 KiB (15 blocks) : User Data (DNP model) or
-** 3. 3008 KiB (47 blocks) : User Data (ADNP model)
-** 4.   64 KiB (1 block)   : System BIOS Entry
-*/
-
-static struct mtd_partition partition_info[]=
-{
-       {
-               .name =         "ADNP boot",
-               .offset =       0,
-               .size =         0xf0000,
-       },
-       {
-               .name =         "ADNP system BIOS",
-               .offset =       MTDPART_OFS_NXTBLK,
-               .size =         0x10000,
-#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
-               .mask_flags =   MTD_WRITEABLE,
-#endif
-       },
-       {
-               .name =         "ADNP file system",
-               .offset =       MTDPART_OFS_NXTBLK,
-               .size =         0x2f0000,
-       },
-       {
-               .name =         "ADNP system BIOS entry",
-               .offset =       MTDPART_OFS_NXTBLK,
-               .size =         MTDPART_SIZ_FULL,
-#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
-               .mask_flags =   MTD_WRITEABLE,
-#endif
-       },
-};
-
-#define NUM_PARTITIONS ARRAY_SIZE(partition_info)
-
-static struct mtd_info *mymtd;
-static struct mtd_info *lowlvl_parts[NUM_PARTITIONS];
-static struct mtd_info *merged_mtd;
-
-/*
-** "Highlevel" partition info:
-**
-** Using the MTD concat layer, we can re-arrange partitions to our
-** liking: we construct a virtual MTD device by concatenating the
-** partitions, specifying the sequence such that the boot block
-** is immediately followed by the filesystem block (i.e. the stupid
-** system BIOS block is mapped to a different place). When re-partitioning
-** this concatenated MTD device, we can set the boot block size to
-** an arbitrary (though erase block aligned) value i.e. not one that
-** is dictated by the flash's physical layout. We can thus set the
-** boot block to be e.g. 64 KB (which is fully sufficient if we want
-** to boot an etherboot image) or to -say- 1.5 MB if we want to boot
-** a large kernel image. In all cases, the remainder of the flash
-** is available as file system space.
-*/
-
-static struct mtd_partition higlvl_partition_info[]=
-{
-       {
-               .name =         "ADNP boot block",
-               .offset =       0,
-               .size =         CONFIG_MTD_DILNETPC_BOOTSIZE,
-       },
-       {
-               .name =         "ADNP file system space",
-               .offset =       MTDPART_OFS_NXTBLK,
-               .size =         ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000,
-       },
-       {
-               .name =         "ADNP system BIOS + BIOS Entry",
-               .offset =       MTDPART_OFS_NXTBLK,
-               .size =         MTDPART_SIZ_FULL,
-#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
-               .mask_flags =   MTD_WRITEABLE,
-#endif
-       },
-};
-
-#define NUM_HIGHLVL_PARTITIONS ARRAY_SIZE(higlvl_partition_info)
-
-
-static int dnp_adnp_probe(void)
-{
-       char *biosid, rc = -1;
-
-       biosid = (char*)ioremap(BIOSID_BASE, 16);
-       if(biosid)
-       {
-               if(!strcmp(biosid, ID_DNPC))
-                       rc = 1;         /* this is a DNPC  */
-               else if(!strcmp(biosid, ID_ADNP))
-                       rc = 0;         /* this is a ADNPC */
-       }
-       iounmap((void *)biosid);
-       return(rc);
-}
-
-
-static int __init init_dnpc(void)
-{
-       int is_dnp;
-
-       /*
-       ** determine hardware (DNP/ADNP/invalid)
-       */
-       if((is_dnp = dnp_adnp_probe()) < 0)
-               return -ENXIO;
-
-       /*
-       ** Things are set up for ADNP by default
-       ** -> modify all that needs to be different for DNP
-       */
-       if(is_dnp)
-       {       /*
-               ** Adjust window size, select correct set_vpp function.
-               ** The partitioning scheme is identical on both DNP
-               ** and ADNP except for the size of the third partition.
-               */
-               int i;
-               dnpc_map.size          = DNP_WINDOW_SIZE;
-               dnpc_map.set_vpp       = dnp_set_vpp;
-               partition_info[2].size = 0xf0000;
-
-               /*
-               ** increment all string pointers so the leading 'A' gets skipped,
-               ** thus turning all occurrences of "ADNP ..." into "DNP ..."
-               */
-               ++dnpc_map.name;
-               for(i = 0; i < NUM_PARTITIONS; i++)
-                       ++partition_info[i].name;
-               higlvl_partition_info[1].size = DNP_WINDOW_SIZE -
-                       CONFIG_MTD_DILNETPC_BOOTSIZE - 0x20000;
-               for(i = 0; i < NUM_HIGHLVL_PARTITIONS; i++)
-                       ++higlvl_partition_info[i].name;
-       }
-
-       printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%llx\n",
-               is_dnp ? "DNPC" : "ADNP", dnpc_map.size, (unsigned long long)dnpc_map.phys);
-
-       dnpc_map.virt = ioremap_nocache(dnpc_map.phys, dnpc_map.size);
-
-       dnpc_map_flash(dnpc_map.phys, dnpc_map.size);
-
-       if (!dnpc_map.virt) {
-               printk("Failed to ioremap_nocache\n");
-               return -EIO;
-       }
-       simple_map_init(&dnpc_map);
-
-       printk("FLASH virtual address: 0x%p\n", dnpc_map.virt);
-
-       mymtd = do_map_probe("jedec_probe", &dnpc_map);
-
-       if (!mymtd)
-               mymtd = do_map_probe("cfi_probe", &dnpc_map);
-
-       /*
-       ** If flash probes fail, try to make flashes accessible
-       ** at least as ROM. Ajust erasesize in this case since
-       ** the default one (128M) will break our partitioning
-       */
-       if (!mymtd)
-               if((mymtd = do_map_probe("map_rom", &dnpc_map)))
-                       mymtd->erasesize = 0x10000;
-
-       if (!mymtd) {
-               iounmap(dnpc_map.virt);
-               return -ENXIO;
-       }
-
-       mymtd->owner = THIS_MODULE;
-
-       /*
-       ** Supply pointers to lowlvl_parts[] array to add_mtd_partitions()
-       ** -> add_mtd_partitions() will _not_ register MTD devices for
-       ** the partitions, but will instead store pointers to the MTD
-       ** objects it creates into our lowlvl_parts[] array.
-       ** NOTE: we arrange the pointers such that the sequence of the
-       **       partitions gets re-arranged: partition #2 follows
-       **       partition #0.
-       */
-       partition_info[0].mtdp = &lowlvl_parts[0];
-       partition_info[1].mtdp = &lowlvl_parts[2];
-       partition_info[2].mtdp = &lowlvl_parts[1];
-       partition_info[3].mtdp = &lowlvl_parts[3];
-
-       mtd_device_register(mymtd, partition_info, NUM_PARTITIONS);
-
-       /*
-       ** now create a virtual MTD device by concatenating the for partitions
-       ** (in the sequence given by the lowlvl_parts[] array.
-       */
-       merged_mtd = mtd_concat_create(lowlvl_parts, NUM_PARTITIONS, "(A)DNP Flash Concatenated");
-       if(merged_mtd)
-       {       /*
-               ** now partition the new device the way we want it. This time,
-               ** we do not supply mtd pointers in higlvl_partition_info, so
-               ** add_mtd_partitions() will register the devices.
-               */
-               mtd_device_register(merged_mtd, higlvl_partition_info,
-                                   NUM_HIGHLVL_PARTITIONS);
-       }
-
-       return 0;
-}
-
-static void __exit cleanup_dnpc(void)
-{
-       if(merged_mtd) {
-               mtd_device_unregister(merged_mtd);
-               mtd_concat_destroy(merged_mtd);
-       }
-
-       if (mymtd) {
-               mtd_device_unregister(mymtd);
-               map_destroy(mymtd);
-       }
-       if (dnpc_map.virt) {
-               iounmap(dnpc_map.virt);
-               dnpc_unmap_flash();
-               dnpc_map.virt = NULL;
-       }
-}
-
-module_init(init_dnpc);
-module_exit(cleanup_dnpc);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Sysgo Real-Time Solutions GmbH");
-MODULE_DESCRIPTION("MTD map driver for SSV DIL/NetPC DNP & ADNP");
diff --git a/drivers/mtd/maps/dmv182.c b/drivers/mtd/maps/dmv182.c
deleted file mode 100644 (file)
index 6538ac6..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-
-/*
- * drivers/mtd/maps/dmv182.c
- *
- * Flash map driver for the Dy4 SVME182 board
- *
- * Copyright 2003-2004, TimeSys Corporation
- *
- * Based on the SVME181 flash map, by Tom Nelson, Dot4, Inc. for TimeSys Corp.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <linux/errno.h>
-
-/*
- * This driver currently handles only the 16MiB user flash bank 1 on the
- * board.  It does not provide access to bank 0 (contains the Dy4 FFW), bank 2
- * (VxWorks boot), or the optional 48MiB expansion flash.
- *
- * scott.wood@timesys.com: On the newer boards with 128MiB flash, it
- * now supports the first 96MiB (the boot flash bank containing FFW
- * is excluded).  The VxWorks loader is in partition 1.
- */
-
-#define FLASH_BASE_ADDR 0xf0000000
-#define FLASH_BANK_SIZE (128*1024*1024)
-
-MODULE_AUTHOR("Scott Wood, TimeSys Corporation <scott.wood@timesys.com>");
-MODULE_DESCRIPTION("User-programmable flash device on the Dy4 SVME182 board");
-MODULE_LICENSE("GPL");
-
-static struct map_info svme182_map = {
-       .name           = "Dy4 SVME182",
-       .bankwidth      = 32,
-       .size           =  128 * 1024 * 1024
-};
-
-#define BOOTIMAGE_PART_SIZE            ((6*1024*1024)-RESERVED_PART_SIZE)
-
-// Allow 6MiB for the kernel
-#define NEW_BOOTIMAGE_PART_SIZE  (6 * 1024 * 1024)
-// Allow 1MiB for the bootloader
-#define NEW_BOOTLOADER_PART_SIZE (1024 * 1024)
-// Use the remaining 9MiB at the end of flash for the RFS
-#define NEW_RFS_PART_SIZE        (0x01000000 - NEW_BOOTLOADER_PART_SIZE - \
-                                  NEW_BOOTIMAGE_PART_SIZE)
-
-static struct mtd_partition svme182_partitions[] = {
-       // The Lower PABS is only 128KiB, but the partition code doesn't
-       // like partitions that don't end on the largest erase block
-       // size of the device, even if all of the erase blocks in the
-       // partition are small ones.  The hardware should prevent
-       // writes to the actual PABS areas.
-       {
-               name:       "Lower PABS and CPU 0 bootloader or kernel",
-               size:       6*1024*1024,
-               offset:     0,
-       },
-       {
-               name:       "Root Filesystem",
-               size:       10*1024*1024,
-               offset:     MTDPART_OFS_NXTBLK
-       },
-       {
-               name:       "CPU1 Bootloader",
-               size:       1024*1024,
-               offset:     MTDPART_OFS_NXTBLK,
-       },
-       {
-               name:       "Extra",
-               size:       110*1024*1024,
-               offset:     MTDPART_OFS_NXTBLK
-       },
-       {
-               name:       "Foundation Firmware and Upper PABS",
-               size:       1024*1024,
-               offset:     MTDPART_OFS_NXTBLK,
-               mask_flags: MTD_WRITEABLE // read-only
-       }
-};
-
-static struct mtd_info *this_mtd;
-
-static int __init init_svme182(void)
-{
-       struct mtd_partition *partitions;
-       int num_parts = ARRAY_SIZE(svme182_partitions);
-
-       partitions = svme182_partitions;
-
-       svme182_map.virt = ioremap(FLASH_BASE_ADDR, svme182_map.size);
-
-       if (svme182_map.virt == 0) {
-               printk("Failed to ioremap FLASH memory area.\n");
-               return -EIO;
-       }
-
-       simple_map_init(&svme182_map);
-
-       this_mtd = do_map_probe("cfi_probe", &svme182_map);
-       if (!this_mtd)
-       {
-               iounmap((void *)svme182_map.virt);
-               return -ENXIO;
-       }
-
-       printk(KERN_NOTICE "SVME182 flash device: %dMiB at 0x%08x\n",
-                  this_mtd->size >> 20, FLASH_BASE_ADDR);
-
-       this_mtd->owner = THIS_MODULE;
-       mtd_device_register(this_mtd, partitions, num_parts);
-
-       return 0;
-}
-
-static void __exit cleanup_svme182(void)
-{
-       if (this_mtd)
-       {
-               mtd_device_unregister(this_mtd);
-               map_destroy(this_mtd);
-       }
-
-       if (svme182_map.virt)
-       {
-               iounmap((void *)svme182_map.virt);
-               svme182_map.virt = 0;
-       }
-
-       return;
-}
-
-module_init(init_svme182);
-module_exit(cleanup_svme182);
index 7b643de2500b35cec6169169d9356592f97c637d..5ede28294f9e49765a9a24ed12867b94cc9e3208 100644 (file)
@@ -157,7 +157,8 @@ static void gf_copy_to(struct map_info *map, unsigned long to,
        memcpy_toio(map->virt + (to % state->win_size), from, len);
 }
 
-static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
+static const char * const part_probe_types[] = {
+       "cmdlinepart", "RedBoot", NULL };
 
 /**
  * gpio_flash_probe() - setup a mapping for a GPIO assisted flash
diff --git a/drivers/mtd/maps/h720x-flash.c b/drivers/mtd/maps/h720x-flash.c
deleted file mode 100644 (file)
index 8ed6cb4..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Flash memory access on Hynix GMS30C7201/HMS30C7202 based
- * evaluation boards
- *
- * (C) 2002 Jungjun Kim <jungjun.kim@hynix.com>
- *     2003 Thomas Gleixner <tglx@linutronix.de>
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <mach/hardware.h>
-#include <asm/io.h>
-
-static struct mtd_info *mymtd;
-
-static struct map_info h720x_map = {
-       .name =         "H720X",
-       .bankwidth =    4,
-       .size =         H720X_FLASH_SIZE,
-       .phys =         H720X_FLASH_PHYS,
-};
-
-static struct mtd_partition h720x_partitions[] = {
-        {
-                .name = "ArMon",
-                .size = 0x00080000,
-                .offset = 0,
-                .mask_flags = MTD_WRITEABLE
-        },{
-                .name = "Env",
-                .size = 0x00040000,
-                .offset = 0x00080000,
-                .mask_flags = MTD_WRITEABLE
-        },{
-                .name = "Kernel",
-                .size = 0x00180000,
-                .offset = 0x000c0000,
-                .mask_flags = MTD_WRITEABLE
-        },{
-                .name = "Ramdisk",
-                .size = 0x00400000,
-                .offset = 0x00240000,
-                .mask_flags = MTD_WRITEABLE
-        },{
-                .name = "jffs2",
-                .size = MTDPART_SIZ_FULL,
-                .offset = MTDPART_OFS_APPEND
-        }
-};
-
-#define NUM_PARTITIONS ARRAY_SIZE(h720x_partitions)
-
-/*
- * Initialize FLASH support
- */
-static int __init h720x_mtd_init(void)
-{
-       h720x_map.virt = ioremap(h720x_map.phys, h720x_map.size);
-
-       if (!h720x_map.virt) {
-               printk(KERN_ERR "H720x-MTD: ioremap failed\n");
-               return -EIO;
-       }
-
-       simple_map_init(&h720x_map);
-
-       // Probe for flash bankwidth 4
-       printk (KERN_INFO "H720x-MTD probing 32bit FLASH\n");
-       mymtd = do_map_probe("cfi_probe", &h720x_map);
-       if (!mymtd) {
-               printk (KERN_INFO "H720x-MTD probing 16bit FLASH\n");
-           // Probe for bankwidth 2
-           h720x_map.bankwidth = 2;
-           mymtd = do_map_probe("cfi_probe", &h720x_map);
-       }
-
-       if (mymtd) {
-               mymtd->owner = THIS_MODULE;
-
-               mtd_device_parse_register(mymtd, NULL, NULL,
-                                         h720x_partitions, NUM_PARTITIONS);
-               return 0;
-       }
-
-       iounmap((void *)h720x_map.virt);
-       return -ENXIO;
-}
-
-/*
- * Cleanup
- */
-static void __exit h720x_mtd_cleanup(void)
-{
-
-       if (mymtd) {
-               mtd_device_unregister(mymtd);
-               map_destroy(mymtd);
-       }
-
-       if (h720x_map.virt) {
-               iounmap((void *)h720x_map.virt);
-               h720x_map.virt = 0;
-       }
-}
-
-
-module_init(h720x_mtd_init);
-module_exit(h720x_mtd_cleanup);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
-MODULE_DESCRIPTION("MTD map driver for Hynix evaluation boards");
index 834a06c56f565ca466276474aebb2aea360fb97b..49686744d93cac9d2dae0758fd1b70618237c9c1 100644 (file)
 #define NUM_FLASHBANKS 2
 #define BUSWIDTH     4
 
-/* can be { "cfi_probe", "jedec_probe", "map_rom", NULL } */
-#define PROBETYPES { "jedec_probe", NULL }
-
 #define MSG_PREFIX "impA7:"   /* prefix for our printk()'s */
 #define MTDID      "impa7-%d"  /* for mtdparts= partitioning */
 
 static struct mtd_info *impa7_mtd[NUM_FLASHBANKS];
 
+static const char * const rom_probe_types[] = { "jedec_probe", NULL };
 
 static struct map_info impa7_map[NUM_FLASHBANKS] = {
        {
@@ -60,8 +58,7 @@ static struct mtd_partition partitions[] =
 
 static int __init init_impa7(void)
 {
-       static const char *rom_probe_types[] = PROBETYPES;
-       const char **type;
+       const char * const *type;
        int i;
        static struct { u_long addr; u_long size; } pt[NUM_FLASHBANKS] = {
          { WINDOW_ADDR0, WINDOW_SIZE0 },
index b14053b2502618e89fc7889ff385bc68db8f074d..f581ac1cf022fb006be3b814f6f1b23341f9e851 100644 (file)
@@ -82,9 +82,9 @@ static void vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p)
 
 static int vr_nor_mtd_setup(struct vr_nor_mtd *p)
 {
-       static const char *probe_types[] =
+       static const char * const probe_types[] =
            { "cfi_probe", "jedec_probe", NULL };
-       const char **type;
+       const char * const *type;
 
        for (type = probe_types; !p->info && *type; type++)
                p->info = do_map_probe(*type, &p->map);
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
deleted file mode 100644 (file)
index 4a41ced..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * drivers/mtd/maps/ixp2000.c
- *
- * Mapping for the Intel XScale IXP2000 based systems
- *
- * Copyright (C) 2002 Intel Corp.
- * Copyright (C) 2003-2004 MontaVista Software, Inc.
- *
- * Original Author: Naeem M Afzal <naeem.m.afzal@intel.com>
- * Maintainer: Deepak Saxena <dsaxena@plexity.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-#include <mach/hardware.h>
-#include <asm/mach/flash.h>
-
-#include <linux/reboot.h>
-
-struct ixp2000_flash_info {
-       struct          mtd_info *mtd;
-       struct          map_info map;
-       struct          resource *res;
-};
-
-static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long ofs)
-{
-       unsigned long (*set_bank)(unsigned long) =
-               (unsigned long(*)(unsigned long))map->map_priv_2;
-
-       return (set_bank ? set_bank(ofs) : ofs);
-}
-
-#ifdef __ARMEB__
-/*
- * Rev A0 and A1 of IXP2400 silicon have a broken addressing unit which
- * causes the lower address bits to be XORed with 0x11 on 8 bit accesses
- * and XORed with 0x10 on 16 bit accesses. See the spec update, erratum 44.
- */
-static int erratum44_workaround = 0;
-
-static inline unsigned long address_fix8_write(unsigned long addr)
-{
-       if (erratum44_workaround) {
-               return (addr ^ 3);
-       }
-       return addr;
-}
-#else
-
-#define address_fix8_write(x)  (x)
-#endif
-
-static map_word ixp2000_flash_read8(struct map_info *map, unsigned long ofs)
-{
-       map_word val;
-
-       val.x[0] =  *((u8 *)(map->map_priv_1 + flash_bank_setup(map, ofs)));
-       return val;
-}
-
-/*
- * We can't use the standard memcpy due to the broken SlowPort
- * address translation on rev A0 and A1 silicon and the fact that
- * we have banked flash.
- */
-static void ixp2000_flash_copy_from(struct map_info *map, void *to,
-                             unsigned long from, ssize_t len)
-{
-       from = flash_bank_setup(map, from);
-       while(len--)
-               *(__u8 *) to++ = *(__u8 *)(map->map_priv_1 + from++);
-}
-
-static void ixp2000_flash_write8(struct map_info *map, map_word d, unsigned long ofs)
-{
-       *(__u8 *) (address_fix8_write(map->map_priv_1 +
-                                     flash_bank_setup(map, ofs))) = d.x[0];
-}
-
-static void ixp2000_flash_copy_to(struct map_info *map, unsigned long to,
-                           const void *from, ssize_t len)
-{
-       to = flash_bank_setup(map, to);
-       while(len--) {
-               unsigned long tmp = address_fix8_write(map->map_priv_1 + to++);
-               *(__u8 *)(tmp) = *(__u8 *)(from++);
-       }
-}
-
-
-static int ixp2000_flash_remove(struct platform_device *dev)
-{
-       struct flash_platform_data *plat = dev->dev.platform_data;
-       struct ixp2000_flash_info *info = platform_get_drvdata(dev);
-
-       platform_set_drvdata(dev, NULL);
-
-       if(!info)
-               return 0;
-
-       if (info->mtd) {
-               mtd_device_unregister(info->mtd);
-               map_destroy(info->mtd);
-       }
-       if (info->map.map_priv_1)
-               iounmap((void *) info->map.map_priv_1);
-
-       if (info->res) {
-               release_resource(info->res);
-               kfree(info->res);
-       }
-
-       if (plat->exit)
-               plat->exit();
-
-       return 0;
-}
-
-
-static int ixp2000_flash_probe(struct platform_device *dev)
-{
-       static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-       struct ixp2000_flash_data *ixp_data = dev->dev.platform_data;
-       struct flash_platform_data *plat;
-       struct ixp2000_flash_info *info;
-       unsigned long window_size;
-       int err = -1;
-
-       if (!ixp_data)
-               return -ENODEV;
-
-       plat = ixp_data->platform_data;
-       if (!plat)
-               return -ENODEV;
-
-       window_size = resource_size(dev->resource);
-       dev_info(&dev->dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
-                ixp_data->nr_banks, ((u32)window_size >> 20));
-
-       if (plat->width != 1) {
-               dev_err(&dev->dev, "IXP2000 MTD map only supports 8-bit mode, asking for %d\n",
-                       plat->width * 8);
-               return -EIO;
-       }
-
-       info = kzalloc(sizeof(struct ixp2000_flash_info), GFP_KERNEL);
-       if(!info) {
-               err = -ENOMEM;
-               goto Error;
-       }
-
-       platform_set_drvdata(dev, info);
-
-       /*
-        * Tell the MTD layer we're not 1:1 mapped so that it does
-        * not attempt to do a direct access on us.
-        */
-       info->map.phys = NO_XIP;
-
-       info->map.size = ixp_data->nr_banks * window_size;
-       info->map.bankwidth = 1;
-
-       /*
-        * map_priv_2 is used to store a ptr to the bank_setup routine
-        */
-       info->map.map_priv_2 = (unsigned long) ixp_data->bank_setup;
-
-       info->map.name = dev_name(&dev->dev);
-       info->map.read = ixp2000_flash_read8;
-       info->map.write = ixp2000_flash_write8;
-       info->map.copy_from = ixp2000_flash_copy_from;
-       info->map.copy_to = ixp2000_flash_copy_to;
-
-       info->res = request_mem_region(dev->resource->start,
-                                      resource_size(dev->resource),
-                                      dev_name(&dev->dev));
-       if (!info->res) {
-               dev_err(&dev->dev, "Could not reserve memory region\n");
-               err = -ENOMEM;
-               goto Error;
-       }
-
-       info->map.map_priv_1 =
-               (unsigned long)ioremap(dev->resource->start,
-                                      resource_size(dev->resource));
-       if (!info->map.map_priv_1) {
-               dev_err(&dev->dev, "Failed to ioremap flash region\n");
-               err = -EIO;
-               goto Error;
-       }
-
-#if defined(__ARMEB__)
-       /*
-        * Enable erratum 44 workaround for NPUs with broken slowport
-        */
-
-       erratum44_workaround = ixp2000_has_broken_slowport();
-       dev_info(&dev->dev, "Erratum 44 workaround %s\n",
-              erratum44_workaround ? "enabled" : "disabled");
-#endif
-
-       info->mtd = do_map_probe(plat->map_name, &info->map);
-       if (!info->mtd) {
-               dev_err(&dev->dev, "map_probe failed\n");
-               err = -ENXIO;
-               goto Error;
-       }
-       info->mtd->owner = THIS_MODULE;
-
-       err = mtd_device_parse_register(info->mtd, probes, NULL, NULL, 0);
-       if (err)
-               goto Error;
-
-       return 0;
-
-Error:
-       ixp2000_flash_remove(dev);
-       return err;
-}
-
-static struct platform_driver ixp2000_flash_driver = {
-       .probe          = ixp2000_flash_probe,
-       .remove         = ixp2000_flash_remove,
-       .driver         = {
-               .name   = "IXP2000-Flash",
-               .owner  = THIS_MODULE,
-       },
-};
-
-module_platform_driver(ixp2000_flash_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
-MODULE_ALIAS("platform:IXP2000-Flash");
index e864fc6c58f9ccd900aad7284570ef70ab919220..52b3410a105c943d47ce3b9ea873781948d028a4 100644 (file)
@@ -148,7 +148,7 @@ struct ixp4xx_flash_info {
        struct resource *res;
 };
 
-static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
+static const char * const probes[] = { "RedBoot", "cmdlinepart", NULL };
 
 static int ixp4xx_flash_remove(struct platform_device *dev)
 {
index d1da6ede3845bfdac001dffb036422d1107bdcd9..d7ac65d1d569dee08e325480501e29cc550ef012 100644 (file)
@@ -46,8 +46,7 @@ struct ltq_mtd {
 };
 
 static const char ltq_map_name[] = "ltq_nor";
-static const char *ltq_probe_types[] = {
-                                       "cmdlinepart", "ofpart", NULL };
+static const char * const ltq_probe_types[] = { "cmdlinepart", "ofpart", NULL };
 
 static map_word
 ltq_read16(struct map_info *map, unsigned long adr)
diff --git a/drivers/mtd/maps/mbx860.c b/drivers/mtd/maps/mbx860.c
deleted file mode 100644 (file)
index 93fa56c..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Handle mapping of the flash on MBX860 boards
- *
- * Author:     Anton Todorov
- * Copyright:  (C) 2001 Emness Technology
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-
-#define WINDOW_ADDR 0xfe000000
-#define WINDOW_SIZE 0x00200000
-
-/* Flash / Partition sizing */
-#define MAX_SIZE_KiB              8192
-#define BOOT_PARTITION_SIZE_KiB    512
-#define KERNEL_PARTITION_SIZE_KiB 5632
-#define APP_PARTITION_SIZE_KiB    2048
-
-#define NUM_PARTITIONS 3
-
-/* partition_info gives details on the logical partitions that the split the
- * single flash device into. If the size if zero we use up to the end of the
- * device. */
-static struct mtd_partition partition_info[]={
-       { .name = "MBX flash BOOT partition",
-       .offset = 0,
-       .size =   BOOT_PARTITION_SIZE_KiB*1024 },
-       { .name = "MBX flash DATA partition",
-       .offset = BOOT_PARTITION_SIZE_KiB*1024,
-       .size = (KERNEL_PARTITION_SIZE_KiB)*1024 },
-       { .name = "MBX flash APPLICATION partition",
-       .offset = (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 }
-};
-
-
-static struct mtd_info *mymtd;
-
-struct map_info mbx_map = {
-       .name = "MBX flash",
-       .size = WINDOW_SIZE,
-       .phys = WINDOW_ADDR,
-       .bankwidth = 4,
-};
-
-static int __init init_mbx(void)
-{
-       printk(KERN_NOTICE "Motorola MBX flash device: 0x%x at 0x%x\n", WINDOW_SIZE*4, WINDOW_ADDR);
-       mbx_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE * 4);
-
-       if (!mbx_map.virt) {
-               printk("Failed to ioremap\n");
-               return -EIO;
-       }
-       simple_map_init(&mbx_map);
-
-       mymtd = do_map_probe("jedec_probe", &mbx_map);
-       if (mymtd) {
-               mymtd->owner = THIS_MODULE;
-               mtd_device_register(mymtd, NULL, 0);
-               mtd_device_register(mymtd, partition_info, NUM_PARTITIONS);
-               return 0;
-       }
-
-       iounmap((void *)mbx_map.virt);
-       return -ENXIO;
-}
-
-static void __exit cleanup_mbx(void)
-{
-       if (mymtd) {
-               mtd_device_unregister(mymtd);
-               map_destroy(mymtd);
-       }
-       if (mbx_map.virt) {
-               iounmap((void *)mbx_map.virt);
-               mbx_map.virt = 0;
-       }
-}
-
-module_init(init_mbx);
-module_exit(cleanup_mbx);
-
-MODULE_AUTHOR("Anton Todorov <a.todorov@emness.com>");
-MODULE_DESCRIPTION("MTD map driver for Motorola MBX860 board");
-MODULE_LICENSE("GPL");
index c3aebd5da5d61046c9f9047148d3d7347a00ec2a..c2604f8b2a5efccd1cde4f77db2be09eb9ce1624 100644 (file)
@@ -283,8 +283,7 @@ static int mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
        if (err)
                goto release;
 
-       /* tsk - do_map_probe should take const char * */
-       mtd = do_map_probe((char *)info->map_name, &map->map);
+       mtd = do_map_probe(info->map_name, &map->map);
        err = -ENODEV;
        if (!mtd)
                goto release;
index 21b0b713cacb8fd8cb1870b6341ac69c08354d19..e7a592c8c76591e02257e5c39b891aefbf43d9d3 100644 (file)
@@ -87,21 +87,18 @@ static void physmap_set_vpp(struct map_info *map, int state)
        spin_unlock_irqrestore(&info->vpp_lock, flags);
 }
 
-static const char *rom_probe_types[] = {
-                                       "cfi_probe",
-                                       "jedec_probe",
-                                       "qinfo_probe",
-                                       "map_rom",
-                                       NULL };
-static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", "afs",
-                                         NULL };
+static const char * const rom_probe_types[] = {
+       "cfi_probe", "jedec_probe", "qinfo_probe", "map_rom", NULL };
+
+static const char * const part_probe_types[] = {
+       "cmdlinepart", "RedBoot", "afs", NULL };
 
 static int physmap_flash_probe(struct platform_device *dev)
 {
        struct physmap_flash_data *physmap_data;
        struct physmap_flash_info *info;
-       const char **probe_type;
-       const char **part_types;
+       const char * const *probe_type;
+       const char * const *part_types;
        int err = 0;
        int i;
        int devices_found = 0;
index 363939dfad05afe9eb24320e31130d99b741080f..d11109762ac5ca311a1f9bb90711bca0855ebc83 100644 (file)
@@ -71,6 +71,9 @@ static int of_flash_remove(struct platform_device *dev)
        return 0;
 }
 
+static const char * const rom_probe_types[] = {
+       "cfi_probe", "jedec_probe", "map_rom" };
+
 /* Helper function to handle probing of the obsolete "direct-mapped"
  * compatible binding, which has an extra "probe-type" property
  * describing the type of flash probe necessary. */
@@ -80,8 +83,6 @@ static struct mtd_info *obsolete_probe(struct platform_device *dev,
        struct device_node *dp = dev->dev.of_node;
        const char *of_probe;
        struct mtd_info *mtd;
-       static const char *rom_probe_types[]
-               = { "cfi_probe", "jedec_probe", "map_rom"};
        int i;
 
        dev_warn(&dev->dev, "Device tree uses obsolete \"direct-mapped\" "
@@ -111,9 +112,10 @@ static struct mtd_info *obsolete_probe(struct platform_device *dev,
    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",
-                                       "ofpart", "ofoldpart", NULL };
-static const char **of_get_probes(struct device_node *dp)
+static const char * const part_probe_types_def[] = {
+       "cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL };
+
+static const char * const *of_get_probes(struct device_node *dp)
 {
        const char *cp;
        int cplen;
@@ -142,7 +144,7 @@ static const char **of_get_probes(struct device_node *dp)
        return res;
 }
 
-static void of_free_probes(const char **probes)
+static void of_free_probes(const char * const *probes)
 {
        if (probes != part_probe_types_def)
                kfree(probes);
@@ -151,7 +153,7 @@ static void of_free_probes(const char **probes)
 static struct of_device_id of_flash_match[];
 static int of_flash_probe(struct platform_device *dev)
 {
-       const char **part_probe_types;
+       const char * const *part_probe_types;
        const struct of_device_id *match;
        struct device_node *dp = dev->dev.of_node;
        struct resource res;
index 2de66b062f0d733be6e97751312d9f576c198236..71fdda29594b7c3595d786c1572012d09b4df8af 100644 (file)
@@ -199,7 +199,7 @@ static int platram_probe(struct platform_device *pdev)
         * supplied by the platform_data struct */
 
        if (pdata->map_probes) {
-               const char **map_probes = pdata->map_probes;
+               const char * const *map_probes = pdata->map_probes;
 
                for ( ; !info->mtd && *map_probes; map_probes++)
                        info->mtd = do_map_probe(*map_probes , &info->map);
index 43e3dbb976d9937e0abf11ad8bab3b08da7f2a26..acb1dbcf7ce58a438ed7ff9a1df9aecb2b57478f 100644 (file)
@@ -45,9 +45,7 @@ struct pxa2xx_flash_info {
        struct map_info         map;
 };
 
-
-static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-
+static const char * const probes[] = { "RedBoot", "cmdlinepart", NULL };
 
 static int pxa2xx_flash_probe(struct platform_device *pdev)
 {
index 49c3fe715eee155cfc7519f5327e5f03640bd3be..ac02fbffd6df940f70e3802895811f5916843541 100644 (file)
@@ -45,14 +45,15 @@ static int rbtx4939_flash_remove(struct platform_device *dev)
        return 0;
 }
 
-static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
+static const char * const rom_probe_types[] = {
+       "cfi_probe", "jedec_probe", NULL };
 
 static int rbtx4939_flash_probe(struct platform_device *dev)
 {
        struct rbtx4939_flash_data *pdata;
        struct rbtx4939_flash_info *info;
        struct resource *res;
-       const char **probe_type;
+       const char * const *probe_type;
        int err = 0;
        unsigned long size;
 
diff --git a/drivers/mtd/maps/rpxlite.c b/drivers/mtd/maps/rpxlite.c
deleted file mode 100644 (file)
index ed88225..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Handle mapping of the flash on the RPX Lite and CLLF boards
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-
-
-#define WINDOW_ADDR 0xfe000000
-#define WINDOW_SIZE 0x800000
-
-static struct mtd_info *mymtd;
-
-static struct map_info rpxlite_map = {
-       .name = "RPX",
-       .size = WINDOW_SIZE,
-       .bankwidth = 4,
-       .phys = WINDOW_ADDR,
-};
-
-static int __init init_rpxlite(void)
-{
-       printk(KERN_NOTICE "RPX Lite or CLLF flash device: %x at %x\n", WINDOW_SIZE*4, WINDOW_ADDR);
-       rpxlite_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE * 4);
-
-       if (!rpxlite_map.virt) {
-               printk("Failed to ioremap\n");
-               return -EIO;
-       }
-       simple_map_init(&rpxlite_map);
-       mymtd = do_map_probe("cfi_probe", &rpxlite_map);
-       if (mymtd) {
-               mymtd->owner = THIS_MODULE;
-               mtd_device_register(mymtd, NULL, 0);
-               return 0;
-       }
-
-       iounmap((void *)rpxlite_map.virt);
-       return -ENXIO;
-}
-
-static void __exit cleanup_rpxlite(void)
-{
-       if (mymtd) {
-               mtd_device_unregister(mymtd);
-               map_destroy(mymtd);
-       }
-       if (rpxlite_map.virt) {
-               iounmap((void *)rpxlite_map.virt);
-               rpxlite_map.virt = 0;
-       }
-}
-
-module_init(init_rpxlite);
-module_exit(cleanup_rpxlite);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Arnold Christensen <AKC@pel.dk>");
-MODULE_DESCRIPTION("MTD map driver for RPX Lite and CLLF boards");
index f694417cf7e694bc3e7f04edef6484ef03449e13..29e3dcaa1d90413b15df9e30c04373d897c2f6c6 100644 (file)
@@ -244,7 +244,7 @@ static struct sa_info *sa1100_setup_mtd(struct platform_device *pdev,
        return ERR_PTR(ret);
 }
 
-static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
+static const char * const part_probes[] = { "cmdlinepart", "RedBoot", NULL };
 
 static int sa1100_mtd_probe(struct platform_device *pdev)
 {
index 9d900ada67084535daa04aa5dd1effb7d9053857..83a7a70915624fbd5ba05a1eaca00a6cf2016d38 100644 (file)
@@ -31,7 +31,7 @@ struct map_info soleng_flash_map = {
        .bankwidth = 4,
 };
 
-static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
+static const char * const probes[] = { "RedBoot", "cmdlinepart", NULL };
 
 #ifdef CONFIG_MTD_SUPERH_RESERVE
 static struct mtd_partition superh_se_partitions[] = {
diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c
deleted file mode 100644 (file)
index d785879..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Handle mapping of the flash memory access routines
- * on TQM8xxL based devices.
- *
- * based on rpxlite.c
- *
- * Copyright(C) 2001 Kirk Lee <kirk@hpc.ee.ntu.edu.tw>
- *
- * This code is GPLed
- *
- */
-
-/*
- * According to TQM8xxL hardware manual, TQM8xxL series have
- * following flash memory organisations:
- *     | capacity |    | chip type |   | bank0 |       | bank1 |
- *         2MiB           512Kx16        2MiB             0
- *         4MiB           1Mx16          4MiB             0
- *         8MiB           1Mx16          4MiB             4MiB
- * Thus, we choose CONFIG_MTD_CFI_I2 & CONFIG_MTD_CFI_B4 at
- * kernel configuration.
- */
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-
-#define FLASH_ADDR 0x40000000
-#define FLASH_SIZE 0x00800000
-#define FLASH_BANK_MAX 4
-
-// trivial struct to describe partition information
-struct mtd_part_def
-{
-       int nums;
-       unsigned char *type;
-       struct mtd_partition* mtd_part;
-};
-
-//static struct mtd_info *mymtd;
-static struct mtd_info* mtd_banks[FLASH_BANK_MAX];
-static struct map_info* map_banks[FLASH_BANK_MAX];
-static struct mtd_part_def part_banks[FLASH_BANK_MAX];
-static unsigned long num_banks;
-static void __iomem *start_scan_addr;
-
-/*
- * Here are partition information for all known TQM8xxL series devices.
- * See include/linux/mtd/partitions.h for definition of the mtd_partition
- * structure.
- *
- * The *_max_flash_size is the maximum possible mapped flash size which
- * is not necessarily the actual flash size.  It must correspond to the
- * value specified in the mapping definition defined by the
- * "struct map_desc *_io_desc" for the corresponding machine.
- */
-
-/* Currently, TQM8xxL has up to 8MiB flash */
-static unsigned long tqm8xxl_max_flash_size = 0x00800000;
-
-/* partition definition for first flash bank
- * (cf. "drivers/char/flash_config.c")
- */
-static struct mtd_partition tqm8xxl_partitions[] = {
-       {
-         .name = "ppcboot",
-         .offset = 0x00000000,
-         .size = 0x00020000,           /* 128KB           */
-         .mask_flags = MTD_WRITEABLE,  /* force read-only */
-       },
-       {
-         .name = "kernel",             /* default kernel image */
-         .offset = 0x00020000,
-         .size = 0x000e0000,
-         .mask_flags = MTD_WRITEABLE,  /* force read-only */
-       },
-       {
-         .name = "user",
-         .offset = 0x00100000,
-         .size = 0x00100000,
-       },
-       {
-         .name = "initrd",
-         .offset = 0x00200000,
-         .size = 0x00200000,
-       }
-};
-/* partition definition for second flash bank */
-static struct mtd_partition tqm8xxl_fs_partitions[] = {
-       {
-         .name = "cramfs",
-         .offset = 0x00000000,
-         .size = 0x00200000,
-       },
-       {
-         .name = "jffs",
-         .offset = 0x00200000,
-         .size = 0x00200000,
-         //.size = MTDPART_SIZ_FULL,
-       }
-};
-
-static int __init init_tqm_mtd(void)
-{
-       int idx = 0, ret = 0;
-       unsigned long flash_addr, flash_size, mtd_size = 0;
-       /* pointer to TQM8xxL board info data */
-       bd_t *bd = (bd_t *)__res;
-
-       flash_addr = bd->bi_flashstart;
-       flash_size = bd->bi_flashsize;
-
-       //request maximum flash size address space
-       start_scan_addr = ioremap(flash_addr, flash_size);
-       if (!start_scan_addr) {
-               printk(KERN_WARNING "%s:Failed to ioremap address:0x%x\n", __func__, flash_addr);
-               return -EIO;
-       }
-
-       for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
-               if(mtd_size >= flash_size)
-                       break;
-
-               printk(KERN_INFO "%s: chip probing count %d\n", __func__, idx);
-
-               map_banks[idx] = kzalloc(sizeof(struct map_info), GFP_KERNEL);
-               if(map_banks[idx] == NULL) {
-                       ret = -ENOMEM;
-                       /* FIXME: What if some MTD devices were probed already? */
-                       goto error_mem;
-               }
-
-               map_banks[idx]->name = kmalloc(16, GFP_KERNEL);
-
-               if (!map_banks[idx]->name) {
-                       ret = -ENOMEM;
-                       /* FIXME: What if some MTD devices were probed already? */
-                       goto error_mem;
-               }
-               sprintf(map_banks[idx]->name, "TQM8xxL%d", idx);
-
-               map_banks[idx]->size = flash_size;
-               map_banks[idx]->bankwidth = 4;
-
-               simple_map_init(map_banks[idx]);
-
-               map_banks[idx]->virt = start_scan_addr;
-               map_banks[idx]->phys = flash_addr;
-               /* FIXME: This looks utterly bogus, but I'm trying to
-                  preserve the behaviour of the original (shown here)...
-
-               map_banks[idx]->map_priv_1 =
-               start_scan_addr + ((idx > 0) ?
-               (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0);
-               */
-
-               if (idx && mtd_banks[idx-1]) {
-                       map_banks[idx]->virt += mtd_banks[idx-1]->size;
-                       map_banks[idx]->phys += mtd_banks[idx-1]->size;
-               }
-
-               //start to probe flash chips
-               mtd_banks[idx] = do_map_probe("cfi_probe", map_banks[idx]);
-
-               if (mtd_banks[idx]) {
-                       mtd_banks[idx]->owner = THIS_MODULE;
-                       mtd_size += mtd_banks[idx]->size;
-                       num_banks++;
-
-                       printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __func__, num_banks,
-                       mtd_banks[idx]->name, mtd_banks[idx]->size);
-               }
-       }
-
-       /* no supported flash chips found */
-       if (!num_banks) {
-               printk(KERN_NOTICE "TQM8xxL: No support flash chips found!\n");
-               ret = -ENXIO;
-               goto error_mem;
-       }
-
-       /*
-        * Select Static partition definitions
-        */
-       part_banks[0].mtd_part = tqm8xxl_partitions;
-       part_banks[0].type = "Static image";
-       part_banks[0].nums = ARRAY_SIZE(tqm8xxl_partitions);
-
-       part_banks[1].mtd_part = tqm8xxl_fs_partitions;
-       part_banks[1].type = "Static file system";
-       part_banks[1].nums = ARRAY_SIZE(tqm8xxl_fs_partitions);
-
-       for(idx = 0; idx < num_banks ; idx++) {
-               if (part_banks[idx].nums == 0)
-                       printk(KERN_NOTICE "TQM flash%d: no partition info available, registering whole flash at once\n", idx);
-               else
-                       printk(KERN_NOTICE "TQM flash%d: Using %s partition definition\n",
-                                       idx, part_banks[idx].type);
-               mtd_device_register(mtd_banks[idx], part_banks[idx].mtd_part,
-               part_banks[idx].nums);
-       }
-       return 0;
-error_mem:
-       for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
-               if(map_banks[idx] != NULL) {
-                       kfree(map_banks[idx]->name);
-                       map_banks[idx]->name = NULL;
-                       kfree(map_banks[idx]);
-                       map_banks[idx] = NULL;
-               }
-       }
-error:
-       iounmap(start_scan_addr);
-       return ret;
-}
-
-static void __exit cleanup_tqm_mtd(void)
-{
-       unsigned int idx = 0;
-       for(idx = 0 ; idx < num_banks ; idx++) {
-               /* destroy mtd_info previously allocated */
-               if (mtd_banks[idx]) {
-                       mtd_device_unregister(mtd_banks[idx]);
-                       map_destroy(mtd_banks[idx]);
-               }
-               /* release map_info not used anymore */
-               kfree(map_banks[idx]->name);
-               kfree(map_banks[idx]);
-       }
-
-       if (start_scan_addr) {
-               iounmap(start_scan_addr);
-               start_scan_addr = 0;
-       }
-}
-
-module_init(init_tqm_mtd);
-module_exit(cleanup_tqm_mtd);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kirk Lee <kirk@hpc.ee.ntu.edu.tw>");
-MODULE_DESCRIPTION("MTD map driver for TQM8xxL boards");
index 1de390e1c2fb3039b98100014e21ac2e6563ba4c..da2cdb5fd6db98862dba7a0fe7c84ca6abd563af 100644 (file)
@@ -82,11 +82,12 @@ static void __exit  cleanup_tsunami_flash(void)
        tsunami_flash_mtd = 0;
 }
 
+static const char * const rom_probe_types[] = {
+       "cfi_probe", "jedec_probe", "map_rom", NULL };
 
 static int __init init_tsunami_flash(void)
 {
-       static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL };
-       char **type;
+       const char * const *type;
 
        tsunami_tig_writeb(FLASH_ENABLE_BYTE, FLASH_ENABLE_PORT);
 
index dc571ebc1aa0be8680f4a20397653e9d4a7f84cf..c719879284bd7b9921a254a70831a39bae644a7d 100644 (file)
@@ -38,6 +38,8 @@
 
 #include <asm/uaccess.h>
 
+#include "mtdcore.h"
+
 static DEFINE_MUTEX(mtd_mutex);
 
 /*
@@ -365,37 +367,35 @@ static void mtdchar_erase_callback (struct erase_info *instr)
        wake_up((wait_queue_head_t *)instr->priv);
 }
 
-#ifdef CONFIG_HAVE_MTD_OTP
 static int otp_select_filemode(struct mtd_file_info *mfi, int mode)
 {
        struct mtd_info *mtd = mfi->mtd;
        size_t retlen;
-       int ret = 0;
-
-       /*
-        * Make a fake call to mtd_read_fact_prot_reg() to check if OTP
-        * operations are supported.
-        */
-       if (mtd_read_fact_prot_reg(mtd, -1, 0, &retlen, NULL) == -EOPNOTSUPP)
-               return -EOPNOTSUPP;
 
        switch (mode) {
        case MTD_OTP_FACTORY:
+               if (mtd_read_fact_prot_reg(mtd, -1, 0, &retlen, NULL) ==
+                               -EOPNOTSUPP)
+                       return -EOPNOTSUPP;
+
                mfi->mode = MTD_FILE_MODE_OTP_FACTORY;
                break;
        case MTD_OTP_USER:
+               if (mtd_read_user_prot_reg(mtd, -1, 0, &retlen, NULL) ==
+                               -EOPNOTSUPP)
+                       return -EOPNOTSUPP;
+
                mfi->mode = MTD_FILE_MODE_OTP_USER;
                break;
-       default:
-               ret = -EINVAL;
        case MTD_OTP_OFF:
+               mfi->mode = MTD_FILE_MODE_NORMAL;
                break;
+       default:
+               return -EINVAL;
        }
-       return ret;
+
+       return 0;
 }
-#else
-# define otp_select_filemode(f,m)      -EOPNOTSUPP
-#endif
 
 static int mtdchar_writeoob(struct file *file, struct mtd_info *mtd,
        uint64_t start, uint32_t length, void __user *ptr,
@@ -888,7 +888,6 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
                break;
        }
 
-#ifdef CONFIG_HAVE_MTD_OTP
        case OTPSELECT:
        {
                int mode;
@@ -944,7 +943,6 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
                ret = mtd_lock_user_prot_reg(mtd, oinfo.start, oinfo.length);
                break;
        }
-#endif
 
        /* This ioctl is being deprecated - it truncates the ECC layout */
        case ECCGETLAYOUT:
@@ -1185,23 +1183,25 @@ static struct file_system_type mtd_inodefs_type = {
 };
 MODULE_ALIAS_FS("mtd_inodefs");
 
-static int __init init_mtdchar(void)
+int __init init_mtdchar(void)
 {
        int ret;
 
        ret = __register_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS,
                                   "mtd", &mtd_fops);
        if (ret < 0) {
-               pr_notice("Can't allocate major number %d for "
-                               "Memory Technology Devices.\n", MTD_CHAR_MAJOR);
+               pr_err("Can't allocate major number %d for MTD\n",
+                      MTD_CHAR_MAJOR);
                return ret;
        }
 
        ret = register_filesystem(&mtd_inodefs_type);
        if (ret) {
-               pr_notice("Can't register mtd_inodefs filesystem: %d\n", ret);
+               pr_err("Can't register mtd_inodefs filesystem, error %d\n",
+                      ret);
                goto err_unregister_chdev;
        }
+
        return ret;
 
 err_unregister_chdev:
@@ -1209,18 +1209,10 @@ err_unregister_chdev:
        return ret;
 }
 
-static void __exit cleanup_mtdchar(void)
+void __exit cleanup_mtdchar(void)
 {
        unregister_filesystem(&mtd_inodefs_type);
        __unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd");
 }
 
-module_init(init_mtdchar);
-module_exit(cleanup_mtdchar);
-
-MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("Direct character-device access to MTD devices");
 MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR);
index 322ca65b0cc59fe5fd0dcf4c13ce71f9f91e2753..c400c57c394aaddb26147bfe2b1955c6716f74d5 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/mtd/partitions.h>
 
 #include "mtdcore.h"
+
 /*
  * backing device capabilities for non-mappable devices (such as NAND flash)
  * - permits private mappings, copies are taken of the data
@@ -97,11 +98,7 @@ EXPORT_SYMBOL_GPL(__mtd_next_device);
 static LIST_HEAD(mtd_notifiers);
 
 
-#if defined(CONFIG_MTD_CHAR) || defined(CONFIG_MTD_CHAR_MODULE)
 #define MTD_DEVT(index) MKDEV(MTD_CHAR_MAJOR, (index)*2)
-#else
-#define MTD_DEVT(index) 0
-#endif
 
 /* REVISIT once MTD uses the driver model better, whoever allocates
  * the mtd_info will probably want to use the release() hook...
@@ -493,7 +490,7 @@ out_error:
  *
  * Returns zero in case of success and a negative error code in case of failure.
  */
-int mtd_device_parse_register(struct mtd_info *mtd, const char **types,
+int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
                              struct mtd_part_parser_data *parser_data,
                              const struct mtd_partition *parts,
                              int nr_parts)
@@ -1117,8 +1114,6 @@ EXPORT_SYMBOL_GPL(mtd_kmalloc_up_to);
 /*====================================================================*/
 /* Support for /proc/mtd */
 
-static struct proc_dir_entry *proc_mtd;
-
 static int mtd_proc_show(struct seq_file *m, void *v)
 {
        struct mtd_info *mtd;
@@ -1164,6 +1159,8 @@ static int __init mtd_bdi_init(struct backing_dev_info *bdi, const char *name)
        return ret;
 }
 
+static struct proc_dir_entry *proc_mtd;
+
 static int __init init_mtd(void)
 {
        int ret;
@@ -1184,11 +1181,17 @@ static int __init init_mtd(void)
        if (ret)
                goto err_bdi3;
 
-#ifdef CONFIG_PROC_FS
        proc_mtd = proc_create("mtd", 0, NULL, &mtd_proc_ops);
-#endif /* CONFIG_PROC_FS */
+
+       ret = init_mtdchar();
+       if (ret)
+               goto out_procfs;
+
        return 0;
 
+out_procfs:
+       if (proc_mtd)
+               remove_proc_entry("mtd", NULL);
 err_bdi3:
        bdi_destroy(&mtd_bdi_ro_mappable);
 err_bdi2:
@@ -1202,10 +1205,9 @@ err_reg:
 
 static void __exit cleanup_mtd(void)
 {
-#ifdef CONFIG_PROC_FS
+       cleanup_mtdchar();
        if (proc_mtd)
-               remove_proc_entry( "mtd", NULL);
-#endif /* CONFIG_PROC_FS */
+               remove_proc_entry("mtd", NULL);
        class_unregister(&mtd_class);
        bdi_destroy(&mtd_bdi_unmappable);
        bdi_destroy(&mtd_bdi_ro_mappable);
index 961a38408542b70df255a8ba05871a2ffb43a3fa..7b0353399a10642f44ca4d15994942066693e9b2 100644 (file)
@@ -1,23 +1,21 @@
-/* linux/drivers/mtd/mtdcore.h
- *
- * Header file for driver private mtdcore exports
- *
+/*
+ * These are exported solely for the purpose of mtd_blkdevs.c and mtdchar.c.
+ * You should not use them for _anything_ else.
  */
 
-/* These are exported solely for the purpose of mtd_blkdevs.c. You
-   should not use them for _anything_ else */
-
 extern struct mutex mtd_table_mutex;
-extern struct mtd_info *__mtd_next_device(int i);
 
-extern int add_mtd_device(struct mtd_info *mtd);
-extern int del_mtd_device(struct mtd_info *mtd);
-extern int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *,
-                             int);
-extern int del_mtd_partitions(struct mtd_info *);
-extern int parse_mtd_partitions(struct mtd_info *master, const char **types,
-                               struct mtd_partition **pparts,
-                               struct mtd_part_parser_data *data);
+struct mtd_info *__mtd_next_device(int i);
+int add_mtd_device(struct mtd_info *mtd);
+int del_mtd_device(struct mtd_info *mtd);
+int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
+int del_mtd_partitions(struct mtd_info *);
+int parse_mtd_partitions(struct mtd_info *master, const char * const *types,
+                        struct mtd_partition **pparts,
+                        struct mtd_part_parser_data *data);
+
+int __init init_mtdchar(void);
+void __exit cleanup_mtdchar(void);
 
 #define mtd_for_each_device(mtd)                       \
        for ((mtd) = __mtd_next_device(0);              \
index 70fa70a8318f4584c473a7fabd35a7bc4fad6027..301493382cd0a27a0df3fe0b5285fdb6a8cbb5f0 100644 (file)
@@ -694,7 +694,7 @@ EXPORT_SYMBOL_GPL(deregister_mtd_parser);
  * Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you
  * are changing this array!
  */
-static const char *default_mtd_part_types[] = {
+static const char * const default_mtd_part_types[] = {
        "cmdlinepart",
        "ofpart",
        NULL
@@ -720,7 +720,7 @@ static const char *default_mtd_part_types[] = {
  * o a positive number of found partitions, in which case on exit @pparts will
  *   point to an array containing this number of &struct mtd_info objects.
  */
-int parse_mtd_partitions(struct mtd_info *master, const char **types,
+int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
                         struct mtd_partition **pparts,
                         struct mtd_part_parser_data *data)
 {
index 5d54ad32697fb9675773eb6c035c7a2058d2dfa3..a60f6c17f57b62acd19528b62a7d1b329df12913 100644 (file)
@@ -41,14 +41,6 @@ config MTD_SM_COMMON
        tristate
        default n
 
-config MTD_NAND_MUSEUM_IDS
-       bool "Enable chip ids for obsolete ancient NAND devices"
-       default n
-       help
-         Enable this option only when your board has first generation
-         NAND chips (page size 256 byte, erase size 4-8KiB). The IDs
-         of these chips were reused by later, larger chips.
-
 config MTD_NAND_DENALI
         tristate "Support Denali NAND controller"
         help
@@ -81,12 +73,6 @@ config MTD_NAND_DENALI_SCRATCH_REG_ADDR
           scratch register here to enable this feature. On Intel Moorestown
           boards, the scratch register is at 0xFF108018.
 
-config MTD_NAND_H1900
-       tristate "iPAQ H1900 flash"
-       depends on ARCH_PXA && BROKEN
-       help
-         This enables the driver for the iPAQ h1900 flash.
-
 config MTD_NAND_GPIO
        tristate "GPIO NAND Flash driver"
        depends on GPIOLIB && ARM
@@ -201,22 +187,6 @@ config MTD_NAND_BF5XX_BOOTROM_ECC
 
          If unsure, say N.
 
-config MTD_NAND_RTC_FROM4
-       tristate "Renesas Flash ROM 4-slot interface board (FROM_BOARD4)"
-       depends on SH_SOLUTION_ENGINE
-       select REED_SOLOMON
-       select REED_SOLOMON_DEC8
-       select BITREVERSE
-       help
-         This enables the driver for the Renesas Technology AG-AND
-         flash interface board (FROM_BOARD4)
-
-config MTD_NAND_PPCHAMELEONEVB
-       tristate "NAND Flash device on PPChameleonEVB board"
-       depends on PPCHAMELEONEVB && BROKEN
-       help
-         This enables the NAND flash driver on the PPChameleon EVB Board.
-
 config MTD_NAND_S3C2410
        tristate "NAND Flash support for Samsung S3C SoCs"
        depends on ARCH_S3C24XX || ARCH_S3C64XX
index d76d912056916a327bcf7ecace6df9dcd06ea97c..bb8189172f62f49871573bb6119555fce1697654 100644 (file)
@@ -15,14 +15,11 @@ obj-$(CONFIG_MTD_NAND_DENALI_PCI)   += denali_pci.o
 obj-$(CONFIG_MTD_NAND_DENALI_DT)       += denali_dt.o
 obj-$(CONFIG_MTD_NAND_AU1550)          += au1550nd.o
 obj-$(CONFIG_MTD_NAND_BF5XX)           += bf5xx_nand.o
-obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB)  += ppchameleonevb.o
 obj-$(CONFIG_MTD_NAND_S3C2410)         += s3c2410.o
 obj-$(CONFIG_MTD_NAND_DAVINCI)         += davinci_nand.o
 obj-$(CONFIG_MTD_NAND_DISKONCHIP)      += diskonchip.o
 obj-$(CONFIG_MTD_NAND_DOCG4)           += docg4.o
 obj-$(CONFIG_MTD_NAND_FSMC)            += fsmc_nand.o
-obj-$(CONFIG_MTD_NAND_H1900)           += h1910.o
-obj-$(CONFIG_MTD_NAND_RTC_FROM4)       += rtc_from4.o
 obj-$(CONFIG_MTD_NAND_SHARPSL)         += sharpsl.o
 obj-$(CONFIG_MTD_NAND_NANDSIM)         += nandsim.o
 obj-$(CONFIG_MTD_NAND_CS553X)          += cs553x_nand.o
index ffcbcca2fd2dbc67627005c177750ef5c35e5da2..2d23d2929438053a255ccad183e111ac7fe633ba 100644 (file)
@@ -1737,20 +1737,7 @@ static struct platform_driver atmel_nand_driver = {
        },
 };
 
-static int __init atmel_nand_init(void)
-{
-       return platform_driver_probe(&atmel_nand_driver, atmel_nand_probe);
-}
-
-
-static void __exit atmel_nand_exit(void)
-{
-       platform_driver_unregister(&atmel_nand_driver);
-}
-
-
-module_init(atmel_nand_init);
-module_exit(atmel_nand_exit);
+module_platform_driver_probe(atmel_nand_driver, atmel_nand_probe);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Rick Bronson");
index 4271e948d1e255b149ce6d5c8c64c38b752ef472..776df3694f755865f88b7e0a499cac533dd04142 100644 (file)
@@ -874,21 +874,7 @@ static struct platform_driver bf5xx_nand_driver = {
        },
 };
 
-static int __init bf5xx_nand_init(void)
-{
-       printk(KERN_INFO "%s, Version %s (c) 2007 Analog Devices, Inc.\n",
-               DRV_DESC, DRV_VERSION);
-
-       return platform_driver_register(&bf5xx_nand_driver);
-}
-
-static void __exit bf5xx_nand_exit(void)
-{
-       platform_driver_unregister(&bf5xx_nand_driver);
-}
-
-module_init(bf5xx_nand_init);
-module_exit(bf5xx_nand_exit);
+module_platform_driver(bf5xx_nand_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR(DRV_AUTHOR);
index 010d612665363632d47f9d0bc75bafdb49c2c9dd..c34985a55101b0606f76ed580f1e13ac562913e2 100644 (file)
@@ -303,13 +303,7 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
        case NAND_CMD_SEQIN:
        case NAND_CMD_RNDIN:
        case NAND_CMD_STATUS:
-       case NAND_CMD_DEPLETE1:
        case NAND_CMD_RNDOUT:
-       case NAND_CMD_STATUS_ERROR:
-       case NAND_CMD_STATUS_ERROR0:
-       case NAND_CMD_STATUS_ERROR1:
-       case NAND_CMD_STATUS_ERROR2:
-       case NAND_CMD_STATUS_ERROR3:
                cafe_writel(cafe, cafe->ctl2, NAND_CTRL2);
                return;
        }
@@ -536,8 +530,8 @@ static int cafe_nand_write_page_lowlevel(struct mtd_info *mtd,
 }
 
 static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
-                               const uint8_t *buf, int oob_required, int page,
-                               int cached, int raw)
+                       uint32_t offset, int data_len, const uint8_t *buf,
+                       int oob_required, int page, int cached, int raw)
 {
        int status;
 
index 94e17af8e4503b423d17f7f0f155d9af928bde90..c3e15a55817349eb4ed2e1c86009b042c38e2405 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
+#include <linux/of.h>
 
 #include <linux/platform_data/mtd-davinci.h>
 #include <linux/platform_data/mtd-davinci-aemif.h>
@@ -577,7 +578,6 @@ static struct davinci_nand_pdata
        return pdev->dev.platform_data;
 }
 #else
-#define davinci_nand_of_match NULL
 static struct davinci_nand_pdata
        *nand_davinci_get_pdata(struct platform_device *pdev)
 {
@@ -878,22 +878,12 @@ static struct platform_driver nand_davinci_driver = {
        .driver         = {
                .name   = "davinci_nand",
                .owner  = THIS_MODULE,
-               .of_match_table = davinci_nand_of_match,
+               .of_match_table = of_match_ptr(davinci_nand_of_match),
        },
 };
 MODULE_ALIAS("platform:davinci_nand");
 
-static int __init nand_davinci_init(void)
-{
-       return platform_driver_probe(&nand_davinci_driver, nand_davinci_probe);
-}
-module_init(nand_davinci_init);
-
-static void __exit nand_davinci_exit(void)
-{
-       platform_driver_unregister(&nand_davinci_driver);
-}
-module_exit(nand_davinci_exit);
+module_platform_driver_probe(nand_davinci_driver, nand_davinci_probe);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Texas Instruments");
index 546f8cb5688d52ce80a10df1cd82810b256a9adb..92530244e2cbfdf48ecc2aa2282b90d12a98d0ad 100644 (file)
@@ -42,7 +42,7 @@ static void __iomem *request_and_map(struct device *dev,
        }
 
        ptr = devm_ioremap_nocache(dev, res->start, resource_size(res));
-       if (!res)
+       if (!ptr)
                dev_err(dev, "ioremap_nocache of %s failed!", res->name);
 
        return ptr;
@@ -90,7 +90,7 @@ static int denali_dt_probe(struct platform_device *ofdev)
        denali->irq = platform_get_irq(ofdev, 0);
        if (denali->irq < 0) {
                dev_err(&ofdev->dev, "no irq defined\n");
-               return -ENXIO;
+               return denali->irq;
        }
 
        denali->flash_reg = request_and_map(&ofdev->dev, denali_reg);
@@ -146,21 +146,11 @@ static struct platform_driver denali_dt_driver = {
        .driver         = {
                .name   = "denali-nand-dt",
                .owner  = THIS_MODULE,
-               .of_match_table = of_match_ptr(denali_nand_dt_ids),
+               .of_match_table = denali_nand_dt_ids,
        },
 };
 
-static int __init denali_init_dt(void)
-{
-       return platform_driver_register(&denali_dt_driver);
-}
-module_init(denali_init_dt);
-
-static void __exit denali_exit_dt(void)
-{
-       platform_driver_unregister(&denali_dt_driver);
-}
-module_exit(denali_exit_dt);
+module_platform_driver(denali_dt_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jamie Iles");
index 18fa4489e52e6687046815b9ed204b4807ebb64c..fa25e7a08134d1cc6bf3d0a68eb15da42a44524b 100644 (file)
@@ -1397,18 +1397,7 @@ static struct platform_driver docg4_driver = {
        .remove         = __exit_p(cleanup_docg4),
 };
 
-static int __init docg4_init(void)
-{
-       return platform_driver_probe(&docg4_driver, probe_docg4);
-}
-
-static void __exit docg4_exit(void)
-{
-       platform_driver_unregister(&docg4_driver);
-}
-
-module_init(docg4_init);
-module_exit(docg4_exit);
+module_platform_driver_probe(docg4_driver, probe_docg4);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Mike Dunn");
index 05ba3f0c2d194ee5c6a0d745f0a78b6744f23486..911e2433fe304b107f1ad8b585621d653578e302 100644 (file)
@@ -1235,18 +1235,7 @@ static struct platform_driver fsmc_nand_driver = {
        },
 };
 
-static int __init fsmc_nand_init(void)
-{
-       return platform_driver_probe(&fsmc_nand_driver,
-                                    fsmc_nand_probe);
-}
-module_init(fsmc_nand_init);
-
-static void __exit fsmc_nand_exit(void)
-{
-       platform_driver_unregister(&fsmc_nand_driver);
-}
-module_exit(fsmc_nand_exit);
+module_platform_driver_probe(fsmc_nand_driver, fsmc_nand_probe);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Vipin Kumar <vipin.kumar@st.com>, Ashish Priyadarshi");
index e789e3f517109402ac35d26fce9e778b7366c3fd..89065dd83d64d7ad64a6d83ca318f36ae65ec6cf 100644 (file)
@@ -190,7 +190,6 @@ static struct resource *gpio_nand_get_io_sync_of(struct platform_device *pdev)
        return r;
 }
 #else /* CONFIG_OF */
-#define gpio_nand_id_table NULL
 static inline int gpio_nand_get_config_of(const struct device *dev,
                                          struct gpio_nand_platdata *plat)
 {
@@ -259,8 +258,6 @@ static int gpio_nand_remove(struct platform_device *dev)
        if (gpio_is_valid(gpiomtd->plat.gpio_rdy))
                gpio_free(gpiomtd->plat.gpio_rdy);
 
-       kfree(gpiomtd);
-
        return 0;
 }
 
@@ -297,7 +294,7 @@ static int gpio_nand_probe(struct platform_device *dev)
        if (!res0)
                return -EINVAL;
 
-       gpiomtd = kzalloc(sizeof(*gpiomtd), GFP_KERNEL);
+       gpiomtd = devm_kzalloc(&dev->dev, sizeof(*gpiomtd), GFP_KERNEL);
        if (gpiomtd == NULL) {
                dev_err(&dev->dev, "failed to create NAND MTD\n");
                return -ENOMEM;
@@ -412,7 +409,6 @@ err_sync:
        iounmap(gpiomtd->nand_chip.IO_ADDR_R);
        release_mem_region(res0->start, resource_size(res0));
 err_map:
-       kfree(gpiomtd);
        return ret;
 }
 
@@ -421,7 +417,7 @@ static struct platform_driver gpio_nand_driver = {
        .remove         = gpio_nand_remove,
        .driver         = {
                .name   = "gpio-nand",
-               .of_match_table = gpio_nand_id_table,
+               .of_match_table = of_match_ptr(gpio_nand_id_table),
        },
 };
 
diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c
deleted file mode 100644 (file)
index 50166e9..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- *  drivers/mtd/nand/h1910.c
- *
- *  Copyright (C) 2003 Joshua Wise (joshua@joshuawise.com)
- *
- *  Derived from drivers/mtd/nand/edb7312.c
- *       Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
- *       Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  Overview:
- *   This is a device driver for the NAND flash device found on the
- *   iPAQ h1910 board which utilizes the Samsung K9F2808 part. This is
- *   a 128Mibit (16MiB x 8 bits) NAND flash device.
- */
-
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-#include <mach/hardware.h>
-#include <asm/sizes.h>
-#include <mach/h1900-gpio.h>
-#include <mach/ipaq.h>
-
-/*
- * MTD structure for EDB7312 board
- */
-static struct mtd_info *h1910_nand_mtd = NULL;
-
-/*
- * Module stuff
- */
-
-/*
- * Define static partitions for flash device
- */
-static struct mtd_partition partition_info[] = {
-      {name:"h1910 NAND Flash",
-             offset:0,
-      size:16 * 1024 * 1024}
-};
-
-#define NUM_PARTITIONS 1
-
-/*
- *     hardware specific access to control-lines
- *
- *     NAND_NCE: bit 0 - don't care
- *     NAND_CLE: bit 1 - address bit 2
- *     NAND_ALE: bit 2 - address bit 3
- */
-static void h1910_hwcontrol(struct mtd_info *mtd, int cmd,
-                           unsigned int ctrl)
-{
-       struct nand_chip *chip = mtd->priv;
-
-       if (cmd != NAND_CMD_NONE)
-               writeb(cmd, chip->IO_ADDR_W | ((ctrl & 0x6) << 1));
-}
-
-/*
- *     read device ready pin
- */
-#if 0
-static int h1910_device_ready(struct mtd_info *mtd)
-{
-       return (GPLR(55) & GPIO_bit(55));
-}
-#endif
-
-/*
- * Main initialization routine
- */
-static int __init h1910_init(void)
-{
-       struct nand_chip *this;
-       void __iomem *nandaddr;
-
-       if (!machine_is_h1900())
-               return -ENODEV;
-
-       nandaddr = ioremap(0x08000000, 0x1000);
-       if (!nandaddr) {
-               printk("Failed to ioremap nand flash.\n");
-               return -ENOMEM;
-       }
-
-       /* Allocate memory for MTD device structure and private data */
-       h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
-       if (!h1910_nand_mtd) {
-               printk("Unable to allocate h1910 NAND MTD device structure.\n");
-               iounmap((void *)nandaddr);
-               return -ENOMEM;
-       }
-
-       /* Get pointer to private data */
-       this = (struct nand_chip *)(&h1910_nand_mtd[1]);
-
-       /* Initialize structures */
-       memset(h1910_nand_mtd, 0, sizeof(struct mtd_info));
-       memset(this, 0, sizeof(struct nand_chip));
-
-       /* Link the private data with the MTD structure */
-       h1910_nand_mtd->priv = this;
-       h1910_nand_mtd->owner = THIS_MODULE;
-
-       /*
-        * Enable VPEN
-        */
-       GPSR(37) = GPIO_bit(37);
-
-       /* insert callbacks */
-       this->IO_ADDR_R = nandaddr;
-       this->IO_ADDR_W = nandaddr;
-       this->cmd_ctrl = h1910_hwcontrol;
-       this->dev_ready = NULL; /* unknown whether that was correct or not so we will just do it like this */
-       /* 15 us command delay time */
-       this->chip_delay = 50;
-       this->ecc.mode = NAND_ECC_SOFT;
-
-       /* Scan to find existence of the device */
-       if (nand_scan(h1910_nand_mtd, 1)) {
-               printk(KERN_NOTICE "No NAND device - returning -ENXIO\n");
-               kfree(h1910_nand_mtd);
-               iounmap((void *)nandaddr);
-               return -ENXIO;
-       }
-
-       /* Register the partitions */
-       mtd_device_parse_register(h1910_nand_mtd, NULL, NULL, partition_info,
-                                 NUM_PARTITIONS);
-
-       /* Return happy */
-       return 0;
-}
-
-module_init(h1910_init);
-
-/*
- * Clean up routine
- */
-static void __exit h1910_cleanup(void)
-{
-       struct nand_chip *this = (struct nand_chip *)&h1910_nand_mtd[1];
-
-       /* Release resources, unregister device */
-       nand_release(h1910_nand_mtd);
-
-       /* Release io resource */
-       iounmap((void *)this->IO_ADDR_W);
-
-       /* Free the MTD device structure */
-       kfree(h1910_nand_mtd);
-}
-
-module_exit(h1910_cleanup);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Joshua Wise <joshua at joshuawise dot com>");
-MODULE_DESCRIPTION("NAND flash driver for iPAQ h1910");
index 0ca22ae9135c6cb9162f06c43f2b316e029e0bab..a94facb46e5ca76bb239af03a32b160571ccd467 100644 (file)
@@ -540,8 +540,8 @@ static int lpc32xx_write_page_lowlevel(struct mtd_info *mtd,
 }
 
 static int lpc32xx_write_page(struct mtd_info *mtd, struct nand_chip *chip,
-                             const uint8_t *buf, int oob_required, int page,
-                             int cached, int raw)
+                       uint32_t offset, int data_len, const uint8_t *buf,
+                       int oob_required, int page, int cached, int raw)
 {
        int res;
 
index 42c63927609dbee8697c691c8e97515cf509b990..dfcd0a565c5b3e8f66d9b24077ae3701f132ee36 100644 (file)
@@ -4,7 +4,6 @@
  *  Overview:
  *   This is the generic MTD driver for NAND flash devices. It should be
  *   capable of working with almost all NAND chips currently available.
- *   Basic support for AG-AND chips is provided.
  *
  *     Additional technical information is available on
  *     http://www.linux-mtd.infradead.org/doc/nand.html
@@ -22,8 +21,6 @@
  *     Enable cached programming for 2k page size chips
  *     Check, if mtd->ecctype should be set to MTD_ECC_HW
  *     if we have HW ECC support.
- *     The AG-AND chips have nice features for speed improvement,
- *     which are not supported yet. Read / program 4 pages in one go.
  *     BBT table is not serialized, has to be fixed
  *
  * This program is free software; you can redistribute it and/or modify
@@ -515,7 +512,7 @@ EXPORT_SYMBOL_GPL(nand_wait_ready);
  * @page_addr: the page address for this command, -1 if none
  *
  * Send command to NAND device. This function is used for small page devices
- * (256/512 Bytes per page).
+ * (512 Bytes per page).
  */
 static void nand_command(struct mtd_info *mtd, unsigned int command,
                         int column, int page_addr)
@@ -631,8 +628,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
        }
 
        /* Command latch cycle */
-       chip->cmd_ctrl(mtd, command & 0xff,
-                      NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
+       chip->cmd_ctrl(mtd, command, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
 
        if (column != -1 || page_addr != -1) {
                int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE;
@@ -671,16 +667,6 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
        case NAND_CMD_SEQIN:
        case NAND_CMD_RNDIN:
        case NAND_CMD_STATUS:
-       case NAND_CMD_DEPLETE1:
-               return;
-
-       case NAND_CMD_STATUS_ERROR:
-       case NAND_CMD_STATUS_ERROR0:
-       case NAND_CMD_STATUS_ERROR1:
-       case NAND_CMD_STATUS_ERROR2:
-       case NAND_CMD_STATUS_ERROR3:
-               /* Read error status commands require only a short delay */
-               udelay(chip->chip_delay);
                return;
 
        case NAND_CMD_RESET:
@@ -836,10 +822,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
         */
        ndelay(100);
 
-       if ((state == FL_ERASING) && (chip->options & NAND_IS_AND))
-               chip->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1);
-       else
-               chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
+       chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
 
        if (in_interrupt() || oops_in_progress)
                panic_nand_wait(mtd, chip, timeo);
@@ -1127,7 +1110,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_read_subpage - [REPLACEABLE] software ECC based sub-page read function
+ * nand_read_subpage - [REPLACEABLE] ECC based sub-page read function
  * @mtd: mtd info structure
  * @chip: nand chip info structure
  * @data_offs: offset of requested data within the page
@@ -1995,6 +1978,67 @@ static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
        return 0;
 }
 
+
+/**
+ * nand_write_subpage_hwecc - [REPLACABLE] hardware ECC based subpage write
+ * @mtd:       mtd info structure
+ * @chip:      nand chip info structure
+ * @column:    column address of subpage within the page
+ * @data_len:  data length
+ * @oob_required: must write chip->oob_poi to OOB
+ */
+static int nand_write_subpage_hwecc(struct mtd_info *mtd,
+                               struct nand_chip *chip, uint32_t offset,
+                               uint32_t data_len, const uint8_t *data_buf,
+                               int oob_required)
+{
+       uint8_t *oob_buf  = chip->oob_poi;
+       uint8_t *ecc_calc = chip->buffers->ecccalc;
+       int ecc_size      = chip->ecc.size;
+       int ecc_bytes     = chip->ecc.bytes;
+       int ecc_steps     = chip->ecc.steps;
+       uint32_t *eccpos  = chip->ecc.layout->eccpos;
+       uint32_t start_step = offset / ecc_size;
+       uint32_t end_step   = (offset + data_len - 1) / ecc_size;
+       int oob_bytes       = mtd->oobsize / ecc_steps;
+       int step, i;
+
+       for (step = 0; step < ecc_steps; step++) {
+               /* configure controller for WRITE access */
+               chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
+
+               /* write data (untouched subpages already masked by 0xFF) */
+               chip->write_buf(mtd, data_buf, ecc_size);
+
+               /* mask ECC of un-touched subpages by padding 0xFF */
+               if ((step < start_step) || (step > end_step))
+                       memset(ecc_calc, 0xff, ecc_bytes);
+               else
+                       chip->ecc.calculate(mtd, data_buf, ecc_calc);
+
+               /* mask OOB of un-touched subpages by padding 0xFF */
+               /* if oob_required, preserve OOB metadata of written subpage */
+               if (!oob_required || (step < start_step) || (step > end_step))
+                       memset(oob_buf, 0xff, oob_bytes);
+
+               data_buf += ecc_size;
+               ecc_calc += ecc_bytes;
+               oob_buf  += oob_bytes;
+       }
+
+       /* copy calculated ECC for whole page to chip->buffer->oob */
+       /* this include masked-value(0xFF) for unwritten subpages */
+       ecc_calc = chip->buffers->ecccalc;
+       for (i = 0; i < chip->ecc.total; i++)
+               chip->oob_poi[eccpos[i]] = ecc_calc[i];
+
+       /* write OOB buffer to NAND device */
+       chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+       return 0;
+}
+
+
 /**
  * nand_write_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page write
  * @mtd: mtd info structure
@@ -2047,6 +2091,8 @@ static int nand_write_page_syndrome(struct mtd_info *mtd,
  * nand_write_page - [REPLACEABLE] write one page
  * @mtd: MTD device structure
  * @chip: NAND chip descriptor
+ * @offset: address offset within the page
+ * @data_len: length of actual data to be written
  * @buf: the data to write
  * @oob_required: must write chip->oob_poi to OOB
  * @page: page number to write
@@ -2054,15 +2100,25 @@ static int nand_write_page_syndrome(struct mtd_info *mtd,
  * @raw: use _raw version of write_page
  */
 static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
-                          const uint8_t *buf, int oob_required, int page,
-                          int cached, int raw)
+               uint32_t offset, int data_len, const uint8_t *buf,
+               int oob_required, int page, int cached, int raw)
 {
-       int status;
+       int status, subpage;
+
+       if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
+               chip->ecc.write_subpage)
+               subpage = offset || (data_len < mtd->writesize);
+       else
+               subpage = 0;
 
        chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
 
        if (unlikely(raw))
-               status = chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
+               status = chip->ecc.write_page_raw(mtd, chip, buf,
+                                                       oob_required);
+       else if (subpage)
+               status = chip->ecc.write_subpage(mtd, chip, offset, data_len,
+                                                        buf, oob_required);
        else
                status = chip->ecc.write_page(mtd, chip, buf, oob_required);
 
@@ -2075,7 +2131,7 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
         */
        cached = 0;
 
-       if (!cached || !(chip->options & NAND_CACHEPRG)) {
+       if (!cached || !NAND_HAS_CACHEPROG(chip)) {
 
                chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
                status = chip->waitfunc(mtd, chip);
@@ -2176,7 +2232,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
 
        uint8_t *oob = ops->oobbuf;
        uint8_t *buf = ops->datbuf;
-       int ret, subpage;
+       int ret;
        int oob_required = oob ? 1 : 0;
 
        ops->retlen = 0;
@@ -2191,10 +2247,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
        }
 
        column = to & (mtd->writesize - 1);
-       subpage = column || (writelen & (mtd->writesize - 1));
-
-       if (subpage && oob)
-               return -EINVAL;
 
        chipnr = (int)(to >> chip->chip_shift);
        chip->select_chip(mtd, chipnr);
@@ -2243,9 +2295,9 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
                        /* We still need to erase leftover OOB data */
                        memset(chip->oob_poi, 0xff, mtd->oobsize);
                }
-
-               ret = chip->write_page(mtd, chip, wbuf, oob_required, page,
-                                      cached, (ops->mode == MTD_OPS_RAW));
+               ret = chip->write_page(mtd, chip, column, bytes, wbuf,
+                                       oob_required, page, cached,
+                                       (ops->mode == MTD_OPS_RAW));
                if (ret)
                        break;
 
@@ -2480,24 +2532,6 @@ static void single_erase_cmd(struct mtd_info *mtd, int page)
        chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
 }
 
-/**
- * multi_erase_cmd - [GENERIC] AND specific block erase command function
- * @mtd: MTD device structure
- * @page: the page address of the block which will be erased
- *
- * AND multi block erase command function. Erase 4 consecutive blocks.
- */
-static void multi_erase_cmd(struct mtd_info *mtd, int page)
-{
-       struct nand_chip *chip = mtd->priv;
-       /* Send commands to erase a block */
-       chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
-       chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
-       chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
-       chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
-       chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
-}
-
 /**
  * nand_erase - [MTD Interface] erase block(s)
  * @mtd: MTD device structure
@@ -2510,7 +2544,6 @@ static int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
        return nand_erase_nand(mtd, instr, 0);
 }
 
-#define BBT_PAGE_MASK  0xffffff3f
 /**
  * nand_erase_nand - [INTERN] erase block(s)
  * @mtd: MTD device structure
@@ -2524,8 +2557,6 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 {
        int page, status, pages_per_block, ret, chipnr;
        struct nand_chip *chip = mtd->priv;
-       loff_t rewrite_bbt[NAND_MAX_CHIPS] = {0};
-       unsigned int bbt_masked_page = 0xffffffff;
        loff_t len;
 
        pr_debug("%s: start = 0x%012llx, len = %llu\n",
@@ -2556,15 +2587,6 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
                goto erase_exit;
        }
 
-       /*
-        * If BBT requires refresh, set the BBT page mask to see if the BBT
-        * should be rewritten. Otherwise the mask is set to 0xffffffff which
-        * can not be matched. This is also done when the bbt is actually
-        * erased to avoid recursive updates.
-        */
-       if (chip->options & BBT_AUTO_REFRESH && !allowbbt)
-               bbt_masked_page = chip->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
-
        /* Loop through the pages */
        len = instr->len;
 
@@ -2610,15 +2632,6 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
                        goto erase_exit;
                }
 
-               /*
-                * If BBT requires refresh, set the BBT rewrite flag to the
-                * page being erased.
-                */
-               if (bbt_masked_page != 0xffffffff &&
-                   (page & BBT_PAGE_MASK) == bbt_masked_page)
-                           rewrite_bbt[chipnr] =
-                                       ((loff_t)page << chip->page_shift);
-
                /* Increment page address and decrement length */
                len -= (1 << chip->phys_erase_shift);
                page += pages_per_block;
@@ -2628,15 +2641,6 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
                        chipnr++;
                        chip->select_chip(mtd, -1);
                        chip->select_chip(mtd, chipnr);
-
-                       /*
-                        * If BBT requires refresh and BBT-PERCHIP, set the BBT
-                        * page mask to see if this BBT should be rewritten.
-                        */
-                       if (bbt_masked_page != 0xffffffff &&
-                           (chip->bbt_td->options & NAND_BBT_PERCHIP))
-                               bbt_masked_page = chip->bbt_td->pages[chipnr] &
-                                       BBT_PAGE_MASK;
                }
        }
        instr->state = MTD_ERASE_DONE;
@@ -2653,23 +2657,6 @@ erase_exit:
        if (!ret)
                mtd_erase_callback(instr);
 
-       /*
-        * If BBT requires refresh and erase was successful, rewrite any
-        * selected bad block tables.
-        */
-       if (bbt_masked_page == 0xffffffff || ret)
-               return ret;
-
-       for (chipnr = 0; chipnr < chip->numchips; chipnr++) {
-               if (!rewrite_bbt[chipnr])
-                       continue;
-               /* Update the BBT for chip */
-               pr_debug("%s: nand_update_bbt (%d:0x%0llx 0x%0x)\n",
-                               __func__, chipnr, rewrite_bbt[chipnr],
-                               chip->bbt_td->pages[chipnr]);
-               nand_update_bbt(mtd, rewrite_bbt[chipnr]);
-       }
-
        /* Return more or less happy */
        return ret;
 }
@@ -2905,8 +2892,6 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
                chip->onfi_version = 20;
        else if (val & (1 << 1))
                chip->onfi_version = 10;
-       else
-               chip->onfi_version = 0;
 
        if (!chip->onfi_version) {
                pr_info("%s: unsupported ONFI version: %d\n", __func__, val);
@@ -3171,6 +3156,30 @@ static void nand_decode_bbm_options(struct mtd_info *mtd,
                chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
 }
 
+static inline bool is_full_id_nand(struct nand_flash_dev *type)
+{
+       return type->id_len;
+}
+
+static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip,
+                  struct nand_flash_dev *type, u8 *id_data, int *busw)
+{
+       if (!strncmp(type->id, id_data, type->id_len)) {
+               mtd->writesize = type->pagesize;
+               mtd->erasesize = type->erasesize;
+               mtd->oobsize = type->oobsize;
+
+               chip->cellinfo = id_data[2];
+               chip->chipsize = (uint64_t)type->chipsize << 20;
+               chip->options |= type->options;
+
+               *busw = type->options & NAND_BUSWIDTH_16;
+
+               return true;
+       }
+       return false;
+}
+
 /*
  * Get the flash and manufacturer id and lookup if the type is supported.
  */
@@ -3222,9 +3231,14 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        if (!type)
                type = nand_flash_ids;
 
-       for (; type->name != NULL; type++)
-               if (*dev_id == type->id)
-                       break;
+       for (; type->name != NULL; type++) {
+               if (is_full_id_nand(type)) {
+                       if (find_full_id_nand(mtd, chip, type, id_data, &busw))
+                               goto ident_done;
+               } else if (*dev_id == type->dev_id) {
+                               break;
+               }
+       }
 
        chip->onfi_version = 0;
        if (!type->name || !type->pagesize) {
@@ -3302,12 +3316,7 @@ ident_done:
        }
 
        chip->badblockbits = 8;
-
-       /* Check for AND chips with 4 page planes */
-       if (chip->options & NAND_4PAGE_ARRAY)
-               chip->erase_cmd = multi_erase_cmd;
-       else
-               chip->erase_cmd = single_erase_cmd;
+       chip->erase_cmd = single_erase_cmd;
 
        /* Do not replace user supplied command function! */
        if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
@@ -3474,6 +3483,10 @@ int nand_scan_tail(struct mtd_info *mtd)
                        chip->ecc.read_oob = nand_read_oob_std;
                if (!chip->ecc.write_oob)
                        chip->ecc.write_oob = nand_write_oob_std;
+               if (!chip->ecc.read_subpage)
+                       chip->ecc.read_subpage = nand_read_subpage;
+               if (!chip->ecc.write_subpage)
+                       chip->ecc.write_subpage = nand_write_subpage_hwecc;
 
        case NAND_ECC_HW_SYNDROME:
                if ((!chip->ecc.calculate || !chip->ecc.correct ||
index 916d6e9c0ab1d9c5872c0ed66b26832ff4bf9062..267264320e06587cbee58ad5e036a38b90f07fe9 100644 (file)
@@ -1240,15 +1240,6 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
  */
 static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
 
-static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 };
-
-static struct nand_bbt_descr agand_flashbased = {
-       .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES,
-       .offs = 0x20,
-       .len = 6,
-       .pattern = scan_agand_pattern
-};
-
 /* Generic flash bbt descriptors */
 static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
 static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
@@ -1333,22 +1324,6 @@ int nand_default_bbt(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
 
-       /*
-        * Default for AG-AND. We must use a flash based bad block table as the
-        * devices have factory marked _good_ blocks. Erasing those blocks
-        * leads to loss of the good / bad information, so we _must_ store this
-        * information in a good / bad table during startup.
-        */
-       if (this->options & NAND_IS_AND) {
-               /* Use the default pattern descriptors */
-               if (!this->bbt_td) {
-                       this->bbt_td = &bbt_main_descr;
-                       this->bbt_md = &bbt_mirror_descr;
-               }
-               this->bbt_options |= NAND_BBT_USE_FLASH;
-               return nand_scan_bbt(mtd, &agand_flashbased);
-       }
-
        /* Is a flash based bad block table requested? */
        if (this->bbt_options & NAND_BBT_USE_FLASH) {
                /* Use the default pattern descriptors */
index 9c612388e5deff15def3bc8014fd1d6408222142..683813a46a905f489feabaced468efd88abc136d 100644 (file)
  */
 #include <linux/module.h>
 #include <linux/mtd/nand.h>
-/*
-*      Chip ID list
-*
-*      Name. ID code, pagesize, chipsize in MegaByte, eraseblock size,
-*      options
-*
-*      Pagesize; 0, 256, 512
-*      0       get this information from the extended chip ID
-+      256     256 Byte page size
-*      512     512 Byte page size
-*/
-struct nand_flash_dev nand_flash_ids[] = {
+#include <linux/sizes.h>
+
+#define LP_OPTIONS NAND_SAMSUNG_LP_OPTIONS
+#define LP_OPTIONS16 (LP_OPTIONS | NAND_BUSWIDTH_16)
+
 #define SP_OPTIONS NAND_NEED_READRDY
 #define SP_OPTIONS16 (SP_OPTIONS | NAND_BUSWIDTH_16)
 
-#ifdef CONFIG_MTD_NAND_MUSEUM_IDS
-       {"NAND 1MiB 5V 8-bit",          0x6e, 256, 1, 0x1000, SP_OPTIONS},
-       {"NAND 2MiB 5V 8-bit",          0x64, 256, 2, 0x1000, SP_OPTIONS},
-       {"NAND 4MiB 5V 8-bit",          0x6b, 512, 4, 0x2000, SP_OPTIONS},
-       {"NAND 1MiB 3,3V 8-bit",        0xe8, 256, 1, 0x1000, SP_OPTIONS},
-       {"NAND 1MiB 3,3V 8-bit",        0xec, 256, 1, 0x1000, SP_OPTIONS},
-       {"NAND 2MiB 3,3V 8-bit",        0xea, 256, 2, 0x1000, SP_OPTIONS},
-       {"NAND 4MiB 3,3V 8-bit",        0xd5, 512, 4, 0x2000, SP_OPTIONS},
-       {"NAND 4MiB 3,3V 8-bit",        0xe3, 512, 4, 0x2000, SP_OPTIONS},
-       {"NAND 4MiB 3,3V 8-bit",        0xe5, 512, 4, 0x2000, SP_OPTIONS},
-       {"NAND 8MiB 3,3V 8-bit",        0xd6, 512, 8, 0x2000, SP_OPTIONS},
-
-       {"NAND 8MiB 1,8V 8-bit",        0x39, 512, 8, 0x2000, SP_OPTIONS},
-       {"NAND 8MiB 3,3V 8-bit",        0xe6, 512, 8, 0x2000, SP_OPTIONS},
-       {"NAND 8MiB 1,8V 16-bit",       0x49, 512, 8, 0x2000, SP_OPTIONS16},
-       {"NAND 8MiB 3,3V 16-bit",       0x59, 512, 8, 0x2000, SP_OPTIONS16},
-#endif
-
-       {"NAND 16MiB 1,8V 8-bit",       0x33, 512, 16, 0x4000, SP_OPTIONS},
-       {"NAND 16MiB 3,3V 8-bit",       0x73, 512, 16, 0x4000, SP_OPTIONS},
-       {"NAND 16MiB 1,8V 16-bit",      0x43, 512, 16, 0x4000, SP_OPTIONS16},
-       {"NAND 16MiB 3,3V 16-bit",      0x53, 512, 16, 0x4000, SP_OPTIONS16},
-
-       {"NAND 32MiB 1,8V 8-bit",       0x35, 512, 32, 0x4000, SP_OPTIONS},
-       {"NAND 32MiB 3,3V 8-bit",       0x75, 512, 32, 0x4000, SP_OPTIONS},
-       {"NAND 32MiB 1,8V 16-bit",      0x45, 512, 32, 0x4000, SP_OPTIONS16},
-       {"NAND 32MiB 3,3V 16-bit",      0x55, 512, 32, 0x4000, SP_OPTIONS16},
-
-       {"NAND 64MiB 1,8V 8-bit",       0x36, 512, 64, 0x4000, SP_OPTIONS},
-       {"NAND 64MiB 3,3V 8-bit",       0x76, 512, 64, 0x4000, SP_OPTIONS},
-       {"NAND 64MiB 1,8V 16-bit",      0x46, 512, 64, 0x4000, SP_OPTIONS16},
-       {"NAND 64MiB 3,3V 16-bit",      0x56, 512, 64, 0x4000, SP_OPTIONS16},
-
-       {"NAND 128MiB 1,8V 8-bit",      0x78, 512, 128, 0x4000, SP_OPTIONS},
-       {"NAND 128MiB 1,8V 8-bit",      0x39, 512, 128, 0x4000, SP_OPTIONS},
-       {"NAND 128MiB 3,3V 8-bit",      0x79, 512, 128, 0x4000, SP_OPTIONS},
-       {"NAND 128MiB 1,8V 16-bit",     0x72, 512, 128, 0x4000, SP_OPTIONS16},
-       {"NAND 128MiB 1,8V 16-bit",     0x49, 512, 128, 0x4000, SP_OPTIONS16},
-       {"NAND 128MiB 3,3V 16-bit",     0x74, 512, 128, 0x4000, SP_OPTIONS16},
-       {"NAND 128MiB 3,3V 16-bit",     0x59, 512, 128, 0x4000, SP_OPTIONS16},
-
-       {"NAND 256MiB 3,3V 8-bit",      0x71, 512, 256, 0x4000, SP_OPTIONS},
+/*
+ * The chip ID list:
+ *    name, device ID, page size, chip size in MiB, eraseblock size, options
+ *
+ * If page size and eraseblock size are 0, the sizes are taken from the
+ * extended chip ID.
+ */
+struct nand_flash_dev nand_flash_ids[] = {
+       /*
+        * Some incompatible NAND chips share device ID's and so must be
+        * listed by full ID. We list them first so that we can easily identify
+        * the most specific match.
+        */
+       {"TC58NVG2S0F 4G 3.3V 8-bit",
+               { .id = {0x98, 0xdc, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08} },
+                 SZ_4K, SZ_512, SZ_256K, 0, 8, 224},
+       {"TC58NVG3S0F 8G 3.3V 8-bit",
+               { .id = {0x98, 0xd3, 0x90, 0x26, 0x76, 0x15, 0x02, 0x08} },
+                 SZ_4K, SZ_1K, SZ_256K, 0, 8, 232},
+       {"TC58NVG5D2 32G 3.3V 8-bit",
+               { .id = {0x98, 0xd7, 0x94, 0x32, 0x76, 0x56, 0x09, 0x00} },
+                 SZ_8K, SZ_4K, SZ_1M, 0, 8, 640},
+       {"TC58NVG6D2 64G 3.3V 8-bit",
+               { .id = {0x98, 0xde, 0x94, 0x82, 0x76, 0x56, 0x04, 0x20} },
+                 SZ_8K, SZ_8K, SZ_2M, 0, 8, 640},
+
+       LEGACY_ID_NAND("NAND 4MiB 5V 8-bit",   0x6B, 4, SZ_8K, SP_OPTIONS),
+       LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE3, 4, SZ_8K, SP_OPTIONS),
+       LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE5, 4, SZ_8K, SP_OPTIONS),
+       LEGACY_ID_NAND("NAND 8MiB 3,3V 8-bit", 0xD6, 8, SZ_8K, SP_OPTIONS),
+       LEGACY_ID_NAND("NAND 8MiB 3,3V 8-bit", 0xE6, 8, SZ_8K, SP_OPTIONS),
+
+       LEGACY_ID_NAND("NAND 16MiB 1,8V 8-bit",  0x33, 16, SZ_16K, SP_OPTIONS),
+       LEGACY_ID_NAND("NAND 16MiB 3,3V 8-bit",  0x73, 16, SZ_16K, SP_OPTIONS),
+       LEGACY_ID_NAND("NAND 16MiB 1,8V 16-bit", 0x43, 16, SZ_16K, SP_OPTIONS16),
+       LEGACY_ID_NAND("NAND 16MiB 3,3V 16-bit", 0x53, 16, SZ_16K, SP_OPTIONS16),
+
+       LEGACY_ID_NAND("NAND 32MiB 1,8V 8-bit",  0x35, 32, SZ_16K, SP_OPTIONS),
+       LEGACY_ID_NAND("NAND 32MiB 3,3V 8-bit",  0x75, 32, SZ_16K, SP_OPTIONS),
+       LEGACY_ID_NAND("NAND 32MiB 1,8V 16-bit", 0x45, 32, SZ_16K, SP_OPTIONS16),
+       LEGACY_ID_NAND("NAND 32MiB 3,3V 16-bit", 0x55, 32, SZ_16K, SP_OPTIONS16),
+
+       LEGACY_ID_NAND("NAND 64MiB 1,8V 8-bit",  0x36, 64, SZ_16K, SP_OPTIONS),
+       LEGACY_ID_NAND("NAND 64MiB 3,3V 8-bit",  0x76, 64, SZ_16K, SP_OPTIONS),
+       LEGACY_ID_NAND("NAND 64MiB 1,8V 16-bit", 0x46, 64, SZ_16K, SP_OPTIONS16),
+       LEGACY_ID_NAND("NAND 64MiB 3,3V 16-bit", 0x56, 64, SZ_16K, SP_OPTIONS16),
+
+       LEGACY_ID_NAND("NAND 128MiB 1,8V 8-bit",  0x78, 128, SZ_16K, SP_OPTIONS),
+       LEGACY_ID_NAND("NAND 128MiB 1,8V 8-bit",  0x39, 128, SZ_16K, SP_OPTIONS),
+       LEGACY_ID_NAND("NAND 128MiB 3,3V 8-bit",  0x79, 128, SZ_16K, SP_OPTIONS),
+       LEGACY_ID_NAND("NAND 128MiB 1,8V 16-bit", 0x72, 128, SZ_16K, SP_OPTIONS16),
+       LEGACY_ID_NAND("NAND 128MiB 1,8V 16-bit", 0x49, 128, SZ_16K, SP_OPTIONS16),
+       LEGACY_ID_NAND("NAND 128MiB 3,3V 16-bit", 0x74, 128, SZ_16K, SP_OPTIONS16),
+       LEGACY_ID_NAND("NAND 128MiB 3,3V 16-bit", 0x59, 128, SZ_16K, SP_OPTIONS16),
+
+       LEGACY_ID_NAND("NAND 256MiB 3,3V 8-bit", 0x71, 256, SZ_16K, SP_OPTIONS),
 
        /*
-        * These are the new chips with large page size. The pagesize and the
-        * erasesize is determined from the extended id bytes
+        * These are the new chips with large page size. Their page size and
+        * eraseblock size are determined from the extended ID bytes.
         */
-#define LP_OPTIONS NAND_SAMSUNG_LP_OPTIONS
-#define LP_OPTIONS16 (LP_OPTIONS | NAND_BUSWIDTH_16)
 
        /* 512 Megabit */
-       {"NAND 64MiB 1,8V 8-bit",       0xA2, 0,  64, 0, LP_OPTIONS},
-       {"NAND 64MiB 1,8V 8-bit",       0xA0, 0,  64, 0, LP_OPTIONS},
-       {"NAND 64MiB 3,3V 8-bit",       0xF2, 0,  64, 0, LP_OPTIONS},
-       {"NAND 64MiB 3,3V 8-bit",       0xD0, 0,  64, 0, LP_OPTIONS},
-       {"NAND 64MiB 3,3V 8-bit",       0xF0, 0,  64, 0, LP_OPTIONS},
-       {"NAND 64MiB 1,8V 16-bit",      0xB2, 0,  64, 0, LP_OPTIONS16},
-       {"NAND 64MiB 1,8V 16-bit",      0xB0, 0,  64, 0, LP_OPTIONS16},
-       {"NAND 64MiB 3,3V 16-bit",      0xC2, 0,  64, 0, LP_OPTIONS16},
-       {"NAND 64MiB 3,3V 16-bit",      0xC0, 0,  64, 0, LP_OPTIONS16},
+       EXTENDED_ID_NAND("NAND 64MiB 1,8V 8-bit",  0xA2,  64, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 64MiB 1,8V 8-bit",  0xA0,  64, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 64MiB 3,3V 8-bit",  0xF2,  64, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 64MiB 3,3V 8-bit",  0xD0,  64, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 64MiB 3,3V 8-bit",  0xF0,  64, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 64MiB 1,8V 16-bit", 0xB2,  64, LP_OPTIONS16),
+       EXTENDED_ID_NAND("NAND 64MiB 1,8V 16-bit", 0xB0,  64, LP_OPTIONS16),
+       EXTENDED_ID_NAND("NAND 64MiB 3,3V 16-bit", 0xC2,  64, LP_OPTIONS16),
+       EXTENDED_ID_NAND("NAND 64MiB 3,3V 16-bit", 0xC0,  64, LP_OPTIONS16),
 
        /* 1 Gigabit */
-       {"NAND 128MiB 1,8V 8-bit",      0xA1, 0, 128, 0, LP_OPTIONS},
-       {"NAND 128MiB 3,3V 8-bit",      0xF1, 0, 128, 0, LP_OPTIONS},
-       {"NAND 128MiB 3,3V 8-bit",      0xD1, 0, 128, 0, LP_OPTIONS},
-       {"NAND 128MiB 1,8V 16-bit",     0xB1, 0, 128, 0, LP_OPTIONS16},
-       {"NAND 128MiB 3,3V 16-bit",     0xC1, 0, 128, 0, LP_OPTIONS16},
-       {"NAND 128MiB 1,8V 16-bit",     0xAD, 0, 128, 0, LP_OPTIONS16},
+       EXTENDED_ID_NAND("NAND 128MiB 1,8V 8-bit",  0xA1, 128, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 128MiB 3,3V 8-bit",  0xF1, 128, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 128MiB 3,3V 8-bit",  0xD1, 128, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 128MiB 1,8V 16-bit", 0xB1, 128, LP_OPTIONS16),
+       EXTENDED_ID_NAND("NAND 128MiB 3,3V 16-bit", 0xC1, 128, LP_OPTIONS16),
+       EXTENDED_ID_NAND("NAND 128MiB 1,8V 16-bit", 0xAD, 128, LP_OPTIONS16),
 
        /* 2 Gigabit */
-       {"NAND 256MiB 1,8V 8-bit",      0xAA, 0, 256, 0, LP_OPTIONS},
-       {"NAND 256MiB 3,3V 8-bit",      0xDA, 0, 256, 0, LP_OPTIONS},
-       {"NAND 256MiB 1,8V 16-bit",     0xBA, 0, 256, 0, LP_OPTIONS16},
-       {"NAND 256MiB 3,3V 16-bit",     0xCA, 0, 256, 0, LP_OPTIONS16},
+       EXTENDED_ID_NAND("NAND 256MiB 1,8V 8-bit",  0xAA, 256, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 256MiB 3,3V 8-bit",  0xDA, 256, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 256MiB 1,8V 16-bit", 0xBA, 256, LP_OPTIONS16),
+       EXTENDED_ID_NAND("NAND 256MiB 3,3V 16-bit", 0xCA, 256, LP_OPTIONS16),
 
        /* 4 Gigabit */
-       {"NAND 512MiB 1,8V 8-bit",      0xAC, 0, 512, 0, LP_OPTIONS},
-       {"NAND 512MiB 3,3V 8-bit",      0xDC, 0, 512, 0, LP_OPTIONS},
-       {"NAND 512MiB 1,8V 16-bit",     0xBC, 0, 512, 0, LP_OPTIONS16},
-       {"NAND 512MiB 3,3V 16-bit",     0xCC, 0, 512, 0, LP_OPTIONS16},
+       EXTENDED_ID_NAND("NAND 512MiB 1,8V 8-bit",  0xAC, 512, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 512MiB 3,3V 8-bit",  0xDC, 512, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 512MiB 1,8V 16-bit", 0xBC, 512, LP_OPTIONS16),
+       EXTENDED_ID_NAND("NAND 512MiB 3,3V 16-bit", 0xCC, 512, LP_OPTIONS16),
 
        /* 8 Gigabit */
-       {"NAND 1GiB 1,8V 8-bit",        0xA3, 0, 1024, 0, LP_OPTIONS},
-       {"NAND 1GiB 3,3V 8-bit",        0xD3, 0, 1024, 0, LP_OPTIONS},
-       {"NAND 1GiB 1,8V 16-bit",       0xB3, 0, 1024, 0, LP_OPTIONS16},
-       {"NAND 1GiB 3,3V 16-bit",       0xC3, 0, 1024, 0, LP_OPTIONS16},
+       EXTENDED_ID_NAND("NAND 1GiB 1,8V 8-bit",  0xA3, 1024, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 1GiB 3,3V 8-bit",  0xD3, 1024, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 1GiB 1,8V 16-bit", 0xB3, 1024, LP_OPTIONS16),
+       EXTENDED_ID_NAND("NAND 1GiB 3,3V 16-bit", 0xC3, 1024, LP_OPTIONS16),
 
        /* 16 Gigabit */
-       {"NAND 2GiB 1,8V 8-bit",        0xA5, 0, 2048, 0, LP_OPTIONS},
-       {"NAND 2GiB 3,3V 8-bit",        0xD5, 0, 2048, 0, LP_OPTIONS},
-       {"NAND 2GiB 1,8V 16-bit",       0xB5, 0, 2048, 0, LP_OPTIONS16},
-       {"NAND 2GiB 3,3V 16-bit",       0xC5, 0, 2048, 0, LP_OPTIONS16},
+       EXTENDED_ID_NAND("NAND 2GiB 1,8V 8-bit",  0xA5, 2048, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 2GiB 3,3V 8-bit",  0xD5, 2048, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 2GiB 1,8V 16-bit", 0xB5, 2048, LP_OPTIONS16),
+       EXTENDED_ID_NAND("NAND 2GiB 3,3V 16-bit", 0xC5, 2048, LP_OPTIONS16),
 
        /* 32 Gigabit */
-       {"NAND 4GiB 1,8V 8-bit",        0xA7, 0, 4096, 0, LP_OPTIONS},
-       {"NAND 4GiB 3,3V 8-bit",        0xD7, 0, 4096, 0, LP_OPTIONS},
-       {"NAND 4GiB 1,8V 16-bit",       0xB7, 0, 4096, 0, LP_OPTIONS16},
-       {"NAND 4GiB 3,3V 16-bit",       0xC7, 0, 4096, 0, LP_OPTIONS16},
+       EXTENDED_ID_NAND("NAND 4GiB 1,8V 8-bit",  0xA7, 4096, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 4GiB 3,3V 8-bit",  0xD7, 4096, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 4GiB 1,8V 16-bit", 0xB7, 4096, LP_OPTIONS16),
+       EXTENDED_ID_NAND("NAND 4GiB 3,3V 16-bit", 0xC7, 4096, LP_OPTIONS16),
 
        /* 64 Gigabit */
-       {"NAND 8GiB 1,8V 8-bit",        0xAE, 0, 8192, 0, LP_OPTIONS},
-       {"NAND 8GiB 3,3V 8-bit",        0xDE, 0, 8192, 0, LP_OPTIONS},
-       {"NAND 8GiB 1,8V 16-bit",       0xBE, 0, 8192, 0, LP_OPTIONS16},
-       {"NAND 8GiB 3,3V 16-bit",       0xCE, 0, 8192, 0, LP_OPTIONS16},
+       EXTENDED_ID_NAND("NAND 8GiB 1,8V 8-bit",  0xAE, 8192, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 8GiB 3,3V 8-bit",  0xDE, 8192, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 8GiB 1,8V 16-bit", 0xBE, 8192, LP_OPTIONS16),
+       EXTENDED_ID_NAND("NAND 8GiB 3,3V 16-bit", 0xCE, 8192, LP_OPTIONS16),
 
        /* 128 Gigabit */
-       {"NAND 16GiB 1,8V 8-bit",       0x1A, 0, 16384, 0, LP_OPTIONS},
-       {"NAND 16GiB 3,3V 8-bit",       0x3A, 0, 16384, 0, LP_OPTIONS},
-       {"NAND 16GiB 1,8V 16-bit",      0x2A, 0, 16384, 0, LP_OPTIONS16},
-       {"NAND 16GiB 3,3V 16-bit",      0x4A, 0, 16384, 0, LP_OPTIONS16},
+       EXTENDED_ID_NAND("NAND 16GiB 1,8V 8-bit",  0x1A, 16384, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 16GiB 3,3V 8-bit",  0x3A, 16384, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 16GiB 1,8V 16-bit", 0x2A, 16384, LP_OPTIONS16),
+       EXTENDED_ID_NAND("NAND 16GiB 3,3V 16-bit", 0x4A, 16384, LP_OPTIONS16),
 
        /* 256 Gigabit */
-       {"NAND 32GiB 1,8V 8-bit",       0x1C, 0, 32768, 0, LP_OPTIONS},
-       {"NAND 32GiB 3,3V 8-bit",       0x3C, 0, 32768, 0, LP_OPTIONS},
-       {"NAND 32GiB 1,8V 16-bit",      0x2C, 0, 32768, 0, LP_OPTIONS16},
-       {"NAND 32GiB 3,3V 16-bit",      0x4C, 0, 32768, 0, LP_OPTIONS16},
+       EXTENDED_ID_NAND("NAND 32GiB 1,8V 8-bit",  0x1C, 32768, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 32GiB 3,3V 8-bit",  0x3C, 32768, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 32GiB 1,8V 16-bit", 0x2C, 32768, LP_OPTIONS16),
+       EXTENDED_ID_NAND("NAND 32GiB 3,3V 16-bit", 0x4C, 32768, LP_OPTIONS16),
 
        /* 512 Gigabit */
-       {"NAND 64GiB 1,8V 8-bit",       0x1E, 0, 65536, 0, LP_OPTIONS},
-       {"NAND 64GiB 3,3V 8-bit",       0x3E, 0, 65536, 0, LP_OPTIONS},
-       {"NAND 64GiB 1,8V 16-bit",      0x2E, 0, 65536, 0, LP_OPTIONS16},
-       {"NAND 64GiB 3,3V 16-bit",      0x4E, 0, 65536, 0, LP_OPTIONS16},
+       EXTENDED_ID_NAND("NAND 64GiB 1,8V 8-bit",  0x1E, 65536, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 64GiB 3,3V 8-bit",  0x3E, 65536, LP_OPTIONS),
+       EXTENDED_ID_NAND("NAND 64GiB 1,8V 16-bit", 0x2E, 65536, LP_OPTIONS16),
+       EXTENDED_ID_NAND("NAND 64GiB 3,3V 16-bit", 0x4E, 65536, LP_OPTIONS16),
 
-       /*
-        * Renesas AND 1 Gigabit. Those chips do not support extended id and
-        * have a strange page/block layout !  The chosen minimum erasesize is
-        * 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page
-        * planes 1 block = 2 pages, but due to plane arrangement the blocks
-        * 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 Anyway JFFS2 would
-        * increase the eraseblock size so we chose a combined one which can be
-        * erased in one go There are more speed improvements for reads and
-        * writes possible, but not implemented now
-        */
-       {"AND 128MiB 3,3V 8-bit",       0x01, 2048, 128, 0x4000,
-        NAND_IS_AND | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},
-
-       {NULL,}
+       {NULL}
 };
 
-/*
-*      Manufacturer ID list
-*/
+/* Manufacturer IDs */
 struct nand_manufacturers nand_manuf_ids[] = {
        {NAND_MFR_TOSHIBA, "Toshiba"},
        {NAND_MFR_SAMSUNG, "Samsung"},
index 891c52a30e6a48468d593926261ea8eee23260d9..cb38f3d94218b2c977437062f8f402d07941fd6c 100644 (file)
@@ -218,7 +218,6 @@ MODULE_PARM_DESC(bch,                "Enable BCH ecc and set how many bits should "
 #define STATE_CMD_READOOB      0x00000005 /* read OOB area */
 #define STATE_CMD_ERASE1       0x00000006 /* sector erase first command */
 #define STATE_CMD_STATUS       0x00000007 /* read status */
-#define STATE_CMD_STATUS_M     0x00000008 /* read multi-plane status (isn't implemented) */
 #define STATE_CMD_SEQIN        0x00000009 /* sequential data input */
 #define STATE_CMD_READID       0x0000000A /* read ID */
 #define STATE_CMD_ERASE2       0x0000000B /* sector erase second command */
@@ -263,14 +262,13 @@ MODULE_PARM_DESC(bch,              "Enable BCH ecc and set how many bits should "
 #define NS_OPER_STATES   6  /* Maximum number of states in operation */
 
 #define OPT_ANY          0xFFFFFFFF /* any chip supports this operation */
-#define OPT_PAGE256      0x00000001 /* 256-byte  page chips */
 #define OPT_PAGE512      0x00000002 /* 512-byte  page chips */
 #define OPT_PAGE2048     0x00000008 /* 2048-byte page chips */
 #define OPT_SMARTMEDIA   0x00000010 /* SmartMedia technology chips */
 #define OPT_PAGE512_8BIT 0x00000040 /* 512-byte page chips with 8-bit bus width */
 #define OPT_PAGE4096     0x00000080 /* 4096-byte page chips */
 #define OPT_LARGEPAGE    (OPT_PAGE2048 | OPT_PAGE4096) /* 2048 & 4096-byte page chips */
-#define OPT_SMALLPAGE    (OPT_PAGE256  | OPT_PAGE512)  /* 256 and 512-byte page chips */
+#define OPT_SMALLPAGE    (OPT_PAGE512) /* 512-byte page chips */
 
 /* Remove action bits from state */
 #define NS_STATE(x) ((x) & ~ACTION_MASK)
@@ -406,8 +404,6 @@ static struct nandsim_operations {
        {OPT_ANY, {STATE_CMD_ERASE1, STATE_ADDR_SEC, STATE_CMD_ERASE2 | ACTION_SECERASE, STATE_READY}},
        /* Read status */
        {OPT_ANY, {STATE_CMD_STATUS, STATE_DATAOUT_STATUS, STATE_READY}},
-       /* Read multi-plane status */
-       {OPT_SMARTMEDIA, {STATE_CMD_STATUS_M, STATE_DATAOUT_STATUS_M, STATE_READY}},
        /* Read ID */
        {OPT_ANY, {STATE_CMD_READID, STATE_ADDR_ZERO, STATE_DATAOUT_ID, STATE_READY}},
        /* Large page devices read page */
@@ -699,10 +695,7 @@ static int init_nandsim(struct mtd_info *mtd)
        ns->geom.secszoob = ns->geom.secsz + ns->geom.oobsz * ns->geom.pgsec;
        ns->options = 0;
 
-       if (ns->geom.pgsz == 256) {
-               ns->options |= OPT_PAGE256;
-       }
-       else if (ns->geom.pgsz == 512) {
+       if (ns->geom.pgsz == 512) {
                ns->options |= OPT_PAGE512;
                if (ns->busw == 8)
                        ns->options |= OPT_PAGE512_8BIT;
@@ -769,9 +762,9 @@ static int init_nandsim(struct mtd_info *mtd)
        }
 
        /* Detect how many ID bytes the NAND chip outputs */
-        for (i = 0; nand_flash_ids[i].name != NULL; i++) {
-                if (second_id_byte != nand_flash_ids[i].id)
-                        continue;
+       for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+               if (second_id_byte != nand_flash_ids[i].dev_id)
+                       continue;
        }
 
        if (ns->busw == 16)
@@ -1079,8 +1072,6 @@ static char *get_state_name(uint32_t state)
                        return "STATE_CMD_ERASE1";
                case STATE_CMD_STATUS:
                        return "STATE_CMD_STATUS";
-               case STATE_CMD_STATUS_M:
-                       return "STATE_CMD_STATUS_M";
                case STATE_CMD_SEQIN:
                        return "STATE_CMD_SEQIN";
                case STATE_CMD_READID:
@@ -1145,7 +1136,6 @@ static int check_command(int cmd)
        case NAND_CMD_RNDOUTSTART:
                return 0;
 
-       case NAND_CMD_STATUS_MULTI:
        default:
                return 1;
        }
@@ -1171,8 +1161,6 @@ static uint32_t get_state_by_command(unsigned command)
                        return STATE_CMD_ERASE1;
                case NAND_CMD_STATUS:
                        return STATE_CMD_STATUS;
-               case NAND_CMD_STATUS_MULTI:
-                       return STATE_CMD_STATUS_M;
                case NAND_CMD_SEQIN:
                        return STATE_CMD_SEQIN;
                case NAND_CMD_READID:
@@ -2306,7 +2294,7 @@ static int __init ns_init_module(void)
                nand->geom.idbytes = 2;
        nand->regs.status = NS_STATUS_OK(nand);
        nand->nxstate = STATE_UNKNOWN;
-       nand->options |= OPT_PAGE256; /* temporary value */
+       nand->options |= OPT_PAGE512; /* temporary value */
        nand->ids[0] = first_id_byte;
        nand->ids[1] = second_id_byte;
        nand->ids[2] = third_id_byte;
index a6191198d259f02b4f1b14e6437eec5d71ea9a30..cd6be2ed53a86a86a1baca65440adb73183d10a8 100644 (file)
@@ -177,15 +177,6 @@ static void nuc900_nand_command_lp(struct mtd_info *mtd, unsigned int command,
        case NAND_CMD_SEQIN:
        case NAND_CMD_RNDIN:
        case NAND_CMD_STATUS:
-       case NAND_CMD_DEPLETE1:
-               return;
-
-       case NAND_CMD_STATUS_ERROR:
-       case NAND_CMD_STATUS_ERROR0:
-       case NAND_CMD_STATUS_ERROR1:
-       case NAND_CMD_STATUS_ERROR2:
-       case NAND_CMD_STATUS_ERROR3:
-               udelay(chip->chip_delay);
                return;
 
        case NAND_CMD_RESET:
index 8e820ddf4e085ba0091c7238085395b40c4b0c39..81b80af55872a4f2481dd6d3d0c61b762e02ff51 100644 (file)
@@ -1023,9 +1023,9 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
        int status, state = this->state;
 
        if (state == FL_ERASING)
-               timeo += (HZ * 400) / 1000;
+               timeo += msecs_to_jiffies(400);
        else
-               timeo += (HZ * 20) / 1000;
+               timeo += msecs_to_jiffies(20);
 
        writeb(NAND_CMD_STATUS & 0xFF, info->reg.gpmc_nand_command);
        while (time_before(jiffies, timeo)) {
@@ -1701,8 +1701,9 @@ static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
                elm_node = of_find_node_by_phandle(be32_to_cpup(parp));
                pdev = of_find_device_by_node(elm_node);
                info->elm_dev = &pdev->dev;
-               elm_config(info->elm_dev, bch_type);
-               info->is_elm_used = true;
+
+               if (elm_config(info->elm_dev, bch_type) == 0)
+                       info->is_elm_used = true;
        }
 
        if (info->is_elm_used && (mtd->writesize <= 4096)) {
index cd72b9299f6b1af0f3491281cbccf1595f0b2a2b..8fbd002086107f1fff96d26307e9b670b1ca7d95 100644 (file)
@@ -231,18 +231,7 @@ static struct platform_driver orion_nand_driver = {
        },
 };
 
-static int __init orion_nand_init(void)
-{
-       return platform_driver_probe(&orion_nand_driver, orion_nand_probe);
-}
-
-static void __exit orion_nand_exit(void)
-{
-       platform_driver_unregister(&orion_nand_driver);
-}
-
-module_init(orion_nand_init);
-module_exit(orion_nand_exit);
+module_platform_driver_probe(orion_nand_driver, orion_nand_probe);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Tzachi Perelstein");
diff --git a/drivers/mtd/nand/ppchameleonevb.c b/drivers/mtd/nand/ppchameleonevb.c
deleted file mode 100644 (file)
index 0ddd90e..0000000
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- *  drivers/mtd/nand/ppchameleonevb.c
- *
- *  Copyright (C) 2003 DAVE Srl (info@wawnet.biz)
- *
- *  Derived from drivers/mtd/nand/edb7312.c
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  Overview:
- *   This is a device driver for the NAND flash devices found on the
- *   PPChameleon/PPChameleonEVB system.
- *   PPChameleon options (autodetected):
- *   - BA model: no NAND
- *   - ME model: 32MB (Samsung K9F5608U0B)
- *   - HI model: 128MB (Samsung K9F1G08UOM)
- *   PPChameleonEVB options:
- *   - 32MB (Samsung K9F5608U0B)
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-#include <platforms/PPChameleonEVB.h>
-
-#undef USE_READY_BUSY_PIN
-#define USE_READY_BUSY_PIN
-/* see datasheets (tR) */
-#define NAND_BIG_DELAY_US              25
-#define NAND_SMALL_DELAY_US            10
-
-/* handy sizes */
-#define SZ_4M                           0x00400000
-#define NAND_SMALL_SIZE                 0x02000000
-#define NAND_MTD_NAME          "ppchameleon-nand"
-#define NAND_EVB_MTD_NAME      "ppchameleonevb-nand"
-
-/* GPIO pins used to drive NAND chip mounted on processor module */
-#define NAND_nCE_GPIO_PIN              (0x80000000 >> 1)
-#define NAND_CLE_GPIO_PIN              (0x80000000 >> 2)
-#define NAND_ALE_GPIO_PIN              (0x80000000 >> 3)
-#define NAND_RB_GPIO_PIN               (0x80000000 >> 4)
-/* GPIO pins used to drive NAND chip mounted on EVB */
-#define NAND_EVB_nCE_GPIO_PIN  (0x80000000 >> 14)
-#define NAND_EVB_CLE_GPIO_PIN  (0x80000000 >> 15)
-#define NAND_EVB_ALE_GPIO_PIN  (0x80000000 >> 16)
-#define NAND_EVB_RB_GPIO_PIN   (0x80000000 >> 31)
-
-/*
- * MTD structure for PPChameleonEVB board
- */
-static struct mtd_info *ppchameleon_mtd = NULL;
-static struct mtd_info *ppchameleonevb_mtd = NULL;
-
-/*
- * Module stuff
- */
-static unsigned long ppchameleon_fio_pbase = CFG_NAND0_PADDR;
-static unsigned long ppchameleonevb_fio_pbase = CFG_NAND1_PADDR;
-
-#ifdef MODULE
-module_param(ppchameleon_fio_pbase, ulong, 0);
-module_param(ppchameleonevb_fio_pbase, ulong, 0);
-#else
-__setup("ppchameleon_fio_pbase=", ppchameleon_fio_pbase);
-__setup("ppchameleonevb_fio_pbase=", ppchameleonevb_fio_pbase);
-#endif
-
-/*
- * Define static partitions for flash devices
- */
-static struct mtd_partition partition_info_hi[] = {
-      { .name = "PPChameleon HI Nand Flash",
-       .offset = 0,
-       .size = 128 * 1024 * 1024
-      }
-};
-
-static struct mtd_partition partition_info_me[] = {
-      { .name = "PPChameleon ME Nand Flash",
-       .offset = 0,
-       .size = 32 * 1024 * 1024
-      }
-};
-
-static struct mtd_partition partition_info_evb[] = {
-      { .name = "PPChameleonEVB Nand Flash",
-       .offset = 0,
-       .size = 32 * 1024 * 1024
-      }
-};
-
-#define NUM_PARTITIONS 1
-
-/*
- *     hardware specific access to control-lines
- */
-static void ppchameleon_hwcontrol(struct mtd_info *mtdinfo, int cmd,
-                                 unsigned int ctrl)
-{
-       struct nand_chip *chip = mtd->priv;
-
-       if (ctrl & NAND_CTRL_CHANGE) {
-#error Missing headerfiles. No way to fix this. -tglx
-               switch (cmd) {
-               case NAND_CTL_SETCLE:
-                       MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND0_PADDR);
-                       break;
-               case NAND_CTL_CLRCLE:
-                       MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND0_PADDR);
-                       break;
-               case NAND_CTL_SETALE:
-                       MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND0_PADDR);
-                       break;
-               case NAND_CTL_CLRALE:
-                       MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND0_PADDR);
-                       break;
-               case NAND_CTL_SETNCE:
-                       MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND0_PADDR);
-                       break;
-               case NAND_CTL_CLRNCE:
-                       MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND0_PADDR);
-                       break;
-               }
-       }
-       if (cmd != NAND_CMD_NONE)
-               writeb(cmd, chip->IO_ADDR_W);
-}
-
-static void ppchameleonevb_hwcontrol(struct mtd_info *mtdinfo, int cmd,
-                                    unsigned int ctrl)
-{
-       struct nand_chip *chip = mtd->priv;
-
-       if (ctrl & NAND_CTRL_CHANGE) {
-#error Missing headerfiles. No way to fix this. -tglx
-               switch (cmd) {
-               case NAND_CTL_SETCLE:
-                       MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND1_PADDR);
-                       break;
-               case NAND_CTL_CLRCLE:
-                       MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND1_PADDR);
-                       break;
-               case NAND_CTL_SETALE:
-                       MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND1_PADDR);
-                       break;
-               case NAND_CTL_CLRALE:
-                       MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND1_PADDR);
-                       break;
-               case NAND_CTL_SETNCE:
-                       MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND1_PADDR);
-                       break;
-               case NAND_CTL_CLRNCE:
-                       MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND1_PADDR);
-                       break;
-               }
-       }
-       if (cmd != NAND_CMD_NONE)
-               writeb(cmd, chip->IO_ADDR_W);
-}
-
-#ifdef USE_READY_BUSY_PIN
-/*
- *     read device ready pin
- */
-static int ppchameleon_device_ready(struct mtd_info *minfo)
-{
-       if (in_be32((volatile unsigned *)GPIO0_IR) & NAND_RB_GPIO_PIN)
-               return 1;
-       return 0;
-}
-
-static int ppchameleonevb_device_ready(struct mtd_info *minfo)
-{
-       if (in_be32((volatile unsigned *)GPIO0_IR) & NAND_EVB_RB_GPIO_PIN)
-               return 1;
-       return 0;
-}
-#endif
-
-/*
- * Main initialization routine
- */
-static int __init ppchameleonevb_init(void)
-{
-       struct nand_chip *this;
-       void __iomem *ppchameleon_fio_base;
-       void __iomem *ppchameleonevb_fio_base;
-
-       /*********************************
-       * Processor module NAND (if any) *
-       *********************************/
-       /* Allocate memory for MTD device structure and private data */
-       ppchameleon_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
-       if (!ppchameleon_mtd) {
-               printk("Unable to allocate PPChameleon NAND MTD device structure.\n");
-               return -ENOMEM;
-       }
-
-       /* map physical address */
-       ppchameleon_fio_base = ioremap(ppchameleon_fio_pbase, SZ_4M);
-       if (!ppchameleon_fio_base) {
-               printk("ioremap PPChameleon NAND flash failed\n");
-               kfree(ppchameleon_mtd);
-               return -EIO;
-       }
-
-       /* Get pointer to private data */
-       this = (struct nand_chip *)(&ppchameleon_mtd[1]);
-
-       /* Initialize structures */
-       memset(ppchameleon_mtd, 0, sizeof(struct mtd_info));
-       memset(this, 0, sizeof(struct nand_chip));
-
-       /* Link the private data with the MTD structure */
-       ppchameleon_mtd->priv = this;
-       ppchameleon_mtd->owner = THIS_MODULE;
-
-       /* Initialize GPIOs */
-       /* Pin mapping for NAND chip */
-       /*
-          CE   GPIO_01
-          CLE  GPIO_02
-          ALE  GPIO_03
-          R/B  GPIO_04
-        */
-       /* output select */
-       out_be32((volatile unsigned *)GPIO0_OSRH, in_be32((volatile unsigned *)GPIO0_OSRH) & 0xC0FFFFFF);
-       /* three-state select */
-       out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xC0FFFFFF);
-       /* enable output driver */
-       out_be32((volatile unsigned *)GPIO0_TCR,
-                in_be32((volatile unsigned *)GPIO0_TCR) | NAND_nCE_GPIO_PIN | NAND_CLE_GPIO_PIN | NAND_ALE_GPIO_PIN);
-#ifdef USE_READY_BUSY_PIN
-       /* three-state select */
-       out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xFF3FFFFF);
-       /* high-impedecence */
-       out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) & (~NAND_RB_GPIO_PIN));
-       /* input select */
-       out_be32((volatile unsigned *)GPIO0_ISR1H,
-                (in_be32((volatile unsigned *)GPIO0_ISR1H) & 0xFF3FFFFF) | 0x00400000);
-#endif
-
-       /* insert callbacks */
-       this->IO_ADDR_R = ppchameleon_fio_base;
-       this->IO_ADDR_W = ppchameleon_fio_base;
-       this->cmd_ctrl = ppchameleon_hwcontrol;
-#ifdef USE_READY_BUSY_PIN
-       this->dev_ready = ppchameleon_device_ready;
-#endif
-       this->chip_delay = NAND_BIG_DELAY_US;
-       /* ECC mode */
-       this->ecc.mode = NAND_ECC_SOFT;
-
-       /* Scan to find existence of the device (it could not be mounted) */
-       if (nand_scan(ppchameleon_mtd, 1)) {
-               iounmap((void *)ppchameleon_fio_base);
-               ppchameleon_fio_base = NULL;
-               kfree(ppchameleon_mtd);
-               goto nand_evb_init;
-       }
-#ifndef USE_READY_BUSY_PIN
-       /* Adjust delay if necessary */
-       if (ppchameleon_mtd->size == NAND_SMALL_SIZE)
-               this->chip_delay = NAND_SMALL_DELAY_US;
-#endif
-
-       ppchameleon_mtd->name = "ppchameleon-nand";
-
-       /* Register the partitions */
-       mtd_device_parse_register(ppchameleon_mtd, NULL, NULL,
-                                 ppchameleon_mtd->size == NAND_SMALL_SIZE ?
-                                       partition_info_me : partition_info_hi,
-                                 NUM_PARTITIONS);
-
- nand_evb_init:
-       /****************************
-       * EVB NAND (always present) *
-       ****************************/
-       /* Allocate memory for MTD device structure and private data */
-       ppchameleonevb_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
-       if (!ppchameleonevb_mtd) {
-               printk("Unable to allocate PPChameleonEVB NAND MTD device structure.\n");
-               if (ppchameleon_fio_base)
-                       iounmap(ppchameleon_fio_base);
-               return -ENOMEM;
-       }
-
-       /* map physical address */
-       ppchameleonevb_fio_base = ioremap(ppchameleonevb_fio_pbase, SZ_4M);
-       if (!ppchameleonevb_fio_base) {
-               printk("ioremap PPChameleonEVB NAND flash failed\n");
-               kfree(ppchameleonevb_mtd);
-               if (ppchameleon_fio_base)
-                       iounmap(ppchameleon_fio_base);
-               return -EIO;
-       }
-
-       /* Get pointer to private data */
-       this = (struct nand_chip *)(&ppchameleonevb_mtd[1]);
-
-       /* Initialize structures */
-       memset(ppchameleonevb_mtd, 0, sizeof(struct mtd_info));
-       memset(this, 0, sizeof(struct nand_chip));
-
-       /* Link the private data with the MTD structure */
-       ppchameleonevb_mtd->priv = this;
-
-       /* Initialize GPIOs */
-       /* Pin mapping for NAND chip */
-       /*
-          CE   GPIO_14
-          CLE  GPIO_15
-          ALE  GPIO_16
-          R/B  GPIO_31
-        */
-       /* output select */
-       out_be32((volatile unsigned *)GPIO0_OSRH, in_be32((volatile unsigned *)GPIO0_OSRH) & 0xFFFFFFF0);
-       out_be32((volatile unsigned *)GPIO0_OSRL, in_be32((volatile unsigned *)GPIO0_OSRL) & 0x3FFFFFFF);
-       /* three-state select */
-       out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xFFFFFFF0);
-       out_be32((volatile unsigned *)GPIO0_TSRL, in_be32((volatile unsigned *)GPIO0_TSRL) & 0x3FFFFFFF);
-       /* enable output driver */
-       out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN |
-                NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN);
-#ifdef USE_READY_BUSY_PIN
-       /* three-state select */
-       out_be32((volatile unsigned *)GPIO0_TSRL, in_be32((volatile unsigned *)GPIO0_TSRL) & 0xFFFFFFFC);
-       /* high-impedecence */
-       out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) & (~NAND_EVB_RB_GPIO_PIN));
-       /* input select */
-       out_be32((volatile unsigned *)GPIO0_ISR1L,
-                (in_be32((volatile unsigned *)GPIO0_ISR1L) & 0xFFFFFFFC) | 0x00000001);
-#endif
-
-       /* insert callbacks */
-       this->IO_ADDR_R = ppchameleonevb_fio_base;
-       this->IO_ADDR_W = ppchameleonevb_fio_base;
-       this->cmd_ctrl = ppchameleonevb_hwcontrol;
-#ifdef USE_READY_BUSY_PIN
-       this->dev_ready = ppchameleonevb_device_ready;
-#endif
-       this->chip_delay = NAND_SMALL_DELAY_US;
-
-       /* ECC mode */
-       this->ecc.mode = NAND_ECC_SOFT;
-
-       /* Scan to find existence of the device */
-       if (nand_scan(ppchameleonevb_mtd, 1)) {
-               iounmap((void *)ppchameleonevb_fio_base);
-               kfree(ppchameleonevb_mtd);
-               if (ppchameleon_fio_base)
-                       iounmap(ppchameleon_fio_base);
-               return -ENXIO;
-       }
-
-       ppchameleonevb_mtd->name = NAND_EVB_MTD_NAME;
-
-       /* Register the partitions */
-       mtd_device_parse_register(ppchameleonevb_mtd, NULL, NULL,
-                                 ppchameleon_mtd->size == NAND_SMALL_SIZE ?
-                                 partition_info_me : partition_info_hi,
-                                 NUM_PARTITIONS);
-
-       /* Return happy */
-       return 0;
-}
-
-module_init(ppchameleonevb_init);
-
-/*
- * Clean up routine
- */
-static void __exit ppchameleonevb_cleanup(void)
-{
-       struct nand_chip *this;
-
-       /* Release resources, unregister device(s) */
-       nand_release(ppchameleon_mtd);
-       nand_release(ppchameleonevb_mtd);
-
-       /* Release iomaps */
-       this = (struct nand_chip *) &ppchameleon_mtd[1];
-       iounmap((void *) this->IO_ADDR_R);
-       this = (struct nand_chip *) &ppchameleonevb_mtd[1];
-       iounmap((void *) this->IO_ADDR_R);
-
-       /* Free the MTD device structure */
-       kfree (ppchameleon_mtd);
-       kfree (ppchameleonevb_mtd);
-}
-module_exit(ppchameleonevb_cleanup);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("DAVE Srl <support-ppchameleon@dave-tech.it>");
-MODULE_DESCRIPTION("MTD map driver for DAVE Srl PPChameleonEVB board");
index 37ee75c7bacb9d3200925a56a8caa9490c913dda..dec80ca6a5ce58dbd187690ea42fc706c9dc9325 100644 (file)
@@ -989,7 +989,7 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
        }
 
        pxa3xx_flash_ids[0].name = f->name;
-       pxa3xx_flash_ids[0].id = (f->chip_id >> 8) & 0xffff;
+       pxa3xx_flash_ids[0].dev_id = (f->chip_id >> 8) & 0xffff;
        pxa3xx_flash_ids[0].pagesize = f->page_size;
        chipsize = (uint64_t)f->num_blocks * f->page_per_block * f->page_size;
        pxa3xx_flash_ids[0].chipsize = chipsize >> 20;
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c
deleted file mode 100644 (file)
index e55b5cf..0000000
+++ /dev/null
@@ -1,624 +0,0 @@
-/*
- *  drivers/mtd/nand/rtc_from4.c
- *
- *  Copyright (C) 2004  Red Hat, Inc.
- *
- *  Derived from drivers/mtd/nand/spia.c
- *       Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Overview:
- *   This is a device driver for the AG-AND flash device found on the
- *   Renesas Technology Corp. Flash ROM 4-slot interface board (FROM_BOARD4),
- *   which utilizes the Renesas HN29V1G91T-30 part.
- *   This chip is a 1 GBibit (128MiB x 8 bits) AG-AND flash device.
- */
-
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/rslib.h>
-#include <linux/bitrev.h>
-#include <linux/module.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-
-/*
- * MTD structure for Renesas board
- */
-static struct mtd_info *rtc_from4_mtd = NULL;
-
-#define RTC_FROM4_MAX_CHIPS    2
-
-/* HS77x9 processor register defines */
-#define SH77X9_BCR1    ((volatile unsigned short *)(0xFFFFFF60))
-#define SH77X9_BCR2    ((volatile unsigned short *)(0xFFFFFF62))
-#define SH77X9_WCR1    ((volatile unsigned short *)(0xFFFFFF64))
-#define SH77X9_WCR2    ((volatile unsigned short *)(0xFFFFFF66))
-#define SH77X9_MCR     ((volatile unsigned short *)(0xFFFFFF68))
-#define SH77X9_PCR     ((volatile unsigned short *)(0xFFFFFF6C))
-#define SH77X9_FRQCR   ((volatile unsigned short *)(0xFFFFFF80))
-
-/*
- * Values specific to the Renesas Technology Corp. FROM_BOARD4 (used with HS77x9 processor)
- */
-/* Address where flash is mapped */
-#define RTC_FROM4_FIO_BASE     0x14000000
-
-/* CLE and ALE are tied to address lines 5 & 4, respectively */
-#define RTC_FROM4_CLE          (1 << 5)
-#define RTC_FROM4_ALE          (1 << 4)
-
-/* address lines A24-A22 used for chip selection */
-#define RTC_FROM4_NAND_ADDR_SLOT3      (0x00800000)
-#define RTC_FROM4_NAND_ADDR_SLOT4      (0x00C00000)
-#define RTC_FROM4_NAND_ADDR_FPGA       (0x01000000)
-/* mask address lines A24-A22 used for chip selection */
-#define RTC_FROM4_NAND_ADDR_MASK       (RTC_FROM4_NAND_ADDR_SLOT3 | RTC_FROM4_NAND_ADDR_SLOT4 | RTC_FROM4_NAND_ADDR_FPGA)
-
-/* FPGA status register for checking device ready (bit zero) */
-#define RTC_FROM4_FPGA_SR              (RTC_FROM4_NAND_ADDR_FPGA | 0x00000002)
-#define RTC_FROM4_DEVICE_READY         0x0001
-
-/* FPGA Reed-Solomon ECC Control register */
-
-#define RTC_FROM4_RS_ECC_CTL           (RTC_FROM4_NAND_ADDR_FPGA | 0x00000050)
-#define RTC_FROM4_RS_ECC_CTL_CLR       (1 << 7)
-#define RTC_FROM4_RS_ECC_CTL_GEN       (1 << 6)
-#define RTC_FROM4_RS_ECC_CTL_FD_E      (1 << 5)
-
-/* FPGA Reed-Solomon ECC code base */
-#define RTC_FROM4_RS_ECC               (RTC_FROM4_NAND_ADDR_FPGA | 0x00000060)
-#define RTC_FROM4_RS_ECCN              (RTC_FROM4_NAND_ADDR_FPGA | 0x00000080)
-
-/* FPGA Reed-Solomon ECC check register */
-#define RTC_FROM4_RS_ECC_CHK           (RTC_FROM4_NAND_ADDR_FPGA | 0x00000070)
-#define RTC_FROM4_RS_ECC_CHK_ERROR     (1 << 7)
-
-#define ERR_STAT_ECC_AVAILABLE         0x20
-
-/* Undefine for software ECC */
-#define RTC_FROM4_HWECC        1
-
-/* Define as 1 for no virtual erase blocks (in JFFS2) */
-#define RTC_FROM4_NO_VIRTBLOCKS        0
-
-/*
- * Module stuff
- */
-static void __iomem *rtc_from4_fio_base = (void *)P2SEGADDR(RTC_FROM4_FIO_BASE);
-
-static const struct mtd_partition partition_info[] = {
-       {
-        .name = "Renesas flash partition 1",
-        .offset = 0,
-        .size = MTDPART_SIZ_FULL},
-};
-
-#define NUM_PARTITIONS 1
-
-/*
- *     hardware specific flash bbt decriptors
- *     Note: this is to allow debugging by disabling
- *             NAND_BBT_CREATE and/or NAND_BBT_WRITE
- *
- */
-static uint8_t bbt_pattern[] = { 'B', 'b', 't', '0' };
-static uint8_t mirror_pattern[] = { '1', 't', 'b', 'B' };
-
-static struct nand_bbt_descr rtc_from4_bbt_main_descr = {
-       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
-               | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
-       .offs = 40,
-       .len = 4,
-       .veroffs = 44,
-       .maxblocks = 4,
-       .pattern = bbt_pattern
-};
-
-static struct nand_bbt_descr rtc_from4_bbt_mirror_descr = {
-       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
-               | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
-       .offs = 40,
-       .len = 4,
-       .veroffs = 44,
-       .maxblocks = 4,
-       .pattern = mirror_pattern
-};
-
-#ifdef RTC_FROM4_HWECC
-
-/* the Reed Solomon control structure */
-static struct rs_control *rs_decoder;
-
-/*
- *      hardware specific Out Of Band information
- */
-static struct nand_ecclayout rtc_from4_nand_oobinfo = {
-       .eccbytes = 32,
-       .eccpos = {
-                  0, 1, 2, 3, 4, 5, 6, 7,
-                  8, 9, 10, 11, 12, 13, 14, 15,
-                  16, 17, 18, 19, 20, 21, 22, 23,
-                  24, 25, 26, 27, 28, 29, 30, 31},
-       .oobfree = {{32, 32}}
-};
-
-#endif
-
-/*
- * rtc_from4_hwcontrol - hardware specific access to control-lines
- * @mtd:       MTD device structure
- * @cmd:       hardware control command
- *
- * Address lines (A5 and A4) are used to control Command and Address Latch
- * Enable on this board, so set the read/write address appropriately.
- *
- * Chip Enable is also controlled by the Chip Select (CS5) and
- * Address lines (A24-A22), so no action is required here.
- *
- */
-static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd,
-                               unsigned int ctrl)
-{
-       struct nand_chip *chip = (mtd->priv);
-
-       if (cmd == NAND_CMD_NONE)
-               return;
-
-       if (ctrl & NAND_CLE)
-               writeb(cmd, chip->IO_ADDR_W | RTC_FROM4_CLE);
-       else
-               writeb(cmd, chip->IO_ADDR_W | RTC_FROM4_ALE);
-}
-
-/*
- * rtc_from4_nand_select_chip - hardware specific chip select
- * @mtd:       MTD device structure
- * @chip:      Chip to select (0 == slot 3, 1 == slot 4)
- *
- * The chip select is based on address lines A24-A22.
- * This driver uses flash slots 3 and 4 (A23-A22).
- *
- */
-static void rtc_from4_nand_select_chip(struct mtd_info *mtd, int chip)
-{
-       struct nand_chip *this = mtd->priv;
-
-       this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R & ~RTC_FROM4_NAND_ADDR_MASK);
-       this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_NAND_ADDR_MASK);
-
-       switch (chip) {
-
-       case 0:         /* select slot 3 chip */
-               this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R | RTC_FROM4_NAND_ADDR_SLOT3);
-               this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_NAND_ADDR_SLOT3);
-               break;
-       case 1:         /* select slot 4 chip */
-               this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R | RTC_FROM4_NAND_ADDR_SLOT4);
-               this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_NAND_ADDR_SLOT4);
-               break;
-
-       }
-}
-
-/*
- * rtc_from4_nand_device_ready - hardware specific ready/busy check
- * @mtd:       MTD device structure
- *
- * This board provides the Ready/Busy state in the status register
- * of the FPGA.  Bit zero indicates the RDY(1)/BSY(0) signal.
- *
- */
-static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
-{
-       unsigned short status;
-
-       status = *((volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_FPGA_SR));
-
-       return (status & RTC_FROM4_DEVICE_READY);
-
-}
-
-/*
- * deplete - code to perform device recovery in case there was a power loss
- * @mtd:       MTD device structure
- * @chip:      Chip to select (0 == slot 3, 1 == slot 4)
- *
- * If there was a sudden loss of power during an erase operation, a
- * "device recovery" operation must be performed when power is restored
- * to ensure correct operation.  This routine performs the required steps
- * for the requested chip.
- *
- * See page 86 of the data sheet for details.
- *
- */
-static void deplete(struct mtd_info *mtd, int chip)
-{
-       struct nand_chip *this = mtd->priv;
-
-       /* wait until device is ready */
-       while (!this->dev_ready(mtd)) ;
-
-       this->select_chip(mtd, chip);
-
-       /* Send the commands for device recovery, phase 1 */
-       this->cmdfunc(mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000);
-       this->cmdfunc(mtd, NAND_CMD_DEPLETE2, -1, -1);
-
-       /* Send the commands for device recovery, phase 2 */
-       this->cmdfunc(mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0004);
-       this->cmdfunc(mtd, NAND_CMD_DEPLETE2, -1, -1);
-
-}
-
-#ifdef RTC_FROM4_HWECC
-/*
- * rtc_from4_enable_hwecc - hardware specific hardware ECC enable function
- * @mtd:       MTD device structure
- * @mode:      I/O mode; read or write
- *
- * enable hardware ECC for data read or write
- *
- */
-static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
-{
-       volatile unsigned short *rs_ecc_ctl = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CTL);
-       unsigned short status;
-
-       switch (mode) {
-       case NAND_ECC_READ:
-               status = RTC_FROM4_RS_ECC_CTL_CLR | RTC_FROM4_RS_ECC_CTL_FD_E;
-
-               *rs_ecc_ctl = status;
-               break;
-
-       case NAND_ECC_READSYN:
-               status = 0x00;
-
-               *rs_ecc_ctl = status;
-               break;
-
-       case NAND_ECC_WRITE:
-               status = RTC_FROM4_RS_ECC_CTL_CLR | RTC_FROM4_RS_ECC_CTL_GEN | RTC_FROM4_RS_ECC_CTL_FD_E;
-
-               *rs_ecc_ctl = status;
-               break;
-
-       default:
-               BUG();
-               break;
-       }
-
-}
-
-/*
- * rtc_from4_calculate_ecc - hardware specific code to read ECC code
- * @mtd:       MTD device structure
- * @dat:       buffer containing the data to generate ECC codes
- * @ecc_code   ECC codes calculated
- *
- * The ECC code is calculated by the FPGA.  All we have to do is read the values
- * from the FPGA registers.
- *
- * Note: We read from the inverted registers, since data is inverted before
- * the code is calculated. So all 0xff data (blank page) results in all 0xff rs code
- *
- */
-static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
-{
-       volatile unsigned short *rs_eccn = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECCN);
-       unsigned short value;
-       int i;
-
-       for (i = 0; i < 8; i++) {
-               value = *rs_eccn;
-               ecc_code[i] = (unsigned char)value;
-               rs_eccn++;
-       }
-       ecc_code[7] |= 0x0f;    /* set the last four bits (not used) */
-}
-
-/*
- * rtc_from4_correct_data - hardware specific code to correct data using ECC code
- * @mtd:       MTD device structure
- * @buf:       buffer containing the data to generate ECC codes
- * @ecc1       ECC codes read
- * @ecc2       ECC codes calculated
- *
- * The FPGA tells us fast, if there's an error or not. If no, we go back happy
- * else we read the ecc results from the fpga and call the rs library to decode
- * and hopefully correct the error.
- *
- */
-static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2)
-{
-       int i, j, res;
-       unsigned short status;
-       uint16_t par[6], syn[6];
-       uint8_t ecc[8];
-       volatile unsigned short *rs_ecc;
-
-       status = *((volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CHK));
-
-       if (!(status & RTC_FROM4_RS_ECC_CHK_ERROR)) {
-               return 0;
-       }
-
-       /* Read the syndrome pattern from the FPGA and correct the bitorder */
-       rs_ecc = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC);
-       for (i = 0; i < 8; i++) {
-               ecc[i] = bitrev8(*rs_ecc);
-               rs_ecc++;
-       }
-
-       /* convert into 6 10bit syndrome fields */
-       par[5] = rs_decoder->index_of[(((uint16_t) ecc[0] >> 0) & 0x0ff) | (((uint16_t) ecc[1] << 8) & 0x300)];
-       par[4] = rs_decoder->index_of[(((uint16_t) ecc[1] >> 2) & 0x03f) | (((uint16_t) ecc[2] << 6) & 0x3c0)];
-       par[3] = rs_decoder->index_of[(((uint16_t) ecc[2] >> 4) & 0x00f) | (((uint16_t) ecc[3] << 4) & 0x3f0)];
-       par[2] = rs_decoder->index_of[(((uint16_t) ecc[3] >> 6) & 0x003) | (((uint16_t) ecc[4] << 2) & 0x3fc)];
-       par[1] = rs_decoder->index_of[(((uint16_t) ecc[5] >> 0) & 0x0ff) | (((uint16_t) ecc[6] << 8) & 0x300)];
-       par[0] = (((uint16_t) ecc[6] >> 2) & 0x03f) | (((uint16_t) ecc[7] << 6) & 0x3c0);
-
-       /* Convert to computable syndrome */
-       for (i = 0; i < 6; i++) {
-               syn[i] = par[0];
-               for (j = 1; j < 6; j++)
-                       if (par[j] != rs_decoder->nn)
-                               syn[i] ^= rs_decoder->alpha_to[rs_modnn(rs_decoder, par[j] + i * j)];
-
-               /* Convert to index form */
-               syn[i] = rs_decoder->index_of[syn[i]];
-       }
-
-       /* Let the library code do its magic. */
-       res = decode_rs8(rs_decoder, (uint8_t *) buf, par, 512, syn, 0, NULL, 0xff, NULL);
-       if (res > 0) {
-               pr_debug("rtc_from4_correct_data: " "ECC corrected %d errors on read\n", res);
-       }
-       return res;
-}
-
-/**
- * rtc_from4_errstat - perform additional error status checks
- * @mtd:       MTD device structure
- * @this:      NAND chip structure
- * @state:     state or the operation
- * @status:    status code returned from read status
- * @page:      startpage inside the chip, must be called with (page & this->pagemask)
- *
- * Perform additional error status checks on erase and write failures
- * to determine if errors are correctable.  For this device, correctable
- * 1-bit errors on erase and write are considered acceptable.
- *
- * note: see pages 34..37 of data sheet for details.
- *
- */
-static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this,
-                            int state, int status, int page)
-{
-       int er_stat = 0;
-       int rtn, retlen;
-       size_t len;
-       uint8_t *buf;
-       int i;
-
-       this->cmdfunc(mtd, NAND_CMD_STATUS_CLEAR, -1, -1);
-
-       if (state == FL_ERASING) {
-
-               for (i = 0; i < 4; i++) {
-                       if (!(status & 1 << (i + 1)))
-                               continue;
-                       this->cmdfunc(mtd, (NAND_CMD_STATUS_ERROR + i + 1),
-                                     -1, -1);
-                       rtn = this->read_byte(mtd);
-                       this->cmdfunc(mtd, NAND_CMD_STATUS_RESET, -1, -1);
-
-                       /* err_ecc_not_avail */
-                       if (!(rtn & ERR_STAT_ECC_AVAILABLE))
-                               er_stat |= 1 << (i + 1);
-               }
-
-       } else if (state == FL_WRITING) {
-
-               unsigned long corrected = mtd->ecc_stats.corrected;
-
-               /* single bank write logic */
-               this->cmdfunc(mtd, NAND_CMD_STATUS_ERROR, -1, -1);
-               rtn = this->read_byte(mtd);
-               this->cmdfunc(mtd, NAND_CMD_STATUS_RESET, -1, -1);
-
-               if (!(rtn & ERR_STAT_ECC_AVAILABLE)) {
-                       /* err_ecc_not_avail */
-                       er_stat |= 1 << 1;
-                       goto out;
-               }
-
-               len = mtd->writesize;
-               buf = kmalloc(len, GFP_KERNEL);
-               if (!buf) {
-                       er_stat = 1;
-                       goto out;
-               }
-
-               /* recovery read */
-               rtn = nand_do_read(mtd, page, len, &retlen, buf);
-
-               /* if read failed or > 1-bit error corrected */
-               if (rtn || (mtd->ecc_stats.corrected - corrected) > 1)
-                       er_stat |= 1 << 1;
-               kfree(buf);
-       }
-out:
-       rtn = status;
-       if (er_stat == 0) {     /* if ECC is available   */
-               rtn = (status & ~NAND_STATUS_FAIL);     /*   clear the error bit */
-       }
-
-       return rtn;
-}
-#endif
-
-/*
- * Main initialization routine
- */
-static int __init rtc_from4_init(void)
-{
-       struct nand_chip *this;
-       unsigned short bcr1, bcr2, wcr2;
-       int i;
-       int ret;
-
-       /* Allocate memory for MTD device structure and private data */
-       rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
-       if (!rtc_from4_mtd) {
-               printk("Unable to allocate Renesas NAND MTD device structure.\n");
-               return -ENOMEM;
-       }
-
-       /* Get pointer to private data */
-       this = (struct nand_chip *)(&rtc_from4_mtd[1]);
-
-       /* Initialize structures */
-       memset(rtc_from4_mtd, 0, sizeof(struct mtd_info));
-       memset(this, 0, sizeof(struct nand_chip));
-
-       /* Link the private data with the MTD structure */
-       rtc_from4_mtd->priv = this;
-       rtc_from4_mtd->owner = THIS_MODULE;
-
-       /* set area 5 as PCMCIA mode to clear the spec of tDH(Data hold time;9ns min) */
-       bcr1 = *SH77X9_BCR1 & ~0x0002;
-       bcr1 |= 0x0002;
-       *SH77X9_BCR1 = bcr1;
-
-       /* set */
-       bcr2 = *SH77X9_BCR2 & ~0x0c00;
-       bcr2 |= 0x0800;
-       *SH77X9_BCR2 = bcr2;
-
-       /* set area 5 wait states */
-       wcr2 = *SH77X9_WCR2 & ~0x1c00;
-       wcr2 |= 0x1c00;
-       *SH77X9_WCR2 = wcr2;
-
-       /* Set address of NAND IO lines */
-       this->IO_ADDR_R = rtc_from4_fio_base;
-       this->IO_ADDR_W = rtc_from4_fio_base;
-       /* Set address of hardware control function */
-       this->cmd_ctrl = rtc_from4_hwcontrol;
-       /* Set address of chip select function */
-       this->select_chip = rtc_from4_nand_select_chip;
-       /* command delay time (in us) */
-       this->chip_delay = 100;
-       /* return the status of the Ready/Busy line */
-       this->dev_ready = rtc_from4_nand_device_ready;
-
-#ifdef RTC_FROM4_HWECC
-       printk(KERN_INFO "rtc_from4_init: using hardware ECC detection.\n");
-
-       this->ecc.mode = NAND_ECC_HW_SYNDROME;
-       this->ecc.size = 512;
-       this->ecc.bytes = 8;
-       this->ecc.strength = 3;
-       /* return the status of extra status and ECC checks */
-       this->errstat = rtc_from4_errstat;
-       /* set the nand_oobinfo to support FPGA H/W error detection */
-       this->ecc.layout = &rtc_from4_nand_oobinfo;
-       this->ecc.hwctl = rtc_from4_enable_hwecc;
-       this->ecc.calculate = rtc_from4_calculate_ecc;
-       this->ecc.correct = rtc_from4_correct_data;
-
-       /* We could create the decoder on demand, if memory is a concern.
-        * This way we have it handy, if an error happens
-        *
-        * Symbolsize is 10 (bits)
-        * Primitve polynomial is x^10+x^3+1
-        * first consecutive root is 0
-        * primitve element to generate roots = 1
-        * generator polinomial degree = 6
-        */
-       rs_decoder = init_rs(10, 0x409, 0, 1, 6);
-       if (!rs_decoder) {
-               printk(KERN_ERR "Could not create a RS decoder\n");
-               ret = -ENOMEM;
-               goto err_1;
-       }
-#else
-       printk(KERN_INFO "rtc_from4_init: using software ECC detection.\n");
-
-       this->ecc.mode = NAND_ECC_SOFT;
-#endif
-
-       /* set the bad block tables to support debugging */
-       this->bbt_td = &rtc_from4_bbt_main_descr;
-       this->bbt_md = &rtc_from4_bbt_mirror_descr;
-
-       /* Scan to find existence of the device */
-       if (nand_scan(rtc_from4_mtd, RTC_FROM4_MAX_CHIPS)) {
-               ret = -ENXIO;
-               goto err_2;
-       }
-
-       /* Perform 'device recovery' for each chip in case there was a power loss. */
-       for (i = 0; i < this->numchips; i++) {
-               deplete(rtc_from4_mtd, i);
-       }
-
-#if RTC_FROM4_NO_VIRTBLOCKS
-       /* use a smaller erase block to minimize wasted space when a block is bad */
-       /* note: this uses eight times as much RAM as using the default and makes */
-       /*       mounts take four times as long. */
-       rtc_from4_mtd->flags |= MTD_NO_VIRTBLOCKS;
-#endif
-
-       /* Register the partitions */
-       ret = mtd_device_register(rtc_from4_mtd, partition_info,
-                                 NUM_PARTITIONS);
-       if (ret)
-               goto err_3;
-
-       /* Return happy */
-       return 0;
-err_3:
-       nand_release(rtc_from4_mtd);
-err_2:
-       free_rs(rs_decoder);
-err_1:
-       kfree(rtc_from4_mtd);
-       return ret;
-}
-
-module_init(rtc_from4_init);
-
-/*
- * Clean up routine
- */
-static void __exit rtc_from4_cleanup(void)
-{
-       /* Release resource, unregister partitions */
-       nand_release(rtc_from4_mtd);
-
-       /* Free the MTD device structure */
-       kfree(rtc_from4_mtd);
-
-#ifdef RTC_FROM4_HWECC
-       /* Free the reed solomon resources */
-       if (rs_decoder) {
-               free_rs(rs_decoder);
-       }
-#endif
-}
-
-module_exit(rtc_from4_cleanup);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("d.marlin <dmarlin@redhat.com");
-MODULE_DESCRIPTION("Board-specific glue layer for AG-AND flash on Renesas FROM_BOARD4");
index 57b3971c9c0a609a89284bef3e32b977466f6662..e57e18e8c2893ab8077693e13385bb06ddaad9af 100644 (file)
@@ -1081,7 +1081,6 @@ static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev)
        return pdata;
 }
 #else /* CONFIG_OF */
-#define of_flctl_match NULL
 static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev)
 {
        return NULL;
@@ -1219,22 +1218,11 @@ static struct platform_driver flctl_driver = {
        .driver = {
                .name   = "sh_flctl",
                .owner  = THIS_MODULE,
-               .of_match_table = of_flctl_match,
+               .of_match_table = of_match_ptr(of_flctl_match),
        },
 };
 
-static int __init flctl_nand_init(void)
-{
-       return platform_driver_probe(&flctl_driver, flctl_probe);
-}
-
-static void __exit flctl_nand_cleanup(void)
-{
-       platform_driver_unregister(&flctl_driver);
-}
-
-module_init(flctl_nand_init);
-module_exit(flctl_nand_cleanup);
+module_platform_driver_probe(flctl_driver, flctl_probe);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Yoshihiro Shimoda");
index 082bcdcd6bcfa3f460e26b68edc183b56aba5947..e8181edebddd10923904c4db4be17adf79d29316 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/mtd/nand.h>
 #include <linux/module.h>
+#include <linux/sizes.h>
 #include "sm_common.h"
 
 static struct nand_ecclayout nand_oob_sm = {
@@ -67,44 +68,37 @@ static int sm_block_markbad(struct mtd_info *mtd, loff_t ofs)
        return error;
 }
 
-
 static struct nand_flash_dev nand_smartmedia_flash_ids[] = {
-       {"SmartMedia 1MiB 5V",          0x6e, 256, 1, 0x1000, 0},
-       {"SmartMedia 1MiB 3,3V",        0xe8, 256, 1, 0x1000, 0},
-       {"SmartMedia 1MiB 3,3V",        0xec, 256, 1, 0x1000, 0},
-       {"SmartMedia 2MiB 3,3V",        0xea, 256, 2, 0x1000, 0},
-       {"SmartMedia 2MiB 5V",          0x64, 256, 2, 0x1000, 0},
-       {"SmartMedia 2MiB 3,3V ROM",    0x5d, 512, 2, 0x2000, NAND_ROM},
-       {"SmartMedia 4MiB 3,3V",        0xe3, 512, 4, 0x2000, 0},
-       {"SmartMedia 4MiB 3,3/5V",      0xe5, 512, 4, 0x2000, 0},
-       {"SmartMedia 4MiB 5V",          0x6b, 512, 4, 0x2000, 0},
-       {"SmartMedia 4MiB 3,3V ROM",    0xd5, 512, 4, 0x2000, NAND_ROM},
-       {"SmartMedia 8MiB 3,3V",        0xe6, 512, 8, 0x2000, 0},
-       {"SmartMedia 8MiB 3,3V ROM",    0xd6, 512, 8, 0x2000, NAND_ROM},
-       {"SmartMedia 16MiB 3,3V",       0x73, 512, 16, 0x4000, 0},
-       {"SmartMedia 16MiB 3,3V ROM",   0x57, 512, 16, 0x4000, NAND_ROM},
-       {"SmartMedia 32MiB 3,3V",       0x75, 512, 32, 0x4000, 0},
-       {"SmartMedia 32MiB 3,3V ROM",   0x58, 512, 32, 0x4000, NAND_ROM},
-       {"SmartMedia 64MiB 3,3V",       0x76, 512, 64, 0x4000, 0},
-       {"SmartMedia 64MiB 3,3V ROM",   0xd9, 512, 64, 0x4000, NAND_ROM},
-       {"SmartMedia 128MiB 3,3V",      0x79, 512, 128, 0x4000, 0},
-       {"SmartMedia 128MiB 3,3V ROM",  0xda, 512, 128, 0x4000, NAND_ROM},
-       {"SmartMedia 256MiB 3,3V",      0x71, 512, 256, 0x4000 },
-       {"SmartMedia 256MiB 3,3V ROM",  0x5b, 512, 256, 0x4000, NAND_ROM},
-       {NULL,}
+       LEGACY_ID_NAND("SmartMedia 2MiB 3,3V ROM",   0x5d, 2,   SZ_8K, NAND_ROM),
+       LEGACY_ID_NAND("SmartMedia 4MiB 3,3V",       0xe3, 4,   SZ_8K, 0),
+       LEGACY_ID_NAND("SmartMedia 4MiB 3,3/5V",     0xe5, 4,   SZ_8K, 0),
+       LEGACY_ID_NAND("SmartMedia 4MiB 5V",         0x6b, 4,   SZ_8K, 0),
+       LEGACY_ID_NAND("SmartMedia 4MiB 3,3V ROM",   0xd5, 4,   SZ_8K, NAND_ROM),
+       LEGACY_ID_NAND("SmartMedia 8MiB 3,3V",       0xe6, 8,   SZ_8K, 0),
+       LEGACY_ID_NAND("SmartMedia 8MiB 3,3V ROM",   0xd6, 8,   SZ_8K, NAND_ROM),
+       LEGACY_ID_NAND("SmartMedia 16MiB 3,3V",      0x73, 16,  SZ_16K, 0),
+       LEGACY_ID_NAND("SmartMedia 16MiB 3,3V ROM",  0x57, 16,  SZ_16K, NAND_ROM),
+       LEGACY_ID_NAND("SmartMedia 32MiB 3,3V",      0x75, 32,  SZ_16K, 0),
+       LEGACY_ID_NAND("SmartMedia 32MiB 3,3V ROM",  0x58, 32,  SZ_16K, NAND_ROM),
+       LEGACY_ID_NAND("SmartMedia 64MiB 3,3V",      0x76, 64,  SZ_16K, 0),
+       LEGACY_ID_NAND("SmartMedia 64MiB 3,3V ROM",  0xd9, 64,  SZ_16K, NAND_ROM),
+       LEGACY_ID_NAND("SmartMedia 128MiB 3,3V",     0x79, 128, SZ_16K, 0),
+       LEGACY_ID_NAND("SmartMedia 128MiB 3,3V ROM", 0xda, 128, SZ_16K, NAND_ROM),
+       LEGACY_ID_NAND("SmartMedia 256MiB 3, 3V",    0x71, 256, SZ_16K, 0),
+       LEGACY_ID_NAND("SmartMedia 256MiB 3,3V ROM", 0x5b, 256, SZ_16K, NAND_ROM),
+       {NULL}
 };
 
 static struct nand_flash_dev nand_xd_flash_ids[] = {
-
-       {"xD 16MiB 3,3V",    0x73, 512, 16, 0x4000, 0},
-       {"xD 32MiB 3,3V",    0x75, 512, 32, 0x4000, 0},
-       {"xD 64MiB 3,3V",    0x76, 512, 64, 0x4000, 0},
-       {"xD 128MiB 3,3V",   0x79, 512, 128, 0x4000, 0},
-       {"xD 256MiB 3,3V",   0x71, 512, 256, 0x4000, NAND_BROKEN_XD},
-       {"xD 512MiB 3,3V",   0xdc, 512, 512, 0x4000, NAND_BROKEN_XD},
-       {"xD 1GiB 3,3V",     0xd3, 512, 1024, 0x4000, NAND_BROKEN_XD},
-       {"xD 2GiB 3,3V",     0xd5, 512, 2048, 0x4000, NAND_BROKEN_XD},
-       {NULL,}
+       LEGACY_ID_NAND("xD 16MiB 3,3V",  0x73, 16,   SZ_16K, 0),
+       LEGACY_ID_NAND("xD 32MiB 3,3V",  0x75, 32,   SZ_16K, 0),
+       LEGACY_ID_NAND("xD 64MiB 3,3V",  0x76, 64,   SZ_16K, 0),
+       LEGACY_ID_NAND("xD 128MiB 3,3V", 0x79, 128,  SZ_16K, 0),
+       LEGACY_ID_NAND("xD 256MiB 3,3V", 0x71, 256,  SZ_16K, NAND_BROKEN_XD),
+       LEGACY_ID_NAND("xD 512MiB 3,3V", 0xdc, 512,  SZ_16K, NAND_BROKEN_XD),
+       LEGACY_ID_NAND("xD 1GiB 3,3V",   0xd3, 1024, SZ_16K, NAND_BROKEN_XD),
+       LEGACY_ID_NAND("xD 2GiB 3,3V",   0xd5, 2048, SZ_16K, NAND_BROKEN_XD),
+       {NULL}
 };
 
 int sm_register_device(struct mtd_info *mtd, int smartmedia)
index e1e8748aa47b263c2f4349b49e5e0f715236d0f5..7ed654c68b0867af79c82da6f65cc210fb827498 100644 (file)
@@ -427,18 +427,7 @@ static struct platform_driver txx9ndfmc_driver = {
        },
 };
 
-static int __init txx9ndfmc_init(void)
-{
-       return platform_driver_probe(&txx9ndfmc_driver, txx9ndfmc_probe);
-}
-
-static void __exit txx9ndfmc_exit(void)
-{
-       platform_driver_unregister(&txx9ndfmc_driver);
-}
-
-module_init(txx9ndfmc_init);
-module_exit(txx9ndfmc_exit);
+module_platform_driver_probe(txx9ndfmc_driver, txx9ndfmc_probe);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("TXx9 SoC NAND flash controller driver");
index 30bd907a260afe19420fd84b0992018faee82e3a..553d6d6d560322c4bcafa44a184e6c09e864b621 100644 (file)
@@ -55,6 +55,7 @@ static int parse_ofpart_partitions(struct mtd_info *master,
        while ((pp = of_get_next_child(node, pp))) {
                const __be32 *reg;
                int len;
+               int a_cells, s_cells;
 
                reg = of_get_property(pp, "reg", &len);
                if (!reg) {
@@ -62,8 +63,10 @@ static int parse_ofpart_partitions(struct mtd_info *master,
                        continue;
                }
 
-               (*pparts)[i].offset = be32_to_cpu(reg[0]);
-               (*pparts)[i].size = be32_to_cpu(reg[1]);
+               a_cells = of_n_addr_cells(pp);
+               s_cells = of_n_size_cells(pp);
+               (*pparts)[i].offset = of_read_number(reg, a_cells);
+               (*pparts)[i].size = of_read_number(reg + a_cells, s_cells);
 
                partname = of_get_property(pp, "label", &len);
                if (!partname)
index 91467bb036341fe52f84a5db00c7664365d0abb9..ab2607273e809e32f62fde7654e794a5a5b252bb 100644 (file)
@@ -40,7 +40,6 @@ config MTD_ONENAND_SAMSUNG
 
 config MTD_ONENAND_OTP
        bool "OneNAND OTP Support"
-       select HAVE_MTD_OTP
        help
          One Block of the NAND Flash Array memory is reserved as
          a One-Time Programmable Block memory area.
@@ -68,10 +67,4 @@ config MTD_ONENAND_2X_PROGRAM
 
          And more recent chips
 
-config MTD_ONENAND_SIM
-       tristate "OneNAND simulator support"
-       help
-         The simulator may simulate various OneNAND flash chips for the
-         OneNAND MTD layer.
-
 endif # MTD_ONENAND
index 2b7884c7577e7cda2e789da09ea3514969658fc5..9d6540e8b3d22ae0fe3d04422c62cdbf2f2b54d1 100644 (file)
@@ -10,7 +10,4 @@ obj-$(CONFIG_MTD_ONENAND_GENERIC)     += generic.o
 obj-$(CONFIG_MTD_ONENAND_OMAP2)                += omap2.o
 obj-$(CONFIG_MTD_ONENAND_SAMSUNG)       += samsung.o
 
-# Simulator
-obj-$(CONFIG_MTD_ONENAND_SIM)          += onenand_sim.o
-
 onenand-objs = onenand_base.o onenand_bbt.o
index eec2aedb4ab83767587cd4f38f28d8632632478a..d98b198edd53a27139c1eaa0ffad5ae5f0fac9f2 100644 (file)
@@ -832,19 +832,7 @@ static struct platform_driver omap2_onenand_driver = {
        },
 };
 
-static int __init omap2_onenand_init(void)
-{
-       printk(KERN_INFO "OneNAND driver initializing\n");
-       return platform_driver_register(&omap2_onenand_driver);
-}
-
-static void __exit omap2_onenand_exit(void)
-{
-       platform_driver_unregister(&omap2_onenand_driver);
-}
-
-module_init(omap2_onenand_init);
-module_exit(omap2_onenand_exit);
+module_platform_driver(omap2_onenand_driver);
 
 MODULE_ALIAS("platform:" DRIVER_NAME);
 MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/onenand/onenand_sim.c b/drivers/mtd/onenand/onenand_sim.c
deleted file mode 100644 (file)
index 85399e3..0000000
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- *  linux/drivers/mtd/onenand/onenand_sim.c
- *
- *  The OneNAND simulator
- *
- *  Copyright Â© 2005-2007 Samsung Electronics
- *  Kyungmin Park <kyungmin.park@samsung.com>
- *
- *  Vishak G <vishak.g at samsung.com>, Rohit Hagargundgi <h.rohit at samsung.com>
- *  Flex-OneNAND simulator support
- *  Copyright (C) Samsung Electronics, 2008
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/vmalloc.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/onenand.h>
-
-#include <linux/io.h>
-
-#ifndef CONFIG_ONENAND_SIM_MANUFACTURER
-#define CONFIG_ONENAND_SIM_MANUFACTURER         0xec
-#endif
-
-#ifndef CONFIG_ONENAND_SIM_DEVICE_ID
-#define CONFIG_ONENAND_SIM_DEVICE_ID            0x04
-#endif
-
-#define CONFIG_FLEXONENAND ((CONFIG_ONENAND_SIM_DEVICE_ID >> 9) & 1)
-
-#ifndef CONFIG_ONENAND_SIM_VERSION_ID
-#define CONFIG_ONENAND_SIM_VERSION_ID           0x1e
-#endif
-
-#ifndef CONFIG_ONENAND_SIM_TECHNOLOGY_ID
-#define CONFIG_ONENAND_SIM_TECHNOLOGY_ID CONFIG_FLEXONENAND
-#endif
-
-/* Initial boundary values for Flex-OneNAND Simulator */
-#ifndef CONFIG_FLEXONENAND_SIM_DIE0_BOUNDARY
-#define CONFIG_FLEXONENAND_SIM_DIE0_BOUNDARY   0x01
-#endif
-
-#ifndef CONFIG_FLEXONENAND_SIM_DIE1_BOUNDARY
-#define CONFIG_FLEXONENAND_SIM_DIE1_BOUNDARY   0x01
-#endif
-
-static int manuf_id    = CONFIG_ONENAND_SIM_MANUFACTURER;
-static int device_id   = CONFIG_ONENAND_SIM_DEVICE_ID;
-static int version_id  = CONFIG_ONENAND_SIM_VERSION_ID;
-static int technology_id = CONFIG_ONENAND_SIM_TECHNOLOGY_ID;
-static int boundary[] = {
-       CONFIG_FLEXONENAND_SIM_DIE0_BOUNDARY,
-       CONFIG_FLEXONENAND_SIM_DIE1_BOUNDARY,
-};
-
-struct onenand_flash {
-       void __iomem *base;
-       void __iomem *data;
-};
-
-#define ONENAND_CORE(flash)            (flash->data)
-#define ONENAND_CORE_SPARE(flash, this, offset)                                \
-       ((flash->data) + (this->chipsize) + (offset >> 5))
-
-#define ONENAND_MAIN_AREA(this, offset)                                        \
-       (this->base + ONENAND_DATARAM + offset)
-
-#define ONENAND_SPARE_AREA(this, offset)                               \
-       (this->base + ONENAND_SPARERAM + offset)
-
-#define ONENAND_GET_WP_STATUS(this)                                    \
-       (readw(this->base + ONENAND_REG_WP_STATUS))
-
-#define ONENAND_SET_WP_STATUS(v, this)                                 \
-       (writew(v, this->base + ONENAND_REG_WP_STATUS))
-
-/* It has all 0xff chars */
-#define MAX_ONENAND_PAGESIZE           (4096 + 128)
-static unsigned char *ffchars;
-
-#if CONFIG_FLEXONENAND
-#define PARTITION_NAME "Flex-OneNAND simulator partition"
-#else
-#define PARTITION_NAME "OneNAND simulator partition"
-#endif
-
-static struct mtd_partition os_partitions[] = {
-       {
-               .name           = PARTITION_NAME,
-               .offset         = 0,
-               .size           = MTDPART_SIZ_FULL,
-       },
-};
-
-/*
- * OneNAND simulator mtd
- */
-struct onenand_info {
-       struct mtd_info         mtd;
-       struct mtd_partition    *parts;
-       struct onenand_chip     onenand;
-       struct onenand_flash    flash;
-};
-
-static struct onenand_info *info;
-
-#define DPRINTK(format, args...)                                       \
-do {                                                                   \
-       printk(KERN_DEBUG "%s[%d]: " format "\n", __func__,             \
-                          __LINE__, ##args);                           \
-} while (0)
-
-/**
- * onenand_lock_handle - Handle Lock scheme
- * @this:              OneNAND device structure
- * @cmd:               The command to be sent
- *
- * Send lock command to OneNAND device.
- * The lock scheme depends on chip type.
- */
-static void onenand_lock_handle(struct onenand_chip *this, int cmd)
-{
-       int block_lock_scheme;
-       int status;
-
-       status = ONENAND_GET_WP_STATUS(this);
-       block_lock_scheme = !(this->options & ONENAND_HAS_CONT_LOCK);
-
-       switch (cmd) {
-       case ONENAND_CMD_UNLOCK:
-       case ONENAND_CMD_UNLOCK_ALL:
-               if (block_lock_scheme)
-                       ONENAND_SET_WP_STATUS(ONENAND_WP_US, this);
-               else
-                       ONENAND_SET_WP_STATUS(status | ONENAND_WP_US, this);
-               break;
-
-       case ONENAND_CMD_LOCK:
-               if (block_lock_scheme)
-                       ONENAND_SET_WP_STATUS(ONENAND_WP_LS, this);
-               else
-                       ONENAND_SET_WP_STATUS(status | ONENAND_WP_LS, this);
-               break;
-
-       case ONENAND_CMD_LOCK_TIGHT:
-               if (block_lock_scheme)
-                       ONENAND_SET_WP_STATUS(ONENAND_WP_LTS, this);
-               else
-                       ONENAND_SET_WP_STATUS(status | ONENAND_WP_LTS, this);
-               break;
-
-       default:
-               break;
-       }
-}
-
-/**
- * onenand_bootram_handle - Handle BootRAM area
- * @this:              OneNAND device structure
- * @cmd:               The command to be sent
- *
- * Emulate BootRAM area. It is possible to do basic operation using BootRAM.
- */
-static void onenand_bootram_handle(struct onenand_chip *this, int cmd)
-{
-       switch (cmd) {
-       case ONENAND_CMD_READID:
-               writew(manuf_id, this->base);
-               writew(device_id, this->base + 2);
-               writew(version_id, this->base + 4);
-               break;
-
-       default:
-               /* REVIST: Handle other commands */
-               break;
-       }
-}
-
-/**
- * onenand_update_interrupt - Set interrupt register
- * @this:         OneNAND device structure
- * @cmd:          The command to be sent
- *
- * Update interrupt register. The status depends on command.
- */
-static void onenand_update_interrupt(struct onenand_chip *this, int cmd)
-{
-       int interrupt = ONENAND_INT_MASTER;
-
-       switch (cmd) {
-       case ONENAND_CMD_READ:
-       case ONENAND_CMD_READOOB:
-               interrupt |= ONENAND_INT_READ;
-               break;
-
-       case ONENAND_CMD_PROG:
-       case ONENAND_CMD_PROGOOB:
-               interrupt |= ONENAND_INT_WRITE;
-               break;
-
-       case ONENAND_CMD_ERASE:
-               interrupt |= ONENAND_INT_ERASE;
-               break;
-
-       case ONENAND_CMD_RESET:
-               interrupt |= ONENAND_INT_RESET;
-               break;
-
-       default:
-               break;
-       }
-
-       writew(interrupt, this->base + ONENAND_REG_INTERRUPT);
-}
-
-/**
- * onenand_check_overwrite - Check if over-write happened
- * @dest:              The destination pointer
- * @src:               The source pointer
- * @count:             The length to be check
- *
- * Returns:            0 on same, otherwise 1
- *
- * Compare the source with destination
- */
-static int onenand_check_overwrite(void *dest, void *src, size_t count)
-{
-       unsigned int *s = (unsigned int *) src;
-       unsigned int *d = (unsigned int *) dest;
-       int i;
-
-       count >>= 2;
-       for (i = 0; i < count; i++)
-               if ((*s++ ^ *d++) != 0)
-                       return 1;
-
-       return 0;
-}
-
-/**
- * onenand_data_handle - Handle OneNAND Core and DataRAM
- * @this:              OneNAND device structure
- * @cmd:               The command to be sent
- * @dataram:           Which dataram used
- * @offset:            The offset to OneNAND Core
- *
- * Copy data from OneNAND Core to DataRAM (read)
- * Copy data from DataRAM to OneNAND Core (write)
- * Erase the OneNAND Core (erase)
- */
-static void onenand_data_handle(struct onenand_chip *this, int cmd,
-                               int dataram, unsigned int offset)
-{
-       struct mtd_info *mtd = &info->mtd;
-       struct onenand_flash *flash = this->priv;
-       int main_offset, spare_offset, die = 0;
-       void __iomem *src;
-       void __iomem *dest;
-       unsigned int i;
-       static int pi_operation;
-       int erasesize, rgn;
-
-       if (dataram) {
-               main_offset = mtd->writesize;
-               spare_offset = mtd->oobsize;
-       } else {
-               main_offset = 0;
-               spare_offset = 0;
-       }
-
-       if (pi_operation) {
-               die = readw(this->base + ONENAND_REG_START_ADDRESS2);
-               die >>= ONENAND_DDP_SHIFT;
-       }
-
-       switch (cmd) {
-       case FLEXONENAND_CMD_PI_ACCESS:
-               pi_operation = 1;
-               break;
-
-       case ONENAND_CMD_RESET:
-               pi_operation = 0;
-               break;
-
-       case ONENAND_CMD_READ:
-               src = ONENAND_CORE(flash) + offset;
-               dest = ONENAND_MAIN_AREA(this, main_offset);
-               if (pi_operation) {
-                       writew(boundary[die], this->base + ONENAND_DATARAM);
-                       break;
-               }
-               memcpy(dest, src, mtd->writesize);
-               /* Fall through */
-
-       case ONENAND_CMD_READOOB:
-               src = ONENAND_CORE_SPARE(flash, this, offset);
-               dest = ONENAND_SPARE_AREA(this, spare_offset);
-               memcpy(dest, src, mtd->oobsize);
-               break;
-
-       case ONENAND_CMD_PROG:
-               src = ONENAND_MAIN_AREA(this, main_offset);
-               dest = ONENAND_CORE(flash) + offset;
-               if (pi_operation) {
-                       boundary[die] = readw(this->base + ONENAND_DATARAM);
-                       break;
-               }
-               /* To handle partial write */
-               for (i = 0; i < (1 << mtd->subpage_sft); i++) {
-                       int off = i * this->subpagesize;
-                       if (!memcmp(src + off, ffchars, this->subpagesize))
-                               continue;
-                       if (memcmp(dest + off, ffchars, this->subpagesize) &&
-                           onenand_check_overwrite(dest + off, src + off, this->subpagesize))
-                               printk(KERN_ERR "over-write happened at 0x%08x\n", offset);
-                       memcpy(dest + off, src + off, this->subpagesize);
-               }
-               /* Fall through */
-
-       case ONENAND_CMD_PROGOOB:
-               src = ONENAND_SPARE_AREA(this, spare_offset);
-               /* Check all data is 0xff chars */
-               if (!memcmp(src, ffchars, mtd->oobsize))
-                       break;
-
-               dest = ONENAND_CORE_SPARE(flash, this, offset);
-               if (memcmp(dest, ffchars, mtd->oobsize) &&
-                   onenand_check_overwrite(dest, src, mtd->oobsize))
-                       printk(KERN_ERR "OOB: over-write happened at 0x%08x\n",
-                              offset);
-               memcpy(dest, src, mtd->oobsize);
-               break;
-
-       case ONENAND_CMD_ERASE:
-               if (pi_operation)
-                       break;
-
-               if (FLEXONENAND(this)) {
-                       rgn = flexonenand_region(mtd, offset);
-                       erasesize = mtd->eraseregions[rgn].erasesize;
-               } else
-                       erasesize = mtd->erasesize;
-
-               memset(ONENAND_CORE(flash) + offset, 0xff, erasesize);
-               memset(ONENAND_CORE_SPARE(flash, this, offset), 0xff,
-                      (erasesize >> 5));
-               break;
-
-       default:
-               break;
-       }
-}
-
-/**
- * onenand_command_handle - Handle command
- * @this:              OneNAND device structure
- * @cmd:               The command to be sent
- *
- * Emulate OneNAND command.
- */
-static void onenand_command_handle(struct onenand_chip *this, int cmd)
-{
-       unsigned long offset = 0;
-       int block = -1, page = -1, bufferram = -1;
-       int dataram = 0;
-
-       switch (cmd) {
-       case ONENAND_CMD_UNLOCK:
-       case ONENAND_CMD_LOCK:
-       case ONENAND_CMD_LOCK_TIGHT:
-       case ONENAND_CMD_UNLOCK_ALL:
-               onenand_lock_handle(this, cmd);
-               break;
-
-       case ONENAND_CMD_BUFFERRAM:
-               /* Do nothing */
-               return;
-
-       default:
-               block = (int) readw(this->base + ONENAND_REG_START_ADDRESS1);
-               if (block & (1 << ONENAND_DDP_SHIFT)) {
-                       block &= ~(1 << ONENAND_DDP_SHIFT);
-                       /* The half of chip block */
-                       block += this->chipsize >> (this->erase_shift + 1);
-               }
-               if (cmd == ONENAND_CMD_ERASE)
-                       break;
-
-               page = (int) readw(this->base + ONENAND_REG_START_ADDRESS8);
-               page = (page >> ONENAND_FPA_SHIFT);
-               bufferram = (int) readw(this->base + ONENAND_REG_START_BUFFER);
-               bufferram >>= ONENAND_BSA_SHIFT;
-               bufferram &= ONENAND_BSA_DATARAM1;
-               dataram = (bufferram == ONENAND_BSA_DATARAM1) ? 1 : 0;
-               break;
-       }
-
-       if (block != -1)
-               offset = onenand_addr(this, block);
-
-       if (page != -1)
-               offset += page << this->page_shift;
-
-       onenand_data_handle(this, cmd, dataram, offset);
-
-       onenand_update_interrupt(this, cmd);
-}
-
-/**
- * onenand_writew - [OneNAND Interface] Emulate write operation
- * @value:             value to write
- * @addr:              address to write
- *
- * Write OneNAND register with value
- */
-static void onenand_writew(unsigned short value, void __iomem * addr)
-{
-       struct onenand_chip *this = info->mtd.priv;
-
-       /* BootRAM handling */
-       if (addr < this->base + ONENAND_DATARAM) {
-               onenand_bootram_handle(this, value);
-               return;
-       }
-       /* Command handling */
-       if (addr == this->base + ONENAND_REG_COMMAND)
-               onenand_command_handle(this, value);
-
-       writew(value, addr);
-}
-
-/**
- * flash_init - Initialize OneNAND simulator
- * @flash:             OneNAND simulator data strucutres
- *
- * Initialize OneNAND simulator.
- */
-static int __init flash_init(struct onenand_flash *flash)
-{
-       int density, size;
-       int buffer_size;
-
-       flash->base = kzalloc(131072, GFP_KERNEL);
-       if (!flash->base) {
-               printk(KERN_ERR "Unable to allocate base address.\n");
-               return -ENOMEM;
-       }
-
-       density = device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
-       density &= ONENAND_DEVICE_DENSITY_MASK;
-       size = ((16 << 20) << density);
-
-       ONENAND_CORE(flash) = vmalloc(size + (size >> 5));
-       if (!ONENAND_CORE(flash)) {
-               printk(KERN_ERR "Unable to allocate nand core address.\n");
-               kfree(flash->base);
-               return -ENOMEM;
-       }
-
-       memset(ONENAND_CORE(flash), 0xff, size + (size >> 5));
-
-       /* Setup registers */
-       writew(manuf_id, flash->base + ONENAND_REG_MANUFACTURER_ID);
-       writew(device_id, flash->base + ONENAND_REG_DEVICE_ID);
-       writew(version_id, flash->base + ONENAND_REG_VERSION_ID);
-       writew(technology_id, flash->base + ONENAND_REG_TECHNOLOGY);
-
-       if (density < 2 && (!CONFIG_FLEXONENAND))
-               buffer_size = 0x0400;   /* 1KiB page */
-       else
-               buffer_size = 0x0800;   /* 2KiB page */
-       writew(buffer_size, flash->base + ONENAND_REG_DATA_BUFFER_SIZE);
-
-       return 0;
-}
-
-/**
- * flash_exit - Clean up OneNAND simulator
- * @flash:             OneNAND simulator data structures
- *
- * Clean up OneNAND simulator.
- */
-static void flash_exit(struct onenand_flash *flash)
-{
-       vfree(ONENAND_CORE(flash));
-       kfree(flash->base);
-}
-
-static int __init onenand_sim_init(void)
-{
-       /* Allocate all 0xff chars pointer */
-       ffchars = kmalloc(MAX_ONENAND_PAGESIZE, GFP_KERNEL);
-       if (!ffchars) {
-               printk(KERN_ERR "Unable to allocate ff chars.\n");
-               return -ENOMEM;
-       }
-       memset(ffchars, 0xff, MAX_ONENAND_PAGESIZE);
-
-       /* Allocate OneNAND simulator mtd pointer */
-       info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL);
-       if (!info) {
-               printk(KERN_ERR "Unable to allocate core structures.\n");
-               kfree(ffchars);
-               return -ENOMEM;
-       }
-
-       /* Override write_word function */
-       info->onenand.write_word = onenand_writew;
-
-       if (flash_init(&info->flash)) {
-               printk(KERN_ERR "Unable to allocate flash.\n");
-               kfree(ffchars);
-               kfree(info);
-               return -ENOMEM;
-       }
-
-       info->parts = os_partitions;
-
-       info->onenand.base = info->flash.base;
-       info->onenand.priv = &info->flash;
-
-       info->mtd.name = "OneNAND simulator";
-       info->mtd.priv = &info->onenand;
-       info->mtd.owner = THIS_MODULE;
-
-       if (onenand_scan(&info->mtd, 1)) {
-               flash_exit(&info->flash);
-               kfree(ffchars);
-               kfree(info);
-               return -ENXIO;
-       }
-
-       mtd_device_register(&info->mtd, info->parts,
-                           ARRAY_SIZE(os_partitions));
-
-       return 0;
-}
-
-static void __exit onenand_sim_exit(void)
-{
-       struct onenand_chip *this = info->mtd.priv;
-       struct onenand_flash *flash = this->priv;
-
-       onenand_release(&info->mtd);
-       flash_exit(flash);
-       kfree(ffchars);
-       kfree(info);
-}
-
-module_init(onenand_sim_init);
-module_exit(onenand_sim_exit);
-
-MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
-MODULE_DESCRIPTION("The OneNAND flash simulator");
-MODULE_LICENSE("GPL");
index fa385a368a561219b3c510524bffd0325ea1446d..09077067b0c858d5e13ab74819c9985b1429c0ca 100644 (file)
@@ -18,7 +18,7 @@
 
 #include "ssb_private.h"
 
-static const char *part_probes[] = { "bcm47xxpart", NULL };
+static const char * const part_probes[] = { "bcm47xxpart", NULL };
 
 static struct physmap_flash_data ssb_pflash_data = {
        .part_probe_types       = part_probes,
index f9ac2897b86b040f0143b9bbc3d10bb9699f6cd6..a5cf4e8d68187e5bd5e7892effc0957dc5bfea0b 100644 (file)
@@ -362,10 +362,10 @@ struct mtd_partition;
 struct mtd_part_parser_data;
 
 extern int mtd_device_parse_register(struct mtd_info *mtd,
-                             const char **part_probe_types,
-                             struct mtd_part_parser_data *parser_data,
-                             const struct mtd_partition *defparts,
-                             int defnr_parts);
+                                    const char * const *part_probe_types,
+                                    struct mtd_part_parser_data *parser_data,
+                                    const struct mtd_partition *defparts,
+                                    int defnr_parts);
 #define mtd_device_register(master, parts, nr_parts)   \
        mtd_device_parse_register(master, NULL, NULL, parts, nr_parts)
 extern int mtd_device_unregister(struct mtd_info *master);
index ef52d9c91459e0204e31c98483922b7ab95b1ebb..ab6363443ce81f033b641b014102a2dfdf8921be 100644 (file)
@@ -86,7 +86,6 @@ extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 #define NAND_CMD_READOOB       0x50
 #define NAND_CMD_ERASE1                0x60
 #define NAND_CMD_STATUS                0x70
-#define NAND_CMD_STATUS_MULTI  0x71
 #define NAND_CMD_SEQIN         0x80
 #define NAND_CMD_RNDIN         0x85
 #define NAND_CMD_READID                0x90
@@ -105,25 +104,6 @@ extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 #define NAND_CMD_RNDOUTSTART   0xE0
 #define NAND_CMD_CACHEDPROG    0x15
 
-/* Extended commands for AG-AND device */
-/*
- * Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but
- *       there is no way to distinguish that from NAND_CMD_READ0
- *       until the remaining sequence of commands has been completed
- *       so add a high order bit and mask it off in the command.
- */
-#define NAND_CMD_DEPLETE1      0x100
-#define NAND_CMD_DEPLETE2      0x38
-#define NAND_CMD_STATUS_MULTI  0x71
-#define NAND_CMD_STATUS_ERROR  0x72
-/* multi-bank error status (banks 0-3) */
-#define NAND_CMD_STATUS_ERROR0 0x73
-#define NAND_CMD_STATUS_ERROR1 0x74
-#define NAND_CMD_STATUS_ERROR2 0x75
-#define NAND_CMD_STATUS_ERROR3 0x76
-#define NAND_CMD_STATUS_RESET  0x7f
-#define NAND_CMD_STATUS_CLEAR  0xff
-
 #define NAND_CMD_NONE          -1
 
 /* Status bits */
@@ -165,28 +145,8 @@ typedef enum {
  */
 /* Buswidth is 16 bit */
 #define NAND_BUSWIDTH_16       0x00000002
-/* Device supports partial programming without padding */
-#define NAND_NO_PADDING                0x00000004
 /* Chip has cache program function */
 #define NAND_CACHEPRG          0x00000008
-/* Chip has copy back function */
-#define NAND_COPYBACK          0x00000010
-/*
- * AND Chip which has 4 banks and a confusing page / block
- * assignment. See Renesas datasheet for further information.
- */
-#define NAND_IS_AND            0x00000020
-/*
- * Chip has a array of 4 pages which can be read without
- * additional ready /busy waits.
- */
-#define NAND_4PAGE_ARRAY       0x00000040
-/*
- * Chip requires that BBT is periodically rewritten to prevent
- * bits from adjacent blocks from 'leaking' in altering data.
- * This happens with the Renesas AG-AND chips, possibly others.
- */
-#define BBT_AUTO_REFRESH       0x00000080
 /*
  * Chip requires ready check on read (for auto-incremented sequential read).
  * True only for small page devices; large page devices do not support
@@ -207,13 +167,10 @@ typedef enum {
 #define NAND_SUBPAGE_READ      0x00001000
 
 /* Options valid for Samsung large page devices */
-#define NAND_SAMSUNG_LP_OPTIONS \
-       (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK)
+#define NAND_SAMSUNG_LP_OPTIONS NAND_CACHEPRG
 
 /* Macros to identify the above */
-#define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING))
 #define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG))
-#define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK))
 #define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ))
 
 /* Non chip related options */
@@ -361,6 +318,7 @@ struct nand_hw_control {
  *             any single ECC step, 0 if bitflips uncorrectable, -EIO hw error
  * @read_subpage:      function to read parts of the page covered by ECC;
  *                     returns same as read_page()
+ * @write_subpage:     function to write parts of the page covered by ECC.
  * @write_page:        function to write a page according to the ECC generator
  *             requirements.
  * @write_oob_raw:     function to write chip OOB data without ECC
@@ -392,6 +350,9 @@ struct nand_ecc_ctrl {
                        uint8_t *buf, int oob_required, int page);
        int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
                        uint32_t offs, uint32_t len, uint8_t *buf);
+       int (*write_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
+                       uint32_t offset, uint32_t data_len,
+                       const uint8_t *data_buf, int oob_required);
        int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
                        const uint8_t *buf, int oob_required);
        int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
@@ -527,8 +488,8 @@ struct nand_chip {
        int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state,
                        int status, int page);
        int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
-                       const uint8_t *buf, int oob_required, int page,
-                       int cached, int raw);
+                       uint32_t offset, int data_len, const uint8_t *buf,
+                       int oob_required, int page, int cached, int raw);
        int (*onfi_set_features)(struct mtd_info *mtd, struct nand_chip *chip,
                        int feature_addr, uint8_t *subfeature_para);
        int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip,
@@ -589,25 +550,65 @@ struct nand_chip {
 #define NAND_MFR_MACRONIX      0xc2
 #define NAND_MFR_EON           0x92
 
+/* The maximum expected count of bytes in the NAND ID sequence */
+#define NAND_MAX_ID_LEN 8
+
+/*
+ * A helper for defining older NAND chips where the second ID byte fully
+ * defined the chip, including the geometry (chip size, eraseblock size, page
+ * size). All these chips have 512 bytes NAND page size.
+ */
+#define LEGACY_ID_NAND(nm, devid, chipsz, erasesz, opts)          \
+       { .name = (nm), {{ .dev_id = (devid) }}, .pagesize = 512, \
+         .chipsize = (chipsz), .erasesize = (erasesz), .options = (opts) }
+
+/*
+ * A helper for defining newer chips which report their page size and
+ * eraseblock size via the extended ID bytes.
+ *
+ * The real difference between LEGACY_ID_NAND and EXTENDED_ID_NAND is that with
+ * EXTENDED_ID_NAND, manufacturers overloaded the same device ID so that the
+ * device ID now only represented a particular total chip size (and voltage,
+ * buswidth), and the page size, eraseblock size, and OOB size could vary while
+ * using the same device ID.
+ */
+#define EXTENDED_ID_NAND(nm, devid, chipsz, opts)                      \
+       { .name = (nm), {{ .dev_id = (devid) }}, .chipsize = (chipsz), \
+         .options = (opts) }
+
 /**
  * struct nand_flash_dev - NAND Flash Device ID Structure
- * @name:      Identify the device type
- * @id:                device ID code
- * @pagesize:  Pagesize in bytes. Either 256 or 512 or 0
- *             If the pagesize is 0, then the real pagesize
- *             and the eraseize are determined from the
- *             extended id bytes in the chip
- * @erasesize: Size of an erase block in the flash device.
- * @chipsize:  Total chipsize in Mega Bytes
- * @options:   Bitfield to store chip relevant options
+ * @name: a human-readable name of the NAND chip
+ * @dev_id: the device ID (the second byte of the full chip ID array)
+ * @mfr_id: manufecturer ID part of the full chip ID array (refers the same
+ *          memory address as @id[0])
+ * @dev_id: device ID part of the full chip ID array (refers the same memory
+ *          address as @id[1])
+ * @id: full device ID array
+ * @pagesize: size of the NAND page in bytes; if 0, then the real page size (as
+ *            well as the eraseblock size) is determined from the extended NAND
+ *            chip ID array)
+ * @chipsize: total chip size in MiB
+ * @erasesize: eraseblock size in bytes (determined from the extended ID if 0)
+ * @options: stores various chip bit options
+ * @id_len: The valid length of the @id.
+ * @oobsize: OOB size
  */
 struct nand_flash_dev {
        char *name;
-       int id;
-       unsigned long pagesize;
-       unsigned long chipsize;
-       unsigned long erasesize;
-       unsigned long options;
+       union {
+               struct {
+                       uint8_t mfr_id;
+                       uint8_t dev_id;
+               };
+               uint8_t id[NAND_MAX_ID_LEN];
+       };
+       unsigned int pagesize;
+       unsigned int chipsize;
+       unsigned int erasesize;
+       unsigned int options;
+       uint16_t id_len;
+       uint16_t oobsize;
 };
 
 /**
index d2887e76b7f66845b3662c9c52b80b211b78f38b..aa6a2633c2da13697a0a969ab320973756f155b3 100644 (file)
@@ -30,7 +30,7 @@ struct physmap_flash_data {
        unsigned int            pfow_base;
        char                    *probe_type;
        struct mtd_partition    *parts;
-       const char              **part_probe_types;
+       const char * const      *part_probe_types;
 };
 
 #endif /* __LINUX_MTD_PHYSMAP__ */
index e07890aff1cf9523cb0fe4d07b0c06353da046c9..44212d65aa9760d3da44aec47fc7139e021a704d 100644 (file)
@@ -20,8 +20,8 @@
 
 struct platdata_mtd_ram {
        const char              *mapname;
-       const char              **map_probes;
-       const char              **probes;
+       const char * const      *map_probes;
+       const char * const      *probes;
        struct mtd_partition    *partitions;
        int                      nr_partitions;
        int                      bankwidth;
index 1bd5244d1dcd0720d878de32059867f125ab803e..bf0a83b7ed9d3e0538cc09c57f7d498065931501 100644 (file)
@@ -50,5 +50,5 @@ struct elm_errorvec {
 
 void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
                struct elm_errorvec *err_vec);
-void elm_config(struct device *dev, enum bch_ecc bch_type);
+int elm_config(struct device *dev, enum bch_ecc bch_type);
 #endif /* __ELM_H */