aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/mtd/nand_ecc.txt714
-rw-r--r--arch/arm/plat-omap/include/mach/onenand.h6
-rw-r--r--drivers/mtd/Kconfig5
-rw-r--r--drivers/mtd/chips/Kconfig3
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c54
-rw-r--r--drivers/mtd/chips/cfi_probe.c58
-rw-r--r--drivers/mtd/chips/cfi_util.c66
-rw-r--r--drivers/mtd/chips/gen_probe.c2
-rw-r--r--drivers/mtd/devices/Kconfig21
-rw-r--r--drivers/mtd/devices/m25p80.c136
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c214
-rw-r--r--drivers/mtd/maps/Kconfig31
-rw-r--r--drivers/mtd/maps/Makefile4
-rw-r--r--drivers/mtd/maps/ebony.c163
-rw-r--r--drivers/mtd/maps/ocotea.c154
-rw-r--r--drivers/mtd/maps/omap-toto-flash.c133
-rw-r--r--drivers/mtd/maps/walnut.c122
-rw-r--r--drivers/mtd/mtdchar.c4
-rw-r--r--drivers/mtd/mtdconcat.c4
-rw-r--r--drivers/mtd/mtdpart.c4
-rw-r--r--drivers/mtd/nand/Kconfig6
-rw-r--r--drivers/mtd/nand/Makefile1
-rw-r--r--drivers/mtd/nand/nand_base.c8
-rw-r--r--drivers/mtd/nand/nand_ecc.c554
-rw-r--r--drivers/mtd/nand/nandsim.c1
-rw-r--r--drivers/mtd/nand/toto.c206
-rw-r--r--drivers/mtd/onenand/Kconfig8
-rw-r--r--drivers/mtd/onenand/Makefile1
-rw-r--r--drivers/mtd/onenand/omap2.c782
-rw-r--r--drivers/mtd/onenand/onenand_base.c2
-rw-r--r--drivers/mtd/ssfdc.c3
-rw-r--r--fs/Kconfig190
-rw-r--r--fs/jffs2/Kconfig188
-rw-r--r--fs/jffs2/dir.c2
-rw-r--r--fs/jffs2/erase.c4
-rw-r--r--fs/jffs2/fs.c2
-rw-r--r--include/linux/mtd/cfi.h9
-rw-r--r--include/linux/mtd/flashchip.h4
-rw-r--r--include/linux/mtd/mtd.h4
-rw-r--r--include/linux/mtd/nand.h1
-rw-r--r--include/linux/mtd/onenand_regs.h2
41 files changed, 2594 insertions, 1282 deletions
diff --git a/Documentation/mtd/nand_ecc.txt b/Documentation/mtd/nand_ecc.txt
new file mode 100644
index 000000000000..bdf93b7f0f24
--- /dev/null
+++ b/Documentation/mtd/nand_ecc.txt
@@ -0,0 +1,714 @@
1Introduction
2============
3
4Having looked at the linux mtd/nand driver and more specific at nand_ecc.c
5I felt there was room for optimisation. I bashed the code for a few hours
6performing tricks like table lookup removing superfluous code etc.
7After that the speed was increased by 35-40%.
8Still I was not too happy as I felt there was additional room for improvement.
9
10Bad! I was hooked.
11I decided to annotate my steps in this file. Perhaps it is useful to someone
12or someone learns something from it.
13
14
15The problem
16===========
17
18NAND flash (at least SLC one) typically has sectors of 256 bytes.
19However NAND flash is not extremely reliable so some error detection
20(and sometimes correction) is needed.
21
22This is done by means of a Hamming code. I'll try to explain it in
23laymans terms (and apologies to all the pro's in the field in case I do
24not use the right terminology, my coding theory class was almost 30
25years ago, and I must admit it was not one of my favourites).
26
27As I said before the ecc calculation is performed on sectors of 256
28bytes. This is done by calculating several parity bits over the rows and
29columns. The parity used is even parity which means that the parity bit = 1
30if the data over which the parity is calculated is 1 and the parity bit = 0
31if the data over which the parity is calculated is 0. So the total
32number of bits over the data over which the parity is calculated + the
33parity bit is even. (see wikipedia if you can't follow this).
34Parity is often calculated by means of an exclusive or operation,
35sometimes also referred to as xor. In C the operator for xor is ^
36
37Back to ecc.
38Let's give a small figure:
39
40byte 0: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp0 rp2 rp4 ... rp14
41byte 1: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp1 rp2 rp4 ... rp14
42byte 2: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp0 rp3 rp4 ... rp14
43byte 3: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp1 rp3 rp4 ... rp14
44byte 4: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp0 rp2 rp5 ... rp14
45....
46byte 254: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp0 rp3 rp5 ... rp15
47byte 255: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp1 rp3 rp5 ... rp15
48 cp1 cp0 cp1 cp0 cp1 cp0 cp1 cp0
49 cp3 cp3 cp2 cp2 cp3 cp3 cp2 cp2
50 cp5 cp5 cp5 cp5 cp4 cp4 cp4 cp4
51
52This figure represents a sector of 256 bytes.
53cp is my abbreviaton for column parity, rp for row parity.
54
55Let's start to explain column parity.
56cp0 is the parity that belongs to all bit0, bit2, bit4, bit6.
57so the sum of all bit0, bit2, bit4 and bit6 values + cp0 itself is even.
58Similarly cp1 is the sum of all bit1, bit3, bit5 and bit7.
59cp2 is the parity over bit0, bit1, bit4 and bit5
60cp3 is the parity over bit2, bit3, bit6 and bit7.
61cp4 is the parity over bit0, bit1, bit2 and bit3.
62cp5 is the parity over bit4, bit5, bit6 and bit7.
63Note that each of cp0 .. cp5 is exactly one bit.
64
65Row parity actually works almost the same.
66rp0 is the parity of all even bytes (0, 2, 4, 6, ... 252, 254)
67rp1 is the parity of all odd bytes (1, 3, 5, 7, ..., 253, 255)
68rp2 is the parity of all bytes 0, 1, 4, 5, 8, 9, ...
69(so handle two bytes, then skip 2 bytes).
70rp3 is covers the half rp2 does not cover (bytes 2, 3, 6, 7, 10, 11, ...)
71for rp4 the rule is cover 4 bytes, skip 4 bytes, cover 4 bytes, skip 4 etc.
72so rp4 calculates parity over bytes 0, 1, 2, 3, 8, 9, 10, 11, 16, ...)
73and rp5 covers the other half, so bytes 4, 5, 6, 7, 12, 13, 14, 15, 20, ..
74The story now becomes quite boring. I guess you get the idea.
75rp6 covers 8 bytes then skips 8 etc
76rp7 skips 8 bytes then covers 8 etc
77rp8 covers 16 bytes then skips 16 etc
78rp9 skips 16 bytes then covers 16 etc
79rp10 covers 32 bytes then skips 32 etc
80rp11 skips 32 bytes then covers 32 etc
81rp12 covers 64 bytes then skips 64 etc
82rp13 skips 64 bytes then covers 64 etc
83rp14 covers 128 bytes then skips 128
84rp15 skips 128 bytes then covers 128
85
86In the end the parity bits are grouped together in three bytes as
87follows:
88ECC Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
89ECC 0 rp07 rp06 rp05 rp04 rp03 rp02 rp01 rp00
90ECC 1 rp15 rp14 rp13 rp12 rp11 rp10 rp09 rp08
91ECC 2 cp5 cp4 cp3 cp2 cp1 cp0 1 1
92
93I detected after writing this that ST application note AN1823
94(http://www.st.com/stonline/books/pdf/docs/10123.pdf) gives a much
95nicer picture.(but they use line parity as term where I use row parity)
96Oh well, I'm graphically challenged, so suffer with me for a moment :-)
97And I could not reuse the ST picture anyway for copyright reasons.
98
99
100Attempt 0
101=========
102
103Implementing the parity calculation is pretty simple.
104In C pseudocode:
105for (i = 0; i < 256; i++)
106{
107 if (i & 0x01)
108 rp1 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp1;
109 else
110 rp0 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp1;
111 if (i & 0x02)
112 rp3 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp3;
113 else
114 rp2 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp2;
115 if (i & 0x04)
116 rp5 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp5;
117 else
118 rp4 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp4;
119 if (i & 0x08)
120 rp7 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp7;
121 else
122 rp6 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp6;
123 if (i & 0x10)
124 rp9 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp9;
125 else
126 rp8 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp8;
127 if (i & 0x20)
128 rp11 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp11;
129 else
130 rp10 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp10;
131 if (i & 0x40)
132 rp13 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp13;
133 else
134 rp12 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp12;
135 if (i & 0x80)
136 rp15 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp15;
137 else
138 rp14 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp14;
139 cp0 = bit6 ^ bit4 ^ bit2 ^ bit0 ^ cp0;
140 cp1 = bit7 ^ bit5 ^ bit3 ^ bit1 ^ cp1;
141 cp2 = bit5 ^ bit4 ^ bit1 ^ bit0 ^ cp2;
142 cp3 = bit7 ^ bit6 ^ bit3 ^ bit2 ^ cp3
143 cp4 = bit3 ^ bit2 ^ bit1 ^ bit0 ^ cp4
144 cp5 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ cp5
145}
146
147
148Analysis 0
149==========
150
151C does have bitwise operators but not really operators to do the above
152efficiently (and most hardware has no such instructions either).
153Therefore without implementing this it was clear that the code above was
154not going to bring me a Nobel prize :-)
155
156Fortunately the exclusive or operation is commutative, so we can combine
157the values in any order. So instead of calculating all the bits
158individually, let us try to rearrange things.
159For the column parity this is easy. We can just xor the bytes and in the
160end filter out the relevant bits. This is pretty nice as it will bring
161all cp calculation out of the if loop.
162
163Similarly we can first xor the bytes for the various rows.
164This leads to:
165
166
167Attempt 1
168=========
169
170const char parity[256] = {
171 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
172 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
173 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
174 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
175 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
176 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
177 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
178 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
179 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
180 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
181 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
182 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
183 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
184 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
185 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
186 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
187};
188
189void ecc1(const unsigned char *buf, unsigned char *code)
190{
191 int i;
192 const unsigned char *bp = buf;
193 unsigned char cur;
194 unsigned char rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7;
195 unsigned char rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15;
196 unsigned char par;
197
198 par = 0;
199 rp0 = 0; rp1 = 0; rp2 = 0; rp3 = 0;
200 rp4 = 0; rp5 = 0; rp6 = 0; rp7 = 0;
201 rp8 = 0; rp9 = 0; rp10 = 0; rp11 = 0;
202 rp12 = 0; rp13 = 0; rp14 = 0; rp15 = 0;
203
204 for (i = 0; i < 256; i++)
205 {
206 cur = *bp++;
207 par ^= cur;
208 if (i & 0x01) rp1 ^= cur; else rp0 ^= cur;
209 if (i & 0x02) rp3 ^= cur; else rp2 ^= cur;
210 if (i & 0x04) rp5 ^= cur; else rp4 ^= cur;
211 if (i & 0x08) rp7 ^= cur; else rp6 ^= cur;
212 if (i & 0x10) rp9 ^= cur; else rp8 ^= cur;
213 if (i & 0x20) rp11 ^= cur; else rp10 ^= cur;
214 if (i & 0x40) rp13 ^= cur; else rp12 ^= cur;
215 if (i & 0x80) rp15 ^= cur; else rp14 ^= cur;
216 }
217 code[0] =
218 (parity[rp7] << 7) |
219 (parity[rp6] << 6) |
220 (parity[rp5] << 5) |
221 (parity[rp4] << 4) |
222 (parity[rp3] << 3) |
223 (parity[rp2] << 2) |
224 (parity[rp1] << 1) |
225 (parity[rp0]);
226 code[1] =
227 (parity[rp15] << 7) |
228 (parity[rp14] << 6) |
229 (parity[rp13] << 5) |
230 (parity[rp12] << 4) |
231 (parity[rp11] << 3) |
232 (parity[rp10] << 2) |
233 (parity[rp9] << 1) |
234 (parity[rp8]);
235 code[2] =
236 (parity[par & 0xf0] << 7) |
237 (parity[par & 0x0f] << 6) |
238 (parity[par & 0xcc] << 5) |
239 (parity[par & 0x33] << 4) |
240 (parity[par & 0xaa] << 3) |
241 (parity[par & 0x55] << 2);
242 code[0] = ~code[0];
243 code[1] = ~code[1];
244 code[2] = ~code[2];
245}
246
247Still pretty straightforward. The last three invert statements are there to
248give a checksum of 0xff 0xff 0xff for an empty flash. In an empty flash
249all data is 0xff, so the checksum then matches.
250
251I also introduced the parity lookup. I expected this to be the fastest
252way to calculate the parity, but I will investigate alternatives later
253on.
254
255
256Analysis 1
257==========
258
259The code works, but is not terribly efficient. On my system it took
260almost 4 times as much time as the linux driver code. But hey, if it was
261*that* easy this would have been done long before.
262No pain. no gain.
263
264Fortunately there is plenty of room for improvement.
265
266In step 1 we moved from bit-wise calculation to byte-wise calculation.
267However in C we can also use the unsigned long data type and virtually
268every modern microprocessor supports 32 bit operations, so why not try
269to write our code in such a way that we process data in 32 bit chunks.
270
271Of course this means some modification as the row parity is byte by
272byte. A quick analysis:
273for the column parity we use the par variable. When extending to 32 bits
274we can in the end easily calculate p0 and p1 from it.
275(because par now consists of 4 bytes, contributing to rp1, rp0, rp1, rp0
276respectively)
277also rp2 and rp3 can be easily retrieved from par as rp3 covers the
278first two bytes and rp2 the last two bytes.
279
280Note that of course now the loop is executed only 64 times (256/4).
281And note that care must taken wrt byte ordering. The way bytes are
282ordered in a long is machine dependent, and might affect us.
283Anyway, if there is an issue: this code is developed on x86 (to be
284precise: a DELL PC with a D920 Intel CPU)
285
286And of course the performance might depend on alignment, but I expect
287that the I/O buffers in the nand driver are aligned properly (and
288otherwise that should be fixed to get maximum performance).
289
290Let's give it a try...
291
292
293Attempt 2
294=========
295
296extern const char parity[256];
297
298void ecc2(const unsigned char *buf, unsigned char *code)
299{
300 int i;
301 const unsigned long *bp = (unsigned long *)buf;
302 unsigned long cur;
303 unsigned long rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7;
304 unsigned long rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15;
305 unsigned long par;
306
307 par = 0;
308 rp0 = 0; rp1 = 0; rp2 = 0; rp3 = 0;
309 rp4 = 0; rp5 = 0; rp6 = 0; rp7 = 0;
310 rp8 = 0; rp9 = 0; rp10 = 0; rp11 = 0;
311 rp12 = 0; rp13 = 0; rp14 = 0; rp15 = 0;
312
313 for (i = 0; i < 64; i++)
314 {
315 cur = *bp++;
316 par ^= cur;
317 if (i & 0x01) rp5 ^= cur; else rp4 ^= cur;
318 if (i & 0x02) rp7 ^= cur; else rp6 ^= cur;
319 if (i & 0x04) rp9 ^= cur; else rp8 ^= cur;
320 if (i & 0x08) rp11 ^= cur; else rp10 ^= cur;
321 if (i & 0x10) rp13 ^= cur; else rp12 ^= cur;
322 if (i & 0x20) rp15 ^= cur; else rp14 ^= cur;
323 }
324 /*
325 we need to adapt the code generation for the fact that rp vars are now
326 long; also the column parity calculation needs to be changed.
327 we'll bring rp4 to 15 back to single byte entities by shifting and
328 xoring
329 */
330 rp4 ^= (rp4 >> 16); rp4 ^= (rp4 >> 8); rp4 &= 0xff;
331 rp5 ^= (rp5 >> 16); rp5 ^= (rp5 >> 8); rp5 &= 0xff;
332 rp6 ^= (rp6 >> 16); rp6 ^= (rp6 >> 8); rp6 &= 0xff;
333 rp7 ^= (rp7 >> 16); rp7 ^= (rp7 >> 8); rp7 &= 0xff;
334 rp8 ^= (rp8 >> 16); rp8 ^= (rp8 >> 8); rp8 &= 0xff;
335 rp9 ^= (rp9 >> 16); rp9 ^= (rp9 >> 8); rp9 &= 0xff;
336 rp10 ^= (rp10 >> 16); rp10 ^= (rp10 >> 8); rp10 &= 0xff;
337 rp11 ^= (rp11 >> 16); rp11 ^= (rp11 >> 8); rp11 &= 0xff;
338 rp12 ^= (rp12 >> 16); rp12 ^= (rp12 >> 8); rp12 &= 0xff;
339 rp13 ^= (rp13 >> 16); rp13 ^= (rp13 >> 8); rp13 &= 0xff;
340 rp14 ^= (rp14 >> 16); rp14 ^= (rp14 >> 8); rp14 &= 0xff;
341 rp15 ^= (rp15 >> 16); rp15 ^= (rp15 >> 8); rp15 &= 0xff;
342 rp3 = (par >> 16); rp3 ^= (rp3 >> 8); rp3 &= 0xff;
343 rp2 = par & 0xffff; rp2 ^= (rp2 >> 8); rp2 &= 0xff;
344 par ^= (par >> 16);
345 rp1 = (par >> 8); rp1 &= 0xff;
346 rp0 = (par & 0xff);
347 par ^= (par >> 8); par &= 0xff;
348
349 code[0] =
350 (parity[rp7] << 7) |
351 (parity[rp6] << 6) |
352 (parity[rp5] << 5) |
353 (parity[rp4] << 4) |
354 (parity[rp3] << 3) |
355 (parity[rp2] << 2) |
356 (parity[rp1] << 1) |
357 (parity[rp0]);
358 code[1] =
359 (parity[rp15] << 7) |
360 (parity[rp14] << 6) |
361 (parity[rp13] << 5) |
362 (parity[rp12] << 4) |
363 (parity[rp11] << 3) |
364 (parity[rp10] << 2) |
365 (parity[rp9] << 1) |
366 (parity[rp8]);
367 code[2] =
368 (parity[par & 0xf0] << 7) |
369 (parity[par & 0x0f] << 6) |
370 (parity[par & 0xcc] << 5) |
371 (parity[par & 0x33] << 4) |
372 (parity[par & 0xaa] << 3) |
373 (parity[par & 0x55] << 2);
374 code[0] = ~code[0];
375 code[1] = ~code[1];
376 code[2] = ~code[2];
377}
378
379The parity array is not shown any more. Note also that for these
380examples I kinda deviated from my regular programming style by allowing
381multiple statements on a line, not using { } in then and else blocks
382with only a single statement and by using operators like ^=
383
384
385Analysis 2
386==========
387
388The code (of course) works, and hurray: we are a little bit faster than
389the linux driver code (about 15%). But wait, don't cheer too quickly.
390THere is more to be gained.
391If we look at e.g. rp14 and rp15 we see that we either xor our data with
392rp14 or with rp15. However we also have par which goes over all data.
393This means there is no need to calculate rp14 as it can be calculated from
394rp15 through rp14 = par ^ rp15;
395(or if desired we can avoid calculating rp15 and calculate it from
396rp14). That is why some places refer to inverse parity.
397Of course the same thing holds for rp4/5, rp6/7, rp8/9, rp10/11 and rp12/13.
398Effectively this means we can eliminate the else clause from the if
399statements. Also we can optimise the calculation in the end a little bit
400by going from long to byte first. Actually we can even avoid the table
401lookups
402
403Attempt 3
404=========
405
406Odd replaced:
407 if (i & 0x01) rp5 ^= cur; else rp4 ^= cur;
408 if (i & 0x02) rp7 ^= cur; else rp6 ^= cur;
409 if (i & 0x04) rp9 ^= cur; else rp8 ^= cur;
410 if (i & 0x08) rp11 ^= cur; else rp10 ^= cur;
411 if (i & 0x10) rp13 ^= cur; else rp12 ^= cur;
412 if (i & 0x20) rp15 ^= cur; else rp14 ^= cur;
413with
414 if (i & 0x01) rp5 ^= cur;
415 if (i & 0x02) rp7 ^= cur;
416 if (i & 0x04) rp9 ^= cur;
417 if (i & 0x08) rp11 ^= cur;
418 if (i & 0x10) rp13 ^= cur;
419 if (i & 0x20) rp15 ^= cur;
420
421 and outside the loop added:
422 rp4 = par ^ rp5;
423 rp6 = par ^ rp7;
424 rp8 = par ^ rp9;
425 rp10 = par ^ rp11;
426 rp12 = par ^ rp13;
427 rp14 = par ^ rp15;
428
429And after that the code takes about 30% more time, although the number of
430statements is reduced. This is also reflected in the assembly code.
431
432
433Analysis 3
434==========
435
436Very weird. Guess it has to do with caching or instruction parallellism
437or so. I also tried on an eeePC (Celeron, clocked at 900 Mhz). Interesting
438observation was that this one is only 30% slower (according to time)
439executing the code as my 3Ghz D920 processor.
440
441Well, it was expected not to be easy so maybe instead move to a
442different track: let's move back to the code from attempt2 and do some
443loop unrolling. This will eliminate a few if statements. I'll try
444different amounts of unrolling to see what works best.
445
446
447Attempt 4
448=========
449
450Unrolled the loop 1, 2, 3 and 4 times.
451For 4 the code starts with:
452
453 for (i = 0; i < 4; i++)
454 {
455 cur = *bp++;
456 par ^= cur;
457 rp4 ^= cur;
458 rp6 ^= cur;
459 rp8 ^= cur;
460 rp10 ^= cur;
461 if (i & 0x1) rp13 ^= cur; else rp12 ^= cur;
462 if (i & 0x2) rp15 ^= cur; else rp14 ^= cur;
463 cur = *bp++;
464 par ^= cur;
465 rp5 ^= cur;
466 rp6 ^= cur;
467 ...
468
469
470Analysis 4
471==========
472
473Unrolling once gains about 15%
474Unrolling twice keeps the gain at about 15%
475Unrolling three times gives a gain of 30% compared to attempt 2.
476Unrolling four times gives a marginal improvement compared to unrolling
477three times.
478
479I decided to proceed with a four time unrolled loop anyway. It was my gut
480feeling that in the next steps I would obtain additional gain from it.
481
482The next step was triggered by the fact that par contains the xor of all
483bytes and rp4 and rp5 each contain the xor of half of the bytes.
484So in effect par = rp4 ^ rp5. But as xor is commutative we can also say
485that rp5 = par ^ rp4. So no need to keep both rp4 and rp5 around. We can
486eliminate rp5 (or rp4, but I already foresaw another optimisation).
487The same holds for rp6/7, rp8/9, rp10/11 rp12/13 and rp14/15.
488
489
490Attempt 5
491=========
492
493Effectively so all odd digit rp assignments in the loop were removed.
494This included the else clause of the if statements.
495Of course after the loop we need to correct things by adding code like:
496 rp5 = par ^ rp4;
497Also the initial assignments (rp5 = 0; etc) could be removed.
498Along the line I also removed the initialisation of rp0/1/2/3.
499
500
501Analysis 5
502==========
503
504Measurements showed this was a good move. The run-time roughly halved
505compared with attempt 4 with 4 times unrolled, and we only require 1/3rd
506of the processor time compared to the current code in the linux kernel.
507
508However, still I thought there was more. I didn't like all the if
509statements. Why not keep a running parity and only keep the last if
510statement. Time for yet another version!
511
512
513Attempt 6
514=========
515
516THe code within the for loop was changed to:
517
518 for (i = 0; i < 4; i++)
519 {
520 cur = *bp++; tmppar = cur; rp4 ^= cur;
521 cur = *bp++; tmppar ^= cur; rp6 ^= tmppar;
522 cur = *bp++; tmppar ^= cur; rp4 ^= cur;
523 cur = *bp++; tmppar ^= cur; rp8 ^= tmppar;
524
525 cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp6 ^= cur;
526 cur = *bp++; tmppar ^= cur; rp6 ^= cur;
527 cur = *bp++; tmppar ^= cur; rp4 ^= cur;
528 cur = *bp++; tmppar ^= cur; rp10 ^= tmppar;
529
530 cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp6 ^= cur; rp8 ^= cur;
531 cur = *bp++; tmppar ^= cur; rp6 ^= cur; rp8 ^= cur;
532 cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp8 ^= cur;
533 cur = *bp++; tmppar ^= cur; rp8 ^= cur;
534
535 cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp6 ^= cur;
536 cur = *bp++; tmppar ^= cur; rp6 ^= cur;
537 cur = *bp++; tmppar ^= cur; rp4 ^= cur;
538 cur = *bp++; tmppar ^= cur;
539
540 par ^= tmppar;
541 if ((i & 0x1) == 0) rp12 ^= tmppar;
542 if ((i & 0x2) == 0) rp14 ^= tmppar;
543 }
544
545As you can see tmppar is used to accumulate the parity within a for
546iteration. In the last 3 statements is is added to par and, if needed,
547to rp12 and rp14.
548
549While making the changes I also found that I could exploit that tmppar
550contains the running parity for this iteration. So instead of having:
551rp4 ^= cur; rp6 = cur;
552I removed the rp6 = cur; statement and did rp6 ^= tmppar; on next
553statement. A similar change was done for rp8 and rp10
554
555
556Analysis 6
557==========
558
559Measuring this code again showed big gain. When executing the original
560linux code 1 million times, this took about 1 second on my system.
561(using time to measure the performance). After this iteration I was back
562to 0.075 sec. Actually I had to decide to start measuring over 10
563million interations in order not to loose too much accuracy. This one
564definitely seemed to be the jackpot!
565
566There is a little bit more room for improvement though. There are three
567places with statements:
568rp4 ^= cur; rp6 ^= cur;
569It seems more efficient to also maintain a variable rp4_6 in the while
570loop; This eliminates 3 statements per loop. Of course after the loop we
571need to correct by adding:
572 rp4 ^= rp4_6;
573 rp6 ^= rp4_6
574Furthermore there are 4 sequential assingments to rp8. This can be
575encoded slightly more efficient by saving tmppar before those 4 lines
576and later do rp8 = rp8 ^ tmppar ^ notrp8;
577(where notrp8 is the value of rp8 before those 4 lines).
578Again a use of the commutative property of xor.
579Time for a new test!
580
581
582Attempt 7
583=========
584
585The new code now looks like:
586
587 for (i = 0; i < 4; i++)
588 {
589 cur = *bp++; tmppar = cur; rp4 ^= cur;
590 cur = *bp++; tmppar ^= cur; rp6 ^= tmppar;
591 cur = *bp++; tmppar ^= cur; rp4 ^= cur;
592 cur = *bp++; tmppar ^= cur; rp8 ^= tmppar;
593
594 cur = *bp++; tmppar ^= cur; rp4_6 ^= cur;
595 cur = *bp++; tmppar ^= cur; rp6 ^= cur;
596 cur = *bp++; tmppar ^= cur; rp4 ^= cur;
597 cur = *bp++; tmppar ^= cur; rp10 ^= tmppar;
598
599 notrp8 = tmppar;
600 cur = *bp++; tmppar ^= cur; rp4_6 ^= cur;
601 cur = *bp++; tmppar ^= cur; rp6 ^= cur;
602 cur = *bp++; tmppar ^= cur; rp4 ^= cur;
603 cur = *bp++; tmppar ^= cur;
604 rp8 = rp8 ^ tmppar ^ notrp8;
605
606 cur = *bp++; tmppar ^= cur; rp4_6 ^= cur;
607 cur = *bp++; tmppar ^= cur; rp6 ^= cur;
608 cur = *bp++; tmppar ^= cur; rp4 ^= cur;
609 cur = *bp++; tmppar ^= cur;
610
611 par ^= tmppar;
612 if ((i & 0x1) == 0) rp12 ^= tmppar;
613 if ((i & 0x2) == 0) rp14 ^= tmppar;
614 }
615 rp4 ^= rp4_6;
616 rp6 ^= rp4_6;
617
618
619Not a big change, but every penny counts :-)
620
621
622Analysis 7
623==========
624
625Acutally this made things worse. Not very much, but I don't want to move
626into the wrong direction. Maybe something to investigate later. Could
627have to do with caching again.
628
629Guess that is what there is to win within the loop. Maybe unrolling one
630more time will help. I'll keep the optimisations from 7 for now.
631
632
633Attempt 8
634=========
635
636Unrolled the loop one more time.
637
638
639Analysis 8
640==========
641
642This makes things worse. Let's stick with attempt 6 and continue from there.
643Although it seems that the code within the loop cannot be optimised
644further there is still room to optimize the generation of the ecc codes.
645We can simply calcualate the total parity. If this is 0 then rp4 = rp5
646etc. If the parity is 1, then rp4 = !rp5;
647But if rp4 = rp5 we do not need rp5 etc. We can just write the even bits
648in the result byte and then do something like
649 code[0] |= (code[0] << 1);
650Lets test this.
651
652
653Attempt 9
654=========
655
656Changed the code but again this slightly degrades performance. Tried all
657kind of other things, like having dedicated parity arrays to avoid the
658shift after parity[rp7] << 7; No gain.
659Change the lookup using the parity array by using shift operators (e.g.
660replace parity[rp7] << 7 with:
661rp7 ^= (rp7 << 4);
662rp7 ^= (rp7 << 2);
663rp7 ^= (rp7 << 1);
664rp7 &= 0x80;
665No gain.
666
667The only marginal change was inverting the parity bits, so we can remove
668the last three invert statements.
669
670Ah well, pity this does not deliver more. Then again 10 million
671iterations using the linux driver code takes between 13 and 13.5
672seconds, whereas my code now takes about 0.73 seconds for those 10
673million iterations. So basically I've improved the performance by a
674factor 18 on my system. Not that bad. Of course on different hardware
675you will get different results. No warranties!
676
677But of course there is no such thing as a free lunch. The codesize almost
678tripled (from 562 bytes to 1434 bytes). Then again, it is not that much.
679
680
681Correcting errors
682=================
683
684For correcting errors I again used the ST application note as a starter,
685but I also peeked at the existing code.
686The algorithm itself is pretty straightforward. Just xor the given and
687the calculated ecc. If all bytes are 0 there is no problem. If 11 bits
688are 1 we have one correctable bit error. If there is 1 bit 1, we have an
689error in the given ecc code.
690It proved to be fastest to do some table lookups. Performance gain
691introduced by this is about a factor 2 on my system when a repair had to
692be done, and 1% or so if no repair had to be done.
693Code size increased from 330 bytes to 686 bytes for this function.
694(gcc 4.2, -O3)
695
696
697Conclusion
698==========
699
700The gain when calculating the ecc is tremendous. Om my development hardware
701a speedup of a factor of 18 for ecc calculation was achieved. On a test on an
702embedded system with a MIPS core a factor 7 was obtained.
703On a test with a Linksys NSLU2 (ARMv5TE processor) the speedup was a factor
7045 (big endian mode, gcc 4.1.2, -O3)
705For correction not much gain could be obtained (as bitflips are rare). Then
706again there are also much less cycles spent there.
707
708It seems there is not much more gain possible in this, at least when
709programmed in C. Of course it might be possible to squeeze something more
710out of it with an assembler program, but due to pipeline behaviour etc
711this is very tricky (at least for intel hw).
712
713Author: Frans Meulenbroeks
714Copyright (C) 2008 Koninklijke Philips Electronics NV.
diff --git a/arch/arm/plat-omap/include/mach/onenand.h b/arch/arm/plat-omap/include/mach/onenand.h
index d57f20226b28..4649d302c263 100644
--- a/arch/arm/plat-omap/include/mach/onenand.h
+++ b/arch/arm/plat-omap/include/mach/onenand.h
@@ -16,6 +16,10 @@ struct omap_onenand_platform_data {
16 int gpio_irq; 16 int gpio_irq;
17 struct mtd_partition *parts; 17 struct mtd_partition *parts;
18 int nr_parts; 18 int nr_parts;
19 int (*onenand_setup)(void __iomem *); 19 int (*onenand_setup)(void __iomem *, int freq);
20 int dma_channel; 20 int dma_channel;
21}; 21};
22
23int omap2_onenand_rephase(void);
24
25#define ONENAND_MAX_PARTITIONS 8
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 14f11f8b9e5f..a90d50c2c3e5 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -172,6 +172,11 @@ config MTD_CHAR
172 memory chips, and also use ioctl() to obtain information about 172 memory chips, and also use ioctl() to obtain information about
173 the device, or to erase parts of it. 173 the device, or to erase parts of it.
174 174
175config HAVE_MTD_OTP
176 bool
177 help
178 Enable access to OTP regions using MTD_CHAR.
179
175config MTD_BLKDEVS 180config MTD_BLKDEVS
176 tristate "Common interface to block layer for MTD 'translation layers'" 181 tristate "Common interface to block layer for MTD 'translation layers'"
177 depends on BLOCK 182 depends on BLOCK
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index 479d32b57a1e..9401bfec4623 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -154,6 +154,7 @@ config MTD_CFI_I8
154config MTD_OTP 154config MTD_OTP
155 bool "Protection Registers aka one-time programmable (OTP) bits" 155 bool "Protection Registers aka one-time programmable (OTP) bits"
156 depends on MTD_CFI_ADV_OPTIONS 156 depends on MTD_CFI_ADV_OPTIONS
157 select HAVE_MTD_OTP
157 default n 158 default n
158 help 159 help
159 This enables support for reading, writing and locking so called 160 This enables support for reading, writing and locking so called
@@ -187,7 +188,7 @@ config MTD_CFI_INTELEXT
187 StrataFlash and other parts. 188 StrataFlash and other parts.
188 189
189config MTD_CFI_AMDSTD 190config MTD_CFI_AMDSTD
190 tristate "Support for AMD/Fujitsu flash chips" 191 tristate "Support for AMD/Fujitsu/Spansion flash chips"
191 depends on MTD_GEN_PROBE 192 depends on MTD_GEN_PROBE
192 select MTD_CFI_UTIL 193 select MTD_CFI_UTIL
193 help 194 help
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 5f1b472137a0..5157e3cb4b9e 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -478,6 +478,28 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
478 else 478 else
479 cfi->chips[i].erase_time = 2000000; 479 cfi->chips[i].erase_time = 2000000;
480 480
481 if (cfi->cfiq->WordWriteTimeoutTyp &&
482 cfi->cfiq->WordWriteTimeoutMax)
483 cfi->chips[i].word_write_time_max =
484 1<<(cfi->cfiq->WordWriteTimeoutTyp +
485 cfi->cfiq->WordWriteTimeoutMax);
486 else
487 cfi->chips[i].word_write_time_max = 50000 * 8;
488
489 if (cfi->cfiq->BufWriteTimeoutTyp &&
490 cfi->cfiq->BufWriteTimeoutMax)
491 cfi->chips[i].buffer_write_time_max =
492 1<<(cfi->cfiq->BufWriteTimeoutTyp +
493 cfi->cfiq->BufWriteTimeoutMax);
494
495 if (cfi->cfiq->BlockEraseTimeoutTyp &&
496 cfi->cfiq->BlockEraseTimeoutMax)
497 cfi->chips[i].erase_time_max =
498 1000<<(cfi->cfiq->BlockEraseTimeoutTyp +
499 cfi->cfiq->BlockEraseTimeoutMax);
500 else
501 cfi->chips[i].erase_time_max = 2000000 * 8;
502
481 cfi->chips[i].ref_point_counter = 0; 503 cfi->chips[i].ref_point_counter = 0;
482 init_waitqueue_head(&(cfi->chips[i].wq)); 504 init_waitqueue_head(&(cfi->chips[i].wq));
483 } 505 }
@@ -1012,7 +1034,7 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
1012 1034
1013static int __xipram xip_wait_for_operation( 1035static int __xipram xip_wait_for_operation(
1014 struct map_info *map, struct flchip *chip, 1036 struct map_info *map, struct flchip *chip,
1015 unsigned long adr, unsigned int chip_op_time ) 1037 unsigned long adr, unsigned int chip_op_time_max)
1016{ 1038{
1017 struct cfi_private *cfi = map->fldrv_priv; 1039 struct cfi_private *cfi = map->fldrv_priv;
1018 struct cfi_pri_intelext *cfip = cfi->cmdset_priv; 1040 struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
@@ -1021,7 +1043,7 @@ static int __xipram xip_wait_for_operation(
1021 flstate_t oldstate, newstate; 1043 flstate_t oldstate, newstate;
1022 1044
1023 start = xip_currtime(); 1045 start = xip_currtime();
1024 usec = chip_op_time * 8; 1046 usec = chip_op_time_max;
1025 if (usec == 0) 1047 if (usec == 0)
1026 usec = 500000; 1048 usec = 500000;
1027 done = 0; 1049 done = 0;
@@ -1131,8 +1153,8 @@ static int __xipram xip_wait_for_operation(
1131#define XIP_INVAL_CACHED_RANGE(map, from, size) \ 1153#define XIP_INVAL_CACHED_RANGE(map, from, size) \
1132 INVALIDATE_CACHED_RANGE(map, from, size) 1154 INVALIDATE_CACHED_RANGE(map, from, size)
1133 1155
1134#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec) \ 1156#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec, usec_max) \
1135 xip_wait_for_operation(map, chip, cmd_adr, usec) 1157 xip_wait_for_operation(map, chip, cmd_adr, usec_max)
1136 1158
1137#else 1159#else
1138 1160
@@ -1144,7 +1166,7 @@ static int __xipram xip_wait_for_operation(
1144static int inval_cache_and_wait_for_operation( 1166static int inval_cache_and_wait_for_operation(
1145 struct map_info *map, struct flchip *chip, 1167 struct map_info *map, struct flchip *chip,
1146 unsigned long cmd_adr, unsigned long inval_adr, int inval_len, 1168 unsigned long cmd_adr, unsigned long inval_adr, int inval_len,
1147 unsigned int chip_op_time) 1169 unsigned int chip_op_time, unsigned int chip_op_time_max)
1148{ 1170{
1149 struct cfi_private *cfi = map->fldrv_priv; 1171 struct cfi_private *cfi = map->fldrv_priv;
1150 map_word status, status_OK = CMD(0x80); 1172 map_word status, status_OK = CMD(0x80);
@@ -1156,8 +1178,7 @@ static int inval_cache_and_wait_for_operation(
1156 INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len); 1178 INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len);
1157 spin_lock(chip->mutex); 1179 spin_lock(chip->mutex);
1158 1180
1159 /* set our timeout to 8 times the expected delay */ 1181 timeo = chip_op_time_max;
1160 timeo = chip_op_time * 8;
1161 if (!timeo) 1182 if (!timeo)
1162 timeo = 500000; 1183 timeo = 500000;
1163 reset_timeo = timeo; 1184 reset_timeo = timeo;
@@ -1217,8 +1238,8 @@ static int inval_cache_and_wait_for_operation(
1217 1238
1218#endif 1239#endif
1219 1240
1220#define WAIT_TIMEOUT(map, chip, adr, udelay) \ 1241#define WAIT_TIMEOUT(map, chip, adr, udelay, udelay_max) \
1221 INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay); 1242 INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay, udelay_max);
1222 1243
1223 1244
1224static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) 1245static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
@@ -1452,7 +1473,8 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1452 1473
1453 ret = INVAL_CACHE_AND_WAIT(map, chip, adr, 1474 ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
1454 adr, map_bankwidth(map), 1475 adr, map_bankwidth(map),
1455 chip->word_write_time); 1476 chip->word_write_time,
1477 chip->word_write_time_max);
1456 if (ret) { 1478 if (ret) {
1457 xip_enable(map, chip, adr); 1479 xip_enable(map, chip, adr);
1458 printk(KERN_ERR "%s: word write error (status timeout)\n", map->name); 1480 printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
@@ -1623,7 +1645,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1623 1645
1624 chip->state = FL_WRITING_TO_BUFFER; 1646 chip->state = FL_WRITING_TO_BUFFER;
1625 map_write(map, write_cmd, cmd_adr); 1647 map_write(map, write_cmd, cmd_adr);
1626 ret = WAIT_TIMEOUT(map, chip, cmd_adr, 0); 1648 ret = WAIT_TIMEOUT(map, chip, cmd_adr, 0, 0);
1627 if (ret) { 1649 if (ret) {
1628 /* Argh. Not ready for write to buffer */ 1650 /* Argh. Not ready for write to buffer */
1629 map_word Xstatus = map_read(map, cmd_adr); 1651 map_word Xstatus = map_read(map, cmd_adr);
@@ -1640,7 +1662,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1640 1662
1641 /* Figure out the number of words to write */ 1663 /* Figure out the number of words to write */
1642 word_gap = (-adr & (map_bankwidth(map)-1)); 1664 word_gap = (-adr & (map_bankwidth(map)-1));
1643 words = (len - word_gap + map_bankwidth(map) - 1) / map_bankwidth(map); 1665 words = DIV_ROUND_UP(len - word_gap, map_bankwidth(map));
1644 if (!word_gap) { 1666 if (!word_gap) {
1645 words--; 1667 words--;
1646 } else { 1668 } else {
@@ -1692,7 +1714,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1692 1714
1693 ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, 1715 ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr,
1694 initial_adr, initial_len, 1716 initial_adr, initial_len,
1695 chip->buffer_write_time); 1717 chip->buffer_write_time,
1718 chip->buffer_write_time_max);
1696 if (ret) { 1719 if (ret) {
1697 map_write(map, CMD(0x70), cmd_adr); 1720 map_write(map, CMD(0x70), cmd_adr);
1698 chip->state = FL_STATUS; 1721 chip->state = FL_STATUS;
@@ -1827,7 +1850,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1827 1850
1828 ret = INVAL_CACHE_AND_WAIT(map, chip, adr, 1851 ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
1829 adr, len, 1852 adr, len,
1830 chip->erase_time); 1853 chip->erase_time,
1854 chip->erase_time_max);
1831 if (ret) { 1855 if (ret) {
1832 map_write(map, CMD(0x70), adr); 1856 map_write(map, CMD(0x70), adr);
1833 chip->state = FL_STATUS; 1857 chip->state = FL_STATUS;
@@ -2006,7 +2030,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
2006 */ 2030 */
2007 udelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1000000/HZ : 0; 2031 udelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1000000/HZ : 0;
2008 2032
2009 ret = WAIT_TIMEOUT(map, chip, adr, udelay); 2033 ret = WAIT_TIMEOUT(map, chip, adr, udelay, udelay * 100);
2010 if (ret) { 2034 if (ret) {
2011 map_write(map, CMD(0x70), adr); 2035 map_write(map, CMD(0x70), adr);
2012 chip->state = FL_STATUS; 2036 chip->state = FL_STATUS;
diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c
index c418e92e1d92..e63e6749429a 100644
--- a/drivers/mtd/chips/cfi_probe.c
+++ b/drivers/mtd/chips/cfi_probe.c
@@ -44,17 +44,14 @@ do { \
44 44
45#define xip_enable(base, map, cfi) \ 45#define xip_enable(base, map, cfi) \
46do { \ 46do { \
47 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); \ 47 cfi_qry_mode_off(base, map, cfi); \
48 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); \
49 xip_allowed(base, map); \ 48 xip_allowed(base, map); \
50} while (0) 49} while (0)
51 50
52#define xip_disable_qry(base, map, cfi) \ 51#define xip_disable_qry(base, map, cfi) \
53do { \ 52do { \
54 xip_disable(); \ 53 xip_disable(); \
55 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); \ 54 cfi_qry_mode_on(base, map, cfi); \
56 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); \
57 cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); \
58} while (0) 55} while (0)
59 56
60#else 57#else
@@ -70,32 +67,6 @@ do { \
70 in: interleave,type,mode 67 in: interleave,type,mode
71 ret: table index, <0 for error 68 ret: table index, <0 for error
72 */ 69 */
73static int __xipram qry_present(struct map_info *map, __u32 base,
74 struct cfi_private *cfi)
75{
76 int osf = cfi->interleave * cfi->device_type; // scale factor
77 map_word val[3];
78 map_word qry[3];
79
80 qry[0] = cfi_build_cmd('Q', map, cfi);
81 qry[1] = cfi_build_cmd('R', map, cfi);
82 qry[2] = cfi_build_cmd('Y', map, cfi);
83
84 val[0] = map_read(map, base + osf*0x10);
85 val[1] = map_read(map, base + osf*0x11);
86 val[2] = map_read(map, base + osf*0x12);
87
88 if (!map_word_equal(map, qry[0], val[0]))
89 return 0;
90
91 if (!map_word_equal(map, qry[1], val[1]))
92 return 0;
93
94 if (!map_word_equal(map, qry[2], val[2]))
95 return 0;
96
97 return 1; // "QRY" found
98}
99 70
100static int __xipram cfi_probe_chip(struct map_info *map, __u32 base, 71static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
101 unsigned long *chip_map, struct cfi_private *cfi) 72 unsigned long *chip_map, struct cfi_private *cfi)
@@ -116,11 +87,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
116 } 87 }
117 88
118 xip_disable(); 89 xip_disable();
119 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); 90 if (!cfi_qry_mode_on(base, map, cfi)) {
120 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
121 cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
122
123 if (!qry_present(map,base,cfi)) {
124 xip_enable(base, map, cfi); 91 xip_enable(base, map, cfi);
125 return 0; 92 return 0;
126 } 93 }
@@ -141,14 +108,13 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
141 start = i << cfi->chipshift; 108 start = i << cfi->chipshift;
142 /* This chip should be in read mode if it's one 109 /* This chip should be in read mode if it's one
143 we've already touched. */ 110 we've already touched. */
144 if (qry_present(map, start, cfi)) { 111 if (cfi_qry_present(map, start, cfi)) {
145 /* Eep. This chip also had the QRY marker. 112 /* Eep. This chip also had the QRY marker.
146 * Is it an alias for the new one? */ 113 * Is it an alias for the new one? */
147 cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL); 114 cfi_qry_mode_off(start, map, cfi);
148 cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
149 115
150 /* If the QRY marker goes away, it's an alias */ 116 /* If the QRY marker goes away, it's an alias */
151 if (!qry_present(map, start, cfi)) { 117 if (!cfi_qry_present(map, start, cfi)) {
152 xip_allowed(base, map); 118 xip_allowed(base, map);
153 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", 119 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
154 map->name, base, start); 120 map->name, base, start);
@@ -158,10 +124,9 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
158 * unfortunate. Stick the new chip in read mode 124 * unfortunate. Stick the new chip in read mode
159 * too and if it's the same, assume it's an alias. */ 125 * too and if it's the same, assume it's an alias. */
160 /* FIXME: Use other modes to do a proper check */ 126 /* FIXME: Use other modes to do a proper check */
161 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); 127 cfi_qry_mode_off(base, map, cfi);
162 cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
163 128
164 if (qry_present(map, base, cfi)) { 129 if (cfi_qry_present(map, base, cfi)) {
165 xip_allowed(base, map); 130 xip_allowed(base, map);
166 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", 131 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
167 map->name, base, start); 132 map->name, base, start);
@@ -176,8 +141,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
176 cfi->numchips++; 141 cfi->numchips++;
177 142
178 /* Put it back into Read Mode */ 143 /* Put it back into Read Mode */
179 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); 144 cfi_qry_mode_off(base, map, cfi);
180 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
181 xip_allowed(base, map); 145 xip_allowed(base, map);
182 146
183 printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", 147 printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
@@ -237,9 +201,7 @@ static int __xipram cfi_chip_setup(struct map_info *map,
237 cfi_read_query(map, base + 0xf * ofs_factor); 201 cfi_read_query(map, base + 0xf * ofs_factor);
238 202
239 /* Put it back into Read Mode */ 203 /* Put it back into Read Mode */
240 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); 204 cfi_qry_mode_off(base, map, cfi);
241 /* ... even if it's an Intel chip */
242 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
243 xip_allowed(base, map); 205 xip_allowed(base, map);
244 206
245 /* Do any necessary byteswapping */ 207 /* Do any necessary byteswapping */
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c
index 0ee457018016..34d40e25d312 100644
--- a/drivers/mtd/chips/cfi_util.c
+++ b/drivers/mtd/chips/cfi_util.c
@@ -24,6 +24,66 @@
24#include <linux/mtd/cfi.h> 24#include <linux/mtd/cfi.h>
25#include <linux/mtd/compatmac.h> 25#include <linux/mtd/compatmac.h>
26 26
27int __xipram cfi_qry_present(struct map_info *map, __u32 base,
28 struct cfi_private *cfi)
29{
30 int osf = cfi->interleave * cfi->device_type; /* scale factor */
31 map_word val[3];
32 map_word qry[3];
33
34 qry[0] = cfi_build_cmd('Q', map, cfi);
35 qry[1] = cfi_build_cmd('R', map, cfi);
36 qry[2] = cfi_build_cmd('Y', map, cfi);
37
38 val[0] = map_read(map, base + osf*0x10);
39 val[1] = map_read(map, base + osf*0x11);
40 val[2] = map_read(map, base + osf*0x12);
41
42 if (!map_word_equal(map, qry[0], val[0]))
43 return 0;
44
45 if (!map_word_equal(map, qry[1], val[1]))
46 return 0;
47
48 if (!map_word_equal(map, qry[2], val[2]))
49 return 0;
50
51 return 1; /* "QRY" found */
52}
53EXPORT_SYMBOL_GPL(cfi_qry_present);
54
55int __xipram cfi_qry_mode_on(uint32_t base, struct map_info *map,
56 struct cfi_private *cfi)
57{
58 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
59 cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
60 if (cfi_qry_present(map, base, cfi))
61 return 1;
62 /* QRY not found probably we deal with some odd CFI chips */
63 /* Some revisions of some old Intel chips? */
64 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
65 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
66 cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
67 if (cfi_qry_present(map, base, cfi))
68 return 1;
69 /* ST M29DW chips */
70 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
71 cfi_send_gen_cmd(0x98, 0x555, base, map, cfi, cfi->device_type, NULL);
72 if (cfi_qry_present(map, base, cfi))
73 return 1;
74 /* QRY not found */
75 return 0;
76}
77EXPORT_SYMBOL_GPL(cfi_qry_mode_on);
78
79void __xipram cfi_qry_mode_off(uint32_t base, struct map_info *map,
80 struct cfi_private *cfi)
81{
82 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
83 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
84}
85EXPORT_SYMBOL_GPL(cfi_qry_mode_off);
86
27struct cfi_extquery * 87struct cfi_extquery *
28__xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name) 88__xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name)
29{ 89{
@@ -48,8 +108,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n
48#endif 108#endif
49 109
50 /* Switch it into Query Mode */ 110 /* Switch it into Query Mode */
51 cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); 111 cfi_qry_mode_on(base, map, cfi);
52
53 /* Read in the Extended Query Table */ 112 /* Read in the Extended Query Table */
54 for (i=0; i<size; i++) { 113 for (i=0; i<size; i++) {
55 ((unsigned char *)extp)[i] = 114 ((unsigned char *)extp)[i] =
@@ -57,8 +116,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n
57 } 116 }
58 117
59 /* Make sure it returns to read mode */ 118 /* Make sure it returns to read mode */
60 cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL); 119 cfi_qry_mode_off(base, map, cfi);
61 cfi_send_gen_cmd(0xff, 0, base, map, cfi, cfi->device_type, NULL);
62 120
63#ifdef CONFIG_MTD_XIP 121#ifdef CONFIG_MTD_XIP
64 (void) map_read(map, base); 122 (void) map_read(map, base);
diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c
index f061885b2812..e2dc96441e05 100644
--- a/drivers/mtd/chips/gen_probe.c
+++ b/drivers/mtd/chips/gen_probe.c
@@ -111,7 +111,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
111 max_chips = 1; 111 max_chips = 1;
112 } 112 }
113 113
114 mapsize = sizeof(long) * ( (max_chips + BITS_PER_LONG-1) / BITS_PER_LONG ); 114 mapsize = sizeof(long) * DIV_ROUND_UP(max_chips, BITS_PER_LONG);
115 chip_map = kzalloc(mapsize, GFP_KERNEL); 115 chip_map = kzalloc(mapsize, GFP_KERNEL);
116 if (!chip_map) { 116 if (!chip_map) {
117 printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name); 117 printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name);
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 9c613f06623c..6fde0a2e3567 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -59,6 +59,27 @@ config MTD_DATAFLASH
59 Sometimes DataFlash chips are packaged inside MMC-format 59 Sometimes DataFlash chips are packaged inside MMC-format
60 cards; at this writing, the MMC stack won't handle those. 60 cards; at this writing, the MMC stack won't handle those.
61 61
62config MTD_DATAFLASH_WRITE_VERIFY
63 bool "Verify DataFlash page writes"
64 depends on MTD_DATAFLASH
65 help
66 This adds an extra check when data is written to the flash.
67 It may help if you are verifying chip setup (timings etc) on
68 your board. There is a rare possibility that even though the
69 device thinks the write was successful, a bit could have been
70 flipped accidentally due to device wear or something else.
71
72config MTD_DATAFLASH_OTP
73 bool "DataFlash OTP support (Security Register)"
74 depends on MTD_DATAFLASH
75 select HAVE_MTD_OTP
76 help
77 Newer DataFlash chips (revisions C and D) support 128 bytes of
78 one-time-programmable (OTP) data. The first half may be written
79 (once) with up to 64 bytes of data, such as a serial number or
80 other key product data. The second half is programmed with a
81 unique-to-each-chip bit pattern at the factory.
82
62config MTD_M25P80 83config MTD_M25P80
63 tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)" 84 tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)"
64 depends on SPI_MASTER && EXPERIMENTAL 85 depends on SPI_MASTER && EXPERIMENTAL
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index b35c3333e210..4d3ae085b1d2 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -39,6 +39,7 @@
39#define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */ 39#define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */
40#define OPCODE_BE_4K 0x20 /* Erase 4KiB block */ 40#define OPCODE_BE_4K 0x20 /* Erase 4KiB block */
41#define OPCODE_BE_32K 0x52 /* Erase 32KiB block */ 41#define OPCODE_BE_32K 0x52 /* Erase 32KiB block */
42#define OPCODE_BE 0xc7 /* Erase whole flash block */
42#define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */ 43#define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */
43#define OPCODE_RDID 0x9f /* Read JEDEC ID */ 44#define OPCODE_RDID 0x9f /* Read JEDEC ID */
44 45
@@ -133,7 +134,7 @@ static inline int write_enable(struct m25p *flash)
133{ 134{
134 u8 code = OPCODE_WREN; 135 u8 code = OPCODE_WREN;
135 136
136 return spi_write_then_read(flash->spi, &code, 1, NULL, 0); 137 return spi_write(flash->spi, &code, 1);
137} 138}
138 139
139 140
@@ -161,6 +162,31 @@ static int wait_till_ready(struct m25p *flash)
161 return 1; 162 return 1;
162} 163}
163 164
165/*
166 * Erase the whole flash memory
167 *
168 * Returns 0 if successful, non-zero otherwise.
169 */
170static int erase_block(struct m25p *flash)
171{
172 DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB\n",
173 flash->spi->dev.bus_id, __func__,
174 flash->mtd.size / 1024);
175
176 /* Wait until finished previous write command. */
177 if (wait_till_ready(flash))
178 return 1;
179
180 /* Send write enable, then erase commands. */
181 write_enable(flash);
182
183 /* Set up command buffer. */
184 flash->command[0] = OPCODE_BE;
185
186 spi_write(flash->spi, flash->command, 1);
187
188 return 0;
189}
164 190
165/* 191/*
166 * Erase one sector of flash memory at offset ``offset'' which is any 192 * Erase one sector of flash memory at offset ``offset'' which is any
@@ -229,15 +255,21 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
229 */ 255 */
230 256
231 /* now erase those sectors */ 257 /* now erase those sectors */
232 while (len) { 258 if (len == flash->mtd.size && erase_block(flash)) {
233 if (erase_sector(flash, addr)) { 259 instr->state = MTD_ERASE_FAILED;
234 instr->state = MTD_ERASE_FAILED; 260 mutex_unlock(&flash->lock);
235 mutex_unlock(&flash->lock); 261 return -EIO;
236 return -EIO; 262 } else {
237 } 263 while (len) {
264 if (erase_sector(flash, addr)) {
265 instr->state = MTD_ERASE_FAILED;
266 mutex_unlock(&flash->lock);
267 return -EIO;
268 }
238 269
239 addr += mtd->erasesize; 270 addr += mtd->erasesize;
240 len -= mtd->erasesize; 271 len -= mtd->erasesize;
272 }
241 } 273 }
242 274
243 mutex_unlock(&flash->lock); 275 mutex_unlock(&flash->lock);
@@ -437,6 +469,7 @@ struct flash_info {
437 * then a two byte device id. 469 * then a two byte device id.
438 */ 470 */
439 u32 jedec_id; 471 u32 jedec_id;
472 u16 ext_id;
440 473
441 /* The size listed here is what works with OPCODE_SE, which isn't 474 /* The size listed here is what works with OPCODE_SE, which isn't
442 * necessarily called a "sector" by the vendor. 475 * necessarily called a "sector" by the vendor.
@@ -456,57 +489,59 @@ struct flash_info {
456static struct flash_info __devinitdata m25p_data [] = { 489static struct flash_info __devinitdata m25p_data [] = {
457 490
458 /* Atmel -- some are (confusingly) marketed as "DataFlash" */ 491 /* Atmel -- some are (confusingly) marketed as "DataFlash" */
459 { "at25fs010", 0x1f6601, 32 * 1024, 4, SECT_4K, }, 492 { "at25fs010", 0x1f6601, 0, 32 * 1024, 4, SECT_4K, },
460 { "at25fs040", 0x1f6604, 64 * 1024, 8, SECT_4K, }, 493 { "at25fs040", 0x1f6604, 0, 64 * 1024, 8, SECT_4K, },
461 494
462 { "at25df041a", 0x1f4401, 64 * 1024, 8, SECT_4K, }, 495 { "at25df041a", 0x1f4401, 0, 64 * 1024, 8, SECT_4K, },
463 { "at25df641", 0x1f4800, 64 * 1024, 128, SECT_4K, }, 496 { "at25df641", 0x1f4800, 0, 64 * 1024, 128, SECT_4K, },
464 497
465 { "at26f004", 0x1f0400, 64 * 1024, 8, SECT_4K, }, 498 { "at26f004", 0x1f0400, 0, 64 * 1024, 8, SECT_4K, },
466 { "at26df081a", 0x1f4501, 64 * 1024, 16, SECT_4K, }, 499 { "at26df081a", 0x1f4501, 0, 64 * 1024, 16, SECT_4K, },
467 { "at26df161a", 0x1f4601, 64 * 1024, 32, SECT_4K, }, 500 { "at26df161a", 0x1f4601, 0, 64 * 1024, 32, SECT_4K, },
468 { "at26df321", 0x1f4701, 64 * 1024, 64, SECT_4K, }, 501 { "at26df321", 0x1f4701, 0, 64 * 1024, 64, SECT_4K, },
469 502
470 /* Spansion -- single (large) sector size only, at least 503 /* Spansion -- single (large) sector size only, at least
471 * for the chips listed here (without boot sectors). 504 * for the chips listed here (without boot sectors).
472 */ 505 */
473 { "s25sl004a", 0x010212, 64 * 1024, 8, }, 506 { "s25sl004a", 0x010212, 0, 64 * 1024, 8, },
474 { "s25sl008a", 0x010213, 64 * 1024, 16, }, 507 { "s25sl008a", 0x010213, 0, 64 * 1024, 16, },
475 { "s25sl016a", 0x010214, 64 * 1024, 32, }, 508 { "s25sl016a", 0x010214, 0, 64 * 1024, 32, },
476 { "s25sl032a", 0x010215, 64 * 1024, 64, }, 509 { "s25sl032a", 0x010215, 0, 64 * 1024, 64, },
477 { "s25sl064a", 0x010216, 64 * 1024, 128, }, 510 { "s25sl064a", 0x010216, 0, 64 * 1024, 128, },
511 { "s25sl12800", 0x012018, 0x0300, 256 * 1024, 64, },
512 { "s25sl12801", 0x012018, 0x0301, 64 * 1024, 256, },
478 513
479 /* SST -- large erase sizes are "overlays", "sectors" are 4K */ 514 /* SST -- large erase sizes are "overlays", "sectors" are 4K */
480 { "sst25vf040b", 0xbf258d, 64 * 1024, 8, SECT_4K, }, 515 { "sst25vf040b", 0xbf258d, 0, 64 * 1024, 8, SECT_4K, },
481 { "sst25vf080b", 0xbf258e, 64 * 1024, 16, SECT_4K, }, 516 { "sst25vf080b", 0xbf258e, 0, 64 * 1024, 16, SECT_4K, },
482 { "sst25vf016b", 0xbf2541, 64 * 1024, 32, SECT_4K, }, 517 { "sst25vf016b", 0xbf2541, 0, 64 * 1024, 32, SECT_4K, },
483 { "sst25vf032b", 0xbf254a, 64 * 1024, 64, SECT_4K, }, 518 { "sst25vf032b", 0xbf254a, 0, 64 * 1024, 64, SECT_4K, },
484 519
485 /* ST Microelectronics -- newer production may have feature updates */ 520 /* ST Microelectronics -- newer production may have feature updates */
486 { "m25p05", 0x202010, 32 * 1024, 2, }, 521 { "m25p05", 0x202010, 0, 32 * 1024, 2, },
487 { "m25p10", 0x202011, 32 * 1024, 4, }, 522 { "m25p10", 0x202011, 0, 32 * 1024, 4, },
488 { "m25p20", 0x202012, 64 * 1024, 4, }, 523 { "m25p20", 0x202012, 0, 64 * 1024, 4, },
489 { "m25p40", 0x202013, 64 * 1024, 8, }, 524 { "m25p40", 0x202013, 0, 64 * 1024, 8, },
490 { "m25p80", 0, 64 * 1024, 16, }, 525 { "m25p80", 0, 0, 64 * 1024, 16, },
491 { "m25p16", 0x202015, 64 * 1024, 32, }, 526 { "m25p16", 0x202015, 0, 64 * 1024, 32, },
492 { "m25p32", 0x202016, 64 * 1024, 64, }, 527 { "m25p32", 0x202016, 0, 64 * 1024, 64, },
493 { "m25p64", 0x202017, 64 * 1024, 128, }, 528 { "m25p64", 0x202017, 0, 64 * 1024, 128, },
494 { "m25p128", 0x202018, 256 * 1024, 64, }, 529 { "m25p128", 0x202018, 0, 256 * 1024, 64, },
495 530
496 { "m45pe80", 0x204014, 64 * 1024, 16, }, 531 { "m45pe80", 0x204014, 0, 64 * 1024, 16, },
497 { "m45pe16", 0x204015, 64 * 1024, 32, }, 532 { "m45pe16", 0x204015, 0, 64 * 1024, 32, },
498 533
499 { "m25pe80", 0x208014, 64 * 1024, 16, }, 534 { "m25pe80", 0x208014, 0, 64 * 1024, 16, },
500 { "m25pe16", 0x208015, 64 * 1024, 32, SECT_4K, }, 535 { "m25pe16", 0x208015, 0, 64 * 1024, 32, SECT_4K, },
501 536
502 /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ 537 /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
503 { "w25x10", 0xef3011, 64 * 1024, 2, SECT_4K, }, 538 { "w25x10", 0xef3011, 0, 64 * 1024, 2, SECT_4K, },
504 { "w25x20", 0xef3012, 64 * 1024, 4, SECT_4K, }, 539 { "w25x20", 0xef3012, 0, 64 * 1024, 4, SECT_4K, },
505 { "w25x40", 0xef3013, 64 * 1024, 8, SECT_4K, }, 540 { "w25x40", 0xef3013, 0, 64 * 1024, 8, SECT_4K, },
506 { "w25x80", 0xef3014, 64 * 1024, 16, SECT_4K, }, 541 { "w25x80", 0xef3014, 0, 64 * 1024, 16, SECT_4K, },
507 { "w25x16", 0xef3015, 64 * 1024, 32, SECT_4K, }, 542 { "w25x16", 0xef3015, 0, 64 * 1024, 32, SECT_4K, },
508 { "w25x32", 0xef3016, 64 * 1024, 64, SECT_4K, }, 543 { "w25x32", 0xef3016, 0, 64 * 1024, 64, SECT_4K, },
509 { "w25x64", 0xef3017, 64 * 1024, 128, SECT_4K, }, 544 { "w25x64", 0xef3017, 0, 64 * 1024, 128, SECT_4K, },
510}; 545};
511 546
512static struct flash_info *__devinit jedec_probe(struct spi_device *spi) 547static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
@@ -515,6 +550,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
515 u8 code = OPCODE_RDID; 550 u8 code = OPCODE_RDID;
516 u8 id[3]; 551 u8 id[3];
517 u32 jedec; 552 u32 jedec;
553 u16 ext_jedec;
518 struct flash_info *info; 554 struct flash_info *info;
519 555
520 /* JEDEC also defines an optional "extended device information" 556 /* JEDEC also defines an optional "extended device information"
@@ -533,10 +569,14 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
533 jedec = jedec << 8; 569 jedec = jedec << 8;
534 jedec |= id[2]; 570 jedec |= id[2];
535 571
572 ext_jedec = id[3] << 8 | id[4];
573
536 for (tmp = 0, info = m25p_data; 574 for (tmp = 0, info = m25p_data;
537 tmp < ARRAY_SIZE(m25p_data); 575 tmp < ARRAY_SIZE(m25p_data);
538 tmp++, info++) { 576 tmp++, info++) {
539 if (info->jedec_id == jedec) 577 if (info->jedec_id == jedec)
578 if (ext_jedec != 0 && info->ext_id != ext_jedec)
579 continue;
540 return info; 580 return info;
541 } 581 }
542 dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec); 582 dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index 8bd0dea6885f..6dd9aff8bb2d 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -30,12 +30,10 @@
30 * doesn't (yet) use these for any kind of i/o overlap or prefetching. 30 * doesn't (yet) use these for any kind of i/o overlap or prefetching.
31 * 31 *
32 * Sometimes DataFlash is packaged in MMC-format cards, although the 32 * Sometimes DataFlash is packaged in MMC-format cards, although the
33 * MMC stack can't use SPI (yet), or distinguish between MMC and DataFlash 33 * MMC stack can't (yet?) distinguish between MMC and DataFlash
34 * protocols during enumeration. 34 * protocols during enumeration.
35 */ 35 */
36 36
37#define CONFIG_DATAFLASH_WRITE_VERIFY
38
39/* reads can bypass the buffers */ 37/* reads can bypass the buffers */
40#define OP_READ_CONTINUOUS 0xE8 38#define OP_READ_CONTINUOUS 0xE8
41#define OP_READ_PAGE 0xD2 39#define OP_READ_PAGE 0xD2
@@ -80,7 +78,8 @@
80 */ 78 */
81#define OP_READ_ID 0x9F 79#define OP_READ_ID 0x9F
82#define OP_READ_SECURITY 0x77 80#define OP_READ_SECURITY 0x77
83#define OP_WRITE_SECURITY 0x9A /* OTP bits */ 81#define OP_WRITE_SECURITY_REVC 0x9A
82#define OP_WRITE_SECURITY 0x9B /* revision D */
84 83
85 84
86struct dataflash { 85struct dataflash {
@@ -402,7 +401,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
402 (void) dataflash_waitready(priv->spi); 401 (void) dataflash_waitready(priv->spi);
403 402
404 403
405#ifdef CONFIG_DATAFLASH_WRITE_VERIFY 404#ifdef CONFIG_MTD_DATAFLASH_VERIFY_WRITE
406 405
407 /* (3) Compare to Buffer1 */ 406 /* (3) Compare to Buffer1 */
408 addr = pageaddr << priv->page_offset; 407 addr = pageaddr << priv->page_offset;
@@ -431,7 +430,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
431 } else 430 } else
432 status = 0; 431 status = 0;
433 432
434#endif /* CONFIG_DATAFLASH_WRITE_VERIFY */ 433#endif /* CONFIG_MTD_DATAFLASH_VERIFY_WRITE */
435 434
436 remaining = remaining - writelen; 435 remaining = remaining - writelen;
437 pageaddr++; 436 pageaddr++;
@@ -451,16 +450,192 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
451 450
452/* ......................................................................... */ 451/* ......................................................................... */
453 452
453#ifdef CONFIG_MTD_DATAFLASH_OTP
454
455static int dataflash_get_otp_info(struct mtd_info *mtd,
456 struct otp_info *info, size_t len)
457{
458 /* Report both blocks as identical: bytes 0..64, locked.
459 * Unless the user block changed from all-ones, we can't
460 * tell whether it's still writable; so we assume it isn't.
461 */
462 info->start = 0;
463 info->length = 64;
464 info->locked = 1;
465 return sizeof(*info);
466}
467
468static ssize_t otp_read(struct spi_device *spi, unsigned base,
469 uint8_t *buf, loff_t off, size_t len)
470{
471 struct spi_message m;
472 size_t l;
473 uint8_t *scratch;
474 struct spi_transfer t;
475 int status;
476
477 if (off > 64)
478 return -EINVAL;
479
480 if ((off + len) > 64)
481 len = 64 - off;
482 if (len == 0)
483 return len;
484
485 spi_message_init(&m);
486
487 l = 4 + base + off + len;
488 scratch = kzalloc(l, GFP_KERNEL);
489 if (!scratch)
490 return -ENOMEM;
491
492 /* OUT: OP_READ_SECURITY, 3 don't-care bytes, zeroes
493 * IN: ignore 4 bytes, data bytes 0..N (max 127)
494 */
495 scratch[0] = OP_READ_SECURITY;
496
497 memset(&t, 0, sizeof t);
498 t.tx_buf = scratch;
499 t.rx_buf = scratch;
500 t.len = l;
501 spi_message_add_tail(&t, &m);
502
503 dataflash_waitready(spi);
504
505 status = spi_sync(spi, &m);
506 if (status >= 0) {
507 memcpy(buf, scratch + 4 + base + off, len);
508 status = len;
509 }
510
511 kfree(scratch);
512 return status;
513}
514
515static int dataflash_read_fact_otp(struct mtd_info *mtd,
516 loff_t from, size_t len, size_t *retlen, u_char *buf)
517{
518 struct dataflash *priv = (struct dataflash *)mtd->priv;
519 int status;
520
521 /* 64 bytes, from 0..63 ... start at 64 on-chip */
522 mutex_lock(&priv->lock);
523 status = otp_read(priv->spi, 64, buf, from, len);
524 mutex_unlock(&priv->lock);
525
526 if (status < 0)
527 return status;
528 *retlen = status;
529 return 0;
530}
531
532static int dataflash_read_user_otp(struct mtd_info *mtd,
533 loff_t from, size_t len, size_t *retlen, u_char *buf)
534{
535 struct dataflash *priv = (struct dataflash *)mtd->priv;
536 int status;
537
538 /* 64 bytes, from 0..63 ... start at 0 on-chip */
539 mutex_lock(&priv->lock);
540 status = otp_read(priv->spi, 0, buf, from, len);
541 mutex_unlock(&priv->lock);
542
543 if (status < 0)
544 return status;
545 *retlen = status;
546 return 0;
547}
548
549static int dataflash_write_user_otp(struct mtd_info *mtd,
550 loff_t from, size_t len, size_t *retlen, u_char *buf)
551{
552 struct spi_message m;
553 const size_t l = 4 + 64;
554 uint8_t *scratch;
555 struct spi_transfer t;
556 struct dataflash *priv = (struct dataflash *)mtd->priv;
557 int status;
558
559 if (len > 64)
560 return -EINVAL;
561
562 /* Strictly speaking, we *could* truncate the write ... but
563 * let's not do that for the only write that's ever possible.
564 */
565 if ((from + len) > 64)
566 return -EINVAL;
567
568 /* OUT: OP_WRITE_SECURITY, 3 zeroes, 64 data-or-zero bytes
569 * IN: ignore all
570 */
571 scratch = kzalloc(l, GFP_KERNEL);
572 if (!scratch)
573 return -ENOMEM;
574 scratch[0] = OP_WRITE_SECURITY;
575 memcpy(scratch + 4 + from, buf, len);
576
577 spi_message_init(&m);
578
579 memset(&t, 0, sizeof t);
580 t.tx_buf = scratch;
581 t.len = l;
582 spi_message_add_tail(&t, &m);
583
584 /* Write the OTP bits, if they've not yet been written.
585 * This modifies SRAM buffer1.
586 */
587 mutex_lock(&priv->lock);
588 dataflash_waitready(priv->spi);
589 status = spi_sync(priv->spi, &m);
590 mutex_unlock(&priv->lock);
591
592 kfree(scratch);
593
594 if (status >= 0) {
595 status = 0;
596 *retlen = len;
597 }
598 return status;
599}
600
601static char *otp_setup(struct mtd_info *device, char revision)
602{
603 device->get_fact_prot_info = dataflash_get_otp_info;
604 device->read_fact_prot_reg = dataflash_read_fact_otp;
605 device->get_user_prot_info = dataflash_get_otp_info;
606 device->read_user_prot_reg = dataflash_read_user_otp;
607
608 /* rev c parts (at45db321c and at45db1281 only!) use a
609 * different write procedure; not (yet?) implemented.
610 */
611 if (revision > 'c')
612 device->write_user_prot_reg = dataflash_write_user_otp;
613
614 return ", OTP";
615}
616
617#else
618
619static char *otp_setup(struct mtd_info *device, char revision)
620{
621 return " (OTP)";
622}
623
624#endif
625
626/* ......................................................................... */
627
454/* 628/*
455 * Register DataFlash device with MTD subsystem. 629 * Register DataFlash device with MTD subsystem.
456 */ 630 */
457static int __devinit 631static int __devinit
458add_dataflash(struct spi_device *spi, char *name, 632add_dataflash_otp(struct spi_device *spi, char *name,
459 int nr_pages, int pagesize, int pageoffset) 633 int nr_pages, int pagesize, int pageoffset, char revision)
460{ 634{
461 struct dataflash *priv; 635 struct dataflash *priv;
462 struct mtd_info *device; 636 struct mtd_info *device;
463 struct flash_platform_data *pdata = spi->dev.platform_data; 637 struct flash_platform_data *pdata = spi->dev.platform_data;
638 char *otp_tag = "";
464 639
465 priv = kzalloc(sizeof *priv, GFP_KERNEL); 640 priv = kzalloc(sizeof *priv, GFP_KERNEL);
466 if (!priv) 641 if (!priv)
@@ -489,8 +664,12 @@ add_dataflash(struct spi_device *spi, char *name,
489 device->write = dataflash_write; 664 device->write = dataflash_write;
490 device->priv = priv; 665 device->priv = priv;
491 666
492 dev_info(&spi->dev, "%s (%d KBytes) pagesize %d bytes\n", 667 if (revision >= 'c')
493 name, DIV_ROUND_UP(device->size, 1024), pagesize); 668 otp_tag = otp_setup(device, revision);
669
670 dev_info(&spi->dev, "%s (%d KBytes) pagesize %d bytes%s\n",
671 name, DIV_ROUND_UP(device->size, 1024),
672 pagesize, otp_tag);
494 dev_set_drvdata(&spi->dev, priv); 673 dev_set_drvdata(&spi->dev, priv);
495 674
496 if (mtd_has_partitions()) { 675 if (mtd_has_partitions()) {
@@ -519,6 +698,14 @@ add_dataflash(struct spi_device *spi, char *name,
519 return add_mtd_device(device) == 1 ? -ENODEV : 0; 698 return add_mtd_device(device) == 1 ? -ENODEV : 0;
520} 699}
521 700
701static inline int __devinit
702add_dataflash(struct spi_device *spi, char *name,
703 int nr_pages, int pagesize, int pageoffset)
704{
705 return add_dataflash_otp(spi, name, nr_pages, pagesize,
706 pageoffset, 0);
707}
708
522struct flash_info { 709struct flash_info {
523 char *name; 710 char *name;
524 711
@@ -664,13 +851,16 @@ static int __devinit dataflash_probe(struct spi_device *spi)
664 * Try to detect dataflash by JEDEC ID. 851 * Try to detect dataflash by JEDEC ID.
665 * If it succeeds we know we have either a C or D part. 852 * If it succeeds we know we have either a C or D part.
666 * D will support power of 2 pagesize option. 853 * D will support power of 2 pagesize option.
854 * Both support the security register, though with different
855 * write procedures.
667 */ 856 */
668 info = jedec_probe(spi); 857 info = jedec_probe(spi);
669 if (IS_ERR(info)) 858 if (IS_ERR(info))
670 return PTR_ERR(info); 859 return PTR_ERR(info);
671 if (info != NULL) 860 if (info != NULL)
672 return add_dataflash(spi, info->name, info->nr_pages, 861 return add_dataflash_otp(spi, info->name, info->nr_pages,
673 info->pagesize, info->pageoffset); 862 info->pagesize, info->pageoffset,
863 (info->flags & SUP_POW2PS) ? 'd' : 'c');
674 864
675 /* 865 /*
676 * Older chips support only legacy commands, identifing 866 * Older chips support only legacy commands, identifing
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index df8e00bba07b..3ae76ecc07d7 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -332,30 +332,6 @@ config MTD_CFI_FLAGADM
332 Mapping for the Flaga digital module. If you don't have one, ignore 332 Mapping for the Flaga digital module. If you don't have one, ignore
333 this setting. 333 this setting.
334 334
335config MTD_WALNUT
336 tristate "Flash device mapped on IBM 405GP Walnut"
337 depends on MTD_JEDECPROBE && WALNUT && !PPC_MERGE
338 help
339 This enables access routines for the flash chips on the IBM 405GP
340 Walnut board. If you have one of these boards and would like to
341 use the flash chips on it, say 'Y'.
342
343config MTD_EBONY
344 tristate "Flash devices mapped on IBM 440GP Ebony"
345 depends on MTD_JEDECPROBE && EBONY && !PPC_MERGE
346 help
347 This enables access routines for the flash chips on the IBM 440GP
348 Ebony board. If you have one of these boards and would like to
349 use the flash chips on it, say 'Y'.
350
351config MTD_OCOTEA
352 tristate "Flash devices mapped on IBM 440GX Ocotea"
353 depends on MTD_CFI && OCOTEA && !PPC_MERGE
354 help
355 This enables access routines for the flash chips on the IBM 440GX
356 Ocotea board. If you have one of these boards and would like to
357 use the flash chips on it, say 'Y'.
358
359config MTD_REDWOOD 335config MTD_REDWOOD
360 tristate "CFI Flash devices mapped on IBM Redwood" 336 tristate "CFI Flash devices mapped on IBM Redwood"
361 depends on MTD_CFI && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 ) 337 depends on MTD_CFI && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 )
@@ -458,13 +434,6 @@ config MTD_CEIVA
458 PhotoMax Digital Picture Frame. 434 PhotoMax Digital Picture Frame.
459 If you have such a device, say 'Y'. 435 If you have such a device, say 'Y'.
460 436
461config MTD_NOR_TOTO
462 tristate "NOR Flash device on TOTO board"
463 depends on ARCH_OMAP && OMAP_TOTO
464 help
465 This enables access to the NOR flash on the Texas Instruments
466 TOTO board.
467
468config MTD_H720X 437config MTD_H720X
469 tristate "Hynix evaluation board mappings" 438 tristate "Hynix evaluation board mappings"
470 depends on MTD_CFI && ( ARCH_H7201 || ARCH_H7202 ) 439 depends on MTD_CFI && ( ARCH_H7201 || ARCH_H7202 )
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 6cda6df973e5..6d9ba35caf11 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -50,12 +50,8 @@ obj-$(CONFIG_MTD_REDWOOD) += redwood.o
50obj-$(CONFIG_MTD_UCLINUX) += uclinux.o 50obj-$(CONFIG_MTD_UCLINUX) += uclinux.o
51obj-$(CONFIG_MTD_NETtel) += nettel.o 51obj-$(CONFIG_MTD_NETtel) += nettel.o
52obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o 52obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o
53obj-$(CONFIG_MTD_EBONY) += ebony.o
54obj-$(CONFIG_MTD_OCOTEA) += ocotea.o
55obj-$(CONFIG_MTD_WALNUT) += walnut.o
56obj-$(CONFIG_MTD_H720X) += h720x-flash.o 53obj-$(CONFIG_MTD_H720X) += h720x-flash.o
57obj-$(CONFIG_MTD_SBC8240) += sbc8240.o 54obj-$(CONFIG_MTD_SBC8240) += sbc8240.o
58obj-$(CONFIG_MTD_NOR_TOTO) += omap-toto-flash.o
59obj-$(CONFIG_MTD_IXP4XX) += ixp4xx.o 55obj-$(CONFIG_MTD_IXP4XX) += ixp4xx.o
60obj-$(CONFIG_MTD_IXP2000) += ixp2000.o 56obj-$(CONFIG_MTD_IXP2000) += ixp2000.o
61obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o 57obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o
diff --git a/drivers/mtd/maps/ebony.c b/drivers/mtd/maps/ebony.c
deleted file mode 100644
index d92b7c70d3ed..000000000000
--- a/drivers/mtd/maps/ebony.c
+++ /dev/null
@@ -1,163 +0,0 @@
1/*
2 * Mapping for Ebony user flash
3 *
4 * Matt Porter <mporter@kernel.crashing.org>
5 *
6 * Copyright 2002-2004 MontaVista Software Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/module.h>
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/mtd/mtd.h>
19#include <linux/mtd/map.h>
20#include <linux/mtd/partitions.h>
21#include <asm/io.h>
22#include <asm/ibm44x.h>
23#include <platforms/4xx/ebony.h>
24
25static struct mtd_info *flash;
26
27static struct map_info ebony_small_map = {
28 .name = "Ebony small flash",
29 .size = EBONY_SMALL_FLASH_SIZE,
30 .bankwidth = 1,
31};
32
33static struct map_info ebony_large_map = {
34 .name = "Ebony large flash",
35 .size = EBONY_LARGE_FLASH_SIZE,
36 .bankwidth = 1,
37};
38
39static struct mtd_partition ebony_small_partitions[] = {
40 {
41 .name = "OpenBIOS",
42 .offset = 0x0,
43 .size = 0x80000,
44 }
45};
46
47static struct mtd_partition ebony_large_partitions[] = {
48 {
49 .name = "fs",
50 .offset = 0,
51 .size = 0x380000,
52 },
53 {
54 .name = "firmware",
55 .offset = 0x380000,
56 .size = 0x80000,
57 }
58};
59
60int __init init_ebony(void)
61{
62 u8 fpga0_reg;
63 u8 __iomem *fpga0_adr;
64 unsigned long long small_flash_base, large_flash_base;
65
66 fpga0_adr = ioremap64(EBONY_FPGA_ADDR, 16);
67 if (!fpga0_adr)
68 return -ENOMEM;
69
70 fpga0_reg = readb(fpga0_adr);
71 iounmap(fpga0_adr);
72
73 if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
74 !EBONY_FLASH_SEL(fpga0_reg))
75 small_flash_base = EBONY_SMALL_FLASH_HIGH2;
76 else if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
77 EBONY_FLASH_SEL(fpga0_reg))
78 small_flash_base = EBONY_SMALL_FLASH_HIGH1;
79 else if (!EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
80 !EBONY_FLASH_SEL(fpga0_reg))
81 small_flash_base = EBONY_SMALL_FLASH_LOW2;
82 else
83 small_flash_base = EBONY_SMALL_FLASH_LOW1;
84
85 if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
86 !EBONY_ONBRD_FLASH_EN(fpga0_reg))
87 large_flash_base = EBONY_LARGE_FLASH_LOW;
88 else
89 large_flash_base = EBONY_LARGE_FLASH_HIGH;
90
91 ebony_small_map.phys = small_flash_base;
92 ebony_small_map.virt = ioremap64(small_flash_base,
93 ebony_small_map.size);
94
95 if (!ebony_small_map.virt) {
96 printk("Failed to ioremap flash\n");
97 return -EIO;
98 }
99
100 simple_map_init(&ebony_small_map);
101
102 flash = do_map_probe("jedec_probe", &ebony_small_map);
103 if (flash) {
104 flash->owner = THIS_MODULE;
105 add_mtd_partitions(flash, ebony_small_partitions,
106 ARRAY_SIZE(ebony_small_partitions));
107 } else {
108 printk("map probe failed for flash\n");
109 iounmap(ebony_small_map.virt);
110 return -ENXIO;
111 }
112
113 ebony_large_map.phys = large_flash_base;
114 ebony_large_map.virt = ioremap64(large_flash_base,
115 ebony_large_map.size);
116
117 if (!ebony_large_map.virt) {
118 printk("Failed to ioremap flash\n");
119 iounmap(ebony_small_map.virt);
120 return -EIO;
121 }
122
123 simple_map_init(&ebony_large_map);
124
125 flash = do_map_probe("jedec_probe", &ebony_large_map);
126 if (flash) {
127 flash->owner = THIS_MODULE;
128 add_mtd_partitions(flash, ebony_large_partitions,
129 ARRAY_SIZE(ebony_large_partitions));
130 } else {
131 printk("map probe failed for flash\n");
132 iounmap(ebony_small_map.virt);
133 iounmap(ebony_large_map.virt);
134 return -ENXIO;
135 }
136
137 return 0;
138}
139
140static void __exit cleanup_ebony(void)
141{
142 if (flash) {
143 del_mtd_partitions(flash);
144 map_destroy(flash);
145 }
146
147 if (ebony_small_map.virt) {
148 iounmap(ebony_small_map.virt);
149 ebony_small_map.virt = NULL;
150 }
151
152 if (ebony_large_map.virt) {
153 iounmap(ebony_large_map.virt);
154 ebony_large_map.virt = NULL;
155 }
156}
157
158module_init(init_ebony);
159module_exit(cleanup_ebony);
160
161MODULE_LICENSE("GPL");
162MODULE_AUTHOR("Matt Porter <mporter@kernel.crashing.org>");
163MODULE_DESCRIPTION("MTD map and partitions for IBM 440GP Ebony boards");
diff --git a/drivers/mtd/maps/ocotea.c b/drivers/mtd/maps/ocotea.c
deleted file mode 100644
index 5522eac8c980..000000000000
--- a/drivers/mtd/maps/ocotea.c
+++ /dev/null
@@ -1,154 +0,0 @@
1/*
2 * Mapping for Ocotea user flash
3 *
4 * Matt Porter <mporter@kernel.crashing.org>
5 *
6 * Copyright 2002-2004 MontaVista Software Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/module.h>
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/mtd/mtd.h>
19#include <linux/mtd/map.h>
20#include <linux/mtd/partitions.h>
21#include <asm/io.h>
22#include <asm/ibm44x.h>
23#include <platforms/4xx/ocotea.h>
24
25static struct mtd_info *flash;
26
27static struct map_info ocotea_small_map = {
28 .name = "Ocotea small flash",
29 .size = OCOTEA_SMALL_FLASH_SIZE,
30 .buswidth = 1,
31};
32
33static struct map_info ocotea_large_map = {
34 .name = "Ocotea large flash",
35 .size = OCOTEA_LARGE_FLASH_SIZE,
36 .buswidth = 1,
37};
38
39static struct mtd_partition ocotea_small_partitions[] = {
40 {
41 .name = "pibs",
42 .offset = 0x0,
43 .size = 0x100000,
44 }
45};
46
47static struct mtd_partition ocotea_large_partitions[] = {
48 {
49 .name = "fs",
50 .offset = 0,
51 .size = 0x300000,
52 },
53 {
54 .name = "firmware",
55 .offset = 0x300000,
56 .size = 0x100000,
57 }
58};
59
60int __init init_ocotea(void)
61{
62 u8 fpga0_reg;
63 u8 *fpga0_adr;
64 unsigned long long small_flash_base, large_flash_base;
65
66 fpga0_adr = ioremap64(OCOTEA_FPGA_ADDR, 16);
67 if (!fpga0_adr)
68 return -ENOMEM;
69
70 fpga0_reg = readb((unsigned long)fpga0_adr);
71 iounmap(fpga0_adr);
72
73 if (OCOTEA_BOOT_LARGE_FLASH(fpga0_reg)) {
74 small_flash_base = OCOTEA_SMALL_FLASH_HIGH;
75 large_flash_base = OCOTEA_LARGE_FLASH_LOW;
76 }
77 else {
78 small_flash_base = OCOTEA_SMALL_FLASH_LOW;
79 large_flash_base = OCOTEA_LARGE_FLASH_HIGH;
80 }
81
82 ocotea_small_map.phys = small_flash_base;
83 ocotea_small_map.virt = ioremap64(small_flash_base,
84 ocotea_small_map.size);
85
86 if (!ocotea_small_map.virt) {
87 printk("Failed to ioremap flash\n");
88 return -EIO;
89 }
90
91 simple_map_init(&ocotea_small_map);
92
93 flash = do_map_probe("map_rom", &ocotea_small_map);
94 if (flash) {
95 flash->owner = THIS_MODULE;
96 add_mtd_partitions(flash, ocotea_small_partitions,
97 ARRAY_SIZE(ocotea_small_partitions));
98 } else {
99 printk("map probe failed for flash\n");
100 iounmap(ocotea_small_map.virt);
101 return -ENXIO;
102 }
103
104 ocotea_large_map.phys = large_flash_base;
105 ocotea_large_map.virt = ioremap64(large_flash_base,
106 ocotea_large_map.size);
107
108 if (!ocotea_large_map.virt) {
109 printk("Failed to ioremap flash\n");
110 iounmap(ocotea_small_map.virt);
111 return -EIO;
112 }
113
114 simple_map_init(&ocotea_large_map);
115
116 flash = do_map_probe("cfi_probe", &ocotea_large_map);
117 if (flash) {
118 flash->owner = THIS_MODULE;
119 add_mtd_partitions(flash, ocotea_large_partitions,
120 ARRAY_SIZE(ocotea_large_partitions));
121 } else {
122 printk("map probe failed for flash\n");
123 iounmap(ocotea_small_map.virt);
124 iounmap(ocotea_large_map.virt);
125 return -ENXIO;
126 }
127
128 return 0;
129}
130
131static void __exit cleanup_ocotea(void)
132{
133 if (flash) {
134 del_mtd_partitions(flash);
135 map_destroy(flash);
136 }
137
138 if (ocotea_small_map.virt) {
139 iounmap((void *)ocotea_small_map.virt);
140 ocotea_small_map.virt = 0;
141 }
142
143 if (ocotea_large_map.virt) {
144 iounmap((void *)ocotea_large_map.virt);
145 ocotea_large_map.virt = 0;
146 }
147}
148
149module_init(init_ocotea);
150module_exit(cleanup_ocotea);
151
152MODULE_LICENSE("GPL");
153MODULE_AUTHOR("Matt Porter <mporter@kernel.crashing.org>");
154MODULE_DESCRIPTION("MTD map and partitions for IBM 440GX Ocotea boards");
diff --git a/drivers/mtd/maps/omap-toto-flash.c b/drivers/mtd/maps/omap-toto-flash.c
deleted file mode 100644
index 0a60ebbc2175..000000000000
--- a/drivers/mtd/maps/omap-toto-flash.c
+++ /dev/null
@@ -1,133 +0,0 @@
1/*
2 * NOR Flash memory access on TI Toto board
3 *
4 * jzhang@ti.com (C) 2003 Texas Instruments.
5 *
6 * (C) 2002 MontVista Software, Inc.
7 */
8
9#include <linux/module.h>
10#include <linux/types.h>
11#include <linux/kernel.h>
12#include <linux/errno.h>
13#include <linux/init.h>
14#include <linux/slab.h>
15
16#include <linux/mtd/mtd.h>
17#include <linux/mtd/map.h>
18#include <linux/mtd/partitions.h>
19
20#include <asm/hardware.h>
21#include <asm/io.h>
22
23
24#ifndef CONFIG_ARCH_OMAP
25#error This is for OMAP architecture only
26#endif
27
28//these lines need be moved to a hardware header file
29#define OMAP_TOTO_FLASH_BASE 0xd8000000
30#define OMAP_TOTO_FLASH_SIZE 0x80000
31
32static struct map_info omap_toto_map_flash = {
33 .name = "OMAP Toto flash",
34 .bankwidth = 2,
35 .virt = (void __iomem *)OMAP_TOTO_FLASH_BASE,
36};
37
38
39static struct mtd_partition toto_flash_partitions[] = {
40 {
41 .name = "BootLoader",
42 .size = 0x00040000, /* hopefully u-boot will stay 128k + 128*/
43 .offset = 0,
44 .mask_flags = MTD_WRITEABLE, /* force read-only */
45 }, {
46 .name = "ReservedSpace",
47 .size = 0x00030000,
48 .offset = MTDPART_OFS_APPEND,
49 //mask_flags: MTD_WRITEABLE, /* force read-only */
50 }, {
51 .name = "EnvArea", /* bottom 64KiB for env vars */
52 .size = MTDPART_SIZ_FULL,
53 .offset = MTDPART_OFS_APPEND,
54 }
55};
56
57static struct mtd_partition *parsed_parts;
58
59static struct mtd_info *flash_mtd;
60
61static int __init init_flash (void)
62{
63
64 struct mtd_partition *parts;
65 int nb_parts = 0;
66 int parsed_nr_parts = 0;
67 const char *part_type;
68
69 /*
70 * Static partition definition selection
71 */
72 part_type = "static";
73
74 parts = toto_flash_partitions;
75 nb_parts = ARRAY_SIZE(toto_flash_partitions);
76 omap_toto_map_flash.size = OMAP_TOTO_FLASH_SIZE;
77 omap_toto_map_flash.phys = virt_to_phys(OMAP_TOTO_FLASH_BASE);
78
79 simple_map_init(&omap_toto_map_flash);
80 /*
81 * Now let's probe for the actual flash. Do it here since
82 * specific machine settings might have been set above.
83 */
84 printk(KERN_NOTICE "OMAP toto flash: probing %d-bit flash bus\n",
85 omap_toto_map_flash.bankwidth*8);
86 flash_mtd = do_map_probe("jedec_probe", &omap_toto_map_flash);
87 if (!flash_mtd)
88 return -ENXIO;
89
90 if (parsed_nr_parts > 0) {
91 parts = parsed_parts;
92 nb_parts = parsed_nr_parts;
93 }
94
95 if (nb_parts == 0) {
96 printk(KERN_NOTICE "OMAP toto flash: no partition info available,"
97 "registering whole flash at once\n");
98 if (add_mtd_device(flash_mtd)){
99 return -ENXIO;
100 }
101 } else {
102 printk(KERN_NOTICE "Using %s partition definition\n",
103 part_type);
104 return add_mtd_partitions(flash_mtd, parts, nb_parts);
105 }
106 return 0;
107}
108
109int __init omap_toto_mtd_init(void)
110{
111 int status;
112
113 if (status = init_flash()) {
114 printk(KERN_ERR "OMAP Toto Flash: unable to init map for toto flash\n");
115 }
116 return status;
117}
118
119static void __exit omap_toto_mtd_cleanup(void)
120{
121 if (flash_mtd) {
122 del_mtd_partitions(flash_mtd);
123 map_destroy(flash_mtd);
124 kfree(parsed_parts);
125 }
126}
127
128module_init(omap_toto_mtd_init);
129module_exit(omap_toto_mtd_cleanup);
130
131MODULE_AUTHOR("Jian Zhang");
132MODULE_DESCRIPTION("OMAP Toto board map driver");
133MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/walnut.c b/drivers/mtd/maps/walnut.c
deleted file mode 100644
index e243476c8171..000000000000
--- a/drivers/mtd/maps/walnut.c
+++ /dev/null
@@ -1,122 +0,0 @@
1/*
2 * Mapping for Walnut flash
3 * (used ebony.c as a "framework")
4 *
5 * Heikki Lindholm <holindho@infradead.org>
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/module.h>
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/mtd/mtd.h>
19#include <linux/mtd/map.h>
20#include <linux/mtd/partitions.h>
21#include <asm/io.h>
22#include <asm/ibm4xx.h>
23#include <platforms/4xx/walnut.h>
24
25/* these should be in platforms/4xx/walnut.h ? */
26#define WALNUT_FLASH_ONBD_N(x) (x & 0x02)
27#define WALNUT_FLASH_SRAM_SEL(x) (x & 0x01)
28#define WALNUT_FLASH_LOW 0xFFF00000
29#define WALNUT_FLASH_HIGH 0xFFF80000
30#define WALNUT_FLASH_SIZE 0x80000
31
32static struct mtd_info *flash;
33
34static struct map_info walnut_map = {
35 .name = "Walnut flash",
36 .size = WALNUT_FLASH_SIZE,
37 .bankwidth = 1,
38};
39
40/* Actually, OpenBIOS is the last 128 KiB of the flash - better
41 * partitioning could be made */
42static struct mtd_partition walnut_partitions[] = {
43 {
44 .name = "OpenBIOS",
45 .offset = 0x0,
46 .size = WALNUT_FLASH_SIZE,
47 /*.mask_flags = MTD_WRITEABLE, */ /* force read-only */
48 }
49};
50
51int __init init_walnut(void)
52{
53 u8 fpga_brds1;
54 void *fpga_brds1_adr;
55 void *fpga_status_adr;
56 unsigned long flash_base;
57
58 /* this should already be mapped (platform/4xx/walnut.c) */
59 fpga_status_adr = ioremap(WALNUT_FPGA_BASE, 8);
60 if (!fpga_status_adr)
61 return -ENOMEM;
62
63 fpga_brds1_adr = fpga_status_adr+5;
64 fpga_brds1 = readb(fpga_brds1_adr);
65 /* iounmap(fpga_status_adr); */
66
67 if (WALNUT_FLASH_ONBD_N(fpga_brds1)) {
68 printk("The on-board flash is disabled (U79 sw 5)!");
69 iounmap(fpga_status_adr);
70 return -EIO;
71 }
72 if (WALNUT_FLASH_SRAM_SEL(fpga_brds1))
73 flash_base = WALNUT_FLASH_LOW;
74 else
75 flash_base = WALNUT_FLASH_HIGH;
76
77 walnut_map.phys = flash_base;
78 walnut_map.virt =
79 (void __iomem *)ioremap(flash_base, walnut_map.size);
80
81 if (!walnut_map.virt) {
82 printk("Failed to ioremap flash.\n");
83 iounmap(fpga_status_adr);
84 return -EIO;
85 }
86
87 simple_map_init(&walnut_map);
88
89 flash = do_map_probe("jedec_probe", &walnut_map);
90 if (flash) {
91 flash->owner = THIS_MODULE;
92 add_mtd_partitions(flash, walnut_partitions,
93 ARRAY_SIZE(walnut_partitions));
94 } else {
95 printk("map probe failed for flash\n");
96 iounmap(fpga_status_adr);
97 return -ENXIO;
98 }
99
100 iounmap(fpga_status_adr);
101 return 0;
102}
103
104static void __exit cleanup_walnut(void)
105{
106 if (flash) {
107 del_mtd_partitions(flash);
108 map_destroy(flash);
109 }
110
111 if (walnut_map.virt) {
112 iounmap((void *)walnut_map.virt);
113 walnut_map.virt = 0;
114 }
115}
116
117module_init(init_walnut);
118module_exit(cleanup_walnut);
119
120MODULE_LICENSE("GPL");
121MODULE_AUTHOR("Heikki Lindholm <holindho@infradead.org>");
122MODULE_DESCRIPTION("MTD map and partitions for IBM 405GP Walnut boards");
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index d2f331876e4c..13cc67ad272a 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -350,7 +350,7 @@ static void mtdchar_erase_callback (struct erase_info *instr)
350 wake_up((wait_queue_head_t *)instr->priv); 350 wake_up((wait_queue_head_t *)instr->priv);
351} 351}
352 352
353#if defined(CONFIG_MTD_OTP) || defined(CONFIG_MTD_ONENAND_OTP) 353#ifdef CONFIG_HAVE_MTD_OTP
354static int otp_select_filemode(struct mtd_file_info *mfi, int mode) 354static int otp_select_filemode(struct mtd_file_info *mfi, int mode)
355{ 355{
356 struct mtd_info *mtd = mfi->mtd; 356 struct mtd_info *mtd = mfi->mtd;
@@ -663,7 +663,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
663 break; 663 break;
664 } 664 }
665 665
666#if defined(CONFIG_MTD_OTP) || defined(CONFIG_MTD_ONENAND_OTP) 666#ifdef CONFIG_HAVE_MTD_OTP
667 case OTPSELECT: 667 case OTPSELECT:
668 { 668 {
669 int mode; 669 int mode;
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 2972a5edb73d..789842d0e6f2 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -444,7 +444,7 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
444 return -EINVAL; 444 return -EINVAL;
445 } 445 }
446 446
447 instr->fail_addr = 0xffffffff; 447 instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
448 448
449 /* make a local copy of instr to avoid modifying the caller's struct */ 449 /* make a local copy of instr to avoid modifying the caller's struct */
450 erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL); 450 erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL);
@@ -493,7 +493,7 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
493 /* sanity check: should never happen since 493 /* sanity check: should never happen since
494 * block alignment has been checked above */ 494 * block alignment has been checked above */
495 BUG_ON(err == -EINVAL); 495 BUG_ON(err == -EINVAL);
496 if (erase->fail_addr != 0xffffffff) 496 if (erase->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
497 instr->fail_addr = erase->fail_addr + offset; 497 instr->fail_addr = erase->fail_addr + offset;
498 break; 498 break;
499 } 499 }
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index edb90b58a9b1..8e77e36e75ee 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -214,7 +214,7 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
214 instr->addr += part->offset; 214 instr->addr += part->offset;
215 ret = part->master->erase(part->master, instr); 215 ret = part->master->erase(part->master, instr);
216 if (ret) { 216 if (ret) {
217 if (instr->fail_addr != 0xffffffff) 217 if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
218 instr->fail_addr -= part->offset; 218 instr->fail_addr -= part->offset;
219 instr->addr -= part->offset; 219 instr->addr -= part->offset;
220 } 220 }
@@ -226,7 +226,7 @@ void mtd_erase_callback(struct erase_info *instr)
226 if (instr->mtd->erase == part_erase) { 226 if (instr->mtd->erase == part_erase) {
227 struct mtd_part *part = PART(instr->mtd); 227 struct mtd_part *part = PART(instr->mtd);
228 228
229 if (instr->fail_addr != 0xffffffff) 229 if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
230 instr->fail_addr -= part->offset; 230 instr->fail_addr -= part->offset;
231 instr->addr -= part->offset; 231 instr->addr -= part->offset;
232 } 232 }
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 41f361c49b32..8eb2b06cf0d9 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -68,12 +68,6 @@ config MTD_NAND_AMS_DELTA
68 help 68 help
69 Support for NAND flash on Amstrad E3 (Delta). 69 Support for NAND flash on Amstrad E3 (Delta).
70 70
71config MTD_NAND_TOTO
72 tristate "NAND Flash device on TOTO board"
73 depends on ARCH_OMAP && BROKEN
74 help
75 Support for NAND flash on Texas Instruments Toto platform.
76
77config MTD_NAND_TS7250 71config MTD_NAND_TS7250
78 tristate "NAND Flash device on TS-7250 board" 72 tristate "NAND Flash device on TS-7250 board"
79 depends on MACH_TS72XX 73 depends on MACH_TS72XX
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index b786c5da82da..8540c46ffba9 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o
8obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o 8obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o
9obj-$(CONFIG_MTD_NAND_SPIA) += spia.o 9obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
10obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o 10obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o
11obj-$(CONFIG_MTD_NAND_TOTO) += toto.o
12obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o 11obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
13obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o 12obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o
14obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o 13obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index d1129bae6c27..d303db39c48d 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -801,9 +801,9 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
801 * nand_read_subpage - [REPLACABLE] software ecc based sub-page read function 801 * nand_read_subpage - [REPLACABLE] software ecc based sub-page read function
802 * @mtd: mtd info structure 802 * @mtd: mtd info structure
803 * @chip: nand chip info structure 803 * @chip: nand chip info structure
804 * @dataofs offset of requested data within the page 804 * @data_offs: offset of requested data within the page
805 * @readlen data length 805 * @readlen: data length
806 * @buf: buffer to store read data 806 * @bufpoi: buffer to store read data
807 */ 807 */
808static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi) 808static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi)
809{ 809{
@@ -2042,7 +2042,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
2042 return -EINVAL; 2042 return -EINVAL;
2043 } 2043 }
2044 2044
2045 instr->fail_addr = 0xffffffff; 2045 instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
2046 2046
2047 /* Grab the lock and see if the device is available */ 2047 /* Grab the lock and see if the device is available */
2048 nand_get_device(chip, mtd, FL_ERASING); 2048 nand_get_device(chip, mtd, FL_ERASING);
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index 918a806a8471..868147acce2c 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -1,13 +1,18 @@
1/* 1/*
2 * This file contains an ECC algorithm from Toshiba that detects and 2 * This file contains an ECC algorithm that detects and corrects 1 bit
3 * corrects 1 bit errors in a 256 byte block of data. 3 * errors in a 256 byte block of data.
4 * 4 *
5 * drivers/mtd/nand/nand_ecc.c 5 * drivers/mtd/nand/nand_ecc.c
6 * 6 *
7 * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) 7 * Copyright © 2008 Koninklijke Philips Electronics NV.
8 * Toshiba America Electronics Components, Inc. 8 * Author: Frans Meulenbroeks
9 * 9 *
10 * Copyright (C) 2006 Thomas Gleixner <tglx@linutronix.de> 10 * Completely replaces the previous ECC implementation which was written by:
11 * Steven J. Hill (sjhill@realitydiluted.com)
12 * Thomas Gleixner (tglx@linutronix.de)
13 *
14 * Information on how this algorithm works and how it was developed
15 * can be found in Documentation/mtd/nand_ecc.txt
11 * 16 *
12 * This file is free software; you can redistribute it and/or modify it 17 * 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 18 * under the terms of the GNU General Public License as published by the
@@ -23,174 +28,475 @@
23 * with this file; if not, write to the Free Software Foundation, Inc., 28 * with this file; if not, write to the Free Software Foundation, Inc.,
24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 * 30 *
26 * As a special exception, if other files instantiate templates or use
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
29 * files, these files do not by themselves cause the resulting work to be
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)
32 * of the GNU General Public License.
33 *
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.
36 */ 31 */
37 32
33/*
34 * The STANDALONE macro is useful when running the code outside the kernel
35 * e.g. when running the code in a testbed or a benchmark program.
36 * When STANDALONE is used, the module related macros are commented out
37 * as well as the linux include files.
38 * Instead a private definition of mtd_info is given to satisfy the compiler
39 * (the code does not use mtd_info, so the code does not care)
40 */
41#ifndef STANDALONE
38#include <linux/types.h> 42#include <linux/types.h>
39#include <linux/kernel.h> 43#include <linux/kernel.h>
40#include <linux/module.h> 44#include <linux/module.h>
45#include <linux/mtd/mtd.h>
46#include <linux/mtd/nand.h>
41#include <linux/mtd/nand_ecc.h> 47#include <linux/mtd/nand_ecc.h>
48#include <asm/byteorder.h>
49#else
50#include <stdint.h>
51struct mtd_info;
52#define EXPORT_SYMBOL(x) /* x */
53
54#define MODULE_LICENSE(x) /* x */
55#define MODULE_AUTHOR(x) /* x */
56#define MODULE_DESCRIPTION(x) /* x */
57
58#define printk printf
59#define KERN_ERR ""
60#endif
61
62/*
63 * invparity is a 256 byte table that contains the odd parity
64 * for each byte. So if the number of bits in a byte is even,
65 * the array element is 1, and when the number of bits is odd
66 * the array eleemnt is 0.
67 */
68static const char invparity[256] = {
69 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
70 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
71 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
72 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
73 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
74 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
75 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
76 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
77 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
78 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
79 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
80 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
81 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
82 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
83 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
84 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
85};
86
87/*
88 * bitsperbyte contains the number of bits per byte
89 * this is only used for testing and repairing parity
90 * (a precalculated value slightly improves performance)
91 */
92static const char bitsperbyte[256] = {
93 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
94 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
95 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
96 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
97 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
98 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
99 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
100 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
101 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
102 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
103 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
104 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
105 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
106 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
107 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
108 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
109};
42 110
43/* 111/*
44 * Pre-calculated 256-way 1 byte column parity 112 * addressbits is a lookup table to filter out the bits from the xor-ed
113 * ecc data that identify the faulty location.
114 * this is only used for repairing parity
115 * see the comments in nand_correct_data for more details
45 */ 116 */
46static const u_char nand_ecc_precalc_table[] = { 117static const char addressbits[256] = {
47 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00, 118 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
48 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, 119 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
49 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, 120 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
50 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, 121 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
51 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, 122 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
52 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, 123 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
53 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, 124 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
54 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, 125 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
55 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, 126 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
56 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, 127 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
57 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, 128 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
58 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, 129 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
59 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, 130 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
60 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, 131 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
61 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, 132 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
62 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00 133 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
134 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
135 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
136 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
137 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
138 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
139 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
140 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
141 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
142 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
143 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
144 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
145 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
146 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
147 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
148 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
149 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f
63}; 150};
64 151
65/** 152/**
66 * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256-byte block 153 * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256/512-byte
154 * block
67 * @mtd: MTD block structure 155 * @mtd: MTD block structure
68 * @dat: raw data 156 * @buf: input buffer with raw data
69 * @ecc_code: buffer for ECC 157 * @code: output buffer with ECC
70 */ 158 */
71int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, 159int nand_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf,
72 u_char *ecc_code) 160 unsigned char *code)
73{ 161{
74 uint8_t idx, reg1, reg2, reg3, tmp1, tmp2;
75 int i; 162 int i;
163 const uint32_t *bp = (uint32_t *)buf;
164 /* 256 or 512 bytes/ecc */
165 const uint32_t eccsize_mult =
166 (((struct nand_chip *)mtd->priv)->ecc.size) >> 8;
167 uint32_t cur; /* current value in buffer */
168 /* rp0..rp15..rp17 are the various accumulated parities (per byte) */
169 uint32_t rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7;
170 uint32_t rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15, rp16;
171 uint32_t uninitialized_var(rp17); /* to make compiler happy */
172 uint32_t par; /* the cumulative parity for all data */
173 uint32_t tmppar; /* the cumulative parity for this iteration;
174 for rp12, rp14 and rp16 at the end of the
175 loop */
176
177 par = 0;
178 rp4 = 0;
179 rp6 = 0;
180 rp8 = 0;
181 rp10 = 0;
182 rp12 = 0;
183 rp14 = 0;
184 rp16 = 0;
185
186 /*
187 * The loop is unrolled a number of times;
188 * This avoids if statements to decide on which rp value to update
189 * Also we process the data by longwords.
190 * Note: passing unaligned data might give a performance penalty.
191 * It is assumed that the buffers are aligned.
192 * tmppar is the cumulative sum of this iteration.
193 * needed for calculating rp12, rp14, rp16 and par
194 * also used as a performance improvement for rp6, rp8 and rp10
195 */
196 for (i = 0; i < eccsize_mult << 2; i++) {
197 cur = *bp++;
198 tmppar = cur;
199 rp4 ^= cur;
200 cur = *bp++;
201 tmppar ^= cur;
202 rp6 ^= tmppar;
203 cur = *bp++;
204 tmppar ^= cur;
205 rp4 ^= cur;
206 cur = *bp++;
207 tmppar ^= cur;
208 rp8 ^= tmppar;
76 209
77 /* Initialize variables */ 210 cur = *bp++;
78 reg1 = reg2 = reg3 = 0; 211 tmppar ^= cur;
212 rp4 ^= cur;
213 rp6 ^= cur;
214 cur = *bp++;
215 tmppar ^= cur;
216 rp6 ^= cur;
217 cur = *bp++;
218 tmppar ^= cur;
219 rp4 ^= cur;
220 cur = *bp++;
221 tmppar ^= cur;
222 rp10 ^= tmppar;
79 223
80 /* Build up column parity */ 224 cur = *bp++;
81 for(i = 0; i < 256; i++) { 225 tmppar ^= cur;
82 /* Get CP0 - CP5 from table */ 226 rp4 ^= cur;
83 idx = nand_ecc_precalc_table[*dat++]; 227 rp6 ^= cur;
84 reg1 ^= (idx & 0x3f); 228 rp8 ^= cur;
229 cur = *bp++;
230 tmppar ^= cur;
231 rp6 ^= cur;
232 rp8 ^= cur;
233 cur = *bp++;
234 tmppar ^= cur;
235 rp4 ^= cur;
236 rp8 ^= cur;
237 cur = *bp++;
238 tmppar ^= cur;
239 rp8 ^= cur;
85 240
86 /* All bit XOR = 1 ? */ 241 cur = *bp++;
87 if (idx & 0x40) { 242 tmppar ^= cur;
88 reg3 ^= (uint8_t) i; 243 rp4 ^= cur;
89 reg2 ^= ~((uint8_t) i); 244 rp6 ^= cur;
90 } 245 cur = *bp++;
246 tmppar ^= cur;
247 rp6 ^= cur;
248 cur = *bp++;
249 tmppar ^= cur;
250 rp4 ^= cur;
251 cur = *bp++;
252 tmppar ^= cur;
253
254 par ^= tmppar;
255 if ((i & 0x1) == 0)
256 rp12 ^= tmppar;
257 if ((i & 0x2) == 0)
258 rp14 ^= tmppar;
259 if (eccsize_mult == 2 && (i & 0x4) == 0)
260 rp16 ^= tmppar;
91 } 261 }
92 262
93 /* Create non-inverted ECC code from line parity */ 263 /*
94 tmp1 = (reg3 & 0x80) >> 0; /* B7 -> B7 */ 264 * handle the fact that we use longword operations
95 tmp1 |= (reg2 & 0x80) >> 1; /* B7 -> B6 */ 265 * we'll bring rp4..rp14..rp16 back to single byte entities by
96 tmp1 |= (reg3 & 0x40) >> 1; /* B6 -> B5 */ 266 * shifting and xoring first fold the upper and lower 16 bits,
97 tmp1 |= (reg2 & 0x40) >> 2; /* B6 -> B4 */ 267 * then the upper and lower 8 bits.
98 tmp1 |= (reg3 & 0x20) >> 2; /* B5 -> B3 */ 268 */
99 tmp1 |= (reg2 & 0x20) >> 3; /* B5 -> B2 */ 269 rp4 ^= (rp4 >> 16);
100 tmp1 |= (reg3 & 0x10) >> 3; /* B4 -> B1 */ 270 rp4 ^= (rp4 >> 8);
101 tmp1 |= (reg2 & 0x10) >> 4; /* B4 -> B0 */ 271 rp4 &= 0xff;
102 272 rp6 ^= (rp6 >> 16);
103 tmp2 = (reg3 & 0x08) << 4; /* B3 -> B7 */ 273 rp6 ^= (rp6 >> 8);
104 tmp2 |= (reg2 & 0x08) << 3; /* B3 -> B6 */ 274 rp6 &= 0xff;
105 tmp2 |= (reg3 & 0x04) << 3; /* B2 -> B5 */ 275 rp8 ^= (rp8 >> 16);
106 tmp2 |= (reg2 & 0x04) << 2; /* B2 -> B4 */ 276 rp8 ^= (rp8 >> 8);
107 tmp2 |= (reg3 & 0x02) << 2; /* B1 -> B3 */ 277 rp8 &= 0xff;
108 tmp2 |= (reg2 & 0x02) << 1; /* B1 -> B2 */ 278 rp10 ^= (rp10 >> 16);
109 tmp2 |= (reg3 & 0x01) << 1; /* B0 -> B1 */ 279 rp10 ^= (rp10 >> 8);
110 tmp2 |= (reg2 & 0x01) << 0; /* B7 -> B0 */ 280 rp10 &= 0xff;
111 281 rp12 ^= (rp12 >> 16);
112 /* Calculate final ECC code */ 282 rp12 ^= (rp12 >> 8);
113#ifdef CONFIG_MTD_NAND_ECC_SMC 283 rp12 &= 0xff;
114 ecc_code[0] = ~tmp2; 284 rp14 ^= (rp14 >> 16);
115 ecc_code[1] = ~tmp1; 285 rp14 ^= (rp14 >> 8);
286 rp14 &= 0xff;
287 if (eccsize_mult == 2) {
288 rp16 ^= (rp16 >> 16);
289 rp16 ^= (rp16 >> 8);
290 rp16 &= 0xff;
291 }
292
293 /*
294 * we also need to calculate the row parity for rp0..rp3
295 * This is present in par, because par is now
296 * rp3 rp3 rp2 rp2 in little endian and
297 * rp2 rp2 rp3 rp3 in big endian
298 * as well as
299 * rp1 rp0 rp1 rp0 in little endian and
300 * rp0 rp1 rp0 rp1 in big endian
301 * First calculate rp2 and rp3
302 */
303#ifdef __BIG_ENDIAN
304 rp2 = (par >> 16);
305 rp2 ^= (rp2 >> 8);
306 rp2 &= 0xff;
307 rp3 = par & 0xffff;
308 rp3 ^= (rp3 >> 8);
309 rp3 &= 0xff;
116#else 310#else
117 ecc_code[0] = ~tmp1; 311 rp3 = (par >> 16);
118 ecc_code[1] = ~tmp2; 312 rp3 ^= (rp3 >> 8);
313 rp3 &= 0xff;
314 rp2 = par & 0xffff;
315 rp2 ^= (rp2 >> 8);
316 rp2 &= 0xff;
119#endif 317#endif
120 ecc_code[2] = ((~reg1) << 2) | 0x03;
121 318
122 return 0; 319 /* reduce par to 16 bits then calculate rp1 and rp0 */
123} 320 par ^= (par >> 16);
124EXPORT_SYMBOL(nand_calculate_ecc); 321#ifdef __BIG_ENDIAN
322 rp0 = (par >> 8) & 0xff;
323 rp1 = (par & 0xff);
324#else
325 rp1 = (par >> 8) & 0xff;
326 rp0 = (par & 0xff);
327#endif
125 328
126static inline int countbits(uint32_t byte) 329 /* finally reduce par to 8 bits */
127{ 330 par ^= (par >> 8);
128 int res = 0; 331 par &= 0xff;
129 332
130 for (;byte; byte >>= 1) 333 /*
131 res += byte & 0x01; 334 * and calculate rp5..rp15..rp17
132 return res; 335 * note that par = rp4 ^ rp5 and due to the commutative property
336 * of the ^ operator we can say:
337 * rp5 = (par ^ rp4);
338 * The & 0xff seems superfluous, but benchmarking learned that
339 * leaving it out gives slightly worse results. No idea why, probably
340 * it has to do with the way the pipeline in pentium is organized.
341 */
342 rp5 = (par ^ rp4) & 0xff;
343 rp7 = (par ^ rp6) & 0xff;
344 rp9 = (par ^ rp8) & 0xff;
345 rp11 = (par ^ rp10) & 0xff;
346 rp13 = (par ^ rp12) & 0xff;
347 rp15 = (par ^ rp14) & 0xff;
348 if (eccsize_mult == 2)
349 rp17 = (par ^ rp16) & 0xff;
350
351 /*
352 * Finally calculate the ecc bits.
353 * Again here it might seem that there are performance optimisations
354 * possible, but benchmarks showed that on the system this is developed
355 * the code below is the fastest
356 */
357#ifdef CONFIG_MTD_NAND_ECC_SMC
358 code[0] =
359 (invparity[rp7] << 7) |
360 (invparity[rp6] << 6) |
361 (invparity[rp5] << 5) |
362 (invparity[rp4] << 4) |
363 (invparity[rp3] << 3) |
364 (invparity[rp2] << 2) |
365 (invparity[rp1] << 1) |
366 (invparity[rp0]);
367 code[1] =
368 (invparity[rp15] << 7) |
369 (invparity[rp14] << 6) |
370 (invparity[rp13] << 5) |
371 (invparity[rp12] << 4) |
372 (invparity[rp11] << 3) |
373 (invparity[rp10] << 2) |
374 (invparity[rp9] << 1) |
375 (invparity[rp8]);
376#else
377 code[1] =
378 (invparity[rp7] << 7) |
379 (invparity[rp6] << 6) |
380 (invparity[rp5] << 5) |
381 (invparity[rp4] << 4) |
382 (invparity[rp3] << 3) |
383 (invparity[rp2] << 2) |
384 (invparity[rp1] << 1) |
385 (invparity[rp0]);
386 code[0] =
387 (invparity[rp15] << 7) |
388 (invparity[rp14] << 6) |
389 (invparity[rp13] << 5) |
390 (invparity[rp12] << 4) |
391 (invparity[rp11] << 3) |
392 (invparity[rp10] << 2) |
393 (invparity[rp9] << 1) |
394 (invparity[rp8]);
395#endif
396 if (eccsize_mult == 1)
397 code[2] =
398 (invparity[par & 0xf0] << 7) |
399 (invparity[par & 0x0f] << 6) |
400 (invparity[par & 0xcc] << 5) |
401 (invparity[par & 0x33] << 4) |
402 (invparity[par & 0xaa] << 3) |
403 (invparity[par & 0x55] << 2) |
404 3;
405 else
406 code[2] =
407 (invparity[par & 0xf0] << 7) |
408 (invparity[par & 0x0f] << 6) |
409 (invparity[par & 0xcc] << 5) |
410 (invparity[par & 0x33] << 4) |
411 (invparity[par & 0xaa] << 3) |
412 (invparity[par & 0x55] << 2) |
413 (invparity[rp17] << 1) |
414 (invparity[rp16] << 0);
415 return 0;
133} 416}
417EXPORT_SYMBOL(nand_calculate_ecc);
134 418
135/** 419/**
136 * nand_correct_data - [NAND Interface] Detect and correct bit error(s) 420 * nand_correct_data - [NAND Interface] Detect and correct bit error(s)
137 * @mtd: MTD block structure 421 * @mtd: MTD block structure
138 * @dat: raw data read from the chip 422 * @buf: raw data read from the chip
139 * @read_ecc: ECC from the chip 423 * @read_ecc: ECC from the chip
140 * @calc_ecc: the ECC calculated from raw data 424 * @calc_ecc: the ECC calculated from raw data
141 * 425 *
142 * Detect and correct a 1 bit error for 256 byte block 426 * Detect and correct a 1 bit error for 256/512 byte block
143 */ 427 */
144int nand_correct_data(struct mtd_info *mtd, u_char *dat, 428int nand_correct_data(struct mtd_info *mtd, unsigned char *buf,
145 u_char *read_ecc, u_char *calc_ecc) 429 unsigned char *read_ecc, unsigned char *calc_ecc)
146{ 430{
147 uint8_t s0, s1, s2; 431 unsigned char b0, b1, b2;
432 unsigned char byte_addr, bit_addr;
433 /* 256 or 512 bytes/ecc */
434 const uint32_t eccsize_mult =
435 (((struct nand_chip *)mtd->priv)->ecc.size) >> 8;
148 436
437 /*
438 * b0 to b2 indicate which bit is faulty (if any)
439 * we might need the xor result more than once,
440 * so keep them in a local var
441 */
149#ifdef CONFIG_MTD_NAND_ECC_SMC 442#ifdef CONFIG_MTD_NAND_ECC_SMC
150 s0 = calc_ecc[0] ^ read_ecc[0]; 443 b0 = read_ecc[0] ^ calc_ecc[0];
151 s1 = calc_ecc[1] ^ read_ecc[1]; 444 b1 = read_ecc[1] ^ calc_ecc[1];
152 s2 = calc_ecc[2] ^ read_ecc[2];
153#else 445#else
154 s1 = calc_ecc[0] ^ read_ecc[0]; 446 b0 = read_ecc[1] ^ calc_ecc[1];
155 s0 = calc_ecc[1] ^ read_ecc[1]; 447 b1 = read_ecc[0] ^ calc_ecc[0];
156 s2 = calc_ecc[2] ^ read_ecc[2];
157#endif 448#endif
158 if ((s0 | s1 | s2) == 0) 449 b2 = read_ecc[2] ^ calc_ecc[2];
159 return 0;
160
161 /* Check for a single bit error */
162 if( ((s0 ^ (s0 >> 1)) & 0x55) == 0x55 &&
163 ((s1 ^ (s1 >> 1)) & 0x55) == 0x55 &&
164 ((s2 ^ (s2 >> 1)) & 0x54) == 0x54) {
165 450
166 uint32_t byteoffs, bitnum; 451 /* check if there are any bitfaults */
167 452
168 byteoffs = (s1 << 0) & 0x80; 453 /* repeated if statements are slightly more efficient than switch ... */
169 byteoffs |= (s1 << 1) & 0x40; 454 /* ordered in order of likelihood */
170 byteoffs |= (s1 << 2) & 0x20;
171 byteoffs |= (s1 << 3) & 0x10;
172 455
173 byteoffs |= (s0 >> 4) & 0x08; 456 if ((b0 | b1 | b2) == 0)
174 byteoffs |= (s0 >> 3) & 0x04; 457 return 0; /* no error */
175 byteoffs |= (s0 >> 2) & 0x02;
176 byteoffs |= (s0 >> 1) & 0x01;
177
178 bitnum = (s2 >> 5) & 0x04;
179 bitnum |= (s2 >> 4) & 0x02;
180 bitnum |= (s2 >> 3) & 0x01;
181
182 dat[byteoffs] ^= (1 << bitnum);
183 458
459 if ((((b0 ^ (b0 >> 1)) & 0x55) == 0x55) &&
460 (((b1 ^ (b1 >> 1)) & 0x55) == 0x55) &&
461 ((eccsize_mult == 1 && ((b2 ^ (b2 >> 1)) & 0x54) == 0x54) ||
462 (eccsize_mult == 2 && ((b2 ^ (b2 >> 1)) & 0x55) == 0x55))) {
463 /* single bit error */
464 /*
465 * rp17/rp15/13/11/9/7/5/3/1 indicate which byte is the faulty
466 * byte, cp 5/3/1 indicate the faulty bit.
467 * A lookup table (called addressbits) is used to filter
468 * the bits from the byte they are in.
469 * A marginal optimisation is possible by having three
470 * different lookup tables.
471 * One as we have now (for b0), one for b2
472 * (that would avoid the >> 1), and one for b1 (with all values
473 * << 4). However it was felt that introducing two more tables
474 * hardly justify the gain.
475 *
476 * The b2 shift is there to get rid of the lowest two bits.
477 * We could also do addressbits[b2] >> 1 but for the
478 * performace it does not make any difference
479 */
480 if (eccsize_mult == 1)
481 byte_addr = (addressbits[b1] << 4) + addressbits[b0];
482 else
483 byte_addr = (addressbits[b2 & 0x3] << 8) +
484 (addressbits[b1] << 4) + addressbits[b0];
485 bit_addr = addressbits[b2 >> 2];
486 /* flip the bit */
487 buf[byte_addr] ^= (1 << bit_addr);
184 return 1; 488 return 1;
185 }
186 489
187 if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1) 490 }
188 return 1; 491 /* count nr of bits; use table lookup, faster than calculating it */
492 if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1)
493 return 1; /* error in ecc data; no action needed */
189 494
190 return -EBADMSG; 495 printk(KERN_ERR "uncorrectable error : ");
496 return -1;
191} 497}
192EXPORT_SYMBOL(nand_correct_data); 498EXPORT_SYMBOL(nand_correct_data);
193 499
194MODULE_LICENSE("GPL"); 500MODULE_LICENSE("GPL");
195MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>"); 501MODULE_AUTHOR("Frans Meulenbroeks <fransmeulenbroeks@gmail.com>");
196MODULE_DESCRIPTION("Generic NAND ECC support"); 502MODULE_DESCRIPTION("Generic NAND ECC support");
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index 556e8131ecdc..ae7c57781a68 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -38,7 +38,6 @@
38#include <linux/delay.h> 38#include <linux/delay.h>
39#include <linux/list.h> 39#include <linux/list.h>
40#include <linux/random.h> 40#include <linux/random.h>
41#include <asm/div64.h>
42 41
43/* Default simulator parameters values */ 42/* Default simulator parameters values */
44#if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE) || \ 43#if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE) || \
diff --git a/drivers/mtd/nand/toto.c b/drivers/mtd/nand/toto.c
deleted file mode 100644
index bbf492e6830d..000000000000
--- a/drivers/mtd/nand/toto.c
+++ /dev/null
@@ -1,206 +0,0 @@
1/*
2 * drivers/mtd/nand/toto.c
3 *
4 * Copyright (c) 2003 Texas Instruments
5 *
6 * Derived from drivers/mtd/autcpu12.c
7 *
8 * Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * Overview:
15 * This is a device driver for the NAND flash device found on the
16 * TI fido board. It supports 32MiB and 64MiB cards
17 */
18
19#include <linux/slab.h>
20#include <linux/init.h>
21#include <linux/module.h>
22#include <linux/delay.h>
23#include <linux/mtd/mtd.h>
24#include <linux/mtd/nand.h>
25#include <linux/mtd/partitions.h>
26#include <asm/io.h>
27#include <asm/arch/hardware.h>
28#include <asm/sizes.h>
29#include <asm/arch/toto.h>
30#include <asm/arch-omap1510/hardware.h>
31#include <asm/arch/gpio.h>
32
33#define CONFIG_NAND_WORKAROUND 1
34
35/*
36 * MTD structure for TOTO board
37 */
38static struct mtd_info *toto_mtd = NULL;
39
40static unsigned long toto_io_base = OMAP_FLASH_1_BASE;
41
42/*
43 * Define partitions for flash devices
44 */
45
46static struct mtd_partition partition_info64M[] = {
47 { .name = "toto kernel partition 1",
48 .offset = 0,
49 .size = 2 * SZ_1M },
50 { .name = "toto file sys partition 2",
51 .offset = 2 * SZ_1M,
52 .size = 14 * SZ_1M },
53 { .name = "toto user partition 3",
54 .offset = 16 * SZ_1M,
55 .size = 16 * SZ_1M },
56 { .name = "toto devboard extra partition 4",
57 .offset = 32 * SZ_1M,
58 .size = 32 * SZ_1M },
59};
60
61static struct mtd_partition partition_info32M[] = {
62 { .name = "toto kernel partition 1",
63 .offset = 0,
64 .size = 2 * SZ_1M },
65 { .name = "toto file sys partition 2",
66 .offset = 2 * SZ_1M,
67 .size = 14 * SZ_1M },
68 { .name = "toto user partition 3",
69 .offset = 16 * SZ_1M,
70 .size = 16 * SZ_1M },
71};
72
73#define NUM_PARTITIONS32M 3
74#define NUM_PARTITIONS64M 4
75
76/*
77 * hardware specific access to control-lines
78 *
79 * ctrl:
80 * NAND_NCE: bit 0 -> bit 14 (0x4000)
81 * NAND_CLE: bit 1 -> bit 12 (0x1000)
82 * NAND_ALE: bit 2 -> bit 1 (0x0002)
83 */
84static void toto_hwcontrol(struct mtd_info *mtd, int cmd,
85 unsigned int ctrl)
86{
87 struct nand_chip *chip = mtd->priv;
88
89 if (ctrl & NAND_CTRL_CHANGE) {
90 unsigned long bits;
91
92 /* hopefully enough time for tc make proceding write to clear */
93 udelay(1);
94
95 bits = (~ctrl & NAND_NCE) << 14;
96 bits |= (ctrl & NAND_CLE) << 12;
97 bits |= (ctrl & NAND_ALE) >> 1;
98
99#warning Wild guess as gpiosetout() is nowhere defined in the kernel source - tglx
100 gpiosetout(0x5002, bits);
101
102#ifdef CONFIG_NAND_WORKAROUND
103 /* "some" dev boards busted, blue wired to rts2 :( */
104 rts2setout(2, (ctrl & NAND_CLE) << 1);
105#endif
106 /* allow time to ensure gpio state to over take memory write */
107 udelay(1);
108 }
109
110 if (cmd != NAND_CMD_NONE)
111 writeb(cmd, chip->IO_ADDR_W);
112}
113
114/*
115 * Main initialization routine
116 */
117static int __init toto_init(void)
118{
119 struct nand_chip *this;
120 int err = 0;
121
122 /* Allocate memory for MTD device structure and private data */
123 toto_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
124 if (!toto_mtd) {
125 printk(KERN_WARNING "Unable to allocate toto NAND MTD device structure.\n");
126 err = -ENOMEM;
127 goto out;
128 }
129
130 /* Get pointer to private data */
131 this = (struct nand_chip *)(&toto_mtd[1]);
132
133 /* Initialize structures */
134 memset(toto_mtd, 0, sizeof(struct mtd_info));
135 memset(this, 0, sizeof(struct nand_chip));
136
137 /* Link the private data with the MTD structure */
138 toto_mtd->priv = this;
139 toto_mtd->owner = THIS_MODULE;
140
141 /* Set address of NAND IO lines */
142 this->IO_ADDR_R = toto_io_base;
143 this->IO_ADDR_W = toto_io_base;
144 this->cmd_ctrl = toto_hwcontrol;
145 this->dev_ready = NULL;
146 /* 25 us command delay time */
147 this->chip_delay = 30;
148 this->ecc.mode = NAND_ECC_SOFT;
149
150 /* Scan to find existance of the device */
151 if (nand_scan(toto_mtd, 1)) {
152 err = -ENXIO;
153 goto out_mtd;
154 }
155
156 /* Register the partitions */
157 switch (toto_mtd->size) {
158 case SZ_64M:
159 add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M);
160 break;
161 case SZ_32M:
162 add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M);
163 break;
164 default:{
165 printk(KERN_WARNING "Unsupported Nand device\n");
166 err = -ENXIO;
167 goto out_buf;
168 }
169 }
170
171 gpioreserve(NAND_MASK); /* claim our gpios */
172 archflashwp(0, 0); /* open up flash for writing */
173
174 goto out;
175
176 out_mtd:
177 kfree(toto_mtd);
178 out:
179 return err;
180}
181
182module_init(toto_init);
183
184/*
185 * Clean up routine
186 */
187static void __exit toto_cleanup(void)
188{
189 /* Release resources, unregister device */
190 nand_release(toto_mtd);
191
192 /* Free the MTD device structure */
193 kfree(toto_mtd);
194
195 /* stop flash writes */
196 archflashwp(0, 1);
197
198 /* release gpios to system */
199 gpiorelease(NAND_MASK);
200}
201
202module_exit(toto_cleanup);
203
204MODULE_LICENSE("GPL");
205MODULE_AUTHOR("Richard Woodruff <r-woodruff2@ti.com>");
206MODULE_DESCRIPTION("Glue layer for NAND flash on toto board");
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
index cb41cbca64f7..79fa79e8f8de 100644
--- a/drivers/mtd/onenand/Kconfig
+++ b/drivers/mtd/onenand/Kconfig
@@ -27,8 +27,16 @@ config MTD_ONENAND_GENERIC
27 help 27 help
28 Support for OneNAND flash via platform device driver. 28 Support for OneNAND flash via platform device driver.
29 29
30config MTD_ONENAND_OMAP2
31 tristate "OneNAND on OMAP2/OMAP3 support"
32 depends on MTD_ONENAND && (ARCH_OMAP2 || ARCH_OMAP3)
33 help
34 Support for a OneNAND flash device connected to an OMAP2/OMAP3 CPU
35 via the GPMC memory controller.
36
30config MTD_ONENAND_OTP 37config MTD_ONENAND_OTP
31 bool "OneNAND OTP Support" 38 bool "OneNAND OTP Support"
39 select HAVE_MTD_OTP
32 help 40 help
33 One Block of the NAND Flash Array memory is reserved as 41 One Block of the NAND Flash Array memory is reserved as
34 a One-Time Programmable Block memory area. 42 a One-Time Programmable Block memory area.
diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
index 4d2eacfd7e11..64b6cc61a520 100644
--- a/drivers/mtd/onenand/Makefile
+++ b/drivers/mtd/onenand/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_MTD_ONENAND) += onenand.o
7 7
8# Board specific. 8# Board specific.
9obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o 9obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o
10obj-$(CONFIG_MTD_ONENAND_OMAP2) += omap2.o
10 11
11# Simulator 12# Simulator
12obj-$(CONFIG_MTD_ONENAND_SIM) += onenand_sim.o 13obj-$(CONFIG_MTD_ONENAND_SIM) += onenand_sim.o
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
new file mode 100644
index 000000000000..34b42533f4bb
--- /dev/null
+++ b/drivers/mtd/onenand/omap2.c
@@ -0,0 +1,782 @@
1/*
2 * linux/drivers/mtd/onenand/omap2.c
3 *
4 * OneNAND driver for OMAP2 / OMAP3
5 *
6 * Copyright © 2005-2006 Nokia Corporation
7 *
8 * Author: Jarkko Lavinen <jarkko.lavinen@nokia.com> and Juha Yrjölä
9 * IRQ and DMA support written by Timo Teras
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 as published by
13 * the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * more details.
19 *
20 * You should have received a copy of the GNU General Public License along with
21 * this program; see the file COPYING. If not, write to the Free Software
22 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 *
24 */
25
26#include <linux/device.h>
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/mtd/mtd.h>
30#include <linux/mtd/onenand.h>
31#include <linux/mtd/partitions.h>
32#include <linux/platform_device.h>
33#include <linux/interrupt.h>
34#include <linux/delay.h>
35
36#include <asm/io.h>
37#include <asm/mach/flash.h>
38#include <asm/arch/gpmc.h>
39#include <asm/arch/onenand.h>
40#include <asm/arch/gpio.h>
41#include <asm/arch/gpmc.h>
42#include <asm/arch/pm.h>
43
44#include <linux/dma-mapping.h>
45#include <asm/dma-mapping.h>
46#include <asm/arch/dma.h>
47
48#include <asm/arch/board.h>
49
50#define DRIVER_NAME "omap2-onenand"
51
52#define ONENAND_IO_SIZE SZ_128K
53#define ONENAND_BUFRAM_SIZE (1024 * 5)
54
55struct omap2_onenand {
56 struct platform_device *pdev;
57 int gpmc_cs;
58 unsigned long phys_base;
59 int gpio_irq;
60 struct mtd_info mtd;
61 struct mtd_partition *parts;
62 struct onenand_chip onenand;
63 struct completion irq_done;
64 struct completion dma_done;
65 int dma_channel;
66 int freq;
67 int (*setup)(void __iomem *base, int freq);
68};
69
70static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)
71{
72 struct omap2_onenand *c = data;
73
74 complete(&c->dma_done);
75}
76
77static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id)
78{
79 struct omap2_onenand *c = dev_id;
80
81 complete(&c->irq_done);
82
83 return IRQ_HANDLED;
84}
85
86static inline unsigned short read_reg(struct omap2_onenand *c, int reg)
87{
88 return readw(c->onenand.base + reg);
89}
90
91static inline void write_reg(struct omap2_onenand *c, unsigned short value,
92 int reg)
93{
94 writew(value, c->onenand.base + reg);
95}
96
97static void wait_err(char *msg, int state, unsigned int ctrl, unsigned int intr)
98{
99 printk(KERN_ERR "onenand_wait: %s! state %d ctrl 0x%04x intr 0x%04x\n",
100 msg, state, ctrl, intr);
101}
102
103static void wait_warn(char *msg, int state, unsigned int ctrl,
104 unsigned int intr)
105{
106 printk(KERN_WARNING "onenand_wait: %s! state %d ctrl 0x%04x "
107 "intr 0x%04x\n", msg, state, ctrl, intr);
108}
109
110static int omap2_onenand_wait(struct mtd_info *mtd, int state)
111{
112 struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
113 unsigned int intr = 0;
114 unsigned int ctrl;
115 unsigned long timeout;
116 u32 syscfg;
117
118 if (state == FL_RESETING) {
119 int i;
120
121 for (i = 0; i < 20; i++) {
122 udelay(1);
123 intr = read_reg(c, ONENAND_REG_INTERRUPT);
124 if (intr & ONENAND_INT_MASTER)
125 break;
126 }
127 ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
128 if (ctrl & ONENAND_CTRL_ERROR) {
129 wait_err("controller error", state, ctrl, intr);
130 return -EIO;
131 }
132 if (!(intr & ONENAND_INT_RESET)) {
133 wait_err("timeout", state, ctrl, intr);
134 return -EIO;
135 }
136 return 0;
137 }
138
139 if (state != FL_READING) {
140 int result;
141
142 /* Turn interrupts on */
143 syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
144 if (!(syscfg & ONENAND_SYS_CFG1_IOBE)) {
145 syscfg |= ONENAND_SYS_CFG1_IOBE;
146 write_reg(c, syscfg, ONENAND_REG_SYS_CFG1);
147 if (cpu_is_omap34xx())
148 /* Add a delay to let GPIO settle */
149 syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
150 }
151
152 INIT_COMPLETION(c->irq_done);
153 if (c->gpio_irq) {
154 result = omap_get_gpio_datain(c->gpio_irq);
155 if (result == -1) {
156 ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
157 intr = read_reg(c, ONENAND_REG_INTERRUPT);
158 wait_err("gpio error", state, ctrl, intr);
159 return -EIO;
160 }
161 } else
162 result = 0;
163 if (result == 0) {
164 int retry_cnt = 0;
165retry:
166 result = wait_for_completion_timeout(&c->irq_done,
167 msecs_to_jiffies(20));
168 if (result == 0) {
169 /* Timeout after 20ms */
170 ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
171 if (ctrl & ONENAND_CTRL_ONGO) {
172 /*
173 * The operation seems to be still going
174 * so give it some more time.
175 */
176 retry_cnt += 1;
177 if (retry_cnt < 3)
178 goto retry;
179 intr = read_reg(c,
180 ONENAND_REG_INTERRUPT);
181 wait_err("timeout", state, ctrl, intr);
182 return -EIO;
183 }
184 intr = read_reg(c, ONENAND_REG_INTERRUPT);
185 if ((intr & ONENAND_INT_MASTER) == 0)
186 wait_warn("timeout", state, ctrl, intr);
187 }
188 }
189 } else {
190 /* Turn interrupts off */
191 syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
192 syscfg &= ~ONENAND_SYS_CFG1_IOBE;
193 write_reg(c, syscfg, ONENAND_REG_SYS_CFG1);
194
195 timeout = jiffies + msecs_to_jiffies(20);
196 while (time_before(jiffies, timeout)) {
197 intr = read_reg(c, ONENAND_REG_INTERRUPT);
198 if (intr & ONENAND_INT_MASTER)
199 break;
200 }
201 }
202
203 intr = read_reg(c, ONENAND_REG_INTERRUPT);
204 ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
205
206 if (intr & ONENAND_INT_READ) {
207 int ecc = read_reg(c, ONENAND_REG_ECC_STATUS);
208
209 if (ecc) {
210 unsigned int addr1, addr8;
211
212 addr1 = read_reg(c, ONENAND_REG_START_ADDRESS1);
213 addr8 = read_reg(c, ONENAND_REG_START_ADDRESS8);
214 if (ecc & ONENAND_ECC_2BIT_ALL) {
215 printk(KERN_ERR "onenand_wait: ECC error = "
216 "0x%04x, addr1 %#x, addr8 %#x\n",
217 ecc, addr1, addr8);
218 mtd->ecc_stats.failed++;
219 return -EBADMSG;
220 } else if (ecc & ONENAND_ECC_1BIT_ALL) {
221 printk(KERN_NOTICE "onenand_wait: correctable "
222 "ECC error = 0x%04x, addr1 %#x, "
223 "addr8 %#x\n", ecc, addr1, addr8);
224 mtd->ecc_stats.corrected++;
225 }
226 }
227 } else if (state == FL_READING) {
228 wait_err("timeout", state, ctrl, intr);
229 return -EIO;
230 }
231
232 if (ctrl & ONENAND_CTRL_ERROR) {
233 wait_err("controller error", state, ctrl, intr);
234 if (ctrl & ONENAND_CTRL_LOCK)
235 printk(KERN_ERR "onenand_wait: "
236 "Device is write protected!!!\n");
237 return -EIO;
238 }
239
240 if (ctrl & 0xFE9F)
241 wait_warn("unexpected controller status", state, ctrl, intr);
242
243 return 0;
244}
245
246static inline int omap2_onenand_bufferram_offset(struct mtd_info *mtd, int area)
247{
248 struct onenand_chip *this = mtd->priv;
249
250 if (ONENAND_CURRENT_BUFFERRAM(this)) {
251 if (area == ONENAND_DATARAM)
252 return mtd->writesize;
253 if (area == ONENAND_SPARERAM)
254 return mtd->oobsize;
255 }
256
257 return 0;
258}
259
260#if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
261
262static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
263 unsigned char *buffer, int offset,
264 size_t count)
265{
266 struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
267 struct onenand_chip *this = mtd->priv;
268 dma_addr_t dma_src, dma_dst;
269 int bram_offset;
270 unsigned long timeout;
271 void *buf = (void *)buffer;
272 size_t xtra;
273 volatile unsigned *done;
274
275 bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
276 if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
277 goto out_copy;
278
279 if (buf >= high_memory) {
280 struct page *p1;
281
282 if (((size_t)buf & PAGE_MASK) !=
283 ((size_t)(buf + count - 1) & PAGE_MASK))
284 goto out_copy;
285 p1 = vmalloc_to_page(buf);
286 if (!p1)
287 goto out_copy;
288 buf = page_address(p1) + ((size_t)buf & ~PAGE_MASK);
289 }
290
291 xtra = count & 3;
292 if (xtra) {
293 count -= xtra;
294 memcpy(buf + count, this->base + bram_offset + count, xtra);
295 }
296
297 dma_src = c->phys_base + bram_offset;
298 dma_dst = dma_map_single(&c->pdev->dev, buf, count, DMA_FROM_DEVICE);
299 if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
300 dev_err(&c->pdev->dev,
301 "Couldn't DMA map a %d byte buffer\n",
302 count);
303 goto out_copy;
304 }
305
306 omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
307 count >> 2, 1, 0, 0, 0);
308 omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
309 dma_src, 0, 0);
310 omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
311 dma_dst, 0, 0);
312
313 INIT_COMPLETION(c->dma_done);
314 omap_start_dma(c->dma_channel);
315
316 timeout = jiffies + msecs_to_jiffies(20);
317 done = &c->dma_done.done;
318 while (time_before(jiffies, timeout))
319 if (*done)
320 break;
321
322 dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
323
324 if (!*done) {
325 dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
326 goto out_copy;
327 }
328
329 return 0;
330
331out_copy:
332 memcpy(buf, this->base + bram_offset, count);
333 return 0;
334}
335
336static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
337 const unsigned char *buffer,
338 int offset, size_t count)
339{
340 struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
341 struct onenand_chip *this = mtd->priv;
342 dma_addr_t dma_src, dma_dst;
343 int bram_offset;
344 unsigned long timeout;
345 void *buf = (void *)buffer;
346 volatile unsigned *done;
347
348 bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
349 if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
350 goto out_copy;
351
352 /* panic_write() may be in an interrupt context */
353 if (in_interrupt())
354 goto out_copy;
355
356 if (buf >= high_memory) {
357 struct page *p1;
358
359 if (((size_t)buf & PAGE_MASK) !=
360 ((size_t)(buf + count - 1) & PAGE_MASK))
361 goto out_copy;
362 p1 = vmalloc_to_page(buf);
363 if (!p1)
364 goto out_copy;
365 buf = page_address(p1) + ((size_t)buf & ~PAGE_MASK);
366 }
367
368 dma_src = dma_map_single(&c->pdev->dev, buf, count, DMA_TO_DEVICE);
369 dma_dst = c->phys_base + bram_offset;
370 if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
371 dev_err(&c->pdev->dev,
372 "Couldn't DMA map a %d byte buffer\n",
373 count);
374 return -1;
375 }
376
377 omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
378 count >> 2, 1, 0, 0, 0);
379 omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
380 dma_src, 0, 0);
381 omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
382 dma_dst, 0, 0);
383
384 INIT_COMPLETION(c->dma_done);
385 omap_start_dma(c->dma_channel);
386
387 timeout = jiffies + msecs_to_jiffies(20);
388 done = &c->dma_done.done;
389 while (time_before(jiffies, timeout))
390 if (*done)
391 break;
392
393 dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_TO_DEVICE);
394
395 if (!*done) {
396 dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
397 goto out_copy;
398 }
399
400 return 0;
401
402out_copy:
403 memcpy(this->base + bram_offset, buf, count);
404 return 0;
405}
406
407#else
408
409int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
410 unsigned char *buffer, int offset,
411 size_t count);
412
413int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
414 const unsigned char *buffer,
415 int offset, size_t count);
416
417#endif
418
419#if defined(CONFIG_ARCH_OMAP2) || defined(MULTI_OMAP2)
420
421static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
422 unsigned char *buffer, int offset,
423 size_t count)
424{
425 struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
426 struct onenand_chip *this = mtd->priv;
427 dma_addr_t dma_src, dma_dst;
428 int bram_offset;
429
430 bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
431 /* DMA is not used. Revisit PM requirements before enabling it. */
432 if (1 || (c->dma_channel < 0) ||
433 ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
434 (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
435 memcpy(buffer, (__force void *)(this->base + bram_offset),
436 count);
437 return 0;
438 }
439
440 dma_src = c->phys_base + bram_offset;
441 dma_dst = dma_map_single(&c->pdev->dev, buffer, count,
442 DMA_FROM_DEVICE);
443 if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
444 dev_err(&c->pdev->dev,
445 "Couldn't DMA map a %d byte buffer\n",
446 count);
447 return -1;
448 }
449
450 omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
451 count / 4, 1, 0, 0, 0);
452 omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
453 dma_src, 0, 0);
454 omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
455 dma_dst, 0, 0);
456
457 INIT_COMPLETION(c->dma_done);
458 omap_start_dma(c->dma_channel);
459 wait_for_completion(&c->dma_done);
460
461 dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
462
463 return 0;
464}
465
466static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
467 const unsigned char *buffer,
468 int offset, size_t count)
469{
470 struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
471 struct onenand_chip *this = mtd->priv;
472 dma_addr_t dma_src, dma_dst;
473 int bram_offset;
474
475 bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
476 /* DMA is not used. Revisit PM requirements before enabling it. */
477 if (1 || (c->dma_channel < 0) ||
478 ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
479 (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
480 memcpy((__force void *)(this->base + bram_offset), buffer,
481 count);
482 return 0;
483 }
484
485 dma_src = dma_map_single(&c->pdev->dev, (void *) buffer, count,
486 DMA_TO_DEVICE);
487 dma_dst = c->phys_base + bram_offset;
488 if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
489 dev_err(&c->pdev->dev,
490 "Couldn't DMA map a %d byte buffer\n",
491 count);
492 return -1;
493 }
494
495 omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S16,
496 count / 2, 1, 0, 0, 0);
497 omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
498 dma_src, 0, 0);
499 omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
500 dma_dst, 0, 0);
501
502 INIT_COMPLETION(c->dma_done);
503 omap_start_dma(c->dma_channel);
504 wait_for_completion(&c->dma_done);
505
506 dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_TO_DEVICE);
507
508 return 0;
509}
510
511#else
512
513int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
514 unsigned char *buffer, int offset,
515 size_t count);
516
517int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
518 const unsigned char *buffer,
519 int offset, size_t count);
520
521#endif
522
523static struct platform_driver omap2_onenand_driver;
524
525static int __adjust_timing(struct device *dev, void *data)
526{
527 int ret = 0;
528 struct omap2_onenand *c;
529
530 c = dev_get_drvdata(dev);
531
532 BUG_ON(c->setup == NULL);
533
534 /* DMA is not in use so this is all that is needed */
535 /* Revisit for OMAP3! */
536 ret = c->setup(c->onenand.base, c->freq);
537
538 return ret;
539}
540
541int omap2_onenand_rephase(void)
542{
543 return driver_for_each_device(&omap2_onenand_driver.driver, NULL,
544 NULL, __adjust_timing);
545}
546
547static void __devexit omap2_onenand_shutdown(struct platform_device *pdev)
548{
549 struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
550
551 /* With certain content in the buffer RAM, the OMAP boot ROM code
552 * can recognize the flash chip incorrectly. Zero it out before
553 * soft reset.
554 */
555 memset((__force void *)c->onenand.base, 0, ONENAND_BUFRAM_SIZE);
556}
557
558static int __devinit omap2_onenand_probe(struct platform_device *pdev)
559{
560 struct omap_onenand_platform_data *pdata;
561 struct omap2_onenand *c;
562 int r;
563
564 pdata = pdev->dev.platform_data;
565 if (pdata == NULL) {
566 dev_err(&pdev->dev, "platform data missing\n");
567 return -ENODEV;
568 }
569
570 c = kzalloc(sizeof(struct omap2_onenand), GFP_KERNEL);
571 if (!c)
572 return -ENOMEM;
573
574 init_completion(&c->irq_done);
575 init_completion(&c->dma_done);
576 c->gpmc_cs = pdata->cs;
577 c->gpio_irq = pdata->gpio_irq;
578 c->dma_channel = pdata->dma_channel;
579 if (c->dma_channel < 0) {
580 /* if -1, don't use DMA */
581 c->gpio_irq = 0;
582 }
583
584 r = gpmc_cs_request(c->gpmc_cs, ONENAND_IO_SIZE, &c->phys_base);
585 if (r < 0) {
586 dev_err(&pdev->dev, "Cannot request GPMC CS\n");
587 goto err_kfree;
588 }
589
590 if (request_mem_region(c->phys_base, ONENAND_IO_SIZE,
591 pdev->dev.driver->name) == NULL) {
592 dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, "
593 "size: 0x%x\n", c->phys_base, ONENAND_IO_SIZE);
594 r = -EBUSY;
595 goto err_free_cs;
596 }
597 c->onenand.base = ioremap(c->phys_base, ONENAND_IO_SIZE);
598 if (c->onenand.base == NULL) {
599 r = -ENOMEM;
600 goto err_release_mem_region;
601 }
602
603 if (pdata->onenand_setup != NULL) {
604 r = pdata->onenand_setup(c->onenand.base, c->freq);
605 if (r < 0) {
606 dev_err(&pdev->dev, "Onenand platform setup failed: "
607 "%d\n", r);
608 goto err_iounmap;
609 }
610 c->setup = pdata->onenand_setup;
611 }
612
613 if (c->gpio_irq) {
614 if ((r = omap_request_gpio(c->gpio_irq)) < 0) {
615 dev_err(&pdev->dev, "Failed to request GPIO%d for "
616 "OneNAND\n", c->gpio_irq);
617 goto err_iounmap;
618 }
619 omap_set_gpio_direction(c->gpio_irq, 1);
620
621 if ((r = request_irq(OMAP_GPIO_IRQ(c->gpio_irq),
622 omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
623 pdev->dev.driver->name, c)) < 0)
624 goto err_release_gpio;
625 }
626
627 if (c->dma_channel >= 0) {
628 r = omap_request_dma(0, pdev->dev.driver->name,
629 omap2_onenand_dma_cb, (void *) c,
630 &c->dma_channel);
631 if (r == 0) {
632 omap_set_dma_write_mode(c->dma_channel,
633 OMAP_DMA_WRITE_NON_POSTED);
634 omap_set_dma_src_data_pack(c->dma_channel, 1);
635 omap_set_dma_src_burst_mode(c->dma_channel,
636 OMAP_DMA_DATA_BURST_8);
637 omap_set_dma_dest_data_pack(c->dma_channel, 1);
638 omap_set_dma_dest_burst_mode(c->dma_channel,
639 OMAP_DMA_DATA_BURST_8);
640 } else {
641 dev_info(&pdev->dev,
642 "failed to allocate DMA for OneNAND, "
643 "using PIO instead\n");
644 c->dma_channel = -1;
645 }
646 }
647
648 dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
649 "base %p\n", c->gpmc_cs, c->phys_base,
650 c->onenand.base);
651
652 c->pdev = pdev;
653 c->mtd.name = pdev->dev.bus_id;
654 c->mtd.priv = &c->onenand;
655 c->mtd.owner = THIS_MODULE;
656
657 if (c->dma_channel >= 0) {
658 struct onenand_chip *this = &c->onenand;
659
660 this->wait = omap2_onenand_wait;
661 if (cpu_is_omap34xx()) {
662 this->read_bufferram = omap3_onenand_read_bufferram;
663 this->write_bufferram = omap3_onenand_write_bufferram;
664 } else {
665 this->read_bufferram = omap2_onenand_read_bufferram;
666 this->write_bufferram = omap2_onenand_write_bufferram;
667 }
668 }
669
670 if ((r = onenand_scan(&c->mtd, 1)) < 0)
671 goto err_release_dma;
672
673 switch ((c->onenand.version_id >> 4) & 0xf) {
674 case 0:
675 c->freq = 40;
676 break;
677 case 1:
678 c->freq = 54;
679 break;
680 case 2:
681 c->freq = 66;
682 break;
683 case 3:
684 c->freq = 83;
685 break;
686 }
687
688#ifdef CONFIG_MTD_PARTITIONS
689 if (pdata->parts != NULL)
690 r = add_mtd_partitions(&c->mtd, pdata->parts,
691 pdata->nr_parts);
692 else
693#endif
694 r = add_mtd_device(&c->mtd);
695 if (r < 0)
696 goto err_release_onenand;
697
698 platform_set_drvdata(pdev, c);
699
700 return 0;
701
702err_release_onenand:
703 onenand_release(&c->mtd);
704err_release_dma:
705 if (c->dma_channel != -1)
706 omap_free_dma(c->dma_channel);
707 if (c->gpio_irq)
708 free_irq(OMAP_GPIO_IRQ(c->gpio_irq), c);
709err_release_gpio:
710 if (c->gpio_irq)
711 omap_free_gpio(c->gpio_irq);
712err_iounmap:
713 iounmap(c->onenand.base);
714err_release_mem_region:
715 release_mem_region(c->phys_base, ONENAND_IO_SIZE);
716err_free_cs:
717 gpmc_cs_free(c->gpmc_cs);
718err_kfree:
719 kfree(c);
720
721 return r;
722}
723
724static int __devexit omap2_onenand_remove(struct platform_device *pdev)
725{
726 struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
727
728 BUG_ON(c == NULL);
729
730#ifdef CONFIG_MTD_PARTITIONS
731 if (c->parts)
732 del_mtd_partitions(&c->mtd);
733 else
734 del_mtd_device(&c->mtd);
735#else
736 del_mtd_device(&c->mtd);
737#endif
738
739 onenand_release(&c->mtd);
740 if (c->dma_channel != -1)
741 omap_free_dma(c->dma_channel);
742 omap2_onenand_shutdown(pdev);
743 platform_set_drvdata(pdev, NULL);
744 if (c->gpio_irq) {
745 free_irq(OMAP_GPIO_IRQ(c->gpio_irq), c);
746 omap_free_gpio(c->gpio_irq);
747 }
748 iounmap(c->onenand.base);
749 release_mem_region(c->phys_base, ONENAND_IO_SIZE);
750 kfree(c);
751
752 return 0;
753}
754
755static struct platform_driver omap2_onenand_driver = {
756 .probe = omap2_onenand_probe,
757 .remove = omap2_onenand_remove,
758 .shutdown = omap2_onenand_shutdown,
759 .driver = {
760 .name = DRIVER_NAME,
761 .owner = THIS_MODULE,
762 },
763};
764
765static int __init omap2_onenand_init(void)
766{
767 printk(KERN_INFO "OneNAND driver initializing\n");
768 return platform_driver_register(&omap2_onenand_driver);
769}
770
771static void __exit omap2_onenand_exit(void)
772{
773 platform_driver_unregister(&omap2_onenand_driver);
774}
775
776module_init(omap2_onenand_init);
777module_exit(omap2_onenand_exit);
778
779MODULE_ALIAS(DRIVER_NAME);
780MODULE_LICENSE("GPL");
781MODULE_AUTHOR("Jarkko Lavinen <jarkko.lavinen@nokia.com>");
782MODULE_DESCRIPTION("Glue layer for OneNAND flash on OMAP2 / OMAP3");
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 926cf3a4135d..90ed319f26e6 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1794,7 +1794,7 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1794 return -EINVAL; 1794 return -EINVAL;
1795 } 1795 }
1796 1796
1797 instr->fail_addr = 0xffffffff; 1797 instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
1798 1798
1799 /* Grab the lock and see if the device is available */ 1799 /* Grab the lock and see if the device is available */
1800 onenand_get_device(mtd, FL_ERASING); 1800 onenand_get_device(mtd, FL_ERASING);
diff --git a/drivers/mtd/ssfdc.c b/drivers/mtd/ssfdc.c
index a5f3d60047d4..33a5d6ed6f18 100644
--- a/drivers/mtd/ssfdc.c
+++ b/drivers/mtd/ssfdc.c
@@ -321,8 +321,7 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
321 DEBUG(MTD_DEBUG_LEVEL1, 321 DEBUG(MTD_DEBUG_LEVEL1,
322 "SSFDC_RO: cis_block=%d,erase_size=%d,map_len=%d,n_zones=%d\n", 322 "SSFDC_RO: cis_block=%d,erase_size=%d,map_len=%d,n_zones=%d\n",
323 ssfdc->cis_block, ssfdc->erase_size, ssfdc->map_len, 323 ssfdc->cis_block, ssfdc->erase_size, ssfdc->map_len,
324 (ssfdc->map_len + MAX_PHYS_BLK_PER_ZONE - 1) / 324 DIV_ROUND_UP(ssfdc->map_len, MAX_PHYS_BLK_PER_ZONE));
325 MAX_PHYS_BLK_PER_ZONE);
326 325
327 /* Set geometry */ 326 /* Set geometry */
328 ssfdc->heads = 16; 327 ssfdc->heads = 16;
diff --git a/fs/Kconfig b/fs/Kconfig
index abccb5dab9a8..b7c88e1f0161 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1136,195 +1136,7 @@ config EFS_FS
1136 To compile the EFS file system support as a module, choose M here: the 1136 To compile the EFS file system support as a module, choose M here: the
1137 module will be called efs. 1137 module will be called efs.
1138 1138
1139config JFFS2_FS 1139source "fs/jffs2/Kconfig"
1140 tristate "Journalling Flash File System v2 (JFFS2) support"
1141 select CRC32
1142 depends on MTD
1143 help
1144 JFFS2 is the second generation of the Journalling Flash File System
1145 for use on diskless embedded devices. It provides improved wear
1146 levelling, compression and support for hard links. You cannot use
1147 this on normal block devices, only on 'MTD' devices.
1148
1149 Further information on the design and implementation of JFFS2 is
1150 available at <http://sources.redhat.com/jffs2/>.
1151
1152config JFFS2_FS_DEBUG
1153 int "JFFS2 debugging verbosity (0 = quiet, 2 = noisy)"
1154 depends on JFFS2_FS
1155 default "0"
1156 help
1157 This controls the amount of debugging messages produced by the JFFS2
1158 code. Set it to zero for use in production systems. For evaluation,
1159 testing and debugging, it's advisable to set it to one. This will
1160 enable a few assertions and will print debugging messages at the
1161 KERN_DEBUG loglevel, where they won't normally be visible. Level 2
1162 is unlikely to be useful - it enables extra debugging in certain
1163 areas which at one point needed debugging, but when the bugs were
1164 located and fixed, the detailed messages were relegated to level 2.
1165
1166 If reporting bugs, please try to have available a full dump of the
1167 messages at debug level 1 while the misbehaviour was occurring.
1168
1169config JFFS2_FS_WRITEBUFFER
1170 bool "JFFS2 write-buffering support"
1171 depends on JFFS2_FS
1172 default y
1173 help
1174 This enables the write-buffering support in JFFS2.
1175
1176 This functionality is required to support JFFS2 on the following
1177 types of flash devices:
1178 - NAND flash
1179 - NOR flash with transparent ECC
1180 - DataFlash
1181
1182config JFFS2_FS_WBUF_VERIFY
1183 bool "Verify JFFS2 write-buffer reads"
1184 depends on JFFS2_FS_WRITEBUFFER
1185 default n
1186 help
1187 This causes JFFS2 to read back every page written through the
1188 write-buffer, and check for errors.
1189
1190config JFFS2_SUMMARY
1191 bool "JFFS2 summary support (EXPERIMENTAL)"
1192 depends on JFFS2_FS && EXPERIMENTAL
1193 default n
1194 help
1195 This feature makes it possible to use summary information
1196 for faster filesystem mount.
1197
1198 The summary information can be inserted into a filesystem image
1199 by the utility 'sumtool'.
1200
1201 If unsure, say 'N'.
1202
1203config JFFS2_FS_XATTR
1204 bool "JFFS2 XATTR support (EXPERIMENTAL)"
1205 depends on JFFS2_FS && EXPERIMENTAL
1206 default n
1207 help
1208 Extended attributes are name:value pairs associated with inodes by
1209 the kernel or by users (see the attr(5) manual page, or visit
1210 <http://acl.bestbits.at/> for details).
1211
1212 If unsure, say N.
1213
1214config JFFS2_FS_POSIX_ACL
1215 bool "JFFS2 POSIX Access Control Lists"
1216 depends on JFFS2_FS_XATTR
1217 default y
1218 select FS_POSIX_ACL
1219 help
1220 Posix Access Control Lists (ACLs) support permissions for users and
1221 groups beyond the owner/group/world scheme.
1222
1223 To learn more about Access Control Lists, visit the Posix ACLs for
1224 Linux website <http://acl.bestbits.at/>.
1225
1226 If you don't know what Access Control Lists are, say N
1227
1228config JFFS2_FS_SECURITY
1229 bool "JFFS2 Security Labels"
1230 depends on JFFS2_FS_XATTR
1231 default y
1232 help
1233 Security labels support alternative access control models
1234 implemented by security modules like SELinux. This option
1235 enables an extended attribute handler for file security
1236 labels in the jffs2 filesystem.
1237
1238 If you are not using a security module that requires using
1239 extended attributes for file security labels, say N.
1240
1241config JFFS2_COMPRESSION_OPTIONS
1242 bool "Advanced compression options for JFFS2"
1243 depends on JFFS2_FS
1244 default n
1245 help
1246 Enabling this option allows you to explicitly choose which
1247 compression modules, if any, are enabled in JFFS2. Removing
1248 compressors can mean you cannot read existing file systems,
1249 and enabling experimental compressors can mean that you
1250 write a file system which cannot be read by a standard kernel.
1251
1252 If unsure, you should _definitely_ say 'N'.
1253
1254config JFFS2_ZLIB
1255 bool "JFFS2 ZLIB compression support" if JFFS2_COMPRESSION_OPTIONS
1256 select ZLIB_INFLATE
1257 select ZLIB_DEFLATE
1258 depends on JFFS2_FS
1259 default y
1260 help
1261 Zlib is designed to be a free, general-purpose, legally unencumbered,
1262 lossless data-compression library for use on virtually any computer
1263 hardware and operating system. See <http://www.gzip.org/zlib/> for
1264 further information.
1265
1266 Say 'Y' if unsure.
1267
1268config JFFS2_LZO
1269 bool "JFFS2 LZO compression support" if JFFS2_COMPRESSION_OPTIONS
1270 select LZO_COMPRESS
1271 select LZO_DECOMPRESS
1272 depends on JFFS2_FS
1273 default n
1274 help
1275 minilzo-based compression. Generally works better than Zlib.
1276
1277 This feature was added in July, 2007. Say 'N' if you need
1278 compatibility with older bootloaders or kernels.
1279
1280config JFFS2_RTIME
1281 bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS
1282 depends on JFFS2_FS
1283 default y
1284 help
1285 Rtime does manage to recompress already-compressed data. Say 'Y' if unsure.
1286
1287config JFFS2_RUBIN
1288 bool "JFFS2 RUBIN compression support" if JFFS2_COMPRESSION_OPTIONS
1289 depends on JFFS2_FS
1290 default n
1291 help
1292 RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure.
1293
1294choice
1295 prompt "JFFS2 default compression mode" if JFFS2_COMPRESSION_OPTIONS
1296 default JFFS2_CMODE_PRIORITY
1297 depends on JFFS2_FS
1298 help
1299 You can set here the default compression mode of JFFS2 from
1300 the available compression modes. Don't touch if unsure.
1301
1302config JFFS2_CMODE_NONE
1303 bool "no compression"
1304 help
1305 Uses no compression.
1306
1307config JFFS2_CMODE_PRIORITY
1308 bool "priority"
1309 help
1310 Tries the compressors in a predefined order and chooses the first
1311 successful one.
1312
1313config JFFS2_CMODE_SIZE
1314 bool "size (EXPERIMENTAL)"
1315 help
1316 Tries all compressors and chooses the one which has the smallest
1317 result.
1318
1319config JFFS2_CMODE_FAVOURLZO
1320 bool "Favour LZO"
1321 help
1322 Tries all compressors and chooses the one which has the smallest
1323 result but gives some preference to LZO (which has faster
1324 decompression) at the expense of size.
1325
1326endchoice
1327
1328# UBIFS File system configuration 1140# UBIFS File system configuration
1329source "fs/ubifs/Kconfig" 1141source "fs/ubifs/Kconfig"
1330 1142
diff --git a/fs/jffs2/Kconfig b/fs/jffs2/Kconfig
new file mode 100644
index 000000000000..6ae169cd8faa
--- /dev/null
+++ b/fs/jffs2/Kconfig
@@ -0,0 +1,188 @@
1config JFFS2_FS
2 tristate "Journalling Flash File System v2 (JFFS2) support"
3 select CRC32
4 depends on MTD
5 help
6 JFFS2 is the second generation of the Journalling Flash File System
7 for use on diskless embedded devices. It provides improved wear
8 levelling, compression and support for hard links. You cannot use
9 this on normal block devices, only on 'MTD' devices.
10
11 Further information on the design and implementation of JFFS2 is
12 available at <http://sources.redhat.com/jffs2/>.
13
14config JFFS2_FS_DEBUG
15 int "JFFS2 debugging verbosity (0 = quiet, 2 = noisy)"
16 depends on JFFS2_FS
17 default "0"
18 help
19 This controls the amount of debugging messages produced by the JFFS2
20 code. Set it to zero for use in production systems. For evaluation,
21 testing and debugging, it's advisable to set it to one. This will
22 enable a few assertions and will print debugging messages at the
23 KERN_DEBUG loglevel, where they won't normally be visible. Level 2
24 is unlikely to be useful - it enables extra debugging in certain
25 areas which at one point needed debugging, but when the bugs were
26 located and fixed, the detailed messages were relegated to level 2.
27
28 If reporting bugs, please try to have available a full dump of the
29 messages at debug level 1 while the misbehaviour was occurring.
30
31config JFFS2_FS_WRITEBUFFER
32 bool "JFFS2 write-buffering support"
33 depends on JFFS2_FS
34 default y
35 help
36 This enables the write-buffering support in JFFS2.
37
38 This functionality is required to support JFFS2 on the following
39 types of flash devices:
40 - NAND flash
41 - NOR flash with transparent ECC
42 - DataFlash
43
44config JFFS2_FS_WBUF_VERIFY
45 bool "Verify JFFS2 write-buffer reads"
46 depends on JFFS2_FS_WRITEBUFFER
47 default n
48 help
49 This causes JFFS2 to read back every page written through the
50 write-buffer, and check for errors.
51
52config JFFS2_SUMMARY
53 bool "JFFS2 summary support (EXPERIMENTAL)"
54 depends on JFFS2_FS && EXPERIMENTAL
55 default n
56 help
57 This feature makes it possible to use summary information
58 for faster filesystem mount.
59
60 The summary information can be inserted into a filesystem image
61 by the utility 'sumtool'.
62
63 If unsure, say 'N'.
64
65config JFFS2_FS_XATTR
66 bool "JFFS2 XATTR support (EXPERIMENTAL)"
67 depends on JFFS2_FS && EXPERIMENTAL
68 default n
69 help
70 Extended attributes are name:value pairs associated with inodes by
71 the kernel or by users (see the attr(5) manual page, or visit
72 <http://acl.bestbits.at/> for details).
73
74 If unsure, say N.
75
76config JFFS2_FS_POSIX_ACL
77 bool "JFFS2 POSIX Access Control Lists"
78 depends on JFFS2_FS_XATTR
79 default y
80 select FS_POSIX_ACL
81 help
82 Posix Access Control Lists (ACLs) support permissions for users and
83 groups beyond the owner/group/world scheme.
84
85 To learn more about Access Control Lists, visit the Posix ACLs for
86 Linux website <http://acl.bestbits.at/>.
87
88 If you don't know what Access Control Lists are, say N
89
90config JFFS2_FS_SECURITY
91 bool "JFFS2 Security Labels"
92 depends on JFFS2_FS_XATTR
93 default y
94 help
95 Security labels support alternative access control models
96 implemented by security modules like SELinux. This option
97 enables an extended attribute handler for file security
98 labels in the jffs2 filesystem.
99
100 If you are not using a security module that requires using
101 extended attributes for file security labels, say N.
102
103config JFFS2_COMPRESSION_OPTIONS
104 bool "Advanced compression options for JFFS2"
105 depends on JFFS2_FS
106 default n
107 help
108 Enabling this option allows you to explicitly choose which
109 compression modules, if any, are enabled in JFFS2. Removing
110 compressors can mean you cannot read existing file systems,
111 and enabling experimental compressors can mean that you
112 write a file system which cannot be read by a standard kernel.
113
114 If unsure, you should _definitely_ say 'N'.
115
116config JFFS2_ZLIB
117 bool "JFFS2 ZLIB compression support" if JFFS2_COMPRESSION_OPTIONS
118 select ZLIB_INFLATE
119 select ZLIB_DEFLATE
120 depends on JFFS2_FS
121 default y
122 help
123 Zlib is designed to be a free, general-purpose, legally unencumbered,
124 lossless data-compression library for use on virtually any computer
125 hardware and operating system. See <http://www.gzip.org/zlib/> for
126 further information.
127
128 Say 'Y' if unsure.
129
130config JFFS2_LZO
131 bool "JFFS2 LZO compression support" if JFFS2_COMPRESSION_OPTIONS
132 select LZO_COMPRESS
133 select LZO_DECOMPRESS
134 depends on JFFS2_FS
135 default n
136 help
137 minilzo-based compression. Generally works better than Zlib.
138
139 This feature was added in July, 2007. Say 'N' if you need
140 compatibility with older bootloaders or kernels.
141
142config JFFS2_RTIME
143 bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS
144 depends on JFFS2_FS
145 default y
146 help
147 Rtime does manage to recompress already-compressed data. Say 'Y' if unsure.
148
149config JFFS2_RUBIN
150 bool "JFFS2 RUBIN compression support" if JFFS2_COMPRESSION_OPTIONS
151 depends on JFFS2_FS
152 default n
153 help
154 RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure.
155
156choice
157 prompt "JFFS2 default compression mode" if JFFS2_COMPRESSION_OPTIONS
158 default JFFS2_CMODE_PRIORITY
159 depends on JFFS2_FS
160 help
161 You can set here the default compression mode of JFFS2 from
162 the available compression modes. Don't touch if unsure.
163
164config JFFS2_CMODE_NONE
165 bool "no compression"
166 help
167 Uses no compression.
168
169config JFFS2_CMODE_PRIORITY
170 bool "priority"
171 help
172 Tries the compressors in a predefined order and chooses the first
173 successful one.
174
175config JFFS2_CMODE_SIZE
176 bool "size (EXPERIMENTAL)"
177 help
178 Tries all compressors and chooses the one which has the smallest
179 result.
180
181config JFFS2_CMODE_FAVOURLZO
182 bool "Favour LZO"
183 help
184 Tries all compressors and chooses the one which has the smallest
185 result but gives some preference to LZO (which has faster
186 decompression) at the expense of size.
187
188endchoice
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index cd219ef55254..b1aaae823a52 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -311,7 +311,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
311 /* FIXME: If you care. We'd need to use frags for the target 311 /* FIXME: If you care. We'd need to use frags for the target
312 if it grows much more than this */ 312 if it grows much more than this */
313 if (targetlen > 254) 313 if (targetlen > 254)
314 return -EINVAL; 314 return -ENAMETOOLONG;
315 315
316 ri = jffs2_alloc_raw_inode(); 316 ri = jffs2_alloc_raw_inode();
317 317
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index dddb2a6c9e2c..259461b910af 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -68,7 +68,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
68 instr->len = c->sector_size; 68 instr->len = c->sector_size;
69 instr->callback = jffs2_erase_callback; 69 instr->callback = jffs2_erase_callback;
70 instr->priv = (unsigned long)(&instr[1]); 70 instr->priv = (unsigned long)(&instr[1]);
71 instr->fail_addr = 0xffffffff; 71 instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
72 72
73 ((struct erase_priv_struct *)instr->priv)->jeb = jeb; 73 ((struct erase_priv_struct *)instr->priv)->jeb = jeb;
74 ((struct erase_priv_struct *)instr->priv)->c = c; 74 ((struct erase_priv_struct *)instr->priv)->c = c;
@@ -175,7 +175,7 @@ static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock
175{ 175{
176 /* For NAND, if the failure did not occur at the device level for a 176 /* For NAND, if the failure did not occur at the device level for a
177 specific physical page, don't bother updating the bad block table. */ 177 specific physical page, don't bother updating the bad block table. */
178 if (jffs2_cleanmarker_oob(c) && (bad_offset != 0xffffffff)) { 178 if (jffs2_cleanmarker_oob(c) && (bad_offset != MTD_FAIL_ADDR_UNKNOWN)) {
179 /* We had a device-level failure to erase. Let's see if we've 179 /* We had a device-level failure to erase. Let's see if we've
180 failed too many times. */ 180 failed too many times. */
181 if (!jffs2_write_nand_badblock(c, jeb, bad_offset)) { 181 if (!jffs2_write_nand_badblock(c, jeb, bad_offset)) {
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 086c43830221..89e9b735d8df 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -207,6 +207,8 @@ int jffs2_statfs(struct dentry *dentry, struct kstatfs *buf)
207 buf->f_files = 0; 207 buf->f_files = 0;
208 buf->f_ffree = 0; 208 buf->f_ffree = 0;
209 buf->f_namelen = JFFS2_MAX_NAME_LEN; 209 buf->f_namelen = JFFS2_MAX_NAME_LEN;
210 buf->f_fsid.val[0] = JFFS2_SUPER_MAGIC;
211 buf->f_fsid.val[1] = c->mtd->index;
210 212
211 spin_lock(&c->erase_completion_lock); 213 spin_lock(&c->erase_completion_lock);
212 avail = c->dirty_size + c->free_size; 214 avail = c->dirty_size + c->free_size;
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
index d6fb115f5a07..ee5124ec319e 100644
--- a/include/linux/mtd/cfi.h
+++ b/include/linux/mtd/cfi.h
@@ -12,6 +12,7 @@
12#include <linux/mtd/flashchip.h> 12#include <linux/mtd/flashchip.h>
13#include <linux/mtd/map.h> 13#include <linux/mtd/map.h>
14#include <linux/mtd/cfi_endian.h> 14#include <linux/mtd/cfi_endian.h>
15#include <linux/mtd/xip.h>
15 16
16#ifdef CONFIG_MTD_CFI_I1 17#ifdef CONFIG_MTD_CFI_I1
17#define cfi_interleave(cfi) 1 18#define cfi_interleave(cfi) 1
@@ -430,7 +431,6 @@ static inline uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t
430{ 431{
431 map_word val; 432 map_word val;
432 uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, cfi_interleave(cfi), type); 433 uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, cfi_interleave(cfi), type);
433
434 val = cfi_build_cmd(cmd, map, cfi); 434 val = cfi_build_cmd(cmd, map, cfi);
435 435
436 if (prev_val) 436 if (prev_val)
@@ -483,6 +483,13 @@ static inline void cfi_udelay(int us)
483 } 483 }
484} 484}
485 485
486int __xipram cfi_qry_present(struct map_info *map, __u32 base,
487 struct cfi_private *cfi);
488int __xipram cfi_qry_mode_on(uint32_t base, struct map_info *map,
489 struct cfi_private *cfi);
490void __xipram cfi_qry_mode_off(uint32_t base, struct map_info *map,
491 struct cfi_private *cfi);
492
486struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t size, 493struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t size,
487 const char* name); 494 const char* name);
488struct cfi_fixup { 495struct cfi_fixup {
diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
index 08dd131301c1..d4f38c5fd44e 100644
--- a/include/linux/mtd/flashchip.h
+++ b/include/linux/mtd/flashchip.h
@@ -73,6 +73,10 @@ struct flchip {
73 int buffer_write_time; 73 int buffer_write_time;
74 int erase_time; 74 int erase_time;
75 75
76 int word_write_time_max;
77 int buffer_write_time_max;
78 int erase_time_max;
79
76 void *priv; 80 void *priv;
77}; 81};
78 82
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 922636548558..eae26bb6430a 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -25,8 +25,10 @@
25#define MTD_ERASE_DONE 0x08 25#define MTD_ERASE_DONE 0x08
26#define MTD_ERASE_FAILED 0x10 26#define MTD_ERASE_FAILED 0x10
27 27
28#define MTD_FAIL_ADDR_UNKNOWN 0xffffffff
29
28/* If the erase fails, fail_addr might indicate exactly which block failed. If 30/* If the erase fails, fail_addr might indicate exactly which block failed. If
29 fail_addr = 0xffffffff, the failure was not at the device level or was not 31 fail_addr = MTD_FAIL_ADDR_UNKNOWN, the failure was not at the device level or was not
30 specific to any particular block. */ 32 specific to any particular block. */
31struct erase_info { 33struct erase_info {
32 struct mtd_info *mtd; 34 struct mtd_info *mtd;
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 81774e5facf4..733d3f3b4eb8 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -248,6 +248,7 @@ struct nand_hw_control {
248 * @read_page_raw: function to read a raw page without ECC 248 * @read_page_raw: function to read a raw page without ECC
249 * @write_page_raw: function to write a raw page without ECC 249 * @write_page_raw: function to write a raw page without ECC
250 * @read_page: function to read a page according to the ecc generator requirements 250 * @read_page: function to read a page according to the ecc generator requirements
251 * @read_subpage: function to read parts of the page covered by ECC.
251 * @write_page: function to write a page according to the ecc generator requirements 252 * @write_page: function to write a page according to the ecc generator requirements
252 * @read_oob: function to read chip OOB data 253 * @read_oob: function to read chip OOB data
253 * @write_oob: function to write chip OOB data 254 * @write_oob: function to write chip OOB data
diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h
index d1b310c92eb4..0c6bbe28f38c 100644
--- a/include/linux/mtd/onenand_regs.h
+++ b/include/linux/mtd/onenand_regs.h
@@ -152,6 +152,8 @@
152#define ONENAND_SYS_CFG1_INT (1 << 6) 152#define ONENAND_SYS_CFG1_INT (1 << 6)
153#define ONENAND_SYS_CFG1_IOBE (1 << 5) 153#define ONENAND_SYS_CFG1_IOBE (1 << 5)
154#define ONENAND_SYS_CFG1_RDY_CONF (1 << 4) 154#define ONENAND_SYS_CFG1_RDY_CONF (1 << 4)
155#define ONENAND_SYS_CFG1_HF (1 << 2)
156#define ONENAND_SYS_CFG1_SYNC_WRITE (1 << 1)
155 157
156/* 158/*
157 * Controller Status Register F240h (R) 159 * Controller Status Register F240h (R)