aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-22 19:56:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-22 19:56:22 -0400
commitac1b7c378ef26fba6694d5f118fe7fc16fee2fe2 (patch)
tree3f72979545bb070eb2c3e903cbf31dc4aef3ffc9 /drivers/mtd
parent9e268beb92ee3a853b3946e84b10358207e2085f (diff)
parentc90173f0907486fe4010c2a8cef534e2473db43f (diff)
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: (63 commits) mtd: OneNAND: Allow setting of boundary information when built as module jffs2: leaking jffs2_summary in function jffs2_scan_medium mtd: nand: Fix memory leak on txx9ndfmc probe failure. mtd: orion_nand: use burst reads with double word accesses mtd/nand: s3c6400 support for s3c2410 driver [MTD] [NAND] S3C2410: Use DIV_ROUND_UP [MTD] [NAND] S3C2410: Deal with unaligned lengths in S3C2440 buffer read/write [MTD] [NAND] S3C2410: Allow the machine code to get the BBT table from NAND [MTD] [NAND] S3C2410: Added a kerneldoc for s3c2410_nand_set mtd: physmap_of: Add multiple regions and concatenation support mtd: nand: max_retries off by one in mxc_nand mtd: nand: s3c2410_nand_setrate(): use correct macros for 2412/2440 mtd: onenand: add bbt_wait & unlock_all as replaceable for some platform mtd: Flex-OneNAND support mtd: nand: add OMAP2/OMAP3 NAND driver mtd: maps: Blackfin async: fix memory leaks in probe/remove funcs mtd: uclinux: mark local stuff static mtd: uclinux: do not allow to be built as a module mtd: uclinux: allow systems to override map addr/size mtd: blackfin NFC: fix hang when using NAND on BF527-EZKITs ...
Diffstat (limited to 'drivers/mtd')
-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/Kconfig24
-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/orion_nand.c23
-rw-r--r--drivers/mtd/nand/plat_nand.c19
-rw-r--r--drivers/mtd/nand/s3c2410.c268
-rw-r--r--drivers/mtd/nand/txx9ndfmc.c16
-rw-r--r--drivers/mtd/onenand/omap2.c4
-rw-r--r--drivers/mtd/onenand/onenand_base.c862
-rw-r--r--drivers/mtd/onenand/onenand_bbt.c14
-rw-r--r--drivers/mtd/onenand/onenand_sim.c81
35 files changed, 2898 insertions, 720 deletions
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 aaac3b6800b7..c3f62654b6df 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -291,7 +291,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
291 gd->private_data = new; 291 gd->private_data = new;
292 new->blkcore_priv = gd; 292 new->blkcore_priv = gd;
293 gd->queue = tr->blkcore_priv->rq; 293 gd->queue = tr->blkcore_priv->rq;
294 gd->driverfs_dev = new->mtd->dev.parent; 294 gd->driverfs_dev = &new->mtd->dev;
295 295
296 if (new->readonly) 296 if (new->readonly)
297 set_disk_ro(gd, 1); 297 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 f3276897859e..ce96c091f01b 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
@@ -139,27 +145,27 @@ config MTD_NAND_PPCHAMELEONEVB
139 This enables the NAND flash driver on the PPChameleon EVB Board. 145 This enables the NAND flash driver on the PPChameleon EVB Board.
140 146
141config MTD_NAND_S3C2410 147config MTD_NAND_S3C2410
142 tristate "NAND Flash support for S3C2410/S3C2440 SoC" 148 tristate "NAND Flash support for Samsung S3C SoCs"
143 depends on ARCH_S3C2410 149 depends on ARCH_S3C2410 || ARCH_S3C64XX
144 help 150 help
145 This enables the NAND flash controller on the S3C2410 and S3C2440 151 This enables the NAND flash controller on the S3C24xx and S3C64xx
146 SoCs 152 SoCs
147 153
148 No board specific support is done by this driver, each board 154 No board specific support is done by this driver, each board
149 must advertise a platform_device for the driver to attach. 155 must advertise a platform_device for the driver to attach.
150 156
151config MTD_NAND_S3C2410_DEBUG 157config MTD_NAND_S3C2410_DEBUG
152 bool "S3C2410 NAND driver debug" 158 bool "Samsung S3C NAND driver debug"
153 depends on MTD_NAND_S3C2410 159 depends on MTD_NAND_S3C2410
154 help 160 help
155 Enable debugging of the S3C2410 NAND driver 161 Enable debugging of the S3C NAND driver
156 162
157config MTD_NAND_S3C2410_HWECC 163config MTD_NAND_S3C2410_HWECC
158 bool "S3C2410 NAND Hardware ECC" 164 bool "Samsung S3C NAND Hardware ECC"
159 depends on MTD_NAND_S3C2410 165 depends on MTD_NAND_S3C2410
160 help 166 help
161 Enable the use of the S3C2410's internal ECC generator when 167 Enable the use of the controller's internal ECC generator when
162 using NAND. Early versions of the chip have had problems with 168 using NAND. Early versions of the chips have had problems with
163 incorrect ECC generation, and if using these, the default of 169 incorrect ECC generation, and if using these, the default of
164 software ECC is preferable. 170 software ECC is preferable.
165 171
@@ -171,7 +177,7 @@ config MTD_NAND_NDFC
171 NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs 177 NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs
172 178
173config MTD_NAND_S3C2410_CLKSTOP 179config MTD_NAND_S3C2410_CLKSTOP
174 bool "S3C2410 NAND IDLE clock stop" 180 bool "Samsung S3C NAND IDLE clock stop"
175 depends on MTD_NAND_S3C2410 181 depends on MTD_NAND_S3C2410
176 default n 182 default n
177 help 183 help
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 02700f769b8a..0fad6487e6f4 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;
@@ -441,12 +660,56 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
441 spin_unlock_irq(&davinci_nand_lock); 660 spin_unlock_irq(&davinci_nand_lock);
442 661
443 /* Scan to find existence of the device(s) */ 662 /* Scan to find existence of the device(s) */
444 ret = nand_scan(&info->mtd, pdata->mask_chipsel ? 2 : 1); 663 ret = nand_scan_ident(&info->mtd, pdata->mask_chipsel ? 2 : 1);
445 if (ret < 0) { 664 if (ret < 0) {
446 dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); 665 dev_dbg(&pdev->dev, "no NAND chip(s) found\n");
447 goto err_scan; 666 goto err_scan;
448 } 667 }
449 668
669 /* Update ECC layout if needed ... for 1-bit HW ECC, the default
670 * is OK, but it allocates 6 bytes when only 3 are needed (for
671 * each 512 bytes). For the 4-bit HW ECC, that default is not
672 * usable: 10 bytes are needed, not 6.
673 */
674 if (pdata->ecc_bits == 4) {
675 int chunks = info->mtd.writesize / 512;
676
677 if (!chunks || info->mtd.oobsize < 16) {
678 dev_dbg(&pdev->dev, "too small\n");
679 ret = -EINVAL;
680 goto err_scan;
681 }
682
683 /* For small page chips, preserve the manufacturer's
684 * badblock marking data ... and make sure a flash BBT
685 * table marker fits in the free bytes.
686 */
687 if (chunks == 1) {
688 info->ecclayout = hwecc4_small;
689 info->ecclayout.oobfree[1].length =
690 info->mtd.oobsize - 16;
691 goto syndrome_done;
692 }
693
694 /* For large page chips we'll be wanting to use a
695 * not-yet-implemented mode that reads OOB data
696 * before reading the body of the page, to avoid
697 * the "infix OOB" model of NAND_ECC_HW_SYNDROME
698 * (and preserve manufacturer badblock markings).
699 */
700 dev_warn(&pdev->dev, "no 4-bit ECC support yet "
701 "for large page NAND\n");
702 ret = -EIO;
703 goto err_scan;
704
705syndrome_done:
706 info->chip.ecc.layout = &info->ecclayout;
707 }
708
709 ret = nand_scan_tail(&info->mtd);
710 if (ret < 0)
711 goto err_scan;
712
450 if (mtd_has_partitions()) { 713 if (mtd_has_partitions()) {
451 struct mtd_partition *mtd_parts = NULL; 714 struct mtd_partition *mtd_parts = NULL;
452 int mtd_parts_nb = 0; 715 int mtd_parts_nb = 0;
@@ -455,22 +718,11 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
455 static const char *probes[] __initconst = 718 static const char *probes[] __initconst =
456 { "cmdlinepart", NULL }; 719 { "cmdlinepart", NULL };
457 720
458 const char *master_name;
459
460 /* Set info->mtd.name = 0 temporarily */
461 master_name = info->mtd.name;
462 info->mtd.name = (char *)0;
463
464 /* info->mtd.name == 0, means: don't bother checking
465 <mtd-id> */
466 mtd_parts_nb = parse_mtd_partitions(&info->mtd, probes, 721 mtd_parts_nb = parse_mtd_partitions(&info->mtd, probes,
467 &mtd_parts, 0); 722 &mtd_parts, 0);
468
469 /* Restore info->mtd.name */
470 info->mtd.name = master_name;
471 } 723 }
472 724
473 if (mtd_parts_nb <= 0 && pdata) { 725 if (mtd_parts_nb <= 0) {
474 mtd_parts = pdata->parts; 726 mtd_parts = pdata->parts;
475 mtd_parts_nb = pdata->nr_parts; 727 mtd_parts_nb = pdata->nr_parts;
476 } 728 }
@@ -483,7 +735,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
483 info->partitioned = true; 735 info->partitioned = true;
484 } 736 }
485 737
486 } else if (pdata && pdata->nr_parts) { 738 } else if (pdata->nr_parts) {
487 dev_warn(&pdev->dev, "ignoring %d default partitions on %s\n", 739 dev_warn(&pdev->dev, "ignoring %d default partitions on %s\n",
488 pdata->nr_parts, info->mtd.name); 740 pdata->nr_parts, info->mtd.name);
489 } 741 }
@@ -509,6 +761,11 @@ err_scan:
509err_clk_enable: 761err_clk_enable:
510 clk_put(info->clk); 762 clk_put(info->clk);
511 763
764 spin_lock_irq(&davinci_nand_lock);
765 if (ecc_mode == NAND_ECC_HW_SYNDROME)
766 ecc4_busy = false;
767 spin_unlock_irq(&davinci_nand_lock);
768
512err_ecc: 769err_ecc:
513err_clk: 770err_clk:
514err_ioremap: 771err_ioremap:
@@ -532,6 +789,11 @@ static int __exit nand_davinci_remove(struct platform_device *pdev)
532 else 789 else
533 status = del_mtd_device(&info->mtd); 790 status = del_mtd_device(&info->mtd);
534 791
792 spin_lock_irq(&davinci_nand_lock);
793 if (info->chip.ecc.mode == NAND_ECC_HW_SYNDROME)
794 ecc4_busy = false;
795 spin_unlock_irq(&davinci_nand_lock);
796
535 iounmap(info->base); 797 iounmap(info->base);
536 iounmap(info->vaddr); 798 iounmap(info->vaddr);
537 799
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/orion_nand.c b/drivers/mtd/nand/orion_nand.c
index c2dfd3ea353d..7ad972229db4 100644
--- a/drivers/mtd/nand/orion_nand.c
+++ b/drivers/mtd/nand/orion_nand.c
@@ -47,6 +47,28 @@ static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl
47 writeb(cmd, nc->IO_ADDR_W + offs); 47 writeb(cmd, nc->IO_ADDR_W + offs);
48} 48}
49 49
50static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
51{
52 struct nand_chip *chip = mtd->priv;
53 void __iomem *io_base = chip->IO_ADDR_R;
54 uint64_t *buf64;
55 int i = 0;
56
57 while (len && (unsigned long)buf & 7) {
58 *buf++ = readb(io_base);
59 len--;
60 }
61 buf64 = (uint64_t *)buf;
62 while (i < len/8) {
63 uint64_t x;
64 asm ("ldrd\t%0, [%1]" : "=r" (x) : "r" (io_base));
65 buf64[i++] = x;
66 }
67 i *= 8;
68 while (i < len)
69 buf[i++] = readb(io_base);
70}
71
50static int __init orion_nand_probe(struct platform_device *pdev) 72static int __init orion_nand_probe(struct platform_device *pdev)
51{ 73{
52 struct mtd_info *mtd; 74 struct mtd_info *mtd;
@@ -83,6 +105,7 @@ static int __init orion_nand_probe(struct platform_device *pdev)
83 nc->priv = board; 105 nc->priv = board;
84 nc->IO_ADDR_R = nc->IO_ADDR_W = io_base; 106 nc->IO_ADDR_R = nc->IO_ADDR_W = io_base;
85 nc->cmd_ctrl = orion_nand_cmd_ctrl; 107 nc->cmd_ctrl = orion_nand_cmd_ctrl;
108 nc->read_buf = orion_nand_read_buf;
86 nc->ecc.mode = NAND_ECC_SOFT; 109 nc->ecc.mode = NAND_ECC_SOFT;
87 110
88 if (board->chip_delay) 111 if (board->chip_delay)
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 8e375d5fe231..11dc7e69c4fb 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -74,6 +74,14 @@ static struct nand_ecclayout nand_hw_eccoob = {
74 74
75struct s3c2410_nand_info; 75struct s3c2410_nand_info;
76 76
77/**
78 * struct s3c2410_nand_mtd - driver MTD structure
79 * @mtd: The MTD instance to pass to the MTD layer.
80 * @chip: The NAND chip information.
81 * @set: The platform information supplied for this set of NAND chips.
82 * @info: Link back to the hardware information.
83 * @scan_res: The result from calling nand_scan_ident().
84*/
77struct s3c2410_nand_mtd { 85struct s3c2410_nand_mtd {
78 struct mtd_info mtd; 86 struct mtd_info mtd;
79 struct nand_chip chip; 87 struct nand_chip chip;
@@ -90,6 +98,21 @@ enum s3c_cpu_type {
90 98
91/* overview of the s3c2410 nand state */ 99/* overview of the s3c2410 nand state */
92 100
101/**
102 * struct s3c2410_nand_info - NAND controller state.
103 * @mtds: An array of MTD instances on this controoler.
104 * @platform: The platform data for this board.
105 * @device: The platform device we bound to.
106 * @area: The IO area resource that came from request_mem_region().
107 * @clk: The clock resource for this controller.
108 * @regs: The area mapped for the hardware registers described by @area.
109 * @sel_reg: Pointer to the register controlling the NAND selection.
110 * @sel_bit: The bit in @sel_reg to select the NAND chip.
111 * @mtd_count: The number of MTDs created from this controller.
112 * @save_sel: The contents of @sel_reg to be saved over suspend.
113 * @clk_rate: The clock rate from @clk.
114 * @cpu_type: The exact type of this controller.
115 */
93struct s3c2410_nand_info { 116struct s3c2410_nand_info {
94 /* mtd info */ 117 /* mtd info */
95 struct nand_hw_control controller; 118 struct nand_hw_control controller;
@@ -145,12 +168,19 @@ static inline int allow_clk_stop(struct s3c2410_nand_info *info)
145 168
146#define NS_IN_KHZ 1000000 169#define NS_IN_KHZ 1000000
147 170
171/**
172 * s3c_nand_calc_rate - calculate timing data.
173 * @wanted: The cycle time in nanoseconds.
174 * @clk: The clock rate in kHz.
175 * @max: The maximum divider value.
176 *
177 * Calculate the timing value from the given parameters.
178 */
148static int s3c_nand_calc_rate(int wanted, unsigned long clk, int max) 179static int s3c_nand_calc_rate(int wanted, unsigned long clk, int max)
149{ 180{
150 int result; 181 int result;
151 182
152 result = (wanted * clk) / NS_IN_KHZ; 183 result = DIV_ROUND_UP((wanted * clk), NS_IN_KHZ);
153 result++;
154 184
155 pr_debug("result %d from %ld, %d\n", result, clk, wanted); 185 pr_debug("result %d from %ld, %d\n", result, clk, wanted);
156 186
@@ -169,13 +199,21 @@ static int s3c_nand_calc_rate(int wanted, unsigned long clk, int max)
169 199
170/* controller setup */ 200/* controller setup */
171 201
202/**
203 * s3c2410_nand_setrate - setup controller timing information.
204 * @info: The controller instance.
205 *
206 * Given the information supplied by the platform, calculate and set
207 * the necessary timing registers in the hardware to generate the
208 * necessary timing cycles to the hardware.
209 */
172static int s3c2410_nand_setrate(struct s3c2410_nand_info *info) 210static int s3c2410_nand_setrate(struct s3c2410_nand_info *info)
173{ 211{
174 struct s3c2410_platform_nand *plat = info->platform; 212 struct s3c2410_platform_nand *plat = info->platform;
175 int tacls_max = (info->cpu_type == TYPE_S3C2412) ? 8 : 4; 213 int tacls_max = (info->cpu_type == TYPE_S3C2412) ? 8 : 4;
176 int tacls, twrph0, twrph1; 214 int tacls, twrph0, twrph1;
177 unsigned long clkrate = clk_get_rate(info->clk); 215 unsigned long clkrate = clk_get_rate(info->clk);
178 unsigned long set, cfg, mask; 216 unsigned long uninitialized_var(set), cfg, uninitialized_var(mask);
179 unsigned long flags; 217 unsigned long flags;
180 218
181 /* calculate the timing information for the controller */ 219 /* calculate the timing information for the controller */
@@ -215,9 +253,9 @@ static int s3c2410_nand_setrate(struct s3c2410_nand_info *info)
215 253
216 case TYPE_S3C2440: 254 case TYPE_S3C2440:
217 case TYPE_S3C2412: 255 case TYPE_S3C2412:
218 mask = (S3C2410_NFCONF_TACLS(tacls_max - 1) | 256 mask = (S3C2440_NFCONF_TACLS(tacls_max - 1) |
219 S3C2410_NFCONF_TWRPH0(7) | 257 S3C2440_NFCONF_TWRPH0(7) |
220 S3C2410_NFCONF_TWRPH1(7)); 258 S3C2440_NFCONF_TWRPH1(7));
221 259
222 set = S3C2440_NFCONF_TACLS(tacls - 1); 260 set = S3C2440_NFCONF_TACLS(tacls - 1);
223 set |= S3C2440_NFCONF_TWRPH0(twrph0 - 1); 261 set |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);
@@ -225,14 +263,9 @@ static int s3c2410_nand_setrate(struct s3c2410_nand_info *info)
225 break; 263 break;
226 264
227 default: 265 default:
228 /* keep compiler happy */
229 mask = 0;
230 set = 0;
231 BUG(); 266 BUG();
232 } 267 }
233 268
234 dev_dbg(info->device, "NF_CONF is 0x%lx\n", cfg);
235
236 local_irq_save(flags); 269 local_irq_save(flags);
237 270
238 cfg = readl(info->regs + S3C2410_NFCONF); 271 cfg = readl(info->regs + S3C2410_NFCONF);
@@ -242,9 +275,18 @@ static int s3c2410_nand_setrate(struct s3c2410_nand_info *info)
242 275
243 local_irq_restore(flags); 276 local_irq_restore(flags);
244 277
278 dev_dbg(info->device, "NF_CONF is 0x%lx\n", cfg);
279
245 return 0; 280 return 0;
246} 281}
247 282
283/**
284 * s3c2410_nand_inithw - basic hardware initialisation
285 * @info: The hardware state.
286 *
287 * Do the basic initialisation of the hardware, using s3c2410_nand_setrate()
288 * to setup the hardware access speeds and set the controller to be enabled.
289*/
248static int s3c2410_nand_inithw(struct s3c2410_nand_info *info) 290static int s3c2410_nand_inithw(struct s3c2410_nand_info *info)
249{ 291{
250 int ret; 292 int ret;
@@ -268,8 +310,19 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info)
268 return 0; 310 return 0;
269} 311}
270 312
271/* select chip */ 313/**
272 314 * s3c2410_nand_select_chip - select the given nand chip
315 * @mtd: The MTD instance for this chip.
316 * @chip: The chip number.
317 *
318 * This is called by the MTD layer to either select a given chip for the
319 * @mtd instance, or to indicate that the access has finished and the
320 * chip can be de-selected.
321 *
322 * The routine ensures that the nFCE line is correctly setup, and any
323 * platform specific selection code is called to route nFCE to the specific
324 * chip.
325 */
273static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) 326static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
274{ 327{
275 struct s3c2410_nand_info *info; 328 struct s3c2410_nand_info *info;
@@ -530,7 +583,16 @@ static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
530static void s3c2440_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) 583static void s3c2440_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
531{ 584{
532 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 585 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
533 readsl(info->regs + S3C2440_NFDATA, buf, len / 4); 586
587 readsl(info->regs + S3C2440_NFDATA, buf, len >> 2);
588
589 /* cleanup if we've got less than a word to do */
590 if (len & 3) {
591 buf += len & ~3;
592
593 for (; len & 3; len--)
594 *buf++ = readb(info->regs + S3C2440_NFDATA);
595 }
534} 596}
535 597
536static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) 598static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
@@ -542,7 +604,16 @@ static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int
542static void s3c2440_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) 604static void s3c2440_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
543{ 605{
544 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 606 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
545 writesl(info->regs + S3C2440_NFDATA, buf, len / 4); 607
608 writesl(info->regs + S3C2440_NFDATA, buf, len >> 2);
609
610 /* cleanup any fractional write */
611 if (len & 3) {
612 buf += len & ~3;
613
614 for (; len & 3; len--, buf++)
615 writeb(*buf, info->regs + S3C2440_NFDATA);
616 }
546} 617}
547 618
548/* cpufreq driver support */ 619/* cpufreq driver support */
@@ -593,7 +664,7 @@ static inline void s3c2410_nand_cpufreq_deregister(struct s3c2410_nand_info *inf
593 664
594/* device management functions */ 665/* device management functions */
595 666
596static int s3c2410_nand_remove(struct platform_device *pdev) 667static int s3c24xx_nand_remove(struct platform_device *pdev)
597{ 668{
598 struct s3c2410_nand_info *info = to_nand_info(pdev); 669 struct s3c2410_nand_info *info = to_nand_info(pdev);
599 670
@@ -645,17 +716,31 @@ static int s3c2410_nand_remove(struct platform_device *pdev)
645} 716}
646 717
647#ifdef CONFIG_MTD_PARTITIONS 718#ifdef CONFIG_MTD_PARTITIONS
719const char *part_probes[] = { "cmdlinepart", NULL };
648static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, 720static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
649 struct s3c2410_nand_mtd *mtd, 721 struct s3c2410_nand_mtd *mtd,
650 struct s3c2410_nand_set *set) 722 struct s3c2410_nand_set *set)
651{ 723{
724 struct mtd_partition *part_info;
725 int nr_part = 0;
726
652 if (set == NULL) 727 if (set == NULL)
653 return add_mtd_device(&mtd->mtd); 728 return add_mtd_device(&mtd->mtd);
654 729
655 if (set->nr_partitions > 0 && set->partitions != NULL) { 730 if (set->nr_partitions == 0) {
656 return add_mtd_partitions(&mtd->mtd, set->partitions, set->nr_partitions); 731 mtd->mtd.name = set->name;
732 nr_part = parse_mtd_partitions(&mtd->mtd, part_probes,
733 &part_info, 0);
734 } else {
735 if (set->nr_partitions > 0 && set->partitions != NULL) {
736 nr_part = set->nr_partitions;
737 part_info = set->partitions;
738 }
657 } 739 }
658 740
741 if (nr_part > 0 && part_info)
742 return add_mtd_partitions(&mtd->mtd, part_info, nr_part);
743
659 return add_mtd_device(&mtd->mtd); 744 return add_mtd_device(&mtd->mtd);
660} 745}
661#else 746#else
@@ -667,11 +752,16 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
667} 752}
668#endif 753#endif
669 754
670/* s3c2410_nand_init_chip 755/**
756 * s3c2410_nand_init_chip - initialise a single instance of an chip
757 * @info: The base NAND controller the chip is on.
758 * @nmtd: The new controller MTD instance to fill in.
759 * @set: The information passed from the board specific platform data.
671 * 760 *
672 * init a single instance of an chip 761 * Initialise the given @nmtd from the information in @info and @set. This
673*/ 762 * readies the structure for use with the MTD layer functions by ensuring
674 763 * all pointers are setup and the necessary control routines selected.
764 */
675static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, 765static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
676 struct s3c2410_nand_mtd *nmtd, 766 struct s3c2410_nand_mtd *nmtd,
677 struct s3c2410_nand_set *set) 767 struct s3c2410_nand_set *set)
@@ -757,14 +847,40 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
757 847
758 if (set->disable_ecc) 848 if (set->disable_ecc)
759 chip->ecc.mode = NAND_ECC_NONE; 849 chip->ecc.mode = NAND_ECC_NONE;
850
851 switch (chip->ecc.mode) {
852 case NAND_ECC_NONE:
853 dev_info(info->device, "NAND ECC disabled\n");
854 break;
855 case NAND_ECC_SOFT:
856 dev_info(info->device, "NAND soft ECC\n");
857 break;
858 case NAND_ECC_HW:
859 dev_info(info->device, "NAND hardware ECC\n");
860 break;
861 default:
862 dev_info(info->device, "NAND ECC UNKNOWN\n");
863 break;
864 }
865
866 /* If you use u-boot BBT creation code, specifying this flag will
867 * let the kernel fish out the BBT from the NAND, and also skip the
868 * full NAND scan that can take 1/2s or so. Little things... */
869 if (set->flash_bbt)
870 chip->options |= NAND_USE_FLASH_BBT | NAND_SKIP_BBTSCAN;
760} 871}
761 872
762/* s3c2410_nand_update_chip 873/**
874 * s3c2410_nand_update_chip - post probe update
875 * @info: The controller instance.
876 * @nmtd: The driver version of the MTD instance.
763 * 877 *
764 * post-probe chip update, to change any items, such as the 878 * This routine is called after the chip probe has succesfully completed
765 * layout for large page nand 879 * and the relevant per-chip information updated. This call ensure that
766 */ 880 * we update the internal state accordingly.
767 881 *
882 * The internal state is currently limited to the ECC state information.
883*/
768static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info, 884static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info,
769 struct s3c2410_nand_mtd *nmtd) 885 struct s3c2410_nand_mtd *nmtd)
770{ 886{
@@ -773,33 +889,33 @@ static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info,
773 dev_dbg(info->device, "chip %p => page shift %d\n", 889 dev_dbg(info->device, "chip %p => page shift %d\n",
774 chip, chip->page_shift); 890 chip, chip->page_shift);
775 891
776 if (hardware_ecc) { 892 if (chip->ecc.mode != NAND_ECC_HW)
893 return;
894
777 /* change the behaviour depending on wether we are using 895 /* change the behaviour depending on wether we are using
778 * the large or small page nand device */ 896 * the large or small page nand device */
779 897
780 if (chip->page_shift > 10) { 898 if (chip->page_shift > 10) {
781 chip->ecc.size = 256; 899 chip->ecc.size = 256;
782 chip->ecc.bytes = 3; 900 chip->ecc.bytes = 3;
783 } else { 901 } else {
784 chip->ecc.size = 512; 902 chip->ecc.size = 512;
785 chip->ecc.bytes = 3; 903 chip->ecc.bytes = 3;
786 chip->ecc.layout = &nand_hw_eccoob; 904 chip->ecc.layout = &nand_hw_eccoob;
787 }
788 } 905 }
789} 906}
790 907
791/* s3c2410_nand_probe 908/* s3c24xx_nand_probe
792 * 909 *
793 * called by device layer when it finds a device matching 910 * called by device layer when it finds a device matching
794 * one our driver can handled. This code checks to see if 911 * one our driver can handled. This code checks to see if
795 * it can allocate all necessary resources then calls the 912 * it can allocate all necessary resources then calls the
796 * nand layer to look for devices 913 * nand layer to look for devices
797*/ 914*/
798 915static int s3c24xx_nand_probe(struct platform_device *pdev)
799static int s3c24xx_nand_probe(struct platform_device *pdev,
800 enum s3c_cpu_type cpu_type)
801{ 916{
802 struct s3c2410_platform_nand *plat = to_nand_plat(pdev); 917 struct s3c2410_platform_nand *plat = to_nand_plat(pdev);
918 enum s3c_cpu_type cpu_type;
803 struct s3c2410_nand_info *info; 919 struct s3c2410_nand_info *info;
804 struct s3c2410_nand_mtd *nmtd; 920 struct s3c2410_nand_mtd *nmtd;
805 struct s3c2410_nand_set *sets; 921 struct s3c2410_nand_set *sets;
@@ -809,6 +925,8 @@ static int s3c24xx_nand_probe(struct platform_device *pdev,
809 int nr_sets; 925 int nr_sets;
810 int setno; 926 int setno;
811 927
928 cpu_type = platform_get_device_id(pdev)->driver_data;
929
812 pr_debug("s3c2410_nand_probe(%p)\n", pdev); 930 pr_debug("s3c2410_nand_probe(%p)\n", pdev);
813 931
814 info = kmalloc(sizeof(*info), GFP_KERNEL); 932 info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -922,7 +1040,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev,
922 return 0; 1040 return 0;
923 1041
924 exit_error: 1042 exit_error:
925 s3c2410_nand_remove(pdev); 1043 s3c24xx_nand_remove(pdev);
926 1044
927 if (err == 0) 1045 if (err == 0)
928 err = -EINVAL; 1046 err = -EINVAL;
@@ -983,50 +1101,33 @@ static int s3c24xx_nand_resume(struct platform_device *dev)
983 1101
984/* driver device registration */ 1102/* driver device registration */
985 1103
986static int s3c2410_nand_probe(struct platform_device *dev) 1104static struct platform_device_id s3c24xx_driver_ids[] = {
987{ 1105 {
988 return s3c24xx_nand_probe(dev, TYPE_S3C2410); 1106 .name = "s3c2410-nand",
989} 1107 .driver_data = TYPE_S3C2410,
990 1108 }, {
991static int s3c2440_nand_probe(struct platform_device *dev) 1109 .name = "s3c2440-nand",
992{ 1110 .driver_data = TYPE_S3C2440,
993 return s3c24xx_nand_probe(dev, TYPE_S3C2440); 1111 }, {
994} 1112 .name = "s3c2412-nand",
995 1113 .driver_data = TYPE_S3C2412,
996static int s3c2412_nand_probe(struct platform_device *dev) 1114 }, {
997{ 1115 .name = "s3c6400-nand",
998 return s3c24xx_nand_probe(dev, TYPE_S3C2412); 1116 .driver_data = TYPE_S3C2412, /* compatible with 2412 */
999}
1000
1001static struct platform_driver s3c2410_nand_driver = {
1002 .probe = s3c2410_nand_probe,
1003 .remove = s3c2410_nand_remove,
1004 .suspend = s3c24xx_nand_suspend,
1005 .resume = s3c24xx_nand_resume,
1006 .driver = {
1007 .name = "s3c2410-nand",
1008 .owner = THIS_MODULE,
1009 }, 1117 },
1118 { }
1010}; 1119};
1011 1120
1012static struct platform_driver s3c2440_nand_driver = { 1121MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids);
1013 .probe = s3c2440_nand_probe,
1014 .remove = s3c2410_nand_remove,
1015 .suspend = s3c24xx_nand_suspend,
1016 .resume = s3c24xx_nand_resume,
1017 .driver = {
1018 .name = "s3c2440-nand",
1019 .owner = THIS_MODULE,
1020 },
1021};
1022 1122
1023static struct platform_driver s3c2412_nand_driver = { 1123static struct platform_driver s3c24xx_nand_driver = {
1024 .probe = s3c2412_nand_probe, 1124 .probe = s3c24xx_nand_probe,
1025 .remove = s3c2410_nand_remove, 1125 .remove = s3c24xx_nand_remove,
1026 .suspend = s3c24xx_nand_suspend, 1126 .suspend = s3c24xx_nand_suspend,
1027 .resume = s3c24xx_nand_resume, 1127 .resume = s3c24xx_nand_resume,
1128 .id_table = s3c24xx_driver_ids,
1028 .driver = { 1129 .driver = {
1029 .name = "s3c2412-nand", 1130 .name = "s3c24xx-nand",
1030 .owner = THIS_MODULE, 1131 .owner = THIS_MODULE,
1031 }, 1132 },
1032}; 1133};
@@ -1035,16 +1136,12 @@ static int __init s3c2410_nand_init(void)
1035{ 1136{
1036 printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n"); 1137 printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n");
1037 1138
1038 platform_driver_register(&s3c2412_nand_driver); 1139 return platform_driver_register(&s3c24xx_nand_driver);
1039 platform_driver_register(&s3c2440_nand_driver);
1040 return platform_driver_register(&s3c2410_nand_driver);
1041} 1140}
1042 1141
1043static void __exit s3c2410_nand_exit(void) 1142static void __exit s3c2410_nand_exit(void)
1044{ 1143{
1045 platform_driver_unregister(&s3c2412_nand_driver); 1144 platform_driver_unregister(&s3c24xx_nand_driver);
1046 platform_driver_unregister(&s3c2440_nand_driver);
1047 platform_driver_unregister(&s3c2410_nand_driver);
1048} 1145}
1049 1146
1050module_init(s3c2410_nand_init); 1147module_init(s3c2410_nand_init);
@@ -1053,6 +1150,3 @@ module_exit(s3c2410_nand_exit);
1053MODULE_LICENSE("GPL"); 1150MODULE_LICENSE("GPL");
1054MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 1151MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
1055MODULE_DESCRIPTION("S3C24XX MTD NAND driver"); 1152MODULE_DESCRIPTION("S3C24XX MTD NAND driver");
1056MODULE_ALIAS("platform:s3c2410-nand");
1057MODULE_ALIAS("platform:s3c2412-nand");
1058MODULE_ALIAS("platform:s3c2440-nand");
diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c
index 812479264896..488088eff2ca 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,16 +334,23 @@ 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 } else { 339 } else {
340 txx9_priv->cs = -1; 340 txx9_priv->cs = -1;
341 strcpy(txx9_priv->mtdname, dev_name(&dev->dev)); 341 txx9_priv->mtdname = kstrdup(dev_name(&dev->dev),
342 GFP_KERNEL);
343 }
344 if (!txx9_priv->mtdname) {
345 kfree(txx9_priv);
346 dev_err(&dev->dev, "Unable to allocate MTD name.\n");
347 continue;
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;
345 351
346 if (nand_scan(mtd, 1)) { 352 if (nand_scan(mtd, 1)) {
353 kfree(txx9_priv->mtdname);
347 kfree(txx9_priv); 354 kfree(txx9_priv);
348 continue; 355 continue;
349 } 356 }
@@ -385,6 +392,7 @@ static int __exit txx9ndfmc_remove(struct platform_device *dev)
385 kfree(drvdata->parts[i]); 392 kfree(drvdata->parts[i]);
386#endif 393#endif
387 del_mtd_device(mtd); 394 del_mtd_device(mtd);
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 6391e3dc8002..38d656b9b2ee 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -565,7 +565,7 @@ int omap2_onenand_rephase(void)
565 NULL, __adjust_timing); 565 NULL, __adjust_timing);
566} 566}
567 567
568static void __devexit omap2_onenand_shutdown(struct platform_device *pdev) 568static void omap2_onenand_shutdown(struct platform_device *pdev)
569{ 569{
570 struct omap2_onenand *c = dev_get_drvdata(&pdev->dev); 570 struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
571 571
@@ -777,7 +777,7 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev)
777 777
778static struct platform_driver omap2_onenand_driver = { 778static struct platform_driver omap2_onenand_driver = {
779 .probe = omap2_onenand_probe, 779 .probe = omap2_onenand_probe,
780 .remove = omap2_onenand_remove, 780 .remove = __devexit_p(omap2_onenand_remove),
781 .shutdown = omap2_onenand_shutdown, 781 .shutdown = omap2_onenand_shutdown,
782 .driver = { 782 .driver = {
783 .name = DRIVER_NAME, 783 .name = DRIVER_NAME,
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 30d6999e5f9f..6e829095ea9d 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.
@@ -16,6 +20,7 @@
16 20
17#include <linux/kernel.h> 21#include <linux/kernel.h>
18#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/moduleparam.h>
19#include <linux/init.h> 24#include <linux/init.h>
20#include <linux/sched.h> 25#include <linux/sched.h>
21#include <linux/delay.h> 26#include <linux/delay.h>
@@ -27,6 +32,38 @@
27 32
28#include <asm/io.h> 33#include <asm/io.h>
29 34
35/* Default Flex-OneNAND boundary and lock respectively */
36static int flex_bdry[MAX_DIES * 2] = { -1, 0, -1, 0 };
37
38module_param_array(flex_bdry, int, NULL, 0400);
39MODULE_PARM_DESC(flex_bdry, "SLC Boundary information for Flex-OneNAND"
40 "Syntax:flex_bdry=DIE_BDRY,LOCK,..."
41 "DIE_BDRY: SLC boundary of the die"
42 "LOCK: Locking information for SLC boundary"
43 " : 0->Set boundary in unlocked status"
44 " : 1->Set boundary in locked status");
45
46/**
47 * onenand_oob_128 - oob info for Flex-Onenand with 4KB page
48 * For now, we expose only 64 out of 80 ecc bytes
49 */
50static struct nand_ecclayout onenand_oob_128 = {
51 .eccbytes = 64,
52 .eccpos = {
53 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
54 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
55 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
56 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
57 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
58 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
59 102, 103, 104, 105
60 },
61 .oobfree = {
62 {2, 4}, {18, 4}, {34, 4}, {50, 4},
63 {66, 4}, {82, 4}, {98, 4}, {114, 4}
64 }
65};
66
30/** 67/**
31 * onenand_oob_64 - oob info for large (2KB) page 68 * onenand_oob_64 - oob info for large (2KB) page
32 */ 69 */
@@ -65,6 +102,14 @@ static const unsigned char ffchars[] = {
65 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */ 102 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */
66 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 103 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
67 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */ 104 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */
105 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
106 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 80 */
107 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
108 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 96 */
109 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
110 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 112 */
111 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
112 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 128 */
68}; 113};
69 114
70/** 115/**
@@ -171,6 +216,70 @@ static int onenand_buffer_address(int dataram1, int sectors, int count)
171} 216}
172 217
173/** 218/**
219 * flexonenand_block- For given address return block number
220 * @param this - OneNAND device structure
221 * @param addr - Address for which block number is needed
222 */
223static unsigned flexonenand_block(struct onenand_chip *this, loff_t addr)
224{
225 unsigned boundary, blk, die = 0;
226
227 if (ONENAND_IS_DDP(this) && addr >= this->diesize[0]) {
228 die = 1;
229 addr -= this->diesize[0];
230 }
231
232 boundary = this->boundary[die];
233
234 blk = addr >> (this->erase_shift - 1);
235 if (blk > boundary)
236 blk = (blk + boundary + 1) >> 1;
237
238 blk += die ? this->density_mask : 0;
239 return blk;
240}
241
242inline unsigned onenand_block(struct onenand_chip *this, loff_t addr)
243{
244 if (!FLEXONENAND(this))
245 return addr >> this->erase_shift;
246 return flexonenand_block(this, addr);
247}
248
249/**
250 * flexonenand_addr - Return address of the block
251 * @this: OneNAND device structure
252 * @block: Block number on Flex-OneNAND
253 *
254 * Return address of the block
255 */
256static loff_t flexonenand_addr(struct onenand_chip *this, int block)
257{
258 loff_t ofs = 0;
259 int die = 0, boundary;
260
261 if (ONENAND_IS_DDP(this) && block >= this->density_mask) {
262 block -= this->density_mask;
263 die = 1;
264 ofs = this->diesize[0];
265 }
266
267 boundary = this->boundary[die];
268 ofs += (loff_t)block << (this->erase_shift - 1);
269 if (block > (boundary + 1))
270 ofs += (loff_t)(block - boundary - 1) << (this->erase_shift - 1);
271 return ofs;
272}
273
274loff_t onenand_addr(struct onenand_chip *this, int block)
275{
276 if (!FLEXONENAND(this))
277 return (loff_t)block << this->erase_shift;
278 return flexonenand_addr(this, block);
279}
280EXPORT_SYMBOL(onenand_addr);
281
282/**
174 * onenand_get_density - [DEFAULT] Get OneNAND density 283 * onenand_get_density - [DEFAULT] Get OneNAND density
175 * @param dev_id OneNAND device ID 284 * @param dev_id OneNAND device ID
176 * 285 *
@@ -183,6 +292,22 @@ static inline int onenand_get_density(int dev_id)
183} 292}
184 293
185/** 294/**
295 * flexonenand_region - [Flex-OneNAND] Return erase region of addr
296 * @param mtd MTD device structure
297 * @param addr address whose erase region needs to be identified
298 */
299int flexonenand_region(struct mtd_info *mtd, loff_t addr)
300{
301 int i;
302
303 for (i = 0; i < mtd->numeraseregions; i++)
304 if (addr < mtd->eraseregions[i].offset)
305 break;
306 return i - 1;
307}
308EXPORT_SYMBOL(flexonenand_region);
309
310/**
186 * onenand_command - [DEFAULT] Send command to OneNAND device 311 * onenand_command - [DEFAULT] Send command to OneNAND device
187 * @param mtd MTD device structure 312 * @param mtd MTD device structure
188 * @param cmd the command to be sent 313 * @param cmd the command to be sent
@@ -207,16 +332,28 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
207 page = -1; 332 page = -1;
208 break; 333 break;
209 334
335 case FLEXONENAND_CMD_PI_ACCESS:
336 /* addr contains die index */
337 block = addr * this->density_mask;
338 page = -1;
339 break;
340
210 case ONENAND_CMD_ERASE: 341 case ONENAND_CMD_ERASE:
211 case ONENAND_CMD_BUFFERRAM: 342 case ONENAND_CMD_BUFFERRAM:
212 case ONENAND_CMD_OTP_ACCESS: 343 case ONENAND_CMD_OTP_ACCESS:
213 block = (int) (addr >> this->erase_shift); 344 block = onenand_block(this, addr);
214 page = -1; 345 page = -1;
215 break; 346 break;
216 347
348 case FLEXONENAND_CMD_READ_PI:
349 cmd = ONENAND_CMD_READ;
350 block = addr * this->density_mask;
351 page = 0;
352 break;
353
217 default: 354 default:
218 block = (int) (addr >> this->erase_shift); 355 block = onenand_block(this, addr);
219 page = (int) (addr >> this->page_shift); 356 page = (int) (addr - onenand_addr(this, block)) >> this->page_shift;
220 357
221 if (ONENAND_IS_2PLANE(this)) { 358 if (ONENAND_IS_2PLANE(this)) {
222 /* Make the even block number */ 359 /* Make the even block number */
@@ -236,7 +373,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
236 value = onenand_bufferram_address(this, block); 373 value = onenand_bufferram_address(this, block);
237 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); 374 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
238 375
239 if (ONENAND_IS_2PLANE(this)) 376 if (ONENAND_IS_MLC(this) || ONENAND_IS_2PLANE(this))
240 /* It is always BufferRAM0 */ 377 /* It is always BufferRAM0 */
241 ONENAND_SET_BUFFERRAM0(this); 378 ONENAND_SET_BUFFERRAM0(this);
242 else 379 else
@@ -258,13 +395,18 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
258 395
259 if (page != -1) { 396 if (page != -1) {
260 /* Now we use page size operation */ 397 /* Now we use page size operation */
261 int sectors = 4, count = 4; 398 int sectors = 0, count = 0;
262 int dataram; 399 int dataram;
263 400
264 switch (cmd) { 401 switch (cmd) {
402 case FLEXONENAND_CMD_RECOVER_LSB:
265 case ONENAND_CMD_READ: 403 case ONENAND_CMD_READ:
266 case ONENAND_CMD_READOOB: 404 case ONENAND_CMD_READOOB:
267 dataram = ONENAND_SET_NEXT_BUFFERRAM(this); 405 if (ONENAND_IS_MLC(this))
406 /* It is always BufferRAM0 */
407 dataram = ONENAND_SET_BUFFERRAM0(this);
408 else
409 dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
268 break; 410 break;
269 411
270 default: 412 default:
@@ -293,6 +435,30 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
293} 435}
294 436
295/** 437/**
438 * onenand_read_ecc - return ecc status
439 * @param this onenand chip structure
440 */
441static inline int onenand_read_ecc(struct onenand_chip *this)
442{
443 int ecc, i, result = 0;
444
445 if (!FLEXONENAND(this))
446 return this->read_word(this->base + ONENAND_REG_ECC_STATUS);
447
448 for (i = 0; i < 4; i++) {
449 ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS + i);
450 if (likely(!ecc))
451 continue;
452 if (ecc & FLEXONENAND_UNCORRECTABLE_ERROR)
453 return ONENAND_ECC_2BIT_ALL;
454 else
455 result = ONENAND_ECC_1BIT_ALL;
456 }
457
458 return result;
459}
460
461/**
296 * onenand_wait - [DEFAULT] wait until the command is done 462 * onenand_wait - [DEFAULT] wait until the command is done
297 * @param mtd MTD device structure 463 * @param mtd MTD device structure
298 * @param state state to select the max. timeout value 464 * @param state state to select the max. timeout value
@@ -331,14 +497,14 @@ static int onenand_wait(struct mtd_info *mtd, int state)
331 * power off recovery (POR) test, it should read ECC status first 497 * power off recovery (POR) test, it should read ECC status first
332 */ 498 */
333 if (interrupt & ONENAND_INT_READ) { 499 if (interrupt & ONENAND_INT_READ) {
334 int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); 500 int ecc = onenand_read_ecc(this);
335 if (ecc) { 501 if (ecc) {
336 if (ecc & ONENAND_ECC_2BIT_ALL) { 502 if (ecc & ONENAND_ECC_2BIT_ALL) {
337 printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc); 503 printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc);
338 mtd->ecc_stats.failed++; 504 mtd->ecc_stats.failed++;
339 return -EBADMSG; 505 return -EBADMSG;
340 } else if (ecc & ONENAND_ECC_1BIT_ALL) { 506 } else if (ecc & ONENAND_ECC_1BIT_ALL) {
341 printk(KERN_INFO "onenand_wait: correctable ECC error = 0x%04x\n", ecc); 507 printk(KERN_DEBUG "onenand_wait: correctable ECC error = 0x%04x\n", ecc);
342 mtd->ecc_stats.corrected++; 508 mtd->ecc_stats.corrected++;
343 } 509 }
344 } 510 }
@@ -656,7 +822,7 @@ static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
656 822
657 if (found && ONENAND_IS_DDP(this)) { 823 if (found && ONENAND_IS_DDP(this)) {
658 /* Select DataRAM for DDP */ 824 /* Select DataRAM for DDP */
659 int block = (int) (addr >> this->erase_shift); 825 int block = onenand_block(this, addr);
660 int value = onenand_bufferram_address(this, block); 826 int value = onenand_bufferram_address(this, block);
661 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); 827 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
662 } 828 }
@@ -816,6 +982,149 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int col
816} 982}
817 983
818/** 984/**
985 * onenand_recover_lsb - [Flex-OneNAND] Recover LSB page data
986 * @param mtd MTD device structure
987 * @param addr address to recover
988 * @param status return value from onenand_wait / onenand_bbt_wait
989 *
990 * MLC NAND Flash cell has paired pages - LSB page and MSB page. LSB page has
991 * lower page address and MSB page has higher page address in paired pages.
992 * If power off occurs during MSB page program, the paired LSB page data can
993 * become corrupt. LSB page recovery read is a way to read LSB page though page
994 * data are corrupted. When uncorrectable error occurs as a result of LSB page
995 * read after power up, issue LSB page recovery read.
996 */
997static int onenand_recover_lsb(struct mtd_info *mtd, loff_t addr, int status)
998{
999 struct onenand_chip *this = mtd->priv;
1000 int i;
1001
1002 /* Recovery is only for Flex-OneNAND */
1003 if (!FLEXONENAND(this))
1004 return status;
1005
1006 /* check if we failed due to uncorrectable error */
1007 if (status != -EBADMSG && status != ONENAND_BBT_READ_ECC_ERROR)
1008 return status;
1009
1010 /* check if address lies in MLC region */
1011 i = flexonenand_region(mtd, addr);
1012 if (mtd->eraseregions[i].erasesize < (1 << this->erase_shift))
1013 return status;
1014
1015 /* We are attempting to reread, so decrement stats.failed
1016 * which was incremented by onenand_wait due to read failure
1017 */
1018 printk(KERN_INFO "onenand_recover_lsb: Attempting to recover from uncorrectable read\n");
1019 mtd->ecc_stats.failed--;
1020
1021 /* Issue the LSB page recovery command */
1022 this->command(mtd, FLEXONENAND_CMD_RECOVER_LSB, addr, this->writesize);
1023 return this->wait(mtd, FL_READING);
1024}
1025
1026/**
1027 * onenand_mlc_read_ops_nolock - MLC OneNAND read main and/or out-of-band
1028 * @param mtd MTD device structure
1029 * @param from offset to read from
1030 * @param ops: oob operation description structure
1031 *
1032 * MLC OneNAND / Flex-OneNAND has 4KB page size and 4KB dataram.
1033 * So, read-while-load is not present.
1034 */
1035static int onenand_mlc_read_ops_nolock(struct mtd_info *mtd, loff_t from,
1036 struct mtd_oob_ops *ops)
1037{
1038 struct onenand_chip *this = mtd->priv;
1039 struct mtd_ecc_stats stats;
1040 size_t len = ops->len;
1041 size_t ooblen = ops->ooblen;
1042 u_char *buf = ops->datbuf;
1043 u_char *oobbuf = ops->oobbuf;
1044 int read = 0, column, thislen;
1045 int oobread = 0, oobcolumn, thisooblen, oobsize;
1046 int ret = 0;
1047 int writesize = this->writesize;
1048
1049 DEBUG(MTD_DEBUG_LEVEL3, "onenand_mlc_read_ops_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
1050
1051 if (ops->mode == MTD_OOB_AUTO)
1052 oobsize = this->ecclayout->oobavail;
1053 else
1054 oobsize = mtd->oobsize;
1055
1056 oobcolumn = from & (mtd->oobsize - 1);
1057
1058 /* Do not allow reads past end of device */
1059 if (from + len > mtd->size) {
1060 printk(KERN_ERR "onenand_mlc_read_ops_nolock: Attempt read beyond end of device\n");
1061 ops->retlen = 0;
1062 ops->oobretlen = 0;
1063 return -EINVAL;
1064 }
1065
1066 stats = mtd->ecc_stats;
1067
1068 while (read < len) {
1069 cond_resched();
1070
1071 thislen = min_t(int, writesize, len - read);
1072
1073 column = from & (writesize - 1);
1074 if (column + thislen > writesize)
1075 thislen = writesize - column;
1076
1077 if (!onenand_check_bufferram(mtd, from)) {
1078 this->command(mtd, ONENAND_CMD_READ, from, writesize);
1079
1080 ret = this->wait(mtd, FL_READING);
1081 if (unlikely(ret))
1082 ret = onenand_recover_lsb(mtd, from, ret);
1083 onenand_update_bufferram(mtd, from, !ret);
1084 if (ret == -EBADMSG)
1085 ret = 0;
1086 }
1087
1088 this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
1089 if (oobbuf) {
1090 thisooblen = oobsize - oobcolumn;
1091 thisooblen = min_t(int, thisooblen, ooblen - oobread);
1092
1093 if (ops->mode == MTD_OOB_AUTO)
1094 onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen);
1095 else
1096 this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
1097 oobread += thisooblen;
1098 oobbuf += thisooblen;
1099 oobcolumn = 0;
1100 }
1101
1102 read += thislen;
1103 if (read == len)
1104 break;
1105
1106 from += thislen;
1107 buf += thislen;
1108 }
1109
1110 /*
1111 * Return success, if no ECC failures, else -EBADMSG
1112 * fs driver will take care of that, because
1113 * retlen == desired len and result == -EBADMSG
1114 */
1115 ops->retlen = read;
1116 ops->oobretlen = oobread;
1117
1118 if (ret)
1119 return ret;
1120
1121 if (mtd->ecc_stats.failed - stats.failed)
1122 return -EBADMSG;
1123
1124 return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
1125}
1126
1127/**
819 * onenand_read_ops_nolock - [OneNAND Interface] OneNAND read main and/or out-of-band 1128 * onenand_read_ops_nolock - [OneNAND Interface] OneNAND read main and/or out-of-band
820 * @param mtd MTD device structure 1129 * @param mtd MTD device structure
821 * @param from offset to read from 1130 * @param from offset to read from
@@ -962,7 +1271,7 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
962 size_t len = ops->ooblen; 1271 size_t len = ops->ooblen;
963 mtd_oob_mode_t mode = ops->mode; 1272 mtd_oob_mode_t mode = ops->mode;
964 u_char *buf = ops->oobbuf; 1273 u_char *buf = ops->oobbuf;
965 int ret = 0; 1274 int ret = 0, readcmd;
966 1275
967 from += ops->ooboffs; 1276 from += ops->ooboffs;
968 1277
@@ -993,17 +1302,22 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
993 1302
994 stats = mtd->ecc_stats; 1303 stats = mtd->ecc_stats;
995 1304
1305 readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1306
996 while (read < len) { 1307 while (read < len) {
997 cond_resched(); 1308 cond_resched();
998 1309
999 thislen = oobsize - column; 1310 thislen = oobsize - column;
1000 thislen = min_t(int, thislen, len); 1311 thislen = min_t(int, thislen, len);
1001 1312
1002 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize); 1313 this->command(mtd, readcmd, from, mtd->oobsize);
1003 1314
1004 onenand_update_bufferram(mtd, from, 0); 1315 onenand_update_bufferram(mtd, from, 0);
1005 1316
1006 ret = this->wait(mtd, FL_READING); 1317 ret = this->wait(mtd, FL_READING);
1318 if (unlikely(ret))
1319 ret = onenand_recover_lsb(mtd, from, ret);
1320
1007 if (ret && ret != -EBADMSG) { 1321 if (ret && ret != -EBADMSG) {
1008 printk(KERN_ERR "onenand_read_oob_nolock: read failed = 0x%x\n", ret); 1322 printk(KERN_ERR "onenand_read_oob_nolock: read failed = 0x%x\n", ret);
1009 break; 1323 break;
@@ -1053,6 +1367,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, 1367static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
1054 size_t *retlen, u_char *buf) 1368 size_t *retlen, u_char *buf)
1055{ 1369{
1370 struct onenand_chip *this = mtd->priv;
1056 struct mtd_oob_ops ops = { 1371 struct mtd_oob_ops ops = {
1057 .len = len, 1372 .len = len,
1058 .ooblen = 0, 1373 .ooblen = 0,
@@ -1062,7 +1377,9 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
1062 int ret; 1377 int ret;
1063 1378
1064 onenand_get_device(mtd, FL_READING); 1379 onenand_get_device(mtd, FL_READING);
1065 ret = onenand_read_ops_nolock(mtd, from, &ops); 1380 ret = ONENAND_IS_MLC(this) ?
1381 onenand_mlc_read_ops_nolock(mtd, from, &ops) :
1382 onenand_read_ops_nolock(mtd, from, &ops);
1066 onenand_release_device(mtd); 1383 onenand_release_device(mtd);
1067 1384
1068 *retlen = ops.retlen; 1385 *retlen = ops.retlen;
@@ -1080,6 +1397,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, 1397static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
1081 struct mtd_oob_ops *ops) 1398 struct mtd_oob_ops *ops)
1082{ 1399{
1400 struct onenand_chip *this = mtd->priv;
1083 int ret; 1401 int ret;
1084 1402
1085 switch (ops->mode) { 1403 switch (ops->mode) {
@@ -1094,7 +1412,9 @@ static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
1094 1412
1095 onenand_get_device(mtd, FL_READING); 1413 onenand_get_device(mtd, FL_READING);
1096 if (ops->datbuf) 1414 if (ops->datbuf)
1097 ret = onenand_read_ops_nolock(mtd, from, ops); 1415 ret = ONENAND_IS_MLC(this) ?
1416 onenand_mlc_read_ops_nolock(mtd, from, ops) :
1417 onenand_read_ops_nolock(mtd, from, ops);
1098 else 1418 else
1099 ret = onenand_read_oob_nolock(mtd, from, ops); 1419 ret = onenand_read_oob_nolock(mtd, from, ops);
1100 onenand_release_device(mtd); 1420 onenand_release_device(mtd);
@@ -1128,11 +1448,11 @@ static int onenand_bbt_wait(struct mtd_info *mtd, int state)
1128 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); 1448 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
1129 1449
1130 if (interrupt & ONENAND_INT_READ) { 1450 if (interrupt & ONENAND_INT_READ) {
1131 int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); 1451 int ecc = onenand_read_ecc(this);
1132 if (ecc & ONENAND_ECC_2BIT_ALL) { 1452 if (ecc & ONENAND_ECC_2BIT_ALL) {
1133 printk(KERN_INFO "onenand_bbt_wait: ecc error = 0x%04x" 1453 printk(KERN_INFO "onenand_bbt_wait: ecc error = 0x%04x"
1134 ", controller error 0x%04x\n", ecc, ctrl); 1454 ", controller error 0x%04x\n", ecc, ctrl);
1135 return ONENAND_BBT_READ_ERROR; 1455 return ONENAND_BBT_READ_ECC_ERROR;
1136 } 1456 }
1137 } else { 1457 } else {
1138 printk(KERN_ERR "onenand_bbt_wait: read timeout!" 1458 printk(KERN_ERR "onenand_bbt_wait: read timeout!"
@@ -1163,7 +1483,7 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
1163{ 1483{
1164 struct onenand_chip *this = mtd->priv; 1484 struct onenand_chip *this = mtd->priv;
1165 int read = 0, thislen, column; 1485 int read = 0, thislen, column;
1166 int ret = 0; 1486 int ret = 0, readcmd;
1167 size_t len = ops->ooblen; 1487 size_t len = ops->ooblen;
1168 u_char *buf = ops->oobbuf; 1488 u_char *buf = ops->oobbuf;
1169 1489
@@ -1183,17 +1503,22 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
1183 1503
1184 column = from & (mtd->oobsize - 1); 1504 column = from & (mtd->oobsize - 1);
1185 1505
1506 readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1507
1186 while (read < len) { 1508 while (read < len) {
1187 cond_resched(); 1509 cond_resched();
1188 1510
1189 thislen = mtd->oobsize - column; 1511 thislen = mtd->oobsize - column;
1190 thislen = min_t(int, thislen, len); 1512 thislen = min_t(int, thislen, len);
1191 1513
1192 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize); 1514 this->command(mtd, readcmd, from, mtd->oobsize);
1193 1515
1194 onenand_update_bufferram(mtd, from, 0); 1516 onenand_update_bufferram(mtd, from, 0);
1195 1517
1196 ret = onenand_bbt_wait(mtd, FL_READING); 1518 ret = this->bbt_wait(mtd, FL_READING);
1519 if (unlikely(ret))
1520 ret = onenand_recover_lsb(mtd, from, ret);
1521
1197 if (ret) 1522 if (ret)
1198 break; 1523 break;
1199 1524
@@ -1230,9 +1555,11 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to
1230{ 1555{
1231 struct onenand_chip *this = mtd->priv; 1556 struct onenand_chip *this = mtd->priv;
1232 u_char *oob_buf = this->oob_buf; 1557 u_char *oob_buf = this->oob_buf;
1233 int status, i; 1558 int status, i, readcmd;
1234 1559
1235 this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize); 1560 readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
1561
1562 this->command(mtd, readcmd, to, mtd->oobsize);
1236 onenand_update_bufferram(mtd, to, 0); 1563 onenand_update_bufferram(mtd, to, 0);
1237 status = this->wait(mtd, FL_READING); 1564 status = this->wait(mtd, FL_READING);
1238 if (status) 1565 if (status)
@@ -1633,7 +1960,7 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
1633{ 1960{
1634 struct onenand_chip *this = mtd->priv; 1961 struct onenand_chip *this = mtd->priv;
1635 int column, ret = 0, oobsize; 1962 int column, ret = 0, oobsize;
1636 int written = 0; 1963 int written = 0, oobcmd;
1637 u_char *oobbuf; 1964 u_char *oobbuf;
1638 size_t len = ops->ooblen; 1965 size_t len = ops->ooblen;
1639 const u_char *buf = ops->oobbuf; 1966 const u_char *buf = ops->oobbuf;
@@ -1675,6 +2002,8 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
1675 2002
1676 oobbuf = this->oob_buf; 2003 oobbuf = this->oob_buf;
1677 2004
2005 oobcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB;
2006
1678 /* Loop until all data write */ 2007 /* Loop until all data write */
1679 while (written < len) { 2008 while (written < len) {
1680 int thislen = min_t(int, oobsize, len - written); 2009 int thislen = min_t(int, oobsize, len - written);
@@ -1692,7 +2021,14 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
1692 memcpy(oobbuf + column, buf, thislen); 2021 memcpy(oobbuf + column, buf, thislen);
1693 this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize); 2022 this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
1694 2023
1695 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize); 2024 if (ONENAND_IS_MLC(this)) {
2025 /* Set main area of DataRAM to 0xff*/
2026 memset(this->page_buf, 0xff, mtd->writesize);
2027 this->write_bufferram(mtd, ONENAND_DATARAM,
2028 this->page_buf, 0, mtd->writesize);
2029 }
2030
2031 this->command(mtd, oobcmd, to, mtd->oobsize);
1696 2032
1697 onenand_update_bufferram(mtd, to, 0); 2033 onenand_update_bufferram(mtd, to, 0);
1698 if (ONENAND_IS_2PLANE(this)) { 2034 if (ONENAND_IS_2PLANE(this)) {
@@ -1815,29 +2151,48 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1815{ 2151{
1816 struct onenand_chip *this = mtd->priv; 2152 struct onenand_chip *this = mtd->priv;
1817 unsigned int block_size; 2153 unsigned int block_size;
1818 loff_t addr; 2154 loff_t addr = instr->addr;
1819 int len; 2155 loff_t len = instr->len;
1820 int ret = 0; 2156 int ret = 0, i;
2157 struct mtd_erase_region_info *region = NULL;
2158 loff_t region_end = 0;
1821 2159
1822 DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%012llx, len = %llu\n", (unsigned long long) instr->addr, (unsigned long long) instr->len); 2160 DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%012llx, len = %llu\n", (unsigned long long) instr->addr, (unsigned long long) instr->len);
1823 2161
1824 block_size = (1 << this->erase_shift); 2162 /* Do not allow erase past end of device */
1825 2163 if (unlikely((len + addr) > mtd->size)) {
1826 /* Start address must align on block boundary */ 2164 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; 2165 return -EINVAL;
1830 } 2166 }
1831 2167
1832 /* Length must align on block boundary */ 2168 if (FLEXONENAND(this)) {
1833 if (unlikely(instr->len & (block_size - 1))) { 2169 /* Find the eraseregion of this address */
1834 printk(KERN_ERR "onenand_erase: Length not block aligned\n"); 2170 i = flexonenand_region(mtd, addr);
1835 return -EINVAL; 2171 region = &mtd->eraseregions[i];
2172
2173 block_size = region->erasesize;
2174 region_end = region->offset + region->erasesize * region->numblocks;
2175
2176 /* Start address within region must align on block boundary.
2177 * Erase region's start offset is always block start address.
2178 */
2179 if (unlikely((addr - region->offset) & (block_size - 1))) {
2180 printk(KERN_ERR "onenand_erase: Unaligned address\n");
2181 return -EINVAL;
2182 }
2183 } else {
2184 block_size = 1 << this->erase_shift;
2185
2186 /* Start address must align on block boundary */
2187 if (unlikely(addr & (block_size - 1))) {
2188 printk(KERN_ERR "onenand_erase: Unaligned address\n");
2189 return -EINVAL;
2190 }
1836 } 2191 }
1837 2192
1838 /* Do not allow erase past end of device */ 2193 /* Length must align on block boundary */
1839 if (unlikely((instr->len + instr->addr) > mtd->size)) { 2194 if (unlikely(len & (block_size - 1))) {
1840 printk(KERN_ERR "onenand_erase: Erase past end of device\n"); 2195 printk(KERN_ERR "onenand_erase: Length not block aligned\n");
1841 return -EINVAL; 2196 return -EINVAL;
1842 } 2197 }
1843 2198
@@ -1847,9 +2202,6 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1847 onenand_get_device(mtd, FL_ERASING); 2202 onenand_get_device(mtd, FL_ERASING);
1848 2203
1849 /* Loop throught the pages */ 2204 /* Loop throught the pages */
1850 len = instr->len;
1851 addr = instr->addr;
1852
1853 instr->state = MTD_ERASING; 2205 instr->state = MTD_ERASING;
1854 2206
1855 while (len) { 2207 while (len) {
@@ -1869,7 +2221,8 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1869 ret = this->wait(mtd, FL_ERASING); 2221 ret = this->wait(mtd, FL_ERASING);
1870 /* Check, if it is write protected */ 2222 /* Check, if it is write protected */
1871 if (ret) { 2223 if (ret) {
1872 printk(KERN_ERR "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift)); 2224 printk(KERN_ERR "onenand_erase: Failed erase, block %d\n",
2225 onenand_block(this, addr));
1873 instr->state = MTD_ERASE_FAILED; 2226 instr->state = MTD_ERASE_FAILED;
1874 instr->fail_addr = addr; 2227 instr->fail_addr = addr;
1875 goto erase_exit; 2228 goto erase_exit;
@@ -1877,6 +2230,22 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1877 2230
1878 len -= block_size; 2231 len -= block_size;
1879 addr += block_size; 2232 addr += block_size;
2233
2234 if (addr == region_end) {
2235 if (!len)
2236 break;
2237 region++;
2238
2239 block_size = region->erasesize;
2240 region_end = region->offset + region->erasesize * region->numblocks;
2241
2242 if (len & (block_size - 1)) {
2243 /* FIXME: This should be handled at MTD partitioning level. */
2244 printk(KERN_ERR "onenand_erase: Unaligned address\n");
2245 goto erase_exit;
2246 }
2247 }
2248
1880 } 2249 }
1881 2250
1882 instr->state = MTD_ERASE_DONE; 2251 instr->state = MTD_ERASE_DONE;
@@ -1955,13 +2324,17 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
1955 int block; 2324 int block;
1956 2325
1957 /* Get block number */ 2326 /* Get block number */
1958 block = ((int) ofs) >> bbm->bbt_erase_shift; 2327 block = onenand_block(this, ofs);
1959 if (bbm->bbt) 2328 if (bbm->bbt)
1960 bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); 2329 bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
1961 2330
1962 /* We write two bytes, so we dont have to mess with 16 bit access */ 2331 /* We write two bytes, so we dont have to mess with 16 bit access */
1963 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01); 2332 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
1964 return onenand_write_oob_nolock(mtd, ofs, &ops); 2333 /* FIXME : What to do when marking SLC block in partition
2334 * with MLC erasesize? For now, it is not advisable to
2335 * create partitions containing both SLC and MLC regions.
2336 */
2337 return onenand_write_oob_nolock(mtd, ofs, &ops);
1965} 2338}
1966 2339
1967/** 2340/**
@@ -2005,8 +2378,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; 2378 int start, end, block, value, status;
2006 int wp_status_mask; 2379 int wp_status_mask;
2007 2380
2008 start = ofs >> this->erase_shift; 2381 start = onenand_block(this, ofs);
2009 end = len >> this->erase_shift; 2382 end = onenand_block(this, ofs + len) - 1;
2010 2383
2011 if (cmd == ONENAND_CMD_LOCK) 2384 if (cmd == ONENAND_CMD_LOCK)
2012 wp_status_mask = ONENAND_WP_LS; 2385 wp_status_mask = ONENAND_WP_LS;
@@ -2018,7 +2391,7 @@ static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int
2018 /* Set start block address */ 2391 /* Set start block address */
2019 this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS); 2392 this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
2020 /* Set end block address */ 2393 /* Set end block address */
2021 this->write_word(start + end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS); 2394 this->write_word(end, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
2022 /* Write lock command */ 2395 /* Write lock command */
2023 this->command(mtd, cmd, 0, 0); 2396 this->command(mtd, cmd, 0, 0);
2024 2397
@@ -2039,7 +2412,7 @@ static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int
2039 } 2412 }
2040 2413
2041 /* Block lock scheme */ 2414 /* Block lock scheme */
2042 for (block = start; block < start + end; block++) { 2415 for (block = start; block < end + 1; block++) {
2043 /* Set block address */ 2416 /* Set block address */
2044 value = onenand_block_address(this, block); 2417 value = onenand_block_address(this, block);
2045 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); 2418 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
@@ -2147,7 +2520,7 @@ static void onenand_unlock_all(struct mtd_info *mtd)
2147{ 2520{
2148 struct onenand_chip *this = mtd->priv; 2521 struct onenand_chip *this = mtd->priv;
2149 loff_t ofs = 0; 2522 loff_t ofs = 0;
2150 size_t len = this->chipsize; 2523 loff_t len = mtd->size;
2151 2524
2152 if (this->options & ONENAND_HAS_UNLOCK_ALL) { 2525 if (this->options & ONENAND_HAS_UNLOCK_ALL) {
2153 /* Set start block address */ 2526 /* Set start block address */
@@ -2163,12 +2536,16 @@ static void onenand_unlock_all(struct mtd_info *mtd)
2163 & ONENAND_CTRL_ONGO) 2536 & ONENAND_CTRL_ONGO)
2164 continue; 2537 continue;
2165 2538
2539 /* Don't check lock status */
2540 if (this->options & ONENAND_SKIP_UNLOCK_CHECK)
2541 return;
2542
2166 /* Check lock status */ 2543 /* Check lock status */
2167 if (onenand_check_lock_status(this)) 2544 if (onenand_check_lock_status(this))
2168 return; 2545 return;
2169 2546
2170 /* Workaround for all block unlock in DDP */ 2547 /* Workaround for all block unlock in DDP */
2171 if (ONENAND_IS_DDP(this)) { 2548 if (ONENAND_IS_DDP(this) && !FLEXONENAND(this)) {
2172 /* All blocks on another chip */ 2549 /* All blocks on another chip */
2173 ofs = this->chipsize >> 1; 2550 ofs = this->chipsize >> 1;
2174 len = this->chipsize >> 1; 2551 len = this->chipsize >> 1;
@@ -2210,7 +2587,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); 2587 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
2211 this->wait(mtd, FL_OTPING); 2588 this->wait(mtd, FL_OTPING);
2212 2589
2213 ret = onenand_read_ops_nolock(mtd, from, &ops); 2590 ret = ONENAND_IS_MLC(this) ?
2591 onenand_mlc_read_ops_nolock(mtd, from, &ops) :
2592 onenand_read_ops_nolock(mtd, from, &ops);
2214 2593
2215 /* Exit OTP access mode */ 2594 /* Exit OTP access mode */
2216 this->command(mtd, ONENAND_CMD_RESET, 0, 0); 2595 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
@@ -2277,21 +2656,32 @@ static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len,
2277 size_t *retlen, u_char *buf) 2656 size_t *retlen, u_char *buf)
2278{ 2657{
2279 struct onenand_chip *this = mtd->priv; 2658 struct onenand_chip *this = mtd->priv;
2280 struct mtd_oob_ops ops = { 2659 struct mtd_oob_ops ops;
2281 .mode = MTD_OOB_PLACE,
2282 .ooblen = len,
2283 .oobbuf = buf,
2284 .ooboffs = 0,
2285 };
2286 int ret; 2660 int ret;
2287 2661
2288 /* Enter OTP access mode */ 2662 /* Enter OTP access mode */
2289 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); 2663 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0);
2290 this->wait(mtd, FL_OTPING); 2664 this->wait(mtd, FL_OTPING);
2291 2665
2292 ret = onenand_write_oob_nolock(mtd, from, &ops); 2666 if (FLEXONENAND(this)) {
2293 2667 /*
2294 *retlen = ops.oobretlen; 2668 * For Flex-OneNAND, we write lock mark to 1st word of sector 4 of
2669 * main area of page 49.
2670 */
2671 ops.len = mtd->writesize;
2672 ops.ooblen = 0;
2673 ops.datbuf = buf;
2674 ops.oobbuf = NULL;
2675 ret = onenand_write_ops_nolock(mtd, mtd->writesize * 49, &ops);
2676 *retlen = ops.retlen;
2677 } else {
2678 ops.mode = MTD_OOB_PLACE;
2679 ops.ooblen = len;
2680 ops.oobbuf = buf;
2681 ops.ooboffs = 0;
2682 ret = onenand_write_oob_nolock(mtd, from, &ops);
2683 *retlen = ops.oobretlen;
2684 }
2295 2685
2296 /* Exit OTP access mode */ 2686 /* Exit OTP access mode */
2297 this->command(mtd, ONENAND_CMD_RESET, 0, 0); 2687 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
@@ -2475,27 +2865,34 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
2475 size_t len) 2865 size_t len)
2476{ 2866{
2477 struct onenand_chip *this = mtd->priv; 2867 struct onenand_chip *this = mtd->priv;
2478 u_char *oob_buf = this->oob_buf; 2868 u_char *buf = FLEXONENAND(this) ? this->page_buf : this->oob_buf;
2479 size_t retlen; 2869 size_t retlen;
2480 int ret; 2870 int ret;
2481 2871
2482 memset(oob_buf, 0xff, mtd->oobsize); 2872 memset(buf, 0xff, FLEXONENAND(this) ? this->writesize
2873 : mtd->oobsize);
2483 /* 2874 /*
2484 * Note: OTP lock operation 2875 * Note: OTP lock operation
2485 * OTP block : 0xXXFC 2876 * OTP block : 0xXXFC
2486 * 1st block : 0xXXF3 (If chip support) 2877 * 1st block : 0xXXF3 (If chip support)
2487 * Both : 0xXXF0 (If chip support) 2878 * Both : 0xXXF0 (If chip support)
2488 */ 2879 */
2489 oob_buf[ONENAND_OTP_LOCK_OFFSET] = 0xFC; 2880 if (FLEXONENAND(this))
2881 buf[FLEXONENAND_OTP_LOCK_OFFSET] = 0xFC;
2882 else
2883 buf[ONENAND_OTP_LOCK_OFFSET] = 0xFC;
2490 2884
2491 /* 2885 /*
2492 * Write lock mark to 8th word of sector0 of page0 of the spare0. 2886 * Write lock mark to 8th word of sector0 of page0 of the spare0.
2493 * We write 16 bytes spare area instead of 2 bytes. 2887 * We write 16 bytes spare area instead of 2 bytes.
2888 * For Flex-OneNAND, we write lock mark to 1st word of sector 4 of
2889 * main area of page 49.
2494 */ 2890 */
2891
2495 from = 0; 2892 from = 0;
2496 len = 16; 2893 len = FLEXONENAND(this) ? mtd->writesize : 16;
2497 2894
2498 ret = onenand_otp_walk(mtd, from, len, &retlen, oob_buf, do_otp_lock, MTD_OTP_USER); 2895 ret = onenand_otp_walk(mtd, from, len, &retlen, buf, do_otp_lock, MTD_OTP_USER);
2499 2896
2500 return ret ? : retlen; 2897 return ret ? : retlen;
2501} 2898}
@@ -2542,6 +2939,14 @@ static void onenand_check_features(struct mtd_info *mtd)
2542 break; 2939 break;
2543 } 2940 }
2544 2941
2942 if (ONENAND_IS_MLC(this))
2943 this->options &= ~ONENAND_HAS_2PLANE;
2944
2945 if (FLEXONENAND(this)) {
2946 this->options &= ~ONENAND_HAS_CONT_LOCK;
2947 this->options |= ONENAND_HAS_UNLOCK_ALL;
2948 }
2949
2545 if (this->options & ONENAND_HAS_CONT_LOCK) 2950 if (this->options & ONENAND_HAS_CONT_LOCK)
2546 printk(KERN_DEBUG "Lock scheme is Continuous Lock\n"); 2951 printk(KERN_DEBUG "Lock scheme is Continuous Lock\n");
2547 if (this->options & ONENAND_HAS_UNLOCK_ALL) 2952 if (this->options & ONENAND_HAS_UNLOCK_ALL)
@@ -2559,14 +2964,16 @@ static void onenand_check_features(struct mtd_info *mtd)
2559 */ 2964 */
2560static void onenand_print_device_info(int device, int version) 2965static void onenand_print_device_info(int device, int version)
2561{ 2966{
2562 int vcc, demuxed, ddp, density; 2967 int vcc, demuxed, ddp, density, flexonenand;
2563 2968
2564 vcc = device & ONENAND_DEVICE_VCC_MASK; 2969 vcc = device & ONENAND_DEVICE_VCC_MASK;
2565 demuxed = device & ONENAND_DEVICE_IS_DEMUX; 2970 demuxed = device & ONENAND_DEVICE_IS_DEMUX;
2566 ddp = device & ONENAND_DEVICE_IS_DDP; 2971 ddp = device & ONENAND_DEVICE_IS_DDP;
2567 density = onenand_get_density(device); 2972 density = onenand_get_density(device);
2568 printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n", 2973 flexonenand = device & DEVICE_IS_FLEXONENAND;
2569 demuxed ? "" : "Muxed ", 2974 printk(KERN_INFO "%s%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n",
2975 demuxed ? "" : "Muxed ",
2976 flexonenand ? "Flex-" : "",
2570 ddp ? "(DDP)" : "", 2977 ddp ? "(DDP)" : "",
2571 (16 << density), 2978 (16 << density),
2572 vcc ? "2.65/3.3" : "1.8", 2979 vcc ? "2.65/3.3" : "1.8",
@@ -2576,6 +2983,7 @@ static void onenand_print_device_info(int device, int version)
2576 2983
2577static const struct onenand_manufacturers onenand_manuf_ids[] = { 2984static const struct onenand_manufacturers onenand_manuf_ids[] = {
2578 {ONENAND_MFR_SAMSUNG, "Samsung"}, 2985 {ONENAND_MFR_SAMSUNG, "Samsung"},
2986 {ONENAND_MFR_NUMONYX, "Numonyx"},
2579}; 2987};
2580 2988
2581/** 2989/**
@@ -2605,6 +3013,261 @@ static int onenand_check_maf(int manuf)
2605} 3013}
2606 3014
2607/** 3015/**
3016* flexonenand_get_boundary - Reads the SLC boundary
3017* @param onenand_info - onenand info structure
3018**/
3019static int flexonenand_get_boundary(struct mtd_info *mtd)
3020{
3021 struct onenand_chip *this = mtd->priv;
3022 unsigned die, bdry;
3023 int ret, syscfg, locked;
3024
3025 /* Disable ECC */
3026 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
3027 this->write_word((syscfg | 0x0100), this->base + ONENAND_REG_SYS_CFG1);
3028
3029 for (die = 0; die < this->dies; die++) {
3030 this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
3031 this->wait(mtd, FL_SYNCING);
3032
3033 this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
3034 ret = this->wait(mtd, FL_READING);
3035
3036 bdry = this->read_word(this->base + ONENAND_DATARAM);
3037 if ((bdry >> FLEXONENAND_PI_UNLOCK_SHIFT) == 3)
3038 locked = 0;
3039 else
3040 locked = 1;
3041 this->boundary[die] = bdry & FLEXONENAND_PI_MASK;
3042
3043 this->command(mtd, ONENAND_CMD_RESET, 0, 0);
3044 ret = this->wait(mtd, FL_RESETING);
3045
3046 printk(KERN_INFO "Die %d boundary: %d%s\n", die,
3047 this->boundary[die], locked ? "(Locked)" : "(Unlocked)");
3048 }
3049
3050 /* Enable ECC */
3051 this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
3052 return 0;
3053}
3054
3055/**
3056 * flexonenand_get_size - Fill up fields in onenand_chip and mtd_info
3057 * boundary[], diesize[], mtd->size, mtd->erasesize
3058 * @param mtd - MTD device structure
3059 */
3060static void flexonenand_get_size(struct mtd_info *mtd)
3061{
3062 struct onenand_chip *this = mtd->priv;
3063 int die, i, eraseshift, density;
3064 int blksperdie, maxbdry;
3065 loff_t ofs;
3066
3067 density = onenand_get_density(this->device_id);
3068 blksperdie = ((loff_t)(16 << density) << 20) >> (this->erase_shift);
3069 blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
3070 maxbdry = blksperdie - 1;
3071 eraseshift = this->erase_shift - 1;
3072
3073 mtd->numeraseregions = this->dies << 1;
3074
3075 /* This fills up the device boundary */
3076 flexonenand_get_boundary(mtd);
3077 die = ofs = 0;
3078 i = -1;
3079 for (; die < this->dies; die++) {
3080 if (!die || this->boundary[die-1] != maxbdry) {
3081 i++;
3082 mtd->eraseregions[i].offset = ofs;
3083 mtd->eraseregions[i].erasesize = 1 << eraseshift;
3084 mtd->eraseregions[i].numblocks =
3085 this->boundary[die] + 1;
3086 ofs += mtd->eraseregions[i].numblocks << eraseshift;
3087 eraseshift++;
3088 } else {
3089 mtd->numeraseregions -= 1;
3090 mtd->eraseregions[i].numblocks +=
3091 this->boundary[die] + 1;
3092 ofs += (this->boundary[die] + 1) << (eraseshift - 1);
3093 }
3094 if (this->boundary[die] != maxbdry) {
3095 i++;
3096 mtd->eraseregions[i].offset = ofs;
3097 mtd->eraseregions[i].erasesize = 1 << eraseshift;
3098 mtd->eraseregions[i].numblocks = maxbdry ^
3099 this->boundary[die];
3100 ofs += mtd->eraseregions[i].numblocks << eraseshift;
3101 eraseshift--;
3102 } else
3103 mtd->numeraseregions -= 1;
3104 }
3105
3106 /* Expose MLC erase size except when all blocks are SLC */
3107 mtd->erasesize = 1 << this->erase_shift;
3108 if (mtd->numeraseregions == 1)
3109 mtd->erasesize >>= 1;
3110
3111 printk(KERN_INFO "Device has %d eraseregions\n", mtd->numeraseregions);
3112 for (i = 0; i < mtd->numeraseregions; i++)
3113 printk(KERN_INFO "[offset: 0x%08x, erasesize: 0x%05x,"
3114 " numblocks: %04u]\n",
3115 (unsigned int) mtd->eraseregions[i].offset,
3116 mtd->eraseregions[i].erasesize,
3117 mtd->eraseregions[i].numblocks);
3118
3119 for (die = 0, mtd->size = 0; die < this->dies; die++) {
3120 this->diesize[die] = (loff_t)blksperdie << this->erase_shift;
3121 this->diesize[die] -= (loff_t)(this->boundary[die] + 1)
3122 << (this->erase_shift - 1);
3123 mtd->size += this->diesize[die];
3124 }
3125}
3126
3127/**
3128 * flexonenand_check_blocks_erased - Check if blocks are erased
3129 * @param mtd_info - mtd info structure
3130 * @param start - first erase block to check
3131 * @param end - last erase block to check
3132 *
3133 * Converting an unerased block from MLC to SLC
3134 * causes byte values to change. Since both data and its ECC
3135 * have changed, reads on the block give uncorrectable error.
3136 * This might lead to the block being detected as bad.
3137 *
3138 * Avoid this by ensuring that the block to be converted is
3139 * erased.
3140 */
3141static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int end)
3142{
3143 struct onenand_chip *this = mtd->priv;
3144 int i, ret;
3145 int block;
3146 struct mtd_oob_ops ops = {
3147 .mode = MTD_OOB_PLACE,
3148 .ooboffs = 0,
3149 .ooblen = mtd->oobsize,
3150 .datbuf = NULL,
3151 .oobbuf = this->oob_buf,
3152 };
3153 loff_t addr;
3154
3155 printk(KERN_DEBUG "Check blocks from %d to %d\n", start, end);
3156
3157 for (block = start; block <= end; block++) {
3158 addr = flexonenand_addr(this, block);
3159 if (onenand_block_isbad_nolock(mtd, addr, 0))
3160 continue;
3161
3162 /*
3163 * Since main area write results in ECC write to spare,
3164 * it is sufficient to check only ECC bytes for change.
3165 */
3166 ret = onenand_read_oob_nolock(mtd, addr, &ops);
3167 if (ret)
3168 return ret;
3169
3170 for (i = 0; i < mtd->oobsize; i++)
3171 if (this->oob_buf[i] != 0xff)
3172 break;
3173
3174 if (i != mtd->oobsize) {
3175 printk(KERN_WARNING "Block %d not erased.\n", block);
3176 return 1;
3177 }
3178 }
3179
3180 return 0;
3181}
3182
3183/**
3184 * flexonenand_set_boundary - Writes the SLC boundary
3185 * @param mtd - mtd info structure
3186 */
3187int flexonenand_set_boundary(struct mtd_info *mtd, int die,
3188 int boundary, int lock)
3189{
3190 struct onenand_chip *this = mtd->priv;
3191 int ret, density, blksperdie, old, new, thisboundary;
3192 loff_t addr;
3193
3194 /* Change only once for SDP Flex-OneNAND */
3195 if (die && (!ONENAND_IS_DDP(this)))
3196 return 0;
3197
3198 /* boundary value of -1 indicates no required change */
3199 if (boundary < 0 || boundary == this->boundary[die])
3200 return 0;
3201
3202 density = onenand_get_density(this->device_id);
3203 blksperdie = ((16 << density) << 20) >> this->erase_shift;
3204 blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0;
3205
3206 if (boundary >= blksperdie) {
3207 printk(KERN_ERR "flexonenand_set_boundary: Invalid boundary value. "
3208 "Boundary not changed.\n");
3209 return -EINVAL;
3210 }
3211
3212 /* Check if converting blocks are erased */
3213 old = this->boundary[die] + (die * this->density_mask);
3214 new = boundary + (die * this->density_mask);
3215 ret = flexonenand_check_blocks_erased(mtd, min(old, new) + 1, max(old, new));
3216 if (ret) {
3217 printk(KERN_ERR "flexonenand_set_boundary: Please erase blocks before boundary change\n");
3218 return ret;
3219 }
3220
3221 this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0);
3222 this->wait(mtd, FL_SYNCING);
3223
3224 /* Check is boundary is locked */
3225 this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0);
3226 ret = this->wait(mtd, FL_READING);
3227
3228 thisboundary = this->read_word(this->base + ONENAND_DATARAM);
3229 if ((thisboundary >> FLEXONENAND_PI_UNLOCK_SHIFT) != 3) {
3230 printk(KERN_ERR "flexonenand_set_boundary: boundary locked\n");
3231 ret = 1;
3232 goto out;
3233 }
3234
3235 printk(KERN_INFO "flexonenand_set_boundary: Changing die %d boundary: %d%s\n",
3236 die, boundary, lock ? "(Locked)" : "(Unlocked)");
3237
3238 addr = die ? this->diesize[0] : 0;
3239
3240 boundary &= FLEXONENAND_PI_MASK;
3241 boundary |= lock ? 0 : (3 << FLEXONENAND_PI_UNLOCK_SHIFT);
3242
3243 this->command(mtd, ONENAND_CMD_ERASE, addr, 0);
3244 ret = this->wait(mtd, FL_ERASING);
3245 if (ret) {
3246 printk(KERN_ERR "flexonenand_set_boundary: Failed PI erase for Die %d\n", die);
3247 goto out;
3248 }
3249
3250 this->write_word(boundary, this->base + ONENAND_DATARAM);
3251 this->command(mtd, ONENAND_CMD_PROG, addr, 0);
3252 ret = this->wait(mtd, FL_WRITING);
3253 if (ret) {
3254 printk(KERN_ERR "flexonenand_set_boundary: Failed PI write for Die %d\n", die);
3255 goto out;
3256 }
3257
3258 this->command(mtd, FLEXONENAND_CMD_PI_UPDATE, die, 0);
3259 ret = this->wait(mtd, FL_WRITING);
3260out:
3261 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_REG_COMMAND);
3262 this->wait(mtd, FL_RESETING);
3263 if (!ret)
3264 /* Recalculate device size on boundary change*/
3265 flexonenand_get_size(mtd);
3266
3267 return ret;
3268}
3269
3270/**
2608 * onenand_probe - [OneNAND Interface] Probe the OneNAND device 3271 * onenand_probe - [OneNAND Interface] Probe the OneNAND device
2609 * @param mtd MTD device structure 3272 * @param mtd MTD device structure
2610 * 3273 *
@@ -2621,7 +3284,7 @@ static int onenand_probe(struct mtd_info *mtd)
2621 /* Save system configuration 1 */ 3284 /* Save system configuration 1 */
2622 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1); 3285 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
2623 /* Clear Sync. Burst Read mode to read BootRAM */ 3286 /* Clear Sync. Burst Read mode to read BootRAM */
2624 this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ), this->base + ONENAND_REG_SYS_CFG1); 3287 this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE), this->base + ONENAND_REG_SYS_CFG1);
2625 3288
2626 /* Send the command for reading device ID from BootRAM */ 3289 /* Send the command for reading device ID from BootRAM */
2627 this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM); 3290 this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
@@ -2646,6 +3309,7 @@ static int onenand_probe(struct mtd_info *mtd)
2646 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID); 3309 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
2647 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID); 3310 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
2648 ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID); 3311 ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
3312 this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
2649 3313
2650 /* Check OneNAND device */ 3314 /* Check OneNAND device */
2651 if (maf_id != bram_maf_id || dev_id != bram_dev_id) 3315 if (maf_id != bram_maf_id || dev_id != bram_dev_id)
@@ -2657,29 +3321,55 @@ static int onenand_probe(struct mtd_info *mtd)
2657 this->version_id = ver_id; 3321 this->version_id = ver_id;
2658 3322
2659 density = onenand_get_density(dev_id); 3323 density = onenand_get_density(dev_id);
3324 if (FLEXONENAND(this)) {
3325 this->dies = ONENAND_IS_DDP(this) ? 2 : 1;
3326 /* Maximum possible erase regions */
3327 mtd->numeraseregions = this->dies << 1;
3328 mtd->eraseregions = kzalloc(sizeof(struct mtd_erase_region_info)
3329 * (this->dies << 1), GFP_KERNEL);
3330 if (!mtd->eraseregions)
3331 return -ENOMEM;
3332 }
3333
3334 /*
3335 * For Flex-OneNAND, chipsize represents maximum possible device size.
3336 * mtd->size represents the actual device size.
3337 */
2660 this->chipsize = (16 << density) << 20; 3338 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 3339
2667 /* OneNAND page size & block size */ 3340 /* OneNAND page size & block size */
2668 /* The data buffer size is equal to page size */ 3341 /* The data buffer size is equal to page size */
2669 mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE); 3342 mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
3343 /* We use the full BufferRAM */
3344 if (ONENAND_IS_MLC(this))
3345 mtd->writesize <<= 1;
3346
2670 mtd->oobsize = mtd->writesize >> 5; 3347 mtd->oobsize = mtd->writesize >> 5;
2671 /* Pages per a block are always 64 in OneNAND */ 3348 /* Pages per a block are always 64 in OneNAND */
2672 mtd->erasesize = mtd->writesize << 6; 3349 mtd->erasesize = mtd->writesize << 6;
3350 /*
3351 * Flex-OneNAND SLC area has 64 pages per block.
3352 * Flex-OneNAND MLC area has 128 pages per block.
3353 * Expose MLC erase size to find erase_shift and page_mask.
3354 */
3355 if (FLEXONENAND(this))
3356 mtd->erasesize <<= 1;
2673 3357
2674 this->erase_shift = ffs(mtd->erasesize) - 1; 3358 this->erase_shift = ffs(mtd->erasesize) - 1;
2675 this->page_shift = ffs(mtd->writesize) - 1; 3359 this->page_shift = ffs(mtd->writesize) - 1;
2676 this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1; 3360 this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1;
3361 /* Set density mask. it is used for DDP */
3362 if (ONENAND_IS_DDP(this))
3363 this->density_mask = this->chipsize >> (this->erase_shift + 1);
2677 /* It's real page size */ 3364 /* It's real page size */
2678 this->writesize = mtd->writesize; 3365 this->writesize = mtd->writesize;
2679 3366
2680 /* REVIST: Multichip handling */ 3367 /* REVIST: Multichip handling */
2681 3368
2682 mtd->size = this->chipsize; 3369 if (FLEXONENAND(this))
3370 flexonenand_get_size(mtd);
3371 else
3372 mtd->size = this->chipsize;
2683 3373
2684 /* Check OneNAND features */ 3374 /* Check OneNAND features */
2685 onenand_check_features(mtd); 3375 onenand_check_features(mtd);
@@ -2734,7 +3424,7 @@ static void onenand_resume(struct mtd_info *mtd)
2734 */ 3424 */
2735int onenand_scan(struct mtd_info *mtd, int maxchips) 3425int onenand_scan(struct mtd_info *mtd, int maxchips)
2736{ 3426{
2737 int i; 3427 int i, ret;
2738 struct onenand_chip *this = mtd->priv; 3428 struct onenand_chip *this = mtd->priv;
2739 3429
2740 if (!this->read_word) 3430 if (!this->read_word)
@@ -2746,6 +3436,10 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
2746 this->command = onenand_command; 3436 this->command = onenand_command;
2747 if (!this->wait) 3437 if (!this->wait)
2748 onenand_setup_wait(mtd); 3438 onenand_setup_wait(mtd);
3439 if (!this->bbt_wait)
3440 this->bbt_wait = onenand_bbt_wait;
3441 if (!this->unlock_all)
3442 this->unlock_all = onenand_unlock_all;
2749 3443
2750 if (!this->read_bufferram) 3444 if (!this->read_bufferram)
2751 this->read_bufferram = onenand_read_bufferram; 3445 this->read_bufferram = onenand_read_bufferram;
@@ -2796,6 +3490,10 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
2796 * Allow subpage writes up to oobsize. 3490 * Allow subpage writes up to oobsize.
2797 */ 3491 */
2798 switch (mtd->oobsize) { 3492 switch (mtd->oobsize) {
3493 case 128:
3494 this->ecclayout = &onenand_oob_128;
3495 mtd->subpage_sft = 0;
3496 break;
2799 case 64: 3497 case 64:
2800 this->ecclayout = &onenand_oob_64; 3498 this->ecclayout = &onenand_oob_64;
2801 mtd->subpage_sft = 2; 3499 mtd->subpage_sft = 2;
@@ -2859,9 +3557,18 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
2859 mtd->owner = THIS_MODULE; 3557 mtd->owner = THIS_MODULE;
2860 3558
2861 /* Unlock whole block */ 3559 /* Unlock whole block */
2862 onenand_unlock_all(mtd); 3560 this->unlock_all(mtd);
3561
3562 ret = this->scan_bbt(mtd);
3563 if ((!FLEXONENAND(this)) || ret)
3564 return ret;
2863 3565
2864 return this->scan_bbt(mtd); 3566 /* Change Flex-OneNAND boundaries if required */
3567 for (i = 0; i < MAX_DIES; i++)
3568 flexonenand_set_boundary(mtd, i, flex_bdry[2 * i],
3569 flex_bdry[(2 * i) + 1]);
3570
3571 return 0;
2865} 3572}
2866 3573
2867/** 3574/**
@@ -2890,6 +3597,7 @@ void onenand_release(struct mtd_info *mtd)
2890 kfree(this->page_buf); 3597 kfree(this->page_buf);
2891 if (this->options & ONENAND_OOBBUF_ALLOC) 3598 if (this->options & ONENAND_OOBBUF_ALLOC)
2892 kfree(this->oob_buf); 3599 kfree(this->oob_buf);
3600 kfree(mtd->eraseregions);
2893} 3601}
2894 3602
2895EXPORT_SYMBOL_GPL(onenand_scan); 3603EXPORT_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 */