Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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
...

+3139 -833
+125
Documentation/ABI/testing/sysfs-class-mtd
··· 1 + What: /sys/class/mtd/ 2 + Date: April 2009 3 + KernelVersion: 2.6.29 4 + Contact: linux-mtd@lists.infradead.org 5 + Description: 6 + The mtd/ class subdirectory belongs to the MTD subsystem 7 + (MTD core). 8 + 9 + What: /sys/class/mtd/mtdX/ 10 + Date: April 2009 11 + KernelVersion: 2.6.29 12 + Contact: linux-mtd@lists.infradead.org 13 + Description: 14 + The /sys/class/mtd/mtd{0,1,2,3,...} directories correspond 15 + to each /dev/mtdX character device. These may represent 16 + physical/simulated flash devices, partitions on a flash 17 + device, or concatenated flash devices. They exist regardless 18 + of whether CONFIG_MTD_CHAR is actually enabled. 19 + 20 + What: /sys/class/mtd/mtdXro/ 21 + Date: April 2009 22 + KernelVersion: 2.6.29 23 + Contact: linux-mtd@lists.infradead.org 24 + Description: 25 + These directories provide the corresponding read-only device 26 + nodes for /sys/class/mtd/mtdX/ . They are only created 27 + (for the benefit of udev) if CONFIG_MTD_CHAR is enabled. 28 + 29 + What: /sys/class/mtd/mtdX/dev 30 + Date: April 2009 31 + KernelVersion: 2.6.29 32 + Contact: linux-mtd@lists.infradead.org 33 + Description: 34 + Major and minor numbers of the character device corresponding 35 + to this MTD device (in <major>:<minor> format). This is the 36 + read-write device so <minor> will be even. 37 + 38 + What: /sys/class/mtd/mtdXro/dev 39 + Date: April 2009 40 + KernelVersion: 2.6.29 41 + Contact: linux-mtd@lists.infradead.org 42 + Description: 43 + Major and minor numbers of the character device corresponding 44 + to the read-only variant of thie MTD device (in 45 + <major>:<minor> format). In this case <minor> will be odd. 46 + 47 + What: /sys/class/mtd/mtdX/erasesize 48 + Date: April 2009 49 + KernelVersion: 2.6.29 50 + Contact: linux-mtd@lists.infradead.org 51 + Description: 52 + "Major" erase size for the device. If numeraseregions is 53 + zero, this is the eraseblock size for the entire device. 54 + Otherwise, the MEMGETREGIONCOUNT/MEMGETREGIONINFO ioctls 55 + can be used to determine the actual eraseblock layout. 56 + 57 + What: /sys/class/mtd/mtdX/flags 58 + Date: April 2009 59 + KernelVersion: 2.6.29 60 + Contact: linux-mtd@lists.infradead.org 61 + Description: 62 + A hexadecimal value representing the device flags, ORed 63 + together: 64 + 65 + 0x0400: MTD_WRITEABLE - device is writable 66 + 0x0800: MTD_BIT_WRITEABLE - single bits can be flipped 67 + 0x1000: MTD_NO_ERASE - no erase necessary 68 + 0x2000: MTD_POWERUP_LOCK - always locked after reset 69 + 70 + What: /sys/class/mtd/mtdX/name 71 + Date: April 2009 72 + KernelVersion: 2.6.29 73 + Contact: linux-mtd@lists.infradead.org 74 + Description: 75 + A human-readable ASCII name for the device or partition. 76 + This will match the name in /proc/mtd . 77 + 78 + What: /sys/class/mtd/mtdX/numeraseregions 79 + Date: April 2009 80 + KernelVersion: 2.6.29 81 + Contact: linux-mtd@lists.infradead.org 82 + Description: 83 + For devices that have variable eraseblock sizes, this 84 + provides the total number of erase regions. Otherwise, 85 + it will read back as zero. 86 + 87 + What: /sys/class/mtd/mtdX/oobsize 88 + Date: April 2009 89 + KernelVersion: 2.6.29 90 + Contact: linux-mtd@lists.infradead.org 91 + Description: 92 + Number of OOB bytes per page. 93 + 94 + What: /sys/class/mtd/mtdX/size 95 + Date: April 2009 96 + KernelVersion: 2.6.29 97 + Contact: linux-mtd@lists.infradead.org 98 + Description: 99 + Total size of the device/partition, in bytes. 100 + 101 + What: /sys/class/mtd/mtdX/type 102 + Date: April 2009 103 + KernelVersion: 2.6.29 104 + Contact: linux-mtd@lists.infradead.org 105 + Description: 106 + One of the following ASCII strings, representing the device 107 + type: 108 + 109 + absent, ram, rom, nor, nand, dataflash, ubi, unknown 110 + 111 + What: /sys/class/mtd/mtdX/writesize 112 + Date: April 2009 113 + KernelVersion: 2.6.29 114 + Contact: linux-mtd@lists.infradead.org 115 + Description: 116 + Minimal writable flash unit size. This will always be 117 + a positive integer. 118 + 119 + In the case of NOR flash it is 1 (even though individual 120 + bits can be cleared). 121 + 122 + In the case of NAND flash it is one NAND page (or a 123 + half page, or a quarter page). 124 + 125 + In the case of ECC NOR, it is the ECC block size.
+10
Documentation/kernel-parameters.txt
··· 1431 1431 mtdparts= [MTD] 1432 1432 See drivers/mtd/cmdlinepart.c. 1433 1433 1434 + onenand.bdry= [HW,MTD] Flex-OneNAND Boundary Configuration 1435 + 1436 + Format: [die0_boundary][,die0_lock][,die1_boundary][,die1_lock] 1437 + 1438 + boundary - index of last SLC block on Flex-OneNAND. 1439 + The remaining blocks are configured as MLC blocks. 1440 + lock - Configure if Flex-OneNAND boundary should be locked. 1441 + Once locked, the boundary cannot be changed. 1442 + 1 indicates lock status, 0 indicates unlock status. 1443 + 1434 1444 mtdset= [ARM] 1435 1445 ARM/S3C2412 JIVE boot control 1436 1446
-1
MAINTAINERS
··· 3252 3252 S: Maintained 3253 3253 F: fs/jffs2/ 3254 3254 F: include/linux/jffs2.h 3255 - F: include/mtd/jffs2-user.h 3256 3255 3257 3256 JOURNALLING LAYER FOR BLOCK DEVICES (JBD) 3258 3257 P: Stephen Tweedie
+6 -2
arch/arm/mach-davinci/include/mach/nand.h
··· 68 68 69 69 /* none == NAND_ECC_NONE (strongly *not* advised!!) 70 70 * soft == NAND_ECC_SOFT 71 - * 1-bit == NAND_ECC_HW 72 - * 4-bit == NAND_ECC_HW_SYNDROME (not on all chips) 71 + * else == NAND_ECC_HW, according to ecc_bits 72 + * 73 + * All DaVinci-family chips support 1-bit hardware ECC. 74 + * Newer ones also support 4-bit ECC, but are awkward 75 + * using it with large page chips. 73 76 */ 74 77 nand_ecc_modes_t ecc_mode; 78 + u8 ecc_bits; 75 79 76 80 /* e.g. NAND_BUSWIDTH_16 or NAND_USE_FLASH_BBT */ 77 81 unsigned options;
+19 -12
arch/arm/plat-s3c/include/plat/nand.h
··· 10 10 * published by the Free Software Foundation. 11 11 */ 12 12 13 - /* struct s3c2410_nand_set 13 + /** 14 + * struct s3c2410_nand_set - define a set of one or more nand chips 15 + * @disable_ecc: Entirely disable ECC - Dangerous 16 + * @flash_bbt: Openmoko u-boot can create a Bad Block Table 17 + * Setting this flag will allow the kernel to 18 + * look for it at boot time and also skip the NAND 19 + * scan. 20 + * @nr_chips: Number of chips in this set 21 + * @nr_partitions: Number of partitions pointed to by @partitions 22 + * @name: Name of set (optional) 23 + * @nr_map: Map for low-layer logical to physical chip numbers (option) 24 + * @partitions: The mtd partition list 14 25 * 15 - * define an set of one or more nand chips registered with an unique mtd 16 - * 17 - * nr_chips = number of chips in this set 18 - * nr_partitions = number of partitions pointed to be partitoons (or zero) 19 - * name = name of set (optional) 20 - * nr_map = map for low-layer logical to physical chip numbers (option) 21 - * partitions = mtd partition list 22 - */ 23 - 26 + * define a set of one or more nand chips registered with an unique mtd. Also 27 + * allows to pass flag to the underlying NAND layer. 'disable_ecc' will trigger 28 + * a warning at boot time. 29 + */ 24 30 struct s3c2410_nand_set { 25 - unsigned int disable_ecc : 1; 31 + unsigned int disable_ecc:1; 32 + unsigned int flash_bbt:1; 26 33 27 34 int nr_chips; 28 35 int nr_partitions; ··· 46 39 int twrph0; /* active time for nWE/nOE */ 47 40 int twrph1; /* time for release CLE/ALE from nWE/nOE inactive */ 48 41 49 - unsigned int ignore_unset_ecc : 1; 42 + unsigned int ignore_unset_ecc:1; 50 43 51 44 int nr_sets; 52 45 struct s3c2410_nand_set *sets;
+22 -4
drivers/mtd/chips/cfi_cmdset_0001.c
··· 46 46 #define MANUFACTURER_INTEL 0x0089 47 47 #define I82802AB 0x00ad 48 48 #define I82802AC 0x00ac 49 + #define PF38F4476 0x881c 49 50 #define MANUFACTURER_ST 0x0020 50 51 #define M50LPW080 0x002F 51 52 #define M50FLW080A 0x0080 ··· 316 315 { 0, 0, NULL, NULL } 317 316 }; 318 317 318 + static void cfi_fixup_major_minor(struct cfi_private *cfi, 319 + struct cfi_pri_intelext *extp) 320 + { 321 + if (cfi->mfr == MANUFACTURER_INTEL && 322 + cfi->id == PF38F4476 && extp->MinorVersion == '3') 323 + extp->MinorVersion = '1'; 324 + } 325 + 319 326 static inline struct cfi_pri_intelext * 320 327 read_pri_intelext(struct map_info *map, __u16 adr) 321 328 { 329 + struct cfi_private *cfi = map->fldrv_priv; 322 330 struct cfi_pri_intelext *extp; 331 + unsigned int extra_size = 0; 323 332 unsigned int extp_size = sizeof(*extp); 324 333 325 334 again: 326 335 extp = (struct cfi_pri_intelext *)cfi_read_pri(map, adr, extp_size, "Intel/Sharp"); 327 336 if (!extp) 328 337 return NULL; 338 + 339 + cfi_fixup_major_minor(cfi, extp); 329 340 330 341 if (extp->MajorVersion != '1' || 331 342 (extp->MinorVersion < '0' || extp->MinorVersion > '5')) { ··· 353 340 extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask); 354 341 extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr); 355 342 356 - if (extp->MajorVersion == '1' && extp->MinorVersion >= '3') { 357 - unsigned int extra_size = 0; 358 - int nb_parts, i; 343 + if (extp->MinorVersion >= '0') { 344 + extra_size = 0; 359 345 360 346 /* Protection Register info */ 361 347 extra_size += (extp->NumProtectionFields - 1) * 362 348 sizeof(struct cfi_intelext_otpinfo); 349 + } 363 350 351 + if (extp->MinorVersion >= '1') { 364 352 /* Burst Read info */ 365 353 extra_size += 2; 366 354 if (extp_size < sizeof(*extp) + extra_size) 367 355 goto need_more; 368 - extra_size += extp->extra[extra_size-1]; 356 + extra_size += extp->extra[extra_size - 1]; 357 + } 358 + 359 + if (extp->MinorVersion >= '3') { 360 + int nb_parts, i; 369 361 370 362 /* Number of hardware-partitions */ 371 363 extra_size += 1;
+13
drivers/mtd/chips/jedec_probe.c
··· 166 166 #define SST39LF040 0x00D7 167 167 #define SST39SF010A 0x00B5 168 168 #define SST39SF020A 0x00B6 169 + #define SST39SF040 0x00B7 169 170 #define SST49LF004B 0x0060 170 171 #define SST49LF040B 0x0050 171 172 #define SST49LF008A 0x005a ··· 1391 1390 .nr_regions = 1, 1392 1391 .regions = { 1393 1392 ERASEINFO(0x01000,64), 1393 + } 1394 + }, { 1395 + .mfr_id = MANUFACTURER_SST, 1396 + .dev_id = SST39SF040, 1397 + .name = "SST 39SF040", 1398 + .devtypes = CFI_DEVICETYPE_X8, 1399 + .uaddr = MTD_UADDR_0x5555_0x2AAA, 1400 + .dev_size = SIZE_512KiB, 1401 + .cmd_set = P_ID_AMD_STD, 1402 + .nr_regions = 1, 1403 + .regions = { 1404 + ERASEINFO(0x01000,128), 1394 1405 } 1395 1406 }, { 1396 1407 .mfr_id = MANUFACTURER_SST,
+4
drivers/mtd/devices/m25p80.c
··· 500 500 { "at26df161a", 0x1f4601, 0, 64 * 1024, 32, SECT_4K, }, 501 501 { "at26df321", 0x1f4701, 0, 64 * 1024, 64, SECT_4K, }, 502 502 503 + /* Macronix */ 504 + { "mx25l12805d", 0xc22018, 0, 64 * 1024, 256, }, 505 + 503 506 /* Spansion -- single (large) sector size only, at least 504 507 * for the chips listed here (without boot sectors). 505 508 */ ··· 531 528 { "m25p64", 0x202017, 0, 64 * 1024, 128, }, 532 529 { "m25p128", 0x202018, 0, 256 * 1024, 64, }, 533 530 531 + { "m45pe10", 0x204011, 0, 64 * 1024, 2, }, 534 532 { "m45pe80", 0x204014, 0, 64 * 1024, 16, }, 535 533 { "m45pe16", 0x204015, 0, 64 * 1024, 32, }, 536 534
+2 -11
drivers/mtd/maps/Kconfig
··· 105 105 default "0x02000000" 106 106 depends on MSP_FLASH_MAP_LIMIT_32M 107 107 108 - config 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 - 117 108 config MTD_SUN_UFLASH 118 109 tristate "Sun Microsystems userflash support" 119 110 depends on SPARC && MTD_CFI && PCI ··· 261 270 262 271 config MTD_DILNETPC 263 272 tristate "CFI Flash device mapped on DIL/Net PC" 264 - depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT 273 + depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN 265 274 help 266 275 MTD map driver for SSV DIL/Net PC Boards "DNP" and "ADNP". 267 276 For details, see <http://www.ssv-embedded.de/ssv/pc104/p169.htm> ··· 492 501 If compiled as a module, it will be called bfin-async-flash. 493 502 494 503 config MTD_UCLINUX 495 - tristate "Generic uClinux RAM/ROM filesystem support" 504 + bool "Generic uClinux RAM/ROM filesystem support" 496 505 depends on MTD_PARTITIONS && MTD_RAM && !MMU 497 506 help 498 507 Map driver to support image based filesystems for uClinux.
-1
drivers/mtd/maps/Makefile
··· 25 25 obj-$(CONFIG_MTD_PHYSMAP) += physmap.o 26 26 obj-$(CONFIG_MTD_PHYSMAP_OF) += physmap_of.o 27 27 obj-$(CONFIG_MTD_PMC_MSP_EVM) += pmcmsp-flash.o 28 - obj-$(CONFIG_MTD_PMC_MSP_RAMROOT)+= pmcmsp-ramroot.o 29 28 obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o 30 29 obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o 31 30 obj-$(CONFIG_MTD_TQM8XXL) += tqm8xxl.o
+5
drivers/mtd/maps/bfin-async-flash.c
··· 40 40 uint32_t flash_ambctl0, flash_ambctl1; 41 41 uint32_t save_ambctl0, save_ambctl1; 42 42 unsigned long irq_flags; 43 + #ifdef CONFIG_MTD_PARTITIONS 44 + struct mtd_partition *parts; 45 + #endif 43 46 }; 44 47 45 48 static void switch_to_flash(struct async_state *state) ··· 173 170 if (ret > 0) { 174 171 pr_devinit(KERN_NOTICE DRIVER_NAME ": Using commandline partition definition\n"); 175 172 add_mtd_partitions(state->mtd, pdata->parts, ret); 173 + state->parts = pdata->parts; 176 174 177 175 } else if (pdata->nr_parts) { 178 176 pr_devinit(KERN_NOTICE DRIVER_NAME ": Using board partition definition\n"); ··· 197 193 gpio_free(state->enet_flash_pin); 198 194 #ifdef CONFIG_MTD_PARTITIONS 199 195 del_mtd_partitions(state->mtd); 196 + kfree(state->parts); 200 197 #endif 201 198 map_destroy(state->mtd); 202 199 kfree(state);
+164 -62
drivers/mtd/maps/integrator-flash.c
··· 36 36 #include <linux/mtd/mtd.h> 37 37 #include <linux/mtd/map.h> 38 38 #include <linux/mtd/partitions.h> 39 + #include <linux/mtd/concat.h> 39 40 40 41 #include <asm/mach/flash.h> 41 42 #include <mach/hardware.h> 42 43 #include <asm/system.h> 43 44 44 - #ifdef CONFIG_ARCH_P720T 45 - #define FLASH_BASE (0x04000000) 46 - #define FLASH_SIZE (64*1024*1024) 47 - #endif 45 + #define SUBDEV_NAME_SIZE (BUS_ID_SIZE + 2) 46 + 47 + struct armflash_subdev_info { 48 + char name[SUBDEV_NAME_SIZE]; 49 + struct mtd_info *mtd; 50 + struct map_info map; 51 + struct flash_platform_data *plat; 52 + }; 48 53 49 54 struct armflash_info { 50 - struct flash_platform_data *plat; 51 55 struct resource *res; 52 56 struct mtd_partition *parts; 53 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 57 62 static 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 67 if (info->plat && info->plat->set_vpp) 62 68 info->plat->set_vpp(on); ··· 70 64 71 65 static const char *probes[] = { "cmdlinepart", "RedBoot", "afs", NULL }; 72 66 73 - static int armflash_probe(struct platform_device *dev) 67 + static int armflash_subdev_probe(struct armflash_subdev_info *subdev, 68 + struct resource *res) 74 69 { 75 - struct flash_platform_data *plat = dev->dev.platform_data; 76 - struct resource *res = dev->resource; 77 - unsigned int size = res->end - res->start + 1; 78 - struct armflash_info *info; 79 - int err; 70 + struct flash_platform_data *plat = subdev->plat; 71 + resource_size_t size = res->end - res->start + 1; 80 72 void __iomem *base; 73 + int err = 0; 81 74 82 - info = kzalloc(sizeof(struct armflash_info), GFP_KERNEL); 83 - if (!info) { 84 - err = -ENOMEM; 85 - goto out; 86 - } 87 - 88 - info->plat = plat; 89 - if (plat && plat->init) { 90 - err = plat->init(); 91 - if (err) 92 - goto no_resource; 93 - } 94 - 95 - info->res = request_mem_region(res->start, size, "armflash"); 96 - if (!info->res) { 75 + if (!request_mem_region(res->start, size, subdev->name)) { 97 76 err = -EBUSY; 98 - goto no_resource; 77 + goto out; 99 78 } 100 79 101 80 base = ioremap(res->start, size); ··· 92 101 /* 93 102 * look for CFI based flash parts fitted to this board 94 103 */ 95 - info->map.size = size; 96 - info->map.bankwidth = plat->width; 97 - info->map.phys = res->start; 98 - info->map.virt = base; 99 - info->map.name = dev_name(&dev->dev); 100 - info->map.set_vpp = armflash_set_vpp; 104 + subdev->map.size = size; 105 + subdev->map.bankwidth = plat->width; 106 + subdev->map.phys = res->start; 107 + subdev->map.virt = base; 108 + subdev->map.name = subdev->name; 109 + subdev->map.set_vpp = armflash_set_vpp; 101 110 102 - simple_map_init(&info->map); 111 + simple_map_init(&subdev->map); 103 112 104 113 /* 105 114 * Also, the CFI layer automatically works out what size 106 115 * of chips we have, and does the necessary identification 107 116 * for us automatically. 108 117 */ 109 - info->mtd = do_map_probe(plat->map_name, &info->map); 110 - if (!info->mtd) { 118 + subdev->mtd = do_map_probe(plat->map_name, &subdev->map); 119 + if (!subdev->mtd) { 111 120 err = -ENXIO; 112 121 goto no_device; 113 122 } 114 123 115 - info->mtd->owner = THIS_MODULE; 124 + subdev->mtd->owner = THIS_MODULE; 125 + 126 + /* Successful? */ 127 + if (err == 0) 128 + return err; 129 + 130 + if (subdev->mtd) 131 + map_destroy(subdev->mtd); 132 + no_device: 133 + iounmap(base); 134 + no_mem: 135 + release_mem_region(res->start, size); 136 + out: 137 + return err; 138 + } 139 + 140 + static void armflash_subdev_remove(struct armflash_subdev_info *subdev) 141 + { 142 + if (subdev->mtd) 143 + map_destroy(subdev->mtd); 144 + if (subdev->map.virt) 145 + iounmap(subdev->map.virt); 146 + release_mem_region(subdev->map.phys, subdev->map.size); 147 + } 148 + 149 + static int armflash_probe(struct platform_device *dev) 150 + { 151 + struct flash_platform_data *plat = dev->dev.platform_data; 152 + unsigned int size; 153 + struct armflash_info *info; 154 + int i, nr, err; 155 + 156 + /* Count the number of devices */ 157 + for (nr = 0; ; nr++) 158 + if (!platform_get_resource(dev, IORESOURCE_MEM, nr)) 159 + break; 160 + if (nr == 0) { 161 + err = -ENODEV; 162 + goto out; 163 + } 164 + 165 + size = sizeof(struct armflash_info) + 166 + sizeof(struct armflash_subdev_info) * nr; 167 + info = kzalloc(size, GFP_KERNEL); 168 + if (!info) { 169 + err = -ENOMEM; 170 + goto out; 171 + } 172 + 173 + if (plat && plat->init) { 174 + err = plat->init(); 175 + if (err) 176 + goto no_resource; 177 + } 178 + 179 + for (i = 0; i < nr; i++) { 180 + struct armflash_subdev_info *subdev = &info->subdev[i]; 181 + struct resource *res; 182 + 183 + res = platform_get_resource(dev, IORESOURCE_MEM, i); 184 + if (!res) 185 + break; 186 + 187 + if (nr == 1) 188 + /* No MTD concatenation, just use the default name */ 189 + snprintf(subdev->name, SUBDEV_NAME_SIZE, "%s", 190 + dev_name(&dev->dev)); 191 + else 192 + snprintf(subdev->name, SUBDEV_NAME_SIZE, "%s-%d", 193 + dev_name(&dev->dev), i); 194 + subdev->plat = plat; 195 + 196 + err = armflash_subdev_probe(subdev, res); 197 + if (err) 198 + break; 199 + } 200 + info->nr_subdev = i; 201 + 202 + if (err) 203 + goto subdev_err; 204 + 205 + if (info->nr_subdev == 1) 206 + info->mtd = info->subdev[0].mtd; 207 + else if (info->nr_subdev > 1) { 208 + #ifdef CONFIG_MTD_CONCAT 209 + struct mtd_info *cdev[info->nr_subdev]; 210 + 211 + /* 212 + * We detected multiple devices. Concatenate them together. 213 + */ 214 + for (i = 0; i < info->nr_subdev; i++) 215 + cdev[i] = info->subdev[i].mtd; 216 + 217 + info->mtd = mtd_concat_create(cdev, info->nr_subdev, 218 + dev_name(&dev->dev)); 219 + if (info->mtd == NULL) 220 + err = -ENXIO; 221 + #else 222 + printk(KERN_ERR "armflash: multiple devices found but " 223 + "MTD concat support disabled.\n"); 224 + err = -ENXIO; 225 + #endif 226 + } 227 + 228 + if (err < 0) 229 + goto cleanup; 116 230 117 231 err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0); 118 232 if (err > 0) { ··· 227 131 "mtd partition registration failed: %d\n", err); 228 132 } 229 133 230 - if (err == 0) 134 + if (err == 0) { 231 135 platform_set_drvdata(dev, info); 136 + return err; 137 + } 232 138 233 139 /* 234 - * If we got an error, free all resources. 140 + * We got an error, free all resources. 235 141 */ 236 - if (err < 0) { 237 - if (info->mtd) { 238 - del_mtd_partitions(info->mtd); 239 - map_destroy(info->mtd); 240 - } 241 - kfree(info->parts); 242 - 243 - no_device: 244 - iounmap(base); 245 - no_mem: 246 - release_mem_region(res->start, size); 247 - no_resource: 248 - if (plat && plat->exit) 249 - plat->exit(); 250 - kfree(info); 142 + cleanup: 143 + if (info->mtd) { 144 + del_mtd_partitions(info->mtd); 145 + #ifdef CONFIG_MTD_CONCAT 146 + if (info->mtd != info->subdev[0].mtd) 147 + mtd_concat_destroy(info->mtd); 148 + #endif 251 149 } 150 + kfree(info->parts); 151 + subdev_err: 152 + for (i = info->nr_subdev - 1; i >= 0; i--) 153 + armflash_subdev_remove(&info->subdev[i]); 154 + no_resource: 155 + if (plat && plat->exit) 156 + plat->exit(); 157 + kfree(info); 252 158 out: 253 159 return err; 254 160 } ··· 258 160 static int armflash_remove(struct platform_device *dev) 259 161 { 260 162 struct armflash_info *info = platform_get_drvdata(dev); 163 + struct flash_platform_data *plat = dev->dev.platform_data; 164 + int i; 261 165 262 166 platform_set_drvdata(dev, NULL); 263 167 264 168 if (info) { 265 169 if (info->mtd) { 266 170 del_mtd_partitions(info->mtd); 267 - map_destroy(info->mtd); 171 + #ifdef CONFIG_MTD_CONCAT 172 + if (info->mtd != info->subdev[0].mtd) 173 + mtd_concat_destroy(info->mtd); 174 + #endif 268 175 } 269 176 kfree(info->parts); 270 177 271 - iounmap(info->map.virt); 272 - release_resource(info->res); 273 - kfree(info->res); 178 + for (i = info->nr_subdev - 1; i >= 0; i--) 179 + armflash_subdev_remove(&info->subdev[i]); 274 180 275 - if (info->plat && info->plat->exit) 276 - info->plat->exit(); 181 + if (plat && plat->exit) 182 + plat->exit(); 277 183 278 184 kfree(info); 279 185 }
-40
drivers/mtd/maps/physmap.c
··· 195 195 } 196 196 197 197 #ifdef CONFIG_PM 198 - static 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; 212 - fail: 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 - 222 - static 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 - 234 198 static void physmap_flash_shutdown(struct platform_device *dev) 235 199 { 236 200 struct physmap_flash_info *info = platform_get_drvdata(dev); ··· 206 242 info->mtd[i]->resume(info->mtd[i]); 207 243 } 208 244 #else 209 - #define physmap_flash_suspend NULL 210 - #define physmap_flash_resume NULL 211 245 #define physmap_flash_shutdown NULL 212 246 #endif 213 247 214 248 static struct platform_driver physmap_flash_driver = { 215 249 .probe = physmap_flash_probe, 216 250 .remove = physmap_flash_remove, 217 - .suspend = physmap_flash_suspend, 218 - .resume = physmap_flash_resume, 219 251 .shutdown = physmap_flash_shutdown, 220 252 .driver = { 221 253 .name = "physmap-flash",
+144 -57
drivers/mtd/maps/physmap_of.c
··· 20 20 #include <linux/mtd/mtd.h> 21 21 #include <linux/mtd/map.h> 22 22 #include <linux/mtd/partitions.h> 23 + #include <linux/mtd/concat.h> 23 24 #include <linux/of.h> 24 25 #include <linux/of_platform.h> 25 26 27 + struct of_flash_list { 28 + struct mtd_info *mtd; 29 + struct map_info map; 30 + struct resource *res; 31 + }; 32 + 26 33 struct of_flash { 27 - struct mtd_info *mtd; 28 - struct map_info map; 29 - struct resource *res; 34 + struct mtd_info *cmtd; 30 35 #ifdef CONFIG_MTD_PARTITIONS 31 36 struct mtd_partition *parts; 32 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 42 #ifdef CONFIG_MTD_PARTITIONS ··· 95 88 static int of_flash_remove(struct of_device *dev) 96 89 { 97 90 struct of_flash *info; 91 + int i; 98 92 99 93 info = dev_get_drvdata(&dev->dev); 100 94 if (!info) 101 95 return 0; 102 96 dev_set_drvdata(&dev->dev, NULL); 103 97 104 - if (info->mtd) { 98 + #ifdef CONFIG_MTD_CONCAT 99 + if (info->cmtd != info->list[0].mtd) { 100 + del_mtd_device(info->cmtd); 101 + mtd_concat_destroy(info->cmtd); 102 + } 103 + #endif 104 + 105 + if (info->cmtd) { 105 106 if (OF_FLASH_PARTS(info)) { 106 - del_mtd_partitions(info->mtd); 107 + del_mtd_partitions(info->cmtd); 107 108 kfree(OF_FLASH_PARTS(info)); 108 109 } else { 109 - del_mtd_device(info->mtd); 110 + del_mtd_device(info->cmtd); 110 111 } 111 - map_destroy(info->mtd); 112 112 } 113 113 114 - if (info->map.virt) 115 - iounmap(info->map.virt); 114 + for (i = 0; i < info->list_size; i++) { 115 + if (info->list[i].mtd) 116 + map_destroy(info->list[i].mtd); 116 117 117 - if (info->res) { 118 - release_resource(info->res); 119 - kfree(info->res); 118 + if (info->list[i].map.virt) 119 + iounmap(info->list[i].map.virt); 120 + 121 + if (info->list[i].res) { 122 + release_resource(info->list[i].res); 123 + kfree(info->list[i].res); 124 + } 120 125 } 126 + 127 + kfree(info); 121 128 122 129 return 0; 123 130 } ··· 185 164 const char *probe_type = match->data; 186 165 const u32 *width; 187 166 int err; 167 + int i; 168 + int count; 169 + const u32 *p; 170 + int reg_tuple_size; 171 + struct mtd_info **mtd_list = NULL; 188 172 189 - err = -ENXIO; 190 - if (of_address_to_resource(dp, 0, &res)) { 191 - dev_err(&dev->dev, "Can't get IO address from device tree\n"); 173 + reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32); 174 + 175 + /* 176 + * Get number of "reg" tuples. Scan for MTD devices on area's 177 + * described by each "reg" region. This makes it possible (including 178 + * the concat support) to support the Intel P30 48F4400 chips which 179 + * consists internally of 2 non-identical NOR chips on one die. 180 + */ 181 + p = of_get_property(dp, "reg", &count); 182 + if (count % reg_tuple_size != 0) { 183 + dev_err(&dev->dev, "Malformed reg property on %s\n", 184 + dev->node->full_name); 185 + err = -EINVAL; 192 186 goto err_out; 193 187 } 194 - 195 - dev_dbg(&dev->dev, "of_flash device: %.8llx-%.8llx\n", 196 - (unsigned long long)res.start, (unsigned long long)res.end); 188 + count /= reg_tuple_size; 197 189 198 190 err = -ENOMEM; 199 - info = kzalloc(sizeof(*info), GFP_KERNEL); 191 + info = kzalloc(sizeof(struct of_flash) + 192 + sizeof(struct of_flash_list) * count, GFP_KERNEL); 193 + if (!info) 194 + goto err_out; 195 + 196 + mtd_list = kzalloc(sizeof(struct mtd_info) * count, GFP_KERNEL); 200 197 if (!info) 201 198 goto err_out; 202 199 203 200 dev_set_drvdata(&dev->dev, info); 204 201 205 - err = -EBUSY; 206 - info->res = request_mem_region(res.start, res.end - res.start + 1, 207 - dev_name(&dev->dev)); 208 - if (!info->res) 209 - goto err_out; 202 + for (i = 0; i < count; i++) { 203 + err = -ENXIO; 204 + if (of_address_to_resource(dp, i, &res)) { 205 + dev_err(&dev->dev, "Can't get IO address from device" 206 + " tree\n"); 207 + goto err_out; 208 + } 210 209 211 - err = -ENXIO; 212 - width = of_get_property(dp, "bank-width", NULL); 213 - if (!width) { 214 - dev_err(&dev->dev, "Can't get bank width from device tree\n"); 215 - goto err_out; 210 + dev_dbg(&dev->dev, "of_flash device: %.8llx-%.8llx\n", 211 + (unsigned long long)res.start, 212 + (unsigned long long)res.end); 213 + 214 + err = -EBUSY; 215 + info->list[i].res = request_mem_region(res.start, res.end - 216 + res.start + 1, 217 + dev_name(&dev->dev)); 218 + if (!info->list[i].res) 219 + goto err_out; 220 + 221 + err = -ENXIO; 222 + width = of_get_property(dp, "bank-width", NULL); 223 + if (!width) { 224 + dev_err(&dev->dev, "Can't get bank width from device" 225 + " tree\n"); 226 + goto err_out; 227 + } 228 + 229 + info->list[i].map.name = dev_name(&dev->dev); 230 + info->list[i].map.phys = res.start; 231 + info->list[i].map.size = res.end - res.start + 1; 232 + info->list[i].map.bankwidth = *width; 233 + 234 + err = -ENOMEM; 235 + info->list[i].map.virt = ioremap(info->list[i].map.phys, 236 + info->list[i].map.size); 237 + if (!info->list[i].map.virt) { 238 + dev_err(&dev->dev, "Failed to ioremap() flash" 239 + " region\n"); 240 + goto err_out; 241 + } 242 + 243 + simple_map_init(&info->list[i].map); 244 + 245 + if (probe_type) { 246 + info->list[i].mtd = do_map_probe(probe_type, 247 + &info->list[i].map); 248 + } else { 249 + info->list[i].mtd = obsolete_probe(dev, 250 + &info->list[i].map); 251 + } 252 + mtd_list[i] = info->list[i].mtd; 253 + 254 + err = -ENXIO; 255 + if (!info->list[i].mtd) { 256 + dev_err(&dev->dev, "do_map_probe() failed\n"); 257 + goto err_out; 258 + } else { 259 + info->list_size++; 260 + } 261 + info->list[i].mtd->owner = THIS_MODULE; 262 + info->list[i].mtd->dev.parent = &dev->dev; 216 263 } 217 264 218 - info->map.name = dev_name(&dev->dev); 219 - info->map.phys = res.start; 220 - info->map.size = res.end - res.start + 1; 221 - info->map.bankwidth = *width; 222 - 223 - err = -ENOMEM; 224 - info->map.virt = ioremap(info->map.phys, info->map.size); 225 - if (!info->map.virt) { 226 - dev_err(&dev->dev, "Failed to ioremap() flash region\n"); 227 - goto err_out; 265 + err = 0; 266 + if (info->list_size == 1) { 267 + info->cmtd = info->list[0].mtd; 268 + } else if (info->list_size > 1) { 269 + /* 270 + * We detected multiple devices. Concatenate them together. 271 + */ 272 + #ifdef CONFIG_MTD_CONCAT 273 + info->cmtd = mtd_concat_create(mtd_list, info->list_size, 274 + dev_name(&dev->dev)); 275 + if (info->cmtd == NULL) 276 + err = -ENXIO; 277 + #else 278 + printk(KERN_ERR "physmap_of: multiple devices " 279 + "found but MTD concat support disabled.\n"); 280 + err = -ENXIO; 281 + #endif 228 282 } 229 - 230 - simple_map_init(&info->map); 231 - 232 - if (probe_type) 233 - info->mtd = do_map_probe(probe_type, &info->map); 234 - else 235 - info->mtd = obsolete_probe(dev, &info->map); 236 - 237 - err = -ENXIO; 238 - if (!info->mtd) { 239 - dev_err(&dev->dev, "do_map_probe() failed\n"); 283 + if (err) 240 284 goto err_out; 241 - } 242 - info->mtd->owner = THIS_MODULE; 243 - info->mtd->dev.parent = &dev->dev; 244 285 245 286 #ifdef CONFIG_MTD_PARTITIONS 246 287 /* First look for RedBoot table or partitions on the command 247 288 * line, these take precedence over device tree information */ 248 - err = parse_mtd_partitions(info->mtd, part_probe_types, 249 - &info->parts, 0); 289 + err = parse_mtd_partitions(info->cmtd, part_probe_types, 290 + &info->parts, 0); 250 291 if (err < 0) 251 292 return err; 252 293 ··· 327 244 } 328 245 329 246 if (err > 0) 330 - add_mtd_partitions(info->mtd, info->parts, err); 247 + add_mtd_partitions(info->cmtd, info->parts, err); 331 248 else 332 249 #endif 333 - add_mtd_device(info->mtd); 250 + add_mtd_device(info->cmtd); 251 + 252 + kfree(mtd_list); 334 253 335 254 return 0; 336 255 337 256 err_out: 257 + kfree(mtd_list); 338 258 of_flash_remove(dev); 259 + 339 260 return err; 340 261 } 341 262
-104
drivers/mtd/maps/pmcmsp-ramroot.c
··· 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 - 42 - static struct mtd_info *rr_mtd; 43 - 44 - struct map_info rr_map = { 45 - .name = "ramroot", 46 - .bankwidth = 4, 47 - }; 48 - 49 - static 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 - 90 - static 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 - 99 - MODULE_AUTHOR("PMC-Sierra, Inc"); 100 - MODULE_DESCRIPTION("MTD map driver for embedded PMC-Sierra MSP filesystem"); 101 - MODULE_LICENSE("GPL"); 102 - 103 - module_init(init_rrmap); 104 - module_exit(cleanup_rrmap);
-22
drivers/mtd/maps/pxa2xx-flash.c
··· 140 140 } 141 141 142 142 #ifdef CONFIG_PM 143 - static 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 - 153 - static 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 - } 161 143 static void pxa2xx_flash_shutdown(struct platform_device *dev) 162 144 { 163 145 struct pxa2xx_flash_info *info = platform_get_drvdata(dev); ··· 148 166 info->mtd->resume(info->mtd); 149 167 } 150 168 #else 151 - #define pxa2xx_flash_suspend NULL 152 - #define pxa2xx_flash_resume NULL 153 169 #define pxa2xx_flash_shutdown NULL 154 170 #endif 155 171 ··· 158 178 }, 159 179 .probe = pxa2xx_flash_probe, 160 180 .remove = __devexit_p(pxa2xx_flash_remove), 161 - .suspend = pxa2xx_flash_suspend, 162 - .resume = pxa2xx_flash_resume, 163 181 .shutdown = pxa2xx_flash_shutdown, 164 182 }; 165 183
-23
drivers/mtd/maps/rbtx4939-flash.c
··· 145 145 } 146 146 147 147 #ifdef CONFIG_PM 148 - static 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 - 158 - static 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 - 167 148 static void rbtx4939_flash_shutdown(struct platform_device *dev) 168 149 { 169 150 struct rbtx4939_flash_info *info = platform_get_drvdata(dev); ··· 154 173 info->mtd->resume(info->mtd); 155 174 } 156 175 #else 157 - #define rbtx4939_flash_suspend NULL 158 - #define rbtx4939_flash_resume NULL 159 176 #define rbtx4939_flash_shutdown NULL 160 177 #endif 161 178 162 179 static struct platform_driver rbtx4939_flash_driver = { 163 180 .probe = rbtx4939_flash_probe, 164 181 .remove = rbtx4939_flash_remove, 165 - .suspend = rbtx4939_flash_suspend, 166 - .resume = rbtx4939_flash_resume, 167 182 .shutdown = rbtx4939_flash_shutdown, 168 183 .driver = { 169 184 .name = "rbtx4939-flash",
-23
drivers/mtd/maps/sa1100-flash.c
··· 415 415 } 416 416 417 417 #ifdef CONFIG_PM 418 - static 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 - 429 - static 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 - 437 418 static void sa1100_mtd_shutdown(struct platform_device *dev) 438 419 { 439 420 struct sa_info *info = platform_get_drvdata(dev); ··· 422 441 info->mtd->resume(info->mtd); 423 442 } 424 443 #else 425 - #define sa1100_mtd_suspend NULL 426 - #define sa1100_mtd_resume NULL 427 444 #define sa1100_mtd_shutdown NULL 428 445 #endif 429 446 430 447 static struct platform_driver sa1100_mtd_driver = { 431 448 .probe = sa1100_mtd_probe, 432 449 .remove = __exit_p(sa1100_mtd_remove), 433 - .suspend = sa1100_mtd_suspend, 434 - .resume = sa1100_mtd_resume, 435 450 .shutdown = sa1100_mtd_shutdown, 436 451 .driver = { 437 452 .name = "sa1100-mtd",
+9 -7
drivers/mtd/maps/uclinux.c
··· 22 22 23 23 /****************************************************************************/ 24 24 25 + extern char _ebss; 26 + 25 27 struct map_info uclinux_ram_map = { 26 28 .name = "RAM", 29 + .phys = (unsigned long)&_ebss, 30 + .size = 0, 27 31 }; 28 32 29 - struct mtd_info *uclinux_ram_mtdinfo; 33 + static struct mtd_info *uclinux_ram_mtdinfo; 30 34 31 35 /****************************************************************************/ 32 36 33 - struct mtd_partition uclinux_romfs[] = { 37 + static struct mtd_partition uclinux_romfs[] = { 34 38 { .name = "ROMfs" } 35 39 }; 36 40 ··· 42 38 43 39 /****************************************************************************/ 44 40 45 - int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len, 41 + static int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len, 46 42 size_t *retlen, void **virt, resource_size_t *phys) 47 43 { 48 44 struct map_info *map = mtd->priv; ··· 59 55 { 60 56 struct mtd_info *mtd; 61 57 struct map_info *mapp; 62 - extern char _ebss; 63 - unsigned long addr = (unsigned long) &_ebss; 64 58 65 59 mapp = &uclinux_ram_map; 66 - mapp->phys = addr; 67 - mapp->size = PAGE_ALIGN(ntohl(*((unsigned long *)(addr + 8)))); 60 + if (!mapp->size) 61 + mapp->size = PAGE_ALIGN(ntohl(*((unsigned long *)(mapp->phys + 8)))); 68 62 mapp->bankwidth = 4; 69 63 70 64 printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n",
+1 -1
drivers/mtd/mtd_blkdevs.c
··· 291 291 gd->private_data = new; 292 292 new->blkcore_priv = gd; 293 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 296 if (new->readonly) 297 297 set_disk_ro(gd, 1);
+217 -88
drivers/mtd/mtdchar.c
··· 14 14 #include <linux/sched.h> 15 15 #include <linux/smp_lock.h> 16 16 #include <linux/backing-dev.h> 17 + #include <linux/compat.h> 17 18 18 19 #include <linux/mtd/mtd.h> 19 20 #include <linux/mtd/compatmac.h> ··· 356 355 # define otp_select_filemode(f,m) -EOPNOTSUPP 357 356 #endif 358 357 358 + static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd, 359 + uint64_t start, uint32_t length, void __user *ptr, 360 + uint32_t __user *retp) 361 + { 362 + struct mtd_oob_ops ops; 363 + uint32_t retlen; 364 + int ret = 0; 365 + 366 + if (!(file->f_mode & FMODE_WRITE)) 367 + return -EPERM; 368 + 369 + if (length > 4096) 370 + return -EINVAL; 371 + 372 + if (!mtd->write_oob) 373 + ret = -EOPNOTSUPP; 374 + else 375 + ret = access_ok(VERIFY_READ, ptr, length) ? 0 : EFAULT; 376 + 377 + if (ret) 378 + return ret; 379 + 380 + ops.ooblen = length; 381 + ops.ooboffs = start & (mtd->oobsize - 1); 382 + ops.datbuf = NULL; 383 + ops.mode = MTD_OOB_PLACE; 384 + 385 + if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs)) 386 + return -EINVAL; 387 + 388 + ops.oobbuf = kmalloc(length, GFP_KERNEL); 389 + if (!ops.oobbuf) 390 + return -ENOMEM; 391 + 392 + if (copy_from_user(ops.oobbuf, ptr, length)) { 393 + kfree(ops.oobbuf); 394 + return -EFAULT; 395 + } 396 + 397 + start &= ~((uint64_t)mtd->oobsize - 1); 398 + ret = mtd->write_oob(mtd, start, &ops); 399 + 400 + if (ops.oobretlen > 0xFFFFFFFFU) 401 + ret = -EOVERFLOW; 402 + retlen = ops.oobretlen; 403 + if (copy_to_user(retp, &retlen, sizeof(length))) 404 + ret = -EFAULT; 405 + 406 + kfree(ops.oobbuf); 407 + return ret; 408 + } 409 + 410 + static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start, 411 + uint32_t length, void __user *ptr, uint32_t __user *retp) 412 + { 413 + struct mtd_oob_ops ops; 414 + int ret = 0; 415 + 416 + if (length > 4096) 417 + return -EINVAL; 418 + 419 + if (!mtd->read_oob) 420 + ret = -EOPNOTSUPP; 421 + else 422 + ret = access_ok(VERIFY_WRITE, ptr, 423 + length) ? 0 : -EFAULT; 424 + if (ret) 425 + return ret; 426 + 427 + ops.ooblen = length; 428 + ops.ooboffs = start & (mtd->oobsize - 1); 429 + ops.datbuf = NULL; 430 + ops.mode = MTD_OOB_PLACE; 431 + 432 + if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs)) 433 + return -EINVAL; 434 + 435 + ops.oobbuf = kmalloc(length, GFP_KERNEL); 436 + if (!ops.oobbuf) 437 + return -ENOMEM; 438 + 439 + start &= ~((uint64_t)mtd->oobsize - 1); 440 + ret = mtd->read_oob(mtd, start, &ops); 441 + 442 + if (put_user(ops.oobretlen, retp)) 443 + ret = -EFAULT; 444 + else if (ops.oobretlen && copy_to_user(ptr, ops.oobbuf, 445 + ops.oobretlen)) 446 + ret = -EFAULT; 447 + 448 + kfree(ops.oobbuf); 449 + return ret; 450 + } 451 + 359 452 static int mtd_ioctl(struct inode *inode, struct file *file, 360 453 u_int cmd, u_long arg) 361 454 { ··· 512 417 break; 513 418 514 419 case MEMERASE: 420 + case MEMERASE64: 515 421 { 516 422 struct erase_info *erase; 517 423 ··· 523 427 if (!erase) 524 428 ret = -ENOMEM; 525 429 else { 526 - struct erase_info_user einfo; 527 - 528 430 wait_queue_head_t waitq; 529 431 DECLARE_WAITQUEUE(wait, current); 530 432 531 433 init_waitqueue_head(&waitq); 532 434 533 - if (copy_from_user(&einfo, argp, 534 - sizeof(struct erase_info_user))) { 535 - kfree(erase); 536 - return -EFAULT; 435 + if (cmd == MEMERASE64) { 436 + struct erase_info_user64 einfo64; 437 + 438 + if (copy_from_user(&einfo64, argp, 439 + sizeof(struct erase_info_user64))) { 440 + kfree(erase); 441 + return -EFAULT; 442 + } 443 + erase->addr = einfo64.start; 444 + erase->len = einfo64.length; 445 + } else { 446 + struct erase_info_user einfo32; 447 + 448 + if (copy_from_user(&einfo32, argp, 449 + sizeof(struct erase_info_user))) { 450 + kfree(erase); 451 + return -EFAULT; 452 + } 453 + erase->addr = einfo32.start; 454 + erase->len = einfo32.length; 537 455 } 538 - erase->addr = einfo.start; 539 - erase->len = einfo.length; 540 456 erase->mtd = mtd; 541 457 erase->callback = mtdchar_erase_callback; 542 458 erase->priv = (unsigned long)&waitq; ··· 582 474 case MEMWRITEOOB: 583 475 { 584 476 struct mtd_oob_buf buf; 585 - struct mtd_oob_ops ops; 586 - struct mtd_oob_buf __user *user_buf = argp; 587 - uint32_t retlen; 477 + struct mtd_oob_buf __user *buf_user = argp; 588 478 589 - if(!(file->f_mode & FMODE_WRITE)) 590 - return -EPERM; 591 - 592 - if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) 593 - return -EFAULT; 594 - 595 - if (buf.length > 4096) 596 - return -EINVAL; 597 - 598 - if (!mtd->write_oob) 599 - ret = -EOPNOTSUPP; 600 - else 601 - ret = access_ok(VERIFY_READ, buf.ptr, 602 - buf.length) ? 0 : EFAULT; 603 - 604 - if (ret) 605 - return ret; 606 - 607 - ops.ooblen = buf.length; 608 - ops.ooboffs = buf.start & (mtd->oobsize - 1); 609 - ops.datbuf = NULL; 610 - ops.mode = MTD_OOB_PLACE; 611 - 612 - if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs)) 613 - return -EINVAL; 614 - 615 - ops.oobbuf = kmalloc(buf.length, GFP_KERNEL); 616 - if (!ops.oobbuf) 617 - return -ENOMEM; 618 - 619 - if (copy_from_user(ops.oobbuf, buf.ptr, buf.length)) { 620 - kfree(ops.oobbuf); 621 - return -EFAULT; 622 - } 623 - 624 - buf.start &= ~(mtd->oobsize - 1); 625 - ret = mtd->write_oob(mtd, buf.start, &ops); 626 - 627 - if (ops.oobretlen > 0xFFFFFFFFU) 628 - ret = -EOVERFLOW; 629 - retlen = ops.oobretlen; 630 - if (copy_to_user(&user_buf->length, &retlen, sizeof(buf.length))) 479 + /* NOTE: writes return length to buf_user->length */ 480 + if (copy_from_user(&buf, argp, sizeof(buf))) 631 481 ret = -EFAULT; 632 - 633 - kfree(ops.oobbuf); 482 + else 483 + ret = mtd_do_writeoob(file, mtd, buf.start, buf.length, 484 + buf.ptr, &buf_user->length); 634 485 break; 635 - 636 486 } 637 487 638 488 case MEMREADOOB: 639 489 { 640 490 struct mtd_oob_buf buf; 641 - struct mtd_oob_ops ops; 491 + struct mtd_oob_buf __user *buf_user = argp; 642 492 643 - if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) 644 - return -EFAULT; 645 - 646 - if (buf.length > 4096) 647 - return -EINVAL; 648 - 649 - if (!mtd->read_oob) 650 - ret = -EOPNOTSUPP; 493 + /* NOTE: writes return length to buf_user->start */ 494 + if (copy_from_user(&buf, argp, sizeof(buf))) 495 + ret = -EFAULT; 651 496 else 652 - ret = access_ok(VERIFY_WRITE, buf.ptr, 653 - buf.length) ? 0 : -EFAULT; 654 - if (ret) 655 - return ret; 497 + ret = mtd_do_readoob(mtd, buf.start, buf.length, 498 + buf.ptr, &buf_user->start); 499 + break; 500 + } 656 501 657 - ops.ooblen = buf.length; 658 - ops.ooboffs = buf.start & (mtd->oobsize - 1); 659 - ops.datbuf = NULL; 660 - ops.mode = MTD_OOB_PLACE; 502 + case MEMWRITEOOB64: 503 + { 504 + struct mtd_oob_buf64 buf; 505 + struct mtd_oob_buf64 __user *buf_user = argp; 661 506 662 - if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs)) 663 - return -EINVAL; 664 - 665 - ops.oobbuf = kmalloc(buf.length, GFP_KERNEL); 666 - if (!ops.oobbuf) 667 - return -ENOMEM; 668 - 669 - buf.start &= ~(mtd->oobsize - 1); 670 - ret = mtd->read_oob(mtd, buf.start, &ops); 671 - 672 - if (put_user(ops.oobretlen, (uint32_t __user *)argp)) 507 + if (copy_from_user(&buf, argp, sizeof(buf))) 673 508 ret = -EFAULT; 674 - else if (ops.oobretlen && copy_to_user(buf.ptr, ops.oobbuf, 675 - ops.oobretlen)) 676 - ret = -EFAULT; 509 + else 510 + ret = mtd_do_writeoob(file, mtd, buf.start, buf.length, 511 + (void __user *)(uintptr_t)buf.usr_ptr, 512 + &buf_user->length); 513 + break; 514 + } 677 515 678 - kfree(ops.oobbuf); 516 + case MEMREADOOB64: 517 + { 518 + struct mtd_oob_buf64 buf; 519 + struct mtd_oob_buf64 __user *buf_user = argp; 520 + 521 + if (copy_from_user(&buf, argp, sizeof(buf))) 522 + ret = -EFAULT; 523 + else 524 + ret = mtd_do_readoob(mtd, buf.start, buf.length, 525 + (void __user *)(uintptr_t)buf.usr_ptr, 526 + &buf_user->length); 679 527 break; 680 528 } 681 529 ··· 822 758 return ret; 823 759 } /* memory_ioctl */ 824 760 761 + #ifdef CONFIG_COMPAT 762 + 763 + struct mtd_oob_buf32 { 764 + u_int32_t start; 765 + u_int32_t length; 766 + compat_caddr_t ptr; /* unsigned char* */ 767 + }; 768 + 769 + #define MEMWRITEOOB32 _IOWR('M', 3, struct mtd_oob_buf32) 770 + #define MEMREADOOB32 _IOWR('M', 4, struct mtd_oob_buf32) 771 + 772 + static long mtd_compat_ioctl(struct file *file, unsigned int cmd, 773 + unsigned long arg) 774 + { 775 + struct inode *inode = file->f_path.dentry->d_inode; 776 + struct mtd_file_info *mfi = file->private_data; 777 + struct mtd_info *mtd = mfi->mtd; 778 + void __user *argp = compat_ptr(arg); 779 + int ret = 0; 780 + 781 + lock_kernel(); 782 + 783 + switch (cmd) { 784 + case MEMWRITEOOB32: 785 + { 786 + struct mtd_oob_buf32 buf; 787 + struct mtd_oob_buf32 __user *buf_user = argp; 788 + 789 + if (copy_from_user(&buf, argp, sizeof(buf))) 790 + ret = -EFAULT; 791 + else 792 + ret = mtd_do_writeoob(file, mtd, buf.start, 793 + buf.length, compat_ptr(buf.ptr), 794 + &buf_user->length); 795 + break; 796 + } 797 + 798 + case MEMREADOOB32: 799 + { 800 + struct mtd_oob_buf32 buf; 801 + struct mtd_oob_buf32 __user *buf_user = argp; 802 + 803 + /* NOTE: writes return length to buf->start */ 804 + if (copy_from_user(&buf, argp, sizeof(buf))) 805 + ret = -EFAULT; 806 + else 807 + ret = mtd_do_readoob(mtd, buf.start, 808 + buf.length, compat_ptr(buf.ptr), 809 + &buf_user->start); 810 + break; 811 + } 812 + default: 813 + ret = mtd_ioctl(inode, file, cmd, (unsigned long)argp); 814 + } 815 + 816 + unlock_kernel(); 817 + 818 + return ret; 819 + } 820 + 821 + #endif /* CONFIG_COMPAT */ 822 + 825 823 /* 826 824 * try to determine where a shared mapping can be made 827 825 * - only supported for NOMMU at the moment (MMU can't doesn't copy private ··· 943 817 .read = mtd_read, 944 818 .write = mtd_write, 945 819 .ioctl = mtd_ioctl, 820 + #ifdef CONFIG_COMPAT 821 + .compat_ioctl = mtd_compat_ioctl, 822 + #endif 946 823 .open = mtd_open, 947 824 .release = mtd_close, 948 825 .mmap = mtd_mmap,
+36 -9
drivers/mtd/mtdcore.c
··· 23 23 24 24 #include "mtdcore.h" 25 25 26 + static int mtd_cls_suspend(struct device *dev, pm_message_t state); 27 + static int mtd_cls_resume(struct device *dev); 26 28 27 - static struct class *mtd_class; 29 + static 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 36 /* These are exported solely for the purpose of mtd_blkdevs.c. You 30 37 should not use them for _anything_ else */ ··· 59 52 60 53 /* remove /dev/mtdXro node if needed */ 61 54 if (index) 62 - device_destroy(mtd_class, index + 1); 55 + device_destroy(&mtd_class, index + 1); 56 + } 57 + 58 + static int mtd_cls_suspend(struct device *dev, pm_message_t state) 59 + { 60 + struct mtd_info *mtd = dev_to_mtd(dev); 61 + 62 + if (mtd->suspend) 63 + return mtd->suspend(mtd); 64 + else 65 + return 0; 66 + } 67 + 68 + static int mtd_cls_resume(struct device *dev) 69 + { 70 + struct mtd_info *mtd = dev_to_mtd(dev); 71 + 72 + if (mtd->resume) 73 + mtd->resume(mtd); 74 + return 0; 63 75 } 64 76 65 77 static ssize_t mtd_type_show(struct device *dev, ··· 295 269 * physical device. 296 270 */ 297 271 mtd->dev.type = &mtd_devtype; 298 - mtd->dev.class = mtd_class; 272 + mtd->dev.class = &mtd_class; 299 273 mtd->dev.devt = MTD_DEVT(i); 300 274 dev_set_name(&mtd->dev, "mtd%d", i); 301 275 if (device_register(&mtd->dev) != 0) { ··· 304 278 } 305 279 306 280 if (MTD_DEVT(i)) 307 - device_create(mtd_class, mtd->dev.parent, 281 + device_create(&mtd_class, mtd->dev.parent, 308 282 MTD_DEVT(i) + 1, 309 283 NULL, "mtd%dro", i); 310 284 ··· 630 604 631 605 static int __init init_mtd(void) 632 606 { 633 - mtd_class = class_create(THIS_MODULE, "mtd"); 607 + int ret; 608 + ret = class_register(&mtd_class); 634 609 635 - if (IS_ERR(mtd_class)) { 636 - pr_err("Error creating mtd class.\n"); 637 - return PTR_ERR(mtd_class); 610 + if (ret) { 611 + pr_err("Error registering mtd class: %d\n", ret); 612 + return ret; 638 613 } 639 614 #ifdef CONFIG_PROC_FS 640 615 if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) ··· 650 623 if (proc_mtd) 651 624 remove_proc_entry( "mtd", NULL); 652 625 #endif /* CONFIG_PROC_FS */ 653 - class_destroy(mtd_class); 626 + class_unregister(&mtd_class); 654 627 } 655 628 656 629 module_init(init_mtd);
+5 -15
drivers/mtd/mtdpart.c
··· 27 27 struct mtd_info mtd; 28 28 struct mtd_info *master; 29 29 uint64_t offset; 30 - int index; 31 30 struct list_head list; 32 - int registered; 33 31 }; 34 32 35 33 /* ··· 319 321 list_for_each_entry_safe(slave, next, &mtd_partitions, list) 320 322 if (slave->master == master) { 321 323 list_del(&slave->list); 322 - if (slave->registered) 323 - del_mtd_device(&slave->mtd); 324 + del_mtd_device(&slave->mtd); 324 325 kfree(slave); 325 326 } 326 327 ··· 392 395 slave->mtd.get_fact_prot_info = part_get_fact_prot_info; 393 396 if (master->sync) 394 397 slave->mtd.sync = part_sync; 395 - if (!partno && master->suspend && master->resume) { 398 + if (!partno && !master->dev.class && master->suspend && master->resume) { 396 399 slave->mtd.suspend = part_suspend; 397 400 slave->mtd.resume = part_resume; 398 401 } ··· 409 412 slave->mtd.erase = part_erase; 410 413 slave->master = master; 411 414 slave->offset = part->offset; 412 - slave->index = partno; 413 415 414 416 if (slave->offset == MTDPART_OFS_APPEND) 415 417 slave->offset = cur_offset; ··· 496 500 } 497 501 498 502 out_register: 499 - if (part->mtdp) { 500 - /* store the object pointer (caller may or may not register it*/ 501 - *part->mtdp = &slave->mtd; 502 - slave->registered = 0; 503 - } else { 504 - /* register our partition */ 505 - add_mtd_device(&slave->mtd); 506 - slave->registered = 1; 507 - } 503 + /* register our partition */ 504 + add_mtd_device(&slave->mtd); 505 + 508 506 return slave; 509 507 } 510 508
+15 -9
drivers/mtd/nand/Kconfig
··· 74 74 help 75 75 Support for NAND flash on Amstrad E3 (Delta). 76 76 77 + config 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 + 77 83 config MTD_NAND_TS7250 78 84 tristate "NAND Flash device on TS-7250 board" 79 85 depends on MACH_TS72XX ··· 145 139 This enables the NAND flash driver on the PPChameleon EVB Board. 146 140 147 141 config MTD_NAND_S3C2410 148 - tristate "NAND Flash support for S3C2410/S3C2440 SoC" 149 - depends on ARCH_S3C2410 142 + tristate "NAND Flash support for Samsung S3C SoCs" 143 + depends on ARCH_S3C2410 || ARCH_S3C64XX 150 144 help 151 - This enables the NAND flash controller on the S3C2410 and S3C2440 145 + This enables the NAND flash controller on the S3C24xx and S3C64xx 152 146 SoCs 153 147 154 148 No board specific support is done by this driver, each board 155 149 must advertise a platform_device for the driver to attach. 156 150 157 151 config MTD_NAND_S3C2410_DEBUG 158 - bool "S3C2410 NAND driver debug" 152 + bool "Samsung S3C NAND driver debug" 159 153 depends on MTD_NAND_S3C2410 160 154 help 161 - Enable debugging of the S3C2410 NAND driver 155 + Enable debugging of the S3C NAND driver 162 156 163 157 config MTD_NAND_S3C2410_HWECC 164 - bool "S3C2410 NAND Hardware ECC" 158 + bool "Samsung S3C NAND Hardware ECC" 165 159 depends on MTD_NAND_S3C2410 166 160 help 167 - Enable the use of the S3C2410's internal ECC generator when 168 - using NAND. Early versions of the chip have had problems with 161 + Enable the use of the controller's internal ECC generator when 162 + using NAND. Early versions of the chips have had problems with 169 163 incorrect ECC generation, and if using these, the default of 170 164 software ECC is preferable. 171 165 ··· 177 171 NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs 178 172 179 173 config MTD_NAND_S3C2410_CLKSTOP 180 - bool "S3C2410 NAND IDLE clock stop" 174 + bool "Samsung S3C NAND IDLE clock stop" 181 175 depends on MTD_NAND_S3C2410 182 176 default n 183 177 help
+1
drivers/mtd/nand/Makefile
··· 25 25 obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o 26 26 obj-$(CONFIG_MTD_NAND_ATMEL) += atmel_nand.o 27 27 obj-$(CONFIG_MTD_NAND_GPIO) += gpio.o 28 + obj-$(CONFIG_MTD_NAND_OMAP2) += omap2.o 28 29 obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o 29 30 obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o 30 31 obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o
+10 -1
drivers/mtd/nand/atmel_nand.c
··· 24 24 25 25 #include <linux/slab.h> 26 26 #include <linux/module.h> 27 + #include <linux/moduleparam.h> 27 28 #include <linux/platform_device.h> 28 29 #include <linux/mtd/mtd.h> 29 30 #include <linux/mtd/nand.h> ··· 47 46 #else 48 47 #define no_ecc 0 49 48 #endif 49 + 50 + static int on_flash_bbt = 0; 51 + module_param(on_flash_bbt, int, 0); 50 52 51 53 /* Register access macros */ 52 54 #define ecc_readl(add, reg) \ ··· 463 459 464 460 if (host->board->det_pin) { 465 461 if (gpio_get_value(host->board->det_pin)) { 466 - printk("No SmartMedia card inserted.\n"); 462 + printk(KERN_INFO "No SmartMedia card inserted.\n"); 467 463 res = ENXIO; 468 464 goto err_no_card; 469 465 } 466 + } 467 + 468 + if (on_flash_bbt) { 469 + printk(KERN_INFO "atmel_nand: Use On Flash BBT\n"); 470 + nand_chip->options |= NAND_USE_FLASH_BBT; 470 471 } 471 472 472 473 /* first scan to find the device and get the page size */
+12 -5
drivers/mtd/nand/bf5xx_nand.c
··· 458 458 return IRQ_HANDLED; 459 459 } 460 460 461 - static int bf5xx_nand_dma_rw(struct mtd_info *mtd, 461 + static void bf5xx_nand_dma_rw(struct mtd_info *mtd, 462 462 uint8_t *buf, int is_read) 463 463 { 464 464 struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); ··· 496 496 /* setup DMA register with Blackfin DMA API */ 497 497 set_dma_config(CH_NFC, 0x0); 498 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 508 set_dma_x_count(CH_NFC, (page_size >> 2)); 500 509 set_dma_x_modify(CH_NFC, 4); 501 - 502 - /* setup write or read operation */ 503 510 val = DI_EN | WDSIZE_32; 511 + #endif 512 + /* setup write or read operation */ 504 513 if (is_read) 505 514 val |= WNR; 506 515 set_dma_config(CH_NFC, val); ··· 521 512 else 522 513 bfin_write_NFC_PGCTL(0x2); 523 514 wait_for_completion(&info->dma_completion); 524 - 525 - return 0; 526 515 } 527 516 528 517 static void bf5xx_nand_dma_read_buf(struct mtd_info *mtd,
+303 -41
drivers/mtd/nand/davinci_nand.c
··· 44 44 * and some flavors of secondary chipselect (e.g. based on A12) as used 45 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 48 * available on chips like the DM355 and OMAP-L137 and needed with the 49 49 * more error-prone MLC NAND chips. 50 50 * ··· 54 54 struct davinci_nand_info { 55 55 struct mtd_info mtd; 56 56 struct nand_chip chip; 57 + struct nand_ecclayout ecclayout; 57 58 58 59 struct device *dev; 59 60 struct clk *clk; 60 61 bool partitioned; 62 + 63 + bool is_readmode; 61 64 62 65 void __iomem *base; 63 66 void __iomem *vaddr; ··· 76 73 }; 77 74 78 75 static DEFINE_SPINLOCK(davinci_nand_lock); 76 + static bool ecc4_busy; 79 77 80 78 #define to_davinci_nand(m) container_of(m, struct davinci_nand_info, mtd) 81 79 ··· 222 218 /*----------------------------------------------------------------------*/ 223 219 224 220 /* 221 + * 4-bit hardware ECC ... context maintained over entire AEMIF 222 + * 223 + * This is a syndrome engine, but we avoid NAND_ECC_HW_SYNDROME 224 + * since that forces use of a problematic "infix OOB" layout. 225 + * Among other things, it trashes manufacturer bad block markers. 226 + * Also, and specific to this hardware, it ECC-protects the "prepad" 227 + * in the OOB ... while having ECC protection for parts of OOB would 228 + * seem useful, the current MTD stack sometimes wants to update the 229 + * OOB without recomputing ECC. 230 + */ 231 + 232 + static void nand_davinci_hwctl_4bit(struct mtd_info *mtd, int mode) 233 + { 234 + struct davinci_nand_info *info = to_davinci_nand(mtd); 235 + unsigned long flags; 236 + u32 val; 237 + 238 + spin_lock_irqsave(&davinci_nand_lock, flags); 239 + 240 + /* Start 4-bit ECC calculation for read/write */ 241 + val = davinci_nand_readl(info, NANDFCR_OFFSET); 242 + val &= ~(0x03 << 4); 243 + val |= (info->core_chipsel << 4) | BIT(12); 244 + davinci_nand_writel(info, NANDFCR_OFFSET, val); 245 + 246 + info->is_readmode = (mode == NAND_ECC_READ); 247 + 248 + spin_unlock_irqrestore(&davinci_nand_lock, flags); 249 + } 250 + 251 + /* Read raw ECC code after writing to NAND. */ 252 + static void 253 + nand_davinci_readecc_4bit(struct davinci_nand_info *info, u32 code[4]) 254 + { 255 + const u32 mask = 0x03ff03ff; 256 + 257 + code[0] = davinci_nand_readl(info, NAND_4BIT_ECC1_OFFSET) & mask; 258 + code[1] = davinci_nand_readl(info, NAND_4BIT_ECC2_OFFSET) & mask; 259 + code[2] = davinci_nand_readl(info, NAND_4BIT_ECC3_OFFSET) & mask; 260 + code[3] = davinci_nand_readl(info, NAND_4BIT_ECC4_OFFSET) & mask; 261 + } 262 + 263 + /* Terminate read ECC; or return ECC (as bytes) of data written to NAND. */ 264 + static int nand_davinci_calculate_4bit(struct mtd_info *mtd, 265 + const u_char *dat, u_char *ecc_code) 266 + { 267 + struct davinci_nand_info *info = to_davinci_nand(mtd); 268 + u32 raw_ecc[4], *p; 269 + unsigned i; 270 + 271 + /* After a read, terminate ECC calculation by a dummy read 272 + * of some 4-bit ECC register. ECC covers everything that 273 + * was read; correct() just uses the hardware state, so 274 + * ecc_code is not needed. 275 + */ 276 + if (info->is_readmode) { 277 + davinci_nand_readl(info, NAND_4BIT_ECC1_OFFSET); 278 + return 0; 279 + } 280 + 281 + /* Pack eight raw 10-bit ecc values into ten bytes, making 282 + * two passes which each convert four values (in upper and 283 + * lower halves of two 32-bit words) into five bytes. The 284 + * ROM boot loader uses this same packing scheme. 285 + */ 286 + nand_davinci_readecc_4bit(info, raw_ecc); 287 + for (i = 0, p = raw_ecc; i < 2; i++, p += 2) { 288 + *ecc_code++ = p[0] & 0xff; 289 + *ecc_code++ = ((p[0] >> 8) & 0x03) | ((p[0] >> 14) & 0xfc); 290 + *ecc_code++ = ((p[0] >> 22) & 0x0f) | ((p[1] << 4) & 0xf0); 291 + *ecc_code++ = ((p[1] >> 4) & 0x3f) | ((p[1] >> 10) & 0xc0); 292 + *ecc_code++ = (p[1] >> 18) & 0xff; 293 + } 294 + 295 + return 0; 296 + } 297 + 298 + /* Correct up to 4 bits in data we just read, using state left in the 299 + * hardware plus the ecc_code computed when it was first written. 300 + */ 301 + static int nand_davinci_correct_4bit(struct mtd_info *mtd, 302 + u_char *data, u_char *ecc_code, u_char *null) 303 + { 304 + int i; 305 + struct davinci_nand_info *info = to_davinci_nand(mtd); 306 + unsigned short ecc10[8]; 307 + unsigned short *ecc16; 308 + u32 syndrome[4]; 309 + unsigned num_errors, corrected; 310 + 311 + /* All bytes 0xff? It's an erased page; ignore its ECC. */ 312 + for (i = 0; i < 10; i++) { 313 + if (ecc_code[i] != 0xff) 314 + goto compare; 315 + } 316 + return 0; 317 + 318 + compare: 319 + /* Unpack ten bytes into eight 10 bit values. We know we're 320 + * little-endian, and use type punning for less shifting/masking. 321 + */ 322 + if (WARN_ON(0x01 & (unsigned) ecc_code)) 323 + return -EINVAL; 324 + ecc16 = (unsigned short *)ecc_code; 325 + 326 + ecc10[0] = (ecc16[0] >> 0) & 0x3ff; 327 + ecc10[1] = ((ecc16[0] >> 10) & 0x3f) | ((ecc16[1] << 6) & 0x3c0); 328 + ecc10[2] = (ecc16[1] >> 4) & 0x3ff; 329 + ecc10[3] = ((ecc16[1] >> 14) & 0x3) | ((ecc16[2] << 2) & 0x3fc); 330 + ecc10[4] = (ecc16[2] >> 8) | ((ecc16[3] << 8) & 0x300); 331 + ecc10[5] = (ecc16[3] >> 2) & 0x3ff; 332 + ecc10[6] = ((ecc16[3] >> 12) & 0xf) | ((ecc16[4] << 4) & 0x3f0); 333 + ecc10[7] = (ecc16[4] >> 6) & 0x3ff; 334 + 335 + /* Tell ECC controller about the expected ECC codes. */ 336 + for (i = 7; i >= 0; i--) 337 + davinci_nand_writel(info, NAND_4BIT_ECC_LOAD_OFFSET, ecc10[i]); 338 + 339 + /* Allow time for syndrome calculation ... then read it. 340 + * A syndrome of all zeroes 0 means no detected errors. 341 + */ 342 + davinci_nand_readl(info, NANDFSR_OFFSET); 343 + nand_davinci_readecc_4bit(info, syndrome); 344 + if (!(syndrome[0] | syndrome[1] | syndrome[2] | syndrome[3])) 345 + return 0; 346 + 347 + /* Start address calculation, and wait for it to complete. 348 + * We _could_ start reading more data while this is working, 349 + * to speed up the overall page read. 350 + */ 351 + davinci_nand_writel(info, NANDFCR_OFFSET, 352 + davinci_nand_readl(info, NANDFCR_OFFSET) | BIT(13)); 353 + for (;;) { 354 + u32 fsr = davinci_nand_readl(info, NANDFSR_OFFSET); 355 + 356 + switch ((fsr >> 8) & 0x0f) { 357 + case 0: /* no error, should not happen */ 358 + return 0; 359 + case 1: /* five or more errors detected */ 360 + return -EIO; 361 + case 2: /* error addresses computed */ 362 + case 3: 363 + num_errors = 1 + ((fsr >> 16) & 0x03); 364 + goto correct; 365 + default: /* still working on it */ 366 + cpu_relax(); 367 + continue; 368 + } 369 + } 370 + 371 + correct: 372 + /* correct each error */ 373 + for (i = 0, corrected = 0; i < num_errors; i++) { 374 + int error_address, error_value; 375 + 376 + if (i > 1) { 377 + error_address = davinci_nand_readl(info, 378 + NAND_ERR_ADD2_OFFSET); 379 + error_value = davinci_nand_readl(info, 380 + NAND_ERR_ERRVAL2_OFFSET); 381 + } else { 382 + error_address = davinci_nand_readl(info, 383 + NAND_ERR_ADD1_OFFSET); 384 + error_value = davinci_nand_readl(info, 385 + NAND_ERR_ERRVAL1_OFFSET); 386 + } 387 + 388 + if (i & 1) { 389 + error_address >>= 16; 390 + error_value >>= 16; 391 + } 392 + error_address &= 0x3ff; 393 + error_address = (512 + 7) - error_address; 394 + 395 + if (error_address < 512) { 396 + data[error_address] ^= error_value; 397 + corrected++; 398 + } 399 + } 400 + 401 + return corrected; 402 + } 403 + 404 + /*----------------------------------------------------------------------*/ 405 + 406 + /* 225 407 * NOTE: NAND boot requires ALE == EM_A[1], CLE == EM_A[2], so that's 226 408 * how these chips are normally wired. This translates to both 8 and 16 227 409 * bit busses using ALE == BIT(3) in byte addresses, and CLE == BIT(4). ··· 484 294 485 295 /*----------------------------------------------------------------------*/ 486 296 297 + /* An ECC layout for using 4-bit ECC with small-page flash, storing 298 + * ten ECC bytes plus the manufacturer's bad block marker byte, and 299 + * and not overlapping the default BBT markers. 300 + */ 301 + static struct nand_ecclayout hwecc4_small __initconst = { 302 + .eccbytes = 10, 303 + .eccpos = { 0, 1, 2, 3, 4, 304 + /* offset 5 holds the badblock marker */ 305 + 6, 7, 306 + 13, 14, 15, }, 307 + .oobfree = { 308 + {.offset = 8, .length = 5, }, 309 + {.offset = 16, }, 310 + }, 311 + }; 312 + 313 + 487 314 static int __init nand_davinci_probe(struct platform_device *pdev) 488 315 { 489 316 struct davinci_nand_pdata *pdata = pdev->dev.platform_data; ··· 512 305 int ret; 513 306 uint32_t val; 514 307 nand_ecc_modes_t ecc_mode; 308 + 309 + /* insist on board-specific configuration */ 310 + if (!pdata) 311 + return -ENODEV; 515 312 516 313 /* which external chipselect will we be managing? */ 517 314 if (pdev->id < 0 || pdev->id > 3) ··· 562 351 info->chip.select_chip = nand_davinci_select_chip; 563 352 564 353 /* options such as NAND_USE_FLASH_BBT or 16-bit widths */ 565 - info->chip.options = pdata ? pdata->options : 0; 354 + info->chip.options = pdata->options; 566 355 567 356 info->ioaddr = (uint32_t __force) vaddr; 568 357 ··· 571 360 info->mask_chipsel = pdata->mask_chipsel; 572 361 573 362 /* use nandboot-capable ALE/CLE masks by default */ 574 - if (pdata && pdata->mask_ale) 575 - info->mask_ale = pdata->mask_cle; 576 - else 577 - info->mask_ale = MASK_ALE; 578 - if (pdata && pdata->mask_cle) 579 - info->mask_cle = pdata->mask_cle; 580 - else 581 - info->mask_cle = MASK_CLE; 363 + info->mask_ale = pdata->mask_cle ? : MASK_ALE; 364 + info->mask_cle = pdata->mask_cle ? : MASK_CLE; 582 365 583 366 /* Set address of hardware control function */ 584 367 info->chip.cmd_ctrl = nand_davinci_hwcontrol; ··· 582 377 info->chip.read_buf = nand_davinci_read_buf; 583 378 info->chip.write_buf = nand_davinci_write_buf; 584 379 585 - /* use board-specific ECC config; else, the best available */ 586 - if (pdata) 587 - ecc_mode = pdata->ecc_mode; 588 - else 589 - ecc_mode = NAND_ECC_HW; 380 + /* Use board-specific ECC config */ 381 + ecc_mode = pdata->ecc_mode; 590 382 383 + ret = -EINVAL; 591 384 switch (ecc_mode) { 592 385 case NAND_ECC_NONE: 593 386 case NAND_ECC_SOFT: 387 + pdata->ecc_bits = 0; 594 388 break; 595 389 case NAND_ECC_HW: 596 - info->chip.ecc.calculate = nand_davinci_calculate_1bit; 597 - info->chip.ecc.correct = nand_davinci_correct_1bit; 598 - info->chip.ecc.hwctl = nand_davinci_hwctl_1bit; 599 - info->chip.ecc.size = 512; 600 - info->chip.ecc.bytes = 3; 601 - break; 602 - case NAND_ECC_HW_SYNDROME: 603 - /* FIXME implement */ 604 - info->chip.ecc.size = 512; 605 - info->chip.ecc.bytes = 10; 390 + if (pdata->ecc_bits == 4) { 391 + /* No sanity checks: CPUs must support this, 392 + * and the chips may not use NAND_BUSWIDTH_16. 393 + */ 606 394 607 - dev_warn(&pdev->dev, "4-bit ECC nyet supported\n"); 608 - /* FALL THROUGH */ 395 + /* No sharing 4-bit hardware between chipselects yet */ 396 + spin_lock_irq(&davinci_nand_lock); 397 + if (ecc4_busy) 398 + ret = -EBUSY; 399 + else 400 + ecc4_busy = true; 401 + spin_unlock_irq(&davinci_nand_lock); 402 + 403 + if (ret == -EBUSY) 404 + goto err_ecc; 405 + 406 + info->chip.ecc.calculate = nand_davinci_calculate_4bit; 407 + info->chip.ecc.correct = nand_davinci_correct_4bit; 408 + info->chip.ecc.hwctl = nand_davinci_hwctl_4bit; 409 + info->chip.ecc.bytes = 10; 410 + } else { 411 + info->chip.ecc.calculate = nand_davinci_calculate_1bit; 412 + info->chip.ecc.correct = nand_davinci_correct_1bit; 413 + info->chip.ecc.hwctl = nand_davinci_hwctl_1bit; 414 + info->chip.ecc.bytes = 3; 415 + } 416 + info->chip.ecc.size = 512; 417 + break; 609 418 default: 610 419 ret = -EINVAL; 611 420 goto err_ecc; ··· 660 441 spin_unlock_irq(&davinci_nand_lock); 661 442 662 443 /* Scan to find existence of the device(s) */ 663 - ret = nand_scan(&info->mtd, pdata->mask_chipsel ? 2 : 1); 444 + ret = nand_scan_ident(&info->mtd, pdata->mask_chipsel ? 2 : 1); 664 445 if (ret < 0) { 665 446 dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); 666 447 goto err_scan; 667 448 } 449 + 450 + /* Update ECC layout if needed ... for 1-bit HW ECC, the default 451 + * is OK, but it allocates 6 bytes when only 3 are needed (for 452 + * each 512 bytes). For the 4-bit HW ECC, that default is not 453 + * usable: 10 bytes are needed, not 6. 454 + */ 455 + if (pdata->ecc_bits == 4) { 456 + int chunks = info->mtd.writesize / 512; 457 + 458 + if (!chunks || info->mtd.oobsize < 16) { 459 + dev_dbg(&pdev->dev, "too small\n"); 460 + ret = -EINVAL; 461 + goto err_scan; 462 + } 463 + 464 + /* For small page chips, preserve the manufacturer's 465 + * badblock marking data ... and make sure a flash BBT 466 + * table marker fits in the free bytes. 467 + */ 468 + if (chunks == 1) { 469 + info->ecclayout = hwecc4_small; 470 + info->ecclayout.oobfree[1].length = 471 + info->mtd.oobsize - 16; 472 + goto syndrome_done; 473 + } 474 + 475 + /* For large page chips we'll be wanting to use a 476 + * not-yet-implemented mode that reads OOB data 477 + * before reading the body of the page, to avoid 478 + * the "infix OOB" model of NAND_ECC_HW_SYNDROME 479 + * (and preserve manufacturer badblock markings). 480 + */ 481 + dev_warn(&pdev->dev, "no 4-bit ECC support yet " 482 + "for large page NAND\n"); 483 + ret = -EIO; 484 + goto err_scan; 485 + 486 + syndrome_done: 487 + info->chip.ecc.layout = &info->ecclayout; 488 + } 489 + 490 + ret = nand_scan_tail(&info->mtd); 491 + if (ret < 0) 492 + goto err_scan; 668 493 669 494 if (mtd_has_partitions()) { 670 495 struct mtd_partition *mtd_parts = NULL; ··· 718 455 static const char *probes[] __initconst = 719 456 { "cmdlinepart", NULL }; 720 457 721 - const char *master_name; 722 - 723 - /* Set info->mtd.name = 0 temporarily */ 724 - master_name = info->mtd.name; 725 - info->mtd.name = (char *)0; 726 - 727 - /* info->mtd.name == 0, means: don't bother checking 728 - <mtd-id> */ 729 458 mtd_parts_nb = parse_mtd_partitions(&info->mtd, probes, 730 459 &mtd_parts, 0); 731 - 732 - /* Restore info->mtd.name */ 733 - info->mtd.name = master_name; 734 460 } 735 461 736 - if (mtd_parts_nb <= 0 && pdata) { 462 + if (mtd_parts_nb <= 0) { 737 463 mtd_parts = pdata->parts; 738 464 mtd_parts_nb = pdata->nr_parts; 739 465 } ··· 735 483 info->partitioned = true; 736 484 } 737 485 738 - } else if (pdata && pdata->nr_parts) { 486 + } else if (pdata->nr_parts) { 739 487 dev_warn(&pdev->dev, "ignoring %d default partitions on %s\n", 740 488 pdata->nr_parts, info->mtd.name); 741 489 } ··· 761 509 err_clk_enable: 762 510 clk_put(info->clk); 763 511 512 + spin_lock_irq(&davinci_nand_lock); 513 + if (ecc_mode == NAND_ECC_HW_SYNDROME) 514 + ecc4_busy = false; 515 + spin_unlock_irq(&davinci_nand_lock); 516 + 764 517 err_ecc: 765 518 err_clk: 766 519 err_ioremap: ··· 788 531 status = del_mtd_partitions(&info->mtd); 789 532 else 790 533 status = del_mtd_device(&info->mtd); 534 + 535 + spin_lock_irq(&davinci_nand_lock); 536 + if (info->chip.ecc.mode == NAND_ECC_HW_SYNDROME) 537 + ecc4_busy = false; 538 + spin_unlock_irq(&davinci_nand_lock); 791 539 792 540 iounmap(info->base); 793 541 iounmap(info->vaddr);
+54 -12
drivers/mtd/nand/mxc_nand.c
··· 138 138 static struct nand_ecclayout nand_hw_eccoob_16 = { 139 139 .eccbytes = 5, 140 140 .eccpos = {6, 7, 8, 9, 10}, 141 - .oobfree = {{0, 6}, {12, 4}, } 141 + .oobfree = {{0, 5}, {11, 5}, } 142 + }; 143 + 144 + static 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 151 #ifdef CONFIG_MTD_PARTITIONS ··· 199 192 } 200 193 udelay(1); 201 194 } 202 - if (max_retries <= 0) 195 + if (max_retries < 0) 203 196 DEBUG(MTD_DEBUG_LEVEL0, "%s(%d): INT not set\n", 204 197 __func__, param); 205 198 } ··· 802 795 send_addr(host, (page_addr & 0xff), false); 803 796 804 797 if (host->pagesize_2k) { 805 - send_addr(host, (page_addr >> 8) & 0xFF, false); 806 - if (mtd->size >= 0x40000000) 798 + if (mtd->size >= 0x10000000) { 799 + /* paddr_8 - paddr_15 */ 800 + send_addr(host, (page_addr >> 8) & 0xff, false); 807 801 send_addr(host, (page_addr >> 16) & 0xff, true); 802 + } else 803 + /* paddr_8 - paddr_15 */ 804 + send_addr(host, (page_addr >> 8) & 0xff, true); 808 805 } else { 809 806 /* One more address cycle for higher density devices */ 810 807 if (mtd->size >= 0x4000000) { ··· 934 923 this->ecc.mode = NAND_ECC_HW; 935 924 this->ecc.size = 512; 936 925 this->ecc.bytes = 3; 937 - this->ecc.layout = &nand_hw_eccoob_8; 938 926 tmp = readw(host->regs + NFC_CONFIG1); 939 927 tmp |= NFC_ECC_EN; 940 928 writew(tmp, host->regs + NFC_CONFIG1); ··· 967 957 this->ecc.layout = &nand_hw_eccoob_16; 968 958 } 969 959 970 - host->pagesize_2k = 0; 960 + /* first scan to find the device and get the page size */ 961 + if (nand_scan_ident(mtd, 1)) { 962 + err = -ENXIO; 963 + goto escan; 964 + } 971 965 972 - /* Scan to find existence of the device */ 973 - if (nand_scan(mtd, 1)) { 974 - DEBUG(MTD_DEBUG_LEVEL0, 975 - "MXC_ND: Unable to find any NAND device.\n"); 966 + host->pagesize_2k = (mtd->writesize == 2048) ? 1 : 0; 967 + 968 + if (this->ecc.mode == NAND_ECC_HW) { 969 + switch (mtd->oobsize) { 970 + case 8: 971 + this->ecc.layout = &nand_hw_eccoob_8; 972 + break; 973 + case 16: 974 + this->ecc.layout = &nand_hw_eccoob_16; 975 + break; 976 + case 64: 977 + this->ecc.layout = &nand_hw_eccoob_64; 978 + break; 979 + default: 980 + /* page size not handled by HW ECC */ 981 + /* switching back to soft ECC */ 982 + this->ecc.size = 512; 983 + this->ecc.bytes = 3; 984 + this->ecc.layout = &nand_hw_eccoob_8; 985 + this->ecc.mode = NAND_ECC_SOFT; 986 + this->ecc.calculate = NULL; 987 + this->ecc.correct = NULL; 988 + this->ecc.hwctl = NULL; 989 + tmp = readw(host->regs + NFC_CONFIG1); 990 + tmp &= ~NFC_ECC_EN; 991 + writew(tmp, host->regs + NFC_CONFIG1); 992 + break; 993 + } 994 + } 995 + 996 + /* second phase scan */ 997 + if (nand_scan_tail(mtd)) { 976 998 err = -ENXIO; 977 999 goto escan; 978 1000 } ··· 1027 985 return 0; 1028 986 1029 987 escan: 1030 - free_irq(host->irq, NULL); 988 + free_irq(host->irq, host); 1031 989 eirq: 1032 990 iounmap(host->regs); 1033 991 eres: ··· 1047 1005 platform_set_drvdata(pdev, NULL); 1048 1006 1049 1007 nand_release(&host->mtd); 1050 - free_irq(host->irq, NULL); 1008 + free_irq(host->irq, host); 1051 1009 iounmap(host->regs); 1052 1010 kfree(host); 1053 1011
+2 -1
drivers/mtd/nand/nand_base.c
··· 2756 2756 * the out of band area 2757 2757 */ 2758 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 2761 chip->ecc.layout->oobavail += 2761 2762 chip->ecc.layout->oobfree[i].length; 2762 2763 mtd->oobavail = chip->ecc.layout->oobavail;
+2 -2
drivers/mtd/nand/nand_ecc.c
··· 428 428 int nand_correct_data(struct mtd_info *mtd, unsigned char *buf, 429 429 unsigned char *read_ecc, unsigned char *calc_ecc) 430 430 { 431 - unsigned char b0, b1, b2; 432 - unsigned char byte_addr, bit_addr; 431 + unsigned char b0, b1, b2, bit_addr; 432 + unsigned int byte_addr; 433 433 /* 256 or 512 bytes/ecc */ 434 434 const uint32_t eccsize_mult = 435 435 (((struct nand_chip *)mtd->priv)->ecc.size) >> 8;
+776
drivers/mtd/nand/omap2.c
··· 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 110 + static const char *part_probes[] = { "cmdlinepart", NULL }; 111 + #endif 112 + 113 + struct 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 + */ 132 + static 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 + */ 158 + static 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 + */ 195 + static 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 + */ 208 + static 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 + */ 231 + static 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 + */ 251 + static 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 + */ 278 + static 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 + */ 300 + static 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 + */ 428 + static 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 + */ 467 + static 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 + */ 492 + static 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 + */ 538 + static 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 + */ 569 + static 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 + 593 + static 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 + 728 + out_release_mem_region: 729 + release_mem_region(info->phys_base, NAND_IO_SIZE); 730 + out_free_cs: 731 + gpmc_cs_free(info->gpmc_cs); 732 + out_free_info: 733 + kfree(info); 734 + 735 + return err; 736 + } 737 + 738 + static 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 + 751 + static 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 + 760 + static 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 + 766 + static void __exit omap_nand_exit(void) 767 + { 768 + platform_driver_unregister(&omap_nand_driver); 769 + } 770 + 771 + module_init(omap_nand_init); 772 + module_exit(omap_nand_exit); 773 + 774 + MODULE_ALIAS(DRIVER_NAME); 775 + MODULE_LICENSE("GPL"); 776 + MODULE_DESCRIPTION("Glue layer for NAND flash on TI OMAP boards");
+23
drivers/mtd/nand/orion_nand.c
··· 47 47 writeb(cmd, nc->IO_ADDR_W + offs); 48 48 } 49 49 50 + static 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 + 50 72 static int __init orion_nand_probe(struct platform_device *pdev) 51 73 { 52 74 struct mtd_info *mtd; ··· 105 83 nc->priv = board; 106 84 nc->IO_ADDR_R = nc->IO_ADDR_W = io_base; 107 85 nc->cmd_ctrl = orion_nand_cmd_ctrl; 86 + nc->read_buf = orion_nand_read_buf; 108 87 nc->ecc.mode = NAND_ECC_SOFT; 109 88 110 89 if (board->chip_delay)
+16 -3
drivers/mtd/nand/plat_nand.c
··· 61 61 data->chip.cmd_ctrl = pdata->ctrl.cmd_ctrl; 62 62 data->chip.dev_ready = pdata->ctrl.dev_ready; 63 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 66 data->chip.chip_delay = pdata->chip.chip_delay; 65 67 data->chip.options |= pdata->chip.options; 66 68 ··· 71 69 data->chip.ecc.mode = NAND_ECC_SOFT; 72 70 73 71 platform_set_drvdata(pdev, data); 72 + 73 + /* Handle any platform specific setup */ 74 + if (pdata->ctrl.probe) { 75 + res = pdata->ctrl.probe(pdev); 76 + if (res) 77 + goto out; 78 + } 74 79 75 80 /* Scan to find existance of the device */ 76 81 if (nand_scan(&data->mtd, 1)) { ··· 95 86 return 0; 96 87 } 97 88 } 89 + if (pdata->chip.set_parts) 90 + pdata->chip.set_parts(data->mtd.size, &pdata->chip); 98 91 if (pdata->chip.partitions) { 99 92 data->parts = pdata->chip.partitions; 100 93 res = add_mtd_partitions(&data->mtd, data->parts, ··· 110 99 111 100 nand_release(&data->mtd); 112 101 out: 102 + if (pdata->ctrl.remove) 103 + pdata->ctrl.remove(pdev); 113 104 platform_set_drvdata(pdev, NULL); 114 105 iounmap(data->io_base); 115 106 kfree(data); ··· 124 111 static int __devexit plat_nand_remove(struct platform_device *pdev) 125 112 { 126 113 struct plat_nand_data *data = platform_get_drvdata(pdev); 127 - #ifdef CONFIG_MTD_PARTITIONS 128 114 struct platform_nand_data *pdata = pdev->dev.platform_data; 129 - #endif 130 115 131 116 nand_release(&data->mtd); 132 117 #ifdef CONFIG_MTD_PARTITIONS 133 118 if (data->parts && data->parts != pdata->chip.partitions) 134 119 kfree(data->parts); 135 120 #endif 121 + if (pdata->ctrl.remove) 122 + pdata->ctrl.remove(pdev); 136 123 iounmap(data->io_base); 137 124 kfree(data); 138 125 ··· 141 128 142 129 static struct platform_driver plat_nand_driver = { 143 130 .probe = plat_nand_probe, 144 - .remove = plat_nand_remove, 131 + .remove = __devexit_p(plat_nand_remove), 145 132 .driver = { 146 133 .name = "gen_nand", 147 134 .owner = THIS_MODULE,
+181 -87
drivers/mtd/nand/s3c2410.c
··· 74 74 75 75 struct 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 + */ 77 85 struct s3c2410_nand_mtd { 78 86 struct mtd_info mtd; 79 87 struct nand_chip chip; ··· 98 90 99 91 /* overview of the s3c2410 nand state */ 100 92 93 + /** 94 + * struct s3c2410_nand_info - NAND controller state. 95 + * @mtds: An array of MTD instances on this controoler. 96 + * @platform: The platform data for this board. 97 + * @device: The platform device we bound to. 98 + * @area: The IO area resource that came from request_mem_region(). 99 + * @clk: The clock resource for this controller. 100 + * @regs: The area mapped for the hardware registers described by @area. 101 + * @sel_reg: Pointer to the register controlling the NAND selection. 102 + * @sel_bit: The bit in @sel_reg to select the NAND chip. 103 + * @mtd_count: The number of MTDs created from this controller. 104 + * @save_sel: The contents of @sel_reg to be saved over suspend. 105 + * @clk_rate: The clock rate from @clk. 106 + * @cpu_type: The exact type of this controller. 107 + */ 101 108 struct s3c2410_nand_info { 102 109 /* mtd info */ 103 110 struct nand_hw_control controller; ··· 168 145 169 146 #define NS_IN_KHZ 1000000 170 147 148 + /** 149 + * s3c_nand_calc_rate - calculate timing data. 150 + * @wanted: The cycle time in nanoseconds. 151 + * @clk: The clock rate in kHz. 152 + * @max: The maximum divider value. 153 + * 154 + * Calculate the timing value from the given parameters. 155 + */ 171 156 static int s3c_nand_calc_rate(int wanted, unsigned long clk, int max) 172 157 { 173 158 int result; 174 159 175 - result = (wanted * clk) / NS_IN_KHZ; 176 - result++; 160 + result = DIV_ROUND_UP((wanted * clk), NS_IN_KHZ); 177 161 178 162 pr_debug("result %d from %ld, %d\n", result, clk, wanted); 179 163 ··· 199 169 200 170 /* controller setup */ 201 171 172 + /** 173 + * s3c2410_nand_setrate - setup controller timing information. 174 + * @info: The controller instance. 175 + * 176 + * Given the information supplied by the platform, calculate and set 177 + * the necessary timing registers in the hardware to generate the 178 + * necessary timing cycles to the hardware. 179 + */ 202 180 static int s3c2410_nand_setrate(struct s3c2410_nand_info *info) 203 181 { 204 182 struct s3c2410_platform_nand *plat = info->platform; 205 183 int tacls_max = (info->cpu_type == TYPE_S3C2412) ? 8 : 4; 206 184 int tacls, twrph0, twrph1; 207 185 unsigned long clkrate = clk_get_rate(info->clk); 208 - unsigned long set, cfg, mask; 186 + unsigned long uninitialized_var(set), cfg, uninitialized_var(mask); 209 187 unsigned long flags; 210 188 211 189 /* calculate the timing information for the controller */ ··· 253 215 254 216 case TYPE_S3C2440: 255 217 case TYPE_S3C2412: 256 - mask = (S3C2410_NFCONF_TACLS(tacls_max - 1) | 257 - S3C2410_NFCONF_TWRPH0(7) | 258 - S3C2410_NFCONF_TWRPH1(7)); 218 + mask = (S3C2440_NFCONF_TACLS(tacls_max - 1) | 219 + S3C2440_NFCONF_TWRPH0(7) | 220 + S3C2440_NFCONF_TWRPH1(7)); 259 221 260 222 set = S3C2440_NFCONF_TACLS(tacls - 1); 261 223 set |= S3C2440_NFCONF_TWRPH0(twrph0 - 1); ··· 263 225 break; 264 226 265 227 default: 266 - /* keep compiler happy */ 267 - mask = 0; 268 - set = 0; 269 228 BUG(); 270 229 } 271 - 272 - dev_dbg(info->device, "NF_CONF is 0x%lx\n", cfg); 273 230 274 231 local_irq_save(flags); 275 232 ··· 275 242 276 243 local_irq_restore(flags); 277 244 245 + dev_dbg(info->device, "NF_CONF is 0x%lx\n", cfg); 246 + 278 247 return 0; 279 248 } 280 249 250 + /** 251 + * s3c2410_nand_inithw - basic hardware initialisation 252 + * @info: The hardware state. 253 + * 254 + * Do the basic initialisation of the hardware, using s3c2410_nand_setrate() 255 + * to setup the hardware access speeds and set the controller to be enabled. 256 + */ 281 257 static int s3c2410_nand_inithw(struct s3c2410_nand_info *info) 282 258 { 283 259 int ret; ··· 310 268 return 0; 311 269 } 312 270 313 - /* select chip */ 314 - 271 + /** 272 + * s3c2410_nand_select_chip - select the given nand chip 273 + * @mtd: The MTD instance for this chip. 274 + * @chip: The chip number. 275 + * 276 + * This is called by the MTD layer to either select a given chip for the 277 + * @mtd instance, or to indicate that the access has finished and the 278 + * chip can be de-selected. 279 + * 280 + * The routine ensures that the nFCE line is correctly setup, and any 281 + * platform specific selection code is called to route nFCE to the specific 282 + * chip. 283 + */ 315 284 static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) 316 285 { 317 286 struct s3c2410_nand_info *info; ··· 583 530 static void s3c2440_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) 584 531 { 585 532 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 586 - readsl(info->regs + S3C2440_NFDATA, buf, len / 4); 533 + 534 + readsl(info->regs + S3C2440_NFDATA, buf, len >> 2); 535 + 536 + /* cleanup if we've got less than a word to do */ 537 + if (len & 3) { 538 + buf += len & ~3; 539 + 540 + for (; len & 3; len--) 541 + *buf++ = readb(info->regs + S3C2440_NFDATA); 542 + } 587 543 } 588 544 589 545 static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) ··· 604 542 static void s3c2440_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) 605 543 { 606 544 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 607 - writesl(info->regs + S3C2440_NFDATA, buf, len / 4); 545 + 546 + writesl(info->regs + S3C2440_NFDATA, buf, len >> 2); 547 + 548 + /* cleanup any fractional write */ 549 + if (len & 3) { 550 + buf += len & ~3; 551 + 552 + for (; len & 3; len--, buf++) 553 + writeb(*buf, info->regs + S3C2440_NFDATA); 554 + } 608 555 } 609 556 610 557 /* cpufreq driver support */ ··· 664 593 665 594 /* device management functions */ 666 595 667 - static int s3c2410_nand_remove(struct platform_device *pdev) 596 + static int s3c24xx_nand_remove(struct platform_device *pdev) 668 597 { 669 598 struct s3c2410_nand_info *info = to_nand_info(pdev); 670 599 ··· 716 645 } 717 646 718 647 #ifdef CONFIG_MTD_PARTITIONS 648 + const char *part_probes[] = { "cmdlinepart", NULL }; 719 649 static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, 720 650 struct s3c2410_nand_mtd *mtd, 721 651 struct s3c2410_nand_set *set) 722 652 { 653 + struct mtd_partition *part_info; 654 + int nr_part = 0; 655 + 723 656 if (set == NULL) 724 657 return add_mtd_device(&mtd->mtd); 725 658 726 - if (set->nr_partitions > 0 && set->partitions != NULL) { 727 - return add_mtd_partitions(&mtd->mtd, set->partitions, set->nr_partitions); 659 + if (set->nr_partitions == 0) { 660 + mtd->mtd.name = set->name; 661 + nr_part = parse_mtd_partitions(&mtd->mtd, part_probes, 662 + &part_info, 0); 663 + } else { 664 + if (set->nr_partitions > 0 && set->partitions != NULL) { 665 + nr_part = set->nr_partitions; 666 + part_info = set->partitions; 667 + } 728 668 } 669 + 670 + if (nr_part > 0 && part_info) 671 + return add_mtd_partitions(&mtd->mtd, part_info, nr_part); 729 672 730 673 return add_mtd_device(&mtd->mtd); 731 674 } ··· 752 667 } 753 668 #endif 754 669 755 - /* s3c2410_nand_init_chip 670 + /** 671 + * s3c2410_nand_init_chip - initialise a single instance of an chip 672 + * @info: The base NAND controller the chip is on. 673 + * @nmtd: The new controller MTD instance to fill in. 674 + * @set: The information passed from the board specific platform data. 756 675 * 757 - * init a single instance of an chip 758 - */ 759 - 676 + * Initialise the given @nmtd from the information in @info and @set. This 677 + * readies the structure for use with the MTD layer functions by ensuring 678 + * all pointers are setup and the necessary control routines selected. 679 + */ 760 680 static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, 761 681 struct s3c2410_nand_mtd *nmtd, 762 682 struct s3c2410_nand_set *set) ··· 847 757 848 758 if (set->disable_ecc) 849 759 chip->ecc.mode = NAND_ECC_NONE; 760 + 761 + switch (chip->ecc.mode) { 762 + case NAND_ECC_NONE: 763 + dev_info(info->device, "NAND ECC disabled\n"); 764 + break; 765 + case NAND_ECC_SOFT: 766 + dev_info(info->device, "NAND soft ECC\n"); 767 + break; 768 + case NAND_ECC_HW: 769 + dev_info(info->device, "NAND hardware ECC\n"); 770 + break; 771 + default: 772 + dev_info(info->device, "NAND ECC UNKNOWN\n"); 773 + break; 774 + } 775 + 776 + /* If you use u-boot BBT creation code, specifying this flag will 777 + * let the kernel fish out the BBT from the NAND, and also skip the 778 + * full NAND scan that can take 1/2s or so. Little things... */ 779 + if (set->flash_bbt) 780 + chip->options |= NAND_USE_FLASH_BBT | NAND_SKIP_BBTSCAN; 850 781 } 851 782 852 - /* s3c2410_nand_update_chip 783 + /** 784 + * s3c2410_nand_update_chip - post probe update 785 + * @info: The controller instance. 786 + * @nmtd: The driver version of the MTD instance. 853 787 * 854 - * post-probe chip update, to change any items, such as the 855 - * layout for large page nand 856 - */ 857 - 788 + * This routine is called after the chip probe has succesfully completed 789 + * and the relevant per-chip information updated. This call ensure that 790 + * we update the internal state accordingly. 791 + * 792 + * The internal state is currently limited to the ECC state information. 793 + */ 858 794 static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info, 859 795 struct s3c2410_nand_mtd *nmtd) 860 796 { ··· 889 773 dev_dbg(info->device, "chip %p => page shift %d\n", 890 774 chip, chip->page_shift); 891 775 892 - if (hardware_ecc) { 776 + if (chip->ecc.mode != NAND_ECC_HW) 777 + return; 778 + 893 779 /* change the behaviour depending on wether we are using 894 780 * the large or small page nand device */ 895 781 896 - if (chip->page_shift > 10) { 897 - chip->ecc.size = 256; 898 - chip->ecc.bytes = 3; 899 - } else { 900 - chip->ecc.size = 512; 901 - chip->ecc.bytes = 3; 902 - chip->ecc.layout = &nand_hw_eccoob; 903 - } 782 + if (chip->page_shift > 10) { 783 + chip->ecc.size = 256; 784 + chip->ecc.bytes = 3; 785 + } else { 786 + chip->ecc.size = 512; 787 + chip->ecc.bytes = 3; 788 + chip->ecc.layout = &nand_hw_eccoob; 904 789 } 905 790 } 906 791 907 - /* s3c2410_nand_probe 792 + /* s3c24xx_nand_probe 908 793 * 909 794 * called by device layer when it finds a device matching 910 795 * one our driver can handled. This code checks to see if 911 796 * it can allocate all necessary resources then calls the 912 797 * nand layer to look for devices 913 798 */ 914 - 915 - static int s3c24xx_nand_probe(struct platform_device *pdev, 916 - enum s3c_cpu_type cpu_type) 799 + static int s3c24xx_nand_probe(struct platform_device *pdev) 917 800 { 918 801 struct s3c2410_platform_nand *plat = to_nand_plat(pdev); 802 + enum s3c_cpu_type cpu_type; 919 803 struct s3c2410_nand_info *info; 920 804 struct s3c2410_nand_mtd *nmtd; 921 805 struct s3c2410_nand_set *sets; ··· 924 808 int size; 925 809 int nr_sets; 926 810 int setno; 811 + 812 + cpu_type = platform_get_device_id(pdev)->driver_data; 927 813 928 814 pr_debug("s3c2410_nand_probe(%p)\n", pdev); 929 815 ··· 1040 922 return 0; 1041 923 1042 924 exit_error: 1043 - s3c2410_nand_remove(pdev); 925 + s3c24xx_nand_remove(pdev); 1044 926 1045 927 if (err == 0) 1046 928 err = -EINVAL; ··· 1101 983 1102 984 /* driver device registration */ 1103 985 1104 - static int s3c2410_nand_probe(struct platform_device *dev) 1105 - { 1106 - return s3c24xx_nand_probe(dev, TYPE_S3C2410); 1107 - } 1108 - 1109 - static int s3c2440_nand_probe(struct platform_device *dev) 1110 - { 1111 - return s3c24xx_nand_probe(dev, TYPE_S3C2440); 1112 - } 1113 - 1114 - static int s3c2412_nand_probe(struct platform_device *dev) 1115 - { 1116 - return s3c24xx_nand_probe(dev, TYPE_S3C2412); 1117 - } 1118 - 1119 - static struct platform_driver s3c2410_nand_driver = { 1120 - .probe = s3c2410_nand_probe, 1121 - .remove = s3c2410_nand_remove, 1122 - .suspend = s3c24xx_nand_suspend, 1123 - .resume = s3c24xx_nand_resume, 1124 - .driver = { 1125 - .name = "s3c2410-nand", 1126 - .owner = THIS_MODULE, 986 + static struct platform_device_id s3c24xx_driver_ids[] = { 987 + { 988 + .name = "s3c2410-nand", 989 + .driver_data = TYPE_S3C2410, 990 + }, { 991 + .name = "s3c2440-nand", 992 + .driver_data = TYPE_S3C2440, 993 + }, { 994 + .name = "s3c2412-nand", 995 + .driver_data = TYPE_S3C2412, 996 + }, { 997 + .name = "s3c6400-nand", 998 + .driver_data = TYPE_S3C2412, /* compatible with 2412 */ 1127 999 }, 1000 + { } 1128 1001 }; 1129 1002 1130 - static struct platform_driver s3c2440_nand_driver = { 1131 - .probe = s3c2440_nand_probe, 1132 - .remove = s3c2410_nand_remove, 1133 - .suspend = s3c24xx_nand_suspend, 1134 - .resume = s3c24xx_nand_resume, 1135 - .driver = { 1136 - .name = "s3c2440-nand", 1137 - .owner = THIS_MODULE, 1138 - }, 1139 - }; 1003 + MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids); 1140 1004 1141 - static struct platform_driver s3c2412_nand_driver = { 1142 - .probe = s3c2412_nand_probe, 1143 - .remove = s3c2410_nand_remove, 1005 + static struct platform_driver s3c24xx_nand_driver = { 1006 + .probe = s3c24xx_nand_probe, 1007 + .remove = s3c24xx_nand_remove, 1144 1008 .suspend = s3c24xx_nand_suspend, 1145 1009 .resume = s3c24xx_nand_resume, 1010 + .id_table = s3c24xx_driver_ids, 1146 1011 .driver = { 1147 - .name = "s3c2412-nand", 1012 + .name = "s3c24xx-nand", 1148 1013 .owner = THIS_MODULE, 1149 1014 }, 1150 1015 }; ··· 1136 1035 { 1137 1036 printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n"); 1138 1037 1139 - platform_driver_register(&s3c2412_nand_driver); 1140 - platform_driver_register(&s3c2440_nand_driver); 1141 - return platform_driver_register(&s3c2410_nand_driver); 1038 + return platform_driver_register(&s3c24xx_nand_driver); 1142 1039 } 1143 1040 1144 1041 static void __exit s3c2410_nand_exit(void) 1145 1042 { 1146 - platform_driver_unregister(&s3c2412_nand_driver); 1147 - platform_driver_unregister(&s3c2440_nand_driver); 1148 - platform_driver_unregister(&s3c2410_nand_driver); 1043 + platform_driver_unregister(&s3c24xx_nand_driver); 1149 1044 } 1150 1045 1151 1046 module_init(s3c2410_nand_init); ··· 1150 1053 MODULE_LICENSE("GPL"); 1151 1054 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 1152 1055 MODULE_DESCRIPTION("S3C24XX MTD NAND driver"); 1153 - MODULE_ALIAS("platform:s3c2410-nand"); 1154 - MODULE_ALIAS("platform:s3c2412-nand"); 1155 - MODULE_ALIAS("platform:s3c2440-nand");
+12 -4
drivers/mtd/nand/txx9ndfmc.c
··· 64 64 struct nand_chip chip; 65 65 struct mtd_info mtd; 66 66 int cs; 67 - char mtdname[BUS_ID_SIZE + 2]; 67 + const char *mtdname; 68 68 }; 69 69 70 70 #define MAX_TXX9NDFMC_DEV 4 ··· 334 334 335 335 if (plat->ch_mask != 1) { 336 336 txx9_priv->cs = i; 337 - sprintf(txx9_priv->mtdname, "%s.%u", 338 - dev_name(&dev->dev), i); 337 + txx9_priv->mtdname = kasprintf(GFP_KERNEL, "%s.%u", 338 + dev_name(&dev->dev), i); 339 339 } else { 340 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 349 if (plat->wide_mask & (1 << i)) 344 350 chip->options |= NAND_BUSWIDTH_16; 345 351 346 352 if (nand_scan(mtd, 1)) { 353 + kfree(txx9_priv->mtdname); 347 354 kfree(txx9_priv); 348 355 continue; 349 356 } ··· 392 385 kfree(drvdata->parts[i]); 393 386 #endif 394 387 del_mtd_device(mtd); 388 + kfree(txx9_priv->mtdname); 395 389 kfree(txx9_priv); 396 390 } 397 391 return 0;
+2 -2
drivers/mtd/onenand/omap2.c
··· 565 565 NULL, __adjust_timing); 566 566 } 567 567 568 - static void __devexit omap2_onenand_shutdown(struct platform_device *pdev) 568 + static void omap2_onenand_shutdown(struct platform_device *pdev) 569 569 { 570 570 struct omap2_onenand *c = dev_get_drvdata(&pdev->dev); 571 571 ··· 777 777 778 778 static struct platform_driver omap2_onenand_driver = { 779 779 .probe = omap2_onenand_probe, 780 - .remove = omap2_onenand_remove, 780 + .remove = __devexit_p(omap2_onenand_remove), 781 781 .shutdown = omap2_onenand_shutdown, 782 782 .driver = { 783 783 .name = DRIVER_NAME,
+789 -81
drivers/mtd/onenand/onenand_base.c
··· 9 9 * auto-placement support, read-while load support, various fixes 10 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 16 * This program is free software; you can redistribute it and/or modify 13 17 * it under the terms of the GNU General Public License version 2 as 14 18 * published by the Free Software Foundation. ··· 20 16 21 17 #include <linux/kernel.h> 22 18 #include <linux/module.h> 19 + #include <linux/moduleparam.h> 23 20 #include <linux/init.h> 24 21 #include <linux/sched.h> 25 22 #include <linux/delay.h> ··· 31 26 #include <linux/mtd/partitions.h> 32 27 33 28 #include <asm/io.h> 29 + 30 + /* Default Flex-OneNAND boundary and lock respectively */ 31 + static int flex_bdry[MAX_DIES * 2] = { -1, 0, -1, 0 }; 32 + 33 + module_param_array(flex_bdry, int, NULL, 0400); 34 + MODULE_PARM_DESC(flex_bdry, "SLC Boundary information for Flex-OneNAND" 35 + "Syntax:flex_bdry=DIE_BDRY,LOCK,..." 36 + "DIE_BDRY: SLC boundary of the die" 37 + "LOCK: Locking information for SLC boundary" 38 + " : 0->Set boundary in unlocked status" 39 + " : 1->Set boundary in locked status"); 40 + 41 + /** 42 + * onenand_oob_128 - oob info for Flex-Onenand with 4KB page 43 + * For now, we expose only 64 out of 80 ecc bytes 44 + */ 45 + static struct nand_ecclayout onenand_oob_128 = { 46 + .eccbytes = 64, 47 + .eccpos = { 48 + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 49 + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 50 + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 51 + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 52 + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 53 + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 54 + 102, 103, 104, 105 55 + }, 56 + .oobfree = { 57 + {2, 4}, {18, 4}, {34, 4}, {50, 4}, 58 + {66, 4}, {82, 4}, {98, 4}, {114, 4} 59 + } 60 + }; 34 61 35 62 /** 36 63 * onenand_oob_64 - oob info for large (2KB) page ··· 102 65 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */ 103 66 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 104 67 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */ 68 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 69 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 80 */ 70 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 71 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 96 */ 72 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 73 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 112 */ 74 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 75 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 128 */ 105 76 }; 106 77 107 78 /** ··· 216 171 } 217 172 218 173 /** 174 + * flexonenand_block- For given address return block number 175 + * @param this - OneNAND device structure 176 + * @param addr - Address for which block number is needed 177 + */ 178 + static unsigned flexonenand_block(struct onenand_chip *this, loff_t addr) 179 + { 180 + unsigned boundary, blk, die = 0; 181 + 182 + if (ONENAND_IS_DDP(this) && addr >= this->diesize[0]) { 183 + die = 1; 184 + addr -= this->diesize[0]; 185 + } 186 + 187 + boundary = this->boundary[die]; 188 + 189 + blk = addr >> (this->erase_shift - 1); 190 + if (blk > boundary) 191 + blk = (blk + boundary + 1) >> 1; 192 + 193 + blk += die ? this->density_mask : 0; 194 + return blk; 195 + } 196 + 197 + inline unsigned onenand_block(struct onenand_chip *this, loff_t addr) 198 + { 199 + if (!FLEXONENAND(this)) 200 + return addr >> this->erase_shift; 201 + return flexonenand_block(this, addr); 202 + } 203 + 204 + /** 205 + * flexonenand_addr - Return address of the block 206 + * @this: OneNAND device structure 207 + * @block: Block number on Flex-OneNAND 208 + * 209 + * Return address of the block 210 + */ 211 + static loff_t flexonenand_addr(struct onenand_chip *this, int block) 212 + { 213 + loff_t ofs = 0; 214 + int die = 0, boundary; 215 + 216 + if (ONENAND_IS_DDP(this) && block >= this->density_mask) { 217 + block -= this->density_mask; 218 + die = 1; 219 + ofs = this->diesize[0]; 220 + } 221 + 222 + boundary = this->boundary[die]; 223 + ofs += (loff_t)block << (this->erase_shift - 1); 224 + if (block > (boundary + 1)) 225 + ofs += (loff_t)(block - boundary - 1) << (this->erase_shift - 1); 226 + return ofs; 227 + } 228 + 229 + loff_t onenand_addr(struct onenand_chip *this, int block) 230 + { 231 + if (!FLEXONENAND(this)) 232 + return (loff_t)block << this->erase_shift; 233 + return flexonenand_addr(this, block); 234 + } 235 + EXPORT_SYMBOL(onenand_addr); 236 + 237 + /** 219 238 * onenand_get_density - [DEFAULT] Get OneNAND density 220 239 * @param dev_id OneNAND device ID 221 240 * ··· 290 181 int density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT; 291 182 return (density & ONENAND_DEVICE_DENSITY_MASK); 292 183 } 184 + 185 + /** 186 + * flexonenand_region - [Flex-OneNAND] Return erase region of addr 187 + * @param mtd MTD device structure 188 + * @param addr address whose erase region needs to be identified 189 + */ 190 + int flexonenand_region(struct mtd_info *mtd, loff_t addr) 191 + { 192 + int i; 193 + 194 + for (i = 0; i < mtd->numeraseregions; i++) 195 + if (addr < mtd->eraseregions[i].offset) 196 + break; 197 + return i - 1; 198 + } 199 + EXPORT_SYMBOL(flexonenand_region); 293 200 294 201 /** 295 202 * onenand_command - [DEFAULT] Send command to OneNAND device ··· 332 207 page = -1; 333 208 break; 334 209 335 - case ONENAND_CMD_ERASE: 336 - case ONENAND_CMD_BUFFERRAM: 337 - case ONENAND_CMD_OTP_ACCESS: 338 - block = (int) (addr >> this->erase_shift); 210 + case FLEXONENAND_CMD_PI_ACCESS: 211 + /* addr contains die index */ 212 + block = addr * this->density_mask; 339 213 page = -1; 340 214 break; 341 215 216 + case ONENAND_CMD_ERASE: 217 + case ONENAND_CMD_BUFFERRAM: 218 + case ONENAND_CMD_OTP_ACCESS: 219 + block = onenand_block(this, addr); 220 + page = -1; 221 + break; 222 + 223 + case FLEXONENAND_CMD_READ_PI: 224 + cmd = ONENAND_CMD_READ; 225 + block = addr * this->density_mask; 226 + page = 0; 227 + break; 228 + 342 229 default: 343 - block = (int) (addr >> this->erase_shift); 344 - page = (int) (addr >> this->page_shift); 230 + block = onenand_block(this, addr); 231 + page = (int) (addr - onenand_addr(this, block)) >> this->page_shift; 345 232 346 233 if (ONENAND_IS_2PLANE(this)) { 347 234 /* Make the even block number */ ··· 373 236 value = onenand_bufferram_address(this, block); 374 237 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); 375 238 376 - if (ONENAND_IS_2PLANE(this)) 239 + if (ONENAND_IS_MLC(this) || ONENAND_IS_2PLANE(this)) 377 240 /* It is always BufferRAM0 */ 378 241 ONENAND_SET_BUFFERRAM0(this); 379 242 else ··· 395 258 396 259 if (page != -1) { 397 260 /* Now we use page size operation */ 398 - int sectors = 4, count = 4; 261 + int sectors = 0, count = 0; 399 262 int dataram; 400 263 401 264 switch (cmd) { 265 + case FLEXONENAND_CMD_RECOVER_LSB: 402 266 case ONENAND_CMD_READ: 403 267 case ONENAND_CMD_READOOB: 404 - dataram = ONENAND_SET_NEXT_BUFFERRAM(this); 268 + if (ONENAND_IS_MLC(this)) 269 + /* It is always BufferRAM0 */ 270 + dataram = ONENAND_SET_BUFFERRAM0(this); 271 + else 272 + dataram = ONENAND_SET_NEXT_BUFFERRAM(this); 405 273 break; 406 274 407 275 default: ··· 432 290 this->write_word(cmd, this->base + ONENAND_REG_COMMAND); 433 291 434 292 return 0; 293 + } 294 + 295 + /** 296 + * onenand_read_ecc - return ecc status 297 + * @param this onenand chip structure 298 + */ 299 + static inline int onenand_read_ecc(struct onenand_chip *this) 300 + { 301 + int ecc, i, result = 0; 302 + 303 + if (!FLEXONENAND(this)) 304 + return this->read_word(this->base + ONENAND_REG_ECC_STATUS); 305 + 306 + for (i = 0; i < 4; i++) { 307 + ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS + i); 308 + if (likely(!ecc)) 309 + continue; 310 + if (ecc & FLEXONENAND_UNCORRECTABLE_ERROR) 311 + return ONENAND_ECC_2BIT_ALL; 312 + else 313 + result = ONENAND_ECC_1BIT_ALL; 314 + } 315 + 316 + return result; 435 317 } 436 318 437 319 /** ··· 497 331 * power off recovery (POR) test, it should read ECC status first 498 332 */ 499 333 if (interrupt & ONENAND_INT_READ) { 500 - int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); 334 + int ecc = onenand_read_ecc(this); 501 335 if (ecc) { 502 336 if (ecc & ONENAND_ECC_2BIT_ALL) { 503 337 printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc); 504 338 mtd->ecc_stats.failed++; 505 339 return -EBADMSG; 506 340 } else if (ecc & ONENAND_ECC_1BIT_ALL) { 507 - printk(KERN_INFO "onenand_wait: correctable ECC error = 0x%04x\n", ecc); 341 + printk(KERN_DEBUG "onenand_wait: correctable ECC error = 0x%04x\n", ecc); 508 342 mtd->ecc_stats.corrected++; 509 343 } 510 344 } ··· 822 656 823 657 if (found && ONENAND_IS_DDP(this)) { 824 658 /* Select DataRAM for DDP */ 825 - int block = (int) (addr >> this->erase_shift); 659 + int block = onenand_block(this, addr); 826 660 int value = onenand_bufferram_address(this, block); 827 661 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); 828 662 } ··· 982 816 } 983 817 984 818 /** 819 + * onenand_recover_lsb - [Flex-OneNAND] Recover LSB page data 820 + * @param mtd MTD device structure 821 + * @param addr address to recover 822 + * @param status return value from onenand_wait / onenand_bbt_wait 823 + * 824 + * MLC NAND Flash cell has paired pages - LSB page and MSB page. LSB page has 825 + * lower page address and MSB page has higher page address in paired pages. 826 + * If power off occurs during MSB page program, the paired LSB page data can 827 + * become corrupt. LSB page recovery read is a way to read LSB page though page 828 + * data are corrupted. When uncorrectable error occurs as a result of LSB page 829 + * read after power up, issue LSB page recovery read. 830 + */ 831 + static int onenand_recover_lsb(struct mtd_info *mtd, loff_t addr, int status) 832 + { 833 + struct onenand_chip *this = mtd->priv; 834 + int i; 835 + 836 + /* Recovery is only for Flex-OneNAND */ 837 + if (!FLEXONENAND(this)) 838 + return status; 839 + 840 + /* check if we failed due to uncorrectable error */ 841 + if (status != -EBADMSG && status != ONENAND_BBT_READ_ECC_ERROR) 842 + return status; 843 + 844 + /* check if address lies in MLC region */ 845 + i = flexonenand_region(mtd, addr); 846 + if (mtd->eraseregions[i].erasesize < (1 << this->erase_shift)) 847 + return status; 848 + 849 + /* We are attempting to reread, so decrement stats.failed 850 + * which was incremented by onenand_wait due to read failure 851 + */ 852 + printk(KERN_INFO "onenand_recover_lsb: Attempting to recover from uncorrectable read\n"); 853 + mtd->ecc_stats.failed--; 854 + 855 + /* Issue the LSB page recovery command */ 856 + this->command(mtd, FLEXONENAND_CMD_RECOVER_LSB, addr, this->writesize); 857 + return this->wait(mtd, FL_READING); 858 + } 859 + 860 + /** 861 + * onenand_mlc_read_ops_nolock - MLC OneNAND read main and/or out-of-band 862 + * @param mtd MTD device structure 863 + * @param from offset to read from 864 + * @param ops: oob operation description structure 865 + * 866 + * MLC OneNAND / Flex-OneNAND has 4KB page size and 4KB dataram. 867 + * So, read-while-load is not present. 868 + */ 869 + static int onenand_mlc_read_ops_nolock(struct mtd_info *mtd, loff_t from, 870 + struct mtd_oob_ops *ops) 871 + { 872 + struct onenand_chip *this = mtd->priv; 873 + struct mtd_ecc_stats stats; 874 + size_t len = ops->len; 875 + size_t ooblen = ops->ooblen; 876 + u_char *buf = ops->datbuf; 877 + u_char *oobbuf = ops->oobbuf; 878 + int read = 0, column, thislen; 879 + int oobread = 0, oobcolumn, thisooblen, oobsize; 880 + int ret = 0; 881 + int writesize = this->writesize; 882 + 883 + DEBUG(MTD_DEBUG_LEVEL3, "onenand_mlc_read_ops_nolock: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); 884 + 885 + if (ops->mode == MTD_OOB_AUTO) 886 + oobsize = this->ecclayout->oobavail; 887 + else 888 + oobsize = mtd->oobsize; 889 + 890 + oobcolumn = from & (mtd->oobsize - 1); 891 + 892 + /* Do not allow reads past end of device */ 893 + if (from + len > mtd->size) { 894 + printk(KERN_ERR "onenand_mlc_read_ops_nolock: Attempt read beyond end of device\n"); 895 + ops->retlen = 0; 896 + ops->oobretlen = 0; 897 + return -EINVAL; 898 + } 899 + 900 + stats = mtd->ecc_stats; 901 + 902 + while (read < len) { 903 + cond_resched(); 904 + 905 + thislen = min_t(int, writesize, len - read); 906 + 907 + column = from & (writesize - 1); 908 + if (column + thislen > writesize) 909 + thislen = writesize - column; 910 + 911 + if (!onenand_check_bufferram(mtd, from)) { 912 + this->command(mtd, ONENAND_CMD_READ, from, writesize); 913 + 914 + ret = this->wait(mtd, FL_READING); 915 + if (unlikely(ret)) 916 + ret = onenand_recover_lsb(mtd, from, ret); 917 + onenand_update_bufferram(mtd, from, !ret); 918 + if (ret == -EBADMSG) 919 + ret = 0; 920 + } 921 + 922 + this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen); 923 + if (oobbuf) { 924 + thisooblen = oobsize - oobcolumn; 925 + thisooblen = min_t(int, thisooblen, ooblen - oobread); 926 + 927 + if (ops->mode == MTD_OOB_AUTO) 928 + onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen); 929 + else 930 + this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen); 931 + oobread += thisooblen; 932 + oobbuf += thisooblen; 933 + oobcolumn = 0; 934 + } 935 + 936 + read += thislen; 937 + if (read == len) 938 + break; 939 + 940 + from += thislen; 941 + buf += thislen; 942 + } 943 + 944 + /* 945 + * Return success, if no ECC failures, else -EBADMSG 946 + * fs driver will take care of that, because 947 + * retlen == desired len and result == -EBADMSG 948 + */ 949 + ops->retlen = read; 950 + ops->oobretlen = oobread; 951 + 952 + if (ret) 953 + return ret; 954 + 955 + if (mtd->ecc_stats.failed - stats.failed) 956 + return -EBADMSG; 957 + 958 + return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0; 959 + } 960 + 961 + /** 985 962 * onenand_read_ops_nolock - [OneNAND Interface] OneNAND read main and/or out-of-band 986 963 * @param mtd MTD device structure 987 964 * @param from offset to read from ··· 1271 962 size_t len = ops->ooblen; 1272 963 mtd_oob_mode_t mode = ops->mode; 1273 964 u_char *buf = ops->oobbuf; 1274 - int ret = 0; 965 + int ret = 0, readcmd; 1275 966 1276 967 from += ops->ooboffs; 1277 968 ··· 1302 993 1303 994 stats = mtd->ecc_stats; 1304 995 996 + readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB; 997 + 1305 998 while (read < len) { 1306 999 cond_resched(); 1307 1000 1308 1001 thislen = oobsize - column; 1309 1002 thislen = min_t(int, thislen, len); 1310 1003 1311 - this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize); 1004 + this->command(mtd, readcmd, from, mtd->oobsize); 1312 1005 1313 1006 onenand_update_bufferram(mtd, from, 0); 1314 1007 1315 1008 ret = this->wait(mtd, FL_READING); 1009 + if (unlikely(ret)) 1010 + ret = onenand_recover_lsb(mtd, from, ret); 1011 + 1316 1012 if (ret && ret != -EBADMSG) { 1317 1013 printk(KERN_ERR "onenand_read_oob_nolock: read failed = 0x%x\n", ret); 1318 1014 break; ··· 1367 1053 static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len, 1368 1054 size_t *retlen, u_char *buf) 1369 1055 { 1056 + struct onenand_chip *this = mtd->priv; 1370 1057 struct mtd_oob_ops ops = { 1371 1058 .len = len, 1372 1059 .ooblen = 0, ··· 1377 1062 int ret; 1378 1063 1379 1064 onenand_get_device(mtd, FL_READING); 1380 - ret = onenand_read_ops_nolock(mtd, from, &ops); 1065 + ret = ONENAND_IS_MLC(this) ? 1066 + onenand_mlc_read_ops_nolock(mtd, from, &ops) : 1067 + onenand_read_ops_nolock(mtd, from, &ops); 1381 1068 onenand_release_device(mtd); 1382 1069 1383 1070 *retlen = ops.retlen; ··· 1397 1080 static int onenand_read_oob(struct mtd_info *mtd, loff_t from, 1398 1081 struct mtd_oob_ops *ops) 1399 1082 { 1083 + struct onenand_chip *this = mtd->priv; 1400 1084 int ret; 1401 1085 1402 1086 switch (ops->mode) { ··· 1412 1094 1413 1095 onenand_get_device(mtd, FL_READING); 1414 1096 if (ops->datbuf) 1415 - ret = onenand_read_ops_nolock(mtd, from, ops); 1097 + ret = ONENAND_IS_MLC(this) ? 1098 + onenand_mlc_read_ops_nolock(mtd, from, ops) : 1099 + onenand_read_ops_nolock(mtd, from, ops); 1416 1100 else 1417 1101 ret = onenand_read_oob_nolock(mtd, from, ops); 1418 1102 onenand_release_device(mtd); ··· 1448 1128 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); 1449 1129 1450 1130 if (interrupt & ONENAND_INT_READ) { 1451 - int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); 1131 + int ecc = onenand_read_ecc(this); 1452 1132 if (ecc & ONENAND_ECC_2BIT_ALL) { 1453 1133 printk(KERN_INFO "onenand_bbt_wait: ecc error = 0x%04x" 1454 1134 ", controller error 0x%04x\n", ecc, ctrl); 1455 - return ONENAND_BBT_READ_ERROR; 1135 + return ONENAND_BBT_READ_ECC_ERROR; 1456 1136 } 1457 1137 } else { 1458 1138 printk(KERN_ERR "onenand_bbt_wait: read timeout!" ··· 1483 1163 { 1484 1164 struct onenand_chip *this = mtd->priv; 1485 1165 int read = 0, thislen, column; 1486 - int ret = 0; 1166 + int ret = 0, readcmd; 1487 1167 size_t len = ops->ooblen; 1488 1168 u_char *buf = ops->oobbuf; 1489 1169 ··· 1503 1183 1504 1184 column = from & (mtd->oobsize - 1); 1505 1185 1186 + readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB; 1187 + 1506 1188 while (read < len) { 1507 1189 cond_resched(); 1508 1190 1509 1191 thislen = mtd->oobsize - column; 1510 1192 thislen = min_t(int, thislen, len); 1511 1193 1512 - this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize); 1194 + this->command(mtd, readcmd, from, mtd->oobsize); 1513 1195 1514 1196 onenand_update_bufferram(mtd, from, 0); 1515 1197 1516 - ret = onenand_bbt_wait(mtd, FL_READING); 1198 + ret = this->bbt_wait(mtd, FL_READING); 1199 + if (unlikely(ret)) 1200 + ret = onenand_recover_lsb(mtd, from, ret); 1201 + 1517 1202 if (ret) 1518 1203 break; 1519 1204 ··· 1555 1230 { 1556 1231 struct onenand_chip *this = mtd->priv; 1557 1232 u_char *oob_buf = this->oob_buf; 1558 - int status, i; 1233 + int status, i, readcmd; 1559 1234 1560 - this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize); 1235 + readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB; 1236 + 1237 + this->command(mtd, readcmd, to, mtd->oobsize); 1561 1238 onenand_update_bufferram(mtd, to, 0); 1562 1239 status = this->wait(mtd, FL_READING); 1563 1240 if (status) ··· 1960 1633 { 1961 1634 struct onenand_chip *this = mtd->priv; 1962 1635 int column, ret = 0, oobsize; 1963 - int written = 0; 1636 + int written = 0, oobcmd; 1964 1637 u_char *oobbuf; 1965 1638 size_t len = ops->ooblen; 1966 1639 const u_char *buf = ops->oobbuf; ··· 2002 1675 2003 1676 oobbuf = this->oob_buf; 2004 1677 1678 + oobcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB; 1679 + 2005 1680 /* Loop until all data write */ 2006 1681 while (written < len) { 2007 1682 int thislen = min_t(int, oobsize, len - written); ··· 2021 1692 memcpy(oobbuf + column, buf, thislen); 2022 1693 this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize); 2023 1694 2024 - this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize); 1695 + if (ONENAND_IS_MLC(this)) { 1696 + /* Set main area of DataRAM to 0xff*/ 1697 + memset(this->page_buf, 0xff, mtd->writesize); 1698 + this->write_bufferram(mtd, ONENAND_DATARAM, 1699 + this->page_buf, 0, mtd->writesize); 1700 + } 1701 + 1702 + this->command(mtd, oobcmd, to, mtd->oobsize); 2025 1703 2026 1704 onenand_update_bufferram(mtd, to, 0); 2027 1705 if (ONENAND_IS_2PLANE(this)) { ··· 2151 1815 { 2152 1816 struct onenand_chip *this = mtd->priv; 2153 1817 unsigned int block_size; 2154 - loff_t addr; 2155 - int len; 2156 - int ret = 0; 1818 + loff_t addr = instr->addr; 1819 + loff_t len = instr->len; 1820 + int ret = 0, i; 1821 + struct mtd_erase_region_info *region = NULL; 1822 + loff_t region_end = 0; 2157 1823 2158 1824 DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%012llx, len = %llu\n", (unsigned long long) instr->addr, (unsigned long long) instr->len); 2159 1825 2160 - block_size = (1 << this->erase_shift); 2161 - 2162 - /* Start address must align on block boundary */ 2163 - if (unlikely(instr->addr & (block_size - 1))) { 2164 - printk(KERN_ERR "onenand_erase: Unaligned address\n"); 1826 + /* Do not allow erase past end of device */ 1827 + if (unlikely((len + addr) > mtd->size)) { 1828 + printk(KERN_ERR "onenand_erase: Erase past end of device\n"); 2165 1829 return -EINVAL; 1830 + } 1831 + 1832 + if (FLEXONENAND(this)) { 1833 + /* Find the eraseregion of this address */ 1834 + i = flexonenand_region(mtd, addr); 1835 + region = &mtd->eraseregions[i]; 1836 + 1837 + block_size = region->erasesize; 1838 + region_end = region->offset + region->erasesize * region->numblocks; 1839 + 1840 + /* Start address within region must align on block boundary. 1841 + * Erase region's start offset is always block start address. 1842 + */ 1843 + if (unlikely((addr - region->offset) & (block_size - 1))) { 1844 + printk(KERN_ERR "onenand_erase: Unaligned address\n"); 1845 + return -EINVAL; 1846 + } 1847 + } else { 1848 + block_size = 1 << this->erase_shift; 1849 + 1850 + /* Start address must align on block boundary */ 1851 + if (unlikely(addr & (block_size - 1))) { 1852 + printk(KERN_ERR "onenand_erase: Unaligned address\n"); 1853 + return -EINVAL; 1854 + } 2166 1855 } 2167 1856 2168 1857 /* Length must align on block boundary */ 2169 - if (unlikely(instr->len & (block_size - 1))) { 1858 + if (unlikely(len & (block_size - 1))) { 2170 1859 printk(KERN_ERR "onenand_erase: Length not block aligned\n"); 2171 - return -EINVAL; 2172 - } 2173 - 2174 - /* Do not allow erase past end of device */ 2175 - if (unlikely((instr->len + instr->addr) > mtd->size)) { 2176 - printk(KERN_ERR "onenand_erase: Erase past end of device\n"); 2177 1860 return -EINVAL; 2178 1861 } 2179 1862 ··· 2202 1847 onenand_get_device(mtd, FL_ERASING); 2203 1848 2204 1849 /* Loop throught the pages */ 2205 - len = instr->len; 2206 - addr = instr->addr; 2207 - 2208 1850 instr->state = MTD_ERASING; 2209 1851 2210 1852 while (len) { ··· 2221 1869 ret = this->wait(mtd, FL_ERASING); 2222 1870 /* Check, if it is write protected */ 2223 1871 if (ret) { 2224 - printk(KERN_ERR "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift)); 1872 + printk(KERN_ERR "onenand_erase: Failed erase, block %d\n", 1873 + onenand_block(this, addr)); 2225 1874 instr->state = MTD_ERASE_FAILED; 2226 1875 instr->fail_addr = addr; 2227 1876 goto erase_exit; ··· 2230 1877 2231 1878 len -= block_size; 2232 1879 addr += block_size; 1880 + 1881 + if (addr == region_end) { 1882 + if (!len) 1883 + break; 1884 + region++; 1885 + 1886 + block_size = region->erasesize; 1887 + region_end = region->offset + region->erasesize * region->numblocks; 1888 + 1889 + if (len & (block_size - 1)) { 1890 + /* FIXME: This should be handled at MTD partitioning level. */ 1891 + printk(KERN_ERR "onenand_erase: Unaligned address\n"); 1892 + goto erase_exit; 1893 + } 1894 + } 1895 + 2233 1896 } 2234 1897 2235 1898 instr->state = MTD_ERASE_DONE; ··· 2324 1955 int block; 2325 1956 2326 1957 /* Get block number */ 2327 - block = ((int) ofs) >> bbm->bbt_erase_shift; 1958 + block = onenand_block(this, ofs); 2328 1959 if (bbm->bbt) 2329 1960 bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); 2330 1961 2331 1962 /* We write two bytes, so we dont have to mess with 16 bit access */ 2332 1963 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01); 2333 - return onenand_write_oob_nolock(mtd, ofs, &ops); 1964 + /* FIXME : What to do when marking SLC block in partition 1965 + * with MLC erasesize? For now, it is not advisable to 1966 + * create partitions containing both SLC and MLC regions. 1967 + */ 1968 + return onenand_write_oob_nolock(mtd, ofs, &ops); 2334 1969 } 2335 1970 2336 1971 /** ··· 2378 2005 int start, end, block, value, status; 2379 2006 int wp_status_mask; 2380 2007 2381 - start = ofs >> this->erase_shift; 2382 - end = len >> this->erase_shift; 2008 + start = onenand_block(this, ofs); 2009 + end = onenand_block(this, ofs + len) - 1; 2383 2010 2384 2011 if (cmd == ONENAND_CMD_LOCK) 2385 2012 wp_status_mask = ONENAND_WP_LS; ··· 2391 2018 /* Set start block address */ 2392 2019 this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS); 2393 2020 /* Set end block address */ 2394 - this->write_word(start + end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS); 2021 + this->write_word(end, this->base + ONENAND_REG_END_BLOCK_ADDRESS); 2395 2022 /* Write lock command */ 2396 2023 this->command(mtd, cmd, 0, 0); 2397 2024 ··· 2412 2039 } 2413 2040 2414 2041 /* Block lock scheme */ 2415 - for (block = start; block < start + end; block++) { 2042 + for (block = start; block < end + 1; block++) { 2416 2043 /* Set block address */ 2417 2044 value = onenand_block_address(this, block); 2418 2045 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); ··· 2520 2147 { 2521 2148 struct onenand_chip *this = mtd->priv; 2522 2149 loff_t ofs = 0; 2523 - size_t len = this->chipsize; 2150 + loff_t len = mtd->size; 2524 2151 2525 2152 if (this->options & ONENAND_HAS_UNLOCK_ALL) { 2526 2153 /* Set start block address */ ··· 2536 2163 & ONENAND_CTRL_ONGO) 2537 2164 continue; 2538 2165 2166 + /* Don't check lock status */ 2167 + if (this->options & ONENAND_SKIP_UNLOCK_CHECK) 2168 + return; 2169 + 2539 2170 /* Check lock status */ 2540 2171 if (onenand_check_lock_status(this)) 2541 2172 return; 2542 2173 2543 2174 /* Workaround for all block unlock in DDP */ 2544 - if (ONENAND_IS_DDP(this)) { 2175 + if (ONENAND_IS_DDP(this) && !FLEXONENAND(this)) { 2545 2176 /* All blocks on another chip */ 2546 2177 ofs = this->chipsize >> 1; 2547 2178 len = this->chipsize >> 1; ··· 2587 2210 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); 2588 2211 this->wait(mtd, FL_OTPING); 2589 2212 2590 - ret = onenand_read_ops_nolock(mtd, from, &ops); 2213 + ret = ONENAND_IS_MLC(this) ? 2214 + onenand_mlc_read_ops_nolock(mtd, from, &ops) : 2215 + onenand_read_ops_nolock(mtd, from, &ops); 2591 2216 2592 2217 /* Exit OTP access mode */ 2593 2218 this->command(mtd, ONENAND_CMD_RESET, 0, 0); ··· 2656 2277 size_t *retlen, u_char *buf) 2657 2278 { 2658 2279 struct onenand_chip *this = mtd->priv; 2659 - struct mtd_oob_ops ops = { 2660 - .mode = MTD_OOB_PLACE, 2661 - .ooblen = len, 2662 - .oobbuf = buf, 2663 - .ooboffs = 0, 2664 - }; 2280 + struct mtd_oob_ops ops; 2665 2281 int ret; 2666 2282 2667 2283 /* Enter OTP access mode */ 2668 2284 this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); 2669 2285 this->wait(mtd, FL_OTPING); 2670 2286 2671 - ret = onenand_write_oob_nolock(mtd, from, &ops); 2672 - 2673 - *retlen = ops.oobretlen; 2287 + if (FLEXONENAND(this)) { 2288 + /* 2289 + * For Flex-OneNAND, we write lock mark to 1st word of sector 4 of 2290 + * main area of page 49. 2291 + */ 2292 + ops.len = mtd->writesize; 2293 + ops.ooblen = 0; 2294 + ops.datbuf = buf; 2295 + ops.oobbuf = NULL; 2296 + ret = onenand_write_ops_nolock(mtd, mtd->writesize * 49, &ops); 2297 + *retlen = ops.retlen; 2298 + } else { 2299 + ops.mode = MTD_OOB_PLACE; 2300 + ops.ooblen = len; 2301 + ops.oobbuf = buf; 2302 + ops.ooboffs = 0; 2303 + ret = onenand_write_oob_nolock(mtd, from, &ops); 2304 + *retlen = ops.oobretlen; 2305 + } 2674 2306 2675 2307 /* Exit OTP access mode */ 2676 2308 this->command(mtd, ONENAND_CMD_RESET, 0, 0); ··· 2865 2475 size_t len) 2866 2476 { 2867 2477 struct onenand_chip *this = mtd->priv; 2868 - u_char *oob_buf = this->oob_buf; 2478 + u_char *buf = FLEXONENAND(this) ? this->page_buf : this->oob_buf; 2869 2479 size_t retlen; 2870 2480 int ret; 2871 2481 2872 - memset(oob_buf, 0xff, mtd->oobsize); 2482 + memset(buf, 0xff, FLEXONENAND(this) ? this->writesize 2483 + : mtd->oobsize); 2873 2484 /* 2874 2485 * Note: OTP lock operation 2875 2486 * OTP block : 0xXXFC 2876 2487 * 1st block : 0xXXF3 (If chip support) 2877 2488 * Both : 0xXXF0 (If chip support) 2878 2489 */ 2879 - oob_buf[ONENAND_OTP_LOCK_OFFSET] = 0xFC; 2490 + if (FLEXONENAND(this)) 2491 + buf[FLEXONENAND_OTP_LOCK_OFFSET] = 0xFC; 2492 + else 2493 + buf[ONENAND_OTP_LOCK_OFFSET] = 0xFC; 2880 2494 2881 2495 /* 2882 2496 * Write lock mark to 8th word of sector0 of page0 of the spare0. 2883 2497 * We write 16 bytes spare area instead of 2 bytes. 2498 + * For Flex-OneNAND, we write lock mark to 1st word of sector 4 of 2499 + * main area of page 49. 2884 2500 */ 2885 - from = 0; 2886 - len = 16; 2887 2501 2888 - ret = onenand_otp_walk(mtd, from, len, &retlen, oob_buf, do_otp_lock, MTD_OTP_USER); 2502 + from = 0; 2503 + len = FLEXONENAND(this) ? mtd->writesize : 16; 2504 + 2505 + ret = onenand_otp_walk(mtd, from, len, &retlen, buf, do_otp_lock, MTD_OTP_USER); 2889 2506 2890 2507 return ret ? : retlen; 2891 2508 } ··· 2939 2542 break; 2940 2543 } 2941 2544 2545 + if (ONENAND_IS_MLC(this)) 2546 + this->options &= ~ONENAND_HAS_2PLANE; 2547 + 2548 + if (FLEXONENAND(this)) { 2549 + this->options &= ~ONENAND_HAS_CONT_LOCK; 2550 + this->options |= ONENAND_HAS_UNLOCK_ALL; 2551 + } 2552 + 2942 2553 if (this->options & ONENAND_HAS_CONT_LOCK) 2943 2554 printk(KERN_DEBUG "Lock scheme is Continuous Lock\n"); 2944 2555 if (this->options & ONENAND_HAS_UNLOCK_ALL) ··· 2964 2559 */ 2965 2560 static void onenand_print_device_info(int device, int version) 2966 2561 { 2967 - int vcc, demuxed, ddp, density; 2562 + int vcc, demuxed, ddp, density, flexonenand; 2968 2563 2969 2564 vcc = device & ONENAND_DEVICE_VCC_MASK; 2970 2565 demuxed = device & ONENAND_DEVICE_IS_DEMUX; 2971 2566 ddp = device & ONENAND_DEVICE_IS_DDP; 2972 2567 density = onenand_get_density(device); 2973 - printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n", 2974 - demuxed ? "" : "Muxed ", 2568 + flexonenand = device & DEVICE_IS_FLEXONENAND; 2569 + printk(KERN_INFO "%s%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n", 2570 + demuxed ? "" : "Muxed ", 2571 + flexonenand ? "Flex-" : "", 2975 2572 ddp ? "(DDP)" : "", 2976 2573 (16 << density), 2977 2574 vcc ? "2.65/3.3" : "1.8", ··· 2983 2576 2984 2577 static const struct onenand_manufacturers onenand_manuf_ids[] = { 2985 2578 {ONENAND_MFR_SAMSUNG, "Samsung"}, 2579 + {ONENAND_MFR_NUMONYX, "Numonyx"}, 2986 2580 }; 2987 2581 2988 2582 /** ··· 3013 2605 } 3014 2606 3015 2607 /** 2608 + * flexonenand_get_boundary - Reads the SLC boundary 2609 + * @param onenand_info - onenand info structure 2610 + **/ 2611 + static int flexonenand_get_boundary(struct mtd_info *mtd) 2612 + { 2613 + struct onenand_chip *this = mtd->priv; 2614 + unsigned die, bdry; 2615 + int ret, syscfg, locked; 2616 + 2617 + /* Disable ECC */ 2618 + syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1); 2619 + this->write_word((syscfg | 0x0100), this->base + ONENAND_REG_SYS_CFG1); 2620 + 2621 + for (die = 0; die < this->dies; die++) { 2622 + this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0); 2623 + this->wait(mtd, FL_SYNCING); 2624 + 2625 + this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0); 2626 + ret = this->wait(mtd, FL_READING); 2627 + 2628 + bdry = this->read_word(this->base + ONENAND_DATARAM); 2629 + if ((bdry >> FLEXONENAND_PI_UNLOCK_SHIFT) == 3) 2630 + locked = 0; 2631 + else 2632 + locked = 1; 2633 + this->boundary[die] = bdry & FLEXONENAND_PI_MASK; 2634 + 2635 + this->command(mtd, ONENAND_CMD_RESET, 0, 0); 2636 + ret = this->wait(mtd, FL_RESETING); 2637 + 2638 + printk(KERN_INFO "Die %d boundary: %d%s\n", die, 2639 + this->boundary[die], locked ? "(Locked)" : "(Unlocked)"); 2640 + } 2641 + 2642 + /* Enable ECC */ 2643 + this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1); 2644 + return 0; 2645 + } 2646 + 2647 + /** 2648 + * flexonenand_get_size - Fill up fields in onenand_chip and mtd_info 2649 + * boundary[], diesize[], mtd->size, mtd->erasesize 2650 + * @param mtd - MTD device structure 2651 + */ 2652 + static void flexonenand_get_size(struct mtd_info *mtd) 2653 + { 2654 + struct onenand_chip *this = mtd->priv; 2655 + int die, i, eraseshift, density; 2656 + int blksperdie, maxbdry; 2657 + loff_t ofs; 2658 + 2659 + density = onenand_get_density(this->device_id); 2660 + blksperdie = ((loff_t)(16 << density) << 20) >> (this->erase_shift); 2661 + blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0; 2662 + maxbdry = blksperdie - 1; 2663 + eraseshift = this->erase_shift - 1; 2664 + 2665 + mtd->numeraseregions = this->dies << 1; 2666 + 2667 + /* This fills up the device boundary */ 2668 + flexonenand_get_boundary(mtd); 2669 + die = ofs = 0; 2670 + i = -1; 2671 + for (; die < this->dies; die++) { 2672 + if (!die || this->boundary[die-1] != maxbdry) { 2673 + i++; 2674 + mtd->eraseregions[i].offset = ofs; 2675 + mtd->eraseregions[i].erasesize = 1 << eraseshift; 2676 + mtd->eraseregions[i].numblocks = 2677 + this->boundary[die] + 1; 2678 + ofs += mtd->eraseregions[i].numblocks << eraseshift; 2679 + eraseshift++; 2680 + } else { 2681 + mtd->numeraseregions -= 1; 2682 + mtd->eraseregions[i].numblocks += 2683 + this->boundary[die] + 1; 2684 + ofs += (this->boundary[die] + 1) << (eraseshift - 1); 2685 + } 2686 + if (this->boundary[die] != maxbdry) { 2687 + i++; 2688 + mtd->eraseregions[i].offset = ofs; 2689 + mtd->eraseregions[i].erasesize = 1 << eraseshift; 2690 + mtd->eraseregions[i].numblocks = maxbdry ^ 2691 + this->boundary[die]; 2692 + ofs += mtd->eraseregions[i].numblocks << eraseshift; 2693 + eraseshift--; 2694 + } else 2695 + mtd->numeraseregions -= 1; 2696 + } 2697 + 2698 + /* Expose MLC erase size except when all blocks are SLC */ 2699 + mtd->erasesize = 1 << this->erase_shift; 2700 + if (mtd->numeraseregions == 1) 2701 + mtd->erasesize >>= 1; 2702 + 2703 + printk(KERN_INFO "Device has %d eraseregions\n", mtd->numeraseregions); 2704 + for (i = 0; i < mtd->numeraseregions; i++) 2705 + printk(KERN_INFO "[offset: 0x%08x, erasesize: 0x%05x," 2706 + " numblocks: %04u]\n", 2707 + (unsigned int) mtd->eraseregions[i].offset, 2708 + mtd->eraseregions[i].erasesize, 2709 + mtd->eraseregions[i].numblocks); 2710 + 2711 + for (die = 0, mtd->size = 0; die < this->dies; die++) { 2712 + this->diesize[die] = (loff_t)blksperdie << this->erase_shift; 2713 + this->diesize[die] -= (loff_t)(this->boundary[die] + 1) 2714 + << (this->erase_shift - 1); 2715 + mtd->size += this->diesize[die]; 2716 + } 2717 + } 2718 + 2719 + /** 2720 + * flexonenand_check_blocks_erased - Check if blocks are erased 2721 + * @param mtd_info - mtd info structure 2722 + * @param start - first erase block to check 2723 + * @param end - last erase block to check 2724 + * 2725 + * Converting an unerased block from MLC to SLC 2726 + * causes byte values to change. Since both data and its ECC 2727 + * have changed, reads on the block give uncorrectable error. 2728 + * This might lead to the block being detected as bad. 2729 + * 2730 + * Avoid this by ensuring that the block to be converted is 2731 + * erased. 2732 + */ 2733 + static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int end) 2734 + { 2735 + struct onenand_chip *this = mtd->priv; 2736 + int i, ret; 2737 + int block; 2738 + struct mtd_oob_ops ops = { 2739 + .mode = MTD_OOB_PLACE, 2740 + .ooboffs = 0, 2741 + .ooblen = mtd->oobsize, 2742 + .datbuf = NULL, 2743 + .oobbuf = this->oob_buf, 2744 + }; 2745 + loff_t addr; 2746 + 2747 + printk(KERN_DEBUG "Check blocks from %d to %d\n", start, end); 2748 + 2749 + for (block = start; block <= end; block++) { 2750 + addr = flexonenand_addr(this, block); 2751 + if (onenand_block_isbad_nolock(mtd, addr, 0)) 2752 + continue; 2753 + 2754 + /* 2755 + * Since main area write results in ECC write to spare, 2756 + * it is sufficient to check only ECC bytes for change. 2757 + */ 2758 + ret = onenand_read_oob_nolock(mtd, addr, &ops); 2759 + if (ret) 2760 + return ret; 2761 + 2762 + for (i = 0; i < mtd->oobsize; i++) 2763 + if (this->oob_buf[i] != 0xff) 2764 + break; 2765 + 2766 + if (i != mtd->oobsize) { 2767 + printk(KERN_WARNING "Block %d not erased.\n", block); 2768 + return 1; 2769 + } 2770 + } 2771 + 2772 + return 0; 2773 + } 2774 + 2775 + /** 2776 + * flexonenand_set_boundary - Writes the SLC boundary 2777 + * @param mtd - mtd info structure 2778 + */ 2779 + int flexonenand_set_boundary(struct mtd_info *mtd, int die, 2780 + int boundary, int lock) 2781 + { 2782 + struct onenand_chip *this = mtd->priv; 2783 + int ret, density, blksperdie, old, new, thisboundary; 2784 + loff_t addr; 2785 + 2786 + /* Change only once for SDP Flex-OneNAND */ 2787 + if (die && (!ONENAND_IS_DDP(this))) 2788 + return 0; 2789 + 2790 + /* boundary value of -1 indicates no required change */ 2791 + if (boundary < 0 || boundary == this->boundary[die]) 2792 + return 0; 2793 + 2794 + density = onenand_get_density(this->device_id); 2795 + blksperdie = ((16 << density) << 20) >> this->erase_shift; 2796 + blksperdie >>= ONENAND_IS_DDP(this) ? 1 : 0; 2797 + 2798 + if (boundary >= blksperdie) { 2799 + printk(KERN_ERR "flexonenand_set_boundary: Invalid boundary value. " 2800 + "Boundary not changed.\n"); 2801 + return -EINVAL; 2802 + } 2803 + 2804 + /* Check if converting blocks are erased */ 2805 + old = this->boundary[die] + (die * this->density_mask); 2806 + new = boundary + (die * this->density_mask); 2807 + ret = flexonenand_check_blocks_erased(mtd, min(old, new) + 1, max(old, new)); 2808 + if (ret) { 2809 + printk(KERN_ERR "flexonenand_set_boundary: Please erase blocks before boundary change\n"); 2810 + return ret; 2811 + } 2812 + 2813 + this->command(mtd, FLEXONENAND_CMD_PI_ACCESS, die, 0); 2814 + this->wait(mtd, FL_SYNCING); 2815 + 2816 + /* Check is boundary is locked */ 2817 + this->command(mtd, FLEXONENAND_CMD_READ_PI, die, 0); 2818 + ret = this->wait(mtd, FL_READING); 2819 + 2820 + thisboundary = this->read_word(this->base + ONENAND_DATARAM); 2821 + if ((thisboundary >> FLEXONENAND_PI_UNLOCK_SHIFT) != 3) { 2822 + printk(KERN_ERR "flexonenand_set_boundary: boundary locked\n"); 2823 + ret = 1; 2824 + goto out; 2825 + } 2826 + 2827 + printk(KERN_INFO "flexonenand_set_boundary: Changing die %d boundary: %d%s\n", 2828 + die, boundary, lock ? "(Locked)" : "(Unlocked)"); 2829 + 2830 + addr = die ? this->diesize[0] : 0; 2831 + 2832 + boundary &= FLEXONENAND_PI_MASK; 2833 + boundary |= lock ? 0 : (3 << FLEXONENAND_PI_UNLOCK_SHIFT); 2834 + 2835 + this->command(mtd, ONENAND_CMD_ERASE, addr, 0); 2836 + ret = this->wait(mtd, FL_ERASING); 2837 + if (ret) { 2838 + printk(KERN_ERR "flexonenand_set_boundary: Failed PI erase for Die %d\n", die); 2839 + goto out; 2840 + } 2841 + 2842 + this->write_word(boundary, this->base + ONENAND_DATARAM); 2843 + this->command(mtd, ONENAND_CMD_PROG, addr, 0); 2844 + ret = this->wait(mtd, FL_WRITING); 2845 + if (ret) { 2846 + printk(KERN_ERR "flexonenand_set_boundary: Failed PI write for Die %d\n", die); 2847 + goto out; 2848 + } 2849 + 2850 + this->command(mtd, FLEXONENAND_CMD_PI_UPDATE, die, 0); 2851 + ret = this->wait(mtd, FL_WRITING); 2852 + out: 2853 + this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_REG_COMMAND); 2854 + this->wait(mtd, FL_RESETING); 2855 + if (!ret) 2856 + /* Recalculate device size on boundary change*/ 2857 + flexonenand_get_size(mtd); 2858 + 2859 + return ret; 2860 + } 2861 + 2862 + /** 3016 2863 * onenand_probe - [OneNAND Interface] Probe the OneNAND device 3017 2864 * @param mtd MTD device structure 3018 2865 * ··· 3284 2621 /* Save system configuration 1 */ 3285 2622 syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1); 3286 2623 /* Clear Sync. Burst Read mode to read BootRAM */ 3287 - this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ), this->base + ONENAND_REG_SYS_CFG1); 2624 + this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE), this->base + ONENAND_REG_SYS_CFG1); 3288 2625 3289 2626 /* Send the command for reading device ID from BootRAM */ 3290 2627 this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM); ··· 3309 2646 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID); 3310 2647 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID); 3311 2648 ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID); 2649 + this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY); 3312 2650 3313 2651 /* Check OneNAND device */ 3314 2652 if (maf_id != bram_maf_id || dev_id != bram_dev_id) ··· 3321 2657 this->version_id = ver_id; 3322 2658 3323 2659 density = onenand_get_density(dev_id); 2660 + if (FLEXONENAND(this)) { 2661 + this->dies = ONENAND_IS_DDP(this) ? 2 : 1; 2662 + /* Maximum possible erase regions */ 2663 + mtd->numeraseregions = this->dies << 1; 2664 + mtd->eraseregions = kzalloc(sizeof(struct mtd_erase_region_info) 2665 + * (this->dies << 1), GFP_KERNEL); 2666 + if (!mtd->eraseregions) 2667 + return -ENOMEM; 2668 + } 2669 + 2670 + /* 2671 + * For Flex-OneNAND, chipsize represents maximum possible device size. 2672 + * mtd->size represents the actual device size. 2673 + */ 3324 2674 this->chipsize = (16 << density) << 20; 3325 - /* Set density mask. it is used for DDP */ 3326 - if (ONENAND_IS_DDP(this)) 3327 - this->density_mask = (1 << (density + 6)); 3328 - else 3329 - this->density_mask = 0; 3330 2675 3331 2676 /* OneNAND page size & block size */ 3332 2677 /* The data buffer size is equal to page size */ 3333 2678 mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE); 2679 + /* We use the full BufferRAM */ 2680 + if (ONENAND_IS_MLC(this)) 2681 + mtd->writesize <<= 1; 2682 + 3334 2683 mtd->oobsize = mtd->writesize >> 5; 3335 2684 /* Pages per a block are always 64 in OneNAND */ 3336 2685 mtd->erasesize = mtd->writesize << 6; 2686 + /* 2687 + * Flex-OneNAND SLC area has 64 pages per block. 2688 + * Flex-OneNAND MLC area has 128 pages per block. 2689 + * Expose MLC erase size to find erase_shift and page_mask. 2690 + */ 2691 + if (FLEXONENAND(this)) 2692 + mtd->erasesize <<= 1; 3337 2693 3338 2694 this->erase_shift = ffs(mtd->erasesize) - 1; 3339 2695 this->page_shift = ffs(mtd->writesize) - 1; 3340 2696 this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1; 2697 + /* Set density mask. it is used for DDP */ 2698 + if (ONENAND_IS_DDP(this)) 2699 + this->density_mask = this->chipsize >> (this->erase_shift + 1); 3341 2700 /* It's real page size */ 3342 2701 this->writesize = mtd->writesize; 3343 2702 3344 2703 /* REVIST: Multichip handling */ 3345 2704 3346 - mtd->size = this->chipsize; 2705 + if (FLEXONENAND(this)) 2706 + flexonenand_get_size(mtd); 2707 + else 2708 + mtd->size = this->chipsize; 3347 2709 3348 2710 /* Check OneNAND features */ 3349 2711 onenand_check_features(mtd); ··· 3424 2734 */ 3425 2735 int onenand_scan(struct mtd_info *mtd, int maxchips) 3426 2736 { 3427 - int i; 2737 + int i, ret; 3428 2738 struct onenand_chip *this = mtd->priv; 3429 2739 3430 2740 if (!this->read_word) ··· 3436 2746 this->command = onenand_command; 3437 2747 if (!this->wait) 3438 2748 onenand_setup_wait(mtd); 2749 + if (!this->bbt_wait) 2750 + this->bbt_wait = onenand_bbt_wait; 2751 + if (!this->unlock_all) 2752 + this->unlock_all = onenand_unlock_all; 3439 2753 3440 2754 if (!this->read_bufferram) 3441 2755 this->read_bufferram = onenand_read_bufferram; ··· 3490 2796 * Allow subpage writes up to oobsize. 3491 2797 */ 3492 2798 switch (mtd->oobsize) { 2799 + case 128: 2800 + this->ecclayout = &onenand_oob_128; 2801 + mtd->subpage_sft = 0; 2802 + break; 3493 2803 case 64: 3494 2804 this->ecclayout = &onenand_oob_64; 3495 2805 mtd->subpage_sft = 2; ··· 3557 2859 mtd->owner = THIS_MODULE; 3558 2860 3559 2861 /* Unlock whole block */ 3560 - onenand_unlock_all(mtd); 2862 + this->unlock_all(mtd); 3561 2863 3562 - return this->scan_bbt(mtd); 2864 + ret = this->scan_bbt(mtd); 2865 + if ((!FLEXONENAND(this)) || ret) 2866 + return ret; 2867 + 2868 + /* Change Flex-OneNAND boundaries if required */ 2869 + for (i = 0; i < MAX_DIES; i++) 2870 + flexonenand_set_boundary(mtd, i, flex_bdry[2 * i], 2871 + flex_bdry[(2 * i) + 1]); 2872 + 2873 + return 0; 3563 2874 } 3564 2875 3565 2876 /** ··· 3597 2890 kfree(this->page_buf); 3598 2891 if (this->options & ONENAND_OOBBUF_ALLOC) 3599 2892 kfree(this->oob_buf); 2893 + kfree(mtd->eraseregions); 3600 2894 } 3601 2895 3602 2896 EXPORT_SYMBOL_GPL(onenand_scan);
+10 -4
drivers/mtd/onenand/onenand_bbt.c
··· 63 63 loff_t from; 64 64 size_t readlen, ooblen; 65 65 struct mtd_oob_ops ops; 66 + int rgn; 66 67 67 68 printk(KERN_INFO "Scanning device for bad blocks\n"); 68 69 ··· 77 76 /* Note that numblocks is 2 * (real numblocks) here; 78 77 * see i += 2 below as it makses shifting and masking less painful 79 78 */ 80 - numblocks = mtd->size >> (bbm->bbt_erase_shift - 1); 79 + numblocks = this->chipsize >> (bbm->bbt_erase_shift - 1); 81 80 startblock = 0; 82 81 from = 0; 83 82 ··· 107 106 } 108 107 } 109 108 i += 2; 110 - from += (1 << bbm->bbt_erase_shift); 109 + 110 + if (FLEXONENAND(this)) { 111 + rgn = flexonenand_region(mtd, from); 112 + from += mtd->eraseregions[rgn].erasesize; 113 + } else 114 + from += (1 << bbm->bbt_erase_shift); 111 115 } 112 116 113 117 return 0; ··· 149 143 uint8_t res; 150 144 151 145 /* Get block number * 2 */ 152 - block = (int) (offs >> (bbm->bbt_erase_shift - 1)); 146 + block = (int) (onenand_block(this, offs) << 1); 153 147 res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03; 154 148 155 149 DEBUG(MTD_DEBUG_LEVEL2, "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n", ··· 184 178 struct bbm_info *bbm = this->bbm; 185 179 int len, ret = 0; 186 180 187 - len = mtd->size >> (this->erase_shift + 2); 181 + len = this->chipsize >> (this->erase_shift + 2); 188 182 /* Allocate memory (2bit per block) and clear the memory bad block table */ 189 183 bbm->bbt = kzalloc(len, GFP_KERNEL); 190 184 if (!bbm->bbt) {
+74 -7
drivers/mtd/onenand/onenand_sim.c
··· 6 6 * Copyright © 2005-2007 Samsung Electronics 7 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 13 * This program is free software; you can redistribute it and/or modify 10 14 * it under the terms of the GNU General Public License version 2 as 11 15 * published by the Free Software Foundation. ··· 28 24 #ifndef CONFIG_ONENAND_SIM_MANUFACTURER 29 25 #define CONFIG_ONENAND_SIM_MANUFACTURER 0xec 30 26 #endif 27 + 31 28 #ifndef CONFIG_ONENAND_SIM_DEVICE_ID 32 29 #define CONFIG_ONENAND_SIM_DEVICE_ID 0x04 33 30 #endif 31 + 32 + #define CONFIG_FLEXONENAND ((CONFIG_ONENAND_SIM_DEVICE_ID >> 9) & 1) 33 + 34 34 #ifndef CONFIG_ONENAND_SIM_VERSION_ID 35 35 #define CONFIG_ONENAND_SIM_VERSION_ID 0x1e 36 + #endif 37 + 38 + #ifndef CONFIG_ONENAND_SIM_TECHNOLOGY_ID 39 + #define CONFIG_ONENAND_SIM_TECHNOLOGY_ID CONFIG_FLEXONENAND 40 + #endif 41 + 42 + /* Initial boundary values for Flex-OneNAND Simulator */ 43 + #ifndef CONFIG_FLEXONENAND_SIM_DIE0_BOUNDARY 44 + #define CONFIG_FLEXONENAND_SIM_DIE0_BOUNDARY 0x01 45 + #endif 46 + 47 + #ifndef CONFIG_FLEXONENAND_SIM_DIE1_BOUNDARY 48 + #define CONFIG_FLEXONENAND_SIM_DIE1_BOUNDARY 0x01 36 49 #endif 37 50 38 51 static int manuf_id = CONFIG_ONENAND_SIM_MANUFACTURER; 39 52 static int device_id = CONFIG_ONENAND_SIM_DEVICE_ID; 40 53 static int version_id = CONFIG_ONENAND_SIM_VERSION_ID; 54 + static int technology_id = CONFIG_ONENAND_SIM_TECHNOLOGY_ID; 55 + static int boundary[] = { 56 + CONFIG_FLEXONENAND_SIM_DIE0_BOUNDARY, 57 + CONFIG_FLEXONENAND_SIM_DIE1_BOUNDARY, 58 + }; 41 59 42 60 struct onenand_flash { 43 61 void __iomem *base; ··· 83 57 (writew(v, this->base + ONENAND_REG_WP_STATUS)) 84 58 85 59 /* It has all 0xff chars */ 86 - #define MAX_ONENAND_PAGESIZE (2048 + 64) 60 + #define MAX_ONENAND_PAGESIZE (4096 + 128) 87 61 static unsigned char *ffchars; 62 + 63 + #if CONFIG_FLEXONENAND 64 + #define PARTITION_NAME "Flex-OneNAND simulator partition" 65 + #else 66 + #define PARTITION_NAME "OneNAND simulator partition" 67 + #endif 88 68 89 69 static struct mtd_partition os_partitions[] = { 90 70 { 91 - .name = "OneNAND simulator partition", 71 + .name = PARTITION_NAME, 92 72 .offset = 0, 93 73 .size = MTDPART_SIZ_FULL, 94 74 }, ··· 136 104 137 105 switch (cmd) { 138 106 case ONENAND_CMD_UNLOCK: 107 + case ONENAND_CMD_UNLOCK_ALL: 139 108 if (block_lock_scheme) 140 109 ONENAND_SET_WP_STATUS(ONENAND_WP_US, this); 141 110 else ··· 261 228 { 262 229 struct mtd_info *mtd = &info->mtd; 263 230 struct onenand_flash *flash = this->priv; 264 - int main_offset, spare_offset; 231 + int main_offset, spare_offset, die = 0; 265 232 void __iomem *src; 266 233 void __iomem *dest; 267 234 unsigned int i; 235 + static int pi_operation; 236 + int erasesize, rgn; 268 237 269 238 if (dataram) { 270 239 main_offset = mtd->writesize; ··· 276 241 spare_offset = 0; 277 242 } 278 243 244 + if (pi_operation) { 245 + die = readw(this->base + ONENAND_REG_START_ADDRESS2); 246 + die >>= ONENAND_DDP_SHIFT; 247 + } 248 + 279 249 switch (cmd) { 250 + case FLEXONENAND_CMD_PI_ACCESS: 251 + pi_operation = 1; 252 + break; 253 + 254 + case ONENAND_CMD_RESET: 255 + pi_operation = 0; 256 + break; 257 + 280 258 case ONENAND_CMD_READ: 281 259 src = ONENAND_CORE(flash) + offset; 282 260 dest = ONENAND_MAIN_AREA(this, main_offset); 261 + if (pi_operation) { 262 + writew(boundary[die], this->base + ONENAND_DATARAM); 263 + break; 264 + } 283 265 memcpy(dest, src, mtd->writesize); 284 266 /* Fall through */ 285 267 ··· 309 257 case ONENAND_CMD_PROG: 310 258 src = ONENAND_MAIN_AREA(this, main_offset); 311 259 dest = ONENAND_CORE(flash) + offset; 260 + if (pi_operation) { 261 + boundary[die] = readw(this->base + ONENAND_DATARAM); 262 + break; 263 + } 312 264 /* To handle partial write */ 313 265 for (i = 0; i < (1 << mtd->subpage_sft); i++) { 314 266 int off = i * this->subpagesize; ··· 340 284 break; 341 285 342 286 case ONENAND_CMD_ERASE: 343 - memset(ONENAND_CORE(flash) + offset, 0xff, mtd->erasesize); 287 + if (pi_operation) 288 + break; 289 + 290 + if (FLEXONENAND(this)) { 291 + rgn = flexonenand_region(mtd, offset); 292 + erasesize = mtd->eraseregions[rgn].erasesize; 293 + } else 294 + erasesize = mtd->erasesize; 295 + 296 + memset(ONENAND_CORE(flash) + offset, 0xff, erasesize); 344 297 memset(ONENAND_CORE_SPARE(flash, this, offset), 0xff, 345 - (mtd->erasesize >> 5)); 298 + (erasesize >> 5)); 346 299 break; 347 300 348 301 default: ··· 404 339 } 405 340 406 341 if (block != -1) 407 - offset += block << this->erase_shift; 342 + offset = onenand_addr(this, block); 408 343 409 344 if (page != -1) 410 345 offset += page << this->page_shift; ··· 455 390 } 456 391 457 392 density = device_id >> ONENAND_DEVICE_DENSITY_SHIFT; 393 + density &= ONENAND_DEVICE_DENSITY_MASK; 458 394 size = ((16 << 20) << density); 459 395 460 396 ONENAND_CORE(flash) = vmalloc(size + (size >> 5)); ··· 471 405 writew(manuf_id, flash->base + ONENAND_REG_MANUFACTURER_ID); 472 406 writew(device_id, flash->base + ONENAND_REG_DEVICE_ID); 473 407 writew(version_id, flash->base + ONENAND_REG_VERSION_ID); 408 + writew(technology_id, flash->base + ONENAND_REG_TECHNOLOGY); 474 409 475 - if (density < 2) 410 + if (density < 2 && (!CONFIG_FLEXONENAND)) 476 411 buffer_size = 0x0400; /* 1KiB page */ 477 412 else 478 413 buffer_size = 0x0800; /* 2KiB page */
-52
fs/compat_ioctl.c
··· 94 94 #include <linux/atm_tcp.h> 95 95 #include <linux/sonet.h> 96 96 #include <linux/atm_suni.h> 97 - #include <linux/mtd/mtd.h> 98 97 99 98 #include <linux/usb.h> 100 99 #include <linux/usbdevice_fs.h> ··· 1404 1405 #define HIDPGETCONNLIST _IOR('H', 210, int) 1405 1406 #define HIDPGETCONNINFO _IOR('H', 211, int) 1406 1407 1407 - struct mtd_oob_buf32 { 1408 - u_int32_t start; 1409 - u_int32_t length; 1410 - compat_caddr_t ptr; /* unsigned char* */ 1411 - }; 1412 - 1413 - #define MEMWRITEOOB32 _IOWR('M',3,struct mtd_oob_buf32) 1414 - #define MEMREADOOB32 _IOWR('M',4,struct mtd_oob_buf32) 1415 - 1416 - static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg) 1417 - { 1418 - struct mtd_oob_buf __user *buf = compat_alloc_user_space(sizeof(*buf)); 1419 - struct mtd_oob_buf32 __user *buf32 = compat_ptr(arg); 1420 - u32 data; 1421 - char __user *datap; 1422 - unsigned int real_cmd; 1423 - int err; 1424 - 1425 - real_cmd = (cmd == MEMREADOOB32) ? 1426 - MEMREADOOB : MEMWRITEOOB; 1427 - 1428 - if (copy_in_user(&buf->start, &buf32->start, 1429 - 2 * sizeof(u32)) || 1430 - get_user(data, &buf32->ptr)) 1431 - return -EFAULT; 1432 - datap = compat_ptr(data); 1433 - if (put_user(datap, &buf->ptr)) 1434 - return -EFAULT; 1435 - 1436 - err = sys_ioctl(fd, real_cmd, (unsigned long) buf); 1437 - 1438 - if (!err) { 1439 - if (copy_in_user(&buf32->start, &buf->start, 1440 - 2 * sizeof(u32))) 1441 - err = -EFAULT; 1442 - } 1443 - 1444 - return err; 1445 - } 1446 - 1447 1408 #ifdef CONFIG_BLOCK 1448 1409 struct raw32_config_request 1449 1410 { ··· 2385 2426 COMPATIBLE_IOCTL(USBDEVFS_REAPURB32) 2386 2427 COMPATIBLE_IOCTL(USBDEVFS_REAPURBNDELAY32) 2387 2428 COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT) 2388 - /* MTD */ 2389 - COMPATIBLE_IOCTL(MEMGETINFO) 2390 - COMPATIBLE_IOCTL(MEMERASE) 2391 - COMPATIBLE_IOCTL(MEMLOCK) 2392 - COMPATIBLE_IOCTL(MEMUNLOCK) 2393 - COMPATIBLE_IOCTL(MEMGETREGIONCOUNT) 2394 - COMPATIBLE_IOCTL(MEMGETREGIONINFO) 2395 - COMPATIBLE_IOCTL(MEMGETBADBLOCK) 2396 - COMPATIBLE_IOCTL(MEMSETBADBLOCK) 2397 2429 /* NBD */ 2398 2430 ULONG_IOCTL(NBD_SET_SOCK) 2399 2431 ULONG_IOCTL(NBD_SET_BLKSIZE) ··· 2494 2544 COMPATIBLE_IOCTL(JSIOCGNAME(0)) 2495 2545 2496 2546 /* now things that need handlers */ 2497 - HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob) 2498 - HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob) 2499 2547 #ifdef CONFIG_NET 2500 2548 HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32) 2501 2549 HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf)
+2 -2
fs/jffs2/scan.c
··· 196 196 if (c->nextblock) { 197 197 ret = file_dirty(c, c->nextblock); 198 198 if (ret) 199 - return ret; 199 + goto out; 200 200 /* deleting summary information of the old nextblock */ 201 201 jffs2_sum_reset_collected(c->summary); 202 202 } ··· 207 207 } else { 208 208 ret = file_dirty(c, jeb); 209 209 if (ret) 210 - return ret; 210 + goto out; 211 211 } 212 212 break; 213 213
+16
include/linux/mtd/nand.h
··· 563 563 * @options: Option flags, e.g. 16bit buswidth 564 564 * @ecclayout: ecc layout info structure 565 565 * @part_probe_types: NULL-terminated array of probe types 566 + * @set_parts: platform specific function to set partitions 566 567 * @priv: hardware controller specific settings 567 568 */ 568 569 struct platform_nand_chip { ··· 575 574 int chip_delay; 576 575 unsigned int options; 577 576 const char **part_probe_types; 577 + void (*set_parts)(uint64_t size, 578 + struct platform_nand_chip *chip); 578 579 void *priv; 579 580 }; 580 581 582 + /* Keep gcc happy */ 583 + struct platform_device; 584 + 581 585 /** 582 586 * struct platform_nand_ctrl - controller level device structure 587 + * @probe: platform specific function to probe/setup hardware 588 + * @remove: platform specific function to remove/teardown hardware 583 589 * @hwcontrol: platform specific hardware control structure 584 590 * @dev_ready: platform specific function to read ready/busy pin 585 591 * @select_chip: platform specific chip select function 586 592 * @cmd_ctrl: platform specific function for controlling 587 593 * ALE/CLE/nCE. Also used to write command and address 594 + * @write_buf: platform specific function for write buffer 595 + * @read_buf: platform specific function for read buffer 588 596 * @priv: private data to transport driver specific settings 589 597 * 590 598 * All fields are optional and depend on the hardware driver requirements 591 599 */ 592 600 struct platform_nand_ctrl { 601 + int (*probe)(struct platform_device *pdev); 602 + void (*remove)(struct platform_device *pdev); 593 603 void (*hwcontrol)(struct mtd_info *mtd, int cmd); 594 604 int (*dev_ready)(struct mtd_info *mtd); 595 605 void (*select_chip)(struct mtd_info *mtd, int chip); 596 606 void (*cmd_ctrl)(struct mtd_info *mtd, int dat, 597 607 unsigned int ctrl); 608 + void (*write_buf)(struct mtd_info *mtd, 609 + const uint8_t *buf, int len); 610 + void (*read_buf)(struct mtd_info *mtd, 611 + uint8_t *buf, int len); 598 612 void *priv; 599 613 }; 600 614
+24
include/linux/mtd/onenand.h
··· 17 17 #include <linux/mtd/onenand_regs.h> 18 18 #include <linux/mtd/bbm.h> 19 19 20 + #define MAX_DIES 2 20 21 #define MAX_BUFFERRAM 2 21 22 22 23 /* Scan and identify a OneNAND device */ ··· 52 51 /** 53 52 * struct onenand_chip - OneNAND Private Flash Chip Data 54 53 * @base: [BOARDSPECIFIC] address to access OneNAND 54 + * @dies: [INTERN][FLEX-ONENAND] number of dies on chip 55 + * @boundary: [INTERN][FLEX-ONENAND] Boundary of the dies 56 + * @diesize: [INTERN][FLEX-ONENAND] Size of the dies 55 57 * @chipsize: [INTERN] the size of one chip for multichip arrays 58 + * FIXME For Flex-OneNAND, chipsize holds maximum possible 59 + * device size ie when all blocks are considered MLC 56 60 * @device_id: [INTERN] device ID 57 61 * @density_mask: chip density, used for DDP devices 58 62 * @verstion_id: [INTERN] version ID ··· 74 68 * @command: [REPLACEABLE] hardware specific function for writing 75 69 * commands to the chip 76 70 * @wait: [REPLACEABLE] hardware specific function for wait on ready 71 + * @bbt_wait: [REPLACEABLE] hardware specific function for bbt wait on ready 72 + * @unlock_all: [REPLACEABLE] hardware specific function for unlock all 77 73 * @read_bufferram: [REPLACEABLE] hardware specific function for BufferRAM Area 78 74 * @write_bufferram: [REPLACEABLE] hardware specific function for BufferRAM Area 79 75 * @read_word: [REPLACEABLE] hardware specific function for read ··· 100 92 */ 101 93 struct onenand_chip { 102 94 void __iomem *base; 95 + unsigned dies; 96 + unsigned boundary[MAX_DIES]; 97 + loff_t diesize[MAX_DIES]; 103 98 unsigned int chipsize; 104 99 unsigned int device_id; 105 100 unsigned int version_id; 101 + unsigned int technology; 106 102 unsigned int density_mask; 107 103 unsigned int options; 108 104 ··· 120 108 121 109 int (*command)(struct mtd_info *mtd, int cmd, loff_t address, size_t len); 122 110 int (*wait)(struct mtd_info *mtd, int state); 111 + int (*bbt_wait)(struct mtd_info *mtd, int state); 112 + void (*unlock_all)(struct mtd_info *mtd); 123 113 int (*read_bufferram)(struct mtd_info *mtd, int area, 124 114 unsigned char *buffer, int offset, size_t count); 125 115 int (*write_bufferram)(struct mtd_info *mtd, int area, ··· 159 145 #define ONENAND_SET_BUFFERRAM0(this) (this->bufferram_index = 0) 160 146 #define ONENAND_SET_BUFFERRAM1(this) (this->bufferram_index = 1) 161 147 148 + #define FLEXONENAND(this) \ 149 + (this->device_id & DEVICE_IS_FLEXONENAND) 162 150 #define ONENAND_GET_SYS_CFG1(this) \ 163 151 (this->read_word(this->base + ONENAND_REG_SYS_CFG1)) 164 152 #define ONENAND_SET_SYS_CFG1(v, this) \ ··· 168 152 169 153 #define ONENAND_IS_DDP(this) \ 170 154 (this->device_id & ONENAND_DEVICE_IS_DDP) 155 + 156 + #define ONENAND_IS_MLC(this) \ 157 + (this->technology & ONENAND_TECHNOLOGY_IS_MLC) 171 158 172 159 #ifdef CONFIG_MTD_ONENAND_2X_PROGRAM 173 160 #define ONENAND_IS_2PLANE(this) \ ··· 188 169 #define ONENAND_HAS_CONT_LOCK (0x0001) 189 170 #define ONENAND_HAS_UNLOCK_ALL (0x0002) 190 171 #define ONENAND_HAS_2PLANE (0x0004) 172 + #define ONENAND_SKIP_UNLOCK_CHECK (0x0100) 191 173 #define ONENAND_PAGEBUF_ALLOC (0x1000) 192 174 #define ONENAND_OOBBUF_ALLOC (0x2000) 193 175 ··· 196 176 * OneNAND Flash Manufacturer ID Codes 197 177 */ 198 178 #define ONENAND_MFR_SAMSUNG 0xec 179 + #define ONENAND_MFR_NUMONYX 0x20 199 180 200 181 /** 201 182 * struct onenand_manufacturers - NAND Flash Manufacturer ID Structure ··· 210 189 211 190 int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, 212 191 struct mtd_oob_ops *ops); 192 + unsigned onenand_block(struct onenand_chip *this, loff_t addr); 193 + loff_t onenand_addr(struct onenand_chip *this, int block); 194 + int flexonenand_region(struct mtd_info *mtd, loff_t addr); 213 195 214 196 #endif /* __LINUX_MTD_ONENAND_H */
+18 -2
include/linux/mtd/onenand_regs.h
··· 67 67 /* 68 68 * Device ID Register F001h (R) 69 69 */ 70 + #define DEVICE_IS_FLEXONENAND (1 << 9) 71 + #define FLEXONENAND_PI_MASK (0x3ff) 72 + #define FLEXONENAND_PI_UNLOCK_SHIFT (14) 70 73 #define ONENAND_DEVICE_DENSITY_MASK (0xf) 71 74 #define ONENAND_DEVICE_DENSITY_SHIFT (4) 72 75 #define ONENAND_DEVICE_IS_DDP (1 << 3) ··· 87 84 #define ONENAND_VERSION_PROCESS_SHIFT (8) 88 85 89 86 /* 87 + * Technology Register F006h (R) 88 + */ 89 + #define ONENAND_TECHNOLOGY_IS_MLC (1 << 0) 90 + 91 + /* 90 92 * Start Address 1 F100h (R/W) & Start Address 2 F101h (R/W) 91 93 */ 92 94 #define ONENAND_DDP_SHIFT (15) ··· 101 93 /* 102 94 * Start Address 8 F107h (R/W) 103 95 */ 104 - #define ONENAND_FPA_MASK (0x3f) 96 + /* Note: It's actually 0x3f in case of SLC */ 97 + #define ONENAND_FPA_MASK (0x7f) 105 98 #define ONENAND_FPA_SHIFT (2) 106 99 #define ONENAND_FSA_MASK (0x03) 107 100 ··· 114 105 #define ONENAND_BSA_BOOTRAM (0 << 2) 115 106 #define ONENAND_BSA_DATARAM0 (2 << 2) 116 107 #define ONENAND_BSA_DATARAM1 (3 << 2) 117 - #define ONENAND_BSC_MASK (0x03) 108 + /* Note: It's actually 0x03 in case of SLC */ 109 + #define ONENAND_BSC_MASK (0x07) 118 110 119 111 /* 120 112 * Command Register F220h (R/W) ··· 134 124 #define ONENAND_CMD_RESET (0xF0) 135 125 #define ONENAND_CMD_OTP_ACCESS (0x65) 136 126 #define ONENAND_CMD_READID (0x90) 127 + #define FLEXONENAND_CMD_PI_UPDATE (0x05) 128 + #define FLEXONENAND_CMD_PI_ACCESS (0x66) 129 + #define FLEXONENAND_CMD_RECOVER_LSB (0x05) 137 130 138 131 /* NOTE: Those are not *REAL* commands */ 139 132 #define ONENAND_CMD_BUFFERRAM (0x1978) 133 + #define FLEXONENAND_CMD_READ_PI (0x1985) 140 134 141 135 /* 142 136 * System Configuration 1 Register F221h (R, R/W) ··· 206 192 #define ONENAND_ECC_1BIT_ALL (0x5555) 207 193 #define ONENAND_ECC_2BIT (1 << 1) 208 194 #define ONENAND_ECC_2BIT_ALL (0xAAAA) 195 + #define FLEXONENAND_UNCORRECTABLE_ERROR (0x1010) 209 196 210 197 /* 211 198 * One-Time Programmable (OTP) 212 199 */ 200 + #define FLEXONENAND_OTP_LOCK_OFFSET (2048) 213 201 #define ONENAND_OTP_LOCK_OFFSET (14) 214 202 215 203 #endif /* __ONENAND_REG_H */
-1
include/linux/mtd/partitions.h
··· 40 40 uint64_t offset; /* offset within the master MTD space */ 41 41 uint32_t mask_flags; /* master MTD flags to mask out for this partition */ 42 42 struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/ 43 - struct mtd_info **mtdp; /* pointer to store the MTD object */ 44 43 }; 45 44 46 45 #define MTDPART_OFS_NXTBLK (-2)
-1
include/mtd/Kbuild
··· 1 1 header-y += inftl-user.h 2 - header-y += jffs2-user.h 3 2 header-y += mtd-abi.h 4 3 header-y += mtd-user.h 5 4 header-y += nftl-user.h
-34
include/mtd/jffs2-user.h
··· 1 - /* 2 - * JFFS2 definitions for use in user space only 3 - */ 4 - 5 - #ifndef __JFFS2_USER_H__ 6 - #define __JFFS2_USER_H__ 7 - 8 - /* This file is blessed for inclusion by userspace */ 9 - #include <linux/jffs2.h> 10 - #include <linux/types.h> 11 - #include <endian.h> 12 - #include <byteswap.h> 13 - 14 - #undef cpu_to_je16 15 - #undef cpu_to_je32 16 - #undef cpu_to_jemode 17 - #undef je16_to_cpu 18 - #undef je32_to_cpu 19 - #undef jemode_to_cpu 20 - 21 - extern int target_endian; 22 - 23 - #define t16(x) ({ __u16 __b = (x); (target_endian==__BYTE_ORDER)?__b:bswap_16(__b); }) 24 - #define t32(x) ({ __u32 __b = (x); (target_endian==__BYTE_ORDER)?__b:bswap_32(__b); }) 25 - 26 - #define cpu_to_je16(x) ((jint16_t){t16(x)}) 27 - #define cpu_to_je32(x) ((jint32_t){t32(x)}) 28 - #define cpu_to_jemode(x) ((jmode_t){t32(x)}) 29 - 30 - #define je16_to_cpu(x) (t16((x).v16)) 31 - #define je32_to_cpu(x) (t32((x).v32)) 32 - #define jemode_to_cpu(x) (t32((x).m)) 33 - 34 - #endif /* __JFFS2_USER_H__ */
+15
include/mtd/mtd-abi.h
··· 12 12 __u32 length; 13 13 }; 14 14 15 + struct erase_info_user64 { 16 + __u64 start; 17 + __u64 length; 18 + }; 19 + 15 20 struct mtd_oob_buf { 16 21 __u32 start; 17 22 __u32 length; 18 23 unsigned char __user *ptr; 24 + }; 25 + 26 + struct mtd_oob_buf64 { 27 + __u64 start; 28 + __u32 pad; 29 + __u32 length; 30 + __u64 usr_ptr; 19 31 }; 20 32 21 33 #define MTD_ABSENT 0 ··· 107 95 #define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout) 108 96 #define ECCGETSTATS _IOR('M', 18, struct mtd_ecc_stats) 109 97 #define MTDFILEMODE _IO('M', 19) 98 + #define MEMERASE64 _IOW('M', 20, struct erase_info_user64) 99 + #define MEMWRITEOOB64 _IOWR('M', 21, struct mtd_oob_buf64) 100 + #define MEMREADOOB64 _IOWR('M', 22, struct mtd_oob_buf64) 110 101 111 102 /* 112 103 * Obsolete legacy interface. Keep it in order not to break userspace