]> rtime.felk.cvut.cz Git - lisovros/linux_canprio.git/commitdiff
Merge git://git.infradead.org/mtd-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 10 Aug 2010 18:49:21 +0000 (11:49 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 10 Aug 2010 18:49:21 +0000 (11:49 -0700)
* git://git.infradead.org/mtd-2.6: (79 commits)
  mtd: Remove obsolete <mtd/compatmac.h> include
  mtd: Update copyright notices
  jffs2: Update copyright notices
  mtd-physmap: add support users can assign the probe type in board files
  mtd: remove redwood map driver
  mxc_nand: Add v3 (i.MX51) Support
  mxc_nand: support 8bit ecc
  mxc_nand: fix correct_data function
  mxc_nand: add V1_V2 namespace to registers
  mxc_nand: factor out a check_int function
  mxc_nand: make some internally used functions overwriteable
  mxc_nand: rework get_dev_status
  mxc_nand: remove 0xe00 offset from registers
  mtd: denali: Add multi connected NAND support
  mtd: denali: Remove set_ecc_config function
  mtd: denali: Remove unuseful code in get_xx_nand_para functions
  mtd: denali: Remove device_info_tag structure
  mtd: m25p80: add support for the Winbond W25Q32 SPI flash chip
  mtd: m25p80: add support for the Intel/Numonyx {16,32,64}0S33B SPI flash chips
  mtd: m25p80: add support for the EON EN25P{32, 64} SPI flash chips
  ...

Fix up trivial conflicts in drivers/mtd/maps/{Kconfig,redwood.c} due to
redwood driver removal.

107 files changed:
arch/blackfin/include/asm/nand.h
drivers/mtd/Kconfig
drivers/mtd/afs.c
drivers/mtd/chips/cfi_cmdset_0001.c
drivers/mtd/chips/cfi_cmdset_0002.c
drivers/mtd/chips/cfi_cmdset_0020.c
drivers/mtd/chips/cfi_probe.c
drivers/mtd/chips/cfi_util.c
drivers/mtd/chips/chipreg.c
drivers/mtd/chips/map_absent.c
drivers/mtd/chips/map_ram.c
drivers/mtd/chips/map_rom.c
drivers/mtd/cmdlinepart.c
drivers/mtd/devices/docecc.c
drivers/mtd/devices/docprobe.c
drivers/mtd/devices/m25p80.c
drivers/mtd/devices/mtd_dataflash.c
drivers/mtd/devices/mtdram.c
drivers/mtd/devices/pmc551.c
drivers/mtd/devices/sst25l.c
drivers/mtd/ftl.c
drivers/mtd/inftlcore.c
drivers/mtd/inftlmount.c
drivers/mtd/lpddr/lpddr_cmds.c
drivers/mtd/maps/Kconfig
drivers/mtd/maps/Makefile
drivers/mtd/maps/ixp4xx.c
drivers/mtd/maps/physmap.c
drivers/mtd/maps/physmap_of.c
drivers/mtd/maps/redwood.c [deleted file]
drivers/mtd/mtd_blkdevs.c
drivers/mtd/mtdblock.c
drivers/mtd/mtdblock_ro.c
drivers/mtd/mtdchar.c
drivers/mtd/mtdconcat.c
drivers/mtd/mtdcore.c
drivers/mtd/mtdoops.c
drivers/mtd/mtdpart.c
drivers/mtd/mtdsuper.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/atmel_nand.c
drivers/mtd/nand/bf5xx_nand.c
drivers/mtd/nand/davinci_nand.c
drivers/mtd/nand/denali.c
drivers/mtd/nand/denali.h
drivers/mtd/nand/diskonchip.c
drivers/mtd/nand/mxc_nand.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/plat_nand.c
drivers/mtd/nand/r852.c
drivers/mtd/nand/rtc_from4.c
drivers/mtd/nand/s3c2410.c
drivers/mtd/nand/sm_common.c
drivers/mtd/nftlcore.c
drivers/mtd/nftlmount.c
drivers/mtd/ofpart.c
drivers/mtd/onenand/Kconfig
drivers/mtd/onenand/onenand_base.c
drivers/mtd/onenand/onenand_bbt.c
drivers/mtd/onenand/samsung.c
drivers/mtd/redboot.c
drivers/mtd/rfd_ftl.c
drivers/mtd/ssfdc.c
drivers/mtd/tests/mtd_pagetest.c
fs/jffs2/background.c
fs/jffs2/build.c
fs/jffs2/compr.c
fs/jffs2/compr.h
fs/jffs2/compr_lzo.c
fs/jffs2/compr_rtime.c
fs/jffs2/compr_rubin.c
fs/jffs2/compr_zlib.c
fs/jffs2/debug.c
fs/jffs2/debug.h
fs/jffs2/dir.c
fs/jffs2/erase.c
fs/jffs2/file.c
fs/jffs2/fs.c
fs/jffs2/gc.c
fs/jffs2/ioctl.c
fs/jffs2/jffs2_fs_i.h
fs/jffs2/jffs2_fs_sb.h
fs/jffs2/nodelist.h
include/linux/jffs2.h
include/linux/mtd/bbm.h
include/linux/mtd/blktrans.h
include/linux/mtd/cfi.h
include/linux/mtd/cfi_endian.h
include/linux/mtd/compatmac.h [deleted file]
include/linux/mtd/concat.h
include/linux/mtd/doc2000.h
include/linux/mtd/flashchip.h
include/linux/mtd/gen_probe.h
include/linux/mtd/map.h
include/linux/mtd/mtd.h
include/linux/mtd/nand.h
include/linux/mtd/nand_ecc.h
include/linux/mtd/nftl.h
include/linux/mtd/onenand.h
include/linux/mtd/physmap.h
include/mtd/mtd-abi.h
include/mtd/mtd-user.h
include/mtd/nftl-user.h
include/mtd/ubi-user.h

index 3a1e79dfc8d92636ab94b17129a7f291c01e4859..256c50d8d46570e5f82cee6bb2e729e20bf30208 100644 (file)
@@ -15,8 +15,6 @@
  * partitions   = mtd partition list
  */
 
-#define NFC_PG_SIZE_256                0
-#define NFC_PG_SIZE_512                1
 #define NFC_PG_SIZE_OFFSET     9
 
 #define NFC_NWIDTH_8           0
@@ -30,7 +28,6 @@
 
 struct bf5xx_nand_platform {
        /* NAND chip information */
-       unsigned short          page_size;
        unsigned short          data_width;
 
        /* RD/WR strobe delay timing information, all times in SCLK cycles */
index f8210bf2d2414dee3e0b5e8f54089374c00c7219..1e2cbf5d9aa11200697a23d0b20f8f35435839b6 100644 (file)
@@ -311,15 +311,17 @@ config SM_FTL
        select MTD_BLKDEVS
        select MTD_NAND_ECC
        help
-         This enables new and very EXPERMENTAL support for SmartMedia/xD
+         This enables EXPERIMENTAL R/W support for SmartMedia/xD
          FTL (Flash translation layer).
-         Write support isn't yet well tested, therefore this code IS likely to
-         eat your card, so please don't use it together with valuable data.
-         Use readonly driver (CONFIG_SSFDC) instead.
+         Write support is only lightly tested, therefore this driver
+         isn't recommended to use with valuable data (anyway if you have
+         valuable data, do backups regardless of software/hardware you
+         use, because you never know what will eat your data...)
+         If you only need R/O access, you can use older R/O driver
+         (CONFIG_SSFDC)
 
 config MTD_OOPS
        tristate "Log panic/oops to an MTD buffer"
-       depends on MTD
        help
          This enables panic and oops messages to be logged to a circular
          buffer in a flash partition where it can be read back at some
index cec7ab98b2a9d9bed2496a335881469b12b0b0b0..302372c08b566cf61b7f0022aa059779bc123208 100644 (file)
@@ -2,7 +2,7 @@
 
     drivers/mtd/afs.c: ARM Flash Layout/Partitioning
 
-    Copyright (C) 2000 ARM Limited
+    Copyright © 2000 ARM Limited
 
    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
index 62f3ea9de848cabfb481014ca0b6176893da5a0f..9e2b7e9e0ad91b4871423cf2f449c1b63329cb10 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/mtd/xip.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/mtd.h>
-#include <linux/mtd/compatmac.h>
 #include <linux/mtd/cfi.h>
 
 /* #define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE */
@@ -63,6 +62,8 @@ static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *);
 static void cfi_intelext_sync (struct mtd_info *);
 static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
+static int cfi_intelext_is_locked(struct mtd_info *mtd, loff_t ofs,
+                                 uint64_t len);
 #ifdef CONFIG_MTD_OTP
 static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
@@ -448,6 +449,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
        mtd->sync    = cfi_intelext_sync;
        mtd->lock    = cfi_intelext_lock;
        mtd->unlock  = cfi_intelext_unlock;
+       mtd->is_locked = cfi_intelext_is_locked;
        mtd->suspend = cfi_intelext_suspend;
        mtd->resume  = cfi_intelext_resume;
        mtd->flags   = MTD_CAP_NORFLASH;
@@ -717,7 +719,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
                chip = &newcfi->chips[0];
                for (i = 0; i < cfi->numchips; i++) {
                        shared[i].writing = shared[i].erasing = NULL;
-                       spin_lock_init(&shared[i].lock);
+                       mutex_init(&shared[i].lock);
                        for (j = 0; j < numparts; j++) {
                                *chip = cfi->chips[i];
                                chip->start += j << partshift;
@@ -886,7 +888,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                 */
                struct flchip_shared *shared = chip->priv;
                struct flchip *contender;
-               spin_lock(&shared->lock);
+               mutex_lock(&shared->lock);
                contender = shared->writing;
                if (contender && contender != chip) {
                        /*
@@ -899,7 +901,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                         * get_chip returns success we're clear to go ahead.
                         */
                        ret = mutex_trylock(&contender->mutex);
-                       spin_unlock(&shared->lock);
+                       mutex_unlock(&shared->lock);
                        if (!ret)
                                goto retry;
                        mutex_unlock(&chip->mutex);
@@ -914,7 +916,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                                mutex_unlock(&contender->mutex);
                                return ret;
                        }
-                       spin_lock(&shared->lock);
+                       mutex_lock(&shared->lock);
 
                        /* We should not own chip if it is already
                         * in FL_SYNCING state. Put contender and retry. */
@@ -930,7 +932,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                 * on this chip. Sleep. */
                if (mode == FL_ERASING && shared->erasing
                    && shared->erasing->oldstate == FL_ERASING) {
-                       spin_unlock(&shared->lock);
+                       mutex_unlock(&shared->lock);
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&chip->wq, &wait);
                        mutex_unlock(&chip->mutex);
@@ -944,7 +946,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                shared->writing = chip;
                if (mode == FL_ERASING)
                        shared->erasing = chip;
-               spin_unlock(&shared->lock);
+               mutex_unlock(&shared->lock);
        }
        ret = chip_ready(map, chip, adr, mode);
        if (ret == -EAGAIN)
@@ -959,7 +961,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
 
        if (chip->priv) {
                struct flchip_shared *shared = chip->priv;
-               spin_lock(&shared->lock);
+               mutex_lock(&shared->lock);
                if (shared->writing == chip && chip->oldstate == FL_READY) {
                        /* We own the ability to write, but we're done */
                        shared->writing = shared->erasing;
@@ -967,7 +969,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
                                /* give back ownership to who we loaned it from */
                                struct flchip *loaner = shared->writing;
                                mutex_lock(&loaner->mutex);
-                               spin_unlock(&shared->lock);
+                               mutex_unlock(&shared->lock);
                                mutex_unlock(&chip->mutex);
                                put_chip(map, loaner, loaner->start);
                                mutex_lock(&chip->mutex);
@@ -985,11 +987,11 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
                         * Don't let the switch below mess things up since
                         * we don't have ownership to resume anything.
                         */
-                       spin_unlock(&shared->lock);
+                       mutex_unlock(&shared->lock);
                        wake_up(&chip->wq);
                        return;
                }
-               spin_unlock(&shared->lock);
+               mutex_unlock(&shared->lock);
        }
 
        switch(chip->oldstate) {
@@ -2139,6 +2141,13 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
        return ret;
 }
 
+static int cfi_intelext_is_locked(struct mtd_info *mtd, loff_t ofs,
+                                 uint64_t len)
+{
+       return cfi_varsize_frob(mtd, do_getlockstatus_oneblock,
+                               ofs, len, NULL) ? 1 : 0;
+}
+
 #ifdef CONFIG_MTD_OTP
 
 typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip,
index d81079ef91a538c20fa97f891df13db2958b36b5..3e6c47bdce5305a4851633db22d6e875930dabc2 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/reboot.h>
-#include <linux/mtd/compatmac.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/cfi.h>
@@ -417,16 +416,26 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
                         */
                        cfi_fixup_major_minor(cfi, extp);
 
+                       /*
+                        * Valid primary extension versions are: 1.0, 1.1, 1.2, 1.3, 1.4
+                        * see: http://www.amd.com/us-en/assets/content_type/DownloadableAssets/cfi_r20.pdf, page 19
+                        *      http://www.amd.com/us-en/assets/content_type/DownloadableAssets/cfi_100_20011201.pdf
+                        *      http://www.spansion.com/Support/Datasheets/s29ws-p_00_a12_e.pdf
+                        */
                        if (extp->MajorVersion != '1' ||
-                           (extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
+                           (extp->MajorVersion == '1' && (extp->MinorVersion < '0' || extp->MinorVersion > '4'))) {
                                printk(KERN_ERR "  Unknown Amd/Fujitsu Extended Query "
-                                      "version %c.%c.\n",  extp->MajorVersion,
-                                      extp->MinorVersion);
+                                      "version %c.%c (%#02x/%#02x).\n",
+                                      extp->MajorVersion, extp->MinorVersion,
+                                      extp->MajorVersion, extp->MinorVersion);
                                kfree(extp);
                                kfree(mtd);
                                return NULL;
                        }
 
+                       printk(KERN_INFO "  Amd/Fujitsu Extended Query version %c.%c.\n",
+                              extp->MajorVersion, extp->MinorVersion);
+
                        /* Install our own private info structure */
                        cfi->cmdset_priv = extp;
 
index e54e8c169d765bde22bcba4200923f1308d3e29b..314af1f5a370ec9d522820842f0054536dea0111 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/mtd/map.h>
 #include <linux/mtd/cfi.h>
 #include <linux/mtd/mtd.h>
-#include <linux/mtd/compatmac.h>
 
 
 static int cfi_staa_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
index b2acd32f4fbf8a89f8fec929b66f76ad47e9dbb9..8f5b96aa87a0ae601f2ebeb2ea2e4353bcf5d65d 100644 (file)
@@ -235,9 +235,9 @@ static int __xipram cfi_chip_setup(struct map_info *map,
        cfi_qry_mode_off(base, map, cfi);
        xip_allowed(base, map);
 
-       printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
+       printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank. Manufacturer ID %#08x Chip ID %#08x\n",
               map->name, cfi->interleave, cfi->device_type*8, base,
-              map->bankwidth*8);
+              map->bankwidth*8, cfi->mfr, cfi->id);
 
        return 1;
 }
index d7c2c672757e4695fe9158c31f1a4672428e446b..e503b2ca894de98687490d8b1806739dc9d61021 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/cfi.h>
-#include <linux/mtd/compatmac.h>
 
 int __xipram cfi_qry_present(struct map_info *map, __u32 base,
                             struct cfi_private *cfi)
index c857609682276468baac7079d2de839c60d7a84d..da1f96f385c70b695f6e52696cc91b3bf6833948 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/slab.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/mtd.h>
-#include <linux/mtd/compatmac.h>
 
 static DEFINE_SPINLOCK(chip_drvs_lock);
 static LIST_HEAD(chip_drvs_list);
index 494d30d0631a30b255b39c3996d827844aae948e..f2b87294687182abedba8ef30379fcd089e2827b 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/init.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
-#include <linux/mtd/compatmac.h>
 
 static int map_absent_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int map_absent_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
index 6bdc50c727e7b1aad9bea45c81e18959fc7f79f6..67640ccb2d4168d959de0f3c3d9c9b573f029923 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
-#include <linux/mtd/compatmac.h>
 
 
 static int mapram_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
index 076090a67b9088319b676ce58fc7cf82263d6a85..593f73d480d2cf9e615ced4e2e66d758e3c4f8f3 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
-#include <linux/mtd/compatmac.h>
 
 static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
index 1479da6d3aa6d78f3462c7817a56dcfede8a764e..e790f38893b00b2f0c0c645b3d66fd1b6a90651b 100644 (file)
@@ -1,7 +1,22 @@
 /*
  * Read flash partition table from command line
  *
- * Copyright 2002 SYSGO Real-Time Solutions GmbH
+ * Copyright © 2002      SYSGO Real-Time Solutions GmbH
+ * Copyright © 2002-2010 David Woodhouse <dwmw2@infradead.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  * The format for the command line is as follows:
  *
index a19cda52da5c15804cdf50aa594f41dc4f27b433..a99838bb2dc0806719efbc19b5c17f140e6281db 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/init.h>
 #include <linux/types.h>
 
-#include <linux/mtd/compatmac.h> /* for min() in older kernels */
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/doc2000.h>
 
index 6e62922942b18efd1a63fc44dfbad3d6ae087612..d374603493a7da77c6f0004643809e0ac5862374 100644 (file)
@@ -49,7 +49,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/doc2000.h>
-#include <linux/mtd/compatmac.h>
 
 /* Where to look for the devices? */
 #ifndef CONFIG_MTD_DOCPROBE_ADDRESS
index 81e49a9b017e32efd4137618c5ad4593e18c3658..f90941a785e4b163bf6f0451f2cbbb001c71b499 100644 (file)
@@ -16,6 +16,8 @@
  */
 
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
@@ -639,8 +641,18 @@ static const struct spi_device_id m25p_ids[] = {
        { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
        { "at26df321",  INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) },
 
+       /* EON -- en25pxx */
+       { "en25p32", INFO(0x1c2016, 0, 64 * 1024,  64, 0) },
+       { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
+
+       /* Intel/Numonyx -- xxxs33b */
+       { "160s33b",  INFO(0x898911, 0, 64 * 1024,  32, 0) },
+       { "320s33b",  INFO(0x898912, 0, 64 * 1024,  64, 0) },
+       { "640s33b",  INFO(0x898913, 0, 64 * 1024, 128, 0) },
+
        /* Macronix */
        { "mx25l4005a",  INFO(0xc22013, 0, 64 * 1024,   8, SECT_4K) },
+       { "mx25l8005",   INFO(0xc22014, 0, 64 * 1024,  16, 0) },
        { "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, 0) },
        { "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, 0) },
        { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
@@ -680,6 +692,16 @@ static const struct spi_device_id m25p_ids[] = {
        { "m25p64",  INFO(0x202017,  0,  64 * 1024, 128, 0) },
        { "m25p128", INFO(0x202018,  0, 256 * 1024,  64, 0) },
 
+       { "m25p05-nonjedec",  INFO(0, 0,  32 * 1024,   2, 0) },
+       { "m25p10-nonjedec",  INFO(0, 0,  32 * 1024,   4, 0) },
+       { "m25p20-nonjedec",  INFO(0, 0,  64 * 1024,   4, 0) },
+       { "m25p40-nonjedec",  INFO(0, 0,  64 * 1024,   8, 0) },
+       { "m25p80-nonjedec",  INFO(0, 0,  64 * 1024,  16, 0) },
+       { "m25p16-nonjedec",  INFO(0, 0,  64 * 1024,  32, 0) },
+       { "m25p32-nonjedec",  INFO(0, 0,  64 * 1024,  64, 0) },
+       { "m25p64-nonjedec",  INFO(0, 0,  64 * 1024, 128, 0) },
+       { "m25p128-nonjedec", INFO(0, 0, 256 * 1024,  64, 0) },
+
        { "m45pe10", INFO(0x204011,  0, 64 * 1024,    2, 0) },
        { "m45pe80", INFO(0x204014,  0, 64 * 1024,   16, 0) },
        { "m45pe16", INFO(0x204015,  0, 64 * 1024,   32, 0) },
@@ -694,6 +716,7 @@ static const struct spi_device_id m25p_ids[] = {
        { "w25x80", INFO(0xef3014, 0, 64 * 1024,  16, SECT_4K) },
        { "w25x16", INFO(0xef3015, 0, 64 * 1024,  32, SECT_4K) },
        { "w25x32", INFO(0xef3016, 0, 64 * 1024,  64, SECT_4K) },
+       { "w25q32", INFO(0xef4016, 0, 64 * 1024,  64, SECT_4K) },
        { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
 
        /* Catalyst / On Semiconductor -- non-JEDEC */
@@ -723,7 +746,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
        if (tmp < 0) {
                DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
                        dev_name(&spi->dev), tmp);
-               return NULL;
+               return ERR_PTR(tmp);
        }
        jedec = id[0];
        jedec = jedec << 8;
@@ -731,14 +754,6 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
        jedec = jedec << 8;
        jedec |= id[2];
 
-       /*
-        * Some chips (like Numonyx M25P80) have JEDEC and non-JEDEC variants,
-        * which depend on technology process. Officially RDID command doesn't
-        * exist for non-JEDEC chips, but for compatibility they return ID 0.
-        */
-       if (jedec == 0)
-               return NULL;
-
        ext_jedec = id[3] << 8 | id[4];
 
        for (tmp = 0; tmp < ARRAY_SIZE(m25p_ids) - 1; tmp++) {
@@ -749,7 +764,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
                        return &m25p_ids[tmp];
                }
        }
-       return NULL;
+       return ERR_PTR(-ENODEV);
 }
 
 
@@ -794,9 +809,8 @@ static int __devinit m25p_probe(struct spi_device *spi)
                const struct spi_device_id *jid;
 
                jid = jedec_probe(spi);
-               if (!jid) {
-                       dev_info(&spi->dev, "non-JEDEC variant of %s\n",
-                                id->name);
+               if (IS_ERR(jid)) {
+                       return PTR_ERR(jid);
                } else if (jid != id) {
                        /*
                         * JEDEC knows better, so overwrite platform ID. We
@@ -826,11 +840,12 @@ static int __devinit m25p_probe(struct spi_device *spi)
        dev_set_drvdata(&spi->dev, flash);
 
        /*
-        * Atmel and SST serial flash tend to power
+        * Atmel, SST and Intel/Numonyx serial flash tend to power
         * up with the software protection bits set
         */
 
        if (info->jedec_id >> 16 == 0x1f ||
+           info->jedec_id >> 16 == 0x89 ||
            info->jedec_id >> 16 == 0xbf) {
                write_enable(flash);
                write_sr(flash, 0);
index 19817404ce7d9e6f240e27cf299b3b724b005268..c5015cc721d50d7f02f1994999810a2a150c01d4 100644 (file)
@@ -141,7 +141,7 @@ static int dataflash_waitready(struct spi_device *spi)
  */
 static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
-       struct dataflash        *priv = (struct dataflash *)mtd->priv;
+       struct dataflash        *priv = mtd->priv;
        struct spi_device       *spi = priv->spi;
        struct spi_transfer     x = { .tx_dma = 0, };
        struct spi_message      msg;
@@ -231,7 +231,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
 static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
                               size_t *retlen, u_char *buf)
 {
-       struct dataflash        *priv = (struct dataflash *)mtd->priv;
+       struct dataflash        *priv = mtd->priv;
        struct spi_transfer     x[2] = { { .tx_dma = 0, }, };
        struct spi_message      msg;
        unsigned int            addr;
@@ -304,7 +304,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
 static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
                                size_t * retlen, const u_char * buf)
 {
-       struct dataflash        *priv = (struct dataflash *)mtd->priv;
+       struct dataflash        *priv = mtd->priv;
        struct spi_device       *spi = priv->spi;
        struct spi_transfer     x[2] = { { .tx_dma = 0, }, };
        struct spi_message      msg;
@@ -515,7 +515,7 @@ static ssize_t otp_read(struct spi_device *spi, unsigned base,
 static int dataflash_read_fact_otp(struct mtd_info *mtd,
                loff_t from, size_t len, size_t *retlen, u_char *buf)
 {
-       struct dataflash        *priv = (struct dataflash *)mtd->priv;
+       struct dataflash        *priv = mtd->priv;
        int                     status;
 
        /* 64 bytes, from 0..63 ... start at 64 on-chip */
@@ -532,7 +532,7 @@ static int dataflash_read_fact_otp(struct mtd_info *mtd,
 static int dataflash_read_user_otp(struct mtd_info *mtd,
                loff_t from, size_t len, size_t *retlen, u_char *buf)
 {
-       struct dataflash        *priv = (struct dataflash *)mtd->priv;
+       struct dataflash        *priv = mtd->priv;
        int                     status;
 
        /* 64 bytes, from 0..63 ... start at 0 on-chip */
@@ -553,7 +553,7 @@ static int dataflash_write_user_otp(struct mtd_info *mtd,
        const size_t            l = 4 + 64;
        uint8_t                 *scratch;
        struct spi_transfer     t;
-       struct dataflash        *priv = (struct dataflash *)mtd->priv;
+       struct dataflash        *priv = mtd->priv;
        int                     status;
 
        if (len > 64)
index fce5ff7589aa7e0591601041d82238878eca38b7..26a6e809013d272059b8f5dbebc2730283bf2c02 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/ioport.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
-#include <linux/mtd/compatmac.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtdram.h>
 
index fc8ea0a57ac2087dbbd46bf5a4791a8adffb727b..ef0aba0ce58fdfb7f9d0f7a40108787392d7bb82 100644 (file)
@@ -98,7 +98,6 @@
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/pmc551.h>
-#include <linux/mtd/compatmac.h>
 
 static struct mtd_info *pmc551list;
 
index ab5d8cd02a15aa1e5e8f53485bb9ec85916061b3..684247a8a5edafa720e102014595d15c7b500181 100644 (file)
@@ -454,7 +454,7 @@ static int __init sst25l_probe(struct spi_device *spi)
                                                  parts, nr_parts);
                }
 
-       } else if (data->nr_parts) {
+       } else if (data && data->nr_parts) {
                dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
                         data->nr_parts, data->name);
        }
index 62da9eb7032bdcc81c7b2722684586915331d1b1..4d6a64c387ecd53d14c2e892fd0b037aa980cd86 100644 (file)
@@ -26,7 +26,7 @@
 
     The initial developer of the original code is David A. Hinds
     <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
-    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+    are Copyright © 1999 David A. Hinds.  All Rights Reserved.
 
     Alternatively, the contents of this file may be used under the
     terms of the GNU General Public License version 2 (the "GPL"), in
index 015a7fe1b6ee3a92390da0cd12667b3634c49f6d..d7592e67d04861cfc2a952112445ef0601dd58ce 100644 (file)
@@ -1,11 +1,11 @@
 /*
  * inftlcore.c -- Linux driver for Inverse Flash Translation Layer (INFTL)
  *
- * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
+ * Copyright © 2002, Greg Ungerer (gerg@snapgear.com)
  *
  * Based heavily on the nftlcore.c code which is:
- * (c) 1999 Machine Vision Holdings, Inc.
- * Author: David Woodhouse <dwmw2@infradead.org>
+ * Copyright © 1999 Machine Vision Holdings, Inc.
+ * Copyright © 1999 David Woodhouse <dwmw2@infradead.org>
  *
  * 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
index 8f988d7d3c5c9925320eae830b4a44a829b360bc..104052e774b06a33ce56191f62077d29b8af57e6 100644 (file)
@@ -2,11 +2,11 @@
  * inftlmount.c -- INFTL mount code with extensive checks.
  *
  * Author: Greg Ungerer (gerg@snapgear.com)
- * (C) Copyright 2002-2003, Greg Ungerer (gerg@snapgear.com)
+ * Copyright © 2002-2003, Greg Ungerer (gerg@snapgear.com)
  *
  * Based heavily on the nftlmount.c code which is:
  * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
- * Copyright (C) 2000 Netgem S.A.
+ * Copyright © 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
@@ -34,7 +34,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nftl.h>
 #include <linux/mtd/inftl.h>
-#include <linux/mtd/compatmac.h>
 
 /*
  * find_boot_record: Find the INFTL Media Header and its Spare copy which
index fece5be587156b76f39d884ec62ca19bfc3e4db9..04fdfcca93f72b2db3c2b24ba41ddc913813fe98 100644 (file)
@@ -98,7 +98,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map)
        numchips = lpddr->numchips / lpddr->qinfo->HWPartsNum;
        for (i = 0; i < numchips; i++) {
                shared[i].writing = shared[i].erasing = NULL;
-               spin_lock_init(&shared[i].lock);
+               mutex_init(&shared[i].lock);
                for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) {
                        *chip = lpddr->chips[i];
                        chip->start += j << lpddr->chipshift;
@@ -217,7 +217,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
                 */
                struct flchip_shared *shared = chip->priv;
                struct flchip *contender;
-               spin_lock(&shared->lock);
+               mutex_lock(&shared->lock);
                contender = shared->writing;
                if (contender && contender != chip) {
                        /*
@@ -230,7 +230,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
                         * get_chip returns success we're clear to go ahead.
                         */
                        ret = mutex_trylock(&contender->mutex);
-                       spin_unlock(&shared->lock);
+                       mutex_unlock(&shared->lock);
                        if (!ret)
                                goto retry;
                        mutex_unlock(&chip->mutex);
@@ -245,7 +245,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
                                mutex_unlock(&contender->mutex);
                                return ret;
                        }
-                       spin_lock(&shared->lock);
+                       mutex_lock(&shared->lock);
 
                        /* We should not own chip if it is already in FL_SYNCING
                         * state. Put contender and retry. */
@@ -261,7 +261,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
                   Must sleep in such a case. */
                if (mode == FL_ERASING && shared->erasing
                    && shared->erasing->oldstate == FL_ERASING) {
-                       spin_unlock(&shared->lock);
+                       mutex_unlock(&shared->lock);
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&chip->wq, &wait);
                        mutex_unlock(&chip->mutex);
@@ -275,7 +275,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
                shared->writing = chip;
                if (mode == FL_ERASING)
                        shared->erasing = chip;
-               spin_unlock(&shared->lock);
+               mutex_unlock(&shared->lock);
        }
 
        ret = chip_ready(map, chip, mode);
@@ -348,7 +348,7 @@ static void put_chip(struct map_info *map, struct flchip *chip)
 {
        if (chip->priv) {
                struct flchip_shared *shared = chip->priv;
-               spin_lock(&shared->lock);
+               mutex_lock(&shared->lock);
                if (shared->writing == chip && chip->oldstate == FL_READY) {
                        /* We own the ability to write, but we're done */
                        shared->writing = shared->erasing;
@@ -356,7 +356,7 @@ static void put_chip(struct map_info *map, struct flchip *chip)
                                /* give back the ownership */
                                struct flchip *loaner = shared->writing;
                                mutex_lock(&loaner->mutex);
-                               spin_unlock(&shared->lock);
+                               mutex_unlock(&shared->lock);
                                mutex_unlock(&chip->mutex);
                                put_chip(map, loaner);
                                mutex_lock(&chip->mutex);
@@ -374,11 +374,11 @@ static void put_chip(struct map_info *map, struct flchip *chip)
                         * Don't let the switch below mess things up since
                         * we don't have ownership to resume anything.
                         */
-                       spin_unlock(&shared->lock);
+                       mutex_unlock(&shared->lock);
                        wake_up(&chip->wq);
                        return;
                }
-               spin_unlock(&shared->lock);
+               mutex_unlock(&shared->lock);
        }
 
        switch (chip->oldstate) {
index 6629d09f3b386bec539cd782264a69fc7d5242d5..701d942c679576492fcc7fea463a317f2e7863e5 100644 (file)
@@ -319,14 +319,6 @@ config MTD_CFI_FLAGADM
          Mapping for the Flaga digital module. If you don't have one, ignore
          this setting.
 
-config MTD_REDWOOD
-       tristate "CFI Flash devices mapped on IBM Redwood"
-       depends on MTD_CFI
-       help
-         This enables access routines for the flash chips on the IBM
-         Redwood board. If you have one of these boards and would like to
-         use the flash chips on it, say 'Y'.
-
 config MTD_SOLUTIONENGINE
        tristate "CFI Flash device mapped on Hitachi SolutionEngine"
        depends on SUPERH && SOLUTION_ENGINE && MTD_CFI && MTD_REDBOOT_PARTS
index bb035cd54c72e6fb0a5f2dcb867443bc5a78c464..f216bb573713a4edc99e7dbecb121541da76eb2b 100644 (file)
@@ -44,7 +44,6 @@ obj-$(CONFIG_MTD_AUTCPU12)    += autcpu12-nvram.o
 obj-$(CONFIG_MTD_EDB7312)      += edb7312.o
 obj-$(CONFIG_MTD_IMPA7)                += impa7.o
 obj-$(CONFIG_MTD_FORTUNET)     += fortunet.o
-obj-$(CONFIG_MTD_REDWOOD)      += redwood.o
 obj-$(CONFIG_MTD_UCLINUX)      += uclinux.o
 obj-$(CONFIG_MTD_NETtel)       += nettel.o
 obj-$(CONFIG_MTD_SCB2_FLASH)   += scb2_flash.o
index e0a5e0426ead49be256a455df91026427c950e97..1f9fde0dad35c95b95cbe4a66b30a4ec0c33e4ad 100644 (file)
@@ -118,7 +118,7 @@ static void ixp4xx_copy_from(struct map_info *map, void *to,
                *dest++ = BYTE1(data);
                src += 2;
                len -= 2;
-        }
+       }
 
        if (len > 0)
                *dest++ = BYTE0(flash_read16(src));
@@ -185,6 +185,8 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
 {
        struct flash_platform_data *plat = dev->dev.platform_data;
        struct ixp4xx_flash_info *info;
+       const char *part_type = NULL;
+       int nr_parts = 0;
        int err = -1;
 
        if (!plat)
@@ -218,9 +220,9 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
         */
        info->map.bankwidth = 2;
        info->map.name = dev_name(&dev->dev);
-       info->map.read = ixp4xx_read16,
-       info->map.write = ixp4xx_probe_write16,
-       info->map.copy_from = ixp4xx_copy_from,
+       info->map.read = ixp4xx_read16;
+       info->map.write = ixp4xx_probe_write16;
+       info->map.copy_from = ixp4xx_copy_from;
 
        info->res = request_mem_region(dev->resource->start,
                        resource_size(dev->resource),
@@ -248,11 +250,28 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
        info->mtd->owner = THIS_MODULE;
 
        /* Use the fast version */
-       info->map.write = ixp4xx_write16,
+       info->map.write = ixp4xx_write16;
+
+#ifdef CONFIG_MTD_PARTITIONS
+       nr_parts = parse_mtd_partitions(info->mtd, probes, &info->partitions,
+                                       dev->resource->start);
+#endif
+       if (nr_parts > 0) {
+               part_type = "dynamic";
+       } else {
+               info->partitions = plat->parts;
+               nr_parts = plat->nr_parts;
+               part_type = "static";
+       }
+       if (nr_parts == 0) {
+               printk(KERN_NOTICE "IXP4xx flash: no partition info "
+                       "available, registering whole flash\n");
+               err = add_mtd_device(info->mtd);
+       } else {
+               printk(KERN_NOTICE "IXP4xx flash: using %s partition "
+                       "definition\n", part_type);
+               err = add_mtd_partitions(info->mtd, info->partitions, nr_parts);
 
-       err = parse_mtd_partitions(info->mtd, probes, &info->partitions, dev->resource->start);
-       if (err > 0) {
-               err = add_mtd_partitions(info->mtd, info->partitions, err);
                if(err)
                        printk(KERN_ERR "Could not parse partitions\n");
        }
index 426461a5f0d43cbebd076e5e07f3d2e0d656c891..4c18b98a3110872f8648fcf8526f46fd19c162f3 100644 (file)
@@ -106,12 +106,12 @@ static int physmap_flash_probe(struct platform_device *dev)
 
        for (i = 0; i < dev->num_resources; i++) {
                printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n",
-                      (unsigned long long)(dev->resource[i].end - dev->resource[i].start + 1),
+                      (unsigned long long)resource_size(&dev->resource[i]),
                       (unsigned long long)dev->resource[i].start);
 
                if (!devm_request_mem_region(&dev->dev,
                        dev->resource[i].start,
-                       dev->resource[i].end - dev->resource[i].start + 1,
+                       resource_size(&dev->resource[i]),
                        dev_name(&dev->dev))) {
                        dev_err(&dev->dev, "Could not reserve memory region\n");
                        err = -ENOMEM;
@@ -120,7 +120,7 @@ static int physmap_flash_probe(struct platform_device *dev)
 
                info->map[i].name = dev_name(&dev->dev);
                info->map[i].phys = dev->resource[i].start;
-               info->map[i].size = dev->resource[i].end - dev->resource[i].start + 1;
+               info->map[i].size = resource_size(&dev->resource[i]);
                info->map[i].bankwidth = physmap_data->width;
                info->map[i].set_vpp = physmap_data->set_vpp;
                info->map[i].pfow_base = physmap_data->pfow_base;
@@ -136,8 +136,12 @@ static int physmap_flash_probe(struct platform_device *dev)
                simple_map_init(&info->map[i]);
 
                probe_type = rom_probe_types;
-               for (; info->mtd[i] == NULL && *probe_type != NULL; probe_type++)
-                       info->mtd[i] = do_map_probe(*probe_type, &info->map[i]);
+               if (physmap_data->probe_type == NULL) {
+                       for (; info->mtd[i] == NULL && *probe_type != NULL; probe_type++)
+                               info->mtd[i] = do_map_probe(*probe_type, &info->map[i]);
+               } else
+                       info->mtd[i] = do_map_probe(physmap_data->probe_type, &info->map[i]);
+
                if (info->mtd[i] == NULL) {
                        dev_err(&dev->dev, "map_probe failed\n");
                        err = -ENXIO;
index ba124baa646d7af1fe54cf958d2e26c2af5a00d9..6ac5f9f28ac3a9083b36411eb6a7518561976c58 100644 (file)
@@ -353,7 +353,7 @@ static int __devinit of_flash_probe(struct of_device *dev,
                                   &info->parts, 0);
        if (err < 0) {
                of_free_probes(part_probe_types);
-               return err;
+               goto err_out;
        }
        of_free_probes(part_probe_types);
 
@@ -361,14 +361,14 @@ static int __devinit of_flash_probe(struct of_device *dev,
        if (err == 0) {
                err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts);
                if (err < 0)
-                       return err;
+                       goto err_out;
        }
 #endif
 
        if (err == 0) {
                err = parse_obsolete_partitions(dev, info, dp);
                if (err < 0)
-                       return err;
+                       goto err_out;
        }
 
        if (err > 0)
diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c
deleted file mode 100644 (file)
index d2c9db0..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * drivers/mtd/maps/redwood.c
- *
- * FLASH map for the IBM Redwood 4/5/6 boards.
- *
- * Author: MontaVista Software, Inc. <source@mvista.com>
- *
- * 2001-2003 (c) MontaVista, Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-
-#define WINDOW_ADDR 0xffc00000
-#define WINDOW_SIZE 0x00400000
-
-#define RW_PART0_OF    0
-#define RW_PART0_SZ    0x10000
-#define RW_PART1_OF    RW_PART0_SZ
-#define RW_PART1_SZ    0x200000 - 0x10000
-#define RW_PART2_OF    0x200000
-#define RW_PART2_SZ    0x10000
-#define RW_PART3_OF    0x210000
-#define RW_PART3_SZ    0x200000 - (0x10000 + 0x20000)
-#define RW_PART4_OF    0x3e0000
-#define RW_PART4_SZ    0x20000
-
-static struct mtd_partition redwood_flash_partitions[] = {
-       {
-               .name = "Redwood OpenBIOS Vital Product Data",
-               .offset = RW_PART0_OF,
-               .size = RW_PART0_SZ,
-               .mask_flags = MTD_WRITEABLE     /* force read-only */
-       },
-       {
-               .name = "Redwood kernel",
-               .offset = RW_PART1_OF,
-               .size = RW_PART1_SZ
-       },
-       {
-               .name = "Redwood OpenBIOS non-volatile storage",
-               .offset = RW_PART2_OF,
-               .size = RW_PART2_SZ,
-               .mask_flags = MTD_WRITEABLE     /* force read-only */
-       },
-       {
-               .name = "Redwood filesystem",
-               .offset = RW_PART3_OF,
-               .size = RW_PART3_SZ
-       },
-       {
-               .name = "Redwood OpenBIOS",
-               .offset = RW_PART4_OF,
-               .size = RW_PART4_SZ,
-               .mask_flags = MTD_WRITEABLE     /* force read-only */
-       }
-};
-
-struct map_info redwood_flash_map = {
-       .name = "IBM Redwood",
-       .size = WINDOW_SIZE,
-       .bankwidth = 2,
-       .phys = WINDOW_ADDR,
-};
-
-
-#define NUM_REDWOOD_FLASH_PARTITIONS ARRAY_SIZE(redwood_flash_partitions)
-
-static struct mtd_info *redwood_mtd;
-
-static int __init init_redwood_flash(void)
-{
-       int err;
-
-       printk(KERN_NOTICE "redwood: flash mapping: %x at %x\n",
-                       WINDOW_SIZE, WINDOW_ADDR);
-
-       redwood_flash_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
-
-       if (!redwood_flash_map.virt) {
-               printk("init_redwood_flash: failed to ioremap\n");
-               return -EIO;
-       }
-       simple_map_init(&redwood_flash_map);
-
-       redwood_mtd = do_map_probe("cfi_probe",&redwood_flash_map);
-
-       if (redwood_mtd) {
-               redwood_mtd->owner = THIS_MODULE;
-               err = add_mtd_partitions(redwood_mtd,
-                               redwood_flash_partitions,
-                               NUM_REDWOOD_FLASH_PARTITIONS);
-               if (err) {
-                       printk("init_redwood_flash: add_mtd_partitions failed\n");
-                       iounmap(redwood_flash_map.virt);
-               }
-               return err;
-
-       }
-
-       iounmap(redwood_flash_map.virt);
-       return -ENXIO;
-}
-
-static void __exit cleanup_redwood_flash(void)
-{
-       if (redwood_mtd) {
-               del_mtd_partitions(redwood_mtd);
-               /* moved iounmap after map_destroy - armin */
-               map_destroy(redwood_mtd);
-               iounmap((void *)redwood_flash_map.virt);
-       }
-}
-
-module_init(init_redwood_flash);
-module_exit(cleanup_redwood_flash);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("MontaVista Software <source@mvista.com>");
-MODULE_DESCRIPTION("MTD map driver for the IBM Redwood reference boards");
index 03e19c1965cc031885e8a288ea092b10f3fea353..1d2144d77470160c0d58e349170766eeead7c729 100644 (file)
@@ -1,7 +1,21 @@
 /*
- * (C) 2003 David Woodhouse <dwmw2@infradead.org>
+ * Interface to Linux block layer for MTD 'translation layers'.
  *
- * Interface to Linux 2.5 block layer for MTD 'translation layers'.
+ * Copyright © 2003-2010 David Woodhouse <dwmw2@infradead.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  */
 
@@ -245,6 +259,7 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
        switch (cmd) {
        case BLKFLSBUF:
                ret = dev->tr->flush ? dev->tr->flush(dev) : 0;
+               break;
        default:
                ret = -ENOTTY;
        }
@@ -409,13 +424,14 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
                BUG();
        }
 
-       /* Stop new requests to arrive */
-       del_gendisk(old->disk);
-
        if (old->disk_attributes)
                sysfs_remove_group(&disk_to_dev(old->disk)->kobj,
                                                old->disk_attributes);
 
+       /* Stop new requests to arrive */
+       del_gendisk(old->disk);
+
+
        /* Stop the thread */
        kthread_stop(old->thread);
 
index e6edbec609fd61e68a5a53967aea4671e8ac2888..1e74ad961040ddc72a7855ee6bc13296873316f6 100644 (file)
@@ -1,8 +1,23 @@
 /*
  * Direct MTD block device access
  *
- * (C) 2000-2003 Nicolas Pitre <nico@fluxnic.net>
- * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
+ * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
+ * Copyright © 2000-2003 Nicolas Pitre <nico@fluxnic.net>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
  */
 
 #include <linux/fs.h>
index d0d3f79f9d03e7a94a38f8c6d8f2f96530876c99..795a8c0a05b82cf4a7cf0bc5d1e31bed4890b9e4 100644 (file)
@@ -1,7 +1,22 @@
 /*
- * (C) 2003 David Woodhouse <dwmw2@infradead.org>
- *
  * Simple read-only (writable only for RAM) mtdblock driver
+ *
+ * Copyright © 2001-2010 David Woodhouse <dwmw2@infradead.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
  */
 
 #include <linux/init.h>
index 91c8013cf0d9b8b818d8587ef036e1229e7c3396..a825002123c84bc0a24ce26e00400be277b09c22 100644 (file)
@@ -1,5 +1,19 @@
 /*
- * Character-device access to raw MTD devices.
+ * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  */
 
@@ -18,7 +32,7 @@
 #include <linux/mount.h>
 
 #include <linux/mtd/mtd.h>
-#include <linux/mtd/compatmac.h>
+#include <linux/mtd/map.h>
 
 #include <asm/uaccess.h>
 
@@ -675,6 +689,20 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
                break;
        }
 
+       case MEMISLOCKED:
+       {
+               struct erase_info_user einfo;
+
+               if (copy_from_user(&einfo, argp, sizeof(einfo)))
+                       return -EFAULT;
+
+               if (!mtd->is_locked)
+                       ret = -EOPNOTSUPP;
+               else
+                       ret = mtd->is_locked(mtd, einfo.start, einfo.length);
+               break;
+       }
+
        /* Legacy interface */
        case MEMGETOOBSEL:
        {
@@ -950,9 +978,34 @@ static int mtd_mmap(struct file *file, struct vm_area_struct *vma)
 #ifdef CONFIG_MMU
        struct mtd_file_info *mfi = file->private_data;
        struct mtd_info *mtd = mfi->mtd;
+       struct map_info *map = mtd->priv;
+       unsigned long start;
+       unsigned long off;
+       u32 len;
+
+       if (mtd->type == MTD_RAM || mtd->type == MTD_ROM) {
+               off = vma->vm_pgoff << PAGE_SHIFT;
+               start = map->phys;
+               len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size);
+               start &= PAGE_MASK;
+               if ((vma->vm_end - vma->vm_start + off) > len)
+                       return -EINVAL;
+
+               off += start;
+               vma->vm_pgoff = off >> PAGE_SHIFT;
+               vma->vm_flags |= VM_IO | VM_RESERVED;
+
+#ifdef pgprot_noncached
+               if (file->f_flags & O_DSYNC || off >= __pa(high_memory))
+                       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+#endif
+               if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+                                      vma->vm_end - vma->vm_start,
+                                      vma->vm_page_prot))
+                       return -EAGAIN;
 
-       if (mtd->type == MTD_RAM || mtd->type == MTD_ROM)
                return 0;
+       }
        return -ENOSYS;
 #else
        return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS;
index 7e075621bbf43fc62bbf42de4ae662dc9296bf8a..bf8de09431031d28d6874519d20a11fa7b1d557c 100644 (file)
@@ -1,11 +1,25 @@
 /*
  * MTD device concatenation layer
  *
- * (C) 2002 Robert Kaiser <rkaiser@sysgo.de>
+ * Copyright © 2002 Robert Kaiser <rkaiser@sysgo.de>
+ * Copyright © 2002-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * NAND support by Christian Gan <cgan@iders.ca>
  *
- * This code is GPL
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
  */
 
 #include <linux/kernel.h>
@@ -540,10 +554,12 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
                else
                        size = len;
 
-               err = subdev->lock(subdev, ofs, size);
-
-               if (err)
-                       break;
+               if (subdev->lock) {
+                       err = subdev->lock(subdev, ofs, size);
+                       if (err)
+                               break;
+               } else
+                       err = -EOPNOTSUPP;
 
                len -= size;
                if (len == 0)
@@ -578,10 +594,12 @@ static int concat_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
                else
                        size = len;
 
-               err = subdev->unlock(subdev, ofs, size);
-
-               if (err)
-                       break;
+               if (subdev->unlock) {
+                       err = subdev->unlock(subdev, ofs, size);
+                       if (err)
+                               break;
+               } else
+                       err = -EOPNOTSUPP;
 
                len -= size;
                if (len == 0)
index a1b8b70d2d0a04d2a6a12b02e48440bc97eac23e..527cebf58da46e9586dcaede286f8d6e662e42cf 100644 (file)
@@ -2,9 +2,23 @@
  * Core registration and callback routines for MTD
  * drivers and users.
  *
- * bdi bits are:
- * Copyright © 2006 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
+ * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
+ * Copyright © 2006      Red Hat UK Limited 
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
  */
 
 #include <linux/module.h>
@@ -17,7 +31,6 @@
 #include <linux/err.h>
 #include <linux/ioctl.h>
 #include <linux/init.h>
-#include <linux/mtd/compatmac.h>
 #include <linux/proc_fs.h>
 #include <linux/idr.h>
 #include <linux/backing-dev.h>
index 328313c3dccb4c4cf8b57e35ba5794e0ddff0ff4..1ee72f3f0512591d1ffd535f22aa2ac7dcb73941 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * MTD Oops/Panic logger
  *
- * Copyright (C) 2007 Nokia Corporation. All rights reserved.
+ * Copyright © 2007 Nokia Corporation. All rights reserved.
  *
  * Author: Richard Purdie <rpurdie@openedhand.com>
  *
index b8043a9ba32d43329080b3664a8ae8678f7c7693..dc65585688765c1f7e6e975b8c3c1fa8bc53429f 100644 (file)
@@ -1,12 +1,24 @@
 /*
  * Simple MTD partitioning layer
  *
- * (C) 2000 Nicolas Pitre <nico@fluxnic.net>
+ * Copyright © 2000 Nicolas Pitre <nico@fluxnic.net>
+ * Copyright © 2002 Thomas Gleixner <gleixner@linutronix.de>
+ * Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org>
  *
- * This code is GPL
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
- *     02-21-2002      Thomas Gleixner <gleixner@autronix.de>
- *                     added support for read_oob, write_oob
  */
 
 #include <linux/module.h>
@@ -17,7 +29,6 @@
 #include <linux/kmod.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
-#include <linux/mtd/compatmac.h>
 
 /* Our partition linked list */
 static LIST_HEAD(mtd_partitions);
@@ -264,6 +275,14 @@ static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
        return part->master->unlock(part->master, ofs + part->offset, len);
 }
 
+static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
+{
+       struct mtd_part *part = PART(mtd);
+       if ((len + ofs) > mtd->size)
+               return -EINVAL;
+       return part->master->is_locked(part->master, ofs + part->offset, len);
+}
+
 static void part_sync(struct mtd_info *mtd)
 {
        struct mtd_part *part = PART(mtd);
@@ -402,6 +421,8 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
                slave->mtd.lock = part_lock;
        if (master->unlock)
                slave->mtd.unlock = part_unlock;
+       if (master->is_locked)
+               slave->mtd.is_locked = part_is_locked;
        if (master->block_isbad)
                slave->mtd.block_isbad = part_block_isbad;
        if (master->block_markbad)
index bd9a443ccf69a508f8abc829be37c8a183e7cbe7..38e2ab07e7a3fc771f40d7a4448b52906d88c0d6 100644 (file)
@@ -1,6 +1,8 @@
 /* MTD-based superblock management
  *
  * Copyright © 2001-2007 Red Hat, Inc. All Rights Reserved.
+ * Copyright © 2001-2010 David Woodhouse <dwmw2@infradead.org>
+ *
  * Written by:  David Howells <dhowells@redhat.com>
  *              David Woodhouse <dwmw2@infradead.org>
  *
index 362d177efe1b4cb567be70bd980dad4db3bec980..8b4b67c8a391005bb530abc91ff61690546f2dfb 100644 (file)
@@ -37,7 +37,6 @@ config MTD_SM_COMMON
 
 config MTD_NAND_MUSEUM_IDS
        bool "Enable chip ids for obsolete ancient NAND devices"
-       depends on MTD_NAND
        default n
        help
          Enable this option only when your board has first generation
@@ -61,6 +60,7 @@ config MTD_NAND_DENALI
 config MTD_NAND_DENALI_SCRATCH_REG_ADDR
         hex "Denali NAND size scratch register address"
         default "0xFF108018"
+        depends on MTD_NAND_DENALI
         help
           Some platforms place the NAND chip size in a scratch register
           because (some versions of) the driver aren't able to automatically
@@ -101,13 +101,13 @@ config MTD_NAND_AMS_DELTA
 
 config MTD_NAND_OMAP2
        tristate "NAND Flash device on OMAP2 and OMAP3"
-       depends on ARM && MTD_NAND && (ARCH_OMAP2 || ARCH_OMAP3)
+       depends on ARM && (ARCH_OMAP2 || ARCH_OMAP3)
        help
           Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms.
 
 config MTD_NAND_OMAP_PREFETCH
        bool "GPMC prefetch support for NAND Flash device"
-       depends on MTD_NAND && MTD_NAND_OMAP2
+       depends on MTD_NAND_OMAP2
        default y
        help
         The NAND device can be accessed for Read/Write using GPMC PREFETCH engine
@@ -146,7 +146,7 @@ config MTD_NAND_AU1550
 
 config MTD_NAND_BF5XX
        tristate "Blackfin on-chip NAND Flash Controller driver"
-       depends on (BF54x || BF52x) && MTD_NAND
+       depends on BF54x || BF52x
        help
          This enables the Blackfin on-chip NAND flash controller
 
@@ -236,7 +236,7 @@ config MTD_NAND_S3C2410_CLKSTOP
 
 config MTD_NAND_BCM_UMI
        tristate "NAND Flash support for BCM Reference Boards"
-       depends on ARCH_BCMRING && MTD_NAND
+       depends on ARCH_BCMRING
        help
          This enables the NAND flash controller on the BCM UMI block.
 
@@ -395,7 +395,7 @@ endchoice
 
 config MTD_NAND_PXA3xx
        tristate "Support for NAND flash devices on PXA3xx"
-       depends on MTD_NAND && (PXA3xx || ARCH_MMP)
+       depends on PXA3xx || ARCH_MMP
        help
          This enables the driver for the NAND flash device found on
          PXA3xx processors
@@ -409,18 +409,18 @@ config MTD_NAND_PXA3xx_BUILTIN
 
 config MTD_NAND_CM_X270
        tristate "Support for NAND Flash on CM-X270 modules"
-       depends on MTD_NAND && MACH_ARMCORE
+       depends on MACH_ARMCORE
 
 config MTD_NAND_PASEMI
        tristate "NAND support for PA Semi PWRficient"
-       depends on MTD_NAND && PPC_PASEMI
+       depends on PPC_PASEMI
        help
          Enables support for NAND Flash interface on PA Semi PWRficient
          based boards
 
 config MTD_NAND_TMIO
        tristate "NAND Flash device on Toshiba Mobile IO Controller"
-       depends on MTD_NAND && MFD_TMIO
+       depends on MFD_TMIO
        help
          Support for NAND flash connected to a Toshiba Mobile IO
          Controller in some PDAs, including the Sharp SL6000x.
@@ -434,7 +434,6 @@ config MTD_NAND_NANDSIM
 
 config MTD_NAND_PLATFORM
        tristate "Support for generic platform NAND driver"
-       depends on MTD_NAND
        help
          This implements a generic NAND driver for on-SOC platform
          devices. You will need to provide platform-specific functions
@@ -442,14 +441,14 @@ config MTD_NAND_PLATFORM
 
 config MTD_ALAUDA
        tristate "MTD driver for Olympus MAUSB-10 and Fujifilm DPC-R1"
-       depends on MTD_NAND && USB
+       depends on USB
        help
          These two (and possibly other) Alauda-based cardreaders for
          SmartMedia and xD allow raw flash access.
 
 config MTD_NAND_ORION
        tristate "NAND Flash support for Marvell Orion SoC"
-       depends on PLAT_ORION && MTD_NAND
+       depends on PLAT_ORION
        help
          This enables the NAND flash controller on Orion machines.
 
@@ -458,7 +457,7 @@ config MTD_NAND_ORION
 
 config MTD_NAND_FSL_ELBC
        tristate "NAND support for Freescale eLBC controllers"
-       depends on MTD_NAND && PPC_OF
+       depends on PPC_OF
        help
          Various Freescale chips, including the 8313, include a NAND Flash
          Controller Module with built-in hardware ECC capabilities.
@@ -467,7 +466,7 @@ config MTD_NAND_FSL_ELBC
 
 config MTD_NAND_FSL_UPM
        tristate "Support for NAND on Freescale UPM"
-       depends on MTD_NAND && (PPC_83xx || PPC_85xx)
+       depends on PPC_83xx || PPC_85xx
        select FSL_LBC
        help
          Enables support for NAND Flash chips wired onto Freescale PowerPC
@@ -482,7 +481,7 @@ config MTD_NAND_MPC5121_NFC
 
 config MTD_NAND_MXC
        tristate "MXC NAND support"
-       depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3
+       depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3 || ARCH_MX51
        help
          This enables the driver for the NAND flash controller on the
          MXC processors.
@@ -495,7 +494,7 @@ config MTD_NAND_NOMADIK
 
 config MTD_NAND_SH_FLCTL
        tristate "Support for NAND on Renesas SuperH FLCTL"
-       depends on MTD_NAND && (SUPERH || ARCH_SHMOBILE)
+       depends on SUPERH || ARCH_SHMOBILE
        help
          Several Renesas SuperH CPU has FLCTL. This option enables support
          for NAND Flash using FLCTL.
@@ -515,7 +514,7 @@ config MTD_NAND_TXX9NDFMC
 
 config MTD_NAND_SOCRATES
        tristate "Support for NAND on Socrates board"
-       depends on MTD_NAND && SOCRATES
+       depends on SOCRATES
        help
          Enables support for NAND Flash chips wired onto Socrates board.
 
index 04d30887ca7f17580ae0fe9144fb1c7fe676c9c5..ccce0f03b5dcf50b300f621e36200d76e0e273c3 100644 (file)
@@ -364,7 +364,7 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
        }
 }
 
-#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
 static const char *part_probes[] = { "cmdlinepart", NULL };
 #endif
 
index 2974995e194d1589a6c697065a08dc6602504d7e..a382e3dd0a5dc8cdcddc2fc5f0b993c3badadd33 100644 (file)
@@ -20,9 +20,6 @@
  *             - DMA supported in ECC_HW
  *             - YAFFS tested as rootfs in both ECC_HW and ECC_SW
  *
- * TODO:
- *     Enable JFFS2 over NAND as rootfs
- *
  * 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
@@ -206,7 +203,7 @@ static void bf5xx_nand_hwcontrol(struct mtd_info *mtd, int cmd,
 
        if (ctrl & NAND_CLE)
                bfin_write_NFC_CMD(cmd);
-       else
+       else if (ctrl & NAND_ALE)
                bfin_write_NFC_ADDR(cmd);
        SSYNC();
 }
@@ -218,9 +215,9 @@ static void bf5xx_nand_hwcontrol(struct mtd_info *mtd, int cmd,
  */
 static int bf5xx_nand_devready(struct mtd_info *mtd)
 {
-       unsigned short val = bfin_read_NFC_IRQSTAT();
+       unsigned short val = bfin_read_NFC_STAT();
 
-       if ((val & NBUSYIRQ) == NBUSYIRQ)
+       if ((val & NBUSY) == NBUSY)
                return 1;
        else
                return 0;
@@ -317,18 +314,16 @@ static int bf5xx_nand_correct_data_256(struct mtd_info *mtd, u_char *dat,
 static int bf5xx_nand_correct_data(struct mtd_info *mtd, u_char *dat,
                                        u_char *read_ecc, u_char *calc_ecc)
 {
-       struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
-       struct bf5xx_nand_platform *plat = info->platform;
-       unsigned short page_size = (plat->page_size ? 512 : 256);
+       struct nand_chip *chip = mtd->priv;
        int ret;
 
        ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc);
 
-       /* If page size is 512, correct second 256 bytes */
-       if (page_size == 512) {
+       /* If ecc size is 512, correct second 256 bytes */
+       if (chip->ecc.size == 512) {
                dat += 256;
-               read_ecc += 8;
-               calc_ecc += 8;
+               read_ecc += 3;
+               calc_ecc += 3;
                ret |= bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc);
        }
 
@@ -344,13 +339,12 @@ static int bf5xx_nand_calculate_ecc(struct mtd_info *mtd,
                const u_char *dat, u_char *ecc_code)
 {
        struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
-       struct bf5xx_nand_platform *plat = info->platform;
-       u16 page_size = (plat->page_size ? 512 : 256);
+       struct nand_chip *chip = mtd->priv;
        u16 ecc0, ecc1;
        u32 code[2];
        u8 *p;
 
-       /* first 4 bytes ECC code for 256 page size */
+       /* first 3 bytes ECC code for 256 page size */
        ecc0 = bfin_read_NFC_ECC0();
        ecc1 = bfin_read_NFC_ECC1();
 
@@ -358,12 +352,11 @@ static int bf5xx_nand_calculate_ecc(struct mtd_info *mtd,
 
        dev_dbg(info->device, "returning ecc 0x%08x\n", code[0]);
 
-       /* first 3 bytes in ecc_code for 256 page size */
        p = (u8 *) code;
        memcpy(ecc_code, p, 3);
 
-       /* second 4 bytes ECC code for 512 page size */
-       if (page_size == 512) {
+       /* second 3 bytes ECC code for 512 ecc size */
+       if (chip->ecc.size == 512) {
                ecc0 = bfin_read_NFC_ECC2();
                ecc1 = bfin_read_NFC_ECC3();
                code[1] = (ecc0 & 0x7ff) | ((ecc1 & 0x7ff) << 11);
@@ -483,8 +476,7 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd,
                                uint8_t *buf, int is_read)
 {
        struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
-       struct bf5xx_nand_platform *plat = info->platform;
-       unsigned short page_size = (plat->page_size ? 512 : 256);
+       struct nand_chip *chip = mtd->priv;
        unsigned short val;
 
        dev_dbg(info->device, " mtd->%p, buf->%p, is_read %d\n",
@@ -498,10 +490,10 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd,
         */
        if (is_read)
                invalidate_dcache_range((unsigned int)buf,
-                               (unsigned int)(buf + page_size));
+                               (unsigned int)(buf + chip->ecc.size));
        else
                flush_dcache_range((unsigned int)buf,
-                               (unsigned int)(buf + page_size));
+                               (unsigned int)(buf + chip->ecc.size));
 
        /*
         * This register must be written before each page is
@@ -510,6 +502,8 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd,
         */
        bfin_write_NFC_RST(ECC_RST);
        SSYNC();
+       while (bfin_read_NFC_RST() & ECC_RST)
+               cpu_relax();
 
        disable_dma(CH_NFC);
        clear_dma_irqstat(CH_NFC);
@@ -520,13 +514,13 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd,
 
        /* The DMAs have different size on BF52x and BF54x */
 #ifdef CONFIG_BF52x
-       set_dma_x_count(CH_NFC, (page_size >> 1));
+       set_dma_x_count(CH_NFC, (chip->ecc.size >> 1));
        set_dma_x_modify(CH_NFC, 2);
        val = DI_EN | WDSIZE_16;
 #endif
 
 #ifdef CONFIG_BF54x
-       set_dma_x_count(CH_NFC, (page_size >> 2));
+       set_dma_x_count(CH_NFC, (chip->ecc.size >> 2));
        set_dma_x_modify(CH_NFC, 4);
        val = DI_EN | WDSIZE_32;
 #endif
@@ -548,12 +542,11 @@ static void bf5xx_nand_dma_read_buf(struct mtd_info *mtd,
                                        uint8_t *buf, int len)
 {
        struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
-       struct bf5xx_nand_platform *plat = info->platform;
-       unsigned short page_size = (plat->page_size ? 512 : 256);
+       struct nand_chip *chip = mtd->priv;
 
        dev_dbg(info->device, "mtd->%p, buf->%p, int %d\n", mtd, buf, len);
 
-       if (len == page_size)
+       if (len == chip->ecc.size)
                bf5xx_nand_dma_rw(mtd, buf, 1);
        else
                bf5xx_nand_read_buf(mtd, buf, len);
@@ -563,17 +556,32 @@ static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd,
                                const uint8_t *buf, int len)
 {
        struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
-       struct bf5xx_nand_platform *plat = info->platform;
-       unsigned short page_size = (plat->page_size ? 512 : 256);
+       struct nand_chip *chip = mtd->priv;
 
        dev_dbg(info->device, "mtd->%p, buf->%p, len %d\n", mtd, buf, len);
 
-       if (len == page_size)
+       if (len == chip->ecc.size)
                bf5xx_nand_dma_rw(mtd, (uint8_t *)buf, 0);
        else
                bf5xx_nand_write_buf(mtd, buf, len);
 }
 
+static int bf5xx_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+               uint8_t *buf, int page)
+{
+       bf5xx_nand_read_buf(mtd, buf, mtd->writesize);
+       bf5xx_nand_read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+       return 0;
+}
+
+static void bf5xx_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+               const uint8_t *buf)
+{
+       bf5xx_nand_write_buf(mtd, buf, mtd->writesize);
+       bf5xx_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize);
+}
+
 /*
  * System initialization functions
  */
@@ -627,15 +635,14 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info)
 
        /* setup NFC_CTL register */
        dev_info(info->device,
-               "page_size=%d, data_width=%d, wr_dly=%d, rd_dly=%d\n",
-               (plat->page_size ? 512 : 256),
+               "data_width=%d, wr_dly=%d, rd_dly=%d\n",
                (plat->data_width ? 16 : 8),
                plat->wr_dly, plat->rd_dly);
 
-       val = (plat->page_size << NFC_PG_SIZE_OFFSET) |
+       val = (1 << NFC_PG_SIZE_OFFSET) |
                (plat->data_width << NFC_NWIDTH_OFFSET) |
                (plat->rd_dly << NFC_RDDLY_OFFSET) |
-               (plat->rd_dly << NFC_WRDLY_OFFSET);
+               (plat->wr_dly << NFC_WRDLY_OFFSET);
        dev_dbg(info->device, "NFC_CTL is 0x%04x\n", val);
 
        bfin_write_NFC_CTL(val);
@@ -698,6 +705,33 @@ static int __devexit bf5xx_nand_remove(struct platform_device *pdev)
        return 0;
 }
 
+static int bf5xx_nand_scan(struct mtd_info *mtd)
+{
+       struct nand_chip *chip = mtd->priv;
+       int ret;
+
+       ret = nand_scan_ident(mtd, 1);
+       if (ret)
+               return ret;
+
+       if (hardware_ecc) {
+               /*
+                * for nand with page size > 512B, think it as several sections with 512B
+                */
+               if (likely(mtd->writesize >= 512)) {
+                       chip->ecc.size = 512;
+                       chip->ecc.bytes = 6;
+               } else {
+                       chip->ecc.size = 256;
+                       chip->ecc.bytes = 3;
+                       bfin_write_NFC_CTL(bfin_read_NFC_CTL() & ~(1 << NFC_PG_SIZE_OFFSET));
+                       SSYNC();
+               }
+       }
+
+       return  nand_scan_tail(mtd);
+}
+
 /*
  * bf5xx_nand_probe
  *
@@ -783,27 +817,20 @@ static int __devinit bf5xx_nand_probe(struct platform_device *pdev)
                chip->badblock_pattern = &bootrom_bbt;
                chip->ecc.layout = &bootrom_ecclayout;
 #endif
-
-               if (plat->page_size == NFC_PG_SIZE_256) {
-                       chip->ecc.bytes = 3;
-                       chip->ecc.size = 256;
-               } else if (plat->page_size == NFC_PG_SIZE_512) {
-                       chip->ecc.bytes = 6;
-                       chip->ecc.size = 512;
-               }
-
                chip->read_buf      = bf5xx_nand_dma_read_buf;
                chip->write_buf     = bf5xx_nand_dma_write_buf;
                chip->ecc.calculate = bf5xx_nand_calculate_ecc;
                chip->ecc.correct   = bf5xx_nand_correct_data;
                chip->ecc.mode      = NAND_ECC_HW;
                chip->ecc.hwctl     = bf5xx_nand_enable_hwecc;
+               chip->ecc.read_page_raw = bf5xx_nand_read_page_raw;
+               chip->ecc.write_page_raw = bf5xx_nand_write_page_raw;
        } else {
                chip->ecc.mode      = NAND_ECC_SOFT;
        }
 
        /* scan hardware nand chip and setup mtd info data struct */
-       if (nand_scan(mtd, 1)) {
+       if (bf5xx_nand_scan(mtd)) {
                err = -ENXIO;
                goto out_err_nand_scan;
        }
index 9c9d893affeb45da9712605892cda59cb8d871fa..2ac7367afe77c26c2a209469218c928db3f6140c 100644 (file)
@@ -311,7 +311,9 @@ static int nand_davinci_correct_4bit(struct mtd_info *mtd,
        unsigned short ecc10[8];
        unsigned short *ecc16;
        u32 syndrome[4];
+       u32 ecc_state;
        unsigned num_errors, corrected;
+       unsigned long timeo = jiffies + msecs_to_jiffies(100);
 
        /* All bytes 0xff?  It's an erased page; ignore its ECC. */
        for (i = 0; i < 10; i++) {
@@ -361,6 +363,21 @@ compare:
         */
        davinci_nand_writel(info, NANDFCR_OFFSET,
                        davinci_nand_readl(info, NANDFCR_OFFSET) | BIT(13));
+
+       /*
+        * ECC_STATE field reads 0x3 (Error correction complete) immediately
+        * after setting the 4BITECC_ADD_CALC_START bit. So if you immediately
+        * begin trying to poll for the state, you may fall right out of your
+        * loop without any of the correction calculations having taken place.
+        * The recommendation from the hardware team is to wait till ECC_STATE
+        * reads less than 4, which means ECC HW has entered correction state.
+        */
+       do {
+               ecc_state = (davinci_nand_readl(info,
+                               NANDFSR_OFFSET) >> 8) & 0x0f;
+               cpu_relax();
+       } while ((ecc_state < 4) && time_before(jiffies, timeo));
+
        for (;;) {
                u32     fsr = davinci_nand_readl(info, NANDFSR_OFFSET);
 
index 3dfda9cc677d1f7de97edc2983d4d48283b293c2..618fb42b86b02f71179ebbd71ae3807b730a4f82 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/delay.h>
 #include <linux/wait.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/mtd/mtd.h>
 #include <linux/module.h>
 
 MODULE_LICENSE("GPL");
 
-/* We define a module parameter that allows the user to override 
+/* We define a module parameter that allows the user to override
  * the hardware and decide what timing mode should be used.
  */
 #define NAND_DEFAULT_TIMINGS   -1
 
 static int onfi_timing_mode = NAND_DEFAULT_TIMINGS;
 module_param(onfi_timing_mode, int, S_IRUGO);
-MODULE_PARM_DESC(onfi_timing_mode, "Overrides default ONFI setting. -1 indicates"
-                                       " use default timings");
+MODULE_PARM_DESC(onfi_timing_mode, "Overrides default ONFI setting."
+                       " -1 indicates use default timings");
 
 #define DENALI_NAND_NAME    "denali-nand"
 
@@ -54,13 +55,13 @@ MODULE_PARM_DESC(onfi_timing_mode, "Overrides default ONFI setting. -1 indicates
                        INTR_STATUS0__RST_COMP | \
                        INTR_STATUS0__ERASE_COMP)
 
-/* indicates whether or not the internal value for the flash bank is 
+/* indicates whether or not the internal value for the flash bank is
    valid or not */
-#define CHIP_SELECT_INVALID    -1
+#define CHIP_SELECT_INVALID    -1
 
 #define SUPPORT_8BITECC                1
 
-/* This macro divides two integers and rounds fractional values up 
+/* This macro divides two integers and rounds fractional values up
  * to the nearest integer value. */
 #define CEIL_DIV(X, Y) (((X)%(Y)) ? ((X)/(Y)+1) : ((X)/(Y)))
 
@@ -83,7 +84,7 @@ MODULE_PARM_DESC(onfi_timing_mode, "Overrides default ONFI setting. -1 indicates
 #define ADDR_CYCLE     1
 #define STATUS_CYCLE   2
 
-/* this is a helper macro that allows us to 
+/* this is a helper macro that allows us to
  * format the bank into the proper bits for the controller */
 #define BANK(x) ((x) << 24)
 
@@ -95,59 +96,64 @@ static const struct pci_device_id denali_pci_ids[] = {
 };
 
 
-/* these are static lookup tables that give us easy access to 
-   registers in the NAND controller.  
+/* these are static lookup tables that give us easy access to
+   registers in the NAND controller.
  */
-static const uint32_t intr_status_addresses[4] = {INTR_STATUS0, 
-                                                 INTR_STATUS1, 
-                                                 INTR_STATUS2, 
+static const uint32_t intr_status_addresses[4] = {INTR_STATUS0,
+                                                 INTR_STATUS1,
+                                                 INTR_STATUS2,
                                                  INTR_STATUS3};
 
 static const uint32_t device_reset_banks[4] = {DEVICE_RESET__BANK0,
-                                               DEVICE_RESET__BANK1,
-                                               DEVICE_RESET__BANK2,
-                                               DEVICE_RESET__BANK3};
+                                                       DEVICE_RESET__BANK1,
+                                                       DEVICE_RESET__BANK2,
+                                                       DEVICE_RESET__BANK3};
 
 static const uint32_t operation_timeout[4] = {INTR_STATUS0__TIME_OUT,
-                                             INTR_STATUS1__TIME_OUT,
-                                             INTR_STATUS2__TIME_OUT,
-                                             INTR_STATUS3__TIME_OUT};
+                                                       INTR_STATUS1__TIME_OUT,
+                                                       INTR_STATUS2__TIME_OUT,
+                                                       INTR_STATUS3__TIME_OUT};
 
 static const uint32_t reset_complete[4] = {INTR_STATUS0__RST_COMP,
-                                          INTR_STATUS1__RST_COMP,
-                                          INTR_STATUS2__RST_COMP,
-                                          INTR_STATUS3__RST_COMP};
+                                                       INTR_STATUS1__RST_COMP,
+                                                       INTR_STATUS2__RST_COMP,
+                                                       INTR_STATUS3__RST_COMP};
 
 /* specifies the debug level of the driver */
-static int nand_debug_level = 0;
+static int nand_debug_level;
 
 /* forward declarations */
 static void clear_interrupts(struct denali_nand_info *denali);
-static uint32_t wait_for_irq(struct denali_nand_info *denali, uint32_t irq_mask);
-static void denali_irq_enable(struct denali_nand_info *denali, uint32_t int_mask);
+static uint32_t wait_for_irq(struct denali_nand_info *denali,
+                                                       uint32_t irq_mask);
+static void denali_irq_enable(struct denali_nand_info *denali,
+                                                       uint32_t int_mask);
 static uint32_t read_interrupt_status(struct denali_nand_info *denali);
 
 #define DEBUG_DENALI 0
 
 /* This is a wrapper for writing to the denali registers.
  * this allows us to create debug information so we can
- * observe how the driver is programming the device. 
+ * observe how the driver is programming the device.
  * it uses standard linux convention for (val, addr) */
 static void denali_write32(uint32_t value, void *addr)
 {
-       iowrite32(value, addr); 
+       iowrite32(value, addr);
 
 #if DEBUG_DENALI
-       printk(KERN_ERR "wrote: 0x%x -> 0x%x\n", value, (uint32_t)((uint32_t)addr & 0x1fff));
+       printk(KERN_INFO "wrote: 0x%x -> 0x%x\n", value,
+                       (uint32_t)((uint32_t)addr & 0x1fff));
 #endif
-} 
+}
 
-/* Certain operations for the denali NAND controller use an indexed mode to read/write 
-   data. The operation is performed by writing the address value of the command to 
-   the device memory followed by the data. This function abstracts this common 
-   operation. 
+/* Certain operations for the denali NAND controller use
+ * an indexed mode to read/write data. The operation is
+ * performed by writing the address value of the command
+ * to the device memory followed by the data. This function
+ * abstracts this common operation.
 */
-static void index_addr(struct denali_nand_info *denali, uint32_t address, uint32_t data)
+static void index_addr(struct denali_nand_info *denali,
+                               uint32_t address, uint32_t data)
 {
        denali_write32(address, denali->flash_mem);
        denali_write32(data, denali->flash_mem + 0x10);
@@ -161,7 +167,7 @@ static void index_addr_read_data(struct denali_nand_info *denali,
        *pdata = ioread32(denali->flash_mem + 0x10);
 }
 
-/* We need to buffer some data for some of the NAND core routines. 
+/* We need to buffer some data for some of the NAND core routines.
  * The operations manage buffering that data. */
 static void reset_buf(struct denali_nand_info *denali)
 {
@@ -183,7 +189,7 @@ static void read_status(struct denali_nand_info *denali)
        reset_buf(denali);
 
        /* initiate a device status read */
-       cmd = MODE_11 | BANK(denali->flash_bank); 
+       cmd = MODE_11 | BANK(denali->flash_bank);
        index_addr(denali, cmd | COMMAND_CYCLE, 0x70);
        denali_write32(cmd | STATUS_CYCLE, denali->flash_mem);
 
@@ -191,7 +197,8 @@ static void read_status(struct denali_nand_info *denali)
        write_byte_to_buf(denali, ioread32(denali->flash_mem + 0x10));
 
 #if DEBUG_DENALI
-       printk("device reporting status value of 0x%2x\n", denali->buf.buf[0]);
+       printk(KERN_INFO "device reporting status value of 0x%2x\n",
+                       denali->buf.buf[0]);
 #endif
 }
 
@@ -199,7 +206,7 @@ static void read_status(struct denali_nand_info *denali)
 static void reset_bank(struct denali_nand_info *denali)
 {
        uint32_t irq_status = 0;
-       uint32_t irq_mask = reset_complete[denali->flash_bank] | 
+       uint32_t irq_mask = reset_complete[denali->flash_bank] |
                            operation_timeout[denali->flash_bank];
        int bank = 0;
 
@@ -209,15 +216,13 @@ static void reset_bank(struct denali_nand_info *denali)
        denali_write32(bank, denali->flash_reg + DEVICE_RESET);
 
        irq_status = wait_for_irq(denali, irq_mask);
-       
+
        if (irq_status & operation_timeout[denali->flash_bank])
-       {
                printk(KERN_ERR "reset bank failed.\n");
-       }
 }
 
 /* Reset the flash controller */
-static uint16_t NAND_Flash_Reset(struct denali_nand_info *denali)
+static uint16_t denali_nand_reset(struct denali_nand_info *denali)
 {
        uint32_t i;
 
@@ -229,8 +234,10 @@ static uint16_t NAND_Flash_Reset(struct denali_nand_info *denali)
                denali->flash_reg + intr_status_addresses[i]);
 
        for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++) {
-               denali_write32(device_reset_banks[i], denali->flash_reg + DEVICE_RESET);
-               while (!(ioread32(denali->flash_reg + intr_status_addresses[i]) &
+               denali_write32(device_reset_banks[i],
+                               denali->flash_reg + DEVICE_RESET);
+               while (!(ioread32(denali->flash_reg +
+                                               intr_status_addresses[i]) &
                        (reset_complete[i] | operation_timeout[i])))
                        ;
                if (ioread32(denali->flash_reg + intr_status_addresses[i]) &
@@ -246,11 +253,12 @@ static uint16_t NAND_Flash_Reset(struct denali_nand_info *denali)
        return PASS;
 }
 
-/* this routine calculates the ONFI timing values for a given mode and programs
- * the clocking register accordingly. The mode is determined by the get_onfi_nand_para
  routine.
+/* this routine calculates the ONFI timing values for a given mode and
+ * programs the clocking register accordingly. The mode is determined by
* the get_onfi_nand_para routine.
  */
-static void NAND_ONFi_Timing_Mode(struct denali_nand_info *denali, uint16_t mode)
+static void nand_onfi_timing_set(struct denali_nand_info *denali,
+                                                               uint16_t mode)
 {
        uint16_t Trea[6] = {40, 30, 25, 20, 20, 16};
        uint16_t Trp[6] = {50, 25, 17, 15, 12, 10};
@@ -347,136 +355,24 @@ static void NAND_ONFi_Timing_Mode(struct denali_nand_info *denali, uint16_t mode
        denali_write32(cs_cnt, denali->flash_reg + CS_SETUP_CNT);
 }
 
-/* configures the initial ECC settings for the controller */
-static void set_ecc_config(struct denali_nand_info *denali)
-{
-#if SUPPORT_8BITECC
-       if ((ioread32(denali->flash_reg + DEVICE_MAIN_AREA_SIZE) < 4096) ||
-               (ioread32(denali->flash_reg + DEVICE_SPARE_AREA_SIZE) <= 128))
-               denali_write32(8, denali->flash_reg + ECC_CORRECTION);
-#endif
-
-       if ((ioread32(denali->flash_reg + ECC_CORRECTION) & ECC_CORRECTION__VALUE)
-               == 1) {
-               denali->dev_info.wECCBytesPerSector = 4;
-               denali->dev_info.wECCBytesPerSector *= denali->dev_info.wDevicesConnected;
-               denali->dev_info.wNumPageSpareFlag =
-                       denali->dev_info.wPageSpareSize -
-                       denali->dev_info.wPageDataSize /
-                       (ECC_SECTOR_SIZE * denali->dev_info.wDevicesConnected) *
-                       denali->dev_info.wECCBytesPerSector
-                       - denali->dev_info.wSpareSkipBytes;
-       } else {
-               denali->dev_info.wECCBytesPerSector =
-                       (ioread32(denali->flash_reg + ECC_CORRECTION) &
-                       ECC_CORRECTION__VALUE) * 13 / 8;
-               if ((denali->dev_info.wECCBytesPerSector) % 2 == 0)
-                       denali->dev_info.wECCBytesPerSector += 2;
-               else
-                       denali->dev_info.wECCBytesPerSector += 1;
-
-               denali->dev_info.wECCBytesPerSector *= denali->dev_info.wDevicesConnected;
-               denali->dev_info.wNumPageSpareFlag = denali->dev_info.wPageSpareSize -
-                       denali->dev_info.wPageDataSize /
-                       (ECC_SECTOR_SIZE * denali->dev_info.wDevicesConnected) *
-                       denali->dev_info.wECCBytesPerSector
-                       - denali->dev_info.wSpareSkipBytes;
-       }
-}
-
 /* queries the NAND device to see what ONFI modes it supports. */
 static uint16_t get_onfi_nand_para(struct denali_nand_info *denali)
 {
        int i;
-       uint16_t blks_lun_l, blks_lun_h, n_of_luns;
-       uint32_t blockperlun, id;
-
-       denali_write32(DEVICE_RESET__BANK0, denali->flash_reg + DEVICE_RESET);
-
-       while (!((ioread32(denali->flash_reg + INTR_STATUS0) &
-               INTR_STATUS0__RST_COMP) |
-               (ioread32(denali->flash_reg + INTR_STATUS0) &
-               INTR_STATUS0__TIME_OUT)))
-               ;
-
-       if (ioread32(denali->flash_reg + INTR_STATUS0) & INTR_STATUS0__RST_COMP) {
-               denali_write32(DEVICE_RESET__BANK1, denali->flash_reg + DEVICE_RESET);
-               while (!((ioread32(denali->flash_reg + INTR_STATUS1) &
-                       INTR_STATUS1__RST_COMP) |
-                       (ioread32(denali->flash_reg + INTR_STATUS1) &
-                       INTR_STATUS1__TIME_OUT)))
-                       ;
-
-               if (ioread32(denali->flash_reg + INTR_STATUS1) &
-                       INTR_STATUS1__RST_COMP) {
-                       denali_write32(DEVICE_RESET__BANK2,
-                               denali->flash_reg + DEVICE_RESET);
-                       while (!((ioread32(denali->flash_reg + INTR_STATUS2) &
-                               INTR_STATUS2__RST_COMP) |
-                               (ioread32(denali->flash_reg + INTR_STATUS2) &
-                               INTR_STATUS2__TIME_OUT)))
-                               ;
-
-                       if (ioread32(denali->flash_reg + INTR_STATUS2) &
-                               INTR_STATUS2__RST_COMP) {
-                               denali_write32(DEVICE_RESET__BANK3,
-                                       denali->flash_reg + DEVICE_RESET);
-                               while (!((ioread32(denali->flash_reg + INTR_STATUS3) &
-                                       INTR_STATUS3__RST_COMP) |
-                                       (ioread32(denali->flash_reg + INTR_STATUS3) &
-                                       INTR_STATUS3__TIME_OUT)))
-                                       ;
-                       } else {
-                               printk(KERN_ERR "Getting a time out for bank 2!\n");
-                       }
-               } else {
-                       printk(KERN_ERR "Getting a time out for bank 1!\n");
-               }
-       }
-
-       denali_write32(INTR_STATUS0__TIME_OUT, denali->flash_reg + INTR_STATUS0);
-       denali_write32(INTR_STATUS1__TIME_OUT, denali->flash_reg + INTR_STATUS1);
-       denali_write32(INTR_STATUS2__TIME_OUT, denali->flash_reg + INTR_STATUS2);
-       denali_write32(INTR_STATUS3__TIME_OUT, denali->flash_reg + INTR_STATUS3);
-
-       denali->dev_info.wONFIDevFeatures =
-               ioread32(denali->flash_reg + ONFI_DEVICE_FEATURES);
-       denali->dev_info.wONFIOptCommands =
-               ioread32(denali->flash_reg + ONFI_OPTIONAL_COMMANDS);
-       denali->dev_info.wONFITimingMode =
-               ioread32(denali->flash_reg + ONFI_TIMING_MODE);
-       denali->dev_info.wONFIPgmCacheTimingMode =
-               ioread32(denali->flash_reg + ONFI_PGM_CACHE_TIMING_MODE);
-
-       n_of_luns = ioread32(denali->flash_reg + ONFI_DEVICE_NO_OF_LUNS) &
-               ONFI_DEVICE_NO_OF_LUNS__NO_OF_LUNS;
-       blks_lun_l = ioread32(denali->flash_reg + ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_L);
-       blks_lun_h = ioread32(denali->flash_reg + ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_U);
-
-       blockperlun = (blks_lun_h << 16) | blks_lun_l;
-
-       denali->dev_info.wTotalBlocks = n_of_luns * blockperlun;
-
+       /* we needn't to do a reset here because driver has already
+        * reset all the banks before
+        * */
        if (!(ioread32(denali->flash_reg + ONFI_TIMING_MODE) &
                ONFI_TIMING_MODE__VALUE))
                return FAIL;
 
        for (i = 5; i > 0; i--) {
-               if (ioread32(denali->flash_reg + ONFI_TIMING_MODE) & (0x01 << i))
+               if (ioread32(denali->flash_reg + ONFI_TIMING_MODE) &
+                       (0x01 << i))
                        break;
        }
 
-       NAND_ONFi_Timing_Mode(denali, i);
-
-       index_addr(denali, MODE_11 | 0, 0x90);
-       index_addr(denali, MODE_11 | 1, 0);
-
-       for (i = 0; i < 3; i++)
-               index_addr_read_data(denali, MODE_11 | 2, &id);
-
-       nand_dbg_print(NAND_DBG_DEBUG, "3rd ID: 0x%x\n", id);
-
-       denali->dev_info.MLCDevice = id & 0x0C;
+       nand_onfi_timing_set(denali, i);
 
        /* By now, all the ONFI devices we know support the page cache */
        /* rw feature. So here we enable the pipeline_rw_ahead feature */
@@ -486,25 +382,10 @@ static uint16_t get_onfi_nand_para(struct denali_nand_info *denali)
        return PASS;
 }
 
-static void get_samsung_nand_para(struct denali_nand_info *denali)
+static void get_samsung_nand_para(struct denali_nand_info *denali,
+                                                       uint8_t device_id)
 {
-       uint8_t no_of_planes;
-       uint32_t blk_size;
-       uint64_t plane_size, capacity;
-       uint32_t id_bytes[5];
-       int i;
-
-       index_addr(denali, (uint32_t)(MODE_11 | 0), 0x90);
-       index_addr(denali, (uint32_t)(MODE_11 | 1), 0);
-       for (i = 0; i < 5; i++)
-               index_addr_read_data(denali, (uint32_t)(MODE_11 | 2), &id_bytes[i]);
-
-       nand_dbg_print(NAND_DBG_DEBUG,
-               "ID bytes: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
-               id_bytes[0], id_bytes[1], id_bytes[2],
-               id_bytes[3], id_bytes[4]);
-
-       if ((id_bytes[1] & 0xff) == 0xd3) { /* Samsung K9WAG08U1A */
+       if (device_id == 0xd3) { /* Samsung K9WAG08U1A */
                /* Set timing register values according to datasheet */
                denali_write32(5, denali->flash_reg + ACC_CLKS);
                denali_write32(20, denali->flash_reg + RE_2_WE);
@@ -514,19 +395,10 @@ static void get_samsung_nand_para(struct denali_nand_info *denali)
                denali_write32(2, denali->flash_reg + RDWR_EN_HI_CNT);
                denali_write32(2, denali->flash_reg + CS_SETUP_CNT);
        }
-
-       no_of_planes = 1 << ((id_bytes[4] & 0x0c) >> 2);
-       plane_size  = (uint64_t)64 << ((id_bytes[4] & 0x70) >> 4);
-       blk_size = 64 << ((ioread32(denali->flash_reg + DEVICE_PARAM_1) & 0x30) >> 4);
-       capacity = (uint64_t)128 * plane_size * no_of_planes;
-
-       do_div(capacity, blk_size);
-       denali->dev_info.wTotalBlocks = capacity;
 }
 
 static void get_toshiba_nand_para(struct denali_nand_info *denali)
 {
-       void __iomem *scratch_reg;
        uint32_t tmp;
 
        /* Workaround to fix a controller bug which reports a wrong */
@@ -536,81 +408,52 @@ static void get_toshiba_nand_para(struct denali_nand_info *denali)
                denali_write32(216, denali->flash_reg + DEVICE_SPARE_AREA_SIZE);
                tmp = ioread32(denali->flash_reg + DEVICES_CONNECTED) *
                        ioread32(denali->flash_reg + DEVICE_SPARE_AREA_SIZE);
-               denali_write32(tmp, denali->flash_reg + LOGICAL_PAGE_SPARE_SIZE);
+               denali_write32(tmp,
+                               denali->flash_reg + LOGICAL_PAGE_SPARE_SIZE);
 #if SUPPORT_15BITECC
                denali_write32(15, denali->flash_reg + ECC_CORRECTION);
 #elif SUPPORT_8BITECC
                denali_write32(8, denali->flash_reg + ECC_CORRECTION);
 #endif
        }
-
-       /* As Toshiba NAND can not provide it's block number, */
-       /* so here we need user to provide the correct block */
-       /* number in a scratch register before the Linux NAND */
-       /* driver is loaded. If no valid value found in the scratch */
-       /* register, then we use default block number value */
-       scratch_reg = ioremap_nocache(SCRATCH_REG_ADDR, SCRATCH_REG_SIZE);
-       if (!scratch_reg) {
-               printk(KERN_ERR "Spectra: ioremap failed in %s, Line %d",
-                       __FILE__, __LINE__);
-               denali->dev_info.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
-       } else {
-               nand_dbg_print(NAND_DBG_WARN,
-                       "Spectra: ioremap reg address: 0x%p\n", scratch_reg);
-               denali->dev_info.wTotalBlocks = 1 << ioread8(scratch_reg);
-               if (denali->dev_info.wTotalBlocks < 512)
-                       denali->dev_info.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
-               iounmap(scratch_reg);
-       }
 }
 
-static void get_hynix_nand_para(struct denali_nand_info *denali)
+static void get_hynix_nand_para(struct denali_nand_info *denali,
+                                                       uint8_t device_id)
 {
-       void __iomem *scratch_reg;
        uint32_t main_size, spare_size;
 
-       switch (denali->dev_info.wDeviceID) {
+       switch (device_id) {
        case 0xD5: /* Hynix H27UAG8T2A, H27UBG8U5A or H27UCG8VFA */
        case 0xD7: /* Hynix H27UDG8VEM, H27UCG8UDM or H27UCG8V5A */
                denali_write32(128, denali->flash_reg + PAGES_PER_BLOCK);
                denali_write32(4096, denali->flash_reg + DEVICE_MAIN_AREA_SIZE);
                denali_write32(224, denali->flash_reg + DEVICE_SPARE_AREA_SIZE);
-               main_size = 4096 * ioread32(denali->flash_reg + DEVICES_CONNECTED);
-               spare_size = 224 * ioread32(denali->flash_reg + DEVICES_CONNECTED);
-               denali_write32(main_size, denali->flash_reg + LOGICAL_PAGE_DATA_SIZE);
-               denali_write32(spare_size, denali->flash_reg + LOGICAL_PAGE_SPARE_SIZE);
+               main_size = 4096 *
+                       ioread32(denali->flash_reg + DEVICES_CONNECTED);
+               spare_size = 224 *
+                       ioread32(denali->flash_reg + DEVICES_CONNECTED);
+               denali_write32(main_size,
+                               denali->flash_reg + LOGICAL_PAGE_DATA_SIZE);
+               denali_write32(spare_size,
+                               denali->flash_reg + LOGICAL_PAGE_SPARE_SIZE);
                denali_write32(0, denali->flash_reg + DEVICE_WIDTH);
 #if SUPPORT_15BITECC
                denali_write32(15, denali->flash_reg + ECC_CORRECTION);
 #elif SUPPORT_8BITECC
                denali_write32(8, denali->flash_reg + ECC_CORRECTION);
 #endif
-               denali->dev_info.MLCDevice  = 1;
                break;
        default:
                nand_dbg_print(NAND_DBG_WARN,
                        "Spectra: Unknown Hynix NAND (Device ID: 0x%x)."
                        "Will use default parameter values instead.\n",
-                       denali->dev_info.wDeviceID);
-       }
-
-       scratch_reg = ioremap_nocache(SCRATCH_REG_ADDR, SCRATCH_REG_SIZE);
-       if (!scratch_reg) {
-               printk(KERN_ERR "Spectra: ioremap failed in %s, Line %d",
-                       __FILE__, __LINE__);
-               denali->dev_info.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
-       } else {
-               nand_dbg_print(NAND_DBG_WARN,
-                       "Spectra: ioremap reg address: 0x%p\n", scratch_reg);
-               denali->dev_info.wTotalBlocks = 1 << ioread8(scratch_reg);
-               if (denali->dev_info.wTotalBlocks < 512)
-                       denali->dev_info.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
-               iounmap(scratch_reg);
+                       device_id);
        }
 }
 
 /* determines how many NAND chips are connected to the controller. Note for
-   Intel CE4100 devices we don't support more than one device. 
+   Intel CE4100 devices we don't support more than one device.
  */
 static void find_valid_banks(struct denali_nand_info *denali)
 {
@@ -621,7 +464,8 @@ static void find_valid_banks(struct denali_nand_info *denali)
        for (i = 0; i < LLD_MAX_FLASH_BANKS; i++) {
                index_addr(denali, (uint32_t)(MODE_11 | (i << 24) | 0), 0x90);
                index_addr(denali, (uint32_t)(MODE_11 | (i << 24) | 1), 0);
-               index_addr_read_data(denali, (uint32_t)(MODE_11 | (i << 24) | 2), &id[i]);
+               index_addr_read_data(denali,
+                               (uint32_t)(MODE_11 | (i << 24) | 2), &id[i]);
 
                nand_dbg_print(NAND_DBG_DEBUG,
                        "Return 1st ID for bank[%d]: %x\n", i, id[i]);
@@ -637,14 +481,12 @@ static void find_valid_banks(struct denali_nand_info *denali)
                }
        }
 
-       if (denali->platform == INTEL_CE4100)
-       {
+       if (denali->platform == INTEL_CE4100) {
                /* Platform limitations of the CE4100 device limit
                 * users to a single chip solution for NAND.
-                 * Multichip support is not enabled. 
-                */ 
-               if (denali->total_used_banks != 1)
-               {
+                * Multichip support is not enabled.
+                */
+               if (denali->total_used_banks != 1) {
                        printk(KERN_ERR "Sorry, Intel CE4100 only supports "
                                        "a single NAND device.\n");
                        BUG();
@@ -656,150 +498,60 @@ static void find_valid_banks(struct denali_nand_info *denali)
 
 static void detect_partition_feature(struct denali_nand_info *denali)
 {
+       /* For MRST platform, denali->fwblks represent the
+        * number of blocks firmware is taken,
+        * FW is in protect partition and MTD driver has no
+        * permission to access it. So let driver know how many
+        * blocks it can't touch.
+        * */
        if (ioread32(denali->flash_reg + FEATURES) & FEATURES__PARTITION) {
                if ((ioread32(denali->flash_reg + PERM_SRC_ID_1) &
                        PERM_SRC_ID_1__SRCID) == SPECTRA_PARTITION_ID) {
-                       denali->dev_info.wSpectraStartBlock =
+                       denali->fwblks =
                            ((ioread32(denali->flash_reg + MIN_MAX_BANK_1) &
                              MIN_MAX_BANK_1__MIN_VALUE) *
-                            denali->dev_info.wTotalBlocks)
+                            denali->blksperchip)
                            +
                            (ioread32(denali->flash_reg + MIN_BLK_ADDR_1) &
                            MIN_BLK_ADDR_1__VALUE);
-
-                       denali->dev_info.wSpectraEndBlock =
-                           (((ioread32(denali->flash_reg + MIN_MAX_BANK_1) &
-                              MIN_MAX_BANK_1__MAX_VALUE) >> 2) *
-                            denali->dev_info.wTotalBlocks)
-                           +
-                           (ioread32(denali->flash_reg + MAX_BLK_ADDR_1) &
-                           MAX_BLK_ADDR_1__VALUE);
-
-                       denali->dev_info.wTotalBlocks *= denali->total_used_banks;
-
-                       if (denali->dev_info.wSpectraEndBlock >=
-                           denali->dev_info.wTotalBlocks) {
-                               denali->dev_info.wSpectraEndBlock =
-                                   denali->dev_info.wTotalBlocks - 1;
-                       }
-
-                       denali->dev_info.wDataBlockNum =
-                               denali->dev_info.wSpectraEndBlock -
-                               denali->dev_info.wSpectraStartBlock + 1;
-               } else {
-                       denali->dev_info.wTotalBlocks *= denali->total_used_banks;
-                       denali->dev_info.wSpectraStartBlock = SPECTRA_START_BLOCK;
-                       denali->dev_info.wSpectraEndBlock =
-                               denali->dev_info.wTotalBlocks - 1;
-                       denali->dev_info.wDataBlockNum =
-                               denali->dev_info.wSpectraEndBlock -
-                               denali->dev_info.wSpectraStartBlock + 1;
-               }
-       } else {
-               denali->dev_info.wTotalBlocks *= denali->total_used_banks;
-               denali->dev_info.wSpectraStartBlock = SPECTRA_START_BLOCK;
-               denali->dev_info.wSpectraEndBlock = denali->dev_info.wTotalBlocks - 1;
-               denali->dev_info.wDataBlockNum =
-                       denali->dev_info.wSpectraEndBlock -
-                       denali->dev_info.wSpectraStartBlock + 1;
-       }
+               } else
+                       denali->fwblks = SPECTRA_START_BLOCK;
+       } else
+               denali->fwblks = SPECTRA_START_BLOCK;
 }
 
-static void dump_device_info(struct denali_nand_info *denali)
-{
-       nand_dbg_print(NAND_DBG_DEBUG, "denali->dev_info:\n");
-       nand_dbg_print(NAND_DBG_DEBUG, "DeviceMaker: 0x%x\n",
-               denali->dev_info.wDeviceMaker);
-       nand_dbg_print(NAND_DBG_DEBUG, "DeviceID: 0x%x\n",
-               denali->dev_info.wDeviceID);
-       nand_dbg_print(NAND_DBG_DEBUG, "DeviceType: 0x%x\n",
-               denali->dev_info.wDeviceType);
-       nand_dbg_print(NAND_DBG_DEBUG, "SpectraStartBlock: %d\n",
-               denali->dev_info.wSpectraStartBlock);
-       nand_dbg_print(NAND_DBG_DEBUG, "SpectraEndBlock: %d\n",
-               denali->dev_info.wSpectraEndBlock);
-       nand_dbg_print(NAND_DBG_DEBUG, "TotalBlocks: %d\n",
-               denali->dev_info.wTotalBlocks);
-       nand_dbg_print(NAND_DBG_DEBUG, "PagesPerBlock: %d\n",
-               denali->dev_info.wPagesPerBlock);
-       nand_dbg_print(NAND_DBG_DEBUG, "PageSize: %d\n",
-               denali->dev_info.wPageSize);
-       nand_dbg_print(NAND_DBG_DEBUG, "PageDataSize: %d\n",
-               denali->dev_info.wPageDataSize);
-       nand_dbg_print(NAND_DBG_DEBUG, "PageSpareSize: %d\n",
-               denali->dev_info.wPageSpareSize);
-       nand_dbg_print(NAND_DBG_DEBUG, "NumPageSpareFlag: %d\n",
-               denali->dev_info.wNumPageSpareFlag);
-       nand_dbg_print(NAND_DBG_DEBUG, "ECCBytesPerSector: %d\n",
-               denali->dev_info.wECCBytesPerSector);
-       nand_dbg_print(NAND_DBG_DEBUG, "BlockSize: %d\n",
-               denali->dev_info.wBlockSize);
-       nand_dbg_print(NAND_DBG_DEBUG, "BlockDataSize: %d\n",
-               denali->dev_info.wBlockDataSize);
-       nand_dbg_print(NAND_DBG_DEBUG, "DataBlockNum: %d\n",
-               denali->dev_info.wDataBlockNum);
-       nand_dbg_print(NAND_DBG_DEBUG, "PlaneNum: %d\n",
-               denali->dev_info.bPlaneNum);
-       nand_dbg_print(NAND_DBG_DEBUG, "DeviceMainAreaSize: %d\n",
-               denali->dev_info.wDeviceMainAreaSize);
-       nand_dbg_print(NAND_DBG_DEBUG, "DeviceSpareAreaSize: %d\n",
-               denali->dev_info.wDeviceSpareAreaSize);
-       nand_dbg_print(NAND_DBG_DEBUG, "DevicesConnected: %d\n",
-               denali->dev_info.wDevicesConnected);
-       nand_dbg_print(NAND_DBG_DEBUG, "DeviceWidth: %d\n",
-               denali->dev_info.wDeviceWidth);
-       nand_dbg_print(NAND_DBG_DEBUG, "HWRevision: 0x%x\n",
-               denali->dev_info.wHWRevision);
-       nand_dbg_print(NAND_DBG_DEBUG, "HWFeatures: 0x%x\n",
-               denali->dev_info.wHWFeatures);
-       nand_dbg_print(NAND_DBG_DEBUG, "ONFIDevFeatures: 0x%x\n",
-               denali->dev_info.wONFIDevFeatures);
-       nand_dbg_print(NAND_DBG_DEBUG, "ONFIOptCommands: 0x%x\n",
-               denali->dev_info.wONFIOptCommands);
-       nand_dbg_print(NAND_DBG_DEBUG, "ONFITimingMode: 0x%x\n",
-               denali->dev_info.wONFITimingMode);
-       nand_dbg_print(NAND_DBG_DEBUG, "ONFIPgmCacheTimingMode: 0x%x\n",
-               denali->dev_info.wONFIPgmCacheTimingMode);
-       nand_dbg_print(NAND_DBG_DEBUG, "MLCDevice: %s\n",
-               denali->dev_info.MLCDevice ? "Yes" : "No");
-       nand_dbg_print(NAND_DBG_DEBUG, "SpareSkipBytes: %d\n",
-               denali->dev_info.wSpareSkipBytes);
-       nand_dbg_print(NAND_DBG_DEBUG, "BitsInPageNumber: %d\n",
-               denali->dev_info.nBitsInPageNumber);
-       nand_dbg_print(NAND_DBG_DEBUG, "BitsInPageDataSize: %d\n",
-               denali->dev_info.nBitsInPageDataSize);
-       nand_dbg_print(NAND_DBG_DEBUG, "BitsInBlockDataSize: %d\n",
-               denali->dev_info.nBitsInBlockDataSize);
-}
-
-static uint16_t NAND_Read_Device_ID(struct denali_nand_info *denali)
+static uint16_t denali_nand_timing_set(struct denali_nand_info *denali)
 {
        uint16_t status = PASS;
-       uint8_t no_of_planes;
+       uint32_t id_bytes[5], addr;
+       uint8_t i, maf_id, device_id;
 
        nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
                       __FILE__, __LINE__, __func__);
 
-       denali->dev_info.wDeviceMaker = ioread32(denali->flash_reg + MANUFACTURER_ID);
-       denali->dev_info.wDeviceID = ioread32(denali->flash_reg + DEVICE_ID);
-       denali->dev_info.bDeviceParam0 = ioread32(denali->flash_reg + DEVICE_PARAM_0);
-       denali->dev_info.bDeviceParam1 = ioread32(denali->flash_reg + DEVICE_PARAM_1);
-       denali->dev_info.bDeviceParam2 = ioread32(denali->flash_reg + DEVICE_PARAM_2);
-
-       denali->dev_info.MLCDevice = ioread32(denali->flash_reg + DEVICE_PARAM_0) & 0x0c;
+       /* Use read id method to get device ID and other
+        * params. For some NAND chips, controller can't
+        * report the correct device ID by reading from
+        * DEVICE_ID register
+        * */
+       addr = (uint32_t)MODE_11 | BANK(denali->flash_bank);
+       index_addr(denali, (uint32_t)addr | 0, 0x90);
+       index_addr(denali, (uint32_t)addr | 1, 0);
+       for (i = 0; i < 5; i++)
+               index_addr_read_data(denali, addr | 2, &id_bytes[i]);
+       maf_id = id_bytes[0];
+       device_id = id_bytes[1];
 
        if (ioread32(denali->flash_reg + ONFI_DEVICE_NO_OF_LUNS) &
                ONFI_DEVICE_NO_OF_LUNS__ONFI_DEVICE) { /* ONFI 1.0 NAND */
                if (FAIL == get_onfi_nand_para(denali))
                        return FAIL;
-       } else if (denali->dev_info.wDeviceMaker == 0xEC) { /* Samsung NAND */
-               get_samsung_nand_para(denali);
-       } else if (denali->dev_info.wDeviceMaker == 0x98) { /* Toshiba NAND */
+       } else if (maf_id == 0xEC) { /* Samsung NAND */
+               get_samsung_nand_para(denali, device_id);
+       } else if (maf_id == 0x98) { /* Toshiba NAND */
                get_toshiba_nand_para(denali);
-       } else if (denali->dev_info.wDeviceMaker == 0xAD) { /* Hynix NAND */
-               get_hynix_nand_para(denali);
-       } else {
-               denali->dev_info.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
+       } else if (maf_id == 0xAD) { /* Hynix NAND */
+               get_hynix_nand_para(denali, device_id);
        }
 
        nand_dbg_print(NAND_DBG_DEBUG, "Dump timing register values:"
@@ -814,88 +566,20 @@ static uint16_t NAND_Read_Device_ID(struct denali_nand_info *denali)
                        ioread32(denali->flash_reg + RDWR_EN_HI_CNT),
                        ioread32(denali->flash_reg + CS_SETUP_CNT));
 
-       denali->dev_info.wHWRevision = ioread32(denali->flash_reg + REVISION);
-       denali->dev_info.wHWFeatures = ioread32(denali->flash_reg + FEATURES);
-
-       denali->dev_info.wDeviceMainAreaSize =
-               ioread32(denali->flash_reg + DEVICE_MAIN_AREA_SIZE);
-       denali->dev_info.wDeviceSpareAreaSize =
-               ioread32(denali->flash_reg + DEVICE_SPARE_AREA_SIZE);
-
-       denali->dev_info.wPageDataSize =
-               ioread32(denali->flash_reg + LOGICAL_PAGE_DATA_SIZE);
-
-       /* Note: When using the Micon 4K NAND device, the controller will report
-        * Page Spare Size as 216 bytes. But Micron's Spec say it's 218 bytes.
-        * And if force set it to 218 bytes, the controller can not work
-        * correctly. So just let it be. But keep in mind that this bug may
-        * cause
-        * other problems in future.       - Yunpeng  2008-10-10
-        */
-       denali->dev_info.wPageSpareSize =
-               ioread32(denali->flash_reg + LOGICAL_PAGE_SPARE_SIZE);
-
-       denali->dev_info.wPagesPerBlock = ioread32(denali->flash_reg + PAGES_PER_BLOCK);
-
-       denali->dev_info.wPageSize =
-           denali->dev_info.wPageDataSize + denali->dev_info.wPageSpareSize;
-       denali->dev_info.wBlockSize =
-           denali->dev_info.wPageSize * denali->dev_info.wPagesPerBlock;
-       denali->dev_info.wBlockDataSize =
-           denali->dev_info.wPagesPerBlock * denali->dev_info.wPageDataSize;
-
-       denali->dev_info.wDeviceWidth = ioread32(denali->flash_reg + DEVICE_WIDTH);
-       denali->dev_info.wDeviceType =
-               ((ioread32(denali->flash_reg + DEVICE_WIDTH) > 0) ? 16 : 8);
-
-       denali->dev_info.wDevicesConnected = ioread32(denali->flash_reg + DEVICES_CONNECTED);
-
-       denali->dev_info.wSpareSkipBytes =
-               ioread32(denali->flash_reg + SPARE_AREA_SKIP_BYTES) *
-               denali->dev_info.wDevicesConnected;
-
-       denali->dev_info.nBitsInPageNumber =
-               ilog2(denali->dev_info.wPagesPerBlock);
-       denali->dev_info.nBitsInPageDataSize =
-               ilog2(denali->dev_info.wPageDataSize);
-       denali->dev_info.nBitsInBlockDataSize =
-               ilog2(denali->dev_info.wBlockDataSize);
-
-       set_ecc_config(denali);
-
-       no_of_planes = ioread32(denali->flash_reg + NUMBER_OF_PLANES) &
-               NUMBER_OF_PLANES__VALUE;
-
-       switch (no_of_planes) {
-       case 0:
-       case 1:
-       case 3:
-       case 7:
-               denali->dev_info.bPlaneNum = no_of_planes + 1;
-               break;
-       default:
-               status = FAIL;
-               break;
-       }
-
        find_valid_banks(denali);
 
        detect_partition_feature(denali);
 
-       dump_device_info(denali);
-
        /* If the user specified to override the default timings
-        * with a specific ONFI mode, we apply those changes here. 
+        * with a specific ONFI mode, we apply those changes here.
         */
        if (onfi_timing_mode != NAND_DEFAULT_TIMINGS)
-       {
-               NAND_ONFi_Timing_Mode(denali, onfi_timing_mode);
-       }
+               nand_onfi_timing_set(denali, onfi_timing_mode);
 
        return status;
 }
 
-static void NAND_LLD_Enable_Disable_Interrupts(struct denali_nand_info *denali,
+static void denali_set_intr_modes(struct denali_nand_info *denali,
                                        uint16_t INT_ENABLE)
 {
        nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
@@ -912,7 +596,7 @@ static void NAND_LLD_Enable_Disable_Interrupts(struct denali_nand_info *denali,
  */
 static inline bool is_flash_bank_valid(int flash_bank)
 {
-       return (flash_bank >= 0 && flash_bank < 4); 
+       return (flash_bank >= 0 && flash_bank < 4);
 }
 
 static void denali_irq_init(struct denali_nand_info *denali)
@@ -920,7 +604,7 @@ static void denali_irq_init(struct denali_nand_info *denali)
        uint32_t int_mask = 0;
 
        /* Disable global interrupts */
-       NAND_LLD_Enable_Disable_Interrupts(denali, false);
+       denali_set_intr_modes(denali, false);
 
        int_mask = DENALI_IRQ_ALL;
 
@@ -935,11 +619,12 @@ static void denali_irq_init(struct denali_nand_info *denali)
 
 static void denali_irq_cleanup(int irqnum, struct denali_nand_info *denali)
 {
-       NAND_LLD_Enable_Disable_Interrupts(denali, false);
+       denali_set_intr_modes(denali, false);
        free_irq(irqnum, denali);
 }
 
-static void denali_irq_enable(struct denali_nand_info *denali, uint32_t int_mask)
+static void denali_irq_enable(struct denali_nand_info *denali,
+                                                       uint32_t int_mask)
 {
        denali_write32(int_mask, denali->flash_reg + INTR_EN0);
        denali_write32(int_mask, denali->flash_reg + INTR_EN1);
@@ -948,15 +633,16 @@ static void denali_irq_enable(struct denali_nand_info *denali, uint32_t int_mask
 }
 
 /* This function only returns when an interrupt that this driver cares about
- * occurs. This is to reduce the overhead of servicing interrupts 
+ * occurs. This is to reduce the overhead of servicing interrupts
  */
 static inline uint32_t denali_irq_detected(struct denali_nand_info *denali)
 {
-       return (read_interrupt_status(denali) & DENALI_IRQ_ALL);
+       return read_interrupt_status(denali) & DENALI_IRQ_ALL;
 }
 
 /* Interrupts are cleared by writing a 1 to the appropriate status bit */
-static inline void clear_interrupt(struct denali_nand_info *denali, uint32_t irq_mask)
+static inline void clear_interrupt(struct denali_nand_info *denali,
+                                                       uint32_t irq_mask)
 {
        uint32_t intr_status_reg = 0;
 
@@ -995,17 +681,15 @@ static void print_irq_log(struct denali_nand_info *denali)
 {
        int i = 0;
 
-       printk("ISR debug log index = %X\n", denali->idx);
+       printk(KERN_INFO "ISR debug log index = %X\n", denali->idx);
        for (i = 0; i < 32; i++)
-       {
-               printk("%08X: %08X\n", i, denali->irq_debug_array[i]);
-       }
+               printk(KERN_INFO "%08X: %08X\n", i, denali->irq_debug_array[i]);
 }
 #endif
 
-/* This is the interrupt service routine. It handles all interrupts 
- * sent to this device. Note that on CE4100, this is a shared 
- * interrupt. 
+/* This is the interrupt service routine. It handles all interrupts
+ * sent to this device. Note that on CE4100, this is a shared
+ * interrupt.
  */
 static irqreturn_t denali_isr(int irq, void *dev_id)
 {
@@ -1015,20 +699,20 @@ static irqreturn_t denali_isr(int irq, void *dev_id)
 
        spin_lock(&denali->irq_lock);
 
-       /* check to see if a valid NAND chip has 
-         * been selected. 
+       /* check to see if a valid NAND chip has
+        * been selected.
         */
-       if (is_flash_bank_valid(denali->flash_bank))
-       {
-               /* check to see if controller generated 
+       if (is_flash_bank_valid(denali->flash_bank)) {
+               /* check to see if controller generated
                 * the interrupt, since this is a shared interrupt */
-               if ((irq_status = denali_irq_detected(denali)) != 0)
-               {
+               irq_status = denali_irq_detected(denali);
+               if (irq_status != 0) {
 #if DEBUG_DENALI
-                       denali->irq_debug_array[denali->idx++] = 0x10000000 | irq_status;
+                       denali->irq_debug_array[denali->idx++] =
+                               0x10000000 | irq_status;
                        denali->idx %= 32;
 
-                       printk("IRQ status = 0x%04x\n", irq_status);
+                       printk(KERN_INFO "IRQ status = 0x%04x\n", irq_status);
 #endif
                        /* handle interrupt */
                        /* first acknowledge it */
@@ -1054,61 +738,62 @@ static uint32_t wait_for_irq(struct denali_nand_info *denali, uint32_t irq_mask)
        bool retry = false;
        unsigned long timeout = msecs_to_jiffies(1000);
 
-       do
-       {
+       do {
 #if DEBUG_DENALI
-               printk("waiting for 0x%x\n", irq_mask);
+               printk(KERN_INFO "waiting for 0x%x\n", irq_mask);
 #endif
-               comp_res = wait_for_completion_timeout(&denali->complete, timeout);
+               comp_res =
+                       wait_for_completion_timeout(&denali->complete, timeout);
                spin_lock_irq(&denali->irq_lock);
                intr_status = denali->irq_status;
 
 #if DEBUG_DENALI
-               denali->irq_debug_array[denali->idx++] = 0x20000000 | (irq_mask << 16) | intr_status;
+               denali->irq_debug_array[denali->idx++] =
+                       0x20000000 | (irq_mask << 16) | intr_status;
                denali->idx %= 32;
 #endif
 
-               if (intr_status & irq_mask)
-               {
+               if (intr_status & irq_mask) {
                        denali->irq_status &= ~irq_mask;
                        spin_unlock_irq(&denali->irq_lock);
 #if DEBUG_DENALI
-                       if (retry) printk("status on retry = 0x%x\n", intr_status);
+                       if (retry)
+                               printk(KERN_INFO "status on retry = 0x%x\n",
+                                               intr_status);
 #endif
                        /* our interrupt was detected */
                        break;
-               }
-               else 
-               {
-                       /* these are not the interrupts you are looking for - 
-                          need to wait again */
+               } else {
+                       /* these are not the interrupts you are looking for -
+                        * need to wait again */
                        spin_unlock_irq(&denali->irq_lock);
 #if DEBUG_DENALI
                        print_irq_log(denali);
-                       printk("received irq nobody cared: irq_status = 0x%x,"
-                               " irq_mask = 0x%x, timeout = %ld\n", intr_status, irq_mask, comp_res);
+                       printk(KERN_INFO "received irq nobody cared:"
+                                       " irq_status = 0x%x, irq_mask = 0x%x,"
+                                       " timeout = %ld\n", intr_status,
+                                       irq_mask, comp_res);
 #endif
                        retry = true;
                }
        } while (comp_res != 0);
 
-       if (comp_res == 0)
-       {
+       if (comp_res == 0) {
                /* timeout */
-               printk(KERN_ERR "timeout occurred, status = 0x%x, mask = 0x%x\n", 
-                               intr_status, irq_mask);
+               printk(KERN_ERR "timeout occurred, status = 0x%x, mask = 0x%x\n",
+                               intr_status, irq_mask);
 
                intr_status = 0;
        }
        return intr_status;
 }
 
-/* This helper function setups the registers for ECC and whether or not 
+/* This helper function setups the registers for ECC and whether or not
    the spare area will be transfered. */
-static void setup_ecc_for_xfer(struct denali_nand_info *denali, bool ecc_en, 
+static void setup_ecc_for_xfer(struct denali_nand_info *denali, bool ecc_en,
                                bool transfer_spare)
 {
-       int ecc_en_flag = 0, transfer_spare_flag = 0; 
+       int ecc_en_flag = 0, transfer_spare_flag = 0;
 
        /* set ECC, transfer spare bits if needed */
        ecc_en_flag = ecc_en ? ECC_ENABLE__FLAG : 0;
@@ -1116,85 +801,85 @@ static void setup_ecc_for_xfer(struct denali_nand_info *denali, bool ecc_en,
 
        /* Enable spare area/ECC per user's request. */
        denali_write32(ecc_en_flag, denali->flash_reg + ECC_ENABLE);
-       denali_write32(transfer_spare_flag, denali->flash_reg + TRANSFER_SPARE_REG);
+       denali_write32(transfer_spare_flag,
+                       denali->flash_reg + TRANSFER_SPARE_REG);
 }
 
-/* sends a pipeline command operation to the controller. See the Denali NAND 
-   controller's user guide for more information (section 4.2.3.6). 
+/* sends a pipeline command operation to the controller. See the Denali NAND
+   controller's user guide for more information (section 4.2.3.6).
  */
-static int denali_send_pipeline_cmd(struct denali_nand_info *denali, bool ecc_en, 
-                                       bool transfer_spare, int access_type, 
-                                       int op)
+static int denali_send_pipeline_cmd(struct denali_nand_info *denali,
+                                                       bool ecc_en,
+                                                       bool transfer_spare,
+                                                       int access_type,
+                                                       int op)
 {
        int status = PASS;
-       uint32_t addr = 0x0, cmd = 0x0, page_count = 1, irq_status = 0, 
+       uint32_t addr = 0x0, cmd = 0x0, page_count = 1, irq_status = 0,
                 irq_mask = 0;
 
-       if (op == DENALI_READ) irq_mask = INTR_STATUS0__LOAD_COMP;
-       else if (op == DENALI_WRITE) irq_mask = 0;
-       else BUG();
+       if (op == DENALI_READ)
+               irq_mask = INTR_STATUS0__LOAD_COMP;
+       else if (op == DENALI_WRITE)
+               irq_mask = 0;
+       else
+               BUG();
 
        setup_ecc_for_xfer(denali, ecc_en, transfer_spare);
 
 #if DEBUG_DENALI
        spin_lock_irq(&denali->irq_lock);
-       denali->irq_debug_array[denali->idx++] = 0x40000000 | ioread32(denali->flash_reg + ECC_ENABLE) | (access_type << 4);
+       denali->irq_debug_array[denali->idx++] =
+               0x40000000 | ioread32(denali->flash_reg + ECC_ENABLE) |
+               (access_type << 4);
        denali->idx %= 32;
        spin_unlock_irq(&denali->irq_lock);
 #endif
 
 
        /* clear interrupts */
-       clear_interrupts(denali);       
+       clear_interrupts(denali);
 
        addr = BANK(denali->flash_bank) | denali->page;
 
-       if (op == DENALI_WRITE && access_type != SPARE_ACCESS)
-       {
-               cmd = MODE_01 | addr; 
+       if (op == DENALI_WRITE && access_type != SPARE_ACCESS) {
+               cmd = MODE_01 | addr;
                denali_write32(cmd, denali->flash_mem);
-       }
-       else if (op == DENALI_WRITE && access_type == SPARE_ACCESS)
-       {
+       } else if (op == DENALI_WRITE && access_type == SPARE_ACCESS) {
                /* read spare area */
-               cmd = MODE_10 | addr; 
+               cmd = MODE_10 | addr;
                index_addr(denali, (uint32_t)cmd, access_type);
 
-               cmd = MODE_01 | addr; 
+               cmd = MODE_01 | addr;
                denali_write32(cmd, denali->flash_mem);
-       }
-       else if (op == DENALI_READ)
-       {
+       } else if (op == DENALI_READ) {
                /* setup page read request for access type */
-               cmd = MODE_10 | addr; 
+               cmd = MODE_10 | addr;
                index_addr(denali, (uint32_t)cmd, access_type);
 
                /* page 33 of the NAND controller spec indicates we should not
-                  use the pipeline commands in Spare area only mode. So we 
+                  use the pipeline commands in Spare area only mode. So we
                   don't.
                 */
-               if (access_type == SPARE_ACCESS)
-               {
+               if (access_type == SPARE_ACCESS) {
                        cmd = MODE_01 | addr;
                        denali_write32(cmd, denali->flash_mem);
-               }
-               else
-               {
-                       index_addr(denali, (uint32_t)cmd, 0x2000 | op | page_count);
-       
-                       /* wait for command to be accepted  
-                        * can always use status0 bit as the mask is identical for each
+               } else {
+                       index_addr(denali, (uint32_t)cmd,
+                                       0x2000 | op | page_count);
+
+                       /* wait for command to be accepted
+                        * can always use status0 bit as the
+                        * mask is identical for each
                         * bank. */
                        irq_status = wait_for_irq(denali, irq_mask);
 
-                       if (irq_status == 0)
-                       {
+                       if (irq_status == 0) {
                                printk(KERN_ERR "cmd, page, addr on timeout "
-                                       "(0x%x, 0x%x, 0x%x)\n", cmd, denali->page, addr);
+                                       "(0x%x, 0x%x, 0x%x)\n", cmd,
+                                       denali->page, addr);
                                status = FAIL;
-                       }
-                       else
-                       {
+                       } else {
                                cmd = MODE_01 | addr;
                                denali_write32(cmd, denali->flash_mem);
                        }
@@ -1204,36 +889,35 @@ static int denali_send_pipeline_cmd(struct denali_nand_info *denali, bool ecc_en
 }
 
 /* helper function that simply writes a buffer to the flash */
-static int write_data_to_flash_mem(struct denali_nand_info *denali, const uint8_t *buf, 
-                                       int len) 
+static int write_data_to_flash_mem(struct denali_nand_info *denali,
+                                                       const uint8_t *buf,
+                                                       int len)
 {
        uint32_t i = 0, *buf32;
 
-       /* verify that the len is a multiple of 4. see comment in 
-        * read_data_from_flash_mem() */        
+       /* verify that the len is a multiple of 4. see comment in
+        * read_data_from_flash_mem() */
        BUG_ON((len % 4) != 0);
 
        /* write the data to the flash memory */
        buf32 = (uint32_t *)buf;
        for (i = 0; i < len / 4; i++)
-       {
                denali_write32(*buf32++, denali->flash_mem + 0x10);
-       }
-       return i*4; /* intent is to return the number of bytes read */ 
+       return i*4; /* intent is to return the number of bytes read */
 }
 
 /* helper function that simply reads a buffer from the flash */
-static int read_data_from_flash_mem(struct denali_nand_info *denali, uint8_t *buf, 
-                                       int len)
+static int read_data_from_flash_mem(struct denali_nand_info *denali,
+                                                               uint8_t *buf,
+                                                               int len)
 {
        uint32_t i = 0, *buf32;
 
        /* we assume that len will be a multiple of 4, if not
         * it would be nice to know about it ASAP rather than
-        * have random failures... 
-         *     
-        * This assumption is based on the fact that this 
-        * function is designed to be used to read flash pages, 
+        * have random failures...
+        * This assumption is based on the fact that this
+        * function is designed to be used to read flash pages,
         * which are typically multiples of 4...
         */
 
@@ -1242,10 +926,8 @@ static int read_data_from_flash_mem(struct denali_nand_info *denali, uint8_t *bu
        /* transfer the data from the flash */
        buf32 = (uint32_t *)buf;
        for (i = 0; i < len / 4; i++)
-       {
                *buf32++ = ioread32(denali->flash_mem + 0x10);
-       }
-       return i*4; /* intent is to return the number of bytes read */ 
+       return i*4; /* intent is to return the number of bytes read */
 }
 
 /* writes OOB data to the device */
@@ -1253,38 +935,35 @@ static int write_oob_data(struct mtd_info *mtd, uint8_t *buf, int page)
 {
        struct denali_nand_info *denali = mtd_to_denali(mtd);
        uint32_t irq_status = 0;
-       uint32_t irq_mask = INTR_STATUS0__PROGRAM_COMP | 
+       uint32_t irq_mask = INTR_STATUS0__PROGRAM_COMP |
                                                INTR_STATUS0__PROGRAM_FAIL;
        int status = 0;
 
        denali->page = page;
 
-       if (denali_send_pipeline_cmd(denali, false, false, SPARE_ACCESS, 
-                                                       DENALI_WRITE) == PASS) 
-       {
+       if (denali_send_pipeline_cmd(denali, false, false, SPARE_ACCESS,
+                                                       DENALI_WRITE) == PASS) {
                write_data_to_flash_mem(denali, buf, mtd->oobsize);
 
 #if DEBUG_DENALI
                spin_lock_irq(&denali->irq_lock);
-               denali->irq_debug_array[denali->idx++] = 0x80000000 | mtd->oobsize;
+               denali->irq_debug_array[denali->idx++] =
+                       0x80000000 | mtd->oobsize;
                denali->idx %= 32;
                spin_unlock_irq(&denali->irq_lock);
 #endif
 
-       
+
                /* wait for operation to complete */
                irq_status = wait_for_irq(denali, irq_mask);
 
-               if (irq_status == 0)
-               {
+               if (irq_status == 0) {
                        printk(KERN_ERR "OOB write failed\n");
                        status = -EIO;
                }
-       }
-       else 
-       {       
+       } else {
                printk(KERN_ERR "unable to send pipeline command\n");
-               status = -EIO; 
+               status = -EIO;
        }
        return status;
 }
@@ -1293,60 +972,56 @@ static int write_oob_data(struct mtd_info *mtd, uint8_t *buf, int page)
 static void read_oob_data(struct mtd_info *mtd, uint8_t *buf, int page)
 {
        struct denali_nand_info *denali = mtd_to_denali(mtd);
-       uint32_t irq_mask = INTR_STATUS0__LOAD_COMP, irq_status = 0, addr = 0x0, cmd = 0x0;
+       uint32_t irq_mask = INTR_STATUS0__LOAD_COMP,
+                        irq_status = 0, addr = 0x0, cmd = 0x0;
 
        denali->page = page;
 
 #if DEBUG_DENALI
-       printk("read_oob %d\n", page);
+       printk(KERN_INFO "read_oob %d\n", page);
 #endif
-       if (denali_send_pipeline_cmd(denali, false, true, SPARE_ACCESS, 
-                                                       DENALI_READ) == PASS) 
-       {
-               read_data_from_flash_mem(denali, buf, mtd->oobsize);    
+       if (denali_send_pipeline_cmd(denali, false, true, SPARE_ACCESS,
+                                                       DENALI_READ) == PASS) {
+               read_data_from_flash_mem(denali, buf, mtd->oobsize);
 
-               /* wait for command to be accepted  
+               /* wait for command to be accepted
                 * can always use status0 bit as the mask is identical for each
                 * bank. */
                irq_status = wait_for_irq(denali, irq_mask);
 
                if (irq_status == 0)
-               {
-                       printk(KERN_ERR "page on OOB timeout %d\n", denali->page);
-               }
+                       printk(KERN_ERR "page on OOB timeout %d\n",
+                                       denali->page);
 
                /* We set the device back to MAIN_ACCESS here as I observed
                 * instability with the controller if you do a block erase
                 * and the last transaction was a SPARE_ACCESS. Block erase
                 * is reliable (according to the MTD test infrastructure)
-                * if you are in MAIN_ACCESS. 
+                * if you are in MAIN_ACCESS.
                 */
                addr = BANK(denali->flash_bank) | denali->page;
-               cmd = MODE_10 | addr; 
+               cmd = MODE_10 | addr;
                index_addr(denali, (uint32_t)cmd, MAIN_ACCESS);
 
 #if DEBUG_DENALI
                spin_lock_irq(&denali->irq_lock);
-               denali->irq_debug_array[denali->idx++] = 0x60000000 | mtd->oobsize;
+               denali->irq_debug_array[denali->idx++] =
+                       0x60000000 | mtd->oobsize;
                denali->idx %= 32;
                spin_unlock_irq(&denali->irq_lock);
 #endif
        }
 }
 
-/* this function examines buffers to see if they contain data that 
+/* this function examines buffers to see if they contain data that
  * indicate that the buffer is part of an erased region of flash.
  */
 bool is_erased(uint8_t *buf, int len)
 {
        int i = 0;
        for (i = 0; i < len; i++)
-       {       
                if (buf[i] != 0xFF)
-               {
                        return false;
-               }
-       }
        return true;
 }
 #define ECC_SECTOR_SIZE 512
@@ -1358,65 +1033,59 @@ bool is_erased(uint8_t *buf, int len)
 #define ECC_ERR_DEVICE(x)      ((x) & ERR_CORRECTION_INFO__DEVICE_NR >> 8)
 #define ECC_LAST_ERR(x)                ((x) & ERR_CORRECTION_INFO__LAST_ERR_INFO)
 
-static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, 
+static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf,
                        uint8_t *oobbuf, uint32_t irq_status)
 {
        bool check_erased_page = false;
 
-       if (irq_status & INTR_STATUS0__ECC_ERR)
-       {
+       if (irq_status & INTR_STATUS0__ECC_ERR) {
                /* read the ECC errors. we'll ignore them for now */
                uint32_t err_address = 0, err_correction_info = 0;
                uint32_t err_byte = 0, err_sector = 0, err_device = 0;
                uint32_t err_correction_value = 0;
 
-               do 
-               {
-                       err_address = ioread32(denali->flash_reg + 
+               do {
+                       err_address = ioread32(denali->flash_reg +
                                                ECC_ERROR_ADDRESS);
                        err_sector = ECC_SECTOR(err_address);
                        err_byte = ECC_BYTE(err_address);
 
 
-                       err_correction_info = ioread32(denali->flash_reg + 
+                       err_correction_info = ioread32(denali->flash_reg +
                                                ERR_CORRECTION_INFO);
-                       err_correction_value = 
+                       err_correction_value =
                                ECC_CORRECTION_VALUE(err_correction_info);
                        err_device = ECC_ERR_DEVICE(err_correction_info);
 
-                       if (ECC_ERROR_CORRECTABLE(err_correction_info))
-                       {
+                       if (ECC_ERROR_CORRECTABLE(err_correction_info)) {
                                /* offset in our buffer is computed as:
-                                  sector number * sector size + offset in 
+                                  sector number * sector size + offset in
                                   sector
                                 */
-                               int offset = err_sector * ECC_SECTOR_SIZE + 
+                               int offset = err_sector * ECC_SECTOR_SIZE +
                                                                err_byte;
-                               if (offset < denali->mtd.writesize)
-                               {
+                               if (offset < denali->mtd.writesize) {
                                        /* correct the ECC error */
                                        buf[offset] ^= err_correction_value;
                                        denali->mtd.ecc_stats.corrected++;
-                               }
-                               else
-                               {
+                               } else {
                                        /* bummer, couldn't correct the error */
                                        printk(KERN_ERR "ECC offset invalid\n");
                                        denali->mtd.ecc_stats.failed++;
                                }
-                       }
-                       else
-                       {
-                               /* if the error is not correctable, need to 
-                                * look at the page to see if it is an erased page.
-                                * if so, then it's not a real ECC error */     
+                       } else {
+                               /* if the error is not correctable, need to
+                                * look at the page to see if it is an erased
+                                * page. if so, then it's not a real ECC error
+                                * */
                                check_erased_page = true;
                        }
 
-#if DEBUG_DENALI 
-                       printk("Detected ECC error in page %d: err_addr = 0x%08x,"
-                               " info to fix is 0x%08x\n", denali->page, err_address, 
-                               err_correction_info);
+#if DEBUG_DENALI
+                       printk(KERN_INFO "Detected ECC error in page %d:"
+                                       " err_addr = 0x%08x, info to fix is"
+                                       " 0x%08x\n", denali->page, err_address,
+                                       err_correction_info);
 #endif
                } while (!ECC_LAST_ERR(err_correction_info));
        }
@@ -1428,7 +1097,8 @@ static void denali_enable_dma(struct denali_nand_info *denali, bool en)
 {
        uint32_t reg_val = 0x0;
 
-       if (en) reg_val = DMA_ENABLE__FLAG;
+       if (en)
+               reg_val = DMA_ENABLE__FLAG;
 
        denali_write32(reg_val, denali->flash_reg + DMA_ENABLE);
        ioread32(denali->flash_reg + DMA_ENABLE);
@@ -1458,9 +1128,9 @@ static void denali_setup_dma(struct denali_nand_info *denali, int op)
        index_addr(denali, mode | 0x14000, 0x2400);
 }
 
-/* writes a page. user specifies type, and this function handles the 
+/* writes a page. user specifies type, and this function handles the
    configuration details. */
-static void write_page(struct mtd_info *mtd, struct nand_chip *chip, 
+static void write_page(struct mtd_info *mtd, struct nand_chip *chip,
                        const uint8_t *buf, bool raw_xfer)
 {
        struct denali_nand_info *denali = mtd_to_denali(mtd);
@@ -1470,7 +1140,7 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip,
        size_t size = denali->mtd.writesize + denali->mtd.oobsize;
 
        uint32_t irq_status = 0;
-       uint32_t irq_mask = INTR_STATUS0__DMA_CMD_COMP | 
+       uint32_t irq_mask = INTR_STATUS0__DMA_CMD_COMP |
                                                INTR_STATUS0__PROGRAM_FAIL;
 
        /* if it is a raw xfer, we want to disable ecc, and send
@@ -1483,74 +1153,73 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip,
        /* copy buffer into DMA buffer */
        memcpy(denali->buf.buf, buf, mtd->writesize);
 
-       if (raw_xfer)
-       {
+       if (raw_xfer) {
                /* transfer the data to the spare area */
-               memcpy(denali->buf.buf + mtd->writesize, 
-                       chip->oob_poi, 
-                       mtd->oobsize); 
+               memcpy(denali->buf.buf + mtd->writesize,
+                       chip->oob_poi,
+                       mtd->oobsize);
        }
 
        pci_dma_sync_single_for_device(pci_dev, addr, size, PCI_DMA_TODEVICE);
 
        clear_interrupts(denali);
-       denali_enable_dma(denali, true);        
+       denali_enable_dma(denali, true);
 
        denali_setup_dma(denali, DENALI_WRITE);
 
        /* wait for operation to complete */
        irq_status = wait_for_irq(denali, irq_mask);
 
-       if (irq_status == 0)
-       {
-               printk(KERN_ERR "timeout on write_page (type = %d)\n", raw_xfer);
-               denali->status = 
-                  (irq_status & INTR_STATUS0__PROGRAM_FAIL) ? NAND_STATUS_FAIL : 
-                                                            PASS;
+       if (irq_status == 0) {
+               printk(KERN_ERR "timeout on write_page"
+                               " (type = %d)\n", raw_xfer);
+               denali->status =
+                       (irq_status & INTR_STATUS0__PROGRAM_FAIL) ?
+                       NAND_STATUS_FAIL : PASS;
        }
 
-       denali_enable_dma(denali, false);       
+       denali_enable_dma(denali, false);
        pci_dma_sync_single_for_cpu(pci_dev, addr, size, PCI_DMA_TODEVICE);
 }
 
 /* NAND core entry points */
 
-/* this is the callback that the NAND core calls to write a page. Since 
-   writing a page with ECC or without is similar, all the work is done 
+/* this is the callback that the NAND core calls to write a page. Since
+   writing a page with ECC or without is similar, all the work is done
    by write_page above.   */
-static void denali_write_page(struct mtd_info *mtd, struct nand_chip *chip, 
+static void denali_write_page(struct mtd_info *mtd, struct nand_chip *chip,
                                const uint8_t *buf)
 {
        /* for regular page writes, we let HW handle all the ECC
-         * data written to the device. */
+        * data written to the device. */
        write_page(mtd, chip, buf, false);
 }
 
-/* This is the callback that the NAND core calls to write a page without ECC. 
+/* This is the callback that the NAND core calls to write a page without ECC.
    raw access is similiar to ECC page writes, so all the work is done in the
-   write_page() function above. 
+   write_page() function above.
  */
-static void denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, 
+static void denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
                                        const uint8_t *buf)
 {
-       /* for raw page writes, we want to disable ECC and simply write 
+       /* for raw page writes, we want to disable ECC and simply write
           whatever data is in the buffer. */
        write_page(mtd, chip, buf, true);
 }
 
-static int denali_write_oob(struct mtd_info *mtd, struct nand_chip *chip, 
+static int denali_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
                            int page)
 {
-       return write_oob_data(mtd, chip->oob_poi, page);        
+       return write_oob_data(mtd, chip->oob_poi, page);
 }
 
-static int denali_read_oob(struct mtd_info *mtd, struct nand_chip *chip, 
+static int denali_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
                           int page, int sndcmd)
 {
        read_oob_data(mtd, chip->oob_poi, page);
 
-       return 0; /* notify NAND core to send command to 
-                   * NAND device. */
+       return 0; /* notify NAND core to send command to
+                          NAND device. */
 }
 
 static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
@@ -1563,7 +1232,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
        size_t size = denali->mtd.writesize + denali->mtd.oobsize;
 
        uint32_t irq_status = 0;
-       uint32_t irq_mask = INTR_STATUS0__ECC_TRANSACTION_DONE | 
+       uint32_t irq_mask = INTR_STATUS0__ECC_TRANSACTION_DONE |
                            INTR_STATUS0__ECC_ERR;
        bool check_erased_page = false;
 
@@ -1581,26 +1250,20 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
        pci_dma_sync_single_for_cpu(pci_dev, addr, size, PCI_DMA_FROMDEVICE);
 
        memcpy(buf, denali->buf.buf, mtd->writesize);
-       
+
        check_erased_page = handle_ecc(denali, buf, chip->oob_poi, irq_status);
        denali_enable_dma(denali, false);
 
-       if (check_erased_page)
-       {
+       if (check_erased_page) {
                read_oob_data(&denali->mtd, chip->oob_poi, denali->page);
 
                /* check ECC failures that may have occurred on erased pages */
-               if (check_erased_page)
-               {
+               if (check_erased_page) {
                        if (!is_erased(buf, denali->mtd.writesize))
-                       {
                                denali->mtd.ecc_stats.failed++;
-                       }
                        if (!is_erased(buf, denali->mtd.oobsize))
-                       {
                                denali->mtd.ecc_stats.failed++;
-                       }
-               }       
+               }
        }
        return 0;
 }
@@ -1616,7 +1279,7 @@ static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 
        uint32_t irq_status = 0;
        uint32_t irq_mask = INTR_STATUS0__DMA_CMD_COMP;
-                                               
+
        setup_ecc_for_xfer(denali, false, true);
        denali_enable_dma(denali, true);
 
@@ -1644,12 +1307,10 @@ static uint8_t denali_read_byte(struct mtd_info *mtd)
        uint8_t result = 0xff;
 
        if (denali->buf.head < denali->buf.tail)
-       {
                result = denali->buf.buf[denali->buf.head++];
-       }
 
 #if DEBUG_DENALI
-       printk("read byte -> 0x%02x\n", result);
+       printk(KERN_INFO "read byte -> 0x%02x\n", result);
 #endif
        return result;
 }
@@ -1658,7 +1319,7 @@ static void denali_select_chip(struct mtd_info *mtd, int chip)
 {
        struct denali_nand_info *denali = mtd_to_denali(mtd);
 #if DEBUG_DENALI
-       printk("denali select chip %d\n", chip);
+       printk(KERN_INFO "denali select chip %d\n", chip);
 #endif
        spin_lock_irq(&denali->irq_lock);
        denali->flash_bank = chip;
@@ -1672,7 +1333,7 @@ static int denali_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
        denali->status = 0;
 
 #if DEBUG_DENALI
-       printk("waitfunc %d\n", status);
+       printk(KERN_INFO "waitfunc %d\n", status);
 #endif
        return status;
 }
@@ -1684,76 +1345,74 @@ static void denali_erase(struct mtd_info *mtd, int page)
        uint32_t cmd = 0x0, irq_status = 0;
 
 #if DEBUG_DENALI
-       printk("erase page: %d\n", page);
+       printk(KERN_INFO "erase page: %d\n", page);
 #endif
        /* clear interrupts */
-       clear_interrupts(denali);       
+       clear_interrupts(denali);
 
        /* setup page read request for access type */
        cmd = MODE_10 | BANK(denali->flash_bank) | page;
        index_addr(denali, (uint32_t)cmd, 0x1);
 
        /* wait for erase to complete or failure to occur */
-       irq_status = wait_for_irq(denali, INTR_STATUS0__ERASE_COMP | 
+       irq_status = wait_for_irq(denali, INTR_STATUS0__ERASE_COMP |
                                        INTR_STATUS0__ERASE_FAIL);
 
-       denali->status = (irq_status & INTR_STATUS0__ERASE_FAIL) ? NAND_STATUS_FAIL : 
-                                                                PASS;
+       denali->status = (irq_status & INTR_STATUS0__ERASE_FAIL) ?
+                                               NAND_STATUS_FAIL : PASS;
 }
 
-static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col, 
+static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,
                           int page)
 {
        struct denali_nand_info *denali = mtd_to_denali(mtd);
+       uint32_t addr, id;
+       int i;
 
 #if DEBUG_DENALI
-       printk("cmdfunc: 0x%x %d %d\n", cmd, col, page);
+       printk(KERN_INFO "cmdfunc: 0x%x %d %d\n", cmd, col, page);
 #endif
-       switch (cmd)
-       { 
-               case NAND_CMD_PAGEPROG:
-                       break;
-               case NAND_CMD_STATUS:
-                       read_status(denali);
-                       break;
-               case NAND_CMD_READID:
-                       reset_buf(denali);
-                       if (denali->flash_bank < denali->total_used_banks)
-                       {
-                               /* write manufacturer information into nand 
-                                  buffer for NAND subsystem to fetch.
-                                */ 
-                               write_byte_to_buf(denali, denali->dev_info.wDeviceMaker);
-                               write_byte_to_buf(denali, denali->dev_info.wDeviceID);
-                               write_byte_to_buf(denali, denali->dev_info.bDeviceParam0);
-                               write_byte_to_buf(denali, denali->dev_info.bDeviceParam1);
-                               write_byte_to_buf(denali, denali->dev_info.bDeviceParam2);
-                       }
-                       else 
-                       {
-                               int i;
-                               for (i = 0; i < 5; i++) 
-                                       write_byte_to_buf(denali, 0xff);
-                       }
-                       break;
-               case NAND_CMD_READ0:
-               case NAND_CMD_SEQIN:
-                       denali->page = page;
-                       break;
-               case NAND_CMD_RESET:
-                       reset_bank(denali);
-                       break;
-               case NAND_CMD_READOOB:
-                       /* TODO: Read OOB data */
-                       break;
-               default:
-                       printk(KERN_ERR ": unsupported command received 0x%x\n", cmd);
-                       break;
+       switch (cmd) {
+       case NAND_CMD_PAGEPROG:
+               break;
+       case NAND_CMD_STATUS:
+               read_status(denali);
+               break;
+       case NAND_CMD_READID:
+               reset_buf(denali);
+               /*sometimes ManufactureId read from register is not right
+                * e.g. some of Micron MT29F32G08QAA MLC NAND chips
+                * So here we send READID cmd to NAND insteand
+                * */
+               addr = (uint32_t)MODE_11 | BANK(denali->flash_bank);
+               index_addr(denali, (uint32_t)addr | 0, 0x90);
+               index_addr(denali, (uint32_t)addr | 1, 0);
+               for (i = 0; i < 5; i++) {
+                       index_addr_read_data(denali,
+                                               (uint32_t)addr | 2,
+                                               &id);
+                       write_byte_to_buf(denali, id);
+               }
+               break;
+       case NAND_CMD_READ0:
+       case NAND_CMD_SEQIN:
+               denali->page = page;
+               break;
+       case NAND_CMD_RESET:
+               reset_bank(denali);
+               break;
+       case NAND_CMD_READOOB:
+               /* TODO: Read OOB data */
+               break;
+       default:
+               printk(KERN_ERR ": unsupported command"
+                               " received 0x%x\n", cmd);
+               break;
        }
 }
 
 /* stubs for ECC functions not used by the NAND core */
-static int denali_ecc_calculate(struct mtd_info *mtd, const uint8_t *data, 
+static int denali_ecc_calculate(struct mtd_info *mtd, const uint8_t *data,
                                uint8_t *ecc_code)
 {
        printk(KERN_ERR "denali_ecc_calculate called unexpectedly\n");
@@ -1761,7 +1420,7 @@ static int denali_ecc_calculate(struct mtd_info *mtd, const uint8_t *data,
        return -EIO;
 }
 
-static int denali_ecc_correct(struct mtd_info *mtd, uint8_t *data, 
+static int denali_ecc_correct(struct mtd_info *mtd, uint8_t *data,
                                uint8_t *read_ecc, uint8_t *calc_ecc)
 {
        printk(KERN_ERR "denali_ecc_correct called unexpectedly\n");
@@ -1779,10 +1438,18 @@ static void denali_ecc_hwctl(struct mtd_info *mtd, int mode)
 /* Initialization code to bring the device up to a known good state */
 static void denali_hw_init(struct denali_nand_info *denali)
 {
+       /* tell driver how many bit controller will skip before
+        * writing ECC code in OOB, this register may be already
+        * set by firmware. So we read this value out.
+        * if this value is 0, just let it be.
+        * */
+       denali->bbtskipbytes = ioread32(denali->flash_reg +
+                                               SPARE_AREA_SKIP_BYTES);
        denali_irq_init(denali);
-       NAND_Flash_Reset(denali);
+       denali_nand_reset(denali);
        denali_write32(0x0F, denali->flash_reg + RB_PIN_ENABLED);
-       denali_write32(CHIP_EN_DONT_CARE__FLAG, denali->flash_reg + CHIP_ENABLE_DONT_CARE);
+       denali_write32(CHIP_EN_DONT_CARE__FLAG,
+                       denali->flash_reg + CHIP_ENABLE_DONT_CARE);
 
        denali_write32(0x0, denali->flash_reg + SPARE_AREA_SKIP_BYTES);
        denali_write32(0xffff, denali->flash_reg + SPARE_AREA_MARKER);
@@ -1792,25 +1459,18 @@ static void denali_hw_init(struct denali_nand_info *denali)
        denali_write32(1, denali->flash_reg + ECC_ENABLE);
 }
 
-/* ECC layout for SLC devices. Denali spec indicates SLC fixed at 4 bytes */
-#define ECC_BYTES_SLC   4 * (2048 / ECC_SECTOR_SIZE)
-static struct nand_ecclayout nand_oob_slc = {
-       .eccbytes = 4,
-       .eccpos = { 0, 1, 2, 3 }, /* not used */
-       .oobfree = {{ 
-                       .offset = ECC_BYTES_SLC, 
-                       .length = 64 - ECC_BYTES_SLC  
-                  }}
+/* Althogh controller spec said SLC ECC is forceb to be 4bit,
+ * but denali controller in MRST only support 15bit and 8bit ECC
+ * correction
+ * */
+#define ECC_8BITS      14
+static struct nand_ecclayout nand_8bit_oob = {
+       .eccbytes = 14,
 };
 
-#define ECC_BYTES_MLC   14 * (2048 / ECC_SECTOR_SIZE)
-static struct nand_ecclayout nand_oob_mlc_14bit = {
-       .eccbytes = 14,
-       .eccpos = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13 }, /* not used */
-       .oobfree = {{ 
-                       .offset = ECC_BYTES_MLC, 
-                       .length = 64 - ECC_BYTES_MLC  
-                  }}
+#define ECC_15BITS     26
+static struct nand_ecclayout nand_15bit_oob = {
+       .eccbytes = 26,
 };
 
 static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
@@ -1842,12 +1502,12 @@ void denali_drv_init(struct denali_nand_info *denali)
        denali->idx = 0;
 
        /* setup interrupt handler */
-       /* the completion object will be used to notify 
+       /* the completion object will be used to notify
         * the callee that the interrupt is done */
        init_completion(&denali->complete);
 
        /* the spinlock will be used to synchronize the ISR
-        * with any element that might be access shared 
+        * with any element that might be access shared
         * data (interrupt status) */
        spin_lock_init(&denali->irq_lock);
 
@@ -1880,13 +1540,12 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
        }
 
        if (id->driver_data == INTEL_CE4100) {
-               /* Due to a silicon limitation, we can only support 
-                * ONFI timing mode 1 and below. 
-                */ 
-               if (onfi_timing_mode < -1 || onfi_timing_mode > 1)
-               {
-                       printk("Intel CE4100 only supports ONFI timing mode 1 "
-                               "or below\n");
+               /* Due to a silicon limitation, we can only support
+                * ONFI timing mode 1 and below.
+                */
+               if (onfi_timing_mode < -1 || onfi_timing_mode > 1) {
+                       printk(KERN_ERR "Intel CE4100 only supports"
+                                       " ONFI timing mode 1 or below\n");
                        ret = -EINVAL;
                        goto failed_enable;
                }
@@ -1905,7 +1564,9 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
                        mem_base = csr_base + csr_len;
                        mem_len = csr_len;
                        nand_dbg_print(NAND_DBG_WARN,
-                                      "Spectra: No second BAR for PCI device; assuming %08Lx\n",
+                                      "Spectra: No second"
+                                          " BAR for PCI device;"
+                                          " assuming %08Lx\n",
                                       (uint64_t)csr_base);
                }
        }
@@ -1913,16 +1574,16 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
        /* Is 32-bit DMA supported? */
        ret = pci_set_dma_mask(dev, DMA_BIT_MASK(32));
 
-       if (ret)
-       {
+       if (ret) {
                printk(KERN_ERR "Spectra: no usable DMA configuration\n");
                goto failed_enable;
        }
-       denali->buf.dma_buf = pci_map_single(dev, denali->buf.buf, DENALI_BUF_SIZE, 
-                                        PCI_DMA_BIDIRECTIONAL);
+       denali->buf.dma_buf =
+               pci_map_single(dev, denali->buf.buf,
+                                               DENALI_BUF_SIZE,
+                                               PCI_DMA_BIDIRECTIONAL);
 
-       if (pci_dma_mapping_error(dev, denali->buf.dma_buf))
-       {
+       if (pci_dma_mapping_error(dev, denali->buf.dma_buf)) {
                printk(KERN_ERR "Spectra: failed to map DMA buffer\n");
                goto failed_enable;
        }
@@ -1970,22 +1631,11 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
        }
 
        /* now that our ISR is registered, we can enable interrupts */
-       NAND_LLD_Enable_Disable_Interrupts(denali, true);
+       denali_set_intr_modes(denali, true);
 
        pci_set_drvdata(dev, denali);
 
-       NAND_Read_Device_ID(denali);
-
-       /* MTD supported page sizes vary by kernel. We validate our 
-           kernel supports the device here.
-        */
-       if (denali->dev_info.wPageSize > NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE)
-       {
-               ret = -ENODEV;
-               printk(KERN_ERR "Spectra: device size not supported by this "
-                       "version of MTD.");
-               goto failed_nand;
-       }
+       denali_nand_timing_set(denali);
 
        nand_dbg_print(NAND_DBG_DEBUG, "Dump timing register values:"
                        "acc_clks: %d, re_2_we: %d, we_2_re: %d,"
@@ -2009,18 +1659,46 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
        denali->nand.read_byte = denali_read_byte;
        denali->nand.waitfunc = denali_waitfunc;
 
-       /* scan for NAND devices attached to the controller 
+       /* scan for NAND devices attached to the controller
         * this is the first stage in a two step process to register
-        * with the nand subsystem */   
-       if (nand_scan_ident(&denali->mtd, LLD_MAX_FLASH_BANKS, NULL))
-       {
+        * with the nand subsystem */
+       if (nand_scan_ident(&denali->mtd, LLD_MAX_FLASH_BANKS, NULL)) {
                ret = -ENXIO;
                goto failed_nand;
        }
-       
-       /* second stage of the NAND scan 
-        * this stage requires information regarding ECC and 
-         * bad block management. */
+
+       /* MTD supported page sizes vary by kernel. We validate our
+        * kernel supports the device here.
+        */
+       if (denali->mtd.writesize > NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) {
+               ret = -ENODEV;
+               printk(KERN_ERR "Spectra: device size not supported by this "
+                       "version of MTD.");
+               goto failed_nand;
+       }
+
+       /* support for multi nand
+        * MTD known nothing about multi nand,
+        * so we should tell it the real pagesize
+        * and anything necessery
+        */
+       denali->devnum = ioread32(denali->flash_reg + DEVICES_CONNECTED);
+       denali->nand.chipsize <<= (denali->devnum - 1);
+       denali->nand.page_shift += (denali->devnum - 1);
+       denali->nand.pagemask = (denali->nand.chipsize >>
+                                               denali->nand.page_shift) - 1;
+       denali->nand.bbt_erase_shift += (denali->devnum - 1);
+       denali->nand.phys_erase_shift = denali->nand.bbt_erase_shift;
+       denali->nand.chip_shift += (denali->devnum - 1);
+       denali->mtd.writesize <<= (denali->devnum - 1);
+       denali->mtd.oobsize <<= (denali->devnum - 1);
+       denali->mtd.erasesize <<= (denali->devnum - 1);
+       denali->mtd.size = denali->nand.numchips * denali->nand.chipsize;
+       denali->bbtskipbytes *= denali->devnum;
+
+       /* second stage of the NAND scan
+        * this stage requires information regarding ECC and
+        * bad block management. */
 
        /* Bad block management */
        denali->nand.bbt_td = &bbt_main_descr;
@@ -2030,26 +1708,57 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
        denali->nand.options |= NAND_USE_FLASH_BBT | NAND_SKIP_BBTSCAN;
        denali->nand.ecc.mode = NAND_ECC_HW_SYNDROME;
 
-       if (denali->dev_info.MLCDevice)
-       {
-               denali->nand.ecc.layout = &nand_oob_mlc_14bit;
-               denali->nand.ecc.bytes = ECC_BYTES_MLC;
-       }
-       else /* SLC */
-       {
-               denali->nand.ecc.layout = &nand_oob_slc;
-               denali->nand.ecc.bytes = ECC_BYTES_SLC;
+       /* Denali Controller only support 15bit and 8bit ECC in MRST,
+        * so just let controller do 15bit ECC for MLC and 8bit ECC for
+        * SLC if possible.
+        * */
+       if (denali->nand.cellinfo & 0xc &&
+                       (denali->mtd.oobsize > (denali->bbtskipbytes +
+                       ECC_15BITS * (denali->mtd.writesize /
+                       ECC_SECTOR_SIZE)))) {
+               /* if MLC OOB size is large enough, use 15bit ECC*/
+               denali->nand.ecc.layout = &nand_15bit_oob;
+               denali->nand.ecc.bytes = ECC_15BITS;
+               denali_write32(15, denali->flash_reg + ECC_CORRECTION);
+       } else if (denali->mtd.oobsize < (denali->bbtskipbytes +
+                       ECC_8BITS * (denali->mtd.writesize /
+                       ECC_SECTOR_SIZE))) {
+               printk(KERN_ERR "Your NAND chip OOB is not large enough to"
+                               " contain 8bit ECC correction codes");
+               goto failed_nand;
+       } else {
+               denali->nand.ecc.layout = &nand_8bit_oob;
+               denali->nand.ecc.bytes = ECC_8BITS;
+               denali_write32(8, denali->flash_reg + ECC_CORRECTION);
        }
 
-       /* These functions are required by the NAND core framework, otherwise, 
-           the NAND core will assert. However, we don't need them, so we'll stub 
-           them out. */
+       denali->nand.ecc.bytes *= denali->devnum;
+       denali->nand.ecc.layout->eccbytes *=
+               denali->mtd.writesize / ECC_SECTOR_SIZE;
+       denali->nand.ecc.layout->oobfree[0].offset =
+               denali->bbtskipbytes + denali->nand.ecc.layout->eccbytes;
+       denali->nand.ecc.layout->oobfree[0].length =
+               denali->mtd.oobsize - denali->nand.ecc.layout->eccbytes -
+               denali->bbtskipbytes;
+
+       /* Let driver know the total blocks number and
+        * how many blocks contained by each nand chip.
+        * blksperchip will help driver to know how many
+        * blocks is taken by FW.
+        * */
+       denali->totalblks = denali->mtd.size >>
+                               denali->nand.phys_erase_shift;
+       denali->blksperchip = denali->totalblks / denali->nand.numchips;
+
+       /* These functions are required by the NAND core framework, otherwise,
+        * the NAND core will assert. However, we don't need them, so we'll stub
+        * them out. */
        denali->nand.ecc.calculate = denali_ecc_calculate;
        denali->nand.ecc.correct = denali_ecc_correct;
        denali->nand.ecc.hwctl = denali_ecc_hwctl;
 
        /* override the default read operations */
-       denali->nand.ecc.size = denali->mtd.writesize;
+       denali->nand.ecc.size = ECC_SECTOR_SIZE * denali->devnum;
        denali->nand.ecc.read_page = denali_read_page;
        denali->nand.ecc.read_page_raw = denali_read_page_raw;
        denali->nand.ecc.write_page = denali_write_page;
@@ -2058,15 +1767,15 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
        denali->nand.ecc.write_oob = denali_write_oob;
        denali->nand.erase_cmd = denali_erase;
 
-       if (nand_scan_tail(&denali->mtd))
-       {
+       if (nand_scan_tail(&denali->mtd)) {
                ret = -ENXIO;
                goto failed_nand;
        }
 
        ret = add_mtd_device(&denali->mtd);
        if (ret) {
-               printk(KERN_ERR "Spectra: Failed to register MTD device: %d\n", ret);
+               printk(KERN_ERR "Spectra: Failed to register"
+                               " MTD device: %d\n", ret);
                goto failed_nand;
        }
        return 0;
@@ -2079,7 +1788,7 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
  failed_remap_csr:
        pci_release_regions(dev);
  failed_req_csr:
-       pci_unmap_single(dev, denali->buf.dma_buf, DENALI_BUF_SIZE, 
+       pci_unmap_single(dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
                                                        PCI_DMA_BIDIRECTIONAL);
  failed_enable:
        kfree(denali);
@@ -2103,7 +1812,7 @@ static void denali_pci_remove(struct pci_dev *dev)
        iounmap(denali->flash_mem);
        pci_release_regions(dev);
        pci_disable_device(dev);
-       pci_unmap_single(dev, denali->buf.dma_buf, DENALI_BUF_SIZE, 
+       pci_unmap_single(dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
                                                        PCI_DMA_BIDIRECTIONAL);
        pci_set_drvdata(dev, NULL);
        kfree(denali);
@@ -2120,7 +1829,8 @@ static struct pci_driver denali_pci_driver = {
 
 static int __devinit denali_init(void)
 {
-       printk(KERN_INFO "Spectra MTD driver built on %s @ %s\n", __DATE__, __TIME__);
+       printk(KERN_INFO "Spectra MTD driver built on %s @ %s\n",
+                       __DATE__, __TIME__);
        return pci_register_driver(&denali_pci_driver);
 }
 
index 422a29ab2f60f08f70d38d9e9e1e37a9b10ec0cd..b680474e6333ffe1e79696141c40179a1de38853 100644 (file)
@@ -17,7 +17,7 @@
  *
  */
 
-#include <linux/mtd/nand.h> 
+#include <linux/mtd/nand.h>
 
 #define DEVICE_RESET                           0x0
 #define     DEVICE_RESET__BANK0                                0x0001
@@ -29,7 +29,7 @@
 #define     TRANSFER_SPARE_REG__FLAG                   0x0001
 
 #define LOAD_WAIT_CNT                          0x20
-#define     LOAD_WAIT_CNT__VALUE                               0xffff
+#define     LOAD_WAIT_CNT__VALUE                       0xffff
 
 #define PROGRAM_WAIT_CNT                       0x30
 #define     PROGRAM_WAIT_CNT__VALUE                    0xffff
@@ -83,7 +83,7 @@
 #define RE_2_WE                                        0x120
 #define     RE_2_WE__VALUE                             0x003f
 
-#define ACC_CLKS                               0x130
+#define ACC_CLKS                               0x130
 #define     ACC_CLKS__VALUE                            0x000f
 
 #define NUMBER_OF_PLANES                       0x140
 #define DEVICES_CONNECTED                      0x250
 #define     DEVICES_CONNECTED__VALUE                   0x0007
 
-#define DIE_MASK                                       0x260
+#define DIE_MASK                               0x260
 #define     DIE_MASK__VALUE                            0x00ff
 
 #define FIRST_BLOCK_OF_NEXT_PLANE              0x270
 #define RE_2_RE                                        0x290
 #define     RE_2_RE__VALUE                             0x003f
 
-#define MANUFACTURER_ID                        0x300
+#define MANUFACTURER_ID                                0x300
 #define     MANUFACTURER_ID__VALUE                     0x00ff
 
 #define DEVICE_ID                              0x310
 #define LOGICAL_PAGE_SPARE_SIZE                        0x360
 #define     LOGICAL_PAGE_SPARE_SIZE__VALUE             0xffff
 
-#define REVISION                                       0x370
+#define REVISION                               0x370
 #define     REVISION__VALUE                            0xffff
 
 #define ONFI_DEVICE_FEATURES                   0x380
 #define     ONFI_DEVICE_FEATURES__VALUE                        0x003f
 
-#define ONFI_OPTIONAL_COMMANDS         0x390
+#define ONFI_OPTIONAL_COMMANDS                 0x390
 #define     ONFI_OPTIONAL_COMMANDS__VALUE              0x003f
 
 #define ONFI_TIMING_MODE                       0x3a0
 #define FEATURES                                       0x3f0
 #define     FEATURES__N_BANKS                          0x0003
 #define     FEATURES__ECC_MAX_ERR                      0x003c
-#define     FEATURES__DMA                                      0x0040
+#define     FEATURES__DMA                              0x0040
 #define     FEATURES__CMD_DMA                          0x0080
 #define     FEATURES__PARTITION                                0x0100
 #define     FEATURES__XDMA_SIDEBAND                    0x0200
 #define     FEATURES__GPREG                            0x0400
-#define     FEATURES__INDEX_ADDR                               0x0800
+#define     FEATURES__INDEX_ADDR                       0x0800
 
 #define TRANSFER_MODE                          0x400
 #define     TRANSFER_MODE__VALUE                       0x0003
 #define     INTR_EN0__DMA_CMD_COMP                     0x0004
 #define     INTR_EN0__TIME_OUT                         0x0008
 #define     INTR_EN0__PROGRAM_FAIL                     0x0010
-#define     INTR_EN0__ERASE_FAIL                               0x0020
+#define     INTR_EN0__ERASE_FAIL                       0x0020
 #define     INTR_EN0__LOAD_COMP                                0x0040
 #define     INTR_EN0__PROGRAM_COMP                     0x0080
-#define     INTR_EN0__ERASE_COMP                               0x0100
+#define     INTR_EN0__ERASE_COMP                       0x0100
 #define     INTR_EN0__PIPE_CPYBCK_CMD_COMP             0x0200
-#define     INTR_EN0__LOCKED_BLK                               0x0400
+#define     INTR_EN0__LOCKED_BLK                       0x0400
 #define     INTR_EN0__UNSUP_CMD                                0x0800
 #define     INTR_EN0__INT_ACT                          0x1000
 #define     INTR_EN0__RST_COMP                         0x2000
 #define ERR_PAGE_ADDR0                         0x440
 #define     ERR_PAGE_ADDR0__VALUE                      0xffff
 
-#define ERR_BLOCK_ADDR0                        0x450
+#define ERR_BLOCK_ADDR0                                0x450
 #define     ERR_BLOCK_ADDR0__VALUE                     0xffff
 
 #define INTR_STATUS1                           0x460
 #define     INTR_EN1__DMA_CMD_COMP                     0x0004
 #define     INTR_EN1__TIME_OUT                         0x0008
 #define     INTR_EN1__PROGRAM_FAIL                     0x0010
-#define     INTR_EN1__ERASE_FAIL                               0x0020
+#define     INTR_EN1__ERASE_FAIL                       0x0020
 #define     INTR_EN1__LOAD_COMP                                0x0040
 #define     INTR_EN1__PROGRAM_COMP                     0x0080
-#define     INTR_EN1__ERASE_COMP                               0x0100
+#define     INTR_EN1__ERASE_COMP                       0x0100
 #define     INTR_EN1__PIPE_CPYBCK_CMD_COMP             0x0200
-#define     INTR_EN1__LOCKED_BLK                               0x0400
+#define     INTR_EN1__LOCKED_BLK                       0x0400
 #define     INTR_EN1__UNSUP_CMD                                0x0800
 #define     INTR_EN1__INT_ACT                          0x1000
 #define     INTR_EN1__RST_COMP                         0x2000
 #define ERR_PAGE_ADDR1                         0x490
 #define     ERR_PAGE_ADDR1__VALUE                      0xffff
 
-#define ERR_BLOCK_ADDR1                        0x4a0
+#define ERR_BLOCK_ADDR1                                0x4a0
 #define     ERR_BLOCK_ADDR1__VALUE                     0xffff
 
 #define INTR_STATUS2                           0x4b0
 #define     INTR_EN2__DMA_CMD_COMP                     0x0004
 #define     INTR_EN2__TIME_OUT                         0x0008
 #define     INTR_EN2__PROGRAM_FAIL                     0x0010
-#define     INTR_EN2__ERASE_FAIL                               0x0020
+#define     INTR_EN2__ERASE_FAIL                       0x0020
 #define     INTR_EN2__LOAD_COMP                                0x0040
 #define     INTR_EN2__PROGRAM_COMP                     0x0080
-#define     INTR_EN2__ERASE_COMP                               0x0100
+#define     INTR_EN2__ERASE_COMP                       0x0100
 #define     INTR_EN2__PIPE_CPYBCK_CMD_COMP             0x0200
-#define     INTR_EN2__LOCKED_BLK                               0x0400
+#define     INTR_EN2__LOCKED_BLK                       0x0400
 #define     INTR_EN2__UNSUP_CMD                                0x0800
 #define     INTR_EN2__INT_ACT                          0x1000
 #define     INTR_EN2__RST_COMP                         0x2000
 #define ERR_PAGE_ADDR2                         0x4e0
 #define     ERR_PAGE_ADDR2__VALUE                      0xffff
 
-#define ERR_BLOCK_ADDR2                        0x4f0
+#define ERR_BLOCK_ADDR2                                0x4f0
 #define     ERR_BLOCK_ADDR2__VALUE                     0xffff
 
 #define INTR_STATUS3                           0x500
 #define     INTR_EN3__DMA_CMD_COMP                     0x0004
 #define     INTR_EN3__TIME_OUT                         0x0008
 #define     INTR_EN3__PROGRAM_FAIL                     0x0010
-#define     INTR_EN3__ERASE_FAIL                               0x0020
+#define     INTR_EN3__ERASE_FAIL                       0x0020
 #define     INTR_EN3__LOAD_COMP                                0x0040
 #define     INTR_EN3__PROGRAM_COMP                     0x0080
-#define     INTR_EN3__ERASE_COMP                               0x0100
+#define     INTR_EN3__ERASE_COMP                       0x0100
 #define     INTR_EN3__PIPE_CPYBCK_CMD_COMP             0x0200
-#define     INTR_EN3__LOCKED_BLK                               0x0400
+#define     INTR_EN3__LOCKED_BLK                       0x0400
 #define     INTR_EN3__UNSUP_CMD                                0x0800
 #define     INTR_EN3__INT_ACT                          0x1000
 #define     INTR_EN3__RST_COMP                         0x2000
 #define ERR_PAGE_ADDR3                         0x530
 #define     ERR_PAGE_ADDR3__VALUE                      0xffff
 
-#define ERR_BLOCK_ADDR3                        0x540
+#define ERR_BLOCK_ADDR3                                0x540
 #define     ERR_BLOCK_ADDR3__VALUE                     0xffff
 
 #define DATA_INTR                              0x550
 #define     GPREG_3__VALUE                             0xffff
 
 #define ECC_THRESHOLD                          0x600
-#define     ECC_THRESHOLD__VALUE                               0x03ff
+#define     ECC_THRESHOLD__VALUE                       0x03ff
 
-#define ECC_ERROR_BLOCK_ADDRESS                0x610
+#define ECC_ERROR_BLOCK_ADDRESS                        0x610
 #define     ECC_ERROR_BLOCK_ADDRESS__VALUE             0xffff
 
 #define ECC_ERROR_PAGE_ADDRESS                 0x620
 #define     CHNL_ACTIVE__CHANNEL3                      0x0008
 
 #define ACTIVE_SRC_ID                          0x800
-#define     ACTIVE_SRC_ID__VALUE                               0x00ff
+#define     ACTIVE_SRC_ID__VALUE                       0x00ff
 
 #define PTN_INTR                                       0x810
 #define     PTN_INTR__CONFIG_ERROR                     0x0001
 #define     PTN_INTR_EN__REG_ACCESS_ERROR              0x0020
 
 #define PERM_SRC_ID_0                          0x830
-#define     PERM_SRC_ID_0__SRCID                               0x00ff
+#define     PERM_SRC_ID_0__SRCID                       0x00ff
 #define     PERM_SRC_ID_0__DIRECT_ACCESS_ACTIVE                0x0800
 #define     PERM_SRC_ID_0__WRITE_ACTIVE                        0x2000
 #define     PERM_SRC_ID_0__READ_ACTIVE                 0x4000
 #define     MIN_MAX_BANK_0__MAX_VALUE                  0x000c
 
 #define PERM_SRC_ID_1                          0x870
-#define     PERM_SRC_ID_1__SRCID                               0x00ff
+#define     PERM_SRC_ID_1__SRCID                       0x00ff
 #define     PERM_SRC_ID_1__DIRECT_ACCESS_ACTIVE                0x0800
 #define     PERM_SRC_ID_1__WRITE_ACTIVE                        0x2000
 #define     PERM_SRC_ID_1__READ_ACTIVE                 0x4000
 #define     MIN_MAX_BANK_1__MAX_VALUE                  0x000c
 
 #define PERM_SRC_ID_2                          0x8b0
-#define     PERM_SRC_ID_2__SRCID                               0x00ff
+#define     PERM_SRC_ID_2__SRCID                       0x00ff
 #define     PERM_SRC_ID_2__DIRECT_ACCESS_ACTIVE                0x0800
 #define     PERM_SRC_ID_2__WRITE_ACTIVE                        0x2000
 #define     PERM_SRC_ID_2__READ_ACTIVE                 0x4000
 #define     MIN_MAX_BANK_2__MAX_VALUE                  0x000c
 
 #define PERM_SRC_ID_3                          0x8f0
-#define     PERM_SRC_ID_3__SRCID                               0x00ff
+#define     PERM_SRC_ID_3__SRCID                       0x00ff
 #define     PERM_SRC_ID_3__DIRECT_ACCESS_ACTIVE                0x0800
 #define     PERM_SRC_ID_3__WRITE_ACTIVE                        0x2000
 #define     PERM_SRC_ID_3__READ_ACTIVE                 0x4000
 #define     MIN_MAX_BANK_3__MAX_VALUE                  0x000c
 
 #define PERM_SRC_ID_4                          0x930
-#define     PERM_SRC_ID_4__SRCID                               0x00ff
+#define     PERM_SRC_ID_4__SRCID                       0x00ff
 #define     PERM_SRC_ID_4__DIRECT_ACCESS_ACTIVE                0x0800
 #define     PERM_SRC_ID_4__WRITE_ACTIVE                        0x2000
 #define     PERM_SRC_ID_4__READ_ACTIVE                 0x4000
 #define     MIN_MAX_BANK_4__MAX_VALUE                  0x000c
 
 #define PERM_SRC_ID_5                          0x970
-#define     PERM_SRC_ID_5__SRCID                               0x00ff
+#define     PERM_SRC_ID_5__SRCID                       0x00ff
 #define     PERM_SRC_ID_5__DIRECT_ACCESS_ACTIVE                0x0800
 #define     PERM_SRC_ID_5__WRITE_ACTIVE                        0x2000
 #define     PERM_SRC_ID_5__READ_ACTIVE                 0x4000
 #define     MIN_MAX_BANK_5__MAX_VALUE                  0x000c
 
 #define PERM_SRC_ID_6                          0x9b0
-#define     PERM_SRC_ID_6__SRCID                               0x00ff
+#define     PERM_SRC_ID_6__SRCID                       0x00ff
 #define     PERM_SRC_ID_6__DIRECT_ACCESS_ACTIVE                0x0800
 #define     PERM_SRC_ID_6__WRITE_ACTIVE                        0x2000
 #define     PERM_SRC_ID_6__READ_ACTIVE                 0x4000
 #define     MIN_MAX_BANK_6__MAX_VALUE                  0x000c
 
 #define PERM_SRC_ID_7                          0x9f0
-#define     PERM_SRC_ID_7__SRCID                               0x00ff
+#define     PERM_SRC_ID_7__SRCID                       0x00ff
 #define     PERM_SRC_ID_7__DIRECT_ACCESS_ACTIVE                0x0800
 #define     PERM_SRC_ID_7__WRITE_ACTIVE                        0x2000
 #define     PERM_SRC_ID_7__READ_ACTIVE                 0x4000
 #define     MIN_MAX_BANK_7__MIN_VALUE                  0x0003
 #define     MIN_MAX_BANK_7__MAX_VALUE                  0x000c
 
-/* flash.h */
-struct device_info_tag {
-        uint16_t wDeviceMaker;
-        uint16_t wDeviceID;
-       uint8_t  bDeviceParam0;
-       uint8_t  bDeviceParam1;
-       uint8_t  bDeviceParam2;
-        uint32_t wDeviceType;
-        uint32_t wSpectraStartBlock;
-        uint32_t wSpectraEndBlock;
-        uint32_t wTotalBlocks;
-        uint16_t wPagesPerBlock;
-        uint16_t wPageSize;
-        uint16_t wPageDataSize;
-        uint16_t wPageSpareSize;
-        uint16_t wNumPageSpareFlag;
-        uint16_t wECCBytesPerSector;
-        uint32_t wBlockSize;
-        uint32_t wBlockDataSize;
-        uint32_t wDataBlockNum;
-        uint8_t bPlaneNum;
-        uint16_t wDeviceMainAreaSize;
-        uint16_t wDeviceSpareAreaSize;
-        uint16_t wDevicesConnected;
-        uint16_t wDeviceWidth;
-        uint16_t wHWRevision;
-        uint16_t wHWFeatures;
-
-        uint16_t wONFIDevFeatures;
-        uint16_t wONFIOptCommands;
-        uint16_t wONFITimingMode;
-        uint16_t wONFIPgmCacheTimingMode;
-
-        uint16_t MLCDevice;
-        uint16_t wSpareSkipBytes;
-
-        uint8_t nBitsInPageNumber;
-        uint8_t nBitsInPageDataSize;
-        uint8_t nBitsInBlockDataSize;
-};
-
 /* ffsdefs.h */
 #define CLEAR 0                 /*use this to clear a field instead of "fail"*/
 #define SET   1                 /*use this to set a field instead of "pass"*/
@@ -684,11 +643,11 @@ struct device_info_tag {
 #define NAND_DBG_TRACE 3
 
 #ifdef VERBOSE
-#define nand_dbg_print(level, args...)                  \
-        do {                                            \
-                if (level <= nand_debug_level)          \
-                        printk(KERN_ALERT args);        \
-        } while (0)
+#define nand_dbg_print(level, args...)                         \
+       do {                                                    \
+                       if (level <= nand_debug_level)          \
+                               printk(KERN_ALERT args);        \
+       } while (0)
 #else
 #define nand_dbg_print(level, args...)
 #endif
@@ -772,10 +731,9 @@ struct device_info_tag {
 #define ECC_SECTOR_SIZE     512
 #define LLD_MAX_FLASH_BANKS     4
 
-#define DENALI_BUF_SIZE                NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE
+#define DENALI_BUF_SIZE                (NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE)
 
-struct nand_buf
-{
+struct nand_buf {
        int head;
        int tail;
        uint8_t buf[DENALI_BUF_SIZE];
@@ -788,7 +746,6 @@ struct nand_buf
 struct denali_nand_info {
        struct mtd_info mtd;
        struct nand_chip nand;
-       struct device_info_tag dev_info;
        int flash_bank; /* currently selected chip */
        int status;
        int platform;
@@ -806,11 +763,12 @@ struct denali_nand_info {
        uint32_t irq_status;
        int irq_debug_array[32];
        int idx;
-};
 
-static uint16_t  NAND_Flash_Reset(struct denali_nand_info *denali);
-static uint16_t  NAND_Read_Device_ID(struct denali_nand_info *denali);
-static void NAND_LLD_Enable_Disable_Interrupts(struct denali_nand_info *denali, uint16_t INT_ENABLE);
+       uint32_t devnum;        /* represent how many nands connected */
+       uint32_t fwblks; /* represent how many blocks FW used */
+       uint32_t totalblks;
+       uint32_t blksperchip;
+       uint32_t bbtskipbytes;
+};
 
 #endif /*_LLD_NAND_*/
-
index 47067bc98248bec58f547e72d89713961ff89983..b7f8de7b27801d96906e10438e7e6fcb9ca833d9 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/doc2000.h>
-#include <linux/mtd/compatmac.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/inftl.h>
 
@@ -146,6 +145,7 @@ static int doc_ecc_decode(struct rs_control *rs, uint8_t *data, uint8_t *ecc)
        uint8_t parity;
        uint16_t ds[4], s[5], tmp, errval[8], syn[4];
 
+       memset(syn, 0, sizeof(syn));
        /* Convert the ecc bytes into words */
        ds[0] = ((ecc[4] & 0xff) >> 0) | ((ecc[5] & 0x03) << 8);
        ds[1] = ((ecc[5] & 0xfc) >> 2) | ((ecc[2] & 0x0f) << 6);
@@ -169,9 +169,9 @@ static int doc_ecc_decode(struct rs_control *rs, uint8_t *data, uint8_t *ecc)
                        s[i] ^= rs->alpha_to[rs_modnn(rs, tmp + (FCR + i) * j)];
        }
 
-       /* Calc s[i] = s[i] / alpha^(v + i) */
+       /* Calc syn[i] = s[i] / alpha^(v + i) */
        for (i = 0; i < NROOTS; i++) {
-               if (syn[i])
+               if (s[i])
                        syn[i] = rs_modnn(rs, rs->index_of[s[i]] + (NN - FCR - i));
        }
        /* Call the decoder library */
index 0d76b169482f47afff1bbb4f09696c771e3f829e..fcf8ceb277d44cd3e78b5c5e0249ec1b40d7ab33 100644 (file)
 
 #define nfc_is_v21()           (cpu_is_mx25() || cpu_is_mx35())
 #define nfc_is_v1()            (cpu_is_mx31() || cpu_is_mx27() || cpu_is_mx21())
+#define nfc_is_v3_2()          cpu_is_mx51()
+#define nfc_is_v3()            nfc_is_v3_2()
 
 /* Addresses for NFC registers */
-#define NFC_BUF_SIZE           0xE00
-#define NFC_BUF_ADDR           0xE04
-#define NFC_FLASH_ADDR         0xE06
-#define NFC_FLASH_CMD          0xE08
-#define NFC_CONFIG             0xE0A
-#define NFC_ECC_STATUS_RESULT  0xE0C
-#define NFC_RSLTMAIN_AREA      0xE0E
-#define NFC_RSLTSPARE_AREA     0xE10
-#define NFC_WRPROT             0xE12
-#define NFC_V1_UNLOCKSTART_BLKADDR     0xe14
-#define NFC_V1_UNLOCKEND_BLKADDR       0xe16
-#define NFC_V21_UNLOCKSTART_BLKADDR    0xe20
-#define NFC_V21_UNLOCKEND_BLKADDR      0xe22
-#define NFC_NF_WRPRST          0xE18
-#define NFC_CONFIG1            0xE1A
-#define NFC_CONFIG2            0xE1C
-
-/* Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register
- * for Command operation */
-#define NFC_CMD            0x1
-
-/* Set INT to 0, FADD to 1, rest to 0 in NFC_CONFIG2 Register
- * for Address operation */
-#define NFC_ADDR           0x2
-
-/* Set INT to 0, FDI to 1, rest to 0 in NFC_CONFIG2 Register
- * for Input operation */
-#define NFC_INPUT          0x4
-
-/* Set INT to 0, FDO to 001, rest to 0 in NFC_CONFIG2 Register
- * for Data Output operation */
-#define NFC_OUTPUT         0x8
-
-/* Set INT to 0, FD0 to 010, rest to 0 in NFC_CONFIG2 Register
- * for Read ID operation */
-#define NFC_ID             0x10
-
-/* Set INT to 0, FDO to 100, rest to 0 in NFC_CONFIG2 Register
- * for Read Status operation */
-#define NFC_STATUS         0x20
-
-/* Set INT to 1, rest to 0 in NFC_CONFIG2 Register for Read
- * Status operation */
-#define NFC_INT            0x8000
-
-#define NFC_SP_EN           (1 << 2)
-#define NFC_ECC_EN          (1 << 3)
-#define NFC_INT_MSK         (1 << 4)
-#define NFC_BIG             (1 << 5)
-#define NFC_RST             (1 << 6)
-#define NFC_CE              (1 << 7)
-#define NFC_ONE_CYCLE       (1 << 8)
+#define NFC_V1_V2_BUF_SIZE             (host->regs + 0x00)
+#define NFC_V1_V2_BUF_ADDR             (host->regs + 0x04)
+#define NFC_V1_V2_FLASH_ADDR           (host->regs + 0x06)
+#define NFC_V1_V2_FLASH_CMD            (host->regs + 0x08)
+#define NFC_V1_V2_CONFIG               (host->regs + 0x0a)
+#define NFC_V1_V2_ECC_STATUS_RESULT    (host->regs + 0x0c)
+#define NFC_V1_V2_RSLTMAIN_AREA                (host->regs + 0x0e)
+#define NFC_V1_V2_RSLTSPARE_AREA       (host->regs + 0x10)
+#define NFC_V1_V2_WRPROT               (host->regs + 0x12)
+#define NFC_V1_UNLOCKSTART_BLKADDR     (host->regs + 0x14)
+#define NFC_V1_UNLOCKEND_BLKADDR       (host->regs + 0x16)
+#define NFC_V21_UNLOCKSTART_BLKADDR    (host->regs + 0x20)
+#define NFC_V21_UNLOCKEND_BLKADDR      (host->regs + 0x22)
+#define NFC_V1_V2_NF_WRPRST            (host->regs + 0x18)
+#define NFC_V1_V2_CONFIG1              (host->regs + 0x1a)
+#define NFC_V1_V2_CONFIG2              (host->regs + 0x1c)
+
+#define NFC_V2_CONFIG1_ECC_MODE_4      (1 << 0)
+#define NFC_V1_V2_CONFIG1_SP_EN                (1 << 2)
+#define NFC_V1_V2_CONFIG1_ECC_EN       (1 << 3)
+#define NFC_V1_V2_CONFIG1_INT_MSK      (1 << 4)
+#define NFC_V1_V2_CONFIG1_BIG          (1 << 5)
+#define NFC_V1_V2_CONFIG1_RST          (1 << 6)
+#define NFC_V1_V2_CONFIG1_CE           (1 << 7)
+#define NFC_V1_V2_CONFIG1_ONE_CYCLE    (1 << 8)
+
+#define NFC_V1_V2_CONFIG2_INT          (1 << 15)
+
+/*
+ * Operation modes for the NFC. Valid for v1, v2 and v3
+ * type controllers.
+ */
+#define NFC_CMD                                (1 << 0)
+#define NFC_ADDR                       (1 << 1)
+#define NFC_INPUT                      (1 << 2)
+#define NFC_OUTPUT                     (1 << 3)
+#define NFC_ID                         (1 << 4)
+#define NFC_STATUS                     (1 << 5)
+
+#define NFC_V3_FLASH_CMD               (host->regs_axi + 0x00)
+#define NFC_V3_FLASH_ADDR0             (host->regs_axi + 0x04)
+
+#define NFC_V3_CONFIG1                 (host->regs_axi + 0x34)
+#define NFC_V3_CONFIG1_SP_EN           (1 << 0)
+#define NFC_V3_CONFIG1_RBA(x)          (((x) & 0x7 ) << 4)
+
+#define NFC_V3_ECC_STATUS_RESULT       (host->regs_axi + 0x38)
+
+#define NFC_V3_LAUNCH                  (host->regs_axi + 0x40)
+
+#define NFC_V3_WRPROT                  (host->regs_ip + 0x0)
+#define NFC_V3_WRPROT_LOCK_TIGHT       (1 << 0)
+#define NFC_V3_WRPROT_LOCK             (1 << 1)
+#define NFC_V3_WRPROT_UNLOCK           (1 << 2)
+#define NFC_V3_WRPROT_BLS_UNLOCK       (2 << 6)
+
+#define NFC_V3_WRPROT_UNLOCK_BLK_ADD0   (host->regs_ip + 0x04)
+
+#define NFC_V3_CONFIG2                 (host->regs_ip + 0x24)
+#define NFC_V3_CONFIG2_PS_512                  (0 << 0)
+#define NFC_V3_CONFIG2_PS_2048                 (1 << 0)
+#define NFC_V3_CONFIG2_PS_4096                 (2 << 0)
+#define NFC_V3_CONFIG2_ONE_CYCLE               (1 << 2)
+#define NFC_V3_CONFIG2_ECC_EN                  (1 << 3)
+#define NFC_V3_CONFIG2_2CMD_PHASES             (1 << 4)
+#define NFC_V3_CONFIG2_NUM_ADDR_PHASE0         (1 << 5)
+#define NFC_V3_CONFIG2_ECC_MODE_8              (1 << 6)
+#define NFC_V3_CONFIG2_PPB(x)                  (((x) & 0x3) << 7)
+#define NFC_V3_CONFIG2_NUM_ADDR_PHASE1(x)      (((x) & 0x3) << 12)
+#define NFC_V3_CONFIG2_INT_MSK                 (1 << 15)
+#define NFC_V3_CONFIG2_ST_CMD(x)               (((x) & 0xff) << 24)
+#define NFC_V3_CONFIG2_SPAS(x)                 (((x) & 0xff) << 16)
+
+#define NFC_V3_CONFIG3                         (host->regs_ip + 0x28)
+#define NFC_V3_CONFIG3_ADD_OP(x)               (((x) & 0x3) << 0)
+#define NFC_V3_CONFIG3_FW8                     (1 << 3)
+#define NFC_V3_CONFIG3_SBB(x)                  (((x) & 0x7) << 8)
+#define NFC_V3_CONFIG3_NUM_OF_DEVICES(x)       (((x) & 0x7) << 12)
+#define NFC_V3_CONFIG3_RBB_MODE                        (1 << 15)
+#define NFC_V3_CONFIG3_NO_SDMA                 (1 << 20)
+
+#define NFC_V3_IPC                     (host->regs_ip + 0x2C)
+#define NFC_V3_IPC_CREQ                        (1 << 0)
+#define NFC_V3_IPC_INT                 (1 << 31)
+
+#define NFC_V3_DELAY_LINE              (host->regs_ip + 0x34)
 
 struct mxc_nand_host {
        struct mtd_info         mtd;
@@ -102,20 +138,30 @@ struct mxc_nand_host {
 
        void                    *spare0;
        void                    *main_area0;
-       void                    *main_area1;
 
        void __iomem            *base;
        void __iomem            *regs;
+       void __iomem            *regs_axi;
+       void __iomem            *regs_ip;
        int                     status_request;
        struct clk              *clk;
        int                     clk_act;
        int                     irq;
+       int                     eccsize;
 
        wait_queue_head_t       irq_waitq;
 
        uint8_t                 *data_buf;
        unsigned int            buf_start;
        int                     spare_len;
+
+       void                    (*preset)(struct mtd_info *);
+       void                    (*send_cmd)(struct mxc_nand_host *, uint16_t, int);
+       void                    (*send_addr)(struct mxc_nand_host *, uint16_t, int);
+       void                    (*send_page)(struct mtd_info *, unsigned int);
+       void                    (*send_read_id)(struct mxc_nand_host *);
+       uint16_t                (*get_dev_status)(struct mxc_nand_host *);
+       int                     (*check_int)(struct mxc_nand_host *);
 };
 
 /* OOB placement block for use with hardware ecc generation */
@@ -175,34 +221,52 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
+static int check_int_v3(struct mxc_nand_host *host)
+{
+       uint32_t tmp;
+
+       tmp = readl(NFC_V3_IPC);
+       if (!(tmp & NFC_V3_IPC_INT))
+               return 0;
+
+       tmp &= ~NFC_V3_IPC_INT;
+       writel(tmp, NFC_V3_IPC);
+
+       return 1;
+}
+
+static int check_int_v1_v2(struct mxc_nand_host *host)
+{
+       uint32_t tmp;
+
+       tmp = readw(NFC_V1_V2_CONFIG2);
+       if (!(tmp & NFC_V1_V2_CONFIG2_INT))
+               return 0;
+
+       writew(tmp & ~NFC_V1_V2_CONFIG2_INT, NFC_V1_V2_CONFIG2);
+
+       return 1;
+}
+
 /* This function polls the NANDFC to wait for the basic operation to
  * complete by checking the INT bit of config2 register.
  */
 static void wait_op_done(struct mxc_nand_host *host, int useirq)
 {
-       uint16_t tmp;
        int max_retries = 8000;
 
        if (useirq) {
-               if ((readw(host->regs + NFC_CONFIG2) & NFC_INT) == 0) {
+               if (!host->check_int(host)) {
 
                        enable_irq(host->irq);
 
-                       wait_event(host->irq_waitq,
-                               readw(host->regs + NFC_CONFIG2) & NFC_INT);
-
-                       tmp = readw(host->regs + NFC_CONFIG2);
-                       tmp  &= ~NFC_INT;
-                       writew(tmp, host->regs + NFC_CONFIG2);
+                       wait_event(host->irq_waitq, host->check_int(host));
                }
        } else {
                while (max_retries-- > 0) {
-                       if (readw(host->regs + NFC_CONFIG2) & NFC_INT) {
-                               tmp = readw(host->regs + NFC_CONFIG2);
-                               tmp  &= ~NFC_INT;
-                               writew(tmp, host->regs + NFC_CONFIG2);
+                       if (host->check_int(host))
                                break;
-                       }
+
                        udelay(1);
                }
                if (max_retries < 0)
@@ -211,21 +275,33 @@ static void wait_op_done(struct mxc_nand_host *host, int useirq)
        }
 }
 
+static void send_cmd_v3(struct mxc_nand_host *host, uint16_t cmd, int useirq)
+{
+       /* fill command */
+       writel(cmd, NFC_V3_FLASH_CMD);
+
+       /* send out command */
+       writel(NFC_CMD, NFC_V3_LAUNCH);
+
+       /* Wait for operation to complete */
+       wait_op_done(host, useirq);
+}
+
 /* This function issues the specified command to the NAND device and
  * waits for completion. */
-static void send_cmd(struct mxc_nand_host *host, uint16_t cmd, int useirq)
+static void send_cmd_v1_v2(struct mxc_nand_host *host, uint16_t cmd, int useirq)
 {
        DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x, %d)\n", cmd, useirq);
 
-       writew(cmd, host->regs + NFC_FLASH_CMD);
-       writew(NFC_CMD, host->regs + NFC_CONFIG2);
+       writew(cmd, NFC_V1_V2_FLASH_CMD);
+       writew(NFC_CMD, NFC_V1_V2_CONFIG2);
 
        if (cpu_is_mx21() && (cmd == NAND_CMD_RESET)) {
                int max_retries = 100;
                /* Reset completion is indicated by NFC_CONFIG2 */
                /* being set to 0 */
                while (max_retries-- > 0) {
-                       if (readw(host->regs + NFC_CONFIG2) == 0) {
+                       if (readw(NFC_V1_V2_CONFIG2) == 0) {
                                break;
                        }
                        udelay(1);
@@ -239,21 +315,48 @@ static void send_cmd(struct mxc_nand_host *host, uint16_t cmd, int useirq)
        }
 }
 
+static void send_addr_v3(struct mxc_nand_host *host, uint16_t addr, int islast)
+{
+       /* fill address */
+       writel(addr, NFC_V3_FLASH_ADDR0);
+
+       /* send out address */
+       writel(NFC_ADDR, NFC_V3_LAUNCH);
+
+       wait_op_done(host, 0);
+}
+
 /* This function sends an address (or partial address) to the
  * NAND device. The address is used to select the source/destination for
  * a NAND command. */
-static void send_addr(struct mxc_nand_host *host, uint16_t addr, int islast)
+static void send_addr_v1_v2(struct mxc_nand_host *host, uint16_t addr, int islast)
 {
        DEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x %d)\n", addr, islast);
 
-       writew(addr, host->regs + NFC_FLASH_ADDR);
-       writew(NFC_ADDR, host->regs + NFC_CONFIG2);
+       writew(addr, NFC_V1_V2_FLASH_ADDR);
+       writew(NFC_ADDR, NFC_V1_V2_CONFIG2);
 
        /* Wait for operation to complete */
        wait_op_done(host, islast);
 }
 
-static void send_page(struct mtd_info *mtd, unsigned int ops)
+static void send_page_v3(struct mtd_info *mtd, unsigned int ops)
+{
+       struct nand_chip *nand_chip = mtd->priv;
+       struct mxc_nand_host *host = nand_chip->priv;
+       uint32_t tmp;
+
+       tmp = readl(NFC_V3_CONFIG1);
+       tmp &= ~(7 << 4);
+       writel(tmp, NFC_V3_CONFIG1);
+
+       /* transfer data from NFC ram to nand */
+       writel(ops, NFC_V3_LAUNCH);
+
+       wait_op_done(host, false);
+}
+
+static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops)
 {
        struct nand_chip *nand_chip = mtd->priv;
        struct mxc_nand_host *host = nand_chip->priv;
@@ -267,24 +370,34 @@ static void send_page(struct mtd_info *mtd, unsigned int ops)
        for (i = 0; i < bufs; i++) {
 
                /* NANDFC buffer 0 is used for page read/write */
-               writew(i, host->regs + NFC_BUF_ADDR);
+               writew(i, NFC_V1_V2_BUF_ADDR);
 
-               writew(ops, host->regs + NFC_CONFIG2);
+               writew(ops, NFC_V1_V2_CONFIG2);
 
                /* Wait for operation to complete */
                wait_op_done(host, true);
        }
 }
 
+static void send_read_id_v3(struct mxc_nand_host *host)
+{
+       /* Read ID into main buffer */
+       writel(NFC_ID, NFC_V3_LAUNCH);
+
+       wait_op_done(host, true);
+
+       memcpy(host->data_buf, host->main_area0, 16);
+}
+
 /* Request the NANDFC to perform a read of the NAND device ID. */
-static void send_read_id(struct mxc_nand_host *host)
+static void send_read_id_v1_v2(struct mxc_nand_host *host)
 {
        struct nand_chip *this = &host->nand;
 
        /* NANDFC buffer 0 is used for device ID output */
-       writew(0x0, host->regs + NFC_BUF_ADDR);
+       writew(0x0, NFC_V1_V2_BUF_ADDR);
 
-       writew(NFC_ID, host->regs + NFC_CONFIG2);
+       writew(NFC_ID, NFC_V1_V2_CONFIG2);
 
        /* Wait for operation to complete */
        wait_op_done(host, true);
@@ -301,29 +414,36 @@ static void send_read_id(struct mxc_nand_host *host)
        memcpy(host->data_buf, host->main_area0, 16);
 }
 
+static uint16_t get_dev_status_v3(struct mxc_nand_host *host)
+{
+       writew(NFC_STATUS, NFC_V3_LAUNCH);
+       wait_op_done(host, true);
+
+       return readl(NFC_V3_CONFIG1) >> 16;
+}
+
 /* This function requests the NANDFC to perform a read of the
  * NAND device status and returns the current status. */
-static uint16_t get_dev_status(struct mxc_nand_host *host)
+static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host)
 {
-       void __iomem *main_buf = host->main_area1;
+       void __iomem *main_buf = host->main_area0;
        uint32_t store;
        uint16_t ret;
-       /* Issue status request to NAND device */
 
-       /* store the main area1 first word, later do recovery */
-       store = readl(main_buf);
-       /* NANDFC buffer 1 is used for device status to prevent
-        * corruption of read/write buffer on status requests. */
-       writew(1, host->regs + NFC_BUF_ADDR);
+       writew(0x0, NFC_V1_V2_BUF_ADDR);
 
-       writew(NFC_STATUS, host->regs + NFC_CONFIG2);
+       /*
+        * The device status is stored in main_area0. To
+        * prevent corruption of the buffer save the value
+        * and restore it afterwards.
+        */
+       store = readl(main_buf);
 
-       /* Wait for operation to complete */
+       writew(NFC_STATUS, NFC_V1_V2_CONFIG2);
        wait_op_done(host, true);
 
-       /* Status is placed in first word of main buffer */
-       /* get status, then recovery area 1 data */
        ret = readw(main_buf);
+
        writel(store, main_buf);
 
        return ret;
@@ -347,7 +467,7 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
         */
 }
 
-static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
+static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
                                 u_char *read_ecc, u_char *calc_ecc)
 {
        struct nand_chip *nand_chip = mtd->priv;
@@ -358,7 +478,7 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
         * additional correction.  2-Bit errors cannot be corrected by
         * HW ECC, so we need to return failure
         */
-       uint16_t ecc_status = readw(host->regs + NFC_ECC_STATUS_RESULT);
+       uint16_t ecc_status = readw(NFC_V1_V2_ECC_STATUS_RESULT);
 
        if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
                DEBUG(MTD_DEBUG_LEVEL0,
@@ -369,6 +489,43 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
        return 0;
 }
 
+static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
+                                u_char *read_ecc, u_char *calc_ecc)
+{
+       struct nand_chip *nand_chip = mtd->priv;
+       struct mxc_nand_host *host = nand_chip->priv;
+       u32 ecc_stat, err;
+       int no_subpages = 1;
+       int ret = 0;
+       u8 ecc_bit_mask, err_limit;
+
+       ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf;
+       err_limit = (host->eccsize == 4) ? 0x4 : 0x8;
+
+       no_subpages = mtd->writesize >> 9;
+
+       if (nfc_is_v21())
+               ecc_stat = readl(NFC_V1_V2_ECC_STATUS_RESULT);
+       else
+               ecc_stat = readl(NFC_V3_ECC_STATUS_RESULT);
+
+       do {
+               err = ecc_stat & ecc_bit_mask;
+               if (err > err_limit) {
+                       printk(KERN_WARNING "UnCorrectable RS-ECC Error\n");
+                       return -1;
+               } else {
+                       ret += err;
+               }
+               ecc_stat >>= 4;
+       } while (--no_subpages);
+
+       mtd->ecc_stats.corrected += ret;
+       pr_debug("%d Symbol Correctable RS-ECC Error\n", ret);
+
+       return ret;
+}
+
 static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
                                  u_char *ecc_code)
 {
@@ -383,7 +540,7 @@ static u_char mxc_nand_read_byte(struct mtd_info *mtd)
 
        /* Check for status request */
        if (host->status_request)
-               return get_dev_status(host) & 0xFF;
+               return host->get_dev_status(host) & 0xFF;
 
        ret = *(uint8_t *)(host->data_buf + host->buf_start);
        host->buf_start++;
@@ -519,71 +676,163 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
                 * we will used the saved column address to index into
                 * the full page.
                 */
-               send_addr(host, 0, page_addr == -1);
+               host->send_addr(host, 0, page_addr == -1);
                if (mtd->writesize > 512)
                        /* another col addr cycle for 2k page */
-                       send_addr(host, 0, false);
+                       host->send_addr(host, 0, false);
        }
 
        /* Write out page address, if necessary */
        if (page_addr != -1) {
                /* paddr_0 - p_addr_7 */
-               send_addr(host, (page_addr & 0xff), false);
+               host->send_addr(host, (page_addr & 0xff), false);
 
                if (mtd->writesize > 512) {
                        if (mtd->size >= 0x10000000) {
                                /* paddr_8 - paddr_15 */
-                               send_addr(host, (page_addr >> 8) & 0xff, false);
-                               send_addr(host, (page_addr >> 16) & 0xff, true);
+                               host->send_addr(host, (page_addr >> 8) & 0xff, false);
+                               host->send_addr(host, (page_addr >> 16) & 0xff, true);
                        } else
                                /* paddr_8 - paddr_15 */
-                               send_addr(host, (page_addr >> 8) & 0xff, true);
+                               host->send_addr(host, (page_addr >> 8) & 0xff, true);
                } else {
                        /* One more address cycle for higher density devices */
                        if (mtd->size >= 0x4000000) {
                                /* paddr_8 - paddr_15 */
-                               send_addr(host, (page_addr >> 8) & 0xff, false);
-                               send_addr(host, (page_addr >> 16) & 0xff, true);
+                               host->send_addr(host, (page_addr >> 8) & 0xff, false);
+                               host->send_addr(host, (page_addr >> 16) & 0xff, true);
                        } else
                                /* paddr_8 - paddr_15 */
-                               send_addr(host, (page_addr >> 8) & 0xff, true);
+                               host->send_addr(host, (page_addr >> 8) & 0xff, true);
                }
        }
 }
 
-static void preset(struct mtd_info *mtd)
+/*
+ * v2 and v3 type controllers can do 4bit or 8bit ecc depending
+ * on how much oob the nand chip has. For 8bit ecc we need at least
+ * 26 bytes of oob data per 512 byte block.
+ */
+static int get_eccsize(struct mtd_info *mtd)
+{
+       int oobbytes_per_512 = 0;
+
+       oobbytes_per_512 = mtd->oobsize * 512 / mtd->writesize;
+
+       if (oobbytes_per_512 < 26)
+               return 4;
+       else
+               return 8;
+}
+
+static void preset_v1_v2(struct mtd_info *mtd)
 {
        struct nand_chip *nand_chip = mtd->priv;
        struct mxc_nand_host *host = nand_chip->priv;
        uint16_t tmp;
 
        /* enable interrupt, disable spare enable */
-       tmp = readw(host->regs + NFC_CONFIG1);
-       tmp &= ~NFC_INT_MSK;
-       tmp &= ~NFC_SP_EN;
+       tmp = readw(NFC_V1_V2_CONFIG1);
+       tmp &= ~NFC_V1_V2_CONFIG1_INT_MSK;
+       tmp &= ~NFC_V1_V2_CONFIG1_SP_EN;
        if (nand_chip->ecc.mode == NAND_ECC_HW) {
-               tmp |= NFC_ECC_EN;
+               tmp |= NFC_V1_V2_CONFIG1_ECC_EN;
+       } else {
+               tmp &= ~NFC_V1_V2_CONFIG1_ECC_EN;
+       }
+
+       if (nfc_is_v21() && mtd->writesize) {
+               host->eccsize = get_eccsize(mtd);
+               if (host->eccsize == 4)
+                       tmp |= NFC_V2_CONFIG1_ECC_MODE_4;
        } else {
-               tmp &= ~NFC_ECC_EN;
+               host->eccsize = 1;
        }
-       writew(tmp, host->regs + NFC_CONFIG1);
+
+       writew(tmp, NFC_V1_V2_CONFIG1);
        /* preset operation */
 
        /* Unlock the internal RAM Buffer */
-       writew(0x2, host->regs + NFC_CONFIG);
+       writew(0x2, NFC_V1_V2_CONFIG);
 
        /* Blocks to be unlocked */
        if (nfc_is_v21()) {
-               writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR);
-               writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR);
+               writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR);
+               writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR);
        } else if (nfc_is_v1()) {
-               writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR);
-               writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR);
+               writew(0x0, NFC_V1_UNLOCKSTART_BLKADDR);
+               writew(0x4000, NFC_V1_UNLOCKEND_BLKADDR);
        } else
                BUG();
 
        /* Unlock Block Command for given address range */
-       writew(0x4, host->regs + NFC_WRPROT);
+       writew(0x4, NFC_V1_V2_WRPROT);
+}
+
+static void preset_v3(struct mtd_info *mtd)
+{
+       struct nand_chip *chip = mtd->priv;
+       struct mxc_nand_host *host = chip->priv;
+       uint32_t config2, config3;
+       int i, addr_phases;
+
+       writel(NFC_V3_CONFIG1_RBA(0), NFC_V3_CONFIG1);
+       writel(NFC_V3_IPC_CREQ, NFC_V3_IPC);
+
+       /* Unlock the internal RAM Buffer */
+       writel(NFC_V3_WRPROT_BLS_UNLOCK | NFC_V3_WRPROT_UNLOCK,
+                       NFC_V3_WRPROT);
+
+       /* Blocks to be unlocked */
+       for (i = 0; i < NAND_MAX_CHIPS; i++)
+               writel(0x0 |    (0xffff << 16),
+                               NFC_V3_WRPROT_UNLOCK_BLK_ADD0 + (i << 2));
+
+       writel(0, NFC_V3_IPC);
+
+       config2 = NFC_V3_CONFIG2_ONE_CYCLE |
+               NFC_V3_CONFIG2_2CMD_PHASES |
+               NFC_V3_CONFIG2_SPAS(mtd->oobsize >> 1) |
+               NFC_V3_CONFIG2_ST_CMD(0x70) |
+               NFC_V3_CONFIG2_NUM_ADDR_PHASE0;
+
+       if (chip->ecc.mode == NAND_ECC_HW)
+               config2 |= NFC_V3_CONFIG2_ECC_EN;
+
+       addr_phases = fls(chip->pagemask) >> 3;
+
+       if (mtd->writesize == 2048) {
+               config2 |= NFC_V3_CONFIG2_PS_2048;
+               config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases);
+       } else if (mtd->writesize == 4096) {
+               config2 |= NFC_V3_CONFIG2_PS_4096;
+               config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases);
+       } else {
+               config2 |= NFC_V3_CONFIG2_PS_512;
+               config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases - 1);
+       }
+
+       if (mtd->writesize) {
+               config2 |= NFC_V3_CONFIG2_PPB(ffs(mtd->erasesize / mtd->writesize) - 6);
+               host->eccsize = get_eccsize(mtd);
+               if (host->eccsize == 8)
+                       config2 |= NFC_V3_CONFIG2_ECC_MODE_8;
+       }
+
+       writel(config2, NFC_V3_CONFIG2);
+
+       config3 = NFC_V3_CONFIG3_NUM_OF_DEVICES(0) |
+                       NFC_V3_CONFIG3_NO_SDMA |
+                       NFC_V3_CONFIG3_RBB_MODE |
+                       NFC_V3_CONFIG3_SBB(6) | /* Reset default */
+                       NFC_V3_CONFIG3_ADD_OP(0);
+
+       if (!(chip->options & NAND_BUSWIDTH_16))
+               config3 |= NFC_V3_CONFIG3_FW8;
+
+       writel(config3, NFC_V3_CONFIG3);
+
+       writel(0, NFC_V3_DELAY_LINE);
 }
 
 /* Used by the upper layer to write command to NAND Flash for
@@ -604,15 +853,15 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
        /* Command pre-processing step */
        switch (command) {
        case NAND_CMD_RESET:
-               send_cmd(host, command, false);
-               preset(mtd);
+               host->preset(mtd);
+               host->send_cmd(host, command, false);
                break;
 
        case NAND_CMD_STATUS:
                host->buf_start = 0;
                host->status_request = true;
 
-               send_cmd(host, command, true);
+               host->send_cmd(host, command, true);
                mxc_do_addr_cycle(mtd, column, page_addr);
                break;
 
@@ -625,13 +874,13 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
 
                command = NAND_CMD_READ0; /* only READ0 is valid */
 
-               send_cmd(host, command, false);
+               host->send_cmd(host, command, false);
                mxc_do_addr_cycle(mtd, column, page_addr);
 
                if (mtd->writesize > 512)
-                       send_cmd(host, NAND_CMD_READSTART, true);
+                       host->send_cmd(host, NAND_CMD_READSTART, true);
 
-               send_page(mtd, NFC_OUTPUT);
+               host->send_page(mtd, NFC_OUTPUT);
 
                memcpy(host->data_buf, host->main_area0, mtd->writesize);
                copy_spare(mtd, true);
@@ -644,28 +893,28 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
 
                host->buf_start = column;
 
-               send_cmd(host, command, false);
+               host->send_cmd(host, command, false);
                mxc_do_addr_cycle(mtd, column, page_addr);
                break;
 
        case NAND_CMD_PAGEPROG:
                memcpy(host->main_area0, host->data_buf, mtd->writesize);
                copy_spare(mtd, false);
-               send_page(mtd, NFC_INPUT);
-               send_cmd(host, command, true);
+               host->send_page(mtd, NFC_INPUT);
+               host->send_cmd(host, command, true);
                mxc_do_addr_cycle(mtd, column, page_addr);
                break;
 
        case NAND_CMD_READID:
-               send_cmd(host, command, true);
+               host->send_cmd(host, command, true);
                mxc_do_addr_cycle(mtd, column, page_addr);
-               send_read_id(host);
+               host->send_read_id(host);
                host->buf_start = column;
                break;
 
        case NAND_CMD_ERASE1:
        case NAND_CMD_ERASE2:
-               send_cmd(host, command, false);
+               host->send_cmd(host, command, false);
                mxc_do_addr_cycle(mtd, column, page_addr);
 
                break;
@@ -761,22 +1010,55 @@ static int __init mxcnd_probe(struct platform_device *pdev)
        }
 
        host->main_area0 = host->base;
-       host->main_area1 = host->base + 0x200;
+
+       if (nfc_is_v1() || nfc_is_v21()) {
+               host->preset = preset_v1_v2;
+               host->send_cmd = send_cmd_v1_v2;
+               host->send_addr = send_addr_v1_v2;
+               host->send_page = send_page_v1_v2;
+               host->send_read_id = send_read_id_v1_v2;
+               host->get_dev_status = get_dev_status_v1_v2;
+               host->check_int = check_int_v1_v2;
+       }
 
        if (nfc_is_v21()) {
-               host->regs = host->base + 0x1000;
+               host->regs = host->base + 0x1e00;
                host->spare0 = host->base + 0x1000;
                host->spare_len = 64;
                oob_smallpage = &nandv2_hw_eccoob_smallpage;
                oob_largepage = &nandv2_hw_eccoob_largepage;
                this->ecc.bytes = 9;
        } else if (nfc_is_v1()) {
-               host->regs = host->base;
+               host->regs = host->base + 0xe00;
                host->spare0 = host->base + 0x800;
                host->spare_len = 16;
                oob_smallpage = &nandv1_hw_eccoob_smallpage;
                oob_largepage = &nandv1_hw_eccoob_largepage;
                this->ecc.bytes = 3;
+               host->eccsize = 1;
+       } else if (nfc_is_v3_2()) {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+               if (!res) {
+                       err = -ENODEV;
+                       goto eirq;
+               }
+               host->regs_ip = ioremap(res->start, resource_size(res));
+               if (!host->regs_ip) {
+                       err = -ENOMEM;
+                       goto eirq;
+               }
+               host->regs_axi = host->base + 0x1e00;
+               host->spare0 = host->base + 0x1000;
+               host->spare_len = 64;
+               host->preset = preset_v3;
+               host->send_cmd = send_cmd_v3;
+               host->send_addr = send_addr_v3;
+               host->send_page = send_page_v3;
+               host->send_read_id = send_read_id_v3;
+               host->check_int = check_int_v3;
+               host->get_dev_status = get_dev_status_v3;
+               oob_smallpage = &nandv2_hw_eccoob_smallpage;
+               oob_largepage = &nandv2_hw_eccoob_largepage;
        } else
                BUG();
 
@@ -786,7 +1068,10 @@ static int __init mxcnd_probe(struct platform_device *pdev)
        if (pdata->hw_ecc) {
                this->ecc.calculate = mxc_nand_calculate_ecc;
                this->ecc.hwctl = mxc_nand_enable_hwecc;
-               this->ecc.correct = mxc_nand_correct_data;
+               if (nfc_is_v1())
+                       this->ecc.correct = mxc_nand_correct_data_v1;
+               else
+                       this->ecc.correct = mxc_nand_correct_data_v2_v3;
                this->ecc.mode = NAND_ECC_HW;
        } else {
                this->ecc.mode = NAND_ECC_SOFT;
@@ -817,6 +1102,9 @@ static int __init mxcnd_probe(struct platform_device *pdev)
                goto escan;
        }
 
+       /* Call preset again, with correct writesize this time */
+       host->preset(mtd);
+
        if (mtd->writesize == 2048)
                this->ecc.layout = oob_largepage;
 
@@ -848,6 +1136,8 @@ static int __init mxcnd_probe(struct platform_device *pdev)
 escan:
        free_irq(host->irq, host);
 eirq:
+       if (host->regs_ip)
+               iounmap(host->regs_ip);
        iounmap(host->base);
 eres:
        clk_put(host->clk);
@@ -867,59 +1157,19 @@ static int __devexit mxcnd_remove(struct platform_device *pdev)
 
        nand_release(&host->mtd);
        free_irq(host->irq, host);
+       if (host->regs_ip)
+               iounmap(host->regs_ip);
        iounmap(host->base);
        kfree(host);
 
        return 0;
 }
 
-#ifdef CONFIG_PM
-static int mxcnd_suspend(struct platform_device *pdev, pm_message_t state)
-{
-       struct mtd_info *mtd = platform_get_drvdata(pdev);
-       struct nand_chip *nand_chip = mtd->priv;
-       struct mxc_nand_host *host = nand_chip->priv;
-       int ret = 0;
-
-       DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND suspend\n");
-
-       ret = mtd->suspend(mtd);
-
-       /*
-        * nand_suspend locks the device for exclusive access, so
-        * the clock must already be off.
-        */
-       BUG_ON(!ret && host->clk_act);
-
-       return ret;
-}
-
-static int mxcnd_resume(struct platform_device *pdev)
-{
-       struct mtd_info *mtd = platform_get_drvdata(pdev);
-       struct nand_chip *nand_chip = mtd->priv;
-       struct mxc_nand_host *host = nand_chip->priv;
-       int ret = 0;
-
-       DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND resume\n");
-
-       mtd->resume(mtd);
-
-       return ret;
-}
-
-#else
-# define mxcnd_suspend   NULL
-# define mxcnd_resume    NULL
-#endif                         /* CONFIG_PM */
-
 static struct platform_driver mxcnd_driver = {
        .driver = {
                   .name = DRIVER_NAME,
-                  },
+       },
        .remove = __devexit_p(mxcnd_remove),
-       .suspend = mxcnd_suspend,
-       .resume = mxcnd_resume,
 };
 
 static int __init mxc_nd_init(void)
index 4a7b86423ee96fb749537f871cb776a2bc172eb3..16a1714df0085b9dd8c464b344fce5a50fb162cf 100644 (file)
@@ -42,7 +42,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/compatmac.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
 #include <linux/leds.h>
@@ -347,7 +346,7 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
        struct nand_chip *chip = mtd->priv;
        u16 bad;
 
-       if (chip->options & NAND_BB_LAST_PAGE)
+       if (chip->options & NAND_BBT_SCANLASTPAGE)
                ofs += mtd->erasesize - mtd->writesize;
 
        page = (int)(ofs >> chip->page_shift) & chip->pagemask;
@@ -397,9 +396,9 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
        struct nand_chip *chip = mtd->priv;
        uint8_t buf[2] = { 0, 0 };
-       int block, ret;
+       int block, ret, i = 0;
 
-       if (chip->options & NAND_BB_LAST_PAGE)
+       if (chip->options & NAND_BBT_SCANLASTPAGE)
                ofs += mtd->erasesize - mtd->writesize;
 
        /* Get block number */
@@ -411,17 +410,31 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
        if (chip->options & NAND_USE_FLASH_BBT)
                ret = nand_update_bbt(mtd, ofs);
        else {
-               /* We write two bytes, so we dont have to mess with 16 bit
-                * access
-                */
                nand_get_device(chip, mtd, FL_WRITING);
-               ofs += mtd->oobsize;
-               chip->ops.len = chip->ops.ooblen = 2;
-               chip->ops.datbuf = NULL;
-               chip->ops.oobbuf = buf;
-               chip->ops.ooboffs = chip->badblockpos & ~0x01;
 
-               ret = nand_do_write_oob(mtd, ofs, &chip->ops);
+               /* Write to first two pages and to byte 1 and 6 if necessary.
+                * If we write to more than one location, the first error
+                * encountered quits the procedure. We write two bytes per
+                * location, so we dont have to mess with 16 bit access.
+                */
+               do {
+                       chip->ops.len = chip->ops.ooblen = 2;
+                       chip->ops.datbuf = NULL;
+                       chip->ops.oobbuf = buf;
+                       chip->ops.ooboffs = chip->badblockpos & ~0x01;
+
+                       ret = nand_do_write_oob(mtd, ofs, &chip->ops);
+
+                       if (!ret && (chip->options & NAND_BBT_SCANBYTE1AND6)) {
+                               chip->ops.ooboffs = NAND_SMALL_BADBLOCK_POS
+                                       & ~0x01;
+                               ret = nand_do_write_oob(mtd, ofs, &chip->ops);
+                       }
+                       i++;
+                       ofs += mtd->writesize;
+               } while (!ret && (chip->options & NAND_BBT_SCAN2NDPAGE) &&
+                               i < 2);
+
                nand_release_device(mtd);
        }
        if (!ret)
@@ -2920,9 +2933,14 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 32 - 1;
 
        /* Set the bad block position */
-       chip->badblockpos = mtd->writesize > 512 ?
-               NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
-       chip->badblockbits = 8;
+       if (!(busw & NAND_BUSWIDTH_16) && (*maf_id == NAND_MFR_STMICRO ||
+                               (*maf_id == NAND_MFR_SAMSUNG &&
+                                mtd->writesize == 512) ||
+                               *maf_id == NAND_MFR_AMD))
+               chip->badblockpos = NAND_SMALL_BADBLOCK_POS;
+       else
+               chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
+
 
        /* Get chip options, preserve non chip based options */
        chip->options &= ~NAND_CHIPOPTIONS_MSK;
@@ -2941,12 +2959,32 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 
        /*
         * Bad block marker is stored in the last page of each block
-        * on Samsung and Hynix MLC devices
+        * on Samsung and Hynix MLC devices; stored in first two pages
+        * of each block on Micron devices with 2KiB pages and on
+        * SLC Samsung, Hynix, and AMD/Spansion. All others scan only
+        * the first page.
         */
        if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
                        (*maf_id == NAND_MFR_SAMSUNG ||
                         *maf_id == NAND_MFR_HYNIX))
-               chip->options |= NAND_BB_LAST_PAGE;
+               chip->options |= NAND_BBT_SCANLASTPAGE;
+       else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+                               (*maf_id == NAND_MFR_SAMSUNG ||
+                                *maf_id == NAND_MFR_HYNIX ||
+                                *maf_id == NAND_MFR_AMD)) ||
+                       (mtd->writesize == 2048 &&
+                        *maf_id == NAND_MFR_MICRON))
+               chip->options |= NAND_BBT_SCAN2NDPAGE;
+
+       /*
+        * Numonyx/ST 2K pages, x8 bus use BOTH byte 1 and 6
+        */
+       if (!(busw & NAND_BUSWIDTH_16) &&
+                       *maf_id == NAND_MFR_STMICRO &&
+                       mtd->writesize == 2048) {
+               chip->options |= NAND_BBT_SCANBYTE1AND6;
+               chip->badblockpos = 0;
+       }
 
        /* Check for AND chips with 4 page planes */
        if (chip->options & NAND_4PAGE_ARRAY)
@@ -3306,6 +3344,11 @@ void nand_release(struct mtd_info *mtd)
        kfree(chip->bbt);
        if (!(chip->options & NAND_OWN_BUFFERS))
                kfree(chip->buffers);
+
+       /* Free bad block descriptor memory */
+       if (chip->badblock_pattern && chip->badblock_pattern->options
+                       & NAND_BBT_DYNAMICSTRUCT)
+               kfree(chip->badblock_pattern);
 }
 
 EXPORT_SYMBOL_GPL(nand_lock);
index ad97c0ce73b265a018c75871afe21bc17dc743c5..5fedf4a74f16ca45bfc0c628ca03ae8dc60d53e4 100644 (file)
@@ -55,7 +55,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/compatmac.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
@@ -93,6 +92,28 @@ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_desc
                        return -1;
        }
 
+       /* Check both positions 1 and 6 for pattern? */
+       if (td->options & NAND_BBT_SCANBYTE1AND6) {
+               if (td->options & NAND_BBT_SCANEMPTY) {
+                       p += td->len;
+                       end += NAND_SMALL_BADBLOCK_POS - td->offs;
+                       /* Check region between positions 1 and 6 */
+                       for (i = 0; i < NAND_SMALL_BADBLOCK_POS - td->offs - td->len;
+                                       i++) {
+                               if (*p++ != 0xff)
+                                       return -1;
+                       }
+               }
+               else {
+                       p += NAND_SMALL_BADBLOCK_POS - td->offs;
+               }
+               /* Compare the pattern */
+               for (i = 0; i < td->len; i++) {
+                       if (p[i] != td->pattern[i])
+                               return -1;
+               }
+       }
+
        if (td->options & NAND_BBT_SCANEMPTY) {
                p += td->len;
                end += td->len;
@@ -124,6 +145,13 @@ static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
                if (p[td->offs + i] != td->pattern[i])
                        return -1;
        }
+       /* Need to check location 1 AND 6? */
+       if (td->options & NAND_BBT_SCANBYTE1AND6) {
+               for (i = 0; i < td->len; i++) {
+                       if (p[NAND_SMALL_BADBLOCK_POS + i] != td->pattern[i])
+                               return -1;
+               }
+       }
        return 0;
 }
 
@@ -397,12 +425,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
 
        if (bd->options & NAND_BBT_SCANALLPAGES)
                len = 1 << (this->bbt_erase_shift - this->page_shift);
-       else {
-               if (bd->options & NAND_BBT_SCAN2NDPAGE)
-                       len = 2;
-               else
-                       len = 1;
-       }
+       else if (bd->options & NAND_BBT_SCAN2NDPAGE)
+               len = 2;
+       else
+               len = 1;
 
        if (!(bd->options & NAND_BBT_SCANEMPTY)) {
                /* We need only read few bytes from the OOB area */
@@ -432,7 +458,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
                from = (loff_t)startblock << (this->bbt_erase_shift - 1);
        }
 
-       if (this->options & NAND_BB_LAST_PAGE)
+       if (this->options & NAND_BBT_SCANLASTPAGE)
                from += mtd->erasesize - (mtd->writesize * len);
 
        for (i = startblock; i < numblocks;) {
@@ -1092,30 +1118,16 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
  * while scanning a device for factory marked good / bad blocks. */
 static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
 
-static struct nand_bbt_descr smallpage_memorybased = {
-       .options = NAND_BBT_SCAN2NDPAGE,
-       .offs = 5,
-       .len = 1,
-       .pattern = scan_ff_pattern
-};
-
-static struct nand_bbt_descr largepage_memorybased = {
-       .options = 0,
-       .offs = 0,
-       .len = 2,
-       .pattern = scan_ff_pattern
-};
-
 static struct nand_bbt_descr smallpage_flashbased = {
        .options = NAND_BBT_SCAN2NDPAGE,
-       .offs = 5,
+       .offs = NAND_SMALL_BADBLOCK_POS,
        .len = 1,
        .pattern = scan_ff_pattern
 };
 
 static struct nand_bbt_descr largepage_flashbased = {
        .options = NAND_BBT_SCAN2NDPAGE,
-       .offs = 0,
+       .offs = NAND_LARGE_BADBLOCK_POS,
        .len = 2,
        .pattern = scan_ff_pattern
 };
@@ -1154,6 +1166,43 @@ static struct nand_bbt_descr bbt_mirror_descr = {
        .pattern = mirror_pattern
 };
 
+#define BBT_SCAN_OPTIONS (NAND_BBT_SCANLASTPAGE | NAND_BBT_SCAN2NDPAGE | \
+               NAND_BBT_SCANBYTE1AND6)
+/**
+ * nand_create_default_bbt_descr - [Internal] Creates a BBT descriptor structure
+ * @this:      NAND chip to create descriptor for
+ *
+ * This function allocates and initializes a nand_bbt_descr for BBM detection
+ * based on the properties of "this". The new descriptor is stored in
+ * this->badblock_pattern. Thus, this->badblock_pattern should be NULL when
+ * passed to this function.
+ *
+ * TODO: Handle other flags, replace other static structs
+ *        (e.g. handle NAND_BBT_FLASH for flash-based BBT,
+ *             replace smallpage_flashbased)
+ *
+ */
+static int nand_create_default_bbt_descr(struct nand_chip *this)
+{
+       struct nand_bbt_descr *bd;
+       if (this->badblock_pattern) {
+               printk(KERN_WARNING "BBT descr already allocated; not replacing.\n");
+               return -EINVAL;
+       }
+       bd = kzalloc(sizeof(*bd), GFP_KERNEL);
+       if (!bd) {
+               printk(KERN_ERR "nand_create_default_bbt_descr: Out of memory\n");
+               return -ENOMEM;
+       }
+       bd->options = this->options & BBT_SCAN_OPTIONS;
+       bd->offs = this->badblockpos;
+       bd->len = (this->options & NAND_BUSWIDTH_16) ? 2 : 1;
+       bd->pattern = scan_ff_pattern;
+       bd->options |= NAND_BBT_DYNAMICSTRUCT;
+       this->badblock_pattern = bd;
+       return 0;
+}
+
 /**
  * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
  * @mtd:       MTD device structure
@@ -1196,10 +1245,8 @@ int nand_default_bbt(struct mtd_info *mtd)
        } else {
                this->bbt_td = NULL;
                this->bbt_md = NULL;
-               if (!this->badblock_pattern) {
-                       this->badblock_pattern = (mtd->writesize > 512) ?
-                           &largepage_memorybased : &smallpage_memorybased;
-               }
+               if (!this->badblock_pattern)
+                       nand_create_default_bbt_descr(this);
        }
        return nand_scan_bbt(mtd, this->badblock_pattern);
 }
index 89907ed990091ff88b734ee17e3905283387d43a..a04b89105b656d59f21c72fee2a3482d790b2e3e 100644 (file)
@@ -85,6 +85,7 @@ struct nand_flash_dev nand_flash_ids[] = {
        {"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},
 
        /* 2 Gigabit */
        {"NAND 256MiB 1,8V 8-bit",      0xAA, 0, 256, 0, LP_OPTIONS},
@@ -110,6 +111,9 @@ struct nand_flash_dev nand_flash_ids[] = {
        {"NAND 2GiB 1,8V 16-bit",       0xB5, 0, 2048, 0, LP_OPTIONS16},
        {"NAND 2GiB 3,3V 16-bit",       0xC5, 0, 2048, 0, LP_OPTIONS16},
 
+       /* 32 Gigabit */
+       {"NAND 4GiB 3,3V 8-bit",        0xD7, 0, 4096, 0, 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
index 261337efe0ee1557e1bb88f9610216554b82a3f3..c25648bb5793423ba0c6ce8378744b912715bdc9 100644 (file)
@@ -553,8 +553,8 @@ static uint64_t divide(uint64_t n, uint32_t d)
  */
 static int init_nandsim(struct mtd_info *mtd)
 {
-       struct nand_chip *chip = (struct nand_chip *)mtd->priv;
-       struct nandsim   *ns   = (struct nandsim *)(chip->priv);
+       struct nand_chip *chip = mtd->priv;
+       struct nandsim   *ns   = chip->priv;
        int i, ret = 0;
        uint64_t remains;
        uint64_t next_offset;
@@ -1877,7 +1877,7 @@ static void switch_state(struct nandsim *ns)
 
 static u_char ns_nand_read_byte(struct mtd_info *mtd)
 {
-        struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
+       struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv;
        u_char outb = 0x00;
 
        /* Sanity and correctness checks */
@@ -1950,7 +1950,7 @@ static u_char ns_nand_read_byte(struct mtd_info *mtd)
 
 static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
 {
-        struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
+       struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv;
 
        /* Sanity and correctness checks */
        if (!ns->lines.ce) {
@@ -2132,7 +2132,7 @@ static uint16_t ns_nand_read_word(struct mtd_info *mtd)
 
 static void ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
 {
-        struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
+       struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv;
 
        /* Check that chip is expecting data input */
        if (!(ns->state & STATE_DATAIN_MASK)) {
@@ -2159,7 +2159,7 @@ static void ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
 
 static void ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
 {
-        struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
+       struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv;
 
        /* Sanity and correctness checks */
        if (!ns->lines.ce) {
@@ -2352,7 +2352,7 @@ module_init(ns_init_module);
  */
 static void __exit ns_cleanup_module(void)
 {
-       struct nandsim *ns = (struct nandsim *)(((struct nand_chip *)nsmtd->priv)->priv);
+       struct nandsim *ns = ((struct nand_chip *)nsmtd->priv)->priv;
        int i;
 
        free_nandsim(ns);    /* Free nandsim private resources */
index 8d467315f02be00efd5b124f104feed37a8282b0..90e143e5ad3eb6bef4bc1bd065548237b93fd3f2 100644 (file)
@@ -91,7 +91,7 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
        }
 
        /* Scan to find existance of the device */
-       if (nand_scan(&data->mtd, 1)) {
+       if (nand_scan(&data->mtd, pdata->chip.nr_chips)) {
                err = -ENXIO;
                goto out;
        }
index bcfc851fe55069bc93ffb38b28f8985a4b87f704..5169ca6a66bcdf55df5033c1868b17964df83888 100644 (file)
@@ -64,8 +64,8 @@ static inline void r852_write_reg_dword(struct r852_device *dev,
 /* returns pointer to our private structure */
 static inline struct r852_device *r852_get_dev(struct mtd_info *mtd)
 {
-       struct nand_chip *chip = (struct nand_chip *)mtd->priv;
-       return (struct r852_device *)chip->priv;
+       struct nand_chip *chip = mtd->priv;
+       return chip->priv;
 }
 
 
@@ -380,7 +380,7 @@ void r852_cmdctl(struct mtd_info *mtd, int dat, unsigned int ctrl)
  */
 int r852_wait(struct mtd_info *mtd, struct nand_chip *chip)
 {
-       struct r852_device *dev = (struct r852_device *)chip->priv;
+       struct r852_device *dev = chip->priv;
 
        unsigned long timeout;
        int status;
index a033c4cd8e16e8b7a6d0b8225eedc78c8df0e690..67440b5beef8c7f12567b1f48240d621b66d324f 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/rslib.h>
 #include <linux/bitrev.h>
 #include <linux/module.h>
-#include <linux/mtd/compatmac.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
index 239aadfd01b0267b44dddeb5e4b9f1c3226a8d11..33d832dddfdd178ff2d9e986eada8dd0ec387c6d 100644 (file)
@@ -727,15 +727,12 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
        if (set == NULL)
                return add_mtd_device(&mtd->mtd);
 
-       if (set->nr_partitions == 0) {
-               mtd->mtd.name = set->name;
-               nr_part = parse_mtd_partitions(&mtd->mtd, part_probes,
-                                               &part_info, 0);
-       } else {
-               if (set->nr_partitions > 0 && set->partitions != NULL) {
-                       nr_part = set->nr_partitions;
-                       part_info = set->partitions;
-               }
+       mtd->mtd.name = set->name;
+       nr_part = parse_mtd_partitions(&mtd->mtd, part_probes, &part_info, 0);
+
+       if (nr_part <= 0 && set->nr_partitions > 0) {
+               nr_part = set->nr_partitions;
+               part_info = set->partitions;
        }
 
        if (nr_part > 0 && part_info)
index ac80fb362e632423753ff82bf1c060b0c7f12833..4a8f367c295c404780e59d61dbcf19802462c29f 100644 (file)
@@ -109,7 +109,7 @@ static struct nand_flash_dev nand_xd_flash_ids[] = {
 
 int sm_register_device(struct mtd_info *mtd, int smartmedia)
 {
-       struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+       struct nand_chip *chip = mtd->priv;
        int ret;
 
        chip->options |= NAND_SKIP_BBTSCAN;
index a4578bf903aa9ca6be19ceb3a0f14e4284e2acb8..b155666acfbe5a1c07ebfa37b1b1ec3c1140d07c 100644 (file)
@@ -1,11 +1,22 @@
-/* Linux driver for NAND Flash Translation Layer      */
-/* (c) 1999 Machine Vision Holdings, Inc.             */
-/* Author: David Woodhouse <dwmw2@infradead.org>      */
-
 /*
-  The contents of this file are distributed under the GNU General
-  Public License version 2. The author places no additional
-  restrictions of any kind on it.
+ * Linux driver for NAND Flash Translation Layer
+ *
+ * Copyright © 1999 Machine Vision Holdings, Inc.
+ * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
+ *
+ * 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
  */
 
 #define PRERELEASE
index 8b22b1836e9fee9281565e2e89294ec4d2b47ad5..e3cd1ffad2f624c203237068847a5643c3254941 100644 (file)
@@ -2,7 +2,8 @@
  * NFTL mount code with extensive checks
  *
  * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
- * Copyright (C) 2000 Netgem S.A.
+ * Copyright © 2000 Netgem S.A.
+ * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * 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
index 4f0d635674f334a0dd5d1699edff8659f82451d0..8bf7dc6d1ce6a452d9ad62185a6b77beab654db9 100644 (file)
@@ -1,11 +1,11 @@
 /*
  * Flash partitions described by the OF (or flattened) device tree
  *
- * Copyright (C) 2006 MontaVista Software Inc.
+ * Copyright © 2006 MontaVista Software Inc.
  * Author: Vitaly Wool <vwool@ru.mvista.com>
  *
  * Revised to handle newer style flash binding by:
- *   Copyright (C) 2007 David Gibson, IBM Corporation.
+ *   Copyright © 2007 David Gibson, IBM Corporation.
  *
  * 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
index 9a49d68ba5f90b6aca3c0bd522d666e3542a86e7..3f32289fdbb596e2e7d20f69e6cf92ecf6e492ec 100644 (file)
@@ -25,14 +25,14 @@ config MTD_ONENAND_GENERIC
 
 config MTD_ONENAND_OMAP2
        tristate "OneNAND on OMAP2/OMAP3 support"
-       depends on MTD_ONENAND && (ARCH_OMAP2 || ARCH_OMAP3)
+       depends on ARCH_OMAP2 || ARCH_OMAP3
        help
          Support for a OneNAND flash device connected to an OMAP2/OMAP3 CPU
          via the GPMC memory controller.
 
 config MTD_ONENAND_SAMSUNG
         tristate "OneNAND on Samsung SOC controller support"
-        depends on MTD_ONENAND && (ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210)
+        depends on ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210
         help
           Support for a OneNAND flash device connected to an Samsung SOC
           S3C64XX/S5PC1XX controller.
index 26caf2590dae1c55ee161f64854c467934164f95..a2bb520286f8f995a909527931cebdfbf63d6210 100644 (file)
@@ -377,8 +377,11 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
 
        default:
                block = onenand_block(this, addr);
-               page = (int) (addr - onenand_addr(this, block)) >> this->page_shift;
-
+               if (FLEXONENAND(this))
+                       page = (int) (addr - onenand_addr(this, block))>>\
+                               this->page_shift;
+               else
+                       page = (int) (addr >> this->page_shift);
                if (ONENAND_IS_2PLANE(this)) {
                        /* Make the even block number */
                        block &= ~1;
@@ -3730,17 +3733,16 @@ out:
 }
 
 /**
- * onenand_probe - [OneNAND Interface] Probe the OneNAND device
+ * onenand_chip_probe - [OneNAND Interface] The generic chip probe
  * @param mtd          MTD device structure
  *
  * OneNAND detection method:
  *   Compare the values from command with ones from register
  */
-static int onenand_probe(struct mtd_info *mtd)
+static int onenand_chip_probe(struct mtd_info *mtd)
 {
        struct onenand_chip *this = mtd->priv;
-       int bram_maf_id, bram_dev_id, maf_id, dev_id, ver_id;
-       int density;
+       int bram_maf_id, bram_dev_id, maf_id, dev_id;
        int syscfg;
 
        /* Save system configuration 1 */
@@ -3763,12 +3765,6 @@ static int onenand_probe(struct mtd_info *mtd)
        /* Restore system configuration 1 */
        this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
 
-       /* Workaround */
-       if (syscfg & ONENAND_SYS_CFG1_SYNC_WRITE) {
-               bram_maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
-               bram_dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
-       }
-
        /* Check manufacturer ID */
        if (onenand_check_maf(bram_maf_id))
                return -ENXIO;
@@ -3776,13 +3772,35 @@ static int onenand_probe(struct mtd_info *mtd)
        /* Read manufacturer and device IDs from Register */
        maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
        dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
-       ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
-       this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
 
        /* Check OneNAND device */
        if (maf_id != bram_maf_id || dev_id != bram_dev_id)
                return -ENXIO;
 
+       return 0;
+}
+
+/**
+ * onenand_probe - [OneNAND Interface] Probe the OneNAND device
+ * @param mtd          MTD device structure
+ */
+static int onenand_probe(struct mtd_info *mtd)
+{
+       struct onenand_chip *this = mtd->priv;
+       int maf_id, dev_id, ver_id;
+       int density;
+       int ret;
+
+       ret = this->chip_probe(mtd);
+       if (ret)
+               return ret;
+
+       /* Read manufacturer and device IDs from Register */
+       maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
+       dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
+       ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
+       this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
+
        /* Flash device information */
        onenand_print_device_info(dev_id, ver_id);
        this->device_id = dev_id;
@@ -3909,6 +3927,9 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
        if (!this->unlock_all)
                this->unlock_all = onenand_unlock_all;
 
+       if (!this->chip_probe)
+               this->chip_probe = onenand_chip_probe;
+
        if (!this->read_bufferram)
                this->read_bufferram = onenand_read_bufferram;
        if (!this->write_bufferram)
index a91fcac1af01c6cf0c4f1b20cb41836308ab5e17..01ab5b3c453bec598380a79cc2594fc70b760d89 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/slab.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/onenand.h>
-#include <linux/mtd/compatmac.h>
 
 /**
  * check_short_pattern - [GENERIC] check if a pattern is in the buffer
index 2750317cb58f0e2a329e88d20d680704fd80ccaa..cb443af3d45feee407bb79e8440f439cbdba7bd1 100644 (file)
@@ -630,6 +630,12 @@ normal:
        return 0;
 }
 
+static int s5pc110_chip_probe(struct mtd_info *mtd)
+{
+       /* Now just return 0 */
+       return 0;
+}
+
 static int s3c_onenand_bbt_wait(struct mtd_info *mtd, int state)
 {
        unsigned int flags = INT_ACT | LOAD_CMP;
@@ -757,6 +763,7 @@ static void s3c_onenand_setup(struct mtd_info *mtd)
                /* Use generic onenand functions */
                onenand->cmd_map = s5pc1xx_cmd_map;
                this->read_bufferram = s5pc110_read_bufferram;
+               this->chip_probe = s5pc110_chip_probe;
                return;
        } else {
                BUG();
@@ -781,7 +788,6 @@ static int s3c_onenand_probe(struct platform_device *pdev)
        struct mtd_info *mtd;
        struct resource *r;
        int size, err;
-       unsigned long onenand_ctrl_cfg = 0;
 
        pdata = pdev->dev.platform_data;
        /* No need to check pdata. the platform data is optional */
@@ -900,14 +906,6 @@ static int s3c_onenand_probe(struct platform_device *pdev)
                }
 
                onenand->phys_base = onenand->base_res->start;
-
-               onenand_ctrl_cfg = readl(onenand->dma_addr + 0x100);
-               if ((onenand_ctrl_cfg & ONENAND_SYS_CFG1_SYNC_WRITE) &&
-                   onenand->dma_addr)
-                       writel(onenand_ctrl_cfg & ~ONENAND_SYS_CFG1_SYNC_WRITE,
-                                       onenand->dma_addr + 0x100);
-               else
-                       onenand_ctrl_cfg = 0;
        }
 
        if (onenand_scan(mtd, 1)) {
@@ -915,10 +913,7 @@ static int s3c_onenand_probe(struct platform_device *pdev)
                goto scan_failed;
        }
 
-       if (onenand->type == TYPE_S5PC110) {
-               if (onenand_ctrl_cfg && onenand->dma_addr)
-                       writel(onenand_ctrl_cfg, onenand->dma_addr + 0x100);
-       } else {
+       if (onenand->type != TYPE_S5PC110) {
                /* S3C doesn't handle subpage write */
                mtd->subpage_sft = 0;
                this->subpagesize = mtd->writesize;
index 2d600a1bf2aa76e804679e2df284d8b7f9be2742..7a87d07cd79f4bcae8dcf11241d0b052fa765cd9 100644 (file)
@@ -1,6 +1,24 @@
 /*
  * Parse RedBoot-style Flash Image System (FIS) tables and
  * produce a Linux partition array to match.
+ *
+ * Copyright © 2001      Red Hat UK Limited
+ * Copyright © 2001-2010 David Woodhouse <dwmw2@infradead.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
  */
 
 #include <linux/kernel.h>
index 63b83c0d9a134ae9ba9591840b06926f90a10ca7..cc4d1805b864d3504f57b227a94b1747f2f7fe50 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * rfd_ftl.c -- resident flash disk (flash translation layer)
  *
- * Copyright (C) 2005  Sean Young <sean@mess.org>
+ * Copyright © 2005  Sean Young <sean@mess.org>
  *
  * This type of flash translation layer (FTL) is used by the Embedded BIOS
  * by General Software. It is known as the Resident Flash Disk (RFD), see:
index 81c4ecdc11f515b92bf10f72573864f87dfdfbb1..5cd18979333296b738696d9430d79b2cd4ce2775 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Linux driver for SSFDC Flash Translation Layer (Read only)
- * (c) 2005 Eptar srl
+ * © 2005 Eptar srl
  * Author: Claudio Lanconelli <lanconelli.claudio@eptar.com>
  *
  * Based on NTFL and MTDBLOCK_RO drivers
index 6bc1b8276c6270353a97a726ec3b999cfe9d7cbf..00b937e38c1d509abcda5cbd6cfc429c06b0807b 100644 (file)
@@ -310,7 +310,7 @@ static int crosstest(void)
 static int erasecrosstest(void)
 {
        size_t read = 0, written = 0;
-       int err = 0, i, ebnum, ok = 1, ebnum2;
+       int err = 0, i, ebnum, ebnum2;
        loff_t addr0;
        char *readbuf = twopages;
 
@@ -357,8 +357,7 @@ static int erasecrosstest(void)
        if (memcmp(writebuf, readbuf, pgsize)) {
                printk(PRINT_PREF "verify failed!\n");
                errcnt += 1;
-               ok = 0;
-               return err;
+               return -1;
        }
 
        printk(PRINT_PREF "erasing block %d\n", ebnum);
@@ -396,10 +395,10 @@ static int erasecrosstest(void)
        if (memcmp(writebuf, readbuf, pgsize)) {
                printk(PRINT_PREF "verify failed!\n");
                errcnt += 1;
-               ok = 0;
+               return -1;
        }
 
-       if (ok && !err)
+       if (!err)
                printk(PRINT_PREF "erasecrosstest ok\n");
        return err;
 }
index 55f1dde2fa8b01ebd9b95266f9457d0b2bd9bb94..404111b016c93324535b4551dd2239f35c398966 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
index c5e1450d79f9d311ea5e797554227230200db4c7..a906f538d11ce33d0f9c81e38cbaf95528030638 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
index f0294410868d4ecd93ebae7f798d65c7c0299104..617a1e5694c1bf8598ca6b5f4c03d4eb65a79d48 100644 (file)
@@ -2,11 +2,12 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
- * Created by Arjan van de Ven <arjanv@redhat.com>
- *
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
  *                 University of Szeged, Hungary
  *
+ * Created by Arjan van de Ven <arjan@infradead.org>
+ *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
  */
index 7d1d72faa7745498a6e3667ec18203154d6b2417..e471a9106fd942515fb8af1d52a22a7cc1f8bb92 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Copyright © 2004   Ferenc Havasi <havasi@inf.u-szeged.hu>,
  *                   University of Szeged, Hungary
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
index cd02acafde8a3352a8fd639704b924b86c9e0160..ed25ae7c98eba0935d10ef3ba20ce4dd2607be86 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2007 Nokia Corporation. All rights reserved.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by Richard Purdie <rpurdie@openedhand.com>
  *
index 546d1538d0762eaf61007fd9d0efbc2f6b57933c..9696ad9ef5f77675dddebd17705a36059de6fc78 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by Arjan van de Ven <arjanv@redhat.com>
  *
index 170d289ac785fcb09ef88004ec2a6f959465a28a..a12b4f763373ff60f8af242f6eec1110ad8eda4c 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by Arjan van de Ven <arjanv@redhat.com>
  *
index b46661a4275866e95f0cd174cd82e498db13532d..97fc45de6f81eace3538ae22e9e8239834d9856f 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
index ec3538413926f677feb3d763df9a7ebaa5d7a07d..e0b76c87a91af298712a5ebc06b3ac7e8a953238 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
index a113ecc3bafeeb5f74172d8d5eb98e09f6eb6979..c4f8eef5ca68b79d82aee1314166ce61802a90b7 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
index 5fd3b5cecda5fa8004932646617728cbb20c0f6b..ed78a3cf3cb047046d8ea385af9554e63214aac8 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
index 6286ad9b00f756c48b85283054ae078c910a1d23..abac961f617b88a739ad3bfbaa49233d45d9e6d4 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
index 8134970244376526710bd99922d823a699306170..1c0a08d711aa431a72770f33840cd5c1b9d997ad 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
index ac0638f049698e1b227c559f0c203ee2497a59cd..6b2964a19850936dce9648c28669c40f4a1928c8 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
index f5e96bd656e85612d844952b01e9561a0b637419..846a79452497b9adcb20b831a8e12c6037038d9d 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
index 9d41f43e47bb29766bc6b309b7179e4d5cee759f..859a598af020907b390c6ff74d8f1e7b4647865e 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
index c6923da98263331c39dd3eea3d5c3c5f6232f39a..2e4a86763c07cd12b945518690768c4a0388de5f 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
index 85ef6dbb1be7adb3dbbd3553f008a32fe1c35dfc..6784bc89add1da39222a5c0c3cfbf4943462332f 100644 (file)
@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
index a881a42f19e3159b8c376e488cd96204c41771c0..523a91691052065e3bf03bec79c59ae309b2398f 100644 (file)
@@ -24,7 +24,6 @@
 #ifdef __ECOS
 #include "os-ecos.h"
 #else
-#include <linux/mtd/compatmac.h> /* For compatibility with older kernels */
 #include "os-linux.h"
 #endif
 
index edb9231f18988b7bf2502e2023237f5a702cd9b1..a18b719f49d4dfbbb978270f791fe992cfc8b2a9 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
- * Copyright (C) 2001-2003 Red Hat, Inc.
+ * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
index 9c3757c5759db88a21501bf69285ab5277818344..7fa20beb2ab9e19786f1358d61afa02f0bf30e81 100644 (file)
@@ -4,12 +4,26 @@
  *  NAND family Bad Block Management (BBM) header file
  *    - Bad Block Table (BBT) implementation
  *
- *  Copyright (c) 2005 Samsung Electronics
+ *  Copyright © 2005 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *
- *  Copyright (c) 2000-2005
+ *  Copyright © 2000-2005
  *  Thomas Gleixner <tglx@linuxtronix.de>
  *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
  */
 #ifndef __LINUX_MTD_BBM_H
 #define __LINUX_MTD_BBM_H
@@ -82,6 +96,12 @@ struct nand_bbt_descr {
 #define NAND_BBT_SAVECONTENT   0x00002000
 /* Search good / bad pattern on the first and the second page */
 #define NAND_BBT_SCAN2NDPAGE   0x00004000
+/* Search good / bad pattern on the last page of the eraseblock */
+#define NAND_BBT_SCANLASTPAGE  0x00008000
+/* Chip stores bad block marker on BOTH 1st and 6th bytes of OOB */
+#define NAND_BBT_SCANBYTE1AND6 0x00100000
+/* The nand_bbt_descr was created dynamicaly and must be freed */
+#define NAND_BBT_DYNAMICSTRUCT 0x00200000
 
 /* The maximum number of blocks to scan for a bbt */
 #define NAND_BBT_SCAN_MAXBLOCKS        4
index b481ccd7ff3c30330046f6b24311f5fcc6e0ef0f..26529ebd59ccf3872fddca921c141184915fcf62 100644 (file)
@@ -1,7 +1,19 @@
 /*
- * (C) 2003 David Woodhouse <dwmw2@infradead.org>
+ * Copyright © 2003-2010 David Woodhouse <dwmw2@infradead.org>
  *
- * Interface to Linux block layer for MTD 'translation layers'.
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  */
 
index 574d9ee066f1bad2b81776bfd650002c54563499..d2118b0eac9ae12fcfd7a7b8c951f3863b096a0a 100644 (file)
@@ -1,6 +1,20 @@
-
-/* Common Flash Interface structures
- * See http://support.intel.com/design/flash/technote/index.htm
+/*
+ * Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org> et al.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
  */
 
 #ifndef __MTD_CFI_H__
index d802f7736be3a474b0cee222b5d3648d8caf1812..51cc3f5917a80725683421d501f1f0016c284aa6 100644 (file)
@@ -1,3 +1,22 @@
+/*
+ * Copyright © 2001-2010 David Woodhouse <dwmw2@infradead.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
 #include <asm/byteorder.h>
 
 #ifndef CONFIG_MTD_CFI_ADV_OPTIONS
diff --git a/include/linux/mtd/compatmac.h b/include/linux/mtd/compatmac.h
deleted file mode 100644 (file)
index 7d1300d..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-
-#ifndef __LINUX_MTD_COMPATMAC_H__
-#define __LINUX_MTD_COMPATMAC_H__
-
-/* Nothing to see here. We write 2.5-compatible code and this
-   file makes it all OK in older kernels, but it's empty in _current_
-   kernels. Include guard just to make GCC ignore it in future inclusions
-   anyway... */
-
-#endif /* __LINUX_MTD_COMPATMAC_H__ */
index e80c674daeb38c8385c55d7e89b87f3909dcc201..ccdbe93a909c2a8fb8575fd2c1f664041ec821e6 100644 (file)
@@ -1,9 +1,22 @@
 /*
  * MTD device concatenation layer definitions
  *
- * (C) 2002 Robert Kaiser <rkaiser@sysgo.de>
+ * Copyright © 2002      Robert Kaiser <rkaiser@sysgo.de>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
- * This code is GPL
  */
 
 #ifndef MTD_CONCAT_H
index 0a6d516ab71d9ba2eb97a7789593b040fb99dcb8..0f6fea73a1f6713c17a29c0e12133a18e883d9b5 100644 (file)
@@ -1,12 +1,25 @@
 /*
  * Linux driver for Disk-On-Chip devices
  *
- * Copyright (C) 1999 Machine Vision Holdings, Inc.
- * Copyright (C) 2001-2003 David Woodhouse <dwmw2@infradead.org>
- * Copyright (C) 2002-2003 Greg Ungerer <gerg@snapgear.com>
- * Copyright (C) 2002-2003 SnapGear Inc
+ * Copyright © 1999 Machine Vision Holdings, Inc.
+ * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
+ * Copyright © 2002-2003 Greg Ungerer <gerg@snapgear.com>
+ * Copyright © 2002-2003 SnapGear Inc
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
- * Released under GPL
  */
 
 #ifndef __MTD_DOC2000_H__
index f43e9b49b751bd479e033e154cc0440689f9ff52..b63fa457febd8d5d379ffe891e981ea2c8e912c8 100644 (file)
@@ -1,10 +1,21 @@
-
 /*
- * struct flchip definition
+ * Copyright © 2000      Red Hat UK Limited
+ * Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org>
+ *
+ * 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.
  *
- * Contains information about the location and state of a given flash device
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
- * (C) 2000 Red Hat. GPLd.
  */
 
 #ifndef __MTD_FLASHCHIP_H__
@@ -92,7 +103,7 @@ struct flchip {
 /* This is used to handle contention on write/erase operations
    between partitions of the same physical chip. */
 struct flchip_shared {
-       spinlock_t lock;
+       struct mutex lock;
        struct flchip *writing;
        struct flchip *erasing;
 };
index df362ddf2949f0f9a49bbd278f87dfa0ec8f5bae..2c456054fded8992d9a45b841398e8b42614f85d 100644 (file)
@@ -1,6 +1,21 @@
 /*
- * (C) 2001, 2001 Red Hat, Inc.
- * GPL'd
+ * Copyright © 2001      Red Hat UK Limited
+ * Copyright © 2001-2010 David Woodhouse <dwmw2@infradead.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
  */
 
 #ifndef __LINUX_MTD_GEN_PROBE_H__
index de89eca864ce02dc4317a4f9e52f328785866473..a9e6ba46865eb9a3be3a2713f6819bf988462b22 100644 (file)
@@ -1,3 +1,21 @@
+/*
+ * Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org> et al.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
 
 /* Overhauled routines for dealing with different mmap regions of flash */
 
@@ -9,7 +27,6 @@
 #include <linux/string.h>
 #include <linux/bug.h>
 
-#include <linux/mtd/compatmac.h>
 
 #include <asm/unaligned.h>
 #include <asm/system.h>
index 5326435a757173e7cd09ce6071b5a904518780bf..8485e42a9b092327e797383d7de8848dfb4d36cb 100644 (file)
@@ -1,7 +1,20 @@
 /*
- * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al.
+ * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org> et al.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
- * Released under GPL
  */
 
 #ifndef __MTD_MTD_H__
@@ -13,7 +26,6 @@
 #include <linux/notifier.h>
 #include <linux/device.h>
 
-#include <linux/mtd/compatmac.h>
 #include <mtd/mtd-abi.h>
 
 #include <asm/div64.h>
@@ -216,6 +228,7 @@ struct mtd_info {
        /* Chip-supported device locking */
        int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
        int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
+       int (*is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
 
        /* Power Management functions */
        int (*suspend) (struct mtd_info *mtd);
index a81b185e23a754f0474fa5eecf24acd96661fb5f..102e12c58cb3bbef023e0802c81f532a8cf428b0 100644 (file)
@@ -1,9 +1,9 @@
 /*
  *  linux/include/linux/mtd/nand.h
  *
- *  Copyright (c) 2000 David Woodhouse <dwmw2@infradead.org>
- *                     Steven J. Hill <sjhill@realitydiluted.com>
- *                    Thomas Gleixner <tglx@linutronix.de>
+ *  Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org>
+ *                        Steven J. Hill <sjhill@realitydiluted.com>
+ *                       Thomas Gleixner <tglx@linutronix.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
@@ -181,8 +181,6 @@ typedef enum {
 #define NAND_NO_READRDY                0x00000100
 /* Chip does not allow subpage writes */
 #define NAND_NO_SUBPAGE_WRITE  0x00000200
-/* Chip stores bad block marker on the last page of the eraseblock */
-#define NAND_BB_LAST_PAGE      0x00000400
 
 /* Device is one of 'new' xD cards that expose fake nand command set */
 #define NAND_BROKEN_XD         0x00000400
index 41bc013571d05eaa7a3dce82ea8eb00c53cb44af..4d8406c816523e50546e0ef16f0ec8460ecda26c 100644 (file)
@@ -1,7 +1,9 @@
 /*
  *  drivers/mtd/nand_ecc.h
  *
- *  Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
+ *  Copyright (C) 2000-2010 Steven J. Hill <sjhill@realitydiluted.com>
+ *                         David Woodhouse <dwmw2@infradead.org>
+ *                         Thomas Gleixner <tglx@linutronix.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
index dcaf611ed74826a5b2a018482e84b38449e08681..b059629e22bc6901f9f17007672b0ee2f24191ec 100644 (file)
@@ -1,5 +1,20 @@
 /*
- * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
+ * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
  */
 
 #ifndef __MTD_NFTL_H__
index c26ff86ad08aa51ec57a9479d6a77b5e2560455d..0c8815bfae1c4583d3d34c24fcb58c3d4593b7db 100644 (file)
@@ -68,6 +68,7 @@ struct onenand_bufferram {
  * @write_word:                [REPLACEABLE] hardware specific function for write
  *                     register of OneNAND
  * @mmcontrol:         sync burst read function
+ * @chip_probe:                [REPLACEABLE] hardware specific function for chip probe
  * @block_markbad:     function to mark a block as bad
  * @scan_bbt:          [REPLACEALBE] hardware specific function for scanning
  *                     Bad block Table
@@ -114,6 +115,7 @@ struct onenand_chip {
        unsigned short (*read_word)(void __iomem *addr);
        void (*write_word)(unsigned short value, void __iomem *addr);
        void (*mmcontrol)(struct mtd_info *mtd, int sync_read);
+       int (*chip_probe)(struct mtd_info *mtd);
        int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
        int (*scan_bbt)(struct mtd_info *mtd);
 
index 76f7cabf07d322ade437ca757a1c6bd9d93b6107..bcfd9f777454247d95dc077c510b6d8c87e863a9 100644 (file)
@@ -25,6 +25,7 @@ struct physmap_flash_data {
        void                    (*set_vpp)(struct map_info *, int);
        unsigned int            nr_parts;
        unsigned int            pfow_base;
+       char                    *probe_type;
        struct mtd_partition    *parts;
 };
 
index be51ae2bd0ffd955428eaabf00317ba45d28a569..4debb451463474a30da023f25161b4077e58f6c0 100644 (file)
@@ -1,5 +1,20 @@
 /*
- * Portions of MTD ABI definition which are shared by kernel and user space
+ * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org> et al.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
  */
 
 #ifndef __MTD_ABI_H__
@@ -110,6 +125,7 @@ struct otp_info {
 #define MEMERASE64             _IOW('M', 20, struct erase_info_user64)
 #define MEMWRITEOOB64          _IOWR('M', 21, struct mtd_oob_buf64)
 #define MEMREADOOB64           _IOWR('M', 22, struct mtd_oob_buf64)
+#define MEMISLOCKED            _IOR('M', 23, struct erase_info_user)
 
 /*
  * Obsolete legacy interface. Keep it in order not to break userspace
index 170ceca3b2d08fb2c77362d8c061f6dc6d51f59d..aa3c2f86a91335e2e755d54399c852d954771141 100644 (file)
@@ -1,5 +1,20 @@
 /*
- * MTD ABI header for use by user space only.
+ * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
  */
 
 #ifndef __MTD_USER_H__
index 98e9e57f22de1925d8448288c5d27c67220b5ffc..bdeabd86ad99efb10590853a357d1088a31a38ac 100644 (file)
@@ -1,5 +1,19 @@
 /*
- * Parts of NFTL headers shared with userspace
+ * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  */
 
index 466a8320f1e6dfe010719c317a9a11962f15a41c..c0d47ad4b103b5a502cf98230f3d52da3e38d74b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) International Business Machines Corp., 2006
+ * Copyright © International Business Machines Corp., 2006
  *
  * 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