diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/chips/Kconfig | 22 | ||||
-rw-r--r-- | drivers/mtd/chips/Makefile | 4 | ||||
-rw-r--r-- | drivers/mtd/chips/amd_flash.c | 80 | ||||
-rw-r--r-- | drivers/mtd/chips/cfi_cmdset_0001.c | 150 | ||||
-rw-r--r-- | drivers/mtd/chips/cfi_cmdset_0002.c | 130 | ||||
-rw-r--r-- | drivers/mtd/chips/cfi_cmdset_0020.c | 172 | ||||
-rw-r--r-- | drivers/mtd/chips/cfi_probe.c | 98 | ||||
-rw-r--r-- | drivers/mtd/chips/cfi_util.c | 16 | ||||
-rw-r--r-- | drivers/mtd/chips/chipreg.c | 6 | ||||
-rw-r--r-- | drivers/mtd/chips/fwh_lock.h | 6 | ||||
-rw-r--r-- | drivers/mtd/chips/gen_probe.c | 32 | ||||
-rw-r--r-- | drivers/mtd/chips/jedec.c | 206 | ||||
-rw-r--r-- | drivers/mtd/chips/jedec_probe.c | 48 | ||||
-rw-r--r-- | drivers/mtd/chips/map_absent.c | 8 | ||||
-rw-r--r-- | drivers/mtd/chips/sharp.c | 8 |
15 files changed, 493 insertions, 493 deletions
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig index df95d2158b16..eafa23f5cbd6 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.15 2005/06/06 23:04:35 tpoynor Exp $ | 2 | # $Id: Kconfig,v 1.18 2005/11/07 11:14:22 gleixner 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 |
@@ -39,7 +39,7 @@ config MTD_CFI_ADV_OPTIONS | |||
39 | If you need to specify a specific endianness for access to flash | 39 | If you need to specify a specific endianness for access to flash |
40 | chips, or if you wish to reduce the size of the kernel by including | 40 | chips, or if you wish to reduce the size of the kernel by including |
41 | support for only specific arrangements of flash chips, say 'Y'. This | 41 | support for only specific arrangements of flash chips, say 'Y'. This |
42 | option does not directly affect the code, but will enable other | 42 | option does not directly affect the code, but will enable other |
43 | configuration options which allow you to do so. | 43 | configuration options which allow you to do so. |
44 | 44 | ||
45 | If unsure, say 'N'. | 45 | If unsure, say 'N'. |
@@ -56,7 +56,7 @@ config MTD_CFI_NOSWAP | |||
56 | data bits when writing the 'magic' commands to the chips. Saying | 56 | data bits when writing the 'magic' commands to the chips. Saying |
57 | 'NO', which is the default when CONFIG_MTD_CFI_ADV_OPTIONS isn't | 57 | 'NO', which is the default when CONFIG_MTD_CFI_ADV_OPTIONS isn't |
58 | enabled, means that the CPU will not do any swapping; the chips | 58 | enabled, means that the CPU will not do any swapping; the chips |
59 | are expected to be wired to the CPU in 'host-endian' form. | 59 | are expected to be wired to the CPU in 'host-endian' form. |
60 | Specific arrangements are possible with the BIG_ENDIAN_BYTE and | 60 | Specific arrangements are possible with the BIG_ENDIAN_BYTE and |
61 | LITTLE_ENDIAN_BYTE, if the bytes are reversed. | 61 | LITTLE_ENDIAN_BYTE, if the bytes are reversed. |
62 | 62 | ||
@@ -79,10 +79,10 @@ config MTD_CFI_GEOMETRY | |||
79 | bool "Specific CFI Flash geometry selection" | 79 | bool "Specific CFI Flash geometry selection" |
80 | depends on MTD_CFI_ADV_OPTIONS | 80 | depends on MTD_CFI_ADV_OPTIONS |
81 | help | 81 | help |
82 | This option does not affect the code directly, but will enable | 82 | This option does not affect the code directly, but will enable |
83 | some other configuration options which would allow you to reduce | 83 | some other configuration options which would allow you to reduce |
84 | the size of the kernel by including support for only certain | 84 | the size of the kernel by including support for only certain |
85 | arrangements of CFI chips. If unsure, say 'N' and all options | 85 | arrangements of CFI chips. If unsure, say 'N' and all options |
86 | which are supported by the current code will be enabled. | 86 | which are supported by the current code will be enabled. |
87 | 87 | ||
88 | config MTD_MAP_BANK_WIDTH_1 | 88 | config MTD_MAP_BANK_WIDTH_1 |
@@ -197,7 +197,7 @@ config MTD_CFI_AMDSTD | |||
197 | help | 197 | help |
198 | The Common Flash Interface defines a number of different command | 198 | The Common Flash Interface defines a number of different command |
199 | sets which a CFI-compliant chip may claim to implement. This code | 199 | sets which a CFI-compliant chip may claim to implement. This code |
200 | provides support for one of those command sets, used on chips | 200 | provides support for one of those command sets, used on chips |
201 | including the AMD Am29LV320. | 201 | including the AMD Am29LV320. |
202 | 202 | ||
203 | config MTD_CFI_AMDSTD_RETRY | 203 | config MTD_CFI_AMDSTD_RETRY |
@@ -237,14 +237,14 @@ config MTD_RAM | |||
237 | tristate "Support for RAM chips in bus mapping" | 237 | tristate "Support for RAM chips in bus mapping" |
238 | depends on MTD | 238 | depends on MTD |
239 | help | 239 | help |
240 | This option enables basic support for RAM chips accessed through | 240 | This option enables basic support for RAM chips accessed through |
241 | a bus mapping driver. | 241 | a bus mapping driver. |
242 | 242 | ||
243 | config MTD_ROM | 243 | config MTD_ROM |
244 | tristate "Support for ROM chips in bus mapping" | 244 | tristate "Support for ROM chips in bus mapping" |
245 | depends on MTD | 245 | depends on MTD |
246 | help | 246 | help |
247 | This option enables basic support for ROM chips accessed through | 247 | This option enables basic support for ROM chips accessed through |
248 | a bus mapping driver. | 248 | a bus mapping driver. |
249 | 249 | ||
250 | config MTD_ABSENT | 250 | config MTD_ABSENT |
@@ -275,7 +275,7 @@ config MTD_AMDSTD | |||
275 | depends on MTD && MTD_OBSOLETE_CHIPS | 275 | depends on MTD && MTD_OBSOLETE_CHIPS |
276 | help | 276 | help |
277 | This option enables support for flash chips using AMD-compatible | 277 | This option enables support for flash chips using AMD-compatible |
278 | commands, including some which are not CFI-compatible and hence | 278 | commands, including some which are not CFI-compatible and hence |
279 | cannot be used with the CONFIG_MTD_CFI_AMDSTD option. | 279 | cannot be used with the CONFIG_MTD_CFI_AMDSTD option. |
280 | 280 | ||
281 | It also works on AMD compatible chips that do conform to CFI. | 281 | It also works on AMD compatible chips that do conform to CFI. |
@@ -285,7 +285,7 @@ config MTD_SHARP | |||
285 | depends on MTD && MTD_OBSOLETE_CHIPS | 285 | depends on MTD && MTD_OBSOLETE_CHIPS |
286 | help | 286 | help |
287 | This option enables support for flash chips using Sharp-compatible | 287 | This option enables support for flash chips using Sharp-compatible |
288 | commands, including some which are not CFI-compatible and hence | 288 | commands, including some which are not CFI-compatible and hence |
289 | cannot be used with the CONFIG_MTD_CFI_INTELxxx options. | 289 | cannot be used with the CONFIG_MTD_CFI_INTELxxx options. |
290 | 290 | ||
291 | config MTD_JEDEC | 291 | config MTD_JEDEC |
diff --git a/drivers/mtd/chips/Makefile b/drivers/mtd/chips/Makefile index 6830489828c6..8afe3092c4e3 100644 --- a/drivers/mtd/chips/Makefile +++ b/drivers/mtd/chips/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # linux/drivers/chips/Makefile | 2 | # linux/drivers/chips/Makefile |
3 | # | 3 | # |
4 | # $Id: Makefile.common,v 1.4 2004/07/12 16:07:30 dwmw2 Exp $ | 4 | # $Id: Makefile.common,v 1.5 2005/11/07 11:14:22 gleixner Exp $ |
5 | 5 | ||
6 | # *** BIG UGLY NOTE *** | 6 | # *** BIG UGLY NOTE *** |
7 | # | 7 | # |
@@ -11,7 +11,7 @@ | |||
11 | # the CFI command set drivers are linked before gen_probe.o | 11 | # the CFI command set drivers are linked before gen_probe.o |
12 | 12 | ||
13 | obj-$(CONFIG_MTD) += chipreg.o | 13 | obj-$(CONFIG_MTD) += chipreg.o |
14 | obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o | 14 | obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o |
15 | obj-$(CONFIG_MTD_CFI) += cfi_probe.o | 15 | obj-$(CONFIG_MTD_CFI) += cfi_probe.o |
16 | obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o | 16 | obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o |
17 | obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o | 17 | obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o |
diff --git a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c index 2dafeba3f3d5..fdb91b6f1d97 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.27 2005/02/04 07:43:09 jonashg Exp $ | 6 | * $Id: amd_flash.c,v 1.28 2005/11/07 11:14:22 gleixner Exp $ |
7 | * | 7 | * |
8 | * Copyright (c) 2001 Axis Communications AB | 8 | * Copyright (c) 2001 Axis Communications AB |
9 | * | 9 | * |
@@ -93,9 +93,9 @@ | |||
93 | #define D6_MASK 0x40 | 93 | #define D6_MASK 0x40 |
94 | 94 | ||
95 | struct amd_flash_private { | 95 | struct amd_flash_private { |
96 | int device_type; | 96 | int device_type; |
97 | int interleave; | 97 | int interleave; |
98 | int numchips; | 98 | int numchips; |
99 | unsigned long chipshift; | 99 | unsigned long chipshift; |
100 | // const char *im_name; | 100 | // const char *im_name; |
101 | struct flchip chips[0]; | 101 | struct flchip chips[0]; |
@@ -253,7 +253,7 @@ static int amd_flash_do_unlock(struct mtd_info *mtd, loff_t ofs, size_t len, | |||
253 | int i; | 253 | int i; |
254 | int retval = 0; | 254 | int retval = 0; |
255 | int lock_status; | 255 | int lock_status; |
256 | 256 | ||
257 | map = mtd->priv; | 257 | map = mtd->priv; |
258 | 258 | ||
259 | /* Pass the whole chip through sector by sector and check for each | 259 | /* Pass the whole chip through sector by sector and check for each |
@@ -273,7 +273,7 @@ static int amd_flash_do_unlock(struct mtd_info *mtd, loff_t ofs, size_t len, | |||
273 | unlock_sector(map, eraseoffset, is_unlock); | 273 | unlock_sector(map, eraseoffset, is_unlock); |
274 | 274 | ||
275 | lock_status = is_sector_locked(map, eraseoffset); | 275 | lock_status = is_sector_locked(map, eraseoffset); |
276 | 276 | ||
277 | if (is_unlock && lock_status) { | 277 | if (is_unlock && lock_status) { |
278 | printk("Cannot unlock sector at address %x length %xx\n", | 278 | printk("Cannot unlock sector at address %x length %xx\n", |
279 | eraseoffset, merip->erasesize); | 279 | eraseoffset, merip->erasesize); |
@@ -305,7 +305,7 @@ static int amd_flash_lock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
305 | /* | 305 | /* |
306 | * Reads JEDEC manufacturer ID and device ID and returns the index of the first | 306 | * Reads JEDEC manufacturer ID and device ID and returns the index of the first |
307 | * matching table entry (-1 if not found or alias for already found chip). | 307 | * matching table entry (-1 if not found or alias for already found chip). |
308 | */ | 308 | */ |
309 | static int probe_new_chip(struct mtd_info *mtd, __u32 base, | 309 | static int probe_new_chip(struct mtd_info *mtd, __u32 base, |
310 | struct flchip *chips, | 310 | struct flchip *chips, |
311 | struct amd_flash_private *private, | 311 | struct amd_flash_private *private, |
@@ -636,7 +636,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map) | |||
636 | { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, | 636 | { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, |
637 | { .offset = 0x1F0000, .erasesize = 0x02000, .numblocks = 8 } | 637 | { .offset = 0x1F0000, .erasesize = 0x02000, .numblocks = 8 } |
638 | } | 638 | } |
639 | } | 639 | } |
640 | }; | 640 | }; |
641 | 641 | ||
642 | struct mtd_info *mtd; | 642 | struct mtd_info *mtd; |
@@ -701,7 +701,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map) | |||
701 | 701 | ||
702 | mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * | 702 | mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * |
703 | mtd->numeraseregions, GFP_KERNEL); | 703 | mtd->numeraseregions, GFP_KERNEL); |
704 | if (!mtd->eraseregions) { | 704 | if (!mtd->eraseregions) { |
705 | printk(KERN_WARNING "%s: Failed to allocate " | 705 | printk(KERN_WARNING "%s: Failed to allocate " |
706 | "memory for MTD erase region info\n", map->name); | 706 | "memory for MTD erase region info\n", map->name); |
707 | kfree(mtd); | 707 | kfree(mtd); |
@@ -739,12 +739,12 @@ static struct mtd_info *amd_flash_probe(struct map_info *map) | |||
739 | mtd->type = MTD_NORFLASH; | 739 | mtd->type = MTD_NORFLASH; |
740 | mtd->flags = MTD_CAP_NORFLASH; | 740 | mtd->flags = MTD_CAP_NORFLASH; |
741 | mtd->name = map->name; | 741 | mtd->name = map->name; |
742 | mtd->erase = amd_flash_erase; | 742 | mtd->erase = amd_flash_erase; |
743 | mtd->read = amd_flash_read; | 743 | mtd->read = amd_flash_read; |
744 | mtd->write = amd_flash_write; | 744 | mtd->write = amd_flash_write; |
745 | mtd->sync = amd_flash_sync; | 745 | mtd->sync = amd_flash_sync; |
746 | mtd->suspend = amd_flash_suspend; | 746 | mtd->suspend = amd_flash_suspend; |
747 | mtd->resume = amd_flash_resume; | 747 | mtd->resume = amd_flash_resume; |
748 | mtd->lock = amd_flash_lock; | 748 | mtd->lock = amd_flash_lock; |
749 | mtd->unlock = amd_flash_unlock; | 749 | mtd->unlock = amd_flash_unlock; |
750 | 750 | ||
@@ -789,7 +789,7 @@ retry: | |||
789 | map->name, chip->state); | 789 | map->name, chip->state); |
790 | set_current_state(TASK_UNINTERRUPTIBLE); | 790 | set_current_state(TASK_UNINTERRUPTIBLE); |
791 | add_wait_queue(&chip->wq, &wait); | 791 | add_wait_queue(&chip->wq, &wait); |
792 | 792 | ||
793 | spin_unlock_bh(chip->mutex); | 793 | spin_unlock_bh(chip->mutex); |
794 | 794 | ||
795 | schedule(); | 795 | schedule(); |
@@ -802,7 +802,7 @@ retry: | |||
802 | timeo = jiffies + HZ; | 802 | timeo = jiffies + HZ; |
803 | 803 | ||
804 | goto retry; | 804 | goto retry; |
805 | } | 805 | } |
806 | 806 | ||
807 | adr += chip->start; | 807 | adr += chip->start; |
808 | 808 | ||
@@ -889,7 +889,7 @@ retry: | |||
889 | map->name, chip->state); | 889 | map->name, chip->state); |
890 | set_current_state(TASK_UNINTERRUPTIBLE); | 890 | set_current_state(TASK_UNINTERRUPTIBLE); |
891 | add_wait_queue(&chip->wq, &wait); | 891 | add_wait_queue(&chip->wq, &wait); |
892 | 892 | ||
893 | spin_unlock_bh(chip->mutex); | 893 | spin_unlock_bh(chip->mutex); |
894 | 894 | ||
895 | schedule(); | 895 | schedule(); |
@@ -901,7 +901,7 @@ retry: | |||
901 | timeo = jiffies + HZ; | 901 | timeo = jiffies + HZ; |
902 | 902 | ||
903 | goto retry; | 903 | goto retry; |
904 | } | 904 | } |
905 | 905 | ||
906 | chip->state = FL_WRITING; | 906 | chip->state = FL_WRITING; |
907 | 907 | ||
@@ -911,7 +911,7 @@ retry: | |||
911 | wide_write(map, datum, adr); | 911 | wide_write(map, datum, adr); |
912 | 912 | ||
913 | times_left = 500000; | 913 | times_left = 500000; |
914 | while (times_left-- && flash_is_busy(map, adr, private->interleave)) { | 914 | while (times_left-- && flash_is_busy(map, adr, private->interleave)) { |
915 | if (need_resched()) { | 915 | if (need_resched()) { |
916 | spin_unlock_bh(chip->mutex); | 916 | spin_unlock_bh(chip->mutex); |
917 | schedule(); | 917 | schedule(); |
@@ -989,7 +989,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len, | |||
989 | if (ret) { | 989 | if (ret) { |
990 | return ret; | 990 | return ret; |
991 | } | 991 | } |
992 | 992 | ||
993 | ofs += n; | 993 | ofs += n; |
994 | buf += n; | 994 | buf += n; |
995 | (*retlen) += n; | 995 | (*retlen) += n; |
@@ -1002,7 +1002,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len, | |||
1002 | } | 1002 | } |
1003 | } | 1003 | } |
1004 | } | 1004 | } |
1005 | 1005 | ||
1006 | /* We are now aligned, write as much as possible. */ | 1006 | /* We are now aligned, write as much as possible. */ |
1007 | while(len >= map->buswidth) { | 1007 | while(len >= map->buswidth) { |
1008 | __u32 datum; | 1008 | __u32 datum; |
@@ -1063,7 +1063,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len, | |||
1063 | if (ret) { | 1063 | if (ret) { |
1064 | return ret; | 1064 | return ret; |
1065 | } | 1065 | } |
1066 | 1066 | ||
1067 | (*retlen) += n; | 1067 | (*retlen) += n; |
1068 | } | 1068 | } |
1069 | 1069 | ||
@@ -1085,7 +1085,7 @@ retry: | |||
1085 | if (chip->state != FL_READY){ | 1085 | if (chip->state != FL_READY){ |
1086 | set_current_state(TASK_UNINTERRUPTIBLE); | 1086 | set_current_state(TASK_UNINTERRUPTIBLE); |
1087 | add_wait_queue(&chip->wq, &wait); | 1087 | add_wait_queue(&chip->wq, &wait); |
1088 | 1088 | ||
1089 | spin_unlock_bh(chip->mutex); | 1089 | spin_unlock_bh(chip->mutex); |
1090 | 1090 | ||
1091 | schedule(); | 1091 | schedule(); |
@@ -1098,7 +1098,7 @@ retry: | |||
1098 | timeo = jiffies + HZ; | 1098 | timeo = jiffies + HZ; |
1099 | 1099 | ||
1100 | goto retry; | 1100 | goto retry; |
1101 | } | 1101 | } |
1102 | 1102 | ||
1103 | chip->state = FL_ERASING; | 1103 | chip->state = FL_ERASING; |
1104 | 1104 | ||
@@ -1106,30 +1106,30 @@ retry: | |||
1106 | ENABLE_VPP(map); | 1106 | ENABLE_VPP(map); |
1107 | send_cmd(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA); | 1107 | send_cmd(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA); |
1108 | send_cmd_to_addr(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA_2, adr); | 1108 | send_cmd_to_addr(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA_2, adr); |
1109 | 1109 | ||
1110 | timeo = jiffies + (HZ * 20); | 1110 | timeo = jiffies + (HZ * 20); |
1111 | 1111 | ||
1112 | spin_unlock_bh(chip->mutex); | 1112 | spin_unlock_bh(chip->mutex); |
1113 | msleep(1000); | 1113 | msleep(1000); |
1114 | spin_lock_bh(chip->mutex); | 1114 | spin_lock_bh(chip->mutex); |
1115 | 1115 | ||
1116 | while (flash_is_busy(map, adr, private->interleave)) { | 1116 | while (flash_is_busy(map, adr, private->interleave)) { |
1117 | 1117 | ||
1118 | if (chip->state != FL_ERASING) { | 1118 | if (chip->state != FL_ERASING) { |
1119 | /* Someone's suspended the erase. Sleep */ | 1119 | /* Someone's suspended the erase. Sleep */ |
1120 | set_current_state(TASK_UNINTERRUPTIBLE); | 1120 | set_current_state(TASK_UNINTERRUPTIBLE); |
1121 | add_wait_queue(&chip->wq, &wait); | 1121 | add_wait_queue(&chip->wq, &wait); |
1122 | 1122 | ||
1123 | spin_unlock_bh(chip->mutex); | 1123 | spin_unlock_bh(chip->mutex); |
1124 | printk(KERN_INFO "%s: erase suspended. Sleeping\n", | 1124 | printk(KERN_INFO "%s: erase suspended. Sleeping\n", |
1125 | map->name); | 1125 | map->name); |
1126 | schedule(); | 1126 | schedule(); |
1127 | remove_wait_queue(&chip->wq, &wait); | 1127 | remove_wait_queue(&chip->wq, &wait); |
1128 | 1128 | ||
1129 | if (signal_pending(current)) { | 1129 | if (signal_pending(current)) { |
1130 | return -EINTR; | 1130 | return -EINTR; |
1131 | } | 1131 | } |
1132 | 1132 | ||
1133 | timeo = jiffies + (HZ*2); /* FIXME */ | 1133 | timeo = jiffies + (HZ*2); /* FIXME */ |
1134 | spin_lock_bh(chip->mutex); | 1134 | spin_lock_bh(chip->mutex); |
1135 | continue; | 1135 | continue; |
@@ -1145,7 +1145,7 @@ retry: | |||
1145 | 1145 | ||
1146 | return -EIO; | 1146 | return -EIO; |
1147 | } | 1147 | } |
1148 | 1148 | ||
1149 | /* Latency issues. Drop the lock, wait a while and retry */ | 1149 | /* Latency issues. Drop the lock, wait a while and retry */ |
1150 | spin_unlock_bh(chip->mutex); | 1150 | spin_unlock_bh(chip->mutex); |
1151 | 1151 | ||
@@ -1153,7 +1153,7 @@ retry: | |||
1153 | schedule(); | 1153 | schedule(); |
1154 | else | 1154 | else |
1155 | udelay(1); | 1155 | udelay(1); |
1156 | 1156 | ||
1157 | spin_lock_bh(chip->mutex); | 1157 | spin_lock_bh(chip->mutex); |
1158 | } | 1158 | } |
1159 | 1159 | ||
@@ -1180,7 +1180,7 @@ retry: | |||
1180 | return -EIO; | 1180 | return -EIO; |
1181 | } | 1181 | } |
1182 | } | 1182 | } |
1183 | 1183 | ||
1184 | DISABLE_VPP(map); | 1184 | DISABLE_VPP(map); |
1185 | chip->state = FL_READY; | 1185 | chip->state = FL_READY; |
1186 | wake_up(&chip->wq); | 1186 | wake_up(&chip->wq); |
@@ -1246,7 +1246,7 @@ static int amd_flash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
1246 | * with the erase region at that address. | 1246 | * with the erase region at that address. |
1247 | */ | 1247 | */ |
1248 | 1248 | ||
1249 | while ((i < mtd->numeraseregions) && | 1249 | while ((i < mtd->numeraseregions) && |
1250 | ((instr->addr + instr->len) >= regions[i].offset)) { | 1250 | ((instr->addr + instr->len) >= regions[i].offset)) { |
1251 | i++; | 1251 | i++; |
1252 | } | 1252 | } |
@@ -1293,10 +1293,10 @@ static int amd_flash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
1293 | } | 1293 | } |
1294 | } | 1294 | } |
1295 | } | 1295 | } |
1296 | 1296 | ||
1297 | instr->state = MTD_ERASE_DONE; | 1297 | instr->state = MTD_ERASE_DONE; |
1298 | mtd_erase_callback(instr); | 1298 | mtd_erase_callback(instr); |
1299 | 1299 | ||
1300 | return 0; | 1300 | return 0; |
1301 | } | 1301 | } |
1302 | 1302 | ||
@@ -1324,7 +1324,7 @@ static void amd_flash_sync(struct mtd_info *mtd) | |||
1324 | case FL_JEDEC_QUERY: | 1324 | case FL_JEDEC_QUERY: |
1325 | chip->oldstate = chip->state; | 1325 | chip->oldstate = chip->state; |
1326 | chip->state = FL_SYNCING; | 1326 | chip->state = FL_SYNCING; |
1327 | /* No need to wake_up() on this state change - | 1327 | /* No need to wake_up() on this state change - |
1328 | * as the whole point is that nobody can do anything | 1328 | * as the whole point is that nobody can do anything |
1329 | * with the chip now anyway. | 1329 | * with the chip now anyway. |
1330 | */ | 1330 | */ |
@@ -1335,13 +1335,13 @@ static void amd_flash_sync(struct mtd_info *mtd) | |||
1335 | default: | 1335 | default: |
1336 | /* Not an idle state */ | 1336 | /* Not an idle state */ |
1337 | add_wait_queue(&chip->wq, &wait); | 1337 | add_wait_queue(&chip->wq, &wait); |
1338 | 1338 | ||
1339 | spin_unlock_bh(chip->mutex); | 1339 | spin_unlock_bh(chip->mutex); |
1340 | 1340 | ||
1341 | schedule(); | 1341 | schedule(); |
1342 | 1342 | ||
1343 | remove_wait_queue(&chip->wq, &wait); | 1343 | remove_wait_queue(&chip->wq, &wait); |
1344 | 1344 | ||
1345 | goto retry; | 1345 | goto retry; |
1346 | } | 1346 | } |
1347 | } | 1347 | } |
@@ -1351,7 +1351,7 @@ static void amd_flash_sync(struct mtd_info *mtd) | |||
1351 | chip = &private->chips[i]; | 1351 | chip = &private->chips[i]; |
1352 | 1352 | ||
1353 | spin_lock_bh(chip->mutex); | 1353 | spin_lock_bh(chip->mutex); |
1354 | 1354 | ||
1355 | if (chip->state == FL_SYNCING) { | 1355 | if (chip->state == FL_SYNCING) { |
1356 | chip->state = chip->oldstate; | 1356 | chip->state = chip->oldstate; |
1357 | wake_up(&chip->wq); | 1357 | wake_up(&chip->wq); |
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 61a2ec9901e2..e3a5c5d331b4 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c | |||
@@ -4,9 +4,9 @@ | |||
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.184 2005/10/25 20:28:40 nico Exp $ | 7 | * $Id: cfi_cmdset_0001.c,v 1.185 2005/11/07 11:14:22 gleixner Exp $ |
8 | * | ||
8 | * | 9 | * |
9 | * | ||
10 | * 10/10/2000 Nicolas Pitre <nico@cam.org> | 10 | * 10/10/2000 Nicolas Pitre <nico@cam.org> |
11 | * - completely revamped method functions so they are aware and | 11 | * - completely revamped method functions so they are aware and |
12 | * independent of the flash geometry (buswidth, interleave, etc.) | 12 | * independent of the flash geometry (buswidth, interleave, etc.) |
@@ -120,17 +120,17 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp) | |||
120 | printk(" - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported"); | 120 | printk(" - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported"); |
121 | printk(" - Extended Flash Array: %s\n", extp->FeatureSupport&1024?"supported":"unsupported"); | 121 | printk(" - Extended Flash Array: %s\n", extp->FeatureSupport&1024?"supported":"unsupported"); |
122 | for (i=11; i<32; i++) { | 122 | for (i=11; i<32; i++) { |
123 | if (extp->FeatureSupport & (1<<i)) | 123 | if (extp->FeatureSupport & (1<<i)) |
124 | printk(" - Unknown Bit %X: supported\n", i); | 124 | printk(" - Unknown Bit %X: supported\n", i); |
125 | } | 125 | } |
126 | 126 | ||
127 | printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); | 127 | printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); |
128 | printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported"); | 128 | printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported"); |
129 | for (i=1; i<8; i++) { | 129 | for (i=1; i<8; i++) { |
130 | if (extp->SuspendCmdSupport & (1<<i)) | 130 | if (extp->SuspendCmdSupport & (1<<i)) |
131 | printk(" - Unknown Bit %X: supported\n", i); | 131 | printk(" - Unknown Bit %X: supported\n", i); |
132 | } | 132 | } |
133 | 133 | ||
134 | printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); | 134 | printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); |
135 | printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); | 135 | printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); |
136 | printk(" - Lock-Down Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); | 136 | printk(" - Lock-Down Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); |
@@ -145,16 +145,16 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp) | |||
145 | printk(" - Unknown Bit %X Active: yes\n",i); | 145 | printk(" - Unknown Bit %X Active: yes\n",i); |
146 | } | 146 | } |
147 | 147 | ||
148 | printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", | 148 | printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", |
149 | extp->VccOptimal >> 4, extp->VccOptimal & 0xf); | 149 | extp->VccOptimal >> 4, extp->VccOptimal & 0xf); |
150 | if (extp->VppOptimal) | 150 | if (extp->VppOptimal) |
151 | printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", | 151 | printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", |
152 | extp->VppOptimal >> 4, extp->VppOptimal & 0xf); | 152 | extp->VppOptimal >> 4, extp->VppOptimal & 0xf); |
153 | } | 153 | } |
154 | #endif | 154 | #endif |
155 | 155 | ||
156 | #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE | 156 | #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE |
157 | /* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ | 157 | /* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ |
158 | static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) | 158 | static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) |
159 | { | 159 | { |
160 | struct map_info *map = mtd->priv; | 160 | struct map_info *map = mtd->priv; |
@@ -185,7 +185,7 @@ static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param) | |||
185 | { | 185 | { |
186 | struct map_info *map = mtd->priv; | 186 | struct map_info *map = mtd->priv; |
187 | struct cfi_private *cfi = map->fldrv_priv; | 187 | struct cfi_private *cfi = map->fldrv_priv; |
188 | 188 | ||
189 | cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */ | 189 | cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */ |
190 | cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */ | 190 | cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */ |
191 | } | 191 | } |
@@ -194,7 +194,7 @@ static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param) | |||
194 | { | 194 | { |
195 | struct map_info *map = mtd->priv; | 195 | struct map_info *map = mtd->priv; |
196 | struct cfi_private *cfi = map->fldrv_priv; | 196 | struct cfi_private *cfi = map->fldrv_priv; |
197 | 197 | ||
198 | /* Note this is done after the region info is endian swapped */ | 198 | /* Note this is done after the region info is endian swapped */ |
199 | cfi->cfiq->EraseRegionInfo[1] = | 199 | cfi->cfiq->EraseRegionInfo[1] = |
200 | (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e; | 200 | (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e; |
@@ -222,7 +222,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) | |||
222 | 222 | ||
223 | static struct cfi_fixup cfi_fixup_table[] = { | 223 | static struct cfi_fixup cfi_fixup_table[] = { |
224 | #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE | 224 | #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE |
225 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL }, | 225 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL }, |
226 | #endif | 226 | #endif |
227 | #ifdef CMDSET0001_DISABLE_WRITE_SUSPEND | 227 | #ifdef CMDSET0001_DISABLE_WRITE_SUSPEND |
228 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL }, | 228 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL }, |
@@ -327,7 +327,7 @@ read_pri_intelext(struct map_info *map, __u16 adr) | |||
327 | goto again; | 327 | goto again; |
328 | } | 328 | } |
329 | } | 329 | } |
330 | 330 | ||
331 | return extp; | 331 | return extp; |
332 | } | 332 | } |
333 | 333 | ||
@@ -368,7 +368,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary) | |||
368 | mtd->reboot_notifier.notifier_call = cfi_intelext_reboot; | 368 | mtd->reboot_notifier.notifier_call = cfi_intelext_reboot; |
369 | 369 | ||
370 | if (cfi->cfi_mode == CFI_MODE_CFI) { | 370 | if (cfi->cfi_mode == CFI_MODE_CFI) { |
371 | /* | 371 | /* |
372 | * It's a real CFI chip, not one for which the probe | 372 | * It's a real CFI chip, not one for which the probe |
373 | * routine faked a CFI structure. So we read the feature | 373 | * routine faked a CFI structure. So we read the feature |
374 | * table from it. | 374 | * table from it. |
@@ -383,14 +383,14 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary) | |||
383 | } | 383 | } |
384 | 384 | ||
385 | /* Install our own private info structure */ | 385 | /* Install our own private info structure */ |
386 | cfi->cmdset_priv = extp; | 386 | cfi->cmdset_priv = extp; |
387 | 387 | ||
388 | cfi_fixup(mtd, cfi_fixup_table); | 388 | cfi_fixup(mtd, cfi_fixup_table); |
389 | 389 | ||
390 | #ifdef DEBUG_CFI_FEATURES | 390 | #ifdef DEBUG_CFI_FEATURES |
391 | /* Tell the user about it in lots of lovely detail */ | 391 | /* Tell the user about it in lots of lovely detail */ |
392 | cfi_tell_features(extp); | 392 | cfi_tell_features(extp); |
393 | #endif | 393 | #endif |
394 | 394 | ||
395 | if(extp->SuspendCmdSupport & 1) { | 395 | if(extp->SuspendCmdSupport & 1) { |
396 | printk(KERN_NOTICE "cfi_cmdset_0001: Erase suspend on write enabled\n"); | 396 | printk(KERN_NOTICE "cfi_cmdset_0001: Erase suspend on write enabled\n"); |
@@ -408,10 +408,10 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary) | |||
408 | cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; | 408 | cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; |
409 | cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp; | 409 | cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp; |
410 | cfi->chips[i].ref_point_counter = 0; | 410 | cfi->chips[i].ref_point_counter = 0; |
411 | } | 411 | } |
412 | 412 | ||
413 | map->fldrv = &cfi_intelext_chipdrv; | 413 | map->fldrv = &cfi_intelext_chipdrv; |
414 | 414 | ||
415 | return cfi_intelext_setup(mtd); | 415 | return cfi_intelext_setup(mtd); |
416 | } | 416 | } |
417 | 417 | ||
@@ -428,13 +428,13 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd) | |||
428 | mtd->size = devsize * cfi->numchips; | 428 | mtd->size = devsize * cfi->numchips; |
429 | 429 | ||
430 | mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; | 430 | mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; |
431 | mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) | 431 | mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) |
432 | * mtd->numeraseregions, GFP_KERNEL); | 432 | * mtd->numeraseregions, GFP_KERNEL); |
433 | if (!mtd->eraseregions) { | 433 | if (!mtd->eraseregions) { |
434 | printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); | 434 | printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); |
435 | goto setup_err; | 435 | goto setup_err; |
436 | } | 436 | } |
437 | 437 | ||
438 | for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { | 438 | for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { |
439 | unsigned long ernum, ersize; | 439 | unsigned long ernum, ersize; |
440 | ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; | 440 | ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; |
@@ -701,7 +701,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr | |||
701 | break; | 701 | break; |
702 | 702 | ||
703 | if (time_after(jiffies, timeo)) { | 703 | if (time_after(jiffies, timeo)) { |
704 | printk(KERN_ERR "%s: Waiting for chip to be ready timed out. Status %lx\n", | 704 | printk(KERN_ERR "%s: Waiting for chip to be ready timed out. Status %lx\n", |
705 | map->name, status.x[0]); | 705 | map->name, status.x[0]); |
706 | return -EIO; | 706 | return -EIO; |
707 | } | 707 | } |
@@ -711,7 +711,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr | |||
711 | /* Someone else might have been playing with it. */ | 711 | /* Someone else might have been playing with it. */ |
712 | goto retry; | 712 | goto retry; |
713 | } | 713 | } |
714 | 714 | ||
715 | case FL_READY: | 715 | case FL_READY: |
716 | case FL_CFI_QUERY: | 716 | case FL_CFI_QUERY: |
717 | case FL_JEDEC_QUERY: | 717 | case FL_JEDEC_QUERY: |
@@ -830,14 +830,14 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad | |||
830 | switch(chip->oldstate) { | 830 | switch(chip->oldstate) { |
831 | case FL_ERASING: | 831 | case FL_ERASING: |
832 | chip->state = chip->oldstate; | 832 | chip->state = chip->oldstate; |
833 | /* What if one interleaved chip has finished and the | 833 | /* What if one interleaved chip has finished and the |
834 | other hasn't? The old code would leave the finished | 834 | other hasn't? The old code would leave the finished |
835 | one in READY mode. That's bad, and caused -EROFS | 835 | one in READY mode. That's bad, and caused -EROFS |
836 | errors to be returned from do_erase_oneblock because | 836 | errors to be returned from do_erase_oneblock because |
837 | that's the only bit it checked for at the time. | 837 | that's the only bit it checked for at the time. |
838 | As the state machine appears to explicitly allow | 838 | As the state machine appears to explicitly allow |
839 | sending the 0x70 (Read Status) command to an erasing | 839 | sending the 0x70 (Read Status) command to an erasing |
840 | chip and expecting it to be ignored, that's what we | 840 | chip and expecting it to be ignored, that's what we |
841 | do. */ | 841 | do. */ |
842 | map_write(map, CMD(0xd0), adr); | 842 | map_write(map, CMD(0xd0), adr); |
843 | map_write(map, CMD(0x70), adr); | 843 | map_write(map, CMD(0x70), adr); |
@@ -1073,8 +1073,8 @@ static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t a | |||
1073 | 1073 | ||
1074 | adr += chip->start; | 1074 | adr += chip->start; |
1075 | 1075 | ||
1076 | /* Ensure cmd read/writes are aligned. */ | 1076 | /* Ensure cmd read/writes are aligned. */ |
1077 | cmd_addr = adr & ~(map_bankwidth(map)-1); | 1077 | cmd_addr = adr & ~(map_bankwidth(map)-1); |
1078 | 1078 | ||
1079 | spin_lock(chip->mutex); | 1079 | spin_lock(chip->mutex); |
1080 | 1080 | ||
@@ -1102,7 +1102,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si | |||
1102 | 1102 | ||
1103 | if (!map->virt || (from + len > mtd->size)) | 1103 | if (!map->virt || (from + len > mtd->size)) |
1104 | return -EINVAL; | 1104 | return -EINVAL; |
1105 | 1105 | ||
1106 | *mtdbuf = (void *)map->virt + from; | 1106 | *mtdbuf = (void *)map->virt + from; |
1107 | *retlen = 0; | 1107 | *retlen = 0; |
1108 | 1108 | ||
@@ -1129,7 +1129,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si | |||
1129 | 1129 | ||
1130 | *retlen += thislen; | 1130 | *retlen += thislen; |
1131 | len -= thislen; | 1131 | len -= thislen; |
1132 | 1132 | ||
1133 | ofs = 0; | 1133 | ofs = 0; |
1134 | chipnum++; | 1134 | chipnum++; |
1135 | } | 1135 | } |
@@ -1187,8 +1187,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof | |||
1187 | 1187 | ||
1188 | adr += chip->start; | 1188 | adr += chip->start; |
1189 | 1189 | ||
1190 | /* Ensure cmd read/writes are aligned. */ | 1190 | /* Ensure cmd read/writes are aligned. */ |
1191 | cmd_addr = adr & ~(map_bankwidth(map)-1); | 1191 | cmd_addr = adr & ~(map_bankwidth(map)-1); |
1192 | 1192 | ||
1193 | spin_lock(chip->mutex); | 1193 | spin_lock(chip->mutex); |
1194 | ret = get_chip(map, chip, cmd_addr, FL_READY); | 1194 | ret = get_chip(map, chip, cmd_addr, FL_READY); |
@@ -1243,7 +1243,7 @@ static int cfi_intelext_read (struct mtd_info *mtd, loff_t from, size_t len, siz | |||
1243 | *retlen += thislen; | 1243 | *retlen += thislen; |
1244 | len -= thislen; | 1244 | len -= thislen; |
1245 | buf += thislen; | 1245 | buf += thislen; |
1246 | 1246 | ||
1247 | ofs = 0; | 1247 | ofs = 0; |
1248 | chipnum++; | 1248 | chipnum++; |
1249 | } | 1249 | } |
@@ -1311,7 +1311,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, | |||
1311 | status = map_read(map, adr); | 1311 | status = map_read(map, adr); |
1312 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1312 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1313 | break; | 1313 | break; |
1314 | 1314 | ||
1315 | /* OK Still waiting */ | 1315 | /* OK Still waiting */ |
1316 | if (time_after(jiffies, timeo)) { | 1316 | if (time_after(jiffies, timeo)) { |
1317 | map_write(map, CMD(0x70), adr); | 1317 | map_write(map, CMD(0x70), adr); |
@@ -1331,7 +1331,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, | |||
1331 | if (!chip->word_write_time) | 1331 | if (!chip->word_write_time) |
1332 | chip->word_write_time = 1; | 1332 | chip->word_write_time = 1; |
1333 | } | 1333 | } |
1334 | if (z > 1) | 1334 | if (z > 1) |
1335 | chip->word_write_time++; | 1335 | chip->word_write_time++; |
1336 | 1336 | ||
1337 | /* Done and happy. */ | 1337 | /* Done and happy. */ |
@@ -1394,7 +1394,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le | |||
1394 | 1394 | ||
1395 | ret = do_write_oneword(map, &cfi->chips[chipnum], | 1395 | ret = do_write_oneword(map, &cfi->chips[chipnum], |
1396 | bus_ofs, datum, FL_WRITING); | 1396 | bus_ofs, datum, FL_WRITING); |
1397 | if (ret) | 1397 | if (ret) |
1398 | return ret; | 1398 | return ret; |
1399 | 1399 | ||
1400 | len -= n; | 1400 | len -= n; |
@@ -1403,13 +1403,13 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le | |||
1403 | (*retlen) += n; | 1403 | (*retlen) += n; |
1404 | 1404 | ||
1405 | if (ofs >> cfi->chipshift) { | 1405 | if (ofs >> cfi->chipshift) { |
1406 | chipnum ++; | 1406 | chipnum ++; |
1407 | ofs = 0; | 1407 | ofs = 0; |
1408 | if (chipnum == cfi->numchips) | 1408 | if (chipnum == cfi->numchips) |
1409 | return 0; | 1409 | return 0; |
1410 | } | 1410 | } |
1411 | } | 1411 | } |
1412 | 1412 | ||
1413 | while(len >= map_bankwidth(map)) { | 1413 | while(len >= map_bankwidth(map)) { |
1414 | map_word datum = map_word_load(map, buf); | 1414 | map_word datum = map_word_load(map, buf); |
1415 | 1415 | ||
@@ -1424,7 +1424,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le | |||
1424 | len -= map_bankwidth(map); | 1424 | len -= map_bankwidth(map); |
1425 | 1425 | ||
1426 | if (ofs >> cfi->chipshift) { | 1426 | if (ofs >> cfi->chipshift) { |
1427 | chipnum ++; | 1427 | chipnum ++; |
1428 | ofs = 0; | 1428 | ofs = 0; |
1429 | if (chipnum == cfi->numchips) | 1429 | if (chipnum == cfi->numchips) |
1430 | return 0; | 1430 | return 0; |
@@ -1439,9 +1439,9 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le | |||
1439 | 1439 | ||
1440 | ret = do_write_oneword(map, &cfi->chips[chipnum], | 1440 | ret = do_write_oneword(map, &cfi->chips[chipnum], |
1441 | ofs, datum, FL_WRITING); | 1441 | ofs, datum, FL_WRITING); |
1442 | if (ret) | 1442 | if (ret) |
1443 | return ret; | 1443 | return ret; |
1444 | 1444 | ||
1445 | (*retlen) += len; | 1445 | (*retlen) += len; |
1446 | } | 1446 | } |
1447 | 1447 | ||
@@ -1449,7 +1449,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le | |||
1449 | } | 1449 | } |
1450 | 1450 | ||
1451 | 1451 | ||
1452 | static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | 1452 | static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, |
1453 | unsigned long adr, const struct kvec **pvec, | 1453 | unsigned long adr, const struct kvec **pvec, |
1454 | unsigned long *pvec_seek, int len) | 1454 | unsigned long *pvec_seek, int len) |
1455 | { | 1455 | { |
@@ -1480,7 +1480,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | |||
1480 | xip_disable(map, chip, cmd_adr); | 1480 | xip_disable(map, chip, cmd_adr); |
1481 | 1481 | ||
1482 | /* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set | 1482 | /* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set |
1483 | [...], the device will not accept any more Write to Buffer commands". | 1483 | [...], the device will not accept any more Write to Buffer commands". |
1484 | So we must check here and reset those bits if they're set. Otherwise | 1484 | So we must check here and reset those bits if they're set. Otherwise |
1485 | we're just pissing in the wind */ | 1485 | we're just pissing in the wind */ |
1486 | if (chip->state != FL_STATUS) | 1486 | if (chip->state != FL_STATUS) |
@@ -1549,9 +1549,9 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | |||
1549 | 1549 | ||
1550 | if (!word_gap && len < map_bankwidth(map)) | 1550 | if (!word_gap && len < map_bankwidth(map)) |
1551 | datum = map_word_ff(map); | 1551 | datum = map_word_ff(map); |
1552 | 1552 | ||
1553 | datum = map_word_load_partial(map, datum, | 1553 | datum = map_word_load_partial(map, datum, |
1554 | vec->iov_base + vec_seek, | 1554 | vec->iov_base + vec_seek, |
1555 | word_gap, n); | 1555 | word_gap, n); |
1556 | 1556 | ||
1557 | len -= n; | 1557 | len -= n; |
@@ -1575,7 +1575,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | |||
1575 | map_write(map, CMD(0xd0), cmd_adr); | 1575 | map_write(map, CMD(0xd0), cmd_adr); |
1576 | chip->state = FL_WRITING; | 1576 | chip->state = FL_WRITING; |
1577 | 1577 | ||
1578 | INVALIDATE_CACHE_UDELAY(map, chip, | 1578 | INVALIDATE_CACHE_UDELAY(map, chip, |
1579 | cmd_adr, len, | 1579 | cmd_adr, len, |
1580 | chip->buffer_write_time); | 1580 | chip->buffer_write_time); |
1581 | 1581 | ||
@@ -1608,7 +1608,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | |||
1608 | ret = -EIO; | 1608 | ret = -EIO; |
1609 | goto out; | 1609 | goto out; |
1610 | } | 1610 | } |
1611 | 1611 | ||
1612 | /* Latency issues. Drop the lock, wait a while and retry */ | 1612 | /* Latency issues. Drop the lock, wait a while and retry */ |
1613 | z++; | 1613 | z++; |
1614 | UDELAY(map, chip, cmd_adr, 1); | 1614 | UDELAY(map, chip, cmd_adr, 1); |
@@ -1618,7 +1618,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | |||
1618 | if (!chip->buffer_write_time) | 1618 | if (!chip->buffer_write_time) |
1619 | chip->buffer_write_time = 1; | 1619 | chip->buffer_write_time = 1; |
1620 | } | 1620 | } |
1621 | if (z > 1) | 1621 | if (z > 1) |
1622 | chip->buffer_write_time++; | 1622 | chip->buffer_write_time++; |
1623 | 1623 | ||
1624 | /* Done and happy. */ | 1624 | /* Done and happy. */ |
@@ -1680,7 +1680,7 @@ static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs, | |||
1680 | 1680 | ||
1681 | if (size > len) | 1681 | if (size > len) |
1682 | size = len; | 1682 | size = len; |
1683 | ret = do_write_buffer(map, &cfi->chips[chipnum], | 1683 | ret = do_write_buffer(map, &cfi->chips[chipnum], |
1684 | ofs, &vecs, &vec_seek, size); | 1684 | ofs, &vecs, &vec_seek, size); |
1685 | if (ret) | 1685 | if (ret) |
1686 | return ret; | 1686 | return ret; |
@@ -1690,7 +1690,7 @@ static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs, | |||
1690 | len -= size; | 1690 | len -= size; |
1691 | 1691 | ||
1692 | if (ofs >> cfi->chipshift) { | 1692 | if (ofs >> cfi->chipshift) { |
1693 | chipnum ++; | 1693 | chipnum ++; |
1694 | ofs = 0; | 1694 | ofs = 0; |
1695 | if (chipnum == cfi->numchips) | 1695 | if (chipnum == cfi->numchips) |
1696 | return 0; | 1696 | return 0; |
@@ -1776,7 +1776,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, | |||
1776 | status = map_read(map, adr); | 1776 | status = map_read(map, adr); |
1777 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1777 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1778 | break; | 1778 | break; |
1779 | 1779 | ||
1780 | /* OK Still waiting */ | 1780 | /* OK Still waiting */ |
1781 | if (time_after(jiffies, timeo)) { | 1781 | if (time_after(jiffies, timeo)) { |
1782 | map_write(map, CMD(0x70), adr); | 1782 | map_write(map, CMD(0x70), adr); |
@@ -1786,7 +1786,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, | |||
1786 | ret = -EIO; | 1786 | ret = -EIO; |
1787 | goto out; | 1787 | goto out; |
1788 | } | 1788 | } |
1789 | 1789 | ||
1790 | /* Latency issues. Drop the lock, wait a while and retry */ | 1790 | /* Latency issues. Drop the lock, wait a while and retry */ |
1791 | UDELAY(map, chip, adr, 1000000/HZ); | 1791 | UDELAY(map, chip, adr, 1000000/HZ); |
1792 | } | 1792 | } |
@@ -1849,7 +1849,7 @@ int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) | |||
1849 | 1849 | ||
1850 | instr->state = MTD_ERASE_DONE; | 1850 | instr->state = MTD_ERASE_DONE; |
1851 | mtd_erase_callback(instr); | 1851 | mtd_erase_callback(instr); |
1852 | 1852 | ||
1853 | return 0; | 1853 | return 0; |
1854 | } | 1854 | } |
1855 | 1855 | ||
@@ -1870,7 +1870,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd) | |||
1870 | if (!ret) { | 1870 | if (!ret) { |
1871 | chip->oldstate = chip->state; | 1871 | chip->oldstate = chip->state; |
1872 | chip->state = FL_SYNCING; | 1872 | chip->state = FL_SYNCING; |
1873 | /* No need to wake_up() on this state change - | 1873 | /* No need to wake_up() on this state change - |
1874 | * as the whole point is that nobody can do anything | 1874 | * as the whole point is that nobody can do anything |
1875 | * with the chip now anyway. | 1875 | * with the chip now anyway. |
1876 | */ | 1876 | */ |
@@ -1884,7 +1884,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd) | |||
1884 | chip = &cfi->chips[i]; | 1884 | chip = &cfi->chips[i]; |
1885 | 1885 | ||
1886 | spin_lock(chip->mutex); | 1886 | spin_lock(chip->mutex); |
1887 | 1887 | ||
1888 | if (chip->state == FL_SYNCING) { | 1888 | if (chip->state == FL_SYNCING) { |
1889 | chip->state = chip->oldstate; | 1889 | chip->state = chip->oldstate; |
1890 | chip->oldstate = FL_READY; | 1890 | chip->oldstate = FL_READY; |
@@ -1941,7 +1941,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip | |||
1941 | 1941 | ||
1942 | ENABLE_VPP(map); | 1942 | ENABLE_VPP(map); |
1943 | xip_disable(map, chip, adr); | 1943 | xip_disable(map, chip, adr); |
1944 | 1944 | ||
1945 | map_write(map, CMD(0x60), adr); | 1945 | map_write(map, CMD(0x60), adr); |
1946 | if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) { | 1946 | if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) { |
1947 | map_write(map, CMD(0x01), adr); | 1947 | map_write(map, CMD(0x01), adr); |
@@ -1969,7 +1969,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip | |||
1969 | status = map_read(map, adr); | 1969 | status = map_read(map, adr); |
1970 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1970 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1971 | break; | 1971 | break; |
1972 | 1972 | ||
1973 | /* OK Still waiting */ | 1973 | /* OK Still waiting */ |
1974 | if (time_after(jiffies, timeo)) { | 1974 | if (time_after(jiffies, timeo)) { |
1975 | map_write(map, CMD(0x70), adr); | 1975 | map_write(map, CMD(0x70), adr); |
@@ -1980,11 +1980,11 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip | |||
1980 | spin_unlock(chip->mutex); | 1980 | spin_unlock(chip->mutex); |
1981 | return -EIO; | 1981 | return -EIO; |
1982 | } | 1982 | } |
1983 | 1983 | ||
1984 | /* Latency issues. Drop the lock, wait a while and retry */ | 1984 | /* Latency issues. Drop the lock, wait a while and retry */ |
1985 | UDELAY(map, chip, adr, 1); | 1985 | UDELAY(map, chip, adr, 1); |
1986 | } | 1986 | } |
1987 | 1987 | ||
1988 | /* Done and happy. */ | 1988 | /* Done and happy. */ |
1989 | chip->state = FL_STATUS; | 1989 | chip->state = FL_STATUS; |
1990 | xip_enable(map, chip, adr); | 1990 | xip_enable(map, chip, adr); |
@@ -2004,9 +2004,9 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
2004 | ofs, len, 0); | 2004 | ofs, len, 0); |
2005 | #endif | 2005 | #endif |
2006 | 2006 | ||
2007 | ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, | 2007 | ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, |
2008 | ofs, len, DO_XXLOCK_ONEBLOCK_LOCK); | 2008 | ofs, len, DO_XXLOCK_ONEBLOCK_LOCK); |
2009 | 2009 | ||
2010 | #ifdef DEBUG_LOCK_BITS | 2010 | #ifdef DEBUG_LOCK_BITS |
2011 | printk(KERN_DEBUG "%s: lock status after, ret=%d\n", | 2011 | printk(KERN_DEBUG "%s: lock status after, ret=%d\n", |
2012 | __FUNCTION__, ret); | 2012 | __FUNCTION__, ret); |
@@ -2030,20 +2030,20 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
2030 | 2030 | ||
2031 | ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, | 2031 | ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, |
2032 | ofs, len, DO_XXLOCK_ONEBLOCK_UNLOCK); | 2032 | ofs, len, DO_XXLOCK_ONEBLOCK_UNLOCK); |
2033 | 2033 | ||
2034 | #ifdef DEBUG_LOCK_BITS | 2034 | #ifdef DEBUG_LOCK_BITS |
2035 | printk(KERN_DEBUG "%s: lock status after, ret=%d\n", | 2035 | printk(KERN_DEBUG "%s: lock status after, ret=%d\n", |
2036 | __FUNCTION__, ret); | 2036 | __FUNCTION__, ret); |
2037 | cfi_varsize_frob(mtd, do_printlockstatus_oneblock, | 2037 | cfi_varsize_frob(mtd, do_printlockstatus_oneblock, |
2038 | ofs, len, 0); | 2038 | ofs, len, 0); |
2039 | #endif | 2039 | #endif |
2040 | 2040 | ||
2041 | return ret; | 2041 | return ret; |
2042 | } | 2042 | } |
2043 | 2043 | ||
2044 | #ifdef CONFIG_MTD_OTP | 2044 | #ifdef CONFIG_MTD_OTP |
2045 | 2045 | ||
2046 | typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip, | 2046 | typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip, |
2047 | u_long data_offset, u_char *buf, u_int size, | 2047 | u_long data_offset, u_char *buf, u_int size, |
2048 | u_long prot_offset, u_int groupno, u_int groupsize); | 2048 | u_long prot_offset, u_int groupno, u_int groupsize); |
2049 | 2049 | ||
@@ -2094,7 +2094,7 @@ do_otp_write(struct map_info *map, struct flchip *chip, u_long offset, | |||
2094 | 2094 | ||
2095 | datum = map_word_load_partial(map, datum, buf, gap, n); | 2095 | datum = map_word_load_partial(map, datum, buf, gap, n); |
2096 | ret = do_write_oneword(map, chip, bus_ofs, datum, FL_OTP_WRITE); | 2096 | ret = do_write_oneword(map, chip, bus_ofs, datum, FL_OTP_WRITE); |
2097 | if (ret) | 2097 | if (ret) |
2098 | return ret; | 2098 | return ret; |
2099 | 2099 | ||
2100 | offset += n; | 2100 | offset += n; |
@@ -2287,7 +2287,7 @@ static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd, | |||
2287 | NULL, do_otp_lock, 1); | 2287 | NULL, do_otp_lock, 1); |
2288 | } | 2288 | } |
2289 | 2289 | ||
2290 | static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd, | 2290 | static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd, |
2291 | struct otp_info *buf, size_t len) | 2291 | struct otp_info *buf, size_t len) |
2292 | { | 2292 | { |
2293 | size_t retlen; | 2293 | size_t retlen; |
@@ -2330,7 +2330,7 @@ static int cfi_intelext_suspend(struct mtd_info *mtd) | |||
2330 | if (chip->oldstate == FL_READY) { | 2330 | if (chip->oldstate == FL_READY) { |
2331 | chip->oldstate = chip->state; | 2331 | chip->oldstate = chip->state; |
2332 | chip->state = FL_PM_SUSPENDED; | 2332 | chip->state = FL_PM_SUSPENDED; |
2333 | /* No need to wake_up() on this state change - | 2333 | /* No need to wake_up() on this state change - |
2334 | * as the whole point is that nobody can do anything | 2334 | * as the whole point is that nobody can do anything |
2335 | * with the chip now anyway. | 2335 | * with the chip now anyway. |
2336 | */ | 2336 | */ |
@@ -2358,9 +2358,9 @@ static int cfi_intelext_suspend(struct mtd_info *mtd) | |||
2358 | if (ret) { | 2358 | if (ret) { |
2359 | for (i--; i >=0; i--) { | 2359 | for (i--; i >=0; i--) { |
2360 | chip = &cfi->chips[i]; | 2360 | chip = &cfi->chips[i]; |
2361 | 2361 | ||
2362 | spin_lock(chip->mutex); | 2362 | spin_lock(chip->mutex); |
2363 | 2363 | ||
2364 | if (chip->state == FL_PM_SUSPENDED) { | 2364 | if (chip->state == FL_PM_SUSPENDED) { |
2365 | /* No need to force it into a known state here, | 2365 | /* No need to force it into a known state here, |
2366 | because we're returning failure, and it didn't | 2366 | because we're returning failure, and it didn't |
@@ -2371,8 +2371,8 @@ static int cfi_intelext_suspend(struct mtd_info *mtd) | |||
2371 | } | 2371 | } |
2372 | spin_unlock(chip->mutex); | 2372 | spin_unlock(chip->mutex); |
2373 | } | 2373 | } |
2374 | } | 2374 | } |
2375 | 2375 | ||
2376 | return ret; | 2376 | return ret; |
2377 | } | 2377 | } |
2378 | 2378 | ||
@@ -2384,11 +2384,11 @@ static void cfi_intelext_resume(struct mtd_info *mtd) | |||
2384 | struct flchip *chip; | 2384 | struct flchip *chip; |
2385 | 2385 | ||
2386 | for (i=0; i<cfi->numchips; i++) { | 2386 | for (i=0; i<cfi->numchips; i++) { |
2387 | 2387 | ||
2388 | chip = &cfi->chips[i]; | 2388 | chip = &cfi->chips[i]; |
2389 | 2389 | ||
2390 | spin_lock(chip->mutex); | 2390 | spin_lock(chip->mutex); |
2391 | 2391 | ||
2392 | /* Go to known state. Chip may have been power cycled */ | 2392 | /* Go to known state. Chip may have been power cycled */ |
2393 | if (chip->state == FL_PM_SUSPENDED) { | 2393 | if (chip->state == FL_PM_SUSPENDED) { |
2394 | map_write(map, CMD(0xFF), cfi->chips[i].start); | 2394 | map_write(map, CMD(0xFF), cfi->chips[i].start); |
@@ -2410,7 +2410,7 @@ static int cfi_intelext_reset(struct mtd_info *mtd) | |||
2410 | struct flchip *chip = &cfi->chips[i]; | 2410 | struct flchip *chip = &cfi->chips[i]; |
2411 | 2411 | ||
2412 | /* force the completion of any ongoing operation | 2412 | /* force the completion of any ongoing operation |
2413 | and switch to array mode so any bootloader in | 2413 | and switch to array mode so any bootloader in |
2414 | flash is accessible for soft reboot. */ | 2414 | flash is accessible for soft reboot. */ |
2415 | spin_lock(chip->mutex); | 2415 | spin_lock(chip->mutex); |
2416 | ret = get_chip(map, chip, chip->start, FL_SYNCING); | 2416 | ret = get_chip(map, chip, chip->start, FL_SYNCING); |
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 50dd7d2f096d..88c5f5a34cb7 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c | |||
@@ -10,14 +10,14 @@ | |||
10 | * | 10 | * |
11 | * 4_by_16 work by Carolyn J. Smith | 11 | * 4_by_16 work by Carolyn J. Smith |
12 | * | 12 | * |
13 | * XIP support hooks by Vitaly Wool (based on code for Intel flash | 13 | * XIP support hooks by Vitaly Wool (based on code for Intel flash |
14 | * by Nicolas Pitre) | 14 | * by Nicolas Pitre) |
15 | * | 15 | * |
16 | * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com | 16 | * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com |
17 | * | 17 | * |
18 | * This code is GPL | 18 | * This code is GPL |
19 | * | 19 | * |
20 | * $Id: cfi_cmdset_0002.c,v 1.121 2005/11/07 09:00:01 gleixner Exp $ | 20 | * $Id: cfi_cmdset_0002.c,v 1.122 2005/11/07 11:14:22 gleixner Exp $ |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
@@ -93,7 +93,7 @@ static void cfi_tell_features(struct cfi_pri_amdstd *extp) | |||
93 | }; | 93 | }; |
94 | 94 | ||
95 | printk(" Silicon revision: %d\n", extp->SiliconRevision >> 1); | 95 | printk(" Silicon revision: %d\n", extp->SiliconRevision >> 1); |
96 | printk(" Address sensitive unlock: %s\n", | 96 | printk(" Address sensitive unlock: %s\n", |
97 | (extp->SiliconRevision & 1) ? "Not required" : "Required"); | 97 | (extp->SiliconRevision & 1) ? "Not required" : "Required"); |
98 | 98 | ||
99 | if (extp->EraseSuspend < ARRAY_SIZE(erase_suspend)) | 99 | if (extp->EraseSuspend < ARRAY_SIZE(erase_suspend)) |
@@ -118,9 +118,9 @@ static void cfi_tell_features(struct cfi_pri_amdstd *extp) | |||
118 | else | 118 | else |
119 | printk(" Page mode: %d word page\n", extp->PageMode << 2); | 119 | printk(" Page mode: %d word page\n", extp->PageMode << 2); |
120 | 120 | ||
121 | printk(" Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n", | 121 | printk(" Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n", |
122 | extp->VppMin >> 4, extp->VppMin & 0xf); | 122 | extp->VppMin >> 4, extp->VppMin & 0xf); |
123 | printk(" Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n", | 123 | printk(" Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n", |
124 | extp->VppMax >> 4, extp->VppMax & 0xf); | 124 | extp->VppMax >> 4, extp->VppMax & 0xf); |
125 | 125 | ||
126 | if (extp->TopBottom < ARRAY_SIZE(top_bottom)) | 126 | if (extp->TopBottom < ARRAY_SIZE(top_bottom)) |
@@ -177,7 +177,7 @@ static void fixup_use_erase_chip(struct mtd_info *mtd, void *param) | |||
177 | ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0)) { | 177 | ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0)) { |
178 | mtd->erase = cfi_amdstd_erase_chip; | 178 | mtd->erase = cfi_amdstd_erase_chip; |
179 | } | 179 | } |
180 | 180 | ||
181 | } | 181 | } |
182 | 182 | ||
183 | static struct cfi_fixup cfi_fixup_table[] = { | 183 | static struct cfi_fixup cfi_fixup_table[] = { |
@@ -239,7 +239,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) | |||
239 | 239 | ||
240 | if (cfi->cfi_mode==CFI_MODE_CFI){ | 240 | if (cfi->cfi_mode==CFI_MODE_CFI){ |
241 | unsigned char bootloc; | 241 | unsigned char bootloc; |
242 | /* | 242 | /* |
243 | * It's a real CFI chip, not one for which the probe | 243 | * It's a real CFI chip, not one for which the probe |
244 | * routine faked a CFI structure. So we read the feature | 244 | * routine faked a CFI structure. So we read the feature |
245 | * table from it. | 245 | * table from it. |
@@ -264,7 +264,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) | |||
264 | } | 264 | } |
265 | 265 | ||
266 | /* Install our own private info structure */ | 266 | /* Install our own private info structure */ |
267 | cfi->cmdset_priv = extp; | 267 | cfi->cmdset_priv = extp; |
268 | 268 | ||
269 | /* Apply cfi device specific fixups */ | 269 | /* Apply cfi device specific fixups */ |
270 | cfi_fixup(mtd, cfi_fixup_table); | 270 | cfi_fixup(mtd, cfi_fixup_table); |
@@ -272,7 +272,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) | |||
272 | #ifdef DEBUG_CFI_FEATURES | 272 | #ifdef DEBUG_CFI_FEATURES |
273 | /* Tell the user about it in lots of lovely detail */ | 273 | /* Tell the user about it in lots of lovely detail */ |
274 | cfi_tell_features(extp); | 274 | cfi_tell_features(extp); |
275 | #endif | 275 | #endif |
276 | 276 | ||
277 | bootloc = extp->TopBottom; | 277 | bootloc = extp->TopBottom; |
278 | if ((bootloc != 2) && (bootloc != 3)) { | 278 | if ((bootloc != 2) && (bootloc != 3)) { |
@@ -283,11 +283,11 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) | |||
283 | 283 | ||
284 | if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) { | 284 | if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) { |
285 | printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name); | 285 | printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name); |
286 | 286 | ||
287 | for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) { | 287 | for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) { |
288 | int j = (cfi->cfiq->NumEraseRegions-1)-i; | 288 | int j = (cfi->cfiq->NumEraseRegions-1)-i; |
289 | __u32 swap; | 289 | __u32 swap; |
290 | 290 | ||
291 | swap = cfi->cfiq->EraseRegionInfo[i]; | 291 | swap = cfi->cfiq->EraseRegionInfo[i]; |
292 | cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j]; | 292 | cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j]; |
293 | cfi->cfiq->EraseRegionInfo[j] = swap; | 293 | cfi->cfiq->EraseRegionInfo[j] = swap; |
@@ -298,11 +298,11 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) | |||
298 | cfi->addr_unlock2 = 0x2aa; | 298 | cfi->addr_unlock2 = 0x2aa; |
299 | /* Modify the unlock address if we are in compatibility mode */ | 299 | /* Modify the unlock address if we are in compatibility mode */ |
300 | if ( /* x16 in x8 mode */ | 300 | if ( /* x16 in x8 mode */ |
301 | ((cfi->device_type == CFI_DEVICETYPE_X8) && | 301 | ((cfi->device_type == CFI_DEVICETYPE_X8) && |
302 | (cfi->cfiq->InterfaceDesc == 2)) || | 302 | (cfi->cfiq->InterfaceDesc == 2)) || |
303 | /* x32 in x16 mode */ | 303 | /* x32 in x16 mode */ |
304 | ((cfi->device_type == CFI_DEVICETYPE_X16) && | 304 | ((cfi->device_type == CFI_DEVICETYPE_X16) && |
305 | (cfi->cfiq->InterfaceDesc == 4))) | 305 | (cfi->cfiq->InterfaceDesc == 4))) |
306 | { | 306 | { |
307 | cfi->addr_unlock1 = 0xaaa; | 307 | cfi->addr_unlock1 = 0xaaa; |
308 | cfi->addr_unlock2 = 0x555; | 308 | cfi->addr_unlock2 = 0x555; |
@@ -320,10 +320,10 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) | |||
320 | cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp; | 320 | cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp; |
321 | cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; | 321 | cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; |
322 | cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp; | 322 | cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp; |
323 | } | 323 | } |
324 | 324 | ||
325 | map->fldrv = &cfi_amdstd_chipdrv; | 325 | map->fldrv = &cfi_amdstd_chipdrv; |
326 | 326 | ||
327 | return cfi_amdstd_setup(mtd); | 327 | return cfi_amdstd_setup(mtd); |
328 | } | 328 | } |
329 | 329 | ||
@@ -336,24 +336,24 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd) | |||
336 | unsigned long offset = 0; | 336 | unsigned long offset = 0; |
337 | int i,j; | 337 | int i,j; |
338 | 338 | ||
339 | printk(KERN_NOTICE "number of %s chips: %d\n", | 339 | printk(KERN_NOTICE "number of %s chips: %d\n", |
340 | (cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips); | 340 | (cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips); |
341 | /* Select the correct geometry setup */ | 341 | /* Select the correct geometry setup */ |
342 | mtd->size = devsize * cfi->numchips; | 342 | mtd->size = devsize * cfi->numchips; |
343 | 343 | ||
344 | mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; | 344 | mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; |
345 | mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) | 345 | mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) |
346 | * mtd->numeraseregions, GFP_KERNEL); | 346 | * mtd->numeraseregions, GFP_KERNEL); |
347 | if (!mtd->eraseregions) { | 347 | if (!mtd->eraseregions) { |
348 | printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n"); | 348 | printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n"); |
349 | goto setup_err; | 349 | goto setup_err; |
350 | } | 350 | } |
351 | 351 | ||
352 | for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { | 352 | for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { |
353 | unsigned long ernum, ersize; | 353 | unsigned long ernum, ersize; |
354 | ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; | 354 | ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; |
355 | ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1; | 355 | ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1; |
356 | 356 | ||
357 | if (mtd->erasesize < ersize) { | 357 | if (mtd->erasesize < ersize) { |
358 | mtd->erasesize = ersize; | 358 | mtd->erasesize = ersize; |
359 | } | 359 | } |
@@ -440,7 +440,7 @@ static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word | |||
440 | oldd = map_read(map, addr); | 440 | oldd = map_read(map, addr); |
441 | curd = map_read(map, addr); | 441 | curd = map_read(map, addr); |
442 | 442 | ||
443 | return map_word_equal(map, oldd, curd) && | 443 | return map_word_equal(map, oldd, curd) && |
444 | map_word_equal(map, curd, expected); | 444 | map_word_equal(map, curd, expected); |
445 | } | 445 | } |
446 | 446 | ||
@@ -472,7 +472,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr | |||
472 | /* Someone else might have been playing with it. */ | 472 | /* Someone else might have been playing with it. */ |
473 | goto retry; | 473 | goto retry; |
474 | } | 474 | } |
475 | 475 | ||
476 | case FL_READY: | 476 | case FL_READY: |
477 | case FL_CFI_QUERY: | 477 | case FL_CFI_QUERY: |
478 | case FL_JEDEC_QUERY: | 478 | case FL_JEDEC_QUERY: |
@@ -515,7 +515,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr | |||
515 | printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__); | 515 | printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__); |
516 | return -EIO; | 516 | return -EIO; |
517 | } | 517 | } |
518 | 518 | ||
519 | spin_unlock(chip->mutex); | 519 | spin_unlock(chip->mutex); |
520 | cfi_udelay(1); | 520 | cfi_udelay(1); |
521 | spin_lock(chip->mutex); | 521 | spin_lock(chip->mutex); |
@@ -618,7 +618,7 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip, | |||
618 | * When a delay is required for the flash operation to complete, the | 618 | * When a delay is required for the flash operation to complete, the |
619 | * xip_udelay() function is polling for both the given timeout and pending | 619 | * xip_udelay() function is polling for both the given timeout and pending |
620 | * (but still masked) hardware interrupts. Whenever there is an interrupt | 620 | * (but still masked) hardware interrupts. Whenever there is an interrupt |
621 | * pending then the flash erase operation is suspended, array mode restored | 621 | * pending then the flash erase operation is suspended, array mode restored |
622 | * and interrupts unmasked. Task scheduling might also happen at that | 622 | * and interrupts unmasked. Task scheduling might also happen at that |
623 | * point. The CPU eventually returns from the interrupt or the call to | 623 | * point. The CPU eventually returns from the interrupt or the call to |
624 | * schedule() and the suspended flash operation is resumed for the remaining | 624 | * schedule() and the suspended flash operation is resumed for the remaining |
@@ -642,9 +642,9 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip, | |||
642 | ((chip->state == FL_ERASING && (extp->EraseSuspend & 2))) && | 642 | ((chip->state == FL_ERASING && (extp->EraseSuspend & 2))) && |
643 | (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) { | 643 | (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) { |
644 | /* | 644 | /* |
645 | * Let's suspend the erase operation when supported. | 645 | * Let's suspend the erase operation when supported. |
646 | * Note that we currently don't try to suspend | 646 | * Note that we currently don't try to suspend |
647 | * interleaved chips if there is already another | 647 | * interleaved chips if there is already another |
648 | * operation suspended (imagine what happens | 648 | * operation suspended (imagine what happens |
649 | * when one chip was already done with the current | 649 | * when one chip was already done with the current |
650 | * operation while another chip suspended it, then | 650 | * operation while another chip suspended it, then |
@@ -780,8 +780,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof | |||
780 | 780 | ||
781 | adr += chip->start; | 781 | adr += chip->start; |
782 | 782 | ||
783 | /* Ensure cmd read/writes are aligned. */ | 783 | /* Ensure cmd read/writes are aligned. */ |
784 | cmd_addr = adr & ~(map_bankwidth(map)-1); | 784 | cmd_addr = adr & ~(map_bankwidth(map)-1); |
785 | 785 | ||
786 | spin_lock(chip->mutex); | 786 | spin_lock(chip->mutex); |
787 | ret = get_chip(map, chip, cmd_addr, FL_READY); | 787 | ret = get_chip(map, chip, cmd_addr, FL_READY); |
@@ -861,7 +861,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi | |||
861 | #endif | 861 | #endif |
862 | set_current_state(TASK_UNINTERRUPTIBLE); | 862 | set_current_state(TASK_UNINTERRUPTIBLE); |
863 | add_wait_queue(&chip->wq, &wait); | 863 | add_wait_queue(&chip->wq, &wait); |
864 | 864 | ||
865 | spin_unlock(chip->mutex); | 865 | spin_unlock(chip->mutex); |
866 | 866 | ||
867 | schedule(); | 867 | schedule(); |
@@ -873,7 +873,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi | |||
873 | timeo = jiffies + HZ; | 873 | timeo = jiffies + HZ; |
874 | 874 | ||
875 | goto retry; | 875 | goto retry; |
876 | } | 876 | } |
877 | 877 | ||
878 | adr += chip->start; | 878 | adr += chip->start; |
879 | 879 | ||
@@ -882,14 +882,14 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi | |||
882 | cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); | 882 | cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); |
883 | cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); | 883 | cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); |
884 | cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); | 884 | cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); |
885 | 885 | ||
886 | map_copy_from(map, buf, adr, len); | 886 | map_copy_from(map, buf, adr, len); |
887 | 887 | ||
888 | cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); | 888 | cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); |
889 | cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); | 889 | cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); |
890 | cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); | 890 | cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); |
891 | cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); | 891 | cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); |
892 | 892 | ||
893 | wake_up(&chip->wq); | 893 | wake_up(&chip->wq); |
894 | spin_unlock(chip->mutex); | 894 | spin_unlock(chip->mutex); |
895 | 895 | ||
@@ -998,7 +998,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, | |||
998 | chip->word_write_time); | 998 | chip->word_write_time); |
999 | 999 | ||
1000 | /* See comment above for timeout value. */ | 1000 | /* See comment above for timeout value. */ |
1001 | timeo = jiffies + uWriteTimeout; | 1001 | timeo = jiffies + uWriteTimeout; |
1002 | for (;;) { | 1002 | for (;;) { |
1003 | if (chip->state != FL_WRITING) { | 1003 | if (chip->state != FL_WRITING) { |
1004 | /* Someone's suspended the write. Sleep */ | 1004 | /* Someone's suspended the write. Sleep */ |
@@ -1033,7 +1033,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, | |||
1033 | map_write( map, CMD(0xF0), chip->start ); | 1033 | map_write( map, CMD(0xF0), chip->start ); |
1034 | /* FIXME - should have reset delay before continuing */ | 1034 | /* FIXME - should have reset delay before continuing */ |
1035 | 1035 | ||
1036 | if (++retry_cnt <= MAX_WORD_RETRIES) | 1036 | if (++retry_cnt <= MAX_WORD_RETRIES) |
1037 | goto retry; | 1037 | goto retry; |
1038 | 1038 | ||
1039 | ret = -EIO; | 1039 | ret = -EIO; |
@@ -1101,27 +1101,27 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len, | |||
1101 | 1101 | ||
1102 | /* Number of bytes to copy from buffer */ | 1102 | /* Number of bytes to copy from buffer */ |
1103 | n = min_t(int, len, map_bankwidth(map)-i); | 1103 | n = min_t(int, len, map_bankwidth(map)-i); |
1104 | 1104 | ||
1105 | tmp_buf = map_word_load_partial(map, tmp_buf, buf, i, n); | 1105 | tmp_buf = map_word_load_partial(map, tmp_buf, buf, i, n); |
1106 | 1106 | ||
1107 | ret = do_write_oneword(map, &cfi->chips[chipnum], | 1107 | ret = do_write_oneword(map, &cfi->chips[chipnum], |
1108 | bus_ofs, tmp_buf); | 1108 | bus_ofs, tmp_buf); |
1109 | if (ret) | 1109 | if (ret) |
1110 | return ret; | 1110 | return ret; |
1111 | 1111 | ||
1112 | ofs += n; | 1112 | ofs += n; |
1113 | buf += n; | 1113 | buf += n; |
1114 | (*retlen) += n; | 1114 | (*retlen) += n; |
1115 | len -= n; | 1115 | len -= n; |
1116 | 1116 | ||
1117 | if (ofs >> cfi->chipshift) { | 1117 | if (ofs >> cfi->chipshift) { |
1118 | chipnum ++; | 1118 | chipnum ++; |
1119 | ofs = 0; | 1119 | ofs = 0; |
1120 | if (chipnum == cfi->numchips) | 1120 | if (chipnum == cfi->numchips) |
1121 | return 0; | 1121 | return 0; |
1122 | } | 1122 | } |
1123 | } | 1123 | } |
1124 | 1124 | ||
1125 | /* We are now aligned, write as much as possible */ | 1125 | /* We are now aligned, write as much as possible */ |
1126 | while(len >= map_bankwidth(map)) { | 1126 | while(len >= map_bankwidth(map)) { |
1127 | map_word datum; | 1127 | map_word datum; |
@@ -1139,7 +1139,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len, | |||
1139 | len -= map_bankwidth(map); | 1139 | len -= map_bankwidth(map); |
1140 | 1140 | ||
1141 | if (ofs >> cfi->chipshift) { | 1141 | if (ofs >> cfi->chipshift) { |
1142 | chipnum ++; | 1142 | chipnum ++; |
1143 | ofs = 0; | 1143 | ofs = 0; |
1144 | if (chipnum == cfi->numchips) | 1144 | if (chipnum == cfi->numchips) |
1145 | return 0; | 1145 | return 0; |
@@ -1177,12 +1177,12 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len, | |||
1177 | spin_unlock(cfi->chips[chipnum].mutex); | 1177 | spin_unlock(cfi->chips[chipnum].mutex); |
1178 | 1178 | ||
1179 | tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len); | 1179 | tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len); |
1180 | 1180 | ||
1181 | ret = do_write_oneword(map, &cfi->chips[chipnum], | 1181 | ret = do_write_oneword(map, &cfi->chips[chipnum], |
1182 | ofs, tmp_buf); | 1182 | ofs, tmp_buf); |
1183 | if (ret) | 1183 | if (ret) |
1184 | return ret; | 1184 | return ret; |
1185 | 1185 | ||
1186 | (*retlen) += len; | 1186 | (*retlen) += len; |
1187 | } | 1187 | } |
1188 | 1188 | ||
@@ -1194,7 +1194,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len, | |||
1194 | * FIXME: interleaved mode not tested, and probably not supported! | 1194 | * FIXME: interleaved mode not tested, and probably not supported! |
1195 | */ | 1195 | */ |
1196 | static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | 1196 | static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, |
1197 | unsigned long adr, const u_char *buf, | 1197 | unsigned long adr, const u_char *buf, |
1198 | int len) | 1198 | int len) |
1199 | { | 1199 | { |
1200 | struct cfi_private *cfi = map->fldrv_priv; | 1200 | struct cfi_private *cfi = map->fldrv_priv; |
@@ -1224,7 +1224,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | |||
1224 | XIP_INVAL_CACHED_RANGE(map, adr, len); | 1224 | XIP_INVAL_CACHED_RANGE(map, adr, len); |
1225 | ENABLE_VPP(map); | 1225 | ENABLE_VPP(map); |
1226 | xip_disable(map, chip, cmd_adr); | 1226 | xip_disable(map, chip, cmd_adr); |
1227 | 1227 | ||
1228 | cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); | 1228 | cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); |
1229 | cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); | 1229 | cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); |
1230 | //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); | 1230 | //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); |
@@ -1258,8 +1258,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | |||
1258 | adr, map_bankwidth(map), | 1258 | adr, map_bankwidth(map), |
1259 | chip->word_write_time); | 1259 | chip->word_write_time); |
1260 | 1260 | ||
1261 | timeo = jiffies + uWriteTimeout; | 1261 | timeo = jiffies + uWriteTimeout; |
1262 | 1262 | ||
1263 | for (;;) { | 1263 | for (;;) { |
1264 | if (chip->state != FL_WRITING) { | 1264 | if (chip->state != FL_WRITING) { |
1265 | /* Someone's suspended the write. Sleep */ | 1265 | /* Someone's suspended the write. Sleep */ |
@@ -1353,7 +1353,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, | |||
1353 | if (size % map_bankwidth(map)) | 1353 | if (size % map_bankwidth(map)) |
1354 | size -= size % map_bankwidth(map); | 1354 | size -= size % map_bankwidth(map); |
1355 | 1355 | ||
1356 | ret = do_write_buffer(map, &cfi->chips[chipnum], | 1356 | ret = do_write_buffer(map, &cfi->chips[chipnum], |
1357 | ofs, buf, size); | 1357 | ofs, buf, size); |
1358 | if (ret) | 1358 | if (ret) |
1359 | return ret; | 1359 | return ret; |
@@ -1364,7 +1364,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, | |||
1364 | len -= size; | 1364 | len -= size; |
1365 | 1365 | ||
1366 | if (ofs >> cfi->chipshift) { | 1366 | if (ofs >> cfi->chipshift) { |
1367 | chipnum ++; | 1367 | chipnum ++; |
1368 | ofs = 0; | 1368 | ofs = 0; |
1369 | if (chipnum == cfi->numchips) | 1369 | if (chipnum == cfi->numchips) |
1370 | return 0; | 1370 | return 0; |
@@ -1581,7 +1581,7 @@ int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) | |||
1581 | 1581 | ||
1582 | instr->state = MTD_ERASE_DONE; | 1582 | instr->state = MTD_ERASE_DONE; |
1583 | mtd_erase_callback(instr); | 1583 | mtd_erase_callback(instr); |
1584 | 1584 | ||
1585 | return 0; | 1585 | return 0; |
1586 | } | 1586 | } |
1587 | 1587 | ||
@@ -1604,7 +1604,7 @@ static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr) | |||
1604 | 1604 | ||
1605 | instr->state = MTD_ERASE_DONE; | 1605 | instr->state = MTD_ERASE_DONE; |
1606 | mtd_erase_callback(instr); | 1606 | mtd_erase_callback(instr); |
1607 | 1607 | ||
1608 | return 0; | 1608 | return 0; |
1609 | } | 1609 | } |
1610 | 1610 | ||
@@ -1631,7 +1631,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd) | |||
1631 | case FL_JEDEC_QUERY: | 1631 | case FL_JEDEC_QUERY: |
1632 | chip->oldstate = chip->state; | 1632 | chip->oldstate = chip->state; |
1633 | chip->state = FL_SYNCING; | 1633 | chip->state = FL_SYNCING; |
1634 | /* No need to wake_up() on this state change - | 1634 | /* No need to wake_up() on this state change - |
1635 | * as the whole point is that nobody can do anything | 1635 | * as the whole point is that nobody can do anything |
1636 | * with the chip now anyway. | 1636 | * with the chip now anyway. |
1637 | */ | 1637 | */ |
@@ -1642,13 +1642,13 @@ static void cfi_amdstd_sync (struct mtd_info *mtd) | |||
1642 | default: | 1642 | default: |
1643 | /* Not an idle state */ | 1643 | /* Not an idle state */ |
1644 | add_wait_queue(&chip->wq, &wait); | 1644 | add_wait_queue(&chip->wq, &wait); |
1645 | 1645 | ||
1646 | spin_unlock(chip->mutex); | 1646 | spin_unlock(chip->mutex); |
1647 | 1647 | ||
1648 | schedule(); | 1648 | schedule(); |
1649 | 1649 | ||
1650 | remove_wait_queue(&chip->wq, &wait); | 1650 | remove_wait_queue(&chip->wq, &wait); |
1651 | 1651 | ||
1652 | goto retry; | 1652 | goto retry; |
1653 | } | 1653 | } |
1654 | } | 1654 | } |
@@ -1659,7 +1659,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd) | |||
1659 | chip = &cfi->chips[i]; | 1659 | chip = &cfi->chips[i]; |
1660 | 1660 | ||
1661 | spin_lock(chip->mutex); | 1661 | spin_lock(chip->mutex); |
1662 | 1662 | ||
1663 | if (chip->state == FL_SYNCING) { | 1663 | if (chip->state == FL_SYNCING) { |
1664 | chip->state = chip->oldstate; | 1664 | chip->state = chip->oldstate; |
1665 | wake_up(&chip->wq); | 1665 | wake_up(&chip->wq); |
@@ -1689,7 +1689,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd) | |||
1689 | case FL_JEDEC_QUERY: | 1689 | case FL_JEDEC_QUERY: |
1690 | chip->oldstate = chip->state; | 1690 | chip->oldstate = chip->state; |
1691 | chip->state = FL_PM_SUSPENDED; | 1691 | chip->state = FL_PM_SUSPENDED; |
1692 | /* No need to wake_up() on this state change - | 1692 | /* No need to wake_up() on this state change - |
1693 | * as the whole point is that nobody can do anything | 1693 | * as the whole point is that nobody can do anything |
1694 | * with the chip now anyway. | 1694 | * with the chip now anyway. |
1695 | */ | 1695 | */ |
@@ -1710,7 +1710,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd) | |||
1710 | chip = &cfi->chips[i]; | 1710 | chip = &cfi->chips[i]; |
1711 | 1711 | ||
1712 | spin_lock(chip->mutex); | 1712 | spin_lock(chip->mutex); |
1713 | 1713 | ||
1714 | if (chip->state == FL_PM_SUSPENDED) { | 1714 | if (chip->state == FL_PM_SUSPENDED) { |
1715 | chip->state = chip->oldstate; | 1715 | chip->state = chip->oldstate; |
1716 | wake_up(&chip->wq); | 1716 | wake_up(&chip->wq); |
@@ -1718,7 +1718,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd) | |||
1718 | spin_unlock(chip->mutex); | 1718 | spin_unlock(chip->mutex); |
1719 | } | 1719 | } |
1720 | } | 1720 | } |
1721 | 1721 | ||
1722 | return ret; | 1722 | return ret; |
1723 | } | 1723 | } |
1724 | 1724 | ||
@@ -1731,11 +1731,11 @@ static void cfi_amdstd_resume(struct mtd_info *mtd) | |||
1731 | struct flchip *chip; | 1731 | struct flchip *chip; |
1732 | 1732 | ||
1733 | for (i=0; i<cfi->numchips; i++) { | 1733 | for (i=0; i<cfi->numchips; i++) { |
1734 | 1734 | ||
1735 | chip = &cfi->chips[i]; | 1735 | chip = &cfi->chips[i]; |
1736 | 1736 | ||
1737 | spin_lock(chip->mutex); | 1737 | spin_lock(chip->mutex); |
1738 | 1738 | ||
1739 | if (chip->state == FL_PM_SUSPENDED) { | 1739 | if (chip->state == FL_PM_SUSPENDED) { |
1740 | chip->state = FL_READY; | 1740 | chip->state = FL_READY; |
1741 | map_write(map, CMD(0xF0), chip->start); | 1741 | map_write(map, CMD(0xF0), chip->start); |
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c index d22df2d96788..39e3c2d9441f 100644 --- a/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/drivers/mtd/chips/cfi_cmdset_0020.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_0020.c,v 1.20 2005/07/20 21:01:14 tpoynor Exp $ | 7 | * $Id: cfi_cmdset_0020.c,v 1.22 2005/11/07 11:14:22 gleixner Exp $ |
8 | * | 8 | * |
9 | * 10/10/2000 Nicolas Pitre <nico@cam.org> | 9 | * 10/10/2000 Nicolas Pitre <nico@cam.org> |
10 | * - completely revamped method functions so they are aware and | 10 | * - completely revamped method functions so they are aware and |
@@ -81,17 +81,17 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp) | |||
81 | printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); | 81 | printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); |
82 | printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); | 82 | printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); |
83 | for (i=9; i<32; i++) { | 83 | for (i=9; i<32; i++) { |
84 | if (extp->FeatureSupport & (1<<i)) | 84 | if (extp->FeatureSupport & (1<<i)) |
85 | printk(" - Unknown Bit %X: supported\n", i); | 85 | printk(" - Unknown Bit %X: supported\n", i); |
86 | } | 86 | } |
87 | 87 | ||
88 | printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); | 88 | printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); |
89 | printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported"); | 89 | printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported"); |
90 | for (i=1; i<8; i++) { | 90 | for (i=1; i<8; i++) { |
91 | if (extp->SuspendCmdSupport & (1<<i)) | 91 | if (extp->SuspendCmdSupport & (1<<i)) |
92 | printk(" - Unknown Bit %X: supported\n", i); | 92 | printk(" - Unknown Bit %X: supported\n", i); |
93 | } | 93 | } |
94 | 94 | ||
95 | printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); | 95 | printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); |
96 | printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); | 96 | printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); |
97 | printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); | 97 | printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); |
@@ -99,11 +99,11 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp) | |||
99 | if (extp->BlkStatusRegMask & (1<<i)) | 99 | if (extp->BlkStatusRegMask & (1<<i)) |
100 | printk(" - Unknown Bit %X Active: yes\n",i); | 100 | printk(" - Unknown Bit %X Active: yes\n",i); |
101 | } | 101 | } |
102 | 102 | ||
103 | printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", | 103 | printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", |
104 | extp->VccOptimal >> 8, extp->VccOptimal & 0xf); | 104 | extp->VccOptimal >> 8, extp->VccOptimal & 0xf); |
105 | if (extp->VppOptimal) | 105 | if (extp->VppOptimal) |
106 | printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", | 106 | printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", |
107 | extp->VppOptimal >> 8, extp->VppOptimal & 0xf); | 107 | extp->VppOptimal >> 8, extp->VppOptimal & 0xf); |
108 | } | 108 | } |
109 | #endif | 109 | #endif |
@@ -121,7 +121,7 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary) | |||
121 | int i; | 121 | int i; |
122 | 122 | ||
123 | if (cfi->cfi_mode) { | 123 | if (cfi->cfi_mode) { |
124 | /* | 124 | /* |
125 | * It's a real CFI chip, not one for which the probe | 125 | * It's a real CFI chip, not one for which the probe |
126 | * routine faked a CFI structure. So we read the feature | 126 | * routine faked a CFI structure. So we read the feature |
127 | * table from it. | 127 | * table from it. |
@@ -145,21 +145,21 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary) | |||
145 | /* Do some byteswapping if necessary */ | 145 | /* Do some byteswapping if necessary */ |
146 | extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport); | 146 | extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport); |
147 | extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask); | 147 | extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask); |
148 | 148 | ||
149 | #ifdef DEBUG_CFI_FEATURES | 149 | #ifdef DEBUG_CFI_FEATURES |
150 | /* Tell the user about it in lots of lovely detail */ | 150 | /* Tell the user about it in lots of lovely detail */ |
151 | cfi_tell_features(extp); | 151 | cfi_tell_features(extp); |
152 | #endif | 152 | #endif |
153 | 153 | ||
154 | /* Install our own private info structure */ | 154 | /* Install our own private info structure */ |
155 | cfi->cmdset_priv = extp; | 155 | cfi->cmdset_priv = extp; |
156 | } | 156 | } |
157 | 157 | ||
158 | for (i=0; i< cfi->numchips; i++) { | 158 | for (i=0; i< cfi->numchips; i++) { |
159 | cfi->chips[i].word_write_time = 128; | 159 | cfi->chips[i].word_write_time = 128; |
160 | cfi->chips[i].buffer_write_time = 128; | 160 | cfi->chips[i].buffer_write_time = 128; |
161 | cfi->chips[i].erase_time = 1024; | 161 | cfi->chips[i].erase_time = 1024; |
162 | } | 162 | } |
163 | 163 | ||
164 | return cfi_staa_setup(map); | 164 | return cfi_staa_setup(map); |
165 | } | 165 | } |
@@ -187,15 +187,15 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map) | |||
187 | mtd->size = devsize * cfi->numchips; | 187 | mtd->size = devsize * cfi->numchips; |
188 | 188 | ||
189 | mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; | 189 | mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; |
190 | mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) | 190 | mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) |
191 | * mtd->numeraseregions, GFP_KERNEL); | 191 | * mtd->numeraseregions, GFP_KERNEL); |
192 | if (!mtd->eraseregions) { | 192 | if (!mtd->eraseregions) { |
193 | printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); | 193 | printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); |
194 | kfree(cfi->cmdset_priv); | 194 | kfree(cfi->cmdset_priv); |
195 | kfree(mtd); | 195 | kfree(mtd); |
196 | return NULL; | 196 | return NULL; |
197 | } | 197 | } |
198 | 198 | ||
199 | for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { | 199 | for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { |
200 | unsigned long ernum, ersize; | 200 | unsigned long ernum, ersize; |
201 | ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; | 201 | ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; |
@@ -228,7 +228,7 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map) | |||
228 | mtd->eraseregions[i].numblocks); | 228 | mtd->eraseregions[i].numblocks); |
229 | } | 229 | } |
230 | 230 | ||
231 | /* Also select the correct geometry setup too */ | 231 | /* Also select the correct geometry setup too */ |
232 | mtd->erase = cfi_staa_erase_varsize; | 232 | mtd->erase = cfi_staa_erase_varsize; |
233 | mtd->read = cfi_staa_read; | 233 | mtd->read = cfi_staa_read; |
234 | mtd->write = cfi_staa_write_buffers; | 234 | mtd->write = cfi_staa_write_buffers; |
@@ -259,8 +259,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof | |||
259 | 259 | ||
260 | adr += chip->start; | 260 | adr += chip->start; |
261 | 261 | ||
262 | /* Ensure cmd read/writes are aligned. */ | 262 | /* Ensure cmd read/writes are aligned. */ |
263 | cmd_addr = adr & ~(map_bankwidth(map)-1); | 263 | cmd_addr = adr & ~(map_bankwidth(map)-1); |
264 | 264 | ||
265 | /* Let's determine this according to the interleave only once */ | 265 | /* Let's determine this according to the interleave only once */ |
266 | status_OK = CMD(0x80); | 266 | status_OK = CMD(0x80); |
@@ -276,7 +276,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof | |||
276 | case FL_ERASING: | 276 | case FL_ERASING: |
277 | if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)) | 277 | if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)) |
278 | goto sleep; /* We don't support erase suspend */ | 278 | goto sleep; /* We don't support erase suspend */ |
279 | 279 | ||
280 | map_write (map, CMD(0xb0), cmd_addr); | 280 | map_write (map, CMD(0xb0), cmd_addr); |
281 | /* If the flash has finished erasing, then 'erase suspend' | 281 | /* If the flash has finished erasing, then 'erase suspend' |
282 | * appears to make some (28F320) flash devices switch to | 282 | * appears to make some (28F320) flash devices switch to |
@@ -291,7 +291,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof | |||
291 | status = map_read(map, cmd_addr); | 291 | status = map_read(map, cmd_addr); |
292 | if (map_word_andequal(map, status, status_OK, status_OK)) | 292 | if (map_word_andequal(map, status, status_OK, status_OK)) |
293 | break; | 293 | break; |
294 | 294 | ||
295 | if (time_after(jiffies, timeo)) { | 295 | if (time_after(jiffies, timeo)) { |
296 | /* Urgh */ | 296 | /* Urgh */ |
297 | map_write(map, CMD(0xd0), cmd_addr); | 297 | map_write(map, CMD(0xd0), cmd_addr); |
@@ -303,17 +303,17 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof | |||
303 | "suspended: status = 0x%lx\n", status.x[0]); | 303 | "suspended: status = 0x%lx\n", status.x[0]); |
304 | return -EIO; | 304 | return -EIO; |
305 | } | 305 | } |
306 | 306 | ||
307 | spin_unlock_bh(chip->mutex); | 307 | spin_unlock_bh(chip->mutex); |
308 | cfi_udelay(1); | 308 | cfi_udelay(1); |
309 | spin_lock_bh(chip->mutex); | 309 | spin_lock_bh(chip->mutex); |
310 | } | 310 | } |
311 | 311 | ||
312 | suspended = 1; | 312 | suspended = 1; |
313 | map_write(map, CMD(0xff), cmd_addr); | 313 | map_write(map, CMD(0xff), cmd_addr); |
314 | chip->state = FL_READY; | 314 | chip->state = FL_READY; |
315 | break; | 315 | break; |
316 | 316 | ||
317 | #if 0 | 317 | #if 0 |
318 | case FL_WRITING: | 318 | case FL_WRITING: |
319 | /* Not quite yet */ | 319 | /* Not quite yet */ |
@@ -334,7 +334,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof | |||
334 | chip->state = FL_READY; | 334 | chip->state = FL_READY; |
335 | break; | 335 | break; |
336 | } | 336 | } |
337 | 337 | ||
338 | /* Urgh. Chip not yet ready to talk to us. */ | 338 | /* Urgh. Chip not yet ready to talk to us. */ |
339 | if (time_after(jiffies, timeo)) { | 339 | if (time_after(jiffies, timeo)) { |
340 | spin_unlock_bh(chip->mutex); | 340 | spin_unlock_bh(chip->mutex); |
@@ -364,17 +364,17 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof | |||
364 | 364 | ||
365 | if (suspended) { | 365 | if (suspended) { |
366 | chip->state = chip->oldstate; | 366 | chip->state = chip->oldstate; |
367 | /* What if one interleaved chip has finished and the | 367 | /* What if one interleaved chip has finished and the |
368 | other hasn't? The old code would leave the finished | 368 | other hasn't? The old code would leave the finished |
369 | one in READY mode. That's bad, and caused -EROFS | 369 | one in READY mode. That's bad, and caused -EROFS |
370 | errors to be returned from do_erase_oneblock because | 370 | errors to be returned from do_erase_oneblock because |
371 | that's the only bit it checked for at the time. | 371 | that's the only bit it checked for at the time. |
372 | As the state machine appears to explicitly allow | 372 | As the state machine appears to explicitly allow |
373 | sending the 0x70 (Read Status) command to an erasing | 373 | sending the 0x70 (Read Status) command to an erasing |
374 | chip and expecting it to be ignored, that's what we | 374 | chip and expecting it to be ignored, that's what we |
375 | do. */ | 375 | do. */ |
376 | map_write(map, CMD(0xd0), cmd_addr); | 376 | map_write(map, CMD(0xd0), cmd_addr); |
377 | map_write(map, CMD(0x70), cmd_addr); | 377 | map_write(map, CMD(0x70), cmd_addr); |
378 | } | 378 | } |
379 | 379 | ||
380 | wake_up(&chip->wq); | 380 | wake_up(&chip->wq); |
@@ -414,14 +414,14 @@ static int cfi_staa_read (struct mtd_info *mtd, loff_t from, size_t len, size_t | |||
414 | *retlen += thislen; | 414 | *retlen += thislen; |
415 | len -= thislen; | 415 | len -= thislen; |
416 | buf += thislen; | 416 | buf += thislen; |
417 | 417 | ||
418 | ofs = 0; | 418 | ofs = 0; |
419 | chipnum++; | 419 | chipnum++; |
420 | } | 420 | } |
421 | return ret; | 421 | return ret; |
422 | } | 422 | } |
423 | 423 | ||
424 | static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | 424 | static inline int do_write_buffer(struct map_info *map, struct flchip *chip, |
425 | unsigned long adr, const u_char *buf, int len) | 425 | unsigned long adr, const u_char *buf, int len) |
426 | { | 426 | { |
427 | struct cfi_private *cfi = map->fldrv_priv; | 427 | struct cfi_private *cfi = map->fldrv_priv; |
@@ -429,7 +429,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
429 | unsigned long cmd_adr, timeo; | 429 | unsigned long cmd_adr, timeo; |
430 | DECLARE_WAITQUEUE(wait, current); | 430 | DECLARE_WAITQUEUE(wait, current); |
431 | int wbufsize, z; | 431 | int wbufsize, z; |
432 | 432 | ||
433 | /* M58LW064A requires bus alignment for buffer wriets -- saw */ | 433 | /* M58LW064A requires bus alignment for buffer wriets -- saw */ |
434 | if (adr & (map_bankwidth(map)-1)) | 434 | if (adr & (map_bankwidth(map)-1)) |
435 | return -EINVAL; | 435 | return -EINVAL; |
@@ -437,10 +437,10 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
437 | wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; | 437 | wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; |
438 | adr += chip->start; | 438 | adr += chip->start; |
439 | cmd_adr = adr & ~(wbufsize-1); | 439 | cmd_adr = adr & ~(wbufsize-1); |
440 | 440 | ||
441 | /* Let's determine this according to the interleave only once */ | 441 | /* Let's determine this according to the interleave only once */ |
442 | status_OK = CMD(0x80); | 442 | status_OK = CMD(0x80); |
443 | 443 | ||
444 | timeo = jiffies + HZ; | 444 | timeo = jiffies + HZ; |
445 | retry: | 445 | retry: |
446 | 446 | ||
@@ -448,7 +448,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
448 | printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state); | 448 | printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state); |
449 | #endif | 449 | #endif |
450 | spin_lock_bh(chip->mutex); | 450 | spin_lock_bh(chip->mutex); |
451 | 451 | ||
452 | /* Check that the chip's ready to talk to us. | 452 | /* Check that the chip's ready to talk to us. |
453 | * Later, we can actually think about interrupting it | 453 | * Later, we can actually think about interrupting it |
454 | * if it's in FL_ERASING state. | 454 | * if it's in FL_ERASING state. |
@@ -457,7 +457,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
457 | switch (chip->state) { | 457 | switch (chip->state) { |
458 | case FL_READY: | 458 | case FL_READY: |
459 | break; | 459 | break; |
460 | 460 | ||
461 | case FL_CFI_QUERY: | 461 | case FL_CFI_QUERY: |
462 | case FL_JEDEC_QUERY: | 462 | case FL_JEDEC_QUERY: |
463 | map_write(map, CMD(0x70), cmd_adr); | 463 | map_write(map, CMD(0x70), cmd_adr); |
@@ -522,7 +522,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
522 | 522 | ||
523 | /* Write length of data to come */ | 523 | /* Write length of data to come */ |
524 | map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr ); | 524 | map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr ); |
525 | 525 | ||
526 | /* Write data */ | 526 | /* Write data */ |
527 | for (z = 0; z < len; | 527 | for (z = 0; z < len; |
528 | z += map_bankwidth(map), buf += map_bankwidth(map)) { | 528 | z += map_bankwidth(map), buf += map_bankwidth(map)) { |
@@ -569,7 +569,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
569 | printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n"); | 569 | printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n"); |
570 | return -EIO; | 570 | return -EIO; |
571 | } | 571 | } |
572 | 572 | ||
573 | /* Latency issues. Drop the lock, wait a while and retry */ | 573 | /* Latency issues. Drop the lock, wait a while and retry */ |
574 | spin_unlock_bh(chip->mutex); | 574 | spin_unlock_bh(chip->mutex); |
575 | cfi_udelay(1); | 575 | cfi_udelay(1); |
@@ -581,9 +581,9 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
581 | if (!chip->buffer_write_time) | 581 | if (!chip->buffer_write_time) |
582 | chip->buffer_write_time++; | 582 | chip->buffer_write_time++; |
583 | } | 583 | } |
584 | if (z > 1) | 584 | if (z > 1) |
585 | chip->buffer_write_time++; | 585 | chip->buffer_write_time++; |
586 | 586 | ||
587 | /* Done and happy. */ | 587 | /* Done and happy. */ |
588 | DISABLE_VPP(map); | 588 | DISABLE_VPP(map); |
589 | chip->state = FL_STATUS; | 589 | chip->state = FL_STATUS; |
@@ -607,7 +607,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
607 | return 0; | 607 | return 0; |
608 | } | 608 | } |
609 | 609 | ||
610 | static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, | 610 | static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, |
611 | size_t len, size_t *retlen, const u_char *buf) | 611 | size_t len, size_t *retlen, const u_char *buf) |
612 | { | 612 | { |
613 | struct map_info *map = mtd->priv; | 613 | struct map_info *map = mtd->priv; |
@@ -629,7 +629,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, | |||
629 | printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize); | 629 | printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize); |
630 | printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len); | 630 | printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len); |
631 | #endif | 631 | #endif |
632 | 632 | ||
633 | /* Write buffer is worth it only if more than one word to write... */ | 633 | /* Write buffer is worth it only if more than one word to write... */ |
634 | while (len > 0) { | 634 | while (len > 0) { |
635 | /* We must not cross write block boundaries */ | 635 | /* We must not cross write block boundaries */ |
@@ -638,7 +638,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, | |||
638 | if (size > len) | 638 | if (size > len) |
639 | size = len; | 639 | size = len; |
640 | 640 | ||
641 | ret = do_write_buffer(map, &cfi->chips[chipnum], | 641 | ret = do_write_buffer(map, &cfi->chips[chipnum], |
642 | ofs, buf, size); | 642 | ofs, buf, size); |
643 | if (ret) | 643 | if (ret) |
644 | return ret; | 644 | return ret; |
@@ -649,13 +649,13 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, | |||
649 | len -= size; | 649 | len -= size; |
650 | 650 | ||
651 | if (ofs >> cfi->chipshift) { | 651 | if (ofs >> cfi->chipshift) { |
652 | chipnum ++; | 652 | chipnum ++; |
653 | ofs = 0; | 653 | ofs = 0; |
654 | if (chipnum == cfi->numchips) | 654 | if (chipnum == cfi->numchips) |
655 | return 0; | 655 | return 0; |
656 | } | 656 | } |
657 | } | 657 | } |
658 | 658 | ||
659 | return 0; | 659 | return 0; |
660 | } | 660 | } |
661 | 661 | ||
@@ -765,7 +765,7 @@ retry: | |||
765 | status = map_read(map, adr); | 765 | status = map_read(map, adr); |
766 | if (map_word_andequal(map, status, status_OK, status_OK)) | 766 | if (map_word_andequal(map, status, status_OK, status_OK)) |
767 | break; | 767 | break; |
768 | 768 | ||
769 | /* Urgh. Chip not yet ready to talk to us. */ | 769 | /* Urgh. Chip not yet ready to talk to us. */ |
770 | if (time_after(jiffies, timeo)) { | 770 | if (time_after(jiffies, timeo)) { |
771 | spin_unlock_bh(chip->mutex); | 771 | spin_unlock_bh(chip->mutex); |
@@ -798,7 +798,7 @@ retry: | |||
798 | map_write(map, CMD(0x20), adr); | 798 | map_write(map, CMD(0x20), adr); |
799 | map_write(map, CMD(0xD0), adr); | 799 | map_write(map, CMD(0xD0), adr); |
800 | chip->state = FL_ERASING; | 800 | chip->state = FL_ERASING; |
801 | 801 | ||
802 | spin_unlock_bh(chip->mutex); | 802 | spin_unlock_bh(chip->mutex); |
803 | msleep(1000); | 803 | msleep(1000); |
804 | spin_lock_bh(chip->mutex); | 804 | spin_lock_bh(chip->mutex); |
@@ -823,7 +823,7 @@ retry: | |||
823 | status = map_read(map, adr); | 823 | status = map_read(map, adr); |
824 | if (map_word_andequal(map, status, status_OK, status_OK)) | 824 | if (map_word_andequal(map, status, status_OK, status_OK)) |
825 | break; | 825 | break; |
826 | 826 | ||
827 | /* OK Still waiting */ | 827 | /* OK Still waiting */ |
828 | if (time_after(jiffies, timeo)) { | 828 | if (time_after(jiffies, timeo)) { |
829 | map_write(map, CMD(0x70), adr); | 829 | map_write(map, CMD(0x70), adr); |
@@ -833,13 +833,13 @@ retry: | |||
833 | spin_unlock_bh(chip->mutex); | 833 | spin_unlock_bh(chip->mutex); |
834 | return -EIO; | 834 | return -EIO; |
835 | } | 835 | } |
836 | 836 | ||
837 | /* Latency issues. Drop the lock, wait a while and retry */ | 837 | /* Latency issues. Drop the lock, wait a while and retry */ |
838 | spin_unlock_bh(chip->mutex); | 838 | spin_unlock_bh(chip->mutex); |
839 | cfi_udelay(1); | 839 | cfi_udelay(1); |
840 | spin_lock_bh(chip->mutex); | 840 | spin_lock_bh(chip->mutex); |
841 | } | 841 | } |
842 | 842 | ||
843 | DISABLE_VPP(map); | 843 | DISABLE_VPP(map); |
844 | ret = 0; | 844 | ret = 0; |
845 | 845 | ||
@@ -864,7 +864,7 @@ retry: | |||
864 | /* Reset the error bits */ | 864 | /* Reset the error bits */ |
865 | map_write(map, CMD(0x50), adr); | 865 | map_write(map, CMD(0x50), adr); |
866 | map_write(map, CMD(0x70), adr); | 866 | map_write(map, CMD(0x70), adr); |
867 | 867 | ||
868 | if ((chipstatus & 0x30) == 0x30) { | 868 | if ((chipstatus & 0x30) == 0x30) { |
869 | printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus); | 869 | printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus); |
870 | ret = -EIO; | 870 | ret = -EIO; |
@@ -913,17 +913,17 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) | |||
913 | 913 | ||
914 | i = 0; | 914 | i = 0; |
915 | 915 | ||
916 | /* Skip all erase regions which are ended before the start of | 916 | /* Skip all erase regions which are ended before the start of |
917 | the requested erase. Actually, to save on the calculations, | 917 | the requested erase. Actually, to save on the calculations, |
918 | we skip to the first erase region which starts after the | 918 | we skip to the first erase region which starts after the |
919 | start of the requested erase, and then go back one. | 919 | start of the requested erase, and then go back one. |
920 | */ | 920 | */ |
921 | 921 | ||
922 | while (i < mtd->numeraseregions && instr->addr >= regions[i].offset) | 922 | while (i < mtd->numeraseregions && instr->addr >= regions[i].offset) |
923 | i++; | 923 | i++; |
924 | i--; | 924 | i--; |
925 | 925 | ||
926 | /* OK, now i is pointing at the erase region in which this | 926 | /* OK, now i is pointing at the erase region in which this |
927 | erase request starts. Check the start of the requested | 927 | erase request starts. Check the start of the requested |
928 | erase range is aligned with the erase size which is in | 928 | erase range is aligned with the erase size which is in |
929 | effect here. | 929 | effect here. |
@@ -946,7 +946,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) | |||
946 | the address actually falls | 946 | the address actually falls |
947 | */ | 947 | */ |
948 | i--; | 948 | i--; |
949 | 949 | ||
950 | if ((instr->addr + instr->len) & (regions[i].erasesize-1)) | 950 | if ((instr->addr + instr->len) & (regions[i].erasesize-1)) |
951 | return -EINVAL; | 951 | return -EINVAL; |
952 | 952 | ||
@@ -958,7 +958,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) | |||
958 | 958 | ||
959 | while(len) { | 959 | while(len) { |
960 | ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr); | 960 | ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr); |
961 | 961 | ||
962 | if (ret) | 962 | if (ret) |
963 | return ret; | 963 | return ret; |
964 | 964 | ||
@@ -971,15 +971,15 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) | |||
971 | if (adr >> cfi->chipshift) { | 971 | if (adr >> cfi->chipshift) { |
972 | adr = 0; | 972 | adr = 0; |
973 | chipnum++; | 973 | chipnum++; |
974 | 974 | ||
975 | if (chipnum >= cfi->numchips) | 975 | if (chipnum >= cfi->numchips) |
976 | break; | 976 | break; |
977 | } | 977 | } |
978 | } | 978 | } |
979 | 979 | ||
980 | instr->state = MTD_ERASE_DONE; | 980 | instr->state = MTD_ERASE_DONE; |
981 | mtd_erase_callback(instr); | 981 | mtd_erase_callback(instr); |
982 | 982 | ||
983 | return 0; | 983 | return 0; |
984 | } | 984 | } |
985 | 985 | ||
@@ -1005,7 +1005,7 @@ static void cfi_staa_sync (struct mtd_info *mtd) | |||
1005 | case FL_JEDEC_QUERY: | 1005 | case FL_JEDEC_QUERY: |
1006 | chip->oldstate = chip->state; | 1006 | chip->oldstate = chip->state; |
1007 | chip->state = FL_SYNCING; | 1007 | chip->state = FL_SYNCING; |
1008 | /* No need to wake_up() on this state change - | 1008 | /* No need to wake_up() on this state change - |
1009 | * as the whole point is that nobody can do anything | 1009 | * as the whole point is that nobody can do anything |
1010 | * with the chip now anyway. | 1010 | * with the chip now anyway. |
1011 | */ | 1011 | */ |
@@ -1016,11 +1016,11 @@ static void cfi_staa_sync (struct mtd_info *mtd) | |||
1016 | default: | 1016 | default: |
1017 | /* Not an idle state */ | 1017 | /* Not an idle state */ |
1018 | add_wait_queue(&chip->wq, &wait); | 1018 | add_wait_queue(&chip->wq, &wait); |
1019 | 1019 | ||
1020 | spin_unlock_bh(chip->mutex); | 1020 | spin_unlock_bh(chip->mutex); |
1021 | schedule(); | 1021 | schedule(); |
1022 | remove_wait_queue(&chip->wq, &wait); | 1022 | remove_wait_queue(&chip->wq, &wait); |
1023 | 1023 | ||
1024 | goto retry; | 1024 | goto retry; |
1025 | } | 1025 | } |
1026 | } | 1026 | } |
@@ -1031,7 +1031,7 @@ static void cfi_staa_sync (struct mtd_info *mtd) | |||
1031 | chip = &cfi->chips[i]; | 1031 | chip = &cfi->chips[i]; |
1032 | 1032 | ||
1033 | spin_lock_bh(chip->mutex); | 1033 | spin_lock_bh(chip->mutex); |
1034 | 1034 | ||
1035 | if (chip->state == FL_SYNCING) { | 1035 | if (chip->state == FL_SYNCING) { |
1036 | chip->state = chip->oldstate; | 1036 | chip->state = chip->oldstate; |
1037 | wake_up(&chip->wq); | 1037 | wake_up(&chip->wq); |
@@ -1066,9 +1066,9 @@ retry: | |||
1066 | 1066 | ||
1067 | case FL_STATUS: | 1067 | case FL_STATUS: |
1068 | status = map_read(map, adr); | 1068 | status = map_read(map, adr); |
1069 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1069 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1070 | break; | 1070 | break; |
1071 | 1071 | ||
1072 | /* Urgh. Chip not yet ready to talk to us. */ | 1072 | /* Urgh. Chip not yet ready to talk to us. */ |
1073 | if (time_after(jiffies, timeo)) { | 1073 | if (time_after(jiffies, timeo)) { |
1074 | spin_unlock_bh(chip->mutex); | 1074 | spin_unlock_bh(chip->mutex); |
@@ -1097,7 +1097,7 @@ retry: | |||
1097 | map_write(map, CMD(0x60), adr); | 1097 | map_write(map, CMD(0x60), adr); |
1098 | map_write(map, CMD(0x01), adr); | 1098 | map_write(map, CMD(0x01), adr); |
1099 | chip->state = FL_LOCKING; | 1099 | chip->state = FL_LOCKING; |
1100 | 1100 | ||
1101 | spin_unlock_bh(chip->mutex); | 1101 | spin_unlock_bh(chip->mutex); |
1102 | msleep(1000); | 1102 | msleep(1000); |
1103 | spin_lock_bh(chip->mutex); | 1103 | spin_lock_bh(chip->mutex); |
@@ -1111,7 +1111,7 @@ retry: | |||
1111 | status = map_read(map, adr); | 1111 | status = map_read(map, adr); |
1112 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1112 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1113 | break; | 1113 | break; |
1114 | 1114 | ||
1115 | /* OK Still waiting */ | 1115 | /* OK Still waiting */ |
1116 | if (time_after(jiffies, timeo)) { | 1116 | if (time_after(jiffies, timeo)) { |
1117 | map_write(map, CMD(0x70), adr); | 1117 | map_write(map, CMD(0x70), adr); |
@@ -1121,13 +1121,13 @@ retry: | |||
1121 | spin_unlock_bh(chip->mutex); | 1121 | spin_unlock_bh(chip->mutex); |
1122 | return -EIO; | 1122 | return -EIO; |
1123 | } | 1123 | } |
1124 | 1124 | ||
1125 | /* Latency issues. Drop the lock, wait a while and retry */ | 1125 | /* Latency issues. Drop the lock, wait a while and retry */ |
1126 | spin_unlock_bh(chip->mutex); | 1126 | spin_unlock_bh(chip->mutex); |
1127 | cfi_udelay(1); | 1127 | cfi_udelay(1); |
1128 | spin_lock_bh(chip->mutex); | 1128 | spin_lock_bh(chip->mutex); |
1129 | } | 1129 | } |
1130 | 1130 | ||
1131 | /* Done and happy. */ | 1131 | /* Done and happy. */ |
1132 | chip->state = FL_STATUS; | 1132 | chip->state = FL_STATUS; |
1133 | DISABLE_VPP(map); | 1133 | DISABLE_VPP(map); |
@@ -1171,8 +1171,8 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1171 | cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); | 1171 | cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); |
1172 | printk("after lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); | 1172 | printk("after lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); |
1173 | cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); | 1173 | cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); |
1174 | #endif | 1174 | #endif |
1175 | 1175 | ||
1176 | if (ret) | 1176 | if (ret) |
1177 | return ret; | 1177 | return ret; |
1178 | 1178 | ||
@@ -1182,7 +1182,7 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1182 | if (adr >> cfi->chipshift) { | 1182 | if (adr >> cfi->chipshift) { |
1183 | adr = 0; | 1183 | adr = 0; |
1184 | chipnum++; | 1184 | chipnum++; |
1185 | 1185 | ||
1186 | if (chipnum >= cfi->numchips) | 1186 | if (chipnum >= cfi->numchips) |
1187 | break; | 1187 | break; |
1188 | } | 1188 | } |
@@ -1217,7 +1217,7 @@ retry: | |||
1217 | status = map_read(map, adr); | 1217 | status = map_read(map, adr); |
1218 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1218 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1219 | break; | 1219 | break; |
1220 | 1220 | ||
1221 | /* Urgh. Chip not yet ready to talk to us. */ | 1221 | /* Urgh. Chip not yet ready to talk to us. */ |
1222 | if (time_after(jiffies, timeo)) { | 1222 | if (time_after(jiffies, timeo)) { |
1223 | spin_unlock_bh(chip->mutex); | 1223 | spin_unlock_bh(chip->mutex); |
@@ -1246,7 +1246,7 @@ retry: | |||
1246 | map_write(map, CMD(0x60), adr); | 1246 | map_write(map, CMD(0x60), adr); |
1247 | map_write(map, CMD(0xD0), adr); | 1247 | map_write(map, CMD(0xD0), adr); |
1248 | chip->state = FL_UNLOCKING; | 1248 | chip->state = FL_UNLOCKING; |
1249 | 1249 | ||
1250 | spin_unlock_bh(chip->mutex); | 1250 | spin_unlock_bh(chip->mutex); |
1251 | msleep(1000); | 1251 | msleep(1000); |
1252 | spin_lock_bh(chip->mutex); | 1252 | spin_lock_bh(chip->mutex); |
@@ -1260,7 +1260,7 @@ retry: | |||
1260 | status = map_read(map, adr); | 1260 | status = map_read(map, adr); |
1261 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1261 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1262 | break; | 1262 | break; |
1263 | 1263 | ||
1264 | /* OK Still waiting */ | 1264 | /* OK Still waiting */ |
1265 | if (time_after(jiffies, timeo)) { | 1265 | if (time_after(jiffies, timeo)) { |
1266 | map_write(map, CMD(0x70), adr); | 1266 | map_write(map, CMD(0x70), adr); |
@@ -1270,13 +1270,13 @@ retry: | |||
1270 | spin_unlock_bh(chip->mutex); | 1270 | spin_unlock_bh(chip->mutex); |
1271 | return -EIO; | 1271 | return -EIO; |
1272 | } | 1272 | } |
1273 | 1273 | ||
1274 | /* Latency issues. Drop the unlock, wait a while and retry */ | 1274 | /* Latency issues. Drop the unlock, wait a while and retry */ |
1275 | spin_unlock_bh(chip->mutex); | 1275 | spin_unlock_bh(chip->mutex); |
1276 | cfi_udelay(1); | 1276 | cfi_udelay(1); |
1277 | spin_lock_bh(chip->mutex); | 1277 | spin_lock_bh(chip->mutex); |
1278 | } | 1278 | } |
1279 | 1279 | ||
1280 | /* Done and happy. */ | 1280 | /* Done and happy. */ |
1281 | chip->state = FL_STATUS; | 1281 | chip->state = FL_STATUS; |
1282 | DISABLE_VPP(map); | 1282 | DISABLE_VPP(map); |
@@ -1301,7 +1301,7 @@ static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1301 | { | 1301 | { |
1302 | unsigned long temp_adr = adr; | 1302 | unsigned long temp_adr = adr; |
1303 | unsigned long temp_len = len; | 1303 | unsigned long temp_len = len; |
1304 | 1304 | ||
1305 | cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); | 1305 | cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); |
1306 | while (temp_len) { | 1306 | while (temp_len) { |
1307 | printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor))); | 1307 | printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor))); |
@@ -1319,7 +1319,7 @@ static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1319 | printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); | 1319 | printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); |
1320 | cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); | 1320 | cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); |
1321 | #endif | 1321 | #endif |
1322 | 1322 | ||
1323 | return ret; | 1323 | return ret; |
1324 | } | 1324 | } |
1325 | 1325 | ||
@@ -1343,7 +1343,7 @@ static int cfi_staa_suspend(struct mtd_info *mtd) | |||
1343 | case FL_JEDEC_QUERY: | 1343 | case FL_JEDEC_QUERY: |
1344 | chip->oldstate = chip->state; | 1344 | chip->oldstate = chip->state; |
1345 | chip->state = FL_PM_SUSPENDED; | 1345 | chip->state = FL_PM_SUSPENDED; |
1346 | /* No need to wake_up() on this state change - | 1346 | /* No need to wake_up() on this state change - |
1347 | * as the whole point is that nobody can do anything | 1347 | * as the whole point is that nobody can do anything |
1348 | * with the chip now anyway. | 1348 | * with the chip now anyway. |
1349 | */ | 1349 | */ |
@@ -1362,9 +1362,9 @@ static int cfi_staa_suspend(struct mtd_info *mtd) | |||
1362 | if (ret) { | 1362 | if (ret) { |
1363 | for (i--; i >=0; i--) { | 1363 | for (i--; i >=0; i--) { |
1364 | chip = &cfi->chips[i]; | 1364 | chip = &cfi->chips[i]; |
1365 | 1365 | ||
1366 | spin_lock_bh(chip->mutex); | 1366 | spin_lock_bh(chip->mutex); |
1367 | 1367 | ||
1368 | if (chip->state == FL_PM_SUSPENDED) { | 1368 | if (chip->state == FL_PM_SUSPENDED) { |
1369 | /* No need to force it into a known state here, | 1369 | /* No need to force it into a known state here, |
1370 | because we're returning failure, and it didn't | 1370 | because we're returning failure, and it didn't |
@@ -1374,8 +1374,8 @@ static int cfi_staa_suspend(struct mtd_info *mtd) | |||
1374 | } | 1374 | } |
1375 | spin_unlock_bh(chip->mutex); | 1375 | spin_unlock_bh(chip->mutex); |
1376 | } | 1376 | } |
1377 | } | 1377 | } |
1378 | 1378 | ||
1379 | return ret; | 1379 | return ret; |
1380 | } | 1380 | } |
1381 | 1381 | ||
@@ -1387,11 +1387,11 @@ static void cfi_staa_resume(struct mtd_info *mtd) | |||
1387 | struct flchip *chip; | 1387 | struct flchip *chip; |
1388 | 1388 | ||
1389 | for (i=0; i<cfi->numchips; i++) { | 1389 | for (i=0; i<cfi->numchips; i++) { |
1390 | 1390 | ||
1391 | chip = &cfi->chips[i]; | 1391 | chip = &cfi->chips[i]; |
1392 | 1392 | ||
1393 | spin_lock_bh(chip->mutex); | 1393 | spin_lock_bh(chip->mutex); |
1394 | 1394 | ||
1395 | /* Go to known state. Chip may have been power cycled */ | 1395 | /* Go to known state. Chip may have been power cycled */ |
1396 | if (chip->state == FL_PM_SUSPENDED) { | 1396 | if (chip->state == FL_PM_SUSPENDED) { |
1397 | map_write(map, CMD(0xFF), 0); | 1397 | map_write(map, CMD(0xFF), 0); |
diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c index cf750038ce6a..90eb30e06b7c 100644 --- a/drivers/mtd/chips/cfi_probe.c +++ b/drivers/mtd/chips/cfi_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: cfi_probe.c,v 1.83 2004/11/16 18:19:02 nico Exp $ | 4 | $Id: cfi_probe.c,v 1.84 2005/11/07 11:14:23 gleixner Exp $ |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/config.h> | 7 | #include <linux/config.h> |
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/mtd/cfi.h> | 20 | #include <linux/mtd/cfi.h> |
21 | #include <linux/mtd/gen_probe.h> | 21 | #include <linux/mtd/gen_probe.h> |
22 | 22 | ||
23 | //#define DEBUG_CFI | 23 | //#define DEBUG_CFI |
24 | 24 | ||
25 | #ifdef DEBUG_CFI | 25 | #ifdef DEBUG_CFI |
26 | static void print_cfi_ident(struct cfi_ident *); | 26 | static void print_cfi_ident(struct cfi_ident *); |
@@ -103,7 +103,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base, | |||
103 | unsigned long *chip_map, struct cfi_private *cfi) | 103 | unsigned long *chip_map, struct cfi_private *cfi) |
104 | { | 104 | { |
105 | int i; | 105 | int i; |
106 | 106 | ||
107 | if ((base + 0) >= map->size) { | 107 | if ((base + 0) >= map->size) { |
108 | printk(KERN_NOTICE | 108 | printk(KERN_NOTICE |
109 | "Probe at base[0x00](0x%08lx) past the end of the map(0x%08lx)\n", | 109 | "Probe at base[0x00](0x%08lx) past the end of the map(0x%08lx)\n", |
@@ -128,7 +128,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base, | |||
128 | } | 128 | } |
129 | 129 | ||
130 | if (!cfi->numchips) { | 130 | if (!cfi->numchips) { |
131 | /* This is the first time we're called. Set up the CFI | 131 | /* This is the first time we're called. Set up the CFI |
132 | stuff accordingly and return */ | 132 | stuff accordingly and return */ |
133 | return cfi_chip_setup(map, cfi); | 133 | return cfi_chip_setup(map, cfi); |
134 | } | 134 | } |
@@ -138,13 +138,13 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base, | |||
138 | unsigned long start; | 138 | unsigned long start; |
139 | if(!test_bit(i, chip_map)) { | 139 | if(!test_bit(i, chip_map)) { |
140 | /* Skip location; no valid chip at this address */ | 140 | /* Skip location; no valid chip at this address */ |
141 | continue; | 141 | continue; |
142 | } | 142 | } |
143 | start = i << cfi->chipshift; | 143 | start = i << cfi->chipshift; |
144 | /* This chip should be in read mode if it's one | 144 | /* This chip should be in read mode if it's one |
145 | we've already touched. */ | 145 | we've already touched. */ |
146 | if (qry_present(map, start, cfi)) { | 146 | if (qry_present(map, start, cfi)) { |
147 | /* Eep. This chip also had the QRY marker. | 147 | /* Eep. This chip also had the QRY marker. |
148 | * Is it an alias for the new one? */ | 148 | * Is it an alias for the new one? */ |
149 | cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL); | 149 | cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL); |
150 | cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL); | 150 | cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL); |
@@ -156,13 +156,13 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base, | |||
156 | map->name, base, start); | 156 | map->name, base, start); |
157 | return 0; | 157 | return 0; |
158 | } | 158 | } |
159 | /* Yes, it's actually got QRY for data. Most | 159 | /* Yes, it's actually got QRY for data. Most |
160 | * unfortunate. Stick the new chip in read mode | 160 | * unfortunate. Stick the new chip in read mode |
161 | * too and if it's the same, assume it's an alias. */ | 161 | * too and if it's the same, assume it's an alias. */ |
162 | /* FIXME: Use other modes to do a proper check */ | 162 | /* FIXME: Use other modes to do a proper check */ |
163 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | 163 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); |
164 | cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL); | 164 | cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL); |
165 | 165 | ||
166 | if (qry_present(map, base, cfi)) { | 166 | if (qry_present(map, base, cfi)) { |
167 | xip_allowed(base, map); | 167 | xip_allowed(base, map); |
168 | printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", | 168 | printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", |
@@ -171,12 +171,12 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base, | |||
171 | } | 171 | } |
172 | } | 172 | } |
173 | } | 173 | } |
174 | 174 | ||
175 | /* OK, if we got to here, then none of the previous chips appear to | 175 | /* OK, if we got to here, then none of the previous chips appear to |
176 | be aliases for the current one. */ | 176 | be aliases for the current one. */ |
177 | set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */ | 177 | set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */ |
178 | cfi->numchips++; | 178 | cfi->numchips++; |
179 | 179 | ||
180 | /* Put it back into Read Mode */ | 180 | /* Put it back into Read Mode */ |
181 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | 181 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); |
182 | cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); | 182 | cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); |
@@ -185,11 +185,11 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base, | |||
185 | printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", | 185 | printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", |
186 | map->name, cfi->interleave, cfi->device_type*8, base, | 186 | map->name, cfi->interleave, cfi->device_type*8, base, |
187 | map->bankwidth*8); | 187 | map->bankwidth*8); |
188 | 188 | ||
189 | return 1; | 189 | return 1; |
190 | } | 190 | } |
191 | 191 | ||
192 | static int __xipram cfi_chip_setup(struct map_info *map, | 192 | static int __xipram cfi_chip_setup(struct map_info *map, |
193 | struct cfi_private *cfi) | 193 | struct cfi_private *cfi) |
194 | { | 194 | { |
195 | int ofs_factor = cfi->interleave*cfi->device_type; | 195 | int ofs_factor = cfi->interleave*cfi->device_type; |
@@ -209,11 +209,11 @@ static int __xipram cfi_chip_setup(struct map_info *map, | |||
209 | printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); | 209 | printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); |
210 | return 0; | 210 | return 0; |
211 | } | 211 | } |
212 | 212 | ||
213 | memset(cfi->cfiq,0,sizeof(struct cfi_ident)); | 213 | memset(cfi->cfiq,0,sizeof(struct cfi_ident)); |
214 | 214 | ||
215 | cfi->cfi_mode = CFI_MODE_CFI; | 215 | cfi->cfi_mode = CFI_MODE_CFI; |
216 | 216 | ||
217 | /* Read the CFI info structure */ | 217 | /* Read the CFI info structure */ |
218 | xip_disable_qry(base, map, cfi); | 218 | xip_disable_qry(base, map, cfi); |
219 | for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) | 219 | for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) |
@@ -231,7 +231,7 @@ static int __xipram cfi_chip_setup(struct map_info *map, | |||
231 | cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL); | 231 | cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL); |
232 | cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL); | 232 | cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL); |
233 | cfi->mfr = cfi_read_query(map, base); | 233 | cfi->mfr = cfi_read_query(map, base); |
234 | cfi->id = cfi_read_query(map, base + ofs_factor); | 234 | cfi->id = cfi_read_query(map, base + ofs_factor); |
235 | 235 | ||
236 | /* Put it back into Read Mode */ | 236 | /* Put it back into Read Mode */ |
237 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | 237 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); |
@@ -255,10 +255,10 @@ static int __xipram cfi_chip_setup(struct map_info *map, | |||
255 | 255 | ||
256 | for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { | 256 | for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { |
257 | cfi->cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]); | 257 | cfi->cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]); |
258 | 258 | ||
259 | #ifdef DEBUG_CFI | 259 | #ifdef DEBUG_CFI |
260 | printk(" Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n", | 260 | printk(" Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n", |
261 | i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff, | 261 | i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff, |
262 | (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1); | 262 | (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1); |
263 | #endif | 263 | #endif |
264 | } | 264 | } |
@@ -271,33 +271,33 @@ static int __xipram cfi_chip_setup(struct map_info *map, | |||
271 | } | 271 | } |
272 | 272 | ||
273 | #ifdef DEBUG_CFI | 273 | #ifdef DEBUG_CFI |
274 | static char *vendorname(__u16 vendor) | 274 | static char *vendorname(__u16 vendor) |
275 | { | 275 | { |
276 | switch (vendor) { | 276 | switch (vendor) { |
277 | case P_ID_NONE: | 277 | case P_ID_NONE: |
278 | return "None"; | 278 | return "None"; |
279 | 279 | ||
280 | case P_ID_INTEL_EXT: | 280 | case P_ID_INTEL_EXT: |
281 | return "Intel/Sharp Extended"; | 281 | return "Intel/Sharp Extended"; |
282 | 282 | ||
283 | case P_ID_AMD_STD: | 283 | case P_ID_AMD_STD: |
284 | return "AMD/Fujitsu Standard"; | 284 | return "AMD/Fujitsu Standard"; |
285 | 285 | ||
286 | case P_ID_INTEL_STD: | 286 | case P_ID_INTEL_STD: |
287 | return "Intel/Sharp Standard"; | 287 | return "Intel/Sharp Standard"; |
288 | 288 | ||
289 | case P_ID_AMD_EXT: | 289 | case P_ID_AMD_EXT: |
290 | return "AMD/Fujitsu Extended"; | 290 | return "AMD/Fujitsu Extended"; |
291 | 291 | ||
292 | case P_ID_WINBOND: | 292 | case P_ID_WINBOND: |
293 | return "Winbond Standard"; | 293 | return "Winbond Standard"; |
294 | 294 | ||
295 | case P_ID_ST_ADV: | 295 | case P_ID_ST_ADV: |
296 | return "ST Advanced"; | 296 | return "ST Advanced"; |
297 | 297 | ||
298 | case P_ID_MITSUBISHI_STD: | 298 | case P_ID_MITSUBISHI_STD: |
299 | return "Mitsubishi Standard"; | 299 | return "Mitsubishi Standard"; |
300 | 300 | ||
301 | case P_ID_MITSUBISHI_EXT: | 301 | case P_ID_MITSUBISHI_EXT: |
302 | return "Mitsubishi Extended"; | 302 | return "Mitsubishi Extended"; |
303 | 303 | ||
@@ -306,13 +306,13 @@ static char *vendorname(__u16 vendor) | |||
306 | 306 | ||
307 | case P_ID_INTEL_PERFORMANCE: | 307 | case P_ID_INTEL_PERFORMANCE: |
308 | return "Intel Performance Code"; | 308 | return "Intel Performance Code"; |
309 | 309 | ||
310 | case P_ID_INTEL_DATA: | 310 | case P_ID_INTEL_DATA: |
311 | return "Intel Data"; | 311 | return "Intel Data"; |
312 | 312 | ||
313 | case P_ID_RESERVED: | 313 | case P_ID_RESERVED: |
314 | return "Not Allowed / Reserved for Future Use"; | 314 | return "Not Allowed / Reserved for Future Use"; |
315 | 315 | ||
316 | default: | 316 | default: |
317 | return "Unknown"; | 317 | return "Unknown"; |
318 | } | 318 | } |
@@ -325,21 +325,21 @@ static void print_cfi_ident(struct cfi_ident *cfip) | |||
325 | if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') { | 325 | if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') { |
326 | printk("Invalid CFI ident structure.\n"); | 326 | printk("Invalid CFI ident structure.\n"); |
327 | return; | 327 | return; |
328 | } | 328 | } |
329 | #endif | 329 | #endif |
330 | printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID)); | 330 | printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID)); |
331 | if (cfip->P_ADR) | 331 | if (cfip->P_ADR) |
332 | printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR); | 332 | printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR); |
333 | else | 333 | else |
334 | printk("No Primary Algorithm Table\n"); | 334 | printk("No Primary Algorithm Table\n"); |
335 | 335 | ||
336 | printk("Alternative Vendor Command Set: %4.4X (%s)\n", cfip->A_ID, vendorname(cfip->A_ID)); | 336 | printk("Alternative Vendor Command Set: %4.4X (%s)\n", cfip->A_ID, vendorname(cfip->A_ID)); |
337 | if (cfip->A_ADR) | 337 | if (cfip->A_ADR) |
338 | printk("Alternate Algorithm Table at %4.4X\n", cfip->A_ADR); | 338 | printk("Alternate Algorithm Table at %4.4X\n", cfip->A_ADR); |
339 | else | 339 | else |
340 | printk("No Alternate Algorithm Table\n"); | 340 | printk("No Alternate Algorithm Table\n"); |
341 | 341 | ||
342 | 342 | ||
343 | printk("Vcc Minimum: %2d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf); | 343 | printk("Vcc Minimum: %2d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf); |
344 | printk("Vcc Maximum: %2d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf); | 344 | printk("Vcc Maximum: %2d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf); |
345 | if (cfip->VppMin) { | 345 | if (cfip->VppMin) { |
@@ -348,61 +348,61 @@ static void print_cfi_ident(struct cfi_ident *cfip) | |||
348 | } | 348 | } |
349 | else | 349 | else |
350 | printk("No Vpp line\n"); | 350 | printk("No Vpp line\n"); |
351 | 351 | ||
352 | printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp); | 352 | printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp); |
353 | printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp)); | 353 | printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp)); |
354 | 354 | ||
355 | if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) { | 355 | if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) { |
356 | printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp); | 356 | printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp); |
357 | printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp)); | 357 | printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp)); |
358 | } | 358 | } |
359 | else | 359 | else |
360 | printk("Full buffer write not supported\n"); | 360 | printk("Full buffer write not supported\n"); |
361 | 361 | ||
362 | printk("Typical block erase timeout: %d ms\n", 1<<cfip->BlockEraseTimeoutTyp); | 362 | printk("Typical block erase timeout: %d ms\n", 1<<cfip->BlockEraseTimeoutTyp); |
363 | printk("Maximum block erase timeout: %d ms\n", (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp)); | 363 | printk("Maximum block erase timeout: %d ms\n", (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp)); |
364 | if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) { | 364 | if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) { |
365 | printk("Typical chip erase timeout: %d ms\n", 1<<cfip->ChipEraseTimeoutTyp); | 365 | printk("Typical chip erase timeout: %d ms\n", 1<<cfip->ChipEraseTimeoutTyp); |
366 | printk("Maximum chip erase timeout: %d ms\n", (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->ChipEraseTimeoutTyp)); | 366 | printk("Maximum chip erase timeout: %d ms\n", (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->ChipEraseTimeoutTyp)); |
367 | } | 367 | } |
368 | else | 368 | else |
369 | printk("Chip erase not supported\n"); | 369 | printk("Chip erase not supported\n"); |
370 | 370 | ||
371 | printk("Device size: 0x%X bytes (%d MiB)\n", 1 << cfip->DevSize, 1<< (cfip->DevSize - 20)); | 371 | printk("Device size: 0x%X bytes (%d MiB)\n", 1 << cfip->DevSize, 1<< (cfip->DevSize - 20)); |
372 | printk("Flash Device Interface description: 0x%4.4X\n", cfip->InterfaceDesc); | 372 | printk("Flash Device Interface description: 0x%4.4X\n", cfip->InterfaceDesc); |
373 | switch(cfip->InterfaceDesc) { | 373 | switch(cfip->InterfaceDesc) { |
374 | case 0: | 374 | case 0: |
375 | printk(" - x8-only asynchronous interface\n"); | 375 | printk(" - x8-only asynchronous interface\n"); |
376 | break; | 376 | break; |
377 | 377 | ||
378 | case 1: | 378 | case 1: |
379 | printk(" - x16-only asynchronous interface\n"); | 379 | printk(" - x16-only asynchronous interface\n"); |
380 | break; | 380 | break; |
381 | 381 | ||
382 | case 2: | 382 | case 2: |
383 | printk(" - supports x8 and x16 via BYTE# with asynchronous interface\n"); | 383 | printk(" - supports x8 and x16 via BYTE# with asynchronous interface\n"); |
384 | break; | 384 | break; |
385 | 385 | ||
386 | case 3: | 386 | case 3: |
387 | printk(" - x32-only asynchronous interface\n"); | 387 | printk(" - x32-only asynchronous interface\n"); |
388 | break; | 388 | break; |
389 | 389 | ||
390 | case 4: | 390 | case 4: |
391 | printk(" - supports x16 and x32 via Word# with asynchronous interface\n"); | 391 | printk(" - supports x16 and x32 via Word# with asynchronous interface\n"); |
392 | break; | 392 | break; |
393 | 393 | ||
394 | case 65535: | 394 | case 65535: |
395 | printk(" - Not Allowed / Reserved\n"); | 395 | printk(" - Not Allowed / Reserved\n"); |
396 | break; | 396 | break; |
397 | 397 | ||
398 | default: | 398 | default: |
399 | printk(" - Unknown\n"); | 399 | printk(" - Unknown\n"); |
400 | break; | 400 | break; |
401 | } | 401 | } |
402 | 402 | ||
403 | printk("Max. bytes in buffer write: 0x%x\n", 1<< cfip->MaxBufWriteSize); | 403 | printk("Max. bytes in buffer write: 0x%x\n", 1<< cfip->MaxBufWriteSize); |
404 | printk("Number of Erase Block Regions: %d\n", cfip->NumEraseRegions); | 404 | printk("Number of Erase Block Regions: %d\n", cfip->NumEraseRegions); |
405 | 405 | ||
406 | } | 406 | } |
407 | #endif /* DEBUG_CFI */ | 407 | #endif /* DEBUG_CFI */ |
408 | 408 | ||
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c index 0cf183f01e49..d8e7a026ba5a 100644 --- a/drivers/mtd/chips/cfi_util.c +++ b/drivers/mtd/chips/cfi_util.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * This code is covered by the GPL. | 8 | * This code is covered by the GPL. |
9 | * | 9 | * |
10 | * $Id: cfi_util.c,v 1.9 2005/07/20 21:01:14 tpoynor Exp $ | 10 | * $Id: cfi_util.c,v 1.10 2005/11/07 11:14:23 gleixner Exp $ |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
@@ -56,7 +56,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n | |||
56 | 56 | ||
57 | /* Read in the Extended Query Table */ | 57 | /* Read in the Extended Query Table */ |
58 | for (i=0; i<size; i++) { | 58 | for (i=0; i<size; i++) { |
59 | ((unsigned char *)extp)[i] = | 59 | ((unsigned char *)extp)[i] = |
60 | cfi_read_query(map, base+((adr+i)*ofs_factor)); | 60 | cfi_read_query(map, base+((adr+i)*ofs_factor)); |
61 | } | 61 | } |
62 | 62 | ||
@@ -113,17 +113,17 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob, | |||
113 | 113 | ||
114 | i = 0; | 114 | i = 0; |
115 | 115 | ||
116 | /* Skip all erase regions which are ended before the start of | 116 | /* Skip all erase regions which are ended before the start of |
117 | the requested erase. Actually, to save on the calculations, | 117 | the requested erase. Actually, to save on the calculations, |
118 | we skip to the first erase region which starts after the | 118 | we skip to the first erase region which starts after the |
119 | start of the requested erase, and then go back one. | 119 | start of the requested erase, and then go back one. |
120 | */ | 120 | */ |
121 | 121 | ||
122 | while (i < mtd->numeraseregions && ofs >= regions[i].offset) | 122 | while (i < mtd->numeraseregions && ofs >= regions[i].offset) |
123 | i++; | 123 | i++; |
124 | i--; | 124 | i--; |
125 | 125 | ||
126 | /* OK, now i is pointing at the erase region in which this | 126 | /* OK, now i is pointing at the erase region in which this |
127 | erase request starts. Check the start of the requested | 127 | erase request starts. Check the start of the requested |
128 | erase range is aligned with the erase size which is in | 128 | erase range is aligned with the erase size which is in |
129 | effect here. | 129 | effect here. |
@@ -146,7 +146,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob, | |||
146 | the address actually falls | 146 | the address actually falls |
147 | */ | 147 | */ |
148 | i--; | 148 | i--; |
149 | 149 | ||
150 | if ((ofs + len) & (regions[i].erasesize-1)) | 150 | if ((ofs + len) & (regions[i].erasesize-1)) |
151 | return -EINVAL; | 151 | return -EINVAL; |
152 | 152 | ||
@@ -159,7 +159,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob, | |||
159 | int size = regions[i].erasesize; | 159 | int size = regions[i].erasesize; |
160 | 160 | ||
161 | ret = (*frob)(map, &cfi->chips[chipnum], adr, size, thunk); | 161 | ret = (*frob)(map, &cfi->chips[chipnum], adr, size, thunk); |
162 | 162 | ||
163 | if (ret) | 163 | if (ret) |
164 | return ret; | 164 | return ret; |
165 | 165 | ||
@@ -173,7 +173,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob, | |||
173 | if (adr >> cfi->chipshift) { | 173 | if (adr >> cfi->chipshift) { |
174 | adr = 0; | 174 | adr = 0; |
175 | chipnum++; | 175 | chipnum++; |
176 | 176 | ||
177 | if (chipnum >= cfi->numchips) | 177 | if (chipnum >= cfi->numchips) |
178 | break; | 178 | break; |
179 | } | 179 | } |
diff --git a/drivers/mtd/chips/chipreg.c b/drivers/mtd/chips/chipreg.c index d7d739a108ae..c2127840a183 100644 --- a/drivers/mtd/chips/chipreg.c +++ b/drivers/mtd/chips/chipreg.c | |||
@@ -41,7 +41,7 @@ static struct mtd_chip_driver *get_mtd_chip_driver (const char *name) | |||
41 | 41 | ||
42 | list_for_each(pos, &chip_drvs_list) { | 42 | list_for_each(pos, &chip_drvs_list) { |
43 | this = list_entry(pos, typeof(*this), list); | 43 | this = list_entry(pos, typeof(*this), list); |
44 | 44 | ||
45 | if (!strcmp(this->name, name)) { | 45 | if (!strcmp(this->name, name)) { |
46 | ret = this; | 46 | ret = this; |
47 | break; | 47 | break; |
@@ -73,7 +73,7 @@ struct mtd_info *do_map_probe(const char *name, struct map_info *map) | |||
73 | 73 | ||
74 | ret = drv->probe(map); | 74 | ret = drv->probe(map); |
75 | 75 | ||
76 | /* We decrease the use count here. It may have been a | 76 | /* We decrease the use count here. It may have been a |
77 | probe-only module, which is no longer required from this | 77 | probe-only module, which is no longer required from this |
78 | point, having given us a handle on (and increased the use | 78 | point, having given us a handle on (and increased the use |
79 | count of) the actual driver code. | 79 | count of) the actual driver code. |
@@ -82,7 +82,7 @@ struct mtd_info *do_map_probe(const char *name, struct map_info *map) | |||
82 | 82 | ||
83 | if (ret) | 83 | if (ret) |
84 | return ret; | 84 | return ret; |
85 | 85 | ||
86 | return NULL; | 86 | return NULL; |
87 | } | 87 | } |
88 | /* | 88 | /* |
diff --git a/drivers/mtd/chips/fwh_lock.h b/drivers/mtd/chips/fwh_lock.h index e1a5b76596c5..77303ce5dcf1 100644 --- a/drivers/mtd/chips/fwh_lock.h +++ b/drivers/mtd/chips/fwh_lock.h | |||
@@ -25,7 +25,7 @@ struct fwh_xxlock_thunk { | |||
25 | * so this code has not been tested with interleaved chips, | 25 | * so this code has not been tested with interleaved chips, |
26 | * and will likely fail in that context. | 26 | * and will likely fail in that context. |
27 | */ | 27 | */ |
28 | static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip, | 28 | static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip, |
29 | unsigned long adr, int len, void *thunk) | 29 | unsigned long adr, int len, void *thunk) |
30 | { | 30 | { |
31 | struct cfi_private *cfi = map->fldrv_priv; | 31 | struct cfi_private *cfi = map->fldrv_priv; |
@@ -44,7 +44,7 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip, | |||
44 | * - on 64k boundariesand | 44 | * - on 64k boundariesand |
45 | * - bit 1 set high | 45 | * - bit 1 set high |
46 | * - block lock registers are 4MiB lower - overflow subtract (danger) | 46 | * - block lock registers are 4MiB lower - overflow subtract (danger) |
47 | * | 47 | * |
48 | * The address manipulation is first done on the logical address | 48 | * The address manipulation is first done on the logical address |
49 | * which is 0 at the start of the chip, and then the offset of | 49 | * which is 0 at the start of the chip, and then the offset of |
50 | * the individual chip is addted to it. Any other order a weird | 50 | * the individual chip is addted to it. Any other order a weird |
@@ -93,7 +93,7 @@ static int fwh_unlock_varsize(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
93 | 93 | ||
94 | ret = cfi_varsize_frob(mtd, fwh_xxlock_oneblock, ofs, len, | 94 | ret = cfi_varsize_frob(mtd, fwh_xxlock_oneblock, ofs, len, |
95 | (void *)&FWH_XXLOCK_ONEBLOCK_UNLOCK); | 95 | (void *)&FWH_XXLOCK_ONEBLOCK_UNLOCK); |
96 | 96 | ||
97 | return ret; | 97 | return ret; |
98 | } | 98 | } |
99 | 99 | ||
diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c index 28807eb9fc86..41bd59d20d85 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.23 2005/08/06 04:40:41 nico Exp $ | 5 | * $Id: gen_probe.c,v 1.24 2005/11/07 11:14:23 gleixner Exp $ |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
@@ -26,7 +26,7 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp) | |||
26 | 26 | ||
27 | /* First probe the map to see if we have CFI stuff there. */ | 27 | /* First probe the map to see if we have CFI stuff there. */ |
28 | cfi = genprobe_ident_chips(map, cp); | 28 | cfi = genprobe_ident_chips(map, cp); |
29 | 29 | ||
30 | if (!cfi) | 30 | if (!cfi) |
31 | return NULL; | 31 | return NULL; |
32 | 32 | ||
@@ -36,12 +36,12 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp) | |||
36 | mtd = check_cmd_set(map, 1); /* First the primary cmdset */ | 36 | mtd = check_cmd_set(map, 1); /* First the primary cmdset */ |
37 | if (!mtd) | 37 | if (!mtd) |
38 | mtd = check_cmd_set(map, 0); /* Then the secondary */ | 38 | mtd = check_cmd_set(map, 0); /* Then the secondary */ |
39 | 39 | ||
40 | if (mtd) | 40 | if (mtd) |
41 | return mtd; | 41 | return mtd; |
42 | 42 | ||
43 | printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n"); | 43 | printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n"); |
44 | 44 | ||
45 | kfree(cfi->cfiq); | 45 | kfree(cfi->cfiq); |
46 | kfree(cfi); | 46 | kfree(cfi); |
47 | map->fldrv_priv = NULL; | 47 | map->fldrv_priv = NULL; |
@@ -60,14 +60,14 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi | |||
60 | 60 | ||
61 | memset(&cfi, 0, sizeof(cfi)); | 61 | memset(&cfi, 0, sizeof(cfi)); |
62 | 62 | ||
63 | /* Call the probetype-specific code with all permutations of | 63 | /* Call the probetype-specific code with all permutations of |
64 | interleave and device type, etc. */ | 64 | interleave and device type, etc. */ |
65 | if (!genprobe_new_chip(map, cp, &cfi)) { | 65 | if (!genprobe_new_chip(map, cp, &cfi)) { |
66 | /* The probe didn't like it */ | 66 | /* The probe didn't like it */ |
67 | printk(KERN_DEBUG "%s: Found no %s device at location zero\n", | 67 | printk(KERN_DEBUG "%s: Found no %s device at location zero\n", |
68 | cp->name, map->name); | 68 | cp->name, map->name); |
69 | return NULL; | 69 | return NULL; |
70 | } | 70 | } |
71 | 71 | ||
72 | #if 0 /* Let the CFI probe routine do this sanity check. The Intel and AMD | 72 | #if 0 /* Let the CFI probe routine do this sanity check. The Intel and AMD |
73 | probe routines won't ever return a broken CFI structure anyway, | 73 | probe routines won't ever return a broken CFI structure anyway, |
@@ -92,13 +92,13 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi | |||
92 | } else { | 92 | } else { |
93 | BUG(); | 93 | BUG(); |
94 | } | 94 | } |
95 | 95 | ||
96 | cfi.numchips = 1; | 96 | cfi.numchips = 1; |
97 | 97 | ||
98 | /* | 98 | /* |
99 | * Allocate memory for bitmap of valid chips. | 99 | * Allocate memory for bitmap of valid chips. |
100 | * Align bitmap storage size to full byte. | 100 | * Align bitmap storage size to full byte. |
101 | */ | 101 | */ |
102 | max_chips = map->size >> cfi.chipshift; | 102 | max_chips = map->size >> cfi.chipshift; |
103 | mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0); | 103 | mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0); |
104 | chip_map = kmalloc(mapsize, GFP_KERNEL); | 104 | chip_map = kmalloc(mapsize, GFP_KERNEL); |
@@ -122,7 +122,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi | |||
122 | } | 122 | } |
123 | 123 | ||
124 | /* | 124 | /* |
125 | * Now allocate the space for the structures we need to return to | 125 | * Now allocate the space for the structures we need to return to |
126 | * our caller, and copy the appropriate data into them. | 126 | * our caller, and copy the appropriate data into them. |
127 | */ | 127 | */ |
128 | 128 | ||
@@ -154,7 +154,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi | |||
154 | return retcfi; | 154 | return retcfi; |
155 | } | 155 | } |
156 | 156 | ||
157 | 157 | ||
158 | static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp, | 158 | static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp, |
159 | struct cfi_private *cfi) | 159 | struct cfi_private *cfi) |
160 | { | 160 | { |
@@ -189,7 +189,7 @@ extern cfi_cmdset_fn_t cfi_cmdset_0001; | |||
189 | extern cfi_cmdset_fn_t cfi_cmdset_0002; | 189 | extern cfi_cmdset_fn_t cfi_cmdset_0002; |
190 | extern cfi_cmdset_fn_t cfi_cmdset_0020; | 190 | extern cfi_cmdset_fn_t cfi_cmdset_0020; |
191 | 191 | ||
192 | static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map, | 192 | static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map, |
193 | int primary) | 193 | int primary) |
194 | { | 194 | { |
195 | struct cfi_private *cfi = map->fldrv_priv; | 195 | struct cfi_private *cfi = map->fldrv_priv; |
@@ -199,7 +199,7 @@ static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map, | |||
199 | cfi_cmdset_fn_t *probe_function; | 199 | cfi_cmdset_fn_t *probe_function; |
200 | 200 | ||
201 | sprintf(probename, "cfi_cmdset_%4.4X", type); | 201 | sprintf(probename, "cfi_cmdset_%4.4X", type); |
202 | 202 | ||
203 | probe_function = inter_module_get_request(probename, probename); | 203 | probe_function = inter_module_get_request(probename, probename); |
204 | 204 | ||
205 | if (probe_function) { | 205 | if (probe_function) { |
@@ -221,7 +221,7 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary) | |||
221 | { | 221 | { |
222 | struct cfi_private *cfi = map->fldrv_priv; | 222 | struct cfi_private *cfi = map->fldrv_priv; |
223 | __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID; | 223 | __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID; |
224 | 224 | ||
225 | if (type == P_ID_NONE || type == P_ID_RESERVED) | 225 | if (type == P_ID_NONE || type == P_ID_RESERVED) |
226 | return NULL; | 226 | return NULL; |
227 | 227 | ||
diff --git a/drivers/mtd/chips/jedec.c b/drivers/mtd/chips/jedec.c index 4f6778f3ee3e..c40b48dabed3 100644 --- a/drivers/mtd/chips/jedec.c +++ b/drivers/mtd/chips/jedec.c | |||
@@ -1,6 +1,6 @@ | |||
1 | 1 | ||
2 | /* JEDEC Flash Interface. | 2 | /* JEDEC Flash Interface. |
3 | * This is an older type of interface for self programming flash. It is | 3 | * This is an older type of interface for self programming flash. It is |
4 | * commonly use in older AMD chips and is obsolete compared with CFI. | 4 | * commonly use in older AMD chips and is obsolete compared with CFI. |
5 | * It is called JEDEC because the JEDEC association distributes the ID codes | 5 | * It is called JEDEC because the JEDEC association distributes the ID codes |
6 | * for the chips. | 6 | * for the chips. |
@@ -88,9 +88,9 @@ static const struct JEDECTable JEDEC_table[] = { | |||
88 | 88 | ||
89 | static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id); | 89 | static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id); |
90 | static void jedec_sync(struct mtd_info *mtd) {}; | 90 | static void jedec_sync(struct mtd_info *mtd) {}; |
91 | static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, | 91 | static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, |
92 | size_t *retlen, u_char *buf); | 92 | size_t *retlen, u_char *buf); |
93 | static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, | 93 | static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, |
94 | size_t *retlen, u_char *buf); | 94 | size_t *retlen, u_char *buf); |
95 | 95 | ||
96 | static struct mtd_info *jedec_probe(struct map_info *map); | 96 | static struct mtd_info *jedec_probe(struct map_info *map); |
@@ -122,7 +122,7 @@ static struct mtd_info *jedec_probe(struct map_info *map) | |||
122 | 122 | ||
123 | memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private)); | 123 | memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private)); |
124 | priv = (struct jedec_private *)&MTD[1]; | 124 | priv = (struct jedec_private *)&MTD[1]; |
125 | 125 | ||
126 | my_bank_size = map->size; | 126 | my_bank_size = map->size; |
127 | 127 | ||
128 | if (map->size/my_bank_size > MAX_JEDEC_CHIPS) | 128 | if (map->size/my_bank_size > MAX_JEDEC_CHIPS) |
@@ -131,13 +131,13 @@ static struct mtd_info *jedec_probe(struct map_info *map) | |||
131 | kfree(MTD); | 131 | kfree(MTD); |
132 | return NULL; | 132 | return NULL; |
133 | } | 133 | } |
134 | 134 | ||
135 | for (Base = 0; Base < map->size; Base += my_bank_size) | 135 | for (Base = 0; Base < map->size; Base += my_bank_size) |
136 | { | 136 | { |
137 | // Perhaps zero could designate all tests? | 137 | // Perhaps zero could designate all tests? |
138 | if (map->buswidth == 0) | 138 | if (map->buswidth == 0) |
139 | map->buswidth = 1; | 139 | map->buswidth = 1; |
140 | 140 | ||
141 | if (map->buswidth == 1){ | 141 | if (map->buswidth == 1){ |
142 | if (jedec_probe8(map,Base,priv) == 0) { | 142 | if (jedec_probe8(map,Base,priv) == 0) { |
143 | printk("did recognize jedec chip\n"); | 143 | printk("did recognize jedec chip\n"); |
@@ -150,7 +150,7 @@ static struct mtd_info *jedec_probe(struct map_info *map) | |||
150 | if (map->buswidth == 4) | 150 | if (map->buswidth == 4) |
151 | jedec_probe32(map,Base,priv); | 151 | jedec_probe32(map,Base,priv); |
152 | } | 152 | } |
153 | 153 | ||
154 | // Get the biggest sector size | 154 | // Get the biggest sector size |
155 | SectorSize = 0; | 155 | SectorSize = 0; |
156 | for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) | 156 | for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) |
@@ -160,7 +160,7 @@ static struct mtd_info *jedec_probe(struct map_info *map) | |||
160 | if (priv->chips[I].sectorsize > SectorSize) | 160 | if (priv->chips[I].sectorsize > SectorSize) |
161 | SectorSize = priv->chips[I].sectorsize; | 161 | SectorSize = priv->chips[I].sectorsize; |
162 | } | 162 | } |
163 | 163 | ||
164 | // Quickly ensure that the other sector sizes are factors of the largest | 164 | // Quickly ensure that the other sector sizes are factors of the largest |
165 | for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) | 165 | for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) |
166 | { | 166 | { |
@@ -169,9 +169,9 @@ static struct mtd_info *jedec_probe(struct map_info *map) | |||
169 | printk("mtd: Failed. Device has incompatible mixed sector sizes\n"); | 169 | printk("mtd: Failed. Device has incompatible mixed sector sizes\n"); |
170 | kfree(MTD); | 170 | kfree(MTD); |
171 | return NULL; | 171 | return NULL; |
172 | } | 172 | } |
173 | } | 173 | } |
174 | 174 | ||
175 | /* Generate a part name that includes the number of different chips and | 175 | /* Generate a part name that includes the number of different chips and |
176 | other configuration information */ | 176 | other configuration information */ |
177 | count = 1; | 177 | count = 1; |
@@ -181,13 +181,13 @@ static struct mtd_info *jedec_probe(struct map_info *map) | |||
181 | for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) | 181 | for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) |
182 | { | 182 | { |
183 | const struct JEDECTable *JEDEC; | 183 | const struct JEDECTable *JEDEC; |
184 | 184 | ||
185 | if (priv->chips[I+1].jedec == priv->chips[I].jedec) | 185 | if (priv->chips[I+1].jedec == priv->chips[I].jedec) |
186 | { | 186 | { |
187 | count++; | 187 | count++; |
188 | continue; | 188 | continue; |
189 | } | 189 | } |
190 | 190 | ||
191 | // Locate the chip in the jedec table | 191 | // Locate the chip in the jedec table |
192 | JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec); | 192 | JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec); |
193 | if (JEDEC == 0) | 193 | if (JEDEC == 0) |
@@ -196,11 +196,11 @@ static struct mtd_info *jedec_probe(struct map_info *map) | |||
196 | kfree(MTD); | 196 | kfree(MTD); |
197 | return NULL; | 197 | return NULL; |
198 | } | 198 | } |
199 | 199 | ||
200 | if (Uniq != 0) | 200 | if (Uniq != 0) |
201 | strcat(Part,","); | 201 | strcat(Part,","); |
202 | Uniq++; | 202 | Uniq++; |
203 | 203 | ||
204 | if (count != 1) | 204 | if (count != 1) |
205 | sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name); | 205 | sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name); |
206 | else | 206 | else |
@@ -208,7 +208,7 @@ static struct mtd_info *jedec_probe(struct map_info *map) | |||
208 | if (strlen(Part) > sizeof(Part)*2/3) | 208 | if (strlen(Part) > sizeof(Part)*2/3) |
209 | break; | 209 | break; |
210 | count = 1; | 210 | count = 1; |
211 | } | 211 | } |
212 | 212 | ||
213 | /* Determine if the chips are organized in a linear fashion, or if there | 213 | /* Determine if the chips are organized in a linear fashion, or if there |
214 | are empty banks. Note, the last bank does not count here, only the | 214 | are empty banks. Note, the last bank does not count here, only the |
@@ -233,7 +233,7 @@ static struct mtd_info *jedec_probe(struct map_info *map) | |||
233 | { | 233 | { |
234 | if (priv->bank_fill[I] != my_bank_size) | 234 | if (priv->bank_fill[I] != my_bank_size) |
235 | priv->is_banked = 1; | 235 | priv->is_banked = 1; |
236 | 236 | ||
237 | /* This even could be eliminated, but new de-optimized read/write | 237 | /* This even could be eliminated, but new de-optimized read/write |
238 | functions have to be written */ | 238 | functions have to be written */ |
239 | printk("priv->bank_fill[%d] is %lx, priv->bank_fill[0] is %lx\n",I,priv->bank_fill[I],priv->bank_fill[0]); | 239 | printk("priv->bank_fill[%d] is %lx, priv->bank_fill[0] is %lx\n",I,priv->bank_fill[I],priv->bank_fill[0]); |
@@ -242,7 +242,7 @@ static struct mtd_info *jedec_probe(struct map_info *map) | |||
242 | printk("mtd: Failed. Cannot handle unsymmetric banking\n"); | 242 | printk("mtd: Failed. Cannot handle unsymmetric banking\n"); |
243 | kfree(MTD); | 243 | kfree(MTD); |
244 | return NULL; | 244 | return NULL; |
245 | } | 245 | } |
246 | } | 246 | } |
247 | } | 247 | } |
248 | } | 248 | } |
@@ -250,7 +250,7 @@ static struct mtd_info *jedec_probe(struct map_info *map) | |||
250 | strcat(Part,", banked"); | 250 | strcat(Part,", banked"); |
251 | 251 | ||
252 | // printk("Part: '%s'\n",Part); | 252 | // printk("Part: '%s'\n",Part); |
253 | 253 | ||
254 | memset(MTD,0,sizeof(*MTD)); | 254 | memset(MTD,0,sizeof(*MTD)); |
255 | // strlcpy(MTD->name,Part,sizeof(MTD->name)); | 255 | // strlcpy(MTD->name,Part,sizeof(MTD->name)); |
256 | MTD->name = map->name; | 256 | MTD->name = map->name; |
@@ -291,7 +291,7 @@ static int checkparity(u_char C) | |||
291 | 291 | ||
292 | /* Take an array of JEDEC numbers that represent interleved flash chips | 292 | /* Take an array of JEDEC numbers that represent interleved flash chips |
293 | and process them. Check to make sure they are good JEDEC numbers, look | 293 | and process them. Check to make sure they are good JEDEC numbers, look |
294 | them up and then add them to the chip list */ | 294 | them up and then add them to the chip list */ |
295 | static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count, | 295 | static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count, |
296 | unsigned long base,struct jedec_private *priv) | 296 | unsigned long base,struct jedec_private *priv) |
297 | { | 297 | { |
@@ -306,16 +306,16 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count, | |||
306 | if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0) | 306 | if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0) |
307 | return 0; | 307 | return 0; |
308 | } | 308 | } |
309 | 309 | ||
310 | // Finally, just make sure all the chip sizes are the same | 310 | // Finally, just make sure all the chip sizes are the same |
311 | JEDEC = jedec_idtoinf(Mfg[0],Id[0]); | 311 | JEDEC = jedec_idtoinf(Mfg[0],Id[0]); |
312 | 312 | ||
313 | if (JEDEC == 0) | 313 | if (JEDEC == 0) |
314 | { | 314 | { |
315 | printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]); | 315 | printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]); |
316 | return 0; | 316 | return 0; |
317 | } | 317 | } |
318 | 318 | ||
319 | Size = JEDEC->size; | 319 | Size = JEDEC->size; |
320 | SectorSize = JEDEC->sectorsize; | 320 | SectorSize = JEDEC->sectorsize; |
321 | for (I = 0; I != Count; I++) | 321 | for (I = 0; I != Count; I++) |
@@ -331,7 +331,7 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count, | |||
331 | { | 331 | { |
332 | printk("mtd: Failed. Interleved flash does not have matching characteristics\n"); | 332 | printk("mtd: Failed. Interleved flash does not have matching characteristics\n"); |
333 | return 0; | 333 | return 0; |
334 | } | 334 | } |
335 | } | 335 | } |
336 | 336 | ||
337 | // Load the Chips | 337 | // Load the Chips |
@@ -345,13 +345,13 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count, | |||
345 | { | 345 | { |
346 | printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n"); | 346 | printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n"); |
347 | return 0; | 347 | return 0; |
348 | } | 348 | } |
349 | 349 | ||
350 | // Add them to the table | 350 | // Add them to the table |
351 | for (J = 0; J != Count; J++) | 351 | for (J = 0; J != Count; J++) |
352 | { | 352 | { |
353 | unsigned long Bank; | 353 | unsigned long Bank; |
354 | 354 | ||
355 | JEDEC = jedec_idtoinf(Mfg[J],Id[J]); | 355 | JEDEC = jedec_idtoinf(Mfg[J],Id[J]); |
356 | priv->chips[I].jedec = (Mfg[J] << 8) | Id[J]; | 356 | priv->chips[I].jedec = (Mfg[J] << 8) | Id[J]; |
357 | priv->chips[I].size = JEDEC->size; | 357 | priv->chips[I].size = JEDEC->size; |
@@ -364,17 +364,17 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count, | |||
364 | // log2 n :| | 364 | // log2 n :| |
365 | priv->chips[I].addrshift = 0; | 365 | priv->chips[I].addrshift = 0; |
366 | for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++); | 366 | for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++); |
367 | 367 | ||
368 | // Determine how filled this bank is. | 368 | // Determine how filled this bank is. |
369 | Bank = base & (~(my_bank_size-1)); | 369 | Bank = base & (~(my_bank_size-1)); |
370 | if (priv->bank_fill[Bank/my_bank_size] < base + | 370 | if (priv->bank_fill[Bank/my_bank_size] < base + |
371 | (JEDEC->size << priv->chips[I].addrshift) - Bank) | 371 | (JEDEC->size << priv->chips[I].addrshift) - Bank) |
372 | priv->bank_fill[Bank/my_bank_size] = base + (JEDEC->size << priv->chips[I].addrshift) - Bank; | 372 | priv->bank_fill[Bank/my_bank_size] = base + (JEDEC->size << priv->chips[I].addrshift) - Bank; |
373 | I++; | 373 | I++; |
374 | } | 374 | } |
375 | 375 | ||
376 | priv->size += priv->chips[I-1].size*Count; | 376 | priv->size += priv->chips[I-1].size*Count; |
377 | 377 | ||
378 | return priv->chips[I-1].size; | 378 | return priv->chips[I-1].size; |
379 | } | 379 | } |
380 | 380 | ||
@@ -392,7 +392,7 @@ static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id) | |||
392 | // Look for flash using an 8 bit bus interface | 392 | // Look for flash using an 8 bit bus interface |
393 | static int jedec_probe8(struct map_info *map,unsigned long base, | 393 | static int jedec_probe8(struct map_info *map,unsigned long base, |
394 | struct jedec_private *priv) | 394 | struct jedec_private *priv) |
395 | { | 395 | { |
396 | #define flread(x) map_read8(map,base+x) | 396 | #define flread(x) map_read8(map,base+x) |
397 | #define flwrite(v,x) map_write8(map,v,base+x) | 397 | #define flwrite(v,x) map_write8(map,v,base+x) |
398 | 398 | ||
@@ -410,20 +410,20 @@ static int jedec_probe8(struct map_info *map,unsigned long base, | |||
410 | OldVal = flread(base); | 410 | OldVal = flread(base); |
411 | for (I = 0; OldVal != flread(base) && I < 10000; I++) | 411 | for (I = 0; OldVal != flread(base) && I < 10000; I++) |
412 | OldVal = flread(base); | 412 | OldVal = flread(base); |
413 | 413 | ||
414 | // Reset the chip | 414 | // Reset the chip |
415 | flwrite(Reset,0x555); | 415 | flwrite(Reset,0x555); |
416 | 416 | ||
417 | // Send the sequence | 417 | // Send the sequence |
418 | flwrite(AutoSel1,0x555); | 418 | flwrite(AutoSel1,0x555); |
419 | flwrite(AutoSel2,0x2AA); | 419 | flwrite(AutoSel2,0x2AA); |
420 | flwrite(AutoSel3,0x555); | 420 | flwrite(AutoSel3,0x555); |
421 | 421 | ||
422 | // Get the JEDEC numbers | 422 | // Get the JEDEC numbers |
423 | Mfg[0] = flread(0); | 423 | Mfg[0] = flread(0); |
424 | Id[0] = flread(1); | 424 | Id[0] = flread(1); |
425 | // printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]); | 425 | // printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]); |
426 | 426 | ||
427 | Size = handle_jedecs(map,Mfg,Id,1,base,priv); | 427 | Size = handle_jedecs(map,Mfg,Id,1,base,priv); |
428 | // printk("handle_jedecs Size is %x\n",(unsigned int)Size); | 428 | // printk("handle_jedecs Size is %x\n",(unsigned int)Size); |
429 | if (Size == 0) | 429 | if (Size == 0) |
@@ -431,13 +431,13 @@ static int jedec_probe8(struct map_info *map,unsigned long base, | |||
431 | flwrite(Reset,0x555); | 431 | flwrite(Reset,0x555); |
432 | return 0; | 432 | return 0; |
433 | } | 433 | } |
434 | 434 | ||
435 | 435 | ||
436 | // Reset. | 436 | // Reset. |
437 | flwrite(Reset,0x555); | 437 | flwrite(Reset,0x555); |
438 | 438 | ||
439 | return 1; | 439 | return 1; |
440 | 440 | ||
441 | #undef flread | 441 | #undef flread |
442 | #undef flwrite | 442 | #undef flwrite |
443 | } | 443 | } |
@@ -470,17 +470,17 @@ static int jedec_probe32(struct map_info *map,unsigned long base, | |||
470 | OldVal = flread(base); | 470 | OldVal = flread(base); |
471 | for (I = 0; OldVal != flread(base) && I < 10000; I++) | 471 | for (I = 0; OldVal != flread(base) && I < 10000; I++) |
472 | OldVal = flread(base); | 472 | OldVal = flread(base); |
473 | 473 | ||
474 | // Reset the chip | 474 | // Reset the chip |
475 | flwrite(Reset,0x555); | 475 | flwrite(Reset,0x555); |
476 | 476 | ||
477 | // Send the sequence | 477 | // Send the sequence |
478 | flwrite(AutoSel1,0x555); | 478 | flwrite(AutoSel1,0x555); |
479 | flwrite(AutoSel2,0x2AA); | 479 | flwrite(AutoSel2,0x2AA); |
480 | flwrite(AutoSel3,0x555); | 480 | flwrite(AutoSel3,0x555); |
481 | 481 | ||
482 | // Test #1, JEDEC numbers are readable from 0x??00/0x??01 | 482 | // Test #1, JEDEC numbers are readable from 0x??00/0x??01 |
483 | if (flread(0) != flread(0x100) || | 483 | if (flread(0) != flread(0x100) || |
484 | flread(1) != flread(0x101)) | 484 | flread(1) != flread(0x101)) |
485 | { | 485 | { |
486 | flwrite(Reset,0x555); | 486 | flwrite(Reset,0x555); |
@@ -494,14 +494,14 @@ static int jedec_probe32(struct map_info *map,unsigned long base, | |||
494 | OldVal = flread(1); | 494 | OldVal = flread(1); |
495 | for (I = 0; I != 4; I++) | 495 | for (I = 0; I != 4; I++) |
496 | Id[I] = (OldVal >> (I*8)); | 496 | Id[I] = (OldVal >> (I*8)); |
497 | 497 | ||
498 | Size = handle_jedecs(map,Mfg,Id,4,base,priv); | 498 | Size = handle_jedecs(map,Mfg,Id,4,base,priv); |
499 | if (Size == 0) | 499 | if (Size == 0) |
500 | { | 500 | { |
501 | flwrite(Reset,0x555); | 501 | flwrite(Reset,0x555); |
502 | return 0; | 502 | return 0; |
503 | } | 503 | } |
504 | 504 | ||
505 | /* Check if there is address wrap around within a single bank, if this | 505 | /* Check if there is address wrap around within a single bank, if this |
506 | returns JEDEC numbers then we assume that it is wrap around. Notice | 506 | returns JEDEC numbers then we assume that it is wrap around. Notice |
507 | we call this routine with the JEDEC return still enabled, if two or | 507 | we call this routine with the JEDEC return still enabled, if two or |
@@ -519,27 +519,27 @@ static int jedec_probe32(struct map_info *map,unsigned long base, | |||
519 | 519 | ||
520 | // Reset. | 520 | // Reset. |
521 | flwrite(0xF0F0F0F0,0x555); | 521 | flwrite(0xF0F0F0F0,0x555); |
522 | 522 | ||
523 | return 1; | 523 | return 1; |
524 | 524 | ||
525 | #undef flread | 525 | #undef flread |
526 | #undef flwrite | 526 | #undef flwrite |
527 | } | 527 | } |
528 | 528 | ||
529 | /* Linear read. */ | 529 | /* Linear read. */ |
530 | static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, | 530 | static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, |
531 | size_t *retlen, u_char *buf) | 531 | size_t *retlen, u_char *buf) |
532 | { | 532 | { |
533 | struct map_info *map = mtd->priv; | 533 | struct map_info *map = mtd->priv; |
534 | 534 | ||
535 | map_copy_from(map, buf, from, len); | 535 | map_copy_from(map, buf, from, len); |
536 | *retlen = len; | 536 | *retlen = len; |
537 | return 0; | 537 | return 0; |
538 | } | 538 | } |
539 | 539 | ||
540 | /* Banked read. Take special care to jump past the holes in the bank | 540 | /* Banked read. Take special care to jump past the holes in the bank |
541 | mapping. This version assumes symetry in the holes.. */ | 541 | mapping. This version assumes symetry in the holes.. */ |
542 | static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, | 542 | static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, |
543 | size_t *retlen, u_char *buf) | 543 | size_t *retlen, u_char *buf) |
544 | { | 544 | { |
545 | struct map_info *map = mtd->priv; | 545 | struct map_info *map = mtd->priv; |
@@ -555,17 +555,17 @@ static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, | |||
555 | if (priv->bank_fill[0] - offset < len) | 555 | if (priv->bank_fill[0] - offset < len) |
556 | get = priv->bank_fill[0] - offset; | 556 | get = priv->bank_fill[0] - offset; |
557 | 557 | ||
558 | bank /= priv->bank_fill[0]; | 558 | bank /= priv->bank_fill[0]; |
559 | map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get); | 559 | map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get); |
560 | 560 | ||
561 | len -= get; | 561 | len -= get; |
562 | *retlen += get; | 562 | *retlen += get; |
563 | from += get; | 563 | from += get; |
564 | } | 564 | } |
565 | return 0; | 565 | return 0; |
566 | } | 566 | } |
567 | 567 | ||
568 | /* Pass the flags value that the flash return before it re-entered read | 568 | /* Pass the flags value that the flash return before it re-entered read |
569 | mode. */ | 569 | mode. */ |
570 | static void jedec_flash_failed(unsigned char code) | 570 | static void jedec_flash_failed(unsigned char code) |
571 | { | 571 | { |
@@ -579,17 +579,17 @@ static void jedec_flash_failed(unsigned char code) | |||
579 | printk("mtd: Programming didn't take\n"); | 579 | printk("mtd: Programming didn't take\n"); |
580 | } | 580 | } |
581 | 581 | ||
582 | /* This uses the erasure function described in the AMD Flash Handbook, | 582 | /* This uses the erasure function described in the AMD Flash Handbook, |
583 | it will work for flashes with a fixed sector size only. Flashes with | 583 | it will work for flashes with a fixed sector size only. Flashes with |
584 | a selection of sector sizes (ie the AMD Am29F800B) will need a different | 584 | a selection of sector sizes (ie the AMD Am29F800B) will need a different |
585 | routine. This routine tries to parallize erasing multiple chips/sectors | 585 | routine. This routine tries to parallize erasing multiple chips/sectors |
586 | where possible */ | 586 | where possible */ |
587 | static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) | 587 | static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) |
588 | { | 588 | { |
589 | // Does IO to the currently selected chip | 589 | // Does IO to the currently selected chip |
590 | #define flread(x) map_read8(map,chip->base+((x)<<chip->addrshift)) | 590 | #define flread(x) map_read8(map,chip->base+((x)<<chip->addrshift)) |
591 | #define flwrite(v,x) map_write8(map,v,chip->base+((x)<<chip->addrshift)) | 591 | #define flwrite(v,x) map_write8(map,v,chip->base+((x)<<chip->addrshift)) |
592 | 592 | ||
593 | unsigned long Time = 0; | 593 | unsigned long Time = 0; |
594 | unsigned long NoTime = 0; | 594 | unsigned long NoTime = 0; |
595 | unsigned long start = instr->addr, len = instr->len; | 595 | unsigned long start = instr->addr, len = instr->len; |
@@ -603,7 +603,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
603 | (len % mtd->erasesize) != 0 || | 603 | (len % mtd->erasesize) != 0 || |
604 | (len/mtd->erasesize) == 0) | 604 | (len/mtd->erasesize) == 0) |
605 | return -EINVAL; | 605 | return -EINVAL; |
606 | 606 | ||
607 | jedec_flash_chip_scan(priv,start,len); | 607 | jedec_flash_chip_scan(priv,start,len); |
608 | 608 | ||
609 | // Start the erase sequence on each chip | 609 | // Start the erase sequence on each chip |
@@ -611,16 +611,16 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
611 | { | 611 | { |
612 | unsigned long off; | 612 | unsigned long off; |
613 | struct jedec_flash_chip *chip = priv->chips + I; | 613 | struct jedec_flash_chip *chip = priv->chips + I; |
614 | 614 | ||
615 | if (chip->length == 0) | 615 | if (chip->length == 0) |
616 | continue; | 616 | continue; |
617 | 617 | ||
618 | if (chip->start + chip->length > chip->size) | 618 | if (chip->start + chip->length > chip->size) |
619 | { | 619 | { |
620 | printk("DIE\n"); | 620 | printk("DIE\n"); |
621 | return -EIO; | 621 | return -EIO; |
622 | } | 622 | } |
623 | 623 | ||
624 | flwrite(0xF0,chip->start + 0x555); | 624 | flwrite(0xF0,chip->start + 0x555); |
625 | flwrite(0xAA,chip->start + 0x555); | 625 | flwrite(0xAA,chip->start + 0x555); |
626 | flwrite(0x55,chip->start + 0x2AA); | 626 | flwrite(0x55,chip->start + 0x2AA); |
@@ -628,8 +628,8 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
628 | flwrite(0xAA,chip->start + 0x555); | 628 | flwrite(0xAA,chip->start + 0x555); |
629 | flwrite(0x55,chip->start + 0x2AA); | 629 | flwrite(0x55,chip->start + 0x2AA); |
630 | 630 | ||
631 | /* Once we start selecting the erase sectors the delay between each | 631 | /* Once we start selecting the erase sectors the delay between each |
632 | command must not exceed 50us or it will immediately start erasing | 632 | command must not exceed 50us or it will immediately start erasing |
633 | and ignore the other sectors */ | 633 | and ignore the other sectors */ |
634 | for (off = 0; off < len; off += chip->sectorsize) | 634 | for (off = 0; off < len; off += chip->sectorsize) |
635 | { | 635 | { |
@@ -641,19 +641,19 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
641 | { | 641 | { |
642 | printk("mtd: Ack! We timed out the erase timer!\n"); | 642 | printk("mtd: Ack! We timed out the erase timer!\n"); |
643 | return -EIO; | 643 | return -EIO; |
644 | } | 644 | } |
645 | } | 645 | } |
646 | } | 646 | } |
647 | 647 | ||
648 | /* We could split this into a timer routine and return early, performing | 648 | /* We could split this into a timer routine and return early, performing |
649 | background erasure.. Maybe later if the need warrents */ | 649 | background erasure.. Maybe later if the need warrents */ |
650 | 650 | ||
651 | /* Poll the flash for erasure completion, specs say this can take as long | 651 | /* Poll the flash for erasure completion, specs say this can take as long |
652 | as 480 seconds to do all the sectors (for a 2 meg flash). | 652 | as 480 seconds to do all the sectors (for a 2 meg flash). |
653 | Erasure time is dependent on chip age, temp and wear.. */ | 653 | Erasure time is dependent on chip age, temp and wear.. */ |
654 | 654 | ||
655 | /* This being a generic routine assumes a 32 bit bus. It does read32s | 655 | /* This being a generic routine assumes a 32 bit bus. It does read32s |
656 | and bundles interleved chips into the same grouping. This will work | 656 | and bundles interleved chips into the same grouping. This will work |
657 | for all bus widths */ | 657 | for all bus widths */ |
658 | Time = 0; | 658 | Time = 0; |
659 | NoTime = 0; | 659 | NoTime = 0; |
@@ -664,20 +664,20 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
664 | unsigned todo[4] = {0,0,0,0}; | 664 | unsigned todo[4] = {0,0,0,0}; |
665 | unsigned todo_left = 0; | 665 | unsigned todo_left = 0; |
666 | unsigned J; | 666 | unsigned J; |
667 | 667 | ||
668 | if (chip->length == 0) | 668 | if (chip->length == 0) |
669 | continue; | 669 | continue; |
670 | 670 | ||
671 | /* Find all chips in this data line, realistically this is all | 671 | /* Find all chips in this data line, realistically this is all |
672 | or nothing up to the interleve count */ | 672 | or nothing up to the interleve count */ |
673 | for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++) | 673 | for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++) |
674 | { | 674 | { |
675 | if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) == | 675 | if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) == |
676 | (chip->base & (~((1<<chip->addrshift)-1)))) | 676 | (chip->base & (~((1<<chip->addrshift)-1)))) |
677 | { | 677 | { |
678 | todo_left++; | 678 | todo_left++; |
679 | todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1; | 679 | todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1; |
680 | } | 680 | } |
681 | } | 681 | } |
682 | 682 | ||
683 | /* printk("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1], | 683 | /* printk("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1], |
@@ -687,7 +687,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
687 | { | 687 | { |
688 | __u32 Last[4]; | 688 | __u32 Last[4]; |
689 | unsigned long Count = 0; | 689 | unsigned long Count = 0; |
690 | 690 | ||
691 | /* During erase bit 7 is held low and bit 6 toggles, we watch this, | 691 | /* During erase bit 7 is held low and bit 6 toggles, we watch this, |
692 | should it stop toggling or go high then the erase is completed, | 692 | should it stop toggling or go high then the erase is completed, |
693 | or this is not really flash ;> */ | 693 | or this is not really flash ;> */ |
@@ -718,23 +718,23 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
718 | __u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF; | 718 | __u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF; |
719 | if (todo[J] == 0) | 719 | if (todo[J] == 0) |
720 | continue; | 720 | continue; |
721 | 721 | ||
722 | if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2) | 722 | if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2) |
723 | { | 723 | { |
724 | // printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2); | 724 | // printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2); |
725 | continue; | 725 | continue; |
726 | } | 726 | } |
727 | 727 | ||
728 | if (Byte1 == Byte2) | 728 | if (Byte1 == Byte2) |
729 | { | 729 | { |
730 | jedec_flash_failed(Byte3); | 730 | jedec_flash_failed(Byte3); |
731 | return -EIO; | 731 | return -EIO; |
732 | } | 732 | } |
733 | 733 | ||
734 | todo[J] = 0; | 734 | todo[J] = 0; |
735 | todo_left--; | 735 | todo_left--; |
736 | } | 736 | } |
737 | 737 | ||
738 | /* if (NoTime == 0) | 738 | /* if (NoTime == 0) |
739 | Time += HZ/10 - schedule_timeout(HZ/10);*/ | 739 | Time += HZ/10 - schedule_timeout(HZ/10);*/ |
740 | NoTime = 0; | 740 | NoTime = 0; |
@@ -751,7 +751,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
751 | break; | 751 | break; |
752 | } | 752 | } |
753 | Count++; | 753 | Count++; |
754 | 754 | ||
755 | /* // Count time, max of 15s per sector (according to AMD) | 755 | /* // Count time, max of 15s per sector (according to AMD) |
756 | if (Time > 15*len/mtd->erasesize*HZ) | 756 | if (Time > 15*len/mtd->erasesize*HZ) |
757 | { | 757 | { |
@@ -759,38 +759,38 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
759 | return -EIO; | 759 | return -EIO; |
760 | } */ | 760 | } */ |
761 | } | 761 | } |
762 | 762 | ||
763 | // Skip to the next chip if we used chip erase | 763 | // Skip to the next chip if we used chip erase |
764 | if (chip->length == chip->size) | 764 | if (chip->length == chip->size) |
765 | off = chip->size; | 765 | off = chip->size; |
766 | else | 766 | else |
767 | off += chip->sectorsize; | 767 | off += chip->sectorsize; |
768 | 768 | ||
769 | if (off >= chip->length) | 769 | if (off >= chip->length) |
770 | break; | 770 | break; |
771 | NoTime = 1; | 771 | NoTime = 1; |
772 | } | 772 | } |
773 | 773 | ||
774 | for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++) | 774 | for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++) |
775 | { | 775 | { |
776 | if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) == | 776 | if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) == |
777 | (chip->base & (~((1<<chip->addrshift)-1)))) | 777 | (chip->base & (~((1<<chip->addrshift)-1)))) |
778 | priv->chips[J].length = 0; | 778 | priv->chips[J].length = 0; |
779 | } | 779 | } |
780 | } | 780 | } |
781 | 781 | ||
782 | //printk("done\n"); | 782 | //printk("done\n"); |
783 | instr->state = MTD_ERASE_DONE; | 783 | instr->state = MTD_ERASE_DONE; |
784 | mtd_erase_callback(instr); | 784 | mtd_erase_callback(instr); |
785 | return 0; | 785 | return 0; |
786 | 786 | ||
787 | #undef flread | 787 | #undef flread |
788 | #undef flwrite | 788 | #undef flwrite |
789 | } | 789 | } |
790 | 790 | ||
791 | /* This is the simple flash writing function. It writes to every byte, in | 791 | /* This is the simple flash writing function. It writes to every byte, in |
792 | sequence. It takes care of how to properly address the flash if | 792 | sequence. It takes care of how to properly address the flash if |
793 | the flash is interleved. It can only be used if all the chips in the | 793 | the flash is interleved. It can only be used if all the chips in the |
794 | array are identical!*/ | 794 | array are identical!*/ |
795 | static int flash_write(struct mtd_info *mtd, loff_t start, size_t len, | 795 | static int flash_write(struct mtd_info *mtd, loff_t start, size_t len, |
796 | size_t *retlen, const u_char *buf) | 796 | size_t *retlen, const u_char *buf) |
@@ -800,25 +800,25 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len, | |||
800 | of addrshift (interleave index) and then adds the control register index. */ | 800 | of addrshift (interleave index) and then adds the control register index. */ |
801 | #define flread(x) map_read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift)) | 801 | #define flread(x) map_read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift)) |
802 | #define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift)) | 802 | #define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift)) |
803 | 803 | ||
804 | struct map_info *map = mtd->priv; | 804 | struct map_info *map = mtd->priv; |
805 | struct jedec_private *priv = map->fldrv_priv; | 805 | struct jedec_private *priv = map->fldrv_priv; |
806 | unsigned long base; | 806 | unsigned long base; |
807 | unsigned long off; | 807 | unsigned long off; |
808 | size_t save_len = len; | 808 | size_t save_len = len; |
809 | 809 | ||
810 | if (start + len > mtd->size) | 810 | if (start + len > mtd->size) |
811 | return -EIO; | 811 | return -EIO; |
812 | 812 | ||
813 | //printk("Here"); | 813 | //printk("Here"); |
814 | 814 | ||
815 | //printk("flash_write: start is %x, len is %x\n",start,(unsigned long)len); | 815 | //printk("flash_write: start is %x, len is %x\n",start,(unsigned long)len); |
816 | while (len != 0) | 816 | while (len != 0) |
817 | { | 817 | { |
818 | struct jedec_flash_chip *chip = priv->chips; | 818 | struct jedec_flash_chip *chip = priv->chips; |
819 | unsigned long bank; | 819 | unsigned long bank; |
820 | unsigned long boffset; | 820 | unsigned long boffset; |
821 | 821 | ||
822 | // Compute the base of the flash. | 822 | // Compute the base of the flash. |
823 | off = ((unsigned long)start) % (chip->size << chip->addrshift); | 823 | off = ((unsigned long)start) % (chip->size << chip->addrshift); |
824 | base = start - off; | 824 | base = start - off; |
@@ -828,10 +828,10 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len, | |||
828 | boffset = base & (priv->bank_fill[0]-1); | 828 | boffset = base & (priv->bank_fill[0]-1); |
829 | bank = (bank/priv->bank_fill[0])*my_bank_size; | 829 | bank = (bank/priv->bank_fill[0])*my_bank_size; |
830 | base = bank + boffset; | 830 | base = bank + boffset; |
831 | 831 | ||
832 | // printk("Flasing %X %X %X\n",base,chip->size,len); | 832 | // printk("Flasing %X %X %X\n",base,chip->size,len); |
833 | // printk("off is %x, compare with %x\n",off,chip->size << chip->addrshift); | 833 | // printk("off is %x, compare with %x\n",off,chip->size << chip->addrshift); |
834 | 834 | ||
835 | // Loop over this page | 835 | // Loop over this page |
836 | for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++) | 836 | for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++) |
837 | { | 837 | { |
@@ -845,7 +845,7 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len, | |||
845 | } | 845 | } |
846 | if (((~oldbyte) & *buf) != 0) | 846 | if (((~oldbyte) & *buf) != 0) |
847 | printk("mtd: warn: Trying to set a 0 to a 1\n"); | 847 | printk("mtd: warn: Trying to set a 0 to a 1\n"); |
848 | 848 | ||
849 | // Write | 849 | // Write |
850 | flwrite(0xAA,0x555); | 850 | flwrite(0xAA,0x555); |
851 | flwrite(0x55,0x2AA); | 851 | flwrite(0x55,0x2AA); |
@@ -854,10 +854,10 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len, | |||
854 | Last[0] = map_read8(map,base + off); | 854 | Last[0] = map_read8(map,base + off); |
855 | Last[1] = map_read8(map,base + off); | 855 | Last[1] = map_read8(map,base + off); |
856 | Last[2] = map_read8(map,base + off); | 856 | Last[2] = map_read8(map,base + off); |
857 | 857 | ||
858 | /* Wait for the flash to finish the operation. We store the last 4 | 858 | /* Wait for the flash to finish the operation. We store the last 4 |
859 | status bytes that have been retrieved so we can determine why | 859 | status bytes that have been retrieved so we can determine why |
860 | it failed. The toggle bits keep toggling when there is a | 860 | it failed. The toggle bits keep toggling when there is a |
861 | failure */ | 861 | failure */ |
862 | for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && | 862 | for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && |
863 | Count < 10000; Count++) | 863 | Count < 10000; Count++) |
@@ -866,7 +866,7 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len, | |||
866 | { | 866 | { |
867 | jedec_flash_failed(Last[(Count - 3) % 4]); | 867 | jedec_flash_failed(Last[(Count - 3) % 4]); |
868 | return -EIO; | 868 | return -EIO; |
869 | } | 869 | } |
870 | } | 870 | } |
871 | } | 871 | } |
872 | *retlen = save_len; | 872 | *retlen = save_len; |
@@ -885,24 +885,24 @@ static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start | |||
885 | // Zero the records | 885 | // Zero the records |
886 | for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) | 886 | for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) |
887 | priv->chips[I].start = priv->chips[I].length = 0; | 887 | priv->chips[I].start = priv->chips[I].length = 0; |
888 | 888 | ||
889 | // Intersect the region with each chip | 889 | // Intersect the region with each chip |
890 | for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) | 890 | for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) |
891 | { | 891 | { |
892 | struct jedec_flash_chip *chip = priv->chips + I; | 892 | struct jedec_flash_chip *chip = priv->chips + I; |
893 | unsigned long ByteStart; | 893 | unsigned long ByteStart; |
894 | unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift); | 894 | unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift); |
895 | 895 | ||
896 | // End is before this chip or the start is after it | 896 | // End is before this chip or the start is after it |
897 | if (start+len < chip->offset || | 897 | if (start+len < chip->offset || |
898 | ChipEndByte - (1 << chip->addrshift) < start) | 898 | ChipEndByte - (1 << chip->addrshift) < start) |
899 | continue; | 899 | continue; |
900 | 900 | ||
901 | if (start < chip->offset) | 901 | if (start < chip->offset) |
902 | { | 902 | { |
903 | ByteStart = chip->offset; | 903 | ByteStart = chip->offset; |
904 | chip->start = 0; | 904 | chip->start = 0; |
905 | } | 905 | } |
906 | else | 906 | else |
907 | { | 907 | { |
908 | chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift; | 908 | chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift; |
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index 30da428eb7b9..edb306c03c0a 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.63 2005/02/14 16:30:32 bjd Exp $ | 4 | $Id: jedec_probe.c,v 1.66 2005/11/07 11:14:23 gleixner Exp $ |
5 | See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5) | 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 | ||
@@ -1719,7 +1719,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, | |||
1719 | 1719 | ||
1720 | static struct mtd_info *jedec_probe(struct map_info *map); | 1720 | static struct mtd_info *jedec_probe(struct map_info *map); |
1721 | 1721 | ||
1722 | static inline u32 jedec_read_mfr(struct map_info *map, __u32 base, | 1722 | static inline u32 jedec_read_mfr(struct map_info *map, __u32 base, |
1723 | struct cfi_private *cfi) | 1723 | struct cfi_private *cfi) |
1724 | { | 1724 | { |
1725 | map_word result; | 1725 | map_word result; |
@@ -1730,7 +1730,7 @@ static inline u32 jedec_read_mfr(struct map_info *map, __u32 base, | |||
1730 | return result.x[0] & mask; | 1730 | return result.x[0] & mask; |
1731 | } | 1731 | } |
1732 | 1732 | ||
1733 | static inline u32 jedec_read_id(struct map_info *map, __u32 base, | 1733 | static inline u32 jedec_read_id(struct map_info *map, __u32 base, |
1734 | struct cfi_private *cfi) | 1734 | struct cfi_private *cfi) |
1735 | { | 1735 | { |
1736 | map_word result; | 1736 | map_word result; |
@@ -1741,7 +1741,7 @@ static inline u32 jedec_read_id(struct map_info *map, __u32 base, | |||
1741 | return result.x[0] & mask; | 1741 | return result.x[0] & mask; |
1742 | } | 1742 | } |
1743 | 1743 | ||
1744 | static inline void jedec_reset(u32 base, struct map_info *map, | 1744 | static inline void jedec_reset(u32 base, struct map_info *map, |
1745 | struct cfi_private *cfi) | 1745 | struct cfi_private *cfi) |
1746 | { | 1746 | { |
1747 | /* Reset */ | 1747 | /* Reset */ |
@@ -1765,7 +1765,7 @@ static inline void jedec_reset(u32 base, struct map_info *map, | |||
1765 | * so ensure we're in read mode. Send both the Intel and the AMD command | 1765 | * so ensure we're in read mode. Send both the Intel and the AMD command |
1766 | * for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so | 1766 | * for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so |
1767 | * this should be safe. | 1767 | * this should be safe. |
1768 | */ | 1768 | */ |
1769 | cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); | 1769 | cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); |
1770 | /* FIXME - should have reset delay before continuing */ | 1770 | /* FIXME - should have reset delay before continuing */ |
1771 | } | 1771 | } |
@@ -1807,14 +1807,14 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index) | |||
1807 | printk("Found: %s\n",jedec_table[index].name); | 1807 | printk("Found: %s\n",jedec_table[index].name); |
1808 | 1808 | ||
1809 | num_erase_regions = jedec_table[index].NumEraseRegions; | 1809 | num_erase_regions = jedec_table[index].NumEraseRegions; |
1810 | 1810 | ||
1811 | p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL); | 1811 | p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL); |
1812 | if (!p_cfi->cfiq) { | 1812 | if (!p_cfi->cfiq) { |
1813 | //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); | 1813 | //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); |
1814 | return 0; | 1814 | return 0; |
1815 | } | 1815 | } |
1816 | 1816 | ||
1817 | memset(p_cfi->cfiq,0,sizeof(struct cfi_ident)); | 1817 | memset(p_cfi->cfiq,0,sizeof(struct cfi_ident)); |
1818 | 1818 | ||
1819 | p_cfi->cfiq->P_ID = jedec_table[index].CmdSet; | 1819 | p_cfi->cfiq->P_ID = jedec_table[index].CmdSet; |
1820 | p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions; | 1820 | p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions; |
@@ -1969,7 +1969,7 @@ static inline int jedec_match( __u32 base, | |||
1969 | cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); | 1969 | cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); |
1970 | /* FIXME - should have a delay before continuing */ | 1970 | /* FIXME - should have a delay before continuing */ |
1971 | 1971 | ||
1972 | match_done: | 1972 | match_done: |
1973 | return rc; | 1973 | return rc; |
1974 | } | 1974 | } |
1975 | 1975 | ||
@@ -1998,23 +1998,23 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, | |||
1998 | "Probe at base(0x%08x) past the end of the map(0x%08lx)\n", | 1998 | "Probe at base(0x%08x) past the end of the map(0x%08lx)\n", |
1999 | base, map->size -1); | 1999 | base, map->size -1); |
2000 | return 0; | 2000 | return 0; |
2001 | 2001 | ||
2002 | } | 2002 | } |
2003 | /* Ensure the unlock addresses we try stay inside the map */ | 2003 | /* Ensure the unlock addresses we try stay inside the map */ |
2004 | probe_offset1 = cfi_build_cmd_addr( | 2004 | probe_offset1 = cfi_build_cmd_addr( |
2005 | cfi->addr_unlock1, | 2005 | cfi->addr_unlock1, |
2006 | cfi_interleave(cfi), | 2006 | cfi_interleave(cfi), |
2007 | cfi->device_type); | 2007 | cfi->device_type); |
2008 | probe_offset2 = cfi_build_cmd_addr( | 2008 | probe_offset2 = cfi_build_cmd_addr( |
2009 | cfi->addr_unlock1, | 2009 | cfi->addr_unlock1, |
2010 | cfi_interleave(cfi), | 2010 | cfi_interleave(cfi), |
2011 | cfi->device_type); | 2011 | cfi->device_type); |
2012 | if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) || | 2012 | if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) || |
2013 | ((base + probe_offset2 + map_bankwidth(map)) >= map->size)) | 2013 | ((base + probe_offset2 + map_bankwidth(map)) >= map->size)) |
2014 | { | 2014 | { |
2015 | goto retry; | 2015 | goto retry; |
2016 | } | 2016 | } |
2017 | 2017 | ||
2018 | /* Reset */ | 2018 | /* Reset */ |
2019 | jedec_reset(base, map, cfi); | 2019 | jedec_reset(base, map, cfi); |
2020 | 2020 | ||
@@ -2027,13 +2027,13 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, | |||
2027 | /* FIXME - should have a delay before continuing */ | 2027 | /* FIXME - should have a delay before continuing */ |
2028 | 2028 | ||
2029 | if (!cfi->numchips) { | 2029 | if (!cfi->numchips) { |
2030 | /* This is the first time we're called. Set up the CFI | 2030 | /* This is the first time we're called. Set up the CFI |
2031 | stuff accordingly and return */ | 2031 | stuff accordingly and return */ |
2032 | 2032 | ||
2033 | cfi->mfr = jedec_read_mfr(map, base, cfi); | 2033 | cfi->mfr = jedec_read_mfr(map, base, cfi); |
2034 | cfi->id = jedec_read_id(map, base, cfi); | 2034 | cfi->id = jedec_read_id(map, base, cfi); |
2035 | DEBUG(MTD_DEBUG_LEVEL3, | 2035 | DEBUG(MTD_DEBUG_LEVEL3, |
2036 | "Search for id:(%02x %02x) interleave(%d) type(%d)\n", | 2036 | "Search for id:(%02x %02x) interleave(%d) type(%d)\n", |
2037 | cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type); | 2037 | cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type); |
2038 | for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) { | 2038 | for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) { |
2039 | if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) { | 2039 | if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) { |
@@ -2062,7 +2062,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, | |||
2062 | return 0; | 2062 | return 0; |
2063 | } | 2063 | } |
2064 | } | 2064 | } |
2065 | 2065 | ||
2066 | /* Check each previous chip locations to see if it's an alias */ | 2066 | /* Check each previous chip locations to see if it's an alias */ |
2067 | for (i=0; i < (base >> cfi->chipshift); i++) { | 2067 | for (i=0; i < (base >> cfi->chipshift); i++) { |
2068 | unsigned long start; | 2068 | unsigned long start; |
@@ -2083,7 +2083,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, | |||
2083 | map->name, base, start); | 2083 | map->name, base, start); |
2084 | return 0; | 2084 | return 0; |
2085 | } | 2085 | } |
2086 | 2086 | ||
2087 | /* Yes, it's actually got the device IDs as data. Most | 2087 | /* Yes, it's actually got the device IDs as data. Most |
2088 | * unfortunate. Stick the new chip in read mode | 2088 | * unfortunate. Stick the new chip in read mode |
2089 | * too and if it's the same, assume it's an alias. */ | 2089 | * too and if it's the same, assume it's an alias. */ |
@@ -2097,20 +2097,20 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, | |||
2097 | } | 2097 | } |
2098 | } | 2098 | } |
2099 | } | 2099 | } |
2100 | 2100 | ||
2101 | /* OK, if we got to here, then none of the previous chips appear to | 2101 | /* OK, if we got to here, then none of the previous chips appear to |
2102 | be aliases for the current one. */ | 2102 | be aliases for the current one. */ |
2103 | set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */ | 2103 | set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */ |
2104 | cfi->numchips++; | 2104 | cfi->numchips++; |
2105 | 2105 | ||
2106 | ok_out: | 2106 | ok_out: |
2107 | /* Put it back into Read Mode */ | 2107 | /* Put it back into Read Mode */ |
2108 | jedec_reset(base, map, cfi); | 2108 | jedec_reset(base, map, cfi); |
2109 | 2109 | ||
2110 | printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", | 2110 | printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", |
2111 | map->name, cfi_interleave(cfi), cfi->device_type*8, base, | 2111 | map->name, cfi_interleave(cfi), cfi->device_type*8, base, |
2112 | map->bankwidth*8); | 2112 | map->bankwidth*8); |
2113 | 2113 | ||
2114 | return 1; | 2114 | return 1; |
2115 | } | 2115 | } |
2116 | 2116 | ||
diff --git a/drivers/mtd/chips/map_absent.c b/drivers/mtd/chips/map_absent.c index c6c83833cc32..a611de9b1515 100644 --- a/drivers/mtd/chips/map_absent.c +++ b/drivers/mtd/chips/map_absent.c | |||
@@ -1,11 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * Common code to handle absent "placeholder" devices | 2 | * Common code to handle absent "placeholder" devices |
3 | * Copyright 2001 Resilience Corporation <ebrower@resilience.com> | 3 | * Copyright 2001 Resilience Corporation <ebrower@resilience.com> |
4 | * $Id: map_absent.c,v 1.5 2004/11/16 18:29:00 dwmw2 Exp $ | 4 | * $Id: map_absent.c,v 1.6 2005/11/07 11:14:23 gleixner Exp $ |
5 | * | 5 | * |
6 | * This map driver is used to allocate "placeholder" MTD | 6 | * This map driver is used to allocate "placeholder" MTD |
7 | * devices on systems that have socketed/removable media. | 7 | * devices on systems that have socketed/removable media. |
8 | * Use of this driver as a fallback preserves the expected | 8 | * Use of this driver as a fallback preserves the expected |
9 | * registration of MTD device nodes regardless of probe outcome. | 9 | * registration of MTD device nodes regardless of probe outcome. |
10 | * A usage example is as follows: | 10 | * A usage example is as follows: |
11 | * | 11 | * |
@@ -80,7 +80,7 @@ static int map_absent_read(struct mtd_info *mtd, loff_t from, size_t len, size_t | |||
80 | static int map_absent_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) | 80 | static int map_absent_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) |
81 | { | 81 | { |
82 | *retlen = 0; | 82 | *retlen = 0; |
83 | return -ENODEV; | 83 | return -ENODEV; |
84 | } | 84 | } |
85 | 85 | ||
86 | static int map_absent_erase(struct mtd_info *mtd, struct erase_info *instr) | 86 | static int map_absent_erase(struct mtd_info *mtd, struct erase_info *instr) |
diff --git a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c index 08376dbf5d62..2d26bdef82d5 100644 --- a/drivers/mtd/chips/sharp.c +++ b/drivers/mtd/chips/sharp.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright 2000,2001 David A. Schleef <ds@schleef.org> | 4 | * Copyright 2000,2001 David A. Schleef <ds@schleef.org> |
5 | * 2000,2001 Lineo, Inc. | 5 | * 2000,2001 Lineo, Inc. |
6 | * | 6 | * |
7 | * $Id: sharp.c,v 1.15 2005/08/02 20:36:05 tpoynor Exp $ | 7 | * $Id: sharp.c,v 1.16 2005/11/07 11:14:23 gleixner Exp $ |
8 | * | 8 | * |
9 | * Devices supported: | 9 | * Devices supported: |
10 | * LH28F016SCT Symmetrical block flash memory, 2Mx8 | 10 | * LH28F016SCT Symmetrical block flash memory, 2Mx8 |
@@ -459,12 +459,12 @@ static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip, | |||
459 | remove_wait_queue(&chip->wq, &wait); | 459 | remove_wait_queue(&chip->wq, &wait); |
460 | 460 | ||
461 | //spin_lock_bh(chip->mutex); | 461 | //spin_lock_bh(chip->mutex); |
462 | 462 | ||
463 | if (signal_pending(current)){ | 463 | if (signal_pending(current)){ |
464 | ret = -EINTR; | 464 | ret = -EINTR; |
465 | goto out; | 465 | goto out; |
466 | } | 466 | } |
467 | 467 | ||
468 | } | 468 | } |
469 | ret = -ETIME; | 469 | ret = -ETIME; |
470 | out: | 470 | out: |
@@ -563,7 +563,7 @@ static int sharp_suspend(struct mtd_info *mtd) | |||
563 | static void sharp_resume(struct mtd_info *mtd) | 563 | static void sharp_resume(struct mtd_info *mtd) |
564 | { | 564 | { |
565 | printk("sharp_resume()\n"); | 565 | printk("sharp_resume()\n"); |
566 | 566 | ||
567 | } | 567 | } |
568 | 568 | ||
569 | static void sharp_destroy(struct mtd_info *mtd) | 569 | static void sharp_destroy(struct mtd_info *mtd) |