Browse Source

Merge git://git.infradead.org/mtd-2.6

* 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.
Linus Torvalds 14 years ago
parent
commit
e8a89cebdb
100 changed files with 1533 additions and 1236 deletions
  1. 0 3
      arch/blackfin/include/asm/nand.h
  2. 7 5
      drivers/mtd/Kconfig
  3. 1 1
      drivers/mtd/afs.c
  4. 20 11
      drivers/mtd/chips/cfi_cmdset_0001.c
  5. 13 4
      drivers/mtd/chips/cfi_cmdset_0002.c
  6. 0 1
      drivers/mtd/chips/cfi_cmdset_0020.c
  7. 2 2
      drivers/mtd/chips/cfi_probe.c
  8. 0 1
      drivers/mtd/chips/cfi_util.c
  9. 0 1
      drivers/mtd/chips/chipreg.c
  10. 0 1
      drivers/mtd/chips/map_absent.c
  11. 0 1
      drivers/mtd/chips/map_ram.c
  12. 0 1
      drivers/mtd/chips/map_rom.c
  13. 16 1
      drivers/mtd/cmdlinepart.c
  14. 0 1
      drivers/mtd/devices/docecc.c
  15. 0 1
      drivers/mtd/devices/docprobe.c
  16. 29 14
      drivers/mtd/devices/m25p80.c
  17. 6 6
      drivers/mtd/devices/mtd_dataflash.c
  18. 0 1
      drivers/mtd/devices/mtdram.c
  19. 0 1
      drivers/mtd/devices/pmc551.c
  20. 1 1
      drivers/mtd/devices/sst25l.c
  21. 1 1
      drivers/mtd/ftl.c
  22. 3 3
      drivers/mtd/inftlcore.c
  23. 2 3
      drivers/mtd/inftlmount.c
  24. 10 10
      drivers/mtd/lpddr/lpddr_cmds.c
  25. 0 8
      drivers/mtd/maps/Kconfig
  26. 0 1
      drivers/mtd/maps/Makefile
  27. 27 8
      drivers/mtd/maps/ixp4xx.c
  28. 9 5
      drivers/mtd/maps/physmap.c
  29. 3 3
      drivers/mtd/maps/physmap_of.c
  30. 0 131
      drivers/mtd/maps/redwood.c
  31. 21 5
      drivers/mtd/mtd_blkdevs.c
  32. 17 2
      drivers/mtd/mtdblock.c
  33. 17 2
      drivers/mtd/mtdblock_ro.c
  34. 56 3
      drivers/mtd/mtdchar.c
  35. 28 10
      drivers/mtd/mtdconcat.c
  36. 17 4
      drivers/mtd/mtdcore.c
  37. 1 1
      drivers/mtd/mtdoops.c
  38. 26 5
      drivers/mtd/mtdpart.c
  39. 2 0
      drivers/mtd/mtdsuper.c
  40. 16 17
      drivers/mtd/nand/Kconfig
  41. 1 1
      drivers/mtd/nand/atmel_nand.c
  42. 72 45
      drivers/mtd/nand/bf5xx_nand.c
  43. 17 0
      drivers/mtd/nand/davinci_nand.c
  44. 166 481
      drivers/mtd/nand/denali.c
  45. 49 91
      drivers/mtd/nand/denali.h
  46. 3 3
      drivers/mtd/nand/diskonchip.c
  47. 425 175
      drivers/mtd/nand/mxc_nand.c
  48. 61 18
      drivers/mtd/nand/nand_base.c
  49. 75 28
      drivers/mtd/nand/nand_bbt.c
  50. 4 0
      drivers/mtd/nand/nand_ids.c
  51. 7 7
      drivers/mtd/nand/nandsim.c
  52. 1 1
      drivers/mtd/nand/plat_nand.c
  53. 3 3
      drivers/mtd/nand/r852.c
  54. 0 1
      drivers/mtd/nand/rtc_from4.c
  55. 6 9
      drivers/mtd/nand/s3c2410.c
  56. 1 1
      drivers/mtd/nand/sm_common.c
  57. 18 7
      drivers/mtd/nftlcore.c
  58. 2 1
      drivers/mtd/nftlmount.c
  59. 2 2
      drivers/mtd/ofpart.c
  60. 2 2
      drivers/mtd/onenand/Kconfig
  61. 35 14
      drivers/mtd/onenand/onenand_base.c
  62. 0 1
      drivers/mtd/onenand/onenand_bbt.c
  63. 8 13
      drivers/mtd/onenand/samsung.c
  64. 18 0
      drivers/mtd/redboot.c
  65. 1 1
      drivers/mtd/rfd_ftl.c
  66. 1 1
      drivers/mtd/ssfdc.c
  67. 4 5
      drivers/mtd/tests/mtd_pagetest.c
  68. 1 0
      fs/jffs2/background.c
  69. 1 0
      fs/jffs2/build.c
  70. 3 2
      fs/jffs2/compr.c
  71. 1 0
      fs/jffs2/compr.h
  72. 1 0
      fs/jffs2/compr_lzo.c
  73. 1 0
      fs/jffs2/compr_rtime.c
  74. 1 0
      fs/jffs2/compr_rubin.c
  75. 1 0
      fs/jffs2/compr_zlib.c
  76. 1 0
      fs/jffs2/debug.c
  77. 1 0
      fs/jffs2/debug.h
  78. 1 0
      fs/jffs2/dir.c
  79. 1 0
      fs/jffs2/erase.c
  80. 1 0
      fs/jffs2/file.c
  81. 1 0
      fs/jffs2/fs.c
  82. 1 0
      fs/jffs2/gc.c
  83. 1 0
      fs/jffs2/ioctl.c
  84. 1 0
      fs/jffs2/jffs2_fs_i.h
  85. 1 0
      fs/jffs2/jffs2_fs_sb.h
  86. 0 1
      fs/jffs2/nodelist.h
  87. 2 1
      include/linux/jffs2.h
  88. 22 2
      include/linux/mtd/bbm.h
  89. 14 2
      include/linux/mtd/blktrans.h
  90. 17 3
      include/linux/mtd/cfi.h
  91. 19 0
      include/linux/mtd/cfi_endian.h
  92. 0 10
      include/linux/mtd/compatmac.h
  93. 15 2
      include/linux/mtd/concat.h
  94. 18 5
      include/linux/mtd/doc2000.h
  95. 16 5
      include/linux/mtd/flashchip.h
  96. 17 2
      include/linux/mtd/gen_probe.h
  97. 18 1
      include/linux/mtd/map.h
  98. 16 3
      include/linux/mtd/mtd.h
  99. 3 5
      include/linux/mtd/nand.h
  100. 3 1
      include/linux/mtd/nand_ecc.h

+ 0 - 3
arch/blackfin/include/asm/nand.h

@@ -15,8 +15,6 @@
  * partitions	 = mtd partition list
  * partitions	 = mtd partition list
  */
  */
 
 
-#define NFC_PG_SIZE_256		0
-#define NFC_PG_SIZE_512		1
 #define NFC_PG_SIZE_OFFSET	9
 #define NFC_PG_SIZE_OFFSET	9
 
 
 #define NFC_NWIDTH_8		0
 #define NFC_NWIDTH_8		0
@@ -30,7 +28,6 @@
 
 
 struct bf5xx_nand_platform {
 struct bf5xx_nand_platform {
 	/* NAND chip information */
 	/* NAND chip information */
-	unsigned short		page_size;
 	unsigned short		data_width;
 	unsigned short		data_width;
 
 
 	/* RD/WR strobe delay timing information, all times in SCLK cycles */
 	/* RD/WR strobe delay timing information, all times in SCLK cycles */

+ 7 - 5
drivers/mtd/Kconfig

@@ -311,15 +311,17 @@ config SM_FTL
 	select MTD_BLKDEVS
 	select MTD_BLKDEVS
 	select MTD_NAND_ECC
 	select MTD_NAND_ECC
 	help
 	help
-	  This enables new and very EXPERMENTAL support for SmartMedia/xD
+	  This enables EXPERIMENTAL R/W support for SmartMedia/xD
 	  FTL (Flash translation layer).
 	  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
 config MTD_OOPS
 	tristate "Log panic/oops to an MTD buffer"
 	tristate "Log panic/oops to an MTD buffer"
-	depends on MTD
 	help
 	help
 	  This enables panic and oops messages to be logged to a circular
 	  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
 	  buffer in a flash partition where it can be read back at some

+ 1 - 1
drivers/mtd/afs.c

@@ -2,7 +2,7 @@
 
 
     drivers/mtd/afs.c: ARM Flash Layout/Partitioning
     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
    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
    it under the terms of the GNU General Public License as published by

+ 20 - 11
drivers/mtd/chips/cfi_cmdset_0001.c

@@ -34,7 +34,6 @@
 #include <linux/mtd/xip.h>
 #include <linux/mtd/xip.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
-#include <linux/mtd/compatmac.h>
 #include <linux/mtd/cfi.h>
 #include <linux/mtd/cfi.h>
 
 
 /* #define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE */
 /* #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 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_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_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
 #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_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 *);
 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->sync    = cfi_intelext_sync;
 	mtd->lock    = cfi_intelext_lock;
 	mtd->lock    = cfi_intelext_lock;
 	mtd->unlock  = cfi_intelext_unlock;
 	mtd->unlock  = cfi_intelext_unlock;
+	mtd->is_locked = cfi_intelext_is_locked;
 	mtd->suspend = cfi_intelext_suspend;
 	mtd->suspend = cfi_intelext_suspend;
 	mtd->resume  = cfi_intelext_resume;
 	mtd->resume  = cfi_intelext_resume;
 	mtd->flags   = MTD_CAP_NORFLASH;
 	mtd->flags   = MTD_CAP_NORFLASH;
@@ -717,7 +719,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
 		chip = &newcfi->chips[0];
 		chip = &newcfi->chips[0];
 		for (i = 0; i < cfi->numchips; i++) {
 		for (i = 0; i < cfi->numchips; i++) {
 			shared[i].writing = shared[i].erasing = NULL;
 			shared[i].writing = shared[i].erasing = NULL;
-			spin_lock_init(&shared[i].lock);
+			mutex_init(&shared[i].lock);
 			for (j = 0; j < numparts; j++) {
 			for (j = 0; j < numparts; j++) {
 				*chip = cfi->chips[i];
 				*chip = cfi->chips[i];
 				chip->start += j << partshift;
 				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_shared *shared = chip->priv;
 		struct flchip *contender;
 		struct flchip *contender;
-		spin_lock(&shared->lock);
+		mutex_lock(&shared->lock);
 		contender = shared->writing;
 		contender = shared->writing;
 		if (contender && contender != chip) {
 		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.
 			 * get_chip returns success we're clear to go ahead.
 			 */
 			 */
 			ret = mutex_trylock(&contender->mutex);
 			ret = mutex_trylock(&contender->mutex);
-			spin_unlock(&shared->lock);
+			mutex_unlock(&shared->lock);
 			if (!ret)
 			if (!ret)
 				goto retry;
 				goto retry;
 			mutex_unlock(&chip->mutex);
 			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);
 				mutex_unlock(&contender->mutex);
 				return ret;
 				return ret;
 			}
 			}
-			spin_lock(&shared->lock);
+			mutex_lock(&shared->lock);
 
 
 			/* We should not own chip if it is already
 			/* We should not own chip if it is already
 			 * in FL_SYNCING state. Put contender and retry. */
 			 * 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. */
 		 * on this chip. Sleep. */
 		if (mode == FL_ERASING && shared->erasing
 		if (mode == FL_ERASING && shared->erasing
 		    && shared->erasing->oldstate == FL_ERASING) {
 		    && shared->erasing->oldstate == FL_ERASING) {
-			spin_unlock(&shared->lock);
+			mutex_unlock(&shared->lock);
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			add_wait_queue(&chip->wq, &wait);
 			add_wait_queue(&chip->wq, &wait);
 			mutex_unlock(&chip->mutex);
 			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;
 		shared->writing = chip;
 		if (mode == FL_ERASING)
 		if (mode == FL_ERASING)
 			shared->erasing = chip;
 			shared->erasing = chip;
-		spin_unlock(&shared->lock);
+		mutex_unlock(&shared->lock);
 	}
 	}
 	ret = chip_ready(map, chip, adr, mode);
 	ret = chip_ready(map, chip, adr, mode);
 	if (ret == -EAGAIN)
 	if (ret == -EAGAIN)
@@ -959,7 +961,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
 
 
 	if (chip->priv) {
 	if (chip->priv) {
 		struct flchip_shared *shared = chip->priv;
 		struct flchip_shared *shared = chip->priv;
-		spin_lock(&shared->lock);
+		mutex_lock(&shared->lock);
 		if (shared->writing == chip && chip->oldstate == FL_READY) {
 		if (shared->writing == chip && chip->oldstate == FL_READY) {
 			/* We own the ability to write, but we're done */
 			/* We own the ability to write, but we're done */
 			shared->writing = shared->erasing;
 			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 */
 				/* give back ownership to who we loaned it from */
 				struct flchip *loaner = shared->writing;
 				struct flchip *loaner = shared->writing;
 				mutex_lock(&loaner->mutex);
 				mutex_lock(&loaner->mutex);
-				spin_unlock(&shared->lock);
+				mutex_unlock(&shared->lock);
 				mutex_unlock(&chip->mutex);
 				mutex_unlock(&chip->mutex);
 				put_chip(map, loaner, loaner->start);
 				put_chip(map, loaner, loaner->start);
 				mutex_lock(&chip->mutex);
 				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
 			 * Don't let the switch below mess things up since
 			 * we don't have ownership to resume anything.
 			 * we don't have ownership to resume anything.
 			 */
 			 */
-			spin_unlock(&shared->lock);
+			mutex_unlock(&shared->lock);
 			wake_up(&chip->wq);
 			wake_up(&chip->wq);
 			return;
 			return;
 		}
 		}
-		spin_unlock(&shared->lock);
+		mutex_unlock(&shared->lock);
 	}
 	}
 
 
 	switch(chip->oldstate) {
 	switch(chip->oldstate) {
@@ -2139,6 +2141,13 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 	return ret;
 	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
 #ifdef CONFIG_MTD_OTP
 
 
 typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip,
 typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip,

+ 13 - 4
drivers/mtd/chips/cfi_cmdset_0002.c

@@ -33,7 +33,6 @@
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/reboot.h>
 #include <linux/reboot.h>
-#include <linux/mtd/compatmac.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/cfi.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);
 			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' ||
 			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 "
 				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(extp);
 				kfree(mtd);
 				kfree(mtd);
 				return NULL;
 				return NULL;
 			}
 			}
 
 
+			printk(KERN_INFO "  Amd/Fujitsu Extended Query version %c.%c.\n",
+			       extp->MajorVersion, extp->MinorVersion);
+
 			/* Install our own private info structure */
 			/* Install our own private info structure */
 			cfi->cmdset_priv = extp;
 			cfi->cmdset_priv = extp;
 
 

+ 0 - 1
drivers/mtd/chips/cfi_cmdset_0020.c

@@ -33,7 +33,6 @@
 #include <linux/mtd/map.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/cfi.h>
 #include <linux/mtd/cfi.h>
 #include <linux/mtd/mtd.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 *);
 static int cfi_staa_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);

+ 2 - 2
drivers/mtd/chips/cfi_probe.c

@@ -235,9 +235,9 @@ static int __xipram cfi_chip_setup(struct map_info *map,
 	cfi_qry_mode_off(base, map, cfi);
 	cfi_qry_mode_off(base, map, cfi);
 	xip_allowed(base, map);
 	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->name, cfi->interleave, cfi->device_type*8, base,
-	       map->bankwidth*8);
+	       map->bankwidth*8, cfi->mfr, cfi->id);
 
 
 	return 1;
 	return 1;
 }
 }

+ 0 - 1
drivers/mtd/chips/cfi_util.c

@@ -22,7 +22,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/cfi.h>
 #include <linux/mtd/cfi.h>
-#include <linux/mtd/compatmac.h>
 
 
 int __xipram cfi_qry_present(struct map_info *map, __u32 base,
 int __xipram cfi_qry_present(struct map_info *map, __u32 base,
 			     struct cfi_private *cfi)
 			     struct cfi_private *cfi)

+ 0 - 1
drivers/mtd/chips/chipreg.c

@@ -10,7 +10,6 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
-#include <linux/mtd/compatmac.h>
 
 
 static DEFINE_SPINLOCK(chip_drvs_lock);
 static DEFINE_SPINLOCK(chip_drvs_lock);
 static LIST_HEAD(chip_drvs_list);
 static LIST_HEAD(chip_drvs_list);

+ 0 - 1
drivers/mtd/chips/map_absent.c

@@ -25,7 +25,6 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.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_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 *);
 static int map_absent_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);

+ 0 - 1
drivers/mtd/chips/map_ram.c

@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.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 *);
 static int mapram_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);

+ 0 - 1
drivers/mtd/chips/map_rom.c

@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.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_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 *);
 static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);

+ 16 - 1
drivers/mtd/cmdlinepart.c

@@ -1,7 +1,22 @@
 /*
 /*
  * Read flash partition table from command line
  * 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:
  * The format for the command line is as follows:
  *
  *

+ 0 - 1
drivers/mtd/devices/docecc.c

@@ -31,7 +31,6 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/types.h>
 
 
-#include <linux/mtd/compatmac.h> /* for min() in older kernels */
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/doc2000.h>
 #include <linux/mtd/doc2000.h>
 
 

+ 0 - 1
drivers/mtd/devices/docprobe.c

@@ -49,7 +49,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/doc2000.h>
 #include <linux/mtd/doc2000.h>
-#include <linux/mtd/compatmac.h>
 
 
 /* Where to look for the devices? */
 /* Where to look for the devices? */
 #ifndef CONFIG_MTD_DOCPROBE_ADDRESS
 #ifndef CONFIG_MTD_DOCPROBE_ADDRESS

+ 29 - 14
drivers/mtd/devices/m25p80.c

@@ -16,6 +16,8 @@
  */
  */
 
 
 #include <linux/init.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/interrupt.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) },
 	{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
 	{ "at26df321",  INFO(0x1f4701, 0, 64 * 1024, 64, 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 */
 	/* Macronix */
 	{ "mx25l4005a",  INFO(0xc22013, 0, 64 * 1024,   8, SECT_4K) },
 	{ "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) },
 	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, 0) },
 	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, 0) },
 	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, 0) },
 	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 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) },
 	{ "m25p64",  INFO(0x202017,  0,  64 * 1024, 128, 0) },
 	{ "m25p128", INFO(0x202018,  0, 256 * 1024,  64, 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) },
 	{ "m45pe10", INFO(0x204011,  0, 64 * 1024,    2, 0) },
 	{ "m45pe80", INFO(0x204014,  0, 64 * 1024,   16, 0) },
 	{ "m45pe80", INFO(0x204014,  0, 64 * 1024,   16, 0) },
 	{ "m45pe16", INFO(0x204015,  0, 64 * 1024,   32, 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) },
 	{ "w25x80", INFO(0xef3014, 0, 64 * 1024,  16, SECT_4K) },
 	{ "w25x16", INFO(0xef3015, 0, 64 * 1024,  32, SECT_4K) },
 	{ "w25x16", INFO(0xef3015, 0, 64 * 1024,  32, SECT_4K) },
 	{ "w25x32", INFO(0xef3016, 0, 64 * 1024,  64, 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) },
 	{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
 
 
 	/* Catalyst / On Semiconductor -- non-JEDEC */
 	/* 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) {
 	if (tmp < 0) {
 		DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
 		DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
 			dev_name(&spi->dev), tmp);
 			dev_name(&spi->dev), tmp);
-		return NULL;
+		return ERR_PTR(tmp);
 	}
 	}
 	jedec = id[0];
 	jedec = id[0];
 	jedec = jedec << 8;
 	jedec = jedec << 8;
@@ -731,14 +754,6 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
 	jedec = jedec << 8;
 	jedec = jedec << 8;
 	jedec |= id[2];
 	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];
 	ext_jedec = id[3] << 8 | id[4];
 
 
 	for (tmp = 0; tmp < ARRAY_SIZE(m25p_ids) - 1; tmp++) {
 	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 &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;
 		const struct spi_device_id *jid;
 
 
 		jid = jedec_probe(spi);
 		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) {
 		} else if (jid != id) {
 			/*
 			/*
 			 * JEDEC knows better, so overwrite platform ID. We
 			 * 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);
 	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
 	 * up with the software protection bits set
 	 */
 	 */
 
 
 	if (info->jedec_id >> 16 == 0x1f ||
 	if (info->jedec_id >> 16 == 0x1f ||
+	    info->jedec_id >> 16 == 0x89 ||
 	    info->jedec_id >> 16 == 0xbf) {
 	    info->jedec_id >> 16 == 0xbf) {
 		write_enable(flash);
 		write_enable(flash);
 		write_sr(flash, 0);
 		write_sr(flash, 0);

+ 6 - 6
drivers/mtd/devices/mtd_dataflash.c

@@ -141,7 +141,7 @@ static int dataflash_waitready(struct spi_device *spi)
  */
  */
 static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
 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_device	*spi = priv->spi;
 	struct spi_transfer	x = { .tx_dma = 0, };
 	struct spi_transfer	x = { .tx_dma = 0, };
 	struct spi_message	msg;
 	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,
 static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
 			       size_t *retlen, u_char *buf)
 			       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_transfer	x[2] = { { .tx_dma = 0, }, };
 	struct spi_message	msg;
 	struct spi_message	msg;
 	unsigned int		addr;
 	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,
 static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
 				size_t * retlen, const u_char * buf)
 				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_device	*spi = priv->spi;
 	struct spi_transfer	x[2] = { { .tx_dma = 0, }, };
 	struct spi_transfer	x[2] = { { .tx_dma = 0, }, };
 	struct spi_message	msg;
 	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,
 static int dataflash_read_fact_otp(struct mtd_info *mtd,
 		loff_t from, size_t len, size_t *retlen, u_char *buf)
 		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;
 	int			status;
 
 
 	/* 64 bytes, from 0..63 ... start at 64 on-chip */
 	/* 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,
 static int dataflash_read_user_otp(struct mtd_info *mtd,
 		loff_t from, size_t len, size_t *retlen, u_char *buf)
 		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;
 	int			status;
 
 
 	/* 64 bytes, from 0..63 ... start at 0 on-chip */
 	/* 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;
 	const size_t		l = 4 + 64;
 	uint8_t			*scratch;
 	uint8_t			*scratch;
 	struct spi_transfer	t;
 	struct spi_transfer	t;
-	struct dataflash	*priv = (struct dataflash *)mtd->priv;
+	struct dataflash	*priv = mtd->priv;
 	int			status;
 	int			status;
 
 
 	if (len > 64)
 	if (len > 64)

+ 0 - 1
drivers/mtd/devices/mtdram.c

@@ -14,7 +14,6 @@
 #include <linux/ioport.h>
 #include <linux/ioport.h>
 #include <linux/vmalloc.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <linux/init.h>
-#include <linux/mtd/compatmac.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtdram.h>
 #include <linux/mtd/mtdram.h>
 
 

+ 0 - 1
drivers/mtd/devices/pmc551.c

@@ -98,7 +98,6 @@
 
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/pmc551.h>
 #include <linux/mtd/pmc551.h>
-#include <linux/mtd/compatmac.h>
 
 
 static struct mtd_info *pmc551list;
 static struct mtd_info *pmc551list;
 
 

+ 1 - 1
drivers/mtd/devices/sst25l.c

@@ -454,7 +454,7 @@ static int __init sst25l_probe(struct spi_device *spi)
 						  parts, nr_parts);
 						  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",
 		dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
 			 data->nr_parts, data->name);
 			 data->nr_parts, data->name);
 	}
 	}

+ 1 - 1
drivers/mtd/ftl.c

@@ -26,7 +26,7 @@
 
 
     The initial developer of the original code is David A. Hinds
     The initial developer of the original code is David A. Hinds
     <dahinds@users.sourceforge.net>.  Portions created by 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
     Alternatively, the contents of this file may be used under the
     terms of the GNU General Public License version 2 (the "GPL"), in
     terms of the GNU General Public License version 2 (the "GPL"), in

+ 3 - 3
drivers/mtd/inftlcore.c

@@ -1,11 +1,11 @@
 /*
 /*
  * inftlcore.c -- Linux driver for Inverse Flash Translation Layer (INFTL)
  * 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:
  * 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
  * 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
  * it under the terms of the GNU General Public License as published by

+ 2 - 3
drivers/mtd/inftlmount.c

@@ -2,11 +2,11 @@
  * inftlmount.c -- INFTL mount code with extensive checks.
  * inftlmount.c -- INFTL mount code with extensive checks.
  *
  *
  * Author: Greg Ungerer (gerg@snapgear.com)
  * 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:
  * Based heavily on the nftlmount.c code which is:
  * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
  * 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
  * 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
  * 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/mtd.h>
 #include <linux/mtd/nftl.h>
 #include <linux/mtd/nftl.h>
 #include <linux/mtd/inftl.h>
 #include <linux/mtd/inftl.h>
-#include <linux/mtd/compatmac.h>
 
 
 /*
 /*
  * find_boot_record: Find the INFTL Media Header and its Spare copy which
  * find_boot_record: Find the INFTL Media Header and its Spare copy which

+ 10 - 10
drivers/mtd/lpddr/lpddr_cmds.c

@@ -98,7 +98,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map)
 	numchips = lpddr->numchips / lpddr->qinfo->HWPartsNum;
 	numchips = lpddr->numchips / lpddr->qinfo->HWPartsNum;
 	for (i = 0; i < numchips; i++) {
 	for (i = 0; i < numchips; i++) {
 		shared[i].writing = shared[i].erasing = NULL;
 		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++) {
 		for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) {
 			*chip = lpddr->chips[i];
 			*chip = lpddr->chips[i];
 			chip->start += j << lpddr->chipshift;
 			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_shared *shared = chip->priv;
 		struct flchip *contender;
 		struct flchip *contender;
-		spin_lock(&shared->lock);
+		mutex_lock(&shared->lock);
 		contender = shared->writing;
 		contender = shared->writing;
 		if (contender && contender != chip) {
 		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.
 			 * get_chip returns success we're clear to go ahead.
 			 */
 			 */
 			ret = mutex_trylock(&contender->mutex);
 			ret = mutex_trylock(&contender->mutex);
-			spin_unlock(&shared->lock);
+			mutex_unlock(&shared->lock);
 			if (!ret)
 			if (!ret)
 				goto retry;
 				goto retry;
 			mutex_unlock(&chip->mutex);
 			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);
 				mutex_unlock(&contender->mutex);
 				return ret;
 				return ret;
 			}
 			}
-			spin_lock(&shared->lock);
+			mutex_lock(&shared->lock);
 
 
 			/* We should not own chip if it is already in FL_SYNCING
 			/* We should not own chip if it is already in FL_SYNCING
 			 * state. Put contender and retry. */
 			 * 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. */
 		   Must sleep in such a case. */
 		if (mode == FL_ERASING && shared->erasing
 		if (mode == FL_ERASING && shared->erasing
 		    && shared->erasing->oldstate == FL_ERASING) {
 		    && shared->erasing->oldstate == FL_ERASING) {
-			spin_unlock(&shared->lock);
+			mutex_unlock(&shared->lock);
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			add_wait_queue(&chip->wq, &wait);
 			add_wait_queue(&chip->wq, &wait);
 			mutex_unlock(&chip->mutex);
 			mutex_unlock(&chip->mutex);
@@ -275,7 +275,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
 		shared->writing = chip;
 		shared->writing = chip;
 		if (mode == FL_ERASING)
 		if (mode == FL_ERASING)
 			shared->erasing = chip;
 			shared->erasing = chip;
-		spin_unlock(&shared->lock);
+		mutex_unlock(&shared->lock);
 	}
 	}
 
 
 	ret = chip_ready(map, chip, mode);
 	ret = chip_ready(map, chip, mode);
@@ -348,7 +348,7 @@ static void put_chip(struct map_info *map, struct flchip *chip)
 {
 {
 	if (chip->priv) {
 	if (chip->priv) {
 		struct flchip_shared *shared = chip->priv;
 		struct flchip_shared *shared = chip->priv;
-		spin_lock(&shared->lock);
+		mutex_lock(&shared->lock);
 		if (shared->writing == chip && chip->oldstate == FL_READY) {
 		if (shared->writing == chip && chip->oldstate == FL_READY) {
 			/* We own the ability to write, but we're done */
 			/* We own the ability to write, but we're done */
 			shared->writing = shared->erasing;
 			shared->writing = shared->erasing;
@@ -356,7 +356,7 @@ static void put_chip(struct map_info *map, struct flchip *chip)
 				/* give back the ownership */
 				/* give back the ownership */
 				struct flchip *loaner = shared->writing;
 				struct flchip *loaner = shared->writing;
 				mutex_lock(&loaner->mutex);
 				mutex_lock(&loaner->mutex);
-				spin_unlock(&shared->lock);
+				mutex_unlock(&shared->lock);
 				mutex_unlock(&chip->mutex);
 				mutex_unlock(&chip->mutex);
 				put_chip(map, loaner);
 				put_chip(map, loaner);
 				mutex_lock(&chip->mutex);
 				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
 			 * Don't let the switch below mess things up since
 			 * we don't have ownership to resume anything.
 			 * we don't have ownership to resume anything.
 			 */
 			 */
-			spin_unlock(&shared->lock);
+			mutex_unlock(&shared->lock);
 			wake_up(&chip->wq);
 			wake_up(&chip->wq);
 			return;
 			return;
 		}
 		}
-		spin_unlock(&shared->lock);
+		mutex_unlock(&shared->lock);
 	}
 	}
 
 
 	switch (chip->oldstate) {
 	switch (chip->oldstate) {

+ 0 - 8
drivers/mtd/maps/Kconfig

@@ -319,14 +319,6 @@ config MTD_CFI_FLAGADM
 	  Mapping for the Flaga digital module. If you don't have one, ignore
 	  Mapping for the Flaga digital module. If you don't have one, ignore
 	  this setting.
 	  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
 config MTD_SOLUTIONENGINE
 	tristate "CFI Flash device mapped on Hitachi SolutionEngine"
 	tristate "CFI Flash device mapped on Hitachi SolutionEngine"
 	depends on SUPERH && SOLUTION_ENGINE && MTD_CFI && MTD_REDBOOT_PARTS
 	depends on SUPERH && SOLUTION_ENGINE && MTD_CFI && MTD_REDBOOT_PARTS

+ 0 - 1
drivers/mtd/maps/Makefile

@@ -44,7 +44,6 @@ obj-$(CONFIG_MTD_AUTCPU12)	+= autcpu12-nvram.o
 obj-$(CONFIG_MTD_EDB7312)	+= edb7312.o
 obj-$(CONFIG_MTD_EDB7312)	+= edb7312.o
 obj-$(CONFIG_MTD_IMPA7)		+= impa7.o
 obj-$(CONFIG_MTD_IMPA7)		+= impa7.o
 obj-$(CONFIG_MTD_FORTUNET)	+= fortunet.o
 obj-$(CONFIG_MTD_FORTUNET)	+= fortunet.o
-obj-$(CONFIG_MTD_REDWOOD)	+= redwood.o
 obj-$(CONFIG_MTD_UCLINUX)	+= uclinux.o
 obj-$(CONFIG_MTD_UCLINUX)	+= uclinux.o
 obj-$(CONFIG_MTD_NETtel)	+= nettel.o
 obj-$(CONFIG_MTD_NETtel)	+= nettel.o
 obj-$(CONFIG_MTD_SCB2_FLASH)	+= scb2_flash.o
 obj-$(CONFIG_MTD_SCB2_FLASH)	+= scb2_flash.o

+ 27 - 8
drivers/mtd/maps/ixp4xx.c

@@ -118,7 +118,7 @@ static void ixp4xx_copy_from(struct map_info *map, void *to,
 		*dest++ = BYTE1(data);
 		*dest++ = BYTE1(data);
 		src += 2;
 		src += 2;
 		len -= 2;
 		len -= 2;
-        }
+	}
 
 
 	if (len > 0)
 	if (len > 0)
 		*dest++ = BYTE0(flash_read16(src));
 		*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 flash_platform_data *plat = dev->dev.platform_data;
 	struct ixp4xx_flash_info *info;
 	struct ixp4xx_flash_info *info;
+	const char *part_type = NULL;
+	int nr_parts = 0;
 	int err = -1;
 	int err = -1;
 
 
 	if (!plat)
 	if (!plat)
@@ -218,9 +220,9 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
 	 */
 	 */
 	info->map.bankwidth = 2;
 	info->map.bankwidth = 2;
 	info->map.name = dev_name(&dev->dev);
 	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,
 	info->res = request_mem_region(dev->resource->start,
 			resource_size(dev->resource),
 			resource_size(dev->resource),
@@ -248,11 +250,28 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
 	info->mtd->owner = THIS_MODULE;
 	info->mtd->owner = THIS_MODULE;
 
 
 	/* Use the fast version */
 	/* 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)
 		if(err)
 			printk(KERN_ERR "Could not parse partitions\n");
 			printk(KERN_ERR "Could not parse partitions\n");
 	}
 	}

+ 9 - 5
drivers/mtd/maps/physmap.c

@@ -106,12 +106,12 @@ static int physmap_flash_probe(struct platform_device *dev)
 
 
 	for (i = 0; i < dev->num_resources; i++) {
 	for (i = 0; i < dev->num_resources; i++) {
 		printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n",
 		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);
 		       (unsigned long long)dev->resource[i].start);
 
 
 		if (!devm_request_mem_region(&dev->dev,
 		if (!devm_request_mem_region(&dev->dev,
 			dev->resource[i].start,
 			dev->resource[i].start,
-			dev->resource[i].end - dev->resource[i].start + 1,
+			resource_size(&dev->resource[i]),
 			dev_name(&dev->dev))) {
 			dev_name(&dev->dev))) {
 			dev_err(&dev->dev, "Could not reserve memory region\n");
 			dev_err(&dev->dev, "Could not reserve memory region\n");
 			err = -ENOMEM;
 			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].name = dev_name(&dev->dev);
 		info->map[i].phys = dev->resource[i].start;
 		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].bankwidth = physmap_data->width;
 		info->map[i].set_vpp = physmap_data->set_vpp;
 		info->map[i].set_vpp = physmap_data->set_vpp;
 		info->map[i].pfow_base = physmap_data->pfow_base;
 		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]);
 		simple_map_init(&info->map[i]);
 
 
 		probe_type = rom_probe_types;
 		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) {
 		if (info->mtd[i] == NULL) {
 			dev_err(&dev->dev, "map_probe failed\n");
 			dev_err(&dev->dev, "map_probe failed\n");
 			err = -ENXIO;
 			err = -ENXIO;

+ 3 - 3
drivers/mtd/maps/physmap_of.c

@@ -353,7 +353,7 @@ static int __devinit of_flash_probe(struct of_device *dev,
 				   &info->parts, 0);
 				   &info->parts, 0);
 	if (err < 0) {
 	if (err < 0) {
 		of_free_probes(part_probe_types);
 		of_free_probes(part_probe_types);
-		return err;
+		goto err_out;
 	}
 	}
 	of_free_probes(part_probe_types);
 	of_free_probes(part_probe_types);
 
 
@@ -361,14 +361,14 @@ static int __devinit of_flash_probe(struct of_device *dev,
 	if (err == 0) {
 	if (err == 0) {
 		err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts);
 		err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts);
 		if (err < 0)
 		if (err < 0)
-			return err;
+			goto err_out;
 	}
 	}
 #endif
 #endif
 
 
 	if (err == 0) {
 	if (err == 0) {
 		err = parse_obsolete_partitions(dev, info, dp);
 		err = parse_obsolete_partitions(dev, info, dp);
 		if (err < 0)
 		if (err < 0)
-			return err;
+			goto err_out;
 	}
 	}
 
 
 	if (err > 0)
 	if (err > 0)

+ 0 - 131
drivers/mtd/maps/redwood.c

@@ -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");

+ 21 - 5
drivers/mtd/mtd_blkdevs.c

@@ -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) {
 	switch (cmd) {
 	case BLKFLSBUF:
 	case BLKFLSBUF:
 		ret = dev->tr->flush ? dev->tr->flush(dev) : 0;
 		ret = dev->tr->flush ? dev->tr->flush(dev) : 0;
+		break;
 	default:
 	default:
 		ret = -ENOTTY;
 		ret = -ENOTTY;
 	}
 	}
@@ -409,13 +424,14 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
 		BUG();
 		BUG();
 	}
 	}
 
 
-	/* Stop new requests to arrive */
-	del_gendisk(old->disk);
-
 	if (old->disk_attributes)
 	if (old->disk_attributes)
 		sysfs_remove_group(&disk_to_dev(old->disk)->kobj,
 		sysfs_remove_group(&disk_to_dev(old->disk)->kobj,
 						old->disk_attributes);
 						old->disk_attributes);
 
 
+	/* Stop new requests to arrive */
+	del_gendisk(old->disk);
+
+
 	/* Stop the thread */
 	/* Stop the thread */
 	kthread_stop(old->thread);
 	kthread_stop(old->thread);
 
 

+ 17 - 2
drivers/mtd/mtdblock.c

@@ -1,8 +1,23 @@
 /*
 /*
  * Direct MTD block device access
  * 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>
 #include <linux/fs.h>

+ 17 - 2
drivers/mtd/mtdblock_ro.c

@@ -1,7 +1,22 @@
 /*
 /*
- * (C) 2003 David Woodhouse <dwmw2@infradead.org>
- *
  * Simple read-only (writable only for RAM) mtdblock driver
  * 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>
 #include <linux/init.h>

+ 56 - 3
drivers/mtd/mtdchar.c

@@ -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/mount.h>
 
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
-#include <linux/mtd/compatmac.h>
+#include <linux/mtd/map.h>
 
 
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 
 
@@ -675,6 +689,20 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
 		break;
 		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 */
 	/* Legacy interface */
 	case MEMGETOOBSEL:
 	case MEMGETOOBSEL:
 	{
 	{
@@ -950,9 +978,34 @@ static int mtd_mmap(struct file *file, struct vm_area_struct *vma)
 #ifdef CONFIG_MMU
 #ifdef CONFIG_MMU
 	struct mtd_file_info *mfi = file->private_data;
 	struct mtd_file_info *mfi = file->private_data;
 	struct mtd_info *mtd = mfi->mtd;
 	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 0;
+	}
 	return -ENOSYS;
 	return -ENOSYS;
 #else
 #else
 	return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS;
 	return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS;

+ 28 - 10
drivers/mtd/mtdconcat.c

@@ -1,11 +1,25 @@
 /*
 /*
  * MTD device concatenation layer
  * 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>
  * 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>
 #include <linux/kernel.h>
@@ -540,10 +554,12 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 		else
 		else
 			size = len;
 			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;
 		len -= size;
 		if (len == 0)
 		if (len == 0)
@@ -578,10 +594,12 @@ static int concat_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 		else
 		else
 			size = len;
 			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;
 		len -= size;
 		if (len == 0)
 		if (len == 0)

+ 17 - 4
drivers/mtd/mtdcore.c

@@ -2,9 +2,23 @@
  * Core registration and callback routines for MTD
  * Core registration and callback routines for MTD
  * drivers and users.
  * 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>
 #include <linux/module.h>
@@ -17,7 +31,6 @@
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/ioctl.h>
 #include <linux/ioctl.h>
 #include <linux/init.h>
 #include <linux/init.h>
-#include <linux/mtd/compatmac.h>
 #include <linux/proc_fs.h>
 #include <linux/proc_fs.h>
 #include <linux/idr.h>
 #include <linux/idr.h>
 #include <linux/backing-dev.h>
 #include <linux/backing-dev.h>

+ 1 - 1
drivers/mtd/mtdoops.c

@@ -1,7 +1,7 @@
 /*
 /*
  * MTD Oops/Panic logger
  * 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>
  * Author: Richard Purdie <rpurdie@openedhand.com>
  *
  *

+ 26 - 5
drivers/mtd/mtdpart.c

@@ -1,12 +1,24 @@
 /*
 /*
  * Simple MTD partitioning layer
  * 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>
 #include <linux/module.h>
@@ -17,7 +29,6 @@
 #include <linux/kmod.h>
 #include <linux/kmod.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/partitions.h>
-#include <linux/mtd/compatmac.h>
 
 
 /* Our partition linked list */
 /* Our partition linked list */
 static LIST_HEAD(mtd_partitions);
 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);
 	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)
 static void part_sync(struct mtd_info *mtd)
 {
 {
 	struct mtd_part *part = PART(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;
 		slave->mtd.lock = part_lock;
 	if (master->unlock)
 	if (master->unlock)
 		slave->mtd.unlock = part_unlock;
 		slave->mtd.unlock = part_unlock;
+	if (master->is_locked)
+		slave->mtd.is_locked = part_is_locked;
 	if (master->block_isbad)
 	if (master->block_isbad)
 		slave->mtd.block_isbad = part_block_isbad;
 		slave->mtd.block_isbad = part_block_isbad;
 	if (master->block_markbad)
 	if (master->block_markbad)

+ 2 - 0
drivers/mtd/mtdsuper.c

@@ -1,6 +1,8 @@
 /* MTD-based superblock management
 /* MTD-based superblock management
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc. All Rights Reserved.
  * Copyright © 2001-2007 Red Hat, Inc. All Rights Reserved.
+ * Copyright © 2001-2010 David Woodhouse <dwmw2@infradead.org>
+ *
  * Written by:  David Howells <dhowells@redhat.com>
  * Written by:  David Howells <dhowells@redhat.com>
  *              David Woodhouse <dwmw2@infradead.org>
  *              David Woodhouse <dwmw2@infradead.org>
  *
  *

+ 16 - 17
drivers/mtd/nand/Kconfig

@@ -37,7 +37,6 @@ config MTD_SM_COMMON
 
 
 config MTD_NAND_MUSEUM_IDS
 config MTD_NAND_MUSEUM_IDS
 	bool "Enable chip ids for obsolete ancient NAND devices"
 	bool "Enable chip ids for obsolete ancient NAND devices"
-	depends on MTD_NAND
 	default n
 	default n
 	help
 	help
 	  Enable this option only when your board has first generation
 	  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
 config MTD_NAND_DENALI_SCRATCH_REG_ADDR
         hex "Denali NAND size scratch register address"
         hex "Denali NAND size scratch register address"
         default "0xFF108018"
         default "0xFF108018"
+        depends on MTD_NAND_DENALI
         help
         help
           Some platforms place the NAND chip size in a scratch register
           Some platforms place the NAND chip size in a scratch register
           because (some versions of) the driver aren't able to automatically
           because (some versions of) the driver aren't able to automatically
@@ -101,13 +101,13 @@ config MTD_NAND_AMS_DELTA
 
 
 config MTD_NAND_OMAP2
 config MTD_NAND_OMAP2
 	tristate "NAND Flash device on OMAP2 and OMAP3"
 	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
 	help
           Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms.
           Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms.
 
 
 config MTD_NAND_OMAP_PREFETCH
 config MTD_NAND_OMAP_PREFETCH
 	bool "GPMC prefetch support for NAND Flash device"
 	bool "GPMC prefetch support for NAND Flash device"
-	depends on MTD_NAND && MTD_NAND_OMAP2
+	depends on MTD_NAND_OMAP2
 	default y
 	default y
 	help
 	help
 	 The NAND device can be accessed for Read/Write using GPMC PREFETCH engine
 	 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
 config MTD_NAND_BF5XX
 	tristate "Blackfin on-chip NAND Flash Controller driver"
 	tristate "Blackfin on-chip NAND Flash Controller driver"
-	depends on (BF54x || BF52x) && MTD_NAND
+	depends on BF54x || BF52x
 	help
 	help
 	  This enables the Blackfin on-chip NAND flash controller
 	  This enables the Blackfin on-chip NAND flash controller
 
 
@@ -236,7 +236,7 @@ config MTD_NAND_S3C2410_CLKSTOP
 
 
 config MTD_NAND_BCM_UMI
 config MTD_NAND_BCM_UMI
 	tristate "NAND Flash support for BCM Reference Boards"
 	tristate "NAND Flash support for BCM Reference Boards"
-	depends on ARCH_BCMRING && MTD_NAND
+	depends on ARCH_BCMRING
 	help
 	help
 	  This enables the NAND flash controller on the BCM UMI block.
 	  This enables the NAND flash controller on the BCM UMI block.
 
 
@@ -395,7 +395,7 @@ endchoice
 
 
 config MTD_NAND_PXA3xx
 config MTD_NAND_PXA3xx
 	tristate "Support for NAND flash devices on PXA3xx"
 	tristate "Support for NAND flash devices on PXA3xx"
-	depends on MTD_NAND && (PXA3xx || ARCH_MMP)
+	depends on PXA3xx || ARCH_MMP
 	help
 	help
 	  This enables the driver for the NAND flash device found on
 	  This enables the driver for the NAND flash device found on
 	  PXA3xx processors
 	  PXA3xx processors
@@ -409,18 +409,18 @@ config MTD_NAND_PXA3xx_BUILTIN
 
 
 config MTD_NAND_CM_X270
 config MTD_NAND_CM_X270
 	tristate "Support for NAND Flash on CM-X270 modules"
 	tristate "Support for NAND Flash on CM-X270 modules"
-	depends on MTD_NAND && MACH_ARMCORE
+	depends on MACH_ARMCORE
 
 
 config MTD_NAND_PASEMI
 config MTD_NAND_PASEMI
 	tristate "NAND support for PA Semi PWRficient"
 	tristate "NAND support for PA Semi PWRficient"
-	depends on MTD_NAND && PPC_PASEMI
+	depends on PPC_PASEMI
 	help
 	help
 	  Enables support for NAND Flash interface on PA Semi PWRficient
 	  Enables support for NAND Flash interface on PA Semi PWRficient
 	  based boards
 	  based boards
 
 
 config MTD_NAND_TMIO
 config MTD_NAND_TMIO
 	tristate "NAND Flash device on Toshiba Mobile IO Controller"
 	tristate "NAND Flash device on Toshiba Mobile IO Controller"
-	depends on MTD_NAND && MFD_TMIO
+	depends on MFD_TMIO
 	help
 	help
 	  Support for NAND flash connected to a Toshiba Mobile IO
 	  Support for NAND flash connected to a Toshiba Mobile IO
 	  Controller in some PDAs, including the Sharp SL6000x.
 	  Controller in some PDAs, including the Sharp SL6000x.
@@ -434,7 +434,6 @@ config MTD_NAND_NANDSIM
 
 
 config MTD_NAND_PLATFORM
 config MTD_NAND_PLATFORM
 	tristate "Support for generic platform NAND driver"
 	tristate "Support for generic platform NAND driver"
-	depends on MTD_NAND
 	help
 	help
 	  This implements a generic NAND driver for on-SOC platform
 	  This implements a generic NAND driver for on-SOC platform
 	  devices. You will need to provide platform-specific functions
 	  devices. You will need to provide platform-specific functions
@@ -442,14 +441,14 @@ config MTD_NAND_PLATFORM
 
 
 config MTD_ALAUDA
 config MTD_ALAUDA
 	tristate "MTD driver for Olympus MAUSB-10 and Fujifilm DPC-R1"
 	tristate "MTD driver for Olympus MAUSB-10 and Fujifilm DPC-R1"
-	depends on MTD_NAND && USB
+	depends on USB
 	help
 	help
 	  These two (and possibly other) Alauda-based cardreaders for
 	  These two (and possibly other) Alauda-based cardreaders for
 	  SmartMedia and xD allow raw flash access.
 	  SmartMedia and xD allow raw flash access.
 
 
 config MTD_NAND_ORION
 config MTD_NAND_ORION
 	tristate "NAND Flash support for Marvell Orion SoC"
 	tristate "NAND Flash support for Marvell Orion SoC"
-	depends on PLAT_ORION && MTD_NAND
+	depends on PLAT_ORION
 	help
 	help
 	  This enables the NAND flash controller on Orion machines.
 	  This enables the NAND flash controller on Orion machines.
 
 
@@ -458,7 +457,7 @@ config MTD_NAND_ORION
 
 
 config MTD_NAND_FSL_ELBC
 config MTD_NAND_FSL_ELBC
 	tristate "NAND support for Freescale eLBC controllers"
 	tristate "NAND support for Freescale eLBC controllers"
-	depends on MTD_NAND && PPC_OF
+	depends on PPC_OF
 	help
 	help
 	  Various Freescale chips, including the 8313, include a NAND Flash
 	  Various Freescale chips, including the 8313, include a NAND Flash
 	  Controller Module with built-in hardware ECC capabilities.
 	  Controller Module with built-in hardware ECC capabilities.
@@ -467,7 +466,7 @@ config MTD_NAND_FSL_ELBC
 
 
 config MTD_NAND_FSL_UPM
 config MTD_NAND_FSL_UPM
 	tristate "Support for NAND on Freescale 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
 	select FSL_LBC
 	help
 	help
 	  Enables support for NAND Flash chips wired onto Freescale PowerPC
 	  Enables support for NAND Flash chips wired onto Freescale PowerPC
@@ -482,7 +481,7 @@ config MTD_NAND_MPC5121_NFC
 
 
 config MTD_NAND_MXC
 config MTD_NAND_MXC
 	tristate "MXC NAND support"
 	tristate "MXC NAND support"
-	depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3
+	depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3 || ARCH_MX51
 	help
 	help
 	  This enables the driver for the NAND flash controller on the
 	  This enables the driver for the NAND flash controller on the
 	  MXC processors.
 	  MXC processors.
@@ -495,7 +494,7 @@ config MTD_NAND_NOMADIK
 
 
 config MTD_NAND_SH_FLCTL
 config MTD_NAND_SH_FLCTL
 	tristate "Support for NAND on Renesas SuperH FLCTL"
 	tristate "Support for NAND on Renesas SuperH FLCTL"
-	depends on MTD_NAND && (SUPERH || ARCH_SHMOBILE)
+	depends on SUPERH || ARCH_SHMOBILE
 	help
 	help
 	  Several Renesas SuperH CPU has FLCTL. This option enables support
 	  Several Renesas SuperH CPU has FLCTL. This option enables support
 	  for NAND Flash using FLCTL.
 	  for NAND Flash using FLCTL.
@@ -515,7 +514,7 @@ config MTD_NAND_TXX9NDFMC
 
 
 config MTD_NAND_SOCRATES
 config MTD_NAND_SOCRATES
 	tristate "Support for NAND on Socrates board"
 	tristate "Support for NAND on Socrates board"
-	depends on MTD_NAND && SOCRATES
+	depends on SOCRATES
 	help
 	help
 	  Enables support for NAND Flash chips wired onto Socrates board.
 	  Enables support for NAND Flash chips wired onto Socrates board.
 
 

+ 1 - 1
drivers/mtd/nand/atmel_nand.c

@@ -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 };
 static const char *part_probes[] = { "cmdlinepart", NULL };
 #endif
 #endif
 
 

+ 72 - 45
drivers/mtd/nand/bf5xx_nand.c

@@ -20,9 +20,6 @@
  *		- DMA supported in ECC_HW
  *		- DMA supported in ECC_HW
  *		- YAFFS tested as rootfs in both ECC_HW and ECC_SW
  *		- 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
  * 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
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * 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)
 	if (ctrl & NAND_CLE)
 		bfin_write_NFC_CMD(cmd);
 		bfin_write_NFC_CMD(cmd);
-	else
+	else if (ctrl & NAND_ALE)
 		bfin_write_NFC_ADDR(cmd);
 		bfin_write_NFC_ADDR(cmd);
 	SSYNC();
 	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)
 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;
 		return 1;
 	else
 	else
 		return 0;
 		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,
 static int bf5xx_nand_correct_data(struct mtd_info *mtd, u_char *dat,
 					u_char *read_ecc, u_char *calc_ecc)
 					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;
 	int ret;
 
 
 	ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc);
 	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;
 		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);
 		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)
 		const u_char *dat, u_char *ecc_code)
 {
 {
 	struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
 	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;
 	u16 ecc0, ecc1;
 	u32 code[2];
 	u32 code[2];
 	u8 *p;
 	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();
 	ecc0 = bfin_read_NFC_ECC0();
 	ecc1 = bfin_read_NFC_ECC1();
 	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]);
 	dev_dbg(info->device, "returning ecc 0x%08x\n", code[0]);
 
 
-	/* first 3 bytes in ecc_code for 256 page size */
 	p = (u8 *) code;
 	p = (u8 *) code;
 	memcpy(ecc_code, p, 3);
 	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();
 		ecc0 = bfin_read_NFC_ECC2();
 		ecc1 = bfin_read_NFC_ECC3();
 		ecc1 = bfin_read_NFC_ECC3();
 		code[1] = (ecc0 & 0x7ff) | ((ecc1 & 0x7ff) << 11);
 		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)
 				uint8_t *buf, int is_read)
 {
 {
 	struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
 	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;
 	unsigned short val;
 
 
 	dev_dbg(info->device, " mtd->%p, buf->%p, is_read %d\n",
 	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)
 	if (is_read)
 		invalidate_dcache_range((unsigned int)buf,
 		invalidate_dcache_range((unsigned int)buf,
-				(unsigned int)(buf + page_size));
+				(unsigned int)(buf + chip->ecc.size));
 	else
 	else
 		flush_dcache_range((unsigned int)buf,
 		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
 	 * 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);
 	bfin_write_NFC_RST(ECC_RST);
 	SSYNC();
 	SSYNC();
+	while (bfin_read_NFC_RST() & ECC_RST)
+		cpu_relax();
 
 
 	disable_dma(CH_NFC);
 	disable_dma(CH_NFC);
 	clear_dma_irqstat(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 */
 	/* The DMAs have different size on BF52x and BF54x */
 #ifdef CONFIG_BF52x
 #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);
 	set_dma_x_modify(CH_NFC, 2);
 	val = DI_EN | WDSIZE_16;
 	val = DI_EN | WDSIZE_16;
 #endif
 #endif
 
 
 #ifdef CONFIG_BF54x
 #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);
 	set_dma_x_modify(CH_NFC, 4);
 	val = DI_EN | WDSIZE_32;
 	val = DI_EN | WDSIZE_32;
 #endif
 #endif
@@ -548,12 +542,11 @@ static void bf5xx_nand_dma_read_buf(struct mtd_info *mtd,
 					uint8_t *buf, int len)
 					uint8_t *buf, int len)
 {
 {
 	struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
 	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);
 	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);
 		bf5xx_nand_dma_rw(mtd, buf, 1);
 	else
 	else
 		bf5xx_nand_read_buf(mtd, buf, len);
 		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)
 				const uint8_t *buf, int len)
 {
 {
 	struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
 	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);
 	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);
 		bf5xx_nand_dma_rw(mtd, (uint8_t *)buf, 0);
 	else
 	else
 		bf5xx_nand_write_buf(mtd, buf, len);
 		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
  * System initialization functions
  */
  */
@@ -627,15 +635,14 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info)
 
 
 	/* setup NFC_CTL register */
 	/* setup NFC_CTL register */
 	dev_info(info->device,
 	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->data_width ? 16 : 8),
 		plat->wr_dly, plat->rd_dly);
 		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->data_width << NFC_NWIDTH_OFFSET) |
 		(plat->rd_dly << NFC_RDDLY_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);
 	dev_dbg(info->device, "NFC_CTL is 0x%04x\n", val);
 
 
 	bfin_write_NFC_CTL(val);
 	bfin_write_NFC_CTL(val);
@@ -698,6 +705,33 @@ static int __devexit bf5xx_nand_remove(struct platform_device *pdev)
 	return 0;
 	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
  * bf5xx_nand_probe
  *
  *
@@ -783,27 +817,20 @@ static int __devinit bf5xx_nand_probe(struct platform_device *pdev)
 		chip->badblock_pattern = &bootrom_bbt;
 		chip->badblock_pattern = &bootrom_bbt;
 		chip->ecc.layout = &bootrom_ecclayout;
 		chip->ecc.layout = &bootrom_ecclayout;
 #endif
 #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->read_buf      = bf5xx_nand_dma_read_buf;
 		chip->write_buf     = bf5xx_nand_dma_write_buf;
 		chip->write_buf     = bf5xx_nand_dma_write_buf;
 		chip->ecc.calculate = bf5xx_nand_calculate_ecc;
 		chip->ecc.calculate = bf5xx_nand_calculate_ecc;
 		chip->ecc.correct   = bf5xx_nand_correct_data;
 		chip->ecc.correct   = bf5xx_nand_correct_data;
 		chip->ecc.mode	    = NAND_ECC_HW;
 		chip->ecc.mode	    = NAND_ECC_HW;
 		chip->ecc.hwctl	    = bf5xx_nand_enable_hwecc;
 		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 {
 	} else {
 		chip->ecc.mode	    = NAND_ECC_SOFT;
 		chip->ecc.mode	    = NAND_ECC_SOFT;
 	}
 	}
 
 
 	/* scan hardware nand chip and setup mtd info data struct */
 	/* scan hardware nand chip and setup mtd info data struct */
-	if (nand_scan(mtd, 1)) {
+	if (bf5xx_nand_scan(mtd)) {
 		err = -ENXIO;
 		err = -ENXIO;
 		goto out_err_nand_scan;
 		goto out_err_nand_scan;
 	}
 	}

+ 17 - 0
drivers/mtd/nand/davinci_nand.c

@@ -311,7 +311,9 @@ static int nand_davinci_correct_4bit(struct mtd_info *mtd,
 	unsigned short ecc10[8];
 	unsigned short ecc10[8];
 	unsigned short *ecc16;
 	unsigned short *ecc16;
 	u32 syndrome[4];
 	u32 syndrome[4];
+	u32 ecc_state;
 	unsigned num_errors, corrected;
 	unsigned num_errors, corrected;
+	unsigned long timeo = jiffies + msecs_to_jiffies(100);
 
 
 	/* All bytes 0xff?  It's an erased page; ignore its ECC. */
 	/* All bytes 0xff?  It's an erased page; ignore its ECC. */
 	for (i = 0; i < 10; i++) {
 	for (i = 0; i < 10; i++) {
@@ -361,6 +363,21 @@ compare:
 	 */
 	 */
 	davinci_nand_writel(info, NANDFCR_OFFSET,
 	davinci_nand_writel(info, NANDFCR_OFFSET,
 			davinci_nand_readl(info, NANDFCR_OFFSET) | BIT(13));
 			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 (;;) {
 	for (;;) {
 		u32	fsr = davinci_nand_readl(info, NANDFSR_OFFSET);
 		u32	fsr = davinci_nand_readl(info, NANDFSR_OFFSET);
 
 

File diff suppressed because it is too large
+ 166 - 481
drivers/mtd/nand/denali.c


+ 49 - 91
drivers/mtd/nand/denali.h

@@ -17,7 +17,7 @@
  *
  *
  */
  */
 
 
-#include <linux/mtd/nand.h> 
+#include <linux/mtd/nand.h>
 
 
 #define DEVICE_RESET				0x0
 #define DEVICE_RESET				0x0
 #define     DEVICE_RESET__BANK0				0x0001
 #define     DEVICE_RESET__BANK0				0x0001
@@ -29,7 +29,7 @@
 #define     TRANSFER_SPARE_REG__FLAG			0x0001
 #define     TRANSFER_SPARE_REG__FLAG			0x0001
 
 
 #define LOAD_WAIT_CNT				0x20
 #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			0x30
 #define     PROGRAM_WAIT_CNT__VALUE			0xffff
 #define     PROGRAM_WAIT_CNT__VALUE			0xffff
@@ -83,7 +83,7 @@
 #define RE_2_WE					0x120
 #define RE_2_WE					0x120
 #define     RE_2_WE__VALUE				0x003f
 #define     RE_2_WE__VALUE				0x003f
 
 
-#define ACC_CLKS    				0x130
+#define ACC_CLKS				0x130
 #define     ACC_CLKS__VALUE				0x000f
 #define     ACC_CLKS__VALUE				0x000f
 
 
 #define NUMBER_OF_PLANES			0x140
 #define NUMBER_OF_PLANES			0x140
@@ -140,7 +140,7 @@
 #define DEVICES_CONNECTED			0x250
 #define DEVICES_CONNECTED			0x250
 #define     DEVICES_CONNECTED__VALUE			0x0007
 #define     DEVICES_CONNECTED__VALUE			0x0007
 
 
-#define DIE_MASK					0x260
+#define DIE_MASK				0x260
 #define     DIE_MASK__VALUE				0x00ff
 #define     DIE_MASK__VALUE				0x00ff
 
 
 #define FIRST_BLOCK_OF_NEXT_PLANE		0x270
 #define FIRST_BLOCK_OF_NEXT_PLANE		0x270
@@ -152,7 +152,7 @@
 #define RE_2_RE					0x290
 #define RE_2_RE					0x290
 #define     RE_2_RE__VALUE				0x003f
 #define     RE_2_RE__VALUE				0x003f
 
 
-#define MANUFACTURER_ID			0x300
+#define MANUFACTURER_ID				0x300
 #define     MANUFACTURER_ID__VALUE			0x00ff
 #define     MANUFACTURER_ID__VALUE			0x00ff
 
 
 #define DEVICE_ID				0x310
 #define DEVICE_ID				0x310
@@ -173,13 +173,13 @@
 #define LOGICAL_PAGE_SPARE_SIZE			0x360
 #define LOGICAL_PAGE_SPARE_SIZE			0x360
 #define     LOGICAL_PAGE_SPARE_SIZE__VALUE		0xffff
 #define     LOGICAL_PAGE_SPARE_SIZE__VALUE		0xffff
 
 
-#define REVISION					0x370
+#define REVISION				0x370
 #define     REVISION__VALUE				0xffff
 #define     REVISION__VALUE				0xffff
 
 
 #define ONFI_DEVICE_FEATURES			0x380
 #define ONFI_DEVICE_FEATURES			0x380
 #define     ONFI_DEVICE_FEATURES__VALUE			0x003f
 #define     ONFI_DEVICE_FEATURES__VALUE			0x003f
 
 
-#define ONFI_OPTIONAL_COMMANDS		0x390
+#define ONFI_OPTIONAL_COMMANDS			0x390
 #define     ONFI_OPTIONAL_COMMANDS__VALUE		0x003f
 #define     ONFI_OPTIONAL_COMMANDS__VALUE		0x003f
 
 
 #define ONFI_TIMING_MODE			0x3a0
 #define ONFI_TIMING_MODE			0x3a0
@@ -201,12 +201,12 @@
 #define FEATURES					0x3f0
 #define FEATURES					0x3f0
 #define     FEATURES__N_BANKS				0x0003
 #define     FEATURES__N_BANKS				0x0003
 #define     FEATURES__ECC_MAX_ERR			0x003c
 #define     FEATURES__ECC_MAX_ERR			0x003c
-#define     FEATURES__DMA					0x0040
+#define     FEATURES__DMA				0x0040
 #define     FEATURES__CMD_DMA				0x0080
 #define     FEATURES__CMD_DMA				0x0080
 #define     FEATURES__PARTITION				0x0100
 #define     FEATURES__PARTITION				0x0100
 #define     FEATURES__XDMA_SIDEBAND			0x0200
 #define     FEATURES__XDMA_SIDEBAND			0x0200
 #define     FEATURES__GPREG				0x0400
 #define     FEATURES__GPREG				0x0400
-#define     FEATURES__INDEX_ADDR				0x0800
+#define     FEATURES__INDEX_ADDR			0x0800
 
 
 #define TRANSFER_MODE				0x400
 #define TRANSFER_MODE				0x400
 #define     TRANSFER_MODE__VALUE			0x0003
 #define     TRANSFER_MODE__VALUE			0x0003
@@ -235,12 +235,12 @@
 #define     INTR_EN0__DMA_CMD_COMP			0x0004
 #define     INTR_EN0__DMA_CMD_COMP			0x0004
 #define     INTR_EN0__TIME_OUT				0x0008
 #define     INTR_EN0__TIME_OUT				0x0008
 #define     INTR_EN0__PROGRAM_FAIL			0x0010
 #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__LOAD_COMP				0x0040
 #define     INTR_EN0__PROGRAM_COMP			0x0080
 #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__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__UNSUP_CMD				0x0800
 #define     INTR_EN0__INT_ACT				0x1000
 #define     INTR_EN0__INT_ACT				0x1000
 #define     INTR_EN0__RST_COMP				0x2000
 #define     INTR_EN0__RST_COMP				0x2000
@@ -253,7 +253,7 @@
 #define ERR_PAGE_ADDR0				0x440
 #define ERR_PAGE_ADDR0				0x440
 #define     ERR_PAGE_ADDR0__VALUE			0xffff
 #define     ERR_PAGE_ADDR0__VALUE			0xffff
 
 
-#define ERR_BLOCK_ADDR0			0x450
+#define ERR_BLOCK_ADDR0				0x450
 #define     ERR_BLOCK_ADDR0__VALUE			0xffff
 #define     ERR_BLOCK_ADDR0__VALUE			0xffff
 
 
 #define INTR_STATUS1				0x460
 #define INTR_STATUS1				0x460
@@ -280,12 +280,12 @@
 #define     INTR_EN1__DMA_CMD_COMP			0x0004
 #define     INTR_EN1__DMA_CMD_COMP			0x0004
 #define     INTR_EN1__TIME_OUT				0x0008
 #define     INTR_EN1__TIME_OUT				0x0008
 #define     INTR_EN1__PROGRAM_FAIL			0x0010
 #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__LOAD_COMP				0x0040
 #define     INTR_EN1__PROGRAM_COMP			0x0080
 #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__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__UNSUP_CMD				0x0800
 #define     INTR_EN1__INT_ACT				0x1000
 #define     INTR_EN1__INT_ACT				0x1000
 #define     INTR_EN1__RST_COMP				0x2000
 #define     INTR_EN1__RST_COMP				0x2000
@@ -298,7 +298,7 @@
 #define ERR_PAGE_ADDR1				0x490
 #define ERR_PAGE_ADDR1				0x490
 #define     ERR_PAGE_ADDR1__VALUE			0xffff
 #define     ERR_PAGE_ADDR1__VALUE			0xffff
 
 
-#define ERR_BLOCK_ADDR1			0x4a0
+#define ERR_BLOCK_ADDR1				0x4a0
 #define     ERR_BLOCK_ADDR1__VALUE			0xffff
 #define     ERR_BLOCK_ADDR1__VALUE			0xffff
 
 
 #define INTR_STATUS2				0x4b0
 #define INTR_STATUS2				0x4b0
@@ -325,12 +325,12 @@
 #define     INTR_EN2__DMA_CMD_COMP			0x0004
 #define     INTR_EN2__DMA_CMD_COMP			0x0004
 #define     INTR_EN2__TIME_OUT				0x0008
 #define     INTR_EN2__TIME_OUT				0x0008
 #define     INTR_EN2__PROGRAM_FAIL			0x0010
 #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__LOAD_COMP				0x0040
 #define     INTR_EN2__PROGRAM_COMP			0x0080
 #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__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__UNSUP_CMD				0x0800
 #define     INTR_EN2__INT_ACT				0x1000
 #define     INTR_EN2__INT_ACT				0x1000
 #define     INTR_EN2__RST_COMP				0x2000
 #define     INTR_EN2__RST_COMP				0x2000
@@ -343,7 +343,7 @@
 #define ERR_PAGE_ADDR2				0x4e0
 #define ERR_PAGE_ADDR2				0x4e0
 #define     ERR_PAGE_ADDR2__VALUE			0xffff
 #define     ERR_PAGE_ADDR2__VALUE			0xffff
 
 
-#define ERR_BLOCK_ADDR2			0x4f0
+#define ERR_BLOCK_ADDR2				0x4f0
 #define     ERR_BLOCK_ADDR2__VALUE			0xffff
 #define     ERR_BLOCK_ADDR2__VALUE			0xffff
 
 
 #define INTR_STATUS3				0x500
 #define INTR_STATUS3				0x500
@@ -370,12 +370,12 @@
 #define     INTR_EN3__DMA_CMD_COMP			0x0004
 #define     INTR_EN3__DMA_CMD_COMP			0x0004
 #define     INTR_EN3__TIME_OUT				0x0008
 #define     INTR_EN3__TIME_OUT				0x0008
 #define     INTR_EN3__PROGRAM_FAIL			0x0010
 #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__LOAD_COMP				0x0040
 #define     INTR_EN3__PROGRAM_COMP			0x0080
 #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__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__UNSUP_CMD				0x0800
 #define     INTR_EN3__INT_ACT				0x1000
 #define     INTR_EN3__INT_ACT				0x1000
 #define     INTR_EN3__RST_COMP				0x2000
 #define     INTR_EN3__RST_COMP				0x2000
@@ -388,7 +388,7 @@
 #define ERR_PAGE_ADDR3				0x530
 #define ERR_PAGE_ADDR3				0x530
 #define     ERR_PAGE_ADDR3__VALUE			0xffff
 #define     ERR_PAGE_ADDR3__VALUE			0xffff
 
 
-#define ERR_BLOCK_ADDR3			0x540
+#define ERR_BLOCK_ADDR3				0x540
 #define     ERR_BLOCK_ADDR3__VALUE			0xffff
 #define     ERR_BLOCK_ADDR3__VALUE			0xffff
 
 
 #define DATA_INTR				0x550
 #define DATA_INTR				0x550
@@ -412,9 +412,9 @@
 #define     GPREG_3__VALUE				0xffff
 #define     GPREG_3__VALUE				0xffff
 
 
 #define ECC_THRESHOLD				0x600
 #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_BLOCK_ADDRESS__VALUE		0xffff
 
 
 #define ECC_ERROR_PAGE_ADDRESS			0x620
 #define ECC_ERROR_PAGE_ADDRESS			0x620
@@ -466,7 +466,7 @@
 #define     CHNL_ACTIVE__CHANNEL3			0x0008
 #define     CHNL_ACTIVE__CHANNEL3			0x0008
 
 
 #define ACTIVE_SRC_ID				0x800
 #define ACTIVE_SRC_ID				0x800
-#define     ACTIVE_SRC_ID__VALUE				0x00ff
+#define     ACTIVE_SRC_ID__VALUE			0x00ff
 
 
 #define PTN_INTR					0x810
 #define PTN_INTR					0x810
 #define     PTN_INTR__CONFIG_ERROR			0x0001
 #define     PTN_INTR__CONFIG_ERROR			0x0001
@@ -485,7 +485,7 @@
 #define     PTN_INTR_EN__REG_ACCESS_ERROR		0x0020
 #define     PTN_INTR_EN__REG_ACCESS_ERROR		0x0020
 
 
 #define PERM_SRC_ID_0				0x830
 #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__DIRECT_ACCESS_ACTIVE		0x0800
 #define     PERM_SRC_ID_0__WRITE_ACTIVE			0x2000
 #define     PERM_SRC_ID_0__WRITE_ACTIVE			0x2000
 #define     PERM_SRC_ID_0__READ_ACTIVE			0x4000
 #define     PERM_SRC_ID_0__READ_ACTIVE			0x4000
@@ -502,7 +502,7 @@
 #define     MIN_MAX_BANK_0__MAX_VALUE			0x000c
 #define     MIN_MAX_BANK_0__MAX_VALUE			0x000c
 
 
 #define PERM_SRC_ID_1				0x870
 #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__DIRECT_ACCESS_ACTIVE		0x0800
 #define     PERM_SRC_ID_1__WRITE_ACTIVE			0x2000
 #define     PERM_SRC_ID_1__WRITE_ACTIVE			0x2000
 #define     PERM_SRC_ID_1__READ_ACTIVE			0x4000
 #define     PERM_SRC_ID_1__READ_ACTIVE			0x4000
@@ -519,7 +519,7 @@
 #define     MIN_MAX_BANK_1__MAX_VALUE			0x000c
 #define     MIN_MAX_BANK_1__MAX_VALUE			0x000c
 
 
 #define PERM_SRC_ID_2				0x8b0
 #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__DIRECT_ACCESS_ACTIVE		0x0800
 #define     PERM_SRC_ID_2__WRITE_ACTIVE			0x2000
 #define     PERM_SRC_ID_2__WRITE_ACTIVE			0x2000
 #define     PERM_SRC_ID_2__READ_ACTIVE			0x4000
 #define     PERM_SRC_ID_2__READ_ACTIVE			0x4000
@@ -536,7 +536,7 @@
 #define     MIN_MAX_BANK_2__MAX_VALUE			0x000c
 #define     MIN_MAX_BANK_2__MAX_VALUE			0x000c
 
 
 #define PERM_SRC_ID_3				0x8f0
 #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__DIRECT_ACCESS_ACTIVE		0x0800
 #define     PERM_SRC_ID_3__WRITE_ACTIVE			0x2000
 #define     PERM_SRC_ID_3__WRITE_ACTIVE			0x2000
 #define     PERM_SRC_ID_3__READ_ACTIVE			0x4000
 #define     PERM_SRC_ID_3__READ_ACTIVE			0x4000
@@ -553,7 +553,7 @@
 #define     MIN_MAX_BANK_3__MAX_VALUE			0x000c
 #define     MIN_MAX_BANK_3__MAX_VALUE			0x000c
 
 
 #define PERM_SRC_ID_4				0x930
 #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__DIRECT_ACCESS_ACTIVE		0x0800
 #define     PERM_SRC_ID_4__WRITE_ACTIVE			0x2000
 #define     PERM_SRC_ID_4__WRITE_ACTIVE			0x2000
 #define     PERM_SRC_ID_4__READ_ACTIVE			0x4000
 #define     PERM_SRC_ID_4__READ_ACTIVE			0x4000
@@ -570,7 +570,7 @@
 #define     MIN_MAX_BANK_4__MAX_VALUE			0x000c
 #define     MIN_MAX_BANK_4__MAX_VALUE			0x000c
 
 
 #define PERM_SRC_ID_5				0x970
 #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__DIRECT_ACCESS_ACTIVE		0x0800
 #define     PERM_SRC_ID_5__WRITE_ACTIVE			0x2000
 #define     PERM_SRC_ID_5__WRITE_ACTIVE			0x2000
 #define     PERM_SRC_ID_5__READ_ACTIVE			0x4000
 #define     PERM_SRC_ID_5__READ_ACTIVE			0x4000
@@ -587,7 +587,7 @@
 #define     MIN_MAX_BANK_5__MAX_VALUE			0x000c
 #define     MIN_MAX_BANK_5__MAX_VALUE			0x000c
 
 
 #define PERM_SRC_ID_6				0x9b0
 #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__DIRECT_ACCESS_ACTIVE		0x0800
 #define     PERM_SRC_ID_6__WRITE_ACTIVE			0x2000
 #define     PERM_SRC_ID_6__WRITE_ACTIVE			0x2000
 #define     PERM_SRC_ID_6__READ_ACTIVE			0x4000
 #define     PERM_SRC_ID_6__READ_ACTIVE			0x4000
@@ -604,7 +604,7 @@
 #define     MIN_MAX_BANK_6__MAX_VALUE			0x000c
 #define     MIN_MAX_BANK_6__MAX_VALUE			0x000c
 
 
 #define PERM_SRC_ID_7				0x9f0
 #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__DIRECT_ACCESS_ACTIVE		0x0800
 #define     PERM_SRC_ID_7__WRITE_ACTIVE			0x2000
 #define     PERM_SRC_ID_7__WRITE_ACTIVE			0x2000
 #define     PERM_SRC_ID_7__READ_ACTIVE			0x4000
 #define     PERM_SRC_ID_7__READ_ACTIVE			0x4000
@@ -620,47 +620,6 @@
 #define     MIN_MAX_BANK_7__MIN_VALUE			0x0003
 #define     MIN_MAX_BANK_7__MIN_VALUE			0x0003
 #define     MIN_MAX_BANK_7__MAX_VALUE			0x000c
 #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 */
 /* ffsdefs.h */
 #define CLEAR 0                 /*use this to clear a field instead of "fail"*/
 #define CLEAR 0                 /*use this to clear a field instead of "fail"*/
 #define SET   1                 /*use this to set a field instead of "pass"*/
 #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
 #define NAND_DBG_TRACE 3
 
 
 #ifdef VERBOSE
 #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
 #else
 #define nand_dbg_print(level, args...)
 #define nand_dbg_print(level, args...)
 #endif
 #endif
@@ -772,10 +731,9 @@ struct device_info_tag {
 #define ECC_SECTOR_SIZE     512
 #define ECC_SECTOR_SIZE     512
 #define LLD_MAX_FLASH_BANKS     4
 #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 head;
 	int tail;
 	int tail;
 	uint8_t buf[DENALI_BUF_SIZE];
 	uint8_t buf[DENALI_BUF_SIZE];
@@ -788,7 +746,6 @@ struct nand_buf
 struct denali_nand_info {
 struct denali_nand_info {
 	struct mtd_info mtd;
 	struct mtd_info mtd;
 	struct nand_chip nand;
 	struct nand_chip nand;
-	struct device_info_tag dev_info;
 	int flash_bank; /* currently selected chip */
 	int flash_bank; /* currently selected chip */
 	int status;
 	int status;
 	int platform;
 	int platform;
@@ -806,11 +763,12 @@ struct denali_nand_info {
 	uint32_t irq_status;
 	uint32_t irq_status;
 	int irq_debug_array[32];
 	int irq_debug_array[32];
 	int idx;
 	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_*/
 #endif /*_LLD_NAND_*/
-

+ 3 - 3
drivers/mtd/nand/diskonchip.c

@@ -29,7 +29,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/doc2000.h>
 #include <linux/mtd/doc2000.h>
-#include <linux/mtd/compatmac.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/inftl.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;
 	uint8_t parity;
 	uint16_t ds[4], s[5], tmp, errval[8], syn[4];
 	uint16_t ds[4], s[5], tmp, errval[8], syn[4];
 
 
+	memset(syn, 0, sizeof(syn));
 	/* Convert the ecc bytes into words */
 	/* Convert the ecc bytes into words */
 	ds[0] = ((ecc[4] & 0xff) >> 0) | ((ecc[5] & 0x03) << 8);
 	ds[0] = ((ecc[4] & 0xff) >> 0) | ((ecc[5] & 0x03) << 8);
 	ds[1] = ((ecc[5] & 0xfc) >> 2) | ((ecc[2] & 0x0f) << 6);
 	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)];
 			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++) {
 	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));
 			syn[i] = rs_modnn(rs, rs->index_of[s[i]] + (NN - FCR - i));
 	}
 	}
 	/* Call the decoder library */
 	/* Call the decoder library */

+ 425 - 175
drivers/mtd/nand/mxc_nand.c

@@ -39,60 +39,96 @@
 
 
 #define nfc_is_v21()		(cpu_is_mx25() || cpu_is_mx35())
 #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_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 */
 /* 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 mxc_nand_host {
 	struct mtd_info		mtd;
 	struct mtd_info		mtd;
@@ -102,20 +138,30 @@ struct mxc_nand_host {
 
 
 	void			*spare0;
 	void			*spare0;
 	void			*main_area0;
 	void			*main_area0;
-	void			*main_area1;
 
 
 	void __iomem		*base;
 	void __iomem		*base;
 	void __iomem		*regs;
 	void __iomem		*regs;
+	void __iomem		*regs_axi;
+	void __iomem		*regs_ip;
 	int			status_request;
 	int			status_request;
 	struct clk		*clk;
 	struct clk		*clk;
 	int			clk_act;
 	int			clk_act;
 	int			irq;
 	int			irq;
+	int			eccsize;
 
 
 	wait_queue_head_t	irq_waitq;
 	wait_queue_head_t	irq_waitq;
 
 
 	uint8_t			*data_buf;
 	uint8_t			*data_buf;
 	unsigned int		buf_start;
 	unsigned int		buf_start;
 	int			spare_len;
 	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 */
 /* 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;
 	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
 /* This function polls the NANDFC to wait for the basic operation to
  * complete by checking the INT bit of config2 register.
  * complete by checking the INT bit of config2 register.
  */
  */
 static void wait_op_done(struct mxc_nand_host *host, int useirq)
 static void wait_op_done(struct mxc_nand_host *host, int useirq)
 {
 {
-	uint16_t tmp;
 	int max_retries = 8000;
 	int max_retries = 8000;
 
 
 	if (useirq) {
 	if (useirq) {
-		if ((readw(host->regs + NFC_CONFIG2) & NFC_INT) == 0) {
+		if (!host->check_int(host)) {
 
 
 			enable_irq(host->irq);
 			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 {
 	} else {
 		while (max_retries-- > 0) {
 		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;
 				break;
-			}
+
 			udelay(1);
 			udelay(1);
 		}
 		}
 		if (max_retries < 0)
 		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
 /* This function issues the specified command to the NAND device and
  * waits for completion. */
  * 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);
 	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)) {
 	if (cpu_is_mx21() && (cmd == NAND_CMD_RESET)) {
 		int max_retries = 100;
 		int max_retries = 100;
 		/* Reset completion is indicated by NFC_CONFIG2 */
 		/* Reset completion is indicated by NFC_CONFIG2 */
 		/* being set to 0 */
 		/* being set to 0 */
 		while (max_retries-- > 0) {
 		while (max_retries-- > 0) {
-			if (readw(host->regs + NFC_CONFIG2) == 0) {
+			if (readw(NFC_V1_V2_CONFIG2) == 0) {
 				break;
 				break;
 			}
 			}
 			udelay(1);
 			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
 /* This function sends an address (or partial address) to the
  * NAND device. The address is used to select the source/destination for
  * NAND device. The address is used to select the source/destination for
  * a NAND command. */
  * 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);
 	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 for operation to complete */
 	wait_op_done(host, islast);
 	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 nand_chip *nand_chip = mtd->priv;
 	struct mxc_nand_host *host = nand_chip->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++) {
 	for (i = 0; i < bufs; i++) {
 
 
 		/* NANDFC buffer 0 is used for page read/write */
 		/* 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 for operation to complete */
 		wait_op_done(host, true);
 		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. */
 /* 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;
 	struct nand_chip *this = &host->nand;
 
 
 	/* NANDFC buffer 0 is used for device ID output */
 	/* 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 for operation to complete */
 	wait_op_done(host, true);
 	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);
 	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
 /* This function requests the NANDFC to perform a read of the
  * NAND device status and returns the current status. */
  * 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;
 	uint32_t store;
 	uint16_t ret;
 	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);
 	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);
 	ret = readw(main_buf);
+
 	writel(store, main_buf);
 	writel(store, main_buf);
 
 
 	return ret;
 	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)
 				 u_char *read_ecc, u_char *calc_ecc)
 {
 {
 	struct nand_chip *nand_chip = mtd->priv;
 	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
 	 * additional correction.  2-Bit errors cannot be corrected by
 	 * HW ECC, so we need to return failure
 	 * 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)) {
 	if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
 		DEBUG(MTD_DEBUG_LEVEL0,
 		DEBUG(MTD_DEBUG_LEVEL0,
@@ -369,6 +489,43 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
 	return 0;
 	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,
 static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
 				  u_char *ecc_code)
 				  u_char *ecc_code)
 {
 {
@@ -383,7 +540,7 @@ static u_char mxc_nand_read_byte(struct mtd_info *mtd)
 
 
 	/* Check for status request */
 	/* Check for status request */
 	if (host->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);
 	ret = *(uint8_t *)(host->data_buf + host->buf_start);
 	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
 		 * we will used the saved column address to index into
 		 * the full page.
 		 * the full page.
 		 */
 		 */
-		send_addr(host, 0, page_addr == -1);
+		host->send_addr(host, 0, page_addr == -1);
 		if (mtd->writesize > 512)
 		if (mtd->writesize > 512)
 			/* another col addr cycle for 2k page */
 			/* another col addr cycle for 2k page */
-			send_addr(host, 0, false);
+			host->send_addr(host, 0, false);
 	}
 	}
 
 
 	/* Write out page address, if necessary */
 	/* Write out page address, if necessary */
 	if (page_addr != -1) {
 	if (page_addr != -1) {
 		/* paddr_0 - p_addr_7 */
 		/* 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->writesize > 512) {
 			if (mtd->size >= 0x10000000) {
 			if (mtd->size >= 0x10000000) {
 				/* paddr_8 - paddr_15 */
 				/* 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
 			} else
 				/* paddr_8 - paddr_15 */
 				/* paddr_8 - paddr_15 */
-				send_addr(host, (page_addr >> 8) & 0xff, true);
+				host->send_addr(host, (page_addr >> 8) & 0xff, true);
 		} else {
 		} else {
 			/* One more address cycle for higher density devices */
 			/* One more address cycle for higher density devices */
 			if (mtd->size >= 0x4000000) {
 			if (mtd->size >= 0x4000000) {
 				/* paddr_8 - paddr_15 */
 				/* 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
 			} else
 				/* paddr_8 - paddr_15 */
 				/* 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 nand_chip *nand_chip = mtd->priv;
 	struct mxc_nand_host *host = nand_chip->priv;
 	struct mxc_nand_host *host = nand_chip->priv;
 	uint16_t tmp;
 	uint16_t tmp;
 
 
 	/* enable interrupt, disable spare enable */
 	/* 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) {
 	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 {
 	} else {
-		tmp &= ~NFC_ECC_EN;
+		host->eccsize = 1;
 	}
 	}
-	writew(tmp, host->regs + NFC_CONFIG1);
+
+	writew(tmp, NFC_V1_V2_CONFIG1);
 	/* preset operation */
 	/* preset operation */
 
 
 	/* Unlock the internal RAM Buffer */
 	/* Unlock the internal RAM Buffer */
-	writew(0x2, host->regs + NFC_CONFIG);
+	writew(0x2, NFC_V1_V2_CONFIG);
 
 
 	/* Blocks to be unlocked */
 	/* Blocks to be unlocked */
 	if (nfc_is_v21()) {
 	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()) {
 	} 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
 	} else
 		BUG();
 		BUG();
 
 
 	/* Unlock Block Command for given address range */
 	/* 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
 /* 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 */
 	/* Command pre-processing step */
 	switch (command) {
 	switch (command) {
 	case NAND_CMD_RESET:
 	case NAND_CMD_RESET:
-		send_cmd(host, command, false);
-		preset(mtd);
+		host->preset(mtd);
+		host->send_cmd(host, command, false);
 		break;
 		break;
 
 
 	case NAND_CMD_STATUS:
 	case NAND_CMD_STATUS:
 		host->buf_start = 0;
 		host->buf_start = 0;
 		host->status_request = true;
 		host->status_request = true;
 
 
-		send_cmd(host, command, true);
+		host->send_cmd(host, command, true);
 		mxc_do_addr_cycle(mtd, column, page_addr);
 		mxc_do_addr_cycle(mtd, column, page_addr);
 		break;
 		break;
 
 
@@ -625,13 +874,13 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
 
 
 		command = NAND_CMD_READ0; /* only READ0 is valid */
 		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);
 		mxc_do_addr_cycle(mtd, column, page_addr);
 
 
 		if (mtd->writesize > 512)
 		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);
 		memcpy(host->data_buf, host->main_area0, mtd->writesize);
 		copy_spare(mtd, true);
 		copy_spare(mtd, true);
@@ -644,28 +893,28 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
 
 
 		host->buf_start = column;
 		host->buf_start = column;
 
 
-		send_cmd(host, command, false);
+		host->send_cmd(host, command, false);
 		mxc_do_addr_cycle(mtd, column, page_addr);
 		mxc_do_addr_cycle(mtd, column, page_addr);
 		break;
 		break;
 
 
 	case NAND_CMD_PAGEPROG:
 	case NAND_CMD_PAGEPROG:
 		memcpy(host->main_area0, host->data_buf, mtd->writesize);
 		memcpy(host->main_area0, host->data_buf, mtd->writesize);
 		copy_spare(mtd, false);
 		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);
 		mxc_do_addr_cycle(mtd, column, page_addr);
 		break;
 		break;
 
 
 	case NAND_CMD_READID:
 	case NAND_CMD_READID:
-		send_cmd(host, command, true);
+		host->send_cmd(host, command, true);
 		mxc_do_addr_cycle(mtd, column, page_addr);
 		mxc_do_addr_cycle(mtd, column, page_addr);
-		send_read_id(host);
+		host->send_read_id(host);
 		host->buf_start = column;
 		host->buf_start = column;
 		break;
 		break;
 
 
 	case NAND_CMD_ERASE1:
 	case NAND_CMD_ERASE1:
 	case NAND_CMD_ERASE2:
 	case NAND_CMD_ERASE2:
-		send_cmd(host, command, false);
+		host->send_cmd(host, command, false);
 		mxc_do_addr_cycle(mtd, column, page_addr);
 		mxc_do_addr_cycle(mtd, column, page_addr);
 
 
 		break;
 		break;
@@ -761,22 +1010,55 @@ static int __init mxcnd_probe(struct platform_device *pdev)
 	}
 	}
 
 
 	host->main_area0 = host->base;
 	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()) {
 	if (nfc_is_v21()) {
-		host->regs = host->base + 0x1000;
+		host->regs = host->base + 0x1e00;
 		host->spare0 = host->base + 0x1000;
 		host->spare0 = host->base + 0x1000;
 		host->spare_len = 64;
 		host->spare_len = 64;
 		oob_smallpage = &nandv2_hw_eccoob_smallpage;
 		oob_smallpage = &nandv2_hw_eccoob_smallpage;
 		oob_largepage = &nandv2_hw_eccoob_largepage;
 		oob_largepage = &nandv2_hw_eccoob_largepage;
 		this->ecc.bytes = 9;
 		this->ecc.bytes = 9;
 	} else if (nfc_is_v1()) {
 	} else if (nfc_is_v1()) {
-		host->regs = host->base;
+		host->regs = host->base + 0xe00;
 		host->spare0 = host->base + 0x800;
 		host->spare0 = host->base + 0x800;
 		host->spare_len = 16;
 		host->spare_len = 16;
 		oob_smallpage = &nandv1_hw_eccoob_smallpage;
 		oob_smallpage = &nandv1_hw_eccoob_smallpage;
 		oob_largepage = &nandv1_hw_eccoob_largepage;
 		oob_largepage = &nandv1_hw_eccoob_largepage;
 		this->ecc.bytes = 3;
 		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
 	} else
 		BUG();
 		BUG();
 
 
@@ -786,7 +1068,10 @@ static int __init mxcnd_probe(struct platform_device *pdev)
 	if (pdata->hw_ecc) {
 	if (pdata->hw_ecc) {
 		this->ecc.calculate = mxc_nand_calculate_ecc;
 		this->ecc.calculate = mxc_nand_calculate_ecc;
 		this->ecc.hwctl = mxc_nand_enable_hwecc;
 		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;
 		this->ecc.mode = NAND_ECC_HW;
 	} else {
 	} else {
 		this->ecc.mode = NAND_ECC_SOFT;
 		this->ecc.mode = NAND_ECC_SOFT;
@@ -817,6 +1102,9 @@ static int __init mxcnd_probe(struct platform_device *pdev)
 		goto escan;
 		goto escan;
 	}
 	}
 
 
+	/* Call preset again, with correct writesize this time */
+	host->preset(mtd);
+
 	if (mtd->writesize == 2048)
 	if (mtd->writesize == 2048)
 		this->ecc.layout = oob_largepage;
 		this->ecc.layout = oob_largepage;
 
 
@@ -848,6 +1136,8 @@ static int __init mxcnd_probe(struct platform_device *pdev)
 escan:
 escan:
 	free_irq(host->irq, host);
 	free_irq(host->irq, host);
 eirq:
 eirq:
+	if (host->regs_ip)
+		iounmap(host->regs_ip);
 	iounmap(host->base);
 	iounmap(host->base);
 eres:
 eres:
 	clk_put(host->clk);
 	clk_put(host->clk);
@@ -867,59 +1157,19 @@ static int __devexit mxcnd_remove(struct platform_device *pdev)
 
 
 	nand_release(&host->mtd);
 	nand_release(&host->mtd);
 	free_irq(host->irq, host);
 	free_irq(host->irq, host);
+	if (host->regs_ip)
+		iounmap(host->regs_ip);
 	iounmap(host->base);
 	iounmap(host->base);
 	kfree(host);
 	kfree(host);
 
 
 	return 0;
 	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 = {
 static struct platform_driver mxcnd_driver = {
 	.driver = {
 	.driver = {
 		   .name = DRIVER_NAME,
 		   .name = DRIVER_NAME,
-		   },
+	},
 	.remove = __devexit_p(mxcnd_remove),
 	.remove = __devexit_p(mxcnd_remove),
-	.suspend = mxcnd_suspend,
-	.resume = mxcnd_resume,
 };
 };
 
 
 static int __init mxc_nd_init(void)
 static int __init mxc_nd_init(void)

+ 61 - 18
drivers/mtd/nand/nand_base.c

@@ -42,7 +42,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/compatmac.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
 #include <linux/bitops.h>
 #include <linux/leds.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;
 	struct nand_chip *chip = mtd->priv;
 	u16 bad;
 	u16 bad;
 
 
-	if (chip->options & NAND_BB_LAST_PAGE)
+	if (chip->options & NAND_BBT_SCANLASTPAGE)
 		ofs += mtd->erasesize - mtd->writesize;
 		ofs += mtd->erasesize - mtd->writesize;
 
 
 	page = (int)(ofs >> chip->page_shift) & chip->pagemask;
 	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;
 	struct nand_chip *chip = mtd->priv;
 	uint8_t buf[2] = { 0, 0 };
 	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;
 		ofs += mtd->erasesize - mtd->writesize;
 
 
 	/* Get block number */
 	/* 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)
 	if (chip->options & NAND_USE_FLASH_BBT)
 		ret = nand_update_bbt(mtd, ofs);
 		ret = nand_update_bbt(mtd, ofs);
 	else {
 	else {
-		/* We write two bytes, so we dont have to mess with 16 bit
-		 * access
-		 */
 		nand_get_device(chip, mtd, FL_WRITING);
 		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);
 		nand_release_device(mtd);
 	}
 	}
 	if (!ret)
 	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;
 		chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 32 - 1;
 
 
 	/* Set the bad block position */
 	/* 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 */
 	/* Get chip options, preserve non chip based options */
 	chip->options &= ~NAND_CHIPOPTIONS_MSK;
 	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
 	 * 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) &&
 	if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
 			(*maf_id == NAND_MFR_SAMSUNG ||
 			(*maf_id == NAND_MFR_SAMSUNG ||
 			 *maf_id == NAND_MFR_HYNIX))
 			 *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 */
 	/* Check for AND chips with 4 page planes */
 	if (chip->options & NAND_4PAGE_ARRAY)
 	if (chip->options & NAND_4PAGE_ARRAY)
@@ -3306,6 +3344,11 @@ void nand_release(struct mtd_info *mtd)
 	kfree(chip->bbt);
 	kfree(chip->bbt);
 	if (!(chip->options & NAND_OWN_BUFFERS))
 	if (!(chip->options & NAND_OWN_BUFFERS))
 		kfree(chip->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);
 EXPORT_SYMBOL_GPL(nand_lock);

+ 75 - 28
drivers/mtd/nand/nand_bbt.c

@@ -55,7 +55,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/compatmac.h>
 #include <linux/bitops.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/vmalloc.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;
 			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) {
 	if (td->options & NAND_BBT_SCANEMPTY) {
 		p += td->len;
 		p += td->len;
 		end += 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])
 		if (p[td->offs + i] != td->pattern[i])
 			return -1;
 			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;
 	return 0;
 }
 }
 
 
@@ -397,12 +425,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
 
 
 	if (bd->options & NAND_BBT_SCANALLPAGES)
 	if (bd->options & NAND_BBT_SCANALLPAGES)
 		len = 1 << (this->bbt_erase_shift - this->page_shift);
 		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)) {
 	if (!(bd->options & NAND_BBT_SCANEMPTY)) {
 		/* We need only read few bytes from the OOB area */
 		/* 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);
 		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);
 		from += mtd->erasesize - (mtd->writesize * len);
 
 
 	for (i = startblock; i < numblocks;) {
 	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. */
  * while scanning a device for factory marked good / bad blocks. */
 static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
 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 = {
 static struct nand_bbt_descr smallpage_flashbased = {
 	.options = NAND_BBT_SCAN2NDPAGE,
 	.options = NAND_BBT_SCAN2NDPAGE,
-	.offs = 5,
+	.offs = NAND_SMALL_BADBLOCK_POS,
 	.len = 1,
 	.len = 1,
 	.pattern = scan_ff_pattern
 	.pattern = scan_ff_pattern
 };
 };
 
 
 static struct nand_bbt_descr largepage_flashbased = {
 static struct nand_bbt_descr largepage_flashbased = {
 	.options = NAND_BBT_SCAN2NDPAGE,
 	.options = NAND_BBT_SCAN2NDPAGE,
-	.offs = 0,
+	.offs = NAND_LARGE_BADBLOCK_POS,
 	.len = 2,
 	.len = 2,
 	.pattern = scan_ff_pattern
 	.pattern = scan_ff_pattern
 };
 };
@@ -1154,6 +1166,43 @@ static struct nand_bbt_descr bbt_mirror_descr = {
 	.pattern = mirror_pattern
 	.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
  * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
  * @mtd:	MTD device structure
  * @mtd:	MTD device structure
@@ -1196,10 +1245,8 @@ int nand_default_bbt(struct mtd_info *mtd)
 	} else {
 	} else {
 		this->bbt_td = NULL;
 		this->bbt_td = NULL;
 		this->bbt_md = 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);
 	return nand_scan_bbt(mtd, this->badblock_pattern);
 }
 }

+ 4 - 0
drivers/mtd/nand/nand_ids.c

@@ -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 3,3V 8-bit",	0xD1, 0, 128, 0, LP_OPTIONS},
 	{"NAND 128MiB 1,8V 16-bit",	0xB1, 0, 128, 0, LP_OPTIONS16},
 	{"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 3,3V 16-bit",	0xC1, 0, 128, 0, LP_OPTIONS16},
+	{"NAND 128MiB 1,8V 16-bit",     0xAD, 0, 128, 0, LP_OPTIONS16},
 
 
 	/* 2 Gigabit */
 	/* 2 Gigabit */
 	{"NAND 256MiB 1,8V 8-bit",	0xAA, 0, 256, 0, LP_OPTIONS},
 	{"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 1,8V 16-bit",	0xB5, 0, 2048, 0, LP_OPTIONS16},
 	{"NAND 2GiB 3,3V 16-bit",	0xC5, 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
 	 * Renesas AND 1 Gigabit. Those chips do not support extended id and
 	 * have a strange page/block layout !  The chosen minimum erasesize is
 	 * have a strange page/block layout !  The chosen minimum erasesize is

+ 7 - 7
drivers/mtd/nand/nandsim.c

@@ -553,8 +553,8 @@ static uint64_t divide(uint64_t n, uint32_t d)
  */
  */
 static int init_nandsim(struct mtd_info *mtd)
 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;
 	int i, ret = 0;
 	uint64_t remains;
 	uint64_t remains;
 	uint64_t next_offset;
 	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)
 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;
 	u_char outb = 0x00;
 
 
 	/* Sanity and correctness checks */
 	/* 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)
 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 */
 	/* Sanity and correctness checks */
 	if (!ns->lines.ce) {
 	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)
 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 */
 	/* Check that chip is expecting data input */
 	if (!(ns->state & STATE_DATAIN_MASK)) {
 	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)
 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 */
 	/* Sanity and correctness checks */
 	if (!ns->lines.ce) {
 	if (!ns->lines.ce) {
@@ -2352,7 +2352,7 @@ module_init(ns_init_module);
  */
  */
 static void __exit ns_cleanup_module(void)
 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;
 	int i;
 
 
 	free_nandsim(ns);    /* Free nandsim private resources */
 	free_nandsim(ns);    /* Free nandsim private resources */

+ 1 - 1
drivers/mtd/nand/plat_nand.c

@@ -91,7 +91,7 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
 	}
 	}
 
 
 	/* Scan to find existance of the device */
 	/* Scan to find existance of the device */
-	if (nand_scan(&data->mtd, 1)) {
+	if (nand_scan(&data->mtd, pdata->chip.nr_chips)) {
 		err = -ENXIO;
 		err = -ENXIO;
 		goto out;
 		goto out;
 	}
 	}

+ 3 - 3
drivers/mtd/nand/r852.c

@@ -64,8 +64,8 @@ static inline void r852_write_reg_dword(struct r852_device *dev,
 /* returns pointer to our private structure */
 /* returns pointer to our private structure */
 static inline struct r852_device *r852_get_dev(struct mtd_info *mtd)
 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)
 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;
 	unsigned long timeout;
 	int status;
 	int status;

+ 0 - 1
drivers/mtd/nand/rtc_from4.c

@@ -24,7 +24,6 @@
 #include <linux/rslib.h>
 #include <linux/rslib.h>
 #include <linux/bitrev.h>
 #include <linux/bitrev.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/mtd/compatmac.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/partitions.h>

+ 6 - 9
drivers/mtd/nand/s3c2410.c

@@ -727,15 +727,12 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
 	if (set == NULL)
 	if (set == NULL)
 		return add_mtd_device(&mtd->mtd);
 		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)
 	if (nr_part > 0 && part_info)

+ 1 - 1
drivers/mtd/nand/sm_common.c

@@ -109,7 +109,7 @@ static struct nand_flash_dev nand_xd_flash_ids[] = {
 
 
 int sm_register_device(struct mtd_info *mtd, int smartmedia)
 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;
 	int ret;
 
 
 	chip->options |= NAND_SKIP_BBTSCAN;
 	chip->options |= NAND_SKIP_BBTSCAN;

+ 18 - 7
drivers/mtd/nftlcore.c

@@ -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
 #define PRERELEASE

+ 2 - 1
drivers/mtd/nftlmount.c

@@ -2,7 +2,8 @@
  * NFTL mount code with extensive checks
  * NFTL mount code with extensive checks
  *
  *
  * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
  * 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
  * 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
  * it under the terms of the GNU General Public License as published by

+ 2 - 2
drivers/mtd/ofpart.c

@@ -1,11 +1,11 @@
 /*
 /*
  * Flash partitions described by the OF (or flattened) device tree
  * 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>
  * Author: Vitaly Wool <vwool@ru.mvista.com>
  *
  *
  * Revised to handle newer style flash binding by:
  * 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
  * 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
  * under  the terms of  the GNU General  Public License as published by the

+ 2 - 2
drivers/mtd/onenand/Kconfig

@@ -25,14 +25,14 @@ config MTD_ONENAND_GENERIC
 
 
 config MTD_ONENAND_OMAP2
 config MTD_ONENAND_OMAP2
 	tristate "OneNAND on OMAP2/OMAP3 support"
 	tristate "OneNAND on OMAP2/OMAP3 support"
-	depends on MTD_ONENAND && (ARCH_OMAP2 || ARCH_OMAP3)
+	depends on ARCH_OMAP2 || ARCH_OMAP3
 	help
 	help
 	  Support for a OneNAND flash device connected to an OMAP2/OMAP3 CPU
 	  Support for a OneNAND flash device connected to an OMAP2/OMAP3 CPU
 	  via the GPMC memory controller.
 	  via the GPMC memory controller.
 
 
 config MTD_ONENAND_SAMSUNG
 config MTD_ONENAND_SAMSUNG
         tristate "OneNAND on Samsung SOC controller support"
         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
         help
           Support for a OneNAND flash device connected to an Samsung SOC
           Support for a OneNAND flash device connected to an Samsung SOC
           S3C64XX/S5PC1XX controller.
           S3C64XX/S5PC1XX controller.

+ 35 - 14
drivers/mtd/onenand/onenand_base.c

@@ -377,8 +377,11 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
 
 
 	default:
 	default:
 		block = onenand_block(this, addr);
 		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)) {
 		if (ONENAND_IS_2PLANE(this)) {
 			/* Make the even block number */
 			/* Make the even block number */
 			block &= ~1;
 			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
  * @param mtd		MTD device structure
  *
  *
  * OneNAND detection method:
  * OneNAND detection method:
  *   Compare the values from command with ones from register
  *   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;
 	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;
 	int syscfg;
 
 
 	/* Save system configuration 1 */
 	/* Save system configuration 1 */
@@ -3763,12 +3765,6 @@ static int onenand_probe(struct mtd_info *mtd)
 	/* Restore system configuration 1 */
 	/* Restore system configuration 1 */
 	this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
 	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 */
 	/* Check manufacturer ID */
 	if (onenand_check_maf(bram_maf_id))
 	if (onenand_check_maf(bram_maf_id))
 		return -ENXIO;
 		return -ENXIO;
@@ -3776,13 +3772,35 @@ static int onenand_probe(struct mtd_info *mtd)
 	/* Read manufacturer and device IDs from Register */
 	/* Read manufacturer and device IDs from Register */
 	maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
 	maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
 	dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_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 */
 	/* Check OneNAND device */
 	if (maf_id != bram_maf_id || dev_id != bram_dev_id)
 	if (maf_id != bram_maf_id || dev_id != bram_dev_id)
 		return -ENXIO;
 		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 */
 	/* Flash device information */
 	onenand_print_device_info(dev_id, ver_id);
 	onenand_print_device_info(dev_id, ver_id);
 	this->device_id = dev_id;
 	this->device_id = dev_id;
@@ -3909,6 +3927,9 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
 	if (!this->unlock_all)
 	if (!this->unlock_all)
 		this->unlock_all = onenand_unlock_all;
 		this->unlock_all = onenand_unlock_all;
 
 
+	if (!this->chip_probe)
+		this->chip_probe = onenand_chip_probe;
+
 	if (!this->read_bufferram)
 	if (!this->read_bufferram)
 		this->read_bufferram = onenand_read_bufferram;
 		this->read_bufferram = onenand_read_bufferram;
 	if (!this->write_bufferram)
 	if (!this->write_bufferram)

+ 0 - 1
drivers/mtd/onenand/onenand_bbt.c

@@ -15,7 +15,6 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/onenand.h>
 #include <linux/mtd/onenand.h>
-#include <linux/mtd/compatmac.h>
 
 
 /**
 /**
  * check_short_pattern - [GENERIC] check if a pattern is in the buffer
  * check_short_pattern - [GENERIC] check if a pattern is in the buffer

+ 8 - 13
drivers/mtd/onenand/samsung.c

@@ -630,6 +630,12 @@ normal:
 	return 0;
 	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)
 static int s3c_onenand_bbt_wait(struct mtd_info *mtd, int state)
 {
 {
 	unsigned int flags = INT_ACT | LOAD_CMP;
 	unsigned int flags = INT_ACT | LOAD_CMP;
@@ -757,6 +763,7 @@ static void s3c_onenand_setup(struct mtd_info *mtd)
 		/* Use generic onenand functions */
 		/* Use generic onenand functions */
 		onenand->cmd_map = s5pc1xx_cmd_map;
 		onenand->cmd_map = s5pc1xx_cmd_map;
 		this->read_bufferram = s5pc110_read_bufferram;
 		this->read_bufferram = s5pc110_read_bufferram;
+		this->chip_probe = s5pc110_chip_probe;
 		return;
 		return;
 	} else {
 	} else {
 		BUG();
 		BUG();
@@ -781,7 +788,6 @@ static int s3c_onenand_probe(struct platform_device *pdev)
 	struct mtd_info *mtd;
 	struct mtd_info *mtd;
 	struct resource *r;
 	struct resource *r;
 	int size, err;
 	int size, err;
-	unsigned long onenand_ctrl_cfg = 0;
 
 
 	pdata = pdev->dev.platform_data;
 	pdata = pdev->dev.platform_data;
 	/* No need to check pdata. the platform data is optional */
 	/* 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->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)) {
 	if (onenand_scan(mtd, 1)) {
@@ -915,10 +913,7 @@ static int s3c_onenand_probe(struct platform_device *pdev)
 		goto scan_failed;
 		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 */
 		/* S3C doesn't handle subpage write */
 		mtd->subpage_sft = 0;
 		mtd->subpage_sft = 0;
 		this->subpagesize = mtd->writesize;
 		this->subpagesize = mtd->writesize;

+ 18 - 0
drivers/mtd/redboot.c

@@ -1,6 +1,24 @@
 /*
 /*
  * Parse RedBoot-style Flash Image System (FIS) tables and
  * Parse RedBoot-style Flash Image System (FIS) tables and
  * produce a Linux partition array to match.
  * 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>
 #include <linux/kernel.h>

+ 1 - 1
drivers/mtd/rfd_ftl.c

@@ -1,7 +1,7 @@
 /*
 /*
  * rfd_ftl.c -- resident flash disk (flash translation layer)
  * 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
  * 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:
  * by General Software. It is known as the Resident Flash Disk (RFD), see:

+ 1 - 1
drivers/mtd/ssfdc.c

@@ -1,6 +1,6 @@
 /*
 /*
  * Linux driver for SSFDC Flash Translation Layer (Read only)
  * Linux driver for SSFDC Flash Translation Layer (Read only)
- * (c) 2005 Eptar srl
+ * © 2005 Eptar srl
  * Author: Claudio Lanconelli <lanconelli.claudio@eptar.com>
  * Author: Claudio Lanconelli <lanconelli.claudio@eptar.com>
  *
  *
  * Based on NTFL and MTDBLOCK_RO drivers
  * Based on NTFL and MTDBLOCK_RO drivers

+ 4 - 5
drivers/mtd/tests/mtd_pagetest.c

@@ -310,7 +310,7 @@ static int crosstest(void)
 static int erasecrosstest(void)
 static int erasecrosstest(void)
 {
 {
 	size_t read = 0, written = 0;
 	size_t read = 0, written = 0;
-	int err = 0, i, ebnum, ok = 1, ebnum2;
+	int err = 0, i, ebnum, ebnum2;
 	loff_t addr0;
 	loff_t addr0;
 	char *readbuf = twopages;
 	char *readbuf = twopages;
 
 
@@ -357,8 +357,7 @@ static int erasecrosstest(void)
 	if (memcmp(writebuf, readbuf, pgsize)) {
 	if (memcmp(writebuf, readbuf, pgsize)) {
 		printk(PRINT_PREF "verify failed!\n");
 		printk(PRINT_PREF "verify failed!\n");
 		errcnt += 1;
 		errcnt += 1;
-		ok = 0;
-		return err;
+		return -1;
 	}
 	}
 
 
 	printk(PRINT_PREF "erasing block %d\n", ebnum);
 	printk(PRINT_PREF "erasing block %d\n", ebnum);
@@ -396,10 +395,10 @@ static int erasecrosstest(void)
 	if (memcmp(writebuf, readbuf, pgsize)) {
 	if (memcmp(writebuf, readbuf, pgsize)) {
 		printk(PRINT_PREF "verify failed!\n");
 		printk(PRINT_PREF "verify failed!\n");
 		errcnt += 1;
 		errcnt += 1;
-		ok = 0;
+		return -1;
 	}
 	}
 
 
-	if (ok && !err)
+	if (!err)
 		printk(PRINT_PREF "erasecrosstest ok\n");
 		printk(PRINT_PREF "erasecrosstest ok\n");
 	return err;
 	return err;
 }
 }

+ 1 - 0
fs/jffs2/background.c

@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc.
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
  *

+ 1 - 0
fs/jffs2/build.c

@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc.
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
  *

+ 3 - 2
fs/jffs2/compr.c

@@ -2,11 +2,12 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc.
  * 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>,
  * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>,
  *		    University of Szeged, Hungary
  *		    University of Szeged, Hungary
  *
  *
+ * Created by Arjan van de Ven <arjan@infradead.org>
+ *
  * For licensing information, see the file 'LICENCE' in this directory.
  * For licensing information, see the file 'LICENCE' in this directory.
  *
  *
  */
  */

+ 1 - 0
fs/jffs2/compr.h

@@ -3,6 +3,7 @@
  *
  *
  * Copyright © 2004   Ferenc Havasi <havasi@inf.u-szeged.hu>,
  * Copyright © 2004   Ferenc Havasi <havasi@inf.u-szeged.hu>,
  *		      University of Szeged, Hungary
  *		      University of Szeged, Hungary
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  * For licensing information, see the file 'LICENCE' in this directory.
  *
  *

+ 1 - 0
fs/jffs2/compr_lzo.c

@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2007 Nokia Corporation. All rights reserved.
  * Copyright © 2007 Nokia Corporation. All rights reserved.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * Created by Richard Purdie <rpurdie@openedhand.com>
  * Created by Richard Purdie <rpurdie@openedhand.com>
  *
  *

+ 1 - 0
fs/jffs2/compr_rtime.c

@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc.
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * Created by Arjan van de Ven <arjanv@redhat.com>
  * Created by Arjan van de Ven <arjanv@redhat.com>
  *
  *

+ 1 - 0
fs/jffs2/compr_rubin.c

@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc.
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * Created by Arjan van de Ven <arjanv@redhat.com>
  * Created by Arjan van de Ven <arjanv@redhat.com>
  *
  *

+ 1 - 0
fs/jffs2/compr_zlib.c

@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc.
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
  *

+ 1 - 0
fs/jffs2/debug.c

@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc.
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
  *

+ 1 - 0
fs/jffs2/debug.h

@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc.
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
  *

+ 1 - 0
fs/jffs2/dir.c

@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc.
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
  *

+ 1 - 0
fs/jffs2/erase.c

@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc.
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
  *

+ 1 - 0
fs/jffs2/file.c

@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc.
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
  *

+ 1 - 0
fs/jffs2/fs.c

@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc.
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
  *

+ 1 - 0
fs/jffs2/gc.c

@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc.
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
  *

+ 1 - 0
fs/jffs2/ioctl.c

@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc.
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
  *

+ 1 - 0
fs/jffs2/jffs2_fs_i.h

@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc.
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
  *

+ 1 - 0
fs/jffs2/jffs2_fs_sb.h

@@ -2,6 +2,7 @@
  * JFFS2 -- Journalling Flash File System, Version 2.
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
  *
  * Copyright © 2001-2007 Red Hat, Inc.
  * Copyright © 2001-2007 Red Hat, Inc.
+ * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
  *
  *
  * Created by David Woodhouse <dwmw2@infradead.org>
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
  *

+ 0 - 1
fs/jffs2/nodelist.h

@@ -24,7 +24,6 @@
 #ifdef __ECOS
 #ifdef __ECOS
 #include "os-ecos.h"
 #include "os-ecos.h"
 #else
 #else
-#include <linux/mtd/compatmac.h> /* For compatibility with older kernels */
 #include "os-linux.h"
 #include "os-linux.h"
 #endif
 #endif
 
 

+ 2 - 1
include/linux/jffs2.h

@@ -1,7 +1,8 @@
 /*
 /*
  * JFFS2 -- Journalling Flash File System, Version 2.
  * 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>
  * Created by David Woodhouse <dwmw2@infradead.org>
  *
  *

+ 22 - 2
include/linux/mtd/bbm.h

@@ -4,12 +4,26 @@
  *  NAND family Bad Block Management (BBM) header file
  *  NAND family Bad Block Management (BBM) header file
  *    - Bad Block Table (BBT) implementation
  *    - Bad Block Table (BBT) implementation
  *
  *
- *  Copyright (c) 2005 Samsung Electronics
+ *  Copyright © 2005 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *
  *
- *  Copyright (c) 2000-2005
+ *  Copyright © 2000-2005
  *  Thomas Gleixner <tglx@linuxtronix.de>
  *  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
 #ifndef __LINUX_MTD_BBM_H
 #define __LINUX_MTD_BBM_H
 #define __LINUX_MTD_BBM_H
@@ -82,6 +96,12 @@ struct nand_bbt_descr {
 #define NAND_BBT_SAVECONTENT	0x00002000
 #define NAND_BBT_SAVECONTENT	0x00002000
 /* Search good / bad pattern on the first and the second page */
 /* Search good / bad pattern on the first and the second page */
 #define NAND_BBT_SCAN2NDPAGE	0x00004000
 #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 */
 /* The maximum number of blocks to scan for a bbt */
 #define NAND_BBT_SCAN_MAXBLOCKS	4
 #define NAND_BBT_SCAN_MAXBLOCKS	4

+ 14 - 2
include/linux/mtd/blktrans.h

@@ -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
  *
  *
  */
  */
 
 

+ 17 - 3
include/linux/mtd/cfi.h

@@ -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__
 #ifndef __MTD_CFI_H__

+ 19 - 0
include/linux/mtd/cfi_endian.h

@@ -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>
 #include <asm/byteorder.h>
 
 
 #ifndef CONFIG_MTD_CFI_ADV_OPTIONS
 #ifndef CONFIG_MTD_CFI_ADV_OPTIONS

+ 0 - 10
include/linux/mtd/compatmac.h

@@ -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__ */

+ 15 - 2
include/linux/mtd/concat.h

@@ -1,9 +1,22 @@
 /*
 /*
  * MTD device concatenation layer definitions
  * 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
 #ifndef MTD_CONCAT_H

+ 18 - 5
include/linux/mtd/doc2000.h

@@ -1,12 +1,25 @@
 /*
 /*
  * Linux driver for Disk-On-Chip devices
  * 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__
 #ifndef __MTD_DOC2000_H__

+ 16 - 5
include/linux/mtd/flashchip.h

@@ -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__
 #ifndef __MTD_FLASHCHIP_H__
@@ -92,7 +103,7 @@ struct flchip {
 /* This is used to handle contention on write/erase operations
 /* This is used to handle contention on write/erase operations
    between partitions of the same physical chip. */
    between partitions of the same physical chip. */
 struct flchip_shared {
 struct flchip_shared {
-	spinlock_t lock;
+	struct mutex lock;
 	struct flchip *writing;
 	struct flchip *writing;
 	struct flchip *erasing;
 	struct flchip *erasing;
 };
 };

+ 17 - 2
include/linux/mtd/gen_probe.h

@@ -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__
 #ifndef __LINUX_MTD_GEN_PROBE_H__

+ 18 - 1
include/linux/mtd/map.h

@@ -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 */
 /* Overhauled routines for dealing with different mmap regions of flash */
 
 
@@ -9,7 +27,6 @@
 #include <linux/string.h>
 #include <linux/string.h>
 #include <linux/bug.h>
 #include <linux/bug.h>
 
 
-#include <linux/mtd/compatmac.h>
 
 
 #include <asm/unaligned.h>
 #include <asm/unaligned.h>
 #include <asm/system.h>
 #include <asm/system.h>

+ 16 - 3
include/linux/mtd/mtd.h

@@ -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__
 #ifndef __MTD_MTD_H__
@@ -13,7 +26,6 @@
 #include <linux/notifier.h>
 #include <linux/notifier.h>
 #include <linux/device.h>
 #include <linux/device.h>
 
 
-#include <linux/mtd/compatmac.h>
 #include <mtd/mtd-abi.h>
 #include <mtd/mtd-abi.h>
 
 
 #include <asm/div64.h>
 #include <asm/div64.h>
@@ -216,6 +228,7 @@ struct mtd_info {
 	/* Chip-supported device locking */
 	/* Chip-supported device locking */
 	int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
 	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 (*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 */
 	/* Power Management functions */
 	int (*suspend) (struct mtd_info *mtd);
 	int (*suspend) (struct mtd_info *mtd);

+ 3 - 5
include/linux/mtd/nand.h

@@ -1,9 +1,9 @@
 /*
 /*
  *  linux/include/linux/mtd/nand.h
  *  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
  * 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
  * it under the terms of the GNU General Public License version 2 as
@@ -181,8 +181,6 @@ typedef enum {
 #define NAND_NO_READRDY		0x00000100
 #define NAND_NO_READRDY		0x00000100
 /* Chip does not allow subpage writes */
 /* Chip does not allow subpage writes */
 #define NAND_NO_SUBPAGE_WRITE	0x00000200
 #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 */
 /* Device is one of 'new' xD cards that expose fake nand command set */
 #define NAND_BROKEN_XD		0x00000400
 #define NAND_BROKEN_XD		0x00000400

+ 3 - 1
include/linux/mtd/nand_ecc.h

@@ -1,7 +1,9 @@
 /*
 /*
  *  drivers/mtd/nand_ecc.h
  *  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
  * 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
  * it under the terms of the GNU General Public License version 2 as

Some files were not shown because too many files changed in this diff