aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/Kconfig40
-rw-r--r--drivers/mtd/Makefile5
-rw-r--r--drivers/mtd/afs.c16
-rw-r--r--drivers/mtd/chips/Kconfig22
-rw-r--r--drivers/mtd/chips/Makefile4
-rw-r--r--drivers/mtd/chips/amd_flash.c80
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c487
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c160
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0020.c183
-rw-r--r--drivers/mtd/chips/cfi_probe.c98
-rw-r--r--drivers/mtd/chips/cfi_util.c25
-rw-r--r--drivers/mtd/chips/chipreg.c6
-rw-r--r--drivers/mtd/chips/fwh_lock.h6
-rw-r--r--drivers/mtd/chips/gen_probe.c33
-rw-r--r--drivers/mtd/chips/jedec.c206
-rw-r--r--drivers/mtd/chips/jedec_probe.c48
-rw-r--r--drivers/mtd/chips/map_absent.c8
-rw-r--r--drivers/mtd/chips/sharp.c23
-rw-r--r--drivers/mtd/cmdlinepart.c56
-rw-r--r--drivers/mtd/devices/Kconfig8
-rw-r--r--drivers/mtd/devices/blkmtd.c17
-rw-r--r--drivers/mtd/devices/block2mtd.c8
-rw-r--r--drivers/mtd/devices/doc2000.c42
-rw-r--r--drivers/mtd/devices/doc2001.c24
-rw-r--r--drivers/mtd/devices/doc2001plus.c20
-rw-r--r--drivers/mtd/devices/docecc.c40
-rw-r--r--drivers/mtd/devices/docprobe.c84
-rw-r--r--drivers/mtd/devices/lart.c8
-rw-r--r--drivers/mtd/devices/phram.c14
-rw-r--r--drivers/mtd/devices/pmc551.c24
-rw-r--r--drivers/mtd/devices/slram.c30
-rw-r--r--drivers/mtd/ftl.c128
-rw-r--r--drivers/mtd/inftlcore.c60
-rw-r--r--drivers/mtd/inftlmount.c26
-rw-r--r--drivers/mtd/maps/Kconfig115
-rw-r--r--drivers/mtd/maps/Makefile7
-rw-r--r--drivers/mtd/maps/alchemy-flash.c12
-rw-r--r--drivers/mtd/maps/amd76xrom.c20
-rw-r--r--drivers/mtd/maps/arctic-mtd.c6
-rw-r--r--drivers/mtd/maps/autcpu12-nvram.c18
-rw-r--r--drivers/mtd/maps/bast-flash.c22
-rw-r--r--drivers/mtd/maps/beech-mtd.c6
-rw-r--r--drivers/mtd/maps/cdb89712.c34
-rw-r--r--drivers/mtd/maps/ceiva.c3
-rw-r--r--drivers/mtd/maps/cfi_flagadm.c12
-rw-r--r--drivers/mtd/maps/cstm_mips_ixx.c24
-rw-r--r--drivers/mtd/maps/dbox2-flash.c38
-rw-r--r--drivers/mtd/maps/dc21285.c34
-rw-r--r--drivers/mtd/maps/dilnetpc.c32
-rw-r--r--drivers/mtd/maps/dmv182.c8
-rw-r--r--drivers/mtd/maps/ebony.c6
-rw-r--r--drivers/mtd/maps/edb7312.c10
-rw-r--r--drivers/mtd/maps/epxa10db-flash.c12
-rw-r--r--drivers/mtd/maps/fortunet.c4
-rw-r--r--drivers/mtd/maps/h720x-flash.c16
-rw-r--r--drivers/mtd/maps/ichxrom.c21
-rw-r--r--drivers/mtd/maps/impa7.c16
-rw-r--r--drivers/mtd/maps/integrator-flash.c20
-rw-r--r--drivers/mtd/maps/ipaq-flash.c37
-rw-r--r--drivers/mtd/maps/iq80310.c7
-rw-r--r--drivers/mtd/maps/ixp2000.c35
-rw-r--r--drivers/mtd/maps/ixp4xx.c56
-rw-r--r--drivers/mtd/maps/l440gx.c18
-rw-r--r--drivers/mtd/maps/lubbock-flash.c17
-rw-r--r--drivers/mtd/maps/mainstone-flash.c22
-rw-r--r--drivers/mtd/maps/mbx860.c6
-rw-r--r--drivers/mtd/maps/mtx-1_flash.c96
-rw-r--r--drivers/mtd/maps/netsc520.c32
-rw-r--r--drivers/mtd/maps/nettel.c8
-rw-r--r--drivers/mtd/maps/ocelot.c10
-rw-r--r--drivers/mtd/maps/octagon-5066.c36
-rw-r--r--drivers/mtd/maps/omap-toto-flash.c23
-rw-r--r--drivers/mtd/maps/omap_nor.c2
-rw-r--r--drivers/mtd/maps/pci.c6
-rw-r--r--drivers/mtd/maps/pcmciamtd.c30
-rw-r--r--drivers/mtd/maps/physmap.c8
-rw-r--r--drivers/mtd/maps/plat-ram.c13
-rw-r--r--drivers/mtd/maps/pnc2000.c8
-rw-r--r--drivers/mtd/maps/pq2fads.c88
-rw-r--r--drivers/mtd/maps/redwood.c4
-rw-r--r--drivers/mtd/maps/sa1100-flash.c9
-rw-r--r--drivers/mtd/maps/sbc8240.c4
-rw-r--r--drivers/mtd/maps/sbc_gxx.c46
-rw-r--r--drivers/mtd/maps/sc520cdp.c6
-rw-r--r--drivers/mtd/maps/scx200_docflash.c46
-rw-r--r--drivers/mtd/maps/sharpsl-flash.c12
-rw-r--r--drivers/mtd/maps/solutionengine.c4
-rw-r--r--drivers/mtd/maps/sun_uflash.c16
-rw-r--r--drivers/mtd/maps/tqm834x.c291
-rw-r--r--drivers/mtd/maps/tqm8xxl.c26
-rw-r--r--drivers/mtd/maps/ts5500_flash.c44
-rw-r--r--drivers/mtd/maps/tsunami_flash.c6
-rw-r--r--drivers/mtd/maps/uclinux.c4
-rw-r--r--drivers/mtd/maps/vmax301.c24
-rw-r--r--drivers/mtd/maps/walnut.c16
-rw-r--r--drivers/mtd/maps/wr_sbc82xx_flash.c6
-rw-r--r--drivers/mtd/mtd_blkdevs.c44
-rw-r--r--drivers/mtd/mtdblock.c53
-rw-r--r--drivers/mtd/mtdchar.c86
-rw-r--r--drivers/mtd/mtdconcat.c13
-rw-r--r--drivers/mtd/mtdcore.c62
-rw-r--r--drivers/mtd/mtdpart.c99
-rw-r--r--drivers/mtd/nand/Kconfig26
-rw-r--r--drivers/mtd/nand/au1550nd.c165
-rw-r--r--drivers/mtd/nand/autcpu12.c22
-rw-r--r--drivers/mtd/nand/diskonchip.c100
-rw-r--r--drivers/mtd/nand/edb7312.c48
-rw-r--r--drivers/mtd/nand/h1910.c48
-rw-r--r--drivers/mtd/nand/nand_base.c534
-rw-r--r--drivers/mtd/nand/nand_bbt.c248
-rw-r--r--drivers/mtd/nand/nand_ecc.c44
-rw-r--r--drivers/mtd/nand/nand_ids.c30
-rw-r--r--drivers/mtd/nand/nandsim.c162
-rw-r--r--drivers/mtd/nand/ppchameleonevb.c6
-rw-r--r--drivers/mtd/nand/rtc_from4.c58
-rw-r--r--drivers/mtd/nand/s3c2410.c61
-rw-r--r--drivers/mtd/nand/sharpsl.c41
-rw-r--r--drivers/mtd/nand/spia.c6
-rw-r--r--drivers/mtd/nand/toto.c20
-rw-r--r--drivers/mtd/nftlcore.c92
-rw-r--r--drivers/mtd/nftlmount.c56
-rw-r--r--drivers/mtd/onenand/Kconfig38
-rw-r--r--drivers/mtd/onenand/Makefile11
-rw-r--r--drivers/mtd/onenand/generic.c147
-rw-r--r--drivers/mtd/onenand/onenand_base.c1588
-rw-r--r--drivers/mtd/onenand/onenand_bbt.c246
-rw-r--r--drivers/mtd/redboot.c4
-rw-r--r--drivers/mtd/rfd_ftl.c855
128 files changed, 6080 insertions, 2590 deletions
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 027054dea032..f6b775e63ac8 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -1,4 +1,4 @@
1# $Id: Kconfig,v 1.7 2004/11/22 11:33:56 ijc Exp $ 1# $Id: Kconfig,v 1.11 2005/11/07 11:14:19 gleixner Exp $
2 2
3menu "Memory Technology Devices (MTD)" 3menu "Memory Technology Devices (MTD)"
4 4
@@ -10,7 +10,7 @@ config MTD
10 will provide the generic support for MTD drivers to register 10 will provide the generic support for MTD drivers to register
11 themselves with the kernel and for potential users of MTD devices 11 themselves with the kernel and for potential users of MTD devices
12 to enumerate the devices which are present and obtain a handle on 12 to enumerate the devices which are present and obtain a handle on
13 them. It will also allow you to select individual drivers for 13 them. It will also allow you to select individual drivers for
14 particular hardware and users of MTD devices. If unsure, say N. 14 particular hardware and users of MTD devices. If unsure, say N.
15 15
16config MTD_DEBUG 16config MTD_DEBUG
@@ -61,11 +61,11 @@ config MTD_REDBOOT_PARTS
61 61
62 If you need code which can detect and parse this table, and register 62 If you need code which can detect and parse this table, and register
63 MTD 'partitions' corresponding to each image in the table, enable 63 MTD 'partitions' corresponding to each image in the table, enable
64 this option. 64 this option.
65 65
66 You will still need the parsing functions to be called by the driver 66 You will still need the parsing functions to be called by the driver
67 for your particular device. It won't happen automatically. The 67 for your particular device. It won't happen automatically. The
68 SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for 68 SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
69 example. 69 example.
70 70
71config MTD_REDBOOT_DIRECTORY_BLOCK 71config MTD_REDBOOT_DIRECTORY_BLOCK
@@ -81,10 +81,10 @@ config MTD_REDBOOT_DIRECTORY_BLOCK
81 partition table. A zero or positive value gives an absolete 81 partition table. A zero or positive value gives an absolete
82 erase block number. A negative value specifies a number of 82 erase block number. A negative value specifies a number of
83 sectors before the end of the device. 83 sectors before the end of the device.
84 84
85 For example "2" means block number 2, "-1" means the last 85 For example "2" means block number 2, "-1" means the last
86 block and "-2" means the penultimate block. 86 block and "-2" means the penultimate block.
87 87
88config MTD_REDBOOT_PARTS_UNALLOCATED 88config MTD_REDBOOT_PARTS_UNALLOCATED
89 bool " Include unallocated flash regions" 89 bool " Include unallocated flash regions"
90 depends on MTD_REDBOOT_PARTS 90 depends on MTD_REDBOOT_PARTS
@@ -105,11 +105,11 @@ config MTD_CMDLINE_PARTS
105 ---help--- 105 ---help---
106 Allow generic configuration of the MTD paritition tables via the kernel 106 Allow generic configuration of the MTD paritition tables via the kernel
107 command line. Multiple flash resources are supported for hardware where 107 command line. Multiple flash resources are supported for hardware where
108 different kinds of flash memory are available. 108 different kinds of flash memory are available.
109 109
110 You will still need the parsing functions to be called by the driver 110 You will still need the parsing functions to be called by the driver
111 for your particular device. It won't happen automatically. The 111 for your particular device. It won't happen automatically. The
112 SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for 112 SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
113 example. 113 example.
114 114
115 The format for the command line is as follows: 115 The format for the command line is as follows:
@@ -118,12 +118,12 @@ config MTD_CMDLINE_PARTS
118 <mtddef> := <mtd-id>:<partdef>[,<partdef>] 118 <mtddef> := <mtd-id>:<partdef>[,<partdef>]
119 <partdef> := <size>[@offset][<name>][ro] 119 <partdef> := <size>[@offset][<name>][ro]
120 <mtd-id> := unique id used in mapping driver/device 120 <mtd-id> := unique id used in mapping driver/device
121 <size> := standard linux memsize OR "-" to denote all 121 <size> := standard linux memsize OR "-" to denote all
122 remaining space 122 remaining space
123 <name> := (NAME) 123 <name> := (NAME)
124 124
125 Due to the way Linux handles the command line, no spaces are 125 Due to the way Linux handles the command line, no spaces are
126 allowed in the partition definition, including mtd id's and partition 126 allowed in the partition definition, including mtd id's and partition
127 names. 127 names.
128 128
129 Examples: 129 Examples:
@@ -240,7 +240,7 @@ config INFTL
240 tristate "INFTL (Inverse NAND Flash Translation Layer) support" 240 tristate "INFTL (Inverse NAND Flash Translation Layer) support"
241 depends on MTD 241 depends on MTD
242 ---help--- 242 ---help---
243 This provides support for the Inverse NAND Flash Translation 243 This provides support for the Inverse NAND Flash Translation
244 Layer which is used on M-Systems' newer DiskOnChip devices. It 244 Layer which is used on M-Systems' newer DiskOnChip devices. It
245 uses a kind of pseudo-file system on a flash device to emulate 245 uses a kind of pseudo-file system on a flash device to emulate
246 a block device with 512-byte sectors, on top of which you put 246 a block device with 512-byte sectors, on top of which you put
@@ -253,6 +253,16 @@ config INFTL
253 permitted to copy, modify and distribute the code as you wish. Just 253 permitted to copy, modify and distribute the code as you wish. Just
254 not use it. 254 not use it.
255 255
256config RFD_FTL
257 tristate "Resident Flash Disk (Flash Translation Layer) support"
258 depends on MTD
259 ---help---
260 This provides support for the flash translation layer known
261 as the Resident Flash Disk (RFD), as used by the Embedded BIOS
262 of General Software. There is a blurb at:
263
264 http://www.gensw.com/pages/prod/bios/rfd.htm
265
256source "drivers/mtd/chips/Kconfig" 266source "drivers/mtd/chips/Kconfig"
257 267
258source "drivers/mtd/maps/Kconfig" 268source "drivers/mtd/maps/Kconfig"
@@ -261,5 +271,7 @@ source "drivers/mtd/devices/Kconfig"
261 271
262source "drivers/mtd/nand/Kconfig" 272source "drivers/mtd/nand/Kconfig"
263 273
274source "drivers/mtd/onenand/Kconfig"
275
264endmenu 276endmenu
265 277
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index e4ad588327f7..fc9374407c2b 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# Makefile for the memory technology device drivers. 2# Makefile for the memory technology device drivers.
3# 3#
4# $Id: Makefile.common,v 1.5 2004/08/10 20:51:49 dwmw2 Exp $ 4# $Id: Makefile.common,v 1.7 2005/07/11 10:39:27 gleixner Exp $
5 5
6# Core functionality. 6# Core functionality.
7mtd-y := mtdcore.o 7mtd-y := mtdcore.o
@@ -20,8 +20,9 @@ obj-$(CONFIG_MTD_BLOCK_RO) += mtdblock_ro.o mtd_blkdevs.o
20obj-$(CONFIG_FTL) += ftl.o mtd_blkdevs.o 20obj-$(CONFIG_FTL) += ftl.o mtd_blkdevs.o
21obj-$(CONFIG_NFTL) += nftl.o mtd_blkdevs.o 21obj-$(CONFIG_NFTL) += nftl.o mtd_blkdevs.o
22obj-$(CONFIG_INFTL) += inftl.o mtd_blkdevs.o 22obj-$(CONFIG_INFTL) += inftl.o mtd_blkdevs.o
23obj-$(CONFIG_RFD_FTL) += rfd_ftl.o mtd_blkdevs.o
23 24
24nftl-objs := nftlcore.o nftlmount.o 25nftl-objs := nftlcore.o nftlmount.o
25inftl-objs := inftlcore.o inftlmount.o 26inftl-objs := inftlcore.o inftlmount.o
26 27
27obj-y += chips/ maps/ devices/ nand/ 28obj-y += chips/ maps/ devices/ nand/ onenand/
diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c
index 7363e101eb0f..6a45be04564b 100644
--- a/drivers/mtd/afs.c
+++ b/drivers/mtd/afs.c
@@ -1,27 +1,27 @@
1/*====================================================================== 1/*======================================================================
2 2
3 drivers/mtd/afs.c: ARM Flash Layout/Partitioning 3 drivers/mtd/afs.c: ARM Flash Layout/Partitioning
4 4
5 Copyright (C) 2000 ARM Limited 5 Copyright (C) 2000 ARM Limited
6 6
7 This program is free software; you can redistribute it and/or modify 7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or 9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version. 10 (at your option) any later version.
11 11
12 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 15 GNU General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 20
21 This is access code for flashes using ARM's flash partitioning 21 This is access code for flashes using ARM's flash partitioning
22 standards. 22 standards.
23 23
24 $Id: afs.c,v 1.13 2004/02/27 22:09:59 rmk Exp $ 24 $Id: afs.c,v 1.15 2005/11/07 11:14:19 gleixner Exp $
25 25
26======================================================================*/ 26======================================================================*/
27 27
@@ -163,7 +163,7 @@ afs_read_iis(struct mtd_info *mtd, struct image_info_struct *iis, u_int ptr)
163 return ret; 163 return ret;
164} 164}
165 165
166static int parse_afs_partitions(struct mtd_info *mtd, 166static int parse_afs_partitions(struct mtd_info *mtd,
167 struct mtd_partition **pparts, 167 struct mtd_partition **pparts,
168 unsigned long origin) 168 unsigned long origin)
169{ 169{
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
4menu "RAM/ROM/Flash chip drivers" 4menu "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
88config MTD_MAP_BANK_WIDTH_1 88config 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
203config MTD_CFI_AMDSTD_RETRY 203config 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
243config MTD_ROM 243config 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
250config MTD_ABSENT 250config 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
291config MTD_JEDEC 291config 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
13obj-$(CONFIG_MTD) += chipreg.o 13obj-$(CONFIG_MTD) += chipreg.o
14obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o 14obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
15obj-$(CONFIG_MTD_CFI) += cfi_probe.o 15obj-$(CONFIG_MTD_CFI) += cfi_probe.o
16obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o 16obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o
17obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o 17obj-$(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
95struct amd_flash_private { 95struct 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 */
309static int probe_new_chip(struct mtd_info *mtd, __u32 base, 309static 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 0cfcd88468e0..143f01a4c170 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.178 2005/05/19 17:05:43 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.)
@@ -51,6 +51,7 @@
51static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); 51static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
52static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); 52static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
53static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); 53static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
54static int cfi_intelext_writev(struct mtd_info *, const struct kvec *, unsigned long, loff_t, size_t *);
54static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *); 55static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *);
55static void cfi_intelext_sync (struct mtd_info *); 56static void cfi_intelext_sync (struct mtd_info *);
56static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len); 57static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len);
@@ -105,6 +106,7 @@ static struct mtd_chip_driver cfi_intelext_chipdrv = {
105static void cfi_tell_features(struct cfi_pri_intelext *extp) 106static void cfi_tell_features(struct cfi_pri_intelext *extp)
106{ 107{
107 int i; 108 int i;
109 printk(" Extended Query version %c.%c\n", extp->MajorVersion, extp->MinorVersion);
108 printk(" Feature/Command Support: %4.4X\n", extp->FeatureSupport); 110 printk(" Feature/Command Support: %4.4X\n", extp->FeatureSupport);
109 printk(" - Chip Erase: %s\n", extp->FeatureSupport&1?"supported":"unsupported"); 111 printk(" - Chip Erase: %s\n", extp->FeatureSupport&1?"supported":"unsupported");
110 printk(" - Suspend Erase: %s\n", extp->FeatureSupport&2?"supported":"unsupported"); 112 printk(" - Suspend Erase: %s\n", extp->FeatureSupport&2?"supported":"unsupported");
@@ -116,36 +118,43 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
116 printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); 118 printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported");
117 printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); 119 printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported");
118 printk(" - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported"); 120 printk(" - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported");
119 for (i=10; i<32; i++) { 121 printk(" - Extended Flash Array: %s\n", extp->FeatureSupport&1024?"supported":"unsupported");
120 if (extp->FeatureSupport & (1<<i)) 122 for (i=11; i<32; i++) {
123 if (extp->FeatureSupport & (1<<i))
121 printk(" - Unknown Bit %X: supported\n", i); 124 printk(" - Unknown Bit %X: supported\n", i);
122 } 125 }
123 126
124 printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); 127 printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport);
125 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");
126 for (i=1; i<8; i++) { 129 for (i=1; i<8; i++) {
127 if (extp->SuspendCmdSupport & (1<<i)) 130 if (extp->SuspendCmdSupport & (1<<i))
128 printk(" - Unknown Bit %X: supported\n", i); 131 printk(" - Unknown Bit %X: supported\n", i);
129 } 132 }
130 133
131 printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); 134 printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask);
132 printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); 135 printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no");
133 printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); 136 printk(" - Lock-Down Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no");
134 for (i=2; i<16; i++) { 137 for (i=2; i<3; i++) {
135 if (extp->BlkStatusRegMask & (1<<i)) 138 if (extp->BlkStatusRegMask & (1<<i))
136 printk(" - Unknown Bit %X Active: yes\n",i); 139 printk(" - Unknown Bit %X Active: yes\n",i);
137 } 140 }
138 141 printk(" - EFA Lock Bit: %s\n", extp->BlkStatusRegMask&16?"yes":"no");
139 printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", 142 printk(" - EFA Lock-Down Bit: %s\n", extp->BlkStatusRegMask&32?"yes":"no");
143 for (i=6; i<16; i++) {
144 if (extp->BlkStatusRegMask & (1<<i))
145 printk(" - Unknown Bit %X Active: yes\n",i);
146 }
147
148 printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",
140 extp->VccOptimal >> 4, extp->VccOptimal & 0xf); 149 extp->VccOptimal >> 4, extp->VccOptimal & 0xf);
141 if (extp->VppOptimal) 150 if (extp->VppOptimal)
142 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",
143 extp->VppOptimal >> 4, extp->VppOptimal & 0xf); 152 extp->VppOptimal >> 4, extp->VppOptimal & 0xf);
144} 153}
145#endif 154#endif
146 155
147#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE 156#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
148/* 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 */
149static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) 158static void fixup_intel_strataflash(struct mtd_info *mtd, void* param)
150{ 159{
151 struct map_info *map = mtd->priv; 160 struct map_info *map = mtd->priv;
@@ -176,7 +185,7 @@ static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param)
176{ 185{
177 struct map_info *map = mtd->priv; 186 struct map_info *map = mtd->priv;
178 struct cfi_private *cfi = map->fldrv_priv; 187 struct cfi_private *cfi = map->fldrv_priv;
179 188
180 cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */ 189 cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */
181 cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */ 190 cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */
182} 191}
@@ -185,7 +194,7 @@ static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param)
185{ 194{
186 struct map_info *map = mtd->priv; 195 struct map_info *map = mtd->priv;
187 struct cfi_private *cfi = map->fldrv_priv; 196 struct cfi_private *cfi = map->fldrv_priv;
188 197
189 /* Note this is done after the region info is endian swapped */ 198 /* Note this is done after the region info is endian swapped */
190 cfi->cfiq->EraseRegionInfo[1] = 199 cfi->cfiq->EraseRegionInfo[1] =
191 (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e; 200 (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e;
@@ -207,12 +216,13 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param)
207 if (cfi->cfiq->BufWriteTimeoutTyp) { 216 if (cfi->cfiq->BufWriteTimeoutTyp) {
208 printk(KERN_INFO "Using buffer write method\n" ); 217 printk(KERN_INFO "Using buffer write method\n" );
209 mtd->write = cfi_intelext_write_buffers; 218 mtd->write = cfi_intelext_write_buffers;
219 mtd->writev = cfi_intelext_writev;
210 } 220 }
211} 221}
212 222
213static struct cfi_fixup cfi_fixup_table[] = { 223static struct cfi_fixup cfi_fixup_table[] = {
214#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE 224#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
215 { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL }, 225 { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL },
216#endif 226#endif
217#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND 227#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND
218 { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL }, 228 { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL },
@@ -252,12 +262,21 @@ read_pri_intelext(struct map_info *map, __u16 adr)
252 if (!extp) 262 if (!extp)
253 return NULL; 263 return NULL;
254 264
265 if (extp->MajorVersion != '1' ||
266 (extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
267 printk(KERN_ERR " Unknown Intel/Sharp Extended Query "
268 "version %c.%c.\n", extp->MajorVersion,
269 extp->MinorVersion);
270 kfree(extp);
271 return NULL;
272 }
273
255 /* Do some byteswapping if necessary */ 274 /* Do some byteswapping if necessary */
256 extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport); 275 extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport);
257 extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask); 276 extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask);
258 extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr); 277 extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr);
259 278
260 if (extp->MajorVersion == '1' && extp->MinorVersion == '3') { 279 if (extp->MajorVersion == '1' && extp->MinorVersion >= '3') {
261 unsigned int extra_size = 0; 280 unsigned int extra_size = 0;
262 int nb_parts, i; 281 int nb_parts, i;
263 282
@@ -266,7 +285,10 @@ read_pri_intelext(struct map_info *map, __u16 adr)
266 sizeof(struct cfi_intelext_otpinfo); 285 sizeof(struct cfi_intelext_otpinfo);
267 286
268 /* Burst Read info */ 287 /* Burst Read info */
269 extra_size += 6; 288 extra_size += 2;
289 if (extp_size < sizeof(*extp) + extra_size)
290 goto need_more;
291 extra_size += extp->extra[extra_size-1];
270 292
271 /* Number of hardware-partitions */ 293 /* Number of hardware-partitions */
272 extra_size += 1; 294 extra_size += 1;
@@ -274,6 +296,10 @@ read_pri_intelext(struct map_info *map, __u16 adr)
274 goto need_more; 296 goto need_more;
275 nb_parts = extp->extra[extra_size - 1]; 297 nb_parts = extp->extra[extra_size - 1];
276 298
299 /* skip the sizeof(partregion) field in CFI 1.4 */
300 if (extp->MinorVersion >= '4')
301 extra_size += 2;
302
277 for (i = 0; i < nb_parts; i++) { 303 for (i = 0; i < nb_parts; i++) {
278 struct cfi_intelext_regioninfo *rinfo; 304 struct cfi_intelext_regioninfo *rinfo;
279 rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[extra_size]; 305 rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[extra_size];
@@ -285,6 +311,9 @@ read_pri_intelext(struct map_info *map, __u16 adr)
285 * sizeof(struct cfi_intelext_blockinfo); 311 * sizeof(struct cfi_intelext_blockinfo);
286 } 312 }
287 313
314 if (extp->MinorVersion >= '4')
315 extra_size += sizeof(struct cfi_intelext_programming_regioninfo);
316
288 if (extp_size < sizeof(*extp) + extra_size) { 317 if (extp_size < sizeof(*extp) + extra_size) {
289 need_more: 318 need_more:
290 extp_size = sizeof(*extp) + extra_size; 319 extp_size = sizeof(*extp) + extra_size;
@@ -298,7 +327,7 @@ read_pri_intelext(struct map_info *map, __u16 adr)
298 goto again; 327 goto again;
299 } 328 }
300 } 329 }
301 330
302 return extp; 331 return extp;
303} 332}
304 333
@@ -339,7 +368,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
339 mtd->reboot_notifier.notifier_call = cfi_intelext_reboot; 368 mtd->reboot_notifier.notifier_call = cfi_intelext_reboot;
340 369
341 if (cfi->cfi_mode == CFI_MODE_CFI) { 370 if (cfi->cfi_mode == CFI_MODE_CFI) {
342 /* 371 /*
343 * 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
344 * routine faked a CFI structure. So we read the feature 373 * routine faked a CFI structure. So we read the feature
345 * table from it. 374 * table from it.
@@ -354,14 +383,14 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
354 } 383 }
355 384
356 /* Install our own private info structure */ 385 /* Install our own private info structure */
357 cfi->cmdset_priv = extp; 386 cfi->cmdset_priv = extp;
358 387
359 cfi_fixup(mtd, cfi_fixup_table); 388 cfi_fixup(mtd, cfi_fixup_table);
360 389
361#ifdef DEBUG_CFI_FEATURES 390#ifdef DEBUG_CFI_FEATURES
362 /* Tell the user about it in lots of lovely detail */ 391 /* Tell the user about it in lots of lovely detail */
363 cfi_tell_features(extp); 392 cfi_tell_features(extp);
364#endif 393#endif
365 394
366 if(extp->SuspendCmdSupport & 1) { 395 if(extp->SuspendCmdSupport & 1) {
367 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");
@@ -379,10 +408,10 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
379 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; 408 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
380 cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp; 409 cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
381 cfi->chips[i].ref_point_counter = 0; 410 cfi->chips[i].ref_point_counter = 0;
382 } 411 }
383 412
384 map->fldrv = &cfi_intelext_chipdrv; 413 map->fldrv = &cfi_intelext_chipdrv;
385 414
386 return cfi_intelext_setup(mtd); 415 return cfi_intelext_setup(mtd);
387} 416}
388 417
@@ -399,13 +428,13 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
399 mtd->size = devsize * cfi->numchips; 428 mtd->size = devsize * cfi->numchips;
400 429
401 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; 430 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
402 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) 431 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
403 * mtd->numeraseregions, GFP_KERNEL); 432 * mtd->numeraseregions, GFP_KERNEL);
404 if (!mtd->eraseregions) { 433 if (!mtd->eraseregions) {
405 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");
406 goto setup_err; 435 goto setup_err;
407 } 436 }
408 437
409 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { 438 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
410 unsigned long ernum, ersize; 439 unsigned long ernum, ersize;
411 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; 440 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
@@ -429,7 +458,7 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
429 } 458 }
430 459
431 for (i=0; i<mtd->numeraseregions;i++){ 460 for (i=0; i<mtd->numeraseregions;i++){
432 printk(KERN_DEBUG "%d: offset=0x%x,size=0x%x,blocks=%d\n", 461 printk(KERN_DEBUG "erase region %d: offset=0x%x,size=0x%x,blocks=%d\n",
433 i,mtd->eraseregions[i].offset, 462 i,mtd->eraseregions[i].offset,
434 mtd->eraseregions[i].erasesize, 463 mtd->eraseregions[i].erasesize,
435 mtd->eraseregions[i].numblocks); 464 mtd->eraseregions[i].numblocks);
@@ -455,8 +484,7 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
455 484
456 setup_err: 485 setup_err:
457 if(mtd) { 486 if(mtd) {
458 if(mtd->eraseregions) 487 kfree(mtd->eraseregions);
459 kfree(mtd->eraseregions);
460 kfree(mtd); 488 kfree(mtd);
461 } 489 }
462 kfree(cfi->cmdset_priv); 490 kfree(cfi->cmdset_priv);
@@ -481,7 +509,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
481 * arrangement at this point. This can be rearranged in the future 509 * arrangement at this point. This can be rearranged in the future
482 * if someone feels motivated enough. --nico 510 * if someone feels motivated enough. --nico
483 */ 511 */
484 if (extp && extp->MajorVersion == '1' && extp->MinorVersion == '3' 512 if (extp && extp->MajorVersion == '1' && extp->MinorVersion >= '3'
485 && extp->FeatureSupport & (1 << 9)) { 513 && extp->FeatureSupport & (1 << 9)) {
486 struct cfi_private *newcfi; 514 struct cfi_private *newcfi;
487 struct flchip *chip; 515 struct flchip *chip;
@@ -493,12 +521,16 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
493 sizeof(struct cfi_intelext_otpinfo); 521 sizeof(struct cfi_intelext_otpinfo);
494 522
495 /* Burst Read info */ 523 /* Burst Read info */
496 offs += 6; 524 offs += extp->extra[offs+1]+2;
497 525
498 /* Number of partition regions */ 526 /* Number of partition regions */
499 numregions = extp->extra[offs]; 527 numregions = extp->extra[offs];
500 offs += 1; 528 offs += 1;
501 529
530 /* skip the sizeof(partregion) field in CFI 1.4 */
531 if (extp->MinorVersion >= '4')
532 offs += 2;
533
502 /* Number of hardware partitions */ 534 /* Number of hardware partitions */
503 numparts = 0; 535 numparts = 0;
504 for (i = 0; i < numregions; i++) { 536 for (i = 0; i < numregions; i++) {
@@ -510,6 +542,20 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
510 sizeof(struct cfi_intelext_blockinfo); 542 sizeof(struct cfi_intelext_blockinfo);
511 } 543 }
512 544
545 /* Programming Region info */
546 if (extp->MinorVersion >= '4') {
547 struct cfi_intelext_programming_regioninfo *prinfo;
548 prinfo = (struct cfi_intelext_programming_regioninfo *)&extp->extra[offs];
549 MTD_PROGREGION_SIZE(mtd) = cfi->interleave << prinfo->ProgRegShift;
550 MTD_PROGREGION_CTRLMODE_VALID(mtd) = cfi->interleave * prinfo->ControlValid;
551 MTD_PROGREGION_CTRLMODE_INVALID(mtd) = cfi->interleave * prinfo->ControlInvalid;
552 mtd->flags |= MTD_PROGRAM_REGIONS;
553 printk(KERN_DEBUG "%s: program region size/ctrl_valid/ctrl_inval = %d/%d/%d\n",
554 map->name, MTD_PROGREGION_SIZE(mtd),
555 MTD_PROGREGION_CTRLMODE_VALID(mtd),
556 MTD_PROGREGION_CTRLMODE_INVALID(mtd));
557 }
558
513 /* 559 /*
514 * All functions below currently rely on all chips having 560 * All functions below currently rely on all chips having
515 * the same geometry so we'll just assume that all hardware 561 * the same geometry so we'll just assume that all hardware
@@ -654,8 +700,8 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
654 break; 700 break;
655 701
656 if (time_after(jiffies, timeo)) { 702 if (time_after(jiffies, timeo)) {
657 printk(KERN_ERR "Waiting for chip to be ready timed out. Status %lx\n", 703 printk(KERN_ERR "%s: Waiting for chip to be ready timed out. Status %lx\n",
658 status.x[0]); 704 map->name, status.x[0]);
659 return -EIO; 705 return -EIO;
660 } 706 }
661 spin_unlock(chip->mutex); 707 spin_unlock(chip->mutex);
@@ -664,7 +710,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
664 /* Someone else might have been playing with it. */ 710 /* Someone else might have been playing with it. */
665 goto retry; 711 goto retry;
666 } 712 }
667 713
668 case FL_READY: 714 case FL_READY:
669 case FL_CFI_QUERY: 715 case FL_CFI_QUERY:
670 case FL_JEDEC_QUERY: 716 case FL_JEDEC_QUERY:
@@ -702,8 +748,8 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
702 map_write(map, CMD(0x70), adr); 748 map_write(map, CMD(0x70), adr);
703 chip->state = FL_ERASING; 749 chip->state = FL_ERASING;
704 chip->oldstate = FL_READY; 750 chip->oldstate = FL_READY;
705 printk(KERN_ERR "Chip not ready after erase " 751 printk(KERN_ERR "%s: Chip not ready after erase "
706 "suspended: status = 0x%lx\n", status.x[0]); 752 "suspended: status = 0x%lx\n", map->name, status.x[0]);
707 return -EIO; 753 return -EIO;
708 } 754 }
709 755
@@ -783,14 +829,14 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
783 switch(chip->oldstate) { 829 switch(chip->oldstate) {
784 case FL_ERASING: 830 case FL_ERASING:
785 chip->state = chip->oldstate; 831 chip->state = chip->oldstate;
786 /* What if one interleaved chip has finished and the 832 /* What if one interleaved chip has finished and the
787 other hasn't? The old code would leave the finished 833 other hasn't? The old code would leave the finished
788 one in READY mode. That's bad, and caused -EROFS 834 one in READY mode. That's bad, and caused -EROFS
789 errors to be returned from do_erase_oneblock because 835 errors to be returned from do_erase_oneblock because
790 that's the only bit it checked for at the time. 836 that's the only bit it checked for at the time.
791 As the state machine appears to explicitly allow 837 As the state machine appears to explicitly allow
792 sending the 0x70 (Read Status) command to an erasing 838 sending the 0x70 (Read Status) command to an erasing
793 chip and expecting it to be ignored, that's what we 839 chip and expecting it to be ignored, that's what we
794 do. */ 840 do. */
795 map_write(map, CMD(0xd0), adr); 841 map_write(map, CMD(0xd0), adr);
796 map_write(map, CMD(0x70), adr); 842 map_write(map, CMD(0x70), adr);
@@ -810,7 +856,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
810 DISABLE_VPP(map); 856 DISABLE_VPP(map);
811 break; 857 break;
812 default: 858 default:
813 printk(KERN_ERR "put_chip() called with oldstate %d!!\n", chip->oldstate); 859 printk(KERN_ERR "%s: put_chip() called with oldstate %d!!\n", map->name, chip->oldstate);
814 } 860 }
815 wake_up(&chip->wq); 861 wake_up(&chip->wq);
816} 862}
@@ -1026,8 +1072,8 @@ static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t a
1026 1072
1027 adr += chip->start; 1073 adr += chip->start;
1028 1074
1029 /* Ensure cmd read/writes are aligned. */ 1075 /* Ensure cmd read/writes are aligned. */
1030 cmd_addr = adr & ~(map_bankwidth(map)-1); 1076 cmd_addr = adr & ~(map_bankwidth(map)-1);
1031 1077
1032 spin_lock(chip->mutex); 1078 spin_lock(chip->mutex);
1033 1079
@@ -1055,7 +1101,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
1055 1101
1056 if (!map->virt || (from + len > mtd->size)) 1102 if (!map->virt || (from + len > mtd->size))
1057 return -EINVAL; 1103 return -EINVAL;
1058 1104
1059 *mtdbuf = (void *)map->virt + from; 1105 *mtdbuf = (void *)map->virt + from;
1060 *retlen = 0; 1106 *retlen = 0;
1061 1107
@@ -1082,7 +1128,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
1082 1128
1083 *retlen += thislen; 1129 *retlen += thislen;
1084 len -= thislen; 1130 len -= thislen;
1085 1131
1086 ofs = 0; 1132 ofs = 0;
1087 chipnum++; 1133 chipnum++;
1088 } 1134 }
@@ -1121,7 +1167,7 @@ static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t fro
1121 if(chip->ref_point_counter == 0) 1167 if(chip->ref_point_counter == 0)
1122 chip->state = FL_READY; 1168 chip->state = FL_READY;
1123 } else 1169 } else
1124 printk(KERN_ERR "Warning: unpoint called on non pointed region\n"); /* Should this give an error? */ 1170 printk(KERN_ERR "%s: Warning: unpoint called on non pointed region\n", map->name); /* Should this give an error? */
1125 1171
1126 put_chip(map, chip, chip->start); 1172 put_chip(map, chip, chip->start);
1127 spin_unlock(chip->mutex); 1173 spin_unlock(chip->mutex);
@@ -1140,8 +1186,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
1140 1186
1141 adr += chip->start; 1187 adr += chip->start;
1142 1188
1143 /* Ensure cmd read/writes are aligned. */ 1189 /* Ensure cmd read/writes are aligned. */
1144 cmd_addr = adr & ~(map_bankwidth(map)-1); 1190 cmd_addr = adr & ~(map_bankwidth(map)-1);
1145 1191
1146 spin_lock(chip->mutex); 1192 spin_lock(chip->mutex);
1147 ret = get_chip(map, chip, cmd_addr, FL_READY); 1193 ret = get_chip(map, chip, cmd_addr, FL_READY);
@@ -1196,7 +1242,7 @@ static int cfi_intelext_read (struct mtd_info *mtd, loff_t from, size_t len, siz
1196 *retlen += thislen; 1242 *retlen += thislen;
1197 len -= thislen; 1243 len -= thislen;
1198 buf += thislen; 1244 buf += thislen;
1199 1245
1200 ofs = 0; 1246 ofs = 0;
1201 chipnum++; 1247 chipnum++;
1202 } 1248 }
@@ -1213,12 +1259,17 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1213 1259
1214 adr += chip->start; 1260 adr += chip->start;
1215 1261
1216 /* Let's determine this according to the interleave only once */ 1262 /* Let's determine those according to the interleave only once */
1217 status_OK = CMD(0x80); 1263 status_OK = CMD(0x80);
1218 switch (mode) { 1264 switch (mode) {
1219 case FL_WRITING: write_cmd = CMD(0x40); break; 1265 case FL_WRITING:
1220 case FL_OTP_WRITE: write_cmd = CMD(0xc0); break; 1266 write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0x40) : CMD(0x41);
1221 default: return -EINVAL; 1267 break;
1268 case FL_OTP_WRITE:
1269 write_cmd = CMD(0xc0);
1270 break;
1271 default:
1272 return -EINVAL;
1222 } 1273 }
1223 1274
1224 spin_lock(chip->mutex); 1275 spin_lock(chip->mutex);
@@ -1259,12 +1310,13 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1259 status = map_read(map, adr); 1310 status = map_read(map, adr);
1260 if (map_word_andequal(map, status, status_OK, status_OK)) 1311 if (map_word_andequal(map, status, status_OK, status_OK))
1261 break; 1312 break;
1262 1313
1263 /* OK Still waiting */ 1314 /* OK Still waiting */
1264 if (time_after(jiffies, timeo)) { 1315 if (time_after(jiffies, timeo)) {
1316 map_write(map, CMD(0x70), adr);
1265 chip->state = FL_STATUS; 1317 chip->state = FL_STATUS;
1266 xip_enable(map, chip, adr); 1318 xip_enable(map, chip, adr);
1267 printk(KERN_ERR "waiting for chip to be ready timed out in word write\n"); 1319 printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
1268 ret = -EIO; 1320 ret = -EIO;
1269 goto out; 1321 goto out;
1270 } 1322 }
@@ -1276,27 +1328,39 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1276 if (!z) { 1328 if (!z) {
1277 chip->word_write_time--; 1329 chip->word_write_time--;
1278 if (!chip->word_write_time) 1330 if (!chip->word_write_time)
1279 chip->word_write_time++; 1331 chip->word_write_time = 1;
1280 } 1332 }
1281 if (z > 1) 1333 if (z > 1)
1282 chip->word_write_time++; 1334 chip->word_write_time++;
1283 1335
1284 /* Done and happy. */ 1336 /* Done and happy. */
1285 chip->state = FL_STATUS; 1337 chip->state = FL_STATUS;
1286 1338
1287 /* check for lock bit */ 1339 /* check for errors */
1288 if (map_word_bitsset(map, status, CMD(0x02))) { 1340 if (map_word_bitsset(map, status, CMD(0x1a))) {
1289 /* clear status */ 1341 unsigned long chipstatus = MERGESTATUS(status);
1342
1343 /* reset status */
1290 map_write(map, CMD(0x50), adr); 1344 map_write(map, CMD(0x50), adr);
1291 /* put back into read status register mode */
1292 map_write(map, CMD(0x70), adr); 1345 map_write(map, CMD(0x70), adr);
1293 ret = -EROFS; 1346 xip_enable(map, chip, adr);
1347
1348 if (chipstatus & 0x02) {
1349 ret = -EROFS;
1350 } else if (chipstatus & 0x08) {
1351 printk(KERN_ERR "%s: word write error (bad VPP)\n", map->name);
1352 ret = -EIO;
1353 } else {
1354 printk(KERN_ERR "%s: word write error (status 0x%lx)\n", map->name, chipstatus);
1355 ret = -EINVAL;
1356 }
1357
1358 goto out;
1294 } 1359 }
1295 1360
1296 xip_enable(map, chip, adr); 1361 xip_enable(map, chip, adr);
1297 out: put_chip(map, chip, adr); 1362 out: put_chip(map, chip, adr);
1298 spin_unlock(chip->mutex); 1363 spin_unlock(chip->mutex);
1299
1300 return ret; 1364 return ret;
1301} 1365}
1302 1366
@@ -1329,7 +1393,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1329 1393
1330 ret = do_write_oneword(map, &cfi->chips[chipnum], 1394 ret = do_write_oneword(map, &cfi->chips[chipnum],
1331 bus_ofs, datum, FL_WRITING); 1395 bus_ofs, datum, FL_WRITING);
1332 if (ret) 1396 if (ret)
1333 return ret; 1397 return ret;
1334 1398
1335 len -= n; 1399 len -= n;
@@ -1338,13 +1402,13 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1338 (*retlen) += n; 1402 (*retlen) += n;
1339 1403
1340 if (ofs >> cfi->chipshift) { 1404 if (ofs >> cfi->chipshift) {
1341 chipnum ++; 1405 chipnum ++;
1342 ofs = 0; 1406 ofs = 0;
1343 if (chipnum == cfi->numchips) 1407 if (chipnum == cfi->numchips)
1344 return 0; 1408 return 0;
1345 } 1409 }
1346 } 1410 }
1347 1411
1348 while(len >= map_bankwidth(map)) { 1412 while(len >= map_bankwidth(map)) {
1349 map_word datum = map_word_load(map, buf); 1413 map_word datum = map_word_load(map, buf);
1350 1414
@@ -1359,7 +1423,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1359 len -= map_bankwidth(map); 1423 len -= map_bankwidth(map);
1360 1424
1361 if (ofs >> cfi->chipshift) { 1425 if (ofs >> cfi->chipshift) {
1362 chipnum ++; 1426 chipnum ++;
1363 ofs = 0; 1427 ofs = 0;
1364 if (chipnum == cfi->numchips) 1428 if (chipnum == cfi->numchips)
1365 return 0; 1429 return 0;
@@ -1374,9 +1438,9 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1374 1438
1375 ret = do_write_oneword(map, &cfi->chips[chipnum], 1439 ret = do_write_oneword(map, &cfi->chips[chipnum],
1376 ofs, datum, FL_WRITING); 1440 ofs, datum, FL_WRITING);
1377 if (ret) 1441 if (ret)
1378 return ret; 1442 return ret;
1379 1443
1380 (*retlen) += len; 1444 (*retlen) += len;
1381 } 1445 }
1382 1446
@@ -1384,20 +1448,24 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1384} 1448}
1385 1449
1386 1450
1387static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, 1451static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1388 unsigned long adr, const u_char *buf, int len) 1452 unsigned long adr, const struct kvec **pvec,
1453 unsigned long *pvec_seek, int len)
1389{ 1454{
1390 struct cfi_private *cfi = map->fldrv_priv; 1455 struct cfi_private *cfi = map->fldrv_priv;
1391 map_word status, status_OK; 1456 map_word status, status_OK, write_cmd, datum;
1392 unsigned long cmd_adr, timeo; 1457 unsigned long cmd_adr, timeo;
1393 int wbufsize, z, ret=0, bytes, words; 1458 int wbufsize, z, ret=0, word_gap, words;
1459 const struct kvec *vec;
1460 unsigned long vec_seek;
1394 1461
1395 wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; 1462 wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
1396 adr += chip->start; 1463 adr += chip->start;
1397 cmd_adr = adr & ~(wbufsize-1); 1464 cmd_adr = adr & ~(wbufsize-1);
1398 1465
1399 /* Let's determine this according to the interleave only once */ 1466 /* Let's determine this according to the interleave only once */
1400 status_OK = CMD(0x80); 1467 status_OK = CMD(0x80);
1468 write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0xe8) : CMD(0xe9);
1401 1469
1402 spin_lock(chip->mutex); 1470 spin_lock(chip->mutex);
1403 ret = get_chip(map, chip, cmd_adr, FL_WRITING); 1471 ret = get_chip(map, chip, cmd_adr, FL_WRITING);
@@ -1411,7 +1479,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1411 xip_disable(map, chip, cmd_adr); 1479 xip_disable(map, chip, cmd_adr);
1412 1480
1413 /* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set 1481 /* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set
1414 [...], the device will not accept any more Write to Buffer commands". 1482 [...], the device will not accept any more Write to Buffer commands".
1415 So we must check here and reset those bits if they're set. Otherwise 1483 So we must check here and reset those bits if they're set. Otherwise
1416 we're just pissing in the wind */ 1484 we're just pissing in the wind */
1417 if (chip->state != FL_STATUS) 1485 if (chip->state != FL_STATUS)
@@ -1429,7 +1497,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1429 1497
1430 z = 0; 1498 z = 0;
1431 for (;;) { 1499 for (;;) {
1432 map_write(map, CMD(0xe8), cmd_adr); 1500 map_write(map, write_cmd, cmd_adr);
1433 1501
1434 status = map_read(map, cmd_adr); 1502 status = map_read(map, cmd_adr);
1435 if (map_word_andequal(map, status, status_OK, status_OK)) 1503 if (map_word_andequal(map, status, status_OK, status_OK))
@@ -1447,41 +1515,66 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1447 map_write(map, CMD(0x50), cmd_adr); 1515 map_write(map, CMD(0x50), cmd_adr);
1448 map_write(map, CMD(0x70), cmd_adr); 1516 map_write(map, CMD(0x70), cmd_adr);
1449 xip_enable(map, chip, cmd_adr); 1517 xip_enable(map, chip, cmd_adr);
1450 printk(KERN_ERR "Chip not ready for buffer write. status = %lx, Xstatus = %lx\n", 1518 printk(KERN_ERR "%s: Chip not ready for buffer write. status = %lx, Xstatus = %lx\n",
1451 status.x[0], Xstatus.x[0]); 1519 map->name, status.x[0], Xstatus.x[0]);
1452 ret = -EIO; 1520 ret = -EIO;
1453 goto out; 1521 goto out;
1454 } 1522 }
1455 } 1523 }
1456 1524
1525 /* Figure out the number of words to write */
1526 word_gap = (-adr & (map_bankwidth(map)-1));
1527 words = (len - word_gap + map_bankwidth(map) - 1) / map_bankwidth(map);
1528 if (!word_gap) {
1529 words--;
1530 } else {
1531 word_gap = map_bankwidth(map) - word_gap;
1532 adr -= word_gap;
1533 datum = map_word_ff(map);
1534 }
1535
1457 /* Write length of data to come */ 1536 /* Write length of data to come */
1458 bytes = len & (map_bankwidth(map)-1); 1537 map_write(map, CMD(words), cmd_adr );
1459 words = len / map_bankwidth(map);
1460 map_write(map, CMD(words - !bytes), cmd_adr );
1461 1538
1462 /* Write data */ 1539 /* Write data */
1463 z = 0; 1540 vec = *pvec;
1464 while(z < words * map_bankwidth(map)) { 1541 vec_seek = *pvec_seek;
1465 map_word datum = map_word_load(map, buf); 1542 do {
1466 map_write(map, datum, adr+z); 1543 int n = map_bankwidth(map) - word_gap;
1544 if (n > vec->iov_len - vec_seek)
1545 n = vec->iov_len - vec_seek;
1546 if (n > len)
1547 n = len;
1467 1548
1468 z += map_bankwidth(map); 1549 if (!word_gap && len < map_bankwidth(map))
1469 buf += map_bankwidth(map); 1550 datum = map_word_ff(map);
1470 }
1471 1551
1472 if (bytes) { 1552 datum = map_word_load_partial(map, datum,
1473 map_word datum; 1553 vec->iov_base + vec_seek,
1554 word_gap, n);
1474 1555
1475 datum = map_word_ff(map); 1556 len -= n;
1476 datum = map_word_load_partial(map, datum, buf, 0, bytes); 1557 word_gap += n;
1477 map_write(map, datum, adr+z); 1558 if (!len || word_gap == map_bankwidth(map)) {
1478 } 1559 map_write(map, datum, adr);
1560 adr += map_bankwidth(map);
1561 word_gap = 0;
1562 }
1563
1564 vec_seek += n;
1565 if (vec_seek == vec->iov_len) {
1566 vec++;
1567 vec_seek = 0;
1568 }
1569 } while (len);
1570 *pvec = vec;
1571 *pvec_seek = vec_seek;
1479 1572
1480 /* GO GO GO */ 1573 /* GO GO GO */
1481 map_write(map, CMD(0xd0), cmd_adr); 1574 map_write(map, CMD(0xd0), cmd_adr);
1482 chip->state = FL_WRITING; 1575 chip->state = FL_WRITING;
1483 1576
1484 INVALIDATE_CACHE_UDELAY(map, chip, 1577 INVALIDATE_CACHE_UDELAY(map, chip,
1485 cmd_adr, len, 1578 cmd_adr, len,
1486 chip->buffer_write_time); 1579 chip->buffer_write_time);
1487 1580
@@ -1507,13 +1600,14 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1507 1600
1508 /* OK Still waiting */ 1601 /* OK Still waiting */
1509 if (time_after(jiffies, timeo)) { 1602 if (time_after(jiffies, timeo)) {
1603 map_write(map, CMD(0x70), cmd_adr);
1510 chip->state = FL_STATUS; 1604 chip->state = FL_STATUS;
1511 xip_enable(map, chip, cmd_adr); 1605 xip_enable(map, chip, cmd_adr);
1512 printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n"); 1606 printk(KERN_ERR "%s: buffer write error (status timeout)\n", map->name);
1513 ret = -EIO; 1607 ret = -EIO;
1514 goto out; 1608 goto out;
1515 } 1609 }
1516 1610
1517 /* Latency issues. Drop the lock, wait a while and retry */ 1611 /* Latency issues. Drop the lock, wait a while and retry */
1518 z++; 1612 z++;
1519 UDELAY(map, chip, cmd_adr, 1); 1613 UDELAY(map, chip, cmd_adr, 1);
@@ -1521,21 +1615,34 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1521 if (!z) { 1615 if (!z) {
1522 chip->buffer_write_time--; 1616 chip->buffer_write_time--;
1523 if (!chip->buffer_write_time) 1617 if (!chip->buffer_write_time)
1524 chip->buffer_write_time++; 1618 chip->buffer_write_time = 1;
1525 } 1619 }
1526 if (z > 1) 1620 if (z > 1)
1527 chip->buffer_write_time++; 1621 chip->buffer_write_time++;
1528 1622
1529 /* Done and happy. */ 1623 /* Done and happy. */
1530 chip->state = FL_STATUS; 1624 chip->state = FL_STATUS;
1531 1625
1532 /* check for lock bit */ 1626 /* check for errors */
1533 if (map_word_bitsset(map, status, CMD(0x02))) { 1627 if (map_word_bitsset(map, status, CMD(0x1a))) {
1534 /* clear status */ 1628 unsigned long chipstatus = MERGESTATUS(status);
1629
1630 /* reset status */
1535 map_write(map, CMD(0x50), cmd_adr); 1631 map_write(map, CMD(0x50), cmd_adr);
1536 /* put back into read status register mode */ 1632 map_write(map, CMD(0x70), cmd_adr);
1537 map_write(map, CMD(0x70), adr); 1633 xip_enable(map, chip, cmd_adr);
1538 ret = -EROFS; 1634
1635 if (chipstatus & 0x02) {
1636 ret = -EROFS;
1637 } else if (chipstatus & 0x08) {
1638 printk(KERN_ERR "%s: buffer write error (bad VPP)\n", map->name);
1639 ret = -EIO;
1640 } else {
1641 printk(KERN_ERR "%s: buffer write error (status 0x%lx)\n", map->name, chipstatus);
1642 ret = -EINVAL;
1643 }
1644
1645 goto out;
1539 } 1646 }
1540 1647
1541 xip_enable(map, chip, cmd_adr); 1648 xip_enable(map, chip, cmd_adr);
@@ -1544,70 +1651,65 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1544 return ret; 1651 return ret;
1545} 1652}
1546 1653
1547static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to, 1654static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs,
1548 size_t len, size_t *retlen, const u_char *buf) 1655 unsigned long count, loff_t to, size_t *retlen)
1549{ 1656{
1550 struct map_info *map = mtd->priv; 1657 struct map_info *map = mtd->priv;
1551 struct cfi_private *cfi = map->fldrv_priv; 1658 struct cfi_private *cfi = map->fldrv_priv;
1552 int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; 1659 int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
1553 int ret = 0; 1660 int ret = 0;
1554 int chipnum; 1661 int chipnum;
1555 unsigned long ofs; 1662 unsigned long ofs, vec_seek, i;
1663 size_t len = 0;
1664
1665 for (i = 0; i < count; i++)
1666 len += vecs[i].iov_len;
1556 1667
1557 *retlen = 0; 1668 *retlen = 0;
1558 if (!len) 1669 if (!len)
1559 return 0; 1670 return 0;
1560 1671
1561 chipnum = to >> cfi->chipshift; 1672 chipnum = to >> cfi->chipshift;
1562 ofs = to - (chipnum << cfi->chipshift); 1673 ofs = to - (chipnum << cfi->chipshift);
1563 1674 vec_seek = 0;
1564 /* If it's not bus-aligned, do the first word write */
1565 if (ofs & (map_bankwidth(map)-1)) {
1566 size_t local_len = (-ofs)&(map_bankwidth(map)-1);
1567 if (local_len > len)
1568 local_len = len;
1569 ret = cfi_intelext_write_words(mtd, to, local_len,
1570 retlen, buf);
1571 if (ret)
1572 return ret;
1573 ofs += local_len;
1574 buf += local_len;
1575 len -= local_len;
1576
1577 if (ofs >> cfi->chipshift) {
1578 chipnum ++;
1579 ofs = 0;
1580 if (chipnum == cfi->numchips)
1581 return 0;
1582 }
1583 }
1584 1675
1585 while(len) { 1676 do {
1586 /* We must not cross write block boundaries */ 1677 /* We must not cross write block boundaries */
1587 int size = wbufsize - (ofs & (wbufsize-1)); 1678 int size = wbufsize - (ofs & (wbufsize-1));
1588 1679
1589 if (size > len) 1680 if (size > len)
1590 size = len; 1681 size = len;
1591 ret = do_write_buffer(map, &cfi->chips[chipnum], 1682 ret = do_write_buffer(map, &cfi->chips[chipnum],
1592 ofs, buf, size); 1683 ofs, &vecs, &vec_seek, size);
1593 if (ret) 1684 if (ret)
1594 return ret; 1685 return ret;
1595 1686
1596 ofs += size; 1687 ofs += size;
1597 buf += size;
1598 (*retlen) += size; 1688 (*retlen) += size;
1599 len -= size; 1689 len -= size;
1600 1690
1601 if (ofs >> cfi->chipshift) { 1691 if (ofs >> cfi->chipshift) {
1602 chipnum ++; 1692 chipnum ++;
1603 ofs = 0; 1693 ofs = 0;
1604 if (chipnum == cfi->numchips) 1694 if (chipnum == cfi->numchips)
1605 return 0; 1695 return 0;
1606 } 1696 }
1607 } 1697 } while (len);
1698
1608 return 0; 1699 return 0;
1609} 1700}
1610 1701
1702static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to,
1703 size_t len, size_t *retlen, const u_char *buf)
1704{
1705 struct kvec vec;
1706
1707 vec.iov_base = (void *) buf;
1708 vec.iov_len = len;
1709
1710 return cfi_intelext_writev(mtd, &vec, 1, to, retlen);
1711}
1712
1611static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, 1713static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1612 unsigned long adr, int len, void *thunk) 1714 unsigned long adr, int len, void *thunk)
1613{ 1715{
@@ -1673,23 +1775,17 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1673 status = map_read(map, adr); 1775 status = map_read(map, adr);
1674 if (map_word_andequal(map, status, status_OK, status_OK)) 1776 if (map_word_andequal(map, status, status_OK, status_OK))
1675 break; 1777 break;
1676 1778
1677 /* OK Still waiting */ 1779 /* OK Still waiting */
1678 if (time_after(jiffies, timeo)) { 1780 if (time_after(jiffies, timeo)) {
1679 map_word Xstatus;
1680 map_write(map, CMD(0x70), adr); 1781 map_write(map, CMD(0x70), adr);
1681 chip->state = FL_STATUS; 1782 chip->state = FL_STATUS;
1682 Xstatus = map_read(map, adr);
1683 /* Clear status bits */
1684 map_write(map, CMD(0x50), adr);
1685 map_write(map, CMD(0x70), adr);
1686 xip_enable(map, chip, adr); 1783 xip_enable(map, chip, adr);
1687 printk(KERN_ERR "waiting for erase at %08lx to complete timed out. status = %lx, Xstatus = %lx.\n", 1784 printk(KERN_ERR "%s: block erase error: (status timeout)\n", map->name);
1688 adr, status.x[0], Xstatus.x[0]);
1689 ret = -EIO; 1785 ret = -EIO;
1690 goto out; 1786 goto out;
1691 } 1787 }
1692 1788
1693 /* Latency issues. Drop the lock, wait a while and retry */ 1789 /* Latency issues. Drop the lock, wait a while and retry */
1694 UDELAY(map, chip, adr, 1000000/HZ); 1790 UDELAY(map, chip, adr, 1000000/HZ);
1695 } 1791 }
@@ -1699,43 +1795,40 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1699 chip->state = FL_STATUS; 1795 chip->state = FL_STATUS;
1700 status = map_read(map, adr); 1796 status = map_read(map, adr);
1701 1797
1702 /* check for lock bit */ 1798 /* check for errors */
1703 if (map_word_bitsset(map, status, CMD(0x3a))) { 1799 if (map_word_bitsset(map, status, CMD(0x3a))) {
1704 unsigned long chipstatus; 1800 unsigned long chipstatus = MERGESTATUS(status);
1705 1801
1706 /* Reset the error bits */ 1802 /* Reset the error bits */
1707 map_write(map, CMD(0x50), adr); 1803 map_write(map, CMD(0x50), adr);
1708 map_write(map, CMD(0x70), adr); 1804 map_write(map, CMD(0x70), adr);
1709 xip_enable(map, chip, adr); 1805 xip_enable(map, chip, adr);
1710 1806
1711 chipstatus = MERGESTATUS(status);
1712
1713 if ((chipstatus & 0x30) == 0x30) { 1807 if ((chipstatus & 0x30) == 0x30) {
1714 printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%lx\n", chipstatus); 1808 printk(KERN_ERR "%s: block erase error: (bad command sequence, status 0x%lx)\n", map->name, chipstatus);
1715 ret = -EIO; 1809 ret = -EINVAL;
1716 } else if (chipstatus & 0x02) { 1810 } else if (chipstatus & 0x02) {
1717 /* Protection bit set */ 1811 /* Protection bit set */
1718 ret = -EROFS; 1812 ret = -EROFS;
1719 } else if (chipstatus & 0x8) { 1813 } else if (chipstatus & 0x8) {
1720 /* Voltage */ 1814 /* Voltage */
1721 printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%lx\n", chipstatus); 1815 printk(KERN_ERR "%s: block erase error: (bad VPP)\n", map->name);
1722 ret = -EIO; 1816 ret = -EIO;
1723 } else if (chipstatus & 0x20) { 1817 } else if (chipstatus & 0x20 && retries--) {
1724 if (retries--) { 1818 printk(KERN_DEBUG "block erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus);
1725 printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus); 1819 timeo = jiffies + HZ;
1726 timeo = jiffies + HZ; 1820 put_chip(map, chip, adr);
1727 put_chip(map, chip, adr); 1821 spin_unlock(chip->mutex);
1728 spin_unlock(chip->mutex); 1822 goto retry;
1729 goto retry; 1823 } else {
1730 } 1824 printk(KERN_ERR "%s: block erase failed at 0x%08lx (status 0x%lx)\n", map->name, adr, chipstatus);
1731 printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%lx\n", adr, chipstatus);
1732 ret = -EIO; 1825 ret = -EIO;
1733 } 1826 }
1734 } else { 1827
1735 xip_enable(map, chip, adr); 1828 goto out;
1736 ret = 0;
1737 } 1829 }
1738 1830
1831 xip_enable(map, chip, adr);
1739 out: put_chip(map, chip, adr); 1832 out: put_chip(map, chip, adr);
1740 spin_unlock(chip->mutex); 1833 spin_unlock(chip->mutex);
1741 return ret; 1834 return ret;
@@ -1755,7 +1848,7 @@ int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
1755 1848
1756 instr->state = MTD_ERASE_DONE; 1849 instr->state = MTD_ERASE_DONE;
1757 mtd_erase_callback(instr); 1850 mtd_erase_callback(instr);
1758 1851
1759 return 0; 1852 return 0;
1760} 1853}
1761 1854
@@ -1776,7 +1869,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
1776 if (!ret) { 1869 if (!ret) {
1777 chip->oldstate = chip->state; 1870 chip->oldstate = chip->state;
1778 chip->state = FL_SYNCING; 1871 chip->state = FL_SYNCING;
1779 /* No need to wake_up() on this state change - 1872 /* No need to wake_up() on this state change -
1780 * as the whole point is that nobody can do anything 1873 * as the whole point is that nobody can do anything
1781 * with the chip now anyway. 1874 * with the chip now anyway.
1782 */ 1875 */
@@ -1790,7 +1883,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
1790 chip = &cfi->chips[i]; 1883 chip = &cfi->chips[i];
1791 1884
1792 spin_lock(chip->mutex); 1885 spin_lock(chip->mutex);
1793 1886
1794 if (chip->state == FL_SYNCING) { 1887 if (chip->state == FL_SYNCING) {
1795 chip->state = chip->oldstate; 1888 chip->state = chip->oldstate;
1796 chip->oldstate = FL_READY; 1889 chip->oldstate = FL_READY;
@@ -1847,7 +1940,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
1847 1940
1848 ENABLE_VPP(map); 1941 ENABLE_VPP(map);
1849 xip_disable(map, chip, adr); 1942 xip_disable(map, chip, adr);
1850 1943
1851 map_write(map, CMD(0x60), adr); 1944 map_write(map, CMD(0x60), adr);
1852 if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) { 1945 if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) {
1853 map_write(map, CMD(0x01), adr); 1946 map_write(map, CMD(0x01), adr);
@@ -1875,25 +1968,22 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
1875 status = map_read(map, adr); 1968 status = map_read(map, adr);
1876 if (map_word_andequal(map, status, status_OK, status_OK)) 1969 if (map_word_andequal(map, status, status_OK, status_OK))
1877 break; 1970 break;
1878 1971
1879 /* OK Still waiting */ 1972 /* OK Still waiting */
1880 if (time_after(jiffies, timeo)) { 1973 if (time_after(jiffies, timeo)) {
1881 map_word Xstatus;
1882 map_write(map, CMD(0x70), adr); 1974 map_write(map, CMD(0x70), adr);
1883 chip->state = FL_STATUS; 1975 chip->state = FL_STATUS;
1884 Xstatus = map_read(map, adr);
1885 xip_enable(map, chip, adr); 1976 xip_enable(map, chip, adr);
1886 printk(KERN_ERR "waiting for unlock to complete timed out. status = %lx, Xstatus = %lx.\n", 1977 printk(KERN_ERR "%s: block unlock error: (status timeout)\n", map->name);
1887 status.x[0], Xstatus.x[0]);
1888 put_chip(map, chip, adr); 1978 put_chip(map, chip, adr);
1889 spin_unlock(chip->mutex); 1979 spin_unlock(chip->mutex);
1890 return -EIO; 1980 return -EIO;
1891 } 1981 }
1892 1982
1893 /* Latency issues. Drop the lock, wait a while and retry */ 1983 /* Latency issues. Drop the lock, wait a while and retry */
1894 UDELAY(map, chip, adr, 1); 1984 UDELAY(map, chip, adr, 1);
1895 } 1985 }
1896 1986
1897 /* Done and happy. */ 1987 /* Done and happy. */
1898 chip->state = FL_STATUS; 1988 chip->state = FL_STATUS;
1899 xip_enable(map, chip, adr); 1989 xip_enable(map, chip, adr);
@@ -1913,9 +2003,9 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
1913 ofs, len, 0); 2003 ofs, len, 0);
1914#endif 2004#endif
1915 2005
1916 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, 2006 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
1917 ofs, len, DO_XXLOCK_ONEBLOCK_LOCK); 2007 ofs, len, DO_XXLOCK_ONEBLOCK_LOCK);
1918 2008
1919#ifdef DEBUG_LOCK_BITS 2009#ifdef DEBUG_LOCK_BITS
1920 printk(KERN_DEBUG "%s: lock status after, ret=%d\n", 2010 printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
1921 __FUNCTION__, ret); 2011 __FUNCTION__, ret);
@@ -1939,20 +2029,20 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1939 2029
1940 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, 2030 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
1941 ofs, len, DO_XXLOCK_ONEBLOCK_UNLOCK); 2031 ofs, len, DO_XXLOCK_ONEBLOCK_UNLOCK);
1942 2032
1943#ifdef DEBUG_LOCK_BITS 2033#ifdef DEBUG_LOCK_BITS
1944 printk(KERN_DEBUG "%s: lock status after, ret=%d\n", 2034 printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
1945 __FUNCTION__, ret); 2035 __FUNCTION__, ret);
1946 cfi_varsize_frob(mtd, do_printlockstatus_oneblock, 2036 cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1947 ofs, len, 0); 2037 ofs, len, 0);
1948#endif 2038#endif
1949 2039
1950 return ret; 2040 return ret;
1951} 2041}
1952 2042
1953#ifdef CONFIG_MTD_OTP 2043#ifdef CONFIG_MTD_OTP
1954 2044
1955typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip, 2045typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip,
1956 u_long data_offset, u_char *buf, u_int size, 2046 u_long data_offset, u_char *buf, u_int size,
1957 u_long prot_offset, u_int groupno, u_int groupsize); 2047 u_long prot_offset, u_int groupno, u_int groupsize);
1958 2048
@@ -2003,7 +2093,7 @@ do_otp_write(struct map_info *map, struct flchip *chip, u_long offset,
2003 2093
2004 datum = map_word_load_partial(map, datum, buf, gap, n); 2094 datum = map_word_load_partial(map, datum, buf, gap, n);
2005 ret = do_write_oneword(map, chip, bus_ofs, datum, FL_OTP_WRITE); 2095 ret = do_write_oneword(map, chip, bus_ofs, datum, FL_OTP_WRITE);
2006 if (ret) 2096 if (ret)
2007 return ret; 2097 return ret;
2008 2098
2009 offset += n; 2099 offset += n;
@@ -2196,7 +2286,7 @@ static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
2196 NULL, do_otp_lock, 1); 2286 NULL, do_otp_lock, 1);
2197} 2287}
2198 2288
2199static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd, 2289static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd,
2200 struct otp_info *buf, size_t len) 2290 struct otp_info *buf, size_t len)
2201{ 2291{
2202 size_t retlen; 2292 size_t retlen;
@@ -2239,7 +2329,7 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
2239 if (chip->oldstate == FL_READY) { 2329 if (chip->oldstate == FL_READY) {
2240 chip->oldstate = chip->state; 2330 chip->oldstate = chip->state;
2241 chip->state = FL_PM_SUSPENDED; 2331 chip->state = FL_PM_SUSPENDED;
2242 /* No need to wake_up() on this state change - 2332 /* No need to wake_up() on this state change -
2243 * as the whole point is that nobody can do anything 2333 * as the whole point is that nobody can do anything
2244 * with the chip now anyway. 2334 * with the chip now anyway.
2245 */ 2335 */
@@ -2267,9 +2357,9 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
2267 if (ret) { 2357 if (ret) {
2268 for (i--; i >=0; i--) { 2358 for (i--; i >=0; i--) {
2269 chip = &cfi->chips[i]; 2359 chip = &cfi->chips[i];
2270 2360
2271 spin_lock(chip->mutex); 2361 spin_lock(chip->mutex);
2272 2362
2273 if (chip->state == FL_PM_SUSPENDED) { 2363 if (chip->state == FL_PM_SUSPENDED) {
2274 /* No need to force it into a known state here, 2364 /* No need to force it into a known state here,
2275 because we're returning failure, and it didn't 2365 because we're returning failure, and it didn't
@@ -2280,8 +2370,8 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
2280 } 2370 }
2281 spin_unlock(chip->mutex); 2371 spin_unlock(chip->mutex);
2282 } 2372 }
2283 } 2373 }
2284 2374
2285 return ret; 2375 return ret;
2286} 2376}
2287 2377
@@ -2293,11 +2383,11 @@ static void cfi_intelext_resume(struct mtd_info *mtd)
2293 struct flchip *chip; 2383 struct flchip *chip;
2294 2384
2295 for (i=0; i<cfi->numchips; i++) { 2385 for (i=0; i<cfi->numchips; i++) {
2296 2386
2297 chip = &cfi->chips[i]; 2387 chip = &cfi->chips[i];
2298 2388
2299 spin_lock(chip->mutex); 2389 spin_lock(chip->mutex);
2300 2390
2301 /* Go to known state. Chip may have been power cycled */ 2391 /* Go to known state. Chip may have been power cycled */
2302 if (chip->state == FL_PM_SUSPENDED) { 2392 if (chip->state == FL_PM_SUSPENDED) {
2303 map_write(map, CMD(0xFF), cfi->chips[i].start); 2393 map_write(map, CMD(0xFF), cfi->chips[i].start);
@@ -2319,7 +2409,7 @@ static int cfi_intelext_reset(struct mtd_info *mtd)
2319 struct flchip *chip = &cfi->chips[i]; 2409 struct flchip *chip = &cfi->chips[i];
2320 2410
2321 /* force the completion of any ongoing operation 2411 /* force the completion of any ongoing operation
2322 and switch to array mode so any bootloader in 2412 and switch to array mode so any bootloader in
2323 flash is accessible for soft reboot. */ 2413 flash is accessible for soft reboot. */
2324 spin_lock(chip->mutex); 2414 spin_lock(chip->mutex);
2325 ret = get_chip(map, chip, chip->start, FL_SYNCING); 2415 ret = get_chip(map, chip, chip->start, FL_SYNCING);
@@ -2356,20 +2446,23 @@ static void cfi_intelext_destroy(struct mtd_info *mtd)
2356 kfree(mtd->eraseregions); 2446 kfree(mtd->eraseregions);
2357} 2447}
2358 2448
2359static char im_name_1[]="cfi_cmdset_0001"; 2449static char im_name_0001[] = "cfi_cmdset_0001";
2360static char im_name_3[]="cfi_cmdset_0003"; 2450static char im_name_0003[] = "cfi_cmdset_0003";
2451static char im_name_0200[] = "cfi_cmdset_0200";
2361 2452
2362static int __init cfi_intelext_init(void) 2453static int __init cfi_intelext_init(void)
2363{ 2454{
2364 inter_module_register(im_name_1, THIS_MODULE, &cfi_cmdset_0001); 2455 inter_module_register(im_name_0001, THIS_MODULE, &cfi_cmdset_0001);
2365 inter_module_register(im_name_3, THIS_MODULE, &cfi_cmdset_0001); 2456 inter_module_register(im_name_0003, THIS_MODULE, &cfi_cmdset_0001);
2457 inter_module_register(im_name_0200, THIS_MODULE, &cfi_cmdset_0001);
2366 return 0; 2458 return 0;
2367} 2459}
2368 2460
2369static void __exit cfi_intelext_exit(void) 2461static void __exit cfi_intelext_exit(void)
2370{ 2462{
2371 inter_module_unregister(im_name_1); 2463 inter_module_unregister(im_name_0001);
2372 inter_module_unregister(im_name_3); 2464 inter_module_unregister(im_name_0003);
2465 inter_module_unregister(im_name_0200);
2373} 2466}
2374 2467
2375module_init(cfi_intelext_init); 2468module_init(cfi_intelext_init);
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 8505f118f2db..aed10bd5c3c3 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.118 2005/07/04 22:34:29 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
183static struct cfi_fixup cfi_fixup_table[] = { 183static 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.
@@ -253,8 +253,18 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
253 return NULL; 253 return NULL;
254 } 254 }
255 255
256 if (extp->MajorVersion != '1' ||
257 (extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
258 printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query "
259 "version %c.%c.\n", extp->MajorVersion,
260 extp->MinorVersion);
261 kfree(extp);
262 kfree(mtd);
263 return NULL;
264 }
265
256 /* Install our own private info structure */ 266 /* Install our own private info structure */
257 cfi->cmdset_priv = extp; 267 cfi->cmdset_priv = extp;
258 268
259 /* Apply cfi device specific fixups */ 269 /* Apply cfi device specific fixups */
260 cfi_fixup(mtd, cfi_fixup_table); 270 cfi_fixup(mtd, cfi_fixup_table);
@@ -262,7 +272,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
262#ifdef DEBUG_CFI_FEATURES 272#ifdef DEBUG_CFI_FEATURES
263 /* Tell the user about it in lots of lovely detail */ 273 /* Tell the user about it in lots of lovely detail */
264 cfi_tell_features(extp); 274 cfi_tell_features(extp);
265#endif 275#endif
266 276
267 bootloc = extp->TopBottom; 277 bootloc = extp->TopBottom;
268 if ((bootloc != 2) && (bootloc != 3)) { 278 if ((bootloc != 2) && (bootloc != 3)) {
@@ -273,11 +283,11 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
273 283
274 if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) { 284 if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) {
275 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);
276 286
277 for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) { 287 for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) {
278 int j = (cfi->cfiq->NumEraseRegions-1)-i; 288 int j = (cfi->cfiq->NumEraseRegions-1)-i;
279 __u32 swap; 289 __u32 swap;
280 290
281 swap = cfi->cfiq->EraseRegionInfo[i]; 291 swap = cfi->cfiq->EraseRegionInfo[i];
282 cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j]; 292 cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j];
283 cfi->cfiq->EraseRegionInfo[j] = swap; 293 cfi->cfiq->EraseRegionInfo[j] = swap;
@@ -288,11 +298,11 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
288 cfi->addr_unlock2 = 0x2aa; 298 cfi->addr_unlock2 = 0x2aa;
289 /* Modify the unlock address if we are in compatibility mode */ 299 /* Modify the unlock address if we are in compatibility mode */
290 if ( /* x16 in x8 mode */ 300 if ( /* x16 in x8 mode */
291 ((cfi->device_type == CFI_DEVICETYPE_X8) && 301 ((cfi->device_type == CFI_DEVICETYPE_X8) &&
292 (cfi->cfiq->InterfaceDesc == 2)) || 302 (cfi->cfiq->InterfaceDesc == 2)) ||
293 /* x32 in x16 mode */ 303 /* x32 in x16 mode */
294 ((cfi->device_type == CFI_DEVICETYPE_X16) && 304 ((cfi->device_type == CFI_DEVICETYPE_X16) &&
295 (cfi->cfiq->InterfaceDesc == 4))) 305 (cfi->cfiq->InterfaceDesc == 4)))
296 { 306 {
297 cfi->addr_unlock1 = 0xaaa; 307 cfi->addr_unlock1 = 0xaaa;
298 cfi->addr_unlock2 = 0x555; 308 cfi->addr_unlock2 = 0x555;
@@ -310,10 +320,10 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
310 cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp; 320 cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
311 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; 321 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
312 cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp; 322 cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
313 } 323 }
314 324
315 map->fldrv = &cfi_amdstd_chipdrv; 325 map->fldrv = &cfi_amdstd_chipdrv;
316 326
317 return cfi_amdstd_setup(mtd); 327 return cfi_amdstd_setup(mtd);
318} 328}
319 329
@@ -326,24 +336,24 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
326 unsigned long offset = 0; 336 unsigned long offset = 0;
327 int i,j; 337 int i,j;
328 338
329 printk(KERN_NOTICE "number of %s chips: %d\n", 339 printk(KERN_NOTICE "number of %s chips: %d\n",
330 (cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips); 340 (cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips);
331 /* Select the correct geometry setup */ 341 /* Select the correct geometry setup */
332 mtd->size = devsize * cfi->numchips; 342 mtd->size = devsize * cfi->numchips;
333 343
334 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; 344 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
335 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) 345 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
336 * mtd->numeraseregions, GFP_KERNEL); 346 * mtd->numeraseregions, GFP_KERNEL);
337 if (!mtd->eraseregions) { 347 if (!mtd->eraseregions) {
338 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");
339 goto setup_err; 349 goto setup_err;
340 } 350 }
341 351
342 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { 352 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
343 unsigned long ernum, ersize; 353 unsigned long ernum, ersize;
344 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; 354 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
345 ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1; 355 ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;
346 356
347 if (mtd->erasesize < ersize) { 357 if (mtd->erasesize < ersize) {
348 mtd->erasesize = ersize; 358 mtd->erasesize = ersize;
349 } 359 }
@@ -378,8 +388,7 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
378 388
379 setup_err: 389 setup_err:
380 if(mtd) { 390 if(mtd) {
381 if(mtd->eraseregions) 391 kfree(mtd->eraseregions);
382 kfree(mtd->eraseregions);
383 kfree(mtd); 392 kfree(mtd);
384 } 393 }
385 kfree(cfi->cmdset_priv); 394 kfree(cfi->cmdset_priv);
@@ -430,7 +439,7 @@ static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word
430 oldd = map_read(map, addr); 439 oldd = map_read(map, addr);
431 curd = map_read(map, addr); 440 curd = map_read(map, addr);
432 441
433 return map_word_equal(map, oldd, curd) && 442 return map_word_equal(map, oldd, curd) &&
434 map_word_equal(map, curd, expected); 443 map_word_equal(map, curd, expected);
435} 444}
436 445
@@ -462,7 +471,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
462 /* Someone else might have been playing with it. */ 471 /* Someone else might have been playing with it. */
463 goto retry; 472 goto retry;
464 } 473 }
465 474
466 case FL_READY: 475 case FL_READY:
467 case FL_CFI_QUERY: 476 case FL_CFI_QUERY:
468 case FL_JEDEC_QUERY: 477 case FL_JEDEC_QUERY:
@@ -505,7 +514,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
505 printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__); 514 printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__);
506 return -EIO; 515 return -EIO;
507 } 516 }
508 517
509 spin_unlock(chip->mutex); 518 spin_unlock(chip->mutex);
510 cfi_udelay(1); 519 cfi_udelay(1);
511 spin_lock(chip->mutex); 520 spin_lock(chip->mutex);
@@ -608,7 +617,7 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
608 * When a delay is required for the flash operation to complete, the 617 * When a delay is required for the flash operation to complete, the
609 * xip_udelay() function is polling for both the given timeout and pending 618 * xip_udelay() function is polling for both the given timeout and pending
610 * (but still masked) hardware interrupts. Whenever there is an interrupt 619 * (but still masked) hardware interrupts. Whenever there is an interrupt
611 * pending then the flash erase operation is suspended, array mode restored 620 * pending then the flash erase operation is suspended, array mode restored
612 * and interrupts unmasked. Task scheduling might also happen at that 621 * and interrupts unmasked. Task scheduling might also happen at that
613 * point. The CPU eventually returns from the interrupt or the call to 622 * point. The CPU eventually returns from the interrupt or the call to
614 * schedule() and the suspended flash operation is resumed for the remaining 623 * schedule() and the suspended flash operation is resumed for the remaining
@@ -632,9 +641,9 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
632 ((chip->state == FL_ERASING && (extp->EraseSuspend & 2))) && 641 ((chip->state == FL_ERASING && (extp->EraseSuspend & 2))) &&
633 (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) { 642 (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) {
634 /* 643 /*
635 * Let's suspend the erase operation when supported. 644 * Let's suspend the erase operation when supported.
636 * Note that we currently don't try to suspend 645 * Note that we currently don't try to suspend
637 * interleaved chips if there is already another 646 * interleaved chips if there is already another
638 * operation suspended (imagine what happens 647 * operation suspended (imagine what happens
639 * when one chip was already done with the current 648 * when one chip was already done with the current
640 * operation while another chip suspended it, then 649 * operation while another chip suspended it, then
@@ -770,8 +779,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
770 779
771 adr += chip->start; 780 adr += chip->start;
772 781
773 /* Ensure cmd read/writes are aligned. */ 782 /* Ensure cmd read/writes are aligned. */
774 cmd_addr = adr & ~(map_bankwidth(map)-1); 783 cmd_addr = adr & ~(map_bankwidth(map)-1);
775 784
776 spin_lock(chip->mutex); 785 spin_lock(chip->mutex);
777 ret = get_chip(map, chip, cmd_addr, FL_READY); 786 ret = get_chip(map, chip, cmd_addr, FL_READY);
@@ -851,7 +860,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
851#endif 860#endif
852 set_current_state(TASK_UNINTERRUPTIBLE); 861 set_current_state(TASK_UNINTERRUPTIBLE);
853 add_wait_queue(&chip->wq, &wait); 862 add_wait_queue(&chip->wq, &wait);
854 863
855 spin_unlock(chip->mutex); 864 spin_unlock(chip->mutex);
856 865
857 schedule(); 866 schedule();
@@ -863,7 +872,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
863 timeo = jiffies + HZ; 872 timeo = jiffies + HZ;
864 873
865 goto retry; 874 goto retry;
866 } 875 }
867 876
868 adr += chip->start; 877 adr += chip->start;
869 878
@@ -872,14 +881,14 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
872 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 881 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
873 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); 882 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
874 cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 883 cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
875 884
876 map_copy_from(map, buf, adr, len); 885 map_copy_from(map, buf, adr, len);
877 886
878 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 887 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
879 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); 888 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
880 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 889 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
881 cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 890 cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
882 891
883 wake_up(&chip->wq); 892 wake_up(&chip->wq);
884 spin_unlock(chip->mutex); 893 spin_unlock(chip->mutex);
885 894
@@ -988,7 +997,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
988 chip->word_write_time); 997 chip->word_write_time);
989 998
990 /* See comment above for timeout value. */ 999 /* See comment above for timeout value. */
991 timeo = jiffies + uWriteTimeout; 1000 timeo = jiffies + uWriteTimeout;
992 for (;;) { 1001 for (;;) {
993 if (chip->state != FL_WRITING) { 1002 if (chip->state != FL_WRITING) {
994 /* Someone's suspended the write. Sleep */ 1003 /* Someone's suspended the write. Sleep */
@@ -1004,16 +1013,16 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1004 continue; 1013 continue;
1005 } 1014 }
1006 1015
1007 if (chip_ready(map, adr)) 1016 if (time_after(jiffies, timeo) && !chip_ready(map, adr)){
1008 break;
1009
1010 if (time_after(jiffies, timeo)) {
1011 xip_enable(map, chip, adr); 1017 xip_enable(map, chip, adr);
1012 printk(KERN_WARNING "MTD %s(): software timeout\n", __func__); 1018 printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
1013 xip_disable(map, chip, adr); 1019 xip_disable(map, chip, adr);
1014 break; 1020 break;
1015 } 1021 }
1016 1022
1023 if (chip_ready(map, adr))
1024 break;
1025
1017 /* Latency issues. Drop the lock, wait a while and retry */ 1026 /* Latency issues. Drop the lock, wait a while and retry */
1018 UDELAY(map, chip, adr, 1); 1027 UDELAY(map, chip, adr, 1);
1019 } 1028 }
@@ -1023,7 +1032,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1023 map_write( map, CMD(0xF0), chip->start ); 1032 map_write( map, CMD(0xF0), chip->start );
1024 /* FIXME - should have reset delay before continuing */ 1033 /* FIXME - should have reset delay before continuing */
1025 1034
1026 if (++retry_cnt <= MAX_WORD_RETRIES) 1035 if (++retry_cnt <= MAX_WORD_RETRIES)
1027 goto retry; 1036 goto retry;
1028 1037
1029 ret = -EIO; 1038 ret = -EIO;
@@ -1091,27 +1100,27 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
1091 1100
1092 /* Number of bytes to copy from buffer */ 1101 /* Number of bytes to copy from buffer */
1093 n = min_t(int, len, map_bankwidth(map)-i); 1102 n = min_t(int, len, map_bankwidth(map)-i);
1094 1103
1095 tmp_buf = map_word_load_partial(map, tmp_buf, buf, i, n); 1104 tmp_buf = map_word_load_partial(map, tmp_buf, buf, i, n);
1096 1105
1097 ret = do_write_oneword(map, &cfi->chips[chipnum], 1106 ret = do_write_oneword(map, &cfi->chips[chipnum],
1098 bus_ofs, tmp_buf); 1107 bus_ofs, tmp_buf);
1099 if (ret) 1108 if (ret)
1100 return ret; 1109 return ret;
1101 1110
1102 ofs += n; 1111 ofs += n;
1103 buf += n; 1112 buf += n;
1104 (*retlen) += n; 1113 (*retlen) += n;
1105 len -= n; 1114 len -= n;
1106 1115
1107 if (ofs >> cfi->chipshift) { 1116 if (ofs >> cfi->chipshift) {
1108 chipnum ++; 1117 chipnum ++;
1109 ofs = 0; 1118 ofs = 0;
1110 if (chipnum == cfi->numchips) 1119 if (chipnum == cfi->numchips)
1111 return 0; 1120 return 0;
1112 } 1121 }
1113 } 1122 }
1114 1123
1115 /* We are now aligned, write as much as possible */ 1124 /* We are now aligned, write as much as possible */
1116 while(len >= map_bankwidth(map)) { 1125 while(len >= map_bankwidth(map)) {
1117 map_word datum; 1126 map_word datum;
@@ -1129,7 +1138,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
1129 len -= map_bankwidth(map); 1138 len -= map_bankwidth(map);
1130 1139
1131 if (ofs >> cfi->chipshift) { 1140 if (ofs >> cfi->chipshift) {
1132 chipnum ++; 1141 chipnum ++;
1133 ofs = 0; 1142 ofs = 0;
1134 if (chipnum == cfi->numchips) 1143 if (chipnum == cfi->numchips)
1135 return 0; 1144 return 0;
@@ -1167,12 +1176,12 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
1167 spin_unlock(cfi->chips[chipnum].mutex); 1176 spin_unlock(cfi->chips[chipnum].mutex);
1168 1177
1169 tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len); 1178 tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len);
1170 1179
1171 ret = do_write_oneword(map, &cfi->chips[chipnum], 1180 ret = do_write_oneword(map, &cfi->chips[chipnum],
1172 ofs, tmp_buf); 1181 ofs, tmp_buf);
1173 if (ret) 1182 if (ret)
1174 return ret; 1183 return ret;
1175 1184
1176 (*retlen) += len; 1185 (*retlen) += len;
1177 } 1186 }
1178 1187
@@ -1184,7 +1193,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
1184 * FIXME: interleaved mode not tested, and probably not supported! 1193 * FIXME: interleaved mode not tested, and probably not supported!
1185 */ 1194 */
1186static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, 1195static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1187 unsigned long adr, const u_char *buf, 1196 unsigned long adr, const u_char *buf,
1188 int len) 1197 int len)
1189{ 1198{
1190 struct cfi_private *cfi = map->fldrv_priv; 1199 struct cfi_private *cfi = map->fldrv_priv;
@@ -1214,7 +1223,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1214 XIP_INVAL_CACHED_RANGE(map, adr, len); 1223 XIP_INVAL_CACHED_RANGE(map, adr, len);
1215 ENABLE_VPP(map); 1224 ENABLE_VPP(map);
1216 xip_disable(map, chip, cmd_adr); 1225 xip_disable(map, chip, cmd_adr);
1217 1226
1218 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 1227 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
1219 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); 1228 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
1220 //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 1229 //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
@@ -1248,8 +1257,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1248 adr, map_bankwidth(map), 1257 adr, map_bankwidth(map),
1249 chip->word_write_time); 1258 chip->word_write_time);
1250 1259
1251 timeo = jiffies + uWriteTimeout; 1260 timeo = jiffies + uWriteTimeout;
1252 1261
1253 for (;;) { 1262 for (;;) {
1254 if (chip->state != FL_WRITING) { 1263 if (chip->state != FL_WRITING) {
1255 /* Someone's suspended the write. Sleep */ 1264 /* Someone's suspended the write. Sleep */
@@ -1265,13 +1274,13 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1265 continue; 1274 continue;
1266 } 1275 }
1267 1276
1277 if (time_after(jiffies, timeo) && !chip_ready(map, adr))
1278 break;
1279
1268 if (chip_ready(map, adr)) { 1280 if (chip_ready(map, adr)) {
1269 xip_enable(map, chip, adr); 1281 xip_enable(map, chip, adr);
1270 goto op_done; 1282 goto op_done;
1271 } 1283 }
1272
1273 if( time_after(jiffies, timeo))
1274 break;
1275 1284
1276 /* Latency issues. Drop the lock, wait a while and retry */ 1285 /* Latency issues. Drop the lock, wait a while and retry */
1277 UDELAY(map, chip, adr, 1); 1286 UDELAY(map, chip, adr, 1);
@@ -1343,7 +1352,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
1343 if (size % map_bankwidth(map)) 1352 if (size % map_bankwidth(map))
1344 size -= size % map_bankwidth(map); 1353 size -= size % map_bankwidth(map);
1345 1354
1346 ret = do_write_buffer(map, &cfi->chips[chipnum], 1355 ret = do_write_buffer(map, &cfi->chips[chipnum],
1347 ofs, buf, size); 1356 ofs, buf, size);
1348 if (ret) 1357 if (ret)
1349 return ret; 1358 return ret;
@@ -1354,7 +1363,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
1354 len -= size; 1363 len -= size;
1355 1364
1356 if (ofs >> cfi->chipshift) { 1365 if (ofs >> cfi->chipshift) {
1357 chipnum ++; 1366 chipnum ++;
1358 ofs = 0; 1367 ofs = 0;
1359 if (chipnum == cfi->numchips) 1368 if (chipnum == cfi->numchips)
1360 return 0; 1369 return 0;
@@ -1571,7 +1580,7 @@ int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
1571 1580
1572 instr->state = MTD_ERASE_DONE; 1581 instr->state = MTD_ERASE_DONE;
1573 mtd_erase_callback(instr); 1582 mtd_erase_callback(instr);
1574 1583
1575 return 0; 1584 return 0;
1576} 1585}
1577 1586
@@ -1594,7 +1603,7 @@ static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr)
1594 1603
1595 instr->state = MTD_ERASE_DONE; 1604 instr->state = MTD_ERASE_DONE;
1596 mtd_erase_callback(instr); 1605 mtd_erase_callback(instr);
1597 1606
1598 return 0; 1607 return 0;
1599} 1608}
1600 1609
@@ -1621,7 +1630,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
1621 case FL_JEDEC_QUERY: 1630 case FL_JEDEC_QUERY:
1622 chip->oldstate = chip->state; 1631 chip->oldstate = chip->state;
1623 chip->state = FL_SYNCING; 1632 chip->state = FL_SYNCING;
1624 /* No need to wake_up() on this state change - 1633 /* No need to wake_up() on this state change -
1625 * as the whole point is that nobody can do anything 1634 * as the whole point is that nobody can do anything
1626 * with the chip now anyway. 1635 * with the chip now anyway.
1627 */ 1636 */
@@ -1632,13 +1641,13 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
1632 default: 1641 default:
1633 /* Not an idle state */ 1642 /* Not an idle state */
1634 add_wait_queue(&chip->wq, &wait); 1643 add_wait_queue(&chip->wq, &wait);
1635 1644
1636 spin_unlock(chip->mutex); 1645 spin_unlock(chip->mutex);
1637 1646
1638 schedule(); 1647 schedule();
1639 1648
1640 remove_wait_queue(&chip->wq, &wait); 1649 remove_wait_queue(&chip->wq, &wait);
1641 1650
1642 goto retry; 1651 goto retry;
1643 } 1652 }
1644 } 1653 }
@@ -1649,7 +1658,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
1649 chip = &cfi->chips[i]; 1658 chip = &cfi->chips[i];
1650 1659
1651 spin_lock(chip->mutex); 1660 spin_lock(chip->mutex);
1652 1661
1653 if (chip->state == FL_SYNCING) { 1662 if (chip->state == FL_SYNCING) {
1654 chip->state = chip->oldstate; 1663 chip->state = chip->oldstate;
1655 wake_up(&chip->wq); 1664 wake_up(&chip->wq);
@@ -1679,7 +1688,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
1679 case FL_JEDEC_QUERY: 1688 case FL_JEDEC_QUERY:
1680 chip->oldstate = chip->state; 1689 chip->oldstate = chip->state;
1681 chip->state = FL_PM_SUSPENDED; 1690 chip->state = FL_PM_SUSPENDED;
1682 /* No need to wake_up() on this state change - 1691 /* No need to wake_up() on this state change -
1683 * as the whole point is that nobody can do anything 1692 * as the whole point is that nobody can do anything
1684 * with the chip now anyway. 1693 * with the chip now anyway.
1685 */ 1694 */
@@ -1700,7 +1709,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
1700 chip = &cfi->chips[i]; 1709 chip = &cfi->chips[i];
1701 1710
1702 spin_lock(chip->mutex); 1711 spin_lock(chip->mutex);
1703 1712
1704 if (chip->state == FL_PM_SUSPENDED) { 1713 if (chip->state == FL_PM_SUSPENDED) {
1705 chip->state = chip->oldstate; 1714 chip->state = chip->oldstate;
1706 wake_up(&chip->wq); 1715 wake_up(&chip->wq);
@@ -1708,7 +1717,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
1708 spin_unlock(chip->mutex); 1717 spin_unlock(chip->mutex);
1709 } 1718 }
1710 } 1719 }
1711 1720
1712 return ret; 1721 return ret;
1713} 1722}
1714 1723
@@ -1721,11 +1730,11 @@ static void cfi_amdstd_resume(struct mtd_info *mtd)
1721 struct flchip *chip; 1730 struct flchip *chip;
1722 1731
1723 for (i=0; i<cfi->numchips; i++) { 1732 for (i=0; i<cfi->numchips; i++) {
1724 1733
1725 chip = &cfi->chips[i]; 1734 chip = &cfi->chips[i];
1726 1735
1727 spin_lock(chip->mutex); 1736 spin_lock(chip->mutex);
1728 1737
1729 if (chip->state == FL_PM_SUSPENDED) { 1738 if (chip->state == FL_PM_SUSPENDED) {
1730 chip->state = FL_READY; 1739 chip->state = FL_READY;
1731 map_write(map, CMD(0xF0), chip->start); 1740 map_write(map, CMD(0xF0), chip->start);
@@ -1742,6 +1751,7 @@ static void cfi_amdstd_destroy(struct mtd_info *mtd)
1742{ 1751{
1743 struct map_info *map = mtd->priv; 1752 struct map_info *map = mtd->priv;
1744 struct cfi_private *cfi = map->fldrv_priv; 1753 struct cfi_private *cfi = map->fldrv_priv;
1754
1745 kfree(cfi->cmdset_priv); 1755 kfree(cfi->cmdset_priv);
1746 kfree(cfi->cfiq); 1756 kfree(cfi->cfiq);
1747 kfree(cfi); 1757 kfree(cfi);
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index c894f8801578..c4a19d2dc67f 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -4,8 +4,8 @@
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.19 2005/07/13 15:52:45 dwmw2 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
11 * independent of the flash geometry (buswidth, interleave, etc.) 11 * independent of the flash geometry (buswidth, interleave, etc.)
@@ -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.
@@ -133,24 +133,33 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
133 if (!extp) 133 if (!extp)
134 return NULL; 134 return NULL;
135 135
136 if (extp->MajorVersion != '1' ||
137 (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
138 printk(KERN_ERR " Unknown ST Microelectronics"
139 " Extended Query version %c.%c.\n",
140 extp->MajorVersion, extp->MinorVersion);
141 kfree(extp);
142 return NULL;
143 }
144
136 /* Do some byteswapping if necessary */ 145 /* Do some byteswapping if necessary */
137 extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport); 146 extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport);
138 extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask); 147 extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask);
139 148
140#ifdef DEBUG_CFI_FEATURES 149#ifdef DEBUG_CFI_FEATURES
141 /* Tell the user about it in lots of lovely detail */ 150 /* Tell the user about it in lots of lovely detail */
142 cfi_tell_features(extp); 151 cfi_tell_features(extp);
143#endif 152#endif
144 153
145 /* Install our own private info structure */ 154 /* Install our own private info structure */
146 cfi->cmdset_priv = extp; 155 cfi->cmdset_priv = extp;
147 } 156 }
148 157
149 for (i=0; i< cfi->numchips; i++) { 158 for (i=0; i< cfi->numchips; i++) {
150 cfi->chips[i].word_write_time = 128; 159 cfi->chips[i].word_write_time = 128;
151 cfi->chips[i].buffer_write_time = 128; 160 cfi->chips[i].buffer_write_time = 128;
152 cfi->chips[i].erase_time = 1024; 161 cfi->chips[i].erase_time = 1024;
153 } 162 }
154 163
155 return cfi_staa_setup(map); 164 return cfi_staa_setup(map);
156} 165}
@@ -178,15 +187,15 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
178 mtd->size = devsize * cfi->numchips; 187 mtd->size = devsize * cfi->numchips;
179 188
180 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; 189 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
181 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) 190 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
182 * mtd->numeraseregions, GFP_KERNEL); 191 * mtd->numeraseregions, GFP_KERNEL);
183 if (!mtd->eraseregions) { 192 if (!mtd->eraseregions) {
184 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");
185 kfree(cfi->cmdset_priv); 194 kfree(cfi->cmdset_priv);
186 kfree(mtd); 195 kfree(mtd);
187 return NULL; 196 return NULL;
188 } 197 }
189 198
190 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { 199 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
191 unsigned long ernum, ersize; 200 unsigned long ernum, ersize;
192 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; 201 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
@@ -219,7 +228,7 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
219 mtd->eraseregions[i].numblocks); 228 mtd->eraseregions[i].numblocks);
220 } 229 }
221 230
222 /* Also select the correct geometry setup too */ 231 /* Also select the correct geometry setup too */
223 mtd->erase = cfi_staa_erase_varsize; 232 mtd->erase = cfi_staa_erase_varsize;
224 mtd->read = cfi_staa_read; 233 mtd->read = cfi_staa_read;
225 mtd->write = cfi_staa_write_buffers; 234 mtd->write = cfi_staa_write_buffers;
@@ -250,8 +259,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
250 259
251 adr += chip->start; 260 adr += chip->start;
252 261
253 /* Ensure cmd read/writes are aligned. */ 262 /* Ensure cmd read/writes are aligned. */
254 cmd_addr = adr & ~(map_bankwidth(map)-1); 263 cmd_addr = adr & ~(map_bankwidth(map)-1);
255 264
256 /* Let's determine this according to the interleave only once */ 265 /* Let's determine this according to the interleave only once */
257 status_OK = CMD(0x80); 266 status_OK = CMD(0x80);
@@ -267,7 +276,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
267 case FL_ERASING: 276 case FL_ERASING:
268 if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)) 277 if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2))
269 goto sleep; /* We don't support erase suspend */ 278 goto sleep; /* We don't support erase suspend */
270 279
271 map_write (map, CMD(0xb0), cmd_addr); 280 map_write (map, CMD(0xb0), cmd_addr);
272 /* If the flash has finished erasing, then 'erase suspend' 281 /* If the flash has finished erasing, then 'erase suspend'
273 * appears to make some (28F320) flash devices switch to 282 * appears to make some (28F320) flash devices switch to
@@ -282,7 +291,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
282 status = map_read(map, cmd_addr); 291 status = map_read(map, cmd_addr);
283 if (map_word_andequal(map, status, status_OK, status_OK)) 292 if (map_word_andequal(map, status, status_OK, status_OK))
284 break; 293 break;
285 294
286 if (time_after(jiffies, timeo)) { 295 if (time_after(jiffies, timeo)) {
287 /* Urgh */ 296 /* Urgh */
288 map_write(map, CMD(0xd0), cmd_addr); 297 map_write(map, CMD(0xd0), cmd_addr);
@@ -294,17 +303,17 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
294 "suspended: status = 0x%lx\n", status.x[0]); 303 "suspended: status = 0x%lx\n", status.x[0]);
295 return -EIO; 304 return -EIO;
296 } 305 }
297 306
298 spin_unlock_bh(chip->mutex); 307 spin_unlock_bh(chip->mutex);
299 cfi_udelay(1); 308 cfi_udelay(1);
300 spin_lock_bh(chip->mutex); 309 spin_lock_bh(chip->mutex);
301 } 310 }
302 311
303 suspended = 1; 312 suspended = 1;
304 map_write(map, CMD(0xff), cmd_addr); 313 map_write(map, CMD(0xff), cmd_addr);
305 chip->state = FL_READY; 314 chip->state = FL_READY;
306 break; 315 break;
307 316
308#if 0 317#if 0
309 case FL_WRITING: 318 case FL_WRITING:
310 /* Not quite yet */ 319 /* Not quite yet */
@@ -325,7 +334,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
325 chip->state = FL_READY; 334 chip->state = FL_READY;
326 break; 335 break;
327 } 336 }
328 337
329 /* Urgh. Chip not yet ready to talk to us. */ 338 /* Urgh. Chip not yet ready to talk to us. */
330 if (time_after(jiffies, timeo)) { 339 if (time_after(jiffies, timeo)) {
331 spin_unlock_bh(chip->mutex); 340 spin_unlock_bh(chip->mutex);
@@ -355,17 +364,17 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
355 364
356 if (suspended) { 365 if (suspended) {
357 chip->state = chip->oldstate; 366 chip->state = chip->oldstate;
358 /* What if one interleaved chip has finished and the 367 /* What if one interleaved chip has finished and the
359 other hasn't? The old code would leave the finished 368 other hasn't? The old code would leave the finished
360 one in READY mode. That's bad, and caused -EROFS 369 one in READY mode. That's bad, and caused -EROFS
361 errors to be returned from do_erase_oneblock because 370 errors to be returned from do_erase_oneblock because
362 that's the only bit it checked for at the time. 371 that's the only bit it checked for at the time.
363 As the state machine appears to explicitly allow 372 As the state machine appears to explicitly allow
364 sending the 0x70 (Read Status) command to an erasing 373 sending the 0x70 (Read Status) command to an erasing
365 chip and expecting it to be ignored, that's what we 374 chip and expecting it to be ignored, that's what we
366 do. */ 375 do. */
367 map_write(map, CMD(0xd0), cmd_addr); 376 map_write(map, CMD(0xd0), cmd_addr);
368 map_write(map, CMD(0x70), cmd_addr); 377 map_write(map, CMD(0x70), cmd_addr);
369 } 378 }
370 379
371 wake_up(&chip->wq); 380 wake_up(&chip->wq);
@@ -405,14 +414,14 @@ static int cfi_staa_read (struct mtd_info *mtd, loff_t from, size_t len, size_t
405 *retlen += thislen; 414 *retlen += thislen;
406 len -= thislen; 415 len -= thislen;
407 buf += thislen; 416 buf += thislen;
408 417
409 ofs = 0; 418 ofs = 0;
410 chipnum++; 419 chipnum++;
411 } 420 }
412 return ret; 421 return ret;
413} 422}
414 423
415static inline int do_write_buffer(struct map_info *map, struct flchip *chip, 424static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
416 unsigned long adr, const u_char *buf, int len) 425 unsigned long adr, const u_char *buf, int len)
417{ 426{
418 struct cfi_private *cfi = map->fldrv_priv; 427 struct cfi_private *cfi = map->fldrv_priv;
@@ -420,7 +429,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
420 unsigned long cmd_adr, timeo; 429 unsigned long cmd_adr, timeo;
421 DECLARE_WAITQUEUE(wait, current); 430 DECLARE_WAITQUEUE(wait, current);
422 int wbufsize, z; 431 int wbufsize, z;
423 432
424 /* M58LW064A requires bus alignment for buffer wriets -- saw */ 433 /* M58LW064A requires bus alignment for buffer wriets -- saw */
425 if (adr & (map_bankwidth(map)-1)) 434 if (adr & (map_bankwidth(map)-1))
426 return -EINVAL; 435 return -EINVAL;
@@ -428,10 +437,10 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
428 wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; 437 wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
429 adr += chip->start; 438 adr += chip->start;
430 cmd_adr = adr & ~(wbufsize-1); 439 cmd_adr = adr & ~(wbufsize-1);
431 440
432 /* Let's determine this according to the interleave only once */ 441 /* Let's determine this according to the interleave only once */
433 status_OK = CMD(0x80); 442 status_OK = CMD(0x80);
434 443
435 timeo = jiffies + HZ; 444 timeo = jiffies + HZ;
436 retry: 445 retry:
437 446
@@ -439,7 +448,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
439 printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state); 448 printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state);
440#endif 449#endif
441 spin_lock_bh(chip->mutex); 450 spin_lock_bh(chip->mutex);
442 451
443 /* Check that the chip's ready to talk to us. 452 /* Check that the chip's ready to talk to us.
444 * Later, we can actually think about interrupting it 453 * Later, we can actually think about interrupting it
445 * if it's in FL_ERASING state. 454 * if it's in FL_ERASING state.
@@ -448,7 +457,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
448 switch (chip->state) { 457 switch (chip->state) {
449 case FL_READY: 458 case FL_READY:
450 break; 459 break;
451 460
452 case FL_CFI_QUERY: 461 case FL_CFI_QUERY:
453 case FL_JEDEC_QUERY: 462 case FL_JEDEC_QUERY:
454 map_write(map, CMD(0x70), cmd_adr); 463 map_write(map, CMD(0x70), cmd_adr);
@@ -513,7 +522,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
513 522
514 /* Write length of data to come */ 523 /* Write length of data to come */
515 map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr ); 524 map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr );
516 525
517 /* Write data */ 526 /* Write data */
518 for (z = 0; z < len; 527 for (z = 0; z < len;
519 z += map_bankwidth(map), buf += map_bankwidth(map)) { 528 z += map_bankwidth(map), buf += map_bankwidth(map)) {
@@ -560,7 +569,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
560 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");
561 return -EIO; 570 return -EIO;
562 } 571 }
563 572
564 /* Latency issues. Drop the lock, wait a while and retry */ 573 /* Latency issues. Drop the lock, wait a while and retry */
565 spin_unlock_bh(chip->mutex); 574 spin_unlock_bh(chip->mutex);
566 cfi_udelay(1); 575 cfi_udelay(1);
@@ -572,9 +581,9 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
572 if (!chip->buffer_write_time) 581 if (!chip->buffer_write_time)
573 chip->buffer_write_time++; 582 chip->buffer_write_time++;
574 } 583 }
575 if (z > 1) 584 if (z > 1)
576 chip->buffer_write_time++; 585 chip->buffer_write_time++;
577 586
578 /* Done and happy. */ 587 /* Done and happy. */
579 DISABLE_VPP(map); 588 DISABLE_VPP(map);
580 chip->state = FL_STATUS; 589 chip->state = FL_STATUS;
@@ -598,7 +607,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
598 return 0; 607 return 0;
599} 608}
600 609
601static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, 610static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
602 size_t len, size_t *retlen, const u_char *buf) 611 size_t len, size_t *retlen, const u_char *buf)
603{ 612{
604 struct map_info *map = mtd->priv; 613 struct map_info *map = mtd->priv;
@@ -620,7 +629,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
620 printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize); 629 printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize);
621 printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len); 630 printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len);
622#endif 631#endif
623 632
624 /* 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... */
625 while (len > 0) { 634 while (len > 0) {
626 /* We must not cross write block boundaries */ 635 /* We must not cross write block boundaries */
@@ -629,7 +638,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
629 if (size > len) 638 if (size > len)
630 size = len; 639 size = len;
631 640
632 ret = do_write_buffer(map, &cfi->chips[chipnum], 641 ret = do_write_buffer(map, &cfi->chips[chipnum],
633 ofs, buf, size); 642 ofs, buf, size);
634 if (ret) 643 if (ret)
635 return ret; 644 return ret;
@@ -640,13 +649,13 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
640 len -= size; 649 len -= size;
641 650
642 if (ofs >> cfi->chipshift) { 651 if (ofs >> cfi->chipshift) {
643 chipnum ++; 652 chipnum ++;
644 ofs = 0; 653 ofs = 0;
645 if (chipnum == cfi->numchips) 654 if (chipnum == cfi->numchips)
646 return 0; 655 return 0;
647 } 656 }
648 } 657 }
649 658
650 return 0; 659 return 0;
651} 660}
652 661
@@ -756,7 +765,7 @@ retry:
756 status = map_read(map, adr); 765 status = map_read(map, adr);
757 if (map_word_andequal(map, status, status_OK, status_OK)) 766 if (map_word_andequal(map, status, status_OK, status_OK))
758 break; 767 break;
759 768
760 /* Urgh. Chip not yet ready to talk to us. */ 769 /* Urgh. Chip not yet ready to talk to us. */
761 if (time_after(jiffies, timeo)) { 770 if (time_after(jiffies, timeo)) {
762 spin_unlock_bh(chip->mutex); 771 spin_unlock_bh(chip->mutex);
@@ -789,7 +798,7 @@ retry:
789 map_write(map, CMD(0x20), adr); 798 map_write(map, CMD(0x20), adr);
790 map_write(map, CMD(0xD0), adr); 799 map_write(map, CMD(0xD0), adr);
791 chip->state = FL_ERASING; 800 chip->state = FL_ERASING;
792 801
793 spin_unlock_bh(chip->mutex); 802 spin_unlock_bh(chip->mutex);
794 msleep(1000); 803 msleep(1000);
795 spin_lock_bh(chip->mutex); 804 spin_lock_bh(chip->mutex);
@@ -814,7 +823,7 @@ retry:
814 status = map_read(map, adr); 823 status = map_read(map, adr);
815 if (map_word_andequal(map, status, status_OK, status_OK)) 824 if (map_word_andequal(map, status, status_OK, status_OK))
816 break; 825 break;
817 826
818 /* OK Still waiting */ 827 /* OK Still waiting */
819 if (time_after(jiffies, timeo)) { 828 if (time_after(jiffies, timeo)) {
820 map_write(map, CMD(0x70), adr); 829 map_write(map, CMD(0x70), adr);
@@ -824,13 +833,13 @@ retry:
824 spin_unlock_bh(chip->mutex); 833 spin_unlock_bh(chip->mutex);
825 return -EIO; 834 return -EIO;
826 } 835 }
827 836
828 /* Latency issues. Drop the lock, wait a while and retry */ 837 /* Latency issues. Drop the lock, wait a while and retry */
829 spin_unlock_bh(chip->mutex); 838 spin_unlock_bh(chip->mutex);
830 cfi_udelay(1); 839 cfi_udelay(1);
831 spin_lock_bh(chip->mutex); 840 spin_lock_bh(chip->mutex);
832 } 841 }
833 842
834 DISABLE_VPP(map); 843 DISABLE_VPP(map);
835 ret = 0; 844 ret = 0;
836 845
@@ -855,7 +864,7 @@ retry:
855 /* Reset the error bits */ 864 /* Reset the error bits */
856 map_write(map, CMD(0x50), adr); 865 map_write(map, CMD(0x50), adr);
857 map_write(map, CMD(0x70), adr); 866 map_write(map, CMD(0x70), adr);
858 867
859 if ((chipstatus & 0x30) == 0x30) { 868 if ((chipstatus & 0x30) == 0x30) {
860 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);
861 ret = -EIO; 870 ret = -EIO;
@@ -904,17 +913,17 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
904 913
905 i = 0; 914 i = 0;
906 915
907 /* Skip all erase regions which are ended before the start of 916 /* Skip all erase regions which are ended before the start of
908 the requested erase. Actually, to save on the calculations, 917 the requested erase. Actually, to save on the calculations,
909 we skip to the first erase region which starts after the 918 we skip to the first erase region which starts after the
910 start of the requested erase, and then go back one. 919 start of the requested erase, and then go back one.
911 */ 920 */
912 921
913 while (i < mtd->numeraseregions && instr->addr >= regions[i].offset) 922 while (i < mtd->numeraseregions && instr->addr >= regions[i].offset)
914 i++; 923 i++;
915 i--; 924 i--;
916 925
917 /* 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
918 erase request starts. Check the start of the requested 927 erase request starts. Check the start of the requested
919 erase range is aligned with the erase size which is in 928 erase range is aligned with the erase size which is in
920 effect here. 929 effect here.
@@ -937,7 +946,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
937 the address actually falls 946 the address actually falls
938 */ 947 */
939 i--; 948 i--;
940 949
941 if ((instr->addr + instr->len) & (regions[i].erasesize-1)) 950 if ((instr->addr + instr->len) & (regions[i].erasesize-1))
942 return -EINVAL; 951 return -EINVAL;
943 952
@@ -949,7 +958,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
949 958
950 while(len) { 959 while(len) {
951 ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr); 960 ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
952 961
953 if (ret) 962 if (ret)
954 return ret; 963 return ret;
955 964
@@ -962,15 +971,15 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
962 if (adr >> cfi->chipshift) { 971 if (adr >> cfi->chipshift) {
963 adr = 0; 972 adr = 0;
964 chipnum++; 973 chipnum++;
965 974
966 if (chipnum >= cfi->numchips) 975 if (chipnum >= cfi->numchips)
967 break; 976 break;
968 } 977 }
969 } 978 }
970 979
971 instr->state = MTD_ERASE_DONE; 980 instr->state = MTD_ERASE_DONE;
972 mtd_erase_callback(instr); 981 mtd_erase_callback(instr);
973 982
974 return 0; 983 return 0;
975} 984}
976 985
@@ -996,7 +1005,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
996 case FL_JEDEC_QUERY: 1005 case FL_JEDEC_QUERY:
997 chip->oldstate = chip->state; 1006 chip->oldstate = chip->state;
998 chip->state = FL_SYNCING; 1007 chip->state = FL_SYNCING;
999 /* No need to wake_up() on this state change - 1008 /* No need to wake_up() on this state change -
1000 * as the whole point is that nobody can do anything 1009 * as the whole point is that nobody can do anything
1001 * with the chip now anyway. 1010 * with the chip now anyway.
1002 */ 1011 */
@@ -1007,11 +1016,11 @@ static void cfi_staa_sync (struct mtd_info *mtd)
1007 default: 1016 default:
1008 /* Not an idle state */ 1017 /* Not an idle state */
1009 add_wait_queue(&chip->wq, &wait); 1018 add_wait_queue(&chip->wq, &wait);
1010 1019
1011 spin_unlock_bh(chip->mutex); 1020 spin_unlock_bh(chip->mutex);
1012 schedule(); 1021 schedule();
1013 remove_wait_queue(&chip->wq, &wait); 1022 remove_wait_queue(&chip->wq, &wait);
1014 1023
1015 goto retry; 1024 goto retry;
1016 } 1025 }
1017 } 1026 }
@@ -1022,7 +1031,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
1022 chip = &cfi->chips[i]; 1031 chip = &cfi->chips[i];
1023 1032
1024 spin_lock_bh(chip->mutex); 1033 spin_lock_bh(chip->mutex);
1025 1034
1026 if (chip->state == FL_SYNCING) { 1035 if (chip->state == FL_SYNCING) {
1027 chip->state = chip->oldstate; 1036 chip->state = chip->oldstate;
1028 wake_up(&chip->wq); 1037 wake_up(&chip->wq);
@@ -1057,9 +1066,9 @@ retry:
1057 1066
1058 case FL_STATUS: 1067 case FL_STATUS:
1059 status = map_read(map, adr); 1068 status = map_read(map, adr);
1060 if (map_word_andequal(map, status, status_OK, status_OK)) 1069 if (map_word_andequal(map, status, status_OK, status_OK))
1061 break; 1070 break;
1062 1071
1063 /* Urgh. Chip not yet ready to talk to us. */ 1072 /* Urgh. Chip not yet ready to talk to us. */
1064 if (time_after(jiffies, timeo)) { 1073 if (time_after(jiffies, timeo)) {
1065 spin_unlock_bh(chip->mutex); 1074 spin_unlock_bh(chip->mutex);
@@ -1088,7 +1097,7 @@ retry:
1088 map_write(map, CMD(0x60), adr); 1097 map_write(map, CMD(0x60), adr);
1089 map_write(map, CMD(0x01), adr); 1098 map_write(map, CMD(0x01), adr);
1090 chip->state = FL_LOCKING; 1099 chip->state = FL_LOCKING;
1091 1100
1092 spin_unlock_bh(chip->mutex); 1101 spin_unlock_bh(chip->mutex);
1093 msleep(1000); 1102 msleep(1000);
1094 spin_lock_bh(chip->mutex); 1103 spin_lock_bh(chip->mutex);
@@ -1102,7 +1111,7 @@ retry:
1102 status = map_read(map, adr); 1111 status = map_read(map, adr);
1103 if (map_word_andequal(map, status, status_OK, status_OK)) 1112 if (map_word_andequal(map, status, status_OK, status_OK))
1104 break; 1113 break;
1105 1114
1106 /* OK Still waiting */ 1115 /* OK Still waiting */
1107 if (time_after(jiffies, timeo)) { 1116 if (time_after(jiffies, timeo)) {
1108 map_write(map, CMD(0x70), adr); 1117 map_write(map, CMD(0x70), adr);
@@ -1112,13 +1121,13 @@ retry:
1112 spin_unlock_bh(chip->mutex); 1121 spin_unlock_bh(chip->mutex);
1113 return -EIO; 1122 return -EIO;
1114 } 1123 }
1115 1124
1116 /* Latency issues. Drop the lock, wait a while and retry */ 1125 /* Latency issues. Drop the lock, wait a while and retry */
1117 spin_unlock_bh(chip->mutex); 1126 spin_unlock_bh(chip->mutex);
1118 cfi_udelay(1); 1127 cfi_udelay(1);
1119 spin_lock_bh(chip->mutex); 1128 spin_lock_bh(chip->mutex);
1120 } 1129 }
1121 1130
1122 /* Done and happy. */ 1131 /* Done and happy. */
1123 chip->state = FL_STATUS; 1132 chip->state = FL_STATUS;
1124 DISABLE_VPP(map); 1133 DISABLE_VPP(map);
@@ -1162,8 +1171,8 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
1162 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);
1163 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)));
1164 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);
1165#endif 1174#endif
1166 1175
1167 if (ret) 1176 if (ret)
1168 return ret; 1177 return ret;
1169 1178
@@ -1173,7 +1182,7 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
1173 if (adr >> cfi->chipshift) { 1182 if (adr >> cfi->chipshift) {
1174 adr = 0; 1183 adr = 0;
1175 chipnum++; 1184 chipnum++;
1176 1185
1177 if (chipnum >= cfi->numchips) 1186 if (chipnum >= cfi->numchips)
1178 break; 1187 break;
1179 } 1188 }
@@ -1208,7 +1217,7 @@ retry:
1208 status = map_read(map, adr); 1217 status = map_read(map, adr);
1209 if (map_word_andequal(map, status, status_OK, status_OK)) 1218 if (map_word_andequal(map, status, status_OK, status_OK))
1210 break; 1219 break;
1211 1220
1212 /* Urgh. Chip not yet ready to talk to us. */ 1221 /* Urgh. Chip not yet ready to talk to us. */
1213 if (time_after(jiffies, timeo)) { 1222 if (time_after(jiffies, timeo)) {
1214 spin_unlock_bh(chip->mutex); 1223 spin_unlock_bh(chip->mutex);
@@ -1237,7 +1246,7 @@ retry:
1237 map_write(map, CMD(0x60), adr); 1246 map_write(map, CMD(0x60), adr);
1238 map_write(map, CMD(0xD0), adr); 1247 map_write(map, CMD(0xD0), adr);
1239 chip->state = FL_UNLOCKING; 1248 chip->state = FL_UNLOCKING;
1240 1249
1241 spin_unlock_bh(chip->mutex); 1250 spin_unlock_bh(chip->mutex);
1242 msleep(1000); 1251 msleep(1000);
1243 spin_lock_bh(chip->mutex); 1252 spin_lock_bh(chip->mutex);
@@ -1251,7 +1260,7 @@ retry:
1251 status = map_read(map, adr); 1260 status = map_read(map, adr);
1252 if (map_word_andequal(map, status, status_OK, status_OK)) 1261 if (map_word_andequal(map, status, status_OK, status_OK))
1253 break; 1262 break;
1254 1263
1255 /* OK Still waiting */ 1264 /* OK Still waiting */
1256 if (time_after(jiffies, timeo)) { 1265 if (time_after(jiffies, timeo)) {
1257 map_write(map, CMD(0x70), adr); 1266 map_write(map, CMD(0x70), adr);
@@ -1261,13 +1270,13 @@ retry:
1261 spin_unlock_bh(chip->mutex); 1270 spin_unlock_bh(chip->mutex);
1262 return -EIO; 1271 return -EIO;
1263 } 1272 }
1264 1273
1265 /* Latency issues. Drop the unlock, wait a while and retry */ 1274 /* Latency issues. Drop the unlock, wait a while and retry */
1266 spin_unlock_bh(chip->mutex); 1275 spin_unlock_bh(chip->mutex);
1267 cfi_udelay(1); 1276 cfi_udelay(1);
1268 spin_lock_bh(chip->mutex); 1277 spin_lock_bh(chip->mutex);
1269 } 1278 }
1270 1279
1271 /* Done and happy. */ 1280 /* Done and happy. */
1272 chip->state = FL_STATUS; 1281 chip->state = FL_STATUS;
1273 DISABLE_VPP(map); 1282 DISABLE_VPP(map);
@@ -1292,7 +1301,7 @@ static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1292 { 1301 {
1293 unsigned long temp_adr = adr; 1302 unsigned long temp_adr = adr;
1294 unsigned long temp_len = len; 1303 unsigned long temp_len = len;
1295 1304
1296 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);
1297 while (temp_len) { 1306 while (temp_len) {
1298 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)));
@@ -1310,7 +1319,7 @@ static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1310 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)));
1311 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);
1312#endif 1321#endif
1313 1322
1314 return ret; 1323 return ret;
1315} 1324}
1316 1325
@@ -1334,7 +1343,7 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
1334 case FL_JEDEC_QUERY: 1343 case FL_JEDEC_QUERY:
1335 chip->oldstate = chip->state; 1344 chip->oldstate = chip->state;
1336 chip->state = FL_PM_SUSPENDED; 1345 chip->state = FL_PM_SUSPENDED;
1337 /* No need to wake_up() on this state change - 1346 /* No need to wake_up() on this state change -
1338 * as the whole point is that nobody can do anything 1347 * as the whole point is that nobody can do anything
1339 * with the chip now anyway. 1348 * with the chip now anyway.
1340 */ 1349 */
@@ -1353,9 +1362,9 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
1353 if (ret) { 1362 if (ret) {
1354 for (i--; i >=0; i--) { 1363 for (i--; i >=0; i--) {
1355 chip = &cfi->chips[i]; 1364 chip = &cfi->chips[i];
1356 1365
1357 spin_lock_bh(chip->mutex); 1366 spin_lock_bh(chip->mutex);
1358 1367
1359 if (chip->state == FL_PM_SUSPENDED) { 1368 if (chip->state == FL_PM_SUSPENDED) {
1360 /* No need to force it into a known state here, 1369 /* No need to force it into a known state here,
1361 because we're returning failure, and it didn't 1370 because we're returning failure, and it didn't
@@ -1365,8 +1374,8 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
1365 } 1374 }
1366 spin_unlock_bh(chip->mutex); 1375 spin_unlock_bh(chip->mutex);
1367 } 1376 }
1368 } 1377 }
1369 1378
1370 return ret; 1379 return ret;
1371} 1380}
1372 1381
@@ -1378,11 +1387,11 @@ static void cfi_staa_resume(struct mtd_info *mtd)
1378 struct flchip *chip; 1387 struct flchip *chip;
1379 1388
1380 for (i=0; i<cfi->numchips; i++) { 1389 for (i=0; i<cfi->numchips; i++) {
1381 1390
1382 chip = &cfi->chips[i]; 1391 chip = &cfi->chips[i];
1383 1392
1384 spin_lock_bh(chip->mutex); 1393 spin_lock_bh(chip->mutex);
1385 1394
1386 /* Go to known state. Chip may have been power cycled */ 1395 /* Go to known state. Chip may have been power cycled */
1387 if (chip->state == FL_PM_SUSPENDED) { 1396 if (chip->state == FL_PM_SUSPENDED) {
1388 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
26static void print_cfi_ident(struct cfi_ident *); 26static 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
192static int __xipram cfi_chip_setup(struct map_info *map, 192static 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
274static char *vendorname(__u16 vendor) 274static 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 2b2ede2bfcca..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.8 2004/12/14 19:55:56 nico 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
@@ -70,15 +70,6 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n
70 local_irq_enable(); 70 local_irq_enable();
71#endif 71#endif
72 72
73 if (extp->MajorVersion != '1' ||
74 (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
75 printk(KERN_WARNING " Unknown %s Extended Query "
76 "version %c.%c.\n", name, extp->MajorVersion,
77 extp->MinorVersion);
78 kfree(extp);
79 extp = NULL;
80 }
81
82 out: return extp; 73 out: return extp;
83} 74}
84 75
@@ -122,17 +113,17 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
122 113
123 i = 0; 114 i = 0;
124 115
125 /* Skip all erase regions which are ended before the start of 116 /* Skip all erase regions which are ended before the start of
126 the requested erase. Actually, to save on the calculations, 117 the requested erase. Actually, to save on the calculations,
127 we skip to the first erase region which starts after the 118 we skip to the first erase region which starts after the
128 start of the requested erase, and then go back one. 119 start of the requested erase, and then go back one.
129 */ 120 */
130 121
131 while (i < mtd->numeraseregions && ofs >= regions[i].offset) 122 while (i < mtd->numeraseregions && ofs >= regions[i].offset)
132 i++; 123 i++;
133 i--; 124 i--;
134 125
135 /* 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
136 erase request starts. Check the start of the requested 127 erase request starts. Check the start of the requested
137 erase range is aligned with the erase size which is in 128 erase range is aligned with the erase size which is in
138 effect here. 129 effect here.
@@ -155,7 +146,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
155 the address actually falls 146 the address actually falls
156 */ 147 */
157 i--; 148 i--;
158 149
159 if ((ofs + len) & (regions[i].erasesize-1)) 150 if ((ofs + len) & (regions[i].erasesize-1))
160 return -EINVAL; 151 return -EINVAL;
161 152
@@ -168,7 +159,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
168 int size = regions[i].erasesize; 159 int size = regions[i].erasesize;
169 160
170 ret = (*frob)(map, &cfi->chips[chipnum], adr, size, thunk); 161 ret = (*frob)(map, &cfi->chips[chipnum], adr, size, thunk);
171 162
172 if (ret) 163 if (ret)
173 return ret; 164 return ret;
174 165
@@ -182,7 +173,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
182 if (adr >> cfi->chipshift) { 173 if (adr >> cfi->chipshift) {
183 adr = 0; 174 adr = 0;
184 chipnum++; 175 chipnum++;
185 176
186 if (chipnum >= cfi->numchips) 177 if (chipnum >= cfi->numchips)
187 break; 178 break;
188 } 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 */
28static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip, 28static 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 dc065b22f79e..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.22 2005/01/24 23:49:50 rmk 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
158static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp, 158static 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;
189extern cfi_cmdset_fn_t cfi_cmdset_0002; 189extern cfi_cmdset_fn_t cfi_cmdset_0002;
190extern cfi_cmdset_fn_t cfi_cmdset_0020; 190extern cfi_cmdset_fn_t cfi_cmdset_0020;
191 191
192static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map, 192static 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
@@ -235,6 +235,7 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
235#ifdef CONFIG_MTD_CFI_INTELEXT 235#ifdef CONFIG_MTD_CFI_INTELEXT
236 case 0x0001: 236 case 0x0001:
237 case 0x0003: 237 case 0x0003:
238 case 0x0200:
238 return cfi_cmdset_0001(map, primary); 239 return cfi_cmdset_0001(map, primary);
239#endif 240#endif
240#ifdef CONFIG_MTD_CFI_AMDSTD 241#ifdef CONFIG_MTD_CFI_AMDSTD
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
89static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id); 89static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id);
90static void jedec_sync(struct mtd_info *mtd) {}; 90static void jedec_sync(struct mtd_info *mtd) {};
91static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, 91static 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);
93static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, 93static 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
96static struct mtd_info *jedec_probe(struct map_info *map); 96static 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 */
295static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count, 295static 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
393static int jedec_probe8(struct map_info *map,unsigned long base, 393static 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. */
530static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, 530static 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.. */
542static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, 542static 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. */
570static void jedec_flash_failed(unsigned char code) 570static 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 */
587static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) 587static 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!*/
795static int flash_write(struct mtd_info *mtd, loff_t start, size_t len, 795static 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
1720static struct mtd_info *jedec_probe(struct map_info *map); 1720static struct mtd_info *jedec_probe(struct map_info *map);
1721 1721
1722static inline u32 jedec_read_mfr(struct map_info *map, __u32 base, 1722static 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
1733static inline u32 jedec_read_id(struct map_info *map, __u32 base, 1733static 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
1744static inline void jedec_reset(u32 base, struct map_info *map, 1744static 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
2106ok_out: 2106ok_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
80static int map_absent_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) 80static 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
86static int map_absent_erase(struct mtd_info *mtd, struct erase_info *instr) 86static 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 c3cf0f63bc93..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.14 2004/08/09 13:19:43 dwmw2 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
@@ -31,6 +31,7 @@
31#include <linux/mtd/cfi.h> 31#include <linux/mtd/cfi.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/init.h> 33#include <linux/init.h>
34#include <linux/slab.h>
34 35
35#define CMD_RESET 0xffffffff 36#define CMD_RESET 0xffffffff
36#define CMD_READ_ID 0x90909090 37#define CMD_READ_ID 0x90909090
@@ -214,7 +215,7 @@ static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
214/* This function returns with the chip->mutex lock held. */ 215/* This function returns with the chip->mutex lock held. */
215static int sharp_wait(struct map_info *map, struct flchip *chip) 216static int sharp_wait(struct map_info *map, struct flchip *chip)
216{ 217{
217 __u16 status; 218 int status, i;
218 unsigned long timeo = jiffies + HZ; 219 unsigned long timeo = jiffies + HZ;
219 DECLARE_WAITQUEUE(wait, current); 220 DECLARE_WAITQUEUE(wait, current);
220 int adr = 0; 221 int adr = 0;
@@ -227,13 +228,11 @@ retry:
227 map_write32(map,CMD_READ_STATUS,adr); 228 map_write32(map,CMD_READ_STATUS,adr);
228 chip->state = FL_STATUS; 229 chip->state = FL_STATUS;
229 case FL_STATUS: 230 case FL_STATUS:
230 status = map_read32(map,adr); 231 for(i=0;i<100;i++){
231//printk("status=%08x\n",status); 232 status = map_read32(map,adr);
232 233 if((status & SR_READY)==SR_READY)
233 udelay(100); 234 break;
234 if((status & SR_READY)!=SR_READY){ 235 udelay(1);
235//printk(".status=%08x\n",status);
236 udelay(100);
237 } 236 }
238 break; 237 break;
239 default: 238 default:
@@ -460,12 +459,12 @@ static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
460 remove_wait_queue(&chip->wq, &wait); 459 remove_wait_queue(&chip->wq, &wait);
461 460
462 //spin_lock_bh(chip->mutex); 461 //spin_lock_bh(chip->mutex);
463 462
464 if (signal_pending(current)){ 463 if (signal_pending(current)){
465 ret = -EINTR; 464 ret = -EINTR;
466 goto out; 465 goto out;
467 } 466 }
468 467
469 } 468 }
470 ret = -ETIME; 469 ret = -ETIME;
471out: 470out:
@@ -564,7 +563,7 @@ static int sharp_suspend(struct mtd_info *mtd)
564static void sharp_resume(struct mtd_info *mtd) 563static void sharp_resume(struct mtd_info *mtd)
565{ 564{
566 printk("sharp_resume()\n"); 565 printk("sharp_resume()\n");
567 566
568} 567}
569 568
570static void sharp_destroy(struct mtd_info *mtd) 569static void sharp_destroy(struct mtd_info *mtd)
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index ef24837019d3..6b8bb2e4dcfd 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -1,24 +1,24 @@
1/* 1/*
2 * $Id: cmdlinepart.c,v 1.18 2005/06/07 15:04:26 joern Exp $ 2 * $Id: cmdlinepart.c,v 1.19 2005/11/07 11:14:19 gleixner Exp $
3 * 3 *
4 * Read flash partition table from command line 4 * Read flash partition table from command line
5 * 5 *
6 * Copyright 2002 SYSGO Real-Time Solutions GmbH 6 * Copyright 2002 SYSGO Real-Time Solutions GmbH
7 * 7 *
8 * The format for the command line is as follows: 8 * The format for the command line is as follows:
9 * 9 *
10 * mtdparts=<mtddef>[;<mtddef] 10 * mtdparts=<mtddef>[;<mtddef]
11 * <mtddef> := <mtd-id>:<partdef>[,<partdef>] 11 * <mtddef> := <mtd-id>:<partdef>[,<partdef>]
12 * <partdef> := <size>[@offset][<name>][ro] 12 * <partdef> := <size>[@offset][<name>][ro]
13 * <mtd-id> := unique name used in mapping driver/device (mtd->name) 13 * <mtd-id> := unique name used in mapping driver/device (mtd->name)
14 * <size> := standard linux memsize OR "-" to denote all remaining space 14 * <size> := standard linux memsize OR "-" to denote all remaining space
15 * <name> := '(' NAME ')' 15 * <name> := '(' NAME ')'
16 * 16 *
17 * Examples: 17 * Examples:
18 * 18 *
19 * 1 NOR Flash, with 1 single writable partition: 19 * 1 NOR Flash, with 1 single writable partition:
20 * edb7312-nor:- 20 * edb7312-nor:-
21 * 21 *
22 * 1 NOR Flash with 2 partitions, 1 NAND with one 22 * 1 NOR Flash with 2 partitions, 1 NAND with one
23 * edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home) 23 * edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home)
24 */ 24 */
@@ -60,17 +60,17 @@ static int cmdline_parsed = 0;
60 60
61/* 61/*
62 * Parse one partition definition for an MTD. Since there can be many 62 * Parse one partition definition for an MTD. Since there can be many
63 * comma separated partition definitions, this function calls itself 63 * comma separated partition definitions, this function calls itself
64 * recursively until no more partition definitions are found. Nice side 64 * recursively until no more partition definitions are found. Nice side
65 * effect: the memory to keep the mtd_partition structs and the names 65 * effect: the memory to keep the mtd_partition structs and the names
66 * is allocated upon the last definition being found. At that point the 66 * is allocated upon the last definition being found. At that point the
67 * syntax has been verified ok. 67 * syntax has been verified ok.
68 */ 68 */
69static struct mtd_partition * newpart(char *s, 69static struct mtd_partition * newpart(char *s,
70 char **retptr, 70 char **retptr,
71 int *num_parts, 71 int *num_parts,
72 int this_part, 72 int this_part,
73 unsigned char **extra_mem_ptr, 73 unsigned char **extra_mem_ptr,
74 int extra_mem_size) 74 int extra_mem_size)
75{ 75{
76 struct mtd_partition *parts; 76 struct mtd_partition *parts;
@@ -102,7 +102,7 @@ static struct mtd_partition * newpart(char *s,
102 mask_flags = 0; /* this is going to be a regular partition */ 102 mask_flags = 0; /* this is going to be a regular partition */
103 delim = 0; 103 delim = 0;
104 /* check for offset */ 104 /* check for offset */
105 if (*s == '@') 105 if (*s == '@')
106 { 106 {
107 s++; 107 s++;
108 offset = memparse(s, &s); 108 offset = memparse(s, &s);
@@ -112,7 +112,7 @@ static struct mtd_partition * newpart(char *s,
112 { 112 {
113 delim = ')'; 113 delim = ')';
114 } 114 }
115 115
116 if (delim) 116 if (delim)
117 { 117 {
118 char *p; 118 char *p;
@@ -131,12 +131,12 @@ static struct mtd_partition * newpart(char *s,
131 name = NULL; 131 name = NULL;
132 name_len = 13; /* Partition_000 */ 132 name_len = 13; /* Partition_000 */
133 } 133 }
134 134
135 /* record name length for memory allocation later */ 135 /* record name length for memory allocation later */
136 extra_mem_size += name_len + 1; 136 extra_mem_size += name_len + 1;
137 137
138 /* test for options */ 138 /* test for options */
139 if (strncmp(s, "ro", 2) == 0) 139 if (strncmp(s, "ro", 2) == 0)
140 { 140 {
141 mask_flags |= MTD_WRITEABLE; 141 mask_flags |= MTD_WRITEABLE;
142 s += 2; 142 s += 2;
@@ -151,7 +151,7 @@ static struct mtd_partition * newpart(char *s,
151 return NULL; 151 return NULL;
152 } 152 }
153 /* more partitions follow, parse them */ 153 /* more partitions follow, parse them */
154 if ((parts = newpart(s + 1, &s, num_parts, 154 if ((parts = newpart(s + 1, &s, num_parts,
155 this_part + 1, &extra_mem, extra_mem_size)) == 0) 155 this_part + 1, &extra_mem, extra_mem_size)) == 0)
156 return NULL; 156 return NULL;
157 } 157 }
@@ -187,7 +187,7 @@ static struct mtd_partition * newpart(char *s,
187 extra_mem += name_len + 1; 187 extra_mem += name_len + 1;
188 188
189 dbg(("partition %d: name <%s>, offset %x, size %x, mask flags %x\n", 189 dbg(("partition %d: name <%s>, offset %x, size %x, mask flags %x\n",
190 this_part, 190 this_part,
191 parts[this_part].name, 191 parts[this_part].name,
192 parts[this_part].offset, 192 parts[this_part].offset,
193 parts[this_part].size, 193 parts[this_part].size,
@@ -204,8 +204,8 @@ static struct mtd_partition * newpart(char *s,
204 return parts; 204 return parts;
205} 205}
206 206
207/* 207/*
208 * Parse the command line. 208 * Parse the command line.
209 */ 209 */
210static int mtdpart_setup_real(char *s) 210static int mtdpart_setup_real(char *s)
211{ 211{
@@ -230,7 +230,7 @@ static int mtdpart_setup_real(char *s)
230 230
231 dbg(("parsing <%s>\n", p+1)); 231 dbg(("parsing <%s>\n", p+1));
232 232
233 /* 233 /*
234 * parse one mtd. have it reserve memory for the 234 * parse one mtd. have it reserve memory for the
235 * struct cmdline_mtd_partition and the mtd-id string. 235 * struct cmdline_mtd_partition and the mtd-id string.
236 */ 236 */
@@ -239,7 +239,7 @@ static int mtdpart_setup_real(char *s)
239 &num_parts, /* out: number of parts */ 239 &num_parts, /* out: number of parts */
240 0, /* first partition */ 240 0, /* first partition */
241 (unsigned char**)&this_mtd, /* out: extra mem */ 241 (unsigned char**)&this_mtd, /* out: extra mem */
242 mtd_id_len + 1 + sizeof(*this_mtd) + 242 mtd_id_len + 1 + sizeof(*this_mtd) +
243 sizeof(void*)-1 /*alignment*/); 243 sizeof(void*)-1 /*alignment*/);
244 if(!parts) 244 if(!parts)
245 { 245 {
@@ -254,21 +254,21 @@ static int mtdpart_setup_real(char *s)
254 } 254 }
255 255
256 /* align this_mtd */ 256 /* align this_mtd */
257 this_mtd = (struct cmdline_mtd_partition *) 257 this_mtd = (struct cmdline_mtd_partition *)
258 ALIGN((unsigned long)this_mtd, sizeof(void*)); 258 ALIGN((unsigned long)this_mtd, sizeof(void*));
259 /* enter results */ 259 /* enter results */
260 this_mtd->parts = parts; 260 this_mtd->parts = parts;
261 this_mtd->num_parts = num_parts; 261 this_mtd->num_parts = num_parts;
262 this_mtd->mtd_id = (char*)(this_mtd + 1); 262 this_mtd->mtd_id = (char*)(this_mtd + 1);
263 strlcpy(this_mtd->mtd_id, mtd_id, mtd_id_len + 1); 263 strlcpy(this_mtd->mtd_id, mtd_id, mtd_id_len + 1);
264 264
265 /* link into chain */ 265 /* link into chain */
266 this_mtd->next = partitions; 266 this_mtd->next = partitions;
267 partitions = this_mtd; 267 partitions = this_mtd;
268 268
269 dbg(("mtdid=<%s> num_parts=<%d>\n", 269 dbg(("mtdid=<%s> num_parts=<%d>\n",
270 this_mtd->mtd_id, this_mtd->num_parts)); 270 this_mtd->mtd_id, this_mtd->num_parts));
271 271
272 272
273 /* EOS - we're done */ 273 /* EOS - we're done */
274 if (*s == 0) 274 if (*s == 0)
@@ -292,7 +292,7 @@ static int mtdpart_setup_real(char *s)
292 * information. It returns partitions for the requested mtd device, or 292 * information. It returns partitions for the requested mtd device, or
293 * the first one in the chain if a NULL mtd_id is passed in. 293 * the first one in the chain if a NULL mtd_id is passed in.
294 */ 294 */
295static int parse_cmdline_partitions(struct mtd_info *master, 295static int parse_cmdline_partitions(struct mtd_info *master,
296 struct mtd_partition **pparts, 296 struct mtd_partition **pparts,
297 unsigned long origin) 297 unsigned long origin)
298{ 298{
@@ -322,7 +322,7 @@ static int parse_cmdline_partitions(struct mtd_info *master,
322 part->parts[i].size = master->size - offset; 322 part->parts[i].size = master->size - offset;
323 if (offset + part->parts[i].size > master->size) 323 if (offset + part->parts[i].size > master->size)
324 { 324 {
325 printk(KERN_WARNING ERRP 325 printk(KERN_WARNING ERRP
326 "%s: partitioning exceeds flash size, truncating\n", 326 "%s: partitioning exceeds flash size, truncating\n",
327 part->mtd_id); 327 part->mtd_id);
328 part->parts[i].size = master->size - offset; 328 part->parts[i].size = master->size - offset;
@@ -338,8 +338,8 @@ static int parse_cmdline_partitions(struct mtd_info *master,
338} 338}
339 339
340 340
341/* 341/*
342 * This is the handler for our kernel parameter, called from 342 * This is the handler for our kernel parameter, called from
343 * main.c::checksetup(). Note that we can not yet kmalloc() anything, 343 * main.c::checksetup(). Note that we can not yet kmalloc() anything,
344 * so we only save the commandline for later processing. 344 * so we only save the commandline for later processing.
345 * 345 *
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index c4a56a4ac5e2..9a2aa4033c6a 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -1,5 +1,5 @@
1# drivers/mtd/maps/Kconfig 1# drivers/mtd/maps/Kconfig
2# $Id: Kconfig,v 1.15 2004/12/22 17:51:15 joern Exp $ 2# $Id: Kconfig,v 1.18 2005/11/07 11:14:24 gleixner Exp $
3 3
4menu "Self-contained MTD device drivers" 4menu "Self-contained MTD device drivers"
5 depends on MTD!=n 5 depends on MTD!=n
@@ -110,7 +110,7 @@ config MTDRAM_ABS_POS
110 If you have system RAM accessible by the CPU but not used by Linux 110 If you have system RAM accessible by the CPU but not used by Linux
111 in normal operation, you can give the physical address at which the 111 in normal operation, you can give the physical address at which the
112 available RAM starts, and the MTDRAM driver will use it instead of 112 available RAM starts, and the MTDRAM driver will use it instead of
113 allocating space from Linux's available memory. Otherwise, leave 113 allocating space from Linux's available memory. Otherwise, leave
114 this set to zero. Most people will want to leave this as zero. 114 this set to zero. Most people will want to leave this as zero.
115 115
116config MTD_BLKMTD 116config MTD_BLKMTD
@@ -165,7 +165,7 @@ config MTD_DOC2001
165 select MTD_DOCPROBE 165 select MTD_DOCPROBE
166 select MTD_NAND_IDS 166 select MTD_NAND_IDS
167 ---help--- 167 ---help---
168 This provides an alternative MTD device driver for the M-Systems 168 This provides an alternative MTD device driver for the M-Systems
169 DiskOnChip Millennium devices. Use this if you have problems with 169 DiskOnChip Millennium devices. Use this if you have problems with
170 the combined DiskOnChip 2000 and Millennium driver above. To get 170 the combined DiskOnChip 2000 and Millennium driver above. To get
171 the DiskOnChip probe code to load and use this driver instead of 171 the DiskOnChip probe code to load and use this driver instead of
@@ -192,7 +192,7 @@ config MTD_DOC2001PLUS
192 192
193 If you use this device, you probably also want to enable the INFTL 193 If you use this device, you probably also want to enable the INFTL
194 'Inverse NAND Flash Translation Layer' option below, which is used 194 'Inverse NAND Flash Translation Layer' option below, which is used
195 to emulate a block device by using a kind of file system on the 195 to emulate a block device by using a kind of file system on the
196 flash chips. 196 flash chips.
197 197
198 NOTE: This driver will soon be replaced by the new DiskOnChip driver 198 NOTE: This driver will soon be replaced by the new DiskOnChip driver
diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
index 662e807801ed..f9db52f6bf00 100644
--- a/drivers/mtd/devices/blkmtd.c
+++ b/drivers/mtd/devices/blkmtd.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: blkmtd.c,v 1.24 2004/11/16 18:29:01 dwmw2 Exp $ 2 * $Id: blkmtd.c,v 1.27 2005/11/07 11:14:24 gleixner Exp $
3 * 3 *
4 * blkmtd.c - use a block device as a fake MTD 4 * blkmtd.c - use a block device as a fake MTD
5 * 5 *
@@ -39,7 +39,7 @@
39 39
40/* Default erase size in K, always make it a multiple of PAGE_SIZE */ 40/* Default erase size in K, always make it a multiple of PAGE_SIZE */
41#define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */ 41#define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */
42#define VERSION "$Revision: 1.24 $" 42#define VERSION "$Revision: 1.27 $"
43 43
44/* Info for the block device */ 44/* Info for the block device */
45struct blkmtd_dev { 45struct blkmtd_dev {
@@ -117,7 +117,7 @@ static int bi_write_complete(struct bio *bio, unsigned int bytes_done, int error
117 unlock_page(page); 117 unlock_page(page);
118 page_cache_release(page); 118 page_cache_release(page);
119 } while (bvec >= bio->bi_io_vec); 119 } while (bvec >= bio->bi_io_vec);
120 120
121 complete((struct completion*)bio->bi_private); 121 complete((struct completion*)bio->bi_private);
122 return 0; 122 return 0;
123} 123}
@@ -135,7 +135,7 @@ static int blkmtd_readpage(struct blkmtd_dev *dev, struct page *page)
135 unlock_page(page); 135 unlock_page(page);
136 return 0; 136 return 0;
137 } 137 }
138 138
139 ClearPageUptodate(page); 139 ClearPageUptodate(page);
140 ClearPageError(page); 140 ClearPageError(page);
141 141
@@ -539,11 +539,8 @@ static void free_device(struct blkmtd_dev *dev)
539{ 539{
540 DEBUG(2, "blkmtd: free_device() dev = %p\n", dev); 540 DEBUG(2, "blkmtd: free_device() dev = %p\n", dev);
541 if(dev) { 541 if(dev) {
542 if(dev->mtd_info.eraseregions) 542 kfree(dev->mtd_info.eraseregions);
543 kfree(dev->mtd_info.eraseregions); 543 kfree(dev->mtd_info.name);
544 if(dev->mtd_info.name)
545 kfree(dev->mtd_info.name);
546
547 if(dev->blkdev) { 544 if(dev->blkdev) {
548 invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping); 545 invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping);
549 close_bdev_excl(dev->blkdev); 546 close_bdev_excl(dev->blkdev);
@@ -710,7 +707,7 @@ static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size
710 dev->mtd_info.erasesize >> 10, 707 dev->mtd_info.erasesize >> 10,
711 readonly ? "(read-only)" : ""); 708 readonly ? "(read-only)" : "");
712 } 709 }
713 710
714 return dev; 711 return dev;
715 712
716 devinit_err: 713 devinit_err:
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 4a7a805e7564..0aaa0ced9aba 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: block2mtd.c,v 1.28 2005/03/19 22:40:44 gleixner Exp $ 2 * $Id: block2mtd.c,v 1.29 2005/11/07 11:14:24 gleixner Exp $
3 * 3 *
4 * block2mtd.c - create an mtd from a block device 4 * block2mtd.c - create an mtd from a block device
5 * 5 *
@@ -19,7 +19,7 @@
19#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
20#include <linux/buffer_head.h> 20#include <linux/buffer_head.h>
21 21
22#define VERSION "$Revision: 1.28 $" 22#define VERSION "$Revision: 1.29 $"
23 23
24 24
25#define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args) 25#define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
@@ -111,7 +111,7 @@ static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len)
111 return PTR_ERR(page); 111 return PTR_ERR(page);
112 112
113 max = (u_long*)page_address(page) + PAGE_SIZE; 113 max = (u_long*)page_address(page) + PAGE_SIZE;
114 for (p=(u_long*)page_address(page); p<max; p++) 114 for (p=(u_long*)page_address(page); p<max; p++)
115 if (*p != -1UL) { 115 if (*p != -1UL) {
116 lock_page(page); 116 lock_page(page);
117 memset(page_address(page), 0xff, PAGE_SIZE); 117 memset(page_address(page), 0xff, PAGE_SIZE);
@@ -206,7 +206,7 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
206 if (retlen) 206 if (retlen)
207 *retlen = 0; 207 *retlen = 0;
208 while (len) { 208 while (len) {
209 if ((offset+len) > PAGE_SIZE) 209 if ((offset+len) > PAGE_SIZE)
210 cpylen = PAGE_SIZE - offset; // multiple pages 210 cpylen = PAGE_SIZE - offset; // multiple pages
211 else 211 else
212 cpylen = len; // this page 212 cpylen = len; // this page
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index 5fc532895a24..be5e88b3888d 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -4,7 +4,7 @@
4 * (c) 1999 Machine Vision Holdings, Inc. 4 * (c) 1999 Machine Vision Holdings, Inc.
5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> 5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
6 * 6 *
7 * $Id: doc2000.c,v 1.66 2005/01/05 18:05:12 dwmw2 Exp $ 7 * $Id: doc2000.c,v 1.67 2005/11/07 11:14:24 gleixner Exp $
8 */ 8 */
9 9
10#include <linux/kernel.h> 10#include <linux/kernel.h>
@@ -58,7 +58,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
58 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); 58 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
59static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, 59static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
60 size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); 60 size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
61static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, 61static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
62 unsigned long count, loff_t to, size_t *retlen, 62 unsigned long count, loff_t to, size_t *retlen,
63 u_char *eccbuf, struct nand_oobinfo *oobsel); 63 u_char *eccbuf, struct nand_oobinfo *oobsel);
64static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 64static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
@@ -76,14 +76,14 @@ static void DoC_Delay(struct DiskOnChip *doc, unsigned short cycles)
76{ 76{
77 volatile char dummy; 77 volatile char dummy;
78 int i; 78 int i;
79 79
80 for (i = 0; i < cycles; i++) { 80 for (i = 0; i < cycles; i++) {
81 if (DoC_is_Millennium(doc)) 81 if (DoC_is_Millennium(doc))
82 dummy = ReadDOC(doc->virtadr, NOP); 82 dummy = ReadDOC(doc->virtadr, NOP);
83 else 83 else
84 dummy = ReadDOC(doc->virtadr, DOCStatus); 84 dummy = ReadDOC(doc->virtadr, DOCStatus);
85 } 85 }
86 86
87} 87}
88 88
89/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */ 89/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
@@ -220,8 +220,8 @@ static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs,
220 WriteDOC(ofs & 0xff, docptr, WritePipeTerm); 220 WriteDOC(ofs & 0xff, docptr, WritePipeTerm);
221 221
222 DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */ 222 DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */
223 223
224 /* FIXME: The SlowIO's for millennium could be replaced by 224 /* FIXME: The SlowIO's for millennium could be replaced by
225 a single WritePipeTerm here. mf. */ 225 a single WritePipeTerm here. mf. */
226 226
227 /* Lower the ALE line */ 227 /* Lower the ALE line */
@@ -377,9 +377,9 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
377 if (mfr == 0xff || mfr == 0) 377 if (mfr == 0xff || mfr == 0)
378 return 0; 378 return 0;
379 379
380 /* Check it's the same as the first chip we identified. 380 /* Check it's the same as the first chip we identified.
381 * M-Systems say that any given DiskOnChip device should only 381 * M-Systems say that any given DiskOnChip device should only
382 * contain _one_ type of flash part, although that's not a 382 * contain _one_ type of flash part, although that's not a
383 * hardware restriction. */ 383 * hardware restriction. */
384 if (doc->mfr) { 384 if (doc->mfr) {
385 if (doc->mfr == mfr && doc->id == id) 385 if (doc->mfr == mfr && doc->id == id)
@@ -397,7 +397,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
397 for (j = 0; nand_manuf_ids[j].id != 0x0; j++) { 397 for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
398 if (nand_manuf_ids[j].id == mfr) 398 if (nand_manuf_ids[j].id == mfr)
399 break; 399 break;
400 } 400 }
401 printk(KERN_INFO 401 printk(KERN_INFO
402 "Flash chip found: Manufacturer ID: %2.2X, " 402 "Flash chip found: Manufacturer ID: %2.2X, "
403 "Chip ID: %2.2X (%s:%s)\n", mfr, id, 403 "Chip ID: %2.2X (%s:%s)\n", mfr, id,
@@ -405,7 +405,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
405 if (!doc->mfr) { 405 if (!doc->mfr) {
406 doc->mfr = mfr; 406 doc->mfr = mfr;
407 doc->id = id; 407 doc->id = id;
408 doc->chipshift = 408 doc->chipshift =
409 ffs((nand_flash_ids[i].chipsize << 20)) - 1; 409 ffs((nand_flash_ids[i].chipsize << 20)) - 1;
410 doc->page256 = (nand_flash_ids[i].pagesize == 256) ? 1 : 0; 410 doc->page256 = (nand_flash_ids[i].pagesize == 256) ? 1 : 0;
411 doc->pageadrlen = doc->chipshift > 25 ? 3 : 2; 411 doc->pageadrlen = doc->chipshift > 25 ? 3 : 2;
@@ -467,7 +467,7 @@ static void DoC_ScanChips(struct DiskOnChip *this, int maxchips)
467 467
468 ret = 0; 468 ret = 0;
469 469
470 /* Fill out the chip array with {floor, chipno} for each 470 /* Fill out the chip array with {floor, chipno} for each
471 * detected chip in the device. */ 471 * detected chip in the device. */
472 for (floor = 0; floor < MAX_FLOORS; floor++) { 472 for (floor = 0; floor < MAX_FLOORS; floor++) {
473 for (chip = 0; chip < numchips[floor]; chip++) { 473 for (chip = 0; chip < numchips[floor]; chip++) {
@@ -757,12 +757,12 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
757 (long)from, eccbuf[0], eccbuf[1], eccbuf[2], 757 (long)from, eccbuf[0], eccbuf[1], eccbuf[2],
758 eccbuf[3], eccbuf[4], eccbuf[5]); 758 eccbuf[3], eccbuf[4], eccbuf[5]);
759#endif 759#endif
760 760
761 /* disable the ECC engine */ 761 /* disable the ECC engine */
762 WriteDOC(DOC_ECC_DIS, docptr , ECCConf); 762 WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
763 } 763 }
764 764
765 /* according to 11.4.1, we need to wait for the busy line 765 /* according to 11.4.1, we need to wait for the busy line
766 * drop if we read to the end of the page. */ 766 * drop if we read to the end of the page. */
767 if(0 == ((from + len) & 0x1ff)) 767 if(0 == ((from + len) & 0x1ff))
768 { 768 {
@@ -941,7 +941,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
941 941
942 /* Let the caller know we completed it */ 942 /* Let the caller know we completed it */
943 *retlen += len; 943 *retlen += len;
944 944
945 if (eccbuf) { 945 if (eccbuf) {
946 unsigned char x[8]; 946 unsigned char x[8];
947 size_t dummy; 947 size_t dummy;
@@ -950,10 +950,10 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
950 /* Write the ECC data to flash */ 950 /* Write the ECC data to flash */
951 for (di=0; di<6; di++) 951 for (di=0; di<6; di++)
952 x[di] = eccbuf[di]; 952 x[di] = eccbuf[di];
953 953
954 x[6]=0x55; 954 x[6]=0x55;
955 x[7]=0x55; 955 x[7]=0x55;
956 956
957 ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x); 957 ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x);
958 if (ret) { 958 if (ret) {
959 up(&this->lock); 959 up(&this->lock);
@@ -970,7 +970,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
970 return 0; 970 return 0;
971} 971}
972 972
973static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, 973static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
974 unsigned long count, loff_t to, size_t *retlen, 974 unsigned long count, loff_t to, size_t *retlen,
975 u_char *eccbuf, struct nand_oobinfo *oobsel) 975 u_char *eccbuf, struct nand_oobinfo *oobsel)
976{ 976{
@@ -1022,7 +1022,7 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
1022 break; 1022 break;
1023 1023
1024 to += thislen; 1024 to += thislen;
1025 } 1025 }
1026 1026
1027 up(&writev_buf_sem); 1027 up(&writev_buf_sem);
1028 *retlen = totretlen; 1028 *retlen = totretlen;
@@ -1080,7 +1080,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1080 /* Reading the full OOB data drops us off of the end of the page, 1080 /* Reading the full OOB data drops us off of the end of the page,
1081 * causing the flash device to go into busy mode, so we need 1081 * causing the flash device to go into busy mode, so we need
1082 * to wait until ready 11.4.1 and Toshiba TC58256FT docs */ 1082 * to wait until ready 11.4.1 and Toshiba TC58256FT docs */
1083 1083
1084 ret = DoC_WaitReady(this); 1084 ret = DoC_WaitReady(this);
1085 1085
1086 up(&this->lock); 1086 up(&this->lock);
@@ -1190,7 +1190,7 @@ static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
1190 return 0; 1190 return 0;
1191 1191
1192} 1192}
1193 1193
1194static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 1194static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1195 size_t * retlen, const u_char * buf) 1195 size_t * retlen, const u_char * buf)
1196{ 1196{
@@ -1222,7 +1222,7 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
1222 } 1222 }
1223 1223
1224 instr->state = MTD_ERASING; 1224 instr->state = MTD_ERASING;
1225 1225
1226 /* FIXME: Do this in the background. Use timers or schedule_task() */ 1226 /* FIXME: Do this in the background. Use timers or schedule_task() */
1227 while(len) { 1227 while(len) {
1228 mychip = &this->chips[ofs >> this->chipshift]; 1228 mychip = &this->chips[ofs >> this->chipshift];
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index 1e704915ef08..fcb28a6fd89f 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -4,7 +4,7 @@
4 * (c) 1999 Machine Vision Holdings, Inc. 4 * (c) 1999 Machine Vision Holdings, Inc.
5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> 5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
6 * 6 *
7 * $Id: doc2001.c,v 1.48 2005/01/05 18:05:12 dwmw2 Exp $ 7 * $Id: doc2001.c,v 1.49 2005/11/07 11:14:24 gleixner Exp $
8 */ 8 */
9 9
10#include <linux/kernel.h> 10#include <linux/kernel.h>
@@ -196,10 +196,10 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
196 DoC_Command(doc->virtadr, NAND_CMD_RESET, CDSN_CTRL_WP); 196 DoC_Command(doc->virtadr, NAND_CMD_RESET, CDSN_CTRL_WP);
197 DoC_WaitReady(doc->virtadr); 197 DoC_WaitReady(doc->virtadr);
198 198
199 /* Read the NAND chip ID: 1. Send ReadID command */ 199 /* Read the NAND chip ID: 1. Send ReadID command */
200 DoC_Command(doc->virtadr, NAND_CMD_READID, CDSN_CTRL_WP); 200 DoC_Command(doc->virtadr, NAND_CMD_READID, CDSN_CTRL_WP);
201 201
202 /* Read the NAND chip ID: 2. Send address byte zero */ 202 /* Read the NAND chip ID: 2. Send address byte zero */
203 DoC_Address(doc->virtadr, 1, 0x00, CDSN_CTRL_WP, 0x00); 203 DoC_Address(doc->virtadr, 1, 0x00, CDSN_CTRL_WP, 0x00);
204 204
205 /* Read the manufacturer and device id codes of the flash device through 205 /* Read the manufacturer and device id codes of the flash device through
@@ -223,7 +223,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
223 for (j = 0; nand_manuf_ids[j].id != 0x0; j++) { 223 for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
224 if (nand_manuf_ids[j].id == mfr) 224 if (nand_manuf_ids[j].id == mfr)
225 break; 225 break;
226 } 226 }
227 printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, " 227 printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, "
228 "Chip ID: %2.2X (%s:%s)\n", 228 "Chip ID: %2.2X (%s:%s)\n",
229 mfr, id, nand_manuf_ids[j].name, nand_flash_ids[i].name); 229 mfr, id, nand_manuf_ids[j].name, nand_flash_ids[i].name);
@@ -275,7 +275,7 @@ static void DoC_ScanChips(struct DiskOnChip *this)
275 return; 275 return;
276 } 276 }
277 277
278 /* Fill out the chip array with {floor, chipno} for each 278 /* Fill out the chip array with {floor, chipno} for each
279 * detected chip in the device. */ 279 * detected chip in the device. */
280 for (floor = 0, ret = 0; floor < MAX_FLOORS_MIL; floor++) { 280 for (floor = 0, ret = 0; floor < MAX_FLOORS_MIL; floor++) {
281 for (chip = 0 ; chip < numchips[floor] ; chip++) { 281 for (chip = 0 ; chip < numchips[floor] ; chip++) {
@@ -309,7 +309,7 @@ static int DoCMil_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
309 tmp2 = ReadDOC(doc2->virtadr, AliasResolution); 309 tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
310 if (tmp1 != tmp2) 310 if (tmp1 != tmp2)
311 return 0; 311 return 0;
312 312
313 WriteDOC((tmp1+1) % 0xff, doc1->virtadr, AliasResolution); 313 WriteDOC((tmp1+1) % 0xff, doc1->virtadr, AliasResolution);
314 tmp2 = ReadDOC(doc2->virtadr, AliasResolution); 314 tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
315 if (tmp2 == (tmp1+1) % 0xff) 315 if (tmp2 == (tmp1+1) % 0xff)
@@ -425,7 +425,7 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
425 return -EINVAL; 425 return -EINVAL;
426 426
427 /* Don't allow a single read to cross a 512-byte block boundary */ 427 /* Don't allow a single read to cross a 512-byte block boundary */
428 if (from + len > ((from | 0x1ff) + 1)) 428 if (from + len > ((from | 0x1ff) + 1))
429 len = ((from | 0x1ff) + 1) - from; 429 len = ((from | 0x1ff) + 1) - from;
430 430
431 /* Find the chip which is to be used and select it */ 431 /* Find the chip which is to be used and select it */
@@ -552,7 +552,7 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
552 552
553#if 0 553#if 0
554 /* Don't allow a single write to cross a 512-byte block boundary */ 554 /* Don't allow a single write to cross a 512-byte block boundary */
555 if (to + len > ( (to | 0x1ff) + 1)) 555 if (to + len > ( (to | 0x1ff) + 1))
556 len = ((to | 0x1ff) + 1) - to; 556 len = ((to | 0x1ff) + 1) - to;
557#else 557#else
558 /* Don't allow writes which aren't exactly one block */ 558 /* Don't allow writes which aren't exactly one block */
@@ -632,7 +632,7 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
632 632
633 /* write the block status BLOCK_USED (0x5555) at the end of ECC data 633 /* write the block status BLOCK_USED (0x5555) at the end of ECC data
634 FIXME: this is only a hack for programming the IPL area for LinuxBIOS 634 FIXME: this is only a hack for programming the IPL area for LinuxBIOS
635 and should be replace with proper codes in user space utilities */ 635 and should be replace with proper codes in user space utilities */
636 WriteDOC(0x55, docptr, Mil_CDSN_IO); 636 WriteDOC(0x55, docptr, Mil_CDSN_IO);
637 WriteDOC(0x55, docptr, Mil_CDSN_IO + 1); 637 WriteDOC(0x55, docptr, Mil_CDSN_IO + 1);
638 638
@@ -802,7 +802,7 @@ int doc_erase (struct mtd_info *mtd, struct erase_info *instr)
802 void __iomem *docptr = this->virtadr; 802 void __iomem *docptr = this->virtadr;
803 struct Nand *mychip = &this->chips[ofs >> this->chipshift]; 803 struct Nand *mychip = &this->chips[ofs >> this->chipshift];
804 804
805 if (len != mtd->erasesize) 805 if (len != mtd->erasesize)
806 printk(KERN_WARNING "Erase not right size (%x != %x)n", 806 printk(KERN_WARNING "Erase not right size (%x != %x)n",
807 len, mtd->erasesize); 807 len, mtd->erasesize);
808 808
@@ -870,9 +870,9 @@ static void __exit cleanup_doc2001(void)
870 while ((mtd=docmillist)) { 870 while ((mtd=docmillist)) {
871 this = mtd->priv; 871 this = mtd->priv;
872 docmillist = this->nextdoc; 872 docmillist = this->nextdoc;
873 873
874 del_mtd_device(mtd); 874 del_mtd_device(mtd);
875 875
876 iounmap(this->virtadr); 876 iounmap(this->virtadr);
877 kfree(this->chips); 877 kfree(this->chips);
878 kfree(mtd); 878 kfree(mtd);
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index ed47bafb2ce2..0595cc7324b2 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -6,7 +6,7 @@
6 * (c) 1999 Machine Vision Holdings, Inc. 6 * (c) 1999 Machine Vision Holdings, Inc.
7 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> 7 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
8 * 8 *
9 * $Id: doc2001plus.c,v 1.13 2005/01/05 18:05:12 dwmw2 Exp $ 9 * $Id: doc2001plus.c,v 1.14 2005/11/07 11:14:24 gleixner Exp $
10 * 10 *
11 * Released under GPL 11 * Released under GPL
12 */ 12 */
@@ -293,10 +293,10 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
293 DoC_Command(docptr, NAND_CMD_RESET, 0); 293 DoC_Command(docptr, NAND_CMD_RESET, 0);
294 DoC_WaitReady(docptr); 294 DoC_WaitReady(docptr);
295 295
296 /* Read the NAND chip ID: 1. Send ReadID command */ 296 /* Read the NAND chip ID: 1. Send ReadID command */
297 DoC_Command(docptr, NAND_CMD_READID, 0); 297 DoC_Command(docptr, NAND_CMD_READID, 0);
298 298
299 /* Read the NAND chip ID: 2. Send address byte zero */ 299 /* Read the NAND chip ID: 2. Send address byte zero */
300 DoC_Address(doc, 1, 0x00, 0, 0x00); 300 DoC_Address(doc, 1, 0x00, 0, 0x00);
301 301
302 WriteDOC(0, docptr, Mplus_FlashControl); 302 WriteDOC(0, docptr, Mplus_FlashControl);
@@ -365,7 +365,7 @@ static void DoC_ScanChips(struct DiskOnChip *this)
365 this->interleave = 1; 365 this->interleave = 1;
366 366
367 /* Check the ASIC agrees */ 367 /* Check the ASIC agrees */
368 if ( (this->interleave << 2) != 368 if ( (this->interleave << 2) !=
369 (ReadDOC(this->virtadr, Mplus_Configuration) & 4)) { 369 (ReadDOC(this->virtadr, Mplus_Configuration) & 4)) {
370 u_char conf = ReadDOC(this->virtadr, Mplus_Configuration); 370 u_char conf = ReadDOC(this->virtadr, Mplus_Configuration);
371 printk(KERN_NOTICE "Setting DiskOnChip Millennium Plus interleave to %s\n", 371 printk(KERN_NOTICE "Setting DiskOnChip Millennium Plus interleave to %s\n",
@@ -398,7 +398,7 @@ static void DoC_ScanChips(struct DiskOnChip *this)
398 return; 398 return;
399 } 399 }
400 400
401 /* Fill out the chip array with {floor, chipno} for each 401 /* Fill out the chip array with {floor, chipno} for each
402 * detected chip in the device. */ 402 * detected chip in the device. */
403 for (floor = 0, ret = 0; floor < MAX_FLOORS_MPLUS; floor++) { 403 for (floor = 0, ret = 0; floor < MAX_FLOORS_MPLUS; floor++) {
404 for (chip = 0 ; chip < numchips[floor] ; chip++) { 404 for (chip = 0 ; chip < numchips[floor] ; chip++) {
@@ -432,7 +432,7 @@ static int DoCMilPlus_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
432 tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution); 432 tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
433 if (tmp1 != tmp2) 433 if (tmp1 != tmp2)
434 return 0; 434 return 0;
435 435
436 WriteDOC((tmp1+1) % 0xff, doc1->virtadr, Mplus_AliasResolution); 436 WriteDOC((tmp1+1) % 0xff, doc1->virtadr, Mplus_AliasResolution);
437 tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution); 437 tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
438 if (tmp2 == (tmp1+1) % 0xff) 438 if (tmp2 == (tmp1+1) % 0xff)
@@ -624,7 +624,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
624 return -EINVAL; 624 return -EINVAL;
625 625
626 /* Don't allow a single read to cross a 512-byte block boundary */ 626 /* Don't allow a single read to cross a 512-byte block boundary */
627 if (from + len > ((from | 0x1ff) + 1)) 627 if (from + len > ((from | 0x1ff) + 1))
628 len = ((from | 0x1ff) + 1) - from; 628 len = ((from | 0x1ff) + 1) - from;
629 629
630 DoC_CheckASIC(docptr); 630 DoC_CheckASIC(docptr);
@@ -1066,7 +1066,7 @@ int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
1066 1066
1067 DoC_CheckASIC(docptr); 1067 DoC_CheckASIC(docptr);
1068 1068
1069 if (len != mtd->erasesize) 1069 if (len != mtd->erasesize)
1070 printk(KERN_WARNING "MTD: Erase not right size (%x != %x)n", 1070 printk(KERN_WARNING "MTD: Erase not right size (%x != %x)n",
1071 len, mtd->erasesize); 1071 len, mtd->erasesize);
1072 1072
@@ -1136,9 +1136,9 @@ static void __exit cleanup_doc2001plus(void)
1136 while ((mtd=docmilpluslist)) { 1136 while ((mtd=docmilpluslist)) {
1137 this = mtd->priv; 1137 this = mtd->priv;
1138 docmilpluslist = this->nextdoc; 1138 docmilpluslist = this->nextdoc;
1139 1139
1140 del_mtd_device(mtd); 1140 del_mtd_device(mtd);
1141 1141
1142 iounmap(this->virtadr); 1142 iounmap(this->virtadr);
1143 kfree(this->chips); 1143 kfree(this->chips);
1144 kfree(mtd); 1144 kfree(mtd);
diff --git a/drivers/mtd/devices/docecc.c b/drivers/mtd/devices/docecc.c
index 24f670b5a4f3..cd3db72bef96 100644
--- a/drivers/mtd/devices/docecc.c
+++ b/drivers/mtd/devices/docecc.c
@@ -4,10 +4,10 @@
4 * GNU GPL License. The rest is simply to convert the disk on chip 4 * GNU GPL License. The rest is simply to convert the disk on chip
5 * syndrom into a standard syndom. 5 * syndrom into a standard syndom.
6 * 6 *
7 * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 7 * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
8 * Copyright (C) 2000 Netgem S.A. 8 * Copyright (C) 2000 Netgem S.A.
9 * 9 *
10 * $Id: docecc.c,v 1.5 2003/05/21 15:15:06 dwmw2 Exp $ 10 * $Id: docecc.c,v 1.7 2005/11/07 11:14:25 gleixner Exp $
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 13 * it under the terms of the GNU General Public License as published by
@@ -122,7 +122,7 @@ for(ci=(n)-1;ci >=0;ci--)\
122 a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1) 122 a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1)
123 we consider the integer "i" whose binary representation with a(0) being LSB 123 we consider the integer "i" whose binary representation with a(0) being LSB
124 and a(m-1) MSB is (a(0),a(1),...,a(m-1)) and locate the entry 124 and a(m-1) MSB is (a(0),a(1),...,a(m-1)) and locate the entry
125 "index_of[i]". Now, @^index_of[i] is that element whose polynomial 125 "index_of[i]". Now, @^index_of[i] is that element whose polynomial
126 representation is (a(0),a(1),a(2),...,a(m-1)). 126 representation is (a(0),a(1),a(2),...,a(m-1)).
127 NOTE: 127 NOTE:
128 The element alpha_to[2^m-1] = 0 always signifying that the 128 The element alpha_to[2^m-1] = 0 always signifying that the
@@ -130,7 +130,7 @@ for(ci=(n)-1;ci >=0;ci--)\
130 Similarily, the element index_of[0] = A0 always signifying 130 Similarily, the element index_of[0] = A0 always signifying
131 that the power of alpha which has the polynomial representation 131 that the power of alpha which has the polynomial representation
132 (0,0,...,0) is "infinity". 132 (0,0,...,0) is "infinity".
133 133
134*/ 134*/
135 135
136static void 136static void
@@ -176,7 +176,7 @@ generate_gf(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1])
176 * are written back. NOTE! This array must be at least NN-KK elements long. 176 * are written back. NOTE! This array must be at least NN-KK elements long.
177 * The corrected data are written in eras_val[]. They must be xor with the data 177 * The corrected data are written in eras_val[]. They must be xor with the data
178 * to retrieve the correct data : data[erase_pos[i]] ^= erase_val[i] . 178 * to retrieve the correct data : data[erase_pos[i]] ^= erase_val[i] .
179 * 179 *
180 * First "no_eras" erasures are declared by the calling program. Then, the 180 * First "no_eras" erasures are declared by the calling program. Then, the
181 * maximum # of errors correctable is t_after_eras = floor((NN-KK-no_eras)/2). 181 * maximum # of errors correctable is t_after_eras = floor((NN-KK-no_eras)/2).
182 * If the number of channel errors is not greater than "t_after_eras" the 182 * If the number of channel errors is not greater than "t_after_eras" the
@@ -189,7 +189,7 @@ generate_gf(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1])
189 * */ 189 * */
190static int 190static int
191eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1], 191eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
192 gf bb[NN - KK + 1], gf eras_val[NN-KK], int eras_pos[NN-KK], 192 gf bb[NN - KK + 1], gf eras_val[NN-KK], int eras_pos[NN-KK],
193 int no_eras) 193 int no_eras)
194{ 194{
195 int deg_lambda, el, deg_omega; 195 int deg_lambda, el, deg_omega;
@@ -212,7 +212,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
212 count = 0; 212 count = 0;
213 goto finish; 213 goto finish;
214 } 214 }
215 215
216 for(i=1;i<=NN-KK;i++){ 216 for(i=1;i<=NN-KK;i++){
217 s[i] = bb[0]; 217 s[i] = bb[0];
218 } 218 }
@@ -220,7 +220,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
220 if(bb[j] == 0) 220 if(bb[j] == 0)
221 continue; 221 continue;
222 tmp = Index_of[bb[j]]; 222 tmp = Index_of[bb[j]];
223 223
224 for(i=1;i<=NN-KK;i++) 224 for(i=1;i<=NN-KK;i++)
225 s[i] ^= Alpha_to[modnn(tmp + (B0+i-1)*PRIM*j)]; 225 s[i] ^= Alpha_to[modnn(tmp + (B0+i-1)*PRIM*j)];
226 } 226 }
@@ -234,7 +234,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
234 tmp = modnn(tmp + 2 * KK * (B0+i-1)*PRIM); 234 tmp = modnn(tmp + 2 * KK * (B0+i-1)*PRIM);
235 s[i] = tmp; 235 s[i] = tmp;
236 } 236 }
237 237
238 CLEAR(&lambda[1],NN-KK); 238 CLEAR(&lambda[1],NN-KK);
239 lambda[0] = 1; 239 lambda[0] = 1;
240 240
@@ -252,7 +252,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
252#if DEBUG_ECC >= 1 252#if DEBUG_ECC >= 1
253 /* Test code that verifies the erasure locator polynomial just constructed 253 /* Test code that verifies the erasure locator polynomial just constructed
254 Needed only for decoder debugging. */ 254 Needed only for decoder debugging. */
255 255
256 /* find roots of the erasure location polynomial */ 256 /* find roots of the erasure location polynomial */
257 for(i=1;i<=no_eras;i++) 257 for(i=1;i<=no_eras;i++)
258 reg[i] = Index_of[lambda[i]]; 258 reg[i] = Index_of[lambda[i]];
@@ -286,7 +286,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
286 } 286 }
287 for(i=0;i<NN-KK+1;i++) 287 for(i=0;i<NN-KK+1;i++)
288 b[i] = Index_of[lambda[i]]; 288 b[i] = Index_of[lambda[i]];
289 289
290 /* 290 /*
291 * Begin Berlekamp-Massey algorithm to determine error+erasure 291 * Begin Berlekamp-Massey algorithm to determine error+erasure
292 * locator polynomial 292 * locator polynomial
@@ -389,7 +389,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
389 omega[i] = Index_of[tmp]; 389 omega[i] = Index_of[tmp];
390 } 390 }
391 omega[NN-KK] = A0; 391 omega[NN-KK] = A0;
392 392
393 /* 393 /*
394 * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 = 394 * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
395 * inv(X(l))**(B0-1) and den = lambda_pr(inv(X(l))) all in poly-form 395 * inv(X(l))**(B0-1) and den = lambda_pr(inv(X(l))) all in poly-form
@@ -402,7 +402,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
402 } 402 }
403 num2 = Alpha_to[modnn(root[j] * (B0 - 1) + NN)]; 403 num2 = Alpha_to[modnn(root[j] * (B0 - 1) + NN)];
404 den = 0; 404 den = 0;
405 405
406 /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */ 406 /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
407 for (i = min(deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) { 407 for (i = min(deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) {
408 if(lambda[i+1] != A0) 408 if(lambda[i+1] != A0)
@@ -436,11 +436,11 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
436/* The sector bytes are packed into NB_DATA MM bits words */ 436/* The sector bytes are packed into NB_DATA MM bits words */
437#define NB_DATA (((SECTOR_SIZE + 1) * 8 + 6) / MM) 437#define NB_DATA (((SECTOR_SIZE + 1) * 8 + 6) / MM)
438 438
439/* 439/*
440 * Correct the errors in 'sector[]' by using 'ecc1[]' which is the 440 * Correct the errors in 'sector[]' by using 'ecc1[]' which is the
441 * content of the feedback shift register applyied to the sector and 441 * content of the feedback shift register applyied to the sector and
442 * the ECC. Return the number of errors corrected (and correct them in 442 * the ECC. Return the number of errors corrected (and correct them in
443 * sector), or -1 if error 443 * sector), or -1 if error
444 */ 444 */
445int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6]) 445int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
446{ 446{
@@ -454,7 +454,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
454 Alpha_to = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL); 454 Alpha_to = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL);
455 if (!Alpha_to) 455 if (!Alpha_to)
456 return -1; 456 return -1;
457 457
458 Index_of = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL); 458 Index_of = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL);
459 if (!Index_of) { 459 if (!Index_of) {
460 kfree(Alpha_to); 460 kfree(Alpha_to);
@@ -470,7 +470,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
470 bb[2] = ((ecc1[2] & 0xf0) >> 4) | ((ecc1[3] & 0x3f) << 4); 470 bb[2] = ((ecc1[2] & 0xf0) >> 4) | ((ecc1[3] & 0x3f) << 4);
471 bb[3] = ((ecc1[3] & 0xc0) >> 6) | ((ecc1[0] & 0xff) << 2); 471 bb[3] = ((ecc1[3] & 0xc0) >> 6) | ((ecc1[0] & 0xff) << 2);
472 472
473 nb_errors = eras_dec_rs(Alpha_to, Index_of, bb, 473 nb_errors = eras_dec_rs(Alpha_to, Index_of, bb,
474 error_val, error_pos, 0); 474 error_val, error_pos, 0);
475 if (nb_errors <= 0) 475 if (nb_errors <= 0)
476 goto the_end; 476 goto the_end;
@@ -489,7 +489,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
489 can be modified since pos is even */ 489 can be modified since pos is even */
490 index = (pos >> 3) ^ 1; 490 index = (pos >> 3) ^ 1;
491 bitpos = pos & 7; 491 bitpos = pos & 7;
492 if ((index >= 0 && index < SECTOR_SIZE) || 492 if ((index >= 0 && index < SECTOR_SIZE) ||
493 index == (SECTOR_SIZE + 1)) { 493 index == (SECTOR_SIZE + 1)) {
494 val = error_val[i] >> (2 + bitpos); 494 val = error_val[i] >> (2 + bitpos);
495 parity ^= val; 495 parity ^= val;
@@ -500,7 +500,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
500 bitpos = (bitpos + 10) & 7; 500 bitpos = (bitpos + 10) & 7;
501 if (bitpos == 0) 501 if (bitpos == 0)
502 bitpos = 8; 502 bitpos = 8;
503 if ((index >= 0 && index < SECTOR_SIZE) || 503 if ((index >= 0 && index < SECTOR_SIZE) ||
504 index == (SECTOR_SIZE + 1)) { 504 index == (SECTOR_SIZE + 1)) {
505 val = error_val[i] << (8 - bitpos); 505 val = error_val[i] << (8 - bitpos);
506 parity ^= val; 506 parity ^= val;
@@ -509,7 +509,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
509 } 509 }
510 } 510 }
511 } 511 }
512 512
513 /* use parity to test extra errors */ 513 /* use parity to test extra errors */
514 if ((parity & 0xff) != 0) 514 if ((parity & 0xff) != 0)
515 nb_errors = -1; 515 nb_errors = -1;
diff --git a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c
index 197d67045e1e..13178b9dd00a 100644
--- a/drivers/mtd/devices/docprobe.c
+++ b/drivers/mtd/devices/docprobe.c
@@ -4,22 +4,22 @@
4/* (C) 1999 Machine Vision Holdings, Inc. */ 4/* (C) 1999 Machine Vision Holdings, Inc. */
5/* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> */ 5/* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> */
6 6
7/* $Id: docprobe.c,v 1.44 2005/01/05 12:40:36 dwmw2 Exp $ */ 7/* $Id: docprobe.c,v 1.46 2005/11/07 11:14:25 gleixner Exp $ */
8 8
9 9
10 10
11/* DOC_PASSIVE_PROBE: 11/* DOC_PASSIVE_PROBE:
12 In order to ensure that the BIOS checksum is correct at boot time, and 12 In order to ensure that the BIOS checksum is correct at boot time, and
13 hence that the onboard BIOS extension gets executed, the DiskOnChip 13 hence that the onboard BIOS extension gets executed, the DiskOnChip
14 goes into reset mode when it is read sequentially: all registers 14 goes into reset mode when it is read sequentially: all registers
15 return 0xff until the chip is woken up again by writing to the 15 return 0xff until the chip is woken up again by writing to the
16 DOCControl register. 16 DOCControl register.
17 17
18 Unfortunately, this means that the probe for the DiskOnChip is unsafe, 18 Unfortunately, this means that the probe for the DiskOnChip is unsafe,
19 because one of the first things it does is write to where it thinks 19 because one of the first things it does is write to where it thinks
20 the DOCControl register should be - which may well be shared memory 20 the DOCControl register should be - which may well be shared memory
21 for another device. I've had machines which lock up when this is 21 for another device. I've had machines which lock up when this is
22 attempted. Hence the possibility to do a passive probe, which will fail 22 attempted. Hence the possibility to do a passive probe, which will fail
23 to detect a chip in reset mode, but is at least guaranteed not to lock 23 to detect a chip in reset mode, but is at least guaranteed not to lock
24 the machine. 24 the machine.
25 25
@@ -33,9 +33,9 @@
33 33
34 The old Millennium-only driver has been retained just in case there 34 The old Millennium-only driver has been retained just in case there
35 are problems with the new code. If the combined driver doesn't work 35 are problems with the new code. If the combined driver doesn't work
36 for you, you can try the old one by undefining DOC_SINGLE_DRIVER 36 for you, you can try the old one by undefining DOC_SINGLE_DRIVER
37 below and also enabling it in your configuration. If this fixes the 37 below and also enabling it in your configuration. If this fixes the
38 problems, please send a report to the MTD mailing list at 38 problems, please send a report to the MTD mailing list at
39 <linux-mtd@lists.infradead.org>. 39 <linux-mtd@lists.infradead.org>.
40*/ 40*/
41#define DOC_SINGLE_DRIVER 41#define DOC_SINGLE_DRIVER
@@ -68,16 +68,16 @@ MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe
68static unsigned long __initdata doc_locations[] = { 68static unsigned long __initdata doc_locations[] = {
69#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__) 69#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
70#ifdef CONFIG_MTD_DOCPROBE_HIGH 70#ifdef CONFIG_MTD_DOCPROBE_HIGH
71 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, 71 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
72 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000, 72 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
73 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, 73 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
74 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000, 74 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
75 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000, 75 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
76#else /* CONFIG_MTD_DOCPROBE_HIGH */ 76#else /* CONFIG_MTD_DOCPROBE_HIGH */
77 0xc8000, 0xca000, 0xcc000, 0xce000, 77 0xc8000, 0xca000, 0xcc000, 0xce000,
78 0xd0000, 0xd2000, 0xd4000, 0xd6000, 78 0xd0000, 0xd2000, 0xd4000, 0xd6000,
79 0xd8000, 0xda000, 0xdc000, 0xde000, 79 0xd8000, 0xda000, 0xdc000, 0xde000,
80 0xe0000, 0xe2000, 0xe4000, 0xe6000, 80 0xe0000, 0xe2000, 0xe4000, 0xe6000,
81 0xe8000, 0xea000, 0xec000, 0xee000, 81 0xe8000, 0xea000, 0xec000, 0xee000,
82#endif /* CONFIG_MTD_DOCPROBE_HIGH */ 82#endif /* CONFIG_MTD_DOCPROBE_HIGH */
83#elif defined(__PPC__) 83#elif defined(__PPC__)
@@ -111,35 +111,35 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
111 return 0; 111 return 0;
112#endif /* CONFIG_MTD_DOCPROBE_55AA */ 112#endif /* CONFIG_MTD_DOCPROBE_55AA */
113 113
114#ifndef DOC_PASSIVE_PROBE 114#ifndef DOC_PASSIVE_PROBE
115 /* It's not possible to cleanly detect the DiskOnChip - the 115 /* It's not possible to cleanly detect the DiskOnChip - the
116 * bootup procedure will put the device into reset mode, and 116 * bootup procedure will put the device into reset mode, and
117 * it's not possible to talk to it without actually writing 117 * it's not possible to talk to it without actually writing
118 * to the DOCControl register. So we store the current contents 118 * to the DOCControl register. So we store the current contents
119 * of the DOCControl register's location, in case we later decide 119 * of the DOCControl register's location, in case we later decide
120 * that it's not a DiskOnChip, and want to put it back how we 120 * that it's not a DiskOnChip, and want to put it back how we
121 * found it. 121 * found it.
122 */ 122 */
123 tmp2 = ReadDOC(window, DOCControl); 123 tmp2 = ReadDOC(window, DOCControl);
124 124
125 /* Reset the DiskOnChip ASIC */ 125 /* Reset the DiskOnChip ASIC */
126 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 126 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
127 window, DOCControl); 127 window, DOCControl);
128 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 128 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
129 window, DOCControl); 129 window, DOCControl);
130 130
131 /* Enable the DiskOnChip ASIC */ 131 /* Enable the DiskOnChip ASIC */
132 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 132 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
133 window, DOCControl); 133 window, DOCControl);
134 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 134 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
135 window, DOCControl); 135 window, DOCControl);
136#endif /* !DOC_PASSIVE_PROBE */ 136#endif /* !DOC_PASSIVE_PROBE */
137 137
138 /* We need to read the ChipID register four times. For some 138 /* We need to read the ChipID register four times. For some
139 newer DiskOnChip 2000 units, the first three reads will 139 newer DiskOnChip 2000 units, the first three reads will
140 return the DiskOnChip Millennium ident. Don't ask. */ 140 return the DiskOnChip Millennium ident. Don't ask. */
141 ChipID = ReadDOC(window, ChipID); 141 ChipID = ReadDOC(window, ChipID);
142 142
143 switch (ChipID) { 143 switch (ChipID) {
144 case DOC_ChipID_Doc2k: 144 case DOC_ChipID_Doc2k:
145 /* Check the TOGGLE bit in the ECC register */ 145 /* Check the TOGGLE bit in the ECC register */
@@ -149,7 +149,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
149 if (tmp != tmpb && tmp == tmpc) 149 if (tmp != tmpb && tmp == tmpc)
150 return ChipID; 150 return ChipID;
151 break; 151 break;
152 152
153 case DOC_ChipID_DocMil: 153 case DOC_ChipID_DocMil:
154 /* Check for the new 2000 with Millennium ASIC */ 154 /* Check for the new 2000 with Millennium ASIC */
155 ReadDOC(window, ChipID); 155 ReadDOC(window, ChipID);
@@ -164,7 +164,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
164 if (tmp != tmpb && tmp == tmpc) 164 if (tmp != tmpb && tmp == tmpc)
165 return ChipID; 165 return ChipID;
166 break; 166 break;
167 167
168 case DOC_ChipID_DocMilPlus16: 168 case DOC_ChipID_DocMilPlus16:
169 case DOC_ChipID_DocMilPlus32: 169 case DOC_ChipID_DocMilPlus32:
170 case 0: 170 case 0:
@@ -179,7 +179,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
179 DOC_MODE_BDECT; 179 DOC_MODE_BDECT;
180 WriteDOC(tmp, window, Mplus_DOCControl); 180 WriteDOC(tmp, window, Mplus_DOCControl);
181 WriteDOC(~tmp, window, Mplus_CtrlConfirm); 181 WriteDOC(~tmp, window, Mplus_CtrlConfirm);
182 182
183 mdelay(1); 183 mdelay(1);
184 /* Enable the DiskOnChip ASIC */ 184 /* Enable the DiskOnChip ASIC */
185 tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | 185 tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
@@ -187,7 +187,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
187 WriteDOC(tmp, window, Mplus_DOCControl); 187 WriteDOC(tmp, window, Mplus_DOCControl);
188 WriteDOC(~tmp, window, Mplus_CtrlConfirm); 188 WriteDOC(~tmp, window, Mplus_CtrlConfirm);
189 mdelay(1); 189 mdelay(1);
190#endif /* !DOC_PASSIVE_PROBE */ 190#endif /* !DOC_PASSIVE_PROBE */
191 191
192 ChipID = ReadDOC(window, ChipID); 192 ChipID = ReadDOC(window, ChipID);
193 193
@@ -227,7 +227,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
227 WriteDOC(tmp2, window, DOCControl); 227 WriteDOC(tmp2, window, DOCControl);
228#endif 228#endif
229 return 0; 229 return 0;
230} 230}
231 231
232static int docfound; 232static int docfound;
233 233
@@ -244,10 +244,10 @@ static void __init DoC_Probe(unsigned long physadr)
244 void (*initroutine)(struct mtd_info *) = NULL; 244 void (*initroutine)(struct mtd_info *) = NULL;
245 245
246 docptr = ioremap(physadr, DOC_IOREMAP_LEN); 246 docptr = ioremap(physadr, DOC_IOREMAP_LEN);
247 247
248 if (!docptr) 248 if (!docptr)
249 return; 249 return;
250 250
251 if ((ChipID = doccheck(docptr, physadr))) { 251 if ((ChipID = doccheck(docptr, physadr))) {
252 if (ChipID == DOC_ChipID_Doc2kTSOP) { 252 if (ChipID == DOC_ChipID_Doc2kTSOP) {
253 /* Remove this at your own peril. The hardware driver works but nothing prevents you from erasing bad blocks */ 253 /* Remove this at your own peril. The hardware driver works but nothing prevents you from erasing bad blocks */
@@ -263,9 +263,9 @@ static void __init DoC_Probe(unsigned long physadr)
263 iounmap(docptr); 263 iounmap(docptr);
264 return; 264 return;
265 } 265 }
266 266
267 this = (struct DiskOnChip *)(&mtd[1]); 267 this = (struct DiskOnChip *)(&mtd[1]);
268 268
269 memset((char *)mtd,0, sizeof(struct mtd_info)); 269 memset((char *)mtd,0, sizeof(struct mtd_info));
270 memset((char *)this, 0, sizeof(struct DiskOnChip)); 270 memset((char *)this, 0, sizeof(struct DiskOnChip));
271 271
@@ -281,13 +281,13 @@ static void __init DoC_Probe(unsigned long physadr)
281 im_funcname = "DoC2k_init"; 281 im_funcname = "DoC2k_init";
282 im_modname = "doc2000"; 282 im_modname = "doc2000";
283 break; 283 break;
284 284
285 case DOC_ChipID_Doc2k: 285 case DOC_ChipID_Doc2k:
286 name="2000"; 286 name="2000";
287 im_funcname = "DoC2k_init"; 287 im_funcname = "DoC2k_init";
288 im_modname = "doc2000"; 288 im_modname = "doc2000";
289 break; 289 break;
290 290
291 case DOC_ChipID_DocMil: 291 case DOC_ChipID_DocMil:
292 name="Millennium"; 292 name="Millennium";
293#ifdef DOC_SINGLE_DRIVER 293#ifdef DOC_SINGLE_DRIVER
@@ -331,7 +331,7 @@ static void __init DoC_Probe(unsigned long physadr)
331static int __init init_doc(void) 331static int __init init_doc(void)
332{ 332{
333 int i; 333 int i;
334 334
335 if (doc_config_location) { 335 if (doc_config_location) {
336 printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location); 336 printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location);
337 DoC_Probe(doc_config_location); 337 DoC_Probe(doc_config_location);
diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c
index df987a53ed9c..1e876fcb0408 100644
--- a/drivers/mtd/devices/lart.c
+++ b/drivers/mtd/devices/lart.c
@@ -2,7 +2,7 @@
2/* 2/*
3 * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART. 3 * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART.
4 * 4 *
5 * $Id: lart.c,v 1.7 2004/08/09 13:19:44 dwmw2 Exp $ 5 * $Id: lart.c,v 1.9 2005/11/07 11:14:25 gleixner Exp $
6 * 6 *
7 * Author: Abraham vd Merwe <abraham@2d3d.co.za> 7 * Author: Abraham vd Merwe <abraham@2d3d.co.za>
8 * 8 *
@@ -122,7 +122,7 @@ static char module_name[] = "lart";
122 122
123/* 123/*
124 * The data line mapping on LART is as follows: 124 * The data line mapping on LART is as follows:
125 * 125 *
126 * U2 CPU | U3 CPU 126 * U2 CPU | U3 CPU
127 * ------------------- 127 * -------------------
128 * 0 20 | 0 12 128 * 0 20 | 0 12
@@ -181,7 +181,7 @@ static char module_name[] = "lart";
181 (((x) & 0x00004000) >> 13) \ 181 (((x) & 0x00004000) >> 13) \
182 ) 182 )
183 183
184/* 184/*
185 * The address line mapping on LART is as follows: 185 * The address line mapping on LART is as follows:
186 * 186 *
187 * U3 CPU | U2 CPU 187 * U3 CPU | U2 CPU
@@ -204,7 +204,7 @@ static char module_name[] = "lart";
204 * 12 15 | 12 15 204 * 12 15 | 12 15
205 * 13 14 | 13 14 205 * 13 14 | 13 14
206 * 14 16 | 14 16 206 * 14 16 | 14 16
207 * 207 *
208 * MAIN BLOCK BOUNDARY 208 * MAIN BLOCK BOUNDARY
209 * 209 *
210 * 15 17 | 15 18 210 * 15 17 | 15 18
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index 765c0179c8df..e8685ee6c1e4 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -1,5 +1,5 @@
1/** 1/**
2 * $Id: phram.c,v 1.14 2005/03/07 21:43:38 joern Exp $ 2 * $Id: phram.c,v 1.16 2005/11/07 11:14:25 gleixner Exp $
3 * 3 *
4 * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de> 4 * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de>
5 * Copyright (c) 2003-2004 Jörn Engel <joern@wh.fh-wedel.de> 5 * Copyright (c) 2003-2004 Jörn Engel <joern@wh.fh-wedel.de>
@@ -41,10 +41,10 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
41 41
42 if (instr->addr + instr->len > mtd->size) 42 if (instr->addr + instr->len > mtd->size)
43 return -EINVAL; 43 return -EINVAL;
44 44
45 memset(start + instr->addr, 0xff, instr->len); 45 memset(start + instr->addr, 0xff, instr->len);
46 46
47 /* This'll catch a few races. Free the thing before returning :) 47 /* This'll catch a few races. Free the thing before returning :)
48 * I don't feel at all ashamed. This kind of thing is possible anyway 48 * I don't feel at all ashamed. This kind of thing is possible anyway
49 * with flash, but unlikely. 49 * with flash, but unlikely.
50 */ 50 */
@@ -63,7 +63,7 @@ static int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
63 63
64 if (from + len > mtd->size) 64 if (from + len > mtd->size)
65 return -EINVAL; 65 return -EINVAL;
66 66
67 *mtdbuf = start + from; 67 *mtdbuf = start + from;
68 *retlen = len; 68 *retlen = len;
69 return 0; 69 return 0;
@@ -84,7 +84,7 @@ static int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
84 84
85 if (len > mtd->size - from) 85 if (len > mtd->size - from)
86 len = mtd->size - from; 86 len = mtd->size - from;
87 87
88 memcpy(buf, start + from, len); 88 memcpy(buf, start + from, len);
89 89
90 *retlen = len; 90 *retlen = len;
@@ -101,7 +101,7 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len,
101 101
102 if (len > mtd->size - to) 102 if (len > mtd->size - to)
103 len = mtd->size - to; 103 len = mtd->size - to;
104 104
105 memcpy(start + to, buf, len); 105 memcpy(start + to, buf, len);
106 106
107 *retlen = len; 107 *retlen = len;
@@ -159,7 +159,7 @@ static int register_device(char *name, unsigned long start, unsigned long len)
159 } 159 }
160 160
161 list_add_tail(&new->list, &phram_list); 161 list_add_tail(&new->list, &phram_list);
162 return 0; 162 return 0;
163 163
164out2: 164out2:
165 iounmap(new->mtd.priv); 165 iounmap(new->mtd.priv);
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index 5b3defadf884..de48b35f5609 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: pmc551.c,v 1.30 2005/01/05 18:05:13 dwmw2 Exp $ 2 * $Id: pmc551.c,v 1.32 2005/11/07 11:14:25 gleixner Exp $
3 * 3 *
4 * PMC551 PCI Mezzanine Ram Device 4 * PMC551 PCI Mezzanine Ram Device
5 * 5 *
@@ -27,7 +27,7 @@
27 * it as high speed swap or for a high speed disk device of some 27 * it as high speed swap or for a high speed disk device of some
28 * sort. Which becomes very useful on diskless systems in the 28 * sort. Which becomes very useful on diskless systems in the
29 * embedded market I might add. 29 * embedded market I might add.
30 * 30 *
31 * Notes: 31 * Notes:
32 * Due to what I assume is more buggy SROM, the 64M PMC551 I 32 * Due to what I assume is more buggy SROM, the 64M PMC551 I
33 * have available claims that all 4 of it's DRAM banks have 64M 33 * have available claims that all 4 of it's DRAM banks have 64M
@@ -63,10 +63,10 @@
63 * Minyard set up the card to utilize a 1M sliding apature. 63 * Minyard set up the card to utilize a 1M sliding apature.
64 * 64 *
65 * Corey Minyard <minyard@nortelnetworks.com> 65 * Corey Minyard <minyard@nortelnetworks.com>
66 * * Modified driver to utilize a sliding aperture instead of 66 * * Modified driver to utilize a sliding aperture instead of
67 * mapping all memory into kernel space which turned out to 67 * mapping all memory into kernel space which turned out to
68 * be very wasteful. 68 * be very wasteful.
69 * * Located a bug in the SROM's initialization sequence that 69 * * Located a bug in the SROM's initialization sequence that
70 * made the memory unusable, added a fix to code to touch up 70 * made the memory unusable, added a fix to code to touch up
71 * the DRAM some. 71 * the DRAM some.
72 * 72 *
@@ -390,7 +390,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
390 bcmd |= (0x40|0x20); 390 bcmd |= (0x40|0x20);
391 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd); 391 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
392 392
393 /* 393 /*
394 * Take care and turn off the memory on the device while we 394 * Take care and turn off the memory on the device while we
395 * tweak the configurations 395 * tweak the configurations
396 */ 396 */
@@ -408,7 +408,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
408 * Grab old BAR0 config so that we can figure out memory size 408 * Grab old BAR0 config so that we can figure out memory size
409 * This is another bit of kludge going on. The reason for the 409 * This is another bit of kludge going on. The reason for the
410 * redundancy is I am hoping to retain the original configuration 410 * redundancy is I am hoping to retain the original configuration
411 * previously assigned to the card by the BIOS or some previous 411 * previously assigned to the card by the BIOS or some previous
412 * fixup routine in the kernel. So we read the old config into cfg, 412 * fixup routine in the kernel. So we read the old config into cfg,
413 * then write all 1's to the memory space, read back the result into 413 * then write all 1's to the memory space, read back the result into
414 * "size", and then write back all the old config. 414 * "size", and then write back all the old config.
@@ -480,7 +480,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
480 } while ( (PCI_COMMAND_IO) & cmd ); 480 } while ( (PCI_COMMAND_IO) & cmd );
481 481
482 /* 482 /*
483 * Turn on auto refresh 483 * Turn on auto refresh
484 * The loop is taken directly from Ramix's example code. I assume that 484 * The loop is taken directly from Ramix's example code. I assume that
485 * this must be held high for some duration of time, but I can find no 485 * this must be held high for some duration of time, but I can find no
486 * documentation refrencing the reasons why. 486 * documentation refrencing the reasons why.
@@ -615,7 +615,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
615 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd ); 615 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd );
616 printk( KERN_DEBUG "pmc551: EEPROM is under %s control\n" 616 printk( KERN_DEBUG "pmc551: EEPROM is under %s control\n"
617 "pmc551: System Control Register is %slocked to PCI access\n" 617 "pmc551: System Control Register is %slocked to PCI access\n"
618 "pmc551: System Control Register is %slocked to EEPROM access\n", 618 "pmc551: System Control Register is %slocked to EEPROM access\n",
619 (bcmd&0x1)?"software":"hardware", 619 (bcmd&0x1)?"software":"hardware",
620 (bcmd&0x20)?"":"un", (bcmd&0x40)?"":"un"); 620 (bcmd&0x20)?"":"un", (bcmd&0x40)?"":"un");
621#endif 621#endif
@@ -744,7 +744,7 @@ static int __init init_pmc551(void)
744 priv->start = ioremap(((PCI_Device->resource[0].start) 744 priv->start = ioremap(((PCI_Device->resource[0].start)
745 & PCI_BASE_ADDRESS_MEM_MASK), 745 & PCI_BASE_ADDRESS_MEM_MASK),
746 priv->asize); 746 priv->asize);
747 747
748 if (!priv->start) { 748 if (!priv->start) {
749 printk(KERN_NOTICE "pmc551: Unable to map IO space\n"); 749 printk(KERN_NOTICE "pmc551: Unable to map IO space\n");
750 kfree(mtd->priv); 750 kfree(mtd->priv);
@@ -765,7 +765,7 @@ static int __init init_pmc551(void)
765 priv->curr_map0 ); 765 priv->curr_map0 );
766 766
767#ifdef CONFIG_MTD_PMC551_DEBUG 767#ifdef CONFIG_MTD_PMC551_DEBUG
768 printk( KERN_DEBUG "pmc551: aperture set to %d\n", 768 printk( KERN_DEBUG "pmc551: aperture set to %d\n",
769 (priv->base_map0 & 0xF0)>>4 ); 769 (priv->base_map0 & 0xF0)>>4 );
770#endif 770#endif
771 771
@@ -823,13 +823,13 @@ static void __exit cleanup_pmc551(void)
823 while((mtd=pmc551list)) { 823 while((mtd=pmc551list)) {
824 priv = mtd->priv; 824 priv = mtd->priv;
825 pmc551list = priv->nextpmc551; 825 pmc551list = priv->nextpmc551;
826 826
827 if(priv->start) { 827 if(priv->start) {
828 printk (KERN_DEBUG "pmc551: unmapping %dM starting at 0x%p\n", 828 printk (KERN_DEBUG "pmc551: unmapping %dM starting at 0x%p\n",
829 priv->asize>>20, priv->start); 829 priv->asize>>20, priv->start);
830 iounmap (priv->start); 830 iounmap (priv->start);
831 } 831 }
832 832
833 kfree (mtd->priv); 833 kfree (mtd->priv);
834 del_mtd_device (mtd); 834 del_mtd_device (mtd);
835 kfree (mtd); 835 kfree (mtd);
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 84fa91392a8c..6faee6c6958c 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -1,6 +1,6 @@
1/*====================================================================== 1/*======================================================================
2 2
3 $Id: slram.c,v 1.34 2005/01/06 21:16:42 jwboyer Exp $ 3 $Id: slram.c,v 1.36 2005/11/07 11:14:25 gleixner Exp $
4 4
5 This driver provides a method to access memory not used by the kernel 5 This driver provides a method to access memory not used by the kernel
6 itself (i.e. if the kernel commandline mem=xxx is used). To actually 6 itself (i.e. if the kernel commandline mem=xxx is used). To actually
@@ -18,14 +18,14 @@
18 <start>: start of the memory region, decimal or hex (0xabcdef) 18 <start>: start of the memory region, decimal or hex (0xabcdef)
19 <end/offset>: end of the memory region. It's possible to use +0x1234 19 <end/offset>: end of the memory region. It's possible to use +0x1234
20 to specify the offset instead of the absolute address 20 to specify the offset instead of the absolute address
21 21
22 NOTE: 22 NOTE:
23 With slram it's only possible to map a contigous memory region. Therfore 23 With slram it's only possible to map a contigous memory region. Therfore
24 if there's a device mapped somewhere in the region specified slram will 24 if there's a device mapped somewhere in the region specified slram will
25 fail to load (see kernel log if modprobe fails). 25 fail to load (see kernel log if modprobe fails).
26 26
27 - 27 -
28 28
29 Jochen Schaeuble <psionic@psionic.de> 29 Jochen Schaeuble <psionic@psionic.de>
30 30
31======================================================================*/ 31======================================================================*/
@@ -89,10 +89,10 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr)
89 if (instr->addr + instr->len > mtd->size) { 89 if (instr->addr + instr->len > mtd->size) {
90 return(-EINVAL); 90 return(-EINVAL);
91 } 91 }
92 92
93 memset(priv->start + instr->addr, 0xff, instr->len); 93 memset(priv->start + instr->addr, 0xff, instr->len);
94 94
95 /* This'll catch a few races. Free the thing before returning :) 95 /* This'll catch a few races. Free the thing before returning :)
96 * I don't feel at all ashamed. This kind of thing is possible anyway 96 * I don't feel at all ashamed. This kind of thing is possible anyway
97 * with flash, but unlikely. 97 * with flash, but unlikely.
98 */ 98 */
@@ -170,12 +170,12 @@ static int register_device(char *name, unsigned long start, unsigned long length
170 } 170 }
171 (*curmtd)->mtdinfo = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); 171 (*curmtd)->mtdinfo = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
172 (*curmtd)->next = NULL; 172 (*curmtd)->next = NULL;
173 173
174 if ((*curmtd)->mtdinfo) { 174 if ((*curmtd)->mtdinfo) {
175 memset((char *)(*curmtd)->mtdinfo, 0, sizeof(struct mtd_info)); 175 memset((char *)(*curmtd)->mtdinfo, 0, sizeof(struct mtd_info));
176 (*curmtd)->mtdinfo->priv = 176 (*curmtd)->mtdinfo->priv =
177 kmalloc(sizeof(slram_priv_t), GFP_KERNEL); 177 kmalloc(sizeof(slram_priv_t), GFP_KERNEL);
178 178
179 if (!(*curmtd)->mtdinfo->priv) { 179 if (!(*curmtd)->mtdinfo->priv) {
180 kfree((*curmtd)->mtdinfo); 180 kfree((*curmtd)->mtdinfo);
181 (*curmtd)->mtdinfo = NULL; 181 (*curmtd)->mtdinfo = NULL;
@@ -188,7 +188,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
188 E("slram: Cannot allocate new MTD device.\n"); 188 E("slram: Cannot allocate new MTD device.\n");
189 return(-ENOMEM); 189 return(-ENOMEM);
190 } 190 }
191 191
192 if (!(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start = 192 if (!(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start =
193 ioremap(start, length))) { 193 ioremap(start, length))) {
194 E("slram: ioremap failed\n"); 194 E("slram: ioremap failed\n");
@@ -223,7 +223,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
223 T("slram: Mapped from 0x%p to 0x%p\n", 223 T("slram: Mapped from 0x%p to 0x%p\n",
224 ((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start, 224 ((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start,
225 ((slram_priv_t *)(*curmtd)->mtdinfo->priv)->end); 225 ((slram_priv_t *)(*curmtd)->mtdinfo->priv)->end);
226 return(0); 226 return(0);
227} 227}
228 228
229static void unregister_devices(void) 229static void unregister_devices(void)
@@ -256,7 +256,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
256 char *buffer; 256 char *buffer;
257 unsigned long devstart; 257 unsigned long devstart;
258 unsigned long devlength; 258 unsigned long devlength;
259 259
260 if ((!devname) || (!szstart) || (!szlength)) { 260 if ((!devname) || (!szstart) || (!szlength)) {
261 unregister_devices(); 261 unregister_devices();
262 return(-EINVAL); 262 return(-EINVAL);
@@ -264,7 +264,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
264 264
265 devstart = simple_strtoul(szstart, &buffer, 0); 265 devstart = simple_strtoul(szstart, &buffer, 0);
266 devstart = handle_unit(devstart, buffer); 266 devstart = handle_unit(devstart, buffer);
267 267
268 if (*(szlength) != '+') { 268 if (*(szlength) != '+') {
269 devlength = simple_strtoul(szlength, &buffer, 0); 269 devlength = simple_strtoul(szlength, &buffer, 0);
270 devlength = handle_unit(devlength, buffer) - devstart; 270 devlength = handle_unit(devlength, buffer) - devstart;
@@ -278,7 +278,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
278 E("slram: Illegal start / length parameter.\n"); 278 E("slram: Illegal start / length parameter.\n");
279 return(-EINVAL); 279 return(-EINVAL);
280 } 280 }
281 281
282 if ((devstart = register_device(devname, devstart, devlength))){ 282 if ((devstart = register_device(devname, devstart, devlength))){
283 unregister_devices(); 283 unregister_devices();
284 return((int)devstart); 284 return((int)devstart);
@@ -335,7 +335,7 @@ static int init_slram(void)
335 } 335 }
336#else 336#else
337 int count; 337 int count;
338 338
339 for (count = 0; (map[count]) && (count < SLRAM_MAX_DEVICES_PARAMS); 339 for (count = 0; (map[count]) && (count < SLRAM_MAX_DEVICES_PARAMS);
340 count++) { 340 count++) {
341 } 341 }
@@ -350,10 +350,10 @@ static int init_slram(void)
350 if (parse_cmdline(devname, map[i * 3 + 1], map[i * 3 + 2])!=0) { 350 if (parse_cmdline(devname, map[i * 3 + 1], map[i * 3 + 2])!=0) {
351 return(-EINVAL); 351 return(-EINVAL);
352 } 352 }
353 353
354 } 354 }
355#endif /* !MODULE */ 355#endif /* !MODULE */
356 356
357 return(0); 357 return(0);
358} 358}
359 359
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
index d32c1b3a8ce3..de7e231d6d18 100644
--- a/drivers/mtd/ftl.c
+++ b/drivers/mtd/ftl.c
@@ -1,5 +1,5 @@
1/* This version ported to the Linux-MTD system by dwmw2@infradead.org 1/* This version ported to the Linux-MTD system by dwmw2@infradead.org
2 * $Id: ftl.c,v 1.55 2005/01/17 13:47:21 hvr Exp $ 2 * $Id: ftl.c,v 1.58 2005/11/07 11:14:19 gleixner Exp $
3 * 3 *
4 * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br> 4 * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
5 * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups 5 * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
@@ -53,7 +53,7 @@
53 Use of the FTL format for non-PCMCIA applications may be an 53 Use of the FTL format for non-PCMCIA applications may be an
54 infringement of these patents. For additional information, 54 infringement of these patents. For additional information,
55 contact M-Systems (http://www.m-sys.com) directly. 55 contact M-Systems (http://www.m-sys.com) directly.
56 56
57======================================================================*/ 57======================================================================*/
58#include <linux/mtd/blktrans.h> 58#include <linux/mtd/blktrans.h>
59#include <linux/module.h> 59#include <linux/module.h>
@@ -160,7 +160,7 @@ static void ftl_erase_callback(struct erase_info *done);
160 Scan_header() checks to see if a memory region contains an FTL 160 Scan_header() checks to see if a memory region contains an FTL
161 partition. build_maps() reads all the erase unit headers, builds 161 partition. build_maps() reads all the erase unit headers, builds
162 the erase unit map, and then builds the virtual page map. 162 the erase unit map, and then builds the virtual page map.
163 163
164======================================================================*/ 164======================================================================*/
165 165
166static int scan_header(partition_t *part) 166static int scan_header(partition_t *part)
@@ -176,10 +176,10 @@ static int scan_header(partition_t *part)
176 (offset + sizeof(header)) < max_offset; 176 (offset + sizeof(header)) < max_offset;
177 offset += part->mbd.mtd->erasesize ? : 0x2000) { 177 offset += part->mbd.mtd->erasesize ? : 0x2000) {
178 178
179 err = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &ret, 179 err = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &ret,
180 (unsigned char *)&header); 180 (unsigned char *)&header);
181 181
182 if (err) 182 if (err)
183 return err; 183 return err;
184 184
185 if (strcmp(header.DataOrgTuple+3, "FTL100") == 0) break; 185 if (strcmp(header.DataOrgTuple+3, "FTL100") == 0) break;
@@ -232,10 +232,10 @@ static int build_maps(partition_t *part)
232 for (i = 0; i < le16_to_cpu(part->header.NumEraseUnits); i++) { 232 for (i = 0; i < le16_to_cpu(part->header.NumEraseUnits); i++) {
233 offset = ((i + le16_to_cpu(part->header.FirstPhysicalEUN)) 233 offset = ((i + le16_to_cpu(part->header.FirstPhysicalEUN))
234 << part->header.EraseUnitSize); 234 << part->header.EraseUnitSize);
235 ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &retval, 235 ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &retval,
236 (unsigned char *)&header); 236 (unsigned char *)&header);
237 237
238 if (ret) 238 if (ret)
239 goto out_XferInfo; 239 goto out_XferInfo;
240 240
241 ret = -1; 241 ret = -1;
@@ -274,7 +274,7 @@ static int build_maps(partition_t *part)
274 "don't add up!\n"); 274 "don't add up!\n");
275 goto out_XferInfo; 275 goto out_XferInfo;
276 } 276 }
277 277
278 /* Set up virtual page map */ 278 /* Set up virtual page map */
279 blocks = le32_to_cpu(header.FormattedSize) >> header.BlockSize; 279 blocks = le32_to_cpu(header.FormattedSize) >> header.BlockSize;
280 part->VirtualBlockMap = vmalloc(blocks * sizeof(u_int32_t)); 280 part->VirtualBlockMap = vmalloc(blocks * sizeof(u_int32_t));
@@ -296,12 +296,12 @@ static int build_maps(partition_t *part)
296 part->EUNInfo[i].Free = 0; 296 part->EUNInfo[i].Free = 0;
297 part->EUNInfo[i].Deleted = 0; 297 part->EUNInfo[i].Deleted = 0;
298 offset = part->EUNInfo[i].Offset + le32_to_cpu(header.BAMOffset); 298 offset = part->EUNInfo[i].Offset + le32_to_cpu(header.BAMOffset);
299 299
300 ret = part->mbd.mtd->read(part->mbd.mtd, offset, 300 ret = part->mbd.mtd->read(part->mbd.mtd, offset,
301 part->BlocksPerUnit * sizeof(u_int32_t), &retval, 301 part->BlocksPerUnit * sizeof(u_int32_t), &retval,
302 (unsigned char *)part->bam_cache); 302 (unsigned char *)part->bam_cache);
303 303
304 if (ret) 304 if (ret)
305 goto out_bam_cache; 305 goto out_bam_cache;
306 306
307 for (j = 0; j < part->BlocksPerUnit; j++) { 307 for (j = 0; j < part->BlocksPerUnit; j++) {
@@ -316,7 +316,7 @@ static int build_maps(partition_t *part)
316 part->EUNInfo[i].Deleted++; 316 part->EUNInfo[i].Deleted++;
317 } 317 }
318 } 318 }
319 319
320 ret = 0; 320 ret = 0;
321 goto out; 321 goto out;
322 322
@@ -336,7 +336,7 @@ out:
336 336
337 Erase_xfer() schedules an asynchronous erase operation for a 337 Erase_xfer() schedules an asynchronous erase operation for a
338 transfer unit. 338 transfer unit.
339 339
340======================================================================*/ 340======================================================================*/
341 341
342static int erase_xfer(partition_t *part, 342static int erase_xfer(partition_t *part,
@@ -351,10 +351,10 @@ static int erase_xfer(partition_t *part,
351 xfer->state = XFER_ERASING; 351 xfer->state = XFER_ERASING;
352 352
353 /* Is there a free erase slot? Always in MTD. */ 353 /* Is there a free erase slot? Always in MTD. */
354 354
355 355
356 erase=kmalloc(sizeof(struct erase_info), GFP_KERNEL); 356 erase=kmalloc(sizeof(struct erase_info), GFP_KERNEL);
357 if (!erase) 357 if (!erase)
358 return -ENOMEM; 358 return -ENOMEM;
359 359
360 erase->mtd = part->mbd.mtd; 360 erase->mtd = part->mbd.mtd;
@@ -362,7 +362,7 @@ static int erase_xfer(partition_t *part,
362 erase->addr = xfer->Offset; 362 erase->addr = xfer->Offset;
363 erase->len = 1 << part->header.EraseUnitSize; 363 erase->len = 1 << part->header.EraseUnitSize;
364 erase->priv = (u_long)part; 364 erase->priv = (u_long)part;
365 365
366 ret = part->mbd.mtd->erase(part->mbd.mtd, erase); 366 ret = part->mbd.mtd->erase(part->mbd.mtd, erase);
367 367
368 if (!ret) 368 if (!ret)
@@ -377,7 +377,7 @@ static int erase_xfer(partition_t *part,
377 377
378 Prepare_xfer() takes a freshly erased transfer unit and gives 378 Prepare_xfer() takes a freshly erased transfer unit and gives
379 it an appropriate header. 379 it an appropriate header.
380 380
381======================================================================*/ 381======================================================================*/
382 382
383static void ftl_erase_callback(struct erase_info *erase) 383static void ftl_erase_callback(struct erase_info *erase)
@@ -385,7 +385,7 @@ static void ftl_erase_callback(struct erase_info *erase)
385 partition_t *part; 385 partition_t *part;
386 struct xfer_info_t *xfer; 386 struct xfer_info_t *xfer;
387 int i; 387 int i;
388 388
389 /* Look up the transfer unit */ 389 /* Look up the transfer unit */
390 part = (partition_t *)(erase->priv); 390 part = (partition_t *)(erase->priv);
391 391
@@ -422,7 +422,7 @@ static int prepare_xfer(partition_t *part, int i)
422 422
423 xfer = &part->XferInfo[i]; 423 xfer = &part->XferInfo[i];
424 xfer->state = XFER_FAILED; 424 xfer->state = XFER_FAILED;
425 425
426 DEBUG(1, "ftl_cs: preparing xfer unit at 0x%x\n", xfer->Offset); 426 DEBUG(1, "ftl_cs: preparing xfer unit at 0x%x\n", xfer->Offset);
427 427
428 /* Write the transfer unit header */ 428 /* Write the transfer unit header */
@@ -446,7 +446,7 @@ static int prepare_xfer(partition_t *part, int i)
446 446
447 for (i = 0; i < nbam; i++, offset += sizeof(u_int32_t)) { 447 for (i = 0; i < nbam; i++, offset += sizeof(u_int32_t)) {
448 448
449 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t), 449 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t),
450 &retlen, (u_char *)&ctl); 450 &retlen, (u_char *)&ctl);
451 451
452 if (ret) 452 if (ret)
@@ -454,7 +454,7 @@ static int prepare_xfer(partition_t *part, int i)
454 } 454 }
455 xfer->state = XFER_PREPARED; 455 xfer->state = XFER_PREPARED;
456 return 0; 456 return 0;
457 457
458} /* prepare_xfer */ 458} /* prepare_xfer */
459 459
460/*====================================================================== 460/*======================================================================
@@ -466,7 +466,7 @@ static int prepare_xfer(partition_t *part, int i)
466 All data blocks are copied to the corresponding blocks in the 466 All data blocks are copied to the corresponding blocks in the
467 target unit, so the virtual block map does not need to be 467 target unit, so the virtual block map does not need to be
468 updated. 468 updated.
469 469
470======================================================================*/ 470======================================================================*/
471 471
472static int copy_erase_unit(partition_t *part, u_int16_t srcunit, 472static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
@@ -486,14 +486,14 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
486 xfer = &part->XferInfo[xferunit]; 486 xfer = &part->XferInfo[xferunit];
487 DEBUG(2, "ftl_cs: copying block 0x%x to 0x%x\n", 487 DEBUG(2, "ftl_cs: copying block 0x%x to 0x%x\n",
488 eun->Offset, xfer->Offset); 488 eun->Offset, xfer->Offset);
489 489
490 490
491 /* Read current BAM */ 491 /* Read current BAM */
492 if (part->bam_index != srcunit) { 492 if (part->bam_index != srcunit) {
493 493
494 offset = eun->Offset + le32_to_cpu(part->header.BAMOffset); 494 offset = eun->Offset + le32_to_cpu(part->header.BAMOffset);
495 495
496 ret = part->mbd.mtd->read(part->mbd.mtd, offset, 496 ret = part->mbd.mtd->read(part->mbd.mtd, offset,
497 part->BlocksPerUnit * sizeof(u_int32_t), 497 part->BlocksPerUnit * sizeof(u_int32_t),
498 &retlen, (u_char *) (part->bam_cache)); 498 &retlen, (u_char *) (part->bam_cache));
499 499
@@ -501,11 +501,11 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
501 part->bam_index = 0xffff; 501 part->bam_index = 0xffff;
502 502
503 if (ret) { 503 if (ret) {
504 printk( KERN_WARNING "ftl: Failed to read BAM cache in copy_erase_unit()!\n"); 504 printk( KERN_WARNING "ftl: Failed to read BAM cache in copy_erase_unit()!\n");
505 return ret; 505 return ret;
506 } 506 }
507 } 507 }
508 508
509 /* Write the LogicalEUN for the transfer unit */ 509 /* Write the LogicalEUN for the transfer unit */
510 xfer->state = XFER_UNKNOWN; 510 xfer->state = XFER_UNKNOWN;
511 offset = xfer->Offset + 20; /* Bad! */ 511 offset = xfer->Offset + 20; /* Bad! */
@@ -513,12 +513,12 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
513 513
514 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int16_t), 514 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int16_t),
515 &retlen, (u_char *) &unit); 515 &retlen, (u_char *) &unit);
516 516
517 if (ret) { 517 if (ret) {
518 printk( KERN_WARNING "ftl: Failed to write back to BAM cache in copy_erase_unit()!\n"); 518 printk( KERN_WARNING "ftl: Failed to write back to BAM cache in copy_erase_unit()!\n");
519 return ret; 519 return ret;
520 } 520 }
521 521
522 /* Copy all data blocks from source unit to transfer unit */ 522 /* Copy all data blocks from source unit to transfer unit */
523 src = eun->Offset; dest = xfer->Offset; 523 src = eun->Offset; dest = xfer->Offset;
524 524
@@ -558,15 +558,15 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
558 } 558 }
559 559
560 /* Write the BAM to the transfer unit */ 560 /* Write the BAM to the transfer unit */
561 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset), 561 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset),
562 part->BlocksPerUnit * sizeof(int32_t), &retlen, 562 part->BlocksPerUnit * sizeof(int32_t), &retlen,
563 (u_char *)part->bam_cache); 563 (u_char *)part->bam_cache);
564 if (ret) { 564 if (ret) {
565 printk( KERN_WARNING "ftl: Error writing BAM in copy_erase_unit\n"); 565 printk( KERN_WARNING "ftl: Error writing BAM in copy_erase_unit\n");
566 return ret; 566 return ret;
567 } 567 }
568 568
569 569
570 /* All clear? Then update the LogicalEUN again */ 570 /* All clear? Then update the LogicalEUN again */
571 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(u_int16_t), 571 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(u_int16_t),
572 &retlen, (u_char *)&srcunitswap); 572 &retlen, (u_char *)&srcunitswap);
@@ -574,9 +574,9 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
574 if (ret) { 574 if (ret) {
575 printk(KERN_WARNING "ftl: Error writing new LogicalEUN in copy_erase_unit\n"); 575 printk(KERN_WARNING "ftl: Error writing new LogicalEUN in copy_erase_unit\n");
576 return ret; 576 return ret;
577 } 577 }
578 578
579 579
580 /* Update the maps and usage stats*/ 580 /* Update the maps and usage stats*/
581 i = xfer->EraseCount; 581 i = xfer->EraseCount;
582 xfer->EraseCount = eun->EraseCount; 582 xfer->EraseCount = eun->EraseCount;
@@ -588,10 +588,10 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
588 part->FreeTotal += free; 588 part->FreeTotal += free;
589 eun->Free = free; 589 eun->Free = free;
590 eun->Deleted = 0; 590 eun->Deleted = 0;
591 591
592 /* Now, the cache should be valid for the new block */ 592 /* Now, the cache should be valid for the new block */
593 part->bam_index = srcunit; 593 part->bam_index = srcunit;
594 594
595 return 0; 595 return 0;
596} /* copy_erase_unit */ 596} /* copy_erase_unit */
597 597
@@ -608,7 +608,7 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
608 oldest data unit instead. This means that we generally postpone 608 oldest data unit instead. This means that we generally postpone
609 the next reclaimation as long as possible, but shuffle static 609 the next reclaimation as long as possible, but shuffle static
610 stuff around a bit for wear leveling. 610 stuff around a bit for wear leveling.
611 611
612======================================================================*/ 612======================================================================*/
613 613
614static int reclaim_block(partition_t *part) 614static int reclaim_block(partition_t *part)
@@ -666,7 +666,7 @@ static int reclaim_block(partition_t *part)
666 else 666 else
667 DEBUG(1, "ftl_cs: reclaim failed: no " 667 DEBUG(1, "ftl_cs: reclaim failed: no "
668 "suitable transfer units!\n"); 668 "suitable transfer units!\n");
669 669
670 return -EIO; 670 return -EIO;
671 } 671 }
672 } 672 }
@@ -715,7 +715,7 @@ static int reclaim_block(partition_t *part)
715 returns the block index -- the erase unit is just the currently 715 returns the block index -- the erase unit is just the currently
716 cached unit. If there are no free blocks, it returns 0 -- this 716 cached unit. If there are no free blocks, it returns 0 -- this
717 is never a valid data block because it contains the header. 717 is never a valid data block because it contains the header.
718 718
719======================================================================*/ 719======================================================================*/
720 720
721#ifdef PSYCHO_DEBUG 721#ifdef PSYCHO_DEBUG
@@ -737,7 +737,7 @@ static u_int32_t find_free(partition_t *part)
737 u_int32_t blk; 737 u_int32_t blk;
738 size_t retlen; 738 size_t retlen;
739 int ret; 739 int ret;
740 740
741 /* Find an erase unit with some free space */ 741 /* Find an erase unit with some free space */
742 stop = (part->bam_index == 0xffff) ? 0 : part->bam_index; 742 stop = (part->bam_index == 0xffff) ? 0 : part->bam_index;
743 eun = stop; 743 eun = stop;
@@ -749,17 +749,17 @@ static u_int32_t find_free(partition_t *part)
749 749
750 if (part->EUNInfo[eun].Free == 0) 750 if (part->EUNInfo[eun].Free == 0)
751 return 0; 751 return 0;
752 752
753 /* Is this unit's BAM cached? */ 753 /* Is this unit's BAM cached? */
754 if (eun != part->bam_index) { 754 if (eun != part->bam_index) {
755 /* Invalidate cache */ 755 /* Invalidate cache */
756 part->bam_index = 0xffff; 756 part->bam_index = 0xffff;
757 757
758 ret = part->mbd.mtd->read(part->mbd.mtd, 758 ret = part->mbd.mtd->read(part->mbd.mtd,
759 part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset), 759 part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset),
760 part->BlocksPerUnit * sizeof(u_int32_t), 760 part->BlocksPerUnit * sizeof(u_int32_t),
761 &retlen, (u_char *) (part->bam_cache)); 761 &retlen, (u_char *) (part->bam_cache));
762 762
763 if (ret) { 763 if (ret) {
764 printk(KERN_WARNING"ftl: Error reading BAM in find_free\n"); 764 printk(KERN_WARNING"ftl: Error reading BAM in find_free\n");
765 return 0; 765 return 0;
@@ -781,14 +781,14 @@ static u_int32_t find_free(partition_t *part)
781 } 781 }
782 DEBUG(2, "ftl_cs: found free block at %d in %d\n", blk, eun); 782 DEBUG(2, "ftl_cs: found free block at %d in %d\n", blk, eun);
783 return blk; 783 return blk;
784 784
785} /* find_free */ 785} /* find_free */
786 786
787 787
788/*====================================================================== 788/*======================================================================
789 789
790 Read a series of sectors from an FTL partition. 790 Read a series of sectors from an FTL partition.
791 791
792======================================================================*/ 792======================================================================*/
793 793
794static int ftl_read(partition_t *part, caddr_t buffer, 794static int ftl_read(partition_t *part, caddr_t buffer,
@@ -798,7 +798,7 @@ static int ftl_read(partition_t *part, caddr_t buffer,
798 u_long i; 798 u_long i;
799 int ret; 799 int ret;
800 size_t offset, retlen; 800 size_t offset, retlen;
801 801
802 DEBUG(2, "ftl_cs: ftl_read(0x%p, 0x%lx, %ld)\n", 802 DEBUG(2, "ftl_cs: ftl_read(0x%p, 0x%lx, %ld)\n",
803 part, sector, nblocks); 803 part, sector, nblocks);
804 if (!(part->state & FTL_FORMATTED)) { 804 if (!(part->state & FTL_FORMATTED)) {
@@ -834,7 +834,7 @@ static int ftl_read(partition_t *part, caddr_t buffer,
834/*====================================================================== 834/*======================================================================
835 835
836 Write a series of sectors to an FTL partition 836 Write a series of sectors to an FTL partition
837 837
838======================================================================*/ 838======================================================================*/
839 839
840static int set_bam_entry(partition_t *part, u_int32_t log_addr, 840static int set_bam_entry(partition_t *part, u_int32_t log_addr,
@@ -855,7 +855,7 @@ static int set_bam_entry(partition_t *part, u_int32_t log_addr,
855 blk = (log_addr % bsize) / SECTOR_SIZE; 855 blk = (log_addr % bsize) / SECTOR_SIZE;
856 offset = (part->EUNInfo[eun].Offset + blk * sizeof(u_int32_t) + 856 offset = (part->EUNInfo[eun].Offset + blk * sizeof(u_int32_t) +
857 le32_to_cpu(part->header.BAMOffset)); 857 le32_to_cpu(part->header.BAMOffset));
858 858
859#ifdef PSYCHO_DEBUG 859#ifdef PSYCHO_DEBUG
860 ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(u_int32_t), 860 ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(u_int32_t),
861 &retlen, (u_char *)&old_addr); 861 &retlen, (u_char *)&old_addr);
@@ -925,7 +925,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
925 if (ret) 925 if (ret)
926 return ret; 926 return ret;
927 } 927 }
928 928
929 bsize = 1 << part->header.EraseUnitSize; 929 bsize = 1 << part->header.EraseUnitSize;
930 930
931 virt_addr = sector * SECTOR_SIZE | BLOCK_DATA; 931 virt_addr = sector * SECTOR_SIZE | BLOCK_DATA;
@@ -949,12 +949,12 @@ static int ftl_write(partition_t *part, caddr_t buffer,
949 log_addr = part->bam_index * bsize + blk * SECTOR_SIZE; 949 log_addr = part->bam_index * bsize + blk * SECTOR_SIZE;
950 part->EUNInfo[part->bam_index].Free--; 950 part->EUNInfo[part->bam_index].Free--;
951 part->FreeTotal--; 951 part->FreeTotal--;
952 if (set_bam_entry(part, log_addr, 0xfffffffe)) 952 if (set_bam_entry(part, log_addr, 0xfffffffe))
953 return -EIO; 953 return -EIO;
954 part->EUNInfo[part->bam_index].Deleted++; 954 part->EUNInfo[part->bam_index].Deleted++;
955 offset = (part->EUNInfo[part->bam_index].Offset + 955 offset = (part->EUNInfo[part->bam_index].Offset +
956 blk * SECTOR_SIZE); 956 blk * SECTOR_SIZE);
957 ret = part->mbd.mtd->write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen, 957 ret = part->mbd.mtd->write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen,
958 buffer); 958 buffer);
959 959
960 if (ret) { 960 if (ret) {
@@ -964,7 +964,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
964 offset); 964 offset);
965 return -EIO; 965 return -EIO;
966 } 966 }
967 967
968 /* Only delete the old entry when the new entry is ready */ 968 /* Only delete the old entry when the new entry is ready */
969 old_addr = part->VirtualBlockMap[sector+i]; 969 old_addr = part->VirtualBlockMap[sector+i];
970 if (old_addr != 0xffffffff) { 970 if (old_addr != 0xffffffff) {
@@ -979,7 +979,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
979 return -EIO; 979 return -EIO;
980 part->VirtualBlockMap[sector+i] = log_addr; 980 part->VirtualBlockMap[sector+i] = log_addr;
981 part->EUNInfo[part->bam_index].Deleted--; 981 part->EUNInfo[part->bam_index].Deleted--;
982 982
983 buffer += SECTOR_SIZE; 983 buffer += SECTOR_SIZE;
984 virt_addr += SECTOR_SIZE; 984 virt_addr += SECTOR_SIZE;
985 } 985 }
@@ -1034,20 +1034,20 @@ static void ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
1034 partition_t *partition; 1034 partition_t *partition;
1035 1035
1036 partition = kmalloc(sizeof(partition_t), GFP_KERNEL); 1036 partition = kmalloc(sizeof(partition_t), GFP_KERNEL);
1037 1037
1038 if (!partition) { 1038 if (!partition) {
1039 printk(KERN_WARNING "No memory to scan for FTL on %s\n", 1039 printk(KERN_WARNING "No memory to scan for FTL on %s\n",
1040 mtd->name); 1040 mtd->name);
1041 return; 1041 return;
1042 } 1042 }
1043 1043
1044 memset(partition, 0, sizeof(partition_t)); 1044 memset(partition, 0, sizeof(partition_t));
1045 1045
1046 partition->mbd.mtd = mtd; 1046 partition->mbd.mtd = mtd;
1047 1047
1048 if ((scan_header(partition) == 0) && 1048 if ((scan_header(partition) == 0) &&
1049 (build_maps(partition) == 0)) { 1049 (build_maps(partition) == 0)) {
1050 1050
1051 partition->state = FTL_FORMATTED; 1051 partition->state = FTL_FORMATTED;
1052#ifdef PCMCIA_DEBUG 1052#ifdef PCMCIA_DEBUG
1053 printk(KERN_INFO "ftl_cs: opening %d KiB FTL partition\n", 1053 printk(KERN_INFO "ftl_cs: opening %d KiB FTL partition\n",
@@ -1086,7 +1086,7 @@ struct mtd_blktrans_ops ftl_tr = {
1086 1086
1087int init_ftl(void) 1087int init_ftl(void)
1088{ 1088{
1089 DEBUG(0, "$Id: ftl.c,v 1.55 2005/01/17 13:47:21 hvr Exp $\n"); 1089 DEBUG(0, "$Id: ftl.c,v 1.58 2005/11/07 11:14:19 gleixner Exp $\n");
1090 1090
1091 return register_mtd_blktrans(&ftl_tr); 1091 return register_mtd_blktrans(&ftl_tr);
1092} 1092}
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index 39eb53f6551f..8a544890173d 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * inftlcore.c -- Linux driver for Inverse Flash Translation Layer (INFTL) 2 * inftlcore.c -- Linux driver for Inverse Flash Translation Layer (INFTL)
3 * 3 *
4 * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) 4 * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
@@ -7,7 +7,7 @@
7 * (c) 1999 Machine Vision Holdings, Inc. 7 * (c) 1999 Machine Vision Holdings, Inc.
8 * Author: David Woodhouse <dwmw2@infradead.org> 8 * Author: David Woodhouse <dwmw2@infradead.org>
9 * 9 *
10 * $Id: inftlcore.c,v 1.18 2004/11/16 18:28:59 dwmw2 Exp $ 10 * $Id: inftlcore.c,v 1.19 2005/11/07 11:14:20 gleixner Exp $
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 13 * it under the terms of the GNU General Public License as published by
@@ -113,23 +113,21 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
113 113
114 if (inftl->mbd.size != inftl->heads * inftl->cylinders * inftl->sectors) { 114 if (inftl->mbd.size != inftl->heads * inftl->cylinders * inftl->sectors) {
115 /* 115 /*
116 Oh no we don't have 116 Oh no we don't have
117 mbd.size == heads * cylinders * sectors 117 mbd.size == heads * cylinders * sectors
118 */ 118 */
119 printk(KERN_WARNING "INFTL: cannot calculate a geometry to " 119 printk(KERN_WARNING "INFTL: cannot calculate a geometry to "
120 "match size of 0x%lx.\n", inftl->mbd.size); 120 "match size of 0x%lx.\n", inftl->mbd.size);
121 printk(KERN_WARNING "INFTL: using C:%d H:%d S:%d " 121 printk(KERN_WARNING "INFTL: using C:%d H:%d S:%d "
122 "(== 0x%lx sects)\n", 122 "(== 0x%lx sects)\n",
123 inftl->cylinders, inftl->heads , inftl->sectors, 123 inftl->cylinders, inftl->heads , inftl->sectors,
124 (long)inftl->cylinders * (long)inftl->heads * 124 (long)inftl->cylinders * (long)inftl->heads *
125 (long)inftl->sectors ); 125 (long)inftl->sectors );
126 } 126 }
127 127
128 if (add_mtd_blktrans_dev(&inftl->mbd)) { 128 if (add_mtd_blktrans_dev(&inftl->mbd)) {
129 if (inftl->PUtable) 129 kfree(inftl->PUtable);
130 kfree(inftl->PUtable); 130 kfree(inftl->VUtable);
131 if (inftl->VUtable)
132 kfree(inftl->VUtable);
133 kfree(inftl); 131 kfree(inftl);
134 return; 132 return;
135 } 133 }
@@ -147,10 +145,8 @@ static void inftl_remove_dev(struct mtd_blktrans_dev *dev)
147 145
148 del_mtd_blktrans_dev(dev); 146 del_mtd_blktrans_dev(dev);
149 147
150 if (inftl->PUtable) 148 kfree(inftl->PUtable);
151 kfree(inftl->PUtable); 149 kfree(inftl->VUtable);
152 if (inftl->VUtable)
153 kfree(inftl->VUtable);
154 kfree(inftl); 150 kfree(inftl);
155} 151}
156 152
@@ -223,7 +219,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
223 "Virtual Unit Chain %d!\n", thisVUC); 219 "Virtual Unit Chain %d!\n", thisVUC);
224 return BLOCK_NIL; 220 return BLOCK_NIL;
225 } 221 }
226 222
227 /* 223 /*
228 * Scan to find the Erase Unit which holds the actual data for each 224 * Scan to find the Erase Unit which holds the actual data for each
229 * 512-byte block within the Chain. 225 * 512-byte block within the Chain.
@@ -264,7 +260,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
264 "Unit Chain 0x%x\n", thisVUC); 260 "Unit Chain 0x%x\n", thisVUC);
265 return BLOCK_NIL; 261 return BLOCK_NIL;
266 } 262 }
267 263
268 thisEUN = inftl->PUtable[thisEUN]; 264 thisEUN = inftl->PUtable[thisEUN];
269 } 265 }
270 266
@@ -295,15 +291,15 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
295 */ 291 */
296 if (BlockMap[block] == BLOCK_NIL) 292 if (BlockMap[block] == BLOCK_NIL)
297 continue; 293 continue;
298 294
299 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize * 295 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize *
300 BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE, 296 BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE,
301 &retlen, movebuf); 297 &retlen, movebuf);
302 if (ret < 0) { 298 if (ret < 0) {
303 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize * 299 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize *
304 BlockMap[block]) + (block * SECTORSIZE), 300 BlockMap[block]) + (block * SECTORSIZE),
305 SECTORSIZE, &retlen, movebuf); 301 SECTORSIZE, &retlen, movebuf);
306 if (ret != -EIO) 302 if (ret != -EIO)
307 DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went " 303 DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went "
308 "away on retry?\n"); 304 "away on retry?\n");
309 } 305 }
@@ -355,7 +351,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
355static u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock) 351static u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock)
356{ 352{
357 /* 353 /*
358 * This is the part that needs some cleverness applied. 354 * This is the part that needs some cleverness applied.
359 * For now, I'm doing the minimum applicable to actually 355 * For now, I'm doing the minimum applicable to actually
360 * get the thing to work. 356 * get the thing to work.
361 * Wear-levelling and other clever stuff needs to be implemented 357 * Wear-levelling and other clever stuff needs to be implemented
@@ -414,7 +410,7 @@ static int nrbits(unsigned int val, int bitcount)
414} 410}
415 411
416/* 412/*
417 * INFTL_findwriteunit: Return the unit number into which we can write 413 * INFTL_findwriteunit: Return the unit number into which we can write
418 * for this block. Make it available if it isn't already. 414 * for this block. Make it available if it isn't already.
419 */ 415 */
420static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block) 416static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
@@ -463,10 +459,10 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
463 * Invalid block. Don't use it any more. 459 * Invalid block. Don't use it any more.
464 * Must implement. 460 * Must implement.
465 */ 461 */
466 break; 462 break;
467 } 463 }
468 464
469 if (!silly--) { 465 if (!silly--) {
470 printk(KERN_WARNING "INFTL: infinite loop in " 466 printk(KERN_WARNING "INFTL: infinite loop in "
471 "Virtual Unit Chain 0x%x\n", thisVUC); 467 "Virtual Unit Chain 0x%x\n", thisVUC);
472 return 0xffff; 468 return 0xffff;
@@ -482,7 +478,7 @@ hitused:
482 478
483 479
484 /* 480 /*
485 * OK. We didn't find one in the existing chain, or there 481 * OK. We didn't find one in the existing chain, or there
486 * is no existing chain. Allocate a new one. 482 * is no existing chain. Allocate a new one.
487 */ 483 */
488 writeEUN = INFTL_findfreeblock(inftl, 0); 484 writeEUN = INFTL_findfreeblock(inftl, 0);
@@ -506,8 +502,8 @@ hitused:
506 if (writeEUN == BLOCK_NIL) { 502 if (writeEUN == BLOCK_NIL) {
507 /* 503 /*
508 * Ouch. This should never happen - we should 504 * Ouch. This should never happen - we should
509 * always be able to make some room somehow. 505 * always be able to make some room somehow.
510 * If we get here, we've allocated more storage 506 * If we get here, we've allocated more storage
511 * space than actual media, or our makefreeblock 507 * space than actual media, or our makefreeblock
512 * routine is missing something. 508 * routine is missing something.
513 */ 509 */
@@ -518,7 +514,7 @@ hitused:
518 INFTL_dumpVUchains(inftl); 514 INFTL_dumpVUchains(inftl);
519#endif 515#endif
520 return BLOCK_NIL; 516 return BLOCK_NIL;
521 } 517 }
522 } 518 }
523 519
524 /* 520 /*
@@ -543,7 +539,7 @@ hitused:
543 parity |= (nrbits(prev_block, 16) & 0x1) ? 0x2 : 0; 539 parity |= (nrbits(prev_block, 16) & 0x1) ? 0x2 : 0;
544 parity |= (nrbits(anac, 8) & 0x1) ? 0x4 : 0; 540 parity |= (nrbits(anac, 8) & 0x1) ? 0x4 : 0;
545 parity |= (nrbits(nacs, 8) & 0x1) ? 0x8 : 0; 541 parity |= (nrbits(nacs, 8) & 0x1) ? 0x8 : 0;
546 542
547 oob.u.a.virtualUnitNo = cpu_to_le16(thisVUC); 543 oob.u.a.virtualUnitNo = cpu_to_le16(thisVUC);
548 oob.u.a.prevUnitNo = cpu_to_le16(prev_block); 544 oob.u.a.prevUnitNo = cpu_to_le16(prev_block);
549 oob.u.a.ANAC = anac; 545 oob.u.a.ANAC = anac;
@@ -562,7 +558,7 @@ hitused:
562 oob.u.b.parityPerField = parity; 558 oob.u.b.parityPerField = parity;
563 oob.u.b.discarded = 0xaa; 559 oob.u.b.discarded = 0xaa;
564 560
565 MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize + 561 MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize +
566 SECTORSIZE * 4 + 8, 8, &retlen, (char *)&oob.u); 562 SECTORSIZE * 4 + 8, 8, &retlen, (char *)&oob.u);
567 563
568 inftl->PUtable[writeEUN] = inftl->VUtable[thisVUC]; 564 inftl->PUtable[writeEUN] = inftl->VUtable[thisVUC];
@@ -602,7 +598,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
602 "Virtual Unit Chain %d!\n", thisVUC); 598 "Virtual Unit Chain %d!\n", thisVUC);
603 return; 599 return;
604 } 600 }
605 601
606 /* 602 /*
607 * Scan through the Erase Units to determine whether any data is in 603 * Scan through the Erase Units to determine whether any data is in
608 * each of the 512-byte blocks within the Chain. 604 * each of the 512-byte blocks within the Chain.
@@ -642,7 +638,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
642 "Unit Chain 0x%x\n", thisVUC); 638 "Unit Chain 0x%x\n", thisVUC);
643 return; 639 return;
644 } 640 }
645 641
646 thisEUN = inftl->PUtable[thisEUN]; 642 thisEUN = inftl->PUtable[thisEUN];
647 } 643 }
648 644
@@ -758,7 +754,7 @@ foundit:
758 return 0; 754 return 0;
759} 755}
760 756
761static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block, 757static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
762 char *buffer) 758 char *buffer)
763{ 759{
764 struct INFTLrecord *inftl = (void *)mbd; 760 struct INFTLrecord *inftl = (void *)mbd;
@@ -893,7 +889,7 @@ extern char inftlmountrev[];
893 889
894static int __init init_inftl(void) 890static int __init init_inftl(void)
895{ 891{
896 printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.18 $, " 892 printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.19 $, "
897 "inftlmount.c %s\n", inftlmountrev); 893 "inftlmount.c %s\n", inftlmountrev);
898 894
899 return register_mtd_blktrans(&inftl_tr); 895 return register_mtd_blktrans(&inftl_tr);
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index b5dda47395a7..43fdc9433882 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -1,14 +1,14 @@
1/* 1/*
2 * inftlmount.c -- INFTL mount code with extensive checks. 2 * inftlmount.c -- INFTL mount code with extensive checks.
3 * 3 *
4 * Author: Greg Ungerer (gerg@snapgear.com) 4 * Author: Greg Ungerer (gerg@snapgear.com)
5 * (C) Copyright 2002-2003, Greg Ungerer (gerg@snapgear.com) 5 * (C) Copyright 2002-2003, Greg Ungerer (gerg@snapgear.com)
6 * 6 *
7 * Based heavily on the nftlmount.c code which is: 7 * Based heavily on the nftlmount.c code which is:
8 * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 8 * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
9 * Copyright (C) 2000 Netgem S.A. 9 * Copyright (C) 2000 Netgem S.A.
10 * 10 *
11 * $Id: inftlmount.c,v 1.16 2004/11/22 13:50:53 kalev Exp $ 11 * $Id: inftlmount.c,v 1.18 2005/11/07 11:14:20 gleixner Exp $
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by 14 * it under the terms of the GNU General Public License as published by
@@ -41,7 +41,7 @@
41#include <linux/mtd/inftl.h> 41#include <linux/mtd/inftl.h>
42#include <linux/mtd/compatmac.h> 42#include <linux/mtd/compatmac.h>
43 43
44char inftlmountrev[]="$Revision: 1.16 $"; 44char inftlmountrev[]="$Revision: 1.18 $";
45 45
46/* 46/*
47 * find_boot_record: Find the INFTL Media Header and its Spare copy which 47 * find_boot_record: Find the INFTL Media Header and its Spare copy which
@@ -273,7 +273,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
273 inftl->nb_boot_blocks); 273 inftl->nb_boot_blocks);
274 return -1; 274 return -1;
275 } 275 }
276 276
277 inftl->mbd.size = inftl->numvunits * 277 inftl->mbd.size = inftl->numvunits *
278 (inftl->EraseSize / SECTORSIZE); 278 (inftl->EraseSize / SECTORSIZE);
279 279
@@ -302,7 +302,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
302 inftl->nb_blocks * sizeof(u16)); 302 inftl->nb_blocks * sizeof(u16));
303 return -ENOMEM; 303 return -ENOMEM;
304 } 304 }
305 305
306 /* Mark the blocks before INFTL MediaHeader as reserved */ 306 /* Mark the blocks before INFTL MediaHeader as reserved */
307 for (i = 0; i < inftl->nb_boot_blocks; i++) 307 for (i = 0; i < inftl->nb_boot_blocks; i++)
308 inftl->PUtable[i] = BLOCK_RESERVED; 308 inftl->PUtable[i] = BLOCK_RESERVED;
@@ -380,7 +380,7 @@ static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address,
380 * 380 *
381 * Return: 0 when succeed, -1 on error. 381 * Return: 0 when succeed, -1 on error.
382 * 382 *
383 * ToDo: 1. Is it neceressary to check_free_sector after erasing ?? 383 * ToDo: 1. Is it neceressary to check_free_sector after erasing ??
384 */ 384 */
385int INFTL_formatblock(struct INFTLrecord *inftl, int block) 385int INFTL_formatblock(struct INFTLrecord *inftl, int block)
386{ 386{
@@ -563,7 +563,7 @@ int INFTL_mount(struct INFTLrecord *s)
563 /* Search for INFTL MediaHeader and Spare INFTL Media Header */ 563 /* Search for INFTL MediaHeader and Spare INFTL Media Header */
564 if (find_boot_record(s) < 0) { 564 if (find_boot_record(s) < 0) {
565 printk(KERN_WARNING "INFTL: could not find valid boot record?\n"); 565 printk(KERN_WARNING "INFTL: could not find valid boot record?\n");
566 return -1; 566 return -ENXIO;
567 } 567 }
568 568
569 /* Init the logical to physical table */ 569 /* Init the logical to physical table */
@@ -574,6 +574,12 @@ int INFTL_mount(struct INFTLrecord *s)
574 574
575 /* Temporary buffer to store ANAC numbers. */ 575 /* Temporary buffer to store ANAC numbers. */
576 ANACtable = kmalloc(s->nb_blocks * sizeof(u8), GFP_KERNEL); 576 ANACtable = kmalloc(s->nb_blocks * sizeof(u8), GFP_KERNEL);
577 if (!ANACtable) {
578 printk(KERN_WARNING "INFTL: allocation of ANACtable "
579 "failed (%zd bytes)\n",
580 s->nb_blocks * sizeof(u8));
581 return -ENOMEM;
582 }
577 memset(ANACtable, 0, s->nb_blocks); 583 memset(ANACtable, 0, s->nb_blocks);
578 584
579 /* 585 /*
@@ -595,7 +601,7 @@ int INFTL_mount(struct INFTLrecord *s)
595 601
596 for (chain_length = 0; ; chain_length++) { 602 for (chain_length = 0; ; chain_length++) {
597 603
598 if ((chain_length == 0) && 604 if ((chain_length == 0) &&
599 (s->PUtable[block] != BLOCK_NOTEXPLORED)) { 605 (s->PUtable[block] != BLOCK_NOTEXPLORED)) {
600 /* Nothing to do here, onto next block */ 606 /* Nothing to do here, onto next block */
601 break; 607 break;
@@ -742,7 +748,7 @@ int INFTL_mount(struct INFTLrecord *s)
742 "in virtual chain %d\n", 748 "in virtual chain %d\n",
743 s->PUtable[block], logical_block); 749 s->PUtable[block], logical_block);
744 s->PUtable[block] = BLOCK_NIL; 750 s->PUtable[block] = BLOCK_NIL;
745 751
746 } 752 }
747 if (ANACtable[block] != ANAC) { 753 if (ANACtable[block] != ANAC) {
748 /* 754 /*
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 44781a83b2e7..48638c8097a5 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -1,5 +1,5 @@
1# drivers/mtd/maps/Kconfig 1# drivers/mtd/maps/Kconfig
2# $Id: Kconfig,v 1.55 2005/07/02 01:53:24 tpoynor Exp $ 2# $Id: Kconfig,v 1.61 2005/11/07 11:14:26 gleixner Exp $
3 3
4menu "Mapping drivers for chip access" 4menu "Mapping drivers for chip access"
5 depends on MTD!=n 5 depends on MTD!=n
@@ -64,9 +64,9 @@ config MTD_SUN_UFLASH
64 tristate "Sun Microsystems userflash support" 64 tristate "Sun Microsystems userflash support"
65 depends on (SPARC32 || SPARC64) && MTD_CFI 65 depends on (SPARC32 || SPARC64) && MTD_CFI
66 help 66 help
67 This provides a 'mapping' driver which supports the way in 67 This provides a 'mapping' driver which supports the way in
68 which user-programmable flash chips are connected on various 68 which user-programmable flash chips are connected on various
69 Sun Microsystems boardsets. This driver will require CFI support 69 Sun Microsystems boardsets. This driver will require CFI support
70 in the kernel, so if you did not enable CFI previously, do that now. 70 in the kernel, so if you did not enable CFI previously, do that now.
71 71
72config MTD_PNC2000 72config MTD_PNC2000
@@ -89,22 +89,22 @@ config MTD_NETSC520
89 depends on X86 && MTD_CFI && MTD_PARTITIONS 89 depends on X86 && MTD_CFI && MTD_PARTITIONS
90 help 90 help
91 This enables access routines for the flash chips on the AMD NetSc520 91 This enables access routines for the flash chips on the AMD NetSc520
92 demonstration board. If you have one of these boards and would like 92 demonstration board. If you have one of these boards and would like
93 to use the flash chips on it, say 'Y'. 93 to use the flash chips on it, say 'Y'.
94 94
95config MTD_TS5500 95config MTD_TS5500
96 tristate "JEDEC Flash device mapped on Technologic Systems TS-5500" 96 tristate "JEDEC Flash device mapped on Technologic Systems TS-5500"
97 depends on X86 && MTD_JEDECPROBE && MTD_PARTITIONS 97 depends on ELAN
98 select MTD_PARTITIONS
99 select MTD_JEDECPROBE
100 select MTD_CFI_AMDSTD
98 help 101 help
99 This provides a driver for the on-board flash of the Technologic 102 This provides a driver for the on-board flash of the Technologic
100 System's TS-5500 board. The flash is split into 3 partitions 103 System's TS-5500 board. The 2MB flash is split into 3 partitions
101 which are accessed as separate MTD devices. 104 which are accessed as separate MTD devices.
102 105
103 mtd0 and mtd2 are the two BIOS drives. Unfortunately the BIOS 106 mtd0 and mtd2 are the two BIOS drives, which use the resident
104 uses a proprietary flash translation layer from General Software, 107 flash disk (RFD) flash translation layer.
105 which is not supported (the drives cannot be mounted). You can
106 create your own file system (jffs for example), but the BIOS
107 won't be able to boot from it.
108 108
109 mtd1 allows you to reprogram your BIOS. BE VERY CAREFUL. 109 mtd1 allows you to reprogram your BIOS. BE VERY CAREFUL.
110 110
@@ -212,11 +212,18 @@ config MTD_NETtel
212 Support for flash chips on NETtel/SecureEdge/SnapGear boards. 212 Support for flash chips on NETtel/SecureEdge/SnapGear boards.
213 213
214config MTD_ALCHEMY 214config MTD_ALCHEMY
215 tristate ' AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support' 215 tristate ' AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support'
216 depends on MIPS && SOC_AU1X00 216 depends on SOC_AU1X00
217 help 217 help
218 Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards 218 Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards
219 219
220config MTD_MTX1
221 tristate "4G Systems MTX-1 Flash device"
222 depends on MIPS && MIPS_MTX1
223 help
224 Flash memory access on 4G Systems MTX-1 Board. If you have one of
225 these boards and would like to use the flash chips on it, say 'Y'.
226
220config MTD_DILNETPC 227config MTD_DILNETPC
221 tristate "CFI Flash device mapped on DIL/Net PC" 228 tristate "CFI Flash device mapped on DIL/Net PC"
222 depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT 229 depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT
@@ -244,14 +251,14 @@ config MTD_L440GX
244 251
245config MTD_SBC8240 252config MTD_SBC8240
246 tristate "Flash device on SBC8240" 253 tristate "Flash device on SBC8240"
247 depends on PPC32 && MTD_JEDECPROBE && 6xx && 8260 254 depends on MTD_JEDECPROBE && 8260
248 help 255 help
249 Flash access on the SBC8240 board from Wind River. See 256 Flash access on the SBC8240 board from Wind River. See
250 <http://www.windriver.com/products/sbc8240/> 257 <http://www.windriver.com/products/sbc8240/>
251 258
252config MTD_TQM8XXL 259config MTD_TQM8XXL
253 tristate "CFI Flash device mapped on TQM8XXL" 260 tristate "CFI Flash device mapped on TQM8XXL"
254 depends on MTD_CFI && PPC32 && 8xx && TQM8xxL 261 depends on MTD_CFI && TQM8xxL
255 help 262 help
256 The TQM8xxL PowerPC board has up to two banks of CFI-compliant 263 The TQM8xxL PowerPC board has up to two banks of CFI-compliant
257 chips, currently uses AMD one. This 'mapping' driver supports 264 chips, currently uses AMD one. This 'mapping' driver supports
@@ -261,7 +268,7 @@ config MTD_TQM8XXL
261 268
262config MTD_RPXLITE 269config MTD_RPXLITE
263 tristate "CFI Flash device mapped on RPX Lite or CLLF" 270 tristate "CFI Flash device mapped on RPX Lite or CLLF"
264 depends on MTD_CFI && PPC32 && 8xx && (RPXCLASSIC || RPXLITE) 271 depends on MTD_CFI && (RPXCLASSIC || RPXLITE)
265 help 272 help
266 The RPXLite PowerPC board has CFI-compliant chips mapped in 273 The RPXLite PowerPC board has CFI-compliant chips mapped in
267 a strange sparse mapping. This 'mapping' driver supports that 274 a strange sparse mapping. This 'mapping' driver supports that
@@ -271,7 +278,7 @@ config MTD_RPXLITE
271 278
272config MTD_MBX860 279config MTD_MBX860
273 tristate "System flash on MBX860 board" 280 tristate "System flash on MBX860 board"
274 depends on MTD_CFI && PPC32 && 8xx && MBX 281 depends on MTD_CFI && MBX
275 help 282 help
276 This enables access routines for the flash chips on the Motorola 283 This enables access routines for the flash chips on the Motorola
277 MBX860 board. If you have one of these boards and would like 284 MBX860 board. If you have one of these boards and would like
@@ -279,7 +286,7 @@ config MTD_MBX860
279 286
280config MTD_DBOX2 287config MTD_DBOX2
281 tristate "CFI Flash device mapped on D-Box2" 288 tristate "CFI Flash device mapped on D-Box2"
282 depends on PPC32 && 8xx && DBOX2 && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD 289 depends on DBOX2 && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD
283 help 290 help
284 This enables access routines for the flash chips on the Nokia/Sagem 291 This enables access routines for the flash chips on the Nokia/Sagem
285 D-Box 2 board. If you have one of these boards and would like to use 292 D-Box 2 board. If you have one of these boards and would like to use
@@ -287,14 +294,14 @@ config MTD_DBOX2
287 294
288config MTD_CFI_FLAGADM 295config MTD_CFI_FLAGADM
289 tristate "CFI Flash device mapping on FlagaDM" 296 tristate "CFI Flash device mapping on FlagaDM"
290 depends on PPC32 && 8xx && MTD_CFI 297 depends on 8xx && MTD_CFI
291 help 298 help
292 Mapping for the Flaga digital module. If you don't have one, ignore 299 Mapping for the Flaga digital module. If you don't have one, ignore
293 this setting. 300 this setting.
294 301
295config MTD_BEECH 302config MTD_BEECH
296 tristate "CFI Flash device mapped on IBM 405LP Beech" 303 tristate "CFI Flash device mapped on IBM 405LP Beech"
297 depends on MTD_CFI && PPC32 && 40x && BEECH 304 depends on MTD_CFI && BEECH
298 help 305 help
299 This enables access routines for the flash chips on the IBM 306 This enables access routines for the flash chips on the IBM
300 405LP Beech board. If you have one of these boards and would like 307 405LP Beech board. If you have one of these boards and would like
@@ -302,7 +309,7 @@ config MTD_BEECH
302 309
303config MTD_ARCTIC 310config MTD_ARCTIC
304 tristate "CFI Flash device mapped on IBM 405LP Arctic" 311 tristate "CFI Flash device mapped on IBM 405LP Arctic"
305 depends on MTD_CFI && PPC32 && 40x && ARCTIC2 312 depends on MTD_CFI && ARCTIC2
306 help 313 help
307 This enables access routines for the flash chips on the IBM 405LP 314 This enables access routines for the flash chips on the IBM 405LP
308 Arctic board. If you have one of these boards and would like to 315 Arctic board. If you have one of these boards and would like to
@@ -310,7 +317,7 @@ config MTD_ARCTIC
310 317
311config MTD_WALNUT 318config MTD_WALNUT
312 tristate "Flash device mapped on IBM 405GP Walnut" 319 tristate "Flash device mapped on IBM 405GP Walnut"
313 depends on MTD_JEDECPROBE && PPC32 && 40x && WALNUT 320 depends on MTD_JEDECPROBE && WALNUT
314 help 321 help
315 This enables access routines for the flash chips on the IBM 405GP 322 This enables access routines for the flash chips on the IBM 405GP
316 Walnut board. If you have one of these boards and would like to 323 Walnut board. If you have one of these boards and would like to
@@ -318,7 +325,7 @@ config MTD_WALNUT
318 325
319config MTD_EBONY 326config MTD_EBONY
320 tristate "Flash devices mapped on IBM 440GP Ebony" 327 tristate "Flash devices mapped on IBM 440GP Ebony"
321 depends on MTD_JEDECPROBE && PPC32 && 44x && EBONY 328 depends on MTD_JEDECPROBE && EBONY
322 help 329 help
323 This enables access routines for the flash chips on the IBM 440GP 330 This enables access routines for the flash chips on the IBM 440GP
324 Ebony board. If you have one of these boards and would like to 331 Ebony board. If you have one of these boards and would like to
@@ -326,7 +333,7 @@ config MTD_EBONY
326 333
327config MTD_OCOTEA 334config MTD_OCOTEA
328 tristate "Flash devices mapped on IBM 440GX Ocotea" 335 tristate "Flash devices mapped on IBM 440GX Ocotea"
329 depends on MTD_CFI && PPC32 && 44x && OCOTEA 336 depends on MTD_CFI && OCOTEA
330 help 337 help
331 This enables access routines for the flash chips on the IBM 440GX 338 This enables access routines for the flash chips on the IBM 440GX
332 Ocotea board. If you have one of these boards and would like to 339 Ocotea board. If you have one of these boards and would like to
@@ -334,12 +341,20 @@ config MTD_OCOTEA
334 341
335config MTD_REDWOOD 342config MTD_REDWOOD
336 tristate "CFI Flash devices mapped on IBM Redwood" 343 tristate "CFI Flash devices mapped on IBM Redwood"
337 depends on MTD_CFI && PPC32 && 4xx && 40x && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 ) 344 depends on MTD_CFI && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 )
338 help 345 help
339 This enables access routines for the flash chips on the IBM 346 This enables access routines for the flash chips on the IBM
340 Redwood board. If you have one of these boards and would like to 347 Redwood board. If you have one of these boards and would like to
341 use the flash chips on it, say 'Y'. 348 use the flash chips on it, say 'Y'.
342 349
350config MTD_TQM834x
351 tristate "Flash device mapped on TQ Components TQM834x Boards"
352 depends on MTD_CFI && TQM834x
353 help
354 This enables access routines for the flash chips on the
355 TQ Components TQM834x boards. If you have one of these boards
356 and would like to use the flash chips on it, say 'Y'.
357
343config MTD_CSTM_MIPS_IXX 358config MTD_CSTM_MIPS_IXX
344 tristate "Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board" 359 tristate "Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board"
345 depends on MIPS && MTD_CFI && MTD_JEDECPROBE && MTD_PARTITIONS 360 depends on MIPS && MTD_CFI && MTD_JEDECPROBE && MTD_PARTITIONS
@@ -362,8 +377,8 @@ config MTD_CSTM_MIPS_IXX_START
362 default "0x8000000" 377 default "0x8000000"
363 help 378 help
364 This is the physical memory location that the MTD driver will 379 This is the physical memory location that the MTD driver will
365 use for the flash chips on your particular target board. 380 use for the flash chips on your particular target board.
366 Refer to the memory map which should hopefully be in the 381 Refer to the memory map which should hopefully be in the
367 documentation for your board. 382 documentation for your board.
368 383
369config MTD_CSTM_MIPS_IXX_LEN 384config MTD_CSTM_MIPS_IXX_LEN
@@ -371,7 +386,7 @@ config MTD_CSTM_MIPS_IXX_LEN
371 depends on MTD_CSTM_MIPS_IXX 386 depends on MTD_CSTM_MIPS_IXX
372 default "0x4000000" 387 default "0x4000000"
373 help 388 help
374 This is the total length that the MTD driver will use for the 389 This is the total length that the MTD driver will use for the
375 flash chips on your particular board. Refer to the memory 390 flash chips on your particular board. Refer to the memory
376 map which should hopefully be in the documentation for your 391 map which should hopefully be in the documentation for your
377 board. 392 board.
@@ -405,14 +420,14 @@ config MTD_ARM_INTEGRATOR
405 420
406config MTD_CDB89712 421config MTD_CDB89712
407 tristate "Cirrus CDB89712 evaluation board mappings" 422 tristate "Cirrus CDB89712 evaluation board mappings"
408 depends on ARM && MTD_CFI && ARCH_CDB89712 423 depends on MTD_CFI && ARCH_CDB89712
409 help 424 help
410 This enables access to the flash or ROM chips on the CDB89712 board. 425 This enables access to the flash or ROM chips on the CDB89712 board.
411 If you have such a board, say 'Y'. 426 If you have such a board, say 'Y'.
412 427
413config MTD_SA1100 428config MTD_SA1100
414 tristate "CFI Flash device mapped on StrongARM SA11x0" 429 tristate "CFI Flash device mapped on StrongARM SA11x0"
415 depends on ARM && MTD_CFI && ARCH_SA1100 && MTD_PARTITIONS 430 depends on MTD_CFI && ARCH_SA1100 && MTD_PARTITIONS
416 help 431 help
417 This enables access to the flash chips on most platforms based on 432 This enables access to the flash chips on most platforms based on
418 the SA1100 and SA1110, including the Assabet and the Compaq iPAQ. 433 the SA1100 and SA1110, including the Assabet and the Compaq iPAQ.
@@ -420,13 +435,13 @@ config MTD_SA1100
420 435
421config MTD_IPAQ 436config MTD_IPAQ
422 tristate "CFI Flash device mapped on Compaq/HP iPAQ" 437 tristate "CFI Flash device mapped on Compaq/HP iPAQ"
423 depends on ARM && IPAQ_HANDHELD && MTD_CFI 438 depends on IPAQ_HANDHELD && MTD_CFI
424 help 439 help
425 This provides a driver for the on-board flash of the iPAQ. 440 This provides a driver for the on-board flash of the iPAQ.
426 441
427config MTD_DC21285 442config MTD_DC21285
428 tristate "CFI Flash device mapped on DC21285 Footbridge" 443 tristate "CFI Flash device mapped on DC21285 Footbridge"
429 depends on ARM && MTD_CFI && ARCH_FOOTBRIDGE && MTD_COMPLEX_MAPPINGS 444 depends on MTD_CFI && ARCH_FOOTBRIDGE && MTD_COMPLEX_MAPPINGS
430 help 445 help
431 This provides a driver for the flash accessed using Intel's 446 This provides a driver for the flash accessed using Intel's
432 21285 bridge used with Intel's StrongARM processors. More info at 447 21285 bridge used with Intel's StrongARM processors. More info at
@@ -434,33 +449,33 @@ config MTD_DC21285
434 449
435config MTD_IQ80310 450config MTD_IQ80310
436 tristate "CFI Flash device mapped on the XScale IQ80310 board" 451 tristate "CFI Flash device mapped on the XScale IQ80310 board"
437 depends on ARM && MTD_CFI && ARCH_IQ80310 452 depends on MTD_CFI && ARCH_IQ80310
438 help 453 help
439 This enables access routines for the flash chips on the Intel XScale 454 This enables access routines for the flash chips on the Intel XScale
440 IQ80310 evaluation board. If you have one of these boards and would 455 IQ80310 evaluation board. If you have one of these boards and would
441 like to use the flash chips on it, say 'Y'. 456 like to use the flash chips on it, say 'Y'.
442 457
443config MTD_IXP4XX 458config MTD_IXP4XX
444 tristate "CFI Flash device mapped on Intel IXP4xx based systems" 459 tristate "CFI Flash device mapped on Intel IXP4xx based systems"
445 depends on ARM && MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX 460 depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX
446 help 461 help
447 This enables MTD access to flash devices on platforms based 462 This enables MTD access to flash devices on platforms based
448 on Intel's IXP4xx family of network processors such as the 463 on Intel's IXP4xx family of network processors such as the
449 IXDP425 and Coyote. If you have an IXP4xx based board and 464 IXDP425 and Coyote. If you have an IXP4xx based board and
450 would like to use the flash chips on it, say 'Y'. 465 would like to use the flash chips on it, say 'Y'.
451 466
452config MTD_IXP2000 467config MTD_IXP2000
453 tristate "CFI Flash device mapped on Intel IXP2000 based systems" 468 tristate "CFI Flash device mapped on Intel IXP2000 based systems"
454 depends on ARM && MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP2000 469 depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP2000
455 help 470 help
456 This enables MTD access to flash devices on platforms based 471 This enables MTD access to flash devices on platforms based
457 on Intel's IXP2000 family of network processors such as the 472 on Intel's IXP2000 family of network processors such as the
458 IXDP425 and Coyote. If you have an IXP2000 based board and 473 IXDP425 and Coyote. If you have an IXP2000 based board and
459 would like to use the flash chips on it, say 'Y'. 474 would like to use the flash chips on it, say 'Y'.
460 475
461config MTD_EPXA10DB 476config MTD_EPXA10DB
462 tristate "CFI Flash device mapped on Epxa10db" 477 tristate "CFI Flash device mapped on Epxa10db"
463 depends on ARM && MTD_CFI && MTD_PARTITIONS && ARCH_CAMELOT 478 depends on MTD_CFI && MTD_PARTITIONS && ARCH_CAMELOT
464 help 479 help
465 This enables support for the flash devices on the Altera 480 This enables support for the flash devices on the Altera
466 Excalibur XA10 Development Board. If you are building a kernel 481 Excalibur XA10 Development Board. If you are building a kernel
@@ -468,21 +483,21 @@ config MTD_EPXA10DB
468 483
469config MTD_FORTUNET 484config MTD_FORTUNET
470 tristate "CFI Flash device mapped on the FortuNet board" 485 tristate "CFI Flash device mapped on the FortuNet board"
471 depends on ARM && MTD_CFI && MTD_PARTITIONS && SA1100_FORTUNET 486 depends on MTD_CFI && MTD_PARTITIONS && SA1100_FORTUNET
472 help 487 help
473 This enables access to the Flash on the FortuNet board. If you 488 This enables access to the Flash on the FortuNet board. If you
474 have such a board, say 'Y'. 489 have such a board, say 'Y'.
475 490
476config MTD_AUTCPU12 491config MTD_AUTCPU12
477 tristate "NV-RAM mapping AUTCPU12 board" 492 tristate "NV-RAM mapping AUTCPU12 board"
478 depends on ARM && ARCH_AUTCPU12 493 depends on ARCH_AUTCPU12
479 help 494 help
480 This enables access to the NV-RAM on autronix autcpu12 board. 495 This enables access to the NV-RAM on autronix autcpu12 board.
481 If you have such a board, say 'Y'. 496 If you have such a board, say 'Y'.
482 497
483config MTD_EDB7312 498config MTD_EDB7312
484 tristate "CFI Flash device mapped on EDB7312" 499 tristate "CFI Flash device mapped on EDB7312"
485 depends on ARM && MTD_CFI 500 depends on ARCH_EDB7312 && MTD_CFI
486 help 501 help
487 This enables access to the CFI Flash on the Cogent EDB7312 board. 502 This enables access to the CFI Flash on the Cogent EDB7312 board.
488 If you have such a board, say 'Y' here. 503 If you have such a board, say 'Y' here.
@@ -496,7 +511,7 @@ config MTD_IMPA7
496 511
497config MTD_CEIVA 512config MTD_CEIVA
498 tristate "JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame" 513 tristate "JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame"
499 depends on ARM && MTD_JEDECPROBE && ARCH_CEIVA 514 depends on MTD_JEDECPROBE && ARCH_CEIVA
500 help 515 help
501 This enables access to the flash chips on the Ceiva/Polaroid 516 This enables access to the flash chips on the Ceiva/Polaroid
502 PhotoMax Digital Picture Frame. 517 PhotoMax Digital Picture Frame.
@@ -504,25 +519,31 @@ config MTD_CEIVA
504 519
505config MTD_NOR_TOTO 520config MTD_NOR_TOTO
506 tristate "NOR Flash device on TOTO board" 521 tristate "NOR Flash device on TOTO board"
507 depends on ARM && ARCH_OMAP && OMAP_TOTO 522 depends on ARCH_OMAP && OMAP_TOTO
508 help 523 help
509 This enables access to the NOR flash on the Texas Instruments 524 This enables access to the NOR flash on the Texas Instruments
510 TOTO board. 525 TOTO board.
511 526
512config MTD_H720X 527config MTD_H720X
513 tristate "Hynix evaluation board mappings" 528 tristate "Hynix evaluation board mappings"
514 depends on ARM && MTD_CFI && ( ARCH_H7201 || ARCH_H7202 ) 529 depends on MTD_CFI && ( ARCH_H7201 || ARCH_H7202 )
515 help 530 help
516 This enables access to the flash chips on the Hynix evaluation boards. 531 This enables access to the flash chips on the Hynix evaluation boards.
517 If you have such a board, say 'Y'. 532 If you have such a board, say 'Y'.
518 533
519config MTD_MPC1211 534config MTD_MPC1211
520 tristate "CFI Flash device mapped on Interface MPC-1211" 535 tristate "CFI Flash device mapped on Interface MPC-1211"
521 depends on SUPERH && SH_MPC1211 && MTD_CFI 536 depends on SH_MPC1211 && MTD_CFI
522 help 537 help
523 This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02). 538 This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02).
524 If you have such a board, say 'Y'. 539 If you have such a board, say 'Y'.
525 540
541config MTD_PQ2FADS
542 tristate "JEDEC flash SIMM mapped on PQ2FADS and 8272ADS boards"
543 depends on (ADS8272 || PQ2FADS) && MTD_PARTITIONS && MTD_JEDECPROBE && MTD_PHYSMAP && MTD_CFI_GEOMETRY && MTD_CFI_INTELEXT
544 help
545 This enables access to flash SIMM on PQ2FADS-like boards
546
526config MTD_OMAP_NOR 547config MTD_OMAP_NOR
527 tristate "TI OMAP board mappings" 548 tristate "TI OMAP board mappings"
528 depends on MTD_CFI && ARCH_OMAP 549 depends on MTD_CFI && ARCH_OMAP
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 7bcbc49e329f..7d9e940a1dcd 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# linux/drivers/maps/Makefile 2# linux/drivers/maps/Makefile
3# 3#
4# $Id: Makefile.common,v 1.30 2005/07/02 01:53:24 tpoynor Exp $ 4# $Id: Makefile.common,v 1.34 2005/11/07 11:14:26 gleixner Exp $
5 5
6ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y) 6ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
7obj-$(CONFIG_MTD) += map_funcs.o 7obj-$(CONFIG_MTD) += map_funcs.o
@@ -26,7 +26,7 @@ obj-$(CONFIG_MTD_MAINSTONE) += mainstone-flash.o
26obj-$(CONFIG_MTD_MBX860) += mbx860.o 26obj-$(CONFIG_MTD_MBX860) += mbx860.o
27obj-$(CONFIG_MTD_CEIVA) += ceiva.o 27obj-$(CONFIG_MTD_CEIVA) += ceiva.o
28obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o 28obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o
29obj-$(CONFIG_MTD_PHYSMAP) += physmap.o 29obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
30obj-$(CONFIG_MTD_PNC2000) += pnc2000.o 30obj-$(CONFIG_MTD_PNC2000) += pnc2000.o
31obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o 31obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o
32obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o 32obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o
@@ -70,3 +70,6 @@ obj-$(CONFIG_MTD_DMV182) += dmv182.o
70obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o 70obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o
71obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o 71obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
72obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o 72obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
73obj-$(CONFIG_MTD_PQ2FADS) += pq2fads.o
74obj-$(CONFIG_MTD_MTX1) += mtx-1_flash.o
75obj-$(CONFIG_MTD_TQM834x) += tqm834x.o
diff --git a/drivers/mtd/maps/alchemy-flash.c b/drivers/mtd/maps/alchemy-flash.c
index 27fd2a3c3b60..a57791a6ce40 100644
--- a/drivers/mtd/maps/alchemy-flash.c
+++ b/drivers/mtd/maps/alchemy-flash.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * Flash memory access on AMD Alchemy evaluation boards 2 * Flash memory access on AMD Alchemy evaluation boards
3 * 3 *
4 * $Id: alchemy-flash.c,v 1.1 2005/02/27 21:50:21 ppopov Exp $ 4 * $Id: alchemy-flash.c,v 1.2 2005/11/07 11:14:26 gleixner Exp $
5 * 5 *
6 * (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com> 6 * (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com>
7 * 7 *
8 */ 8 */
9 9
10#include <linux/config.h> 10#include <linux/config.h>
@@ -22,7 +22,7 @@
22#ifdef DEBUG_RW 22#ifdef DEBUG_RW
23#define DBG(x...) printk(x) 23#define DBG(x...) printk(x)
24#else 24#else
25#define DBG(x...) 25#define DBG(x...)
26#endif 26#endif
27 27
28#ifdef CONFIG_MIPS_PB1000 28#ifdef CONFIG_MIPS_PB1000
@@ -136,7 +136,7 @@ int __init alchemy_mtd_init(void)
136 int nb_parts = 0; 136 int nb_parts = 0;
137 unsigned long window_addr; 137 unsigned long window_addr;
138 unsigned long window_size; 138 unsigned long window_size;
139 139
140 /* Default flash buswidth */ 140 /* Default flash buswidth */
141 alchemy_map.bankwidth = BOARD_FLASH_WIDTH; 141 alchemy_map.bankwidth = BOARD_FLASH_WIDTH;
142 142
@@ -161,7 +161,7 @@ int __init alchemy_mtd_init(void)
161 * Now let's probe for the actual flash. Do it here since 161 * Now let's probe for the actual flash. Do it here since
162 * specific machine settings might have been set above. 162 * specific machine settings might have been set above.
163 */ 163 */
164 printk(KERN_NOTICE BOARD_MAP_NAME ": probing %d-bit flash bus\n", 164 printk(KERN_NOTICE BOARD_MAP_NAME ": probing %d-bit flash bus\n",
165 alchemy_map.bankwidth*8); 165 alchemy_map.bankwidth*8);
166 alchemy_map.virt = ioremap(window_addr, window_size); 166 alchemy_map.virt = ioremap(window_addr, window_size);
167 mymtd = do_map_probe("cfi_probe", &alchemy_map); 167 mymtd = do_map_probe("cfi_probe", &alchemy_map);
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c
index e8a900a77685..c350878d4592 100644
--- a/drivers/mtd/maps/amd76xrom.c
+++ b/drivers/mtd/maps/amd76xrom.c
@@ -2,7 +2,7 @@
2 * amd76xrom.c 2 * amd76xrom.c
3 * 3 *
4 * Normal mappings of chips in physical memory 4 * Normal mappings of chips in physical memory
5 * $Id: amd76xrom.c,v 1.20 2005/03/18 14:04:35 gleixner Exp $ 5 * $Id: amd76xrom.c,v 1.21 2005/11/07 11:14:26 gleixner Exp $
6 */ 6 */
7 7
8#include <linux/module.h> 8#include <linux/module.h>
@@ -70,7 +70,7 @@ static void amd76xrom_cleanup(struct amd76xrom_window *window)
70 list_del(&map->list); 70 list_del(&map->list);
71 kfree(map); 71 kfree(map);
72 } 72 }
73 if (window->rsrc.parent) 73 if (window->rsrc.parent)
74 release_resource(&window->rsrc); 74 release_resource(&window->rsrc);
75 75
76 if (window->virt) { 76 if (window->virt) {
@@ -107,7 +107,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
107 window->phys = 0xffff0000; /* 64KiB */ 107 window->phys = 0xffff0000; /* 64KiB */
108 } 108 }
109 window->size = 0xffffffffUL - window->phys + 1UL; 109 window->size = 0xffffffffUL - window->phys + 1UL;
110 110
111 /* 111 /*
112 * Try to reserve the window mem region. If this fails then 112 * Try to reserve the window mem region. If this fails then
113 * it is likely due to a fragment of the window being 113 * it is likely due to a fragment of the window being
@@ -138,7 +138,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
138 /* Enable writes through the rom window */ 138 /* Enable writes through the rom window */
139 pci_read_config_byte(pdev, 0x40, &byte); 139 pci_read_config_byte(pdev, 0x40, &byte);
140 pci_write_config_byte(pdev, 0x40, byte | 1); 140 pci_write_config_byte(pdev, 0x40, byte | 1);
141 141
142 /* FIXME handle registers 0x80 - 0x8C the bios region locks */ 142 /* FIXME handle registers 0x80 - 0x8C the bios region locks */
143 143
144 /* For write accesses caches are useless */ 144 /* For write accesses caches are useless */
@@ -186,7 +186,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
186 MOD_NAME, map->map.phys); 186 MOD_NAME, map->map.phys);
187 187
188 /* There is no generic VPP support */ 188 /* There is no generic VPP support */
189 for(map->map.bankwidth = 32; map->map.bankwidth; 189 for(map->map.bankwidth = 32; map->map.bankwidth;
190 map->map.bankwidth >>= 1) 190 map->map.bankwidth >>= 1)
191 { 191 {
192 char **probe_type; 192 char **probe_type;
@@ -239,7 +239,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
239 for(i = 0; i < cfi->numchips; i++) { 239 for(i = 0; i < cfi->numchips; i++) {
240 cfi->chips[i].start += offset; 240 cfi->chips[i].start += offset;
241 } 241 }
242 242
243 /* Now that the mtd devices is complete claim and export it */ 243 /* Now that the mtd devices is complete claim and export it */
244 map->mtd->owner = THIS_MODULE; 244 map->mtd->owner = THIS_MODULE;
245 if (add_mtd_device(map->mtd)) { 245 if (add_mtd_device(map->mtd)) {
@@ -259,9 +259,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
259 259
260 out: 260 out:
261 /* Free any left over map structures */ 261 /* Free any left over map structures */
262 if (map) { 262 kfree(map);
263 kfree(map);
264 }
265 /* See if I have any map structures */ 263 /* See if I have any map structures */
266 if (list_empty(&window->maps)) { 264 if (list_empty(&window->maps)) {
267 amd76xrom_cleanup(window); 265 amd76xrom_cleanup(window);
@@ -279,9 +277,9 @@ static void __devexit amd76xrom_remove_one (struct pci_dev *pdev)
279} 277}
280 278
281static struct pci_device_id amd76xrom_pci_tbl[] = { 279static struct pci_device_id amd76xrom_pci_tbl[] = {
282 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, 280 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410,
283 PCI_ANY_ID, PCI_ANY_ID, }, 281 PCI_ANY_ID, PCI_ANY_ID, },
284 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7440, 282 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7440,
285 PCI_ANY_ID, PCI_ANY_ID, }, 283 PCI_ANY_ID, PCI_ANY_ID, },
286 { PCI_VENDOR_ID_AMD, 0x7468 }, /* amd8111 support */ 284 { PCI_VENDOR_ID_AMD, 0x7468 }, /* amd8111 support */
287 { 0, } 285 { 0, }
diff --git a/drivers/mtd/maps/arctic-mtd.c b/drivers/mtd/maps/arctic-mtd.c
index 777276fd0e15..d95ae582fbe9 100644
--- a/drivers/mtd/maps/arctic-mtd.c
+++ b/drivers/mtd/maps/arctic-mtd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * $Id: arctic-mtd.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: arctic-mtd.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for 4 * drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for
5 * IBM 405LP Arctic boards. 5 * IBM 405LP Arctic boards.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/mtd/maps/autcpu12-nvram.c b/drivers/mtd/maps/autcpu12-nvram.c
index cf362ccc3c8e..7ed3424dd959 100644
--- a/drivers/mtd/maps/autcpu12-nvram.c
+++ b/drivers/mtd/maps/autcpu12-nvram.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * NV-RAM memory access on autcpu12 2 * NV-RAM memory access on autcpu12
3 * (C) 2002 Thomas Gleixner (gleixner@autronix.de) 3 * (C) 2002 Thomas Gleixner (gleixner@autronix.de)
4 * 4 *
5 * $Id: autcpu12-nvram.c,v 1.8 2004/11/04 13:24:14 gleixner Exp $ 5 * $Id: autcpu12-nvram.c,v 1.9 2005/11/07 11:14:26 gleixner Exp $
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -55,10 +55,10 @@ static int __init init_autcpu12_sram (void)
55 } 55 }
56 simple_map_init(&autcpu_sram_map); 56 simple_map_init(&autcpu_sram_map);
57 57
58 /* 58 /*
59 * Check for 32K/128K 59 * Check for 32K/128K
60 * read ofs 0 60 * read ofs 0
61 * read ofs 0x10000 61 * read ofs 0x10000
62 * Write complement to ofs 0x100000 62 * Write complement to ofs 0x100000
63 * Read and check result on ofs 0x0 63 * Read and check result on ofs 0x0
64 * Restore contents 64 * Restore contents
@@ -66,7 +66,7 @@ static int __init init_autcpu12_sram (void)
66 save0 = map_read32(&autcpu12_sram_map,0); 66 save0 = map_read32(&autcpu12_sram_map,0);
67 save1 = map_read32(&autcpu12_sram_map,0x10000); 67 save1 = map_read32(&autcpu12_sram_map,0x10000);
68 map_write32(&autcpu12_sram_map,~save0,0x10000); 68 map_write32(&autcpu12_sram_map,~save0,0x10000);
69 /* if we find this pattern on 0x0, we have 32K size 69 /* if we find this pattern on 0x0, we have 32K size
70 * restore contents and exit 70 * restore contents and exit
71 */ 71 */
72 if ( map_read32(&autcpu12_sram_map,0) != save0) { 72 if ( map_read32(&autcpu12_sram_map,0) != save0) {
@@ -89,7 +89,7 @@ map:
89 89
90 sram_mtd->owner = THIS_MODULE; 90 sram_mtd->owner = THIS_MODULE;
91 sram_mtd->erasesize = 16; 91 sram_mtd->erasesize = 16;
92 92
93 if (add_mtd_device(sram_mtd)) { 93 if (add_mtd_device(sram_mtd)) {
94 printk("NV-RAM device addition failed\n"); 94 printk("NV-RAM device addition failed\n");
95 err = -ENOMEM; 95 err = -ENOMEM;
@@ -97,7 +97,7 @@ map:
97 } 97 }
98 98
99 printk("NV-RAM device size %ldKiB registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K); 99 printk("NV-RAM device size %ldKiB registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K);
100 100
101 return 0; 101 return 0;
102 102
103out_probe: 103out_probe:
diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c
index bfe994e59265..b7858eb93534 100644
--- a/drivers/mtd/maps/bast-flash.c
+++ b/drivers/mtd/maps/bast-flash.c
@@ -9,7 +9,7 @@
9 * 20-Sep-2004 BJD Initial version 9 * 20-Sep-2004 BJD Initial version
10 * 17-Jan-2005 BJD Add whole device if no partitions found 10 * 17-Jan-2005 BJD Add whole device if no partitions found
11 * 11 *
12 * $Id: bast-flash.c,v 1.2 2005/01/18 11:13:47 bjd Exp $ 12 * $Id: bast-flash.c,v 1.5 2005/11/07 11:14:26 gleixner Exp $
13 * 13 *
14 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
@@ -75,7 +75,7 @@ static void bast_flash_setrw(int to)
75 75
76 local_irq_save(flags); 76 local_irq_save(flags);
77 val = __raw_readb(BAST_VA_CTRL3); 77 val = __raw_readb(BAST_VA_CTRL3);
78 78
79 if (to) 79 if (to)
80 val |= BAST_CPLD_CTRL3_ROMWEN; 80 val |= BAST_CPLD_CTRL3_ROMWEN;
81 else 81 else
@@ -93,7 +93,7 @@ static int bast_flash_remove(struct device *dev)
93 93
94 dev_set_drvdata(dev, NULL); 94 dev_set_drvdata(dev, NULL);
95 95
96 if (info == NULL) 96 if (info == NULL)
97 return 0; 97 return 0;
98 98
99 if (info->map.virt != NULL) 99 if (info->map.virt != NULL)
@@ -104,14 +104,13 @@ static int bast_flash_remove(struct device *dev)
104 map_destroy(info->mtd); 104 map_destroy(info->mtd);
105 } 105 }
106 106
107 if (info->partitions) 107 kfree(info->partitions);
108 kfree(info->partitions);
109 108
110 if (info->area) { 109 if (info->area) {
111 release_resource(info->area); 110 release_resource(info->area);
112 kfree(info->area); 111 kfree(info->area);
113 } 112 }
114 113
115 kfree(info); 114 kfree(info);
116 115
117 return 0; 116 return 0;
@@ -138,15 +137,15 @@ static int bast_flash_probe(struct device *dev)
138 137
139 info->map.phys = res->start; 138 info->map.phys = res->start;
140 info->map.size = res->end - res->start + 1; 139 info->map.size = res->end - res->start + 1;
141 info->map.name = dev->bus_id; 140 info->map.name = dev->bus_id;
142 info->map.bankwidth = 2; 141 info->map.bankwidth = 2;
143 142
144 if (info->map.size > AREA_MAXSIZE) 143 if (info->map.size > AREA_MAXSIZE)
145 info->map.size = AREA_MAXSIZE; 144 info->map.size = AREA_MAXSIZE;
146 145
147 pr_debug("%s: area %08lx, size %ld\n", __FUNCTION__, 146 pr_debug("%s: area %08lx, size %ld\n", __FUNCTION__,
148 info->map.phys, info->map.size); 147 info->map.phys, info->map.size);
149 148
150 info->area = request_mem_region(res->start, info->map.size, 149 info->area = request_mem_region(res->start, info->map.size,
151 pdev->name); 150 pdev->name);
152 if (info->area == NULL) { 151 if (info->area == NULL) {
@@ -163,7 +162,7 @@ static int bast_flash_probe(struct device *dev)
163 err = -EIO; 162 err = -EIO;
164 goto exit_error; 163 goto exit_error;
165 } 164 }
166 165
167 simple_map_init(&info->map); 166 simple_map_init(&info->map);
168 167
169 /* enable the write to the flash area */ 168 /* enable the write to the flash area */
@@ -188,7 +187,7 @@ static int bast_flash_probe(struct device *dev)
188 err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0); 187 err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0);
189 if (err > 0) { 188 if (err > 0) {
190 err = add_mtd_partitions(info->mtd, info->partitions, err); 189 err = add_mtd_partitions(info->mtd, info->partitions, err);
191 if (err) 190 if (err)
192 printk(KERN_ERR PFX "cannot add/parse partitions\n"); 191 printk(KERN_ERR PFX "cannot add/parse partitions\n");
193 } else { 192 } else {
194 err = add_mtd_device(info->mtd); 193 err = add_mtd_device(info->mtd);
@@ -206,6 +205,7 @@ static int bast_flash_probe(struct device *dev)
206 205
207static struct device_driver bast_flash_driver = { 206static struct device_driver bast_flash_driver = {
208 .name = "bast-nor", 207 .name = "bast-nor",
208 .owner = THIS_MODULE,
209 .bus = &platform_bus_type, 209 .bus = &platform_bus_type,
210 .probe = bast_flash_probe, 210 .probe = bast_flash_probe,
211 .remove = bast_flash_remove, 211 .remove = bast_flash_remove,
diff --git a/drivers/mtd/maps/beech-mtd.c b/drivers/mtd/maps/beech-mtd.c
index 5e79c9d5da2b..5df7361d1407 100644
--- a/drivers/mtd/maps/beech-mtd.c
+++ b/drivers/mtd/maps/beech-mtd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * $Id: beech-mtd.c,v 1.10 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: beech-mtd.c,v 1.11 2005/11/07 11:14:26 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/beech-mtd.c MTD mappings and partition tables for 4 * drivers/mtd/maps/beech-mtd.c MTD mappings and partition tables for
5 * IBM 405LP Beech boards. 5 * IBM 405LP Beech boards.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/mtd/maps/cdb89712.c b/drivers/mtd/maps/cdb89712.c
index ab15dac2f936..9f17bb6c5a9d 100644
--- a/drivers/mtd/maps/cdb89712.c
+++ b/drivers/mtd/maps/cdb89712.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Flash on Cirrus CDB89712 2 * Flash on Cirrus CDB89712
3 * 3 *
4 * $Id: cdb89712.c,v 1.10 2004/11/04 13:24:14 gleixner Exp $ 4 * $Id: cdb89712.c,v 1.11 2005/11/07 11:14:26 gleixner Exp $
5 */ 5 */
6 6
7#include <linux/module.h> 7#include <linux/module.h>
@@ -37,13 +37,13 @@ struct resource cdb89712_flash_resource = {
37static int __init init_cdb89712_flash (void) 37static int __init init_cdb89712_flash (void)
38{ 38{
39 int err; 39 int err;
40 40
41 if (request_resource (&ioport_resource, &cdb89712_flash_resource)) { 41 if (request_resource (&ioport_resource, &cdb89712_flash_resource)) {
42 printk(KERN_NOTICE "Failed to reserve Cdb89712 FLASH space\n"); 42 printk(KERN_NOTICE "Failed to reserve Cdb89712 FLASH space\n");
43 err = -EBUSY; 43 err = -EBUSY;
44 goto out; 44 goto out;
45 } 45 }
46 46
47 cdb89712_flash_map.virt = ioremap(FLASH_START, FLASH_SIZE); 47 cdb89712_flash_map.virt = ioremap(FLASH_START, FLASH_SIZE);
48 if (!cdb89712_flash_map.virt) { 48 if (!cdb89712_flash_map.virt) {
49 printk(KERN_NOTICE "Failed to ioremap Cdb89712 FLASH space\n"); 49 printk(KERN_NOTICE "Failed to ioremap Cdb89712 FLASH space\n");
@@ -64,13 +64,13 @@ static int __init init_cdb89712_flash (void)
64 } 64 }
65 65
66 flash_mtd->owner = THIS_MODULE; 66 flash_mtd->owner = THIS_MODULE;
67 67
68 if (add_mtd_device(flash_mtd)) { 68 if (add_mtd_device(flash_mtd)) {
69 printk("FLASH device addition failed\n"); 69 printk("FLASH device addition failed\n");
70 err = -ENOMEM; 70 err = -ENOMEM;
71 goto out_probe; 71 goto out_probe;
72 } 72 }
73 73
74 return 0; 74 return 0;
75 75
76out_probe: 76out_probe:
@@ -107,13 +107,13 @@ struct resource cdb89712_sram_resource = {
107static int __init init_cdb89712_sram (void) 107static int __init init_cdb89712_sram (void)
108{ 108{
109 int err; 109 int err;
110 110
111 if (request_resource (&ioport_resource, &cdb89712_sram_resource)) { 111 if (request_resource (&ioport_resource, &cdb89712_sram_resource)) {
112 printk(KERN_NOTICE "Failed to reserve Cdb89712 SRAM space\n"); 112 printk(KERN_NOTICE "Failed to reserve Cdb89712 SRAM space\n");
113 err = -EBUSY; 113 err = -EBUSY;
114 goto out; 114 goto out;
115 } 115 }
116 116
117 cdb89712_sram_map.virt = ioremap(SRAM_START, SRAM_SIZE); 117 cdb89712_sram_map.virt = ioremap(SRAM_START, SRAM_SIZE);
118 if (!cdb89712_sram_map.virt) { 118 if (!cdb89712_sram_map.virt) {
119 printk(KERN_NOTICE "Failed to ioremap Cdb89712 SRAM space\n"); 119 printk(KERN_NOTICE "Failed to ioremap Cdb89712 SRAM space\n");
@@ -130,13 +130,13 @@ static int __init init_cdb89712_sram (void)
130 130
131 sram_mtd->owner = THIS_MODULE; 131 sram_mtd->owner = THIS_MODULE;
132 sram_mtd->erasesize = 16; 132 sram_mtd->erasesize = 16;
133 133
134 if (add_mtd_device(sram_mtd)) { 134 if (add_mtd_device(sram_mtd)) {
135 printk("SRAM device addition failed\n"); 135 printk("SRAM device addition failed\n");
136 err = -ENOMEM; 136 err = -ENOMEM;
137 goto out_probe; 137 goto out_probe;
138 } 138 }
139 139
140 return 0; 140 return 0;
141 141
142out_probe: 142out_probe:
@@ -175,13 +175,13 @@ struct resource cdb89712_bootrom_resource = {
175static int __init init_cdb89712_bootrom (void) 175static int __init init_cdb89712_bootrom (void)
176{ 176{
177 int err; 177 int err;
178 178
179 if (request_resource (&ioport_resource, &cdb89712_bootrom_resource)) { 179 if (request_resource (&ioport_resource, &cdb89712_bootrom_resource)) {
180 printk(KERN_NOTICE "Failed to reserve Cdb89712 BOOTROM space\n"); 180 printk(KERN_NOTICE "Failed to reserve Cdb89712 BOOTROM space\n");
181 err = -EBUSY; 181 err = -EBUSY;
182 goto out; 182 goto out;
183 } 183 }
184 184
185 cdb89712_bootrom_map.virt = ioremap(BOOTROM_START, BOOTROM_SIZE); 185 cdb89712_bootrom_map.virt = ioremap(BOOTROM_START, BOOTROM_SIZE);
186 if (!cdb89712_bootrom_map.virt) { 186 if (!cdb89712_bootrom_map.virt) {
187 printk(KERN_NOTICE "Failed to ioremap Cdb89712 BootROM space\n"); 187 printk(KERN_NOTICE "Failed to ioremap Cdb89712 BootROM space\n");
@@ -198,13 +198,13 @@ static int __init init_cdb89712_bootrom (void)
198 198
199 bootrom_mtd->owner = THIS_MODULE; 199 bootrom_mtd->owner = THIS_MODULE;
200 bootrom_mtd->erasesize = 0x10000; 200 bootrom_mtd->erasesize = 0x10000;
201 201
202 if (add_mtd_device(bootrom_mtd)) { 202 if (add_mtd_device(bootrom_mtd)) {
203 printk("BootROM device addition failed\n"); 203 printk("BootROM device addition failed\n");
204 err = -ENOMEM; 204 err = -ENOMEM;
205 goto out_probe; 205 goto out_probe;
206 } 206 }
207 207
208 return 0; 208 return 0;
209 209
210out_probe: 210out_probe:
@@ -225,16 +225,16 @@ out:
225static int __init init_cdb89712_maps(void) 225static int __init init_cdb89712_maps(void)
226{ 226{
227 227
228 printk(KERN_INFO "Cirrus CDB89712 MTD mappings:\n Flash 0x%x at 0x%x\n SRAM 0x%x at 0x%x\n BootROM 0x%x at 0x%x\n", 228 printk(KERN_INFO "Cirrus CDB89712 MTD mappings:\n Flash 0x%x at 0x%x\n SRAM 0x%x at 0x%x\n BootROM 0x%x at 0x%x\n",
229 FLASH_SIZE, FLASH_START, SRAM_SIZE, SRAM_START, BOOTROM_SIZE, BOOTROM_START); 229 FLASH_SIZE, FLASH_START, SRAM_SIZE, SRAM_START, BOOTROM_SIZE, BOOTROM_START);
230 230
231 init_cdb89712_flash(); 231 init_cdb89712_flash();
232 init_cdb89712_sram(); 232 init_cdb89712_sram();
233 init_cdb89712_bootrom(); 233 init_cdb89712_bootrom();
234 234
235 return 0; 235 return 0;
236} 236}
237 237
238 238
239static void __exit cleanup_cdb89712_maps(void) 239static void __exit cleanup_cdb89712_maps(void)
240{ 240{
@@ -244,7 +244,7 @@ static void __exit cleanup_cdb89712_maps(void)
244 iounmap((void *)cdb89712_sram_map.virt); 244 iounmap((void *)cdb89712_sram_map.virt);
245 release_resource (&cdb89712_sram_resource); 245 release_resource (&cdb89712_sram_resource);
246 } 246 }
247 247
248 if (flash_mtd) { 248 if (flash_mtd) {
249 del_mtd_device(flash_mtd); 249 del_mtd_device(flash_mtd);
250 map_destroy(flash_mtd); 250 map_destroy(flash_mtd);
diff --git a/drivers/mtd/maps/ceiva.c b/drivers/mtd/maps/ceiva.c
index c68b31dc7e6d..5a95ab370a97 100644
--- a/drivers/mtd/maps/ceiva.c
+++ b/drivers/mtd/maps/ceiva.c
@@ -313,8 +313,7 @@ static void __init clps_locate_partitions(struct mtd_info *mtd)
313 313
314static void __exit clps_destroy_partitions(void) 314static void __exit clps_destroy_partitions(void)
315{ 315{
316 if (parsed_parts) 316 kfree(parsed_parts);
317 kfree(parsed_parts);
318} 317}
319 318
320static struct mtd_info *mymtd; 319static struct mtd_info *mymtd;
diff --git a/drivers/mtd/maps/cfi_flagadm.c b/drivers/mtd/maps/cfi_flagadm.c
index f72e4f894b32..6a8c0415bde8 100644
--- a/drivers/mtd/maps/cfi_flagadm.c
+++ b/drivers/mtd/maps/cfi_flagadm.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is> 2 * Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is>
3 * 3 *
4 * $Id: cfi_flagadm.c,v 1.14 2004/11/04 13:24:14 gleixner Exp $ 4 * $Id: cfi_flagadm.c,v 1.15 2005/11/07 11:14:26 gleixner Exp $
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the 7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your 8 * Free Software Foundation; either version 2 of the License, or (at your
@@ -42,7 +42,7 @@
42 */ 42 */
43 43
44#define FLASH_PHYS_ADDR 0x40000000 44#define FLASH_PHYS_ADDR 0x40000000
45#define FLASH_SIZE 0x400000 45#define FLASH_SIZE 0x400000
46 46
47#define FLASH_PARTITION0_ADDR 0x00000000 47#define FLASH_PARTITION0_ADDR 0x00000000
48#define FLASH_PARTITION0_SIZE 0x00020000 48#define FLASH_PARTITION0_SIZE 0x00020000
@@ -79,7 +79,7 @@ struct mtd_partition flagadm_parts[] = {
79 .offset = FLASH_PARTITION2_ADDR, 79 .offset = FLASH_PARTITION2_ADDR,
80 .size = FLASH_PARTITION2_SIZE 80 .size = FLASH_PARTITION2_SIZE
81 }, 81 },
82 { 82 {
83 .name = "Persistant storage", 83 .name = "Persistant storage",
84 .offset = FLASH_PARTITION3_ADDR, 84 .offset = FLASH_PARTITION3_ADDR,
85 .size = FLASH_PARTITION3_SIZE 85 .size = FLASH_PARTITION3_SIZE
@@ -91,10 +91,10 @@ struct mtd_partition flagadm_parts[] = {
91static struct mtd_info *mymtd; 91static struct mtd_info *mymtd;
92 92
93int __init init_flagadm(void) 93int __init init_flagadm(void)
94{ 94{
95 printk(KERN_NOTICE "FlagaDM flash device: %x at %x\n", 95 printk(KERN_NOTICE "FlagaDM flash device: %x at %x\n",
96 FLASH_SIZE, FLASH_PHYS_ADDR); 96 FLASH_SIZE, FLASH_PHYS_ADDR);
97 97
98 flagadm_map.phys = FLASH_PHYS_ADDR; 98 flagadm_map.phys = FLASH_PHYS_ADDR;
99 flagadm_map.virt = ioremap(FLASH_PHYS_ADDR, 99 flagadm_map.virt = ioremap(FLASH_PHYS_ADDR,
100 FLASH_SIZE); 100 FLASH_SIZE);
diff --git a/drivers/mtd/maps/cstm_mips_ixx.c b/drivers/mtd/maps/cstm_mips_ixx.c
index ae9252fbf176..a370953c1513 100644
--- a/drivers/mtd/maps/cstm_mips_ixx.c
+++ b/drivers/mtd/maps/cstm_mips_ixx.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * $Id: cstm_mips_ixx.c,v 1.12 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: cstm_mips_ixx.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
3 * 3 *
4 * Mapping of a custom board with both AMD CFI and JEDEC flash in partitions. 4 * Mapping of a custom board with both AMD CFI and JEDEC flash in partitions.
5 * Config with both CFI and JEDEC device support. 5 * Config with both CFI and JEDEC device support.
6 * 6 *
7 * Basically physmap.c with the addition of partitions and 7 * Basically physmap.c with the addition of partitions and
8 * an array of mapping info to accomodate more than one flash type per board. 8 * an array of mapping info to accomodate more than one flash type per board.
9 * 9 *
10 * Copyright 2000 MontaVista Software Inc. 10 * Copyright 2000 MontaVista Software Inc.
@@ -69,7 +69,7 @@ void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp)
69 __u16 data; 69 __u16 data;
70 __u8 data1; 70 __u8 data1;
71 static u8 first = 1; 71 static u8 first = 1;
72 72
73 // Set GPIO port B pin3 to high 73 // Set GPIO port B pin3 to high
74 data = *(__u16 *)(CC_GPBCR); 74 data = *(__u16 *)(CC_GPBCR);
75 data = (data & 0xff0f) | 0x0040; 75 data = (data & 0xff0f) | 0x0040;
@@ -85,7 +85,7 @@ void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp)
85 } else { 85 } else {
86 if (!--vpp_count) { 86 if (!--vpp_count) {
87 __u16 data; 87 __u16 data;
88 88
89 // Set GPIO port B pin3 to high 89 // Set GPIO port B pin3 to high
90 data = *(__u16 *)(CC_GPBCR); 90 data = *(__u16 *)(CC_GPBCR);
91 data = (data & 0xff3f) | 0x0040; 91 data = (data & 0xff3f) | 0x0040;
@@ -109,8 +109,8 @@ struct cstm_mips_ixx_info {
109}; 109};
110 110
111#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) 111#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
112#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type 112#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type
113const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] = 113const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
114{ 114{
115 { // 28F128J3A in 2x16 configuration 115 { // 28F128J3A in 2x16 configuration
116 "big flash", // name 116 "big flash", // name
@@ -131,10 +131,10 @@ static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP
131}, 131},
132}; 132};
133#else /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */ 133#else /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
134#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type 134#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type
135const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] = 135const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
136{ 136{
137 { 137 {
138 "MTD flash", // name 138 "MTD flash", // name
139 CONFIG_MTD_CSTM_MIPS_IXX_START, // window_addr 139 CONFIG_MTD_CSTM_MIPS_IXX_START, // window_addr
140 CONFIG_MTD_CSTM_MIPS_IXX_LEN, // window_size 140 CONFIG_MTD_CSTM_MIPS_IXX_LEN, // window_size
@@ -144,7 +144,7 @@ const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
144 144
145}; 145};
146static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = { 146static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {
147{ 147{
148 { 148 {
149 .name = "main partition", 149 .name = "main partition",
150 .size = CONFIG_MTD_CSTM_MIPS_IXX_LEN, 150 .size = CONFIG_MTD_CSTM_MIPS_IXX_LEN,
@@ -165,7 +165,7 @@ int __init init_cstm_mips_ixx(void)
165 165
166 /* Initialize mapping */ 166 /* Initialize mapping */
167 for (i=0;i<PHYSMAP_NUMBER;i++) { 167 for (i=0;i<PHYSMAP_NUMBER;i++) {
168 printk(KERN_NOTICE "cstm_mips_ixx flash device: 0x%lx at 0x%lx\n", 168 printk(KERN_NOTICE "cstm_mips_ixx flash device: 0x%lx at 0x%lx\n",
169 cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr); 169 cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr);
170 170
171 171
@@ -235,7 +235,7 @@ void PCISetULongByOffset(__u32 DevNumber, __u32 FuncNumber, __u32 Offset, __u32
235 235
236 offset = ( unsigned long )( 0x80000000 | ( DevNumber << 11 ) + ( FuncNumber << 8 ) + Offset) ; 236 offset = ( unsigned long )( 0x80000000 | ( DevNumber << 11 ) + ( FuncNumber << 8 ) + Offset) ;
237 237
238 *(__u32 *)CC_CONFADDR = offset; 238 *(__u32 *)CC_CONFADDR = offset;
239 *(__u32 *)CC_CONFDATA = data; 239 *(__u32 *)CC_CONFDATA = data;
240} 240}
241void setup_ITE_IVR_flash() 241void setup_ITE_IVR_flash()
diff --git a/drivers/mtd/maps/dbox2-flash.c b/drivers/mtd/maps/dbox2-flash.c
index d850a27a4b59..49d90542fc75 100644
--- a/drivers/mtd/maps/dbox2-flash.c
+++ b/drivers/mtd/maps/dbox2-flash.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: dbox2-flash.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: dbox2-flash.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
3 * 3 *
4 * D-Box 2 flash driver 4 * D-Box 2 flash driver
5 */ 5 */
@@ -21,38 +21,38 @@
21static struct mtd_partition partition_info[]= { 21static struct mtd_partition partition_info[]= {
22 { 22 {
23 .name = "BR bootloader", 23 .name = "BR bootloader",
24 .size = 128 * 1024, 24 .size = 128 * 1024,
25 .offset = 0, 25 .offset = 0,
26 .mask_flags = MTD_WRITEABLE 26 .mask_flags = MTD_WRITEABLE
27 }, 27 },
28 { 28 {
29 .name = "FLFS (U-Boot)", 29 .name = "FLFS (U-Boot)",
30 .size = 128 * 1024, 30 .size = 128 * 1024,
31 .offset = MTDPART_OFS_APPEND, 31 .offset = MTDPART_OFS_APPEND,
32 .mask_flags = 0 32 .mask_flags = 0
33 }, 33 },
34 { 34 {
35 .name = "Root (SquashFS)", 35 .name = "Root (SquashFS)",
36 .size = 7040 * 1024, 36 .size = 7040 * 1024,
37 .offset = MTDPART_OFS_APPEND, 37 .offset = MTDPART_OFS_APPEND,
38 .mask_flags = 0 38 .mask_flags = 0
39 }, 39 },
40 { 40 {
41 .name = "var (JFFS2)", 41 .name = "var (JFFS2)",
42 .size = 896 * 1024, 42 .size = 896 * 1024,
43 .offset = MTDPART_OFS_APPEND, 43 .offset = MTDPART_OFS_APPEND,
44 .mask_flags = 0 44 .mask_flags = 0
45 }, 45 },
46 { 46 {
47 .name = "Flash without bootloader", 47 .name = "Flash without bootloader",
48 .size = MTDPART_SIZ_FULL, 48 .size = MTDPART_SIZ_FULL,
49 .offset = 128 * 1024, 49 .offset = 128 * 1024,
50 .mask_flags = 0 50 .mask_flags = 0
51 }, 51 },
52 { 52 {
53 .name = "Complete Flash", 53 .name = "Complete Flash",
54 .size = MTDPART_SIZ_FULL, 54 .size = MTDPART_SIZ_FULL,
55 .offset = 0, 55 .offset = 0,
56 .mask_flags = MTD_WRITEABLE 56 .mask_flags = MTD_WRITEABLE
57 } 57 }
58}; 58};
@@ -88,16 +88,16 @@ int __init init_dbox2_flash(void)
88 if (!mymtd) { 88 if (!mymtd) {
89 // Probe for single Intel 28F640 89 // Probe for single Intel 28F640
90 dbox2_flash_map.bankwidth = 2; 90 dbox2_flash_map.bankwidth = 2;
91 91
92 mymtd = do_map_probe("cfi_probe", &dbox2_flash_map); 92 mymtd = do_map_probe("cfi_probe", &dbox2_flash_map);
93 } 93 }
94 94
95 if (mymtd) { 95 if (mymtd) {
96 mymtd->owner = THIS_MODULE; 96 mymtd->owner = THIS_MODULE;
97 97
98 /* Create MTD devices for each partition. */ 98 /* Create MTD devices for each partition. */
99 add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS); 99 add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
100 100
101 return 0; 101 return 0;
102 } 102 }
103 103
diff --git a/drivers/mtd/maps/dc21285.c b/drivers/mtd/maps/dc21285.c
index e5b74169fde6..701620b6baed 100644
--- a/drivers/mtd/maps/dc21285.c
+++ b/drivers/mtd/maps/dc21285.c
@@ -4,8 +4,8 @@
4 * (C) 2000 Nicolas Pitre <nico@cam.org> 4 * (C) 2000 Nicolas Pitre <nico@cam.org>
5 * 5 *
6 * This code is GPL 6 * This code is GPL
7 * 7 *
8 * $Id: dc21285.c,v 1.22 2004/11/01 13:39:21 rmk Exp $ 8 * $Id: dc21285.c,v 1.24 2005/11/07 11:14:26 gleixner Exp $
9 */ 9 */
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/module.h> 11#include <linux/module.h>
@@ -27,9 +27,9 @@
27static struct mtd_info *dc21285_mtd; 27static struct mtd_info *dc21285_mtd;
28 28
29#ifdef CONFIG_ARCH_NETWINDER 29#ifdef CONFIG_ARCH_NETWINDER
30/* 30/*
31 * This is really ugly, but it seams to be the only 31 * This is really ugly, but it seams to be the only
32 * realiable way to do it, as the cpld state machine 32 * realiable way to do it, as the cpld state machine
33 * is unpredictible. So we have a 25us penalty per 33 * is unpredictible. So we have a 25us penalty per
34 * write access. 34 * write access.
35 */ 35 */
@@ -150,7 +150,7 @@ static struct map_info dc21285_map = {
150static struct mtd_partition *dc21285_parts; 150static struct mtd_partition *dc21285_parts;
151static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; 151static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
152#endif 152#endif
153 153
154static int __init init_dc21285(void) 154static int __init init_dc21285(void)
155{ 155{
156 156
@@ -160,20 +160,20 @@ static int __init init_dc21285(void)
160 160
161 /* Determine bankwidth */ 161 /* Determine bankwidth */
162 switch (*CSR_SA110_CNTL & (3<<14)) { 162 switch (*CSR_SA110_CNTL & (3<<14)) {
163 case SA110_CNTL_ROMWIDTH_8: 163 case SA110_CNTL_ROMWIDTH_8:
164 dc21285_map.bankwidth = 1; 164 dc21285_map.bankwidth = 1;
165 dc21285_map.read = dc21285_read8; 165 dc21285_map.read = dc21285_read8;
166 dc21285_map.write = dc21285_write8; 166 dc21285_map.write = dc21285_write8;
167 dc21285_map.copy_to = dc21285_copy_to_8; 167 dc21285_map.copy_to = dc21285_copy_to_8;
168 break; 168 break;
169 case SA110_CNTL_ROMWIDTH_16: 169 case SA110_CNTL_ROMWIDTH_16:
170 dc21285_map.bankwidth = 2; 170 dc21285_map.bankwidth = 2;
171 dc21285_map.read = dc21285_read16; 171 dc21285_map.read = dc21285_read16;
172 dc21285_map.write = dc21285_write16; 172 dc21285_map.write = dc21285_write16;
173 dc21285_map.copy_to = dc21285_copy_to_16; 173 dc21285_map.copy_to = dc21285_copy_to_16;
174 break; 174 break;
175 case SA110_CNTL_ROMWIDTH_32: 175 case SA110_CNTL_ROMWIDTH_32:
176 dc21285_map.bankwidth = 4; 176 dc21285_map.bankwidth = 4;
177 dc21285_map.read = dc21285_read32; 177 dc21285_map.read = dc21285_read32;
178 dc21285_map.write = dc21285_write32; 178 dc21285_map.write = dc21285_write32;
179 dc21285_map.copy_to = dc21285_copy_to_32; 179 dc21285_map.copy_to = dc21285_copy_to_32;
@@ -201,20 +201,20 @@ static int __init init_dc21285(void)
201 if (!dc21285_mtd) { 201 if (!dc21285_mtd) {
202 iounmap(dc21285_map.virt); 202 iounmap(dc21285_map.virt);
203 return -ENXIO; 203 return -ENXIO;
204 } 204 }
205 205
206 dc21285_mtd->owner = THIS_MODULE; 206 dc21285_mtd->owner = THIS_MODULE;
207 207
208#ifdef CONFIG_MTD_PARTITIONS 208#ifdef CONFIG_MTD_PARTITIONS
209 nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0); 209 nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0);
210 if (nrparts > 0) 210 if (nrparts > 0)
211 add_mtd_partitions(dc21285_mtd, dc21285_parts, nrparts); 211 add_mtd_partitions(dc21285_mtd, dc21285_parts, nrparts);
212 else 212 else
213#endif 213#endif
214 add_mtd_device(dc21285_mtd); 214 add_mtd_device(dc21285_mtd);
215 215
216 if(machine_is_ebsa285()) { 216 if(machine_is_ebsa285()) {
217 /* 217 /*
218 * Flash timing is determined with bits 19-16 of the 218 * Flash timing is determined with bits 19-16 of the
219 * CSR_SA110_CNTL. The value is the number of wait cycles, or 219 * CSR_SA110_CNTL. The value is the number of wait cycles, or
220 * 0 for 16 cycles (the default). Cycles are 20 ns. 220 * 0 for 16 cycles (the default). Cycles are 20 ns.
@@ -227,7 +227,7 @@ static int __init init_dc21285(void)
227 /* tristate time */ 227 /* tristate time */
228 *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24)); 228 *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24));
229 } 229 }
230 230
231 return 0; 231 return 0;
232} 232}
233 233
diff --git a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c
index f99519692cb7..b51c757817d8 100644
--- a/drivers/mtd/maps/dilnetpc.c
+++ b/drivers/mtd/maps/dilnetpc.c
@@ -14,7 +14,7 @@
14 * along with this program; if not, write to the Free Software 14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
16 * 16 *
17 * $Id: dilnetpc.c,v 1.17 2004/11/28 09:40:39 dwmw2 Exp $ 17 * $Id: dilnetpc.c,v 1.20 2005/11/07 11:14:26 gleixner Exp $
18 * 18 *
19 * The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems 19 * The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems
20 * featuring the AMD Elan SC410 processor. There are two variants of this 20 * featuring the AMD Elan SC410 processor. There are two variants of this
@@ -272,13 +272,13 @@ static struct map_info dnpc_map = {
272 272
273static struct mtd_partition partition_info[]= 273static struct mtd_partition partition_info[]=
274{ 274{
275 { 275 {
276 .name = "ADNP boot", 276 .name = "ADNP boot",
277 .offset = 0, 277 .offset = 0,
278 .size = 0xf0000, 278 .size = 0xf0000,
279 }, 279 },
280 { 280 {
281 .name = "ADNP system BIOS", 281 .name = "ADNP system BIOS",
282 .offset = MTDPART_OFS_NXTBLK, 282 .offset = MTDPART_OFS_NXTBLK,
283 .size = 0x10000, 283 .size = 0x10000,
284#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED 284#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
@@ -291,7 +291,7 @@ static struct mtd_partition partition_info[]=
291 .size = 0x2f0000, 291 .size = 0x2f0000,
292 }, 292 },
293 { 293 {
294 .name = "ADNP system BIOS entry", 294 .name = "ADNP system BIOS entry",
295 .offset = MTDPART_OFS_NXTBLK, 295 .offset = MTDPART_OFS_NXTBLK,
296 .size = MTDPART_SIZ_FULL, 296 .size = MTDPART_SIZ_FULL,
297#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED 297#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
@@ -325,9 +325,9 @@ static struct mtd_info *merged_mtd;
325 325
326static struct mtd_partition higlvl_partition_info[]= 326static struct mtd_partition higlvl_partition_info[]=
327{ 327{
328 { 328 {
329 .name = "ADNP boot block", 329 .name = "ADNP boot block",
330 .offset = 0, 330 .offset = 0,
331 .size = CONFIG_MTD_DILNETPC_BOOTSIZE, 331 .size = CONFIG_MTD_DILNETPC_BOOTSIZE,
332 }, 332 },
333 { 333 {
@@ -335,8 +335,8 @@ static struct mtd_partition higlvl_partition_info[]=
335 .offset = MTDPART_OFS_NXTBLK, 335 .offset = MTDPART_OFS_NXTBLK,
336 .size = ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000, 336 .size = ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000,
337 }, 337 },
338 { 338 {
339 .name = "ADNP system BIOS + BIOS Entry", 339 .name = "ADNP system BIOS + BIOS Entry",
340 .offset = MTDPART_OFS_NXTBLK, 340 .offset = MTDPART_OFS_NXTBLK,
341 .size = MTDPART_SIZ_FULL, 341 .size = MTDPART_SIZ_FULL,
342#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED 342#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
@@ -371,7 +371,7 @@ static int __init init_dnpc(void)
371 371
372 /* 372 /*
373 ** determine hardware (DNP/ADNP/invalid) 373 ** determine hardware (DNP/ADNP/invalid)
374 */ 374 */
375 if((is_dnp = dnp_adnp_probe()) < 0) 375 if((is_dnp = dnp_adnp_probe()) < 0)
376 return -ENXIO; 376 return -ENXIO;
377 377
@@ -397,13 +397,13 @@ static int __init init_dnpc(void)
397 ++dnpc_map.name; 397 ++dnpc_map.name;
398 for(i = 0; i < NUM_PARTITIONS; i++) 398 for(i = 0; i < NUM_PARTITIONS; i++)
399 ++partition_info[i].name; 399 ++partition_info[i].name;
400 higlvl_partition_info[1].size = DNP_WINDOW_SIZE - 400 higlvl_partition_info[1].size = DNP_WINDOW_SIZE -
401 CONFIG_MTD_DILNETPC_BOOTSIZE - 0x20000; 401 CONFIG_MTD_DILNETPC_BOOTSIZE - 0x20000;
402 for(i = 0; i < NUM_HIGHLVL_PARTITIONS; i++) 402 for(i = 0; i < NUM_HIGHLVL_PARTITIONS; i++)
403 ++higlvl_partition_info[i].name; 403 ++higlvl_partition_info[i].name;
404 } 404 }
405 405
406 printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n", 406 printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n",
407 is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.phys); 407 is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.phys);
408 408
409 dnpc_map.virt = ioremap_nocache(dnpc_map.phys, dnpc_map.size); 409 dnpc_map.virt = ioremap_nocache(dnpc_map.phys, dnpc_map.size);
@@ -436,7 +436,7 @@ static int __init init_dnpc(void)
436 iounmap(dnpc_map.virt); 436 iounmap(dnpc_map.virt);
437 return -ENXIO; 437 return -ENXIO;
438 } 438 }
439 439
440 mymtd->owner = THIS_MODULE; 440 mymtd->owner = THIS_MODULE;
441 441
442 /* 442 /*
diff --git a/drivers/mtd/maps/dmv182.c b/drivers/mtd/maps/dmv182.c
index b9bc63503e26..b993ac01a9a5 100644
--- a/drivers/mtd/maps/dmv182.c
+++ b/drivers/mtd/maps/dmv182.c
@@ -1,10 +1,10 @@
1 1
2/* 2/*
3 * drivers/mtd/maps/svme182.c 3 * drivers/mtd/maps/svme182.c
4 * 4 *
5 * Flash map driver for the Dy4 SVME182 board 5 * Flash map driver for the Dy4 SVME182 board
6 * 6 *
7 * $Id: dmv182.c,v 1.5 2004/11/04 13:24:14 gleixner Exp $ 7 * $Id: dmv182.c,v 1.6 2005/11/07 11:14:26 gleixner Exp $
8 * 8 *
9 * Copyright 2003-2004, TimeSys Corporation 9 * Copyright 2003-2004, TimeSys Corporation
10 * 10 *
@@ -104,7 +104,7 @@ static int __init init_svme182(void)
104 partitions = svme182_partitions; 104 partitions = svme182_partitions;
105 105
106 svme182_map.virt = ioremap(FLASH_BASE_ADDR, svme182_map.size); 106 svme182_map.virt = ioremap(FLASH_BASE_ADDR, svme182_map.size);
107 107
108 if (svme182_map.virt == 0) { 108 if (svme182_map.virt == 0) {
109 printk("Failed to ioremap FLASH memory area.\n"); 109 printk("Failed to ioremap FLASH memory area.\n");
110 return -EIO; 110 return -EIO;
diff --git a/drivers/mtd/maps/ebony.c b/drivers/mtd/maps/ebony.c
index b9d9cf4854b6..c0daf58357ca 100644
--- a/drivers/mtd/maps/ebony.c
+++ b/drivers/mtd/maps/ebony.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * $Id: ebony.c,v 1.15 2004/12/09 18:39:54 holindho Exp $ 2 * $Id: ebony.c,v 1.16 2005/11/07 11:14:26 gleixner Exp $
3 * 3 *
4 * Mapping for Ebony user flash 4 * Mapping for Ebony user flash
5 * 5 *
6 * Matt Porter <mporter@kernel.crashing.org> 6 * Matt Porter <mporter@kernel.crashing.org>
@@ -85,7 +85,7 @@ int __init init_ebony(void)
85 small_flash_base = EBONY_SMALL_FLASH_LOW2; 85 small_flash_base = EBONY_SMALL_FLASH_LOW2;
86 else 86 else
87 small_flash_base = EBONY_SMALL_FLASH_LOW1; 87 small_flash_base = EBONY_SMALL_FLASH_LOW1;
88 88
89 if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) && 89 if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
90 !EBONY_ONBRD_FLASH_EN(fpga0_reg)) 90 !EBONY_ONBRD_FLASH_EN(fpga0_reg))
91 large_flash_base = EBONY_LARGE_FLASH_LOW; 91 large_flash_base = EBONY_LARGE_FLASH_LOW;
diff --git a/drivers/mtd/maps/edb7312.c b/drivers/mtd/maps/edb7312.c
index 8b0da394f3fa..b48a3473ffc1 100644
--- a/drivers/mtd/maps/edb7312.c
+++ b/drivers/mtd/maps/edb7312.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * $Id: edb7312.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: edb7312.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Handle mapping of the NOR flash on Cogent EDB7312 boards 4 * Handle mapping of the NOR flash on Cogent EDB7312 boards
5 * 5 *
6 * Copyright 2002 SYSGO Real-Time Solutions GmbH 6 * Copyright 2002 SYSGO Real-Time Solutions GmbH
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
@@ -46,7 +46,7 @@ struct map_info edb7312nor_map = {
46#ifdef CONFIG_MTD_PARTITIONS 46#ifdef CONFIG_MTD_PARTITIONS
47 47
48/* 48/*
49 * MTD partitioning stuff 49 * MTD partitioning stuff
50 */ 50 */
51static struct mtd_partition static_partitions[3] = 51static struct mtd_partition static_partitions[3] =
52{ 52{
@@ -80,7 +80,7 @@ int __init init_edb7312nor(void)
80 const char **type; 80 const char **type;
81 const char *part_type = 0; 81 const char *part_type = 0;
82 82
83 printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n", 83 printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n",
84 WINDOW_SIZE, WINDOW_ADDR); 84 WINDOW_SIZE, WINDOW_ADDR);
85 edb7312nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); 85 edb7312nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
86 86
@@ -88,7 +88,7 @@ int __init init_edb7312nor(void)
88 printk(MSG_PREFIX "failed to ioremap\n"); 88 printk(MSG_PREFIX "failed to ioremap\n");
89 return -EIO; 89 return -EIO;
90 } 90 }
91 91
92 simple_map_init(&edb7312nor_map); 92 simple_map_init(&edb7312nor_map);
93 93
94 mymtd = 0; 94 mymtd = 0;
diff --git a/drivers/mtd/maps/epxa10db-flash.c b/drivers/mtd/maps/epxa10db-flash.c
index 1df6188926b3..265b079fe934 100644
--- a/drivers/mtd/maps/epxa10db-flash.c
+++ b/drivers/mtd/maps/epxa10db-flash.c
@@ -5,7 +5,7 @@
5 * Copyright (C) 2001 Altera Corporation 5 * Copyright (C) 2001 Altera Corporation
6 * Copyright (C) 2001 Red Hat, Inc. 6 * Copyright (C) 2001 Red Hat, Inc.
7 * 7 *
8 * $Id: epxa10db-flash.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $ 8 * $Id: epxa10db-flash.c,v 1.15 2005/11/07 11:14:27 gleixner Exp $
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
@@ -62,7 +62,7 @@ static const char *probes[] = { "RedBoot", "afs", NULL };
62static int __init epxa_mtd_init(void) 62static int __init epxa_mtd_init(void)
63{ 63{
64 int i; 64 int i;
65 65
66 printk(KERN_NOTICE "%s flash device: 0x%x at 0x%x\n", BOARD_NAME, FLASH_SIZE, FLASH_START); 66 printk(KERN_NOTICE "%s flash device: 0x%x at 0x%x\n", BOARD_NAME, FLASH_SIZE, FLASH_START);
67 67
68 epxa_map.virt = ioremap(FLASH_START, FLASH_SIZE); 68 epxa_map.virt = ioremap(FLASH_START, FLASH_SIZE);
@@ -126,8 +126,8 @@ static void __exit epxa_mtd_cleanup(void)
126} 126}
127 127
128 128
129/* 129/*
130 * This will do for now, once we decide which bootldr we're finally 130 * This will do for now, once we decide which bootldr we're finally
131 * going to use then we'll remove this function and do it properly 131 * going to use then we'll remove this function and do it properly
132 * 132 *
133 * Partions are currently (as offsets from base of flash): 133 * Partions are currently (as offsets from base of flash):
@@ -140,7 +140,7 @@ static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_pa
140 struct mtd_partition *parts; 140 struct mtd_partition *parts;
141 int ret, i; 141 int ret, i;
142 int npartitions = 0; 142 int npartitions = 0;
143 char *names; 143 char *names;
144 const char *name = "jffs"; 144 const char *name = "jffs";
145 145
146 printk("Using default partitions for %s\n",BOARD_NAME); 146 printk("Using default partitions for %s\n",BOARD_NAME);
@@ -152,7 +152,7 @@ static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_pa
152 goto out; 152 goto out;
153 } 153 }
154 i=0; 154 i=0;
155 names = (char *)&parts[npartitions]; 155 names = (char *)&parts[npartitions];
156 parts[i].name = names; 156 parts[i].name = names;
157 names += strlen(name) + 1; 157 names += strlen(name) + 1;
158 strcpy(parts[i].name, name); 158 strcpy(parts[i].name, name);
diff --git a/drivers/mtd/maps/fortunet.c b/drivers/mtd/maps/fortunet.c
index 00f7bbe5479e..c6bf4e1219ef 100644
--- a/drivers/mtd/maps/fortunet.c
+++ b/drivers/mtd/maps/fortunet.c
@@ -1,6 +1,6 @@
1/* fortunet.c memory map 1/* fortunet.c memory map
2 * 2 *
3 * $Id: fortunet.c,v 1.9 2004/11/04 13:24:14 gleixner Exp $ 3 * $Id: fortunet.c,v 1.11 2005/11/07 11:14:27 gleixner Exp $
4 */ 4 */
5 5
6#include <linux/module.h> 6#include <linux/module.h>
@@ -212,7 +212,7 @@ int __init init_fortunet(void)
212 212
213 map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical, 213 map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical,
214 214
215 map_regions[ix].map_info.virt = 215 map_regions[ix].map_info.virt =
216 ioremap_nocache( 216 ioremap_nocache(
217 map_regions[ix].window_addr_physical, 217 map_regions[ix].window_addr_physical,
218 map_regions[ix].map_info.size); 218 map_regions[ix].map_info.size);
diff --git a/drivers/mtd/maps/h720x-flash.c b/drivers/mtd/maps/h720x-flash.c
index c73828171d9b..319094821101 100644
--- a/drivers/mtd/maps/h720x-flash.c
+++ b/drivers/mtd/maps/h720x-flash.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * Flash memory access on Hynix GMS30C7201/HMS30C7202 based 2 * Flash memory access on Hynix GMS30C7201/HMS30C7202 based
3 * evaluation boards 3 * evaluation boards
4 * 4 *
5 * $Id: h720x-flash.c,v 1.11 2004/11/04 13:24:14 gleixner Exp $ 5 * $Id: h720x-flash.c,v 1.12 2005/11/07 11:14:27 gleixner Exp $
6 * 6 *
7 * (C) 2002 Jungjun Kim <jungjun.kim@hynix.com> 7 * (C) 2002 Jungjun Kim <jungjun.kim@hynix.com>
8 * 2003 Thomas Gleixner <tglx@linutronix.de> 8 * 2003 Thomas Gleixner <tglx@linutronix.de>
9 */ 9 */
10 10
11#include <linux/config.h> 11#include <linux/config.h>
@@ -72,7 +72,7 @@ int __init h720x_mtd_init(void)
72{ 72{
73 73
74 char *part_type = NULL; 74 char *part_type = NULL;
75 75
76 h720x_map.virt = ioremap(FLASH_PHYS, FLASH_SIZE); 76 h720x_map.virt = ioremap(FLASH_PHYS, FLASH_SIZE);
77 77
78 if (!h720x_map.virt) { 78 if (!h720x_map.virt) {
@@ -91,7 +91,7 @@ int __init h720x_mtd_init(void)
91 h720x_map.bankwidth = 2; 91 h720x_map.bankwidth = 2;
92 mymtd = do_map_probe("cfi_probe", &h720x_map); 92 mymtd = do_map_probe("cfi_probe", &h720x_map);
93 } 93 }
94 94
95 if (mymtd) { 95 if (mymtd) {
96 mymtd->owner = THIS_MODULE; 96 mymtd->owner = THIS_MODULE;
97 97
@@ -124,11 +124,11 @@ static void __exit h720x_mtd_cleanup(void)
124 del_mtd_partitions(mymtd); 124 del_mtd_partitions(mymtd);
125 map_destroy(mymtd); 125 map_destroy(mymtd);
126 } 126 }
127 127
128 /* Free partition info, if commandline partition was used */ 128 /* Free partition info, if commandline partition was used */
129 if (mtd_parts && (mtd_parts != h720x_partitions)) 129 if (mtd_parts && (mtd_parts != h720x_partitions))
130 kfree (mtd_parts); 130 kfree (mtd_parts);
131 131
132 if (h720x_map.virt) { 132 if (h720x_map.virt) {
133 iounmap((void *)h720x_map.virt); 133 iounmap((void *)h720x_map.virt);
134 h720x_map.virt = 0; 134 h720x_map.virt = 0;
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c
index e505207cd489..ea5073781b3a 100644
--- a/drivers/mtd/maps/ichxrom.c
+++ b/drivers/mtd/maps/ichxrom.c
@@ -2,7 +2,7 @@
2 * ichxrom.c 2 * ichxrom.c
3 * 3 *
4 * Normal mappings of chips in physical memory 4 * Normal mappings of chips in physical memory
5 * $Id: ichxrom.c,v 1.18 2005/07/07 10:26:20 dwmw2 Exp $ 5 * $Id: ichxrom.c,v 1.19 2005/11/07 11:14:27 gleixner Exp $
6 */ 6 */
7 7
8#include <linux/module.h> 8#include <linux/module.h>
@@ -101,7 +101,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
101 * you can only really attach a FWH to an ICHX there 101 * you can only really attach a FWH to an ICHX there
102 * a number of simplifications you can make. 102 * a number of simplifications you can make.
103 * 103 *
104 * Also you can page firmware hubs if an 8MB window isn't enough 104 * Also you can page firmware hubs if an 8MB window isn't enough
105 * but don't currently handle that case either. 105 * but don't currently handle that case either.
106 */ 106 */
107 window->pdev = pdev; 107 window->pdev = pdev;
@@ -144,7 +144,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
144 window->phys = 0xfff00000; 144 window->phys = 0xfff00000;
145 } 145 }
146 else if ((byte & 0x80) == 0x80) { 146 else if ((byte & 0x80) == 0x80) {
147 window->phys = 0xfff80000; 147 window->phys = 0xfff80000;
148 } 148 }
149 149
150 if (window->phys == 0) { 150 if (window->phys == 0) {
@@ -233,7 +233,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
233 * in a factory setting. So in-place programming 233 * in a factory setting. So in-place programming
234 * needs to use a different method. 234 * needs to use a different method.
235 */ 235 */
236 for(map->map.bankwidth = 32; map->map.bankwidth; 236 for(map->map.bankwidth = 32; map->map.bankwidth;
237 map->map.bankwidth >>= 1) 237 map->map.bankwidth >>= 1)
238 { 238 {
239 char **probe_type; 239 char **probe_type;
@@ -286,7 +286,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
286 for(i = 0; i < cfi->numchips; i++) { 286 for(i = 0; i < cfi->numchips; i++) {
287 cfi->chips[i].start += offset; 287 cfi->chips[i].start += offset;
288 } 288 }
289 289
290 /* Now that the mtd devices is complete claim and export it */ 290 /* Now that the mtd devices is complete claim and export it */
291 map->mtd->owner = THIS_MODULE; 291 map->mtd->owner = THIS_MODULE;
292 if (add_mtd_device(map->mtd)) { 292 if (add_mtd_device(map->mtd)) {
@@ -306,9 +306,8 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
306 306
307 out: 307 out:
308 /* Free any left over map structures */ 308 /* Free any left over map structures */
309 if (map) { 309 kfree(map);
310 kfree(map); 310
311 }
312 /* See if I have any map structures */ 311 /* See if I have any map structures */
313 if (list_empty(&window->maps)) { 312 if (list_empty(&window->maps)) {
314 ichxrom_cleanup(window); 313 ichxrom_cleanup(window);
@@ -325,11 +324,11 @@ static void __devexit ichxrom_remove_one (struct pci_dev *pdev)
325} 324}
326 325
327static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = { 326static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = {
328 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, 327 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,
329 PCI_ANY_ID, PCI_ANY_ID, }, 328 PCI_ANY_ID, PCI_ANY_ID, },
330 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, 329 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
331 PCI_ANY_ID, PCI_ANY_ID, }, 330 PCI_ANY_ID, PCI_ANY_ID, },
332 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, 331 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
333 PCI_ANY_ID, PCI_ANY_ID, }, 332 PCI_ANY_ID, PCI_ANY_ID, },
334 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, 333 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,
335 PCI_ANY_ID, PCI_ANY_ID, }, 334 PCI_ANY_ID, PCI_ANY_ID, },
diff --git a/drivers/mtd/maps/impa7.c b/drivers/mtd/maps/impa7.c
index cb39172c81d2..ba7f40311a7e 100644
--- a/drivers/mtd/maps/impa7.c
+++ b/drivers/mtd/maps/impa7.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * $Id: impa7.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: impa7.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Handle mapping of the NOR flash on implementa A7 boards 4 * Handle mapping of the NOR flash on implementa A7 boards
5 * 5 *
6 * Copyright 2002 SYSGO Real-Time Solutions GmbH 6 * Copyright 2002 SYSGO Real-Time Solutions GmbH
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
@@ -55,7 +55,7 @@ static struct map_info impa7_map[NUM_FLASHBANKS] = {
55#ifdef CONFIG_MTD_PARTITIONS 55#ifdef CONFIG_MTD_PARTITIONS
56 56
57/* 57/*
58 * MTD partitioning stuff 58 * MTD partitioning stuff
59 */ 59 */
60static struct mtd_partition static_partitions[] = 60static struct mtd_partition static_partitions[] =
61{ 61{
@@ -108,9 +108,9 @@ int __init init_impa7(void)
108 impa7_mtd[i]->owner = THIS_MODULE; 108 impa7_mtd[i]->owner = THIS_MODULE;
109 devicesfound++; 109 devicesfound++;
110#ifdef CONFIG_MTD_PARTITIONS 110#ifdef CONFIG_MTD_PARTITIONS
111 mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i], 111 mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i],
112 probes, 112 probes,
113 &mtd_parts[i], 113 &mtd_parts[i],
114 0); 114 0);
115 if (mtd_parts_nb[i] > 0) { 115 if (mtd_parts_nb[i] > 0) {
116 part_type = "command line"; 116 part_type = "command line";
@@ -121,16 +121,16 @@ int __init init_impa7(void)
121 } 121 }
122 122
123 printk(KERN_NOTICE MSG_PREFIX 123 printk(KERN_NOTICE MSG_PREFIX
124 "using %s partition definition\n", 124 "using %s partition definition\n",
125 part_type); 125 part_type);
126 add_mtd_partitions(impa7_mtd[i], 126 add_mtd_partitions(impa7_mtd[i],
127 mtd_parts[i], mtd_parts_nb[i]); 127 mtd_parts[i], mtd_parts_nb[i]);
128#else 128#else
129 add_mtd_device(impa7_mtd[i]); 129 add_mtd_device(impa7_mtd[i]);
130 130
131#endif 131#endif
132 } 132 }
133 else 133 else
134 iounmap((void *)impa7_map[i].virt); 134 iounmap((void *)impa7_map[i].virt);
135 } 135 }
136 return devicesfound == 0 ? -ENXIO : 0; 136 return devicesfound == 0 ? -ENXIO : 0;
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c
index d14a0185b8f4..fe738fd8d6f8 100644
--- a/drivers/mtd/maps/integrator-flash.c
+++ b/drivers/mtd/maps/integrator-flash.c
@@ -1,28 +1,28 @@
1/*====================================================================== 1/*======================================================================
2 2
3 drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver 3 drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver
4 4
5 Copyright (C) 2000 ARM Limited 5 Copyright (C) 2000 ARM Limited
6 Copyright (C) 2003 Deep Blue Solutions Ltd. 6 Copyright (C) 2003 Deep Blue Solutions Ltd.
7 7
8 This program is free software; you can redistribute it and/or modify 8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version. 11 (at your option) any later version.
12 12
13 This program is distributed in the hope that it will be useful, 13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 16 GNU General Public License for more details.
17 17
18 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software 19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 21
22 This is access code for flashes using ARM's flash partitioning 22 This is access code for flashes using ARM's flash partitioning
23 standards. 23 standards.
24 24
25 $Id: integrator-flash.c,v 1.18 2004/11/01 13:26:15 rmk Exp $ 25 $Id: integrator-flash.c,v 1.20 2005/11/07 11:14:27 gleixner Exp $
26 26
27======================================================================*/ 27======================================================================*/
28 28
@@ -148,8 +148,7 @@ static int armflash_probe(struct device *_dev)
148 del_mtd_partitions(info->mtd); 148 del_mtd_partitions(info->mtd);
149 map_destroy(info->mtd); 149 map_destroy(info->mtd);
150 } 150 }
151 if (info->parts) 151 kfree(info->parts);
152 kfree(info->parts);
153 152
154 no_device: 153 no_device:
155 iounmap(base); 154 iounmap(base);
@@ -176,8 +175,7 @@ static int armflash_remove(struct device *_dev)
176 del_mtd_partitions(info->mtd); 175 del_mtd_partitions(info->mtd);
177 map_destroy(info->mtd); 176 map_destroy(info->mtd);
178 } 177 }
179 if (info->parts) 178 kfree(info->parts);
180 kfree(info->parts);
181 179
182 iounmap(info->map.virt); 180 iounmap(info->map.virt);
183 release_resource(info->res); 181 release_resource(info->res);
diff --git a/drivers/mtd/maps/ipaq-flash.c b/drivers/mtd/maps/ipaq-flash.c
index 712401810841..35097c9bbf50 100644
--- a/drivers/mtd/maps/ipaq-flash.c
+++ b/drivers/mtd/maps/ipaq-flash.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * Flash memory access on iPAQ Handhelds (either SA1100 or PXA250 based) 2 * Flash memory access on iPAQ Handhelds (either SA1100 or PXA250 based)
3 * 3 *
4 * (C) 2000 Nicolas Pitre <nico@cam.org> 4 * (C) 2000 Nicolas Pitre <nico@cam.org>
5 * (C) 2002 Hewlett-Packard Company <jamey.hicks@hp.com> 5 * (C) 2002 Hewlett-Packard Company <jamey.hicks@hp.com>
6 * (C) 2003 Christian Pellegrin <chri@ascensit.com>, <chri@infis.univ.ts.it>: concatenation of multiple flashes 6 * (C) 2003 Christian Pellegrin <chri@ascensit.com>, <chri@infis.univ.ts.it>: concatenation of multiple flashes
7 * 7 *
8 * $Id: ipaq-flash.c,v 1.3 2004/11/04 13:24:15 gleixner Exp $ 8 * $Id: ipaq-flash.c,v 1.5 2005/11/07 11:14:27 gleixner Exp $
9 */ 9 */
10 10
11#include <linux/config.h> 11#include <linux/config.h>
@@ -107,7 +107,7 @@ static struct mtd_partition h3xxx_partitions[] = {
107#ifndef CONFIG_LAB 107#ifndef CONFIG_LAB
108 mask_flags: MTD_WRITEABLE, /* force read-only */ 108 mask_flags: MTD_WRITEABLE, /* force read-only */
109#endif 109#endif
110 }, 110 },
111 { 111 {
112 name: "H3XXX root jffs2", 112 name: "H3XXX root jffs2",
113#ifndef CONFIG_LAB 113#ifndef CONFIG_LAB
@@ -148,7 +148,7 @@ static DEFINE_SPINLOCK(ipaq_vpp_lock);
148static void h3xxx_set_vpp(struct map_info *map, int vpp) 148static void h3xxx_set_vpp(struct map_info *map, int vpp)
149{ 149{
150 static int nest = 0; 150 static int nest = 0;
151 151
152 spin_lock(&ipaq_vpp_lock); 152 spin_lock(&ipaq_vpp_lock);
153 if (vpp) 153 if (vpp)
154 nest++; 154 nest++;
@@ -191,7 +191,7 @@ static unsigned long cs_phys[] = {
191 SA1100_CS3_PHYS, 191 SA1100_CS3_PHYS,
192 SA1100_CS4_PHYS, 192 SA1100_CS4_PHYS,
193 SA1100_CS5_PHYS, 193 SA1100_CS5_PHYS,
194#else 194#else
195 PXA_CS0_PHYS, 195 PXA_CS0_PHYS,
196 PXA_CS1_PHYS, 196 PXA_CS1_PHYS,
197 PXA_CS2_PHYS, 197 PXA_CS2_PHYS,
@@ -216,7 +216,7 @@ int __init ipaq_mtd_init(void)
216 216
217 /* Default flash bankwidth */ 217 /* Default flash bankwidth */
218 // ipaq_map.bankwidth = (MSC0 & MSC_RBW) ? 2 : 4; 218 // ipaq_map.bankwidth = (MSC0 & MSC_RBW) ? 2 : 4;
219 219
220 if (machine_is_h1900()) 220 if (machine_is_h1900())
221 { 221 {
222 /* For our intents, the h1900 is not a real iPAQ, so we special-case it. */ 222 /* For our intents, the h1900 is not a real iPAQ, so we special-case it. */
@@ -229,7 +229,7 @@ int __init ipaq_mtd_init(void)
229 else 229 else
230 for(i=0; i<MAX_IPAQ_CS; i++) 230 for(i=0; i<MAX_IPAQ_CS; i++)
231 ipaq_map[i].bankwidth = 4; 231 ipaq_map[i].bankwidth = 4;
232 232
233 /* 233 /*
234 * Static partition definition selection 234 * Static partition definition selection
235 */ 235 */
@@ -309,7 +309,7 @@ int __init ipaq_mtd_init(void)
309 return -ENXIO; 309 return -ENXIO;
310 } else 310 } else
311 printk(KERN_NOTICE "iPAQ flash: found %d bytes\n", my_sub_mtd[i]->size); 311 printk(KERN_NOTICE "iPAQ flash: found %d bytes\n", my_sub_mtd[i]->size);
312 312
313 /* do we really need this debugging? --joshua 20030703 */ 313 /* do we really need this debugging? --joshua 20030703 */
314 // printk("my_sub_mtd[%d]=%p\n", i, my_sub_mtd[i]); 314 // printk("my_sub_mtd[%d]=%p\n", i, my_sub_mtd[i]);
315 my_sub_mtd[i]->owner = THIS_MODULE; 315 my_sub_mtd[i]->owner = THIS_MODULE;
@@ -333,11 +333,11 @@ int __init ipaq_mtd_init(void)
333#else 333#else
334 mymtd = my_sub_mtd[0]; 334 mymtd = my_sub_mtd[0];
335 335
336 /* 336 /*
337 *In the very near future, command line partition parsing 337 *In the very near future, command line partition parsing
338 * will use the device name as 'mtd-id' instead of a value 338 * will use the device name as 'mtd-id' instead of a value
339 * passed to the parse_cmdline_partitions() routine. Since 339 * passed to the parse_cmdline_partitions() routine. Since
340 * the bootldr says 'ipaq', make sure it continues to work. 340 * the bootldr says 'ipaq', make sure it continues to work.
341 */ 341 */
342 mymtd->name = "ipaq"; 342 mymtd->name = "ipaq";
343 343
@@ -385,7 +385,7 @@ int __init ipaq_mtd_init(void)
385 */ 385 */
386 386
387 i = parse_mtd_partitions(mymtd, part_probes, &parsed_parts, 0); 387 i = parse_mtd_partitions(mymtd, part_probes, &parsed_parts, 0);
388 388
389 if (i > 0) { 389 if (i > 0) {
390 nb_parts = parsed_nr_parts = i; 390 nb_parts = parsed_nr_parts = i;
391 parts = parsed_parts; 391 parts = parsed_parts;
@@ -423,16 +423,15 @@ static void __exit ipaq_mtd_cleanup(void)
423#endif 423#endif
424 map_destroy(mymtd); 424 map_destroy(mymtd);
425#ifdef CONFIG_MTD_CONCAT 425#ifdef CONFIG_MTD_CONCAT
426 for(i=0; i<MAX_IPAQ_CS; i++) 426 for(i=0; i<MAX_IPAQ_CS; i++)
427#else 427#else
428 for(i=1; i<MAX_IPAQ_CS; i++) 428 for(i=1; i<MAX_IPAQ_CS; i++)
429#endif 429#endif
430 { 430 {
431 if (my_sub_mtd[i]) 431 if (my_sub_mtd[i])
432 map_destroy(my_sub_mtd[i]); 432 map_destroy(my_sub_mtd[i]);
433 } 433 }
434 if (parsed_parts) 434 kfree(parsed_parts);
435 kfree(parsed_parts);
436 } 435 }
437} 436}
438 437
@@ -445,14 +444,14 @@ static int __init h1900_special_case(void)
445 ipaq_map[0].phys = 0x0; 444 ipaq_map[0].phys = 0x0;
446 ipaq_map[0].virt = __ioremap(0x0, 0x04000000, 0, 1); 445 ipaq_map[0].virt = __ioremap(0x0, 0x04000000, 0, 1);
447 ipaq_map[0].bankwidth = 2; 446 ipaq_map[0].bankwidth = 2;
448 447
449 printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt); 448 printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt);
450 mymtd = do_map_probe("jedec_probe", &ipaq_map[0]); 449 mymtd = do_map_probe("jedec_probe", &ipaq_map[0]);
451 if (!mymtd) 450 if (!mymtd)
452 return -ENODEV; 451 return -ENODEV;
453 add_mtd_device(mymtd); 452 add_mtd_device(mymtd);
454 printk(KERN_NOTICE "iPAQ flash: registered h1910 flash\n"); 453 printk(KERN_NOTICE "iPAQ flash: registered h1910 flash\n");
455 454
456 return 0; 455 return 0;
457} 456}
458 457
diff --git a/drivers/mtd/maps/iq80310.c b/drivers/mtd/maps/iq80310.c
index 558d014e7acc..62d9e87d84e2 100644
--- a/drivers/mtd/maps/iq80310.c
+++ b/drivers/mtd/maps/iq80310.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * $Id: iq80310.c,v 1.20 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: iq80310.c,v 1.21 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Mapping for the Intel XScale IQ80310 evaluation board 4 * Mapping for the Intel XScale IQ80310 evaluation board
5 * 5 *
6 * Author: Nicolas Pitre 6 * Author: Nicolas Pitre
7 * Copyright: (C) 2001 MontaVista Software Inc. 7 * Copyright: (C) 2001 MontaVista Software Inc.
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
@@ -103,8 +103,7 @@ static void __exit cleanup_iq80310(void)
103 if (mymtd) { 103 if (mymtd) {
104 del_mtd_partitions(mymtd); 104 del_mtd_partitions(mymtd);
105 map_destroy(mymtd); 105 map_destroy(mymtd);
106 if (parsed_parts) 106 kfree(parsed_parts);
107 kfree(parsed_parts);
108 } 107 }
109 if (iq80310_map.virt) 108 if (iq80310_map.virt)
110 iounmap((void *)iq80310_map.virt); 109 iounmap((void *)iq80310_map.virt);
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
index 00b9f67580f1..641eb2b55e9f 100644
--- a/drivers/mtd/maps/ixp2000.c
+++ b/drivers/mtd/maps/ixp2000.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ixp2000.c,v 1.6 2005/03/18 14:07:46 gleixner Exp $ 2 * $Id: ixp2000.c,v 1.9 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/ixp2000.c 4 * drivers/mtd/maps/ixp2000.c
5 * 5 *
@@ -14,7 +14,7 @@
14 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as 15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation. 16 * published by the Free Software Foundation.
17 * 17 *
18 */ 18 */
19 19
20#include <linux/module.h> 20#include <linux/module.h>
@@ -46,8 +46,8 @@ struct ixp2000_flash_info {
46}; 46};
47 47
48static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long ofs) 48static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long ofs)
49{ 49{
50 unsigned long (*set_bank)(unsigned long) = 50 unsigned long (*set_bank)(unsigned long) =
51 (unsigned long(*)(unsigned long))map->map_priv_2; 51 (unsigned long(*)(unsigned long))map->map_priv_2;
52 52
53 return (set_bank ? set_bank(ofs) : ofs); 53 return (set_bank ? set_bank(ofs) : ofs);
@@ -55,8 +55,8 @@ static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long
55 55
56#ifdef __ARMEB__ 56#ifdef __ARMEB__
57/* 57/*
58 * Rev A0 and A1 of IXP2400 silicon have a broken addressing unit which 58 * Rev A0 and A1 of IXP2400 silicon have a broken addressing unit which
59 * causes the lower address bits to be XORed with 0x11 on 8 bit accesses 59 * causes the lower address bits to be XORed with 0x11 on 8 bit accesses
60 * and XORed with 0x10 on 16 bit accesses. See the spec update, erratum 44. 60 * and XORed with 0x10 on 16 bit accesses. See the spec update, erratum 44.
61 */ 61 */
62static int erratum44_workaround = 0; 62static int erratum44_workaround = 0;
@@ -90,7 +90,7 @@ static void ixp2000_flash_copy_from(struct map_info *map, void *to,
90 unsigned long from, ssize_t len) 90 unsigned long from, ssize_t len)
91{ 91{
92 from = flash_bank_setup(map, from); 92 from = flash_bank_setup(map, from);
93 while(len--) 93 while(len--)
94 *(__u8 *) to++ = *(__u8 *)(map->map_priv_1 + from++); 94 *(__u8 *) to++ = *(__u8 *)(map->map_priv_1 + from++);
95} 95}
96 96
@@ -129,8 +129,7 @@ static int ixp2000_flash_remove(struct device *_dev)
129 if (info->map.map_priv_1) 129 if (info->map.map_priv_1)
130 iounmap((void *) info->map.map_priv_1); 130 iounmap((void *) info->map.map_priv_1);
131 131
132 if (info->partitions) { 132 kfree(info->partitions);
133 kfree(info->partitions); }
134 133
135 if (info->res) { 134 if (info->res) {
136 release_resource(info->res); 135 release_resource(info->res);
@@ -149,11 +148,11 @@ static int ixp2000_flash_probe(struct device *_dev)
149 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; 148 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
150 struct platform_device *dev = to_platform_device(_dev); 149 struct platform_device *dev = to_platform_device(_dev);
151 struct ixp2000_flash_data *ixp_data = dev->dev.platform_data; 150 struct ixp2000_flash_data *ixp_data = dev->dev.platform_data;
152 struct flash_platform_data *plat; 151 struct flash_platform_data *plat;
153 struct ixp2000_flash_info *info; 152 struct ixp2000_flash_info *info;
154 unsigned long window_size; 153 unsigned long window_size;
155 int err = -1; 154 int err = -1;
156 155
157 if (!ixp_data) 156 if (!ixp_data)
158 return -ENODEV; 157 return -ENODEV;
159 158
@@ -162,7 +161,7 @@ static int ixp2000_flash_probe(struct device *_dev)
162 return -ENODEV; 161 return -ENODEV;
163 162
164 window_size = dev->resource->end - dev->resource->start + 1; 163 window_size = dev->resource->end - dev->resource->start + 1;
165 dev_info(_dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n", 164 dev_info(_dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
166 ixp_data->nr_banks, ((u32)window_size >> 20)); 165 ixp_data->nr_banks, ((u32)window_size >> 20));
167 166
168 if (plat->width != 1) { 167 if (plat->width != 1) {
@@ -175,7 +174,7 @@ static int ixp2000_flash_probe(struct device *_dev)
175 if(!info) { 174 if(!info) {
176 err = -ENOMEM; 175 err = -ENOMEM;
177 goto Error; 176 goto Error;
178 } 177 }
179 memzero(info, sizeof(struct ixp2000_flash_info)); 178 memzero(info, sizeof(struct ixp2000_flash_info));
180 179
181 dev_set_drvdata(&dev->dev, info); 180 dev_set_drvdata(&dev->dev, info);
@@ -185,7 +184,7 @@ static int ixp2000_flash_probe(struct device *_dev)
185 * not attempt to do a direct access on us. 184 * not attempt to do a direct access on us.
186 */ 185 */
187 info->map.phys = NO_XIP; 186 info->map.phys = NO_XIP;
188 187
189 info->nr_banks = ixp_data->nr_banks; 188 info->nr_banks = ixp_data->nr_banks;
190 info->map.size = ixp_data->nr_banks * window_size; 189 info->map.size = ixp_data->nr_banks * window_size;
191 info->map.bankwidth = 1; 190 info->map.bankwidth = 1;
@@ -193,7 +192,7 @@ static int ixp2000_flash_probe(struct device *_dev)
193 /* 192 /*
194 * map_priv_2 is used to store a ptr to to the bank_setup routine 193 * map_priv_2 is used to store a ptr to to the bank_setup routine
195 */ 194 */
196 info->map.map_priv_2 = (void __iomem *) ixp_data->bank_setup; 195 info->map.map_priv_2 = (unsigned long) ixp_data->bank_setup;
197 196
198 info->map.name = dev->dev.bus_id; 197 info->map.name = dev->dev.bus_id;
199 info->map.read = ixp2000_flash_read8; 198 info->map.read = ixp2000_flash_read8;
@@ -201,8 +200,8 @@ static int ixp2000_flash_probe(struct device *_dev)
201 info->map.copy_from = ixp2000_flash_copy_from; 200 info->map.copy_from = ixp2000_flash_copy_from;
202 info->map.copy_to = ixp2000_flash_copy_to; 201 info->map.copy_to = ixp2000_flash_copy_to;
203 202
204 info->res = request_mem_region(dev->resource->start, 203 info->res = request_mem_region(dev->resource->start,
205 dev->resource->end - dev->resource->start + 1, 204 dev->resource->end - dev->resource->start + 1,
206 dev->dev.bus_id); 205 dev->dev.bus_id);
207 if (!info->res) { 206 if (!info->res) {
208 dev_err(_dev, "Could not reserve memory region\n"); 207 dev_err(_dev, "Could not reserve memory region\n");
@@ -210,7 +209,7 @@ static int ixp2000_flash_probe(struct device *_dev)
210 goto Error; 209 goto Error;
211 } 210 }
212 211
213 info->map.map_priv_1 = ioremap(dev->resource->start, 212 info->map.map_priv_1 = (unsigned long) ioremap(dev->resource->start,
214 dev->resource->end - dev->resource->start + 1); 213 dev->resource->end - dev->resource->start + 1);
215 if (!info->map.map_priv_1) { 214 if (!info->map.map_priv_1) {
216 dev_err(_dev, "Failed to ioremap flash region\n"); 215 dev_err(_dev, "Failed to ioremap flash region\n");
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c
index 733a9297a562..56b3a355bf7b 100644
--- a/drivers/mtd/maps/ixp4xx.c
+++ b/drivers/mtd/maps/ixp4xx.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ixp4xx.c,v 1.7 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: ixp4xx.c,v 1.12 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/ixp4xx.c 4 * drivers/mtd/maps/ixp4xx.c
5 * 5 *
@@ -45,7 +45,7 @@
45static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs) 45static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs)
46{ 46{
47 map_word val; 47 map_word val;
48 val.x[0] = *(__u16 *) (map->map_priv_1 + ofs); 48 val.x[0] = le16_to_cpu(readw(map->virt + ofs));
49 return val; 49 return val;
50} 50}
51 51
@@ -59,35 +59,35 @@ static void ixp4xx_copy_from(struct map_info *map, void *to,
59{ 59{
60 int i; 60 int i;
61 u8 *dest = (u8 *) to; 61 u8 *dest = (u8 *) to;
62 u16 *src = (u16 *) (map->map_priv_1 + from); 62 void __iomem *src = map->virt + from;
63 u16 data; 63 u16 data;
64 64
65 for (i = 0; i < (len / 2); i++) { 65 for (i = 0; i < (len / 2); i++) {
66 data = src[i]; 66 data = le16_to_cpu(readw(src + 2*i));
67 dest[i * 2] = BYTE0(data); 67 dest[i * 2] = BYTE0(data);
68 dest[i * 2 + 1] = BYTE1(data); 68 dest[i * 2 + 1] = BYTE1(data);
69 } 69 }
70 70
71 if (len & 1) 71 if (len & 1)
72 dest[len - 1] = BYTE0(src[i]); 72 dest[len - 1] = BYTE0(le16_to_cpu(readw(src + 2*i)));
73} 73}
74 74
75/* 75/*
76 * Unaligned writes are ignored, causing the 8-bit 76 * Unaligned writes are ignored, causing the 8-bit
77 * probe to fail and proceed to the 16-bit probe (which succeeds). 77 * probe to fail and proceed to the 16-bit probe (which succeeds).
78 */ 78 */
79static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr) 79static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr)
80{ 80{
81 if (!(adr & 1)) 81 if (!(adr & 1))
82 *(__u16 *) (map->map_priv_1 + adr) = d.x[0]; 82 writew(cpu_to_le16(d.x[0]), map->virt + adr);
83} 83}
84 84
85/* 85/*
86 * Fast write16 function without the probing check above 86 * Fast write16 function without the probing check above
87 */ 87 */
88static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr) 88static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr)
89{ 89{
90 *(__u16 *) (map->map_priv_1 + adr) = d.x[0]; 90 writew(cpu_to_le16(d.x[0]), map->virt + adr);
91} 91}
92 92
93struct ixp4xx_flash_info { 93struct ixp4xx_flash_info {
@@ -104,28 +104,20 @@ static int ixp4xx_flash_remove(struct device *_dev)
104 struct platform_device *dev = to_platform_device(_dev); 104 struct platform_device *dev = to_platform_device(_dev);
105 struct flash_platform_data *plat = dev->dev.platform_data; 105 struct flash_platform_data *plat = dev->dev.platform_data;
106 struct ixp4xx_flash_info *info = dev_get_drvdata(&dev->dev); 106 struct ixp4xx_flash_info *info = dev_get_drvdata(&dev->dev);
107 map_word d;
108 107
109 dev_set_drvdata(&dev->dev, NULL); 108 dev_set_drvdata(&dev->dev, NULL);
110 109
111 if(!info) 110 if(!info)
112 return 0; 111 return 0;
113 112
114 /*
115 * This is required for a soft reboot to work.
116 */
117 d.x[0] = 0xff;
118 ixp4xx_write16(&info->map, d, 0x55 * 0x2);
119
120 if (info->mtd) { 113 if (info->mtd) {
121 del_mtd_partitions(info->mtd); 114 del_mtd_partitions(info->mtd);
122 map_destroy(info->mtd); 115 map_destroy(info->mtd);
123 } 116 }
124 if (info->map.map_priv_1) 117 if (info->map.virt)
125 iounmap((void *) info->map.map_priv_1); 118 iounmap(info->map.virt);
126 119
127 if (info->partitions) 120 kfree(info->partitions);
128 kfree(info->partitions);
129 121
130 if (info->res) { 122 if (info->res) {
131 release_resource(info->res); 123 release_resource(info->res);
@@ -135,9 +127,6 @@ static int ixp4xx_flash_remove(struct device *_dev)
135 if (plat->exit) 127 if (plat->exit)
136 plat->exit(); 128 plat->exit();
137 129
138 /* Disable flash write */
139 *IXP4XX_EXP_CS0 &= ~IXP4XX_FLASH_WRITABLE;
140
141 return 0; 130 return 0;
142} 131}
143 132
@@ -161,17 +150,11 @@ static int ixp4xx_flash_probe(struct device *_dev)
161 if(!info) { 150 if(!info) {
162 err = -ENOMEM; 151 err = -ENOMEM;
163 goto Error; 152 goto Error;
164 } 153 }
165 memzero(info, sizeof(struct ixp4xx_flash_info)); 154 memzero(info, sizeof(struct ixp4xx_flash_info));
166 155
167 dev_set_drvdata(&dev->dev, info); 156 dev_set_drvdata(&dev->dev, info);
168 157
169 /*
170 * Enable flash write
171 * TODO: Move this out to board specific code
172 */
173 *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
174
175 /* 158 /*
176 * Tell the MTD layer we're not 1:1 mapped so that it does 159 * Tell the MTD layer we're not 1:1 mapped so that it does
177 * not attempt to do a direct access on us. 160 * not attempt to do a direct access on us.
@@ -190,8 +173,8 @@ static int ixp4xx_flash_probe(struct device *_dev)
190 info->map.write = ixp4xx_probe_write16, 173 info->map.write = ixp4xx_probe_write16,
191 info->map.copy_from = ixp4xx_copy_from, 174 info->map.copy_from = ixp4xx_copy_from,
192 175
193 info->res = request_mem_region(dev->resource->start, 176 info->res = request_mem_region(dev->resource->start,
194 dev->resource->end - dev->resource->start + 1, 177 dev->resource->end - dev->resource->start + 1,
195 "IXP4XXFlash"); 178 "IXP4XXFlash");
196 if (!info->res) { 179 if (!info->res) {
197 printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n"); 180 printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n");
@@ -199,9 +182,9 @@ static int ixp4xx_flash_probe(struct device *_dev)
199 goto Error; 182 goto Error;
200 } 183 }
201 184
202 info->map.map_priv_1 = ioremap(dev->resource->start, 185 info->map.virt = ioremap(dev->resource->start,
203 dev->resource->end - dev->resource->start + 1); 186 dev->resource->end - dev->resource->start + 1);
204 if (!info->map.map_priv_1) { 187 if (!info->map.virt) {
205 printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n"); 188 printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n");
206 err = -EIO; 189 err = -EIO;
207 goto Error; 190 goto Error;
@@ -214,7 +197,7 @@ static int ixp4xx_flash_probe(struct device *_dev)
214 goto Error; 197 goto Error;
215 } 198 }
216 info->mtd->owner = THIS_MODULE; 199 info->mtd->owner = THIS_MODULE;
217 200
218 /* Use the fast version */ 201 /* Use the fast version */
219 info->map.write = ixp4xx_write16, 202 info->map.write = ixp4xx_write16,
220 203
@@ -259,4 +242,3 @@ module_exit(ixp4xx_flash_exit);
259MODULE_LICENSE("GPL"); 242MODULE_LICENSE("GPL");
260MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems"); 243MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems");
261MODULE_AUTHOR("Deepak Saxena"); 244MODULE_AUTHOR("Deepak Saxena");
262
diff --git a/drivers/mtd/maps/l440gx.c b/drivers/mtd/maps/l440gx.c
index b08668212ab7..851bf9576052 100644
--- a/drivers/mtd/maps/l440gx.c
+++ b/drivers/mtd/maps/l440gx.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: l440gx.c,v 1.17 2004/11/28 09:40:39 dwmw2 Exp $ 2 * $Id: l440gx.c,v 1.18 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * BIOS Flash chip on Intel 440GX board. 4 * BIOS Flash chip on Intel 440GX board.
5 * 5 *
@@ -49,7 +49,7 @@ static struct map_info l440gx_map = {
49 .bankwidth = BUSWIDTH, 49 .bankwidth = BUSWIDTH,
50 .phys = WINDOW_ADDR, 50 .phys = WINDOW_ADDR,
51#if 0 51#if 0
52 /* FIXME verify that this is the 52 /* FIXME verify that this is the
53 * appripriate code for vpp enable/disable 53 * appripriate code for vpp enable/disable
54 */ 54 */
55 .set_vpp = l440gx_set_vpp 55 .set_vpp = l440gx_set_vpp
@@ -62,10 +62,10 @@ static int __init init_l440gx(void)
62 struct resource *pm_iobase; 62 struct resource *pm_iobase;
63 __u16 word; 63 __u16 word;
64 64
65 dev = pci_find_device(PCI_VENDOR_ID_INTEL, 65 dev = pci_find_device(PCI_VENDOR_ID_INTEL,
66 PCI_DEVICE_ID_INTEL_82371AB_0, NULL); 66 PCI_DEVICE_ID_INTEL_82371AB_0, NULL);
67 67
68 pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL, 68 pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
69 PCI_DEVICE_ID_INTEL_82371AB_3, NULL); 69 PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
70 70
71 if (!dev || !pm_dev) { 71 if (!dev || !pm_dev) {
@@ -82,10 +82,10 @@ static int __init init_l440gx(void)
82 simple_map_init(&l440gx_map); 82 simple_map_init(&l440gx_map);
83 printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.virt); 83 printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.virt);
84 84
85 /* Setup the pm iobase resource 85 /* Setup the pm iobase resource
86 * This code should move into some kind of generic bridge 86 * This code should move into some kind of generic bridge
87 * driver but for the moment I'm content with getting the 87 * driver but for the moment I'm content with getting the
88 * allocation correct. 88 * allocation correct.
89 */ 89 */
90 pm_iobase = &pm_dev->resource[PIIXE_IOBASE_RESOURCE]; 90 pm_iobase = &pm_dev->resource[PIIXE_IOBASE_RESOURCE];
91 if (!(pm_iobase->flags & IORESOURCE_IO)) { 91 if (!(pm_iobase->flags & IORESOURCE_IO)) {
@@ -110,7 +110,7 @@ static int __init init_l440gx(void)
110 /* Set the iobase */ 110 /* Set the iobase */
111 iobase = pm_iobase->start; 111 iobase = pm_iobase->start;
112 pci_write_config_dword(pm_dev, 0x40, iobase | 1); 112 pci_write_config_dword(pm_dev, 0x40, iobase | 1);
113 113
114 114
115 /* Set XBCS# */ 115 /* Set XBCS# */
116 pci_read_config_word(dev, 0x4e, &word); 116 pci_read_config_word(dev, 0x4e, &word);
@@ -122,7 +122,7 @@ static int __init init_l440gx(void)
122 122
123 /* Enable the gate on the WE line */ 123 /* Enable the gate on the WE line */
124 outb(inb(TRIBUF_PORT) & ~1, TRIBUF_PORT); 124 outb(inb(TRIBUF_PORT) & ~1, TRIBUF_PORT);
125 125
126 printk(KERN_NOTICE "Enabled WE line to L440GX BIOS flash chip.\n"); 126 printk(KERN_NOTICE "Enabled WE line to L440GX BIOS flash chip.\n");
127 127
128 mymtd = do_map_probe("jedec_probe", &l440gx_map); 128 mymtd = do_map_probe("jedec_probe", &l440gx_map);
@@ -145,7 +145,7 @@ static void __exit cleanup_l440gx(void)
145{ 145{
146 del_mtd_device(mymtd); 146 del_mtd_device(mymtd);
147 map_destroy(mymtd); 147 map_destroy(mymtd);
148 148
149 iounmap(l440gx_map.virt); 149 iounmap(l440gx_map.virt);
150} 150}
151 151
diff --git a/drivers/mtd/maps/lubbock-flash.c b/drivers/mtd/maps/lubbock-flash.c
index 2337e0c46750..1aa0447c5e66 100644
--- a/drivers/mtd/maps/lubbock-flash.c
+++ b/drivers/mtd/maps/lubbock-flash.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * $Id: lubbock-flash.c,v 1.19 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: lubbock-flash.c,v 1.21 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Map driver for the Lubbock developer platform. 4 * Map driver for the Lubbock developer platform.
5 * 5 *
6 * Author: Nicolas Pitre 6 * Author: Nicolas Pitre
7 * Copyright: (C) 2001 MontaVista Software Inc. 7 * Copyright: (C) 2001 MontaVista Software Inc.
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
@@ -76,7 +76,7 @@ static int __init init_lubbock(void)
76 int flashboot = (LUB_CONF_SWITCHES & 1); 76 int flashboot = (LUB_CONF_SWITCHES & 1);
77 int ret = 0, i; 77 int ret = 0, i;
78 78
79 lubbock_maps[0].bankwidth = lubbock_maps[1].bankwidth = 79 lubbock_maps[0].bankwidth = lubbock_maps[1].bankwidth =
80 (BOOT_DEF & 1) ? 2 : 4; 80 (BOOT_DEF & 1) ? 2 : 4;
81 81
82 /* Compensate for the nROMBT switch which swaps the flash banks */ 82 /* Compensate for the nROMBT switch which swaps the flash banks */
@@ -100,11 +100,11 @@ static int __init init_lubbock(void)
100 simple_map_init(&lubbock_maps[i]); 100 simple_map_init(&lubbock_maps[i]);
101 101
102 printk(KERN_NOTICE "Probing %s at physical address 0x%08lx (%d-bit bankwidth)\n", 102 printk(KERN_NOTICE "Probing %s at physical address 0x%08lx (%d-bit bankwidth)\n",
103 lubbock_maps[i].name, lubbock_maps[i].phys, 103 lubbock_maps[i].name, lubbock_maps[i].phys,
104 lubbock_maps[i].bankwidth * 8); 104 lubbock_maps[i].bankwidth * 8);
105 105
106 mymtds[i] = do_map_probe("cfi_probe", &lubbock_maps[i]); 106 mymtds[i] = do_map_probe("cfi_probe", &lubbock_maps[i]);
107 107
108 if (!mymtds[i]) { 108 if (!mymtds[i]) {
109 iounmap((void *)lubbock_maps[i].virt); 109 iounmap((void *)lubbock_maps[i].virt);
110 if (lubbock_maps[i].cached) 110 if (lubbock_maps[i].cached)
@@ -124,7 +124,7 @@ static int __init init_lubbock(void)
124 124
125 if (!mymtds[0] && !mymtds[1]) 125 if (!mymtds[0] && !mymtds[1])
126 return ret; 126 return ret;
127 127
128 for (i = 0; i < 2; i++) { 128 for (i = 0; i < 2; i++) {
129 if (!mymtds[i]) { 129 if (!mymtds[i]) {
130 printk(KERN_WARNING "%s is absent. Skipping\n", lubbock_maps[i].name); 130 printk(KERN_WARNING "%s is absent. Skipping\n", lubbock_maps[i].name);
@@ -151,15 +151,14 @@ static void __exit cleanup_lubbock(void)
151 if (nr_parsed_parts[i] || !i) 151 if (nr_parsed_parts[i] || !i)
152 del_mtd_partitions(mymtds[i]); 152 del_mtd_partitions(mymtds[i]);
153 else 153 else
154 del_mtd_device(mymtds[i]); 154 del_mtd_device(mymtds[i]);
155 155
156 map_destroy(mymtds[i]); 156 map_destroy(mymtds[i]);
157 iounmap((void *)lubbock_maps[i].virt); 157 iounmap((void *)lubbock_maps[i].virt);
158 if (lubbock_maps[i].cached) 158 if (lubbock_maps[i].cached)
159 iounmap(lubbock_maps[i].cached); 159 iounmap(lubbock_maps[i].cached);
160 160
161 if (parsed_parts[i]) 161 kfree(parsed_parts[i]);
162 kfree(parsed_parts[i]);
163 } 162 }
164} 163}
165 164
diff --git a/drivers/mtd/maps/mainstone-flash.c b/drivers/mtd/maps/mainstone-flash.c
index da0f8a692628..eaa4bbb868a3 100644
--- a/drivers/mtd/maps/mainstone-flash.c
+++ b/drivers/mtd/maps/mainstone-flash.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * Author: Nicolas Pitre 6 * Author: Nicolas Pitre
7 * Copyright: (C) 2001 MontaVista Software Inc. 7 * Copyright: (C) 2001 MontaVista Software Inc.
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
@@ -91,27 +91,27 @@ static int __init init_mainstone(void)
91 mainstone_maps[i].virt = ioremap(mainstone_maps[i].phys, 91 mainstone_maps[i].virt = ioremap(mainstone_maps[i].phys,
92 WINDOW_SIZE); 92 WINDOW_SIZE);
93 if (!mainstone_maps[i].virt) { 93 if (!mainstone_maps[i].virt) {
94 printk(KERN_WARNING "Failed to ioremap %s\n", 94 printk(KERN_WARNING "Failed to ioremap %s\n",
95 mainstone_maps[i].name); 95 mainstone_maps[i].name);
96 if (!ret) 96 if (!ret)
97 ret = -ENOMEM; 97 ret = -ENOMEM;
98 continue; 98 continue;
99 } 99 }
100 mainstone_maps[i].cached = 100 mainstone_maps[i].cached =
101 ioremap_cached(mainstone_maps[i].phys, WINDOW_SIZE); 101 ioremap_cached(mainstone_maps[i].phys, WINDOW_SIZE);
102 if (!mainstone_maps[i].cached) 102 if (!mainstone_maps[i].cached)
103 printk(KERN_WARNING "Failed to ioremap cached %s\n", 103 printk(KERN_WARNING "Failed to ioremap cached %s\n",
104 mainstone_maps[i].name); 104 mainstone_maps[i].name);
105 simple_map_init(&mainstone_maps[i]); 105 simple_map_init(&mainstone_maps[i]);
106 106
107 printk(KERN_NOTICE 107 printk(KERN_NOTICE
108 "Probing %s at physical address 0x%08lx" 108 "Probing %s at physical address 0x%08lx"
109 " (%d-bit bankwidth)\n", 109 " (%d-bit bankwidth)\n",
110 mainstone_maps[i].name, mainstone_maps[i].phys, 110 mainstone_maps[i].name, mainstone_maps[i].phys,
111 mainstone_maps[i].bankwidth * 8); 111 mainstone_maps[i].bankwidth * 8);
112 112
113 mymtds[i] = do_map_probe("cfi_probe", &mainstone_maps[i]); 113 mymtds[i] = do_map_probe("cfi_probe", &mainstone_maps[i]);
114 114
115 if (!mymtds[i]) { 115 if (!mymtds[i]) {
116 iounmap((void *)mainstone_maps[i].virt); 116 iounmap((void *)mainstone_maps[i].virt);
117 if (mainstone_maps[i].cached) 117 if (mainstone_maps[i].cached)
@@ -131,21 +131,21 @@ static int __init init_mainstone(void)
131 131
132 if (!mymtds[0] && !mymtds[1]) 132 if (!mymtds[0] && !mymtds[1])
133 return ret; 133 return ret;
134 134
135 for (i = 0; i < 2; i++) { 135 for (i = 0; i < 2; i++) {
136 if (!mymtds[i]) { 136 if (!mymtds[i]) {
137 printk(KERN_WARNING "%s is absent. Skipping\n", 137 printk(KERN_WARNING "%s is absent. Skipping\n",
138 mainstone_maps[i].name); 138 mainstone_maps[i].name);
139 } else if (nr_parsed_parts[i]) { 139 } else if (nr_parsed_parts[i]) {
140 add_mtd_partitions(mymtds[i], parsed_parts[i], 140 add_mtd_partitions(mymtds[i], parsed_parts[i],
141 nr_parsed_parts[i]); 141 nr_parsed_parts[i]);
142 } else if (!i) { 142 } else if (!i) {
143 printk("Using static partitions on %s\n", 143 printk("Using static partitions on %s\n",
144 mainstone_maps[i].name); 144 mainstone_maps[i].name);
145 add_mtd_partitions(mymtds[i], mainstone_partitions, 145 add_mtd_partitions(mymtds[i], mainstone_partitions,
146 ARRAY_SIZE(mainstone_partitions)); 146 ARRAY_SIZE(mainstone_partitions));
147 } else { 147 } else {
148 printk("Registering %s as whole device\n", 148 printk("Registering %s as whole device\n",
149 mainstone_maps[i].name); 149 mainstone_maps[i].name);
150 add_mtd_device(mymtds[i]); 150 add_mtd_device(mymtds[i]);
151 } 151 }
diff --git a/drivers/mtd/maps/mbx860.c b/drivers/mtd/maps/mbx860.c
index c5c6901a4763..06b118727846 100644
--- a/drivers/mtd/maps/mbx860.c
+++ b/drivers/mtd/maps/mbx860.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * $Id: mbx860.c,v 1.8 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: mbx860.c,v 1.9 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Handle mapping of the flash on MBX860 boards 4 * Handle mapping of the flash on MBX860 boards
5 * 5 *
6 * Author: Anton Todorov 6 * Author: Anton Todorov
7 * Copyright: (C) 2001 Emness Technology 7 * Copyright: (C) 2001 Emness Technology
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
@@ -46,7 +46,7 @@ static struct mtd_partition partition_info[]={
46 { .name = "MBX flash APPLICATION partition", 46 { .name = "MBX flash APPLICATION partition",
47 .offset = (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 } 47 .offset = (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 }
48}; 48};
49 49
50 50
51static struct mtd_info *mymtd; 51static struct mtd_info *mymtd;
52 52
diff --git a/drivers/mtd/maps/mtx-1_flash.c b/drivers/mtd/maps/mtx-1_flash.c
new file mode 100644
index 000000000000..d1e66e186746
--- /dev/null
+++ b/drivers/mtd/maps/mtx-1_flash.c
@@ -0,0 +1,96 @@
1/*
2 * Flash memory access on 4G Systems MTX-1 boards
3 *
4 * $Id: mtx-1_flash.c,v 1.2 2005/11/07 11:14:27 gleixner Exp $
5 *
6 * (C) 2005 Bruno Randolf <bruno.randolf@4g-systems.biz>
7 * (C) 2005 Jörn Engel <joern@wohnheim.fh-wedel.de>
8 *
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/types.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16
17#include <linux/mtd/mtd.h>
18#include <linux/mtd/map.h>
19#include <linux/mtd/partitions.h>
20
21#include <asm/io.h>
22
23static struct map_info mtx1_map = {
24 .name = "MTX-1 flash",
25 .bankwidth = 4,
26 .size = 0x2000000,
27 .phys = 0x1E000000,
28};
29
30static struct mtd_partition mtx1_partitions[] = {
31 {
32 .name = "filesystem",
33 .size = 0x01C00000,
34 .offset = 0,
35 },{
36 .name = "yamon",
37 .size = 0x00100000,
38 .offset = MTDPART_OFS_APPEND,
39 .mask_flags = MTD_WRITEABLE,
40 },{
41 .name = "kernel",
42 .size = 0x002c0000,
43 .offset = MTDPART_OFS_APPEND,
44 },{
45 .name = "yamon env",
46 .size = 0x00040000,
47 .offset = MTDPART_OFS_APPEND,
48 }
49};
50
51static struct mtd_info *mtx1_mtd;
52
53int __init mtx1_mtd_init(void)
54{
55 int ret = -ENXIO;
56
57 simple_map_init(&mtx1_map);
58
59 mtx1_map.virt = ioremap(mtx1_map.phys, mtx1_map.size);
60 if (!mtx1_map.virt)
61 return -EIO;
62
63 mtx1_mtd = do_map_probe("cfi_probe", &mtx1_map);
64 if (!mtx1_mtd)
65 goto err;
66
67 mtx1_mtd->owner = THIS_MODULE;
68
69 ret = add_mtd_partitions(mtx1_mtd, mtx1_partitions,
70 ARRAY_SIZE(mtx1_partitions));
71 if (ret)
72 goto err;
73
74 return 0;
75
76err:
77 iounmap(mtx1_map.virt);
78 return ret;
79}
80
81static void __exit mtx1_mtd_cleanup(void)
82{
83 if (mtx1_mtd) {
84 del_mtd_partitions(mtx1_mtd);
85 map_destroy(mtx1_mtd);
86 }
87 if (mtx1_map.virt)
88 iounmap(mtx1_map.virt);
89}
90
91module_init(mtx1_mtd_init);
92module_exit(mtx1_mtd_cleanup);
93
94MODULE_AUTHOR("Bruno Randolf <bruno.randolf@4g-systems.biz>");
95MODULE_DESCRIPTION("MTX-1 flash map");
96MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/netsc520.c b/drivers/mtd/maps/netsc520.c
index ab7e6358d281..33060a315722 100644
--- a/drivers/mtd/maps/netsc520.c
+++ b/drivers/mtd/maps/netsc520.c
@@ -3,7 +3,7 @@
3 * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com) 3 * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com)
4 * based on sc520cdp.c by Sysgo Real-Time Solutions GmbH 4 * based on sc520cdp.c by Sysgo Real-Time Solutions GmbH
5 * 5 *
6 * $Id: netsc520.c,v 1.13 2004/11/28 09:40:40 dwmw2 Exp $ 6 * $Id: netsc520.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -38,7 +38,7 @@
38** The single, 16 megabyte flash bank is divided into four virtual 38** The single, 16 megabyte flash bank is divided into four virtual
39** partitions. The first partition is 768 KiB and is intended to 39** partitions. The first partition is 768 KiB and is intended to
40** store the kernel image loaded by the bootstrap loader. The second 40** store the kernel image loaded by the bootstrap loader. The second
41** partition is 256 KiB and holds the BIOS image. The third 41** partition is 256 KiB and holds the BIOS image. The third
42** partition is 14.5 MiB and is intended for the flash file system 42** partition is 14.5 MiB and is intended for the flash file system
43** image. The last partition is 512 KiB and contains another copy 43** image. The last partition is 512 KiB and contains another copy
44** of the BIOS image and the reset vector. 44** of the BIOS image and the reset vector.
@@ -51,28 +51,28 @@
51** recoverable afterwards. 51** recoverable afterwards.
52*/ 52*/
53 53
54/* partition_info gives details on the logical partitions that the split the 54/* partition_info gives details on the logical partitions that the split the
55 * single flash device into. If the size if zero we use up to the end of the 55 * single flash device into. If the size if zero we use up to the end of the
56 * device. */ 56 * device. */
57static struct mtd_partition partition_info[]={ 57static struct mtd_partition partition_info[]={
58 { 58 {
59 .name = "NetSc520 boot kernel", 59 .name = "NetSc520 boot kernel",
60 .offset = 0, 60 .offset = 0,
61 .size = 0xc0000 61 .size = 0xc0000
62 }, 62 },
63 { 63 {
64 .name = "NetSc520 Low BIOS", 64 .name = "NetSc520 Low BIOS",
65 .offset = 0xc0000, 65 .offset = 0xc0000,
66 .size = 0x40000 66 .size = 0x40000
67 }, 67 },
68 { 68 {
69 .name = "NetSc520 file system", 69 .name = "NetSc520 file system",
70 .offset = 0x100000, 70 .offset = 0x100000,
71 .size = 0xe80000 71 .size = 0xe80000
72 }, 72 },
73 { 73 {
74 .name = "NetSc520 High BIOS", 74 .name = "NetSc520 High BIOS",
75 .offset = 0xf80000, 75 .offset = 0xf80000,
76 .size = 0x80000 76 .size = 0x80000
77 }, 77 },
78}; 78};
@@ -114,7 +114,7 @@ static int __init init_netsc520(void)
114 iounmap(netsc520_map.virt); 114 iounmap(netsc520_map.virt);
115 return -ENXIO; 115 return -ENXIO;
116 } 116 }
117 117
118 mymtd->owner = THIS_MODULE; 118 mymtd->owner = THIS_MODULE;
119 add_mtd_partitions( mymtd, partition_info, NUM_PARTITIONS ); 119 add_mtd_partitions( mymtd, partition_info, NUM_PARTITIONS );
120 return 0; 120 return 0;
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
index 61be5a4148c9..f00ee7e54dba 100644
--- a/drivers/mtd/maps/nettel.c
+++ b/drivers/mtd/maps/nettel.c
@@ -6,7 +6,7 @@
6 * (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com) 6 * (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
7 * (C) Copyright 2001-2002, SnapGear (www.snapgear.com) 7 * (C) Copyright 2001-2002, SnapGear (www.snapgear.com)
8 * 8 *
9 * $Id: nettel.c,v 1.10 2005/01/05 17:11:29 dwmw2 Exp $ 9 * $Id: nettel.c,v 1.11 2005/11/07 11:14:27 gleixner Exp $
10 */ 10 */
11 11
12/****************************************************************************/ 12/****************************************************************************/
@@ -143,7 +143,7 @@ static int nettel_reboot_notifier(struct notifier_block *nb, unsigned long val,
143{ 143{
144 struct cfi_private *cfi = nettel_intel_map.fldrv_priv; 144 struct cfi_private *cfi = nettel_intel_map.fldrv_priv;
145 unsigned long b; 145 unsigned long b;
146 146
147 /* Make sure all FLASH chips are put back into read mode */ 147 /* Make sure all FLASH chips are put back into read mode */
148 for (b = 0; (b < nettel_intel_partitions[3].size); b += 0x100000) { 148 for (b = 0; (b < nettel_intel_partitions[3].size); b += 0x100000) {
149 cfi_send_gen_cmd(0xff, 0x55, b, &nettel_intel_map, cfi, 149 cfi_send_gen_cmd(0xff, 0x55, b, &nettel_intel_map, cfi,
@@ -199,7 +199,7 @@ int nettel_eraseconfig(void)
199 199
200 schedule(); /* Wait for erase to finish. */ 200 schedule(); /* Wait for erase to finish. */
201 remove_wait_queue(&wait_q, &wait); 201 remove_wait_queue(&wait_q, &wait);
202 202
203 put_mtd_device(mtd); 203 put_mtd_device(mtd);
204 } 204 }
205 205
@@ -430,7 +430,7 @@ int __init nettel_init(void)
430 nettel_intel_partitions[1].size = (intel0size + intel1size) - 430 nettel_intel_partitions[1].size = (intel0size + intel1size) -
431 (1024*1024 + intel_mtd->erasesize); 431 (1024*1024 + intel_mtd->erasesize);
432 nettel_intel_partitions[3].size = intel0size + intel1size; 432 nettel_intel_partitions[3].size = intel0size + intel1size;
433 nettel_intel_partitions[4].offset = 433 nettel_intel_partitions[4].offset =
434 (intel0size + intel1size) - intel_mtd->erasesize; 434 (intel0size + intel1size) - intel_mtd->erasesize;
435 nettel_intel_partitions[4].size = intel_mtd->erasesize; 435 nettel_intel_partitions[4].size = intel_mtd->erasesize;
436 nettel_intel_partitions[5].offset = 436 nettel_intel_partitions[5].offset =
diff --git a/drivers/mtd/maps/ocelot.c b/drivers/mtd/maps/ocelot.c
index 82c3070678c5..6977963d7897 100644
--- a/drivers/mtd/maps/ocelot.c
+++ b/drivers/mtd/maps/ocelot.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ocelot.c,v 1.16 2005/01/05 18:05:13 dwmw2 Exp $ 2 * $Id: ocelot.c,v 1.17 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Flash on Momenco Ocelot 4 * Flash on Momenco Ocelot
5 */ 5 */
@@ -31,7 +31,7 @@ static void ocelot_ram_write(struct mtd_info *mtd, loff_t to, size_t len, size_t
31 struct map_info *map = mtd->priv; 31 struct map_info *map = mtd->priv;
32 size_t done = 0; 32 size_t done = 0;
33 33
34 /* If we use memcpy, it does word-wide writes. Even though we told the 34 /* If we use memcpy, it does word-wide writes. Even though we told the
35 GT64120A that it's an 8-bit wide region, word-wide writes don't work. 35 GT64120A that it's an 8-bit wide region, word-wide writes don't work.
36 We end up just writing the first byte of the four to all four bytes. 36 We end up just writing the first byte of the four to all four bytes.
37 So we have this loop instead */ 37 So we have this loop instead */
@@ -68,7 +68,7 @@ static int __init init_ocelot_maps(void)
68 int nr_parts; 68 int nr_parts;
69 unsigned char brd_status; 69 unsigned char brd_status;
70 70
71 printk(KERN_INFO "Momenco Ocelot MTD mappings: Flash 0x%x at 0x%x, NVRAM 0x%x at 0x%x\n", 71 printk(KERN_INFO "Momenco Ocelot MTD mappings: Flash 0x%x at 0x%x, NVRAM 0x%x at 0x%x\n",
72 FLASH_WINDOW_SIZE, FLASH_WINDOW_ADDR, NVRAM_WINDOW_SIZE, NVRAM_WINDOW_ADDR); 72 FLASH_WINDOW_SIZE, FLASH_WINDOW_ADDR, NVRAM_WINDOW_SIZE, NVRAM_WINDOW_ADDR);
73 73
74 /* First check whether the flash jumper is present */ 74 /* First check whether the flash jumper is present */
@@ -138,8 +138,8 @@ static int __init init_ocelot_maps(void)
138 add_mtd_device(flash_mtd); 138 add_mtd_device(flash_mtd);
139 139
140 return 0; 140 return 0;
141 141
142 fail3: 142 fail3:
143 iounmap((void *)ocelot_flash_map.virt); 143 iounmap((void *)ocelot_flash_map.virt);
144 if (ocelot_flash_map.cached) 144 if (ocelot_flash_map.cached)
145 iounmap((void *)ocelot_flash_map.cached); 145 iounmap((void *)ocelot_flash_map.cached);
diff --git a/drivers/mtd/maps/octagon-5066.c b/drivers/mtd/maps/octagon-5066.c
index e5ff83de420e..a6642db3d325 100644
--- a/drivers/mtd/maps/octagon-5066.c
+++ b/drivers/mtd/maps/octagon-5066.c
@@ -1,12 +1,12 @@
1// $Id: octagon-5066.c,v 1.26 2004/07/12 22:38:29 dwmw2 Exp $ 1// $Id: octagon-5066.c,v 1.28 2005/11/07 11:14:27 gleixner Exp $
2/* ###################################################################### 2/* ######################################################################
3 3
4 Octagon 5066 MTD Driver. 4 Octagon 5066 MTD Driver.
5 5
6 The Octagon 5066 is a SBC based on AMD's 586-WB running at 133 MHZ. It 6 The Octagon 5066 is a SBC based on AMD's 586-WB running at 133 MHZ. It
7 comes with a builtin AMD 29F016 flash chip and a socketed EEPROM that 7 comes with a builtin AMD 29F016 flash chip and a socketed EEPROM that
8 is replacable by flash. Both units are mapped through a multiplexer 8 is replacable by flash. Both units are mapped through a multiplexer
9 into a 32k memory window at 0xe8000. The control register for the 9 into a 32k memory window at 0xe8000. The control register for the
10 multiplexing unit is located at IO 0x208 with a bit map of 10 multiplexing unit is located at IO 0x208 with a bit map of
11 0-5 Page Selection in 32k increments 11 0-5 Page Selection in 32k increments
12 6-7 Device selection: 12 6-7 Device selection:
@@ -14,14 +14,14 @@
14 01 SSD 0 (Socket) 14 01 SSD 0 (Socket)
15 10 SSD 1 (Flash chip) 15 10 SSD 1 (Flash chip)
16 11 undefined 16 11 undefined
17 17
18 On each SSD, the first 128k is reserved for use by the bios 18 On each SSD, the first 128k is reserved for use by the bios
19 (actually it IS the bios..) This only matters if you are booting off the 19 (actually it IS the bios..) This only matters if you are booting off the
20 flash, you must not put a file system starting there. 20 flash, you must not put a file system starting there.
21 21
22 The driver tries to do a detection algorithm to guess what sort of devices 22 The driver tries to do a detection algorithm to guess what sort of devices
23 are plugged into the sockets. 23 are plugged into the sockets.
24 24
25 ##################################################################### */ 25 ##################################################################### */
26 26
27#include <linux/module.h> 27#include <linux/module.h>
@@ -56,7 +56,7 @@ static void __oct5066_page(struct map_info *map, __u8 byte)
56static inline void oct5066_page(struct map_info *map, unsigned long ofs) 56static inline void oct5066_page(struct map_info *map, unsigned long ofs)
57{ 57{
58 __u8 byte = map->map_priv_1 | (ofs >> WINDOW_SHIFT); 58 __u8 byte = map->map_priv_1 | (ofs >> WINDOW_SHIFT);
59 59
60 if (page_n_dev != byte) 60 if (page_n_dev != byte)
61 __oct5066_page(map, byte); 61 __oct5066_page(map, byte);
62} 62}
@@ -78,7 +78,7 @@ static void oct5066_copy_from(struct map_info *map, void *to, unsigned long from
78 unsigned long thislen = len; 78 unsigned long thislen = len;
79 if (len > (WINDOW_LENGTH - (from & WINDOW_MASK))) 79 if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
80 thislen = WINDOW_LENGTH-(from & WINDOW_MASK); 80 thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
81 81
82 spin_lock(&oct5066_spin); 82 spin_lock(&oct5066_spin);
83 oct5066_page(map, from); 83 oct5066_page(map, from);
84 memcpy_fromio(to, iomapadr + from, thislen); 84 memcpy_fromio(to, iomapadr + from, thislen);
@@ -103,7 +103,7 @@ static void oct5066_copy_to(struct map_info *map, unsigned long to, const void *
103 unsigned long thislen = len; 103 unsigned long thislen = len;
104 if (len > (WINDOW_LENGTH - (to & WINDOW_MASK))) 104 if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
105 thislen = WINDOW_LENGTH-(to & WINDOW_MASK); 105 thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
106 106
107 spin_lock(&oct5066_spin); 107 spin_lock(&oct5066_spin);
108 oct5066_page(map, to); 108 oct5066_page(map, to);
109 memcpy_toio(iomapadr + to, from, thislen); 109 memcpy_toio(iomapadr + to, from, thislen);
@@ -144,7 +144,7 @@ static struct mtd_info *oct5066_mtd[2] = {NULL, NULL};
144// OctProbe - Sense if this is an octagon card 144// OctProbe - Sense if this is an octagon card
145// --------------------------------------------------------------------- 145// ---------------------------------------------------------------------
146/* Perform a simple validity test, we map the window select SSD0 and 146/* Perform a simple validity test, we map the window select SSD0 and
147 change pages while monitoring the window. A change in the window, 147 change pages while monitoring the window. A change in the window,
148 controlled by the PAGE_IO port is a functioning 5066 board. This will 148 controlled by the PAGE_IO port is a functioning 5066 board. This will
149 fail if the thing in the socket is set to a uniform value. */ 149 fail if the thing in the socket is set to a uniform value. */
150static int __init OctProbe(void) 150static int __init OctProbe(void)
@@ -161,13 +161,13 @@ static int __init OctProbe(void)
161 Values[I%10] = readl(iomapadr); 161 Values[I%10] = readl(iomapadr);
162 if (I > 0 && Values[I%10] == Values[0]) 162 if (I > 0 && Values[I%10] == Values[0])
163 return -EAGAIN; 163 return -EAGAIN;
164 } 164 }
165 else 165 else
166 { 166 {
167 // Make sure we get the same values on the second pass 167 // Make sure we get the same values on the second pass
168 if (Values[I%10] != readl(iomapadr)) 168 if (Values[I%10] != readl(iomapadr))
169 return -EAGAIN; 169 return -EAGAIN;
170 } 170 }
171 } 171 }
172 return 0; 172 return 0;
173} 173}
@@ -207,11 +207,11 @@ int __init init_oct5066(void)
207 ret = -EAGAIN; 207 ret = -EAGAIN;
208 goto out_unmap; 208 goto out_unmap;
209 } 209 }
210 210
211 // Print out our little header.. 211 // Print out our little header..
212 printk("Octagon 5066 SSD IO:0x%x MEM:0x%x-0x%x\n",PAGE_IO,WINDOW_START, 212 printk("Octagon 5066 SSD IO:0x%x MEM:0x%x-0x%x\n",PAGE_IO,WINDOW_START,
213 WINDOW_START+WINDOW_LENGTH); 213 WINDOW_START+WINDOW_LENGTH);
214 214
215 for (i=0; i<2; i++) { 215 for (i=0; i<2; i++) {
216 oct5066_mtd[i] = do_map_probe("cfi_probe", &oct5066_map[i]); 216 oct5066_mtd[i] = do_map_probe("cfi_probe", &oct5066_map[i]);
217 if (!oct5066_mtd[i]) 217 if (!oct5066_mtd[i])
@@ -225,11 +225,11 @@ int __init init_oct5066(void)
225 add_mtd_device(oct5066_mtd[i]); 225 add_mtd_device(oct5066_mtd[i]);
226 } 226 }
227 } 227 }
228 228
229 if (!oct5066_mtd[0] && !oct5066_mtd[1]) { 229 if (!oct5066_mtd[0] && !oct5066_mtd[1]) {
230 cleanup_oct5066(); 230 cleanup_oct5066();
231 return -ENXIO; 231 return -ENXIO;
232 } 232 }
233 233
234 return 0; 234 return 0;
235 235
diff --git a/drivers/mtd/maps/omap-toto-flash.c b/drivers/mtd/maps/omap-toto-flash.c
index da36e8dddd17..dc3765270057 100644
--- a/drivers/mtd/maps/omap-toto-flash.c
+++ b/drivers/mtd/maps/omap-toto-flash.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * (C) 2002 MontVista Software, Inc. 6 * (C) 2002 MontVista Software, Inc.
7 * 7 *
8 * $Id: omap-toto-flash.c,v 1.3 2004/09/16 23:27:13 gleixner Exp $ 8 * $Id: omap-toto-flash.c,v 1.5 2005/11/07 11:14:27 gleixner Exp $
9 */ 9 */
10 10
11#include <linux/config.h> 11#include <linux/config.h>
@@ -38,7 +38,7 @@ static struct map_info omap_toto_map_flash = {
38 .virt = (void __iomem *)OMAP_TOTO_FLASH_BASE, 38 .virt = (void __iomem *)OMAP_TOTO_FLASH_BASE,
39}; 39};
40 40
41 41
42static struct mtd_partition toto_flash_partitions[] = { 42static struct mtd_partition toto_flash_partitions[] = {
43 { 43 {
44 .name = "BootLoader", 44 .name = "BootLoader",
@@ -54,21 +54,21 @@ static struct mtd_partition toto_flash_partitions[] = {
54 .name = "EnvArea", /* bottom 64KiB for env vars */ 54 .name = "EnvArea", /* bottom 64KiB for env vars */
55 .size = MTDPART_SIZ_FULL, 55 .size = MTDPART_SIZ_FULL,
56 .offset = MTDPART_OFS_APPEND, 56 .offset = MTDPART_OFS_APPEND,
57 } 57 }
58}; 58};
59 59
60static struct mtd_partition *parsed_parts; 60static struct mtd_partition *parsed_parts;
61 61
62static struct mtd_info *flash_mtd; 62static struct mtd_info *flash_mtd;
63 63
64static int __init init_flash (void) 64static int __init init_flash (void)
65{ 65{
66 66
67 struct mtd_partition *parts; 67 struct mtd_partition *parts;
68 int nb_parts = 0; 68 int nb_parts = 0;
69 int parsed_nr_parts = 0; 69 int parsed_nr_parts = 0;
70 const char *part_type; 70 const char *part_type;
71 71
72 /* 72 /*
73 * Static partition definition selection 73 * Static partition definition selection
74 */ 74 */
@@ -89,7 +89,7 @@ static int __init init_flash (void)
89 flash_mtd = do_map_probe("jedec_probe", &omap_toto_map_flash); 89 flash_mtd = do_map_probe("jedec_probe", &omap_toto_map_flash);
90 if (!flash_mtd) 90 if (!flash_mtd)
91 return -ENXIO; 91 return -ENXIO;
92 92
93 if (parsed_nr_parts > 0) { 93 if (parsed_nr_parts > 0) {
94 parts = parsed_parts; 94 parts = parsed_parts;
95 nb_parts = parsed_nr_parts; 95 nb_parts = parsed_nr_parts;
@@ -108,8 +108,8 @@ static int __init init_flash (void)
108 } 108 }
109 return 0; 109 return 0;
110} 110}
111 111
112int __init omap_toto_mtd_init(void) 112int __init omap_toto_mtd_init(void)
113{ 113{
114 int status; 114 int status;
115 115
@@ -119,13 +119,12 @@ int __init omap_toto_mtd_init(void)
119 return status; 119 return status;
120} 120}
121 121
122static void __exit omap_toto_mtd_cleanup(void) 122static void __exit omap_toto_mtd_cleanup(void)
123{ 123{
124 if (flash_mtd) { 124 if (flash_mtd) {
125 del_mtd_partitions(flash_mtd); 125 del_mtd_partitions(flash_mtd);
126 map_destroy(flash_mtd); 126 map_destroy(flash_mtd);
127 if (parsed_parts) 127 kfree(parsed_parts);
128 kfree(parsed_parts);
129 } 128 }
130} 129}
131 130
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
index 7f370bb794fe..fd3b4a5fc207 100644
--- a/drivers/mtd/maps/omap_nor.c
+++ b/drivers/mtd/maps/omap_nor.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2001-2002 MontaVista Software Inc. 4 * Copyright (C) 2001-2002 MontaVista Software Inc.
5 * Copyright (C) 2003-2004 Texas Instruments 5 * Copyright (C) 2003-2004 Texas Instruments
6 * Copyright (C) 2004 Nokia Corporation 6 * Copyright (C) 2004 Nokia Corporation
7 * 7 *
8 * Assembled using driver code copyright the companies above 8 * Assembled using driver code copyright the companies above
9 * and written by David Brownell, Jian Zhang <jzhang@ti.com>, 9 * and written by David Brownell, Jian Zhang <jzhang@ti.com>,
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
index d9c64e99ee32..8b3570b09095 100644
--- a/drivers/mtd/maps/pci.c
+++ b/drivers/mtd/maps/pci.c
@@ -7,8 +7,8 @@
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 * 9 *
10 * $Id: pci.c,v 1.10 2005/03/18 14:04:35 gleixner Exp $ 10 * $Id: pci.c,v 1.13 2005/11/07 11:14:27 gleixner Exp $
11 * 11 *
12 * Generic PCI memory map driver. We support the following boards: 12 * Generic PCI memory map driver. We support the following boards:
13 * - Intel IQ80310 ATU. 13 * - Intel IQ80310 ATU.
14 * - Intel EBSA285 (blank rom programming mode). Tested working 27/09/2001 14 * - Intel EBSA285 (blank rom programming mode). Tested working 27/09/2001
@@ -38,7 +38,7 @@ struct map_pci_info {
38 void (*exit)(struct pci_dev *dev, struct map_pci_info *map); 38 void (*exit)(struct pci_dev *dev, struct map_pci_info *map);
39 unsigned long (*translate)(struct map_pci_info *map, unsigned long ofs); 39 unsigned long (*translate)(struct map_pci_info *map, unsigned long ofs);
40 struct pci_dev *dev; 40 struct pci_dev *dev;
41}; 41};
42 42
43static map_word mtd_pci_read8(struct map_info *_map, unsigned long ofs) 43static map_word mtd_pci_read8(struct map_info *_map, unsigned long ofs)
44{ 44{
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index ff7c50d10180..af24216a0626 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: pcmciamtd.c,v 1.51 2004/07/12 22:38:29 dwmw2 Exp $ 2 * $Id: pcmciamtd.c,v 1.55 2005/11/07 11:14:28 gleixner Exp $
3 * 3 *
4 * pcmciamtd.c - MTD driver for PCMCIA flash memory cards 4 * pcmciamtd.c - MTD driver for PCMCIA flash memory cards
5 * 5 *
@@ -48,7 +48,7 @@ static const int debug = 0;
48 48
49 49
50#define DRIVER_DESC "PCMCIA Flash memory card driver" 50#define DRIVER_DESC "PCMCIA Flash memory card driver"
51#define DRIVER_VERSION "$Revision: 1.51 $" 51#define DRIVER_VERSION "$Revision: 1.55 $"
52 52
53/* Size of the PCMCIA address space: 26 bits = 64 MB */ 53/* Size of the PCMCIA address space: 26 bits = 64 MB */
54#define MAX_PCMCIA_ADDR 0x4000000 54#define MAX_PCMCIA_ADDR 0x4000000
@@ -176,7 +176,7 @@ static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long
176 176
177 if(toread > len) 177 if(toread > len)
178 toread = len; 178 toread = len;
179 179
180 addr = remap_window(map, from); 180 addr = remap_window(map, from);
181 if(!addr) 181 if(!addr)
182 return; 182 return;
@@ -386,7 +386,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
386 cs_error(link->handle, ParseTuple, rc); 386 cs_error(link->handle, ParseTuple, rc);
387 break; 387 break;
388 } 388 }
389 389
390 switch(tuple.TupleCode) { 390 switch(tuple.TupleCode) {
391 case CISTPL_FORMAT: { 391 case CISTPL_FORMAT: {
392 cistpl_format_t *t = &parse.format; 392 cistpl_format_t *t = &parse.format;
@@ -394,9 +394,9 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
394 DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u", 394 DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
395 t->type, t->edc, t->offset, t->length); 395 t->type, t->edc, t->offset, t->length);
396 break; 396 break;
397 397
398 } 398 }
399 399
400 case CISTPL_DEVICE: { 400 case CISTPL_DEVICE: {
401 cistpl_device_t *t = &parse.device; 401 cistpl_device_t *t = &parse.device;
402 int i; 402 int i;
@@ -410,7 +410,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
410 } 410 }
411 break; 411 break;
412 } 412 }
413 413
414 case CISTPL_VERS_1: { 414 case CISTPL_VERS_1: {
415 cistpl_vers_1_t *t = &parse.version_1; 415 cistpl_vers_1_t *t = &parse.version_1;
416 int i; 416 int i;
@@ -425,7 +425,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
425 DEBUG(2, "Found name: %s", dev->mtd_name); 425 DEBUG(2, "Found name: %s", dev->mtd_name);
426 break; 426 break;
427 } 427 }
428 428
429 case CISTPL_JEDEC_C: { 429 case CISTPL_JEDEC_C: {
430 cistpl_jedec_t *t = &parse.jedec; 430 cistpl_jedec_t *t = &parse.jedec;
431 int i; 431 int i;
@@ -434,7 +434,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
434 } 434 }
435 break; 435 break;
436 } 436 }
437 437
438 case CISTPL_DEVICE_GEO: { 438 case CISTPL_DEVICE_GEO: {
439 cistpl_device_geo_t *t = &parse.device_geo; 439 cistpl_device_geo_t *t = &parse.device_geo;
440 int i; 440 int i;
@@ -449,11 +449,11 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
449 } 449 }
450 break; 450 break;
451 } 451 }
452 452
453 default: 453 default:
454 DEBUG(2, "Unknown tuple code %d", tuple.TupleCode); 454 DEBUG(2, "Unknown tuple code %d", tuple.TupleCode);
455 } 455 }
456 456
457 rc = pcmcia_get_next_tuple(link->handle, &tuple); 457 rc = pcmcia_get_next_tuple(link->handle, &tuple);
458 } 458 }
459 if(!dev->pcmcia_map.size) 459 if(!dev->pcmcia_map.size)
@@ -470,7 +470,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
470 if(bankwidth) { 470 if(bankwidth) {
471 dev->pcmcia_map.bankwidth = bankwidth; 471 dev->pcmcia_map.bankwidth = bankwidth;
472 DEBUG(2, "bankwidth forced to %d", bankwidth); 472 DEBUG(2, "bankwidth forced to %d", bankwidth);
473 } 473 }
474 474
475 dev->pcmcia_map.name = dev->mtd_name; 475 dev->pcmcia_map.name = dev->mtd_name;
476 if(!dev->mtd_name[0]) { 476 if(!dev->mtd_name[0]) {
@@ -568,7 +568,7 @@ static void pcmciamtd_config(dev_link_t *link)
568 return; 568 return;
569 } 569 }
570 DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10); 570 DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
571 571
572 /* Get write protect status */ 572 /* Get write protect status */
573 CS_CHECK(GetStatus, pcmcia_get_status(link->handle, &status)); 573 CS_CHECK(GetStatus, pcmcia_get_status(link->handle, &status));
574 DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx", 574 DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx",
@@ -624,11 +624,11 @@ static void pcmciamtd_config(dev_link_t *link)
624 mtd = do_map_probe(probes[i], &dev->pcmcia_map); 624 mtd = do_map_probe(probes[i], &dev->pcmcia_map);
625 if(mtd) 625 if(mtd)
626 break; 626 break;
627 627
628 DEBUG(1, "FAILED: %s", probes[i]); 628 DEBUG(1, "FAILED: %s", probes[i]);
629 } 629 }
630 } 630 }
631 631
632 if(!mtd) { 632 if(!mtd) {
633 DEBUG(1, "Cant find an MTD"); 633 DEBUG(1, "Cant find an MTD");
634 pcmciamtd_release(link); 634 pcmciamtd_release(link);
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index b853670bfb81..9ee760f97bc6 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: physmap.c,v 1.37 2004/11/28 09:40:40 dwmw2 Exp $ 2 * $Id: physmap.c,v 1.38 2005/11/07 11:14:28 gleixner Exp $
3 * 3 *
4 * Normal mappings of chips in physical memory 4 * Normal mappings of chips in physical memory
5 * 5 *
@@ -69,7 +69,7 @@ static int __init init_physmap(void)
69 mymtd->owner = THIS_MODULE; 69 mymtd->owner = THIS_MODULE;
70 70
71#ifdef CONFIG_MTD_PARTITIONS 71#ifdef CONFIG_MTD_PARTITIONS
72 mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes, 72 mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes,
73 &mtd_parts, 0); 73 &mtd_parts, 0);
74 74
75 if (mtd_parts_nb > 0) 75 if (mtd_parts_nb > 0)
@@ -78,9 +78,9 @@ static int __init init_physmap(void)
78 return 0; 78 return 0;
79 } 79 }
80 80
81 if (num_physmap_partitions != 0) 81 if (num_physmap_partitions != 0)
82 { 82 {
83 printk(KERN_NOTICE 83 printk(KERN_NOTICE
84 "Using physmap partition definition\n"); 84 "Using physmap partition definition\n");
85 add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions); 85 add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions);
86 return 0; 86 return 0;
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
index 104576b5be34..a02eed94a231 100644
--- a/drivers/mtd/maps/plat-ram.c
+++ b/drivers/mtd/maps/plat-ram.c
@@ -6,7 +6,7 @@
6 * 6 *
7 * Generic platfrom device based RAM map 7 * Generic platfrom device based RAM map
8 * 8 *
9 * $Id: plat-ram.c,v 1.3 2005/03/19 22:41:27 gleixner Exp $ 9 * $Id: plat-ram.c,v 1.7 2005/11/07 11:14:28 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
@@ -91,7 +91,7 @@ static int platram_remove(struct device *dev)
91 91
92 dev_dbg(dev, "removing device\n"); 92 dev_dbg(dev, "removing device\n");
93 93
94 if (info == NULL) 94 if (info == NULL)
95 return 0; 95 return 0;
96 96
97 if (info->mtd) { 97 if (info->mtd) {
@@ -118,7 +118,7 @@ static int platram_remove(struct device *dev)
118 118
119 if (info->map.virt != NULL) 119 if (info->map.virt != NULL)
120 iounmap(info->map.virt); 120 iounmap(info->map.virt);
121 121
122 kfree(info); 122 kfree(info);
123 123
124 return 0; 124 return 0;
@@ -139,7 +139,7 @@ static int platram_probe(struct device *dev)
139 int err = 0; 139 int err = 0;
140 140
141 dev_dbg(dev, "probe entered\n"); 141 dev_dbg(dev, "probe entered\n");
142 142
143 if (dev->platform_data == NULL) { 143 if (dev->platform_data == NULL) {
144 dev_err(dev, "no platform data supplied\n"); 144 dev_err(dev, "no platform data supplied\n");
145 err = -ENOENT; 145 err = -ENOENT;
@@ -177,7 +177,7 @@ static int platram_probe(struct device *dev)
177 177
178 info->map.phys = res->start; 178 info->map.phys = res->start;
179 info->map.size = (res->end - res->start) + 1; 179 info->map.size = (res->end - res->start) + 1;
180 info->map.name = pdata->mapname != NULL ? pdata->mapname : pd->name; 180 info->map.name = pdata->mapname != NULL ? pdata->mapname : (char *)pd->name;
181 info->map.bankwidth = pdata->bankwidth; 181 info->map.bankwidth = pdata->bankwidth;
182 182
183 /* register our usage of the memory area */ 183 /* register our usage of the memory area */
@@ -240,7 +240,7 @@ static int platram_probe(struct device *dev)
240 dev_err(dev, "add_mtd_device() failed\n"); 240 dev_err(dev, "add_mtd_device() failed\n");
241 err = -ENOMEM; 241 err = -ENOMEM;
242 } 242 }
243 243
244 dev_info(dev, "registered mtd device\n"); 244 dev_info(dev, "registered mtd device\n");
245 return err; 245 return err;
246 246
@@ -254,6 +254,7 @@ static int platram_probe(struct device *dev)
254 254
255static struct device_driver platram_driver = { 255static struct device_driver platram_driver = {
256 .name = "mtd-ram", 256 .name = "mtd-ram",
257 .owner = THIS_MODULE,
257 .bus = &platform_bus_type, 258 .bus = &platform_bus_type,
258 .probe = platram_probe, 259 .probe = platram_probe,
259 .remove = platram_remove, 260 .remove = platram_remove,
diff --git a/drivers/mtd/maps/pnc2000.c b/drivers/mtd/maps/pnc2000.c
index a0f43dad8985..d7e16c2d5c44 100644
--- a/drivers/mtd/maps/pnc2000.c
+++ b/drivers/mtd/maps/pnc2000.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * This code is GPL 6 * This code is GPL
7 * 7 *
8 * $Id: pnc2000.c,v 1.17 2004/11/16 18:29:02 dwmw2 Exp $ 8 * $Id: pnc2000.c,v 1.18 2005/11/07 11:14:28 gleixner Exp $
9 */ 9 */
10 10
11#include <linux/module.h> 11#include <linux/module.h>
@@ -21,7 +21,7 @@
21#define WINDOW_ADDR 0xbf000000 21#define WINDOW_ADDR 0xbf000000
22#define WINDOW_SIZE 0x00400000 22#define WINDOW_SIZE 0x00400000
23 23
24/* 24/*
25 * MAP DRIVER STUFF 25 * MAP DRIVER STUFF
26 */ 26 */
27 27
@@ -36,7 +36,7 @@ static struct map_info pnc_map = {
36 36
37 37
38/* 38/*
39 * MTD 'PARTITIONING' STUFF 39 * MTD 'PARTITIONING' STUFF
40 */ 40 */
41static struct mtd_partition pnc_partitions[3] = { 41static struct mtd_partition pnc_partitions[3] = {
42 { 42 {
@@ -56,7 +56,7 @@ static struct mtd_partition pnc_partitions[3] = {
56 } 56 }
57}; 57};
58 58
59/* 59/*
60 * This is the master MTD device for which all the others are just 60 * This is the master MTD device for which all the others are just
61 * auto-relocating aliases. 61 * auto-relocating aliases.
62 */ 62 */
diff --git a/drivers/mtd/maps/pq2fads.c b/drivers/mtd/maps/pq2fads.c
new file mode 100644
index 000000000000..fb78d87cc130
--- /dev/null
+++ b/drivers/mtd/maps/pq2fads.c
@@ -0,0 +1,88 @@
1/*
2 * drivers/mtd/maps/pq2fads.c
3 *
4 * Mapping for the flash SIMM on 8272ADS and PQ2FADS board
5 *
6 * Author: Vitaly Bordug <vbordug@ru.mvista.com>
7 *
8 * 2005 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/module.h>
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <asm/io.h>
19#include <asm/ppcboot.h>
20#include <linux/mtd/mtd.h>
21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h>
23#include <linux/mtd/physmap.h>
24
25/*
26 NOTE: bank width and interleave relative to the installed flash
27 should have been chosen within MTD_CFI_GEOMETRY options.
28 */
29#define PQ2FADS_BANK_WIDTH 4
30
31static struct mtd_partition pq2fads_partitions[] = {
32 {
33#ifdef CONFIG_ADS8272
34 .name = "HRCW",
35 .size = 0x40000,
36 .offset = 0,
37 .mask_flags = MTD_WRITEABLE, /* force read-only */
38 }, {
39 .name = "User FS",
40 .size = 0x5c0000,
41 .offset = 0x40000,
42#else
43 .name = "User FS",
44 .size = 0x600000,
45 .offset = 0,
46#endif
47 }, {
48 .name = "uImage",
49 .size = 0x100000,
50 .offset = 0x600000,
51 .mask_flags = MTD_WRITEABLE, /* force read-only */
52 }, {
53 .name = "bootloader",
54 .size = 0x40000,
55 .offset = 0x700000,
56 .mask_flags = MTD_WRITEABLE, /* force read-only */
57 }, {
58 .name = "bootloader env",
59 .size = 0x40000,
60 .offset = 0x740000,
61 .mask_flags = MTD_WRITEABLE, /* force read-only */
62 }
63};
64
65
66/* pointer to MPC885ADS board info data */
67extern unsigned char __res[];
68
69static int __init init_pq2fads_mtd(void)
70{
71 bd_t *bd = (bd_t *)__res;
72 physmap_configure(bd->bi_flashstart, bd->bi_flashsize, PQ2FADS_BANK_WIDTH, NULL);
73
74 physmap_set_partitions(pq2fads_partitions,
75 sizeof (pq2fads_partitions) /
76 sizeof (pq2fads_partitions[0]));
77 return 0;
78}
79
80static void __exit cleanup_pq2fads_mtd(void)
81{
82}
83
84module_init(init_pq2fads_mtd);
85module_exit(cleanup_pq2fads_mtd);
86
87MODULE_LICENSE("GPL");
88MODULE_DESCRIPTION("MTD map and partitions for MPC8272ADS boards");
diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c
index edd01ee4f90b..5b76ed886185 100644
--- a/drivers/mtd/maps/redwood.c
+++ b/drivers/mtd/maps/redwood.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: redwood.c,v 1.10 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: redwood.c,v 1.11 2005/11/07 11:14:28 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/redwood.c 4 * drivers/mtd/maps/redwood.c
5 * 5 *
@@ -79,7 +79,7 @@ static struct mtd_partition redwood_flash_partitions[] = {
79 79
80#define RW_PART0_OF 0 80#define RW_PART0_OF 0
81#define RW_PART0_SZ 0x400000 /* 4 MiB data */ 81#define RW_PART0_SZ 0x400000 /* 4 MiB data */
82#define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ 82#define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ
83#define RW_PART1_SZ 0x10000 /* 64K VPD */ 83#define RW_PART1_SZ 0x10000 /* 64K VPD */
84#define RW_PART2_OF RW_PART1_OF + RW_PART1_SZ 84#define RW_PART2_OF RW_PART1_OF + RW_PART1_SZ
85#define RW_PART2_SZ 0x400000 - (0x10000 + 0x20000) 85#define RW_PART2_SZ 0x400000 - (0x10000 + 0x20000)
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index c8d0da19d897..9e8bb1782be0 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * Flash memory access on SA11x0 based devices 2 * Flash memory access on SA11x0 based devices
3 * 3 *
4 * (C) 2000 Nicolas Pitre <nico@cam.org> 4 * (C) 2000 Nicolas Pitre <nico@cam.org>
5 * 5 *
6 * $Id: sa1100-flash.c,v 1.47 2004/11/01 13:44:36 rmk Exp $ 6 * $Id: sa1100-flash.c,v 1.51 2005/11/07 11:14:28 gleixner Exp $
7 */ 7 */
8#include <linux/config.h> 8#include <linux/config.h>
9#include <linux/module.h> 9#include <linux/module.h>
@@ -241,8 +241,7 @@ static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *pla
241#endif 241#endif
242 } 242 }
243 243
244 if (info->parts) 244 kfree(info->parts);
245 kfree(info->parts);
246 245
247 for (i = info->num_subdev - 1; i >= 0; i--) 246 for (i = info->num_subdev - 1; i >= 0; i--)
248 sa1100_destroy_subdev(&info->subdev[i]); 247 sa1100_destroy_subdev(&info->subdev[i]);
diff --git a/drivers/mtd/maps/sbc8240.c b/drivers/mtd/maps/sbc8240.c
index da684d3384e9..225cdd9ba5b2 100644
--- a/drivers/mtd/maps/sbc8240.c
+++ b/drivers/mtd/maps/sbc8240.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * This code is GPLed 6 * This code is GPLed
7 * 7 *
8 * $Id: sbc8240.c,v 1.4 2004/07/12 22:38:29 dwmw2 Exp $ 8 * $Id: sbc8240.c,v 1.5 2005/11/07 11:14:28 gleixner Exp $
9 * 9 *
10 */ 10 */
11 11
@@ -205,7 +205,7 @@ int __init init_sbc8240_mtd (void)
205 } else { 205 } else {
206 printk (KERN_NOTICE MSG_PREFIX 206 printk (KERN_NOTICE MSG_PREFIX
207 "Using %s partition definition\n", sbc8240_part_banks[i].mtd_part->name); 207 "Using %s partition definition\n", sbc8240_part_banks[i].mtd_part->name);
208 add_mtd_partitions (sbc8240_mtd[i], 208 add_mtd_partitions (sbc8240_mtd[i],
209 sbc8240_part_banks[i].mtd_part, 209 sbc8240_part_banks[i].mtd_part,
210 sbc8240_part_banks[i].nums); 210 sbc8240_part_banks[i].nums);
211 } 211 }
diff --git a/drivers/mtd/maps/sbc_gxx.c b/drivers/mtd/maps/sbc_gxx.c
index 65add28bde14..7cc4041d096d 100644
--- a/drivers/mtd/maps/sbc_gxx.c
+++ b/drivers/mtd/maps/sbc_gxx.c
@@ -1,35 +1,35 @@
1/* sbc_gxx.c -- MTD map driver for Arcom Control Systems SBC-MediaGX, 1/* sbc_gxx.c -- MTD map driver for Arcom Control Systems SBC-MediaGX,
2 SBC-GXm and SBC-GX1 series boards. 2 SBC-GXm and SBC-GX1 series boards.
3 3
4 Copyright (C) 2001 Arcom Control System Ltd 4 Copyright (C) 2001 Arcom Control System Ltd
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or 8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version. 9 (at your option) any later version.
10 10
11 This program is distributed in the hope that it will be useful, 11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software 17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 19
20 $Id: sbc_gxx.c,v 1.33 2004/11/28 09:40:40 dwmw2 Exp $ 20 $Id: sbc_gxx.c,v 1.35 2005/11/07 11:14:28 gleixner Exp $
21 21
22The SBC-MediaGX / SBC-GXx has up to 16 MiB of 22The SBC-MediaGX / SBC-GXx has up to 16 MiB of
23Intel StrataFlash (28F320/28F640) in x8 mode. 23Intel StrataFlash (28F320/28F640) in x8 mode.
24 24
25This driver uses the CFI probe and Intel Extended Command Set drivers. 25This driver uses the CFI probe and Intel Extended Command Set drivers.
26 26
27The flash is accessed as follows: 27The flash is accessed as follows:
28 28
29 16 KiB memory window at 0xdc000-0xdffff 29 16 KiB memory window at 0xdc000-0xdffff
30 30
31 Two IO address locations for paging 31 Two IO address locations for paging
32 32
33 0x258 33 0x258
34 bit 0-7: address bit 14-21 34 bit 0-7: address bit 14-21
35 0x259 35 0x259
@@ -37,7 +37,7 @@ The flash is accessed as follows:
37 bit 7: 0 - reset/powered down 37 bit 7: 0 - reset/powered down
38 1 - device enabled 38 1 - device enabled
39 39
40The single flash device is divided into 3 partition which appear as 40The single flash device is divided into 3 partition which appear as
41separate MTD devices. 41separate MTD devices.
42 42
4325/04/2001 AJL (Arcom) Modified signon strings and partition sizes 4325/04/2001 AJL (Arcom) Modified signon strings and partition sizes
@@ -87,17 +87,17 @@ static volatile int page_in_window = -1; // Current page in window.
87static void __iomem *iomapadr; 87static void __iomem *iomapadr;
88static DEFINE_SPINLOCK(sbc_gxx_spin); 88static DEFINE_SPINLOCK(sbc_gxx_spin);
89 89
90/* partition_info gives details on the logical partitions that the split the 90/* partition_info gives details on the logical partitions that the split the
91 * single flash device into. If the size if zero we use up to the end of the 91 * single flash device into. If the size if zero we use up to the end of the
92 * device. */ 92 * device. */
93static struct mtd_partition partition_info[]={ 93static struct mtd_partition partition_info[]={
94 { .name = "SBC-GXx flash boot partition", 94 { .name = "SBC-GXx flash boot partition",
95 .offset = 0, 95 .offset = 0,
96 .size = BOOT_PARTITION_SIZE_KiB*1024 }, 96 .size = BOOT_PARTITION_SIZE_KiB*1024 },
97 { .name = "SBC-GXx flash data partition", 97 { .name = "SBC-GXx flash data partition",
98 .offset = BOOT_PARTITION_SIZE_KiB*1024, 98 .offset = BOOT_PARTITION_SIZE_KiB*1024,
99 .size = (DATA_PARTITION_SIZE_KiB)*1024 }, 99 .size = (DATA_PARTITION_SIZE_KiB)*1024 },
100 { .name = "SBC-GXx flash application partition", 100 { .name = "SBC-GXx flash application partition",
101 .offset = (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 } 101 .offset = (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 }
102}; 102};
103 103
@@ -130,7 +130,7 @@ static void sbc_gxx_copy_from(struct map_info *map, void *to, unsigned long from
130 unsigned long thislen = len; 130 unsigned long thislen = len;
131 if (len > (WINDOW_LENGTH - (from & WINDOW_MASK))) 131 if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
132 thislen = WINDOW_LENGTH-(from & WINDOW_MASK); 132 thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
133 133
134 spin_lock(&sbc_gxx_spin); 134 spin_lock(&sbc_gxx_spin);
135 sbc_gxx_page(map, from); 135 sbc_gxx_page(map, from);
136 memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen); 136 memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen);
@@ -150,12 +150,12 @@ static void sbc_gxx_write8(struct map_info *map, map_word d, unsigned long adr)
150} 150}
151 151
152static void sbc_gxx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) 152static void sbc_gxx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
153{ 153{
154 while(len) { 154 while(len) {
155 unsigned long thislen = len; 155 unsigned long thislen = len;
156 if (len > (WINDOW_LENGTH - (to & WINDOW_MASK))) 156 if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
157 thislen = WINDOW_LENGTH-(to & WINDOW_MASK); 157 thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
158 158
159 spin_lock(&sbc_gxx_spin); 159 spin_lock(&sbc_gxx_spin);
160 sbc_gxx_page(map, to); 160 sbc_gxx_page(map, to);
161 memcpy_toio(iomapadr + (to & WINDOW_MASK), from, thislen); 161 memcpy_toio(iomapadr + (to & WINDOW_MASK), from, thislen);
@@ -201,7 +201,7 @@ static int __init init_sbc_gxx(void)
201 sbc_gxx_map.name ); 201 sbc_gxx_map.name );
202 return -EIO; 202 return -EIO;
203 } 203 }
204 204
205 if (!request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash")) { 205 if (!request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash")) {
206 printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n", 206 printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
207 sbc_gxx_map.name, 207 sbc_gxx_map.name,
@@ -209,8 +209,8 @@ static int __init init_sbc_gxx(void)
209 iounmap(iomapadr); 209 iounmap(iomapadr);
210 return -EAGAIN; 210 return -EAGAIN;
211 } 211 }
212 212
213 213
214 printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n", 214 printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
215 sbc_gxx_map.name, 215 sbc_gxx_map.name,
216 PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1, 216 PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1,
@@ -222,7 +222,7 @@ static int __init init_sbc_gxx(void)
222 cleanup_sbc_gxx(); 222 cleanup_sbc_gxx();
223 return -ENXIO; 223 return -ENXIO;
224 } 224 }
225 225
226 all_mtd->owner = THIS_MODULE; 226 all_mtd->owner = THIS_MODULE;
227 227
228 /* Create MTD devices for each partition. */ 228 /* Create MTD devices for each partition. */
diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c
index a06ed21e7ed1..6fb9f3c57aab 100644
--- a/drivers/mtd/maps/sc520cdp.c
+++ b/drivers/mtd/maps/sc520cdp.c
@@ -16,7 +16,7 @@
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18 * 18 *
19 * $Id: sc520cdp.c,v 1.21 2004/12/13 10:27:08 dedekind Exp $ 19 * $Id: sc520cdp.c,v 1.22 2005/11/07 11:14:28 gleixner Exp $
20 * 20 *
21 * 21 *
22 * The SC520CDP is an evaluation board for the Elan SC520 processor available 22 * The SC520CDP is an evaluation board for the Elan SC520 processor available
@@ -231,7 +231,7 @@ static void sc520cdp_setup_par(void)
231static int __init init_sc520cdp(void) 231static int __init init_sc520cdp(void)
232{ 232{
233 int i, devices_found = 0; 233 int i, devices_found = 0;
234 234
235#ifdef REPROGRAM_PAR 235#ifdef REPROGRAM_PAR
236 /* reprogram PAR registers so flash appears at the desired addresses */ 236 /* reprogram PAR registers so flash appears at the desired addresses */
237 sc520cdp_setup_par(); 237 sc520cdp_setup_par();
@@ -278,7 +278,7 @@ static int __init init_sc520cdp(void)
278static void __exit cleanup_sc520cdp(void) 278static void __exit cleanup_sc520cdp(void)
279{ 279{
280 int i; 280 int i;
281 281
282 if (merged_mtd) { 282 if (merged_mtd) {
283 del_mtd_device(merged_mtd); 283 del_mtd_device(merged_mtd);
284 mtd_concat_destroy(merged_mtd); 284 mtd_concat_destroy(merged_mtd);
diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c
index 0ece3786d6ea..2c91dff8bb60 100644
--- a/drivers/mtd/maps/scx200_docflash.c
+++ b/drivers/mtd/maps/scx200_docflash.c
@@ -1,8 +1,8 @@
1/* linux/drivers/mtd/maps/scx200_docflash.c 1/* linux/drivers/mtd/maps/scx200_docflash.c
2 2
3 Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> 3 Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
4 4
5 $Id: scx200_docflash.c,v 1.10 2004/11/28 09:40:40 dwmw2 Exp $ 5 $Id: scx200_docflash.c,v 1.12 2005/11/07 11:14:28 gleixner Exp $
6 6
7 National Semiconductor SCx200 flash mapped with DOCCS 7 National Semiconductor SCx200 flash mapped with DOCCS
8*/ 8*/
@@ -49,23 +49,23 @@ static struct mtd_info *mymtd;
49 49
50#ifdef CONFIG_MTD_PARTITIONS 50#ifdef CONFIG_MTD_PARTITIONS
51static struct mtd_partition partition_info[] = { 51static struct mtd_partition partition_info[] = {
52 { 52 {
53 .name = "DOCCS Boot kernel", 53 .name = "DOCCS Boot kernel",
54 .offset = 0, 54 .offset = 0,
55 .size = 0xc0000 55 .size = 0xc0000
56 }, 56 },
57 { 57 {
58 .name = "DOCCS Low BIOS", 58 .name = "DOCCS Low BIOS",
59 .offset = 0xc0000, 59 .offset = 0xc0000,
60 .size = 0x40000 60 .size = 0x40000
61 }, 61 },
62 { 62 {
63 .name = "DOCCS File system", 63 .name = "DOCCS File system",
64 .offset = 0x100000, 64 .offset = 0x100000,
65 .size = ~0 /* calculate from flash size */ 65 .size = ~0 /* calculate from flash size */
66 }, 66 },
67 { 67 {
68 .name = "DOCCS High BIOS", 68 .name = "DOCCS High BIOS",
69 .offset = ~0, /* calculate from flash size */ 69 .offset = ~0, /* calculate from flash size */
70 .size = 0x80000 70 .size = 0x80000
71 }, 71 },
@@ -88,7 +88,7 @@ static int __init init_scx200_docflash(void)
88 88
89 printk(KERN_DEBUG NAME ": NatSemi SCx200 DOCCS Flash Driver\n"); 89 printk(KERN_DEBUG NAME ": NatSemi SCx200 DOCCS Flash Driver\n");
90 90
91 if ((bridge = pci_find_device(PCI_VENDOR_ID_NS, 91 if ((bridge = pci_find_device(PCI_VENDOR_ID_NS,
92 PCI_DEVICE_ID_NS_SCx200_BRIDGE, 92 PCI_DEVICE_ID_NS_SCx200_BRIDGE,
93 NULL)) == NULL) 93 NULL)) == NULL)
94 return -ENODEV; 94 return -ENODEV;
@@ -134,28 +134,28 @@ static int __init init_scx200_docflash(void)
134 printk(KERN_ERR NAME ": invalid size for flash mapping\n"); 134 printk(KERN_ERR NAME ": invalid size for flash mapping\n");
135 return -EINVAL; 135 return -EINVAL;
136 } 136 }
137 137
138 if (width != 8 && width != 16) { 138 if (width != 8 && width != 16) {
139 printk(KERN_ERR NAME ": invalid bus width for flash mapping\n"); 139 printk(KERN_ERR NAME ": invalid bus width for flash mapping\n");
140 return -EINVAL; 140 return -EINVAL;
141 } 141 }
142 142
143 if (allocate_resource(&iomem_resource, &docmem, 143 if (allocate_resource(&iomem_resource, &docmem,
144 size, 144 size,
145 0xc0000000, 0xffffffff, 145 0xc0000000, 0xffffffff,
146 size, NULL, NULL)) { 146 size, NULL, NULL)) {
147 printk(KERN_ERR NAME ": unable to allocate memory for flash mapping\n"); 147 printk(KERN_ERR NAME ": unable to allocate memory for flash mapping\n");
148 return -ENOMEM; 148 return -ENOMEM;
149 } 149 }
150 150
151 ctrl = 0x07000000 | ((size-1) >> 13); 151 ctrl = 0x07000000 | ((size-1) >> 13);
152 152
153 printk(KERN_INFO "DOCCS BASE=0x%08lx, CTRL=0x%08lx\n", (long)docmem.start, (long)ctrl); 153 printk(KERN_INFO "DOCCS BASE=0x%08lx, CTRL=0x%08lx\n", (long)docmem.start, (long)ctrl);
154 154
155 pci_write_config_dword(bridge, SCx200_DOCCS_BASE, docmem.start); 155 pci_write_config_dword(bridge, SCx200_DOCCS_BASE, docmem.start);
156 pci_write_config_dword(bridge, SCx200_DOCCS_CTRL, ctrl); 156 pci_write_config_dword(bridge, SCx200_DOCCS_CTRL, ctrl);
157 pmr = inl(scx200_cb_base + SCx200_PMR); 157 pmr = inl(scx200_cb_base + SCx200_PMR);
158 158
159 if (width == 8) { 159 if (width == 8) {
160 pmr &= ~(1<<6); 160 pmr &= ~(1<<6);
161 } else { 161 } else {
@@ -163,8 +163,8 @@ static int __init init_scx200_docflash(void)
163 } 163 }
164 outl(pmr, scx200_cb_base + SCx200_PMR); 164 outl(pmr, scx200_cb_base + SCx200_PMR);
165 } 165 }
166 166
167 printk(KERN_INFO NAME ": DOCCS mapped at 0x%lx-0x%lx, width %d\n", 167 printk(KERN_INFO NAME ": DOCCS mapped at 0x%lx-0x%lx, width %d\n",
168 docmem.start, docmem.end, width); 168 docmem.start, docmem.end, width);
169 169
170 scx200_docflash_map.size = size; 170 scx200_docflash_map.size = size;
diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c
index b7f093fbf9b0..999f4bb3d845 100644
--- a/drivers/mtd/maps/sharpsl-flash.c
+++ b/drivers/mtd/maps/sharpsl-flash.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * sharpsl-flash.c 2 * sharpsl-flash.c
3 * 3 *
4 * Copyright (C) 2001 Lineo Japan, Inc. 4 * Copyright (C) 2001 Lineo Japan, Inc.
5 * Copyright (C) 2002 SHARP 5 * Copyright (C) 2002 SHARP
6 * 6 *
7 * $Id: sharpsl-flash.c,v 1.5 2005/03/21 08:42:11 rpurdie Exp $ 7 * $Id: sharpsl-flash.c,v 1.7 2005/11/07 11:14:28 gleixner Exp $
8 * 8 *
9 * based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp 9 * based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp
10 * Handle mapping of the flash on the RPX Lite and CLLF boards 10 * Handle mapping of the flash on the RPX Lite and CLLF boards
@@ -57,7 +57,7 @@ int __init init_sharpsl(void)
57 int nb_parts = 0; 57 int nb_parts = 0;
58 char *part_type = "static"; 58 char *part_type = "static";
59 59
60 printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n", 60 printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n",
61 WINDOW_SIZE, WINDOW_ADDR); 61 WINDOW_SIZE, WINDOW_ADDR);
62 sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); 62 sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
63 if (!sharpsl_map.virt) { 63 if (!sharpsl_map.virt) {
@@ -75,7 +75,7 @@ int __init init_sharpsl(void)
75 75
76 mymtd->owner = THIS_MODULE; 76 mymtd->owner = THIS_MODULE;
77 77
78 if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky() 78 if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky()
79 || machine_is_poodle()) { 79 || machine_is_poodle()) {
80 sharpsl_partitions[0].size=0x006d0000; 80 sharpsl_partitions[0].size=0x006d0000;
81 sharpsl_partitions[0].offset=0x00120000; 81 sharpsl_partitions[0].offset=0x00120000;
@@ -87,10 +87,10 @@ int __init init_sharpsl(void)
87 sharpsl_partitions[0].offset=0x00140000; 87 sharpsl_partitions[0].offset=0x00140000;
88 } else { 88 } else {
89 map_destroy(mymtd); 89 map_destroy(mymtd);
90 iounmap(sharpsl_map.virt); 90 iounmap(sharpsl_map.virt);
91 return -ENODEV; 91 return -ENODEV;
92 } 92 }
93 93
94 parts = sharpsl_partitions; 94 parts = sharpsl_partitions;
95 nb_parts = NB_OF(sharpsl_partitions); 95 nb_parts = NB_OF(sharpsl_partitions);
96 96
diff --git a/drivers/mtd/maps/solutionengine.c b/drivers/mtd/maps/solutionengine.c
index 8ce5d897645c..c53c2c369c9d 100644
--- a/drivers/mtd/maps/solutionengine.c
+++ b/drivers/mtd/maps/solutionengine.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: solutionengine.c,v 1.14 2004/09/16 23:27:14 gleixner Exp $ 2 * $Id: solutionengine.c,v 1.15 2005/11/07 11:14:28 gleixner Exp $
3 * 3 *
4 * Flash and EPROM on Hitachi Solution Engine and similar boards. 4 * Flash and EPROM on Hitachi Solution Engine and similar boards.
5 * 5 *
@@ -67,7 +67,7 @@ static int __init init_soleng_maps(void)
67 soleng_eprom_map.virt = (void __iomem *)P1SEGADDR(0x01000000); 67 soleng_eprom_map.virt = (void __iomem *)P1SEGADDR(0x01000000);
68 simple_map_init(&soleng_eprom_map); 68 simple_map_init(&soleng_eprom_map);
69 simple_map_init(&soleng_flash_map); 69 simple_map_init(&soleng_flash_map);
70 70
71 printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n"); 71 printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n");
72 flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map); 72 flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map);
73 if (!flash_mtd) { 73 if (!flash_mtd) {
diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c
index 29091d10030a..0758cb1d0105 100644
--- a/drivers/mtd/maps/sun_uflash.c
+++ b/drivers/mtd/maps/sun_uflash.c
@@ -1,4 +1,4 @@
1/* $Id: sun_uflash.c,v 1.11 2004/11/04 13:24:15 gleixner Exp $ 1/* $Id: sun_uflash.c,v 1.13 2005/11/07 11:14:28 gleixner Exp $
2 * 2 *
3 * sun_uflash - Driver implementation for user-programmable flash 3 * sun_uflash - Driver implementation for user-programmable flash
4 * present on many Sun Microsystems SME boardsets. 4 * present on many Sun Microsystems SME boardsets.
@@ -63,7 +63,7 @@ int uflash_devinit(struct linux_ebus_device* edev)
63 iTmp = prom_getproperty( 63 iTmp = prom_getproperty(
64 edev->prom_node, "reg", (void *)regs, sizeof(regs)); 64 edev->prom_node, "reg", (void *)regs, sizeof(regs));
65 if ((iTmp % sizeof(regs[0])) != 0) { 65 if ((iTmp % sizeof(regs[0])) != 0) {
66 printk("%s: Strange reg property size %d\n", 66 printk("%s: Strange reg property size %d\n",
67 UFLASH_DEVNAME, iTmp); 67 UFLASH_DEVNAME, iTmp);
68 return -ENODEV; 68 return -ENODEV;
69 } 69 }
@@ -75,7 +75,7 @@ int uflash_devinit(struct linux_ebus_device* edev)
75 * can work on supporting it. 75 * can work on supporting it.
76 */ 76 */
77 printk("%s: unsupported device at 0x%lx (%d regs): " \ 77 printk("%s: unsupported device at 0x%lx (%d regs): " \
78 "email ebrower@usa.net\n", 78 "email ebrower@usa.net\n",
79 UFLASH_DEVNAME, edev->resource[0].start, nregs); 79 UFLASH_DEVNAME, edev->resource[0].start, nregs);
80 return -ENODEV; 80 return -ENODEV;
81 } 81 }
@@ -84,7 +84,7 @@ int uflash_devinit(struct linux_ebus_device* edev)
84 printk("%s: unable to kmalloc new device\n", UFLASH_DEVNAME); 84 printk("%s: unable to kmalloc new device\n", UFLASH_DEVNAME);
85 return(-ENOMEM); 85 return(-ENOMEM);
86 } 86 }
87 87
88 /* copy defaults and tweak parameters */ 88 /* copy defaults and tweak parameters */
89 memcpy(&pdev->map, &uflash_map_templ, sizeof(uflash_map_templ)); 89 memcpy(&pdev->map, &uflash_map_templ, sizeof(uflash_map_templ));
90 pdev->map.size = regs[0].reg_size; 90 pdev->map.size = regs[0].reg_size;
@@ -155,7 +155,7 @@ static void __exit uflash_cleanup(void)
155 155
156 list_for_each(udevlist, &device_list) { 156 list_for_each(udevlist, &device_list) {
157 udev = list_entry(udevlist, struct uflash_dev, list); 157 udev = list_entry(udevlist, struct uflash_dev, list);
158 DEBUG(2, "%s: removing device %s\n", 158 DEBUG(2, "%s: removing device %s\n",
159 UFLASH_DEVNAME, udev->name); 159 UFLASH_DEVNAME, udev->name);
160 160
161 if(0 != udev->mtd) { 161 if(0 != udev->mtd) {
@@ -166,11 +166,9 @@ static void __exit uflash_cleanup(void)
166 iounmap(udev->map.virt); 166 iounmap(udev->map.virt);
167 udev->map.virt = NULL; 167 udev->map.virt = NULL;
168 } 168 }
169 if(0 != udev->name) { 169 kfree(udev->name);
170 kfree(udev->name);
171 }
172 kfree(udev); 170 kfree(udev);
173 } 171 }
174} 172}
175 173
176module_init(uflash_init); 174module_init(uflash_init);
diff --git a/drivers/mtd/maps/tqm834x.c b/drivers/mtd/maps/tqm834x.c
new file mode 100644
index 000000000000..c7ae9a515c1a
--- /dev/null
+++ b/drivers/mtd/maps/tqm834x.c
@@ -0,0 +1,291 @@
1/*
2 * drivers/mtd/maps/tqm834x.c
3 *
4 * MTD mapping driver for TQM834x boards
5 *
6 * Copyright 2005 Wolfgang Denk, DENX Software Engineering, <wd@denx.de>.
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 *
12 */
13
14#include <linux/config.h>
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/types.h>
18#include <linux/kernel.h>
19#include <linux/slab.h>
20#include <asm/io.h>
21#include <asm/ppcboot.h>
22
23#include <linux/mtd/mtd.h>
24#include <linux/mtd/map.h>
25#include <linux/mtd/partitions.h>
26
27#define FLASH_BANK_MAX 2
28
29extern unsigned char __res[];
30
31/* trivial struct to describe partition information */
32struct mtd_part_def
33{
34 int nums;
35 unsigned char *type;
36 struct mtd_partition* mtd_part;
37};
38
39static struct mtd_info* mtd_banks[FLASH_BANK_MAX];
40static struct map_info* map_banks[FLASH_BANK_MAX];
41static struct mtd_part_def part_banks[FLASH_BANK_MAX];
42
43static unsigned long num_banks;
44static unsigned long start_scan_addr;
45
46#ifdef CONFIG_MTD_PARTITIONS
47/*
48 * The following defines the partition layout of TQM834x boards.
49 *
50 * See include/linux/mtd/partitions.h for definition of the
51 * mtd_partition structure.
52 *
53 * Assume minimal initial size of 4 MiB per bank, will be updated
54 * later in init_tqm834x_mtd() routine.
55 */
56
57/* Partition definition for the first flash bank which is always present. */
58static struct mtd_partition tqm834x_partitions_bank1[] = {
59 {
60 .name = "u-boot", /* u-boot firmware */
61 .offset = 0x00000000,
62 .size = 0x00040000, /* 256 KiB */
63 /*mask_flags: MTD_WRITEABLE, * force read-only */
64 },
65 {
66 .name = "env", /* u-boot environment */
67 .offset = 0x00040000,
68 .size = 0x00020000, /* 128 KiB */
69 /*mask_flags: MTD_WRITEABLE, * force read-only */
70 },
71 {
72 .name = "kernel", /* linux kernel image */
73 .offset = 0x00060000,
74 .size = 0x00100000, /* 1 MiB */
75 /*mask_flags: MTD_WRITEABLE, * force read-only */
76 },
77 {
78 .name = "initrd", /* ramdisk image */
79 .offset = 0x00160000,
80 .size = 0x00200000, /* 2 MiB */
81 },
82 {
83 .name = "user", /* user data */
84 .offset = 0x00360000,
85 .size = 0x000a0000, /* remaining space */
86 /* NOTE: this parttion size is re-calcated in */
87 /* init_tqm834x_mtd() to cover actual remaining space. */
88 },
89};
90
91/* Partition definition for the second flash bank which may be present on some
92 * TQM834x boards.
93 */
94static struct mtd_partition tqm834x_partitions_bank2[] = {
95 {
96 .name = "jffs2", /* jffs2 filesystem */
97 .offset = 0x00000000,
98 .size = 0x00400000, /* whole device */
99 /* NOTE: this parttion size is re-calcated in */
100 /* init_tqm834x_mtd() to cover actual device size. */
101 },
102};
103
104#endif /* CONFIG_MTD_PARTITIONS */
105
106static int __init init_tqm834x_mtd(void)
107{
108 int idx = 0, ret = 0;
109 unsigned long flash_addr, flash_size, mtd_size = 0;
110
111 /* pointer to TQM834x board info data */
112 bd_t *bd = (bd_t *)__res;
113#ifdef CONFIG_MTD_CMDLINE_PARTS
114 int n;
115 char mtdid[4];
116 const char *part_probes[] = { "cmdlinepart", NULL };
117#endif
118
119 flash_addr = bd->bi_flashstart;
120 flash_size = bd->bi_flashsize;
121
122 /* request maximum flash size address space */
123 start_scan_addr = (unsigned long)ioremap(flash_addr, flash_size);
124 if (!start_scan_addr) {
125 printk("%s: Failed to ioremap address: 0x%lx\n",
126 __FUNCTION__, flash_addr);
127 return -EIO;
128 }
129
130 for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
131 if (mtd_size >= flash_size)
132 break;
133
134 pr_debug("%s: chip probing count %d\n", __FUNCTION__, idx);
135
136 map_banks[idx] =
137 (struct map_info *)kmalloc(sizeof(struct map_info),
138 GFP_KERNEL);
139 if (map_banks[idx] == NULL) {
140 ret = -ENOMEM;
141 goto error_mem;
142 }
143 memset((void *)map_banks[idx], 0, sizeof(struct map_info));
144 map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL);
145 if (map_banks[idx]->name == NULL) {
146 ret = -ENOMEM;
147 goto error_mem;
148 }
149 memset((void *)map_banks[idx]->name, 0, 16);
150
151 sprintf(map_banks[idx]->name, "TQM834x-%d", idx);
152 map_banks[idx]->size = flash_size;
153 map_banks[idx]->bankwidth = 4;
154
155 simple_map_init(map_banks[idx]);
156
157 map_banks[idx]->virt = (void __iomem *)
158 (start_scan_addr + ((idx > 0) ?
159 (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0));
160 map_banks[idx]->phys =
161 flash_addr + ((idx > 0) ?
162 (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0);
163
164 /* start to probe flash chips */
165 mtd_banks[idx] = do_map_probe("cfi_probe", map_banks[idx]);
166 if (mtd_banks[idx]) {
167 mtd_banks[idx]->owner = THIS_MODULE;
168 mtd_size += mtd_banks[idx]->size;
169 num_banks++;
170 pr_debug("%s: bank %ld, name: %s, size: %d bytes \n",
171 __FUNCTION__, num_banks,
172 mtd_banks[idx]->name, mtd_banks[idx]->size);
173 }
174 }
175
176 /* no supported flash chips found */
177 if (!num_banks) {
178 printk("TQM834x: No supported flash chips found!\n");
179 ret = -ENXIO;
180 goto error_mem;
181 }
182
183#ifdef CONFIG_MTD_PARTITIONS
184 /*
185 * Select static partition definitions
186 */
187 n = ARRAY_SIZE(tqm834x_partitions_bank1);
188 part_banks[0].mtd_part = tqm834x_partitions_bank1;
189 part_banks[0].type = "static image bank1";
190 part_banks[0].nums = n;
191
192 /* update last partition size to cover actual remaining space */
193 tqm834x_partitions_bank1[n - 1].size =
194 mtd_banks[0]->size -
195 tqm834x_partitions_bank1[n - 1].offset;
196
197 /* check if we have second bank? */
198 if (num_banks == 2) {
199 n = ARRAY_SIZE(tqm834x_partitions_bank2);
200 part_banks[1].mtd_part = tqm834x_partitions_bank2;
201 part_banks[1].type = "static image bank2";
202 part_banks[1].nums = n;
203
204 /* update last partition size to cover actual remaining space */
205 tqm834x_partitions_bank2[n - 1].size =
206 mtd_banks[1]->size -
207 tqm834x_partitions_bank2[n - 1].offset;
208 }
209
210 for(idx = 0; idx < num_banks ; idx++) {
211#ifdef CONFIG_MTD_CMDLINE_PARTS
212 sprintf(mtdid, "%d", idx);
213 n = parse_mtd_partitions(mtd_banks[idx],
214 part_probes,
215 &part_banks[idx].mtd_part,
216 0);
217 pr_debug("%s: %d command line partitions on bank %s\n",
218 __FUNCTION__, n, mtdid);
219 if (n > 0) {
220 part_banks[idx].type = "command line";
221 part_banks[idx].nums = n;
222 }
223#endif /* CONFIG_MTD_CMDLINE_PARTS */
224 if (part_banks[idx].nums == 0) {
225 printk(KERN_NOTICE
226 "TQM834x flash bank %d: no partition info "
227 "available, registering whole device\n", idx);
228 add_mtd_device(mtd_banks[idx]);
229 } else {
230 printk(KERN_NOTICE
231 "TQM834x flash bank %d: Using %s partition "
232 "definition\n", idx, part_banks[idx].type);
233 add_mtd_partitions(mtd_banks[idx],
234 part_banks[idx].mtd_part,
235 part_banks[idx].nums);
236 }
237 }
238#else /* ! CONFIG_MTD_PARTITIONS */
239 printk(KERN_NOTICE "TQM834x flash: registering %d flash banks "
240 "at once\n", num_banks);
241
242 for(idx = 0 ; idx < num_banks ; idx++)
243 add_mtd_device(mtd_banks[idx]);
244
245#endif /* CONFIG_MTD_PARTITIONS */
246
247 return 0;
248error_mem:
249 for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
250 if (map_banks[idx] != NULL) {
251 if (map_banks[idx]->name != NULL) {
252 kfree(map_banks[idx]->name);
253 map_banks[idx]->name = NULL;
254 }
255 kfree(map_banks[idx]);
256 map_banks[idx] = NULL;
257 }
258 }
259
260 iounmap((void *)start_scan_addr);
261
262 return ret;
263}
264
265static void __exit cleanup_tqm834x_mtd(void)
266{
267 unsigned int idx = 0;
268 for(idx = 0 ; idx < num_banks ; idx++) {
269 /* destroy mtd_info previously allocated */
270 if (mtd_banks[idx]) {
271 del_mtd_partitions(mtd_banks[idx]);
272 map_destroy(mtd_banks[idx]);
273 }
274
275 /* release map_info not used anymore */
276 kfree(map_banks[idx]->name);
277 kfree(map_banks[idx]);
278 }
279
280 if (start_scan_addr) {
281 iounmap((void *)start_scan_addr);
282 start_scan_addr = 0;
283 }
284}
285
286module_init(init_tqm834x_mtd);
287module_exit(cleanup_tqm834x_mtd);
288
289MODULE_LICENSE("GPL");
290MODULE_AUTHOR("Wolfgang Denk <wd@denx.de>");
291MODULE_DESCRIPTION("MTD map driver for TQM834x boards");
diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c
index 4e28b977f224..a43517053e7c 100644
--- a/drivers/mtd/maps/tqm8xxl.c
+++ b/drivers/mtd/maps/tqm8xxl.c
@@ -1,15 +1,15 @@
1/* 1/*
2 * Handle mapping of the flash memory access routines 2 * Handle mapping of the flash memory access routines
3 * on TQM8xxL based devices. 3 * on TQM8xxL based devices.
4 * 4 *
5 * $Id: tqm8xxl.c,v 1.13 2004/10/20 22:21:53 dwmw2 Exp $ 5 * $Id: tqm8xxl.c,v 1.15 2005/11/07 11:14:28 gleixner Exp $
6 * 6 *
7 * based on rpxlite.c 7 * based on rpxlite.c
8 * 8 *
9 * Copyright(C) 2001 Kirk Lee <kirk@hpc.ee.ntu.edu.tw> 9 * Copyright(C) 2001 Kirk Lee <kirk@hpc.ee.ntu.edu.tw>
10 * 10 *
11 * This code is GPLed 11 * This code is GPLed
12 * 12 *
13 */ 13 */
14 14
15/* 15/*
@@ -19,7 +19,7 @@
19 * 2MiB 512Kx16 2MiB 0 19 * 2MiB 512Kx16 2MiB 0
20 * 4MiB 1Mx16 4MiB 0 20 * 4MiB 1Mx16 4MiB 0
21 * 8MiB 1Mx16 4MiB 4MiB 21 * 8MiB 1Mx16 4MiB 4MiB
22 * Thus, we choose CONFIG_MTD_CFI_I2 & CONFIG_MTD_CFI_B4 at 22 * Thus, we choose CONFIG_MTD_CFI_I2 & CONFIG_MTD_CFI_B4 at
23 * kernel configuration. 23 * kernel configuration.
24 */ 24 */
25#include <linux/config.h> 25#include <linux/config.h>
@@ -58,9 +58,9 @@ static void __iomem *start_scan_addr;
58 * Here are partition information for all known TQM8xxL series devices. 58 * Here are partition information for all known TQM8xxL series devices.
59 * See include/linux/mtd/partitions.h for definition of the mtd_partition 59 * See include/linux/mtd/partitions.h for definition of the mtd_partition
60 * structure. 60 * structure.
61 * 61 *
62 * The *_max_flash_size is the maximum possible mapped flash size which 62 * The *_max_flash_size is the maximum possible mapped flash size which
63 * is not necessarily the actual flash size. It must correspond to the 63 * is not necessarily the actual flash size. It must correspond to the
64 * value specified in the mapping definition defined by the 64 * value specified in the mapping definition defined by the
65 * "struct map_desc *_io_desc" for the corresponding machine. 65 * "struct map_desc *_io_desc" for the corresponding machine.
66 */ 66 */
@@ -132,9 +132,9 @@ int __init init_tqm_mtd(void)
132 for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) { 132 for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
133 if(mtd_size >= flash_size) 133 if(mtd_size >= flash_size)
134 break; 134 break;
135 135
136 printk(KERN_INFO "%s: chip probing count %d\n", __FUNCTION__, idx); 136 printk(KERN_INFO "%s: chip probing count %d\n", __FUNCTION__, idx);
137 137
138 map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info), GFP_KERNEL); 138 map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info), GFP_KERNEL);
139 if(map_banks[idx] == NULL) { 139 if(map_banks[idx] == NULL) {
140 ret = -ENOMEM; 140 ret = -ENOMEM;
@@ -180,7 +180,7 @@ int __init init_tqm_mtd(void)
180 mtd_size += mtd_banks[idx]->size; 180 mtd_size += mtd_banks[idx]->size;
181 num_banks++; 181 num_banks++;
182 182
183 printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks, 183 printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks,
184 mtd_banks[idx]->name, mtd_banks[idx]->size); 184 mtd_banks[idx]->name, mtd_banks[idx]->size);
185 } 185 }
186 } 186 }
@@ -211,7 +211,7 @@ int __init init_tqm_mtd(void)
211 } else { 211 } else {
212 printk(KERN_NOTICE "TQM flash%d: Using %s partition definition\n", 212 printk(KERN_NOTICE "TQM flash%d: Using %s partition definition\n",
213 idx, part_banks[idx].type); 213 idx, part_banks[idx].type);
214 add_mtd_partitions(mtd_banks[idx], part_banks[idx].mtd_part, 214 add_mtd_partitions(mtd_banks[idx], part_banks[idx].mtd_part,
215 part_banks[idx].nums); 215 part_banks[idx].nums);
216 } 216 }
217 } 217 }
@@ -224,10 +224,8 @@ int __init init_tqm_mtd(void)
224error_mem: 224error_mem:
225 for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) { 225 for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
226 if(map_banks[idx] != NULL) { 226 if(map_banks[idx] != NULL) {
227 if(map_banks[idx]->name != NULL) { 227 kfree(map_banks[idx]->name);
228 kfree(map_banks[idx]->name); 228 map_banks[idx]->name = NULL;
229 map_banks[idx]->name = NULL;
230 }
231 kfree(map_banks[idx]); 229 kfree(map_banks[idx]);
232 map_banks[idx] = NULL; 230 map_banks[idx] = NULL;
233 } 231 }
diff --git a/drivers/mtd/maps/ts5500_flash.c b/drivers/mtd/maps/ts5500_flash.c
index 3ebd90f56503..4b372bcb17f1 100644
--- a/drivers/mtd/maps/ts5500_flash.c
+++ b/drivers/mtd/maps/ts5500_flash.c
@@ -19,26 +19,22 @@
19 * 19 *
20 * Note: 20 * Note:
21 * - In order for detection to work, jumper 3 must be set. 21 * - In order for detection to work, jumper 3 must be set.
22 * - Drive A and B use a proprietary FTL from General Software which isn't 22 * - Drive A and B use the resident flash disk (RFD) flash translation layer.
23 * supported as of yet so standard drives can't be mounted; you can create 23 * - If you have created your own jffs file system and the bios overwrites
24 * your own (e.g. jffs) file system.
25 * - If you have created your own jffs file system and the bios overwrites
26 * it during boot, try disabling Drive A: and B: in the boot order. 24 * it during boot, try disabling Drive A: and B: in the boot order.
27 * 25 *
28 * $Id: ts5500_flash.c,v 1.2 2004/11/28 09:40:40 dwmw2 Exp $ 26 * $Id: ts5500_flash.c,v 1.5 2005/11/07 11:14:28 gleixner Exp $
29 */ 27 */
30 28
31#include <linux/config.h> 29#include <linux/config.h>
30#include <linux/init.h>
32#include <linux/module.h> 31#include <linux/module.h>
33#include <linux/types.h>
34#include <linux/kernel.h> 32#include <linux/kernel.h>
35#include <linux/init.h>
36#include <linux/mtd/mtd.h>
37#include <linux/mtd/map.h> 33#include <linux/mtd/map.h>
38 34#include <linux/mtd/mtd.h>
39#ifdef CONFIG_MTD_PARTITIONS
40#include <linux/mtd/partitions.h> 35#include <linux/mtd/partitions.h>
41#endif 36#include <linux/types.h>
37
42 38
43#define WINDOW_ADDR 0x09400000 39#define WINDOW_ADDR 0x09400000
44#define WINDOW_SIZE 0x00200000 40#define WINDOW_SIZE 0x00200000
@@ -50,7 +46,6 @@ static struct map_info ts5500_map = {
50 .phys = WINDOW_ADDR 46 .phys = WINDOW_ADDR
51}; 47};
52 48
53#ifdef CONFIG_MTD_PARTITIONS
54static struct mtd_partition ts5500_partitions[] = { 49static struct mtd_partition ts5500_partitions[] = {
55 { 50 {
56 .name = "Drive A", 51 .name = "Drive A",
@@ -71,8 +66,6 @@ static struct mtd_partition ts5500_partitions[] = {
71 66
72#define NUM_PARTITIONS (sizeof(ts5500_partitions)/sizeof(struct mtd_partition)) 67#define NUM_PARTITIONS (sizeof(ts5500_partitions)/sizeof(struct mtd_partition))
73 68
74#endif
75
76static struct mtd_info *mymtd; 69static struct mtd_info *mymtd;
77 70
78static int __init init_ts5500_map(void) 71static int __init init_ts5500_map(void)
@@ -81,48 +74,39 @@ static int __init init_ts5500_map(void)
81 74
82 ts5500_map.virt = ioremap_nocache(ts5500_map.phys, ts5500_map.size); 75 ts5500_map.virt = ioremap_nocache(ts5500_map.phys, ts5500_map.size);
83 76
84 if(!ts5500_map.virt) { 77 if (!ts5500_map.virt) {
85 printk(KERN_ERR "Failed to ioremap_nocache\n"); 78 printk(KERN_ERR "Failed to ioremap_nocache\n");
86 rc = -EIO; 79 rc = -EIO;
87 goto err_out_ioremap; 80 goto err2;
88 } 81 }
89 82
90 simple_map_init(&ts5500_map); 83 simple_map_init(&ts5500_map);
91 84
92 mymtd = do_map_probe("jedec_probe", &ts5500_map); 85 mymtd = do_map_probe("jedec_probe", &ts5500_map);
93 if(!mymtd) 86 if (!mymtd)
94 mymtd = do_map_probe("map_rom", &ts5500_map); 87 mymtd = do_map_probe("map_rom", &ts5500_map);
95 88
96 if(!mymtd) { 89 if (!mymtd) {
97 rc = -ENXIO; 90 rc = -ENXIO;
98 goto err_out_map; 91 goto err1;
99 } 92 }
100 93
101 mymtd->owner = THIS_MODULE; 94 mymtd->owner = THIS_MODULE;
102#ifdef CONFIG_MTD_PARTITIONS
103 add_mtd_partitions(mymtd, ts5500_partitions, NUM_PARTITIONS); 95 add_mtd_partitions(mymtd, ts5500_partitions, NUM_PARTITIONS);
104#else
105 add_mtd_device(mymtd);
106#endif
107 96
108 return 0; 97 return 0;
109 98
110err_out_map: 99err1:
111 map_destroy(mymtd); 100 map_destroy(mymtd);
112err_out_ioremap:
113 iounmap(ts5500_map.virt); 101 iounmap(ts5500_map.virt);
114 102err2:
115 return rc; 103 return rc;
116} 104}
117 105
118static void __exit cleanup_ts5500_map(void) 106static void __exit cleanup_ts5500_map(void)
119{ 107{
120 if (mymtd) { 108 if (mymtd) {
121#ifdef CONFIG_MTD_PARTITIONS
122 del_mtd_partitions(mymtd); 109 del_mtd_partitions(mymtd);
123#else
124 del_mtd_device(mymtd);
125#endif
126 map_destroy(mymtd); 110 map_destroy(mymtd);
127 } 111 }
128 112
diff --git a/drivers/mtd/maps/tsunami_flash.c b/drivers/mtd/maps/tsunami_flash.c
index 170d71239e5e..9e21e6c02f80 100644
--- a/drivers/mtd/maps/tsunami_flash.c
+++ b/drivers/mtd/maps/tsunami_flash.c
@@ -2,7 +2,7 @@
2 * tsunami_flash.c 2 * tsunami_flash.c
3 * 3 *
4 * flash chip on alpha ds10... 4 * flash chip on alpha ds10...
5 * $Id: tsunami_flash.c,v 1.9 2004/07/14 09:52:55 dwmw2 Exp $ 5 * $Id: tsunami_flash.c,v 1.10 2005/11/07 11:14:29 gleixner Exp $
6 */ 6 */
7#include <asm/io.h> 7#include <asm/io.h>
8#include <asm/core_tsunami.h> 8#include <asm/core_tsunami.h>
@@ -41,7 +41,7 @@ static void tsunami_flash_copy_from(
41} 41}
42 42
43static void tsunami_flash_copy_to( 43static void tsunami_flash_copy_to(
44 struct map_info *map, unsigned long offset, 44 struct map_info *map, unsigned long offset,
45 const void *addr, ssize_t len) 45 const void *addr, ssize_t len)
46{ 46{
47 const unsigned char *src; 47 const unsigned char *src;
@@ -90,7 +90,7 @@ static int __init init_tsunami_flash(void)
90 char **type; 90 char **type;
91 91
92 tsunami_tig_writeb(FLASH_ENABLE_BYTE, FLASH_ENABLE_PORT); 92 tsunami_tig_writeb(FLASH_ENABLE_BYTE, FLASH_ENABLE_PORT);
93 93
94 tsunami_flash_mtd = 0; 94 tsunami_flash_mtd = 0;
95 type = rom_probe_types; 95 type = rom_probe_types;
96 for(; !tsunami_flash_mtd && *type; type++) { 96 for(; !tsunami_flash_mtd && *type; type++) {
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
index cc372136e852..79d92808b766 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) 6 * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
7 * 7 *
8 * $Id: uclinux.c,v 1.10 2005/01/05 18:05:13 dwmw2 Exp $ 8 * $Id: uclinux.c,v 1.12 2005/11/07 11:14:29 gleixner Exp $
9 */ 9 */
10 10
11/****************************************************************************/ 11/****************************************************************************/
@@ -82,7 +82,7 @@ int __init uclinux_mtd_init(void)
82 iounmap(mapp->virt); 82 iounmap(mapp->virt);
83 return(-ENXIO); 83 return(-ENXIO);
84 } 84 }
85 85
86 mtd->owner = THIS_MODULE; 86 mtd->owner = THIS_MODULE;
87 mtd->point = uclinux_point; 87 mtd->point = uclinux_point;
88 mtd->priv = mapp; 88 mtd->priv = mapp;
diff --git a/drivers/mtd/maps/vmax301.c b/drivers/mtd/maps/vmax301.c
index c8c74110ed1b..e0063941c0df 100644
--- a/drivers/mtd/maps/vmax301.c
+++ b/drivers/mtd/maps/vmax301.c
@@ -1,19 +1,19 @@
1// $Id: vmax301.c,v 1.30 2004/07/12 22:38:29 dwmw2 Exp $ 1// $Id: vmax301.c,v 1.32 2005/11/07 11:14:29 gleixner Exp $
2/* ###################################################################### 2/* ######################################################################
3 3
4 Tempustech VMAX SBC301 MTD Driver. 4 Tempustech VMAX SBC301 MTD Driver.
5 5
6 The VMAx 301 is a SBC based on . It 6 The VMAx 301 is a SBC based on . It
7 comes with three builtin AMD 29F016B flash chips and a socket for SRAM or 7 comes with three builtin AMD 29F016B flash chips and a socket for SRAM or
8 more flash. Each unit has it's own 8k mapping into a settable region 8 more flash. Each unit has it's own 8k mapping into a settable region
9 (0xD8000). There are two 8k mappings for each MTD, the first is always set 9 (0xD8000). There are two 8k mappings for each MTD, the first is always set
10 to the lower 8k of the device the second is paged. Writing a 16 bit page 10 to the lower 8k of the device the second is paged. Writing a 16 bit page
11 value to anywhere in the first 8k will cause the second 8k to page around. 11 value to anywhere in the first 8k will cause the second 8k to page around.
12 12
13 To boot the device a bios extension must be installed into the first 8k 13 To boot the device a bios extension must be installed into the first 8k
14 of flash that is smart enough to copy itself down, page in the rest of 14 of flash that is smart enough to copy itself down, page in the rest of
15 itself and begin executing. 15 itself and begin executing.
16 16
17 ##################################################################### */ 17 ##################################################################### */
18 18
19#include <linux/module.h> 19#include <linux/module.h>
@@ -35,7 +35,7 @@
35/* Actually we could use two spinlocks, but we'd have to have 35/* Actually we could use two spinlocks, but we'd have to have
36 more private space in the struct map_info. We lose a little 36 more private space in the struct map_info. We lose a little
37 performance like this, but we'd probably lose more by having 37 performance like this, but we'd probably lose more by having
38 the extra indirection from having one of the map->map_priv 38 the extra indirection from having one of the map->map_priv
39 fields pointing to yet another private struct. 39 fields pointing to yet another private struct.
40*/ 40*/
41static DEFINE_SPINLOCK(vmax301_spin); 41static DEFINE_SPINLOCK(vmax301_spin);
@@ -98,7 +98,7 @@ static void vmax301_copy_to(struct map_info *map, unsigned long to, const void *
98 spin_lock(&vmax301_spin); 98 spin_lock(&vmax301_spin);
99 vmax301_page(map, to); 99 vmax301_page(map, to);
100 memcpy_toio(map->map_priv_2 + to, from, thislen); 100 memcpy_toio(map->map_priv_2 + to, from, thislen);
101 spin_unlock(&vmax301_spin); 101 spin_unlock(&vmax301_spin);
102 to += thislen; 102 to += thislen;
103 from += thislen; 103 from += thislen;
104 len -= thislen; 104 len -= thislen;
@@ -137,7 +137,7 @@ static struct mtd_info *vmax_mtd[2] = {NULL, NULL};
137static void __exit cleanup_vmax301(void) 137static void __exit cleanup_vmax301(void)
138{ 138{
139 int i; 139 int i;
140 140
141 for (i=0; i<2; i++) { 141 for (i=0; i<2; i++) {
142 if (vmax_mtd[i]) { 142 if (vmax_mtd[i]) {
143 del_mtd_device(vmax_mtd[i]); 143 del_mtd_device(vmax_mtd[i]);
@@ -161,13 +161,13 @@ int __init init_vmax301(void)
161 return -EIO; 161 return -EIO;
162 } 162 }
163 /* Put the address in the map's private data area. 163 /* Put the address in the map's private data area.
164 We store the actual MTD IO address rather than the 164 We store the actual MTD IO address rather than the
165 address of the first half, because it's used more 165 address of the first half, because it's used more
166 often. 166 often.
167 */ 167 */
168 vmax_map[0].map_priv_2 = iomapadr + WINDOW_START; 168 vmax_map[0].map_priv_2 = iomapadr + WINDOW_START;
169 vmax_map[1].map_priv_2 = iomapadr + (3*WINDOW_START); 169 vmax_map[1].map_priv_2 = iomapadr + (3*WINDOW_START);
170 170
171 for (i=0; i<2; i++) { 171 for (i=0; i<2; i++) {
172 vmax_mtd[i] = do_map_probe("cfi_probe", &vmax_map[i]); 172 vmax_mtd[i] = do_map_probe("cfi_probe", &vmax_map[i]);
173 if (!vmax_mtd[i]) 173 if (!vmax_mtd[i])
diff --git a/drivers/mtd/maps/walnut.c b/drivers/mtd/maps/walnut.c
index d6137b1b5670..5c17bca3a37e 100644
--- a/drivers/mtd/maps/walnut.c
+++ b/drivers/mtd/maps/walnut.c
@@ -1,12 +1,12 @@
1/* 1/*
2 * $Id: walnut.c,v 1.2 2004/12/10 12:07:42 holindho Exp $ 2 * $Id: walnut.c,v 1.3 2005/11/07 11:14:29 gleixner Exp $
3 * 3 *
4 * Mapping for Walnut flash 4 * Mapping for Walnut flash
5 * (used ebony.c as a "framework") 5 * (used ebony.c as a "framework")
6 * 6 *
7 * Heikki Lindholm <holindho@infradead.org> 7 * Heikki Lindholm <holindho@infradead.org>
8 * 8 *
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the 11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your 12 * Free Software Foundation; either version 2 of the License, or (at your
@@ -48,7 +48,7 @@ static struct mtd_partition walnut_partitions[] = {
48 .name = "OpenBIOS", 48 .name = "OpenBIOS",
49 .offset = 0x0, 49 .offset = 0x0,
50 .size = WALNUT_FLASH_SIZE, 50 .size = WALNUT_FLASH_SIZE,
51 /*.mask_flags = MTD_WRITEABLE, */ /* force read-only */ 51 /*.mask_flags = MTD_WRITEABLE, */ /* force read-only */
52 } 52 }
53}; 53};
54 54
@@ -72,11 +72,11 @@ int __init init_walnut(void)
72 printk("The on-board flash is disabled (U79 sw 5)!"); 72 printk("The on-board flash is disabled (U79 sw 5)!");
73 return -EIO; 73 return -EIO;
74 } 74 }
75 if (WALNUT_FLASH_SRAM_SEL(fpga_brds1)) 75 if (WALNUT_FLASH_SRAM_SEL(fpga_brds1))
76 flash_base = WALNUT_FLASH_LOW; 76 flash_base = WALNUT_FLASH_LOW;
77 else 77 else
78 flash_base = WALNUT_FLASH_HIGH; 78 flash_base = WALNUT_FLASH_HIGH;
79 79
80 walnut_map.phys = flash_base; 80 walnut_map.phys = flash_base;
81 walnut_map.virt = 81 walnut_map.virt =
82 (void __iomem *)ioremap(flash_base, walnut_map.size); 82 (void __iomem *)ioremap(flash_base, walnut_map.size);
diff --git a/drivers/mtd/maps/wr_sbc82xx_flash.c b/drivers/mtd/maps/wr_sbc82xx_flash.c
index 82b887b05707..60c197ec455b 100644
--- a/drivers/mtd/maps/wr_sbc82xx_flash.c
+++ b/drivers/mtd/maps/wr_sbc82xx_flash.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: wr_sbc82xx_flash.c,v 1.7 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: wr_sbc82xx_flash.c,v 1.8 2005/11/07 11:14:29 gleixner Exp $
3 * 3 *
4 * Map for flash chips on Wind River PowerQUICC II SBC82xx board. 4 * Map for flash chips on Wind River PowerQUICC II SBC82xx board.
5 * 5 *
@@ -163,10 +163,10 @@ static void __exit cleanup_sbc82xx_flash(void)
163 del_mtd_partitions(sbcmtd[i]); 163 del_mtd_partitions(sbcmtd[i]);
164 else 164 else
165 del_mtd_device(sbcmtd[i]); 165 del_mtd_device(sbcmtd[i]);
166 166
167 kfree(sbcmtd_parts[i]); 167 kfree(sbcmtd_parts[i]);
168 map_destroy(sbcmtd[i]); 168 map_destroy(sbcmtd[i]);
169 169
170 iounmap((void *)sbc82xx_flash_map[i].virt); 170 iounmap((void *)sbc82xx_flash_map[i].virt);
171 sbc82xx_flash_map[i].virt = 0; 171 sbc82xx_flash_map[i].virt = 0;
172 } 172 }
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index f8d2185819e7..339cb1218eaa 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: mtd_blkdevs.c,v 1.24 2004/11/16 18:28:59 dwmw2 Exp $ 2 * $Id: mtd_blkdevs.c,v 1.27 2005/11/07 11:14:20 gleixner Exp $
3 * 3 *
4 * (C) 2003 David Woodhouse <dwmw2@infradead.org> 4 * (C) 2003 David Woodhouse <dwmw2@infradead.org>
5 * 5 *
@@ -21,7 +21,6 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <asm/semaphore.h> 22#include <asm/semaphore.h>
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <linux/devfs_fs_kernel.h>
25 24
26static LIST_HEAD(blktrans_majors); 25static LIST_HEAD(blktrans_majors);
27 26
@@ -86,7 +85,7 @@ static int mtd_blktrans_thread(void *arg)
86 daemonize("%sd", tr->name); 85 daemonize("%sd", tr->name);
87 86
88 /* daemonize() doesn't do this for us since some kernel threads 87 /* daemonize() doesn't do this for us since some kernel threads
89 actually want to deal with signals. We can't just call 88 actually want to deal with signals. We can't just call
90 exit_sighand() since that'll cause an oops when we finally 89 exit_sighand() since that'll cause an oops when we finally
91 do exit. */ 90 do exit. */
92 spin_lock_irq(&current->sighand->siglock); 91 spin_lock_irq(&current->sighand->siglock);
@@ -95,7 +94,7 @@ static int mtd_blktrans_thread(void *arg)
95 spin_unlock_irq(&current->sighand->siglock); 94 spin_unlock_irq(&current->sighand->siglock);
96 95
97 spin_lock_irq(rq->queue_lock); 96 spin_lock_irq(rq->queue_lock);
98 97
99 while (!tr->blkcore_priv->exiting) { 98 while (!tr->blkcore_priv->exiting) {
100 struct request *req; 99 struct request *req;
101 struct mtd_blktrans_dev *dev; 100 struct mtd_blktrans_dev *dev;
@@ -158,7 +157,7 @@ static int blktrans_open(struct inode *i, struct file *f)
158 if (!try_module_get(tr->owner)) 157 if (!try_module_get(tr->owner))
159 goto out_tr; 158 goto out_tr;
160 159
161 /* FIXME: Locking. A hot pluggable device can go away 160 /* FIXME: Locking. A hot pluggable device can go away
162 (del_mtd_device can be called for it) without its module 161 (del_mtd_device can be called for it) without its module
163 being unloaded. */ 162 being unloaded. */
164 dev->mtd->usecount++; 163 dev->mtd->usecount++;
@@ -196,7 +195,7 @@ static int blktrans_release(struct inode *i, struct file *f)
196} 195}
197 196
198 197
199static int blktrans_ioctl(struct inode *inode, struct file *file, 198static int blktrans_ioctl(struct inode *inode, struct file *file,
200 unsigned int cmd, unsigned long arg) 199 unsigned int cmd, unsigned long arg)
201{ 200{
202 struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data; 201 struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data;
@@ -265,7 +264,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
265 /* Required number was free */ 264 /* Required number was free */
266 list_add_tail(&new->list, &d->list); 265 list_add_tail(&new->list, &d->list);
267 goto added; 266 goto added;
268 } 267 }
269 last_devnum = d->devnum; 268 last_devnum = d->devnum;
270 } 269 }
271 if (new->devnum == -1) 270 if (new->devnum == -1)
@@ -289,11 +288,19 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
289 gd->major = tr->major; 288 gd->major = tr->major;
290 gd->first_minor = (new->devnum) << tr->part_bits; 289 gd->first_minor = (new->devnum) << tr->part_bits;
291 gd->fops = &mtd_blktrans_ops; 290 gd->fops = &mtd_blktrans_ops;
292 291
293 snprintf(gd->disk_name, sizeof(gd->disk_name), 292 if (tr->part_bits)
294 "%s%c", tr->name, (tr->part_bits?'a':'0') + new->devnum); 293 if (new->devnum < 26)
295 snprintf(gd->devfs_name, sizeof(gd->devfs_name), 294 snprintf(gd->disk_name, sizeof(gd->disk_name),
296 "%s/%c", tr->name, (tr->part_bits?'a':'0') + new->devnum); 295 "%s%c", tr->name, 'a' + new->devnum);
296 else
297 snprintf(gd->disk_name, sizeof(gd->disk_name),
298 "%s%c%c", tr->name,
299 'a' - 1 + new->devnum / 26,
300 'a' + new->devnum % 26);
301 else
302 snprintf(gd->disk_name, sizeof(gd->disk_name),
303 "%s%d", tr->name, new->devnum);
297 304
298 /* 2.5 has capacity in units of 512 bytes while still 305 /* 2.5 has capacity in units of 512 bytes while still
299 having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */ 306 having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */
@@ -307,7 +314,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
307 set_disk_ro(gd, 1); 314 set_disk_ro(gd, 1);
308 315
309 add_disk(gd); 316 add_disk(gd);
310 317
311 return 0; 318 return 0;
312} 319}
313 320
@@ -322,7 +329,7 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
322 329
323 del_gendisk(old->blkcore_priv); 330 del_gendisk(old->blkcore_priv);
324 put_disk(old->blkcore_priv); 331 put_disk(old->blkcore_priv);
325 332
326 return 0; 333 return 0;
327} 334}
328 335
@@ -361,12 +368,12 @@ static struct mtd_notifier blktrans_notifier = {
361 .add = blktrans_notify_add, 368 .add = blktrans_notify_add,
362 .remove = blktrans_notify_remove, 369 .remove = blktrans_notify_remove,
363}; 370};
364 371
365int register_mtd_blktrans(struct mtd_blktrans_ops *tr) 372int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
366{ 373{
367 int ret, i; 374 int ret, i;
368 375
369 /* Register the notifier if/when the first device type is 376 /* Register the notifier if/when the first device type is
370 registered, to prevent the link/init ordering from fucking 377 registered, to prevent the link/init ordering from fucking
371 us over. */ 378 us over. */
372 if (!blktrans_notifier.list.next) 379 if (!blktrans_notifier.list.next)
@@ -409,9 +416,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
409 kfree(tr->blkcore_priv); 416 kfree(tr->blkcore_priv);
410 up(&mtd_table_mutex); 417 up(&mtd_table_mutex);
411 return ret; 418 return ret;
412 } 419 }
413
414 devfs_mk_dir(tr->name);
415 420
416 INIT_LIST_HEAD(&tr->devs); 421 INIT_LIST_HEAD(&tr->devs);
417 list_add(&tr->list, &blktrans_majors); 422 list_add(&tr->list, &blktrans_majors);
@@ -445,7 +450,6 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
445 tr->remove_dev(dev); 450 tr->remove_dev(dev);
446 } 451 }
447 452
448 devfs_remove(tr->name);
449 blk_cleanup_queue(tr->blkcore_priv->rq); 453 blk_cleanup_queue(tr->blkcore_priv->rq);
450 unregister_blkdev(tr->major, tr->name); 454 unregister_blkdev(tr->major, tr->name);
451 455
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index 400dd9c89883..e84756644fd1 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -1,21 +1,22 @@
1/* 1/*
2 * Direct MTD block device access 2 * Direct MTD block device access
3 * 3 *
4 * $Id: mtdblock.c,v 1.66 2004/11/25 13:52:52 joern Exp $ 4 * $Id: mtdblock.c,v 1.68 2005/11/07 11:14:20 gleixner Exp $
5 * 5 *
6 * (C) 2000-2003 Nicolas Pitre <nico@cam.org> 6 * (C) 2000-2003 Nicolas Pitre <nico@cam.org>
7 * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> 7 * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
8 */ 8 */
9 9
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/types.h>
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/fs.h> 11#include <linux/fs.h>
15#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/sched.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/types.h>
17#include <linux/vmalloc.h> 18#include <linux/vmalloc.h>
18#include <linux/sched.h> /* TASK_* */ 19
19#include <linux/mtd/mtd.h> 20#include <linux/mtd/mtd.h>
20#include <linux/mtd/blktrans.h> 21#include <linux/mtd/blktrans.h>
21 22
@@ -31,7 +32,7 @@ static struct mtdblk_dev {
31 32
32/* 33/*
33 * Cache stuff... 34 * Cache stuff...
34 * 35 *
35 * Since typical flash erasable sectors are much larger than what Linux's 36 * Since typical flash erasable sectors are much larger than what Linux's
36 * buffer cache can handle, we must implement read-modify-write on flash 37 * buffer cache can handle, we must implement read-modify-write on flash
37 * sectors for each block write requests. To avoid over-erasing flash sectors 38 * sectors for each block write requests. To avoid over-erasing flash sectors
@@ -45,7 +46,7 @@ static void erase_callback(struct erase_info *done)
45 wake_up(wait_q); 46 wake_up(wait_q);
46} 47}
47 48
48static int erase_write (struct mtd_info *mtd, unsigned long pos, 49static int erase_write (struct mtd_info *mtd, unsigned long pos,
49 int len, const char *buf) 50 int len, const char *buf)
50{ 51{
51 struct erase_info erase; 52 struct erase_info erase;
@@ -103,18 +104,18 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
103 return 0; 104 return 0;
104 105
105 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" " 106 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" "
106 "at 0x%lx, size 0x%x\n", mtd->name, 107 "at 0x%lx, size 0x%x\n", mtd->name,
107 mtdblk->cache_offset, mtdblk->cache_size); 108 mtdblk->cache_offset, mtdblk->cache_size);
108 109
109 ret = erase_write (mtd, mtdblk->cache_offset, 110 ret = erase_write (mtd, mtdblk->cache_offset,
110 mtdblk->cache_size, mtdblk->cache_data); 111 mtdblk->cache_size, mtdblk->cache_data);
111 if (ret) 112 if (ret)
112 return ret; 113 return ret;
113 114
114 /* 115 /*
115 * Here we could argubly set the cache state to STATE_CLEAN. 116 * Here we could argubly set the cache state to STATE_CLEAN.
116 * However this could lead to inconsistency since we will not 117 * However this could lead to inconsistency since we will not
117 * be notified if this content is altered on the flash by other 118 * be notified if this content is altered on the flash by other
118 * means. Let's declare it empty and leave buffering tasks to 119 * means. Let's declare it empty and leave buffering tasks to
119 * the buffer cache instead. 120 * the buffer cache instead.
120 */ 121 */
@@ -123,7 +124,7 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
123} 124}
124 125
125 126
126static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, 127static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
127 int len, const char *buf) 128 int len, const char *buf)
128{ 129{
129 struct mtd_info *mtd = mtdblk->mtd; 130 struct mtd_info *mtd = mtdblk->mtd;
@@ -133,7 +134,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
133 134
134 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n", 135 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n",
135 mtd->name, pos, len); 136 mtd->name, pos, len);
136 137
137 if (!sect_size) 138 if (!sect_size)
138 return MTD_WRITE (mtd, pos, len, &retlen, buf); 139 return MTD_WRITE (mtd, pos, len, &retlen, buf);
139 140
@@ -141,11 +142,11 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
141 unsigned long sect_start = (pos/sect_size)*sect_size; 142 unsigned long sect_start = (pos/sect_size)*sect_size;
142 unsigned int offset = pos - sect_start; 143 unsigned int offset = pos - sect_start;
143 unsigned int size = sect_size - offset; 144 unsigned int size = sect_size - offset;
144 if( size > len ) 145 if( size > len )
145 size = len; 146 size = len;
146 147
147 if (size == sect_size) { 148 if (size == sect_size) {
148 /* 149 /*
149 * We are covering a whole sector. Thus there is no 150 * We are covering a whole sector. Thus there is no
150 * need to bother with the cache while it may still be 151 * need to bother with the cache while it may still be
151 * useful for other partial writes. 152 * useful for other partial writes.
@@ -159,7 +160,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
159 if (mtdblk->cache_state == STATE_DIRTY && 160 if (mtdblk->cache_state == STATE_DIRTY &&
160 mtdblk->cache_offset != sect_start) { 161 mtdblk->cache_offset != sect_start) {
161 ret = write_cached_data(mtdblk); 162 ret = write_cached_data(mtdblk);
162 if (ret) 163 if (ret)
163 return ret; 164 return ret;
164 } 165 }
165 166
@@ -192,7 +193,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
192} 193}
193 194
194 195
195static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, 196static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
196 int len, char *buf) 197 int len, char *buf)
197{ 198{
198 struct mtd_info *mtd = mtdblk->mtd; 199 struct mtd_info *mtd = mtdblk->mtd;
@@ -200,9 +201,9 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
200 size_t retlen; 201 size_t retlen;
201 int ret; 202 int ret;
202 203
203 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n", 204 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
204 mtd->name, pos, len); 205 mtd->name, pos, len);
205 206
206 if (!sect_size) 207 if (!sect_size)
207 return MTD_READ (mtd, pos, len, &retlen, buf); 208 return MTD_READ (mtd, pos, len, &retlen, buf);
208 209
@@ -210,7 +211,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
210 unsigned long sect_start = (pos/sect_size)*sect_size; 211 unsigned long sect_start = (pos/sect_size)*sect_size;
211 unsigned int offset = pos - sect_start; 212 unsigned int offset = pos - sect_start;
212 unsigned int size = sect_size - offset; 213 unsigned int size = sect_size - offset;
213 if (size > len) 214 if (size > len)
214 size = len; 215 size = len;
215 216
216 /* 217 /*
@@ -268,12 +269,12 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
268 int dev = mbd->devnum; 269 int dev = mbd->devnum;
269 270
270 DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n"); 271 DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
271 272
272 if (mtdblks[dev]) { 273 if (mtdblks[dev]) {
273 mtdblks[dev]->count++; 274 mtdblks[dev]->count++;
274 return 0; 275 return 0;
275 } 276 }
276 277
277 /* OK, it's not open. Create cache info for it */ 278 /* OK, it's not open. Create cache info for it */
278 mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL); 279 mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
279 if (!mtdblk) 280 if (!mtdblk)
@@ -292,7 +293,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
292 } 293 }
293 294
294 mtdblks[dev] = mtdblk; 295 mtdblks[dev] = mtdblk;
295 296
296 DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); 297 DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
297 298
298 return 0; 299 return 0;
@@ -320,7 +321,7 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
320 DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); 321 DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
321 322
322 return 0; 323 return 0;
323} 324}
324 325
325static int mtdblock_flush(struct mtd_blktrans_dev *dev) 326static int mtdblock_flush(struct mtd_blktrans_dev *dev)
326{ 327{
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 16df1e4fb0e9..6f044584bdc6 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1,22 +1,23 @@
1/* 1/*
2 * $Id: mtdchar.c,v 1.73 2005/07/04 17:36:41 gleixner Exp $ 2 * $Id: mtdchar.c,v 1.76 2005/11/07 11:14:20 gleixner Exp $
3 * 3 *
4 * Character-device access to raw MTD devices. 4 * Character-device access to raw MTD devices.
5 * 5 *
6 */ 6 */
7 7
8#include <linux/config.h> 8#include <linux/config.h>
9#include <linux/device.h>
10#include <linux/fs.h>
11#include <linux/init.h>
9#include <linux/kernel.h> 12#include <linux/kernel.h>
10#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/sched.h>
16
11#include <linux/mtd/mtd.h> 17#include <linux/mtd/mtd.h>
12#include <linux/mtd/compatmac.h> 18#include <linux/mtd/compatmac.h>
13#include <linux/slab.h>
14#include <linux/init.h>
15#include <linux/fs.h>
16#include <linux/sched.h> /* TASK_* */
17#include <asm/uaccess.h>
18 19
19#include <linux/device.h> 20#include <asm/uaccess.h>
20 21
21static struct class *mtd_class; 22static struct class *mtd_class;
22 23
@@ -27,7 +28,7 @@ static void mtd_notify_add(struct mtd_info* mtd)
27 28
28 class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2), 29 class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
29 NULL, "mtd%d", mtd->index); 30 NULL, "mtd%d", mtd->index);
30 31
31 class_device_create(mtd_class, NULL, 32 class_device_create(mtd_class, NULL,
32 MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), 33 MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
33 NULL, "mtd%dro", mtd->index); 34 NULL, "mtd%dro", mtd->index);
@@ -70,26 +71,23 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
70 switch (orig) { 71 switch (orig) {
71 case 0: 72 case 0:
72 /* SEEK_SET */ 73 /* SEEK_SET */
73 file->f_pos = offset;
74 break; 74 break;
75 case 1: 75 case 1:
76 /* SEEK_CUR */ 76 /* SEEK_CUR */
77 file->f_pos += offset; 77 offset += file->f_pos;
78 break; 78 break;
79 case 2: 79 case 2:
80 /* SEEK_END */ 80 /* SEEK_END */
81 file->f_pos =mtd->size + offset; 81 offset += mtd->size;
82 break; 82 break;
83 default: 83 default:
84 return -EINVAL; 84 return -EINVAL;
85 } 85 }
86 86
87 if (file->f_pos < 0) 87 if (offset >= 0 && offset < mtd->size)
88 file->f_pos = 0; 88 return file->f_pos = offset;
89 else if (file->f_pos >= mtd->size)
90 file->f_pos = mtd->size - 1;
91 89
92 return file->f_pos; 90 return -EINVAL;
93} 91}
94 92
95 93
@@ -110,23 +108,23 @@ static int mtd_open(struct inode *inode, struct file *file)
110 return -EACCES; 108 return -EACCES;
111 109
112 mtd = get_mtd_device(NULL, devnum); 110 mtd = get_mtd_device(NULL, devnum);
113 111
114 if (!mtd) 112 if (!mtd)
115 return -ENODEV; 113 return -ENODEV;
116 114
117 if (MTD_ABSENT == mtd->type) { 115 if (MTD_ABSENT == mtd->type) {
118 put_mtd_device(mtd); 116 put_mtd_device(mtd);
119 return -ENODEV; 117 return -ENODEV;
120 } 118 }
121 119
122 file->private_data = mtd; 120 file->private_data = mtd;
123 121
124 /* You can't open it RW if it's not a writeable device */ 122 /* You can't open it RW if it's not a writeable device */
125 if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) { 123 if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) {
126 put_mtd_device(mtd); 124 put_mtd_device(mtd);
127 return -EACCES; 125 return -EACCES;
128 } 126 }
129 127
130 return 0; 128 return 0;
131} /* mtd_open */ 129} /* mtd_open */
132 130
@@ -139,10 +137,10 @@ static int mtd_close(struct inode *inode, struct file *file)
139 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n"); 137 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
140 138
141 mtd = TO_MTD(file); 139 mtd = TO_MTD(file);
142 140
143 if (mtd->sync) 141 if (mtd->sync)
144 mtd->sync(mtd); 142 mtd->sync(mtd);
145 143
146 put_mtd_device(mtd); 144 put_mtd_device(mtd);
147 145
148 return 0; 146 return 0;
@@ -161,7 +159,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
161 int ret=0; 159 int ret=0;
162 int len; 160 int len;
163 char *kbuf; 161 char *kbuf;
164 162
165 DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n"); 163 DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n");
166 164
167 if (*ppos + count > mtd->size) 165 if (*ppos + count > mtd->size)
@@ -169,11 +167,11 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
169 167
170 if (!count) 168 if (!count)
171 return 0; 169 return 0;
172 170
173 /* FIXME: Use kiovec in 2.5 to lock down the user's buffers 171 /* FIXME: Use kiovec in 2.5 to lock down the user's buffers
174 and pass them directly to the MTD functions */ 172 and pass them directly to the MTD functions */
175 while (count) { 173 while (count) {
176 if (count > MAX_KMALLOC_SIZE) 174 if (count > MAX_KMALLOC_SIZE)
177 len = MAX_KMALLOC_SIZE; 175 len = MAX_KMALLOC_SIZE;
178 else 176 else
179 len = count; 177 len = count;
@@ -181,7 +179,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
181 kbuf=kmalloc(len,GFP_KERNEL); 179 kbuf=kmalloc(len,GFP_KERNEL);
182 if (!kbuf) 180 if (!kbuf)
183 return -ENOMEM; 181 return -ENOMEM;
184 182
185 switch (MTD_MODE(file)) { 183 switch (MTD_MODE(file)) {
186 case MTD_MODE_OTP_FACT: 184 case MTD_MODE_OTP_FACT:
187 ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf); 185 ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf);
@@ -194,7 +192,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
194 } 192 }
195 /* Nand returns -EBADMSG on ecc errors, but it returns 193 /* Nand returns -EBADMSG on ecc errors, but it returns
196 * the data. For our userspace tools it is important 194 * the data. For our userspace tools it is important
197 * to dump areas with ecc errors ! 195 * to dump areas with ecc errors !
198 * Userspace software which accesses NAND this way 196 * Userspace software which accesses NAND this way
199 * must be aware of the fact that it deals with NAND 197 * must be aware of the fact that it deals with NAND
200 */ 198 */
@@ -216,7 +214,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
216 kfree(kbuf); 214 kfree(kbuf);
217 return ret; 215 return ret;
218 } 216 }
219 217
220 kfree(kbuf); 218 kfree(kbuf);
221 } 219 }
222 220
@@ -233,10 +231,10 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
233 int len; 231 int len;
234 232
235 DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n"); 233 DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n");
236 234
237 if (*ppos == mtd->size) 235 if (*ppos == mtd->size)
238 return -ENOSPC; 236 return -ENOSPC;
239 237
240 if (*ppos + count > mtd->size) 238 if (*ppos + count > mtd->size)
241 count = mtd->size - *ppos; 239 count = mtd->size - *ppos;
242 240
@@ -244,7 +242,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
244 return 0; 242 return 0;
245 243
246 while (count) { 244 while (count) {
247 if (count > MAX_KMALLOC_SIZE) 245 if (count > MAX_KMALLOC_SIZE)
248 len = MAX_KMALLOC_SIZE; 246 len = MAX_KMALLOC_SIZE;
249 else 247 else
250 len = count; 248 len = count;
@@ -259,7 +257,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
259 kfree(kbuf); 257 kfree(kbuf);
260 return -EFAULT; 258 return -EFAULT;
261 } 259 }
262 260
263 switch (MTD_MODE(file)) { 261 switch (MTD_MODE(file)) {
264 case MTD_MODE_OTP_FACT: 262 case MTD_MODE_OTP_FACT:
265 ret = -EROFS; 263 ret = -EROFS;
@@ -284,7 +282,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
284 kfree(kbuf); 282 kfree(kbuf);
285 return ret; 283 return ret;
286 } 284 }
287 285
288 kfree(kbuf); 286 kfree(kbuf);
289 } 287 }
290 288
@@ -308,7 +306,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
308 void __user *argp = (void __user *)arg; 306 void __user *argp = (void __user *)arg;
309 int ret = 0; 307 int ret = 0;
310 u_long size; 308 u_long size;
311 309
312 DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n"); 310 DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n");
313 311
314 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT; 312 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
@@ -320,7 +318,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
320 if (!access_ok(VERIFY_WRITE, argp, size)) 318 if (!access_ok(VERIFY_WRITE, argp, size))
321 return -EFAULT; 319 return -EFAULT;
322 } 320 }
323 321
324 switch (cmd) { 322 switch (cmd) {
325 case MEMGETREGIONCOUNT: 323 case MEMGETREGIONCOUNT:
326 if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int))) 324 if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int)))
@@ -372,11 +370,11 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
372 erase->mtd = mtd; 370 erase->mtd = mtd;
373 erase->callback = mtdchar_erase_callback; 371 erase->callback = mtdchar_erase_callback;
374 erase->priv = (unsigned long)&waitq; 372 erase->priv = (unsigned long)&waitq;
375 373
376 /* 374 /*
377 FIXME: Allow INTERRUPTIBLE. Which means 375 FIXME: Allow INTERRUPTIBLE. Which means
378 not having the wait_queue head on the stack. 376 not having the wait_queue head on the stack.
379 377
380 If the wq_head is on the stack, and we 378 If the wq_head is on the stack, and we
381 leave because we got interrupted, then the 379 leave because we got interrupted, then the
382 wq_head is no longer there when the 380 wq_head is no longer there when the
@@ -404,13 +402,13 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
404 struct mtd_oob_buf buf; 402 struct mtd_oob_buf buf;
405 void *databuf; 403 void *databuf;
406 ssize_t retlen; 404 ssize_t retlen;
407 405
408 if(!(file->f_mode & 2)) 406 if(!(file->f_mode & 2))
409 return -EPERM; 407 return -EPERM;
410 408
411 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) 409 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
412 return -EFAULT; 410 return -EFAULT;
413 411
414 if (buf.length > 0x4096) 412 if (buf.length > 0x4096)
415 return -EINVAL; 413 return -EINVAL;
416 414
@@ -426,7 +424,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
426 databuf = kmalloc(buf.length, GFP_KERNEL); 424 databuf = kmalloc(buf.length, GFP_KERNEL);
427 if (!databuf) 425 if (!databuf)
428 return -ENOMEM; 426 return -ENOMEM;
429 427
430 if (copy_from_user(databuf, buf.ptr, buf.length)) { 428 if (copy_from_user(databuf, buf.ptr, buf.length)) {
431 kfree(databuf); 429 kfree(databuf);
432 return -EFAULT; 430 return -EFAULT;
@@ -450,7 +448,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
450 448
451 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) 449 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
452 return -EFAULT; 450 return -EFAULT;
453 451
454 if (buf.length > 0x4096) 452 if (buf.length > 0x4096)
455 return -EINVAL; 453 return -EINVAL;
456 454
@@ -466,14 +464,14 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
466 databuf = kmalloc(buf.length, GFP_KERNEL); 464 databuf = kmalloc(buf.length, GFP_KERNEL);
467 if (!databuf) 465 if (!databuf)
468 return -ENOMEM; 466 return -ENOMEM;
469 467
470 ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf); 468 ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf);
471 469
472 if (put_user(retlen, (uint32_t __user *)argp)) 470 if (put_user(retlen, (uint32_t __user *)argp))
473 ret = -EFAULT; 471 ret = -EFAULT;
474 else if (retlen && copy_to_user(buf.ptr, databuf, retlen)) 472 else if (retlen && copy_to_user(buf.ptr, databuf, retlen))
475 ret = -EFAULT; 473 ret = -EFAULT;
476 474
477 kfree(databuf); 475 kfree(databuf);
478 break; 476 break;
479 } 477 }
@@ -523,7 +521,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
523 case MEMGETBADBLOCK: 521 case MEMGETBADBLOCK:
524 { 522 {
525 loff_t offs; 523 loff_t offs;
526 524
527 if (copy_from_user(&offs, argp, sizeof(loff_t))) 525 if (copy_from_user(&offs, argp, sizeof(loff_t)))
528 return -EFAULT; 526 return -EFAULT;
529 if (!mtd->block_isbad) 527 if (!mtd->block_isbad)
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index f3e65af33a9c..b1bf8c411de7 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -7,14 +7,15 @@
7 * 7 *
8 * This code is GPL 8 * This code is GPL
9 * 9 *
10 * $Id: mtdconcat.c,v 1.9 2004/06/30 15:17:41 dbrown Exp $ 10 * $Id: mtdconcat.c,v 1.11 2005/11/07 11:14:20 gleixner Exp $
11 */ 11 */
12 12
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/module.h>
16#include <linux/slab.h> 15#include <linux/slab.h>
17#include <linux/sched.h> /* TASK_* */ 16#include <linux/sched.h>
17#include <linux/types.h>
18
18#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
19#include <linux/mtd/concat.h> 20#include <linux/mtd/concat.h>
20 21
@@ -43,7 +44,7 @@ struct mtd_concat {
43 */ 44 */
44#define CONCAT(x) ((struct mtd_concat *)(x)) 45#define CONCAT(x) ((struct mtd_concat *)(x))
45 46
46/* 47/*
47 * MTD methods which look up the relevant subdevice, translate the 48 * MTD methods which look up the relevant subdevice, translate the
48 * effective address and pass through to the subdevice. 49 * effective address and pass through to the subdevice.
49 */ 50 */
@@ -877,7 +878,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
877 return &concat->mtd; 878 return &concat->mtd;
878} 879}
879 880
880/* 881/*
881 * This function destroys an MTD object obtained from concat_mtd_devs() 882 * This function destroys an MTD object obtained from concat_mtd_devs()
882 */ 883 */
883 884
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index dc86df18e94b..dade02ab0687 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: mtdcore.c,v 1.45 2005/02/18 14:34:50 dedekind Exp $ 2 * $Id: mtdcore.c,v 1.47 2005/11/07 11:14:20 gleixner Exp $
3 * 3 *
4 * Core registration and callback routines for MTD 4 * Core registration and callback routines for MTD
5 * drivers and users. 5 * drivers and users.
@@ -25,7 +25,7 @@
25 25
26#include <linux/mtd/mtd.h> 26#include <linux/mtd/mtd.h>
27 27
28/* These are exported solely for the purpose of mtd_blkdevs.c. You 28/* These are exported solely for the purpose of mtd_blkdevs.c. You
29 should not use them for _anything_ else */ 29 should not use them for _anything_ else */
30DECLARE_MUTEX(mtd_table_mutex); 30DECLARE_MUTEX(mtd_table_mutex);
31struct mtd_info *mtd_table[MAX_MTD_DEVICES]; 31struct mtd_info *mtd_table[MAX_MTD_DEVICES];
@@ -66,7 +66,7 @@ int add_mtd_device(struct mtd_info *mtd)
66 struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list); 66 struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);
67 not->add(mtd); 67 not->add(mtd);
68 } 68 }
69 69
70 up(&mtd_table_mutex); 70 up(&mtd_table_mutex);
71 /* We _know_ we aren't being removed, because 71 /* We _know_ we aren't being removed, because
72 our caller is still holding us here. So none 72 our caller is still holding us here. So none
@@ -75,7 +75,7 @@ int add_mtd_device(struct mtd_info *mtd)
75 __module_get(THIS_MODULE); 75 __module_get(THIS_MODULE);
76 return 0; 76 return 0;
77 } 77 }
78 78
79 up(&mtd_table_mutex); 79 up(&mtd_table_mutex);
80 return 1; 80 return 1;
81} 81}
@@ -93,13 +93,13 @@ int add_mtd_device(struct mtd_info *mtd)
93int del_mtd_device (struct mtd_info *mtd) 93int del_mtd_device (struct mtd_info *mtd)
94{ 94{
95 int ret; 95 int ret;
96 96
97 down(&mtd_table_mutex); 97 down(&mtd_table_mutex);
98 98
99 if (mtd_table[mtd->index] != mtd) { 99 if (mtd_table[mtd->index] != mtd) {
100 ret = -ENODEV; 100 ret = -ENODEV;
101 } else if (mtd->usecount) { 101 } else if (mtd->usecount) {
102 printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n", 102 printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n",
103 mtd->index, mtd->name, mtd->usecount); 103 mtd->index, mtd->name, mtd->usecount);
104 ret = -EBUSY; 104 ret = -EBUSY;
105 } else { 105 } else {
@@ -140,7 +140,7 @@ void register_mtd_user (struct mtd_notifier *new)
140 list_add(&new->list, &mtd_notifiers); 140 list_add(&new->list, &mtd_notifiers);
141 141
142 __module_get(THIS_MODULE); 142 __module_get(THIS_MODULE);
143 143
144 for (i=0; i< MAX_MTD_DEVICES; i++) 144 for (i=0; i< MAX_MTD_DEVICES; i++)
145 if (mtd_table[i]) 145 if (mtd_table[i])
146 new->add(mtd_table[i]); 146 new->add(mtd_table[i]);
@@ -169,7 +169,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
169 for (i=0; i< MAX_MTD_DEVICES; i++) 169 for (i=0; i< MAX_MTD_DEVICES; i++)
170 if (mtd_table[i]) 170 if (mtd_table[i])
171 old->remove(mtd_table[i]); 171 old->remove(mtd_table[i]);
172 172
173 list_del(&old->list); 173 list_del(&old->list);
174 up(&mtd_table_mutex); 174 up(&mtd_table_mutex);
175 return 0; 175 return 0;
@@ -187,7 +187,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
187 * both, return the num'th driver only if its address matches. Return NULL 187 * both, return the num'th driver only if its address matches. Return NULL
188 * if not. 188 * if not.
189 */ 189 */
190 190
191struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) 191struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
192{ 192{
193 struct mtd_info *ret = NULL; 193 struct mtd_info *ret = NULL;
@@ -297,39 +297,6 @@ EXPORT_SYMBOL(default_mtd_writev);
297EXPORT_SYMBOL(default_mtd_readv); 297EXPORT_SYMBOL(default_mtd_readv);
298 298
299/*====================================================================*/ 299/*====================================================================*/
300/* Power management code */
301
302#ifdef CONFIG_PM
303
304#include <linux/pm.h>
305
306static struct pm_dev *mtd_pm_dev = NULL;
307
308static int mtd_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
309{
310 int ret = 0, i;
311
312 if (down_trylock(&mtd_table_mutex))
313 return -EAGAIN;
314 if (rqst == PM_SUSPEND) {
315 for (i = 0; ret == 0 && i < MAX_MTD_DEVICES; i++) {
316 if (mtd_table[i] && mtd_table[i]->suspend)
317 ret = mtd_table[i]->suspend(mtd_table[i]);
318 }
319 } else i = MAX_MTD_DEVICES-1;
320
321 if (rqst == PM_RESUME || ret) {
322 for ( ; i >= 0; i--) {
323 if (mtd_table[i] && mtd_table[i]->resume)
324 mtd_table[i]->resume(mtd_table[i]);
325 }
326 }
327 up(&mtd_table_mutex);
328 return ret;
329}
330#endif
331
332/*====================================================================*/
333/* Support for /proc/mtd */ 300/* Support for /proc/mtd */
334 301
335#ifdef CONFIG_PROC_FS 302#ifdef CONFIG_PROC_FS
@@ -388,22 +355,11 @@ static int __init init_mtd(void)
388 if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) 355 if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
389 proc_mtd->read_proc = mtd_read_proc; 356 proc_mtd->read_proc = mtd_read_proc;
390#endif 357#endif
391
392#ifdef CONFIG_PM
393 mtd_pm_dev = pm_register(PM_UNKNOWN_DEV, 0, mtd_pm_callback);
394#endif
395 return 0; 358 return 0;
396} 359}
397 360
398static void __exit cleanup_mtd(void) 361static void __exit cleanup_mtd(void)
399{ 362{
400#ifdef CONFIG_PM
401 if (mtd_pm_dev) {
402 pm_unregister(mtd_pm_dev);
403 mtd_pm_dev = NULL;
404 }
405#endif
406
407#ifdef CONFIG_PROC_FS 363#ifdef CONFIG_PROC_FS
408 if (proc_mtd) 364 if (proc_mtd)
409 remove_proc_entry( "mtd", NULL); 365 remove_proc_entry( "mtd", NULL);
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index b92e6bfffaf2..99395911d26f 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -5,11 +5,11 @@
5 * 5 *
6 * This code is GPL 6 * This code is GPL
7 * 7 *
8 * $Id: mtdpart.c,v 1.53 2005/02/08 17:11:13 nico Exp $ 8 * $Id: mtdpart.c,v 1.55 2005/11/07 11:14:20 gleixner Exp $
9 * 9 *
10 * 02-21-2002 Thomas Gleixner <gleixner@autronix.de> 10 * 02-21-2002 Thomas Gleixner <gleixner@autronix.de>
11 * added support for read_oob, write_oob 11 * added support for read_oob, write_oob
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/types.h> 15#include <linux/types.h>
@@ -41,13 +41,13 @@ struct mtd_part {
41 */ 41 */
42#define PART(x) ((struct mtd_part *)(x)) 42#define PART(x) ((struct mtd_part *)(x))
43 43
44 44
45/* 45/*
46 * MTD methods which simply translate the effective address and pass through 46 * MTD methods which simply translate the effective address and pass through
47 * to the _real_ device. 47 * to the _real_ device.
48 */ 48 */
49 49
50static int part_read (struct mtd_info *mtd, loff_t from, size_t len, 50static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
51 size_t *retlen, u_char *buf) 51 size_t *retlen, u_char *buf)
52{ 52{
53 struct mtd_part *part = PART(mtd); 53 struct mtd_part *part = PART(mtd);
@@ -55,15 +55,15 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
55 len = 0; 55 len = 0;
56 else if (from + len > mtd->size) 56 else if (from + len > mtd->size)
57 len = mtd->size - from; 57 len = mtd->size - from;
58 if (part->master->read_ecc == NULL) 58 if (part->master->read_ecc == NULL)
59 return part->master->read (part->master, from + part->offset, 59 return part->master->read (part->master, from + part->offset,
60 len, retlen, buf); 60 len, retlen, buf);
61 else 61 else
62 return part->master->read_ecc (part->master, from + part->offset, 62 return part->master->read_ecc (part->master, from + part->offset,
63 len, retlen, buf, NULL, &mtd->oobinfo); 63 len, retlen, buf, NULL, &mtd->oobinfo);
64} 64}
65 65
66static int part_point (struct mtd_info *mtd, loff_t from, size_t len, 66static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
67 size_t *retlen, u_char **buf) 67 size_t *retlen, u_char **buf)
68{ 68{
69 struct mtd_part *part = PART(mtd); 69 struct mtd_part *part = PART(mtd);
@@ -71,7 +71,7 @@ static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
71 len = 0; 71 len = 0;
72 else if (from + len > mtd->size) 72 else if (from + len > mtd->size)
73 len = mtd->size - from; 73 len = mtd->size - from;
74 return part->master->point (part->master, from + part->offset, 74 return part->master->point (part->master, from + part->offset,
75 len, retlen, buf); 75 len, retlen, buf);
76} 76}
77static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) 77static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
@@ -82,7 +82,7 @@ static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_
82} 82}
83 83
84 84
85static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, 85static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
86 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel) 86 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel)
87{ 87{
88 struct mtd_part *part = PART(mtd); 88 struct mtd_part *part = PART(mtd);
@@ -92,11 +92,11 @@ static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
92 len = 0; 92 len = 0;
93 else if (from + len > mtd->size) 93 else if (from + len > mtd->size)
94 len = mtd->size - from; 94 len = mtd->size - from;
95 return part->master->read_ecc (part->master, from + part->offset, 95 return part->master->read_ecc (part->master, from + part->offset,
96 len, retlen, buf, eccbuf, oobsel); 96 len, retlen, buf, eccbuf, oobsel);
97} 97}
98 98
99static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len, 99static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
100 size_t *retlen, u_char *buf) 100 size_t *retlen, u_char *buf)
101{ 101{
102 struct mtd_part *part = PART(mtd); 102 struct mtd_part *part = PART(mtd);
@@ -104,15 +104,15 @@ static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
104 len = 0; 104 len = 0;
105 else if (from + len > mtd->size) 105 else if (from + len > mtd->size)
106 len = mtd->size - from; 106 len = mtd->size - from;
107 return part->master->read_oob (part->master, from + part->offset, 107 return part->master->read_oob (part->master, from + part->offset,
108 len, retlen, buf); 108 len, retlen, buf);
109} 109}
110 110
111static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 111static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
112 size_t *retlen, u_char *buf) 112 size_t *retlen, u_char *buf)
113{ 113{
114 struct mtd_part *part = PART(mtd); 114 struct mtd_part *part = PART(mtd);
115 return part->master->read_user_prot_reg (part->master, from, 115 return part->master->read_user_prot_reg (part->master, from,
116 len, retlen, buf); 116 len, retlen, buf);
117} 117}
118 118
@@ -123,11 +123,11 @@ static int part_get_user_prot_info (struct mtd_info *mtd,
123 return part->master->get_user_prot_info (part->master, buf, len); 123 return part->master->get_user_prot_info (part->master, buf, len);
124} 124}
125 125
126static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 126static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
127 size_t *retlen, u_char *buf) 127 size_t *retlen, u_char *buf)
128{ 128{
129 struct mtd_part *part = PART(mtd); 129 struct mtd_part *part = PART(mtd);
130 return part->master->read_fact_prot_reg (part->master, from, 130 return part->master->read_fact_prot_reg (part->master, from,
131 len, retlen, buf); 131 len, retlen, buf);
132} 132}
133 133
@@ -148,13 +148,13 @@ static int part_write (struct mtd_info *mtd, loff_t to, size_t len,
148 len = 0; 148 len = 0;
149 else if (to + len > mtd->size) 149 else if (to + len > mtd->size)
150 len = mtd->size - to; 150 len = mtd->size - to;
151 if (part->master->write_ecc == NULL) 151 if (part->master->write_ecc == NULL)
152 return part->master->write (part->master, to + part->offset, 152 return part->master->write (part->master, to + part->offset,
153 len, retlen, buf); 153 len, retlen, buf);
154 else 154 else
155 return part->master->write_ecc (part->master, to + part->offset, 155 return part->master->write_ecc (part->master, to + part->offset,
156 len, retlen, buf, NULL, &mtd->oobinfo); 156 len, retlen, buf, NULL, &mtd->oobinfo);
157 157
158} 158}
159 159
160static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, 160static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
@@ -170,7 +170,7 @@ static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
170 len = 0; 170 len = 0;
171 else if (to + len > mtd->size) 171 else if (to + len > mtd->size)
172 len = mtd->size - to; 172 len = mtd->size - to;
173 return part->master->write_ecc (part->master, to + part->offset, 173 return part->master->write_ecc (part->master, to + part->offset,
174 len, retlen, buf, eccbuf, oobsel); 174 len, retlen, buf, eccbuf, oobsel);
175} 175}
176 176
@@ -184,19 +184,19 @@ static int part_write_oob (struct mtd_info *mtd, loff_t to, size_t len,
184 len = 0; 184 len = 0;
185 else if (to + len > mtd->size) 185 else if (to + len > mtd->size)
186 len = mtd->size - to; 186 len = mtd->size - to;
187 return part->master->write_oob (part->master, to + part->offset, 187 return part->master->write_oob (part->master, to + part->offset,
188 len, retlen, buf); 188 len, retlen, buf);
189} 189}
190 190
191static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 191static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
192 size_t *retlen, u_char *buf) 192 size_t *retlen, u_char *buf)
193{ 193{
194 struct mtd_part *part = PART(mtd); 194 struct mtd_part *part = PART(mtd);
195 return part->master->write_user_prot_reg (part->master, from, 195 return part->master->write_user_prot_reg (part->master, from,
196 len, retlen, buf); 196 len, retlen, buf);
197} 197}
198 198
199static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len) 199static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len)
200{ 200{
201 struct mtd_part *part = PART(mtd); 201 struct mtd_part *part = PART(mtd);
202 return part->master->lock_user_prot_reg (part->master, from, len); 202 return part->master->lock_user_prot_reg (part->master, from, len);
@@ -208,7 +208,7 @@ static int part_writev (struct mtd_info *mtd, const struct kvec *vecs,
208 struct mtd_part *part = PART(mtd); 208 struct mtd_part *part = PART(mtd);
209 if (!(mtd->flags & MTD_WRITEABLE)) 209 if (!(mtd->flags & MTD_WRITEABLE))
210 return -EROFS; 210 return -EROFS;
211 if (part->master->writev_ecc == NULL) 211 if (part->master->writev_ecc == NULL)
212 return part->master->writev (part->master, vecs, count, 212 return part->master->writev (part->master, vecs, count,
213 to + part->offset, retlen); 213 to + part->offset, retlen);
214 else 214 else
@@ -221,12 +221,12 @@ static int part_readv (struct mtd_info *mtd, struct kvec *vecs,
221 unsigned long count, loff_t from, size_t *retlen) 221 unsigned long count, loff_t from, size_t *retlen)
222{ 222{
223 struct mtd_part *part = PART(mtd); 223 struct mtd_part *part = PART(mtd);
224 if (part->master->readv_ecc == NULL) 224 if (part->master->readv_ecc == NULL)
225 return part->master->readv (part->master, vecs, count, 225 return part->master->readv (part->master, vecs, count,
226 from + part->offset, retlen); 226 from + part->offset, retlen);
227 else 227 else
228 return part->master->readv_ecc (part->master, vecs, count, 228 return part->master->readv_ecc (part->master, vecs, count,
229 from + part->offset, retlen, 229 from + part->offset, retlen,
230 NULL, &mtd->oobinfo); 230 NULL, &mtd->oobinfo);
231} 231}
232 232
@@ -252,7 +252,7 @@ static int part_readv_ecc (struct mtd_info *mtd, struct kvec *vecs,
252 if (oobsel == NULL) 252 if (oobsel == NULL)
253 oobsel = &mtd->oobinfo; 253 oobsel = &mtd->oobinfo;
254 return part->master->readv_ecc (part->master, vecs, count, 254 return part->master->readv_ecc (part->master, vecs, count,
255 from + part->offset, retlen, 255 from + part->offset, retlen,
256 eccbuf, oobsel); 256 eccbuf, oobsel);
257} 257}
258 258
@@ -286,7 +286,7 @@ EXPORT_SYMBOL_GPL(mtd_erase_callback);
286static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len) 286static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
287{ 287{
288 struct mtd_part *part = PART(mtd); 288 struct mtd_part *part = PART(mtd);
289 if ((len + ofs) > mtd->size) 289 if ((len + ofs) > mtd->size)
290 return -EINVAL; 290 return -EINVAL;
291 return part->master->lock(part->master, ofs + part->offset, len); 291 return part->master->lock(part->master, ofs + part->offset, len);
292} 292}
@@ -294,7 +294,7 @@ static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
294static int part_unlock (struct mtd_info *mtd, loff_t ofs, size_t len) 294static int part_unlock (struct mtd_info *mtd, loff_t ofs, size_t len)
295{ 295{
296 struct mtd_part *part = PART(mtd); 296 struct mtd_part *part = PART(mtd);
297 if ((len + ofs) > mtd->size) 297 if ((len + ofs) > mtd->size)
298 return -EINVAL; 298 return -EINVAL;
299 return part->master->unlock(part->master, ofs + part->offset, len); 299 return part->master->unlock(part->master, ofs + part->offset, len);
300} 300}
@@ -337,8 +337,8 @@ static int part_block_markbad (struct mtd_info *mtd, loff_t ofs)
337 return part->master->block_markbad(part->master, ofs); 337 return part->master->block_markbad(part->master, ofs);
338} 338}
339 339
340/* 340/*
341 * This function unregisters and destroy all slave MTD objects which are 341 * This function unregisters and destroy all slave MTD objects which are
342 * attached to the given master MTD object. 342 * attached to the given master MTD object.
343 */ 343 */
344 344
@@ -371,7 +371,7 @@ int del_mtd_partitions(struct mtd_info *master)
371 * (Q: should we register the master MTD object as well?) 371 * (Q: should we register the master MTD object as well?)
372 */ 372 */
373 373
374int add_mtd_partitions(struct mtd_info *master, 374int add_mtd_partitions(struct mtd_info *master,
375 const struct mtd_partition *parts, 375 const struct mtd_partition *parts,
376 int nbparts) 376 int nbparts)
377{ 377{
@@ -414,7 +414,7 @@ int add_mtd_partitions(struct mtd_info *master,
414 slave->mtd.point = part_point; 414 slave->mtd.point = part_point;
415 slave->mtd.unpoint = part_unpoint; 415 slave->mtd.unpoint = part_unpoint;
416 } 416 }
417 417
418 if (master->read_ecc) 418 if (master->read_ecc)
419 slave->mtd.read_ecc = part_read_ecc; 419 slave->mtd.read_ecc = part_read_ecc;
420 if (master->write_ecc) 420 if (master->write_ecc)
@@ -465,9 +465,10 @@ int add_mtd_partitions(struct mtd_info *master,
465 if (slave->offset == MTDPART_OFS_APPEND) 465 if (slave->offset == MTDPART_OFS_APPEND)
466 slave->offset = cur_offset; 466 slave->offset = cur_offset;
467 if (slave->offset == MTDPART_OFS_NXTBLK) { 467 if (slave->offset == MTDPART_OFS_NXTBLK) {
468 u_int32_t emask = master->erasesize-1; 468 slave->offset = cur_offset;
469 slave->offset = (cur_offset + emask) & ~emask; 469 if ((cur_offset % master->erasesize) != 0) {
470 if (slave->offset != cur_offset) { 470 /* Round up to next erasesize */
471 slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize;
471 printk(KERN_NOTICE "Moving partition %d: " 472 printk(KERN_NOTICE "Moving partition %d: "
472 "0x%08x -> 0x%08x\n", i, 473 "0x%08x -> 0x%08x\n", i,
473 cur_offset, slave->offset); 474 cur_offset, slave->offset);
@@ -476,8 +477,8 @@ int add_mtd_partitions(struct mtd_info *master,
476 if (slave->mtd.size == MTDPART_SIZ_FULL) 477 if (slave->mtd.size == MTDPART_SIZ_FULL)
477 slave->mtd.size = master->size - slave->offset; 478 slave->mtd.size = master->size - slave->offset;
478 cur_offset = slave->offset + slave->mtd.size; 479 cur_offset = slave->offset + slave->mtd.size;
479 480
480 printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, 481 printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset,
481 slave->offset + slave->mtd.size, slave->mtd.name); 482 slave->offset + slave->mtd.size, slave->mtd.name);
482 483
483 /* let's do some sanity checks */ 484 /* let's do some sanity checks */
@@ -497,7 +498,7 @@ int add_mtd_partitions(struct mtd_info *master,
497 /* Deal with variable erase size stuff */ 498 /* Deal with variable erase size stuff */
498 int i; 499 int i;
499 struct mtd_erase_region_info *regions = master->eraseregions; 500 struct mtd_erase_region_info *regions = master->eraseregions;
500 501
501 /* Find the first erase regions which is part of this partition. */ 502 /* Find the first erase regions which is part of this partition. */
502 for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++) 503 for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++)
503 ; 504 ;
@@ -512,7 +513,7 @@ int add_mtd_partitions(struct mtd_info *master,
512 slave->mtd.erasesize = master->erasesize; 513 slave->mtd.erasesize = master->erasesize;
513 } 514 }
514 515
515 if ((slave->mtd.flags & MTD_WRITEABLE) && 516 if ((slave->mtd.flags & MTD_WRITEABLE) &&
516 (slave->offset % slave->mtd.erasesize)) { 517 (slave->offset % slave->mtd.erasesize)) {
517 /* Doesn't start on a boundary of major erase size */ 518 /* Doesn't start on a boundary of major erase size */
518 /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */ 519 /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */
@@ -520,14 +521,14 @@ int add_mtd_partitions(struct mtd_info *master,
520 printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", 521 printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",
521 parts[i].name); 522 parts[i].name);
522 } 523 }
523 if ((slave->mtd.flags & MTD_WRITEABLE) && 524 if ((slave->mtd.flags & MTD_WRITEABLE) &&
524 (slave->mtd.size % slave->mtd.erasesize)) { 525 (slave->mtd.size % slave->mtd.erasesize)) {
525 slave->mtd.flags &= ~MTD_WRITEABLE; 526 slave->mtd.flags &= ~MTD_WRITEABLE;
526 printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", 527 printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",
527 parts[i].name); 528 parts[i].name);
528 } 529 }
529 530
530 /* copy oobinfo from master */ 531 /* copy oobinfo from master */
531 memcpy(&slave->mtd.oobinfo, &master->oobinfo, sizeof(slave->mtd.oobinfo)); 532 memcpy(&slave->mtd.oobinfo, &master->oobinfo, sizeof(slave->mtd.oobinfo));
532 533
533 if(parts[i].mtdp) 534 if(parts[i].mtdp)
@@ -588,12 +589,12 @@ int deregister_mtd_parser(struct mtd_part_parser *p)
588 return 0; 589 return 0;
589} 590}
590 591
591int parse_mtd_partitions(struct mtd_info *master, const char **types, 592int parse_mtd_partitions(struct mtd_info *master, const char **types,
592 struct mtd_partition **pparts, unsigned long origin) 593 struct mtd_partition **pparts, unsigned long origin)
593{ 594{
594 struct mtd_part_parser *parser; 595 struct mtd_part_parser *parser;
595 int ret = 0; 596 int ret = 0;
596 597
597 for ( ; ret <= 0 && *types; types++) { 598 for ( ; ret <= 0 && *types; types++) {
598 parser = get_partition_parser(*types); 599 parser = get_partition_parser(*types);
599#ifdef CONFIG_KMOD 600#ifdef CONFIG_KMOD
@@ -607,7 +608,7 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
607 } 608 }
608 ret = (*parser->parse_fn)(master, pparts, origin); 609 ret = (*parser->parse_fn)(master, pparts, origin);
609 if (ret > 0) { 610 if (ret > 0) {
610 printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", 611 printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
611 ret, parser->name, master->name); 612 ret, parser->name, master->name);
612 } 613 }
613 put_partition_parser(parser); 614 put_partition_parser(parser);
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 36d34e5e5a5a..1fc4c134d939 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -1,5 +1,5 @@
1# drivers/mtd/nand/Kconfig 1# drivers/mtd/nand/Kconfig
2# $Id: Kconfig,v 1.31 2005/06/20 12:03:21 bjd Exp $ 2# $Id: Kconfig,v 1.35 2005/11/07 11:14:30 gleixner Exp $
3 3
4menu "NAND Flash Device Drivers" 4menu "NAND Flash Device Drivers"
5 depends on MTD!=n 5 depends on MTD!=n
@@ -25,33 +25,33 @@ config MTD_NAND_VERIFY_WRITE
25 25
26config MTD_NAND_AUTCPU12 26config MTD_NAND_AUTCPU12
27 tristate "SmartMediaCard on autronix autcpu12 board" 27 tristate "SmartMediaCard on autronix autcpu12 board"
28 depends on ARM && MTD_NAND && ARCH_AUTCPU12 28 depends on MTD_NAND && ARCH_AUTCPU12
29 help 29 help
30 This enables the driver for the autronix autcpu12 board to 30 This enables the driver for the autronix autcpu12 board to
31 access the SmartMediaCard. 31 access the SmartMediaCard.
32 32
33config MTD_NAND_EDB7312 33config MTD_NAND_EDB7312
34 tristate "Support for Cirrus Logic EBD7312 evaluation board" 34 tristate "Support for Cirrus Logic EBD7312 evaluation board"
35 depends on ARM && MTD_NAND && ARCH_EDB7312 35 depends on MTD_NAND && ARCH_EDB7312
36 help 36 help
37 This enables the driver for the Cirrus Logic EBD7312 evaluation 37 This enables the driver for the Cirrus Logic EBD7312 evaluation
38 board to access the onboard NAND Flash. 38 board to access the onboard NAND Flash.
39 39
40config MTD_NAND_H1900 40config MTD_NAND_H1900
41 tristate "iPAQ H1900 flash" 41 tristate "iPAQ H1900 flash"
42 depends on ARM && MTD_NAND && ARCH_PXA && MTD_PARTITIONS 42 depends on MTD_NAND && ARCH_PXA && MTD_PARTITIONS
43 help 43 help
44 This enables the driver for the iPAQ h1900 flash. 44 This enables the driver for the iPAQ h1900 flash.
45 45
46config MTD_NAND_SPIA 46config MTD_NAND_SPIA
47 tristate "NAND Flash device on SPIA board" 47 tristate "NAND Flash device on SPIA board"
48 depends on ARM && ARCH_P720T && MTD_NAND 48 depends on ARCH_P720T && MTD_NAND
49 help 49 help
50 If you had to ask, you don't have one. Say 'N'. 50 If you had to ask, you don't have one. Say 'N'.
51 51
52config MTD_NAND_TOTO 52config MTD_NAND_TOTO
53 tristate "NAND Flash device on TOTO board" 53 tristate "NAND Flash device on TOTO board"
54 depends on ARM && ARCH_OMAP && MTD_NAND 54 depends on ARCH_OMAP && MTD_NAND
55 help 55 help
56 Support for NAND flash on Texas Instruments Toto platform. 56 Support for NAND flash on Texas Instruments Toto platform.
57 57
@@ -59,8 +59,8 @@ config MTD_NAND_IDS
59 tristate 59 tristate
60 60
61config MTD_NAND_AU1550 61config MTD_NAND_AU1550
62 tristate "Au1550 NAND support" 62 tristate "Au1550/1200 NAND support"
63 depends on SOC_AU1550 && MTD_NAND 63 depends on (SOC_AU1200 || SOC_AU1550) && MTD_NAND
64 help 64 help
65 This enables the driver for the NAND flash controller on the 65 This enables the driver for the NAND flash controller on the
66 AMD/Alchemy 1550 SOC. 66 AMD/Alchemy 1550 SOC.
@@ -71,7 +71,7 @@ config MTD_NAND_RTC_FROM4
71 select REED_SOLOMON 71 select REED_SOLOMON
72 select REED_SOLOMON_DEC8 72 select REED_SOLOMON_DEC8
73 help 73 help
74 This enables the driver for the Renesas Technology AG-AND 74 This enables the driver for the Renesas Technology AG-AND
75 flash interface board (FROM_BOARD4) 75 flash interface board (FROM_BOARD4)
76 76
77config MTD_NAND_PPCHAMELEONEVB 77config MTD_NAND_PPCHAMELEONEVB
@@ -88,7 +88,7 @@ config MTD_NAND_S3C2410
88 SoCs 88 SoCs
89 89
90 No board specfic support is done by this driver, each board 90 No board specfic support is done by this driver, each board
91 must advertise a platform_device for the driver to attach. 91 must advertise a platform_device for the driver to attach.
92 92
93config MTD_NAND_S3C2410_DEBUG 93config MTD_NAND_S3C2410_DEBUG
94 bool "S3C2410 NAND driver debug" 94 bool "S3C2410 NAND driver debug"
@@ -181,7 +181,7 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
181 181
182 config MTD_NAND_SHARPSL 182 config MTD_NAND_SHARPSL
183 bool "Support for NAND Flash on Sharp SL Series (C7xx + others)" 183 bool "Support for NAND Flash on Sharp SL Series (C7xx + others)"
184 depends on MTD_NAND && ARCH_PXA 184 depends on MTD_NAND && ARCH_PXA
185 185
186 config MTD_NAND_NANDSIM 186 config MTD_NAND_NANDSIM
187 bool "Support for NAND Flash Simulator" 187 bool "Support for NAND Flash Simulator"
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 4c7719ce3f48..3cafcdf28aed 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2004 Embedded Edge, LLC 4 * Copyright (C) 2004 Embedded Edge, LLC
5 * 5 *
6 * $Id: au1550nd.c,v 1.11 2004/11/04 12:53:10 gleixner Exp $ 6 * $Id: au1550nd.c,v 1.13 2005/11/07 11:14:30 gleixner Exp $
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -21,20 +21,14 @@
21 21
22/* fixme: this is ugly */ 22/* fixme: this is ugly */
23#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0) 23#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0)
24#include <asm/mach-au1x00/au1000.h> 24#include <asm/mach-au1x00/au1xxx.h>
25#ifdef CONFIG_MIPS_PB1550
26#include <asm/mach-pb1x00/pb1550.h>
27#endif
28#ifdef CONFIG_MIPS_DB1550
29#include <asm/mach-db1x00/db1x00.h>
30#endif
31#else 25#else
32#include <asm/au1000.h> 26#include <asm/au1000.h>
33#ifdef CONFIG_MIPS_PB1550 27#ifdef CONFIG_MIPS_PB1550
34#include <asm/pb1550.h> 28#include <asm/pb1550.h>
35#endif 29#endif
36#ifdef CONFIG_MIPS_DB1550 30#ifdef CONFIG_MIPS_DB1550
37#include <asm/db1x00.h> 31#include <asm/db1x00.h>
38#endif 32#endif
39#endif 33#endif
40 34
@@ -45,39 +39,22 @@ static struct mtd_info *au1550_mtd = NULL;
45static void __iomem *p_nand; 39static void __iomem *p_nand;
46static int nand_width = 1; /* default x8*/ 40static int nand_width = 1; /* default x8*/
47 41
48#define NAND_CS 1
49
50/* 42/*
51 * Define partitions for flash device 43 * Define partitions for flash device
52 */ 44 */
53const static struct mtd_partition partition_info[] = { 45const static struct mtd_partition partition_info[] = {
54#ifdef CONFIG_MIPS_PB1550 46 {
55#define NUM_PARTITIONS 2 47 .name = "NAND FS 0",
56 {
57 .name = "Pb1550 NAND FS 0",
58 .offset = 0, 48 .offset = 0,
59 .size = 8*1024*1024 49 .size = 8*1024*1024
60 }, 50 },
61 { 51 {
62 .name = "Pb1550 NAND FS 1", 52 .name = "NAND FS 1",
63 .offset = MTDPART_OFS_APPEND, 53 .offset = MTDPART_OFS_APPEND,
64 .size = MTDPART_SIZ_FULL 54 .size = MTDPART_SIZ_FULL
65 } 55 }
66#endif
67#ifdef CONFIG_MIPS_DB1550
68#define NUM_PARTITIONS 2
69 {
70 .name = "Db1550 NAND FS 0",
71 .offset = 0,
72 .size = 8*1024*1024
73 },
74 {
75 .name = "Db1550 NAND FS 1",
76 .offset = MTDPART_OFS_APPEND,
77 .size = MTDPART_SIZ_FULL
78 }
79#endif
80}; 56};
57#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
81 58
82 59
83/** 60/**
@@ -112,7 +89,7 @@ static void au_write_byte(struct mtd_info *mtd, u_char byte)
112 * au_read_byte16 - read one byte endianess aware from the chip 89 * au_read_byte16 - read one byte endianess aware from the chip
113 * @mtd: MTD device structure 90 * @mtd: MTD device structure
114 * 91 *
115 * read function for 16bit buswith with 92 * read function for 16bit buswith with
116 * endianess conversion 93 * endianess conversion
117 */ 94 */
118static u_char au_read_byte16(struct mtd_info *mtd) 95static u_char au_read_byte16(struct mtd_info *mtd)
@@ -142,7 +119,7 @@ static void au_write_byte16(struct mtd_info *mtd, u_char byte)
142 * au_read_word - read one word from the chip 119 * au_read_word - read one word from the chip
143 * @mtd: MTD device structure 120 * @mtd: MTD device structure
144 * 121 *
145 * read function for 16bit buswith without 122 * read function for 16bit buswith without
146 * endianess conversion 123 * endianess conversion
147 */ 124 */
148static u16 au_read_word(struct mtd_info *mtd) 125static u16 au_read_word(struct mtd_info *mtd)
@@ -158,7 +135,7 @@ static u16 au_read_word(struct mtd_info *mtd)
158 * @mtd: MTD device structure 135 * @mtd: MTD device structure
159 * @word: data word to write 136 * @word: data word to write
160 * 137 *
161 * write function for 16bit buswith without 138 * write function for 16bit buswith without
162 * endianess conversion 139 * endianess conversion
163 */ 140 */
164static void au_write_word(struct mtd_info *mtd, u16 word) 141static void au_write_word(struct mtd_info *mtd, u16 word)
@@ -188,7 +165,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
188} 165}
189 166
190/** 167/**
191 * au_read_buf - read chip data into buffer 168 * au_read_buf - read chip data into buffer
192 * @mtd: MTD device structure 169 * @mtd: MTD device structure
193 * @buf: buffer to store date 170 * @buf: buffer to store date
194 * @len: number of bytes to read 171 * @len: number of bytes to read
@@ -202,12 +179,12 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len)
202 179
203 for (i=0; i<len; i++) { 180 for (i=0; i<len; i++) {
204 buf[i] = readb(this->IO_ADDR_R); 181 buf[i] = readb(this->IO_ADDR_R);
205 au_sync(); 182 au_sync();
206 } 183 }
207} 184}
208 185
209/** 186/**
210 * au_verify_buf - Verify chip data against buffer 187 * au_verify_buf - Verify chip data against buffer
211 * @mtd: MTD device structure 188 * @mtd: MTD device structure
212 * @buf: buffer containing the data to compare 189 * @buf: buffer containing the data to compare
213 * @len: number of bytes to compare 190 * @len: number of bytes to compare
@@ -242,16 +219,16 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
242 struct nand_chip *this = mtd->priv; 219 struct nand_chip *this = mtd->priv;
243 u16 *p = (u16 *) buf; 220 u16 *p = (u16 *) buf;
244 len >>= 1; 221 len >>= 1;
245 222
246 for (i=0; i<len; i++) { 223 for (i=0; i<len; i++) {
247 writew(p[i], this->IO_ADDR_W); 224 writew(p[i], this->IO_ADDR_W);
248 au_sync(); 225 au_sync();
249 } 226 }
250 227
251} 228}
252 229
253/** 230/**
254 * au_read_buf16 - read chip data into buffer 231 * au_read_buf16 - read chip data into buffer
255 * @mtd: MTD device structure 232 * @mtd: MTD device structure
256 * @buf: buffer to store date 233 * @buf: buffer to store date
257 * @len: number of bytes to read 234 * @len: number of bytes to read
@@ -272,7 +249,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
272} 249}
273 250
274/** 251/**
275 * au_verify_buf16 - Verify chip data against buffer 252 * au_verify_buf16 - Verify chip data against buffer
276 * @mtd: MTD device structure 253 * @mtd: MTD device structure
277 * @buf: buffer containing the data to compare 254 * @buf: buffer containing the data to compare
278 * @len: number of bytes to compare 255 * @len: number of bytes to compare
@@ -305,26 +282,26 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)
305 case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break; 282 case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break;
306 283
307 case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break; 284 case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break;
308 case NAND_CTL_CLRALE: 285 case NAND_CTL_CLRALE:
309 this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; 286 this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
310 /* FIXME: Nobody knows why this is neccecary, 287 /* FIXME: Nobody knows why this is neccecary,
311 * but it works only that way */ 288 * but it works only that way */
312 udelay(1); 289 udelay(1);
313 break; 290 break;
314 291
315 case NAND_CTL_SETNCE: 292 case NAND_CTL_SETNCE:
316 /* assert (force assert) chip enable */ 293 /* assert (force assert) chip enable */
317 au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break; 294 au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break;
318 break; 295 break;
319 296
320 case NAND_CTL_CLRNCE: 297 case NAND_CTL_CLRNCE:
321 /* deassert chip enable */ 298 /* deassert chip enable */
322 au_writel(0, MEM_STNDCTL); break; 299 au_writel(0, MEM_STNDCTL); break;
323 break; 300 break;
324 } 301 }
325 302
326 this->IO_ADDR_R = this->IO_ADDR_W; 303 this->IO_ADDR_R = this->IO_ADDR_W;
327 304
328 /* Drain the writebuffer */ 305 /* Drain the writebuffer */
329 au_sync(); 306 au_sync();
330} 307}
@@ -339,14 +316,16 @@ int au1550_device_ready(struct mtd_info *mtd)
339/* 316/*
340 * Main initialization routine 317 * Main initialization routine
341 */ 318 */
342int __init au1550_init (void) 319int __init au1xxx_nand_init (void)
343{ 320{
344 struct nand_chip *this; 321 struct nand_chip *this;
345 u16 boot_swapboot = 0; /* default value */ 322 u16 boot_swapboot = 0; /* default value */
346 int retval; 323 int retval;
324 u32 mem_staddr;
325 u32 nand_phys;
347 326
348 /* Allocate memory for MTD device structure and private data */ 327 /* Allocate memory for MTD device structure and private data */
349 au1550_mtd = kmalloc (sizeof(struct mtd_info) + 328 au1550_mtd = kmalloc (sizeof(struct mtd_info) +
350 sizeof (struct nand_chip), GFP_KERNEL); 329 sizeof (struct nand_chip), GFP_KERNEL);
351 if (!au1550_mtd) { 330 if (!au1550_mtd) {
352 printk ("Unable to allocate NAND MTD dev structure.\n"); 331 printk ("Unable to allocate NAND MTD dev structure.\n");
@@ -364,14 +343,17 @@ int __init au1550_init (void)
364 au1550_mtd->priv = this; 343 au1550_mtd->priv = this;
365 344
366 345
367 /* MEM_STNDCTL: disable ints, disable nand boot */ 346 /* disable interrupts */
368 au_writel(0, MEM_STNDCTL); 347 au_writel(au_readl(MEM_STNDCTL) & ~(1<<8), MEM_STNDCTL);
348
349 /* disable NAND boot */
350 au_writel(au_readl(MEM_STNDCTL) & ~(1<<0), MEM_STNDCTL);
369 351
370#ifdef CONFIG_MIPS_PB1550 352#ifdef CONFIG_MIPS_PB1550
371 /* set gpio206 high */ 353 /* set gpio206 high */
372 au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR); 354 au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR);
373 355
374 boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) | 356 boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) |
375 ((bcsr->status >> 6) & 0x1); 357 ((bcsr->status >> 6) & 0x1);
376 switch (boot_swapboot) { 358 switch (boot_swapboot) {
377 case 0: 359 case 0:
@@ -397,25 +379,66 @@ int __init au1550_init (void)
397 } 379 }
398#endif 380#endif
399 381
400 /* Configure RCE1 - should be done by YAMON */ 382 /* Configure chip-select; normally done by boot code, e.g. YAMON */
401 au_writel(0x5 | (nand_width << 22), 0xB4001010); /* MEM_STCFG1 */ 383#ifdef NAND_STCFG
402 au_writel(NAND_TIMING, 0xB4001014); /* MEM_STTIME1 */ 384 if (NAND_CS == 0) {
403 au_sync(); 385 au_writel(NAND_STCFG, MEM_STCFG0);
386 au_writel(NAND_STTIME, MEM_STTIME0);
387 au_writel(NAND_STADDR, MEM_STADDR0);
388 }
389 if (NAND_CS == 1) {
390 au_writel(NAND_STCFG, MEM_STCFG1);
391 au_writel(NAND_STTIME, MEM_STTIME1);
392 au_writel(NAND_STADDR, MEM_STADDR1);
393 }
394 if (NAND_CS == 2) {
395 au_writel(NAND_STCFG, MEM_STCFG2);
396 au_writel(NAND_STTIME, MEM_STTIME2);
397 au_writel(NAND_STADDR, MEM_STADDR2);
398 }
399 if (NAND_CS == 3) {
400 au_writel(NAND_STCFG, MEM_STCFG3);
401 au_writel(NAND_STTIME, MEM_STTIME3);
402 au_writel(NAND_STADDR, MEM_STADDR3);
403 }
404#endif
404 405
405 /* setup and enable chip select, MEM_STADDR1 */ 406 /* Locate NAND chip-select in order to determine NAND phys address */
406 /* we really need to decode offsets only up till 0x20 */ 407 mem_staddr = 0x00000000;
407 au_writel((1<<28) | (NAND_PHYS_ADDR>>4) | 408 if (((au_readl(MEM_STCFG0) & 0x7) == 0x5) && (NAND_CS == 0))
408 (((NAND_PHYS_ADDR + 0x1000)-1) & (0x3fff<<18)>>18), 409 mem_staddr = au_readl(MEM_STADDR0);
409 MEM_STADDR1); 410 else if (((au_readl(MEM_STCFG1) & 0x7) == 0x5) && (NAND_CS == 1))
410 au_sync(); 411 mem_staddr = au_readl(MEM_STADDR1);
412 else if (((au_readl(MEM_STCFG2) & 0x7) == 0x5) && (NAND_CS == 2))
413 mem_staddr = au_readl(MEM_STADDR2);
414 else if (((au_readl(MEM_STCFG3) & 0x7) == 0x5) && (NAND_CS == 3))
415 mem_staddr = au_readl(MEM_STADDR3);
416
417 if (mem_staddr == 0x00000000) {
418 printk("Au1xxx NAND: ERROR WITH NAND CHIP-SELECT\n");
419 kfree(au1550_mtd);
420 return 1;
421 }
422 nand_phys = (mem_staddr << 4) & 0xFFFC0000;
423
424 p_nand = (void __iomem *)ioremap(nand_phys, 0x1000);
425
426 /* make controller and MTD agree */
427 if (NAND_CS == 0)
428 nand_width = au_readl(MEM_STCFG0) & (1<<22);
429 if (NAND_CS == 1)
430 nand_width = au_readl(MEM_STCFG1) & (1<<22);
431 if (NAND_CS == 2)
432 nand_width = au_readl(MEM_STCFG2) & (1<<22);
433 if (NAND_CS == 3)
434 nand_width = au_readl(MEM_STCFG3) & (1<<22);
411 435
412 p_nand = ioremap(NAND_PHYS_ADDR, 0x1000);
413 436
414 /* Set address of hardware control function */ 437 /* Set address of hardware control function */
415 this->hwcontrol = au1550_hwcontrol; 438 this->hwcontrol = au1550_hwcontrol;
416 this->dev_ready = au1550_device_ready; 439 this->dev_ready = au1550_device_ready;
417 /* 30 us command delay time */ 440 /* 30 us command delay time */
418 this->chip_delay = 30; 441 this->chip_delay = 30;
419 this->eccmode = NAND_ECC_SOFT; 442 this->eccmode = NAND_ECC_SOFT;
420 443
421 this->options = NAND_NO_AUTOINCR; 444 this->options = NAND_NO_AUTOINCR;
@@ -438,19 +461,19 @@ int __init au1550_init (void)
438 } 461 }
439 462
440 /* Register the partitions */ 463 /* Register the partitions */
441 add_mtd_partitions(au1550_mtd, partition_info, NUM_PARTITIONS); 464 add_mtd_partitions(au1550_mtd, partition_info, NB_OF(partition_info));
442 465
443 return 0; 466 return 0;
444 467
445 outio: 468 outio:
446 iounmap ((void *)p_nand); 469 iounmap ((void *)p_nand);
447 470
448 outmem: 471 outmem:
449 kfree (au1550_mtd); 472 kfree (au1550_mtd);
450 return retval; 473 return retval;
451} 474}
452 475
453module_init(au1550_init); 476module_init(au1xxx_nand_init);
454 477
455/* 478/*
456 * Clean up routine 479 * Clean up routine
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c
index 4afa8ced05ad..056dfc17a075 100644
--- a/drivers/mtd/nand/autcpu12.c
+++ b/drivers/mtd/nand/autcpu12.c
@@ -5,8 +5,8 @@
5 * 5 *
6 * Derived from drivers/mtd/spia.c 6 * Derived from drivers/mtd/spia.c
7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
8 * 8 *
9 * $Id: autcpu12.c,v 1.22 2004/11/04 12:53:10 gleixner Exp $ 9 * $Id: autcpu12.c,v 1.23 2005/11/07 11:14:30 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -14,7 +14,7 @@
14 * 14 *
15 * Overview: 15 * Overview:
16 * This is a device driver for the NAND flash device found on the 16 * This is a device driver for the NAND flash device found on the
17 * autronix autcpu12 board, which is a SmartMediaCard. It supports 17 * autronix autcpu12 board, which is a SmartMediaCard. It supports
18 * 16MiB, 32MiB and 64MiB cards. 18 * 16MiB, 32MiB and 64MiB cards.
19 * 19 *
20 * 20 *
@@ -93,7 +93,7 @@ static struct mtd_partition partition_info128k[] = {
93#define NUM_PARTITIONS32K 2 93#define NUM_PARTITIONS32K 2
94#define NUM_PARTITIONS64K 2 94#define NUM_PARTITIONS64K 2
95#define NUM_PARTITIONS128K 2 95#define NUM_PARTITIONS128K 2
96/* 96/*
97 * hardware specific access to control-lines 97 * hardware specific access to control-lines
98*/ 98*/
99static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd) 99static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd)
@@ -163,7 +163,7 @@ int __init autcpu12_init (void)
163 this->hwcontrol = autcpu12_hwcontrol; 163 this->hwcontrol = autcpu12_hwcontrol;
164 this->dev_ready = autcpu12_device_ready; 164 this->dev_ready = autcpu12_device_ready;
165 /* 20 us command delay time */ 165 /* 20 us command delay time */
166 this->chip_delay = 20; 166 this->chip_delay = 20;
167 this->eccmode = NAND_ECC_SOFT; 167 this->eccmode = NAND_ECC_SOFT;
168 168
169 /* Enable the following for a flash based bad block table */ 169 /* Enable the following for a flash based bad block table */
@@ -171,21 +171,21 @@ int __init autcpu12_init (void)
171 this->options = NAND_USE_FLASH_BBT; 171 this->options = NAND_USE_FLASH_BBT;
172 */ 172 */
173 this->options = NAND_USE_FLASH_BBT; 173 this->options = NAND_USE_FLASH_BBT;
174 174
175 /* Scan to find existance of the device */ 175 /* Scan to find existance of the device */
176 if (nand_scan (autcpu12_mtd, 1)) { 176 if (nand_scan (autcpu12_mtd, 1)) {
177 err = -ENXIO; 177 err = -ENXIO;
178 goto out_ior; 178 goto out_ior;
179 } 179 }
180 180
181 /* Register the partitions */ 181 /* Register the partitions */
182 switch(autcpu12_mtd->size){ 182 switch(autcpu12_mtd->size){
183 case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break; 183 case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break;
184 case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break; 184 case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break;
185 case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break; 185 case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break;
186 case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break; 186 case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break;
187 default: { 187 default: {
188 printk ("Unsupported SmartMedia device\n"); 188 printk ("Unsupported SmartMedia device\n");
189 err = -ENXIO; 189 err = -ENXIO;
190 goto out_ior; 190 goto out_ior;
191 } 191 }
@@ -213,7 +213,7 @@ static void __exit autcpu12_cleanup (void)
213 213
214 /* unmap physical adress */ 214 /* unmap physical adress */
215 iounmap((void *)autcpu12_fio_base); 215 iounmap((void *)autcpu12_fio_base);
216 216
217 /* Free the MTD device structure */ 217 /* Free the MTD device structure */
218 kfree (autcpu12_mtd); 218 kfree (autcpu12_mtd);
219} 219}
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index fdb5d4ad3d52..21d4e8f4b7af 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * drivers/mtd/nand/diskonchip.c 2 * drivers/mtd/nand/diskonchip.c
3 * 3 *
4 * (C) 2003 Red Hat, Inc. 4 * (C) 2003 Red Hat, Inc.
@@ -8,15 +8,15 @@
8 * Author: David Woodhouse <dwmw2@infradead.org> 8 * Author: David Woodhouse <dwmw2@infradead.org>
9 * Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org> 9 * Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org>
10 * Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee> 10 * Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee>
11 * 11 *
12 * Error correction code lifted from the old docecc code 12 * Error correction code lifted from the old docecc code
13 * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 13 * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
14 * Copyright (C) 2000 Netgem S.A. 14 * Copyright (C) 2000 Netgem S.A.
15 * converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de> 15 * converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de>
16 * 16 *
17 * Interface to generic NAND code for M-Systems DiskOnChip devices 17 * Interface to generic NAND code for M-Systems DiskOnChip devices
18 * 18 *
19 * $Id: diskonchip.c,v 1.54 2005/04/07 14:22:55 dbrown Exp $ 19 * $Id: diskonchip.c,v 1.55 2005/11/07 11:14:30 gleixner Exp $
20 */ 20 */
21 21
22#include <linux/kernel.h> 22#include <linux/kernel.h>
@@ -42,16 +42,16 @@
42static unsigned long __initdata doc_locations[] = { 42static unsigned long __initdata doc_locations[] = {
43#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__) 43#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
44#ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH 44#ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH
45 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, 45 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
46 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000, 46 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
47 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, 47 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
48 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000, 48 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
49 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000, 49 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
50#else /* CONFIG_MTD_DOCPROBE_HIGH */ 50#else /* CONFIG_MTD_DOCPROBE_HIGH */
51 0xc8000, 0xca000, 0xcc000, 0xce000, 51 0xc8000, 0xca000, 0xcc000, 0xce000,
52 0xd0000, 0xd2000, 0xd4000, 0xd6000, 52 0xd0000, 0xd2000, 0xd4000, 0xd6000,
53 0xd8000, 0xda000, 0xdc000, 0xde000, 53 0xd8000, 0xda000, 0xdc000, 0xde000,
54 0xe0000, 0xe2000, 0xe4000, 0xe6000, 54 0xe0000, 0xe2000, 0xe4000, 0xe6000,
55 0xe8000, 0xea000, 0xec000, 0xee000, 55 0xe8000, 0xea000, 0xec000, 0xee000,
56#endif /* CONFIG_MTD_DOCPROBE_HIGH */ 56#endif /* CONFIG_MTD_DOCPROBE_HIGH */
57#elif defined(__PPC__) 57#elif defined(__PPC__)
@@ -138,7 +138,7 @@ MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe
138/* the Reed Solomon control structure */ 138/* the Reed Solomon control structure */
139static struct rs_control *rs_decoder; 139static struct rs_control *rs_decoder;
140 140
141/* 141/*
142 * The HW decoder in the DoC ASIC's provides us a error syndrome, 142 * The HW decoder in the DoC ASIC's provides us a error syndrome,
143 * which we must convert to a standard syndrom usable by the generic 143 * which we must convert to a standard syndrom usable by the generic
144 * Reed-Solomon library code. 144 * Reed-Solomon library code.
@@ -163,8 +163,8 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
163 /* Initialize the syndrom buffer */ 163 /* Initialize the syndrom buffer */
164 for (i = 0; i < NROOTS; i++) 164 for (i = 0; i < NROOTS; i++)
165 s[i] = ds[0]; 165 s[i] = ds[0];
166 /* 166 /*
167 * Evaluate 167 * Evaluate
168 * s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0] 168 * s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0]
169 * where x = alpha^(FCR + i) 169 * where x = alpha^(FCR + i)
170 */ 170 */
@@ -188,7 +188,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
188 if (nerr < 0) 188 if (nerr < 0)
189 return nerr; 189 return nerr;
190 190
191 /* 191 /*
192 * Correct the errors. The bitpositions are a bit of magic, 192 * Correct the errors. The bitpositions are a bit of magic,
193 * but they are given by the design of the de/encoder circuit 193 * but they are given by the design of the de/encoder circuit
194 * in the DoC ASIC's. 194 * in the DoC ASIC's.
@@ -205,7 +205,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
205 can be modified since pos is even */ 205 can be modified since pos is even */
206 index = (pos >> 3) ^ 1; 206 index = (pos >> 3) ^ 1;
207 bitpos = pos & 7; 207 bitpos = pos & 7;
208 if ((index >= 0 && index < SECTOR_SIZE) || 208 if ((index >= 0 && index < SECTOR_SIZE) ||
209 index == (SECTOR_SIZE + 1)) { 209 index == (SECTOR_SIZE + 1)) {
210 val = (uint8_t) (errval[i] >> (2 + bitpos)); 210 val = (uint8_t) (errval[i] >> (2 + bitpos));
211 parity ^= val; 211 parity ^= val;
@@ -216,7 +216,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
216 bitpos = (bitpos + 10) & 7; 216 bitpos = (bitpos + 10) & 7;
217 if (bitpos == 0) 217 if (bitpos == 0)
218 bitpos = 8; 218 bitpos = 8;
219 if ((index >= 0 && index < SECTOR_SIZE) || 219 if ((index >= 0 && index < SECTOR_SIZE) ||
220 index == (SECTOR_SIZE + 1)) { 220 index == (SECTOR_SIZE + 1)) {
221 val = (uint8_t)(errval[i] << (8 - bitpos)); 221 val = (uint8_t)(errval[i] << (8 - bitpos));
222 parity ^= val; 222 parity ^= val;
@@ -233,7 +233,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
233{ 233{
234 volatile char dummy; 234 volatile char dummy;
235 int i; 235 int i;
236 236
237 for (i = 0; i < cycles; i++) { 237 for (i = 0; i < cycles; i++) {
238 if (DoC_is_Millennium(doc)) 238 if (DoC_is_Millennium(doc))
239 dummy = ReadDOC(doc->virtadr, NOP); 239 dummy = ReadDOC(doc->virtadr, NOP);
@@ -242,7 +242,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
242 else 242 else
243 dummy = ReadDOC(doc->virtadr, DOCStatus); 243 dummy = ReadDOC(doc->virtadr, DOCStatus);
244 } 244 }
245 245
246} 246}
247 247
248#define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1) 248#define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1)
@@ -327,7 +327,7 @@ static u_char doc2000_read_byte(struct mtd_info *mtd)
327 return ret; 327 return ret;
328} 328}
329 329
330static void doc2000_writebuf(struct mtd_info *mtd, 330static void doc2000_writebuf(struct mtd_info *mtd,
331 const u_char *buf, int len) 331 const u_char *buf, int len)
332{ 332{
333 struct nand_chip *this = mtd->priv; 333 struct nand_chip *this = mtd->priv;
@@ -343,7 +343,7 @@ static void doc2000_writebuf(struct mtd_info *mtd,
343 if (debug) printk("\n"); 343 if (debug) printk("\n");
344} 344}
345 345
346static void doc2000_readbuf(struct mtd_info *mtd, 346static void doc2000_readbuf(struct mtd_info *mtd,
347 u_char *buf, int len) 347 u_char *buf, int len)
348{ 348{
349 struct nand_chip *this = mtd->priv; 349 struct nand_chip *this = mtd->priv;
@@ -358,7 +358,7 @@ static void doc2000_readbuf(struct mtd_info *mtd,
358 } 358 }
359} 359}
360 360
361static void doc2000_readbuf_dword(struct mtd_info *mtd, 361static void doc2000_readbuf_dword(struct mtd_info *mtd,
362 u_char *buf, int len) 362 u_char *buf, int len)
363{ 363{
364 struct nand_chip *this = mtd->priv; 364 struct nand_chip *this = mtd->priv;
@@ -379,7 +379,7 @@ static void doc2000_readbuf_dword(struct mtd_info *mtd,
379 } 379 }
380} 380}
381 381
382static int doc2000_verifybuf(struct mtd_info *mtd, 382static int doc2000_verifybuf(struct mtd_info *mtd,
383 const u_char *buf, int len) 383 const u_char *buf, int len)
384{ 384{
385 struct nand_chip *this = mtd->priv; 385 struct nand_chip *this = mtd->priv;
@@ -406,12 +406,12 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
406 doc200x_hwcontrol(mtd, NAND_CTL_SETALE); 406 doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
407 this->write_byte(mtd, 0); 407 this->write_byte(mtd, 0);
408 doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); 408 doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
409 409
410 /* We cant' use dev_ready here, but at least we wait for the 410 /* We cant' use dev_ready here, but at least we wait for the
411 * command to complete 411 * command to complete
412 */ 412 */
413 udelay(50); 413 udelay(50);
414 414
415 ret = this->read_byte(mtd) << 8; 415 ret = this->read_byte(mtd) << 8;
416 ret |= this->read_byte(mtd); 416 ret |= this->read_byte(mtd);
417 417
@@ -438,7 +438,7 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
438 this->read_buf = &doc2000_readbuf_dword; 438 this->read_buf = &doc2000_readbuf_dword;
439 } 439 }
440 } 440 }
441 441
442 return ret; 442 return ret;
443} 443}
444 444
@@ -469,7 +469,7 @@ static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
469 struct doc_priv *doc = this->priv; 469 struct doc_priv *doc = this->priv;
470 470
471 int status; 471 int status;
472 472
473 DoC_WaitReady(doc); 473 DoC_WaitReady(doc);
474 this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); 474 this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
475 DoC_WaitReady(doc); 475 DoC_WaitReady(doc);
@@ -503,7 +503,7 @@ static u_char doc2001_read_byte(struct mtd_info *mtd)
503 return ReadDOC(docptr, LastDataRead); 503 return ReadDOC(docptr, LastDataRead);
504} 504}
505 505
506static void doc2001_writebuf(struct mtd_info *mtd, 506static void doc2001_writebuf(struct mtd_info *mtd,
507 const u_char *buf, int len) 507 const u_char *buf, int len)
508{ 508{
509 struct nand_chip *this = mtd->priv; 509 struct nand_chip *this = mtd->priv;
@@ -517,7 +517,7 @@ static void doc2001_writebuf(struct mtd_info *mtd,
517 WriteDOC(0x00, docptr, WritePipeTerm); 517 WriteDOC(0x00, docptr, WritePipeTerm);
518} 518}
519 519
520static void doc2001_readbuf(struct mtd_info *mtd, 520static void doc2001_readbuf(struct mtd_info *mtd,
521 u_char *buf, int len) 521 u_char *buf, int len)
522{ 522{
523 struct nand_chip *this = mtd->priv; 523 struct nand_chip *this = mtd->priv;
@@ -535,7 +535,7 @@ static void doc2001_readbuf(struct mtd_info *mtd,
535 buf[i] = ReadDOC(docptr, LastDataRead); 535 buf[i] = ReadDOC(docptr, LastDataRead);
536} 536}
537 537
538static int doc2001_verifybuf(struct mtd_info *mtd, 538static int doc2001_verifybuf(struct mtd_info *mtd,
539 const u_char *buf, int len) 539 const u_char *buf, int len)
540{ 540{
541 struct nand_chip *this = mtd->priv; 541 struct nand_chip *this = mtd->priv;
@@ -570,7 +570,7 @@ static u_char doc2001plus_read_byte(struct mtd_info *mtd)
570 return ret; 570 return ret;
571} 571}
572 572
573static void doc2001plus_writebuf(struct mtd_info *mtd, 573static void doc2001plus_writebuf(struct mtd_info *mtd,
574 const u_char *buf, int len) 574 const u_char *buf, int len)
575{ 575{
576 struct nand_chip *this = mtd->priv; 576 struct nand_chip *this = mtd->priv;
@@ -587,7 +587,7 @@ static void doc2001plus_writebuf(struct mtd_info *mtd,
587 if (debug) printk("\n"); 587 if (debug) printk("\n");
588} 588}
589 589
590static void doc2001plus_readbuf(struct mtd_info *mtd, 590static void doc2001plus_readbuf(struct mtd_info *mtd,
591 u_char *buf, int len) 591 u_char *buf, int len)
592{ 592{
593 struct nand_chip *this = mtd->priv; 593 struct nand_chip *this = mtd->priv;
@@ -617,7 +617,7 @@ static void doc2001plus_readbuf(struct mtd_info *mtd,
617 if (debug) printk("\n"); 617 if (debug) printk("\n");
618} 618}
619 619
620static int doc2001plus_verifybuf(struct mtd_info *mtd, 620static int doc2001plus_verifybuf(struct mtd_info *mtd,
621 const u_char *buf, int len) 621 const u_char *buf, int len)
622{ 622{
623 struct nand_chip *this = mtd->priv; 623 struct nand_chip *this = mtd->priv;
@@ -797,7 +797,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
797 WriteDOC(0, docptr, Mplus_FlashControl); 797 WriteDOC(0, docptr, Mplus_FlashControl);
798 } 798 }
799 799
800 /* 800 /*
801 * program and erase have their own busy handlers 801 * program and erase have their own busy handlers
802 * status and sequential in needs no delay 802 * status and sequential in needs no delay
803 */ 803 */
@@ -822,7 +822,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
822 822
823 /* This applies to read commands */ 823 /* This applies to read commands */
824 default: 824 default:
825 /* 825 /*
826 * If we don't have access to the busy pin, we apply the given 826 * If we don't have access to the busy pin, we apply the given
827 * command delay 827 * command delay
828 */ 828 */
@@ -945,7 +945,7 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
945 for (i = 0; i < 6; i++) { 945 for (i = 0; i < 6; i++) {
946 if (DoC_is_MillenniumPlus(doc)) 946 if (DoC_is_MillenniumPlus(doc))
947 ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i); 947 ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i);
948 else 948 else
949 ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i); 949 ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
950 if (ecc_code[i] != empty_write_ecc[i]) 950 if (ecc_code[i] != empty_write_ecc[i])
951 emptymatch = 0; 951 emptymatch = 0;
@@ -982,7 +982,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
982 void __iomem *docptr = doc->virtadr; 982 void __iomem *docptr = doc->virtadr;
983 volatile u_char dummy; 983 volatile u_char dummy;
984 int emptymatch = 1; 984 int emptymatch = 1;
985 985
986 /* flush the pipeline */ 986 /* flush the pipeline */
987 if (DoC_is_2000(doc)) { 987 if (DoC_is_2000(doc)) {
988 dummy = ReadDOC(docptr, 2k_ECCStatus); 988 dummy = ReadDOC(docptr, 2k_ECCStatus);
@@ -997,7 +997,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
997 dummy = ReadDOC(docptr, ECCConf); 997 dummy = ReadDOC(docptr, ECCConf);
998 dummy = ReadDOC(docptr, ECCConf); 998 dummy = ReadDOC(docptr, ECCConf);
999 } 999 }
1000 1000
1001 /* Error occured ? */ 1001 /* Error occured ? */
1002 if (dummy & 0x80) { 1002 if (dummy & 0x80) {
1003 for (i = 0; i < 6; i++) { 1003 for (i = 0; i < 6; i++) {
@@ -1035,7 +1035,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
1035 if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc); 1035 if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc);
1036 if (ret > 0) 1036 if (ret > 0)
1037 printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret); 1037 printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret);
1038 } 1038 }
1039 if (DoC_is_MillenniumPlus(doc)) 1039 if (DoC_is_MillenniumPlus(doc))
1040 WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); 1040 WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
1041 else 1041 else
@@ -1046,7 +1046,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
1046 } 1046 }
1047 return ret; 1047 return ret;
1048} 1048}
1049 1049
1050//u_char mydatabuf[528]; 1050//u_char mydatabuf[528];
1051 1051
1052/* The strange out-of-order .oobfree list below is a (possibly unneeded) 1052/* The strange out-of-order .oobfree list below is a (possibly unneeded)
@@ -1065,7 +1065,7 @@ static struct nand_oobinfo doc200x_oobinfo = {
1065 .eccpos = {0, 1, 2, 3, 4, 5}, 1065 .eccpos = {0, 1, 2, 3, 4, 5},
1066 .oobfree = { {8, 8}, {6, 2} } 1066 .oobfree = { {8, 8}, {6, 2} }
1067}; 1067};
1068 1068
1069/* Find the (I)NFTL Media Header, and optionally also the mirror media header. 1069/* Find the (I)NFTL Media Header, and optionally also the mirror media header.
1070 On sucessful return, buf will contain a copy of the media header for 1070 On sucessful return, buf will contain a copy of the media header for
1071 further processing. id is the string to scan for, and will presumably be 1071 further processing. id is the string to scan for, and will presumably be
@@ -1251,7 +1251,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
1251 mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits); 1251 mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits);
1252 mh->FormatFlags = le32_to_cpu(mh->FormatFlags); 1252 mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
1253 mh->PercentUsed = le32_to_cpu(mh->PercentUsed); 1253 mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
1254 1254
1255 printk(KERN_INFO " bootRecordID = %s\n" 1255 printk(KERN_INFO " bootRecordID = %s\n"
1256 " NoOfBootImageBlocks = %d\n" 1256 " NoOfBootImageBlocks = %d\n"
1257 " NoOfBinaryPartitions = %d\n" 1257 " NoOfBinaryPartitions = %d\n"
@@ -1468,7 +1468,7 @@ static inline int __init doc2001_init(struct mtd_info *mtd)
1468 ReadDOC(doc->virtadr, ChipID); 1468 ReadDOC(doc->virtadr, ChipID);
1469 if (ReadDOC(doc->virtadr, ChipID) != DOC_ChipID_DocMil) { 1469 if (ReadDOC(doc->virtadr, ChipID) != DOC_ChipID_DocMil) {
1470 /* It's not a Millennium; it's one of the newer 1470 /* It's not a Millennium; it's one of the newer
1471 DiskOnChip 2000 units with a similar ASIC. 1471 DiskOnChip 2000 units with a similar ASIC.
1472 Treat it like a Millennium, except that it 1472 Treat it like a Millennium, except that it
1473 can have multiple chips. */ 1473 can have multiple chips. */
1474 doc2000_count_chips(mtd); 1474 doc2000_count_chips(mtd);
@@ -1530,20 +1530,20 @@ static inline int __init doc_probe(unsigned long physadr)
1530 * to the DOCControl register. So we store the current contents 1530 * to the DOCControl register. So we store the current contents
1531 * of the DOCControl register's location, in case we later decide 1531 * of the DOCControl register's location, in case we later decide
1532 * that it's not a DiskOnChip, and want to put it back how we 1532 * that it's not a DiskOnChip, and want to put it back how we
1533 * found it. 1533 * found it.
1534 */ 1534 */
1535 save_control = ReadDOC(virtadr, DOCControl); 1535 save_control = ReadDOC(virtadr, DOCControl);
1536 1536
1537 /* Reset the DiskOnChip ASIC */ 1537 /* Reset the DiskOnChip ASIC */
1538 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 1538 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
1539 virtadr, DOCControl); 1539 virtadr, DOCControl);
1540 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 1540 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
1541 virtadr, DOCControl); 1541 virtadr, DOCControl);
1542 1542
1543 /* Enable the DiskOnChip ASIC */ 1543 /* Enable the DiskOnChip ASIC */
1544 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 1544 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
1545 virtadr, DOCControl); 1545 virtadr, DOCControl);
1546 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 1546 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
1547 virtadr, DOCControl); 1547 virtadr, DOCControl);
1548 1548
1549 ChipID = ReadDOC(virtadr, ChipID); 1549 ChipID = ReadDOC(virtadr, ChipID);
@@ -1738,7 +1738,7 @@ static int __init init_nanddoc(void)
1738 int i, ret = 0; 1738 int i, ret = 0;
1739 1739
1740 /* We could create the decoder on demand, if memory is a concern. 1740 /* We could create the decoder on demand, if memory is a concern.
1741 * This way we have it handy, if an error happens 1741 * This way we have it handy, if an error happens
1742 * 1742 *
1743 * Symbolsize is 10 (bits) 1743 * Symbolsize is 10 (bits)
1744 * Primitve polynomial is x^10+x^3+1 1744 * Primitve polynomial is x^10+x^3+1
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c
index 5549681ccdce..9b1fd2f387fa 100644
--- a/drivers/mtd/nand/edb7312.c
+++ b/drivers/mtd/nand/edb7312.c
@@ -6,7 +6,7 @@
6 * Derived from drivers/mtd/nand/autcpu12.c 6 * Derived from drivers/mtd/nand/autcpu12.c
7 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) 7 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
8 * 8 *
9 * $Id: edb7312.c,v 1.11 2004/11/04 12:53:10 gleixner Exp $ 9 * $Id: edb7312.c,v 1.12 2005/11/07 11:14:30 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -71,27 +71,27 @@ static struct mtd_partition partition_info[] = {
71#endif 71#endif
72 72
73 73
74/* 74/*
75 * hardware specific access to control-lines 75 * hardware specific access to control-lines
76 */ 76 */
77static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd) 77static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd)
78{ 78{
79 switch(cmd) { 79 switch(cmd) {
80 80
81 case NAND_CTL_SETCLE: 81 case NAND_CTL_SETCLE:
82 clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr); 82 clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr);
83 break; 83 break;
84 case NAND_CTL_CLRCLE: 84 case NAND_CTL_CLRCLE:
85 clps_writeb(clps_readb(ep7312_pxdr) & ~0x10, ep7312_pxdr); 85 clps_writeb(clps_readb(ep7312_pxdr) & ~0x10, ep7312_pxdr);
86 break; 86 break;
87 87
88 case NAND_CTL_SETALE: 88 case NAND_CTL_SETALE:
89 clps_writeb(clps_readb(ep7312_pxdr) | 0x20, ep7312_pxdr); 89 clps_writeb(clps_readb(ep7312_pxdr) | 0x20, ep7312_pxdr);
90 break; 90 break;
91 case NAND_CTL_CLRALE: 91 case NAND_CTL_CLRALE:
92 clps_writeb(clps_readb(ep7312_pxdr) & ~0x20, ep7312_pxdr); 92 clps_writeb(clps_readb(ep7312_pxdr) & ~0x20, ep7312_pxdr);
93 break; 93 break;
94 94
95 case NAND_CTL_SETNCE: 95 case NAND_CTL_SETNCE:
96 clps_writeb((clps_readb(ep7312_pxdr) | 0x80) & ~0x40, ep7312_pxdr); 96 clps_writeb((clps_readb(ep7312_pxdr) | 0x80) & ~0x40, ep7312_pxdr);
97 break; 97 break;
@@ -122,16 +122,16 @@ static int __init ep7312_init (void)
122 int mtd_parts_nb = 0; 122 int mtd_parts_nb = 0;
123 struct mtd_partition *mtd_parts = 0; 123 struct mtd_partition *mtd_parts = 0;
124 void __iomem * ep7312_fio_base; 124 void __iomem * ep7312_fio_base;
125 125
126 /* Allocate memory for MTD device structure and private data */ 126 /* Allocate memory for MTD device structure and private data */
127 ep7312_mtd = kmalloc(sizeof(struct mtd_info) + 127 ep7312_mtd = kmalloc(sizeof(struct mtd_info) +
128 sizeof(struct nand_chip), 128 sizeof(struct nand_chip),
129 GFP_KERNEL); 129 GFP_KERNEL);
130 if (!ep7312_mtd) { 130 if (!ep7312_mtd) {
131 printk("Unable to allocate EDB7312 NAND MTD device structure.\n"); 131 printk("Unable to allocate EDB7312 NAND MTD device structure.\n");
132 return -ENOMEM; 132 return -ENOMEM;
133 } 133 }
134 134
135 /* map physical adress */ 135 /* map physical adress */
136 ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K); 136 ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K);
137 if(!ep7312_fio_base) { 137 if(!ep7312_fio_base) {
@@ -139,23 +139,23 @@ static int __init ep7312_init (void)
139 kfree(ep7312_mtd); 139 kfree(ep7312_mtd);
140 return -EIO; 140 return -EIO;
141 } 141 }
142 142
143 /* Get pointer to private data */ 143 /* Get pointer to private data */
144 this = (struct nand_chip *) (&ep7312_mtd[1]); 144 this = (struct nand_chip *) (&ep7312_mtd[1]);
145 145
146 /* Initialize structures */ 146 /* Initialize structures */
147 memset((char *) ep7312_mtd, 0, sizeof(struct mtd_info)); 147 memset((char *) ep7312_mtd, 0, sizeof(struct mtd_info));
148 memset((char *) this, 0, sizeof(struct nand_chip)); 148 memset((char *) this, 0, sizeof(struct nand_chip));
149 149
150 /* Link the private data with the MTD structure */ 150 /* Link the private data with the MTD structure */
151 ep7312_mtd->priv = this; 151 ep7312_mtd->priv = this;
152 152
153 /* 153 /*
154 * Set GPIO Port B control register so that the pins are configured 154 * Set GPIO Port B control register so that the pins are configured
155 * to be outputs for controlling the NAND flash. 155 * to be outputs for controlling the NAND flash.
156 */ 156 */
157 clps_writeb(0xf0, ep7312_pxddr); 157 clps_writeb(0xf0, ep7312_pxddr);
158 158
159 /* insert callbacks */ 159 /* insert callbacks */
160 this->IO_ADDR_R = ep7312_fio_base; 160 this->IO_ADDR_R = ep7312_fio_base;
161 this->IO_ADDR_W = ep7312_fio_base; 161 this->IO_ADDR_W = ep7312_fio_base;
@@ -163,14 +163,14 @@ static int __init ep7312_init (void)
163 this->dev_ready = ep7312_device_ready; 163 this->dev_ready = ep7312_device_ready;
164 /* 15 us command delay time */ 164 /* 15 us command delay time */
165 this->chip_delay = 15; 165 this->chip_delay = 15;
166 166
167 /* Scan to find existence of the device */ 167 /* Scan to find existence of the device */
168 if (nand_scan (ep7312_mtd, 1)) { 168 if (nand_scan (ep7312_mtd, 1)) {
169 iounmap((void *)ep7312_fio_base); 169 iounmap((void *)ep7312_fio_base);
170 kfree (ep7312_mtd); 170 kfree (ep7312_mtd);
171 return -ENXIO; 171 return -ENXIO;
172 } 172 }
173 173
174#ifdef CONFIG_MTD_PARTITIONS 174#ifdef CONFIG_MTD_PARTITIONS
175 ep7312_mtd->name = "edb7312-nand"; 175 ep7312_mtd->name = "edb7312-nand";
176 mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, 176 mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes,
@@ -185,11 +185,11 @@ static int __init ep7312_init (void)
185 mtd_parts_nb = NUM_PARTITIONS; 185 mtd_parts_nb = NUM_PARTITIONS;
186 part_type = "static"; 186 part_type = "static";
187 } 187 }
188 188
189 /* Register the partitions */ 189 /* Register the partitions */
190 printk(KERN_NOTICE "Using %s partition definition\n", part_type); 190 printk(KERN_NOTICE "Using %s partition definition\n", part_type);
191 add_mtd_partitions(ep7312_mtd, mtd_parts, mtd_parts_nb); 191 add_mtd_partitions(ep7312_mtd, mtd_parts, mtd_parts_nb);
192 192
193 /* Return happy */ 193 /* Return happy */
194 return 0; 194 return 0;
195} 195}
@@ -201,13 +201,13 @@ module_init(ep7312_init);
201static void __exit ep7312_cleanup (void) 201static void __exit ep7312_cleanup (void)
202{ 202{
203 struct nand_chip *this = (struct nand_chip *) &ep7312_mtd[1]; 203 struct nand_chip *this = (struct nand_chip *) &ep7312_mtd[1];
204 204
205 /* Release resources, unregister device */ 205 /* Release resources, unregister device */
206 nand_release (ap7312_mtd); 206 nand_release (ap7312_mtd);
207 207
208 /* Free internal data buffer */ 208 /* Free internal data buffer */
209 kfree (this->data_buf); 209 kfree (this->data_buf);
210 210
211 /* Free the MTD device structure */ 211 /* Free the MTD device structure */
212 kfree (ep7312_mtd); 212 kfree (ep7312_mtd);
213} 213}
diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c
index 3825a7a0900c..041e4b3358fb 100644
--- a/drivers/mtd/nand/h1910.c
+++ b/drivers/mtd/nand/h1910.c
@@ -7,7 +7,7 @@
7 * Copyright (C) 2002 Marius Gröger (mag@sysgo.de) 7 * Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
8 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) 8 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
9 * 9 *
10 * $Id: h1910.c,v 1.5 2004/11/04 12:53:10 gleixner Exp $ 10 * $Id: h1910.c,v 1.6 2005/11/07 11:14:30 gleixner Exp $
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as 13 * it under the terms of the GNU General Public License version 2 as
@@ -54,24 +54,24 @@ static struct mtd_partition partition_info[] = {
54#endif 54#endif
55 55
56 56
57/* 57/*
58 * hardware specific access to control-lines 58 * hardware specific access to control-lines
59 */ 59 */
60static void h1910_hwcontrol(struct mtd_info *mtd, int cmd) 60static void h1910_hwcontrol(struct mtd_info *mtd, int cmd)
61{ 61{
62 struct nand_chip* this = (struct nand_chip *) (mtd->priv); 62 struct nand_chip* this = (struct nand_chip *) (mtd->priv);
63 63
64 switch(cmd) { 64 switch(cmd) {
65 65
66 case NAND_CTL_SETCLE: 66 case NAND_CTL_SETCLE:
67 this->IO_ADDR_R |= (1 << 2); 67 this->IO_ADDR_R |= (1 << 2);
68 this->IO_ADDR_W |= (1 << 2); 68 this->IO_ADDR_W |= (1 << 2);
69 break; 69 break;
70 case NAND_CTL_CLRCLE: 70 case NAND_CTL_CLRCLE:
71 this->IO_ADDR_R &= ~(1 << 2); 71 this->IO_ADDR_R &= ~(1 << 2);
72 this->IO_ADDR_W &= ~(1 << 2); 72 this->IO_ADDR_W &= ~(1 << 2);
73 break; 73 break;
74 74
75 case NAND_CTL_SETALE: 75 case NAND_CTL_SETALE:
76 this->IO_ADDR_R |= (1 << 3); 76 this->IO_ADDR_R |= (1 << 3);
77 this->IO_ADDR_W |= (1 << 3); 77 this->IO_ADDR_W |= (1 << 3);
@@ -80,7 +80,7 @@ static void h1910_hwcontrol(struct mtd_info *mtd, int cmd)
80 this->IO_ADDR_R &= ~(1 << 3); 80 this->IO_ADDR_R &= ~(1 << 3);
81 this->IO_ADDR_W &= ~(1 << 3); 81 this->IO_ADDR_W &= ~(1 << 3);
82 break; 82 break;
83 83
84 case NAND_CTL_SETNCE: 84 case NAND_CTL_SETNCE:
85 break; 85 break;
86 case NAND_CTL_CLRNCE: 86 case NAND_CTL_CLRNCE:
@@ -108,18 +108,18 @@ static int __init h1910_init (void)
108 int mtd_parts_nb = 0; 108 int mtd_parts_nb = 0;
109 struct mtd_partition *mtd_parts = 0; 109 struct mtd_partition *mtd_parts = 0;
110 void __iomem *nandaddr; 110 void __iomem *nandaddr;
111 111
112 if (!machine_is_h1900()) 112 if (!machine_is_h1900())
113 return -ENODEV; 113 return -ENODEV;
114 114
115 nandaddr = __ioremap(0x08000000, 0x1000, 0, 1); 115 nandaddr = __ioremap(0x08000000, 0x1000, 0, 1);
116 if (!nandaddr) { 116 if (!nandaddr) {
117 printk("Failed to ioremap nand flash.\n"); 117 printk("Failed to ioremap nand flash.\n");
118 return -ENOMEM; 118 return -ENOMEM;
119 } 119 }
120 120
121 /* Allocate memory for MTD device structure and private data */ 121 /* Allocate memory for MTD device structure and private data */
122 h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) + 122 h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) +
123 sizeof(struct nand_chip), 123 sizeof(struct nand_chip),
124 GFP_KERNEL); 124 GFP_KERNEL);
125 if (!h1910_nand_mtd) { 125 if (!h1910_nand_mtd) {
@@ -127,22 +127,22 @@ static int __init h1910_init (void)
127 iounmap ((void *) nandaddr); 127 iounmap ((void *) nandaddr);
128 return -ENOMEM; 128 return -ENOMEM;
129 } 129 }
130 130
131 /* Get pointer to private data */ 131 /* Get pointer to private data */
132 this = (struct nand_chip *) (&h1910_nand_mtd[1]); 132 this = (struct nand_chip *) (&h1910_nand_mtd[1]);
133 133
134 /* Initialize structures */ 134 /* Initialize structures */
135 memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info)); 135 memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info));
136 memset((char *) this, 0, sizeof(struct nand_chip)); 136 memset((char *) this, 0, sizeof(struct nand_chip));
137 137
138 /* Link the private data with the MTD structure */ 138 /* Link the private data with the MTD structure */
139 h1910_nand_mtd->priv = this; 139 h1910_nand_mtd->priv = this;
140 140
141 /* 141 /*
142 * Enable VPEN 142 * Enable VPEN
143 */ 143 */
144 GPSR(37) = GPIO_bit(37); 144 GPSR(37) = GPIO_bit(37);
145 145
146 /* insert callbacks */ 146 /* insert callbacks */
147 this->IO_ADDR_R = nandaddr; 147 this->IO_ADDR_R = nandaddr;
148 this->IO_ADDR_W = nandaddr; 148 this->IO_ADDR_W = nandaddr;
@@ -152,7 +152,7 @@ static int __init h1910_init (void)
152 this->chip_delay = 50; 152 this->chip_delay = 50;
153 this->eccmode = NAND_ECC_SOFT; 153 this->eccmode = NAND_ECC_SOFT;
154 this->options = NAND_NO_AUTOINCR; 154 this->options = NAND_NO_AUTOINCR;
155 155
156 /* Scan to find existence of the device */ 156 /* Scan to find existence of the device */
157 if (nand_scan (h1910_nand_mtd, 1)) { 157 if (nand_scan (h1910_nand_mtd, 1)) {
158 printk(KERN_NOTICE "No NAND device - returning -ENXIO\n"); 158 printk(KERN_NOTICE "No NAND device - returning -ENXIO\n");
@@ -160,9 +160,9 @@ static int __init h1910_init (void)
160 iounmap ((void *) nandaddr); 160 iounmap ((void *) nandaddr);
161 return -ENXIO; 161 return -ENXIO;
162 } 162 }
163 163
164#ifdef CONFIG_MTD_CMDLINE_PARTS 164#ifdef CONFIG_MTD_CMDLINE_PARTS
165 mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts, 165 mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts,
166 "h1910-nand"); 166 "h1910-nand");
167 if (mtd_parts_nb > 0) 167 if (mtd_parts_nb > 0)
168 part_type = "command line"; 168 part_type = "command line";
@@ -175,11 +175,11 @@ static int __init h1910_init (void)
175 mtd_parts_nb = NUM_PARTITIONS; 175 mtd_parts_nb = NUM_PARTITIONS;
176 part_type = "static"; 176 part_type = "static";
177 } 177 }
178 178
179 /* Register the partitions */ 179 /* Register the partitions */
180 printk(KERN_NOTICE "Using %s partition definition\n", part_type); 180 printk(KERN_NOTICE "Using %s partition definition\n", part_type);
181 add_mtd_partitions(h1910_nand_mtd, mtd_parts, mtd_parts_nb); 181 add_mtd_partitions(h1910_nand_mtd, mtd_parts, mtd_parts_nb);
182 182
183 /* Return happy */ 183 /* Return happy */
184 return 0; 184 return 0;
185} 185}
@@ -191,7 +191,7 @@ module_init(h1910_init);
191static void __exit h1910_cleanup (void) 191static void __exit h1910_cleanup (void)
192{ 192{
193 struct nand_chip *this = (struct nand_chip *) &h1910_nand_mtd[1]; 193 struct nand_chip *this = (struct nand_chip *) &h1910_nand_mtd[1];
194 194
195 /* Release resources, unregister device */ 195 /* Release resources, unregister device */
196 nand_release (h1910_nand_mtd); 196 nand_release (h1910_nand_mtd);
197 197
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 04e54318bc6a..5d222460b42a 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -5,14 +5,14 @@
5 * This is the generic MTD driver for NAND flash devices. It should be 5 * This is the generic MTD driver for NAND flash devices. It should be
6 * capable of working with almost all NAND chips currently available. 6 * capable of working with almost all NAND chips currently available.
7 * Basic support for AG-AND chips is provided. 7 * Basic support for AG-AND chips is provided.
8 * 8 *
9 * Additional technical information is available on 9 * Additional technical information is available on
10 * http://www.linux-mtd.infradead.org/tech/nand.html 10 * http://www.linux-mtd.infradead.org/tech/nand.html
11 * 11 *
12 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 12 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
13 * 2002 Thomas Gleixner (tglx@linutronix.de) 13 * 2002 Thomas Gleixner (tglx@linutronix.de)
14 * 14 *
15 * 02-08-2004 tglx: support for strange chips, which cannot auto increment 15 * 02-08-2004 tglx: support for strange chips, which cannot auto increment
16 * pages on read / read_oob 16 * pages on read / read_oob
17 * 17 *
18 * 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes 18 * 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes
@@ -21,7 +21,7 @@
21 * Make reads over block boundaries work too 21 * Make reads over block boundaries work too
22 * 22 *
23 * 04-14-2004 tglx: first working version for 2k page size chips 23 * 04-14-2004 tglx: first working version for 2k page size chips
24 * 24 *
25 * 05-19-2004 tglx: Basic support for Renesas AG-AND chips 25 * 05-19-2004 tglx: Basic support for Renesas AG-AND chips
26 * 26 *
27 * 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared 27 * 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared
@@ -30,25 +30,27 @@
30 * 30 *
31 * 12-05-2004 dmarlin: add workaround for Renesas AG-AND chips "disturb" issue. 31 * 12-05-2004 dmarlin: add workaround for Renesas AG-AND chips "disturb" issue.
32 * Basically, any block not rewritten may lose data when surrounding blocks 32 * Basically, any block not rewritten may lose data when surrounding blocks
33 * are rewritten many times. JFFS2 ensures this doesn't happen for blocks 33 * are rewritten many times. JFFS2 ensures this doesn't happen for blocks
34 * it uses, but the Bad Block Table(s) may not be rewritten. To ensure they 34 * it uses, but the Bad Block Table(s) may not be rewritten. To ensure they
35 * do not lose data, force them to be rewritten when some of the surrounding 35 * do not lose data, force them to be rewritten when some of the surrounding
36 * blocks are erased. Rather than tracking a specific nearby block (which 36 * blocks are erased. Rather than tracking a specific nearby block (which
37 * could itself go bad), use a page address 'mask' to select several blocks 37 * could itself go bad), use a page address 'mask' to select several blocks
38 * in the same area, and rewrite the BBT when any of them are erased. 38 * in the same area, and rewrite the BBT when any of them are erased.
39 * 39 *
40 * 01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas 40 * 01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas
41 * AG-AND chips. If there was a sudden loss of power during an erase operation, 41 * AG-AND chips. If there was a sudden loss of power during an erase operation,
42 * a "device recovery" operation must be performed when power is restored 42 * a "device recovery" operation must be performed when power is restored
43 * to ensure correct operation. 43 * to ensure correct operation.
44 * 44 *
45 * 01-20-2005 dmarlin: added support for optional hardware specific callback routine to 45 * 01-20-2005 dmarlin: added support for optional hardware specific callback routine to
46 * perform extra error status checks on erase and write failures. This required 46 * perform extra error status checks on erase and write failures. This required
47 * adding a wrapper function for nand_read_ecc. 47 * adding a wrapper function for nand_read_ecc.
48 * 48 *
49 * 08-20-2005 vwool: suspend/resume added
50 *
49 * Credits: 51 * Credits:
50 * David Woodhouse for adding multichip support 52 * David Woodhouse for adding multichip support
51 * 53 *
52 * Aleph One Ltd. and Toby Churchill Ltd. for supporting the 54 * Aleph One Ltd. and Toby Churchill Ltd. for supporting the
53 * rework for 2K page size chips 55 * rework for 2K page size chips
54 * 56 *
@@ -59,7 +61,7 @@
59 * The AG-AND chips have nice features for speed improvement, 61 * The AG-AND chips have nice features for speed improvement,
60 * which are not supported yet. Read / program 4 pages in one go. 62 * which are not supported yet. Read / program 4 pages in one go.
61 * 63 *
62 * $Id: nand_base.c,v 1.147 2005/07/15 07:18:06 gleixner Exp $ 64 * $Id: nand_base.c,v 1.150 2005/09/15 13:58:48 vwool Exp $
63 * 65 *
64 * This program is free software; you can redistribute it and/or modify 66 * This program is free software; you can redistribute it and/or modify
65 * it under the terms of the GNU General Public License version 2 as 67 * it under the terms of the GNU General Public License version 2 as
@@ -103,8 +105,8 @@ static struct nand_oobinfo nand_oob_64 = {
103 .useecc = MTD_NANDECC_AUTOPLACE, 105 .useecc = MTD_NANDECC_AUTOPLACE,
104 .eccbytes = 24, 106 .eccbytes = 24,
105 .eccpos = { 107 .eccpos = {
106 40, 41, 42, 43, 44, 45, 46, 47, 108 40, 41, 42, 43, 44, 45, 46, 47,
107 48, 49, 50, 51, 52, 53, 54, 55, 109 48, 49, 50, 51, 52, 53, 54, 55,
108 56, 57, 58, 59, 60, 61, 62, 63}, 110 56, 57, 58, 59, 60, 61, 62, 63},
109 .oobfree = { {2, 38} } 111 .oobfree = { {2, 38} }
110}; 112};
@@ -147,19 +149,19 @@ static void nand_sync (struct mtd_info *mtd);
147static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, 149static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf,
148 struct nand_oobinfo *oobsel, int mode); 150 struct nand_oobinfo *oobsel, int mode);
149#ifdef CONFIG_MTD_NAND_VERIFY_WRITE 151#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
150static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, 152static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
151 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode); 153 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode);
152#else 154#else
153#define nand_verify_pages(...) (0) 155#define nand_verify_pages(...) (0)
154#endif 156#endif
155 157
156static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state); 158static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state);
157 159
158/** 160/**
159 * nand_release_device - [GENERIC] release chip 161 * nand_release_device - [GENERIC] release chip
160 * @mtd: MTD device structure 162 * @mtd: MTD device structure
161 * 163 *
162 * Deselect, release chip lock and wake up anyone waiting on the device 164 * Deselect, release chip lock and wake up anyone waiting on the device
163 */ 165 */
164static void nand_release_device (struct mtd_info *mtd) 166static void nand_release_device (struct mtd_info *mtd)
165{ 167{
@@ -213,7 +215,7 @@ static void nand_write_byte(struct mtd_info *mtd, u_char byte)
213 * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip 215 * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
214 * @mtd: MTD device structure 216 * @mtd: MTD device structure
215 * 217 *
216 * Default read function for 16bit buswith with 218 * Default read function for 16bit buswith with
217 * endianess conversion 219 * endianess conversion
218 */ 220 */
219static u_char nand_read_byte16(struct mtd_info *mtd) 221static u_char nand_read_byte16(struct mtd_info *mtd)
@@ -240,7 +242,7 @@ static void nand_write_byte16(struct mtd_info *mtd, u_char byte)
240 * nand_read_word - [DEFAULT] read one word from the chip 242 * nand_read_word - [DEFAULT] read one word from the chip
241 * @mtd: MTD device structure 243 * @mtd: MTD device structure
242 * 244 *
243 * Default read function for 16bit buswith without 245 * Default read function for 16bit buswith without
244 * endianess conversion 246 * endianess conversion
245 */ 247 */
246static u16 nand_read_word(struct mtd_info *mtd) 248static u16 nand_read_word(struct mtd_info *mtd)
@@ -254,7 +256,7 @@ static u16 nand_read_word(struct mtd_info *mtd)
254 * @mtd: MTD device structure 256 * @mtd: MTD device structure
255 * @word: data word to write 257 * @word: data word to write
256 * 258 *
257 * Default write function for 16bit buswith without 259 * Default write function for 16bit buswith without
258 * endianess conversion 260 * endianess conversion
259 */ 261 */
260static void nand_write_word(struct mtd_info *mtd, u16 word) 262static void nand_write_word(struct mtd_info *mtd, u16 word)
@@ -275,7 +277,7 @@ static void nand_select_chip(struct mtd_info *mtd, int chip)
275 struct nand_chip *this = mtd->priv; 277 struct nand_chip *this = mtd->priv;
276 switch(chip) { 278 switch(chip) {
277 case -1: 279 case -1:
278 this->hwcontrol(mtd, NAND_CTL_CLRNCE); 280 this->hwcontrol(mtd, NAND_CTL_CLRNCE);
279 break; 281 break;
280 case 0: 282 case 0:
281 this->hwcontrol(mtd, NAND_CTL_SETNCE); 283 this->hwcontrol(mtd, NAND_CTL_SETNCE);
@@ -304,7 +306,7 @@ static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
304} 306}
305 307
306/** 308/**
307 * nand_read_buf - [DEFAULT] read chip data into buffer 309 * nand_read_buf - [DEFAULT] read chip data into buffer
308 * @mtd: MTD device structure 310 * @mtd: MTD device structure
309 * @buf: buffer to store date 311 * @buf: buffer to store date
310 * @len: number of bytes to read 312 * @len: number of bytes to read
@@ -321,7 +323,7 @@ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
321} 323}
322 324
323/** 325/**
324 * nand_verify_buf - [DEFAULT] Verify chip data against buffer 326 * nand_verify_buf - [DEFAULT] Verify chip data against buffer
325 * @mtd: MTD device structure 327 * @mtd: MTD device structure
326 * @buf: buffer containing the data to compare 328 * @buf: buffer containing the data to compare
327 * @len: number of bytes to compare 329 * @len: number of bytes to compare
@@ -354,14 +356,14 @@ static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
354 struct nand_chip *this = mtd->priv; 356 struct nand_chip *this = mtd->priv;
355 u16 *p = (u16 *) buf; 357 u16 *p = (u16 *) buf;
356 len >>= 1; 358 len >>= 1;
357 359
358 for (i=0; i<len; i++) 360 for (i=0; i<len; i++)
359 writew(p[i], this->IO_ADDR_W); 361 writew(p[i], this->IO_ADDR_W);
360 362
361} 363}
362 364
363/** 365/**
364 * nand_read_buf16 - [DEFAULT] read chip data into buffer 366 * nand_read_buf16 - [DEFAULT] read chip data into buffer
365 * @mtd: MTD device structure 367 * @mtd: MTD device structure
366 * @buf: buffer to store date 368 * @buf: buffer to store date
367 * @len: number of bytes to read 369 * @len: number of bytes to read
@@ -380,7 +382,7 @@ static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
380} 382}
381 383
382/** 384/**
383 * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer 385 * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
384 * @mtd: MTD device structure 386 * @mtd: MTD device structure
385 * @buf: buffer containing the data to compare 387 * @buf: buffer containing the data to compare
386 * @len: number of bytes to compare 388 * @len: number of bytes to compare
@@ -407,7 +409,7 @@ static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
407 * @ofs: offset from device start 409 * @ofs: offset from device start
408 * @getchip: 0, if the chip is already selected 410 * @getchip: 0, if the chip is already selected
409 * 411 *
410 * Check, if the block is bad. 412 * Check, if the block is bad.
411 */ 413 */
412static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) 414static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
413{ 415{
@@ -424,14 +426,14 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
424 426
425 /* Select the NAND device */ 427 /* Select the NAND device */
426 this->select_chip(mtd, chipnr); 428 this->select_chip(mtd, chipnr);
427 } else 429 } else
428 page = (int) ofs; 430 page = (int) ofs;
429 431
430 if (this->options & NAND_BUSWIDTH_16) { 432 if (this->options & NAND_BUSWIDTH_16) {
431 this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask); 433 this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask);
432 bad = cpu_to_le16(this->read_word(mtd)); 434 bad = cpu_to_le16(this->read_word(mtd));
433 if (this->badblockpos & 0x1) 435 if (this->badblockpos & 0x1)
434 bad >>= 1; 436 bad >>= 8;
435 if ((bad & 0xFF) != 0xff) 437 if ((bad & 0xFF) != 0xff)
436 res = 1; 438 res = 1;
437 } else { 439 } else {
@@ -439,12 +441,12 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
439 if (this->read_byte(mtd) != 0xff) 441 if (this->read_byte(mtd) != 0xff)
440 res = 1; 442 res = 1;
441 } 443 }
442 444
443 if (getchip) { 445 if (getchip) {
444 /* Deselect and wake up anyone waiting on the device */ 446 /* Deselect and wake up anyone waiting on the device */
445 nand_release_device(mtd); 447 nand_release_device(mtd);
446 } 448 }
447 449
448 return res; 450 return res;
449} 451}
450 452
@@ -462,7 +464,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
462 u_char buf[2] = {0, 0}; 464 u_char buf[2] = {0, 0};
463 size_t retlen; 465 size_t retlen;
464 int block; 466 int block;
465 467
466 /* Get block number */ 468 /* Get block number */
467 block = ((int) ofs) >> this->bbt_erase_shift; 469 block = ((int) ofs) >> this->bbt_erase_shift;
468 if (this->bbt) 470 if (this->bbt)
@@ -471,25 +473,25 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
471 /* Do we have a flash based bad block table ? */ 473 /* Do we have a flash based bad block table ? */
472 if (this->options & NAND_USE_FLASH_BBT) 474 if (this->options & NAND_USE_FLASH_BBT)
473 return nand_update_bbt (mtd, ofs); 475 return nand_update_bbt (mtd, ofs);
474 476
475 /* We write two bytes, so we dont have to mess with 16 bit access */ 477 /* We write two bytes, so we dont have to mess with 16 bit access */
476 ofs += mtd->oobsize + (this->badblockpos & ~0x01); 478 ofs += mtd->oobsize + (this->badblockpos & ~0x01);
477 return nand_write_oob (mtd, ofs , 2, &retlen, buf); 479 return nand_write_oob (mtd, ofs , 2, &retlen, buf);
478} 480}
479 481
480/** 482/**
481 * nand_check_wp - [GENERIC] check if the chip is write protected 483 * nand_check_wp - [GENERIC] check if the chip is write protected
482 * @mtd: MTD device structure 484 * @mtd: MTD device structure
483 * Check, if the device is write protected 485 * Check, if the device is write protected
484 * 486 *
485 * The function expects, that the device is already selected 487 * The function expects, that the device is already selected
486 */ 488 */
487static int nand_check_wp (struct mtd_info *mtd) 489static int nand_check_wp (struct mtd_info *mtd)
488{ 490{
489 struct nand_chip *this = mtd->priv; 491 struct nand_chip *this = mtd->priv;
490 /* Check the WP bit */ 492 /* Check the WP bit */
491 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); 493 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
492 return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1; 494 return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
493} 495}
494 496
495/** 497/**
@@ -505,15 +507,15 @@ static int nand_check_wp (struct mtd_info *mtd)
505static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt) 507static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
506{ 508{
507 struct nand_chip *this = mtd->priv; 509 struct nand_chip *this = mtd->priv;
508 510
509 if (!this->bbt) 511 if (!this->bbt)
510 return this->block_bad(mtd, ofs, getchip); 512 return this->block_bad(mtd, ofs, getchip);
511 513
512 /* Return info from the table */ 514 /* Return info from the table */
513 return nand_isbad_bbt (mtd, ofs, allowbbt); 515 return nand_isbad_bbt (mtd, ofs, allowbbt);
514} 516}
515 517
516/* 518/*
517 * Wait for the ready pin, after a command 519 * Wait for the ready pin, after a command
518 * The timeout is catched later. 520 * The timeout is catched later.
519 */ 521 */
@@ -527,7 +529,7 @@ static void nand_wait_ready(struct mtd_info *mtd)
527 if (this->dev_ready(mtd)) 529 if (this->dev_ready(mtd))
528 return; 530 return;
529 touch_softlockup_watchdog(); 531 touch_softlockup_watchdog();
530 } while (time_before(jiffies, timeo)); 532 } while (time_before(jiffies, timeo));
531} 533}
532 534
533/** 535/**
@@ -590,13 +592,13 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
590 /* Latch in address */ 592 /* Latch in address */
591 this->hwcontrol(mtd, NAND_CTL_CLRALE); 593 this->hwcontrol(mtd, NAND_CTL_CLRALE);
592 } 594 }
593 595
594 /* 596 /*
595 * program and erase have their own busy handlers 597 * program and erase have their own busy handlers
596 * status and sequential in needs no delay 598 * status and sequential in needs no delay
597 */ 599 */
598 switch (command) { 600 switch (command) {
599 601
600 case NAND_CMD_PAGEPROG: 602 case NAND_CMD_PAGEPROG:
601 case NAND_CMD_ERASE1: 603 case NAND_CMD_ERASE1:
602 case NAND_CMD_ERASE2: 604 case NAND_CMD_ERASE2:
@@ -605,7 +607,7 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
605 return; 607 return;
606 608
607 case NAND_CMD_RESET: 609 case NAND_CMD_RESET:
608 if (this->dev_ready) 610 if (this->dev_ready)
609 break; 611 break;
610 udelay(this->chip_delay); 612 udelay(this->chip_delay);
611 this->hwcontrol(mtd, NAND_CTL_SETCLE); 613 this->hwcontrol(mtd, NAND_CTL_SETCLE);
@@ -614,16 +616,16 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
614 while ( !(this->read_byte(mtd) & NAND_STATUS_READY)); 616 while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
615 return; 617 return;
616 618
617 /* This applies to read commands */ 619 /* This applies to read commands */
618 default: 620 default:
619 /* 621 /*
620 * If we don't have access to the busy pin, we apply the given 622 * If we don't have access to the busy pin, we apply the given
621 * command delay 623 * command delay
622 */ 624 */
623 if (!this->dev_ready) { 625 if (!this->dev_ready) {
624 udelay (this->chip_delay); 626 udelay (this->chip_delay);
625 return; 627 return;
626 } 628 }
627 } 629 }
628 /* Apply this short delay always to ensure that we do wait tWB in 630 /* Apply this short delay always to ensure that we do wait tWB in
629 * any case on any machine. */ 631 * any case on any machine. */
@@ -653,8 +655,8 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
653 column += mtd->oobblock; 655 column += mtd->oobblock;
654 command = NAND_CMD_READ0; 656 command = NAND_CMD_READ0;
655 } 657 }
656 658
657 659
658 /* Begin command latch cycle */ 660 /* Begin command latch cycle */
659 this->hwcontrol(mtd, NAND_CTL_SETCLE); 661 this->hwcontrol(mtd, NAND_CTL_SETCLE);
660 /* Write out the command to the device. */ 662 /* Write out the command to the device. */
@@ -672,7 +674,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
672 column >>= 1; 674 column >>= 1;
673 this->write_byte(mtd, column & 0xff); 675 this->write_byte(mtd, column & 0xff);
674 this->write_byte(mtd, column >> 8); 676 this->write_byte(mtd, column >> 8);
675 } 677 }
676 if (page_addr != -1) { 678 if (page_addr != -1) {
677 this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); 679 this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
678 this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); 680 this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
@@ -683,13 +685,13 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
683 /* Latch in address */ 685 /* Latch in address */
684 this->hwcontrol(mtd, NAND_CTL_CLRALE); 686 this->hwcontrol(mtd, NAND_CTL_CLRALE);
685 } 687 }
686 688
687 /* 689 /*
688 * program and erase have their own busy handlers 690 * program and erase have their own busy handlers
689 * status, sequential in, and deplete1 need no delay 691 * status, sequential in, and deplete1 need no delay
690 */ 692 */
691 switch (command) { 693 switch (command) {
692 694
693 case NAND_CMD_CACHEDPROG: 695 case NAND_CMD_CACHEDPROG:
694 case NAND_CMD_PAGEPROG: 696 case NAND_CMD_PAGEPROG:
695 case NAND_CMD_ERASE1: 697 case NAND_CMD_ERASE1:
@@ -699,7 +701,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
699 case NAND_CMD_DEPLETE1: 701 case NAND_CMD_DEPLETE1:
700 return; 702 return;
701 703
702 /* 704 /*
703 * read error status commands require only a short delay 705 * read error status commands require only a short delay
704 */ 706 */
705 case NAND_CMD_STATUS_ERROR: 707 case NAND_CMD_STATUS_ERROR:
@@ -711,7 +713,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
711 return; 713 return;
712 714
713 case NAND_CMD_RESET: 715 case NAND_CMD_RESET:
714 if (this->dev_ready) 716 if (this->dev_ready)
715 break; 717 break;
716 udelay(this->chip_delay); 718 udelay(this->chip_delay);
717 this->hwcontrol(mtd, NAND_CTL_SETCLE); 719 this->hwcontrol(mtd, NAND_CTL_SETCLE);
@@ -728,17 +730,17 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
728 /* End command latch cycle */ 730 /* End command latch cycle */
729 this->hwcontrol(mtd, NAND_CTL_CLRCLE); 731 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
730 /* Fall through into ready check */ 732 /* Fall through into ready check */
731 733
732 /* This applies to read commands */ 734 /* This applies to read commands */
733 default: 735 default:
734 /* 736 /*
735 * If we don't have access to the busy pin, we apply the given 737 * If we don't have access to the busy pin, we apply the given
736 * command delay 738 * command delay
737 */ 739 */
738 if (!this->dev_ready) { 740 if (!this->dev_ready) {
739 udelay (this->chip_delay); 741 udelay (this->chip_delay);
740 return; 742 return;
741 } 743 }
742 } 744 }
743 745
744 /* Apply this short delay always to ensure that we do wait tWB in 746 /* Apply this short delay always to ensure that we do wait tWB in
@@ -752,11 +754,11 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
752 * nand_get_device - [GENERIC] Get chip for selected access 754 * nand_get_device - [GENERIC] Get chip for selected access
753 * @this: the nand chip descriptor 755 * @this: the nand chip descriptor
754 * @mtd: MTD device structure 756 * @mtd: MTD device structure
755 * @new_state: the state which is requested 757 * @new_state: the state which is requested
756 * 758 *
757 * Get the device and lock it for exclusive access 759 * Get the device and lock it for exclusive access
758 */ 760 */
759static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) 761static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
760{ 762{
761 struct nand_chip *active; 763 struct nand_chip *active;
762 spinlock_t *lock; 764 spinlock_t *lock;
@@ -779,7 +781,11 @@ retry:
779 if (active == this && this->state == FL_READY) { 781 if (active == this && this->state == FL_READY) {
780 this->state = new_state; 782 this->state = new_state;
781 spin_unlock(lock); 783 spin_unlock(lock);
782 return; 784 return 0;
785 }
786 if (new_state == FL_PM_SUSPENDED) {
787 spin_unlock(lock);
788 return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
783 } 789 }
784 set_current_state(TASK_UNINTERRUPTIBLE); 790 set_current_state(TASK_UNINTERRUPTIBLE);
785 add_wait_queue(wq, &wait); 791 add_wait_queue(wq, &wait);
@@ -796,7 +802,7 @@ retry:
796 * @state: state to select the max. timeout value 802 * @state: state to select the max. timeout value
797 * 803 *
798 * Wait for command done. This applies to erase and program only 804 * Wait for command done. This applies to erase and program only
799 * Erase can take up to 400ms and program up to 20ms according to 805 * Erase can take up to 400ms and program up to 20ms according to
800 * general NAND and SmartMedia specs 806 * general NAND and SmartMedia specs
801 * 807 *
802*/ 808*/
@@ -805,7 +811,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
805 811
806 unsigned long timeo = jiffies; 812 unsigned long timeo = jiffies;
807 int status; 813 int status;
808 814
809 if (state == FL_ERASING) 815 if (state == FL_ERASING)
810 timeo += (HZ * 400) / 1000; 816 timeo += (HZ * 400) / 1000;
811 else 817 else
@@ -817,17 +823,17 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
817 823
818 if ((state == FL_ERASING) && (this->options & NAND_IS_AND)) 824 if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
819 this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1); 825 this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1);
820 else 826 else
821 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); 827 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
822 828
823 while (time_before(jiffies, timeo)) { 829 while (time_before(jiffies, timeo)) {
824 /* Check, if we were interrupted */ 830 /* Check, if we were interrupted */
825 if (this->state != state) 831 if (this->state != state)
826 return 0; 832 return 0;
827 833
828 if (this->dev_ready) { 834 if (this->dev_ready) {
829 if (this->dev_ready(mtd)) 835 if (this->dev_ready(mtd))
830 break; 836 break;
831 } else { 837 } else {
832 if (this->read_byte(mtd) & NAND_STATUS_READY) 838 if (this->read_byte(mtd) & NAND_STATUS_READY)
833 break; 839 break;
@@ -853,7 +859,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
853 * 859 *
854 * Cached programming is not supported yet. 860 * Cached programming is not supported yet.
855 */ 861 */
856static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, 862static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page,
857 u_char *oob_buf, struct nand_oobinfo *oobsel, int cached) 863 u_char *oob_buf, struct nand_oobinfo *oobsel, int cached)
858{ 864{
859 int i, status; 865 int i, status;
@@ -862,10 +868,10 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
862 int *oob_config = oobsel->eccpos; 868 int *oob_config = oobsel->eccpos;
863 int datidx = 0, eccidx = 0, eccsteps = this->eccsteps; 869 int datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
864 int eccbytes = 0; 870 int eccbytes = 0;
865 871
866 /* FIXME: Enable cached programming */ 872 /* FIXME: Enable cached programming */
867 cached = 0; 873 cached = 0;
868 874
869 /* Send command to begin auto page programming */ 875 /* Send command to begin auto page programming */
870 this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page); 876 this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
871 877
@@ -876,7 +882,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
876 printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n"); 882 printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n");
877 this->write_buf(mtd, this->data_poi, mtd->oobblock); 883 this->write_buf(mtd, this->data_poi, mtd->oobblock);
878 break; 884 break;
879 885
880 /* Software ecc 3/256, write all */ 886 /* Software ecc 3/256, write all */
881 case NAND_ECC_SOFT: 887 case NAND_ECC_SOFT:
882 for (; eccsteps; eccsteps--) { 888 for (; eccsteps; eccsteps--) {
@@ -905,11 +911,11 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
905 } 911 }
906 break; 912 break;
907 } 913 }
908 914
909 /* Write out OOB data */ 915 /* Write out OOB data */
910 if (this->options & NAND_HWECC_SYNDROME) 916 if (this->options & NAND_HWECC_SYNDROME)
911 this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes); 917 this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes);
912 else 918 else
913 this->write_buf(mtd, oob_buf, mtd->oobsize); 919 this->write_buf(mtd, oob_buf, mtd->oobsize);
914 920
915 /* Send command to actually program the data */ 921 /* Send command to actually program the data */
@@ -934,7 +940,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
934 /* wait until cache is ready*/ 940 /* wait until cache is ready*/
935 // status = this->waitfunc (mtd, this, FL_CACHEDRPG); 941 // status = this->waitfunc (mtd, this, FL_CACHEDRPG);
936 } 942 }
937 return 0; 943 return 0;
938} 944}
939 945
940#ifdef CONFIG_MTD_NAND_VERIFY_WRITE 946#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
@@ -950,19 +956,19 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
950 * @oobmode: 1 = full buffer verify, 0 = ecc only 956 * @oobmode: 1 = full buffer verify, 0 = ecc only
951 * 957 *
952 * The NAND device assumes that it is always writing to a cleanly erased page. 958 * The NAND device assumes that it is always writing to a cleanly erased page.
953 * Hence, it performs its internal write verification only on bits that 959 * Hence, it performs its internal write verification only on bits that
954 * transitioned from 1 to 0. The device does NOT verify the whole page on a 960 * transitioned from 1 to 0. The device does NOT verify the whole page on a
955 * byte by byte basis. It is possible that the page was not completely erased 961 * byte by byte basis. It is possible that the page was not completely erased
956 * or the page is becoming unusable due to wear. The read with ECC would catch 962 * or the page is becoming unusable due to wear. The read with ECC would catch
957 * the error later when the ECC page check fails, but we would rather catch 963 * the error later when the ECC page check fails, but we would rather catch
958 * it early in the page write stage. Better to write no data than invalid data. 964 * it early in the page write stage. Better to write no data than invalid data.
959 */ 965 */
960static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, 966static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
961 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode) 967 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode)
962{ 968{
963 int i, j, datidx = 0, oobofs = 0, res = -EIO; 969 int i, j, datidx = 0, oobofs = 0, res = -EIO;
964 int eccsteps = this->eccsteps; 970 int eccsteps = this->eccsteps;
965 int hweccbytes; 971 int hweccbytes;
966 u_char oobdata[64]; 972 u_char oobdata[64];
967 973
968 hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0; 974 hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0;
@@ -1002,7 +1008,7 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
1002 1008
1003 if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) { 1009 if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) {
1004 int ecccnt = oobsel->eccbytes; 1010 int ecccnt = oobsel->eccbytes;
1005 1011
1006 for (i = 0; i < ecccnt; i++) { 1012 for (i = 0; i < ecccnt; i++) {
1007 int idx = oobsel->eccpos[i]; 1013 int idx = oobsel->eccpos[i];
1008 if (oobdata[idx] != oob_buf[oobofs + idx] ) { 1014 if (oobdata[idx] != oob_buf[oobofs + idx] ) {
@@ -1012,20 +1018,20 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
1012 goto out; 1018 goto out;
1013 } 1019 }
1014 } 1020 }
1015 } 1021 }
1016 } 1022 }
1017 oobofs += mtd->oobsize - hweccbytes * eccsteps; 1023 oobofs += mtd->oobsize - hweccbytes * eccsteps;
1018 page++; 1024 page++;
1019 numpages--; 1025 numpages--;
1020 1026
1021 /* Apply delay or wait for ready/busy pin 1027 /* Apply delay or wait for ready/busy pin
1022 * Do this before the AUTOINCR check, so no problems 1028 * Do this before the AUTOINCR check, so no problems
1023 * arise if a chip which does auto increment 1029 * arise if a chip which does auto increment
1024 * is marked as NOAUTOINCR by the board driver. 1030 * is marked as NOAUTOINCR by the board driver.
1025 * Do this also before returning, so the chip is 1031 * Do this also before returning, so the chip is
1026 * ready for the next command. 1032 * ready for the next command.
1027 */ 1033 */
1028 if (!this->dev_ready) 1034 if (!this->dev_ready)
1029 udelay (this->chip_delay); 1035 udelay (this->chip_delay);
1030 else 1036 else
1031 nand_wait_ready(mtd); 1037 nand_wait_ready(mtd);
@@ -1033,17 +1039,17 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
1033 /* All done, return happy */ 1039 /* All done, return happy */
1034 if (!numpages) 1040 if (!numpages)
1035 return 0; 1041 return 0;
1036 1042
1037 1043
1038 /* Check, if the chip supports auto page increment */ 1044 /* Check, if the chip supports auto page increment */
1039 if (!NAND_CANAUTOINCR(this)) 1045 if (!NAND_CANAUTOINCR(this))
1040 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); 1046 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
1041 } 1047 }
1042 /* 1048 /*
1043 * Terminate the read command. We come here in case of an error 1049 * Terminate the read command. We come here in case of an error
1044 * So we must issue a reset command. 1050 * So we must issue a reset command.
1045 */ 1051 */
1046out: 1052out:
1047 this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1); 1053 this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1);
1048 return res; 1054 return res;
1049} 1055}
@@ -1105,7 +1111,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1105 * NAND read with ECC 1111 * NAND read with ECC
1106 */ 1112 */
1107int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, 1113int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1108 size_t * retlen, u_char * buf, u_char * oob_buf, 1114 size_t * retlen, u_char * buf, u_char * oob_buf,
1109 struct nand_oobinfo *oobsel, int flags) 1115 struct nand_oobinfo *oobsel, int flags)
1110{ 1116{
1111 1117
@@ -1139,7 +1145,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1139 /* Autoplace of oob data ? Use the default placement scheme */ 1145 /* Autoplace of oob data ? Use the default placement scheme */
1140 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) 1146 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
1141 oobsel = this->autooob; 1147 oobsel = this->autooob;
1142 1148
1143 eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; 1149 eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
1144 oob_config = oobsel->eccpos; 1150 oob_config = oobsel->eccpos;
1145 1151
@@ -1157,28 +1163,28 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1157 end = mtd->oobblock; 1163 end = mtd->oobblock;
1158 ecc = this->eccsize; 1164 ecc = this->eccsize;
1159 eccbytes = this->eccbytes; 1165 eccbytes = this->eccbytes;
1160 1166
1161 if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME)) 1167 if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
1162 compareecc = 0; 1168 compareecc = 0;
1163 1169
1164 oobreadlen = mtd->oobsize; 1170 oobreadlen = mtd->oobsize;
1165 if (this->options & NAND_HWECC_SYNDROME) 1171 if (this->options & NAND_HWECC_SYNDROME)
1166 oobreadlen -= oobsel->eccbytes; 1172 oobreadlen -= oobsel->eccbytes;
1167 1173
1168 /* Loop until all data read */ 1174 /* Loop until all data read */
1169 while (read < len) { 1175 while (read < len) {
1170 1176
1171 int aligned = (!col && (len - read) >= end); 1177 int aligned = (!col && (len - read) >= end);
1172 /* 1178 /*
1173 * If the read is not page aligned, we have to read into data buffer 1179 * If the read is not page aligned, we have to read into data buffer
1174 * due to ecc, else we read into return buffer direct 1180 * due to ecc, else we read into return buffer direct
1175 */ 1181 */
1176 if (aligned) 1182 if (aligned)
1177 data_poi = &buf[read]; 1183 data_poi = &buf[read];
1178 else 1184 else
1179 data_poi = this->data_buf; 1185 data_poi = this->data_buf;
1180 1186
1181 /* Check, if we have this page in the buffer 1187 /* Check, if we have this page in the buffer
1182 * 1188 *
1183 * FIXME: Make it work when we must provide oob data too, 1189 * FIXME: Make it work when we must provide oob data too,
1184 * check the usage of data_buf oob field 1190 * check the usage of data_buf oob field
@@ -1194,7 +1200,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1194 if (sndcmd) { 1200 if (sndcmd) {
1195 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); 1201 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
1196 sndcmd = 0; 1202 sndcmd = 0;
1197 } 1203 }
1198 1204
1199 /* get oob area, if we have no oob buffer from fs-driver */ 1205 /* get oob area, if we have no oob buffer from fs-driver */
1200 if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE || 1206 if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE ||
@@ -1202,7 +1208,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1202 oob_data = &this->data_buf[end]; 1208 oob_data = &this->data_buf[end];
1203 1209
1204 eccsteps = this->eccsteps; 1210 eccsteps = this->eccsteps;
1205 1211
1206 switch (eccmode) { 1212 switch (eccmode) {
1207 case NAND_ECC_NONE: { /* No ECC, Read in a page */ 1213 case NAND_ECC_NONE: { /* No ECC, Read in a page */
1208 static unsigned long lastwhinge = 0; 1214 static unsigned long lastwhinge = 0;
@@ -1213,12 +1219,12 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1213 this->read_buf(mtd, data_poi, end); 1219 this->read_buf(mtd, data_poi, end);
1214 break; 1220 break;
1215 } 1221 }
1216 1222
1217 case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */ 1223 case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */
1218 this->read_buf(mtd, data_poi, end); 1224 this->read_buf(mtd, data_poi, end);
1219 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) 1225 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc)
1220 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); 1226 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
1221 break; 1227 break;
1222 1228
1223 default: 1229 default:
1224 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) { 1230 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
@@ -1237,15 +1243,15 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1237 * does the error correction on the fly */ 1243 * does the error correction on the fly */
1238 ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]); 1244 ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]);
1239 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) { 1245 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
1240 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " 1246 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
1241 "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr); 1247 "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
1242 ecc_failed++; 1248 ecc_failed++;
1243 } 1249 }
1244 } else { 1250 } else {
1245 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); 1251 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
1246 } 1252 }
1247 } 1253 }
1248 break; 1254 break;
1249 } 1255 }
1250 1256
1251 /* read oobdata */ 1257 /* read oobdata */
@@ -1253,8 +1259,8 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1253 1259
1254 /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */ 1260 /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */
1255 if (!compareecc) 1261 if (!compareecc)
1256 goto readoob; 1262 goto readoob;
1257 1263
1258 /* Pick the ECC bytes out of the oob data */ 1264 /* Pick the ECC bytes out of the oob data */
1259 for (j = 0; j < oobsel->eccbytes; j++) 1265 for (j = 0; j < oobsel->eccbytes; j++)
1260 ecc_code[j] = oob_data[oob_config[j]]; 1266 ecc_code[j] = oob_data[oob_config[j]];
@@ -1262,24 +1268,24 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1262 /* correct data, if neccecary */ 1268 /* correct data, if neccecary */
1263 for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) { 1269 for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) {
1264 ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]); 1270 ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]);
1265 1271
1266 /* Get next chunk of ecc bytes */ 1272 /* Get next chunk of ecc bytes */
1267 j += eccbytes; 1273 j += eccbytes;
1268 1274
1269 /* Check, if we have a fs supplied oob-buffer, 1275 /* Check, if we have a fs supplied oob-buffer,
1270 * This is the legacy mode. Used by YAFFS1 1276 * This is the legacy mode. Used by YAFFS1
1271 * Should go away some day 1277 * Should go away some day
1272 */ 1278 */
1273 if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) { 1279 if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) {
1274 int *p = (int *)(&oob_data[mtd->oobsize]); 1280 int *p = (int *)(&oob_data[mtd->oobsize]);
1275 p[i] = ecc_status; 1281 p[i] = ecc_status;
1276 } 1282 }
1277 1283
1278 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) { 1284 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
1279 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page); 1285 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
1280 ecc_failed++; 1286 ecc_failed++;
1281 } 1287 }
1282 } 1288 }
1283 1289
1284 readoob: 1290 readoob:
1285 /* check, if we have a fs supplied oob-buffer */ 1291 /* check, if we have a fs supplied oob-buffer */
@@ -1305,25 +1311,25 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1305 } 1311 }
1306 readdata: 1312 readdata:
1307 /* Partial page read, transfer data into fs buffer */ 1313 /* Partial page read, transfer data into fs buffer */
1308 if (!aligned) { 1314 if (!aligned) {
1309 for (j = col; j < end && read < len; j++) 1315 for (j = col; j < end && read < len; j++)
1310 buf[read++] = data_poi[j]; 1316 buf[read++] = data_poi[j];
1311 this->pagebuf = realpage; 1317 this->pagebuf = realpage;
1312 } else 1318 } else
1313 read += mtd->oobblock; 1319 read += mtd->oobblock;
1314 1320
1315 /* Apply delay or wait for ready/busy pin 1321 /* Apply delay or wait for ready/busy pin
1316 * Do this before the AUTOINCR check, so no problems 1322 * Do this before the AUTOINCR check, so no problems
1317 * arise if a chip which does auto increment 1323 * arise if a chip which does auto increment
1318 * is marked as NOAUTOINCR by the board driver. 1324 * is marked as NOAUTOINCR by the board driver.
1319 */ 1325 */
1320 if (!this->dev_ready) 1326 if (!this->dev_ready)
1321 udelay (this->chip_delay); 1327 udelay (this->chip_delay);
1322 else 1328 else
1323 nand_wait_ready(mtd); 1329 nand_wait_ready(mtd);
1324 1330
1325 if (read == len) 1331 if (read == len)
1326 break; 1332 break;
1327 1333
1328 /* For subsequent reads align to page boundary. */ 1334 /* For subsequent reads align to page boundary. */
1329 col = 0; 1335 col = 0;
@@ -1337,11 +1343,11 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1337 this->select_chip(mtd, -1); 1343 this->select_chip(mtd, -1);
1338 this->select_chip(mtd, chipnr); 1344 this->select_chip(mtd, chipnr);
1339 } 1345 }
1340 /* Check, if the chip supports auto page increment 1346 /* Check, if the chip supports auto page increment
1341 * or if we have hit a block boundary. 1347 * or if we have hit a block boundary.
1342 */ 1348 */
1343 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) 1349 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
1344 sndcmd = 1; 1350 sndcmd = 1;
1345 } 1351 }
1346 1352
1347 /* Deselect and wake up anyone waiting on the device */ 1353 /* Deselect and wake up anyone waiting on the device */
@@ -1378,7 +1384,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
1378 /* Shift to get page */ 1384 /* Shift to get page */
1379 page = (int)(from >> this->page_shift); 1385 page = (int)(from >> this->page_shift);
1380 chipnr = (int)(from >> this->chip_shift); 1386 chipnr = (int)(from >> this->chip_shift);
1381 1387
1382 /* Mask to get column */ 1388 /* Mask to get column */
1383 col = from & (mtd->oobsize - 1); 1389 col = from & (mtd->oobsize - 1);
1384 1390
@@ -1400,7 +1406,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
1400 1406
1401 /* Send the read command */ 1407 /* Send the read command */
1402 this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask); 1408 this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask);
1403 /* 1409 /*
1404 * Read the data, if we read more than one page 1410 * Read the data, if we read more than one page
1405 * oob data, let the device transfer the data ! 1411 * oob data, let the device transfer the data !
1406 */ 1412 */
@@ -1422,20 +1428,20 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
1422 this->select_chip(mtd, -1); 1428 this->select_chip(mtd, -1);
1423 this->select_chip(mtd, chipnr); 1429 this->select_chip(mtd, chipnr);
1424 } 1430 }
1425 1431
1426 /* Apply delay or wait for ready/busy pin 1432 /* Apply delay or wait for ready/busy pin
1427 * Do this before the AUTOINCR check, so no problems 1433 * Do this before the AUTOINCR check, so no problems
1428 * arise if a chip which does auto increment 1434 * arise if a chip which does auto increment
1429 * is marked as NOAUTOINCR by the board driver. 1435 * is marked as NOAUTOINCR by the board driver.
1430 */ 1436 */
1431 if (!this->dev_ready) 1437 if (!this->dev_ready)
1432 udelay (this->chip_delay); 1438 udelay (this->chip_delay);
1433 else 1439 else
1434 nand_wait_ready(mtd); 1440 nand_wait_ready(mtd);
1435 1441
1436 /* Check, if the chip supports auto page increment 1442 /* Check, if the chip supports auto page increment
1437 * or if we have hit a block boundary. 1443 * or if we have hit a block boundary.
1438 */ 1444 */
1439 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) { 1445 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) {
1440 /* For subsequent page reads set offset to 0 */ 1446 /* For subsequent page reads set offset to 0 */
1441 this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask); 1447 this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
@@ -1481,27 +1487,27 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len,
1481 nand_get_device (this, mtd , FL_READING); 1487 nand_get_device (this, mtd , FL_READING);
1482 1488
1483 this->select_chip (mtd, chip); 1489 this->select_chip (mtd, chip);
1484 1490
1485 /* Add requested oob length */ 1491 /* Add requested oob length */
1486 len += ooblen; 1492 len += ooblen;
1487 1493
1488 while (len) { 1494 while (len) {
1489 if (sndcmd) 1495 if (sndcmd)
1490 this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask); 1496 this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask);
1491 sndcmd = 0; 1497 sndcmd = 0;
1492 1498
1493 this->read_buf (mtd, &buf[cnt], pagesize); 1499 this->read_buf (mtd, &buf[cnt], pagesize);
1494 1500
1495 len -= pagesize; 1501 len -= pagesize;
1496 cnt += pagesize; 1502 cnt += pagesize;
1497 page++; 1503 page++;
1498 1504
1499 if (!this->dev_ready) 1505 if (!this->dev_ready)
1500 udelay (this->chip_delay); 1506 udelay (this->chip_delay);
1501 else 1507 else
1502 nand_wait_ready(mtd); 1508 nand_wait_ready(mtd);
1503 1509
1504 /* Check, if the chip supports auto page increment */ 1510 /* Check, if the chip supports auto page increment */
1505 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) 1511 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
1506 sndcmd = 1; 1512 sndcmd = 1;
1507 } 1513 }
@@ -1512,8 +1518,8 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len,
1512} 1518}
1513 1519
1514 1520
1515/** 1521/**
1516 * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer 1522 * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer
1517 * @mtd: MTD device structure 1523 * @mtd: MTD device structure
1518 * @fsbuf: buffer given by fs driver 1524 * @fsbuf: buffer given by fs driver
1519 * @oobsel: out of band selection structre 1525 * @oobsel: out of band selection structre
@@ -1542,20 +1548,20 @@ static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct
1542 int i, len, ofs; 1548 int i, len, ofs;
1543 1549
1544 /* Zero copy fs supplied buffer */ 1550 /* Zero copy fs supplied buffer */
1545 if (fsbuf && !autoplace) 1551 if (fsbuf && !autoplace)
1546 return fsbuf; 1552 return fsbuf;
1547 1553
1548 /* Check, if the buffer must be filled with ff again */ 1554 /* Check, if the buffer must be filled with ff again */
1549 if (this->oobdirty) { 1555 if (this->oobdirty) {
1550 memset (this->oob_buf, 0xff, 1556 memset (this->oob_buf, 0xff,
1551 mtd->oobsize << (this->phys_erase_shift - this->page_shift)); 1557 mtd->oobsize << (this->phys_erase_shift - this->page_shift));
1552 this->oobdirty = 0; 1558 this->oobdirty = 0;
1553 } 1559 }
1554 1560
1555 /* If we have no autoplacement or no fs buffer use the internal one */ 1561 /* If we have no autoplacement or no fs buffer use the internal one */
1556 if (!autoplace || !fsbuf) 1562 if (!autoplace || !fsbuf)
1557 return this->oob_buf; 1563 return this->oob_buf;
1558 1564
1559 /* Walk through the pages and place the data */ 1565 /* Walk through the pages and place the data */
1560 this->oobdirty = 1; 1566 this->oobdirty = 1;
1561 ofs = 0; 1567 ofs = 0;
@@ -1589,7 +1595,7 @@ static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * ret
1589{ 1595{
1590 return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL)); 1596 return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL));
1591} 1597}
1592 1598
1593/** 1599/**
1594 * nand_write_ecc - [MTD Interface] NAND write with ECC 1600 * nand_write_ecc - [MTD Interface] NAND write with ECC
1595 * @mtd: MTD device structure 1601 * @mtd: MTD device structure
@@ -1622,7 +1628,7 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1622 return -EINVAL; 1628 return -EINVAL;
1623 } 1629 }
1624 1630
1625 /* reject writes, which are not page aligned */ 1631 /* reject writes, which are not page aligned */
1626 if (NOTALIGNED (to) || NOTALIGNED(len)) { 1632 if (NOTALIGNED (to) || NOTALIGNED(len)) {
1627 printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); 1633 printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
1628 return -EINVAL; 1634 return -EINVAL;
@@ -1641,14 +1647,14 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1641 goto out; 1647 goto out;
1642 1648
1643 /* if oobsel is NULL, use chip defaults */ 1649 /* if oobsel is NULL, use chip defaults */
1644 if (oobsel == NULL) 1650 if (oobsel == NULL)
1645 oobsel = &mtd->oobinfo; 1651 oobsel = &mtd->oobinfo;
1646 1652
1647 /* Autoplace of oob data ? Use the default placement scheme */ 1653 /* Autoplace of oob data ? Use the default placement scheme */
1648 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { 1654 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
1649 oobsel = this->autooob; 1655 oobsel = this->autooob;
1650 autoplace = 1; 1656 autoplace = 1;
1651 } 1657 }
1652 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) 1658 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
1653 autoplace = 1; 1659 autoplace = 1;
1654 1660
@@ -1656,9 +1662,9 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1656 totalpages = len >> this->page_shift; 1662 totalpages = len >> this->page_shift;
1657 page = (int) (to >> this->page_shift); 1663 page = (int) (to >> this->page_shift);
1658 /* Invalidate the page cache, if we write to the cached page */ 1664 /* Invalidate the page cache, if we write to the cached page */
1659 if (page <= this->pagebuf && this->pagebuf < (page + totalpages)) 1665 if (page <= this->pagebuf && this->pagebuf < (page + totalpages))
1660 this->pagebuf = -1; 1666 this->pagebuf = -1;
1661 1667
1662 /* Set it relative to chip */ 1668 /* Set it relative to chip */
1663 page &= this->pagemask; 1669 page &= this->pagemask;
1664 startpage = page; 1670 startpage = page;
@@ -1680,14 +1686,14 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1680 if (ret) { 1686 if (ret) {
1681 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret); 1687 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret);
1682 goto out; 1688 goto out;
1683 } 1689 }
1684 /* Next oob page */ 1690 /* Next oob page */
1685 oob += mtd->oobsize; 1691 oob += mtd->oobsize;
1686 /* Update written bytes count */ 1692 /* Update written bytes count */
1687 written += mtd->oobblock; 1693 written += mtd->oobblock;
1688 if (written == len) 1694 if (written == len)
1689 goto cmp; 1695 goto cmp;
1690 1696
1691 /* Increment page address */ 1697 /* Increment page address */
1692 page++; 1698 page++;
1693 1699
@@ -1698,13 +1704,13 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1698 if (!(page & (ppblock - 1))){ 1704 if (!(page & (ppblock - 1))){
1699 int ofs; 1705 int ofs;
1700 this->data_poi = bufstart; 1706 this->data_poi = bufstart;
1701 ret = nand_verify_pages (mtd, this, startpage, 1707 ret = nand_verify_pages (mtd, this, startpage,
1702 page - startpage, 1708 page - startpage,
1703 oobbuf, oobsel, chipnr, (eccbuf != NULL)); 1709 oobbuf, oobsel, chipnr, (eccbuf != NULL));
1704 if (ret) { 1710 if (ret) {
1705 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); 1711 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
1706 goto out; 1712 goto out;
1707 } 1713 }
1708 *retlen = written; 1714 *retlen = written;
1709 1715
1710 ofs = autoplace ? mtd->oobavail : mtd->oobsize; 1716 ofs = autoplace ? mtd->oobavail : mtd->oobsize;
@@ -1714,8 +1720,9 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1714 numpages = min (totalpages, ppblock); 1720 numpages = min (totalpages, ppblock);
1715 page &= this->pagemask; 1721 page &= this->pagemask;
1716 startpage = page; 1722 startpage = page;
1717 oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, 1723 oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel,
1718 autoplace, numpages); 1724 autoplace, numpages);
1725 oob = 0;
1719 /* Check, if we cross a chip boundary */ 1726 /* Check, if we cross a chip boundary */
1720 if (!page) { 1727 if (!page) {
1721 chipnr++; 1728 chipnr++;
@@ -1731,7 +1738,7 @@ cmp:
1731 oobbuf, oobsel, chipnr, (eccbuf != NULL)); 1738 oobbuf, oobsel, chipnr, (eccbuf != NULL));
1732 if (!ret) 1739 if (!ret)
1733 *retlen = written; 1740 *retlen = written;
1734 else 1741 else
1735 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); 1742 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
1736 1743
1737out: 1744out:
@@ -1791,7 +1798,7 @@ static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t *
1791 /* Check, if it is write protected */ 1798 /* Check, if it is write protected */
1792 if (nand_check_wp(mtd)) 1799 if (nand_check_wp(mtd))
1793 goto out; 1800 goto out;
1794 1801
1795 /* Invalidate the page cache, if we write to the cached page */ 1802 /* Invalidate the page cache, if we write to the cached page */
1796 if (page == this->pagebuf) 1803 if (page == this->pagebuf)
1797 this->pagebuf = -1; 1804 this->pagebuf = -1;
@@ -1854,10 +1861,10 @@ out:
1854 * 1861 *
1855 * NAND write with kvec. This just calls the ecc function 1862 * NAND write with kvec. This just calls the ecc function
1856 */ 1863 */
1857static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, 1864static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
1858 loff_t to, size_t * retlen) 1865 loff_t to, size_t * retlen)
1859{ 1866{
1860 return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL)); 1867 return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL));
1861} 1868}
1862 1869
1863/** 1870/**
@@ -1872,7 +1879,7 @@ static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned
1872 * 1879 *
1873 * NAND write with iovec with ecc 1880 * NAND write with iovec with ecc
1874 */ 1881 */
1875static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, 1882static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
1876 loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) 1883 loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel)
1877{ 1884{
1878 int i, page, len, total_len, ret = -EIO, written = 0, chipnr; 1885 int i, page, len, total_len, ret = -EIO, written = 0, chipnr;
@@ -1898,7 +1905,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
1898 return -EINVAL; 1905 return -EINVAL;
1899 } 1906 }
1900 1907
1901 /* reject writes, which are not page aligned */ 1908 /* reject writes, which are not page aligned */
1902 if (NOTALIGNED (to) || NOTALIGNED(total_len)) { 1909 if (NOTALIGNED (to) || NOTALIGNED(total_len)) {
1903 printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); 1910 printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
1904 return -EINVAL; 1911 return -EINVAL;
@@ -1917,21 +1924,21 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
1917 goto out; 1924 goto out;
1918 1925
1919 /* if oobsel is NULL, use chip defaults */ 1926 /* if oobsel is NULL, use chip defaults */
1920 if (oobsel == NULL) 1927 if (oobsel == NULL)
1921 oobsel = &mtd->oobinfo; 1928 oobsel = &mtd->oobinfo;
1922 1929
1923 /* Autoplace of oob data ? Use the default placement scheme */ 1930 /* Autoplace of oob data ? Use the default placement scheme */
1924 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { 1931 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
1925 oobsel = this->autooob; 1932 oobsel = this->autooob;
1926 autoplace = 1; 1933 autoplace = 1;
1927 } 1934 }
1928 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) 1935 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
1929 autoplace = 1; 1936 autoplace = 1;
1930 1937
1931 /* Setup start page */ 1938 /* Setup start page */
1932 page = (int) (to >> this->page_shift); 1939 page = (int) (to >> this->page_shift);
1933 /* Invalidate the page cache, if we write to the cached page */ 1940 /* Invalidate the page cache, if we write to the cached page */
1934 if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift)) 1941 if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift))
1935 this->pagebuf = -1; 1942 this->pagebuf = -1;
1936 1943
1937 startpage = page & this->pagemask; 1944 startpage = page & this->pagemask;
@@ -1955,10 +1962,10 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
1955 oob = 0; 1962 oob = 0;
1956 for (i = 1; i <= numpages; i++) { 1963 for (i = 1; i <= numpages; i++) {
1957 /* Write one page. If this is the last page to write 1964 /* Write one page. If this is the last page to write
1958 * then use the real pageprogram command, else select 1965 * then use the real pageprogram command, else select
1959 * cached programming if supported by the chip. 1966 * cached programming if supported by the chip.
1960 */ 1967 */
1961 ret = nand_write_page (mtd, this, page & this->pagemask, 1968 ret = nand_write_page (mtd, this, page & this->pagemask,
1962 &oobbuf[oob], oobsel, i != numpages); 1969 &oobbuf[oob], oobsel, i != numpages);
1963 if (ret) 1970 if (ret)
1964 goto out; 1971 goto out;
@@ -1974,12 +1981,12 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
1974 count--; 1981 count--;
1975 } 1982 }
1976 } else { 1983 } else {
1977 /* We must use the internal buffer, read data out of each 1984 /* We must use the internal buffer, read data out of each
1978 * tuple until we have a full page to write 1985 * tuple until we have a full page to write
1979 */ 1986 */
1980 int cnt = 0; 1987 int cnt = 0;
1981 while (cnt < mtd->oobblock) { 1988 while (cnt < mtd->oobblock) {
1982 if (vecs->iov_base != NULL && vecs->iov_len) 1989 if (vecs->iov_base != NULL && vecs->iov_len)
1983 this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++]; 1990 this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++];
1984 /* Check, if we have to switch to the next tuple */ 1991 /* Check, if we have to switch to the next tuple */
1985 if (len >= (int) vecs->iov_len) { 1992 if (len >= (int) vecs->iov_len) {
@@ -1988,10 +1995,10 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
1988 count--; 1995 count--;
1989 } 1996 }
1990 } 1997 }
1991 this->pagebuf = page; 1998 this->pagebuf = page;
1992 this->data_poi = this->data_buf; 1999 this->data_poi = this->data_buf;
1993 bufstart = this->data_poi; 2000 bufstart = this->data_poi;
1994 numpages = 1; 2001 numpages = 1;
1995 oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages); 2002 oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
1996 ret = nand_write_page (mtd, this, page & this->pagemask, 2003 ret = nand_write_page (mtd, this, page & this->pagemask,
1997 oobbuf, oobsel, 0); 2004 oobbuf, oobsel, 0);
@@ -2004,7 +2011,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
2004 ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0); 2011 ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0);
2005 if (ret) 2012 if (ret)
2006 goto out; 2013 goto out;
2007 2014
2008 written += mtd->oobblock * numpages; 2015 written += mtd->oobblock * numpages;
2009 /* All done ? */ 2016 /* All done ? */
2010 if (!count) 2017 if (!count)
@@ -2072,7 +2079,7 @@ static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
2072{ 2079{
2073 return nand_erase_nand (mtd, instr, 0); 2080 return nand_erase_nand (mtd, instr, 0);
2074} 2081}
2075 2082
2076#define BBT_PAGE_MASK 0xffffff3f 2083#define BBT_PAGE_MASK 0xffffff3f
2077/** 2084/**
2078 * nand_erase_intern - [NAND Interface] erase block(s) 2085 * nand_erase_intern - [NAND Interface] erase block(s)
@@ -2154,14 +2161,14 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
2154 instr->state = MTD_ERASE_FAILED; 2161 instr->state = MTD_ERASE_FAILED;
2155 goto erase_exit; 2162 goto erase_exit;
2156 } 2163 }
2157 2164
2158 /* Invalidate the page cache, if we erase the block which contains 2165 /* Invalidate the page cache, if we erase the block which contains
2159 the current cached page */ 2166 the current cached page */
2160 if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block)) 2167 if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block))
2161 this->pagebuf = -1; 2168 this->pagebuf = -1;
2162 2169
2163 this->erase_cmd (mtd, page & this->pagemask); 2170 this->erase_cmd (mtd, page & this->pagemask);
2164 2171
2165 status = this->waitfunc (mtd, this, FL_ERASING); 2172 status = this->waitfunc (mtd, this, FL_ERASING);
2166 2173
2167 /* See if operation failed and additional status checks are available */ 2174 /* See if operation failed and additional status checks are available */
@@ -2179,12 +2186,12 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
2179 2186
2180 /* if BBT requires refresh, set the BBT rewrite flag to the page being erased */ 2187 /* if BBT requires refresh, set the BBT rewrite flag to the page being erased */
2181 if (this->options & BBT_AUTO_REFRESH) { 2188 if (this->options & BBT_AUTO_REFRESH) {
2182 if (((page & BBT_PAGE_MASK) == bbt_masked_page) && 2189 if (((page & BBT_PAGE_MASK) == bbt_masked_page) &&
2183 (page != this->bbt_td->pages[chipnr])) { 2190 (page != this->bbt_td->pages[chipnr])) {
2184 rewrite_bbt[chipnr] = (page << this->page_shift); 2191 rewrite_bbt[chipnr] = (page << this->page_shift);
2185 } 2192 }
2186 } 2193 }
2187 2194
2188 /* Increment page address and decrement length */ 2195 /* Increment page address and decrement length */
2189 len -= (1 << this->phys_erase_shift); 2196 len -= (1 << this->phys_erase_shift);
2190 page += pages_per_block; 2197 page += pages_per_block;
@@ -2195,7 +2202,7 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
2195 this->select_chip(mtd, -1); 2202 this->select_chip(mtd, -1);
2196 this->select_chip(mtd, chipnr); 2203 this->select_chip(mtd, chipnr);
2197 2204
2198 /* if BBT requires refresh and BBT-PERCHIP, 2205 /* if BBT requires refresh and BBT-PERCHIP,
2199 * set the BBT page mask to see if this BBT should be rewritten */ 2206 * set the BBT page mask to see if this BBT should be rewritten */
2200 if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) { 2207 if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) {
2201 bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK; 2208 bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
@@ -2220,7 +2227,7 @@ erase_exit:
2220 for (chipnr = 0; chipnr < this->numchips; chipnr++) { 2227 for (chipnr = 0; chipnr < this->numchips; chipnr++) {
2221 if (rewrite_bbt[chipnr]) { 2228 if (rewrite_bbt[chipnr]) {
2222 /* update the BBT for chip */ 2229 /* update the BBT for chip */
2223 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n", 2230 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n",
2224 chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]); 2231 chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]);
2225 nand_update_bbt (mtd, rewrite_bbt[chipnr]); 2232 nand_update_bbt (mtd, rewrite_bbt[chipnr]);
2226 } 2233 }
@@ -2258,9 +2265,9 @@ static void nand_sync (struct mtd_info *mtd)
2258static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs) 2265static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs)
2259{ 2266{
2260 /* Check for invalid offset */ 2267 /* Check for invalid offset */
2261 if (ofs > mtd->size) 2268 if (ofs > mtd->size)
2262 return -EINVAL; 2269 return -EINVAL;
2263 2270
2264 return nand_block_checkbad (mtd, ofs, 1, 0); 2271 return nand_block_checkbad (mtd, ofs, 1, 0);
2265} 2272}
2266 2273
@@ -2285,6 +2292,34 @@ static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs)
2285} 2292}
2286 2293
2287/** 2294/**
2295 * nand_suspend - [MTD Interface] Suspend the NAND flash
2296 * @mtd: MTD device structure
2297 */
2298static int nand_suspend(struct mtd_info *mtd)
2299{
2300 struct nand_chip *this = mtd->priv;
2301
2302 return nand_get_device (this, mtd, FL_PM_SUSPENDED);
2303}
2304
2305/**
2306 * nand_resume - [MTD Interface] Resume the NAND flash
2307 * @mtd: MTD device structure
2308 */
2309static void nand_resume(struct mtd_info *mtd)
2310{
2311 struct nand_chip *this = mtd->priv;
2312
2313 if (this->state == FL_PM_SUSPENDED)
2314 nand_release_device(mtd);
2315 else
2316 printk(KERN_ERR "resume() called for the chip which is not "
2317 "in suspended state\n");
2318
2319}
2320
2321
2322/**
2288 * nand_scan - [NAND Interface] Scan for the NAND device 2323 * nand_scan - [NAND Interface] Scan for the NAND device
2289 * @mtd: MTD device structure 2324 * @mtd: MTD device structure
2290 * @maxchips: Number of chips to scan for 2325 * @maxchips: Number of chips to scan for
@@ -2351,13 +2386,13 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2351 2386
2352 /* Print and store flash device information */ 2387 /* Print and store flash device information */
2353 for (i = 0; nand_flash_ids[i].name != NULL; i++) { 2388 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
2354 2389
2355 if (nand_dev_id != nand_flash_ids[i].id) 2390 if (nand_dev_id != nand_flash_ids[i].id)
2356 continue; 2391 continue;
2357 2392
2358 if (!mtd->name) mtd->name = nand_flash_ids[i].name; 2393 if (!mtd->name) mtd->name = nand_flash_ids[i].name;
2359 this->chipsize = nand_flash_ids[i].chipsize << 20; 2394 this->chipsize = nand_flash_ids[i].chipsize << 20;
2360 2395
2361 /* New devices have all the information in additional id bytes */ 2396 /* New devices have all the information in additional id bytes */
2362 if (!nand_flash_ids[i].pagesize) { 2397 if (!nand_flash_ids[i].pagesize) {
2363 int extid; 2398 int extid;
@@ -2369,14 +2404,14 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2369 mtd->oobblock = 1024 << (extid & 0x3); 2404 mtd->oobblock = 1024 << (extid & 0x3);
2370 extid >>= 2; 2405 extid >>= 2;
2371 /* Calc oobsize */ 2406 /* Calc oobsize */
2372 mtd->oobsize = (8 << (extid & 0x03)) * (mtd->oobblock / 512); 2407 mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock >> 9);
2373 extid >>= 2; 2408 extid >>= 2;
2374 /* Calc blocksize. Blocksize is multiples of 64KiB */ 2409 /* Calc blocksize. Blocksize is multiples of 64KiB */
2375 mtd->erasesize = (64 * 1024) << (extid & 0x03); 2410 mtd->erasesize = (64 * 1024) << (extid & 0x03);
2376 extid >>= 2; 2411 extid >>= 2;
2377 /* Get buswidth information */ 2412 /* Get buswidth information */
2378 busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; 2413 busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
2379 2414
2380 } else { 2415 } else {
2381 /* Old devices have this data hardcoded in the 2416 /* Old devices have this data hardcoded in the
2382 * device id table */ 2417 * device id table */
@@ -2396,23 +2431,23 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2396 * this correct ! */ 2431 * this correct ! */
2397 if (busw != (this->options & NAND_BUSWIDTH_16)) { 2432 if (busw != (this->options & NAND_BUSWIDTH_16)) {
2398 printk (KERN_INFO "NAND device: Manufacturer ID:" 2433 printk (KERN_INFO "NAND device: Manufacturer ID:"
2399 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, 2434 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
2400 nand_manuf_ids[maf_id].name , mtd->name); 2435 nand_manuf_ids[maf_id].name , mtd->name);
2401 printk (KERN_WARNING 2436 printk (KERN_WARNING
2402 "NAND bus width %d instead %d bit\n", 2437 "NAND bus width %d instead %d bit\n",
2403 (this->options & NAND_BUSWIDTH_16) ? 16 : 8, 2438 (this->options & NAND_BUSWIDTH_16) ? 16 : 8,
2404 busw ? 16 : 8); 2439 busw ? 16 : 8);
2405 this->select_chip(mtd, -1); 2440 this->select_chip(mtd, -1);
2406 return 1; 2441 return 1;
2407 } 2442 }
2408 2443
2409 /* Calculate the address shift from the page size */ 2444 /* Calculate the address shift from the page size */
2410 this->page_shift = ffs(mtd->oobblock) - 1; 2445 this->page_shift = ffs(mtd->oobblock) - 1;
2411 this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1; 2446 this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1;
2412 this->chip_shift = ffs(this->chipsize) - 1; 2447 this->chip_shift = ffs(this->chipsize) - 1;
2413 2448
2414 /* Set the bad block position */ 2449 /* Set the bad block position */
2415 this->badblockpos = mtd->oobblock > 512 ? 2450 this->badblockpos = mtd->oobblock > 512 ?
2416 NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS; 2451 NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
2417 2452
2418 /* Get chip options, preserve non chip based options */ 2453 /* Get chip options, preserve non chip based options */
@@ -2422,10 +2457,10 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2422 this->options |= NAND_NO_AUTOINCR; 2457 this->options |= NAND_NO_AUTOINCR;
2423 /* Check if this is a not a samsung device. Do not clear the options 2458 /* Check if this is a not a samsung device. Do not clear the options
2424 * for chips which are not having an extended id. 2459 * for chips which are not having an extended id.
2425 */ 2460 */
2426 if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize) 2461 if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize)
2427 this->options &= ~NAND_SAMSUNG_LP_OPTIONS; 2462 this->options &= ~NAND_SAMSUNG_LP_OPTIONS;
2428 2463
2429 /* Check for AND chips with 4 page planes */ 2464 /* Check for AND chips with 4 page planes */
2430 if (this->options & NAND_4PAGE_ARRAY) 2465 if (this->options & NAND_4PAGE_ARRAY)
2431 this->erase_cmd = multi_erase_cmd; 2466 this->erase_cmd = multi_erase_cmd;
@@ -2435,9 +2470,9 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2435 /* Do not replace user supplied command function ! */ 2470 /* Do not replace user supplied command function ! */
2436 if (mtd->oobblock > 512 && this->cmdfunc == nand_command) 2471 if (mtd->oobblock > 512 && this->cmdfunc == nand_command)
2437 this->cmdfunc = nand_command_lp; 2472 this->cmdfunc = nand_command_lp;
2438 2473
2439 printk (KERN_INFO "NAND device: Manufacturer ID:" 2474 printk (KERN_INFO "NAND device: Manufacturer ID:"
2440 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, 2475 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
2441 nand_manuf_ids[maf_id].name , nand_flash_ids[i].name); 2476 nand_manuf_ids[maf_id].name , nand_flash_ids[i].name);
2442 break; 2477 break;
2443 } 2478 }
@@ -2461,7 +2496,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2461 } 2496 }
2462 if (i > 1) 2497 if (i > 1)
2463 printk(KERN_INFO "%d NAND chips detected\n", i); 2498 printk(KERN_INFO "%d NAND chips detected\n", i);
2464 2499
2465 /* Allocate buffers, if neccecary */ 2500 /* Allocate buffers, if neccecary */
2466 if (!this->oob_buf) { 2501 if (!this->oob_buf) {
2467 size_t len; 2502 size_t len;
@@ -2473,7 +2508,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2473 } 2508 }
2474 this->options |= NAND_OOBBUF_ALLOC; 2509 this->options |= NAND_OOBBUF_ALLOC;
2475 } 2510 }
2476 2511
2477 if (!this->data_buf) { 2512 if (!this->data_buf) {
2478 size_t len; 2513 size_t len;
2479 len = mtd->oobblock + mtd->oobsize; 2514 len = mtd->oobblock + mtd->oobsize;
@@ -2500,7 +2535,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2500 if (!this->autooob) { 2535 if (!this->autooob) {
2501 /* Select the appropriate default oob placement scheme for 2536 /* Select the appropriate default oob placement scheme for
2502 * placement agnostic filesystems */ 2537 * placement agnostic filesystems */
2503 switch (mtd->oobsize) { 2538 switch (mtd->oobsize) {
2504 case 8: 2539 case 8:
2505 this->autooob = &nand_oob_8; 2540 this->autooob = &nand_oob_8;
2506 break; 2541 break;
@@ -2516,19 +2551,19 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2516 BUG(); 2551 BUG();
2517 } 2552 }
2518 } 2553 }
2519 2554
2520 /* The number of bytes available for the filesystem to place fs dependend 2555 /* The number of bytes available for the filesystem to place fs dependend
2521 * oob data */ 2556 * oob data */
2522 mtd->oobavail = 0; 2557 mtd->oobavail = 0;
2523 for (i = 0; this->autooob->oobfree[i][1]; i++) 2558 for (i = 0; this->autooob->oobfree[i][1]; i++)
2524 mtd->oobavail += this->autooob->oobfree[i][1]; 2559 mtd->oobavail += this->autooob->oobfree[i][1];
2525 2560
2526 /* 2561 /*
2527 * check ECC mode, default to software 2562 * check ECC mode, default to software
2528 * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize 2563 * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize
2529 * fallback to software ECC 2564 * fallback to software ECC
2530 */ 2565 */
2531 this->eccsize = 256; /* set default eccsize */ 2566 this->eccsize = 256; /* set default eccsize */
2532 this->eccbytes = 3; 2567 this->eccbytes = 3;
2533 2568
2534 switch (this->eccmode) { 2569 switch (this->eccmode) {
@@ -2543,56 +2578,56 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2543 this->eccsize = 2048; 2578 this->eccsize = 2048;
2544 break; 2579 break;
2545 2580
2546 case NAND_ECC_HW3_512: 2581 case NAND_ECC_HW3_512:
2547 case NAND_ECC_HW6_512: 2582 case NAND_ECC_HW6_512:
2548 case NAND_ECC_HW8_512: 2583 case NAND_ECC_HW8_512:
2549 if (mtd->oobblock == 256) { 2584 if (mtd->oobblock == 256) {
2550 printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n"); 2585 printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n");
2551 this->eccmode = NAND_ECC_SOFT; 2586 this->eccmode = NAND_ECC_SOFT;
2552 this->calculate_ecc = nand_calculate_ecc; 2587 this->calculate_ecc = nand_calculate_ecc;
2553 this->correct_data = nand_correct_data; 2588 this->correct_data = nand_correct_data;
2554 } else 2589 } else
2555 this->eccsize = 512; /* set eccsize to 512 */ 2590 this->eccsize = 512; /* set eccsize to 512 */
2556 break; 2591 break;
2557 2592
2558 case NAND_ECC_HW3_256: 2593 case NAND_ECC_HW3_256:
2559 break; 2594 break;
2560 2595
2561 case NAND_ECC_NONE: 2596 case NAND_ECC_NONE:
2562 printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n"); 2597 printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n");
2563 this->eccmode = NAND_ECC_NONE; 2598 this->eccmode = NAND_ECC_NONE;
2564 break; 2599 break;
2565 2600
2566 case NAND_ECC_SOFT: 2601 case NAND_ECC_SOFT:
2567 this->calculate_ecc = nand_calculate_ecc; 2602 this->calculate_ecc = nand_calculate_ecc;
2568 this->correct_data = nand_correct_data; 2603 this->correct_data = nand_correct_data;
2569 break; 2604 break;
2570 2605
2571 default: 2606 default:
2572 printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode); 2607 printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
2573 BUG(); 2608 BUG();
2574 } 2609 }
2575 2610
2576 /* Check hardware ecc function availability and adjust number of ecc bytes per 2611 /* Check hardware ecc function availability and adjust number of ecc bytes per
2577 * calculation step 2612 * calculation step
2578 */ 2613 */
2579 switch (this->eccmode) { 2614 switch (this->eccmode) {
2580 case NAND_ECC_HW12_2048: 2615 case NAND_ECC_HW12_2048:
2581 this->eccbytes += 4; 2616 this->eccbytes += 4;
2582 case NAND_ECC_HW8_512: 2617 case NAND_ECC_HW8_512:
2583 this->eccbytes += 2; 2618 this->eccbytes += 2;
2584 case NAND_ECC_HW6_512: 2619 case NAND_ECC_HW6_512:
2585 this->eccbytes += 3; 2620 this->eccbytes += 3;
2586 case NAND_ECC_HW3_512: 2621 case NAND_ECC_HW3_512:
2587 case NAND_ECC_HW3_256: 2622 case NAND_ECC_HW3_256:
2588 if (this->calculate_ecc && this->correct_data && this->enable_hwecc) 2623 if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
2589 break; 2624 break;
2590 printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n"); 2625 printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
2591 BUG(); 2626 BUG();
2592 } 2627 }
2593 2628
2594 mtd->eccsize = this->eccsize; 2629 mtd->eccsize = this->eccsize;
2595 2630
2596 /* Set the number of read / write steps for one page to ensure ECC generation */ 2631 /* Set the number of read / write steps for one page to ensure ECC generation */
2597 switch (this->eccmode) { 2632 switch (this->eccmode) {
2598 case NAND_ECC_HW12_2048: 2633 case NAND_ECC_HW12_2048:
@@ -2604,15 +2639,15 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2604 this->eccsteps = mtd->oobblock / 512; 2639 this->eccsteps = mtd->oobblock / 512;
2605 break; 2640 break;
2606 case NAND_ECC_HW3_256: 2641 case NAND_ECC_HW3_256:
2607 case NAND_ECC_SOFT: 2642 case NAND_ECC_SOFT:
2608 this->eccsteps = mtd->oobblock / 256; 2643 this->eccsteps = mtd->oobblock / 256;
2609 break; 2644 break;
2610 2645
2611 case NAND_ECC_NONE: 2646 case NAND_ECC_NONE:
2612 this->eccsteps = 1; 2647 this->eccsteps = 1;
2613 break; 2648 break;
2614 } 2649 }
2615 2650
2616 /* Initialize state, waitqueue and spinlock */ 2651 /* Initialize state, waitqueue and spinlock */
2617 this->state = FL_READY; 2652 this->state = FL_READY;
2618 init_waitqueue_head (&this->wq); 2653 init_waitqueue_head (&this->wq);
@@ -2643,8 +2678,8 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2643 mtd->sync = nand_sync; 2678 mtd->sync = nand_sync;
2644 mtd->lock = NULL; 2679 mtd->lock = NULL;
2645 mtd->unlock = NULL; 2680 mtd->unlock = NULL;
2646 mtd->suspend = NULL; 2681 mtd->suspend = nand_suspend;
2647 mtd->resume = NULL; 2682 mtd->resume = nand_resume;
2648 mtd->block_isbad = nand_block_isbad; 2683 mtd->block_isbad = nand_block_isbad;
2649 mtd->block_markbad = nand_block_markbad; 2684 mtd->block_markbad = nand_block_markbad;
2650 2685
@@ -2652,7 +2687,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2652 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo)); 2687 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
2653 2688
2654 mtd->owner = THIS_MODULE; 2689 mtd->owner = THIS_MODULE;
2655 2690
2656 /* Check, if we should skip the bad block table scan */ 2691 /* Check, if we should skip the bad block table scan */
2657 if (this->options & NAND_SKIP_BBTSCAN) 2692 if (this->options & NAND_SKIP_BBTSCAN)
2658 return 0; 2693 return 0;
@@ -2662,7 +2697,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2662} 2697}
2663 2698
2664/** 2699/**
2665 * nand_release - [NAND Interface] Free resources held by the NAND device 2700 * nand_release - [NAND Interface] Free resources held by the NAND device
2666 * @mtd: MTD device structure 2701 * @mtd: MTD device structure
2667*/ 2702*/
2668void nand_release (struct mtd_info *mtd) 2703void nand_release (struct mtd_info *mtd)
@@ -2676,9 +2711,8 @@ void nand_release (struct mtd_info *mtd)
2676 /* Deregister the device */ 2711 /* Deregister the device */
2677 del_mtd_device (mtd); 2712 del_mtd_device (mtd);
2678 2713
2679 /* Free bad block table memory, if allocated */ 2714 /* Free bad block table memory */
2680 if (this->bbt) 2715 kfree (this->bbt);
2681 kfree (this->bbt);
2682 /* Buffer allocated by nand_scan ? */ 2716 /* Buffer allocated by nand_scan ? */
2683 if (this->options & NAND_OOBBUF_ALLOC) 2717 if (this->options & NAND_OOBBUF_ALLOC)
2684 kfree (this->oob_buf); 2718 kfree (this->oob_buf);
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 7535ef53685e..ca286999fe08 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -3,10 +3,10 @@
3 * 3 *
4 * Overview: 4 * Overview:
5 * Bad block table support for the NAND driver 5 * Bad block table support for the NAND driver
6 * 6 *
7 * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) 7 * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
8 * 8 *
9 * $Id: nand_bbt.c,v 1.35 2005/07/15 13:53:47 gleixner Exp $ 9 * $Id: nand_bbt.c,v 1.36 2005/11/07 11:14:30 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -14,23 +14,23 @@
14 * 14 *
15 * Description: 15 * Description:
16 * 16 *
17 * When nand_scan_bbt is called, then it tries to find the bad block table 17 * When nand_scan_bbt is called, then it tries to find the bad block table
18 * depending on the options in the bbt descriptor(s). If a bbt is found 18 * depending on the options in the bbt descriptor(s). If a bbt is found
19 * then the contents are read and the memory based bbt is created. If a 19 * then the contents are read and the memory based bbt is created. If a
20 * mirrored bbt is selected then the mirror is searched too and the 20 * mirrored bbt is selected then the mirror is searched too and the
21 * versions are compared. If the mirror has a greater version number 21 * versions are compared. If the mirror has a greater version number
22 * than the mirror bbt is used to build the memory based bbt. 22 * than the mirror bbt is used to build the memory based bbt.
23 * If the tables are not versioned, then we "or" the bad block information. 23 * If the tables are not versioned, then we "or" the bad block information.
24 * If one of the bbt's is out of date or does not exist it is (re)created. 24 * If one of the bbt's is out of date or does not exist it is (re)created.
25 * If no bbt exists at all then the device is scanned for factory marked 25 * If no bbt exists at all then the device is scanned for factory marked
26 * good / bad blocks and the bad block tables are created. 26 * good / bad blocks and the bad block tables are created.
27 * 27 *
28 * For manufacturer created bbts like the one found on M-SYS DOC devices 28 * For manufacturer created bbts like the one found on M-SYS DOC devices
29 * the bbt is searched and read but never created 29 * the bbt is searched and read but never created
30 * 30 *
31 * The autogenerated bad block table is located in the last good blocks 31 * The autogenerated bad block table is located in the last good blocks
32 * of the device. The table is mirrored, so it can be updated eventually. 32 * of the device. The table is mirrored, so it can be updated eventually.
33 * The table is marked in the oob area with an ident pattern and a version 33 * The table is marked in the oob area with an ident pattern and a version
34 * number which indicates which of both tables is more up to date. 34 * number which indicates which of both tables is more up to date.
35 * 35 *
36 * The table uses 2 bits per block 36 * The table uses 2 bits per block
@@ -43,13 +43,13 @@
43 * 01b: block is marked bad due to wear 43 * 01b: block is marked bad due to wear
44 * 10b: block is reserved (to protect the bbt area) 44 * 10b: block is reserved (to protect the bbt area)
45 * 11b: block is factory marked bad 45 * 11b: block is factory marked bad
46 * 46 *
47 * Multichip devices like DOC store the bad block info per floor. 47 * Multichip devices like DOC store the bad block info per floor.
48 * 48 *
49 * Following assumptions are made: 49 * Following assumptions are made:
50 * - bbts start at a page boundary, if autolocated on a block boundary 50 * - bbts start at a page boundary, if autolocated on a block boundary
51 * - the space neccecary for a bbt in FLASH does not exceed a block boundary 51 * - the space neccecary for a bbt in FLASH does not exceed a block boundary
52 * 52 *
53 */ 53 */
54 54
55#include <linux/slab.h> 55#include <linux/slab.h>
@@ -62,7 +62,7 @@
62#include <linux/delay.h> 62#include <linux/delay.h>
63 63
64 64
65/** 65/**
66 * check_pattern - [GENERIC] check if a pattern is in the buffer 66 * check_pattern - [GENERIC] check if a pattern is in the buffer
67 * @buf: the buffer to search 67 * @buf: the buffer to search
68 * @len: the length of buffer to search 68 * @len: the length of buffer to search
@@ -86,9 +86,9 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
86 if (p[i] != 0xff) 86 if (p[i] != 0xff)
87 return -1; 87 return -1;
88 } 88 }
89 } 89 }
90 p += end; 90 p += end;
91 91
92 /* Compare the pattern */ 92 /* Compare the pattern */
93 for (i = 0; i < td->len; i++) { 93 for (i = 0; i < td->len; i++) {
94 if (p[i] != td->pattern[i]) 94 if (p[i] != td->pattern[i])
@@ -106,13 +106,13 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
106 return 0; 106 return 0;
107} 107}
108 108
109/** 109/**
110 * check_short_pattern - [GENERIC] check if a pattern is in the buffer 110 * check_short_pattern - [GENERIC] check if a pattern is in the buffer
111 * @buf: the buffer to search 111 * @buf: the buffer to search
112 * @td: search pattern descriptor 112 * @td: search pattern descriptor
113 * 113 *
114 * Check for a pattern at the given place. Used to search bad block 114 * Check for a pattern at the given place. Used to search bad block
115 * tables and good / bad block identifiers. Same as check_pattern, but 115 * tables and good / bad block identifiers. Same as check_pattern, but
116 * no optional empty check 116 * no optional empty check
117 * 117 *
118*/ 118*/
@@ -142,7 +142,7 @@ static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
142 * Read the bad block table starting from page. 142 * Read the bad block table starting from page.
143 * 143 *
144 */ 144 */
145static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, 145static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
146 int bits, int offs, int reserved_block_code) 146 int bits, int offs, int reserved_block_code)
147{ 147{
148 int res, i, j, act = 0; 148 int res, i, j, act = 0;
@@ -153,7 +153,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
153 153
154 totlen = (num * bits) >> 3; 154 totlen = (num * bits) >> 3;
155 from = ((loff_t)page) << this->page_shift; 155 from = ((loff_t)page) << this->page_shift;
156 156
157 while (totlen) { 157 while (totlen) {
158 len = min (totlen, (size_t) (1 << this->bbt_erase_shift)); 158 len = min (totlen, (size_t) (1 << this->bbt_erase_shift));
159 res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob); 159 res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob);
@@ -163,7 +163,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
163 return res; 163 return res;
164 } 164 }
165 printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n"); 165 printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
166 } 166 }
167 167
168 /* Analyse data */ 168 /* Analyse data */
169 for (i = 0; i < len; i++) { 169 for (i = 0; i < len; i++) {
@@ -183,12 +183,12 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
183 * message to MTD_DEBUG_LEVEL0 */ 183 * message to MTD_DEBUG_LEVEL0 */
184 printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n", 184 printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
185 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); 185 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
186 /* Factory marked bad or worn out ? */ 186 /* Factory marked bad or worn out ? */
187 if (tmp == 0) 187 if (tmp == 0)
188 this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06); 188 this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
189 else 189 else
190 this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06); 190 this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06);
191 } 191 }
192 } 192 }
193 totlen -= len; 193 totlen -= len;
194 from += len; 194 from += len;
@@ -200,7 +200,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
200 * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page 200 * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
201 * @mtd: MTD device structure 201 * @mtd: MTD device structure
202 * @buf: temporary buffer 202 * @buf: temporary buffer
203 * @td: descriptor for the bad block table 203 * @td: descriptor for the bad block table
204 * @chip: read the table for a specific chip, -1 read all chips. 204 * @chip: read the table for a specific chip, -1 read all chips.
205 * Applies only if NAND_BBT_PERCHIP option is set 205 * Applies only if NAND_BBT_PERCHIP option is set
206 * 206 *
@@ -235,7 +235,7 @@ static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
235 * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page 235 * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
236 * @mtd: MTD device structure 236 * @mtd: MTD device structure
237 * @buf: temporary buffer 237 * @buf: temporary buffer
238 * @td: descriptor for the bad block table 238 * @td: descriptor for the bad block table
239 * @md: descriptor for the bad block table mirror 239 * @md: descriptor for the bad block table mirror
240 * 240 *
241 * Read the bad block table(s) for all chips starting at a given page 241 * Read the bad block table(s) for all chips starting at a given page
@@ -247,16 +247,16 @@ static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_de
247{ 247{
248 struct nand_chip *this = mtd->priv; 248 struct nand_chip *this = mtd->priv;
249 249
250 /* Read the primary version, if available */ 250 /* Read the primary version, if available */
251 if (td->options & NAND_BBT_VERSION) { 251 if (td->options & NAND_BBT_VERSION) {
252 nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); 252 nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
253 td->version[0] = buf[mtd->oobblock + td->veroffs]; 253 td->version[0] = buf[mtd->oobblock + td->veroffs];
254 printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]); 254 printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]);
255 } 255 }
256 256
257 /* Read the mirror version, if available */ 257 /* Read the mirror version, if available */
258 if (md && (md->options & NAND_BBT_VERSION)) { 258 if (md && (md->options & NAND_BBT_VERSION)) {
259 nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); 259 nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
260 md->version[0] = buf[mtd->oobblock + md->veroffs]; 260 md->version[0] = buf[mtd->oobblock + md->veroffs];
261 printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]); 261 printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]);
262 } 262 }
@@ -290,7 +290,7 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
290 else { 290 else {
291 if (bd->options & NAND_BBT_SCAN2NDPAGE) 291 if (bd->options & NAND_BBT_SCAN2NDPAGE)
292 len = 2; 292 len = 2;
293 else 293 else
294 len = 1; 294 len = 1;
295 } 295 }
296 296
@@ -322,10 +322,10 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
322 numblocks += startblock; 322 numblocks += startblock;
323 from = startblock << (this->bbt_erase_shift - 1); 323 from = startblock << (this->bbt_erase_shift - 1);
324 } 324 }
325 325
326 for (i = startblock; i < numblocks;) { 326 for (i = startblock; i < numblocks;) {
327 int ret; 327 int ret;
328 328
329 if (bd->options & NAND_BBT_SCANEMPTY) 329 if (bd->options & NAND_BBT_SCANEMPTY)
330 if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen))) 330 if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen)))
331 return ret; 331 return ret;
@@ -333,8 +333,8 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
333 for (j = 0; j < len; j++) { 333 for (j = 0; j < len; j++) {
334 if (!(bd->options & NAND_BBT_SCANEMPTY)) { 334 if (!(bd->options & NAND_BBT_SCANEMPTY)) {
335 size_t retlen; 335 size_t retlen;
336 336
337 /* Read the full oob until read_oob is fixed to 337 /* Read the full oob until read_oob is fixed to
338 * handle single byte reads for 16 bit buswidth */ 338 * handle single byte reads for 16 bit buswidth */
339 ret = mtd->read_oob(mtd, from + j * mtd->oobblock, 339 ret = mtd->read_oob(mtd, from + j * mtd->oobblock,
340 mtd->oobsize, &retlen, buf); 340 mtd->oobsize, &retlen, buf);
@@ -343,14 +343,14 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
343 343
344 if (check_short_pattern (buf, bd)) { 344 if (check_short_pattern (buf, bd)) {
345 this->bbt[i >> 3] |= 0x03 << (i & 0x6); 345 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
346 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 346 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
347 i >> 1, (unsigned int) from); 347 i >> 1, (unsigned int) from);
348 break; 348 break;
349 } 349 }
350 } else { 350 } else {
351 if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { 351 if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
352 this->bbt[i >> 3] |= 0x03 << (i & 0x6); 352 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
353 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 353 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
354 i >> 1, (unsigned int) from); 354 i >> 1, (unsigned int) from);
355 break; 355 break;
356 } 356 }
@@ -369,15 +369,15 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
369 * @td: descriptor for the bad block table 369 * @td: descriptor for the bad block table
370 * 370 *
371 * Read the bad block table by searching for a given ident pattern. 371 * Read the bad block table by searching for a given ident pattern.
372 * Search is preformed either from the beginning up or from the end of 372 * Search is preformed either from the beginning up or from the end of
373 * the device downwards. The search starts always at the start of a 373 * the device downwards. The search starts always at the start of a
374 * block. 374 * block.
375 * If the option NAND_BBT_PERCHIP is given, each chip is searched 375 * If the option NAND_BBT_PERCHIP is given, each chip is searched
376 * for a bbt, which contains the bad block information of this chip. 376 * for a bbt, which contains the bad block information of this chip.
377 * This is neccecary to provide support for certain DOC devices. 377 * This is neccecary to provide support for certain DOC devices.
378 * 378 *
379 * The bbt ident pattern resides in the oob area of the first page 379 * The bbt ident pattern resides in the oob area of the first page
380 * in a block. 380 * in a block.
381 */ 381 */
382static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) 382static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
383{ 383{
@@ -392,10 +392,10 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
392 startblock = (mtd->size >> this->bbt_erase_shift) -1; 392 startblock = (mtd->size >> this->bbt_erase_shift) -1;
393 dir = -1; 393 dir = -1;
394 } else { 394 } else {
395 startblock = 0; 395 startblock = 0;
396 dir = 1; 396 dir = 1;
397 } 397 }
398 398
399 /* Do we have a bbt per chip ? */ 399 /* Do we have a bbt per chip ? */
400 if (td->options & NAND_BBT_PERCHIP) { 400 if (td->options & NAND_BBT_PERCHIP) {
401 chips = this->numchips; 401 chips = this->numchips;
@@ -405,19 +405,19 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
405 chips = 1; 405 chips = 1;
406 bbtblocks = mtd->size >> this->bbt_erase_shift; 406 bbtblocks = mtd->size >> this->bbt_erase_shift;
407 } 407 }
408 408
409 /* Number of bits for each erase block in the bbt */ 409 /* Number of bits for each erase block in the bbt */
410 bits = td->options & NAND_BBT_NRBITS_MSK; 410 bits = td->options & NAND_BBT_NRBITS_MSK;
411 411
412 for (i = 0; i < chips; i++) { 412 for (i = 0; i < chips; i++) {
413 /* Reset version information */ 413 /* Reset version information */
414 td->version[i] = 0; 414 td->version[i] = 0;
415 td->pages[i] = -1; 415 td->pages[i] = -1;
416 /* Scan the maximum number of blocks */ 416 /* Scan the maximum number of blocks */
417 for (block = 0; block < td->maxblocks; block++) { 417 for (block = 0; block < td->maxblocks; block++) {
418 int actblock = startblock + dir * block; 418 int actblock = startblock + dir * block;
419 /* Read first page */ 419 /* Read first page */
420 nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize); 420 nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize);
421 if (!check_pattern(buf, scanlen, mtd->oobblock, td)) { 421 if (!check_pattern(buf, scanlen, mtd->oobblock, td)) {
422 td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift); 422 td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift);
423 if (td->options & NAND_BBT_VERSION) { 423 if (td->options & NAND_BBT_VERSION) {
@@ -435,46 +435,46 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
435 else 435 else
436 printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]); 436 printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]);
437 } 437 }
438 return 0; 438 return 0;
439} 439}
440 440
441/** 441/**
442 * search_read_bbts - [GENERIC] scan the device for bad block table(s) 442 * search_read_bbts - [GENERIC] scan the device for bad block table(s)
443 * @mtd: MTD device structure 443 * @mtd: MTD device structure
444 * @buf: temporary buffer 444 * @buf: temporary buffer
445 * @td: descriptor for the bad block table 445 * @td: descriptor for the bad block table
446 * @md: descriptor for the bad block table mirror 446 * @md: descriptor for the bad block table mirror
447 * 447 *
448 * Search and read the bad block table(s) 448 * Search and read the bad block table(s)
449*/ 449*/
450static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf, 450static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
451 struct nand_bbt_descr *td, struct nand_bbt_descr *md) 451 struct nand_bbt_descr *td, struct nand_bbt_descr *md)
452{ 452{
453 /* Search the primary table */ 453 /* Search the primary table */
454 search_bbt (mtd, buf, td); 454 search_bbt (mtd, buf, td);
455 455
456 /* Search the mirror table */ 456 /* Search the mirror table */
457 if (md) 457 if (md)
458 search_bbt (mtd, buf, md); 458 search_bbt (mtd, buf, md);
459 459
460 /* Force result check */ 460 /* Force result check */
461 return 1; 461 return 1;
462} 462}
463
464 463
465/** 464
465/**
466 * write_bbt - [GENERIC] (Re)write the bad block table 466 * write_bbt - [GENERIC] (Re)write the bad block table
467 * 467 *
468 * @mtd: MTD device structure 468 * @mtd: MTD device structure
469 * @buf: temporary buffer 469 * @buf: temporary buffer
470 * @td: descriptor for the bad block table 470 * @td: descriptor for the bad block table
471 * @md: descriptor for the bad block table mirror 471 * @md: descriptor for the bad block table mirror
472 * @chipsel: selector for a specific chip, -1 for all 472 * @chipsel: selector for a specific chip, -1 for all
473 * 473 *
474 * (Re)write the bad block table 474 * (Re)write the bad block table
475 * 475 *
476*/ 476*/
477static int write_bbt (struct mtd_info *mtd, uint8_t *buf, 477static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
478 struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel) 478 struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel)
479{ 479{
480 struct nand_chip *this = mtd->priv; 480 struct nand_chip *this = mtd->priv;
@@ -493,7 +493,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
493 /* Write bad block table per chip rather than per device ? */ 493 /* Write bad block table per chip rather than per device ? */
494 if (td->options & NAND_BBT_PERCHIP) { 494 if (td->options & NAND_BBT_PERCHIP) {
495 numblocks = (int) (this->chipsize >> this->bbt_erase_shift); 495 numblocks = (int) (this->chipsize >> this->bbt_erase_shift);
496 /* Full device write or specific chip ? */ 496 /* Full device write or specific chip ? */
497 if (chipsel == -1) { 497 if (chipsel == -1) {
498 nrchips = this->numchips; 498 nrchips = this->numchips;
499 } else { 499 } else {
@@ -503,19 +503,19 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
503 } else { 503 } else {
504 numblocks = (int) (mtd->size >> this->bbt_erase_shift); 504 numblocks = (int) (mtd->size >> this->bbt_erase_shift);
505 nrchips = 1; 505 nrchips = 1;
506 } 506 }
507 507
508 /* Loop through the chips */ 508 /* Loop through the chips */
509 for (; chip < nrchips; chip++) { 509 for (; chip < nrchips; chip++) {
510 510
511 /* There was already a version of the table, reuse the page 511 /* There was already a version of the table, reuse the page
512 * This applies for absolute placement too, as we have the 512 * This applies for absolute placement too, as we have the
513 * page nr. in td->pages. 513 * page nr. in td->pages.
514 */ 514 */
515 if (td->pages[chip] != -1) { 515 if (td->pages[chip] != -1) {
516 page = td->pages[chip]; 516 page = td->pages[chip];
517 goto write; 517 goto write;
518 } 518 }
519 519
520 /* Automatic placement of the bad block table */ 520 /* Automatic placement of the bad block table */
521 /* Search direction top -> down ? */ 521 /* Search direction top -> down ? */
@@ -525,7 +525,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
525 } else { 525 } else {
526 startblock = chip * numblocks; 526 startblock = chip * numblocks;
527 dir = 1; 527 dir = 1;
528 } 528 }
529 529
530 for (i = 0; i < td->maxblocks; i++) { 530 for (i = 0; i < td->maxblocks; i++) {
531 int block = startblock + dir * i; 531 int block = startblock + dir * i;
@@ -542,7 +542,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
542 } 542 }
543 printk (KERN_ERR "No space left to write bad block table\n"); 543 printk (KERN_ERR "No space left to write bad block table\n");
544 return -ENOSPC; 544 return -ENOSPC;
545write: 545write:
546 546
547 /* Set up shift count and masks for the flash table */ 547 /* Set up shift count and masks for the flash table */
548 bits = td->options & NAND_BBT_NRBITS_MSK; 548 bits = td->options & NAND_BBT_NRBITS_MSK;
@@ -553,14 +553,14 @@ write:
553 case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break; 553 case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break;
554 default: return -EINVAL; 554 default: return -EINVAL;
555 } 555 }
556 556
557 bbtoffs = chip * (numblocks >> 2); 557 bbtoffs = chip * (numblocks >> 2);
558 558
559 to = ((loff_t) page) << this->page_shift; 559 to = ((loff_t) page) << this->page_shift;
560 560
561 memcpy (&oobinfo, this->autooob, sizeof(oobinfo)); 561 memcpy (&oobinfo, this->autooob, sizeof(oobinfo));
562 oobinfo.useecc = MTD_NANDECC_PLACEONLY; 562 oobinfo.useecc = MTD_NANDECC_PLACEONLY;
563 563
564 /* Must we save the block contents ? */ 564 /* Must we save the block contents ? */
565 if (td->options & NAND_BBT_SAVECONTENT) { 565 if (td->options & NAND_BBT_SAVECONTENT) {
566 /* Make it block aligned */ 566 /* Make it block aligned */
@@ -599,7 +599,7 @@ write:
599 buf[len + td->veroffs] = td->version[chip]; 599 buf[len + td->veroffs] = td->version[chip];
600 } 600 }
601 } 601 }
602 602
603 /* walk through the memory table */ 603 /* walk through the memory table */
604 for (i = 0; i < numblocks; ) { 604 for (i = 0; i < numblocks; ) {
605 uint8_t dat; 605 uint8_t dat;
@@ -611,7 +611,7 @@ write:
611 dat >>= 2; 611 dat >>= 2;
612 } 612 }
613 } 613 }
614 614
615 memset (&einfo, 0, sizeof (einfo)); 615 memset (&einfo, 0, sizeof (einfo));
616 einfo.mtd = mtd; 616 einfo.mtd = mtd;
617 einfo.addr = (unsigned long) to; 617 einfo.addr = (unsigned long) to;
@@ -621,18 +621,18 @@ write:
621 printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res); 621 printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res);
622 return res; 622 return res;
623 } 623 }
624 624
625 res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo); 625 res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
626 if (res < 0) { 626 if (res < 0) {
627 printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res); 627 printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res);
628 return res; 628 return res;
629 } 629 }
630 printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n", 630 printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n",
631 (unsigned int) to, td->version[chip]); 631 (unsigned int) to, td->version[chip]);
632 632
633 /* Mark it as used */ 633 /* Mark it as used */
634 td->pages[chip] = page; 634 td->pages[chip] = page;
635 } 635 }
636 return 0; 636 return 0;
637} 637}
638 638
@@ -641,7 +641,7 @@ write:
641 * @mtd: MTD device structure 641 * @mtd: MTD device structure
642 * @bd: descriptor for the good/bad block search pattern 642 * @bd: descriptor for the good/bad block search pattern
643 * 643 *
644 * The function creates a memory based bbt by scanning the device 644 * The function creates a memory based bbt by scanning the device
645 * for manufacturer / software marked good / bad blocks 645 * for manufacturer / software marked good / bad blocks
646*/ 646*/
647static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) 647static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
@@ -673,11 +673,11 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
673 struct nand_bbt_descr *rd, *rd2; 673 struct nand_bbt_descr *rd, *rd2;
674 674
675 /* Do we have a bbt per chip ? */ 675 /* Do we have a bbt per chip ? */
676 if (td->options & NAND_BBT_PERCHIP) 676 if (td->options & NAND_BBT_PERCHIP)
677 chips = this->numchips; 677 chips = this->numchips;
678 else 678 else
679 chips = 1; 679 chips = 1;
680 680
681 for (i = 0; i < chips; i++) { 681 for (i = 0; i < chips; i++) {
682 writeops = 0; 682 writeops = 0;
683 rd = NULL; 683 rd = NULL;
@@ -692,7 +692,7 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
692 } 692 }
693 693
694 if (td->pages[i] == -1) { 694 if (td->pages[i] == -1) {
695 rd = md; 695 rd = md;
696 td->version[i] = md->version[i]; 696 td->version[i] = md->version[i];
697 writeops = 1; 697 writeops = 1;
698 goto writecheck; 698 goto writecheck;
@@ -710,7 +710,7 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
710 if (!(td->options & NAND_BBT_VERSION)) 710 if (!(td->options & NAND_BBT_VERSION))
711 rd2 = md; 711 rd2 = md;
712 goto writecheck; 712 goto writecheck;
713 } 713 }
714 714
715 if (((int8_t) (td->version[i] - md->version[i])) > 0) { 715 if (((int8_t) (td->version[i] - md->version[i])) > 0) {
716 rd = td; 716 rd = td;
@@ -735,15 +735,15 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
735create: 735create:
736 /* Create the bad block table by scanning the device ? */ 736 /* Create the bad block table by scanning the device ? */
737 if (!(td->options & NAND_BBT_CREATE)) 737 if (!(td->options & NAND_BBT_CREATE))
738 continue; 738 continue;
739 739
740 /* Create the table in memory by scanning the chip(s) */ 740 /* Create the table in memory by scanning the chip(s) */
741 create_bbt (mtd, buf, bd, chipsel); 741 create_bbt (mtd, buf, bd, chipsel);
742 742
743 td->version[i] = 1; 743 td->version[i] = 1;
744 if (md) 744 if (md)
745 md->version[i] = 1; 745 md->version[i] = 1;
746writecheck: 746writecheck:
747 /* read back first ? */ 747 /* read back first ? */
748 if (rd) 748 if (rd)
749 read_abs_bbt (mtd, buf, rd, chipsel); 749 read_abs_bbt (mtd, buf, rd, chipsel);
@@ -757,7 +757,7 @@ writecheck:
757 if (res < 0) 757 if (res < 0)
758 return res; 758 return res;
759 } 759 }
760 760
761 /* Write the mirror bad block table to the device ? */ 761 /* Write the mirror bad block table to the device ? */
762 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { 762 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
763 res = write_bbt (mtd, buf, md, td, chipsel); 763 res = write_bbt (mtd, buf, md, td, chipsel);
@@ -765,11 +765,11 @@ writecheck:
765 return res; 765 return res;
766 } 766 }
767 } 767 }
768 return 0; 768 return 0;
769} 769}
770 770
771/** 771/**
772 * mark_bbt_regions - [GENERIC] mark the bad block table regions 772 * mark_bbt_regions - [GENERIC] mark the bad block table regions
773 * @mtd: MTD device structure 773 * @mtd: MTD device structure
774 * @td: bad block table descriptor 774 * @td: bad block table descriptor
775 * 775 *
@@ -790,14 +790,14 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
790 } else { 790 } else {
791 chips = 1; 791 chips = 1;
792 nrblocks = (int)(mtd->size >> this->bbt_erase_shift); 792 nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
793 } 793 }
794 794
795 for (i = 0; i < chips; i++) { 795 for (i = 0; i < chips; i++) {
796 if ((td->options & NAND_BBT_ABSPAGE) || 796 if ((td->options & NAND_BBT_ABSPAGE) ||
797 !(td->options & NAND_BBT_WRITE)) { 797 !(td->options & NAND_BBT_WRITE)) {
798 if (td->pages[i] == -1) continue; 798 if (td->pages[i] == -1) continue;
799 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift); 799 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
800 block <<= 1; 800 block <<= 1;
801 oldval = this->bbt[(block >> 3)]; 801 oldval = this->bbt[(block >> 3)];
802 newval = oldval | (0x2 << (block & 0x06)); 802 newval = oldval | (0x2 << (block & 0x06));
803 this->bbt[(block >> 3)] = newval; 803 this->bbt[(block >> 3)] = newval;
@@ -808,16 +808,16 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
808 update = 0; 808 update = 0;
809 if (td->options & NAND_BBT_LASTBLOCK) 809 if (td->options & NAND_BBT_LASTBLOCK)
810 block = ((i + 1) * nrblocks) - td->maxblocks; 810 block = ((i + 1) * nrblocks) - td->maxblocks;
811 else 811 else
812 block = i * nrblocks; 812 block = i * nrblocks;
813 block <<= 1; 813 block <<= 1;
814 for (j = 0; j < td->maxblocks; j++) { 814 for (j = 0; j < td->maxblocks; j++) {
815 oldval = this->bbt[(block >> 3)]; 815 oldval = this->bbt[(block >> 3)];
816 newval = oldval | (0x2 << (block & 0x06)); 816 newval = oldval | (0x2 << (block & 0x06));
817 this->bbt[(block >> 3)] = newval; 817 this->bbt[(block >> 3)] = newval;
818 if (oldval != newval) update = 1; 818 if (oldval != newval) update = 1;
819 block += 2; 819 block += 2;
820 } 820 }
821 /* If we want reserved blocks to be recorded to flash, and some 821 /* If we want reserved blocks to be recorded to flash, and some
822 new ones have been marked, then we need to update the stored 822 new ones have been marked, then we need to update the stored
823 bbts. This should only happen once. */ 823 bbts. This should only happen once. */
@@ -831,7 +831,7 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
831 * @mtd: MTD device structure 831 * @mtd: MTD device structure
832 * @bd: descriptor for the good/bad block search pattern 832 * @bd: descriptor for the good/bad block search pattern
833 * 833 *
834 * The function checks, if a bad block table(s) is/are already 834 * The function checks, if a bad block table(s) is/are already
835 * available. If not it scans the device for manufacturer 835 * available. If not it scans the device for manufacturer
836 * marked good / bad blocks and writes the bad block table(s) to 836 * marked good / bad blocks and writes the bad block table(s) to
837 * the selected place. 837 * the selected place.
@@ -880,30 +880,30 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
880 this->bbt = NULL; 880 this->bbt = NULL;
881 return -ENOMEM; 881 return -ENOMEM;
882 } 882 }
883 883
884 /* Is the bbt at a given page ? */ 884 /* Is the bbt at a given page ? */
885 if (td->options & NAND_BBT_ABSPAGE) { 885 if (td->options & NAND_BBT_ABSPAGE) {
886 res = read_abs_bbts (mtd, buf, td, md); 886 res = read_abs_bbts (mtd, buf, td, md);
887 } else { 887 } else {
888 /* Search the bad block table using a pattern in oob */ 888 /* Search the bad block table using a pattern in oob */
889 res = search_read_bbts (mtd, buf, td, md); 889 res = search_read_bbts (mtd, buf, td, md);
890 } 890 }
891 891
892 if (res) 892 if (res)
893 res = check_create (mtd, buf, bd); 893 res = check_create (mtd, buf, bd);
894 894
895 /* Prevent the bbt regions from erasing / writing */ 895 /* Prevent the bbt regions from erasing / writing */
896 mark_bbt_region (mtd, td); 896 mark_bbt_region (mtd, td);
897 if (md) 897 if (md)
898 mark_bbt_region (mtd, md); 898 mark_bbt_region (mtd, md);
899 899
900 kfree (buf); 900 kfree (buf);
901 return res; 901 return res;
902} 902}
903 903
904 904
905/** 905/**
906 * nand_update_bbt - [NAND Interface] update bad block table(s) 906 * nand_update_bbt - [NAND Interface] update bad block table(s)
907 * @mtd: MTD device structure 907 * @mtd: MTD device structure
908 * @offs: the offset of the newly marked block 908 * @offs: the offset of the newly marked block
909 * 909 *
@@ -930,7 +930,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
930 printk (KERN_ERR "nand_update_bbt: Out of memory\n"); 930 printk (KERN_ERR "nand_update_bbt: Out of memory\n");
931 return -ENOMEM; 931 return -ENOMEM;
932 } 932 }
933 933
934 writeops = md != NULL ? 0x03 : 0x01; 934 writeops = md != NULL ? 0x03 : 0x01;
935 935
936 /* Do we have a bbt per chip ? */ 936 /* Do we have a bbt per chip ? */
@@ -944,7 +944,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
944 944
945 td->version[chip]++; 945 td->version[chip]++;
946 if (md) 946 if (md)
947 md->version[chip]++; 947 md->version[chip]++;
948 948
949 /* Write the bad block table to the device ? */ 949 /* Write the bad block table to the device ? */
950 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { 950 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
@@ -957,12 +957,12 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
957 res = write_bbt (mtd, buf, md, td, chipsel); 957 res = write_bbt (mtd, buf, md, td, chipsel);
958 } 958 }
959 959
960out: 960out:
961 kfree (buf); 961 kfree (buf);
962 return res; 962 return res;
963} 963}
964 964
965/* Define some generic bad / good block scan pattern which are used 965/* Define some generic bad / good block scan pattern which are used
966 * while scanning a device for factory marked good / bad blocks. */ 966 * while scanning a device for factory marked good / bad blocks. */
967static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; 967static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
968 968
@@ -1009,7 +1009,7 @@ static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
1009static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; 1009static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
1010 1010
1011static struct nand_bbt_descr bbt_main_descr = { 1011static struct nand_bbt_descr bbt_main_descr = {
1012 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 1012 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
1013 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 1013 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
1014 .offs = 8, 1014 .offs = 8,
1015 .len = 4, 1015 .len = 4,
@@ -1019,7 +1019,7 @@ static struct nand_bbt_descr bbt_main_descr = {
1019}; 1019};
1020 1020
1021static struct nand_bbt_descr bbt_mirror_descr = { 1021static struct nand_bbt_descr bbt_mirror_descr = {
1022 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 1022 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
1023 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 1023 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
1024 .offs = 8, 1024 .offs = 8,
1025 .len = 4, 1025 .len = 4,
@@ -1029,7 +1029,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {
1029}; 1029};
1030 1030
1031/** 1031/**
1032 * nand_default_bbt - [NAND Interface] Select a default bad block table for the device 1032 * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
1033 * @mtd: MTD device structure 1033 * @mtd: MTD device structure
1034 * 1034 *
1035 * This function selects the default bad block table 1035 * This function selects the default bad block table
@@ -1039,29 +1039,29 @@ static struct nand_bbt_descr bbt_mirror_descr = {
1039int nand_default_bbt (struct mtd_info *mtd) 1039int nand_default_bbt (struct mtd_info *mtd)
1040{ 1040{
1041 struct nand_chip *this = mtd->priv; 1041 struct nand_chip *this = mtd->priv;
1042 1042
1043 /* Default for AG-AND. We must use a flash based 1043 /* Default for AG-AND. We must use a flash based
1044 * bad block table as the devices have factory marked 1044 * bad block table as the devices have factory marked
1045 * _good_ blocks. Erasing those blocks leads to loss 1045 * _good_ blocks. Erasing those blocks leads to loss
1046 * of the good / bad information, so we _must_ store 1046 * of the good / bad information, so we _must_ store
1047 * this information in a good / bad table during 1047 * this information in a good / bad table during
1048 * startup 1048 * startup
1049 */ 1049 */
1050 if (this->options & NAND_IS_AND) { 1050 if (this->options & NAND_IS_AND) {
1051 /* Use the default pattern descriptors */ 1051 /* Use the default pattern descriptors */
1052 if (!this->bbt_td) { 1052 if (!this->bbt_td) {
1053 this->bbt_td = &bbt_main_descr; 1053 this->bbt_td = &bbt_main_descr;
1054 this->bbt_md = &bbt_mirror_descr; 1054 this->bbt_md = &bbt_mirror_descr;
1055 } 1055 }
1056 this->options |= NAND_USE_FLASH_BBT; 1056 this->options |= NAND_USE_FLASH_BBT;
1057 return nand_scan_bbt (mtd, &agand_flashbased); 1057 return nand_scan_bbt (mtd, &agand_flashbased);
1058 } 1058 }
1059 1059
1060 1060
1061 /* Is a flash based bad block table requested ? */ 1061 /* Is a flash based bad block table requested ? */
1062 if (this->options & NAND_USE_FLASH_BBT) { 1062 if (this->options & NAND_USE_FLASH_BBT) {
1063 /* Use the default pattern descriptors */ 1063 /* Use the default pattern descriptors */
1064 if (!this->bbt_td) { 1064 if (!this->bbt_td) {
1065 this->bbt_td = &bbt_main_descr; 1065 this->bbt_td = &bbt_main_descr;
1066 this->bbt_md = &bbt_mirror_descr; 1066 this->bbt_md = &bbt_mirror_descr;
1067 } 1067 }
@@ -1081,7 +1081,7 @@ int nand_default_bbt (struct mtd_info *mtd)
1081} 1081}
1082 1082
1083/** 1083/**
1084 * nand_isbad_bbt - [NAND Interface] Check if a block is bad 1084 * nand_isbad_bbt - [NAND Interface] Check if a block is bad
1085 * @mtd: MTD device structure 1085 * @mtd: MTD device structure
1086 * @offs: offset in the device 1086 * @offs: offset in the device
1087 * @allowbbt: allow access to bad block table region 1087 * @allowbbt: allow access to bad block table region
@@ -1092,12 +1092,12 @@ int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt)
1092 struct nand_chip *this = mtd->priv; 1092 struct nand_chip *this = mtd->priv;
1093 int block; 1093 int block;
1094 uint8_t res; 1094 uint8_t res;
1095 1095
1096 /* Get block number * 2 */ 1096 /* Get block number * 2 */
1097 block = (int) (offs >> (this->bbt_erase_shift - 1)); 1097 block = (int) (offs >> (this->bbt_erase_shift - 1));
1098 res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03; 1098 res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
1099 1099
1100 DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n", 1100 DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
1101 (unsigned int)offs, block >> 1, res); 1101 (unsigned int)offs, block >> 1, res);
1102 1102
1103 switch ((int)res) { 1103 switch ((int)res) {
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index 2e341b75437a..40ac909150a3 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -7,22 +7,22 @@
7 * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) 7 * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com)
8 * Toshiba America Electronics Components, Inc. 8 * Toshiba America Electronics Components, Inc.
9 * 9 *
10 * $Id: nand_ecc.c,v 1.14 2004/06/16 15:34:37 gleixner Exp $ 10 * $Id: nand_ecc.c,v 1.15 2005/11/07 11:14:30 gleixner Exp $
11 * 11 *
12 * This file is free software; you can redistribute it and/or modify it 12 * This file is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the 13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 or (at your option) any 14 * Free Software Foundation; either version 2 or (at your option) any
15 * later version. 15 * later version.
16 * 16 *
17 * This file is distributed in the hope that it will be useful, but WITHOUT 17 * This file is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details. 20 * for more details.
21 * 21 *
22 * You should have received a copy of the GNU General Public License along 22 * You should have received a copy of the GNU General Public License along
23 * with this file; if not, write to the Free Software Foundation, Inc., 23 * with this file; if not, write to the Free Software Foundation, Inc.,
24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 * 25 *
26 * As a special exception, if other files instantiate templates or use 26 * As a special exception, if other files instantiate templates or use
27 * macros or inline functions from these files, or you compile these 27 * macros or inline functions from these files, or you compile these
28 * files and link them with other works to produce a work based on these 28 * files and link them with other works to produce a work based on these
@@ -30,7 +30,7 @@
30 * covered by the GNU General Public License. However the source code for 30 * covered by the GNU General Public License. However the source code for
31 * these files must still be made available in accordance with section (3) 31 * these files must still be made available in accordance with section (3)
32 * of the GNU General Public License. 32 * of the GNU General Public License.
33 * 33 *
34 * This exception does not invalidate any other reasons why a work based on 34 * This exception does not invalidate any other reasons why a work based on
35 * this file might be covered by the GNU General Public License. 35 * this file might be covered by the GNU General Public License.
36 */ 36 */
@@ -67,7 +67,7 @@ static const u_char nand_ecc_precalc_table[] = {
67 * nand_trans_result - [GENERIC] create non-inverted ECC 67 * nand_trans_result - [GENERIC] create non-inverted ECC
68 * @reg2: line parity reg 2 68 * @reg2: line parity reg 2
69 * @reg3: line parity reg 3 69 * @reg3: line parity reg 3
70 * @ecc_code: ecc 70 * @ecc_code: ecc
71 * 71 *
72 * Creates non-inverted ECC code from line parity 72 * Creates non-inverted ECC code from line parity
73 */ 73 */
@@ -75,11 +75,11 @@ static void nand_trans_result(u_char reg2, u_char reg3,
75 u_char *ecc_code) 75 u_char *ecc_code)
76{ 76{
77 u_char a, b, i, tmp1, tmp2; 77 u_char a, b, i, tmp1, tmp2;
78 78
79 /* Initialize variables */ 79 /* Initialize variables */
80 a = b = 0x80; 80 a = b = 0x80;
81 tmp1 = tmp2 = 0; 81 tmp1 = tmp2 = 0;
82 82
83 /* Calculate first ECC byte */ 83 /* Calculate first ECC byte */
84 for (i = 0; i < 4; i++) { 84 for (i = 0; i < 4; i++) {
85 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ 85 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
@@ -90,7 +90,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
90 b >>= 1; 90 b >>= 1;
91 a >>= 1; 91 a >>= 1;
92 } 92 }
93 93
94 /* Calculate second ECC byte */ 94 /* Calculate second ECC byte */
95 b = 0x80; 95 b = 0x80;
96 for (i = 0; i < 4; i++) { 96 for (i = 0; i < 4; i++) {
@@ -102,7 +102,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
102 b >>= 1; 102 b >>= 1;
103 a >>= 1; 103 a >>= 1;
104 } 104 }
105 105
106 /* Store two of the ECC bytes */ 106 /* Store two of the ECC bytes */
107 ecc_code[0] = tmp1; 107 ecc_code[0] = tmp1;
108 ecc_code[1] = tmp2; 108 ecc_code[1] = tmp2;
@@ -118,28 +118,28 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
118{ 118{
119 u_char idx, reg1, reg2, reg3; 119 u_char idx, reg1, reg2, reg3;
120 int j; 120 int j;
121 121
122 /* Initialize variables */ 122 /* Initialize variables */
123 reg1 = reg2 = reg3 = 0; 123 reg1 = reg2 = reg3 = 0;
124 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; 124 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
125 125
126 /* Build up column parity */ 126 /* Build up column parity */
127 for(j = 0; j < 256; j++) { 127 for(j = 0; j < 256; j++) {
128 128
129 /* Get CP0 - CP5 from table */ 129 /* Get CP0 - CP5 from table */
130 idx = nand_ecc_precalc_table[dat[j]]; 130 idx = nand_ecc_precalc_table[dat[j]];
131 reg1 ^= (idx & 0x3f); 131 reg1 ^= (idx & 0x3f);
132 132
133 /* All bit XOR = 1 ? */ 133 /* All bit XOR = 1 ? */
134 if (idx & 0x40) { 134 if (idx & 0x40) {
135 reg3 ^= (u_char) j; 135 reg3 ^= (u_char) j;
136 reg2 ^= ~((u_char) j); 136 reg2 ^= ~((u_char) j);
137 } 137 }
138 } 138 }
139 139
140 /* Create non-inverted ECC code from line parity */ 140 /* Create non-inverted ECC code from line parity */
141 nand_trans_result(reg2, reg3, ecc_code); 141 nand_trans_result(reg2, reg3, ecc_code);
142 142
143 /* Calculate final ECC code */ 143 /* Calculate final ECC code */
144 ecc_code[0] = ~ecc_code[0]; 144 ecc_code[0] = ~ecc_code[0];
145 ecc_code[1] = ~ecc_code[1]; 145 ecc_code[1] = ~ecc_code[1];
@@ -159,12 +159,12 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
159int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) 159int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
160{ 160{
161 u_char a, b, c, d1, d2, d3, add, bit, i; 161 u_char a, b, c, d1, d2, d3, add, bit, i;
162 162
163 /* Do error detection */ 163 /* Do error detection */
164 d1 = calc_ecc[0] ^ read_ecc[0]; 164 d1 = calc_ecc[0] ^ read_ecc[0];
165 d2 = calc_ecc[1] ^ read_ecc[1]; 165 d2 = calc_ecc[1] ^ read_ecc[1];
166 d3 = calc_ecc[2] ^ read_ecc[2]; 166 d3 = calc_ecc[2] ^ read_ecc[2];
167 167
168 if ((d1 | d2 | d3) == 0) { 168 if ((d1 | d2 | d3) == 0) {
169 /* No errors */ 169 /* No errors */
170 return 0; 170 return 0;
@@ -173,7 +173,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
173 a = (d1 ^ (d1 >> 1)) & 0x55; 173 a = (d1 ^ (d1 >> 1)) & 0x55;
174 b = (d2 ^ (d2 >> 1)) & 0x55; 174 b = (d2 ^ (d2 >> 1)) & 0x55;
175 c = (d3 ^ (d3 >> 1)) & 0x54; 175 c = (d3 ^ (d3 >> 1)) & 0x54;
176 176
177 /* Found and will correct single bit error in the data */ 177 /* Found and will correct single bit error in the data */
178 if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { 178 if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
179 c = 0x80; 179 c = 0x80;
@@ -237,7 +237,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
237 } 237 }
238 } 238 }
239 } 239 }
240 240
241 /* Should never happen */ 241 /* Should never happen */
242 return -1; 242 return -1;
243} 243}
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index efe246961b69..dbc7e55a4247 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de) 4 * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)
5 * 5 *
6 * $Id: nand_ids.c,v 1.14 2005/06/23 09:38:50 gleixner Exp $ 6 * $Id: nand_ids.c,v 1.16 2005/11/07 11:14:31 gleixner Exp $
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -14,14 +14,14 @@
14#include <linux/mtd/nand.h> 14#include <linux/mtd/nand.h>
15/* 15/*
16* Chip ID list 16* Chip ID list
17* 17*
18* Name. ID code, pagesize, chipsize in MegaByte, eraseblock size, 18* Name. ID code, pagesize, chipsize in MegaByte, eraseblock size,
19* options 19* options
20* 20*
21* Pagesize; 0, 256, 512 21* Pagesize; 0, 256, 512
22* 0 get this information from the extended chip ID 22* 0 get this information from the extended chip ID
23+ 256 256 Byte page size 23+ 256 256 Byte page size
24* 512 512 Byte page size 24* 512 512 Byte page size
25*/ 25*/
26struct nand_flash_dev nand_flash_ids[] = { 26struct nand_flash_dev nand_flash_ids[] = {
27 {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0}, 27 {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0},
@@ -34,27 +34,27 @@ struct nand_flash_dev nand_flash_ids[] = {
34 {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0}, 34 {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0},
35 {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0}, 35 {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0},
36 {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0}, 36 {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0},
37 37
38 {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0}, 38 {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0},
39 {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0}, 39 {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0},
40 {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16}, 40 {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
41 {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16}, 41 {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},
42 42
43 {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0}, 43 {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0},
44 {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0}, 44 {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0},
45 {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16}, 45 {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},
46 {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16}, 46 {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},
47 47
48 {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0}, 48 {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0},
49 {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0}, 49 {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0},
50 {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16}, 50 {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},
51 {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16}, 51 {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},
52 52
53 {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0}, 53 {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0},
54 {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0}, 54 {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0},
55 {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16}, 55 {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},
56 {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16}, 56 {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
57 57
58 {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0}, 58 {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0},
59 {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0}, 59 {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0},
60 {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0}, 60 {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0},
@@ -62,7 +62,7 @@ struct nand_flash_dev nand_flash_ids[] = {
62 {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16}, 62 {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},
63 {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16}, 63 {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
64 {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16}, 64 {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},
65 65
66 {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0}, 66 {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0},
67 67
68 /* These are the new chips with large page size. The pagesize 68 /* These are the new chips with large page size. The pagesize
@@ -73,7 +73,7 @@ struct nand_flash_dev nand_flash_ids[] = {
73 {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 73 {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
74 {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 74 {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
75 {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 75 {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
76 76
77 /* 1 Gigabit */ 77 /* 1 Gigabit */
78 {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 78 {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
79 {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 79 {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
@@ -85,13 +85,13 @@ struct nand_flash_dev nand_flash_ids[] = {
85 {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 85 {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
86 {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 86 {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
87 {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 87 {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
88 88
89 /* 4 Gigabit */ 89 /* 4 Gigabit */
90 {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 90 {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
91 {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 91 {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
92 {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 92 {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
93 {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 93 {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
94 94
95 /* 8 Gigabit */ 95 /* 8 Gigabit */
96 {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 96 {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
97 {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 97 {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
@@ -104,11 +104,11 @@ struct nand_flash_dev nand_flash_ids[] = {
104 {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 104 {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
105 {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 105 {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
106 106
107 /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout ! 107 /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout !
108 * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes 108 * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes
109 * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 109 * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7
110 * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go 110 * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go
111 * There are more speed improvements for reads and writes possible, but not implemented now 111 * There are more speed improvements for reads and writes possible, but not implemented now
112 */ 112 */
113 {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH}, 113 {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},
114 114
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index 754b6ed7ce14..de4500395300 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Author: Artem B. Bityuckiy <dedekind@oktetlabs.ru>, <dedekind@infradead.org> 4 * Author: Artem B. Bityuckiy <dedekind@oktetlabs.ru>, <dedekind@infradead.org>
5 * 5 *
6 * Copyright (C) 2004 Nokia Corporation 6 * Copyright (C) 2004 Nokia Corporation
7 * 7 *
8 * Note: NS means "NAND Simulator". 8 * Note: NS means "NAND Simulator".
9 * Note: Input means input TO flash chip, output means output FROM chip. 9 * Note: Input means input TO flash chip, output means output FROM chip.
@@ -126,7 +126,7 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
126 126
127/* The largest possible page size */ 127/* The largest possible page size */
128#define NS_LARGEST_PAGE_SIZE 2048 128#define NS_LARGEST_PAGE_SIZE 2048
129 129
130/* The prefix for simulator output */ 130/* The prefix for simulator output */
131#define NS_OUTPUT_PREFIX "[nandsim]" 131#define NS_OUTPUT_PREFIX "[nandsim]"
132 132
@@ -145,7 +145,7 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
145 do { if (do_delays) udelay(us); } while(0) 145 do { if (do_delays) udelay(us); } while(0)
146#define NS_MDELAY(us) \ 146#define NS_MDELAY(us) \
147 do { if (do_delays) mdelay(us); } while(0) 147 do { if (do_delays) mdelay(us); } while(0)
148 148
149/* Is the nandsim structure initialized ? */ 149/* Is the nandsim structure initialized ? */
150#define NS_IS_INITIALIZED(ns) ((ns)->geom.totsz != 0) 150#define NS_IS_INITIALIZED(ns) ((ns)->geom.totsz != 0)
151 151
@@ -153,12 +153,12 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
153#define NS_STATUS_OK(ns) (NAND_STATUS_READY | (NAND_STATUS_WP * ((ns)->lines.wp == 0))) 153#define NS_STATUS_OK(ns) (NAND_STATUS_READY | (NAND_STATUS_WP * ((ns)->lines.wp == 0)))
154 154
155/* Operation failed completion status */ 155/* Operation failed completion status */
156#define NS_STATUS_FAILED(ns) (NAND_STATUS_FAIL | NS_STATUS_OK(ns)) 156#define NS_STATUS_FAILED(ns) (NAND_STATUS_FAIL | NS_STATUS_OK(ns))
157 157
158/* Calculate the page offset in flash RAM image by (row, column) address */ 158/* Calculate the page offset in flash RAM image by (row, column) address */
159#define NS_RAW_OFFSET(ns) \ 159#define NS_RAW_OFFSET(ns) \
160 (((ns)->regs.row << (ns)->geom.pgshift) + ((ns)->regs.row * (ns)->geom.oobsz) + (ns)->regs.column) 160 (((ns)->regs.row << (ns)->geom.pgshift) + ((ns)->regs.row * (ns)->geom.oobsz) + (ns)->regs.column)
161 161
162/* Calculate the OOB offset in flash RAM image by (row, column) address */ 162/* Calculate the OOB offset in flash RAM image by (row, column) address */
163#define NS_RAW_OFFSET_OOB(ns) (NS_RAW_OFFSET(ns) + ns->geom.pgsz) 163#define NS_RAW_OFFSET_OOB(ns) (NS_RAW_OFFSET(ns) + ns->geom.pgsz)
164 164
@@ -223,15 +223,15 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
223 223
224/* Remove action bits ftom state */ 224/* Remove action bits ftom state */
225#define NS_STATE(x) ((x) & ~ACTION_MASK) 225#define NS_STATE(x) ((x) & ~ACTION_MASK)
226 226
227/* 227/*
228 * Maximum previous states which need to be saved. Currently saving is 228 * Maximum previous states which need to be saved. Currently saving is
229 * only needed for page programm operation with preceeded read command 229 * only needed for page programm operation with preceeded read command
230 * (which is only valid for 512-byte pages). 230 * (which is only valid for 512-byte pages).
231 */ 231 */
232#define NS_MAX_PREVSTATES 1 232#define NS_MAX_PREVSTATES 1
233 233
234/* 234/*
235 * The structure which describes all the internal simulator data. 235 * The structure which describes all the internal simulator data.
236 */ 236 */
237struct nandsim { 237struct nandsim {
@@ -242,7 +242,7 @@ struct nandsim {
242 uint32_t options; /* chip's characteristic bits */ 242 uint32_t options; /* chip's characteristic bits */
243 uint32_t state; /* current chip state */ 243 uint32_t state; /* current chip state */
244 uint32_t nxstate; /* next expected state */ 244 uint32_t nxstate; /* next expected state */
245 245
246 uint32_t *op; /* current operation, NULL operations isn't known yet */ 246 uint32_t *op; /* current operation, NULL operations isn't known yet */
247 uint32_t pstates[NS_MAX_PREVSTATES]; /* previous states */ 247 uint32_t pstates[NS_MAX_PREVSTATES]; /* previous states */
248 uint16_t npstates; /* number of previous states saved */ 248 uint16_t npstates; /* number of previous states saved */
@@ -413,7 +413,7 @@ init_nandsim(struct mtd_info *mtd)
413 ns->geom.secaddrbytes = 3; 413 ns->geom.secaddrbytes = 3;
414 } 414 }
415 } 415 }
416 416
417 /* Detect how many ID bytes the NAND chip outputs */ 417 /* Detect how many ID bytes the NAND chip outputs */
418 for (i = 0; nand_flash_ids[i].name != NULL; i++) { 418 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
419 if (second_id_byte != nand_flash_ids[i].id) 419 if (second_id_byte != nand_flash_ids[i].id)
@@ -444,7 +444,7 @@ init_nandsim(struct mtd_info *mtd)
444#ifdef CONFIG_NS_ABS_POS 444#ifdef CONFIG_NS_ABS_POS
445 ns->mem.byte = ioremap(CONFIG_NS_ABS_POS, ns->geom.totszoob); 445 ns->mem.byte = ioremap(CONFIG_NS_ABS_POS, ns->geom.totszoob);
446 if (!ns->mem.byte) { 446 if (!ns->mem.byte) {
447 NS_ERR("init_nandsim: failed to map the NAND flash image at address %p\n", 447 NS_ERR("init_nandsim: failed to map the NAND flash image at address %p\n",
448 (void *)CONFIG_NS_ABS_POS); 448 (void *)CONFIG_NS_ABS_POS);
449 return -ENOMEM; 449 return -ENOMEM;
450 } 450 }
@@ -567,7 +567,7 @@ static int
567check_command(int cmd) 567check_command(int cmd)
568{ 568{
569 switch (cmd) { 569 switch (cmd) {
570 570
571 case NAND_CMD_READ0: 571 case NAND_CMD_READ0:
572 case NAND_CMD_READSTART: 572 case NAND_CMD_READSTART:
573 case NAND_CMD_PAGEPROG: 573 case NAND_CMD_PAGEPROG:
@@ -580,7 +580,7 @@ check_command(int cmd)
580 case NAND_CMD_RESET: 580 case NAND_CMD_RESET:
581 case NAND_CMD_READ1: 581 case NAND_CMD_READ1:
582 return 0; 582 return 0;
583 583
584 case NAND_CMD_STATUS_MULTI: 584 case NAND_CMD_STATUS_MULTI:
585 default: 585 default:
586 return 1; 586 return 1;
@@ -631,7 +631,7 @@ static inline void
631accept_addr_byte(struct nandsim *ns, u_char bt) 631accept_addr_byte(struct nandsim *ns, u_char bt)
632{ 632{
633 uint byte = (uint)bt; 633 uint byte = (uint)bt;
634 634
635 if (ns->regs.count < (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) 635 if (ns->regs.count < (ns->geom.pgaddrbytes - ns->geom.secaddrbytes))
636 ns->regs.column |= (byte << 8 * ns->regs.count); 636 ns->regs.column |= (byte << 8 * ns->regs.count);
637 else { 637 else {
@@ -642,11 +642,11 @@ accept_addr_byte(struct nandsim *ns, u_char bt)
642 642
643 return; 643 return;
644} 644}
645 645
646/* 646/*
647 * Switch to STATE_READY state. 647 * Switch to STATE_READY state.
648 */ 648 */
649static inline void 649static inline void
650switch_to_ready_state(struct nandsim *ns, u_char status) 650switch_to_ready_state(struct nandsim *ns, u_char status)
651{ 651{
652 NS_DBG("switch_to_ready_state: switch to %s state\n", get_state_name(STATE_READY)); 652 NS_DBG("switch_to_ready_state: switch to %s state\n", get_state_name(STATE_READY));
@@ -675,7 +675,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status)
675 * (for example program from the second half and read from the 675 * (for example program from the second half and read from the
676 * second half operations both begin with the READ1 command). In this 676 * second half operations both begin with the READ1 command). In this
677 * case the ns->pstates[] array contains previous states. 677 * case the ns->pstates[] array contains previous states.
678 * 678 *
679 * Thus, the function tries to find operation containing the following 679 * Thus, the function tries to find operation containing the following
680 * states (if the 'flag' parameter is 0): 680 * states (if the 'flag' parameter is 0):
681 * ns->pstates[0], ... ns->pstates[ns->npstates], ns->state 681 * ns->pstates[0], ... ns->pstates[ns->npstates], ns->state
@@ -683,7 +683,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status)
683 * If (one and only one) matching operation is found, it is accepted ( 683 * If (one and only one) matching operation is found, it is accepted (
684 * ns->ops, ns->state, ns->nxstate are initialized, ns->npstate is 684 * ns->ops, ns->state, ns->nxstate are initialized, ns->npstate is
685 * zeroed). 685 * zeroed).
686 * 686 *
687 * If there are several maches, the current state is pushed to the 687 * If there are several maches, the current state is pushed to the
688 * ns->pstates. 688 * ns->pstates.
689 * 689 *
@@ -692,7 +692,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status)
692 * In such situation the function is called with 'flag' != 0, and the 692 * In such situation the function is called with 'flag' != 0, and the
693 * operation is searched using the following pattern: 693 * operation is searched using the following pattern:
694 * ns->pstates[0], ... ns->pstates[ns->npstates], <address input> 694 * ns->pstates[0], ... ns->pstates[ns->npstates], <address input>
695 * 695 *
696 * It is supposed that this pattern must either match one operation on 696 * It is supposed that this pattern must either match one operation on
697 * none. There can't be ambiguity in that case. 697 * none. There can't be ambiguity in that case.
698 * 698 *
@@ -711,15 +711,15 @@ find_operation(struct nandsim *ns, uint32_t flag)
711{ 711{
712 int opsfound = 0; 712 int opsfound = 0;
713 int i, j, idx = 0; 713 int i, j, idx = 0;
714 714
715 for (i = 0; i < NS_OPER_NUM; i++) { 715 for (i = 0; i < NS_OPER_NUM; i++) {
716 716
717 int found = 1; 717 int found = 1;
718 718
719 if (!(ns->options & ops[i].reqopts)) 719 if (!(ns->options & ops[i].reqopts))
720 /* Ignore operations we can't perform */ 720 /* Ignore operations we can't perform */
721 continue; 721 continue;
722 722
723 if (flag) { 723 if (flag) {
724 if (!(ops[i].states[ns->npstates] & STATE_ADDR_MASK)) 724 if (!(ops[i].states[ns->npstates] & STATE_ADDR_MASK))
725 continue; 725 continue;
@@ -728,7 +728,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
728 continue; 728 continue;
729 } 729 }
730 730
731 for (j = 0; j < ns->npstates; j++) 731 for (j = 0; j < ns->npstates; j++)
732 if (NS_STATE(ops[i].states[j]) != NS_STATE(ns->pstates[j]) 732 if (NS_STATE(ops[i].states[j]) != NS_STATE(ns->pstates[j])
733 && (ns->options & ops[idx].reqopts)) { 733 && (ns->options & ops[idx].reqopts)) {
734 found = 0; 734 found = 0;
@@ -745,7 +745,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
745 /* Exact match */ 745 /* Exact match */
746 ns->op = &ops[idx].states[0]; 746 ns->op = &ops[idx].states[0];
747 if (flag) { 747 if (flag) {
748 /* 748 /*
749 * In this case the find_operation function was 749 * In this case the find_operation function was
750 * called when address has just began input. But it isn't 750 * called when address has just began input. But it isn't
751 * yet fully input and the current state must 751 * yet fully input and the current state must
@@ -763,7 +763,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
763 idx, get_state_name(ns->state), get_state_name(ns->nxstate)); 763 idx, get_state_name(ns->state), get_state_name(ns->nxstate));
764 return 0; 764 return 0;
765 } 765 }
766 766
767 if (opsfound == 0) { 767 if (opsfound == 0) {
768 /* Nothing was found. Try to ignore previous commands (if any) and search again */ 768 /* Nothing was found. Try to ignore previous commands (if any) and search again */
769 if (ns->npstates != 0) { 769 if (ns->npstates != 0) {
@@ -777,13 +777,13 @@ find_operation(struct nandsim *ns, uint32_t flag)
777 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 777 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
778 return -2; 778 return -2;
779 } 779 }
780 780
781 if (flag) { 781 if (flag) {
782 /* This shouldn't happen */ 782 /* This shouldn't happen */
783 NS_DBG("find_operation: BUG, operation must be known if address is input\n"); 783 NS_DBG("find_operation: BUG, operation must be known if address is input\n");
784 return -2; 784 return -2;
785 } 785 }
786 786
787 NS_DBG("find_operation: there is still ambiguity\n"); 787 NS_DBG("find_operation: there is still ambiguity\n");
788 788
789 ns->pstates[ns->npstates++] = ns->state; 789 ns->pstates[ns->npstates++] = ns->state;
@@ -803,7 +803,7 @@ do_state_action(struct nandsim *ns, uint32_t action)
803 int busdiv = ns->busw == 8 ? 1 : 2; 803 int busdiv = ns->busw == 8 ? 1 : 2;
804 804
805 action &= ACTION_MASK; 805 action &= ACTION_MASK;
806 806
807 /* Check that page address input is correct */ 807 /* Check that page address input is correct */
808 if (action != ACTION_SECERASE && ns->regs.row >= ns->geom.pgnum) { 808 if (action != ACTION_SECERASE && ns->regs.row >= ns->geom.pgnum) {
809 NS_WARN("do_state_action: wrong page number (%#x)\n", ns->regs.row); 809 NS_WARN("do_state_action: wrong page number (%#x)\n", ns->regs.row);
@@ -827,14 +827,14 @@ do_state_action(struct nandsim *ns, uint32_t action)
827 827
828 NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int buf, raw offset %d\n", 828 NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int buf, raw offset %d\n",
829 num, NS_RAW_OFFSET(ns) + ns->regs.off); 829 num, NS_RAW_OFFSET(ns) + ns->regs.off);
830 830
831 if (ns->regs.off == 0) 831 if (ns->regs.off == 0)
832 NS_LOG("read page %d\n", ns->regs.row); 832 NS_LOG("read page %d\n", ns->regs.row);
833 else if (ns->regs.off < ns->geom.pgsz) 833 else if (ns->regs.off < ns->geom.pgsz)
834 NS_LOG("read page %d (second half)\n", ns->regs.row); 834 NS_LOG("read page %d (second half)\n", ns->regs.row);
835 else 835 else
836 NS_LOG("read OOB of page %d\n", ns->regs.row); 836 NS_LOG("read OOB of page %d\n", ns->regs.row);
837 837
838 NS_UDELAY(access_delay); 838 NS_UDELAY(access_delay);
839 NS_UDELAY(input_cycle * ns->geom.pgsz / 1000 / busdiv); 839 NS_UDELAY(input_cycle * ns->geom.pgsz / 1000 / busdiv);
840 840
@@ -844,30 +844,30 @@ do_state_action(struct nandsim *ns, uint32_t action)
844 /* 844 /*
845 * Erase sector. 845 * Erase sector.
846 */ 846 */
847 847
848 if (ns->lines.wp) { 848 if (ns->lines.wp) {
849 NS_ERR("do_state_action: device is write-protected, ignore sector erase\n"); 849 NS_ERR("do_state_action: device is write-protected, ignore sector erase\n");
850 return -1; 850 return -1;
851 } 851 }
852 852
853 if (ns->regs.row >= ns->geom.pgnum - ns->geom.pgsec 853 if (ns->regs.row >= ns->geom.pgnum - ns->geom.pgsec
854 || (ns->regs.row & ~(ns->geom.secsz - 1))) { 854 || (ns->regs.row & ~(ns->geom.secsz - 1))) {
855 NS_ERR("do_state_action: wrong sector address (%#x)\n", ns->regs.row); 855 NS_ERR("do_state_action: wrong sector address (%#x)\n", ns->regs.row);
856 return -1; 856 return -1;
857 } 857 }
858 858
859 ns->regs.row = (ns->regs.row << 859 ns->regs.row = (ns->regs.row <<
860 8 * (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) | ns->regs.column; 860 8 * (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) | ns->regs.column;
861 ns->regs.column = 0; 861 ns->regs.column = 0;
862 862
863 NS_DBG("do_state_action: erase sector at address %#x, off = %d\n", 863 NS_DBG("do_state_action: erase sector at address %#x, off = %d\n",
864 ns->regs.row, NS_RAW_OFFSET(ns)); 864 ns->regs.row, NS_RAW_OFFSET(ns));
865 NS_LOG("erase sector %d\n", ns->regs.row >> (ns->geom.secshift - ns->geom.pgshift)); 865 NS_LOG("erase sector %d\n", ns->regs.row >> (ns->geom.secshift - ns->geom.pgshift));
866 866
867 memset(ns->mem.byte + NS_RAW_OFFSET(ns), 0xFF, ns->geom.secszoob); 867 memset(ns->mem.byte + NS_RAW_OFFSET(ns), 0xFF, ns->geom.secszoob);
868 868
869 NS_MDELAY(erase_delay); 869 NS_MDELAY(erase_delay);
870 870
871 break; 871 break;
872 872
873 case ACTION_PRGPAGE: 873 case ACTION_PRGPAGE:
@@ -893,12 +893,12 @@ do_state_action(struct nandsim *ns, uint32_t action)
893 NS_DBG("do_state_action: copy %d bytes from int buf to (%#x, %#x), raw off = %d\n", 893 NS_DBG("do_state_action: copy %d bytes from int buf to (%#x, %#x), raw off = %d\n",
894 num, ns->regs.row, ns->regs.column, NS_RAW_OFFSET(ns) + ns->regs.off); 894 num, ns->regs.row, ns->regs.column, NS_RAW_OFFSET(ns) + ns->regs.off);
895 NS_LOG("programm page %d\n", ns->regs.row); 895 NS_LOG("programm page %d\n", ns->regs.row);
896 896
897 NS_UDELAY(programm_delay); 897 NS_UDELAY(programm_delay);
898 NS_UDELAY(output_cycle * ns->geom.pgsz / 1000 / busdiv); 898 NS_UDELAY(output_cycle * ns->geom.pgsz / 1000 / busdiv);
899 899
900 break; 900 break;
901 901
902 case ACTION_ZEROOFF: 902 case ACTION_ZEROOFF:
903 NS_DBG("do_state_action: set internal offset to 0\n"); 903 NS_DBG("do_state_action: set internal offset to 0\n");
904 ns->regs.off = 0; 904 ns->regs.off = 0;
@@ -918,7 +918,7 @@ do_state_action(struct nandsim *ns, uint32_t action)
918 NS_DBG("do_state_action: set internal offset to %d\n", ns->geom.pgsz); 918 NS_DBG("do_state_action: set internal offset to %d\n", ns->geom.pgsz);
919 ns->regs.off = ns->geom.pgsz; 919 ns->regs.off = ns->geom.pgsz;
920 break; 920 break;
921 921
922 default: 922 default:
923 NS_DBG("do_state_action: BUG! unknown action\n"); 923 NS_DBG("do_state_action: BUG! unknown action\n");
924 } 924 }
@@ -937,7 +937,7 @@ switch_state(struct nandsim *ns)
937 * The current operation have already been identified. 937 * The current operation have already been identified.
938 * Just follow the states chain. 938 * Just follow the states chain.
939 */ 939 */
940 940
941 ns->stateidx += 1; 941 ns->stateidx += 1;
942 ns->state = ns->nxstate; 942 ns->state = ns->nxstate;
943 ns->nxstate = ns->op[ns->stateidx + 1]; 943 ns->nxstate = ns->op[ns->stateidx + 1];
@@ -951,14 +951,14 @@ switch_state(struct nandsim *ns)
951 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 951 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
952 return; 952 return;
953 } 953 }
954 954
955 } else { 955 } else {
956 /* 956 /*
957 * We don't yet know which operation we perform. 957 * We don't yet know which operation we perform.
958 * Try to identify it. 958 * Try to identify it.
959 */ 959 */
960 960
961 /* 961 /*
962 * The only event causing the switch_state function to 962 * The only event causing the switch_state function to
963 * be called with yet unknown operation is new command. 963 * be called with yet unknown operation is new command.
964 */ 964 */
@@ -987,7 +987,7 @@ switch_state(struct nandsim *ns)
987 */ 987 */
988 988
989 u_char status = NS_STATUS_OK(ns); 989 u_char status = NS_STATUS_OK(ns);
990 990
991 /* In case of data states, see if all bytes were input/output */ 991 /* In case of data states, see if all bytes were input/output */
992 if ((ns->state & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) 992 if ((ns->state & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK))
993 && ns->regs.count != ns->regs.num) { 993 && ns->regs.count != ns->regs.num) {
@@ -995,17 +995,17 @@ switch_state(struct nandsim *ns)
995 ns->regs.num - ns->regs.count); 995 ns->regs.num - ns->regs.count);
996 status = NS_STATUS_FAILED(ns); 996 status = NS_STATUS_FAILED(ns);
997 } 997 }
998 998
999 NS_DBG("switch_state: operation complete, switch to STATE_READY state\n"); 999 NS_DBG("switch_state: operation complete, switch to STATE_READY state\n");
1000 1000
1001 switch_to_ready_state(ns, status); 1001 switch_to_ready_state(ns, status);
1002 1002
1003 return; 1003 return;
1004 } else if (ns->nxstate & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) { 1004 } else if (ns->nxstate & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) {
1005 /* 1005 /*
1006 * If the next state is data input/output, switch to it now 1006 * If the next state is data input/output, switch to it now
1007 */ 1007 */
1008 1008
1009 ns->state = ns->nxstate; 1009 ns->state = ns->nxstate;
1010 ns->nxstate = ns->op[++ns->stateidx + 1]; 1010 ns->nxstate = ns->op[++ns->stateidx + 1];
1011 ns->regs.num = ns->regs.count = 0; 1011 ns->regs.num = ns->regs.count = 0;
@@ -1023,16 +1023,16 @@ switch_state(struct nandsim *ns)
1023 case STATE_DATAOUT: 1023 case STATE_DATAOUT:
1024 ns->regs.num = ns->geom.pgszoob - ns->regs.off - ns->regs.column; 1024 ns->regs.num = ns->geom.pgszoob - ns->regs.off - ns->regs.column;
1025 break; 1025 break;
1026 1026
1027 case STATE_DATAOUT_ID: 1027 case STATE_DATAOUT_ID:
1028 ns->regs.num = ns->geom.idbytes; 1028 ns->regs.num = ns->geom.idbytes;
1029 break; 1029 break;
1030 1030
1031 case STATE_DATAOUT_STATUS: 1031 case STATE_DATAOUT_STATUS:
1032 case STATE_DATAOUT_STATUS_M: 1032 case STATE_DATAOUT_STATUS_M:
1033 ns->regs.count = ns->regs.num = 0; 1033 ns->regs.count = ns->regs.num = 0;
1034 break; 1034 break;
1035 1035
1036 default: 1036 default:
1037 NS_ERR("switch_state: BUG! unknown data state\n"); 1037 NS_ERR("switch_state: BUG! unknown data state\n");
1038 } 1038 }
@@ -1044,16 +1044,16 @@ switch_state(struct nandsim *ns)
1044 */ 1044 */
1045 1045
1046 ns->regs.count = 0; 1046 ns->regs.count = 0;
1047 1047
1048 switch (NS_STATE(ns->nxstate)) { 1048 switch (NS_STATE(ns->nxstate)) {
1049 case STATE_ADDR_PAGE: 1049 case STATE_ADDR_PAGE:
1050 ns->regs.num = ns->geom.pgaddrbytes; 1050 ns->regs.num = ns->geom.pgaddrbytes;
1051 1051
1052 break; 1052 break;
1053 case STATE_ADDR_SEC: 1053 case STATE_ADDR_SEC:
1054 ns->regs.num = ns->geom.secaddrbytes; 1054 ns->regs.num = ns->geom.secaddrbytes;
1055 break; 1055 break;
1056 1056
1057 case STATE_ADDR_ZERO: 1057 case STATE_ADDR_ZERO:
1058 ns->regs.num = 1; 1058 ns->regs.num = 1;
1059 break; 1059 break;
@@ -1062,7 +1062,7 @@ switch_state(struct nandsim *ns)
1062 NS_ERR("switch_state: BUG! unknown address state\n"); 1062 NS_ERR("switch_state: BUG! unknown address state\n");
1063 } 1063 }
1064 } else { 1064 } else {
1065 /* 1065 /*
1066 * Just reset internal counters. 1066 * Just reset internal counters.
1067 */ 1067 */
1068 1068
@@ -1184,7 +1184,7 @@ ns_nand_read_byte(struct mtd_info *mtd)
1184 default: 1184 default:
1185 BUG(); 1185 BUG();
1186 } 1186 }
1187 1187
1188 if (ns->regs.count == ns->regs.num) { 1188 if (ns->regs.count == ns->regs.num) {
1189 NS_DBG("read_byte: all bytes were read\n"); 1189 NS_DBG("read_byte: all bytes were read\n");
1190 1190
@@ -1201,9 +1201,9 @@ ns_nand_read_byte(struct mtd_info *mtd)
1201 } 1201 }
1202 else if (NS_STATE(ns->nxstate) == STATE_READY) 1202 else if (NS_STATE(ns->nxstate) == STATE_READY)
1203 switch_state(ns); 1203 switch_state(ns);
1204 1204
1205 } 1205 }
1206 1206
1207 return outb; 1207 return outb;
1208} 1208}
1209 1209
@@ -1211,7 +1211,7 @@ static void
1211ns_nand_write_byte(struct mtd_info *mtd, u_char byte) 1211ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1212{ 1212{
1213 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; 1213 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
1214 1214
1215 /* Sanity and correctness checks */ 1215 /* Sanity and correctness checks */
1216 if (!ns->lines.ce) { 1216 if (!ns->lines.ce) {
1217 NS_ERR("write_byte: chip is disabled, ignore write\n"); 1217 NS_ERR("write_byte: chip is disabled, ignore write\n");
@@ -1221,7 +1221,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1221 NS_ERR("write_byte: ALE and CLE pins are high simultaneously, ignore write\n"); 1221 NS_ERR("write_byte: ALE and CLE pins are high simultaneously, ignore write\n");
1222 return; 1222 return;
1223 } 1223 }
1224 1224
1225 if (ns->lines.cle == 1) { 1225 if (ns->lines.cle == 1) {
1226 /* 1226 /*
1227 * The byte written is a command. 1227 * The byte written is a command.
@@ -1233,7 +1233,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1233 return; 1233 return;
1234 } 1234 }
1235 1235
1236 /* 1236 /*
1237 * Chip might still be in STATE_DATAOUT 1237 * Chip might still be in STATE_DATAOUT
1238 * (if OPT_AUTOINCR feature is supported), STATE_DATAOUT_STATUS or 1238 * (if OPT_AUTOINCR feature is supported), STATE_DATAOUT_STATUS or
1239 * STATE_DATAOUT_STATUS_M state. If so, switch state. 1239 * STATE_DATAOUT_STATUS_M state. If so, switch state.
@@ -1254,13 +1254,13 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1254 "ignore previous states\n", (uint)byte, get_state_name(ns->nxstate)); 1254 "ignore previous states\n", (uint)byte, get_state_name(ns->nxstate));
1255 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 1255 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
1256 } 1256 }
1257 1257
1258 /* Check that the command byte is correct */ 1258 /* Check that the command byte is correct */
1259 if (check_command(byte)) { 1259 if (check_command(byte)) {
1260 NS_ERR("write_byte: unknown command %#x\n", (uint)byte); 1260 NS_ERR("write_byte: unknown command %#x\n", (uint)byte);
1261 return; 1261 return;
1262 } 1262 }
1263 1263
1264 NS_DBG("command byte corresponding to %s state accepted\n", 1264 NS_DBG("command byte corresponding to %s state accepted\n",
1265 get_state_name(get_state_by_command(byte))); 1265 get_state_name(get_state_by_command(byte)));
1266 ns->regs.command = byte; 1266 ns->regs.command = byte;
@@ -1277,12 +1277,12 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1277 1277
1278 if (find_operation(ns, 1) < 0) 1278 if (find_operation(ns, 1) < 0)
1279 return; 1279 return;
1280 1280
1281 if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) { 1281 if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) {
1282 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 1282 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
1283 return; 1283 return;
1284 } 1284 }
1285 1285
1286 ns->regs.count = 0; 1286 ns->regs.count = 0;
1287 switch (NS_STATE(ns->nxstate)) { 1287 switch (NS_STATE(ns->nxstate)) {
1288 case STATE_ADDR_PAGE: 1288 case STATE_ADDR_PAGE:
@@ -1306,7 +1306,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1306 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 1306 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
1307 return; 1307 return;
1308 } 1308 }
1309 1309
1310 /* Check if this is expected byte */ 1310 /* Check if this is expected byte */
1311 if (ns->regs.count == ns->regs.num) { 1311 if (ns->regs.count == ns->regs.num) {
1312 NS_ERR("write_byte: no more address bytes expected\n"); 1312 NS_ERR("write_byte: no more address bytes expected\n");
@@ -1325,12 +1325,12 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1325 NS_DBG("address (%#x, %#x) is accepted\n", ns->regs.row, ns->regs.column); 1325 NS_DBG("address (%#x, %#x) is accepted\n", ns->regs.row, ns->regs.column);
1326 switch_state(ns); 1326 switch_state(ns);
1327 } 1327 }
1328 1328
1329 } else { 1329 } else {
1330 /* 1330 /*
1331 * The byte written is an input data. 1331 * The byte written is an input data.
1332 */ 1332 */
1333 1333
1334 /* Check that chip is expecting data input */ 1334 /* Check that chip is expecting data input */
1335 if (!(ns->state & STATE_DATAIN_MASK)) { 1335 if (!(ns->state & STATE_DATAIN_MASK)) {
1336 NS_ERR("write_byte: data input (%#x) isn't expected, state is %s, " 1336 NS_ERR("write_byte: data input (%#x) isn't expected, state is %s, "
@@ -1372,7 +1372,7 @@ ns_nand_read_word(struct mtd_info *mtd)
1372 struct nand_chip *chip = (struct nand_chip *)mtd->priv; 1372 struct nand_chip *chip = (struct nand_chip *)mtd->priv;
1373 1373
1374 NS_DBG("read_word\n"); 1374 NS_DBG("read_word\n");
1375 1375
1376 return chip->read_byte(mtd) | (chip->read_byte(mtd) << 8); 1376 return chip->read_byte(mtd) | (chip->read_byte(mtd) << 8);
1377} 1377}
1378 1378
@@ -1380,14 +1380,14 @@ static void
1380ns_nand_write_word(struct mtd_info *mtd, uint16_t word) 1380ns_nand_write_word(struct mtd_info *mtd, uint16_t word)
1381{ 1381{
1382 struct nand_chip *chip = (struct nand_chip *)mtd->priv; 1382 struct nand_chip *chip = (struct nand_chip *)mtd->priv;
1383 1383
1384 NS_DBG("write_word\n"); 1384 NS_DBG("write_word\n");
1385 1385
1386 chip->write_byte(mtd, word & 0xFF); 1386 chip->write_byte(mtd, word & 0xFF);
1387 chip->write_byte(mtd, word >> 8); 1387 chip->write_byte(mtd, word >> 8);
1388} 1388}
1389 1389
1390static void 1390static void
1391ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) 1391ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
1392{ 1392{
1393 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; 1393 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
@@ -1409,13 +1409,13 @@ ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
1409 1409
1410 memcpy(ns->buf.byte + ns->regs.count, buf, len); 1410 memcpy(ns->buf.byte + ns->regs.count, buf, len);
1411 ns->regs.count += len; 1411 ns->regs.count += len;
1412 1412
1413 if (ns->regs.count == ns->regs.num) { 1413 if (ns->regs.count == ns->regs.num) {
1414 NS_DBG("write_buf: %d bytes were written\n", ns->regs.count); 1414 NS_DBG("write_buf: %d bytes were written\n", ns->regs.count);
1415 } 1415 }
1416} 1416}
1417 1417
1418static void 1418static void
1419ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) 1419ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
1420{ 1420{
1421 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; 1421 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
@@ -1453,7 +1453,7 @@ ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
1453 1453
1454 memcpy(buf, ns->buf.byte + ns->regs.count, len); 1454 memcpy(buf, ns->buf.byte + ns->regs.count, len);
1455 ns->regs.count += len; 1455 ns->regs.count += len;
1456 1456
1457 if (ns->regs.count == ns->regs.num) { 1457 if (ns->regs.count == ns->regs.num) {
1458 if ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT) { 1458 if ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT) {
1459 ns->regs.count = 0; 1459 ns->regs.count = 0;
@@ -1465,11 +1465,11 @@ ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
1465 else if (NS_STATE(ns->nxstate) == STATE_READY) 1465 else if (NS_STATE(ns->nxstate) == STATE_READY)
1466 switch_state(ns); 1466 switch_state(ns);
1467 } 1467 }
1468 1468
1469 return; 1469 return;
1470} 1470}
1471 1471
1472static int 1472static int
1473ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) 1473ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
1474{ 1474{
1475 ns_nand_read_buf(mtd, (u_char *)&ns_verify_buf[0], len); 1475 ns_nand_read_buf(mtd, (u_char *)&ns_verify_buf[0], len);
@@ -1496,7 +1496,7 @@ int __init ns_init_module(void)
1496 NS_ERR("wrong bus width (%d), use only 8 or 16\n", bus_width); 1496 NS_ERR("wrong bus width (%d), use only 8 or 16\n", bus_width);
1497 return -EINVAL; 1497 return -EINVAL;
1498 } 1498 }
1499 1499
1500 /* Allocate and initialize mtd_info, nand_chip and nandsim structures */ 1500 /* Allocate and initialize mtd_info, nand_chip and nandsim structures */
1501 nsmtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip) 1501 nsmtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip)
1502 + sizeof(struct nandsim), GFP_KERNEL); 1502 + sizeof(struct nandsim), GFP_KERNEL);
@@ -1509,7 +1509,7 @@ int __init ns_init_module(void)
1509 chip = (struct nand_chip *)(nsmtd + 1); 1509 chip = (struct nand_chip *)(nsmtd + 1);
1510 nsmtd->priv = (void *)chip; 1510 nsmtd->priv = (void *)chip;
1511 nand = (struct nandsim *)(chip + 1); 1511 nand = (struct nandsim *)(chip + 1);
1512 chip->priv = (void *)nand; 1512 chip->priv = (void *)nand;
1513 1513
1514 /* 1514 /*
1515 * Register simulator's callbacks. 1515 * Register simulator's callbacks.
@@ -1526,9 +1526,9 @@ int __init ns_init_module(void)
1526 chip->eccmode = NAND_ECC_SOFT; 1526 chip->eccmode = NAND_ECC_SOFT;
1527 chip->options |= NAND_SKIP_BBTSCAN; 1527 chip->options |= NAND_SKIP_BBTSCAN;
1528 1528
1529 /* 1529 /*
1530 * Perform minimum nandsim structure initialization to handle 1530 * Perform minimum nandsim structure initialization to handle
1531 * the initial ID read command correctly 1531 * the initial ID read command correctly
1532 */ 1532 */
1533 if (third_id_byte != 0xFF || fourth_id_byte != 0xFF) 1533 if (third_id_byte != 0xFF || fourth_id_byte != 0xFF)
1534 nand->geom.idbytes = 4; 1534 nand->geom.idbytes = 4;
@@ -1557,7 +1557,7 @@ int __init ns_init_module(void)
1557 NS_ERR("scan_bbt: can't initialize the nandsim structure\n"); 1557 NS_ERR("scan_bbt: can't initialize the nandsim structure\n");
1558 goto error; 1558 goto error;
1559 } 1559 }
1560 1560
1561 if ((retval = nand_default_bbt(nsmtd)) != 0) { 1561 if ((retval = nand_default_bbt(nsmtd)) != 0) {
1562 free_nandsim(nand); 1562 free_nandsim(nand);
1563 goto error; 1563 goto error;
diff --git a/drivers/mtd/nand/ppchameleonevb.c b/drivers/mtd/nand/ppchameleonevb.c
index e510a83d7bdb..91a95f34a6ee 100644
--- a/drivers/mtd/nand/ppchameleonevb.c
+++ b/drivers/mtd/nand/ppchameleonevb.c
@@ -6,7 +6,7 @@
6 * Derived from drivers/mtd/nand/edb7312.c 6 * Derived from drivers/mtd/nand/edb7312.c
7 * 7 *
8 * 8 *
9 * $Id: ppchameleonevb.c,v 1.6 2004/11/05 16:07:16 kalev Exp $ 9 * $Id: ppchameleonevb.c,v 1.7 2005/11/07 11:14:31 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -338,7 +338,7 @@ nand_evb_init:
338 out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFFFFFFF0); 338 out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFFFFFFF0);
339 out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0x3FFFFFFF); 339 out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0x3FFFFFFF);
340 /* enable output driver */ 340 /* enable output driver */
341 out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN | 341 out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN |
342 NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN); 342 NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN);
343#ifdef USE_READY_BUSY_PIN 343#ifdef USE_READY_BUSY_PIN
344 /* three-state select */ 344 /* three-state select */
@@ -402,7 +402,7 @@ static void __exit ppchameleonevb_cleanup (void)
402 /* Release resources, unregister device(s) */ 402 /* Release resources, unregister device(s) */
403 nand_release (ppchameleon_mtd); 403 nand_release (ppchameleon_mtd);
404 nand_release (ppchameleonevb_mtd); 404 nand_release (ppchameleonevb_mtd);
405 405
406 /* Release iomaps */ 406 /* Release iomaps */
407 this = (struct nand_chip *) &ppchameleon_mtd[1]; 407 this = (struct nand_chip *) &ppchameleon_mtd[1];
408 iounmap((void *) this->IO_ADDR_R; 408 iounmap((void *) this->IO_ADDR_R;
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c
index 031051cbde76..3a5841c9d950 100644
--- a/drivers/mtd/nand/rtc_from4.c
+++ b/drivers/mtd/nand/rtc_from4.c
@@ -2,11 +2,11 @@
2 * drivers/mtd/nand/rtc_from4.c 2 * drivers/mtd/nand/rtc_from4.c
3 * 3 *
4 * Copyright (C) 2004 Red Hat, Inc. 4 * Copyright (C) 2004 Red Hat, Inc.
5 * 5 *
6 * Derived from drivers/mtd/nand/spia.c 6 * Derived from drivers/mtd/nand/spia.c
7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
8 * 8 *
9 * $Id: rtc_from4.c,v 1.9 2005/01/24 20:40:11 dmarlin Exp $ 9 * $Id: rtc_from4.c,v 1.10 2005/11/07 11:14:31 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -14,8 +14,8 @@
14 * 14 *
15 * Overview: 15 * Overview:
16 * This is a device driver for the AG-AND flash device found on the 16 * This is a device driver for the AG-AND flash device found on the
17 * Renesas Technology Corp. Flash ROM 4-slot interface board (FROM_BOARD4), 17 * Renesas Technology Corp. Flash ROM 4-slot interface board (FROM_BOARD4),
18 * which utilizes the Renesas HN29V1G91T-30 part. 18 * which utilizes the Renesas HN29V1G91T-30 part.
19 * This chip is a 1 GBibit (128MiB x 8 bits) AG-AND flash device. 19 * This chip is a 1 GBibit (128MiB x 8 bits) AG-AND flash device.
20 */ 20 */
21 21
@@ -105,9 +105,9 @@ const static struct mtd_partition partition_info[] = {
105}; 105};
106#define NUM_PARTITIONS 1 106#define NUM_PARTITIONS 1
107 107
108/* 108/*
109 * hardware specific flash bbt decriptors 109 * hardware specific flash bbt decriptors
110 * Note: this is to allow debugging by disabling 110 * Note: this is to allow debugging by disabling
111 * NAND_BBT_CREATE and/or NAND_BBT_WRITE 111 * NAND_BBT_CREATE and/or NAND_BBT_WRITE
112 * 112 *
113 */ 113 */
@@ -141,7 +141,7 @@ static struct nand_bbt_descr rtc_from4_bbt_mirror_descr = {
141/* the Reed Solomon control structure */ 141/* the Reed Solomon control structure */
142static struct rs_control *rs_decoder; 142static struct rs_control *rs_decoder;
143 143
144/* 144/*
145 * hardware specific Out Of Band information 145 * hardware specific Out Of Band information
146 */ 146 */
147static struct nand_oobinfo rtc_from4_nand_oobinfo = { 147static struct nand_oobinfo rtc_from4_nand_oobinfo = {
@@ -200,38 +200,38 @@ static uint8_t revbits[256] = {
200 200
201 201
202 202
203/* 203/*
204 * rtc_from4_hwcontrol - hardware specific access to control-lines 204 * rtc_from4_hwcontrol - hardware specific access to control-lines
205 * @mtd: MTD device structure 205 * @mtd: MTD device structure
206 * @cmd: hardware control command 206 * @cmd: hardware control command
207 * 207 *
208 * Address lines (A5 and A4) are used to control Command and Address Latch 208 * Address lines (A5 and A4) are used to control Command and Address Latch
209 * Enable on this board, so set the read/write address appropriately. 209 * Enable on this board, so set the read/write address appropriately.
210 * 210 *
211 * Chip Enable is also controlled by the Chip Select (CS5) and 211 * Chip Enable is also controlled by the Chip Select (CS5) and
212 * Address lines (A24-A22), so no action is required here. 212 * Address lines (A24-A22), so no action is required here.
213 * 213 *
214 */ 214 */
215static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd) 215static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd)
216{ 216{
217 struct nand_chip* this = (struct nand_chip *) (mtd->priv); 217 struct nand_chip* this = (struct nand_chip *) (mtd->priv);
218 218
219 switch(cmd) { 219 switch(cmd) {
220 220
221 case NAND_CTL_SETCLE: 221 case NAND_CTL_SETCLE:
222 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE); 222 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE);
223 break; 223 break;
224 case NAND_CTL_CLRCLE: 224 case NAND_CTL_CLRCLE:
225 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_CLE); 225 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_CLE);
226 break; 226 break;
227 227
228 case NAND_CTL_SETALE: 228 case NAND_CTL_SETALE:
229 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_ALE); 229 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_ALE);
230 break; 230 break;
231 case NAND_CTL_CLRALE: 231 case NAND_CTL_CLRALE:
232 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_ALE); 232 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_ALE);
233 break; 233 break;
234 234
235 case NAND_CTL_SETNCE: 235 case NAND_CTL_SETNCE:
236 break; 236 break;
237 case NAND_CTL_CLRNCE: 237 case NAND_CTL_CLRNCE:
@@ -296,7 +296,7 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
296 * @mtd: MTD device structure 296 * @mtd: MTD device structure
297 * @chip: Chip to select (0 == slot 3, 1 == slot 4) 297 * @chip: Chip to select (0 == slot 3, 1 == slot 4)
298 * 298 *
299 * If there was a sudden loss of power during an erase operation, a 299 * If there was a sudden loss of power during an erase operation, a
300 * "device recovery" operation must be performed when power is restored 300 * "device recovery" operation must be performed when power is restored
301 * to ensure correct operation. This routine performs the required steps 301 * to ensure correct operation. This routine performs the required steps
302 * for the requested chip. 302 * for the requested chip.
@@ -312,7 +312,7 @@ static void deplete(struct mtd_info *mtd, int chip)
312 while (!this->dev_ready(mtd)); 312 while (!this->dev_ready(mtd));
313 313
314 this->select_chip(mtd, chip); 314 this->select_chip(mtd, chip);
315 315
316 /* Send the commands for device recovery, phase 1 */ 316 /* Send the commands for device recovery, phase 1 */
317 this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000); 317 this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000);
318 this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1); 318 this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1);
@@ -330,7 +330,7 @@ static void deplete(struct mtd_info *mtd, int chip)
330 * @mtd: MTD device structure 330 * @mtd: MTD device structure
331 * @mode: I/O mode; read or write 331 * @mode: I/O mode; read or write
332 * 332 *
333 * enable hardware ECC for data read or write 333 * enable hardware ECC for data read or write
334 * 334 *
335 */ 335 */
336static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode) 336static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
@@ -340,7 +340,7 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
340 340
341 switch (mode) { 341 switch (mode) {
342 case NAND_ECC_READ : 342 case NAND_ECC_READ :
343 status = RTC_FROM4_RS_ECC_CTL_CLR 343 status = RTC_FROM4_RS_ECC_CTL_CLR
344 | RTC_FROM4_RS_ECC_CTL_FD_E; 344 | RTC_FROM4_RS_ECC_CTL_FD_E;
345 345
346 *rs_ecc_ctl = status; 346 *rs_ecc_ctl = status;
@@ -353,8 +353,8 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
353 break; 353 break;
354 354
355 case NAND_ECC_WRITE : 355 case NAND_ECC_WRITE :
356 status = RTC_FROM4_RS_ECC_CTL_CLR 356 status = RTC_FROM4_RS_ECC_CTL_CLR
357 | RTC_FROM4_RS_ECC_CTL_GEN 357 | RTC_FROM4_RS_ECC_CTL_GEN
358 | RTC_FROM4_RS_ECC_CTL_FD_E; 358 | RTC_FROM4_RS_ECC_CTL_FD_E;
359 359
360 *rs_ecc_ctl = status; 360 *rs_ecc_ctl = status;
@@ -411,7 +411,7 @@ static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_c
411static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2) 411static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2)
412{ 412{
413 int i, j, res; 413 int i, j, res;
414 unsigned short status; 414 unsigned short status;
415 uint16_t par[6], syn[6]; 415 uint16_t par[6], syn[6];
416 uint8_t ecc[8]; 416 uint8_t ecc[8];
417 volatile unsigned short *rs_ecc; 417 volatile unsigned short *rs_ecc;
@@ -430,7 +430,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
430 } 430 }
431 431
432 /* convert into 6 10bit syndrome fields */ 432 /* convert into 6 10bit syndrome fields */
433 par[5] = rs_decoder->index_of[(((uint16_t)ecc[0] >> 0) & 0x0ff) | 433 par[5] = rs_decoder->index_of[(((uint16_t)ecc[0] >> 0) & 0x0ff) |
434 (((uint16_t)ecc[1] << 8) & 0x300)]; 434 (((uint16_t)ecc[1] << 8) & 0x300)];
435 par[4] = rs_decoder->index_of[(((uint16_t)ecc[1] >> 2) & 0x03f) | 435 par[4] = rs_decoder->index_of[(((uint16_t)ecc[1] >> 2) & 0x03f) |
436 (((uint16_t)ecc[2] << 6) & 0x3c0)]; 436 (((uint16_t)ecc[2] << 6) & 0x3c0)];
@@ -456,7 +456,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
456 /* Let the library code do its magic.*/ 456 /* Let the library code do its magic.*/
457 res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL); 457 res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL);
458 if (res > 0) { 458 if (res > 0) {
459 DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " 459 DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: "
460 "ECC corrected %d errors on read\n", res); 460 "ECC corrected %d errors on read\n", res);
461 } 461 }
462 return res; 462 return res;
@@ -470,9 +470,9 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
470 * @state: state or the operation 470 * @state: state or the operation
471 * @status: status code returned from read status 471 * @status: status code returned from read status
472 * @page: startpage inside the chip, must be called with (page & this->pagemask) 472 * @page: startpage inside the chip, must be called with (page & this->pagemask)
473 * 473 *
474 * Perform additional error status checks on erase and write failures 474 * Perform additional error status checks on erase and write failures
475 * to determine if errors are correctable. For this device, correctable 475 * to determine if errors are correctable. For this device, correctable
476 * 1-bit errors on erase and write are considered acceptable. 476 * 1-bit errors on erase and write are considered acceptable.
477 * 477 *
478 * note: see pages 34..37 of data sheet for details. 478 * note: see pages 34..37 of data sheet for details.
@@ -633,7 +633,7 @@ int __init rtc_from4_init (void)
633 633
634#ifdef RTC_FROM4_HWECC 634#ifdef RTC_FROM4_HWECC
635 /* We could create the decoder on demand, if memory is a concern. 635 /* We could create the decoder on demand, if memory is a concern.
636 * This way we have it handy, if an error happens 636 * This way we have it handy, if an error happens
637 * 637 *
638 * Symbolsize is 10 (bits) 638 * Symbolsize is 10 (bits)
639 * Primitve polynomial is x^10+x^3+1 639 * Primitve polynomial is x^10+x^3+1
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index 2df5e47d1f5c..97e9b7892d29 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -17,8 +17,9 @@
17 * 02-May-2005 BJD Reduced hwcontrol decode 17 * 02-May-2005 BJD Reduced hwcontrol decode
18 * 20-Jun-2005 BJD Updated s3c2440 support, fixed timing bug 18 * 20-Jun-2005 BJD Updated s3c2440 support, fixed timing bug
19 * 08-Jul-2005 BJD Fix OOPS when no platform data supplied 19 * 08-Jul-2005 BJD Fix OOPS when no platform data supplied
20 * 20-Oct-2005 BJD Fix timing calculation bug
20 * 21 *
21 * $Id: s3c2410.c,v 1.14 2005/07/06 20:05:06 bjd Exp $ 22 * $Id: s3c2410.c,v 1.20 2005/11/07 11:14:31 gleixner Exp $
22 * 23 *
23 * This program is free software; you can redistribute it and/or modify 24 * This program is free software; you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published by 25 * it under the terms of the GNU General Public License as published by
@@ -136,13 +137,13 @@ static struct s3c2410_platform_nand *to_nand_plat(struct device *dev)
136 137
137/* timing calculations */ 138/* timing calculations */
138 139
139#define NS_IN_KHZ 10000000 140#define NS_IN_KHZ 1000000
140 141
141static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max) 142static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
142{ 143{
143 int result; 144 int result;
144 145
145 result = (wanted * NS_IN_KHZ) / clk; 146 result = (wanted * clk) / NS_IN_KHZ;
146 result++; 147 result++;
147 148
148 pr_debug("result %d from %ld, %d\n", result, clk, wanted); 149 pr_debug("result %d from %ld, %d\n", result, clk, wanted);
@@ -159,20 +160,22 @@ static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
159 return result; 160 return result;
160} 161}
161 162
162#define to_ns(ticks,clk) (((clk) * (ticks)) / NS_IN_KHZ) 163#define to_ns(ticks,clk) (((ticks) * NS_IN_KHZ) / (unsigned int)(clk))
163 164
164/* controller setup */ 165/* controller setup */
165 166
166static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, 167static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
167 struct device *dev) 168 struct device *dev)
168{ 169{
169 struct s3c2410_platform_nand *plat = to_nand_plat(dev); 170 struct s3c2410_platform_nand *plat = to_nand_plat(dev);
170 unsigned int tacls, twrph0, twrph1;
171 unsigned long clkrate = clk_get_rate(info->clk); 171 unsigned long clkrate = clk_get_rate(info->clk);
172 int tacls, twrph0, twrph1;
172 unsigned long cfg; 173 unsigned long cfg;
173 174
174 /* calculate the timing information for the controller */ 175 /* calculate the timing information for the controller */
175 176
177 clkrate /= 1000; /* turn clock into kHz for ease of use */
178
176 if (plat != NULL) { 179 if (plat != NULL) {
177 tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4); 180 tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4);
178 twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8); 181 twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);
@@ -183,16 +186,16 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
183 twrph0 = 8; 186 twrph0 = 8;
184 twrph1 = 8; 187 twrph1 = 8;
185 } 188 }
186 189
187 if (tacls < 0 || twrph0 < 0 || twrph1 < 0) { 190 if (tacls < 0 || twrph0 < 0 || twrph1 < 0) {
188 printk(KERN_ERR PFX "cannot get timings suitable for board\n"); 191 printk(KERN_ERR PFX "cannot get timings suitable for board\n");
189 return -EINVAL; 192 return -EINVAL;
190 } 193 }
191 194
192 printk(KERN_INFO PFX "timing: Tacls %ldns, Twrph0 %ldns, Twrph1 %ldns\n", 195 printk(KERN_INFO PFX "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n",
193 to_ns(tacls, clkrate), 196 tacls, to_ns(tacls, clkrate),
194 to_ns(twrph0, clkrate), 197 twrph0, to_ns(twrph0, clkrate),
195 to_ns(twrph1, clkrate)); 198 twrph1, to_ns(twrph1, clkrate));
196 199
197 if (!info->is_s3c2440) { 200 if (!info->is_s3c2440) {
198 cfg = S3C2410_NFCONF_EN; 201 cfg = S3C2410_NFCONF_EN;
@@ -216,7 +219,7 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
216static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) 219static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
217{ 220{
218 struct s3c2410_nand_info *info; 221 struct s3c2410_nand_info *info;
219 struct s3c2410_nand_mtd *nmtd; 222 struct s3c2410_nand_mtd *nmtd;
220 struct nand_chip *this = mtd->priv; 223 struct nand_chip *this = mtd->priv;
221 void __iomem *reg; 224 void __iomem *reg;
222 unsigned long cur; 225 unsigned long cur;
@@ -249,7 +252,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
249 writel(cur, reg); 252 writel(cur, reg);
250} 253}
251 254
252/* command and control functions 255/* command and control functions
253 * 256 *
254 * Note, these all use tglx's method of changing the IO_ADDR_W field 257 * Note, these all use tglx's method of changing the IO_ADDR_W field
255 * to make the code simpler, and use the nand layer's code to issue the 258 * to make the code simpler, and use the nand layer's code to issue the
@@ -321,7 +324,7 @@ static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd)
321static int s3c2410_nand_devready(struct mtd_info *mtd) 324static int s3c2410_nand_devready(struct mtd_info *mtd)
322{ 325{
323 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 326 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
324 327
325 if (info->is_s3c2440) 328 if (info->is_s3c2440)
326 return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY; 329 return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY;
327 return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY; 330 return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY;
@@ -342,7 +345,7 @@ static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
342 345
343 if (read_ecc[0] == calc_ecc[0] && 346 if (read_ecc[0] == calc_ecc[0] &&
344 read_ecc[1] == calc_ecc[1] && 347 read_ecc[1] == calc_ecc[1] &&
345 read_ecc[2] == calc_ecc[2]) 348 read_ecc[2] == calc_ecc[2])
346 return 0; 349 return 0;
347 350
348 /* we curently have no method for correcting the error */ 351 /* we curently have no method for correcting the error */
@@ -433,14 +436,14 @@ static int s3c2410_nand_remove(struct device *dev)
433 436
434 dev_set_drvdata(dev, NULL); 437 dev_set_drvdata(dev, NULL);
435 438
436 if (info == NULL) 439 if (info == NULL)
437 return 0; 440 return 0;
438 441
439 /* first thing we need to do is release all our mtds 442 /* first thing we need to do is release all our mtds
440 * and their partitions, then go through freeing the 443 * and their partitions, then go through freeing the
441 * resources used 444 * resources used
442 */ 445 */
443 446
444 if (info->mtds != NULL) { 447 if (info->mtds != NULL) {
445 struct s3c2410_nand_mtd *ptr = info->mtds; 448 struct s3c2410_nand_mtd *ptr = info->mtds;
446 int mtdno; 449 int mtdno;
@@ -504,7 +507,7 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
504 507
505/* s3c2410_nand_init_chip 508/* s3c2410_nand_init_chip
506 * 509 *
507 * init a single instance of an chip 510 * init a single instance of an chip
508*/ 511*/
509 512
510static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, 513static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
@@ -576,7 +579,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
576 579
577 info = kmalloc(sizeof(*info), GFP_KERNEL); 580 info = kmalloc(sizeof(*info), GFP_KERNEL);
578 if (info == NULL) { 581 if (info == NULL) {
579 printk(KERN_ERR PFX "no memory for flash info\n"); 582 dev_err(dev, "no memory for flash info\n");
580 err = -ENOMEM; 583 err = -ENOMEM;
581 goto exit_error; 584 goto exit_error;
582 } 585 }
@@ -591,7 +594,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
591 594
592 info->clk = clk_get(dev, "nand"); 595 info->clk = clk_get(dev, "nand");
593 if (IS_ERR(info->clk)) { 596 if (IS_ERR(info->clk)) {
594 printk(KERN_ERR PFX "failed to get clock"); 597 dev_err(dev, "failed to get clock");
595 err = -ENOENT; 598 err = -ENOENT;
596 goto exit_error; 599 goto exit_error;
597 } 600 }
@@ -608,7 +611,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
608 info->area = request_mem_region(res->start, size, pdev->name); 611 info->area = request_mem_region(res->start, size, pdev->name);
609 612
610 if (info->area == NULL) { 613 if (info->area == NULL) {
611 printk(KERN_ERR PFX "cannot reserve register region\n"); 614 dev_err(dev, "cannot reserve register region\n");
612 err = -ENOENT; 615 err = -ENOENT;
613 goto exit_error; 616 goto exit_error;
614 } 617 }
@@ -619,12 +622,12 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
619 info->is_s3c2440 = is_s3c2440; 622 info->is_s3c2440 = is_s3c2440;
620 623
621 if (info->regs == NULL) { 624 if (info->regs == NULL) {
622 printk(KERN_ERR PFX "cannot reserve register region\n"); 625 dev_err(dev, "cannot reserve register region\n");
623 err = -EIO; 626 err = -EIO;
624 goto exit_error; 627 goto exit_error;
625 } 628 }
626 629
627 printk(KERN_INFO PFX "mapped registers at %p\n", info->regs); 630 dev_dbg(dev, "mapped registers at %p\n", info->regs);
628 631
629 /* initialise the hardware */ 632 /* initialise the hardware */
630 633
@@ -642,7 +645,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
642 size = nr_sets * sizeof(*info->mtds); 645 size = nr_sets * sizeof(*info->mtds);
643 info->mtds = kmalloc(size, GFP_KERNEL); 646 info->mtds = kmalloc(size, GFP_KERNEL);
644 if (info->mtds == NULL) { 647 if (info->mtds == NULL) {
645 printk(KERN_ERR PFX "failed to allocate mtd storage\n"); 648 dev_err(dev, "failed to allocate mtd storage\n");
646 err = -ENOMEM; 649 err = -ENOMEM;
647 goto exit_error; 650 goto exit_error;
648 } 651 }
@@ -656,7 +659,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
656 for (setno = 0; setno < nr_sets; setno++, nmtd++) { 659 for (setno = 0; setno < nr_sets; setno++, nmtd++) {
657 pr_debug("initialising set %d (%p, info %p)\n", 660 pr_debug("initialising set %d (%p, info %p)\n",
658 setno, nmtd, info); 661 setno, nmtd, info);
659 662
660 s3c2410_nand_init_chip(info, nmtd, sets); 663 s3c2410_nand_init_chip(info, nmtd, sets);
661 664
662 nmtd->scan_res = nand_scan(&nmtd->mtd, 665 nmtd->scan_res = nand_scan(&nmtd->mtd,
@@ -669,7 +672,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
669 if (sets != NULL) 672 if (sets != NULL)
670 sets++; 673 sets++;
671 } 674 }
672 675
673 pr_debug("initialised ok\n"); 676 pr_debug("initialised ok\n");
674 return 0; 677 return 0;
675 678
@@ -695,6 +698,7 @@ static int s3c2440_nand_probe(struct device *dev)
695 698
696static struct device_driver s3c2410_nand_driver = { 699static struct device_driver s3c2410_nand_driver = {
697 .name = "s3c2410-nand", 700 .name = "s3c2410-nand",
701 .owner = THIS_MODULE,
698 .bus = &platform_bus_type, 702 .bus = &platform_bus_type,
699 .probe = s3c2410_nand_probe, 703 .probe = s3c2410_nand_probe,
700 .remove = s3c2410_nand_remove, 704 .remove = s3c2410_nand_remove,
@@ -702,6 +706,7 @@ static struct device_driver s3c2410_nand_driver = {
702 706
703static struct device_driver s3c2440_nand_driver = { 707static struct device_driver s3c2440_nand_driver = {
704 .name = "s3c2440-nand", 708 .name = "s3c2440-nand",
709 .owner = THIS_MODULE,
705 .bus = &platform_bus_type, 710 .bus = &platform_bus_type,
706 .probe = s3c2440_nand_probe, 711 .probe = s3c2440_nand_probe,
707 .remove = s3c2410_nand_remove, 712 .remove = s3c2410_nand_remove,
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c
index 88b5b5b40b43..1924a4f137c7 100644
--- a/drivers/mtd/nand/sharpsl.c
+++ b/drivers/mtd/nand/sharpsl.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2004 Richard Purdie 4 * Copyright (C) 2004 Richard Purdie
5 * 5 *
6 * $Id: sharpsl.c,v 1.4 2005/01/23 11:09:19 rpurdie Exp $ 6 * $Id: sharpsl.c,v 1.7 2005/11/07 11:14:31 gleixner Exp $
7 * 7 *
8 * Based on Sharp's NAND driver sharp_sl.c 8 * Based on Sharp's NAND driver sharp_sl.c
9 * 9 *
@@ -76,14 +76,14 @@ static struct mtd_partition sharpsl_nand_default_partition_info[] = {
76 }, 76 },
77}; 77};
78 78
79/* 79/*
80 * hardware specific access to control-lines 80 * hardware specific access to control-lines
81 */ 81 */
82static void 82static void
83sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd) 83sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
84{ 84{
85 switch (cmd) { 85 switch (cmd) {
86 case NAND_CTL_SETCLE: 86 case NAND_CTL_SETCLE:
87 writeb(readb(FLASHCTL) | FLCLE, FLASHCTL); 87 writeb(readb(FLASHCTL) | FLCLE, FLASHCTL);
88 break; 88 break;
89 case NAND_CTL_CLRCLE: 89 case NAND_CTL_CLRCLE:
@@ -97,10 +97,10 @@ sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
97 writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL); 97 writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL);
98 break; 98 break;
99 99
100 case NAND_CTL_SETNCE: 100 case NAND_CTL_SETNCE:
101 writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL); 101 writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL);
102 break; 102 break;
103 case NAND_CTL_CLRNCE: 103 case NAND_CTL_CLRNCE:
104 writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL); 104 writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL);
105 break; 105 break;
106 } 106 }
@@ -115,6 +115,23 @@ static struct nand_bbt_descr sharpsl_bbt = {
115 .pattern = scan_ff_pattern 115 .pattern = scan_ff_pattern
116}; 116};
117 117
118static struct nand_bbt_descr sharpsl_akita_bbt = {
119 .options = 0,
120 .offs = 4,
121 .len = 1,
122 .pattern = scan_ff_pattern
123};
124
125static struct nand_oobinfo akita_oobinfo = {
126 .useecc = MTD_NANDECC_AUTOPLACE,
127 .eccbytes = 24,
128 .eccpos = {
129 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11,
130 0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
131 0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37},
132 .oobfree = { {0x08, 0x09} }
133};
134
118static int 135static int
119sharpsl_nand_dev_ready(struct mtd_info* mtd) 136sharpsl_nand_dev_ready(struct mtd_info* mtd)
120{ 137{
@@ -160,7 +177,7 @@ sharpsl_nand_init(void)
160 printk ("Unable to allocate SharpSL NAND MTD device structure.\n"); 177 printk ("Unable to allocate SharpSL NAND MTD device structure.\n");
161 return -ENOMEM; 178 return -ENOMEM;
162 } 179 }
163 180
164 /* map physical adress */ 181 /* map physical adress */
165 sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000); 182 sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000);
166 if(!sharpsl_io_base){ 183 if(!sharpsl_io_base){
@@ -168,7 +185,7 @@ sharpsl_nand_init(void)
168 kfree(sharpsl_mtd); 185 kfree(sharpsl_mtd);
169 return -EIO; 186 return -EIO;
170 } 187 }
171 188
172 /* Get pointer to private data */ 189 /* Get pointer to private data */
173 this = (struct nand_chip *) (&sharpsl_mtd[1]); 190 this = (struct nand_chip *) (&sharpsl_mtd[1]);
174 191
@@ -194,10 +211,14 @@ sharpsl_nand_init(void)
194 this->chip_delay = 15; 211 this->chip_delay = 15;
195 /* set eccmode using hardware ECC */ 212 /* set eccmode using hardware ECC */
196 this->eccmode = NAND_ECC_HW3_256; 213 this->eccmode = NAND_ECC_HW3_256;
214 this->badblock_pattern = &sharpsl_bbt;
215 if (machine_is_akita() || machine_is_borzoi()) {
216 this->badblock_pattern = &sharpsl_akita_bbt;
217 this->autooob = &akita_oobinfo;
218 }
197 this->enable_hwecc = sharpsl_nand_enable_hwecc; 219 this->enable_hwecc = sharpsl_nand_enable_hwecc;
198 this->calculate_ecc = sharpsl_nand_calculate_ecc; 220 this->calculate_ecc = sharpsl_nand_calculate_ecc;
199 this->correct_data = nand_correct_data; 221 this->correct_data = nand_correct_data;
200 this->badblock_pattern = &sharpsl_bbt;
201 222
202 /* Scan to find existence of the device */ 223 /* Scan to find existence of the device */
203 err=nand_scan(sharpsl_mtd,1); 224 err=nand_scan(sharpsl_mtd,1);
@@ -211,7 +232,7 @@ sharpsl_nand_init(void)
211 sharpsl_mtd->name = "sharpsl-nand"; 232 sharpsl_mtd->name = "sharpsl-nand";
212 nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes, 233 nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes,
213 &sharpsl_partition_info, 0); 234 &sharpsl_partition_info, 0);
214 235
215 if (nr_partitions <= 0) { 236 if (nr_partitions <= 0) {
216 nr_partitions = DEFAULT_NUM_PARTITIONS; 237 nr_partitions = DEFAULT_NUM_PARTITIONS;
217 sharpsl_partition_info = sharpsl_nand_default_partition_info; 238 sharpsl_partition_info = sharpsl_nand_default_partition_info;
@@ -230,7 +251,7 @@ sharpsl_nand_init(void)
230 } 251 }
231 } 252 }
232 253
233 if (machine_is_husky() || machine_is_borzoi()) { 254 if (machine_is_husky() || machine_is_borzoi() || machine_is_akita()) {
234 /* Need to use small eraseblock size for backward compatibility */ 255 /* Need to use small eraseblock size for backward compatibility */
235 sharpsl_mtd->flags |= MTD_NO_VIRTBLOCKS; 256 sharpsl_mtd->flags |= MTD_NO_VIRTBLOCKS;
236 } 257 }
diff --git a/drivers/mtd/nand/spia.c b/drivers/mtd/nand/spia.c
index b777c412b758..32541cbb0103 100644
--- a/drivers/mtd/nand/spia.c
+++ b/drivers/mtd/nand/spia.c
@@ -8,7 +8,7 @@
8 * to controllines (due to change in nand.c) 8 * to controllines (due to change in nand.c)
9 * page_cache added 9 * page_cache added
10 * 10 *
11 * $Id: spia.c,v 1.24 2004/11/04 12:53:10 gleixner Exp $ 11 * $Id: spia.c,v 1.25 2005/11/07 11:14:31 gleixner Exp $
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as 14 * it under the terms of the GNU General Public License version 2 as
@@ -82,7 +82,7 @@ const static struct mtd_partition partition_info[] = {
82#define NUM_PARTITIONS 2 82#define NUM_PARTITIONS 2
83 83
84 84
85/* 85/*
86 * hardware specific access to control-lines 86 * hardware specific access to control-lines
87*/ 87*/
88static void spia_hwcontrol(struct mtd_info *mtd, int cmd){ 88static void spia_hwcontrol(struct mtd_info *mtd, int cmd){
@@ -137,7 +137,7 @@ int __init spia_init (void)
137 /* Set address of hardware control function */ 137 /* Set address of hardware control function */
138 this->hwcontrol = spia_hwcontrol; 138 this->hwcontrol = spia_hwcontrol;
139 /* 15 us command delay time */ 139 /* 15 us command delay time */
140 this->chip_delay = 15; 140 this->chip_delay = 15;
141 141
142 /* Scan to find existence of the device */ 142 /* Scan to find existence of the device */
143 if (nand_scan (spia_mtd, 1)) { 143 if (nand_scan (spia_mtd, 1)) {
diff --git a/drivers/mtd/nand/toto.c b/drivers/mtd/nand/toto.c
index 52c808fb5fa9..7609c43cb3ec 100644
--- a/drivers/mtd/nand/toto.c
+++ b/drivers/mtd/nand/toto.c
@@ -15,7 +15,7 @@
15 * This is a device driver for the NAND flash device found on the 15 * This is a device driver for the NAND flash device found on the
16 * TI fido board. It supports 32MiB and 64MiB cards 16 * TI fido board. It supports 32MiB and 64MiB cards
17 * 17 *
18 * $Id: toto.c,v 1.4 2004/10/05 13:50:20 gleixner Exp $ 18 * $Id: toto.c,v 1.5 2005/11/07 11:14:31 gleixner Exp $
19 */ 19 */
20 20
21#include <linux/slab.h> 21#include <linux/slab.h>
@@ -57,7 +57,7 @@ static unsigned long toto_io_base = OMAP_FLASH_1_BASE;
57#endif 57#endif
58#define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0) 58#define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0)
59#define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE) 59#define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE)
60 60
61/* 61/*
62 * Define partitions for flash devices 62 * Define partitions for flash devices
63 */ 63 */
@@ -91,7 +91,7 @@ static struct mtd_partition partition_info32M[] = {
91 91
92#define NUM_PARTITIONS32M 3 92#define NUM_PARTITIONS32M 3
93#define NUM_PARTITIONS64M 4 93#define NUM_PARTITIONS64M 4
94/* 94/*
95 * hardware specific access to control-lines 95 * hardware specific access to control-lines
96*/ 96*/
97 97
@@ -146,7 +146,7 @@ int __init toto_init (void)
146 this->hwcontrol = toto_hwcontrol; 146 this->hwcontrol = toto_hwcontrol;
147 this->dev_ready = NULL; 147 this->dev_ready = NULL;
148 /* 25 us command delay time */ 148 /* 25 us command delay time */
149 this->chip_delay = 30; 149 this->chip_delay = 30;
150 this->eccmode = NAND_ECC_SOFT; 150 this->eccmode = NAND_ECC_SOFT;
151 151
152 /* Scan to find existance of the device */ 152 /* Scan to find existance of the device */
@@ -157,10 +157,10 @@ int __init toto_init (void)
157 157
158 /* Register the partitions */ 158 /* Register the partitions */
159 switch(toto_mtd->size){ 159 switch(toto_mtd->size){
160 case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break; 160 case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break;
161 case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break; 161 case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break;
162 default: { 162 default: {
163 printk (KERN_WARNING "Unsupported Nand device\n"); 163 printk (KERN_WARNING "Unsupported Nand device\n");
164 err = -ENXIO; 164 err = -ENXIO;
165 goto out_buf; 165 goto out_buf;
166 } 166 }
@@ -170,9 +170,9 @@ int __init toto_init (void)
170 archflashwp(0,0); /* open up flash for writing */ 170 archflashwp(0,0); /* open up flash for writing */
171 171
172 goto out; 172 goto out;
173 173
174out_buf: 174out_buf:
175 kfree (this->data_buf); 175 kfree (this->data_buf);
176out_mtd: 176out_mtd:
177 kfree (toto_mtd); 177 kfree (toto_mtd);
178out: 178out:
@@ -194,7 +194,7 @@ static void __exit toto_cleanup (void)
194 194
195 /* stop flash writes */ 195 /* stop flash writes */
196 archflashwp(0,1); 196 archflashwp(0,1);
197 197
198 /* release gpios to system */ 198 /* release gpios to system */
199 gpiorelease(NAND_MASK); 199 gpiorelease(NAND_MASK);
200} 200}
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index b2014043634f..d7cd5fa16ba4 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -1,7 +1,7 @@
1/* Linux driver for NAND Flash Translation Layer */ 1/* Linux driver for NAND Flash Translation Layer */
2/* (c) 1999 Machine Vision Holdings, Inc. */ 2/* (c) 1999 Machine Vision Holdings, Inc. */
3/* Author: David Woodhouse <dwmw2@infradead.org> */ 3/* Author: David Woodhouse <dwmw2@infradead.org> */
4/* $Id: nftlcore.c,v 1.97 2004/11/16 18:28:59 dwmw2 Exp $ */ 4/* $Id: nftlcore.c,v 1.98 2005/11/07 11:14:21 gleixner Exp $ */
5 5
6/* 6/*
7 The contents of this file are distributed under the GNU General 7 The contents of this file are distributed under the GNU General
@@ -101,23 +101,21 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
101 101
102 if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) { 102 if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) {
103 /* 103 /*
104 Oh no we don't have 104 Oh no we don't have
105 mbd.size == heads * cylinders * sectors 105 mbd.size == heads * cylinders * sectors
106 */ 106 */
107 printk(KERN_WARNING "NFTL: cannot calculate a geometry to " 107 printk(KERN_WARNING "NFTL: cannot calculate a geometry to "
108 "match size of 0x%lx.\n", nftl->mbd.size); 108 "match size of 0x%lx.\n", nftl->mbd.size);
109 printk(KERN_WARNING "NFTL: using C:%d H:%d S:%d " 109 printk(KERN_WARNING "NFTL: using C:%d H:%d S:%d "
110 "(== 0x%lx sects)\n", 110 "(== 0x%lx sects)\n",
111 nftl->cylinders, nftl->heads , nftl->sectors, 111 nftl->cylinders, nftl->heads , nftl->sectors,
112 (long)nftl->cylinders * (long)nftl->heads * 112 (long)nftl->cylinders * (long)nftl->heads *
113 (long)nftl->sectors ); 113 (long)nftl->sectors );
114 } 114 }
115 115
116 if (add_mtd_blktrans_dev(&nftl->mbd)) { 116 if (add_mtd_blktrans_dev(&nftl->mbd)) {
117 if (nftl->ReplUnitTable) 117 kfree(nftl->ReplUnitTable);
118 kfree(nftl->ReplUnitTable); 118 kfree(nftl->EUNtable);
119 if (nftl->EUNtable)
120 kfree(nftl->EUNtable);
121 kfree(nftl); 119 kfree(nftl);
122 return; 120 return;
123 } 121 }
@@ -133,10 +131,8 @@ static void nftl_remove_dev(struct mtd_blktrans_dev *dev)
133 DEBUG(MTD_DEBUG_LEVEL1, "NFTL: remove_dev (i=%d)\n", dev->devnum); 131 DEBUG(MTD_DEBUG_LEVEL1, "NFTL: remove_dev (i=%d)\n", dev->devnum);
134 132
135 del_mtd_blktrans_dev(dev); 133 del_mtd_blktrans_dev(dev);
136 if (nftl->ReplUnitTable) 134 kfree(nftl->ReplUnitTable);
137 kfree(nftl->ReplUnitTable); 135 kfree(nftl->EUNtable);
138 if (nftl->EUNtable)
139 kfree(nftl->EUNtable);
140 kfree(nftl); 136 kfree(nftl);
141} 137}
142 138
@@ -178,7 +174,7 @@ static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate )
178 174
179 if (!silly--) { 175 if (!silly--) {
180 printk("Argh! No free blocks found! LastFreeEUN = %d, " 176 printk("Argh! No free blocks found! LastFreeEUN = %d, "
181 "FirstEUN = %d\n", nftl->LastFreeEUN, 177 "FirstEUN = %d\n", nftl->LastFreeEUN,
182 le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN)); 178 le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN));
183 return 0xffff; 179 return 0xffff;
184 } 180 }
@@ -210,7 +206,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
210 "Virtual Unit Chain %d!\n", thisVUC); 206 "Virtual Unit Chain %d!\n", thisVUC);
211 return BLOCK_NIL; 207 return BLOCK_NIL;
212 } 208 }
213 209
214 /* Scan to find the Erase Unit which holds the actual data for each 210 /* Scan to find the Erase Unit which holds the actual data for each
215 512-byte block within the Chain. 211 512-byte block within the Chain.
216 */ 212 */
@@ -227,7 +223,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
227 if (block == 2) { 223 if (block == 2) {
228 foldmark = oob.u.c.FoldMark | oob.u.c.FoldMark1; 224 foldmark = oob.u.c.FoldMark | oob.u.c.FoldMark1;
229 if (foldmark == FOLD_MARK_IN_PROGRESS) { 225 if (foldmark == FOLD_MARK_IN_PROGRESS) {
230 DEBUG(MTD_DEBUG_LEVEL1, 226 DEBUG(MTD_DEBUG_LEVEL1,
231 "Write Inhibited on EUN %d\n", thisEUN); 227 "Write Inhibited on EUN %d\n", thisEUN);
232 inplace = 0; 228 inplace = 0;
233 } else { 229 } else {
@@ -249,7 +245,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
249 if (!BlockFreeFound[block]) 245 if (!BlockFreeFound[block])
250 BlockMap[block] = thisEUN; 246 BlockMap[block] = thisEUN;
251 else 247 else
252 printk(KERN_WARNING 248 printk(KERN_WARNING
253 "SECTOR_USED found after SECTOR_FREE " 249 "SECTOR_USED found after SECTOR_FREE "
254 "in Virtual Unit Chain %d for block %d\n", 250 "in Virtual Unit Chain %d for block %d\n",
255 thisVUC, block); 251 thisVUC, block);
@@ -258,7 +254,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
258 if (!BlockFreeFound[block]) 254 if (!BlockFreeFound[block])
259 BlockMap[block] = BLOCK_NIL; 255 BlockMap[block] = BLOCK_NIL;
260 else 256 else
261 printk(KERN_WARNING 257 printk(KERN_WARNING
262 "SECTOR_DELETED found after SECTOR_FREE " 258 "SECTOR_DELETED found after SECTOR_FREE "
263 "in Virtual Unit Chain %d for block %d\n", 259 "in Virtual Unit Chain %d for block %d\n",
264 thisVUC, block); 260 thisVUC, block);
@@ -277,14 +273,14 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
277 thisVUC); 273 thisVUC);
278 return BLOCK_NIL; 274 return BLOCK_NIL;
279 } 275 }
280 276
281 thisEUN = nftl->ReplUnitTable[thisEUN]; 277 thisEUN = nftl->ReplUnitTable[thisEUN];
282 } 278 }
283 279
284 if (inplace) { 280 if (inplace) {
285 /* We're being asked to be a fold-in-place. Check 281 /* We're being asked to be a fold-in-place. Check
286 that all blocks which actually have data associated 282 that all blocks which actually have data associated
287 with them (i.e. BlockMap[block] != BLOCK_NIL) are 283 with them (i.e. BlockMap[block] != BLOCK_NIL) are
288 either already present or SECTOR_FREE in the target 284 either already present or SECTOR_FREE in the target
289 block. If not, we're going to have to fold out-of-place 285 block. If not, we're going to have to fold out-of-place
290 anyway. 286 anyway.
@@ -297,7 +293,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
297 "block %d was %x lastEUN, " 293 "block %d was %x lastEUN, "
298 "and is in EUN %d (%s) %d\n", 294 "and is in EUN %d (%s) %d\n",
299 thisVUC, block, BlockLastState[block], 295 thisVUC, block, BlockLastState[block],
300 BlockMap[block], 296 BlockMap[block],
301 BlockMap[block]== targetEUN ? "==" : "!=", 297 BlockMap[block]== targetEUN ? "==" : "!=",
302 targetEUN); 298 targetEUN);
303 inplace = 0; 299 inplace = 0;
@@ -314,17 +310,17 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
314 inplace = 0; 310 inplace = 0;
315 } 311 }
316 } 312 }
317 313
318 if (!inplace) { 314 if (!inplace) {
319 DEBUG(MTD_DEBUG_LEVEL1, "Cannot fold Virtual Unit Chain %d in place. " 315 DEBUG(MTD_DEBUG_LEVEL1, "Cannot fold Virtual Unit Chain %d in place. "
320 "Trying out-of-place\n", thisVUC); 316 "Trying out-of-place\n", thisVUC);
321 /* We need to find a targetEUN to fold into. */ 317 /* We need to find a targetEUN to fold into. */
322 targetEUN = NFTL_findfreeblock(nftl, 1); 318 targetEUN = NFTL_findfreeblock(nftl, 1);
323 if (targetEUN == BLOCK_NIL) { 319 if (targetEUN == BLOCK_NIL) {
324 /* Ouch. Now we're screwed. We need to do a 320 /* Ouch. Now we're screwed. We need to do a
325 fold-in-place of another chain to make room 321 fold-in-place of another chain to make room
326 for this one. We need a better way of selecting 322 for this one. We need a better way of selecting
327 which chain to fold, because makefreeblock will 323 which chain to fold, because makefreeblock will
328 only ask us to fold the same one again. 324 only ask us to fold the same one again.
329 */ 325 */
330 printk(KERN_WARNING 326 printk(KERN_WARNING
@@ -338,7 +334,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
338 chain by selecting the longer one */ 334 chain by selecting the longer one */
339 oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS); 335 oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS);
340 oob.u.c.unused = 0xffffffff; 336 oob.u.c.unused = 0xffffffff;
341 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8, 337 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8,
342 8, &retlen, (char *)&oob.u); 338 8, &retlen, (char *)&oob.u);
343 } 339 }
344 340
@@ -361,14 +357,14 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
361 happen in case of media errors or deleted blocks) */ 357 happen in case of media errors or deleted blocks) */
362 if (BlockMap[block] == BLOCK_NIL) 358 if (BlockMap[block] == BLOCK_NIL)
363 continue; 359 continue;
364 360
365 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512), 361 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512),
366 512, &retlen, movebuf); 362 512, &retlen, movebuf);
367 if (ret < 0) { 363 if (ret < 0) {
368 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) 364 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block])
369 + (block * 512), 512, &retlen, 365 + (block * 512), 512, &retlen,
370 movebuf); 366 movebuf);
371 if (ret != -EIO) 367 if (ret != -EIO)
372 printk("Error went away on retry.\n"); 368 printk("Error went away on retry.\n");
373 } 369 }
374 memset(&oob, 0xff, sizeof(struct nftl_oob)); 370 memset(&oob, 0xff, sizeof(struct nftl_oob));
@@ -376,18 +372,18 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
376 MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512), 372 MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512),
377 512, &retlen, movebuf, (char *)&oob, &nftl->oobinfo); 373 512, &retlen, movebuf, (char *)&oob, &nftl->oobinfo);
378 } 374 }
379 375
380 /* add the header so that it is now a valid chain */ 376 /* add the header so that it is now a valid chain */
381 oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum 377 oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum
382 = cpu_to_le16(thisVUC); 378 = cpu_to_le16(thisVUC);
383 oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff; 379 oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff;
384 380
385 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8, 381 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8,
386 8, &retlen, (char *)&oob.u); 382 8, &retlen, (char *)&oob.u);
387 383
388 /* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */ 384 /* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */
389 385
390 /* At this point, we have two different chains for this Virtual Unit, and no way to tell 386 /* At this point, we have two different chains for this Virtual Unit, and no way to tell
391 them apart. If we crash now, we get confused. However, both contain the same data, so we 387 them apart. If we crash now, we get confused. However, both contain the same data, so we
392 shouldn't actually lose data in this case. It's just that when we load up on a medium which 388 shouldn't actually lose data in this case. It's just that when we load up on a medium which
393 has duplicate chains, we need to free one of the chains because it's not necessary any more. 389 has duplicate chains, we need to free one of the chains because it's not necessary any more.
@@ -395,7 +391,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
395 thisEUN = nftl->EUNtable[thisVUC]; 391 thisEUN = nftl->EUNtable[thisVUC];
396 DEBUG(MTD_DEBUG_LEVEL1,"Want to erase\n"); 392 DEBUG(MTD_DEBUG_LEVEL1,"Want to erase\n");
397 393
398 /* For each block in the old chain (except the targetEUN of course), 394 /* For each block in the old chain (except the targetEUN of course),
399 free it and make it available for future use */ 395 free it and make it available for future use */
400 while (thisEUN <= nftl->lastEUN && thisEUN != targetEUN) { 396 while (thisEUN <= nftl->lastEUN && thisEUN != targetEUN) {
401 unsigned int EUNtmp; 397 unsigned int EUNtmp;
@@ -413,7 +409,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
413 } 409 }
414 thisEUN = EUNtmp; 410 thisEUN = EUNtmp;
415 } 411 }
416 412
417 /* Make this the new start of chain for thisVUC */ 413 /* Make this the new start of chain for thisVUC */
418 nftl->ReplUnitTable[targetEUN] = BLOCK_NIL; 414 nftl->ReplUnitTable[targetEUN] = BLOCK_NIL;
419 nftl->EUNtable[thisVUC] = targetEUN; 415 nftl->EUNtable[thisVUC] = targetEUN;
@@ -423,7 +419,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
423 419
424static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock) 420static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock)
425{ 421{
426 /* This is the part that needs some cleverness applied. 422 /* This is the part that needs some cleverness applied.
427 For now, I'm doing the minimum applicable to actually 423 For now, I'm doing the minimum applicable to actually
428 get the thing to work. 424 get the thing to work.
429 Wear-levelling and other clever stuff needs to be implemented 425 Wear-levelling and other clever stuff needs to be implemented
@@ -470,7 +466,7 @@ static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock)
470 return NFTL_foldchain (nftl, LongestChain, pendingblock); 466 return NFTL_foldchain (nftl, LongestChain, pendingblock);
471} 467}
472 468
473/* NFTL_findwriteunit: Return the unit number into which we can write 469/* NFTL_findwriteunit: Return the unit number into which we can write
474 for this block. Make it available if it isn't already 470 for this block. Make it available if it isn't already
475*/ 471*/
476static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block) 472static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
@@ -488,7 +484,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
488 a free space for the block in question. 484 a free space for the block in question.
489 */ 485 */
490 486
491 /* This condition catches the 0x[7f]fff cases, as well as 487 /* This condition catches the 0x[7f]fff cases, as well as
492 being a sanity check for past-end-of-media access 488 being a sanity check for past-end-of-media access
493 */ 489 */
494 lastEUN = BLOCK_NIL; 490 lastEUN = BLOCK_NIL;
@@ -503,7 +499,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
503 499
504 MTD_READOOB(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs, 500 MTD_READOOB(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs,
505 8, &retlen, (char *)&bci); 501 8, &retlen, (char *)&bci);
506 502
507 DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n", 503 DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n",
508 block , writeEUN, le16_to_cpu(bci.Status)); 504 block , writeEUN, le16_to_cpu(bci.Status));
509 505
@@ -518,10 +514,10 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
518 break; 514 break;
519 default: 515 default:
520 // Invalid block. Don't use it any more. Must implement. 516 // Invalid block. Don't use it any more. Must implement.
521 break; 517 break;
522 } 518 }
523 519
524 if (!silly--) { 520 if (!silly--) {
525 printk(KERN_WARNING 521 printk(KERN_WARNING
526 "Infinite loop in Virtual Unit Chain 0x%x\n", 522 "Infinite loop in Virtual Unit Chain 0x%x\n",
527 thisVUC); 523 thisVUC);
@@ -532,7 +528,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
532 writeEUN = nftl->ReplUnitTable[writeEUN]; 528 writeEUN = nftl->ReplUnitTable[writeEUN];
533 } 529 }
534 530
535 /* OK. We didn't find one in the existing chain, or there 531 /* OK. We didn't find one in the existing chain, or there
536 is no existing chain. */ 532 is no existing chain. */
537 533
538 /* Try to find an already-free block */ 534 /* Try to find an already-free block */
@@ -546,12 +542,12 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
546 542
547 /* First remember the start of this chain */ 543 /* First remember the start of this chain */
548 //u16 startEUN = nftl->EUNtable[thisVUC]; 544 //u16 startEUN = nftl->EUNtable[thisVUC];
549 545
550 //printk("Write to VirtualUnitChain %d, calling makefreeblock()\n", thisVUC); 546 //printk("Write to VirtualUnitChain %d, calling makefreeblock()\n", thisVUC);
551 writeEUN = NFTL_makefreeblock(nftl, 0xffff); 547 writeEUN = NFTL_makefreeblock(nftl, 0xffff);
552 548
553 if (writeEUN == BLOCK_NIL) { 549 if (writeEUN == BLOCK_NIL) {
554 /* OK, we accept that the above comment is 550 /* OK, we accept that the above comment is
555 lying - there may have been free blocks 551 lying - there may have been free blocks
556 last time we called NFTL_findfreeblock(), 552 last time we called NFTL_findfreeblock(),
557 but they are reserved for when we're 553 but they are reserved for when we're
@@ -562,21 +558,21 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
562 } 558 }
563 if (writeEUN == BLOCK_NIL) { 559 if (writeEUN == BLOCK_NIL) {
564 /* Ouch. This should never happen - we should 560 /* Ouch. This should never happen - we should
565 always be able to make some room somehow. 561 always be able to make some room somehow.
566 If we get here, we've allocated more storage 562 If we get here, we've allocated more storage
567 space than actual media, or our makefreeblock 563 space than actual media, or our makefreeblock
568 routine is missing something. 564 routine is missing something.
569 */ 565 */
570 printk(KERN_WARNING "Cannot make free space.\n"); 566 printk(KERN_WARNING "Cannot make free space.\n");
571 return BLOCK_NIL; 567 return BLOCK_NIL;
572 } 568 }
573 //printk("Restarting scan\n"); 569 //printk("Restarting scan\n");
574 lastEUN = BLOCK_NIL; 570 lastEUN = BLOCK_NIL;
575 continue; 571 continue;
576 } 572 }
577 573
578 /* We've found a free block. Insert it into the chain. */ 574 /* We've found a free block. Insert it into the chain. */
579 575
580 if (lastEUN != BLOCK_NIL) { 576 if (lastEUN != BLOCK_NIL) {
581 thisVUC |= 0x8000; /* It's a replacement block */ 577 thisVUC |= 0x8000; /* It's a replacement block */
582 } else { 578 } else {
@@ -749,7 +745,7 @@ extern char nftlmountrev[];
749 745
750static int __init init_nftl(void) 746static int __init init_nftl(void)
751{ 747{
752 printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.97 $, nftlmount.c %s\n", nftlmountrev); 748 printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.98 $, nftlmount.c %s\n", nftlmountrev);
753 749
754 return register_mtd_blktrans(&nftl_tr); 750 return register_mtd_blktrans(&nftl_tr);
755} 751}
diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c
index 84afd9029f53..3b104ebb219a 100644
--- a/drivers/mtd/nftlmount.c
+++ b/drivers/mtd/nftlmount.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * NFTL mount code with extensive checks 2 * NFTL mount code with extensive checks
3 * 3 *
4 * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 4 * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
5 * Copyright (C) 2000 Netgem S.A. 5 * Copyright (C) 2000 Netgem S.A.
6 * 6 *
7 * $Id: nftlmount.c,v 1.40 2004/11/22 14:38:29 kalev Exp $ 7 * $Id: nftlmount.c,v 1.41 2005/11/07 11:14:21 gleixner Exp $
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -31,7 +31,7 @@
31 31
32#define SECTORSIZE 512 32#define SECTORSIZE 512
33 33
34char nftlmountrev[]="$Revision: 1.40 $"; 34char nftlmountrev[]="$Revision: 1.41 $";
35 35
36/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the 36/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
37 * various device information of the NFTL partition and Bad Unit Table. Update 37 * various device information of the NFTL partition and Bad Unit Table. Update
@@ -47,7 +47,7 @@ static int find_boot_record(struct NFTLrecord *nftl)
47 struct NFTLMediaHeader *mh = &nftl->MediaHdr; 47 struct NFTLMediaHeader *mh = &nftl->MediaHdr;
48 unsigned int i; 48 unsigned int i;
49 49
50 /* Assume logical EraseSize == physical erasesize for starting the scan. 50 /* Assume logical EraseSize == physical erasesize for starting the scan.
51 We'll sort it out later if we find a MediaHeader which says otherwise */ 51 We'll sort it out later if we find a MediaHeader which says otherwise */
52 /* Actually, we won't. The new DiskOnChip driver has already scanned 52 /* Actually, we won't. The new DiskOnChip driver has already scanned
53 the MediaHeader and adjusted the virtual erasesize it presents in 53 the MediaHeader and adjusted the virtual erasesize it presents in
@@ -83,9 +83,9 @@ static int find_boot_record(struct NFTLrecord *nftl)
83 if (retlen < 6 || memcmp(buf, "ANAND", 6)) { 83 if (retlen < 6 || memcmp(buf, "ANAND", 6)) {
84 /* ANAND\0 not found. Continue */ 84 /* ANAND\0 not found. Continue */
85#if 0 85#if 0
86 printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n", 86 printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n",
87 block * nftl->EraseSize, nftl->mbd.mtd->index); 87 block * nftl->EraseSize, nftl->mbd.mtd->index);
88#endif 88#endif
89 continue; 89 continue;
90 } 90 }
91 91
@@ -103,7 +103,7 @@ static int find_boot_record(struct NFTLrecord *nftl)
103 */ 103 */
104 if (le16_to_cpu(h1.EraseMark | h1.EraseMark1) != ERASE_MARK) { 104 if (le16_to_cpu(h1.EraseMark | h1.EraseMark1) != ERASE_MARK) {
105 printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but erase mark not present (0x%04x,0x%04x instead)\n", 105 printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but erase mark not present (0x%04x,0x%04x instead)\n",
106 block * nftl->EraseSize, nftl->mbd.mtd->index, 106 block * nftl->EraseSize, nftl->mbd.mtd->index,
107 le16_to_cpu(h1.EraseMark), le16_to_cpu(h1.EraseMark1)); 107 le16_to_cpu(h1.EraseMark), le16_to_cpu(h1.EraseMark1));
108 continue; 108 continue;
109 } 109 }
@@ -175,7 +175,7 @@ device is already correct.
175 nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN); 175 nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN);
176 if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) { 176 if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) {
177 printk(KERN_NOTICE "NFTL Media Header sanity check failed:\n"); 177 printk(KERN_NOTICE "NFTL Media Header sanity check failed:\n");
178 printk(KERN_NOTICE "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n", 178 printk(KERN_NOTICE "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n",
179 nftl->nb_boot_blocks, nftl->nb_blocks); 179 nftl->nb_boot_blocks, nftl->nb_blocks);
180 return -1; 180 return -1;
181 } 181 }
@@ -187,7 +187,7 @@ device is already correct.
187 nftl->numvunits, nftl->nb_blocks, nftl->nb_boot_blocks); 187 nftl->numvunits, nftl->nb_blocks, nftl->nb_boot_blocks);
188 return -1; 188 return -1;
189 } 189 }
190 190
191 nftl->mbd.size = nftl->numvunits * (nftl->EraseSize / SECTORSIZE); 191 nftl->mbd.size = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
192 192
193 /* If we're not using the last sectors in the device for some reason, 193 /* If we're not using the last sectors in the device for some reason,
@@ -210,12 +210,12 @@ device is already correct.
210 printk(KERN_NOTICE "NFTL: allocation of ReplUnitTable failed\n"); 210 printk(KERN_NOTICE "NFTL: allocation of ReplUnitTable failed\n");
211 return -ENOMEM; 211 return -ENOMEM;
212 } 212 }
213 213
214 /* mark the bios blocks (blocks before NFTL MediaHeader) as reserved */ 214 /* mark the bios blocks (blocks before NFTL MediaHeader) as reserved */
215 for (i = 0; i < nftl->nb_boot_blocks; i++) 215 for (i = 0; i < nftl->nb_boot_blocks; i++)
216 nftl->ReplUnitTable[i] = BLOCK_RESERVED; 216 nftl->ReplUnitTable[i] = BLOCK_RESERVED;
217 /* mark all remaining blocks as potentially containing data */ 217 /* mark all remaining blocks as potentially containing data */
218 for (; i < nftl->nb_blocks; i++) { 218 for (; i < nftl->nb_blocks; i++) {
219 nftl->ReplUnitTable[i] = BLOCK_NOTEXPLORED; 219 nftl->ReplUnitTable[i] = BLOCK_NOTEXPLORED;
220 } 220 }
221 221
@@ -245,12 +245,12 @@ The new DiskOnChip driver already scanned the bad block table. Just query it.
245 if (nftl->mbd.mtd->block_isbad(nftl->mbd.mtd, i * nftl->EraseSize)) 245 if (nftl->mbd.mtd->block_isbad(nftl->mbd.mtd, i * nftl->EraseSize))
246 nftl->ReplUnitTable[i] = BLOCK_RESERVED; 246 nftl->ReplUnitTable[i] = BLOCK_RESERVED;
247 } 247 }
248 248
249 nftl->MediaUnit = block; 249 nftl->MediaUnit = block;
250 boot_record_count++; 250 boot_record_count++;
251 251
252 } /* foreach (block) */ 252 } /* foreach (block) */
253 253
254 return boot_record_count?0:-1; 254 return boot_record_count?0:-1;
255} 255}
256 256
@@ -265,7 +265,7 @@ static int memcmpb(void *a, int c, int n)
265} 265}
266 266
267/* check_free_sector: check if a free sector is actually FREE, i.e. All 0xff in data and oob area */ 267/* check_free_sector: check if a free sector is actually FREE, i.e. All 0xff in data and oob area */
268static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len, 268static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len,
269 int check_oob) 269 int check_oob)
270{ 270{
271 int i; 271 int i;
@@ -293,7 +293,7 @@ static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int
293 * 293 *
294 * Return: 0 when succeed, -1 on error. 294 * Return: 0 when succeed, -1 on error.
295 * 295 *
296 * ToDo: 1. Is it neceressary to check_free_sector after erasing ?? 296 * ToDo: 1. Is it neceressary to check_free_sector after erasing ??
297 */ 297 */
298int NFTL_formatblock(struct NFTLrecord *nftl, int block) 298int NFTL_formatblock(struct NFTLrecord *nftl, int block)
299{ 299{
@@ -385,7 +385,7 @@ static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_b
385 /* verify that the sector is really free. If not, mark 385 /* verify that the sector is really free. If not, mark
386 as ignore */ 386 as ignore */
387 if (memcmpb(&bci, 0xff, 8) != 0 || 387 if (memcmpb(&bci, 0xff, 8) != 0 ||
388 check_free_sectors(nftl, block * nftl->EraseSize + i * SECTORSIZE, 388 check_free_sectors(nftl, block * nftl->EraseSize + i * SECTORSIZE,
389 SECTORSIZE, 0) != 0) { 389 SECTORSIZE, 0) != 0) {
390 printk("Incorrect free sector %d in block %d: " 390 printk("Incorrect free sector %d in block %d: "
391 "marking it as ignored\n", 391 "marking it as ignored\n",
@@ -486,7 +486,7 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
486 size_t retlen; 486 size_t retlen;
487 487
488 /* check erase mark. */ 488 /* check erase mark. */
489 if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 489 if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
490 &retlen, (char *)&h1) < 0) 490 &retlen, (char *)&h1) < 0)
491 return -1; 491 return -1;
492 492
@@ -501,7 +501,7 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
501 h1.EraseMark = cpu_to_le16(ERASE_MARK); 501 h1.EraseMark = cpu_to_le16(ERASE_MARK);
502 h1.EraseMark1 = cpu_to_le16(ERASE_MARK); 502 h1.EraseMark1 = cpu_to_le16(ERASE_MARK);
503 h1.WearInfo = cpu_to_le32(0); 503 h1.WearInfo = cpu_to_le32(0);
504 if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 504 if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
505 &retlen, (char *)&h1) < 0) 505 &retlen, (char *)&h1) < 0)
506 return -1; 506 return -1;
507 } else { 507 } else {
@@ -582,9 +582,9 @@ int NFTL_mount(struct NFTLrecord *s)
582 582
583 for (;;) { 583 for (;;) {
584 /* read the block header. If error, we format the chain */ 584 /* read the block header. If error, we format the chain */
585 if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8, 585 if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8,
586 &retlen, (char *)&h0) < 0 || 586 &retlen, (char *)&h0) < 0 ||
587 MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8, 587 MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8,
588 &retlen, (char *)&h1) < 0) { 588 &retlen, (char *)&h1) < 0) {
589 s->ReplUnitTable[block] = BLOCK_NIL; 589 s->ReplUnitTable[block] = BLOCK_NIL;
590 do_format_chain = 1; 590 do_format_chain = 1;
@@ -639,7 +639,7 @@ int NFTL_mount(struct NFTLrecord *s)
639 first_logical_block = logical_block; 639 first_logical_block = logical_block;
640 } else { 640 } else {
641 if (logical_block != first_logical_block) { 641 if (logical_block != first_logical_block) {
642 printk("Block %d: incorrect logical block: %d expected: %d\n", 642 printk("Block %d: incorrect logical block: %d expected: %d\n",
643 block, logical_block, first_logical_block); 643 block, logical_block, first_logical_block);
644 /* the chain is incorrect : we must format it, 644 /* the chain is incorrect : we must format it,
645 but we need to read it completly */ 645 but we need to read it completly */
@@ -668,7 +668,7 @@ int NFTL_mount(struct NFTLrecord *s)
668 s->ReplUnitTable[block] = BLOCK_NIL; 668 s->ReplUnitTable[block] = BLOCK_NIL;
669 break; 669 break;
670 } else if (rep_block >= s->nb_blocks) { 670 } else if (rep_block >= s->nb_blocks) {
671 printk("Block %d: referencing invalid block %d\n", 671 printk("Block %d: referencing invalid block %d\n",
672 block, rep_block); 672 block, rep_block);
673 do_format_chain = 1; 673 do_format_chain = 1;
674 s->ReplUnitTable[block] = BLOCK_NIL; 674 s->ReplUnitTable[block] = BLOCK_NIL;
@@ -688,7 +688,7 @@ int NFTL_mount(struct NFTLrecord *s)
688 s->ReplUnitTable[block] = rep_block; 688 s->ReplUnitTable[block] = rep_block;
689 s->EUNtable[first_logical_block] = BLOCK_NIL; 689 s->EUNtable[first_logical_block] = BLOCK_NIL;
690 } else { 690 } else {
691 printk("Block %d: referencing block %d already in another chain\n", 691 printk("Block %d: referencing block %d already in another chain\n",
692 block, rep_block); 692 block, rep_block);
693 /* XXX: should handle correctly fold in progress chains */ 693 /* XXX: should handle correctly fold in progress chains */
694 do_format_chain = 1; 694 do_format_chain = 1;
@@ -710,7 +710,7 @@ int NFTL_mount(struct NFTLrecord *s)
710 } else { 710 } else {
711 unsigned int first_block1, chain_to_format, chain_length1; 711 unsigned int first_block1, chain_to_format, chain_length1;
712 int fold_mark; 712 int fold_mark;
713 713
714 /* valid chain : get foldmark */ 714 /* valid chain : get foldmark */
715 fold_mark = get_fold_mark(s, first_block); 715 fold_mark = get_fold_mark(s, first_block);
716 if (fold_mark == 0) { 716 if (fold_mark == 0) {
@@ -729,9 +729,9 @@ int NFTL_mount(struct NFTLrecord *s)
729 if (first_block1 != BLOCK_NIL) { 729 if (first_block1 != BLOCK_NIL) {
730 /* XXX: what to do if same length ? */ 730 /* XXX: what to do if same length ? */
731 chain_length1 = calc_chain_length(s, first_block1); 731 chain_length1 = calc_chain_length(s, first_block1);
732 printk("Two chains at blocks %d (len=%d) and %d (len=%d)\n", 732 printk("Two chains at blocks %d (len=%d) and %d (len=%d)\n",
733 first_block1, chain_length1, first_block, chain_length); 733 first_block1, chain_length1, first_block, chain_length);
734 734
735 if (chain_length >= chain_length1) { 735 if (chain_length >= chain_length1) {
736 chain_to_format = first_block1; 736 chain_to_format = first_block1;
737 s->EUNtable[first_logical_block] = first_block; 737 s->EUNtable[first_logical_block] = first_block;
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
new file mode 100644
index 000000000000..126ff6bf63d5
--- /dev/null
+++ b/drivers/mtd/onenand/Kconfig
@@ -0,0 +1,38 @@
1#
2# linux/drivers/mtd/onenand/Kconfig
3#
4
5menu "OneNAND Flash Device Drivers"
6 depends on MTD != n
7
8config MTD_ONENAND
9 tristate "OneNAND Device Support"
10 depends on MTD
11 help
12 This enables support for accessing all type of OneNAND flash
13 devices. For further information see
14 <http://www.samsung.com/Products/Semiconductor/Flash/OneNAND_TM/index.htm>.
15
16config MTD_ONENAND_VERIFY_WRITE
17 bool "Verify OneNAND page writes"
18 depends on MTD_ONENAND
19 help
20 This adds an extra check when data is written to the flash. The
21 OneNAND flash device internally checks only bits transitioning
22 from 1 to 0. There is a rare possibility that even though the
23 device thinks the write was successful, a bit could have been
24 flipped accidentaly due to device wear or something else.
25
26config MTD_ONENAND_GENERIC
27 tristate "OneNAND Flash device via platform device driver"
28 depends on MTD_ONENAND && ARM
29 help
30 Support for OneNAND flash via platform device driver.
31
32config MTD_ONENAND_SYNC_READ
33 bool "OneNAND Sync. Burst Read Support"
34 depends on ARCH_OMAP
35 help
36 This enables support for Sync. Burst Read.
37
38endmenu
diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
new file mode 100644
index 000000000000..269cfe467345
--- /dev/null
+++ b/drivers/mtd/onenand/Makefile
@@ -0,0 +1,11 @@
1#
2# Makefile for the OneNAND MTD
3#
4
5# Core functionality.
6obj-$(CONFIG_MTD_ONENAND) += onenand.o
7
8# Board specific.
9obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o
10
11onenand-objs = onenand_base.o onenand_bbt.o
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
new file mode 100644
index 000000000000..48cce431f89f
--- /dev/null
+++ b/drivers/mtd/onenand/generic.c
@@ -0,0 +1,147 @@
1/*
2 * linux/drivers/mtd/onenand/generic.c
3 *
4 * Copyright (c) 2005 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Overview:
12 * This is a device driver for the OneNAND flash for generic boards.
13 */
14
15#include <linux/device.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/mtd/mtd.h>
19#include <linux/mtd/onenand.h>
20#include <linux/mtd/partitions.h>
21
22#include <asm/io.h>
23#include <asm/mach/flash.h>
24
25#define DRIVER_NAME "onenand"
26
27
28#ifdef CONFIG_MTD_PARTITIONS
29static const char *part_probes[] = { "cmdlinepart", NULL, };
30#endif
31
32struct onenand_info {
33 struct mtd_info mtd;
34 struct mtd_partition *parts;
35 struct onenand_chip onenand;
36};
37
38static int __devinit generic_onenand_probe(struct device *dev)
39{
40 struct onenand_info *info;
41 struct platform_device *pdev = to_platform_device(dev);
42 struct onenand_platform_data *pdata = pdev->dev.platform_data;
43 struct resource *res = pdev->resource;
44 unsigned long size = res->end - res->start + 1;
45 int err;
46
47 info = kmalloc(sizeof(struct onenand_info), GFP_KERNEL);
48 if (!info)
49 return -ENOMEM;
50
51 memset(info, 0, sizeof(struct onenand_info));
52
53 if (!request_mem_region(res->start, size, dev->driver->name)) {
54 err = -EBUSY;
55 goto out_free_info;
56 }
57
58 info->onenand.base = ioremap(res->start, size);
59 if (!info->onenand.base) {
60 err = -ENOMEM;
61 goto out_release_mem_region;
62 }
63
64 info->onenand.mmcontrol = pdata->mmcontrol;
65
66 info->mtd.name = pdev->dev.bus_id;
67 info->mtd.priv = &info->onenand;
68 info->mtd.owner = THIS_MODULE;
69
70 if (onenand_scan(&info->mtd, 1)) {
71 err = -ENXIO;
72 goto out_iounmap;
73 }
74
75#ifdef CONFIG_MTD_PARTITIONS
76 err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);
77 if (err > 0)
78 add_mtd_partitions(&info->mtd, info->parts, err);
79 else if (err < 0 && pdata->parts)
80 add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts);
81 else
82#endif
83 err = add_mtd_device(&info->mtd);
84
85 dev_set_drvdata(&pdev->dev, info);
86
87 return 0;
88
89out_iounmap:
90 iounmap(info->onenand.base);
91out_release_mem_region:
92 release_mem_region(res->start, size);
93out_free_info:
94 kfree(info);
95
96 return err;
97}
98
99static int __devexit generic_onenand_remove(struct device *dev)
100{
101 struct platform_device *pdev = to_platform_device(dev);
102 struct onenand_info *info = dev_get_drvdata(&pdev->dev);
103 struct resource *res = pdev->resource;
104 unsigned long size = res->end - res->start + 1;
105
106 dev_set_drvdata(&pdev->dev, NULL);
107
108 if (info) {
109 if (info->parts)
110 del_mtd_partitions(&info->mtd);
111 else
112 del_mtd_device(&info->mtd);
113
114 onenand_release(&info->mtd);
115 release_mem_region(res->start, size);
116 iounmap(info->onenand.base);
117 kfree(info);
118 }
119
120 return 0;
121}
122
123static struct device_driver generic_onenand_driver = {
124 .name = DRIVER_NAME,
125 .bus = &platform_bus_type,
126 .probe = generic_onenand_probe,
127 .remove = __devexit_p(generic_onenand_remove),
128};
129
130MODULE_ALIAS(DRIVER_NAME);
131
132static int __init generic_onenand_init(void)
133{
134 return driver_register(&generic_onenand_driver);
135}
136
137static void __exit generic_onenand_exit(void)
138{
139 driver_unregister(&generic_onenand_driver);
140}
141
142module_init(generic_onenand_init);
143module_exit(generic_onenand_exit);
144
145MODULE_LICENSE("GPL");
146MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
147MODULE_DESCRIPTION("Glue layer for OneNAND flash on generic boards");
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
new file mode 100644
index 000000000000..cc38fa0d45c6
--- /dev/null
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -0,0 +1,1588 @@
1/*
2 * linux/drivers/mtd/onenand/onenand_base.c
3 *
4 * Copyright (C) 2005 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/mtd/mtd.h>
16#include <linux/mtd/onenand.h>
17#include <linux/mtd/partitions.h>
18
19#include <asm/io.h>
20
21/**
22 * onenand_oob_64 - oob info for large (2KB) page
23 */
24static struct nand_oobinfo onenand_oob_64 = {
25 .useecc = MTD_NANDECC_AUTOPLACE,
26 .eccbytes = 20,
27 .eccpos = {
28 8, 9, 10, 11, 12,
29 24, 25, 26, 27, 28,
30 40, 41, 42, 43, 44,
31 56, 57, 58, 59, 60,
32 },
33 .oobfree = {
34 {2, 3}, {14, 2}, {18, 3}, {30, 2},
35 {24, 3}, {46, 2}, {40, 3}, {62, 2} }
36};
37
38/**
39 * onenand_oob_32 - oob info for middle (1KB) page
40 */
41static struct nand_oobinfo onenand_oob_32 = {
42 .useecc = MTD_NANDECC_AUTOPLACE,
43 .eccbytes = 10,
44 .eccpos = {
45 8, 9, 10, 11, 12,
46 24, 25, 26, 27, 28,
47 },
48 .oobfree = { {2, 3}, {14, 2}, {18, 3}, {30, 2} }
49};
50
51static const unsigned char ffchars[] = {
52 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
53 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 */
54 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
55 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 32 */
56 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
57 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */
58 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
59 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */
60};
61
62/**
63 * onenand_readw - [OneNAND Interface] Read OneNAND register
64 * @param addr address to read
65 *
66 * Read OneNAND register
67 */
68static unsigned short onenand_readw(void __iomem *addr)
69{
70 return readw(addr);
71}
72
73/**
74 * onenand_writew - [OneNAND Interface] Write OneNAND register with value
75 * @param value value to write
76 * @param addr address to write
77 *
78 * Write OneNAND register with value
79 */
80static void onenand_writew(unsigned short value, void __iomem *addr)
81{
82 writew(value, addr);
83}
84
85/**
86 * onenand_block_address - [DEFAULT] Get block address
87 * @param this onenand chip data structure
88 * @param block the block
89 * @return translated block address if DDP, otherwise same
90 *
91 * Setup Start Address 1 Register (F100h)
92 */
93static int onenand_block_address(struct onenand_chip *this, int block)
94{
95 if (this->device_id & ONENAND_DEVICE_IS_DDP) {
96 /* Device Flash Core select, NAND Flash Block Address */
97 int dfs = 0;
98
99 if (block & this->density_mask)
100 dfs = 1;
101
102 return (dfs << ONENAND_DDP_SHIFT) |
103 (block & (this->density_mask - 1));
104 }
105
106 return block;
107}
108
109/**
110 * onenand_bufferram_address - [DEFAULT] Get bufferram address
111 * @param this onenand chip data structure
112 * @param block the block
113 * @return set DBS value if DDP, otherwise 0
114 *
115 * Setup Start Address 2 Register (F101h) for DDP
116 */
117static int onenand_bufferram_address(struct onenand_chip *this, int block)
118{
119 if (this->device_id & ONENAND_DEVICE_IS_DDP) {
120 /* Device BufferRAM Select */
121 int dbs = 0;
122
123 if (block & this->density_mask)
124 dbs = 1;
125
126 return (dbs << ONENAND_DDP_SHIFT);
127 }
128
129 return 0;
130}
131
132/**
133 * onenand_page_address - [DEFAULT] Get page address
134 * @param page the page address
135 * @param sector the sector address
136 * @return combined page and sector address
137 *
138 * Setup Start Address 8 Register (F107h)
139 */
140static int onenand_page_address(int page, int sector)
141{
142 /* Flash Page Address, Flash Sector Address */
143 int fpa, fsa;
144
145 fpa = page & ONENAND_FPA_MASK;
146 fsa = sector & ONENAND_FSA_MASK;
147
148 return ((fpa << ONENAND_FPA_SHIFT) | fsa);
149}
150
151/**
152 * onenand_buffer_address - [DEFAULT] Get buffer address
153 * @param dataram1 DataRAM index
154 * @param sectors the sector address
155 * @param count the number of sectors
156 * @return the start buffer value
157 *
158 * Setup Start Buffer Register (F200h)
159 */
160static int onenand_buffer_address(int dataram1, int sectors, int count)
161{
162 int bsa, bsc;
163
164 /* BufferRAM Sector Address */
165 bsa = sectors & ONENAND_BSA_MASK;
166
167 if (dataram1)
168 bsa |= ONENAND_BSA_DATARAM1; /* DataRAM1 */
169 else
170 bsa |= ONENAND_BSA_DATARAM0; /* DataRAM0 */
171
172 /* BufferRAM Sector Count */
173 bsc = count & ONENAND_BSC_MASK;
174
175 return ((bsa << ONENAND_BSA_SHIFT) | bsc);
176}
177
178/**
179 * onenand_command - [DEFAULT] Send command to OneNAND device
180 * @param mtd MTD device structure
181 * @param cmd the command to be sent
182 * @param addr offset to read from or write to
183 * @param len number of bytes to read or write
184 *
185 * Send command to OneNAND device. This function is used for middle/large page
186 * devices (1KB/2KB Bytes per page)
187 */
188static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t len)
189{
190 struct onenand_chip *this = mtd->priv;
191 int value, readcmd = 0;
192 int block, page;
193 /* Now we use page size operation */
194 int sectors = 4, count = 4;
195
196 /* Address translation */
197 switch (cmd) {
198 case ONENAND_CMD_UNLOCK:
199 case ONENAND_CMD_LOCK:
200 case ONENAND_CMD_LOCK_TIGHT:
201 block = -1;
202 page = -1;
203 break;
204
205 case ONENAND_CMD_ERASE:
206 case ONENAND_CMD_BUFFERRAM:
207 block = (int) (addr >> this->erase_shift);
208 page = -1;
209 break;
210
211 default:
212 block = (int) (addr >> this->erase_shift);
213 page = (int) (addr >> this->page_shift);
214 page &= this->page_mask;
215 break;
216 }
217
218 /* NOTE: The setting order of the registers is very important! */
219 if (cmd == ONENAND_CMD_BUFFERRAM) {
220 /* Select DataRAM for DDP */
221 value = onenand_bufferram_address(this, block);
222 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
223
224 /* Switch to the next data buffer */
225 ONENAND_SET_NEXT_BUFFERRAM(this);
226
227 return 0;
228 }
229
230 if (block != -1) {
231 /* Write 'DFS, FBA' of Flash */
232 value = onenand_block_address(this, block);
233 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
234 }
235
236 if (page != -1) {
237 int dataram;
238
239 switch (cmd) {
240 case ONENAND_CMD_READ:
241 case ONENAND_CMD_READOOB:
242 dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
243 readcmd = 1;
244 break;
245
246 default:
247 dataram = ONENAND_CURRENT_BUFFERRAM(this);
248 break;
249 }
250
251 /* Write 'FPA, FSA' of Flash */
252 value = onenand_page_address(page, sectors);
253 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS8);
254
255 /* Write 'BSA, BSC' of DataRAM */
256 value = onenand_buffer_address(dataram, sectors, count);
257 this->write_word(value, this->base + ONENAND_REG_START_BUFFER);
258
259 if (readcmd) {
260 /* Select DataRAM for DDP */
261 value = onenand_bufferram_address(this, block);
262 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
263 }
264 }
265
266 /* Interrupt clear */
267 this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT);
268
269 /* Write command */
270 this->write_word(cmd, this->base + ONENAND_REG_COMMAND);
271
272 return 0;
273}
274
275/**
276 * onenand_wait - [DEFAULT] wait until the command is done
277 * @param mtd MTD device structure
278 * @param state state to select the max. timeout value
279 *
280 * Wait for command done. This applies to all OneNAND command
281 * Read can take up to 30us, erase up to 2ms and program up to 350us
282 * according to general OneNAND specs
283 */
284static int onenand_wait(struct mtd_info *mtd, int state)
285{
286 struct onenand_chip * this = mtd->priv;
287 unsigned long timeout;
288 unsigned int flags = ONENAND_INT_MASTER;
289 unsigned int interrupt = 0;
290 unsigned int ctrl, ecc;
291
292 /* The 20 msec is enough */
293 timeout = jiffies + msecs_to_jiffies(20);
294 while (time_before(jiffies, timeout)) {
295 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
296
297 if (interrupt & flags)
298 break;
299
300 if (state != FL_READING)
301 cond_resched();
302 }
303 /* To get correct interrupt status in timeout case */
304 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
305
306 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
307
308 if (ctrl & ONENAND_CTRL_ERROR) {
309 /* It maybe occur at initial bad block */
310 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl);
311 /* Clear other interrupt bits for preventing ECC error */
312 interrupt &= ONENAND_INT_MASTER;
313 }
314
315 if (ctrl & ONENAND_CTRL_LOCK) {
316 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error = 0x%04x\n", ctrl);
317 return -EACCES;
318 }
319
320 if (interrupt & ONENAND_INT_READ) {
321 ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
322 if (ecc & ONENAND_ECC_2BIT_ALL) {
323 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x\n", ecc);
324 return -EBADMSG;
325 }
326 }
327
328 return 0;
329}
330
331/**
332 * onenand_bufferram_offset - [DEFAULT] BufferRAM offset
333 * @param mtd MTD data structure
334 * @param area BufferRAM area
335 * @return offset given area
336 *
337 * Return BufferRAM offset given area
338 */
339static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
340{
341 struct onenand_chip *this = mtd->priv;
342
343 if (ONENAND_CURRENT_BUFFERRAM(this)) {
344 if (area == ONENAND_DATARAM)
345 return mtd->oobblock;
346 if (area == ONENAND_SPARERAM)
347 return mtd->oobsize;
348 }
349
350 return 0;
351}
352
353/**
354 * onenand_read_bufferram - [OneNAND Interface] Read the bufferram area
355 * @param mtd MTD data structure
356 * @param area BufferRAM area
357 * @param buffer the databuffer to put/get data
358 * @param offset offset to read from or write to
359 * @param count number of bytes to read/write
360 *
361 * Read the BufferRAM area
362 */
363static int onenand_read_bufferram(struct mtd_info *mtd, int area,
364 unsigned char *buffer, int offset, size_t count)
365{
366 struct onenand_chip *this = mtd->priv;
367 void __iomem *bufferram;
368
369 bufferram = this->base + area;
370
371 bufferram += onenand_bufferram_offset(mtd, area);
372
373 memcpy(buffer, bufferram + offset, count);
374
375 return 0;
376}
377
378/**
379 * onenand_sync_read_bufferram - [OneNAND Interface] Read the bufferram area with Sync. Burst mode
380 * @param mtd MTD data structure
381 * @param area BufferRAM area
382 * @param buffer the databuffer to put/get data
383 * @param offset offset to read from or write to
384 * @param count number of bytes to read/write
385 *
386 * Read the BufferRAM area with Sync. Burst Mode
387 */
388static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
389 unsigned char *buffer, int offset, size_t count)
390{
391 struct onenand_chip *this = mtd->priv;
392 void __iomem *bufferram;
393
394 bufferram = this->base + area;
395
396 bufferram += onenand_bufferram_offset(mtd, area);
397
398 this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
399
400 memcpy(buffer, bufferram + offset, count);
401
402 this->mmcontrol(mtd, 0);
403
404 return 0;
405}
406
407/**
408 * onenand_write_bufferram - [OneNAND Interface] Write the bufferram area
409 * @param mtd MTD data structure
410 * @param area BufferRAM area
411 * @param buffer the databuffer to put/get data
412 * @param offset offset to read from or write to
413 * @param count number of bytes to read/write
414 *
415 * Write the BufferRAM area
416 */
417static int onenand_write_bufferram(struct mtd_info *mtd, int area,
418 const unsigned char *buffer, int offset, size_t count)
419{
420 struct onenand_chip *this = mtd->priv;
421 void __iomem *bufferram;
422
423 bufferram = this->base + area;
424
425 bufferram += onenand_bufferram_offset(mtd, area);
426
427 memcpy(bufferram + offset, buffer, count);
428
429 return 0;
430}
431
432/**
433 * onenand_check_bufferram - [GENERIC] Check BufferRAM information
434 * @param mtd MTD data structure
435 * @param addr address to check
436 * @return 1 if there are valid data, otherwise 0
437 *
438 * Check bufferram if there is data we required
439 */
440static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
441{
442 struct onenand_chip *this = mtd->priv;
443 int block, page;
444 int i;
445
446 block = (int) (addr >> this->erase_shift);
447 page = (int) (addr >> this->page_shift);
448 page &= this->page_mask;
449
450 i = ONENAND_CURRENT_BUFFERRAM(this);
451
452 /* Is there valid data? */
453 if (this->bufferram[i].block == block &&
454 this->bufferram[i].page == page &&
455 this->bufferram[i].valid)
456 return 1;
457
458 return 0;
459}
460
461/**
462 * onenand_update_bufferram - [GENERIC] Update BufferRAM information
463 * @param mtd MTD data structure
464 * @param addr address to update
465 * @param valid valid flag
466 *
467 * Update BufferRAM information
468 */
469static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
470 int valid)
471{
472 struct onenand_chip *this = mtd->priv;
473 int block, page;
474 int i;
475
476 block = (int) (addr >> this->erase_shift);
477 page = (int) (addr >> this->page_shift);
478 page &= this->page_mask;
479
480 /* Invalidate BufferRAM */
481 for (i = 0; i < MAX_BUFFERRAM; i++) {
482 if (this->bufferram[i].block == block &&
483 this->bufferram[i].page == page)
484 this->bufferram[i].valid = 0;
485 }
486
487 /* Update BufferRAM */
488 i = ONENAND_CURRENT_BUFFERRAM(this);
489 this->bufferram[i].block = block;
490 this->bufferram[i].page = page;
491 this->bufferram[i].valid = valid;
492
493 return 0;
494}
495
496/**
497 * onenand_get_device - [GENERIC] Get chip for selected access
498 * @param mtd MTD device structure
499 * @param new_state the state which is requested
500 *
501 * Get the device and lock it for exclusive access
502 */
503static int onenand_get_device(struct mtd_info *mtd, int new_state)
504{
505 struct onenand_chip *this = mtd->priv;
506 DECLARE_WAITQUEUE(wait, current);
507
508 /*
509 * Grab the lock and see if the device is available
510 */
511 while (1) {
512 spin_lock(&this->chip_lock);
513 if (this->state == FL_READY) {
514 this->state = new_state;
515 spin_unlock(&this->chip_lock);
516 break;
517 }
518 if (new_state == FL_PM_SUSPENDED) {
519 spin_unlock(&this->chip_lock);
520 return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
521 }
522 set_current_state(TASK_UNINTERRUPTIBLE);
523 add_wait_queue(&this->wq, &wait);
524 spin_unlock(&this->chip_lock);
525 schedule();
526 remove_wait_queue(&this->wq, &wait);
527 }
528
529 return 0;
530}
531
532/**
533 * onenand_release_device - [GENERIC] release chip
534 * @param mtd MTD device structure
535 *
536 * Deselect, release chip lock and wake up anyone waiting on the device
537 */
538static void onenand_release_device(struct mtd_info *mtd)
539{
540 struct onenand_chip *this = mtd->priv;
541
542 /* Release the chip */
543 spin_lock(&this->chip_lock);
544 this->state = FL_READY;
545 wake_up(&this->wq);
546 spin_unlock(&this->chip_lock);
547}
548
549/**
550 * onenand_read_ecc - [MTD Interface] Read data with ECC
551 * @param mtd MTD device structure
552 * @param from offset to read from
553 * @param len number of bytes to read
554 * @param retlen pointer to variable to store the number of read bytes
555 * @param buf the databuffer to put data
556 * @param oob_buf filesystem supplied oob data buffer
557 * @param oobsel oob selection structure
558 *
559 * OneNAND read with ECC
560 */
561static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
562 size_t *retlen, u_char *buf,
563 u_char *oob_buf, struct nand_oobinfo *oobsel)
564{
565 struct onenand_chip *this = mtd->priv;
566 int read = 0, column;
567 int thislen;
568 int ret = 0;
569
570 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
571
572 /* Do not allow reads past end of device */
573 if ((from + len) > mtd->size) {
574 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: Attempt read beyond end of device\n");
575 *retlen = 0;
576 return -EINVAL;
577 }
578
579 /* Grab the lock and see if the device is available */
580 onenand_get_device(mtd, FL_READING);
581
582 /* TODO handling oob */
583
584 while (read < len) {
585 thislen = min_t(int, mtd->oobblock, len - read);
586
587 column = from & (mtd->oobblock - 1);
588 if (column + thislen > mtd->oobblock)
589 thislen = mtd->oobblock - column;
590
591 if (!onenand_check_bufferram(mtd, from)) {
592 this->command(mtd, ONENAND_CMD_READ, from, mtd->oobblock);
593
594 ret = this->wait(mtd, FL_READING);
595 /* First copy data and check return value for ECC handling */
596 onenand_update_bufferram(mtd, from, 1);
597 }
598
599 this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
600
601 read += thislen;
602
603 if (read == len)
604 break;
605
606 if (ret) {
607 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: read failed = %d\n", ret);
608 goto out;
609 }
610
611 from += thislen;
612 buf += thislen;
613 }
614
615out:
616 /* Deselect and wake up anyone waiting on the device */
617 onenand_release_device(mtd);
618
619 /*
620 * Return success, if no ECC failures, else -EBADMSG
621 * fs driver will take care of that, because
622 * retlen == desired len and result == -EBADMSG
623 */
624 *retlen = read;
625 return ret;
626}
627
628/**
629 * onenand_read - [MTD Interface] MTD compability function for onenand_read_ecc
630 * @param mtd MTD device structure
631 * @param from offset to read from
632 * @param len number of bytes to read
633 * @param retlen pointer to variable to store the number of read bytes
634 * @param buf the databuffer to put data
635 *
636 * This function simply calls onenand_read_ecc with oob buffer and oobsel = NULL
637*/
638static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
639 size_t *retlen, u_char *buf)
640{
641 return onenand_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
642}
643
644/**
645 * onenand_read_oob - [MTD Interface] OneNAND read out-of-band
646 * @param mtd MTD device structure
647 * @param from offset to read from
648 * @param len number of bytes to read
649 * @param retlen pointer to variable to store the number of read bytes
650 * @param buf the databuffer to put data
651 *
652 * OneNAND read out-of-band data from the spare area
653 */
654static int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
655 size_t *retlen, u_char *buf)
656{
657 struct onenand_chip *this = mtd->priv;
658 int read = 0, thislen, column;
659 int ret = 0;
660
661 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
662
663 /* Initialize return length value */
664 *retlen = 0;
665
666 /* Do not allow reads past end of device */
667 if (unlikely((from + len) > mtd->size)) {
668 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: Attempt read beyond end of device\n");
669 return -EINVAL;
670 }
671
672 /* Grab the lock and see if the device is available */
673 onenand_get_device(mtd, FL_READING);
674
675 column = from & (mtd->oobsize - 1);
676
677 while (read < len) {
678 thislen = mtd->oobsize - column;
679 thislen = min_t(int, thislen, len);
680
681 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
682
683 onenand_update_bufferram(mtd, from, 0);
684
685 ret = this->wait(mtd, FL_READING);
686 /* First copy data and check return value for ECC handling */
687
688 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
689
690 read += thislen;
691
692 if (read == len)
693 break;
694
695 if (ret) {
696 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = %d\n", ret);
697 goto out;
698 }
699
700 buf += thislen;
701
702 /* Read more? */
703 if (read < len) {
704 /* Page size */
705 from += mtd->oobblock;
706 column = 0;
707 }
708 }
709
710out:
711 /* Deselect and wake up anyone waiting on the device */
712 onenand_release_device(mtd);
713
714 *retlen = read;
715 return ret;
716}
717
718#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
719/**
720 * onenand_verify_page - [GENERIC] verify the chip contents after a write
721 * @param mtd MTD device structure
722 * @param buf the databuffer to verify
723 *
724 * Check DataRAM area directly
725 */
726static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr)
727{
728 struct onenand_chip *this = mtd->priv;
729 void __iomem *dataram0, *dataram1;
730 int ret = 0;
731
732 this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock);
733
734 ret = this->wait(mtd, FL_READING);
735 if (ret)
736 return ret;
737
738 onenand_update_bufferram(mtd, addr, 1);
739
740 /* Check, if the two dataram areas are same */
741 dataram0 = this->base + ONENAND_DATARAM;
742 dataram1 = dataram0 + mtd->oobblock;
743
744 if (memcmp(dataram0, dataram1, mtd->oobblock))
745 return -EBADMSG;
746
747 return 0;
748}
749#else
750#define onenand_verify_page(...) (0)
751#endif
752
753#define NOTALIGNED(x) ((x & (mtd->oobblock - 1)) != 0)
754
755/**
756 * onenand_write_ecc - [MTD Interface] OneNAND write with ECC
757 * @param mtd MTD device structure
758 * @param to offset to write to
759 * @param len number of bytes to write
760 * @param retlen pointer to variable to store the number of written bytes
761 * @param buf the data to write
762 * @param eccbuf filesystem supplied oob data buffer
763 * @param oobsel oob selection structure
764 *
765 * OneNAND write with ECC
766 */
767static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
768 size_t *retlen, const u_char *buf,
769 u_char *eccbuf, struct nand_oobinfo *oobsel)
770{
771 struct onenand_chip *this = mtd->priv;
772 int written = 0;
773 int ret = 0;
774
775 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
776
777 /* Initialize retlen, in case of early exit */
778 *retlen = 0;
779
780 /* Do not allow writes past end of device */
781 if (unlikely((to + len) > mtd->size)) {
782 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt write to past end of device\n");
783 return -EINVAL;
784 }
785
786 /* Reject writes, which are not page aligned */
787 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
788 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt to write not page aligned data\n");
789 return -EINVAL;
790 }
791
792 /* Grab the lock and see if the device is available */
793 onenand_get_device(mtd, FL_WRITING);
794
795 /* Loop until all data write */
796 while (written < len) {
797 int thislen = min_t(int, mtd->oobblock, len - written);
798
799 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
800
801 this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);
802 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
803
804 this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
805
806 onenand_update_bufferram(mtd, to, 1);
807
808 ret = this->wait(mtd, FL_WRITING);
809 if (ret) {
810 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: write filaed %d\n", ret);
811 goto out;
812 }
813
814 written += thislen;
815
816 /* Only check verify write turn on */
817 ret = onenand_verify_page(mtd, (u_char *) buf, to);
818 if (ret) {
819 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: verify failed %d\n", ret);
820 goto out;
821 }
822
823 if (written == len)
824 break;
825
826 to += thislen;
827 buf += thislen;
828 }
829
830out:
831 /* Deselect and wake up anyone waiting on the device */
832 onenand_release_device(mtd);
833
834 *retlen = written;
835
836 return ret;
837}
838
839/**
840 * onenand_write - [MTD Interface] compability function for onenand_write_ecc
841 * @param mtd MTD device structure
842 * @param to offset to write to
843 * @param len number of bytes to write
844 * @param retlen pointer to variable to store the number of written bytes
845 * @param buf the data to write
846 *
847 * This function simply calls onenand_write_ecc
848 * with oob buffer and oobsel = NULL
849 */
850static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
851 size_t *retlen, const u_char *buf)
852{
853 return onenand_write_ecc(mtd, to, len, retlen, buf, NULL, NULL);
854}
855
856/**
857 * onenand_write_oob - [MTD Interface] OneNAND write out-of-band
858 * @param mtd MTD device structure
859 * @param to offset to write to
860 * @param len number of bytes to write
861 * @param retlen pointer to variable to store the number of written bytes
862 * @param buf the data to write
863 *
864 * OneNAND write out-of-band
865 */
866static int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
867 size_t *retlen, const u_char *buf)
868{
869 struct onenand_chip *this = mtd->priv;
870 int column, status;
871 int written = 0;
872
873 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
874
875 /* Initialize retlen, in case of early exit */
876 *retlen = 0;
877
878 /* Do not allow writes past end of device */
879 if (unlikely((to + len) > mtd->size)) {
880 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: Attempt write to past end of device\n");
881 return -EINVAL;
882 }
883
884 /* Grab the lock and see if the device is available */
885 onenand_get_device(mtd, FL_WRITING);
886
887 /* Loop until all data write */
888 while (written < len) {
889 int thislen = min_t(int, mtd->oobsize, len - written);
890
891 column = to & (mtd->oobsize - 1);
892
893 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
894
895 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
896 this->write_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
897
898 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
899
900 onenand_update_bufferram(mtd, to, 0);
901
902 status = this->wait(mtd, FL_WRITING);
903 if (status)
904 goto out;
905
906 written += thislen;
907
908 if (written == len)
909 break;
910
911 to += thislen;
912 buf += thislen;
913 }
914
915out:
916 /* Deselect and wake up anyone waiting on the device */
917 onenand_release_device(mtd);
918
919 *retlen = written;
920
921 return 0;
922}
923
924/**
925 * onenand_writev_ecc - [MTD Interface] write with iovec with ecc
926 * @param mtd MTD device structure
927 * @param vecs the iovectors to write
928 * @param count number of vectors
929 * @param to offset to write to
930 * @param retlen pointer to variable to store the number of written bytes
931 * @param eccbuf filesystem supplied oob data buffer
932 * @param oobsel oob selection structure
933 *
934 * OneNAND write with iovec with ecc
935 */
936static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
937 unsigned long count, loff_t to, size_t *retlen,
938 u_char *eccbuf, struct nand_oobinfo *oobsel)
939{
940 struct onenand_chip *this = mtd->priv;
941 unsigned char buffer[MAX_ONENAND_PAGESIZE], *pbuf;
942 size_t total_len, len;
943 int i, written = 0;
944 int ret = 0;
945
946 /* Preset written len for early exit */
947 *retlen = 0;
948
949 /* Calculate total length of data */
950 total_len = 0;
951 for (i = 0; i < count; i++)
952 total_len += vecs[i].iov_len;
953
954 DEBUG(MTD_DEBUG_LEVEL3, "onenand_writev_ecc: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
955
956 /* Do not allow write past end of the device */
957 if (unlikely((to + total_len) > mtd->size)) {
958 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempted write past end of device\n");
959 return -EINVAL;
960 }
961
962 /* Reject writes, which are not page aligned */
963 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(total_len))) {
964 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempt to write not page aligned data\n");
965 return -EINVAL;
966 }
967
968 /* Grab the lock and see if the device is available */
969 onenand_get_device(mtd, FL_WRITING);
970
971 /* TODO handling oob */
972
973 /* Loop until all keve's data has been written */
974 len = 0;
975 while (count) {
976 pbuf = buffer;
977 /*
978 * If the given tuple is >= pagesize then
979 * write it out from the iov
980 */
981 if ((vecs->iov_len - len) >= mtd->oobblock) {
982 pbuf = vecs->iov_base + len;
983
984 len += mtd->oobblock;
985
986 /* Check, if we have to switch to the next tuple */
987 if (len >= (int) vecs->iov_len) {
988 vecs++;
989 len = 0;
990 count--;
991 }
992 } else {
993 int cnt = 0, thislen;
994 while (cnt < mtd->oobblock) {
995 thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len);
996 memcpy(buffer + cnt, vecs->iov_base + len, thislen);
997 cnt += thislen;
998 len += thislen;
999
1000 /* Check, if we have to switch to the next tuple */
1001 if (len >= (int) vecs->iov_len) {
1002 vecs++;
1003 len = 0;
1004 count--;
1005 }
1006 }
1007 }
1008
1009 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
1010
1011 this->write_bufferram(mtd, ONENAND_DATARAM, pbuf, 0, mtd->oobblock);
1012 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
1013
1014 this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
1015
1016 onenand_update_bufferram(mtd, to, 1);
1017
1018 ret = this->wait(mtd, FL_WRITING);
1019 if (ret) {
1020 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: write failed %d\n", ret);
1021 goto out;
1022 }
1023
1024
1025 /* Only check verify write turn on */
1026 ret = onenand_verify_page(mtd, (u_char *) pbuf, to);
1027 if (ret) {
1028 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: verify failed %d\n", ret);
1029 goto out;
1030 }
1031
1032 written += mtd->oobblock;
1033
1034 to += mtd->oobblock;
1035 }
1036
1037out:
1038 /* Deselect and wakt up anyone waiting on the device */
1039 onenand_release_device(mtd);
1040
1041 *retlen = written;
1042
1043 return 0;
1044}
1045
1046/**
1047 * onenand_writev - [MTD Interface] compabilty function for onenand_writev_ecc
1048 * @param mtd MTD device structure
1049 * @param vecs the iovectors to write
1050 * @param count number of vectors
1051 * @param to offset to write to
1052 * @param retlen pointer to variable to store the number of written bytes
1053 *
1054 * OneNAND write with kvec. This just calls the ecc function
1055 */
1056static int onenand_writev(struct mtd_info *mtd, const struct kvec *vecs,
1057 unsigned long count, loff_t to, size_t *retlen)
1058{
1059 return onenand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL);
1060}
1061
1062/**
1063 * onenand_block_checkbad - [GENERIC] Check if a block is marked bad
1064 * @param mtd MTD device structure
1065 * @param ofs offset from device start
1066 * @param getchip 0, if the chip is already selected
1067 * @param allowbbt 1, if its allowed to access the bbt area
1068 *
1069 * Check, if the block is bad. Either by reading the bad block table or
1070 * calling of the scan function.
1071 */
1072static int onenand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
1073{
1074 struct onenand_chip *this = mtd->priv;
1075 struct bbm_info *bbm = this->bbm;
1076
1077 /* Return info from the table */
1078 return bbm->isbad_bbt(mtd, ofs, allowbbt);
1079}
1080
1081/**
1082 * onenand_erase - [MTD Interface] erase block(s)
1083 * @param mtd MTD device structure
1084 * @param instr erase instruction
1085 *
1086 * Erase one ore more blocks
1087 */
1088static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1089{
1090 struct onenand_chip *this = mtd->priv;
1091 unsigned int block_size;
1092 loff_t addr;
1093 int len;
1094 int ret = 0;
1095
1096 DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len);
1097
1098 block_size = (1 << this->erase_shift);
1099
1100 /* Start address must align on block boundary */
1101 if (unlikely(instr->addr & (block_size - 1))) {
1102 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Unaligned address\n");
1103 return -EINVAL;
1104 }
1105
1106 /* Length must align on block boundary */
1107 if (unlikely(instr->len & (block_size - 1))) {
1108 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Length not block aligned\n");
1109 return -EINVAL;
1110 }
1111
1112 /* Do not allow erase past end of device */
1113 if (unlikely((instr->len + instr->addr) > mtd->size)) {
1114 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Erase past end of device\n");
1115 return -EINVAL;
1116 }
1117
1118 instr->fail_addr = 0xffffffff;
1119
1120 /* Grab the lock and see if the device is available */
1121 onenand_get_device(mtd, FL_ERASING);
1122
1123 /* Loop throught the pages */
1124 len = instr->len;
1125 addr = instr->addr;
1126
1127 instr->state = MTD_ERASING;
1128
1129 while (len) {
1130
1131 /* Check if we have a bad block, we do not erase bad blocks */
1132 if (onenand_block_checkbad(mtd, addr, 0, 0)) {
1133 printk (KERN_WARNING "onenand_erase: attempt to erase a bad block at addr 0x%08x\n", (unsigned int) addr);
1134 instr->state = MTD_ERASE_FAILED;
1135 goto erase_exit;
1136 }
1137
1138 this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
1139
1140 ret = this->wait(mtd, FL_ERASING);
1141 /* Check, if it is write protected */
1142 if (ret) {
1143 if (ret == -EPERM)
1144 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Device is write protected!!!\n");
1145 else
1146 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));
1147 instr->state = MTD_ERASE_FAILED;
1148 instr->fail_addr = addr;
1149 goto erase_exit;
1150 }
1151
1152 len -= block_size;
1153 addr += block_size;
1154 }
1155
1156 instr->state = MTD_ERASE_DONE;
1157
1158erase_exit:
1159
1160 ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
1161 /* Do call back function */
1162 if (!ret)
1163 mtd_erase_callback(instr);
1164
1165 /* Deselect and wake up anyone waiting on the device */
1166 onenand_release_device(mtd);
1167
1168 return ret;
1169}
1170
1171/**
1172 * onenand_sync - [MTD Interface] sync
1173 * @param mtd MTD device structure
1174 *
1175 * Sync is actually a wait for chip ready function
1176 */
1177static void onenand_sync(struct mtd_info *mtd)
1178{
1179 DEBUG(MTD_DEBUG_LEVEL3, "onenand_sync: called\n");
1180
1181 /* Grab the lock and see if the device is available */
1182 onenand_get_device(mtd, FL_SYNCING);
1183
1184 /* Release it and go back */
1185 onenand_release_device(mtd);
1186}
1187
1188
1189/**
1190 * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
1191 * @param mtd MTD device structure
1192 * @param ofs offset relative to mtd start
1193 *
1194 * Check whether the block is bad
1195 */
1196static int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
1197{
1198 /* Check for invalid offset */
1199 if (ofs > mtd->size)
1200 return -EINVAL;
1201
1202 return onenand_block_checkbad(mtd, ofs, 1, 0);
1203}
1204
1205/**
1206 * onenand_default_block_markbad - [DEFAULT] mark a block bad
1207 * @param mtd MTD device structure
1208 * @param ofs offset from device start
1209 *
1210 * This is the default implementation, which can be overridden by
1211 * a hardware specific driver.
1212 */
1213static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
1214{
1215 struct onenand_chip *this = mtd->priv;
1216 struct bbm_info *bbm = this->bbm;
1217 u_char buf[2] = {0, 0};
1218 size_t retlen;
1219 int block;
1220
1221 /* Get block number */
1222 block = ((int) ofs) >> bbm->bbt_erase_shift;
1223 if (bbm->bbt)
1224 bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
1225
1226 /* We write two bytes, so we dont have to mess with 16 bit access */
1227 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
1228 return mtd->write_oob(mtd, ofs , 2, &retlen, buf);
1229}
1230
1231/**
1232 * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
1233 * @param mtd MTD device structure
1234 * @param ofs offset relative to mtd start
1235 *
1236 * Mark the block as bad
1237 */
1238static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
1239{
1240 struct onenand_chip *this = mtd->priv;
1241 int ret;
1242
1243 ret = onenand_block_isbad(mtd, ofs);
1244 if (ret) {
1245 /* If it was bad already, return success and do nothing */
1246 if (ret > 0)
1247 return 0;
1248 return ret;
1249 }
1250
1251 return this->block_markbad(mtd, ofs);
1252}
1253
1254/**
1255 * onenand_unlock - [MTD Interface] Unlock block(s)
1256 * @param mtd MTD device structure
1257 * @param ofs offset relative to mtd start
1258 * @param len number of bytes to unlock
1259 *
1260 * Unlock one or more blocks
1261 */
1262static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1263{
1264 struct onenand_chip *this = mtd->priv;
1265 int start, end, block, value, status;
1266
1267 start = ofs >> this->erase_shift;
1268 end = len >> this->erase_shift;
1269
1270 /* Continuous lock scheme */
1271 if (this->options & ONENAND_CONT_LOCK) {
1272 /* Set start block address */
1273 this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1274 /* Set end block address */
1275 this->write_word(end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
1276 /* Write unlock command */
1277 this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
1278
1279 /* There's no return value */
1280 this->wait(mtd, FL_UNLOCKING);
1281
1282 /* Sanity check */
1283 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
1284 & ONENAND_CTRL_ONGO)
1285 continue;
1286
1287 /* Check lock status */
1288 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1289 if (!(status & ONENAND_WP_US))
1290 printk(KERN_ERR "wp status = 0x%x\n", status);
1291
1292 return 0;
1293 }
1294
1295 /* Block lock scheme */
1296 for (block = start; block < end; block++) {
1297 /* Set start block address */
1298 this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1299 /* Write unlock command */
1300 this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
1301
1302 /* There's no return value */
1303 this->wait(mtd, FL_UNLOCKING);
1304
1305 /* Sanity check */
1306 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
1307 & ONENAND_CTRL_ONGO)
1308 continue;
1309
1310 /* Set block address for read block status */
1311 value = onenand_block_address(this, block);
1312 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
1313
1314 /* Check lock status */
1315 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1316 if (!(status & ONENAND_WP_US))
1317 printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
1318 }
1319
1320 return 0;
1321}
1322
1323/**
1324 * onenand_print_device_info - Print device ID
1325 * @param device device ID
1326 *
1327 * Print device ID
1328 */
1329static void onenand_print_device_info(int device)
1330{
1331 int vcc, demuxed, ddp, density;
1332
1333 vcc = device & ONENAND_DEVICE_VCC_MASK;
1334 demuxed = device & ONENAND_DEVICE_IS_DEMUX;
1335 ddp = device & ONENAND_DEVICE_IS_DDP;
1336 density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
1337 printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n",
1338 demuxed ? "" : "Muxed ",
1339 ddp ? "(DDP)" : "",
1340 (16 << density),
1341 vcc ? "2.65/3.3" : "1.8",
1342 device);
1343}
1344
1345static const struct onenand_manufacturers onenand_manuf_ids[] = {
1346 {ONENAND_MFR_SAMSUNG, "Samsung"},
1347 {ONENAND_MFR_UNKNOWN, "Unknown"}
1348};
1349
1350/**
1351 * onenand_check_maf - Check manufacturer ID
1352 * @param manuf manufacturer ID
1353 *
1354 * Check manufacturer ID
1355 */
1356static int onenand_check_maf(int manuf)
1357{
1358 int i;
1359
1360 for (i = 0; onenand_manuf_ids[i].id; i++) {
1361 if (manuf == onenand_manuf_ids[i].id)
1362 break;
1363 }
1364
1365 printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n",
1366 onenand_manuf_ids[i].name, manuf);
1367
1368 return (i != ONENAND_MFR_UNKNOWN);
1369}
1370
1371/**
1372 * onenand_probe - [OneNAND Interface] Probe the OneNAND device
1373 * @param mtd MTD device structure
1374 *
1375 * OneNAND detection method:
1376 * Compare the the values from command with ones from register
1377 */
1378static int onenand_probe(struct mtd_info *mtd)
1379{
1380 struct onenand_chip *this = mtd->priv;
1381 int bram_maf_id, bram_dev_id, maf_id, dev_id;
1382 int version_id;
1383 int density;
1384
1385 /* Send the command for reading device ID from BootRAM */
1386 this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
1387
1388 /* Read manufacturer and device IDs from BootRAM */
1389 bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
1390 bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
1391
1392 /* Check manufacturer ID */
1393 if (onenand_check_maf(bram_maf_id))
1394 return -ENXIO;
1395
1396 /* Reset OneNAND to read default register values */
1397 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
1398
1399 /* Read manufacturer and device IDs from Register */
1400 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
1401 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
1402
1403 /* Check OneNAND device */
1404 if (maf_id != bram_maf_id || dev_id != bram_dev_id)
1405 return -ENXIO;
1406
1407 /* Flash device information */
1408 onenand_print_device_info(dev_id);
1409 this->device_id = dev_id;
1410
1411 density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
1412 this->chipsize = (16 << density) << 20;
1413 /* Set density mask. it is used for DDP */
1414 this->density_mask = (1 << (density + 6));
1415
1416 /* OneNAND page size & block size */
1417 /* The data buffer size is equal to page size */
1418 mtd->oobblock = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
1419 mtd->oobsize = mtd->oobblock >> 5;
1420 /* Pagers per block is always 64 in OneNAND */
1421 mtd->erasesize = mtd->oobblock << 6;
1422
1423 this->erase_shift = ffs(mtd->erasesize) - 1;
1424 this->page_shift = ffs(mtd->oobblock) - 1;
1425 this->ppb_shift = (this->erase_shift - this->page_shift);
1426 this->page_mask = (mtd->erasesize / mtd->oobblock) - 1;
1427
1428 /* REVIST: Multichip handling */
1429
1430 mtd->size = this->chipsize;
1431
1432 /* Version ID */
1433 version_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
1434 printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version_id);
1435
1436 /* Lock scheme */
1437 if (density <= ONENAND_DEVICE_DENSITY_512Mb &&
1438 !(version_id >> ONENAND_VERSION_PROCESS_SHIFT)) {
1439 printk(KERN_INFO "Lock scheme is Continues Lock\n");
1440 this->options |= ONENAND_CONT_LOCK;
1441 }
1442
1443 return 0;
1444}
1445
1446/**
1447 * onenand_suspend - [MTD Interface] Suspend the OneNAND flash
1448 * @param mtd MTD device structure
1449 */
1450static int onenand_suspend(struct mtd_info *mtd)
1451{
1452 return onenand_get_device(mtd, FL_PM_SUSPENDED);
1453}
1454
1455/**
1456 * onenand_resume - [MTD Interface] Resume the OneNAND flash
1457 * @param mtd MTD device structure
1458 */
1459static void onenand_resume(struct mtd_info *mtd)
1460{
1461 struct onenand_chip *this = mtd->priv;
1462
1463 if (this->state == FL_PM_SUSPENDED)
1464 onenand_release_device(mtd);
1465 else
1466 printk(KERN_ERR "resume() called for the chip which is not"
1467 "in suspended state\n");
1468}
1469
1470
1471/**
1472 * onenand_scan - [OneNAND Interface] Scan for the OneNAND device
1473 * @param mtd MTD device structure
1474 * @param maxchips Number of chips to scan for
1475 *
1476 * This fills out all the not initialized function pointers
1477 * with the defaults.
1478 * The flash ID is read and the mtd/chip structures are
1479 * filled with the appropriate values.
1480 */
1481int onenand_scan(struct mtd_info *mtd, int maxchips)
1482{
1483 struct onenand_chip *this = mtd->priv;
1484
1485 if (!this->read_word)
1486 this->read_word = onenand_readw;
1487 if (!this->write_word)
1488 this->write_word = onenand_writew;
1489
1490 if (!this->command)
1491 this->command = onenand_command;
1492 if (!this->wait)
1493 this->wait = onenand_wait;
1494
1495 if (!this->read_bufferram)
1496 this->read_bufferram = onenand_read_bufferram;
1497 if (!this->write_bufferram)
1498 this->write_bufferram = onenand_write_bufferram;
1499
1500 if (!this->block_markbad)
1501 this->block_markbad = onenand_default_block_markbad;
1502 if (!this->scan_bbt)
1503 this->scan_bbt = onenand_default_bbt;
1504
1505 if (onenand_probe(mtd))
1506 return -ENXIO;
1507
1508 /* Set Sync. Burst Read after probing */
1509 if (this->mmcontrol) {
1510 printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
1511 this->read_bufferram = onenand_sync_read_bufferram;
1512 }
1513
1514 this->state = FL_READY;
1515 init_waitqueue_head(&this->wq);
1516 spin_lock_init(&this->chip_lock);
1517
1518 switch (mtd->oobsize) {
1519 case 64:
1520 this->autooob = &onenand_oob_64;
1521 break;
1522
1523 case 32:
1524 this->autooob = &onenand_oob_32;
1525 break;
1526
1527 default:
1528 printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",
1529 mtd->oobsize);
1530 /* To prevent kernel oops */
1531 this->autooob = &onenand_oob_32;
1532 break;
1533 }
1534
1535 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
1536
1537 /* Fill in remaining MTD driver data */
1538 mtd->type = MTD_NANDFLASH;
1539 mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC;
1540 mtd->ecctype = MTD_ECC_SW;
1541 mtd->erase = onenand_erase;
1542 mtd->point = NULL;
1543 mtd->unpoint = NULL;
1544 mtd->read = onenand_read;
1545 mtd->write = onenand_write;
1546 mtd->read_ecc = onenand_read_ecc;
1547 mtd->write_ecc = onenand_write_ecc;
1548 mtd->read_oob = onenand_read_oob;
1549 mtd->write_oob = onenand_write_oob;
1550 mtd->readv = NULL;
1551 mtd->readv_ecc = NULL;
1552 mtd->writev = onenand_writev;
1553 mtd->writev_ecc = onenand_writev_ecc;
1554 mtd->sync = onenand_sync;
1555 mtd->lock = NULL;
1556 mtd->unlock = onenand_unlock;
1557 mtd->suspend = onenand_suspend;
1558 mtd->resume = onenand_resume;
1559 mtd->block_isbad = onenand_block_isbad;
1560 mtd->block_markbad = onenand_block_markbad;
1561 mtd->owner = THIS_MODULE;
1562
1563 /* Unlock whole block */
1564 mtd->unlock(mtd, 0x0, this->chipsize);
1565
1566 return this->scan_bbt(mtd);
1567}
1568
1569/**
1570 * onenand_release - [OneNAND Interface] Free resources held by the OneNAND device
1571 * @param mtd MTD device structure
1572 */
1573void onenand_release(struct mtd_info *mtd)
1574{
1575#ifdef CONFIG_MTD_PARTITIONS
1576 /* Deregister partitions */
1577 del_mtd_partitions (mtd);
1578#endif
1579 /* Deregister the device */
1580 del_mtd_device (mtd);
1581}
1582
1583EXPORT_SYMBOL_GPL(onenand_scan);
1584EXPORT_SYMBOL_GPL(onenand_release);
1585
1586MODULE_LICENSE("GPL");
1587MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
1588MODULE_DESCRIPTION("Generic OneNAND flash driver code");
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
new file mode 100644
index 000000000000..f40190f499e1
--- /dev/null
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -0,0 +1,246 @@
1/*
2 * linux/drivers/mtd/onenand/onenand_bbt.c
3 *
4 * Bad Block Table support for the OneNAND driver
5 *
6 * Copyright(c) 2005 Samsung Electronics
7 * Kyungmin Park <kyungmin.park@samsung.com>
8 *
9 * Derived from nand_bbt.c
10 *
11 * TODO:
12 * Split BBT core and chip specific BBT.
13 */
14
15#include <linux/slab.h>
16#include <linux/mtd/mtd.h>
17#include <linux/mtd/onenand.h>
18#include <linux/mtd/compatmac.h>
19
20/**
21 * check_short_pattern - [GENERIC] check if a pattern is in the buffer
22 * @param buf the buffer to search
23 * @param len the length of buffer to search
24 * @param paglen the pagelength
25 * @param td search pattern descriptor
26 *
27 * Check for a pattern at the given place. Used to search bad block
28 * tables and good / bad block identifiers. Same as check_pattern, but
29 * no optional empty check and the pattern is expected to start
30 * at offset 0.
31 *
32 */
33static int check_short_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
34{
35 int i;
36 uint8_t *p = buf;
37
38 /* Compare the pattern */
39 for (i = 0; i < td->len; i++) {
40 if (p[i] != td->pattern[i])
41 return -1;
42 }
43 return 0;
44}
45
46/**
47 * create_bbt - [GENERIC] Create a bad block table by scanning the device
48 * @param mtd MTD device structure
49 * @param buf temporary buffer
50 * @param bd descriptor for the good/bad block search pattern
51 * @param chip create the table for a specific chip, -1 read all chips.
52 * Applies only if NAND_BBT_PERCHIP option is set
53 *
54 * Create a bad block table by scanning the device
55 * for the given good/bad block identify pattern
56 */
57static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
58{
59 struct onenand_chip *this = mtd->priv;
60 struct bbm_info *bbm = this->bbm;
61 int i, j, numblocks, len, scanlen;
62 int startblock;
63 loff_t from;
64 size_t readlen, ooblen;
65
66 printk(KERN_INFO "Scanning device for bad blocks\n");
67
68 len = 1;
69
70 /* We need only read few bytes from the OOB area */
71 scanlen = ooblen = 0;
72 readlen = bd->len;
73
74 /* chip == -1 case only */
75 /* Note that numblocks is 2 * (real numblocks) here;
76 * see i += 2 below as it makses shifting and masking less painful
77 */
78 numblocks = mtd->size >> (bbm->bbt_erase_shift - 1);
79 startblock = 0;
80 from = 0;
81
82 for (i = startblock; i < numblocks; ) {
83 int ret;
84
85 for (j = 0; j < len; j++) {
86 size_t retlen;
87
88 /* No need to read pages fully,
89 * just read required OOB bytes */
90 ret = mtd->read_oob(mtd, from + j * mtd->oobblock + bd->offs,
91 readlen, &retlen, &buf[0]);
92
93 if (ret)
94 return ret;
95
96 if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
97 bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
98 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
99 i >> 1, (unsigned int) from);
100 break;
101 }
102 }
103 i += 2;
104 from += (1 << bbm->bbt_erase_shift);
105 }
106
107 return 0;
108}
109
110
111/**
112 * onenand_memory_bbt - [GENERIC] create a memory based bad block table
113 * @param mtd MTD device structure
114 * @param bd descriptor for the good/bad block search pattern
115 *
116 * The function creates a memory based bbt by scanning the device
117 * for manufacturer / software marked good / bad blocks
118 */
119static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
120{
121 unsigned char data_buf[MAX_ONENAND_PAGESIZE];
122
123 bd->options &= ~NAND_BBT_SCANEMPTY;
124 return create_bbt(mtd, data_buf, bd, -1);
125}
126
127/**
128 * onenand_isbad_bbt - [OneNAND Interface] Check if a block is bad
129 * @param mtd MTD device structure
130 * @param offs offset in the device
131 * @param allowbbt allow access to bad block table region
132 */
133static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
134{
135 struct onenand_chip *this = mtd->priv;
136 struct bbm_info *bbm = this->bbm;
137 int block;
138 uint8_t res;
139
140 /* Get block number * 2 */
141 block = (int) (offs >> (bbm->bbt_erase_shift - 1));
142 res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
143
144 DEBUG(MTD_DEBUG_LEVEL2, "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n",
145 (unsigned int) offs, block >> 1, res);
146
147 switch ((int) res) {
148 case 0x00: return 0;
149 case 0x01: return 1;
150 case 0x02: return allowbbt ? 0 : 1;
151 }
152
153 return 1;
154}
155
156/**
157 * onenand_scan_bbt - [OneNAND Interface] scan, find, read and maybe create bad block table(s)
158 * @param mtd MTD device structure
159 * @param bd descriptor for the good/bad block search pattern
160 *
161 * The function checks, if a bad block table(s) is/are already
162 * available. If not it scans the device for manufacturer
163 * marked good / bad blocks and writes the bad block table(s) to
164 * the selected place.
165 *
166 * The bad block table memory is allocated here. It must be freed
167 * by calling the onenand_free_bbt function.
168 *
169 */
170int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
171{
172 struct onenand_chip *this = mtd->priv;
173 struct bbm_info *bbm = this->bbm;
174 int len, ret = 0;
175
176 len = mtd->size >> (this->erase_shift + 2);
177 /* Allocate memory (2bit per block) */
178 bbm->bbt = kmalloc(len, GFP_KERNEL);
179 if (!bbm->bbt) {
180 printk(KERN_ERR "onenand_scan_bbt: Out of memory\n");
181 return -ENOMEM;
182 }
183 /* Clear the memory bad block table */
184 memset(bbm->bbt, 0x00, len);
185
186 /* Set the bad block position */
187 bbm->badblockpos = ONENAND_BADBLOCK_POS;
188
189 /* Set erase shift */
190 bbm->bbt_erase_shift = this->erase_shift;
191
192 if (!bbm->isbad_bbt)
193 bbm->isbad_bbt = onenand_isbad_bbt;
194
195 /* Scan the device to build a memory based bad block table */
196 if ((ret = onenand_memory_bbt(mtd, bd))) {
197 printk(KERN_ERR "onenand_scan_bbt: Can't scan flash and build the RAM-based BBT\n");
198 kfree(bbm->bbt);
199 bbm->bbt = NULL;
200 }
201
202 return ret;
203}
204
205/*
206 * Define some generic bad / good block scan pattern which are used
207 * while scanning a device for factory marked good / bad blocks.
208 */
209static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
210
211static struct nand_bbt_descr largepage_memorybased = {
212 .options = 0,
213 .offs = 0,
214 .len = 2,
215 .pattern = scan_ff_pattern,
216};
217
218/**
219 * onenand_default_bbt - [OneNAND Interface] Select a default bad block table for the device
220 * @param mtd MTD device structure
221 *
222 * This function selects the default bad block table
223 * support for the device and calls the onenand_scan_bbt function
224 */
225int onenand_default_bbt(struct mtd_info *mtd)
226{
227 struct onenand_chip *this = mtd->priv;
228 struct bbm_info *bbm;
229
230 this->bbm = kmalloc(sizeof(struct bbm_info), GFP_KERNEL);
231 if (!this->bbm)
232 return -ENOMEM;
233
234 bbm = this->bbm;
235
236 memset(bbm, 0, sizeof(struct bbm_info));
237
238 /* 1KB page has same configuration as 2KB page */
239 if (!bbm->badblock_pattern)
240 bbm->badblock_pattern = &largepage_memorybased;
241
242 return onenand_scan_bbt(mtd, bbm->badblock_pattern);
243}
244
245EXPORT_SYMBOL(onenand_scan_bbt);
246EXPORT_SYMBOL(onenand_default_bbt);
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c
index 13f9e992bef8..7b7ca5ab5ae4 100644
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: redboot.c,v 1.17 2004/11/22 11:33:56 ijc Exp $ 2 * $Id: redboot.c,v 1.18 2005/11/07 11:14:21 gleixner Exp $
3 * 3 *
4 * Parse RedBoot-style Flash Image System (FIS) tables and 4 * Parse RedBoot-style Flash Image System (FIS) tables and
5 * produce a Linux partition array to match. 5 * produce a Linux partition array to match.
@@ -39,7 +39,7 @@ static inline int redboot_checksum(struct fis_image_desc *img)
39 return 1; 39 return 1;
40} 40}
41 41
42static int parse_redboot_partitions(struct mtd_info *master, 42static int parse_redboot_partitions(struct mtd_info *master,
43 struct mtd_partition **pparts, 43 struct mtd_partition **pparts,
44 unsigned long fis_origin) 44 unsigned long fis_origin)
45{ 45{
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
new file mode 100644
index 000000000000..041ee59ea77d
--- /dev/null
+++ b/drivers/mtd/rfd_ftl.c
@@ -0,0 +1,855 @@
1/*
2 * rfd_ftl.c -- resident flash disk (flash translation layer)
3 *
4 * Copyright (C) 2005 Sean Young <sean@mess.org>
5 *
6 * $Id: rfd_ftl.c,v 1.5 2005/11/07 11:14:21 gleixner Exp $
7 *
8 * This type of flash translation layer (FTL) is used by the Embedded BIOS
9 * by General Software. It is known as the Resident Flash Disk (RFD), see:
10 *
11 * http://www.gensw.com/pages/prod/bios/rfd.htm
12 *
13 * based on ftl.c
14 */
15
16#include <linux/hdreg.h>
17#include <linux/init.h>
18#include <linux/mtd/blktrans.h>
19#include <linux/mtd/mtd.h>
20#include <linux/vmalloc.h>
21
22#include <asm/types.h>
23
24#define const_cpu_to_le16 __constant_cpu_to_le16
25
26static int block_size = 0;
27module_param(block_size, int, 0);
28MODULE_PARM_DESC(block_size, "Block size to use by RFD, defaults to erase unit size");
29
30#define PREFIX "rfd_ftl: "
31
32/* Major device # for FTL device */
33
34/* A request for this major has been sent to device@lanana.org */
35#ifndef RFD_FTL_MAJOR
36#define RFD_FTL_MAJOR 95
37#endif
38
39/* Maximum number of partitions in an FTL region */
40#define PART_BITS 4
41
42/* An erase unit should start with this value */
43#define RFD_MAGIC 0x9193
44
45/* the second value is 0xffff or 0xffc8; function unknown */
46
47/* the third value is always 0xffff, ignored */
48
49/* next is an array of mapping for each corresponding sector */
50#define HEADER_MAP_OFFSET 3
51#define SECTOR_DELETED 0x0000
52#define SECTOR_ZERO 0xfffe
53#define SECTOR_FREE 0xffff
54
55#define SECTOR_SIZE 512
56
57#define SECTORS_PER_TRACK 63
58
59struct block {
60 enum {
61 BLOCK_OK,
62 BLOCK_ERASING,
63 BLOCK_ERASED,
64 BLOCK_FAILED
65 } state;
66 int free_sectors;
67 int used_sectors;
68 int erases;
69 u_long offset;
70};
71
72struct partition {
73 struct mtd_blktrans_dev mbd;
74
75 u_int block_size; /* size of erase unit */
76 u_int total_blocks; /* number of erase units */
77 u_int header_sectors_per_block; /* header sectors in erase unit */
78 u_int data_sectors_per_block; /* data sectors in erase unit */
79 u_int sector_count; /* sectors in translated disk */
80 u_int header_size; /* bytes in header sector */
81 int reserved_block; /* block next up for reclaim */
82 int current_block; /* block to write to */
83 u16 *header_cache; /* cached header */
84
85 int is_reclaiming;
86 int cylinders;
87 int errors;
88 u_long *sector_map;
89 struct block *blocks;
90};
91
92static int rfd_ftl_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf);
93
94static int build_block_map(struct partition *part, int block_no)
95{
96 struct block *block = &part->blocks[block_no];
97 int i;
98
99 block->offset = part->block_size * block_no;
100
101 if (le16_to_cpu(part->header_cache[0]) != RFD_MAGIC) {
102 block->state = BLOCK_ERASED; /* assumption */
103 block->free_sectors = part->data_sectors_per_block;
104 part->reserved_block = block_no;
105 return 1;
106 }
107
108 block->state = BLOCK_OK;
109
110 for (i=0; i<part->data_sectors_per_block; i++) {
111 u16 entry;
112
113 entry = le16_to_cpu(part->header_cache[HEADER_MAP_OFFSET + i]);
114
115 if (entry == SECTOR_DELETED)
116 continue;
117
118 if (entry == SECTOR_FREE) {
119 block->free_sectors++;
120 continue;
121 }
122
123 if (entry == SECTOR_ZERO)
124 entry = 0;
125
126 if (entry >= part->sector_count) {
127 printk(KERN_NOTICE PREFIX
128 "'%s': unit #%d: entry %d corrupt, "
129 "sector %d out of range\n",
130 part->mbd.mtd->name, block_no, i, entry);
131 continue;
132 }
133
134 if (part->sector_map[entry] != -1) {
135 printk(KERN_NOTICE PREFIX
136 "'%s': more than one entry for sector %d\n",
137 part->mbd.mtd->name, entry);
138 part->errors = 1;
139 continue;
140 }
141
142 part->sector_map[entry] = block->offset +
143 (i + part->header_sectors_per_block) * SECTOR_SIZE;
144
145 block->used_sectors++;
146 }
147
148 if (block->free_sectors == part->data_sectors_per_block)
149 part->reserved_block = block_no;
150
151 return 0;
152}
153
154static int scan_header(struct partition *part)
155{
156 int sectors_per_block;
157 int i, rc = -ENOMEM;
158 int blocks_found;
159 size_t retlen;
160
161 sectors_per_block = part->block_size / SECTOR_SIZE;
162 part->total_blocks = part->mbd.mtd->size / part->block_size;
163
164 if (part->total_blocks < 2)
165 return -ENOENT;
166
167 /* each erase block has three bytes header, followed by the map */
168 part->header_sectors_per_block =
169 ((HEADER_MAP_OFFSET + sectors_per_block) *
170 sizeof(u16) + SECTOR_SIZE - 1) / SECTOR_SIZE;
171
172 part->data_sectors_per_block = sectors_per_block -
173 part->header_sectors_per_block;
174
175 part->header_size = (HEADER_MAP_OFFSET +
176 part->data_sectors_per_block) * sizeof(u16);
177
178 part->cylinders = (part->data_sectors_per_block *
179 (part->total_blocks - 1) - 1) / SECTORS_PER_TRACK;
180
181 part->sector_count = part->cylinders * SECTORS_PER_TRACK;
182
183 part->current_block = -1;
184 part->reserved_block = -1;
185 part->is_reclaiming = 0;
186
187 part->header_cache = kmalloc(part->header_size, GFP_KERNEL);
188 if (!part->header_cache)
189 goto err;
190
191 part->blocks = kcalloc(part->total_blocks, sizeof(struct block),
192 GFP_KERNEL);
193 if (!part->blocks)
194 goto err;
195
196 part->sector_map = vmalloc(part->sector_count * sizeof(u_long));
197 if (!part->sector_map) {
198 printk(KERN_ERR PREFIX "'%s': unable to allocate memory for "
199 "sector map", part->mbd.mtd->name);
200 goto err;
201 }
202
203 for (i=0; i<part->sector_count; i++)
204 part->sector_map[i] = -1;
205
206 for (i=0, blocks_found=0; i<part->total_blocks; i++) {
207 rc = part->mbd.mtd->read(part->mbd.mtd,
208 i * part->block_size, part->header_size,
209 &retlen, (u_char*)part->header_cache);
210
211 if (!rc && retlen != part->header_size)
212 rc = -EIO;
213
214 if (rc)
215 goto err;
216
217 if (!build_block_map(part, i))
218 blocks_found++;
219 }
220
221 if (blocks_found == 0) {
222 printk(KERN_NOTICE PREFIX "no RFD magic found in '%s'\n",
223 part->mbd.mtd->name);
224 rc = -ENOENT;
225 goto err;
226 }
227
228 if (part->reserved_block == -1) {
229 printk(KERN_NOTICE PREFIX "'%s': no empty erase unit found\n",
230 part->mbd.mtd->name);
231
232 part->errors = 1;
233 }
234
235 return 0;
236
237err:
238 vfree(part->sector_map);
239 kfree(part->header_cache);
240 kfree(part->blocks);
241
242 return rc;
243}
244
245static int rfd_ftl_readsect(struct mtd_blktrans_dev *dev, u_long sector, char *buf)
246{
247 struct partition *part = (struct partition*)dev;
248 u_long addr;
249 size_t retlen;
250 int rc;
251
252 if (sector >= part->sector_count)
253 return -EIO;
254
255 addr = part->sector_map[sector];
256 if (addr != -1) {
257 rc = part->mbd.mtd->read(part->mbd.mtd, addr, SECTOR_SIZE,
258 &retlen, (u_char*)buf);
259 if (!rc && retlen != SECTOR_SIZE)
260 rc = -EIO;
261
262 if (rc) {
263 printk(KERN_WARNING PREFIX "error reading '%s' at "
264 "0x%lx\n", part->mbd.mtd->name, addr);
265 return rc;
266 }
267 } else
268 memset(buf, 0, SECTOR_SIZE);
269
270 return 0;
271}
272
273static void erase_callback(struct erase_info *erase)
274{
275 struct partition *part;
276 u16 magic;
277 int i, rc;
278 size_t retlen;
279
280 part = (struct partition*)erase->priv;
281
282 i = erase->addr / part->block_size;
283 if (i >= part->total_blocks || part->blocks[i].offset != erase->addr) {
284 printk(KERN_ERR PREFIX "erase callback for unknown offset %x "
285 "on '%s'\n", erase->addr, part->mbd.mtd->name);
286 return;
287 }
288
289 if (erase->state != MTD_ERASE_DONE) {
290 printk(KERN_WARNING PREFIX "erase failed at 0x%x on '%s', "
291 "state %d\n", erase->addr,
292 part->mbd.mtd->name, erase->state);
293
294 part->blocks[i].state = BLOCK_FAILED;
295 part->blocks[i].free_sectors = 0;
296 part->blocks[i].used_sectors = 0;
297
298 kfree(erase);
299
300 return;
301 }
302
303 magic = const_cpu_to_le16(RFD_MAGIC);
304
305 part->blocks[i].state = BLOCK_ERASED;
306 part->blocks[i].free_sectors = part->data_sectors_per_block;
307 part->blocks[i].used_sectors = 0;
308 part->blocks[i].erases++;
309
310 rc = part->mbd.mtd->write(part->mbd.mtd,
311 part->blocks[i].offset, sizeof(magic), &retlen,
312 (u_char*)&magic);
313
314 if (!rc && retlen != sizeof(magic))
315 rc = -EIO;
316
317 if (rc) {
318 printk(KERN_NOTICE PREFIX "'%s': unable to write RFD "
319 "header at 0x%lx\n",
320 part->mbd.mtd->name,
321 part->blocks[i].offset);
322 part->blocks[i].state = BLOCK_FAILED;
323 }
324 else
325 part->blocks[i].state = BLOCK_OK;
326
327 kfree(erase);
328}
329
330static int erase_block(struct partition *part, int block)
331{
332 struct erase_info *erase;
333 int rc = -ENOMEM;
334
335 erase = kmalloc(sizeof(struct erase_info), GFP_KERNEL);
336 if (!erase)
337 goto err;
338
339 erase->mtd = part->mbd.mtd;
340 erase->callback = erase_callback;
341 erase->addr = part->blocks[block].offset;
342 erase->len = part->block_size;
343 erase->priv = (u_long)part;
344
345 part->blocks[block].state = BLOCK_ERASING;
346 part->blocks[block].free_sectors = 0;
347
348 rc = part->mbd.mtd->erase(part->mbd.mtd, erase);
349
350 if (rc) {
351 printk(KERN_WARNING PREFIX "erase of region %x,%x on '%s' "
352 "failed\n", erase->addr, erase->len,
353 part->mbd.mtd->name);
354 kfree(erase);
355 }
356
357err:
358 return rc;
359}
360
361static int move_block_contents(struct partition *part, int block_no, u_long *old_sector)
362{
363 void *sector_data;
364 u16 *map;
365 size_t retlen;
366 int i, rc = -ENOMEM;
367
368 part->is_reclaiming = 1;
369
370 sector_data = kmalloc(SECTOR_SIZE, GFP_KERNEL);
371 if (!sector_data)
372 goto err3;
373
374 map = kmalloc(part->header_size, GFP_KERNEL);
375 if (!map)
376 goto err2;
377
378 rc = part->mbd.mtd->read(part->mbd.mtd,
379 part->blocks[block_no].offset, part->header_size,
380 &retlen, (u_char*)map);
381
382 if (!rc && retlen != part->header_size)
383 rc = -EIO;
384
385 if (rc) {
386 printk(KERN_NOTICE PREFIX "error reading '%s' at "
387 "0x%lx\n", part->mbd.mtd->name,
388 part->blocks[block_no].offset);
389
390 goto err;
391 }
392
393 for (i=0; i<part->data_sectors_per_block; i++) {
394 u16 entry = le16_to_cpu(map[HEADER_MAP_OFFSET + i]);
395 u_long addr;
396
397
398 if (entry == SECTOR_FREE || entry == SECTOR_DELETED)
399 continue;
400
401 if (entry == SECTOR_ZERO)
402 entry = 0;
403
404 /* already warned about and ignored in build_block_map() */
405 if (entry >= part->sector_count)
406 continue;
407
408 addr = part->blocks[block_no].offset +
409 (i + part->header_sectors_per_block) * SECTOR_SIZE;
410
411 if (*old_sector == addr) {
412 *old_sector = -1;
413 if (!part->blocks[block_no].used_sectors--) {
414 rc = erase_block(part, block_no);
415 break;
416 }
417 continue;
418 }
419 rc = part->mbd.mtd->read(part->mbd.mtd, addr,
420 SECTOR_SIZE, &retlen, sector_data);
421
422 if (!rc && retlen != SECTOR_SIZE)
423 rc = -EIO;
424
425 if (rc) {
426 printk(KERN_NOTICE PREFIX "'%s': Unable to "
427 "read sector for relocation\n",
428 part->mbd.mtd->name);
429
430 goto err;
431 }
432
433 rc = rfd_ftl_writesect((struct mtd_blktrans_dev*)part,
434 entry, sector_data);
435
436 if (rc)
437 goto err;
438 }
439
440err:
441 kfree(map);
442err2:
443 kfree(sector_data);
444err3:
445 part->is_reclaiming = 0;
446
447 return rc;
448}
449
450static int reclaim_block(struct partition *part, u_long *old_sector)
451{
452 int block, best_block, score, old_sector_block;
453 int rc;
454
455 /* we have a race if sync doesn't exist */
456 if (part->mbd.mtd->sync)
457 part->mbd.mtd->sync(part->mbd.mtd);
458
459 score = 0x7fffffff; /* MAX_INT */
460 best_block = -1;
461 if (*old_sector != -1)
462 old_sector_block = *old_sector / part->block_size;
463 else
464 old_sector_block = -1;
465
466 for (block=0; block<part->total_blocks; block++) {
467 int this_score;
468
469 if (block == part->reserved_block)
470 continue;
471
472 /*
473 * Postpone reclaiming if there is a free sector as
474 * more removed sectors is more efficient (have to move
475 * less).
476 */
477 if (part->blocks[block].free_sectors)
478 return 0;
479
480 this_score = part->blocks[block].used_sectors;
481
482 if (block == old_sector_block)
483 this_score--;
484 else {
485 /* no point in moving a full block */
486 if (part->blocks[block].used_sectors ==
487 part->data_sectors_per_block)
488 continue;
489 }
490
491 this_score += part->blocks[block].erases;
492
493 if (this_score < score) {
494 best_block = block;
495 score = this_score;
496 }
497 }
498
499 if (best_block == -1)
500 return -ENOSPC;
501
502 part->current_block = -1;
503 part->reserved_block = best_block;
504
505 pr_debug("reclaim_block: reclaiming block #%d with %d used "
506 "%d free sectors\n", best_block,
507 part->blocks[best_block].used_sectors,
508 part->blocks[best_block].free_sectors);
509
510 if (part->blocks[best_block].used_sectors)
511 rc = move_block_contents(part, best_block, old_sector);
512 else
513 rc = erase_block(part, best_block);
514
515 return rc;
516}
517
518/*
519 * IMPROVE: It would be best to choose the block with the most deleted sectors,
520 * because if we fill that one up first it'll have the most chance of having
521 * the least live sectors at reclaim.
522 */
523static int find_free_block(const struct partition *part)
524{
525 int block, stop;
526
527 block = part->current_block == -1 ?
528 jiffies % part->total_blocks : part->current_block;
529 stop = block;
530
531 do {
532 if (part->blocks[block].free_sectors &&
533 block != part->reserved_block)
534 return block;
535
536 if (++block >= part->total_blocks)
537 block = 0;
538
539 } while (block != stop);
540
541 return -1;
542}
543
544static int find_writeable_block(struct partition *part, u_long *old_sector)
545{
546 int rc, block;
547 size_t retlen;
548
549 block = find_free_block(part);
550
551 if (block == -1) {
552 if (!part->is_reclaiming) {
553 rc = reclaim_block(part, old_sector);
554 if (rc)
555 goto err;
556
557 block = find_free_block(part);
558 }
559
560 if (block == -1) {
561 rc = -ENOSPC;
562 goto err;
563 }
564 }
565
566 rc = part->mbd.mtd->read(part->mbd.mtd, part->blocks[block].offset,
567 part->header_size, &retlen, (u_char*)part->header_cache);
568
569 if (!rc && retlen != part->header_size)
570 rc = -EIO;
571
572 if (rc) {
573 printk(KERN_NOTICE PREFIX "'%s': unable to read header at "
574 "0x%lx\n", part->mbd.mtd->name,
575 part->blocks[block].offset);
576 goto err;
577 }
578
579 part->current_block = block;
580
581err:
582 return rc;
583}
584
585static int mark_sector_deleted(struct partition *part, u_long old_addr)
586{
587 int block, offset, rc;
588 u_long addr;
589 size_t retlen;
590 u16 del = const_cpu_to_le16(SECTOR_DELETED);
591
592 block = old_addr / part->block_size;
593 offset = (old_addr % part->block_size) / SECTOR_SIZE -
594 part->header_sectors_per_block;
595
596 addr = part->blocks[block].offset +
597 (HEADER_MAP_OFFSET + offset) * sizeof(u16);
598 rc = part->mbd.mtd->write(part->mbd.mtd, addr,
599 sizeof(del), &retlen, (u_char*)&del);
600
601 if (!rc && retlen != sizeof(del))
602 rc = -EIO;
603
604 if (rc) {
605 printk(KERN_WARNING PREFIX "error writing '%s' at "
606 "0x%lx\n", part->mbd.mtd->name, addr);
607 if (rc)
608 goto err;
609 }
610 if (block == part->current_block)
611 part->header_cache[offset + HEADER_MAP_OFFSET] = del;
612
613 part->blocks[block].used_sectors--;
614
615 if (!part->blocks[block].used_sectors &&
616 !part->blocks[block].free_sectors)
617 rc = erase_block(part, block);
618
619err:
620 return rc;
621}
622
623static int find_free_sector(const struct partition *part, const struct block *block)
624{
625 int i, stop;
626
627 i = stop = part->data_sectors_per_block - block->free_sectors;
628
629 do {
630 if (le16_to_cpu(part->header_cache[HEADER_MAP_OFFSET + i])
631 == SECTOR_FREE)
632 return i;
633
634 if (++i == part->data_sectors_per_block)
635 i = 0;
636 }
637 while(i != stop);
638
639 return -1;
640}
641
642static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf, ulong *old_addr)
643{
644 struct partition *part = (struct partition*)dev;
645 struct block *block;
646 u_long addr;
647 int i;
648 int rc;
649 size_t retlen;
650 u16 entry;
651
652 if (part->current_block == -1 ||
653 !part->blocks[part->current_block].free_sectors) {
654
655 rc = find_writeable_block(part, old_addr);
656 if (rc)
657 goto err;
658 }
659
660 block = &part->blocks[part->current_block];
661
662 i = find_free_sector(part, block);
663
664 if (i < 0) {
665 rc = -ENOSPC;
666 goto err;
667 }
668
669 addr = (i + part->header_sectors_per_block) * SECTOR_SIZE +
670 block->offset;
671 rc = part->mbd.mtd->write(part->mbd.mtd,
672 addr, SECTOR_SIZE, &retlen, (u_char*)buf);
673
674 if (!rc && retlen != SECTOR_SIZE)
675 rc = -EIO;
676
677 if (rc) {
678 printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n",
679 part->mbd.mtd->name, addr);
680 if (rc)
681 goto err;
682 }
683
684 part->sector_map[sector] = addr;
685
686 entry = cpu_to_le16(sector == 0 ? SECTOR_ZERO : sector);
687
688 part->header_cache[i + HEADER_MAP_OFFSET] = entry;
689
690 addr = block->offset + (HEADER_MAP_OFFSET + i) * sizeof(u16);
691 rc = part->mbd.mtd->write(part->mbd.mtd, addr,
692 sizeof(entry), &retlen, (u_char*)&entry);
693
694 if (!rc && retlen != sizeof(entry))
695 rc = -EIO;
696
697 if (rc) {
698 printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n",
699 part->mbd.mtd->name, addr);
700 if (rc)
701 goto err;
702 }
703 block->used_sectors++;
704 block->free_sectors--;
705
706err:
707 return rc;
708}
709
710static int rfd_ftl_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf)
711{
712 struct partition *part = (struct partition*)dev;
713 u_long old_addr;
714 int i;
715 int rc = 0;
716
717 pr_debug("rfd_ftl_writesect(sector=0x%lx)\n", sector);
718
719 if (part->reserved_block == -1) {
720 rc = -EACCES;
721 goto err;
722 }
723
724 if (sector >= part->sector_count) {
725 rc = -EIO;
726 goto err;
727 }
728
729 old_addr = part->sector_map[sector];
730
731 for (i=0; i<SECTOR_SIZE; i++) {
732 if (!buf[i])
733 continue;
734
735 rc = do_writesect(dev, sector, buf, &old_addr);
736 if (rc)
737 goto err;
738 break;
739 }
740
741 if (i == SECTOR_SIZE)
742 part->sector_map[sector] = -1;
743
744 if (old_addr != -1)
745 rc = mark_sector_deleted(part, old_addr);
746
747err:
748 return rc;
749}
750
751static int rfd_ftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
752{
753 struct partition *part = (struct partition*)dev;
754
755 geo->heads = 1;
756 geo->sectors = SECTORS_PER_TRACK;
757 geo->cylinders = part->cylinders;
758
759 return 0;
760}
761
762static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
763{
764 struct partition *part;
765
766 if (mtd->type != MTD_NORFLASH)
767 return;
768
769 part = kcalloc(1, sizeof(struct partition), GFP_KERNEL);
770 if (!part)
771 return;
772
773 part->mbd.mtd = mtd;
774
775 if (block_size)
776 part->block_size = block_size;
777 else {
778 if (!mtd->erasesize) {
779 printk(KERN_NOTICE PREFIX "please provide block_size");
780 return;
781 }
782 else
783 part->block_size = mtd->erasesize;
784 }
785
786 if (scan_header(part) == 0) {
787 part->mbd.size = part->sector_count;
788 part->mbd.blksize = SECTOR_SIZE;
789 part->mbd.tr = tr;
790 part->mbd.devnum = -1;
791 if (!(mtd->flags & MTD_WRITEABLE))
792 part->mbd.readonly = 1;
793 else if (part->errors) {
794 printk(KERN_NOTICE PREFIX "'%s': errors found, "
795 "setting read-only", mtd->name);
796 part->mbd.readonly = 1;
797 }
798
799 printk(KERN_INFO PREFIX "name: '%s' type: %d flags %x\n",
800 mtd->name, mtd->type, mtd->flags);
801
802 if (!add_mtd_blktrans_dev((void*)part))
803 return;
804 }
805
806 kfree(part);
807}
808
809static void rfd_ftl_remove_dev(struct mtd_blktrans_dev *dev)
810{
811 struct partition *part = (struct partition*)dev;
812 int i;
813
814 for (i=0; i<part->total_blocks; i++) {
815 pr_debug("rfd_ftl_remove_dev:'%s': erase unit #%02d: %d erases\n",
816 part->mbd.mtd->name, i, part->blocks[i].erases);
817 }
818
819 del_mtd_blktrans_dev(dev);
820 vfree(part->sector_map);
821 kfree(part->header_cache);
822 kfree(part->blocks);
823 kfree(part);
824}
825
826struct mtd_blktrans_ops rfd_ftl_tr = {
827 .name = "rfd",
828 .major = RFD_FTL_MAJOR,
829 .part_bits = PART_BITS,
830 .readsect = rfd_ftl_readsect,
831 .writesect = rfd_ftl_writesect,
832 .getgeo = rfd_ftl_getgeo,
833 .add_mtd = rfd_ftl_add_mtd,
834 .remove_dev = rfd_ftl_remove_dev,
835 .owner = THIS_MODULE,
836};
837
838static int __init init_rfd_ftl(void)
839{
840 return register_mtd_blktrans(&rfd_ftl_tr);
841}
842
843static void __exit cleanup_rfd_ftl(void)
844{
845 deregister_mtd_blktrans(&rfd_ftl_tr);
846}
847
848module_init(init_rfd_ftl);
849module_exit(cleanup_rfd_ftl);
850
851MODULE_LICENSE("GPL");
852MODULE_AUTHOR("Sean Young <sean@mess.org>");
853MODULE_DESCRIPTION("Support code for RFD Flash Translation Layer, "
854 "used by General Software's Embedded BIOS");
855