]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'l2-mtd/master'
authorThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2013 12:35:47 +0000 (14:35 +0200)
committerThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2013 12:35:47 +0000 (14:35 +0200)
54 files changed:
Documentation/ABI/testing/sysfs-class-mtd
arch/powerpc/include/asm/fsl_ifc.h
drivers/mtd/bcm47xxpart.c
drivers/mtd/devices/block2mtd.c
drivers/mtd/devices/docg3.c
drivers/mtd/devices/m25p80.c
drivers/mtd/devices/mtd_dataflash.c
drivers/mtd/devices/phram.c
drivers/mtd/devices/sst25l.c
drivers/mtd/inftlcore.c
drivers/mtd/lpddr/lpddr_cmds.c
drivers/mtd/maps/intel_vr_nor.c
drivers/mtd/maps/pci.c
drivers/mtd/maps/plat-ram.c
drivers/mtd/maps/scb2_flash.c
drivers/mtd/mtdblock.c
drivers/mtd/mtdblock_ro.c
drivers/mtd/mtdchar.c
drivers/mtd/mtdcore.c
drivers/mtd/mtdsuper.c
drivers/mtd/nand/atmel_nand.c
drivers/mtd/nand/bcm47xxnflash/main.c
drivers/mtd/nand/denali.c
drivers/mtd/nand/denali_pci.c
drivers/mtd/nand/diskonchip.c
drivers/mtd/nand/docg4.c
drivers/mtd/nand/fsl_elbc_nand.c
drivers/mtd/nand/fsl_ifc_nand.c
drivers/mtd/nand/gpmi-nand/gpmi-lib.c
drivers/mtd/nand/gpmi-nand/gpmi-nand.c
drivers/mtd/nand/gpmi-nand/gpmi-regs.h
drivers/mtd/nand/lpc32xx_mlc.c
drivers/mtd/nand/lpc32xx_slc.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_bbt.c
drivers/mtd/nand/nandsim.c
drivers/mtd/nand/pxa3xx_nand.c
drivers/mtd/nand/socrates_nand.c
drivers/mtd/nftlcore.c
drivers/mtd/onenand/omap2.c
drivers/mtd/onenand/onenand_base.c
drivers/mtd/ssfdc.c
drivers/mtd/tests/nandbiterrs.c
drivers/mtd/tests/oobtest.c
drivers/mtd/tests/pagetest.c
drivers/mtd/tests/subpagetest.c
drivers/mtd/ubi/build.c
fs/jffs2/fs.c
include/linux/mtd/map.h
include/linux/mtd/mtd.h
include/linux/mtd/nand.h
include/linux/of_mtd.h
include/uapi/linux/major.h
include/uapi/mtd/mtd-abi.h

index bfd119ace6ad00c2ee56c4c16b25a78ec6b5d7f0..1399bb2da3ebf762ffd0c392c07121d1687ee1dd 100644 (file)
@@ -104,7 +104,7 @@ Description:
                One of the following ASCII strings, representing the device
                type:
 
-               absent, ram, rom, nor, nand, dataflash, ubi, unknown
+               absent, ram, rom, nor, nand, mlc-nand, dataflash, ubi, unknown
 
 What:          /sys/class/mtd/mtdX/writesize
 Date:          April 2009
index b8a4b9bc50b326b07efda9e6f82e59e16be3e318..f49ddb1b2273b0d46e1cbf07ca434287a42e3cca 100644 (file)
@@ -93,6 +93,7 @@
 #define CSOR_NAND_PGS_512              0x00000000
 #define CSOR_NAND_PGS_2K               0x00080000
 #define CSOR_NAND_PGS_4K               0x00100000
+#define CSOR_NAND_PGS_8K               0x00180000
 /* Spare region Size */
 #define CSOR_NAND_SPRZ_MASK            0x0000E000
 #define CSOR_NAND_SPRZ_SHIFT           13
 #define CSOR_NAND_SPRZ_210             0x00006000
 #define CSOR_NAND_SPRZ_218             0x00008000
 #define CSOR_NAND_SPRZ_224             0x0000A000
+#define CSOR_NAND_SPRZ_CSOR_EXT                0x0000C000
 /* Pages Per Block */
 #define CSOR_NAND_PB_MASK              0x00000700
 #define CSOR_NAND_PB_SHIFT             8
index 9279a9174f84ad9cd3a2ae2c7117c29cc8134e9e..7a6384b0962a9de2c92dffb81f1fc45d6d89a490 100644 (file)
 
 /* Magics */
 #define BOARD_DATA_MAGIC               0x5246504D      /* MPFR */
+#define FACTORY_MAGIC                  0x59544346      /* FCTY */
 #define POT_MAGIC1                     0x54544f50      /* POTT */
 #define POT_MAGIC2                     0x504f          /* OP */
 #define ML_MAGIC1                      0x39685a42
 #define ML_MAGIC2                      0x26594131
 #define TRX_MAGIC                      0x30524448
+#define SQSH_MAGIC                     0x71736873      /* shsq */
 
 struct trx_header {
        uint32_t magic;
@@ -71,7 +73,14 @@ static int bcm47xxpart_parse(struct mtd_info *master,
        /* Alloc */
        parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS,
                        GFP_KERNEL);
+       if (!parts)
+               return -ENOMEM;
+
        buf = kzalloc(BCM47XXPART_BYTES_TO_READ, GFP_KERNEL);
+       if (!buf) {
+               kfree(parts);
+               return -ENOMEM;
+       }
 
        /* Parse block by block looking for magics */
        for (offset = 0; offset <= master->size - blocksize;
@@ -110,6 +119,13 @@ static int bcm47xxpart_parse(struct mtd_info *master,
                        continue;
                }
 
+               /* Found on Huawei E970 */
+               if (buf[0x000 / 4] == FACTORY_MAGIC) {
+                       bcm47xxpart_add_part(&parts[curr_part++], "factory",
+                                            offset, MTD_WRITEABLE);
+                       continue;
+               }
+
                /* POT(TOP) */
                if (buf[0x000 / 4] == POT_MAGIC1 &&
                    (buf[0x004 / 4] & 0xFFFF) == POT_MAGIC2) {
@@ -167,6 +183,13 @@ static int bcm47xxpart_parse(struct mtd_info *master,
                        offset = rounddown(offset + trx->length, blocksize);
                        continue;
                }
+
+               /* Squashfs on devices not using TRX */
+               if (buf[0x000 / 4] == SQSH_MAGIC) {
+                       bcm47xxpart_add_part(&parts[curr_part++], "rootfs",
+                                            offset, 0);
+                       continue;
+               }
        }
 
        /* Look for NVRAM at the end of the last block. */
index 5cb4c04726b2e0eb58dd6452b293602f82fa1945..d9fd87a4c8dc08a6b191e4454cf529898c1688c6 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/mutex.h>
 #include <linux/mount.h>
 #include <linux/slab.h>
+#include <linux/major.h>
 
 /* Info for the block device */
 struct block2mtd_dev {
index 3e1b0a0ef4dba22e559b74e603ebe1bf90f389cb..4f091c1a9981c060e3ea2cae43960ade8b4bc2f7 100644 (file)
@@ -2097,7 +2097,7 @@ notfound:
        ret = -ENODEV;
        dev_info(dev, "No supported DiskOnChip found\n");
 err_probe:
-       kfree(cascade->bch);
+       free_bch(cascade->bch);
        for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++)
                if (cascade->floors[floor])
                        doc_release_device(cascade->floors[floor]);
index 6bc9618af0942528d67e7846810adf7c2288b75a..8d6c87be95982f22ec48c79fe581dc0a387116e6 100644 (file)
@@ -756,6 +756,9 @@ static const struct spi_device_id m25p_ids[] = {
        { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
        { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) },
 
+       /* ESMT */
+       { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K) },
+
        /* Everspin */
        { "mr25h256", CAT25_INFO(  32 * 1024, 1, 256, 2, M25P_NO_ERASE | M25P_NO_FR) },
        { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, M25P_NO_ERASE | M25P_NO_FR) },
@@ -787,6 +790,7 @@ static const struct spi_device_id m25p_ids[] = {
        { "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
        { "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
        { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
+       { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K) },
 
        /* PMC */
        { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
index 0e8cbfeba11e42a85da4a843cd7f212263eb9448..1cfbfcfb6e191f7a41db7b0e696b7d082bf20788 100644 (file)
@@ -88,8 +88,6 @@ struct dataflash {
        uint8_t                 command[4];
        char                    name[24];
 
-       unsigned                partitioned:1;
-
        unsigned short          page_offset;    /* offset in flash address */
        unsigned int            page_size;      /* of bytes per page */
 
index 67823de68db69e7f2ae80d378ed7b9289eb811e0..e1f2aebaa48955035f6eef98f31e7640202461f1 100644 (file)
@@ -94,7 +94,7 @@ static void unregister_devices(void)
        }
 }
 
-static int register_device(char *name, unsigned long start, unsigned long len)
+static int register_device(char *name, phys_addr_t start, size_t len)
 {
        struct phram_mtd_list *new;
        int ret = -ENOMEM;
@@ -141,35 +141,35 @@ out0:
        return ret;
 }
 
-static int ustrtoul(const char *cp, char **endp, unsigned int base)
+static int parse_num64(uint64_t *num64, char *token)
 {
-       unsigned long result = simple_strtoul(cp, endp, base);
-
-       switch (**endp) {
-       case 'G':
-               result *= 1024;
-       case 'M':
-               result *= 1024;
-       case 'k':
-               result *= 1024;
+       size_t len;
+       int shift = 0;
+       int ret;
+
+       len = strlen(token);
        /* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */
-               if ((*endp)[1] == 'i')
-                       (*endp) += 2;
+       if (len > 2) {
+               if (token[len - 1] == 'i') {
+                       switch (token[len - 2]) {
+                       case 'G':
+                               shift += 10;
+                       case 'M':
+                               shift += 10;
+                       case 'k':
+                               shift += 10;
+                               token[len - 2] = 0;
+                               break;
+                       default:
+                               return -EINVAL;
+                       }
+               }
        }
-       return result;
-}
 
-static int parse_num32(uint32_t *num32, const char *token)
-{
-       char *endp;
-       unsigned long n;
+       ret = kstrtou64(token, 0, num64);
+       *num64 <<= shift;
 
-       n = ustrtoul(token, &endp, 0);
-       if (*endp)
-               return -EINVAL;
-
-       *num32 = n;
-       return 0;
+       return ret;
 }
 
 static int parse_name(char **pname, const char *token)
@@ -209,19 +209,19 @@ static inline void kill_final_newline(char *str)
  * This shall contain the module parameter if any. It is of the form:
  * - phram=<device>,<address>,<size> for module case
  * - phram.phram=<device>,<address>,<size> for built-in case
- * We leave 64 bytes for the device name, 12 for the address and 12 for the
+ * We leave 64 bytes for the device name, 20 for the address and 20 for the
  * size.
  * Example: phram.phram=rootfs,0xa0000000,512Mi
  */
-static __initdata char phram_paramline[64+12+12];
+static __initdata char phram_paramline[64 + 20 + 20];
 
 static int __init phram_setup(const char *val)
 {
-       char buf[64+12+12], *str = buf;
+       char buf[64 + 20 + 20], *str = buf;
        char *token[3];
        char *name;
-       uint32_t start;
-       uint32_t len;
+       uint64_t start;
+       uint64_t len;
        int i, ret;
 
        if (strnlen(val, sizeof(buf)) >= sizeof(buf))
@@ -243,13 +243,13 @@ static int __init phram_setup(const char *val)
        if (ret)
                return ret;
 
-       ret = parse_num32(&start, token[1]);
+       ret = parse_num64(&start, token[1]);
        if (ret) {
                kfree(name);
                parse_err("illegal start address\n");
        }
 
-       ret = parse_num32(&len, token[2]);
+       ret = parse_num64(&len, token[2]);
        if (ret) {
                kfree(name);
                parse_err("illegal device length\n");
@@ -257,7 +257,7 @@ static int __init phram_setup(const char *val)
 
        ret = register_device(name, start, len);
        if (!ret)
-               pr_info("%s device: %#x at %#x\n", name, len, start);
+               pr_info("%s device: %#llx at %#llx\n", name, len, start);
        else
                kfree(name);
 
index a42f1f0e7281417398f4de453845ff8edf79b60c..687bf27ec85076c2d735418714c12c537c2dc498 100644 (file)
@@ -364,7 +364,7 @@ static int sst25l_probe(struct spi_device *spi)
        if (!flash_info)
                return -ENODEV;
 
-       flash = kzalloc(sizeof(struct sst25l_flash), GFP_KERNEL);
+       flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
        if (!flash)
                return -ENOMEM;
 
@@ -402,11 +402,8 @@ static int sst25l_probe(struct spi_device *spi)
        ret = mtd_device_parse_register(&flash->mtd, NULL, NULL,
                                        data ? data->parts : NULL,
                                        data ? data->nr_parts : 0);
-       if (ret) {
-               kfree(flash);
-               spi_set_drvdata(spi, NULL);
+       if (ret)
                return -ENODEV;
-       }
 
        return 0;
 }
@@ -414,12 +411,8 @@ static int sst25l_probe(struct spi_device *spi)
 static int sst25l_remove(struct spi_device *spi)
 {
        struct sst25l_flash *flash = spi_get_drvdata(spi);
-       int ret;
 
-       ret = mtd_device_unregister(&flash->mtd);
-       if (ret == 0)
-               kfree(flash);
-       return ret;
+       return mtd_device_unregister(&flash->mtd);
 }
 
 static struct spi_driver sst25l_driver = {
index 3af351484098b6b47c5b0973dda092abdc1bfe0d..b66b541877f0aea5c84e947f72bb45b557fc403a 100644 (file)
@@ -50,7 +50,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
        struct INFTLrecord *inftl;
        unsigned long temp;
 
-       if (mtd->type != MTD_NANDFLASH || mtd->size > UINT_MAX)
+       if (!mtd_type_is_nand(mtd) || mtd->size > UINT_MAX)
                return;
        /* OK, this is moderately ugly.  But probably safe.  Alternatives? */
        if (memcmp(mtd->name, "DiskOnChip", 10))
index d3cfe26beeaa6bcc771a085f1e3f41d641af4c19..2ef19aa0086bee62d51a9986ea50f5983461869c 100644 (file)
@@ -703,7 +703,7 @@ static int lpddr_erase(struct mtd_info *mtd, struct erase_info *instr)
 
 #define DO_XXLOCK_LOCK         1
 #define DO_XXLOCK_UNLOCK       2
-int do_xxlock(struct mtd_info *mtd, loff_t adr, uint32_t len, int thunk)
+static int do_xxlock(struct mtd_info *mtd, loff_t adr, uint32_t len, int thunk)
 {
        int ret = 0;
        struct map_info *map = mtd->priv;
index f581ac1cf022fb006be3b814f6f1b23341f9e851..46d195fca94267631887f76d7d98f7d67005f3b7 100644 (file)
@@ -180,7 +180,6 @@ static void vr_nor_pci_remove(struct pci_dev *dev)
 {
        struct vr_nor_mtd *p = pci_get_drvdata(dev);
 
-       pci_set_drvdata(dev, NULL);
        vr_nor_destroy_partitions(p);
        vr_nor_destroy_mtd_setup(p);
        vr_nor_destroy_maps(p);
index c2604f8b2a5efccd1cde4f77db2be09eb9ce1624..36da518915b52b8220e5e6d23ed57acc6738ce0e 100644 (file)
@@ -316,7 +316,6 @@ static void mtd_pci_remove(struct pci_dev *dev)
        map->exit(dev, map);
        kfree(map);
 
-       pci_set_drvdata(dev, NULL);
        pci_release_regions(dev);
 }
 
index 676271659b37442a85d4d545fca05f80c48bdb54..10196f5a897d6b31674232652869cb5617e820ec 100644 (file)
@@ -55,7 +55,7 @@ struct platram_info {
 
 static inline struct platram_info *to_platram_info(struct platform_device *dev)
 {
-       return (struct platram_info *)platform_get_drvdata(dev);
+       return platform_get_drvdata(dev);
 }
 
 /* platram_setrw
@@ -257,21 +257,7 @@ static struct platform_driver platram_driver = {
        },
 };
 
-/* module init/exit */
-
-static int __init platram_init(void)
-{
-       printk("Generic platform RAM MTD, (c) 2004 Simtec Electronics\n");
-       return platform_driver_register(&platram_driver);
-}
-
-static void __exit platram_exit(void)
-{
-       platform_driver_unregister(&platram_driver);
-}
-
-module_init(platram_init);
-module_exit(platram_exit);
+module_platform_driver(platram_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
index c77b68c9412f8631955f6b52df633a6ab3fbce07..3051c4c362404bab5119dcf00d8c1e7321e4dbf3 100644 (file)
@@ -212,7 +212,6 @@ static void scb2_flash_remove(struct pci_dev *dev)
 
        if (!region_fail)
                release_mem_region(SCB2_ADDR, SCB2_WINDOW);
-       pci_set_drvdata(dev, NULL);
 }
 
 static struct pci_device_id scb2_flash_pci_ids[] = {
index 2aef5dda522be57cbd6652963d4078966f7bc64e..485ea751c7f9b6ab18530e2d7ffcec3f328146c0 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/blktrans.h>
 #include <linux/mutex.h>
+#include <linux/major.h>
 
 
 struct mtdblk_dev {
@@ -373,7 +374,7 @@ static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
 
 static struct mtd_blktrans_ops mtdblock_tr = {
        .name           = "mtdblock",
-       .major          = 31,
+       .major          = MTD_BLOCK_MAJOR,
        .part_bits      = 0,
        .blksize        = 512,
        .open           = mtdblock_open,
index 92759a9d2985e8a478b6a05734db195453d39434..fb5dc89369de34f1ec95126e64b1ed4a7c275c18 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/blktrans.h>
 #include <linux/module.h>
+#include <linux/major.h>
 
 static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
                              unsigned long block, char *buf)
@@ -70,7 +71,7 @@ static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
 
 static struct mtd_blktrans_ops mtdblock_tr = {
        .name           = "mtdblock",
-       .major          = 31,
+       .major          = MTD_BLOCK_MAJOR,
        .part_bits      = 0,
        .blksize        = 512,
        .readsect       = mtdblock_readsect,
index 684bfa39e4ee4892f901874c52c699fa71fd572a..9aa0c5e49c1d3aec1641a08fb27b979e5e97f79f 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/mount.h>
 #include <linux/blkpg.h>
 #include <linux/magic.h>
+#include <linux/major.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/map.h>
index 5e14d540ba2f623abb6438c4b6c204b991ed260b..7189089d87e3dbbca1dee15fe656a0a487b40dee 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/backing-dev.h>
 #include <linux/gfp.h>
 #include <linux/slab.h>
+#include <linux/major.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -157,6 +158,9 @@ static ssize_t mtd_type_show(struct device *dev,
        case MTD_UBIVOLUME:
                type = "ubi";
                break;
+       case MTD_MLCNANDFLASH:
+               type = "mlc-nand";
+               break;
        default:
                type = "unknown";
        }
index 334da5f583c021124ea2e64ae7860f513bd9816f..20c02a3b7417cd3025a6c17142f86a3479e2e3a8 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/export.h>
 #include <linux/ctype.h>
 #include <linux/slab.h>
+#include <linux/major.h>
 
 /*
  * compare superblocks to see if they're equivalent
index 060feeaf6b3e5554328904a1ac870a97cbc5685b..ef9c9f547c01fffe391235e3a6d9dffe95944321 100644 (file)
@@ -1062,56 +1062,28 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
 }
 
 /*
- * Get ECC requirement in ONFI parameters, returns -1 if ONFI
- * parameters is not supported.
- * return 0 if success to get the ECC requirement.
- */
-static int get_onfi_ecc_param(struct nand_chip *chip,
-               int *ecc_bits, int *sector_size)
-{
-       *ecc_bits = *sector_size = 0;
-
-       if (chip->onfi_params.ecc_bits == 0xff)
-               /* TODO: the sector_size and ecc_bits need to be find in
-                * extended ecc parameter, currently we don't support it.
-                */
-               return -1;
-
-       *ecc_bits = chip->onfi_params.ecc_bits;
-
-       /* The default sector size (ecc codeword size) is 512 */
-       *sector_size = 512;
-
-       return 0;
-}
-
-/*
- * Get ecc requirement from ONFI parameters ecc requirement.
+ * Get minimum ecc requirements from NAND.
  * If pmecc-cap, pmecc-sector-size in DTS are not specified, this function
- * will set them according to ONFI ecc requirement. Otherwise, use the
+ * will set them according to minimum ecc requirement. Otherwise, use the
  * value in DTS file.
  * return 0 if success. otherwise return error code.
  */
 static int pmecc_choose_ecc(struct atmel_nand_host *host,
                int *cap, int *sector_size)
 {
-       /* Get ECC requirement from ONFI parameters */
-       *cap = *sector_size = 0;
-       if (host->nand_chip.onfi_version) {
-               if (!get_onfi_ecc_param(&host->nand_chip, cap, sector_size))
-                       dev_info(host->dev, "ONFI params, minimum required ECC: %d bits in %d bytes\n",
+       /* Get minimum ECC requirements */
+       if (host->nand_chip.ecc_strength_ds) {
+               *cap = host->nand_chip.ecc_strength_ds;
+               *sector_size = host->nand_chip.ecc_step_ds;
+               dev_info(host->dev, "minimum ECC: %d bits in %d bytes\n",
                                *cap, *sector_size);
-               else
-                       dev_info(host->dev, "NAND chip ECC reqirement is in Extended ONFI parameter, we don't support yet.\n");
        } else {
-               dev_info(host->dev, "NAND chip is not ONFI compliant, assume ecc_bits is 2 in 512 bytes");
-       }
-       if (*cap == 0 && *sector_size == 0) {
                *cap = 2;
                *sector_size = 512;
+               dev_info(host->dev, "can't detect min. ECC, assume 2 bits in 512 bytes\n");
        }
 
-       /* If dts file doesn't specify then use the one in ONFI parameters */
+       /* If device tree doesn't specify, use NAND's minimum ECC parameters */
        if (host->pmecc_corr_cap == 0) {
                /* use the most fitable ecc bits (the near bigger one ) */
                if (*cap <= 2)
@@ -1449,7 +1421,6 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
                ecc_writel(host->ecc, CR, ATMEL_ECC_RST);
 }
 
-#if defined(CONFIG_OF)
 static int atmel_of_init_port(struct atmel_nand_host *host,
                              struct device_node *np)
 {
@@ -1457,7 +1428,7 @@ static int atmel_of_init_port(struct atmel_nand_host *host,
        u32 offset[2];
        int ecc_mode;
        struct atmel_nand_data *board = &host->board;
-       enum of_gpio_flags flags;
+       enum of_gpio_flags flags = 0;
 
        if (of_property_read_u32(np, "atmel,nand-addr-offset", &val) == 0) {
                if (val >= 32) {
@@ -1540,13 +1511,6 @@ static int atmel_of_init_port(struct atmel_nand_host *host,
 
        return 0;
 }
-#else
-static int atmel_of_init_port(struct atmel_nand_host *host,
-                             struct device_node *np)
-{
-       return -EINVAL;
-}
-#endif
 
 static int __init atmel_hw_nand_init_params(struct platform_device *pdev,
                                         struct atmel_nand_host *host)
@@ -2019,7 +1983,8 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
        mtd = &host->mtd;
        nand_chip = &host->nand_chip;
        host->dev = &pdev->dev;
-       if (pdev->dev.of_node) {
+       if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+               /* Only when CONFIG_OF is enabled of_node can be parsed */
                res = atmel_of_init_port(host, pdev->dev.of_node);
                if (res)
                        goto err_nand_ioremap;
@@ -2207,14 +2172,12 @@ static int __exit atmel_nand_remove(struct platform_device *pdev)
        return 0;
 }
 
-#if defined(CONFIG_OF)
 static const struct of_device_id atmel_nand_dt_ids[] = {
        { .compatible = "atmel,at91rm9200-nand" },
        { /* sentinel */ }
 };
 
 MODULE_DEVICE_TABLE(of, atmel_nand_dt_ids);
-#endif
 
 static int atmel_nand_nfc_probe(struct platform_device *pdev)
 {
@@ -2253,12 +2216,11 @@ static int atmel_nand_nfc_probe(struct platform_device *pdev)
        return 0;
 }
 
-#if defined(CONFIG_OF)
-static struct of_device_id atmel_nand_nfc_match[] = {
+static const struct of_device_id atmel_nand_nfc_match[] = {
        { .compatible = "atmel,sama5d3-nfc" },
        { /* sentinel */ }
 };
-#endif
+MODULE_DEVICE_TABLE(of, atmel_nand_nfc_match);
 
 static struct platform_driver atmel_nand_nfc_driver = {
        .driver = {
index 7bae569fdc79880e5025a5db3e93dd34da274598..107445911315cba4f78a509ab72e91677a1cfb18 100644 (file)
@@ -29,11 +29,9 @@ static int bcm47xxnflash_probe(struct platform_device *pdev)
        struct bcm47xxnflash *b47n;
        int err = 0;
 
-       b47n = kzalloc(sizeof(*b47n), GFP_KERNEL);
-       if (!b47n) {
-               err = -ENOMEM;
-               goto out;
-       }
+       b47n = devm_kzalloc(&pdev->dev, sizeof(*b47n), GFP_KERNEL);
+       if (!b47n)
+               return -ENOMEM;
 
        b47n->nand_chip.priv = b47n;
        b47n->mtd.owner = THIS_MODULE;
@@ -48,22 +46,16 @@ static int bcm47xxnflash_probe(struct platform_device *pdev)
        }
        if (err) {
                pr_err("Initialization failed: %d\n", err);
-               goto err_init;
+               return err;
        }
 
        err = mtd_device_parse_register(&b47n->mtd, probes, NULL, NULL, 0);
        if (err) {
                pr_err("Failed to register MTD device: %d\n", err);
-               goto err_dev_reg;
+               return err;
        }
 
        return 0;
-
-err_dev_reg:
-err_init:
-       kfree(b47n);
-out:
-       return err;
 }
 
 static int bcm47xxnflash_remove(struct platform_device *pdev)
@@ -85,22 +77,4 @@ static struct platform_driver bcm47xxnflash_driver = {
        },
 };
 
-static int __init bcm47xxnflash_init(void)
-{
-       int err;
-
-       err = platform_driver_register(&bcm47xxnflash_driver);
-       if (err)
-               pr_err("Failed to register bcm47xx nand flash driver: %d\n",
-                      err);
-
-       return err;
-}
-
-static void __exit bcm47xxnflash_exit(void)
-{
-       platform_driver_unregister(&bcm47xxnflash_driver);
-}
-
-module_init(bcm47xxnflash_init);
-module_exit(bcm47xxnflash_exit);
+module_platform_driver(bcm47xxnflash_driver);
index 2ed2bb33a6e773f6a81835b2787db2ef9b6bf774..370b9dd7a2786841f3180d732321c99416030559 100644 (file)
@@ -1394,7 +1394,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {
 };
 
 /* initialize driver data structures */
-void denali_drv_init(struct denali_nand_info *denali)
+static void denali_drv_init(struct denali_nand_info *denali)
 {
        denali->idx = 0;
 
@@ -1520,7 +1520,7 @@ int denali_init(struct denali_nand_info *denali)
         * so just let controller do 15bit ECC for MLC and 8bit ECC for
         * SLC if possible.
         * */
-       if (denali->nand.cellinfo & NAND_CI_CELLTYPE_MSK &&
+       if (!nand_is_slc(&denali->nand) &&
                        (denali->mtd.oobsize > (denali->bbtskipbytes +
                        ECC_15BITS * (denali->mtd.writesize /
                        ECC_SECTOR_SIZE)))) {
index e3e46623b2b450f8a1d6cdab3b2c39c6b167836e..033f177a6369b2d240b499f33df0b6bd925ed4d2 100644 (file)
@@ -119,7 +119,6 @@ static void denali_pci_remove(struct pci_dev *dev)
        iounmap(denali->flash_mem);
        pci_release_regions(dev);
        pci_disable_device(dev);
-       pci_set_drvdata(dev, NULL);
        kfree(denali);
 }
 
index eaa3c29ad860eb7c84a5e1309ef879d9d2044ed1..b68a4959f700af3e2768af69e6dd9afd0f94c8e1 100644 (file)
@@ -38,7 +38,7 @@
 #define CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS 0
 #endif
 
-static unsigned long __initdata doc_locations[] = {
+static unsigned long doc_locations[] __initdata = {
 #if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
 #ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH
        0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
index 548db2389fab8b63e41f2f61731606c32643084a..bd1cb672034fe770d2db2b986caa1821c1f63f58 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/bch.h>
 #include <linux/bitrev.h>
+#include <linux/jiffies.h>
 
 /*
  * In "reliable mode" consecutive 2k pages are used in parallel (in some
@@ -269,7 +270,7 @@ static int poll_status(struct docg4_priv *doc)
         */
 
        uint16_t flash_status;
-       unsigned int timeo;
+       unsigned long timeo;
        void __iomem *docptr = doc->virtadr;
 
        dev_dbg(doc->dev, "%s...\n", __func__);
@@ -277,22 +278,18 @@ static int poll_status(struct docg4_priv *doc)
        /* hardware quirk requires reading twice initially */
        flash_status = readw(docptr + DOC_FLASHCONTROL);
 
-       timeo = 1000;
+       timeo = jiffies + msecs_to_jiffies(200); /* generous timeout */
        do {
                cpu_relax();
                flash_status = readb(docptr + DOC_FLASHCONTROL);
-       } while (!(flash_status & DOC_CTRL_FLASHREADY) && --timeo);
+       } while (!(flash_status & DOC_CTRL_FLASHREADY) &&
+                time_before(jiffies, timeo));
 
-
-       if (!timeo) {
+       if (unlikely(!(flash_status & DOC_CTRL_FLASHREADY))) {
                dev_err(doc->dev, "%s: timed out!\n", __func__);
                return NAND_STATUS_FAIL;
        }
 
-       if (unlikely(timeo < 50))
-               dev_warn(doc->dev, "%s: nearly timed out; %d remaining\n",
-                        __func__, timeo);
-
        return 0;
 }
 
@@ -1239,7 +1236,6 @@ static void __init init_mtd_structs(struct mtd_info *mtd)
        nand->block_markbad = docg4_block_markbad;
        nand->read_buf = docg4_read_buf;
        nand->write_buf = docg4_write_buf16;
-       nand->scan_bbt = nand_default_bbt;
        nand->erase_cmd = docg4_erase_block;
        nand->ecc.read_page = docg4_read_page;
        nand->ecc.write_page = docg4_write_page;
index 20657209a472f388a0ecdd933322db5ad2d945cb..c6ef9f1c7a825f718a901139f4f56bc1c36d9e1d 100644 (file)
@@ -650,8 +650,6 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
                chip->page_shift);
        dev_dbg(priv->dev, "fsl_elbc_init: nand->phys_erase_shift = %d\n",
                chip->phys_erase_shift);
-       dev_dbg(priv->dev, "fsl_elbc_init: nand->ecclayout = %p\n",
-               chip->ecclayout);
        dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.mode = %d\n",
                chip->ecc.mode);
        dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.steps = %d\n",
index 317a771f1587c94f3fd57c45c8e140deeb08b982..c96e1e0943f56d1a852f043d8243fb515ec3a371 100644 (file)
@@ -135,6 +135,69 @@ static struct nand_ecclayout oob_4096_ecc8 = {
        .oobfree = { {2, 6}, {136, 82} },
 };
 
+/* 8192-byte page size with 4-bit ECC */
+static struct nand_ecclayout oob_8192_ecc4 = {
+       .eccbytes = 128,
+       .eccpos = {
+               8, 9, 10, 11, 12, 13, 14, 15,
+               16, 17, 18, 19, 20, 21, 22, 23,
+               24, 25, 26, 27, 28, 29, 30, 31,
+               32, 33, 34, 35, 36, 37, 38, 39,
+               40, 41, 42, 43, 44, 45, 46, 47,
+               48, 49, 50, 51, 52, 53, 54, 55,
+               56, 57, 58, 59, 60, 61, 62, 63,
+               64, 65, 66, 67, 68, 69, 70, 71,
+               72, 73, 74, 75, 76, 77, 78, 79,
+               80, 81, 82, 83, 84, 85, 86, 87,
+               88, 89, 90, 91, 92, 93, 94, 95,
+               96, 97, 98, 99, 100, 101, 102, 103,
+               104, 105, 106, 107, 108, 109, 110, 111,
+               112, 113, 114, 115, 116, 117, 118, 119,
+               120, 121, 122, 123, 124, 125, 126, 127,
+               128, 129, 130, 131, 132, 133, 134, 135,
+       },
+       .oobfree = { {2, 6}, {136, 208} },
+};
+
+/* 8192-byte page size with 8-bit ECC -- requires 218-byte OOB */
+static struct nand_ecclayout oob_8192_ecc8 = {
+       .eccbytes = 256,
+       .eccpos = {
+               8, 9, 10, 11, 12, 13, 14, 15,
+               16, 17, 18, 19, 20, 21, 22, 23,
+               24, 25, 26, 27, 28, 29, 30, 31,
+               32, 33, 34, 35, 36, 37, 38, 39,
+               40, 41, 42, 43, 44, 45, 46, 47,
+               48, 49, 50, 51, 52, 53, 54, 55,
+               56, 57, 58, 59, 60, 61, 62, 63,
+               64, 65, 66, 67, 68, 69, 70, 71,
+               72, 73, 74, 75, 76, 77, 78, 79,
+               80, 81, 82, 83, 84, 85, 86, 87,
+               88, 89, 90, 91, 92, 93, 94, 95,
+               96, 97, 98, 99, 100, 101, 102, 103,
+               104, 105, 106, 107, 108, 109, 110, 111,
+               112, 113, 114, 115, 116, 117, 118, 119,
+               120, 121, 122, 123, 124, 125, 126, 127,
+               128, 129, 130, 131, 132, 133, 134, 135,
+               136, 137, 138, 139, 140, 141, 142, 143,
+               144, 145, 146, 147, 148, 149, 150, 151,
+               152, 153, 154, 155, 156, 157, 158, 159,
+               160, 161, 162, 163, 164, 165, 166, 167,
+               168, 169, 170, 171, 172, 173, 174, 175,
+               176, 177, 178, 179, 180, 181, 182, 183,
+               184, 185, 186, 187, 188, 189, 190, 191,
+               192, 193, 194, 195, 196, 197, 198, 199,
+               200, 201, 202, 203, 204, 205, 206, 207,
+               208, 209, 210, 211, 212, 213, 214, 215,
+               216, 217, 218, 219, 220, 221, 222, 223,
+               224, 225, 226, 227, 228, 229, 230, 231,
+               232, 233, 234, 235, 236, 237, 238, 239,
+               240, 241, 242, 243, 244, 245, 246, 247,
+               248, 249, 250, 251, 252, 253, 254, 255,
+               256, 257, 258, 259, 260, 261, 262, 263,
+       },
+       .oobfree = { {2, 6}, {264, 80} },
+};
 
 /*
  * Generic flash bbt descriptors
@@ -441,20 +504,29 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
                if (mtd->writesize > 512) {
                        nand_fcr0 =
                                (NAND_CMD_SEQIN << IFC_NAND_FCR0_CMD0_SHIFT) |
-                               (NAND_CMD_PAGEPROG << IFC_NAND_FCR0_CMD1_SHIFT);
+                               (NAND_CMD_STATUS << IFC_NAND_FCR0_CMD1_SHIFT) |
+                               (NAND_CMD_PAGEPROG << IFC_NAND_FCR0_CMD2_SHIFT);
 
                        iowrite32be(
-                               (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
-                               (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
-                               (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
-                               (IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP3_SHIFT) |
-                               (IFC_FIR_OP_CW1 << IFC_NAND_FIR0_OP4_SHIFT),
-                               &ifc->ifc_nand.nand_fir0);
+                                (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
+                                (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
+                                (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
+                                (IFC_FIR_OP_WBCD  << IFC_NAND_FIR0_OP3_SHIFT) |
+                                (IFC_FIR_OP_CMD2 << IFC_NAND_FIR0_OP4_SHIFT),
+                                &ifc->ifc_nand.nand_fir0);
+                       iowrite32be(
+                                (IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT) |
+                                (IFC_FIR_OP_RDSTAT <<
+                                       IFC_NAND_FIR1_OP6_SHIFT) |
+                                (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP7_SHIFT),
+                                &ifc->ifc_nand.nand_fir1);
                } else {
                        nand_fcr0 = ((NAND_CMD_PAGEPROG <<
                                        IFC_NAND_FCR0_CMD1_SHIFT) |
                                    (NAND_CMD_SEQIN <<
-                                       IFC_NAND_FCR0_CMD2_SHIFT));
+                                       IFC_NAND_FCR0_CMD2_SHIFT) |
+                                   (NAND_CMD_STATUS <<
+                                       IFC_NAND_FCR0_CMD3_SHIFT));
 
                        iowrite32be(
                                (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
@@ -463,8 +535,13 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
                                (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP3_SHIFT) |
                                (IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP4_SHIFT),
                                &ifc->ifc_nand.nand_fir0);
-                       iowrite32be(IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT,
-                                   &ifc->ifc_nand.nand_fir1);
+                       iowrite32be(
+                                (IFC_FIR_OP_CMD1 << IFC_NAND_FIR1_OP5_SHIFT) |
+                                (IFC_FIR_OP_CW3 << IFC_NAND_FIR1_OP6_SHIFT) |
+                                (IFC_FIR_OP_RDSTAT <<
+                                       IFC_NAND_FIR1_OP7_SHIFT) |
+                                (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP8_SHIFT),
+                                 &ifc->ifc_nand.nand_fir1);
 
                        if (column >= mtd->writesize)
                                nand_fcr0 |=
@@ -718,8 +795,6 @@ static int fsl_ifc_chip_init_tail(struct mtd_info *mtd)
                                                        chip->page_shift);
        dev_dbg(priv->dev, "%s: nand->phys_erase_shift = %d\n", __func__,
                                                        chip->phys_erase_shift);
-       dev_dbg(priv->dev, "%s: nand->ecclayout = %p\n", __func__,
-                                                       chip->ecclayout);
        dev_dbg(priv->dev, "%s: nand->ecc.mode = %d\n", __func__,
                                                        chip->ecc.mode);
        dev_dbg(priv->dev, "%s: nand->ecc.steps = %d\n", __func__,
@@ -872,11 +947,25 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
                } else {
                        layout = &oob_4096_ecc8;
                        chip->ecc.bytes = 16;
+                       chip->ecc.strength = 8;
                }
 
                priv->bufnum_mask = 1;
                break;
 
+       case CSOR_NAND_PGS_8K:
+               if ((csor & CSOR_NAND_ECC_MODE_MASK) ==
+                   CSOR_NAND_ECC_MODE_4) {
+                       layout = &oob_8192_ecc4;
+               } else {
+                       layout = &oob_8192_ecc8;
+                       chip->ecc.bytes = 16;
+                       chip->ecc.strength = 8;
+               }
+
+               priv->bufnum_mask = 0;
+       break;
+
        default:
                dev_err(priv->dev, "bad csor %#x: bad page size\n", csor);
                return -ENODEV;
@@ -907,7 +996,6 @@ static int fsl_ifc_chip_remove(struct fsl_ifc_mtd *priv)
                iounmap(priv->vbase);
 
        ifc_nand_ctrl->chips[priv->bank] = NULL;
-       dev_set_drvdata(priv->dev, NULL);
 
        return 0;
 }
@@ -1082,25 +1170,7 @@ static struct platform_driver fsl_ifc_nand_driver = {
        .remove      = fsl_ifc_nand_remove,
 };
 
-static int __init fsl_ifc_nand_init(void)
-{
-       int ret;
-
-       ret = platform_driver_register(&fsl_ifc_nand_driver);
-       if (ret)
-               printk(KERN_ERR "fsl-ifc: Failed to register platform"
-                               "driver\n");
-
-       return ret;
-}
-
-static void __exit fsl_ifc_nand_exit(void)
-{
-       platform_driver_unregister(&fsl_ifc_nand_driver);
-}
-
-module_init(fsl_ifc_nand_init);
-module_exit(fsl_ifc_nand_exit);
+module_platform_driver(fsl_ifc_nand_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Freescale");
index 4f8857fa48a7f93f502e7b0d1a2581eebac64234..aaced29727fb0437f6a0c142253b04cbc0ca82d0 100644 (file)
@@ -187,6 +187,12 @@ int gpmi_init(struct gpmi_nand_data *this)
        /* Select BCH ECC. */
        writel(BM_GPMI_CTRL1_BCH_MODE, r->gpmi_regs + HW_GPMI_CTRL1_SET);
 
+       /*
+        * Decouple the chip select from dma channel. We use dma0 for all
+        * the chips.
+        */
+       writel(BM_GPMI_CTRL1_DECOUPLE_CS, r->gpmi_regs + HW_GPMI_CTRL1_SET);
+
        gpmi_disable_clk(this);
        return 0;
 err_out:
@@ -1073,6 +1079,13 @@ int gpmi_is_ready(struct gpmi_nand_data *this, unsigned chip)
                mask = MX23_BM_GPMI_DEBUG_READY0 << chip;
                reg = readl(r->gpmi_regs + HW_GPMI_DEBUG);
        } else if (GPMI_IS_MX28(this) || GPMI_IS_MX6Q(this)) {
+               /*
+                * In the imx6, all the ready/busy pins are bound
+                * together. So we only need to check chip 0.
+                */
+               if (GPMI_IS_MX6Q(this))
+                       chip = 0;
+
                /* MX28 shares the same R/B register as MX6Q. */
                mask = MX28_BF_GPMI_STAT_READY_BUSY(1 << chip);
                reg = readl(r->gpmi_regs + HW_GPMI_STAT);
index 59ab0692f0b97f58fef750b6f5e29c11b6fa0367..6807d7cfe49c1ce7f5f7a68c305e46bdd2f283c4 100644 (file)
@@ -45,7 +45,10 @@ static struct nand_bbt_descr gpmi_bbt_descr = {
        .pattern        = scan_ff_pattern
 };
 
-/*  We will use all the (page + OOB). */
+/*
+ * We may change the layout if we can get the ECC info from the datasheet,
+ * else we will use all the (page + OOB).
+ */
 static struct nand_ecclayout gpmi_hw_ecclayout = {
        .eccbytes = 0,
        .eccpos = { 0, },
@@ -354,9 +357,8 @@ int common_nfc_set_geometry(struct gpmi_nand_data *this)
 
 struct dma_chan *get_dma_chan(struct gpmi_nand_data *this)
 {
-       int chipnr = this->current_chip;
-
-       return this->dma_chans[chipnr];
+       /* We use the DMA channel 0 to access all the nand chips. */
+       return this->dma_chans[0];
 }
 
 /* Can we use the upper's buffer directly for DMA? */
@@ -1263,14 +1265,22 @@ static int gpmi_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 static int
 gpmi_ecc_write_oob(struct mtd_info *mtd, struct nand_chip *chip, int page)
 {
-       /*
-        * The BCH will use all the (page + oob).
-        * Our gpmi_hw_ecclayout can only prohibit the JFFS2 to write the oob.
-        * But it can not stop some ioctls such MEMWRITEOOB which uses
-        * MTD_OPS_PLACE_OOB. So We have to implement this function to prohibit
-        * these ioctls too.
-        */
-       return -EPERM;
+       struct nand_oobfree *of = mtd->ecclayout->oobfree;
+       int status = 0;
+
+       /* Do we have available oob area? */
+       if (!of->length)
+               return -EPERM;
+
+       if (!nand_is_slc(chip))
+               return -EPERM;
+
+       chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize + of->offset, page);
+       chip->write_buf(mtd, chip->oob_poi + of->offset, of->length);
+       chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+
+       status = chip->waitfunc(mtd, chip);
+       return status & NAND_STATUS_FAIL ? -EIO : 0;
 }
 
 static int gpmi_block_markbad(struct mtd_info *mtd, loff_t ofs)
@@ -1664,7 +1674,7 @@ static int gpmi_nfc_init(struct gpmi_nand_data *this)
        if (ret)
                goto err_out;
 
-       ret = nand_scan_ident(mtd, 1, NULL);
+       ret = nand_scan_ident(mtd, 2, NULL);
        if (ret)
                goto err_out;
 
@@ -1691,19 +1701,19 @@ static const struct platform_device_id gpmi_ids[] = {
        { .name = "imx23-gpmi-nand", .driver_data = IS_MX23, },
        { .name = "imx28-gpmi-nand", .driver_data = IS_MX28, },
        { .name = "imx6q-gpmi-nand", .driver_data = IS_MX6Q, },
-       {},
+       {}
 };
 
 static const struct of_device_id gpmi_nand_id_table[] = {
        {
                .compatible = "fsl,imx23-gpmi-nand",
-               .data = (void *)&gpmi_ids[IS_MX23]
+               .data = (void *)&gpmi_ids[IS_MX23],
        }, {
                .compatible = "fsl,imx28-gpmi-nand",
-               .data = (void *)&gpmi_ids[IS_MX28]
+               .data = (void *)&gpmi_ids[IS_MX28],
        }, {
                .compatible = "fsl,imx6q-gpmi-nand",
-               .data = (void *)&gpmi_ids[IS_MX6Q]
+               .data = (void *)&gpmi_ids[IS_MX6Q],
        }, {}
 };
 MODULE_DEVICE_TABLE(of, gpmi_nand_id_table);
index 53397cc290fcb522c921d746e768a649de663335..82114cdc8330574ad418fbde6e51d7efb2d4da44 100644 (file)
 #define HW_GPMI_CTRL1_CLR                              0x00000068
 #define HW_GPMI_CTRL1_TOG                              0x0000006c
 
+#define BP_GPMI_CTRL1_DECOUPLE_CS                      24
+#define BM_GPMI_CTRL1_DECOUPLE_CS      (1 << BP_GPMI_CTRL1_DECOUPLE_CS)
+
 #define BP_GPMI_CTRL1_WRN_DLY_SEL                      22
 #define BM_GPMI_CTRL1_WRN_DLY_SEL      (0x3 << BP_GPMI_CTRL1_WRN_DLY_SEL)
 #define BF_GPMI_CTRL1_WRN_DLY_SEL(v)  \
index f4dd2a887ea5da15b0b64c743f9ecb2603035b97..327d96c035050ce178711f03ee8ff4dd527a1fb3 100644 (file)
@@ -905,7 +905,7 @@ static struct platform_driver lpc32xx_nand_driver = {
        .driver         = {
                .name   = DRV_NAME,
                .owner  = THIS_MODULE,
-               .of_match_table = of_match_ptr(lpc32xx_nand_match),
+               .of_match_table = lpc32xx_nand_match,
        },
 };
 
index add75709d41550d893f9dc0ef144a8b2edc281f7..23e6974ccd205ec23a7bf19adcea54ffb3304bfa 100644 (file)
@@ -893,7 +893,6 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
 
        /* Avoid extra scan if using BBT, setup BBT support */
        if (host->ncfg->use_bbt) {
-               chip->options |= NAND_SKIP_BBTSCAN;
                chip->bbt_options |= NAND_BBT_USE_FLASH;
 
                /*
@@ -915,13 +914,6 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
                goto err_exit3;
        }
 
-       /* Standard layout in FLASH for bad block tables */
-       if (host->ncfg->use_bbt) {
-               if (nand_default_bbt(mtd) < 0)
-                       dev_err(&pdev->dev,
-                              "Error initializing default bad block tables\n");
-       }
-
        mtd->name = "nxp_lpc3220_slc";
        ppdata.of_node = pdev->dev.of_node;
        res = mtd_device_parse_register(mtd, NULL, &ppdata, host->ncfg->parts,
@@ -1023,7 +1015,7 @@ static struct platform_driver lpc32xx_nand_driver = {
        .driver         = {
                .name   = LPC32XX_MODNAME,
                .owner  = THIS_MODULE,
-               .of_match_table = of_match_ptr(lpc32xx_nand_match),
+               .of_match_table = lpc32xx_nand_match,
        },
 };
 
index d340b2f198c614b72fc68eed945a8c1a662d147c..ec1db1e19c053367c61a5428319c21f49ad44a5d 100644 (file)
@@ -2912,12 +2912,13 @@ static int nand_flash_detect_ext_param_page(struct mtd_info *mtd,
        /* get the info we want. */
        ecc = (struct onfi_ext_ecc_info *)cursor;
 
-       if (ecc->codeword_size) {
-               chip->ecc_strength_ds = ecc->ecc_bits;
-               chip->ecc_step_ds = 1 << ecc->codeword_size;
+       if (!ecc->codeword_size) {
+               pr_debug("Invalid codeword size\n");
+               goto ext_out;
        }
 
-       pr_info("ONFI extended param page detected.\n");
+       chip->ecc_strength_ds = ecc->ecc_bits;
+       chip->ecc_step_ds = 1 << ecc->codeword_size;
        ret = 0;
 
 ext_out:
@@ -2935,29 +2936,34 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
        int i;
        int val;
 
-       /* ONFI need to be probed in 8 bits mode, and 16 bits should be selected with NAND_BUSWIDTH_AUTO */
-       if (chip->options & NAND_BUSWIDTH_16) {
-               pr_err("Trying ONFI probe in 16 bits mode, aborting !\n");
-               return 0;
-       }
        /* Try ONFI for unknown chip or LP */
        chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
        if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
                chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I')
                return 0;
 
+       /*
+        * ONFI must be probed in 8-bit mode or with NAND_BUSWIDTH_AUTO, not
+        * with NAND_BUSWIDTH_16
+        */
+       if (chip->options & NAND_BUSWIDTH_16) {
+               pr_err("ONFI cannot be probed in 16-bit mode; aborting\n");
+               return 0;
+       }
+
        chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
        for (i = 0; i < 3; i++) {
                chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));
                if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
                                le16_to_cpu(p->crc)) {
-                       pr_info("ONFI param page %d valid\n", i);
                        break;
                }
        }
 
-       if (i == 3)
+       if (i == 3) {
+               pr_err("Could not find valid ONFI parameter page; aborting\n");
                return 0;
+       }
 
        /* Check version */
        val = le16_to_cpu(p->revision);
@@ -2981,11 +2987,23 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
        sanitize_string(p->model, sizeof(p->model));
        if (!mtd->name)
                mtd->name = p->model;
+
        mtd->writesize = le32_to_cpu(p->byte_per_page);
-       mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize;
+
+       /*
+        * pages_per_block and blocks_per_lun may not be a power-of-2 size
+        * (don't ask me who thought of this...). MTD assumes that these
+        * dimensions will be power-of-2, so just truncate the remaining area.
+        */
+       mtd->erasesize = 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1);
+       mtd->erasesize *= mtd->writesize;
+
        mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
-       chip->chipsize = le32_to_cpu(p->blocks_per_lun);
+
+       /* See erasesize comment */
+       chip->chipsize = 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1);
        chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
+       chip->bits_per_cell = p->bits_per_cell;
 
        if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS)
                *busw = NAND_BUSWIDTH_16;
@@ -3009,10 +3027,11 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
 
                /* The Extended Parameter Page is supported since ONFI 2.1. */
                if (nand_flash_detect_ext_param_page(mtd, chip, p))
-                       pr_info("Failed to detect the extended param page.\n");
+                       pr_warn("Failed to detect ONFI extended param page\n");
+       } else {
+               pr_warn("Could not retrieve ONFI ECC requirements\n");
        }
 
-       pr_info("ONFI flash detected\n");
        return 1;
 }
 
@@ -3075,6 +3094,16 @@ static int nand_id_len(u8 *id_data, int arrlen)
        return arrlen;
 }
 
+/* Extract the bits of per cell from the 3rd byte of the extended ID */
+static int nand_get_bits_per_cell(u8 cellinfo)
+{
+       int bits;
+
+       bits = cellinfo & NAND_CI_CELLTYPE_MSK;
+       bits >>= NAND_CI_CELLTYPE_SHIFT;
+       return bits + 1;
+}
+
 /*
  * Many new NAND share similar device ID codes, which represent the size of the
  * chip. The rest of the parameters must be decoded according to generic or
@@ -3085,7 +3114,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
 {
        int extid, id_len;
        /* The 3rd id byte holds MLC / multichip data */
-       chip->cellinfo = id_data[2];
+       chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
        /* The 4th id byte is the important one */
        extid = id_data[3];
 
@@ -3101,8 +3130,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
         * ID to decide what to do.
         */
        if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
-                       (chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
-                       id_data[5] != 0x00) {
+                       !nand_is_slc(chip) && id_data[5] != 0x00) {
                /* Calc pagesize */
                mtd->writesize = 2048 << (extid & 0x03);
                extid >>= 2;
@@ -3134,7 +3162,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
                        (((extid >> 1) & 0x04) | (extid & 0x03));
                *busw = 0;
        } else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX &&
-                       (chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
+                       !nand_is_slc(chip)) {
                unsigned int tmp;
 
                /* Calc pagesize */
@@ -3197,7 +3225,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
                 * - ID byte 5, bit[7]:    1 -> BENAND, 0 -> raw SLC
                 */
                if (id_len >= 6 && id_data[0] == NAND_MFR_TOSHIBA &&
-                               !(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+                               nand_is_slc(chip) &&
                                (id_data[5] & 0x7) == 0x6 /* 24nm */ &&
                                !(id_data[4] & 0x80) /* !BENAND */) {
                        mtd->oobsize = 32 * mtd->writesize >> 9;
@@ -3222,6 +3250,9 @@ static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip,
        mtd->oobsize = mtd->writesize / 32;
        *busw = type->options & NAND_BUSWIDTH_16;
 
+       /* All legacy ID NAND are small-page, SLC */
+       chip->bits_per_cell = 1;
+
        /*
         * Check for Spansion/AMD ID + repeating 5th, 6th byte since
         * some Spansion chips have erasesize that conflicts with size
@@ -3258,11 +3289,11 @@ static void nand_decode_bbm_options(struct mtd_info *mtd,
         * Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba,
         * AMD/Spansion, and Macronix.  All others scan only the first page.
         */
-       if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+       if (!nand_is_slc(chip) &&
                        (maf_id == NAND_MFR_SAMSUNG ||
                         maf_id == NAND_MFR_HYNIX))
                chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
-       else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+       else if ((nand_is_slc(chip) &&
                                (maf_id == NAND_MFR_SAMSUNG ||
                                 maf_id == NAND_MFR_HYNIX ||
                                 maf_id == NAND_MFR_TOSHIBA ||
@@ -3286,7 +3317,7 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip,
                mtd->erasesize = type->erasesize;
                mtd->oobsize = type->oobsize;
 
-               chip->cellinfo = id_data[2];
+               chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
                chip->chipsize = (uint64_t)type->chipsize << 20;
                chip->options |= type->options;
                chip->ecc_strength_ds = NAND_ECC_STRENGTH(type);
@@ -3441,11 +3472,13 @@ ident_done:
        if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
                chip->cmdfunc = nand_command_lp;
 
-       pr_info("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s),"
-               " %dMiB, page size: %d, OOB size: %d\n",
+       pr_info("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s)\n",
                *maf_id, *dev_id, nand_manuf_ids[maf_idx].name,
-               chip->onfi_version ? chip->onfi_params.model : type->name,
-               (int)(chip->chipsize >> 20), mtd->writesize, mtd->oobsize);
+               chip->onfi_version ? chip->onfi_params.model : type->name);
+
+       pr_info("NAND device: %dMiB, %s, page size: %d, OOB size: %d\n",
+               (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC",
+               mtd->writesize, mtd->oobsize);
 
        return type;
 }
@@ -3738,8 +3771,7 @@ int nand_scan_tail(struct mtd_info *mtd)
        chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
 
        /* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
-       if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
-           !(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
+       if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && nand_is_slc(chip)) {
                switch (chip->ecc.steps) {
                case 2:
                        mtd->subpage_sft = 1;
@@ -3764,7 +3796,7 @@ int nand_scan_tail(struct mtd_info *mtd)
                chip->options |= NAND_SUBPAGE_READ;
 
        /* Fill in remaining MTD driver data */
-       mtd->type = MTD_NANDFLASH;
+       mtd->type = nand_is_slc(chip) ? MTD_NANDFLASH : MTD_MLCNANDFLASH;
        mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :
                                                MTD_CAP_NANDFLASH;
        mtd->_erase = nand_erase;
index bc06196d57395c5c0a9ec8dba4ea5fcd8832e8b2..c75b6a7c6ea430e040675e038ea00f398756bd64 100644 (file)
@@ -1392,4 +1392,3 @@ int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
 }
 
 EXPORT_SYMBOL(nand_scan_bbt);
-EXPORT_SYMBOL(nand_default_bbt);
index 414f5225ae8b2ece87f1044e6c2a293ae481a773..3c6d5c601ade269f258175cb8bf740fd10041e09 100644 (file)
@@ -2372,7 +2372,7 @@ static int __init ns_init_module(void)
        if ((retval = init_nandsim(nsmtd)) != 0)
                goto err_exit;
 
-       if ((retval = nand_default_bbt(nsmtd)) != 0)
+       if ((retval = chip->scan_bbt(nsmtd)) != 0)
                goto err_exit;
 
        if ((retval = parse_badblocks(nand, nsmtd)) != 0)
index dd03dfdfb0d65e0ded1b0a124221663b586482b5..aa75adf98d79f1e37fa4ae11d9b2bf8f5715d557 100644 (file)
 #define NAND_STOP_DELAY                (2 * HZ/50)
 #define PAGE_CHUNK_SIZE                (2048)
 
+/*
+ * Define a buffer size for the initial command that detects the flash device:
+ * STATUS, READID and PARAM. The largest of these is the PARAM command,
+ * needing 256 bytes.
+ */
+#define INIT_BUFFER_SIZE       256
+
 /* registers and bit definitions */
 #define NDCR           (0x00) /* Control register */
 #define NDTR0CS0       (0x04) /* Timing Parameter 0 for CS0 */
@@ -164,6 +171,7 @@ struct pxa3xx_nand_info {
 
        unsigned int            buf_start;
        unsigned int            buf_count;
+       unsigned int            buf_size;
 
        /* DMA information */
        int                     drcmr_dat;
@@ -540,7 +548,6 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
        info->oob_size          = 0;
        info->use_ecc           = 0;
        info->use_spare         = 1;
-       info->use_dma           = (use_dma) ? 1 : 0;
        info->is_ready          = 0;
        info->retcode           = ERR_NONE;
        if (info->cs != 0)
@@ -912,26 +919,20 @@ static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
        return 0;
 }
 
-/* the maximum possible buffer size for large page with OOB data
- * is: 2048 + 64 = 2112 bytes, allocate a page here for both the
- * data buffer and the DMA descriptor
- */
-#define MAX_BUFF_SIZE  PAGE_SIZE
-
 #ifdef ARCH_HAS_DMA
 static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
 {
        struct platform_device *pdev = info->pdev;
-       int data_desc_offset = MAX_BUFF_SIZE - sizeof(struct pxa_dma_desc);
+       int data_desc_offset = info->buf_size - sizeof(struct pxa_dma_desc);
 
        if (use_dma == 0) {
-               info->data_buff = kmalloc(MAX_BUFF_SIZE, GFP_KERNEL);
+               info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
                if (info->data_buff == NULL)
                        return -ENOMEM;
                return 0;
        }
 
-       info->data_buff = dma_alloc_coherent(&pdev->dev, MAX_BUFF_SIZE,
+       info->data_buff = dma_alloc_coherent(&pdev->dev, info->buf_size,
                                &info->data_buff_phys, GFP_KERNEL);
        if (info->data_buff == NULL) {
                dev_err(&pdev->dev, "failed to allocate dma buffer\n");
@@ -945,11 +946,16 @@ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
                                pxa3xx_nand_data_dma_irq, info);
        if (info->data_dma_ch < 0) {
                dev_err(&pdev->dev, "failed to request data dma\n");
-               dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE,
+               dma_free_coherent(&pdev->dev, info->buf_size,
                                info->data_buff, info->data_buff_phys);
                return info->data_dma_ch;
        }
 
+       /*
+        * Now that DMA buffers are allocated we turn on
+        * DMA proper for I/O operations.
+        */
+       info->use_dma = 1;
        return 0;
 }
 
@@ -958,7 +964,7 @@ static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info)
        struct platform_device *pdev = info->pdev;
        if (use_dma) {
                pxa_free_dma(info->data_dma_ch);
-               dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE,
+               dma_free_coherent(&pdev->dev, info->buf_size,
                                  info->data_buff, info->data_buff_phys);
        } else {
                kfree(info->data_buff);
@@ -967,7 +973,7 @@ static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info)
 #else
 static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
 {
-       info->data_buff = kmalloc(MAX_BUFF_SIZE, GFP_KERNEL);
+       info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
        if (info->data_buff == NULL)
                return -ENOMEM;
        return 0;
@@ -1081,7 +1087,16 @@ KEEP_CONFIG:
        else
                host->col_addr_cycles = 1;
 
+       /* release the initial buffer */
+       kfree(info->data_buff);
+
+       /* allocate the real data + oob buffer */
+       info->buf_size = mtd->writesize + mtd->oobsize;
+       ret = pxa3xx_nand_init_buff(info);
+       if (ret)
+               return ret;
        info->oob_buff = info->data_buff + mtd->writesize;
+
        if ((mtd->size >> chip->page_shift) > 65536)
                host->row_addr_cycles = 3;
        else
@@ -1187,9 +1202,13 @@ static int alloc_nand_resource(struct platform_device *pdev)
        }
        info->mmio_phys = r->start;
 
-       ret = pxa3xx_nand_init_buff(info);
-       if (ret)
+       /* Allocate a buffer to allow flash detection */
+       info->buf_size = INIT_BUFFER_SIZE;
+       info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
+       if (info->data_buff == NULL) {
+               ret = -ENOMEM;
                goto fail_disable_clk;
+       }
 
        /* initialize all interrupts to be disabled */
        disable_int(info, NDSR_MASK);
@@ -1207,7 +1226,7 @@ static int alloc_nand_resource(struct platform_device *pdev)
 
 fail_free_buf:
        free_irq(irq, info);
-       pxa3xx_nand_free_buff(info);
+       kfree(info->data_buff);
 fail_disable_clk:
        clk_disable_unprepare(info->clk);
        return ret;
@@ -1407,7 +1426,7 @@ static int pxa3xx_nand_resume(struct platform_device *pdev)
 static struct platform_driver pxa3xx_nand_driver = {
        .driver = {
                .name   = "pxa3xx-nand",
-               .of_match_table = of_match_ptr(pxa3xx_nand_dt_ids),
+               .of_match_table = pxa3xx_nand_dt_ids,
        },
        .probe          = pxa3xx_nand_probe,
        .remove         = pxa3xx_nand_remove,
index 09dde7d27178c72b4f058da3ed9699c0b028c8e5..9a9fa4949b4f8b62d17e2cb43eac7ea909ba0964 100644 (file)
@@ -149,17 +149,13 @@ static int socrates_nand_probe(struct platform_device *ofdev)
        struct mtd_part_parser_data ppdata;
 
        /* Allocate memory for the device structure (and zero it) */
-       host = kzalloc(sizeof(struct socrates_nand_host), GFP_KERNEL);
-       if (!host) {
-               printk(KERN_ERR
-                      "socrates_nand: failed to allocate device structure.\n");
+       host = devm_kzalloc(&ofdev->dev, sizeof(*host), GFP_KERNEL);
+       if (!host)
                return -ENOMEM;
-       }
 
        host->io_base = of_iomap(ofdev->dev.of_node, 0);
        if (host->io_base == NULL) {
-               printk(KERN_ERR "socrates_nand: ioremap failed\n");
-               kfree(host);
+               dev_err(&ofdev->dev, "ioremap failed\n");
                return -EIO;
        }
 
@@ -211,9 +207,7 @@ static int socrates_nand_probe(struct platform_device *ofdev)
        nand_release(mtd);
 
 out:
-       dev_set_drvdata(&ofdev->dev, NULL);
        iounmap(host->io_base);
-       kfree(host);
        return res;
 }
 
@@ -227,9 +221,7 @@ static int socrates_nand_remove(struct platform_device *ofdev)
 
        nand_release(mtd);
 
-       dev_set_drvdata(&ofdev->dev, NULL);
        iounmap(host->io_base);
-       kfree(host);
 
        return 0;
 }
index c5f4ebf4b384404a47df44ec843046e6bb243b44..46f27de018c34e35313a559576d850283933d51a 100644 (file)
@@ -50,7 +50,7 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
        struct NFTLrecord *nftl;
        unsigned long temp;
 
-       if (mtd->type != MTD_NANDFLASH || mtd->size > UINT_MAX)
+       if (!mtd_type_is_nand(mtd) || mtd->size > UINT_MAX)
                return;
        /* OK, this is moderately ugly.  But probably safe.  Alternatives? */
        if (memcmp(mtd->name, "DiskOnChip", 10))
index 558071bf92de0ed607355067b08ebea7fe3833b4..2362909d20c00f740c086049d410aa2450f81d3a 100644 (file)
@@ -573,28 +573,6 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
 
 static struct platform_driver omap2_onenand_driver;
 
-static int __adjust_timing(struct device *dev, void *data)
-{
-       int ret = 0;
-       struct omap2_onenand *c;
-
-       c = dev_get_drvdata(dev);
-
-       BUG_ON(c->setup == NULL);
-
-       /* DMA is not in use so this is all that is needed */
-       /* Revisit for OMAP3! */
-       ret = c->setup(c->onenand.base, &c->freq);
-
-       return ret;
-}
-
-int omap2_onenand_rephase(void)
-{
-       return driver_for_each_device(&omap2_onenand_driver.driver, NULL,
-                                     NULL, __adjust_timing);
-}
-
 static void omap2_onenand_shutdown(struct platform_device *pdev)
 {
        struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
index b3f41f200622b39f5ef7d46ab6b772ed2eb9e97e..1de33b5d390358b58a2cbaaaf6991e08ebcc97db 100644 (file)
@@ -2556,10 +2556,6 @@ static int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
 {
        int ret;
 
-       /* Check for invalid offset */
-       if (ofs > mtd->size)
-               return -EINVAL;
-
        onenand_get_device(mtd, FL_READING);
        ret = onenand_block_isbad_nolock(mtd, ofs, 0);
        onenand_release_device(mtd);
@@ -3529,7 +3525,7 @@ static int flexonenand_get_boundary(struct mtd_info *mtd)
 {
        struct onenand_chip *this = mtd->priv;
        unsigned die, bdry;
-       int ret, syscfg, locked;
+       int syscfg, locked;
 
        /* Disable ECC */
        syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
@@ -3540,7 +3536,7 @@ static int flexonenand_get_boundary(struct mtd_info *mtd)
                this->wait(mtd, FL_SYNCING);
 
                this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
-               ret = this->wait(mtd, FL_READING);
+               this->wait(mtd, FL_READING);
 
                bdry = this->read_word(this->base + ONENAND_DATARAM);
                if ((bdry >> FLEXONENAND_PI_UNLOCK_SHIFT) == 3)
@@ -3550,7 +3546,7 @@ static int flexonenand_get_boundary(struct mtd_info *mtd)
                this->boundary[die] = bdry & FLEXONENAND_PI_MASK;
 
                this->command(mtd, ONENAND_CMD_RESET, 0, 0);
-               ret = this->wait(mtd, FL_RESETING);
+               this->wait(mtd, FL_RESETING);
 
                printk(KERN_INFO "Die %d boundary: %d%s\n", die,
                       this->boundary[die], locked ? "(Locked)" : "(Unlocked)");
@@ -3734,7 +3730,7 @@ static int flexonenand_set_boundary(struct mtd_info *mtd, int die,
 
        /* Check is boundary is locked */
        this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
-       ret = this->wait(mtd, FL_READING);
+       this->wait(mtd, FL_READING);
 
        thisboundary = this->read_word(this->base + ONENAND_DATARAM);
        if ((thisboundary >> FLEXONENAND_PI_UNLOCK_SHIFT) != 3) {
@@ -3835,7 +3831,7 @@ static int onenand_chip_probe(struct mtd_info *mtd)
 static int onenand_probe(struct mtd_info *mtd)
 {
        struct onenand_chip *this = mtd->priv;
-       int maf_id, dev_id, ver_id;
+       int dev_id, ver_id;
        int density;
        int ret;
 
@@ -3843,8 +3839,7 @@ static int onenand_probe(struct mtd_info *mtd)
        if (ret)
                return ret;
 
-       /* Read manufacturer and device IDs from Register */
-       maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
+       /* Device and version IDs from Register */
        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);
index ab2a52a039c3eef994e7e4a53645d34e1a059eb2..daf82ba7aba038ba4ca322921826cf23d748076f 100644 (file)
@@ -290,7 +290,7 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
        int cis_sector;
 
        /* Check for small page NAND flash */
-       if (mtd->type != MTD_NANDFLASH || mtd->oobsize != OOB_SIZE ||
+       if (!mtd_type_is_nand(mtd) || mtd->oobsize != OOB_SIZE ||
            mtd->size > UINT_MAX)
                return;
 
index 3cd3aabbe1cd8bd3a92a1131e4955c83c41d4431..6f976159611f4ab86ee61033fe6a242b6bc1101f 100644 (file)
@@ -349,7 +349,7 @@ static int __init mtd_nandbiterrs_init(void)
                goto exit_mtddev;
        }
 
-       if (mtd->type != MTD_NANDFLASH) {
+       if (!mtd_type_is_nand(mtd)) {
                pr_info("this test requires NAND flash\n");
                err = -ENODEV;
                goto exit_nand;
index ff35c465bfeea5cb4f8598d95e05993c8cc590db..2e9e2d11f204aa8db90d775743778ce5719443e4 100644 (file)
@@ -289,7 +289,7 @@ static int __init mtd_oobtest_init(void)
                return err;
        }
 
-       if (mtd->type != MTD_NANDFLASH) {
+       if (!mtd_type_is_nand(mtd)) {
                pr_info("this test requires NAND flash\n");
                goto out;
        }
index 44b96e999ad4694c5ad222c357d98bc22c27c247..ed2d3f656fd2ffd41fca36537244e27d7d7fe712 100644 (file)
@@ -353,7 +353,7 @@ static int __init mtd_pagetest_init(void)
                return err;
        }
 
-       if (mtd->type != MTD_NANDFLASH) {
+       if (!mtd_type_is_nand(mtd)) {
                pr_info("this test requires NAND flash\n");
                goto out;
        }
index e2c0adf24cfc35aa6692ff5267b93babc523c69c..a876371ad410c5eec22c912d924574360d769c90 100644 (file)
@@ -299,7 +299,7 @@ static int __init mtd_subpagetest_init(void)
                return err;
        }
 
-       if (mtd->type != MTD_NANDFLASH) {
+       if (!mtd_type_is_nand(mtd)) {
                pr_info("this test requires NAND flash\n");
                goto out;
        }
index 315dcc6ec1f55a0a49de6e79e60ec701f9ae4b64..e05dc6298c1dcc157598e99ac57cb32e702918ae 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/kthread.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/major.h>
 #include "ubi.h"
 
 /* Maximum length of the 'mtd=' parameter */
index fe3c0527545f3b96d495f422a220339b0373e620..09b3ed45572475feb68b117fcf5b420a1a5e4d8f 100644 (file)
@@ -515,6 +515,10 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
 
        c = JFFS2_SB_INFO(sb);
 
+       /* Do not support the MLC nand */
+       if (c->mtd->type == MTD_MLCNANDFLASH)
+               return -EINVAL;
+
 #ifndef CONFIG_JFFS2_FS_WRITEBUFFER
        if (c->mtd->type == MTD_NANDFLASH) {
                pr_err("Cannot operate on NAND flash unless jffs2 NAND support is compiled in\n");
index 4b02512e421c6601db2cd1902094193a7aa7b647..5f487d77641174626c14c0857d2cad96aea92ffd 100644 (file)
@@ -365,7 +365,7 @@ static inline map_word map_word_load_partial(struct map_info *map, map_word orig
                        bitpos = (map_bankwidth(map)-1-i)*8;
 #endif
                        orig.x[0] &= ~(0xff << bitpos);
-                       orig.x[0] |= buf[i-start] << bitpos;
+                       orig.x[0] |= (unsigned long)buf[i-start] << bitpos;
                }
        }
        return orig;
@@ -384,7 +384,7 @@ static inline map_word map_word_ff(struct map_info *map)
 
        if (map_bankwidth(map) < MAP_FF_LIMIT) {
                int bw = 8 * map_bankwidth(map);
-               r.x[0] = (1 << bw) - 1;
+               r.x[0] = (1UL << bw) - 1;
        } else {
                for (i=0; i<map_words(map); i++)
                        r.x[i] = ~0UL;
index f9bfe526d3102175ab3d32149966f61aab35da62..8cc0e2fb68941f5169593076ad50411bb8939c85 100644 (file)
@@ -29,9 +29,6 @@
 
 #include <asm/div64.h>
 
-#define MTD_CHAR_MAJOR 90
-#define MTD_BLOCK_MAJOR 31
-
 #define MTD_ERASE_PENDING      0x01
 #define MTD_ERASING            0x02
 #define MTD_ERASE_SUSPEND      0x04
@@ -354,6 +351,11 @@ static inline int mtd_has_oob(const struct mtd_info *mtd)
        return mtd->_read_oob && mtd->_write_oob;
 }
 
+static inline int mtd_type_is_nand(const struct mtd_info *mtd)
+{
+       return mtd->type == MTD_NANDFLASH || mtd->type == MTD_MLCNANDFLASH;
+}
+
 static inline int mtd_can_have_bb(const struct mtd_info *mtd)
 {
        return !!mtd->_block_isbad;
index ac8e89d5a7929b6bdd40c424928a7d0d9872a73e..9e6c8f9f306e016923a0c32d3ae0e2d9f0ce0d1f 100644 (file)
@@ -198,6 +198,7 @@ typedef enum {
 /* Cell info constants */
 #define NAND_CI_CHIPNR_MSK     0x03
 #define NAND_CI_CELLTYPE_MSK   0x0C
+#define NAND_CI_CELLTYPE_SHIFT 2
 
 /* Keep gcc happy */
 struct nand_chip;
@@ -477,7 +478,7 @@ struct nand_buffers {
  * @badblockbits:      [INTERN] minimum number of set bits in a good block's
  *                     bad block marker position; i.e., BBM == 11110111b is
  *                     not bad when badblockbits == 7
- * @cellinfo:          [INTERN] MLC/multichip data from chip ident
+ * @bits_per_cell:     [INTERN] number of bits per cell. i.e., 1 means SLC.
  * @ecc_strength_ds:   [INTERN] ECC correctability from the datasheet.
  *                     Minimum amount of bit errors per @ecc_step_ds guaranteed
  *                     to be correctable. If unknown, set to zero.
@@ -498,7 +499,6 @@ struct nand_buffers {
  *                     supported, 0 otherwise.
  * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
  * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
- * @ecclayout:         [REPLACEABLE] the default ECC placement scheme
  * @bbt:               [INTERN] bad block table pointer
  * @bbt_td:            [REPLACEABLE] bad block table descriptor for flash
  *                     lookup.
@@ -559,7 +559,7 @@ struct nand_chip {
        int pagebuf;
        unsigned int pagebuf_bitflips;
        int subpagesize;
-       uint8_t cellinfo;
+       uint8_t bits_per_cell;
        uint16_t ecc_strength_ds;
        uint16_t ecc_step_ds;
        int badblockpos;
@@ -572,7 +572,6 @@ struct nand_chip {
 
        uint8_t *oob_poi;
        struct nand_hw_control *controller;
-       struct nand_ecclayout *ecclayout;
 
        struct nand_ecc_ctrl ecc;
        struct nand_buffers *buffers;
@@ -797,4 +796,13 @@ static inline int onfi_get_sync_timing_mode(struct nand_chip *chip)
        return le16_to_cpu(chip->onfi_params.src_sync_timing_mode);
 }
 
+/*
+ * Check if it is a SLC nand.
+ * The !nand_is_slc() can be used to check the MLC/TLC nand chips.
+ * We do not distinguish the MLC and TLC now.
+ */
+static inline bool nand_is_slc(struct nand_chip *chip)
+{
+       return chip->bits_per_cell == 1;
+}
 #endif /* __LINUX_MTD_NAND_H */
index ed7f267e63897794773ee201e32ad01d89d7bd7d..6f10e938ff7e74d4db19b991a55193f5073946e7 100644 (file)
 #define __LINUX_OF_NET_H
 
 #ifdef CONFIG_OF_MTD
+
 #include <linux/of.h>
 int of_get_nand_ecc_mode(struct device_node *np);
 int of_get_nand_bus_width(struct device_node *np);
 bool of_get_nand_on_flash_bbt(struct device_node *np);
-#endif
+
+#else /* CONFIG_OF_MTD */
+
+static inline int of_get_nand_ecc_mode(struct device_node *np)
+{
+       return -ENOSYS;
+}
+
+static inline int of_get_nand_bus_width(struct device_node *np)
+{
+       return -ENOSYS;
+}
+
+static inline bool of_get_nand_on_flash_bbt(struct device_node *np)
+{
+       return false;
+}
+
+#endif /* CONFIG_OF_MTD */
 
 #endif /* __LINUX_OF_MTD_H */
index 6a8ca98c9a962ee67fbcf3da94fe0222f6885c2c..620252e69b44a525b3fae1419f66f631d67e2de3 100644 (file)
@@ -54,6 +54,7 @@
 #define ACSI_MAJOR             28
 #define AZTECH_CDROM_MAJOR     29
 #define FB_MAJOR               29   /* /dev/fb* framebuffers */
+#define MTD_BLOCK_MAJOR                31
 #define CM206_CDROM_MAJOR      32
 #define IDE2_MAJOR             33
 #define IDE3_MAJOR             34
 #define IDE6_MAJOR             88
 #define IDE7_MAJOR             89
 #define IDE8_MAJOR             90
+#define MTD_CHAR_MAJOR         90
 #define IDE9_MAJOR             91
 
 #define DASD_MAJOR             94
index 36eace03b2ac79229984b09254db9aed3e3b8d5f..e272ea060e3851959878932ef2dd61c87e9d185e 100644 (file)
@@ -94,10 +94,10 @@ struct mtd_write_req {
 #define MTD_RAM                        1
 #define MTD_ROM                        2
 #define MTD_NORFLASH           3
-#define MTD_NANDFLASH          4
+#define MTD_NANDFLASH          4       /* SLC NAND */
 #define MTD_DATAFLASH          6
 #define MTD_UBIVOLUME          7
-#define MTD_MLCNANDFLASH       8
+#define MTD_MLCNANDFLASH       8       /* MLC NAND (including TLC) */
 
 #define MTD_WRITEABLE          0x400   /* Device is writeable */
 #define MTD_BIT_WRITEABLE      0x800   /* Single bits can be flipped */
@@ -275,4 +275,9 @@ enum mtd_file_modes {
        MTD_FILE_MODE_RAW,
 };
 
+static inline int mtd_type_is_nand_user(const struct mtd_info_user *mtd)
+{
+       return mtd->type == MTD_NANDFLASH || mtd->type == MTD_MLCNANDFLASH;
+}
+
 #endif /* __MTD_ABI_H__ */