aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/Makefile2
-rw-r--r--drivers/mtd/ar7part.c6
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c8
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c11
-rw-r--r--drivers/mtd/chips/jedec_probe.c16
-rw-r--r--drivers/mtd/chips/map_ram.c17
-rw-r--r--drivers/mtd/chips/map_rom.c25
-rw-r--r--drivers/mtd/cmdlinepart.c6
-rw-r--r--drivers/mtd/devices/Kconfig7
-rw-r--r--drivers/mtd/devices/Makefile1
-rw-r--r--drivers/mtd/devices/doc2000.c1
-rw-r--r--drivers/mtd/devices/doc2001.c1
-rw-r--r--drivers/mtd/devices/doc2001plus.c1
-rw-r--r--drivers/mtd/devices/docecc.c1
-rw-r--r--drivers/mtd/devices/m25p80.c19
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c21
-rw-r--r--drivers/mtd/devices/mtdram.c14
-rw-r--r--drivers/mtd/devices/ps3vram.c768
-rw-r--r--drivers/mtd/devices/slram.c14
-rw-r--r--drivers/mtd/inftlmount.c1
-rw-r--r--drivers/mtd/internal.h17
-rw-r--r--drivers/mtd/lpddr/Kconfig1
-rw-r--r--drivers/mtd/maps/Kconfig26
-rw-r--r--drivers/mtd/maps/Makefile3
-rw-r--r--drivers/mtd/maps/bfin-async-flash.c6
-rw-r--r--drivers/mtd/maps/ck804xrom.c2
-rw-r--r--drivers/mtd/maps/integrator-flash.c2
-rw-r--r--drivers/mtd/maps/omap_nor.c2
-rw-r--r--drivers/mtd/maps/physmap.c42
-rw-r--r--drivers/mtd/maps/physmap_of.c1
-rw-r--r--drivers/mtd/maps/plat-ram.c1
-rw-r--r--drivers/mtd/maps/pxa2xx-flash.c37
-rw-r--r--drivers/mtd/maps/rbtx4939-flash.c208
-rw-r--r--drivers/mtd/maps/sa1100-flash.c4
-rw-r--r--drivers/mtd/maps/sharpsl-flash.c116
-rw-r--r--drivers/mtd/maps/vmu-flash.c832
-rw-r--r--drivers/mtd/mtd_blkdevs.c4
-rw-r--r--drivers/mtd/mtdbdi.c43
-rw-r--r--drivers/mtd/mtdchar.c111
-rw-r--r--drivers/mtd/mtdconcat.c47
-rw-r--r--drivers/mtd/mtdcore.c208
-rw-r--r--drivers/mtd/mtdoops.c16
-rw-r--r--drivers/mtd/mtdpart.c31
-rw-r--r--drivers/mtd/mtdsuper.c7
-rw-r--r--drivers/mtd/nand/Kconfig23
-rw-r--r--drivers/mtd/nand/Makefile3
-rw-r--r--drivers/mtd/nand/atmel_nand.c3
-rw-r--r--drivers/mtd/nand/bf5xx_nand.c18
-rw-r--r--drivers/mtd/nand/cafe_nand.c1
-rw-r--r--drivers/mtd/nand/cmx270_nand.c3
-rw-r--r--drivers/mtd/nand/davinci_nand.c570
-rw-r--r--drivers/mtd/nand/diskonchip.c2
-rw-r--r--drivers/mtd/nand/excite_nandflash.c25
-rw-r--r--drivers/mtd/nand/fsl_upm.c119
-rw-r--r--drivers/mtd/nand/mxc_nand.c3
-rw-r--r--drivers/mtd/nand/nand_base.c129
-rw-r--r--drivers/mtd/nand/ndfc.c2
-rw-r--r--drivers/mtd/nand/orion_nand.c2
-rw-r--r--drivers/mtd/nand/plat_nand.c2
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c120
-rw-r--r--drivers/mtd/nand/sh_flctl.c18
-rw-r--r--drivers/mtd/nand/socrates_nand.c325
-rw-r--r--drivers/mtd/nand/txx9ndfmc.c428
-rw-r--r--drivers/mtd/nftlcore.c3
-rw-r--r--drivers/mtd/ofpart.c7
-rw-r--r--drivers/mtd/onenand/generic.c26
-rw-r--r--drivers/mtd/onenand/omap2.c6
-rw-r--r--drivers/mtd/onenand/onenand_base.c145
-rw-r--r--drivers/mtd/tests/mtd_oobtest.c24
-rw-r--r--drivers/mtd/tests/mtd_readtest.c2
70 files changed, 3529 insertions, 1187 deletions
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 4521b1ecce45..82d1e4de475b 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -4,7 +4,7 @@
4 4
5# Core functionality. 5# Core functionality.
6obj-$(CONFIG_MTD) += mtd.o 6obj-$(CONFIG_MTD) += mtd.o
7mtd-y := mtdcore.o mtdsuper.o 7mtd-y := mtdcore.o mtdsuper.o mtdbdi.o
8mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o 8mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o
9 9
10obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o 10obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o
diff --git a/drivers/mtd/ar7part.c b/drivers/mtd/ar7part.c
index ecf170b55c32..6697a1ec72d0 100644
--- a/drivers/mtd/ar7part.c
+++ b/drivers/mtd/ar7part.c
@@ -44,8 +44,6 @@ struct ar7_bin_rec {
44 unsigned int address; 44 unsigned int address;
45}; 45};
46 46
47static struct mtd_partition ar7_parts[AR7_PARTS];
48
49static int create_mtd_partitions(struct mtd_info *master, 47static int create_mtd_partitions(struct mtd_info *master,
50 struct mtd_partition **pparts, 48 struct mtd_partition **pparts,
51 unsigned long origin) 49 unsigned long origin)
@@ -57,7 +55,11 @@ static int create_mtd_partitions(struct mtd_info *master,
57 unsigned int root_offset = ROOT_OFFSET; 55 unsigned int root_offset = ROOT_OFFSET;
58 56
59 int retries = 10; 57 int retries = 10;
58 struct mtd_partition *ar7_parts;
60 59
60 ar7_parts = kzalloc(sizeof(*ar7_parts) * AR7_PARTS, GFP_KERNEL);
61 if (!ar7_parts)
62 return -ENOMEM;
61 ar7_parts[0].name = "loader"; 63 ar7_parts[0].name = "loader";
62 ar7_parts[0].offset = 0; 64 ar7_parts[0].offset = 0;
63 ar7_parts[0].size = master->erasesize; 65 ar7_parts[0].size = master->erasesize;
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index f5ab6fa1057b..c240454fd113 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -1236,10 +1236,14 @@ static int inval_cache_and_wait_for_operation(
1236 remove_wait_queue(&chip->wq, &wait); 1236 remove_wait_queue(&chip->wq, &wait);
1237 spin_lock(chip->mutex); 1237 spin_lock(chip->mutex);
1238 } 1238 }
1239 if (chip->erase_suspended || chip->write_suspended) { 1239 if (chip->erase_suspended && chip_state == FL_ERASING) {
1240 /* Suspend has occured while sleep: reset timeout */ 1240 /* Erase suspend occured while sleep: reset timeout */
1241 timeo = reset_timeo; 1241 timeo = reset_timeo;
1242 chip->erase_suspended = 0; 1242 chip->erase_suspended = 0;
1243 }
1244 if (chip->write_suspended && chip_state == FL_WRITING) {
1245 /* Write suspend occured while sleep: reset timeout */
1246 timeo = reset_timeo;
1243 chip->write_suspended = 0; 1247 chip->write_suspended = 0;
1244 } 1248 }
1245 } 1249 }
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 94bb61e19047..61ea833e0908 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -282,6 +282,16 @@ static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param)
282 } 282 }
283} 283}
284 284
285static void fixup_M29W128G_write_buffer(struct mtd_info *mtd, void *param)
286{
287 struct map_info *map = mtd->priv;
288 struct cfi_private *cfi = map->fldrv_priv;
289 if (cfi->cfiq->BufWriteTimeoutTyp) {
290 pr_warning("Don't use write buffer on ST flash M29W128G\n");
291 cfi->cfiq->BufWriteTimeoutTyp = 0;
292 }
293}
294
285static struct cfi_fixup cfi_fixup_table[] = { 295static struct cfi_fixup cfi_fixup_table[] = {
286 { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, 296 { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
287#ifdef AMD_BOOTLOC_BUG 297#ifdef AMD_BOOTLOC_BUG
@@ -298,6 +308,7 @@ static struct cfi_fixup cfi_fixup_table[] = {
298 { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, }, 308 { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, },
299 { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, }, 309 { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, },
300 { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, }, 310 { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, },
311 { CFI_MFR_ST, 0x227E, fixup_M29W128G_write_buffer, NULL, },
301#if !FORCE_WORD_WRITE 312#if !FORCE_WORD_WRITE
302 { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, 313 { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, },
303#endif 314#endif
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index 2f3f2f719ba4..e824b9b9b056 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -159,6 +159,7 @@
159#define SST39LF800 0x2781 159#define SST39LF800 0x2781
160#define SST39LF160 0x2782 160#define SST39LF160 0x2782
161#define SST39VF1601 0x234b 161#define SST39VF1601 0x234b
162#define SST39VF3201 0x235b
162#define SST39LF512 0x00D4 163#define SST39LF512 0x00D4
163#define SST39LF010 0x00D5 164#define SST39LF010 0x00D5
164#define SST39LF020 0x00D6 165#define SST39LF020 0x00D6
@@ -1490,6 +1491,21 @@ static const struct amd_flash_info jedec_table[] = {
1490 ERASEINFO(0x1000,256) 1491 ERASEINFO(0x1000,256)
1491 } 1492 }
1492 }, { 1493 }, {
1494 .mfr_id = MANUFACTURER_SST, /* should be CFI */
1495 .dev_id = SST39VF3201,
1496 .name = "SST 39VF3201",
1497 .devtypes = CFI_DEVICETYPE_X16,
1498 .uaddr = MTD_UADDR_0xAAAA_0x5555,
1499 .dev_size = SIZE_4MiB,
1500 .cmd_set = P_ID_AMD_STD,
1501 .nr_regions = 4,
1502 .regions = {
1503 ERASEINFO(0x1000,256),
1504 ERASEINFO(0x1000,256),
1505 ERASEINFO(0x1000,256),
1506 ERASEINFO(0x1000,256)
1507 }
1508 }, {
1493 .mfr_id = MANUFACTURER_SST, 1509 .mfr_id = MANUFACTURER_SST,
1494 .dev_id = SST36VF3203, 1510 .dev_id = SST36VF3203,
1495 .name = "SST 36VF3203", 1511 .name = "SST 36VF3203",
diff --git a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c
index 072dd8abf33a..6bdc50c727e7 100644
--- a/drivers/mtd/chips/map_ram.c
+++ b/drivers/mtd/chips/map_ram.c
@@ -21,6 +21,8 @@ static int mapram_write (struct mtd_info *, loff_t, size_t, size_t *, const u_ch
21static int mapram_erase (struct mtd_info *, struct erase_info *); 21static int mapram_erase (struct mtd_info *, struct erase_info *);
22static void mapram_nop (struct mtd_info *); 22static void mapram_nop (struct mtd_info *);
23static struct mtd_info *map_ram_probe(struct map_info *map); 23static struct mtd_info *map_ram_probe(struct map_info *map);
24static unsigned long mapram_unmapped_area(struct mtd_info *, unsigned long,
25 unsigned long, unsigned long);
24 26
25 27
26static struct mtd_chip_driver mapram_chipdrv = { 28static struct mtd_chip_driver mapram_chipdrv = {
@@ -64,6 +66,7 @@ static struct mtd_info *map_ram_probe(struct map_info *map)
64 mtd->type = MTD_RAM; 66 mtd->type = MTD_RAM;
65 mtd->size = map->size; 67 mtd->size = map->size;
66 mtd->erase = mapram_erase; 68 mtd->erase = mapram_erase;
69 mtd->get_unmapped_area = mapram_unmapped_area;
67 mtd->read = mapram_read; 70 mtd->read = mapram_read;
68 mtd->write = mapram_write; 71 mtd->write = mapram_write;
69 mtd->sync = mapram_nop; 72 mtd->sync = mapram_nop;
@@ -79,6 +82,20 @@ static struct mtd_info *map_ram_probe(struct map_info *map)
79} 82}
80 83
81 84
85/*
86 * Allow NOMMU mmap() to directly map the device (if not NULL)
87 * - return the address to which the offset maps
88 * - return -ENOSYS to indicate refusal to do the mapping
89 */
90static unsigned long mapram_unmapped_area(struct mtd_info *mtd,
91 unsigned long len,
92 unsigned long offset,
93 unsigned long flags)
94{
95 struct map_info *map = mtd->priv;
96 return (unsigned long) map->virt + offset;
97}
98
82static int mapram_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) 99static int mapram_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
83{ 100{
84 struct map_info *map = mtd->priv; 101 struct map_info *map = mtd->priv;
diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c
index 821d0ed6bae3..076090a67b90 100644
--- a/drivers/mtd/chips/map_rom.c
+++ b/drivers/mtd/chips/map_rom.c
@@ -19,6 +19,9 @@ static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
19static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *); 19static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
20static void maprom_nop (struct mtd_info *); 20static void maprom_nop (struct mtd_info *);
21static struct mtd_info *map_rom_probe(struct map_info *map); 21static struct mtd_info *map_rom_probe(struct map_info *map);
22static int maprom_erase (struct mtd_info *mtd, struct erase_info *info);
23static unsigned long maprom_unmapped_area(struct mtd_info *, unsigned long,
24 unsigned long, unsigned long);
22 25
23static struct mtd_chip_driver maprom_chipdrv = { 26static struct mtd_chip_driver maprom_chipdrv = {
24 .probe = map_rom_probe, 27 .probe = map_rom_probe,
@@ -39,9 +42,11 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
39 mtd->name = map->name; 42 mtd->name = map->name;
40 mtd->type = MTD_ROM; 43 mtd->type = MTD_ROM;
41 mtd->size = map->size; 44 mtd->size = map->size;
45 mtd->get_unmapped_area = maprom_unmapped_area;
42 mtd->read = maprom_read; 46 mtd->read = maprom_read;
43 mtd->write = maprom_write; 47 mtd->write = maprom_write;
44 mtd->sync = maprom_nop; 48 mtd->sync = maprom_nop;
49 mtd->erase = maprom_erase;
45 mtd->flags = MTD_CAP_ROM; 50 mtd->flags = MTD_CAP_ROM;
46 mtd->erasesize = map->size; 51 mtd->erasesize = map->size;
47 mtd->writesize = 1; 52 mtd->writesize = 1;
@@ -51,6 +56,20 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
51} 56}
52 57
53 58
59/*
60 * Allow NOMMU mmap() to directly map the device (if not NULL)
61 * - return the address to which the offset maps
62 * - return -ENOSYS to indicate refusal to do the mapping
63 */
64static unsigned long maprom_unmapped_area(struct mtd_info *mtd,
65 unsigned long len,
66 unsigned long offset,
67 unsigned long flags)
68{
69 struct map_info *map = mtd->priv;
70 return (unsigned long) map->virt + offset;
71}
72
54static int maprom_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) 73static int maprom_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
55{ 74{
56 struct map_info *map = mtd->priv; 75 struct map_info *map = mtd->priv;
@@ -71,6 +90,12 @@ static int maprom_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *re
71 return -EIO; 90 return -EIO;
72} 91}
73 92
93static int maprom_erase (struct mtd_info *mtd, struct erase_info *info)
94{
95 /* We do our best 8) */
96 return -EROFS;
97}
98
74static int __init map_rom_init(void) 99static int __init map_rom_init(void)
75{ 100{
76 register_mtd_chip_driver(&maprom_chipdrv); 101 register_mtd_chip_driver(&maprom_chipdrv);
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index 50a340388e74..5011fa73f918 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -335,7 +335,11 @@ static int parse_cmdline_partitions(struct mtd_info *master,
335 } 335 }
336 offset += part->parts[i].size; 336 offset += part->parts[i].size;
337 } 337 }
338 *pparts = part->parts; 338 *pparts = kmemdup(part->parts,
339 sizeof(*part->parts) * part->num_parts,
340 GFP_KERNEL);
341 if (!*pparts)
342 return -ENOMEM;
339 return part->num_parts; 343 return part->num_parts;
340 } 344 }
341 } 345 }
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index bc33200535fc..6fde0a2e3567 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -120,13 +120,6 @@ config MTD_PHRAM
120 doesn't have access to, memory beyond the mem=xxx limit, nvram, 120 doesn't have access to, memory beyond the mem=xxx limit, nvram,
121 memory on the video card, etc... 121 memory on the video card, etc...
122 122
123config MTD_PS3VRAM
124 tristate "PS3 video RAM"
125 depends on FB_PS3
126 help
127 This driver allows you to use excess PS3 video RAM as volatile
128 storage or system swap.
129
130config MTD_LART 123config MTD_LART
131 tristate "28F160xx flash driver for LART" 124 tristate "28F160xx flash driver for LART"
132 depends on SA1100_LART 125 depends on SA1100_LART
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index e51521df4e40..0993d5cf3923 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -16,4 +16,3 @@ obj-$(CONFIG_MTD_LART) += lart.o
16obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o 16obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o
17obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o 17obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o
18obj-$(CONFIG_MTD_M25P80) += m25p80.o 18obj-$(CONFIG_MTD_M25P80) += m25p80.o
19obj-$(CONFIG_MTD_PS3VRAM) += ps3vram.o
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index 50de839c77a9..5bf5f460e132 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -10,7 +10,6 @@
10#include <asm/errno.h> 10#include <asm/errno.h>
11#include <asm/io.h> 11#include <asm/io.h>
12#include <asm/uaccess.h> 12#include <asm/uaccess.h>
13#include <linux/miscdevice.h>
14#include <linux/delay.h> 13#include <linux/delay.h>
15#include <linux/slab.h> 14#include <linux/slab.h>
16#include <linux/sched.h> 15#include <linux/sched.h>
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index e32c568c1145..0990f7803628 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -10,7 +10,6 @@
10#include <asm/errno.h> 10#include <asm/errno.h>
11#include <asm/io.h> 11#include <asm/io.h>
12#include <asm/uaccess.h> 12#include <asm/uaccess.h>
13#include <linux/miscdevice.h>
14#include <linux/delay.h> 13#include <linux/delay.h>
15#include <linux/slab.h> 14#include <linux/slab.h>
16#include <linux/init.h> 15#include <linux/init.h>
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index d853f891b586..719b2915dc3a 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -14,7 +14,6 @@
14#include <asm/errno.h> 14#include <asm/errno.h>
15#include <asm/io.h> 15#include <asm/io.h>
16#include <asm/uaccess.h> 16#include <asm/uaccess.h>
17#include <linux/miscdevice.h>
18#include <linux/delay.h> 17#include <linux/delay.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
20#include <linux/init.h> 19#include <linux/init.h>
diff --git a/drivers/mtd/devices/docecc.c b/drivers/mtd/devices/docecc.c
index 874e51b110a2..a19cda52da5c 100644
--- a/drivers/mtd/devices/docecc.c
+++ b/drivers/mtd/devices/docecc.c
@@ -26,7 +26,6 @@
26#include <asm/errno.h> 26#include <asm/errno.h>
27#include <asm/io.h> 27#include <asm/io.h>
28#include <asm/uaccess.h> 28#include <asm/uaccess.h>
29#include <linux/miscdevice.h>
30#include <linux/delay.h> 29#include <linux/delay.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
32#include <linux/init.h> 31#include <linux/init.h>
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 7c3fc766dcf1..8185b1f3e5e6 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -65,12 +65,6 @@
65#define FAST_READ_DUMMY_BYTE 0 65#define FAST_READ_DUMMY_BYTE 0
66#endif 66#endif
67 67
68#ifdef CONFIG_MTD_PARTITIONS
69#define mtd_has_partitions() (1)
70#else
71#define mtd_has_partitions() (0)
72#endif
73
74/****************************************************************************/ 68/****************************************************************************/
75 69
76struct m25p { 70struct m25p {
@@ -678,6 +672,8 @@ static int __devinit m25p_probe(struct spi_device *spi)
678 flash->mtd.erasesize = info->sector_size; 672 flash->mtd.erasesize = info->sector_size;
679 } 673 }
680 674
675 flash->mtd.dev.parent = &spi->dev;
676
681 dev_info(&spi->dev, "%s (%lld Kbytes)\n", info->name, 677 dev_info(&spi->dev, "%s (%lld Kbytes)\n", info->name,
682 (long long)flash->mtd.size >> 10); 678 (long long)flash->mtd.size >> 10);
683 679
@@ -708,12 +704,13 @@ static int __devinit m25p_probe(struct spi_device *spi)
708 struct mtd_partition *parts = NULL; 704 struct mtd_partition *parts = NULL;
709 int nr_parts = 0; 705 int nr_parts = 0;
710 706
711#ifdef CONFIG_MTD_CMDLINE_PARTS 707 if (mtd_has_cmdlinepart()) {
712 static const char *part_probes[] = { "cmdlinepart", NULL, }; 708 static const char *part_probes[]
709 = { "cmdlinepart", NULL, };
713 710
714 nr_parts = parse_mtd_partitions(&flash->mtd, 711 nr_parts = parse_mtd_partitions(&flash->mtd,
715 part_probes, &parts, 0); 712 part_probes, &parts, 0);
716#endif 713 }
717 714
718 if (nr_parts <= 0 && data && data->parts) { 715 if (nr_parts <= 0 && data && data->parts) {
719 parts = data->parts; 716 parts = data->parts;
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index d44f741ae229..62dee54af0a5 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -98,12 +98,6 @@ struct dataflash {
98 struct mtd_info mtd; 98 struct mtd_info mtd;
99}; 99};
100 100
101#ifdef CONFIG_MTD_PARTITIONS
102#define mtd_has_partitions() (1)
103#else
104#define mtd_has_partitions() (0)
105#endif
106
107/* ......................................................................... */ 101/* ......................................................................... */
108 102
109/* 103/*
@@ -670,6 +664,8 @@ add_dataflash_otp(struct spi_device *spi, char *name,
670 device->write = dataflash_write; 664 device->write = dataflash_write;
671 device->priv = priv; 665 device->priv = priv;
672 666
667 device->dev.parent = &spi->dev;
668
673 if (revision >= 'c') 669 if (revision >= 'c')
674 otp_tag = otp_setup(device, revision); 670 otp_tag = otp_setup(device, revision);
675 671
@@ -682,11 +678,13 @@ add_dataflash_otp(struct spi_device *spi, char *name,
682 struct mtd_partition *parts; 678 struct mtd_partition *parts;
683 int nr_parts = 0; 679 int nr_parts = 0;
684 680
685#ifdef CONFIG_MTD_CMDLINE_PARTS 681 if (mtd_has_cmdlinepart()) {
686 static const char *part_probes[] = { "cmdlinepart", NULL, }; 682 static const char *part_probes[]
683 = { "cmdlinepart", NULL, };
687 684
688 nr_parts = parse_mtd_partitions(device, part_probes, &parts, 0); 685 nr_parts = parse_mtd_partitions(device,
689#endif 686 part_probes, &parts, 0);
687 }
690 688
691 if (nr_parts <= 0 && pdata && pdata->parts) { 689 if (nr_parts <= 0 && pdata && pdata->parts) {
692 parts = pdata->parts; 690 parts = pdata->parts;
@@ -821,7 +819,8 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
821 if (!(info->flags & IS_POW2PS)) 819 if (!(info->flags & IS_POW2PS))
822 return info; 820 return info;
823 } 821 }
824 } 822 } else
823 return info;
825 } 824 }
826 } 825 }
827 826
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c
index 3aaca88847d3..fce5ff7589aa 100644
--- a/drivers/mtd/devices/mtdram.c
+++ b/drivers/mtd/devices/mtdram.c
@@ -65,6 +65,19 @@ static void ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
65{ 65{
66} 66}
67 67
68/*
69 * Allow NOMMU mmap() to directly map the device (if not NULL)
70 * - return the address to which the offset maps
71 * - return -ENOSYS to indicate refusal to do the mapping
72 */
73static unsigned long ram_get_unmapped_area(struct mtd_info *mtd,
74 unsigned long len,
75 unsigned long offset,
76 unsigned long flags)
77{
78 return (unsigned long) mtd->priv + offset;
79}
80
68static int ram_read(struct mtd_info *mtd, loff_t from, size_t len, 81static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
69 size_t *retlen, u_char *buf) 82 size_t *retlen, u_char *buf)
70{ 83{
@@ -116,6 +129,7 @@ int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
116 mtd->erase = ram_erase; 129 mtd->erase = ram_erase;
117 mtd->point = ram_point; 130 mtd->point = ram_point;
118 mtd->unpoint = ram_unpoint; 131 mtd->unpoint = ram_unpoint;
132 mtd->get_unmapped_area = ram_get_unmapped_area;
119 mtd->read = ram_read; 133 mtd->read = ram_read;
120 mtd->write = ram_write; 134 mtd->write = ram_write;
121 135
diff --git a/drivers/mtd/devices/ps3vram.c b/drivers/mtd/devices/ps3vram.c
deleted file mode 100644
index d21e9beb7ed2..000000000000
--- a/drivers/mtd/devices/ps3vram.c
+++ /dev/null
@@ -1,768 +0,0 @@
1/**
2 * ps3vram - Use extra PS3 video ram as MTD block device.
3 *
4 * Copyright (c) 2007-2008 Jim Paris <jim@jtan.com>
5 * Added support RSX DMA Vivien Chappelier <vivien.chappelier@free.fr>
6 */
7
8#include <linux/io.h>
9#include <linux/mm.h>
10#include <linux/init.h>
11#include <linux/kernel.h>
12#include <linux/list.h>
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/slab.h>
16#include <linux/version.h>
17#include <linux/gfp.h>
18#include <linux/delay.h>
19#include <linux/mtd/mtd.h>
20
21#include <asm/lv1call.h>
22#include <asm/ps3.h>
23
24#define DEVICE_NAME "ps3vram"
25
26#define XDR_BUF_SIZE (2 * 1024 * 1024) /* XDR buffer (must be 1MiB aligned) */
27#define XDR_IOIF 0x0c000000
28
29#define FIFO_BASE XDR_IOIF
30#define FIFO_SIZE (64 * 1024)
31
32#define DMA_PAGE_SIZE (4 * 1024)
33
34#define CACHE_PAGE_SIZE (256 * 1024)
35#define CACHE_PAGE_COUNT ((XDR_BUF_SIZE - FIFO_SIZE) / CACHE_PAGE_SIZE)
36
37#define CACHE_OFFSET CACHE_PAGE_SIZE
38#define FIFO_OFFSET 0
39
40#define CTRL_PUT 0x10
41#define CTRL_GET 0x11
42#define CTRL_TOP 0x15
43
44#define UPLOAD_SUBCH 1
45#define DOWNLOAD_SUBCH 2
46
47#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c
48#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104
49
50#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601
51
52struct mtd_info ps3vram_mtd;
53
54#define CACHE_PAGE_PRESENT 1
55#define CACHE_PAGE_DIRTY 2
56
57struct ps3vram_tag {
58 unsigned int address;
59 unsigned int flags;
60};
61
62struct ps3vram_cache {
63 unsigned int page_count;
64 unsigned int page_size;
65 struct ps3vram_tag *tags;
66};
67
68struct ps3vram_priv {
69 u64 memory_handle;
70 u64 context_handle;
71 u32 *ctrl;
72 u32 *reports;
73 u8 __iomem *ddr_base;
74 u8 *xdr_buf;
75
76 u32 *fifo_base;
77 u32 *fifo_ptr;
78
79 struct device *dev;
80 struct ps3vram_cache cache;
81
82 /* Used to serialize cache/DMA operations */
83 struct mutex lock;
84};
85
86#define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */
87#define DMA_NOTIFIER_OFFSET_BASE 0x1000 /* first DMA notifier offset */
88#define DMA_NOTIFIER_SIZE 0x40
89#define NOTIFIER 7 /* notifier used for completion report */
90
91/* A trailing '-' means to subtract off ps3fb_videomemory.size */
92char *size = "256M-";
93module_param(size, charp, 0);
94MODULE_PARM_DESC(size, "memory size");
95
96static u32 *ps3vram_get_notifier(u32 *reports, int notifier)
97{
98 return (void *) reports +
99 DMA_NOTIFIER_OFFSET_BASE +
100 DMA_NOTIFIER_SIZE * notifier;
101}
102
103static void ps3vram_notifier_reset(struct mtd_info *mtd)
104{
105 int i;
106
107 struct ps3vram_priv *priv = mtd->priv;
108 u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
109 for (i = 0; i < 4; i++)
110 notify[i] = 0xffffffff;
111}
112
113static int ps3vram_notifier_wait(struct mtd_info *mtd, unsigned int timeout_ms)
114{
115 struct ps3vram_priv *priv = mtd->priv;
116 u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
117 unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
118
119 do {
120 if (!notify[3])
121 return 0;
122 msleep(1);
123 } while (time_before(jiffies, timeout));
124
125 return -ETIMEDOUT;
126}
127
128static void ps3vram_init_ring(struct mtd_info *mtd)
129{
130 struct ps3vram_priv *priv = mtd->priv;
131
132 priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
133 priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET;
134}
135
136static int ps3vram_wait_ring(struct mtd_info *mtd, unsigned int timeout_ms)
137{
138 struct ps3vram_priv *priv = mtd->priv;
139 unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
140
141 do {
142 if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET])
143 return 0;
144 msleep(1);
145 } while (time_before(jiffies, timeout));
146
147 dev_dbg(priv->dev, "%s:%d: FIFO timeout (%08x/%08x/%08x)\n", __func__,
148 __LINE__, priv->ctrl[CTRL_PUT], priv->ctrl[CTRL_GET],
149 priv->ctrl[CTRL_TOP]);
150
151 return -ETIMEDOUT;
152}
153
154static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data)
155{
156 *(priv->fifo_ptr)++ = data;
157}
158
159static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan,
160 u32 tag, u32 size)
161{
162 ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag);
163}
164
165static void ps3vram_rewind_ring(struct mtd_info *mtd)
166{
167 struct ps3vram_priv *priv = mtd->priv;
168 u64 status;
169
170 ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET));
171
172 priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
173
174 /* asking the HV for a blit will kick the fifo */
175 status = lv1_gpu_context_attribute(priv->context_handle,
176 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
177 0, 0, 0, 0);
178 if (status)
179 dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n",
180 __func__, __LINE__);
181
182 priv->fifo_ptr = priv->fifo_base;
183}
184
185static void ps3vram_fire_ring(struct mtd_info *mtd)
186{
187 struct ps3vram_priv *priv = mtd->priv;
188 u64 status;
189
190 mutex_lock(&ps3_gpu_mutex);
191
192 priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET +
193 (priv->fifo_ptr - priv->fifo_base) * sizeof(u32);
194
195 /* asking the HV for a blit will kick the fifo */
196 status = lv1_gpu_context_attribute(priv->context_handle,
197 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
198 0, 0, 0, 0);
199 if (status)
200 dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n",
201 __func__, __LINE__);
202
203 if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) >
204 FIFO_SIZE - 1024) {
205 dev_dbg(priv->dev, "%s:%d: fifo full, rewinding\n", __func__,
206 __LINE__);
207 ps3vram_wait_ring(mtd, 200);
208 ps3vram_rewind_ring(mtd);
209 }
210
211 mutex_unlock(&ps3_gpu_mutex);
212}
213
214static void ps3vram_bind(struct mtd_info *mtd)
215{
216 struct ps3vram_priv *priv = mtd->priv;
217
218 ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1);
219 ps3vram_out_ring(priv, 0x31337303);
220 ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x180, 3);
221 ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER);
222 ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */
223 ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */
224
225 ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0, 1);
226 ps3vram_out_ring(priv, 0x3137c0de);
227 ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x180, 3);
228 ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER);
229 ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */
230 ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */
231
232 ps3vram_fire_ring(mtd);
233}
234
235static int ps3vram_upload(struct mtd_info *mtd, unsigned int src_offset,
236 unsigned int dst_offset, int len, int count)
237{
238 struct ps3vram_priv *priv = mtd->priv;
239
240 ps3vram_begin_ring(priv, UPLOAD_SUBCH,
241 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
242 ps3vram_out_ring(priv, XDR_IOIF + src_offset);
243 ps3vram_out_ring(priv, dst_offset);
244 ps3vram_out_ring(priv, len);
245 ps3vram_out_ring(priv, len);
246 ps3vram_out_ring(priv, len);
247 ps3vram_out_ring(priv, count);
248 ps3vram_out_ring(priv, (1 << 8) | 1);
249 ps3vram_out_ring(priv, 0);
250
251 ps3vram_notifier_reset(mtd);
252 ps3vram_begin_ring(priv, UPLOAD_SUBCH,
253 NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
254 ps3vram_out_ring(priv, 0);
255 ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x100, 1);
256 ps3vram_out_ring(priv, 0);
257 ps3vram_fire_ring(mtd);
258 if (ps3vram_notifier_wait(mtd, 200) < 0) {
259 dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__,
260 __LINE__);
261 return -1;
262 }
263
264 return 0;
265}
266
267static int ps3vram_download(struct mtd_info *mtd, unsigned int src_offset,
268 unsigned int dst_offset, int len, int count)
269{
270 struct ps3vram_priv *priv = mtd->priv;
271
272 ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
273 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
274 ps3vram_out_ring(priv, src_offset);
275 ps3vram_out_ring(priv, XDR_IOIF + dst_offset);
276 ps3vram_out_ring(priv, len);
277 ps3vram_out_ring(priv, len);
278 ps3vram_out_ring(priv, len);
279 ps3vram_out_ring(priv, count);
280 ps3vram_out_ring(priv, (1 << 8) | 1);
281 ps3vram_out_ring(priv, 0);
282
283 ps3vram_notifier_reset(mtd);
284 ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
285 NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
286 ps3vram_out_ring(priv, 0);
287 ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x100, 1);
288 ps3vram_out_ring(priv, 0);
289 ps3vram_fire_ring(mtd);
290 if (ps3vram_notifier_wait(mtd, 200) < 0) {
291 dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__,
292 __LINE__);
293 return -1;
294 }
295
296 return 0;
297}
298
299static void ps3vram_cache_evict(struct mtd_info *mtd, int entry)
300{
301 struct ps3vram_priv *priv = mtd->priv;
302 struct ps3vram_cache *cache = &priv->cache;
303
304 if (cache->tags[entry].flags & CACHE_PAGE_DIRTY) {
305 dev_dbg(priv->dev, "%s:%d: flushing %d : 0x%08x\n", __func__,
306 __LINE__, entry, cache->tags[entry].address);
307 if (ps3vram_upload(mtd,
308 CACHE_OFFSET + entry * cache->page_size,
309 cache->tags[entry].address,
310 DMA_PAGE_SIZE,
311 cache->page_size / DMA_PAGE_SIZE) < 0) {
312 dev_dbg(priv->dev, "%s:%d: failed to upload from "
313 "0x%x to 0x%x size 0x%x\n", __func__, __LINE__,
314 entry * cache->page_size,
315 cache->tags[entry].address, cache->page_size);
316 }
317 cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY;
318 }
319}
320
321static void ps3vram_cache_load(struct mtd_info *mtd, int entry,
322 unsigned int address)
323{
324 struct ps3vram_priv *priv = mtd->priv;
325 struct ps3vram_cache *cache = &priv->cache;
326
327 dev_dbg(priv->dev, "%s:%d: fetching %d : 0x%08x\n", __func__, __LINE__,
328 entry, address);
329 if (ps3vram_download(mtd,
330 address,
331 CACHE_OFFSET + entry * cache->page_size,
332 DMA_PAGE_SIZE,
333 cache->page_size / DMA_PAGE_SIZE) < 0) {
334 dev_err(priv->dev, "%s:%d: failed to download from "
335 "0x%x to 0x%x size 0x%x\n", __func__, __LINE__, address,
336 entry * cache->page_size, cache->page_size);
337 }
338
339 cache->tags[entry].address = address;
340 cache->tags[entry].flags |= CACHE_PAGE_PRESENT;
341}
342
343
344static void ps3vram_cache_flush(struct mtd_info *mtd)
345{
346 struct ps3vram_priv *priv = mtd->priv;
347 struct ps3vram_cache *cache = &priv->cache;
348 int i;
349
350 dev_dbg(priv->dev, "%s:%d: FLUSH\n", __func__, __LINE__);
351 for (i = 0; i < cache->page_count; i++) {
352 ps3vram_cache_evict(mtd, i);
353 cache->tags[i].flags = 0;
354 }
355}
356
357static unsigned int ps3vram_cache_match(struct mtd_info *mtd, loff_t address)
358{
359 struct ps3vram_priv *priv = mtd->priv;
360 struct ps3vram_cache *cache = &priv->cache;
361 unsigned int base;
362 unsigned int offset;
363 int i;
364 static int counter;
365
366 offset = (unsigned int) (address & (cache->page_size - 1));
367 base = (unsigned int) (address - offset);
368
369 /* fully associative check */
370 for (i = 0; i < cache->page_count; i++) {
371 if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) &&
372 cache->tags[i].address == base) {
373 dev_dbg(priv->dev, "%s:%d: found entry %d : 0x%08x\n",
374 __func__, __LINE__, i, cache->tags[i].address);
375 return i;
376 }
377 }
378
379 /* choose a random entry */
380 i = (jiffies + (counter++)) % cache->page_count;
381 dev_dbg(priv->dev, "%s:%d: using entry %d\n", __func__, __LINE__, i);
382
383 ps3vram_cache_evict(mtd, i);
384 ps3vram_cache_load(mtd, i, base);
385
386 return i;
387}
388
389static int ps3vram_cache_init(struct mtd_info *mtd)
390{
391 struct ps3vram_priv *priv = mtd->priv;
392
393 priv->cache.page_count = CACHE_PAGE_COUNT;
394 priv->cache.page_size = CACHE_PAGE_SIZE;
395 priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) *
396 CACHE_PAGE_COUNT, GFP_KERNEL);
397 if (priv->cache.tags == NULL) {
398 dev_err(priv->dev, "%s:%d: could not allocate cache tags\n",
399 __func__, __LINE__);
400 return -ENOMEM;
401 }
402
403 dev_info(priv->dev, "created ram cache: %d entries, %d KiB each\n",
404 CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024);
405
406 return 0;
407}
408
409static void ps3vram_cache_cleanup(struct mtd_info *mtd)
410{
411 struct ps3vram_priv *priv = mtd->priv;
412
413 ps3vram_cache_flush(mtd);
414 kfree(priv->cache.tags);
415}
416
417static int ps3vram_erase(struct mtd_info *mtd, struct erase_info *instr)
418{
419 struct ps3vram_priv *priv = mtd->priv;
420
421 if (instr->addr + instr->len > mtd->size)
422 return -EINVAL;
423
424 mutex_lock(&priv->lock);
425
426 ps3vram_cache_flush(mtd);
427
428 /* Set bytes to 0xFF */
429 memset_io(priv->ddr_base + instr->addr, 0xFF, instr->len);
430
431 mutex_unlock(&priv->lock);
432
433 instr->state = MTD_ERASE_DONE;
434 mtd_erase_callback(instr);
435
436 return 0;
437}
438
439static int ps3vram_read(struct mtd_info *mtd, loff_t from, size_t len,
440 size_t *retlen, u_char *buf)
441{
442 struct ps3vram_priv *priv = mtd->priv;
443 unsigned int cached, count;
444
445 dev_dbg(priv->dev, "%s:%d: from=0x%08x len=0x%zx\n", __func__, __LINE__,
446 (unsigned int)from, len);
447
448 if (from >= mtd->size)
449 return -EINVAL;
450
451 if (len > mtd->size - from)
452 len = mtd->size - from;
453
454 /* Copy from vram to buf */
455 count = len;
456 while (count) {
457 unsigned int offset, avail;
458 unsigned int entry;
459
460 offset = (unsigned int) (from & (priv->cache.page_size - 1));
461 avail = priv->cache.page_size - offset;
462
463 mutex_lock(&priv->lock);
464
465 entry = ps3vram_cache_match(mtd, from);
466 cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
467
468 dev_dbg(priv->dev, "%s:%d: from=%08x cached=%08x offset=%08x "
469 "avail=%08x count=%08x\n", __func__, __LINE__,
470 (unsigned int)from, cached, offset, avail, count);
471
472 if (avail > count)
473 avail = count;
474 memcpy(buf, priv->xdr_buf + cached, avail);
475
476 mutex_unlock(&priv->lock);
477
478 buf += avail;
479 count -= avail;
480 from += avail;
481 }
482
483 *retlen = len;
484 return 0;
485}
486
487static int ps3vram_write(struct mtd_info *mtd, loff_t to, size_t len,
488 size_t *retlen, const u_char *buf)
489{
490 struct ps3vram_priv *priv = mtd->priv;
491 unsigned int cached, count;
492
493 if (to >= mtd->size)
494 return -EINVAL;
495
496 if (len > mtd->size - to)
497 len = mtd->size - to;
498
499 /* Copy from buf to vram */
500 count = len;
501 while (count) {
502 unsigned int offset, avail;
503 unsigned int entry;
504
505 offset = (unsigned int) (to & (priv->cache.page_size - 1));
506 avail = priv->cache.page_size - offset;
507
508 mutex_lock(&priv->lock);
509
510 entry = ps3vram_cache_match(mtd, to);
511 cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
512
513 dev_dbg(priv->dev, "%s:%d: to=%08x cached=%08x offset=%08x "
514 "avail=%08x count=%08x\n", __func__, __LINE__,
515 (unsigned int)to, cached, offset, avail, count);
516
517 if (avail > count)
518 avail = count;
519 memcpy(priv->xdr_buf + cached, buf, avail);
520
521 priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY;
522
523 mutex_unlock(&priv->lock);
524
525 buf += avail;
526 count -= avail;
527 to += avail;
528 }
529
530 *retlen = len;
531 return 0;
532}
533
534static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
535{
536 struct ps3vram_priv *priv;
537 int status;
538 u64 ddr_lpar;
539 u64 ctrl_lpar;
540 u64 info_lpar;
541 u64 reports_lpar;
542 u64 ddr_size;
543 u64 reports_size;
544 int ret = -ENOMEM;
545 char *rest;
546
547 ret = -EIO;
548 ps3vram_mtd.priv = kzalloc(sizeof(struct ps3vram_priv), GFP_KERNEL);
549 if (!ps3vram_mtd.priv)
550 goto out;
551 priv = ps3vram_mtd.priv;
552
553 mutex_init(&priv->lock);
554 priv->dev = &dev->core;
555
556 /* Allocate XDR buffer (1MiB aligned) */
557 priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL,
558 get_order(XDR_BUF_SIZE));
559 if (priv->xdr_buf == NULL) {
560 dev_dbg(&dev->core, "%s:%d: could not allocate XDR buffer\n",
561 __func__, __LINE__);
562 ret = -ENOMEM;
563 goto out_free_priv;
564 }
565
566 /* Put FIFO at begginning of XDR buffer */
567 priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET);
568 priv->fifo_ptr = priv->fifo_base;
569
570 /* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */
571 if (ps3_open_hv_device(dev)) {
572 dev_err(&dev->core, "%s:%d: ps3_open_hv_device failed\n",
573 __func__, __LINE__);
574 ret = -EAGAIN;
575 goto out_close_gpu;
576 }
577
578 /* Request memory */
579 status = -1;
580 ddr_size = memparse(size, &rest);
581 if (*rest == '-')
582 ddr_size -= ps3fb_videomemory.size;
583 ddr_size = ALIGN(ddr_size, 1024*1024);
584 if (ddr_size <= 0) {
585 dev_err(&dev->core, "%s:%d: specified size is too small\n",
586 __func__, __LINE__);
587 ret = -EINVAL;
588 goto out_close_gpu;
589 }
590
591 while (ddr_size > 0) {
592 status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0,
593 &priv->memory_handle,
594 &ddr_lpar);
595 if (!status)
596 break;
597 ddr_size -= 1024*1024;
598 }
599 if (status || ddr_size <= 0) {
600 dev_err(&dev->core, "%s:%d: lv1_gpu_memory_allocate failed\n",
601 __func__, __LINE__);
602 ret = -ENOMEM;
603 goto out_free_xdr_buf;
604 }
605
606 /* Request context */
607 status = lv1_gpu_context_allocate(priv->memory_handle,
608 0,
609 &priv->context_handle,
610 &ctrl_lpar,
611 &info_lpar,
612 &reports_lpar,
613 &reports_size);
614 if (status) {
615 dev_err(&dev->core, "%s:%d: lv1_gpu_context_allocate failed\n",
616 __func__, __LINE__);
617 ret = -ENOMEM;
618 goto out_free_memory;
619 }
620
621 /* Map XDR buffer to RSX */
622 status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF,
623 ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)),
624 XDR_BUF_SIZE, 0);
625 if (status) {
626 dev_err(&dev->core, "%s:%d: lv1_gpu_context_iomap failed\n",
627 __func__, __LINE__);
628 ret = -ENOMEM;
629 goto out_free_context;
630 }
631
632 priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE);
633
634 if (!priv->ddr_base) {
635 dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__,
636 __LINE__);
637 ret = -ENOMEM;
638 goto out_free_context;
639 }
640
641 priv->ctrl = ioremap(ctrl_lpar, 64 * 1024);
642 if (!priv->ctrl) {
643 dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__,
644 __LINE__);
645 ret = -ENOMEM;
646 goto out_unmap_vram;
647 }
648
649 priv->reports = ioremap(reports_lpar, reports_size);
650 if (!priv->reports) {
651 dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__,
652 __LINE__);
653 ret = -ENOMEM;
654 goto out_unmap_ctrl;
655 }
656
657 mutex_lock(&ps3_gpu_mutex);
658 ps3vram_init_ring(&ps3vram_mtd);
659 mutex_unlock(&ps3_gpu_mutex);
660
661 ps3vram_mtd.name = "ps3vram";
662 ps3vram_mtd.size = ddr_size;
663 ps3vram_mtd.flags = MTD_CAP_RAM;
664 ps3vram_mtd.erase = ps3vram_erase;
665 ps3vram_mtd.point = NULL;
666 ps3vram_mtd.unpoint = NULL;
667 ps3vram_mtd.read = ps3vram_read;
668 ps3vram_mtd.write = ps3vram_write;
669 ps3vram_mtd.owner = THIS_MODULE;
670 ps3vram_mtd.type = MTD_RAM;
671 ps3vram_mtd.erasesize = CACHE_PAGE_SIZE;
672 ps3vram_mtd.writesize = 1;
673
674 ps3vram_bind(&ps3vram_mtd);
675
676 mutex_lock(&ps3_gpu_mutex);
677 ret = ps3vram_wait_ring(&ps3vram_mtd, 100);
678 mutex_unlock(&ps3_gpu_mutex);
679 if (ret < 0) {
680 dev_err(&dev->core, "%s:%d: failed to initialize channels\n",
681 __func__, __LINE__);
682 ret = -ETIMEDOUT;
683 goto out_unmap_reports;
684 }
685
686 ps3vram_cache_init(&ps3vram_mtd);
687
688 if (add_mtd_device(&ps3vram_mtd)) {
689 dev_err(&dev->core, "%s:%d: add_mtd_device failed\n",
690 __func__, __LINE__);
691 ret = -EAGAIN;
692 goto out_cache_cleanup;
693 }
694
695 dev_info(&dev->core, "reserved %u MiB of gpu memory\n",
696 (unsigned int)(ddr_size / 1024 / 1024));
697
698 return 0;
699
700out_cache_cleanup:
701 ps3vram_cache_cleanup(&ps3vram_mtd);
702out_unmap_reports:
703 iounmap(priv->reports);
704out_unmap_ctrl:
705 iounmap(priv->ctrl);
706out_unmap_vram:
707 iounmap(priv->ddr_base);
708out_free_context:
709 lv1_gpu_context_free(priv->context_handle);
710out_free_memory:
711 lv1_gpu_memory_free(priv->memory_handle);
712out_close_gpu:
713 ps3_close_hv_device(dev);
714out_free_xdr_buf:
715 free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
716out_free_priv:
717 kfree(ps3vram_mtd.priv);
718 ps3vram_mtd.priv = NULL;
719out:
720 return ret;
721}
722
723static int ps3vram_shutdown(struct ps3_system_bus_device *dev)
724{
725 struct ps3vram_priv *priv;
726
727 priv = ps3vram_mtd.priv;
728
729 del_mtd_device(&ps3vram_mtd);
730 ps3vram_cache_cleanup(&ps3vram_mtd);
731 iounmap(priv->reports);
732 iounmap(priv->ctrl);
733 iounmap(priv->ddr_base);
734 lv1_gpu_context_free(priv->context_handle);
735 lv1_gpu_memory_free(priv->memory_handle);
736 ps3_close_hv_device(dev);
737 free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
738 kfree(priv);
739 return 0;
740}
741
742static struct ps3_system_bus_driver ps3vram_driver = {
743 .match_id = PS3_MATCH_ID_GPU,
744 .match_sub_id = PS3_MATCH_SUB_ID_GPU_RAMDISK,
745 .core.name = DEVICE_NAME,
746 .core.owner = THIS_MODULE,
747 .probe = ps3vram_probe,
748 .remove = ps3vram_shutdown,
749 .shutdown = ps3vram_shutdown,
750};
751
752static int __init ps3vram_init(void)
753{
754 return ps3_system_bus_driver_register(&ps3vram_driver);
755}
756
757static void __exit ps3vram_exit(void)
758{
759 ps3_system_bus_driver_unregister(&ps3vram_driver);
760}
761
762module_init(ps3vram_init);
763module_exit(ps3vram_exit);
764
765MODULE_LICENSE("GPL");
766MODULE_AUTHOR("Jim Paris <jim@jtan.com>");
767MODULE_DESCRIPTION("MTD driver for PS3 video RAM");
768MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK);
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index a425d09f35a0..00248e81ecd5 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -267,22 +267,28 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
267 if (*(szlength) != '+') { 267 if (*(szlength) != '+') {
268 devlength = simple_strtoul(szlength, &buffer, 0); 268 devlength = simple_strtoul(szlength, &buffer, 0);
269 devlength = handle_unit(devlength, buffer) - devstart; 269 devlength = handle_unit(devlength, buffer) - devstart;
270 if (devlength < devstart)
271 goto err_out;
272
273 devlength -= devstart;
270 } else { 274 } else {
271 devlength = simple_strtoul(szlength + 1, &buffer, 0); 275 devlength = simple_strtoul(szlength + 1, &buffer, 0);
272 devlength = handle_unit(devlength, buffer); 276 devlength = handle_unit(devlength, buffer);
273 } 277 }
274 T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n", 278 T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
275 devname, devstart, devlength); 279 devname, devstart, devlength);
276 if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) { 280 if (devlength % SLRAM_BLK_SZ != 0)
277 E("slram: Illegal start / length parameter.\n"); 281 goto err_out;
278 return(-EINVAL);
279 }
280 282
281 if ((devstart = register_device(devname, devstart, devlength))){ 283 if ((devstart = register_device(devname, devstart, devlength))){
282 unregister_devices(); 284 unregister_devices();
283 return((int)devstart); 285 return((int)devstart);
284 } 286 }
285 return(0); 287 return(0);
288
289err_out:
290 E("slram: Illegal length parameter.\n");
291 return(-EINVAL);
286} 292}
287 293
288#ifndef MODULE 294#ifndef MODULE
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index f751dd97c549..32e82aef3e53 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -28,7 +28,6 @@
28#include <asm/errno.h> 28#include <asm/errno.h>
29#include <asm/io.h> 29#include <asm/io.h>
30#include <asm/uaccess.h> 30#include <asm/uaccess.h>
31#include <linux/miscdevice.h>
32#include <linux/delay.h> 31#include <linux/delay.h>
33#include <linux/slab.h> 32#include <linux/slab.h>
34#include <linux/init.h> 33#include <linux/init.h>
diff --git a/drivers/mtd/internal.h b/drivers/mtd/internal.h
new file mode 100644
index 000000000000..c658fe7216b5
--- /dev/null
+++ b/drivers/mtd/internal.h
@@ -0,0 +1,17 @@
1/* Internal MTD definitions
2 *
3 * Copyright © 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12/*
13 * mtdbdi.c
14 */
15extern struct backing_dev_info mtd_bdi_unmappable;
16extern struct backing_dev_info mtd_bdi_ro_mappable;
17extern struct backing_dev_info mtd_bdi_rw_mappable;
diff --git a/drivers/mtd/lpddr/Kconfig b/drivers/mtd/lpddr/Kconfig
index acd4ea9b2278..5a401d8047ab 100644
--- a/drivers/mtd/lpddr/Kconfig
+++ b/drivers/mtd/lpddr/Kconfig
@@ -12,6 +12,7 @@ config MTD_LPDDR
12 DDR memories, intended for battery-operated systems. 12 DDR memories, intended for battery-operated systems.
13 13
14config MTD_QINFO_PROBE 14config MTD_QINFO_PROBE
15 depends on MTD_LPDDR
15 tristate "Detect flash chips by QINFO probe" 16 tristate "Detect flash chips by QINFO probe"
16 help 17 help
17 Device Information for LPDDR chips is offered through the Overlay 18 Device Information for LPDDR chips is offered through the Overlay
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 0225cbbf22de..82923bd2d9c5 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -491,7 +491,7 @@ config MTD_PCMCIA_ANONYMOUS
491 491
492config MTD_BFIN_ASYNC 492config MTD_BFIN_ASYNC
493 tristate "Blackfin BF533-STAMP Flash Chip Support" 493 tristate "Blackfin BF533-STAMP Flash Chip Support"
494 depends on BFIN533_STAMP && MTD_CFI 494 depends on BFIN533_STAMP && MTD_CFI && MTD_COMPLEX_MAPPINGS
495 select MTD_PARTITIONS 495 select MTD_PARTITIONS
496 default y 496 default y
497 help 497 help
@@ -529,12 +529,6 @@ config MTD_DMV182
529 help 529 help
530 Map driver for Dy-4 SVME/DMV-182 board. 530 Map driver for Dy-4 SVME/DMV-182 board.
531 531
532config MTD_SHARP_SL
533 tristate "ROM mapped on Sharp SL Series"
534 depends on ARCH_PXA
535 help
536 This enables access to the flash chip on the Sharp SL Series of PDAs.
537
538config MTD_INTEL_VR_NOR 532config MTD_INTEL_VR_NOR
539 tristate "NOR flash on Intel Vermilion Range Expansion Bus CS0" 533 tristate "NOR flash on Intel Vermilion Range Expansion Bus CS0"
540 depends on PCI 534 depends on PCI
@@ -542,6 +536,12 @@ config MTD_INTEL_VR_NOR
542 Map driver for a NOR flash bank located on the Expansion Bus of the 536 Map driver for a NOR flash bank located on the Expansion Bus of the
543 Intel Vermilion Range chipset. 537 Intel Vermilion Range chipset.
544 538
539config MTD_RBTX4939
540 tristate "Map driver for RBTX4939 board"
541 depends on TOSHIBA_RBTX4939 && MTD_CFI && MTD_COMPLEX_MAPPINGS
542 help
543 Map driver for NOR flash chips on RBTX4939 board.
544
545config MTD_PLATRAM 545config MTD_PLATRAM
546 tristate "Map driver for platform device RAM (mtd-ram)" 546 tristate "Map driver for platform device RAM (mtd-ram)"
547 select MTD_RAM 547 select MTD_RAM
@@ -551,5 +551,15 @@ config MTD_PLATRAM
551 551
552 This selection automatically selects the map_ram driver. 552 This selection automatically selects the map_ram driver.
553 553
554endmenu 554config MTD_VMU
555 tristate "Map driver for Dreamcast VMU"
556 depends on MAPLE
557 help
558 This driver enables access to the Dreamcast Visual Memory Unit (VMU).
559
560 Most Dreamcast users will want to say Y here.
555 561
562 To build this as a module select M here, the module will be called
563 vmu-flash.
564
565endmenu
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 6d9ba35caf11..2dbc1bec8488 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -56,8 +56,9 @@ obj-$(CONFIG_MTD_IXP4XX) += ixp4xx.o
56obj-$(CONFIG_MTD_IXP2000) += ixp2000.o 56obj-$(CONFIG_MTD_IXP2000) += ixp2000.o
57obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o 57obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o
58obj-$(CONFIG_MTD_DMV182) += dmv182.o 58obj-$(CONFIG_MTD_DMV182) += dmv182.o
59obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o
60obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o 59obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
61obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o 60obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
62obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o 61obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o
63obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o 62obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o
63obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o
64obj-$(CONFIG_MTD_VMU) += vmu-flash.o
diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c
index 6fec86aaed7e..576611f605db 100644
--- a/drivers/mtd/maps/bfin-async-flash.c
+++ b/drivers/mtd/maps/bfin-async-flash.c
@@ -152,14 +152,18 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev)
152 152
153 if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) { 153 if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) {
154 pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin); 154 pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin);
155 kfree(state);
155 return -EBUSY; 156 return -EBUSY;
156 } 157 }
157 gpio_direction_output(state->enet_flash_pin, 1); 158 gpio_direction_output(state->enet_flash_pin, 1);
158 159
159 pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8); 160 pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8);
160 state->mtd = do_map_probe(memory->name, &state->map); 161 state->mtd = do_map_probe(memory->name, &state->map);
161 if (!state->mtd) 162 if (!state->mtd) {
163 gpio_free(state->enet_flash_pin);
164 kfree(state);
162 return -ENXIO; 165 return -ENXIO;
166 }
163 167
164#ifdef CONFIG_MTD_PARTITIONS 168#ifdef CONFIG_MTD_PARTITIONS
165 ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0); 169 ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0);
diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c
index 5f7a245ed132..424f17d6ffd1 100644
--- a/drivers/mtd/maps/ck804xrom.c
+++ b/drivers/mtd/maps/ck804xrom.c
@@ -342,9 +342,9 @@ static struct pci_device_id ck804xrom_pci_tbl[] = {
342 { 0, } 342 { 0, }
343}; 343};
344 344
345#if 0
345MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl); 346MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl);
346 347
347#if 0
348static struct pci_driver ck804xrom_driver = { 348static struct pci_driver ck804xrom_driver = {
349 .name = MOD_NAME, 349 .name = MOD_NAME,
350 .id_table = ck804xrom_pci_tbl, 350 .id_table = ck804xrom_pci_tbl,
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c
index d2ec262666c7..c9681a339a59 100644
--- a/drivers/mtd/maps/integrator-flash.c
+++ b/drivers/mtd/maps/integrator-flash.c
@@ -31,6 +31,7 @@
31#include <linux/ioport.h> 31#include <linux/ioport.h>
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/init.h> 33#include <linux/init.h>
34#include <linux/io.h>
34 35
35#include <linux/mtd/mtd.h> 36#include <linux/mtd/mtd.h>
36#include <linux/mtd/map.h> 37#include <linux/mtd/map.h>
@@ -38,7 +39,6 @@
38 39
39#include <asm/mach/flash.h> 40#include <asm/mach/flash.h>
40#include <mach/hardware.h> 41#include <mach/hardware.h>
41#include <asm/io.h>
42#include <asm/system.h> 42#include <asm/system.h>
43 43
44#ifdef CONFIG_ARCH_P720T 44#ifdef CONFIG_ARCH_P720T
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
index 7e50e9b1b781..a24478102b11 100644
--- a/drivers/mtd/maps/omap_nor.c
+++ b/drivers/mtd/maps/omap_nor.c
@@ -115,6 +115,8 @@ static int __init omapflash_probe(struct platform_device *pdev)
115 } 115 }
116 info->mtd->owner = THIS_MODULE; 116 info->mtd->owner = THIS_MODULE;
117 117
118 info->mtd->dev.parent = &pdev->dev;
119
118#ifdef CONFIG_MTD_PARTITIONS 120#ifdef CONFIG_MTD_PARTITIONS
119 err = parse_mtd_partitions(info->mtd, part_probes, &info->parts, 0); 121 err = parse_mtd_partitions(info->mtd, part_probes, &info->parts, 0);
120 if (err > 0) 122 if (err > 0)
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index 87743661d48e..29a901157352 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -29,6 +29,7 @@ struct physmap_flash_info {
29 struct map_info map[MAX_RESOURCES]; 29 struct map_info map[MAX_RESOURCES];
30#ifdef CONFIG_MTD_PARTITIONS 30#ifdef CONFIG_MTD_PARTITIONS
31 int nr_parts; 31 int nr_parts;
32 struct mtd_partition *parts;
32#endif 33#endif
33}; 34};
34 35
@@ -45,25 +46,29 @@ static int physmap_flash_remove(struct platform_device *dev)
45 46
46 physmap_data = dev->dev.platform_data; 47 physmap_data = dev->dev.platform_data;
47 48
48#ifdef CONFIG_MTD_CONCAT 49 if (info->cmtd) {
49 if (info->cmtd != info->mtd[0]) { 50#ifdef CONFIG_MTD_PARTITIONS
51 if (info->nr_parts || physmap_data->nr_parts)
52 del_mtd_partitions(info->cmtd);
53 else
54 del_mtd_device(info->cmtd);
55#else
50 del_mtd_device(info->cmtd); 56 del_mtd_device(info->cmtd);
51 mtd_concat_destroy(info->cmtd); 57#endif
52 } 58 }
59#ifdef CONFIG_MTD_PARTITIONS
60 if (info->nr_parts)
61 kfree(info->parts);
53#endif 62#endif
54 63
55 for (i = 0; i < MAX_RESOURCES; i++) { 64#ifdef CONFIG_MTD_CONCAT
56 if (info->mtd[i] != NULL) { 65 if (info->cmtd != info->mtd[0])
57#ifdef CONFIG_MTD_PARTITIONS 66 mtd_concat_destroy(info->cmtd);
58 if (info->nr_parts || physmap_data->nr_parts)
59 del_mtd_partitions(info->mtd[i]);
60 else
61 del_mtd_device(info->mtd[i]);
62#else
63 del_mtd_device(info->mtd[i]);
64#endif 67#endif
68
69 for (i = 0; i < MAX_RESOURCES; i++) {
70 if (info->mtd[i] != NULL)
65 map_destroy(info->mtd[i]); 71 map_destroy(info->mtd[i]);
66 }
67 } 72 }
68 return 0; 73 return 0;
69} 74}
@@ -86,9 +91,6 @@ static int physmap_flash_probe(struct platform_device *dev)
86 int err = 0; 91 int err = 0;
87 int i; 92 int i;
88 int devices_found = 0; 93 int devices_found = 0;
89#ifdef CONFIG_MTD_PARTITIONS
90 struct mtd_partition *parts;
91#endif
92 94
93 physmap_data = dev->dev.platform_data; 95 physmap_data = dev->dev.platform_data;
94 if (physmap_data == NULL) 96 if (physmap_data == NULL)
@@ -145,6 +147,7 @@ static int physmap_flash_probe(struct platform_device *dev)
145 devices_found++; 147 devices_found++;
146 } 148 }
147 info->mtd[i]->owner = THIS_MODULE; 149 info->mtd[i]->owner = THIS_MODULE;
150 info->mtd[i]->dev.parent = &dev->dev;
148 } 151 }
149 152
150 if (devices_found == 1) { 153 if (devices_found == 1) {
@@ -167,10 +170,11 @@ static int physmap_flash_probe(struct platform_device *dev)
167 goto err_out; 170 goto err_out;
168 171
169#ifdef CONFIG_MTD_PARTITIONS 172#ifdef CONFIG_MTD_PARTITIONS
170 err = parse_mtd_partitions(info->cmtd, part_probe_types, &parts, 0); 173 err = parse_mtd_partitions(info->cmtd, part_probe_types,
174 &info->parts, 0);
171 if (err > 0) { 175 if (err > 0) {
172 add_mtd_partitions(info->cmtd, parts, err); 176 add_mtd_partitions(info->cmtd, info->parts, err);
173 kfree(parts); 177 info->nr_parts = err;
174 return 0; 178 return 0;
175 } 179 }
176 180
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index fbf0ca939d72..c83a60fada53 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -219,6 +219,7 @@ static int __devinit of_flash_probe(struct of_device *dev,
219 goto err_out; 219 goto err_out;
220 } 220 }
221 info->mtd->owner = THIS_MODULE; 221 info->mtd->owner = THIS_MODULE;
222 info->mtd->dev.parent = &dev->dev;
222 223
223#ifdef CONFIG_MTD_PARTITIONS 224#ifdef CONFIG_MTD_PARTITIONS
224 /* First look for RedBoot table or partitions on the command 225 /* First look for RedBoot table or partitions on the command
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
index e7dd9c8a965e..49c9ece76477 100644
--- a/drivers/mtd/maps/plat-ram.c
+++ b/drivers/mtd/maps/plat-ram.c
@@ -224,6 +224,7 @@ static int platram_probe(struct platform_device *pdev)
224 } 224 }
225 225
226 info->mtd->owner = THIS_MODULE; 226 info->mtd->owner = THIS_MODULE;
227 info->mtd->dev.parent = &pdev->dev;
227 228
228 platram_setrw(info, PLATRAM_RW); 229 platram_setrw(info, PLATRAM_RW);
229 230
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index 771139c5bf87..572d32fdf38a 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -41,9 +41,8 @@ struct pxa2xx_flash_info {
41static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; 41static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
42 42
43 43
44static int __init pxa2xx_flash_probe(struct device *dev) 44static int __init pxa2xx_flash_probe(struct platform_device *pdev)
45{ 45{
46 struct platform_device *pdev = to_platform_device(dev);
47 struct flash_platform_data *flash = pdev->dev.platform_data; 46 struct flash_platform_data *flash = pdev->dev.platform_data;
48 struct pxa2xx_flash_info *info; 47 struct pxa2xx_flash_info *info;
49 struct mtd_partition *parts; 48 struct mtd_partition *parts;
@@ -114,15 +113,15 @@ static int __init pxa2xx_flash_probe(struct device *dev)
114 add_mtd_device(info->mtd); 113 add_mtd_device(info->mtd);
115 } 114 }
116 115
117 dev_set_drvdata(dev, info); 116 platform_set_drvdata(pdev, info);
118 return 0; 117 return 0;
119} 118}
120 119
121static int __exit pxa2xx_flash_remove(struct device *dev) 120static int __devexit pxa2xx_flash_remove(struct platform_device *dev)
122{ 121{
123 struct pxa2xx_flash_info *info = dev_get_drvdata(dev); 122 struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
124 123
125 dev_set_drvdata(dev, NULL); 124 platform_set_drvdata(dev, NULL);
126 125
127#ifdef CONFIG_MTD_PARTITIONS 126#ifdef CONFIG_MTD_PARTITIONS
128 if (info->nr_parts) 127 if (info->nr_parts)
@@ -141,9 +140,9 @@ static int __exit pxa2xx_flash_remove(struct device *dev)
141} 140}
142 141
143#ifdef CONFIG_PM 142#ifdef CONFIG_PM
144static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state) 143static int pxa2xx_flash_suspend(struct platform_device *dev, pm_message_t state)
145{ 144{
146 struct pxa2xx_flash_info *info = dev_get_drvdata(dev); 145 struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
147 int ret = 0; 146 int ret = 0;
148 147
149 if (info->mtd && info->mtd->suspend) 148 if (info->mtd && info->mtd->suspend)
@@ -151,17 +150,17 @@ static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state)
151 return ret; 150 return ret;
152} 151}
153 152
154static int pxa2xx_flash_resume(struct device *dev) 153static int pxa2xx_flash_resume(struct platform_device *dev)
155{ 154{
156 struct pxa2xx_flash_info *info = dev_get_drvdata(dev); 155 struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
157 156
158 if (info->mtd && info->mtd->resume) 157 if (info->mtd && info->mtd->resume)
159 info->mtd->resume(info->mtd); 158 info->mtd->resume(info->mtd);
160 return 0; 159 return 0;
161} 160}
162static void pxa2xx_flash_shutdown(struct device *dev) 161static void pxa2xx_flash_shutdown(struct platform_device *dev)
163{ 162{
164 struct pxa2xx_flash_info *info = dev_get_drvdata(dev); 163 struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
165 164
166 if (info && info->mtd->suspend(info->mtd) == 0) 165 if (info && info->mtd->suspend(info->mtd) == 0)
167 info->mtd->resume(info->mtd); 166 info->mtd->resume(info->mtd);
@@ -172,11 +171,13 @@ static void pxa2xx_flash_shutdown(struct device *dev)
172#define pxa2xx_flash_shutdown NULL 171#define pxa2xx_flash_shutdown NULL
173#endif 172#endif
174 173
175static struct device_driver pxa2xx_flash_driver = { 174static struct platform_driver pxa2xx_flash_driver = {
176 .name = "pxa2xx-flash", 175 .driver = {
177 .bus = &platform_bus_type, 176 .name = "pxa2xx-flash",
177 .owner = THIS_MODULE,
178 },
178 .probe = pxa2xx_flash_probe, 179 .probe = pxa2xx_flash_probe,
179 .remove = __exit_p(pxa2xx_flash_remove), 180 .remove = __devexit_p(pxa2xx_flash_remove),
180 .suspend = pxa2xx_flash_suspend, 181 .suspend = pxa2xx_flash_suspend,
181 .resume = pxa2xx_flash_resume, 182 .resume = pxa2xx_flash_resume,
182 .shutdown = pxa2xx_flash_shutdown, 183 .shutdown = pxa2xx_flash_shutdown,
@@ -184,12 +185,12 @@ static struct device_driver pxa2xx_flash_driver = {
184 185
185static int __init init_pxa2xx_flash(void) 186static int __init init_pxa2xx_flash(void)
186{ 187{
187 return driver_register(&pxa2xx_flash_driver); 188 return platform_driver_register(&pxa2xx_flash_driver);
188} 189}
189 190
190static void __exit cleanup_pxa2xx_flash(void) 191static void __exit cleanup_pxa2xx_flash(void)
191{ 192{
192 driver_unregister(&pxa2xx_flash_driver); 193 platform_driver_unregister(&pxa2xx_flash_driver);
193} 194}
194 195
195module_init(init_pxa2xx_flash); 196module_init(init_pxa2xx_flash);
diff --git a/drivers/mtd/maps/rbtx4939-flash.c b/drivers/mtd/maps/rbtx4939-flash.c
new file mode 100644
index 000000000000..d39f0adac846
--- /dev/null
+++ b/drivers/mtd/maps/rbtx4939-flash.c
@@ -0,0 +1,208 @@
1/*
2 * rbtx4939-flash (based on physmap.c)
3 *
4 * This is a simplified physmap driver with map_init callback function.
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 * Copyright (C) 2009 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
11 */
12
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/device.h>
19#include <linux/platform_device.h>
20#include <linux/mtd/mtd.h>
21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h>
23#include <asm/txx9/rbtx4939.h>
24
25struct rbtx4939_flash_info {
26 struct mtd_info *mtd;
27 struct map_info map;
28#ifdef CONFIG_MTD_PARTITIONS
29 int nr_parts;
30 struct mtd_partition *parts;
31#endif
32};
33
34static int rbtx4939_flash_remove(struct platform_device *dev)
35{
36 struct rbtx4939_flash_info *info;
37
38 info = platform_get_drvdata(dev);
39 if (!info)
40 return 0;
41 platform_set_drvdata(dev, NULL);
42
43 if (info->mtd) {
44#ifdef CONFIG_MTD_PARTITIONS
45 struct rbtx4939_flash_data *pdata = dev->dev.platform_data;
46
47 if (info->nr_parts) {
48 del_mtd_partitions(info->mtd);
49 kfree(info->parts);
50 } else if (pdata->nr_parts)
51 del_mtd_partitions(info->mtd);
52 else
53 del_mtd_device(info->mtd);
54#else
55 del_mtd_device(info->mtd);
56#endif
57 map_destroy(info->mtd);
58 }
59 return 0;
60}
61
62static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
63#ifdef CONFIG_MTD_PARTITIONS
64static const char *part_probe_types[] = { "cmdlinepart", NULL };
65#endif
66
67static int rbtx4939_flash_probe(struct platform_device *dev)
68{
69 struct rbtx4939_flash_data *pdata;
70 struct rbtx4939_flash_info *info;
71 struct resource *res;
72 const char **probe_type;
73 int err = 0;
74 unsigned long size;
75
76 pdata = dev->dev.platform_data;
77 if (!pdata)
78 return -ENODEV;
79
80 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
81 if (!res)
82 return -ENODEV;
83 info = devm_kzalloc(&dev->dev, sizeof(struct rbtx4939_flash_info),
84 GFP_KERNEL);
85 if (!info)
86 return -ENOMEM;
87
88 platform_set_drvdata(dev, info);
89
90 size = resource_size(res);
91 pr_notice("rbtx4939 platform flash device: %pR\n", res);
92
93 if (!devm_request_mem_region(&dev->dev, res->start, size,
94 dev_name(&dev->dev)))
95 return -EBUSY;
96
97 info->map.name = dev_name(&dev->dev);
98 info->map.phys = res->start;
99 info->map.size = size;
100 info->map.bankwidth = pdata->width;
101
102 info->map.virt = devm_ioremap(&dev->dev, info->map.phys, size);
103 if (!info->map.virt)
104 return -EBUSY;
105
106 if (pdata->map_init)
107 (*pdata->map_init)(&info->map);
108 else
109 simple_map_init(&info->map);
110
111 probe_type = rom_probe_types;
112 for (; !info->mtd && *probe_type; probe_type++)
113 info->mtd = do_map_probe(*probe_type, &info->map);
114 if (!info->mtd) {
115 dev_err(&dev->dev, "map_probe failed\n");
116 err = -ENXIO;
117 goto err_out;
118 }
119 info->mtd->owner = THIS_MODULE;
120 if (err)
121 goto err_out;
122
123#ifdef CONFIG_MTD_PARTITIONS
124 err = parse_mtd_partitions(info->mtd, part_probe_types,
125 &info->parts, 0);
126 if (err > 0) {
127 add_mtd_partitions(info->mtd, info->parts, err);
128 info->nr_parts = err;
129 return 0;
130 }
131
132 if (pdata->nr_parts) {
133 pr_notice("Using rbtx4939 partition information\n");
134 add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts);
135 return 0;
136 }
137#endif
138
139 add_mtd_device(info->mtd);
140 return 0;
141
142err_out:
143 rbtx4939_flash_remove(dev);
144 return err;
145}
146
147#ifdef CONFIG_PM
148static int rbtx4939_flash_suspend(struct platform_device *dev,
149 pm_message_t state)
150{
151 struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
152
153 if (info->mtd->suspend)
154 return info->mtd->suspend(info->mtd);
155 return 0;
156}
157
158static int rbtx4939_flash_resume(struct platform_device *dev)
159{
160 struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
161
162 if (info->mtd->resume)
163 info->mtd->resume(info->mtd);
164 return 0;
165}
166
167static void rbtx4939_flash_shutdown(struct platform_device *dev)
168{
169 struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
170
171 if (info->mtd->suspend && info->mtd->resume)
172 if (info->mtd->suspend(info->mtd) == 0)
173 info->mtd->resume(info->mtd);
174}
175#else
176#define rbtx4939_flash_suspend NULL
177#define rbtx4939_flash_resume NULL
178#define rbtx4939_flash_shutdown NULL
179#endif
180
181static struct platform_driver rbtx4939_flash_driver = {
182 .probe = rbtx4939_flash_probe,
183 .remove = rbtx4939_flash_remove,
184 .suspend = rbtx4939_flash_suspend,
185 .resume = rbtx4939_flash_resume,
186 .shutdown = rbtx4939_flash_shutdown,
187 .driver = {
188 .name = "rbtx4939-flash",
189 .owner = THIS_MODULE,
190 },
191};
192
193static int __init rbtx4939_flash_init(void)
194{
195 return platform_driver_register(&rbtx4939_flash_driver);
196}
197
198static void __exit rbtx4939_flash_exit(void)
199{
200 platform_driver_unregister(&rbtx4939_flash_driver);
201}
202
203module_init(rbtx4939_flash_init);
204module_exit(rbtx4939_flash_exit);
205
206MODULE_LICENSE("GPL");
207MODULE_DESCRIPTION("RBTX4939 MTD map driver");
208MODULE_ALIAS("platform:rbtx4939-flash");
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index 6f6a0f6dafd6..05e9362dc7f0 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -12,6 +12,7 @@
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/io.h>
15 16
16#include <linux/mtd/mtd.h> 17#include <linux/mtd/mtd.h>
17#include <linux/mtd/map.h> 18#include <linux/mtd/map.h>
@@ -19,7 +20,6 @@
19#include <linux/mtd/concat.h> 20#include <linux/mtd/concat.h>
20 21
21#include <mach/hardware.h> 22#include <mach/hardware.h>
22#include <asm/io.h>
23#include <asm/sizes.h> 23#include <asm/sizes.h>
24#include <asm/mach/flash.h> 24#include <asm/mach/flash.h>
25 25
@@ -351,7 +351,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat)
351 351
352static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; 352static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
353 353
354static int __init sa1100_mtd_probe(struct platform_device *pdev) 354static int __devinit sa1100_mtd_probe(struct platform_device *pdev)
355{ 355{
356 struct flash_platform_data *plat = pdev->dev.platform_data; 356 struct flash_platform_data *plat = pdev->dev.platform_data;
357 struct mtd_partition *parts; 357 struct mtd_partition *parts;
diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c
deleted file mode 100644
index b392f096c706..000000000000
--- a/drivers/mtd/maps/sharpsl-flash.c
+++ /dev/null
@@ -1,116 +0,0 @@
1/*
2 * sharpsl-flash.c
3 *
4 * Copyright (C) 2001 Lineo Japan, Inc.
5 * Copyright (C) 2002 SHARP
6 *
7 * based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp
8 * Handle mapping of the flash on the RPX Lite and CLLF boards
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/types.h>
24#include <linux/kernel.h>
25#include <linux/mtd/mtd.h>
26#include <linux/mtd/map.h>
27#include <linux/mtd/partitions.h>
28#include <asm/io.h>
29#include <asm/mach-types.h>
30
31#define WINDOW_ADDR 0x00000000
32#define WINDOW_SIZE 0x00800000
33#define BANK_WIDTH 2
34
35static struct mtd_info *mymtd;
36
37struct map_info sharpsl_map = {
38 .name = "sharpsl-flash",
39 .size = WINDOW_SIZE,
40 .bankwidth = BANK_WIDTH,
41 .phys = WINDOW_ADDR
42};
43
44static struct mtd_partition sharpsl_partitions[1] = {
45 {
46 name: "Boot PROM Filesystem",
47 }
48};
49
50static int __init init_sharpsl(void)
51{
52 struct mtd_partition *parts;
53 int nb_parts = 0;
54 char *part_type = "static";
55
56 printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n",
57 WINDOW_SIZE, WINDOW_ADDR);
58 sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
59 if (!sharpsl_map.virt) {
60 printk("Failed to ioremap\n");
61 return -EIO;
62 }
63
64 simple_map_init(&sharpsl_map);
65
66 mymtd = do_map_probe("map_rom", &sharpsl_map);
67 if (!mymtd) {
68 iounmap(sharpsl_map.virt);
69 return -ENXIO;
70 }
71
72 mymtd->owner = THIS_MODULE;
73
74 if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky()
75 || machine_is_poodle()) {
76 sharpsl_partitions[0].size=0x006d0000;
77 sharpsl_partitions[0].offset=0x00120000;
78 } else if (machine_is_tosa()) {
79 sharpsl_partitions[0].size=0x006a0000;
80 sharpsl_partitions[0].offset=0x00160000;
81 } else if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi()) {
82 sharpsl_partitions[0].size=0x006b0000;
83 sharpsl_partitions[0].offset=0x00140000;
84 } else {
85 map_destroy(mymtd);
86 iounmap(sharpsl_map.virt);
87 return -ENODEV;
88 }
89
90 parts = sharpsl_partitions;
91 nb_parts = ARRAY_SIZE(sharpsl_partitions);
92
93 printk(KERN_NOTICE "Using %s partition definition\n", part_type);
94 add_mtd_partitions(mymtd, parts, nb_parts);
95
96 return 0;
97}
98
99static void __exit cleanup_sharpsl(void)
100{
101 if (mymtd) {
102 del_mtd_partitions(mymtd);
103 map_destroy(mymtd);
104 }
105 if (sharpsl_map.virt) {
106 iounmap(sharpsl_map.virt);
107 sharpsl_map.virt = 0;
108 }
109}
110
111module_init(init_sharpsl);
112module_exit(cleanup_sharpsl);
113
114MODULE_LICENSE("GPL");
115MODULE_AUTHOR("SHARP (Original: Arnold Christensen <AKC@pel.dk>)");
116MODULE_DESCRIPTION("MTD map driver for SHARP SL series");
diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c
new file mode 100644
index 000000000000..1f73297e7776
--- /dev/null
+++ b/drivers/mtd/maps/vmu-flash.c
@@ -0,0 +1,832 @@
1/* vmu-flash.c
2 * Driver for SEGA Dreamcast Visual Memory Unit
3 *
4 * Copyright (c) Adrian McMenamin 2002 - 2009
5 * Copyright (c) Paul Mundt 2001
6 *
7 * Licensed under version 2 of the
8 * GNU General Public Licence
9 */
10#include <linux/init.h>
11#include <linux/sched.h>
12#include <linux/delay.h>
13#include <linux/maple.h>
14#include <linux/mtd/mtd.h>
15#include <linux/mtd/map.h>
16
17struct vmu_cache {
18 unsigned char *buffer; /* Cache */
19 unsigned int block; /* Which block was cached */
20 unsigned long jiffies_atc; /* When was it cached? */
21 int valid;
22};
23
24struct mdev_part {
25 struct maple_device *mdev;
26 int partition;
27};
28
29struct vmupart {
30 u16 user_blocks;
31 u16 root_block;
32 u16 numblocks;
33 char *name;
34 struct vmu_cache *pcache;
35};
36
37struct memcard {
38 u16 tempA;
39 u16 tempB;
40 u32 partitions;
41 u32 blocklen;
42 u32 writecnt;
43 u32 readcnt;
44 u32 removeable;
45 int partition;
46 int read;
47 unsigned char *blockread;
48 struct vmupart *parts;
49 struct mtd_info *mtd;
50};
51
52struct vmu_block {
53 unsigned int num; /* block number */
54 unsigned int ofs; /* block offset */
55};
56
57static struct vmu_block *ofs_to_block(unsigned long src_ofs,
58 struct mtd_info *mtd, int partition)
59{
60 struct vmu_block *vblock;
61 struct maple_device *mdev;
62 struct memcard *card;
63 struct mdev_part *mpart;
64 int num;
65
66 mpart = mtd->priv;
67 mdev = mpart->mdev;
68 card = maple_get_drvdata(mdev);
69
70 if (src_ofs >= card->parts[partition].numblocks * card->blocklen)
71 goto failed;
72
73 num = src_ofs / card->blocklen;
74 if (num > card->parts[partition].numblocks)
75 goto failed;
76
77 vblock = kmalloc(sizeof(struct vmu_block), GFP_KERNEL);
78 if (!vblock)
79 goto failed;
80
81 vblock->num = num;
82 vblock->ofs = src_ofs % card->blocklen;
83 return vblock;
84
85failed:
86 return NULL;
87}
88
89/* Maple bus callback function for reads */
90static void vmu_blockread(struct mapleq *mq)
91{
92 struct maple_device *mdev;
93 struct memcard *card;
94
95 mdev = mq->dev;
96 card = maple_get_drvdata(mdev);
97 /* copy the read in data */
98
99 if (unlikely(!card->blockread))
100 return;
101
102 memcpy(card->blockread, mq->recvbuf->buf + 12,
103 card->blocklen/card->readcnt);
104
105}
106
107/* Interface with maple bus to read blocks
108 * caching the results so that other parts
109 * of the driver can access block reads */
110static int maple_vmu_read_block(unsigned int num, unsigned char *buf,
111 struct mtd_info *mtd)
112{
113 struct memcard *card;
114 struct mdev_part *mpart;
115 struct maple_device *mdev;
116 int partition, error = 0, x, wait;
117 unsigned char *blockread = NULL;
118 struct vmu_cache *pcache;
119 __be32 sendbuf;
120
121 mpart = mtd->priv;
122 mdev = mpart->mdev;
123 partition = mpart->partition;
124 card = maple_get_drvdata(mdev);
125 pcache = card->parts[partition].pcache;
126 pcache->valid = 0;
127
128 /* prepare the cache for this block */
129 if (!pcache->buffer) {
130 pcache->buffer = kmalloc(card->blocklen, GFP_KERNEL);
131 if (!pcache->buffer) {
132 dev_err(&mdev->dev, "VMU at (%d, %d) - read fails due"
133 " to lack of memory\n", mdev->port,
134 mdev->unit);
135 error = -ENOMEM;
136 goto outB;
137 }
138 }
139
140 /*
141 * Reads may be phased - again the hardware spec
142 * supports this - though may not be any devices in
143 * the wild that implement it, but we will here
144 */
145 for (x = 0; x < card->readcnt; x++) {
146 sendbuf = cpu_to_be32(partition << 24 | x << 16 | num);
147
148 if (atomic_read(&mdev->busy) == 1) {
149 wait_event_interruptible_timeout(mdev->maple_wait,
150 atomic_read(&mdev->busy) == 0, HZ);
151 if (atomic_read(&mdev->busy) == 1) {
152 dev_notice(&mdev->dev, "VMU at (%d, %d)"
153 " is busy\n", mdev->port, mdev->unit);
154 error = -EAGAIN;
155 goto outB;
156 }
157 }
158
159 atomic_set(&mdev->busy, 1);
160 blockread = kmalloc(card->blocklen/card->readcnt, GFP_KERNEL);
161 if (!blockread) {
162 error = -ENOMEM;
163 atomic_set(&mdev->busy, 0);
164 goto outB;
165 }
166 card->blockread = blockread;
167
168 maple_getcond_callback(mdev, vmu_blockread, 0,
169 MAPLE_FUNC_MEMCARD);
170 error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
171 MAPLE_COMMAND_BREAD, 2, &sendbuf);
172 /* Very long timeouts seem to be needed when box is stressed */
173 wait = wait_event_interruptible_timeout(mdev->maple_wait,
174 (atomic_read(&mdev->busy) == 0 ||
175 atomic_read(&mdev->busy) == 2), HZ * 3);
176 /*
177 * MTD layer does not handle hotplugging well
178 * so have to return errors when VMU is unplugged
179 * in the middle of a read (busy == 2)
180 */
181 if (error || atomic_read(&mdev->busy) == 2) {
182 if (atomic_read(&mdev->busy) == 2)
183 error = -ENXIO;
184 atomic_set(&mdev->busy, 0);
185 card->blockread = NULL;
186 goto outA;
187 }
188 if (wait == 0 || wait == -ERESTARTSYS) {
189 card->blockread = NULL;
190 atomic_set(&mdev->busy, 0);
191 error = -EIO;
192 list_del_init(&(mdev->mq->list));
193 kfree(mdev->mq->sendbuf);
194 mdev->mq->sendbuf = NULL;
195 if (wait == -ERESTARTSYS) {
196 dev_warn(&mdev->dev, "VMU read on (%d, %d)"
197 " interrupted on block 0x%X\n",
198 mdev->port, mdev->unit, num);
199 } else
200 dev_notice(&mdev->dev, "VMU read on (%d, %d)"
201 " timed out on block 0x%X\n",
202 mdev->port, mdev->unit, num);
203 goto outA;
204 }
205
206 memcpy(buf + (card->blocklen/card->readcnt) * x, blockread,
207 card->blocklen/card->readcnt);
208
209 memcpy(pcache->buffer + (card->blocklen/card->readcnt) * x,
210 card->blockread, card->blocklen/card->readcnt);
211 card->blockread = NULL;
212 pcache->block = num;
213 pcache->jiffies_atc = jiffies;
214 pcache->valid = 1;
215 kfree(blockread);
216 }
217
218 return error;
219
220outA:
221 kfree(blockread);
222outB:
223 return error;
224}
225
226/* communicate with maple bus for phased writing */
227static int maple_vmu_write_block(unsigned int num, const unsigned char *buf,
228 struct mtd_info *mtd)
229{
230 struct memcard *card;
231 struct mdev_part *mpart;
232 struct maple_device *mdev;
233 int partition, error, locking, x, phaselen, wait;
234 __be32 *sendbuf;
235
236 mpart = mtd->priv;
237 mdev = mpart->mdev;
238 partition = mpart->partition;
239 card = maple_get_drvdata(mdev);
240
241 phaselen = card->blocklen/card->writecnt;
242
243 sendbuf = kmalloc(phaselen + 4, GFP_KERNEL);
244 if (!sendbuf) {
245 error = -ENOMEM;
246 goto fail_nosendbuf;
247 }
248 for (x = 0; x < card->writecnt; x++) {
249 sendbuf[0] = cpu_to_be32(partition << 24 | x << 16 | num);
250 memcpy(&sendbuf[1], buf + phaselen * x, phaselen);
251 /* wait until the device is not busy doing something else
252 * or 1 second - which ever is longer */
253 if (atomic_read(&mdev->busy) == 1) {
254 wait_event_interruptible_timeout(mdev->maple_wait,
255 atomic_read(&mdev->busy) == 0, HZ);
256 if (atomic_read(&mdev->busy) == 1) {
257 error = -EBUSY;
258 dev_notice(&mdev->dev, "VMU write at (%d, %d)"
259 "failed - device is busy\n",
260 mdev->port, mdev->unit);
261 goto fail_nolock;
262 }
263 }
264 atomic_set(&mdev->busy, 1);
265
266 locking = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
267 MAPLE_COMMAND_BWRITE, phaselen / 4 + 2, sendbuf);
268 wait = wait_event_interruptible_timeout(mdev->maple_wait,
269 atomic_read(&mdev->busy) == 0, HZ/10);
270 if (locking) {
271 error = -EIO;
272 atomic_set(&mdev->busy, 0);
273 goto fail_nolock;
274 }
275 if (atomic_read(&mdev->busy) == 2) {
276 atomic_set(&mdev->busy, 0);
277 } else if (wait == 0 || wait == -ERESTARTSYS) {
278 error = -EIO;
279 dev_warn(&mdev->dev, "Write at (%d, %d) of block"
280 " 0x%X at phase %d failed: could not"
281 " communicate with VMU", mdev->port,
282 mdev->unit, num, x);
283 atomic_set(&mdev->busy, 0);
284 kfree(mdev->mq->sendbuf);
285 mdev->mq->sendbuf = NULL;
286 list_del_init(&(mdev->mq->list));
287 goto fail_nolock;
288 }
289 }
290 kfree(sendbuf);
291
292 return card->blocklen;
293
294fail_nolock:
295 kfree(sendbuf);
296fail_nosendbuf:
297 dev_err(&mdev->dev, "VMU (%d, %d): write failed\n", mdev->port,
298 mdev->unit);
299 return error;
300}
301
302/* mtd function to simulate reading byte by byte */
303static unsigned char vmu_flash_read_char(unsigned long ofs, int *retval,
304 struct mtd_info *mtd)
305{
306 struct vmu_block *vblock;
307 struct memcard *card;
308 struct mdev_part *mpart;
309 struct maple_device *mdev;
310 unsigned char *buf, ret;
311 int partition, error;
312
313 mpart = mtd->priv;
314 mdev = mpart->mdev;
315 partition = mpart->partition;
316 card = maple_get_drvdata(mdev);
317 *retval = 0;
318
319 buf = kmalloc(card->blocklen, GFP_KERNEL);
320 if (!buf) {
321 *retval = 1;
322 ret = -ENOMEM;
323 goto finish;
324 }
325
326 vblock = ofs_to_block(ofs, mtd, partition);
327 if (!vblock) {
328 *retval = 3;
329 ret = -ENOMEM;
330 goto out_buf;
331 }
332
333 error = maple_vmu_read_block(vblock->num, buf, mtd);
334 if (error) {
335 ret = error;
336 *retval = 2;
337 goto out_vblock;
338 }
339
340 ret = buf[vblock->ofs];
341
342out_vblock:
343 kfree(vblock);
344out_buf:
345 kfree(buf);
346finish:
347 return ret;
348}
349
350/* mtd higher order function to read flash */
351static int vmu_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
352 size_t *retlen, u_char *buf)
353{
354 struct maple_device *mdev;
355 struct memcard *card;
356 struct mdev_part *mpart;
357 struct vmu_cache *pcache;
358 struct vmu_block *vblock;
359 int index = 0, retval, partition, leftover, numblocks;
360 unsigned char cx;
361
362 if (len < 1)
363 return -EIO;
364
365 mpart = mtd->priv;
366 mdev = mpart->mdev;
367 partition = mpart->partition;
368 card = maple_get_drvdata(mdev);
369
370 numblocks = card->parts[partition].numblocks;
371 if (from + len > numblocks * card->blocklen)
372 len = numblocks * card->blocklen - from;
373 if (len == 0)
374 return -EIO;
375 /* Have we cached this bit already? */
376 pcache = card->parts[partition].pcache;
377 do {
378 vblock = ofs_to_block(from + index, mtd, partition);
379 if (!vblock)
380 return -ENOMEM;
381 /* Have we cached this and is the cache valid and timely? */
382 if (pcache->valid &&
383 time_before(jiffies, pcache->jiffies_atc + HZ) &&
384 (pcache->block == vblock->num)) {
385 /* we have cached it, so do necessary copying */
386 leftover = card->blocklen - vblock->ofs;
387 if (vblock->ofs + len - index < card->blocklen) {
388 /* only a bit of this block to copy */
389 memcpy(buf + index,
390 pcache->buffer + vblock->ofs,
391 len - index);
392 index = len;
393 } else {
394 /* otherwise copy remainder of whole block */
395 memcpy(buf + index, pcache->buffer +
396 vblock->ofs, leftover);
397 index += leftover;
398 }
399 } else {
400 /*
401 * Not cached so read one byte -
402 * but cache the rest of the block
403 */
404 cx = vmu_flash_read_char(from + index, &retval, mtd);
405 if (retval) {
406 *retlen = index;
407 kfree(vblock);
408 return cx;
409 }
410 memset(buf + index, cx, 1);
411 index++;
412 }
413 kfree(vblock);
414 } while (len > index);
415 *retlen = index;
416
417 return 0;
418}
419
420static int vmu_flash_write(struct mtd_info *mtd, loff_t to, size_t len,
421 size_t *retlen, const u_char *buf)
422{
423 struct maple_device *mdev;
424 struct memcard *card;
425 struct mdev_part *mpart;
426 int index = 0, partition, error = 0, numblocks;
427 struct vmu_cache *pcache;
428 struct vmu_block *vblock;
429 unsigned char *buffer;
430
431 mpart = mtd->priv;
432 mdev = mpart->mdev;
433 partition = mpart->partition;
434 card = maple_get_drvdata(mdev);
435
436 /* simple sanity checks */
437 if (len < 1) {
438 error = -EIO;
439 goto failed;
440 }
441 numblocks = card->parts[partition].numblocks;
442 if (to + len > numblocks * card->blocklen)
443 len = numblocks * card->blocklen - to;
444 if (len == 0) {
445 error = -EIO;
446 goto failed;
447 }
448
449 vblock = ofs_to_block(to, mtd, partition);
450 if (!vblock) {
451 error = -ENOMEM;
452 goto failed;
453 }
454
455 buffer = kmalloc(card->blocklen, GFP_KERNEL);
456 if (!buffer) {
457 error = -ENOMEM;
458 goto fail_buffer;
459 }
460
461 do {
462 /* Read in the block we are to write to */
463 error = maple_vmu_read_block(vblock->num, buffer, mtd);
464 if (error)
465 goto fail_io;
466
467 do {
468 buffer[vblock->ofs] = buf[index];
469 vblock->ofs++;
470 index++;
471 if (index >= len)
472 break;
473 } while (vblock->ofs < card->blocklen);
474
475 /* write out new buffer */
476 error = maple_vmu_write_block(vblock->num, buffer, mtd);
477 /* invalidate the cache */
478 pcache = card->parts[partition].pcache;
479 pcache->valid = 0;
480
481 if (error != card->blocklen)
482 goto fail_io;
483
484 vblock->num++;
485 vblock->ofs = 0;
486 } while (len > index);
487
488 kfree(buffer);
489 *retlen = index;
490 kfree(vblock);
491 return 0;
492
493fail_io:
494 kfree(buffer);
495fail_buffer:
496 kfree(vblock);
497failed:
498 dev_err(&mdev->dev, "VMU write failing with error %d\n", error);
499 return error;
500}
501
502static void vmu_flash_sync(struct mtd_info *mtd)
503{
504 /* Do nothing here */
505}
506
507/* Maple bus callback function to recursively query hardware details */
508static void vmu_queryblocks(struct mapleq *mq)
509{
510 struct maple_device *mdev;
511 unsigned short *res;
512 struct memcard *card;
513 __be32 partnum;
514 struct vmu_cache *pcache;
515 struct mdev_part *mpart;
516 struct mtd_info *mtd_cur;
517 struct vmupart *part_cur;
518 int error;
519
520 mdev = mq->dev;
521 card = maple_get_drvdata(mdev);
522 res = (unsigned short *) (mq->recvbuf->buf);
523 card->tempA = res[12];
524 card->tempB = res[6];
525
526 dev_info(&mdev->dev, "VMU device at partition %d has %d user "
527 "blocks with a root block at %d\n", card->partition,
528 card->tempA, card->tempB);
529
530 part_cur = &card->parts[card->partition];
531 part_cur->user_blocks = card->tempA;
532 part_cur->root_block = card->tempB;
533 part_cur->numblocks = card->tempB + 1;
534 part_cur->name = kmalloc(12, GFP_KERNEL);
535 if (!part_cur->name)
536 goto fail_name;
537
538 sprintf(part_cur->name, "vmu%d.%d.%d",
539 mdev->port, mdev->unit, card->partition);
540 mtd_cur = &card->mtd[card->partition];
541 mtd_cur->name = part_cur->name;
542 mtd_cur->type = 8;
543 mtd_cur->flags = MTD_WRITEABLE|MTD_NO_ERASE;
544 mtd_cur->size = part_cur->numblocks * card->blocklen;
545 mtd_cur->erasesize = card->blocklen;
546 mtd_cur->write = vmu_flash_write;
547 mtd_cur->read = vmu_flash_read;
548 mtd_cur->sync = vmu_flash_sync;
549 mtd_cur->writesize = card->blocklen;
550
551 mpart = kmalloc(sizeof(struct mdev_part), GFP_KERNEL);
552 if (!mpart)
553 goto fail_mpart;
554
555 mpart->mdev = mdev;
556 mpart->partition = card->partition;
557 mtd_cur->priv = mpart;
558 mtd_cur->owner = THIS_MODULE;
559
560 pcache = kzalloc(sizeof(struct vmu_cache), GFP_KERNEL);
561 if (!pcache)
562 goto fail_cache_create;
563 part_cur->pcache = pcache;
564
565 error = add_mtd_device(mtd_cur);
566 if (error)
567 goto fail_mtd_register;
568
569 maple_getcond_callback(mdev, NULL, 0,
570 MAPLE_FUNC_MEMCARD);
571
572 /*
573 * Set up a recursive call to the (probably theoretical)
574 * second or more partition
575 */
576 if (++card->partition < card->partitions) {
577 partnum = cpu_to_be32(card->partition << 24);
578 maple_getcond_callback(mdev, vmu_queryblocks, 0,
579 MAPLE_FUNC_MEMCARD);
580 maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
581 MAPLE_COMMAND_GETMINFO, 2, &partnum);
582 }
583 return;
584
585fail_mtd_register:
586 dev_err(&mdev->dev, "Could not register maple device at (%d, %d)"
587 "error is 0x%X\n", mdev->port, mdev->unit, error);
588 for (error = 0; error <= card->partition; error++) {
589 kfree(((card->parts)[error]).pcache);
590 ((card->parts)[error]).pcache = NULL;
591 }
592fail_cache_create:
593fail_mpart:
594 for (error = 0; error <= card->partition; error++) {
595 kfree(((card->mtd)[error]).priv);
596 ((card->mtd)[error]).priv = NULL;
597 }
598 maple_getcond_callback(mdev, NULL, 0,
599 MAPLE_FUNC_MEMCARD);
600 kfree(part_cur->name);
601fail_name:
602 return;
603}
604
605/* Handles very basic info about the flash, queries for details */
606static int __devinit vmu_connect(struct maple_device *mdev)
607{
608 unsigned long test_flash_data, basic_flash_data;
609 int c, error;
610 struct memcard *card;
611 u32 partnum = 0;
612
613 test_flash_data = be32_to_cpu(mdev->devinfo.function);
614 /* Need to count how many bits are set - to find out which
615 * function_data element has details of the memory card:
616 * using Brian Kernighan's/Peter Wegner's method */
617 for (c = 0; test_flash_data; c++)
618 test_flash_data &= test_flash_data - 1;
619
620 basic_flash_data = be32_to_cpu(mdev->devinfo.function_data[c - 1]);
621
622 card = kmalloc(sizeof(struct memcard), GFP_KERNEL);
623 if (!card) {
624 error = ENOMEM;
625 goto fail_nomem;
626 }
627
628 card->partitions = (basic_flash_data >> 24 & 0xFF) + 1;
629 card->blocklen = ((basic_flash_data >> 16 & 0xFF) + 1) << 5;
630 card->writecnt = basic_flash_data >> 12 & 0xF;
631 card->readcnt = basic_flash_data >> 8 & 0xF;
632 card->removeable = basic_flash_data >> 7 & 1;
633
634 card->partition = 0;
635
636 /*
637 * Not sure there are actually any multi-partition devices in the
638 * real world, but the hardware supports them, so, so will we
639 */
640 card->parts = kmalloc(sizeof(struct vmupart) * card->partitions,
641 GFP_KERNEL);
642 if (!card->parts) {
643 error = -ENOMEM;
644 goto fail_partitions;
645 }
646
647 card->mtd = kmalloc(sizeof(struct mtd_info) * card->partitions,
648 GFP_KERNEL);
649 if (!card->mtd) {
650 error = -ENOMEM;
651 goto fail_mtd_info;
652 }
653
654 maple_set_drvdata(mdev, card);
655
656 /*
657 * We want to trap meminfo not get cond
658 * so set interval to zero, but rely on maple bus
659 * driver to pass back the results of the meminfo
660 */
661 maple_getcond_callback(mdev, vmu_queryblocks, 0,
662 MAPLE_FUNC_MEMCARD);
663
664 /* Make sure we are clear to go */
665 if (atomic_read(&mdev->busy) == 1) {
666 wait_event_interruptible_timeout(mdev->maple_wait,
667 atomic_read(&mdev->busy) == 0, HZ);
668 if (atomic_read(&mdev->busy) == 1) {
669 dev_notice(&mdev->dev, "VMU at (%d, %d) is busy\n",
670 mdev->port, mdev->unit);
671 error = -EAGAIN;
672 goto fail_device_busy;
673 }
674 }
675
676 atomic_set(&mdev->busy, 1);
677
678 /*
679 * Set up the minfo call: vmu_queryblocks will handle
680 * the information passed back
681 */
682 error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
683 MAPLE_COMMAND_GETMINFO, 2, &partnum);
684 if (error) {
685 dev_err(&mdev->dev, "Could not lock VMU at (%d, %d)"
686 " error is 0x%X\n", mdev->port, mdev->unit, error);
687 goto fail_mtd_info;
688 }
689 return 0;
690
691fail_device_busy:
692 kfree(card->mtd);
693fail_mtd_info:
694 kfree(card->parts);
695fail_partitions:
696 kfree(card);
697fail_nomem:
698 return error;
699}
700
701static void __devexit vmu_disconnect(struct maple_device *mdev)
702{
703 struct memcard *card;
704 struct mdev_part *mpart;
705 int x;
706
707 mdev->callback = NULL;
708 card = maple_get_drvdata(mdev);
709 for (x = 0; x < card->partitions; x++) {
710 mpart = ((card->mtd)[x]).priv;
711 mpart->mdev = NULL;
712 del_mtd_device(&((card->mtd)[x]));
713 kfree(((card->parts)[x]).name);
714 }
715 kfree(card->parts);
716 kfree(card->mtd);
717 kfree(card);
718}
719
720/* Callback to handle eccentricities of both mtd subsystem
721 * and general flakyness of Dreamcast VMUs
722 */
723static int vmu_can_unload(struct maple_device *mdev)
724{
725 struct memcard *card;
726 int x;
727 struct mtd_info *mtd;
728
729 card = maple_get_drvdata(mdev);
730 for (x = 0; x < card->partitions; x++) {
731 mtd = &((card->mtd)[x]);
732 if (mtd->usecount > 0)
733 return 0;
734 }
735 return 1;
736}
737
738#define ERRSTR "VMU at (%d, %d) file error -"
739
740static void vmu_file_error(struct maple_device *mdev, void *recvbuf)
741{
742 enum maple_file_errors error = ((int *)recvbuf)[1];
743
744 switch (error) {
745
746 case MAPLE_FILEERR_INVALID_PARTITION:
747 dev_notice(&mdev->dev, ERRSTR " invalid partition number\n",
748 mdev->port, mdev->unit);
749 break;
750
751 case MAPLE_FILEERR_PHASE_ERROR:
752 dev_notice(&mdev->dev, ERRSTR " phase error\n",
753 mdev->port, mdev->unit);
754 break;
755
756 case MAPLE_FILEERR_INVALID_BLOCK:
757 dev_notice(&mdev->dev, ERRSTR " invalid block number\n",
758 mdev->port, mdev->unit);
759 break;
760
761 case MAPLE_FILEERR_WRITE_ERROR:
762 dev_notice(&mdev->dev, ERRSTR " write error\n",
763 mdev->port, mdev->unit);
764 break;
765
766 case MAPLE_FILEERR_INVALID_WRITE_LENGTH:
767 dev_notice(&mdev->dev, ERRSTR " invalid write length\n",
768 mdev->port, mdev->unit);
769 break;
770
771 case MAPLE_FILEERR_BAD_CRC:
772 dev_notice(&mdev->dev, ERRSTR " bad CRC\n",
773 mdev->port, mdev->unit);
774 break;
775
776 default:
777 dev_notice(&mdev->dev, ERRSTR " 0x%X\n",
778 mdev->port, mdev->unit, error);
779 }
780}
781
782
783static int __devinit probe_maple_vmu(struct device *dev)
784{
785 int error;
786 struct maple_device *mdev = to_maple_dev(dev);
787 struct maple_driver *mdrv = to_maple_driver(dev->driver);
788
789 mdev->can_unload = vmu_can_unload;
790 mdev->fileerr_handler = vmu_file_error;
791 mdev->driver = mdrv;
792
793 error = vmu_connect(mdev);
794 if (error)
795 return error;
796
797 return 0;
798}
799
800static int __devexit remove_maple_vmu(struct device *dev)
801{
802 struct maple_device *mdev = to_maple_dev(dev);
803
804 vmu_disconnect(mdev);
805 return 0;
806}
807
808static struct maple_driver vmu_flash_driver = {
809 .function = MAPLE_FUNC_MEMCARD,
810 .drv = {
811 .name = "Dreamcast_visual_memory",
812 .probe = probe_maple_vmu,
813 .remove = __devexit_p(remove_maple_vmu),
814 },
815};
816
817static int __init vmu_flash_map_init(void)
818{
819 return maple_driver_register(&vmu_flash_driver);
820}
821
822static void __exit vmu_flash_map_exit(void)
823{
824 maple_driver_unregister(&vmu_flash_driver);
825}
826
827module_init(vmu_flash_map_init);
828module_exit(vmu_flash_map_exit);
829
830MODULE_LICENSE("GPL");
831MODULE_AUTHOR("Adrian McMenamin");
832MODULE_DESCRIPTION("Flash mapping for Sega Dreamcast visual memory");
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 1409f01406f6..a49a9c8f2cb1 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -286,6 +286,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
286 gd->private_data = new; 286 gd->private_data = new;
287 new->blkcore_priv = gd; 287 new->blkcore_priv = gd;
288 gd->queue = tr->blkcore_priv->rq; 288 gd->queue = tr->blkcore_priv->rq;
289 gd->driverfs_dev = new->mtd->dev.parent;
289 290
290 if (new->readonly) 291 if (new->readonly)
291 set_disk_ro(gd, 1); 292 set_disk_ro(gd, 1);
@@ -382,11 +383,12 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
382 tr->blkcore_priv->thread = kthread_run(mtd_blktrans_thread, tr, 383 tr->blkcore_priv->thread = kthread_run(mtd_blktrans_thread, tr,
383 "%sd", tr->name); 384 "%sd", tr->name);
384 if (IS_ERR(tr->blkcore_priv->thread)) { 385 if (IS_ERR(tr->blkcore_priv->thread)) {
386 int ret = PTR_ERR(tr->blkcore_priv->thread);
385 blk_cleanup_queue(tr->blkcore_priv->rq); 387 blk_cleanup_queue(tr->blkcore_priv->rq);
386 unregister_blkdev(tr->major, tr->name); 388 unregister_blkdev(tr->major, tr->name);
387 kfree(tr->blkcore_priv); 389 kfree(tr->blkcore_priv);
388 mutex_unlock(&mtd_table_mutex); 390 mutex_unlock(&mtd_table_mutex);
389 return PTR_ERR(tr->blkcore_priv->thread); 391 return ret;
390 } 392 }
391 393
392 INIT_LIST_HEAD(&tr->devs); 394 INIT_LIST_HEAD(&tr->devs);
diff --git a/drivers/mtd/mtdbdi.c b/drivers/mtd/mtdbdi.c
new file mode 100644
index 000000000000..5ca5aed0b225
--- /dev/null
+++ b/drivers/mtd/mtdbdi.c
@@ -0,0 +1,43 @@
1/* MTD backing device capabilities
2 *
3 * Copyright © 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/backing-dev.h>
13#include <linux/mtd/mtd.h>
14#include "internal.h"
15
16/*
17 * backing device capabilities for non-mappable devices (such as NAND flash)
18 * - permits private mappings, copies are taken of the data
19 */
20struct backing_dev_info mtd_bdi_unmappable = {
21 .capabilities = BDI_CAP_MAP_COPY,
22};
23
24/*
25 * backing device capabilities for R/O mappable devices (such as ROM)
26 * - permits private mappings, copies are taken of the data
27 * - permits non-writable shared mappings
28 */
29struct backing_dev_info mtd_bdi_ro_mappable = {
30 .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
31 BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP),
32};
33
34/*
35 * backing device capabilities for writable mappable devices (such as RAM)
36 * - permits private mappings, copies are taken of the data
37 * - permits non-writable shared mappings
38 */
39struct backing_dev_info mtd_bdi_rw_mappable = {
40 .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
41 BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP |
42 BDI_CAP_WRITE_MAP),
43};
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index e9ec59e9a566..763d3f0a1f42 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -13,39 +13,13 @@
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/smp_lock.h> 15#include <linux/smp_lock.h>
16#include <linux/backing-dev.h>
16 17
17#include <linux/mtd/mtd.h> 18#include <linux/mtd/mtd.h>
18#include <linux/mtd/compatmac.h> 19#include <linux/mtd/compatmac.h>
19 20
20#include <asm/uaccess.h> 21#include <asm/uaccess.h>
21 22
22static struct class *mtd_class;
23
24static void mtd_notify_add(struct mtd_info* mtd)
25{
26 if (!mtd)
27 return;
28
29 device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
30 NULL, "mtd%d", mtd->index);
31
32 device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
33 NULL, "mtd%dro", mtd->index);
34}
35
36static void mtd_notify_remove(struct mtd_info* mtd)
37{
38 if (!mtd)
39 return;
40
41 device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2));
42 device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1));
43}
44
45static struct mtd_notifier notifier = {
46 .add = mtd_notify_add,
47 .remove = mtd_notify_remove,
48};
49 23
50/* 24/*
51 * Data structure to hold the pointer to the mtd device as well 25 * Data structure to hold the pointer to the mtd device as well
@@ -107,12 +81,15 @@ static int mtd_open(struct inode *inode, struct file *file)
107 goto out; 81 goto out;
108 } 82 }
109 83
110 if (MTD_ABSENT == mtd->type) { 84 if (mtd->type == MTD_ABSENT) {
111 put_mtd_device(mtd); 85 put_mtd_device(mtd);
112 ret = -ENODEV; 86 ret = -ENODEV;
113 goto out; 87 goto out;
114 } 88 }
115 89
90 if (mtd->backing_dev_info)
91 file->f_mapping->backing_dev_info = mtd->backing_dev_info;
92
116 /* You can't open it RW if it's not a writeable device */ 93 /* You can't open it RW if it's not a writeable device */
117 if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) { 94 if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) {
118 put_mtd_device(mtd); 95 put_mtd_device(mtd);
@@ -781,6 +758,59 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
781 return ret; 758 return ret;
782} /* memory_ioctl */ 759} /* memory_ioctl */
783 760
761/*
762 * try to determine where a shared mapping can be made
763 * - only supported for NOMMU at the moment (MMU can't doesn't copy private
764 * mappings)
765 */
766#ifndef CONFIG_MMU
767static unsigned long mtd_get_unmapped_area(struct file *file,
768 unsigned long addr,
769 unsigned long len,
770 unsigned long pgoff,
771 unsigned long flags)
772{
773 struct mtd_file_info *mfi = file->private_data;
774 struct mtd_info *mtd = mfi->mtd;
775
776 if (mtd->get_unmapped_area) {
777 unsigned long offset;
778
779 if (addr != 0)
780 return (unsigned long) -EINVAL;
781
782 if (len > mtd->size || pgoff >= (mtd->size >> PAGE_SHIFT))
783 return (unsigned long) -EINVAL;
784
785 offset = pgoff << PAGE_SHIFT;
786 if (offset > mtd->size - len)
787 return (unsigned long) -EINVAL;
788
789 return mtd->get_unmapped_area(mtd, len, offset, flags);
790 }
791
792 /* can't map directly */
793 return (unsigned long) -ENOSYS;
794}
795#endif
796
797/*
798 * set up a mapping for shared memory segments
799 */
800static int mtd_mmap(struct file *file, struct vm_area_struct *vma)
801{
802#ifdef CONFIG_MMU
803 struct mtd_file_info *mfi = file->private_data;
804 struct mtd_info *mtd = mfi->mtd;
805
806 if (mtd->type == MTD_RAM || mtd->type == MTD_ROM)
807 return 0;
808 return -ENOSYS;
809#else
810 return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS;
811#endif
812}
813
784static const struct file_operations mtd_fops = { 814static const struct file_operations mtd_fops = {
785 .owner = THIS_MODULE, 815 .owner = THIS_MODULE,
786 .llseek = mtd_lseek, 816 .llseek = mtd_lseek,
@@ -789,39 +819,36 @@ static const struct file_operations mtd_fops = {
789 .ioctl = mtd_ioctl, 819 .ioctl = mtd_ioctl,
790 .open = mtd_open, 820 .open = mtd_open,
791 .release = mtd_close, 821 .release = mtd_close,
822 .mmap = mtd_mmap,
823#ifndef CONFIG_MMU
824 .get_unmapped_area = mtd_get_unmapped_area,
825#endif
792}; 826};
793 827
794static int __init init_mtdchar(void) 828static int __init init_mtdchar(void)
795{ 829{
796 if (register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops)) { 830 int status;
831
832 status = register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops);
833 if (status < 0) {
797 printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", 834 printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
798 MTD_CHAR_MAJOR); 835 MTD_CHAR_MAJOR);
799 return -EAGAIN;
800 } 836 }
801 837
802 mtd_class = class_create(THIS_MODULE, "mtd"); 838 return status;
803
804 if (IS_ERR(mtd_class)) {
805 printk(KERN_ERR "Error creating mtd class.\n");
806 unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
807 return PTR_ERR(mtd_class);
808 }
809
810 register_mtd_user(&notifier);
811 return 0;
812} 839}
813 840
814static void __exit cleanup_mtdchar(void) 841static void __exit cleanup_mtdchar(void)
815{ 842{
816 unregister_mtd_user(&notifier);
817 class_destroy(mtd_class);
818 unregister_chrdev(MTD_CHAR_MAJOR, "mtd"); 843 unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
819} 844}
820 845
821module_init(init_mtdchar); 846module_init(init_mtdchar);
822module_exit(cleanup_mtdchar); 847module_exit(cleanup_mtdchar);
823 848
849MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR);
824 850
825MODULE_LICENSE("GPL"); 851MODULE_LICENSE("GPL");
826MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 852MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
827MODULE_DESCRIPTION("Direct character-device access to MTD devices"); 853MODULE_DESCRIPTION("Direct character-device access to MTD devices");
854MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR);
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 3dbb1b38db66..792b547786b8 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -13,6 +13,7 @@
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/backing-dev.h>
16 17
17#include <linux/mtd/mtd.h> 18#include <linux/mtd/mtd.h>
18#include <linux/mtd/concat.h> 19#include <linux/mtd/concat.h>
@@ -684,6 +685,40 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs)
684} 685}
685 686
686/* 687/*
688 * try to support NOMMU mmaps on concatenated devices
689 * - we don't support subdev spanning as we can't guarantee it'll work
690 */
691static unsigned long concat_get_unmapped_area(struct mtd_info *mtd,
692 unsigned long len,
693 unsigned long offset,
694 unsigned long flags)
695{
696 struct mtd_concat *concat = CONCAT(mtd);
697 int i;
698
699 for (i = 0; i < concat->num_subdev; i++) {
700 struct mtd_info *subdev = concat->subdev[i];
701
702 if (offset >= subdev->size) {
703 offset -= subdev->size;
704 continue;
705 }
706
707 /* we've found the subdev over which the mapping will reside */
708 if (offset + len > subdev->size)
709 return (unsigned long) -EINVAL;
710
711 if (subdev->get_unmapped_area)
712 return subdev->get_unmapped_area(subdev, len, offset,
713 flags);
714
715 break;
716 }
717
718 return (unsigned long) -ENOSYS;
719}
720
721/*
687 * This function constructs a virtual MTD device by concatenating 722 * This function constructs a virtual MTD device by concatenating
688 * num_devs MTD devices. A pointer to the new device object is 723 * num_devs MTD devices. A pointer to the new device object is
689 * stored to *new_dev upon success. This function does _not_ 724 * stored to *new_dev upon success. This function does _not_
@@ -740,6 +775,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
740 775
741 concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks; 776 concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks;
742 777
778 concat->mtd.backing_dev_info = subdev[0]->backing_dev_info;
779
743 concat->subdev[0] = subdev[0]; 780 concat->subdev[0] = subdev[0];
744 781
745 for (i = 1; i < num_devs; i++) { 782 for (i = 1; i < num_devs; i++) {
@@ -766,6 +803,15 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
766 concat->mtd.flags |= 803 concat->mtd.flags |=
767 subdev[i]->flags & MTD_WRITEABLE; 804 subdev[i]->flags & MTD_WRITEABLE;
768 } 805 }
806
807 /* only permit direct mapping if the BDIs are all the same
808 * - copy-mapping is still permitted
809 */
810 if (concat->mtd.backing_dev_info !=
811 subdev[i]->backing_dev_info)
812 concat->mtd.backing_dev_info =
813 &default_backing_dev_info;
814
769 concat->mtd.size += subdev[i]->size; 815 concat->mtd.size += subdev[i]->size;
770 concat->mtd.ecc_stats.badblocks += 816 concat->mtd.ecc_stats.badblocks +=
771 subdev[i]->ecc_stats.badblocks; 817 subdev[i]->ecc_stats.badblocks;
@@ -796,6 +842,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
796 concat->mtd.unlock = concat_unlock; 842 concat->mtd.unlock = concat_unlock;
797 concat->mtd.suspend = concat_suspend; 843 concat->mtd.suspend = concat_suspend;
798 concat->mtd.resume = concat_resume; 844 concat->mtd.resume = concat_resume;
845 concat->mtd.get_unmapped_area = concat_get_unmapped_area;
799 846
800 /* 847 /*
801 * Combine the erase block size info of the subdevices: 848 * Combine the erase block size info of the subdevices:
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 76fe0a1e7a5e..fdd6ae859397 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -19,9 +19,13 @@
19#include <linux/proc_fs.h> 19#include <linux/proc_fs.h>
20 20
21#include <linux/mtd/mtd.h> 21#include <linux/mtd/mtd.h>
22#include "internal.h"
22 23
23#include "mtdcore.h" 24#include "mtdcore.h"
24 25
26
27static struct class *mtd_class;
28
25/* These are exported solely for the purpose of mtd_blkdevs.c. You 29/* These are exported solely for the purpose of mtd_blkdevs.c. You
26 should not use them for _anything_ else */ 30 should not use them for _anything_ else */
27DEFINE_MUTEX(mtd_table_mutex); 31DEFINE_MUTEX(mtd_table_mutex);
@@ -32,6 +36,160 @@ EXPORT_SYMBOL_GPL(mtd_table);
32 36
33static LIST_HEAD(mtd_notifiers); 37static LIST_HEAD(mtd_notifiers);
34 38
39
40#if defined(CONFIG_MTD_CHAR) || defined(CONFIG_MTD_CHAR_MODULE)
41#define MTD_DEVT(index) MKDEV(MTD_CHAR_MAJOR, (index)*2)
42#else
43#define MTD_DEVT(index) 0
44#endif
45
46/* REVISIT once MTD uses the driver model better, whoever allocates
47 * the mtd_info will probably want to use the release() hook...
48 */
49static void mtd_release(struct device *dev)
50{
51 struct mtd_info *mtd = dev_to_mtd(dev);
52
53 /* remove /dev/mtdXro node if needed */
54 if (MTD_DEVT(mtd->index))
55 device_destroy(mtd_class, MTD_DEVT(mtd->index) + 1);
56}
57
58static ssize_t mtd_type_show(struct device *dev,
59 struct device_attribute *attr, char *buf)
60{
61 struct mtd_info *mtd = dev_to_mtd(dev);
62 char *type;
63
64 switch (mtd->type) {
65 case MTD_ABSENT:
66 type = "absent";
67 break;
68 case MTD_RAM:
69 type = "ram";
70 break;
71 case MTD_ROM:
72 type = "rom";
73 break;
74 case MTD_NORFLASH:
75 type = "nor";
76 break;
77 case MTD_NANDFLASH:
78 type = "nand";
79 break;
80 case MTD_DATAFLASH:
81 type = "dataflash";
82 break;
83 case MTD_UBIVOLUME:
84 type = "ubi";
85 break;
86 default:
87 type = "unknown";
88 }
89
90 return snprintf(buf, PAGE_SIZE, "%s\n", type);
91}
92static DEVICE_ATTR(type, S_IRUGO, mtd_type_show, NULL);
93
94static ssize_t mtd_flags_show(struct device *dev,
95 struct device_attribute *attr, char *buf)
96{
97 struct mtd_info *mtd = dev_to_mtd(dev);
98
99 return snprintf(buf, PAGE_SIZE, "0x%lx\n", (unsigned long)mtd->flags);
100
101}
102static DEVICE_ATTR(flags, S_IRUGO, mtd_flags_show, NULL);
103
104static ssize_t mtd_size_show(struct device *dev,
105 struct device_attribute *attr, char *buf)
106{
107 struct mtd_info *mtd = dev_to_mtd(dev);
108
109 return snprintf(buf, PAGE_SIZE, "%llu\n",
110 (unsigned long long)mtd->size);
111
112}
113static DEVICE_ATTR(size, S_IRUGO, mtd_size_show, NULL);
114
115static ssize_t mtd_erasesize_show(struct device *dev,
116 struct device_attribute *attr, char *buf)
117{
118 struct mtd_info *mtd = dev_to_mtd(dev);
119
120 return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->erasesize);
121
122}
123static DEVICE_ATTR(erasesize, S_IRUGO, mtd_erasesize_show, NULL);
124
125static ssize_t mtd_writesize_show(struct device *dev,
126 struct device_attribute *attr, char *buf)
127{
128 struct mtd_info *mtd = dev_to_mtd(dev);
129
130 return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->writesize);
131
132}
133static DEVICE_ATTR(writesize, S_IRUGO, mtd_writesize_show, NULL);
134
135static ssize_t mtd_oobsize_show(struct device *dev,
136 struct device_attribute *attr, char *buf)
137{
138 struct mtd_info *mtd = dev_to_mtd(dev);
139
140 return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->oobsize);
141
142}
143static DEVICE_ATTR(oobsize, S_IRUGO, mtd_oobsize_show, NULL);
144
145static ssize_t mtd_numeraseregions_show(struct device *dev,
146 struct device_attribute *attr, char *buf)
147{
148 struct mtd_info *mtd = dev_to_mtd(dev);
149
150 return snprintf(buf, PAGE_SIZE, "%u\n", mtd->numeraseregions);
151
152}
153static DEVICE_ATTR(numeraseregions, S_IRUGO, mtd_numeraseregions_show,
154 NULL);
155
156static ssize_t mtd_name_show(struct device *dev,
157 struct device_attribute *attr, char *buf)
158{
159 struct mtd_info *mtd = dev_to_mtd(dev);
160
161 return snprintf(buf, PAGE_SIZE, "%s\n", mtd->name);
162
163}
164static DEVICE_ATTR(name, S_IRUGO, mtd_name_show, NULL);
165
166static struct attribute *mtd_attrs[] = {
167 &dev_attr_type.attr,
168 &dev_attr_flags.attr,
169 &dev_attr_size.attr,
170 &dev_attr_erasesize.attr,
171 &dev_attr_writesize.attr,
172 &dev_attr_oobsize.attr,
173 &dev_attr_numeraseregions.attr,
174 &dev_attr_name.attr,
175 NULL,
176};
177
178struct attribute_group mtd_group = {
179 .attrs = mtd_attrs,
180};
181
182struct attribute_group *mtd_groups[] = {
183 &mtd_group,
184 NULL,
185};
186
187static struct device_type mtd_devtype = {
188 .name = "mtd",
189 .groups = mtd_groups,
190 .release = mtd_release,
191};
192
35/** 193/**
36 * add_mtd_device - register an MTD device 194 * add_mtd_device - register an MTD device
37 * @mtd: pointer to new MTD device info structure 195 * @mtd: pointer to new MTD device info structure
@@ -40,12 +198,27 @@ static LIST_HEAD(mtd_notifiers);
40 * notify each currently active MTD 'user' of its arrival. Returns 198 * notify each currently active MTD 'user' of its arrival. Returns
41 * zero on success or 1 on failure, which currently will only happen 199 * zero on success or 1 on failure, which currently will only happen
42 * if the number of present devices exceeds MAX_MTD_DEVICES (i.e. 16) 200 * if the number of present devices exceeds MAX_MTD_DEVICES (i.e. 16)
201 * or there's a sysfs error.
43 */ 202 */
44 203
45int add_mtd_device(struct mtd_info *mtd) 204int add_mtd_device(struct mtd_info *mtd)
46{ 205{
47 int i; 206 int i;
48 207
208 if (!mtd->backing_dev_info) {
209 switch (mtd->type) {
210 case MTD_RAM:
211 mtd->backing_dev_info = &mtd_bdi_rw_mappable;
212 break;
213 case MTD_ROM:
214 mtd->backing_dev_info = &mtd_bdi_ro_mappable;
215 break;
216 default:
217 mtd->backing_dev_info = &mtd_bdi_unmappable;
218 break;
219 }
220 }
221
49 BUG_ON(mtd->writesize == 0); 222 BUG_ON(mtd->writesize == 0);
50 mutex_lock(&mtd_table_mutex); 223 mutex_lock(&mtd_table_mutex);
51 224
@@ -80,6 +253,23 @@ int add_mtd_device(struct mtd_info *mtd)
80 mtd->name); 253 mtd->name);
81 } 254 }
82 255
256 /* Caller should have set dev.parent to match the
257 * physical device.
258 */
259 mtd->dev.type = &mtd_devtype;
260 mtd->dev.class = mtd_class;
261 mtd->dev.devt = MTD_DEVT(i);
262 dev_set_name(&mtd->dev, "mtd%d", i);
263 if (device_register(&mtd->dev) != 0) {
264 mtd_table[i] = NULL;
265 break;
266 }
267
268 if (MTD_DEVT(i))
269 device_create(mtd_class, mtd->dev.parent,
270 MTD_DEVT(i) + 1,
271 NULL, "mtd%dro", i);
272
83 DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name); 273 DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name);
84 /* No need to get a refcount on the module containing 274 /* No need to get a refcount on the module containing
85 the notifier, since we hold the mtd_table_mutex */ 275 the notifier, since we hold the mtd_table_mutex */
@@ -124,6 +314,8 @@ int del_mtd_device (struct mtd_info *mtd)
124 } else { 314 } else {
125 struct mtd_notifier *not; 315 struct mtd_notifier *not;
126 316
317 device_unregister(&mtd->dev);
318
127 /* No need to get a refcount on the module containing 319 /* No need to get a refcount on the module containing
128 the notifier, since we hold the mtd_table_mutex */ 320 the notifier, since we hold the mtd_table_mutex */
129 list_for_each_entry(not, &mtd_notifiers, list) 321 list_for_each_entry(not, &mtd_notifiers, list)
@@ -393,28 +585,38 @@ done:
393 return ((count < begin+len-off) ? count : begin+len-off); 585 return ((count < begin+len-off) ? count : begin+len-off);
394} 586}
395 587
588#endif /* CONFIG_PROC_FS */
589
396/*====================================================================*/ 590/*====================================================================*/
397/* Init code */ 591/* Init code */
398 592
399static int __init init_mtd(void) 593static int __init init_mtd(void)
400{ 594{
595 mtd_class = class_create(THIS_MODULE, "mtd");
596
597 if (IS_ERR(mtd_class)) {
598 pr_err("Error creating mtd class.\n");
599 return PTR_ERR(mtd_class);
600 }
601#ifdef CONFIG_PROC_FS
401 if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) 602 if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
402 proc_mtd->read_proc = mtd_read_proc; 603 proc_mtd->read_proc = mtd_read_proc;
604#endif /* CONFIG_PROC_FS */
403 return 0; 605 return 0;
404} 606}
405 607
406static void __exit cleanup_mtd(void) 608static void __exit cleanup_mtd(void)
407{ 609{
610#ifdef CONFIG_PROC_FS
408 if (proc_mtd) 611 if (proc_mtd)
409 remove_proc_entry( "mtd", NULL); 612 remove_proc_entry( "mtd", NULL);
613#endif /* CONFIG_PROC_FS */
614 class_destroy(mtd_class);
410} 615}
411 616
412module_init(init_mtd); 617module_init(init_mtd);
413module_exit(cleanup_mtd); 618module_exit(cleanup_mtd);
414 619
415#endif /* CONFIG_PROC_FS */
416
417
418MODULE_LICENSE("GPL"); 620MODULE_LICENSE("GPL");
419MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 621MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
420MODULE_DESCRIPTION("Core MTD registration and access routines"); 622MODULE_DESCRIPTION("Core MTD registration and access routines");
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
index 1a6b3beabe8d..1060337c06df 100644
--- a/drivers/mtd/mtdoops.c
+++ b/drivers/mtd/mtdoops.c
@@ -44,6 +44,7 @@ static struct mtdoops_context {
44 int oops_pages; 44 int oops_pages;
45 int nextpage; 45 int nextpage;
46 int nextcount; 46 int nextcount;
47 char *name;
47 48
48 void *oops_buf; 49 void *oops_buf;
49 50
@@ -273,6 +274,9 @@ static void mtdoops_notify_add(struct mtd_info *mtd)
273{ 274{
274 struct mtdoops_context *cxt = &oops_cxt; 275 struct mtdoops_context *cxt = &oops_cxt;
275 276
277 if (cxt->name && !strcmp(mtd->name, cxt->name))
278 cxt->mtd_index = mtd->index;
279
276 if ((mtd->index != cxt->mtd_index) || cxt->mtd_index < 0) 280 if ((mtd->index != cxt->mtd_index) || cxt->mtd_index < 0)
277 return; 281 return;
278 282
@@ -357,8 +361,10 @@ mtdoops_console_write(struct console *co, const char *s, unsigned int count)
357 spin_lock_irqsave(&cxt->writecount_lock, flags); 361 spin_lock_irqsave(&cxt->writecount_lock, flags);
358 362
359 /* Check ready status didn't change whilst waiting for the lock */ 363 /* Check ready status didn't change whilst waiting for the lock */
360 if (!cxt->ready) 364 if (!cxt->ready) {
365 spin_unlock_irqrestore(&cxt->writecount_lock, flags);
361 return; 366 return;
367 }
362 368
363 if (cxt->writecount == 0) { 369 if (cxt->writecount == 0) {
364 u32 *stamp = cxt->oops_buf; 370 u32 *stamp = cxt->oops_buf;
@@ -383,8 +389,12 @@ static int __init mtdoops_console_setup(struct console *co, char *options)
383{ 389{
384 struct mtdoops_context *cxt = co->data; 390 struct mtdoops_context *cxt = co->data;
385 391
386 if (cxt->mtd_index != -1) 392 if (cxt->mtd_index != -1 || cxt->name)
387 return -EBUSY; 393 return -EBUSY;
394 if (options) {
395 cxt->name = kstrdup(options, GFP_KERNEL);
396 return 0;
397 }
388 if (co->index == -1) 398 if (co->index == -1)
389 return -EINVAL; 399 return -EINVAL;
390 400
@@ -412,6 +422,7 @@ static int __init mtdoops_console_init(void)
412 422
413 cxt->mtd_index = -1; 423 cxt->mtd_index = -1;
414 cxt->oops_buf = vmalloc(OOPS_PAGE_SIZE); 424 cxt->oops_buf = vmalloc(OOPS_PAGE_SIZE);
425 spin_lock_init(&cxt->writecount_lock);
415 426
416 if (!cxt->oops_buf) { 427 if (!cxt->oops_buf) {
417 printk(KERN_ERR "Failed to allocate mtdoops buffer workspace\n"); 428 printk(KERN_ERR "Failed to allocate mtdoops buffer workspace\n");
@@ -432,6 +443,7 @@ static void __exit mtdoops_console_exit(void)
432 443
433 unregister_mtd_user(&mtdoops_notifier); 444 unregister_mtd_user(&mtdoops_notifier);
434 unregister_console(&mtdoops_console); 445 unregister_console(&mtdoops_console);
446 kfree(cxt->name);
435 vfree(cxt->oops_buf); 447 vfree(cxt->oops_buf);
436} 448}
437 449
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 144e6b613a77..29675edb44b4 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -48,8 +48,11 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
48 size_t *retlen, u_char *buf) 48 size_t *retlen, u_char *buf)
49{ 49{
50 struct mtd_part *part = PART(mtd); 50 struct mtd_part *part = PART(mtd);
51 struct mtd_ecc_stats stats;
51 int res; 52 int res;
52 53
54 stats = part->master->ecc_stats;
55
53 if (from >= mtd->size) 56 if (from >= mtd->size)
54 len = 0; 57 len = 0;
55 else if (from + len > mtd->size) 58 else if (from + len > mtd->size)
@@ -58,9 +61,9 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
58 len, retlen, buf); 61 len, retlen, buf);
59 if (unlikely(res)) { 62 if (unlikely(res)) {
60 if (res == -EUCLEAN) 63 if (res == -EUCLEAN)
61 mtd->ecc_stats.corrected++; 64 mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected;
62 if (res == -EBADMSG) 65 if (res == -EBADMSG)
63 mtd->ecc_stats.failed++; 66 mtd->ecc_stats.failed += part->master->ecc_stats.failed - stats.failed;
64 } 67 }
65 return res; 68 return res;
66} 69}
@@ -84,6 +87,18 @@ static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
84 part->master->unpoint(part->master, from + part->offset, len); 87 part->master->unpoint(part->master, from + part->offset, len);
85} 88}
86 89
90static unsigned long part_get_unmapped_area(struct mtd_info *mtd,
91 unsigned long len,
92 unsigned long offset,
93 unsigned long flags)
94{
95 struct mtd_part *part = PART(mtd);
96
97 offset += part->offset;
98 return part->master->get_unmapped_area(part->master, len, offset,
99 flags);
100}
101
87static int part_read_oob(struct mtd_info *mtd, loff_t from, 102static int part_read_oob(struct mtd_info *mtd, loff_t from,
88 struct mtd_oob_ops *ops) 103 struct mtd_oob_ops *ops)
89{ 104{
@@ -342,6 +357,12 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
342 357
343 slave->mtd.name = part->name; 358 slave->mtd.name = part->name;
344 slave->mtd.owner = master->owner; 359 slave->mtd.owner = master->owner;
360 slave->mtd.backing_dev_info = master->backing_dev_info;
361
362 /* NOTE: we don't arrange MTDs as a tree; it'd be error-prone
363 * to have the same data be in two different partitions.
364 */
365 slave->mtd.dev.parent = master->dev.parent;
345 366
346 slave->mtd.read = part_read; 367 slave->mtd.read = part_read;
347 slave->mtd.write = part_write; 368 slave->mtd.write = part_write;
@@ -354,6 +375,8 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
354 slave->mtd.unpoint = part_unpoint; 375 slave->mtd.unpoint = part_unpoint;
355 } 376 }
356 377
378 if (master->get_unmapped_area)
379 slave->mtd.get_unmapped_area = part_get_unmapped_area;
357 if (master->read_oob) 380 if (master->read_oob)
358 slave->mtd.read_oob = part_read_oob; 381 slave->mtd.read_oob = part_read_oob;
359 if (master->write_oob) 382 if (master->write_oob)
@@ -493,7 +516,9 @@ out_register:
493 * This function, given a master MTD object and a partition table, creates 516 * This function, given a master MTD object and a partition table, creates
494 * and registers slave MTD objects which are bound to the master according to 517 * and registers slave MTD objects which are bound to the master according to
495 * the partition definitions. 518 * the partition definitions.
496 * (Q: should we register the master MTD object as well?) 519 *
520 * We don't register the master, or expect the caller to have done so,
521 * for reasons of data integrity.
497 */ 522 */
498 523
499int add_mtd_partitions(struct mtd_info *master, 524int add_mtd_partitions(struct mtd_info *master,
diff --git a/drivers/mtd/mtdsuper.c b/drivers/mtd/mtdsuper.c
index 00d46e137b2a..92285d0089c2 100644
--- a/drivers/mtd/mtdsuper.c
+++ b/drivers/mtd/mtdsuper.c
@@ -81,13 +81,16 @@ static int get_sb_mtd_aux(struct file_system_type *fs_type, int flags,
81 81
82 /* go */ 82 /* go */
83 sb->s_flags |= MS_ACTIVE; 83 sb->s_flags |= MS_ACTIVE;
84 return simple_set_mnt(mnt, sb); 84 simple_set_mnt(mnt, sb);
85
86 return 0;
85 87
86 /* new mountpoint for an already mounted superblock */ 88 /* new mountpoint for an already mounted superblock */
87already_mounted: 89already_mounted:
88 DEBUG(1, "MTDSB: Device %d (\"%s\") is already mounted\n", 90 DEBUG(1, "MTDSB: Device %d (\"%s\") is already mounted\n",
89 mtd->index, mtd->name); 91 mtd->index, mtd->name);
90 ret = simple_set_mnt(mnt, sb); 92 simple_set_mnt(mnt, sb);
93 ret = 0;
91 goto out_put; 94 goto out_put;
92 95
93out_error: 96out_error:
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 8b12e6e109d3..890936d0275e 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -273,7 +273,7 @@ config MTD_NAND_CAFE
273 273
274config MTD_NAND_CS553X 274config MTD_NAND_CS553X
275 tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)" 275 tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)"
276 depends on X86_32 && (X86_PC || X86_GENERICARCH) 276 depends on X86_32
277 help 277 help
278 The CS553x companion chips for the AMD Geode processor 278 The CS553x companion chips for the AMD Geode processor
279 include NAND flash controllers with built-in hardware ECC 279 include NAND flash controllers with built-in hardware ECC
@@ -334,7 +334,7 @@ config MTD_NAND_ATMEL_ECC_NONE
334endchoice 334endchoice
335 335
336config MTD_NAND_PXA3xx 336config MTD_NAND_PXA3xx
337 bool "Support for NAND flash devices on PXA3xx" 337 tristate "Support for NAND flash devices on PXA3xx"
338 depends on MTD_NAND && PXA3xx 338 depends on MTD_NAND && PXA3xx
339 help 339 help
340 This enables the driver for the NAND flash device found on 340 This enables the driver for the NAND flash device found on
@@ -427,4 +427,23 @@ config MTD_NAND_SH_FLCTL
427 Several Renesas SuperH CPU has FLCTL. This option enables support 427 Several Renesas SuperH CPU has FLCTL. This option enables support
428 for NAND Flash using FLCTL. This driver support SH7723. 428 for NAND Flash using FLCTL. This driver support SH7723.
429 429
430config MTD_NAND_DAVINCI
431 tristate "Support NAND on DaVinci SoC"
432 depends on ARCH_DAVINCI
433 help
434 Enable the driver for NAND flash chips on Texas Instruments
435 DaVinci processors.
436
437config MTD_NAND_TXX9NDFMC
438 tristate "NAND Flash support for TXx9 SoC"
439 depends on SOC_TX4938 || SOC_TX4939
440 help
441 This enables the NAND flash controller on the TXx9 SoCs.
442
443config MTD_NAND_SOCRATES
444 tristate "Support for NAND on Socrates board"
445 depends on MTD_NAND && SOCRATES
446 help
447 Enables support for NAND Flash chips wired onto Socrates board.
448
430endif # MTD_NAND 449endif # MTD_NAND
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index b661586afbfc..d33860ac42c3 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o
14obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o 14obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o
15obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o 15obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o
16obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o 16obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o
17obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o
17obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o 18obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o
18obj-$(CONFIG_MTD_NAND_H1900) += h1910.o 19obj-$(CONFIG_MTD_NAND_H1900) += h1910.o
19obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o 20obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o
@@ -36,5 +37,7 @@ obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o
36obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o 37obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o
37obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o 38obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o
38obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o 39obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o
40obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o
41obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o
39 42
40nand-objs := nand_base.o nand_bbt.o 43nand-objs := nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index c98c1570a40b..47a33cec3793 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -139,7 +139,8 @@ static int atmel_nand_device_ready(struct mtd_info *mtd)
139 struct nand_chip *nand_chip = mtd->priv; 139 struct nand_chip *nand_chip = mtd->priv;
140 struct atmel_nand_host *host = nand_chip->priv; 140 struct atmel_nand_host *host = nand_chip->priv;
141 141
142 return gpio_get_value(host->board->rdy_pin); 142 return gpio_get_value(host->board->rdy_pin) ^
143 !!host->board->rdy_pin_active_low;
143} 144}
144 145
145/* 146/*
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c
index 9af2a2cc1153..4c2a67ca801e 100644
--- a/drivers/mtd/nand/bf5xx_nand.c
+++ b/drivers/mtd/nand/bf5xx_nand.c
@@ -552,7 +552,6 @@ static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd,
552static int bf5xx_nand_dma_init(struct bf5xx_nand_info *info) 552static int bf5xx_nand_dma_init(struct bf5xx_nand_info *info)
553{ 553{
554 int ret; 554 int ret;
555 unsigned short val;
556 555
557 /* Do not use dma */ 556 /* Do not use dma */
558 if (!hardware_ecc) 557 if (!hardware_ecc)
@@ -560,13 +559,6 @@ static int bf5xx_nand_dma_init(struct bf5xx_nand_info *info)
560 559
561 init_completion(&info->dma_completion); 560 init_completion(&info->dma_completion);
562 561
563#ifdef CONFIG_BF54x
564 /* Setup DMAC1 channel mux for NFC which shared with SDH */
565 val = bfin_read_DMAC1_PERIMUX();
566 val &= 0xFFFE;
567 bfin_write_DMAC1_PERIMUX(val);
568 SSYNC();
569#endif
570 /* Request NFC DMA channel */ 562 /* Request NFC DMA channel */
571 ret = request_dma(CH_NFC, "BF5XX NFC driver"); 563 ret = request_dma(CH_NFC, "BF5XX NFC driver");
572 if (ret < 0) { 564 if (ret < 0) {
@@ -574,7 +566,13 @@ static int bf5xx_nand_dma_init(struct bf5xx_nand_info *info)
574 return ret; 566 return ret;
575 } 567 }
576 568
577 set_dma_callback(CH_NFC, (void *) bf5xx_nand_dma_irq, (void *) info); 569#ifdef CONFIG_BF54x
570 /* Setup DMAC1 channel mux for NFC which shared with SDH */
571 bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() & ~1);
572 SSYNC();
573#endif
574
575 set_dma_callback(CH_NFC, bf5xx_nand_dma_irq, info);
578 576
579 /* Turn off the DMA channel first */ 577 /* Turn off the DMA channel first */
580 disable_dma(CH_NFC); 578 disable_dma(CH_NFC);
@@ -632,7 +630,7 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info)
632/* 630/*
633 * Device management interface 631 * Device management interface
634 */ 632 */
635static int bf5xx_nand_add_partition(struct bf5xx_nand_info *info) 633static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
636{ 634{
637 struct mtd_info *mtd = &info->mtd; 635 struct mtd_info *mtd = &info->mtd;
638 636
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
index 22a6b2e50e91..7c5b257ce8e4 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/cafe_nand.c
@@ -654,6 +654,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
654 } 654 }
655 cafe = (void *)(&mtd[1]); 655 cafe = (void *)(&mtd[1]);
656 656
657 mtd->dev.parent = &pdev->dev;
657 mtd->priv = cafe; 658 mtd->priv = cafe;
658 mtd->owner = THIS_MODULE; 659 mtd->owner = THIS_MODULE;
659 660
diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c
index fa129c09bca8..10081e656a6f 100644
--- a/drivers/mtd/nand/cmx270_nand.c
+++ b/drivers/mtd/nand/cmx270_nand.c
@@ -26,8 +26,7 @@
26#include <asm/irq.h> 26#include <asm/irq.h>
27#include <asm/mach-types.h> 27#include <asm/mach-types.h>
28 28
29#include <mach/hardware.h> 29#include <mach/pxa2xx-regs.h>
30#include <mach/pxa-regs.h>
31 30
32#define GPIO_NAND_CS (11) 31#define GPIO_NAND_CS (11)
33#define GPIO_NAND_RB (89) 32#define GPIO_NAND_RB (89)
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
new file mode 100644
index 000000000000..0119220de7d0
--- /dev/null
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -0,0 +1,570 @@
1/*
2 * davinci_nand.c - NAND Flash Driver for DaVinci family chips
3 *
4 * Copyright © 2006 Texas Instruments.
5 *
6 * Port to 2.6.23 Copyright © 2008 by:
7 * Sander Huijsen <Shuijsen@optelecom-nkf.com>
8 * Troy Kisky <troy.kisky@boundarydevices.com>
9 * Dirk Behme <Dirk.Behme@gmail.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/kernel.h>
27#include <linux/init.h>
28#include <linux/module.h>
29#include <linux/platform_device.h>
30#include <linux/err.h>
31#include <linux/clk.h>
32#include <linux/io.h>
33#include <linux/mtd/nand.h>
34#include <linux/mtd/partitions.h>
35
36#include <mach/nand.h>
37
38#include <asm/mach-types.h>
39
40
41/*
42 * This is a device driver for the NAND flash controller found on the
43 * various DaVinci family chips. It handles up to four SoC chipselects,
44 * and some flavors of secondary chipselect (e.g. based on A12) as used
45 * with multichip packages.
46 *
47 * The 1-bit ECC hardware is supported, but not yet the newer 4-bit ECC
48 * available on chips like the DM355 and OMAP-L137 and needed with the
49 * more error-prone MLC NAND chips.
50 *
51 * This driver assumes EM_WAIT connects all the NAND devices' RDY/nBUSY
52 * outputs in a "wire-AND" configuration, with no per-chip signals.
53 */
54struct davinci_nand_info {
55 struct mtd_info mtd;
56 struct nand_chip chip;
57
58 struct device *dev;
59 struct clk *clk;
60 bool partitioned;
61
62 void __iomem *base;
63 void __iomem *vaddr;
64
65 uint32_t ioaddr;
66 uint32_t current_cs;
67
68 uint32_t mask_chipsel;
69 uint32_t mask_ale;
70 uint32_t mask_cle;
71
72 uint32_t core_chipsel;
73};
74
75static DEFINE_SPINLOCK(davinci_nand_lock);
76
77#define to_davinci_nand(m) container_of(m, struct davinci_nand_info, mtd)
78
79
80static inline unsigned int davinci_nand_readl(struct davinci_nand_info *info,
81 int offset)
82{
83 return __raw_readl(info->base + offset);
84}
85
86static inline void davinci_nand_writel(struct davinci_nand_info *info,
87 int offset, unsigned long value)
88{
89 __raw_writel(value, info->base + offset);
90}
91
92/*----------------------------------------------------------------------*/
93
94/*
95 * Access to hardware control lines: ALE, CLE, secondary chipselect.
96 */
97
98static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd,
99 unsigned int ctrl)
100{
101 struct davinci_nand_info *info = to_davinci_nand(mtd);
102 uint32_t addr = info->current_cs;
103 struct nand_chip *nand = mtd->priv;
104
105 /* Did the control lines change? */
106 if (ctrl & NAND_CTRL_CHANGE) {
107 if ((ctrl & NAND_CTRL_CLE) == NAND_CTRL_CLE)
108 addr |= info->mask_cle;
109 else if ((ctrl & NAND_CTRL_ALE) == NAND_CTRL_ALE)
110 addr |= info->mask_ale;
111
112 nand->IO_ADDR_W = (void __iomem __force *)addr;
113 }
114
115 if (cmd != NAND_CMD_NONE)
116 iowrite8(cmd, nand->IO_ADDR_W);
117}
118
119static void nand_davinci_select_chip(struct mtd_info *mtd, int chip)
120{
121 struct davinci_nand_info *info = to_davinci_nand(mtd);
122 uint32_t addr = info->ioaddr;
123
124 /* maybe kick in a second chipselect */
125 if (chip > 0)
126 addr |= info->mask_chipsel;
127 info->current_cs = addr;
128
129 info->chip.IO_ADDR_W = (void __iomem __force *)addr;
130 info->chip.IO_ADDR_R = info->chip.IO_ADDR_W;
131}
132
133/*----------------------------------------------------------------------*/
134
135/*
136 * 1-bit hardware ECC ... context maintained for each core chipselect
137 */
138
139static inline uint32_t nand_davinci_readecc_1bit(struct mtd_info *mtd)
140{
141 struct davinci_nand_info *info = to_davinci_nand(mtd);
142
143 return davinci_nand_readl(info, NANDF1ECC_OFFSET
144 + 4 * info->core_chipsel);
145}
146
147static void nand_davinci_hwctl_1bit(struct mtd_info *mtd, int mode)
148{
149 struct davinci_nand_info *info;
150 uint32_t nandcfr;
151 unsigned long flags;
152
153 info = to_davinci_nand(mtd);
154
155 /* Reset ECC hardware */
156 nand_davinci_readecc_1bit(mtd);
157
158 spin_lock_irqsave(&davinci_nand_lock, flags);
159
160 /* Restart ECC hardware */
161 nandcfr = davinci_nand_readl(info, NANDFCR_OFFSET);
162 nandcfr |= BIT(8 + info->core_chipsel);
163 davinci_nand_writel(info, NANDFCR_OFFSET, nandcfr);
164
165 spin_unlock_irqrestore(&davinci_nand_lock, flags);
166}
167
168/*
169 * Read hardware ECC value and pack into three bytes
170 */
171static int nand_davinci_calculate_1bit(struct mtd_info *mtd,
172 const u_char *dat, u_char *ecc_code)
173{
174 unsigned int ecc_val = nand_davinci_readecc_1bit(mtd);
175 unsigned int ecc24 = (ecc_val & 0x0fff) | ((ecc_val & 0x0fff0000) >> 4);
176
177 /* invert so that erased block ecc is correct */
178 ecc24 = ~ecc24;
179 ecc_code[0] = (u_char)(ecc24);
180 ecc_code[1] = (u_char)(ecc24 >> 8);
181 ecc_code[2] = (u_char)(ecc24 >> 16);
182
183 return 0;
184}
185
186static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat,
187 u_char *read_ecc, u_char *calc_ecc)
188{
189 struct nand_chip *chip = mtd->priv;
190 uint32_t eccNand = read_ecc[0] | (read_ecc[1] << 8) |
191 (read_ecc[2] << 16);
192 uint32_t eccCalc = calc_ecc[0] | (calc_ecc[1] << 8) |
193 (calc_ecc[2] << 16);
194 uint32_t diff = eccCalc ^ eccNand;
195
196 if (diff) {
197 if ((((diff >> 12) ^ diff) & 0xfff) == 0xfff) {
198 /* Correctable error */
199 if ((diff >> (12 + 3)) < chip->ecc.size) {
200 dat[diff >> (12 + 3)] ^= BIT((diff >> 12) & 7);
201 return 1;
202 } else {
203 return -1;
204 }
205 } else if (!(diff & (diff - 1))) {
206 /* Single bit ECC error in the ECC itself,
207 * nothing to fix */
208 return 1;
209 } else {
210 /* Uncorrectable error */
211 return -1;
212 }
213
214 }
215 return 0;
216}
217
218/*----------------------------------------------------------------------*/
219
220/*
221 * NOTE: NAND boot requires ALE == EM_A[1], CLE == EM_A[2], so that's
222 * how these chips are normally wired. This translates to both 8 and 16
223 * bit busses using ALE == BIT(3) in byte addresses, and CLE == BIT(4).
224 *
225 * For now we assume that configuration, or any other one which ignores
226 * the two LSBs for NAND access ... so we can issue 32-bit reads/writes
227 * and have that transparently morphed into multiple NAND operations.
228 */
229static void nand_davinci_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
230{
231 struct nand_chip *chip = mtd->priv;
232
233 if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0)
234 ioread32_rep(chip->IO_ADDR_R, buf, len >> 2);
235 else if ((0x01 & ((unsigned)buf)) == 0 && (0x01 & len) == 0)
236 ioread16_rep(chip->IO_ADDR_R, buf, len >> 1);
237 else
238 ioread8_rep(chip->IO_ADDR_R, buf, len);
239}
240
241static void nand_davinci_write_buf(struct mtd_info *mtd,
242 const uint8_t *buf, int len)
243{
244 struct nand_chip *chip = mtd->priv;
245
246 if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0)
247 iowrite32_rep(chip->IO_ADDR_R, buf, len >> 2);
248 else if ((0x01 & ((unsigned)buf)) == 0 && (0x01 & len) == 0)
249 iowrite16_rep(chip->IO_ADDR_R, buf, len >> 1);
250 else
251 iowrite8_rep(chip->IO_ADDR_R, buf, len);
252}
253
254/*
255 * Check hardware register for wait status. Returns 1 if device is ready,
256 * 0 if it is still busy.
257 */
258static int nand_davinci_dev_ready(struct mtd_info *mtd)
259{
260 struct davinci_nand_info *info = to_davinci_nand(mtd);
261
262 return davinci_nand_readl(info, NANDFSR_OFFSET) & BIT(0);
263}
264
265static void __init nand_dm6446evm_flash_init(struct davinci_nand_info *info)
266{
267 uint32_t regval, a1cr;
268
269 /*
270 * NAND FLASH timings @ PLL1 == 459 MHz
271 * - AEMIF.CLK freq = PLL1/6 = 459/6 = 76.5 MHz
272 * - AEMIF.CLK period = 1/76.5 MHz = 13.1 ns
273 */
274 regval = 0
275 | (0 << 31) /* selectStrobe */
276 | (0 << 30) /* extWait (never with NAND) */
277 | (1 << 26) /* writeSetup 10 ns */
278 | (3 << 20) /* writeStrobe 40 ns */
279 | (1 << 17) /* writeHold 10 ns */
280 | (0 << 13) /* readSetup 10 ns */
281 | (3 << 7) /* readStrobe 60 ns */
282 | (0 << 4) /* readHold 10 ns */
283 | (3 << 2) /* turnAround ?? ns */
284 | (0 << 0) /* asyncSize 8-bit bus */
285 ;
286 a1cr = davinci_nand_readl(info, A1CR_OFFSET);
287 if (a1cr != regval) {
288 dev_dbg(info->dev, "Warning: NAND config: Set A1CR " \
289 "reg to 0x%08x, was 0x%08x, should be done by " \
290 "bootloader.\n", regval, a1cr);
291 davinci_nand_writel(info, A1CR_OFFSET, regval);
292 }
293}
294
295/*----------------------------------------------------------------------*/
296
297static int __init nand_davinci_probe(struct platform_device *pdev)
298{
299 struct davinci_nand_pdata *pdata = pdev->dev.platform_data;
300 struct davinci_nand_info *info;
301 struct resource *res1;
302 struct resource *res2;
303 void __iomem *vaddr;
304 void __iomem *base;
305 int ret;
306 uint32_t val;
307 nand_ecc_modes_t ecc_mode;
308
309 /* which external chipselect will we be managing? */
310 if (pdev->id < 0 || pdev->id > 3)
311 return -ENODEV;
312
313 info = kzalloc(sizeof(*info), GFP_KERNEL);
314 if (!info) {
315 dev_err(&pdev->dev, "unable to allocate memory\n");
316 ret = -ENOMEM;
317 goto err_nomem;
318 }
319
320 platform_set_drvdata(pdev, info);
321
322 res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
323 res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
324 if (!res1 || !res2) {
325 dev_err(&pdev->dev, "resource missing\n");
326 ret = -EINVAL;
327 goto err_nomem;
328 }
329
330 vaddr = ioremap(res1->start, res1->end - res1->start);
331 base = ioremap(res2->start, res2->end - res2->start);
332 if (!vaddr || !base) {
333 dev_err(&pdev->dev, "ioremap failed\n");
334 ret = -EINVAL;
335 goto err_ioremap;
336 }
337
338 info->dev = &pdev->dev;
339 info->base = base;
340 info->vaddr = vaddr;
341
342 info->mtd.priv = &info->chip;
343 info->mtd.name = dev_name(&pdev->dev);
344 info->mtd.owner = THIS_MODULE;
345
346 info->mtd.dev.parent = &pdev->dev;
347
348 info->chip.IO_ADDR_R = vaddr;
349 info->chip.IO_ADDR_W = vaddr;
350 info->chip.chip_delay = 0;
351 info->chip.select_chip = nand_davinci_select_chip;
352
353 /* options such as NAND_USE_FLASH_BBT or 16-bit widths */
354 info->chip.options = pdata ? pdata->options : 0;
355
356 info->ioaddr = (uint32_t __force) vaddr;
357
358 info->current_cs = info->ioaddr;
359 info->core_chipsel = pdev->id;
360 info->mask_chipsel = pdata->mask_chipsel;
361
362 /* use nandboot-capable ALE/CLE masks by default */
363 if (pdata && pdata->mask_ale)
364 info->mask_ale = pdata->mask_cle;
365 else
366 info->mask_ale = MASK_ALE;
367 if (pdata && pdata->mask_cle)
368 info->mask_cle = pdata->mask_cle;
369 else
370 info->mask_cle = MASK_CLE;
371
372 /* Set address of hardware control function */
373 info->chip.cmd_ctrl = nand_davinci_hwcontrol;
374 info->chip.dev_ready = nand_davinci_dev_ready;
375
376 /* Speed up buffer I/O */
377 info->chip.read_buf = nand_davinci_read_buf;
378 info->chip.write_buf = nand_davinci_write_buf;
379
380 /* use board-specific ECC config; else, the best available */
381 if (pdata)
382 ecc_mode = pdata->ecc_mode;
383 else
384 ecc_mode = NAND_ECC_HW;
385
386 switch (ecc_mode) {
387 case NAND_ECC_NONE:
388 case NAND_ECC_SOFT:
389 break;
390 case NAND_ECC_HW:
391 info->chip.ecc.calculate = nand_davinci_calculate_1bit;
392 info->chip.ecc.correct = nand_davinci_correct_1bit;
393 info->chip.ecc.hwctl = nand_davinci_hwctl_1bit;
394 info->chip.ecc.size = 512;
395 info->chip.ecc.bytes = 3;
396 break;
397 case NAND_ECC_HW_SYNDROME:
398 /* FIXME implement */
399 info->chip.ecc.size = 512;
400 info->chip.ecc.bytes = 10;
401
402 dev_warn(&pdev->dev, "4-bit ECC nyet supported\n");
403 /* FALL THROUGH */
404 default:
405 ret = -EINVAL;
406 goto err_ecc;
407 }
408 info->chip.ecc.mode = ecc_mode;
409
410 info->clk = clk_get(&pdev->dev, "AEMIFCLK");
411 if (IS_ERR(info->clk)) {
412 ret = PTR_ERR(info->clk);
413 dev_dbg(&pdev->dev, "unable to get AEMIFCLK, err %d\n", ret);
414 goto err_clk;
415 }
416
417 ret = clk_enable(info->clk);
418 if (ret < 0) {
419 dev_dbg(&pdev->dev, "unable to enable AEMIFCLK, err %d\n", ret);
420 goto err_clk_enable;
421 }
422
423 /* EMIF timings should normally be set by the boot loader,
424 * especially after boot-from-NAND. The *only* reason to
425 * have this special casing for the DM6446 EVM is to work
426 * with boot-from-NOR ... with CS0 manually re-jumpered
427 * (after startup) so it addresses the NAND flash, not NOR.
428 * Even for dev boards, that's unusually rude...
429 */
430 if (machine_is_davinci_evm())
431 nand_dm6446evm_flash_init(info);
432
433 spin_lock_irq(&davinci_nand_lock);
434
435 /* put CSxNAND into NAND mode */
436 val = davinci_nand_readl(info, NANDFCR_OFFSET);
437 val |= BIT(info->core_chipsel);
438 davinci_nand_writel(info, NANDFCR_OFFSET, val);
439
440 spin_unlock_irq(&davinci_nand_lock);
441
442 /* Scan to find existence of the device(s) */
443 ret = nand_scan(&info->mtd, pdata->mask_chipsel ? 2 : 1);
444 if (ret < 0) {
445 dev_dbg(&pdev->dev, "no NAND chip(s) found\n");
446 goto err_scan;
447 }
448
449 if (mtd_has_partitions()) {
450 struct mtd_partition *mtd_parts = NULL;
451 int mtd_parts_nb = 0;
452
453 if (mtd_has_cmdlinepart()) {
454 static const char *probes[] __initconst =
455 { "cmdlinepart", NULL };
456
457 const char *master_name;
458
459 /* Set info->mtd.name = 0 temporarily */
460 master_name = info->mtd.name;
461 info->mtd.name = (char *)0;
462
463 /* info->mtd.name == 0, means: don't bother checking
464 <mtd-id> */
465 mtd_parts_nb = parse_mtd_partitions(&info->mtd, probes,
466 &mtd_parts, 0);
467
468 /* Restore info->mtd.name */
469 info->mtd.name = master_name;
470 }
471
472 if (mtd_parts_nb <= 0 && pdata) {
473 mtd_parts = pdata->parts;
474 mtd_parts_nb = pdata->nr_parts;
475 }
476
477 /* Register any partitions */
478 if (mtd_parts_nb > 0) {
479 ret = add_mtd_partitions(&info->mtd,
480 mtd_parts, mtd_parts_nb);
481 if (ret == 0)
482 info->partitioned = true;
483 }
484
485 } else if (pdata && pdata->nr_parts) {
486 dev_warn(&pdev->dev, "ignoring %d default partitions on %s\n",
487 pdata->nr_parts, info->mtd.name);
488 }
489
490 /* If there's no partition info, just package the whole chip
491 * as a single MTD device.
492 */
493 if (!info->partitioned)
494 ret = add_mtd_device(&info->mtd) ? -ENODEV : 0;
495
496 if (ret < 0)
497 goto err_scan;
498
499 val = davinci_nand_readl(info, NRCSR_OFFSET);
500 dev_info(&pdev->dev, "controller rev. %d.%d\n",
501 (val >> 8) & 0xff, val & 0xff);
502
503 return 0;
504
505err_scan:
506 clk_disable(info->clk);
507
508err_clk_enable:
509 clk_put(info->clk);
510
511err_ecc:
512err_clk:
513err_ioremap:
514 if (base)
515 iounmap(base);
516 if (vaddr)
517 iounmap(vaddr);
518
519err_nomem:
520 kfree(info);
521 return ret;
522}
523
524static int __exit nand_davinci_remove(struct platform_device *pdev)
525{
526 struct davinci_nand_info *info = platform_get_drvdata(pdev);
527 int status;
528
529 if (mtd_has_partitions() && info->partitioned)
530 status = del_mtd_partitions(&info->mtd);
531 else
532 status = del_mtd_device(&info->mtd);
533
534 iounmap(info->base);
535 iounmap(info->vaddr);
536
537 nand_release(&info->mtd);
538
539 clk_disable(info->clk);
540 clk_put(info->clk);
541
542 kfree(info);
543
544 return 0;
545}
546
547static struct platform_driver nand_davinci_driver = {
548 .remove = __exit_p(nand_davinci_remove),
549 .driver = {
550 .name = "davinci_nand",
551 },
552};
553MODULE_ALIAS("platform:davinci_nand");
554
555static int __init nand_davinci_init(void)
556{
557 return platform_driver_probe(&nand_davinci_driver, nand_davinci_probe);
558}
559module_init(nand_davinci_init);
560
561static void __exit nand_davinci_exit(void)
562{
563 platform_driver_unregister(&nand_davinci_driver);
564}
565module_exit(nand_davinci_exit);
566
567MODULE_LICENSE("GPL");
568MODULE_AUTHOR("Texas Instruments");
569MODULE_DESCRIPTION("Davinci NAND flash driver");
570
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index e4226e02d63e..e51c1ed7ac18 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -1773,4 +1773,4 @@ module_exit(cleanup_nanddoc);
1773 1773
1774MODULE_LICENSE("GPL"); 1774MODULE_LICENSE("GPL");
1775MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 1775MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
1776MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver\n"); 1776MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver");
diff --git a/drivers/mtd/nand/excite_nandflash.c b/drivers/mtd/nand/excite_nandflash.c
index ced14b5294d5..72446fb48d4b 100644
--- a/drivers/mtd/nand/excite_nandflash.c
+++ b/drivers/mtd/nand/excite_nandflash.c
@@ -128,11 +128,11 @@ static int excite_nand_devready(struct mtd_info *mtd)
128 * The binding to the mtd and all allocated 128 * The binding to the mtd and all allocated
129 * resources are released. 129 * resources are released.
130 */ 130 */
131static int __exit excite_nand_remove(struct device *dev) 131static int __exit excite_nand_remove(struct platform_device *dev)
132{ 132{
133 struct excite_nand_drvdata * const this = dev_get_drvdata(dev); 133 struct excite_nand_drvdata * const this = platform_get_drvdata(dev);
134 134
135 dev_set_drvdata(dev, NULL); 135 platform_set_drvdata(dev, NULL);
136 136
137 if (unlikely(!this)) { 137 if (unlikely(!this)) {
138 printk(KERN_ERR "%s: called %s without private data!!", 138 printk(KERN_ERR "%s: called %s without private data!!",
@@ -159,9 +159,8 @@ static int __exit excite_nand_remove(struct device *dev)
159 * it can allocate all necessary resources then calls the 159 * it can allocate all necessary resources then calls the
160 * nand layer to look for devices. 160 * nand layer to look for devices.
161*/ 161*/
162static int __init excite_nand_probe(struct device *dev) 162static int __init excite_nand_probe(struct platform_device *pdev)
163{ 163{
164 struct platform_device * const pdev = to_platform_device(dev);
165 struct excite_nand_drvdata *drvdata; /* private driver data */ 164 struct excite_nand_drvdata *drvdata; /* private driver data */
166 struct nand_chip *board_chip; /* private flash chip data */ 165 struct nand_chip *board_chip; /* private flash chip data */
167 struct mtd_info *board_mtd; /* mtd info for this board */ 166 struct mtd_info *board_mtd; /* mtd info for this board */
@@ -175,7 +174,7 @@ static int __init excite_nand_probe(struct device *dev)
175 } 174 }
176 175
177 /* bind private data into driver */ 176 /* bind private data into driver */
178 dev_set_drvdata(dev, drvdata); 177 platform_set_drvdata(pdev, drvdata);
179 178
180 /* allocate and map the resource */ 179 /* allocate and map the resource */
181 drvdata->regs = 180 drvdata->regs =
@@ -219,23 +218,25 @@ static int __init excite_nand_probe(struct device *dev)
219 return 0; 218 return 0;
220} 219}
221 220
222static struct device_driver excite_nand_driver = { 221static struct platform_driver excite_nand_driver = {
223 .name = "excite_nand", 222 .driver = {
224 .bus = &platform_bus_type, 223 .name = "excite_nand",
224 .owner = THIS_MODULE,
225 },
225 .probe = excite_nand_probe, 226 .probe = excite_nand_probe,
226 .remove = __exit_p(excite_nand_remove) 227 .remove = __devexit_p(excite_nand_remove)
227}; 228};
228 229
229static int __init excite_nand_init(void) 230static int __init excite_nand_init(void)
230{ 231{
231 pr_info("Basler eXcite nand flash driver Version " 232 pr_info("Basler eXcite nand flash driver Version "
232 EXCITE_NANDFLASH_VERSION "\n"); 233 EXCITE_NANDFLASH_VERSION "\n");
233 return driver_register(&excite_nand_driver); 234 return platform_driver_register(&excite_nand_driver);
234} 235}
235 236
236static void __exit excite_nand_exit(void) 237static void __exit excite_nand_exit(void)
237{ 238{
238 driver_unregister(&excite_nand_driver); 239 platform_driver_unregister(&excite_nand_driver);
239} 240}
240 241
241module_init(excite_nand_init); 242module_init(excite_nand_init);
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c
index 7815a404a632..d120cd8d7267 100644
--- a/drivers/mtd/nand/fsl_upm.c
+++ b/drivers/mtd/nand/fsl_upm.c
@@ -23,6 +23,10 @@
23#include <linux/io.h> 23#include <linux/io.h>
24#include <asm/fsl_lbc.h> 24#include <asm/fsl_lbc.h>
25 25
26#define FSL_UPM_WAIT_RUN_PATTERN 0x1
27#define FSL_UPM_WAIT_WRITE_BYTE 0x2
28#define FSL_UPM_WAIT_WRITE_BUFFER 0x4
29
26struct fsl_upm_nand { 30struct fsl_upm_nand {
27 struct device *dev; 31 struct device *dev;
28 struct mtd_info mtd; 32 struct mtd_info mtd;
@@ -36,8 +40,12 @@ struct fsl_upm_nand {
36 uint8_t upm_addr_offset; 40 uint8_t upm_addr_offset;
37 uint8_t upm_cmd_offset; 41 uint8_t upm_cmd_offset;
38 void __iomem *io_base; 42 void __iomem *io_base;
39 int rnb_gpio; 43 int rnb_gpio[NAND_MAX_CHIPS];
44 uint32_t mchip_offsets[NAND_MAX_CHIPS];
45 uint32_t mchip_count;
46 uint32_t mchip_number;
40 int chip_delay; 47 int chip_delay;
48 uint32_t wait_flags;
41}; 49};
42 50
43#define to_fsl_upm_nand(mtd) container_of(mtd, struct fsl_upm_nand, mtd) 51#define to_fsl_upm_nand(mtd) container_of(mtd, struct fsl_upm_nand, mtd)
@@ -46,7 +54,7 @@ static int fun_chip_ready(struct mtd_info *mtd)
46{ 54{
47 struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd); 55 struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd);
48 56
49 if (gpio_get_value(fun->rnb_gpio)) 57 if (gpio_get_value(fun->rnb_gpio[fun->mchip_number]))
50 return 1; 58 return 1;
51 59
52 dev_vdbg(fun->dev, "busy\n"); 60 dev_vdbg(fun->dev, "busy\n");
@@ -55,9 +63,9 @@ static int fun_chip_ready(struct mtd_info *mtd)
55 63
56static void fun_wait_rnb(struct fsl_upm_nand *fun) 64static void fun_wait_rnb(struct fsl_upm_nand *fun)
57{ 65{
58 int cnt = 1000000; 66 if (fun->rnb_gpio[fun->mchip_number] >= 0) {
67 int cnt = 1000000;
59 68
60 if (fun->rnb_gpio >= 0) {
61 while (--cnt && !fun_chip_ready(&fun->mtd)) 69 while (--cnt && !fun_chip_ready(&fun->mtd))
62 cpu_relax(); 70 cpu_relax();
63 if (!cnt) 71 if (!cnt)
@@ -69,7 +77,9 @@ static void fun_wait_rnb(struct fsl_upm_nand *fun)
69 77
70static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) 78static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
71{ 79{
80 struct nand_chip *chip = mtd->priv;
72 struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd); 81 struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd);
82 u32 mar;
73 83
74 if (!(ctrl & fun->last_ctrl)) { 84 if (!(ctrl & fun->last_ctrl)) {
75 fsl_upm_end_pattern(&fun->upm); 85 fsl_upm_end_pattern(&fun->upm);
@@ -87,9 +97,28 @@ static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
87 fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset); 97 fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset);
88 } 98 }
89 99
90 fsl_upm_run_pattern(&fun->upm, fun->io_base, cmd); 100 mar = (cmd << (32 - fun->upm.width)) |
101 fun->mchip_offsets[fun->mchip_number];
102 fsl_upm_run_pattern(&fun->upm, chip->IO_ADDR_R, mar);
103
104 if (fun->wait_flags & FSL_UPM_WAIT_RUN_PATTERN)
105 fun_wait_rnb(fun);
106}
107
108static void fun_select_chip(struct mtd_info *mtd, int mchip_nr)
109{
110 struct nand_chip *chip = mtd->priv;
111 struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd);
91 112
92 fun_wait_rnb(fun); 113 if (mchip_nr == -1) {
114 chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
115 } else if (mchip_nr >= 0) {
116 fun->mchip_number = mchip_nr;
117 chip->IO_ADDR_R = fun->io_base + fun->mchip_offsets[mchip_nr];
118 chip->IO_ADDR_W = chip->IO_ADDR_R;
119 } else {
120 BUG();
121 }
93} 122}
94 123
95static uint8_t fun_read_byte(struct mtd_info *mtd) 124static uint8_t fun_read_byte(struct mtd_info *mtd)
@@ -115,8 +144,11 @@ static void fun_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
115 144
116 for (i = 0; i < len; i++) { 145 for (i = 0; i < len; i++) {
117 out_8(fun->chip.IO_ADDR_W, buf[i]); 146 out_8(fun->chip.IO_ADDR_W, buf[i]);
118 fun_wait_rnb(fun); 147 if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BYTE)
148 fun_wait_rnb(fun);
119 } 149 }
150 if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BUFFER)
151 fun_wait_rnb(fun);
120} 152}
121 153
122static int __devinit fun_chip_init(struct fsl_upm_nand *fun, 154static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
@@ -137,8 +169,10 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
137 fun->chip.read_buf = fun_read_buf; 169 fun->chip.read_buf = fun_read_buf;
138 fun->chip.write_buf = fun_write_buf; 170 fun->chip.write_buf = fun_write_buf;
139 fun->chip.ecc.mode = NAND_ECC_SOFT; 171 fun->chip.ecc.mode = NAND_ECC_SOFT;
172 if (fun->mchip_count > 1)
173 fun->chip.select_chip = fun_select_chip;
140 174
141 if (fun->rnb_gpio >= 0) 175 if (fun->rnb_gpio[0] >= 0)
142 fun->chip.dev_ready = fun_chip_ready; 176 fun->chip.dev_ready = fun_chip_ready;
143 177
144 fun->mtd.priv = &fun->chip; 178 fun->mtd.priv = &fun->chip;
@@ -155,7 +189,7 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
155 goto err; 189 goto err;
156 } 190 }
157 191
158 ret = nand_scan(&fun->mtd, 1); 192 ret = nand_scan(&fun->mtd, fun->mchip_count);
159 if (ret) 193 if (ret)
160 goto err; 194 goto err;
161 195
@@ -185,8 +219,10 @@ static int __devinit fun_probe(struct of_device *ofdev,
185 struct fsl_upm_nand *fun; 219 struct fsl_upm_nand *fun;
186 struct resource io_res; 220 struct resource io_res;
187 const uint32_t *prop; 221 const uint32_t *prop;
222 int rnb_gpio;
188 int ret; 223 int ret;
189 int size; 224 int size;
225 int i;
190 226
191 fun = kzalloc(sizeof(*fun), GFP_KERNEL); 227 fun = kzalloc(sizeof(*fun), GFP_KERNEL);
192 if (!fun) 228 if (!fun)
@@ -208,7 +244,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
208 if (!prop || size != sizeof(uint32_t)) { 244 if (!prop || size != sizeof(uint32_t)) {
209 dev_err(&ofdev->dev, "can't get UPM address offset\n"); 245 dev_err(&ofdev->dev, "can't get UPM address offset\n");
210 ret = -EINVAL; 246 ret = -EINVAL;
211 goto err2; 247 goto err1;
212 } 248 }
213 fun->upm_addr_offset = *prop; 249 fun->upm_addr_offset = *prop;
214 250
@@ -216,21 +252,40 @@ static int __devinit fun_probe(struct of_device *ofdev,
216 if (!prop || size != sizeof(uint32_t)) { 252 if (!prop || size != sizeof(uint32_t)) {
217 dev_err(&ofdev->dev, "can't get UPM command offset\n"); 253 dev_err(&ofdev->dev, "can't get UPM command offset\n");
218 ret = -EINVAL; 254 ret = -EINVAL;
219 goto err2; 255 goto err1;
220 } 256 }
221 fun->upm_cmd_offset = *prop; 257 fun->upm_cmd_offset = *prop;
222 258
223 fun->rnb_gpio = of_get_gpio(ofdev->node, 0); 259 prop = of_get_property(ofdev->node,
224 if (fun->rnb_gpio >= 0) { 260 "fsl,upm-addr-line-cs-offsets", &size);
225 ret = gpio_request(fun->rnb_gpio, dev_name(&ofdev->dev)); 261 if (prop && (size / sizeof(uint32_t)) > 0) {
226 if (ret) { 262 fun->mchip_count = size / sizeof(uint32_t);
227 dev_err(&ofdev->dev, "can't request RNB gpio\n"); 263 if (fun->mchip_count >= NAND_MAX_CHIPS) {
264 dev_err(&ofdev->dev, "too much multiple chips\n");
265 goto err1;
266 }
267 for (i = 0; i < fun->mchip_count; i++)
268 fun->mchip_offsets[i] = prop[i];
269 } else {
270 fun->mchip_count = 1;
271 }
272
273 for (i = 0; i < fun->mchip_count; i++) {
274 fun->rnb_gpio[i] = -1;
275 rnb_gpio = of_get_gpio(ofdev->node, i);
276 if (rnb_gpio >= 0) {
277 ret = gpio_request(rnb_gpio, dev_name(&ofdev->dev));
278 if (ret) {
279 dev_err(&ofdev->dev,
280 "can't request RNB gpio #%d\n", i);
281 goto err2;
282 }
283 gpio_direction_input(rnb_gpio);
284 fun->rnb_gpio[i] = rnb_gpio;
285 } else if (rnb_gpio == -EINVAL) {
286 dev_err(&ofdev->dev, "RNB gpio #%d is invalid\n", i);
228 goto err2; 287 goto err2;
229 } 288 }
230 gpio_direction_input(fun->rnb_gpio);
231 } else if (fun->rnb_gpio == -EINVAL) {
232 dev_err(&ofdev->dev, "specified RNB gpio is invalid\n");
233 goto err2;
234 } 289 }
235 290
236 prop = of_get_property(ofdev->node, "chip-delay", NULL); 291 prop = of_get_property(ofdev->node, "chip-delay", NULL);
@@ -239,8 +294,15 @@ static int __devinit fun_probe(struct of_device *ofdev,
239 else 294 else
240 fun->chip_delay = 50; 295 fun->chip_delay = 50;
241 296
297 prop = of_get_property(ofdev->node, "fsl,upm-wait-flags", &size);
298 if (prop && size == sizeof(uint32_t))
299 fun->wait_flags = *prop;
300 else
301 fun->wait_flags = FSL_UPM_WAIT_RUN_PATTERN |
302 FSL_UPM_WAIT_WRITE_BYTE;
303
242 fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start, 304 fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start,
243 io_res.end - io_res.start + 1); 305 io_res.end - io_res.start + 1);
244 if (!fun->io_base) { 306 if (!fun->io_base) {
245 ret = -ENOMEM; 307 ret = -ENOMEM;
246 goto err2; 308 goto err2;
@@ -257,8 +319,11 @@ static int __devinit fun_probe(struct of_device *ofdev,
257 319
258 return 0; 320 return 0;
259err2: 321err2:
260 if (fun->rnb_gpio >= 0) 322 for (i = 0; i < fun->mchip_count; i++) {
261 gpio_free(fun->rnb_gpio); 323 if (fun->rnb_gpio[i] < 0)
324 break;
325 gpio_free(fun->rnb_gpio[i]);
326 }
262err1: 327err1:
263 kfree(fun); 328 kfree(fun);
264 329
@@ -268,12 +333,16 @@ err1:
268static int __devexit fun_remove(struct of_device *ofdev) 333static int __devexit fun_remove(struct of_device *ofdev)
269{ 334{
270 struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev); 335 struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev);
336 int i;
271 337
272 nand_release(&fun->mtd); 338 nand_release(&fun->mtd);
273 kfree(fun->mtd.name); 339 kfree(fun->mtd.name);
274 340
275 if (fun->rnb_gpio >= 0) 341 for (i = 0; i < fun->mchip_count; i++) {
276 gpio_free(fun->rnb_gpio); 342 if (fun->rnb_gpio[i] < 0)
343 break;
344 gpio_free(fun->rnb_gpio[i]);
345 }
277 346
278 kfree(fun); 347 kfree(fun);
279 348
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 21fd4f1c4806..f3548d048014 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -866,6 +866,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
866 mtd = &host->mtd; 866 mtd = &host->mtd;
867 mtd->priv = this; 867 mtd->priv = this;
868 mtd->owner = THIS_MODULE; 868 mtd->owner = THIS_MODULE;
869 mtd->dev.parent = &pdev->dev;
869 870
870 /* 50 us command delay time */ 871 /* 50 us command delay time */
871 this->chip_delay = 5; 872 this->chip_delay = 5;
@@ -880,7 +881,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
880 this->read_buf = mxc_nand_read_buf; 881 this->read_buf = mxc_nand_read_buf;
881 this->verify_buf = mxc_nand_verify_buf; 882 this->verify_buf = mxc_nand_verify_buf;
882 883
883 host->clk = clk_get(&pdev->dev, "nfc_clk"); 884 host->clk = clk_get(&pdev->dev, "nfc");
884 if (IS_ERR(host->clk)) 885 if (IS_ERR(host->clk))
885 goto eclk; 886 goto eclk;
886 887
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 0c3afccde8a2..3d7ed432fa41 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -82,6 +82,20 @@ static struct nand_ecclayout nand_oob_64 = {
82 .length = 38}} 82 .length = 38}}
83}; 83};
84 84
85static struct nand_ecclayout nand_oob_128 = {
86 .eccbytes = 48,
87 .eccpos = {
88 80, 81, 82, 83, 84, 85, 86, 87,
89 88, 89, 90, 91, 92, 93, 94, 95,
90 96, 97, 98, 99, 100, 101, 102, 103,
91 104, 105, 106, 107, 108, 109, 110, 111,
92 112, 113, 114, 115, 116, 117, 118, 119,
93 120, 121, 122, 123, 124, 125, 126, 127},
94 .oobfree = {
95 {.offset = 2,
96 .length = 78}}
97};
98
85static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, 99static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd,
86 int new_state); 100 int new_state);
87 101
@@ -748,6 +762,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
748 * @mtd: mtd info structure 762 * @mtd: mtd info structure
749 * @chip: nand chip info structure 763 * @chip: nand chip info structure
750 * @buf: buffer to store read data 764 * @buf: buffer to store read data
765 *
766 * Not for syndrome calculating ecc controllers, which use a special oob layout
751 */ 767 */
752static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, 768static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
753 uint8_t *buf) 769 uint8_t *buf)
@@ -758,6 +774,47 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
758} 774}
759 775
760/** 776/**
777 * nand_read_page_raw_syndrome - [Intern] read raw page data without ecc
778 * @mtd: mtd info structure
779 * @chip: nand chip info structure
780 * @buf: buffer to store read data
781 *
782 * We need a special oob layout and handling even when OOB isn't used.
783 */
784static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
785 uint8_t *buf)
786{
787 int eccsize = chip->ecc.size;
788 int eccbytes = chip->ecc.bytes;
789 uint8_t *oob = chip->oob_poi;
790 int steps, size;
791
792 for (steps = chip->ecc.steps; steps > 0; steps--) {
793 chip->read_buf(mtd, buf, eccsize);
794 buf += eccsize;
795
796 if (chip->ecc.prepad) {
797 chip->read_buf(mtd, oob, chip->ecc.prepad);
798 oob += chip->ecc.prepad;
799 }
800
801 chip->read_buf(mtd, oob, eccbytes);
802 oob += eccbytes;
803
804 if (chip->ecc.postpad) {
805 chip->read_buf(mtd, oob, chip->ecc.postpad);
806 oob += chip->ecc.postpad;
807 }
808 }
809
810 size = mtd->oobsize - (oob - chip->oob_poi);
811 if (size)
812 chip->read_buf(mtd, oob, size);
813
814 return 0;
815}
816
817/**
761 * nand_read_page_swecc - [REPLACABLE] software ecc based page read function 818 * nand_read_page_swecc - [REPLACABLE] software ecc based page read function
762 * @mtd: mtd info structure 819 * @mtd: mtd info structure
763 * @chip: nand chip info structure 820 * @chip: nand chip info structure
@@ -1482,6 +1539,8 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
1482 * @mtd: mtd info structure 1539 * @mtd: mtd info structure
1483 * @chip: nand chip info structure 1540 * @chip: nand chip info structure
1484 * @buf: data buffer 1541 * @buf: data buffer
1542 *
1543 * Not for syndrome calculating ecc controllers, which use a special oob layout
1485 */ 1544 */
1486static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, 1545static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
1487 const uint8_t *buf) 1546 const uint8_t *buf)
@@ -1491,6 +1550,44 @@ static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
1491} 1550}
1492 1551
1493/** 1552/**
1553 * nand_write_page_raw_syndrome - [Intern] raw page write function
1554 * @mtd: mtd info structure
1555 * @chip: nand chip info structure
1556 * @buf: data buffer
1557 *
1558 * We need a special oob layout and handling even when ECC isn't checked.
1559 */
1560static void nand_write_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
1561 const uint8_t *buf)
1562{
1563 int eccsize = chip->ecc.size;
1564 int eccbytes = chip->ecc.bytes;
1565 uint8_t *oob = chip->oob_poi;
1566 int steps, size;
1567
1568 for (steps = chip->ecc.steps; steps > 0; steps--) {
1569 chip->write_buf(mtd, buf, eccsize);
1570 buf += eccsize;
1571
1572 if (chip->ecc.prepad) {
1573 chip->write_buf(mtd, oob, chip->ecc.prepad);
1574 oob += chip->ecc.prepad;
1575 }
1576
1577 chip->read_buf(mtd, oob, eccbytes);
1578 oob += eccbytes;
1579
1580 if (chip->ecc.postpad) {
1581 chip->write_buf(mtd, oob, chip->ecc.postpad);
1582 oob += chip->ecc.postpad;
1583 }
1584 }
1585
1586 size = mtd->oobsize - (oob - chip->oob_poi);
1587 if (size)
1588 chip->write_buf(mtd, oob, size);
1589}
1590/**
1494 * nand_write_page_swecc - [REPLACABLE] software ecc based page write function 1591 * nand_write_page_swecc - [REPLACABLE] software ecc based page write function
1495 * @mtd: mtd info structure 1592 * @mtd: mtd info structure
1496 * @chip: nand chip info structure 1593 * @chip: nand chip info structure
@@ -1863,7 +1960,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
1863 } 1960 }
1864 1961
1865 if (unlikely(ops->ooboffs >= len)) { 1962 if (unlikely(ops->ooboffs >= len)) {
1866 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: " 1963 DEBUG(MTD_DEBUG_LEVEL0, "nand_do_write_oob: "
1867 "Attempt to start write outside oob\n"); 1964 "Attempt to start write outside oob\n");
1868 return -EINVAL; 1965 return -EINVAL;
1869 } 1966 }
@@ -1873,7 +1970,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
1873 ops->ooboffs + ops->ooblen > 1970 ops->ooboffs + ops->ooblen >
1874 ((mtd->size >> chip->page_shift) - 1971 ((mtd->size >> chip->page_shift) -
1875 (to >> chip->page_shift)) * len)) { 1972 (to >> chip->page_shift)) * len)) {
1876 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: " 1973 DEBUG(MTD_DEBUG_LEVEL0, "nand_do_write_oob: "
1877 "Attempt write beyond end of device\n"); 1974 "Attempt write beyond end of device\n");
1878 return -EINVAL; 1975 return -EINVAL;
1879 } 1976 }
@@ -1929,8 +2026,8 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
1929 2026
1930 /* Do not allow writes past end of device */ 2027 /* Do not allow writes past end of device */
1931 if (ops->datbuf && (to + ops->len) > mtd->size) { 2028 if (ops->datbuf && (to + ops->len) > mtd->size) {
1932 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: " 2029 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
1933 "Attempt read beyond end of device\n"); 2030 "Attempt write beyond end of device\n");
1934 return -EINVAL; 2031 return -EINVAL;
1935 } 2032 }
1936 2033
@@ -2555,6 +2652,9 @@ int nand_scan_tail(struct mtd_info *mtd)
2555 case 64: 2652 case 64:
2556 chip->ecc.layout = &nand_oob_64; 2653 chip->ecc.layout = &nand_oob_64;
2557 break; 2654 break;
2655 case 128:
2656 chip->ecc.layout = &nand_oob_128;
2657 break;
2558 default: 2658 default:
2559 printk(KERN_WARNING "No oob scheme defined for " 2659 printk(KERN_WARNING "No oob scheme defined for "
2560 "oobsize %d\n", mtd->oobsize); 2660 "oobsize %d\n", mtd->oobsize);
@@ -2569,10 +2669,6 @@ int nand_scan_tail(struct mtd_info *mtd)
2569 * check ECC mode, default to software if 3byte/512byte hardware ECC is 2669 * check ECC mode, default to software if 3byte/512byte hardware ECC is
2570 * selected and we have 256 byte pagesize fallback to software ECC 2670 * selected and we have 256 byte pagesize fallback to software ECC
2571 */ 2671 */
2572 if (!chip->ecc.read_page_raw)
2573 chip->ecc.read_page_raw = nand_read_page_raw;
2574 if (!chip->ecc.write_page_raw)
2575 chip->ecc.write_page_raw = nand_write_page_raw;
2576 2672
2577 switch (chip->ecc.mode) { 2673 switch (chip->ecc.mode) {
2578 case NAND_ECC_HW: 2674 case NAND_ECC_HW:
@@ -2581,6 +2677,10 @@ int nand_scan_tail(struct mtd_info *mtd)
2581 chip->ecc.read_page = nand_read_page_hwecc; 2677 chip->ecc.read_page = nand_read_page_hwecc;
2582 if (!chip->ecc.write_page) 2678 if (!chip->ecc.write_page)
2583 chip->ecc.write_page = nand_write_page_hwecc; 2679 chip->ecc.write_page = nand_write_page_hwecc;
2680 if (!chip->ecc.read_page_raw)
2681 chip->ecc.read_page_raw = nand_read_page_raw;
2682 if (!chip->ecc.write_page_raw)
2683 chip->ecc.write_page_raw = nand_write_page_raw;
2584 if (!chip->ecc.read_oob) 2684 if (!chip->ecc.read_oob)
2585 chip->ecc.read_oob = nand_read_oob_std; 2685 chip->ecc.read_oob = nand_read_oob_std;
2586 if (!chip->ecc.write_oob) 2686 if (!chip->ecc.write_oob)
@@ -2602,6 +2702,10 @@ int nand_scan_tail(struct mtd_info *mtd)
2602 chip->ecc.read_page = nand_read_page_syndrome; 2702 chip->ecc.read_page = nand_read_page_syndrome;
2603 if (!chip->ecc.write_page) 2703 if (!chip->ecc.write_page)
2604 chip->ecc.write_page = nand_write_page_syndrome; 2704 chip->ecc.write_page = nand_write_page_syndrome;
2705 if (!chip->ecc.read_page_raw)
2706 chip->ecc.read_page_raw = nand_read_page_raw_syndrome;
2707 if (!chip->ecc.write_page_raw)
2708 chip->ecc.write_page_raw = nand_write_page_raw_syndrome;
2605 if (!chip->ecc.read_oob) 2709 if (!chip->ecc.read_oob)
2606 chip->ecc.read_oob = nand_read_oob_syndrome; 2710 chip->ecc.read_oob = nand_read_oob_syndrome;
2607 if (!chip->ecc.write_oob) 2711 if (!chip->ecc.write_oob)
@@ -2620,6 +2724,8 @@ int nand_scan_tail(struct mtd_info *mtd)
2620 chip->ecc.read_page = nand_read_page_swecc; 2724 chip->ecc.read_page = nand_read_page_swecc;
2621 chip->ecc.read_subpage = nand_read_subpage; 2725 chip->ecc.read_subpage = nand_read_subpage;
2622 chip->ecc.write_page = nand_write_page_swecc; 2726 chip->ecc.write_page = nand_write_page_swecc;
2727 chip->ecc.read_page_raw = nand_read_page_raw;
2728 chip->ecc.write_page_raw = nand_write_page_raw;
2623 chip->ecc.read_oob = nand_read_oob_std; 2729 chip->ecc.read_oob = nand_read_oob_std;
2624 chip->ecc.write_oob = nand_write_oob_std; 2730 chip->ecc.write_oob = nand_write_oob_std;
2625 chip->ecc.size = 256; 2731 chip->ecc.size = 256;
@@ -2632,6 +2738,8 @@ int nand_scan_tail(struct mtd_info *mtd)
2632 chip->ecc.read_page = nand_read_page_raw; 2738 chip->ecc.read_page = nand_read_page_raw;
2633 chip->ecc.write_page = nand_write_page_raw; 2739 chip->ecc.write_page = nand_write_page_raw;
2634 chip->ecc.read_oob = nand_read_oob_std; 2740 chip->ecc.read_oob = nand_read_oob_std;
2741 chip->ecc.read_page_raw = nand_read_page_raw;
2742 chip->ecc.write_page_raw = nand_write_page_raw;
2635 chip->ecc.write_oob = nand_write_oob_std; 2743 chip->ecc.write_oob = nand_write_oob_std;
2636 chip->ecc.size = mtd->writesize; 2744 chip->ecc.size = mtd->writesize;
2637 chip->ecc.bytes = 0; 2745 chip->ecc.bytes = 0;
@@ -2676,6 +2784,7 @@ int nand_scan_tail(struct mtd_info *mtd)
2676 break; 2784 break;
2677 case 4: 2785 case 4:
2678 case 8: 2786 case 8:
2787 case 16:
2679 mtd->subpage_sft = 2; 2788 mtd->subpage_sft = 2;
2680 break; 2789 break;
2681 } 2790 }
@@ -2720,14 +2829,14 @@ int nand_scan_tail(struct mtd_info *mtd)
2720 return chip->scan_bbt(mtd); 2829 return chip->scan_bbt(mtd);
2721} 2830}
2722 2831
2723/* module_text_address() isn't exported, and it's mostly a pointless 2832/* is_module_text_address() isn't exported, and it's mostly a pointless
2724 test if this is a module _anyway_ -- they'd have to try _really_ hard 2833 test if this is a module _anyway_ -- they'd have to try _really_ hard
2725 to call us from in-kernel code if the core NAND support is modular. */ 2834 to call us from in-kernel code if the core NAND support is modular. */
2726#ifdef MODULE 2835#ifdef MODULE
2727#define caller_is_module() (1) 2836#define caller_is_module() (1)
2728#else 2837#else
2729#define caller_is_module() \ 2838#define caller_is_module() \
2730 module_text_address((unsigned long)__builtin_return_address(0)) 2839 is_module_text_address((unsigned long)__builtin_return_address(0))
2731#endif 2840#endif
2732 2841
2733/** 2842/**
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index 582cf80f555a..89bf85af642c 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -187,7 +187,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
187 return -ENODEV; 187 return -ENODEV;
188 188
189 ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s", 189 ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s",
190 ndfc->ofdev->dev.bus_id, flash_np->name); 190 dev_name(&ndfc->ofdev->dev), flash_np->name);
191 if (!ndfc->mtd.name) { 191 if (!ndfc->mtd.name) {
192 ret = -ENOMEM; 192 ret = -ENOMEM;
193 goto err; 193 goto err;
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c
index 917cf8d3ae95..c2dfd3ea353d 100644
--- a/drivers/mtd/nand/orion_nand.c
+++ b/drivers/mtd/nand/orion_nand.c
@@ -149,7 +149,7 @@ static int __devexit orion_nand_remove(struct platform_device *pdev)
149 149
150static struct platform_driver orion_nand_driver = { 150static struct platform_driver orion_nand_driver = {
151 .probe = orion_nand_probe, 151 .probe = orion_nand_probe,
152 .remove = orion_nand_remove, 152 .remove = __devexit_p(orion_nand_remove),
153 .driver = { 153 .driver = {
154 .name = "orion_nand", 154 .name = "orion_nand",
155 .owner = THIS_MODULE, 155 .owner = THIS_MODULE,
diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c
index 75f9f4874ecf..86e1d08eee00 100644
--- a/drivers/mtd/nand/plat_nand.c
+++ b/drivers/mtd/nand/plat_nand.c
@@ -30,7 +30,7 @@ struct plat_nand_data {
30/* 30/*
31 * Probe for the NAND device. 31 * Probe for the NAND device.
32 */ 32 */
33static int __init plat_nand_probe(struct platform_device *pdev) 33static int __devinit plat_nand_probe(struct platform_device *pdev)
34{ 34{
35 struct platform_nand_data *pdata = pdev->dev.platform_data; 35 struct platform_nand_data *pdata = pdev->dev.platform_data;
36 struct plat_nand_data *data; 36 struct plat_nand_data *data;
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index cc55cbc2b308..30a8ce6d3e69 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -22,7 +22,6 @@
22#include <linux/irq.h> 22#include <linux/irq.h>
23 23
24#include <mach/dma.h> 24#include <mach/dma.h>
25#include <mach/pxa-regs.h>
26#include <mach/pxa3xx_nand.h> 25#include <mach/pxa3xx_nand.h>
27 26
28#define CHIP_DELAY_TIMEOUT (2 * HZ/10) 27#define CHIP_DELAY_TIMEOUT (2 * HZ/10)
@@ -171,7 +170,13 @@ static int use_dma = 1;
171module_param(use_dma, bool, 0444); 170module_param(use_dma, bool, 0444);
172MODULE_PARM_DESC(use_dma, "enable DMA for data transfering to/from NAND HW"); 171MODULE_PARM_DESC(use_dma, "enable DMA for data transfering to/from NAND HW");
173 172
174#ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN 173/*
174 * Default NAND flash controller configuration setup by the
175 * bootloader. This configuration is used only when pdata->keep_config is set
176 */
177static struct pxa3xx_nand_timing default_timing;
178static struct pxa3xx_nand_flash default_flash;
179
175static struct pxa3xx_nand_cmdset smallpage_cmdset = { 180static struct pxa3xx_nand_cmdset smallpage_cmdset = {
176 .read1 = 0x0000, 181 .read1 = 0x0000,
177 .read2 = 0x0050, 182 .read2 = 0x0050,
@@ -198,6 +203,7 @@ static struct pxa3xx_nand_cmdset largepage_cmdset = {
198 .lock_status = 0x007A, 203 .lock_status = 0x007A,
199}; 204};
200 205
206#ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN
201static struct pxa3xx_nand_timing samsung512MbX16_timing = { 207static struct pxa3xx_nand_timing samsung512MbX16_timing = {
202 .tCH = 10, 208 .tCH = 10,
203 .tCS = 0, 209 .tCS = 0,
@@ -297,9 +303,23 @@ static struct pxa3xx_nand_flash *builtin_flash_types[] = {
297#define NDTR1_tWHR(c) (min((c), 15) << 4) 303#define NDTR1_tWHR(c) (min((c), 15) << 4)
298#define NDTR1_tAR(c) (min((c), 15) << 0) 304#define NDTR1_tAR(c) (min((c), 15) << 0)
299 305
306#define tCH_NDTR0(r) (((r) >> 19) & 0x7)
307#define tCS_NDTR0(r) (((r) >> 16) & 0x7)
308#define tWH_NDTR0(r) (((r) >> 11) & 0x7)
309#define tWP_NDTR0(r) (((r) >> 8) & 0x7)
310#define tRH_NDTR0(r) (((r) >> 3) & 0x7)
311#define tRP_NDTR0(r) (((r) >> 0) & 0x7)
312
313#define tR_NDTR1(r) (((r) >> 16) & 0xffff)
314#define tWHR_NDTR1(r) (((r) >> 4) & 0xf)
315#define tAR_NDTR1(r) (((r) >> 0) & 0xf)
316
300/* convert nano-seconds to nand flash controller clock cycles */ 317/* convert nano-seconds to nand flash controller clock cycles */
301#define ns2cycle(ns, clk) (int)(((ns) * (clk / 1000000) / 1000) - 1) 318#define ns2cycle(ns, clk) (int)(((ns) * (clk / 1000000) / 1000) - 1)
302 319
320/* convert nand flash controller clock cycles to nano-seconds */
321#define cycle2ns(c, clk) ((((c) + 1) * 1000000 + clk / 500) / (clk / 1000))
322
303static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info, 323static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info,
304 const struct pxa3xx_nand_timing *t) 324 const struct pxa3xx_nand_timing *t)
305{ 325{
@@ -921,6 +941,82 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
921 return 0; 941 return 0;
922} 942}
923 943
944static void pxa3xx_nand_detect_timing(struct pxa3xx_nand_info *info,
945 struct pxa3xx_nand_timing *t)
946{
947 unsigned long nand_clk = clk_get_rate(info->clk);
948 uint32_t ndtr0 = nand_readl(info, NDTR0CS0);
949 uint32_t ndtr1 = nand_readl(info, NDTR1CS0);
950
951 t->tCH = cycle2ns(tCH_NDTR0(ndtr0), nand_clk);
952 t->tCS = cycle2ns(tCS_NDTR0(ndtr0), nand_clk);
953 t->tWH = cycle2ns(tWH_NDTR0(ndtr0), nand_clk);
954 t->tWP = cycle2ns(tWP_NDTR0(ndtr0), nand_clk);
955 t->tRH = cycle2ns(tRH_NDTR0(ndtr0), nand_clk);
956 t->tRP = cycle2ns(tRP_NDTR0(ndtr0), nand_clk);
957
958 t->tR = cycle2ns(tR_NDTR1(ndtr1), nand_clk);
959 t->tWHR = cycle2ns(tWHR_NDTR1(ndtr1), nand_clk);
960 t->tAR = cycle2ns(tAR_NDTR1(ndtr1), nand_clk);
961}
962
963static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
964{
965 uint32_t ndcr = nand_readl(info, NDCR);
966 struct nand_flash_dev *type = NULL;
967 uint32_t id = -1;
968 int i;
969
970 default_flash.page_per_block = ndcr & NDCR_PG_PER_BLK ? 64 : 32;
971 default_flash.page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512;
972 default_flash.flash_width = ndcr & NDCR_DWIDTH_M ? 16 : 8;
973 default_flash.dfc_width = ndcr & NDCR_DWIDTH_C ? 16 : 8;
974
975 if (default_flash.page_size == 2048)
976 default_flash.cmdset = &largepage_cmdset;
977 else
978 default_flash.cmdset = &smallpage_cmdset;
979
980 /* set info fields needed to __readid */
981 info->flash_info = &default_flash;
982 info->read_id_bytes = (default_flash.page_size == 2048) ? 4 : 2;
983 info->reg_ndcr = ndcr;
984
985 if (__readid(info, &id))
986 return -ENODEV;
987
988 /* Lookup the flash id */
989 id = (id >> 8) & 0xff; /* device id is byte 2 */
990 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
991 if (id == nand_flash_ids[i].id) {
992 type = &nand_flash_ids[i];
993 break;
994 }
995 }
996
997 if (!type)
998 return -ENODEV;
999
1000 /* fill the missing flash information */
1001 i = __ffs(default_flash.page_per_block * default_flash.page_size);
1002 default_flash.num_blocks = type->chipsize << (20 - i);
1003
1004 info->oob_size = (default_flash.page_size == 2048) ? 64 : 16;
1005
1006 /* calculate addressing information */
1007 info->col_addr_cycles = (default_flash.page_size == 2048) ? 2 : 1;
1008
1009 if (default_flash.num_blocks * default_flash.page_per_block > 65536)
1010 info->row_addr_cycles = 3;
1011 else
1012 info->row_addr_cycles = 2;
1013
1014 pxa3xx_nand_detect_timing(info, &default_timing);
1015 default_flash.timing = &default_timing;
1016
1017 return 0;
1018}
1019
924static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info, 1020static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info,
925 const struct pxa3xx_nand_platform_data *pdata) 1021 const struct pxa3xx_nand_platform_data *pdata)
926{ 1022{
@@ -928,6 +1024,10 @@ static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info,
928 uint32_t id = -1; 1024 uint32_t id = -1;
929 int i; 1025 int i;
930 1026
1027 if (pdata->keep_config)
1028 if (pxa3xx_nand_detect_config(info) == 0)
1029 return 0;
1030
931 for (i = 0; i<pdata->num_flash; ++i) { 1031 for (i = 0; i<pdata->num_flash; ++i) {
932 f = pdata->flash + i; 1032 f = pdata->flash + i;
933 1033
@@ -1079,6 +1179,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
1079 1179
1080 this = &info->nand_chip; 1180 this = &info->nand_chip;
1081 mtd->priv = info; 1181 mtd->priv = info;
1182 mtd->owner = THIS_MODULE;
1082 1183
1083 info->clk = clk_get(&pdev->dev, NULL); 1184 info->clk = clk_get(&pdev->dev, NULL);
1084 if (IS_ERR(info->clk)) { 1185 if (IS_ERR(info->clk)) {
@@ -1118,14 +1219,14 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
1118 goto fail_put_clk; 1219 goto fail_put_clk;
1119 } 1220 }
1120 1221
1121 r = request_mem_region(r->start, r->end - r->start + 1, pdev->name); 1222 r = request_mem_region(r->start, resource_size(r), pdev->name);
1122 if (r == NULL) { 1223 if (r == NULL) {
1123 dev_err(&pdev->dev, "failed to request memory resource\n"); 1224 dev_err(&pdev->dev, "failed to request memory resource\n");
1124 ret = -EBUSY; 1225 ret = -EBUSY;
1125 goto fail_put_clk; 1226 goto fail_put_clk;
1126 } 1227 }
1127 1228
1128 info->mmio_base = ioremap(r->start, r->end - r->start + 1); 1229 info->mmio_base = ioremap(r->start, resource_size(r));
1129 if (info->mmio_base == NULL) { 1230 if (info->mmio_base == NULL) {
1130 dev_err(&pdev->dev, "ioremap() failed\n"); 1231 dev_err(&pdev->dev, "ioremap() failed\n");
1131 ret = -ENODEV; 1232 ret = -ENODEV;
@@ -1174,7 +1275,7 @@ fail_free_buf:
1174fail_free_io: 1275fail_free_io:
1175 iounmap(info->mmio_base); 1276 iounmap(info->mmio_base);
1176fail_free_res: 1277fail_free_res:
1177 release_mem_region(r->start, r->end - r->start + 1); 1278 release_mem_region(r->start, resource_size(r));
1178fail_put_clk: 1279fail_put_clk:
1179 clk_disable(info->clk); 1280 clk_disable(info->clk);
1180 clk_put(info->clk); 1281 clk_put(info->clk);
@@ -1187,6 +1288,7 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
1187{ 1288{
1188 struct mtd_info *mtd = platform_get_drvdata(pdev); 1289 struct mtd_info *mtd = platform_get_drvdata(pdev);
1189 struct pxa3xx_nand_info *info = mtd->priv; 1290 struct pxa3xx_nand_info *info = mtd->priv;
1291 struct resource *r;
1190 1292
1191 platform_set_drvdata(pdev, NULL); 1293 platform_set_drvdata(pdev, NULL);
1192 1294
@@ -1199,6 +1301,14 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
1199 info->data_buff, info->data_buff_phys); 1301 info->data_buff, info->data_buff_phys);
1200 } else 1302 } else
1201 kfree(info->data_buff); 1303 kfree(info->data_buff);
1304
1305 iounmap(info->mmio_base);
1306 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1307 release_mem_region(r->start, resource_size(r));
1308
1309 clk_disable(info->clk);
1310 clk_put(info->clk);
1311
1202 kfree(mtd); 1312 kfree(mtd);
1203 return 0; 1313 return 0;
1204} 1314}
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 821acb08ff1c..2bc896623e2d 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -58,7 +58,7 @@ static struct nand_bbt_descr flctl_4secc_smallpage = {
58}; 58};
59 59
60static struct nand_bbt_descr flctl_4secc_largepage = { 60static struct nand_bbt_descr flctl_4secc_largepage = {
61 .options = 0, 61 .options = NAND_BBT_SCAN2NDPAGE,
62 .offs = 58, 62 .offs = 58,
63 .len = 2, 63 .len = 2,
64 .pattern = scan_ff_pattern, 64 .pattern = scan_ff_pattern,
@@ -149,7 +149,7 @@ static void wait_wfifo_ready(struct sh_flctl *flctl)
149 printk(KERN_ERR "wait_wfifo_ready(): Timeout occured \n"); 149 printk(KERN_ERR "wait_wfifo_ready(): Timeout occured \n");
150} 150}
151 151
152static int wait_recfifo_ready(struct sh_flctl *flctl) 152static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
153{ 153{
154 uint32_t timeout = LOOP_TIMEOUT_MAX; 154 uint32_t timeout = LOOP_TIMEOUT_MAX;
155 int checked[4]; 155 int checked[4];
@@ -183,7 +183,12 @@ static int wait_recfifo_ready(struct sh_flctl *flctl)
183 uint8_t org; 183 uint8_t org;
184 int index; 184 int index;
185 185
186 index = data >> 16; 186 if (flctl->page_size)
187 index = (512 * sector_number) +
188 (data >> 16);
189 else
190 index = data >> 16;
191
187 org = flctl->done_buff[index]; 192 org = flctl->done_buff[index];
188 flctl->done_buff[index] = org ^ (data & 0xFF); 193 flctl->done_buff[index] = org ^ (data & 0xFF);
189 checked[i] = 1; 194 checked[i] = 1;
@@ -238,14 +243,14 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
238 } 243 }
239} 244}
240 245
241static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff) 246static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff, int sector)
242{ 247{
243 int i; 248 int i;
244 unsigned long *ecc_buf = (unsigned long *)buff; 249 unsigned long *ecc_buf = (unsigned long *)buff;
245 void *fifo_addr = (void *)FLECFIFO(flctl); 250 void *fifo_addr = (void *)FLECFIFO(flctl);
246 251
247 for (i = 0; i < 4; i++) { 252 for (i = 0; i < 4; i++) {
248 if (wait_recfifo_ready(flctl)) 253 if (wait_recfifo_ready(flctl , sector))
249 return 1; 254 return 1;
250 ecc_buf[i] = readl(fifo_addr); 255 ecc_buf[i] = readl(fifo_addr);
251 ecc_buf[i] = be32_to_cpu(ecc_buf[i]); 256 ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
@@ -384,7 +389,8 @@ static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
384 read_fiforeg(flctl, 512, 512 * sector); 389 read_fiforeg(flctl, 512, 512 * sector);
385 390
386 ret = read_ecfiforeg(flctl, 391 ret = read_ecfiforeg(flctl,
387 &flctl->done_buff[mtd->writesize + 16 * sector]); 392 &flctl->done_buff[mtd->writesize + 16 * sector],
393 sector);
388 394
389 if (ret) 395 if (ret)
390 flctl->hwecc_cant_correct[sector] = 1; 396 flctl->hwecc_cant_correct[sector] = 1;
diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c
new file mode 100644
index 000000000000..a4519a7bd683
--- /dev/null
+++ b/drivers/mtd/nand/socrates_nand.c
@@ -0,0 +1,325 @@
1/*
2 * drivers/mtd/nand/socrates_nand.c
3 *
4 * Copyright © 2008 Ilya Yanok, Emcraft Systems
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12
13#include <linux/slab.h>
14#include <linux/module.h>
15#include <linux/mtd/mtd.h>
16#include <linux/mtd/nand.h>
17#include <linux/mtd/partitions.h>
18#include <linux/of_platform.h>
19#include <linux/io.h>
20
21#define FPGA_NAND_CMD_MASK (0x7 << 28)
22#define FPGA_NAND_CMD_COMMAND (0x0 << 28)
23#define FPGA_NAND_CMD_ADDR (0x1 << 28)
24#define FPGA_NAND_CMD_READ (0x2 << 28)
25#define FPGA_NAND_CMD_WRITE (0x3 << 28)
26#define FPGA_NAND_BUSY (0x1 << 15)
27#define FPGA_NAND_ENABLE (0x1 << 31)
28#define FPGA_NAND_DATA_SHIFT 16
29
30struct socrates_nand_host {
31 struct nand_chip nand_chip;
32 struct mtd_info mtd;
33 void __iomem *io_base;
34 struct device *dev;
35};
36
37/**
38 * socrates_nand_write_buf - write buffer to chip
39 * @mtd: MTD device structure
40 * @buf: data buffer
41 * @len: number of bytes to write
42 */
43static void socrates_nand_write_buf(struct mtd_info *mtd,
44 const uint8_t *buf, int len)
45{
46 int i;
47 struct nand_chip *this = mtd->priv;
48 struct socrates_nand_host *host = this->priv;
49
50 for (i = 0; i < len; i++) {
51 out_be32(host->io_base, FPGA_NAND_ENABLE |
52 FPGA_NAND_CMD_WRITE |
53 (buf[i] << FPGA_NAND_DATA_SHIFT));
54 }
55}
56
57/**
58 * socrates_nand_read_buf - read chip data into buffer
59 * @mtd: MTD device structure
60 * @buf: buffer to store date
61 * @len: number of bytes to read
62 */
63static void socrates_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
64{
65 int i;
66 struct nand_chip *this = mtd->priv;
67 struct socrates_nand_host *host = this->priv;
68 uint32_t val;
69
70 val = FPGA_NAND_ENABLE | FPGA_NAND_CMD_READ;
71
72 out_be32(host->io_base, val);
73 for (i = 0; i < len; i++) {
74 buf[i] = (in_be32(host->io_base) >>
75 FPGA_NAND_DATA_SHIFT) & 0xff;
76 }
77}
78
79/**
80 * socrates_nand_read_byte - read one byte from the chip
81 * @mtd: MTD device structure
82 */
83static uint8_t socrates_nand_read_byte(struct mtd_info *mtd)
84{
85 uint8_t byte;
86 socrates_nand_read_buf(mtd, &byte, sizeof(byte));
87 return byte;
88}
89
90/**
91 * socrates_nand_read_word - read one word from the chip
92 * @mtd: MTD device structure
93 */
94static uint16_t socrates_nand_read_word(struct mtd_info *mtd)
95{
96 uint16_t word;
97 socrates_nand_read_buf(mtd, (uint8_t *)&word, sizeof(word));
98 return word;
99}
100
101/**
102 * socrates_nand_verify_buf - Verify chip data against buffer
103 * @mtd: MTD device structure
104 * @buf: buffer containing the data to compare
105 * @len: number of bytes to compare
106 */
107static int socrates_nand_verify_buf(struct mtd_info *mtd, const u8 *buf,
108 int len)
109{
110 int i;
111
112 for (i = 0; i < len; i++) {
113 if (buf[i] != socrates_nand_read_byte(mtd))
114 return -EFAULT;
115 }
116 return 0;
117}
118
119/*
120 * Hardware specific access to control-lines
121 */
122static void socrates_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
123 unsigned int ctrl)
124{
125 struct nand_chip *nand_chip = mtd->priv;
126 struct socrates_nand_host *host = nand_chip->priv;
127 uint32_t val;
128
129 if (cmd == NAND_CMD_NONE)
130 return;
131
132 if (ctrl & NAND_CLE)
133 val = FPGA_NAND_CMD_COMMAND;
134 else
135 val = FPGA_NAND_CMD_ADDR;
136
137 if (ctrl & NAND_NCE)
138 val |= FPGA_NAND_ENABLE;
139
140 val |= (cmd & 0xff) << FPGA_NAND_DATA_SHIFT;
141
142 out_be32(host->io_base, val);
143}
144
145/*
146 * Read the Device Ready pin.
147 */
148static int socrates_nand_device_ready(struct mtd_info *mtd)
149{
150 struct nand_chip *nand_chip = mtd->priv;
151 struct socrates_nand_host *host = nand_chip->priv;
152
153 if (in_be32(host->io_base) & FPGA_NAND_BUSY)
154 return 0; /* busy */
155 return 1;
156}
157
158#ifdef CONFIG_MTD_PARTITIONS
159static const char *part_probes[] = { "cmdlinepart", NULL };
160#endif
161
162/*
163 * Probe for the NAND device.
164 */
165static int __devinit socrates_nand_probe(struct of_device *ofdev,
166 const struct of_device_id *ofid)
167{
168 struct socrates_nand_host *host;
169 struct mtd_info *mtd;
170 struct nand_chip *nand_chip;
171 int res;
172
173#ifdef CONFIG_MTD_PARTITIONS
174 struct mtd_partition *partitions = NULL;
175 int num_partitions = 0;
176#endif
177
178 /* Allocate memory for the device structure (and zero it) */
179 host = kzalloc(sizeof(struct socrates_nand_host), GFP_KERNEL);
180 if (!host) {
181 printk(KERN_ERR
182 "socrates_nand: failed to allocate device structure.\n");
183 return -ENOMEM;
184 }
185
186 host->io_base = of_iomap(ofdev->node, 0);
187 if (host->io_base == NULL) {
188 printk(KERN_ERR "socrates_nand: ioremap failed\n");
189 kfree(host);
190 return -EIO;
191 }
192
193 mtd = &host->mtd;
194 nand_chip = &host->nand_chip;
195 host->dev = &ofdev->dev;
196
197 nand_chip->priv = host; /* link the private data structures */
198 mtd->priv = nand_chip;
199 mtd->name = "socrates_nand";
200 mtd->owner = THIS_MODULE;
201 mtd->dev.parent = &ofdev->dev;
202
203 /*should never be accessed directly */
204 nand_chip->IO_ADDR_R = (void *)0xdeadbeef;
205 nand_chip->IO_ADDR_W = (void *)0xdeadbeef;
206
207 nand_chip->cmd_ctrl = socrates_nand_cmd_ctrl;
208 nand_chip->read_byte = socrates_nand_read_byte;
209 nand_chip->read_word = socrates_nand_read_word;
210 nand_chip->write_buf = socrates_nand_write_buf;
211 nand_chip->read_buf = socrates_nand_read_buf;
212 nand_chip->verify_buf = socrates_nand_verify_buf;
213 nand_chip->dev_ready = socrates_nand_device_ready;
214
215 nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */
216
217 /* TODO: I have no idea what real delay is. */
218 nand_chip->chip_delay = 20; /* 20us command delay time */
219
220 dev_set_drvdata(&ofdev->dev, host);
221
222 /* first scan to find the device and get the page size */
223 if (nand_scan_ident(mtd, 1)) {
224 res = -ENXIO;
225 goto out;
226 }
227
228 /* second phase scan */
229 if (nand_scan_tail(mtd)) {
230 res = -ENXIO;
231 goto out;
232 }
233
234#ifdef CONFIG_MTD_PARTITIONS
235#ifdef CONFIG_MTD_CMDLINE_PARTS
236 num_partitions = parse_mtd_partitions(mtd, part_probes,
237 &partitions, 0);
238 if (num_partitions < 0) {
239 res = num_partitions;
240 goto release;
241 }
242#endif
243
244#ifdef CONFIG_MTD_OF_PARTS
245 if (num_partitions == 0) {
246 num_partitions = of_mtd_parse_partitions(&ofdev->dev,
247 ofdev->node,
248 &partitions);
249 if (num_partitions < 0) {
250 res = num_partitions;
251 goto release;
252 }
253 }
254#endif
255 if (partitions && (num_partitions > 0))
256 res = add_mtd_partitions(mtd, partitions, num_partitions);
257 else
258#endif
259 res = add_mtd_device(mtd);
260
261 if (!res)
262 return res;
263
264#ifdef CONFIG_MTD_PARTITIONS
265release:
266#endif
267 nand_release(mtd);
268
269out:
270 dev_set_drvdata(&ofdev->dev, NULL);
271 iounmap(host->io_base);
272 kfree(host);
273 return res;
274}
275
276/*
277 * Remove a NAND device.
278 */
279static int __devexit socrates_nand_remove(struct of_device *ofdev)
280{
281 struct socrates_nand_host *host = dev_get_drvdata(&ofdev->dev);
282 struct mtd_info *mtd = &host->mtd;
283
284 nand_release(mtd);
285
286 dev_set_drvdata(&ofdev->dev, NULL);
287 iounmap(host->io_base);
288 kfree(host);
289
290 return 0;
291}
292
293static struct of_device_id socrates_nand_match[] =
294{
295 {
296 .compatible = "abb,socrates-nand",
297 },
298 {},
299};
300
301MODULE_DEVICE_TABLE(of, socrates_nand_match);
302
303static struct of_platform_driver socrates_nand_driver = {
304 .name = "socrates_nand",
305 .match_table = socrates_nand_match,
306 .probe = socrates_nand_probe,
307 .remove = __devexit_p(socrates_nand_remove),
308};
309
310static int __init socrates_nand_init(void)
311{
312 return of_register_platform_driver(&socrates_nand_driver);
313}
314
315static void __exit socrates_nand_exit(void)
316{
317 of_unregister_platform_driver(&socrates_nand_driver);
318}
319
320module_init(socrates_nand_init);
321module_exit(socrates_nand_exit);
322
323MODULE_LICENSE("GPL");
324MODULE_AUTHOR("Ilya Yanok");
325MODULE_DESCRIPTION("NAND driver for Socrates board");
diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c
new file mode 100644
index 000000000000..812479264896
--- /dev/null
+++ b/drivers/mtd/nand/txx9ndfmc.c
@@ -0,0 +1,428 @@
1/*
2 * TXx9 NAND flash memory controller driver
3 * Based on RBTX49xx patch from CELF patch archive.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * (C) Copyright TOSHIBA CORPORATION 2004-2007
10 * All Rights Reserved.
11 */
12#include <linux/init.h>
13#include <linux/slab.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/delay.h>
17#include <linux/mtd/mtd.h>
18#include <linux/mtd/nand.h>
19#include <linux/mtd/nand_ecc.h>
20#include <linux/mtd/partitions.h>
21#include <linux/io.h>
22#include <asm/txx9/ndfmc.h>
23
24/* TXX9 NDFMC Registers */
25#define TXX9_NDFDTR 0x00
26#define TXX9_NDFMCR 0x04
27#define TXX9_NDFSR 0x08
28#define TXX9_NDFISR 0x0c
29#define TXX9_NDFIMR 0x10
30#define TXX9_NDFSPR 0x14
31#define TXX9_NDFRSTR 0x18 /* not TX4939 */
32
33/* NDFMCR : NDFMC Mode Control */
34#define TXX9_NDFMCR_WE 0x80
35#define TXX9_NDFMCR_ECC_ALL 0x60
36#define TXX9_NDFMCR_ECC_RESET 0x60
37#define TXX9_NDFMCR_ECC_READ 0x40
38#define TXX9_NDFMCR_ECC_ON 0x20
39#define TXX9_NDFMCR_ECC_OFF 0x00
40#define TXX9_NDFMCR_CE 0x10
41#define TXX9_NDFMCR_BSPRT 0x04 /* TX4925/TX4926 only */
42#define TXX9_NDFMCR_ALE 0x02
43#define TXX9_NDFMCR_CLE 0x01
44/* TX4939 only */
45#define TXX9_NDFMCR_X16 0x0400
46#define TXX9_NDFMCR_DMAREQ_MASK 0x0300
47#define TXX9_NDFMCR_DMAREQ_NODMA 0x0000
48#define TXX9_NDFMCR_DMAREQ_128 0x0100
49#define TXX9_NDFMCR_DMAREQ_256 0x0200
50#define TXX9_NDFMCR_DMAREQ_512 0x0300
51#define TXX9_NDFMCR_CS_MASK 0x0c
52#define TXX9_NDFMCR_CS(ch) ((ch) << 2)
53
54/* NDFMCR : NDFMC Status */
55#define TXX9_NDFSR_BUSY 0x80
56/* TX4939 only */
57#define TXX9_NDFSR_DMARUN 0x40
58
59/* NDFMCR : NDFMC Reset */
60#define TXX9_NDFRSTR_RST 0x01
61
62struct txx9ndfmc_priv {
63 struct platform_device *dev;
64 struct nand_chip chip;
65 struct mtd_info mtd;
66 int cs;
67 char mtdname[BUS_ID_SIZE + 2];
68};
69
70#define MAX_TXX9NDFMC_DEV 4
71struct txx9ndfmc_drvdata {
72 struct mtd_info *mtds[MAX_TXX9NDFMC_DEV];
73 void __iomem *base;
74 unsigned char hold; /* in gbusclock */
75 unsigned char spw; /* in gbusclock */
76 struct nand_hw_control hw_control;
77#ifdef CONFIG_MTD_PARTITIONS
78 struct mtd_partition *parts[MAX_TXX9NDFMC_DEV];
79#endif
80};
81
82static struct platform_device *mtd_to_platdev(struct mtd_info *mtd)
83{
84 struct nand_chip *chip = mtd->priv;
85 struct txx9ndfmc_priv *txx9_priv = chip->priv;
86 return txx9_priv->dev;
87}
88
89static void __iomem *ndregaddr(struct platform_device *dev, unsigned int reg)
90{
91 struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
92 struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
93
94 return drvdata->base + (reg << plat->shift);
95}
96
97static u32 txx9ndfmc_read(struct platform_device *dev, unsigned int reg)
98{
99 return __raw_readl(ndregaddr(dev, reg));
100}
101
102static void txx9ndfmc_write(struct platform_device *dev,
103 u32 val, unsigned int reg)
104{
105 __raw_writel(val, ndregaddr(dev, reg));
106}
107
108static uint8_t txx9ndfmc_read_byte(struct mtd_info *mtd)
109{
110 struct platform_device *dev = mtd_to_platdev(mtd);
111
112 return txx9ndfmc_read(dev, TXX9_NDFDTR);
113}
114
115static void txx9ndfmc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
116 int len)
117{
118 struct platform_device *dev = mtd_to_platdev(mtd);
119 void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
120 u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
121
122 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_WE, TXX9_NDFMCR);
123 while (len--)
124 __raw_writel(*buf++, ndfdtr);
125 txx9ndfmc_write(dev, mcr, TXX9_NDFMCR);
126}
127
128static void txx9ndfmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
129{
130 struct platform_device *dev = mtd_to_platdev(mtd);
131 void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
132
133 while (len--)
134 *buf++ = __raw_readl(ndfdtr);
135}
136
137static int txx9ndfmc_verify_buf(struct mtd_info *mtd, const uint8_t *buf,
138 int len)
139{
140 struct platform_device *dev = mtd_to_platdev(mtd);
141 void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
142
143 while (len--)
144 if (*buf++ != (uint8_t)__raw_readl(ndfdtr))
145 return -EFAULT;
146 return 0;
147}
148
149static void txx9ndfmc_cmd_ctrl(struct mtd_info *mtd, int cmd,
150 unsigned int ctrl)
151{
152 struct nand_chip *chip = mtd->priv;
153 struct txx9ndfmc_priv *txx9_priv = chip->priv;
154 struct platform_device *dev = txx9_priv->dev;
155 struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
156
157 if (ctrl & NAND_CTRL_CHANGE) {
158 u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
159
160 mcr &= ~(TXX9_NDFMCR_CLE | TXX9_NDFMCR_ALE | TXX9_NDFMCR_CE);
161 mcr |= ctrl & NAND_CLE ? TXX9_NDFMCR_CLE : 0;
162 mcr |= ctrl & NAND_ALE ? TXX9_NDFMCR_ALE : 0;
163 /* TXX9_NDFMCR_CE bit is 0:high 1:low */
164 mcr |= ctrl & NAND_NCE ? TXX9_NDFMCR_CE : 0;
165 if (txx9_priv->cs >= 0 && (ctrl & NAND_NCE)) {
166 mcr &= ~TXX9_NDFMCR_CS_MASK;
167 mcr |= TXX9_NDFMCR_CS(txx9_priv->cs);
168 }
169 txx9ndfmc_write(dev, mcr, TXX9_NDFMCR);
170 }
171 if (cmd != NAND_CMD_NONE)
172 txx9ndfmc_write(dev, cmd & 0xff, TXX9_NDFDTR);
173 if (plat->flags & NDFMC_PLAT_FLAG_DUMMYWRITE) {
174 /* dummy write to update external latch */
175 if ((ctrl & NAND_CTRL_CHANGE) && cmd == NAND_CMD_NONE)
176 txx9ndfmc_write(dev, 0, TXX9_NDFDTR);
177 }
178 mmiowb();
179}
180
181static int txx9ndfmc_dev_ready(struct mtd_info *mtd)
182{
183 struct platform_device *dev = mtd_to_platdev(mtd);
184
185 return !(txx9ndfmc_read(dev, TXX9_NDFSR) & TXX9_NDFSR_BUSY);
186}
187
188static int txx9ndfmc_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
189 uint8_t *ecc_code)
190{
191 struct platform_device *dev = mtd_to_platdev(mtd);
192 u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
193
194 mcr &= ~TXX9_NDFMCR_ECC_ALL;
195 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
196 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_READ, TXX9_NDFMCR);
197 ecc_code[1] = txx9ndfmc_read(dev, TXX9_NDFDTR);
198 ecc_code[0] = txx9ndfmc_read(dev, TXX9_NDFDTR);
199 ecc_code[2] = txx9ndfmc_read(dev, TXX9_NDFDTR);
200 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
201 return 0;
202}
203
204static void txx9ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
205{
206 struct platform_device *dev = mtd_to_platdev(mtd);
207 u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
208
209 mcr &= ~TXX9_NDFMCR_ECC_ALL;
210 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_RESET, TXX9_NDFMCR);
211 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
212 txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_ON, TXX9_NDFMCR);
213}
214
215static void txx9ndfmc_initialize(struct platform_device *dev)
216{
217 struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
218 struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
219 int tmout = 100;
220
221 if (plat->flags & NDFMC_PLAT_FLAG_NO_RSTR)
222 ; /* no NDFRSTR. Write to NDFSPR resets the NDFMC. */
223 else {
224 /* reset NDFMC */
225 txx9ndfmc_write(dev,
226 txx9ndfmc_read(dev, TXX9_NDFRSTR) |
227 TXX9_NDFRSTR_RST,
228 TXX9_NDFRSTR);
229 while (txx9ndfmc_read(dev, TXX9_NDFRSTR) & TXX9_NDFRSTR_RST) {
230 if (--tmout == 0) {
231 dev_err(&dev->dev, "reset failed.\n");
232 break;
233 }
234 udelay(1);
235 }
236 }
237 /* setup Hold Time, Strobe Pulse Width */
238 txx9ndfmc_write(dev, (drvdata->hold << 4) | drvdata->spw, TXX9_NDFSPR);
239 txx9ndfmc_write(dev,
240 (plat->flags & NDFMC_PLAT_FLAG_USE_BSPRT) ?
241 TXX9_NDFMCR_BSPRT : 0, TXX9_NDFMCR);
242}
243
244#define TXX9NDFMC_NS_TO_CYC(gbusclk, ns) \
245 DIV_ROUND_UP((ns) * DIV_ROUND_UP(gbusclk, 1000), 1000000)
246
247static int __init txx9ndfmc_probe(struct platform_device *dev)
248{
249 struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
250#ifdef CONFIG_MTD_PARTITIONS
251 static const char *probes[] = { "cmdlinepart", NULL };
252#endif
253 int hold, spw;
254 int i;
255 struct txx9ndfmc_drvdata *drvdata;
256 unsigned long gbusclk = plat->gbus_clock;
257 struct resource *res;
258
259 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
260 if (!res)
261 return -ENODEV;
262 drvdata = devm_kzalloc(&dev->dev, sizeof(*drvdata), GFP_KERNEL);
263 if (!drvdata)
264 return -ENOMEM;
265 if (!devm_request_mem_region(&dev->dev, res->start,
266 resource_size(res), dev_name(&dev->dev)))
267 return -EBUSY;
268 drvdata->base = devm_ioremap(&dev->dev, res->start,
269 resource_size(res));
270 if (!drvdata->base)
271 return -EBUSY;
272
273 hold = plat->hold ?: 20; /* tDH */
274 spw = plat->spw ?: 90; /* max(tREADID, tWP, tRP) */
275
276 hold = TXX9NDFMC_NS_TO_CYC(gbusclk, hold);
277 spw = TXX9NDFMC_NS_TO_CYC(gbusclk, spw);
278 if (plat->flags & NDFMC_PLAT_FLAG_HOLDADD)
279 hold -= 2; /* actual hold time : (HOLD + 2) BUSCLK */
280 spw -= 1; /* actual wait time : (SPW + 1) BUSCLK */
281 hold = clamp(hold, 1, 15);
282 drvdata->hold = hold;
283 spw = clamp(spw, 1, 15);
284 drvdata->spw = spw;
285 dev_info(&dev->dev, "CLK:%ldMHz HOLD:%d SPW:%d\n",
286 (gbusclk + 500000) / 1000000, hold, spw);
287
288 spin_lock_init(&drvdata->hw_control.lock);
289 init_waitqueue_head(&drvdata->hw_control.wq);
290
291 platform_set_drvdata(dev, drvdata);
292 txx9ndfmc_initialize(dev);
293
294 for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {
295 struct txx9ndfmc_priv *txx9_priv;
296 struct nand_chip *chip;
297 struct mtd_info *mtd;
298#ifdef CONFIG_MTD_PARTITIONS
299 int nr_parts;
300#endif
301
302 if (!(plat->ch_mask & (1 << i)))
303 continue;
304 txx9_priv = kzalloc(sizeof(struct txx9ndfmc_priv),
305 GFP_KERNEL);
306 if (!txx9_priv) {
307 dev_err(&dev->dev, "Unable to allocate "
308 "TXx9 NDFMC MTD device structure.\n");
309 continue;
310 }
311 chip = &txx9_priv->chip;
312 mtd = &txx9_priv->mtd;
313 mtd->owner = THIS_MODULE;
314
315 mtd->priv = chip;
316
317 chip->read_byte = txx9ndfmc_read_byte;
318 chip->read_buf = txx9ndfmc_read_buf;
319 chip->write_buf = txx9ndfmc_write_buf;
320 chip->verify_buf = txx9ndfmc_verify_buf;
321 chip->cmd_ctrl = txx9ndfmc_cmd_ctrl;
322 chip->dev_ready = txx9ndfmc_dev_ready;
323 chip->ecc.calculate = txx9ndfmc_calculate_ecc;
324 chip->ecc.correct = nand_correct_data;
325 chip->ecc.hwctl = txx9ndfmc_enable_hwecc;
326 chip->ecc.mode = NAND_ECC_HW;
327 chip->ecc.size = 256;
328 chip->ecc.bytes = 3;
329 chip->chip_delay = 100;
330 chip->controller = &drvdata->hw_control;
331
332 chip->priv = txx9_priv;
333 txx9_priv->dev = dev;
334
335 if (plat->ch_mask != 1) {
336 txx9_priv->cs = i;
337 sprintf(txx9_priv->mtdname, "%s.%u",
338 dev_name(&dev->dev), i);
339 } else {
340 txx9_priv->cs = -1;
341 strcpy(txx9_priv->mtdname, dev_name(&dev->dev));
342 }
343 if (plat->wide_mask & (1 << i))
344 chip->options |= NAND_BUSWIDTH_16;
345
346 if (nand_scan(mtd, 1)) {
347 kfree(txx9_priv);
348 continue;
349 }
350 mtd->name = txx9_priv->mtdname;
351
352#ifdef CONFIG_MTD_PARTITIONS
353 nr_parts = parse_mtd_partitions(mtd, probes,
354 &drvdata->parts[i], 0);
355 if (nr_parts > 0)
356 add_mtd_partitions(mtd, drvdata->parts[i], nr_parts);
357#endif
358 add_mtd_device(mtd);
359 drvdata->mtds[i] = mtd;
360 }
361
362 return 0;
363}
364
365static int __exit txx9ndfmc_remove(struct platform_device *dev)
366{
367 struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
368 int i;
369
370 platform_set_drvdata(dev, NULL);
371 if (!drvdata)
372 return 0;
373 for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {
374 struct mtd_info *mtd = drvdata->mtds[i];
375 struct nand_chip *chip;
376 struct txx9ndfmc_priv *txx9_priv;
377
378 if (!mtd)
379 continue;
380 chip = mtd->priv;
381 txx9_priv = chip->priv;
382
383#ifdef CONFIG_MTD_PARTITIONS
384 del_mtd_partitions(mtd);
385 kfree(drvdata->parts[i]);
386#endif
387 del_mtd_device(mtd);
388 kfree(txx9_priv);
389 }
390 return 0;
391}
392
393#ifdef CONFIG_PM
394static int txx9ndfmc_resume(struct platform_device *dev)
395{
396 if (platform_get_drvdata(dev))
397 txx9ndfmc_initialize(dev);
398 return 0;
399}
400#else
401#define txx9ndfmc_resume NULL
402#endif
403
404static struct platform_driver txx9ndfmc_driver = {
405 .remove = __exit_p(txx9ndfmc_remove),
406 .resume = txx9ndfmc_resume,
407 .driver = {
408 .name = "txx9ndfmc",
409 .owner = THIS_MODULE,
410 },
411};
412
413static int __init txx9ndfmc_init(void)
414{
415 return platform_driver_probe(&txx9ndfmc_driver, txx9ndfmc_probe);
416}
417
418static void __exit txx9ndfmc_exit(void)
419{
420 platform_driver_unregister(&txx9ndfmc_driver);
421}
422
423module_init(txx9ndfmc_init);
424module_exit(txx9ndfmc_exit);
425
426MODULE_LICENSE("GPL");
427MODULE_DESCRIPTION("TXx9 SoC NAND flash controller driver");
428MODULE_ALIAS("platform:txx9ndfmc");
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index d1c4546513f7..e3f8495a94c2 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -15,11 +15,11 @@
15#include <asm/errno.h> 15#include <asm/errno.h>
16#include <asm/io.h> 16#include <asm/io.h>
17#include <asm/uaccess.h> 17#include <asm/uaccess.h>
18#include <linux/miscdevice.h>
19#include <linux/delay.h> 18#include <linux/delay.h>
20#include <linux/slab.h> 19#include <linux/slab.h>
21#include <linux/init.h> 20#include <linux/init.h>
22#include <linux/hdreg.h> 21#include <linux/hdreg.h>
22#include <linux/blkdev.h>
23 23
24#include <linux/kmod.h> 24#include <linux/kmod.h>
25#include <linux/mtd/mtd.h> 25#include <linux/mtd/mtd.h>
@@ -818,3 +818,4 @@ module_exit(cleanup_nftl);
818MODULE_LICENSE("GPL"); 818MODULE_LICENSE("GPL");
819MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>, Fabrice Bellard <fabrice.bellard@netgem.com> et al."); 819MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>, Fabrice Bellard <fabrice.bellard@netgem.com> et al.");
820MODULE_DESCRIPTION("Support code for NAND Flash Translation Layer, used on M-Systems DiskOnChip 2000 and Millennium"); 820MODULE_DESCRIPTION("Support code for NAND Flash Translation Layer, used on M-Systems DiskOnChip 2000 and Millennium");
821MODULE_ALIAS_BLOCKDEV_MAJOR(NFTL_MAJOR);
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
index 9e45b3f39c0e..3e164f0c9295 100644
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -46,6 +46,13 @@ int __devinit of_mtd_parse_partitions(struct device *dev,
46 const u32 *reg; 46 const u32 *reg;
47 int len; 47 int len;
48 48
49 /* check if this is a partition node */
50 partname = of_get_property(pp, "name", &len);
51 if (strcmp(partname, "partition") != 0) {
52 nr_parts--;
53 continue;
54 }
55
49 reg = of_get_property(pp, "reg", &len); 56 reg = of_get_property(pp, "reg", &len);
50 if (!reg || (len != 2 * sizeof(u32))) { 57 if (!reg || (len != 2 * sizeof(u32))) {
51 of_node_put(pp); 58 of_node_put(pp);
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
index 5b69e7773c6c..3a496c33fb52 100644
--- a/drivers/mtd/onenand/generic.c
+++ b/drivers/mtd/onenand/generic.c
@@ -36,10 +36,9 @@ struct onenand_info {
36 struct onenand_chip onenand; 36 struct onenand_chip onenand;
37}; 37};
38 38
39static int __devinit generic_onenand_probe(struct device *dev) 39static int __devinit generic_onenand_probe(struct platform_device *pdev)
40{ 40{
41 struct onenand_info *info; 41 struct onenand_info *info;
42 struct platform_device *pdev = to_platform_device(dev);
43 struct flash_platform_data *pdata = pdev->dev.platform_data; 42 struct flash_platform_data *pdata = pdev->dev.platform_data;
44 struct resource *res = pdev->resource; 43 struct resource *res = pdev->resource;
45 unsigned long size = res->end - res->start + 1; 44 unsigned long size = res->end - res->start + 1;
@@ -49,7 +48,7 @@ static int __devinit generic_onenand_probe(struct device *dev)
49 if (!info) 48 if (!info)
50 return -ENOMEM; 49 return -ENOMEM;
51 50
52 if (!request_mem_region(res->start, size, dev->driver->name)) { 51 if (!request_mem_region(res->start, size, pdev->dev.driver->name)) {
53 err = -EBUSY; 52 err = -EBUSY;
54 goto out_free_info; 53 goto out_free_info;
55 } 54 }
@@ -82,7 +81,7 @@ static int __devinit generic_onenand_probe(struct device *dev)
82#endif 81#endif
83 err = add_mtd_device(&info->mtd); 82 err = add_mtd_device(&info->mtd);
84 83
85 dev_set_drvdata(&pdev->dev, info); 84 platform_set_drvdata(pdev, info);
86 85
87 return 0; 86 return 0;
88 87
@@ -96,14 +95,13 @@ out_free_info:
96 return err; 95 return err;
97} 96}
98 97
99static int __devexit generic_onenand_remove(struct device *dev) 98static int __devexit generic_onenand_remove(struct platform_device *pdev)
100{ 99{
101 struct platform_device *pdev = to_platform_device(dev); 100 struct onenand_info *info = platform_get_drvdata(pdev);
102 struct onenand_info *info = dev_get_drvdata(&pdev->dev);
103 struct resource *res = pdev->resource; 101 struct resource *res = pdev->resource;
104 unsigned long size = res->end - res->start + 1; 102 unsigned long size = res->end - res->start + 1;
105 103
106 dev_set_drvdata(&pdev->dev, NULL); 104 platform_set_drvdata(pdev, NULL);
107 105
108 if (info) { 106 if (info) {
109 if (info->parts) 107 if (info->parts)
@@ -120,9 +118,11 @@ static int __devexit generic_onenand_remove(struct device *dev)
120 return 0; 118 return 0;
121} 119}
122 120
123static struct device_driver generic_onenand_driver = { 121static struct platform_driver generic_onenand_driver = {
124 .name = DRIVER_NAME, 122 .driver = {
125 .bus = &platform_bus_type, 123 .name = DRIVER_NAME,
124 .owner = THIS_MODULE,
125 },
126 .probe = generic_onenand_probe, 126 .probe = generic_onenand_probe,
127 .remove = __devexit_p(generic_onenand_remove), 127 .remove = __devexit_p(generic_onenand_remove),
128}; 128};
@@ -131,12 +131,12 @@ MODULE_ALIAS(DRIVER_NAME);
131 131
132static int __init generic_onenand_init(void) 132static int __init generic_onenand_init(void)
133{ 133{
134 return driver_register(&generic_onenand_driver); 134 return platform_driver_register(&generic_onenand_driver);
135} 135}
136 136
137static void __exit generic_onenand_exit(void) 137static void __exit generic_onenand_exit(void)
138{ 138{
139 driver_unregister(&generic_onenand_driver); 139 platform_driver_unregister(&generic_onenand_driver);
140} 140}
141 141
142module_init(generic_onenand_init); 142module_init(generic_onenand_init);
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 77a4f1446156..f2e9de1414df 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -294,6 +294,10 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
294 if (bram_offset & 3 || (size_t)buf & 3 || count < 384) 294 if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
295 goto out_copy; 295 goto out_copy;
296 296
297 /* panic_write() may be in an interrupt context */
298 if (in_interrupt())
299 goto out_copy;
300
297 if (buf >= high_memory) { 301 if (buf >= high_memory) {
298 struct page *p1; 302 struct page *p1;
299 303
@@ -672,6 +676,8 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
672 c->mtd.priv = &c->onenand; 676 c->mtd.priv = &c->onenand;
673 c->mtd.owner = THIS_MODULE; 677 c->mtd.owner = THIS_MODULE;
674 678
679 c->mtd.dev.parent = &pdev->dev;
680
675 if (c->dma_channel >= 0) { 681 if (c->dma_channel >= 0) {
676 struct onenand_chip *this = &c->onenand; 682 struct onenand_chip *this = &c->onenand;
677 683
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 529af271db17..30d6999e5f9f 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1455,7 +1455,8 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
1455 struct mtd_oob_ops *ops) 1455 struct mtd_oob_ops *ops)
1456{ 1456{
1457 struct onenand_chip *this = mtd->priv; 1457 struct onenand_chip *this = mtd->priv;
1458 int written = 0, column, thislen, subpage; 1458 int written = 0, column, thislen = 0, subpage = 0;
1459 int prev = 0, prevlen = 0, prev_subpage = 0, first = 1;
1459 int oobwritten = 0, oobcolumn, thisooblen, oobsize; 1460 int oobwritten = 0, oobcolumn, thisooblen, oobsize;
1460 size_t len = ops->len; 1461 size_t len = ops->len;
1461 size_t ooblen = ops->ooblen; 1462 size_t ooblen = ops->ooblen;
@@ -1482,6 +1483,10 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
1482 return -EINVAL; 1483 return -EINVAL;
1483 } 1484 }
1484 1485
1486 /* Check zero length */
1487 if (!len)
1488 return 0;
1489
1485 if (ops->mode == MTD_OOB_AUTO) 1490 if (ops->mode == MTD_OOB_AUTO)
1486 oobsize = this->ecclayout->oobavail; 1491 oobsize = this->ecclayout->oobavail;
1487 else 1492 else
@@ -1492,79 +1497,121 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
1492 column = to & (mtd->writesize - 1); 1497 column = to & (mtd->writesize - 1);
1493 1498
1494 /* Loop until all data write */ 1499 /* Loop until all data write */
1495 while (written < len) { 1500 while (1) {
1496 u_char *wbuf = (u_char *) buf; 1501 if (written < len) {
1502 u_char *wbuf = (u_char *) buf;
1497 1503
1498 thislen = min_t(int, mtd->writesize - column, len - written); 1504 thislen = min_t(int, mtd->writesize - column, len - written);
1499 thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten); 1505 thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten);
1500 1506
1501 cond_resched(); 1507 cond_resched();
1502 1508
1503 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen); 1509 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
1504 1510
1505 /* Partial page write */ 1511 /* Partial page write */
1506 subpage = thislen < mtd->writesize; 1512 subpage = thislen < mtd->writesize;
1507 if (subpage) { 1513 if (subpage) {
1508 memset(this->page_buf, 0xff, mtd->writesize); 1514 memset(this->page_buf, 0xff, mtd->writesize);
1509 memcpy(this->page_buf + column, buf, thislen); 1515 memcpy(this->page_buf + column, buf, thislen);
1510 wbuf = this->page_buf; 1516 wbuf = this->page_buf;
1511 } 1517 }
1512 1518
1513 this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize); 1519 this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
1514 1520
1515 if (oob) { 1521 if (oob) {
1516 oobbuf = this->oob_buf; 1522 oobbuf = this->oob_buf;
1517 1523
1518 /* We send data to spare ram with oobsize 1524 /* We send data to spare ram with oobsize
1519 * to prevent byte access */ 1525 * to prevent byte access */
1520 memset(oobbuf, 0xff, mtd->oobsize); 1526 memset(oobbuf, 0xff, mtd->oobsize);
1521 if (ops->mode == MTD_OOB_AUTO) 1527 if (ops->mode == MTD_OOB_AUTO)
1522 onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen); 1528 onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
1523 else 1529 else
1524 memcpy(oobbuf + oobcolumn, oob, thisooblen); 1530 memcpy(oobbuf + oobcolumn, oob, thisooblen);
1525 1531
1526 oobwritten += thisooblen; 1532 oobwritten += thisooblen;
1527 oob += thisooblen; 1533 oob += thisooblen;
1528 oobcolumn = 0; 1534 oobcolumn = 0;
1535 } else
1536 oobbuf = (u_char *) ffchars;
1537
1538 this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
1529 } else 1539 } else
1530 oobbuf = (u_char *) ffchars; 1540 ONENAND_SET_NEXT_BUFFERRAM(this);
1531 1541
1532 this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize); 1542 /*
1543 * 2 PLANE, MLC, and Flex-OneNAND doesn't support
1544 * write-while-programe feature.
1545 */
1546 if (!ONENAND_IS_2PLANE(this) && !first) {
1547 ONENAND_SET_PREV_BUFFERRAM(this);
1533 1548
1534 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize); 1549 ret = this->wait(mtd, FL_WRITING);
1535 1550
1536 ret = this->wait(mtd, FL_WRITING); 1551 /* In partial page write we don't update bufferram */
1552 onenand_update_bufferram(mtd, prev, !ret && !prev_subpage);
1553 if (ret) {
1554 written -= prevlen;
1555 printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
1556 break;
1557 }
1537 1558
1538 /* In partial page write we don't update bufferram */ 1559 if (written == len) {
1539 onenand_update_bufferram(mtd, to, !ret && !subpage); 1560 /* Only check verify write turn on */
1540 if (ONENAND_IS_2PLANE(this)) { 1561 ret = onenand_verify(mtd, buf - len, to - len, len);
1541 ONENAND_SET_BUFFERRAM1(this); 1562 if (ret)
1542 onenand_update_bufferram(mtd, to + this->writesize, !ret && !subpage); 1563 printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
1543 } 1564 break;
1565 }
1544 1566
1545 if (ret) { 1567 ONENAND_SET_NEXT_BUFFERRAM(this);
1546 printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
1547 break;
1548 } 1568 }
1549 1569
1550 /* Only check verify write turn on */ 1570 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
1551 ret = onenand_verify(mtd, buf, to, thislen);
1552 if (ret) {
1553 printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
1554 break;
1555 }
1556 1571
1557 written += thislen; 1572 /*
1573 * 2 PLANE, MLC, and Flex-OneNAND wait here
1574 */
1575 if (ONENAND_IS_2PLANE(this)) {
1576 ret = this->wait(mtd, FL_WRITING);
1558 1577
1559 if (written == len) 1578 /* In partial page write we don't update bufferram */
1560 break; 1579 onenand_update_bufferram(mtd, to, !ret && !subpage);
1580 if (ret) {
1581 printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
1582 break;
1583 }
1584
1585 /* Only check verify write turn on */
1586 ret = onenand_verify(mtd, buf, to, thislen);
1587 if (ret) {
1588 printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
1589 break;
1590 }
1591
1592 written += thislen;
1593
1594 if (written == len)
1595 break;
1596
1597 } else
1598 written += thislen;
1561 1599
1562 column = 0; 1600 column = 0;
1601 prev_subpage = subpage;
1602 prev = to;
1603 prevlen = thislen;
1563 to += thislen; 1604 to += thislen;
1564 buf += thislen; 1605 buf += thislen;
1606 first = 0;
1565 } 1607 }
1566 1608
1609 /* In error case, clear all bufferrams */
1610 if (written != len)
1611 onenand_invalidate_bufferram(mtd, 0, -1);
1612
1567 ops->retlen = written; 1613 ops->retlen = written;
1614 ops->oobretlen = oobwritten;
1568 1615
1569 return ret; 1616 return ret;
1570} 1617}
diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c
index afbc3f8126db..a18e8d2f2557 100644
--- a/drivers/mtd/tests/mtd_oobtest.c
+++ b/drivers/mtd/tests/mtd_oobtest.c
@@ -136,7 +136,7 @@ static int write_eraseblock(int ebnum)
136 ops.ooblen = use_len; 136 ops.ooblen = use_len;
137 ops.oobretlen = 0; 137 ops.oobretlen = 0;
138 ops.ooboffs = use_offset; 138 ops.ooboffs = use_offset;
139 ops.datbuf = 0; 139 ops.datbuf = NULL;
140 ops.oobbuf = writebuf; 140 ops.oobbuf = writebuf;
141 err = mtd->write_oob(mtd, addr, &ops); 141 err = mtd->write_oob(mtd, addr, &ops);
142 if (err || ops.oobretlen != use_len) { 142 if (err || ops.oobretlen != use_len) {
@@ -189,7 +189,7 @@ static int verify_eraseblock(int ebnum)
189 ops.ooblen = use_len; 189 ops.ooblen = use_len;
190 ops.oobretlen = 0; 190 ops.oobretlen = 0;
191 ops.ooboffs = use_offset; 191 ops.ooboffs = use_offset;
192 ops.datbuf = 0; 192 ops.datbuf = NULL;
193 ops.oobbuf = readbuf; 193 ops.oobbuf = readbuf;
194 err = mtd->read_oob(mtd, addr, &ops); 194 err = mtd->read_oob(mtd, addr, &ops);
195 if (err || ops.oobretlen != use_len) { 195 if (err || ops.oobretlen != use_len) {
@@ -216,7 +216,7 @@ static int verify_eraseblock(int ebnum)
216 ops.ooblen = mtd->ecclayout->oobavail; 216 ops.ooblen = mtd->ecclayout->oobavail;
217 ops.oobretlen = 0; 217 ops.oobretlen = 0;
218 ops.ooboffs = 0; 218 ops.ooboffs = 0;
219 ops.datbuf = 0; 219 ops.datbuf = NULL;
220 ops.oobbuf = readbuf; 220 ops.oobbuf = readbuf;
221 err = mtd->read_oob(mtd, addr, &ops); 221 err = mtd->read_oob(mtd, addr, &ops);
222 if (err || ops.oobretlen != mtd->ecclayout->oobavail) { 222 if (err || ops.oobretlen != mtd->ecclayout->oobavail) {
@@ -281,7 +281,7 @@ static int verify_eraseblock_in_one_go(int ebnum)
281 ops.ooblen = len; 281 ops.ooblen = len;
282 ops.oobretlen = 0; 282 ops.oobretlen = 0;
283 ops.ooboffs = 0; 283 ops.ooboffs = 0;
284 ops.datbuf = 0; 284 ops.datbuf = NULL;
285 ops.oobbuf = readbuf; 285 ops.oobbuf = readbuf;
286 err = mtd->read_oob(mtd, addr, &ops); 286 err = mtd->read_oob(mtd, addr, &ops);
287 if (err || ops.oobretlen != len) { 287 if (err || ops.oobretlen != len) {
@@ -522,7 +522,7 @@ static int __init mtd_oobtest_init(void)
522 ops.ooblen = 1; 522 ops.ooblen = 1;
523 ops.oobretlen = 0; 523 ops.oobretlen = 0;
524 ops.ooboffs = mtd->ecclayout->oobavail; 524 ops.ooboffs = mtd->ecclayout->oobavail;
525 ops.datbuf = 0; 525 ops.datbuf = NULL;
526 ops.oobbuf = writebuf; 526 ops.oobbuf = writebuf;
527 printk(PRINT_PREF "attempting to start write past end of OOB\n"); 527 printk(PRINT_PREF "attempting to start write past end of OOB\n");
528 printk(PRINT_PREF "an error is expected...\n"); 528 printk(PRINT_PREF "an error is expected...\n");
@@ -542,7 +542,7 @@ static int __init mtd_oobtest_init(void)
542 ops.ooblen = 1; 542 ops.ooblen = 1;
543 ops.oobretlen = 0; 543 ops.oobretlen = 0;
544 ops.ooboffs = mtd->ecclayout->oobavail; 544 ops.ooboffs = mtd->ecclayout->oobavail;
545 ops.datbuf = 0; 545 ops.datbuf = NULL;
546 ops.oobbuf = readbuf; 546 ops.oobbuf = readbuf;
547 printk(PRINT_PREF "attempting to start read past end of OOB\n"); 547 printk(PRINT_PREF "attempting to start read past end of OOB\n");
548 printk(PRINT_PREF "an error is expected...\n"); 548 printk(PRINT_PREF "an error is expected...\n");
@@ -566,7 +566,7 @@ static int __init mtd_oobtest_init(void)
566 ops.ooblen = mtd->ecclayout->oobavail + 1; 566 ops.ooblen = mtd->ecclayout->oobavail + 1;
567 ops.oobretlen = 0; 567 ops.oobretlen = 0;
568 ops.ooboffs = 0; 568 ops.ooboffs = 0;
569 ops.datbuf = 0; 569 ops.datbuf = NULL;
570 ops.oobbuf = writebuf; 570 ops.oobbuf = writebuf;
571 printk(PRINT_PREF "attempting to write past end of device\n"); 571 printk(PRINT_PREF "attempting to write past end of device\n");
572 printk(PRINT_PREF "an error is expected...\n"); 572 printk(PRINT_PREF "an error is expected...\n");
@@ -586,7 +586,7 @@ static int __init mtd_oobtest_init(void)
586 ops.ooblen = mtd->ecclayout->oobavail + 1; 586 ops.ooblen = mtd->ecclayout->oobavail + 1;
587 ops.oobretlen = 0; 587 ops.oobretlen = 0;
588 ops.ooboffs = 0; 588 ops.ooboffs = 0;
589 ops.datbuf = 0; 589 ops.datbuf = NULL;
590 ops.oobbuf = readbuf; 590 ops.oobbuf = readbuf;
591 printk(PRINT_PREF "attempting to read past end of device\n"); 591 printk(PRINT_PREF "attempting to read past end of device\n");
592 printk(PRINT_PREF "an error is expected...\n"); 592 printk(PRINT_PREF "an error is expected...\n");
@@ -610,7 +610,7 @@ static int __init mtd_oobtest_init(void)
610 ops.ooblen = mtd->ecclayout->oobavail; 610 ops.ooblen = mtd->ecclayout->oobavail;
611 ops.oobretlen = 0; 611 ops.oobretlen = 0;
612 ops.ooboffs = 1; 612 ops.ooboffs = 1;
613 ops.datbuf = 0; 613 ops.datbuf = NULL;
614 ops.oobbuf = writebuf; 614 ops.oobbuf = writebuf;
615 printk(PRINT_PREF "attempting to write past end of device\n"); 615 printk(PRINT_PREF "attempting to write past end of device\n");
616 printk(PRINT_PREF "an error is expected...\n"); 616 printk(PRINT_PREF "an error is expected...\n");
@@ -630,7 +630,7 @@ static int __init mtd_oobtest_init(void)
630 ops.ooblen = mtd->ecclayout->oobavail; 630 ops.ooblen = mtd->ecclayout->oobavail;
631 ops.oobretlen = 0; 631 ops.oobretlen = 0;
632 ops.ooboffs = 1; 632 ops.ooboffs = 1;
633 ops.datbuf = 0; 633 ops.datbuf = NULL;
634 ops.oobbuf = readbuf; 634 ops.oobbuf = readbuf;
635 printk(PRINT_PREF "attempting to read past end of device\n"); 635 printk(PRINT_PREF "attempting to read past end of device\n");
636 printk(PRINT_PREF "an error is expected...\n"); 636 printk(PRINT_PREF "an error is expected...\n");
@@ -670,7 +670,7 @@ static int __init mtd_oobtest_init(void)
670 ops.ooblen = sz; 670 ops.ooblen = sz;
671 ops.oobretlen = 0; 671 ops.oobretlen = 0;
672 ops.ooboffs = 0; 672 ops.ooboffs = 0;
673 ops.datbuf = 0; 673 ops.datbuf = NULL;
674 ops.oobbuf = writebuf; 674 ops.oobbuf = writebuf;
675 err = mtd->write_oob(mtd, addr, &ops); 675 err = mtd->write_oob(mtd, addr, &ops);
676 if (err) 676 if (err)
@@ -698,7 +698,7 @@ static int __init mtd_oobtest_init(void)
698 ops.ooblen = mtd->ecclayout->oobavail * 2; 698 ops.ooblen = mtd->ecclayout->oobavail * 2;
699 ops.oobretlen = 0; 699 ops.oobretlen = 0;
700 ops.ooboffs = 0; 700 ops.ooboffs = 0;
701 ops.datbuf = 0; 701 ops.datbuf = NULL;
702 ops.oobbuf = readbuf; 702 ops.oobbuf = readbuf;
703 err = mtd->read_oob(mtd, addr, &ops); 703 err = mtd->read_oob(mtd, addr, &ops);
704 if (err) 704 if (err)
diff --git a/drivers/mtd/tests/mtd_readtest.c b/drivers/mtd/tests/mtd_readtest.c
index 645e77fdc63d..79fc4530987b 100644
--- a/drivers/mtd/tests/mtd_readtest.c
+++ b/drivers/mtd/tests/mtd_readtest.c
@@ -71,7 +71,7 @@ static int read_eraseblock_by_page(int ebnum)
71 ops.ooblen = mtd->oobsize; 71 ops.ooblen = mtd->oobsize;
72 ops.oobretlen = 0; 72 ops.oobretlen = 0;
73 ops.ooboffs = 0; 73 ops.ooboffs = 0;
74 ops.datbuf = 0; 74 ops.datbuf = NULL;
75 ops.oobbuf = oobbuf; 75 ops.oobbuf = oobbuf;
76 ret = mtd->read_oob(mtd, addr, &ops); 76 ret = mtd->read_oob(mtd, addr, &ops);
77 if (ret || ops.oobretlen != mtd->oobsize) { 77 if (ret || ops.oobretlen != mtd->oobsize) {