aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-class-mtd125
-rw-r--r--Documentation/kernel-parameters.txt10
-rw-r--r--MAINTAINERS1
-rw-r--r--arch/arm/mach-davinci/include/mach/nand.h8
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c26
-rw-r--r--drivers/mtd/chips/jedec_probe.c13
-rw-r--r--drivers/mtd/devices/m25p80.c4
-rw-r--r--drivers/mtd/maps/Kconfig13
-rw-r--r--drivers/mtd/maps/Makefile1
-rw-r--r--drivers/mtd/maps/bfin-async-flash.c5
-rw-r--r--drivers/mtd/maps/integrator-flash.c226
-rw-r--r--drivers/mtd/maps/physmap.c40
-rw-r--r--drivers/mtd/maps/physmap_of.c199
-rw-r--r--drivers/mtd/maps/pmcmsp-ramroot.c104
-rw-r--r--drivers/mtd/maps/pxa2xx-flash.c22
-rw-r--r--drivers/mtd/maps/rbtx4939-flash.c23
-rw-r--r--drivers/mtd/maps/sa1100-flash.c23
-rw-r--r--drivers/mtd/maps/uclinux.c16
-rw-r--r--drivers/mtd/mtd_blkdevs.c2
-rw-r--r--drivers/mtd/mtdchar.c303
-rw-r--r--drivers/mtd/mtdcore.c47
-rw-r--r--drivers/mtd/mtdpart.c20
-rw-r--r--drivers/mtd/nand/Kconfig6
-rw-r--r--drivers/mtd/nand/Makefile1
-rw-r--r--drivers/mtd/nand/atmel_nand.c11
-rw-r--r--drivers/mtd/nand/bf5xx_nand.c17
-rw-r--r--drivers/mtd/nand/davinci_nand.c342
-rw-r--r--drivers/mtd/nand/mxc_nand.c66
-rw-r--r--drivers/mtd/nand/nand_base.c3
-rw-r--r--drivers/mtd/nand/nand_ecc.c4
-rw-r--r--drivers/mtd/nand/omap2.c776
-rw-r--r--drivers/mtd/nand/plat_nand.c19
-rw-r--r--drivers/mtd/nand/s3c2410.c6
-rw-r--r--drivers/mtd/nand/txx9ndfmc.c16
-rw-r--r--drivers/mtd/onenand/omap2.c4
-rw-r--r--drivers/mtd/onenand/onenand_base.c872
-rw-r--r--drivers/mtd/onenand/onenand_bbt.c14
-rw-r--r--drivers/mtd/onenand/onenand_sim.c81
-rw-r--r--fs/compat_ioctl.c52
-rw-r--r--include/linux/mtd/nand.h16
-rw-r--r--include/linux/mtd/onenand.h24
-rw-r--r--include/linux/mtd/onenand_regs.h20
-rw-r--r--include/linux/mtd/partitions.h1
-rw-r--r--include/mtd/Kbuild1
-rw-r--r--include/mtd/jffs2-user.h34
-rw-r--r--include/mtd/mtd-abi.h15
46 files changed, 2912 insertions, 720 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-mtd b/Documentation/ABI/testing/sysfs-class-mtd
new file mode 100644
index 000000000000..4d55a1888981
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-mtd
@@ -0,0 +1,125 @@
1What: /sys/class/mtd/
2Date: April 2009
3KernelVersion: 2.6.29
4Contact: linux-mtd@lists.infradead.org
5Description:
6 The mtd/ class subdirectory belongs to the MTD subsystem
7 (MTD core).
8
9What: /sys/class/mtd/mtdX/
10Date: April 2009
11KernelVersion: 2.6.29
12Contact: linux-mtd@lists.infradead.org
13Description:
14 The /sys/class/mtd/mtd{0,1,2,3,...} directories correspond
15 to each /dev/mtdX character device. These may represent
16 physical/simulated flash devices, partitions on a flash
17 device, or concatenated flash devices. They exist regardless
18 of whether CONFIG_MTD_CHAR is actually enabled.
19
20What: /sys/class/mtd/mtdXro/
21Date: April 2009
22KernelVersion: 2.6.29
23Contact: linux-mtd@lists.infradead.org
24Description:
25 These directories provide the corresponding read-only device
26 nodes for /sys/class/mtd/mtdX/ . They are only created
27 (for the benefit of udev) if CONFIG_MTD_CHAR is enabled.
28
29What: /sys/class/mtd/mtdX/dev
30Date: April 2009
31KernelVersion: 2.6.29
32Contact: linux-mtd@lists.infradead.org
33Description:
34 Major and minor numbers of the character device corresponding
35 to this MTD device (in <major>:<minor> format). This is the
36 read-write device so <minor> will be even.
37
38What: /sys/class/mtd/mtdXro/dev
39Date: April 2009
40KernelVersion: 2.6.29
41Contact: linux-mtd@lists.infradead.org
42Description:
43 Major and minor numbers of the character device corresponding
44 to the read-only variant of thie MTD device (in
45 <major>:<minor> format). In this case <minor> will be odd.
46
47What: /sys/class/mtd/mtdX/erasesize
48Date: April 2009
49KernelVersion: 2.6.29
50Contact: linux-mtd@lists.infradead.org
51Description:
52 "Major" erase size for the device. If numeraseregions is
53 zero, this is the eraseblock size for the entire device.
54 Otherwise, the MEMGETREGIONCOUNT/MEMGETREGIONINFO ioctls
55 can be used to determine the actual eraseblock layout.
56
57What: /sys/class/mtd/mtdX/flags
58Date: April 2009
59KernelVersion: 2.6.29
60Contact: linux-mtd@lists.infradead.org
61Description:
62 A hexadecimal value representing the device flags, ORed
63 together:
64
65 0x0400: MTD_WRITEABLE - device is writable
66 0x0800: MTD_BIT_WRITEABLE - single bits can be flipped
67 0x1000: MTD_NO_ERASE - no erase necessary
68 0x2000: MTD_POWERUP_LOCK - always locked after reset
69
70What: /sys/class/mtd/mtdX/name
71Date: April 2009
72KernelVersion: 2.6.29
73Contact: linux-mtd@lists.infradead.org
74Description:
75 A human-readable ASCII name for the device or partition.
76 This will match the name in /proc/mtd .
77
78What: /sys/class/mtd/mtdX/numeraseregions
79Date: April 2009
80KernelVersion: 2.6.29
81Contact: linux-mtd@lists.infradead.org
82Description:
83 For devices that have variable eraseblock sizes, this
84 provides the total number of erase regions. Otherwise,
85 it will read back as zero.
86
87What: /sys/class/mtd/mtdX/oobsize
88Date: April 2009
89KernelVersion: 2.6.29
90Contact: linux-mtd@lists.infradead.org
91Description:
92 Number of OOB bytes per page.
93
94What: /sys/class/mtd/mtdX/size
95Date: April 2009
96KernelVersion: 2.6.29
97Contact: linux-mtd@lists.infradead.org
98Description:
99 Total size of the device/partition, in bytes.
100
101What: /sys/class/mtd/mtdX/type
102Date: April 2009
103KernelVersion: 2.6.29
104Contact: linux-mtd@lists.infradead.org
105Description:
106 One of the following ASCII strings, representing the device
107 type:
108
109 absent, ram, rom, nor, nand, dataflash, ubi, unknown
110
111What: /sys/class/mtd/mtdX/writesize
112Date: April 2009
113KernelVersion: 2.6.29
114Contact: linux-mtd@lists.infradead.org
115Description:
116 Minimal writable flash unit size. This will always be
117 a positive integer.
118
119 In the case of NOR flash it is 1 (even though individual
120 bits can be cleared).
121
122 In the case of NAND flash it is one NAND page (or a
123 half page, or a quarter page).
124
125 In the case of ECC NOR, it is the ECC block size.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index fd5cac013037..ad2b3078e59c 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1380,6 +1380,16 @@ and is between 256 and 4096 characters. It is defined in the file
1380 mtdparts= [MTD] 1380 mtdparts= [MTD]
1381 See drivers/mtd/cmdlinepart.c. 1381 See drivers/mtd/cmdlinepart.c.
1382 1382
1383 onenand.bdry= [HW,MTD] Flex-OneNAND Boundary Configuration
1384
1385 Format: [die0_boundary][,die0_lock][,die1_boundary][,die1_lock]
1386
1387 boundary - index of last SLC block on Flex-OneNAND.
1388 The remaining blocks are configured as MLC blocks.
1389 lock - Configure if Flex-OneNAND boundary should be locked.
1390 Once locked, the boundary cannot be changed.
1391 1 indicates lock status, 0 indicates unlock status.
1392
1383 mtdset= [ARM] 1393 mtdset= [ARM]
1384 ARM/S3C2412 JIVE boot control 1394 ARM/S3C2412 JIVE boot control
1385 1395
diff --git a/MAINTAINERS b/MAINTAINERS
index 41c6605feb0a..51ebf7488b3a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3179,7 +3179,6 @@ W: http://www.linux-mtd.infradead.org/doc/jffs2.html
3179S: Maintained 3179S: Maintained
3180F: fs/jffs2/ 3180F: fs/jffs2/
3181F: include/linux/jffs2.h 3181F: include/linux/jffs2.h
3182F: include/mtd/jffs2-user.h
3183 3182
3184JOURNALLING LAYER FOR BLOCK DEVICES (JBD) 3183JOURNALLING LAYER FOR BLOCK DEVICES (JBD)
3185P: Stephen Tweedie 3184P: Stephen Tweedie
diff --git a/arch/arm/mach-davinci/include/mach/nand.h b/arch/arm/mach-davinci/include/mach/nand.h
index aa482841270b..b520c4b5678a 100644
--- a/arch/arm/mach-davinci/include/mach/nand.h
+++ b/arch/arm/mach-davinci/include/mach/nand.h
@@ -68,10 +68,14 @@ struct davinci_nand_pdata { /* platform_data */
68 68
69 /* none == NAND_ECC_NONE (strongly *not* advised!!) 69 /* none == NAND_ECC_NONE (strongly *not* advised!!)
70 * soft == NAND_ECC_SOFT 70 * soft == NAND_ECC_SOFT
71 * 1-bit == NAND_ECC_HW 71 * else == NAND_ECC_HW, according to ecc_bits
72 * 4-bit == NAND_ECC_HW_SYNDROME (not on all chips) 72 *
73 * All DaVinci-family chips support 1-bit hardware ECC.
74 * Newer ones also support 4-bit ECC, but are awkward
75 * using it with large page chips.
73 */ 76 */
74 nand_ecc_modes_t ecc_mode; 77 nand_ecc_modes_t ecc_mode;
78 u8 ecc_bits;
75 79
76 /* e.g. NAND_BUSWIDTH_16 or NAND_USE_FLASH_BBT */ 80 /* e.g. NAND_BUSWIDTH_16 or NAND_USE_FLASH_BBT */
77 unsigned options; 81 unsigned options;
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index c240454fd113..8664feebc93b 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -46,6 +46,7 @@
46#define MANUFACTURER_INTEL 0x0089 46#define MANUFACTURER_INTEL 0x0089
47#define I82802AB 0x00ad 47#define I82802AB 0x00ad
48#define I82802AC 0x00ac 48#define I82802AC 0x00ac
49#define PF38F4476 0x881c
49#define MANUFACTURER_ST 0x0020 50#define MANUFACTURER_ST 0x0020
50#define M50LPW080 0x002F 51#define M50LPW080 0x002F
51#define M50FLW080A 0x0080 52#define M50FLW080A 0x0080
@@ -315,10 +316,20 @@ static struct cfi_fixup fixup_table[] = {
315 { 0, 0, NULL, NULL } 316 { 0, 0, NULL, NULL }
316}; 317};
317 318
319static void cfi_fixup_major_minor(struct cfi_private *cfi,
320 struct cfi_pri_intelext *extp)
321{
322 if (cfi->mfr == MANUFACTURER_INTEL &&
323 cfi->id == PF38F4476 && extp->MinorVersion == '3')
324 extp->MinorVersion = '1';
325}
326
318static inline struct cfi_pri_intelext * 327static inline struct cfi_pri_intelext *
319read_pri_intelext(struct map_info *map, __u16 adr) 328read_pri_intelext(struct map_info *map, __u16 adr)
320{ 329{
330 struct cfi_private *cfi = map->fldrv_priv;
321 struct cfi_pri_intelext *extp; 331 struct cfi_pri_intelext *extp;
332 unsigned int extra_size = 0;
322 unsigned int extp_size = sizeof(*extp); 333 unsigned int extp_size = sizeof(*extp);
323 334
324 again: 335 again:
@@ -326,6 +337,8 @@ read_pri_intelext(struct map_info *map, __u16 adr)
326 if (!extp) 337 if (!extp)
327 return NULL; 338 return NULL;
328 339
340 cfi_fixup_major_minor(cfi, extp);
341
329 if (extp->MajorVersion != '1' || 342 if (extp->MajorVersion != '1' ||
330 (extp->MinorVersion < '0' || extp->MinorVersion > '5')) { 343 (extp->MinorVersion < '0' || extp->MinorVersion > '5')) {
331 printk(KERN_ERR " Unknown Intel/Sharp Extended Query " 344 printk(KERN_ERR " Unknown Intel/Sharp Extended Query "
@@ -340,19 +353,24 @@ read_pri_intelext(struct map_info *map, __u16 adr)
340 extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask); 353 extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask);
341 extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr); 354 extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr);
342 355
343 if (extp->MajorVersion == '1' && extp->MinorVersion >= '3') { 356 if (extp->MinorVersion >= '0') {
344 unsigned int extra_size = 0; 357 extra_size = 0;
345 int nb_parts, i;
346 358
347 /* Protection Register info */ 359 /* Protection Register info */
348 extra_size += (extp->NumProtectionFields - 1) * 360 extra_size += (extp->NumProtectionFields - 1) *
349 sizeof(struct cfi_intelext_otpinfo); 361 sizeof(struct cfi_intelext_otpinfo);
362 }
350 363
364 if (extp->MinorVersion >= '1') {
351 /* Burst Read info */ 365 /* Burst Read info */
352 extra_size += 2; 366 extra_size += 2;
353 if (extp_size < sizeof(*extp) + extra_size) 367 if (extp_size < sizeof(*extp) + extra_size)
354 goto need_more; 368 goto need_more;
355 extra_size += extp->extra[extra_size-1]; 369 extra_size += extp->extra[extra_size - 1];
370 }
371
372 if (extp->MinorVersion >= '3') {
373 int nb_parts, i;
356 374
357 /* Number of hardware-partitions */ 375 /* Number of hardware-partitions */
358 extra_size += 1; 376 extra_size += 1;
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index e824b9b9b056..ccc4cfc7e4b5 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -166,6 +166,7 @@
166#define SST39LF040 0x00D7 166#define SST39LF040 0x00D7
167#define SST39SF010A 0x00B5 167#define SST39SF010A 0x00B5
168#define SST39SF020A 0x00B6 168#define SST39SF020A 0x00B6
169#define SST39SF040 0x00B7
169#define SST49LF004B 0x0060 170#define SST49LF004B 0x0060
170#define SST49LF040B 0x0050 171#define SST49LF040B 0x0050
171#define SST49LF008A 0x005a 172#define SST49LF008A 0x005a
@@ -1393,6 +1394,18 @@ static const struct amd_flash_info jedec_table[] = {
1393 } 1394 }
1394 }, { 1395 }, {
1395 .mfr_id = MANUFACTURER_SST, 1396 .mfr_id = MANUFACTURER_SST,
1397 .dev_id = SST39SF040,
1398 .name = "SST 39SF040",
1399 .devtypes = CFI_DEVICETYPE_X8,
1400 .uaddr = MTD_UADDR_0x5555_0x2AAA,
1401 .dev_size = SIZE_512KiB,
1402 .cmd_set = P_ID_AMD_STD,
1403 .nr_regions = 1,
1404 .regions = {
1405 ERASEINFO(0x01000,128),
1406 }
1407 }, {
1408 .mfr_id = MANUFACTURER_SST,
1396 .dev_id = SST49LF040B, 1409 .dev_id = SST49LF040B,
1397 .name = "SST 49LF040B", 1410 .name = "SST 49LF040B",
1398 .devtypes = CFI_DEVICETYPE_X8, 1411 .devtypes = CFI_DEVICETYPE_X8,
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index cc6369ea67dd..59c46126a5ce 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -500,6 +500,9 @@ static struct flash_info __devinitdata m25p_data [] = {
500 { "at26df161a", 0x1f4601, 0, 64 * 1024, 32, SECT_4K, }, 500 { "at26df161a", 0x1f4601, 0, 64 * 1024, 32, SECT_4K, },
501 { "at26df321", 0x1f4701, 0, 64 * 1024, 64, SECT_4K, }, 501 { "at26df321", 0x1f4701, 0, 64 * 1024, 64, SECT_4K, },
502 502
503 /* Macronix */
504 { "mx25l12805d", 0xc22018, 0, 64 * 1024, 256, },
505
503 /* Spansion -- single (large) sector size only, at least 506 /* Spansion -- single (large) sector size only, at least
504 * for the chips listed here (without boot sectors). 507 * for the chips listed here (without boot sectors).
505 */ 508 */
@@ -528,6 +531,7 @@ static struct flash_info __devinitdata m25p_data [] = {
528 { "m25p64", 0x202017, 0, 64 * 1024, 128, }, 531 { "m25p64", 0x202017, 0, 64 * 1024, 128, },
529 { "m25p128", 0x202018, 0, 256 * 1024, 64, }, 532 { "m25p128", 0x202018, 0, 256 * 1024, 64, },
530 533
534 { "m45pe10", 0x204011, 0, 64 * 1024, 2, },
531 { "m45pe80", 0x204014, 0, 64 * 1024, 16, }, 535 { "m45pe80", 0x204014, 0, 64 * 1024, 16, },
532 { "m45pe16", 0x204015, 0, 64 * 1024, 32, }, 536 { "m45pe16", 0x204015, 0, 64 * 1024, 32, },
533 537
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 82923bd2d9c5..0b98654d8eed 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -105,15 +105,6 @@ config MSP_FLASH_MAP_LIMIT
105 default "0x02000000" 105 default "0x02000000"
106 depends on MSP_FLASH_MAP_LIMIT_32M 106 depends on MSP_FLASH_MAP_LIMIT_32M
107 107
108config MTD_PMC_MSP_RAMROOT
109 tristate "Embedded RAM block device for root on PMC-Sierra MSP"
110 depends on PMC_MSP_EMBEDDED_ROOTFS && \
111 (MTD_BLOCK || MTD_BLOCK_RO) && \
112 MTD_RAM
113 help
114 This provides support for the embedded root file system
115 on PMC MSP devices. This memory is mapped as a MTD block device.
116
117config MTD_SUN_UFLASH 108config MTD_SUN_UFLASH
118 tristate "Sun Microsystems userflash support" 109 tristate "Sun Microsystems userflash support"
119 depends on SPARC && MTD_CFI && PCI 110 depends on SPARC && MTD_CFI && PCI
@@ -270,7 +261,7 @@ config MTD_ALCHEMY
270 261
271config MTD_DILNETPC 262config MTD_DILNETPC
272 tristate "CFI Flash device mapped on DIL/Net PC" 263 tristate "CFI Flash device mapped on DIL/Net PC"
273 depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT 264 depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN
274 help 265 help
275 MTD map driver for SSV DIL/Net PC Boards "DNP" and "ADNP". 266 MTD map driver for SSV DIL/Net PC Boards "DNP" and "ADNP".
276 For details, see <http://www.ssv-embedded.de/ssv/pc104/p169.htm> 267 For details, see <http://www.ssv-embedded.de/ssv/pc104/p169.htm>
@@ -501,7 +492,7 @@ config MTD_BFIN_ASYNC
501 If compiled as a module, it will be called bfin-async-flash. 492 If compiled as a module, it will be called bfin-async-flash.
502 493
503config MTD_UCLINUX 494config MTD_UCLINUX
504 tristate "Generic uClinux RAM/ROM filesystem support" 495 bool "Generic uClinux RAM/ROM filesystem support"
505 depends on MTD_PARTITIONS && MTD_RAM && !MMU 496 depends on MTD_PARTITIONS && MTD_RAM && !MMU
506 help 497 help
507 Map driver to support image based filesystems for uClinux. 498 Map driver to support image based filesystems for uClinux.
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 2dbc1bec8488..8bae7f9850c0 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -25,7 +25,6 @@ obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o
25obj-$(CONFIG_MTD_PHYSMAP) += physmap.o 25obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
26obj-$(CONFIG_MTD_PHYSMAP_OF) += physmap_of.o 26obj-$(CONFIG_MTD_PHYSMAP_OF) += physmap_of.o
27obj-$(CONFIG_MTD_PMC_MSP_EVM) += pmcmsp-flash.o 27obj-$(CONFIG_MTD_PMC_MSP_EVM) += pmcmsp-flash.o
28obj-$(CONFIG_MTD_PMC_MSP_RAMROOT)+= pmcmsp-ramroot.o
29obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o 28obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o
30obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o 29obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o
31obj-$(CONFIG_MTD_TQM8XXL) += tqm8xxl.o 30obj-$(CONFIG_MTD_TQM8XXL) += tqm8xxl.o
diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c
index 576611f605db..365c77b1b871 100644
--- a/drivers/mtd/maps/bfin-async-flash.c
+++ b/drivers/mtd/maps/bfin-async-flash.c
@@ -40,6 +40,9 @@ struct async_state {
40 uint32_t flash_ambctl0, flash_ambctl1; 40 uint32_t flash_ambctl0, flash_ambctl1;
41 uint32_t save_ambctl0, save_ambctl1; 41 uint32_t save_ambctl0, save_ambctl1;
42 unsigned long irq_flags; 42 unsigned long irq_flags;
43#ifdef CONFIG_MTD_PARTITIONS
44 struct mtd_partition *parts;
45#endif
43}; 46};
44 47
45static void switch_to_flash(struct async_state *state) 48static void switch_to_flash(struct async_state *state)
@@ -170,6 +173,7 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev)
170 if (ret > 0) { 173 if (ret > 0) {
171 pr_devinit(KERN_NOTICE DRIVER_NAME ": Using commandline partition definition\n"); 174 pr_devinit(KERN_NOTICE DRIVER_NAME ": Using commandline partition definition\n");
172 add_mtd_partitions(state->mtd, pdata->parts, ret); 175 add_mtd_partitions(state->mtd, pdata->parts, ret);
176 state->parts = pdata->parts;
173 177
174 } else if (pdata->nr_parts) { 178 } else if (pdata->nr_parts) {
175 pr_devinit(KERN_NOTICE DRIVER_NAME ": Using board partition definition\n"); 179 pr_devinit(KERN_NOTICE DRIVER_NAME ": Using board partition definition\n");
@@ -193,6 +197,7 @@ static int __devexit bfin_flash_remove(struct platform_device *pdev)
193 gpio_free(state->enet_flash_pin); 197 gpio_free(state->enet_flash_pin);
194#ifdef CONFIG_MTD_PARTITIONS 198#ifdef CONFIG_MTD_PARTITIONS
195 del_mtd_partitions(state->mtd); 199 del_mtd_partitions(state->mtd);
200 kfree(state->parts);
196#endif 201#endif
197 map_destroy(state->mtd); 202 map_destroy(state->mtd);
198 kfree(state); 203 kfree(state);
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c
index c9681a339a59..b08a798ee254 100644
--- a/drivers/mtd/maps/integrator-flash.c
+++ b/drivers/mtd/maps/integrator-flash.c
@@ -36,27 +36,33 @@
36#include <linux/mtd/mtd.h> 36#include <linux/mtd/mtd.h>
37#include <linux/mtd/map.h> 37#include <linux/mtd/map.h>
38#include <linux/mtd/partitions.h> 38#include <linux/mtd/partitions.h>
39#include <linux/mtd/concat.h>
39 40
40#include <asm/mach/flash.h> 41#include <asm/mach/flash.h>
41#include <mach/hardware.h> 42#include <mach/hardware.h>
42#include <asm/system.h> 43#include <asm/system.h>
43 44
44#ifdef CONFIG_ARCH_P720T 45#define SUBDEV_NAME_SIZE (BUS_ID_SIZE + 2)
45#define FLASH_BASE (0x04000000)
46#define FLASH_SIZE (64*1024*1024)
47#endif
48 46
49struct armflash_info { 47struct armflash_subdev_info {
48 char name[SUBDEV_NAME_SIZE];
49 struct mtd_info *mtd;
50 struct map_info map;
50 struct flash_platform_data *plat; 51 struct flash_platform_data *plat;
52};
53
54struct armflash_info {
51 struct resource *res; 55 struct resource *res;
52 struct mtd_partition *parts; 56 struct mtd_partition *parts;
53 struct mtd_info *mtd; 57 struct mtd_info *mtd;
54 struct map_info map; 58 int nr_subdev;
59 struct armflash_subdev_info subdev[0];
55}; 60};
56 61
57static void armflash_set_vpp(struct map_info *map, int on) 62static void armflash_set_vpp(struct map_info *map, int on)
58{ 63{
59 struct armflash_info *info = container_of(map, struct armflash_info, map); 64 struct armflash_subdev_info *info =
65 container_of(map, struct armflash_subdev_info, map);
60 66
61 if (info->plat && info->plat->set_vpp) 67 if (info->plat && info->plat->set_vpp)
62 info->plat->set_vpp(on); 68 info->plat->set_vpp(on);
@@ -64,32 +70,17 @@ static void armflash_set_vpp(struct map_info *map, int on)
64 70
65static const char *probes[] = { "cmdlinepart", "RedBoot", "afs", NULL }; 71static const char *probes[] = { "cmdlinepart", "RedBoot", "afs", NULL };
66 72
67static int armflash_probe(struct platform_device *dev) 73static int armflash_subdev_probe(struct armflash_subdev_info *subdev,
74 struct resource *res)
68{ 75{
69 struct flash_platform_data *plat = dev->dev.platform_data; 76 struct flash_platform_data *plat = subdev->plat;
70 struct resource *res = dev->resource; 77 resource_size_t size = res->end - res->start + 1;
71 unsigned int size = res->end - res->start + 1;
72 struct armflash_info *info;
73 int err;
74 void __iomem *base; 78 void __iomem *base;
79 int err = 0;
75 80
76 info = kzalloc(sizeof(struct armflash_info), GFP_KERNEL); 81 if (!request_mem_region(res->start, size, subdev->name)) {
77 if (!info) {
78 err = -ENOMEM;
79 goto out;
80 }
81
82 info->plat = plat;
83 if (plat && plat->init) {
84 err = plat->init();
85 if (err)
86 goto no_resource;
87 }
88
89 info->res = request_mem_region(res->start, size, "armflash");
90 if (!info->res) {
91 err = -EBUSY; 82 err = -EBUSY;
92 goto no_resource; 83 goto out;
93 } 84 }
94 85
95 base = ioremap(res->start, size); 86 base = ioremap(res->start, size);
@@ -101,27 +92,132 @@ static int armflash_probe(struct platform_device *dev)
101 /* 92 /*
102 * look for CFI based flash parts fitted to this board 93 * look for CFI based flash parts fitted to this board
103 */ 94 */
104 info->map.size = size; 95 subdev->map.size = size;
105 info->map.bankwidth = plat->width; 96 subdev->map.bankwidth = plat->width;
106 info->map.phys = res->start; 97 subdev->map.phys = res->start;
107 info->map.virt = base; 98 subdev->map.virt = base;
108 info->map.name = dev_name(&dev->dev); 99 subdev->map.name = subdev->name;
109 info->map.set_vpp = armflash_set_vpp; 100 subdev->map.set_vpp = armflash_set_vpp;
110 101
111 simple_map_init(&info->map); 102 simple_map_init(&subdev->map);
112 103
113 /* 104 /*
114 * Also, the CFI layer automatically works out what size 105 * Also, the CFI layer automatically works out what size
115 * of chips we have, and does the necessary identification 106 * of chips we have, and does the necessary identification
116 * for us automatically. 107 * for us automatically.
117 */ 108 */
118 info->mtd = do_map_probe(plat->map_name, &info->map); 109 subdev->mtd = do_map_probe(plat->map_name, &subdev->map);
119 if (!info->mtd) { 110 if (!subdev->mtd) {
120 err = -ENXIO; 111 err = -ENXIO;
121 goto no_device; 112 goto no_device;
122 } 113 }
123 114
124 info->mtd->owner = THIS_MODULE; 115 subdev->mtd->owner = THIS_MODULE;
116
117 /* Successful? */
118 if (err == 0)
119 return err;
120
121 if (subdev->mtd)
122 map_destroy(subdev->mtd);
123 no_device:
124 iounmap(base);
125 no_mem:
126 release_mem_region(res->start, size);
127 out:
128 return err;
129}
130
131static void armflash_subdev_remove(struct armflash_subdev_info *subdev)
132{
133 if (subdev->mtd)
134 map_destroy(subdev->mtd);
135 if (subdev->map.virt)
136 iounmap(subdev->map.virt);
137 release_mem_region(subdev->map.phys, subdev->map.size);
138}
139
140static int armflash_probe(struct platform_device *dev)
141{
142 struct flash_platform_data *plat = dev->dev.platform_data;
143 unsigned int size;
144 struct armflash_info *info;
145 int i, nr, err;
146
147 /* Count the number of devices */
148 for (nr = 0; ; nr++)
149 if (!platform_get_resource(dev, IORESOURCE_MEM, nr))
150 break;
151 if (nr == 0) {
152 err = -ENODEV;
153 goto out;
154 }
155
156 size = sizeof(struct armflash_info) +
157 sizeof(struct armflash_subdev_info) * nr;
158 info = kzalloc(size, GFP_KERNEL);
159 if (!info) {
160 err = -ENOMEM;
161 goto out;
162 }
163
164 if (plat && plat->init) {
165 err = plat->init();
166 if (err)
167 goto no_resource;
168 }
169
170 for (i = 0; i < nr; i++) {
171 struct armflash_subdev_info *subdev = &info->subdev[i];
172 struct resource *res;
173
174 res = platform_get_resource(dev, IORESOURCE_MEM, i);
175 if (!res)
176 break;
177
178 if (nr == 1)
179 /* No MTD concatenation, just use the default name */
180 snprintf(subdev->name, SUBDEV_NAME_SIZE, "%s",
181 dev_name(&dev->dev));
182 else
183 snprintf(subdev->name, SUBDEV_NAME_SIZE, "%s-%d",
184 dev_name(&dev->dev), i);
185 subdev->plat = plat;
186
187 err = armflash_subdev_probe(subdev, res);
188 if (err)
189 break;
190 }
191 info->nr_subdev = i;
192
193 if (err)
194 goto subdev_err;
195
196 if (info->nr_subdev == 1)
197 info->mtd = info->subdev[0].mtd;
198 else if (info->nr_subdev > 1) {
199#ifdef CONFIG_MTD_CONCAT
200 struct mtd_info *cdev[info->nr_subdev];
201
202 /*
203 * We detected multiple devices. Concatenate them together.
204 */
205 for (i = 0; i < info->nr_subdev; i++)
206 cdev[i] = info->subdev[i].mtd;
207
208 info->mtd = mtd_concat_create(cdev, info->nr_subdev,
209 dev_name(&dev->dev));
210 if (info->mtd == NULL)
211 err = -ENXIO;
212#else
213 printk(KERN_ERR "armflash: multiple devices found but "
214 "MTD concat support disabled.\n");
215 err = -ENXIO;
216#endif
217 }
218
219 if (err < 0)
220 goto cleanup;
125 221
126 err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0); 222 err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0);
127 if (err > 0) { 223 if (err > 0) {
@@ -131,28 +227,30 @@ static int armflash_probe(struct platform_device *dev)
131 "mtd partition registration failed: %d\n", err); 227 "mtd partition registration failed: %d\n", err);
132 } 228 }
133 229
134 if (err == 0) 230 if (err == 0) {
135 platform_set_drvdata(dev, info); 231 platform_set_drvdata(dev, info);
232 return err;
233 }
136 234
137 /* 235 /*
138 * If we got an error, free all resources. 236 * We got an error, free all resources.
139 */ 237 */
140 if (err < 0) { 238 cleanup:
141 if (info->mtd) { 239 if (info->mtd) {
142 del_mtd_partitions(info->mtd); 240 del_mtd_partitions(info->mtd);
143 map_destroy(info->mtd); 241#ifdef CONFIG_MTD_CONCAT
144 } 242 if (info->mtd != info->subdev[0].mtd)
145 kfree(info->parts); 243 mtd_concat_destroy(info->mtd);
146 244#endif
147 no_device:
148 iounmap(base);
149 no_mem:
150 release_mem_region(res->start, size);
151 no_resource:
152 if (plat && plat->exit)
153 plat->exit();
154 kfree(info);
155 } 245 }
246 kfree(info->parts);
247 subdev_err:
248 for (i = info->nr_subdev - 1; i >= 0; i--)
249 armflash_subdev_remove(&info->subdev[i]);
250 no_resource:
251 if (plat && plat->exit)
252 plat->exit();
253 kfree(info);
156 out: 254 out:
157 return err; 255 return err;
158} 256}
@@ -160,22 +258,26 @@ static int armflash_probe(struct platform_device *dev)
160static int armflash_remove(struct platform_device *dev) 258static int armflash_remove(struct platform_device *dev)
161{ 259{
162 struct armflash_info *info = platform_get_drvdata(dev); 260 struct armflash_info *info = platform_get_drvdata(dev);
261 struct flash_platform_data *plat = dev->dev.platform_data;
262 int i;
163 263
164 platform_set_drvdata(dev, NULL); 264 platform_set_drvdata(dev, NULL);
165 265
166 if (info) { 266 if (info) {
167 if (info->mtd) { 267 if (info->mtd) {
168 del_mtd_partitions(info->mtd); 268 del_mtd_partitions(info->mtd);
169 map_destroy(info->mtd); 269#ifdef CONFIG_MTD_CONCAT
270 if (info->mtd != info->subdev[0].mtd)
271 mtd_concat_destroy(info->mtd);
272#endif
170 } 273 }
171 kfree(info->parts); 274 kfree(info->parts);
172 275
173 iounmap(info->map.virt); 276 for (i = info->nr_subdev - 1; i >= 0; i--)
174 release_resource(info->res); 277 armflash_subdev_remove(&info->subdev[i]);
175 kfree(info->res);
176 278
177 if (info->plat && info->plat->exit) 279 if (plat && plat->exit)
178 info->plat->exit(); 280 plat->exit();
179 281
180 kfree(info); 282 kfree(info);
181 } 283 }
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index 29a901157352..380648e9051a 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -195,42 +195,6 @@ err_out:
195} 195}
196 196
197#ifdef CONFIG_PM 197#ifdef CONFIG_PM
198static int physmap_flash_suspend(struct platform_device *dev, pm_message_t state)
199{
200 struct physmap_flash_info *info = platform_get_drvdata(dev);
201 int ret = 0;
202 int i;
203
204 for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++)
205 if (info->mtd[i]->suspend) {
206 ret = info->mtd[i]->suspend(info->mtd[i]);
207 if (ret)
208 goto fail;
209 }
210
211 return 0;
212fail:
213 for (--i; i >= 0; --i)
214 if (info->mtd[i]->suspend) {
215 BUG_ON(!info->mtd[i]->resume);
216 info->mtd[i]->resume(info->mtd[i]);
217 }
218
219 return ret;
220}
221
222static int physmap_flash_resume(struct platform_device *dev)
223{
224 struct physmap_flash_info *info = platform_get_drvdata(dev);
225 int i;
226
227 for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++)
228 if (info->mtd[i]->resume)
229 info->mtd[i]->resume(info->mtd[i]);
230
231 return 0;
232}
233
234static void physmap_flash_shutdown(struct platform_device *dev) 198static void physmap_flash_shutdown(struct platform_device *dev)
235{ 199{
236 struct physmap_flash_info *info = platform_get_drvdata(dev); 200 struct physmap_flash_info *info = platform_get_drvdata(dev);
@@ -242,16 +206,12 @@ static void physmap_flash_shutdown(struct platform_device *dev)
242 info->mtd[i]->resume(info->mtd[i]); 206 info->mtd[i]->resume(info->mtd[i]);
243} 207}
244#else 208#else
245#define physmap_flash_suspend NULL
246#define physmap_flash_resume NULL
247#define physmap_flash_shutdown NULL 209#define physmap_flash_shutdown NULL
248#endif 210#endif
249 211
250static struct platform_driver physmap_flash_driver = { 212static struct platform_driver physmap_flash_driver = {
251 .probe = physmap_flash_probe, 213 .probe = physmap_flash_probe,
252 .remove = physmap_flash_remove, 214 .remove = physmap_flash_remove,
253 .suspend = physmap_flash_suspend,
254 .resume = physmap_flash_resume,
255 .shutdown = physmap_flash_shutdown, 215 .shutdown = physmap_flash_shutdown,
256 .driver = { 216 .driver = {
257 .name = "physmap-flash", 217 .name = "physmap-flash",
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index c83a60fada53..39d357b2eb47 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -20,16 +20,23 @@
20#include <linux/mtd/mtd.h> 20#include <linux/mtd/mtd.h>
21#include <linux/mtd/map.h> 21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h> 22#include <linux/mtd/partitions.h>
23#include <linux/mtd/concat.h>
23#include <linux/of.h> 24#include <linux/of.h>
24#include <linux/of_platform.h> 25#include <linux/of_platform.h>
25 26
27struct of_flash_list {
28 struct mtd_info *mtd;
29 struct map_info map;
30 struct resource *res;
31};
32
26struct of_flash { 33struct of_flash {
27 struct mtd_info *mtd; 34 struct mtd_info *cmtd;
28 struct map_info map;
29 struct resource *res;
30#ifdef CONFIG_MTD_PARTITIONS 35#ifdef CONFIG_MTD_PARTITIONS
31 struct mtd_partition *parts; 36 struct mtd_partition *parts;
32#endif 37#endif
38 int list_size; /* number of elements in of_flash_list */
39 struct of_flash_list list[0];
33}; 40};
34 41
35#ifdef CONFIG_MTD_PARTITIONS 42#ifdef CONFIG_MTD_PARTITIONS
@@ -88,30 +95,44 @@ static int parse_obsolete_partitions(struct of_device *dev,
88static int of_flash_remove(struct of_device *dev) 95static int of_flash_remove(struct of_device *dev)
89{ 96{
90 struct of_flash *info; 97 struct of_flash *info;
98 int i;
91 99
92 info = dev_get_drvdata(&dev->dev); 100 info = dev_get_drvdata(&dev->dev);
93 if (!info) 101 if (!info)
94 return 0; 102 return 0;
95 dev_set_drvdata(&dev->dev, NULL); 103 dev_set_drvdata(&dev->dev, NULL);
96 104
97 if (info->mtd) { 105#ifdef CONFIG_MTD_CONCAT
106 if (info->cmtd != info->list[0].mtd) {
107 del_mtd_device(info->cmtd);
108 mtd_concat_destroy(info->cmtd);
109 }
110#endif
111
112 if (info->cmtd) {
98 if (OF_FLASH_PARTS(info)) { 113 if (OF_FLASH_PARTS(info)) {
99 del_mtd_partitions(info->mtd); 114 del_mtd_partitions(info->cmtd);
100 kfree(OF_FLASH_PARTS(info)); 115 kfree(OF_FLASH_PARTS(info));
101 } else { 116 } else {
102 del_mtd_device(info->mtd); 117 del_mtd_device(info->cmtd);
103 } 118 }
104 map_destroy(info->mtd);
105 } 119 }
106 120
107 if (info->map.virt) 121 for (i = 0; i < info->list_size; i++) {
108 iounmap(info->map.virt); 122 if (info->list[i].mtd)
123 map_destroy(info->list[i].mtd);
109 124
110 if (info->res) { 125 if (info->list[i].map.virt)
111 release_resource(info->res); 126 iounmap(info->list[i].map.virt);
112 kfree(info->res); 127
128 if (info->list[i].res) {
129 release_resource(info->list[i].res);
130 kfree(info->list[i].res);
131 }
113 } 132 }
114 133
134 kfree(info);
135
115 return 0; 136 return 0;
116} 137}
117 138
@@ -164,68 +185,130 @@ static int __devinit of_flash_probe(struct of_device *dev,
164 const char *probe_type = match->data; 185 const char *probe_type = match->data;
165 const u32 *width; 186 const u32 *width;
166 int err; 187 int err;
167 188 int i;
168 err = -ENXIO; 189 int count;
169 if (of_address_to_resource(dp, 0, &res)) { 190 const u32 *p;
170 dev_err(&dev->dev, "Can't get IO address from device tree\n"); 191 int reg_tuple_size;
192 struct mtd_info **mtd_list = NULL;
193
194 reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32);
195
196 /*
197 * Get number of "reg" tuples. Scan for MTD devices on area's
198 * described by each "reg" region. This makes it possible (including
199 * the concat support) to support the Intel P30 48F4400 chips which
200 * consists internally of 2 non-identical NOR chips on one die.
201 */
202 p = of_get_property(dp, "reg", &count);
203 if (count % reg_tuple_size != 0) {
204 dev_err(&dev->dev, "Malformed reg property on %s\n",
205 dev->node->full_name);
206 err = -EINVAL;
171 goto err_out; 207 goto err_out;
172 } 208 }
173 209 count /= reg_tuple_size;
174 dev_dbg(&dev->dev, "of_flash device: %.8llx-%.8llx\n",
175 (unsigned long long)res.start, (unsigned long long)res.end);
176 210
177 err = -ENOMEM; 211 err = -ENOMEM;
178 info = kzalloc(sizeof(*info), GFP_KERNEL); 212 info = kzalloc(sizeof(struct of_flash) +
213 sizeof(struct of_flash_list) * count, GFP_KERNEL);
214 if (!info)
215 goto err_out;
216
217 mtd_list = kzalloc(sizeof(struct mtd_info) * count, GFP_KERNEL);
179 if (!info) 218 if (!info)
180 goto err_out; 219 goto err_out;
181 220
182 dev_set_drvdata(&dev->dev, info); 221 dev_set_drvdata(&dev->dev, info);
183 222
184 err = -EBUSY; 223 for (i = 0; i < count; i++) {
185 info->res = request_mem_region(res.start, res.end - res.start + 1, 224 err = -ENXIO;
186 dev_name(&dev->dev)); 225 if (of_address_to_resource(dp, i, &res)) {
187 if (!info->res) 226 dev_err(&dev->dev, "Can't get IO address from device"
188 goto err_out; 227 " tree\n");
228 goto err_out;
229 }
189 230
190 err = -ENXIO; 231 dev_dbg(&dev->dev, "of_flash device: %.8llx-%.8llx\n",
191 width = of_get_property(dp, "bank-width", NULL); 232 (unsigned long long)res.start,
192 if (!width) { 233 (unsigned long long)res.end);
193 dev_err(&dev->dev, "Can't get bank width from device tree\n"); 234
194 goto err_out; 235 err = -EBUSY;
195 } 236 info->list[i].res = request_mem_region(res.start, res.end -
237 res.start + 1,
238 dev_name(&dev->dev));
239 if (!info->list[i].res)
240 goto err_out;
241
242 err = -ENXIO;
243 width = of_get_property(dp, "bank-width", NULL);
244 if (!width) {
245 dev_err(&dev->dev, "Can't get bank width from device"
246 " tree\n");
247 goto err_out;
248 }
196 249
197 info->map.name = dev_name(&dev->dev); 250 info->list[i].map.name = dev_name(&dev->dev);
198 info->map.phys = res.start; 251 info->list[i].map.phys = res.start;
199 info->map.size = res.end - res.start + 1; 252 info->list[i].map.size = res.end - res.start + 1;
200 info->map.bankwidth = *width; 253 info->list[i].map.bankwidth = *width;
254
255 err = -ENOMEM;
256 info->list[i].map.virt = ioremap(info->list[i].map.phys,
257 info->list[i].map.size);
258 if (!info->list[i].map.virt) {
259 dev_err(&dev->dev, "Failed to ioremap() flash"
260 " region\n");
261 goto err_out;
262 }
201 263
202 err = -ENOMEM; 264 simple_map_init(&info->list[i].map);
203 info->map.virt = ioremap(info->map.phys, info->map.size);
204 if (!info->map.virt) {
205 dev_err(&dev->dev, "Failed to ioremap() flash region\n");
206 goto err_out;
207 }
208 265
209 simple_map_init(&info->map); 266 if (probe_type) {
267 info->list[i].mtd = do_map_probe(probe_type,
268 &info->list[i].map);
269 } else {
270 info->list[i].mtd = obsolete_probe(dev,
271 &info->list[i].map);
272 }
273 mtd_list[i] = info->list[i].mtd;
210 274
211 if (probe_type) 275 err = -ENXIO;
212 info->mtd = do_map_probe(probe_type, &info->map); 276 if (!info->list[i].mtd) {
213 else 277 dev_err(&dev->dev, "do_map_probe() failed\n");
214 info->mtd = obsolete_probe(dev, &info->map); 278 goto err_out;
279 } else {
280 info->list_size++;
281 }
282 info->list[i].mtd->owner = THIS_MODULE;
283 info->list[i].mtd->dev.parent = &dev->dev;
284 }
215 285
216 err = -ENXIO; 286 err = 0;
217 if (!info->mtd) { 287 if (info->list_size == 1) {
218 dev_err(&dev->dev, "do_map_probe() failed\n"); 288 info->cmtd = info->list[0].mtd;
219 goto err_out; 289 } else if (info->list_size > 1) {
290 /*
291 * We detected multiple devices. Concatenate them together.
292 */
293#ifdef CONFIG_MTD_CONCAT
294 info->cmtd = mtd_concat_create(mtd_list, info->list_size,
295 dev_name(&dev->dev));
296 if (info->cmtd == NULL)
297 err = -ENXIO;
298#else
299 printk(KERN_ERR "physmap_of: multiple devices "
300 "found but MTD concat support disabled.\n");
301 err = -ENXIO;
302#endif
220 } 303 }
221 info->mtd->owner = THIS_MODULE; 304 if (err)
222 info->mtd->dev.parent = &dev->dev; 305 goto err_out;
223 306
224#ifdef CONFIG_MTD_PARTITIONS 307#ifdef CONFIG_MTD_PARTITIONS
225 /* First look for RedBoot table or partitions on the command 308 /* First look for RedBoot table or partitions on the command
226 * line, these take precedence over device tree information */ 309 * line, these take precedence over device tree information */
227 err = parse_mtd_partitions(info->mtd, part_probe_types, 310 err = parse_mtd_partitions(info->cmtd, part_probe_types,
228 &info->parts, 0); 311 &info->parts, 0);
229 if (err < 0) 312 if (err < 0)
230 return err; 313 return err;
231 314
@@ -244,15 +327,19 @@ static int __devinit of_flash_probe(struct of_device *dev,
244 } 327 }
245 328
246 if (err > 0) 329 if (err > 0)
247 add_mtd_partitions(info->mtd, info->parts, err); 330 add_mtd_partitions(info->cmtd, info->parts, err);
248 else 331 else
249#endif 332#endif
250 add_mtd_device(info->mtd); 333 add_mtd_device(info->cmtd);
334
335 kfree(mtd_list);
251 336
252 return 0; 337 return 0;
253 338
254err_out: 339err_out:
340 kfree(mtd_list);
255 of_flash_remove(dev); 341 of_flash_remove(dev);
342
256 return err; 343 return err;
257} 344}
258 345
diff --git a/drivers/mtd/maps/pmcmsp-ramroot.c b/drivers/mtd/maps/pmcmsp-ramroot.c
deleted file mode 100644
index 30de5c0c09a9..000000000000
--- a/drivers/mtd/maps/pmcmsp-ramroot.c
+++ /dev/null
@@ -1,104 +0,0 @@
1/*
2 * Mapping of the rootfs in a physical region of memory
3 *
4 * Copyright (C) 2005-2007 PMC-Sierra Inc.
5 * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
15 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
16 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
18 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#include <linux/module.h>
29#include <linux/types.h>
30#include <linux/kernel.h>
31#include <linux/init.h>
32#include <linux/slab.h>
33#include <linux/fs.h>
34#include <linux/root_dev.h>
35#include <linux/mtd/mtd.h>
36#include <linux/mtd/map.h>
37
38#include <asm/io.h>
39
40#include <msp_prom.h>
41
42static struct mtd_info *rr_mtd;
43
44struct map_info rr_map = {
45 .name = "ramroot",
46 .bankwidth = 4,
47};
48
49static int __init init_rrmap(void)
50{
51 void *ramroot_start;
52 unsigned long ramroot_size;
53
54 /* Check for supported rootfs types */
55 if (get_ramroot(&ramroot_start, &ramroot_size)) {
56 rr_map.phys = CPHYSADDR(ramroot_start);
57 rr_map.size = ramroot_size;
58
59 printk(KERN_NOTICE
60 "PMC embedded root device: 0x%08lx @ 0x%08lx\n",
61 rr_map.size, (unsigned long)rr_map.phys);
62 } else {
63 printk(KERN_ERR
64 "init_rrmap: no supported embedded rootfs detected!\n");
65 return -ENXIO;
66 }
67
68 /* Map rootfs to I/O space for block device driver */
69 rr_map.virt = ioremap(rr_map.phys, rr_map.size);
70 if (!rr_map.virt) {
71 printk(KERN_ERR "Failed to ioremap\n");
72 return -EIO;
73 }
74
75 simple_map_init(&rr_map);
76
77 rr_mtd = do_map_probe("map_ram", &rr_map);
78 if (rr_mtd) {
79 rr_mtd->owner = THIS_MODULE;
80
81 add_mtd_device(rr_mtd);
82
83 return 0;
84 }
85
86 iounmap(rr_map.virt);
87 return -ENXIO;
88}
89
90static void __exit cleanup_rrmap(void)
91{
92 del_mtd_device(rr_mtd);
93 map_destroy(rr_mtd);
94
95 iounmap(rr_map.virt);
96 rr_map.virt = NULL;
97}
98
99MODULE_AUTHOR("PMC-Sierra, Inc");
100MODULE_DESCRIPTION("MTD map driver for embedded PMC-Sierra MSP filesystem");
101MODULE_LICENSE("GPL");
102
103module_init(init_rrmap);
104module_exit(cleanup_rrmap);
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index 572d32fdf38a..643aa06b599e 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -140,24 +140,6 @@ static int __devexit pxa2xx_flash_remove(struct platform_device *dev)
140} 140}
141 141
142#ifdef CONFIG_PM 142#ifdef CONFIG_PM
143static int pxa2xx_flash_suspend(struct platform_device *dev, pm_message_t state)
144{
145 struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
146 int ret = 0;
147
148 if (info->mtd && info->mtd->suspend)
149 ret = info->mtd->suspend(info->mtd);
150 return ret;
151}
152
153static int pxa2xx_flash_resume(struct platform_device *dev)
154{
155 struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
156
157 if (info->mtd && info->mtd->resume)
158 info->mtd->resume(info->mtd);
159 return 0;
160}
161static void pxa2xx_flash_shutdown(struct platform_device *dev) 143static void pxa2xx_flash_shutdown(struct platform_device *dev)
162{ 144{
163 struct pxa2xx_flash_info *info = platform_get_drvdata(dev); 145 struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
@@ -166,8 +148,6 @@ static void pxa2xx_flash_shutdown(struct platform_device *dev)
166 info->mtd->resume(info->mtd); 148 info->mtd->resume(info->mtd);
167} 149}
168#else 150#else
169#define pxa2xx_flash_suspend NULL
170#define pxa2xx_flash_resume NULL
171#define pxa2xx_flash_shutdown NULL 151#define pxa2xx_flash_shutdown NULL
172#endif 152#endif
173 153
@@ -178,8 +158,6 @@ static struct platform_driver pxa2xx_flash_driver = {
178 }, 158 },
179 .probe = pxa2xx_flash_probe, 159 .probe = pxa2xx_flash_probe,
180 .remove = __devexit_p(pxa2xx_flash_remove), 160 .remove = __devexit_p(pxa2xx_flash_remove),
181 .suspend = pxa2xx_flash_suspend,
182 .resume = pxa2xx_flash_resume,
183 .shutdown = pxa2xx_flash_shutdown, 161 .shutdown = pxa2xx_flash_shutdown,
184}; 162};
185 163
diff --git a/drivers/mtd/maps/rbtx4939-flash.c b/drivers/mtd/maps/rbtx4939-flash.c
index d39f0adac846..83ed64512c5e 100644
--- a/drivers/mtd/maps/rbtx4939-flash.c
+++ b/drivers/mtd/maps/rbtx4939-flash.c
@@ -145,25 +145,6 @@ err_out:
145} 145}
146 146
147#ifdef CONFIG_PM 147#ifdef CONFIG_PM
148static int rbtx4939_flash_suspend(struct platform_device *dev,
149 pm_message_t state)
150{
151 struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
152
153 if (info->mtd->suspend)
154 return info->mtd->suspend(info->mtd);
155 return 0;
156}
157
158static int rbtx4939_flash_resume(struct platform_device *dev)
159{
160 struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
161
162 if (info->mtd->resume)
163 info->mtd->resume(info->mtd);
164 return 0;
165}
166
167static void rbtx4939_flash_shutdown(struct platform_device *dev) 148static void rbtx4939_flash_shutdown(struct platform_device *dev)
168{ 149{
169 struct rbtx4939_flash_info *info = platform_get_drvdata(dev); 150 struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
@@ -173,16 +154,12 @@ static void rbtx4939_flash_shutdown(struct platform_device *dev)
173 info->mtd->resume(info->mtd); 154 info->mtd->resume(info->mtd);
174} 155}
175#else 156#else
176#define rbtx4939_flash_suspend NULL
177#define rbtx4939_flash_resume NULL
178#define rbtx4939_flash_shutdown NULL 157#define rbtx4939_flash_shutdown NULL
179#endif 158#endif
180 159
181static struct platform_driver rbtx4939_flash_driver = { 160static struct platform_driver rbtx4939_flash_driver = {
182 .probe = rbtx4939_flash_probe, 161 .probe = rbtx4939_flash_probe,
183 .remove = rbtx4939_flash_remove, 162 .remove = rbtx4939_flash_remove,
184 .suspend = rbtx4939_flash_suspend,
185 .resume = rbtx4939_flash_resume,
186 .shutdown = rbtx4939_flash_shutdown, 163 .shutdown = rbtx4939_flash_shutdown,
187 .driver = { 164 .driver = {
188 .name = "rbtx4939-flash", 165 .name = "rbtx4939-flash",
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index 05e9362dc7f0..c6210f5118d1 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -415,25 +415,6 @@ static int __exit sa1100_mtd_remove(struct platform_device *pdev)
415} 415}
416 416
417#ifdef CONFIG_PM 417#ifdef CONFIG_PM
418static int sa1100_mtd_suspend(struct platform_device *dev, pm_message_t state)
419{
420 struct sa_info *info = platform_get_drvdata(dev);
421 int ret = 0;
422
423 if (info)
424 ret = info->mtd->suspend(info->mtd);
425
426 return ret;
427}
428
429static int sa1100_mtd_resume(struct platform_device *dev)
430{
431 struct sa_info *info = platform_get_drvdata(dev);
432 if (info)
433 info->mtd->resume(info->mtd);
434 return 0;
435}
436
437static void sa1100_mtd_shutdown(struct platform_device *dev) 418static void sa1100_mtd_shutdown(struct platform_device *dev)
438{ 419{
439 struct sa_info *info = platform_get_drvdata(dev); 420 struct sa_info *info = platform_get_drvdata(dev);
@@ -441,16 +422,12 @@ static void sa1100_mtd_shutdown(struct platform_device *dev)
441 info->mtd->resume(info->mtd); 422 info->mtd->resume(info->mtd);
442} 423}
443#else 424#else
444#define sa1100_mtd_suspend NULL
445#define sa1100_mtd_resume NULL
446#define sa1100_mtd_shutdown NULL 425#define sa1100_mtd_shutdown NULL
447#endif 426#endif
448 427
449static struct platform_driver sa1100_mtd_driver = { 428static struct platform_driver sa1100_mtd_driver = {
450 .probe = sa1100_mtd_probe, 429 .probe = sa1100_mtd_probe,
451 .remove = __exit_p(sa1100_mtd_remove), 430 .remove = __exit_p(sa1100_mtd_remove),
452 .suspend = sa1100_mtd_suspend,
453 .resume = sa1100_mtd_resume,
454 .shutdown = sa1100_mtd_shutdown, 431 .shutdown = sa1100_mtd_shutdown,
455 .driver = { 432 .driver = {
456 .name = "sa1100-mtd", 433 .name = "sa1100-mtd",
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
index 81756e397711..d4314fb88212 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -22,15 +22,19 @@
22 22
23/****************************************************************************/ 23/****************************************************************************/
24 24
25extern char _ebss;
26
25struct map_info uclinux_ram_map = { 27struct map_info uclinux_ram_map = {
26 .name = "RAM", 28 .name = "RAM",
29 .phys = (unsigned long)&_ebss,
30 .size = 0,
27}; 31};
28 32
29struct mtd_info *uclinux_ram_mtdinfo; 33static struct mtd_info *uclinux_ram_mtdinfo;
30 34
31/****************************************************************************/ 35/****************************************************************************/
32 36
33struct mtd_partition uclinux_romfs[] = { 37static struct mtd_partition uclinux_romfs[] = {
34 { .name = "ROMfs" } 38 { .name = "ROMfs" }
35}; 39};
36 40
@@ -38,7 +42,7 @@ struct mtd_partition uclinux_romfs[] = {
38 42
39/****************************************************************************/ 43/****************************************************************************/
40 44
41int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len, 45static int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len,
42 size_t *retlen, void **virt, resource_size_t *phys) 46 size_t *retlen, void **virt, resource_size_t *phys)
43{ 47{
44 struct map_info *map = mtd->priv; 48 struct map_info *map = mtd->priv;
@@ -55,12 +59,10 @@ static int __init uclinux_mtd_init(void)
55{ 59{
56 struct mtd_info *mtd; 60 struct mtd_info *mtd;
57 struct map_info *mapp; 61 struct map_info *mapp;
58 extern char _ebss;
59 unsigned long addr = (unsigned long) &_ebss;
60 62
61 mapp = &uclinux_ram_map; 63 mapp = &uclinux_ram_map;
62 mapp->phys = addr; 64 if (!mapp->size)
63 mapp->size = PAGE_ALIGN(ntohl(*((unsigned long *)(addr + 8)))); 65 mapp->size = PAGE_ALIGN(ntohl(*((unsigned long *)(mapp->phys + 8))));
64 mapp->bankwidth = 4; 66 mapp->bankwidth = 4;
65 67
66 printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n", 68 printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n",
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index a49a9c8f2cb1..8773481a30c2 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -286,7 +286,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
286 gd->private_data = new; 286 gd->private_data = new;
287 new->blkcore_priv = gd; 287 new->blkcore_priv = gd;
288 gd->queue = tr->blkcore_priv->rq; 288 gd->queue = tr->blkcore_priv->rq;
289 gd->driverfs_dev = new->mtd->dev.parent; 289 gd->driverfs_dev = &new->mtd->dev;
290 290
291 if (new->readonly) 291 if (new->readonly)
292 set_disk_ro(gd, 1); 292 set_disk_ro(gd, 1);
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 763d3f0a1f42..5b081cb84351 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -14,6 +14,7 @@
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/smp_lock.h> 15#include <linux/smp_lock.h>
16#include <linux/backing-dev.h> 16#include <linux/backing-dev.h>
17#include <linux/compat.h>
17 18
18#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
19#include <linux/mtd/compatmac.h> 20#include <linux/mtd/compatmac.h>
@@ -355,6 +356,100 @@ static int otp_select_filemode(struct mtd_file_info *mfi, int mode)
355# define otp_select_filemode(f,m) -EOPNOTSUPP 356# define otp_select_filemode(f,m) -EOPNOTSUPP
356#endif 357#endif
357 358
359static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd,
360 uint64_t start, uint32_t length, void __user *ptr,
361 uint32_t __user *retp)
362{
363 struct mtd_oob_ops ops;
364 uint32_t retlen;
365 int ret = 0;
366
367 if (!(file->f_mode & FMODE_WRITE))
368 return -EPERM;
369
370 if (length > 4096)
371 return -EINVAL;
372
373 if (!mtd->write_oob)
374 ret = -EOPNOTSUPP;
375 else
376 ret = access_ok(VERIFY_READ, ptr, length) ? 0 : EFAULT;
377
378 if (ret)
379 return ret;
380
381 ops.ooblen = length;
382 ops.ooboffs = start & (mtd->oobsize - 1);
383 ops.datbuf = NULL;
384 ops.mode = MTD_OOB_PLACE;
385
386 if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs))
387 return -EINVAL;
388
389 ops.oobbuf = kmalloc(length, GFP_KERNEL);
390 if (!ops.oobbuf)
391 return -ENOMEM;
392
393 if (copy_from_user(ops.oobbuf, ptr, length)) {
394 kfree(ops.oobbuf);
395 return -EFAULT;
396 }
397
398 start &= ~((uint64_t)mtd->oobsize - 1);
399 ret = mtd->write_oob(mtd, start, &ops);
400
401 if (ops.oobretlen > 0xFFFFFFFFU)
402 ret = -EOVERFLOW;
403 retlen = ops.oobretlen;
404 if (copy_to_user(retp, &retlen, sizeof(length)))
405 ret = -EFAULT;
406
407 kfree(ops.oobbuf);
408 return ret;
409}
410
411static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
412 uint32_t length, void __user *ptr, uint32_t __user *retp)
413{
414 struct mtd_oob_ops ops;
415 int ret = 0;
416
417 if (length > 4096)
418 return -EINVAL;
419
420 if (!mtd->read_oob)
421 ret = -EOPNOTSUPP;
422 else
423 ret = access_ok(VERIFY_WRITE, ptr,
424 length) ? 0 : -EFAULT;
425 if (ret)
426 return ret;
427
428 ops.ooblen = length;
429 ops.ooboffs = start & (mtd->oobsize - 1);
430 ops.datbuf = NULL;
431 ops.mode = MTD_OOB_PLACE;
432
433 if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs))
434 return -EINVAL;
435
436 ops.oobbuf = kmalloc(length, GFP_KERNEL);
437 if (!ops.oobbuf)
438 return -ENOMEM;
439
440 start &= ~((uint64_t)mtd->oobsize - 1);
441 ret = mtd->read_oob(mtd, start, &ops);
442
443 if (put_user(ops.oobretlen, retp))
444 ret = -EFAULT;
445 else if (ops.oobretlen && copy_to_user(ptr, ops.oobbuf,
446 ops.oobretlen))
447 ret = -EFAULT;
448
449 kfree(ops.oobbuf);
450 return ret;
451}
452
358static int mtd_ioctl(struct inode *inode, struct file *file, 453static int mtd_ioctl(struct inode *inode, struct file *file,
359 u_int cmd, u_long arg) 454 u_int cmd, u_long arg)
360{ 455{
@@ -417,6 +512,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
417 break; 512 break;
418 513
419 case MEMERASE: 514 case MEMERASE:
515 case MEMERASE64:
420 { 516 {
421 struct erase_info *erase; 517 struct erase_info *erase;
422 518
@@ -427,20 +523,32 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
427 if (!erase) 523 if (!erase)
428 ret = -ENOMEM; 524 ret = -ENOMEM;
429 else { 525 else {
430 struct erase_info_user einfo;
431
432 wait_queue_head_t waitq; 526 wait_queue_head_t waitq;
433 DECLARE_WAITQUEUE(wait, current); 527 DECLARE_WAITQUEUE(wait, current);
434 528
435 init_waitqueue_head(&waitq); 529 init_waitqueue_head(&waitq);
436 530
437 if (copy_from_user(&einfo, argp, 531 if (cmd == MEMERASE64) {
438 sizeof(struct erase_info_user))) { 532 struct erase_info_user64 einfo64;
439 kfree(erase); 533
440 return -EFAULT; 534 if (copy_from_user(&einfo64, argp,
535 sizeof(struct erase_info_user64))) {
536 kfree(erase);
537 return -EFAULT;
538 }
539 erase->addr = einfo64.start;
540 erase->len = einfo64.length;
541 } else {
542 struct erase_info_user einfo32;
543
544 if (copy_from_user(&einfo32, argp,
545 sizeof(struct erase_info_user))) {
546 kfree(erase);
547 return -EFAULT;
548 }
549 erase->addr = einfo32.start;
550 erase->len = einfo32.length;
441 } 551 }
442 erase->addr = einfo.start;
443 erase->len = einfo.length;
444 erase->mtd = mtd; 552 erase->mtd = mtd;
445 erase->callback = mtdchar_erase_callback; 553 erase->callback = mtdchar_erase_callback;
446 erase->priv = (unsigned long)&waitq; 554 erase->priv = (unsigned long)&waitq;
@@ -474,100 +582,56 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
474 case MEMWRITEOOB: 582 case MEMWRITEOOB:
475 { 583 {
476 struct mtd_oob_buf buf; 584 struct mtd_oob_buf buf;
477 struct mtd_oob_ops ops; 585 struct mtd_oob_buf __user *buf_user = argp;
478 struct mtd_oob_buf __user *user_buf = argp;
479 uint32_t retlen;
480
481 if(!(file->f_mode & FMODE_WRITE))
482 return -EPERM;
483
484 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
485 return -EFAULT;
486
487 if (buf.length > 4096)
488 return -EINVAL;
489
490 if (!mtd->write_oob)
491 ret = -EOPNOTSUPP;
492 else
493 ret = access_ok(VERIFY_READ, buf.ptr,
494 buf.length) ? 0 : EFAULT;
495
496 if (ret)
497 return ret;
498
499 ops.ooblen = buf.length;
500 ops.ooboffs = buf.start & (mtd->oobsize - 1);
501 ops.datbuf = NULL;
502 ops.mode = MTD_OOB_PLACE;
503
504 if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs))
505 return -EINVAL;
506
507 ops.oobbuf = kmalloc(buf.length, GFP_KERNEL);
508 if (!ops.oobbuf)
509 return -ENOMEM;
510
511 if (copy_from_user(ops.oobbuf, buf.ptr, buf.length)) {
512 kfree(ops.oobbuf);
513 return -EFAULT;
514 }
515 586
516 buf.start &= ~(mtd->oobsize - 1); 587 /* NOTE: writes return length to buf_user->length */
517 ret = mtd->write_oob(mtd, buf.start, &ops); 588 if (copy_from_user(&buf, argp, sizeof(buf)))
518
519 if (ops.oobretlen > 0xFFFFFFFFU)
520 ret = -EOVERFLOW;
521 retlen = ops.oobretlen;
522 if (copy_to_user(&user_buf->length, &retlen, sizeof(buf.length)))
523 ret = -EFAULT; 589 ret = -EFAULT;
524 590 else
525 kfree(ops.oobbuf); 591 ret = mtd_do_writeoob(file, mtd, buf.start, buf.length,
592 buf.ptr, &buf_user->length);
526 break; 593 break;
527
528 } 594 }
529 595
530 case MEMREADOOB: 596 case MEMREADOOB:
531 { 597 {
532 struct mtd_oob_buf buf; 598 struct mtd_oob_buf buf;
533 struct mtd_oob_ops ops; 599 struct mtd_oob_buf __user *buf_user = argp;
534
535 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
536 return -EFAULT;
537
538 if (buf.length > 4096)
539 return -EINVAL;
540 600
541 if (!mtd->read_oob) 601 /* NOTE: writes return length to buf_user->start */
542 ret = -EOPNOTSUPP; 602 if (copy_from_user(&buf, argp, sizeof(buf)))
603 ret = -EFAULT;
543 else 604 else
544 ret = access_ok(VERIFY_WRITE, buf.ptr, 605 ret = mtd_do_readoob(mtd, buf.start, buf.length,
545 buf.length) ? 0 : -EFAULT; 606 buf.ptr, &buf_user->start);
546 if (ret) 607 break;
547 return ret; 608 }
548
549 ops.ooblen = buf.length;
550 ops.ooboffs = buf.start & (mtd->oobsize - 1);
551 ops.datbuf = NULL;
552 ops.mode = MTD_OOB_PLACE;
553 609
554 if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs)) 610 case MEMWRITEOOB64:
555 return -EINVAL; 611 {
612 struct mtd_oob_buf64 buf;
613 struct mtd_oob_buf64 __user *buf_user = argp;
556 614
557 ops.oobbuf = kmalloc(buf.length, GFP_KERNEL); 615 if (copy_from_user(&buf, argp, sizeof(buf)))
558 if (!ops.oobbuf) 616 ret = -EFAULT;
559 return -ENOMEM; 617 else
618 ret = mtd_do_writeoob(file, mtd, buf.start, buf.length,
619 (void __user *)(uintptr_t)buf.usr_ptr,
620 &buf_user->length);
621 break;
622 }
560 623
561 buf.start &= ~(mtd->oobsize - 1); 624 case MEMREADOOB64:
562 ret = mtd->read_oob(mtd, buf.start, &ops); 625 {
626 struct mtd_oob_buf64 buf;
627 struct mtd_oob_buf64 __user *buf_user = argp;
563 628
564 if (put_user(ops.oobretlen, (uint32_t __user *)argp)) 629 if (copy_from_user(&buf, argp, sizeof(buf)))
565 ret = -EFAULT;
566 else if (ops.oobretlen && copy_to_user(buf.ptr, ops.oobbuf,
567 ops.oobretlen))
568 ret = -EFAULT; 630 ret = -EFAULT;
569 631 else
570 kfree(ops.oobbuf); 632 ret = mtd_do_readoob(mtd, buf.start, buf.length,
633 (void __user *)(uintptr_t)buf.usr_ptr,
634 &buf_user->length);
571 break; 635 break;
572 } 636 }
573 637
@@ -758,6 +822,68 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
758 return ret; 822 return ret;
759} /* memory_ioctl */ 823} /* memory_ioctl */
760 824
825#ifdef CONFIG_COMPAT
826
827struct mtd_oob_buf32 {
828 u_int32_t start;
829 u_int32_t length;
830 compat_caddr_t ptr; /* unsigned char* */
831};
832
833#define MEMWRITEOOB32 _IOWR('M', 3, struct mtd_oob_buf32)
834#define MEMREADOOB32 _IOWR('M', 4, struct mtd_oob_buf32)
835
836static long mtd_compat_ioctl(struct file *file, unsigned int cmd,
837 unsigned long arg)
838{
839 struct inode *inode = file->f_path.dentry->d_inode;
840 struct mtd_file_info *mfi = file->private_data;
841 struct mtd_info *mtd = mfi->mtd;
842 void __user *argp = compat_ptr(arg);
843 int ret = 0;
844
845 lock_kernel();
846
847 switch (cmd) {
848 case MEMWRITEOOB32:
849 {
850 struct mtd_oob_buf32 buf;
851 struct mtd_oob_buf32 __user *buf_user = argp;
852
853 if (copy_from_user(&buf, argp, sizeof(buf)))
854 ret = -EFAULT;
855 else
856 ret = mtd_do_writeoob(file, mtd, buf.start,
857 buf.length, compat_ptr(buf.ptr),
858 &buf_user->length);
859 break;
860 }
861
862 case MEMREADOOB32:
863 {
864 struct mtd_oob_buf32 buf;
865 struct mtd_oob_buf32 __user *buf_user = argp;
866
867 /* NOTE: writes return length to buf->start */
868 if (copy_from_user(&buf, argp, sizeof(buf)))
869 ret = -EFAULT;
870 else
871 ret = mtd_do_readoob(mtd, buf.start,
872 buf.length, compat_ptr(buf.ptr),
873 &buf_user->start);
874 break;
875 }
876 default:
877 ret = mtd_ioctl(inode, file, cmd, (unsigned long)argp);
878 }
879
880 unlock_kernel();
881
882 return ret;
883}
884
885#endif /* CONFIG_COMPAT */
886
761/* 887/*
762 * try to determine where a shared mapping can be made 888 * try to determine where a shared mapping can be made
763 * - only supported for NOMMU at the moment (MMU can't doesn't copy private 889 * - only supported for NOMMU at the moment (MMU can't doesn't copy private
@@ -817,6 +943,9 @@ static const struct file_operations mtd_fops = {
817 .read = mtd_read, 943 .read = mtd_read,
818 .write = mtd_write, 944 .write = mtd_write,
819 .ioctl = mtd_ioctl, 945 .ioctl = mtd_ioctl,
946#ifdef CONFIG_COMPAT
947 .compat_ioctl = mtd_compat_ioctl,
948#endif
820 .open = mtd_open, 949 .open = mtd_open,
821 .release = mtd_close, 950 .release = mtd_close,
822 .mmap = mtd_mmap, 951 .mmap = mtd_mmap,
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index bccb4b1ffc46..fac54a3fa3f1 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -23,8 +23,15 @@
23 23
24#include "mtdcore.h" 24#include "mtdcore.h"
25 25
26 26static int mtd_cls_suspend(struct device *dev, pm_message_t state);
27static struct class *mtd_class; 27static int mtd_cls_resume(struct device *dev);
28
29static struct class mtd_class = {
30 .name = "mtd",
31 .owner = THIS_MODULE,
32 .suspend = mtd_cls_suspend,
33 .resume = mtd_cls_resume,
34};
28 35
29/* These are exported solely for the purpose of mtd_blkdevs.c. You 36/* These are exported solely for the purpose of mtd_blkdevs.c. You
30 should not use them for _anything_ else */ 37 should not use them for _anything_ else */
@@ -52,7 +59,26 @@ static void mtd_release(struct device *dev)
52 59
53 /* remove /dev/mtdXro node if needed */ 60 /* remove /dev/mtdXro node if needed */
54 if (index) 61 if (index)
55 device_destroy(mtd_class, index + 1); 62 device_destroy(&mtd_class, index + 1);
63}
64
65static int mtd_cls_suspend(struct device *dev, pm_message_t state)
66{
67 struct mtd_info *mtd = dev_to_mtd(dev);
68
69 if (mtd->suspend)
70 return mtd->suspend(mtd);
71 else
72 return 0;
73}
74
75static int mtd_cls_resume(struct device *dev)
76{
77 struct mtd_info *mtd = dev_to_mtd(dev);
78
79 if (mtd->resume)
80 mtd->resume(mtd);
81 return 0;
56} 82}
57 83
58static ssize_t mtd_type_show(struct device *dev, 84static ssize_t mtd_type_show(struct device *dev,
@@ -269,7 +295,7 @@ int add_mtd_device(struct mtd_info *mtd)
269 * physical device. 295 * physical device.
270 */ 296 */
271 mtd->dev.type = &mtd_devtype; 297 mtd->dev.type = &mtd_devtype;
272 mtd->dev.class = mtd_class; 298 mtd->dev.class = &mtd_class;
273 mtd->dev.devt = MTD_DEVT(i); 299 mtd->dev.devt = MTD_DEVT(i);
274 dev_set_name(&mtd->dev, "mtd%d", i); 300 dev_set_name(&mtd->dev, "mtd%d", i);
275 if (device_register(&mtd->dev) != 0) { 301 if (device_register(&mtd->dev) != 0) {
@@ -278,7 +304,7 @@ int add_mtd_device(struct mtd_info *mtd)
278 } 304 }
279 305
280 if (MTD_DEVT(i)) 306 if (MTD_DEVT(i))
281 device_create(mtd_class, mtd->dev.parent, 307 device_create(&mtd_class, mtd->dev.parent,
282 MTD_DEVT(i) + 1, 308 MTD_DEVT(i) + 1,
283 NULL, "mtd%dro", i); 309 NULL, "mtd%dro", i);
284 310
@@ -604,11 +630,12 @@ done:
604 630
605static int __init init_mtd(void) 631static int __init init_mtd(void)
606{ 632{
607 mtd_class = class_create(THIS_MODULE, "mtd"); 633 int ret;
634 ret = class_register(&mtd_class);
608 635
609 if (IS_ERR(mtd_class)) { 636 if (ret) {
610 pr_err("Error creating mtd class.\n"); 637 pr_err("Error registering mtd class: %d\n", ret);
611 return PTR_ERR(mtd_class); 638 return ret;
612 } 639 }
613#ifdef CONFIG_PROC_FS 640#ifdef CONFIG_PROC_FS
614 if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) 641 if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
@@ -623,7 +650,7 @@ static void __exit cleanup_mtd(void)
623 if (proc_mtd) 650 if (proc_mtd)
624 remove_proc_entry( "mtd", NULL); 651 remove_proc_entry( "mtd", NULL);
625#endif /* CONFIG_PROC_FS */ 652#endif /* CONFIG_PROC_FS */
626 class_destroy(mtd_class); 653 class_unregister(&mtd_class);
627} 654}
628 655
629module_init(init_mtd); 656module_init(init_mtd);
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 29675edb44b4..349fcbe5cc0f 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -27,9 +27,7 @@ struct mtd_part {
27 struct mtd_info mtd; 27 struct mtd_info mtd;
28 struct mtd_info *master; 28 struct mtd_info *master;
29 uint64_t offset; 29 uint64_t offset;
30 int index;
31 struct list_head list; 30 struct list_head list;
32 int registered;
33}; 31};
34 32
35/* 33/*
@@ -321,8 +319,7 @@ int del_mtd_partitions(struct mtd_info *master)
321 list_for_each_entry_safe(slave, next, &mtd_partitions, list) 319 list_for_each_entry_safe(slave, next, &mtd_partitions, list)
322 if (slave->master == master) { 320 if (slave->master == master) {
323 list_del(&slave->list); 321 list_del(&slave->list);
324 if (slave->registered) 322 del_mtd_device(&slave->mtd);
325 del_mtd_device(&slave->mtd);
326 kfree(slave); 323 kfree(slave);
327 } 324 }
328 325
@@ -395,7 +392,7 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
395 slave->mtd.get_fact_prot_info = part_get_fact_prot_info; 392 slave->mtd.get_fact_prot_info = part_get_fact_prot_info;
396 if (master->sync) 393 if (master->sync)
397 slave->mtd.sync = part_sync; 394 slave->mtd.sync = part_sync;
398 if (!partno && master->suspend && master->resume) { 395 if (!partno && !master->dev.class && master->suspend && master->resume) {
399 slave->mtd.suspend = part_suspend; 396 slave->mtd.suspend = part_suspend;
400 slave->mtd.resume = part_resume; 397 slave->mtd.resume = part_resume;
401 } 398 }
@@ -412,7 +409,6 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
412 slave->mtd.erase = part_erase; 409 slave->mtd.erase = part_erase;
413 slave->master = master; 410 slave->master = master;
414 slave->offset = part->offset; 411 slave->offset = part->offset;
415 slave->index = partno;
416 412
417 if (slave->offset == MTDPART_OFS_APPEND) 413 if (slave->offset == MTDPART_OFS_APPEND)
418 slave->offset = cur_offset; 414 slave->offset = cur_offset;
@@ -500,15 +496,9 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
500 } 496 }
501 497
502out_register: 498out_register:
503 if (part->mtdp) { 499 /* register our partition */
504 /* store the object pointer (caller may or may not register it*/ 500 add_mtd_device(&slave->mtd);
505 *part->mtdp = &slave->mtd; 501
506 slave->registered = 0;
507 } else {
508 /* register our partition */
509 add_mtd_device(&slave->mtd);
510 slave->registered = 1;
511 }
512 return slave; 502 return slave;
513} 503}
514 504
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 890936d0275e..3b3a21d1a6ba 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -74,6 +74,12 @@ config MTD_NAND_AMS_DELTA
74 help 74 help
75 Support for NAND flash on Amstrad E3 (Delta). 75 Support for NAND flash on Amstrad E3 (Delta).
76 76
77config MTD_NAND_OMAP2
78 tristate "NAND Flash device on OMAP2 and OMAP3"
79 depends on ARM && MTD_NAND && (ARCH_OMAP2 || ARCH_OMAP3)
80 help
81 Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms.
82
77config MTD_NAND_TS7250 83config MTD_NAND_TS7250
78 tristate "NAND Flash device on TS-7250 board" 84 tristate "NAND Flash device on TS-7250 board"
79 depends on MACH_TS72XX 85 depends on MACH_TS72XX
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index d33860ac42c3..f3a786b3cff3 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o
25obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o 25obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o
26obj-$(CONFIG_MTD_NAND_ATMEL) += atmel_nand.o 26obj-$(CONFIG_MTD_NAND_ATMEL) += atmel_nand.o
27obj-$(CONFIG_MTD_NAND_GPIO) += gpio.o 27obj-$(CONFIG_MTD_NAND_GPIO) += gpio.o
28obj-$(CONFIG_MTD_NAND_OMAP2) += omap2.o
28obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o 29obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o
29obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o 30obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o
30obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o 31obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 47a33cec3793..2802992b39da 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -24,6 +24,7 @@
24 24
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/moduleparam.h>
27#include <linux/platform_device.h> 28#include <linux/platform_device.h>
28#include <linux/mtd/mtd.h> 29#include <linux/mtd/mtd.h>
29#include <linux/mtd/nand.h> 30#include <linux/mtd/nand.h>
@@ -47,6 +48,9 @@
47#define no_ecc 0 48#define no_ecc 0
48#endif 49#endif
49 50
51static int on_flash_bbt = 0;
52module_param(on_flash_bbt, int, 0);
53
50/* Register access macros */ 54/* Register access macros */
51#define ecc_readl(add, reg) \ 55#define ecc_readl(add, reg) \
52 __raw_readl(add + ATMEL_ECC_##reg) 56 __raw_readl(add + ATMEL_ECC_##reg)
@@ -459,12 +463,17 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
459 463
460 if (host->board->det_pin) { 464 if (host->board->det_pin) {
461 if (gpio_get_value(host->board->det_pin)) { 465 if (gpio_get_value(host->board->det_pin)) {
462 printk("No SmartMedia card inserted.\n"); 466 printk(KERN_INFO "No SmartMedia card inserted.\n");
463 res = ENXIO; 467 res = ENXIO;
464 goto err_no_card; 468 goto err_no_card;
465 } 469 }
466 } 470 }
467 471
472 if (on_flash_bbt) {
473 printk(KERN_INFO "atmel_nand: Use On Flash BBT\n");
474 nand_chip->options |= NAND_USE_FLASH_BBT;
475 }
476
468 /* first scan to find the device and get the page size */ 477 /* first scan to find the device and get the page size */
469 if (nand_scan_ident(mtd, 1)) { 478 if (nand_scan_ident(mtd, 1)) {
470 res = -ENXIO; 479 res = -ENXIO;
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c
index 4c2a67ca801e..8506e7e606fd 100644
--- a/drivers/mtd/nand/bf5xx_nand.c
+++ b/drivers/mtd/nand/bf5xx_nand.c
@@ -458,7 +458,7 @@ static irqreturn_t bf5xx_nand_dma_irq(int irq, void *dev_id)
458 return IRQ_HANDLED; 458 return IRQ_HANDLED;
459} 459}
460 460
461static int bf5xx_nand_dma_rw(struct mtd_info *mtd, 461static void bf5xx_nand_dma_rw(struct mtd_info *mtd,
462 uint8_t *buf, int is_read) 462 uint8_t *buf, int is_read)
463{ 463{
464 struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); 464 struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
@@ -496,11 +496,20 @@ static int bf5xx_nand_dma_rw(struct mtd_info *mtd,
496 /* setup DMA register with Blackfin DMA API */ 496 /* setup DMA register with Blackfin DMA API */
497 set_dma_config(CH_NFC, 0x0); 497 set_dma_config(CH_NFC, 0x0);
498 set_dma_start_addr(CH_NFC, (unsigned long) buf); 498 set_dma_start_addr(CH_NFC, (unsigned long) buf);
499
500/* The DMAs have different size on BF52x and BF54x */
501#ifdef CONFIG_BF52x
502 set_dma_x_count(CH_NFC, (page_size >> 1));
503 set_dma_x_modify(CH_NFC, 2);
504 val = DI_EN | WDSIZE_16;
505#endif
506
507#ifdef CONFIG_BF54x
499 set_dma_x_count(CH_NFC, (page_size >> 2)); 508 set_dma_x_count(CH_NFC, (page_size >> 2));
500 set_dma_x_modify(CH_NFC, 4); 509 set_dma_x_modify(CH_NFC, 4);
501
502 /* setup write or read operation */
503 val = DI_EN | WDSIZE_32; 510 val = DI_EN | WDSIZE_32;
511#endif
512 /* setup write or read operation */
504 if (is_read) 513 if (is_read)
505 val |= WNR; 514 val |= WNR;
506 set_dma_config(CH_NFC, val); 515 set_dma_config(CH_NFC, val);
@@ -512,8 +521,6 @@ static int bf5xx_nand_dma_rw(struct mtd_info *mtd,
512 else 521 else
513 bfin_write_NFC_PGCTL(0x2); 522 bfin_write_NFC_PGCTL(0x2);
514 wait_for_completion(&info->dma_completion); 523 wait_for_completion(&info->dma_completion);
515
516 return 0;
517} 524}
518 525
519static void bf5xx_nand_dma_read_buf(struct mtd_info *mtd, 526static void bf5xx_nand_dma_read_buf(struct mtd_info *mtd,
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 0119220de7d0..ba6940d1d3d1 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -44,7 +44,7 @@
44 * and some flavors of secondary chipselect (e.g. based on A12) as used 44 * and some flavors of secondary chipselect (e.g. based on A12) as used
45 * with multichip packages. 45 * with multichip packages.
46 * 46 *
47 * The 1-bit ECC hardware is supported, but not yet the newer 4-bit ECC 47 * The 1-bit ECC hardware is supported, as well as the newer 4-bit ECC
48 * available on chips like the DM355 and OMAP-L137 and needed with the 48 * available on chips like the DM355 and OMAP-L137 and needed with the
49 * more error-prone MLC NAND chips. 49 * more error-prone MLC NAND chips.
50 * 50 *
@@ -54,11 +54,14 @@
54struct davinci_nand_info { 54struct davinci_nand_info {
55 struct mtd_info mtd; 55 struct mtd_info mtd;
56 struct nand_chip chip; 56 struct nand_chip chip;
57 struct nand_ecclayout ecclayout;
57 58
58 struct device *dev; 59 struct device *dev;
59 struct clk *clk; 60 struct clk *clk;
60 bool partitioned; 61 bool partitioned;
61 62
63 bool is_readmode;
64
62 void __iomem *base; 65 void __iomem *base;
63 void __iomem *vaddr; 66 void __iomem *vaddr;
64 67
@@ -73,6 +76,7 @@ struct davinci_nand_info {
73}; 76};
74 77
75static DEFINE_SPINLOCK(davinci_nand_lock); 78static DEFINE_SPINLOCK(davinci_nand_lock);
79static bool ecc4_busy;
76 80
77#define to_davinci_nand(m) container_of(m, struct davinci_nand_info, mtd) 81#define to_davinci_nand(m) container_of(m, struct davinci_nand_info, mtd)
78 82
@@ -218,6 +222,192 @@ static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat,
218/*----------------------------------------------------------------------*/ 222/*----------------------------------------------------------------------*/
219 223
220/* 224/*
225 * 4-bit hardware ECC ... context maintained over entire AEMIF
226 *
227 * This is a syndrome engine, but we avoid NAND_ECC_HW_SYNDROME
228 * since that forces use of a problematic "infix OOB" layout.
229 * Among other things, it trashes manufacturer bad block markers.
230 * Also, and specific to this hardware, it ECC-protects the "prepad"
231 * in the OOB ... while having ECC protection for parts of OOB would
232 * seem useful, the current MTD stack sometimes wants to update the
233 * OOB without recomputing ECC.
234 */
235
236static void nand_davinci_hwctl_4bit(struct mtd_info *mtd, int mode)
237{
238 struct davinci_nand_info *info = to_davinci_nand(mtd);
239 unsigned long flags;
240 u32 val;
241
242 spin_lock_irqsave(&davinci_nand_lock, flags);
243
244 /* Start 4-bit ECC calculation for read/write */
245 val = davinci_nand_readl(info, NANDFCR_OFFSET);
246 val &= ~(0x03 << 4);
247 val |= (info->core_chipsel << 4) | BIT(12);
248 davinci_nand_writel(info, NANDFCR_OFFSET, val);
249
250 info->is_readmode = (mode == NAND_ECC_READ);
251
252 spin_unlock_irqrestore(&davinci_nand_lock, flags);
253}
254
255/* Read raw ECC code after writing to NAND. */
256static void
257nand_davinci_readecc_4bit(struct davinci_nand_info *info, u32 code[4])
258{
259 const u32 mask = 0x03ff03ff;
260
261 code[0] = davinci_nand_readl(info, NAND_4BIT_ECC1_OFFSET) & mask;
262 code[1] = davinci_nand_readl(info, NAND_4BIT_ECC2_OFFSET) & mask;
263 code[2] = davinci_nand_readl(info, NAND_4BIT_ECC3_OFFSET) & mask;
264 code[3] = davinci_nand_readl(info, NAND_4BIT_ECC4_OFFSET) & mask;
265}
266
267/* Terminate read ECC; or return ECC (as bytes) of data written to NAND. */
268static int nand_davinci_calculate_4bit(struct mtd_info *mtd,
269 const u_char *dat, u_char *ecc_code)
270{
271 struct davinci_nand_info *info = to_davinci_nand(mtd);
272 u32 raw_ecc[4], *p;
273 unsigned i;
274
275 /* After a read, terminate ECC calculation by a dummy read
276 * of some 4-bit ECC register. ECC covers everything that
277 * was read; correct() just uses the hardware state, so
278 * ecc_code is not needed.
279 */
280 if (info->is_readmode) {
281 davinci_nand_readl(info, NAND_4BIT_ECC1_OFFSET);
282 return 0;
283 }
284
285 /* Pack eight raw 10-bit ecc values into ten bytes, making
286 * two passes which each convert four values (in upper and
287 * lower halves of two 32-bit words) into five bytes. The
288 * ROM boot loader uses this same packing scheme.
289 */
290 nand_davinci_readecc_4bit(info, raw_ecc);
291 for (i = 0, p = raw_ecc; i < 2; i++, p += 2) {
292 *ecc_code++ = p[0] & 0xff;
293 *ecc_code++ = ((p[0] >> 8) & 0x03) | ((p[0] >> 14) & 0xfc);
294 *ecc_code++ = ((p[0] >> 22) & 0x0f) | ((p[1] << 4) & 0xf0);
295 *ecc_code++ = ((p[1] >> 4) & 0x3f) | ((p[1] >> 10) & 0xc0);
296 *ecc_code++ = (p[1] >> 18) & 0xff;
297 }
298
299 return 0;
300}
301
302/* Correct up to 4 bits in data we just read, using state left in the
303 * hardware plus the ecc_code computed when it was first written.
304 */
305static int nand_davinci_correct_4bit(struct mtd_info *mtd,
306 u_char *data, u_char *ecc_code, u_char *null)
307{
308 int i;
309 struct davinci_nand_info *info = to_davinci_nand(mtd);
310 unsigned short ecc10[8];
311 unsigned short *ecc16;
312 u32 syndrome[4];
313 unsigned num_errors, corrected;
314
315 /* All bytes 0xff? It's an erased page; ignore its ECC. */
316 for (i = 0; i < 10; i++) {
317 if (ecc_code[i] != 0xff)
318 goto compare;
319 }
320 return 0;
321
322compare:
323 /* Unpack ten bytes into eight 10 bit values. We know we're
324 * little-endian, and use type punning for less shifting/masking.
325 */
326 if (WARN_ON(0x01 & (unsigned) ecc_code))
327 return -EINVAL;
328 ecc16 = (unsigned short *)ecc_code;
329
330 ecc10[0] = (ecc16[0] >> 0) & 0x3ff;
331 ecc10[1] = ((ecc16[0] >> 10) & 0x3f) | ((ecc16[1] << 6) & 0x3c0);
332 ecc10[2] = (ecc16[1] >> 4) & 0x3ff;
333 ecc10[3] = ((ecc16[1] >> 14) & 0x3) | ((ecc16[2] << 2) & 0x3fc);
334 ecc10[4] = (ecc16[2] >> 8) | ((ecc16[3] << 8) & 0x300);
335 ecc10[5] = (ecc16[3] >> 2) & 0x3ff;
336 ecc10[6] = ((ecc16[3] >> 12) & 0xf) | ((ecc16[4] << 4) & 0x3f0);
337 ecc10[7] = (ecc16[4] >> 6) & 0x3ff;
338
339 /* Tell ECC controller about the expected ECC codes. */
340 for (i = 7; i >= 0; i--)
341 davinci_nand_writel(info, NAND_4BIT_ECC_LOAD_OFFSET, ecc10[i]);
342
343 /* Allow time for syndrome calculation ... then read it.
344 * A syndrome of all zeroes 0 means no detected errors.
345 */
346 davinci_nand_readl(info, NANDFSR_OFFSET);
347 nand_davinci_readecc_4bit(info, syndrome);
348 if (!(syndrome[0] | syndrome[1] | syndrome[2] | syndrome[3]))
349 return 0;
350
351 /* Start address calculation, and wait for it to complete.
352 * We _could_ start reading more data while this is working,
353 * to speed up the overall page read.
354 */
355 davinci_nand_writel(info, NANDFCR_OFFSET,
356 davinci_nand_readl(info, NANDFCR_OFFSET) | BIT(13));
357 for (;;) {
358 u32 fsr = davinci_nand_readl(info, NANDFSR_OFFSET);
359
360 switch ((fsr >> 8) & 0x0f) {
361 case 0: /* no error, should not happen */
362 return 0;
363 case 1: /* five or more errors detected */
364 return -EIO;
365 case 2: /* error addresses computed */
366 case 3:
367 num_errors = 1 + ((fsr >> 16) & 0x03);
368 goto correct;
369 default: /* still working on it */
370 cpu_relax();
371 continue;
372 }
373 }
374
375correct:
376 /* correct each error */
377 for (i = 0, corrected = 0; i < num_errors; i++) {
378 int error_address, error_value;
379
380 if (i > 1) {
381 error_address = davinci_nand_readl(info,
382 NAND_ERR_ADD2_OFFSET);
383 error_value = davinci_nand_readl(info,
384 NAND_ERR_ERRVAL2_OFFSET);
385 } else {
386 error_address = davinci_nand_readl(info,
387 NAND_ERR_ADD1_OFFSET);
388 error_value = davinci_nand_readl(info,
389 NAND_ERR_ERRVAL1_OFFSET);
390 }
391
392 if (i & 1) {
393 error_address >>= 16;
394 error_value >>= 16;
395 }
396 error_address &= 0x3ff;
397 error_address = (512 + 7) - error_address;
398
399 if (error_address < 512) {
400 data[error_address] ^= error_value;
401 corrected++;
402 }
403 }
404
405 return corrected;
406}
407
408/*----------------------------------------------------------------------*/
409
410/*
221 * NOTE: NAND boot requires ALE == EM_A[1], CLE == EM_A[2], so that's 411 * NOTE: NAND boot requires ALE == EM_A[1], CLE == EM_A[2], so that's
222 * how these chips are normally wired. This translates to both 8 and 16 412 * how these chips are normally wired. This translates to both 8 and 16
223 * bit busses using ALE == BIT(3) in byte addresses, and CLE == BIT(4). 413 * bit busses using ALE == BIT(3) in byte addresses, and CLE == BIT(4).
@@ -294,6 +484,23 @@ static void __init nand_dm6446evm_flash_init(struct davinci_nand_info *info)
294 484
295/*----------------------------------------------------------------------*/ 485/*----------------------------------------------------------------------*/
296 486
487/* An ECC layout for using 4-bit ECC with small-page flash, storing
488 * ten ECC bytes plus the manufacturer's bad block marker byte, and
489 * and not overlapping the default BBT markers.
490 */
491static struct nand_ecclayout hwecc4_small __initconst = {
492 .eccbytes = 10,
493 .eccpos = { 0, 1, 2, 3, 4,
494 /* offset 5 holds the badblock marker */
495 6, 7,
496 13, 14, 15, },
497 .oobfree = {
498 {.offset = 8, .length = 5, },
499 {.offset = 16, },
500 },
501};
502
503
297static int __init nand_davinci_probe(struct platform_device *pdev) 504static int __init nand_davinci_probe(struct platform_device *pdev)
298{ 505{
299 struct davinci_nand_pdata *pdata = pdev->dev.platform_data; 506 struct davinci_nand_pdata *pdata = pdev->dev.platform_data;
@@ -306,6 +513,10 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
306 uint32_t val; 513 uint32_t val;
307 nand_ecc_modes_t ecc_mode; 514 nand_ecc_modes_t ecc_mode;
308 515
516 /* insist on board-specific configuration */
517 if (!pdata)
518 return -ENODEV;
519
309 /* which external chipselect will we be managing? */ 520 /* which external chipselect will we be managing? */
310 if (pdev->id < 0 || pdev->id > 3) 521 if (pdev->id < 0 || pdev->id > 3)
311 return -ENODEV; 522 return -ENODEV;
@@ -351,7 +562,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
351 info->chip.select_chip = nand_davinci_select_chip; 562 info->chip.select_chip = nand_davinci_select_chip;
352 563
353 /* options such as NAND_USE_FLASH_BBT or 16-bit widths */ 564 /* options such as NAND_USE_FLASH_BBT or 16-bit widths */
354 info->chip.options = pdata ? pdata->options : 0; 565 info->chip.options = pdata->options;
355 566
356 info->ioaddr = (uint32_t __force) vaddr; 567 info->ioaddr = (uint32_t __force) vaddr;
357 568
@@ -360,14 +571,8 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
360 info->mask_chipsel = pdata->mask_chipsel; 571 info->mask_chipsel = pdata->mask_chipsel;
361 572
362 /* use nandboot-capable ALE/CLE masks by default */ 573 /* use nandboot-capable ALE/CLE masks by default */
363 if (pdata && pdata->mask_ale) 574 info->mask_ale = pdata->mask_cle ? : MASK_ALE;
364 info->mask_ale = pdata->mask_cle; 575 info->mask_cle = pdata->mask_cle ? : MASK_CLE;
365 else
366 info->mask_ale = MASK_ALE;
367 if (pdata && pdata->mask_cle)
368 info->mask_cle = pdata->mask_cle;
369 else
370 info->mask_cle = MASK_CLE;
371 576
372 /* Set address of hardware control function */ 577 /* Set address of hardware control function */
373 info->chip.cmd_ctrl = nand_davinci_hwcontrol; 578 info->chip.cmd_ctrl = nand_davinci_hwcontrol;
@@ -377,30 +582,44 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
377 info->chip.read_buf = nand_davinci_read_buf; 582 info->chip.read_buf = nand_davinci_read_buf;
378 info->chip.write_buf = nand_davinci_write_buf; 583 info->chip.write_buf = nand_davinci_write_buf;
379 584
380 /* use board-specific ECC config; else, the best available */ 585 /* Use board-specific ECC config */
381 if (pdata) 586 ecc_mode = pdata->ecc_mode;
382 ecc_mode = pdata->ecc_mode;
383 else
384 ecc_mode = NAND_ECC_HW;
385 587
588 ret = -EINVAL;
386 switch (ecc_mode) { 589 switch (ecc_mode) {
387 case NAND_ECC_NONE: 590 case NAND_ECC_NONE:
388 case NAND_ECC_SOFT: 591 case NAND_ECC_SOFT:
592 pdata->ecc_bits = 0;
389 break; 593 break;
390 case NAND_ECC_HW: 594 case NAND_ECC_HW:
391 info->chip.ecc.calculate = nand_davinci_calculate_1bit; 595 if (pdata->ecc_bits == 4) {
392 info->chip.ecc.correct = nand_davinci_correct_1bit; 596 /* No sanity checks: CPUs must support this,
393 info->chip.ecc.hwctl = nand_davinci_hwctl_1bit; 597 * and the chips may not use NAND_BUSWIDTH_16.
598 */
599
600 /* No sharing 4-bit hardware between chipselects yet */
601 spin_lock_irq(&davinci_nand_lock);
602 if (ecc4_busy)
603 ret = -EBUSY;
604 else
605 ecc4_busy = true;
606 spin_unlock_irq(&davinci_nand_lock);
607
608 if (ret == -EBUSY)
609 goto err_ecc;
610
611 info->chip.ecc.calculate = nand_davinci_calculate_4bit;
612 info->chip.ecc.correct = nand_davinci_correct_4bit;
613 info->chip.ecc.hwctl = nand_davinci_hwctl_4bit;
614 info->chip.ecc.bytes = 10;
615 } else {
616 info->chip.ecc.calculate = nand_davinci_calculate_1bit;
617 info->chip.ecc.correct = nand_davinci_correct_1bit;
618 info->chip.ecc.hwctl = nand_davinci_hwctl_1bit;
619 info->chip.ecc.bytes = 3;
620 }
394 info->chip.ecc.size = 512; 621 info->chip.ecc.size = 512;
395 info->chip.ecc.bytes = 3;
396 break; 622 break;
397 case NAND_ECC_HW_SYNDROME:
398 /* FIXME implement */
399 info->chip.ecc.size = 512;
400 info->chip.ecc.bytes = 10;
401
402 dev_warn(&pdev->dev, "4-bit ECC nyet supported\n");
403 /* FALL THROUGH */
404 default: 623 default:
405 ret = -EINVAL; 624 ret = -EINVAL;
406 goto err_ecc; 625 goto err_ecc;
@@ -440,12 +659,56 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
440 spin_unlock_irq(&davinci_nand_lock); 659 spin_unlock_irq(&davinci_nand_lock);
441 660
442 /* Scan to find existence of the device(s) */ 661 /* Scan to find existence of the device(s) */
443 ret = nand_scan(&info->mtd, pdata->mask_chipsel ? 2 : 1); 662 ret = nand_scan_ident(&info->mtd, pdata->mask_chipsel ? 2 : 1);
444 if (ret < 0) { 663 if (ret < 0) {
445 dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); 664 dev_dbg(&pdev->dev, "no NAND chip(s) found\n");
446 goto err_scan; 665 goto err_scan;
447 } 666 }
448 667
668 /* Update ECC layout if needed ... for 1-bit HW ECC, the default
669 * is OK, but it allocates 6 bytes when only 3 are needed (for
670 * each 512 bytes). For the 4-bit HW ECC, that default is not
671 * usable: 10 bytes are needed, not 6.
672 */
673 if (pdata->ecc_bits == 4) {
674 int chunks = info->mtd.writesize / 512;
675
676 if (!chunks || info->mtd.oobsize < 16) {
677 dev_dbg(&pdev->dev, "too small\n");
678 ret = -EINVAL;
679 goto err_scan;
680 }
681
682 /* For small page chips, preserve the manufacturer's
683 * badblock marking data ... and make sure a flash BBT
684 * table marker fits in the free bytes.
685 */
686 if (chunks == 1) {
687 info->ecclayout = hwecc4_small;
688 info->ecclayout.oobfree[1].length =
689 info->mtd.oobsize - 16;
690 goto syndrome_done;
691 }
692
693 /* For large page chips we'll be wanting to use a
694 * not-yet-implemented mode that reads OOB data
695 * before reading the body of the page, to avoid
696 * the "infix OOB" model of NAND_ECC_HW_SYNDROME
697 * (and preserve manufacturer badblock markings).
698 */
699 dev_warn(&pdev->dev, "no 4-bit ECC support yet "
700 "for large page NAND\n");
701 ret = -EIO;
702 goto err_scan;
703
704syndrome_done:
705 info->chip.ecc.layout = &info->ecclayout;
706 }
707
708 ret = nand_scan_tail(&info->mtd);
709 if (ret < 0)
710 goto err_scan;
711
449 if (mtd_has_partitions()) { 712 if (mtd_has_partitions()) {
450 struct mtd_partition *mtd_parts = NULL; 713 struct mtd_partition *mtd_parts = NULL;
451 int mtd_parts_nb = 0; 714 int mtd_parts_nb = 0;
@@ -454,22 +717,11 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
454 static const char *probes[] __initconst = 717 static const char *probes[] __initconst =
455 { "cmdlinepart", NULL }; 718 { "cmdlinepart", NULL };
456 719
457 const char *master_name;
458
459 /* Set info->mtd.name = 0 temporarily */
460 master_name = info->mtd.name;
461 info->mtd.name = (char *)0;
462
463 /* info->mtd.name == 0, means: don't bother checking
464 <mtd-id> */
465 mtd_parts_nb = parse_mtd_partitions(&info->mtd, probes, 720 mtd_parts_nb = parse_mtd_partitions(&info->mtd, probes,
466 &mtd_parts, 0); 721 &mtd_parts, 0);
467
468 /* Restore info->mtd.name */
469 info->mtd.name = master_name;
470 } 722 }
471 723
472 if (mtd_parts_nb <= 0 && pdata) { 724 if (mtd_parts_nb <= 0) {
473 mtd_parts = pdata->parts; 725 mtd_parts = pdata->parts;
474 mtd_parts_nb = pdata->nr_parts; 726 mtd_parts_nb = pdata->nr_parts;
475 } 727 }
@@ -482,7 +734,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
482 info->partitioned = true; 734 info->partitioned = true;
483 } 735 }
484 736
485 } else if (pdata && pdata->nr_parts) { 737 } else if (pdata->nr_parts) {
486 dev_warn(&pdev->dev, "ignoring %d default partitions on %s\n", 738 dev_warn(&pdev->dev, "ignoring %d default partitions on %s\n",
487 pdata->nr_parts, info->mtd.name); 739 pdata->nr_parts, info->mtd.name);
488 } 740 }
@@ -508,6 +760,11 @@ err_scan:
508err_clk_enable: 760err_clk_enable:
509 clk_put(info->clk); 761 clk_put(info->clk);
510 762
763 spin_lock_irq(&davinci_nand_lock);
764 if (ecc_mode == NAND_ECC_HW_SYNDROME)
765 ecc4_busy = false;
766 spin_unlock_irq(&davinci_nand_lock);
767
511err_ecc: 768err_ecc:
512err_clk: 769err_clk:
513err_ioremap: 770err_ioremap:
@@ -531,6 +788,11 @@ static int __exit nand_davinci_remove(struct platform_device *pdev)
531 else 788 else
532 status = del_mtd_device(&info->mtd); 789 status = del_mtd_device(&info->mtd);
533 790
791 spin_lock_irq(&davinci_nand_lock);
792 if (info->chip.ecc.mode == NAND_ECC_HW_SYNDROME)
793 ecc4_busy = false;
794 spin_unlock_irq(&davinci_nand_lock);
795
534 iounmap(info->base); 796 iounmap(info->base);
535 iounmap(info->vaddr); 797 iounmap(info->vaddr);
536 798
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 40c26080ecda..76beea40d2cf 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -138,7 +138,14 @@ static struct nand_ecclayout nand_hw_eccoob_8 = {
138static struct nand_ecclayout nand_hw_eccoob_16 = { 138static struct nand_ecclayout nand_hw_eccoob_16 = {
139 .eccbytes = 5, 139 .eccbytes = 5,
140 .eccpos = {6, 7, 8, 9, 10}, 140 .eccpos = {6, 7, 8, 9, 10},
141 .oobfree = {{0, 6}, {12, 4}, } 141 .oobfree = {{0, 5}, {11, 5}, }
142};
143
144static struct nand_ecclayout nand_hw_eccoob_64 = {
145 .eccbytes = 20,
146 .eccpos = {6, 7, 8, 9, 10, 22, 23, 24, 25, 26,
147 38, 39, 40, 41, 42, 54, 55, 56, 57, 58},
148 .oobfree = {{2, 4}, {11, 10}, {27, 10}, {43, 10}, {59, 5}, }
142}; 149};
143 150
144#ifdef CONFIG_MTD_PARTITIONS 151#ifdef CONFIG_MTD_PARTITIONS
@@ -192,7 +199,7 @@ static void wait_op_done(struct mxc_nand_host *host, int max_retries,
192 } 199 }
193 udelay(1); 200 udelay(1);
194 } 201 }
195 if (max_retries <= 0) 202 if (max_retries < 0)
196 DEBUG(MTD_DEBUG_LEVEL0, "%s(%d): INT not set\n", 203 DEBUG(MTD_DEBUG_LEVEL0, "%s(%d): INT not set\n",
197 __func__, param); 204 __func__, param);
198 } 205 }
@@ -795,9 +802,13 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
795 send_addr(host, (page_addr & 0xff), false); 802 send_addr(host, (page_addr & 0xff), false);
796 803
797 if (host->pagesize_2k) { 804 if (host->pagesize_2k) {
798 send_addr(host, (page_addr >> 8) & 0xFF, false); 805 if (mtd->size >= 0x10000000) {
799 if (mtd->size >= 0x40000000) 806 /* paddr_8 - paddr_15 */
807 send_addr(host, (page_addr >> 8) & 0xff, false);
800 send_addr(host, (page_addr >> 16) & 0xff, true); 808 send_addr(host, (page_addr >> 16) & 0xff, true);
809 } else
810 /* paddr_8 - paddr_15 */
811 send_addr(host, (page_addr >> 8) & 0xff, true);
801 } else { 812 } else {
802 /* One more address cycle for higher density devices */ 813 /* One more address cycle for higher density devices */
803 if (mtd->size >= 0x4000000) { 814 if (mtd->size >= 0x4000000) {
@@ -923,7 +934,6 @@ static int __init mxcnd_probe(struct platform_device *pdev)
923 this->ecc.mode = NAND_ECC_HW; 934 this->ecc.mode = NAND_ECC_HW;
924 this->ecc.size = 512; 935 this->ecc.size = 512;
925 this->ecc.bytes = 3; 936 this->ecc.bytes = 3;
926 this->ecc.layout = &nand_hw_eccoob_8;
927 tmp = readw(host->regs + NFC_CONFIG1); 937 tmp = readw(host->regs + NFC_CONFIG1);
928 tmp |= NFC_ECC_EN; 938 tmp |= NFC_ECC_EN;
929 writew(tmp, host->regs + NFC_CONFIG1); 939 writew(tmp, host->regs + NFC_CONFIG1);
@@ -957,12 +967,44 @@ static int __init mxcnd_probe(struct platform_device *pdev)
957 this->ecc.layout = &nand_hw_eccoob_16; 967 this->ecc.layout = &nand_hw_eccoob_16;
958 } 968 }
959 969
960 host->pagesize_2k = 0; 970 /* first scan to find the device and get the page size */
971 if (nand_scan_ident(mtd, 1)) {
972 err = -ENXIO;
973 goto escan;
974 }
961 975
962 /* Scan to find existence of the device */ 976 host->pagesize_2k = (mtd->writesize == 2048) ? 1 : 0;
963 if (nand_scan(mtd, 1)) { 977
964 DEBUG(MTD_DEBUG_LEVEL0, 978 if (this->ecc.mode == NAND_ECC_HW) {
965 "MXC_ND: Unable to find any NAND device.\n"); 979 switch (mtd->oobsize) {
980 case 8:
981 this->ecc.layout = &nand_hw_eccoob_8;
982 break;
983 case 16:
984 this->ecc.layout = &nand_hw_eccoob_16;
985 break;
986 case 64:
987 this->ecc.layout = &nand_hw_eccoob_64;
988 break;
989 default:
990 /* page size not handled by HW ECC */
991 /* switching back to soft ECC */
992 this->ecc.size = 512;
993 this->ecc.bytes = 3;
994 this->ecc.layout = &nand_hw_eccoob_8;
995 this->ecc.mode = NAND_ECC_SOFT;
996 this->ecc.calculate = NULL;
997 this->ecc.correct = NULL;
998 this->ecc.hwctl = NULL;
999 tmp = readw(host->regs + NFC_CONFIG1);
1000 tmp &= ~NFC_ECC_EN;
1001 writew(tmp, host->regs + NFC_CONFIG1);
1002 break;
1003 }
1004 }
1005
1006 /* second phase scan */
1007 if (nand_scan_tail(mtd)) {
966 err = -ENXIO; 1008 err = -ENXIO;
967 goto escan; 1009 goto escan;
968 } 1010 }
@@ -985,7 +1027,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
985 return 0; 1027 return 0;
986 1028
987escan: 1029escan:
988 free_irq(host->irq, NULL); 1030 free_irq(host->irq, host);
989eirq: 1031eirq:
990 iounmap(host->regs); 1032 iounmap(host->regs);
991eres: 1033eres:
@@ -1005,7 +1047,7 @@ static int __devexit mxcnd_remove(struct platform_device *pdev)
1005 platform_set_drvdata(pdev, NULL); 1047 platform_set_drvdata(pdev, NULL);
1006 1048
1007 nand_release(&host->mtd); 1049 nand_release(&host->mtd);
1008 free_irq(host->irq, NULL); 1050 free_irq(host->irq, host);
1009 iounmap(host->regs); 1051 iounmap(host->regs);
1010 kfree(host); 1052 kfree(host);
1011 1053
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 3d7ed432fa41..8c21b89d2d0c 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2756,7 +2756,8 @@ int nand_scan_tail(struct mtd_info *mtd)
2756 * the out of band area 2756 * the out of band area
2757 */ 2757 */
2758 chip->ecc.layout->oobavail = 0; 2758 chip->ecc.layout->oobavail = 0;
2759 for (i = 0; chip->ecc.layout->oobfree[i].length; i++) 2759 for (i = 0; chip->ecc.layout->oobfree[i].length
2760 && i < ARRAY_SIZE(chip->ecc.layout->oobfree); i++)
2760 chip->ecc.layout->oobavail += 2761 chip->ecc.layout->oobavail +=
2761 chip->ecc.layout->oobfree[i].length; 2762 chip->ecc.layout->oobfree[i].length;
2762 mtd->oobavail = chip->ecc.layout->oobavail; 2763 mtd->oobavail = chip->ecc.layout->oobavail;
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index 868147acce2c..c0cb87d6d16e 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -428,8 +428,8 @@ EXPORT_SYMBOL(nand_calculate_ecc);
428int nand_correct_data(struct mtd_info *mtd, unsigned char *buf, 428int nand_correct_data(struct mtd_info *mtd, unsigned char *buf,
429 unsigned char *read_ecc, unsigned char *calc_ecc) 429 unsigned char *read_ecc, unsigned char *calc_ecc)
430{ 430{
431 unsigned char b0, b1, b2; 431 unsigned char b0, b1, b2, bit_addr;
432 unsigned char byte_addr, bit_addr; 432 unsigned int byte_addr;
433 /* 256 or 512 bytes/ecc */ 433 /* 256 or 512 bytes/ecc */
434 const uint32_t eccsize_mult = 434 const uint32_t eccsize_mult =
435 (((struct nand_chip *)mtd->priv)->ecc.size) >> 8; 435 (((struct nand_chip *)mtd->priv)->ecc.size) >> 8;
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
new file mode 100644
index 000000000000..0cd76f89f4b0
--- /dev/null
+++ b/drivers/mtd/nand/omap2.c
@@ -0,0 +1,776 @@
1/*
2 * Copyright © 2004 Texas Instruments, Jian Zhang <jzhang@ti.com>
3 * Copyright © 2004 Micron Technology Inc.
4 * Copyright © 2004 David Brownell
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h>
13#include <linux/delay.h>
14#include <linux/mtd/mtd.h>
15#include <linux/mtd/nand.h>
16#include <linux/mtd/partitions.h>
17#include <linux/io.h>
18
19#include <asm/dma.h>
20
21#include <mach/gpmc.h>
22#include <mach/nand.h>
23
24#define GPMC_IRQ_STATUS 0x18
25#define GPMC_ECC_CONFIG 0x1F4
26#define GPMC_ECC_CONTROL 0x1F8
27#define GPMC_ECC_SIZE_CONFIG 0x1FC
28#define GPMC_ECC1_RESULT 0x200
29
30#define DRIVER_NAME "omap2-nand"
31
32/* size (4 KiB) for IO mapping */
33#define NAND_IO_SIZE SZ_4K
34
35#define NAND_WP_OFF 0
36#define NAND_WP_BIT 0x00000010
37#define WR_RD_PIN_MONITORING 0x00600000
38
39#define GPMC_BUF_FULL 0x00000001
40#define GPMC_BUF_EMPTY 0x00000000
41
42#define NAND_Ecc_P1e (1 << 0)
43#define NAND_Ecc_P2e (1 << 1)
44#define NAND_Ecc_P4e (1 << 2)
45#define NAND_Ecc_P8e (1 << 3)
46#define NAND_Ecc_P16e (1 << 4)
47#define NAND_Ecc_P32e (1 << 5)
48#define NAND_Ecc_P64e (1 << 6)
49#define NAND_Ecc_P128e (1 << 7)
50#define NAND_Ecc_P256e (1 << 8)
51#define NAND_Ecc_P512e (1 << 9)
52#define NAND_Ecc_P1024e (1 << 10)
53#define NAND_Ecc_P2048e (1 << 11)
54
55#define NAND_Ecc_P1o (1 << 16)
56#define NAND_Ecc_P2o (1 << 17)
57#define NAND_Ecc_P4o (1 << 18)
58#define NAND_Ecc_P8o (1 << 19)
59#define NAND_Ecc_P16o (1 << 20)
60#define NAND_Ecc_P32o (1 << 21)
61#define NAND_Ecc_P64o (1 << 22)
62#define NAND_Ecc_P128o (1 << 23)
63#define NAND_Ecc_P256o (1 << 24)
64#define NAND_Ecc_P512o (1 << 25)
65#define NAND_Ecc_P1024o (1 << 26)
66#define NAND_Ecc_P2048o (1 << 27)
67
68#define TF(value) (value ? 1 : 0)
69
70#define P2048e(a) (TF(a & NAND_Ecc_P2048e) << 0)
71#define P2048o(a) (TF(a & NAND_Ecc_P2048o) << 1)
72#define P1e(a) (TF(a & NAND_Ecc_P1e) << 2)
73#define P1o(a) (TF(a & NAND_Ecc_P1o) << 3)
74#define P2e(a) (TF(a & NAND_Ecc_P2e) << 4)
75#define P2o(a) (TF(a & NAND_Ecc_P2o) << 5)
76#define P4e(a) (TF(a & NAND_Ecc_P4e) << 6)
77#define P4o(a) (TF(a & NAND_Ecc_P4o) << 7)
78
79#define P8e(a) (TF(a & NAND_Ecc_P8e) << 0)
80#define P8o(a) (TF(a & NAND_Ecc_P8o) << 1)
81#define P16e(a) (TF(a & NAND_Ecc_P16e) << 2)
82#define P16o(a) (TF(a & NAND_Ecc_P16o) << 3)
83#define P32e(a) (TF(a & NAND_Ecc_P32e) << 4)
84#define P32o(a) (TF(a & NAND_Ecc_P32o) << 5)
85#define P64e(a) (TF(a & NAND_Ecc_P64e) << 6)
86#define P64o(a) (TF(a & NAND_Ecc_P64o) << 7)
87
88#define P128e(a) (TF(a & NAND_Ecc_P128e) << 0)
89#define P128o(a) (TF(a & NAND_Ecc_P128o) << 1)
90#define P256e(a) (TF(a & NAND_Ecc_P256e) << 2)
91#define P256o(a) (TF(a & NAND_Ecc_P256o) << 3)
92#define P512e(a) (TF(a & NAND_Ecc_P512e) << 4)
93#define P512o(a) (TF(a & NAND_Ecc_P512o) << 5)
94#define P1024e(a) (TF(a & NAND_Ecc_P1024e) << 6)
95#define P1024o(a) (TF(a & NAND_Ecc_P1024o) << 7)
96
97#define P8e_s(a) (TF(a & NAND_Ecc_P8e) << 0)
98#define P8o_s(a) (TF(a & NAND_Ecc_P8o) << 1)
99#define P16e_s(a) (TF(a & NAND_Ecc_P16e) << 2)
100#define P16o_s(a) (TF(a & NAND_Ecc_P16o) << 3)
101#define P1e_s(a) (TF(a & NAND_Ecc_P1e) << 4)
102#define P1o_s(a) (TF(a & NAND_Ecc_P1o) << 5)
103#define P2e_s(a) (TF(a & NAND_Ecc_P2e) << 6)
104#define P2o_s(a) (TF(a & NAND_Ecc_P2o) << 7)
105
106#define P4e_s(a) (TF(a & NAND_Ecc_P4e) << 0)
107#define P4o_s(a) (TF(a & NAND_Ecc_P4o) << 1)
108
109#ifdef CONFIG_MTD_PARTITIONS
110static const char *part_probes[] = { "cmdlinepart", NULL };
111#endif
112
113struct omap_nand_info {
114 struct nand_hw_control controller;
115 struct omap_nand_platform_data *pdata;
116 struct mtd_info mtd;
117 struct mtd_partition *parts;
118 struct nand_chip nand;
119 struct platform_device *pdev;
120
121 int gpmc_cs;
122 unsigned long phys_base;
123 void __iomem *gpmc_cs_baseaddr;
124 void __iomem *gpmc_baseaddr;
125};
126
127/**
128 * omap_nand_wp - This function enable or disable the Write Protect feature
129 * @mtd: MTD device structure
130 * @mode: WP ON/OFF
131 */
132static void omap_nand_wp(struct mtd_info *mtd, int mode)
133{
134 struct omap_nand_info *info = container_of(mtd,
135 struct omap_nand_info, mtd);
136
137 unsigned long config = __raw_readl(info->gpmc_baseaddr + GPMC_CONFIG);
138
139 if (mode)
140 config &= ~(NAND_WP_BIT); /* WP is ON */
141 else
142 config |= (NAND_WP_BIT); /* WP is OFF */
143
144 __raw_writel(config, (info->gpmc_baseaddr + GPMC_CONFIG));
145}
146
147/**
148 * omap_hwcontrol - hardware specific access to control-lines
149 * @mtd: MTD device structure
150 * @cmd: command to device
151 * @ctrl:
152 * NAND_NCE: bit 0 -> don't care
153 * NAND_CLE: bit 1 -> Command Latch
154 * NAND_ALE: bit 2 -> Address Latch
155 *
156 * NOTE: boards may use different bits for these!!
157 */
158static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
159{
160 struct omap_nand_info *info = container_of(mtd,
161 struct omap_nand_info, mtd);
162 switch (ctrl) {
163 case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
164 info->nand.IO_ADDR_W = info->gpmc_cs_baseaddr +
165 GPMC_CS_NAND_COMMAND;
166 info->nand.IO_ADDR_R = info->gpmc_cs_baseaddr +
167 GPMC_CS_NAND_DATA;
168 break;
169
170 case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
171 info->nand.IO_ADDR_W = info->gpmc_cs_baseaddr +
172 GPMC_CS_NAND_ADDRESS;
173 info->nand.IO_ADDR_R = info->gpmc_cs_baseaddr +
174 GPMC_CS_NAND_DATA;
175 break;
176
177 case NAND_CTRL_CHANGE | NAND_NCE:
178 info->nand.IO_ADDR_W = info->gpmc_cs_baseaddr +
179 GPMC_CS_NAND_DATA;
180 info->nand.IO_ADDR_R = info->gpmc_cs_baseaddr +
181 GPMC_CS_NAND_DATA;
182 break;
183 }
184
185 if (cmd != NAND_CMD_NONE)
186 __raw_writeb(cmd, info->nand.IO_ADDR_W);
187}
188
189/**
190 * omap_read_buf16 - read data from NAND controller into buffer
191 * @mtd: MTD device structure
192 * @buf: buffer to store date
193 * @len: number of bytes to read
194 */
195static void omap_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
196{
197 struct nand_chip *nand = mtd->priv;
198
199 __raw_readsw(nand->IO_ADDR_R, buf, len / 2);
200}
201
202/**
203 * omap_write_buf16 - write buffer to NAND controller
204 * @mtd: MTD device structure
205 * @buf: data buffer
206 * @len: number of bytes to write
207 */
208static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len)
209{
210 struct omap_nand_info *info = container_of(mtd,
211 struct omap_nand_info, mtd);
212 u16 *p = (u16 *) buf;
213
214 /* FIXME try bursts of writesw() or DMA ... */
215 len >>= 1;
216
217 while (len--) {
218 writew(*p++, info->nand.IO_ADDR_W);
219
220 while (GPMC_BUF_EMPTY == (readl(info->gpmc_baseaddr +
221 GPMC_STATUS) & GPMC_BUF_FULL))
222 ;
223 }
224}
225/**
226 * omap_verify_buf - Verify chip data against buffer
227 * @mtd: MTD device structure
228 * @buf: buffer containing the data to compare
229 * @len: number of bytes to compare
230 */
231static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len)
232{
233 struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
234 mtd);
235 u16 *p = (u16 *) buf;
236
237 len >>= 1;
238 while (len--) {
239 if (*p++ != cpu_to_le16(readw(info->nand.IO_ADDR_R)))
240 return -EFAULT;
241 }
242
243 return 0;
244}
245
246#ifdef CONFIG_MTD_NAND_OMAP_HWECC
247/**
248 * omap_hwecc_init - Initialize the HW ECC for NAND flash in GPMC controller
249 * @mtd: MTD device structure
250 */
251static void omap_hwecc_init(struct mtd_info *mtd)
252{
253 struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
254 mtd);
255 struct nand_chip *chip = mtd->priv;
256 unsigned long val = 0x0;
257
258 /* Read from ECC Control Register */
259 val = __raw_readl(info->gpmc_baseaddr + GPMC_ECC_CONTROL);
260 /* Clear all ECC | Enable Reg1 */
261 val = ((0x00000001<<8) | 0x00000001);
262 __raw_writel(val, info->gpmc_baseaddr + GPMC_ECC_CONTROL);
263
264 /* Read from ECC Size Config Register */
265 val = __raw_readl(info->gpmc_baseaddr + GPMC_ECC_SIZE_CONFIG);
266 /* ECCSIZE1=512 | Select eccResultsize[0-3] */
267 val = ((((chip->ecc.size >> 1) - 1) << 22) | (0x0000000F));
268 __raw_writel(val, info->gpmc_baseaddr + GPMC_ECC_SIZE_CONFIG);
269}
270
271/**
272 * gen_true_ecc - This function will generate true ECC value
273 * @ecc_buf: buffer to store ecc code
274 *
275 * This generated true ECC value can be used when correcting
276 * data read from NAND flash memory core
277 */
278static void gen_true_ecc(u8 *ecc_buf)
279{
280 u32 tmp = ecc_buf[0] | (ecc_buf[1] << 16) |
281 ((ecc_buf[2] & 0xF0) << 20) | ((ecc_buf[2] & 0x0F) << 8);
282
283 ecc_buf[0] = ~(P64o(tmp) | P64e(tmp) | P32o(tmp) | P32e(tmp) |
284 P16o(tmp) | P16e(tmp) | P8o(tmp) | P8e(tmp));
285 ecc_buf[1] = ~(P1024o(tmp) | P1024e(tmp) | P512o(tmp) | P512e(tmp) |
286 P256o(tmp) | P256e(tmp) | P128o(tmp) | P128e(tmp));
287 ecc_buf[2] = ~(P4o(tmp) | P4e(tmp) | P2o(tmp) | P2e(tmp) | P1o(tmp) |
288 P1e(tmp) | P2048o(tmp) | P2048e(tmp));
289}
290
291/**
292 * omap_compare_ecc - Detect (2 bits) and correct (1 bit) error in data
293 * @ecc_data1: ecc code from nand spare area
294 * @ecc_data2: ecc code from hardware register obtained from hardware ecc
295 * @page_data: page data
296 *
297 * This function compares two ECC's and indicates if there is an error.
298 * If the error can be corrected it will be corrected to the buffer.
299 */
300static int omap_compare_ecc(u8 *ecc_data1, /* read from NAND memory */
301 u8 *ecc_data2, /* read from register */
302 u8 *page_data)
303{
304 uint i;
305 u8 tmp0_bit[8], tmp1_bit[8], tmp2_bit[8];
306 u8 comp0_bit[8], comp1_bit[8], comp2_bit[8];
307 u8 ecc_bit[24];
308 u8 ecc_sum = 0;
309 u8 find_bit = 0;
310 uint find_byte = 0;
311 int isEccFF;
312
313 isEccFF = ((*(u32 *)ecc_data1 & 0xFFFFFF) == 0xFFFFFF);
314
315 gen_true_ecc(ecc_data1);
316 gen_true_ecc(ecc_data2);
317
318 for (i = 0; i <= 2; i++) {
319 *(ecc_data1 + i) = ~(*(ecc_data1 + i));
320 *(ecc_data2 + i) = ~(*(ecc_data2 + i));
321 }
322
323 for (i = 0; i < 8; i++) {
324 tmp0_bit[i] = *ecc_data1 % 2;
325 *ecc_data1 = *ecc_data1 / 2;
326 }
327
328 for (i = 0; i < 8; i++) {
329 tmp1_bit[i] = *(ecc_data1 + 1) % 2;
330 *(ecc_data1 + 1) = *(ecc_data1 + 1) / 2;
331 }
332
333 for (i = 0; i < 8; i++) {
334 tmp2_bit[i] = *(ecc_data1 + 2) % 2;
335 *(ecc_data1 + 2) = *(ecc_data1 + 2) / 2;
336 }
337
338 for (i = 0; i < 8; i++) {
339 comp0_bit[i] = *ecc_data2 % 2;
340 *ecc_data2 = *ecc_data2 / 2;
341 }
342
343 for (i = 0; i < 8; i++) {
344 comp1_bit[i] = *(ecc_data2 + 1) % 2;
345 *(ecc_data2 + 1) = *(ecc_data2 + 1) / 2;
346 }
347
348 for (i = 0; i < 8; i++) {
349 comp2_bit[i] = *(ecc_data2 + 2) % 2;
350 *(ecc_data2 + 2) = *(ecc_data2 + 2) / 2;
351 }
352
353 for (i = 0; i < 6; i++)
354 ecc_bit[i] = tmp2_bit[i + 2] ^ comp2_bit[i + 2];
355
356 for (i = 0; i < 8; i++)
357 ecc_bit[i + 6] = tmp0_bit[i] ^ comp0_bit[i];
358
359 for (i = 0; i < 8; i++)
360 ecc_bit[i + 14] = tmp1_bit[i] ^ comp1_bit[i];
361
362 ecc_bit[22] = tmp2_bit[0] ^ comp2_bit[0];
363 ecc_bit[23] = tmp2_bit[1] ^ comp2_bit[1];
364
365 for (i = 0; i < 24; i++)
366 ecc_sum += ecc_bit[i];
367
368 switch (ecc_sum) {
369 case 0:
370 /* Not reached because this function is not called if
371 * ECC values are equal
372 */
373 return 0;
374
375 case 1:
376 /* Uncorrectable error */
377 DEBUG(MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR 1\n");
378 return -1;
379
380 case 11:
381 /* UN-Correctable error */
382 DEBUG(MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR B\n");
383 return -1;
384
385 case 12:
386 /* Correctable error */
387 find_byte = (ecc_bit[23] << 8) +
388 (ecc_bit[21] << 7) +
389 (ecc_bit[19] << 6) +
390 (ecc_bit[17] << 5) +
391 (ecc_bit[15] << 4) +
392 (ecc_bit[13] << 3) +
393 (ecc_bit[11] << 2) +
394 (ecc_bit[9] << 1) +
395 ecc_bit[7];
396
397 find_bit = (ecc_bit[5] << 2) + (ecc_bit[3] << 1) + ecc_bit[1];
398
399 DEBUG(MTD_DEBUG_LEVEL0, "Correcting single bit ECC error at "
400 "offset: %d, bit: %d\n", find_byte, find_bit);
401
402 page_data[find_byte] ^= (1 << find_bit);
403
404 return 0;
405 default:
406 if (isEccFF) {
407 if (ecc_data2[0] == 0 &&
408 ecc_data2[1] == 0 &&
409 ecc_data2[2] == 0)
410 return 0;
411 }
412 DEBUG(MTD_DEBUG_LEVEL0, "UNCORRECTED_ERROR default\n");
413 return -1;
414 }
415}
416
417/**
418 * omap_correct_data - Compares the ECC read with HW generated ECC
419 * @mtd: MTD device structure
420 * @dat: page data
421 * @read_ecc: ecc read from nand flash
422 * @calc_ecc: ecc read from HW ECC registers
423 *
424 * Compares the ecc read from nand spare area with ECC registers values
425 * and if ECC's mismached, it will call 'omap_compare_ecc' for error detection
426 * and correction.
427 */
428static int omap_correct_data(struct mtd_info *mtd, u_char *dat,
429 u_char *read_ecc, u_char *calc_ecc)
430{
431 struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
432 mtd);
433 int blockCnt = 0, i = 0, ret = 0;
434
435 /* Ex NAND_ECC_HW12_2048 */
436 if ((info->nand.ecc.mode == NAND_ECC_HW) &&
437 (info->nand.ecc.size == 2048))
438 blockCnt = 4;
439 else
440 blockCnt = 1;
441
442 for (i = 0; i < blockCnt; i++) {
443 if (memcmp(read_ecc, calc_ecc, 3) != 0) {
444 ret = omap_compare_ecc(read_ecc, calc_ecc, dat);
445 if (ret < 0)
446 return ret;
447 }
448 read_ecc += 3;
449 calc_ecc += 3;
450 dat += 512;
451 }
452 return 0;
453}
454
455/**
456 * omap_calcuate_ecc - Generate non-inverted ECC bytes.
457 * @mtd: MTD device structure
458 * @dat: The pointer to data on which ecc is computed
459 * @ecc_code: The ecc_code buffer
460 *
461 * Using noninverted ECC can be considered ugly since writing a blank
462 * page ie. padding will clear the ECC bytes. This is no problem as long
463 * nobody is trying to write data on the seemingly unused page. Reading
464 * an erased page will produce an ECC mismatch between generated and read
465 * ECC bytes that has to be dealt with separately.
466 */
467static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
468 u_char *ecc_code)
469{
470 struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
471 mtd);
472 unsigned long val = 0x0;
473 unsigned long reg;
474
475 /* Start Reading from HW ECC1_Result = 0x200 */
476 reg = (unsigned long)(info->gpmc_baseaddr + GPMC_ECC1_RESULT);
477 val = __raw_readl(reg);
478 *ecc_code++ = val; /* P128e, ..., P1e */
479 *ecc_code++ = val >> 16; /* P128o, ..., P1o */
480 /* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */
481 *ecc_code++ = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0);
482 reg += 4;
483
484 return 0;
485}
486
487/**
488 * omap_enable_hwecc - This function enables the hardware ecc functionality
489 * @mtd: MTD device structure
490 * @mode: Read/Write mode
491 */
492static void omap_enable_hwecc(struct mtd_info *mtd, int mode)
493{
494 struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
495 mtd);
496 struct nand_chip *chip = mtd->priv;
497 unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
498 unsigned long val = __raw_readl(info->gpmc_baseaddr + GPMC_ECC_CONFIG);
499
500 switch (mode) {
501 case NAND_ECC_READ:
502 __raw_writel(0x101, info->gpmc_baseaddr + GPMC_ECC_CONTROL);
503 /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */
504 val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1);
505 break;
506 case NAND_ECC_READSYN:
507 __raw_writel(0x100, info->gpmc_baseaddr + GPMC_ECC_CONTROL);
508 /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */
509 val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1);
510 break;
511 case NAND_ECC_WRITE:
512 __raw_writel(0x101, info->gpmc_baseaddr + GPMC_ECC_CONTROL);
513 /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */
514 val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1);
515 break;
516 default:
517 DEBUG(MTD_DEBUG_LEVEL0, "Error: Unrecognized Mode[%d]!\n",
518 mode);
519 break;
520 }
521
522 __raw_writel(val, info->gpmc_baseaddr + GPMC_ECC_CONFIG);
523}
524#endif
525
526/**
527 * omap_wait - wait until the command is done
528 * @mtd: MTD device structure
529 * @chip: NAND Chip structure
530 *
531 * Wait function is called during Program and erase operations and
532 * the way it is called from MTD layer, we should wait till the NAND
533 * chip is ready after the programming/erase operation has completed.
534 *
535 * Erase can take up to 400ms and program up to 20ms according to
536 * general NAND and SmartMedia specs
537 */
538static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
539{
540 struct nand_chip *this = mtd->priv;
541 struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
542 mtd);
543 unsigned long timeo = jiffies;
544 int status, state = this->state;
545
546 if (state == FL_ERASING)
547 timeo += (HZ * 400) / 1000;
548 else
549 timeo += (HZ * 20) / 1000;
550
551 this->IO_ADDR_W = (void *) info->gpmc_cs_baseaddr +
552 GPMC_CS_NAND_COMMAND;
553 this->IO_ADDR_R = (void *) info->gpmc_cs_baseaddr + GPMC_CS_NAND_DATA;
554
555 __raw_writeb(NAND_CMD_STATUS & 0xFF, this->IO_ADDR_W);
556
557 while (time_before(jiffies, timeo)) {
558 status = __raw_readb(this->IO_ADDR_R);
559 if (!(status & 0x40))
560 break;
561 }
562 return status;
563}
564
565/**
566 * omap_dev_ready - calls the platform specific dev_ready function
567 * @mtd: MTD device structure
568 */
569static int omap_dev_ready(struct mtd_info *mtd)
570{
571 struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
572 mtd);
573 unsigned int val = __raw_readl(info->gpmc_baseaddr + GPMC_IRQ_STATUS);
574
575 if ((val & 0x100) == 0x100) {
576 /* Clear IRQ Interrupt */
577 val |= 0x100;
578 val &= ~(0x0);
579 __raw_writel(val, info->gpmc_baseaddr + GPMC_IRQ_STATUS);
580 } else {
581 unsigned int cnt = 0;
582 while (cnt++ < 0x1FF) {
583 if ((val & 0x100) == 0x100)
584 return 0;
585 val = __raw_readl(info->gpmc_baseaddr +
586 GPMC_IRQ_STATUS);
587 }
588 }
589
590 return 1;
591}
592
593static int __devinit omap_nand_probe(struct platform_device *pdev)
594{
595 struct omap_nand_info *info;
596 struct omap_nand_platform_data *pdata;
597 int err;
598 unsigned long val;
599
600
601 pdata = pdev->dev.platform_data;
602 if (pdata == NULL) {
603 dev_err(&pdev->dev, "platform data missing\n");
604 return -ENODEV;
605 }
606
607 info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL);
608 if (!info)
609 return -ENOMEM;
610
611 platform_set_drvdata(pdev, info);
612
613 spin_lock_init(&info->controller.lock);
614 init_waitqueue_head(&info->controller.wq);
615
616 info->pdev = pdev;
617
618 info->gpmc_cs = pdata->cs;
619 info->gpmc_baseaddr = pdata->gpmc_baseaddr;
620 info->gpmc_cs_baseaddr = pdata->gpmc_cs_baseaddr;
621
622 info->mtd.priv = &info->nand;
623 info->mtd.name = dev_name(&pdev->dev);
624 info->mtd.owner = THIS_MODULE;
625
626 err = gpmc_cs_request(info->gpmc_cs, NAND_IO_SIZE, &info->phys_base);
627 if (err < 0) {
628 dev_err(&pdev->dev, "Cannot request GPMC CS\n");
629 goto out_free_info;
630 }
631
632 /* Enable RD PIN Monitoring Reg */
633 if (pdata->dev_ready) {
634 val = gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG1);
635 val |= WR_RD_PIN_MONITORING;
636 gpmc_cs_write_reg(info->gpmc_cs, GPMC_CS_CONFIG1, val);
637 }
638
639 val = gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG7);
640 val &= ~(0xf << 8);
641 val |= (0xc & 0xf) << 8;
642 gpmc_cs_write_reg(info->gpmc_cs, GPMC_CS_CONFIG7, val);
643
644 /* NAND write protect off */
645 omap_nand_wp(&info->mtd, NAND_WP_OFF);
646
647 if (!request_mem_region(info->phys_base, NAND_IO_SIZE,
648 pdev->dev.driver->name)) {
649 err = -EBUSY;
650 goto out_free_cs;
651 }
652
653 info->nand.IO_ADDR_R = ioremap(info->phys_base, NAND_IO_SIZE);
654 if (!info->nand.IO_ADDR_R) {
655 err = -ENOMEM;
656 goto out_release_mem_region;
657 }
658 info->nand.controller = &info->controller;
659
660 info->nand.IO_ADDR_W = info->nand.IO_ADDR_R;
661 info->nand.cmd_ctrl = omap_hwcontrol;
662
663 /* REVISIT: only supports 16-bit NAND flash */
664
665 info->nand.read_buf = omap_read_buf16;
666 info->nand.write_buf = omap_write_buf16;
667 info->nand.verify_buf = omap_verify_buf;
668
669 /*
670 * If RDY/BSY line is connected to OMAP then use the omap ready
671 * funcrtion and the generic nand_wait function which reads the status
672 * register after monitoring the RDY/BSY line.Otherwise use a standard
673 * chip delay which is slightly more than tR (AC Timing) of the NAND
674 * device and read status register until you get a failure or success
675 */
676 if (pdata->dev_ready) {
677 info->nand.dev_ready = omap_dev_ready;
678 info->nand.chip_delay = 0;
679 } else {
680 info->nand.waitfunc = omap_wait;
681 info->nand.chip_delay = 50;
682 }
683
684 info->nand.options |= NAND_SKIP_BBTSCAN;
685 if ((gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG1) & 0x3000)
686 == 0x1000)
687 info->nand.options |= NAND_BUSWIDTH_16;
688
689#ifdef CONFIG_MTD_NAND_OMAP_HWECC
690 info->nand.ecc.bytes = 3;
691 info->nand.ecc.size = 512;
692 info->nand.ecc.calculate = omap_calculate_ecc;
693 info->nand.ecc.hwctl = omap_enable_hwecc;
694 info->nand.ecc.correct = omap_correct_data;
695 info->nand.ecc.mode = NAND_ECC_HW;
696
697 /* init HW ECC */
698 omap_hwecc_init(&info->mtd);
699#else
700 info->nand.ecc.mode = NAND_ECC_SOFT;
701#endif
702
703 /* DIP switches on some boards change between 8 and 16 bit
704 * bus widths for flash. Try the other width if the first try fails.
705 */
706 if (nand_scan(&info->mtd, 1)) {
707 info->nand.options ^= NAND_BUSWIDTH_16;
708 if (nand_scan(&info->mtd, 1)) {
709 err = -ENXIO;
710 goto out_release_mem_region;
711 }
712 }
713
714#ifdef CONFIG_MTD_PARTITIONS
715 err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);
716 if (err > 0)
717 add_mtd_partitions(&info->mtd, info->parts, err);
718 else if (pdata->parts)
719 add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts);
720 else
721#endif
722 add_mtd_device(&info->mtd);
723
724 platform_set_drvdata(pdev, &info->mtd);
725
726 return 0;
727
728out_release_mem_region:
729 release_mem_region(info->phys_base, NAND_IO_SIZE);
730out_free_cs:
731 gpmc_cs_free(info->gpmc_cs);
732out_free_info:
733 kfree(info);
734
735 return err;
736}
737
738static int omap_nand_remove(struct platform_device *pdev)
739{
740 struct mtd_info *mtd = platform_get_drvdata(pdev);
741 struct omap_nand_info *info = mtd->priv;
742
743 platform_set_drvdata(pdev, NULL);
744 /* Release NAND device, its internal structures and partitions */
745 nand_release(&info->mtd);
746 iounmap(info->nand.IO_ADDR_R);
747 kfree(&info->mtd);
748 return 0;
749}
750
751static struct platform_driver omap_nand_driver = {
752 .probe = omap_nand_probe,
753 .remove = omap_nand_remove,
754 .driver = {
755 .name = DRIVER_NAME,
756 .owner = THIS_MODULE,
757 },
758};
759
760static int __init omap_nand_init(void)
761{
762 printk(KERN_INFO "%s driver initializing\n", DRIVER_NAME);
763 return platform_driver_register(&omap_nand_driver);
764}
765
766static void __exit omap_nand_exit(void)
767{
768 platform_driver_unregister(&omap_nand_driver);
769}
770
771module_init(omap_nand_init);
772module_exit(omap_nand_exit);
773
774MODULE_ALIAS(DRIVER_NAME);
775MODULE_LICENSE("GPL");
776MODULE_DESCRIPTION("Glue layer for NAND flash on TI OMAP boards");
diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c
index 86e1d08eee00..4e16c6f5bdd5 100644
--- a/drivers/mtd/nand/plat_nand.c
+++ b/drivers/mtd/nand/plat_nand.c
@@ -61,6 +61,8 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
61 data->chip.cmd_ctrl = pdata->ctrl.cmd_ctrl; 61 data->chip.cmd_ctrl = pdata->ctrl.cmd_ctrl;
62 data->chip.dev_ready = pdata->ctrl.dev_ready; 62 data->chip.dev_ready = pdata->ctrl.dev_ready;
63 data->chip.select_chip = pdata->ctrl.select_chip; 63 data->chip.select_chip = pdata->ctrl.select_chip;
64 data->chip.write_buf = pdata->ctrl.write_buf;
65 data->chip.read_buf = pdata->ctrl.read_buf;
64 data->chip.chip_delay = pdata->chip.chip_delay; 66 data->chip.chip_delay = pdata->chip.chip_delay;
65 data->chip.options |= pdata->chip.options; 67 data->chip.options |= pdata->chip.options;
66 68
@@ -70,6 +72,13 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
70 72
71 platform_set_drvdata(pdev, data); 73 platform_set_drvdata(pdev, data);
72 74
75 /* Handle any platform specific setup */
76 if (pdata->ctrl.probe) {
77 res = pdata->ctrl.probe(pdev);
78 if (res)
79 goto out;
80 }
81
73 /* Scan to find existance of the device */ 82 /* Scan to find existance of the device */
74 if (nand_scan(&data->mtd, 1)) { 83 if (nand_scan(&data->mtd, 1)) {
75 res = -ENXIO; 84 res = -ENXIO;
@@ -86,6 +95,8 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
86 return 0; 95 return 0;
87 } 96 }
88 } 97 }
98 if (pdata->chip.set_parts)
99 pdata->chip.set_parts(data->mtd.size, &pdata->chip);
89 if (pdata->chip.partitions) { 100 if (pdata->chip.partitions) {
90 data->parts = pdata->chip.partitions; 101 data->parts = pdata->chip.partitions;
91 res = add_mtd_partitions(&data->mtd, data->parts, 102 res = add_mtd_partitions(&data->mtd, data->parts,
@@ -99,6 +110,8 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
99 110
100 nand_release(&data->mtd); 111 nand_release(&data->mtd);
101out: 112out:
113 if (pdata->ctrl.remove)
114 pdata->ctrl.remove(pdev);
102 platform_set_drvdata(pdev, NULL); 115 platform_set_drvdata(pdev, NULL);
103 iounmap(data->io_base); 116 iounmap(data->io_base);
104 kfree(data); 117 kfree(data);
@@ -111,15 +124,15 @@ out:
111static int __devexit plat_nand_remove(struct platform_device *pdev) 124static int __devexit plat_nand_remove(struct platform_device *pdev)
112{ 125{
113 struct plat_nand_data *data = platform_get_drvdata(pdev); 126 struct plat_nand_data *data = platform_get_drvdata(pdev);
114#ifdef CONFIG_MTD_PARTITIONS
115 struct platform_nand_data *pdata = pdev->dev.platform_data; 127 struct platform_nand_data *pdata = pdev->dev.platform_data;
116#endif
117 128
118 nand_release(&data->mtd); 129 nand_release(&data->mtd);
119#ifdef CONFIG_MTD_PARTITIONS 130#ifdef CONFIG_MTD_PARTITIONS
120 if (data->parts && data->parts != pdata->chip.partitions) 131 if (data->parts && data->parts != pdata->chip.partitions)
121 kfree(data->parts); 132 kfree(data->parts);
122#endif 133#endif
134 if (pdata->ctrl.remove)
135 pdata->ctrl.remove(pdev);
123 iounmap(data->io_base); 136 iounmap(data->io_base);
124 kfree(data); 137 kfree(data);
125 138
@@ -128,7 +141,7 @@ static int __devexit plat_nand_remove(struct platform_device *pdev)
128 141
129static struct platform_driver plat_nand_driver = { 142static struct platform_driver plat_nand_driver = {
130 .probe = plat_nand_probe, 143 .probe = plat_nand_probe,
131 .remove = plat_nand_remove, 144 .remove = __devexit_p(plat_nand_remove),
132 .driver = { 145 .driver = {
133 .name = "gen_nand", 146 .name = "gen_nand",
134 .owner = THIS_MODULE, 147 .owner = THIS_MODULE,
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index 89b79051cc68..01a105eda3f4 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -253,9 +253,9 @@ static int s3c2410_nand_setrate(struct s3c2410_nand_info *info)
253 253
254 case TYPE_S3C2440: 254 case TYPE_S3C2440:
255 case TYPE_S3C2412: 255 case TYPE_S3C2412:
256 mask = (S3C2410_NFCONF_TACLS(tacls_max - 1) | 256 mask = (S3C2440_NFCONF_TACLS(tacls_max - 1) |
257 S3C2410_NFCONF_TWRPH0(7) | 257 S3C2440_NFCONF_TWRPH0(7) |
258 S3C2410_NFCONF_TWRPH1(7)); 258 S3C2440_NFCONF_TWRPH1(7));
259 259
260 set = S3C2440_NFCONF_TACLS(tacls - 1); 260 set = S3C2440_NFCONF_TACLS(tacls - 1);
261 set |= S3C2440_NFCONF_TWRPH0(twrph0 - 1); 261 set |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);
diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c
index 812479264896..5f919e63b29b 100644
--- a/drivers/mtd/nand/txx9ndfmc.c
+++ b/drivers/mtd/nand/txx9ndfmc.c
@@ -64,7 +64,7 @@ struct txx9ndfmc_priv {
64 struct nand_chip chip; 64 struct nand_chip chip;
65 struct mtd_info mtd; 65 struct mtd_info mtd;
66 int cs; 66 int cs;
67 char mtdname[BUS_ID_SIZE + 2]; 67 const char *mtdname;
68}; 68};
69 69
70#define MAX_TXX9NDFMC_DEV 4 70#define MAX_TXX9NDFMC_DEV 4
@@ -334,11 +334,17 @@ static int __init txx9ndfmc_probe(struct platform_device *dev)
334 334
335 if (plat->ch_mask != 1) { 335 if (plat->ch_mask != 1) {
336 txx9_priv->cs = i; 336 txx9_priv->cs = i;
337 sprintf(txx9_priv->mtdname, "%s.%u", 337 txx9_priv->mtdname = kasprintf(GFP_KERNEL, "%s.%u",
338 dev_name(&dev->dev), i); 338 dev_name(&dev->dev), i);
339 if (!txx9_priv->mtdname) {
340 kfree(txx9_priv);
341 dev_err(&dev->dev,
342 "Unable to allocate TXx9 NDFMC MTD device name.\n");
343 continue;
344 }
339 } else { 345 } else {
340 txx9_priv->cs = -1; 346 txx9_priv->cs = -1;
341 strcpy(txx9_priv->mtdname, dev_name(&dev->dev)); 347 txx9_priv->mtdname = dev_name(&dev->dev);
342 } 348 }
343 if (plat->wide_mask & (1 << i)) 349 if (plat->wide_mask & (1 << i))
344 chip->options |= NAND_BUSWIDTH_16; 350 chip->options |= NAND_BUSWIDTH_16;
@@ -385,6 +391,8 @@ static int __exit txx9ndfmc_remove(struct platform_device *dev)
385 kfree(drvdata->parts[i]); 391 kfree(drvdata->parts[i]);
386#endif 392#endif
387 del_mtd_device(mtd); 393 del_mtd_device(mtd);
394 if (txx9_priv->mtdname != dev_name(&dev->dev))
395 kfree(txx9_priv->mtdname);
388 kfree(txx9_priv); 396 kfree(txx9_priv);
389 } 397 }
390 return 0; 398 return 0;
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index f2e9de1414df..df26db863f2f 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -566,7 +566,7 @@ int omap2_onenand_rephase(void)
566 NULL, __adjust_timing); 566 NULL, __adjust_timing);
567} 567}
568 568
569static void __devexit omap2_onenand_shutdown(struct platform_device *pdev) 569static void omap2_onenand_shutdown(struct platform_device *pdev)
570{ 570{
571 struct omap2_onenand *c = dev_get_drvdata(&pdev->dev); 571 struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
572 572
@@ -778,7 +778,7 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev)
778 778
779static struct platform_driver omap2_onenand_driver = { 779static struct platform_driver omap2_onenand_driver = {
780 .probe = omap2_onenand_probe, 780 .probe = omap2_onenand_probe,
781 .remove = omap2_onenand_remove, 781 .remove = __devexit_p(omap2_onenand_remove),
782 .shutdown = omap2_onenand_shutdown, 782 .shutdown = omap2_onenand_shutdown,
783 .driver = { 783 .driver = {
784 .name = DRIVER_NAME, 784 .name = DRIVER_NAME,
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 30d6999e5f9f..864327ed7fb3 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -9,6 +9,10 @@
9 * auto-placement support, read-while load support, various fixes 9 * auto-placement support, read-while load support, various fixes
10 * Copyright (C) Nokia Corporation, 2007 10 * Copyright (C) Nokia Corporation, 2007
11 * 11 *
12 * Vishak G <vishak.g at samsung.com>, Rohit Hagargundgi <h.rohit at samsung.com>
13 * Flex-OneNAND support
14 * Copyright (C) Samsung Electronics, 2008
15 *
12 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as 17 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation. 18 * published by the Free Software Foundation.
@@ -27,6 +31,30 @@
27 31
28#include <asm/io.h> 32#include <asm/io.h>
29 33
34/* Default Flex-OneNAND boundary and lock respectively */
35static int flex_bdry[MAX_DIES * 2] = { -1, 0, -1, 0 };
36
37/**
38 * onenand_oob_128 - oob info for Flex-Onenand with 4KB page
39 * For now, we expose only 64 out of 80 ecc bytes
40 */
41static struct nand_ecclayout onenand_oob_128 = {
42 .eccbytes = 64,
43 .eccpos = {
44 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
45 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
46 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
47 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
48 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
49 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
50 102, 103, 104, 105
51 },
52 .oobfree = {
53 {2, 4}, {18, 4}, {34, 4}, {50, 4},
54 {66, 4}, {82, 4}, {98, 4}, {114, 4}
55 }
56};
57
30/** 58/**
31 * onenand_oob_64 - oob info for large (2KB) page 59 * onenand_oob_64 - oob info for large (2KB) page
32 */ 60 */
@@ -65,6 +93,14 @@ static const unsigned char ffchars[] = {
65 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */ 93 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */
66 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 94 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
67 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */ 95 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */
96 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
97 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 80 */
98 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
99 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 96 */
100 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
101 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 112 */
102 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
103 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 128 */
68}; 104};
69 105
70/** 106/**
@@ -171,6 +207,70 @@ static int onenand_buffer_address(int dataram1, int sectors, int count)
171} 207}
172 208
173/** 209/**
210 * flexonenand_block- For given address return block number
211 * @param this - OneNAND device structure
212 * @param addr - Address for which block number is needed
213 */
214static unsigned flexonenand_block(struct onenand_chip *this, loff_t addr)
215{
216 unsigned boundary, blk, die = 0;
217
218 if (ONENAND_IS_DDP(this) && addr >= this->diesize[0]) {
219 die = 1;
220 addr -= this->diesize[0];
221 }
222
223 boundary = this->boundary[die];
224
225 blk = addr >> (this->erase_shift - 1);
226 if (blk > boundary)
227 blk = (blk + boundary + 1) >> 1;
228
229 blk += die ? this->density_mask : 0;
230 return blk;
231}
232
233inline unsigned onenand_block(struct onenand_chip *this, loff_t addr)
234{
235 if (!FLEXONENAND(this))
236 return addr >> this->erase_shift;
237 return flexonenand_block(this, addr);
238}
239
240/**
241 * flexonenand_addr - Return address of the block
242 * @this: OneNAND device structure
243 * @block: Block number on Flex-OneNAND
244 *
245 * Return address of the block
246 */
247static loff_t flexonenand_addr(struct onenand_chip *this, int block)
248{
249 loff_t ofs = 0;
250 int die = 0, boundary;
251
252 if (ONENAND_IS_DDP(this) && block >= this->density_mask) {
253 block -= this->density_mask;
254 die = 1;
255 ofs = this->diesize[0];
256 }
257
258 boundary = this->boundary[die];
259 ofs += (loff_t)block << (this->erase_shift - 1);
260 if (block > (boundary + 1))
261 ofs += (loff_t)(block - boundary - 1) << (this->erase_shift - 1);
262 return ofs;
263}
264
265loff_t onenand_addr(struct onenand_chip *this, int block)
266{
267 if (!FLEXONENAND(this))
268 return (loff_t)block << this->erase_shift;
269 return flexonenand_addr(this, block);
270}
271EXPORT_SYMBOL(onenand_addr);
272
273/**
174 * onenand_get_density - [DEFAULT] Get OneNAND density 274 * onenand_get_density - [DEFAULT] Get OneNAND density
175 * @param dev_id OneNAND device ID 275 * @param dev_id OneNAND device ID
176 * 276 *
@@ -183,6 +283,22 @@ static inline int onenand_get_density(int dev_id)
183} 283}
184 284
185/** 285/**
286 * flexonenand_region - [Flex-OneNAND] Return erase region of addr
287 * @param mtd MTD device structure
288 * @param addr address whose erase region needs to be identified
289 */
290int flexonenand_region(struct mtd_info *mtd, loff_t addr)
291{
292 int i;
293
294 for (i = 0; i < mtd->numeraseregions; i++)
295 if (addr < mtd->eraseregions[i].offset)
296 break;
297 return i - 1;
298}
299EXPORT_SYMBOL(flexonenand_region);
300
301/**
186 * onenand_command - [DEFAULT] Send command to OneNAND device 302 * onenand_command - [DEFAULT] Send command to OneNAND device
187 * @param mtd MTD device structure 303 * @param mtd MTD device structure
188 * @param cmd the command to be sent 304 * @param cmd the command to be sent
@@ -207,16 +323,28 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
207 page = -1; 323 page = -1;
208 break; 324 break;
209 325
326 case FLEXONENAND_CMD_PI_ACCESS:
327 /* addr contains die index */
328 block = addr * this->density_mask;
329 page = -1;
330 break;
331
210 case ONENAND_CMD_ERASE: 332 case ONENAND_CMD_ERASE:
211 case ONENAND_CMD_BUFFERRAM: 333 case ONENAND_CMD_BUFFERRAM:
212 case ONENAND_CMD_OTP_ACCESS: 334 case ONENAND_CMD_OTP_ACCESS:
213 block = (int) (addr >> this->erase_shift); 335 block = onenand_block(this, addr);
214 page = -1; 336 page = -1;
215 break; 337 break;
216 338
339 case FLEXONENAND_CMD_READ_PI:
340 cmd = ONENAND_CMD_READ;
341 block = addr * this->density_mask;
342 page = 0;
343 break;
344
217 default: 345 default:
218 block = (int) (addr >> this->erase_shift); 346 block = onenand_block(this, addr);
219 page = (int) (addr >> this->page_shift); 347 page = (int) (addr - onenand_addr(this, block)) >> this->page_shift;
220 348
221 if (ONENAND_IS_2PLANE(this)) { 349 if (ONENAND_IS_2PLANE(this)) {
222 /* Make the even block number */ 350 /* Make the even block number */
@@ -236,7 +364,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
236 value = onenand_bufferram_address(this, block); 364 value = onenand_bufferram_address(this, block);
237 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); 365 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
238 366
239 if (ONENAND_IS_2PLANE(this)) 367 if (ONENAND_IS_MLC(this) || ONENAND_IS_2PLANE(this))
240 /* It is always BufferRAM0 */ 368 /* It is always BufferRAM0 */
241 ONENAND_SET_BUFFERRAM0(this); 369 ONENAND_SET_BUFFERRAM0(this);
242 else 370 else
@@ -258,13 +386,18 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
258 386
259 if (page != -1) { 387 if (page != -1) {
260 /* Now we use page size operation */ 388 /* Now we use page size operation */
261 int sectors = 4, count = 4; 389 int sectors = 0, count = 0;
262 int dataram; 390 int dataram;
263 391
264 switch (cmd) { 392 switch (cmd) {
393 case FLEXONENAND_CMD_RECOVER_LSB:
265 case ONENAND_CMD_READ: 394 case ONENAND_CMD_READ:
266 case ONENAND_CMD_READOOB: 395 case ONENAND_CMD_READOOB:
267 dataram = ONENAND_SET_NEXT_BUFFERRAM(this); 396 if (ONENAND_IS_MLC(this))
397 /* It is always BufferRAM0 */
398 dataram = ONENAND_SET_BUFFERRAM0(this);
399 else
400 dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
268 break; 401 break;
269 402
270 default: 403 default:
@@ -293,6 +426,30 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
293} 426}
294 427
295/** 428/**
429 * onenand_read_ecc - return ecc status
430 * @param this onenand chip structure
431 */
432static inline int onenand_read_ecc(struct onenand_chip *this)
433{
434 int ecc, i, result = 0;
435
436 if (!FLEXONENAND(this))
437 return this->read_word(this->base + ONENAND_REG_ECC_STATUS);
438
439 for (i = 0; i < 4; i++) {
440 ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS + i);
441 if (likely(!ecc))
442 continue;
443 if (ecc & FLEXONENAND_UNCORRECTABLE_ERROR)
444 return ONENAND_ECC_2BIT_ALL;
445 else
446 result = ONENAND_ECC_1BIT_ALL;
447 }
448
449 return result;
450}
451
452/**
296 * onenand_wait - [DEFAULT] wait until the command is done 453 * onenand_wait - [DEFAULT] wait until the command is done
297 * @param mtd MTD device structure 454 * @param mtd MTD device structure
298 * @param state state to select the max. timeout value 455 * @param state state to select the max. timeout value
@@ -331,14 +488,14 @@ static int onenand_wait(struct mtd_info *mtd, int state)
331 * power off recovery (POR) test, it should read ECC status first 488 * power off recovery (POR) test, it should read ECC status first
332 */ 489 */
333 if (interrupt & ONENAND_INT_READ) { 490 if (interrupt & ONENAND_INT_READ) {
334 int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); 491 int ecc = onenand_read_ecc(this);
335 if (ecc) { 492 if (ecc) {
336 if (ecc & ONENAND_ECC_2BIT_ALL) { 493 if (ecc & ONENAND_ECC_2BIT_ALL) {
337 printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc); 494 printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc);
338 mtd->ecc_stats.failed++; 495 mtd->ecc_stats.failed++;
339 return -EBADMSG; 496 return -EBADMSG;
340 } else if (ecc & ONENAND_ECC_1BIT_ALL) { 497 } else if (ecc & ONENAND_ECC_1BIT_ALL) {
341 printk(KERN_INFO "onenand_wait: correctable ECC error = 0x%04x\n", ecc); 498 printk(KERN_DEBUG "onenand_wait: correctable ECC error = 0x%04x\n", ecc);
342 mtd->ecc_stats.corrected++; 499 mtd->ecc_stats.corrected++;
343 } 500 }
344 } 501 }
@@ -656,7 +813,7 @@ static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
656 813
657 if (found && ONENAND_IS_DDP(this)) { 814 if (found && ONENAND_IS_DDP(this)) {
658 /* Select DataRAM for DDP */ 815 /* Select DataRAM for DDP */
659 int block = (int) (addr >> this->erase_shift); 816 int block = onenand_block(this, addr);
660 int value = onenand_bufferram_address(this, block); 817 int value = onenand_bufferram_address(this, block);
661 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); 818 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
662 } 819 }
@@ -816,6 +973,149 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int col
816} 973}
817 974
818/** 975/**
976 * onenand_recover_lsb - [Flex-OneNAND] Recover LSB page data
977 * @param mtd MTD device structure
978 * @param addr address to recover
979 * @param status return value from onenand_wait / onenand_bbt_wait
980 *
981 * MLC NAND Flash cell has paired pages - LSB page and MSB page. LSB page has
982 * lower page address and MSB page has higher page address in paired pages.
983 * If power off occurs during MSB page program, the paired LSB page data can
984 * become corrupt. LSB page recovery read is a way to read LSB page though page
985 * data are corrupted. When uncorrectable error occurs as a result of LSB page
986 * read after power up, issue LSB page recovery read.
987 */
988static int onenand_recover_lsb(struct mtd_info *mtd, loff_t addr, int status)
989{
990 struct onenand_chip *this = mtd->priv;
991 int i;
992
993 /* Recovery is only for Flex-OneNAND */
994 if (!FLEXONENAND(this))
995 return status;
996
997 /* check if we failed due to uncorrectable error */
998 if (status != -EBADMSG && status != ONENAND_BBT_READ_ECC_ERROR)
999 return status;
1000
1001 /* check if address lies in MLC region */
1002 i = flexonenand_region(mtd, addr);
1003 if (mtd->eraseregions[i].erasesize < (1 << this->erase_shift))
1004 return status;
1005
1006 /* We are attempting to reread, so decrement stats.failed
1007 * which was incremented by onenand_wait due to read failure
1008 */
1009 printk(KERN_INFO "onenand_recover_lsb: Attempting to recover from uncorrectable read\n");
1010 mtd->ecc_stats.failed--;
1011
1012 /* Issue the LSB page recovery command */
1013 this->command(mtd, FLEXONENAND_CMD_RECOVER_LSB, addr, this->writesize);
1014 return this->wait(mtd, FL_READING);
1015}
1016
1017/**
1018 * onenand_mlc_read_ops_nolock - MLC OneNAND read main and/or out-of-band
1019 * @param mtd MTD device structure
1020 * @param from offset to read from
1021 * @param ops: oob operation description structure
1022 *
1023 * MLC OneNAND / Flex-OneNAND has 4KB page size and 4KB dataram.
1024 * So, read-while-load is not present.
1025 */
1026static int onenand_mlc_read_ops_nolock(struct mtd_info *mtd, loff_t from,
1027 struct mtd_oob_ops *ops)
1028{
1029 struct onenand_chip *this = mtd->priv;
1030 struct mtd_ecc_stats stats;
1031 size_t len = ops->len;
1032 size_t ooblen = ops->ooblen;
1033 u_char *buf = ops->datbuf;
1034 u_char *oobbuf = ops->oobbuf;
1035 int read = 0, column, thislen;
1036 int oobread = 0, oobcolumn, thisooblen, oobsize;
1037 int ret = 0;
1038 int writesize = this->writesize;
1039
1040 DEBUG(MTD_DEBUG_LEVEL3, "onenand_mlc_read_ops_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
1041
1042 if (ops->mode == MTD_OOB_AUTO)
1043 oobsize = this->ecclayout->oobavail;
1044 else
1045 oobsize = mtd->oobsize;
1046
1047 oobcolumn = from & (mtd->oobsize - 1);
1048
1049 /* Do not allow reads past end of device */
1050 if (from + len > mtd->size) {
1051 printk(KERN_ERR "onenand_mlc_read_ops_nolock: Attempt read beyond end of device\n");
1052 ops->retlen = 0;
1053 ops->oobretlen = 0;
1054 return -EINVAL;
1055 }
1056
1057 stats = mtd->ecc_stats;
1058
1059 while (read < len) {
1060 cond_resched();
1061
1062 thislen = min_t(int, writesize, len - read);
1063
1064 column = from & (writesize - 1);
1065 if (column + thislen > writesize)
1066 thislen = writesize - column;
1067
1068 if (!onenand_check_bufferram(mtd, from)) {
1069 this->command(mtd, ONENAND_CMD_READ, from, writesize);
1070
1071 ret = this->wait(mtd, FL_READING);
1072 if (unlikely(ret))
1073 ret = onenand_recover_lsb(mtd, from, ret);
1074 onenand_update_bufferram(mtd, from, !ret);
1075 if (ret == -EBADMSG)
1076 ret = 0;
1077 }
1078
1079 this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
1080 if (oobbuf) {
1081 thisooblen = oobsize - oobcolumn;
1082 thisooblen = min_t(int, thisooblen, ooblen - oobread);
1083
1084 if (ops->mode == MTD_OOB_AUTO)
1085 onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen);
1086 else
1087 this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
1088 oobread += thisooblen;
1089 oobbuf += thisooblen;
1090 oobcolumn = 0;
1091 }
1092
1093 read += thislen;
1094 if (read == len)
1095 break;
1096
1097 from += thislen;
1098 buf += thislen;
1099 }
1100
1101 /*
1102 * Return success, if no ECC failures, else -EBADMSG
1103 * fs driver will take care of that, because
1104 * retlen == desired len and result == -EBADMSG
1105 */
1106 ops->retlen = read;
1107 ops->oobretlen = oobread;
1108
1109 if (ret)
1110 return ret;
1111
1112 if (mtd->ecc_stats.failed - stats.failed)
1113 return -EBADMSG;
1114
1115 return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
1116}
1117
1118/**
819 * onenand_read_ops_nolock - [OneNAND Interface] OneNAND read main and/or out-of-band 1119 * onenand_read_ops_nolock - [OneNAND Interface] OneNAND read main and/or out-of-band
820 * @param mtd MTD device structure 1120 * @param mtd MTD device structure
821 * @param from offset to read from 1121 * @param from offset to read from
@@ -962,7 +1262,7 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
962 size_t len = ops->ooblen; 1262 size_t len = ops->ooblen;
963 mtd_oob_mode_t mode = ops->mode; 1263 mtd_oob_mode_t mode = ops->mode;
964 u_char *buf = ops->oobbuf; 1264 u_char *buf = ops->oobbuf;
965 int ret = 0; 1265 int ret = 0, readcmd;
966 1266
967 from += ops->ooboffs; 1267 from += ops->ooboffs;
968 1268
@@ -993,17 +1293,22 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
993 1293
994 stats = mtd->ecc_stats; 1294 stats = mtd->ecc_stats;
995 1295
1296 readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1297
996 while (read < len) { 1298 while (read < len) {
997 cond_resched(); 1299 cond_resched();
998 1300
999 thislen = oobsize - column; 1301 thislen = oobsize - column;
1000 thislen = min_t(int, thislen, len); 1302 thislen = min_t(int, thislen, len);
1001 1303
1002 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize); 1304 this->command(mtd, readcmd, from, mtd->oobsize);
1003 1305
1004 onenand_update_bufferram(mtd, from, 0); 1306 onenand_update_bufferram(mtd, from, 0);
1005 1307
1006 ret = this->wait(mtd, FL_READING); 1308 ret = this->wait(mtd, FL_READING);
1309 if (unlikely(ret))
1310 ret = onenand_recover_lsb(mtd, from, ret);
1311
1007 if (ret && ret != -EBADMSG) { 1312 if (ret && ret != -EBADMSG) {
1008 printk(KERN_ERR "onenand_read_oob_nolock: read failed = 0x%x\n", ret); 1313 printk(KERN_ERR "onenand_read_oob_nolock: read failed = 0x%x\n", ret);
1009 break; 1314 break;
@@ -1053,6 +1358,7 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
1053static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len, 1358static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
1054 size_t *retlen, u_char *buf) 1359 size_t *retlen, u_char *buf)
1055{ 1360{
1361 struct onenand_chip *this = mtd->priv;
1056 struct mtd_oob_ops ops = { 1362 struct mtd_oob_ops ops = {
1057 .len = len, 1363 .len = len,
1058 .ooblen = 0, 1364 .ooblen = 0,
@@ -1062,7 +1368,9 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
1062 int ret; 1368 int ret;
1063 1369
1064 onenand_get_device(mtd, FL_READING); 1370 onenand_get_device(mtd, FL_READING);
1065 ret = onenand_read_ops_nolock(mtd, from, &ops); 1371 ret = ONENAND_IS_MLC(this) ?
1372 onenand_mlc_read_ops_nolock(mtd, from, &ops) :
1373 onenand_read_ops_nolock(mtd, from, &ops);
1066 onenand_release_device(mtd); 1374 onenand_release_device(mtd);
1067 1375
1068 *retlen = ops.retlen; 1376 *retlen = ops.retlen;
@@ -1080,6 +1388,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
1080static int onenand_read_oob(struct mtd_info *mtd, loff_t from, 1388static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
1081 struct mtd_oob_ops *ops) 1389 struct mtd_oob_ops *ops)
1082{ 1390{
1391 struct onenand_chip *this = mtd->priv;
1083 int ret; 1392 int ret;
1084 1393
1085 switch (ops->mode) { 1394 switch (ops->mode) {
@@ -1094,7 +1403,9 @@ static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
1094 1403
1095 onenand_get_device(mtd, FL_READING); 1404 onenand_get_device(mtd, FL_READING);
1096 if (ops->datbuf) 1405 if (ops->datbuf)
1097 ret = onenand_read_ops_nolock(mtd, from, ops); 1406 ret = ONENAND_IS_MLC(this) ?
1407 onenand_mlc_read_ops_nolock(mtd, from, ops) :
1408 onenand_read_ops_nolock(mtd, from, ops);
1098 else 1409 else
1099 ret = onenand_read_oob_nolock(mtd, from, ops); 1410 ret = onenand_read_oob_nolock(mtd, from, ops);
1100 onenand_release_device(mtd); 1411 onenand_release_device(mtd);
@@ -1128,11 +1439,11 @@ static int onenand_bbt_wait(struct mtd_info *mtd, int state)
1128 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); 1439 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
1129 1440
1130 if (interrupt & ONENAND_INT_READ) { 1441 if (interrupt & ONENAND_INT_READ) {
1131 int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); 1442 int ecc = onenand_read_ecc(this);
1132 if (ecc & ONENAND_ECC_2BIT_ALL) { 1443 if (ecc & ONENAND_ECC_2BIT_ALL) {
1133 printk(KERN_INFO "onenand_bbt_wait: ecc error = 0x%04x" 1444 printk(KERN_INFO "onenand_bbt_wait: ecc error = 0x%04x"
1134 ", controller error 0x%04x\n", ecc, ctrl); 1445 ", controller error 0x%04x\n", ecc, ctrl);
1135 return ONENAND_BBT_READ_ERROR; 1446 return ONENAND_BBT_READ_ECC_ERROR;
1136 } 1447 }
1137 } else { 1448 } else {
1138 printk(KERN_ERR "onenand_bbt_wait: read timeout!" 1449 printk(KERN_ERR "onenand_bbt_wait: read timeout!"
@@ -1163,7 +1474,7 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
1163{ 1474{
1164 struct onenand_chip *this = mtd->priv; 1475 struct onenand_chip *this = mtd->priv;
1165 int read = 0, thislen, column; 1476 int read = 0, thislen, column;
1166 int ret = 0; 1477 int ret = 0, readcmd;
1167 size_t len = ops->ooblen; 1478 size_t len = ops->ooblen;
1168 u_char *buf = ops->oobbuf; 1479 u_char *buf = ops->oobbuf;
1169 1480
@@ -1183,17 +1494,22 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
1183 1494
1184 column = from & (mtd->oobsize - 1); 1495 column = from & (mtd->oobsize - 1);
1185 1496
1497 readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1498
1186 while (read < len) { 1499 while (read < len) {
1187 cond_resched(); 1500 cond_resched();
1188 1501
1189 thislen = mtd->oobsize - column; 1502 thislen = mtd->oobsize - column;
1190 thislen = min_t(int, thislen, len); 1503 thislen = min_t(int, thislen, len);
1191 1504
1192 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize); 1505 this->command(mtd, readcmd, from, mtd->oobsize);
1193 1506
1194 onenand_update_bufferram(mtd, from, 0); 1507 onenand_update_bufferram(mtd, from, 0);
1195 1508
1196 ret = onenand_bbt_wait(mtd, FL_READING); 1509 ret = this->bbt_wait(mtd, FL_READING);
1510 if (unlikely(ret))
1511 ret = onenand_recover_lsb(mtd, from, ret);
1512
1197 if (ret) 1513 if (ret)
1198 break; 1514 break;
1199 1515
@@ -1230,9 +1546,11 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to
1230{ 1546{
1231 struct onenand_chip *this = mtd->priv; 1547 struct onenand_chip *this = mtd->priv;
1232 u_char *oob_buf = this->oob_buf; 1548 u_char *oob_buf = this->oob_buf;
1233 int status, i; 1549 int status, i, readcmd;
1234 1550
1235 this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize); 1551 readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1552
1553 this->command(mtd, readcmd, to, mtd->oobsize);
1236 onenand_update_bufferram(mtd, to, 0); 1554 onenand_update_bufferram(mtd, to, 0);
1237 status = this->wait(mtd, FL_READING); 1555 status = this->wait(mtd, FL_READING);
1238 if (status) 1556 if (status)
@@ -1633,7 +1951,7 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
1633{ 1951{
1634 struct onenand_chip *this = mtd->priv; 1952 struct onenand_chip *this = mtd->priv;
1635 int column, ret = 0, oobsize; 1953 int column, ret = 0, oobsize;
1636 int written = 0; 1954 int written = 0, oobcmd;
1637 u_char *oobbuf; 1955 u_char *oobbuf;
1638 size_t len = ops->ooblen; 1956 size_t len = ops->ooblen;
1639 const u_char *buf = ops->oobbuf; 1957 const u_char *buf = ops->oobbuf;
@@ -1675,6 +1993,8 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
1675 1993
1676 oobbuf = this->oob_buf; 1994 oobbuf = this->oob_buf;
1677 1995
1996 oobcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB;
1997
1678 /* Loop until all data write */ 1998 /* Loop until all data write */
1679 while (written < len) { 1999 while (written < len) {
1680 int thislen = min_t(int, oobsize, len - written); 2000 int thislen = min_t(int, oobsize, len - written);
@@ -1692,7 +2012,14 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
1692 memcpy(oobbuf + column, buf, thislen); 2012 memcpy(oobbuf + column, buf, thislen);
1693 this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize); 2013 this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
1694 2014
1695 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize); 2015 if (ONENAND_IS_MLC(this)) {
2016 /* Set main area of DataRAM to 0xff*/
2017 memset(this->page_buf, 0xff, mtd->writesize);
2018 this->write_bufferram(mtd, ONENAND_DATARAM,
2019 this->page_buf, 0, mtd->writesize);
2020 }
2021
2022 this->command(mtd, oobcmd, to, mtd->oobsize);
1696 2023
1697 onenand_update_bufferram(mtd, to, 0); 2024 onenand_update_bufferram(mtd, to, 0);
1698 if (ONENAND_IS_2PLANE(this)) { 2025 if (ONENAND_IS_2PLANE(this)) {
@@ -1815,29 +2142,48 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1815{ 2142{
1816 struct onenand_chip *this = mtd->priv; 2143 struct onenand_chip *this = mtd->priv;
1817 unsigned int block_size; 2144 unsigned int block_size;
1818 loff_t addr; 2145 loff_t addr = instr->addr;
1819 int len; 2146 loff_t len = instr->len;
1820 int ret = 0; 2147 int ret = 0, i;
2148 struct mtd_erase_region_info *region = NULL;
2149 loff_t region_end = 0;
1821 2150
1822 DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%012llx, len = %llu\n", (unsigned long long) instr->addr, (unsigned long long) instr->len); 2151 DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%012llx, len = %llu\n", (unsigned long long) instr->addr, (unsigned long long) instr->len);
1823 2152
1824 block_size = (1 << this->erase_shift); 2153 /* Do not allow erase past end of device */
1825 2154 if (unlikely((len + addr) > mtd->size)) {
1826 /* Start address must align on block boundary */ 2155 printk(KERN_ERR "onenand_erase: Erase past end of device\n");
1827 if (unlikely(instr->addr & (block_size - 1))) {
1828 printk(KERN_ERR "onenand_erase: Unaligned address\n");
1829 return -EINVAL; 2156 return -EINVAL;
1830 } 2157 }
1831 2158
1832 /* Length must align on block boundary */ 2159 if (FLEXONENAND(this)) {
1833 if (unlikely(instr->len & (block_size - 1))) { 2160 /* Find the eraseregion of this address */
1834 printk(KERN_ERR "onenand_erase: Length not block aligned\n"); 2161 i = flexonenand_region(mtd, addr);
1835 return -EINVAL; 2162 region = &mtd->eraseregions[i];
2163
2164 block_size = region->erasesize;
2165 region_end = region->offset + region->erasesize * region->numblocks;
2166
2167 /* Start address within region must align on block boundary.
2168 * Erase region's start offset is always block start address.
2169 */
2170 if (unlikely((addr - region->offset) & (block_size - 1))) {
2171 printk(KERN_ERR "onenand_erase: Unaligned address\n");
2172 return -EINVAL;
2173 }
2174 } else {
2175 block_size = 1 << this->erase_shift;
2176
2177 /* Start address must align on block boundary */
2178 if (unlikely(addr & (block_size - 1))) {
2179 printk(KERN_ERR "onenand_erase: Unaligned address\n");
2180 return -EINVAL;
2181 }
1836 } 2182 }
1837 2183
1838 /* Do not allow erase past end of device */ 2184 /* Length must align on block boundary */
1839 if (unlikely((instr->len + instr->addr) > mtd->size)) { 2185 if (unlikely(len & (block_size - 1))) {
1840 printk(KERN_ERR "onenand_erase: Erase past end of device\n"); 2186 printk(KERN_ERR "onenand_erase: Length not block aligned\n");
1841 return -EINVAL; 2187 return -EINVAL;
1842 } 2188 }
1843 2189
@@ -1847,9 +2193,6 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1847 onenand_get_device(mtd, FL_ERASING); 2193 onenand_get_device(mtd, FL_ERASING);
1848 2194
1849 /* Loop throught the pages */ 2195 /* Loop throught the pages */
1850 len = instr->len;
1851 addr = instr->addr;
1852
1853 instr->state = MTD_ERASING; 2196 instr->state = MTD_ERASING;
1854 2197
1855 while (len) { 2198 while (len) {
@@ -1869,7 +2212,8 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1869 ret = this->wait(mtd, FL_ERASING); 2212 ret = this->wait(mtd, FL_ERASING);
1870 /* Check, if it is write protected */ 2213 /* Check, if it is write protected */
1871 if (ret) { 2214 if (ret) {
1872 printk(KERN_ERR "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift)); 2215 printk(KERN_ERR "onenand_erase: Failed erase, block %d\n",
2216 onenand_block(this, addr));
1873 instr->state = MTD_ERASE_FAILED; 2217 instr->state = MTD_ERASE_FAILED;
1874 instr->fail_addr = addr; 2218 instr->fail_addr = addr;
1875 goto erase_exit; 2219 goto erase_exit;
@@ -1877,6 +2221,22 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1877 2221
1878 len -= block_size; 2222 len -= block_size;
1879 addr += block_size; 2223 addr += block_size;
2224
2225 if (addr == region_end) {
2226 if (!len)
2227 break;
2228 region++;
2229
2230 block_size = region->erasesize;
2231 region_end = region->offset + region->erasesize * region->numblocks;
2232
2233 if (len & (block_size - 1)) {
2234 /* FIXME: This should be handled at MTD partitioning level. */
2235 printk(KERN_ERR "onenand_erase: Unaligned address\n");
2236 goto erase_exit;
2237 }
2238 }
2239
1880 } 2240 }
1881 2241
1882 instr->state = MTD_ERASE_DONE; 2242 instr->state = MTD_ERASE_DONE;
@@ -1955,13 +2315,17 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
1955 int block; 2315 int block;
1956 2316
1957 /* Get block number */ 2317 /* Get block number */
1958 block = ((int) ofs) >> bbm->bbt_erase_shift; 2318 block = onenand_block(this, ofs);
1959 if (bbm->bbt) 2319 if (bbm->bbt)
1960 bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); 2320 bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
1961 2321
1962 /* We write two bytes, so we dont have to mess with 16 bit access */ 2322 /* We write two bytes, so we dont have to mess with 16 bit access */
1963 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01); 2323 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
1964 return onenand_write_oob_nolock(mtd, ofs, &ops); 2324 /* FIXME : What to do when marking SLC block in partition
2325 * with MLC erasesize? For now, it is not advisable to
2326 * create partitions containing both SLC and MLC regions.
2327 */
2328 return onenand_write_oob_nolock(mtd, ofs, &ops);
1965} 2329}
1966 2330
1967/** 2331/**
@@ -2005,8 +2369,8 @@ static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int
2005 int start, end, block, value, status; 2369 int start, end, block, value, status;
2006 int wp_status_mask; 2370 int wp_status_mask;
2007 2371
2008 start = ofs >> this->erase_shift; 2372 start = onenand_block(this, ofs);
2009 end = len >> this->erase_shift; 2373 end = onenand_block(this, ofs + len) - 1;
2010 2374
2011 if (cmd == ONENAND_CMD_LOCK) 2375 if (cmd == ONENAND_CMD_LOCK)
2012 wp_status_mask = ONENAND_WP_LS; 2376 wp_status_mask = ONENAND_WP_LS;
@@ -2018,7 +2382,7 @@ static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int
2018 /* Set start block address */ 2382 /* Set start block address */
2019 this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS); 2383 this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
2020 /* Set end block address */ 2384 /* Set end block address */
2021 this->write_word(start + end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS); 2385 this->write_word(end, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
2022 /* Write lock command */ 2386 /* Write lock command */
2023 this->command(mtd, cmd, 0, 0); 2387 this->command(mtd, cmd, 0, 0);
2024 2388
@@ -2039,7 +2403,7 @@ static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int
2039 } 2403 }
2040 2404
2041 /* Block lock scheme */ 2405 /* Block lock scheme */
2042 for (block = start; block < start + end; block++) { 2406 for (block = start; block < end + 1; block++) {
2043 /* Set block address */ 2407 /* Set block address */
2044 value = onenand_block_address(this, block); 2408 value = onenand_block_address(this, block);
2045 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); 2409 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
@@ -2147,7 +2511,7 @@ static void onenand_unlock_all(struct mtd_info *mtd)
2147{ 2511{
2148 struct onenand_chip *this = mtd->priv; 2512 struct onenand_chip *this = mtd->priv;
2149 loff_t ofs = 0; 2513 loff_t ofs = 0;
2150 size_t len = this->chipsize; 2514 loff_t len = mtd->size;
2151 2515
2152 if (this->options & ONENAND_HAS_UNLOCK_ALL) { 2516 if (this->options & ONENAND_HAS_UNLOCK_ALL) {
2153 /* Set start block address */ 2517 /* Set start block address */
@@ -2163,12 +2527,16 @@ static void onenand_unlock_all(struct mtd_info *mtd)
2163 & ONENAND_CTRL_ONGO) 2527 & ONENAND_CTRL_ONGO)
2164 continue; 2528 continue;
2165 2529
2530 /* Don't check lock status */
2531 if (this->options & ONENAND_SKIP_UNLOCK_CHECK)
2532 return;
2533
2166 /* Check lock status */ 2534 /* Check lock status */
2167 if (onenand_check_lock_status(this)) 2535 if (onenand_check_lock_status(this))
2168 return; 2536 return;
2169 2537
2170 /* Workaround for all block unlock in DDP */ 2538 /* Workaround for all block unlock in DDP */
2171 if (ONENAND_IS_DDP(this)) { 2539 if (ONENAND_IS_DDP(this) && !FLEXONENAND(this)) {
2172 /* All blocks on another chip */ 2540 /* All blocks on another chip */
2173 ofs = this->chipsize >> 1; 2541 ofs = this->chipsize >> 1;
2174 len = this->chipsize >> 1; 2542 len = this->chipsize >> 1;
@@ -2210,7 +2578,9 @@ static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len,
2210 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); 2578 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
2211 this->wait(mtd, FL_OTPING); 2579 this->wait(mtd, FL_OTPING);
2212 2580
2213 ret = onenand_read_ops_nolock(mtd, from, &ops); 2581 ret = ONENAND_IS_MLC(this) ?
2582 onenand_mlc_read_ops_nolock(mtd, from, &ops) :
2583 onenand_read_ops_nolock(mtd, from, &ops);
2214 2584
2215 /* Exit OTP access mode */ 2585 /* Exit OTP access mode */
2216 this->command(mtd, ONENAND_CMD_RESET, 0, 0); 2586 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
@@ -2277,21 +2647,32 @@ static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len,
2277 size_t *retlen, u_char *buf) 2647 size_t *retlen, u_char *buf)
2278{ 2648{
2279 struct onenand_chip *this = mtd->priv; 2649 struct onenand_chip *this = mtd->priv;
2280 struct mtd_oob_ops ops = { 2650 struct mtd_oob_ops ops;
2281 .mode = MTD_OOB_PLACE,
2282 .ooblen = len,
2283 .oobbuf = buf,
2284 .ooboffs = 0,
2285 };
2286 int ret; 2651 int ret;
2287 2652
2288 /* Enter OTP access mode */ 2653 /* Enter OTP access mode */
2289 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); 2654 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
2290 this->wait(mtd, FL_OTPING); 2655 this->wait(mtd, FL_OTPING);
2291 2656
2292 ret = onenand_write_oob_nolock(mtd, from, &ops); 2657 if (FLEXONENAND(this)) {
2293 2658 /*
2294 *retlen = ops.oobretlen; 2659 * For Flex-OneNAND, we write lock mark to 1st word of sector 4 of
2660 * main area of page 49.
2661 */
2662 ops.len = mtd->writesize;
2663 ops.ooblen = 0;
2664 ops.datbuf = buf;
2665 ops.oobbuf = NULL;
2666 ret = onenand_write_ops_nolock(mtd, mtd->writesize * 49, &ops);
2667 *retlen = ops.retlen;
2668 } else {
2669 ops.mode = MTD_OOB_PLACE;
2670 ops.ooblen = len;
2671 ops.oobbuf = buf;
2672 ops.ooboffs = 0;
2673 ret = onenand_write_oob_nolock(mtd, from, &ops);
2674 *retlen = ops.oobretlen;
2675 }
2295 2676
2296 /* Exit OTP access mode */ 2677 /* Exit OTP access mode */
2297 this->command(mtd, ONENAND_CMD_RESET, 0, 0); 2678 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
@@ -2475,27 +2856,34 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
2475 size_t len) 2856 size_t len)
2476{ 2857{
2477 struct onenand_chip *this = mtd->priv; 2858 struct onenand_chip *this = mtd->priv;
2478 u_char *oob_buf = this->oob_buf; 2859 u_char *buf = FLEXONENAND(this) ? this->page_buf : this->oob_buf;
2479 size_t retlen; 2860 size_t retlen;
2480 int ret; 2861 int ret;
2481 2862
2482 memset(oob_buf, 0xff, mtd->oobsize); 2863 memset(buf, 0xff, FLEXONENAND(this) ? this->writesize
2864 : mtd->oobsize);
2483 /* 2865 /*
2484 * Note: OTP lock operation 2866 * Note: OTP lock operation
2485 * OTP block : 0xXXFC 2867 * OTP block : 0xXXFC
2486 * 1st block : 0xXXF3 (If chip support) 2868 * 1st block : 0xXXF3 (If chip support)
2487 * Both : 0xXXF0 (If chip support) 2869 * Both : 0xXXF0 (If chip support)
2488 */ 2870 */
2489 oob_buf[ONENAND_OTP_LOCK_OFFSET] = 0xFC; 2871 if (FLEXONENAND(this))
2872 buf[FLEXONENAND_OTP_LOCK_OFFSET] = 0xFC;
2873 else
2874 buf[ONENAND_OTP_LOCK_OFFSET] = 0xFC;
2490 2875
2491 /* 2876 /*
2492 * Write lock mark to 8th word of sector0 of page0 of the spare0. 2877 * Write lock mark to 8th word of sector0 of page0 of the spare0.
2493 * We write 16 bytes spare area instead of 2 bytes. 2878 * We write 16 bytes spare area instead of 2 bytes.
2879 * For Flex-OneNAND, we write lock mark to 1st word of sector 4 of
2880 * main area of page 49.
2494 */ 2881 */
2882
2495 from = 0; 2883 from = 0;
2496 len = 16; 2884 len = FLEXONENAND(this) ? mtd->writesize : 16;
2497 2885
2498 ret = onenand_otp_walk(mtd, from, len, &retlen, oob_buf, do_otp_lock, MTD_OTP_USER); 2886 ret = onenand_otp_walk(mtd, from, len, &retlen, buf, do_otp_lock, MTD_OTP_USER);
2499 2887
2500 return ret ? : retlen; 2888 return ret ? : retlen;
2501} 2889}
@@ -2542,6 +2930,14 @@ static void onenand_check_features(struct mtd_info *mtd)
2542 break; 2930 break;
2543 } 2931 }
2544 2932
2933 if (ONENAND_IS_MLC(this))
2934 this->options &= ~ONENAND_HAS_2PLANE;
2935
2936 if (FLEXONENAND(this)) {
2937 this->options &= ~ONENAND_HAS_CONT_LOCK;
2938 this->options |= ONENAND_HAS_UNLOCK_ALL;
2939 }
2940
2545 if (this->options & ONENAND_HAS_CONT_LOCK) 2941 if (this->options & ONENAND_HAS_CONT_LOCK)
2546 printk(KERN_DEBUG "Lock scheme is Continuous Lock\n"); 2942 printk(KERN_DEBUG "Lock scheme is Continuous Lock\n");
2547 if (this->options & ONENAND_HAS_UNLOCK_ALL) 2943 if (this->options & ONENAND_HAS_UNLOCK_ALL)
@@ -2559,14 +2955,16 @@ static void onenand_check_features(struct mtd_info *mtd)
2559 */ 2955 */
2560static void onenand_print_device_info(int device, int version) 2956static void onenand_print_device_info(int device, int version)
2561{ 2957{
2562 int vcc, demuxed, ddp, density; 2958 int vcc, demuxed, ddp, density, flexonenand;
2563 2959
2564 vcc = device & ONENAND_DEVICE_VCC_MASK; 2960 vcc = device & ONENAND_DEVICE_VCC_MASK;
2565 demuxed = device & ONENAND_DEVICE_IS_DEMUX; 2961 demuxed = device & ONENAND_DEVICE_IS_DEMUX;
2566 ddp = device & ONENAND_DEVICE_IS_DDP; 2962 ddp = device & ONENAND_DEVICE_IS_DDP;
2567 density = onenand_get_density(device); 2963 density = onenand_get_density(device);
2568 printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n", 2964 flexonenand = device & DEVICE_IS_FLEXONENAND;
2569 demuxed ? "" : "Muxed ", 2965 printk(KERN_INFO "%s%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n",
2966 demuxed ? "" : "Muxed ",
2967 flexonenand ? "Flex-" : "",
2570 ddp ? "(DDP)" : "", 2968 ddp ? "(DDP)" : "",
2571 (16 << density), 2969 (16 << density),
2572 vcc ? "2.65/3.3" : "1.8", 2970 vcc ? "2.65/3.3" : "1.8",
@@ -2576,6 +2974,7 @@ static void onenand_print_device_info(int device, int version)
2576 2974
2577static const struct onenand_manufacturers onenand_manuf_ids[] = { 2975static const struct onenand_manufacturers onenand_manuf_ids[] = {
2578 {ONENAND_MFR_SAMSUNG, "Samsung"}, 2976 {ONENAND_MFR_SAMSUNG, "Samsung"},
2977 {ONENAND_MFR_NUMONYX, "Numonyx"},
2579}; 2978};
2580 2979
2581/** 2980/**
@@ -2605,6 +3004,280 @@ static int onenand_check_maf(int manuf)
2605} 3004}
2606 3005
2607/** 3006/**
3007* flexonenand_get_boundary - Reads the SLC boundary
3008* @param onenand_info - onenand info structure
3009**/
3010static int flexonenand_get_boundary(struct mtd_info *mtd)
3011{
3012 struct onenand_chip *this = mtd->priv;
3013 unsigned die, bdry;
3014 int ret, syscfg, locked;
3015
3016 /* Disable ECC */
3017 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
3018 this->write_word((syscfg | 0x0100), this->base + ONENAND_REG_SYS_CFG1);
3019
3020 for (die = 0; die < this->dies; die++) {
3021 this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
3022 this->wait(mtd, FL_SYNCING);
3023
3024 this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
3025 ret = this->wait(mtd, FL_READING);
3026
3027 bdry = this->read_word(this->base + ONENAND_DATARAM);
3028 if ((bdry >> FLEXONENAND_PI_UNLOCK_SHIFT) == 3)
3029 locked = 0;
3030 else
3031 locked = 1;
3032 this->boundary[die] = bdry & FLEXONENAND_PI_MASK;
3033
3034 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
3035 ret = this->wait(mtd, FL_RESETING);
3036
3037 printk(KERN_INFO "Die %d boundary: %d%s\n", die,
3038 this->boundary[die], locked ? "(Locked)" : "(Unlocked)");
3039 }
3040
3041 /* Enable ECC */
3042 this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
3043 return 0;
3044}
3045
3046/**
3047 * flexonenand_get_size - Fill up fields in onenand_chip and mtd_info
3048 * boundary[], diesize[], mtd->size, mtd->erasesize
3049 * @param mtd - MTD device structure
3050 */
3051static void flexonenand_get_size(struct mtd_info *mtd)
3052{
3053 struct onenand_chip *this = mtd->priv;
3054 int die, i, eraseshift, density;
3055 int blksperdie, maxbdry;
3056 loff_t ofs;
3057
3058 density = onenand_get_density(this->device_id);
3059 blksperdie = ((loff_t)(16 << density) << 20) >> (this->erase_shift);
3060 blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
3061 maxbdry = blksperdie - 1;
3062 eraseshift = this->erase_shift - 1;
3063
3064 mtd->numeraseregions = this->dies << 1;
3065
3066 /* This fills up the device boundary */
3067 flexonenand_get_boundary(mtd);
3068 die = ofs = 0;
3069 i = -1;
3070 for (; die < this->dies; die++) {
3071 if (!die || this->boundary[die-1] != maxbdry) {
3072 i++;
3073 mtd->eraseregions[i].offset = ofs;
3074 mtd->eraseregions[i].erasesize = 1 << eraseshift;
3075 mtd->eraseregions[i].numblocks =
3076 this->boundary[die] + 1;
3077 ofs += mtd->eraseregions[i].numblocks << eraseshift;
3078 eraseshift++;
3079 } else {
3080 mtd->numeraseregions -= 1;
3081 mtd->eraseregions[i].numblocks +=
3082 this->boundary[die] + 1;
3083 ofs += (this->boundary[die] + 1) << (eraseshift - 1);
3084 }
3085 if (this->boundary[die] != maxbdry) {
3086 i++;
3087 mtd->eraseregions[i].offset = ofs;
3088 mtd->eraseregions[i].erasesize = 1 << eraseshift;
3089 mtd->eraseregions[i].numblocks = maxbdry ^
3090 this->boundary[die];
3091 ofs += mtd->eraseregions[i].numblocks << eraseshift;
3092 eraseshift--;
3093 } else
3094 mtd->numeraseregions -= 1;
3095 }
3096
3097 /* Expose MLC erase size except when all blocks are SLC */
3098 mtd->erasesize = 1 << this->erase_shift;
3099 if (mtd->numeraseregions == 1)
3100 mtd->erasesize >>= 1;
3101
3102 printk(KERN_INFO "Device has %d eraseregions\n", mtd->numeraseregions);
3103 for (i = 0; i < mtd->numeraseregions; i++)
3104 printk(KERN_INFO "[offset: 0x%08x, erasesize: 0x%05x,"
3105 " numblocks: %04u]\n",
3106 (unsigned int) mtd->eraseregions[i].offset,
3107 mtd->eraseregions[i].erasesize,
3108 mtd->eraseregions[i].numblocks);
3109
3110 for (die = 0, mtd->size = 0; die < this->dies; die++) {
3111 this->diesize[die] = (loff_t)blksperdie << this->erase_shift;
3112 this->diesize[die] -= (loff_t)(this->boundary[die] + 1)
3113 << (this->erase_shift - 1);
3114 mtd->size += this->diesize[die];
3115 }
3116}
3117
3118/**
3119 * flexonenand_check_blocks_erased - Check if blocks are erased
3120 * @param mtd_info - mtd info structure
3121 * @param start - first erase block to check
3122 * @param end - last erase block to check
3123 *
3124 * Converting an unerased block from MLC to SLC
3125 * causes byte values to change. Since both data and its ECC
3126 * have changed, reads on the block give uncorrectable error.
3127 * This might lead to the block being detected as bad.
3128 *
3129 * Avoid this by ensuring that the block to be converted is
3130 * erased.
3131 */
3132static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int end)
3133{
3134 struct onenand_chip *this = mtd->priv;
3135 int i, ret;
3136 int block;
3137 struct mtd_oob_ops ops = {
3138 .mode = MTD_OOB_PLACE,
3139 .ooboffs = 0,
3140 .ooblen = mtd->oobsize,
3141 .datbuf = NULL,
3142 .oobbuf = this->oob_buf,
3143 };
3144 loff_t addr;
3145
3146 printk(KERN_DEBUG "Check blocks from %d to %d\n", start, end);
3147
3148 for (block = start; block <= end; block++) {
3149 addr = flexonenand_addr(this, block);
3150 if (onenand_block_isbad_nolock(mtd, addr, 0))
3151 continue;
3152
3153 /*
3154 * Since main area write results in ECC write to spare,
3155 * it is sufficient to check only ECC bytes for change.
3156 */
3157 ret = onenand_read_oob_nolock(mtd, addr, &ops);
3158 if (ret)
3159 return ret;
3160
3161 for (i = 0; i < mtd->oobsize; i++)
3162 if (this->oob_buf[i] != 0xff)
3163 break;
3164
3165 if (i != mtd->oobsize) {
3166 printk(KERN_WARNING "Block %d not erased.\n", block);
3167 return 1;
3168 }
3169 }
3170
3171 return 0;
3172}
3173
3174/**
3175 * flexonenand_set_boundary - Writes the SLC boundary
3176 * @param mtd - mtd info structure
3177 */
3178int flexonenand_set_boundary(struct mtd_info *mtd, int die,
3179 int boundary, int lock)
3180{
3181 struct onenand_chip *this = mtd->priv;
3182 int ret, density, blksperdie, old, new, thisboundary;
3183 loff_t addr;
3184
3185 /* Change only once for SDP Flex-OneNAND */
3186 if (die && (!ONENAND_IS_DDP(this)))
3187 return 0;
3188
3189 /* boundary value of -1 indicates no required change */
3190 if (boundary < 0 || boundary == this->boundary[die])
3191 return 0;
3192
3193 density = onenand_get_density(this->device_id);
3194 blksperdie = ((16 << density) << 20) >> this->erase_shift;
3195 blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
3196
3197 if (boundary >= blksperdie) {
3198 printk(KERN_ERR "flexonenand_set_boundary: Invalid boundary value. "
3199 "Boundary not changed.\n");
3200 return -EINVAL;
3201 }
3202
3203 /* Check if converting blocks are erased */
3204 old = this->boundary[die] + (die * this->density_mask);
3205 new = boundary + (die * this->density_mask);
3206 ret = flexonenand_check_blocks_erased(mtd, min(old, new) + 1, max(old, new));
3207 if (ret) {
3208 printk(KERN_ERR "flexonenand_set_boundary: Please erase blocks before boundary change\n");
3209 return ret;
3210 }
3211
3212 this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
3213 this->wait(mtd, FL_SYNCING);
3214
3215 /* Check is boundary is locked */
3216 this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
3217 ret = this->wait(mtd, FL_READING);
3218
3219 thisboundary = this->read_word(this->base + ONENAND_DATARAM);
3220 if ((thisboundary >> FLEXONENAND_PI_UNLOCK_SHIFT) != 3) {
3221 printk(KERN_ERR "flexonenand_set_boundary: boundary locked\n");
3222 ret = 1;
3223 goto out;
3224 }
3225
3226 printk(KERN_INFO "flexonenand_set_boundary: Changing die %d boundary: %d%s\n",
3227 die, boundary, lock ? "(Locked)" : "(Unlocked)");
3228
3229 addr = die ? this->diesize[0] : 0;
3230
3231 boundary &= FLEXONENAND_PI_MASK;
3232 boundary |= lock ? 0 : (3 << FLEXONENAND_PI_UNLOCK_SHIFT);
3233
3234 this->command(mtd, ONENAND_CMD_ERASE, addr, 0);
3235 ret = this->wait(mtd, FL_ERASING);
3236 if (ret) {
3237 printk(KERN_ERR "flexonenand_set_boundary: Failed PI erase for Die %d\n", die);
3238 goto out;
3239 }
3240
3241 this->write_word(boundary, this->base + ONENAND_DATARAM);
3242 this->command(mtd, ONENAND_CMD_PROG, addr, 0);
3243 ret = this->wait(mtd, FL_WRITING);
3244 if (ret) {
3245 printk(KERN_ERR "flexonenand_set_boundary: Failed PI write for Die %d\n", die);
3246 goto out;
3247 }
3248
3249 this->command(mtd, FLEXONENAND_CMD_PI_UPDATE, die, 0);
3250 ret = this->wait(mtd, FL_WRITING);
3251out:
3252 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_REG_COMMAND);
3253 this->wait(mtd, FL_RESETING);
3254 if (!ret)
3255 /* Recalculate device size on boundary change*/
3256 flexonenand_get_size(mtd);
3257
3258 return ret;
3259}
3260
3261/**
3262 * flexonenand_setup - capture Flex-OneNAND boundary and lock
3263 * values passed as kernel parameters
3264 * @param s kernel parameter string
3265 */
3266static int flexonenand_setup(char *s)
3267{
3268 int ints[5], i;
3269
3270 s = get_options(s, 5, ints);
3271
3272 for (i = 0; i < ints[0]; i++)
3273 flex_bdry[i] = ints[i + 1];
3274
3275 return 1;
3276}
3277
3278__setup("onenand.bdry=", flexonenand_setup);
3279
3280/**
2608 * onenand_probe - [OneNAND Interface] Probe the OneNAND device 3281 * onenand_probe - [OneNAND Interface] Probe the OneNAND device
2609 * @param mtd MTD device structure 3282 * @param mtd MTD device structure
2610 * 3283 *
@@ -2621,7 +3294,7 @@ static int onenand_probe(struct mtd_info *mtd)
2621 /* Save system configuration 1 */ 3294 /* Save system configuration 1 */
2622 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1); 3295 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
2623 /* Clear Sync. Burst Read mode to read BootRAM */ 3296 /* Clear Sync. Burst Read mode to read BootRAM */
2624 this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ), this->base + ONENAND_REG_SYS_CFG1); 3297 this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE), this->base + ONENAND_REG_SYS_CFG1);
2625 3298
2626 /* Send the command for reading device ID from BootRAM */ 3299 /* Send the command for reading device ID from BootRAM */
2627 this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM); 3300 this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
@@ -2646,6 +3319,7 @@ static int onenand_probe(struct mtd_info *mtd)
2646 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID); 3319 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
2647 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID); 3320 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
2648 ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID); 3321 ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
3322 this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
2649 3323
2650 /* Check OneNAND device */ 3324 /* Check OneNAND device */
2651 if (maf_id != bram_maf_id || dev_id != bram_dev_id) 3325 if (maf_id != bram_maf_id || dev_id != bram_dev_id)
@@ -2657,29 +3331,55 @@ static int onenand_probe(struct mtd_info *mtd)
2657 this->version_id = ver_id; 3331 this->version_id = ver_id;
2658 3332
2659 density = onenand_get_density(dev_id); 3333 density = onenand_get_density(dev_id);
3334 if (FLEXONENAND(this)) {
3335 this->dies = ONENAND_IS_DDP(this) ? 2 : 1;
3336 /* Maximum possible erase regions */
3337 mtd->numeraseregions = this->dies << 1;
3338 mtd->eraseregions = kzalloc(sizeof(struct mtd_erase_region_info)
3339 * (this->dies << 1), GFP_KERNEL);
3340 if (!mtd->eraseregions)
3341 return -ENOMEM;
3342 }
3343
3344 /*
3345 * For Flex-OneNAND, chipsize represents maximum possible device size.
3346 * mtd->size represents the actual device size.
3347 */
2660 this->chipsize = (16 << density) << 20; 3348 this->chipsize = (16 << density) << 20;
2661 /* Set density mask. it is used for DDP */
2662 if (ONENAND_IS_DDP(this))
2663 this->density_mask = (1 << (density + 6));
2664 else
2665 this->density_mask = 0;
2666 3349
2667 /* OneNAND page size & block size */ 3350 /* OneNAND page size & block size */
2668 /* The data buffer size is equal to page size */ 3351 /* The data buffer size is equal to page size */
2669 mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE); 3352 mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
3353 /* We use the full BufferRAM */
3354 if (ONENAND_IS_MLC(this))
3355 mtd->writesize <<= 1;
3356
2670 mtd->oobsize = mtd->writesize >> 5; 3357 mtd->oobsize = mtd->writesize >> 5;
2671 /* Pages per a block are always 64 in OneNAND */ 3358 /* Pages per a block are always 64 in OneNAND */
2672 mtd->erasesize = mtd->writesize << 6; 3359 mtd->erasesize = mtd->writesize << 6;
3360 /*
3361 * Flex-OneNAND SLC area has 64 pages per block.
3362 * Flex-OneNAND MLC area has 128 pages per block.
3363 * Expose MLC erase size to find erase_shift and page_mask.
3364 */
3365 if (FLEXONENAND(this))
3366 mtd->erasesize <<= 1;
2673 3367
2674 this->erase_shift = ffs(mtd->erasesize) - 1; 3368 this->erase_shift = ffs(mtd->erasesize) - 1;
2675 this->page_shift = ffs(mtd->writesize) - 1; 3369 this->page_shift = ffs(mtd->writesize) - 1;
2676 this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1; 3370 this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1;
3371 /* Set density mask. it is used for DDP */
3372 if (ONENAND_IS_DDP(this))
3373 this->density_mask = this->chipsize >> (this->erase_shift + 1);
2677 /* It's real page size */ 3374 /* It's real page size */
2678 this->writesize = mtd->writesize; 3375 this->writesize = mtd->writesize;
2679 3376
2680 /* REVIST: Multichip handling */ 3377 /* REVIST: Multichip handling */
2681 3378
2682 mtd->size = this->chipsize; 3379 if (FLEXONENAND(this))
3380 flexonenand_get_size(mtd);
3381 else
3382 mtd->size = this->chipsize;
2683 3383
2684 /* Check OneNAND features */ 3384 /* Check OneNAND features */
2685 onenand_check_features(mtd); 3385 onenand_check_features(mtd);
@@ -2734,7 +3434,7 @@ static void onenand_resume(struct mtd_info *mtd)
2734 */ 3434 */
2735int onenand_scan(struct mtd_info *mtd, int maxchips) 3435int onenand_scan(struct mtd_info *mtd, int maxchips)
2736{ 3436{
2737 int i; 3437 int i, ret;
2738 struct onenand_chip *this = mtd->priv; 3438 struct onenand_chip *this = mtd->priv;
2739 3439
2740 if (!this->read_word) 3440 if (!this->read_word)
@@ -2746,6 +3446,10 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
2746 this->command = onenand_command; 3446 this->command = onenand_command;
2747 if (!this->wait) 3447 if (!this->wait)
2748 onenand_setup_wait(mtd); 3448 onenand_setup_wait(mtd);
3449 if (!this->bbt_wait)
3450 this->bbt_wait = onenand_bbt_wait;
3451 if (!this->unlock_all)
3452 this->unlock_all = onenand_unlock_all;
2749 3453
2750 if (!this->read_bufferram) 3454 if (!this->read_bufferram)
2751 this->read_bufferram = onenand_read_bufferram; 3455 this->read_bufferram = onenand_read_bufferram;
@@ -2796,6 +3500,10 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
2796 * Allow subpage writes up to oobsize. 3500 * Allow subpage writes up to oobsize.
2797 */ 3501 */
2798 switch (mtd->oobsize) { 3502 switch (mtd->oobsize) {
3503 case 128:
3504 this->ecclayout = &onenand_oob_128;
3505 mtd->subpage_sft = 0;
3506 break;
2799 case 64: 3507 case 64:
2800 this->ecclayout = &onenand_oob_64; 3508 this->ecclayout = &onenand_oob_64;
2801 mtd->subpage_sft = 2; 3509 mtd->subpage_sft = 2;
@@ -2859,9 +3567,18 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
2859 mtd->owner = THIS_MODULE; 3567 mtd->owner = THIS_MODULE;
2860 3568
2861 /* Unlock whole block */ 3569 /* Unlock whole block */
2862 onenand_unlock_all(mtd); 3570 this->unlock_all(mtd);
3571
3572 ret = this->scan_bbt(mtd);
3573 if ((!FLEXONENAND(this)) || ret)
3574 return ret;
2863 3575
2864 return this->scan_bbt(mtd); 3576 /* Change Flex-OneNAND boundaries if required */
3577 for (i = 0; i < MAX_DIES; i++)
3578 flexonenand_set_boundary(mtd, i, flex_bdry[2 * i],
3579 flex_bdry[(2 * i) + 1]);
3580
3581 return 0;
2865} 3582}
2866 3583
2867/** 3584/**
@@ -2890,6 +3607,7 @@ void onenand_release(struct mtd_info *mtd)
2890 kfree(this->page_buf); 3607 kfree(this->page_buf);
2891 if (this->options & ONENAND_OOBBUF_ALLOC) 3608 if (this->options & ONENAND_OOBBUF_ALLOC)
2892 kfree(this->oob_buf); 3609 kfree(this->oob_buf);
3610 kfree(mtd->eraseregions);
2893} 3611}
2894 3612
2895EXPORT_SYMBOL_GPL(onenand_scan); 3613EXPORT_SYMBOL_GPL(onenand_scan);
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
index 2f53b51c6805..a91fcac1af01 100644
--- a/drivers/mtd/onenand/onenand_bbt.c
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -63,6 +63,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
63 loff_t from; 63 loff_t from;
64 size_t readlen, ooblen; 64 size_t readlen, ooblen;
65 struct mtd_oob_ops ops; 65 struct mtd_oob_ops ops;
66 int rgn;
66 67
67 printk(KERN_INFO "Scanning device for bad blocks\n"); 68 printk(KERN_INFO "Scanning device for bad blocks\n");
68 69
@@ -76,7 +77,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
76 /* Note that numblocks is 2 * (real numblocks) here; 77 /* Note that numblocks is 2 * (real numblocks) here;
77 * see i += 2 below as it makses shifting and masking less painful 78 * see i += 2 below as it makses shifting and masking less painful
78 */ 79 */
79 numblocks = mtd->size >> (bbm->bbt_erase_shift - 1); 80 numblocks = this->chipsize >> (bbm->bbt_erase_shift - 1);
80 startblock = 0; 81 startblock = 0;
81 from = 0; 82 from = 0;
82 83
@@ -106,7 +107,12 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
106 } 107 }
107 } 108 }
108 i += 2; 109 i += 2;
109 from += (1 << bbm->bbt_erase_shift); 110
111 if (FLEXONENAND(this)) {
112 rgn = flexonenand_region(mtd, from);
113 from += mtd->eraseregions[rgn].erasesize;
114 } else
115 from += (1 << bbm->bbt_erase_shift);
110 } 116 }
111 117
112 return 0; 118 return 0;
@@ -143,7 +149,7 @@ static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
143 uint8_t res; 149 uint8_t res;
144 150
145 /* Get block number * 2 */ 151 /* Get block number * 2 */
146 block = (int) (offs >> (bbm->bbt_erase_shift - 1)); 152 block = (int) (onenand_block(this, offs) << 1);
147 res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03; 153 res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
148 154
149 DEBUG(MTD_DEBUG_LEVEL2, "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n", 155 DEBUG(MTD_DEBUG_LEVEL2, "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n",
@@ -178,7 +184,7 @@ int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
178 struct bbm_info *bbm = this->bbm; 184 struct bbm_info *bbm = this->bbm;
179 int len, ret = 0; 185 int len, ret = 0;
180 186
181 len = mtd->size >> (this->erase_shift + 2); 187 len = this->chipsize >> (this->erase_shift + 2);
182 /* Allocate memory (2bit per block) and clear the memory bad block table */ 188 /* Allocate memory (2bit per block) and clear the memory bad block table */
183 bbm->bbt = kzalloc(len, GFP_KERNEL); 189 bbm->bbt = kzalloc(len, GFP_KERNEL);
184 if (!bbm->bbt) { 190 if (!bbm->bbt) {
diff --git a/drivers/mtd/onenand/onenand_sim.c b/drivers/mtd/onenand/onenand_sim.c
index d64200b7c94b..f6e3c8aebd3a 100644
--- a/drivers/mtd/onenand/onenand_sim.c
+++ b/drivers/mtd/onenand/onenand_sim.c
@@ -6,6 +6,10 @@
6 * Copyright © 2005-2007 Samsung Electronics 6 * Copyright © 2005-2007 Samsung Electronics
7 * Kyungmin Park <kyungmin.park@samsung.com> 7 * Kyungmin Park <kyungmin.park@samsung.com>
8 * 8 *
9 * Vishak G <vishak.g at samsung.com>, Rohit Hagargundgi <h.rohit at samsung.com>
10 * Flex-OneNAND simulator support
11 * Copyright (C) Samsung Electronics, 2008
12 *
9 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 14 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 15 * published by the Free Software Foundation.
@@ -24,16 +28,38 @@
24#ifndef CONFIG_ONENAND_SIM_MANUFACTURER 28#ifndef CONFIG_ONENAND_SIM_MANUFACTURER
25#define CONFIG_ONENAND_SIM_MANUFACTURER 0xec 29#define CONFIG_ONENAND_SIM_MANUFACTURER 0xec
26#endif 30#endif
31
27#ifndef CONFIG_ONENAND_SIM_DEVICE_ID 32#ifndef CONFIG_ONENAND_SIM_DEVICE_ID
28#define CONFIG_ONENAND_SIM_DEVICE_ID 0x04 33#define CONFIG_ONENAND_SIM_DEVICE_ID 0x04
29#endif 34#endif
35
36#define CONFIG_FLEXONENAND ((CONFIG_ONENAND_SIM_DEVICE_ID >> 9) & 1)
37
30#ifndef CONFIG_ONENAND_SIM_VERSION_ID 38#ifndef CONFIG_ONENAND_SIM_VERSION_ID
31#define CONFIG_ONENAND_SIM_VERSION_ID 0x1e 39#define CONFIG_ONENAND_SIM_VERSION_ID 0x1e
32#endif 40#endif
33 41
42#ifndef CONFIG_ONENAND_SIM_TECHNOLOGY_ID
43#define CONFIG_ONENAND_SIM_TECHNOLOGY_ID CONFIG_FLEXONENAND
44#endif
45
46/* Initial boundary values for Flex-OneNAND Simulator */
47#ifndef CONFIG_FLEXONENAND_SIM_DIE0_BOUNDARY
48#define CONFIG_FLEXONENAND_SIM_DIE0_BOUNDARY 0x01
49#endif
50
51#ifndef CONFIG_FLEXONENAND_SIM_DIE1_BOUNDARY
52#define CONFIG_FLEXONENAND_SIM_DIE1_BOUNDARY 0x01
53#endif
54
34static int manuf_id = CONFIG_ONENAND_SIM_MANUFACTURER; 55static int manuf_id = CONFIG_ONENAND_SIM_MANUFACTURER;
35static int device_id = CONFIG_ONENAND_SIM_DEVICE_ID; 56static int device_id = CONFIG_ONENAND_SIM_DEVICE_ID;
36static int version_id = CONFIG_ONENAND_SIM_VERSION_ID; 57static int version_id = CONFIG_ONENAND_SIM_VERSION_ID;
58static int technology_id = CONFIG_ONENAND_SIM_TECHNOLOGY_ID;
59static int boundary[] = {
60 CONFIG_FLEXONENAND_SIM_DIE0_BOUNDARY,
61 CONFIG_FLEXONENAND_SIM_DIE1_BOUNDARY,
62};
37 63
38struct onenand_flash { 64struct onenand_flash {
39 void __iomem *base; 65 void __iomem *base;
@@ -57,12 +83,18 @@ struct onenand_flash {
57 (writew(v, this->base + ONENAND_REG_WP_STATUS)) 83 (writew(v, this->base + ONENAND_REG_WP_STATUS))
58 84
59/* It has all 0xff chars */ 85/* It has all 0xff chars */
60#define MAX_ONENAND_PAGESIZE (2048 + 64) 86#define MAX_ONENAND_PAGESIZE (4096 + 128)
61static unsigned char *ffchars; 87static unsigned char *ffchars;
62 88
89#if CONFIG_FLEXONENAND
90#define PARTITION_NAME "Flex-OneNAND simulator partition"
91#else
92#define PARTITION_NAME "OneNAND simulator partition"
93#endif
94
63static struct mtd_partition os_partitions[] = { 95static struct mtd_partition os_partitions[] = {
64 { 96 {
65 .name = "OneNAND simulator partition", 97 .name = PARTITION_NAME,
66 .offset = 0, 98 .offset = 0,
67 .size = MTDPART_SIZ_FULL, 99 .size = MTDPART_SIZ_FULL,
68 }, 100 },
@@ -104,6 +136,7 @@ static void onenand_lock_handle(struct onenand_chip *this, int cmd)
104 136
105 switch (cmd) { 137 switch (cmd) {
106 case ONENAND_CMD_UNLOCK: 138 case ONENAND_CMD_UNLOCK:
139 case ONENAND_CMD_UNLOCK_ALL:
107 if (block_lock_scheme) 140 if (block_lock_scheme)
108 ONENAND_SET_WP_STATUS(ONENAND_WP_US, this); 141 ONENAND_SET_WP_STATUS(ONENAND_WP_US, this);
109 else 142 else
@@ -228,10 +261,12 @@ static void onenand_data_handle(struct onenand_chip *this, int cmd,
228{ 261{
229 struct mtd_info *mtd = &info->mtd; 262 struct mtd_info *mtd = &info->mtd;
230 struct onenand_flash *flash = this->priv; 263 struct onenand_flash *flash = this->priv;
231 int main_offset, spare_offset; 264 int main_offset, spare_offset, die = 0;
232 void __iomem *src; 265 void __iomem *src;
233 void __iomem *dest; 266 void __iomem *dest;
234 unsigned int i; 267 unsigned int i;
268 static int pi_operation;
269 int erasesize, rgn;
235 270
236 if (dataram) { 271 if (dataram) {
237 main_offset = mtd->writesize; 272 main_offset = mtd->writesize;
@@ -241,10 +276,27 @@ static void onenand_data_handle(struct onenand_chip *this, int cmd,
241 spare_offset = 0; 276 spare_offset = 0;
242 } 277 }
243 278
279 if (pi_operation) {
280 die = readw(this->base + ONENAND_REG_START_ADDRESS2);
281 die >>= ONENAND_DDP_SHIFT;
282 }
283
244 switch (cmd) { 284 switch (cmd) {
285 case FLEXONENAND_CMD_PI_ACCESS:
286 pi_operation = 1;
287 break;
288
289 case ONENAND_CMD_RESET:
290 pi_operation = 0;
291 break;
292
245 case ONENAND_CMD_READ: 293 case ONENAND_CMD_READ:
246 src = ONENAND_CORE(flash) + offset; 294 src = ONENAND_CORE(flash) + offset;
247 dest = ONENAND_MAIN_AREA(this, main_offset); 295 dest = ONENAND_MAIN_AREA(this, main_offset);
296 if (pi_operation) {
297 writew(boundary[die], this->base + ONENAND_DATARAM);
298 break;
299 }
248 memcpy(dest, src, mtd->writesize); 300 memcpy(dest, src, mtd->writesize);
249 /* Fall through */ 301 /* Fall through */
250 302
@@ -257,6 +309,10 @@ static void onenand_data_handle(struct onenand_chip *this, int cmd,
257 case ONENAND_CMD_PROG: 309 case ONENAND_CMD_PROG:
258 src = ONENAND_MAIN_AREA(this, main_offset); 310 src = ONENAND_MAIN_AREA(this, main_offset);
259 dest = ONENAND_CORE(flash) + offset; 311 dest = ONENAND_CORE(flash) + offset;
312 if (pi_operation) {
313 boundary[die] = readw(this->base + ONENAND_DATARAM);
314 break;
315 }
260 /* To handle partial write */ 316 /* To handle partial write */
261 for (i = 0; i < (1 << mtd->subpage_sft); i++) { 317 for (i = 0; i < (1 << mtd->subpage_sft); i++) {
262 int off = i * this->subpagesize; 318 int off = i * this->subpagesize;
@@ -284,9 +340,18 @@ static void onenand_data_handle(struct onenand_chip *this, int cmd,
284 break; 340 break;
285 341
286 case ONENAND_CMD_ERASE: 342 case ONENAND_CMD_ERASE:
287 memset(ONENAND_CORE(flash) + offset, 0xff, mtd->erasesize); 343 if (pi_operation)
344 break;
345
346 if (FLEXONENAND(this)) {
347 rgn = flexonenand_region(mtd, offset);
348 erasesize = mtd->eraseregions[rgn].erasesize;
349 } else
350 erasesize = mtd->erasesize;
351
352 memset(ONENAND_CORE(flash) + offset, 0xff, erasesize);
288 memset(ONENAND_CORE_SPARE(flash, this, offset), 0xff, 353 memset(ONENAND_CORE_SPARE(flash, this, offset), 0xff,
289 (mtd->erasesize >> 5)); 354 (erasesize >> 5));
290 break; 355 break;
291 356
292 default: 357 default:
@@ -339,7 +404,7 @@ static void onenand_command_handle(struct onenand_chip *this, int cmd)
339 } 404 }
340 405
341 if (block != -1) 406 if (block != -1)
342 offset += block << this->erase_shift; 407 offset = onenand_addr(this, block);
343 408
344 if (page != -1) 409 if (page != -1)
345 offset += page << this->page_shift; 410 offset += page << this->page_shift;
@@ -390,6 +455,7 @@ static int __init flash_init(struct onenand_flash *flash)
390 } 455 }
391 456
392 density = device_id >> ONENAND_DEVICE_DENSITY_SHIFT; 457 density = device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
458 density &= ONENAND_DEVICE_DENSITY_MASK;
393 size = ((16 << 20) << density); 459 size = ((16 << 20) << density);
394 460
395 ONENAND_CORE(flash) = vmalloc(size + (size >> 5)); 461 ONENAND_CORE(flash) = vmalloc(size + (size >> 5));
@@ -405,8 +471,9 @@ static int __init flash_init(struct onenand_flash *flash)
405 writew(manuf_id, flash->base + ONENAND_REG_MANUFACTURER_ID); 471 writew(manuf_id, flash->base + ONENAND_REG_MANUFACTURER_ID);
406 writew(device_id, flash->base + ONENAND_REG_DEVICE_ID); 472 writew(device_id, flash->base + ONENAND_REG_DEVICE_ID);
407 writew(version_id, flash->base + ONENAND_REG_VERSION_ID); 473 writew(version_id, flash->base + ONENAND_REG_VERSION_ID);
474 writew(technology_id, flash->base + ONENAND_REG_TECHNOLOGY);
408 475
409 if (density < 2) 476 if (density < 2 && (!CONFIG_FLEXONENAND))
410 buffer_size = 0x0400; /* 1KiB page */ 477 buffer_size = 0x0400; /* 1KiB page */
411 else 478 else
412 buffer_size = 0x0800; /* 2KiB page */ 479 buffer_size = 0x0800; /* 2KiB page */
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index b83f6bcfa51a..aa6ba39ff370 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -94,7 +94,6 @@
94#include <linux/atm_tcp.h> 94#include <linux/atm_tcp.h>
95#include <linux/sonet.h> 95#include <linux/sonet.h>
96#include <linux/atm_suni.h> 96#include <linux/atm_suni.h>
97#include <linux/mtd/mtd.h>
98 97
99#include <linux/usb.h> 98#include <linux/usb.h>
100#include <linux/usbdevice_fs.h> 99#include <linux/usbdevice_fs.h>
@@ -1411,46 +1410,6 @@ static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
1411#define HIDPGETCONNLIST _IOR('H', 210, int) 1410#define HIDPGETCONNLIST _IOR('H', 210, int)
1412#define HIDPGETCONNINFO _IOR('H', 211, int) 1411#define HIDPGETCONNINFO _IOR('H', 211, int)
1413 1412
1414struct mtd_oob_buf32 {
1415 u_int32_t start;
1416 u_int32_t length;
1417 compat_caddr_t ptr; /* unsigned char* */
1418};
1419
1420#define MEMWRITEOOB32 _IOWR('M',3,struct mtd_oob_buf32)
1421#define MEMREADOOB32 _IOWR('M',4,struct mtd_oob_buf32)
1422
1423static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
1424{
1425 struct mtd_oob_buf __user *buf = compat_alloc_user_space(sizeof(*buf));
1426 struct mtd_oob_buf32 __user *buf32 = compat_ptr(arg);
1427 u32 data;
1428 char __user *datap;
1429 unsigned int real_cmd;
1430 int err;
1431
1432 real_cmd = (cmd == MEMREADOOB32) ?
1433 MEMREADOOB : MEMWRITEOOB;
1434
1435 if (copy_in_user(&buf->start, &buf32->start,
1436 2 * sizeof(u32)) ||
1437 get_user(data, &buf32->ptr))
1438 return -EFAULT;
1439 datap = compat_ptr(data);
1440 if (put_user(datap, &buf->ptr))
1441 return -EFAULT;
1442
1443 err = sys_ioctl(fd, real_cmd, (unsigned long) buf);
1444
1445 if (!err) {
1446 if (copy_in_user(&buf32->start, &buf->start,
1447 2 * sizeof(u32)))
1448 err = -EFAULT;
1449 }
1450
1451 return err;
1452}
1453
1454#ifdef CONFIG_BLOCK 1413#ifdef CONFIG_BLOCK
1455struct raw32_config_request 1414struct raw32_config_request
1456{ 1415{
@@ -2432,15 +2391,6 @@ COMPATIBLE_IOCTL(USBDEVFS_SUBMITURB32)
2432COMPATIBLE_IOCTL(USBDEVFS_REAPURB32) 2391COMPATIBLE_IOCTL(USBDEVFS_REAPURB32)
2433COMPATIBLE_IOCTL(USBDEVFS_REAPURBNDELAY32) 2392COMPATIBLE_IOCTL(USBDEVFS_REAPURBNDELAY32)
2434COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT) 2393COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT)
2435/* MTD */
2436COMPATIBLE_IOCTL(MEMGETINFO)
2437COMPATIBLE_IOCTL(MEMERASE)
2438COMPATIBLE_IOCTL(MEMLOCK)
2439COMPATIBLE_IOCTL(MEMUNLOCK)
2440COMPATIBLE_IOCTL(MEMGETREGIONCOUNT)
2441COMPATIBLE_IOCTL(MEMGETREGIONINFO)
2442COMPATIBLE_IOCTL(MEMGETBADBLOCK)
2443COMPATIBLE_IOCTL(MEMSETBADBLOCK)
2444/* NBD */ 2394/* NBD */
2445ULONG_IOCTL(NBD_SET_SOCK) 2395ULONG_IOCTL(NBD_SET_SOCK)
2446ULONG_IOCTL(NBD_SET_BLKSIZE) 2396ULONG_IOCTL(NBD_SET_BLKSIZE)
@@ -2550,8 +2500,6 @@ COMPATIBLE_IOCTL(JSIOCGBUTTONS)
2550COMPATIBLE_IOCTL(JSIOCGNAME(0)) 2500COMPATIBLE_IOCTL(JSIOCGNAME(0))
2551 2501
2552/* now things that need handlers */ 2502/* now things that need handlers */
2553HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob)
2554HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob)
2555#ifdef CONFIG_NET 2503#ifdef CONFIG_NET
2556HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32) 2504HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32)
2557HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf) 2505HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf)
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 7efb9be34662..4030ebada49e 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -563,6 +563,7 @@ extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
563 * @options: Option flags, e.g. 16bit buswidth 563 * @options: Option flags, e.g. 16bit buswidth
564 * @ecclayout: ecc layout info structure 564 * @ecclayout: ecc layout info structure
565 * @part_probe_types: NULL-terminated array of probe types 565 * @part_probe_types: NULL-terminated array of probe types
566 * @set_parts: platform specific function to set partitions
566 * @priv: hardware controller specific settings 567 * @priv: hardware controller specific settings
567 */ 568 */
568struct platform_nand_chip { 569struct platform_nand_chip {
@@ -574,26 +575,41 @@ struct platform_nand_chip {
574 int chip_delay; 575 int chip_delay;
575 unsigned int options; 576 unsigned int options;
576 const char **part_probe_types; 577 const char **part_probe_types;
578 void (*set_parts)(uint64_t size,
579 struct platform_nand_chip *chip);
577 void *priv; 580 void *priv;
578}; 581};
579 582
583/* Keep gcc happy */
584struct platform_device;
585
580/** 586/**
581 * struct platform_nand_ctrl - controller level device structure 587 * struct platform_nand_ctrl - controller level device structure
588 * @probe: platform specific function to probe/setup hardware
589 * @remove: platform specific function to remove/teardown hardware
582 * @hwcontrol: platform specific hardware control structure 590 * @hwcontrol: platform specific hardware control structure
583 * @dev_ready: platform specific function to read ready/busy pin 591 * @dev_ready: platform specific function to read ready/busy pin
584 * @select_chip: platform specific chip select function 592 * @select_chip: platform specific chip select function
585 * @cmd_ctrl: platform specific function for controlling 593 * @cmd_ctrl: platform specific function for controlling
586 * ALE/CLE/nCE. Also used to write command and address 594 * ALE/CLE/nCE. Also used to write command and address
595 * @write_buf: platform specific function for write buffer
596 * @read_buf: platform specific function for read buffer
587 * @priv: private data to transport driver specific settings 597 * @priv: private data to transport driver specific settings
588 * 598 *
589 * All fields are optional and depend on the hardware driver requirements 599 * All fields are optional and depend on the hardware driver requirements
590 */ 600 */
591struct platform_nand_ctrl { 601struct platform_nand_ctrl {
602 int (*probe)(struct platform_device *pdev);
603 void (*remove)(struct platform_device *pdev);
592 void (*hwcontrol)(struct mtd_info *mtd, int cmd); 604 void (*hwcontrol)(struct mtd_info *mtd, int cmd);
593 int (*dev_ready)(struct mtd_info *mtd); 605 int (*dev_ready)(struct mtd_info *mtd);
594 void (*select_chip)(struct mtd_info *mtd, int chip); 606 void (*select_chip)(struct mtd_info *mtd, int chip);
595 void (*cmd_ctrl)(struct mtd_info *mtd, int dat, 607 void (*cmd_ctrl)(struct mtd_info *mtd, int dat,
596 unsigned int ctrl); 608 unsigned int ctrl);
609 void (*write_buf)(struct mtd_info *mtd,
610 const uint8_t *buf, int len);
611 void (*read_buf)(struct mtd_info *mtd,
612 uint8_t *buf, int len);
597 void *priv; 613 void *priv;
598}; 614};
599 615
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index 9aa2a9149b58..8ed873374381 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -17,6 +17,7 @@
17#include <linux/mtd/onenand_regs.h> 17#include <linux/mtd/onenand_regs.h>
18#include <linux/mtd/bbm.h> 18#include <linux/mtd/bbm.h>
19 19
20#define MAX_DIES 2
20#define MAX_BUFFERRAM 2 21#define MAX_BUFFERRAM 2
21 22
22/* Scan and identify a OneNAND device */ 23/* Scan and identify a OneNAND device */
@@ -51,7 +52,12 @@ struct onenand_bufferram {
51/** 52/**
52 * struct onenand_chip - OneNAND Private Flash Chip Data 53 * struct onenand_chip - OneNAND Private Flash Chip Data
53 * @base: [BOARDSPECIFIC] address to access OneNAND 54 * @base: [BOARDSPECIFIC] address to access OneNAND
55 * @dies: [INTERN][FLEX-ONENAND] number of dies on chip
56 * @boundary: [INTERN][FLEX-ONENAND] Boundary of the dies
57 * @diesize: [INTERN][FLEX-ONENAND] Size of the dies
54 * @chipsize: [INTERN] the size of one chip for multichip arrays 58 * @chipsize: [INTERN] the size of one chip for multichip arrays
59 * FIXME For Flex-OneNAND, chipsize holds maximum possible
60 * device size ie when all blocks are considered MLC
55 * @device_id: [INTERN] device ID 61 * @device_id: [INTERN] device ID
56 * @density_mask: chip density, used for DDP devices 62 * @density_mask: chip density, used for DDP devices
57 * @verstion_id: [INTERN] version ID 63 * @verstion_id: [INTERN] version ID
@@ -68,6 +74,8 @@ struct onenand_bufferram {
68 * @command: [REPLACEABLE] hardware specific function for writing 74 * @command: [REPLACEABLE] hardware specific function for writing
69 * commands to the chip 75 * commands to the chip
70 * @wait: [REPLACEABLE] hardware specific function for wait on ready 76 * @wait: [REPLACEABLE] hardware specific function for wait on ready
77 * @bbt_wait: [REPLACEABLE] hardware specific function for bbt wait on ready
78 * @unlock_all: [REPLACEABLE] hardware specific function for unlock all
71 * @read_bufferram: [REPLACEABLE] hardware specific function for BufferRAM Area 79 * @read_bufferram: [REPLACEABLE] hardware specific function for BufferRAM Area
72 * @write_bufferram: [REPLACEABLE] hardware specific function for BufferRAM Area 80 * @write_bufferram: [REPLACEABLE] hardware specific function for BufferRAM Area
73 * @read_word: [REPLACEABLE] hardware specific function for read 81 * @read_word: [REPLACEABLE] hardware specific function for read
@@ -92,9 +100,13 @@ struct onenand_bufferram {
92 */ 100 */
93struct onenand_chip { 101struct onenand_chip {
94 void __iomem *base; 102 void __iomem *base;
103 unsigned dies;
104 unsigned boundary[MAX_DIES];
105 loff_t diesize[MAX_DIES];
95 unsigned int chipsize; 106 unsigned int chipsize;
96 unsigned int device_id; 107 unsigned int device_id;
97 unsigned int version_id; 108 unsigned int version_id;
109 unsigned int technology;
98 unsigned int density_mask; 110 unsigned int density_mask;
99 unsigned int options; 111 unsigned int options;
100 112
@@ -108,6 +120,8 @@ struct onenand_chip {
108 120
109 int (*command)(struct mtd_info *mtd, int cmd, loff_t address, size_t len); 121 int (*command)(struct mtd_info *mtd, int cmd, loff_t address, size_t len);
110 int (*wait)(struct mtd_info *mtd, int state); 122 int (*wait)(struct mtd_info *mtd, int state);
123 int (*bbt_wait)(struct mtd_info *mtd, int state);
124 void (*unlock_all)(struct mtd_info *mtd);
111 int (*read_bufferram)(struct mtd_info *mtd, int area, 125 int (*read_bufferram)(struct mtd_info *mtd, int area,
112 unsigned char *buffer, int offset, size_t count); 126 unsigned char *buffer, int offset, size_t count);
113 int (*write_bufferram)(struct mtd_info *mtd, int area, 127 int (*write_bufferram)(struct mtd_info *mtd, int area,
@@ -145,6 +159,8 @@ struct onenand_chip {
145#define ONENAND_SET_BUFFERRAM0(this) (this->bufferram_index = 0) 159#define ONENAND_SET_BUFFERRAM0(this) (this->bufferram_index = 0)
146#define ONENAND_SET_BUFFERRAM1(this) (this->bufferram_index = 1) 160#define ONENAND_SET_BUFFERRAM1(this) (this->bufferram_index = 1)
147 161
162#define FLEXONENAND(this) \
163 (this->device_id & DEVICE_IS_FLEXONENAND)
148#define ONENAND_GET_SYS_CFG1(this) \ 164#define ONENAND_GET_SYS_CFG1(this) \
149 (this->read_word(this->base + ONENAND_REG_SYS_CFG1)) 165 (this->read_word(this->base + ONENAND_REG_SYS_CFG1))
150#define ONENAND_SET_SYS_CFG1(v, this) \ 166#define ONENAND_SET_SYS_CFG1(v, this) \
@@ -153,6 +169,9 @@ struct onenand_chip {
153#define ONENAND_IS_DDP(this) \ 169#define ONENAND_IS_DDP(this) \
154 (this->device_id & ONENAND_DEVICE_IS_DDP) 170 (this->device_id & ONENAND_DEVICE_IS_DDP)
155 171
172#define ONENAND_IS_MLC(this) \
173 (this->technology & ONENAND_TECHNOLOGY_IS_MLC)
174
156#ifdef CONFIG_MTD_ONENAND_2X_PROGRAM 175#ifdef CONFIG_MTD_ONENAND_2X_PROGRAM
157#define ONENAND_IS_2PLANE(this) \ 176#define ONENAND_IS_2PLANE(this) \
158 (this->options & ONENAND_HAS_2PLANE) 177 (this->options & ONENAND_HAS_2PLANE)
@@ -169,6 +188,7 @@ struct onenand_chip {
169#define ONENAND_HAS_CONT_LOCK (0x0001) 188#define ONENAND_HAS_CONT_LOCK (0x0001)
170#define ONENAND_HAS_UNLOCK_ALL (0x0002) 189#define ONENAND_HAS_UNLOCK_ALL (0x0002)
171#define ONENAND_HAS_2PLANE (0x0004) 190#define ONENAND_HAS_2PLANE (0x0004)
191#define ONENAND_SKIP_UNLOCK_CHECK (0x0100)
172#define ONENAND_PAGEBUF_ALLOC (0x1000) 192#define ONENAND_PAGEBUF_ALLOC (0x1000)
173#define ONENAND_OOBBUF_ALLOC (0x2000) 193#define ONENAND_OOBBUF_ALLOC (0x2000)
174 194
@@ -176,6 +196,7 @@ struct onenand_chip {
176 * OneNAND Flash Manufacturer ID Codes 196 * OneNAND Flash Manufacturer ID Codes
177 */ 197 */
178#define ONENAND_MFR_SAMSUNG 0xec 198#define ONENAND_MFR_SAMSUNG 0xec
199#define ONENAND_MFR_NUMONYX 0x20
179 200
180/** 201/**
181 * struct onenand_manufacturers - NAND Flash Manufacturer ID Structure 202 * struct onenand_manufacturers - NAND Flash Manufacturer ID Structure
@@ -189,5 +210,8 @@ struct onenand_manufacturers {
189 210
190int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, 211int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
191 struct mtd_oob_ops *ops); 212 struct mtd_oob_ops *ops);
213unsigned onenand_block(struct onenand_chip *this, loff_t addr);
214loff_t onenand_addr(struct onenand_chip *this, int block);
215int flexonenand_region(struct mtd_info *mtd, loff_t addr);
192 216
193#endif /* __LINUX_MTD_ONENAND_H */ 217#endif /* __LINUX_MTD_ONENAND_H */
diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h
index 0c6bbe28f38c..86a6bbef6465 100644
--- a/include/linux/mtd/onenand_regs.h
+++ b/include/linux/mtd/onenand_regs.h
@@ -67,6 +67,9 @@
67/* 67/*
68 * Device ID Register F001h (R) 68 * Device ID Register F001h (R)
69 */ 69 */
70#define DEVICE_IS_FLEXONENAND (1 << 9)
71#define FLEXONENAND_PI_MASK (0x3ff)
72#define FLEXONENAND_PI_UNLOCK_SHIFT (14)
70#define ONENAND_DEVICE_DENSITY_MASK (0xf) 73#define ONENAND_DEVICE_DENSITY_MASK (0xf)
71#define ONENAND_DEVICE_DENSITY_SHIFT (4) 74#define ONENAND_DEVICE_DENSITY_SHIFT (4)
72#define ONENAND_DEVICE_IS_DDP (1 << 3) 75#define ONENAND_DEVICE_IS_DDP (1 << 3)
@@ -84,6 +87,11 @@
84#define ONENAND_VERSION_PROCESS_SHIFT (8) 87#define ONENAND_VERSION_PROCESS_SHIFT (8)
85 88
86/* 89/*
90 * Technology Register F006h (R)
91 */
92#define ONENAND_TECHNOLOGY_IS_MLC (1 << 0)
93
94/*
87 * Start Address 1 F100h (R/W) & Start Address 2 F101h (R/W) 95 * Start Address 1 F100h (R/W) & Start Address 2 F101h (R/W)
88 */ 96 */
89#define ONENAND_DDP_SHIFT (15) 97#define ONENAND_DDP_SHIFT (15)
@@ -93,7 +101,8 @@
93/* 101/*
94 * Start Address 8 F107h (R/W) 102 * Start Address 8 F107h (R/W)
95 */ 103 */
96#define ONENAND_FPA_MASK (0x3f) 104/* Note: It's actually 0x3f in case of SLC */
105#define ONENAND_FPA_MASK (0x7f)
97#define ONENAND_FPA_SHIFT (2) 106#define ONENAND_FPA_SHIFT (2)
98#define ONENAND_FSA_MASK (0x03) 107#define ONENAND_FSA_MASK (0x03)
99 108
@@ -105,7 +114,8 @@
105#define ONENAND_BSA_BOOTRAM (0 << 2) 114#define ONENAND_BSA_BOOTRAM (0 << 2)
106#define ONENAND_BSA_DATARAM0 (2 << 2) 115#define ONENAND_BSA_DATARAM0 (2 << 2)
107#define ONENAND_BSA_DATARAM1 (3 << 2) 116#define ONENAND_BSA_DATARAM1 (3 << 2)
108#define ONENAND_BSC_MASK (0x03) 117/* Note: It's actually 0x03 in case of SLC */
118#define ONENAND_BSC_MASK (0x07)
109 119
110/* 120/*
111 * Command Register F220h (R/W) 121 * Command Register F220h (R/W)
@@ -124,9 +134,13 @@
124#define ONENAND_CMD_RESET (0xF0) 134#define ONENAND_CMD_RESET (0xF0)
125#define ONENAND_CMD_OTP_ACCESS (0x65) 135#define ONENAND_CMD_OTP_ACCESS (0x65)
126#define ONENAND_CMD_READID (0x90) 136#define ONENAND_CMD_READID (0x90)
137#define FLEXONENAND_CMD_PI_UPDATE (0x05)
138#define FLEXONENAND_CMD_PI_ACCESS (0x66)
139#define FLEXONENAND_CMD_RECOVER_LSB (0x05)
127 140
128/* NOTE: Those are not *REAL* commands */ 141/* NOTE: Those are not *REAL* commands */
129#define ONENAND_CMD_BUFFERRAM (0x1978) 142#define ONENAND_CMD_BUFFERRAM (0x1978)
143#define FLEXONENAND_CMD_READ_PI (0x1985)
130 144
131/* 145/*
132 * System Configuration 1 Register F221h (R, R/W) 146 * System Configuration 1 Register F221h (R, R/W)
@@ -192,10 +206,12 @@
192#define ONENAND_ECC_1BIT_ALL (0x5555) 206#define ONENAND_ECC_1BIT_ALL (0x5555)
193#define ONENAND_ECC_2BIT (1 << 1) 207#define ONENAND_ECC_2BIT (1 << 1)
194#define ONENAND_ECC_2BIT_ALL (0xAAAA) 208#define ONENAND_ECC_2BIT_ALL (0xAAAA)
209#define FLEXONENAND_UNCORRECTABLE_ERROR (0x1010)
195 210
196/* 211/*
197 * One-Time Programmable (OTP) 212 * One-Time Programmable (OTP)
198 */ 213 */
214#define FLEXONENAND_OTP_LOCK_OFFSET (2048)
199#define ONENAND_OTP_LOCK_OFFSET (14) 215#define ONENAND_OTP_LOCK_OFFSET (14)
200 216
201#endif /* __ONENAND_REG_H */ 217#endif /* __ONENAND_REG_H */
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index 7535a74083b9..af6dcb992bc3 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -40,7 +40,6 @@ struct mtd_partition {
40 uint64_t offset; /* offset within the master MTD space */ 40 uint64_t offset; /* offset within the master MTD space */
41 uint32_t mask_flags; /* master MTD flags to mask out for this partition */ 41 uint32_t mask_flags; /* master MTD flags to mask out for this partition */
42 struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/ 42 struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/
43 struct mtd_info **mtdp; /* pointer to store the MTD object */
44}; 43};
45 44
46#define MTDPART_OFS_NXTBLK (-2) 45#define MTDPART_OFS_NXTBLK (-2)
diff --git a/include/mtd/Kbuild b/include/mtd/Kbuild
index 8eb018f96002..192f8fb7d546 100644
--- a/include/mtd/Kbuild
+++ b/include/mtd/Kbuild
@@ -1,5 +1,4 @@
1header-y += inftl-user.h 1header-y += inftl-user.h
2header-y += jffs2-user.h
3header-y += mtd-abi.h 2header-y += mtd-abi.h
4header-y += mtd-user.h 3header-y += mtd-user.h
5header-y += nftl-user.h 4header-y += nftl-user.h
diff --git a/include/mtd/jffs2-user.h b/include/mtd/jffs2-user.h
deleted file mode 100644
index fa94b0eb67c1..000000000000
--- a/include/mtd/jffs2-user.h
+++ /dev/null
@@ -1,34 +0,0 @@
1/*
2 * JFFS2 definitions for use in user space only
3 */
4
5#ifndef __JFFS2_USER_H__
6#define __JFFS2_USER_H__
7
8/* This file is blessed for inclusion by userspace */
9#include <linux/jffs2.h>
10#include <linux/types.h>
11#include <endian.h>
12#include <byteswap.h>
13
14#undef cpu_to_je16
15#undef cpu_to_je32
16#undef cpu_to_jemode
17#undef je16_to_cpu
18#undef je32_to_cpu
19#undef jemode_to_cpu
20
21extern int target_endian;
22
23#define t16(x) ({ __u16 __b = (x); (target_endian==__BYTE_ORDER)?__b:bswap_16(__b); })
24#define t32(x) ({ __u32 __b = (x); (target_endian==__BYTE_ORDER)?__b:bswap_32(__b); })
25
26#define cpu_to_je16(x) ((jint16_t){t16(x)})
27#define cpu_to_je32(x) ((jint32_t){t32(x)})
28#define cpu_to_jemode(x) ((jmode_t){t32(x)})
29
30#define je16_to_cpu(x) (t16((x).v16))
31#define je32_to_cpu(x) (t32((x).v32))
32#define jemode_to_cpu(x) (t32((x).m))
33
34#endif /* __JFFS2_USER_H__ */
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index b6595b3c68b6..be51ae2bd0ff 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -12,12 +12,24 @@ struct erase_info_user {
12 __u32 length; 12 __u32 length;
13}; 13};
14 14
15struct erase_info_user64 {
16 __u64 start;
17 __u64 length;
18};
19
15struct mtd_oob_buf { 20struct mtd_oob_buf {
16 __u32 start; 21 __u32 start;
17 __u32 length; 22 __u32 length;
18 unsigned char __user *ptr; 23 unsigned char __user *ptr;
19}; 24};
20 25
26struct mtd_oob_buf64 {
27 __u64 start;
28 __u32 pad;
29 __u32 length;
30 __u64 usr_ptr;
31};
32
21#define MTD_ABSENT 0 33#define MTD_ABSENT 0
22#define MTD_RAM 1 34#define MTD_RAM 1
23#define MTD_ROM 2 35#define MTD_ROM 2
@@ -95,6 +107,9 @@ struct otp_info {
95#define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout) 107#define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout)
96#define ECCGETSTATS _IOR('M', 18, struct mtd_ecc_stats) 108#define ECCGETSTATS _IOR('M', 18, struct mtd_ecc_stats)
97#define MTDFILEMODE _IO('M', 19) 109#define MTDFILEMODE _IO('M', 19)
110#define MEMERASE64 _IOW('M', 20, struct erase_info_user64)
111#define MEMWRITEOOB64 _IOWR('M', 21, struct mtd_oob_buf64)
112#define MEMREADOOB64 _IOWR('M', 22, struct mtd_oob_buf64)
98 113
99/* 114/*
100 * Obsolete legacy interface. Keep it in order not to break userspace 115 * Obsolete legacy interface. Keep it in order not to break userspace