aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/chips/Kconfig29
-rw-r--r--drivers/mtd/chips/amd_flash.c14
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c578
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c497
-rw-r--r--drivers/mtd/chips/fwh_lock.h6
-rw-r--r--drivers/mtd/chips/gen_probe.c4
-rw-r--r--drivers/mtd/chips/jedec_probe.c28
-rw-r--r--drivers/mtd/cmdlinepart.c8
-rw-r--r--drivers/mtd/devices/block2mtd.c20
-rw-r--r--drivers/mtd/devices/ms02-nv.c8
-rw-r--r--drivers/mtd/devices/mtdram.c265
-rw-r--r--drivers/mtd/devices/phram.c34
-rw-r--r--drivers/mtd/devices/slram.c23
-rw-r--r--drivers/mtd/ftl.c5
-rw-r--r--drivers/mtd/maps/Kconfig117
-rw-r--r--drivers/mtd/maps/Makefile11
-rw-r--r--drivers/mtd/maps/alchemy-flash.c192
-rw-r--r--drivers/mtd/maps/amd76xrom.c4
-rw-r--r--drivers/mtd/maps/bast-flash.c13
-rw-r--r--drivers/mtd/maps/db1550-flash.c187
-rw-r--r--drivers/mtd/maps/db1x00-flash.c226
-rw-r--r--drivers/mtd/maps/elan-104nc.c228
-rw-r--r--drivers/mtd/maps/ichxrom.c4
-rw-r--r--drivers/mtd/maps/ixp2000.c7
-rw-r--r--drivers/mtd/maps/mainstone-flash.c178
-rw-r--r--drivers/mtd/maps/map_funcs.c11
-rw-r--r--drivers/mtd/maps/omap_nor.c179
-rw-r--r--drivers/mtd/maps/pb1550-flash.c203
-rw-r--r--drivers/mtd/maps/pb1xxx-flash.c178
-rw-r--r--drivers/mtd/maps/pci.c4
-rw-r--r--drivers/mtd/maps/plat-ram.c278
-rw-r--r--drivers/mtd/maps/scb2_flash.c4
-rw-r--r--drivers/mtd/maps/sharpsl-flash.c33
-rw-r--r--drivers/mtd/mtdchar.c176
-rw-r--r--drivers/mtd/mtdcore.c6
-rw-r--r--drivers/mtd/mtdpart.c28
-rw-r--r--drivers/mtd/nand/Kconfig21
-rw-r--r--drivers/mtd/nand/Makefile2
-rw-r--r--drivers/mtd/nand/diskonchip.c96
-rw-r--r--drivers/mtd/nand/nand_base.c299
-rw-r--r--drivers/mtd/nand/nand_bbt.c114
-rw-r--r--drivers/mtd/nand/nand_ids.c18
-rw-r--r--drivers/mtd/nand/nandsim.c41
-rw-r--r--drivers/mtd/nand/rtc_from4.c140
-rw-r--r--drivers/mtd/nand/s3c2410.c294
-rw-r--r--[-rwxr-xr-x]drivers/mtd/nand/sharpsl.c4
-rw-r--r--drivers/mtd/nand/tx4925ndfmc.c416
-rw-r--r--drivers/mtd/nand/tx4938ndfmc.c406
-rw-r--r--fs/Kconfig26
-rw-r--r--fs/jffs2/Makefile5
-rw-r--r--fs/jffs2/README.Locking6
-rw-r--r--fs/jffs2/background.c13
-rw-r--r--fs/jffs2/build.c9
-rw-r--r--fs/jffs2/compr_zlib.c4
-rw-r--r--fs/jffs2/dir.c46
-rw-r--r--fs/jffs2/erase.c24
-rw-r--r--fs/jffs2/file.c5
-rw-r--r--fs/jffs2/fs.c24
-rw-r--r--fs/jffs2/gc.c41
-rw-r--r--fs/jffs2/nodelist.c93
-rw-r--r--fs/jffs2/nodelist.h21
-rw-r--r--fs/jffs2/nodemgmt.c31
-rw-r--r--fs/jffs2/os-linux.h60
-rw-r--r--fs/jffs2/read.c32
-rw-r--r--fs/jffs2/readinode.c96
-rw-r--r--fs/jffs2/scan.c39
-rw-r--r--fs/jffs2/super.c8
-rw-r--r--fs/jffs2/symlink.c42
-rw-r--r--fs/jffs2/wbuf.c164
-rw-r--r--fs/jffs2/write.c55
-rw-r--r--include/linux/jffs2_fs_sb.h9
-rw-r--r--include/linux/mtd/cfi.h85
-rw-r--r--include/linux/mtd/flashchip.h7
-rw-r--r--include/linux/mtd/inftl.h4
-rw-r--r--include/linux/mtd/map.h33
-rw-r--r--include/linux/mtd/mtd.h15
-rw-r--r--include/linux/mtd/nand.h48
-rw-r--r--include/linux/mtd/plat-ram.h35
-rw-r--r--include/mtd/mtd-abi.h19
79 files changed, 3515 insertions, 3221 deletions
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index d682dbc8157e..b5dc59389bb3 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -1,5 +1,5 @@
1# drivers/mtd/chips/Kconfig 1# drivers/mtd/chips/Kconfig
2# $Id: Kconfig,v 1.13 2004/12/01 15:49:10 nico Exp $ 2# $Id: Kconfig,v 1.15 2005/06/06 23:04:35 tpoynor Exp $
3 3
4menu "RAM/ROM/Flash chip drivers" 4menu "RAM/ROM/Flash chip drivers"
5 depends on MTD!=n 5 depends on MTD!=n
@@ -155,6 +155,31 @@ config MTD_CFI_I8
155 If your flash chips are interleaved in eights - i.e. you have eight 155 If your flash chips are interleaved in eights - i.e. you have eight
156 flash chips addressed by each bus cycle, then say 'Y'. 156 flash chips addressed by each bus cycle, then say 'Y'.
157 157
158config MTD_OTP
159 bool "Protection Registers aka one-time programmable (OTP) bits"
160 depends on MTD_CFI_ADV_OPTIONS
161 default n
162 help
163 This enables support for reading, writing and locking so called
164 "Protection Registers" present on some flash chips.
165 A subset of them are pre-programmed at the factory with a
166 unique set of values. The rest is user-programmable.
167
168 The user-programmable Protection Registers contain one-time
169 programmable (OTP) bits; when programmed, register bits cannot be
170 erased. Each Protection Register can be accessed multiple times to
171 program individual bits, as long as the register remains unlocked.
172
173 Each Protection Register has an associated Lock Register bit. When a
174 Lock Register bit is programmed, the associated Protection Register
175 can only be read; it can no longer be programmed. Additionally,
176 because the Lock Register bits themselves are OTP, when programmed,
177 Lock Register bits cannot be erased. Therefore, when a Protection
178 Register is locked, it cannot be unlocked.
179
180 This feature should therefore be used with extreme care. Any mistake
181 in the programming of OTP bits will waste them.
182
158config MTD_CFI_INTELEXT 183config MTD_CFI_INTELEXT
159 tristate "Support for Intel/Sharp flash chips" 184 tristate "Support for Intel/Sharp flash chips"
160 depends on MTD_GEN_PROBE 185 depends on MTD_GEN_PROBE
@@ -275,7 +300,7 @@ config MTD_JEDEC
275 300
276config MTD_XIP 301config MTD_XIP
277 bool "XIP aware MTD support" 302 bool "XIP aware MTD support"
278 depends on !SMP && MTD_CFI_INTELEXT && EXPERIMENTAL 303 depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL
279 default y if XIP_KERNEL 304 default y if XIP_KERNEL
280 help 305 help
281 This allows MTD support to work with flash memory which is also 306 This allows MTD support to work with flash memory which is also
diff --git a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c
index 41e2e3e31603..2dafeba3f3d5 100644
--- a/drivers/mtd/chips/amd_flash.c
+++ b/drivers/mtd/chips/amd_flash.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Author: Jonas Holmberg <jonas.holmberg@axis.com> 4 * Author: Jonas Holmberg <jonas.holmberg@axis.com>
5 * 5 *
6 * $Id: amd_flash.c,v 1.26 2004/11/20 12:49:04 dwmw2 Exp $ 6 * $Id: amd_flash.c,v 1.27 2005/02/04 07:43:09 jonashg Exp $
7 * 7 *
8 * Copyright (c) 2001 Axis Communications AB 8 * Copyright (c) 2001 Axis Communications AB
9 * 9 *
@@ -67,7 +67,6 @@
67#define AM29LV160DT 0x22C4 67#define AM29LV160DT 0x22C4
68#define AM29LV160DB 0x2249 68#define AM29LV160DB 0x2249
69#define AM29BDS323D 0x22D1 69#define AM29BDS323D 0x22D1
70#define AM29BDS643D 0x227E
71 70
72/* Atmel */ 71/* Atmel */
73#define AT49xV16x 0x00C0 72#define AT49xV16x 0x00C0
@@ -618,17 +617,6 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
618 { .offset = 0x3f0000, .erasesize = 0x02000, .numblocks = 8 }, 617 { .offset = 0x3f0000, .erasesize = 0x02000, .numblocks = 8 },
619 } 618 }
620 }, { 619 }, {
621 .mfr_id = MANUFACTURER_AMD,
622 .dev_id = AM29BDS643D,
623 .name = "AMD AM29BDS643D",
624 .size = 0x00800000,
625 .numeraseregions = 3,
626 .regions = {
627 { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 96 },
628 { .offset = 0x600000, .erasesize = 0x10000, .numblocks = 31 },
629 { .offset = 0x7f0000, .erasesize = 0x02000, .numblocks = 8 },
630 }
631 }, {
632 .mfr_id = MANUFACTURER_ATMEL, 620 .mfr_id = MANUFACTURER_ATMEL,
633 .dev_id = AT49xV16x, 621 .dev_id = AT49xV16x,
634 .name = "Atmel AT49xV16x", 622 .name = "Atmel AT49xV16x",
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index c268bcd71720..8b1304531d8f 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -4,7 +4,7 @@
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.164 2004/11/16 18:29:00 dwmw2 Exp $ 7 * $Id: cfi_cmdset_0001.c,v 1.178 2005/05/19 17:05:43 nico Exp $
8 * 8 *
9 * 9 *
10 * 10/10/2000 Nicolas Pitre <nico@cam.org> 10 * 10/10/2000 Nicolas Pitre <nico@cam.org>
@@ -29,6 +29,7 @@
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/reboot.h>
32#include <linux/mtd/xip.h> 33#include <linux/mtd/xip.h>
33#include <linux/mtd/map.h> 34#include <linux/mtd/map.h>
34#include <linux/mtd/mtd.h> 35#include <linux/mtd/mtd.h>
@@ -48,16 +49,25 @@
48#define M50LPW080 0x002F 49#define M50LPW080 0x002F
49 50
50static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); 51static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
51//static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
52//static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
53static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); 52static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
54static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); 53static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
55static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *); 54static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *);
56static void cfi_intelext_sync (struct mtd_info *); 55static void cfi_intelext_sync (struct mtd_info *);
57static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len); 56static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len);
58static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len); 57static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len);
58#ifdef CONFIG_MTD_OTP
59static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
60static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
61static int cfi_intelext_write_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
62static int cfi_intelext_lock_user_prot_reg (struct mtd_info *, loff_t, size_t);
63static int cfi_intelext_get_fact_prot_info (struct mtd_info *,
64 struct otp_info *, size_t);
65static int cfi_intelext_get_user_prot_info (struct mtd_info *,
66 struct otp_info *, size_t);
67#endif
59static int cfi_intelext_suspend (struct mtd_info *); 68static int cfi_intelext_suspend (struct mtd_info *);
60static void cfi_intelext_resume (struct mtd_info *); 69static void cfi_intelext_resume (struct mtd_info *);
70static int cfi_intelext_reboot (struct notifier_block *, unsigned long, void *);
61 71
62static void cfi_intelext_destroy(struct mtd_info *); 72static void cfi_intelext_destroy(struct mtd_info *);
63 73
@@ -252,7 +262,8 @@ read_pri_intelext(struct map_info *map, __u16 adr)
252 int nb_parts, i; 262 int nb_parts, i;
253 263
254 /* Protection Register info */ 264 /* Protection Register info */
255 extra_size += (extp->NumProtectionFields - 1) * (4 + 6); 265 extra_size += (extp->NumProtectionFields - 1) *
266 sizeof(struct cfi_intelext_otpinfo);
256 267
257 /* Burst Read info */ 268 /* Burst Read info */
258 extra_size += 6; 269 extra_size += 6;
@@ -324,7 +335,9 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
324 mtd->resume = cfi_intelext_resume; 335 mtd->resume = cfi_intelext_resume;
325 mtd->flags = MTD_CAP_NORFLASH; 336 mtd->flags = MTD_CAP_NORFLASH;
326 mtd->name = map->name; 337 mtd->name = map->name;
327 338
339 mtd->reboot_notifier.notifier_call = cfi_intelext_reboot;
340
328 if (cfi->cfi_mode == CFI_MODE_CFI) { 341 if (cfi->cfi_mode == CFI_MODE_CFI) {
329 /* 342 /*
330 * It's a real CFI chip, not one for which the probe 343 * It's a real CFI chip, not one for which the probe
@@ -422,9 +435,13 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
422 mtd->eraseregions[i].numblocks); 435 mtd->eraseregions[i].numblocks);
423 } 436 }
424 437
425#if 0 438#ifdef CONFIG_MTD_OTP
426 mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg;
427 mtd->read_fact_prot_reg = cfi_intelext_read_fact_prot_reg; 439 mtd->read_fact_prot_reg = cfi_intelext_read_fact_prot_reg;
440 mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg;
441 mtd->write_user_prot_reg = cfi_intelext_write_user_prot_reg;
442 mtd->lock_user_prot_reg = cfi_intelext_lock_user_prot_reg;
443 mtd->get_fact_prot_info = cfi_intelext_get_fact_prot_info;
444 mtd->get_user_prot_info = cfi_intelext_get_user_prot_info;
428#endif 445#endif
429 446
430 /* This function has the potential to distort the reality 447 /* This function has the potential to distort the reality
@@ -433,6 +450,7 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
433 goto setup_err; 450 goto setup_err;
434 451
435 __module_get(THIS_MODULE); 452 __module_get(THIS_MODULE);
453 register_reboot_notifier(&mtd->reboot_notifier);
436 return mtd; 454 return mtd;
437 455
438 setup_err: 456 setup_err:
@@ -471,7 +489,8 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
471 int offs, numregions, numparts, partshift, numvirtchips, i, j; 489 int offs, numregions, numparts, partshift, numvirtchips, i, j;
472 490
473 /* Protection Register info */ 491 /* Protection Register info */
474 offs = (extp->NumProtectionFields - 1) * (4 + 6); 492 offs = (extp->NumProtectionFields - 1) *
493 sizeof(struct cfi_intelext_otpinfo);
475 494
476 /* Burst Read info */ 495 /* Burst Read info */
477 offs += 6; 496 offs += 6;
@@ -563,7 +582,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
563 resettime: 582 resettime:
564 timeo = jiffies + HZ; 583 timeo = jiffies + HZ;
565 retry: 584 retry:
566 if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING)) { 585 if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE)) {
567 /* 586 /*
568 * OK. We have possibility for contension on the write/erase 587 * OK. We have possibility for contension on the write/erase
569 * operations which are global to the real chip and not per 588 * operations which are global to the real chip and not per
@@ -807,10 +826,6 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
807 * assembly to make sure inline functions were actually inlined and that gcc 826 * assembly to make sure inline functions were actually inlined and that gcc
808 * didn't emit calls to its own support functions). Also configuring MTD CFI 827 * didn't emit calls to its own support functions). Also configuring MTD CFI
809 * support to a single buswidth and a single interleave is also recommended. 828 * support to a single buswidth and a single interleave is also recommended.
810 * Note that not only IRQs are disabled but the preemption count is also
811 * increased to prevent other locking primitives (namely spin_unlock) from
812 * decrementing the preempt count to zero and scheduling the CPU away while
813 * not in array mode.
814 */ 829 */
815 830
816static void xip_disable(struct map_info *map, struct flchip *chip, 831static void xip_disable(struct map_info *map, struct flchip *chip,
@@ -818,7 +833,6 @@ static void xip_disable(struct map_info *map, struct flchip *chip,
818{ 833{
819 /* TODO: chips with no XIP use should ignore and return */ 834 /* TODO: chips with no XIP use should ignore and return */
820 (void) map_read(map, adr); /* ensure mmu mapping is up to date */ 835 (void) map_read(map, adr); /* ensure mmu mapping is up to date */
821 preempt_disable();
822 local_irq_disable(); 836 local_irq_disable();
823} 837}
824 838
@@ -833,7 +847,6 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
833 (void) map_read(map, adr); 847 (void) map_read(map, adr);
834 asm volatile (".rep 8; nop; .endr"); /* fill instruction prefetch */ 848 asm volatile (".rep 8; nop; .endr"); /* fill instruction prefetch */
835 local_irq_enable(); 849 local_irq_enable();
836 preempt_enable();
837} 850}
838 851
839/* 852/*
@@ -909,7 +922,7 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
909 (void) map_read(map, adr); 922 (void) map_read(map, adr);
910 asm volatile (".rep 8; nop; .endr"); 923 asm volatile (".rep 8; nop; .endr");
911 local_irq_enable(); 924 local_irq_enable();
912 preempt_enable(); 925 spin_unlock(chip->mutex);
913 asm volatile (".rep 8; nop; .endr"); 926 asm volatile (".rep 8; nop; .endr");
914 cond_resched(); 927 cond_resched();
915 928
@@ -919,15 +932,15 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
919 * a suspended erase state. If so let's wait 932 * a suspended erase state. If so let's wait
920 * until it's done. 933 * until it's done.
921 */ 934 */
922 preempt_disable(); 935 spin_lock(chip->mutex);
923 while (chip->state != newstate) { 936 while (chip->state != newstate) {
924 DECLARE_WAITQUEUE(wait, current); 937 DECLARE_WAITQUEUE(wait, current);
925 set_current_state(TASK_UNINTERRUPTIBLE); 938 set_current_state(TASK_UNINTERRUPTIBLE);
926 add_wait_queue(&chip->wq, &wait); 939 add_wait_queue(&chip->wq, &wait);
927 preempt_enable(); 940 spin_unlock(chip->mutex);
928 schedule(); 941 schedule();
929 remove_wait_queue(&chip->wq, &wait); 942 remove_wait_queue(&chip->wq, &wait);
930 preempt_disable(); 943 spin_lock(chip->mutex);
931 } 944 }
932 /* Disallow XIP again */ 945 /* Disallow XIP again */
933 local_irq_disable(); 946 local_irq_disable();
@@ -956,12 +969,14 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
956 * The INVALIDATE_CACHED_RANGE() macro is normally used in parallel while 969 * The INVALIDATE_CACHED_RANGE() macro is normally used in parallel while
957 * the flash is actively programming or erasing since we have to poll for 970 * the flash is actively programming or erasing since we have to poll for
958 * the operation to complete anyway. We can't do that in a generic way with 971 * the operation to complete anyway. We can't do that in a generic way with
959 * a XIP setup so do it before the actual flash operation in this case. 972 * a XIP setup so do it before the actual flash operation in this case
973 * and stub it out from INVALIDATE_CACHE_UDELAY.
960 */ 974 */
961#undef INVALIDATE_CACHED_RANGE 975#define XIP_INVAL_CACHED_RANGE(map, from, size) \
962#define INVALIDATE_CACHED_RANGE(x...) 976 INVALIDATE_CACHED_RANGE(map, from, size)
963#define XIP_INVAL_CACHED_RANGE(map, from, size) \ 977
964 do { if(map->inval_cache) map->inval_cache(map, from, size); } while(0) 978#define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec) \
979 UDELAY(map, chip, adr, usec)
965 980
966/* 981/*
967 * Extra notes: 982 * Extra notes:
@@ -984,11 +999,23 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
984 999
985#define xip_disable(map, chip, adr) 1000#define xip_disable(map, chip, adr)
986#define xip_enable(map, chip, adr) 1001#define xip_enable(map, chip, adr)
987
988#define UDELAY(map, chip, adr, usec) cfi_udelay(usec)
989
990#define XIP_INVAL_CACHED_RANGE(x...) 1002#define XIP_INVAL_CACHED_RANGE(x...)
991 1003
1004#define UDELAY(map, chip, adr, usec) \
1005do { \
1006 spin_unlock(chip->mutex); \
1007 cfi_udelay(usec); \
1008 spin_lock(chip->mutex); \
1009} while (0)
1010
1011#define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec) \
1012do { \
1013 spin_unlock(chip->mutex); \
1014 INVALIDATE_CACHED_RANGE(map, adr, len); \
1015 cfi_udelay(usec); \
1016 spin_lock(chip->mutex); \
1017} while (0)
1018
992#endif 1019#endif
993 1020
994static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) 1021static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
@@ -1176,111 +1203,11 @@ static int cfi_intelext_read (struct mtd_info *mtd, loff_t from, size_t len, siz
1176 return ret; 1203 return ret;
1177} 1204}
1178 1205
1179#if 0
1180static int __xipram cfi_intelext_read_prot_reg (struct mtd_info *mtd,
1181 loff_t from, size_t len,
1182 size_t *retlen,
1183 u_char *buf,
1184 int base_offst, int reg_sz)
1185{
1186 struct map_info *map = mtd->priv;
1187 struct cfi_private *cfi = map->fldrv_priv;
1188 struct cfi_pri_intelext *extp = cfi->cmdset_priv;
1189 struct flchip *chip;
1190 int ofs_factor = cfi->interleave * cfi->device_type;
1191 int count = len;
1192 int chip_num, offst;
1193 int ret;
1194
1195 chip_num = ((unsigned int)from/reg_sz);
1196 offst = from - (reg_sz*chip_num)+base_offst;
1197
1198 while (count) {
1199 /* Calculate which chip & protection register offset we need */
1200
1201 if (chip_num >= cfi->numchips)
1202 goto out;
1203
1204 chip = &cfi->chips[chip_num];
1205
1206 spin_lock(chip->mutex);
1207 ret = get_chip(map, chip, chip->start, FL_JEDEC_QUERY);
1208 if (ret) {
1209 spin_unlock(chip->mutex);
1210 return (len-count)?:ret;
1211 }
1212
1213 xip_disable(map, chip, chip->start);
1214
1215 if (chip->state != FL_JEDEC_QUERY) {
1216 map_write(map, CMD(0x90), chip->start);
1217 chip->state = FL_JEDEC_QUERY;
1218 }
1219
1220 while (count && ((offst-base_offst) < reg_sz)) {
1221 *buf = map_read8(map,(chip->start+((extp->ProtRegAddr+1)*ofs_factor)+offst));
1222 buf++;
1223 offst++;
1224 count--;
1225 }
1226
1227 xip_enable(map, chip, chip->start);
1228 put_chip(map, chip, chip->start);
1229 spin_unlock(chip->mutex);
1230
1231 /* Move on to the next chip */
1232 chip_num++;
1233 offst = base_offst;
1234 }
1235
1236 out:
1237 return len-count;
1238}
1239
1240static int cfi_intelext_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
1241{
1242 struct map_info *map = mtd->priv;
1243 struct cfi_private *cfi = map->fldrv_priv;
1244 struct cfi_pri_intelext *extp=cfi->cmdset_priv;
1245 int base_offst,reg_sz;
1246
1247 /* Check that we actually have some protection registers */
1248 if(!extp || !(extp->FeatureSupport&64)){
1249 printk(KERN_WARNING "%s: This flash device has no protection data to read!\n",map->name);
1250 return 0;
1251 }
1252
1253 base_offst=(1<<extp->FactProtRegSize);
1254 reg_sz=(1<<extp->UserProtRegSize);
1255
1256 return cfi_intelext_read_prot_reg(mtd, from, len, retlen, buf, base_offst, reg_sz);
1257}
1258
1259static int cfi_intelext_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
1260{
1261 struct map_info *map = mtd->priv;
1262 struct cfi_private *cfi = map->fldrv_priv;
1263 struct cfi_pri_intelext *extp=cfi->cmdset_priv;
1264 int base_offst,reg_sz;
1265
1266 /* Check that we actually have some protection registers */
1267 if(!extp || !(extp->FeatureSupport&64)){
1268 printk(KERN_WARNING "%s: This flash device has no protection data to read!\n",map->name);
1269 return 0;
1270 }
1271
1272 base_offst=0;
1273 reg_sz=(1<<extp->FactProtRegSize);
1274
1275 return cfi_intelext_read_prot_reg(mtd, from, len, retlen, buf, base_offst, reg_sz);
1276}
1277#endif
1278
1279static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, 1206static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1280 unsigned long adr, map_word datum) 1207 unsigned long adr, map_word datum, int mode)
1281{ 1208{
1282 struct cfi_private *cfi = map->fldrv_priv; 1209 struct cfi_private *cfi = map->fldrv_priv;
1283 map_word status, status_OK; 1210 map_word status, status_OK, write_cmd;
1284 unsigned long timeo; 1211 unsigned long timeo;
1285 int z, ret=0; 1212 int z, ret=0;
1286 1213
@@ -1288,9 +1215,14 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1288 1215
1289 /* Let's determine this according to the interleave only once */ 1216 /* Let's determine this according to the interleave only once */
1290 status_OK = CMD(0x80); 1217 status_OK = CMD(0x80);
1218 switch (mode) {
1219 case FL_WRITING: write_cmd = CMD(0x40); break;
1220 case FL_OTP_WRITE: write_cmd = CMD(0xc0); break;
1221 default: return -EINVAL;
1222 }
1291 1223
1292 spin_lock(chip->mutex); 1224 spin_lock(chip->mutex);
1293 ret = get_chip(map, chip, adr, FL_WRITING); 1225 ret = get_chip(map, chip, adr, mode);
1294 if (ret) { 1226 if (ret) {
1295 spin_unlock(chip->mutex); 1227 spin_unlock(chip->mutex);
1296 return ret; 1228 return ret;
@@ -1299,19 +1231,18 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1299 XIP_INVAL_CACHED_RANGE(map, adr, map_bankwidth(map)); 1231 XIP_INVAL_CACHED_RANGE(map, adr, map_bankwidth(map));
1300 ENABLE_VPP(map); 1232 ENABLE_VPP(map);
1301 xip_disable(map, chip, adr); 1233 xip_disable(map, chip, adr);
1302 map_write(map, CMD(0x40), adr); 1234 map_write(map, write_cmd, adr);
1303 map_write(map, datum, adr); 1235 map_write(map, datum, adr);
1304 chip->state = FL_WRITING; 1236 chip->state = mode;
1305 1237
1306 spin_unlock(chip->mutex); 1238 INVALIDATE_CACHE_UDELAY(map, chip,
1307 INVALIDATE_CACHED_RANGE(map, adr, map_bankwidth(map)); 1239 adr, map_bankwidth(map),
1308 UDELAY(map, chip, adr, chip->word_write_time); 1240 chip->word_write_time);
1309 spin_lock(chip->mutex);
1310 1241
1311 timeo = jiffies + (HZ/2); 1242 timeo = jiffies + (HZ/2);
1312 z = 0; 1243 z = 0;
1313 for (;;) { 1244 for (;;) {
1314 if (chip->state != FL_WRITING) { 1245 if (chip->state != mode) {
1315 /* Someone's suspended the write. Sleep */ 1246 /* Someone's suspended the write. Sleep */
1316 DECLARE_WAITQUEUE(wait, current); 1247 DECLARE_WAITQUEUE(wait, current);
1317 1248
@@ -1339,10 +1270,8 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1339 } 1270 }
1340 1271
1341 /* Latency issues. Drop the lock, wait a while and retry */ 1272 /* Latency issues. Drop the lock, wait a while and retry */
1342 spin_unlock(chip->mutex);
1343 z++; 1273 z++;
1344 UDELAY(map, chip, adr, 1); 1274 UDELAY(map, chip, adr, 1);
1345 spin_lock(chip->mutex);
1346 } 1275 }
1347 if (!z) { 1276 if (!z) {
1348 chip->word_write_time--; 1277 chip->word_write_time--;
@@ -1399,7 +1328,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1399 datum = map_word_load_partial(map, datum, buf, gap, n); 1328 datum = map_word_load_partial(map, datum, buf, gap, n);
1400 1329
1401 ret = do_write_oneword(map, &cfi->chips[chipnum], 1330 ret = do_write_oneword(map, &cfi->chips[chipnum],
1402 bus_ofs, datum); 1331 bus_ofs, datum, FL_WRITING);
1403 if (ret) 1332 if (ret)
1404 return ret; 1333 return ret;
1405 1334
@@ -1420,7 +1349,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1420 map_word datum = map_word_load(map, buf); 1349 map_word datum = map_word_load(map, buf);
1421 1350
1422 ret = do_write_oneword(map, &cfi->chips[chipnum], 1351 ret = do_write_oneword(map, &cfi->chips[chipnum],
1423 ofs, datum); 1352 ofs, datum, FL_WRITING);
1424 if (ret) 1353 if (ret)
1425 return ret; 1354 return ret;
1426 1355
@@ -1444,7 +1373,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1444 datum = map_word_load_partial(map, datum, buf, 0, len); 1373 datum = map_word_load_partial(map, datum, buf, 0, len);
1445 1374
1446 ret = do_write_oneword(map, &cfi->chips[chipnum], 1375 ret = do_write_oneword(map, &cfi->chips[chipnum],
1447 ofs, datum); 1376 ofs, datum, FL_WRITING);
1448 if (ret) 1377 if (ret)
1449 return ret; 1378 return ret;
1450 1379
@@ -1506,9 +1435,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1506 if (map_word_andequal(map, status, status_OK, status_OK)) 1435 if (map_word_andequal(map, status, status_OK, status_OK))
1507 break; 1436 break;
1508 1437
1509 spin_unlock(chip->mutex);
1510 UDELAY(map, chip, cmd_adr, 1); 1438 UDELAY(map, chip, cmd_adr, 1);
1511 spin_lock(chip->mutex);
1512 1439
1513 if (++z > 20) { 1440 if (++z > 20) {
1514 /* Argh. Not ready for write to buffer */ 1441 /* Argh. Not ready for write to buffer */
@@ -1554,10 +1481,9 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1554 map_write(map, CMD(0xd0), cmd_adr); 1481 map_write(map, CMD(0xd0), cmd_adr);
1555 chip->state = FL_WRITING; 1482 chip->state = FL_WRITING;
1556 1483
1557 spin_unlock(chip->mutex); 1484 INVALIDATE_CACHE_UDELAY(map, chip,
1558 INVALIDATE_CACHED_RANGE(map, adr, len); 1485 cmd_adr, len,
1559 UDELAY(map, chip, cmd_adr, chip->buffer_write_time); 1486 chip->buffer_write_time);
1560 spin_lock(chip->mutex);
1561 1487
1562 timeo = jiffies + (HZ/2); 1488 timeo = jiffies + (HZ/2);
1563 z = 0; 1489 z = 0;
@@ -1589,10 +1515,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1589 } 1515 }
1590 1516
1591 /* Latency issues. Drop the lock, wait a while and retry */ 1517 /* Latency issues. Drop the lock, wait a while and retry */
1592 spin_unlock(chip->mutex);
1593 UDELAY(map, chip, cmd_adr, 1);
1594 z++; 1518 z++;
1595 spin_lock(chip->mutex); 1519 UDELAY(map, chip, cmd_adr, 1);
1596 } 1520 }
1597 if (!z) { 1521 if (!z) {
1598 chip->buffer_write_time--; 1522 chip->buffer_write_time--;
@@ -1720,10 +1644,9 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1720 chip->state = FL_ERASING; 1644 chip->state = FL_ERASING;
1721 chip->erase_suspended = 0; 1645 chip->erase_suspended = 0;
1722 1646
1723 spin_unlock(chip->mutex); 1647 INVALIDATE_CACHE_UDELAY(map, chip,
1724 INVALIDATE_CACHED_RANGE(map, adr, len); 1648 adr, len,
1725 UDELAY(map, chip, adr, chip->erase_time*1000/2); 1649 chip->erase_time*1000/2);
1726 spin_lock(chip->mutex);
1727 1650
1728 /* FIXME. Use a timer to check this, and return immediately. */ 1651 /* FIXME. Use a timer to check this, and return immediately. */
1729 /* Once the state machine's known to be working I'll do that */ 1652 /* Once the state machine's known to be working I'll do that */
@@ -1768,9 +1691,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1768 } 1691 }
1769 1692
1770 /* Latency issues. Drop the lock, wait a while and retry */ 1693 /* Latency issues. Drop the lock, wait a while and retry */
1771 spin_unlock(chip->mutex);
1772 UDELAY(map, chip, adr, 1000000/HZ); 1694 UDELAY(map, chip, adr, 1000000/HZ);
1773 spin_lock(chip->mutex);
1774 } 1695 }
1775 1696
1776 /* We've broken this before. It doesn't hurt to be safe */ 1697 /* We've broken this before. It doesn't hurt to be safe */
@@ -1780,44 +1701,34 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1780 1701
1781 /* check for lock bit */ 1702 /* check for lock bit */
1782 if (map_word_bitsset(map, status, CMD(0x3a))) { 1703 if (map_word_bitsset(map, status, CMD(0x3a))) {
1783 unsigned char chipstatus; 1704 unsigned long chipstatus;
1784 1705
1785 /* Reset the error bits */ 1706 /* Reset the error bits */
1786 map_write(map, CMD(0x50), adr); 1707 map_write(map, CMD(0x50), adr);
1787 map_write(map, CMD(0x70), adr); 1708 map_write(map, CMD(0x70), adr);
1788 xip_enable(map, chip, adr); 1709 xip_enable(map, chip, adr);
1789 1710
1790 chipstatus = status.x[0]; 1711 chipstatus = MERGESTATUS(status);
1791 if (!map_word_equal(map, status, CMD(chipstatus))) {
1792 int i, w;
1793 for (w=0; w<map_words(map); w++) {
1794 for (i = 0; i<cfi_interleave(cfi); i++) {
1795 chipstatus |= status.x[w] >> (cfi->device_type * 8);
1796 }
1797 }
1798 printk(KERN_WARNING "Status is not identical for all chips: 0x%lx. Merging to give 0x%02x\n",
1799 status.x[0], chipstatus);
1800 }
1801 1712
1802 if ((chipstatus & 0x30) == 0x30) { 1713 if ((chipstatus & 0x30) == 0x30) {
1803 printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus); 1714 printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%lx\n", chipstatus);
1804 ret = -EIO; 1715 ret = -EIO;
1805 } else if (chipstatus & 0x02) { 1716 } else if (chipstatus & 0x02) {
1806 /* Protection bit set */ 1717 /* Protection bit set */
1807 ret = -EROFS; 1718 ret = -EROFS;
1808 } else if (chipstatus & 0x8) { 1719 } else if (chipstatus & 0x8) {
1809 /* Voltage */ 1720 /* Voltage */
1810 printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%x\n", chipstatus); 1721 printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%lx\n", chipstatus);
1811 ret = -EIO; 1722 ret = -EIO;
1812 } else if (chipstatus & 0x20) { 1723 } else if (chipstatus & 0x20) {
1813 if (retries--) { 1724 if (retries--) {
1814 printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x. Retrying...\n", adr, chipstatus); 1725 printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus);
1815 timeo = jiffies + HZ; 1726 timeo = jiffies + HZ;
1816 put_chip(map, chip, adr); 1727 put_chip(map, chip, adr);
1817 spin_unlock(chip->mutex); 1728 spin_unlock(chip->mutex);
1818 goto retry; 1729 goto retry;
1819 } 1730 }
1820 printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x\n", adr, chipstatus); 1731 printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%lx\n", adr, chipstatus);
1821 ret = -EIO; 1732 ret = -EIO;
1822 } 1733 }
1823 } else { 1734 } else {
@@ -1882,6 +1793,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
1882 1793
1883 if (chip->state == FL_SYNCING) { 1794 if (chip->state == FL_SYNCING) {
1884 chip->state = chip->oldstate; 1795 chip->state = chip->oldstate;
1796 chip->oldstate = FL_READY;
1885 wake_up(&chip->wq); 1797 wake_up(&chip->wq);
1886 } 1798 }
1887 spin_unlock(chip->mutex); 1799 spin_unlock(chip->mutex);
@@ -1897,8 +1809,9 @@ static int __xipram do_printlockstatus_oneblock(struct map_info *map,
1897 struct cfi_private *cfi = map->fldrv_priv; 1809 struct cfi_private *cfi = map->fldrv_priv;
1898 int status, ofs_factor = cfi->interleave * cfi->device_type; 1810 int status, ofs_factor = cfi->interleave * cfi->device_type;
1899 1811
1812 adr += chip->start;
1900 xip_disable(map, chip, adr+(2*ofs_factor)); 1813 xip_disable(map, chip, adr+(2*ofs_factor));
1901 cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); 1814 map_write(map, CMD(0x90), adr+(2*ofs_factor));
1902 chip->state = FL_JEDEC_QUERY; 1815 chip->state = FL_JEDEC_QUERY;
1903 status = cfi_read_query(map, adr+(2*ofs_factor)); 1816 status = cfi_read_query(map, adr+(2*ofs_factor));
1904 xip_enable(map, chip, 0); 1817 xip_enable(map, chip, 0);
@@ -1915,6 +1828,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
1915 unsigned long adr, int len, void *thunk) 1828 unsigned long adr, int len, void *thunk)
1916{ 1829{
1917 struct cfi_private *cfi = map->fldrv_priv; 1830 struct cfi_private *cfi = map->fldrv_priv;
1831 struct cfi_pri_intelext *extp = cfi->cmdset_priv;
1918 map_word status, status_OK; 1832 map_word status, status_OK;
1919 unsigned long timeo = jiffies + HZ; 1833 unsigned long timeo = jiffies + HZ;
1920 int ret; 1834 int ret;
@@ -1944,9 +1858,13 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
1944 } else 1858 } else
1945 BUG(); 1859 BUG();
1946 1860
1947 spin_unlock(chip->mutex); 1861 /*
1948 UDELAY(map, chip, adr, 1000000/HZ); 1862 * If Instant Individual Block Locking supported then no need
1949 spin_lock(chip->mutex); 1863 * to delay.
1864 */
1865
1866 if (!extp || !(extp->FeatureSupport & (1 << 5)))
1867 UDELAY(map, chip, adr, 1000000/HZ);
1950 1868
1951 /* FIXME. Use a timer to check this, and return immediately. */ 1869 /* FIXME. Use a timer to check this, and return immediately. */
1952 /* Once the state machine's known to be working I'll do that */ 1870 /* Once the state machine's known to be working I'll do that */
@@ -1973,9 +1891,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
1973 } 1891 }
1974 1892
1975 /* Latency issues. Drop the lock, wait a while and retry */ 1893 /* Latency issues. Drop the lock, wait a while and retry */
1976 spin_unlock(chip->mutex);
1977 UDELAY(map, chip, adr, 1); 1894 UDELAY(map, chip, adr, 1);
1978 spin_lock(chip->mutex);
1979 } 1895 }
1980 1896
1981 /* Done and happy. */ 1897 /* Done and happy. */
@@ -2034,6 +1950,274 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
2034 return ret; 1950 return ret;
2035} 1951}
2036 1952
1953#ifdef CONFIG_MTD_OTP
1954
1955typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip,
1956 u_long data_offset, u_char *buf, u_int size,
1957 u_long prot_offset, u_int groupno, u_int groupsize);
1958
1959static int __xipram
1960do_otp_read(struct map_info *map, struct flchip *chip, u_long offset,
1961 u_char *buf, u_int size, u_long prot, u_int grpno, u_int grpsz)
1962{
1963 struct cfi_private *cfi = map->fldrv_priv;
1964 int ret;
1965
1966 spin_lock(chip->mutex);
1967 ret = get_chip(map, chip, chip->start, FL_JEDEC_QUERY);
1968 if (ret) {
1969 spin_unlock(chip->mutex);
1970 return ret;
1971 }
1972
1973 /* let's ensure we're not reading back cached data from array mode */
1974 INVALIDATE_CACHED_RANGE(map, chip->start + offset, size);
1975
1976 xip_disable(map, chip, chip->start);
1977 if (chip->state != FL_JEDEC_QUERY) {
1978 map_write(map, CMD(0x90), chip->start);
1979 chip->state = FL_JEDEC_QUERY;
1980 }
1981 map_copy_from(map, buf, chip->start + offset, size);
1982 xip_enable(map, chip, chip->start);
1983
1984 /* then ensure we don't keep OTP data in the cache */
1985 INVALIDATE_CACHED_RANGE(map, chip->start + offset, size);
1986
1987 put_chip(map, chip, chip->start);
1988 spin_unlock(chip->mutex);
1989 return 0;
1990}
1991
1992static int
1993do_otp_write(struct map_info *map, struct flchip *chip, u_long offset,
1994 u_char *buf, u_int size, u_long prot, u_int grpno, u_int grpsz)
1995{
1996 int ret;
1997
1998 while (size) {
1999 unsigned long bus_ofs = offset & ~(map_bankwidth(map)-1);
2000 int gap = offset - bus_ofs;
2001 int n = min_t(int, size, map_bankwidth(map)-gap);
2002 map_word datum = map_word_ff(map);
2003
2004 datum = map_word_load_partial(map, datum, buf, gap, n);
2005 ret = do_write_oneword(map, chip, bus_ofs, datum, FL_OTP_WRITE);
2006 if (ret)
2007 return ret;
2008
2009 offset += n;
2010 buf += n;
2011 size -= n;
2012 }
2013
2014 return 0;
2015}
2016
2017static int
2018do_otp_lock(struct map_info *map, struct flchip *chip, u_long offset,
2019 u_char *buf, u_int size, u_long prot, u_int grpno, u_int grpsz)
2020{
2021 struct cfi_private *cfi = map->fldrv_priv;
2022 map_word datum;
2023
2024 /* make sure area matches group boundaries */
2025 if (size != grpsz)
2026 return -EXDEV;
2027
2028 datum = map_word_ff(map);
2029 datum = map_word_clr(map, datum, CMD(1 << grpno));
2030 return do_write_oneword(map, chip, prot, datum, FL_OTP_WRITE);
2031}
2032
2033static int cfi_intelext_otp_walk(struct mtd_info *mtd, loff_t from, size_t len,
2034 size_t *retlen, u_char *buf,
2035 otp_op_t action, int user_regs)
2036{
2037 struct map_info *map = mtd->priv;
2038 struct cfi_private *cfi = map->fldrv_priv;
2039 struct cfi_pri_intelext *extp = cfi->cmdset_priv;
2040 struct flchip *chip;
2041 struct cfi_intelext_otpinfo *otp;
2042 u_long devsize, reg_prot_offset, data_offset;
2043 u_int chip_num, chip_step, field, reg_fact_size, reg_user_size;
2044 u_int groups, groupno, groupsize, reg_fact_groups, reg_user_groups;
2045 int ret;
2046
2047 *retlen = 0;
2048
2049 /* Check that we actually have some OTP registers */
2050 if (!extp || !(extp->FeatureSupport & 64) || !extp->NumProtectionFields)
2051 return -ENODATA;
2052
2053 /* we need real chips here not virtual ones */
2054 devsize = (1 << cfi->cfiq->DevSize) * cfi->interleave;
2055 chip_step = devsize >> cfi->chipshift;
2056 chip_num = 0;
2057
2058 /* Some chips have OTP located in the _top_ partition only.
2059 For example: Intel 28F256L18T (T means top-parameter device) */
2060 if (cfi->mfr == MANUFACTURER_INTEL) {
2061 switch (cfi->id) {
2062 case 0x880b:
2063 case 0x880c:
2064 case 0x880d:
2065 chip_num = chip_step - 1;
2066 }
2067 }
2068
2069 for ( ; chip_num < cfi->numchips; chip_num += chip_step) {
2070 chip = &cfi->chips[chip_num];
2071 otp = (struct cfi_intelext_otpinfo *)&extp->extra[0];
2072
2073 /* first OTP region */
2074 field = 0;
2075 reg_prot_offset = extp->ProtRegAddr;
2076 reg_fact_groups = 1;
2077 reg_fact_size = 1 << extp->FactProtRegSize;
2078 reg_user_groups = 1;
2079 reg_user_size = 1 << extp->UserProtRegSize;
2080
2081 while (len > 0) {
2082 /* flash geometry fixup */
2083 data_offset = reg_prot_offset + 1;
2084 data_offset *= cfi->interleave * cfi->device_type;
2085 reg_prot_offset *= cfi->interleave * cfi->device_type;
2086 reg_fact_size *= cfi->interleave;
2087 reg_user_size *= cfi->interleave;
2088
2089 if (user_regs) {
2090 groups = reg_user_groups;
2091 groupsize = reg_user_size;
2092 /* skip over factory reg area */
2093 groupno = reg_fact_groups;
2094 data_offset += reg_fact_groups * reg_fact_size;
2095 } else {
2096 groups = reg_fact_groups;
2097 groupsize = reg_fact_size;
2098 groupno = 0;
2099 }
2100
2101 while (len > 0 && groups > 0) {
2102 if (!action) {
2103 /*
2104 * Special case: if action is NULL
2105 * we fill buf with otp_info records.
2106 */
2107 struct otp_info *otpinfo;
2108 map_word lockword;
2109 len -= sizeof(struct otp_info);
2110 if (len <= 0)
2111 return -ENOSPC;
2112 ret = do_otp_read(map, chip,
2113 reg_prot_offset,
2114 (u_char *)&lockword,
2115 map_bankwidth(map),
2116 0, 0, 0);
2117 if (ret)
2118 return ret;
2119 otpinfo = (struct otp_info *)buf;
2120 otpinfo->start = from;
2121 otpinfo->length = groupsize;
2122 otpinfo->locked =
2123 !map_word_bitsset(map, lockword,
2124 CMD(1 << groupno));
2125 from += groupsize;
2126 buf += sizeof(*otpinfo);
2127 *retlen += sizeof(*otpinfo);
2128 } else if (from >= groupsize) {
2129 from -= groupsize;
2130 data_offset += groupsize;
2131 } else {
2132 int size = groupsize;
2133 data_offset += from;
2134 size -= from;
2135 from = 0;
2136 if (size > len)
2137 size = len;
2138 ret = action(map, chip, data_offset,
2139 buf, size, reg_prot_offset,
2140 groupno, groupsize);
2141 if (ret < 0)
2142 return ret;
2143 buf += size;
2144 len -= size;
2145 *retlen += size;
2146 data_offset += size;
2147 }
2148 groupno++;
2149 groups--;
2150 }
2151
2152 /* next OTP region */
2153 if (++field == extp->NumProtectionFields)
2154 break;
2155 reg_prot_offset = otp->ProtRegAddr;
2156 reg_fact_groups = otp->FactGroups;
2157 reg_fact_size = 1 << otp->FactProtRegSize;
2158 reg_user_groups = otp->UserGroups;
2159 reg_user_size = 1 << otp->UserProtRegSize;
2160 otp++;
2161 }
2162 }
2163
2164 return 0;
2165}
2166
2167static int cfi_intelext_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
2168 size_t len, size_t *retlen,
2169 u_char *buf)
2170{
2171 return cfi_intelext_otp_walk(mtd, from, len, retlen,
2172 buf, do_otp_read, 0);
2173}
2174
2175static int cfi_intelext_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
2176 size_t len, size_t *retlen,
2177 u_char *buf)
2178{
2179 return cfi_intelext_otp_walk(mtd, from, len, retlen,
2180 buf, do_otp_read, 1);
2181}
2182
2183static int cfi_intelext_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
2184 size_t len, size_t *retlen,
2185 u_char *buf)
2186{
2187 return cfi_intelext_otp_walk(mtd, from, len, retlen,
2188 buf, do_otp_write, 1);
2189}
2190
2191static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
2192 loff_t from, size_t len)
2193{
2194 size_t retlen;
2195 return cfi_intelext_otp_walk(mtd, from, len, &retlen,
2196 NULL, do_otp_lock, 1);
2197}
2198
2199static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd,
2200 struct otp_info *buf, size_t len)
2201{
2202 size_t retlen;
2203 int ret;
2204
2205 ret = cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf, NULL, 0);
2206 return ret ? : retlen;
2207}
2208
2209static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd,
2210 struct otp_info *buf, size_t len)
2211{
2212 size_t retlen;
2213 int ret;
2214
2215 ret = cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf, NULL, 1);
2216 return ret ? : retlen;
2217}
2218
2219#endif
2220
2037static int cfi_intelext_suspend(struct mtd_info *mtd) 2221static int cfi_intelext_suspend(struct mtd_info *mtd)
2038{ 2222{
2039 struct map_info *map = mtd->priv; 2223 struct map_info *map = mtd->priv;
@@ -2125,10 +2309,46 @@ static void cfi_intelext_resume(struct mtd_info *mtd)
2125 } 2309 }
2126} 2310}
2127 2311
2312static int cfi_intelext_reset(struct mtd_info *mtd)
2313{
2314 struct map_info *map = mtd->priv;
2315 struct cfi_private *cfi = map->fldrv_priv;
2316 int i, ret;
2317
2318 for (i=0; i < cfi->numchips; i++) {
2319 struct flchip *chip = &cfi->chips[i];
2320
2321 /* force the completion of any ongoing operation
2322 and switch to array mode so any bootloader in
2323 flash is accessible for soft reboot. */
2324 spin_lock(chip->mutex);
2325 ret = get_chip(map, chip, chip->start, FL_SYNCING);
2326 if (!ret) {
2327 map_write(map, CMD(0xff), chip->start);
2328 chip->state = FL_READY;
2329 }
2330 spin_unlock(chip->mutex);
2331 }
2332
2333 return 0;
2334}
2335
2336static int cfi_intelext_reboot(struct notifier_block *nb, unsigned long val,
2337 void *v)
2338{
2339 struct mtd_info *mtd;
2340
2341 mtd = container_of(nb, struct mtd_info, reboot_notifier);
2342 cfi_intelext_reset(mtd);
2343 return NOTIFY_DONE;
2344}
2345
2128static void cfi_intelext_destroy(struct mtd_info *mtd) 2346static void cfi_intelext_destroy(struct mtd_info *mtd)
2129{ 2347{
2130 struct map_info *map = mtd->priv; 2348 struct map_info *map = mtd->priv;
2131 struct cfi_private *cfi = map->fldrv_priv; 2349 struct cfi_private *cfi = map->fldrv_priv;
2350 cfi_intelext_reset(mtd);
2351 unregister_reboot_notifier(&mtd->reboot_notifier);
2132 kfree(cfi->cmdset_priv); 2352 kfree(cfi->cmdset_priv);
2133 kfree(cfi->cfiq); 2353 kfree(cfi->cfiq);
2134 kfree(cfi->chips[0].priv); 2354 kfree(cfi->chips[0].priv);
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index fca8ff6f7e14..c76c30de48fb 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -4,16 +4,20 @@
4 * 4 *
5 * Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp> 5 * Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp>
6 * Copyright (C) 2004 Arcom Control Systems Ltd <linux@arcom.com> 6 * Copyright (C) 2004 Arcom Control Systems Ltd <linux@arcom.com>
7 * Copyright (C) 2005 MontaVista Software Inc. <source@mvista.com>
7 * 8 *
8 * 2_by_8 routines added by Simon Munton 9 * 2_by_8 routines added by Simon Munton
9 * 10 *
10 * 4_by_16 work by Carolyn J. Smith 11 * 4_by_16 work by Carolyn J. Smith
11 * 12 *
13 * XIP support hooks by Vitaly Wool (based on code for Intel flash
14 * by Nicolas Pitre)
15 *
12 * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com 16 * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
13 * 17 *
14 * This code is GPL 18 * This code is GPL
15 * 19 *
16 * $Id: cfi_cmdset_0002.c,v 1.114 2004/12/11 15:43:53 dedekind Exp $ 20 * $Id: cfi_cmdset_0002.c,v 1.118 2005/07/04 22:34:29 gleixner Exp $
17 * 21 *
18 */ 22 */
19 23
@@ -34,6 +38,7 @@
34#include <linux/mtd/map.h> 38#include <linux/mtd/map.h>
35#include <linux/mtd/mtd.h> 39#include <linux/mtd/mtd.h>
36#include <linux/mtd/cfi.h> 40#include <linux/mtd/cfi.h>
41#include <linux/mtd/xip.h>
37 42
38#define AMD_BOOTLOC_BUG 43#define AMD_BOOTLOC_BUG
39#define FORCE_WORD_WRITE 0 44#define FORCE_WORD_WRITE 0
@@ -43,6 +48,7 @@
43#define MANUFACTURER_AMD 0x0001 48#define MANUFACTURER_AMD 0x0001
44#define MANUFACTURER_SST 0x00BF 49#define MANUFACTURER_SST 0x00BF
45#define SST49LF004B 0x0060 50#define SST49LF004B 0x0060
51#define SST49LF008A 0x005a
46 52
47static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); 53static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
48static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); 54static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
@@ -191,6 +197,7 @@ static struct cfi_fixup cfi_fixup_table[] = {
191}; 197};
192static struct cfi_fixup jedec_fixup_table[] = { 198static struct cfi_fixup jedec_fixup_table[] = {
193 { MANUFACTURER_SST, SST49LF004B, fixup_use_fwh_lock, NULL, }, 199 { MANUFACTURER_SST, SST49LF004B, fixup_use_fwh_lock, NULL, },
200 { MANUFACTURER_SST, SST49LF008A, fixup_use_fwh_lock, NULL, },
194 { 0, 0, NULL, NULL } 201 { 0, 0, NULL, NULL }
195}; 202};
196 203
@@ -391,7 +398,7 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
391 * correctly and is therefore not done (particulary with interleaved chips 398 * correctly and is therefore not done (particulary with interleaved chips
392 * as each chip must be checked independantly of the others). 399 * as each chip must be checked independantly of the others).
393 */ 400 */
394static int chip_ready(struct map_info *map, unsigned long addr) 401static int __xipram chip_ready(struct map_info *map, unsigned long addr)
395{ 402{
396 map_word d, t; 403 map_word d, t;
397 404
@@ -401,6 +408,32 @@ static int chip_ready(struct map_info *map, unsigned long addr)
401 return map_word_equal(map, d, t); 408 return map_word_equal(map, d, t);
402} 409}
403 410
411/*
412 * Return true if the chip is ready and has the correct value.
413 *
414 * Ready is one of: read mode, query mode, erase-suspend-read mode (in any
415 * non-suspended sector) and it is indicated by no bits toggling.
416 *
417 * Error are indicated by toggling bits or bits held with the wrong value,
418 * or with bits toggling.
419 *
420 * Note that anything more complicated than checking if no bits are toggling
421 * (including checking DQ5 for an error status) is tricky to get working
422 * correctly and is therefore not done (particulary with interleaved chips
423 * as each chip must be checked independantly of the others).
424 *
425 */
426static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word expected)
427{
428 map_word oldd, curd;
429
430 oldd = map_read(map, addr);
431 curd = map_read(map, addr);
432
433 return map_word_equal(map, oldd, curd) &&
434 map_word_equal(map, curd, expected);
435}
436
404static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) 437static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
405{ 438{
406 DECLARE_WAITQUEUE(wait, current); 439 DECLARE_WAITQUEUE(wait, current);
@@ -420,12 +453,12 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
420 453
421 if (time_after(jiffies, timeo)) { 454 if (time_after(jiffies, timeo)) {
422 printk(KERN_ERR "Waiting for chip to be ready timed out.\n"); 455 printk(KERN_ERR "Waiting for chip to be ready timed out.\n");
423 cfi_spin_unlock(chip->mutex); 456 spin_unlock(chip->mutex);
424 return -EIO; 457 return -EIO;
425 } 458 }
426 cfi_spin_unlock(chip->mutex); 459 spin_unlock(chip->mutex);
427 cfi_udelay(1); 460 cfi_udelay(1);
428 cfi_spin_lock(chip->mutex); 461 spin_lock(chip->mutex);
429 /* Someone else might have been playing with it. */ 462 /* Someone else might have been playing with it. */
430 goto retry; 463 goto retry;
431 } 464 }
@@ -473,15 +506,23 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
473 return -EIO; 506 return -EIO;
474 } 507 }
475 508
476 cfi_spin_unlock(chip->mutex); 509 spin_unlock(chip->mutex);
477 cfi_udelay(1); 510 cfi_udelay(1);
478 cfi_spin_lock(chip->mutex); 511 spin_lock(chip->mutex);
479 /* Nobody will touch it while it's in state FL_ERASE_SUSPENDING. 512 /* Nobody will touch it while it's in state FL_ERASE_SUSPENDING.
480 So we can just loop here. */ 513 So we can just loop here. */
481 } 514 }
482 chip->state = FL_READY; 515 chip->state = FL_READY;
483 return 0; 516 return 0;
484 517
518 case FL_XIP_WHILE_ERASING:
519 if (mode != FL_READY && mode != FL_POINT &&
520 (!cfip || !(cfip->EraseSuspend&2)))
521 goto sleep;
522 chip->oldstate = chip->state;
523 chip->state = FL_READY;
524 return 0;
525
485 case FL_POINT: 526 case FL_POINT:
486 /* Only if there's no operation suspended... */ 527 /* Only if there's no operation suspended... */
487 if (mode == FL_READY && chip->oldstate == FL_READY) 528 if (mode == FL_READY && chip->oldstate == FL_READY)
@@ -491,10 +532,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
491 sleep: 532 sleep:
492 set_current_state(TASK_UNINTERRUPTIBLE); 533 set_current_state(TASK_UNINTERRUPTIBLE);
493 add_wait_queue(&chip->wq, &wait); 534 add_wait_queue(&chip->wq, &wait);
494 cfi_spin_unlock(chip->mutex); 535 spin_unlock(chip->mutex);
495 schedule(); 536 schedule();
496 remove_wait_queue(&chip->wq, &wait); 537 remove_wait_queue(&chip->wq, &wait);
497 cfi_spin_lock(chip->mutex); 538 spin_lock(chip->mutex);
498 goto resettime; 539 goto resettime;
499 } 540 }
500} 541}
@@ -512,6 +553,11 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
512 chip->state = FL_ERASING; 553 chip->state = FL_ERASING;
513 break; 554 break;
514 555
556 case FL_XIP_WHILE_ERASING:
557 chip->state = chip->oldstate;
558 chip->oldstate = FL_READY;
559 break;
560
515 case FL_READY: 561 case FL_READY:
516 case FL_STATUS: 562 case FL_STATUS:
517 /* We should really make set_vpp() count, rather than doing this */ 563 /* We should really make set_vpp() count, rather than doing this */
@@ -523,6 +569,198 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
523 wake_up(&chip->wq); 569 wake_up(&chip->wq);
524} 570}
525 571
572#ifdef CONFIG_MTD_XIP
573
574/*
575 * No interrupt what so ever can be serviced while the flash isn't in array
576 * mode. This is ensured by the xip_disable() and xip_enable() functions
577 * enclosing any code path where the flash is known not to be in array mode.
578 * And within a XIP disabled code path, only functions marked with __xipram
579 * may be called and nothing else (it's a good thing to inspect generated
580 * assembly to make sure inline functions were actually inlined and that gcc
581 * didn't emit calls to its own support functions). Also configuring MTD CFI
582 * support to a single buswidth and a single interleave is also recommended.
583 */
584
585static void xip_disable(struct map_info *map, struct flchip *chip,
586 unsigned long adr)
587{
588 /* TODO: chips with no XIP use should ignore and return */
589 (void) map_read(map, adr); /* ensure mmu mapping is up to date */
590 local_irq_disable();
591}
592
593static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
594 unsigned long adr)
595{
596 struct cfi_private *cfi = map->fldrv_priv;
597
598 if (chip->state != FL_POINT && chip->state != FL_READY) {
599 map_write(map, CMD(0xf0), adr);
600 chip->state = FL_READY;
601 }
602 (void) map_read(map, adr);
603 asm volatile (".rep 8; nop; .endr"); /* fill instruction prefetch */
604 local_irq_enable();
605}
606
607/*
608 * When a delay is required for the flash operation to complete, the
609 * xip_udelay() function is polling for both the given timeout and pending
610 * (but still masked) hardware interrupts. Whenever there is an interrupt
611 * pending then the flash erase operation is suspended, array mode restored
612 * and interrupts unmasked. Task scheduling might also happen at that
613 * point. The CPU eventually returns from the interrupt or the call to
614 * schedule() and the suspended flash operation is resumed for the remaining
615 * of the delay period.
616 *
617 * Warning: this function _will_ fool interrupt latency tracing tools.
618 */
619
620static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
621 unsigned long adr, int usec)
622{
623 struct cfi_private *cfi = map->fldrv_priv;
624 struct cfi_pri_amdstd *extp = cfi->cmdset_priv;
625 map_word status, OK = CMD(0x80);
626 unsigned long suspended, start = xip_currtime();
627 flstate_t oldstate;
628
629 do {
630 cpu_relax();
631 if (xip_irqpending() && extp &&
632 ((chip->state == FL_ERASING && (extp->EraseSuspend & 2))) &&
633 (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) {
634 /*
635 * Let's suspend the erase operation when supported.
636 * Note that we currently don't try to suspend
637 * interleaved chips if there is already another
638 * operation suspended (imagine what happens
639 * when one chip was already done with the current
640 * operation while another chip suspended it, then
641 * we resume the whole thing at once). Yes, it
642 * can happen!
643 */
644 map_write(map, CMD(0xb0), adr);
645 usec -= xip_elapsed_since(start);
646 suspended = xip_currtime();
647 do {
648 if (xip_elapsed_since(suspended) > 100000) {
649 /*
650 * The chip doesn't want to suspend
651 * after waiting for 100 msecs.
652 * This is a critical error but there
653 * is not much we can do here.
654 */
655 return;
656 }
657 status = map_read(map, adr);
658 } while (!map_word_andequal(map, status, OK, OK));
659
660 /* Suspend succeeded */
661 oldstate = chip->state;
662 if (!map_word_bitsset(map, status, CMD(0x40)))
663 break;
664 chip->state = FL_XIP_WHILE_ERASING;
665 chip->erase_suspended = 1;
666 map_write(map, CMD(0xf0), adr);
667 (void) map_read(map, adr);
668 asm volatile (".rep 8; nop; .endr");
669 local_irq_enable();
670 spin_unlock(chip->mutex);
671 asm volatile (".rep 8; nop; .endr");
672 cond_resched();
673
674 /*
675 * We're back. However someone else might have
676 * decided to go write to the chip if we are in
677 * a suspended erase state. If so let's wait
678 * until it's done.
679 */
680 spin_lock(chip->mutex);
681 while (chip->state != FL_XIP_WHILE_ERASING) {
682 DECLARE_WAITQUEUE(wait, current);
683 set_current_state(TASK_UNINTERRUPTIBLE);
684 add_wait_queue(&chip->wq, &wait);
685 spin_unlock(chip->mutex);
686 schedule();
687 remove_wait_queue(&chip->wq, &wait);
688 spin_lock(chip->mutex);
689 }
690 /* Disallow XIP again */
691 local_irq_disable();
692
693 /* Resume the write or erase operation */
694 map_write(map, CMD(0x30), adr);
695 chip->state = oldstate;
696 start = xip_currtime();
697 } else if (usec >= 1000000/HZ) {
698 /*
699 * Try to save on CPU power when waiting delay
700 * is at least a system timer tick period.
701 * No need to be extremely accurate here.
702 */
703 xip_cpu_idle();
704 }
705 status = map_read(map, adr);
706 } while (!map_word_andequal(map, status, OK, OK)
707 && xip_elapsed_since(start) < usec);
708}
709
710#define UDELAY(map, chip, adr, usec) xip_udelay(map, chip, adr, usec)
711
712/*
713 * The INVALIDATE_CACHED_RANGE() macro is normally used in parallel while
714 * the flash is actively programming or erasing since we have to poll for
715 * the operation to complete anyway. We can't do that in a generic way with
716 * a XIP setup so do it before the actual flash operation in this case
717 * and stub it out from INVALIDATE_CACHE_UDELAY.
718 */
719#define XIP_INVAL_CACHED_RANGE(map, from, size) \
720 INVALIDATE_CACHED_RANGE(map, from, size)
721
722#define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec) \
723 UDELAY(map, chip, adr, usec)
724
725/*
726 * Extra notes:
727 *
728 * Activating this XIP support changes the way the code works a bit. For
729 * example the code to suspend the current process when concurrent access
730 * happens is never executed because xip_udelay() will always return with the
731 * same chip state as it was entered with. This is why there is no care for
732 * the presence of add_wait_queue() or schedule() calls from within a couple
733 * xip_disable()'d areas of code, like in do_erase_oneblock for example.
734 * The queueing and scheduling are always happening within xip_udelay().
735 *
736 * Similarly, get_chip() and put_chip() just happen to always be executed
737 * with chip->state set to FL_READY (or FL_XIP_WHILE_*) where flash state
738 * is in array mode, therefore never executing many cases therein and not
739 * causing any problem with XIP.
740 */
741
742#else
743
744#define xip_disable(map, chip, adr)
745#define xip_enable(map, chip, adr)
746#define XIP_INVAL_CACHED_RANGE(x...)
747
748#define UDELAY(map, chip, adr, usec) \
749do { \
750 spin_unlock(chip->mutex); \
751 cfi_udelay(usec); \
752 spin_lock(chip->mutex); \
753} while (0)
754
755#define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec) \
756do { \
757 spin_unlock(chip->mutex); \
758 INVALIDATE_CACHED_RANGE(map, adr, len); \
759 cfi_udelay(usec); \
760 spin_lock(chip->mutex); \
761} while (0)
762
763#endif
526 764
527static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) 765static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
528{ 766{
@@ -535,10 +773,10 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
535 /* Ensure cmd read/writes are aligned. */ 773 /* Ensure cmd read/writes are aligned. */
536 cmd_addr = adr & ~(map_bankwidth(map)-1); 774 cmd_addr = adr & ~(map_bankwidth(map)-1);
537 775
538 cfi_spin_lock(chip->mutex); 776 spin_lock(chip->mutex);
539 ret = get_chip(map, chip, cmd_addr, FL_READY); 777 ret = get_chip(map, chip, cmd_addr, FL_READY);
540 if (ret) { 778 if (ret) {
541 cfi_spin_unlock(chip->mutex); 779 spin_unlock(chip->mutex);
542 return ret; 780 return ret;
543 } 781 }
544 782
@@ -551,7 +789,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
551 789
552 put_chip(map, chip, cmd_addr); 790 put_chip(map, chip, cmd_addr);
553 791
554 cfi_spin_unlock(chip->mutex); 792 spin_unlock(chip->mutex);
555 return 0; 793 return 0;
556} 794}
557 795
@@ -605,7 +843,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
605 struct cfi_private *cfi = map->fldrv_priv; 843 struct cfi_private *cfi = map->fldrv_priv;
606 844
607 retry: 845 retry:
608 cfi_spin_lock(chip->mutex); 846 spin_lock(chip->mutex);
609 847
610 if (chip->state != FL_READY){ 848 if (chip->state != FL_READY){
611#if 0 849#if 0
@@ -614,7 +852,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
614 set_current_state(TASK_UNINTERRUPTIBLE); 852 set_current_state(TASK_UNINTERRUPTIBLE);
615 add_wait_queue(&chip->wq, &wait); 853 add_wait_queue(&chip->wq, &wait);
616 854
617 cfi_spin_unlock(chip->mutex); 855 spin_unlock(chip->mutex);
618 856
619 schedule(); 857 schedule();
620 remove_wait_queue(&chip->wq, &wait); 858 remove_wait_queue(&chip->wq, &wait);
@@ -643,7 +881,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
643 cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 881 cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
644 882
645 wake_up(&chip->wq); 883 wake_up(&chip->wq);
646 cfi_spin_unlock(chip->mutex); 884 spin_unlock(chip->mutex);
647 885
648 return 0; 886 return 0;
649} 887}
@@ -692,7 +930,7 @@ static int cfi_amdstd_secsi_read (struct mtd_info *mtd, loff_t from, size_t len,
692} 930}
693 931
694 932
695static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, map_word datum) 933static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, map_word datum)
696{ 934{
697 struct cfi_private *cfi = map->fldrv_priv; 935 struct cfi_private *cfi = map->fldrv_priv;
698 unsigned long timeo = jiffies + HZ; 936 unsigned long timeo = jiffies + HZ;
@@ -712,10 +950,10 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned
712 950
713 adr += chip->start; 951 adr += chip->start;
714 952
715 cfi_spin_lock(chip->mutex); 953 spin_lock(chip->mutex);
716 ret = get_chip(map, chip, adr, FL_WRITING); 954 ret = get_chip(map, chip, adr, FL_WRITING);
717 if (ret) { 955 if (ret) {
718 cfi_spin_unlock(chip->mutex); 956 spin_unlock(chip->mutex);
719 return ret; 957 return ret;
720 } 958 }
721 959
@@ -735,7 +973,9 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned
735 goto op_done; 973 goto op_done;
736 } 974 }
737 975
976 XIP_INVAL_CACHED_RANGE(map, adr, map_bankwidth(map));
738 ENABLE_VPP(map); 977 ENABLE_VPP(map);
978 xip_disable(map, chip, adr);
739 retry: 979 retry:
740 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 980 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
741 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); 981 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
@@ -743,9 +983,9 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned
743 map_write(map, datum, adr); 983 map_write(map, datum, adr);
744 chip->state = FL_WRITING; 984 chip->state = FL_WRITING;
745 985
746 cfi_spin_unlock(chip->mutex); 986 INVALIDATE_CACHE_UDELAY(map, chip,
747 cfi_udelay(chip->word_write_time); 987 adr, map_bankwidth(map),
748 cfi_spin_lock(chip->mutex); 988 chip->word_write_time);
749 989
750 /* See comment above for timeout value. */ 990 /* See comment above for timeout value. */
751 timeo = jiffies + uWriteTimeout; 991 timeo = jiffies + uWriteTimeout;
@@ -756,39 +996,43 @@ static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned
756 996
757 set_current_state(TASK_UNINTERRUPTIBLE); 997 set_current_state(TASK_UNINTERRUPTIBLE);
758 add_wait_queue(&chip->wq, &wait); 998 add_wait_queue(&chip->wq, &wait);
759 cfi_spin_unlock(chip->mutex); 999 spin_unlock(chip->mutex);
760 schedule(); 1000 schedule();
761 remove_wait_queue(&chip->wq, &wait); 1001 remove_wait_queue(&chip->wq, &wait);
762 timeo = jiffies + (HZ / 2); /* FIXME */ 1002 timeo = jiffies + (HZ / 2); /* FIXME */
763 cfi_spin_lock(chip->mutex); 1003 spin_lock(chip->mutex);
764 continue; 1004 continue;
765 } 1005 }
766 1006
767 if (chip_ready(map, adr)) 1007 if (chip_ready(map, adr))
768 goto op_done; 1008 break;
769 1009
770 if (time_after(jiffies, timeo)) 1010 if (time_after(jiffies, timeo)) {
1011 xip_enable(map, chip, adr);
1012 printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
1013 xip_disable(map, chip, adr);
771 break; 1014 break;
1015 }
772 1016
773 /* Latency issues. Drop the lock, wait a while and retry */ 1017 /* Latency issues. Drop the lock, wait a while and retry */
774 cfi_spin_unlock(chip->mutex); 1018 UDELAY(map, chip, adr, 1);
775 cfi_udelay(1);
776 cfi_spin_lock(chip->mutex);
777 } 1019 }
1020 /* Did we succeed? */
1021 if (!chip_good(map, adr, datum)) {
1022 /* reset on all failures. */
1023 map_write( map, CMD(0xF0), chip->start );
1024 /* FIXME - should have reset delay before continuing */
778 1025
779 printk(KERN_WARNING "MTD %s(): software timeout\n", __func__); 1026 if (++retry_cnt <= MAX_WORD_RETRIES)
780 1027 goto retry;
781 /* reset on all failures. */
782 map_write( map, CMD(0xF0), chip->start );
783 /* FIXME - should have reset delay before continuing */
784 if (++retry_cnt <= MAX_WORD_RETRIES)
785 goto retry;
786 1028
787 ret = -EIO; 1029 ret = -EIO;
1030 }
1031 xip_enable(map, chip, adr);
788 op_done: 1032 op_done:
789 chip->state = FL_READY; 1033 chip->state = FL_READY;
790 put_chip(map, chip, adr); 1034 put_chip(map, chip, adr);
791 cfi_spin_unlock(chip->mutex); 1035 spin_unlock(chip->mutex);
792 1036
793 return ret; 1037 return ret;
794} 1038}
@@ -820,7 +1064,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
820 map_word tmp_buf; 1064 map_word tmp_buf;
821 1065
822 retry: 1066 retry:
823 cfi_spin_lock(cfi->chips[chipnum].mutex); 1067 spin_lock(cfi->chips[chipnum].mutex);
824 1068
825 if (cfi->chips[chipnum].state != FL_READY) { 1069 if (cfi->chips[chipnum].state != FL_READY) {
826#if 0 1070#if 0
@@ -829,7 +1073,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
829 set_current_state(TASK_UNINTERRUPTIBLE); 1073 set_current_state(TASK_UNINTERRUPTIBLE);
830 add_wait_queue(&cfi->chips[chipnum].wq, &wait); 1074 add_wait_queue(&cfi->chips[chipnum].wq, &wait);
831 1075
832 cfi_spin_unlock(cfi->chips[chipnum].mutex); 1076 spin_unlock(cfi->chips[chipnum].mutex);
833 1077
834 schedule(); 1078 schedule();
835 remove_wait_queue(&cfi->chips[chipnum].wq, &wait); 1079 remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
@@ -843,7 +1087,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
843 /* Load 'tmp_buf' with old contents of flash */ 1087 /* Load 'tmp_buf' with old contents of flash */
844 tmp_buf = map_read(map, bus_ofs+chipstart); 1088 tmp_buf = map_read(map, bus_ofs+chipstart);
845 1089
846 cfi_spin_unlock(cfi->chips[chipnum].mutex); 1090 spin_unlock(cfi->chips[chipnum].mutex);
847 1091
848 /* Number of bytes to copy from buffer */ 1092 /* Number of bytes to copy from buffer */
849 n = min_t(int, len, map_bankwidth(map)-i); 1093 n = min_t(int, len, map_bankwidth(map)-i);
@@ -898,7 +1142,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
898 map_word tmp_buf; 1142 map_word tmp_buf;
899 1143
900 retry1: 1144 retry1:
901 cfi_spin_lock(cfi->chips[chipnum].mutex); 1145 spin_lock(cfi->chips[chipnum].mutex);
902 1146
903 if (cfi->chips[chipnum].state != FL_READY) { 1147 if (cfi->chips[chipnum].state != FL_READY) {
904#if 0 1148#if 0
@@ -907,7 +1151,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
907 set_current_state(TASK_UNINTERRUPTIBLE); 1151 set_current_state(TASK_UNINTERRUPTIBLE);
908 add_wait_queue(&cfi->chips[chipnum].wq, &wait); 1152 add_wait_queue(&cfi->chips[chipnum].wq, &wait);
909 1153
910 cfi_spin_unlock(cfi->chips[chipnum].mutex); 1154 spin_unlock(cfi->chips[chipnum].mutex);
911 1155
912 schedule(); 1156 schedule();
913 remove_wait_queue(&cfi->chips[chipnum].wq, &wait); 1157 remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
@@ -920,7 +1164,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
920 1164
921 tmp_buf = map_read(map, ofs + chipstart); 1165 tmp_buf = map_read(map, ofs + chipstart);
922 1166
923 cfi_spin_unlock(cfi->chips[chipnum].mutex); 1167 spin_unlock(cfi->chips[chipnum].mutex);
924 1168
925 tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len); 1169 tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len);
926 1170
@@ -939,8 +1183,9 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
939/* 1183/*
940 * FIXME: interleaved mode not tested, and probably not supported! 1184 * FIXME: interleaved mode not tested, and probably not supported!
941 */ 1185 */
942static inline int do_write_buffer(struct map_info *map, struct flchip *chip, 1186static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
943 unsigned long adr, const u_char *buf, int len) 1187 unsigned long adr, const u_char *buf,
1188 int len)
944{ 1189{
945 struct cfi_private *cfi = map->fldrv_priv; 1190 struct cfi_private *cfi = map->fldrv_priv;
946 unsigned long timeo = jiffies + HZ; 1191 unsigned long timeo = jiffies + HZ;
@@ -954,10 +1199,10 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
954 adr += chip->start; 1199 adr += chip->start;
955 cmd_adr = adr; 1200 cmd_adr = adr;
956 1201
957 cfi_spin_lock(chip->mutex); 1202 spin_lock(chip->mutex);
958 ret = get_chip(map, chip, adr, FL_WRITING); 1203 ret = get_chip(map, chip, adr, FL_WRITING);
959 if (ret) { 1204 if (ret) {
960 cfi_spin_unlock(chip->mutex); 1205 spin_unlock(chip->mutex);
961 return ret; 1206 return ret;
962 } 1207 }
963 1208
@@ -966,7 +1211,10 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
966 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n", 1211 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
967 __func__, adr, datum.x[0] ); 1212 __func__, adr, datum.x[0] );
968 1213
1214 XIP_INVAL_CACHED_RANGE(map, adr, len);
969 ENABLE_VPP(map); 1215 ENABLE_VPP(map);
1216 xip_disable(map, chip, cmd_adr);
1217
970 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 1218 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
971 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); 1219 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
972 //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 1220 //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
@@ -996,9 +1244,9 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
996 map_write(map, CMD(0x29), cmd_adr); 1244 map_write(map, CMD(0x29), cmd_adr);
997 chip->state = FL_WRITING; 1245 chip->state = FL_WRITING;
998 1246
999 cfi_spin_unlock(chip->mutex); 1247 INVALIDATE_CACHE_UDELAY(map, chip,
1000 cfi_udelay(chip->buffer_write_time); 1248 adr, map_bankwidth(map),
1001 cfi_spin_lock(chip->mutex); 1249 chip->word_write_time);
1002 1250
1003 timeo = jiffies + uWriteTimeout; 1251 timeo = jiffies + uWriteTimeout;
1004 1252
@@ -1009,38 +1257,39 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
1009 1257
1010 set_current_state(TASK_UNINTERRUPTIBLE); 1258 set_current_state(TASK_UNINTERRUPTIBLE);
1011 add_wait_queue(&chip->wq, &wait); 1259 add_wait_queue(&chip->wq, &wait);
1012 cfi_spin_unlock(chip->mutex); 1260 spin_unlock(chip->mutex);
1013 schedule(); 1261 schedule();
1014 remove_wait_queue(&chip->wq, &wait); 1262 remove_wait_queue(&chip->wq, &wait);
1015 timeo = jiffies + (HZ / 2); /* FIXME */ 1263 timeo = jiffies + (HZ / 2); /* FIXME */
1016 cfi_spin_lock(chip->mutex); 1264 spin_lock(chip->mutex);
1017 continue; 1265 continue;
1018 } 1266 }
1019 1267
1020 if (chip_ready(map, adr)) 1268 if (chip_ready(map, adr)) {
1269 xip_enable(map, chip, adr);
1021 goto op_done; 1270 goto op_done;
1271 }
1022 1272
1023 if( time_after(jiffies, timeo)) 1273 if( time_after(jiffies, timeo))
1024 break; 1274 break;
1025 1275
1026 /* Latency issues. Drop the lock, wait a while and retry */ 1276 /* Latency issues. Drop the lock, wait a while and retry */
1027 cfi_spin_unlock(chip->mutex); 1277 UDELAY(map, chip, adr, 1);
1028 cfi_udelay(1);
1029 cfi_spin_lock(chip->mutex);
1030 } 1278 }
1031 1279
1032 printk(KERN_WARNING "MTD %s(): software timeout\n",
1033 __func__ );
1034
1035 /* reset on all failures. */ 1280 /* reset on all failures. */
1036 map_write( map, CMD(0xF0), chip->start ); 1281 map_write( map, CMD(0xF0), chip->start );
1282 xip_enable(map, chip, adr);
1037 /* FIXME - should have reset delay before continuing */ 1283 /* FIXME - should have reset delay before continuing */
1038 1284
1285 printk(KERN_WARNING "MTD %s(): software timeout\n",
1286 __func__ );
1287
1039 ret = -EIO; 1288 ret = -EIO;
1040 op_done: 1289 op_done:
1041 chip->state = FL_READY; 1290 chip->state = FL_READY;
1042 put_chip(map, chip, adr); 1291 put_chip(map, chip, adr);
1043 cfi_spin_unlock(chip->mutex); 1292 spin_unlock(chip->mutex);
1044 1293
1045 return ret; 1294 return ret;
1046} 1295}
@@ -1130,7 +1379,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
1130 * Handle devices with one erase region, that only implement 1379 * Handle devices with one erase region, that only implement
1131 * the chip erase command. 1380 * the chip erase command.
1132 */ 1381 */
1133static inline int do_erase_chip(struct map_info *map, struct flchip *chip) 1382static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
1134{ 1383{
1135 struct cfi_private *cfi = map->fldrv_priv; 1384 struct cfi_private *cfi = map->fldrv_priv;
1136 unsigned long timeo = jiffies + HZ; 1385 unsigned long timeo = jiffies + HZ;
@@ -1140,17 +1389,20 @@ static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
1140 1389
1141 adr = cfi->addr_unlock1; 1390 adr = cfi->addr_unlock1;
1142 1391
1143 cfi_spin_lock(chip->mutex); 1392 spin_lock(chip->mutex);
1144 ret = get_chip(map, chip, adr, FL_WRITING); 1393 ret = get_chip(map, chip, adr, FL_WRITING);
1145 if (ret) { 1394 if (ret) {
1146 cfi_spin_unlock(chip->mutex); 1395 spin_unlock(chip->mutex);
1147 return ret; 1396 return ret;
1148 } 1397 }
1149 1398
1150 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n", 1399 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
1151 __func__, chip->start ); 1400 __func__, chip->start );
1152 1401
1402 XIP_INVAL_CACHED_RANGE(map, adr, map->size);
1153 ENABLE_VPP(map); 1403 ENABLE_VPP(map);
1404 xip_disable(map, chip, adr);
1405
1154 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 1406 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
1155 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); 1407 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
1156 cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 1408 cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
@@ -1162,9 +1414,9 @@ static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
1162 chip->erase_suspended = 0; 1414 chip->erase_suspended = 0;
1163 chip->in_progress_block_addr = adr; 1415 chip->in_progress_block_addr = adr;
1164 1416
1165 cfi_spin_unlock(chip->mutex); 1417 INVALIDATE_CACHE_UDELAY(map, chip,
1166 msleep(chip->erase_time/2); 1418 adr, map->size,
1167 cfi_spin_lock(chip->mutex); 1419 chip->erase_time*500);
1168 1420
1169 timeo = jiffies + (HZ*20); 1421 timeo = jiffies + (HZ*20);
1170 1422
@@ -1173,10 +1425,10 @@ static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
1173 /* Someone's suspended the erase. Sleep */ 1425 /* Someone's suspended the erase. Sleep */
1174 set_current_state(TASK_UNINTERRUPTIBLE); 1426 set_current_state(TASK_UNINTERRUPTIBLE);
1175 add_wait_queue(&chip->wq, &wait); 1427 add_wait_queue(&chip->wq, &wait);
1176 cfi_spin_unlock(chip->mutex); 1428 spin_unlock(chip->mutex);
1177 schedule(); 1429 schedule();
1178 remove_wait_queue(&chip->wq, &wait); 1430 remove_wait_queue(&chip->wq, &wait);
1179 cfi_spin_lock(chip->mutex); 1431 spin_lock(chip->mutex);
1180 continue; 1432 continue;
1181 } 1433 }
1182 if (chip->erase_suspended) { 1434 if (chip->erase_suspended) {
@@ -1187,36 +1439,36 @@ static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
1187 } 1439 }
1188 1440
1189 if (chip_ready(map, adr)) 1441 if (chip_ready(map, adr))
1190 goto op_done; 1442 break;
1191 1443
1192 if (time_after(jiffies, timeo)) 1444 if (time_after(jiffies, timeo)) {
1445 printk(KERN_WARNING "MTD %s(): software timeout\n",
1446 __func__ );
1193 break; 1447 break;
1448 }
1194 1449
1195 /* Latency issues. Drop the lock, wait a while and retry */ 1450 /* Latency issues. Drop the lock, wait a while and retry */
1196 cfi_spin_unlock(chip->mutex); 1451 UDELAY(map, chip, adr, 1000000/HZ);
1197 set_current_state(TASK_UNINTERRUPTIBLE);
1198 schedule_timeout(1);
1199 cfi_spin_lock(chip->mutex);
1200 } 1452 }
1453 /* Did we succeed? */
1454 if (!chip_good(map, adr, map_word_ff(map))) {
1455 /* reset on all failures. */
1456 map_write( map, CMD(0xF0), chip->start );
1457 /* FIXME - should have reset delay before continuing */
1201 1458
1202 printk(KERN_WARNING "MTD %s(): software timeout\n", 1459 ret = -EIO;
1203 __func__ ); 1460 }
1204
1205 /* reset on all failures. */
1206 map_write( map, CMD(0xF0), chip->start );
1207 /* FIXME - should have reset delay before continuing */
1208 1461
1209 ret = -EIO;
1210 op_done:
1211 chip->state = FL_READY; 1462 chip->state = FL_READY;
1463 xip_enable(map, chip, adr);
1212 put_chip(map, chip, adr); 1464 put_chip(map, chip, adr);
1213 cfi_spin_unlock(chip->mutex); 1465 spin_unlock(chip->mutex);
1214 1466
1215 return ret; 1467 return ret;
1216} 1468}
1217 1469
1218 1470
1219static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, int len, void *thunk) 1471static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, int len, void *thunk)
1220{ 1472{
1221 struct cfi_private *cfi = map->fldrv_priv; 1473 struct cfi_private *cfi = map->fldrv_priv;
1222 unsigned long timeo = jiffies + HZ; 1474 unsigned long timeo = jiffies + HZ;
@@ -1225,17 +1477,20 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
1225 1477
1226 adr += chip->start; 1478 adr += chip->start;
1227 1479
1228 cfi_spin_lock(chip->mutex); 1480 spin_lock(chip->mutex);
1229 ret = get_chip(map, chip, adr, FL_ERASING); 1481 ret = get_chip(map, chip, adr, FL_ERASING);
1230 if (ret) { 1482 if (ret) {
1231 cfi_spin_unlock(chip->mutex); 1483 spin_unlock(chip->mutex);
1232 return ret; 1484 return ret;
1233 } 1485 }
1234 1486
1235 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n", 1487 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
1236 __func__, adr ); 1488 __func__, adr );
1237 1489
1490 XIP_INVAL_CACHED_RANGE(map, adr, len);
1238 ENABLE_VPP(map); 1491 ENABLE_VPP(map);
1492 xip_disable(map, chip, adr);
1493
1239 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 1494 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
1240 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); 1495 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
1241 cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 1496 cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
@@ -1246,10 +1501,10 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
1246 chip->state = FL_ERASING; 1501 chip->state = FL_ERASING;
1247 chip->erase_suspended = 0; 1502 chip->erase_suspended = 0;
1248 chip->in_progress_block_addr = adr; 1503 chip->in_progress_block_addr = adr;
1249 1504
1250 cfi_spin_unlock(chip->mutex); 1505 INVALIDATE_CACHE_UDELAY(map, chip,
1251 msleep(chip->erase_time/2); 1506 adr, len,
1252 cfi_spin_lock(chip->mutex); 1507 chip->erase_time*500);
1253 1508
1254 timeo = jiffies + (HZ*20); 1509 timeo = jiffies + (HZ*20);
1255 1510
@@ -1258,10 +1513,10 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
1258 /* Someone's suspended the erase. Sleep */ 1513 /* Someone's suspended the erase. Sleep */
1259 set_current_state(TASK_UNINTERRUPTIBLE); 1514 set_current_state(TASK_UNINTERRUPTIBLE);
1260 add_wait_queue(&chip->wq, &wait); 1515 add_wait_queue(&chip->wq, &wait);
1261 cfi_spin_unlock(chip->mutex); 1516 spin_unlock(chip->mutex);
1262 schedule(); 1517 schedule();
1263 remove_wait_queue(&chip->wq, &wait); 1518 remove_wait_queue(&chip->wq, &wait);
1264 cfi_spin_lock(chip->mutex); 1519 spin_lock(chip->mutex);
1265 continue; 1520 continue;
1266 } 1521 }
1267 if (chip->erase_suspended) { 1522 if (chip->erase_suspended) {
@@ -1271,31 +1526,33 @@ static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, u
1271 chip->erase_suspended = 0; 1526 chip->erase_suspended = 0;
1272 } 1527 }
1273 1528
1274 if (chip_ready(map, adr)) 1529 if (chip_ready(map, adr)) {
1275 goto op_done; 1530 xip_enable(map, chip, adr);
1531 break;
1532 }
1276 1533
1277 if (time_after(jiffies, timeo)) 1534 if (time_after(jiffies, timeo)) {
1535 xip_enable(map, chip, adr);
1536 printk(KERN_WARNING "MTD %s(): software timeout\n",
1537 __func__ );
1278 break; 1538 break;
1539 }
1279 1540
1280 /* Latency issues. Drop the lock, wait a while and retry */ 1541 /* Latency issues. Drop the lock, wait a while and retry */
1281 cfi_spin_unlock(chip->mutex); 1542 UDELAY(map, chip, adr, 1000000/HZ);
1282 set_current_state(TASK_UNINTERRUPTIBLE); 1543 }
1283 schedule_timeout(1); 1544 /* Did we succeed? */
1284 cfi_spin_lock(chip->mutex); 1545 if (!chip_good(map, adr, map_word_ff(map))) {
1546 /* reset on all failures. */
1547 map_write( map, CMD(0xF0), chip->start );
1548 /* FIXME - should have reset delay before continuing */
1549
1550 ret = -EIO;
1285 } 1551 }
1286
1287 printk(KERN_WARNING "MTD %s(): software timeout\n",
1288 __func__ );
1289
1290 /* reset on all failures. */
1291 map_write( map, CMD(0xF0), chip->start );
1292 /* FIXME - should have reset delay before continuing */
1293 1552
1294 ret = -EIO;
1295 op_done:
1296 chip->state = FL_READY; 1553 chip->state = FL_READY;
1297 put_chip(map, chip, adr); 1554 put_chip(map, chip, adr);
1298 cfi_spin_unlock(chip->mutex); 1555 spin_unlock(chip->mutex);
1299 return ret; 1556 return ret;
1300} 1557}
1301 1558
@@ -1355,7 +1612,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
1355 chip = &cfi->chips[i]; 1612 chip = &cfi->chips[i];
1356 1613
1357 retry: 1614 retry:
1358 cfi_spin_lock(chip->mutex); 1615 spin_lock(chip->mutex);
1359 1616
1360 switch(chip->state) { 1617 switch(chip->state) {
1361 case FL_READY: 1618 case FL_READY:
@@ -1369,14 +1626,14 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
1369 * with the chip now anyway. 1626 * with the chip now anyway.
1370 */ 1627 */
1371 case FL_SYNCING: 1628 case FL_SYNCING:
1372 cfi_spin_unlock(chip->mutex); 1629 spin_unlock(chip->mutex);
1373 break; 1630 break;
1374 1631
1375 default: 1632 default:
1376 /* Not an idle state */ 1633 /* Not an idle state */
1377 add_wait_queue(&chip->wq, &wait); 1634 add_wait_queue(&chip->wq, &wait);
1378 1635
1379 cfi_spin_unlock(chip->mutex); 1636 spin_unlock(chip->mutex);
1380 1637
1381 schedule(); 1638 schedule();
1382 1639
@@ -1391,13 +1648,13 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
1391 for (i--; i >=0; i--) { 1648 for (i--; i >=0; i--) {
1392 chip = &cfi->chips[i]; 1649 chip = &cfi->chips[i];
1393 1650
1394 cfi_spin_lock(chip->mutex); 1651 spin_lock(chip->mutex);
1395 1652
1396 if (chip->state == FL_SYNCING) { 1653 if (chip->state == FL_SYNCING) {
1397 chip->state = chip->oldstate; 1654 chip->state = chip->oldstate;
1398 wake_up(&chip->wq); 1655 wake_up(&chip->wq);
1399 } 1656 }
1400 cfi_spin_unlock(chip->mutex); 1657 spin_unlock(chip->mutex);
1401 } 1658 }
1402} 1659}
1403 1660
@@ -1413,7 +1670,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
1413 for (i=0; !ret && i<cfi->numchips; i++) { 1670 for (i=0; !ret && i<cfi->numchips; i++) {
1414 chip = &cfi->chips[i]; 1671 chip = &cfi->chips[i];
1415 1672
1416 cfi_spin_lock(chip->mutex); 1673 spin_lock(chip->mutex);
1417 1674
1418 switch(chip->state) { 1675 switch(chip->state) {
1419 case FL_READY: 1676 case FL_READY:
@@ -1433,7 +1690,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
1433 ret = -EAGAIN; 1690 ret = -EAGAIN;
1434 break; 1691 break;
1435 } 1692 }
1436 cfi_spin_unlock(chip->mutex); 1693 spin_unlock(chip->mutex);
1437 } 1694 }
1438 1695
1439 /* Unlock the chips again */ 1696 /* Unlock the chips again */
@@ -1442,13 +1699,13 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
1442 for (i--; i >=0; i--) { 1699 for (i--; i >=0; i--) {
1443 chip = &cfi->chips[i]; 1700 chip = &cfi->chips[i];
1444 1701
1445 cfi_spin_lock(chip->mutex); 1702 spin_lock(chip->mutex);
1446 1703
1447 if (chip->state == FL_PM_SUSPENDED) { 1704 if (chip->state == FL_PM_SUSPENDED) {
1448 chip->state = chip->oldstate; 1705 chip->state = chip->oldstate;
1449 wake_up(&chip->wq); 1706 wake_up(&chip->wq);
1450 } 1707 }
1451 cfi_spin_unlock(chip->mutex); 1708 spin_unlock(chip->mutex);
1452 } 1709 }
1453 } 1710 }
1454 1711
@@ -1467,7 +1724,7 @@ static void cfi_amdstd_resume(struct mtd_info *mtd)
1467 1724
1468 chip = &cfi->chips[i]; 1725 chip = &cfi->chips[i];
1469 1726
1470 cfi_spin_lock(chip->mutex); 1727 spin_lock(chip->mutex);
1471 1728
1472 if (chip->state == FL_PM_SUSPENDED) { 1729 if (chip->state == FL_PM_SUSPENDED) {
1473 chip->state = FL_READY; 1730 chip->state = FL_READY;
@@ -1477,7 +1734,7 @@ static void cfi_amdstd_resume(struct mtd_info *mtd)
1477 else 1734 else
1478 printk(KERN_ERR "Argh. Chip not in PM_SUSPENDED state upon resume()\n"); 1735 printk(KERN_ERR "Argh. Chip not in PM_SUSPENDED state upon resume()\n");
1479 1736
1480 cfi_spin_unlock(chip->mutex); 1737 spin_unlock(chip->mutex);
1481 } 1738 }
1482} 1739}
1483 1740
diff --git a/drivers/mtd/chips/fwh_lock.h b/drivers/mtd/chips/fwh_lock.h
index fbf44708a861..e1a5b76596c5 100644
--- a/drivers/mtd/chips/fwh_lock.h
+++ b/drivers/mtd/chips/fwh_lock.h
@@ -58,10 +58,10 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
58 * to flash memory - that means that we don't have to check status 58 * to flash memory - that means that we don't have to check status
59 * and timeout. 59 * and timeout.
60 */ 60 */
61 cfi_spin_lock(chip->mutex); 61 spin_lock(chip->mutex);
62 ret = get_chip(map, chip, adr, FL_LOCKING); 62 ret = get_chip(map, chip, adr, FL_LOCKING);
63 if (ret) { 63 if (ret) {
64 cfi_spin_unlock(chip->mutex); 64 spin_unlock(chip->mutex);
65 return ret; 65 return ret;
66 } 66 }
67 67
@@ -71,7 +71,7 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
71 /* Done and happy. */ 71 /* Done and happy. */
72 chip->state = FL_READY; 72 chip->state = FL_READY;
73 put_chip(map, chip, adr); 73 put_chip(map, chip, adr);
74 cfi_spin_unlock(chip->mutex); 74 spin_unlock(chip->mutex);
75 return 0; 75 return 0;
76} 76}
77 77
diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c
index fc982c4671f0..dc065b22f79e 100644
--- a/drivers/mtd/chips/gen_probe.c
+++ b/drivers/mtd/chips/gen_probe.c
@@ -2,7 +2,7 @@
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.21 2004/08/14 15:14:05 dwmw2 Exp $ 5 * $Id: gen_probe.c,v 1.22 2005/01/24 23:49:50 rmk Exp $
6 */ 6 */
7 7
8#include <linux/kernel.h> 8#include <linux/kernel.h>
@@ -162,7 +162,7 @@ static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp,
162 int max_chips = map_bankwidth(map); /* And minimum 1 */ 162 int max_chips = map_bankwidth(map); /* And minimum 1 */
163 int nr_chips, type; 163 int nr_chips, type;
164 164
165 for (nr_chips = min_chips; nr_chips <= max_chips; nr_chips <<= 1) { 165 for (nr_chips = max_chips; nr_chips >= min_chips; nr_chips >>= 1) {
166 166
167 if (!cfi_interleave_supported(nr_chips)) 167 if (!cfi_interleave_supported(nr_chips))
168 continue; 168 continue;
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index 30325a25ab95..30da428eb7b9 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -1,7 +1,7 @@
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.61 2004/11/19 20:52:16 thayne Exp $ 4 $Id: jedec_probe.c,v 1.63 2005/02/14 16:30:32 bjd Exp $
5 See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5) 5 See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
6 for the standard this probe goes back to. 6 for the standard this probe goes back to.
7 7
@@ -142,6 +142,7 @@
142#define SST29LE512 0x003d 142#define SST29LE512 0x003d
143#define SST39LF800 0x2781 143#define SST39LF800 0x2781
144#define SST39LF160 0x2782 144#define SST39LF160 0x2782
145#define SST39VF1601 0x234b
145#define SST39LF512 0x00D4 146#define SST39LF512 0x00D4
146#define SST39LF010 0x00D5 147#define SST39LF010 0x00D5
147#define SST39LF020 0x00D6 148#define SST39LF020 0x00D6
@@ -1448,6 +1449,21 @@ static const struct amd_flash_info jedec_table[] = {
1448 ERASEINFO(0x1000,256), 1449 ERASEINFO(0x1000,256),
1449 ERASEINFO(0x1000,256) 1450 ERASEINFO(0x1000,256)
1450 } 1451 }
1452 }, {
1453 .mfr_id = MANUFACTURER_SST, /* should be CFI */
1454 .dev_id = SST39VF1601,
1455 .name = "SST 39VF1601",
1456 .uaddr = {
1457 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
1458 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
1459 },
1460 .DevSize = SIZE_2MiB,
1461 .CmdSet = P_ID_AMD_STD,
1462 .NumEraseRegions= 2,
1463 .regions = {
1464 ERASEINFO(0x1000,256),
1465 ERASEINFO(0x1000,256)
1466 }
1451 1467
1452 }, { 1468 }, {
1453 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ 1469 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
@@ -1856,6 +1872,16 @@ static inline int jedec_match( __u32 base,
1856 case CFI_DEVICETYPE_X8: 1872 case CFI_DEVICETYPE_X8:
1857 mfr = (__u8)finfo->mfr_id; 1873 mfr = (__u8)finfo->mfr_id;
1858 id = (__u8)finfo->dev_id; 1874 id = (__u8)finfo->dev_id;
1875
1876 /* bjd: it seems that if we do this, we can end up
1877 * detecting 16bit flashes as an 8bit device, even though
1878 * there aren't.
1879 */
1880 if (finfo->dev_id > 0xff) {
1881 DEBUG( MTD_DEBUG_LEVEL3, "%s(): ID is not 8bit\n",
1882 __func__);
1883 goto match_done;
1884 }
1859 break; 1885 break;
1860 case CFI_DEVICETYPE_X16: 1886 case CFI_DEVICETYPE_X16:
1861 mfr = (__u16)finfo->mfr_id; 1887 mfr = (__u16)finfo->mfr_id;
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index 60ab4b89a2f9..ef24837019d3 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: cmdlinepart.c,v 1.17 2004/11/26 11:18:47 lavinen Exp $ 2 * $Id: cmdlinepart.c,v 1.18 2005/06/07 15:04:26 joern Exp $
3 * 3 *
4 * Read flash partition table from command line 4 * Read flash partition table from command line
5 * 5 *
@@ -239,7 +239,8 @@ static int mtdpart_setup_real(char *s)
239 &num_parts, /* out: number of parts */ 239 &num_parts, /* out: number of parts */
240 0, /* first partition */ 240 0, /* first partition */
241 (unsigned char**)&this_mtd, /* out: extra mem */ 241 (unsigned char**)&this_mtd, /* out: extra mem */
242 mtd_id_len + 1 + sizeof(*this_mtd)); 242 mtd_id_len + 1 + sizeof(*this_mtd) +
243 sizeof(void*)-1 /*alignment*/);
243 if(!parts) 244 if(!parts)
244 { 245 {
245 /* 246 /*
@@ -252,6 +253,9 @@ static int mtdpart_setup_real(char *s)
252 return 0; 253 return 0;
253 } 254 }
254 255
256 /* align this_mtd */
257 this_mtd = (struct cmdline_mtd_partition *)
258 ALIGN((unsigned long)this_mtd, sizeof(void*));
255 /* enter results */ 259 /* enter results */
256 this_mtd->parts = parts; 260 this_mtd->parts = parts;
257 this_mtd->num_parts = num_parts; 261 this_mtd->num_parts = num_parts;
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index cfe6ccf07972..4a7a805e7564 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -1,10 +1,9 @@
1/* 1/*
2 * $Id: block2mtd.c,v 1.23 2005/01/05 17:05:46 dwmw2 Exp $ 2 * $Id: block2mtd.c,v 1.28 2005/03/19 22:40:44 gleixner Exp $
3 * 3 *
4 * block2mtd.c - create an mtd from a block device 4 * block2mtd.c - create an mtd from a block device
5 * 5 *
6 * Copyright (C) 2001,2002 Simon Evans <spse@secret.org.uk> 6 * Copyright (C) 2001,2002 Simon Evans <spse@secret.org.uk>
7 * Copyright (C) 2004 Gareth Bult <Gareth@Encryptec.net>
8 * Copyright (C) 2004,2005 Jörn Engel <joern@wh.fh-wedel.de> 7 * Copyright (C) 2004,2005 Jörn Engel <joern@wh.fh-wedel.de>
9 * 8 *
10 * Licence: GPL 9 * Licence: GPL
@@ -20,7 +19,7 @@
20#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
21#include <linux/buffer_head.h> 20#include <linux/buffer_head.h>
22 21
23#define VERSION "$Revision: 1.23 $" 22#define VERSION "$Revision: 1.28 $"
24 23
25 24
26#define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args) 25#define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
@@ -89,7 +88,6 @@ void cache_readahead(struct address_space *mapping, int index)
89static struct page* page_readahead(struct address_space *mapping, int index) 88static struct page* page_readahead(struct address_space *mapping, int index)
90{ 89{
91 filler_t *filler = (filler_t*)mapping->a_ops->readpage; 90 filler_t *filler = (filler_t*)mapping->a_ops->readpage;
92 //do_page_cache_readahead(mapping, index, XXX, 64);
93 cache_readahead(mapping, index); 91 cache_readahead(mapping, index);
94 return read_cache_page(mapping, index, filler, NULL); 92 return read_cache_page(mapping, index, filler, NULL);
95} 93}
@@ -157,7 +155,7 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
157 struct block2mtd_dev *dev = mtd->priv; 155 struct block2mtd_dev *dev = mtd->priv;
158 struct page *page; 156 struct page *page;
159 int index = from >> PAGE_SHIFT; 157 int index = from >> PAGE_SHIFT;
160 int offset = from & (PAGE_SHIFT-1); 158 int offset = from & (PAGE_SIZE-1);
161 int cpylen; 159 int cpylen;
162 160
163 if (from > mtd->size) 161 if (from > mtd->size)
@@ -370,16 +368,16 @@ static int ustrtoul(const char *cp, char **endp, unsigned int base)
370} 368}
371 369
372 370
373static int parse_num32(u32 *num32, const char *token) 371static int parse_num(size_t *num, const char *token)
374{ 372{
375 char *endp; 373 char *endp;
376 unsigned long n; 374 size_t n;
377 375
378 n = ustrtoul(token, &endp, 0); 376 n = (size_t) ustrtoul(token, &endp, 0);
379 if (*endp) 377 if (*endp)
380 return -EINVAL; 378 return -EINVAL;
381 379
382 *num32 = n; 380 *num = n;
383 return 0; 381 return 0;
384} 382}
385 383
@@ -422,7 +420,7 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp)
422 char buf[80+12], *str=buf; /* 80 for device, 12 for erase size */ 420 char buf[80+12], *str=buf; /* 80 for device, 12 for erase size */
423 char *token[2]; 421 char *token[2];
424 char *name; 422 char *name;
425 u32 erase_size = PAGE_SIZE; 423 size_t erase_size = PAGE_SIZE;
426 int i, ret; 424 int i, ret;
427 425
428 if (strnlen(val, sizeof(buf)) >= sizeof(buf)) 426 if (strnlen(val, sizeof(buf)) >= sizeof(buf))
@@ -449,7 +447,7 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp)
449 return 0; 447 return 0;
450 448
451 if (token[1]) { 449 if (token[1]) {
452 ret = parse_num32(&erase_size, token[1]); 450 ret = parse_num(&erase_size, token[1]);
453 if (ret) 451 if (ret)
454 parse_err("illegal erase size"); 452 parse_err("illegal erase size");
455 } 453 }
diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c
index 380ff08d29e4..f5026cee087f 100644
--- a/drivers/mtd/devices/ms02-nv.c
+++ b/drivers/mtd/devices/ms02-nv.c
@@ -6,7 +6,7 @@
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 * 8 *
9 * $Id: ms02-nv.c,v 1.8 2005/01/05 18:05:12 dwmw2 Exp $ 9 * $Id: ms02-nv.c,v 1.10 2005/06/20 12:24:41 macro Exp $
10 */ 10 */
11 11
12#include <linux/init.h> 12#include <linux/init.h>
@@ -99,8 +99,8 @@ static inline uint ms02nv_probe_one(ulong addr)
99 * The firmware writes MS02NV_ID at MS02NV_MAGIC and also 99 * The firmware writes MS02NV_ID at MS02NV_MAGIC and also
100 * a diagnostic status at MS02NV_DIAG. 100 * a diagnostic status at MS02NV_DIAG.
101 */ 101 */
102 ms02nv_diagp = (ms02nv_uint *)(KSEG1ADDR(addr + MS02NV_DIAG)); 102 ms02nv_diagp = (ms02nv_uint *)(CKSEG1ADDR(addr + MS02NV_DIAG));
103 ms02nv_magicp = (ms02nv_uint *)(KSEG1ADDR(addr + MS02NV_MAGIC)); 103 ms02nv_magicp = (ms02nv_uint *)(CKSEG1ADDR(addr + MS02NV_MAGIC));
104 err = get_dbe(ms02nv_magic, ms02nv_magicp); 104 err = get_dbe(ms02nv_magic, ms02nv_magicp);
105 if (err) 105 if (err)
106 return 0; 106 return 0;
@@ -233,7 +233,7 @@ static int __init ms02nv_init_one(ulong addr)
233 goto err_out_csr_res; 233 goto err_out_csr_res;
234 } 234 }
235 235
236 printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %uMiB.\n", 236 printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %zuMiB.\n",
237 mtd->index, ms02nv_name, addr, size >> 20); 237 mtd->index, ms02nv_name, addr, size >> 20);
238 238
239 mp->next = root_ms02nv_mtd; 239 mp->next = root_ms02nv_mtd;
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c
index edac4156d69c..bb713fed2f37 100644
--- a/drivers/mtd/devices/mtdram.c
+++ b/drivers/mtd/devices/mtdram.c
@@ -1,9 +1,10 @@
1/* 1/*
2 * mtdram - a test mtd device 2 * mtdram - a test mtd device
3 * $Id: mtdram.c,v 1.35 2005/01/05 18:05:12 dwmw2 Exp $ 3 * $Id: mtdram.c,v 1.37 2005/04/21 03:42:11 joern Exp $
4 * Author: Alexander Larsson <alex@cendio.se> 4 * Author: Alexander Larsson <alex@cendio.se>
5 * 5 *
6 * Copyright (c) 1999 Alexander Larsson <alex@cendio.se> 6 * Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
7 * Copyright (c) 2005 Joern Engel <joern@wh.fh-wedel.de>
7 * 8 *
8 * This code is GPL 9 * This code is GPL
9 * 10 *
@@ -18,213 +19,140 @@
18#include <linux/mtd/compatmac.h> 19#include <linux/mtd/compatmac.h>
19#include <linux/mtd/mtd.h> 20#include <linux/mtd/mtd.h>
20 21
21#ifndef CONFIG_MTDRAM_ABS_POS
22 #define CONFIG_MTDRAM_ABS_POS 0
23#endif
24
25#if CONFIG_MTDRAM_ABS_POS > 0
26 #include <asm/io.h>
27#endif
28
29#ifdef MODULE
30static unsigned long total_size = CONFIG_MTDRAM_TOTAL_SIZE; 22static unsigned long total_size = CONFIG_MTDRAM_TOTAL_SIZE;
31static unsigned long erase_size = CONFIG_MTDRAM_ERASE_SIZE; 23static unsigned long erase_size = CONFIG_MTDRAM_ERASE_SIZE;
32module_param(total_size,ulong,0);
33MODULE_PARM_DESC(total_size, "Total device size in KiB");
34module_param(erase_size,ulong,0);
35MODULE_PARM_DESC(erase_size, "Device erase block size in KiB");
36#define MTDRAM_TOTAL_SIZE (total_size * 1024) 24#define MTDRAM_TOTAL_SIZE (total_size * 1024)
37#define MTDRAM_ERASE_SIZE (erase_size * 1024) 25#define MTDRAM_ERASE_SIZE (erase_size * 1024)
38#else
39#define MTDRAM_TOTAL_SIZE (CONFIG_MTDRAM_TOTAL_SIZE * 1024)
40#define MTDRAM_ERASE_SIZE (CONFIG_MTDRAM_ERASE_SIZE * 1024)
41#endif
42 26
27#ifdef MODULE
28module_param(total_size, ulong, 0);
29MODULE_PARM_DESC(total_size, "Total device size in KiB");
30module_param(erase_size, ulong, 0);
31MODULE_PARM_DESC(erase_size, "Device erase block size in KiB");
32#endif
43 33
44// We could store these in the mtd structure, but we only support 1 device.. 34// We could store these in the mtd structure, but we only support 1 device..
45static struct mtd_info *mtd_info; 35static struct mtd_info *mtd_info;
46 36
47 37static int ram_erase(struct mtd_info *mtd, struct erase_info *instr)
48static int
49ram_erase(struct mtd_info *mtd, struct erase_info *instr)
50{ 38{
51 DEBUG(MTD_DEBUG_LEVEL2, "ram_erase(pos:%ld, len:%ld)\n", (long)instr->addr, (long)instr->len); 39 if (instr->addr + instr->len > mtd->size)
52 if (instr->addr + instr->len > mtd->size) { 40 return -EINVAL;
53 DEBUG(MTD_DEBUG_LEVEL1, "ram_erase() out of bounds (%ld > %ld)\n", (long)(instr->addr + instr->len), (long)mtd->size); 41
54 return -EINVAL; 42 memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
55 } 43
56 44 instr->state = MTD_ERASE_DONE;
57 memset((char *)mtd->priv + instr->addr, 0xff, instr->len); 45 mtd_erase_callback(instr);
58 46
59 instr->state = MTD_ERASE_DONE; 47 return 0;
60 mtd_erase_callback(instr);
61
62 return 0;
63} 48}
64 49
65static int ram_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf) 50static int ram_point(struct mtd_info *mtd, loff_t from, size_t len,
51 size_t *retlen, u_char **mtdbuf)
66{ 52{
67 if (from + len > mtd->size) 53 if (from + len > mtd->size)
68 return -EINVAL; 54 return -EINVAL;
69 55
70 *mtdbuf = mtd->priv + from; 56 *mtdbuf = mtd->priv + from;
71 *retlen = len; 57 *retlen = len;
72 return 0; 58 return 0;
73} 59}
74 60
75static void ram_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, 61static void ram_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from,
76 size_t len) 62 size_t len)
77{ 63{
78 DEBUG(MTD_DEBUG_LEVEL2, "ram_unpoint\n");
79} 64}
80 65
81static int ram_read(struct mtd_info *mtd, loff_t from, size_t len, 66static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
82 size_t *retlen, u_char *buf) 67 size_t *retlen, u_char *buf)
83{ 68{
84 DEBUG(MTD_DEBUG_LEVEL2, "ram_read(pos:%ld, len:%ld)\n", (long)from, (long)len); 69 if (from + len > mtd->size)
85 if (from + len > mtd->size) { 70 return -EINVAL;
86 DEBUG(MTD_DEBUG_LEVEL1, "ram_read() out of bounds (%ld > %ld)\n", (long)(from + len), (long)mtd->size);
87 return -EINVAL;
88 }
89 71
90 memcpy(buf, mtd->priv + from, len); 72 memcpy(buf, mtd->priv + from, len);
91 73
92 *retlen=len; 74 *retlen = len;
93 return 0; 75 return 0;
94} 76}
95 77
96static int ram_write(struct mtd_info *mtd, loff_t to, size_t len, 78static int ram_write(struct mtd_info *mtd, loff_t to, size_t len,
97 size_t *retlen, const u_char *buf) 79 size_t *retlen, const u_char *buf)
98{ 80{
99 DEBUG(MTD_DEBUG_LEVEL2, "ram_write(pos:%ld, len:%ld)\n", (long)to, (long)len); 81 if (to + len > mtd->size)
100 if (to + len > mtd->size) { 82 return -EINVAL;
101 DEBUG(MTD_DEBUG_LEVEL1, "ram_write() out of bounds (%ld > %ld)\n", (long)(to + len), (long)mtd->size);
102 return -EINVAL;
103 }
104 83
105 memcpy ((char *)mtd->priv + to, buf, len); 84 memcpy((char *)mtd->priv + to, buf, len);
106 85
107 *retlen=len; 86 *retlen = len;
108 return 0; 87 return 0;
109} 88}
110 89
111static void __exit cleanup_mtdram(void) 90static void __exit cleanup_mtdram(void)
112{ 91{
113 if (mtd_info) { 92 if (mtd_info) {
114 del_mtd_device(mtd_info); 93 del_mtd_device(mtd_info);
115#if CONFIG_MTDRAM_TOTAL_SIZE > 0 94 if (mtd_info->priv)
116 if (mtd_info->priv) 95 vfree(mtd_info->priv);
117#if CONFIG_MTDRAM_ABS_POS > 0 96 kfree(mtd_info);
118 iounmap(mtd_info->priv); 97 }
119#else
120 vfree(mtd_info->priv);
121#endif
122#endif
123 kfree(mtd_info);
124 }
125}
126
127int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
128 unsigned long size, char *name)
129{
130 memset(mtd, 0, sizeof(*mtd));
131
132 /* Setup the MTD structure */
133 mtd->name = name;
134 mtd->type = MTD_RAM;
135 mtd->flags = MTD_CAP_RAM;
136 mtd->size = size;
137 mtd->erasesize = MTDRAM_ERASE_SIZE;
138 mtd->priv = mapped_address;
139
140 mtd->owner = THIS_MODULE;
141 mtd->erase = ram_erase;
142 mtd->point = ram_point;
143 mtd->unpoint = ram_unpoint;
144 mtd->read = ram_read;
145 mtd->write = ram_write;
146
147 if (add_mtd_device(mtd)) {
148 return -EIO;
149 }
150
151 return 0;
152}
153
154#if CONFIG_MTDRAM_TOTAL_SIZE > 0
155#if CONFIG_MTDRAM_ABS_POS > 0
156static int __init init_mtdram(void)
157{
158 void *addr;
159 int err;
160 /* Allocate some memory */
161 mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
162 if (!mtd_info)
163 return -ENOMEM;
164
165 addr = ioremap(CONFIG_MTDRAM_ABS_POS, MTDRAM_TOTAL_SIZE);
166 if (!addr) {
167 DEBUG(MTD_DEBUG_LEVEL1,
168 "Failed to ioremap) memory region of size %ld at ABS_POS:%ld\n",
169 (long)MTDRAM_TOTAL_SIZE, (long)CONFIG_MTDRAM_ABS_POS);
170 kfree(mtd_info);
171 mtd_info = NULL;
172 return -ENOMEM;
173 }
174 err = mtdram_init_device(mtd_info, addr,
175 MTDRAM_TOTAL_SIZE, "mtdram test device");
176 if (err)
177 {
178 iounmap(addr);
179 kfree(mtd_info);
180 mtd_info = NULL;
181 return err;
182 }
183 memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE);
184 return err;
185} 98}
186 99
187#else /* CONFIG_MTDRAM_ABS_POS > 0 */ 100int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
188 101 unsigned long size, char *name)
189static int __init init_mtdram(void)
190{ 102{
191 void *addr; 103 memset(mtd, 0, sizeof(*mtd));
192 int err; 104
193 /* Allocate some memory */ 105 /* Setup the MTD structure */
194 mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); 106 mtd->name = name;
195 if (!mtd_info) 107 mtd->type = MTD_RAM;
196 return -ENOMEM; 108 mtd->flags = MTD_CAP_RAM;
197 109 mtd->size = size;
198 addr = vmalloc(MTDRAM_TOTAL_SIZE); 110 mtd->erasesize = MTDRAM_ERASE_SIZE;
199 if (!addr) { 111 mtd->priv = mapped_address;
200 DEBUG(MTD_DEBUG_LEVEL1, 112
201 "Failed to vmalloc memory region of size %ld\n", 113 mtd->owner = THIS_MODULE;
202 (long)MTDRAM_TOTAL_SIZE); 114 mtd->erase = ram_erase;
203 kfree(mtd_info); 115 mtd->point = ram_point;
204 mtd_info = NULL; 116 mtd->unpoint = ram_unpoint;
205 return -ENOMEM; 117 mtd->read = ram_read;
206 } 118 mtd->write = ram_write;
207 err = mtdram_init_device(mtd_info, addr, 119
208 MTDRAM_TOTAL_SIZE, "mtdram test device"); 120 if (add_mtd_device(mtd)) {
209 if (err) 121 return -EIO;
210 { 122 }
211 vfree(addr); 123
212 kfree(mtd_info); 124 return 0;
213 mtd_info = NULL;
214 return err;
215 }
216 memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE);
217 return err;
218} 125}
219#endif /* !(CONFIG_MTDRAM_ABS_POS > 0) */
220
221#else /* CONFIG_MTDRAM_TOTAL_SIZE > 0 */
222 126
223static int __init init_mtdram(void) 127static int __init init_mtdram(void)
224{ 128{
225 return 0; 129 void *addr;
130 int err;
131
132 if (!total_size)
133 return -EINVAL;
134
135 /* Allocate some memory */
136 mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
137 if (!mtd_info)
138 return -ENOMEM;
139
140 addr = vmalloc(MTDRAM_TOTAL_SIZE);
141 if (!addr) {
142 kfree(mtd_info);
143 mtd_info = NULL;
144 return -ENOMEM;
145 }
146 err = mtdram_init_device(mtd_info, addr, MTDRAM_TOTAL_SIZE, "mtdram test device");
147 if (err) {
148 vfree(addr);
149 kfree(mtd_info);
150 mtd_info = NULL;
151 return err;
152 }
153 memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE);
154 return err;
226} 155}
227#endif /* !(CONFIG_MTDRAM_TOTAL_SIZE > 0) */
228 156
229module_init(init_mtdram); 157module_init(init_mtdram);
230module_exit(cleanup_mtdram); 158module_exit(cleanup_mtdram);
@@ -232,4 +160,3 @@ module_exit(cleanup_mtdram);
232MODULE_LICENSE("GPL"); 160MODULE_LICENSE("GPL");
233MODULE_AUTHOR("Alexander Larsson <alexl@redhat.com>"); 161MODULE_AUTHOR("Alexander Larsson <alexl@redhat.com>");
234MODULE_DESCRIPTION("Simulated MTD driver for testing"); 162MODULE_DESCRIPTION("Simulated MTD driver for testing");
235
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index 5f8e164ddb71..a423a382095a 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -1,5 +1,5 @@
1/** 1/**
2 * $Id: phram.c,v 1.11 2005/01/05 18:05:13 dwmw2 Exp $ 2 * $Id: phram.c,v 1.14 2005/03/07 21:43:38 joern Exp $
3 * 3 *
4 * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de> 4 * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de>
5 * Copyright (c) 2003-2004 Jörn Engel <joern@wh.fh-wedel.de> 5 * Copyright (c) 2003-2004 Jörn Engel <joern@wh.fh-wedel.de>
@@ -15,9 +15,7 @@
15 * 15 *
16 * Example: 16 * Example:
17 * phram=swap,64Mi,128Mi phram=test,900Mi,1Mi 17 * phram=swap,64Mi,128Mi phram=test,900Mi,1Mi
18 *
19 */ 18 */
20
21#include <asm/io.h> 19#include <asm/io.h>
22#include <linux/init.h> 20#include <linux/init.h>
23#include <linux/kernel.h> 21#include <linux/kernel.h>
@@ -36,7 +34,6 @@ struct phram_mtd_list {
36static LIST_HEAD(phram_list); 34static LIST_HEAD(phram_list);
37 35
38 36
39
40static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) 37static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
41{ 38{
42 u_char *start = mtd->priv; 39 u_char *start = mtd->priv;
@@ -71,7 +68,8 @@ static int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
71 return 0; 68 return 0;
72} 69}
73 70
74static void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) 71static void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from,
72 size_t len)
75{ 73{
76} 74}
77 75
@@ -80,8 +78,11 @@ static int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
80{ 78{
81 u_char *start = mtd->priv; 79 u_char *start = mtd->priv;
82 80
83 if (from + len > mtd->size) 81 if (from >= mtd->size)
84 return -EINVAL; 82 return -EINVAL;
83
84 if (len > mtd->size - from)
85 len = mtd->size - from;
85 86
86 memcpy(buf, start + from, len); 87 memcpy(buf, start + from, len);
87 88
@@ -94,8 +95,11 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len,
94{ 95{
95 u_char *start = mtd->priv; 96 u_char *start = mtd->priv;
96 97
97 if (to + len > mtd->size) 98 if (to >= mtd->size)
98 return -EINVAL; 99 return -EINVAL;
100
101 if (len > mtd->size - to)
102 len = mtd->size - to;
99 103
100 memcpy(start + to, buf, len); 104 memcpy(start + to, buf, len);
101 105
@@ -107,9 +111,9 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len,
107 111
108static void unregister_devices(void) 112static void unregister_devices(void)
109{ 113{
110 struct phram_mtd_list *this; 114 struct phram_mtd_list *this, *safe;
111 115
112 list_for_each_entry(this, &phram_list, list) { 116 list_for_each_entry_safe(this, safe, &phram_list, list) {
113 del_mtd_device(&this->mtd); 117 del_mtd_device(&this->mtd);
114 iounmap(this->mtd.priv); 118 iounmap(this->mtd.priv);
115 kfree(this); 119 kfree(this);
@@ -145,7 +149,7 @@ static int register_device(char *name, unsigned long start, unsigned long len)
145 new->mtd.write = phram_write; 149 new->mtd.write = phram_write;
146 new->mtd.owner = THIS_MODULE; 150 new->mtd.owner = THIS_MODULE;
147 new->mtd.type = MTD_RAM; 151 new->mtd.type = MTD_RAM;
148 new->mtd.erasesize = 0; 152 new->mtd.erasesize = PAGE_SIZE;
149 153
150 ret = -EAGAIN; 154 ret = -EAGAIN;
151 if (add_mtd_device(&new->mtd)) { 155 if (add_mtd_device(&new->mtd)) {
@@ -214,6 +218,15 @@ static int parse_name(char **pname, const char *token)
214 return 0; 218 return 0;
215} 219}
216 220
221
222static inline void kill_final_newline(char *str)
223{
224 char *newline = strrchr(str, '\n');
225 if (newline && !newline[1])
226 *newline = 0;
227}
228
229
217#define parse_err(fmt, args...) do { \ 230#define parse_err(fmt, args...) do { \
218 ERROR(fmt , ## args); \ 231 ERROR(fmt , ## args); \
219 return 0; \ 232 return 0; \
@@ -232,6 +245,7 @@ static int phram_setup(const char *val, struct kernel_param *kp)
232 parse_err("parameter too long\n"); 245 parse_err("parameter too long\n");
233 246
234 strcpy(str, val); 247 strcpy(str, val);
248 kill_final_newline(str);
235 249
236 for (i=0; i<3; i++) 250 for (i=0; i<3; i++)
237 token[i] = strsep(&str, ","); 251 token[i] = strsep(&str, ",");
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 5ab15e643be7..84fa91392a8c 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -1,6 +1,6 @@
1/*====================================================================== 1/*======================================================================
2 2
3 $Id: slram.c,v 1.33 2005/01/05 18:05:13 dwmw2 Exp $ 3 $Id: slram.c,v 1.34 2005/01/06 21:16:42 jwboyer Exp $
4 4
5 This driver provides a method to access memory not used by the kernel 5 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 6 itself (i.e. if the kernel commandline mem=xxx is used). To actually
@@ -50,6 +50,7 @@
50#include <linux/mtd/mtd.h> 50#include <linux/mtd/mtd.h>
51 51
52#define SLRAM_MAX_DEVICES_PARAMS 6 /* 3 parameters / device */ 52#define SLRAM_MAX_DEVICES_PARAMS 6 /* 3 parameters / device */
53#define SLRAM_BLK_SZ 0x4000
53 54
54#define T(fmt, args...) printk(KERN_DEBUG fmt, ## args) 55#define T(fmt, args...) printk(KERN_DEBUG fmt, ## args)
55#define E(fmt, args...) printk(KERN_NOTICE fmt, ## args) 56#define E(fmt, args...) printk(KERN_NOTICE fmt, ## args)
@@ -108,6 +109,9 @@ static int slram_point(struct mtd_info *mtd, loff_t from, size_t len,
108{ 109{
109 slram_priv_t *priv = mtd->priv; 110 slram_priv_t *priv = mtd->priv;
110 111
112 if (from + len > mtd->size)
113 return -EINVAL;
114
111 *mtdbuf = priv->start + from; 115 *mtdbuf = priv->start + from;
112 *retlen = len; 116 *retlen = len;
113 return(0); 117 return(0);
@@ -121,7 +125,13 @@ static int slram_read(struct mtd_info *mtd, loff_t from, size_t len,
121 size_t *retlen, u_char *buf) 125 size_t *retlen, u_char *buf)
122{ 126{
123 slram_priv_t *priv = mtd->priv; 127 slram_priv_t *priv = mtd->priv;
124 128
129 if (from > mtd->size)
130 return -EINVAL;
131
132 if (from + len > mtd->size)
133 len = mtd->size - from;
134
125 memcpy(buf, priv->start + from, len); 135 memcpy(buf, priv->start + from, len);
126 136
127 *retlen = len; 137 *retlen = len;
@@ -133,6 +143,9 @@ static int slram_write(struct mtd_info *mtd, loff_t to, size_t len,
133{ 143{
134 slram_priv_t *priv = mtd->priv; 144 slram_priv_t *priv = mtd->priv;
135 145
146 if (to + len > mtd->size)
147 return -EINVAL;
148
136 memcpy(priv->start + to, buf, len); 149 memcpy(priv->start + to, buf, len);
137 150
138 *retlen = len; 151 *retlen = len;
@@ -188,7 +201,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
188 (*curmtd)->mtdinfo->name = name; 201 (*curmtd)->mtdinfo->name = name;
189 (*curmtd)->mtdinfo->size = length; 202 (*curmtd)->mtdinfo->size = length;
190 (*curmtd)->mtdinfo->flags = MTD_CLEAR_BITS | MTD_SET_BITS | 203 (*curmtd)->mtdinfo->flags = MTD_CLEAR_BITS | MTD_SET_BITS |
191 MTD_WRITEB_WRITEABLE | MTD_VOLATILE; 204 MTD_WRITEB_WRITEABLE | MTD_VOLATILE | MTD_CAP_RAM;
192 (*curmtd)->mtdinfo->erase = slram_erase; 205 (*curmtd)->mtdinfo->erase = slram_erase;
193 (*curmtd)->mtdinfo->point = slram_point; 206 (*curmtd)->mtdinfo->point = slram_point;
194 (*curmtd)->mtdinfo->unpoint = slram_unpoint; 207 (*curmtd)->mtdinfo->unpoint = slram_unpoint;
@@ -196,7 +209,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
196 (*curmtd)->mtdinfo->write = slram_write; 209 (*curmtd)->mtdinfo->write = slram_write;
197 (*curmtd)->mtdinfo->owner = THIS_MODULE; 210 (*curmtd)->mtdinfo->owner = THIS_MODULE;
198 (*curmtd)->mtdinfo->type = MTD_RAM; 211 (*curmtd)->mtdinfo->type = MTD_RAM;
199 (*curmtd)->mtdinfo->erasesize = 0x0; 212 (*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ;
200 213
201 if (add_mtd_device((*curmtd)->mtdinfo)) { 214 if (add_mtd_device((*curmtd)->mtdinfo)) {
202 E("slram: Failed to register new device\n"); 215 E("slram: Failed to register new device\n");
@@ -261,7 +274,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
261 } 274 }
262 T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n", 275 T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
263 devname, devstart, devlength); 276 devname, devstart, devlength);
264 if ((devstart < 0) || (devlength < 0)) { 277 if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
265 E("slram: Illegal start / length parameter.\n"); 278 E("slram: Illegal start / length parameter.\n");
266 return(-EINVAL); 279 return(-EINVAL);
267 } 280 }
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
index 18cc8846e733..d9ab60b36fd4 100644
--- a/drivers/mtd/ftl.c
+++ b/drivers/mtd/ftl.c
@@ -1,5 +1,5 @@
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.54 2004/11/16 18:33:15 dwmw2 Exp $ 2 * $Id: ftl.c,v 1.55 2005/01/17 13:47:21 hvr Exp $
3 * 3 *
4 * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br> 4 * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
5 * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups 5 * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
@@ -357,6 +357,7 @@ static int erase_xfer(partition_t *part,
357 if (!erase) 357 if (!erase)
358 return -ENOMEM; 358 return -ENOMEM;
359 359
360 erase->mtd = part->mbd.mtd;
360 erase->callback = ftl_erase_callback; 361 erase->callback = ftl_erase_callback;
361 erase->addr = xfer->Offset; 362 erase->addr = xfer->Offset;
362 erase->len = 1 << part->header.EraseUnitSize; 363 erase->len = 1 << part->header.EraseUnitSize;
@@ -1096,7 +1097,7 @@ struct mtd_blktrans_ops ftl_tr = {
1096 1097
1097int init_ftl(void) 1098int init_ftl(void)
1098{ 1099{
1099 DEBUG(0, "$Id: ftl.c,v 1.54 2004/11/16 18:33:15 dwmw2 Exp $\n"); 1100 DEBUG(0, "$Id: ftl.c,v 1.55 2005/01/17 13:47:21 hvr Exp $\n");
1100 1101
1101 return register_mtd_blktrans(&ftl_tr); 1102 return register_mtd_blktrans(&ftl_tr);
1102} 1103}
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 2bea2e0b06f2..44781a83b2e7 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -1,5 +1,5 @@
1# drivers/mtd/maps/Kconfig 1# drivers/mtd/maps/Kconfig
2# $Id: Kconfig,v 1.42 2005/01/05 16:59:50 dwmw2 Exp $ 2# $Id: Kconfig,v 1.55 2005/07/02 01:53:24 tpoynor Exp $
3 3
4menu "Mapping drivers for chip access" 4menu "Mapping drivers for chip access"
5 depends on MTD!=n 5 depends on MTD!=n
@@ -122,16 +122,6 @@ config MTD_SBC_GXX
122 More info at 122 More info at
123 <http://www.arcomcontrols.com/products/icp/pc104/processors/SBC_GX1.htm>. 123 <http://www.arcomcontrols.com/products/icp/pc104/processors/SBC_GX1.htm>.
124 124
125config MTD_ELAN_104NC
126 tristate "CFI Flash device mapped on Arcom ELAN-104NC"
127 depends on X86 && MTD_CFI_INTELEXT && MTD_PARTITIONS && MTD_COMPLEX_MAPPINGS
128 help
129 This provides a driver for the on-board flash of the Arcom Control
130 System's ELAN-104NC development board. By default the flash
131 is split into 3 partitions which are accessed as separate MTD
132 devices. This board utilizes Intel StrataFlash. More info at
133 <http://www.arcomcontrols.com/products/icp/pc104/processors/ELAN104NC.htm>.
134
135config MTD_LUBBOCK 125config MTD_LUBBOCK
136 tristate "CFI Flash device mapped on Intel Lubbock XScale eval board" 126 tristate "CFI Flash device mapped on Intel Lubbock XScale eval board"
137 depends on ARCH_LUBBOCK && MTD_CFI_INTELEXT && MTD_PARTITIONS 127 depends on ARCH_LUBBOCK && MTD_CFI_INTELEXT && MTD_PARTITIONS
@@ -139,6 +129,14 @@ config MTD_LUBBOCK
139 This provides a driver for the on-board flash of the Intel 129 This provides a driver for the on-board flash of the Intel
140 'Lubbock' XScale evaluation board. 130 'Lubbock' XScale evaluation board.
141 131
132config MTD_MAINSTONE
133 tristate "CFI Flash device mapped on Intel Mainstone XScale eval board"
134 depends on MACH_MAINSTONE && MTD_CFI_INTELEXT
135 select MTD_PARTITIONS
136 help
137 This provides a driver for the on-board flash of the Intel
138 'Mainstone PXA27x evaluation board.
139
142config MTD_OCTAGON 140config MTD_OCTAGON
143 tristate "JEDEC Flash device mapped on Octagon 5066 SBC" 141 tristate "JEDEC Flash device mapped on Octagon 5066 SBC"
144 depends on X86 && MTD_JEDEC && MTD_COMPLEX_MAPPINGS 142 depends on X86 && MTD_JEDEC && MTD_COMPLEX_MAPPINGS
@@ -213,74 +211,11 @@ config MTD_NETtel
213 help 211 help
214 Support for flash chips on NETtel/SecureEdge/SnapGear boards. 212 Support for flash chips on NETtel/SecureEdge/SnapGear boards.
215 213
216config MTD_PB1XXX 214config MTD_ALCHEMY
217 tristate "Flash devices on Alchemy PB1xxx boards" 215 tristate ' AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support'
218 depends on MIPS && ( MIPS_PB1000 || MIPS_PB1100 || MIPS_PB1500 ) 216 depends on MIPS && SOC_AU1X00
219 help
220 Flash memory access on Alchemy Pb1000/Pb1100/Pb1500 boards
221
222config MTD_PB1XXX_BOOT
223 bool "PB1x00 boot flash device"
224 depends on MTD_PB1XXX && ( MIPS_PB1100 || MIPS_PB1500 )
225 help
226 Use the first of the two 32MiB flash banks on Pb1100/Pb1500 board.
227 You can say 'Y' to both this and 'MTD_PB1XXX_USER' below, to use
228 both banks.
229
230config MTD_PB1XXX_USER
231 bool "PB1x00 user flash device"
232 depends on MTD_PB1XXX && ( MIPS_PB1100 || MIPS_PB1500 )
233 default y if MTD_PB1XX_BOOT = n
234 help
235 Use the second of the two 32MiB flash banks on Pb1100/Pb1500 board.
236 You can say 'Y' to both this and 'MTD_PB1XXX_BOOT' above, to use
237 both banks.
238
239config MTD_PB1550
240 tristate "Flash devices on Alchemy PB1550 board"
241 depends on MIPS && MIPS_PB1550
242 help
243 Flash memory access on Alchemy Pb1550 board
244
245config MTD_PB1550_BOOT
246 bool "PB1550 boot flash device"
247 depends on MTD_PB1550
248 help 217 help
249 Use the first of the two 64MiB flash banks on Pb1550 board. 218 Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards
250 You can say 'Y' to both this and 'MTD_PB1550_USER' below, to use
251 both banks.
252
253config MTD_PB1550_USER
254 bool "PB1550 user flash device"
255 depends on MTD_PB1550
256 default y if MTD_PB1550_BOOT = n
257 help
258 Use the second of the two 64MiB flash banks on Pb1550 board.
259 You can say 'Y' to both this and 'MTD_PB1550_BOOT' above, to use
260 both banks.
261
262config MTD_DB1550
263 tristate "Flash devices on Alchemy DB1550 board"
264 depends on MIPS && MIPS_DB1550
265 help
266 Flash memory access on Alchemy Db1550 board
267
268config MTD_DB1550_BOOT
269 bool "DB1550 boot flash device"
270 depends on MTD_DB1550
271 help
272 Use the first of the two 64MiB flash banks on Db1550 board.
273 You can say 'Y' to both this and 'MTD_DB1550_USER' below, to use
274 both banks.
275
276config MTD_DB1550_USER
277 bool "DB1550 user flash device"
278 depends on MTD_DB1550
279 default y if MTD_DB1550_BOOT = n
280 help
281 Use the second of the two 64MiB flash banks on Db1550 board.
282 You can say 'Y' to both this and 'MTD_DB1550_BOOT' above, to use
283 both banks.
284 219
285config MTD_DILNETPC 220config MTD_DILNETPC
286 tristate "CFI Flash device mapped on DIL/Net PC" 221 tristate "CFI Flash device mapped on DIL/Net PC"
@@ -588,6 +523,15 @@ config MTD_MPC1211
588 This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02). 523 This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02).
589 If you have such a board, say 'Y'. 524 If you have such a board, say 'Y'.
590 525
526config MTD_OMAP_NOR
527 tristate "TI OMAP board mappings"
528 depends on MTD_CFI && ARCH_OMAP
529 help
530 This enables access to the NOR flash chips on TI OMAP-based
531 boards defining flash platform devices and flash platform data.
532 These boards include the Innovator, H2, H3, OSK, Perseus2, and
533 more. If you have such a board, say 'Y'.
534
591# This needs CFI or JEDEC, depending on the cards found. 535# This needs CFI or JEDEC, depending on the cards found.
592config MTD_PCI 536config MTD_PCI
593 tristate "PCI MTD driver" 537 tristate "PCI MTD driver"
@@ -647,13 +591,14 @@ config MTD_DMV182
647 Map driver for Dy-4 SVME/DMV-182 board. 591 Map driver for Dy-4 SVME/DMV-182 board.
648 592
649config MTD_BAST 593config MTD_BAST
650 tristate "Map driver for Simtec BAST (EB2410ITX)" 594 tristate "Map driver for Simtec BAST (EB2410ITX) or Thorcom VR1000"
651 depends on ARCH_BAST 595 depends on ARCH_BAST || MACH_VR1000
652 select MTD_PARTITIONS 596 select MTD_PARTITIONS
653 select MTD_MAP_BANK_WIDTH_16 597 select MTD_MAP_BANK_WIDTH_16
654 select MTD_JEDECPROBE 598 select MTD_JEDECPROBE
655 help 599 help
656 Map driver for NOR flash on the Simtec BAST (EB2410ITX). 600 Map driver for NOR flash on the Simtec BAST (EB2410ITX), or the
601 Thorcom VR1000
657 602
658 Note, this driver *cannot* over-ride the WP link on the 603 Note, this driver *cannot* over-ride the WP link on the
659 board, or currently detect the state of the link. 604 board, or currently detect the state of the link.
@@ -669,5 +614,15 @@ config MTD_SHARP_SL
669 help 614 help
670 This enables access to the flash chip on the Sharp SL Series of PDAs. 615 This enables access to the flash chip on the Sharp SL Series of PDAs.
671 616
617config MTD_PLATRAM
618 tristate "Map driver for platform device RAM (mtd-ram)"
619 depends on MTD
620 select MTD_RAM
621 help
622 Map driver for RAM areas described via the platform device
623 system.
624
625 This selection automatically selects the map_ram driver.
626
672endmenu 627endmenu
673 628
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 7ffe02b85301..7bcbc49e329f 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# linux/drivers/maps/Makefile 2# linux/drivers/maps/Makefile
3# 3#
4# $Id: Makefile.common,v 1.23 2005/01/05 17:06:36 dwmw2 Exp $ 4# $Id: Makefile.common,v 1.30 2005/07/02 01:53:24 tpoynor Exp $
5 5
6ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y) 6ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
7obj-$(CONFIG_MTD) += map_funcs.o 7obj-$(CONFIG_MTD) += map_funcs.o
@@ -15,7 +15,6 @@ obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o
15obj-$(CONFIG_MTD_CSTM_MIPS_IXX) += cstm_mips_ixx.o 15obj-$(CONFIG_MTD_CSTM_MIPS_IXX) += cstm_mips_ixx.o
16obj-$(CONFIG_MTD_DC21285) += dc21285.o 16obj-$(CONFIG_MTD_DC21285) += dc21285.o
17obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o 17obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o
18obj-$(CONFIG_MTD_ELAN_104NC) += elan-104nc.o
19obj-$(CONFIG_MTD_EPXA10DB) += epxa10db-flash.o 18obj-$(CONFIG_MTD_EPXA10DB) += epxa10db-flash.o
20obj-$(CONFIG_MTD_IQ80310) += iq80310.o 19obj-$(CONFIG_MTD_IQ80310) += iq80310.o
21obj-$(CONFIG_MTD_L440GX) += l440gx.o 20obj-$(CONFIG_MTD_L440GX) += l440gx.o
@@ -23,6 +22,7 @@ obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o
23obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o 22obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o
24obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o 23obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o
25obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o 24obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o
25obj-$(CONFIG_MTD_MAINSTONE) += mainstone-flash.o
26obj-$(CONFIG_MTD_MBX860) += mbx860.o 26obj-$(CONFIG_MTD_MBX860) += mbx860.o
27obj-$(CONFIG_MTD_CEIVA) += ceiva.o 27obj-$(CONFIG_MTD_CEIVA) += ceiva.o
28obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o 28obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o
@@ -44,10 +44,7 @@ obj-$(CONFIG_MTD_DBOX2) += dbox2-flash.o
44obj-$(CONFIG_MTD_OCELOT) += ocelot.o 44obj-$(CONFIG_MTD_OCELOT) += ocelot.o
45obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o 45obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
46obj-$(CONFIG_MTD_PCI) += pci.o 46obj-$(CONFIG_MTD_PCI) += pci.o
47obj-$(CONFIG_MTD_PB1XXX) += pb1xxx-flash.o 47obj-$(CONFIG_MTD_ALCHEMY) += alchemy-flash.o
48obj-$(CONFIG_MTD_DB1X00) += db1x00-flash.o
49obj-$(CONFIG_MTD_PB1550) += pb1550-flash.o
50obj-$(CONFIG_MTD_DB1550) += db1550-flash.o
51obj-$(CONFIG_MTD_LASAT) += lasat.o 48obj-$(CONFIG_MTD_LASAT) += lasat.o
52obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o 49obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o
53obj-$(CONFIG_MTD_EDB7312) += edb7312.o 50obj-$(CONFIG_MTD_EDB7312) += edb7312.o
@@ -71,3 +68,5 @@ obj-$(CONFIG_MTD_IXP2000) += ixp2000.o
71obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o 68obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o
72obj-$(CONFIG_MTD_DMV182) += dmv182.o 69obj-$(CONFIG_MTD_DMV182) += dmv182.o
73obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o 70obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o
71obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
72obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
diff --git a/drivers/mtd/maps/alchemy-flash.c b/drivers/mtd/maps/alchemy-flash.c
new file mode 100644
index 000000000000..27fd2a3c3b60
--- /dev/null
+++ b/drivers/mtd/maps/alchemy-flash.c
@@ -0,0 +1,192 @@
1/*
2 * Flash memory access on AMD Alchemy evaluation boards
3 *
4 * $Id: alchemy-flash.c,v 1.1 2005/02/27 21:50:21 ppopov Exp $
5 *
6 * (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com>
7 *
8 */
9
10#include <linux/config.h>
11#include <linux/init.h>
12#include <linux/module.h>
13#include <linux/types.h>
14#include <linux/kernel.h>
15
16#include <linux/mtd/mtd.h>
17#include <linux/mtd/map.h>
18#include <linux/mtd/partitions.h>
19
20#include <asm/io.h>
21
22#ifdef DEBUG_RW
23#define DBG(x...) printk(x)
24#else
25#define DBG(x...)
26#endif
27
28#ifdef CONFIG_MIPS_PB1000
29#define BOARD_MAP_NAME "Pb1000 Flash"
30#define BOARD_FLASH_SIZE 0x00800000 /* 8MB */
31#define BOARD_FLASH_WIDTH 4 /* 32-bits */
32#endif
33
34#ifdef CONFIG_MIPS_PB1500
35#define BOARD_MAP_NAME "Pb1500 Flash"
36#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
37#define BOARD_FLASH_WIDTH 4 /* 32-bits */
38#endif
39
40#ifdef CONFIG_MIPS_PB1100
41#define BOARD_MAP_NAME "Pb1100 Flash"
42#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
43#define BOARD_FLASH_WIDTH 4 /* 32-bits */
44#endif
45
46#ifdef CONFIG_MIPS_PB1550
47#define BOARD_MAP_NAME "Pb1550 Flash"
48#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
49#define BOARD_FLASH_WIDTH 4 /* 32-bits */
50#endif
51
52#ifdef CONFIG_MIPS_PB1200
53#define BOARD_MAP_NAME "Pb1200 Flash"
54#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
55#define BOARD_FLASH_WIDTH 2 /* 16-bits */
56#endif
57
58#ifdef CONFIG_MIPS_DB1000
59#define BOARD_MAP_NAME "Db1000 Flash"
60#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
61#define BOARD_FLASH_WIDTH 4 /* 32-bits */
62#endif
63
64#ifdef CONFIG_MIPS_DB1500
65#define BOARD_MAP_NAME "Db1500 Flash"
66#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
67#define BOARD_FLASH_WIDTH 4 /* 32-bits */
68#endif
69
70#ifdef CONFIG_MIPS_DB1100
71#define BOARD_MAP_NAME "Db1100 Flash"
72#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
73#define BOARD_FLASH_WIDTH 4 /* 32-bits */
74#endif
75
76#ifdef CONFIG_MIPS_DB1550
77#define BOARD_MAP_NAME "Db1550 Flash"
78#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
79#define BOARD_FLASH_WIDTH 4 /* 32-bits */
80#endif
81
82#ifdef CONFIG_MIPS_DB1200
83#define BOARD_MAP_NAME "Db1200 Flash"
84#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
85#define BOARD_FLASH_WIDTH 2 /* 16-bits */
86#endif
87
88#ifdef CONFIG_MIPS_HYDROGEN3
89#define BOARD_MAP_NAME "Hydrogen3 Flash"
90#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
91#define BOARD_FLASH_WIDTH 4 /* 32-bits */
92#define USE_LOCAL_ACCESSORS /* why? */
93#endif
94
95#ifdef CONFIG_MIPS_BOSPORUS
96#define BOARD_MAP_NAME "Bosporus Flash"
97#define BOARD_FLASH_SIZE 0x01000000 /* 16MB */
98#define BOARD_FLASH_WIDTH 2 /* 16-bits */
99#endif
100
101#ifdef CONFIG_MIPS_MIRAGE
102#define BOARD_MAP_NAME "Mirage Flash"
103#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
104#define BOARD_FLASH_WIDTH 4 /* 32-bits */
105#define USE_LOCAL_ACCESSORS /* why? */
106#endif
107
108static struct map_info alchemy_map = {
109 .name = BOARD_MAP_NAME,
110};
111
112static struct mtd_partition alchemy_partitions[] = {
113 {
114 .name = "User FS",
115 .size = BOARD_FLASH_SIZE - 0x00400000,
116 .offset = 0x0000000
117 },{
118 .name = "YAMON",
119 .size = 0x0100000,
120 .offset = MTDPART_OFS_APPEND,
121 .mask_flags = MTD_WRITEABLE
122 },{
123 .name = "raw kernel",
124 .size = (0x300000 - 0x40000), /* last 256KB is yamon env */
125 .offset = MTDPART_OFS_APPEND,
126 }
127};
128
129#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
130
131static struct mtd_info *mymtd;
132
133int __init alchemy_mtd_init(void)
134{
135 struct mtd_partition *parts;
136 int nb_parts = 0;
137 unsigned long window_addr;
138 unsigned long window_size;
139
140 /* Default flash buswidth */
141 alchemy_map.bankwidth = BOARD_FLASH_WIDTH;
142
143 window_addr = 0x20000000 - BOARD_FLASH_SIZE;
144 window_size = BOARD_FLASH_SIZE;
145#ifdef CONFIG_MIPS_MIRAGE_WHY
146 /* Boot ROM flash bank only; no user bank */
147 window_addr = 0x1C000000;
148 window_size = 0x04000000;
149 /* USERFS from 0x1C00 0000 to 0x1FC00000 */
150 alchemy_partitions[0].size = 0x03C00000;
151#endif
152
153 /*
154 * Static partition definition selection
155 */
156 parts = alchemy_partitions;
157 nb_parts = NB_OF(alchemy_partitions);
158 alchemy_map.size = window_size;
159
160 /*
161 * Now let's probe for the actual flash. Do it here since
162 * specific machine settings might have been set above.
163 */
164 printk(KERN_NOTICE BOARD_MAP_NAME ": probing %d-bit flash bus\n",
165 alchemy_map.bankwidth*8);
166 alchemy_map.virt = ioremap(window_addr, window_size);
167 mymtd = do_map_probe("cfi_probe", &alchemy_map);
168 if (!mymtd) {
169 iounmap(alchemy_map.virt);
170 return -ENXIO;
171 }
172 mymtd->owner = THIS_MODULE;
173
174 add_mtd_partitions(mymtd, parts, nb_parts);
175 return 0;
176}
177
178static void __exit alchemy_mtd_cleanup(void)
179{
180 if (mymtd) {
181 del_mtd_partitions(mymtd);
182 map_destroy(mymtd);
183 iounmap(alchemy_map.virt);
184 }
185}
186
187module_init(alchemy_mtd_init);
188module_exit(alchemy_mtd_cleanup);
189
190MODULE_AUTHOR("Embedded Alley Solutions, Inc");
191MODULE_DESCRIPTION(BOARD_MAP_NAME " MTD driver");
192MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c
index 51e97b05304e..e8a900a77685 100644
--- a/drivers/mtd/maps/amd76xrom.c
+++ b/drivers/mtd/maps/amd76xrom.c
@@ -2,7 +2,7 @@
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.19 2004/11/28 09:40:39 dwmw2 Exp $ 5 * $Id: amd76xrom.c,v 1.20 2005/03/18 14:04:35 gleixner Exp $
6 */ 6 */
7 7
8#include <linux/module.h> 8#include <linux/module.h>
@@ -314,7 +314,7 @@ static int __init init_amd76xrom(void)
314 } 314 }
315 return -ENXIO; 315 return -ENXIO;
316#if 0 316#if 0
317 return pci_module_init(&amd76xrom_driver); 317 return pci_register_driver(&amd76xrom_driver);
318#endif 318#endif
319} 319}
320 320
diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c
index 44de3a81b277..0c45464e3f7b 100644
--- a/drivers/mtd/maps/bast-flash.c
+++ b/drivers/mtd/maps/bast-flash.c
@@ -1,14 +1,15 @@
1/* linux/drivers/mtd/maps/bast_flash.c 1/* linux/drivers/mtd/maps/bast_flash.c
2 * 2 *
3 * Copyright (c) 2004 Simtec Electronics 3 * Copyright (c) 2004-2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
5 * 5 *
6 * Simtec Bast (EB2410ITX) NOR MTD Mapping driver 6 * Simtec Bast (EB2410ITX) NOR MTD Mapping driver
7 * 7 *
8 * Changelog: 8 * Changelog:
9 * 20-Sep-2004 BJD Initial version 9 * 20-Sep-2004 BJD Initial version
10 * 17-Jan-2005 BJD Add whole device if no partitions found
10 * 11 *
11 * $Id: bast-flash.c,v 1.1 2004/09/21 14:29:04 bjd Exp $ 12 * $Id: bast-flash.c,v 1.2 2005/01/18 11:13:47 bjd Exp $
12 * 13 *
13 * This program is free software; you can redistribute it and/or modify 14 * 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 15 * it under the terms of the GNU General Public License as published by
@@ -46,9 +47,9 @@
46#include <asm/arch/bast-cpld.h> 47#include <asm/arch/bast-cpld.h>
47 48
48#ifdef CONFIG_MTD_BAST_MAXSIZE 49#ifdef CONFIG_MTD_BAST_MAXSIZE
49#define AREA_MAXSIZE (CONFIG_MTD_BAST_MAXSIZE * (1024*1024)) 50#define AREA_MAXSIZE (CONFIG_MTD_BAST_MAXSIZE * SZ_1M)
50#else 51#else
51#define AREA_MAXSIZE (32*1024*1024) 52#define AREA_MAXSIZE (32 * SZ_1M)
52#endif 53#endif
53 54
54#define PFX "bast-flash: " 55#define PFX "bast-flash: "
@@ -189,6 +190,8 @@ static int bast_flash_probe(struct device *dev)
189 err = add_mtd_partitions(info->mtd, info->partitions, err); 190 err = add_mtd_partitions(info->mtd, info->partitions, err);
190 if (err) 191 if (err)
191 printk(KERN_ERR PFX "cannot add/parse partitions\n"); 192 printk(KERN_ERR PFX "cannot add/parse partitions\n");
193 } else {
194 err = add_mtd_device(info->mtd);
192 } 195 }
193 196
194 if (err == 0) 197 if (err == 0)
diff --git a/drivers/mtd/maps/db1550-flash.c b/drivers/mtd/maps/db1550-flash.c
deleted file mode 100644
index d213888462a4..000000000000
--- a/drivers/mtd/maps/db1550-flash.c
+++ /dev/null
@@ -1,187 +0,0 @@
1/*
2 * Flash memory access on Alchemy Db1550 board
3 *
4 * $Id: db1550-flash.c,v 1.7 2004/11/04 13:24:14 gleixner Exp $
5 *
6 * (C) 2004 Embedded Edge, LLC, based on db1550-flash.c:
7 * (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com>
8 *
9 */
10
11#include <linux/config.h>
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/kernel.h>
16
17#include <linux/mtd/mtd.h>
18#include <linux/mtd/map.h>
19#include <linux/mtd/partitions.h>
20
21#include <asm/io.h>
22
23#ifdef DEBUG_RW
24#define DBG(x...) printk(x)
25#else
26#define DBG(x...)
27#endif
28
29static unsigned long window_addr;
30static unsigned long window_size;
31
32
33static struct map_info db1550_map = {
34 .name = "Db1550 flash",
35};
36
37static unsigned char flash_bankwidth = 4;
38
39/*
40 * Support only 64MB NOR Flash parts
41 */
42
43#if defined(CONFIG_MTD_DB1550_BOOT) && defined(CONFIG_MTD_DB1550_USER)
44#define DB1550_BOTH_BANKS
45#elif defined(CONFIG_MTD_DB1550_BOOT) && !defined(CONFIG_MTD_DB1550_USER)
46#define DB1550_BOOT_ONLY
47#elif !defined(CONFIG_MTD_DB1550_BOOT) && defined(CONFIG_MTD_DB1550_USER)
48#define DB1550_USER_ONLY
49#endif
50
51#ifdef DB1550_BOTH_BANKS
52/* both banks will be used. Combine the first bank and the first
53 * part of the second bank together into a single jffs/jffs2
54 * partition.
55 */
56static struct mtd_partition db1550_partitions[] = {
57 /* assume boot[2:0]:swap is '0000' or '1000', which translates to:
58 * 1C00 0000 1FFF FFFF CE0 64MB Boot NOR Flash
59 * 1800 0000 1BFF FFFF CE0 64MB Param NOR Flash
60 */
61 {
62 .name = "User FS",
63 .size = (0x1FC00000 - 0x18000000),
64 .offset = 0x0000000
65 },{
66 .name = "yamon",
67 .size = 0x0100000,
68 .offset = MTDPART_OFS_APPEND,
69 .mask_flags = MTD_WRITEABLE
70 },{
71 .name = "raw kernel",
72 .size = (0x300000 - 0x40000), /* last 256KB is yamon env */
73 .offset = MTDPART_OFS_APPEND,
74 }
75};
76#elif defined(DB1550_BOOT_ONLY)
77static struct mtd_partition db1550_partitions[] = {
78 /* assume boot[2:0]:swap is '0000' or '1000', which translates to:
79 * 1C00 0000 1FFF FFFF CE0 64MB Boot NOR Flash
80 */
81 {
82 .name = "User FS",
83 .size = 0x03c00000,
84 .offset = 0x0000000
85 },{
86 .name = "yamon",
87 .size = 0x0100000,
88 .offset = MTDPART_OFS_APPEND,
89 .mask_flags = MTD_WRITEABLE
90 },{
91 .name = "raw kernel",
92 .size = (0x300000-0x40000), /* last 256KB is yamon env */
93 .offset = MTDPART_OFS_APPEND,
94 }
95};
96#elif defined(DB1550_USER_ONLY)
97static struct mtd_partition db1550_partitions[] = {
98 /* assume boot[2:0]:swap is '0000' or '1000', which translates to:
99 * 1800 0000 1BFF FFFF CE0 64MB Param NOR Flash
100 */
101 {
102 .name = "User FS",
103 .size = (0x4000000 - 0x200000), /* reserve 2MB for raw kernel */
104 .offset = 0x0000000
105 },{
106 .name = "raw kernel",
107 .size = MTDPART_SIZ_FULL,
108 .offset = MTDPART_OFS_APPEND,
109 }
110};
111#else
112#error MTD_DB1550 define combo error /* should never happen */
113#endif
114
115#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
116
117static struct mtd_info *mymtd;
118
119/*
120 * Probe the flash density and setup window address and size
121 * based on user CONFIG options. There are times when we don't
122 * want the MTD driver to be probing the boot or user flash,
123 * so having the option to enable only one bank is important.
124 */
125int setup_flash_params(void)
126{
127#if defined(DB1550_BOTH_BANKS)
128 window_addr = 0x18000000;
129 window_size = 0x8000000;
130#elif defined(DB1550_BOOT_ONLY)
131 window_addr = 0x1C000000;
132 window_size = 0x4000000;
133#else /* USER ONLY */
134 window_addr = 0x18000000;
135 window_size = 0x4000000;
136#endif
137 return 0;
138}
139
140int __init db1550_mtd_init(void)
141{
142 struct mtd_partition *parts;
143 int nb_parts = 0;
144
145 /* Default flash bankwidth */
146 db1550_map.bankwidth = flash_bankwidth;
147
148 if (setup_flash_params())
149 return -ENXIO;
150
151 /*
152 * Static partition definition selection
153 */
154 parts = db1550_partitions;
155 nb_parts = NB_OF(db1550_partitions);
156 db1550_map.size = window_size;
157
158 /*
159 * Now let's probe for the actual flash. Do it here since
160 * specific machine settings might have been set above.
161 */
162 printk(KERN_NOTICE "Db1550 flash: probing %d-bit flash bus\n",
163 db1550_map.bankwidth*8);
164 db1550_map.virt = ioremap(window_addr, window_size);
165 mymtd = do_map_probe("cfi_probe", &db1550_map);
166 if (!mymtd) return -ENXIO;
167 mymtd->owner = THIS_MODULE;
168
169 add_mtd_partitions(mymtd, parts, nb_parts);
170 return 0;
171}
172
173static void __exit db1550_mtd_cleanup(void)
174{
175 if (mymtd) {
176 del_mtd_partitions(mymtd);
177 map_destroy(mymtd);
178 iounmap((void *) db1550_map.virt);
179 }
180}
181
182module_init(db1550_mtd_init);
183module_exit(db1550_mtd_cleanup);
184
185MODULE_AUTHOR("Embedded Edge, LLC");
186MODULE_DESCRIPTION("Db1550 mtd map driver");
187MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/db1x00-flash.c b/drivers/mtd/maps/db1x00-flash.c
deleted file mode 100644
index faa68ec56902..000000000000
--- a/drivers/mtd/maps/db1x00-flash.c
+++ /dev/null
@@ -1,226 +0,0 @@
1/*
2 * Flash memory access on Alchemy Db1xxx boards
3 *
4 * $Id: db1x00-flash.c,v 1.6 2004/11/04 13:24:14 gleixner Exp $
5 *
6 * (C) 2003 Pete Popov <ppopov@embeddedalley.com>
7 *
8 */
9
10#include <linux/config.h>
11#include <linux/module.h>
12#include <linux/types.h>
13#include <linux/init.h>
14#include <linux/kernel.h>
15
16#include <linux/mtd/mtd.h>
17#include <linux/mtd/map.h>
18#include <linux/mtd/partitions.h>
19
20#include <asm/io.h>
21
22#ifdef DEBUG_RW
23#define DBG(x...) printk(x)
24#else
25#define DBG(x...)
26#endif
27
28/* MTD CONFIG OPTIONS */
29#if defined(CONFIG_MTD_DB1X00_BOOT) && defined(CONFIG_MTD_DB1X00_USER)
30#define DB1X00_BOTH_BANKS
31#elif defined(CONFIG_MTD_DB1X00_BOOT) && !defined(CONFIG_MTD_DB1X00_USER)
32#define DB1X00_BOOT_ONLY
33#elif !defined(CONFIG_MTD_DB1X00_BOOT) && defined(CONFIG_MTD_DB1X00_USER)
34#define DB1X00_USER_ONLY
35#endif
36
37static unsigned long window_addr;
38static unsigned long window_size;
39static unsigned long flash_size;
40
41static unsigned short *bcsr = (unsigned short *)0xAE000000;
42static unsigned char flash_bankwidth = 4;
43
44/*
45 * The Db1x boards support different flash densities. We setup
46 * the mtd_partition structures below for default of 64Mbit
47 * flash densities, and override the partitions sizes, if
48 * necessary, after we check the board status register.
49 */
50
51#ifdef DB1X00_BOTH_BANKS
52/* both banks will be used. Combine the first bank and the first
53 * part of the second bank together into a single jffs/jffs2
54 * partition.
55 */
56static struct mtd_partition db1x00_partitions[] = {
57 {
58 .name = "User FS",
59 .size = 0x1c00000,
60 .offset = 0x0000000
61 },{
62 .name = "yamon",
63 .size = 0x0100000,
64 .offset = MTDPART_OFS_APPEND,
65 .mask_flags = MTD_WRITEABLE
66 },{
67 .name = "raw kernel",
68 .size = (0x300000-0x40000), /* last 256KB is env */
69 .offset = MTDPART_OFS_APPEND,
70 }
71};
72#elif defined(DB1X00_BOOT_ONLY)
73static struct mtd_partition db1x00_partitions[] = {
74 {
75 .name = "User FS",
76 .size = 0x00c00000,
77 .offset = 0x0000000
78 },{
79 .name = "yamon",
80 .size = 0x0100000,
81 .offset = MTDPART_OFS_APPEND,
82 .mask_flags = MTD_WRITEABLE
83 },{
84 .name = "raw kernel",
85 .size = (0x300000-0x40000), /* last 256KB is env */
86 .offset = MTDPART_OFS_APPEND,
87 }
88};
89#elif defined(DB1X00_USER_ONLY)
90static struct mtd_partition db1x00_partitions[] = {
91 {
92 .name = "User FS",
93 .size = 0x0e00000,
94 .offset = 0x0000000
95 },{
96 .name = "raw kernel",
97 .size = MTDPART_SIZ_FULL,
98 .offset = MTDPART_OFS_APPEND,
99 }
100};
101#else
102#error MTD_DB1X00 define combo error /* should never happen */
103#endif
104#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
105
106#define NAME "Db1x00 Linux Flash"
107
108static struct map_info db1xxx_mtd_map = {
109 .name = NAME,
110};
111
112static struct mtd_partition *parsed_parts;
113static struct mtd_info *db1xxx_mtd;
114
115/*
116 * Probe the flash density and setup window address and size
117 * based on user CONFIG options. There are times when we don't
118 * want the MTD driver to be probing the boot or user flash,
119 * so having the option to enable only one bank is important.
120 */
121int setup_flash_params(void)
122{
123 switch ((bcsr[2] >> 14) & 0x3) {
124 case 0: /* 64Mbit devices */
125 flash_size = 0x800000; /* 8MB per part */
126#if defined(DB1X00_BOTH_BANKS)
127 window_addr = 0x1E000000;
128 window_size = 0x2000000;
129#elif defined(DB1X00_BOOT_ONLY)
130 window_addr = 0x1F000000;
131 window_size = 0x1000000;
132#else /* USER ONLY */
133 window_addr = 0x1E000000;
134 window_size = 0x1000000;
135#endif
136 break;
137 case 1:
138 /* 128 Mbit devices */
139 flash_size = 0x1000000; /* 16MB per part */
140#if defined(DB1X00_BOTH_BANKS)
141 window_addr = 0x1C000000;
142 window_size = 0x4000000;
143 /* USERFS from 0x1C00 0000 to 0x1FC0 0000 */
144 db1x00_partitions[0].size = 0x3C00000;
145#elif defined(DB1X00_BOOT_ONLY)
146 window_addr = 0x1E000000;
147 window_size = 0x2000000;
148 /* USERFS from 0x1E00 0000 to 0x1FC0 0000 */
149 db1x00_partitions[0].size = 0x1C00000;
150#else /* USER ONLY */
151 window_addr = 0x1C000000;
152 window_size = 0x2000000;
153 /* USERFS from 0x1C00 0000 to 0x1DE00000 */
154 db1x00_partitions[0].size = 0x1DE0000;
155#endif
156 break;
157 case 2:
158 /* 256 Mbit devices */
159 flash_size = 0x4000000; /* 64MB per part */
160#if defined(DB1X00_BOTH_BANKS)
161 return 1;
162#elif defined(DB1X00_BOOT_ONLY)
163 /* Boot ROM flash bank only; no user bank */
164 window_addr = 0x1C000000;
165 window_size = 0x4000000;
166 /* USERFS from 0x1C00 0000 to 0x1FC00000 */
167 db1x00_partitions[0].size = 0x3C00000;
168#else /* USER ONLY */
169 return 1;
170#endif
171 break;
172 default:
173 return 1;
174 }
175 db1xxx_mtd_map.size = window_size;
176 db1xxx_mtd_map.bankwidth = flash_bankwidth;
177 db1xxx_mtd_map.phys = window_addr;
178 db1xxx_mtd_map.bankwidth = flash_bankwidth;
179 return 0;
180}
181
182int __init db1x00_mtd_init(void)
183{
184 struct mtd_partition *parts;
185 int nb_parts = 0;
186
187 if (setup_flash_params())
188 return -ENXIO;
189
190 /*
191 * Static partition definition selection
192 */
193 parts = db1x00_partitions;
194 nb_parts = NB_OF(db1x00_partitions);
195
196 /*
197 * Now let's probe for the actual flash. Do it here since
198 * specific machine settings might have been set above.
199 */
200 printk(KERN_NOTICE "Db1xxx flash: probing %d-bit flash bus\n",
201 db1xxx_mtd_map.bankwidth*8);
202 db1xxx_mtd_map.virt = ioremap(window_addr, window_size);
203 db1xxx_mtd = do_map_probe("cfi_probe", &db1xxx_mtd_map);
204 if (!db1xxx_mtd) return -ENXIO;
205 db1xxx_mtd->owner = THIS_MODULE;
206
207 add_mtd_partitions(db1xxx_mtd, parts, nb_parts);
208 return 0;
209}
210
211static void __exit db1x00_mtd_cleanup(void)
212{
213 if (db1xxx_mtd) {
214 del_mtd_partitions(db1xxx_mtd);
215 map_destroy(db1xxx_mtd);
216 if (parsed_parts)
217 kfree(parsed_parts);
218 }
219}
220
221module_init(db1x00_mtd_init);
222module_exit(db1x00_mtd_cleanup);
223
224MODULE_AUTHOR("Pete Popov");
225MODULE_DESCRIPTION("Db1x00 mtd map driver");
226MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/elan-104nc.c b/drivers/mtd/maps/elan-104nc.c
deleted file mode 100644
index e9465f5c069e..000000000000
--- a/drivers/mtd/maps/elan-104nc.c
+++ /dev/null
@@ -1,228 +0,0 @@
1/* elan-104nc.c -- MTD map driver for Arcom Control Systems ELAN-104NC
2
3 Copyright (C) 2000 Arcom Control System Ltd
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
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
18
19 $Id: elan-104nc.c,v 1.25 2004/11/28 09:40:39 dwmw2 Exp $
20
21The ELAN-104NC has up to 8 Mibyte of Intel StrataFlash (28F320/28F640) in x16
22mode. This drivers uses the CFI probe and Intel Extended Command Set drivers.
23
24The flash is accessed as follows:
25
26 32 kbyte memory window at 0xb0000-0xb7fff
27
28 16 bit I/O port (0x22) for some sort of paging.
29
30The single flash device is divided into 3 partition which appear as separate
31MTD devices.
32
33Linux thinks that the I/O port is used by the PIC and hence check_region() will
34always fail. So we don't do it. I just hope it doesn't break anything.
35*/
36#include <linux/module.h>
37#include <linux/slab.h>
38#include <linux/ioport.h>
39#include <linux/init.h>
40#include <asm/io.h>
41
42#include <linux/mtd/map.h>
43#include <linux/mtd/mtd.h>
44#include <linux/mtd/partitions.h>
45
46#define WINDOW_START 0xb0000
47/* Number of bits in offset. */
48#define WINDOW_SHIFT 15
49#define WINDOW_LENGTH (1 << WINDOW_SHIFT)
50/* The bits for the offset into the window. */
51#define WINDOW_MASK (WINDOW_LENGTH-1)
52#define PAGE_IO 0x22
53#define PAGE_IO_SIZE 2
54
55static volatile int page_in_window = -1; // Current page in window.
56static void __iomem *iomapadr;
57static DEFINE_SPINLOCK(elan_104nc_spin);
58
59/* partition_info gives details on the logical partitions that the split the
60 * single flash device into. If the size if zero we use up to the end of the
61 * device. */
62static struct mtd_partition partition_info[]={
63 { .name = "ELAN-104NC flash boot partition",
64 .offset = 0,
65 .size = 640*1024 },
66 { .name = "ELAN-104NC flash partition 1",
67 .offset = 640*1024,
68 .size = 896*1024 },
69 { .name = "ELAN-104NC flash partition 2",
70 .offset = (640+896)*1024 }
71};
72#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0]))
73
74/*
75 * If no idea what is going on here. This is taken from the FlashFX stuff.
76 */
77#define ROMCS 1
78
79static inline void elan_104nc_setup(void)
80{
81 u16 t;
82
83 outw( 0x0023 + ROMCS*2, PAGE_IO );
84 t=inb( PAGE_IO+1 );
85
86 t=(t & 0xf9) | 0x04;
87
88 outw( ((0x0023 + ROMCS*2) | (t << 8)), PAGE_IO );
89}
90
91static inline void elan_104nc_page(struct map_info *map, unsigned long ofs)
92{
93 unsigned long page = ofs >> WINDOW_SHIFT;
94
95 if( page!=page_in_window ) {
96 int cmd1;
97 int cmd2;
98
99 cmd1=(page & 0x700) + 0x0833 + ROMCS*0x4000;
100 cmd2=((page & 0xff) << 8) + 0x0032;
101
102 outw( cmd1, PAGE_IO );
103 outw( cmd2, PAGE_IO );
104
105 page_in_window = page;
106 }
107}
108
109
110static map_word elan_104nc_read16(struct map_info *map, unsigned long ofs)
111{
112 map_word ret;
113 spin_lock(&elan_104nc_spin);
114 elan_104nc_page(map, ofs);
115 ret.x[0] = readw(iomapadr + (ofs & WINDOW_MASK));
116 spin_unlock(&elan_104nc_spin);
117 return ret;
118}
119
120static void elan_104nc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
121{
122 while (len) {
123 unsigned long thislen = len;
124 if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
125 thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
126
127 spin_lock(&elan_104nc_spin);
128 elan_104nc_page(map, from);
129 memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen);
130 spin_unlock(&elan_104nc_spin);
131 to += thislen;
132 from += thislen;
133 len -= thislen;
134 }
135}
136
137static void elan_104nc_write16(struct map_info *map, map_word d, unsigned long adr)
138{
139 spin_lock(&elan_104nc_spin);
140 elan_104nc_page(map, adr);
141 writew(d.x[0], iomapadr + (adr & WINDOW_MASK));
142 spin_unlock(&elan_104nc_spin);
143}
144
145static void elan_104nc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
146{
147 while(len) {
148 unsigned long thislen = len;
149 if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
150 thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
151
152 spin_lock(&elan_104nc_spin);
153 elan_104nc_page(map, to);
154 memcpy_toio(iomapadr + (to & WINDOW_MASK), from, thislen);
155 spin_unlock(&elan_104nc_spin);
156 to += thislen;
157 from += thislen;
158 len -= thislen;
159 }
160}
161
162static struct map_info elan_104nc_map = {
163 .name = "ELAN-104NC flash",
164 .phys = NO_XIP,
165 .size = 8*1024*1024, /* this must be set to a maximum possible amount
166 of flash so the cfi probe routines find all
167 the chips */
168 .bankwidth = 2,
169 .read = elan_104nc_read16,
170 .copy_from = elan_104nc_copy_from,
171 .write = elan_104nc_write16,
172 .copy_to = elan_104nc_copy_to
173};
174
175/* MTD device for all of the flash. */
176static struct mtd_info *all_mtd;
177
178static void cleanup_elan_104nc(void)
179{
180 if( all_mtd ) {
181 del_mtd_partitions( all_mtd );
182 map_destroy( all_mtd );
183 }
184
185 iounmap(iomapadr);
186}
187
188static int __init init_elan_104nc(void)
189{
190 /* Urg! We use I/O port 0x22 without request_region()ing it,
191 because it's already allocated to the PIC. */
192
193 iomapadr = ioremap(WINDOW_START, WINDOW_LENGTH);
194 if (!iomapadr) {
195 printk( KERN_ERR"%s: failed to ioremap memory region\n",
196 elan_104nc_map.name );
197 return -EIO;
198 }
199
200 printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
201 elan_104nc_map.name,
202 PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1,
203 WINDOW_START, WINDOW_START+WINDOW_LENGTH-1 );
204
205 elan_104nc_setup();
206
207 /* Probe for chip. */
208 all_mtd = do_map_probe("cfi_probe", &elan_104nc_map );
209 if( !all_mtd ) {
210 cleanup_elan_104nc();
211 return -ENXIO;
212 }
213
214 all_mtd->owner = THIS_MODULE;
215
216 /* Create MTD devices for each partition. */
217 add_mtd_partitions( all_mtd, partition_info, NUM_PARTITIONS );
218
219 return 0;
220}
221
222module_init(init_elan_104nc);
223module_exit(cleanup_elan_104nc);
224
225
226MODULE_LICENSE("GPL");
227MODULE_AUTHOR("Arcom Control Systems Ltd.");
228MODULE_DESCRIPTION("MTD map driver for Arcom Control Systems ELAN-104NC");
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c
index 29d1cc1bb426..1800ceedf380 100644
--- a/drivers/mtd/maps/ichxrom.c
+++ b/drivers/mtd/maps/ichxrom.c
@@ -2,7 +2,7 @@
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.16 2004/11/28 09:40:39 dwmw2 Exp $ 5 * $Id: ichxrom.c,v 1.17 2005/03/18 14:04:35 gleixner Exp $
6 */ 6 */
7 7
8#include <linux/module.h> 8#include <linux/module.h>
@@ -366,7 +366,7 @@ static int __init init_ichxrom(void)
366 } 366 }
367 return -ENXIO; 367 return -ENXIO;
368#if 0 368#if 0
369 return pci_module_init(&ichxrom_driver); 369 return pci_register_driver(&ichxrom_driver);
370#endif 370#endif
371} 371}
372 372
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
index c5b5f447e34b..3e94b616743d 100644
--- a/drivers/mtd/maps/ixp2000.c
+++ b/drivers/mtd/maps/ixp2000.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ixp2000.c,v 1.5 2004/11/16 17:15:48 dsaxena Exp $ 2 * $Id: ixp2000.c,v 1.6 2005/03/18 14:07:46 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/ixp2000.c 4 * drivers/mtd/maps/ixp2000.c
5 * 5 *
@@ -216,11 +216,6 @@ static int ixp2000_flash_probe(struct device *_dev)
216 goto Error; 216 goto Error;
217 } 217 }
218 218
219 /*
220 * Setup read mode for FLASH
221 */
222 *IXP2000_SLOWPORT_FRM = 1;
223
224#if defined(__ARMEB__) 219#if defined(__ARMEB__)
225 /* 220 /*
226 * Enable erratum 44 workaround for NPUs with broken slowport 221 * Enable erratum 44 workaround for NPUs with broken slowport
diff --git a/drivers/mtd/maps/mainstone-flash.c b/drivers/mtd/maps/mainstone-flash.c
new file mode 100644
index 000000000000..87e93fa60588
--- /dev/null
+++ b/drivers/mtd/maps/mainstone-flash.c
@@ -0,0 +1,178 @@
1/*
2 * $Id: $
3 *
4 * Map driver for the Mainstone developer platform.
5 *
6 * Author: Nicolas Pitre
7 * Copyright: (C) 2001 MontaVista Software Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/dma-mapping.h>
19#include <linux/mtd/mtd.h>
20#include <linux/mtd/map.h>
21#include <linux/mtd/partitions.h>
22#include <asm/io.h>
23#include <asm/hardware.h>
24#include <asm/arch/pxa-regs.h>
25#include <asm/arch/mainstone.h>
26
27
28#define ROM_ADDR 0x00000000
29#define FLASH_ADDR 0x04000000
30
31#define WINDOW_SIZE 0x04000000
32
33static void mainstone_map_inval_cache(struct map_info *map, unsigned long from,
34 ssize_t len)
35{
36 consistent_sync((char *)map->cached + from, len, DMA_FROM_DEVICE);
37}
38
39static struct map_info mainstone_maps[2] = { {
40 .size = WINDOW_SIZE,
41 .phys = PXA_CS0_PHYS,
42 .inval_cache = mainstone_map_inval_cache,
43}, {
44 .size = WINDOW_SIZE,
45 .phys = PXA_CS1_PHYS,
46 .inval_cache = mainstone_map_inval_cache,
47} };
48
49static struct mtd_partition mainstone_partitions[] = {
50 {
51 .name = "Bootloader",
52 .size = 0x00040000,
53 .offset = 0,
54 .mask_flags = MTD_WRITEABLE /* force read-only */
55 },{
56 .name = "Kernel",
57 .size = 0x00400000,
58 .offset = 0x00040000,
59 },{
60 .name = "Filesystem",
61 .size = MTDPART_SIZ_FULL,
62 .offset = 0x00440000
63 }
64};
65
66static struct mtd_info *mymtds[2];
67static struct mtd_partition *parsed_parts[2];
68static int nr_parsed_parts[2];
69
70static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
71
72static int __init init_mainstone(void)
73{
74 int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
75 int ret = 0, i;
76
77 mainstone_maps[0].bankwidth = (BOOT_DEF & 1) ? 2 : 4;
78 mainstone_maps[1].bankwidth = 4;
79
80 /* Compensate for SW7 which swaps the flash banks */
81 mainstone_maps[SW7].name = "processor flash";
82 mainstone_maps[SW7 ^ 1].name = "main board flash";
83
84 printk(KERN_NOTICE "Mainstone configured to boot from %s\n",
85 mainstone_maps[0].name);
86
87 for (i = 0; i < 2; i++) {
88 mainstone_maps[i].virt = ioremap(mainstone_maps[i].phys,
89 WINDOW_SIZE);
90 if (!mainstone_maps[i].virt) {
91 printk(KERN_WARNING "Failed to ioremap %s\n",
92 mainstone_maps[i].name);
93 if (!ret)
94 ret = -ENOMEM;
95 continue;
96 }
97 mainstone_maps[i].cached =
98 ioremap_cached(mainstone_maps[i].phys, WINDOW_SIZE);
99 if (!mainstone_maps[i].cached)
100 printk(KERN_WARNING "Failed to ioremap cached %s\n",
101 mainstone_maps[i].name);
102 simple_map_init(&mainstone_maps[i]);
103
104 printk(KERN_NOTICE
105 "Probing %s at physical address 0x%08lx"
106 " (%d-bit bankwidth)\n",
107 mainstone_maps[i].name, mainstone_maps[i].phys,
108 mainstone_maps[i].bankwidth * 8);
109
110 mymtds[i] = do_map_probe("cfi_probe", &mainstone_maps[i]);
111
112 if (!mymtds[i]) {
113 iounmap((void *)mainstone_maps[i].virt);
114 if (mainstone_maps[i].cached)
115 iounmap(mainstone_maps[i].cached);
116 if (!ret)
117 ret = -EIO;
118 continue;
119 }
120 mymtds[i]->owner = THIS_MODULE;
121
122 ret = parse_mtd_partitions(mymtds[i], probes,
123 &parsed_parts[i], 0);
124
125 if (ret > 0)
126 nr_parsed_parts[i] = ret;
127 }
128
129 if (!mymtds[0] && !mymtds[1])
130 return ret;
131
132 for (i = 0; i < 2; i++) {
133 if (!mymtds[i]) {
134 printk(KERN_WARNING "%s is absent. Skipping\n",
135 mainstone_maps[i].name);
136 } else if (nr_parsed_parts[i]) {
137 add_mtd_partitions(mymtds[i], parsed_parts[i],
138 nr_parsed_parts[i]);
139 } else if (!i) {
140 printk("Using static partitions on %s\n",
141 mainstone_maps[i].name);
142 add_mtd_partitions(mymtds[i], mainstone_partitions,
143 ARRAY_SIZE(mainstone_partitions));
144 } else {
145 printk("Registering %s as whole device\n",
146 mainstone_maps[i].name);
147 add_mtd_device(mymtds[i]);
148 }
149 }
150 return 0;
151}
152
153static void __exit cleanup_mainstone(void)
154{
155 int i;
156 for (i = 0; i < 2; i++) {
157 if (!mymtds[i])
158 continue;
159
160 if (nr_parsed_parts[i] || !i)
161 del_mtd_partitions(mymtds[i]);
162 else
163 del_mtd_device(mymtds[i]);
164
165 map_destroy(mymtds[i]);
166 iounmap((void *)mainstone_maps[i].virt);
167 if (mainstone_maps[i].cached)
168 iounmap(mainstone_maps[i].cached);
169 kfree(parsed_parts[i]);
170 }
171}
172
173module_init(init_mainstone);
174module_exit(cleanup_mainstone);
175
176MODULE_LICENSE("GPL");
177MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
178MODULE_DESCRIPTION("MTD map driver for Intel Mainstone");
diff --git a/drivers/mtd/maps/map_funcs.c b/drivers/mtd/maps/map_funcs.c
index 38f6a7af53f8..9105e6ca0aa6 100644
--- a/drivers/mtd/maps/map_funcs.c
+++ b/drivers/mtd/maps/map_funcs.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: map_funcs.c,v 1.9 2004/07/13 22:33:15 dwmw2 Exp $ 2 * $Id: map_funcs.c,v 1.10 2005/06/06 23:04:36 tpoynor Exp $
3 * 3 *
4 * Out-of-line map I/O functions for simple maps when CONFIG_COMPLEX_MAPPINGS 4 * Out-of-line map I/O functions for simple maps when CONFIG_COMPLEX_MAPPINGS
5 * is enabled. 5 * is enabled.
@@ -9,23 +9,24 @@
9#include <linux/module.h> 9#include <linux/module.h>
10 10
11#include <linux/mtd/map.h> 11#include <linux/mtd/map.h>
12#include <linux/mtd/xip.h>
12 13
13static map_word simple_map_read(struct map_info *map, unsigned long ofs) 14static map_word __xipram simple_map_read(struct map_info *map, unsigned long ofs)
14{ 15{
15 return inline_map_read(map, ofs); 16 return inline_map_read(map, ofs);
16} 17}
17 18
18static void simple_map_write(struct map_info *map, const map_word datum, unsigned long ofs) 19static void __xipram simple_map_write(struct map_info *map, const map_word datum, unsigned long ofs)
19{ 20{
20 inline_map_write(map, datum, ofs); 21 inline_map_write(map, datum, ofs);
21} 22}
22 23
23static void simple_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) 24static void __xipram simple_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
24{ 25{
25 inline_map_copy_from(map, to, from, len); 26 inline_map_copy_from(map, to, from, len);
26} 27}
27 28
28static void simple_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) 29static void __xipram simple_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
29{ 30{
30 inline_map_copy_to(map, to, from, len); 31 inline_map_copy_to(map, to, from, len);
31} 32}
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
new file mode 100644
index 000000000000..8cc71409a328
--- /dev/null
+++ b/drivers/mtd/maps/omap_nor.c
@@ -0,0 +1,179 @@
1/*
2 * Flash memory support for various TI OMAP boards
3 *
4 * Copyright (C) 2001-2002 MontaVista Software Inc.
5 * Copyright (C) 2003-2004 Texas Instruments
6 * Copyright (C) 2004 Nokia Corporation
7 *
8 * Assembled using driver code copyright the companies above
9 * and written by David Brownell, Jian Zhang <jzhang@ti.com>,
10 * Tony Lindgren <tony@atomide.com> and others.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
20 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 */
32
33#include <linux/device.h>
34#include <linux/module.h>
35#include <linux/types.h>
36#include <linux/kernel.h>
37#include <linux/init.h>
38#include <linux/ioport.h>
39#include <linux/mtd/mtd.h>
40#include <linux/mtd/map.h>
41#include <linux/mtd/partitions.h>
42
43#include <asm/io.h>
44#include <asm/hardware.h>
45#include <asm/mach-types.h>
46#include <asm/mach/flash.h>
47#include <asm/arch/tc.h>
48
49#ifdef CONFIG_MTD_PARTITIONS
50static const char *part_probes[] = { /* "RedBoot", */ "cmdlinepart", NULL };
51#endif
52
53struct omapflash_info {
54 struct mtd_partition *parts;
55 struct mtd_info *mtd;
56 struct map_info map;
57};
58
59static void omap_set_vpp(struct map_info *map, int enable)
60{
61 static int count;
62
63 if (enable) {
64 if (count++ == 0)
65 OMAP_EMIFS_CONFIG_REG |= OMAP_EMIFS_CONFIG_WP;
66 } else {
67 if (count && (--count == 0))
68 OMAP_EMIFS_CONFIG_REG &= ~OMAP_EMIFS_CONFIG_WP;
69 }
70}
71
72static int __devinit omapflash_probe(struct device *dev)
73{
74 int err;
75 struct omapflash_info *info;
76 struct platform_device *pdev = to_platform_device(dev);
77 struct flash_platform_data *pdata = pdev->dev.platform_data;
78 struct resource *res = pdev->resource;
79 unsigned long size = res->end - res->start + 1;
80
81 info = kmalloc(sizeof(struct omapflash_info), GFP_KERNEL);
82 if (!info)
83 return -ENOMEM;
84
85 memset(info, 0, sizeof(struct omapflash_info));
86
87 if (!request_mem_region(res->start, size, "flash")) {
88 err = -EBUSY;
89 goto out_free_info;
90 }
91
92 info->map.virt = ioremap(res->start, size);
93 if (!info->map.virt) {
94 err = -ENOMEM;
95 goto out_release_mem_region;
96 }
97 info->map.name = pdev->dev.bus_id;
98 info->map.phys = res->start;
99 info->map.size = size;
100 info->map.bankwidth = pdata->width;
101 info->map.set_vpp = omap_set_vpp;
102
103 simple_map_init(&info->map);
104 info->mtd = do_map_probe(pdata->map_name, &info->map);
105 if (!info->mtd) {
106 err = -EIO;
107 goto out_iounmap;
108 }
109 info->mtd->owner = THIS_MODULE;
110
111#ifdef CONFIG_MTD_PARTITIONS
112 err = parse_mtd_partitions(info->mtd, part_probes, &info->parts, 0);
113 if (err > 0)
114 add_mtd_partitions(info->mtd, info->parts, err);
115 else if (err < 0 && pdata->parts)
116 add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts);
117 else
118#endif
119 add_mtd_device(info->mtd);
120
121 dev_set_drvdata(&pdev->dev, info);
122
123 return 0;
124
125out_iounmap:
126 iounmap(info->map.virt);
127out_release_mem_region:
128 release_mem_region(res->start, size);
129out_free_info:
130 kfree(info);
131
132 return err;
133}
134
135static int __devexit omapflash_remove(struct device *dev)
136{
137 struct platform_device *pdev = to_platform_device(dev);
138 struct omapflash_info *info = dev_get_drvdata(&pdev->dev);
139
140 dev_set_drvdata(&pdev->dev, NULL);
141
142 if (info) {
143 if (info->parts) {
144 del_mtd_partitions(info->mtd);
145 kfree(info->parts);
146 } else
147 del_mtd_device(info->mtd);
148 map_destroy(info->mtd);
149 release_mem_region(info->map.phys, info->map.size);
150 iounmap((void __iomem *) info->map.virt);
151 kfree(info);
152 }
153
154 return 0;
155}
156
157static struct device_driver omapflash_driver = {
158 .name = "omapflash",
159 .bus = &platform_bus_type,
160 .probe = omapflash_probe,
161 .remove = __devexit_p(omapflash_remove),
162};
163
164static int __init omapflash_init(void)
165{
166 return driver_register(&omapflash_driver);
167}
168
169static void __exit omapflash_exit(void)
170{
171 driver_unregister(&omapflash_driver);
172}
173
174module_init(omapflash_init);
175module_exit(omapflash_exit);
176
177MODULE_LICENSE("GPL");
178MODULE_DESCRIPTION("MTD NOR map driver for TI OMAP boards");
179
diff --git a/drivers/mtd/maps/pb1550-flash.c b/drivers/mtd/maps/pb1550-flash.c
deleted file mode 100644
index 1424726a219e..000000000000
--- a/drivers/mtd/maps/pb1550-flash.c
+++ /dev/null
@@ -1,203 +0,0 @@
1/*
2 * Flash memory access on Alchemy Pb1550 board
3 *
4 * $Id: pb1550-flash.c,v 1.6 2004/11/04 13:24:15 gleixner Exp $
5 *
6 * (C) 2004 Embedded Edge, LLC, based on pb1550-flash.c:
7 * (C) 2003 Pete Popov <ppopov@pacbell.net>
8 *
9 */
10
11#include <linux/config.h>
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/kernel.h>
16
17#include <linux/mtd/mtd.h>
18#include <linux/mtd/map.h>
19#include <linux/mtd/partitions.h>
20
21#include <asm/io.h>
22#include <asm/au1000.h>
23#include <asm/pb1550.h>
24
25#ifdef DEBUG_RW
26#define DBG(x...) printk(x)
27#else
28#define DBG(x...)
29#endif
30
31static unsigned long window_addr;
32static unsigned long window_size;
33
34
35static struct map_info pb1550_map = {
36 .name = "Pb1550 flash",
37};
38
39static unsigned char flash_bankwidth = 4;
40
41/*
42 * Support only 64MB NOR Flash parts
43 */
44
45#ifdef PB1550_BOTH_BANKS
46/* both banks will be used. Combine the first bank and the first
47 * part of the second bank together into a single jffs/jffs2
48 * partition.
49 */
50static struct mtd_partition pb1550_partitions[] = {
51 /* assume boot[2:0]:swap is '0000' or '1000', which translates to:
52 * 1C00 0000 1FFF FFFF CE0 64MB Boot NOR Flash
53 * 1800 0000 1BFF FFFF CE0 64MB Param NOR Flash
54 */
55 {
56 .name = "User FS",
57 .size = (0x1FC00000 - 0x18000000),
58 .offset = 0x0000000
59 },{
60 .name = "yamon",
61 .size = 0x0100000,
62 .offset = MTDPART_OFS_APPEND,
63 .mask_flags = MTD_WRITEABLE
64 },{
65 .name = "raw kernel",
66 .size = (0x300000 - 0x40000), /* last 256KB is yamon env */
67 .offset = MTDPART_OFS_APPEND,
68 }
69};
70#elif defined(PB1550_BOOT_ONLY)
71static struct mtd_partition pb1550_partitions[] = {
72 /* assume boot[2:0]:swap is '0000' or '1000', which translates to:
73 * 1C00 0000 1FFF FFFF CE0 64MB Boot NOR Flash
74 */
75 {
76 .name = "User FS",
77 .size = 0x03c00000,
78 .offset = 0x0000000
79 },{
80 .name = "yamon",
81 .size = 0x0100000,
82 .offset = MTDPART_OFS_APPEND,
83 .mask_flags = MTD_WRITEABLE
84 },{
85 .name = "raw kernel",
86 .size = (0x300000-0x40000), /* last 256KB is yamon env */
87 .offset = MTDPART_OFS_APPEND,
88 }
89};
90#elif defined(PB1550_USER_ONLY)
91static struct mtd_partition pb1550_partitions[] = {
92 /* assume boot[2:0]:swap is '0000' or '1000', which translates to:
93 * 1800 0000 1BFF FFFF CE0 64MB Param NOR Flash
94 */
95 {
96 .name = "User FS",
97 .size = (0x4000000 - 0x200000), /* reserve 2MB for raw kernel */
98 .offset = 0x0000000
99 },{
100 .name = "raw kernel",
101 .size = MTDPART_SIZ_FULL,
102 .offset = MTDPART_OFS_APPEND,
103 }
104};
105#else
106#error MTD_PB1550 define combo error /* should never happen */
107#endif
108
109#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
110
111static struct mtd_info *mymtd;
112
113/*
114 * Probe the flash density and setup window address and size
115 * based on user CONFIG options. There are times when we don't
116 * want the MTD driver to be probing the boot or user flash,
117 * so having the option to enable only one bank is important.
118 */
119int setup_flash_params(void)
120{
121 u16 boot_swapboot;
122 boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) |
123 ((bcsr->status >> 6) & 0x1);
124 printk("Pb1550 MTD: boot:swap %d\n", boot_swapboot);
125
126 switch (boot_swapboot) {
127 case 0: /* 512Mbit devices, both enabled */
128 case 1:
129 case 8:
130 case 9:
131#if defined(PB1550_BOTH_BANKS)
132 window_addr = 0x18000000;
133 window_size = 0x8000000;
134#elif defined(PB1550_BOOT_ONLY)
135 window_addr = 0x1C000000;
136 window_size = 0x4000000;
137#else /* USER ONLY */
138 window_addr = 0x1E000000;
139 window_size = 0x4000000;
140#endif
141 break;
142 case 0xC:
143 case 0xD:
144 case 0xE:
145 case 0xF:
146 /* 64 MB Boot NOR Flash is disabled */
147 /* and the start address is moved to 0x0C00000 */
148 window_addr = 0x0C000000;
149 window_size = 0x4000000;
150 default:
151 printk("Pb1550 MTD: unsupported boot:swap setting\n");
152 return 1;
153 }
154 return 0;
155}
156
157int __init pb1550_mtd_init(void)
158{
159 struct mtd_partition *parts;
160 int nb_parts = 0;
161
162 /* Default flash bankwidth */
163 pb1550_map.bankwidth = flash_bankwidth;
164
165 if (setup_flash_params())
166 return -ENXIO;
167
168 /*
169 * Static partition definition selection
170 */
171 parts = pb1550_partitions;
172 nb_parts = NB_OF(pb1550_partitions);
173 pb1550_map.size = window_size;
174
175 /*
176 * Now let's probe for the actual flash. Do it here since
177 * specific machine settings might have been set above.
178 */
179 printk(KERN_NOTICE "Pb1550 flash: probing %d-bit flash bus\n",
180 pb1550_map.bankwidth*8);
181 pb1550_map.virt = ioremap(window_addr, window_size);
182 mymtd = do_map_probe("cfi_probe", &pb1550_map);
183 if (!mymtd) return -ENXIO;
184 mymtd->owner = THIS_MODULE;
185
186 add_mtd_partitions(mymtd, parts, nb_parts);
187 return 0;
188}
189
190static void __exit pb1550_mtd_cleanup(void)
191{
192 if (mymtd) {
193 del_mtd_partitions(mymtd);
194 map_destroy(mymtd);
195 }
196}
197
198module_init(pb1550_mtd_init);
199module_exit(pb1550_mtd_cleanup);
200
201MODULE_AUTHOR("Embedded Edge, LLC");
202MODULE_DESCRIPTION("Pb1550 mtd map driver");
203MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/pb1xxx-flash.c b/drivers/mtd/maps/pb1xxx-flash.c
deleted file mode 100644
index 06e731540552..000000000000
--- a/drivers/mtd/maps/pb1xxx-flash.c
+++ /dev/null
@@ -1,178 +0,0 @@
1/*
2 * Flash memory access on Alchemy Pb1xxx boards
3 *
4 * (C) 2001 Pete Popov <ppopov@mvista.com>
5 *
6 * $Id: pb1xxx-flash.c,v 1.14 2004/11/04 13:24:15 gleixner Exp $
7 */
8
9#include <linux/config.h>
10#include <linux/module.h>
11#include <linux/types.h>
12#include <linux/init.h>
13#include <linux/kernel.h>
14
15#include <linux/mtd/mtd.h>
16#include <linux/mtd/map.h>
17#include <linux/mtd/partitions.h>
18
19#include <asm/io.h>
20
21#ifdef DEBUG_RW
22#define DBG(x...) printk(x)
23#else
24#define DBG(x...)
25#endif
26
27#ifdef CONFIG_MIPS_PB1000
28
29#define WINDOW_ADDR 0x1F800000
30#define WINDOW_SIZE 0x800000
31
32static struct mtd_partition pb1xxx_partitions[] = {
33 {
34 .name = "yamon env",
35 .size = 0x00020000,
36 .offset = 0,
37 .mask_flags = MTD_WRITEABLE},
38 {
39 .name = "User FS",
40 .size = 0x003e0000,
41 .offset = 0x20000,},
42 {
43 .name = "boot code",
44 .size = 0x100000,
45 .offset = 0x400000,
46 .mask_flags = MTD_WRITEABLE},
47 {
48 .name = "raw/kernel",
49 .size = 0x300000,
50 .offset = 0x500000}
51};
52
53#elif defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100)
54
55#if defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER)
56/* both 32MB banks will be used. Combine the first 32MB bank and the
57 * first 28MB of the second bank together into a single jffs/jffs2
58 * partition.
59 */
60#define WINDOW_ADDR 0x1C000000
61#define WINDOW_SIZE 0x4000000
62static struct mtd_partition pb1xxx_partitions[] = {
63 {
64 .name = "User FS",
65 .size = 0x3c00000,
66 .offset = 0x0000000
67 },{
68 .name = "yamon",
69 .size = 0x0100000,
70 .offset = 0x3c00000,
71 .mask_flags = MTD_WRITEABLE
72 },{
73 .name = "raw kernel",
74 .size = 0x02c0000,
75 .offset = 0x3d00000
76 }
77};
78#elif defined(CONFIG_MTD_PB1500_BOOT) && !defined(CONFIG_MTD_PB1500_USER)
79#define WINDOW_ADDR 0x1E000000
80#define WINDOW_SIZE 0x2000000
81static struct mtd_partition pb1xxx_partitions[] = {
82 {
83 .name = "User FS",
84 .size = 0x1c00000,
85 .offset = 0x0000000
86 },{
87 .name = "yamon",
88 .size = 0x0100000,
89 .offset = 0x1c00000,
90 .mask_flags = MTD_WRITEABLE
91 },{
92 .name = "raw kernel",
93 .size = 0x02c0000,
94 .offset = 0x1d00000
95 }
96};
97#elif !defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER)
98#define WINDOW_ADDR 0x1C000000
99#define WINDOW_SIZE 0x2000000
100static struct mtd_partition pb1xxx_partitions[] = {
101 {
102 .name = "User FS",
103 .size = 0x1e00000,
104 .offset = 0x0000000
105 },{
106 .name = "raw kernel",
107 .size = 0x0200000,
108 .offset = 0x1e00000,
109 }
110};
111#else
112#error MTD_PB1500 define combo error /* should never happen */
113#endif
114#else
115#error Unsupported board
116#endif
117
118#define NAME "Pb1x00 Linux Flash"
119#define PADDR WINDOW_ADDR
120#define BUSWIDTH 4
121#define SIZE WINDOW_SIZE
122#define PARTITIONS 4
123
124static struct map_info pb1xxx_mtd_map = {
125 .name = NAME,
126 .size = SIZE,
127 .bankwidth = BUSWIDTH,
128 .phys = PADDR,
129};
130
131static struct mtd_info *pb1xxx_mtd;
132
133int __init pb1xxx_mtd_init(void)
134{
135 struct mtd_partition *parts;
136 int nb_parts = 0;
137 char *part_type;
138
139 /*
140 * Static partition definition selection
141 */
142 part_type = "static";
143 parts = pb1xxx_partitions;
144 nb_parts = ARRAY_SIZE(pb1xxx_partitions);
145
146 /*
147 * Now let's probe for the actual flash. Do it here since
148 * specific machine settings might have been set above.
149 */
150 printk(KERN_NOTICE "Pb1xxx flash: probing %d-bit flash bus\n",
151 BUSWIDTH*8);
152 pb1xxx_mtd_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
153
154 simple_map_init(&pb1xxx_mtd_map);
155
156 pb1xxx_mtd = do_map_probe("cfi_probe", &pb1xxx_mtd_map);
157 if (!pb1xxx_mtd) return -ENXIO;
158 pb1xxx_mtd->owner = THIS_MODULE;
159
160 add_mtd_partitions(pb1xxx_mtd, parts, nb_parts);
161 return 0;
162}
163
164static void __exit pb1xxx_mtd_cleanup(void)
165{
166 if (pb1xxx_mtd) {
167 del_mtd_partitions(pb1xxx_mtd);
168 map_destroy(pb1xxx_mtd);
169 iounmap((void *) pb1xxx_mtd_map.virt);
170 }
171}
172
173module_init(pb1xxx_mtd_init);
174module_exit(pb1xxx_mtd_cleanup);
175
176MODULE_AUTHOR("Pete Popov");
177MODULE_DESCRIPTION("Pb1xxx CFI map driver");
178MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
index 08b60bdc5381..18dbd3af1eaa 100644
--- a/drivers/mtd/maps/pci.c
+++ b/drivers/mtd/maps/pci.c
@@ -7,7 +7,7 @@
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.9 2004/11/28 09:40:40 dwmw2 Exp $ 10 * $Id: pci.c,v 1.10 2005/03/18 14:04:35 gleixner Exp $
11 * 11 *
12 * Generic PCI memory map driver. We support the following boards: 12 * Generic PCI memory map driver. We support the following boards:
13 * - Intel IQ80310 ATU. 13 * - Intel IQ80310 ATU.
@@ -370,7 +370,7 @@ static struct pci_driver mtd_pci_driver = {
370 370
371static int __init mtd_pci_maps_init(void) 371static int __init mtd_pci_maps_init(void)
372{ 372{
373 return pci_module_init(&mtd_pci_driver); 373 return pci_register_driver(&mtd_pci_driver);
374} 374}
375 375
376static void __exit mtd_pci_maps_exit(void) 376static void __exit mtd_pci_maps_exit(void)
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
new file mode 100644
index 000000000000..118b04544cad
--- /dev/null
+++ b/drivers/mtd/maps/plat-ram.c
@@ -0,0 +1,278 @@
1/* drivers/mtd/maps/plat-ram.c
2 *
3 * (c) 2004-2005 Simtec Electronics
4 * http://www.simtec.co.uk/products/SWLINUX/
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * Generic platfrom device based RAM map
8 *
9 * $Id: plat-ram.c,v 1.3 2005/03/19 22:41:27 gleixner Exp $
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24*/
25
26#include <linux/module.h>
27#include <linux/types.h>
28#include <linux/init.h>
29#include <linux/kernel.h>
30#include <linux/string.h>
31#include <linux/ioport.h>
32#include <linux/device.h>
33
34#include <linux/mtd/mtd.h>
35#include <linux/mtd/map.h>
36#include <linux/mtd/partitions.h>
37#include <linux/mtd/plat-ram.h>
38
39#include <asm/io.h>
40
41/* private structure for each mtd platform ram device created */
42
43struct platram_info {
44 struct device *dev;
45 struct mtd_info *mtd;
46 struct map_info map;
47 struct mtd_partition *partitions;
48 struct resource *area;
49 struct platdata_mtd_ram *pdata;
50};
51
52/* to_platram_info()
53 *
54 * device private data to struct platram_info conversion
55*/
56
57static inline struct platram_info *to_platram_info(struct device *dev)
58{
59 return (struct platram_info *)dev_get_drvdata(dev);
60}
61
62/* platram_setrw
63 *
64 * call the platform device's set rw/ro control
65 *
66 * to = 0 => read-only
67 * = 1 => read-write
68*/
69
70static inline void platram_setrw(struct platram_info *info, int to)
71{
72 if (info->pdata == NULL)
73 return;
74
75 if (info->pdata->set_rw != NULL)
76 (info->pdata->set_rw)(info->dev, to);
77}
78
79/* platram_remove
80 *
81 * called to remove the device from the driver's control
82*/
83
84static int platram_remove(struct device *dev)
85{
86 struct platram_info *info = to_platram_info(dev);
87
88 dev_set_drvdata(dev, NULL);
89
90 dev_dbg(dev, "removing device\n");
91
92 if (info == NULL)
93 return 0;
94
95 if (info->mtd) {
96#ifdef CONFIG_MTD_PARTITIONS
97 if (info->partitions) {
98 del_mtd_partitions(info->mtd);
99 kfree(info->partitions);
100 }
101#endif
102 del_mtd_device(info->mtd);
103 map_destroy(info->mtd);
104 }
105
106 /* ensure ram is left read-only */
107
108 platram_setrw(info, PLATRAM_RO);
109
110 /* release resources */
111
112 if (info->area) {
113 release_resource(info->area);
114 kfree(info->area);
115 }
116
117 if (info->map.virt != NULL)
118 iounmap(info->map.virt);
119
120 kfree(info);
121
122 return 0;
123}
124
125/* platram_probe
126 *
127 * called from device drive system when a device matching our
128 * driver is found.
129*/
130
131static int platram_probe(struct device *dev)
132{
133 struct platform_device *pd = to_platform_device(dev);
134 struct platdata_mtd_ram *pdata;
135 struct platram_info *info;
136 struct resource *res;
137 int err = 0;
138
139 dev_dbg(dev, "probe entered\n");
140
141 if (dev->platform_data == NULL) {
142 dev_err(dev, "no platform data supplied\n");
143 err = -ENOENT;
144 goto exit_error;
145 }
146
147 pdata = dev->platform_data;
148
149 info = kmalloc(sizeof(*info), GFP_KERNEL);
150 if (info == NULL) {
151 dev_err(dev, "no memory for flash info\n");
152 err = -ENOMEM;
153 goto exit_error;
154 }
155
156 memset(info, 0, sizeof(*info));
157 dev_set_drvdata(dev, info);
158
159 info->dev = dev;
160 info->pdata = pdata;
161
162 /* get the resource for the memory mapping */
163
164 res = platform_get_resource(pd, IORESOURCE_MEM, 0);
165
166 if (res == NULL) {
167 dev_err(dev, "no memory resource specified\n");
168 err = -ENOENT;
169 goto exit_free;
170 }
171
172 dev_dbg(dev, "got platform resource %p (0x%lx)\n", res, res->start);
173
174 /* setup map parameters */
175
176 info->map.phys = res->start;
177 info->map.size = (res->end - res->start) + 1;
178 info->map.name = pdata->mapname != NULL ? pdata->mapname : pd->name;
179 info->map.bankwidth = pdata->bankwidth;
180
181 /* register our usage of the memory area */
182
183 info->area = request_mem_region(res->start, info->map.size, pd->name);
184 if (info->area == NULL) {
185 dev_err(dev, "failed to request memory region\n");
186 err = -EIO;
187 goto exit_free;
188 }
189
190 /* remap the memory area */
191
192 info->map.virt = ioremap(res->start, info->map.size);
193 dev_dbg(dev, "virt %p, %lu bytes\n", info->map.virt, info->map.size);
194
195 if (info->map.virt == NULL) {
196 dev_err(dev, "failed to ioremap() region\n");
197 err = -EIO;
198 goto exit_free;
199 }
200
201 simple_map_init(&info->map);
202
203 dev_dbg(dev, "initialised map, probing for mtd\n");
204
205 /* probe for the right mtd map driver */
206
207 info->mtd = do_map_probe("map_ram" , &info->map);
208 if (info->mtd == NULL) {
209 dev_err(dev, "failed to probe for map_ram\n");
210 err = -ENOMEM;
211 goto exit_free;
212 }
213
214 info->mtd->owner = THIS_MODULE;
215
216 platram_setrw(info, PLATRAM_RW);
217
218 /* check to see if there are any available partitions, or wether
219 * to add this device whole */
220
221#ifdef CONFIG_MTD_PARTITIONS
222 if (pdata->nr_partitions > 0) {
223 const char **probes = { NULL };
224
225 if (pdata->probes)
226 probes = (const char **)pdata->probes;
227
228 err = parse_mtd_partitions(info->mtd, probes,
229 &info->partitions, 0);
230 if (err > 0) {
231 err = add_mtd_partitions(info->mtd, info->partitions,
232 err);
233 }
234 }
235#endif /* CONFIG_MTD_PARTITIONS */
236
237 if (add_mtd_device(info->mtd)) {
238 dev_err(dev, "add_mtd_device() failed\n");
239 err = -ENOMEM;
240 }
241
242 dev_info(dev, "registered mtd device\n");
243 return err;
244
245 exit_free:
246 platram_remove(dev);
247 exit_error:
248 return err;
249}
250
251/* device driver info */
252
253static struct device_driver platram_driver = {
254 .name = "mtd-ram",
255 .bus = &platform_bus_type,
256 .probe = platram_probe,
257 .remove = platram_remove,
258};
259
260/* module init/exit */
261
262static int __init platram_init(void)
263{
264 printk("Generic platform RAM MTD, (c) 2004 Simtec Electronics\n");
265 return driver_register(&platram_driver);
266}
267
268static void __exit platram_exit(void)
269{
270 driver_unregister(&platram_driver);
271}
272
273module_init(platram_init);
274module_exit(platram_exit);
275
276MODULE_LICENSE("GPL");
277MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
278MODULE_DESCRIPTION("MTD platform RAM map driver");
diff --git a/drivers/mtd/maps/scb2_flash.c b/drivers/mtd/maps/scb2_flash.c
index 5bb3b600e5d0..97a8dfd69258 100644
--- a/drivers/mtd/maps/scb2_flash.c
+++ b/drivers/mtd/maps/scb2_flash.c
@@ -1,6 +1,6 @@
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.11 2004/11/28 09:40:40 dwmw2 Exp $ 3 * $Id: scb2_flash.c,v 1.12 2005/03/18 14:04:35 gleixner Exp $
4 * Copyright (C) 2002 Sun Microsystems, Inc. 4 * Copyright (C) 2002 Sun Microsystems, Inc.
5 * Tim Hockin <thockin@sun.com> 5 * Tim Hockin <thockin@sun.com>
6 * 6 *
@@ -238,7 +238,7 @@ static struct pci_driver scb2_flash_driver = {
238static int __init 238static int __init
239scb2_flash_init(void) 239scb2_flash_init(void)
240{ 240{
241 return pci_module_init(&scb2_flash_driver); 241 return pci_register_driver(&scb2_flash_driver);
242} 242}
243 243
244static void __exit 244static void __exit
diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c
index b3b39cb7c608..d15da6fd84c1 100644
--- a/drivers/mtd/maps/sharpsl-flash.c
+++ b/drivers/mtd/maps/sharpsl-flash.c
@@ -4,7 +4,7 @@
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.2 2004/11/24 20:38:06 rpurdie Exp $ 7 * $Id: sharpsl-flash.c,v 1.5 2005/03/21 08:42:11 rpurdie Exp $
8 * 8 *
9 * based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp 9 * 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 10 * Handle mapping of the flash on the RPX Lite and CLLF boards
@@ -24,13 +24,14 @@
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/types.h> 25#include <linux/types.h>
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <asm/io.h>
28#include <linux/mtd/mtd.h> 27#include <linux/mtd/mtd.h>
29#include <linux/mtd/map.h> 28#include <linux/mtd/map.h>
30#include <linux/mtd/partitions.h> 29#include <linux/mtd/partitions.h>
30#include <asm/io.h>
31#include <asm/mach-types.h>
31 32
32#define WINDOW_ADDR 0x00000000 33#define WINDOW_ADDR 0x00000000
33#define WINDOW_SIZE 0x01000000 34#define WINDOW_SIZE 0x00800000
34#define BANK_WIDTH 2 35#define BANK_WIDTH 2
35 36
36static struct mtd_info *mymtd; 37static struct mtd_info *mymtd;
@@ -44,9 +45,7 @@ struct map_info sharpsl_map = {
44 45
45static struct mtd_partition sharpsl_partitions[1] = { 46static struct mtd_partition sharpsl_partitions[1] = {
46 { 47 {
47 name: "Filesystem", 48 name: "Boot PROM Filesystem",
48 size: 0x006d0000,
49 offset: 0x00120000
50 } 49 }
51}; 50};
52 51
@@ -58,12 +57,16 @@ int __init init_sharpsl(void)
58 int nb_parts = 0; 57 int nb_parts = 0;
59 char *part_type = "static"; 58 char *part_type = "static";
60 59
61 printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR); 60 printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n",
61 WINDOW_SIZE, WINDOW_ADDR);
62 sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); 62 sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
63 if (!sharpsl_map.virt) { 63 if (!sharpsl_map.virt) {
64 printk("Failed to ioremap\n"); 64 printk("Failed to ioremap\n");
65 return -EIO; 65 return -EIO;
66 } 66 }
67
68 simple_map_init(&sharpsl_map);
69
67 mymtd = do_map_probe("map_rom", &sharpsl_map); 70 mymtd = do_map_probe("map_rom", &sharpsl_map);
68 if (!mymtd) { 71 if (!mymtd) {
69 iounmap(sharpsl_map.virt); 72 iounmap(sharpsl_map.virt);
@@ -72,6 +75,22 @@ int __init init_sharpsl(void)
72 75
73 mymtd->owner = THIS_MODULE; 76 mymtd->owner = THIS_MODULE;
74 77
78 if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky()
79 || machine_is_poodle()) {
80 sharpsl_partitions[0].size=0x006d0000;
81 sharpsl_partitions[0].offset=0x00120000;
82 } else if (machine_is_tosa()) {
83 sharpsl_partitions[0].size=0x006a0000;
84 sharpsl_partitions[0].offset=0x00160000;
85 } else if (machine_is_spitz()) {
86 sharpsl_partitions[0].size=0x006b0000;
87 sharpsl_partitions[0].offset=0x00140000;
88 } else {
89 map_destroy(mymtd);
90 iounmap(sharpsl_map.virt);
91 return -ENODEV;
92 }
93
75 parts = sharpsl_partitions; 94 parts = sharpsl_partitions;
76 nb_parts = NB_OF(sharpsl_partitions); 95 nb_parts = NB_OF(sharpsl_partitions);
77 96
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 510ad78312cc..1ed602a0f24c 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: mtdchar.c,v 1.66 2005/01/05 18:05:11 dwmw2 Exp $ 2 * $Id: mtdchar.c,v 1.73 2005/07/04 17:36:41 gleixner Exp $
3 * 3 *
4 * Character-device access to raw MTD devices. 4 * Character-device access to raw MTD devices.
5 * 5 *
@@ -15,27 +15,30 @@
15#include <linux/fs.h> 15#include <linux/fs.h>
16#include <asm/uaccess.h> 16#include <asm/uaccess.h>
17 17
18#ifdef CONFIG_DEVFS_FS 18#include <linux/device.h>
19#include <linux/devfs_fs_kernel.h> 19
20static struct class *mtd_class;
20 21
21static void mtd_notify_add(struct mtd_info* mtd) 22static void mtd_notify_add(struct mtd_info* mtd)
22{ 23{
23 if (!mtd) 24 if (!mtd)
24 return; 25 return;
25 26
26 devfs_mk_cdev(MKDEV(MTD_CHAR_MAJOR, mtd->index*2), 27 class_device_create(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
27 S_IFCHR | S_IRUGO | S_IWUGO, "mtd/%d", mtd->index); 28 NULL, "mtd%d", mtd->index);
28 29
29 devfs_mk_cdev(MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), 30 class_device_create(mtd_class,
30 S_IFCHR | S_IRUGO, "mtd/%dro", mtd->index); 31 MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
32 NULL, "mtd%dro", mtd->index);
31} 33}
32 34
33static void mtd_notify_remove(struct mtd_info* mtd) 35static void mtd_notify_remove(struct mtd_info* mtd)
34{ 36{
35 if (!mtd) 37 if (!mtd)
36 return; 38 return;
37 devfs_remove("mtd/%d", mtd->index); 39
38 devfs_remove("mtd/%dro", mtd->index); 40 class_device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2));
41 class_device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1));
39} 42}
40 43
41static struct mtd_notifier notifier = { 44static struct mtd_notifier notifier = {
@@ -43,25 +46,25 @@ static struct mtd_notifier notifier = {
43 .remove = mtd_notify_remove, 46 .remove = mtd_notify_remove,
44}; 47};
45 48
46static inline void mtdchar_devfs_init(void) 49/*
47{ 50 * We use file->private_data to store a pointer to the MTDdevice.
48 devfs_mk_dir("mtd"); 51 * Since alighment is at least 32 bits, we have 2 bits free for OTP
49 register_mtd_user(&notifier); 52 * modes as well.
50} 53 */
51 54
52static inline void mtdchar_devfs_exit(void) 55#define TO_MTD(file) (struct mtd_info *)((long)((file)->private_data) & ~3L)
53{ 56
54 unregister_mtd_user(&notifier); 57#define MTD_MODE_OTP_FACT 1
55 devfs_remove("mtd"); 58#define MTD_MODE_OTP_USER 2
56} 59#define MTD_MODE(file) ((long)((file)->private_data) & 3)
57#else /* !DEVFS */ 60
58#define mtdchar_devfs_init() do { } while(0) 61#define SET_MTD_MODE(file, mode) \
59#define mtdchar_devfs_exit() do { } while(0) 62 do { long __p = (long)((file)->private_data); \
60#endif 63 (file)->private_data = (void *)((__p & ~3L) | mode); } while (0)
61 64
62static loff_t mtd_lseek (struct file *file, loff_t offset, int orig) 65static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
63{ 66{
64 struct mtd_info *mtd = file->private_data; 67 struct mtd_info *mtd = TO_MTD(file);
65 68
66 switch (orig) { 69 switch (orig) {
67 case 0: 70 case 0:
@@ -134,7 +137,7 @@ static int mtd_close(struct inode *inode, struct file *file)
134 137
135 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n"); 138 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
136 139
137 mtd = file->private_data; 140 mtd = TO_MTD(file);
138 141
139 if (mtd->sync) 142 if (mtd->sync)
140 mtd->sync(mtd); 143 mtd->sync(mtd);
@@ -151,7 +154,7 @@ static int mtd_close(struct inode *inode, struct file *file)
151 154
152static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos) 155static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos)
153{ 156{
154 struct mtd_info *mtd = file->private_data; 157 struct mtd_info *mtd = TO_MTD(file);
155 size_t retlen=0; 158 size_t retlen=0;
156 size_t total_retlen=0; 159 size_t total_retlen=0;
157 int ret=0; 160 int ret=0;
@@ -178,7 +181,16 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
178 if (!kbuf) 181 if (!kbuf)
179 return -ENOMEM; 182 return -ENOMEM;
180 183
181 ret = MTD_READ(mtd, *ppos, len, &retlen, kbuf); 184 switch (MTD_MODE(file)) {
185 case MTD_MODE_OTP_FACT:
186 ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf);
187 break;
188 case MTD_MODE_OTP_USER:
189 ret = mtd->read_user_prot_reg(mtd, *ppos, len, &retlen, kbuf);
190 break;
191 default:
192 ret = MTD_READ(mtd, *ppos, len, &retlen, kbuf);
193 }
182 /* Nand returns -EBADMSG on ecc errors, but it returns 194 /* Nand returns -EBADMSG on ecc errors, but it returns
183 * the data. For our userspace tools it is important 195 * the data. For our userspace tools it is important
184 * to dump areas with ecc errors ! 196 * to dump areas with ecc errors !
@@ -196,6 +208,8 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
196 208
197 count -= retlen; 209 count -= retlen;
198 buf += retlen; 210 buf += retlen;
211 if (retlen == 0)
212 count = 0;
199 } 213 }
200 else { 214 else {
201 kfree(kbuf); 215 kfree(kbuf);
@@ -210,7 +224,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
210 224
211static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count,loff_t *ppos) 225static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count,loff_t *ppos)
212{ 226{
213 struct mtd_info *mtd = file->private_data; 227 struct mtd_info *mtd = TO_MTD(file);
214 char *kbuf; 228 char *kbuf;
215 size_t retlen; 229 size_t retlen;
216 size_t total_retlen=0; 230 size_t total_retlen=0;
@@ -245,7 +259,20 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
245 return -EFAULT; 259 return -EFAULT;
246 } 260 }
247 261
248 ret = (*(mtd->write))(mtd, *ppos, len, &retlen, kbuf); 262 switch (MTD_MODE(file)) {
263 case MTD_MODE_OTP_FACT:
264 ret = -EROFS;
265 break;
266 case MTD_MODE_OTP_USER:
267 if (!mtd->write_user_prot_reg) {
268 ret = -EOPNOTSUPP;
269 break;
270 }
271 ret = mtd->write_user_prot_reg(mtd, *ppos, len, &retlen, kbuf);
272 break;
273 default:
274 ret = (*(mtd->write))(mtd, *ppos, len, &retlen, kbuf);
275 }
249 if (!ret) { 276 if (!ret) {
250 *ppos += retlen; 277 *ppos += retlen;
251 total_retlen += retlen; 278 total_retlen += retlen;
@@ -276,7 +303,7 @@ static void mtdchar_erase_callback (struct erase_info *instr)
276static int mtd_ioctl(struct inode *inode, struct file *file, 303static int mtd_ioctl(struct inode *inode, struct file *file,
277 u_int cmd, u_long arg) 304 u_int cmd, u_long arg)
278{ 305{
279 struct mtd_info *mtd = file->private_data; 306 struct mtd_info *mtd = TO_MTD(file);
280 void __user *argp = (void __user *)arg; 307 void __user *argp = (void __user *)arg;
281 int ret = 0; 308 int ret = 0;
282 u_long size; 309 u_long size;
@@ -518,6 +545,80 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
518 break; 545 break;
519 } 546 }
520 547
548#ifdef CONFIG_MTD_OTP
549 case OTPSELECT:
550 {
551 int mode;
552 if (copy_from_user(&mode, argp, sizeof(int)))
553 return -EFAULT;
554 SET_MTD_MODE(file, 0);
555 switch (mode) {
556 case MTD_OTP_FACTORY:
557 if (!mtd->read_fact_prot_reg)
558 ret = -EOPNOTSUPP;
559 else
560 SET_MTD_MODE(file, MTD_MODE_OTP_FACT);
561 break;
562 case MTD_OTP_USER:
563 if (!mtd->read_fact_prot_reg)
564 ret = -EOPNOTSUPP;
565 else
566 SET_MTD_MODE(file, MTD_MODE_OTP_USER);
567 break;
568 default:
569 ret = -EINVAL;
570 case MTD_OTP_OFF:
571 break;
572 }
573 file->f_pos = 0;
574 break;
575 }
576
577 case OTPGETREGIONCOUNT:
578 case OTPGETREGIONINFO:
579 {
580 struct otp_info *buf = kmalloc(4096, GFP_KERNEL);
581 if (!buf)
582 return -ENOMEM;
583 ret = -EOPNOTSUPP;
584 switch (MTD_MODE(file)) {
585 case MTD_MODE_OTP_FACT:
586 if (mtd->get_fact_prot_info)
587 ret = mtd->get_fact_prot_info(mtd, buf, 4096);
588 break;
589 case MTD_MODE_OTP_USER:
590 if (mtd->get_user_prot_info)
591 ret = mtd->get_user_prot_info(mtd, buf, 4096);
592 break;
593 }
594 if (ret >= 0) {
595 if (cmd == OTPGETREGIONCOUNT) {
596 int nbr = ret / sizeof(struct otp_info);
597 ret = copy_to_user(argp, &nbr, sizeof(int));
598 } else
599 ret = copy_to_user(argp, buf, ret);
600 if (ret)
601 ret = -EFAULT;
602 }
603 kfree(buf);
604 break;
605 }
606
607 case OTPLOCK:
608 {
609 struct otp_info info;
610
611 if (MTD_MODE(file) != MTD_MODE_OTP_USER)
612 return -EINVAL;
613 if (copy_from_user(&info, argp, sizeof(info)))
614 return -EFAULT;
615 if (!mtd->lock_user_prot_reg)
616 return -EOPNOTSUPP;
617 ret = mtd->lock_user_prot_reg(mtd, info.start, info.length);
618 break;
619 }
620#endif
621
521 default: 622 default:
522 ret = -ENOTTY; 623 ret = -ENOTTY;
523 } 624 }
@@ -543,13 +644,22 @@ static int __init init_mtdchar(void)
543 return -EAGAIN; 644 return -EAGAIN;
544 } 645 }
545 646
546 mtdchar_devfs_init(); 647 mtd_class = class_create(THIS_MODULE, "mtd");
648
649 if (IS_ERR(mtd_class)) {
650 printk(KERN_ERR "Error creating mtd class.\n");
651 unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
652 return PTR_ERR(mtd_class);
653 }
654
655 register_mtd_user(&notifier);
547 return 0; 656 return 0;
548} 657}
549 658
550static void __exit cleanup_mtdchar(void) 659static void __exit cleanup_mtdchar(void)
551{ 660{
552 mtdchar_devfs_exit(); 661 unregister_mtd_user(&notifier);
662 class_destroy(mtd_class);
553 unregister_chrdev(MTD_CHAR_MAJOR, "mtd"); 663 unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
554} 664}
555 665
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 9c0315d1b1c4..dc86df18e94b 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: mtdcore.c,v 1.44 2004/11/16 18:28:59 dwmw2 Exp $ 2 * $Id: mtdcore.c,v 1.45 2005/02/18 14:34:50 dedekind Exp $
3 * 3 *
4 * Core registration and callback routines for MTD 4 * Core registration and callback routines for MTD
5 * drivers and users. 5 * drivers and users.
@@ -149,8 +149,8 @@ void register_mtd_user (struct mtd_notifier *new)
149} 149}
150 150
151/** 151/**
152 * register_mtd_user - unregister a 'user' of MTD devices. 152 * unregister_mtd_user - unregister a 'user' of MTD devices.
153 * @new: pointer to notifier info structure 153 * @old: pointer to notifier info structure
154 * 154 *
155 * Removes a callback function pair from the list of 'users' to be 155 * Removes a callback function pair from the list of 'users' to be
156 * notified upon addition or removal of MTD devices. Causes the 156 * notified upon addition or removal of MTD devices. Causes the
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 96ebb52f24b1..b92e6bfffaf2 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * This code is GPL 6 * This code is GPL
7 * 7 *
8 * $Id: mtdpart.c,v 1.51 2004/11/16 18:28:59 dwmw2 Exp $ 8 * $Id: mtdpart.c,v 1.53 2005/02/08 17:11:13 nico Exp $
9 * 9 *
10 * 02-21-2002 Thomas Gleixner <gleixner@autronix.de> 10 * 02-21-2002 Thomas Gleixner <gleixner@autronix.de>
11 * added support for read_oob, write_oob 11 * added support for read_oob, write_oob
@@ -116,6 +116,13 @@ static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t le
116 len, retlen, buf); 116 len, retlen, buf);
117} 117}
118 118
119static int part_get_user_prot_info (struct mtd_info *mtd,
120 struct otp_info *buf, size_t len)
121{
122 struct mtd_part *part = PART(mtd);
123 return part->master->get_user_prot_info (part->master, buf, len);
124}
125
119static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 126static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
120 size_t *retlen, u_char *buf) 127 size_t *retlen, u_char *buf)
121{ 128{
@@ -124,6 +131,13 @@ static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t le
124 len, retlen, buf); 131 len, retlen, buf);
125} 132}
126 133
134static int part_get_fact_prot_info (struct mtd_info *mtd,
135 struct otp_info *buf, size_t len)
136{
137 struct mtd_part *part = PART(mtd);
138 return part->master->get_fact_prot_info (part->master, buf, len);
139}
140
127static int part_write (struct mtd_info *mtd, loff_t to, size_t len, 141static int part_write (struct mtd_info *mtd, loff_t to, size_t len,
128 size_t *retlen, const u_char *buf) 142 size_t *retlen, const u_char *buf)
129{ 143{
@@ -182,6 +196,12 @@ static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t l
182 len, retlen, buf); 196 len, retlen, buf);
183} 197}
184 198
199static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len)
200{
201 struct mtd_part *part = PART(mtd);
202 return part->master->lock_user_prot_reg (part->master, from, len);
203}
204
185static int part_writev (struct mtd_info *mtd, const struct kvec *vecs, 205static int part_writev (struct mtd_info *mtd, const struct kvec *vecs,
186 unsigned long count, loff_t to, size_t *retlen) 206 unsigned long count, loff_t to, size_t *retlen)
187{ 207{
@@ -409,6 +429,12 @@ int add_mtd_partitions(struct mtd_info *master,
409 slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg; 429 slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg;
410 if(master->write_user_prot_reg) 430 if(master->write_user_prot_reg)
411 slave->mtd.write_user_prot_reg = part_write_user_prot_reg; 431 slave->mtd.write_user_prot_reg = part_write_user_prot_reg;
432 if(master->lock_user_prot_reg)
433 slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg;
434 if(master->get_user_prot_info)
435 slave->mtd.get_user_prot_info = part_get_user_prot_info;
436 if(master->get_fact_prot_info)
437 slave->mtd.get_fact_prot_info = part_get_fact_prot_info;
412 if (master->sync) 438 if (master->sync)
413 slave->mtd.sync = part_sync; 439 slave->mtd.sync = part_sync;
414 if (!i && master->suspend && master->resume) { 440 if (!i && master->suspend && master->resume) {
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index f7801eb730ce..36d34e5e5a5a 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -1,5 +1,5 @@
1# drivers/mtd/nand/Kconfig 1# drivers/mtd/nand/Kconfig
2# $Id: Kconfig,v 1.26 2005/01/05 12:42:24 dwmw2 Exp $ 2# $Id: Kconfig,v 1.31 2005/06/20 12:03:21 bjd Exp $
3 3
4menu "NAND Flash Device Drivers" 4menu "NAND Flash Device Drivers"
5 depends on MTD!=n 5 depends on MTD!=n
@@ -58,20 +58,6 @@ config MTD_NAND_TOTO
58config MTD_NAND_IDS 58config MTD_NAND_IDS
59 tristate 59 tristate
60 60
61config MTD_NAND_TX4925NDFMC
62 tristate "SmartMedia Card on Toshiba RBTX4925 reference board"
63 depends on TOSHIBA_RBTX4925 && MTD_NAND && TOSHIBA_RBTX4925_MPLEX_NAND
64 help
65 This enables the driver for the NAND flash device found on the
66 Toshiba RBTX4925 reference board, which is a SmartMediaCard.
67
68config MTD_NAND_TX4938NDFMC
69 tristate "NAND Flash device on Toshiba RBTX4938 reference board"
70 depends on TOSHIBA_RBTX4938 && MTD_NAND && TOSHIBA_RBTX4938_MPLEX_NAND
71 help
72 This enables the driver for the NAND flash device found on the
73 Toshiba RBTX4938 reference board.
74
75config MTD_NAND_AU1550 61config MTD_NAND_AU1550
76 tristate "Au1550 NAND support" 62 tristate "Au1550 NAND support"
77 depends on SOC_AU1550 && MTD_NAND 63 depends on SOC_AU1550 && MTD_NAND
@@ -95,10 +81,11 @@ config MTD_NAND_PPCHAMELEONEVB
95 This enables the NAND flash driver on the PPChameleon EVB Board. 81 This enables the NAND flash driver on the PPChameleon EVB Board.
96 82
97config MTD_NAND_S3C2410 83config MTD_NAND_S3C2410
98 tristate "NAND Flash support for S3C2410 SoC" 84 tristate "NAND Flash support for S3C2410/S3C2440 SoC"
99 depends on ARCH_S3C2410 && MTD_NAND 85 depends on ARCH_S3C2410 && MTD_NAND
100 help 86 help
101 This enables the NAND flash controller on the S3C2410. 87 This enables the NAND flash controller on the S3C2410 and S3C2440
88 SoCs
102 89
103 No board specfic support is done by this driver, each board 90 No board specfic support is done by this driver, each board
104 must advertise a platform_device for the driver to attach. 91 must advertise a platform_device for the driver to attach.
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index d9dc8cc2da8c..41742026a52e 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -10,8 +10,6 @@ obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
10obj-$(CONFIG_MTD_NAND_TOTO) += toto.o 10obj-$(CONFIG_MTD_NAND_TOTO) += toto.o
11obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o 11obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
12obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o 12obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o
13obj-$(CONFIG_MTD_NAND_TX4925NDFMC) += tx4925ndfmc.o
14obj-$(CONFIG_MTD_NAND_TX4938NDFMC) += tx4938ndfmc.o
15obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o 13obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o
16obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o 14obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o
17obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o 15obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index 02135c3ac29a..fdb5d4ad3d52 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -16,7 +16,7 @@
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 * 18 *
19 * $Id: diskonchip.c,v 1.45 2005/01/05 18:05:14 dwmw2 Exp $ 19 * $Id: diskonchip.c,v 1.54 2005/04/07 14:22:55 dbrown Exp $
20 */ 20 */
21 21
22#include <linux/kernel.h> 22#include <linux/kernel.h>
@@ -35,13 +35,13 @@
35#include <linux/mtd/inftl.h> 35#include <linux/mtd/inftl.h>
36 36
37/* Where to look for the devices? */ 37/* Where to look for the devices? */
38#ifndef CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS 38#ifndef CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS
39#define CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS 0 39#define CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS 0
40#endif 40#endif
41 41
42static unsigned long __initdata doc_locations[] = { 42static unsigned long __initdata doc_locations[] = {
43#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__) 43#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
44#ifdef CONFIG_MTD_DISKONCHIP_PROBE_HIGH 44#ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH
45 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, 45 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
46 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000, 46 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
47 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, 47 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
@@ -81,11 +81,6 @@ struct doc_priv {
81 struct mtd_info *nextdoc; 81 struct mtd_info *nextdoc;
82}; 82};
83 83
84/* Max number of eraseblocks to scan (from start of device) for the (I)NFTL
85 MediaHeader. The spec says to just keep going, I think, but that's just
86 silly. */
87#define MAX_MEDIAHEADER_SCAN 8
88
89/* This is the syndrome computed by the HW ecc generator upon reading an empty 84/* This is the syndrome computed by the HW ecc generator upon reading an empty
90 page, one with all 0xff for data and stored ecc code. */ 85 page, one with all 0xff for data and stored ecc code. */
91static u_char empty_read_syndrome[6] = { 0x26, 0xff, 0x6d, 0x47, 0x73, 0x7a }; 86static u_char empty_read_syndrome[6] = { 0x26, 0xff, 0x6d, 0x47, 0x73, 0x7a };
@@ -111,10 +106,11 @@ module_param(try_dword, int, 0);
111static int no_ecc_failures=0; 106static int no_ecc_failures=0;
112module_param(no_ecc_failures, int, 0); 107module_param(no_ecc_failures, int, 0);
113 108
114#ifdef CONFIG_MTD_PARTITIONS
115static int no_autopart=0; 109static int no_autopart=0;
116module_param(no_autopart, int, 0); 110module_param(no_autopart, int, 0);
117#endif 111
112static int show_firmware_partition=0;
113module_param(show_firmware_partition, int, 0);
118 114
119#ifdef MTD_NAND_DISKONCHIP_BBTWRITE 115#ifdef MTD_NAND_DISKONCHIP_BBTWRITE
120static int inftl_bbt_write=1; 116static int inftl_bbt_write=1;
@@ -123,7 +119,7 @@ static int inftl_bbt_write=0;
123#endif 119#endif
124module_param(inftl_bbt_write, int, 0); 120module_param(inftl_bbt_write, int, 0);
125 121
126static unsigned long doc_config_location = CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS; 122static unsigned long doc_config_location = CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS;
127module_param(doc_config_location, ulong, 0); 123module_param(doc_config_location, ulong, 0);
128MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe for DiskOnChip"); 124MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe for DiskOnChip");
129 125
@@ -410,7 +406,12 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
410 doc200x_hwcontrol(mtd, NAND_CTL_SETALE); 406 doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
411 this->write_byte(mtd, 0); 407 this->write_byte(mtd, 0);
412 doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); 408 doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
413 409
410 /* We cant' use dev_ready here, but at least we wait for the
411 * command to complete
412 */
413 udelay(50);
414
414 ret = this->read_byte(mtd) << 8; 415 ret = this->read_byte(mtd) << 8;
415 ret |= this->read_byte(mtd); 416 ret |= this->read_byte(mtd);
416 417
@@ -429,6 +430,8 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
429 doc2000_write_byte(mtd, 0); 430 doc2000_write_byte(mtd, 0);
430 doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); 431 doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
431 432
433 udelay(50);
434
432 ident.dword = readl(docptr + DoC_2k_CDSN_IO); 435 ident.dword = readl(docptr + DoC_2k_CDSN_IO);
433 if (((ident.byte[0] << 8) | ident.byte[1]) == ret) { 436 if (((ident.byte[0] << 8) | ident.byte[1]) == ret) {
434 printk(KERN_INFO "DiskOnChip 2000 responds to DWORD access\n"); 437 printk(KERN_INFO "DiskOnChip 2000 responds to DWORD access\n");
@@ -1046,11 +1049,21 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
1046 1049
1047//u_char mydatabuf[528]; 1050//u_char mydatabuf[528];
1048 1051
1052/* The strange out-of-order .oobfree list below is a (possibly unneeded)
1053 * attempt to retain compatibility. It used to read:
1054 * .oobfree = { {8, 8} }
1055 * Since that leaves two bytes unusable, it was changed. But the following
1056 * scheme might affect existing jffs2 installs by moving the cleanmarker:
1057 * .oobfree = { {6, 10} }
1058 * jffs2 seems to handle the above gracefully, but the current scheme seems
1059 * safer. The only problem with it is that any code that parses oobfree must
1060 * be able to handle out-of-order segments.
1061 */
1049static struct nand_oobinfo doc200x_oobinfo = { 1062static struct nand_oobinfo doc200x_oobinfo = {
1050 .useecc = MTD_NANDECC_AUTOPLACE, 1063 .useecc = MTD_NANDECC_AUTOPLACE,
1051 .eccbytes = 6, 1064 .eccbytes = 6,
1052 .eccpos = {0, 1, 2, 3, 4, 5}, 1065 .eccpos = {0, 1, 2, 3, 4, 5},
1053 .oobfree = { {8, 8} } 1066 .oobfree = { {8, 8}, {6, 2} }
1054}; 1067};
1055 1068
1056/* Find the (I)NFTL Media Header, and optionally also the mirror media header. 1069/* Find the (I)NFTL Media Header, and optionally also the mirror media header.
@@ -1064,12 +1077,11 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf,
1064{ 1077{
1065 struct nand_chip *this = mtd->priv; 1078 struct nand_chip *this = mtd->priv;
1066 struct doc_priv *doc = this->priv; 1079 struct doc_priv *doc = this->priv;
1067 unsigned offs, end = (MAX_MEDIAHEADER_SCAN << this->phys_erase_shift); 1080 unsigned offs;
1068 int ret; 1081 int ret;
1069 size_t retlen; 1082 size_t retlen;
1070 1083
1071 end = min(end, mtd->size); // paranoia 1084 for (offs = 0; offs < mtd->size; offs += mtd->erasesize) {
1072 for (offs = 0; offs < end; offs += mtd->erasesize) {
1073 ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf); 1085 ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf);
1074 if (retlen != mtd->oobblock) continue; 1086 if (retlen != mtd->oobblock) continue;
1075 if (ret) { 1087 if (ret) {
@@ -1111,6 +1123,7 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
1111 u_char *buf; 1123 u_char *buf;
1112 struct NFTLMediaHeader *mh; 1124 struct NFTLMediaHeader *mh;
1113 const unsigned psize = 1 << this->page_shift; 1125 const unsigned psize = 1 << this->page_shift;
1126 int numparts = 0;
1114 unsigned blocks, maxblocks; 1127 unsigned blocks, maxblocks;
1115 int offs, numheaders; 1128 int offs, numheaders;
1116 1129
@@ -1122,8 +1135,10 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
1122 if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) goto out; 1135 if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) goto out;
1123 mh = (struct NFTLMediaHeader *) buf; 1136 mh = (struct NFTLMediaHeader *) buf;
1124 1137
1125//#ifdef CONFIG_MTD_DEBUG_VERBOSE 1138 mh->NumEraseUnits = le16_to_cpu(mh->NumEraseUnits);
1126// if (CONFIG_MTD_DEBUG_VERBOSE >= 2) 1139 mh->FirstPhysicalEUN = le16_to_cpu(mh->FirstPhysicalEUN);
1140 mh->FormattedSize = le32_to_cpu(mh->FormattedSize);
1141
1127 printk(KERN_INFO " DataOrgID = %s\n" 1142 printk(KERN_INFO " DataOrgID = %s\n"
1128 " NumEraseUnits = %d\n" 1143 " NumEraseUnits = %d\n"
1129 " FirstPhysicalEUN = %d\n" 1144 " FirstPhysicalEUN = %d\n"
@@ -1132,7 +1147,6 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
1132 mh->DataOrgID, mh->NumEraseUnits, 1147 mh->DataOrgID, mh->NumEraseUnits,
1133 mh->FirstPhysicalEUN, mh->FormattedSize, 1148 mh->FirstPhysicalEUN, mh->FormattedSize,
1134 mh->UnitSizeFactor); 1149 mh->UnitSizeFactor);
1135//#endif
1136 1150
1137 blocks = mtd->size >> this->phys_erase_shift; 1151 blocks = mtd->size >> this->phys_erase_shift;
1138 maxblocks = min(32768U, mtd->erasesize - psize); 1152 maxblocks = min(32768U, mtd->erasesize - psize);
@@ -1175,23 +1189,28 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
1175 offs <<= this->page_shift; 1189 offs <<= this->page_shift;
1176 offs += mtd->erasesize; 1190 offs += mtd->erasesize;
1177 1191
1178 //parts[0].name = " DiskOnChip Boot / Media Header partition"; 1192 if (show_firmware_partition == 1) {
1179 //parts[0].offset = 0; 1193 parts[0].name = " DiskOnChip Firmware / Media Header partition";
1180 //parts[0].size = offs; 1194 parts[0].offset = 0;
1195 parts[0].size = offs;
1196 numparts = 1;
1197 }
1181 1198
1182 parts[0].name = " DiskOnChip BDTL partition"; 1199 parts[numparts].name = " DiskOnChip BDTL partition";
1183 parts[0].offset = offs; 1200 parts[numparts].offset = offs;
1184 parts[0].size = (mh->NumEraseUnits - numheaders) << this->bbt_erase_shift; 1201 parts[numparts].size = (mh->NumEraseUnits - numheaders) << this->bbt_erase_shift;
1202
1203 offs += parts[numparts].size;
1204 numparts++;
1185 1205
1186 offs += parts[0].size;
1187 if (offs < mtd->size) { 1206 if (offs < mtd->size) {
1188 parts[1].name = " DiskOnChip Remainder partition"; 1207 parts[numparts].name = " DiskOnChip Remainder partition";
1189 parts[1].offset = offs; 1208 parts[numparts].offset = offs;
1190 parts[1].size = mtd->size - offs; 1209 parts[numparts].size = mtd->size - offs;
1191 ret = 2; 1210 numparts++;
1192 goto out;
1193 } 1211 }
1194 ret = 1; 1212
1213 ret = numparts;
1195out: 1214out:
1196 kfree(buf); 1215 kfree(buf);
1197 return ret; 1216 return ret;
@@ -1233,8 +1252,6 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
1233 mh->FormatFlags = le32_to_cpu(mh->FormatFlags); 1252 mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
1234 mh->PercentUsed = le32_to_cpu(mh->PercentUsed); 1253 mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
1235 1254
1236//#ifdef CONFIG_MTD_DEBUG_VERBOSE
1237// if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
1238 printk(KERN_INFO " bootRecordID = %s\n" 1255 printk(KERN_INFO " bootRecordID = %s\n"
1239 " NoOfBootImageBlocks = %d\n" 1256 " NoOfBootImageBlocks = %d\n"
1240 " NoOfBinaryPartitions = %d\n" 1257 " NoOfBinaryPartitions = %d\n"
@@ -1252,7 +1269,6 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
1252 ((unsigned char *) &mh->OsakVersion)[2] & 0xf, 1269 ((unsigned char *) &mh->OsakVersion)[2] & 0xf,
1253 ((unsigned char *) &mh->OsakVersion)[3] & 0xf, 1270 ((unsigned char *) &mh->OsakVersion)[3] & 0xf,
1254 mh->PercentUsed); 1271 mh->PercentUsed);
1255//#endif
1256 1272
1257 vshift = this->phys_erase_shift + mh->BlockMultiplierBits; 1273 vshift = this->phys_erase_shift + mh->BlockMultiplierBits;
1258 1274
@@ -1278,8 +1294,6 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
1278 ip->spareUnits = le32_to_cpu(ip->spareUnits); 1294 ip->spareUnits = le32_to_cpu(ip->spareUnits);
1279 ip->Reserved0 = le32_to_cpu(ip->Reserved0); 1295 ip->Reserved0 = le32_to_cpu(ip->Reserved0);
1280 1296
1281//#ifdef CONFIG_MTD_DEBUG_VERBOSE
1282// if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
1283 printk(KERN_INFO " PARTITION[%d] ->\n" 1297 printk(KERN_INFO " PARTITION[%d] ->\n"
1284 " virtualUnits = %d\n" 1298 " virtualUnits = %d\n"
1285 " firstUnit = %d\n" 1299 " firstUnit = %d\n"
@@ -1289,16 +1303,14 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
1289 i, ip->virtualUnits, ip->firstUnit, 1303 i, ip->virtualUnits, ip->firstUnit,
1290 ip->lastUnit, ip->flags, 1304 ip->lastUnit, ip->flags,
1291 ip->spareUnits); 1305 ip->spareUnits);
1292//#endif
1293 1306
1294/* 1307 if ((show_firmware_partition == 1) &&
1295 if ((i == 0) && (ip->firstUnit > 0)) { 1308 (i == 0) && (ip->firstUnit > 0)) {
1296 parts[0].name = " DiskOnChip IPL / Media Header partition"; 1309 parts[0].name = " DiskOnChip IPL / Media Header partition";
1297 parts[0].offset = 0; 1310 parts[0].offset = 0;
1298 parts[0].size = mtd->erasesize * ip->firstUnit; 1311 parts[0].size = mtd->erasesize * ip->firstUnit;
1299 numparts = 1; 1312 numparts = 1;
1300 } 1313 }
1301*/
1302 1314
1303 if (ip->flags & INFTL_BINARY) 1315 if (ip->flags & INFTL_BINARY)
1304 parts[numparts].name = " DiskOnChip BDK partition"; 1316 parts[numparts].name = " DiskOnChip BDK partition";
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 44d5b128911f..1bd71a598c79 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -28,6 +28,24 @@
28 * among multiple independend devices. Suggestions and initial patch 28 * among multiple independend devices. Suggestions and initial patch
29 * from Ben Dooks <ben-mtd@fluff.org> 29 * from Ben Dooks <ben-mtd@fluff.org>
30 * 30 *
31 * 12-05-2004 dmarlin: add workaround for Renesas AG-AND chips "disturb" issue.
32 * Basically, any block not rewritten may lose data when surrounding blocks
33 * are rewritten many times. JFFS2 ensures this doesn't happen for blocks
34 * it uses, but the Bad Block Table(s) may not be rewritten. To ensure they
35 * do not lose data, force them to be rewritten when some of the surrounding
36 * blocks are erased. Rather than tracking a specific nearby block (which
37 * could itself go bad), use a page address 'mask' to select several blocks
38 * in the same area, and rewrite the BBT when any of them are erased.
39 *
40 * 01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas
41 * AG-AND chips. If there was a sudden loss of power during an erase operation,
42 * a "device recovery" operation must be performed when power is restored
43 * to ensure correct operation.
44 *
45 * 01-20-2005 dmarlin: added support for optional hardware specific callback routine to
46 * perform extra error status checks on erase and write failures. This required
47 * adding a wrapper function for nand_read_ecc.
48 *
31 * Credits: 49 * Credits:
32 * David Woodhouse for adding multichip support 50 * David Woodhouse for adding multichip support
33 * 51 *
@@ -41,7 +59,7 @@
41 * The AG-AND chips have nice features for speed improvement, 59 * The AG-AND chips have nice features for speed improvement,
42 * which are not supported yet. Read / program 4 pages in one go. 60 * which are not supported yet. Read / program 4 pages in one go.
43 * 61 *
44 * $Id: nand_base.c,v 1.126 2004/12/13 11:22:25 lavinen Exp $ 62 * $Id: nand_base.c,v 1.146 2005/06/17 15:02:06 gleixner Exp $
45 * 63 *
46 * This program is free software; you can redistribute it and/or modify 64 * This program is free software; you can redistribute it and/or modify
47 * it under the terms of the GNU General Public License version 2 as 65 * it under the terms of the GNU General Public License version 2 as
@@ -149,17 +167,21 @@ static void nand_release_device (struct mtd_info *mtd)
149 167
150 /* De-select the NAND device */ 168 /* De-select the NAND device */
151 this->select_chip(mtd, -1); 169 this->select_chip(mtd, -1);
152 /* Do we have a hardware controller ? */ 170
153 if (this->controller) { 171 if (this->controller) {
172 /* Release the controller and the chip */
154 spin_lock(&this->controller->lock); 173 spin_lock(&this->controller->lock);
155 this->controller->active = NULL; 174 this->controller->active = NULL;
175 this->state = FL_READY;
176 wake_up(&this->controller->wq);
156 spin_unlock(&this->controller->lock); 177 spin_unlock(&this->controller->lock);
178 } else {
179 /* Release the chip */
180 spin_lock(&this->chip_lock);
181 this->state = FL_READY;
182 wake_up(&this->wq);
183 spin_unlock(&this->chip_lock);
157 } 184 }
158 /* Release the chip */
159 spin_lock (&this->chip_lock);
160 this->state = FL_READY;
161 wake_up (&this->wq);
162 spin_unlock (&this->chip_lock);
163} 185}
164 186
165/** 187/**
@@ -443,7 +465,8 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
443 465
444 /* Get block number */ 466 /* Get block number */
445 block = ((int) ofs) >> this->bbt_erase_shift; 467 block = ((int) ofs) >> this->bbt_erase_shift;
446 this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); 468 if (this->bbt)
469 this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
447 470
448 /* Do we have a flash based bad block table ? */ 471 /* Do we have a flash based bad block table ? */
449 if (this->options & NAND_USE_FLASH_BBT) 472 if (this->options & NAND_USE_FLASH_BBT)
@@ -466,7 +489,7 @@ static int nand_check_wp (struct mtd_info *mtd)
466 struct nand_chip *this = mtd->priv; 489 struct nand_chip *this = mtd->priv;
467 /* Check the WP bit */ 490 /* Check the WP bit */
468 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); 491 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
469 return (this->read_byte(mtd) & 0x80) ? 0 : 1; 492 return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
470} 493}
471 494
472/** 495/**
@@ -490,6 +513,22 @@ static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, i
490 return nand_isbad_bbt (mtd, ofs, allowbbt); 513 return nand_isbad_bbt (mtd, ofs, allowbbt);
491} 514}
492 515
516/*
517 * Wait for the ready pin, after a command
518 * The timeout is catched later.
519 */
520static void nand_wait_ready(struct mtd_info *mtd)
521{
522 struct nand_chip *this = mtd->priv;
523 unsigned long timeo = jiffies + 2;
524
525 /* wait until command is processed or timeout occures */
526 do {
527 if (this->dev_ready(mtd))
528 return;
529 } while (time_before(jiffies, timeo));
530}
531
493/** 532/**
494 * nand_command - [DEFAULT] Send command to NAND device 533 * nand_command - [DEFAULT] Send command to NAND device
495 * @mtd: MTD device structure 534 * @mtd: MTD device structure
@@ -571,7 +610,7 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
571 this->hwcontrol(mtd, NAND_CTL_SETCLE); 610 this->hwcontrol(mtd, NAND_CTL_SETCLE);
572 this->write_byte(mtd, NAND_CMD_STATUS); 611 this->write_byte(mtd, NAND_CMD_STATUS);
573 this->hwcontrol(mtd, NAND_CTL_CLRCLE); 612 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
574 while ( !(this->read_byte(mtd) & 0x40)); 613 while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
575 return; 614 return;
576 615
577 /* This applies to read commands */ 616 /* This applies to read commands */
@@ -585,12 +624,11 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
585 return; 624 return;
586 } 625 }
587 } 626 }
588
589 /* Apply this short delay always to ensure that we do wait tWB in 627 /* Apply this short delay always to ensure that we do wait tWB in
590 * any case on any machine. */ 628 * any case on any machine. */
591 ndelay (100); 629 ndelay (100);
592 /* wait until command is processed */ 630
593 while (!this->dev_ready(mtd)); 631 nand_wait_ready(mtd);
594} 632}
595 633
596/** 634/**
@@ -619,7 +657,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
619 /* Begin command latch cycle */ 657 /* Begin command latch cycle */
620 this->hwcontrol(mtd, NAND_CTL_SETCLE); 658 this->hwcontrol(mtd, NAND_CTL_SETCLE);
621 /* Write out the command to the device. */ 659 /* Write out the command to the device. */
622 this->write_byte(mtd, command); 660 this->write_byte(mtd, (command & 0xff));
623 /* End command latch cycle */ 661 /* End command latch cycle */
624 this->hwcontrol(mtd, NAND_CTL_CLRCLE); 662 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
625 663
@@ -647,8 +685,8 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
647 685
648 /* 686 /*
649 * program and erase have their own busy handlers 687 * program and erase have their own busy handlers
650 * status and sequential in needs no delay 688 * status, sequential in, and deplete1 need no delay
651 */ 689 */
652 switch (command) { 690 switch (command) {
653 691
654 case NAND_CMD_CACHEDPROG: 692 case NAND_CMD_CACHEDPROG:
@@ -657,8 +695,19 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
657 case NAND_CMD_ERASE2: 695 case NAND_CMD_ERASE2:
658 case NAND_CMD_SEQIN: 696 case NAND_CMD_SEQIN:
659 case NAND_CMD_STATUS: 697 case NAND_CMD_STATUS:
698 case NAND_CMD_DEPLETE1:
660 return; 699 return;
661 700
701 /*
702 * read error status commands require only a short delay
703 */
704 case NAND_CMD_STATUS_ERROR:
705 case NAND_CMD_STATUS_ERROR0:
706 case NAND_CMD_STATUS_ERROR1:
707 case NAND_CMD_STATUS_ERROR2:
708 case NAND_CMD_STATUS_ERROR3:
709 udelay(this->chip_delay);
710 return;
662 711
663 case NAND_CMD_RESET: 712 case NAND_CMD_RESET:
664 if (this->dev_ready) 713 if (this->dev_ready)
@@ -667,7 +716,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
667 this->hwcontrol(mtd, NAND_CTL_SETCLE); 716 this->hwcontrol(mtd, NAND_CTL_SETCLE);
668 this->write_byte(mtd, NAND_CMD_STATUS); 717 this->write_byte(mtd, NAND_CMD_STATUS);
669 this->hwcontrol(mtd, NAND_CTL_CLRCLE); 718 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
670 while ( !(this->read_byte(mtd) & 0x40)); 719 while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
671 return; 720 return;
672 721
673 case NAND_CMD_READ0: 722 case NAND_CMD_READ0:
@@ -690,12 +739,12 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
690 return; 739 return;
691 } 740 }
692 } 741 }
693 742
694 /* Apply this short delay always to ensure that we do wait tWB in 743 /* Apply this short delay always to ensure that we do wait tWB in
695 * any case on any machine. */ 744 * any case on any machine. */
696 ndelay (100); 745 ndelay (100);
697 /* wait until command is processed */ 746
698 while (!this->dev_ready(mtd)); 747 nand_wait_ready(mtd);
699} 748}
700 749
701/** 750/**
@@ -708,37 +757,34 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
708 */ 757 */
709static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) 758static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
710{ 759{
711 struct nand_chip *active = this; 760 struct nand_chip *active;
712 761 spinlock_t *lock;
762 wait_queue_head_t *wq;
713 DECLARE_WAITQUEUE (wait, current); 763 DECLARE_WAITQUEUE (wait, current);
714 764
715 /* 765 lock = (this->controller) ? &this->controller->lock : &this->chip_lock;
716 * Grab the lock and see if the device is available 766 wq = (this->controller) ? &this->controller->wq : &this->wq;
717 */
718retry: 767retry:
768 active = this;
769 spin_lock(lock);
770
719 /* Hardware controller shared among independend devices */ 771 /* Hardware controller shared among independend devices */
720 if (this->controller) { 772 if (this->controller) {
721 spin_lock (&this->controller->lock);
722 if (this->controller->active) 773 if (this->controller->active)
723 active = this->controller->active; 774 active = this->controller->active;
724 else 775 else
725 this->controller->active = this; 776 this->controller->active = this;
726 spin_unlock (&this->controller->lock);
727 } 777 }
728 778 if (active == this && this->state == FL_READY) {
729 if (active == this) { 779 this->state = new_state;
730 spin_lock (&this->chip_lock); 780 spin_unlock(lock);
731 if (this->state == FL_READY) { 781 return;
732 this->state = new_state; 782 }
733 spin_unlock (&this->chip_lock); 783 set_current_state(TASK_UNINTERRUPTIBLE);
734 return; 784 add_wait_queue(wq, &wait);
735 } 785 spin_unlock(lock);
736 } 786 schedule();
737 set_current_state (TASK_UNINTERRUPTIBLE); 787 remove_wait_queue(wq, &wait);
738 add_wait_queue (&active->wq, &wait);
739 spin_unlock (&active->chip_lock);
740 schedule ();
741 remove_wait_queue (&active->wq, &wait);
742 goto retry; 788 goto retry;
743} 789}
744 790
@@ -785,7 +831,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
785 if (this->read_byte(mtd) & NAND_STATUS_READY) 831 if (this->read_byte(mtd) & NAND_STATUS_READY)
786 break; 832 break;
787 } 833 }
788 yield (); 834 cond_resched();
789 } 835 }
790 status = (int) this->read_byte(mtd); 836 status = (int) this->read_byte(mtd);
791 return status; 837 return status;
@@ -871,8 +917,14 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
871 if (!cached) { 917 if (!cached) {
872 /* call wait ready function */ 918 /* call wait ready function */
873 status = this->waitfunc (mtd, this, FL_WRITING); 919 status = this->waitfunc (mtd, this, FL_WRITING);
920
921 /* See if operation failed and additional status checks are available */
922 if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
923 status = this->errstat(mtd, this, FL_WRITING, status, page);
924 }
925
874 /* See if device thinks it succeeded */ 926 /* See if device thinks it succeeded */
875 if (status & 0x01) { 927 if (status & NAND_STATUS_FAIL) {
876 DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNCTION__, page); 928 DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNCTION__, page);
877 return -EIO; 929 return -EIO;
878 } 930 }
@@ -975,7 +1027,7 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
975 if (!this->dev_ready) 1027 if (!this->dev_ready)
976 udelay (this->chip_delay); 1028 udelay (this->chip_delay);
977 else 1029 else
978 while (!this->dev_ready(mtd)); 1030 nand_wait_ready(mtd);
979 1031
980 /* All done, return happy */ 1032 /* All done, return happy */
981 if (!numpages) 1033 if (!numpages)
@@ -997,23 +1049,24 @@ out:
997#endif 1049#endif
998 1050
999/** 1051/**
1000 * nand_read - [MTD Interface] MTD compability function for nand_read_ecc 1052 * nand_read - [MTD Interface] MTD compability function for nand_do_read_ecc
1001 * @mtd: MTD device structure 1053 * @mtd: MTD device structure
1002 * @from: offset to read from 1054 * @from: offset to read from
1003 * @len: number of bytes to read 1055 * @len: number of bytes to read
1004 * @retlen: pointer to variable to store the number of read bytes 1056 * @retlen: pointer to variable to store the number of read bytes
1005 * @buf: the databuffer to put data 1057 * @buf: the databuffer to put data
1006 * 1058 *
1007 * This function simply calls nand_read_ecc with oob buffer and oobsel = NULL 1059 * This function simply calls nand_do_read_ecc with oob buffer and oobsel = NULL
1008*/ 1060 * and flags = 0xff
1061 */
1009static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf) 1062static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
1010{ 1063{
1011 return nand_read_ecc (mtd, from, len, retlen, buf, NULL, NULL); 1064 return nand_do_read_ecc (mtd, from, len, retlen, buf, NULL, &mtd->oobinfo, 0xff);
1012} 1065}
1013 1066
1014 1067
1015/** 1068/**
1016 * nand_read_ecc - [MTD Interface] Read data with ECC 1069 * nand_read_ecc - [MTD Interface] MTD compability function for nand_do_read_ecc
1017 * @mtd: MTD device structure 1070 * @mtd: MTD device structure
1018 * @from: offset to read from 1071 * @from: offset to read from
1019 * @len: number of bytes to read 1072 * @len: number of bytes to read
@@ -1022,11 +1075,39 @@ static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * re
1022 * @oob_buf: filesystem supplied oob data buffer 1075 * @oob_buf: filesystem supplied oob data buffer
1023 * @oobsel: oob selection structure 1076 * @oobsel: oob selection structure
1024 * 1077 *
1025 * NAND read with ECC 1078 * This function simply calls nand_do_read_ecc with flags = 0xff
1026 */ 1079 */
1027static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, 1080static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1028 size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel) 1081 size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel)
1029{ 1082{
1083 /* use userspace supplied oobinfo, if zero */
1084 if (oobsel == NULL)
1085 oobsel = &mtd->oobinfo;
1086 return nand_do_read_ecc(mtd, from, len, retlen, buf, oob_buf, oobsel, 0xff);
1087}
1088
1089
1090/**
1091 * nand_do_read_ecc - [MTD Interface] Read data with ECC
1092 * @mtd: MTD device structure
1093 * @from: offset to read from
1094 * @len: number of bytes to read
1095 * @retlen: pointer to variable to store the number of read bytes
1096 * @buf: the databuffer to put data
1097 * @oob_buf: filesystem supplied oob data buffer (can be NULL)
1098 * @oobsel: oob selection structure
1099 * @flags: flag to indicate if nand_get_device/nand_release_device should be preformed
1100 * and how many corrected error bits are acceptable:
1101 * bits 0..7 - number of tolerable errors
1102 * bit 8 - 0 == do not get/release chip, 1 == get/release chip
1103 *
1104 * NAND read with ECC
1105 */
1106int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1107 size_t * retlen, u_char * buf, u_char * oob_buf,
1108 struct nand_oobinfo *oobsel, int flags)
1109{
1110
1030 int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1; 1111 int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1;
1031 int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0; 1112 int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0;
1032 struct nand_chip *this = mtd->priv; 1113 struct nand_chip *this = mtd->priv;
@@ -1051,12 +1132,9 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1051 } 1132 }
1052 1133
1053 /* Grab the lock and see if the device is available */ 1134 /* Grab the lock and see if the device is available */
1054 nand_get_device (this, mtd ,FL_READING); 1135 if (flags & NAND_GET_DEVICE)
1136 nand_get_device (this, mtd, FL_READING);
1055 1137
1056 /* use userspace supplied oobinfo, if zero */
1057 if (oobsel == NULL)
1058 oobsel = &mtd->oobinfo;
1059
1060 /* Autoplace of oob data ? Use the default placement scheme */ 1138 /* Autoplace of oob data ? Use the default placement scheme */
1061 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) 1139 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
1062 oobsel = this->autooob; 1140 oobsel = this->autooob;
@@ -1118,7 +1196,8 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1118 } 1196 }
1119 1197
1120 /* get oob area, if we have no oob buffer from fs-driver */ 1198 /* get oob area, if we have no oob buffer from fs-driver */
1121 if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE) 1199 if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE ||
1200 oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
1122 oob_data = &this->data_buf[end]; 1201 oob_data = &this->data_buf[end];
1123 1202
1124 eccsteps = this->eccsteps; 1203 eccsteps = this->eccsteps;
@@ -1155,7 +1234,8 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1155 /* We calc error correction directly, it checks the hw 1234 /* We calc error correction directly, it checks the hw
1156 * generator for an error, reads back the syndrome and 1235 * generator for an error, reads back the syndrome and
1157 * does the error correction on the fly */ 1236 * does the error correction on the fly */
1158 if (this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]) == -1) { 1237 ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]);
1238 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
1159 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " 1239 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
1160 "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr); 1240 "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
1161 ecc_failed++; 1241 ecc_failed++;
@@ -1194,7 +1274,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1194 p[i] = ecc_status; 1274 p[i] = ecc_status;
1195 } 1275 }
1196 1276
1197 if (ecc_status == -1) { 1277 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
1198 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page); 1278 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
1199 ecc_failed++; 1279 ecc_failed++;
1200 } 1280 }
@@ -1206,14 +1286,14 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1206 /* without autoplace. Legacy mode used by YAFFS1 */ 1286 /* without autoplace. Legacy mode used by YAFFS1 */
1207 switch(oobsel->useecc) { 1287 switch(oobsel->useecc) {
1208 case MTD_NANDECC_AUTOPLACE: 1288 case MTD_NANDECC_AUTOPLACE:
1289 case MTD_NANDECC_AUTOPL_USR:
1209 /* Walk through the autoplace chunks */ 1290 /* Walk through the autoplace chunks */
1210 for (i = 0, j = 0; j < mtd->oobavail; i++) { 1291 for (i = 0; oobsel->oobfree[i][1]; i++) {
1211 int from = oobsel->oobfree[i][0]; 1292 int from = oobsel->oobfree[i][0];
1212 int num = oobsel->oobfree[i][1]; 1293 int num = oobsel->oobfree[i][1];
1213 memcpy(&oob_buf[oob], &oob_data[from], num); 1294 memcpy(&oob_buf[oob], &oob_data[from], num);
1214 j+= num; 1295 oob += num;
1215 } 1296 }
1216 oob += mtd->oobavail;
1217 break; 1297 break;
1218 case MTD_NANDECC_PLACE: 1298 case MTD_NANDECC_PLACE:
1219 /* YAFFS1 legacy mode */ 1299 /* YAFFS1 legacy mode */
@@ -1239,7 +1319,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1239 if (!this->dev_ready) 1319 if (!this->dev_ready)
1240 udelay (this->chip_delay); 1320 udelay (this->chip_delay);
1241 else 1321 else
1242 while (!this->dev_ready(mtd)); 1322 nand_wait_ready(mtd);
1243 1323
1244 if (read == len) 1324 if (read == len)
1245 break; 1325 break;
@@ -1264,7 +1344,8 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1264 } 1344 }
1265 1345
1266 /* Deselect and wake up anyone waiting on the device */ 1346 /* Deselect and wake up anyone waiting on the device */
1267 nand_release_device(mtd); 1347 if (flags & NAND_GET_DEVICE)
1348 nand_release_device(mtd);
1268 1349
1269 /* 1350 /*
1270 * Return success, if no ECC failures, else -EBADMSG 1351 * Return success, if no ECC failures, else -EBADMSG
@@ -1337,7 +1418,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
1337 if (!this->dev_ready) 1418 if (!this->dev_ready)
1338 udelay (this->chip_delay); 1419 udelay (this->chip_delay);
1339 else 1420 else
1340 while (!this->dev_ready(mtd)); 1421 nand_wait_ready(mtd);
1341 1422
1342 /* Read more ? */ 1423 /* Read more ? */
1343 if (i < len) { 1424 if (i < len) {
@@ -1417,7 +1498,7 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len,
1417 if (!this->dev_ready) 1498 if (!this->dev_ready)
1418 udelay (this->chip_delay); 1499 udelay (this->chip_delay);
1419 else 1500 else
1420 while (!this->dev_ready(mtd)); 1501 nand_wait_ready(mtd);
1421 1502
1422 /* Check, if the chip supports auto page increment */ 1503 /* Check, if the chip supports auto page increment */
1423 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) 1504 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
@@ -1567,6 +1648,8 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1567 oobsel = this->autooob; 1648 oobsel = this->autooob;
1568 autoplace = 1; 1649 autoplace = 1;
1569 } 1650 }
1651 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
1652 autoplace = 1;
1570 1653
1571 /* Setup variables and oob buffer */ 1654 /* Setup variables and oob buffer */
1572 totalpages = len >> this->page_shift; 1655 totalpages = len >> this->page_shift;
@@ -1733,7 +1816,7 @@ static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t *
1733 status = this->waitfunc (mtd, this, FL_WRITING); 1816 status = this->waitfunc (mtd, this, FL_WRITING);
1734 1817
1735 /* See if device thinks it succeeded */ 1818 /* See if device thinks it succeeded */
1736 if (status & 0x01) { 1819 if (status & NAND_STATUS_FAIL) {
1737 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page); 1820 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page);
1738 ret = -EIO; 1821 ret = -EIO;
1739 goto out; 1822 goto out;
@@ -1841,6 +1924,8 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
1841 oobsel = this->autooob; 1924 oobsel = this->autooob;
1842 autoplace = 1; 1925 autoplace = 1;
1843 } 1926 }
1927 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
1928 autoplace = 1;
1844 1929
1845 /* Setup start page */ 1930 /* Setup start page */
1846 page = (int) (to >> this->page_shift); 1931 page = (int) (to >> this->page_shift);
@@ -1987,6 +2072,7 @@ static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
1987 return nand_erase_nand (mtd, instr, 0); 2072 return nand_erase_nand (mtd, instr, 0);
1988} 2073}
1989 2074
2075#define BBT_PAGE_MASK 0xffffff3f
1990/** 2076/**
1991 * nand_erase_intern - [NAND Interface] erase block(s) 2077 * nand_erase_intern - [NAND Interface] erase block(s)
1992 * @mtd: MTD device structure 2078 * @mtd: MTD device structure
@@ -1999,6 +2085,10 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
1999{ 2085{
2000 int page, len, status, pages_per_block, ret, chipnr; 2086 int page, len, status, pages_per_block, ret, chipnr;
2001 struct nand_chip *this = mtd->priv; 2087 struct nand_chip *this = mtd->priv;
2088 int rewrite_bbt[NAND_MAX_CHIPS]={0}; /* flags to indicate the page, if bbt needs to be rewritten. */
2089 unsigned int bbt_masked_page; /* bbt mask to compare to page being erased. */
2090 /* It is used to see if the current page is in the same */
2091 /* 256 block group and the same bank as the bbt. */
2002 2092
2003 DEBUG (MTD_DEBUG_LEVEL3, 2093 DEBUG (MTD_DEBUG_LEVEL3,
2004 "nand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len); 2094 "nand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len);
@@ -2044,6 +2134,13 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
2044 goto erase_exit; 2134 goto erase_exit;
2045 } 2135 }
2046 2136
2137 /* if BBT requires refresh, set the BBT page mask to see if the BBT should be rewritten */
2138 if (this->options & BBT_AUTO_REFRESH) {
2139 bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
2140 } else {
2141 bbt_masked_page = 0xffffffff; /* should not match anything */
2142 }
2143
2047 /* Loop through the pages */ 2144 /* Loop through the pages */
2048 len = instr->len; 2145 len = instr->len;
2049 2146
@@ -2066,13 +2163,26 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
2066 2163
2067 status = this->waitfunc (mtd, this, FL_ERASING); 2164 status = this->waitfunc (mtd, this, FL_ERASING);
2068 2165
2166 /* See if operation failed and additional status checks are available */
2167 if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
2168 status = this->errstat(mtd, this, FL_ERASING, status, page);
2169 }
2170
2069 /* See if block erase succeeded */ 2171 /* See if block erase succeeded */
2070 if (status & 0x01) { 2172 if (status & NAND_STATUS_FAIL) {
2071 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page); 2173 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page);
2072 instr->state = MTD_ERASE_FAILED; 2174 instr->state = MTD_ERASE_FAILED;
2073 instr->fail_addr = (page << this->page_shift); 2175 instr->fail_addr = (page << this->page_shift);
2074 goto erase_exit; 2176 goto erase_exit;
2075 } 2177 }
2178
2179 /* if BBT requires refresh, set the BBT rewrite flag to the page being erased */
2180 if (this->options & BBT_AUTO_REFRESH) {
2181 if (((page & BBT_PAGE_MASK) == bbt_masked_page) &&
2182 (page != this->bbt_td->pages[chipnr])) {
2183 rewrite_bbt[chipnr] = (page << this->page_shift);
2184 }
2185 }
2076 2186
2077 /* Increment page address and decrement length */ 2187 /* Increment page address and decrement length */
2078 len -= (1 << this->phys_erase_shift); 2188 len -= (1 << this->phys_erase_shift);
@@ -2083,6 +2193,13 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
2083 chipnr++; 2193 chipnr++;
2084 this->select_chip(mtd, -1); 2194 this->select_chip(mtd, -1);
2085 this->select_chip(mtd, chipnr); 2195 this->select_chip(mtd, chipnr);
2196
2197 /* if BBT requires refresh and BBT-PERCHIP,
2198 * set the BBT page mask to see if this BBT should be rewritten */
2199 if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) {
2200 bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
2201 }
2202
2086 } 2203 }
2087 } 2204 }
2088 instr->state = MTD_ERASE_DONE; 2205 instr->state = MTD_ERASE_DONE;
@@ -2097,6 +2214,18 @@ erase_exit:
2097 /* Deselect and wake up anyone waiting on the device */ 2214 /* Deselect and wake up anyone waiting on the device */
2098 nand_release_device(mtd); 2215 nand_release_device(mtd);
2099 2216
2217 /* if BBT requires refresh and erase was successful, rewrite any selected bad block tables */
2218 if ((this->options & BBT_AUTO_REFRESH) && (!ret)) {
2219 for (chipnr = 0; chipnr < this->numchips; chipnr++) {
2220 if (rewrite_bbt[chipnr]) {
2221 /* update the BBT for chip */
2222 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n",
2223 chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]);
2224 nand_update_bbt (mtd, rewrite_bbt[chipnr]);
2225 }
2226 }
2227 }
2228
2100 /* Return more or less happy */ 2229 /* Return more or less happy */
2101 return ret; 2230 return ret;
2102} 2231}
@@ -2168,7 +2297,7 @@ static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs)
2168 */ 2297 */
2169int nand_scan (struct mtd_info *mtd, int maxchips) 2298int nand_scan (struct mtd_info *mtd, int maxchips)
2170{ 2299{
2171 int i, j, nand_maf_id, nand_dev_id, busw; 2300 int i, nand_maf_id, nand_dev_id, busw, maf_id;
2172 struct nand_chip *this = mtd->priv; 2301 struct nand_chip *this = mtd->priv;
2173 2302
2174 /* Get buswidth to select the correct functions*/ 2303 /* Get buswidth to select the correct functions*/
@@ -2256,12 +2385,18 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2256 busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16; 2385 busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16;
2257 } 2386 }
2258 2387
2388 /* Try to identify manufacturer */
2389 for (maf_id = 0; nand_manuf_ids[maf_id].id != 0x0; maf_id++) {
2390 if (nand_manuf_ids[maf_id].id == nand_maf_id)
2391 break;
2392 }
2393
2259 /* Check, if buswidth is correct. Hardware drivers should set 2394 /* Check, if buswidth is correct. Hardware drivers should set
2260 * this correct ! */ 2395 * this correct ! */
2261 if (busw != (this->options & NAND_BUSWIDTH_16)) { 2396 if (busw != (this->options & NAND_BUSWIDTH_16)) {
2262 printk (KERN_INFO "NAND device: Manufacturer ID:" 2397 printk (KERN_INFO "NAND device: Manufacturer ID:"
2263 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, 2398 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
2264 nand_manuf_ids[i].name , mtd->name); 2399 nand_manuf_ids[maf_id].name , mtd->name);
2265 printk (KERN_WARNING 2400 printk (KERN_WARNING
2266 "NAND bus width %d instead %d bit\n", 2401 "NAND bus width %d instead %d bit\n",
2267 (this->options & NAND_BUSWIDTH_16) ? 16 : 8, 2402 (this->options & NAND_BUSWIDTH_16) ? 16 : 8,
@@ -2300,14 +2435,9 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2300 if (mtd->oobblock > 512 && this->cmdfunc == nand_command) 2435 if (mtd->oobblock > 512 && this->cmdfunc == nand_command)
2301 this->cmdfunc = nand_command_lp; 2436 this->cmdfunc = nand_command_lp;
2302 2437
2303 /* Try to identify manufacturer */
2304 for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
2305 if (nand_manuf_ids[j].id == nand_maf_id)
2306 break;
2307 }
2308 printk (KERN_INFO "NAND device: Manufacturer ID:" 2438 printk (KERN_INFO "NAND device: Manufacturer ID:"
2309 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, 2439 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
2310 nand_manuf_ids[j].name , nand_flash_ids[i].name); 2440 nand_manuf_ids[maf_id].name , nand_flash_ids[i].name);
2311 break; 2441 break;
2312 } 2442 }
2313 2443
@@ -2388,12 +2518,9 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2388 2518
2389 /* The number of bytes available for the filesystem to place fs dependend 2519 /* The number of bytes available for the filesystem to place fs dependend
2390 * oob data */ 2520 * oob data */
2391 if (this->options & NAND_BUSWIDTH_16) { 2521 mtd->oobavail = 0;
2392 mtd->oobavail = mtd->oobsize - (this->autooob->eccbytes + 2); 2522 for (i = 0; this->autooob->oobfree[i][1]; i++)
2393 if (this->autooob->eccbytes & 0x01) 2523 mtd->oobavail += this->autooob->oobfree[i][1];
2394 mtd->oobavail--;
2395 } else
2396 mtd->oobavail = mtd->oobsize - (this->autooob->eccbytes + 1);
2397 2524
2398 /* 2525 /*
2399 * check ECC mode, default to software 2526 * check ECC mode, default to software
@@ -2524,6 +2651,10 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2524 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo)); 2651 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
2525 2652
2526 mtd->owner = THIS_MODULE; 2653 mtd->owner = THIS_MODULE;
2654
2655 /* Check, if we should skip the bad block table scan */
2656 if (this->options & NAND_SKIP_BBTSCAN)
2657 return 0;
2527 2658
2528 /* Build bad block table */ 2659 /* Build bad block table */
2529 return this->scan_bbt (mtd); 2660 return this->scan_bbt (mtd);
@@ -2555,8 +2686,8 @@ void nand_release (struct mtd_info *mtd)
2555 kfree (this->data_buf); 2686 kfree (this->data_buf);
2556} 2687}
2557 2688
2558EXPORT_SYMBOL (nand_scan); 2689EXPORT_SYMBOL_GPL (nand_scan);
2559EXPORT_SYMBOL (nand_release); 2690EXPORT_SYMBOL_GPL (nand_release);
2560 2691
2561MODULE_LICENSE ("GPL"); 2692MODULE_LICENSE ("GPL");
2562MODULE_AUTHOR ("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>"); 2693MODULE_AUTHOR ("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>");
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 9a1949751c1f..5ac2d2962220 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -6,7 +6,7 @@
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.28 2004/11/13 10:19:09 gleixner Exp $ 9 * $Id: nand_bbt.c,v 1.33 2005/06/14 15:47:56 gleixner Exp $
10 * 10 *
11 * 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
12 * 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
@@ -77,7 +77,7 @@
77*/ 77*/
78static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td) 78static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
79{ 79{
80 int i, end; 80 int i, end = 0;
81 uint8_t *p = buf; 81 uint8_t *p = buf;
82 82
83 end = paglen + td->offs; 83 end = paglen + td->offs;
@@ -95,9 +95,9 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
95 return -1; 95 return -1;
96 } 96 }
97 97
98 p += td->len;
99 end += td->len;
100 if (td->options & NAND_BBT_SCANEMPTY) { 98 if (td->options & NAND_BBT_SCANEMPTY) {
99 p += td->len;
100 end += td->len;
101 for (i = end; i < len; i++) { 101 for (i = end; i < len; i++) {
102 if (*p++ != 0xff) 102 if (*p++ != 0xff)
103 return -1; 103 return -1;
@@ -106,6 +106,32 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
106 return 0; 106 return 0;
107} 107}
108 108
109/**
110 * check_short_pattern - [GENERIC] check if a pattern is in the buffer
111 * @buf: the buffer to search
112 * @len: the length of buffer to search
113 * @paglen: the pagelength
114 * @td: search pattern descriptor
115 *
116 * Check for a pattern at the given place. Used to search bad block
117 * tables and good / bad block identifiers. Same as check_pattern, but
118 * no optional empty check and the pattern is expected to start
119 * at offset 0.
120 *
121*/
122static int check_short_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
123{
124 int i;
125 uint8_t *p = buf;
126
127 /* Compare the pattern */
128 for (i = 0; i < td->len; i++) {
129 if (p[i] != td->pattern[i])
130 return -1;
131 }
132 return 0;
133}
134
109/** 135/**
110 * read_bbt - [GENERIC] Read the bad block table starting from page 136 * read_bbt - [GENERIC] Read the bad block table starting from page
111 * @mtd: MTD device structure 137 * @mtd: MTD device structure
@@ -252,7 +278,7 @@ static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_de
252 * Create a bad block table by scanning the device 278 * Create a bad block table by scanning the device
253 * for the given good/bad block identify pattern 279 * for the given good/bad block identify pattern
254 */ 280 */
255static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip) 281static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
256{ 282{
257 struct nand_chip *this = mtd->priv; 283 struct nand_chip *this = mtd->priv;
258 int i, j, numblocks, len, scanlen; 284 int i, j, numblocks, len, scanlen;
@@ -270,9 +296,17 @@ static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
270 else 296 else
271 len = 1; 297 len = 1;
272 } 298 }
273 scanlen = mtd->oobblock + mtd->oobsize; 299
274 readlen = len * mtd->oobblock; 300 if (!(bd->options & NAND_BBT_SCANEMPTY)) {
275 ooblen = len * mtd->oobsize; 301 /* We need only read few bytes from the OOB area */
302 scanlen = ooblen = 0;
303 readlen = bd->len;
304 } else {
305 /* Full page content should be read */
306 scanlen = mtd->oobblock + mtd->oobsize;
307 readlen = len * mtd->oobblock;
308 ooblen = len * mtd->oobsize;
309 }
276 310
277 if (chip == -1) { 311 if (chip == -1) {
278 /* Note that numblocks is 2 * (real numblocks) here, see i+=2 below as it 312 /* Note that numblocks is 2 * (real numblocks) here, see i+=2 below as it
@@ -284,7 +318,7 @@ static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
284 if (chip >= this->numchips) { 318 if (chip >= this->numchips) {
285 printk (KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n", 319 printk (KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n",
286 chip + 1, this->numchips); 320 chip + 1, this->numchips);
287 return; 321 return -EINVAL;
288 } 322 }
289 numblocks = this->chipsize >> (this->bbt_erase_shift - 1); 323 numblocks = this->chipsize >> (this->bbt_erase_shift - 1);
290 startblock = chip * numblocks; 324 startblock = chip * numblocks;
@@ -293,18 +327,41 @@ static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
293 } 327 }
294 328
295 for (i = startblock; i < numblocks;) { 329 for (i = startblock; i < numblocks;) {
296 nand_read_raw (mtd, buf, from, readlen, ooblen); 330 int ret;
331
332 if (bd->options & NAND_BBT_SCANEMPTY)
333 if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen)))
334 return ret;
335
297 for (j = 0; j < len; j++) { 336 for (j = 0; j < len; j++) {
298 if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { 337 if (!(bd->options & NAND_BBT_SCANEMPTY)) {
299 this->bbt[i >> 3] |= 0x03 << (i & 0x6); 338 size_t retlen;
300 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 339
301 i >> 1, (unsigned int) from); 340 /* No need to read pages fully, just read required OOB bytes */
302 break; 341 ret = mtd->read_oob(mtd, from + j * mtd->oobblock + bd->offs,
342 readlen, &retlen, &buf[0]);
343 if (ret)
344 return ret;
345
346 if (check_short_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
347 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
348 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
349 i >> 1, (unsigned int) from);
350 break;
351 }
352 } else {
353 if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
354 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
355 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
356 i >> 1, (unsigned int) from);
357 break;
358 }
303 } 359 }
304 } 360 }
305 i += 2; 361 i += 2;
306 from += (1 << this->bbt_erase_shift); 362 from += (1 << this->bbt_erase_shift);
307 } 363 }
364 return 0;
308} 365}
309 366
310/** 367/**
@@ -589,14 +646,12 @@ write:
589 * The function creates a memory based bbt by scanning the device 646 * The function creates a memory based bbt by scanning the device
590 * for manufacturer / software marked good / bad blocks 647 * for manufacturer / software marked good / bad blocks
591*/ 648*/
592static int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) 649static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
593{ 650{
594 struct nand_chip *this = mtd->priv; 651 struct nand_chip *this = mtd->priv;
595 652
596 /* Ensure that we only scan for the pattern and nothing else */ 653 bd->options &= ~NAND_BBT_SCANEMPTY;
597 bd->options = 0; 654 return create_bbt (mtd, this->data_buf, bd, -1);
598 create_bbt (mtd, this->data_buf, bd, -1);
599 return 0;
600} 655}
601 656
602/** 657/**
@@ -808,8 +863,14 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
808 /* If no primary table decriptor is given, scan the device 863 /* If no primary table decriptor is given, scan the device
809 * to build a memory based bad block table 864 * to build a memory based bad block table
810 */ 865 */
811 if (!td) 866 if (!td) {
812 return nand_memory_bbt(mtd, bd); 867 if ((res = nand_memory_bbt(mtd, bd))) {
868 printk (KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n");
869 kfree (this->bbt);
870 this->bbt = NULL;
871 }
872 return res;
873 }
813 874
814 /* Allocate a temporary buffer for one eraseblock incl. oob */ 875 /* Allocate a temporary buffer for one eraseblock incl. oob */
815 len = (1 << this->bbt_erase_shift); 876 len = (1 << this->bbt_erase_shift);
@@ -904,14 +965,11 @@ out:
904} 965}
905 966
906/* Define some generic bad / good block scan pattern which are used 967/* Define some generic bad / good block scan pattern which are used
907 * while scanning a device for factory marked good / bad blocks 968 * while scanning a device for factory marked good / bad blocks. */
908 *
909 * The memory based patterns just
910 */
911static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; 969static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
912 970
913static struct nand_bbt_descr smallpage_memorybased = { 971static struct nand_bbt_descr smallpage_memorybased = {
914 .options = 0, 972 .options = NAND_BBT_SCAN2NDPAGE,
915 .offs = 5, 973 .offs = 5,
916 .len = 1, 974 .len = 1,
917 .pattern = scan_ff_pattern 975 .pattern = scan_ff_pattern
@@ -1042,7 +1100,7 @@ int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt)
1042 res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03; 1100 res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
1043 1101
1044 DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n", 1102 DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
1045 (unsigned int)offs, res, block >> 1); 1103 (unsigned int)offs, block >> 1, res);
1046 1104
1047 switch ((int)res) { 1105 switch ((int)res) {
1048 case 0x00: return 0; 1106 case 0x00: return 0;
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index 2d8c4321275b..efe246961b69 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -2,8 +2,8 @@
2 * drivers/mtd/nandids.c 2 * drivers/mtd/nandids.c
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.10 2004/05/26 13:40:12 gleixner Exp $ 6 * $Id: nand_ids.c,v 1.14 2005/06/23 09:38:50 gleixner Exp $
7 * 7 *
8 * 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
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -56,17 +56,24 @@ struct nand_flash_dev nand_flash_ids[] = {
56 {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16}, 56 {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
57 57
58 {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0}, 58 {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0},
59 {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0},
59 {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0}, 60 {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0},
60 {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16}, 61 {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16},
62 {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},
61 {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16}, 63 {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
64 {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},
62 65
63 {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0}, 66 {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0},
64 67
65 {"NAND 512MiB 3,3V 8-bit", 0xDC, 512, 512, 0x4000, 0},
66
67 /* These are the new chips with large page size. The pagesize 68 /* These are the new chips with large page size. The pagesize
68 * and the erasesize is determined from the extended id bytes 69 * and the erasesize is determined from the extended id bytes
69 */ 70 */
71 /*512 Megabit */
72 {"NAND 64MiB 1,8V 8-bit", 0xA2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
73 {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
74 {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
75 {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
76
70 /* 1 Gigabit */ 77 /* 1 Gigabit */
71 {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 78 {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
72 {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 79 {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
@@ -103,7 +110,7 @@ struct nand_flash_dev nand_flash_ids[] = {
103 * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go 110 * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go
104 * There are more speed improvements for reads and writes possible, but not implemented now 111 * There are more speed improvements for reads and writes possible, but not implemented now
105 */ 112 */
106 {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY}, 113 {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},
107 114
108 {NULL,} 115 {NULL,}
109}; 116};
@@ -118,6 +125,7 @@ struct nand_manufacturers nand_manuf_ids[] = {
118 {NAND_MFR_NATIONAL, "National"}, 125 {NAND_MFR_NATIONAL, "National"},
119 {NAND_MFR_RENESAS, "Renesas"}, 126 {NAND_MFR_RENESAS, "Renesas"},
120 {NAND_MFR_STMICRO, "ST Micro"}, 127 {NAND_MFR_STMICRO, "ST Micro"},
128 {NAND_MFR_HYNIX, "Hynix"},
121 {0x0, "Unknown"} 129 {0x0, "Unknown"}
122}; 130};
123 131
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index 13feefd7d8ca..754b6ed7ce14 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -22,7 +22,7 @@
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 * 24 *
25 * $Id: nandsim.c,v 1.7 2004/12/06 11:53:06 dedekind Exp $ 25 * $Id: nandsim.c,v 1.8 2005/03/19 15:33:56 dedekind Exp $
26 */ 26 */
27 27
28#include <linux/config.h> 28#include <linux/config.h>
@@ -1484,33 +1484,6 @@ ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
1484} 1484}
1485 1485
1486/* 1486/*
1487 * Having only NAND chip IDs we call nand_scan which detects NAND flash
1488 * parameters and then calls scan_bbt in order to scan/find/build the
1489 * NAND flash bad block table. But since at that moment the NAND flash
1490 * image isn't allocated in the simulator, errors arise. To avoid this
1491 * we redefine the scan_bbt callback and initialize the nandsim structure
1492 * before the flash media scanning.
1493 */
1494int ns_scan_bbt(struct mtd_info *mtd)
1495{
1496 struct nand_chip *chip = (struct nand_chip *)mtd->priv;
1497 struct nandsim *ns = (struct nandsim *)(chip->priv);
1498 int retval;
1499
1500 if (!NS_IS_INITIALIZED(ns))
1501 if ((retval = init_nandsim(mtd)) != 0) {
1502 NS_ERR("scan_bbt: can't initialize the nandsim structure\n");
1503 return retval;
1504 }
1505 if ((retval = nand_default_bbt(mtd)) != 0) {
1506 free_nandsim(ns);
1507 return retval;
1508 }
1509
1510 return 0;
1511}
1512
1513/*
1514 * Module initialization function 1487 * Module initialization function
1515 */ 1488 */
1516int __init ns_init_module(void) 1489int __init ns_init_module(void)
@@ -1544,7 +1517,6 @@ int __init ns_init_module(void)
1544 chip->hwcontrol = ns_hwcontrol; 1517 chip->hwcontrol = ns_hwcontrol;
1545 chip->read_byte = ns_nand_read_byte; 1518 chip->read_byte = ns_nand_read_byte;
1546 chip->dev_ready = ns_device_ready; 1519 chip->dev_ready = ns_device_ready;
1547 chip->scan_bbt = ns_scan_bbt;
1548 chip->write_byte = ns_nand_write_byte; 1520 chip->write_byte = ns_nand_write_byte;
1549 chip->write_buf = ns_nand_write_buf; 1521 chip->write_buf = ns_nand_write_buf;
1550 chip->read_buf = ns_nand_read_buf; 1522 chip->read_buf = ns_nand_read_buf;
@@ -1552,6 +1524,7 @@ int __init ns_init_module(void)
1552 chip->write_word = ns_nand_write_word; 1524 chip->write_word = ns_nand_write_word;
1553 chip->read_word = ns_nand_read_word; 1525 chip->read_word = ns_nand_read_word;
1554 chip->eccmode = NAND_ECC_SOFT; 1526 chip->eccmode = NAND_ECC_SOFT;
1527 chip->options |= NAND_SKIP_BBTSCAN;
1555 1528
1556 /* 1529 /*
1557 * Perform minimum nandsim structure initialization to handle 1530 * Perform minimum nandsim structure initialization to handle
@@ -1580,6 +1553,16 @@ int __init ns_init_module(void)
1580 goto error; 1553 goto error;
1581 } 1554 }
1582 1555
1556 if ((retval = init_nandsim(nsmtd)) != 0) {
1557 NS_ERR("scan_bbt: can't initialize the nandsim structure\n");
1558 goto error;
1559 }
1560
1561 if ((retval = nand_default_bbt(nsmtd)) != 0) {
1562 free_nandsim(nand);
1563 goto error;
1564 }
1565
1583 /* Register NAND as one big partition */ 1566 /* Register NAND as one big partition */
1584 add_mtd_partitions(nsmtd, &nand->part, 1); 1567 add_mtd_partitions(nsmtd, &nand->part, 1);
1585 1568
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c
index 02305a2adca7..031051cbde76 100644
--- a/drivers/mtd/nand/rtc_from4.c
+++ b/drivers/mtd/nand/rtc_from4.c
@@ -6,7 +6,7 @@
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.7 2004/11/04 12:53:10 gleixner Exp $ 9 * $Id: rtc_from4.c,v 1.9 2005/01/24 20:40:11 dmarlin Exp $
10 * 10 *
11 * 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
12 * 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
@@ -83,13 +83,18 @@ static struct mtd_info *rtc_from4_mtd = NULL;
83#define RTC_FROM4_RS_ECC_CHK (RTC_FROM4_NAND_ADDR_FPGA | 0x00000070) 83#define RTC_FROM4_RS_ECC_CHK (RTC_FROM4_NAND_ADDR_FPGA | 0x00000070)
84#define RTC_FROM4_RS_ECC_CHK_ERROR (1 << 7) 84#define RTC_FROM4_RS_ECC_CHK_ERROR (1 << 7)
85 85
86#define ERR_STAT_ECC_AVAILABLE 0x20
87
86/* Undefine for software ECC */ 88/* Undefine for software ECC */
87#define RTC_FROM4_HWECC 1 89#define RTC_FROM4_HWECC 1
88 90
91/* Define as 1 for no virtual erase blocks (in JFFS2) */
92#define RTC_FROM4_NO_VIRTBLOCKS 0
93
89/* 94/*
90 * Module stuff 95 * Module stuff
91 */ 96 */
92static void __iomem *rtc_from4_fio_base = P2SEGADDR(RTC_FROM4_FIO_BASE); 97static void __iomem *rtc_from4_fio_base = (void *)P2SEGADDR(RTC_FROM4_FIO_BASE);
93 98
94const static struct mtd_partition partition_info[] = { 99const static struct mtd_partition partition_info[] = {
95 { 100 {
@@ -267,7 +272,6 @@ static void rtc_from4_nand_select_chip(struct mtd_info *mtd, int chip)
267} 272}
268 273
269 274
270
271/* 275/*
272 * rtc_from4_nand_device_ready - hardware specific ready/busy check 276 * rtc_from4_nand_device_ready - hardware specific ready/busy check
273 * @mtd: MTD device structure 277 * @mtd: MTD device structure
@@ -286,6 +290,40 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
286 290
287} 291}
288 292
293
294/*
295 * deplete - code to perform device recovery in case there was a power loss
296 * @mtd: MTD device structure
297 * @chip: Chip to select (0 == slot 3, 1 == slot 4)
298 *
299 * If there was a sudden loss of power during an erase operation, a
300 * "device recovery" operation must be performed when power is restored
301 * to ensure correct operation. This routine performs the required steps
302 * for the requested chip.
303 *
304 * See page 86 of the data sheet for details.
305 *
306 */
307static void deplete(struct mtd_info *mtd, int chip)
308{
309 struct nand_chip *this = mtd->priv;
310
311 /* wait until device is ready */
312 while (!this->dev_ready(mtd));
313
314 this->select_chip(mtd, chip);
315
316 /* Send the commands for device recovery, phase 1 */
317 this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000);
318 this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1);
319
320 /* Send the commands for device recovery, phase 2 */
321 this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0004);
322 this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1);
323
324}
325
326
289#ifdef RTC_FROM4_HWECC 327#ifdef RTC_FROM4_HWECC
290/* 328/*
291 * rtc_from4_enable_hwecc - hardware specific hardware ECC enable function 329 * rtc_from4_enable_hwecc - hardware specific hardware ECC enable function
@@ -329,6 +367,7 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
329 367
330} 368}
331 369
370
332/* 371/*
333 * rtc_from4_calculate_ecc - hardware specific code to read ECC code 372 * rtc_from4_calculate_ecc - hardware specific code to read ECC code
334 * @mtd: MTD device structure 373 * @mtd: MTD device structure
@@ -356,6 +395,7 @@ static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_c
356 ecc_code[7] |= 0x0f; /* set the last four bits (not used) */ 395 ecc_code[7] |= 0x0f; /* set the last four bits (not used) */
357} 396}
358 397
398
359/* 399/*
360 * rtc_from4_correct_data - hardware specific code to correct data using ECC code 400 * rtc_from4_correct_data - hardware specific code to correct data using ECC code
361 * @mtd: MTD device structure 401 * @mtd: MTD device structure
@@ -365,16 +405,14 @@ static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_c
365 * 405 *
366 * The FPGA tells us fast, if there's an error or not. If no, we go back happy 406 * The FPGA tells us fast, if there's an error or not. If no, we go back happy
367 * else we read the ecc results from the fpga and call the rs library to decode 407 * else we read the ecc results from the fpga and call the rs library to decode
368 * and hopefully correct the error 408 * and hopefully correct the error.
369 * 409 *
370 * For now I use the code, which we read from the FLASH to use the RS lib,
371 * as the syndrom conversion has a unresolved issue.
372 */ 410 */
373static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2) 411static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2)
374{ 412{
375 int i, j, res; 413 int i, j, res;
376 unsigned short status; 414 unsigned short status;
377 uint16_t par[6], syn[6], tmp; 415 uint16_t par[6], syn[6];
378 uint8_t ecc[8]; 416 uint8_t ecc[8];
379 volatile unsigned short *rs_ecc; 417 volatile unsigned short *rs_ecc;
380 418
@@ -416,15 +454,86 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
416 } 454 }
417 455
418 /* Let the library code do its magic.*/ 456 /* Let the library code do its magic.*/
419 res = decode_rs8(rs_decoder, buf, par, 512, syn, 0, NULL, 0xff, NULL); 457 res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL);
420 if (res > 0) { 458 if (res > 0) {
421 DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " 459 DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: "
422 "ECC corrected %d errors on read\n", res); 460 "ECC corrected %d errors on read\n", res);
423 } 461 }
424 return res; 462 return res;
425} 463}
464
465
466/**
467 * rtc_from4_errstat - perform additional error status checks
468 * @mtd: MTD device structure
469 * @this: NAND chip structure
470 * @state: state or the operation
471 * @status: status code returned from read status
472 * @page: startpage inside the chip, must be called with (page & this->pagemask)
473 *
474 * Perform additional error status checks on erase and write failures
475 * to determine if errors are correctable. For this device, correctable
476 * 1-bit errors on erase and write are considered acceptable.
477 *
478 * note: see pages 34..37 of data sheet for details.
479 *
480 */
481static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page)
482{
483 int er_stat=0;
484 int rtn, retlen;
485 size_t len;
486 uint8_t *buf;
487 int i;
488
489 this->cmdfunc (mtd, NAND_CMD_STATUS_CLEAR, -1, -1);
490
491 if (state == FL_ERASING) {
492 for (i=0; i<4; i++) {
493 if (status & 1<<(i+1)) {
494 this->cmdfunc (mtd, (NAND_CMD_STATUS_ERROR + i + 1), -1, -1);
495 rtn = this->read_byte(mtd);
496 this->cmdfunc (mtd, NAND_CMD_STATUS_RESET, -1, -1);
497 if (!(rtn & ERR_STAT_ECC_AVAILABLE)) {
498 er_stat |= 1<<(i+1); /* err_ecc_not_avail */
499 }
500 }
501 }
502 } else if (state == FL_WRITING) {
503 /* single bank write logic */
504 this->cmdfunc (mtd, NAND_CMD_STATUS_ERROR, -1, -1);
505 rtn = this->read_byte(mtd);
506 this->cmdfunc (mtd, NAND_CMD_STATUS_RESET, -1, -1);
507 if (!(rtn & ERR_STAT_ECC_AVAILABLE)) {
508 er_stat |= 1<<1; /* err_ecc_not_avail */
509 } else {
510 len = mtd->oobblock;
511 buf = kmalloc (len, GFP_KERNEL);
512 if (!buf) {
513 printk (KERN_ERR "rtc_from4_errstat: Out of memory!\n");
514 er_stat = 1; /* if we can't check, assume failed */
515 } else {
516 /* recovery read */
517 /* page read */
518 rtn = nand_do_read_ecc (mtd, page, len, &retlen, buf, NULL, this->autooob, 1);
519 if (rtn) { /* if read failed or > 1-bit error corrected */
520 er_stat |= 1<<1; /* ECC read failed */
521 }
522 kfree(buf);
523 }
524 }
525 }
526
527 rtn = status;
528 if (er_stat == 0) { /* if ECC is available */
529 rtn = (status & ~NAND_STATUS_FAIL); /* clear the error bit */
530 }
531
532 return rtn;
533}
426#endif 534#endif
427 535
536
428/* 537/*
429 * Main initialization routine 538 * Main initialization routine
430 */ 539 */
@@ -432,6 +541,7 @@ int __init rtc_from4_init (void)
432{ 541{
433 struct nand_chip *this; 542 struct nand_chip *this;
434 unsigned short bcr1, bcr2, wcr2; 543 unsigned short bcr1, bcr2, wcr2;
544 int i;
435 545
436 /* Allocate memory for MTD device structure and private data */ 546 /* Allocate memory for MTD device structure and private data */
437 rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof (struct nand_chip), 547 rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof (struct nand_chip),
@@ -483,6 +593,8 @@ int __init rtc_from4_init (void)
483 593
484 this->eccmode = NAND_ECC_HW8_512; 594 this->eccmode = NAND_ECC_HW8_512;
485 this->options |= NAND_HWECC_SYNDROME; 595 this->options |= NAND_HWECC_SYNDROME;
596 /* return the status of extra status and ECC checks */
597 this->errstat = rtc_from4_errstat;
486 /* set the nand_oobinfo to support FPGA H/W error detection */ 598 /* set the nand_oobinfo to support FPGA H/W error detection */
487 this->autooob = &rtc_from4_nand_oobinfo; 599 this->autooob = &rtc_from4_nand_oobinfo;
488 this->enable_hwecc = rtc_from4_enable_hwecc; 600 this->enable_hwecc = rtc_from4_enable_hwecc;
@@ -504,6 +616,18 @@ int __init rtc_from4_init (void)
504 return -ENXIO; 616 return -ENXIO;
505 } 617 }
506 618
619 /* Perform 'device recovery' for each chip in case there was a power loss. */
620 for (i=0; i < this->numchips; i++) {
621 deplete(rtc_from4_mtd, i);
622 }
623
624#if RTC_FROM4_NO_VIRTBLOCKS
625 /* use a smaller erase block to minimize wasted space when a block is bad */
626 /* note: this uses eight times as much RAM as using the default and makes */
627 /* mounts take four times as long. */
628 rtc_from4_mtd->flags |= MTD_NO_VIRTBLOCKS;
629#endif
630
507 /* Register the partitions */ 631 /* Register the partitions */
508 add_mtd_partitions(rtc_from4_mtd, partition_info, NUM_PARTITIONS); 632 add_mtd_partitions(rtc_from4_mtd, partition_info, NUM_PARTITIONS);
509 633
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index d05e9b97947d..630a9c0edf31 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -1,17 +1,23 @@
1/* linux/drivers/mtd/nand/s3c2410.c 1/* linux/drivers/mtd/nand/s3c2410.c
2 * 2 *
3 * Copyright (c) 2004 Simtec Electronics 3 * Copyright (c) 2004,2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * http://www.simtec.co.uk/products/SWLINUX/
5 * Ben Dooks <ben@simtec.co.uk>
5 * 6 *
6 * Samsung S3C2410 NAND driver 7 * Samsung S3C2410/S3C240 NAND driver
7 * 8 *
8 * Changelog: 9 * Changelog:
9 * 21-Sep-2004 BJD Initial version 10 * 21-Sep-2004 BJD Initial version
10 * 23-Sep-2004 BJD Mulitple device support 11 * 23-Sep-2004 BJD Mulitple device support
11 * 28-Sep-2004 BJD Fixed ECC placement for Hardware mode 12 * 28-Sep-2004 BJD Fixed ECC placement for Hardware mode
12 * 12-Oct-2004 BJD Fixed errors in use of platform data 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
13 * 19 *
14 * $Id: s3c2410.c,v 1.7 2005/01/05 18:05:14 dwmw2 Exp $ 20 * $Id: s3c2410.c,v 1.13 2005/06/20 11:48:21 bjd Exp $
15 * 21 *
16 * This program is free software; you can redistribute it and/or modify 22 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by 23 * it under the terms of the GNU General Public License as published by
@@ -69,10 +75,10 @@ static int hardware_ecc = 0;
69 */ 75 */
70 76
71static struct nand_oobinfo nand_hw_eccoob = { 77static struct nand_oobinfo nand_hw_eccoob = {
72 .useecc = MTD_NANDECC_AUTOPLACE, 78 .useecc = MTD_NANDECC_AUTOPLACE,
73 .eccbytes = 3, 79 .eccbytes = 3,
74 .eccpos = {0, 1, 2 }, 80 .eccpos = {0, 1, 2 },
75 .oobfree = { {8, 8} } 81 .oobfree = { {8, 8} }
76}; 82};
77 83
78/* controller and mtd information */ 84/* controller and mtd information */
@@ -99,8 +105,10 @@ struct s3c2410_nand_info {
99 struct device *device; 105 struct device *device;
100 struct resource *area; 106 struct resource *area;
101 struct clk *clk; 107 struct clk *clk;
102 void *regs; 108 void __iomem *regs;
103 int mtd_count; 109 int mtd_count;
110
111 unsigned char is_s3c2440;
104}; 112};
105 113
106/* conversion functions */ 114/* conversion functions */
@@ -165,12 +173,12 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
165 /* calculate the timing information for the controller */ 173 /* calculate the timing information for the controller */
166 174
167 if (plat != NULL) { 175 if (plat != NULL) {
168 tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 8); 176 tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4);
169 twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8); 177 twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);
170 twrph1 = s3c2410_nand_calc_rate(plat->twrph1, clkrate, 8); 178 twrph1 = s3c2410_nand_calc_rate(plat->twrph1, clkrate, 8);
171 } else { 179 } else {
172 /* default timings */ 180 /* default timings */
173 tacls = 8; 181 tacls = 4;
174 twrph0 = 8; 182 twrph0 = 8;
175 twrph1 = 8; 183 twrph1 = 8;
176 } 184 }
@@ -185,10 +193,16 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
185 to_ns(twrph0, clkrate), 193 to_ns(twrph0, clkrate),
186 to_ns(twrph1, clkrate)); 194 to_ns(twrph1, clkrate));
187 195
188 cfg = S3C2410_NFCONF_EN; 196 if (!info->is_s3c2440) {
189 cfg |= S3C2410_NFCONF_TACLS(tacls-1); 197 cfg = S3C2410_NFCONF_EN;
190 cfg |= S3C2410_NFCONF_TWRPH0(twrph0-1); 198 cfg |= S3C2410_NFCONF_TACLS(tacls-1);
191 cfg |= S3C2410_NFCONF_TWRPH1(twrph1-1); 199 cfg |= S3C2410_NFCONF_TWRPH0(twrph0-1);
200 cfg |= S3C2410_NFCONF_TWRPH1(twrph1-1);
201 } else {
202 cfg = S3C2440_NFCONF_TACLS(tacls-1);
203 cfg |= S3C2440_NFCONF_TWRPH0(twrph0-1);
204 cfg |= S3C2440_NFCONF_TWRPH1(twrph1-1);
205 }
192 206
193 pr_debug(PFX "NF_CONF is 0x%lx\n", cfg); 207 pr_debug(PFX "NF_CONF is 0x%lx\n", cfg);
194 208
@@ -203,15 +217,20 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
203 struct s3c2410_nand_info *info; 217 struct s3c2410_nand_info *info;
204 struct s3c2410_nand_mtd *nmtd; 218 struct s3c2410_nand_mtd *nmtd;
205 struct nand_chip *this = mtd->priv; 219 struct nand_chip *this = mtd->priv;
220 void __iomem *reg;
206 unsigned long cur; 221 unsigned long cur;
222 unsigned long bit;
207 223
208 nmtd = this->priv; 224 nmtd = this->priv;
209 info = nmtd->info; 225 info = nmtd->info;
210 226
211 cur = readl(info->regs + S3C2410_NFCONF); 227 bit = (info->is_s3c2440) ? S3C2440_NFCONT_nFCE : S3C2410_NFCONF_nFCE;
228 reg = info->regs+((info->is_s3c2440) ? S3C2440_NFCONT:S3C2410_NFCONF);
229
230 cur = readl(reg);
212 231
213 if (chip == -1) { 232 if (chip == -1) {
214 cur |= S3C2410_NFCONF_nFCE; 233 cur |= bit;
215 } else { 234 } else {
216 if (chip > nmtd->set->nr_chips) { 235 if (chip > nmtd->set->nr_chips) {
217 printk(KERN_ERR PFX "chip %d out of range\n", chip); 236 printk(KERN_ERR PFX "chip %d out of range\n", chip);
@@ -223,143 +242,76 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
223 (info->platform->select_chip)(nmtd->set, chip); 242 (info->platform->select_chip)(nmtd->set, chip);
224 } 243 }
225 244
226 cur &= ~S3C2410_NFCONF_nFCE; 245 cur &= ~bit;
227 } 246 }
228 247
229 writel(cur, info->regs + S3C2410_NFCONF); 248 writel(cur, reg);
230} 249}
231 250
232/* command and control functions */ 251/* command and control functions
252 *
253 * Note, these all use tglx's method of changing the IO_ADDR_W field
254 * to make the code simpler, and use the nand layer's code to issue the
255 * command and address sequences via the proper IO ports.
256 *
257*/
233 258
234static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd) 259static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd)
235{ 260{
236 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 261 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
237 unsigned long cur; 262 struct nand_chip *chip = mtd->priv;
238 263
239 switch (cmd) { 264 switch (cmd) {
240 case NAND_CTL_SETNCE: 265 case NAND_CTL_SETNCE:
241 cur = readl(info->regs + S3C2410_NFCONF);
242 cur &= ~S3C2410_NFCONF_nFCE;
243 writel(cur, info->regs + S3C2410_NFCONF);
244 break;
245
246 case NAND_CTL_CLRNCE: 266 case NAND_CTL_CLRNCE:
247 cur = readl(info->regs + S3C2410_NFCONF); 267 printk(KERN_ERR "%s: called for NCE\n", __FUNCTION__);
248 cur |= S3C2410_NFCONF_nFCE;
249 writel(cur, info->regs + S3C2410_NFCONF);
250 break; 268 break;
251 269
252 /* we don't need to implement these */
253 case NAND_CTL_SETCLE: 270 case NAND_CTL_SETCLE:
254 case NAND_CTL_CLRCLE: 271 chip->IO_ADDR_W = info->regs + S3C2410_NFCMD;
272 break;
273
255 case NAND_CTL_SETALE: 274 case NAND_CTL_SETALE:
256 case NAND_CTL_CLRALE: 275 chip->IO_ADDR_W = info->regs + S3C2410_NFADDR;
257 pr_debug(PFX "s3c2410_nand_hwcontrol(%d) unusedn", cmd); 276 break;
277
278 /* NAND_CTL_CLRCLE: */
279 /* NAND_CTL_CLRALE: */
280 default:
281 chip->IO_ADDR_W = info->regs + S3C2410_NFDATA;
258 break; 282 break;
259 } 283 }
260} 284}
261 285
262/* s3c2410_nand_command 286/* command and control functions */
263 *
264 * This function implements sending commands and the relevant address
265 * information to the chip, via the hardware controller. Since the
266 * S3C2410 generates the correct ALE/CLE signaling automatically, we
267 * do not need to use hwcontrol.
268*/
269 287
270static void s3c2410_nand_command (struct mtd_info *mtd, unsigned command, 288static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd)
271 int column, int page_addr)
272{ 289{
273 register struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 290 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
274 register struct nand_chip *this = mtd->priv; 291 struct nand_chip *chip = mtd->priv;
275 292
276 /* 293 switch (cmd) {
277 * Write out the command to the device. 294 case NAND_CTL_SETNCE:
278 */ 295 case NAND_CTL_CLRNCE:
279 if (command == NAND_CMD_SEQIN) { 296 printk(KERN_ERR "%s: called for NCE\n", __FUNCTION__);
280 int readcmd; 297 break;
281
282 if (column >= mtd->oobblock) {
283 /* OOB area */
284 column -= mtd->oobblock;
285 readcmd = NAND_CMD_READOOB;
286 } else if (column < 256) {
287 /* First 256 bytes --> READ0 */
288 readcmd = NAND_CMD_READ0;
289 } else {
290 column -= 256;
291 readcmd = NAND_CMD_READ1;
292 }
293
294 writeb(readcmd, info->regs + S3C2410_NFCMD);
295 }
296 writeb(command, info->regs + S3C2410_NFCMD);
297 298
298 /* Set ALE and clear CLE to start address cycle */ 299 case NAND_CTL_SETCLE:
300 chip->IO_ADDR_W = info->regs + S3C2440_NFCMD;
301 break;
299 302
300 if (column != -1 || page_addr != -1) { 303 case NAND_CTL_SETALE:
304 chip->IO_ADDR_W = info->regs + S3C2440_NFADDR;
305 break;
301 306
302 /* Serially input address */ 307 /* NAND_CTL_CLRCLE: */
303 if (column != -1) { 308 /* NAND_CTL_CLRALE: */
304 /* Adjust columns for 16 bit buswidth */
305 if (this->options & NAND_BUSWIDTH_16)
306 column >>= 1;
307 writeb(column, info->regs + S3C2410_NFADDR);
308 }
309 if (page_addr != -1) {
310 writeb((unsigned char) (page_addr), info->regs + S3C2410_NFADDR);
311 writeb((unsigned char) (page_addr >> 8), info->regs + S3C2410_NFADDR);
312 /* One more address cycle for higher density devices */
313 if (this->chipsize & 0x0c000000)
314 writeb((unsigned char) ((page_addr >> 16) & 0x0f),
315 info->regs + S3C2410_NFADDR);
316 }
317 /* Latch in address */
318 }
319
320 /*
321 * program and erase have their own busy handlers
322 * status and sequential in needs no delay
323 */
324 switch (command) {
325
326 case NAND_CMD_PAGEPROG:
327 case NAND_CMD_ERASE1:
328 case NAND_CMD_ERASE2:
329 case NAND_CMD_SEQIN:
330 case NAND_CMD_STATUS:
331 return;
332
333 case NAND_CMD_RESET:
334 if (this->dev_ready)
335 break;
336
337 udelay(this->chip_delay);
338 writeb(NAND_CMD_STATUS, info->regs + S3C2410_NFCMD);
339
340 while ( !(this->read_byte(mtd) & 0x40));
341 return;
342
343 /* This applies to read commands */
344 default: 309 default:
345 /* 310 chip->IO_ADDR_W = info->regs + S3C2440_NFDATA;
346 * If we don't have access to the busy pin, we apply the given 311 break;
347 * command delay
348 */
349 if (!this->dev_ready) {
350 udelay (this->chip_delay);
351 return;
352 }
353 } 312 }
354
355 /* Apply this short delay always to ensure that we do wait tWB in
356 * any case on any machine. */
357 ndelay (100);
358 /* wait until command is processed */
359 while (!this->dev_ready(mtd));
360} 313}
361 314
362
363/* s3c2410_nand_devready() 315/* s3c2410_nand_devready()
364 * 316 *
365 * returns 0 if the nand is busy, 1 if it is ready 317 * returns 0 if the nand is busy, 1 if it is ready
@@ -369,9 +321,12 @@ static int s3c2410_nand_devready(struct mtd_info *mtd)
369{ 321{
370 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 322 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
371 323
324 if (info->is_s3c2440)
325 return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY;
372 return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY; 326 return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY;
373} 327}
374 328
329
375/* ECC handling functions */ 330/* ECC handling functions */
376 331
377static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, 332static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
@@ -394,6 +349,12 @@ static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
394 return -1; 349 return -1;
395} 350}
396 351
352/* ECC functions
353 *
354 * These allow the s3c2410 and s3c2440 to use the controller's ECC
355 * generator block to ECC the data as it passes through]
356*/
357
397static void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode) 358static void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
398{ 359{
399 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 360 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
@@ -404,6 +365,15 @@ static void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
404 writel(ctrl, info->regs + S3C2410_NFCONF); 365 writel(ctrl, info->regs + S3C2410_NFCONF);
405} 366}
406 367
368static void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)
369{
370 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
371 unsigned long ctrl;
372
373 ctrl = readl(info->regs + S3C2440_NFCONT);
374 writel(ctrl | S3C2440_NFCONT_INITECC, info->regs + S3C2440_NFCONT);
375}
376
407static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, 377static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd,
408 const u_char *dat, u_char *ecc_code) 378 const u_char *dat, u_char *ecc_code)
409{ 379{
@@ -420,7 +390,26 @@ static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd,
420} 390}
421 391
422 392
423/* over-ride the standard functions for a little more speed? */ 393static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd,
394 const u_char *dat, u_char *ecc_code)
395{
396 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
397 unsigned long ecc = readl(info->regs + S3C2440_NFMECC0);
398
399 ecc_code[0] = ecc;
400 ecc_code[1] = ecc >> 8;
401 ecc_code[2] = ecc >> 16;
402
403 pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n",
404 ecc_code[0], ecc_code[1], ecc_code[2]);
405
406 return 0;
407}
408
409
410/* over-ride the standard functions for a little more speed. We can
411 * use read/write block to move the data buffers to/from the controller
412*/
424 413
425static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) 414static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
426{ 415{
@@ -523,11 +512,10 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
523{ 512{
524 struct nand_chip *chip = &nmtd->chip; 513 struct nand_chip *chip = &nmtd->chip;
525 514
526 chip->IO_ADDR_R = (char *)info->regs + S3C2410_NFDATA; 515 chip->IO_ADDR_R = info->regs + S3C2410_NFDATA;
527 chip->IO_ADDR_W = (char *)info->regs + S3C2410_NFDATA; 516 chip->IO_ADDR_W = info->regs + S3C2410_NFDATA;
528 chip->hwcontrol = s3c2410_nand_hwcontrol; 517 chip->hwcontrol = s3c2410_nand_hwcontrol;
529 chip->dev_ready = s3c2410_nand_devready; 518 chip->dev_ready = s3c2410_nand_devready;
530 chip->cmdfunc = s3c2410_nand_command;
531 chip->write_buf = s3c2410_nand_write_buf; 519 chip->write_buf = s3c2410_nand_write_buf;
532 chip->read_buf = s3c2410_nand_read_buf; 520 chip->read_buf = s3c2410_nand_read_buf;
533 chip->select_chip = s3c2410_nand_select_chip; 521 chip->select_chip = s3c2410_nand_select_chip;
@@ -536,6 +524,12 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
536 chip->options = 0; 524 chip->options = 0;
537 chip->controller = &info->controller; 525 chip->controller = &info->controller;
538 526
527 if (info->is_s3c2440) {
528 chip->IO_ADDR_R = info->regs + S3C2440_NFDATA;
529 chip->IO_ADDR_W = info->regs + S3C2440_NFDATA;
530 chip->hwcontrol = s3c2440_nand_hwcontrol;
531 }
532
539 nmtd->info = info; 533 nmtd->info = info;
540 nmtd->mtd.priv = chip; 534 nmtd->mtd.priv = chip;
541 nmtd->set = set; 535 nmtd->set = set;
@@ -546,6 +540,11 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
546 chip->calculate_ecc = s3c2410_nand_calculate_ecc; 540 chip->calculate_ecc = s3c2410_nand_calculate_ecc;
547 chip->eccmode = NAND_ECC_HW3_512; 541 chip->eccmode = NAND_ECC_HW3_512;
548 chip->autooob = &nand_hw_eccoob; 542 chip->autooob = &nand_hw_eccoob;
543
544 if (info->is_s3c2440) {
545 chip->enable_hwecc = s3c2440_nand_enable_hwecc;
546 chip->calculate_ecc = s3c2440_nand_calculate_ecc;
547 }
549 } else { 548 } else {
550 chip->eccmode = NAND_ECC_SOFT; 549 chip->eccmode = NAND_ECC_SOFT;
551 } 550 }
@@ -559,7 +558,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
559 * nand layer to look for devices 558 * nand layer to look for devices
560*/ 559*/
561 560
562static int s3c2410_nand_probe(struct device *dev) 561static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
563{ 562{
564 struct platform_device *pdev = to_platform_device(dev); 563 struct platform_device *pdev = to_platform_device(dev);
565 struct s3c2410_platform_nand *plat = to_nand_plat(dev); 564 struct s3c2410_platform_nand *plat = to_nand_plat(dev);
@@ -585,6 +584,7 @@ static int s3c2410_nand_probe(struct device *dev)
585 dev_set_drvdata(dev, info); 584 dev_set_drvdata(dev, info);
586 585
587 spin_lock_init(&info->controller.lock); 586 spin_lock_init(&info->controller.lock);
587 init_waitqueue_head(&info->controller.wq);
588 588
589 /* get the clock source and enable it */ 589 /* get the clock source and enable it */
590 590
@@ -600,7 +600,8 @@ static int s3c2410_nand_probe(struct device *dev)
600 600
601 /* allocate and map the resource */ 601 /* allocate and map the resource */
602 602
603 res = pdev->resource; /* assume that the flash has one resource */ 603 /* currently we assume we have the one resource */
604 res = pdev->resource;
604 size = res->end - res->start + 1; 605 size = res->end - res->start + 1;
605 606
606 info->area = request_mem_region(res->start, size, pdev->name); 607 info->area = request_mem_region(res->start, size, pdev->name);
@@ -611,9 +612,10 @@ static int s3c2410_nand_probe(struct device *dev)
611 goto exit_error; 612 goto exit_error;
612 } 613 }
613 614
614 info->device = dev; 615 info->device = dev;
615 info->platform = plat; 616 info->platform = plat;
616 info->regs = ioremap(res->start, size); 617 info->regs = ioremap(res->start, size);
618 info->is_s3c2440 = is_s3c2440;
617 619
618 if (info->regs == NULL) { 620 if (info->regs == NULL) {
619 printk(KERN_ERR PFX "cannot reserve register region\n"); 621 printk(KERN_ERR PFX "cannot reserve register region\n");
@@ -678,6 +680,18 @@ static int s3c2410_nand_probe(struct device *dev)
678 return err; 680 return err;
679} 681}
680 682
683/* driver device registration */
684
685static int s3c2410_nand_probe(struct device *dev)
686{
687 return s3c24xx_nand_probe(dev, 0);
688}
689
690static int s3c2440_nand_probe(struct device *dev)
691{
692 return s3c24xx_nand_probe(dev, 1);
693}
694
681static struct device_driver s3c2410_nand_driver = { 695static struct device_driver s3c2410_nand_driver = {
682 .name = "s3c2410-nand", 696 .name = "s3c2410-nand",
683 .bus = &platform_bus_type, 697 .bus = &platform_bus_type,
@@ -685,14 +699,24 @@ static struct device_driver s3c2410_nand_driver = {
685 .remove = s3c2410_nand_remove, 699 .remove = s3c2410_nand_remove,
686}; 700};
687 701
702static struct device_driver s3c2440_nand_driver = {
703 .name = "s3c2440-nand",
704 .bus = &platform_bus_type,
705 .probe = s3c2440_nand_probe,
706 .remove = s3c2410_nand_remove,
707};
708
688static int __init s3c2410_nand_init(void) 709static int __init s3c2410_nand_init(void)
689{ 710{
690 printk("S3C2410 NAND Driver, (c) 2004 Simtec Electronics\n"); 711 printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n");
712
713 driver_register(&s3c2440_nand_driver);
691 return driver_register(&s3c2410_nand_driver); 714 return driver_register(&s3c2410_nand_driver);
692} 715}
693 716
694static void __exit s3c2410_nand_exit(void) 717static void __exit s3c2410_nand_exit(void)
695{ 718{
719 driver_unregister(&s3c2440_nand_driver);
696 driver_unregister(&s3c2410_nand_driver); 720 driver_unregister(&s3c2410_nand_driver);
697} 721}
698 722
@@ -701,4 +725,4 @@ module_exit(s3c2410_nand_exit);
701 725
702MODULE_LICENSE("GPL"); 726MODULE_LICENSE("GPL");
703MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 727MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
704MODULE_DESCRIPTION("S3C2410 MTD NAND driver"); 728MODULE_DESCRIPTION("S3C24XX MTD NAND driver");
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c
index 29572793334c..9853b87bb756 100755..100644
--- a/drivers/mtd/nand/sharpsl.c
+++ b/drivers/mtd/nand/sharpsl.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2004 Richard Purdie 4 * Copyright (C) 2004 Richard Purdie
5 * 5 *
6 * $Id: sharpsl.c,v 1.3 2005/01/03 14:53:50 rpurdie Exp $ 6 * $Id: sharpsl.c,v 1.4 2005/01/23 11:09:19 rpurdie Exp $
7 * 7 *
8 * Based on Sharp's NAND driver sharp_sl.c 8 * Based on Sharp's NAND driver sharp_sl.c
9 * 9 *
@@ -216,7 +216,7 @@ sharpsl_nand_init(void)
216 nr_partitions = DEFAULT_NUM_PARTITIONS; 216 nr_partitions = DEFAULT_NUM_PARTITIONS;
217 sharpsl_partition_info = sharpsl_nand_default_partition_info; 217 sharpsl_partition_info = sharpsl_nand_default_partition_info;
218 if (machine_is_poodle()) { 218 if (machine_is_poodle()) {
219 sharpsl_partition_info[1].size=22 * 1024 * 1024; 219 sharpsl_partition_info[1].size=30 * 1024 * 1024;
220 } else if (machine_is_corgi() || machine_is_shepherd()) { 220 } else if (machine_is_corgi() || machine_is_shepherd()) {
221 sharpsl_partition_info[1].size=25 * 1024 * 1024; 221 sharpsl_partition_info[1].size=25 * 1024 * 1024;
222 } else if (machine_is_husky()) { 222 } else if (machine_is_husky()) {
diff --git a/drivers/mtd/nand/tx4925ndfmc.c b/drivers/mtd/nand/tx4925ndfmc.c
deleted file mode 100644
index bba688830c9b..000000000000
--- a/drivers/mtd/nand/tx4925ndfmc.c
+++ /dev/null
@@ -1,416 +0,0 @@
1/*
2 * drivers/mtd/tx4925ndfmc.c
3 *
4 * Overview:
5 * This is a device driver for the NAND flash device found on the
6 * Toshiba RBTX4925 reference board, which is a SmartMediaCard. It supports
7 * 16MiB, 32MiB and 64MiB cards.
8 *
9 * Author: MontaVista Software, Inc. source@mvista.com
10 *
11 * Derived from drivers/mtd/autcpu12.c
12 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
13 *
14 * $Id: tx4925ndfmc.c,v 1.5 2004/10/05 13:50:20 gleixner Exp $
15 *
16 * Copyright (C) 2001 Toshiba Corporation
17 *
18 * 2003 (c) MontaVista Software, Inc. This file is licensed under
19 * the terms of the GNU General Public License version 2. This program
20 * is licensed "as is" without any warranty of any kind, whether express
21 * or implied.
22 *
23 */
24
25#include <linux/slab.h>
26#include <linux/init.h>
27#include <linux/module.h>
28#include <linux/mtd/mtd.h>
29#include <linux/mtd/nand.h>
30#include <linux/mtd/partitions.h>
31#include <linux/delay.h>
32#include <asm/io.h>
33#include <asm/tx4925/tx4925_nand.h>
34
35extern struct nand_oobinfo jffs2_oobinfo;
36
37/*
38 * MTD structure for RBTX4925 board
39 */
40static struct mtd_info *tx4925ndfmc_mtd = NULL;
41
42/*
43 * Define partitions for flash devices
44 */
45
46static struct mtd_partition partition_info16k[] = {
47 { .name = "RBTX4925 flash partition 1",
48 .offset = 0,
49 .size = 8 * 0x00100000 },
50 { .name = "RBTX4925 flash partition 2",
51 .offset = 8 * 0x00100000,
52 .size = 8 * 0x00100000 },
53};
54
55static struct mtd_partition partition_info32k[] = {
56 { .name = "RBTX4925 flash partition 1",
57 .offset = 0,
58 .size = 8 * 0x00100000 },
59 { .name = "RBTX4925 flash partition 2",
60 .offset = 8 * 0x00100000,
61 .size = 24 * 0x00100000 },
62};
63
64static struct mtd_partition partition_info64k[] = {
65 { .name = "User FS",
66 .offset = 0,
67 .size = 16 * 0x00100000 },
68 { .name = "RBTX4925 flash partition 2",
69 .offset = 16 * 0x00100000,
70 .size = 48 * 0x00100000},
71};
72
73static struct mtd_partition partition_info128k[] = {
74 { .name = "Skip bad section",
75 .offset = 0,
76 .size = 16 * 0x00100000 },
77 { .name = "User FS",
78 .offset = 16 * 0x00100000,
79 .size = 112 * 0x00100000 },
80};
81#define NUM_PARTITIONS16K 2
82#define NUM_PARTITIONS32K 2
83#define NUM_PARTITIONS64K 2
84#define NUM_PARTITIONS128K 2
85
86/*
87 * hardware specific access to control-lines
88*/
89static void tx4925ndfmc_hwcontrol(struct mtd_info *mtd, int cmd)
90{
91
92 switch(cmd){
93
94 case NAND_CTL_SETCLE:
95 tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_CLE;
96 break;
97 case NAND_CTL_CLRCLE:
98 tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_CLE;
99 break;
100 case NAND_CTL_SETALE:
101 tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ALE;
102 break;
103 case NAND_CTL_CLRALE:
104 tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ALE;
105 break;
106 case NAND_CTL_SETNCE:
107 tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_CE;
108 break;
109 case NAND_CTL_CLRNCE:
110 tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_CE;
111 break;
112 case NAND_CTL_SETWP:
113 tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_WE;
114 break;
115 case NAND_CTL_CLRWP:
116 tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_WE;
117 break;
118 }
119}
120
121/*
122* read device ready pin
123*/
124static int tx4925ndfmc_device_ready(struct mtd_info *mtd)
125{
126 int ready;
127 ready = (tx4925_ndfmcptr->sr & TX4925_NDSFR_BUSY) ? 0 : 1;
128 return ready;
129}
130void tx4925ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
131{
132 /* reset first */
133 tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_MASK;
134 tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
135 tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_ENAB;
136}
137static void tx4925ndfmc_disable_ecc(void)
138{
139 tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
140}
141static void tx4925ndfmc_enable_read_ecc(void)
142{
143 tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
144 tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_READ;
145}
146void tx4925ndfmc_readecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code){
147 int i;
148 u_char *ecc = ecc_code;
149 tx4925ndfmc_enable_read_ecc();
150 for (i = 0;i < 6;i++,ecc++)
151 *ecc = tx4925_read_nfmc(&(tx4925_ndfmcptr->dtr));
152 tx4925ndfmc_disable_ecc();
153}
154void tx4925ndfmc_device_setup(void)
155{
156
157 *(unsigned char *)0xbb005000 &= ~0x08;
158
159 /* reset NDFMC */
160 tx4925_ndfmcptr->rstr |= TX4925_NDFRSTR_RST;
161 while (tx4925_ndfmcptr->rstr & TX4925_NDFRSTR_RST);
162
163 /* setup BusSeparete, Hold Time, Strobe Pulse Width */
164 tx4925_ndfmcptr->mcr = TX4925_BSPRT ? TX4925_NDFMCR_BSPRT : 0;
165 tx4925_ndfmcptr->spr = TX4925_HOLD << 4 | TX4925_SPW;
166}
167static u_char tx4925ndfmc_nand_read_byte(struct mtd_info *mtd)
168{
169 struct nand_chip *this = mtd->priv;
170 return tx4925_read_nfmc(this->IO_ADDR_R);
171}
172
173static void tx4925ndfmc_nand_write_byte(struct mtd_info *mtd, u_char byte)
174{
175 struct nand_chip *this = mtd->priv;
176 tx4925_write_nfmc(byte, this->IO_ADDR_W);
177}
178
179static void tx4925ndfmc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
180{
181 int i;
182 struct nand_chip *this = mtd->priv;
183
184 for (i=0; i<len; i++)
185 tx4925_write_nfmc(buf[i], this->IO_ADDR_W);
186}
187
188static void tx4925ndfmc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
189{
190 int i;
191 struct nand_chip *this = mtd->priv;
192
193 for (i=0; i<len; i++)
194 buf[i] = tx4925_read_nfmc(this->IO_ADDR_R);
195}
196
197static int tx4925ndfmc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
198{
199 int i;
200 struct nand_chip *this = mtd->priv;
201
202 for (i=0; i<len; i++)
203 if (buf[i] != tx4925_read_nfmc(this->IO_ADDR_R))
204 return -EFAULT;
205
206 return 0;
207}
208
209/*
210 * Send command to NAND device
211 */
212static void tx4925ndfmc_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
213{
214 register struct nand_chip *this = mtd->priv;
215
216 /* Begin command latch cycle */
217 this->hwcontrol(mtd, NAND_CTL_SETCLE);
218 /*
219 * Write out the command to the device.
220 */
221 if (command == NAND_CMD_SEQIN) {
222 int readcmd;
223
224 if (column >= mtd->oobblock) {
225 /* OOB area */
226 column -= mtd->oobblock;
227 readcmd = NAND_CMD_READOOB;
228 } else if (column < 256) {
229 /* First 256 bytes --> READ0 */
230 readcmd = NAND_CMD_READ0;
231 } else {
232 column -= 256;
233 readcmd = NAND_CMD_READ1;
234 }
235 this->write_byte(mtd, readcmd);
236 }
237 this->write_byte(mtd, command);
238
239 /* Set ALE and clear CLE to start address cycle */
240 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
241
242 if (column != -1 || page_addr != -1) {
243 this->hwcontrol(mtd, NAND_CTL_SETALE);
244
245 /* Serially input address */
246 if (column != -1)
247 this->write_byte(mtd, column);
248 if (page_addr != -1) {
249 this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
250 this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
251 /* One more address cycle for higher density devices */
252 if (mtd->size & 0x0c000000)
253 this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
254 }
255 /* Latch in address */
256 this->hwcontrol(mtd, NAND_CTL_CLRALE);
257 }
258
259 /*
260 * program and erase have their own busy handlers
261 * status and sequential in needs no delay
262 */
263 switch (command) {
264
265 case NAND_CMD_PAGEPROG:
266 /* Turn off WE */
267 this->hwcontrol (mtd, NAND_CTL_CLRWP);
268 return;
269
270 case NAND_CMD_SEQIN:
271 /* Turn on WE */
272 this->hwcontrol (mtd, NAND_CTL_SETWP);
273 return;
274
275 case NAND_CMD_ERASE1:
276 case NAND_CMD_ERASE2:
277 case NAND_CMD_STATUS:
278 return;
279
280 case NAND_CMD_RESET:
281 if (this->dev_ready)
282 break;
283 this->hwcontrol(mtd, NAND_CTL_SETCLE);
284 this->write_byte(mtd, NAND_CMD_STATUS);
285 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
286 while ( !(this->read_byte(mtd) & 0x40));
287 return;
288
289 /* This applies to read commands */
290 default:
291 /*
292 * If we don't have access to the busy pin, we apply the given
293 * command delay
294 */
295 if (!this->dev_ready) {
296 udelay (this->chip_delay);
297 return;
298 }
299 }
300
301 /* wait until command is processed */
302 while (!this->dev_ready(mtd));
303}
304
305#ifdef CONFIG_MTD_CMDLINE_PARTS
306extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partitio
307n **pparts, char *);
308#endif
309
310/*
311 * Main initialization routine
312 */
313extern int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
314int __init tx4925ndfmc_init (void)
315{
316 struct nand_chip *this;
317 int err = 0;
318
319 /* Allocate memory for MTD device structure and private data */
320 tx4925ndfmc_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
321 GFP_KERNEL);
322 if (!tx4925ndfmc_mtd) {
323 printk ("Unable to allocate RBTX4925 NAND MTD device structure.\n");
324 err = -ENOMEM;
325 goto out;
326 }
327
328 tx4925ndfmc_device_setup();
329
330 /* io is indirect via a register so don't need to ioremap address */
331
332 /* Get pointer to private data */
333 this = (struct nand_chip *) (&tx4925ndfmc_mtd[1]);
334
335 /* Initialize structures */
336 memset((char *) tx4925ndfmc_mtd, 0, sizeof(struct mtd_info));
337 memset((char *) this, 0, sizeof(struct nand_chip));
338
339 /* Link the private data with the MTD structure */
340 tx4925ndfmc_mtd->priv = this;
341
342 /* Set address of NAND IO lines */
343 this->IO_ADDR_R = (void __iomem *)&(tx4925_ndfmcptr->dtr);
344 this->IO_ADDR_W = (void __iomem *)&(tx4925_ndfmcptr->dtr);
345 this->hwcontrol = tx4925ndfmc_hwcontrol;
346 this->enable_hwecc = tx4925ndfmc_enable_hwecc;
347 this->calculate_ecc = tx4925ndfmc_readecc;
348 this->correct_data = nand_correct_data;
349 this->eccmode = NAND_ECC_HW6_512;
350 this->dev_ready = tx4925ndfmc_device_ready;
351 /* 20 us command delay time */
352 this->chip_delay = 20;
353 this->read_byte = tx4925ndfmc_nand_read_byte;
354 this->write_byte = tx4925ndfmc_nand_write_byte;
355 this->cmdfunc = tx4925ndfmc_nand_command;
356 this->write_buf = tx4925ndfmc_nand_write_buf;
357 this->read_buf = tx4925ndfmc_nand_read_buf;
358 this->verify_buf = tx4925ndfmc_nand_verify_buf;
359
360 /* Scan to find existance of the device */
361 if (nand_scan (tx4925ndfmc_mtd, 1)) {
362 err = -ENXIO;
363 goto out_ior;
364 }
365
366 /* Register the partitions */
367#ifdef CONFIG_MTD_CMDLINE_PARTS
368 {
369 int mtd_parts_nb = 0;
370 struct mtd_partition *mtd_parts = 0;
371 mtd_parts_nb = parse_cmdline_partitions(tx4925ndfmc_mtd, &mtd_parts, "tx4925ndfmc");
372 if (mtd_parts_nb > 0)
373 add_mtd_partitions(tx4925ndfmc_mtd, mtd_parts, mtd_parts_nb);
374 else
375 add_mtd_device(tx4925ndfmc_mtd);
376 }
377#else /* ifdef CONFIG_MTD_CMDLINE_PARTS */
378 switch(tx4925ndfmc_mtd->size){
379 case 0x01000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info16k, NUM_PARTITIONS16K); break;
380 case 0x02000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info32k, NUM_PARTITIONS32K); break;
381 case 0x04000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info64k, NUM_PARTITIONS64K); break;
382 case 0x08000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info128k, NUM_PARTITIONS128K); break;
383 default: {
384 printk ("Unsupported SmartMedia device\n");
385 err = -ENXIO;
386 goto out_ior;
387 }
388 }
389#endif /* ifdef CONFIG_MTD_CMDLINE_PARTS */
390 goto out;
391
392out_ior:
393out:
394 return err;
395}
396
397module_init(tx4925ndfmc_init);
398
399/*
400 * Clean up routine
401 */
402#ifdef MODULE
403static void __exit tx4925ndfmc_cleanup (void)
404{
405 /* Release resources, unregister device */
406 nand_release (tx4925ndfmc_mtd);
407
408 /* Free the MTD device structure */
409 kfree (tx4925ndfmc_mtd);
410}
411module_exit(tx4925ndfmc_cleanup);
412#endif
413
414MODULE_LICENSE("GPL");
415MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>");
416MODULE_DESCRIPTION("Glue layer for SmartMediaCard on Toshiba RBTX4925");
diff --git a/drivers/mtd/nand/tx4938ndfmc.c b/drivers/mtd/nand/tx4938ndfmc.c
deleted file mode 100644
index df26e58820b3..000000000000
--- a/drivers/mtd/nand/tx4938ndfmc.c
+++ /dev/null
@@ -1,406 +0,0 @@
1/*
2 * drivers/mtd/nand/tx4938ndfmc.c
3 *
4 * Overview:
5 * This is a device driver for the NAND flash device connected to
6 * TX4938 internal NAND Memory Controller.
7 * TX4938 NDFMC is almost same as TX4925 NDFMC, but register size are 64 bit.
8 *
9 * Author: source@mvista.com
10 *
11 * Based on spia.c by Steven J. Hill
12 *
13 * $Id: tx4938ndfmc.c,v 1.4 2004/10/05 13:50:20 gleixner Exp $
14 *
15 * Copyright (C) 2000-2001 Toshiba Corporation
16 *
17 * 2003 (c) MontaVista Software, Inc. This file is licensed under the
18 * terms of the GNU General Public License version 2. This program is
19 * licensed "as is" without any warranty of any kind, whether express
20 * or implied.
21 */
22#include <linux/config.h>
23#include <linux/slab.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/mtd/mtd.h>
27#include <linux/mtd/nand.h>
28#include <linux/mtd/nand_ecc.h>
29#include <linux/mtd/partitions.h>
30#include <asm/io.h>
31#include <asm/bootinfo.h>
32#include <linux/delay.h>
33#include <asm/tx4938/rbtx4938.h>
34
35extern struct nand_oobinfo jffs2_oobinfo;
36
37/*
38 * MTD structure for TX4938 NDFMC
39 */
40static struct mtd_info *tx4938ndfmc_mtd;
41
42/*
43 * Define partitions for flash device
44 */
45#define flush_wb() (void)tx4938_ndfmcptr->mcr;
46
47#define NUM_PARTITIONS 3
48#define NUMBER_OF_CIS_BLOCKS 24
49#define SIZE_OF_BLOCK 0x00004000
50#define NUMBER_OF_BLOCK_PER_ZONE 1024
51#define SIZE_OF_ZONE (NUMBER_OF_BLOCK_PER_ZONE * SIZE_OF_BLOCK)
52#ifndef CONFIG_MTD_CMDLINE_PARTS
53/*
54 * You can use the following sample of MTD partitions
55 * on the NAND Flash Memory 32MB or more.
56 *
57 * The following figure shows the image of the sample partition on
58 * the 32MB NAND Flash Memory.
59 *
60 * Block No.
61 * 0 +-----------------------------+ ------
62 * | CIS | ^
63 * 24 +-----------------------------+ |
64 * | kernel image | | Zone 0
65 * | | |
66 * +-----------------------------+ |
67 * 1023 | unused area | v
68 * +-----------------------------+ ------
69 * 1024 | JFFS2 | ^
70 * | | |
71 * | | | Zone 1
72 * | | |
73 * | | |
74 * | | v
75 * 2047 +-----------------------------+ ------
76 *
77 */
78static struct mtd_partition partition_info[NUM_PARTITIONS] = {
79 {
80 .name = "RBTX4938 CIS Area",
81 .offset = 0,
82 .size = (NUMBER_OF_CIS_BLOCKS * SIZE_OF_BLOCK),
83 .mask_flags = MTD_WRITEABLE /* This partition is NOT writable */
84 },
85 {
86 .name = "RBTX4938 kernel image",
87 .offset = MTDPART_OFS_APPEND,
88 .size = 8 * 0x00100000, /* 8MB (Depends on size of kernel image) */
89 .mask_flags = MTD_WRITEABLE /* This partition is NOT writable */
90 },
91 {
92 .name = "Root FS (JFFS2)",
93 .offset = (0 + SIZE_OF_ZONE), /* start address of next zone */
94 .size = MTDPART_SIZ_FULL
95 },
96};
97#endif
98
99static void tx4938ndfmc_hwcontrol(struct mtd_info *mtd, int cmd)
100{
101 switch (cmd) {
102 case NAND_CTL_SETCLE:
103 tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_CLE;
104 break;
105 case NAND_CTL_CLRCLE:
106 tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_CLE;
107 break;
108 case NAND_CTL_SETALE:
109 tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_ALE;
110 break;
111 case NAND_CTL_CLRALE:
112 tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_ALE;
113 break;
114 /* TX4938_NDFMCR_CE bit is 0:high 1:low */
115 case NAND_CTL_SETNCE:
116 tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_CE;
117 break;
118 case NAND_CTL_CLRNCE:
119 tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_CE;
120 break;
121 case NAND_CTL_SETWP:
122 tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_WE;
123 break;
124 case NAND_CTL_CLRWP:
125 tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_WE;
126 break;
127 }
128}
129static int tx4938ndfmc_dev_ready(struct mtd_info *mtd)
130{
131 flush_wb();
132 return !(tx4938_ndfmcptr->sr & TX4938_NDFSR_BUSY);
133}
134static void tx4938ndfmc_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
135{
136 u32 mcr = tx4938_ndfmcptr->mcr;
137 mcr &= ~TX4938_NDFMCR_ECC_ALL;
138 tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
139 tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_READ;
140 ecc_code[1] = tx4938_ndfmcptr->dtr;
141 ecc_code[0] = tx4938_ndfmcptr->dtr;
142 ecc_code[2] = tx4938_ndfmcptr->dtr;
143 tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
144}
145static void tx4938ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
146{
147 u32 mcr = tx4938_ndfmcptr->mcr;
148 mcr &= ~TX4938_NDFMCR_ECC_ALL;
149 tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_RESET;
150 tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
151 tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_ON;
152}
153
154static u_char tx4938ndfmc_nand_read_byte(struct mtd_info *mtd)
155{
156 struct nand_chip *this = mtd->priv;
157 return tx4938_read_nfmc(this->IO_ADDR_R);
158}
159
160static void tx4938ndfmc_nand_write_byte(struct mtd_info *mtd, u_char byte)
161{
162 struct nand_chip *this = mtd->priv;
163 tx4938_write_nfmc(byte, this->IO_ADDR_W);
164}
165
166static void tx4938ndfmc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
167{
168 int i;
169 struct nand_chip *this = mtd->priv;
170
171 for (i=0; i<len; i++)
172 tx4938_write_nfmc(buf[i], this->IO_ADDR_W);
173}
174
175static void tx4938ndfmc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
176{
177 int i;
178 struct nand_chip *this = mtd->priv;
179
180 for (i=0; i<len; i++)
181 buf[i] = tx4938_read_nfmc(this->IO_ADDR_R);
182}
183
184static int tx4938ndfmc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
185{
186 int i;
187 struct nand_chip *this = mtd->priv;
188
189 for (i=0; i<len; i++)
190 if (buf[i] != tx4938_read_nfmc(this->IO_ADDR_R))
191 return -EFAULT;
192
193 return 0;
194}
195
196/*
197 * Send command to NAND device
198 */
199static void tx4938ndfmc_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
200{
201 register struct nand_chip *this = mtd->priv;
202
203 /* Begin command latch cycle */
204 this->hwcontrol(mtd, NAND_CTL_SETCLE);
205 /*
206 * Write out the command to the device.
207 */
208 if (command == NAND_CMD_SEQIN) {
209 int readcmd;
210
211 if (column >= mtd->oobblock) {
212 /* OOB area */
213 column -= mtd->oobblock;
214 readcmd = NAND_CMD_READOOB;
215 } else if (column < 256) {
216 /* First 256 bytes --> READ0 */
217 readcmd = NAND_CMD_READ0;
218 } else {
219 column -= 256;
220 readcmd = NAND_CMD_READ1;
221 }
222 this->write_byte(mtd, readcmd);
223 }
224 this->write_byte(mtd, command);
225
226 /* Set ALE and clear CLE to start address cycle */
227 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
228
229 if (column != -1 || page_addr != -1) {
230 this->hwcontrol(mtd, NAND_CTL_SETALE);
231
232 /* Serially input address */
233 if (column != -1)
234 this->write_byte(mtd, column);
235 if (page_addr != -1) {
236 this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
237 this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
238 /* One more address cycle for higher density devices */
239 if (mtd->size & 0x0c000000)
240 this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
241 }
242 /* Latch in address */
243 this->hwcontrol(mtd, NAND_CTL_CLRALE);
244 }
245
246 /*
247 * program and erase have their own busy handlers
248 * status and sequential in needs no delay
249 */
250 switch (command) {
251
252 case NAND_CMD_PAGEPROG:
253 /* Turn off WE */
254 this->hwcontrol (mtd, NAND_CTL_CLRWP);
255 return;
256
257 case NAND_CMD_SEQIN:
258 /* Turn on WE */
259 this->hwcontrol (mtd, NAND_CTL_SETWP);
260 return;
261
262 case NAND_CMD_ERASE1:
263 case NAND_CMD_ERASE2:
264 case NAND_CMD_STATUS:
265 return;
266
267 case NAND_CMD_RESET:
268 if (this->dev_ready)
269 break;
270 this->hwcontrol(mtd, NAND_CTL_SETCLE);
271 this->write_byte(mtd, NAND_CMD_STATUS);
272 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
273 while ( !(this->read_byte(mtd) & 0x40));
274 return;
275
276 /* This applies to read commands */
277 default:
278 /*
279 * If we don't have access to the busy pin, we apply the given
280 * command delay
281 */
282 if (!this->dev_ready) {
283 udelay (this->chip_delay);
284 return;
285 }
286 }
287
288 /* wait until command is processed */
289 while (!this->dev_ready(mtd));
290}
291
292#ifdef CONFIG_MTD_CMDLINE_PARTS
293extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, char *);
294#endif
295/*
296 * Main initialization routine
297 */
298int __init tx4938ndfmc_init (void)
299{
300 struct nand_chip *this;
301 int bsprt = 0, hold = 0xf, spw = 0xf;
302 int protected = 0;
303
304 if ((*rbtx4938_piosel_ptr & 0x0c) != 0x08) {
305 printk("TX4938 NDFMC: disabled by IOC PIOSEL\n");
306 return -ENODEV;
307 }
308 bsprt = 1;
309 hold = 2;
310 spw = 9 - 1; /* 8 GBUSCLK = 80ns (@ GBUSCLK 100MHz) */
311
312 if ((tx4938_ccfgptr->pcfg &
313 (TX4938_PCFG_ATA_SEL|TX4938_PCFG_ISA_SEL|TX4938_PCFG_NDF_SEL))
314 != TX4938_PCFG_NDF_SEL) {
315 printk("TX4938 NDFMC: disabled by PCFG.\n");
316 return -ENODEV;
317 }
318
319 /* reset NDFMC */
320 tx4938_ndfmcptr->rstr |= TX4938_NDFRSTR_RST;
321 while (tx4938_ndfmcptr->rstr & TX4938_NDFRSTR_RST)
322 ;
323 /* setup BusSeparete, Hold Time, Strobe Pulse Width */
324 tx4938_ndfmcptr->mcr = bsprt ? TX4938_NDFMCR_BSPRT : 0;
325 tx4938_ndfmcptr->spr = hold << 4 | spw;
326
327 /* Allocate memory for MTD device structure and private data */
328 tx4938ndfmc_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
329 GFP_KERNEL);
330 if (!tx4938ndfmc_mtd) {
331 printk ("Unable to allocate TX4938 NDFMC MTD device structure.\n");
332 return -ENOMEM;
333 }
334
335 /* Get pointer to private data */
336 this = (struct nand_chip *) (&tx4938ndfmc_mtd[1]);
337
338 /* Initialize structures */
339 memset((char *) tx4938ndfmc_mtd, 0, sizeof(struct mtd_info));
340 memset((char *) this, 0, sizeof(struct nand_chip));
341
342 /* Link the private data with the MTD structure */
343 tx4938ndfmc_mtd->priv = this;
344
345 /* Set address of NAND IO lines */
346 this->IO_ADDR_R = (unsigned long)&tx4938_ndfmcptr->dtr;
347 this->IO_ADDR_W = (unsigned long)&tx4938_ndfmcptr->dtr;
348 this->hwcontrol = tx4938ndfmc_hwcontrol;
349 this->dev_ready = tx4938ndfmc_dev_ready;
350 this->calculate_ecc = tx4938ndfmc_calculate_ecc;
351 this->correct_data = nand_correct_data;
352 this->enable_hwecc = tx4938ndfmc_enable_hwecc;
353 this->eccmode = NAND_ECC_HW3_256;
354 this->chip_delay = 100;
355 this->read_byte = tx4938ndfmc_nand_read_byte;
356 this->write_byte = tx4938ndfmc_nand_write_byte;
357 this->cmdfunc = tx4938ndfmc_nand_command;
358 this->write_buf = tx4938ndfmc_nand_write_buf;
359 this->read_buf = tx4938ndfmc_nand_read_buf;
360 this->verify_buf = tx4938ndfmc_nand_verify_buf;
361
362 /* Scan to find existance of the device */
363 if (nand_scan (tx4938ndfmc_mtd, 1)) {
364 kfree (tx4938ndfmc_mtd);
365 return -ENXIO;
366 }
367
368 if (protected) {
369 printk(KERN_INFO "TX4938 NDFMC: write protected.\n");
370 tx4938ndfmc_mtd->flags &= ~(MTD_WRITEABLE | MTD_ERASEABLE);
371 }
372
373#ifdef CONFIG_MTD_CMDLINE_PARTS
374 {
375 int mtd_parts_nb = 0;
376 struct mtd_partition *mtd_parts = 0;
377 mtd_parts_nb = parse_cmdline_partitions(tx4938ndfmc_mtd, &mtd_parts, "tx4938ndfmc");
378 if (mtd_parts_nb > 0)
379 add_mtd_partitions(tx4938ndfmc_mtd, mtd_parts, mtd_parts_nb);
380 else
381 add_mtd_device(tx4938ndfmc_mtd);
382 }
383#else
384 add_mtd_partitions(tx4938ndfmc_mtd, partition_info, NUM_PARTITIONS );
385#endif
386
387 return 0;
388}
389module_init(tx4938ndfmc_init);
390
391/*
392 * Clean up routine
393 */
394static void __exit tx4938ndfmc_cleanup (void)
395{
396 /* Release resources, unregister device */
397 nand_release (tx4938ndfmc_mtd);
398
399 /* Free the MTD device structure */
400 kfree (tx4938ndfmc_mtd);
401}
402module_exit(tx4938ndfmc_cleanup);
403
404MODULE_LICENSE("GPL");
405MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>");
406MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on TX4938 NDFMC");
diff --git a/fs/Kconfig b/fs/Kconfig
index 062177956239..8d50a610c0e0 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1036,26 +1036,18 @@ config JFFS2_FS_DEBUG
1036 If reporting bugs, please try to have available a full dump of the 1036 If reporting bugs, please try to have available a full dump of the
1037 messages at debug level 1 while the misbehaviour was occurring. 1037 messages at debug level 1 while the misbehaviour was occurring.
1038 1038
1039config JFFS2_FS_NAND 1039config JFFS2_FS_WRITEBUFFER
1040 bool "JFFS2 support for NAND flash" 1040 bool "JFFS2 write-buffering support"
1041 depends on JFFS2_FS 1041 depends on JFFS2_FS
1042 default n 1042 default y
1043 help 1043 help
1044 This enables the support for NAND flash in JFFS2. NAND is a newer 1044 This enables the write-buffering support in JFFS2.
1045 type of flash chip design than the traditional NOR flash, with
1046 higher density but a handful of characteristics which make it more
1047 interesting for the file system to use.
1048 1045
1049 Say 'N' unless you have NAND flash. 1046 This functionality is required to support JFFS2 on the following
1050 1047 types of flash devices:
1051config JFFS2_FS_NOR_ECC 1048 - NAND flash
1052 bool "JFFS2 support for ECC'd NOR flash (EXPERIMENTAL)" 1049 - NOR flash with transparent ECC
1053 depends on JFFS2_FS && EXPERIMENTAL 1050 - DataFlash
1054 default n
1055 help
1056 This enables the experimental support for NOR flash with transparent
1057 ECC for JFFS2. This type of flash chip is not common, however it is
1058 available from ST Microelectronics.
1059 1051
1060config JFFS2_COMPRESSION_OPTIONS 1052config JFFS2_COMPRESSION_OPTIONS
1061 bool "Advanced compression options for JFFS2" 1053 bool "Advanced compression options for JFFS2"
diff --git a/fs/jffs2/Makefile b/fs/jffs2/Makefile
index e3c38ccf9c7d..f1afe681ecd6 100644
--- a/fs/jffs2/Makefile
+++ b/fs/jffs2/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# Makefile for the Linux Journalling Flash File System v2 (JFFS2) 2# Makefile for the Linux Journalling Flash File System v2 (JFFS2)
3# 3#
4# $Id: Makefile.common,v 1.7 2004/11/03 12:57:38 jwboyer Exp $ 4# $Id: Makefile.common,v 1.9 2005/02/09 09:23:53 pavlov Exp $
5# 5#
6 6
7obj-$(CONFIG_JFFS2_FS) += jffs2.o 7obj-$(CONFIG_JFFS2_FS) += jffs2.o
@@ -11,8 +11,7 @@ jffs2-y += read.o nodemgmt.o readinode.o write.o scan.o gc.o
11jffs2-y += symlink.o build.o erase.o background.o fs.o writev.o 11jffs2-y += symlink.o build.o erase.o background.o fs.o writev.o
12jffs2-y += super.o 12jffs2-y += super.o
13 13
14jffs2-$(CONFIG_JFFS2_FS_NAND) += wbuf.o 14jffs2-$(CONFIG_JFFS2_FS_WRITEBUFFER) += wbuf.o
15jffs2-$(CONFIG_JFFS2_FS_NOR_ECC) += wbuf.o
16jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o 15jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o
17jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o 16jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o
18jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o 17jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o
diff --git a/fs/jffs2/README.Locking b/fs/jffs2/README.Locking
index 49771cf8513a..b7943439b6ec 100644
--- a/fs/jffs2/README.Locking
+++ b/fs/jffs2/README.Locking
@@ -1,4 +1,4 @@
1 $Id: README.Locking,v 1.9 2004/11/20 10:35:40 dwmw2 Exp $ 1 $Id: README.Locking,v 1.12 2005/04/13 13:22:35 dwmw2 Exp $
2 2
3 JFFS2 LOCKING DOCUMENTATION 3 JFFS2 LOCKING DOCUMENTATION
4 --------------------------- 4 ---------------------------
@@ -108,6 +108,10 @@ in-core jffs2_inode_cache objects (each inode in JFFS2 has the
108correspondent jffs2_inode_cache object). So, the inocache_lock 108correspondent jffs2_inode_cache object). So, the inocache_lock
109has to be locked while walking the c->inocache_list hash buckets. 109has to be locked while walking the c->inocache_list hash buckets.
110 110
111This spinlock also covers allocation of new inode numbers, which is
112currently just '++->highest_ino++', but might one day get more complicated
113if we need to deal with wrapping after 4 milliard inode numbers are used.
114
111Note, the f->sem guarantees that the correspondent jffs2_inode_cache 115Note, the f->sem guarantees that the correspondent jffs2_inode_cache
112will not be removed. So, it is allowed to access it without locking 116will not be removed. So, it is allowed to access it without locking
113the inocache_lock spinlock. 117the inocache_lock spinlock.
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c
index 638836b277d4..0f224384f176 100644
--- a/fs/jffs2/background.c
+++ b/fs/jffs2/background.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: background.c,v 1.50 2004/11/16 20:36:10 dwmw2 Exp $ 10 * $Id: background.c,v 1.54 2005/05/20 21:37:12 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -37,7 +37,7 @@ int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
37 if (c->gc_task) 37 if (c->gc_task)
38 BUG(); 38 BUG();
39 39
40 init_MUTEX_LOCKED(&c->gc_thread_start); 40 init_completion(&c->gc_thread_start);
41 init_completion(&c->gc_thread_exit); 41 init_completion(&c->gc_thread_exit);
42 42
43 pid = kernel_thread(jffs2_garbage_collect_thread, c, CLONE_FS|CLONE_FILES); 43 pid = kernel_thread(jffs2_garbage_collect_thread, c, CLONE_FS|CLONE_FILES);
@@ -48,7 +48,7 @@ int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
48 } else { 48 } else {
49 /* Wait for it... */ 49 /* Wait for it... */
50 D1(printk(KERN_DEBUG "JFFS2: Garbage collect thread is pid %d\n", pid)); 50 D1(printk(KERN_DEBUG "JFFS2: Garbage collect thread is pid %d\n", pid));
51 down(&c->gc_thread_start); 51 wait_for_completion(&c->gc_thread_start);
52 } 52 }
53 53
54 return ret; 54 return ret;
@@ -56,13 +56,16 @@ int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
56 56
57void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c) 57void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c)
58{ 58{
59 int wait = 0;
59 spin_lock(&c->erase_completion_lock); 60 spin_lock(&c->erase_completion_lock);
60 if (c->gc_task) { 61 if (c->gc_task) {
61 D1(printk(KERN_DEBUG "jffs2: Killing GC task %d\n", c->gc_task->pid)); 62 D1(printk(KERN_DEBUG "jffs2: Killing GC task %d\n", c->gc_task->pid));
62 send_sig(SIGKILL, c->gc_task, 1); 63 send_sig(SIGKILL, c->gc_task, 1);
64 wait = 1;
63 } 65 }
64 spin_unlock(&c->erase_completion_lock); 66 spin_unlock(&c->erase_completion_lock);
65 wait_for_completion(&c->gc_thread_exit); 67 if (wait)
68 wait_for_completion(&c->gc_thread_exit);
66} 69}
67 70
68static int jffs2_garbage_collect_thread(void *_c) 71static int jffs2_garbage_collect_thread(void *_c)
@@ -75,7 +78,7 @@ static int jffs2_garbage_collect_thread(void *_c)
75 allow_signal(SIGCONT); 78 allow_signal(SIGCONT);
76 79
77 c->gc_task = current; 80 c->gc_task = current;
78 up(&c->gc_thread_start); 81 complete(&c->gc_thread_start);
79 82
80 set_user_nice(current, 10); 83 set_user_nice(current, 10);
81 84
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c
index a01dd5fdbb95..3dd5394921c9 100644
--- a/fs/jffs2/build.c
+++ b/fs/jffs2/build.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: build.c,v 1.69 2004/12/16 20:22:18 dmarlin Exp $ 10 * $Id: build.c,v 1.70 2005/02/28 08:21:05 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -97,14 +97,16 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
97 /* First, scan the medium and build all the inode caches with 97 /* First, scan the medium and build all the inode caches with
98 lists of physical nodes */ 98 lists of physical nodes */
99 99
100 c->flags |= JFFS2_SB_FLAG_MOUNTING; 100 c->flags |= JFFS2_SB_FLAG_SCANNING;
101 ret = jffs2_scan_medium(c); 101 ret = jffs2_scan_medium(c);
102 c->flags &= ~JFFS2_SB_FLAG_SCANNING;
102 if (ret) 103 if (ret)
103 goto exit; 104 goto exit;
104 105
105 D1(printk(KERN_DEBUG "Scanned flash completely\n")); 106 D1(printk(KERN_DEBUG "Scanned flash completely\n"));
106 D2(jffs2_dump_block_lists(c)); 107 D2(jffs2_dump_block_lists(c));
107 108
109 c->flags |= JFFS2_SB_FLAG_BUILDING;
108 /* Now scan the directory tree, increasing nlink according to every dirent found. */ 110 /* Now scan the directory tree, increasing nlink according to every dirent found. */
109 for_each_inode(i, c, ic) { 111 for_each_inode(i, c, ic) {
110 D1(printk(KERN_DEBUG "Pass 1: ino #%u\n", ic->ino)); 112 D1(printk(KERN_DEBUG "Pass 1: ino #%u\n", ic->ino));
@@ -116,7 +118,6 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
116 cond_resched(); 118 cond_resched();
117 } 119 }
118 } 120 }
119 c->flags &= ~JFFS2_SB_FLAG_MOUNTING;
120 121
121 D1(printk(KERN_DEBUG "Pass 1 complete\n")); 122 D1(printk(KERN_DEBUG "Pass 1 complete\n"));
122 123
@@ -164,6 +165,8 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
164 ic->scan_dents = NULL; 165 ic->scan_dents = NULL;
165 cond_resched(); 166 cond_resched();
166 } 167 }
168 c->flags &= ~JFFS2_SB_FLAG_BUILDING;
169
167 D1(printk(KERN_DEBUG "Pass 3 complete\n")); 170 D1(printk(KERN_DEBUG "Pass 3 complete\n"));
168 D2(jffs2_dump_block_lists(c)); 171 D2(jffs2_dump_block_lists(c));
169 172
diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c
index 078a30e406b5..83f7e0788fd0 100644
--- a/fs/jffs2/compr_zlib.c
+++ b/fs/jffs2/compr_zlib.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: compr_zlib.c,v 1.29 2004/11/16 20:36:11 dwmw2 Exp $ 10 * $Id: compr_zlib.c,v 1.31 2005/05/20 19:30:06 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -17,10 +17,10 @@
17 17
18#include <linux/config.h> 18#include <linux/config.h>
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/sched.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
21#include <linux/zlib.h> 22#include <linux/zlib.h>
22#include <linux/zutil.h> 23#include <linux/zutil.h>
23#include <asm/semaphore.h>
24#include "nodelist.h" 24#include "nodelist.h"
25#include "compr.h" 25#include "compr.h"
26 26
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 757306fa3ff4..3ca0d25eef1d 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: dir.c,v 1.84 2004/11/16 20:36:11 dwmw2 Exp $ 10 * $Id: dir.c,v 1.86 2005/07/06 12:13:09 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -22,16 +22,6 @@
22#include <linux/time.h> 22#include <linux/time.h>
23#include "nodelist.h" 23#include "nodelist.h"
24 24
25/* Urgh. Please tell me there's a nicer way of doing these. */
26#include <linux/version.h>
27#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,48)
28typedef int mknod_arg_t;
29#define NAMEI_COMPAT(x) ((void *)x)
30#else
31typedef dev_t mknod_arg_t;
32#define NAMEI_COMPAT(x) (x)
33#endif
34
35static int jffs2_readdir (struct file *, void *, filldir_t); 25static int jffs2_readdir (struct file *, void *, filldir_t);
36 26
37static int jffs2_create (struct inode *,struct dentry *,int, 27static int jffs2_create (struct inode *,struct dentry *,int,
@@ -43,7 +33,7 @@ static int jffs2_unlink (struct inode *,struct dentry *);
43static int jffs2_symlink (struct inode *,struct dentry *,const char *); 33static int jffs2_symlink (struct inode *,struct dentry *,const char *);
44static int jffs2_mkdir (struct inode *,struct dentry *,int); 34static int jffs2_mkdir (struct inode *,struct dentry *,int);
45static int jffs2_rmdir (struct inode *,struct dentry *); 35static int jffs2_rmdir (struct inode *,struct dentry *);
46static int jffs2_mknod (struct inode *,struct dentry *,int,mknod_arg_t); 36static int jffs2_mknod (struct inode *,struct dentry *,int,dev_t);
47static int jffs2_rename (struct inode *, struct dentry *, 37static int jffs2_rename (struct inode *, struct dentry *,
48 struct inode *, struct dentry *); 38 struct inode *, struct dentry *);
49 39
@@ -58,8 +48,8 @@ struct file_operations jffs2_dir_operations =
58 48
59struct inode_operations jffs2_dir_inode_operations = 49struct inode_operations jffs2_dir_inode_operations =
60{ 50{
61 .create = NAMEI_COMPAT(jffs2_create), 51 .create = jffs2_create,
62 .lookup = NAMEI_COMPAT(jffs2_lookup), 52 .lookup = jffs2_lookup,
63 .link = jffs2_link, 53 .link = jffs2_link,
64 .unlink = jffs2_unlink, 54 .unlink = jffs2_unlink,
65 .symlink = jffs2_symlink, 55 .symlink = jffs2_symlink,
@@ -296,11 +286,11 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
296 struct jffs2_full_dirent *fd; 286 struct jffs2_full_dirent *fd;
297 int namelen; 287 int namelen;
298 uint32_t alloclen, phys_ofs; 288 uint32_t alloclen, phys_ofs;
299 int ret; 289 int ret, targetlen = strlen(target);
300 290
301 /* FIXME: If you care. We'd need to use frags for the target 291 /* FIXME: If you care. We'd need to use frags for the target
302 if it grows much more than this */ 292 if it grows much more than this */
303 if (strlen(target) > 254) 293 if (targetlen > 254)
304 return -EINVAL; 294 return -EINVAL;
305 295
306 ri = jffs2_alloc_raw_inode(); 296 ri = jffs2_alloc_raw_inode();
@@ -314,7 +304,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
314 * Just the node will do for now, though 304 * Just the node will do for now, though
315 */ 305 */
316 namelen = dentry->d_name.len; 306 namelen = dentry->d_name.len;
317 ret = jffs2_reserve_space(c, sizeof(*ri) + strlen(target), &phys_ofs, &alloclen, ALLOC_NORMAL); 307 ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &phys_ofs, &alloclen, ALLOC_NORMAL);
318 308
319 if (ret) { 309 if (ret) {
320 jffs2_free_raw_inode(ri); 310 jffs2_free_raw_inode(ri);
@@ -333,16 +323,16 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
333 323
334 f = JFFS2_INODE_INFO(inode); 324 f = JFFS2_INODE_INFO(inode);
335 325
336 inode->i_size = strlen(target); 326 inode->i_size = targetlen;
337 ri->isize = ri->dsize = ri->csize = cpu_to_je32(inode->i_size); 327 ri->isize = ri->dsize = ri->csize = cpu_to_je32(inode->i_size);
338 ri->totlen = cpu_to_je32(sizeof(*ri) + inode->i_size); 328 ri->totlen = cpu_to_je32(sizeof(*ri) + inode->i_size);
339 ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); 329 ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
340 330
341 ri->compr = JFFS2_COMPR_NONE; 331 ri->compr = JFFS2_COMPR_NONE;
342 ri->data_crc = cpu_to_je32(crc32(0, target, strlen(target))); 332 ri->data_crc = cpu_to_je32(crc32(0, target, targetlen));
343 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); 333 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
344 334
345 fn = jffs2_write_dnode(c, f, ri, target, strlen(target), phys_ofs, ALLOC_NORMAL); 335 fn = jffs2_write_dnode(c, f, ri, target, targetlen, phys_ofs, ALLOC_NORMAL);
346 336
347 jffs2_free_raw_inode(ri); 337 jffs2_free_raw_inode(ri);
348 338
@@ -353,6 +343,20 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
353 jffs2_clear_inode(inode); 343 jffs2_clear_inode(inode);
354 return PTR_ERR(fn); 344 return PTR_ERR(fn);
355 } 345 }
346
347 /* We use f->dents field to store the target path. */
348 f->dents = kmalloc(targetlen + 1, GFP_KERNEL);
349 if (!f->dents) {
350 printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1);
351 up(&f->sem);
352 jffs2_complete_reservation(c);
353 jffs2_clear_inode(inode);
354 return -ENOMEM;
355 }
356
357 memcpy(f->dents, target, targetlen + 1);
358 D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->dents));
359
356 /* No data here. Only a metadata node, which will be 360 /* No data here. Only a metadata node, which will be
357 obsoleted by the first data write 361 obsoleted by the first data write
358 */ 362 */
@@ -564,7 +568,7 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry)
564 return ret; 568 return ret;
565} 569}
566 570
567static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, mknod_arg_t rdev) 571static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, dev_t rdev)
568{ 572{
569 struct jffs2_inode_info *f, *dir_f; 573 struct jffs2_inode_info *f, *dir_f;
570 struct jffs2_sb_info *c; 574 struct jffs2_sb_info *c;
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index 41451e8bf361..6a4c0a3685da 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: erase.c,v 1.66 2004/11/16 20:36:11 dwmw2 Exp $ 10 * $Id: erase.c,v 1.76 2005/05/03 15:11:40 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -48,6 +48,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
48#else /* Linux */ 48#else /* Linux */
49 struct erase_info *instr; 49 struct erase_info *instr;
50 50
51 D1(printk(KERN_DEBUG "jffs2_erase_block(): erase block %#x (range %#x-%#x)\n", jeb->offset, jeb->offset, jeb->offset + c->sector_size));
51 instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL); 52 instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL);
52 if (!instr) { 53 if (!instr) {
53 printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n"); 54 printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n");
@@ -233,7 +234,7 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
233 continue; 234 continue;
234 } 235 }
235 236
236 if (((*prev)->flash_offset & ~(c->sector_size -1)) == jeb->offset) { 237 if (SECTOR_ADDR((*prev)->flash_offset) == jeb->offset) {
237 /* It's in the block we're erasing */ 238 /* It's in the block we're erasing */
238 struct jffs2_raw_node_ref *this; 239 struct jffs2_raw_node_ref *this;
239 240
@@ -277,11 +278,8 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
277 printk("\n"); 278 printk("\n");
278 }); 279 });
279 280
280 if (ic->nodes == (void *)ic) { 281 if (ic->nodes == (void *)ic && ic->nlink == 0)
281 D1(printk(KERN_DEBUG "inocache for ino #%u is all gone now. Freeing\n", ic->ino));
282 jffs2_del_ino_cache(c, ic); 282 jffs2_del_ino_cache(c, ic);
283 jffs2_free_inode_cache(ic);
284 }
285} 283}
286 284
287static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) 285static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
@@ -310,7 +308,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
310 int ret; 308 int ret;
311 uint32_t bad_offset; 309 uint32_t bad_offset;
312 310
313 if (!jffs2_cleanmarker_oob(c)) { 311 if ((!jffs2_cleanmarker_oob(c)) && (c->cleanmarker_size > 0)) {
314 marker_ref = jffs2_alloc_raw_node_ref(); 312 marker_ref = jffs2_alloc_raw_node_ref();
315 if (!marker_ref) { 313 if (!marker_ref) {
316 printk(KERN_WARNING "Failed to allocate raw node ref for clean marker\n"); 314 printk(KERN_WARNING "Failed to allocate raw node ref for clean marker\n");
@@ -335,7 +333,8 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
335 333
336 bad_offset = ofs; 334 bad_offset = ofs;
337 335
338 ret = jffs2_flash_read(c, ofs, readlen, &retlen, ebuf); 336 ret = c->mtd->read(c->mtd, ofs, readlen, &retlen, ebuf);
337
339 if (ret) { 338 if (ret) {
340 printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret); 339 printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret);
341 goto bad; 340 goto bad;
@@ -351,7 +350,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
351 bad_offset += i; 350 bad_offset += i;
352 printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", datum, bad_offset); 351 printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", datum, bad_offset);
353 bad: 352 bad:
354 if (!jffs2_cleanmarker_oob(c)) 353 if ((!jffs2_cleanmarker_oob(c)) && (c->cleanmarker_size > 0))
355 jffs2_free_raw_node_ref(marker_ref); 354 jffs2_free_raw_node_ref(marker_ref);
356 kfree(ebuf); 355 kfree(ebuf);
357 bad2: 356 bad2:
@@ -387,6 +386,13 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
387 jeb->used_size = 0; 386 jeb->used_size = 0;
388 jeb->dirty_size = 0; 387 jeb->dirty_size = 0;
389 jeb->wasted_size = 0; 388 jeb->wasted_size = 0;
389 } else if (c->cleanmarker_size == 0) {
390 jeb->first_node = jeb->last_node = NULL;
391
392 jeb->free_size = c->sector_size;
393 jeb->used_size = 0;
394 jeb->dirty_size = 0;
395 jeb->wasted_size = 0;
390 } else { 396 } else {
391 struct kvec vecs[1]; 397 struct kvec vecs[1];
392 struct jffs2_unknown_node marker = { 398 struct jffs2_unknown_node marker = {
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 771a554701d6..bd9ed9b0247b 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -7,11 +7,10 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: file.c,v 1.99 2004/11/16 20:36:11 dwmw2 Exp $ 10 * $Id: file.c,v 1.102 2005/07/06 12:13:09 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
14#include <linux/version.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16#include <linux/slab.h> 15#include <linux/slab.h>
17#include <linux/fs.h> 16#include <linux/fs.h>
@@ -51,9 +50,7 @@ struct file_operations jffs2_file_operations =
51 .ioctl = jffs2_ioctl, 50 .ioctl = jffs2_ioctl,
52 .mmap = generic_file_readonly_mmap, 51 .mmap = generic_file_readonly_mmap,
53 .fsync = jffs2_fsync, 52 .fsync = jffs2_fsync,
54#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,29)
55 .sendfile = generic_file_sendfile 53 .sendfile = generic_file_sendfile
56#endif
57}; 54};
58 55
59/* jffs2_file_inode_operations */ 56/* jffs2_file_inode_operations */
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 30ab233fe423..5687c3f42002 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -7,11 +7,10 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: fs.c,v 1.51 2004/11/28 12:19:37 dedekind Exp $ 10 * $Id: fs.c,v 1.56 2005/07/06 12:13:09 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
14#include <linux/version.h>
15#include <linux/config.h> 14#include <linux/config.h>
16#include <linux/kernel.h> 15#include <linux/kernel.h>
17#include <linux/sched.h> 16#include <linux/sched.h>
@@ -450,11 +449,15 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
450 449
451 c = JFFS2_SB_INFO(sb); 450 c = JFFS2_SB_INFO(sb);
452 451
453#ifndef CONFIG_JFFS2_FS_NAND 452#ifndef CONFIG_JFFS2_FS_WRITEBUFFER
454 if (c->mtd->type == MTD_NANDFLASH) { 453 if (c->mtd->type == MTD_NANDFLASH) {
455 printk(KERN_ERR "jffs2: Cannot operate on NAND flash unless jffs2 NAND support is compiled in.\n"); 454 printk(KERN_ERR "jffs2: Cannot operate on NAND flash unless jffs2 NAND support is compiled in.\n");
456 return -EINVAL; 455 return -EINVAL;
457 } 456 }
457 if (c->mtd->type == MTD_DATAFLASH) {
458 printk(KERN_ERR "jffs2: Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in.\n");
459 return -EINVAL;
460 }
458#endif 461#endif
459 462
460 c->flash_size = c->mtd->size; 463 c->flash_size = c->mtd->size;
@@ -522,9 +525,7 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
522 if (!sb->s_root) 525 if (!sb->s_root)
523 goto out_root_i; 526 goto out_root_i;
524 527
525#if LINUX_VERSION_CODE >= 0x20403
526 sb->s_maxbytes = 0xFFFFFFFF; 528 sb->s_maxbytes = 0xFFFFFFFF;
527#endif
528 sb->s_blocksize = PAGE_CACHE_SIZE; 529 sb->s_blocksize = PAGE_CACHE_SIZE;
529 sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 530 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
530 sb->s_magic = JFFS2_SUPER_MAGIC; 531 sb->s_magic = JFFS2_SUPER_MAGIC;
@@ -661,6 +662,14 @@ static int jffs2_flash_setup(struct jffs2_sb_info *c) {
661 if (ret) 662 if (ret)
662 return ret; 663 return ret;
663 } 664 }
665
666 /* and Dataflash */
667 if (jffs2_dataflash(c)) {
668 ret = jffs2_dataflash_setup(c);
669 if (ret)
670 return ret;
671 }
672
664 return ret; 673 return ret;
665} 674}
666 675
@@ -674,4 +683,9 @@ void jffs2_flash_cleanup(struct jffs2_sb_info *c) {
674 if (jffs2_nor_ecc(c)) { 683 if (jffs2_nor_ecc(c)) {
675 jffs2_nor_ecc_flash_cleanup(c); 684 jffs2_nor_ecc_flash_cleanup(c);
676 } 685 }
686
687 /* and DataFlash */
688 if (jffs2_dataflash(c)) {
689 jffs2_dataflash_cleanup(c);
690 }
677} 691}
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
index 87ec74ff5930..7086cd634503 100644
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: gc.c,v 1.144 2004/12/21 11:18:50 dwmw2 Exp $ 10 * $Id: gc.c,v 1.148 2005/04/09 10:47:00 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -50,6 +50,7 @@ static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c)
50 put the clever wear-levelling algorithms. Eventually. */ 50 put the clever wear-levelling algorithms. Eventually. */
51 /* We possibly want to favour the dirtier blocks more when the 51 /* We possibly want to favour the dirtier blocks more when the
52 number of free blocks is low. */ 52 number of free blocks is low. */
53again:
53 if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > c->resv_blocks_gcbad) { 54 if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > c->resv_blocks_gcbad) {
54 D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n")); 55 D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n"));
55 nextlist = &c->bad_used_list; 56 nextlist = &c->bad_used_list;
@@ -79,6 +80,13 @@ static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c)
79 D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next (clean_list and {very_,}dirty_list were empty)\n")); 80 D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next (clean_list and {very_,}dirty_list were empty)\n"));
80 81
81 nextlist = &c->erasable_list; 82 nextlist = &c->erasable_list;
83 } else if (!list_empty(&c->erasable_pending_wbuf_list)) {
84 /* There are blocks are wating for the wbuf sync */
85 D1(printk(KERN_DEBUG "Synching wbuf in order to reuse erasable_pending_wbuf_list blocks\n"));
86 spin_unlock(&c->erase_completion_lock);
87 jffs2_flush_wbuf_pad(c);
88 spin_lock(&c->erase_completion_lock);
89 goto again;
82 } else { 90 } else {
83 /* Eep. All were empty */ 91 /* Eep. All were empty */
84 D1(printk(KERN_NOTICE "jffs2: No clean, dirty _or_ erasable blocks to GC from! Where are they all?\n")); 92 D1(printk(KERN_NOTICE "jffs2: No clean, dirty _or_ erasable blocks to GC from! Where are they all?\n"));
@@ -661,9 +669,10 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
661{ 669{
662 struct jffs2_full_dnode *new_fn; 670 struct jffs2_full_dnode *new_fn;
663 struct jffs2_raw_inode ri; 671 struct jffs2_raw_inode ri;
672 struct jffs2_node_frag *last_frag;
664 jint16_t dev; 673 jint16_t dev;
665 char *mdata = NULL, mdatalen = 0; 674 char *mdata = NULL, mdatalen = 0;
666 uint32_t alloclen, phys_ofs; 675 uint32_t alloclen, phys_ofs, ilen;
667 int ret; 676 int ret;
668 677
669 if (S_ISBLK(JFFS2_F_I_MODE(f)) || 678 if (S_ISBLK(JFFS2_F_I_MODE(f)) ||
@@ -699,6 +708,14 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
699 goto out; 708 goto out;
700 } 709 }
701 710
711 last_frag = frag_last(&f->fragtree);
712 if (last_frag)
713 /* Fetch the inode length from the fragtree rather then
714 * from i_size since i_size may have not been updated yet */
715 ilen = last_frag->ofs + last_frag->size;
716 else
717 ilen = JFFS2_F_I_SIZE(f);
718
702 memset(&ri, 0, sizeof(ri)); 719 memset(&ri, 0, sizeof(ri));
703 ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 720 ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
704 ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); 721 ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
@@ -710,7 +727,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
710 ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f)); 727 ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
711 ri.uid = cpu_to_je16(JFFS2_F_I_UID(f)); 728 ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
712 ri.gid = cpu_to_je16(JFFS2_F_I_GID(f)); 729 ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
713 ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f)); 730 ri.isize = cpu_to_je32(ilen);
714 ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f)); 731 ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
715 ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f)); 732 ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
716 ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f)); 733 ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f));
@@ -816,8 +833,7 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct
816 833
817 /* Doesn't matter if there's one in the same erase block. We're going to 834 /* Doesn't matter if there's one in the same erase block. We're going to
818 delete it too at the same time. */ 835 delete it too at the same time. */
819 if ((raw->flash_offset & ~(c->sector_size-1)) == 836 if (SECTOR_ADDR(raw->flash_offset) == SECTOR_ADDR(fd->raw->flash_offset))
820 (fd->raw->flash_offset & ~(c->sector_size-1)))
821 continue; 837 continue;
822 838
823 D1(printk(KERN_DEBUG "Check potential deletion dirent at %08x\n", ref_offset(raw))); 839 D1(printk(KERN_DEBUG "Check potential deletion dirent at %08x\n", ref_offset(raw)));
@@ -891,7 +907,7 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
891 struct jffs2_raw_inode ri; 907 struct jffs2_raw_inode ri;
892 struct jffs2_node_frag *frag; 908 struct jffs2_node_frag *frag;
893 struct jffs2_full_dnode *new_fn; 909 struct jffs2_full_dnode *new_fn;
894 uint32_t alloclen, phys_ofs; 910 uint32_t alloclen, phys_ofs, ilen;
895 int ret; 911 int ret;
896 912
897 D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n", 913 D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n",
@@ -951,10 +967,19 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
951 ri.csize = cpu_to_je32(0); 967 ri.csize = cpu_to_je32(0);
952 ri.compr = JFFS2_COMPR_ZERO; 968 ri.compr = JFFS2_COMPR_ZERO;
953 } 969 }
970
971 frag = frag_last(&f->fragtree);
972 if (frag)
973 /* Fetch the inode length from the fragtree rather then
974 * from i_size since i_size may have not been updated yet */
975 ilen = frag->ofs + frag->size;
976 else
977 ilen = JFFS2_F_I_SIZE(f);
978
954 ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f)); 979 ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
955 ri.uid = cpu_to_je16(JFFS2_F_I_UID(f)); 980 ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
956 ri.gid = cpu_to_je16(JFFS2_F_I_GID(f)); 981 ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
957 ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f)); 982 ri.isize = cpu_to_je32(ilen);
958 ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f)); 983 ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
959 ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f)); 984 ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
960 ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f)); 985 ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f));
@@ -1161,7 +1186,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
1161 D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n", 1186 D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n",
1162 orig_start, orig_end, start, end)); 1187 orig_start, orig_end, start, end));
1163 1188
1164 BUG_ON(end > JFFS2_F_I_SIZE(f)); 1189 D1(BUG_ON(end > frag_last(&f->fragtree)->ofs + frag_last(&f->fragtree)->size));
1165 BUG_ON(end < orig_end); 1190 BUG_ON(end < orig_end);
1166 BUG_ON(start > orig_start); 1191 BUG_ON(start > orig_start);
1167 } 1192 }
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
index cd6a8bd13e0b..c7bbdeec93a6 100644
--- a/fs/jffs2/nodelist.c
+++ b/fs/jffs2/nodelist.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: nodelist.c,v 1.90 2004/12/08 17:59:20 dwmw2 Exp $ 10 * $Id: nodelist.c,v 1.97 2005/07/06 15:18:41 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -58,27 +58,60 @@ void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new
58/* Put a new tmp_dnode_info into the list, keeping the list in 58/* Put a new tmp_dnode_info into the list, keeping the list in
59 order of increasing version 59 order of increasing version
60*/ 60*/
61static void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct jffs2_tmp_dnode_info **list) 61
62static void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct rb_root *list)
62{ 63{
63 struct jffs2_tmp_dnode_info **prev = list; 64 struct rb_node **p = &list->rb_node;
64 65 struct rb_node * parent = NULL;
65 while ((*prev) && (*prev)->version < tn->version) { 66 struct jffs2_tmp_dnode_info *this;
66 prev = &((*prev)->next); 67
67 } 68 while (*p) {
68 tn->next = (*prev); 69 parent = *p;
69 *prev = tn; 70 this = rb_entry(parent, struct jffs2_tmp_dnode_info, rb);
71
72 /* There may actually be a collision here, but it doesn't
73 actually matter. As long as the two nodes with the same
74 version are together, it's all fine. */
75 if (tn->version < this->version)
76 p = &(*p)->rb_left;
77 else
78 p = &(*p)->rb_right;
79 }
80
81 rb_link_node(&tn->rb, parent, p);
82 rb_insert_color(&tn->rb, list);
70} 83}
71 84
72static void jffs2_free_tmp_dnode_info_list(struct jffs2_tmp_dnode_info *tn) 85static void jffs2_free_tmp_dnode_info_list(struct rb_root *list)
73{ 86{
74 struct jffs2_tmp_dnode_info *next; 87 struct rb_node *this;
88 struct jffs2_tmp_dnode_info *tn;
89
90 this = list->rb_node;
91
92 /* Now at bottom of tree */
93 while (this) {
94 if (this->rb_left)
95 this = this->rb_left;
96 else if (this->rb_right)
97 this = this->rb_right;
98 else {
99 tn = rb_entry(this, struct jffs2_tmp_dnode_info, rb);
100 jffs2_free_full_dnode(tn->fn);
101 jffs2_free_tmp_dnode_info(tn);
102
103 this = this->rb_parent;
104 if (!this)
105 break;
75 106
76 while (tn) { 107 if (this->rb_left == &tn->rb)
77 next = tn; 108 this->rb_left = NULL;
78 tn = tn->next; 109 else if (this->rb_right == &tn->rb)
79 jffs2_free_full_dnode(next->fn); 110 this->rb_right = NULL;
80 jffs2_free_tmp_dnode_info(next); 111 else BUG();
112 }
81 } 113 }
114 list->rb_node = NULL;
82} 115}
83 116
84static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd) 117static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
@@ -108,12 +141,13 @@ static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_r
108 with this ino, returning the former in order of version */ 141 with this ino, returning the former in order of version */
109 142
110int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 143int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
111 struct jffs2_tmp_dnode_info **tnp, struct jffs2_full_dirent **fdp, 144 struct rb_root *tnp, struct jffs2_full_dirent **fdp,
112 uint32_t *highest_version, uint32_t *latest_mctime, 145 uint32_t *highest_version, uint32_t *latest_mctime,
113 uint32_t *mctime_ver) 146 uint32_t *mctime_ver)
114{ 147{
115 struct jffs2_raw_node_ref *ref, *valid_ref; 148 struct jffs2_raw_node_ref *ref, *valid_ref;
116 struct jffs2_tmp_dnode_info *tn, *ret_tn = NULL; 149 struct jffs2_tmp_dnode_info *tn;
150 struct rb_root ret_tn = RB_ROOT;
117 struct jffs2_full_dirent *fd, *ret_fd = NULL; 151 struct jffs2_full_dirent *fd, *ret_fd = NULL;
118 union jffs2_node_union node; 152 union jffs2_node_union node;
119 size_t retlen; 153 size_t retlen;
@@ -127,7 +161,7 @@ int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
127 161
128 valid_ref = jffs2_first_valid_node(f->inocache->nodes); 162 valid_ref = jffs2_first_valid_node(f->inocache->nodes);
129 163
130 if (!valid_ref) 164 if (!valid_ref && (f->inocache->ino != 1))
131 printk(KERN_WARNING "Eep. No valid nodes for ino #%u\n", f->inocache->ino); 165 printk(KERN_WARNING "Eep. No valid nodes for ino #%u\n", f->inocache->ino);
132 166
133 while (valid_ref) { 167 while (valid_ref) {
@@ -450,7 +484,7 @@ int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
450 return 0; 484 return 0;
451 485
452 free_out: 486 free_out:
453 jffs2_free_tmp_dnode_info_list(ret_tn); 487 jffs2_free_tmp_dnode_info_list(&ret_tn);
454 jffs2_free_full_dirent_list(ret_fd); 488 jffs2_free_full_dirent_list(ret_fd);
455 return err; 489 return err;
456} 490}
@@ -489,9 +523,13 @@ struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t
489void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new) 523void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new)
490{ 524{
491 struct jffs2_inode_cache **prev; 525 struct jffs2_inode_cache **prev;
492 D2(printk(KERN_DEBUG "jffs2_add_ino_cache: Add %p (ino #%u)\n", new, new->ino)); 526
493 spin_lock(&c->inocache_lock); 527 spin_lock(&c->inocache_lock);
494 528 if (!new->ino)
529 new->ino = ++c->highest_ino;
530
531 D2(printk(KERN_DEBUG "jffs2_add_ino_cache: Add %p (ino #%u)\n", new, new->ino));
532
495 prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE]; 533 prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE];
496 534
497 while ((*prev) && (*prev)->ino < new->ino) { 535 while ((*prev) && (*prev)->ino < new->ino) {
@@ -506,7 +544,7 @@ void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new
506void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old) 544void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
507{ 545{
508 struct jffs2_inode_cache **prev; 546 struct jffs2_inode_cache **prev;
509 D2(printk(KERN_DEBUG "jffs2_del_ino_cache: Del %p (ino #%u)\n", old, old->ino)); 547 D1(printk(KERN_DEBUG "jffs2_del_ino_cache: Del %p (ino #%u)\n", old, old->ino));
510 spin_lock(&c->inocache_lock); 548 spin_lock(&c->inocache_lock);
511 549
512 prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE]; 550 prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE];
@@ -518,6 +556,14 @@ void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
518 *prev = old->next; 556 *prev = old->next;
519 } 557 }
520 558
559 /* Free it now unless it's in READING or CLEARING state, which
560 are the transitions upon read_inode() and clear_inode(). The
561 rest of the time we know nobody else is looking at it, and
562 if it's held by read_inode() or clear_inode() they'll free it
563 for themselves. */
564 if (old->state != INO_STATE_READING && old->state != INO_STATE_CLEARING)
565 jffs2_free_inode_cache(old);
566
521 spin_unlock(&c->inocache_lock); 567 spin_unlock(&c->inocache_lock);
522} 568}
523 569
@@ -530,7 +576,6 @@ void jffs2_free_ino_caches(struct jffs2_sb_info *c)
530 this = c->inocache_list[i]; 576 this = c->inocache_list[i];
531 while (this) { 577 while (this) {
532 next = this->next; 578 next = this->next;
533 D2(printk(KERN_DEBUG "jffs2_free_ino_caches: Freeing ino #%u at %p\n", this->ino, this));
534 jffs2_free_inode_cache(this); 579 jffs2_free_inode_cache(this);
535 this = next; 580 this = next;
536 } 581 }
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index a4864d05ea92..b34c397909ef 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: nodelist.h,v 1.126 2004/11/19 15:06:29 dedekind Exp $ 10 * $Id: nodelist.h,v 1.131 2005/07/05 21:03:07 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -135,6 +135,7 @@ struct jffs2_inode_cache {
135#define INO_STATE_CHECKEDABSENT 3 /* Checked, cleared again */ 135#define INO_STATE_CHECKEDABSENT 3 /* Checked, cleared again */
136#define INO_STATE_GC 4 /* GCing a 'pristine' node */ 136#define INO_STATE_GC 4 /* GCing a 'pristine' node */
137#define INO_STATE_READING 5 /* In read_inode() */ 137#define INO_STATE_READING 5 /* In read_inode() */
138#define INO_STATE_CLEARING 6 /* In clear_inode() */
138 139
139#define INOCACHE_HASHSIZE 128 140#define INOCACHE_HASHSIZE 128
140 141
@@ -160,7 +161,7 @@ struct jffs2_full_dnode
160*/ 161*/
161struct jffs2_tmp_dnode_info 162struct jffs2_tmp_dnode_info
162{ 163{
163 struct jffs2_tmp_dnode_info *next; 164 struct rb_node rb;
164 struct jffs2_full_dnode *fn; 165 struct jffs2_full_dnode *fn;
165 uint32_t version; 166 uint32_t version;
166}; 167};
@@ -362,6 +363,18 @@ static inline struct jffs2_node_frag *frag_first(struct rb_root *root)
362 node = node->rb_left; 363 node = node->rb_left;
363 return rb_entry(node, struct jffs2_node_frag, rb); 364 return rb_entry(node, struct jffs2_node_frag, rb);
364} 365}
366
367static inline struct jffs2_node_frag *frag_last(struct rb_root *root)
368{
369 struct rb_node *node = root->rb_node;
370
371 if (!node)
372 return NULL;
373 while(node->rb_right)
374 node = node->rb_right;
375 return rb_entry(node, struct jffs2_node_frag, rb);
376}
377
365#define rb_parent(rb) ((rb)->rb_parent) 378#define rb_parent(rb) ((rb)->rb_parent)
366#define frag_next(frag) rb_entry(rb_next(&(frag)->rb), struct jffs2_node_frag, rb) 379#define frag_next(frag) rb_entry(rb_next(&(frag)->rb), struct jffs2_node_frag, rb)
367#define frag_prev(frag) rb_entry(rb_prev(&(frag)->rb), struct jffs2_node_frag, rb) 380#define frag_prev(frag) rb_entry(rb_prev(&(frag)->rb), struct jffs2_node_frag, rb)
@@ -374,7 +387,7 @@ static inline struct jffs2_node_frag *frag_first(struct rb_root *root)
374D2(void jffs2_print_frag_list(struct jffs2_inode_info *f)); 387D2(void jffs2_print_frag_list(struct jffs2_inode_info *f));
375void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list); 388void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list);
376int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 389int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
377 struct jffs2_tmp_dnode_info **tnp, struct jffs2_full_dirent **fdp, 390 struct rb_root *tnp, struct jffs2_full_dirent **fdp,
378 uint32_t *highest_version, uint32_t *latest_mctime, 391 uint32_t *highest_version, uint32_t *latest_mctime,
379 uint32_t *mctime_ver); 392 uint32_t *mctime_ver);
380void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state); 393void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state);
@@ -462,7 +475,7 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c);
462/* erase.c */ 475/* erase.c */
463void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count); 476void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count);
464 477
465#ifdef CONFIG_JFFS2_FS_NAND 478#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
466/* wbuf.c */ 479/* wbuf.c */
467int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino); 480int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino);
468int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c); 481int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c);
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
index 2651135bdf42..c1d8b5ed9ab9 100644
--- a/fs/jffs2/nodemgmt.c
+++ b/fs/jffs2/nodemgmt.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: nodemgmt.c,v 1.115 2004/11/22 11:07:21 dwmw2 Exp $ 10 * $Id: nodemgmt.c,v 1.122 2005/05/06 09:30:27 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -75,7 +75,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs
75 dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size + c->unchecked_size; 75 dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size + c->unchecked_size;
76 if (dirty < c->nospc_dirty_size) { 76 if (dirty < c->nospc_dirty_size) {
77 if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) { 77 if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) {
78 printk(KERN_NOTICE "jffs2_reserve_space(): Low on dirty space to GC, but it's a deletion. Allowing...\n"); 78 D1(printk(KERN_NOTICE "jffs2_reserve_space(): Low on dirty space to GC, but it's a deletion. Allowing...\n"));
79 break; 79 break;
80 } 80 }
81 D1(printk(KERN_DEBUG "dirty size 0x%08x + unchecked_size 0x%08x < nospc_dirty_size 0x%08x, returning -ENOSPC\n", 81 D1(printk(KERN_DEBUG "dirty size 0x%08x + unchecked_size 0x%08x < nospc_dirty_size 0x%08x, returning -ENOSPC\n",
@@ -98,7 +98,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs
98 avail = c->free_size + c->dirty_size + c->erasing_size + c->unchecked_size; 98 avail = c->free_size + c->dirty_size + c->erasing_size + c->unchecked_size;
99 if ( (avail / c->sector_size) <= blocksneeded) { 99 if ( (avail / c->sector_size) <= blocksneeded) {
100 if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) { 100 if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) {
101 printk(KERN_NOTICE "jffs2_reserve_space(): Low on possibly available space, but it's a deletion. Allowing...\n"); 101 D1(printk(KERN_NOTICE "jffs2_reserve_space(): Low on possibly available space, but it's a deletion. Allowing...\n"));
102 break; 102 break;
103 } 103 }
104 104
@@ -308,7 +308,10 @@ int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_r
308 308
309 D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n", ref_offset(new), ref_flags(new), len)); 309 D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n", ref_offset(new), ref_flags(new), len));
310#if 1 310#if 1
311 if (jeb != c->nextblock || (ref_offset(new)) != jeb->offset + (c->sector_size - jeb->free_size)) { 311 /* we could get some obsolete nodes after nextblock was refiled
312 in wbuf.c */
313 if ((c->nextblock || !ref_obsolete(new))
314 &&(jeb != c->nextblock || ref_offset(new) != jeb->offset + (c->sector_size - jeb->free_size))) {
312 printk(KERN_WARNING "argh. node added in wrong place\n"); 315 printk(KERN_WARNING "argh. node added in wrong place\n");
313 jffs2_free_raw_node_ref(new); 316 jffs2_free_raw_node_ref(new);
314 return -EINVAL; 317 return -EINVAL;
@@ -332,7 +335,7 @@ int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_r
332 c->used_size += len; 335 c->used_size += len;
333 } 336 }
334 337
335 if (!jeb->free_size && !jeb->dirty_size) { 338 if (!jeb->free_size && !jeb->dirty_size && !ISDIRTY(jeb->wasted_size)) {
336 /* If it lives on the dirty_list, jffs2_reserve_space will put it there */ 339 /* If it lives on the dirty_list, jffs2_reserve_space will put it there */
337 D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", 340 D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
338 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); 341 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
@@ -400,7 +403,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
400 jeb = &c->blocks[blocknr]; 403 jeb = &c->blocks[blocknr];
401 404
402 if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) && 405 if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) &&
403 !(c->flags & JFFS2_SB_FLAG_MOUNTING)) { 406 !(c->flags & (JFFS2_SB_FLAG_SCANNING | JFFS2_SB_FLAG_BUILDING))) {
404 /* Hm. This may confuse static lock analysis. If any of the above 407 /* Hm. This may confuse static lock analysis. If any of the above
405 three conditions is false, we're going to return from this 408 three conditions is false, we're going to return from this
406 function without actually obliterating any nodes or freeing 409 function without actually obliterating any nodes or freeing
@@ -434,7 +437,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
434 437
435 // Take care, that wasted size is taken into concern 438 // Take care, that wasted size is taken into concern
436 if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref_totlen(c, jeb, ref))) && jeb != c->nextblock) { 439 if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref_totlen(c, jeb, ref))) && jeb != c->nextblock) {
437 D1(printk("Dirtying\n")); 440 D1(printk(KERN_DEBUG "Dirtying\n"));
438 addedsize = ref_totlen(c, jeb, ref); 441 addedsize = ref_totlen(c, jeb, ref);
439 jeb->dirty_size += ref_totlen(c, jeb, ref); 442 jeb->dirty_size += ref_totlen(c, jeb, ref);
440 c->dirty_size += ref_totlen(c, jeb, ref); 443 c->dirty_size += ref_totlen(c, jeb, ref);
@@ -456,7 +459,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
456 } 459 }
457 } 460 }
458 } else { 461 } else {
459 D1(printk("Wasting\n")); 462 D1(printk(KERN_DEBUG "Wasting\n"));
460 addedsize = 0; 463 addedsize = 0;
461 jeb->wasted_size += ref_totlen(c, jeb, ref); 464 jeb->wasted_size += ref_totlen(c, jeb, ref);
462 c->wasted_size += ref_totlen(c, jeb, ref); 465 c->wasted_size += ref_totlen(c, jeb, ref);
@@ -467,8 +470,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
467 470
468 D1(ACCT_PARANOIA_CHECK(jeb)); 471 D1(ACCT_PARANOIA_CHECK(jeb));
469 472
470 if (c->flags & JFFS2_SB_FLAG_MOUNTING) { 473 if (c->flags & JFFS2_SB_FLAG_SCANNING) {
471 /* Mount in progress. Don't muck about with the block 474 /* Flash scanning is in progress. Don't muck about with the block
472 lists because they're not ready yet, and don't actually 475 lists because they're not ready yet, and don't actually
473 obliterate nodes that look obsolete. If they weren't 476 obliterate nodes that look obsolete. If they weren't
474 marked obsolete on the flash at the time they _became_ 477 marked obsolete on the flash at the time they _became_
@@ -527,7 +530,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
527 530
528 spin_unlock(&c->erase_completion_lock); 531 spin_unlock(&c->erase_completion_lock);
529 532
530 if (!jffs2_can_mark_obsolete(c) || jffs2_is_readonly(c)) { 533 if (!jffs2_can_mark_obsolete(c) || jffs2_is_readonly(c) ||
534 (c->flags & JFFS2_SB_FLAG_BUILDING)) {
531 /* We didn't lock the erase_free_sem */ 535 /* We didn't lock the erase_free_sem */
532 return; 536 return;
533 } 537 }
@@ -590,11 +594,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
590 *p = ref->next_in_ino; 594 *p = ref->next_in_ino;
591 ref->next_in_ino = NULL; 595 ref->next_in_ino = NULL;
592 596
593 if (ic->nodes == (void *)ic) { 597 if (ic->nodes == (void *)ic && ic->nlink == 0)
594 D1(printk(KERN_DEBUG "inocache for ino #%u is all gone now. Freeing\n", ic->ino));
595 jffs2_del_ino_cache(c, ic); 598 jffs2_del_ino_cache(c, ic);
596 jffs2_free_inode_cache(ic);
597 }
598 599
599 spin_unlock(&c->erase_completion_lock); 600 spin_unlock(&c->erase_completion_lock);
600 } 601 }
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index 03b0acc37b73..7bf72e012c94 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -7,41 +7,24 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: os-linux.h,v 1.51 2004/11/16 20:36:11 dwmw2 Exp $ 10 * $Id: os-linux.h,v 1.57 2005/07/06 12:13:09 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
14#ifndef __JFFS2_OS_LINUX_H__ 14#ifndef __JFFS2_OS_LINUX_H__
15#define __JFFS2_OS_LINUX_H__ 15#define __JFFS2_OS_LINUX_H__
16#include <linux/version.h>
17 16
18/* JFFS2 uses Linux mode bits natively -- no need for conversion */ 17/* JFFS2 uses Linux mode bits natively -- no need for conversion */
19#define os_to_jffs2_mode(x) (x) 18#define os_to_jffs2_mode(x) (x)
20#define jffs2_to_os_mode(x) (x) 19#define jffs2_to_os_mode(x) (x)
21 20
22#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,73)
23#define kstatfs statfs
24#endif
25
26struct kstatfs; 21struct kstatfs;
27struct kvec; 22struct kvec;
28 23
29#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
30#define JFFS2_INODE_INFO(i) (list_entry(i, struct jffs2_inode_info, vfs_inode)) 24#define JFFS2_INODE_INFO(i) (list_entry(i, struct jffs2_inode_info, vfs_inode))
31#define OFNI_EDONI_2SFFJ(f) (&(f)->vfs_inode) 25#define OFNI_EDONI_2SFFJ(f) (&(f)->vfs_inode)
32#define JFFS2_SB_INFO(sb) (sb->s_fs_info) 26#define JFFS2_SB_INFO(sb) (sb->s_fs_info)
33#define OFNI_BS_2SFFJ(c) ((struct super_block *)c->os_priv) 27#define OFNI_BS_2SFFJ(c) ((struct super_block *)c->os_priv)
34#elif defined(JFFS2_OUT_OF_KERNEL)
35#define JFFS2_INODE_INFO(i) ((struct jffs2_inode_info *) &(i)->u)
36#define OFNI_EDONI_2SFFJ(f) ((struct inode *) ( ((char *)f) - ((char *)(&((struct inode *)NULL)->u)) ) )
37#define JFFS2_SB_INFO(sb) ((struct jffs2_sb_info *) &(sb)->u)
38#define OFNI_BS_2SFFJ(c) ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) )
39#else
40#define JFFS2_INODE_INFO(i) (&i->u.jffs2_i)
41#define OFNI_EDONI_2SFFJ(f) ((struct inode *) ( ((char *)f) - ((char *)(&((struct inode *)NULL)->u)) ) )
42#define JFFS2_SB_INFO(sb) (&sb->u.jffs2_sb)
43#define OFNI_BS_2SFFJ(c) ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) )
44#endif
45 28
46 29
47#define JFFS2_F_I_SIZE(f) (OFNI_EDONI_2SFFJ(f)->i_size) 30#define JFFS2_F_I_SIZE(f) (OFNI_EDONI_2SFFJ(f)->i_size)
@@ -49,28 +32,14 @@ struct kvec;
49#define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid) 32#define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid)
50#define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid) 33#define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid)
51 34
52#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,1)
53#define JFFS2_F_I_RDEV_MIN(f) (iminor(OFNI_EDONI_2SFFJ(f))) 35#define JFFS2_F_I_RDEV_MIN(f) (iminor(OFNI_EDONI_2SFFJ(f)))
54#define JFFS2_F_I_RDEV_MAJ(f) (imajor(OFNI_EDONI_2SFFJ(f))) 36#define JFFS2_F_I_RDEV_MAJ(f) (imajor(OFNI_EDONI_2SFFJ(f)))
55#else
56#define JFFS2_F_I_RDEV_MIN(f) (MINOR(to_kdev_t(OFNI_EDONI_2SFFJ(f)->i_rdev)))
57#define JFFS2_F_I_RDEV_MAJ(f) (MAJOR(to_kdev_t(OFNI_EDONI_2SFFJ(f)->i_rdev)))
58#endif
59 37
60/* Urgh. The things we do to keep the 2.4 build working */
61#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,47)
62#define ITIME(sec) ((struct timespec){sec, 0}) 38#define ITIME(sec) ((struct timespec){sec, 0})
63#define I_SEC(tv) ((tv).tv_sec) 39#define I_SEC(tv) ((tv).tv_sec)
64#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime.tv_sec) 40#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime.tv_sec)
65#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime.tv_sec) 41#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime.tv_sec)
66#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime.tv_sec) 42#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime.tv_sec)
67#else
68#define ITIME(x) (x)
69#define I_SEC(x) (x)
70#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime)
71#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime)
72#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime)
73#endif
74 43
75#define sleep_on_spinunlock(wq, s) \ 44#define sleep_on_spinunlock(wq, s) \
76 do { \ 45 do { \
@@ -84,23 +53,21 @@ struct kvec;
84 53
85static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) 54static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
86{ 55{
87#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
88 f->highest_version = 0; 56 f->highest_version = 0;
89 f->fragtree = RB_ROOT; 57 f->fragtree = RB_ROOT;
90 f->metadata = NULL; 58 f->metadata = NULL;
91 f->dents = NULL; 59 f->dents = NULL;
92 f->flags = 0; 60 f->flags = 0;
93 f->usercompr = 0; 61 f->usercompr = 0;
94#else
95 memset(f, 0, sizeof(*f));
96 init_MUTEX_LOCKED(&f->sem);
97#endif
98} 62}
99 63
64
100#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY) 65#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
101 66
102#if (!defined CONFIG_JFFS2_FS_NAND && !defined CONFIG_JFFS2_FS_NOR_ECC) 67#ifndef CONFIG_JFFS2_FS_WRITEBUFFER
68#define SECTOR_ADDR(x) ( ((unsigned long)(x) & ~(c->sector_size-1)) )
103#define jffs2_can_mark_obsolete(c) (1) 69#define jffs2_can_mark_obsolete(c) (1)
70#define jffs2_is_writebuffered(c) (0)
104#define jffs2_cleanmarker_oob(c) (0) 71#define jffs2_cleanmarker_oob(c) (0)
105#define jffs2_write_nand_cleanmarker(c,jeb) (-EIO) 72#define jffs2_write_nand_cleanmarker(c,jeb) (-EIO)
106 73
@@ -116,11 +83,14 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
116#define jffs2_wbuf_timeout NULL 83#define jffs2_wbuf_timeout NULL
117#define jffs2_wbuf_process NULL 84#define jffs2_wbuf_process NULL
118#define jffs2_nor_ecc(c) (0) 85#define jffs2_nor_ecc(c) (0)
86#define jffs2_dataflash(c) (0)
119#define jffs2_nor_ecc_flash_setup(c) (0) 87#define jffs2_nor_ecc_flash_setup(c) (0)
120#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0) 88#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0)
121 89
122#else /* NAND and/or ECC'd NOR support present */ 90#else /* NAND and/or ECC'd NOR support present */
123 91
92#define jffs2_is_writebuffered(c) (c->wbuf != NULL)
93#define SECTOR_ADDR(x) ( ((unsigned long)(x) / (unsigned long)(c->sector_size)) * c->sector_size )
124#define jffs2_can_mark_obsolete(c) ((c->mtd->type == MTD_NORFLASH && !(c->mtd->flags & MTD_ECC)) || c->mtd->type == MTD_RAM) 94#define jffs2_can_mark_obsolete(c) ((c->mtd->type == MTD_NORFLASH && !(c->mtd->flags & MTD_ECC)) || c->mtd->type == MTD_RAM)
125#define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH) 95#define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH)
126 96
@@ -142,16 +112,16 @@ int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino);
142int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c); 112int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c);
143int jffs2_nand_flash_setup(struct jffs2_sb_info *c); 113int jffs2_nand_flash_setup(struct jffs2_sb_info *c);
144void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c); 114void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c);
145#ifdef CONFIG_JFFS2_FS_NOR_ECC 115
146#define jffs2_nor_ecc(c) (c->mtd->type == MTD_NORFLASH && (c->mtd->flags & MTD_ECC)) 116#define jffs2_nor_ecc(c) (c->mtd->type == MTD_NORFLASH && (c->mtd->flags & MTD_ECC))
147int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c); 117int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c);
148void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c); 118void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c);
149#else 119
150#define jffs2_nor_ecc(c) (0) 120#define jffs2_dataflash(c) (c->mtd->type == MTD_DATAFLASH)
151#define jffs2_nor_ecc_flash_setup(c) (0) 121int jffs2_dataflash_setup(struct jffs2_sb_info *c);
152#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0) 122void jffs2_dataflash_cleanup(struct jffs2_sb_info *c);
153#endif /* NOR ECC */ 123
154#endif /* NAND */ 124#endif /* WRITEBUFFER */
155 125
156/* erase.c */ 126/* erase.c */
157static inline void jffs2_erase_pending_trigger(struct jffs2_sb_info *c) 127static inline void jffs2_erase_pending_trigger(struct jffs2_sb_info *c)
diff --git a/fs/jffs2/read.c b/fs/jffs2/read.c
index eb493dc06db7..c7f9068907cf 100644
--- a/fs/jffs2/read.c
+++ b/fs/jffs2/read.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: read.c,v 1.38 2004/11/16 20:36:12 dwmw2 Exp $ 10 * $Id: read.c,v 1.39 2005/03/01 10:34:03 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -214,33 +214,3 @@ int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
214 return 0; 214 return 0;
215} 215}
216 216
217/* Core function to read symlink target. */
218char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
219{
220 char *buf;
221 int ret;
222
223 down(&f->sem);
224
225 if (!f->metadata) {
226 printk(KERN_NOTICE "No metadata for symlink inode #%u\n", f->inocache->ino);
227 up(&f->sem);
228 return ERR_PTR(-EINVAL);
229 }
230 buf = kmalloc(f->metadata->size+1, GFP_USER);
231 if (!buf) {
232 up(&f->sem);
233 return ERR_PTR(-ENOMEM);
234 }
235 buf[f->metadata->size]=0;
236
237 ret = jffs2_read_dnode(c, f, f->metadata, buf, 0, f->metadata->size);
238
239 up(&f->sem);
240
241 if (ret) {
242 kfree(buf);
243 return ERR_PTR(ret);
244 }
245 return buf;
246}
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index aca4a0b17bcd..081656c1d49e 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: readinode.c,v 1.117 2004/11/20 18:06:54 dwmw2 Exp $ 10 * $Id: readinode.c,v 1.120 2005/07/05 21:03:07 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -500,7 +500,9 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
500 struct jffs2_inode_info *f, 500 struct jffs2_inode_info *f,
501 struct jffs2_raw_inode *latest_node) 501 struct jffs2_raw_inode *latest_node)
502{ 502{
503 struct jffs2_tmp_dnode_info *tn_list, *tn; 503 struct jffs2_tmp_dnode_info *tn = NULL;
504 struct rb_root tn_list;
505 struct rb_node *rb, *repl_rb;
504 struct jffs2_full_dirent *fd_list; 506 struct jffs2_full_dirent *fd_list;
505 struct jffs2_full_dnode *fn = NULL; 507 struct jffs2_full_dnode *fn = NULL;
506 uint32_t crc; 508 uint32_t crc;
@@ -522,9 +524,10 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
522 } 524 }
523 f->dents = fd_list; 525 f->dents = fd_list;
524 526
525 while (tn_list) { 527 rb = rb_first(&tn_list);
526 tn = tn_list;
527 528
529 while (rb) {
530 tn = rb_entry(rb, struct jffs2_tmp_dnode_info, rb);
528 fn = tn->fn; 531 fn = tn->fn;
529 532
530 if (f->metadata) { 533 if (f->metadata) {
@@ -556,7 +559,30 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
556 mdata_ver = tn->version; 559 mdata_ver = tn->version;
557 } 560 }
558 next_tn: 561 next_tn:
559 tn_list = tn->next; 562 BUG_ON(rb->rb_left);
563 repl_rb = NULL;
564 if (rb->rb_parent && rb->rb_parent->rb_left == rb) {
565 /* We were then left-hand child of our parent. We need
566 to move our own right-hand child into our place. */
567 repl_rb = rb->rb_right;
568 if (repl_rb)
569 repl_rb->rb_parent = rb->rb_parent;
570 } else
571 repl_rb = NULL;
572
573 rb = rb_next(rb);
574
575 /* Remove the spent tn from the tree; don't bother rebalancing
576 but put our right-hand child in our own place. */
577 if (tn->rb.rb_parent) {
578 if (tn->rb.rb_parent->rb_left == &tn->rb)
579 tn->rb.rb_parent->rb_left = repl_rb;
580 else if (tn->rb.rb_parent->rb_right == &tn->rb)
581 tn->rb.rb_parent->rb_right = repl_rb;
582 else BUG();
583 } else if (tn->rb.rb_right)
584 tn->rb.rb_right->rb_parent = NULL;
585
560 jffs2_free_tmp_dnode_info(tn); 586 jffs2_free_tmp_dnode_info(tn);
561 } 587 }
562 D1(jffs2_sanitycheck_fragtree(f)); 588 D1(jffs2_sanitycheck_fragtree(f));
@@ -623,6 +649,40 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
623 case. */ 649 case. */
624 if (!je32_to_cpu(latest_node->isize)) 650 if (!je32_to_cpu(latest_node->isize))
625 latest_node->isize = latest_node->dsize; 651 latest_node->isize = latest_node->dsize;
652
653 if (f->inocache->state != INO_STATE_CHECKING) {
654 /* Symlink's inode data is the target path. Read it and
655 * keep in RAM to facilitate quick follow symlink operation.
656 * We use f->dents field to store the target path, which
657 * is somewhat ugly. */
658 f->dents = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL);
659 if (!f->dents) {
660 printk(KERN_WARNING "Can't allocate %d bytes of memory "
661 "for the symlink target path cache\n",
662 je32_to_cpu(latest_node->csize));
663 up(&f->sem);
664 jffs2_do_clear_inode(c, f);
665 return -ENOMEM;
666 }
667
668 ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node),
669 je32_to_cpu(latest_node->csize), &retlen, (char *)f->dents);
670
671 if (ret || retlen != je32_to_cpu(latest_node->csize)) {
672 if (retlen != je32_to_cpu(latest_node->csize))
673 ret = -EIO;
674 kfree(f->dents);
675 f->dents = NULL;
676 up(&f->sem);
677 jffs2_do_clear_inode(c, f);
678 return -ret;
679 }
680
681 ((char *)f->dents)[je32_to_cpu(latest_node->csize)] = '\0';
682 D1(printk(KERN_DEBUG "jffs2_do_read_inode(): symlink's target '%s' cached\n",
683 (char *)f->dents));
684 }
685
626 /* fall through... */ 686 /* fall through... */
627 687
628 case S_IFBLK: 688 case S_IFBLK:
@@ -672,6 +732,9 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
672 down(&f->sem); 732 down(&f->sem);
673 deleted = f->inocache && !f->inocache->nlink; 733 deleted = f->inocache && !f->inocache->nlink;
674 734
735 if (f->inocache && f->inocache->state != INO_STATE_CHECKING)
736 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING);
737
675 if (f->metadata) { 738 if (f->metadata) {
676 if (deleted) 739 if (deleted)
677 jffs2_mark_node_obsolete(c, f->metadata->raw); 740 jffs2_mark_node_obsolete(c, f->metadata->raw);
@@ -680,16 +743,27 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
680 743
681 jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL); 744 jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL);
682 745
683 fds = f->dents; 746 /* For symlink inodes we us f->dents to store the target path name */
747 if (S_ISLNK(OFNI_EDONI_2SFFJ(f)->i_mode)) {
748 if (f->dents) {
749 kfree(f->dents);
750 f->dents = NULL;
751 }
752 } else {
753 fds = f->dents;
684 754
685 while(fds) { 755 while(fds) {
686 fd = fds; 756 fd = fds;
687 fds = fd->next; 757 fds = fd->next;
688 jffs2_free_full_dirent(fd); 758 jffs2_free_full_dirent(fd);
759 }
689 } 760 }
690 761
691 if (f->inocache && f->inocache->state != INO_STATE_CHECKING) 762 if (f->inocache && f->inocache->state != INO_STATE_CHECKING) {
692 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); 763 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
764 if (f->inocache->nodes == (void *)f->inocache)
765 jffs2_del_ino_cache(c, f->inocache);
766 }
693 767
694 up(&f->sem); 768 up(&f->sem);
695} 769}
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index ded53584a897..b63160f83bab 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: scan.c,v 1.115 2004/11/17 12:59:08 dedekind Exp $ 10 * $Id: scan.c,v 1.119 2005/02/17 17:51:13 dedekind Exp $
11 * 11 *
12 */ 12 */
13#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -19,7 +19,7 @@
19#include <linux/compiler.h> 19#include <linux/compiler.h>
20#include "nodelist.h" 20#include "nodelist.h"
21 21
22#define EMPTY_SCAN_SIZE 1024 22#define DEFAULT_EMPTY_SCAN_SIZE 1024
23 23
24#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \ 24#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
25 c->free_size -= _x; c->dirty_size += _x; \ 25 c->free_size -= _x; c->dirty_size += _x; \
@@ -68,13 +68,21 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
68static inline int min_free(struct jffs2_sb_info *c) 68static inline int min_free(struct jffs2_sb_info *c)
69{ 69{
70 uint32_t min = 2 * sizeof(struct jffs2_raw_inode); 70 uint32_t min = 2 * sizeof(struct jffs2_raw_inode);
71#if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC 71#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
72 if (!jffs2_can_mark_obsolete(c) && min < c->wbuf_pagesize) 72 if (!jffs2_can_mark_obsolete(c) && min < c->wbuf_pagesize)
73 return c->wbuf_pagesize; 73 return c->wbuf_pagesize;
74#endif 74#endif
75 return min; 75 return min;
76 76
77} 77}
78
79static inline uint32_t EMPTY_SCAN_SIZE(uint32_t sector_size) {
80 if (sector_size < DEFAULT_EMPTY_SCAN_SIZE)
81 return sector_size;
82 else
83 return DEFAULT_EMPTY_SCAN_SIZE;
84}
85
78int jffs2_scan_medium(struct jffs2_sb_info *c) 86int jffs2_scan_medium(struct jffs2_sb_info *c)
79{ 87{
80 int i, ret; 88 int i, ret;
@@ -220,7 +228,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
220 c->dirty_size -= c->nextblock->dirty_size; 228 c->dirty_size -= c->nextblock->dirty_size;
221 c->nextblock->dirty_size = 0; 229 c->nextblock->dirty_size = 0;
222 } 230 }
223#if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC 231#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
224 if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) { 232 if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) {
225 /* If we're going to start writing into a block which already 233 /* If we're going to start writing into a block which already
226 contains data, and the end of the data isn't page-aligned, 234 contains data, and the end of the data isn't page-aligned,
@@ -286,7 +294,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
286 uint32_t hdr_crc, buf_ofs, buf_len; 294 uint32_t hdr_crc, buf_ofs, buf_len;
287 int err; 295 int err;
288 int noise = 0; 296 int noise = 0;
289#ifdef CONFIG_JFFS2_FS_NAND 297#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
290 int cleanmarkerfound = 0; 298 int cleanmarkerfound = 0;
291#endif 299#endif
292 300
@@ -295,7 +303,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
295 303
296 D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs)); 304 D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs));
297 305
298#ifdef CONFIG_JFFS2_FS_NAND 306#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
299 if (jffs2_cleanmarker_oob(c)) { 307 if (jffs2_cleanmarker_oob(c)) {
300 int ret = jffs2_check_nand_cleanmarker(c, jeb); 308 int ret = jffs2_check_nand_cleanmarker(c, jeb);
301 D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret)); 309 D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret));
@@ -316,7 +324,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
316 if (!buf_size) { 324 if (!buf_size) {
317 buf_len = c->sector_size; 325 buf_len = c->sector_size;
318 } else { 326 } else {
319 buf_len = EMPTY_SCAN_SIZE; 327 buf_len = EMPTY_SCAN_SIZE(c->sector_size);
320 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len); 328 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
321 if (err) 329 if (err)
322 return err; 330 return err;
@@ -326,11 +334,11 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
326 ofs = 0; 334 ofs = 0;
327 335
328 /* Scan only 4KiB of 0xFF before declaring it's empty */ 336 /* Scan only 4KiB of 0xFF before declaring it's empty */
329 while(ofs < EMPTY_SCAN_SIZE && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF) 337 while(ofs < EMPTY_SCAN_SIZE(c->sector_size) && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF)
330 ofs += 4; 338 ofs += 4;
331 339
332 if (ofs == EMPTY_SCAN_SIZE) { 340 if (ofs == EMPTY_SCAN_SIZE(c->sector_size)) {
333#ifdef CONFIG_JFFS2_FS_NAND 341#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
334 if (jffs2_cleanmarker_oob(c)) { 342 if (jffs2_cleanmarker_oob(c)) {
335 /* scan oob, take care of cleanmarker */ 343 /* scan oob, take care of cleanmarker */
336 int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound); 344 int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound);
@@ -343,7 +351,10 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
343 } 351 }
344#endif 352#endif
345 D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset)); 353 D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset));
346 return BLK_STATE_ALLFF; /* OK to erase if all blocks are like this */ 354 if (c->cleanmarker_size == 0)
355 return BLK_STATE_CLEANMARKER; /* don't bother with re-erase */
356 else
357 return BLK_STATE_ALLFF; /* OK to erase if all blocks are like this */
347 } 358 }
348 if (ofs) { 359 if (ofs) {
349 D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset, 360 D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset,
@@ -422,8 +433,8 @@ scan_more:
422 /* If we're only checking the beginning of a block with a cleanmarker, 433 /* If we're only checking the beginning of a block with a cleanmarker,
423 bail now */ 434 bail now */
424 if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) && 435 if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) &&
425 c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_in_ino) { 436 c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_phys) {
426 D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE)); 437 D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size)));
427 return BLK_STATE_CLEANMARKER; 438 return BLK_STATE_CLEANMARKER;
428 } 439 }
429 440
@@ -618,7 +629,7 @@ scan_more:
618 } 629 }
619 630
620 if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size 631 if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size
621 && (!jeb->first_node || !jeb->first_node->next_in_ino) ) 632 && (!jeb->first_node || !jeb->first_node->next_phys) )
622 return BLK_STATE_CLEANMARKER; 633 return BLK_STATE_CLEANMARKER;
623 634
624 /* move blocks with max 4 byte dirty space to cleanlist */ 635 /* move blocks with max 4 byte dirty space to cleanlist */
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 6b2a441d2766..2cf14cf8b35a 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: super.c,v 1.104 2004/11/23 15:37:31 gleixner Exp $ 10 * $Id: super.c,v 1.106 2005/05/18 11:37:25 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -270,8 +270,6 @@ static void jffs2_put_super (struct super_block *sb)
270 270
271 D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n")); 271 D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n"));
272 272
273 if (!(sb->s_flags & MS_RDONLY))
274 jffs2_stop_garbage_collect_thread(c);
275 down(&c->alloc_sem); 273 down(&c->alloc_sem);
276 jffs2_flush_wbuf_pad(c); 274 jffs2_flush_wbuf_pad(c);
277 up(&c->alloc_sem); 275 up(&c->alloc_sem);
@@ -292,6 +290,8 @@ static void jffs2_put_super (struct super_block *sb)
292static void jffs2_kill_sb(struct super_block *sb) 290static void jffs2_kill_sb(struct super_block *sb)
293{ 291{
294 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); 292 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
293 if (!(sb->s_flags & MS_RDONLY))
294 jffs2_stop_garbage_collect_thread(c);
295 generic_shutdown_super(sb); 295 generic_shutdown_super(sb);
296 put_mtd_device(c->mtd); 296 put_mtd_device(c->mtd);
297 kfree(c); 297 kfree(c);
@@ -309,7 +309,7 @@ static int __init init_jffs2_fs(void)
309 int ret; 309 int ret;
310 310
311 printk(KERN_INFO "JFFS2 version 2.2." 311 printk(KERN_INFO "JFFS2 version 2.2."
312#ifdef CONFIG_JFFS2_FS_NAND 312#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
313 " (NAND)" 313 " (NAND)"
314#endif 314#endif
315 " (C) 2001-2003 Red Hat, Inc.\n"); 315 " (C) 2001-2003 Red Hat, Inc.\n");
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
index 7b1820d13712..65ab6b001dca 100644
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: symlink.c,v 1.14 2004/11/16 20:36:12 dwmw2 Exp $ 10 * $Id: symlink.c,v 1.16 2005/03/01 10:50:48 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -19,27 +19,45 @@
19#include "nodelist.h" 19#include "nodelist.h"
20 20
21static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd); 21static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd);
22static void jffs2_put_link(struct dentry *dentry, struct nameidata *nd);
23 22
24struct inode_operations jffs2_symlink_inode_operations = 23struct inode_operations jffs2_symlink_inode_operations =
25{ 24{
26 .readlink = generic_readlink, 25 .readlink = generic_readlink,
27 .follow_link = jffs2_follow_link, 26 .follow_link = jffs2_follow_link,
28 .put_link = jffs2_put_link,
29 .setattr = jffs2_setattr 27 .setattr = jffs2_setattr
30}; 28};
31 29
32static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd) 30static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
33{ 31{
34 unsigned char *buf; 32 struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode);
35 buf = jffs2_getlink(JFFS2_SB_INFO(dentry->d_inode->i_sb), JFFS2_INODE_INFO(dentry->d_inode)); 33
36 nd_set_link(nd, buf); 34 /*
35 * We don't acquire the f->sem mutex here since the only data we
36 * use is f->dents which in case of the symlink inode points to the
37 * symlink's target path.
38 *
39 * 1. If we are here the inode has already built and f->dents has
40 * to point to the target path.
41 * 2. Nobody uses f->dents (if the inode is symlink's inode). The
42 * exception is inode freeing function which frees f->dents. But
43 * it can't be called while we are here and before VFS has
44 * stopped using our f->dents string which we provide by means of
45 * nd_set_link() call.
46 */
47
48 if (!f->dents) {
49 printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n");
50 return -EIO;
51 }
52 D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->dents));
53
54 nd_set_link(nd, (char *)f->dents);
55
56 /*
57 * We unlock the f->sem mutex but VFS will use the f->dents string. This is safe
58 * since the only way that may cause f->dents to be changed is iput() operation.
59 * But VFS will not use f->dents after iput() has been called.
60 */
37 return 0; 61 return 0;
38} 62}
39 63
40static void jffs2_put_link(struct dentry *dentry, struct nameidata *nd)
41{
42 char *s = nd_get_link(nd);
43 if (!IS_ERR(s))
44 kfree(s);
45}
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index c8128069ecf0..996d922e503e 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -9,7 +9,7 @@
9 * 9 *
10 * For licensing information, see the file 'LICENCE' in this directory. 10 * For licensing information, see the file 'LICENCE' in this directory.
11 * 11 *
12 * $Id: wbuf.c,v 1.82 2004/11/20 22:08:31 dwmw2 Exp $ 12 * $Id: wbuf.c,v 1.92 2005/04/05 12:51:54 dedekind Exp $
13 * 13 *
14 */ 14 */
15 15
@@ -83,7 +83,7 @@ static void jffs2_wbuf_dirties_inode(struct jffs2_sb_info *c, uint32_t ino)
83 struct jffs2_inodirty *new; 83 struct jffs2_inodirty *new;
84 84
85 /* Mark the superblock dirty so that kupdated will flush... */ 85 /* Mark the superblock dirty so that kupdated will flush... */
86 OFNI_BS_2SFFJ(c)->s_dirt = 1; 86 jffs2_erase_pending_trigger(c);
87 87
88 if (jffs2_wbuf_pending_for_ino(c, ino)) 88 if (jffs2_wbuf_pending_for_ino(c, ino))
89 return; 89 return;
@@ -130,7 +130,10 @@ static inline void jffs2_refile_wbuf_blocks(struct jffs2_sb_info *c)
130 } 130 }
131} 131}
132 132
133static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) 133#define REFILE_NOTEMPTY 0
134#define REFILE_ANYWAY 1
135
136static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, int allow_empty)
134{ 137{
135 D1(printk("About to refile bad block at %08x\n", jeb->offset)); 138 D1(printk("About to refile bad block at %08x\n", jeb->offset));
136 139
@@ -144,7 +147,7 @@ static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock
144 D1(printk("Refiling block at %08x to bad_used_list\n", jeb->offset)); 147 D1(printk("Refiling block at %08x to bad_used_list\n", jeb->offset));
145 list_add(&jeb->list, &c->bad_used_list); 148 list_add(&jeb->list, &c->bad_used_list);
146 } else { 149 } else {
147 BUG(); 150 BUG_ON(allow_empty == REFILE_NOTEMPTY);
148 /* It has to have had some nodes or we couldn't be here */ 151 /* It has to have had some nodes or we couldn't be here */
149 D1(printk("Refiling block at %08x to erase_pending_list\n", jeb->offset)); 152 D1(printk("Refiling block at %08x to erase_pending_list\n", jeb->offset));
150 list_add(&jeb->list, &c->erase_pending_list); 153 list_add(&jeb->list, &c->erase_pending_list);
@@ -179,7 +182,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
179 182
180 jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; 183 jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
181 184
182 jffs2_block_refile(c, jeb); 185 jffs2_block_refile(c, jeb, REFILE_NOTEMPTY);
183 186
184 /* Find the first node to be recovered, by skipping over every 187 /* Find the first node to be recovered, by skipping over every
185 node which ends before the wbuf starts, or which is obsolete. */ 188 node which ends before the wbuf starts, or which is obsolete. */
@@ -264,17 +267,16 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
264 ret = jffs2_reserve_space_gc(c, end-start, &ofs, &len); 267 ret = jffs2_reserve_space_gc(c, end-start, &ofs, &len);
265 if (ret) { 268 if (ret) {
266 printk(KERN_WARNING "Failed to allocate space for wbuf recovery. Data loss ensues.\n"); 269 printk(KERN_WARNING "Failed to allocate space for wbuf recovery. Data loss ensues.\n");
267 if (buf) 270 kfree(buf);
268 kfree(buf);
269 return; 271 return;
270 } 272 }
271 if (end-start >= c->wbuf_pagesize) { 273 if (end-start >= c->wbuf_pagesize) {
272 /* Need to do another write immediately. This, btw, 274 /* Need to do another write immediately, but it's possible
273 means that we'll be writing from 'buf' and not from 275 that this is just because the wbuf itself is completely
274 the wbuf. Since if we're writing from the wbuf there 276 full, and there's nothing earlier read back from the
275 won't be more than a wbuf full of data, now will 277 flash. Hence 'buf' isn't necessarily what we're writing
276 there? :) */ 278 from. */
277 279 unsigned char *rewrite_buf = buf?:c->wbuf;
278 uint32_t towrite = (end-start) - ((end-start)%c->wbuf_pagesize); 280 uint32_t towrite = (end-start) - ((end-start)%c->wbuf_pagesize);
279 281
280 D1(printk(KERN_DEBUG "Write 0x%x bytes at 0x%08x in wbuf recover\n", 282 D1(printk(KERN_DEBUG "Write 0x%x bytes at 0x%08x in wbuf recover\n",
@@ -292,9 +294,9 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
292#endif 294#endif
293 if (jffs2_cleanmarker_oob(c)) 295 if (jffs2_cleanmarker_oob(c))
294 ret = c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen, 296 ret = c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen,
295 buf, NULL, c->oobinfo); 297 rewrite_buf, NULL, c->oobinfo);
296 else 298 else
297 ret = c->mtd->write(c->mtd, ofs, towrite, &retlen, buf); 299 ret = c->mtd->write(c->mtd, ofs, towrite, &retlen, rewrite_buf);
298 300
299 if (ret || retlen != towrite) { 301 if (ret || retlen != towrite) {
300 /* Argh. We tried. Really we did. */ 302 /* Argh. We tried. Really we did. */
@@ -321,10 +323,10 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
321 323
322 c->wbuf_len = (end - start) - towrite; 324 c->wbuf_len = (end - start) - towrite;
323 c->wbuf_ofs = ofs + towrite; 325 c->wbuf_ofs = ofs + towrite;
324 memcpy(c->wbuf, buf + towrite, c->wbuf_len); 326 memmove(c->wbuf, rewrite_buf + towrite, c->wbuf_len);
325 /* Don't muck about with c->wbuf_inodes. False positives are harmless. */ 327 /* Don't muck about with c->wbuf_inodes. False positives are harmless. */
326 328 if (buf)
327 kfree(buf); 329 kfree(buf);
328 } else { 330 } else {
329 /* OK, now we're left with the dregs in whichever buffer we're using */ 331 /* OK, now we're left with the dregs in whichever buffer we're using */
330 if (buf) { 332 if (buf) {
@@ -413,9 +415,9 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
413 int ret; 415 int ret;
414 size_t retlen; 416 size_t retlen;
415 417
416 /* Nothing to do if not NAND flash. In particular, we shouldn't 418 /* Nothing to do if not write-buffering the flash. In particular, we shouldn't
417 del_timer() the timer we never initialised. */ 419 del_timer() the timer we never initialised. */
418 if (jffs2_can_mark_obsolete(c)) 420 if (!jffs2_is_writebuffered(c))
419 return 0; 421 return 0;
420 422
421 if (!down_trylock(&c->alloc_sem)) { 423 if (!down_trylock(&c->alloc_sem)) {
@@ -424,7 +426,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
424 BUG(); 426 BUG();
425 } 427 }
426 428
427 if(!c->wbuf || !c->wbuf_len) 429 if (!c->wbuf_len) /* already checked c->wbuf above */
428 return 0; 430 return 0;
429 431
430 /* claim remaining space on the page 432 /* claim remaining space on the page
@@ -433,7 +435,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
433 if we have a switch to next page, we will not have 435 if we have a switch to next page, we will not have
434 enough remaining space for this. 436 enough remaining space for this.
435 */ 437 */
436 if (pad) { 438 if (pad && !jffs2_dataflash(c)) {
437 c->wbuf_len = PAD(c->wbuf_len); 439 c->wbuf_len = PAD(c->wbuf_len);
438 440
439 /* Pad with JFFS2_DIRTY_BITMASK initially. this helps out ECC'd NOR 441 /* Pad with JFFS2_DIRTY_BITMASK initially. this helps out ECC'd NOR
@@ -484,7 +486,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
484 spin_lock(&c->erase_completion_lock); 486 spin_lock(&c->erase_completion_lock);
485 487
486 /* Adjust free size of the block if we padded. */ 488 /* Adjust free size of the block if we padded. */
487 if (pad) { 489 if (pad && !jffs2_dataflash(c)) {
488 struct jffs2_eraseblock *jeb; 490 struct jffs2_eraseblock *jeb;
489 491
490 jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; 492 jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
@@ -532,6 +534,9 @@ int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino)
532 534
533 D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() called for ino #%u...\n", ino)); 535 D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() called for ino #%u...\n", ino));
534 536
537 if (!c->wbuf)
538 return 0;
539
535 down(&c->alloc_sem); 540 down(&c->alloc_sem);
536 if (!jffs2_wbuf_pending_for_ino(c, ino)) { 541 if (!jffs2_wbuf_pending_for_ino(c, ino)) {
537 D1(printk(KERN_DEBUG "Ino #%d not pending in wbuf. Returning\n", ino)); 542 D1(printk(KERN_DEBUG "Ino #%d not pending in wbuf. Returning\n", ino));
@@ -547,6 +552,10 @@ int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino)
547 D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() padding. Not finished checking\n")); 552 D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() padding. Not finished checking\n"));
548 down_write(&c->wbuf_sem); 553 down_write(&c->wbuf_sem);
549 ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING); 554 ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
555 /* retry flushing wbuf in case jffs2_wbuf_recover
556 left some data in the wbuf */
557 if (ret)
558 ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
550 up_write(&c->wbuf_sem); 559 up_write(&c->wbuf_sem);
551 } else while (old_wbuf_len && 560 } else while (old_wbuf_len &&
552 old_wbuf_ofs == c->wbuf_ofs) { 561 old_wbuf_ofs == c->wbuf_ofs) {
@@ -561,6 +570,10 @@ int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino)
561 down(&c->alloc_sem); 570 down(&c->alloc_sem);
562 down_write(&c->wbuf_sem); 571 down_write(&c->wbuf_sem);
563 ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING); 572 ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
573 /* retry flushing wbuf in case jffs2_wbuf_recover
574 left some data in the wbuf */
575 if (ret)
576 ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
564 up_write(&c->wbuf_sem); 577 up_write(&c->wbuf_sem);
565 break; 578 break;
566 } 579 }
@@ -578,15 +591,27 @@ int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c)
578{ 591{
579 int ret; 592 int ret;
580 593
594 if (!c->wbuf)
595 return 0;
596
581 down_write(&c->wbuf_sem); 597 down_write(&c->wbuf_sem);
582 ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT); 598 ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT);
599 /* retry - maybe wbuf recover left some data in wbuf. */
600 if (ret)
601 ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT);
583 up_write(&c->wbuf_sem); 602 up_write(&c->wbuf_sem);
584 603
585 return ret; 604 return ret;
586} 605}
587 606
607#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
608#define PAGE_DIV(x) ( ((unsigned long)(x) / (unsigned long)(c->wbuf_pagesize)) * (unsigned long)(c->wbuf_pagesize) )
609#define PAGE_MOD(x) ( (unsigned long)(x) % (unsigned long)(c->wbuf_pagesize) )
610#else
588#define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) ) 611#define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) )
589#define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) ) 612#define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) )
613#endif
614
590int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino) 615int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino)
591{ 616{
592 struct kvec outvecs[3]; 617 struct kvec outvecs[3];
@@ -601,7 +626,7 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
601 uint32_t outvec_to = to; 626 uint32_t outvec_to = to;
602 627
603 /* If not NAND flash, don't bother */ 628 /* If not NAND flash, don't bother */
604 if (!c->wbuf) 629 if (!jffs2_is_writebuffered(c))
605 return jffs2_flash_direct_writev(c, invecs, count, to, retlen); 630 return jffs2_flash_direct_writev(c, invecs, count, to, retlen);
606 631
607 down_write(&c->wbuf_sem); 632 down_write(&c->wbuf_sem);
@@ -630,7 +655,7 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
630 erase block. Anything else, and you die. 655 erase block. Anything else, and you die.
631 New block starts at xxx000c (0-b = block header) 656 New block starts at xxx000c (0-b = block header)
632 */ 657 */
633 if ( (to & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) { 658 if (SECTOR_ADDR(to) != SECTOR_ADDR(c->wbuf_ofs)) {
634 /* It's a write to a new block */ 659 /* It's a write to a new block */
635 if (c->wbuf_len) { 660 if (c->wbuf_len) {
636 D1(printk(KERN_DEBUG "jffs2_flash_writev() to 0x%lx causes flush of wbuf at 0x%08x\n", (unsigned long)to, c->wbuf_ofs)); 661 D1(printk(KERN_DEBUG "jffs2_flash_writev() to 0x%lx causes flush of wbuf at 0x%08x\n", (unsigned long)to, c->wbuf_ofs));
@@ -762,9 +787,18 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
762 787
763 if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) { 788 if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) {
764 /* At this point we have no problem, 789 /* At this point we have no problem,
765 c->wbuf is empty. 790 c->wbuf is empty. However refile nextblock to avoid
791 writing again to same address.
766 */ 792 */
767 *retlen = donelen; 793 struct jffs2_eraseblock *jeb;
794
795 spin_lock(&c->erase_completion_lock);
796
797 jeb = &c->blocks[outvec_to / c->sector_size];
798 jffs2_block_refile(c, jeb, REFILE_ANYWAY);
799
800 *retlen = 0;
801 spin_unlock(&c->erase_completion_lock);
768 goto exit; 802 goto exit;
769 } 803 }
770 804
@@ -819,7 +853,7 @@ int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *r
819{ 853{
820 struct kvec vecs[1]; 854 struct kvec vecs[1];
821 855
822 if (jffs2_can_mark_obsolete(c)) 856 if (!jffs2_is_writebuffered(c))
823 return c->mtd->write(c->mtd, ofs, len, retlen, buf); 857 return c->mtd->write(c->mtd, ofs, len, retlen, buf);
824 858
825 vecs[0].iov_base = (unsigned char *) buf; 859 vecs[0].iov_base = (unsigned char *) buf;
@@ -835,39 +869,38 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re
835 loff_t orbf = 0, owbf = 0, lwbf = 0; 869 loff_t orbf = 0, owbf = 0, lwbf = 0;
836 int ret; 870 int ret;
837 871
838 /* Read flash */ 872 if (!jffs2_is_writebuffered(c))
839 if (!jffs2_can_mark_obsolete(c)) {
840 down_read(&c->wbuf_sem);
841
842 if (jffs2_cleanmarker_oob(c))
843 ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo);
844 else
845 ret = c->mtd->read(c->mtd, ofs, len, retlen, buf);
846
847 if ( (ret == -EBADMSG) && (*retlen == len) ) {
848 printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
849 len, ofs);
850 /*
851 * We have the raw data without ECC correction in the buffer, maybe
852 * we are lucky and all data or parts are correct. We check the node.
853 * If data are corrupted node check will sort it out.
854 * We keep this block, it will fail on write or erase and the we
855 * mark it bad. Or should we do that now? But we should give him a chance.
856 * Maybe we had a system crash or power loss before the ecc write or
857 * a erase was completed.
858 * So we return success. :)
859 */
860 ret = 0;
861 }
862 } else
863 return c->mtd->read(c->mtd, ofs, len, retlen, buf); 873 return c->mtd->read(c->mtd, ofs, len, retlen, buf);
864 874
875 /* Read flash */
876 down_read(&c->wbuf_sem);
877 if (jffs2_cleanmarker_oob(c))
878 ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo);
879 else
880 ret = c->mtd->read(c->mtd, ofs, len, retlen, buf);
881
882 if ( (ret == -EBADMSG) && (*retlen == len) ) {
883 printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
884 len, ofs);
885 /*
886 * We have the raw data without ECC correction in the buffer, maybe
887 * we are lucky and all data or parts are correct. We check the node.
888 * If data are corrupted node check will sort it out.
889 * We keep this block, it will fail on write or erase and the we
890 * mark it bad. Or should we do that now? But we should give him a chance.
891 * Maybe we had a system crash or power loss before the ecc write or
892 * a erase was completed.
893 * So we return success. :)
894 */
895 ret = 0;
896 }
897
865 /* if no writebuffer available or write buffer empty, return */ 898 /* if no writebuffer available or write buffer empty, return */
866 if (!c->wbuf_pagesize || !c->wbuf_len) 899 if (!c->wbuf_pagesize || !c->wbuf_len)
867 goto exit; 900 goto exit;
868 901
869 /* if we read in a different block, return */ 902 /* if we read in a different block, return */
870 if ( (ofs & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) 903 if (SECTOR_ADDR(ofs) != SECTOR_ADDR(c->wbuf_ofs))
871 goto exit; 904 goto exit;
872 905
873 if (ofs >= c->wbuf_ofs) { 906 if (ofs >= c->wbuf_ofs) {
@@ -1161,7 +1194,27 @@ void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c)
1161 kfree(c->wbuf); 1194 kfree(c->wbuf);
1162} 1195}
1163 1196
1164#ifdef CONFIG_JFFS2_FS_NOR_ECC 1197int jffs2_dataflash_setup(struct jffs2_sb_info *c) {
1198 c->cleanmarker_size = 0; /* No cleanmarkers needed */
1199
1200 /* Initialize write buffer */
1201 init_rwsem(&c->wbuf_sem);
1202 c->wbuf_pagesize = c->sector_size;
1203 c->wbuf_ofs = 0xFFFFFFFF;
1204
1205 c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
1206 if (!c->wbuf)
1207 return -ENOMEM;
1208
1209 printk(KERN_INFO "JFFS2 write-buffering enabled (%i)\n", c->wbuf_pagesize);
1210
1211 return 0;
1212}
1213
1214void jffs2_dataflash_cleanup(struct jffs2_sb_info *c) {
1215 kfree(c->wbuf);
1216}
1217
1165int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) { 1218int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) {
1166 /* Cleanmarker is actually larger on the flashes */ 1219 /* Cleanmarker is actually larger on the flashes */
1167 c->cleanmarker_size = 16; 1220 c->cleanmarker_size = 16;
@@ -1181,4 +1234,3 @@ int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) {
1181void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c) { 1234void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c) {
1182 kfree(c->wbuf); 1235 kfree(c->wbuf);
1183} 1236}
1184#endif
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index 80a5db542629..69100615d9ae 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: write.c,v 1.87 2004/11/16 20:36:12 dwmw2 Exp $ 10 * $Id: write.c,v 1.92 2005/04/13 13:22:35 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -35,13 +35,12 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint
35 f->inocache = ic; 35 f->inocache = ic;
36 f->inocache->nlink = 1; 36 f->inocache->nlink = 1;
37 f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; 37 f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
38 f->inocache->ino = ++c->highest_ino;
39 f->inocache->state = INO_STATE_PRESENT; 38 f->inocache->state = INO_STATE_PRESENT;
40 39
41 ri->ino = cpu_to_je32(f->inocache->ino);
42 40
43 D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino));
44 jffs2_add_ino_cache(c, f->inocache); 41 jffs2_add_ino_cache(c, f->inocache);
42 D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino));
43 ri->ino = cpu_to_je32(f->inocache->ino);
45 44
46 ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 45 ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
47 ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); 46 ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
@@ -136,6 +135,15 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
136 raw->__totlen = PAD(sizeof(*ri)+datalen); 135 raw->__totlen = PAD(sizeof(*ri)+datalen);
137 raw->next_phys = NULL; 136 raw->next_phys = NULL;
138 137
138 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) {
139 BUG_ON(!retried);
140 D1(printk(KERN_DEBUG "jffs2_write_dnode : dnode_version %d, "
141 "highest version %d -> updating dnode\n",
142 je32_to_cpu(ri->version), f->highest_version));
143 ri->version = cpu_to_je32(++f->highest_version);
144 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
145 }
146
139 ret = jffs2_flash_writev(c, vecs, cnt, flash_ofs, &retlen, 147 ret = jffs2_flash_writev(c, vecs, cnt, flash_ofs, &retlen,
140 (alloc_mode==ALLOC_GC)?0:f->inocache->ino); 148 (alloc_mode==ALLOC_GC)?0:f->inocache->ino);
141 149
@@ -280,6 +288,16 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
280 raw->__totlen = PAD(sizeof(*rd)+namelen); 288 raw->__totlen = PAD(sizeof(*rd)+namelen);
281 raw->next_phys = NULL; 289 raw->next_phys = NULL;
282 290
291 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(rd->version) < f->highest_version)) {
292 BUG_ON(!retried);
293 D1(printk(KERN_DEBUG "jffs2_write_dirent : dirent_version %d, "
294 "highest version %d -> updating dirent\n",
295 je32_to_cpu(rd->version), f->highest_version));
296 rd->version = cpu_to_je32(++f->highest_version);
297 fd->version = je32_to_cpu(rd->version);
298 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
299 }
300
283 ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen, 301 ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen,
284 (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino)); 302 (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino));
285 if (ret || (retlen != sizeof(*rd) + namelen)) { 303 if (ret || (retlen != sizeof(*rd) + namelen)) {
@@ -625,20 +643,23 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
625 643
626 down(&dead_f->sem); 644 down(&dead_f->sem);
627 645
628 while (dead_f->dents) { 646 if (S_ISDIR(OFNI_EDONI_2SFFJ(dead_f)->i_mode)) {
629 /* There can be only deleted ones */ 647 while (dead_f->dents) {
630 fd = dead_f->dents; 648 /* There can be only deleted ones */
631 649 fd = dead_f->dents;
632 dead_f->dents = fd->next; 650
633 651 dead_f->dents = fd->next;
634 if (fd->ino) { 652
635 printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n", 653 if (fd->ino) {
636 dead_f->inocache->ino, fd->name, fd->ino); 654 printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
637 } else { 655 dead_f->inocache->ino, fd->name, fd->ino);
638 D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", fd->name, dead_f->inocache->ino)); 656 } else {
657 D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n",
658 fd->name, dead_f->inocache->ino));
659 }
660 jffs2_mark_node_obsolete(c, fd->raw);
661 jffs2_free_full_dirent(fd);
639 } 662 }
640 jffs2_mark_node_obsolete(c, fd->raw);
641 jffs2_free_full_dirent(fd);
642 } 663 }
643 664
644 dead_f->inocache->nlink--; 665 dead_f->inocache->nlink--;
diff --git a/include/linux/jffs2_fs_sb.h b/include/linux/jffs2_fs_sb.h
index 4afc8d8c2e9e..1e21546622de 100644
--- a/include/linux/jffs2_fs_sb.h
+++ b/include/linux/jffs2_fs_sb.h
@@ -1,4 +1,4 @@
1/* $Id: jffs2_fs_sb.h,v 1.48 2004/11/20 10:41:12 dwmw2 Exp $ */ 1/* $Id: jffs2_fs_sb.h,v 1.52 2005/05/19 16:12:17 gleixner Exp $ */
2 2
3#ifndef _JFFS2_FS_SB 3#ifndef _JFFS2_FS_SB
4#define _JFFS2_FS_SB 4#define _JFFS2_FS_SB
@@ -14,7 +14,8 @@
14#include <linux/rwsem.h> 14#include <linux/rwsem.h>
15 15
16#define JFFS2_SB_FLAG_RO 1 16#define JFFS2_SB_FLAG_RO 1
17#define JFFS2_SB_FLAG_MOUNTING 2 17#define JFFS2_SB_FLAG_SCANNING 2 /* Flash scanning is in progress */
18#define JFFS2_SB_FLAG_BUILDING 4 /* File system building is in progress */
18 19
19struct jffs2_inodirty; 20struct jffs2_inodirty;
20 21
@@ -31,7 +32,7 @@ struct jffs2_sb_info {
31 unsigned int flags; 32 unsigned int flags;
32 33
33 struct task_struct *gc_task; /* GC task struct */ 34 struct task_struct *gc_task; /* GC task struct */
34 struct semaphore gc_thread_start; /* GC thread start mutex */ 35 struct completion gc_thread_start; /* GC thread start completion */
35 struct completion gc_thread_exit; /* GC thread exit completion port */ 36 struct completion gc_thread_exit; /* GC thread exit completion port */
36 37
37 struct semaphore alloc_sem; /* Used to protect all the following 38 struct semaphore alloc_sem; /* Used to protect all the following
@@ -94,7 +95,7 @@ struct jffs2_sb_info {
94 to an obsoleted node. I don't like this. Alternatives welcomed. */ 95 to an obsoleted node. I don't like this. Alternatives welcomed. */
95 struct semaphore erase_free_sem; 96 struct semaphore erase_free_sem;
96 97
97#if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC 98#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
98 /* Write-behind buffer for NAND flash */ 99 /* Write-behind buffer for NAND flash */
99 unsigned char *wbuf; 100 unsigned char *wbuf;
100 uint32_t wbuf_ofs; 101 uint32_t wbuf_ofs;
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
index 2ed8c585021e..e6b6a1c66bd5 100644
--- a/include/linux/mtd/cfi.h
+++ b/include/linux/mtd/cfi.h
@@ -1,7 +1,7 @@
1 1
2/* Common Flash Interface structures 2/* Common Flash Interface structures
3 * See http://support.intel.com/design/flash/technote/index.htm 3 * See http://support.intel.com/design/flash/technote/index.htm
4 * $Id: cfi.h,v 1.50 2004/11/20 12:46:51 dwmw2 Exp $ 4 * $Id: cfi.h,v 1.54 2005/06/06 23:04:36 tpoynor Exp $
5 */ 5 */
6 6
7#ifndef __MTD_CFI_H__ 7#ifndef __MTD_CFI_H__
@@ -148,6 +148,14 @@ struct cfi_pri_intelext {
148 uint8_t extra[0]; 148 uint8_t extra[0];
149} __attribute__((packed)); 149} __attribute__((packed));
150 150
151struct cfi_intelext_otpinfo {
152 uint32_t ProtRegAddr;
153 uint16_t FactGroups;
154 uint8_t FactProtRegSize;
155 uint16_t UserGroups;
156 uint8_t UserProtRegSize;
157} __attribute__((packed));
158
151struct cfi_intelext_blockinfo { 159struct cfi_intelext_blockinfo {
152 uint16_t NumIdentBlocks; 160 uint16_t NumIdentBlocks;
153 uint16_t BlockSize; 161 uint16_t BlockSize;
@@ -244,7 +252,7 @@ static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, int interleave, int
244 * It looks too long to be inline, but in the common case it should almost all 252 * It looks too long to be inline, but in the common case it should almost all
245 * get optimised away. 253 * get optimised away.
246 */ 254 */
247static inline map_word cfi_build_cmd(u_char cmd, struct map_info *map, struct cfi_private *cfi) 255static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cfi_private *cfi)
248{ 256{
249 map_word val = { {0} }; 257 map_word val = { {0} };
250 int wordwidth, words_per_bus, chip_mode, chips_per_word; 258 int wordwidth, words_per_bus, chip_mode, chips_per_word;
@@ -307,6 +315,69 @@ static inline map_word cfi_build_cmd(u_char cmd, struct map_info *map, struct cf
307} 315}
308#define CMD(x) cfi_build_cmd((x), map, cfi) 316#define CMD(x) cfi_build_cmd((x), map, cfi)
309 317
318
319static inline unsigned char cfi_merge_status(map_word val, struct map_info *map,
320 struct cfi_private *cfi)
321{
322 int wordwidth, words_per_bus, chip_mode, chips_per_word;
323 unsigned long onestat, res = 0;
324 int i;
325
326 /* We do it this way to give the compiler a fighting chance
327 of optimising away all the crap for 'bankwidth' larger than
328 an unsigned long, in the common case where that support is
329 disabled */
330 if (map_bankwidth_is_large(map)) {
331 wordwidth = sizeof(unsigned long);
332 words_per_bus = (map_bankwidth(map)) / wordwidth; // i.e. normally 1
333 } else {
334 wordwidth = map_bankwidth(map);
335 words_per_bus = 1;
336 }
337
338 chip_mode = map_bankwidth(map) / cfi_interleave(cfi);
339 chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map);
340
341 onestat = val.x[0];
342 /* Or all status words together */
343 for (i=1; i < words_per_bus; i++) {
344 onestat |= val.x[i];
345 }
346
347 res = onestat;
348 switch(chips_per_word) {
349 default: BUG();
350#if BITS_PER_LONG >= 64
351 case 8:
352 res |= (onestat >> (chip_mode * 32));
353#endif
354 case 4:
355 res |= (onestat >> (chip_mode * 16));
356 case 2:
357 res |= (onestat >> (chip_mode * 8));
358 case 1:
359 ;
360 }
361
362 /* Last, determine what the bit-pattern should be for a single
363 device, according to chip mode and endianness... */
364 switch (chip_mode) {
365 case 1:
366 break;
367 case 2:
368 res = cfi16_to_cpu(res);
369 break;
370 case 4:
371 res = cfi32_to_cpu(res);
372 break;
373 default: BUG();
374 }
375 return res;
376}
377
378#define MERGESTATUS(x) cfi_merge_status((x), map, cfi)
379
380
310/* 381/*
311 * Sends a CFI command to a bank of flash for the given geometry. 382 * Sends a CFI command to a bank of flash for the given geometry.
312 * 383 *
@@ -357,16 +428,6 @@ static inline void cfi_udelay(int us)
357 } 428 }
358} 429}
359 430
360static inline void cfi_spin_lock(spinlock_t *mutex)
361{
362 spin_lock_bh(mutex);
363}
364
365static inline void cfi_spin_unlock(spinlock_t *mutex)
366{
367 spin_unlock_bh(mutex);
368}
369
370struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t size, 431struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t size,
371 const char* name); 432 const char* name);
372struct cfi_fixup { 433struct cfi_fixup {
diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
index c66ba812bf90..675776fa3e27 100644
--- a/include/linux/mtd/flashchip.h
+++ b/include/linux/mtd/flashchip.h
@@ -6,7 +6,7 @@
6 * 6 *
7 * (C) 2000 Red Hat. GPLd. 7 * (C) 2000 Red Hat. GPLd.
8 * 8 *
9 * $Id: flashchip.h,v 1.15 2004/11/05 22:41:06 nico Exp $ 9 * $Id: flashchip.h,v 1.17 2005/03/14 18:27:15 bjd Exp $
10 * 10 *
11 */ 11 */
12 12
@@ -29,6 +29,7 @@ typedef enum {
29 FL_ERASE_SUSPENDED, 29 FL_ERASE_SUSPENDED,
30 FL_WRITING, 30 FL_WRITING,
31 FL_WRITING_TO_BUFFER, 31 FL_WRITING_TO_BUFFER,
32 FL_OTP_WRITE,
32 FL_WRITE_SUSPENDING, 33 FL_WRITE_SUSPENDING,
33 FL_WRITE_SUSPENDED, 34 FL_WRITE_SUSPENDED,
34 FL_PM_SUSPENDED, 35 FL_PM_SUSPENDED,
@@ -62,8 +63,8 @@ struct flchip {
62 flstate_t state; 63 flstate_t state;
63 flstate_t oldstate; 64 flstate_t oldstate;
64 65
65 int write_suspended:1; 66 unsigned int write_suspended:1;
66 int erase_suspended:1; 67 unsigned int erase_suspended:1;
67 unsigned long in_progress_block_addr; 68 unsigned long in_progress_block_addr;
68 69
69 spinlock_t *mutex; 70 spinlock_t *mutex;
diff --git a/include/linux/mtd/inftl.h b/include/linux/mtd/inftl.h
index b52c8cbd235c..0268125a6271 100644
--- a/include/linux/mtd/inftl.h
+++ b/include/linux/mtd/inftl.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) 4 * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
5 * 5 *
6 * $Id: inftl.h,v 1.6 2004/06/30 14:49:00 dbrown Exp $ 6 * $Id: inftl.h,v 1.7 2005/06/13 13:08:45 sean Exp $
7 */ 7 */
8 8
9#ifndef __MTD_INFTL_H__ 9#ifndef __MTD_INFTL_H__
@@ -20,7 +20,7 @@
20#include <mtd/inftl-user.h> 20#include <mtd/inftl-user.h>
21 21
22#ifndef INFTL_MAJOR 22#ifndef INFTL_MAJOR
23#define INFTL_MAJOR 94 23#define INFTL_MAJOR 96
24#endif 24#endif
25#define INFTL_PARTN_BITS 4 25#define INFTL_PARTN_BITS 4
26 26
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index f0268b99c900..142963f01d29 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -1,6 +1,6 @@
1 1
2/* Overhauled routines for dealing with different mmap regions of flash */ 2/* Overhauled routines for dealing with different mmap regions of flash */
3/* $Id: map.h,v 1.46 2005/01/05 17:09:44 dwmw2 Exp $ */ 3/* $Id: map.h,v 1.52 2005/05/25 10:29:41 gleixner Exp $ */
4 4
5#ifndef __LINUX_MTD_MAP_H__ 5#ifndef __LINUX_MTD_MAP_H__
6#define __LINUX_MTD_MAP_H__ 6#define __LINUX_MTD_MAP_H__
@@ -263,6 +263,17 @@ static inline map_word map_word_and(struct map_info *map, map_word val1, map_wor
263 return r; 263 return r;
264} 264}
265 265
266static inline map_word map_word_clr(struct map_info *map, map_word val1, map_word val2)
267{
268 map_word r;
269 int i;
270
271 for (i=0; i<map_words(map); i++) {
272 r.x[i] = val1.x[i] & ~val2.x[i];
273 }
274 return r;
275}
276
266static inline map_word map_word_or(struct map_info *map, map_word val1, map_word val2) 277static inline map_word map_word_or(struct map_info *map, map_word val1, map_word val2)
267{ 278{
268 map_word r; 279 map_word r;
@@ -273,6 +284,7 @@ static inline map_word map_word_or(struct map_info *map, map_word val1, map_word
273 } 284 }
274 return r; 285 return r;
275} 286}
287
276#define map_word_andequal(m, a, b, z) map_word_equal(m, z, map_word_and(m, a, b)) 288#define map_word_andequal(m, a, b, z) map_word_equal(m, z, map_word_and(m, a, b))
277 289
278static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2) 290static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2)
@@ -328,16 +340,27 @@ static inline map_word map_word_load_partial(struct map_info *map, map_word orig
328 return orig; 340 return orig;
329} 341}
330 342
343#if BITS_PER_LONG < 64
344#define MAP_FF_LIMIT 4
345#else
346#define MAP_FF_LIMIT 8
347#endif
348
331static inline map_word map_word_ff(struct map_info *map) 349static inline map_word map_word_ff(struct map_info *map)
332{ 350{
333 map_word r; 351 map_word r;
334 int i; 352 int i;
335 353
336 for (i=0; i<map_words(map); i++) { 354 if (map_bankwidth(map) < MAP_FF_LIMIT) {
337 r.x[i] = ~0UL; 355 int bw = 8 * map_bankwidth(map);
356 r.x[0] = (1 << bw) - 1;
357 } else {
358 for (i=0; i<map_words(map); i++)
359 r.x[i] = ~0UL;
338 } 360 }
339 return r; 361 return r;
340} 362}
363
341static inline map_word inline_map_read(struct map_info *map, unsigned long ofs) 364static inline map_word inline_map_read(struct map_info *map, unsigned long ofs)
342{ 365{
343 map_word r; 366 map_word r;
@@ -405,7 +428,7 @@ extern void simple_map_init(struct map_info *);
405 428
406 429
407#define simple_map_init(map) BUG_ON(!map_bankwidth_supported((map)->bankwidth)) 430#define simple_map_init(map) BUG_ON(!map_bankwidth_supported((map)->bankwidth))
408#define map_is_linear(map) (1) 431#define map_is_linear(map) ({ (void)(map); 1; })
409 432
410#endif /* !CONFIG_MTD_COMPLEX_MAPPINGS */ 433#endif /* !CONFIG_MTD_COMPLEX_MAPPINGS */
411 434
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index b3d134392b31..c50c3f3927d9 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: mtd.h,v 1.56 2004/08/09 18:46:04 dmarlin Exp $ 2 * $Id: mtd.h,v 1.59 2005/04/11 10:19:02 gleixner Exp $
3 * 3 *
4 * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al. 4 * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al.
5 * 5 *
@@ -18,6 +18,7 @@
18#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/uio.h> 20#include <linux/uio.h>
21#include <linux/notifier.h>
21 22
22#include <linux/mtd/compatmac.h> 23#include <linux/mtd/compatmac.h>
23#include <mtd/mtd-abi.h> 24#include <mtd/mtd-abi.h>
@@ -69,7 +70,6 @@ struct mtd_info {
69 70
70 u_int32_t oobblock; // Size of OOB blocks (e.g. 512) 71 u_int32_t oobblock; // Size of OOB blocks (e.g. 512)
71 u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) 72 u_int32_t oobsize; // Amount of OOB data per block (e.g. 16)
72 u_int32_t oobavail; // Number of bytes in OOB area available for fs
73 u_int32_t ecctype; 73 u_int32_t ecctype;
74 u_int32_t eccsize; 74 u_int32_t eccsize;
75 75
@@ -80,6 +80,7 @@ struct mtd_info {
80 80
81 // oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO) 81 // oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO)
82 struct nand_oobinfo oobinfo; 82 struct nand_oobinfo oobinfo;
83 u_int32_t oobavail; // Number of bytes in OOB area available for fs
83 84
84 /* Data for variable erase regions. If numeraseregions is zero, 85 /* Data for variable erase regions. If numeraseregions is zero,
85 * it means that the whole device has erasesize as given above. 86 * it means that the whole device has erasesize as given above.
@@ -113,12 +114,12 @@ struct mtd_info {
113 * flash devices. The user data is one time programmable but the 114 * flash devices. The user data is one time programmable but the
114 * factory data is read only. 115 * factory data is read only.
115 */ 116 */
116 int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 117 int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
117
118 int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 118 int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
119 119 int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
120 /* This function is not yet implemented */ 120 int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
121 int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 121 int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
122 int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len);
122 123
123 /* kvec-based read/write methods. We need these especially for NAND flash, 124 /* kvec-based read/write methods. We need these especially for NAND flash,
124 with its limited number of write cycles per erase. 125 with its limited number of write cycles per erase.
@@ -147,6 +148,8 @@ struct mtd_info {
147 int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); 148 int (*block_isbad) (struct mtd_info *mtd, loff_t ofs);
148 int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); 149 int (*block_markbad) (struct mtd_info *mtd, loff_t ofs);
149 150
151 struct notifier_block reboot_notifier; /* default mode before reboot */
152
150 void *priv; 153 void *priv;
151 154
152 struct module *owner; 155 struct module *owner;
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 9a19c65abd74..9b5b76217584 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -5,7 +5,7 @@
5 * Steven J. Hill <sjhill@realitydiluted.com> 5 * Steven J. Hill <sjhill@realitydiluted.com>
6 * Thomas Gleixner <tglx@linutronix.de> 6 * Thomas Gleixner <tglx@linutronix.de>
7 * 7 *
8 * $Id: nand.h,v 1.68 2004/11/12 10:40:37 gleixner Exp $ 8 * $Id: nand.h,v 1.73 2005/05/31 19:39:17 gleixner Exp $
9 * 9 *
10 * 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
11 * 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
@@ -48,6 +48,10 @@
48 * 02-08-2004 tglx added option field to nand structure for chip anomalities 48 * 02-08-2004 tglx added option field to nand structure for chip anomalities
49 * 05-25-2004 tglx added bad block table support, ST-MICRO manufacturer id 49 * 05-25-2004 tglx added bad block table support, ST-MICRO manufacturer id
50 * update of nand_chip structure description 50 * update of nand_chip structure description
51 * 01-17-2005 dmarlin added extended commands for AG-AND device and added option
52 * for BBT_AUTO_REFRESH.
53 * 01-20-2005 dmarlin added optional pointer to hardware specific callback for
54 * extra error status checks.
51 */ 55 */
52#ifndef __LINUX_MTD_NAND_H 56#ifndef __LINUX_MTD_NAND_H
53#define __LINUX_MTD_NAND_H 57#define __LINUX_MTD_NAND_H
@@ -115,6 +119,25 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
115#define NAND_CMD_READSTART 0x30 119#define NAND_CMD_READSTART 0x30
116#define NAND_CMD_CACHEDPROG 0x15 120#define NAND_CMD_CACHEDPROG 0x15
117 121
122/* Extended commands for AG-AND device */
123/*
124 * Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but
125 * there is no way to distinguish that from NAND_CMD_READ0
126 * until the remaining sequence of commands has been completed
127 * so add a high order bit and mask it off in the command.
128 */
129#define NAND_CMD_DEPLETE1 0x100
130#define NAND_CMD_DEPLETE2 0x38
131#define NAND_CMD_STATUS_MULTI 0x71
132#define NAND_CMD_STATUS_ERROR 0x72
133/* multi-bank error status (banks 0-3) */
134#define NAND_CMD_STATUS_ERROR0 0x73
135#define NAND_CMD_STATUS_ERROR1 0x74
136#define NAND_CMD_STATUS_ERROR2 0x75
137#define NAND_CMD_STATUS_ERROR3 0x76
138#define NAND_CMD_STATUS_RESET 0x7f
139#define NAND_CMD_STATUS_CLEAR 0xff
140
118/* Status bits */ 141/* Status bits */
119#define NAND_STATUS_FAIL 0x01 142#define NAND_STATUS_FAIL 0x01
120#define NAND_STATUS_FAIL_N1 0x02 143#define NAND_STATUS_FAIL_N1 0x02
@@ -143,7 +166,7 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
143 166
144/* 167/*
145 * Constants for Hardware ECC 168 * Constants for Hardware ECC
146*/ 169 */
147/* Reset Hardware ECC for read */ 170/* Reset Hardware ECC for read */
148#define NAND_ECC_READ 0 171#define NAND_ECC_READ 0
149/* Reset Hardware ECC for write */ 172/* Reset Hardware ECC for write */
@@ -151,6 +174,10 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
151/* Enable Hardware ECC before syndrom is read back from flash */ 174/* Enable Hardware ECC before syndrom is read back from flash */
152#define NAND_ECC_READSYN 2 175#define NAND_ECC_READSYN 2
153 176
177/* Bit mask for flags passed to do_nand_read_ecc */
178#define NAND_GET_DEVICE 0x80
179
180
154/* Option constants for bizarre disfunctionality and real 181/* Option constants for bizarre disfunctionality and real
155* features 182* features
156*/ 183*/
@@ -170,6 +197,10 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
170/* Chip has a array of 4 pages which can be read without 197/* Chip has a array of 4 pages which can be read without
171 * additional ready /busy waits */ 198 * additional ready /busy waits */
172#define NAND_4PAGE_ARRAY 0x00000040 199#define NAND_4PAGE_ARRAY 0x00000040
200/* Chip requires that BBT is periodically rewritten to prevent
201 * bits from adjacent blocks from 'leaking' in altering data.
202 * This happens with the Renesas AG-AND chips, possibly others. */
203#define BBT_AUTO_REFRESH 0x00000080
173 204
174/* Options valid for Samsung large page devices */ 205/* Options valid for Samsung large page devices */
175#define NAND_SAMSUNG_LP_OPTIONS \ 206#define NAND_SAMSUNG_LP_OPTIONS \
@@ -192,7 +223,8 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_
192 * This can only work if we have the ecc bytes directly behind the 223 * This can only work if we have the ecc bytes directly behind the
193 * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */ 224 * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */
194#define NAND_HWECC_SYNDROME 0x00020000 225#define NAND_HWECC_SYNDROME 0x00020000
195 226/* This option skips the bbt scan during initialization. */
227#define NAND_SKIP_BBTSCAN 0x00040000
196 228
197/* Options set by nand scan */ 229/* Options set by nand scan */
198/* Nand scan has allocated oob_buf */ 230/* Nand scan has allocated oob_buf */
@@ -221,10 +253,13 @@ struct nand_chip;
221 * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices 253 * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices
222 * @lock: protection lock 254 * @lock: protection lock
223 * @active: the mtd device which holds the controller currently 255 * @active: the mtd device which holds the controller currently
256 * @wq: wait queue to sleep on if a NAND operation is in progress
257 * used instead of the per chip wait queue when a hw controller is available
224 */ 258 */
225struct nand_hw_control { 259struct nand_hw_control {
226 spinlock_t lock; 260 spinlock_t lock;
227 struct nand_chip *active; 261 struct nand_chip *active;
262 wait_queue_head_t wq;
228}; 263};
229 264
230/** 265/**
@@ -283,6 +318,8 @@ struct nand_hw_control {
283 * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan 318 * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan
284 * @controller: [OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices 319 * @controller: [OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices
285 * @priv: [OPTIONAL] pointer to private chip date 320 * @priv: [OPTIONAL] pointer to private chip date
321 * @errstat: [OPTIONAL] hardware specific function to perform additional error status checks
322 * (determine if errors are correctable)
286 */ 323 */
287 324
288struct nand_chip { 325struct nand_chip {
@@ -338,6 +375,7 @@ struct nand_chip {
338 struct nand_bbt_descr *badblock_pattern; 375 struct nand_bbt_descr *badblock_pattern;
339 struct nand_hw_control *controller; 376 struct nand_hw_control *controller;
340 void *priv; 377 void *priv;
378 int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
341}; 379};
342 380
343/* 381/*
@@ -349,6 +387,7 @@ struct nand_chip {
349#define NAND_MFR_NATIONAL 0x8f 387#define NAND_MFR_NATIONAL 0x8f
350#define NAND_MFR_RENESAS 0x07 388#define NAND_MFR_RENESAS 0x07
351#define NAND_MFR_STMICRO 0x20 389#define NAND_MFR_STMICRO 0x20
390#define NAND_MFR_HYNIX 0xad
352 391
353/** 392/**
354 * struct nand_flash_dev - NAND Flash Device ID Structure 393 * struct nand_flash_dev - NAND Flash Device ID Structure
@@ -459,6 +498,9 @@ extern int nand_update_bbt (struct mtd_info *mtd, loff_t offs);
459extern int nand_default_bbt (struct mtd_info *mtd); 498extern int nand_default_bbt (struct mtd_info *mtd);
460extern int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt); 499extern int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt);
461extern int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt); 500extern int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt);
501extern int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
502 size_t * retlen, u_char * buf, u_char * oob_buf,
503 struct nand_oobinfo *oobsel, int flags);
462 504
463/* 505/*
464* Constants for oob configuration 506* Constants for oob configuration
diff --git a/include/linux/mtd/plat-ram.h b/include/linux/mtd/plat-ram.h
new file mode 100644
index 000000000000..2332eda07e0e
--- /dev/null
+++ b/include/linux/mtd/plat-ram.h
@@ -0,0 +1,35 @@
1/* linux/include/mtd/plat-ram.h
2 *
3 * (c) 2004 Simtec Electronics
4 * http://www.simtec.co.uk/products/SWLINUX/
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * Generic platform device based RAM map
8 *
9 * $Id: plat-ram.h,v 1.2 2005/01/24 00:37:40 bjd Exp $
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 */
16
17#ifndef __LINUX_MTD_PLATRAM_H
18#define __LINUX_MTD_PLATRAM_H __FILE__
19
20#define PLATRAM_RO (0)
21#define PLATRAM_RW (1)
22
23struct platdata_mtd_ram {
24 char *mapname;
25 char **probes;
26 struct mtd_partition *partitions;
27 int nr_partitions;
28 int bankwidth;
29
30 /* control callbacks */
31
32 void (*set_rw)(struct device *dev, int to);
33};
34
35#endif /* __LINUX_MTD_PLATRAM_H */
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index a76ab898f445..428d9122940b 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: mtd-abi.h,v 1.7 2004/11/23 15:37:32 gleixner Exp $ 2 * $Id: mtd-abi.h,v 1.11 2005/05/19 16:08:58 gleixner Exp $
3 * 3 *
4 * Portions of MTD ABI definition which are shared by kernel and user space 4 * Portions of MTD ABI definition which are shared by kernel and user space
5 */ 5 */
@@ -29,6 +29,7 @@ struct mtd_oob_buf {
29#define MTD_NORFLASH 3 29#define MTD_NORFLASH 3
30#define MTD_NANDFLASH 4 30#define MTD_NANDFLASH 4
31#define MTD_PEROM 5 31#define MTD_PEROM 5
32#define MTD_DATAFLASH 6
32#define MTD_OTHER 14 33#define MTD_OTHER 14
33#define MTD_UNKNOWN 15 34#define MTD_UNKNOWN 15
34 35
@@ -60,6 +61,12 @@ struct mtd_oob_buf {
60#define MTD_NANDECC_PLACE 1 // Use the given placement in the structure (YAFFS1 legacy mode) 61#define MTD_NANDECC_PLACE 1 // Use the given placement in the structure (YAFFS1 legacy mode)
61#define MTD_NANDECC_AUTOPLACE 2 // Use the default placement scheme 62#define MTD_NANDECC_AUTOPLACE 2 // Use the default placement scheme
62#define MTD_NANDECC_PLACEONLY 3 // Use the given placement in the structure (Do not store ecc result on read) 63#define MTD_NANDECC_PLACEONLY 3 // Use the given placement in the structure (Do not store ecc result on read)
64#define MTD_NANDECC_AUTOPL_USR 4 // Use the given autoplacement scheme rather than using the default
65
66/* OTP mode selection */
67#define MTD_OTP_OFF 0
68#define MTD_OTP_FACTORY 1
69#define MTD_OTP_USER 2
63 70
64struct mtd_info_user { 71struct mtd_info_user {
65 uint8_t type; 72 uint8_t type;
@@ -80,6 +87,12 @@ struct region_info_user {
80 uint32_t regionindex; 87 uint32_t regionindex;
81}; 88};
82 89
90struct otp_info {
91 uint32_t start;
92 uint32_t length;
93 uint32_t locked;
94};
95
83#define MEMGETINFO _IOR('M', 1, struct mtd_info_user) 96#define MEMGETINFO _IOR('M', 1, struct mtd_info_user)
84#define MEMERASE _IOW('M', 2, struct erase_info_user) 97#define MEMERASE _IOW('M', 2, struct erase_info_user)
85#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) 98#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf)
@@ -92,6 +105,10 @@ struct region_info_user {
92#define MEMGETOOBSEL _IOR('M', 10, struct nand_oobinfo) 105#define MEMGETOOBSEL _IOR('M', 10, struct nand_oobinfo)
93#define MEMGETBADBLOCK _IOW('M', 11, loff_t) 106#define MEMGETBADBLOCK _IOW('M', 11, loff_t)
94#define MEMSETBADBLOCK _IOW('M', 12, loff_t) 107#define MEMSETBADBLOCK _IOW('M', 12, loff_t)
108#define OTPSELECT _IOR('M', 13, int)
109#define OTPGETREGIONCOUNT _IOW('M', 14, int)
110#define OTPGETREGIONINFO _IOW('M', 15, struct otp_info)
111#define OTPLOCK _IOR('M', 16, struct otp_info)
95 112
96struct nand_oobinfo { 113struct nand_oobinfo {
97 uint32_t useecc; 114 uint32_t useecc;