diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-26 23:30:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-26 23:30:56 -0400 |
commit | 9ee08c2df47c10ba624ff05a6c0f2500748bcb69 (patch) | |
tree | 0a2788abb3b5547b83965e0b3132eec8b196bd81 /drivers/mtd | |
parent | eaf0ba5ef69538b6913525294a3a0fcb0e0992e0 (diff) | |
parent | 3d45955962496879dead8d4dd70bb9a23b07154b (diff) |
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: (57 commits)
[MTD] [NAND] subpage read feature as a way to increase performance.
CPUFREQ: S3C24XX NAND driver frequency scaling support.
[MTD][NAND] au1550nd: remove unused variable
[MTD] jedec_probe: Fix SST 16-bit chip detection
[MTD][MTDPART] Fix a division by zero bug
[MTD][MTDPART] Cleanup and document the erase region handling
[MTD][MTDPART] Handle most checkpatch findings
[MTD][MTDPART] Seperate main loop from per-partition code in add_mtd_partition
[MTD] physmap: resume already suspended chips on failure to suspend
[MTD] physmap: Fix suspend/resume/shutdown bugs.
[MTD] [NOR] Fix -ETIMEO errors in CFI driver
[MTD] [NAND] fsl_elbc_nand: fix section mismatch with CONFIG_MTD_OF_PARTS=y
[JFFS2] Use .unlocked_ioctl
[MTD] Fix const assignment in the MTD command line partitioning driver
[MTD] [NOR] gen_probe: No debug message when debugging is disabled
[MTD] [NAND] remove __PPC__ hardcoded address from DiskOnChip drivers
[MTD] [MAPS] Remove the bast-flash driver.
[MTD] [NAND] fsl_elbc_nand: ecclayout cleanups
[MTD] [NAND] fsl_elbc_nand: implement support for flash-based BBT
[MTD] [NAND] fsl_elbc_nand: fix OOB workability for large page NAND chips
...
Diffstat (limited to 'drivers/mtd')
122 files changed, 1324 insertions, 984 deletions
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index eed06d068fd1..14f11f8b9e5f 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig | |||
@@ -1,5 +1,3 @@ | |||
1 | # $Id: Kconfig,v 1.11 2005/11/07 11:14:19 gleixner Exp $ | ||
2 | |||
3 | menuconfig MTD | 1 | menuconfig MTD |
4 | tristate "Memory Technology Device (MTD) support" | 2 | tristate "Memory Technology Device (MTD) support" |
5 | depends on HAS_IOMEM | 3 | depends on HAS_IOMEM |
diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c index 52d51eb91c16..d072ca5be689 100644 --- a/drivers/mtd/afs.c +++ b/drivers/mtd/afs.c | |||
@@ -21,8 +21,6 @@ | |||
21 | This is access code for flashes using ARM's flash partitioning | 21 | This is access code for flashes using ARM's flash partitioning |
22 | standards. | 22 | standards. |
23 | 23 | ||
24 | $Id: afs.c,v 1.15 2005/11/07 11:14:19 gleixner Exp $ | ||
25 | |||
26 | ======================================================================*/ | 24 | ======================================================================*/ |
27 | 25 | ||
28 | #include <linux/module.h> | 26 | #include <linux/module.h> |
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index fcd1aeccdf93..5f1b472137a0 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c | |||
@@ -4,8 +4,6 @@ | |||
4 | * | 4 | * |
5 | * (C) 2000 Red Hat. GPL'd | 5 | * (C) 2000 Red Hat. GPL'd |
6 | * | 6 | * |
7 | * $Id: cfi_cmdset_0001.c,v 1.186 2005/11/23 22:07:52 nico Exp $ | ||
8 | * | ||
9 | * | 7 | * |
10 | * 10/10/2000 Nicolas Pitre <nico@cam.org> | 8 | * 10/10/2000 Nicolas Pitre <nico@cam.org> |
11 | * - completely revamped method functions so they are aware and | 9 | * - completely revamped method functions so they are aware and |
@@ -50,6 +48,8 @@ | |||
50 | #define I82802AC 0x00ac | 48 | #define I82802AC 0x00ac |
51 | #define MANUFACTURER_ST 0x0020 | 49 | #define MANUFACTURER_ST 0x0020 |
52 | #define M50LPW080 0x002F | 50 | #define M50LPW080 0x002F |
51 | #define M50FLW080A 0x0080 | ||
52 | #define M50FLW080B 0x0081 | ||
53 | #define AT49BV640D 0x02de | 53 | #define AT49BV640D 0x02de |
54 | 54 | ||
55 | static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); | 55 | static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); |
@@ -204,7 +204,7 @@ static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) | |||
204 | { | 204 | { |
205 | struct map_info *map = mtd->priv; | 205 | struct map_info *map = mtd->priv; |
206 | struct cfi_private *cfi = map->fldrv_priv; | 206 | struct cfi_private *cfi = map->fldrv_priv; |
207 | struct cfi_pri_amdstd *extp = cfi->cmdset_priv; | 207 | struct cfi_pri_intelext *extp = cfi->cmdset_priv; |
208 | 208 | ||
209 | printk(KERN_WARNING "cfi_cmdset_0001: Suspend " | 209 | printk(KERN_WARNING "cfi_cmdset_0001: Suspend " |
210 | "erase on write disabled.\n"); | 210 | "erase on write disabled.\n"); |
@@ -301,6 +301,8 @@ static struct cfi_fixup jedec_fixup_table[] = { | |||
301 | { MANUFACTURER_INTEL, I82802AB, fixup_use_fwh_lock, NULL, }, | 301 | { MANUFACTURER_INTEL, I82802AB, fixup_use_fwh_lock, NULL, }, |
302 | { MANUFACTURER_INTEL, I82802AC, fixup_use_fwh_lock, NULL, }, | 302 | { MANUFACTURER_INTEL, I82802AC, fixup_use_fwh_lock, NULL, }, |
303 | { MANUFACTURER_ST, M50LPW080, fixup_use_fwh_lock, NULL, }, | 303 | { MANUFACTURER_ST, M50LPW080, fixup_use_fwh_lock, NULL, }, |
304 | { MANUFACTURER_ST, M50FLW080A, fixup_use_fwh_lock, NULL, }, | ||
305 | { MANUFACTURER_ST, M50FLW080B, fixup_use_fwh_lock, NULL, }, | ||
304 | { 0, 0, NULL, NULL } | 306 | { 0, 0, NULL, NULL } |
305 | }; | 307 | }; |
306 | static struct cfi_fixup fixup_table[] = { | 308 | static struct cfi_fixup fixup_table[] = { |
@@ -1147,7 +1149,7 @@ static int inval_cache_and_wait_for_operation( | |||
1147 | struct cfi_private *cfi = map->fldrv_priv; | 1149 | struct cfi_private *cfi = map->fldrv_priv; |
1148 | map_word status, status_OK = CMD(0x80); | 1150 | map_word status, status_OK = CMD(0x80); |
1149 | int chip_state = chip->state; | 1151 | int chip_state = chip->state; |
1150 | unsigned int timeo, sleep_time; | 1152 | unsigned int timeo, sleep_time, reset_timeo; |
1151 | 1153 | ||
1152 | spin_unlock(chip->mutex); | 1154 | spin_unlock(chip->mutex); |
1153 | if (inval_len) | 1155 | if (inval_len) |
@@ -1158,6 +1160,7 @@ static int inval_cache_and_wait_for_operation( | |||
1158 | timeo = chip_op_time * 8; | 1160 | timeo = chip_op_time * 8; |
1159 | if (!timeo) | 1161 | if (!timeo) |
1160 | timeo = 500000; | 1162 | timeo = 500000; |
1163 | reset_timeo = timeo; | ||
1161 | sleep_time = chip_op_time / 2; | 1164 | sleep_time = chip_op_time / 2; |
1162 | 1165 | ||
1163 | for (;;) { | 1166 | for (;;) { |
@@ -1199,6 +1202,12 @@ static int inval_cache_and_wait_for_operation( | |||
1199 | remove_wait_queue(&chip->wq, &wait); | 1202 | remove_wait_queue(&chip->wq, &wait); |
1200 | spin_lock(chip->mutex); | 1203 | spin_lock(chip->mutex); |
1201 | } | 1204 | } |
1205 | if (chip->erase_suspended || chip->write_suspended) { | ||
1206 | /* Suspend has occured while sleep: reset timeout */ | ||
1207 | timeo = reset_timeo; | ||
1208 | chip->erase_suspended = 0; | ||
1209 | chip->write_suspended = 0; | ||
1210 | } | ||
1202 | } | 1211 | } |
1203 | 1212 | ||
1204 | /* Done and happy. */ | 1213 | /* Done and happy. */ |
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index f7fcc6389533..a972cc6be436 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c | |||
@@ -16,9 +16,6 @@ | |||
16 | * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com | 16 | * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com |
17 | * | 17 | * |
18 | * This code is GPL | 18 | * This code is GPL |
19 | * | ||
20 | * $Id: cfi_cmdset_0002.c,v 1.122 2005/11/07 11:14:22 gleixner Exp $ | ||
21 | * | ||
22 | */ | 19 | */ |
23 | 20 | ||
24 | #include <linux/module.h> | 21 | #include <linux/module.h> |
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c index 1b720cc571f3..d4714dd9f7ab 100644 --- a/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/drivers/mtd/chips/cfi_cmdset_0020.c | |||
@@ -4,8 +4,6 @@ | |||
4 | * | 4 | * |
5 | * (C) 2000 Red Hat. GPL'd | 5 | * (C) 2000 Red Hat. GPL'd |
6 | * | 6 | * |
7 | * $Id: cfi_cmdset_0020.c,v 1.22 2005/11/07 11:14:22 gleixner Exp $ | ||
8 | * | ||
9 | * 10/10/2000 Nicolas Pitre <nico@cam.org> | 7 | * 10/10/2000 Nicolas Pitre <nico@cam.org> |
10 | * - completely revamped method functions so they are aware and | 8 | * - completely revamped method functions so they are aware and |
11 | * independent of the flash geometry (buswidth, interleave, etc.) | 9 | * independent of the flash geometry (buswidth, interleave, etc.) |
diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c index a4463a91ce31..c418e92e1d92 100644 --- a/drivers/mtd/chips/cfi_probe.c +++ b/drivers/mtd/chips/cfi_probe.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Common Flash Interface probe code. | 2 | Common Flash Interface probe code. |
3 | (C) 2000 Red Hat. GPL'd. | 3 | (C) 2000 Red Hat. GPL'd. |
4 | $Id: cfi_probe.c,v 1.86 2005/11/29 14:48:31 gleixner Exp $ | ||
5 | */ | 4 | */ |
6 | 5 | ||
7 | #include <linux/module.h> | 6 | #include <linux/module.h> |
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c index 72e0022a47bf..0ee457018016 100644 --- a/drivers/mtd/chips/cfi_util.c +++ b/drivers/mtd/chips/cfi_util.c | |||
@@ -6,9 +6,6 @@ | |||
6 | * Copyright (C) 2003 STMicroelectronics Limited | 6 | * Copyright (C) 2003 STMicroelectronics Limited |
7 | * | 7 | * |
8 | * This code is covered by the GPL. | 8 | * This code is covered by the GPL. |
9 | * | ||
10 | * $Id: cfi_util.c,v 1.10 2005/11/07 11:14:23 gleixner Exp $ | ||
11 | * | ||
12 | */ | 9 | */ |
13 | 10 | ||
14 | #include <linux/module.h> | 11 | #include <linux/module.h> |
diff --git a/drivers/mtd/chips/chipreg.c b/drivers/mtd/chips/chipreg.c index 2174c97549f0..c85760968227 100644 --- a/drivers/mtd/chips/chipreg.c +++ b/drivers/mtd/chips/chipreg.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: chipreg.c,v 1.17 2004/11/16 18:29:00 dwmw2 Exp $ | ||
3 | * | ||
4 | * Registration for chip drivers | 2 | * Registration for chip drivers |
5 | * | 3 | * |
6 | */ | 4 | */ |
diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c index d338b8c92780..f061885b2812 100644 --- a/drivers/mtd/chips/gen_probe.c +++ b/drivers/mtd/chips/gen_probe.c | |||
@@ -2,7 +2,6 @@ | |||
2 | * Routines common to all CFI-type probes. | 2 | * Routines common to all CFI-type probes. |
3 | * (C) 2001-2003 Red Hat, Inc. | 3 | * (C) 2001-2003 Red Hat, Inc. |
4 | * GPL'd | 4 | * GPL'd |
5 | * $Id: gen_probe.c,v 1.24 2005/11/07 11:14:23 gleixner Exp $ | ||
6 | */ | 5 | */ |
7 | 6 | ||
8 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
@@ -71,8 +70,8 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi | |||
71 | interleave and device type, etc. */ | 70 | interleave and device type, etc. */ |
72 | if (!genprobe_new_chip(map, cp, &cfi)) { | 71 | if (!genprobe_new_chip(map, cp, &cfi)) { |
73 | /* The probe didn't like it */ | 72 | /* The probe didn't like it */ |
74 | printk(KERN_DEBUG "%s: Found no %s device at location zero\n", | 73 | pr_debug("%s: Found no %s device at location zero\n", |
75 | cp->name, map->name); | 74 | cp->name, map->name); |
76 | return NULL; | 75 | return NULL; |
77 | } | 76 | } |
78 | 77 | ||
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index aa07575eb288..dbba5abf0db8 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Common Flash Interface probe code. | 2 | Common Flash Interface probe code. |
3 | (C) 2000 Red Hat. GPL'd. | 3 | (C) 2000 Red Hat. GPL'd. |
4 | $Id: jedec_probe.c,v 1.66 2005/11/07 11:14:23 gleixner Exp $ | ||
5 | See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5) | 4 | See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5) |
6 | for the standard this probe goes back to. | 5 | for the standard this probe goes back to. |
7 | 6 | ||
@@ -26,6 +25,7 @@ | |||
26 | /* Manufacturers */ | 25 | /* Manufacturers */ |
27 | #define MANUFACTURER_AMD 0x0001 | 26 | #define MANUFACTURER_AMD 0x0001 |
28 | #define MANUFACTURER_ATMEL 0x001f | 27 | #define MANUFACTURER_ATMEL 0x001f |
28 | #define MANUFACTURER_EON 0x001c | ||
29 | #define MANUFACTURER_FUJITSU 0x0004 | 29 | #define MANUFACTURER_FUJITSU 0x0004 |
30 | #define MANUFACTURER_HYUNDAI 0x00AD | 30 | #define MANUFACTURER_HYUNDAI 0x00AD |
31 | #define MANUFACTURER_INTEL 0x0089 | 31 | #define MANUFACTURER_INTEL 0x0089 |
@@ -37,6 +37,7 @@ | |||
37 | #define MANUFACTURER_ST 0x0020 | 37 | #define MANUFACTURER_ST 0x0020 |
38 | #define MANUFACTURER_TOSHIBA 0x0098 | 38 | #define MANUFACTURER_TOSHIBA 0x0098 |
39 | #define MANUFACTURER_WINBOND 0x00da | 39 | #define MANUFACTURER_WINBOND 0x00da |
40 | #define CONTINUATION_CODE 0x007f | ||
40 | 41 | ||
41 | 42 | ||
42 | /* AMD */ | 43 | /* AMD */ |
@@ -58,6 +59,8 @@ | |||
58 | #define AM29LV040B 0x004F | 59 | #define AM29LV040B 0x004F |
59 | #define AM29F032B 0x0041 | 60 | #define AM29F032B 0x0041 |
60 | #define AM29F002T 0x00B0 | 61 | #define AM29F002T 0x00B0 |
62 | #define AM29SL800DB 0x226B | ||
63 | #define AM29SL800DT 0x22EA | ||
61 | 64 | ||
62 | /* Atmel */ | 65 | /* Atmel */ |
63 | #define AT49BV512 0x0003 | 66 | #define AT49BV512 0x0003 |
@@ -67,6 +70,10 @@ | |||
67 | #define AT49BV32X 0x00C8 | 70 | #define AT49BV32X 0x00C8 |
68 | #define AT49BV32XT 0x00C9 | 71 | #define AT49BV32XT 0x00C9 |
69 | 72 | ||
73 | /* Eon */ | ||
74 | #define EN29SL800BB 0x226B | ||
75 | #define EN29SL800BT 0x22EA | ||
76 | |||
70 | /* Fujitsu */ | 77 | /* Fujitsu */ |
71 | #define MBM29F040C 0x00A4 | 78 | #define MBM29F040C 0x00A4 |
72 | #define MBM29F800BA 0x2258 | 79 | #define MBM29F800BA 0x2258 |
@@ -141,6 +148,8 @@ | |||
141 | #define M50FW080 0x002D | 148 | #define M50FW080 0x002D |
142 | #define M50FW016 0x002E | 149 | #define M50FW016 0x002E |
143 | #define M50LPW080 0x002F | 150 | #define M50LPW080 0x002F |
151 | #define M50FLW080A 0x0080 | ||
152 | #define M50FLW080B 0x0081 | ||
144 | 153 | ||
145 | /* SST */ | 154 | /* SST */ |
146 | #define SST29EE020 0x0010 | 155 | #define SST29EE020 0x0010 |
@@ -191,6 +200,7 @@ enum uaddr { | |||
191 | MTD_UADDR_0x0555_0x0AAA, | 200 | MTD_UADDR_0x0555_0x0AAA, |
192 | MTD_UADDR_0x5555_0x2AAA, | 201 | MTD_UADDR_0x5555_0x2AAA, |
193 | MTD_UADDR_0x0AAA_0x0555, | 202 | MTD_UADDR_0x0AAA_0x0555, |
203 | MTD_UADDR_0xAAAA_0x5555, | ||
194 | MTD_UADDR_DONT_CARE, /* Requires an arbitrary address */ | 204 | MTD_UADDR_DONT_CARE, /* Requires an arbitrary address */ |
195 | MTD_UADDR_UNNECESSARY, /* Does not require any address */ | 205 | MTD_UADDR_UNNECESSARY, /* Does not require any address */ |
196 | }; | 206 | }; |
@@ -238,6 +248,11 @@ static const struct unlock_addr unlock_addrs[] = { | |||
238 | .addr2 = 0x0555 | 248 | .addr2 = 0x0555 |
239 | }, | 249 | }, |
240 | 250 | ||
251 | [MTD_UADDR_0xAAAA_0x5555] = { | ||
252 | .addr1 = 0xaaaa, | ||
253 | .addr2 = 0x5555 | ||
254 | }, | ||
255 | |||
241 | [MTD_UADDR_DONT_CARE] = { | 256 | [MTD_UADDR_DONT_CARE] = { |
242 | .addr1 = 0x0000, /* Doesn't matter which address */ | 257 | .addr1 = 0x0000, /* Doesn't matter which address */ |
243 | .addr2 = 0x0000 /* is used - must be last entry */ | 258 | .addr2 = 0x0000 /* is used - must be last entry */ |
@@ -522,6 +537,36 @@ static const struct amd_flash_info jedec_table[] = { | |||
522 | ERASEINFO(0x04000,1), | 537 | ERASEINFO(0x04000,1), |
523 | } | 538 | } |
524 | }, { | 539 | }, { |
540 | .mfr_id = MANUFACTURER_AMD, | ||
541 | .dev_id = AM29SL800DT, | ||
542 | .name = "AMD AM29SL800DT", | ||
543 | .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, | ||
544 | .uaddr = MTD_UADDR_0x0AAA_0x0555, | ||
545 | .dev_size = SIZE_1MiB, | ||
546 | .cmd_set = P_ID_AMD_STD, | ||
547 | .nr_regions = 4, | ||
548 | .regions = { | ||
549 | ERASEINFO(0x10000,15), | ||
550 | ERASEINFO(0x08000,1), | ||
551 | ERASEINFO(0x02000,2), | ||
552 | ERASEINFO(0x04000,1), | ||
553 | } | ||
554 | }, { | ||
555 | .mfr_id = MANUFACTURER_AMD, | ||
556 | .dev_id = AM29SL800DB, | ||
557 | .name = "AMD AM29SL800DB", | ||
558 | .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, | ||
559 | .uaddr = MTD_UADDR_0x0AAA_0x0555, | ||
560 | .dev_size = SIZE_1MiB, | ||
561 | .cmd_set = P_ID_AMD_STD, | ||
562 | .nr_regions = 4, | ||
563 | .regions = { | ||
564 | ERASEINFO(0x04000,1), | ||
565 | ERASEINFO(0x02000,2), | ||
566 | ERASEINFO(0x08000,1), | ||
567 | ERASEINFO(0x10000,15), | ||
568 | } | ||
569 | }, { | ||
525 | .mfr_id = MANUFACTURER_ATMEL, | 570 | .mfr_id = MANUFACTURER_ATMEL, |
526 | .dev_id = AT49BV512, | 571 | .dev_id = AT49BV512, |
527 | .name = "Atmel AT49BV512", | 572 | .name = "Atmel AT49BV512", |
@@ -599,6 +644,36 @@ static const struct amd_flash_info jedec_table[] = { | |||
599 | ERASEINFO(0x02000,8) | 644 | ERASEINFO(0x02000,8) |
600 | } | 645 | } |
601 | }, { | 646 | }, { |
647 | .mfr_id = MANUFACTURER_EON, | ||
648 | .dev_id = EN29SL800BT, | ||
649 | .name = "Eon EN29SL800BT", | ||
650 | .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, | ||
651 | .uaddr = MTD_UADDR_0x0AAA_0x0555, | ||
652 | .dev_size = SIZE_1MiB, | ||
653 | .cmd_set = P_ID_AMD_STD, | ||
654 | .nr_regions = 4, | ||
655 | .regions = { | ||
656 | ERASEINFO(0x10000,15), | ||
657 | ERASEINFO(0x08000,1), | ||
658 | ERASEINFO(0x02000,2), | ||
659 | ERASEINFO(0x04000,1), | ||
660 | } | ||
661 | }, { | ||
662 | .mfr_id = MANUFACTURER_EON, | ||
663 | .dev_id = EN29SL800BB, | ||
664 | .name = "Eon EN29SL800BB", | ||
665 | .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, | ||
666 | .uaddr = MTD_UADDR_0x0AAA_0x0555, | ||
667 | .dev_size = SIZE_1MiB, | ||
668 | .cmd_set = P_ID_AMD_STD, | ||
669 | .nr_regions = 4, | ||
670 | .regions = { | ||
671 | ERASEINFO(0x04000,1), | ||
672 | ERASEINFO(0x02000,2), | ||
673 | ERASEINFO(0x08000,1), | ||
674 | ERASEINFO(0x10000,15), | ||
675 | } | ||
676 | }, { | ||
602 | .mfr_id = MANUFACTURER_FUJITSU, | 677 | .mfr_id = MANUFACTURER_FUJITSU, |
603 | .dev_id = MBM29F040C, | 678 | .dev_id = MBM29F040C, |
604 | .name = "Fujitsu MBM29F040C", | 679 | .name = "Fujitsu MBM29F040C", |
@@ -1392,8 +1467,8 @@ static const struct amd_flash_info jedec_table[] = { | |||
1392 | .mfr_id = MANUFACTURER_SST, /* should be CFI */ | 1467 | .mfr_id = MANUFACTURER_SST, /* should be CFI */ |
1393 | .dev_id = SST39LF160, | 1468 | .dev_id = SST39LF160, |
1394 | .name = "SST 39LF160", | 1469 | .name = "SST 39LF160", |
1395 | .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, | 1470 | .devtypes = CFI_DEVICETYPE_X16, |
1396 | .uaddr = MTD_UADDR_0x5555_0x2AAA, /* ???? */ | 1471 | .uaddr = MTD_UADDR_0xAAAA_0x5555, |
1397 | .dev_size = SIZE_2MiB, | 1472 | .dev_size = SIZE_2MiB, |
1398 | .cmd_set = P_ID_AMD_STD, | 1473 | .cmd_set = P_ID_AMD_STD, |
1399 | .nr_regions = 2, | 1474 | .nr_regions = 2, |
@@ -1405,8 +1480,8 @@ static const struct amd_flash_info jedec_table[] = { | |||
1405 | .mfr_id = MANUFACTURER_SST, /* should be CFI */ | 1480 | .mfr_id = MANUFACTURER_SST, /* should be CFI */ |
1406 | .dev_id = SST39VF1601, | 1481 | .dev_id = SST39VF1601, |
1407 | .name = "SST 39VF1601", | 1482 | .name = "SST 39VF1601", |
1408 | .devtypes = CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8, | 1483 | .devtypes = CFI_DEVICETYPE_X16, |
1409 | .uaddr = MTD_UADDR_0x5555_0x2AAA, /* ???? */ | 1484 | .uaddr = MTD_UADDR_0xAAAA_0x5555, |
1410 | .dev_size = SIZE_2MiB, | 1485 | .dev_size = SIZE_2MiB, |
1411 | .cmd_set = P_ID_AMD_STD, | 1486 | .cmd_set = P_ID_AMD_STD, |
1412 | .nr_regions = 2, | 1487 | .nr_regions = 2, |
@@ -1590,6 +1665,36 @@ static const struct amd_flash_info jedec_table[] = { | |||
1590 | .nr_regions = 1, | 1665 | .nr_regions = 1, |
1591 | .regions = { | 1666 | .regions = { |
1592 | ERASEINFO(0x10000,16), | 1667 | ERASEINFO(0x10000,16), |
1668 | }, | ||
1669 | }, { | ||
1670 | .mfr_id = MANUFACTURER_ST, | ||
1671 | .dev_id = M50FLW080A, | ||
1672 | .name = "ST M50FLW080A", | ||
1673 | .devtypes = CFI_DEVICETYPE_X8, | ||
1674 | .uaddr = MTD_UADDR_UNNECESSARY, | ||
1675 | .dev_size = SIZE_1MiB, | ||
1676 | .cmd_set = P_ID_INTEL_EXT, | ||
1677 | .nr_regions = 4, | ||
1678 | .regions = { | ||
1679 | ERASEINFO(0x1000,16), | ||
1680 | ERASEINFO(0x10000,13), | ||
1681 | ERASEINFO(0x1000,16), | ||
1682 | ERASEINFO(0x1000,16), | ||
1683 | } | ||
1684 | }, { | ||
1685 | .mfr_id = MANUFACTURER_ST, | ||
1686 | .dev_id = M50FLW080B, | ||
1687 | .name = "ST M50FLW080B", | ||
1688 | .devtypes = CFI_DEVICETYPE_X8, | ||
1689 | .uaddr = MTD_UADDR_UNNECESSARY, | ||
1690 | .dev_size = SIZE_1MiB, | ||
1691 | .cmd_set = P_ID_INTEL_EXT, | ||
1692 | .nr_regions = 4, | ||
1693 | .regions = { | ||
1694 | ERASEINFO(0x1000,16), | ||
1695 | ERASEINFO(0x1000,16), | ||
1696 | ERASEINFO(0x10000,13), | ||
1697 | ERASEINFO(0x1000,16), | ||
1593 | } | 1698 | } |
1594 | }, { | 1699 | }, { |
1595 | .mfr_id = MANUFACTURER_TOSHIBA, | 1700 | .mfr_id = MANUFACTURER_TOSHIBA, |
@@ -1696,9 +1801,21 @@ static inline u32 jedec_read_mfr(struct map_info *map, uint32_t base, | |||
1696 | { | 1801 | { |
1697 | map_word result; | 1802 | map_word result; |
1698 | unsigned long mask; | 1803 | unsigned long mask; |
1699 | u32 ofs = cfi_build_cmd_addr(0, cfi_interleave(cfi), cfi->device_type); | 1804 | int bank = 0; |
1700 | mask = (1 << (cfi->device_type * 8)) -1; | 1805 | |
1701 | result = map_read(map, base + ofs); | 1806 | /* According to JEDEC "Standard Manufacturer's Identification Code" |
1807 | * (http://www.jedec.org/download/search/jep106W.pdf) | ||
1808 | * several first banks can contain 0x7f instead of actual ID | ||
1809 | */ | ||
1810 | do { | ||
1811 | uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), | ||
1812 | cfi_interleave(cfi), | ||
1813 | cfi->device_type); | ||
1814 | mask = (1 << (cfi->device_type * 8)) - 1; | ||
1815 | result = map_read(map, base + ofs); | ||
1816 | bank++; | ||
1817 | } while ((result.x[0] & mask) == CONTINUATION_CODE); | ||
1818 | |||
1702 | return result.x[0] & mask; | 1819 | return result.x[0] & mask; |
1703 | } | 1820 | } |
1704 | 1821 | ||
diff --git a/drivers/mtd/chips/map_absent.c b/drivers/mtd/chips/map_absent.c index fc478c0f93f5..494d30d0631a 100644 --- a/drivers/mtd/chips/map_absent.c +++ b/drivers/mtd/chips/map_absent.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Common code to handle absent "placeholder" devices | 2 | * Common code to handle absent "placeholder" devices |
3 | * Copyright 2001 Resilience Corporation <ebrower@resilience.com> | 3 | * Copyright 2001 Resilience Corporation <ebrower@resilience.com> |
4 | * $Id: map_absent.c,v 1.6 2005/11/07 11:14:23 gleixner Exp $ | ||
5 | * | 4 | * |
6 | * This map driver is used to allocate "placeholder" MTD | 5 | * This map driver is used to allocate "placeholder" MTD |
7 | * devices on systems that have socketed/removable media. | 6 | * devices on systems that have socketed/removable media. |
diff --git a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c index 5cb6d5263661..072dd8abf33a 100644 --- a/drivers/mtd/chips/map_ram.c +++ b/drivers/mtd/chips/map_ram.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Common code to handle map devices which are simple RAM | 2 | * Common code to handle map devices which are simple RAM |
3 | * (C) 2000 Red Hat. GPL'd. | 3 | * (C) 2000 Red Hat. GPL'd. |
4 | * $Id: map_ram.c,v 1.22 2005/01/05 18:05:12 dwmw2 Exp $ | ||
5 | */ | 4 | */ |
6 | 5 | ||
7 | #include <linux/module.h> | 6 | #include <linux/module.h> |
diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c index cb27f855074c..821d0ed6bae3 100644 --- a/drivers/mtd/chips/map_rom.c +++ b/drivers/mtd/chips/map_rom.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Common code to handle map devices which are simple ROM | 2 | * Common code to handle map devices which are simple ROM |
3 | * (C) 2000 Red Hat. GPL'd. | 3 | * (C) 2000 Red Hat. GPL'd. |
4 | * $Id: map_rom.c,v 1.23 2005/01/05 18:05:12 dwmw2 Exp $ | ||
5 | */ | 4 | */ |
6 | 5 | ||
7 | #include <linux/module.h> | 6 | #include <linux/module.h> |
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index e472a0e9de9d..71bc07f149b7 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: cmdlinepart.c,v 1.19 2005/11/07 11:14:19 gleixner Exp $ | ||
3 | * | ||
4 | * Read flash partition table from command line | 2 | * Read flash partition table from command line |
5 | * | 3 | * |
6 | * Copyright 2002 SYSGO Real-Time Solutions GmbH | 4 | * Copyright 2002 SYSGO Real-Time Solutions GmbH |
@@ -308,7 +306,7 @@ static int parse_cmdline_partitions(struct mtd_info *master, | |||
308 | unsigned long offset; | 306 | unsigned long offset; |
309 | int i; | 307 | int i; |
310 | struct cmdline_mtd_partition *part; | 308 | struct cmdline_mtd_partition *part; |
311 | char *mtd_id = master->name; | 309 | const char *mtd_id = master->name; |
312 | 310 | ||
313 | /* parse command line */ | 311 | /* parse command line */ |
314 | if (!cmdline_parsed) | 312 | if (!cmdline_parsed) |
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index 35ed1103dbb2..9c613f06623c 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig | |||
@@ -1,5 +1,4 @@ | |||
1 | # drivers/mtd/maps/Kconfig | 1 | # drivers/mtd/maps/Kconfig |
2 | # $Id: Kconfig,v 1.18 2005/11/07 11:14:24 gleixner Exp $ | ||
3 | 2 | ||
4 | menu "Self-contained MTD device drivers" | 3 | menu "Self-contained MTD device drivers" |
5 | depends on MTD!=n | 4 | depends on MTD!=n |
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile index 0f788d5c4bf8..0993d5cf3923 100644 --- a/drivers/mtd/devices/Makefile +++ b/drivers/mtd/devices/Makefile | |||
@@ -1,7 +1,6 @@ | |||
1 | # | 1 | # |
2 | # linux/drivers/devices/Makefile | 2 | # linux/drivers/devices/Makefile |
3 | # | 3 | # |
4 | # $Id: Makefile.common,v 1.7 2004/12/22 17:51:15 joern Exp $ | ||
5 | 4 | ||
6 | obj-$(CONFIG_MTD_DOC2000) += doc2000.o | 5 | obj-$(CONFIG_MTD_DOC2000) += doc2000.o |
7 | obj-$(CONFIG_MTD_DOC2001) += doc2001.o | 6 | obj-$(CONFIG_MTD_DOC2001) += doc2001.o |
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 7b72a1b36115..91fbba767635 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: block2mtd.c,v 1.30 2005/11/29 14:48:32 gleixner Exp $ | ||
3 | * | ||
4 | * block2mtd.c - create an mtd from a block device | 2 | * block2mtd.c - create an mtd from a block device |
5 | * | 3 | * |
6 | * Copyright (C) 2001,2002 Simon Evans <spse@secret.org.uk> | 4 | * Copyright (C) 2001,2002 Simon Evans <spse@secret.org.uk> |
@@ -20,9 +18,6 @@ | |||
20 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
21 | #include <linux/mount.h> | 19 | #include <linux/mount.h> |
22 | 20 | ||
23 | #define VERSION "$Revision: 1.30 $" | ||
24 | |||
25 | |||
26 | #define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args) | 21 | #define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args) |
27 | #define INFO(fmt, args...) printk(KERN_INFO "block2mtd: " fmt "\n" , ## args) | 22 | #define INFO(fmt, args...) printk(KERN_INFO "block2mtd: " fmt "\n" , ## args) |
28 | 23 | ||
@@ -453,7 +448,6 @@ MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\""); | |||
453 | static int __init block2mtd_init(void) | 448 | static int __init block2mtd_init(void) |
454 | { | 449 | { |
455 | int ret = 0; | 450 | int ret = 0; |
456 | INFO("version " VERSION); | ||
457 | 451 | ||
458 | #ifndef MODULE | 452 | #ifndef MODULE |
459 | if (strlen(block2mtd_paramline)) | 453 | if (strlen(block2mtd_paramline)) |
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c index 846989f292e3..50de839c77a9 100644 --- a/drivers/mtd/devices/doc2000.c +++ b/drivers/mtd/devices/doc2000.c | |||
@@ -3,8 +3,6 @@ | |||
3 | * Linux driver for Disk-On-Chip 2000 and Millennium | 3 | * Linux driver for Disk-On-Chip 2000 and Millennium |
4 | * (c) 1999 Machine Vision Holdings, Inc. | 4 | * (c) 1999 Machine Vision Holdings, Inc. |
5 | * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> | 5 | * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> |
6 | * | ||
7 | * $Id: doc2000.c,v 1.67 2005/11/07 11:14:24 gleixner Exp $ | ||
8 | */ | 6 | */ |
9 | 7 | ||
10 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c index 6413efc045e0..e32c568c1145 100644 --- a/drivers/mtd/devices/doc2001.c +++ b/drivers/mtd/devices/doc2001.c | |||
@@ -3,8 +3,6 @@ | |||
3 | * Linux driver for Disk-On-Chip Millennium | 3 | * Linux driver for Disk-On-Chip Millennium |
4 | * (c) 1999 Machine Vision Holdings, Inc. | 4 | * (c) 1999 Machine Vision Holdings, Inc. |
5 | * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> | 5 | * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> |
6 | * | ||
7 | * $Id: doc2001.c,v 1.49 2005/11/07 11:14:24 gleixner Exp $ | ||
8 | */ | 6 | */ |
9 | 7 | ||
10 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c index 83be3461658f..d853f891b586 100644 --- a/drivers/mtd/devices/doc2001plus.c +++ b/drivers/mtd/devices/doc2001plus.c | |||
@@ -6,8 +6,6 @@ | |||
6 | * (c) 1999 Machine Vision Holdings, Inc. | 6 | * (c) 1999 Machine Vision Holdings, Inc. |
7 | * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> | 7 | * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> |
8 | * | 8 | * |
9 | * $Id: doc2001plus.c,v 1.14 2005/11/07 11:14:24 gleixner Exp $ | ||
10 | * | ||
11 | * Released under GPL | 9 | * Released under GPL |
12 | */ | 10 | */ |
13 | 11 | ||
diff --git a/drivers/mtd/devices/docecc.c b/drivers/mtd/devices/docecc.c index fd8a8daba3a8..874e51b110a2 100644 --- a/drivers/mtd/devices/docecc.c +++ b/drivers/mtd/devices/docecc.c | |||
@@ -7,8 +7,6 @@ | |||
7 | * Author: Fabrice Bellard (fabrice.bellard@netgem.com) | 7 | * Author: Fabrice Bellard (fabrice.bellard@netgem.com) |
8 | * Copyright (C) 2000 Netgem S.A. | 8 | * Copyright (C) 2000 Netgem S.A. |
9 | * | 9 | * |
10 | * $Id: docecc.c,v 1.7 2005/11/07 11:14:25 gleixner Exp $ | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
14 | * the Free Software Foundation; either version 2 of the License, or | 12 | * the Free Software Foundation; either version 2 of the License, or |
diff --git a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c index d8cc94ec4e50..6e62922942b1 100644 --- a/drivers/mtd/devices/docprobe.c +++ b/drivers/mtd/devices/docprobe.c | |||
@@ -4,9 +4,6 @@ | |||
4 | /* (C) 1999 Machine Vision Holdings, Inc. */ | 4 | /* (C) 1999 Machine Vision Holdings, Inc. */ |
5 | /* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> */ | 5 | /* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> */ |
6 | 6 | ||
7 | /* $Id: docprobe.c,v 1.46 2005/11/07 11:14:25 gleixner Exp $ */ | ||
8 | |||
9 | |||
10 | 7 | ||
11 | /* DOC_PASSIVE_PROBE: | 8 | /* DOC_PASSIVE_PROBE: |
12 | In order to ensure that the BIOS checksum is correct at boot time, and | 9 | In order to ensure that the BIOS checksum is correct at boot time, and |
@@ -79,8 +76,6 @@ static unsigned long __initdata doc_locations[] = { | |||
79 | 0xe0000, 0xe2000, 0xe4000, 0xe6000, | 76 | 0xe0000, 0xe2000, 0xe4000, 0xe6000, |
80 | 0xe8000, 0xea000, 0xec000, 0xee000, | 77 | 0xe8000, 0xea000, 0xec000, 0xee000, |
81 | #endif /* CONFIG_MTD_DOCPROBE_HIGH */ | 78 | #endif /* CONFIG_MTD_DOCPROBE_HIGH */ |
82 | #elif defined(__PPC__) | ||
83 | 0xe4000000, | ||
84 | #else | 79 | #else |
85 | #warning Unknown architecture for DiskOnChip. No default probe locations defined | 80 | #warning Unknown architecture for DiskOnChip. No default probe locations defined |
86 | #endif | 81 | #endif |
diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index 1d324e5c412d..f4bda4cee495 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c | |||
@@ -2,8 +2,6 @@ | |||
2 | /* | 2 | /* |
3 | * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART. | 3 | * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART. |
4 | * | 4 | * |
5 | * $Id: lart.c,v 1.9 2005/11/07 11:14:25 gleixner Exp $ | ||
6 | * | ||
7 | * Author: Abraham vd Merwe <abraham@2d3d.co.za> | 5 | * Author: Abraham vd Merwe <abraham@2d3d.co.za> |
8 | * | 6 | * |
9 | * Copyright (c) 2001, 2d3D, Inc. | 7 | * Copyright (c) 2001, 2d3D, Inc. |
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index b402269301f6..b35c3333e210 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c | |||
@@ -33,6 +33,7 @@ | |||
33 | /* Flash opcodes. */ | 33 | /* Flash opcodes. */ |
34 | #define OPCODE_WREN 0x06 /* Write enable */ | 34 | #define OPCODE_WREN 0x06 /* Write enable */ |
35 | #define OPCODE_RDSR 0x05 /* Read status register */ | 35 | #define OPCODE_RDSR 0x05 /* Read status register */ |
36 | #define OPCODE_WRSR 0x01 /* Write status register 1 byte */ | ||
36 | #define OPCODE_NORM_READ 0x03 /* Read data bytes (low frequency) */ | 37 | #define OPCODE_NORM_READ 0x03 /* Read data bytes (low frequency) */ |
37 | #define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */ | 38 | #define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */ |
38 | #define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */ | 39 | #define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */ |
@@ -112,6 +113,17 @@ static int read_sr(struct m25p *flash) | |||
112 | return val; | 113 | return val; |
113 | } | 114 | } |
114 | 115 | ||
116 | /* | ||
117 | * Write status register 1 byte | ||
118 | * Returns negative if error occurred. | ||
119 | */ | ||
120 | static int write_sr(struct m25p *flash, u8 val) | ||
121 | { | ||
122 | flash->command[0] = OPCODE_WRSR; | ||
123 | flash->command[1] = val; | ||
124 | |||
125 | return spi_write(flash->spi, flash->command, 2); | ||
126 | } | ||
115 | 127 | ||
116 | /* | 128 | /* |
117 | * Set write enable latch with Write Enable command. | 129 | * Set write enable latch with Write Enable command. |
@@ -589,6 +601,16 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
589 | mutex_init(&flash->lock); | 601 | mutex_init(&flash->lock); |
590 | dev_set_drvdata(&spi->dev, flash); | 602 | dev_set_drvdata(&spi->dev, flash); |
591 | 603 | ||
604 | /* | ||
605 | * Atmel serial flash tend to power up | ||
606 | * with the software protection bits set | ||
607 | */ | ||
608 | |||
609 | if (info->jedec_id >> 16 == 0x1f) { | ||
610 | write_enable(flash); | ||
611 | write_sr(flash, 0); | ||
612 | } | ||
613 | |||
592 | if (data && data->name) | 614 | if (data && data->name) |
593 | flash->mtd.name = data->name; | 615 | flash->mtd.name = data->name; |
594 | else | 616 | else |
diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c index 9cff119a2024..6a9a24a80a6d 100644 --- a/drivers/mtd/devices/ms02-nv.c +++ b/drivers/mtd/devices/ms02-nv.c | |||
@@ -5,8 +5,6 @@ | |||
5 | * modify it under the terms of the GNU General Public License | 5 | * modify it under the terms of the GNU General Public License |
6 | * as published by the Free Software Foundation; either version | 6 | * as published by the Free Software Foundation; either version |
7 | * 2 of the License, or (at your option) any later version. | 7 | * 2 of the License, or (at your option) any later version. |
8 | * | ||
9 | * $Id: ms02-nv.c,v 1.11 2005/11/14 13:41:47 macro Exp $ | ||
10 | */ | 8 | */ |
11 | 9 | ||
12 | #include <linux/init.h> | 10 | #include <linux/init.h> |
diff --git a/drivers/mtd/devices/ms02-nv.h b/drivers/mtd/devices/ms02-nv.h index 8a6eef7cfee3..04deafd3a771 100644 --- a/drivers/mtd/devices/ms02-nv.h +++ b/drivers/mtd/devices/ms02-nv.h | |||
@@ -9,8 +9,6 @@ | |||
9 | * modify it under the terms of the GNU General Public License | 9 | * modify it under the terms of the GNU General Public License |
10 | * as published by the Free Software Foundation; either version | 10 | * as published by the Free Software Foundation; either version |
11 | * 2 of the License, or (at your option) any later version. | 11 | * 2 of the License, or (at your option) any later version. |
12 | * | ||
13 | * $Id: ms02-nv.h,v 1.3 2003/08/19 09:25:36 dwmw2 Exp $ | ||
14 | */ | 12 | */ |
15 | 13 | ||
16 | #include <linux/ioport.h> | 14 | #include <linux/ioport.h> |
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index b35e4813a3a5..54e36bfc2c3b 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c | |||
@@ -82,7 +82,7 @@ | |||
82 | 82 | ||
83 | 83 | ||
84 | struct dataflash { | 84 | struct dataflash { |
85 | u8 command[4]; | 85 | uint8_t command[4]; |
86 | char name[24]; | 86 | char name[24]; |
87 | 87 | ||
88 | unsigned partitioned:1; | 88 | unsigned partitioned:1; |
@@ -150,7 +150,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
150 | struct spi_transfer x = { .tx_dma = 0, }; | 150 | struct spi_transfer x = { .tx_dma = 0, }; |
151 | struct spi_message msg; | 151 | struct spi_message msg; |
152 | unsigned blocksize = priv->page_size << 3; | 152 | unsigned blocksize = priv->page_size << 3; |
153 | u8 *command; | 153 | uint8_t *command; |
154 | 154 | ||
155 | DEBUG(MTD_DEBUG_LEVEL2, "%s: erase addr=0x%x len 0x%x\n", | 155 | DEBUG(MTD_DEBUG_LEVEL2, "%s: erase addr=0x%x len 0x%x\n", |
156 | spi->dev.bus_id, | 156 | spi->dev.bus_id, |
@@ -182,8 +182,8 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
182 | pageaddr = pageaddr << priv->page_offset; | 182 | pageaddr = pageaddr << priv->page_offset; |
183 | 183 | ||
184 | command[0] = do_block ? OP_ERASE_BLOCK : OP_ERASE_PAGE; | 184 | command[0] = do_block ? OP_ERASE_BLOCK : OP_ERASE_PAGE; |
185 | command[1] = (u8)(pageaddr >> 16); | 185 | command[1] = (uint8_t)(pageaddr >> 16); |
186 | command[2] = (u8)(pageaddr >> 8); | 186 | command[2] = (uint8_t)(pageaddr >> 8); |
187 | command[3] = 0; | 187 | command[3] = 0; |
188 | 188 | ||
189 | DEBUG(MTD_DEBUG_LEVEL3, "ERASE %s: (%x) %x %x %x [%i]\n", | 189 | DEBUG(MTD_DEBUG_LEVEL3, "ERASE %s: (%x) %x %x %x [%i]\n", |
@@ -234,7 +234,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
234 | struct spi_transfer x[2] = { { .tx_dma = 0, }, }; | 234 | struct spi_transfer x[2] = { { .tx_dma = 0, }, }; |
235 | struct spi_message msg; | 235 | struct spi_message msg; |
236 | unsigned int addr; | 236 | unsigned int addr; |
237 | u8 *command; | 237 | uint8_t *command; |
238 | int status; | 238 | int status; |
239 | 239 | ||
240 | DEBUG(MTD_DEBUG_LEVEL2, "%s: read 0x%x..0x%x\n", | 240 | DEBUG(MTD_DEBUG_LEVEL2, "%s: read 0x%x..0x%x\n", |
@@ -274,9 +274,9 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
274 | * fewer "don't care" bytes. Both buffers stay unchanged. | 274 | * fewer "don't care" bytes. Both buffers stay unchanged. |
275 | */ | 275 | */ |
276 | command[0] = OP_READ_CONTINUOUS; | 276 | command[0] = OP_READ_CONTINUOUS; |
277 | command[1] = (u8)(addr >> 16); | 277 | command[1] = (uint8_t)(addr >> 16); |
278 | command[2] = (u8)(addr >> 8); | 278 | command[2] = (uint8_t)(addr >> 8); |
279 | command[3] = (u8)(addr >> 0); | 279 | command[3] = (uint8_t)(addr >> 0); |
280 | /* plus 4 "don't care" bytes */ | 280 | /* plus 4 "don't care" bytes */ |
281 | 281 | ||
282 | status = spi_sync(priv->spi, &msg); | 282 | status = spi_sync(priv->spi, &msg); |
@@ -311,7 +311,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
311 | size_t remaining = len; | 311 | size_t remaining = len; |
312 | u_char *writebuf = (u_char *) buf; | 312 | u_char *writebuf = (u_char *) buf; |
313 | int status = -EINVAL; | 313 | int status = -EINVAL; |
314 | u8 *command; | 314 | uint8_t *command; |
315 | 315 | ||
316 | DEBUG(MTD_DEBUG_LEVEL2, "%s: write 0x%x..0x%x\n", | 316 | DEBUG(MTD_DEBUG_LEVEL2, "%s: write 0x%x..0x%x\n", |
317 | spi->dev.bus_id, (unsigned)to, (unsigned)(to + len)); | 317 | spi->dev.bus_id, (unsigned)to, (unsigned)(to + len)); |
@@ -487,7 +487,9 @@ add_dataflash(struct spi_device *spi, char *name, | |||
487 | device->write = dataflash_write; | 487 | device->write = dataflash_write; |
488 | device->priv = priv; | 488 | device->priv = priv; |
489 | 489 | ||
490 | dev_info(&spi->dev, "%s (%d KBytes)\n", name, device->size/1024); | 490 | dev_info(&spi->dev, "%s (%d KBytes) pagesize %d bytes, " |
491 | "erasesize %d bytes\n", name, device->size/1024, | ||
492 | pagesize, pagesize * 8); /* 8 pages = 1 block */ | ||
491 | dev_set_drvdata(&spi->dev, priv); | 493 | dev_set_drvdata(&spi->dev, priv); |
492 | 494 | ||
493 | if (mtd_has_partitions()) { | 495 | if (mtd_has_partitions()) { |
@@ -521,7 +523,7 @@ add_dataflash(struct spi_device *spi, char *name, | |||
521 | * | 523 | * |
522 | * Device Density ID code #Pages PageSize Offset | 524 | * Device Density ID code #Pages PageSize Offset |
523 | * AT45DB011B 1Mbit (128K) xx0011xx (0x0c) 512 264 9 | 525 | * AT45DB011B 1Mbit (128K) xx0011xx (0x0c) 512 264 9 |
524 | * AT45DB021B 2Mbit (256K) xx0101xx (0x14) 1025 264 9 | 526 | * AT45DB021B 2Mbit (256K) xx0101xx (0x14) 1024 264 9 |
525 | * AT45DB041B 4Mbit (512K) xx0111xx (0x1c) 2048 264 9 | 527 | * AT45DB041B 4Mbit (512K) xx0111xx (0x1c) 2048 264 9 |
526 | * AT45DB081B 8Mbit (1M) xx1001xx (0x24) 4096 264 9 | 528 | * AT45DB081B 8Mbit (1M) xx1001xx (0x24) 4096 264 9 |
527 | * AT45DB0161B 16Mbit (2M) xx1011xx (0x2c) 4096 528 10 | 529 | * AT45DB0161B 16Mbit (2M) xx1011xx (0x2c) 4096 528 10 |
@@ -529,9 +531,114 @@ add_dataflash(struct spi_device *spi, char *name, | |||
529 | * AT45DB0642 64Mbit (8M) xx111xxx (0x3c) 8192 1056 11 | 531 | * AT45DB0642 64Mbit (8M) xx111xxx (0x3c) 8192 1056 11 |
530 | * AT45DB1282 128Mbit (16M) xx0100xx (0x10) 16384 1056 11 | 532 | * AT45DB1282 128Mbit (16M) xx0100xx (0x10) 16384 1056 11 |
531 | */ | 533 | */ |
534 | |||
535 | struct flash_info { | ||
536 | char *name; | ||
537 | |||
538 | /* JEDEC id zero means "no ID" (most older chips); otherwise it has | ||
539 | * a high byte of zero plus three data bytes: the manufacturer id, | ||
540 | * then a two byte device id. | ||
541 | */ | ||
542 | uint32_t jedec_id; | ||
543 | |||
544 | /* The size listed here is what works with OPCODE_SE, which isn't | ||
545 | * necessarily called a "sector" by the vendor. | ||
546 | */ | ||
547 | unsigned nr_pages; | ||
548 | uint16_t pagesize; | ||
549 | uint16_t pageoffset; | ||
550 | |||
551 | uint16_t flags; | ||
552 | #define SUP_POW2PS 0x02 | ||
553 | #define IS_POW2PS 0x01 | ||
554 | }; | ||
555 | |||
556 | static struct flash_info __devinitdata dataflash_data [] = { | ||
557 | |||
558 | { "at45db011d", 0x1f2200, 512, 264, 9, SUP_POW2PS}, | ||
559 | { "at45db011d", 0x1f2200, 512, 256, 8, SUP_POW2PS | IS_POW2PS}, | ||
560 | |||
561 | { "at45db021d", 0x1f2300, 1024, 264, 9, SUP_POW2PS}, | ||
562 | { "at45db021d", 0x1f2300, 1024, 256, 8, SUP_POW2PS | IS_POW2PS}, | ||
563 | |||
564 | { "at45db041d", 0x1f2400, 2048, 264, 9, SUP_POW2PS}, | ||
565 | { "at45db041d", 0x1f2400, 2048, 256, 8, SUP_POW2PS | IS_POW2PS}, | ||
566 | |||
567 | { "at45db081d", 0x1f2500, 4096, 264, 9, SUP_POW2PS}, | ||
568 | { "at45db081d", 0x1f2500, 4096, 256, 8, SUP_POW2PS | IS_POW2PS}, | ||
569 | |||
570 | { "at45db161d", 0x1f2600, 4096, 528, 10, SUP_POW2PS}, | ||
571 | { "at45db161d", 0x1f2600, 4096, 512, 9, SUP_POW2PS | IS_POW2PS}, | ||
572 | |||
573 | { "at45db321c", 0x1f2700, 8192, 528, 10, }, | ||
574 | |||
575 | { "at45db321d", 0x1f2701, 8192, 528, 10, SUP_POW2PS}, | ||
576 | { "at45db321d", 0x1f2701, 8192, 512, 9, SUP_POW2PS | IS_POW2PS}, | ||
577 | |||
578 | { "at45db641d", 0x1f2800, 8192, 1056, 11, SUP_POW2PS}, | ||
579 | { "at45db641d", 0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS}, | ||
580 | }; | ||
581 | |||
582 | static struct flash_info *__devinit jedec_probe(struct spi_device *spi) | ||
583 | { | ||
584 | int tmp; | ||
585 | uint8_t code = OP_READ_ID; | ||
586 | uint8_t id[3]; | ||
587 | uint32_t jedec; | ||
588 | struct flash_info *info; | ||
589 | int status; | ||
590 | |||
591 | |||
592 | /* JEDEC also defines an optional "extended device information" | ||
593 | * string for after vendor-specific data, after the three bytes | ||
594 | * we use here. Supporting some chips might require using it. | ||
595 | */ | ||
596 | tmp = spi_write_then_read(spi, &code, 1, id, 3); | ||
597 | if (tmp < 0) { | ||
598 | DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n", | ||
599 | spi->dev.bus_id, tmp); | ||
600 | return NULL; | ||
601 | } | ||
602 | jedec = id[0]; | ||
603 | jedec = jedec << 8; | ||
604 | jedec |= id[1]; | ||
605 | jedec = jedec << 8; | ||
606 | jedec |= id[2]; | ||
607 | |||
608 | for (tmp = 0, info = dataflash_data; | ||
609 | tmp < ARRAY_SIZE(dataflash_data); | ||
610 | tmp++, info++) { | ||
611 | if (info->jedec_id == jedec) { | ||
612 | if (info->flags & SUP_POW2PS) { | ||
613 | status = dataflash_status(spi); | ||
614 | if (status & 0x1) | ||
615 | /* return power of 2 pagesize */ | ||
616 | return ++info; | ||
617 | else | ||
618 | return info; | ||
619 | } | ||
620 | } | ||
621 | } | ||
622 | return NULL; | ||
623 | } | ||
624 | |||
532 | static int __devinit dataflash_probe(struct spi_device *spi) | 625 | static int __devinit dataflash_probe(struct spi_device *spi) |
533 | { | 626 | { |
534 | int status; | 627 | int status; |
628 | struct flash_info *info; | ||
629 | |||
630 | /* | ||
631 | * Try to detect dataflash by JEDEC ID. | ||
632 | * If it succeeds we know we have either a C or D part. | ||
633 | * D will support power of 2 pagesize option. | ||
634 | */ | ||
635 | |||
636 | info = jedec_probe(spi); | ||
637 | |||
638 | if (info != NULL) | ||
639 | return add_dataflash(spi, info->name, info->nr_pages, | ||
640 | info->pagesize, info->pageoffset); | ||
641 | |||
535 | 642 | ||
536 | status = dataflash_status(spi); | 643 | status = dataflash_status(spi); |
537 | if (status <= 0 || status == 0xff) { | 644 | if (status <= 0 || status == 0xff) { |
@@ -551,16 +658,16 @@ static int __devinit dataflash_probe(struct spi_device *spi) | |||
551 | status = add_dataflash(spi, "AT45DB011B", 512, 264, 9); | 658 | status = add_dataflash(spi, "AT45DB011B", 512, 264, 9); |
552 | break; | 659 | break; |
553 | case 0x14: /* 0 1 0 1 x x */ | 660 | case 0x14: /* 0 1 0 1 x x */ |
554 | status = add_dataflash(spi, "AT45DB021B", 1025, 264, 9); | 661 | status = add_dataflash(spi, "AT45DB021B", 1024, 264, 9); |
555 | break; | 662 | break; |
556 | case 0x1c: /* 0 1 1 1 x x */ | 663 | case 0x1c: /* 0 1 1 1 x x */ |
557 | status = add_dataflash(spi, "AT45DB041x", 2048, 264, 9); | 664 | status = add_dataflash(spi, "AT45DB041B", 2048, 264, 9); |
558 | break; | 665 | break; |
559 | case 0x24: /* 1 0 0 1 x x */ | 666 | case 0x24: /* 1 0 0 1 x x */ |
560 | status = add_dataflash(spi, "AT45DB081B", 4096, 264, 9); | 667 | status = add_dataflash(spi, "AT45DB081B", 4096, 264, 9); |
561 | break; | 668 | break; |
562 | case 0x2c: /* 1 0 1 1 x x */ | 669 | case 0x2c: /* 1 0 1 1 x x */ |
563 | status = add_dataflash(spi, "AT45DB161x", 4096, 528, 10); | 670 | status = add_dataflash(spi, "AT45DB161B", 4096, 528, 10); |
564 | break; | 671 | break; |
565 | case 0x34: /* 1 1 0 1 x x */ | 672 | case 0x34: /* 1 1 0 1 x x */ |
566 | status = add_dataflash(spi, "AT45DB321x", 8192, 528, 10); | 673 | status = add_dataflash(spi, "AT45DB321x", 8192, 528, 10); |
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c index 0399be178620..3aaca88847d3 100644 --- a/drivers/mtd/devices/mtdram.c +++ b/drivers/mtd/devices/mtdram.c | |||
@@ -1,6 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * mtdram - a test mtd device | 2 | * mtdram - a test mtd device |
3 | * $Id: mtdram.c,v 1.37 2005/04/21 03:42:11 joern Exp $ | ||
4 | * Author: Alexander Larsson <alex@cendio.se> | 3 | * Author: Alexander Larsson <alex@cendio.se> |
5 | * | 4 | * |
6 | * Copyright (c) 1999 Alexander Larsson <alex@cendio.se> | 5 | * Copyright (c) 1999 Alexander Larsson <alex@cendio.se> |
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index c7987b1c5e01..088fbb7595b5 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /** | 1 | /** |
2 | * $Id: phram.c,v 1.16 2005/11/07 11:14:25 gleixner Exp $ | ||
3 | * | ||
4 | * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de> | 2 | * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de> |
5 | * Copyright (c) 2003-2004 Joern Engel <joern@wh.fh-wedel.de> | 3 | * Copyright (c) 2003-2004 Joern Engel <joern@wh.fh-wedel.de> |
6 | * | 4 | * |
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index bc9981749064..d38bca64bb15 100644 --- a/drivers/mtd/devices/pmc551.c +++ b/drivers/mtd/devices/pmc551.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: pmc551.c,v 1.32 2005/11/07 11:14:25 gleixner Exp $ | ||
3 | * | ||
4 | * PMC551 PCI Mezzanine Ram Device | 2 | * PMC551 PCI Mezzanine Ram Device |
5 | * | 3 | * |
6 | * Author: | 4 | * Author: |
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index cb86db746f28..a425d09f35a0 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c | |||
@@ -1,7 +1,5 @@ | |||
1 | /*====================================================================== | 1 | /*====================================================================== |
2 | 2 | ||
3 | $Id: slram.c,v 1.36 2005/11/07 11:14:25 gleixner Exp $ | ||
4 | |||
5 | This driver provides a method to access memory not used by the kernel | 3 | This driver provides a method to access memory not used by the kernel |
6 | itself (i.e. if the kernel commandline mem=xxx is used). To actually | 4 | itself (i.e. if the kernel commandline mem=xxx is used). To actually |
7 | use slram at least mtdblock or mtdchar is required (for block or | 5 | use slram at least mtdblock or mtdchar is required (for block or |
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index 5c29872184e6..f34f20c78911 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* This version ported to the Linux-MTD system by dwmw2@infradead.org | 1 | /* This version ported to the Linux-MTD system by dwmw2@infradead.org |
2 | * $Id: ftl.c,v 1.59 2005/11/29 14:48:31 gleixner Exp $ | ||
3 | * | 2 | * |
4 | * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br> | 3 | * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br> |
5 | * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups | 4 | * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups |
@@ -1078,8 +1077,6 @@ static struct mtd_blktrans_ops ftl_tr = { | |||
1078 | 1077 | ||
1079 | static int init_ftl(void) | 1078 | static int init_ftl(void) |
1080 | { | 1079 | { |
1081 | DEBUG(0, "$Id: ftl.c,v 1.59 2005/11/29 14:48:31 gleixner Exp $\n"); | ||
1082 | |||
1083 | return register_mtd_blktrans(&ftl_tr); | 1080 | return register_mtd_blktrans(&ftl_tr); |
1084 | } | 1081 | } |
1085 | 1082 | ||
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c index b0e396504e67..c4f9d3378b24 100644 --- a/drivers/mtd/inftlcore.c +++ b/drivers/mtd/inftlcore.c | |||
@@ -7,8 +7,6 @@ | |||
7 | * (c) 1999 Machine Vision Holdings, Inc. | 7 | * (c) 1999 Machine Vision Holdings, Inc. |
8 | * Author: David Woodhouse <dwmw2@infradead.org> | 8 | * Author: David Woodhouse <dwmw2@infradead.org> |
9 | * | 9 | * |
10 | * $Id: inftlcore.c,v 1.19 2005/11/07 11:14:20 gleixner Exp $ | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
14 | * the Free Software Foundation; either version 2 of the License, or | 12 | * the Free Software Foundation; either version 2 of the License, or |
@@ -953,9 +951,6 @@ static struct mtd_blktrans_ops inftl_tr = { | |||
953 | 951 | ||
954 | static int __init init_inftl(void) | 952 | static int __init init_inftl(void) |
955 | { | 953 | { |
956 | printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.19 $, " | ||
957 | "inftlmount.c %s\n", inftlmountrev); | ||
958 | |||
959 | return register_mtd_blktrans(&inftl_tr); | 954 | return register_mtd_blktrans(&inftl_tr); |
960 | } | 955 | } |
961 | 956 | ||
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c index c551d2f0779c..9113628ed1ef 100644 --- a/drivers/mtd/inftlmount.c +++ b/drivers/mtd/inftlmount.c | |||
@@ -8,8 +8,6 @@ | |||
8 | * Author: Fabrice Bellard (fabrice.bellard@netgem.com) | 8 | * Author: Fabrice Bellard (fabrice.bellard@netgem.com) |
9 | * Copyright (C) 2000 Netgem S.A. | 9 | * Copyright (C) 2000 Netgem S.A. |
10 | * | 10 | * |
11 | * $Id: inftlmount.c,v 1.18 2005/11/07 11:14:20 gleixner Exp $ | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
14 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
15 | * the Free Software Foundation; either version 2 of the License, or | 13 | * the Free Software Foundation; either version 2 of the License, or |
@@ -39,8 +37,6 @@ | |||
39 | #include <linux/mtd/inftl.h> | 37 | #include <linux/mtd/inftl.h> |
40 | #include <linux/mtd/compatmac.h> | 38 | #include <linux/mtd/compatmac.h> |
41 | 39 | ||
42 | char inftlmountrev[]="$Revision: 1.18 $"; | ||
43 | |||
44 | /* | 40 | /* |
45 | * find_boot_record: Find the INFTL Media Header and its Spare copy which | 41 | * find_boot_record: Find the INFTL Media Header and its Spare copy which |
46 | * contains the various device information of the INFTL partition and | 42 | * contains the various device information of the INFTL partition and |
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index d2fbc2964523..df8e00bba07b 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
@@ -1,5 +1,4 @@ | |||
1 | # drivers/mtd/maps/Kconfig | 1 | # drivers/mtd/maps/Kconfig |
2 | # $Id: Kconfig,v 1.61 2005/11/07 11:14:26 gleixner Exp $ | ||
3 | 2 | ||
4 | menu "Mapping drivers for chip access" | 3 | menu "Mapping drivers for chip access" |
5 | depends on MTD!=n | 4 | depends on MTD!=n |
@@ -510,6 +509,17 @@ config MTD_PCMCIA_ANONYMOUS | |||
510 | 509 | ||
511 | If unsure, say N. | 510 | If unsure, say N. |
512 | 511 | ||
512 | config MTD_BFIN_ASYNC | ||
513 | tristate "Blackfin BF533-STAMP Flash Chip Support" | ||
514 | depends on BFIN533_STAMP && MTD_CFI | ||
515 | select MTD_PARTITIONS | ||
516 | default y | ||
517 | help | ||
518 | Map driver which allows for simultaneous utilization of | ||
519 | ethernet and CFI parallel flash. | ||
520 | |||
521 | If compiled as a module, it will be called bfin-async-flash. | ||
522 | |||
513 | config MTD_UCLINUX | 523 | config MTD_UCLINUX |
514 | tristate "Generic uClinux RAM/ROM filesystem support" | 524 | tristate "Generic uClinux RAM/ROM filesystem support" |
515 | depends on MTD_PARTITIONS && !MMU | 525 | depends on MTD_PARTITIONS && !MMU |
@@ -539,24 +549,6 @@ config MTD_DMV182 | |||
539 | help | 549 | help |
540 | Map driver for Dy-4 SVME/DMV-182 board. | 550 | Map driver for Dy-4 SVME/DMV-182 board. |
541 | 551 | ||
542 | config MTD_BAST | ||
543 | tristate "Map driver for Simtec BAST (EB2410ITX) or Thorcom VR1000" | ||
544 | depends on ARCH_BAST || MACH_VR1000 | ||
545 | select MTD_PARTITIONS | ||
546 | select MTD_MAP_BANK_WIDTH_16 | ||
547 | select MTD_JEDECPROBE | ||
548 | help | ||
549 | Map driver for NOR flash on the Simtec BAST (EB2410ITX), or the | ||
550 | Thorcom VR1000 | ||
551 | |||
552 | Note, this driver *cannot* over-ride the WP link on the | ||
553 | board, or currently detect the state of the link. | ||
554 | |||
555 | config MTD_BAST_MAXSIZE | ||
556 | int "Maximum size for BAST flash area (MiB)" | ||
557 | depends on MTD_BAST | ||
558 | default "4" | ||
559 | |||
560 | config MTD_SHARP_SL | 552 | config MTD_SHARP_SL |
561 | tristate "ROM mapped on Sharp SL Series" | 553 | tristate "ROM mapped on Sharp SL Series" |
562 | depends on ARCH_PXA | 554 | depends on ARCH_PXA |
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index c6ce8673dab2..6cda6df973e5 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile | |||
@@ -1,7 +1,6 @@ | |||
1 | # | 1 | # |
2 | # linux/drivers/maps/Makefile | 2 | # linux/drivers/maps/Makefile |
3 | # | 3 | # |
4 | # $Id: Makefile.common,v 1.34 2005/11/07 11:14:26 gleixner Exp $ | ||
5 | 4 | ||
6 | ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y) | 5 | ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y) |
7 | obj-$(CONFIG_MTD) += map_funcs.o | 6 | obj-$(CONFIG_MTD) += map_funcs.o |
@@ -10,7 +9,6 @@ endif | |||
10 | # Chip mappings | 9 | # Chip mappings |
11 | obj-$(CONFIG_MTD_CDB89712) += cdb89712.o | 10 | obj-$(CONFIG_MTD_CDB89712) += cdb89712.o |
12 | obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o | 11 | obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o |
13 | obj-$(CONFIG_MTD_BAST) += bast-flash.o | ||
14 | obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o | 12 | obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o |
15 | obj-$(CONFIG_MTD_DC21285) += dc21285.o | 13 | obj-$(CONFIG_MTD_DC21285) += dc21285.o |
16 | obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o | 14 | obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o |
@@ -66,3 +64,4 @@ obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o | |||
66 | obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o | 64 | obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o |
67 | obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o | 65 | obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o |
68 | obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o | 66 | obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o |
67 | obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o | ||
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c index 728aed6ad722..948b86f35ef4 100644 --- a/drivers/mtd/maps/amd76xrom.c +++ b/drivers/mtd/maps/amd76xrom.c | |||
@@ -2,7 +2,6 @@ | |||
2 | * amd76xrom.c | 2 | * amd76xrom.c |
3 | * | 3 | * |
4 | * Normal mappings of chips in physical memory | 4 | * Normal mappings of chips in physical memory |
5 | * $Id: amd76xrom.c,v 1.21 2005/11/07 11:14:26 gleixner Exp $ | ||
6 | */ | 5 | */ |
7 | 6 | ||
8 | #include <linux/module.h> | 7 | #include <linux/module.h> |
diff --git a/drivers/mtd/maps/autcpu12-nvram.c b/drivers/mtd/maps/autcpu12-nvram.c index 7ed3424dd959..cf32267263df 100644 --- a/drivers/mtd/maps/autcpu12-nvram.c +++ b/drivers/mtd/maps/autcpu12-nvram.c | |||
@@ -2,8 +2,6 @@ | |||
2 | * NV-RAM memory access on autcpu12 | 2 | * NV-RAM memory access on autcpu12 |
3 | * (C) 2002 Thomas Gleixner (gleixner@autronix.de) | 3 | * (C) 2002 Thomas Gleixner (gleixner@autronix.de) |
4 | * | 4 | * |
5 | * $Id: autcpu12-nvram.c,v 1.9 2005/11/07 11:14:26 gleixner Exp $ | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2 of the License, or | 7 | * the Free Software Foundation; either version 2 of the License, or |
diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c deleted file mode 100644 index 1f492062f8ca..000000000000 --- a/drivers/mtd/maps/bast-flash.c +++ /dev/null | |||
@@ -1,226 +0,0 @@ | |||
1 | /* linux/drivers/mtd/maps/bast-flash.c | ||
2 | * | ||
3 | * Copyright (c) 2004-2005 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * Simtec Bast (EB2410ITX) NOR MTD Mapping driver | ||
7 | * | ||
8 | * Changelog: | ||
9 | * 20-Sep-2004 BJD Initial version | ||
10 | * 17-Jan-2005 BJD Add whole device if no partitions found | ||
11 | * | ||
12 | * $Id: bast-flash.c,v 1.5 2005/11/07 11:14:26 gleixner Exp $ | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/types.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/kernel.h> | ||
33 | #include <linux/string.h> | ||
34 | #include <linux/ioport.h> | ||
35 | #include <linux/device.h> | ||
36 | #include <linux/slab.h> | ||
37 | #include <linux/platform_device.h> | ||
38 | #include <linux/mtd/mtd.h> | ||
39 | #include <linux/mtd/map.h> | ||
40 | #include <linux/mtd/partitions.h> | ||
41 | |||
42 | #include <asm/io.h> | ||
43 | #include <asm/mach/flash.h> | ||
44 | |||
45 | #include <asm/arch/map.h> | ||
46 | #include <asm/arch/bast-map.h> | ||
47 | #include <asm/arch/bast-cpld.h> | ||
48 | |||
49 | #ifdef CONFIG_MTD_BAST_MAXSIZE | ||
50 | #define AREA_MAXSIZE (CONFIG_MTD_BAST_MAXSIZE * SZ_1M) | ||
51 | #else | ||
52 | #define AREA_MAXSIZE (32 * SZ_1M) | ||
53 | #endif | ||
54 | |||
55 | #define PFX "bast-flash: " | ||
56 | |||
57 | struct bast_flash_info { | ||
58 | struct mtd_info *mtd; | ||
59 | struct map_info map; | ||
60 | struct mtd_partition *partitions; | ||
61 | struct resource *area; | ||
62 | }; | ||
63 | |||
64 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; | ||
65 | |||
66 | static void bast_flash_setrw(int to) | ||
67 | { | ||
68 | unsigned int val; | ||
69 | unsigned long flags; | ||
70 | |||
71 | local_irq_save(flags); | ||
72 | val = __raw_readb(BAST_VA_CTRL3); | ||
73 | |||
74 | if (to) | ||
75 | val |= BAST_CPLD_CTRL3_ROMWEN; | ||
76 | else | ||
77 | val &= ~BAST_CPLD_CTRL3_ROMWEN; | ||
78 | |||
79 | pr_debug("new cpld ctrl3=%02x\n", val); | ||
80 | |||
81 | __raw_writeb(val, BAST_VA_CTRL3); | ||
82 | local_irq_restore(flags); | ||
83 | } | ||
84 | |||
85 | static int bast_flash_remove(struct platform_device *pdev) | ||
86 | { | ||
87 | struct bast_flash_info *info = platform_get_drvdata(pdev); | ||
88 | |||
89 | platform_set_drvdata(pdev, NULL); | ||
90 | |||
91 | if (info == NULL) | ||
92 | return 0; | ||
93 | |||
94 | if (info->map.virt != NULL) | ||
95 | iounmap(info->map.virt); | ||
96 | |||
97 | if (info->mtd) { | ||
98 | del_mtd_partitions(info->mtd); | ||
99 | map_destroy(info->mtd); | ||
100 | } | ||
101 | |||
102 | kfree(info->partitions); | ||
103 | |||
104 | if (info->area) { | ||
105 | release_resource(info->area); | ||
106 | kfree(info->area); | ||
107 | } | ||
108 | |||
109 | kfree(info); | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int bast_flash_probe(struct platform_device *pdev) | ||
115 | { | ||
116 | struct bast_flash_info *info; | ||
117 | struct resource *res; | ||
118 | int err = 0; | ||
119 | |||
120 | info = kmalloc(sizeof(*info), GFP_KERNEL); | ||
121 | if (info == NULL) { | ||
122 | printk(KERN_ERR PFX "no memory for flash info\n"); | ||
123 | err = -ENOMEM; | ||
124 | goto exit_error; | ||
125 | } | ||
126 | |||
127 | memzero(info, sizeof(*info)); | ||
128 | platform_set_drvdata(pdev, info); | ||
129 | |||
130 | res = pdev->resource; /* assume that the flash has one resource */ | ||
131 | |||
132 | info->map.phys = res->start; | ||
133 | info->map.size = res->end - res->start + 1; | ||
134 | info->map.name = pdev->dev.bus_id; | ||
135 | info->map.bankwidth = 2; | ||
136 | |||
137 | if (info->map.size > AREA_MAXSIZE) | ||
138 | info->map.size = AREA_MAXSIZE; | ||
139 | |||
140 | pr_debug("%s: area %08lx, size %ld\n", __func__, | ||
141 | info->map.phys, info->map.size); | ||
142 | |||
143 | info->area = request_mem_region(res->start, info->map.size, | ||
144 | pdev->name); | ||
145 | if (info->area == NULL) { | ||
146 | printk(KERN_ERR PFX "cannot reserve flash memory region\n"); | ||
147 | err = -ENOENT; | ||
148 | goto exit_error; | ||
149 | } | ||
150 | |||
151 | info->map.virt = ioremap(res->start, info->map.size); | ||
152 | pr_debug("%s: virt at %08x\n", __func__, (int)info->map.virt); | ||
153 | |||
154 | if (info->map.virt == 0) { | ||
155 | printk(KERN_ERR PFX "failed to ioremap() region\n"); | ||
156 | err = -EIO; | ||
157 | goto exit_error; | ||
158 | } | ||
159 | |||
160 | simple_map_init(&info->map); | ||
161 | |||
162 | /* enable the write to the flash area */ | ||
163 | |||
164 | bast_flash_setrw(1); | ||
165 | |||
166 | /* probe for the device(s) */ | ||
167 | |||
168 | info->mtd = do_map_probe("jedec_probe", &info->map); | ||
169 | if (info->mtd == NULL) | ||
170 | info->mtd = do_map_probe("cfi_probe", &info->map); | ||
171 | |||
172 | if (info->mtd == NULL) { | ||
173 | printk(KERN_ERR PFX "map_probe() failed\n"); | ||
174 | err = -ENXIO; | ||
175 | goto exit_error; | ||
176 | } | ||
177 | |||
178 | /* mark ourselves as the owner */ | ||
179 | info->mtd->owner = THIS_MODULE; | ||
180 | |||
181 | err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0); | ||
182 | if (err > 0) { | ||
183 | err = add_mtd_partitions(info->mtd, info->partitions, err); | ||
184 | if (err) | ||
185 | printk(KERN_ERR PFX "cannot add/parse partitions\n"); | ||
186 | } else { | ||
187 | err = add_mtd_device(info->mtd); | ||
188 | } | ||
189 | |||
190 | if (err == 0) | ||
191 | return 0; | ||
192 | |||
193 | /* fall through to exit error */ | ||
194 | |||
195 | exit_error: | ||
196 | bast_flash_remove(pdev); | ||
197 | return err; | ||
198 | } | ||
199 | |||
200 | static struct platform_driver bast_flash_driver = { | ||
201 | .probe = bast_flash_probe, | ||
202 | .remove = bast_flash_remove, | ||
203 | .driver = { | ||
204 | .name = "bast-nor", | ||
205 | .owner = THIS_MODULE, | ||
206 | }, | ||
207 | }; | ||
208 | |||
209 | static int __init bast_flash_init(void) | ||
210 | { | ||
211 | printk("BAST NOR-Flash Driver, (c) 2004 Simtec Electronics\n"); | ||
212 | return platform_driver_register(&bast_flash_driver); | ||
213 | } | ||
214 | |||
215 | static void __exit bast_flash_exit(void) | ||
216 | { | ||
217 | platform_driver_unregister(&bast_flash_driver); | ||
218 | } | ||
219 | |||
220 | module_init(bast_flash_init); | ||
221 | module_exit(bast_flash_exit); | ||
222 | |||
223 | MODULE_LICENSE("GPL"); | ||
224 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | ||
225 | MODULE_DESCRIPTION("BAST MTD Map driver"); | ||
226 | MODULE_ALIAS("platform:bast-nor"); | ||
diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c new file mode 100644 index 000000000000..6fec86aaed7e --- /dev/null +++ b/drivers/mtd/maps/bfin-async-flash.c | |||
@@ -0,0 +1,219 @@ | |||
1 | /* | ||
2 | * drivers/mtd/maps/bfin-async-flash.c | ||
3 | * | ||
4 | * Handle the case where flash memory and ethernet mac/phy are | ||
5 | * mapped onto the same async bank. The BF533-STAMP does this | ||
6 | * for example. All board-specific configuration goes in your | ||
7 | * board resources file. | ||
8 | * | ||
9 | * Copyright 2000 Nicolas Pitre <nico@cam.org> | ||
10 | * Copyright 2005-2008 Analog Devices Inc. | ||
11 | * | ||
12 | * Enter bugs at http://blackfin.uclinux.org/ | ||
13 | * | ||
14 | * Licensed under the GPL-2 or later. | ||
15 | */ | ||
16 | |||
17 | #include <linux/init.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/mtd/mtd.h> | ||
21 | #include <linux/mtd/map.h> | ||
22 | #include <linux/mtd/partitions.h> | ||
23 | #include <linux/mtd/physmap.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/types.h> | ||
26 | |||
27 | #include <asm/blackfin.h> | ||
28 | #include <linux/gpio.h> | ||
29 | #include <linux/io.h> | ||
30 | #include <asm/unaligned.h> | ||
31 | |||
32 | #define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); }) | ||
33 | |||
34 | #define DRIVER_NAME "bfin-async-flash" | ||
35 | |||
36 | struct async_state { | ||
37 | struct mtd_info *mtd; | ||
38 | struct map_info map; | ||
39 | int enet_flash_pin; | ||
40 | uint32_t flash_ambctl0, flash_ambctl1; | ||
41 | uint32_t save_ambctl0, save_ambctl1; | ||
42 | unsigned long irq_flags; | ||
43 | }; | ||
44 | |||
45 | static void switch_to_flash(struct async_state *state) | ||
46 | { | ||
47 | local_irq_save(state->irq_flags); | ||
48 | |||
49 | gpio_set_value(state->enet_flash_pin, 0); | ||
50 | |||
51 | state->save_ambctl0 = bfin_read_EBIU_AMBCTL0(); | ||
52 | state->save_ambctl1 = bfin_read_EBIU_AMBCTL1(); | ||
53 | bfin_write_EBIU_AMBCTL0(state->flash_ambctl0); | ||
54 | bfin_write_EBIU_AMBCTL1(state->flash_ambctl1); | ||
55 | SSYNC(); | ||
56 | } | ||
57 | |||
58 | static void switch_back(struct async_state *state) | ||
59 | { | ||
60 | bfin_write_EBIU_AMBCTL0(state->save_ambctl0); | ||
61 | bfin_write_EBIU_AMBCTL1(state->save_ambctl1); | ||
62 | SSYNC(); | ||
63 | |||
64 | gpio_set_value(state->enet_flash_pin, 1); | ||
65 | |||
66 | local_irq_restore(state->irq_flags); | ||
67 | } | ||
68 | |||
69 | static map_word bfin_read(struct map_info *map, unsigned long ofs) | ||
70 | { | ||
71 | struct async_state *state = (struct async_state *)map->map_priv_1; | ||
72 | uint16_t word; | ||
73 | map_word test; | ||
74 | |||
75 | switch_to_flash(state); | ||
76 | |||
77 | word = readw(map->virt + ofs); | ||
78 | |||
79 | switch_back(state); | ||
80 | |||
81 | test.x[0] = word; | ||
82 | return test; | ||
83 | } | ||
84 | |||
85 | static void bfin_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) | ||
86 | { | ||
87 | struct async_state *state = (struct async_state *)map->map_priv_1; | ||
88 | |||
89 | switch_to_flash(state); | ||
90 | |||
91 | memcpy(to, map->virt + from, len); | ||
92 | |||
93 | switch_back(state); | ||
94 | } | ||
95 | |||
96 | static void bfin_write(struct map_info *map, map_word d1, unsigned long ofs) | ||
97 | { | ||
98 | struct async_state *state = (struct async_state *)map->map_priv_1; | ||
99 | uint16_t d; | ||
100 | |||
101 | d = d1.x[0]; | ||
102 | |||
103 | switch_to_flash(state); | ||
104 | |||
105 | writew(d, map->virt + ofs); | ||
106 | SSYNC(); | ||
107 | |||
108 | switch_back(state); | ||
109 | } | ||
110 | |||
111 | static void bfin_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) | ||
112 | { | ||
113 | struct async_state *state = (struct async_state *)map->map_priv_1; | ||
114 | |||
115 | switch_to_flash(state); | ||
116 | |||
117 | memcpy(map->virt + to, from, len); | ||
118 | SSYNC(); | ||
119 | |||
120 | switch_back(state); | ||
121 | } | ||
122 | |||
123 | #ifdef CONFIG_MTD_PARTITIONS | ||
124 | static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; | ||
125 | #endif | ||
126 | |||
127 | static int __devinit bfin_flash_probe(struct platform_device *pdev) | ||
128 | { | ||
129 | int ret; | ||
130 | struct physmap_flash_data *pdata = pdev->dev.platform_data; | ||
131 | struct resource *memory = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
132 | struct resource *flash_ambctl = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
133 | struct async_state *state; | ||
134 | |||
135 | state = kzalloc(sizeof(*state), GFP_KERNEL); | ||
136 | if (!state) | ||
137 | return -ENOMEM; | ||
138 | |||
139 | state->map.name = DRIVER_NAME; | ||
140 | state->map.read = bfin_read; | ||
141 | state->map.copy_from = bfin_copy_from; | ||
142 | state->map.write = bfin_write; | ||
143 | state->map.copy_to = bfin_copy_to; | ||
144 | state->map.bankwidth = pdata->width; | ||
145 | state->map.size = memory->end - memory->start + 1; | ||
146 | state->map.virt = (void __iomem *)memory->start; | ||
147 | state->map.phys = memory->start; | ||
148 | state->map.map_priv_1 = (unsigned long)state; | ||
149 | state->enet_flash_pin = platform_get_irq(pdev, 0); | ||
150 | state->flash_ambctl0 = flash_ambctl->start; | ||
151 | state->flash_ambctl1 = flash_ambctl->end; | ||
152 | |||
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); | ||
155 | return -EBUSY; | ||
156 | } | ||
157 | gpio_direction_output(state->enet_flash_pin, 1); | ||
158 | |||
159 | 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 | if (!state->mtd) | ||
162 | return -ENXIO; | ||
163 | |||
164 | #ifdef CONFIG_MTD_PARTITIONS | ||
165 | ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0); | ||
166 | if (ret > 0) { | ||
167 | pr_devinit(KERN_NOTICE DRIVER_NAME ": Using commandline partition definition\n"); | ||
168 | add_mtd_partitions(state->mtd, pdata->parts, ret); | ||
169 | |||
170 | } else if (pdata->nr_parts) { | ||
171 | pr_devinit(KERN_NOTICE DRIVER_NAME ": Using board partition definition\n"); | ||
172 | add_mtd_partitions(state->mtd, pdata->parts, pdata->nr_parts); | ||
173 | |||
174 | } else | ||
175 | #endif | ||
176 | { | ||
177 | pr_devinit(KERN_NOTICE DRIVER_NAME ": no partition info available, registering whole flash at once\n"); | ||
178 | add_mtd_device(state->mtd); | ||
179 | } | ||
180 | |||
181 | platform_set_drvdata(pdev, state); | ||
182 | |||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | static int __devexit bfin_flash_remove(struct platform_device *pdev) | ||
187 | { | ||
188 | struct async_state *state = platform_get_drvdata(pdev); | ||
189 | gpio_free(state->enet_flash_pin); | ||
190 | #ifdef CONFIG_MTD_PARTITIONS | ||
191 | del_mtd_partitions(state->mtd); | ||
192 | #endif | ||
193 | map_destroy(state->mtd); | ||
194 | kfree(state); | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static struct platform_driver bfin_flash_driver = { | ||
199 | .probe = bfin_flash_probe, | ||
200 | .remove = __devexit_p(bfin_flash_remove), | ||
201 | .driver = { | ||
202 | .name = DRIVER_NAME, | ||
203 | }, | ||
204 | }; | ||
205 | |||
206 | static int __init bfin_flash_init(void) | ||
207 | { | ||
208 | return platform_driver_register(&bfin_flash_driver); | ||
209 | } | ||
210 | module_init(bfin_flash_init); | ||
211 | |||
212 | static void __exit bfin_flash_exit(void) | ||
213 | { | ||
214 | platform_driver_unregister(&bfin_flash_driver); | ||
215 | } | ||
216 | module_exit(bfin_flash_exit); | ||
217 | |||
218 | MODULE_LICENSE("GPL"); | ||
219 | MODULE_DESCRIPTION("MTD map driver for Blackfins with flash/ethernet on same async bank"); | ||
diff --git a/drivers/mtd/maps/cdb89712.c b/drivers/mtd/maps/cdb89712.c index 9f17bb6c5a9d..cb507da0a87d 100644 --- a/drivers/mtd/maps/cdb89712.c +++ b/drivers/mtd/maps/cdb89712.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Flash on Cirrus CDB89712 | 2 | * Flash on Cirrus CDB89712 |
3 | * | 3 | * |
4 | * $Id: cdb89712.c,v 1.11 2005/11/07 11:14:26 gleixner Exp $ | ||
5 | */ | 4 | */ |
6 | 5 | ||
7 | #include <linux/module.h> | 6 | #include <linux/module.h> |
diff --git a/drivers/mtd/maps/ceiva.c b/drivers/mtd/maps/ceiva.c index 629e6e2641a8..6464d487eb1a 100644 --- a/drivers/mtd/maps/ceiva.c +++ b/drivers/mtd/maps/ceiva.c | |||
@@ -11,7 +11,6 @@ | |||
11 | * | 11 | * |
12 | * (C) 2000 Nicolas Pitre <nico@cam.org> | 12 | * (C) 2000 Nicolas Pitre <nico@cam.org> |
13 | * | 13 | * |
14 | * $Id: ceiva.c,v 1.11 2004/09/16 23:27:12 gleixner Exp $ | ||
15 | */ | 14 | */ |
16 | 15 | ||
17 | #include <linux/module.h> | 16 | #include <linux/module.h> |
diff --git a/drivers/mtd/maps/cfi_flagadm.c b/drivers/mtd/maps/cfi_flagadm.c index 65e5ee552010..0ecc3f6d735b 100644 --- a/drivers/mtd/maps/cfi_flagadm.c +++ b/drivers/mtd/maps/cfi_flagadm.c | |||
@@ -1,8 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright © 2001 Flaga hf. Medical Devices, Kári DavÃðsson <kd@flaga.is> | 2 | * Copyright © 2001 Flaga hf. Medical Devices, Kári DavÃðsson <kd@flaga.is> |
3 | * | 3 | * |
4 | * $Id: cfi_flagadm.c,v 1.15 2005/11/07 11:14:26 gleixner Exp $ | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License as published by the | 5 | * under the terms of the GNU General Public License as published by the |
8 | * Free Software Foundation; either version 2 of the License, or (at your | 6 | * Free Software Foundation; either version 2 of the License, or (at your |
diff --git a/drivers/mtd/maps/dbox2-flash.c b/drivers/mtd/maps/dbox2-flash.c index 92a9c7fac993..e115667bf1d0 100644 --- a/drivers/mtd/maps/dbox2-flash.c +++ b/drivers/mtd/maps/dbox2-flash.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: dbox2-flash.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $ | ||
3 | * | ||
4 | * D-Box 2 flash driver | 2 | * D-Box 2 flash driver |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/mtd/maps/dc21285.c b/drivers/mtd/maps/dc21285.c index b32bb9347d71..3aa018c092f8 100644 --- a/drivers/mtd/maps/dc21285.c +++ b/drivers/mtd/maps/dc21285.c | |||
@@ -4,8 +4,6 @@ | |||
4 | * (C) 2000 Nicolas Pitre <nico@cam.org> | 4 | * (C) 2000 Nicolas Pitre <nico@cam.org> |
5 | * | 5 | * |
6 | * This code is GPL | 6 | * This code is GPL |
7 | * | ||
8 | * $Id: dc21285.c,v 1.24 2005/11/07 11:14:26 gleixner Exp $ | ||
9 | */ | 7 | */ |
10 | #include <linux/module.h> | 8 | #include <linux/module.h> |
11 | #include <linux/types.h> | 9 | #include <linux/types.h> |
diff --git a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c index 1c3b34ad7325..0713e3a5a22c 100644 --- a/drivers/mtd/maps/dilnetpc.c +++ b/drivers/mtd/maps/dilnetpc.c | |||
@@ -14,8 +14,6 @@ | |||
14 | * along with this program; if not, write to the Free Software | 14 | * along with this program; if not, write to the Free Software |
15 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | 15 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
16 | * | 16 | * |
17 | * $Id: dilnetpc.c,v 1.20 2005/11/07 11:14:26 gleixner Exp $ | ||
18 | * | ||
19 | * The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems | 17 | * The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems |
20 | * featuring the AMD Elan SC410 processor. There are two variants of this | 18 | * featuring the AMD Elan SC410 processor. There are two variants of this |
21 | * board: DNP/1486 and ADNP/1486. The DNP version has 2 megs of flash | 19 | * board: DNP/1486 and ADNP/1486. The DNP version has 2 megs of flash |
diff --git a/drivers/mtd/maps/dmv182.c b/drivers/mtd/maps/dmv182.c index e0558b0b2fe6..d171674eb2ed 100644 --- a/drivers/mtd/maps/dmv182.c +++ b/drivers/mtd/maps/dmv182.c | |||
@@ -4,8 +4,6 @@ | |||
4 | * | 4 | * |
5 | * Flash map driver for the Dy4 SVME182 board | 5 | * Flash map driver for the Dy4 SVME182 board |
6 | * | 6 | * |
7 | * $Id: dmv182.c,v 1.6 2005/11/07 11:14:26 gleixner Exp $ | ||
8 | * | ||
9 | * Copyright 2003-2004, TimeSys Corporation | 7 | * Copyright 2003-2004, TimeSys Corporation |
10 | * | 8 | * |
11 | * Based on the SVME181 flash map, by Tom Nelson, Dot4, Inc. for TimeSys Corp. | 9 | * Based on the SVME181 flash map, by Tom Nelson, Dot4, Inc. for TimeSys Corp. |
diff --git a/drivers/mtd/maps/ebony.c b/drivers/mtd/maps/ebony.c index 1488bb92f26f..d92b7c70d3ed 100644 --- a/drivers/mtd/maps/ebony.c +++ b/drivers/mtd/maps/ebony.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: ebony.c,v 1.16 2005/11/07 11:14:26 gleixner Exp $ | ||
3 | * | ||
4 | * Mapping for Ebony user flash | 2 | * Mapping for Ebony user flash |
5 | * | 3 | * |
6 | * Matt Porter <mporter@kernel.crashing.org> | 4 | * Matt Porter <mporter@kernel.crashing.org> |
diff --git a/drivers/mtd/maps/edb7312.c b/drivers/mtd/maps/edb7312.c index 1c5b97c89685..9433738c1664 100644 --- a/drivers/mtd/maps/edb7312.c +++ b/drivers/mtd/maps/edb7312.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: edb7312.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $ | ||
3 | * | ||
4 | * Handle mapping of the NOR flash on Cogent EDB7312 boards | 2 | * Handle mapping of the NOR flash on Cogent EDB7312 boards |
5 | * | 3 | * |
6 | * Copyright 2002 SYSGO Real-Time Solutions GmbH | 4 | * Copyright 2002 SYSGO Real-Time Solutions GmbH |
diff --git a/drivers/mtd/maps/fortunet.c b/drivers/mtd/maps/fortunet.c index 7c50c271651c..a8e3fde4cbd5 100644 --- a/drivers/mtd/maps/fortunet.c +++ b/drivers/mtd/maps/fortunet.c | |||
@@ -1,6 +1,5 @@ | |||
1 | /* fortunet.c memory map | 1 | /* fortunet.c memory map |
2 | * | 2 | * |
3 | * $Id: fortunet.c,v 1.11 2005/11/07 11:14:27 gleixner Exp $ | ||
4 | */ | 3 | */ |
5 | 4 | ||
6 | #include <linux/module.h> | 5 | #include <linux/module.h> |
diff --git a/drivers/mtd/maps/h720x-flash.c b/drivers/mtd/maps/h720x-flash.c index 6dde3182d64a..ef8915474462 100644 --- a/drivers/mtd/maps/h720x-flash.c +++ b/drivers/mtd/maps/h720x-flash.c | |||
@@ -2,8 +2,6 @@ | |||
2 | * Flash memory access on Hynix GMS30C7201/HMS30C7202 based | 2 | * Flash memory access on Hynix GMS30C7201/HMS30C7202 based |
3 | * evaluation boards | 3 | * evaluation boards |
4 | * | 4 | * |
5 | * $Id: h720x-flash.c,v 1.12 2005/11/07 11:14:27 gleixner Exp $ | ||
6 | * | ||
7 | * (C) 2002 Jungjun Kim <jungjun.kim@hynix.com> | 5 | * (C) 2002 Jungjun Kim <jungjun.kim@hynix.com> |
8 | * 2003 Thomas Gleixner <tglx@linutronix.de> | 6 | * 2003 Thomas Gleixner <tglx@linutronix.de> |
9 | */ | 7 | */ |
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c index 2c884c49e84a..aeb6c916e23f 100644 --- a/drivers/mtd/maps/ichxrom.c +++ b/drivers/mtd/maps/ichxrom.c | |||
@@ -2,7 +2,6 @@ | |||
2 | * ichxrom.c | 2 | * ichxrom.c |
3 | * | 3 | * |
4 | * Normal mappings of chips in physical memory | 4 | * Normal mappings of chips in physical memory |
5 | * $Id: ichxrom.c,v 1.19 2005/11/07 11:14:27 gleixner Exp $ | ||
6 | */ | 5 | */ |
7 | 6 | ||
8 | #include <linux/module.h> | 7 | #include <linux/module.h> |
diff --git a/drivers/mtd/maps/impa7.c b/drivers/mtd/maps/impa7.c index a0b4dc7155dc..2682ab51a367 100644 --- a/drivers/mtd/maps/impa7.c +++ b/drivers/mtd/maps/impa7.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: impa7.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $ | ||
3 | * | ||
4 | * Handle mapping of the NOR flash on implementa A7 boards | 2 | * Handle mapping of the NOR flash on implementa A7 boards |
5 | * | 3 | * |
6 | * Copyright 2002 SYSGO Real-Time Solutions GmbH | 4 | * Copyright 2002 SYSGO Real-Time Solutions GmbH |
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c index 325c8880c437..ee361aaadb1e 100644 --- a/drivers/mtd/maps/integrator-flash.c +++ b/drivers/mtd/maps/integrator-flash.c | |||
@@ -22,8 +22,6 @@ | |||
22 | This is access code for flashes using ARM's flash partitioning | 22 | This is access code for flashes using ARM's flash partitioning |
23 | standards. | 23 | standards. |
24 | 24 | ||
25 | $Id: integrator-flash.c,v 1.20 2005/11/07 11:14:27 gleixner Exp $ | ||
26 | |||
27 | ======================================================================*/ | 25 | ======================================================================*/ |
28 | 26 | ||
29 | #include <linux/module.h> | 27 | #include <linux/module.h> |
diff --git a/drivers/mtd/maps/ipaq-flash.c b/drivers/mtd/maps/ipaq-flash.c index f27c132794c3..a806119797e0 100644 --- a/drivers/mtd/maps/ipaq-flash.c +++ b/drivers/mtd/maps/ipaq-flash.c | |||
@@ -4,8 +4,6 @@ | |||
4 | * (C) 2000 Nicolas Pitre <nico@cam.org> | 4 | * (C) 2000 Nicolas Pitre <nico@cam.org> |
5 | * (C) 2002 Hewlett-Packard Company <jamey.hicks@hp.com> | 5 | * (C) 2002 Hewlett-Packard Company <jamey.hicks@hp.com> |
6 | * (C) 2003 Christian Pellegrin <chri@ascensit.com>, <chri@infis.univ.ts.it>: concatenation of multiple flashes | 6 | * (C) 2003 Christian Pellegrin <chri@ascensit.com>, <chri@infis.univ.ts.it>: concatenation of multiple flashes |
7 | * | ||
8 | * $Id: ipaq-flash.c,v 1.5 2005/11/07 11:14:27 gleixner Exp $ | ||
9 | */ | 7 | */ |
10 | 8 | ||
11 | #include <linux/module.h> | 9 | #include <linux/module.h> |
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c index c8396b8574c4..c2264792a20b 100644 --- a/drivers/mtd/maps/ixp2000.c +++ b/drivers/mtd/maps/ixp2000.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: ixp2000.c,v 1.9 2005/11/07 11:14:27 gleixner Exp $ | ||
3 | * | ||
4 | * drivers/mtd/maps/ixp2000.c | 2 | * drivers/mtd/maps/ixp2000.c |
5 | * | 3 | * |
6 | * Mapping for the Intel XScale IXP2000 based systems | 4 | * Mapping for the Intel XScale IXP2000 based systems |
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c index 01f19a4714b5..9c7a5fbd4e51 100644 --- a/drivers/mtd/maps/ixp4xx.c +++ b/drivers/mtd/maps/ixp4xx.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: ixp4xx.c,v 1.13 2005/11/16 16:23:21 dvrabel Exp $ | ||
3 | * | ||
4 | * drivers/mtd/maps/ixp4xx.c | 2 | * drivers/mtd/maps/ixp4xx.c |
5 | * | 3 | * |
6 | * MTD Map file for IXP4XX based systems. Please do not make per-board | 4 | * MTD Map file for IXP4XX based systems. Please do not make per-board |
diff --git a/drivers/mtd/maps/l440gx.c b/drivers/mtd/maps/l440gx.c index 67620adf4811..9e054503c4cf 100644 --- a/drivers/mtd/maps/l440gx.c +++ b/drivers/mtd/maps/l440gx.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: l440gx.c,v 1.18 2005/11/07 11:14:27 gleixner Exp $ | ||
3 | * | ||
4 | * BIOS Flash chip on Intel 440GX board. | 2 | * BIOS Flash chip on Intel 440GX board. |
5 | * | 3 | * |
6 | * Bugs this currently does not work under linuxBIOS. | 4 | * Bugs this currently does not work under linuxBIOS. |
diff --git a/drivers/mtd/maps/map_funcs.c b/drivers/mtd/maps/map_funcs.c index 9105e6ca0aa6..3f268370eeca 100644 --- a/drivers/mtd/maps/map_funcs.c +++ b/drivers/mtd/maps/map_funcs.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: map_funcs.c,v 1.10 2005/06/06 23:04:36 tpoynor Exp $ | ||
3 | * | ||
4 | * Out-of-line map I/O functions for simple maps when CONFIG_COMPLEX_MAPPINGS | 2 | * Out-of-line map I/O functions for simple maps when CONFIG_COMPLEX_MAPPINGS |
5 | * is enabled. | 3 | * is enabled. |
6 | */ | 4 | */ |
diff --git a/drivers/mtd/maps/mbx860.c b/drivers/mtd/maps/mbx860.c index 06b118727846..706f67394b07 100644 --- a/drivers/mtd/maps/mbx860.c +++ b/drivers/mtd/maps/mbx860.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: mbx860.c,v 1.9 2005/11/07 11:14:27 gleixner Exp $ | ||
3 | * | ||
4 | * Handle mapping of the flash on MBX860 boards | 2 | * Handle mapping of the flash on MBX860 boards |
5 | * | 3 | * |
6 | * Author: Anton Todorov | 4 | * Author: Anton Todorov |
diff --git a/drivers/mtd/maps/netsc520.c b/drivers/mtd/maps/netsc520.c index 95dcab2146ad..c0cb319b2b70 100644 --- a/drivers/mtd/maps/netsc520.c +++ b/drivers/mtd/maps/netsc520.c | |||
@@ -3,8 +3,6 @@ | |||
3 | * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com) | 3 | * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com) |
4 | * based on sc520cdp.c by Sysgo Real-Time Solutions GmbH | 4 | * based on sc520cdp.c by Sysgo Real-Time Solutions GmbH |
5 | * | 5 | * |
6 | * $Id: netsc520.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c index 0c9b305a72e0..965e6c6d6ab0 100644 --- a/drivers/mtd/maps/nettel.c +++ b/drivers/mtd/maps/nettel.c | |||
@@ -5,8 +5,6 @@ | |||
5 | * | 5 | * |
6 | * (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com) | 6 | * (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com) |
7 | * (C) Copyright 2001-2002, SnapGear (www.snapgear.com) | 7 | * (C) Copyright 2001-2002, SnapGear (www.snapgear.com) |
8 | * | ||
9 | * $Id: nettel.c,v 1.12 2005/11/29 14:30:00 gleixner Exp $ | ||
10 | */ | 8 | */ |
11 | 9 | ||
12 | /****************************************************************************/ | 10 | /****************************************************************************/ |
diff --git a/drivers/mtd/maps/octagon-5066.c b/drivers/mtd/maps/octagon-5066.c index a6642db3d325..43e04c1d22a9 100644 --- a/drivers/mtd/maps/octagon-5066.c +++ b/drivers/mtd/maps/octagon-5066.c | |||
@@ -1,4 +1,3 @@ | |||
1 | // $Id: octagon-5066.c,v 1.28 2005/11/07 11:14:27 gleixner Exp $ | ||
2 | /* ###################################################################### | 1 | /* ###################################################################### |
3 | 2 | ||
4 | Octagon 5066 MTD Driver. | 3 | Octagon 5066 MTD Driver. |
diff --git a/drivers/mtd/maps/omap-toto-flash.c b/drivers/mtd/maps/omap-toto-flash.c index e6e391efbeb6..0a60ebbc2175 100644 --- a/drivers/mtd/maps/omap-toto-flash.c +++ b/drivers/mtd/maps/omap-toto-flash.c | |||
@@ -4,8 +4,6 @@ | |||
4 | * jzhang@ti.com (C) 2003 Texas Instruments. | 4 | * jzhang@ti.com (C) 2003 Texas Instruments. |
5 | * | 5 | * |
6 | * (C) 2002 MontVista Software, Inc. | 6 | * (C) 2002 MontVista Software, Inc. |
7 | * | ||
8 | * $Id: omap-toto-flash.c,v 1.5 2005/11/07 11:14:27 gleixner Exp $ | ||
9 | */ | 7 | */ |
10 | 8 | ||
11 | #include <linux/module.h> | 9 | #include <linux/module.h> |
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c index d2ab1bae9c34..5c6a25c90380 100644 --- a/drivers/mtd/maps/pci.c +++ b/drivers/mtd/maps/pci.c | |||
@@ -7,8 +7,6 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * $Id: pci.c,v 1.14 2005/11/17 08:20:27 dwmw2 Exp $ | ||
11 | * | ||
12 | * Generic PCI memory map driver. We support the following boards: | 10 | * Generic PCI memory map driver. We support the following boards: |
13 | * - Intel IQ80310 ATU. | 11 | * - Intel IQ80310 ATU. |
14 | * - Intel EBSA285 (blank rom programming mode). Tested working 27/09/2001 | 12 | * - Intel EBSA285 (blank rom programming mode). Tested working 27/09/2001 |
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index 0cc31675aeb9..90924fb00481 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: pcmciamtd.c,v 1.55 2005/11/07 11:14:28 gleixner Exp $ | ||
3 | * | ||
4 | * pcmciamtd.c - MTD driver for PCMCIA flash memory cards | 2 | * pcmciamtd.c - MTD driver for PCMCIA flash memory cards |
5 | * | 3 | * |
6 | * Author: Simon Evans <spse@secret.org.uk> | 4 | * Author: Simon Evans <spse@secret.org.uk> |
@@ -48,7 +46,6 @@ static const int debug = 0; | |||
48 | 46 | ||
49 | 47 | ||
50 | #define DRIVER_DESC "PCMCIA Flash memory card driver" | 48 | #define DRIVER_DESC "PCMCIA Flash memory card driver" |
51 | #define DRIVER_VERSION "$Revision: 1.55 $" | ||
52 | 49 | ||
53 | /* Size of the PCMCIA address space: 26 bits = 64 MB */ | 50 | /* Size of the PCMCIA address space: 26 bits = 64 MB */ |
54 | #define MAX_PCMCIA_ADDR 0x4000000 | 51 | #define MAX_PCMCIA_ADDR 0x4000000 |
@@ -785,7 +782,7 @@ static struct pcmcia_driver pcmciamtd_driver = { | |||
785 | 782 | ||
786 | static int __init init_pcmciamtd(void) | 783 | static int __init init_pcmciamtd(void) |
787 | { | 784 | { |
788 | info(DRIVER_DESC " " DRIVER_VERSION); | 785 | info(DRIVER_DESC); |
789 | 786 | ||
790 | if(bankwidth && bankwidth != 1 && bankwidth != 2) { | 787 | if(bankwidth && bankwidth != 1 && bankwidth != 2) { |
791 | info("bad bankwidth (%d), using default", bankwidth); | 788 | info("bad bankwidth (%d), using default", bankwidth); |
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 183255fcfdcb..42d844f8f6bf 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: physmap.c,v 1.39 2005/11/29 14:49:36 gleixner Exp $ | ||
3 | * | ||
4 | * Normal mappings of chips in physical memory | 2 | * Normal mappings of chips in physical memory |
5 | * | 3 | * |
6 | * Copyright (C) 2003 MontaVista Software Inc. | 4 | * Copyright (C) 2003 MontaVista Software Inc. |
@@ -203,7 +201,19 @@ static int physmap_flash_suspend(struct platform_device *dev, pm_message_t state | |||
203 | int i; | 201 | int i; |
204 | 202 | ||
205 | for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++) | 203 | for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++) |
206 | ret |= info->mtd[i]->suspend(info->mtd[i]); | 204 | if (info->mtd[i]->suspend) { |
205 | ret = info->mtd[i]->suspend(info->mtd[i]); | ||
206 | if (ret) | ||
207 | goto fail; | ||
208 | } | ||
209 | |||
210 | return 0; | ||
211 | fail: | ||
212 | for (--i; i >= 0; --i) | ||
213 | if (info->mtd[i]->suspend) { | ||
214 | BUG_ON(!info->mtd[i]->resume); | ||
215 | info->mtd[i]->resume(info->mtd[i]); | ||
216 | } | ||
207 | 217 | ||
208 | return ret; | 218 | return ret; |
209 | } | 219 | } |
@@ -214,7 +224,8 @@ static int physmap_flash_resume(struct platform_device *dev) | |||
214 | int i; | 224 | int i; |
215 | 225 | ||
216 | for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++) | 226 | for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++) |
217 | info->mtd[i]->resume(info->mtd[i]); | 227 | if (info->mtd[i]->resume) |
228 | info->mtd[i]->resume(info->mtd[i]); | ||
218 | 229 | ||
219 | return 0; | 230 | return 0; |
220 | } | 231 | } |
@@ -225,8 +236,9 @@ static void physmap_flash_shutdown(struct platform_device *dev) | |||
225 | int i; | 236 | int i; |
226 | 237 | ||
227 | for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++) | 238 | for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++) |
228 | if (info->mtd[i]->suspend(info->mtd[i]) == 0) | 239 | if (info->mtd[i]->suspend && info->mtd[i]->resume) |
229 | info->mtd[i]->resume(info->mtd[i]); | 240 | if (info->mtd[i]->suspend(info->mtd[i]) == 0) |
241 | info->mtd[i]->resume(info->mtd[i]); | ||
230 | } | 242 | } |
231 | #else | 243 | #else |
232 | #define physmap_flash_suspend NULL | 244 | #define physmap_flash_suspend NULL |
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c index 3eb2643b2328..e7dd9c8a965e 100644 --- a/drivers/mtd/maps/plat-ram.c +++ b/drivers/mtd/maps/plat-ram.c | |||
@@ -6,8 +6,6 @@ | |||
6 | * | 6 | * |
7 | * Generic platfrom device based RAM map | 7 | * Generic platfrom device based RAM map |
8 | * | 8 | * |
9 | * $Id: plat-ram.c,v 1.7 2005/11/07 11:14:28 gleixner Exp $ | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | 9 | * 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 | 10 | * 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 | 11 | * the Free Software Foundation; either version 2 of the License, or |
diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c index 4d858b3d5f82..de002eb1a7fe 100644 --- a/drivers/mtd/maps/redwood.c +++ b/drivers/mtd/maps/redwood.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: redwood.c,v 1.11 2005/11/07 11:14:28 gleixner Exp $ | ||
3 | * | ||
4 | * drivers/mtd/maps/redwood.c | 2 | * drivers/mtd/maps/redwood.c |
5 | * | 3 | * |
6 | * FLASH map for the IBM Redwood 4/5/6 boards. | 4 | * FLASH map for the IBM Redwood 4/5/6 boards. |
diff --git a/drivers/mtd/maps/rpxlite.c b/drivers/mtd/maps/rpxlite.c index 809a0c8e7aaf..14d90edb4430 100644 --- a/drivers/mtd/maps/rpxlite.c +++ b/drivers/mtd/maps/rpxlite.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: rpxlite.c,v 1.22 2004/11/04 13:24:15 gleixner Exp $ | ||
3 | * | ||
4 | * Handle mapping of the flash on the RPX Lite and CLLF boards | 2 | * Handle mapping of the flash on the RPX Lite and CLLF boards |
5 | */ | 3 | */ |
6 | 4 | ||
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index c7d5a52a2d55..e177a43dfff0 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c | |||
@@ -2,8 +2,6 @@ | |||
2 | * Flash memory access on SA11x0 based devices | 2 | * Flash memory access on SA11x0 based devices |
3 | * | 3 | * |
4 | * (C) 2000 Nicolas Pitre <nico@cam.org> | 4 | * (C) 2000 Nicolas Pitre <nico@cam.org> |
5 | * | ||
6 | * $Id: sa1100-flash.c,v 1.51 2005/11/07 11:14:28 gleixner Exp $ | ||
7 | */ | 5 | */ |
8 | #include <linux/module.h> | 6 | #include <linux/module.h> |
9 | #include <linux/types.h> | 7 | #include <linux/types.h> |
diff --git a/drivers/mtd/maps/sbc8240.c b/drivers/mtd/maps/sbc8240.c index b8c1331b7a04..6e1e99cd2b59 100644 --- a/drivers/mtd/maps/sbc8240.c +++ b/drivers/mtd/maps/sbc8240.c | |||
@@ -4,9 +4,6 @@ | |||
4 | * Carolyn Smith, Tektronix, Inc. | 4 | * Carolyn Smith, Tektronix, Inc. |
5 | * | 5 | * |
6 | * This code is GPLed | 6 | * This code is GPLed |
7 | * | ||
8 | * $Id: sbc8240.c,v 1.5 2005/11/07 11:14:28 gleixner Exp $ | ||
9 | * | ||
10 | */ | 7 | */ |
11 | 8 | ||
12 | /* | 9 | /* |
diff --git a/drivers/mtd/maps/sbc_gxx.c b/drivers/mtd/maps/sbc_gxx.c index 7cc4041d096d..1b1c0b7e11ef 100644 --- a/drivers/mtd/maps/sbc_gxx.c +++ b/drivers/mtd/maps/sbc_gxx.c | |||
@@ -17,8 +17,6 @@ | |||
17 | along with this program; if not, write to the Free Software | 17 | along with this program; if not, write to the Free Software |
18 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | 18 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
19 | 19 | ||
20 | $Id: sbc_gxx.c,v 1.35 2005/11/07 11:14:28 gleixner Exp $ | ||
21 | |||
22 | The SBC-MediaGX / SBC-GXx has up to 16 MiB of | 20 | The SBC-MediaGX / SBC-GXx has up to 16 MiB of |
23 | Intel StrataFlash (28F320/28F640) in x8 mode. | 21 | Intel StrataFlash (28F320/28F640) in x8 mode. |
24 | 22 | ||
diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c index 4045e372b90d..85c1e56309ec 100644 --- a/drivers/mtd/maps/sc520cdp.c +++ b/drivers/mtd/maps/sc520cdp.c | |||
@@ -16,8 +16,6 @@ | |||
16 | * along with this program; if not, write to the Free Software | 16 | * along with this program; if not, write to the Free Software |
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | 17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
18 | * | 18 | * |
19 | * $Id: sc520cdp.c,v 1.23 2005/11/17 08:20:27 dwmw2 Exp $ | ||
20 | * | ||
21 | * | 19 | * |
22 | * The SC520CDP is an evaluation board for the Elan SC520 processor available | 20 | * The SC520CDP is an evaluation board for the Elan SC520 processor available |
23 | * from AMD. It has two banks of 32-bit Flash ROM, each 8 Megabytes in size, | 21 | * from AMD. It has two banks of 32-bit Flash ROM, each 8 Megabytes in size, |
diff --git a/drivers/mtd/maps/scb2_flash.c b/drivers/mtd/maps/scb2_flash.c index 0fc5584324e3..21169e6d646c 100644 --- a/drivers/mtd/maps/scb2_flash.c +++ b/drivers/mtd/maps/scb2_flash.c | |||
@@ -1,6 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * MTD map driver for BIOS Flash on Intel SCB2 boards | 2 | * MTD map driver for BIOS Flash on Intel SCB2 boards |
3 | * $Id: scb2_flash.c,v 1.12 2005/03/18 14:04:35 gleixner Exp $ | ||
4 | * Copyright (C) 2002 Sun Microsystems, Inc. | 3 | * Copyright (C) 2002 Sun Microsystems, Inc. |
5 | * Tim Hockin <thockin@sun.com> | 4 | * Tim Hockin <thockin@sun.com> |
6 | * | 5 | * |
diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c index 5e2bce22f37c..b5391ebb736e 100644 --- a/drivers/mtd/maps/scx200_docflash.c +++ b/drivers/mtd/maps/scx200_docflash.c | |||
@@ -2,8 +2,6 @@ | |||
2 | 2 | ||
3 | Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> | 3 | Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> |
4 | 4 | ||
5 | $Id: scx200_docflash.c,v 1.12 2005/11/07 11:14:28 gleixner Exp $ | ||
6 | |||
7 | National Semiconductor SCx200 flash mapped with DOCCS | 5 | National Semiconductor SCx200 flash mapped with DOCCS |
8 | */ | 6 | */ |
9 | 7 | ||
diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c index 917dc778f24e..026eab028189 100644 --- a/drivers/mtd/maps/sharpsl-flash.c +++ b/drivers/mtd/maps/sharpsl-flash.c | |||
@@ -4,8 +4,6 @@ | |||
4 | * Copyright (C) 2001 Lineo Japan, Inc. | 4 | * Copyright (C) 2001 Lineo Japan, Inc. |
5 | * Copyright (C) 2002 SHARP | 5 | * Copyright (C) 2002 SHARP |
6 | * | 6 | * |
7 | * $Id: sharpsl-flash.c,v 1.7 2005/11/07 11:14:28 gleixner Exp $ | ||
8 | * | ||
9 | * based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp | 7 | * based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp |
10 | * Handle mapping of the flash on the RPX Lite and CLLF boards | 8 | * Handle mapping of the flash on the RPX Lite and CLLF boards |
11 | * | 9 | * |
diff --git a/drivers/mtd/maps/solutionengine.c b/drivers/mtd/maps/solutionengine.c index d76ceef453ce..0eb41d9c6786 100644 --- a/drivers/mtd/maps/solutionengine.c +++ b/drivers/mtd/maps/solutionengine.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: solutionengine.c,v 1.15 2005/11/07 11:14:28 gleixner Exp $ | ||
3 | * | ||
4 | * Flash and EPROM on Hitachi Solution Engine and similar boards. | 2 | * Flash and EPROM on Hitachi Solution Engine and similar boards. |
5 | * | 3 | * |
6 | * (C) 2001 Red Hat, Inc. | 4 | * (C) 2001 Red Hat, Inc. |
diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index 001af7f7ddda..0d7c88396c88 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: sun_uflash.c,v 1.13 2005/11/07 11:14:28 gleixner Exp $ | 1 | /* |
2 | * | 2 | * |
3 | * sun_uflash - Driver implementation for user-programmable flash | 3 | * sun_uflash - Driver implementation for user-programmable flash |
4 | * present on many Sun Microsystems SME boardsets. | 4 | * present on many Sun Microsystems SME boardsets. |
diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c index 521734057314..a5d3d8531faa 100644 --- a/drivers/mtd/maps/tqm8xxl.c +++ b/drivers/mtd/maps/tqm8xxl.c | |||
@@ -2,8 +2,6 @@ | |||
2 | * Handle mapping of the flash memory access routines | 2 | * Handle mapping of the flash memory access routines |
3 | * on TQM8xxL based devices. | 3 | * on TQM8xxL based devices. |
4 | * | 4 | * |
5 | * $Id: tqm8xxl.c,v 1.15 2005/11/07 11:14:28 gleixner Exp $ | ||
6 | * | ||
7 | * based on rpxlite.c | 5 | * based on rpxlite.c |
8 | * | 6 | * |
9 | * Copyright(C) 2001 Kirk Lee <kirk@hpc.ee.ntu.edu.tw> | 7 | * Copyright(C) 2001 Kirk Lee <kirk@hpc.ee.ntu.edu.tw> |
diff --git a/drivers/mtd/maps/ts5500_flash.c b/drivers/mtd/maps/ts5500_flash.c index b47270e850bc..e2147bf11c88 100644 --- a/drivers/mtd/maps/ts5500_flash.c +++ b/drivers/mtd/maps/ts5500_flash.c | |||
@@ -22,8 +22,6 @@ | |||
22 | * - Drive A and B use the resident flash disk (RFD) flash translation layer. | 22 | * - Drive A and B use the resident flash disk (RFD) flash translation layer. |
23 | * - If you have created your own jffs file system and the bios overwrites | 23 | * - If you have created your own jffs file system and the bios overwrites |
24 | * it during boot, try disabling Drive A: and B: in the boot order. | 24 | * it during boot, try disabling Drive A: and B: in the boot order. |
25 | * | ||
26 | * $Id: ts5500_flash.c,v 1.5 2005/11/07 11:14:28 gleixner Exp $ | ||
27 | */ | 25 | */ |
28 | 26 | ||
29 | #include <linux/init.h> | 27 | #include <linux/init.h> |
diff --git a/drivers/mtd/maps/tsunami_flash.c b/drivers/mtd/maps/tsunami_flash.c index 0f915ac3102e..77a8bfc02577 100644 --- a/drivers/mtd/maps/tsunami_flash.c +++ b/drivers/mtd/maps/tsunami_flash.c | |||
@@ -2,7 +2,6 @@ | |||
2 | * tsunami_flash.c | 2 | * tsunami_flash.c |
3 | * | 3 | * |
4 | * flash chip on alpha ds10... | 4 | * flash chip on alpha ds10... |
5 | * $Id: tsunami_flash.c,v 1.10 2005/11/07 11:14:29 gleixner Exp $ | ||
6 | */ | 5 | */ |
7 | #include <asm/io.h> | 6 | #include <asm/io.h> |
8 | #include <asm/core_tsunami.h> | 7 | #include <asm/core_tsunami.h> |
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c index 3fcf92130aa4..0dc645f8152f 100644 --- a/drivers/mtd/maps/uclinux.c +++ b/drivers/mtd/maps/uclinux.c | |||
@@ -4,8 +4,6 @@ | |||
4 | * uclinux.c -- generic memory mapped MTD driver for uclinux | 4 | * uclinux.c -- generic memory mapped MTD driver for uclinux |
5 | * | 5 | * |
6 | * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) | 6 | * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) |
7 | * | ||
8 | * $Id: uclinux.c,v 1.12 2005/11/07 11:14:29 gleixner Exp $ | ||
9 | */ | 7 | */ |
10 | 8 | ||
11 | /****************************************************************************/ | 9 | /****************************************************************************/ |
diff --git a/drivers/mtd/maps/vmax301.c b/drivers/mtd/maps/vmax301.c index b3e487395435..5a0c9a353b0f 100644 --- a/drivers/mtd/maps/vmax301.c +++ b/drivers/mtd/maps/vmax301.c | |||
@@ -1,4 +1,3 @@ | |||
1 | // $Id: vmax301.c,v 1.32 2005/11/07 11:14:29 gleixner Exp $ | ||
2 | /* ###################################################################### | 1 | /* ###################################################################### |
3 | 2 | ||
4 | Tempustech VMAX SBC301 MTD Driver. | 3 | Tempustech VMAX SBC301 MTD Driver. |
diff --git a/drivers/mtd/maps/walnut.c b/drivers/mtd/maps/walnut.c index ca932122fb64..e243476c8171 100644 --- a/drivers/mtd/maps/walnut.c +++ b/drivers/mtd/maps/walnut.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: walnut.c,v 1.3 2005/11/07 11:14:29 gleixner Exp $ | ||
3 | * | ||
4 | * Mapping for Walnut flash | 2 | * Mapping for Walnut flash |
5 | * (used ebony.c as a "framework") | 3 | * (used ebony.c as a "framework") |
6 | * | 4 | * |
diff --git a/drivers/mtd/maps/wr_sbc82xx_flash.c b/drivers/mtd/maps/wr_sbc82xx_flash.c index ac5b8105b6ef..413b0cf9bbd2 100644 --- a/drivers/mtd/maps/wr_sbc82xx_flash.c +++ b/drivers/mtd/maps/wr_sbc82xx_flash.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: wr_sbc82xx_flash.c,v 1.8 2005/11/07 11:14:29 gleixner Exp $ | ||
3 | * | ||
4 | * Map for flash chips on Wind River PowerQUICC II SBC82xx board. | 2 | * Map for flash chips on Wind River PowerQUICC II SBC82xx board. |
5 | * | 3 | * |
6 | * Copyright (C) 2004 Red Hat, Inc. | 4 | * Copyright (C) 2004 Red Hat, Inc. |
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 839eed8430a2..9ff007c4962c 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: mtd_blkdevs.c,v 1.27 2005/11/07 11:14:20 gleixner Exp $ | ||
3 | * | ||
4 | * (C) 2003 David Woodhouse <dwmw2@infradead.org> | 2 | * (C) 2003 David Woodhouse <dwmw2@infradead.org> |
5 | * | 3 | * |
6 | * Interface to Linux 2.5 block layer for MTD 'translation layers'. | 4 | * Interface to Linux 2.5 block layer for MTD 'translation layers'. |
@@ -212,7 +210,7 @@ static struct block_device_operations mtd_blktrans_ops = { | |||
212 | int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) | 210 | int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) |
213 | { | 211 | { |
214 | struct mtd_blktrans_ops *tr = new->tr; | 212 | struct mtd_blktrans_ops *tr = new->tr; |
215 | struct list_head *this; | 213 | struct mtd_blktrans_dev *d; |
216 | int last_devnum = -1; | 214 | int last_devnum = -1; |
217 | struct gendisk *gd; | 215 | struct gendisk *gd; |
218 | 216 | ||
@@ -221,8 +219,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) | |||
221 | BUG(); | 219 | BUG(); |
222 | } | 220 | } |
223 | 221 | ||
224 | list_for_each(this, &tr->devs) { | 222 | list_for_each_entry(d, &tr->devs, list) { |
225 | struct mtd_blktrans_dev *d = list_entry(this, struct mtd_blktrans_dev, list); | ||
226 | if (new->devnum == -1) { | 223 | if (new->devnum == -1) { |
227 | /* Use first free number */ | 224 | /* Use first free number */ |
228 | if (d->devnum != last_devnum+1) { | 225 | if (d->devnum != last_devnum+1) { |
@@ -309,33 +306,24 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) | |||
309 | 306 | ||
310 | static void blktrans_notify_remove(struct mtd_info *mtd) | 307 | static void blktrans_notify_remove(struct mtd_info *mtd) |
311 | { | 308 | { |
312 | struct list_head *this, *this2, *next; | 309 | struct mtd_blktrans_ops *tr; |
313 | 310 | struct mtd_blktrans_dev *dev, *next; | |
314 | list_for_each(this, &blktrans_majors) { | ||
315 | struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list); | ||
316 | |||
317 | list_for_each_safe(this2, next, &tr->devs) { | ||
318 | struct mtd_blktrans_dev *dev = list_entry(this2, struct mtd_blktrans_dev, list); | ||
319 | 311 | ||
312 | list_for_each_entry(tr, &blktrans_majors, list) | ||
313 | list_for_each_entry_safe(dev, next, &tr->devs, list) | ||
320 | if (dev->mtd == mtd) | 314 | if (dev->mtd == mtd) |
321 | tr->remove_dev(dev); | 315 | tr->remove_dev(dev); |
322 | } | ||
323 | } | ||
324 | } | 316 | } |
325 | 317 | ||
326 | static void blktrans_notify_add(struct mtd_info *mtd) | 318 | static void blktrans_notify_add(struct mtd_info *mtd) |
327 | { | 319 | { |
328 | struct list_head *this; | 320 | struct mtd_blktrans_ops *tr; |
329 | 321 | ||
330 | if (mtd->type == MTD_ABSENT) | 322 | if (mtd->type == MTD_ABSENT) |
331 | return; | 323 | return; |
332 | 324 | ||
333 | list_for_each(this, &blktrans_majors) { | 325 | list_for_each_entry(tr, &blktrans_majors, list) |
334 | struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list); | ||
335 | |||
336 | tr->add_mtd(tr, mtd); | 326 | tr->add_mtd(tr, mtd); |
337 | } | ||
338 | |||
339 | } | 327 | } |
340 | 328 | ||
341 | static struct mtd_notifier blktrans_notifier = { | 329 | static struct mtd_notifier blktrans_notifier = { |
@@ -406,7 +394,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) | |||
406 | 394 | ||
407 | int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr) | 395 | int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr) |
408 | { | 396 | { |
409 | struct list_head *this, *next; | 397 | struct mtd_blktrans_dev *dev, *next; |
410 | 398 | ||
411 | mutex_lock(&mtd_table_mutex); | 399 | mutex_lock(&mtd_table_mutex); |
412 | 400 | ||
@@ -416,10 +404,8 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr) | |||
416 | /* Remove it from the list of active majors */ | 404 | /* Remove it from the list of active majors */ |
417 | list_del(&tr->list); | 405 | list_del(&tr->list); |
418 | 406 | ||
419 | list_for_each_safe(this, next, &tr->devs) { | 407 | list_for_each_entry_safe(dev, next, &tr->devs, list) |
420 | struct mtd_blktrans_dev *dev = list_entry(this, struct mtd_blktrans_dev, list); | ||
421 | tr->remove_dev(dev); | 408 | tr->remove_dev(dev); |
422 | } | ||
423 | 409 | ||
424 | blk_cleanup_queue(tr->blkcore_priv->rq); | 410 | blk_cleanup_queue(tr->blkcore_priv->rq); |
425 | unregister_blkdev(tr->major, tr->name); | 411 | unregister_blkdev(tr->major, tr->name); |
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c index 952da30b1745..208c6faa0358 100644 --- a/drivers/mtd/mtdblock.c +++ b/drivers/mtd/mtdblock.c | |||
@@ -1,8 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Direct MTD block device access | 2 | * Direct MTD block device access |
3 | * | 3 | * |
4 | * $Id: mtdblock.c,v 1.68 2005/11/07 11:14:20 gleixner Exp $ | ||
5 | * | ||
6 | * (C) 2000-2003 Nicolas Pitre <nico@cam.org> | 4 | * (C) 2000-2003 Nicolas Pitre <nico@cam.org> |
7 | * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> | 5 | * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> |
8 | */ | 6 | */ |
diff --git a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c index f79dbb49b1a2..852165f8b1c3 100644 --- a/drivers/mtd/mtdblock_ro.c +++ b/drivers/mtd/mtdblock_ro.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: mtdblock_ro.c,v 1.19 2004/11/16 18:28:59 dwmw2 Exp $ | ||
3 | * | ||
4 | * (C) 2003 David Woodhouse <dwmw2@infradead.org> | 2 | * (C) 2003 David Woodhouse <dwmw2@infradead.org> |
5 | * | 3 | * |
6 | * Simple read-only (writable only for RAM) mtdblock driver | 4 | * Simple read-only (writable only for RAM) mtdblock driver |
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index aef9f4b687c9..d2f331876e4c 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: mtdchar.c,v 1.76 2005/11/07 11:14:20 gleixner Exp $ | ||
3 | * | ||
4 | * Character-device access to raw MTD devices. | 2 | * Character-device access to raw MTD devices. |
5 | * | 3 | * |
6 | */ | 4 | */ |
@@ -494,6 +492,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, | |||
494 | { | 492 | { |
495 | struct mtd_oob_buf buf; | 493 | struct mtd_oob_buf buf; |
496 | struct mtd_oob_ops ops; | 494 | struct mtd_oob_ops ops; |
495 | struct mtd_oob_buf __user *user_buf = argp; | ||
497 | uint32_t retlen; | 496 | uint32_t retlen; |
498 | 497 | ||
499 | if(!(file->f_mode & 2)) | 498 | if(!(file->f_mode & 2)) |
@@ -537,8 +536,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, | |||
537 | if (ops.oobretlen > 0xFFFFFFFFU) | 536 | if (ops.oobretlen > 0xFFFFFFFFU) |
538 | ret = -EOVERFLOW; | 537 | ret = -EOVERFLOW; |
539 | retlen = ops.oobretlen; | 538 | retlen = ops.oobretlen; |
540 | if (copy_to_user(&((struct mtd_oob_buf *)argp)->length, | 539 | if (copy_to_user(&user_buf->length, &retlen, sizeof(buf.length))) |
541 | &retlen, sizeof(buf.length))) | ||
542 | ret = -EFAULT; | 540 | ret = -EFAULT; |
543 | 541 | ||
544 | kfree(ops.oobbuf); | 542 | kfree(ops.oobbuf); |
@@ -592,29 +590,29 @@ static int mtd_ioctl(struct inode *inode, struct file *file, | |||
592 | 590 | ||
593 | case MEMLOCK: | 591 | case MEMLOCK: |
594 | { | 592 | { |
595 | struct erase_info_user info; | 593 | struct erase_info_user einfo; |
596 | 594 | ||
597 | if (copy_from_user(&info, argp, sizeof(info))) | 595 | if (copy_from_user(&einfo, argp, sizeof(einfo))) |
598 | return -EFAULT; | 596 | return -EFAULT; |
599 | 597 | ||
600 | if (!mtd->lock) | 598 | if (!mtd->lock) |
601 | ret = -EOPNOTSUPP; | 599 | ret = -EOPNOTSUPP; |
602 | else | 600 | else |
603 | ret = mtd->lock(mtd, info.start, info.length); | 601 | ret = mtd->lock(mtd, einfo.start, einfo.length); |
604 | break; | 602 | break; |
605 | } | 603 | } |
606 | 604 | ||
607 | case MEMUNLOCK: | 605 | case MEMUNLOCK: |
608 | { | 606 | { |
609 | struct erase_info_user info; | 607 | struct erase_info_user einfo; |
610 | 608 | ||
611 | if (copy_from_user(&info, argp, sizeof(info))) | 609 | if (copy_from_user(&einfo, argp, sizeof(einfo))) |
612 | return -EFAULT; | 610 | return -EFAULT; |
613 | 611 | ||
614 | if (!mtd->unlock) | 612 | if (!mtd->unlock) |
615 | ret = -EOPNOTSUPP; | 613 | ret = -EOPNOTSUPP; |
616 | else | 614 | else |
617 | ret = mtd->unlock(mtd, info.start, info.length); | 615 | ret = mtd->unlock(mtd, einfo.start, einfo.length); |
618 | break; | 616 | break; |
619 | } | 617 | } |
620 | 618 | ||
@@ -714,15 +712,15 @@ static int mtd_ioctl(struct inode *inode, struct file *file, | |||
714 | 712 | ||
715 | case OTPLOCK: | 713 | case OTPLOCK: |
716 | { | 714 | { |
717 | struct otp_info info; | 715 | struct otp_info oinfo; |
718 | 716 | ||
719 | if (mfi->mode != MTD_MODE_OTP_USER) | 717 | if (mfi->mode != MTD_MODE_OTP_USER) |
720 | return -EINVAL; | 718 | return -EINVAL; |
721 | if (copy_from_user(&info, argp, sizeof(info))) | 719 | if (copy_from_user(&oinfo, argp, sizeof(oinfo))) |
722 | return -EFAULT; | 720 | return -EFAULT; |
723 | if (!mtd->lock_user_prot_reg) | 721 | if (!mtd->lock_user_prot_reg) |
724 | return -EOPNOTSUPP; | 722 | return -EOPNOTSUPP; |
725 | ret = mtd->lock_user_prot_reg(mtd, info.start, info.length); | 723 | ret = mtd->lock_user_prot_reg(mtd, oinfo.start, oinfo.length); |
726 | break; | 724 | break; |
727 | } | 725 | } |
728 | #endif | 726 | #endif |
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c index d563dcd4b264..2972a5edb73d 100644 --- a/drivers/mtd/mtdconcat.c +++ b/drivers/mtd/mtdconcat.c | |||
@@ -6,8 +6,6 @@ | |||
6 | * NAND support by Christian Gan <cgan@iders.ca> | 6 | * NAND support by Christian Gan <cgan@iders.ca> |
7 | * | 7 | * |
8 | * This code is GPL | 8 | * This code is GPL |
9 | * | ||
10 | * $Id: mtdconcat.c,v 1.11 2005/11/07 11:14:20 gleixner Exp $ | ||
11 | */ | 9 | */ |
12 | 10 | ||
13 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index f7e7890e5bc6..a9d246949820 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: mtdcore.c,v 1.47 2005/11/07 11:14:20 gleixner Exp $ | ||
3 | * | ||
4 | * Core registration and callback routines for MTD | 2 | * Core registration and callback routines for MTD |
5 | * drivers and users. | 3 | * drivers and users. |
6 | * | 4 | * |
@@ -53,7 +51,7 @@ int add_mtd_device(struct mtd_info *mtd) | |||
53 | 51 | ||
54 | for (i=0; i < MAX_MTD_DEVICES; i++) | 52 | for (i=0; i < MAX_MTD_DEVICES; i++) |
55 | if (!mtd_table[i]) { | 53 | if (!mtd_table[i]) { |
56 | struct list_head *this; | 54 | struct mtd_notifier *not; |
57 | 55 | ||
58 | mtd_table[i] = mtd; | 56 | mtd_table[i] = mtd; |
59 | mtd->index = i; | 57 | mtd->index = i; |
@@ -72,10 +70,8 @@ int add_mtd_device(struct mtd_info *mtd) | |||
72 | DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name); | 70 | DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name); |
73 | /* No need to get a refcount on the module containing | 71 | /* No need to get a refcount on the module containing |
74 | the notifier, since we hold the mtd_table_mutex */ | 72 | the notifier, since we hold the mtd_table_mutex */ |
75 | list_for_each(this, &mtd_notifiers) { | 73 | list_for_each_entry(not, &mtd_notifiers, list) |
76 | struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list); | ||
77 | not->add(mtd); | 74 | not->add(mtd); |
78 | } | ||
79 | 75 | ||
80 | mutex_unlock(&mtd_table_mutex); | 76 | mutex_unlock(&mtd_table_mutex); |
81 | /* We _know_ we aren't being removed, because | 77 | /* We _know_ we aren't being removed, because |
@@ -113,14 +109,12 @@ int del_mtd_device (struct mtd_info *mtd) | |||
113 | mtd->index, mtd->name, mtd->usecount); | 109 | mtd->index, mtd->name, mtd->usecount); |
114 | ret = -EBUSY; | 110 | ret = -EBUSY; |
115 | } else { | 111 | } else { |
116 | struct list_head *this; | 112 | struct mtd_notifier *not; |
117 | 113 | ||
118 | /* No need to get a refcount on the module containing | 114 | /* No need to get a refcount on the module containing |
119 | the notifier, since we hold the mtd_table_mutex */ | 115 | the notifier, since we hold the mtd_table_mutex */ |
120 | list_for_each(this, &mtd_notifiers) { | 116 | list_for_each_entry(not, &mtd_notifiers, list) |
121 | struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list); | ||
122 | not->remove(mtd); | 117 | not->remove(mtd); |
123 | } | ||
124 | 118 | ||
125 | mtd_table[mtd->index] = NULL; | 119 | mtd_table[mtd->index] = NULL; |
126 | 120 | ||
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 07c701169344..edb90b58a9b1 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c | |||
@@ -5,8 +5,6 @@ | |||
5 | * | 5 | * |
6 | * This code is GPL | 6 | * This code is GPL |
7 | * | 7 | * |
8 | * $Id: mtdpart.c,v 1.55 2005/11/07 11:14:20 gleixner Exp $ | ||
9 | * | ||
10 | * 02-21-2002 Thomas Gleixner <gleixner@autronix.de> | 8 | * 02-21-2002 Thomas Gleixner <gleixner@autronix.de> |
11 | * added support for read_oob, write_oob | 9 | * added support for read_oob, write_oob |
12 | */ | 10 | */ |
@@ -46,8 +44,8 @@ struct mtd_part { | |||
46 | * to the _real_ device. | 44 | * to the _real_ device. |
47 | */ | 45 | */ |
48 | 46 | ||
49 | static int part_read (struct mtd_info *mtd, loff_t from, size_t len, | 47 | static int part_read(struct mtd_info *mtd, loff_t from, size_t len, |
50 | size_t *retlen, u_char *buf) | 48 | size_t *retlen, u_char *buf) |
51 | { | 49 | { |
52 | struct mtd_part *part = PART(mtd); | 50 | struct mtd_part *part = PART(mtd); |
53 | int res; | 51 | int res; |
@@ -56,7 +54,7 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len, | |||
56 | len = 0; | 54 | len = 0; |
57 | else if (from + len > mtd->size) | 55 | else if (from + len > mtd->size) |
58 | len = mtd->size - from; | 56 | len = mtd->size - from; |
59 | res = part->master->read (part->master, from + part->offset, | 57 | res = part->master->read(part->master, from + part->offset, |
60 | len, retlen, buf); | 58 | len, retlen, buf); |
61 | if (unlikely(res)) { | 59 | if (unlikely(res)) { |
62 | if (res == -EUCLEAN) | 60 | if (res == -EUCLEAN) |
@@ -67,8 +65,8 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len, | |||
67 | return res; | 65 | return res; |
68 | } | 66 | } |
69 | 67 | ||
70 | static int part_point (struct mtd_info *mtd, loff_t from, size_t len, | 68 | static int part_point(struct mtd_info *mtd, loff_t from, size_t len, |
71 | size_t *retlen, void **virt, resource_size_t *phys) | 69 | size_t *retlen, void **virt, resource_size_t *phys) |
72 | { | 70 | { |
73 | struct mtd_part *part = PART(mtd); | 71 | struct mtd_part *part = PART(mtd); |
74 | if (from >= mtd->size) | 72 | if (from >= mtd->size) |
@@ -87,7 +85,7 @@ static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) | |||
87 | } | 85 | } |
88 | 86 | ||
89 | static int part_read_oob(struct mtd_info *mtd, loff_t from, | 87 | static int part_read_oob(struct mtd_info *mtd, loff_t from, |
90 | struct mtd_oob_ops *ops) | 88 | struct mtd_oob_ops *ops) |
91 | { | 89 | { |
92 | struct mtd_part *part = PART(mtd); | 90 | struct mtd_part *part = PART(mtd); |
93 | int res; | 91 | int res; |
@@ -107,38 +105,38 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from, | |||
107 | return res; | 105 | return res; |
108 | } | 106 | } |
109 | 107 | ||
110 | static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, | 108 | static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from, |
111 | size_t *retlen, u_char *buf) | 109 | size_t len, size_t *retlen, u_char *buf) |
112 | { | 110 | { |
113 | struct mtd_part *part = PART(mtd); | 111 | struct mtd_part *part = PART(mtd); |
114 | return part->master->read_user_prot_reg (part->master, from, | 112 | return part->master->read_user_prot_reg(part->master, from, |
115 | len, retlen, buf); | 113 | len, retlen, buf); |
116 | } | 114 | } |
117 | 115 | ||
118 | static int part_get_user_prot_info (struct mtd_info *mtd, | 116 | static int part_get_user_prot_info(struct mtd_info *mtd, |
119 | struct otp_info *buf, size_t len) | 117 | struct otp_info *buf, size_t len) |
120 | { | 118 | { |
121 | struct mtd_part *part = PART(mtd); | 119 | struct mtd_part *part = PART(mtd); |
122 | return part->master->get_user_prot_info (part->master, buf, len); | 120 | return part->master->get_user_prot_info(part->master, buf, len); |
123 | } | 121 | } |
124 | 122 | ||
125 | static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, | 123 | static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, |
126 | size_t *retlen, u_char *buf) | 124 | size_t len, size_t *retlen, u_char *buf) |
127 | { | 125 | { |
128 | struct mtd_part *part = PART(mtd); | 126 | struct mtd_part *part = PART(mtd); |
129 | return part->master->read_fact_prot_reg (part->master, from, | 127 | return part->master->read_fact_prot_reg(part->master, from, |
130 | len, retlen, buf); | 128 | len, retlen, buf); |
131 | } | 129 | } |
132 | 130 | ||
133 | static int part_get_fact_prot_info (struct mtd_info *mtd, | 131 | static int part_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf, |
134 | struct otp_info *buf, size_t len) | 132 | size_t len) |
135 | { | 133 | { |
136 | struct mtd_part *part = PART(mtd); | 134 | struct mtd_part *part = PART(mtd); |
137 | return part->master->get_fact_prot_info (part->master, buf, len); | 135 | return part->master->get_fact_prot_info(part->master, buf, len); |
138 | } | 136 | } |
139 | 137 | ||
140 | static int part_write (struct mtd_info *mtd, loff_t to, size_t len, | 138 | static int part_write(struct mtd_info *mtd, loff_t to, size_t len, |
141 | size_t *retlen, const u_char *buf) | 139 | size_t *retlen, const u_char *buf) |
142 | { | 140 | { |
143 | struct mtd_part *part = PART(mtd); | 141 | struct mtd_part *part = PART(mtd); |
144 | if (!(mtd->flags & MTD_WRITEABLE)) | 142 | if (!(mtd->flags & MTD_WRITEABLE)) |
@@ -147,12 +145,12 @@ static int part_write (struct mtd_info *mtd, loff_t to, size_t len, | |||
147 | len = 0; | 145 | len = 0; |
148 | else if (to + len > mtd->size) | 146 | else if (to + len > mtd->size) |
149 | len = mtd->size - to; | 147 | len = mtd->size - to; |
150 | return part->master->write (part->master, to + part->offset, | 148 | return part->master->write(part->master, to + part->offset, |
151 | len, retlen, buf); | 149 | len, retlen, buf); |
152 | } | 150 | } |
153 | 151 | ||
154 | static int part_panic_write (struct mtd_info *mtd, loff_t to, size_t len, | 152 | static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len, |
155 | size_t *retlen, const u_char *buf) | 153 | size_t *retlen, const u_char *buf) |
156 | { | 154 | { |
157 | struct mtd_part *part = PART(mtd); | 155 | struct mtd_part *part = PART(mtd); |
158 | if (!(mtd->flags & MTD_WRITEABLE)) | 156 | if (!(mtd->flags & MTD_WRITEABLE)) |
@@ -161,12 +159,12 @@ static int part_panic_write (struct mtd_info *mtd, loff_t to, size_t len, | |||
161 | len = 0; | 159 | len = 0; |
162 | else if (to + len > mtd->size) | 160 | else if (to + len > mtd->size) |
163 | len = mtd->size - to; | 161 | len = mtd->size - to; |
164 | return part->master->panic_write (part->master, to + part->offset, | 162 | return part->master->panic_write(part->master, to + part->offset, |
165 | len, retlen, buf); | 163 | len, retlen, buf); |
166 | } | 164 | } |
167 | 165 | ||
168 | static int part_write_oob(struct mtd_info *mtd, loff_t to, | 166 | static int part_write_oob(struct mtd_info *mtd, loff_t to, |
169 | struct mtd_oob_ops *ops) | 167 | struct mtd_oob_ops *ops) |
170 | { | 168 | { |
171 | struct mtd_part *part = PART(mtd); | 169 | struct mtd_part *part = PART(mtd); |
172 | 170 | ||
@@ -180,31 +178,32 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to, | |||
180 | return part->master->write_oob(part->master, to + part->offset, ops); | 178 | return part->master->write_oob(part->master, to + part->offset, ops); |
181 | } | 179 | } |
182 | 180 | ||
183 | static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, | 181 | static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from, |
184 | size_t *retlen, u_char *buf) | 182 | size_t len, size_t *retlen, u_char *buf) |
185 | { | 183 | { |
186 | struct mtd_part *part = PART(mtd); | 184 | struct mtd_part *part = PART(mtd); |
187 | return part->master->write_user_prot_reg (part->master, from, | 185 | return part->master->write_user_prot_reg(part->master, from, |
188 | len, retlen, buf); | 186 | len, retlen, buf); |
189 | } | 187 | } |
190 | 188 | ||
191 | static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len) | 189 | static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, |
190 | size_t len) | ||
192 | { | 191 | { |
193 | struct mtd_part *part = PART(mtd); | 192 | struct mtd_part *part = PART(mtd); |
194 | return part->master->lock_user_prot_reg (part->master, from, len); | 193 | return part->master->lock_user_prot_reg(part->master, from, len); |
195 | } | 194 | } |
196 | 195 | ||
197 | static int part_writev (struct mtd_info *mtd, const struct kvec *vecs, | 196 | static int part_writev(struct mtd_info *mtd, const struct kvec *vecs, |
198 | unsigned long count, loff_t to, size_t *retlen) | 197 | unsigned long count, loff_t to, size_t *retlen) |
199 | { | 198 | { |
200 | struct mtd_part *part = PART(mtd); | 199 | struct mtd_part *part = PART(mtd); |
201 | if (!(mtd->flags & MTD_WRITEABLE)) | 200 | if (!(mtd->flags & MTD_WRITEABLE)) |
202 | return -EROFS; | 201 | return -EROFS; |
203 | return part->master->writev (part->master, vecs, count, | 202 | return part->master->writev(part->master, vecs, count, |
204 | to + part->offset, retlen); | 203 | to + part->offset, retlen); |
205 | } | 204 | } |
206 | 205 | ||
207 | static int part_erase (struct mtd_info *mtd, struct erase_info *instr) | 206 | static int part_erase(struct mtd_info *mtd, struct erase_info *instr) |
208 | { | 207 | { |
209 | struct mtd_part *part = PART(mtd); | 208 | struct mtd_part *part = PART(mtd); |
210 | int ret; | 209 | int ret; |
@@ -236,7 +235,7 @@ void mtd_erase_callback(struct erase_info *instr) | |||
236 | } | 235 | } |
237 | EXPORT_SYMBOL_GPL(mtd_erase_callback); | 236 | EXPORT_SYMBOL_GPL(mtd_erase_callback); |
238 | 237 | ||
239 | static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len) | 238 | static int part_lock(struct mtd_info *mtd, loff_t ofs, size_t len) |
240 | { | 239 | { |
241 | struct mtd_part *part = PART(mtd); | 240 | struct mtd_part *part = PART(mtd); |
242 | if ((len + ofs) > mtd->size) | 241 | if ((len + ofs) > mtd->size) |
@@ -244,7 +243,7 @@ static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len) | |||
244 | return part->master->lock(part->master, ofs + part->offset, len); | 243 | return part->master->lock(part->master, ofs + part->offset, len); |
245 | } | 244 | } |
246 | 245 | ||
247 | static int part_unlock (struct mtd_info *mtd, loff_t ofs, size_t len) | 246 | static int part_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) |
248 | { | 247 | { |
249 | struct mtd_part *part = PART(mtd); | 248 | struct mtd_part *part = PART(mtd); |
250 | if ((len + ofs) > mtd->size) | 249 | if ((len + ofs) > mtd->size) |
@@ -270,7 +269,7 @@ static void part_resume(struct mtd_info *mtd) | |||
270 | part->master->resume(part->master); | 269 | part->master->resume(part->master); |
271 | } | 270 | } |
272 | 271 | ||
273 | static int part_block_isbad (struct mtd_info *mtd, loff_t ofs) | 272 | static int part_block_isbad(struct mtd_info *mtd, loff_t ofs) |
274 | { | 273 | { |
275 | struct mtd_part *part = PART(mtd); | 274 | struct mtd_part *part = PART(mtd); |
276 | if (ofs >= mtd->size) | 275 | if (ofs >= mtd->size) |
@@ -279,7 +278,7 @@ static int part_block_isbad (struct mtd_info *mtd, loff_t ofs) | |||
279 | return part->master->block_isbad(part->master, ofs); | 278 | return part->master->block_isbad(part->master, ofs); |
280 | } | 279 | } |
281 | 280 | ||
282 | static int part_block_markbad (struct mtd_info *mtd, loff_t ofs) | 281 | static int part_block_markbad(struct mtd_info *mtd, loff_t ofs) |
283 | { | 282 | { |
284 | struct mtd_part *part = PART(mtd); | 283 | struct mtd_part *part = PART(mtd); |
285 | int res; | 284 | int res; |
@@ -302,229 +301,237 @@ static int part_block_markbad (struct mtd_info *mtd, loff_t ofs) | |||
302 | 301 | ||
303 | int del_mtd_partitions(struct mtd_info *master) | 302 | int del_mtd_partitions(struct mtd_info *master) |
304 | { | 303 | { |
305 | struct list_head *node; | 304 | struct mtd_part *slave, *next; |
306 | struct mtd_part *slave; | ||
307 | 305 | ||
308 | for (node = mtd_partitions.next; | 306 | list_for_each_entry_safe(slave, next, &mtd_partitions, list) |
309 | node != &mtd_partitions; | ||
310 | node = node->next) { | ||
311 | slave = list_entry(node, struct mtd_part, list); | ||
312 | if (slave->master == master) { | 307 | if (slave->master == master) { |
313 | struct list_head *prev = node->prev; | 308 | list_del(&slave->list); |
314 | __list_del(prev, node->next); | 309 | if (slave->registered) |
315 | if(slave->registered) | ||
316 | del_mtd_device(&slave->mtd); | 310 | del_mtd_device(&slave->mtd); |
317 | kfree(slave); | 311 | kfree(slave); |
318 | node = prev; | ||
319 | } | 312 | } |
320 | } | ||
321 | 313 | ||
322 | return 0; | 314 | return 0; |
323 | } | 315 | } |
316 | EXPORT_SYMBOL(del_mtd_partitions); | ||
324 | 317 | ||
325 | /* | 318 | static struct mtd_part *add_one_partition(struct mtd_info *master, |
326 | * This function, given a master MTD object and a partition table, creates | 319 | const struct mtd_partition *part, int partno, |
327 | * and registers slave MTD objects which are bound to the master according to | 320 | u_int32_t cur_offset) |
328 | * the partition definitions. | ||
329 | * (Q: should we register the master MTD object as well?) | ||
330 | */ | ||
331 | |||
332 | int add_mtd_partitions(struct mtd_info *master, | ||
333 | const struct mtd_partition *parts, | ||
334 | int nbparts) | ||
335 | { | 321 | { |
336 | struct mtd_part *slave; | 322 | struct mtd_part *slave; |
337 | u_int32_t cur_offset = 0; | ||
338 | int i; | ||
339 | |||
340 | printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); | ||
341 | |||
342 | for (i = 0; i < nbparts; i++) { | ||
343 | 323 | ||
344 | /* allocate the partition structure */ | 324 | /* allocate the partition structure */ |
345 | slave = kzalloc (sizeof(*slave), GFP_KERNEL); | 325 | slave = kzalloc(sizeof(*slave), GFP_KERNEL); |
346 | if (!slave) { | 326 | if (!slave) { |
347 | printk ("memory allocation error while creating partitions for \"%s\"\n", | 327 | printk(KERN_ERR"memory allocation error while creating partitions for \"%s\"\n", |
348 | master->name); | 328 | master->name); |
349 | del_mtd_partitions(master); | 329 | del_mtd_partitions(master); |
350 | return -ENOMEM; | 330 | return NULL; |
351 | } | 331 | } |
352 | list_add(&slave->list, &mtd_partitions); | 332 | list_add(&slave->list, &mtd_partitions); |
353 | 333 | ||
354 | /* set up the MTD object for this partition */ | 334 | /* set up the MTD object for this partition */ |
355 | slave->mtd.type = master->type; | 335 | slave->mtd.type = master->type; |
356 | slave->mtd.flags = master->flags & ~parts[i].mask_flags; | 336 | slave->mtd.flags = master->flags & ~part->mask_flags; |
357 | slave->mtd.size = parts[i].size; | 337 | slave->mtd.size = part->size; |
358 | slave->mtd.writesize = master->writesize; | 338 | slave->mtd.writesize = master->writesize; |
359 | slave->mtd.oobsize = master->oobsize; | 339 | slave->mtd.oobsize = master->oobsize; |
360 | slave->mtd.oobavail = master->oobavail; | 340 | slave->mtd.oobavail = master->oobavail; |
361 | slave->mtd.subpage_sft = master->subpage_sft; | 341 | slave->mtd.subpage_sft = master->subpage_sft; |
362 | 342 | ||
363 | slave->mtd.name = parts[i].name; | 343 | slave->mtd.name = part->name; |
364 | slave->mtd.owner = master->owner; | 344 | slave->mtd.owner = master->owner; |
365 | 345 | ||
366 | slave->mtd.read = part_read; | 346 | slave->mtd.read = part_read; |
367 | slave->mtd.write = part_write; | 347 | slave->mtd.write = part_write; |
368 | 348 | ||
369 | if (master->panic_write) | 349 | if (master->panic_write) |
370 | slave->mtd.panic_write = part_panic_write; | 350 | slave->mtd.panic_write = part_panic_write; |
371 | 351 | ||
372 | if(master->point && master->unpoint){ | 352 | if (master->point && master->unpoint) { |
373 | slave->mtd.point = part_point; | 353 | slave->mtd.point = part_point; |
374 | slave->mtd.unpoint = part_unpoint; | 354 | slave->mtd.unpoint = part_unpoint; |
375 | } | 355 | } |
376 | 356 | ||
377 | if (master->read_oob) | 357 | if (master->read_oob) |
378 | slave->mtd.read_oob = part_read_oob; | 358 | slave->mtd.read_oob = part_read_oob; |
379 | if (master->write_oob) | 359 | if (master->write_oob) |
380 | slave->mtd.write_oob = part_write_oob; | 360 | slave->mtd.write_oob = part_write_oob; |
381 | if(master->read_user_prot_reg) | 361 | if (master->read_user_prot_reg) |
382 | slave->mtd.read_user_prot_reg = part_read_user_prot_reg; | 362 | slave->mtd.read_user_prot_reg = part_read_user_prot_reg; |
383 | if(master->read_fact_prot_reg) | 363 | if (master->read_fact_prot_reg) |
384 | slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg; | 364 | slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg; |
385 | if(master->write_user_prot_reg) | 365 | if (master->write_user_prot_reg) |
386 | slave->mtd.write_user_prot_reg = part_write_user_prot_reg; | 366 | slave->mtd.write_user_prot_reg = part_write_user_prot_reg; |
387 | if(master->lock_user_prot_reg) | 367 | if (master->lock_user_prot_reg) |
388 | slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg; | 368 | slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg; |
389 | if(master->get_user_prot_info) | 369 | if (master->get_user_prot_info) |
390 | slave->mtd.get_user_prot_info = part_get_user_prot_info; | 370 | slave->mtd.get_user_prot_info = part_get_user_prot_info; |
391 | if(master->get_fact_prot_info) | 371 | if (master->get_fact_prot_info) |
392 | slave->mtd.get_fact_prot_info = part_get_fact_prot_info; | 372 | slave->mtd.get_fact_prot_info = part_get_fact_prot_info; |
393 | if (master->sync) | 373 | if (master->sync) |
394 | slave->mtd.sync = part_sync; | 374 | slave->mtd.sync = part_sync; |
395 | if (!i && master->suspend && master->resume) { | 375 | if (!partno && master->suspend && master->resume) { |
396 | slave->mtd.suspend = part_suspend; | 376 | slave->mtd.suspend = part_suspend; |
397 | slave->mtd.resume = part_resume; | 377 | slave->mtd.resume = part_resume; |
378 | } | ||
379 | if (master->writev) | ||
380 | slave->mtd.writev = part_writev; | ||
381 | if (master->lock) | ||
382 | slave->mtd.lock = part_lock; | ||
383 | if (master->unlock) | ||
384 | slave->mtd.unlock = part_unlock; | ||
385 | if (master->block_isbad) | ||
386 | slave->mtd.block_isbad = part_block_isbad; | ||
387 | if (master->block_markbad) | ||
388 | slave->mtd.block_markbad = part_block_markbad; | ||
389 | slave->mtd.erase = part_erase; | ||
390 | slave->master = master; | ||
391 | slave->offset = part->offset; | ||
392 | slave->index = partno; | ||
393 | |||
394 | if (slave->offset == MTDPART_OFS_APPEND) | ||
395 | slave->offset = cur_offset; | ||
396 | if (slave->offset == MTDPART_OFS_NXTBLK) { | ||
397 | slave->offset = cur_offset; | ||
398 | if ((cur_offset % master->erasesize) != 0) { | ||
399 | /* Round up to next erasesize */ | ||
400 | slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize; | ||
401 | printk(KERN_NOTICE "Moving partition %d: " | ||
402 | "0x%08x -> 0x%08x\n", partno, | ||
403 | cur_offset, slave->offset); | ||
398 | } | 404 | } |
399 | if (master->writev) | 405 | } |
400 | slave->mtd.writev = part_writev; | 406 | if (slave->mtd.size == MTDPART_SIZ_FULL) |
401 | if (master->lock) | 407 | slave->mtd.size = master->size - slave->offset; |
402 | slave->mtd.lock = part_lock; | 408 | |
403 | if (master->unlock) | 409 | printk(KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, |
404 | slave->mtd.unlock = part_unlock; | 410 | slave->offset + slave->mtd.size, slave->mtd.name); |
405 | if (master->block_isbad) | 411 | |
406 | slave->mtd.block_isbad = part_block_isbad; | 412 | /* let's do some sanity checks */ |
407 | if (master->block_markbad) | 413 | if (slave->offset >= master->size) { |
408 | slave->mtd.block_markbad = part_block_markbad; | 414 | /* let's register it anyway to preserve ordering */ |
409 | slave->mtd.erase = part_erase; | 415 | slave->offset = 0; |
410 | slave->master = master; | 416 | slave->mtd.size = 0; |
411 | slave->offset = parts[i].offset; | 417 | printk(KERN_ERR"mtd: partition \"%s\" is out of reach -- disabled\n", |
412 | slave->index = i; | 418 | part->name); |
413 | 419 | goto out_register; | |
414 | if (slave->offset == MTDPART_OFS_APPEND) | 420 | } |
415 | slave->offset = cur_offset; | 421 | if (slave->offset + slave->mtd.size > master->size) { |
416 | if (slave->offset == MTDPART_OFS_NXTBLK) { | 422 | slave->mtd.size = master->size - slave->offset; |
417 | slave->offset = cur_offset; | 423 | printk(KERN_WARNING"mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n", |
418 | if ((cur_offset % master->erasesize) != 0) { | 424 | part->name, master->name, slave->mtd.size); |
419 | /* Round up to next erasesize */ | 425 | } |
420 | slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize; | 426 | if (master->numeraseregions > 1) { |
421 | printk(KERN_NOTICE "Moving partition %d: " | 427 | /* Deal with variable erase size stuff */ |
422 | "0x%08x -> 0x%08x\n", i, | 428 | int i, max = master->numeraseregions; |
423 | cur_offset, slave->offset); | 429 | u32 end = slave->offset + slave->mtd.size; |
430 | struct mtd_erase_region_info *regions = master->eraseregions; | ||
431 | |||
432 | /* Find the first erase regions which is part of this | ||
433 | * partition. */ | ||
434 | for (i = 0; i < max && regions[i].offset <= slave->offset; i++) | ||
435 | ; | ||
436 | /* The loop searched for the region _behind_ the first one */ | ||
437 | i--; | ||
438 | |||
439 | /* Pick biggest erasesize */ | ||
440 | for (; i < max && regions[i].offset < end; i++) { | ||
441 | if (slave->mtd.erasesize < regions[i].erasesize) { | ||
442 | slave->mtd.erasesize = regions[i].erasesize; | ||
424 | } | 443 | } |
425 | } | 444 | } |
426 | if (slave->mtd.size == MTDPART_SIZ_FULL) | 445 | BUG_ON(slave->mtd.erasesize == 0); |
427 | slave->mtd.size = master->size - slave->offset; | 446 | } else { |
428 | cur_offset = slave->offset + slave->mtd.size; | 447 | /* Single erase size */ |
448 | slave->mtd.erasesize = master->erasesize; | ||
449 | } | ||
429 | 450 | ||
430 | printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, | 451 | if ((slave->mtd.flags & MTD_WRITEABLE) && |
431 | slave->offset + slave->mtd.size, slave->mtd.name); | 452 | (slave->offset % slave->mtd.erasesize)) { |
453 | /* Doesn't start on a boundary of major erase size */ | ||
454 | /* FIXME: Let it be writable if it is on a boundary of | ||
455 | * _minor_ erase size though */ | ||
456 | slave->mtd.flags &= ~MTD_WRITEABLE; | ||
457 | printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", | ||
458 | part->name); | ||
459 | } | ||
460 | if ((slave->mtd.flags & MTD_WRITEABLE) && | ||
461 | (slave->mtd.size % slave->mtd.erasesize)) { | ||
462 | slave->mtd.flags &= ~MTD_WRITEABLE; | ||
463 | printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", | ||
464 | part->name); | ||
465 | } | ||
432 | 466 | ||
433 | /* let's do some sanity checks */ | 467 | slave->mtd.ecclayout = master->ecclayout; |
434 | if (slave->offset >= master->size) { | 468 | if (master->block_isbad) { |
435 | /* let's register it anyway to preserve ordering */ | 469 | uint32_t offs = 0; |
436 | slave->offset = 0; | ||
437 | slave->mtd.size = 0; | ||
438 | printk ("mtd: partition \"%s\" is out of reach -- disabled\n", | ||
439 | parts[i].name); | ||
440 | } | ||
441 | if (slave->offset + slave->mtd.size > master->size) { | ||
442 | slave->mtd.size = master->size - slave->offset; | ||
443 | printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n", | ||
444 | parts[i].name, master->name, slave->mtd.size); | ||
445 | } | ||
446 | if (master->numeraseregions>1) { | ||
447 | /* Deal with variable erase size stuff */ | ||
448 | int i; | ||
449 | struct mtd_erase_region_info *regions = master->eraseregions; | ||
450 | |||
451 | /* Find the first erase regions which is part of this partition. */ | ||
452 | for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++) | ||
453 | ; | ||
454 | |||
455 | for (i--; i < master->numeraseregions && slave->offset + slave->mtd.size > regions[i].offset; i++) { | ||
456 | if (slave->mtd.erasesize < regions[i].erasesize) { | ||
457 | slave->mtd.erasesize = regions[i].erasesize; | ||
458 | } | ||
459 | } | ||
460 | } else { | ||
461 | /* Single erase size */ | ||
462 | slave->mtd.erasesize = master->erasesize; | ||
463 | } | ||
464 | 470 | ||
465 | if ((slave->mtd.flags & MTD_WRITEABLE) && | 471 | while (offs < slave->mtd.size) { |
466 | (slave->offset % slave->mtd.erasesize)) { | 472 | if (master->block_isbad(master, |
467 | /* Doesn't start on a boundary of major erase size */ | 473 | offs + slave->offset)) |
468 | /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */ | 474 | slave->mtd.ecc_stats.badblocks++; |
469 | slave->mtd.flags &= ~MTD_WRITEABLE; | 475 | offs += slave->mtd.erasesize; |
470 | printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", | ||
471 | parts[i].name); | ||
472 | } | ||
473 | if ((slave->mtd.flags & MTD_WRITEABLE) && | ||
474 | (slave->mtd.size % slave->mtd.erasesize)) { | ||
475 | slave->mtd.flags &= ~MTD_WRITEABLE; | ||
476 | printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", | ||
477 | parts[i].name); | ||
478 | } | 476 | } |
477 | } | ||
479 | 478 | ||
480 | slave->mtd.ecclayout = master->ecclayout; | 479 | out_register: |
481 | if (master->block_isbad) { | 480 | if (part->mtdp) { |
482 | uint32_t offs = 0; | 481 | /* store the object pointer (caller may or may not register it*/ |
482 | *part->mtdp = &slave->mtd; | ||
483 | slave->registered = 0; | ||
484 | } else { | ||
485 | /* register our partition */ | ||
486 | add_mtd_device(&slave->mtd); | ||
487 | slave->registered = 1; | ||
488 | } | ||
489 | return slave; | ||
490 | } | ||
483 | 491 | ||
484 | while(offs < slave->mtd.size) { | 492 | /* |
485 | if (master->block_isbad(master, | 493 | * This function, given a master MTD object and a partition table, creates |
486 | offs + slave->offset)) | 494 | * and registers slave MTD objects which are bound to the master according to |
487 | slave->mtd.ecc_stats.badblocks++; | 495 | * the partition definitions. |
488 | offs += slave->mtd.erasesize; | 496 | * (Q: should we register the master MTD object as well?) |
489 | } | 497 | */ |
490 | } | ||
491 | 498 | ||
492 | if(parts[i].mtdp) | 499 | int add_mtd_partitions(struct mtd_info *master, |
493 | { /* store the object pointer (caller may or may not register it */ | 500 | const struct mtd_partition *parts, |
494 | *parts[i].mtdp = &slave->mtd; | 501 | int nbparts) |
495 | slave->registered = 0; | 502 | { |
496 | } | 503 | struct mtd_part *slave; |
497 | else | 504 | u_int32_t cur_offset = 0; |
498 | { | 505 | int i; |
499 | /* register our partition */ | 506 | |
500 | add_mtd_device(&slave->mtd); | 507 | printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); |
501 | slave->registered = 1; | 508 | |
502 | } | 509 | for (i = 0; i < nbparts; i++) { |
510 | slave = add_one_partition(master, parts + i, i, cur_offset); | ||
511 | if (!slave) | ||
512 | return -ENOMEM; | ||
513 | cur_offset = slave->offset + slave->mtd.size; | ||
503 | } | 514 | } |
504 | 515 | ||
505 | return 0; | 516 | return 0; |
506 | } | 517 | } |
507 | |||
508 | EXPORT_SYMBOL(add_mtd_partitions); | 518 | EXPORT_SYMBOL(add_mtd_partitions); |
509 | EXPORT_SYMBOL(del_mtd_partitions); | ||
510 | 519 | ||
511 | static DEFINE_SPINLOCK(part_parser_lock); | 520 | static DEFINE_SPINLOCK(part_parser_lock); |
512 | static LIST_HEAD(part_parsers); | 521 | static LIST_HEAD(part_parsers); |
513 | 522 | ||
514 | static struct mtd_part_parser *get_partition_parser(const char *name) | 523 | static struct mtd_part_parser *get_partition_parser(const char *name) |
515 | { | 524 | { |
516 | struct list_head *this; | 525 | struct mtd_part_parser *p, *ret = NULL; |
517 | void *ret = NULL; | ||
518 | spin_lock(&part_parser_lock); | ||
519 | 526 | ||
520 | list_for_each(this, &part_parsers) { | 527 | spin_lock(&part_parser_lock); |
521 | struct mtd_part_parser *p = list_entry(this, struct mtd_part_parser, list); | ||
522 | 528 | ||
529 | list_for_each_entry(p, &part_parsers, list) | ||
523 | if (!strcmp(p->name, name) && try_module_get(p->owner)) { | 530 | if (!strcmp(p->name, name) && try_module_get(p->owner)) { |
524 | ret = p; | 531 | ret = p; |
525 | break; | 532 | break; |
526 | } | 533 | } |
527 | } | 534 | |
528 | spin_unlock(&part_parser_lock); | 535 | spin_unlock(&part_parser_lock); |
529 | 536 | ||
530 | return ret; | 537 | return ret; |
@@ -538,6 +545,7 @@ int register_mtd_parser(struct mtd_part_parser *p) | |||
538 | 545 | ||
539 | return 0; | 546 | return 0; |
540 | } | 547 | } |
548 | EXPORT_SYMBOL_GPL(register_mtd_parser); | ||
541 | 549 | ||
542 | int deregister_mtd_parser(struct mtd_part_parser *p) | 550 | int deregister_mtd_parser(struct mtd_part_parser *p) |
543 | { | 551 | { |
@@ -546,6 +554,7 @@ int deregister_mtd_parser(struct mtd_part_parser *p) | |||
546 | spin_unlock(&part_parser_lock); | 554 | spin_unlock(&part_parser_lock); |
547 | return 0; | 555 | return 0; |
548 | } | 556 | } |
557 | EXPORT_SYMBOL_GPL(deregister_mtd_parser); | ||
549 | 558 | ||
550 | int parse_mtd_partitions(struct mtd_info *master, const char **types, | 559 | int parse_mtd_partitions(struct mtd_info *master, const char **types, |
551 | struct mtd_partition **pparts, unsigned long origin) | 560 | struct mtd_partition **pparts, unsigned long origin) |
@@ -573,7 +582,4 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types, | |||
573 | } | 582 | } |
574 | return ret; | 583 | return ret; |
575 | } | 584 | } |
576 | |||
577 | EXPORT_SYMBOL_GPL(parse_mtd_partitions); | 585 | EXPORT_SYMBOL_GPL(parse_mtd_partitions); |
578 | EXPORT_SYMBOL_GPL(register_mtd_parser); | ||
579 | EXPORT_SYMBOL_GPL(deregister_mtd_parser); | ||
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 5076faf9ca66..71406e517857 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -1,5 +1,4 @@ | |||
1 | # drivers/mtd/nand/Kconfig | 1 | # drivers/mtd/nand/Kconfig |
2 | # $Id: Kconfig,v 1.35 2005/11/07 11:14:30 gleixner Exp $ | ||
3 | 2 | ||
4 | menuconfig MTD_NAND | 3 | menuconfig MTD_NAND |
5 | tristate "NAND Device Support" | 4 | tristate "NAND Device Support" |
@@ -272,22 +271,23 @@ config MTD_NAND_CS553X | |||
272 | 271 | ||
273 | If you say "m", the module will be called "cs553x_nand.ko". | 272 | If you say "m", the module will be called "cs553x_nand.ko". |
274 | 273 | ||
275 | config MTD_NAND_AT91 | 274 | config MTD_NAND_ATMEL |
276 | bool "Support for NAND Flash / SmartMedia on AT91" | 275 | tristate "Support for NAND Flash / SmartMedia on AT91 and AVR32" |
277 | depends on ARCH_AT91 | 276 | depends on ARCH_AT91 || AVR32 |
278 | help | 277 | help |
279 | Enables support for NAND Flash / Smart Media Card interface | 278 | Enables support for NAND Flash / Smart Media Card interface |
280 | on Atmel AT91 processors. | 279 | on Atmel AT91 and AVR32 processors. |
281 | choice | 280 | choice |
282 | prompt "ECC management for NAND Flash / SmartMedia on AT91" | 281 | prompt "ECC management for NAND Flash / SmartMedia on AT91 / AVR32" |
283 | depends on MTD_NAND_AT91 | 282 | depends on MTD_NAND_ATMEL |
284 | 283 | ||
285 | config MTD_NAND_AT91_ECC_HW | 284 | config MTD_NAND_ATMEL_ECC_HW |
286 | bool "Hardware ECC" | 285 | bool "Hardware ECC" |
287 | depends on ARCH_AT91SAM9263 || ARCH_AT91SAM9260 | 286 | depends on ARCH_AT91SAM9263 || ARCH_AT91SAM9260 || AVR32 |
288 | help | 287 | help |
289 | Uses hardware ECC provided by the at91sam9260/at91sam9263 chip | 288 | Use hardware ECC instead of software ECC when the chip |
290 | instead of software ECC. | 289 | supports it. |
290 | |||
291 | The hardware ECC controller is capable of single bit error | 291 | The hardware ECC controller is capable of single bit error |
292 | correction and 2-bit random detection per page. | 292 | correction and 2-bit random detection per page. |
293 | 293 | ||
@@ -297,16 +297,16 @@ config MTD_NAND_AT91_ECC_HW | |||
297 | 297 | ||
298 | If unsure, say Y | 298 | If unsure, say Y |
299 | 299 | ||
300 | config MTD_NAND_AT91_ECC_SOFT | 300 | config MTD_NAND_ATMEL_ECC_SOFT |
301 | bool "Software ECC" | 301 | bool "Software ECC" |
302 | help | 302 | help |
303 | Uses software ECC. | 303 | Use software ECC. |
304 | 304 | ||
305 | NB : hardware and software ECC schemes are incompatible. | 305 | NB : hardware and software ECC schemes are incompatible. |
306 | If you switch from one to another, you'll have to erase your | 306 | If you switch from one to another, you'll have to erase your |
307 | mtd partition. | 307 | mtd partition. |
308 | 308 | ||
309 | config MTD_NAND_AT91_ECC_NONE | 309 | config MTD_NAND_ATMEL_ECC_NONE |
310 | bool "No ECC (testing only, DANGEROUS)" | 310 | bool "No ECC (testing only, DANGEROUS)" |
311 | depends on DEBUG_KERNEL | 311 | depends on DEBUG_KERNEL |
312 | help | 312 | help |
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index a6e74a46992a..d772581de573 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile | |||
@@ -1,7 +1,6 @@ | |||
1 | # | 1 | # |
2 | # linux/drivers/nand/Makefile | 2 | # linux/drivers/nand/Makefile |
3 | # | 3 | # |
4 | # $Id: Makefile.common,v 1.15 2004/11/26 12:28:22 dedekind Exp $ | ||
5 | 4 | ||
6 | obj-$(CONFIG_MTD_NAND) += nand.o nand_ecc.o | 5 | obj-$(CONFIG_MTD_NAND) += nand.o nand_ecc.o |
7 | obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o | 6 | obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o |
@@ -24,7 +23,7 @@ obj-$(CONFIG_MTD_NAND_TS7250) += ts7250.o | |||
24 | obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o | 23 | obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o |
25 | obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o | 24 | obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o |
26 | obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o | 25 | obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o |
27 | obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o | 26 | obj-$(CONFIG_MTD_NAND_ATMEL) += atmel_nand.o |
28 | obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o | 27 | obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o |
29 | obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o | 28 | obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o |
30 | obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o | 29 | obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o |
diff --git a/drivers/mtd/nand/at91_nand.c b/drivers/mtd/nand/atmel_nand.c index 0adb287027a2..99aec46e2145 100644 --- a/drivers/mtd/nand/at91_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/mtd/nand/at91_nand.c | ||
3 | * | ||
4 | * Copyright (C) 2003 Rick Bronson | 2 | * Copyright (C) 2003 Rick Bronson |
5 | * | 3 | * |
6 | * Derived from drivers/mtd/nand/autcpu12.c | 4 | * Derived from drivers/mtd/nand/autcpu12.c |
@@ -31,20 +29,19 @@ | |||
31 | #include <linux/mtd/nand.h> | 29 | #include <linux/mtd/nand.h> |
32 | #include <linux/mtd/partitions.h> | 30 | #include <linux/mtd/partitions.h> |
33 | 31 | ||
34 | #include <asm/io.h> | 32 | #include <linux/gpio.h> |
35 | #include <asm/sizes.h> | 33 | #include <linux/io.h> |
36 | 34 | ||
37 | #include <asm/hardware.h> | ||
38 | #include <asm/arch/board.h> | 35 | #include <asm/arch/board.h> |
39 | #include <asm/arch/gpio.h> | 36 | #include <asm/arch/cpu.h> |
40 | 37 | ||
41 | #ifdef CONFIG_MTD_NAND_AT91_ECC_HW | 38 | #ifdef CONFIG_MTD_NAND_ATMEL_ECC_HW |
42 | #define hard_ecc 1 | 39 | #define hard_ecc 1 |
43 | #else | 40 | #else |
44 | #define hard_ecc 0 | 41 | #define hard_ecc 0 |
45 | #endif | 42 | #endif |
46 | 43 | ||
47 | #ifdef CONFIG_MTD_NAND_AT91_ECC_NONE | 44 | #ifdef CONFIG_MTD_NAND_ATMEL_ECC_NONE |
48 | #define no_ecc 1 | 45 | #define no_ecc 1 |
49 | #else | 46 | #else |
50 | #define no_ecc 0 | 47 | #define no_ecc 0 |
@@ -52,18 +49,18 @@ | |||
52 | 49 | ||
53 | /* Register access macros */ | 50 | /* Register access macros */ |
54 | #define ecc_readl(add, reg) \ | 51 | #define ecc_readl(add, reg) \ |
55 | __raw_readl(add + AT91_ECC_##reg) | 52 | __raw_readl(add + ATMEL_ECC_##reg) |
56 | #define ecc_writel(add, reg, value) \ | 53 | #define ecc_writel(add, reg, value) \ |
57 | __raw_writel((value), add + AT91_ECC_##reg) | 54 | __raw_writel((value), add + ATMEL_ECC_##reg) |
58 | 55 | ||
59 | #include <asm/arch/at91_ecc.h> /* AT91SAM9260/3 ECC registers */ | 56 | #include "atmel_nand_ecc.h" /* Hardware ECC registers */ |
60 | 57 | ||
61 | /* oob layout for large page size | 58 | /* oob layout for large page size |
62 | * bad block info is on bytes 0 and 1 | 59 | * bad block info is on bytes 0 and 1 |
63 | * the bytes have to be consecutives to avoid | 60 | * the bytes have to be consecutives to avoid |
64 | * several NAND_CMD_RNDOUT during read | 61 | * several NAND_CMD_RNDOUT during read |
65 | */ | 62 | */ |
66 | static struct nand_ecclayout at91_oobinfo_large = { | 63 | static struct nand_ecclayout atmel_oobinfo_large = { |
67 | .eccbytes = 4, | 64 | .eccbytes = 4, |
68 | .eccpos = {60, 61, 62, 63}, | 65 | .eccpos = {60, 61, 62, 63}, |
69 | .oobfree = { | 66 | .oobfree = { |
@@ -76,7 +73,7 @@ static struct nand_ecclayout at91_oobinfo_large = { | |||
76 | * the bytes have to be consecutives to avoid | 73 | * the bytes have to be consecutives to avoid |
77 | * several NAND_CMD_RNDOUT during read | 74 | * several NAND_CMD_RNDOUT during read |
78 | */ | 75 | */ |
79 | static struct nand_ecclayout at91_oobinfo_small = { | 76 | static struct nand_ecclayout atmel_oobinfo_small = { |
80 | .eccbytes = 4, | 77 | .eccbytes = 4, |
81 | .eccpos = {0, 1, 2, 3}, | 78 | .eccpos = {0, 1, 2, 3}, |
82 | .oobfree = { | 79 | .oobfree = { |
@@ -84,11 +81,11 @@ static struct nand_ecclayout at91_oobinfo_small = { | |||
84 | }, | 81 | }, |
85 | }; | 82 | }; |
86 | 83 | ||
87 | struct at91_nand_host { | 84 | struct atmel_nand_host { |
88 | struct nand_chip nand_chip; | 85 | struct nand_chip nand_chip; |
89 | struct mtd_info mtd; | 86 | struct mtd_info mtd; |
90 | void __iomem *io_base; | 87 | void __iomem *io_base; |
91 | struct at91_nand_data *board; | 88 | struct atmel_nand_data *board; |
92 | struct device *dev; | 89 | struct device *dev; |
93 | void __iomem *ecc; | 90 | void __iomem *ecc; |
94 | }; | 91 | }; |
@@ -96,34 +93,34 @@ struct at91_nand_host { | |||
96 | /* | 93 | /* |
97 | * Enable NAND. | 94 | * Enable NAND. |
98 | */ | 95 | */ |
99 | static void at91_nand_enable(struct at91_nand_host *host) | 96 | static void atmel_nand_enable(struct atmel_nand_host *host) |
100 | { | 97 | { |
101 | if (host->board->enable_pin) | 98 | if (host->board->enable_pin) |
102 | at91_set_gpio_value(host->board->enable_pin, 0); | 99 | gpio_set_value(host->board->enable_pin, 0); |
103 | } | 100 | } |
104 | 101 | ||
105 | /* | 102 | /* |
106 | * Disable NAND. | 103 | * Disable NAND. |
107 | */ | 104 | */ |
108 | static void at91_nand_disable(struct at91_nand_host *host) | 105 | static void atmel_nand_disable(struct atmel_nand_host *host) |
109 | { | 106 | { |
110 | if (host->board->enable_pin) | 107 | if (host->board->enable_pin) |
111 | at91_set_gpio_value(host->board->enable_pin, 1); | 108 | gpio_set_value(host->board->enable_pin, 1); |
112 | } | 109 | } |
113 | 110 | ||
114 | /* | 111 | /* |
115 | * Hardware specific access to control-lines | 112 | * Hardware specific access to control-lines |
116 | */ | 113 | */ |
117 | static void at91_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 114 | static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
118 | { | 115 | { |
119 | struct nand_chip *nand_chip = mtd->priv; | 116 | struct nand_chip *nand_chip = mtd->priv; |
120 | struct at91_nand_host *host = nand_chip->priv; | 117 | struct atmel_nand_host *host = nand_chip->priv; |
121 | 118 | ||
122 | if (ctrl & NAND_CTRL_CHANGE) { | 119 | if (ctrl & NAND_CTRL_CHANGE) { |
123 | if (ctrl & NAND_NCE) | 120 | if (ctrl & NAND_NCE) |
124 | at91_nand_enable(host); | 121 | atmel_nand_enable(host); |
125 | else | 122 | else |
126 | at91_nand_disable(host); | 123 | atmel_nand_disable(host); |
127 | } | 124 | } |
128 | if (cmd == NAND_CMD_NONE) | 125 | if (cmd == NAND_CMD_NONE) |
129 | return; | 126 | return; |
@@ -137,18 +134,49 @@ static void at91_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | |||
137 | /* | 134 | /* |
138 | * Read the Device Ready pin. | 135 | * Read the Device Ready pin. |
139 | */ | 136 | */ |
140 | static int at91_nand_device_ready(struct mtd_info *mtd) | 137 | static int atmel_nand_device_ready(struct mtd_info *mtd) |
141 | { | 138 | { |
142 | struct nand_chip *nand_chip = mtd->priv; | 139 | struct nand_chip *nand_chip = mtd->priv; |
143 | struct at91_nand_host *host = nand_chip->priv; | 140 | struct atmel_nand_host *host = nand_chip->priv; |
144 | 141 | ||
145 | return at91_get_gpio_value(host->board->rdy_pin); | 142 | return gpio_get_value(host->board->rdy_pin); |
143 | } | ||
144 | |||
145 | /* | ||
146 | * Minimal-overhead PIO for data access. | ||
147 | */ | ||
148 | static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) | ||
149 | { | ||
150 | struct nand_chip *nand_chip = mtd->priv; | ||
151 | |||
152 | __raw_readsb(nand_chip->IO_ADDR_R, buf, len); | ||
153 | } | ||
154 | |||
155 | static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len) | ||
156 | { | ||
157 | struct nand_chip *nand_chip = mtd->priv; | ||
158 | |||
159 | __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2); | ||
160 | } | ||
161 | |||
162 | static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len) | ||
163 | { | ||
164 | struct nand_chip *nand_chip = mtd->priv; | ||
165 | |||
166 | __raw_writesb(nand_chip->IO_ADDR_W, buf, len); | ||
167 | } | ||
168 | |||
169 | static void atmel_write_buf16(struct mtd_info *mtd, const u8 *buf, int len) | ||
170 | { | ||
171 | struct nand_chip *nand_chip = mtd->priv; | ||
172 | |||
173 | __raw_writesw(nand_chip->IO_ADDR_W, buf, len / 2); | ||
146 | } | 174 | } |
147 | 175 | ||
148 | /* | 176 | /* |
149 | * write oob for small pages | 177 | * write oob for small pages |
150 | */ | 178 | */ |
151 | static int at91_nand_write_oob_512(struct mtd_info *mtd, | 179 | static int atmel_nand_write_oob_512(struct mtd_info *mtd, |
152 | struct nand_chip *chip, int page) | 180 | struct nand_chip *chip, int page) |
153 | { | 181 | { |
154 | int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; | 182 | int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; |
@@ -176,7 +204,7 @@ static int at91_nand_write_oob_512(struct mtd_info *mtd, | |||
176 | /* | 204 | /* |
177 | * read oob for small pages | 205 | * read oob for small pages |
178 | */ | 206 | */ |
179 | static int at91_nand_read_oob_512(struct mtd_info *mtd, | 207 | static int atmel_nand_read_oob_512(struct mtd_info *mtd, |
180 | struct nand_chip *chip, int page, int sndcmd) | 208 | struct nand_chip *chip, int page, int sndcmd) |
181 | { | 209 | { |
182 | if (sndcmd) { | 210 | if (sndcmd) { |
@@ -196,11 +224,11 @@ static int at91_nand_read_oob_512(struct mtd_info *mtd, | |||
196 | * dat: raw data (unused) | 224 | * dat: raw data (unused) |
197 | * ecc_code: buffer for ECC | 225 | * ecc_code: buffer for ECC |
198 | */ | 226 | */ |
199 | static int at91_nand_calculate(struct mtd_info *mtd, | 227 | static int atmel_nand_calculate(struct mtd_info *mtd, |
200 | const u_char *dat, unsigned char *ecc_code) | 228 | const u_char *dat, unsigned char *ecc_code) |
201 | { | 229 | { |
202 | struct nand_chip *nand_chip = mtd->priv; | 230 | struct nand_chip *nand_chip = mtd->priv; |
203 | struct at91_nand_host *host = nand_chip->priv; | 231 | struct atmel_nand_host *host = nand_chip->priv; |
204 | uint32_t *eccpos = nand_chip->ecc.layout->eccpos; | 232 | uint32_t *eccpos = nand_chip->ecc.layout->eccpos; |
205 | unsigned int ecc_value; | 233 | unsigned int ecc_value; |
206 | 234 | ||
@@ -211,7 +239,7 @@ static int at91_nand_calculate(struct mtd_info *mtd, | |||
211 | ecc_code[eccpos[1]] = (ecc_value >> 8) & 0xFF; | 239 | ecc_code[eccpos[1]] = (ecc_value >> 8) & 0xFF; |
212 | 240 | ||
213 | /* get the last 2 ECC bytes */ | 241 | /* get the last 2 ECC bytes */ |
214 | ecc_value = ecc_readl(host->ecc, NPR) & AT91_ECC_NPARITY; | 242 | ecc_value = ecc_readl(host->ecc, NPR) & ATMEL_ECC_NPARITY; |
215 | 243 | ||
216 | ecc_code[eccpos[2]] = ecc_value & 0xFF; | 244 | ecc_code[eccpos[2]] = ecc_value & 0xFF; |
217 | ecc_code[eccpos[3]] = (ecc_value >> 8) & 0xFF; | 245 | ecc_code[eccpos[3]] = (ecc_value >> 8) & 0xFF; |
@@ -226,7 +254,7 @@ static int at91_nand_calculate(struct mtd_info *mtd, | |||
226 | * chip: nand chip info structure | 254 | * chip: nand chip info structure |
227 | * buf: buffer to store read data | 255 | * buf: buffer to store read data |
228 | */ | 256 | */ |
229 | static int at91_nand_read_page(struct mtd_info *mtd, | 257 | static int atmel_nand_read_page(struct mtd_info *mtd, |
230 | struct nand_chip *chip, uint8_t *buf) | 258 | struct nand_chip *chip, uint8_t *buf) |
231 | { | 259 | { |
232 | int eccsize = chip->ecc.size; | 260 | int eccsize = chip->ecc.size; |
@@ -237,6 +265,19 @@ static int at91_nand_read_page(struct mtd_info *mtd, | |||
237 | uint8_t *ecc_pos; | 265 | uint8_t *ecc_pos; |
238 | int stat; | 266 | int stat; |
239 | 267 | ||
268 | /* | ||
269 | * Errata: ALE is incorrectly wired up to the ECC controller | ||
270 | * on the AP7000, so it will include the address cycles in the | ||
271 | * ECC calculation. | ||
272 | * | ||
273 | * Workaround: Reset the parity registers before reading the | ||
274 | * actual data. | ||
275 | */ | ||
276 | if (cpu_is_at32ap7000()) { | ||
277 | struct atmel_nand_host *host = chip->priv; | ||
278 | ecc_writel(host->ecc, CR, ATMEL_ECC_RST); | ||
279 | } | ||
280 | |||
240 | /* read the page */ | 281 | /* read the page */ |
241 | chip->read_buf(mtd, p, eccsize); | 282 | chip->read_buf(mtd, p, eccsize); |
242 | 283 | ||
@@ -285,11 +326,11 @@ static int at91_nand_read_page(struct mtd_info *mtd, | |||
285 | * | 326 | * |
286 | * Detect and correct a 1 bit error for a page | 327 | * Detect and correct a 1 bit error for a page |
287 | */ | 328 | */ |
288 | static int at91_nand_correct(struct mtd_info *mtd, u_char *dat, | 329 | static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, |
289 | u_char *read_ecc, u_char *isnull) | 330 | u_char *read_ecc, u_char *isnull) |
290 | { | 331 | { |
291 | struct nand_chip *nand_chip = mtd->priv; | 332 | struct nand_chip *nand_chip = mtd->priv; |
292 | struct at91_nand_host *host = nand_chip->priv; | 333 | struct atmel_nand_host *host = nand_chip->priv; |
293 | unsigned int ecc_status; | 334 | unsigned int ecc_status; |
294 | unsigned int ecc_word, ecc_bit; | 335 | unsigned int ecc_word, ecc_bit; |
295 | 336 | ||
@@ -297,43 +338,43 @@ static int at91_nand_correct(struct mtd_info *mtd, u_char *dat, | |||
297 | ecc_status = ecc_readl(host->ecc, SR); | 338 | ecc_status = ecc_readl(host->ecc, SR); |
298 | 339 | ||
299 | /* if there's no error */ | 340 | /* if there's no error */ |
300 | if (likely(!(ecc_status & AT91_ECC_RECERR))) | 341 | if (likely(!(ecc_status & ATMEL_ECC_RECERR))) |
301 | return 0; | 342 | return 0; |
302 | 343 | ||
303 | /* get error bit offset (4 bits) */ | 344 | /* get error bit offset (4 bits) */ |
304 | ecc_bit = ecc_readl(host->ecc, PR) & AT91_ECC_BITADDR; | 345 | ecc_bit = ecc_readl(host->ecc, PR) & ATMEL_ECC_BITADDR; |
305 | /* get word address (12 bits) */ | 346 | /* get word address (12 bits) */ |
306 | ecc_word = ecc_readl(host->ecc, PR) & AT91_ECC_WORDADDR; | 347 | ecc_word = ecc_readl(host->ecc, PR) & ATMEL_ECC_WORDADDR; |
307 | ecc_word >>= 4; | 348 | ecc_word >>= 4; |
308 | 349 | ||
309 | /* if there are multiple errors */ | 350 | /* if there are multiple errors */ |
310 | if (ecc_status & AT91_ECC_MULERR) { | 351 | if (ecc_status & ATMEL_ECC_MULERR) { |
311 | /* check if it is a freshly erased block | 352 | /* check if it is a freshly erased block |
312 | * (filled with 0xff) */ | 353 | * (filled with 0xff) */ |
313 | if ((ecc_bit == AT91_ECC_BITADDR) | 354 | if ((ecc_bit == ATMEL_ECC_BITADDR) |
314 | && (ecc_word == (AT91_ECC_WORDADDR >> 4))) { | 355 | && (ecc_word == (ATMEL_ECC_WORDADDR >> 4))) { |
315 | /* the block has just been erased, return OK */ | 356 | /* the block has just been erased, return OK */ |
316 | return 0; | 357 | return 0; |
317 | } | 358 | } |
318 | /* it doesn't seems to be a freshly | 359 | /* it doesn't seems to be a freshly |
319 | * erased block. | 360 | * erased block. |
320 | * We can't correct so many errors */ | 361 | * We can't correct so many errors */ |
321 | dev_dbg(host->dev, "at91_nand : multiple errors detected." | 362 | dev_dbg(host->dev, "atmel_nand : multiple errors detected." |
322 | " Unable to correct.\n"); | 363 | " Unable to correct.\n"); |
323 | return -EIO; | 364 | return -EIO; |
324 | } | 365 | } |
325 | 366 | ||
326 | /* if there's a single bit error : we can correct it */ | 367 | /* if there's a single bit error : we can correct it */ |
327 | if (ecc_status & AT91_ECC_ECCERR) { | 368 | if (ecc_status & ATMEL_ECC_ECCERR) { |
328 | /* there's nothing much to do here. | 369 | /* there's nothing much to do here. |
329 | * the bit error is on the ECC itself. | 370 | * the bit error is on the ECC itself. |
330 | */ | 371 | */ |
331 | dev_dbg(host->dev, "at91_nand : one bit error on ECC code." | 372 | dev_dbg(host->dev, "atmel_nand : one bit error on ECC code." |
332 | " Nothing to correct\n"); | 373 | " Nothing to correct\n"); |
333 | return 0; | 374 | return 0; |
334 | } | 375 | } |
335 | 376 | ||
336 | dev_dbg(host->dev, "at91_nand : one bit error on data." | 377 | dev_dbg(host->dev, "atmel_nand : one bit error on data." |
337 | " (word offset in the page :" | 378 | " (word offset in the page :" |
338 | " 0x%x bit offset : 0x%x)\n", | 379 | " 0x%x bit offset : 0x%x)\n", |
339 | ecc_word, ecc_bit); | 380 | ecc_word, ecc_bit); |
@@ -345,14 +386,21 @@ static int at91_nand_correct(struct mtd_info *mtd, u_char *dat, | |||
345 | /* 8 bits words */ | 386 | /* 8 bits words */ |
346 | dat[ecc_word] ^= (1 << ecc_bit); | 387 | dat[ecc_word] ^= (1 << ecc_bit); |
347 | } | 388 | } |
348 | dev_dbg(host->dev, "at91_nand : error corrected\n"); | 389 | dev_dbg(host->dev, "atmel_nand : error corrected\n"); |
349 | return 1; | 390 | return 1; |
350 | } | 391 | } |
351 | 392 | ||
352 | /* | 393 | /* |
353 | * Enable HW ECC : unsused | 394 | * Enable HW ECC : unused on most chips |
354 | */ | 395 | */ |
355 | static void at91_nand_hwctl(struct mtd_info *mtd, int mode) { ; } | 396 | static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) |
397 | { | ||
398 | if (cpu_is_at32ap7000()) { | ||
399 | struct nand_chip *nand_chip = mtd->priv; | ||
400 | struct atmel_nand_host *host = nand_chip->priv; | ||
401 | ecc_writel(host->ecc, CR, ATMEL_ECC_RST); | ||
402 | } | ||
403 | } | ||
356 | 404 | ||
357 | #ifdef CONFIG_MTD_PARTITIONS | 405 | #ifdef CONFIG_MTD_PARTITIONS |
358 | static const char *part_probes[] = { "cmdlinepart", NULL }; | 406 | static const char *part_probes[] = { "cmdlinepart", NULL }; |
@@ -361,9 +409,9 @@ static const char *part_probes[] = { "cmdlinepart", NULL }; | |||
361 | /* | 409 | /* |
362 | * Probe for the NAND device. | 410 | * Probe for the NAND device. |
363 | */ | 411 | */ |
364 | static int __init at91_nand_probe(struct platform_device *pdev) | 412 | static int __init atmel_nand_probe(struct platform_device *pdev) |
365 | { | 413 | { |
366 | struct at91_nand_host *host; | 414 | struct atmel_nand_host *host; |
367 | struct mtd_info *mtd; | 415 | struct mtd_info *mtd; |
368 | struct nand_chip *nand_chip; | 416 | struct nand_chip *nand_chip; |
369 | struct resource *regs; | 417 | struct resource *regs; |
@@ -375,24 +423,24 @@ static int __init at91_nand_probe(struct platform_device *pdev) | |||
375 | int num_partitions = 0; | 423 | int num_partitions = 0; |
376 | #endif | 424 | #endif |
377 | 425 | ||
378 | /* Allocate memory for the device structure (and zero it) */ | ||
379 | host = kzalloc(sizeof(struct at91_nand_host), GFP_KERNEL); | ||
380 | if (!host) { | ||
381 | printk(KERN_ERR "at91_nand: failed to allocate device structure.\n"); | ||
382 | return -ENOMEM; | ||
383 | } | ||
384 | |||
385 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 426 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
386 | if (!mem) { | 427 | if (!mem) { |
387 | printk(KERN_ERR "at91_nand: can't get I/O resource mem\n"); | 428 | printk(KERN_ERR "atmel_nand: can't get I/O resource mem\n"); |
388 | return -ENXIO; | 429 | return -ENXIO; |
389 | } | 430 | } |
390 | 431 | ||
432 | /* Allocate memory for the device structure (and zero it) */ | ||
433 | host = kzalloc(sizeof(struct atmel_nand_host), GFP_KERNEL); | ||
434 | if (!host) { | ||
435 | printk(KERN_ERR "atmel_nand: failed to allocate device structure.\n"); | ||
436 | return -ENOMEM; | ||
437 | } | ||
438 | |||
391 | host->io_base = ioremap(mem->start, mem->end - mem->start + 1); | 439 | host->io_base = ioremap(mem->start, mem->end - mem->start + 1); |
392 | if (host->io_base == NULL) { | 440 | if (host->io_base == NULL) { |
393 | printk(KERN_ERR "at91_nand: ioremap failed\n"); | 441 | printk(KERN_ERR "atmel_nand: ioremap failed\n"); |
394 | kfree(host); | 442 | res = -EIO; |
395 | return -EIO; | 443 | goto err_nand_ioremap; |
396 | } | 444 | } |
397 | 445 | ||
398 | mtd = &host->mtd; | 446 | mtd = &host->mtd; |
@@ -407,14 +455,14 @@ static int __init at91_nand_probe(struct platform_device *pdev) | |||
407 | /* Set address of NAND IO lines */ | 455 | /* Set address of NAND IO lines */ |
408 | nand_chip->IO_ADDR_R = host->io_base; | 456 | nand_chip->IO_ADDR_R = host->io_base; |
409 | nand_chip->IO_ADDR_W = host->io_base; | 457 | nand_chip->IO_ADDR_W = host->io_base; |
410 | nand_chip->cmd_ctrl = at91_nand_cmd_ctrl; | 458 | nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl; |
411 | 459 | ||
412 | if (host->board->rdy_pin) | 460 | if (host->board->rdy_pin) |
413 | nand_chip->dev_ready = at91_nand_device_ready; | 461 | nand_chip->dev_ready = atmel_nand_device_ready; |
414 | 462 | ||
415 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 463 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
416 | if (!regs && hard_ecc) { | 464 | if (!regs && hard_ecc) { |
417 | printk(KERN_ERR "at91_nand: can't get I/O resource " | 465 | printk(KERN_ERR "atmel_nand: can't get I/O resource " |
418 | "regs\nFalling back on software ECC\n"); | 466 | "regs\nFalling back on software ECC\n"); |
419 | } | 467 | } |
420 | 468 | ||
@@ -424,15 +472,15 @@ static int __init at91_nand_probe(struct platform_device *pdev) | |||
424 | if (hard_ecc && regs) { | 472 | if (hard_ecc && regs) { |
425 | host->ecc = ioremap(regs->start, regs->end - regs->start + 1); | 473 | host->ecc = ioremap(regs->start, regs->end - regs->start + 1); |
426 | if (host->ecc == NULL) { | 474 | if (host->ecc == NULL) { |
427 | printk(KERN_ERR "at91_nand: ioremap failed\n"); | 475 | printk(KERN_ERR "atmel_nand: ioremap failed\n"); |
428 | res = -EIO; | 476 | res = -EIO; |
429 | goto err_ecc_ioremap; | 477 | goto err_ecc_ioremap; |
430 | } | 478 | } |
431 | nand_chip->ecc.mode = NAND_ECC_HW_SYNDROME; | 479 | nand_chip->ecc.mode = NAND_ECC_HW_SYNDROME; |
432 | nand_chip->ecc.calculate = at91_nand_calculate; | 480 | nand_chip->ecc.calculate = atmel_nand_calculate; |
433 | nand_chip->ecc.correct = at91_nand_correct; | 481 | nand_chip->ecc.correct = atmel_nand_correct; |
434 | nand_chip->ecc.hwctl = at91_nand_hwctl; | 482 | nand_chip->ecc.hwctl = atmel_nand_hwctl; |
435 | nand_chip->ecc.read_page = at91_nand_read_page; | 483 | nand_chip->ecc.read_page = atmel_nand_read_page; |
436 | nand_chip->ecc.bytes = 4; | 484 | nand_chip->ecc.bytes = 4; |
437 | nand_chip->ecc.prepad = 0; | 485 | nand_chip->ecc.prepad = 0; |
438 | nand_chip->ecc.postpad = 0; | 486 | nand_chip->ecc.postpad = 0; |
@@ -440,24 +488,30 @@ static int __init at91_nand_probe(struct platform_device *pdev) | |||
440 | 488 | ||
441 | nand_chip->chip_delay = 20; /* 20us command delay time */ | 489 | nand_chip->chip_delay = 20; /* 20us command delay time */ |
442 | 490 | ||
443 | if (host->board->bus_width_16) /* 16-bit bus width */ | 491 | if (host->board->bus_width_16) { /* 16-bit bus width */ |
444 | nand_chip->options |= NAND_BUSWIDTH_16; | 492 | nand_chip->options |= NAND_BUSWIDTH_16; |
493 | nand_chip->read_buf = atmel_read_buf16; | ||
494 | nand_chip->write_buf = atmel_write_buf16; | ||
495 | } else { | ||
496 | nand_chip->read_buf = atmel_read_buf; | ||
497 | nand_chip->write_buf = atmel_write_buf; | ||
498 | } | ||
445 | 499 | ||
446 | platform_set_drvdata(pdev, host); | 500 | platform_set_drvdata(pdev, host); |
447 | at91_nand_enable(host); | 501 | atmel_nand_enable(host); |
448 | 502 | ||
449 | if (host->board->det_pin) { | 503 | if (host->board->det_pin) { |
450 | if (at91_get_gpio_value(host->board->det_pin)) { | 504 | if (gpio_get_value(host->board->det_pin)) { |
451 | printk ("No SmartMedia card inserted.\n"); | 505 | printk("No SmartMedia card inserted.\n"); |
452 | res = ENXIO; | 506 | res = ENXIO; |
453 | goto out; | 507 | goto err_no_card; |
454 | } | 508 | } |
455 | } | 509 | } |
456 | 510 | ||
457 | /* first scan to find the device and get the page size */ | 511 | /* first scan to find the device and get the page size */ |
458 | if (nand_scan_ident(mtd, 1)) { | 512 | if (nand_scan_ident(mtd, 1)) { |
459 | res = -ENXIO; | 513 | res = -ENXIO; |
460 | goto out; | 514 | goto err_scan_ident; |
461 | } | 515 | } |
462 | 516 | ||
463 | if (nand_chip->ecc.mode == NAND_ECC_HW_SYNDROME) { | 517 | if (nand_chip->ecc.mode == NAND_ECC_HW_SYNDROME) { |
@@ -467,22 +521,22 @@ static int __init at91_nand_probe(struct platform_device *pdev) | |||
467 | /* set ECC page size and oob layout */ | 521 | /* set ECC page size and oob layout */ |
468 | switch (mtd->writesize) { | 522 | switch (mtd->writesize) { |
469 | case 512: | 523 | case 512: |
470 | nand_chip->ecc.layout = &at91_oobinfo_small; | 524 | nand_chip->ecc.layout = &atmel_oobinfo_small; |
471 | nand_chip->ecc.read_oob = at91_nand_read_oob_512; | 525 | nand_chip->ecc.read_oob = atmel_nand_read_oob_512; |
472 | nand_chip->ecc.write_oob = at91_nand_write_oob_512; | 526 | nand_chip->ecc.write_oob = atmel_nand_write_oob_512; |
473 | ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_528); | 527 | ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_528); |
474 | break; | 528 | break; |
475 | case 1024: | 529 | case 1024: |
476 | nand_chip->ecc.layout = &at91_oobinfo_large; | 530 | nand_chip->ecc.layout = &atmel_oobinfo_large; |
477 | ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_1056); | 531 | ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_1056); |
478 | break; | 532 | break; |
479 | case 2048: | 533 | case 2048: |
480 | nand_chip->ecc.layout = &at91_oobinfo_large; | 534 | nand_chip->ecc.layout = &atmel_oobinfo_large; |
481 | ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_2112); | 535 | ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_2112); |
482 | break; | 536 | break; |
483 | case 4096: | 537 | case 4096: |
484 | nand_chip->ecc.layout = &at91_oobinfo_large; | 538 | nand_chip->ecc.layout = &atmel_oobinfo_large; |
485 | ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_4224); | 539 | ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_4224); |
486 | break; | 540 | break; |
487 | default: | 541 | default: |
488 | /* page size not handled by HW ECC */ | 542 | /* page size not handled by HW ECC */ |
@@ -502,12 +556,12 @@ static int __init at91_nand_probe(struct platform_device *pdev) | |||
502 | /* second phase scan */ | 556 | /* second phase scan */ |
503 | if (nand_scan_tail(mtd)) { | 557 | if (nand_scan_tail(mtd)) { |
504 | res = -ENXIO; | 558 | res = -ENXIO; |
505 | goto out; | 559 | goto err_scan_tail; |
506 | } | 560 | } |
507 | 561 | ||
508 | #ifdef CONFIG_MTD_PARTITIONS | 562 | #ifdef CONFIG_MTD_PARTITIONS |
509 | #ifdef CONFIG_MTD_CMDLINE_PARTS | 563 | #ifdef CONFIG_MTD_CMDLINE_PARTS |
510 | mtd->name = "at91_nand"; | 564 | mtd->name = "atmel_nand"; |
511 | num_partitions = parse_mtd_partitions(mtd, part_probes, | 565 | num_partitions = parse_mtd_partitions(mtd, part_probes, |
512 | &partitions, 0); | 566 | &partitions, 0); |
513 | #endif | 567 | #endif |
@@ -516,9 +570,9 @@ static int __init at91_nand_probe(struct platform_device *pdev) | |||
516 | &num_partitions); | 570 | &num_partitions); |
517 | 571 | ||
518 | if ((!partitions) || (num_partitions == 0)) { | 572 | if ((!partitions) || (num_partitions == 0)) { |
519 | printk(KERN_ERR "at91_nand: No parititions defined, or unsupported device.\n"); | 573 | printk(KERN_ERR "atmel_nand: No parititions defined, or unsupported device.\n"); |
520 | res = ENXIO; | 574 | res = ENXIO; |
521 | goto release; | 575 | goto err_no_partitions; |
522 | } | 576 | } |
523 | 577 | ||
524 | res = add_mtd_partitions(mtd, partitions, num_partitions); | 578 | res = add_mtd_partitions(mtd, partitions, num_partitions); |
@@ -530,17 +584,19 @@ static int __init at91_nand_probe(struct platform_device *pdev) | |||
530 | return res; | 584 | return res; |
531 | 585 | ||
532 | #ifdef CONFIG_MTD_PARTITIONS | 586 | #ifdef CONFIG_MTD_PARTITIONS |
533 | release: | 587 | err_no_partitions: |
534 | #endif | 588 | #endif |
535 | nand_release(mtd); | 589 | nand_release(mtd); |
536 | 590 | err_scan_tail: | |
537 | out: | 591 | err_scan_ident: |
538 | iounmap(host->ecc); | 592 | err_no_card: |
539 | 593 | atmel_nand_disable(host); | |
540 | err_ecc_ioremap: | ||
541 | at91_nand_disable(host); | ||
542 | platform_set_drvdata(pdev, NULL); | 594 | platform_set_drvdata(pdev, NULL); |
595 | if (host->ecc) | ||
596 | iounmap(host->ecc); | ||
597 | err_ecc_ioremap: | ||
543 | iounmap(host->io_base); | 598 | iounmap(host->io_base); |
599 | err_nand_ioremap: | ||
544 | kfree(host); | 600 | kfree(host); |
545 | return res; | 601 | return res; |
546 | } | 602 | } |
@@ -548,47 +604,47 @@ err_ecc_ioremap: | |||
548 | /* | 604 | /* |
549 | * Remove a NAND device. | 605 | * Remove a NAND device. |
550 | */ | 606 | */ |
551 | static int __devexit at91_nand_remove(struct platform_device *pdev) | 607 | static int __exit atmel_nand_remove(struct platform_device *pdev) |
552 | { | 608 | { |
553 | struct at91_nand_host *host = platform_get_drvdata(pdev); | 609 | struct atmel_nand_host *host = platform_get_drvdata(pdev); |
554 | struct mtd_info *mtd = &host->mtd; | 610 | struct mtd_info *mtd = &host->mtd; |
555 | 611 | ||
556 | nand_release(mtd); | 612 | nand_release(mtd); |
557 | 613 | ||
558 | at91_nand_disable(host); | 614 | atmel_nand_disable(host); |
559 | 615 | ||
616 | if (host->ecc) | ||
617 | iounmap(host->ecc); | ||
560 | iounmap(host->io_base); | 618 | iounmap(host->io_base); |
561 | iounmap(host->ecc); | ||
562 | kfree(host); | 619 | kfree(host); |
563 | 620 | ||
564 | return 0; | 621 | return 0; |
565 | } | 622 | } |
566 | 623 | ||
567 | static struct platform_driver at91_nand_driver = { | 624 | static struct platform_driver atmel_nand_driver = { |
568 | .probe = at91_nand_probe, | 625 | .remove = __exit_p(atmel_nand_remove), |
569 | .remove = at91_nand_remove, | ||
570 | .driver = { | 626 | .driver = { |
571 | .name = "at91_nand", | 627 | .name = "atmel_nand", |
572 | .owner = THIS_MODULE, | 628 | .owner = THIS_MODULE, |
573 | }, | 629 | }, |
574 | }; | 630 | }; |
575 | 631 | ||
576 | static int __init at91_nand_init(void) | 632 | static int __init atmel_nand_init(void) |
577 | { | 633 | { |
578 | return platform_driver_register(&at91_nand_driver); | 634 | return platform_driver_probe(&atmel_nand_driver, atmel_nand_probe); |
579 | } | 635 | } |
580 | 636 | ||
581 | 637 | ||
582 | static void __exit at91_nand_exit(void) | 638 | static void __exit atmel_nand_exit(void) |
583 | { | 639 | { |
584 | platform_driver_unregister(&at91_nand_driver); | 640 | platform_driver_unregister(&atmel_nand_driver); |
585 | } | 641 | } |
586 | 642 | ||
587 | 643 | ||
588 | module_init(at91_nand_init); | 644 | module_init(atmel_nand_init); |
589 | module_exit(at91_nand_exit); | 645 | module_exit(atmel_nand_exit); |
590 | 646 | ||
591 | MODULE_LICENSE("GPL"); | 647 | MODULE_LICENSE("GPL"); |
592 | MODULE_AUTHOR("Rick Bronson"); | 648 | MODULE_AUTHOR("Rick Bronson"); |
593 | MODULE_DESCRIPTION("NAND/SmartMedia driver for AT91RM9200 / AT91SAM9"); | 649 | MODULE_DESCRIPTION("NAND/SmartMedia driver for AT91 / AVR32"); |
594 | MODULE_ALIAS("platform:at91_nand"); | 650 | MODULE_ALIAS("platform:atmel_nand"); |
diff --git a/drivers/mtd/nand/atmel_nand_ecc.h b/drivers/mtd/nand/atmel_nand_ecc.h new file mode 100644 index 000000000000..1ee7f993db1c --- /dev/null +++ b/drivers/mtd/nand/atmel_nand_ecc.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * Error Corrected Code Controller (ECC) - System peripherals regsters. | ||
3 | * Based on AT91SAM9260 datasheet revision B. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | */ | ||
10 | |||
11 | #ifndef ATMEL_NAND_ECC_H | ||
12 | #define ATMEL_NAND_ECC_H | ||
13 | |||
14 | #define ATMEL_ECC_CR 0x00 /* Control register */ | ||
15 | #define ATMEL_ECC_RST (1 << 0) /* Reset parity */ | ||
16 | |||
17 | #define ATMEL_ECC_MR 0x04 /* Mode register */ | ||
18 | #define ATMEL_ECC_PAGESIZE (3 << 0) /* Page Size */ | ||
19 | #define ATMEL_ECC_PAGESIZE_528 (0) | ||
20 | #define ATMEL_ECC_PAGESIZE_1056 (1) | ||
21 | #define ATMEL_ECC_PAGESIZE_2112 (2) | ||
22 | #define ATMEL_ECC_PAGESIZE_4224 (3) | ||
23 | |||
24 | #define ATMEL_ECC_SR 0x08 /* Status register */ | ||
25 | #define ATMEL_ECC_RECERR (1 << 0) /* Recoverable Error */ | ||
26 | #define ATMEL_ECC_ECCERR (1 << 1) /* ECC Single Bit Error */ | ||
27 | #define ATMEL_ECC_MULERR (1 << 2) /* Multiple Errors */ | ||
28 | |||
29 | #define ATMEL_ECC_PR 0x0c /* Parity register */ | ||
30 | #define ATMEL_ECC_BITADDR (0xf << 0) /* Bit Error Address */ | ||
31 | #define ATMEL_ECC_WORDADDR (0xfff << 4) /* Word Error Address */ | ||
32 | |||
33 | #define ATMEL_ECC_NPR 0x10 /* NParity register */ | ||
34 | #define ATMEL_ECC_NPARITY (0xffff << 0) /* NParity */ | ||
35 | |||
36 | #endif | ||
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 09e421a96893..761946ea45b1 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c | |||
@@ -3,8 +3,6 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2004 Embedded Edge, LLC | 4 | * Copyright (C) 2004 Embedded Edge, LLC |
5 | * | 5 | * |
6 | * $Id: au1550nd.c,v 1.13 2005/11/07 11:14:30 gleixner Exp $ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
@@ -604,8 +602,6 @@ module_init(au1xxx_nand_init); | |||
604 | */ | 602 | */ |
605 | static void __exit au1550_cleanup(void) | 603 | static void __exit au1550_cleanup(void) |
606 | { | 604 | { |
607 | struct nand_chip *this = (struct nand_chip *)&au1550_mtd[1]; | ||
608 | |||
609 | /* Release resources, unregister device */ | 605 | /* Release resources, unregister device */ |
610 | nand_release(au1550_mtd); | 606 | nand_release(au1550_mtd); |
611 | 607 | ||
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c index dd38011ee0b7..553dd7e9b41c 100644 --- a/drivers/mtd/nand/autcpu12.c +++ b/drivers/mtd/nand/autcpu12.c | |||
@@ -6,8 +6,6 @@ | |||
6 | * Derived from drivers/mtd/spia.c | 6 | * Derived from drivers/mtd/spia.c |
7 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) | 7 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) |
8 | * | 8 | * |
9 | * $Id: autcpu12.c,v 1.23 2005/11/07 11:14:30 gleixner Exp $ | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
13 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index da6ceaa80ba1..95345d051579 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c | |||
@@ -626,10 +626,12 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, | |||
626 | { | 626 | { |
627 | struct mtd_info *mtd; | 627 | struct mtd_info *mtd; |
628 | struct cafe_priv *cafe; | 628 | struct cafe_priv *cafe; |
629 | struct mtd_partition *parts; | ||
630 | uint32_t ctrl; | 629 | uint32_t ctrl; |
631 | int nr_parts; | ||
632 | int err = 0; | 630 | int err = 0; |
631 | #ifdef CONFIG_MTD_PARTITIONS | ||
632 | struct mtd_partition *parts; | ||
633 | int nr_parts; | ||
634 | #endif | ||
633 | 635 | ||
634 | /* Very old versions shared the same PCI ident for all three | 636 | /* Very old versions shared the same PCI ident for all three |
635 | functions on the chip. Verify the class too... */ | 637 | functions on the chip. Verify the class too... */ |
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index 0e72153b3297..765d4f0f7c86 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c | |||
@@ -15,8 +15,6 @@ | |||
15 | * converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de> | 15 | * converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de> |
16 | * | 16 | * |
17 | * Interface to generic NAND code for M-Systems DiskOnChip devices | 17 | * Interface to generic NAND code for M-Systems DiskOnChip devices |
18 | * | ||
19 | * $Id: diskonchip.c,v 1.55 2005/11/07 11:14:30 gleixner Exp $ | ||
20 | */ | 18 | */ |
21 | 19 | ||
22 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
@@ -54,8 +52,6 @@ static unsigned long __initdata doc_locations[] = { | |||
54 | 0xe0000, 0xe2000, 0xe4000, 0xe6000, | 52 | 0xe0000, 0xe2000, 0xe4000, 0xe6000, |
55 | 0xe8000, 0xea000, 0xec000, 0xee000, | 53 | 0xe8000, 0xea000, 0xec000, 0xee000, |
56 | #endif /* CONFIG_MTD_DOCPROBE_HIGH */ | 54 | #endif /* CONFIG_MTD_DOCPROBE_HIGH */ |
57 | #elif defined(__PPC__) | ||
58 | 0xe4000000, | ||
59 | #else | 55 | #else |
60 | #warning Unknown architecture for DiskOnChip. No default probe locations defined | 56 | #warning Unknown architecture for DiskOnChip. No default probe locations defined |
61 | #endif | 57 | #endif |
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c index ba67bbec20d3..387e4352903e 100644 --- a/drivers/mtd/nand/edb7312.c +++ b/drivers/mtd/nand/edb7312.c | |||
@@ -6,8 +6,6 @@ | |||
6 | * Derived from drivers/mtd/nand/autcpu12.c | 6 | * Derived from drivers/mtd/nand/autcpu12.c |
7 | * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) | 7 | * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) |
8 | * | 8 | * |
9 | * $Id: edb7312.c,v 1.12 2005/11/07 11:14:30 gleixner Exp $ | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
13 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
diff --git a/drivers/mtd/nand/excite_nandflash.c b/drivers/mtd/nand/excite_nandflash.c index bed87290decc..ced14b5294d5 100644 --- a/drivers/mtd/nand/excite_nandflash.c +++ b/drivers/mtd/nand/excite_nandflash.c | |||
@@ -209,7 +209,7 @@ static int __init excite_nand_probe(struct device *dev) | |||
209 | if (likely(!scan_res)) { | 209 | if (likely(!scan_res)) { |
210 | DEBUG(MTD_DEBUG_LEVEL2, "%s: register partitions\n", module_id); | 210 | DEBUG(MTD_DEBUG_LEVEL2, "%s: register partitions\n", module_id); |
211 | add_mtd_partitions(&drvdata->board_mtd, partition_info, | 211 | add_mtd_partitions(&drvdata->board_mtd, partition_info, |
212 | sizeof partition_info / sizeof partition_info[0]); | 212 | ARRAY_SIZE(partition_info)); |
213 | } else { | 213 | } else { |
214 | iounmap(drvdata->regs); | 214 | iounmap(drvdata->regs); |
215 | kfree(drvdata); | 215 | kfree(drvdata); |
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 4b69aacdf5ca..9dff51351f4f 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c | |||
@@ -89,7 +89,6 @@ static struct nand_ecclayout fsl_elbc_oob_sp_eccm0 = { | |||
89 | .eccbytes = 3, | 89 | .eccbytes = 3, |
90 | .eccpos = {6, 7, 8}, | 90 | .eccpos = {6, 7, 8}, |
91 | .oobfree = { {0, 5}, {9, 7} }, | 91 | .oobfree = { {0, 5}, {9, 7} }, |
92 | .oobavail = 12, | ||
93 | }; | 92 | }; |
94 | 93 | ||
95 | /* Small Page FLASH with FMR[ECCM] = 1 */ | 94 | /* Small Page FLASH with FMR[ECCM] = 1 */ |
@@ -97,7 +96,6 @@ static struct nand_ecclayout fsl_elbc_oob_sp_eccm1 = { | |||
97 | .eccbytes = 3, | 96 | .eccbytes = 3, |
98 | .eccpos = {8, 9, 10}, | 97 | .eccpos = {8, 9, 10}, |
99 | .oobfree = { {0, 5}, {6, 2}, {11, 5} }, | 98 | .oobfree = { {0, 5}, {6, 2}, {11, 5} }, |
100 | .oobavail = 12, | ||
101 | }; | 99 | }; |
102 | 100 | ||
103 | /* Large Page FLASH with FMR[ECCM] = 0 */ | 101 | /* Large Page FLASH with FMR[ECCM] = 0 */ |
@@ -105,7 +103,6 @@ static struct nand_ecclayout fsl_elbc_oob_lp_eccm0 = { | |||
105 | .eccbytes = 12, | 103 | .eccbytes = 12, |
106 | .eccpos = {6, 7, 8, 22, 23, 24, 38, 39, 40, 54, 55, 56}, | 104 | .eccpos = {6, 7, 8, 22, 23, 24, 38, 39, 40, 54, 55, 56}, |
107 | .oobfree = { {1, 5}, {9, 13}, {25, 13}, {41, 13}, {57, 7} }, | 105 | .oobfree = { {1, 5}, {9, 13}, {25, 13}, {41, 13}, {57, 7} }, |
108 | .oobavail = 48, | ||
109 | }; | 106 | }; |
110 | 107 | ||
111 | /* Large Page FLASH with FMR[ECCM] = 1 */ | 108 | /* Large Page FLASH with FMR[ECCM] = 1 */ |
@@ -113,7 +110,48 @@ static struct nand_ecclayout fsl_elbc_oob_lp_eccm1 = { | |||
113 | .eccbytes = 12, | 110 | .eccbytes = 12, |
114 | .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58}, | 111 | .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58}, |
115 | .oobfree = { {1, 7}, {11, 13}, {27, 13}, {43, 13}, {59, 5} }, | 112 | .oobfree = { {1, 7}, {11, 13}, {27, 13}, {43, 13}, {59, 5} }, |
116 | .oobavail = 48, | 113 | }; |
114 | |||
115 | /* | ||
116 | * fsl_elbc_oob_lp_eccm* specify that LP NAND's OOB free area starts at offset | ||
117 | * 1, so we have to adjust bad block pattern. This pattern should be used for | ||
118 | * x8 chips only. So far hardware does not support x16 chips anyway. | ||
119 | */ | ||
120 | static u8 scan_ff_pattern[] = { 0xff, }; | ||
121 | |||
122 | static struct nand_bbt_descr largepage_memorybased = { | ||
123 | .options = 0, | ||
124 | .offs = 0, | ||
125 | .len = 1, | ||
126 | .pattern = scan_ff_pattern, | ||
127 | }; | ||
128 | |||
129 | /* | ||
130 | * ELBC may use HW ECC, so that OOB offsets, that NAND core uses for bbt, | ||
131 | * interfere with ECC positions, that's why we implement our own descriptors. | ||
132 | * OOB {11, 5}, works for both SP and LP chips, with ECCM = 1 and ECCM = 0. | ||
133 | */ | ||
134 | static u8 bbt_pattern[] = {'B', 'b', 't', '0' }; | ||
135 | static u8 mirror_pattern[] = {'1', 't', 'b', 'B' }; | ||
136 | |||
137 | static struct nand_bbt_descr bbt_main_descr = { | ||
138 | .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | | ||
139 | NAND_BBT_2BIT | NAND_BBT_VERSION, | ||
140 | .offs = 11, | ||
141 | .len = 4, | ||
142 | .veroffs = 15, | ||
143 | .maxblocks = 4, | ||
144 | .pattern = bbt_pattern, | ||
145 | }; | ||
146 | |||
147 | static struct nand_bbt_descr bbt_mirror_descr = { | ||
148 | .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | | ||
149 | NAND_BBT_2BIT | NAND_BBT_VERSION, | ||
150 | .offs = 11, | ||
151 | .len = 4, | ||
152 | .veroffs = 15, | ||
153 | .maxblocks = 4, | ||
154 | .pattern = mirror_pattern, | ||
117 | }; | 155 | }; |
118 | 156 | ||
119 | /*=================================*/ | 157 | /*=================================*/ |
@@ -687,8 +725,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) | |||
687 | chip->ecc.layout = (priv->fmr & FMR_ECCM) ? | 725 | chip->ecc.layout = (priv->fmr & FMR_ECCM) ? |
688 | &fsl_elbc_oob_lp_eccm1 : | 726 | &fsl_elbc_oob_lp_eccm1 : |
689 | &fsl_elbc_oob_lp_eccm0; | 727 | &fsl_elbc_oob_lp_eccm0; |
690 | mtd->ecclayout = chip->ecc.layout; | 728 | chip->badblock_pattern = &largepage_memorybased; |
691 | mtd->oobavail = chip->ecc.layout->oobavail; | ||
692 | } | 729 | } |
693 | } else { | 730 | } else { |
694 | dev_err(ctrl->dev, | 731 | dev_err(ctrl->dev, |
@@ -752,8 +789,12 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) | |||
752 | chip->cmdfunc = fsl_elbc_cmdfunc; | 789 | chip->cmdfunc = fsl_elbc_cmdfunc; |
753 | chip->waitfunc = fsl_elbc_wait; | 790 | chip->waitfunc = fsl_elbc_wait; |
754 | 791 | ||
792 | chip->bbt_td = &bbt_main_descr; | ||
793 | chip->bbt_md = &bbt_mirror_descr; | ||
794 | |||
755 | /* set up nand options */ | 795 | /* set up nand options */ |
756 | chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR; | 796 | chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR | |
797 | NAND_USE_FLASH_BBT; | ||
757 | 798 | ||
758 | chip->controller = &ctrl->controller; | 799 | chip->controller = &ctrl->controller; |
759 | chip->priv = priv; | 800 | chip->priv = priv; |
@@ -795,8 +836,8 @@ static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv) | |||
795 | return 0; | 836 | return 0; |
796 | } | 837 | } |
797 | 838 | ||
798 | static int fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl, | 839 | static int __devinit fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl, |
799 | struct device_node *node) | 840 | struct device_node *node) |
800 | { | 841 | { |
801 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; | 842 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; |
802 | struct fsl_elbc_mtd *priv; | 843 | struct fsl_elbc_mtd *priv; |
@@ -917,7 +958,7 @@ static int __devinit fsl_elbc_ctrl_init(struct fsl_elbc_ctrl *ctrl) | |||
917 | return 0; | 958 | return 0; |
918 | } | 959 | } |
919 | 960 | ||
920 | static int __devexit fsl_elbc_ctrl_remove(struct of_device *ofdev) | 961 | static int fsl_elbc_ctrl_remove(struct of_device *ofdev) |
921 | { | 962 | { |
922 | struct fsl_elbc_ctrl *ctrl = dev_get_drvdata(&ofdev->dev); | 963 | struct fsl_elbc_ctrl *ctrl = dev_get_drvdata(&ofdev->dev); |
923 | int i; | 964 | int i; |
@@ -1041,7 +1082,7 @@ static struct of_platform_driver fsl_elbc_ctrl_driver = { | |||
1041 | }, | 1082 | }, |
1042 | .match_table = fsl_elbc_match, | 1083 | .match_table = fsl_elbc_match, |
1043 | .probe = fsl_elbc_ctrl_probe, | 1084 | .probe = fsl_elbc_ctrl_probe, |
1044 | .remove = __devexit_p(fsl_elbc_ctrl_remove), | 1085 | .remove = fsl_elbc_ctrl_remove, |
1045 | }; | 1086 | }; |
1046 | 1087 | ||
1047 | static int __init fsl_elbc_init(void) | 1088 | static int __init fsl_elbc_init(void) |
diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c index 2d585d2d090c..9e59de501c2e 100644 --- a/drivers/mtd/nand/h1910.c +++ b/drivers/mtd/nand/h1910.c | |||
@@ -7,8 +7,6 @@ | |||
7 | * Copyright (C) 2002 Marius Gröger (mag@sysgo.de) | 7 | * Copyright (C) 2002 Marius Gröger (mag@sysgo.de) |
8 | * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) | 8 | * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) |
9 | * | 9 | * |
10 | * $Id: h1910.c,v 1.6 2005/11/07 11:14:30 gleixner Exp $ | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
14 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index ba1bdf787323..d1129bae6c27 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -798,6 +798,87 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
798 | } | 798 | } |
799 | 799 | ||
800 | /** | 800 | /** |
801 | * nand_read_subpage - [REPLACABLE] software ecc based sub-page read function | ||
802 | * @mtd: mtd info structure | ||
803 | * @chip: nand chip info structure | ||
804 | * @dataofs offset of requested data within the page | ||
805 | * @readlen data length | ||
806 | * @buf: buffer to store read data | ||
807 | */ | ||
808 | static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi) | ||
809 | { | ||
810 | int start_step, end_step, num_steps; | ||
811 | uint32_t *eccpos = chip->ecc.layout->eccpos; | ||
812 | uint8_t *p; | ||
813 | int data_col_addr, i, gaps = 0; | ||
814 | int datafrag_len, eccfrag_len, aligned_len, aligned_pos; | ||
815 | int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1; | ||
816 | |||
817 | /* Column address wihin the page aligned to ECC size (256bytes). */ | ||
818 | start_step = data_offs / chip->ecc.size; | ||
819 | end_step = (data_offs + readlen - 1) / chip->ecc.size; | ||
820 | num_steps = end_step - start_step + 1; | ||
821 | |||
822 | /* Data size aligned to ECC ecc.size*/ | ||
823 | datafrag_len = num_steps * chip->ecc.size; | ||
824 | eccfrag_len = num_steps * chip->ecc.bytes; | ||
825 | |||
826 | data_col_addr = start_step * chip->ecc.size; | ||
827 | /* If we read not a page aligned data */ | ||
828 | if (data_col_addr != 0) | ||
829 | chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_col_addr, -1); | ||
830 | |||
831 | p = bufpoi + data_col_addr; | ||
832 | chip->read_buf(mtd, p, datafrag_len); | ||
833 | |||
834 | /* Calculate ECC */ | ||
835 | for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) | ||
836 | chip->ecc.calculate(mtd, p, &chip->buffers->ecccalc[i]); | ||
837 | |||
838 | /* The performance is faster if to position offsets | ||
839 | according to ecc.pos. Let make sure here that | ||
840 | there are no gaps in ecc positions */ | ||
841 | for (i = 0; i < eccfrag_len - 1; i++) { | ||
842 | if (eccpos[i + start_step * chip->ecc.bytes] + 1 != | ||
843 | eccpos[i + start_step * chip->ecc.bytes + 1]) { | ||
844 | gaps = 1; | ||
845 | break; | ||
846 | } | ||
847 | } | ||
848 | if (gaps) { | ||
849 | chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1); | ||
850 | chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); | ||
851 | } else { | ||
852 | /* send the command to read the particular ecc bytes */ | ||
853 | /* take care about buswidth alignment in read_buf */ | ||
854 | aligned_pos = eccpos[start_step * chip->ecc.bytes] & ~(busw - 1); | ||
855 | aligned_len = eccfrag_len; | ||
856 | if (eccpos[start_step * chip->ecc.bytes] & (busw - 1)) | ||
857 | aligned_len++; | ||
858 | if (eccpos[(start_step + num_steps) * chip->ecc.bytes] & (busw - 1)) | ||
859 | aligned_len++; | ||
860 | |||
861 | chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize + aligned_pos, -1); | ||
862 | chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len); | ||
863 | } | ||
864 | |||
865 | for (i = 0; i < eccfrag_len; i++) | ||
866 | chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + start_step * chip->ecc.bytes]]; | ||
867 | |||
868 | p = bufpoi + data_col_addr; | ||
869 | for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) { | ||
870 | int stat; | ||
871 | |||
872 | stat = chip->ecc.correct(mtd, p, &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]); | ||
873 | if (stat == -1) | ||
874 | mtd->ecc_stats.failed++; | ||
875 | else | ||
876 | mtd->ecc_stats.corrected += stat; | ||
877 | } | ||
878 | return 0; | ||
879 | } | ||
880 | |||
881 | /** | ||
801 | * nand_read_page_hwecc - [REPLACABLE] hardware ecc based page read function | 882 | * nand_read_page_hwecc - [REPLACABLE] hardware ecc based page read function |
802 | * @mtd: mtd info structure | 883 | * @mtd: mtd info structure |
803 | * @chip: nand chip info structure | 884 | * @chip: nand chip info structure |
@@ -994,6 +1075,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
994 | /* Now read the page into the buffer */ | 1075 | /* Now read the page into the buffer */ |
995 | if (unlikely(ops->mode == MTD_OOB_RAW)) | 1076 | if (unlikely(ops->mode == MTD_OOB_RAW)) |
996 | ret = chip->ecc.read_page_raw(mtd, chip, bufpoi); | 1077 | ret = chip->ecc.read_page_raw(mtd, chip, bufpoi); |
1078 | else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob) | ||
1079 | ret = chip->ecc.read_subpage(mtd, chip, col, bytes, bufpoi); | ||
997 | else | 1080 | else |
998 | ret = chip->ecc.read_page(mtd, chip, bufpoi); | 1081 | ret = chip->ecc.read_page(mtd, chip, bufpoi); |
999 | if (ret < 0) | 1082 | if (ret < 0) |
@@ -1001,7 +1084,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
1001 | 1084 | ||
1002 | /* Transfer not aligned data */ | 1085 | /* Transfer not aligned data */ |
1003 | if (!aligned) { | 1086 | if (!aligned) { |
1004 | chip->pagebuf = realpage; | 1087 | if (!NAND_SUBPAGE_READ(chip) && !oob) |
1088 | chip->pagebuf = realpage; | ||
1005 | memcpy(buf, chip->buffers->databuf + col, bytes); | 1089 | memcpy(buf, chip->buffers->databuf + col, bytes); |
1006 | } | 1090 | } |
1007 | 1091 | ||
@@ -2521,6 +2605,7 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
2521 | chip->ecc.calculate = nand_calculate_ecc; | 2605 | chip->ecc.calculate = nand_calculate_ecc; |
2522 | chip->ecc.correct = nand_correct_data; | 2606 | chip->ecc.correct = nand_correct_data; |
2523 | chip->ecc.read_page = nand_read_page_swecc; | 2607 | chip->ecc.read_page = nand_read_page_swecc; |
2608 | chip->ecc.read_subpage = nand_read_subpage; | ||
2524 | chip->ecc.write_page = nand_write_page_swecc; | 2609 | chip->ecc.write_page = nand_write_page_swecc; |
2525 | chip->ecc.read_oob = nand_read_oob_std; | 2610 | chip->ecc.read_oob = nand_read_oob_std; |
2526 | chip->ecc.write_oob = nand_write_oob_std; | 2611 | chip->ecc.write_oob = nand_write_oob_std; |
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 5e121ceaa598..0b1c48595f12 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c | |||
@@ -6,8 +6,6 @@ | |||
6 | * | 6 | * |
7 | * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) | 7 | * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) |
8 | * | 8 | * |
9 | * $Id: nand_bbt.c,v 1.36 2005/11/07 11:14:30 gleixner Exp $ | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
13 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c index 9003a135e050..918a806a8471 100644 --- a/drivers/mtd/nand/nand_ecc.c +++ b/drivers/mtd/nand/nand_ecc.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * | 9 | * |
10 | * Copyright (C) 2006 Thomas Gleixner <tglx@linutronix.de> | 10 | * Copyright (C) 2006 Thomas Gleixner <tglx@linutronix.de> |
11 | * | 11 | * |
12 | * $Id: nand_ecc.c,v 1.15 2005/11/07 11:14:30 gleixner Exp $ | ||
13 | * | ||
14 | * This file is free software; you can redistribute it and/or modify it | 12 | * This file is free software; you can redistribute it and/or modify it |
15 | * under the terms of the GNU General Public License as published by the | 13 | * under the terms of the GNU General Public License as published by the |
16 | * Free Software Foundation; either version 2 or (at your option) any | 14 | * Free Software Foundation; either version 2 or (at your option) any |
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c index a3e3ab0185d5..69ee2c90eb0b 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/nand_ids.c | |||
@@ -3,8 +3,6 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de) | 4 | * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de) |
5 | * | 5 | * |
6 | * $Id: nand_ids.c,v 1.16 2005/11/07 11:14:31 gleixner Exp $ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index bb885d1fcab5..ecd70e2504f6 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c | |||
@@ -21,8 +21,6 @@ | |||
21 | * You should have received a copy of the GNU General Public License | 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 | 22 | * along with this program; if not, write to the Free Software |
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA | 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA |
24 | * | ||
25 | * $Id: nandsim.c,v 1.8 2005/03/19 15:33:56 dedekind Exp $ | ||
26 | */ | 24 | */ |
27 | 25 | ||
28 | #include <linux/init.h> | 26 | #include <linux/init.h> |
@@ -39,6 +37,7 @@ | |||
39 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
40 | #include <linux/list.h> | 38 | #include <linux/list.h> |
41 | #include <linux/random.h> | 39 | #include <linux/random.h> |
40 | #include <asm/div64.h> | ||
42 | 41 | ||
43 | /* Default simulator parameters values */ | 42 | /* Default simulator parameters values */ |
44 | #if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE) || \ | 43 | #if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE) || \ |
@@ -298,11 +297,11 @@ struct nandsim { | |||
298 | 297 | ||
299 | /* NAND flash "geometry" */ | 298 | /* NAND flash "geometry" */ |
300 | struct nandsin_geometry { | 299 | struct nandsin_geometry { |
301 | uint32_t totsz; /* total flash size, bytes */ | 300 | uint64_t totsz; /* total flash size, bytes */ |
302 | uint32_t secsz; /* flash sector (erase block) size, bytes */ | 301 | uint32_t secsz; /* flash sector (erase block) size, bytes */ |
303 | uint pgsz; /* NAND flash page size, bytes */ | 302 | uint pgsz; /* NAND flash page size, bytes */ |
304 | uint oobsz; /* page OOB area size, bytes */ | 303 | uint oobsz; /* page OOB area size, bytes */ |
305 | uint32_t totszoob; /* total flash size including OOB, bytes */ | 304 | uint64_t totszoob; /* total flash size including OOB, bytes */ |
306 | uint pgszoob; /* page size including OOB , bytes*/ | 305 | uint pgszoob; /* page size including OOB , bytes*/ |
307 | uint secszoob; /* sector size including OOB, bytes */ | 306 | uint secszoob; /* sector size including OOB, bytes */ |
308 | uint pgnum; /* total number of pages */ | 307 | uint pgnum; /* total number of pages */ |
@@ -459,6 +458,12 @@ static char *get_partition_name(int i) | |||
459 | return kstrdup(buf, GFP_KERNEL); | 458 | return kstrdup(buf, GFP_KERNEL); |
460 | } | 459 | } |
461 | 460 | ||
461 | static u_int64_t divide(u_int64_t n, u_int32_t d) | ||
462 | { | ||
463 | do_div(n, d); | ||
464 | return n; | ||
465 | } | ||
466 | |||
462 | /* | 467 | /* |
463 | * Initialize the nandsim structure. | 468 | * Initialize the nandsim structure. |
464 | * | 469 | * |
@@ -469,8 +474,8 @@ static int init_nandsim(struct mtd_info *mtd) | |||
469 | struct nand_chip *chip = (struct nand_chip *)mtd->priv; | 474 | struct nand_chip *chip = (struct nand_chip *)mtd->priv; |
470 | struct nandsim *ns = (struct nandsim *)(chip->priv); | 475 | struct nandsim *ns = (struct nandsim *)(chip->priv); |
471 | int i, ret = 0; | 476 | int i, ret = 0; |
472 | u_int32_t remains; | 477 | u_int64_t remains; |
473 | u_int32_t next_offset; | 478 | u_int64_t next_offset; |
474 | 479 | ||
475 | if (NS_IS_INITIALIZED(ns)) { | 480 | if (NS_IS_INITIALIZED(ns)) { |
476 | NS_ERR("init_nandsim: nandsim is already initialized\n"); | 481 | NS_ERR("init_nandsim: nandsim is already initialized\n"); |
@@ -487,8 +492,8 @@ static int init_nandsim(struct mtd_info *mtd) | |||
487 | ns->geom.oobsz = mtd->oobsize; | 492 | ns->geom.oobsz = mtd->oobsize; |
488 | ns->geom.secsz = mtd->erasesize; | 493 | ns->geom.secsz = mtd->erasesize; |
489 | ns->geom.pgszoob = ns->geom.pgsz + ns->geom.oobsz; | 494 | ns->geom.pgszoob = ns->geom.pgsz + ns->geom.oobsz; |
490 | ns->geom.pgnum = ns->geom.totsz / ns->geom.pgsz; | 495 | ns->geom.pgnum = divide(ns->geom.totsz, ns->geom.pgsz); |
491 | ns->geom.totszoob = ns->geom.totsz + ns->geom.pgnum * ns->geom.oobsz; | 496 | ns->geom.totszoob = ns->geom.totsz + (uint64_t)ns->geom.pgnum * ns->geom.oobsz; |
492 | ns->geom.secshift = ffs(ns->geom.secsz) - 1; | 497 | ns->geom.secshift = ffs(ns->geom.secsz) - 1; |
493 | ns->geom.pgshift = chip->page_shift; | 498 | ns->geom.pgshift = chip->page_shift; |
494 | ns->geom.oobshift = ffs(ns->geom.oobsz) - 1; | 499 | ns->geom.oobshift = ffs(ns->geom.oobsz) - 1; |
@@ -511,7 +516,7 @@ static int init_nandsim(struct mtd_info *mtd) | |||
511 | } | 516 | } |
512 | 517 | ||
513 | if (ns->options & OPT_SMALLPAGE) { | 518 | if (ns->options & OPT_SMALLPAGE) { |
514 | if (ns->geom.totsz < (32 << 20)) { | 519 | if (ns->geom.totsz <= (32 << 20)) { |
515 | ns->geom.pgaddrbytes = 3; | 520 | ns->geom.pgaddrbytes = 3; |
516 | ns->geom.secaddrbytes = 2; | 521 | ns->geom.secaddrbytes = 2; |
517 | } else { | 522 | } else { |
@@ -537,15 +542,16 @@ static int init_nandsim(struct mtd_info *mtd) | |||
537 | remains = ns->geom.totsz; | 542 | remains = ns->geom.totsz; |
538 | next_offset = 0; | 543 | next_offset = 0; |
539 | for (i = 0; i < parts_num; ++i) { | 544 | for (i = 0; i < parts_num; ++i) { |
540 | unsigned long part = parts[i]; | 545 | u_int64_t part_sz = (u_int64_t)parts[i] * ns->geom.secsz; |
541 | if (!part || part > remains / ns->geom.secsz) { | 546 | |
547 | if (!part_sz || part_sz > remains) { | ||
542 | NS_ERR("bad partition size.\n"); | 548 | NS_ERR("bad partition size.\n"); |
543 | ret = -EINVAL; | 549 | ret = -EINVAL; |
544 | goto error; | 550 | goto error; |
545 | } | 551 | } |
546 | ns->partitions[i].name = get_partition_name(i); | 552 | ns->partitions[i].name = get_partition_name(i); |
547 | ns->partitions[i].offset = next_offset; | 553 | ns->partitions[i].offset = next_offset; |
548 | ns->partitions[i].size = part * ns->geom.secsz; | 554 | ns->partitions[i].size = part_sz; |
549 | next_offset += ns->partitions[i].size; | 555 | next_offset += ns->partitions[i].size; |
550 | remains -= ns->partitions[i].size; | 556 | remains -= ns->partitions[i].size; |
551 | } | 557 | } |
@@ -573,7 +579,7 @@ static int init_nandsim(struct mtd_info *mtd) | |||
573 | if (ns->busw == 16) | 579 | if (ns->busw == 16) |
574 | NS_WARN("16-bit flashes support wasn't tested\n"); | 580 | NS_WARN("16-bit flashes support wasn't tested\n"); |
575 | 581 | ||
576 | printk("flash size: %u MiB\n", ns->geom.totsz >> 20); | 582 | printk("flash size: %llu MiB\n", ns->geom.totsz >> 20); |
577 | printk("page size: %u bytes\n", ns->geom.pgsz); | 583 | printk("page size: %u bytes\n", ns->geom.pgsz); |
578 | printk("OOB area size: %u bytes\n", ns->geom.oobsz); | 584 | printk("OOB area size: %u bytes\n", ns->geom.oobsz); |
579 | printk("sector size: %u KiB\n", ns->geom.secsz >> 10); | 585 | printk("sector size: %u KiB\n", ns->geom.secsz >> 10); |
@@ -583,7 +589,7 @@ static int init_nandsim(struct mtd_info *mtd) | |||
583 | printk("bits in sector size: %u\n", ns->geom.secshift); | 589 | printk("bits in sector size: %u\n", ns->geom.secshift); |
584 | printk("bits in page size: %u\n", ns->geom.pgshift); | 590 | printk("bits in page size: %u\n", ns->geom.pgshift); |
585 | printk("bits in OOB size: %u\n", ns->geom.oobshift); | 591 | printk("bits in OOB size: %u\n", ns->geom.oobshift); |
586 | printk("flash size with OOB: %u KiB\n", ns->geom.totszoob >> 10); | 592 | printk("flash size with OOB: %llu KiB\n", ns->geom.totszoob >> 10); |
587 | printk("page address bytes: %u\n", ns->geom.pgaddrbytes); | 593 | printk("page address bytes: %u\n", ns->geom.pgaddrbytes); |
588 | printk("sector address bytes: %u\n", ns->geom.secaddrbytes); | 594 | printk("sector address bytes: %u\n", ns->geom.secaddrbytes); |
589 | printk("options: %#x\n", ns->options); | 595 | printk("options: %#x\n", ns->options); |
@@ -825,7 +831,7 @@ static int setup_wear_reporting(struct mtd_info *mtd) | |||
825 | 831 | ||
826 | if (!rptwear) | 832 | if (!rptwear) |
827 | return 0; | 833 | return 0; |
828 | wear_eb_count = mtd->size / mtd->erasesize; | 834 | wear_eb_count = divide(mtd->size, mtd->erasesize); |
829 | mem = wear_eb_count * sizeof(unsigned long); | 835 | mem = wear_eb_count * sizeof(unsigned long); |
830 | if (mem / sizeof(unsigned long) != wear_eb_count) { | 836 | if (mem / sizeof(unsigned long) != wear_eb_count) { |
831 | NS_ERR("Too many erase blocks for wear reporting\n"); | 837 | NS_ERR("Too many erase blocks for wear reporting\n"); |
@@ -2013,7 +2019,7 @@ static int __init ns_init_module(void) | |||
2013 | } | 2019 | } |
2014 | 2020 | ||
2015 | if (overridesize) { | 2021 | if (overridesize) { |
2016 | u_int32_t new_size = nsmtd->erasesize << overridesize; | 2022 | u_int64_t new_size = (u_int64_t)nsmtd->erasesize << overridesize; |
2017 | if (new_size >> overridesize != nsmtd->erasesize) { | 2023 | if (new_size >> overridesize != nsmtd->erasesize) { |
2018 | NS_ERR("overridesize is too big\n"); | 2024 | NS_ERR("overridesize is too big\n"); |
2019 | goto err_exit; | 2025 | goto err_exit; |
@@ -2021,7 +2027,8 @@ static int __init ns_init_module(void) | |||
2021 | /* N.B. This relies on nand_scan not doing anything with the size before we change it */ | 2027 | /* N.B. This relies on nand_scan not doing anything with the size before we change it */ |
2022 | nsmtd->size = new_size; | 2028 | nsmtd->size = new_size; |
2023 | chip->chipsize = new_size; | 2029 | chip->chipsize = new_size; |
2024 | chip->chip_shift = ffs(new_size) - 1; | 2030 | chip->chip_shift = ffs(nsmtd->erasesize) + overridesize - 1; |
2031 | chip->pagemask = (chip->chipsize >> chip->page_shift) - 1; | ||
2025 | } | 2032 | } |
2026 | 2033 | ||
2027 | if ((retval = setup_wear_reporting(nsmtd)) != 0) | 2034 | if ((retval = setup_wear_reporting(nsmtd)) != 0) |
diff --git a/drivers/mtd/nand/ppchameleonevb.c b/drivers/mtd/nand/ppchameleonevb.c index 082073acf20f..cc8658431851 100644 --- a/drivers/mtd/nand/ppchameleonevb.c +++ b/drivers/mtd/nand/ppchameleonevb.c | |||
@@ -6,8 +6,6 @@ | |||
6 | * Derived from drivers/mtd/nand/edb7312.c | 6 | * Derived from drivers/mtd/nand/edb7312.c |
7 | * | 7 | * |
8 | * | 8 | * |
9 | * $Id: ppchameleonevb.c,v 1.7 2005/11/07 11:14:31 gleixner Exp $ | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
13 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c index 26f88215bc47..a033c4cd8e16 100644 --- a/drivers/mtd/nand/rtc_from4.c +++ b/drivers/mtd/nand/rtc_from4.c | |||
@@ -6,8 +6,6 @@ | |||
6 | * Derived from drivers/mtd/nand/spia.c | 6 | * Derived from drivers/mtd/nand/spia.c |
7 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) | 7 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) |
8 | * | 8 | * |
9 | * $Id: rtc_from4.c,v 1.10 2005/11/07 11:14:31 gleixner Exp $ | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
13 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index b34a460ab679..556139ed1fdf 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c | |||
@@ -1,26 +1,10 @@ | |||
1 | /* linux/drivers/mtd/nand/s3c2410.c | 1 | /* linux/drivers/mtd/nand/s3c2410.c |
2 | * | 2 | * |
3 | * Copyright (c) 2004,2005 Simtec Electronics | 3 | * Copyright © 2004-2008 Simtec Electronics |
4 | * http://www.simtec.co.uk/products/SWLINUX/ | 4 | * http://armlinux.simtec.co.uk/ |
5 | * Ben Dooks <ben@simtec.co.uk> | 5 | * Ben Dooks <ben@simtec.co.uk> |
6 | * | 6 | * |
7 | * Samsung S3C2410/S3C240 NAND driver | 7 | * Samsung S3C2410/S3C2440/S3C2412 NAND driver |
8 | * | ||
9 | * Changelog: | ||
10 | * 21-Sep-2004 BJD Initial version | ||
11 | * 23-Sep-2004 BJD Multiple device support | ||
12 | * 28-Sep-2004 BJD Fixed ECC placement for Hardware mode | ||
13 | * 12-Oct-2004 BJD Fixed errors in use of platform data | ||
14 | * 18-Feb-2005 BJD Fix sparse errors | ||
15 | * 14-Mar-2005 BJD Applied tglx's code reduction patch | ||
16 | * 02-May-2005 BJD Fixed s3c2440 support | ||
17 | * 02-May-2005 BJD Reduced hwcontrol decode | ||
18 | * 20-Jun-2005 BJD Updated s3c2440 support, fixed timing bug | ||
19 | * 08-Jul-2005 BJD Fix OOPS when no platform data supplied | ||
20 | * 20-Oct-2005 BJD Fix timing calculation bug | ||
21 | * 14-Jan-2006 BJD Allow clock to be stopped when idle | ||
22 | * | ||
23 | * $Id: s3c2410.c,v 1.23 2006/04/01 18:06:29 bjd Exp $ | ||
24 | * | 8 | * |
25 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
26 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
@@ -52,6 +36,7 @@ | |||
52 | #include <linux/err.h> | 36 | #include <linux/err.h> |
53 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
54 | #include <linux/clk.h> | 38 | #include <linux/clk.h> |
39 | #include <linux/cpufreq.h> | ||
55 | 40 | ||
56 | #include <linux/mtd/mtd.h> | 41 | #include <linux/mtd/mtd.h> |
57 | #include <linux/mtd/nand.h> | 42 | #include <linux/mtd/nand.h> |
@@ -120,8 +105,13 @@ struct s3c2410_nand_info { | |||
120 | int sel_bit; | 105 | int sel_bit; |
121 | int mtd_count; | 106 | int mtd_count; |
122 | unsigned long save_sel; | 107 | unsigned long save_sel; |
108 | unsigned long clk_rate; | ||
123 | 109 | ||
124 | enum s3c_cpu_type cpu_type; | 110 | enum s3c_cpu_type cpu_type; |
111 | |||
112 | #ifdef CONFIG_CPU_FREQ | ||
113 | struct notifier_block freq_transition; | ||
114 | #endif | ||
125 | }; | 115 | }; |
126 | 116 | ||
127 | /* conversion functions */ | 117 | /* conversion functions */ |
@@ -179,17 +169,18 @@ static int s3c_nand_calc_rate(int wanted, unsigned long clk, int max) | |||
179 | 169 | ||
180 | /* controller setup */ | 170 | /* controller setup */ |
181 | 171 | ||
182 | static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, | 172 | static int s3c2410_nand_setrate(struct s3c2410_nand_info *info) |
183 | struct platform_device *pdev) | ||
184 | { | 173 | { |
185 | struct s3c2410_platform_nand *plat = to_nand_plat(pdev); | 174 | struct s3c2410_platform_nand *plat = info->platform; |
186 | unsigned long clkrate = clk_get_rate(info->clk); | ||
187 | int tacls_max = (info->cpu_type == TYPE_S3C2412) ? 8 : 4; | 175 | int tacls_max = (info->cpu_type == TYPE_S3C2412) ? 8 : 4; |
188 | int tacls, twrph0, twrph1; | 176 | int tacls, twrph0, twrph1; |
189 | unsigned long cfg = 0; | 177 | unsigned long clkrate = clk_get_rate(info->clk); |
178 | unsigned long set, cfg, mask; | ||
179 | unsigned long flags; | ||
190 | 180 | ||
191 | /* calculate the timing information for the controller */ | 181 | /* calculate the timing information for the controller */ |
192 | 182 | ||
183 | info->clk_rate = clkrate; | ||
193 | clkrate /= 1000; /* turn clock into kHz for ease of use */ | 184 | clkrate /= 1000; /* turn clock into kHz for ease of use */ |
194 | 185 | ||
195 | if (plat != NULL) { | 186 | if (plat != NULL) { |
@@ -211,28 +202,69 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, | |||
211 | dev_info(info->device, "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n", | 202 | dev_info(info->device, "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n", |
212 | tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate)); | 203 | tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate)); |
213 | 204 | ||
205 | switch (info->cpu_type) { | ||
206 | case TYPE_S3C2410: | ||
207 | mask = (S3C2410_NFCONF_TACLS(3) | | ||
208 | S3C2410_NFCONF_TWRPH0(7) | | ||
209 | S3C2410_NFCONF_TWRPH1(7)); | ||
210 | set = S3C2410_NFCONF_EN; | ||
211 | set |= S3C2410_NFCONF_TACLS(tacls - 1); | ||
212 | set |= S3C2410_NFCONF_TWRPH0(twrph0 - 1); | ||
213 | set |= S3C2410_NFCONF_TWRPH1(twrph1 - 1); | ||
214 | break; | ||
215 | |||
216 | case TYPE_S3C2440: | ||
217 | case TYPE_S3C2412: | ||
218 | mask = (S3C2410_NFCONF_TACLS(tacls_max - 1) | | ||
219 | S3C2410_NFCONF_TWRPH0(7) | | ||
220 | S3C2410_NFCONF_TWRPH1(7)); | ||
221 | |||
222 | set = S3C2440_NFCONF_TACLS(tacls - 1); | ||
223 | set |= S3C2440_NFCONF_TWRPH0(twrph0 - 1); | ||
224 | set |= S3C2440_NFCONF_TWRPH1(twrph1 - 1); | ||
225 | break; | ||
226 | |||
227 | default: | ||
228 | /* keep compiler happy */ | ||
229 | mask = 0; | ||
230 | set = 0; | ||
231 | BUG(); | ||
232 | } | ||
233 | |||
234 | dev_dbg(info->device, "NF_CONF is 0x%lx\n", cfg); | ||
235 | |||
236 | local_irq_save(flags); | ||
237 | |||
238 | cfg = readl(info->regs + S3C2410_NFCONF); | ||
239 | cfg &= ~mask; | ||
240 | cfg |= set; | ||
241 | writel(cfg, info->regs + S3C2410_NFCONF); | ||
242 | |||
243 | local_irq_restore(flags); | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static int s3c2410_nand_inithw(struct s3c2410_nand_info *info) | ||
249 | { | ||
250 | int ret; | ||
251 | |||
252 | ret = s3c2410_nand_setrate(info); | ||
253 | if (ret < 0) | ||
254 | return ret; | ||
255 | |||
214 | switch (info->cpu_type) { | 256 | switch (info->cpu_type) { |
215 | case TYPE_S3C2410: | 257 | case TYPE_S3C2410: |
216 | cfg = S3C2410_NFCONF_EN; | 258 | default: |
217 | cfg |= S3C2410_NFCONF_TACLS(tacls - 1); | ||
218 | cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1); | ||
219 | cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1); | ||
220 | break; | 259 | break; |
221 | 260 | ||
222 | case TYPE_S3C2440: | 261 | case TYPE_S3C2440: |
223 | case TYPE_S3C2412: | 262 | case TYPE_S3C2412: |
224 | cfg = S3C2440_NFCONF_TACLS(tacls - 1); | ||
225 | cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1); | ||
226 | cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1); | ||
227 | |||
228 | /* enable the controller and de-assert nFCE */ | 263 | /* enable the controller and de-assert nFCE */ |
229 | 264 | ||
230 | writel(S3C2440_NFCONT_ENABLE, info->regs + S3C2440_NFCONT); | 265 | writel(S3C2440_NFCONT_ENABLE, info->regs + S3C2440_NFCONT); |
231 | } | 266 | } |
232 | 267 | ||
233 | dev_dbg(info->device, "NF_CONF is 0x%lx\n", cfg); | ||
234 | |||
235 | writel(cfg, info->regs + S3C2410_NFCONF); | ||
236 | return 0; | 268 | return 0; |
237 | } | 269 | } |
238 | 270 | ||
@@ -513,6 +545,52 @@ static void s3c2440_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int | |||
513 | writesl(info->regs + S3C2440_NFDATA, buf, len / 4); | 545 | writesl(info->regs + S3C2440_NFDATA, buf, len / 4); |
514 | } | 546 | } |
515 | 547 | ||
548 | /* cpufreq driver support */ | ||
549 | |||
550 | #ifdef CONFIG_CPU_FREQ | ||
551 | |||
552 | static int s3c2410_nand_cpufreq_transition(struct notifier_block *nb, | ||
553 | unsigned long val, void *data) | ||
554 | { | ||
555 | struct s3c2410_nand_info *info; | ||
556 | unsigned long newclk; | ||
557 | |||
558 | info = container_of(nb, struct s3c2410_nand_info, freq_transition); | ||
559 | newclk = clk_get_rate(info->clk); | ||
560 | |||
561 | if ((val == CPUFREQ_POSTCHANGE && newclk < info->clk_rate) || | ||
562 | (val == CPUFREQ_PRECHANGE && newclk > info->clk_rate)) { | ||
563 | s3c2410_nand_setrate(info); | ||
564 | } | ||
565 | |||
566 | return 0; | ||
567 | } | ||
568 | |||
569 | static inline int s3c2410_nand_cpufreq_register(struct s3c2410_nand_info *info) | ||
570 | { | ||
571 | info->freq_transition.notifier_call = s3c2410_nand_cpufreq_transition; | ||
572 | |||
573 | return cpufreq_register_notifier(&info->freq_transition, | ||
574 | CPUFREQ_TRANSITION_NOTIFIER); | ||
575 | } | ||
576 | |||
577 | static inline void s3c2410_nand_cpufreq_deregister(struct s3c2410_nand_info *info) | ||
578 | { | ||
579 | cpufreq_unregister_notifier(&info->freq_transition, | ||
580 | CPUFREQ_TRANSITION_NOTIFIER); | ||
581 | } | ||
582 | |||
583 | #else | ||
584 | static inline int s3c2410_nand_cpufreq_register(struct s3c2410_nand_info *info) | ||
585 | { | ||
586 | return 0; | ||
587 | } | ||
588 | |||
589 | static inline void s3c2410_nand_cpufreq_deregister(struct s3c2410_nand_info *info) | ||
590 | { | ||
591 | } | ||
592 | #endif | ||
593 | |||
516 | /* device management functions */ | 594 | /* device management functions */ |
517 | 595 | ||
518 | static int s3c2410_nand_remove(struct platform_device *pdev) | 596 | static int s3c2410_nand_remove(struct platform_device *pdev) |
@@ -524,9 +602,10 @@ static int s3c2410_nand_remove(struct platform_device *pdev) | |||
524 | if (info == NULL) | 602 | if (info == NULL) |
525 | return 0; | 603 | return 0; |
526 | 604 | ||
527 | /* first thing we need to do is release all our mtds | 605 | s3c2410_nand_cpufreq_deregister(info); |
528 | * and their partitions, then go through freeing the | 606 | |
529 | * resources used | 607 | /* Release all our mtds and their partitions, then go through |
608 | * freeing the resources used | ||
530 | */ | 609 | */ |
531 | 610 | ||
532 | if (info->mtds != NULL) { | 611 | if (info->mtds != NULL) { |
@@ -691,7 +770,8 @@ static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info, | |||
691 | { | 770 | { |
692 | struct nand_chip *chip = &nmtd->chip; | 771 | struct nand_chip *chip = &nmtd->chip; |
693 | 772 | ||
694 | printk("%s: chip %p: %d\n", __func__, chip, chip->page_shift); | 773 | dev_dbg(info->device, "chip %p => page shift %d\n", |
774 | chip, chip->page_shift); | ||
695 | 775 | ||
696 | if (hardware_ecc) { | 776 | if (hardware_ecc) { |
697 | /* change the behaviour depending on wether we are using | 777 | /* change the behaviour depending on wether we are using |
@@ -784,7 +864,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev, | |||
784 | 864 | ||
785 | /* initialise the hardware */ | 865 | /* initialise the hardware */ |
786 | 866 | ||
787 | err = s3c2410_nand_inithw(info, pdev); | 867 | err = s3c2410_nand_inithw(info); |
788 | if (err != 0) | 868 | if (err != 0) |
789 | goto exit_error; | 869 | goto exit_error; |
790 | 870 | ||
@@ -827,6 +907,12 @@ static int s3c24xx_nand_probe(struct platform_device *pdev, | |||
827 | sets++; | 907 | sets++; |
828 | } | 908 | } |
829 | 909 | ||
910 | err = s3c2410_nand_cpufreq_register(info); | ||
911 | if (err < 0) { | ||
912 | dev_err(&pdev->dev, "failed to init cpufreq support\n"); | ||
913 | goto exit_error; | ||
914 | } | ||
915 | |||
830 | if (allow_clk_stop(info)) { | 916 | if (allow_clk_stop(info)) { |
831 | dev_info(&pdev->dev, "clock idle support enabled\n"); | 917 | dev_info(&pdev->dev, "clock idle support enabled\n"); |
832 | clk_disable(info->clk); | 918 | clk_disable(info->clk); |
@@ -874,7 +960,7 @@ static int s3c24xx_nand_resume(struct platform_device *dev) | |||
874 | 960 | ||
875 | if (info) { | 961 | if (info) { |
876 | clk_enable(info->clk); | 962 | clk_enable(info->clk); |
877 | s3c2410_nand_inithw(info, dev); | 963 | s3c2410_nand_inithw(info); |
878 | 964 | ||
879 | /* Restore the state of the nFCE line. */ | 965 | /* Restore the state of the nFCE line. */ |
880 | 966 | ||
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index 033f8800b1e6..6dba2fb66ae5 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c | |||
@@ -3,8 +3,6 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2004 Richard Purdie | 4 | * Copyright (C) 2004 Richard Purdie |
5 | * | 5 | * |
6 | * $Id: sharpsl.c,v 1.7 2005/11/07 11:14:31 gleixner Exp $ | ||
7 | * | ||
8 | * Based on Sharp's NAND driver sharp_sl.c | 6 | * Based on Sharp's NAND driver sharp_sl.c |
9 | * | 7 | * |
10 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/mtd/nand/spia.c b/drivers/mtd/nand/spia.c index 1f6d429b1583..0cc6d0acb8fe 100644 --- a/drivers/mtd/nand/spia.c +++ b/drivers/mtd/nand/spia.c | |||
@@ -8,8 +8,6 @@ | |||
8 | * to controllines (due to change in nand.c) | 8 | * to controllines (due to change in nand.c) |
9 | * page_cache added | 9 | * page_cache added |
10 | * | 10 | * |
11 | * $Id: spia.c,v 1.25 2005/11/07 11:14:31 gleixner Exp $ | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
14 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
15 | * published by the Free Software Foundation. | 13 | * published by the Free Software Foundation. |
diff --git a/drivers/mtd/nand/toto.c b/drivers/mtd/nand/toto.c index f9e2d4a0ab8c..bbf492e6830d 100644 --- a/drivers/mtd/nand/toto.c +++ b/drivers/mtd/nand/toto.c | |||
@@ -14,8 +14,6 @@ | |||
14 | * Overview: | 14 | * Overview: |
15 | * This is a device driver for the NAND flash device found on the | 15 | * This is a device driver for the NAND flash device found on the |
16 | * TI fido board. It supports 32MiB and 64MiB cards | 16 | * TI fido board. It supports 32MiB and 64MiB cards |
17 | * | ||
18 | * $Id: toto.c,v 1.5 2005/11/07 11:14:31 gleixner Exp $ | ||
19 | */ | 17 | */ |
20 | 18 | ||
21 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
diff --git a/drivers/mtd/nand/ts7250.c b/drivers/mtd/nand/ts7250.c index f40081069ab2..807a72752eeb 100644 --- a/drivers/mtd/nand/ts7250.c +++ b/drivers/mtd/nand/ts7250.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * Derived from drivers/mtd/nand/autcpu12.c | 9 | * Derived from drivers/mtd/nand/autcpu12.c |
10 | * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) | 10 | * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) |
11 | * | 11 | * |
12 | * $Id: ts7250.c,v 1.4 2004/12/30 22:02:07 joff Exp $ | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
15 | * it under the terms of the GNU General Public License version 2 as | 13 | * it under the terms of the GNU General Public License version 2 as |
16 | * published by the Free Software Foundation. | 14 | * published by the Free Software Foundation. |
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c index 0c9ce19ea27a..320b929abe79 100644 --- a/drivers/mtd/nftlcore.c +++ b/drivers/mtd/nftlcore.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* Linux driver for NAND Flash Translation Layer */ | 1 | /* Linux driver for NAND Flash Translation Layer */ |
2 | /* (c) 1999 Machine Vision Holdings, Inc. */ | 2 | /* (c) 1999 Machine Vision Holdings, Inc. */ |
3 | /* Author: David Woodhouse <dwmw2@infradead.org> */ | 3 | /* Author: David Woodhouse <dwmw2@infradead.org> */ |
4 | /* $Id: nftlcore.c,v 1.98 2005/11/07 11:14:21 gleixner Exp $ */ | ||
5 | 4 | ||
6 | /* | 5 | /* |
7 | The contents of this file are distributed under the GNU General | 6 | The contents of this file are distributed under the GNU General |
@@ -803,12 +802,8 @@ static struct mtd_blktrans_ops nftl_tr = { | |||
803 | .owner = THIS_MODULE, | 802 | .owner = THIS_MODULE, |
804 | }; | 803 | }; |
805 | 804 | ||
806 | extern char nftlmountrev[]; | ||
807 | |||
808 | static int __init init_nftl(void) | 805 | static int __init init_nftl(void) |
809 | { | 806 | { |
810 | printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.98 $, nftlmount.c %s\n", nftlmountrev); | ||
811 | |||
812 | return register_mtd_blktrans(&nftl_tr); | 807 | return register_mtd_blktrans(&nftl_tr); |
813 | } | 808 | } |
814 | 809 | ||
diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c index 345e6eff89ce..ccc4f209fbb5 100644 --- a/drivers/mtd/nftlmount.c +++ b/drivers/mtd/nftlmount.c | |||
@@ -4,8 +4,6 @@ | |||
4 | * Author: Fabrice Bellard (fabrice.bellard@netgem.com) | 4 | * Author: Fabrice Bellard (fabrice.bellard@netgem.com) |
5 | * Copyright (C) 2000 Netgem S.A. | 5 | * Copyright (C) 2000 Netgem S.A. |
6 | * | 6 | * |
7 | * $Id: nftlmount.c,v 1.41 2005/11/07 11:14:21 gleixner Exp $ | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
11 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
@@ -31,8 +29,6 @@ | |||
31 | 29 | ||
32 | #define SECTORSIZE 512 | 30 | #define SECTORSIZE 512 |
33 | 31 | ||
34 | char nftlmountrev[]="$Revision: 1.41 $"; | ||
35 | |||
36 | /* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the | 32 | /* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the |
37 | * various device information of the NFTL partition and Bad Unit Table. Update | 33 | * various device information of the NFTL partition and Bad Unit Table. Update |
38 | * the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[] | 34 | * the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[] |
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 5d7965f7e9ce..926cf3a4135d 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c | |||
@@ -325,28 +325,11 @@ static int onenand_wait(struct mtd_info *mtd, int state) | |||
325 | 325 | ||
326 | ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); | 326 | ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); |
327 | 327 | ||
328 | if (ctrl & ONENAND_CTRL_ERROR) { | 328 | /* |
329 | printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n", ctrl); | 329 | * In the Spec. it checks the controller status first |
330 | if (ctrl & ONENAND_CTRL_LOCK) | 330 | * However if you get the correct information in case of |
331 | printk(KERN_ERR "onenand_wait: it's locked error.\n"); | 331 | * power off recovery (POR) test, it should read ECC status first |
332 | if (state == FL_READING) { | 332 | */ |
333 | /* | ||
334 | * A power loss while writing can result in a page | ||
335 | * becoming unreadable. When the device is mounted | ||
336 | * again, reading that page gives controller errors. | ||
337 | * Upper level software like JFFS2 treat -EIO as fatal, | ||
338 | * refusing to mount at all. That means it is necessary | ||
339 | * to treat the error as an ECC error to allow recovery. | ||
340 | * Note that typically in this case, the eraseblock can | ||
341 | * still be erased and rewritten i.e. it has not become | ||
342 | * a bad block. | ||
343 | */ | ||
344 | mtd->ecc_stats.failed++; | ||
345 | return -EBADMSG; | ||
346 | } | ||
347 | return -EIO; | ||
348 | } | ||
349 | |||
350 | if (interrupt & ONENAND_INT_READ) { | 333 | if (interrupt & ONENAND_INT_READ) { |
351 | int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); | 334 | int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); |
352 | if (ecc) { | 335 | if (ecc) { |
@@ -364,6 +347,15 @@ static int onenand_wait(struct mtd_info *mtd, int state) | |||
364 | return -EIO; | 347 | return -EIO; |
365 | } | 348 | } |
366 | 349 | ||
350 | /* If there's controller error, it's a real error */ | ||
351 | if (ctrl & ONENAND_CTRL_ERROR) { | ||
352 | printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n", | ||
353 | ctrl); | ||
354 | if (ctrl & ONENAND_CTRL_LOCK) | ||
355 | printk(KERN_ERR "onenand_wait: it's locked error.\n"); | ||
356 | return -EIO; | ||
357 | } | ||
358 | |||
367 | return 0; | 359 | return 0; |
368 | } | 360 | } |
369 | 361 | ||
@@ -1135,22 +1127,26 @@ static int onenand_bbt_wait(struct mtd_info *mtd, int state) | |||
1135 | interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); | 1127 | interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); |
1136 | ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); | 1128 | ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); |
1137 | 1129 | ||
1138 | /* Initial bad block case: 0x2400 or 0x0400 */ | ||
1139 | if (ctrl & ONENAND_CTRL_ERROR) { | ||
1140 | printk(KERN_DEBUG "onenand_bbt_wait: controller error = 0x%04x\n", ctrl); | ||
1141 | return ONENAND_BBT_READ_ERROR; | ||
1142 | } | ||
1143 | |||
1144 | if (interrupt & ONENAND_INT_READ) { | 1130 | if (interrupt & ONENAND_INT_READ) { |
1145 | int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); | 1131 | int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS); |
1146 | if (ecc & ONENAND_ECC_2BIT_ALL) | 1132 | if (ecc & ONENAND_ECC_2BIT_ALL) { |
1133 | printk(KERN_INFO "onenand_bbt_wait: ecc error = 0x%04x" | ||
1134 | ", controller error 0x%04x\n", ecc, ctrl); | ||
1147 | return ONENAND_BBT_READ_ERROR; | 1135 | return ONENAND_BBT_READ_ERROR; |
1136 | } | ||
1148 | } else { | 1137 | } else { |
1149 | printk(KERN_ERR "onenand_bbt_wait: read timeout!" | 1138 | printk(KERN_ERR "onenand_bbt_wait: read timeout!" |
1150 | "ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt); | 1139 | "ctrl=0x%04x intr=0x%04x\n", ctrl, interrupt); |
1151 | return ONENAND_BBT_READ_FATAL_ERROR; | 1140 | return ONENAND_BBT_READ_FATAL_ERROR; |
1152 | } | 1141 | } |
1153 | 1142 | ||
1143 | /* Initial bad block case: 0x2400 or 0x0400 */ | ||
1144 | if (ctrl & ONENAND_CTRL_ERROR) { | ||
1145 | printk(KERN_DEBUG "onenand_bbt_wait: " | ||
1146 | "controller error = 0x%04x\n", ctrl); | ||
1147 | return ONENAND_BBT_READ_ERROR; | ||
1148 | } | ||
1149 | |||
1154 | return 0; | 1150 | return 0; |
1155 | } | 1151 | } |
1156 | 1152 | ||
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c index c5030f94f04e..2d600a1bf2aa 100644 --- a/drivers/mtd/redboot.c +++ b/drivers/mtd/redboot.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: redboot.c,v 1.21 2006/03/30 18:34:37 bjd Exp $ | ||
3 | * | ||
4 | * Parse RedBoot-style Flash Image System (FIS) tables and | 2 | * Parse RedBoot-style Flash Image System (FIS) tables and |
5 | * produce a Linux partition array to match. | 3 | * produce a Linux partition array to match. |
6 | */ | 4 | */ |
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c index c84e45465499..e538c0a72abb 100644 --- a/drivers/mtd/rfd_ftl.c +++ b/drivers/mtd/rfd_ftl.c | |||
@@ -3,8 +3,6 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2005 Sean Young <sean@mess.org> | 4 | * Copyright (C) 2005 Sean Young <sean@mess.org> |
5 | * | 5 | * |
6 | * $Id: rfd_ftl.c,v 1.8 2006/01/15 12:51:44 sean Exp $ | ||
7 | * | ||
8 | * This type of flash translation layer (FTL) is used by the Embedded BIOS | 6 | * This type of flash translation layer (FTL) is used by the Embedded BIOS |
9 | * by General Software. It is known as the Resident Flash Disk (RFD), see: | 7 | * by General Software. It is known as the Resident Flash Disk (RFD), see: |
10 | * | 8 | * |