diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-07-13 16:23:51 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-07-13 16:23:51 -0400 |
commit | 327309e899662b482c58cf25f574513d38b5788c (patch) | |
tree | 069de438aa0e92dd9b6ba28e6b207e2cd07151a5 /drivers/mtd/chips | |
parent | 0c168775709faa74c1b87f1e61046e0c51ade7f3 (diff) | |
parent | c32511e2718618f0b53479eb36e07439aa363a74 (diff) |
Merge upstream 2.6.13-rc3 into ieee80211 branch of netdev-2.6.
Diffstat (limited to 'drivers/mtd/chips')
-rw-r--r-- | drivers/mtd/chips/Kconfig | 29 | ||||
-rw-r--r-- | drivers/mtd/chips/amd_flash.c | 14 | ||||
-rw-r--r-- | drivers/mtd/chips/cfi_cmdset_0001.c | 580 | ||||
-rw-r--r-- | drivers/mtd/chips/cfi_cmdset_0002.c | 497 | ||||
-rw-r--r-- | drivers/mtd/chips/fwh_lock.h | 6 | ||||
-rw-r--r-- | drivers/mtd/chips/gen_probe.c | 4 | ||||
-rw-r--r-- | drivers/mtd/chips/jedec_probe.c | 28 |
7 files changed, 837 insertions, 321 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 | ||
4 | menu "RAM/ROM/Flash chip drivers" | 4 | menu "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 | ||
158 | config 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 | |||
158 | config MTD_CFI_INTELEXT | 183 | config 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 | ||
276 | config MTD_XIP | 301 | config 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..0cfcd88468e0 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 | ||
50 | static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); | 51 | static 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 *); | ||
53 | static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); | 52 | static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); |
54 | static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); | 53 | static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); |
55 | static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *); | 54 | static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *); |
56 | static void cfi_intelext_sync (struct mtd_info *); | 55 | static void cfi_intelext_sync (struct mtd_info *); |
57 | static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len); | 56 | static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len); |
58 | static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len); | 57 | static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len); |
58 | #ifdef CONFIG_MTD_OTP | ||
59 | static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *); | ||
60 | static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *); | ||
61 | static int cfi_intelext_write_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *); | ||
62 | static int cfi_intelext_lock_user_prot_reg (struct mtd_info *, loff_t, size_t); | ||
63 | static int cfi_intelext_get_fact_prot_info (struct mtd_info *, | ||
64 | struct otp_info *, size_t); | ||
65 | static int cfi_intelext_get_user_prot_info (struct mtd_info *, | ||
66 | struct otp_info *, size_t); | ||
67 | #endif | ||
59 | static int cfi_intelext_suspend (struct mtd_info *); | 68 | static int cfi_intelext_suspend (struct mtd_info *); |
60 | static void cfi_intelext_resume (struct mtd_info *); | 69 | static void cfi_intelext_resume (struct mtd_info *); |
70 | static int cfi_intelext_reboot (struct notifier_block *, unsigned long, void *); | ||
61 | 71 | ||
62 | static void cfi_intelext_destroy(struct mtd_info *); | 72 | static 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 | ||
816 | static void xip_disable(struct map_info *map, struct flchip *chip, | 831 | static 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 | ||
@@ -831,9 +845,8 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip, | |||
831 | chip->state = FL_READY; | 845 | chip->state = FL_READY; |
832 | } | 846 | } |
833 | (void) map_read(map, adr); | 847 | (void) map_read(map, adr); |
834 | asm volatile (".rep 8; nop; .endr"); /* fill instruction prefetch */ | 848 | xip_iprefetch(); |
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) \ | ||
1005 | do { \ | ||
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) \ | ||
1012 | do { \ | ||
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 | ||
994 | static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) | 1021 | static 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 | ||
1180 | static 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 | |||
1240 | static 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 | |||
1259 | static 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 | |||
1279 | static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, | 1206 | static 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 | |||
1955 | typedef 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 | |||
1959 | static int __xipram | ||
1960 | do_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 | |||
1992 | static int | ||
1993 | do_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 | |||
2017 | static int | ||
2018 | do_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 | |||
2033 | static 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 | |||
2167 | static 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 | |||
2175 | static 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 | |||
2183 | static 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 | |||
2191 | static 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 | |||
2199 | static 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 | |||
2209 | static 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 | |||
2037 | static int cfi_intelext_suspend(struct mtd_info *mtd) | 2221 | static 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 | ||
2312 | static 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 | |||
2336 | static 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 | |||
2128 | static void cfi_intelext_destroy(struct mtd_info *mtd) | 2346 | static 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..8505f118f2db 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 | ||
47 | static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); | 53 | static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); |
48 | static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); | 54 | static 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 | }; |
192 | static struct cfi_fixup jedec_fixup_table[] = { | 198 | static 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 | */ |
394 | static int chip_ready(struct map_info *map, unsigned long addr) | 401 | static 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 | */ | ||
426 | static 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 | |||
404 | static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) | 437 | static 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 | |||
585 | static 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 | |||
593 | static 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 | xip_iprefetch(); | ||
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 | |||
620 | static 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) \ | ||
749 | do { \ | ||
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) \ | ||
756 | do { \ | ||
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 | ||
527 | static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) | 765 | static 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 | ||
695 | static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, map_word datum) | 933 | static 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 | */ |
942 | static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | 1186 | static 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 | */ |
1133 | static inline int do_erase_chip(struct map_info *map, struct flchip *chip) | 1382 | static 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 | ||
1219 | static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, int len, void *thunk) | 1471 | static 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; |