ia64/linux-2.6.18-xen.hg

view drivers/mtd/chips/jedec_probe.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /*
2 Common Flash Interface probe code.
3 (C) 2000 Red Hat. GPL'd.
4 $Id: jedec_probe.c,v 1.66 2005/11/07 11:14:23 gleixner Exp $
5 See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
6 for the standard this probe goes back to.
8 Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
9 */
11 #include <linux/module.h>
12 #include <linux/init.h>
13 #include <linux/types.h>
14 #include <linux/kernel.h>
15 #include <asm/io.h>
16 #include <asm/byteorder.h>
17 #include <linux/errno.h>
18 #include <linux/slab.h>
19 #include <linux/interrupt.h>
20 #include <linux/init.h>
22 #include <linux/mtd/mtd.h>
23 #include <linux/mtd/map.h>
24 #include <linux/mtd/cfi.h>
25 #include <linux/mtd/gen_probe.h>
27 /* Manufacturers */
28 #define MANUFACTURER_AMD 0x0001
29 #define MANUFACTURER_ATMEL 0x001f
30 #define MANUFACTURER_FUJITSU 0x0004
31 #define MANUFACTURER_HYUNDAI 0x00AD
32 #define MANUFACTURER_INTEL 0x0089
33 #define MANUFACTURER_MACRONIX 0x00C2
34 #define MANUFACTURER_NEC 0x0010
35 #define MANUFACTURER_PMC 0x009D
36 #define MANUFACTURER_SHARP 0x00b0
37 #define MANUFACTURER_SST 0x00BF
38 #define MANUFACTURER_ST 0x0020
39 #define MANUFACTURER_TOSHIBA 0x0098
40 #define MANUFACTURER_WINBOND 0x00da
43 /* AMD */
44 #define AM29DL800BB 0x22C8
45 #define AM29DL800BT 0x224A
47 #define AM29F800BB 0x2258
48 #define AM29F800BT 0x22D6
49 #define AM29LV400BB 0x22BA
50 #define AM29LV400BT 0x22B9
51 #define AM29LV800BB 0x225B
52 #define AM29LV800BT 0x22DA
53 #define AM29LV160DT 0x22C4
54 #define AM29LV160DB 0x2249
55 #define AM29F017D 0x003D
56 #define AM29F016D 0x00AD
57 #define AM29F080 0x00D5
58 #define AM29F040 0x00A4
59 #define AM29LV040B 0x004F
60 #define AM29F032B 0x0041
61 #define AM29F002T 0x00B0
63 /* Atmel */
64 #define AT49BV512 0x0003
65 #define AT29LV512 0x003d
66 #define AT49BV16X 0x00C0
67 #define AT49BV16XT 0x00C2
68 #define AT49BV32X 0x00C8
69 #define AT49BV32XT 0x00C9
71 /* Fujitsu */
72 #define MBM29F040C 0x00A4
73 #define MBM29LV650UE 0x22D7
74 #define MBM29LV320TE 0x22F6
75 #define MBM29LV320BE 0x22F9
76 #define MBM29LV160TE 0x22C4
77 #define MBM29LV160BE 0x2249
78 #define MBM29LV800BA 0x225B
79 #define MBM29LV800TA 0x22DA
80 #define MBM29LV400TC 0x22B9
81 #define MBM29LV400BC 0x22BA
83 /* Hyundai */
84 #define HY29F002T 0x00B0
86 /* Intel */
87 #define I28F004B3T 0x00d4
88 #define I28F004B3B 0x00d5
89 #define I28F400B3T 0x8894
90 #define I28F400B3B 0x8895
91 #define I28F008S5 0x00a6
92 #define I28F016S5 0x00a0
93 #define I28F008SA 0x00a2
94 #define I28F008B3T 0x00d2
95 #define I28F008B3B 0x00d3
96 #define I28F800B3T 0x8892
97 #define I28F800B3B 0x8893
98 #define I28F016S3 0x00aa
99 #define I28F016B3T 0x00d0
100 #define I28F016B3B 0x00d1
101 #define I28F160B3T 0x8890
102 #define I28F160B3B 0x8891
103 #define I28F320B3T 0x8896
104 #define I28F320B3B 0x8897
105 #define I28F640B3T 0x8898
106 #define I28F640B3B 0x8899
107 #define I82802AB 0x00ad
108 #define I82802AC 0x00ac
110 /* Macronix */
111 #define MX29LV040C 0x004F
112 #define MX29LV160T 0x22C4
113 #define MX29LV160B 0x2249
114 #define MX29F040 0x00A4
115 #define MX29F016 0x00AD
116 #define MX29F002T 0x00B0
117 #define MX29F004T 0x0045
118 #define MX29F004B 0x0046
120 /* NEC */
121 #define UPD29F064115 0x221C
123 /* PMC */
124 #define PM49FL002 0x006D
125 #define PM49FL004 0x006E
126 #define PM49FL008 0x006A
128 /* Sharp */
129 #define LH28F640BF 0x00b0
131 /* ST - www.st.com */
132 #define M29W800DT 0x00D7
133 #define M29W800DB 0x005B
134 #define M29W160DT 0x22C4
135 #define M29W160DB 0x2249
136 #define M29W040B 0x00E3
137 #define M50FW040 0x002C
138 #define M50FW080 0x002D
139 #define M50FW016 0x002E
140 #define M50LPW080 0x002F
142 /* SST */
143 #define SST29EE020 0x0010
144 #define SST29LE020 0x0012
145 #define SST29EE512 0x005d
146 #define SST29LE512 0x003d
147 #define SST39LF800 0x2781
148 #define SST39LF160 0x2782
149 #define SST39VF1601 0x234b
150 #define SST39LF512 0x00D4
151 #define SST39LF010 0x00D5
152 #define SST39LF020 0x00D6
153 #define SST39LF040 0x00D7
154 #define SST39SF010A 0x00B5
155 #define SST39SF020A 0x00B6
156 #define SST49LF004B 0x0060
157 #define SST49LF008A 0x005a
158 #define SST49LF030A 0x001C
159 #define SST49LF040A 0x0051
160 #define SST49LF080A 0x005B
162 /* Toshiba */
163 #define TC58FVT160 0x00C2
164 #define TC58FVB160 0x0043
165 #define TC58FVT321 0x009A
166 #define TC58FVB321 0x009C
167 #define TC58FVT641 0x0093
168 #define TC58FVB641 0x0095
170 /* Winbond */
171 #define W49V002A 0x00b0
174 /*
175 * Unlock address sets for AMD command sets.
176 * Intel command sets use the MTD_UADDR_UNNECESSARY.
177 * Each identifier, except MTD_UADDR_UNNECESSARY, and
178 * MTD_UADDR_NO_SUPPORT must be defined below in unlock_addrs[].
179 * MTD_UADDR_NOT_SUPPORTED must be 0 so that structure
180 * initialization need not require initializing all of the
181 * unlock addresses for all bit widths.
182 */
183 enum uaddr {
184 MTD_UADDR_NOT_SUPPORTED = 0, /* data width not supported */
185 MTD_UADDR_0x0555_0x02AA,
186 MTD_UADDR_0x0555_0x0AAA,
187 MTD_UADDR_0x5555_0x2AAA,
188 MTD_UADDR_0x0AAA_0x0555,
189 MTD_UADDR_DONT_CARE, /* Requires an arbitrary address */
190 MTD_UADDR_UNNECESSARY, /* Does not require any address */
191 };
194 struct unlock_addr {
195 u32 addr1;
196 u32 addr2;
197 };
200 /*
201 * I don't like the fact that the first entry in unlock_addrs[]
202 * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore,
203 * should not be used. The problem is that structures with
204 * initializers have extra fields initialized to 0. It is _very_
205 * desireable to have the unlock address entries for unsupported
206 * data widths automatically initialized - that means that
207 * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here
208 * must go unused.
209 */
210 static const struct unlock_addr unlock_addrs[] = {
211 [MTD_UADDR_NOT_SUPPORTED] = {
212 .addr1 = 0xffff,
213 .addr2 = 0xffff
214 },
216 [MTD_UADDR_0x0555_0x02AA] = {
217 .addr1 = 0x0555,
218 .addr2 = 0x02aa
219 },
221 [MTD_UADDR_0x0555_0x0AAA] = {
222 .addr1 = 0x0555,
223 .addr2 = 0x0aaa
224 },
226 [MTD_UADDR_0x5555_0x2AAA] = {
227 .addr1 = 0x5555,
228 .addr2 = 0x2aaa
229 },
231 [MTD_UADDR_0x0AAA_0x0555] = {
232 .addr1 = 0x0AAA,
233 .addr2 = 0x0555
234 },
236 [MTD_UADDR_DONT_CARE] = {
237 .addr1 = 0x0000, /* Doesn't matter which address */
238 .addr2 = 0x0000 /* is used - must be last entry */
239 },
241 [MTD_UADDR_UNNECESSARY] = {
242 .addr1 = 0x0000,
243 .addr2 = 0x0000
244 }
245 };
248 struct amd_flash_info {
249 const __u16 mfr_id;
250 const __u16 dev_id;
251 const char *name;
252 const int DevSize;
253 const int NumEraseRegions;
254 const int CmdSet;
255 const __u8 uaddr[4]; /* unlock addrs for 8, 16, 32, 64 */
256 const ulong regions[6];
257 };
259 #define ERASEINFO(size,blocks) (size<<8)|(blocks-1)
261 #define SIZE_64KiB 16
262 #define SIZE_128KiB 17
263 #define SIZE_256KiB 18
264 #define SIZE_512KiB 19
265 #define SIZE_1MiB 20
266 #define SIZE_2MiB 21
267 #define SIZE_4MiB 22
268 #define SIZE_8MiB 23
271 /*
272 * Please keep this list ordered by manufacturer!
273 * Fortunately, the list isn't searched often and so a
274 * slow, linear search isn't so bad.
275 */
276 static const struct amd_flash_info jedec_table[] = {
277 {
278 .mfr_id = MANUFACTURER_AMD,
279 .dev_id = AM29F032B,
280 .name = "AMD AM29F032B",
281 .uaddr = {
282 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
283 },
284 .DevSize = SIZE_4MiB,
285 .CmdSet = P_ID_AMD_STD,
286 .NumEraseRegions= 1,
287 .regions = {
288 ERASEINFO(0x10000,64)
289 }
290 }, {
291 .mfr_id = MANUFACTURER_AMD,
292 .dev_id = AM29LV160DT,
293 .name = "AMD AM29LV160DT",
294 .uaddr = {
295 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
296 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
297 },
298 .DevSize = SIZE_2MiB,
299 .CmdSet = P_ID_AMD_STD,
300 .NumEraseRegions= 4,
301 .regions = {
302 ERASEINFO(0x10000,31),
303 ERASEINFO(0x08000,1),
304 ERASEINFO(0x02000,2),
305 ERASEINFO(0x04000,1)
306 }
307 }, {
308 .mfr_id = MANUFACTURER_AMD,
309 .dev_id = AM29LV160DB,
310 .name = "AMD AM29LV160DB",
311 .uaddr = {
312 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
313 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
314 },
315 .DevSize = SIZE_2MiB,
316 .CmdSet = P_ID_AMD_STD,
317 .NumEraseRegions= 4,
318 .regions = {
319 ERASEINFO(0x04000,1),
320 ERASEINFO(0x02000,2),
321 ERASEINFO(0x08000,1),
322 ERASEINFO(0x10000,31)
323 }
324 }, {
325 .mfr_id = MANUFACTURER_AMD,
326 .dev_id = AM29LV400BB,
327 .name = "AMD AM29LV400BB",
328 .uaddr = {
329 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
330 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
331 },
332 .DevSize = SIZE_512KiB,
333 .CmdSet = P_ID_AMD_STD,
334 .NumEraseRegions= 4,
335 .regions = {
336 ERASEINFO(0x04000,1),
337 ERASEINFO(0x02000,2),
338 ERASEINFO(0x08000,1),
339 ERASEINFO(0x10000,7)
340 }
341 }, {
342 .mfr_id = MANUFACTURER_AMD,
343 .dev_id = AM29LV400BT,
344 .name = "AMD AM29LV400BT",
345 .uaddr = {
346 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
347 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
348 },
349 .DevSize = SIZE_512KiB,
350 .CmdSet = P_ID_AMD_STD,
351 .NumEraseRegions= 4,
352 .regions = {
353 ERASEINFO(0x10000,7),
354 ERASEINFO(0x08000,1),
355 ERASEINFO(0x02000,2),
356 ERASEINFO(0x04000,1)
357 }
358 }, {
359 .mfr_id = MANUFACTURER_AMD,
360 .dev_id = AM29LV800BB,
361 .name = "AMD AM29LV800BB",
362 .uaddr = {
363 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
364 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
365 },
366 .DevSize = SIZE_1MiB,
367 .CmdSet = P_ID_AMD_STD,
368 .NumEraseRegions= 4,
369 .regions = {
370 ERASEINFO(0x04000,1),
371 ERASEINFO(0x02000,2),
372 ERASEINFO(0x08000,1),
373 ERASEINFO(0x10000,15),
374 }
375 }, {
376 /* add DL */
377 .mfr_id = MANUFACTURER_AMD,
378 .dev_id = AM29DL800BB,
379 .name = "AMD AM29DL800BB",
380 .uaddr = {
381 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
382 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
383 },
384 .DevSize = SIZE_1MiB,
385 .CmdSet = P_ID_AMD_STD,
386 .NumEraseRegions= 6,
387 .regions = {
388 ERASEINFO(0x04000,1),
389 ERASEINFO(0x08000,1),
390 ERASEINFO(0x02000,4),
391 ERASEINFO(0x08000,1),
392 ERASEINFO(0x04000,1),
393 ERASEINFO(0x10000,14)
394 }
395 }, {
396 .mfr_id = MANUFACTURER_AMD,
397 .dev_id = AM29DL800BT,
398 .name = "AMD AM29DL800BT",
399 .uaddr = {
400 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
401 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
402 },
403 .DevSize = SIZE_1MiB,
404 .CmdSet = P_ID_AMD_STD,
405 .NumEraseRegions= 6,
406 .regions = {
407 ERASEINFO(0x10000,14),
408 ERASEINFO(0x04000,1),
409 ERASEINFO(0x08000,1),
410 ERASEINFO(0x02000,4),
411 ERASEINFO(0x08000,1),
412 ERASEINFO(0x04000,1)
413 }
414 }, {
415 .mfr_id = MANUFACTURER_AMD,
416 .dev_id = AM29F800BB,
417 .name = "AMD AM29F800BB",
418 .uaddr = {
419 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
420 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
421 },
422 .DevSize = SIZE_1MiB,
423 .CmdSet = P_ID_AMD_STD,
424 .NumEraseRegions= 4,
425 .regions = {
426 ERASEINFO(0x04000,1),
427 ERASEINFO(0x02000,2),
428 ERASEINFO(0x08000,1),
429 ERASEINFO(0x10000,15),
430 }
431 }, {
432 .mfr_id = MANUFACTURER_AMD,
433 .dev_id = AM29LV800BT,
434 .name = "AMD AM29LV800BT",
435 .uaddr = {
436 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
437 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
438 },
439 .DevSize = SIZE_1MiB,
440 .CmdSet = P_ID_AMD_STD,
441 .NumEraseRegions= 4,
442 .regions = {
443 ERASEINFO(0x10000,15),
444 ERASEINFO(0x08000,1),
445 ERASEINFO(0x02000,2),
446 ERASEINFO(0x04000,1)
447 }
448 }, {
449 .mfr_id = MANUFACTURER_AMD,
450 .dev_id = AM29F800BT,
451 .name = "AMD AM29F800BT",
452 .uaddr = {
453 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
454 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
455 },
456 .DevSize = SIZE_1MiB,
457 .CmdSet = P_ID_AMD_STD,
458 .NumEraseRegions= 4,
459 .regions = {
460 ERASEINFO(0x10000,15),
461 ERASEINFO(0x08000,1),
462 ERASEINFO(0x02000,2),
463 ERASEINFO(0x04000,1)
464 }
465 }, {
466 .mfr_id = MANUFACTURER_AMD,
467 .dev_id = AM29F017D,
468 .name = "AMD AM29F017D",
469 .uaddr = {
470 [0] = MTD_UADDR_DONT_CARE /* x8 */
471 },
472 .DevSize = SIZE_2MiB,
473 .CmdSet = P_ID_AMD_STD,
474 .NumEraseRegions= 1,
475 .regions = {
476 ERASEINFO(0x10000,32),
477 }
478 }, {
479 .mfr_id = MANUFACTURER_AMD,
480 .dev_id = AM29F016D,
481 .name = "AMD AM29F016D",
482 .uaddr = {
483 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
484 },
485 .DevSize = SIZE_2MiB,
486 .CmdSet = P_ID_AMD_STD,
487 .NumEraseRegions= 1,
488 .regions = {
489 ERASEINFO(0x10000,32),
490 }
491 }, {
492 .mfr_id = MANUFACTURER_AMD,
493 .dev_id = AM29F080,
494 .name = "AMD AM29F080",
495 .uaddr = {
496 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
497 },
498 .DevSize = SIZE_1MiB,
499 .CmdSet = P_ID_AMD_STD,
500 .NumEraseRegions= 1,
501 .regions = {
502 ERASEINFO(0x10000,16),
503 }
504 }, {
505 .mfr_id = MANUFACTURER_AMD,
506 .dev_id = AM29F040,
507 .name = "AMD AM29F040",
508 .uaddr = {
509 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
510 },
511 .DevSize = SIZE_512KiB,
512 .CmdSet = P_ID_AMD_STD,
513 .NumEraseRegions= 1,
514 .regions = {
515 ERASEINFO(0x10000,8),
516 }
517 }, {
518 .mfr_id = MANUFACTURER_AMD,
519 .dev_id = AM29LV040B,
520 .name = "AMD AM29LV040B",
521 .uaddr = {
522 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
523 },
524 .DevSize = SIZE_512KiB,
525 .CmdSet = P_ID_AMD_STD,
526 .NumEraseRegions= 1,
527 .regions = {
528 ERASEINFO(0x10000,8),
529 }
530 }, {
531 .mfr_id = MANUFACTURER_AMD,
532 .dev_id = AM29F002T,
533 .name = "AMD AM29F002T",
534 .uaddr = {
535 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
536 },
537 .DevSize = SIZE_256KiB,
538 .CmdSet = P_ID_AMD_STD,
539 .NumEraseRegions= 4,
540 .regions = {
541 ERASEINFO(0x10000,3),
542 ERASEINFO(0x08000,1),
543 ERASEINFO(0x02000,2),
544 ERASEINFO(0x04000,1),
545 }
546 }, {
547 .mfr_id = MANUFACTURER_ATMEL,
548 .dev_id = AT49BV512,
549 .name = "Atmel AT49BV512",
550 .uaddr = {
551 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
552 },
553 .DevSize = SIZE_64KiB,
554 .CmdSet = P_ID_AMD_STD,
555 .NumEraseRegions= 1,
556 .regions = {
557 ERASEINFO(0x10000,1)
558 }
559 }, {
560 .mfr_id = MANUFACTURER_ATMEL,
561 .dev_id = AT29LV512,
562 .name = "Atmel AT29LV512",
563 .uaddr = {
564 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
565 },
566 .DevSize = SIZE_64KiB,
567 .CmdSet = P_ID_AMD_STD,
568 .NumEraseRegions= 1,
569 .regions = {
570 ERASEINFO(0x80,256),
571 ERASEINFO(0x80,256)
572 }
573 }, {
574 .mfr_id = MANUFACTURER_ATMEL,
575 .dev_id = AT49BV16X,
576 .name = "Atmel AT49BV16X",
577 .uaddr = {
578 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
579 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
580 },
581 .DevSize = SIZE_2MiB,
582 .CmdSet = P_ID_AMD_STD,
583 .NumEraseRegions= 2,
584 .regions = {
585 ERASEINFO(0x02000,8),
586 ERASEINFO(0x10000,31)
587 }
588 }, {
589 .mfr_id = MANUFACTURER_ATMEL,
590 .dev_id = AT49BV16XT,
591 .name = "Atmel AT49BV16XT",
592 .uaddr = {
593 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
594 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
595 },
596 .DevSize = SIZE_2MiB,
597 .CmdSet = P_ID_AMD_STD,
598 .NumEraseRegions= 2,
599 .regions = {
600 ERASEINFO(0x10000,31),
601 ERASEINFO(0x02000,8)
602 }
603 }, {
604 .mfr_id = MANUFACTURER_ATMEL,
605 .dev_id = AT49BV32X,
606 .name = "Atmel AT49BV32X",
607 .uaddr = {
608 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
609 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
610 },
611 .DevSize = SIZE_4MiB,
612 .CmdSet = P_ID_AMD_STD,
613 .NumEraseRegions= 2,
614 .regions = {
615 ERASEINFO(0x02000,8),
616 ERASEINFO(0x10000,63)
617 }
618 }, {
619 .mfr_id = MANUFACTURER_ATMEL,
620 .dev_id = AT49BV32XT,
621 .name = "Atmel AT49BV32XT",
622 .uaddr = {
623 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
624 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
625 },
626 .DevSize = SIZE_4MiB,
627 .CmdSet = P_ID_AMD_STD,
628 .NumEraseRegions= 2,
629 .regions = {
630 ERASEINFO(0x10000,63),
631 ERASEINFO(0x02000,8)
632 }
633 }, {
634 .mfr_id = MANUFACTURER_FUJITSU,
635 .dev_id = MBM29F040C,
636 .name = "Fujitsu MBM29F040C",
637 .uaddr = {
638 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
639 },
640 .DevSize = SIZE_512KiB,
641 .CmdSet = P_ID_AMD_STD,
642 .NumEraseRegions= 1,
643 .regions = {
644 ERASEINFO(0x10000,8)
645 }
646 }, {
647 .mfr_id = MANUFACTURER_FUJITSU,
648 .dev_id = MBM29LV650UE,
649 .name = "Fujitsu MBM29LV650UE",
650 .uaddr = {
651 [0] = MTD_UADDR_DONT_CARE /* x16 */
652 },
653 .DevSize = SIZE_8MiB,
654 .CmdSet = P_ID_AMD_STD,
655 .NumEraseRegions= 1,
656 .regions = {
657 ERASEINFO(0x10000,128)
658 }
659 }, {
660 .mfr_id = MANUFACTURER_FUJITSU,
661 .dev_id = MBM29LV320TE,
662 .name = "Fujitsu MBM29LV320TE",
663 .uaddr = {
664 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
665 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
666 },
667 .DevSize = SIZE_4MiB,
668 .CmdSet = P_ID_AMD_STD,
669 .NumEraseRegions= 2,
670 .regions = {
671 ERASEINFO(0x10000,63),
672 ERASEINFO(0x02000,8)
673 }
674 }, {
675 .mfr_id = MANUFACTURER_FUJITSU,
676 .dev_id = MBM29LV320BE,
677 .name = "Fujitsu MBM29LV320BE",
678 .uaddr = {
679 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
680 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
681 },
682 .DevSize = SIZE_4MiB,
683 .CmdSet = P_ID_AMD_STD,
684 .NumEraseRegions= 2,
685 .regions = {
686 ERASEINFO(0x02000,8),
687 ERASEINFO(0x10000,63)
688 }
689 }, {
690 .mfr_id = MANUFACTURER_FUJITSU,
691 .dev_id = MBM29LV160TE,
692 .name = "Fujitsu MBM29LV160TE",
693 .uaddr = {
694 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
695 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
696 },
697 .DevSize = SIZE_2MiB,
698 .CmdSet = P_ID_AMD_STD,
699 .NumEraseRegions= 4,
700 .regions = {
701 ERASEINFO(0x10000,31),
702 ERASEINFO(0x08000,1),
703 ERASEINFO(0x02000,2),
704 ERASEINFO(0x04000,1)
705 }
706 }, {
707 .mfr_id = MANUFACTURER_FUJITSU,
708 .dev_id = MBM29LV160BE,
709 .name = "Fujitsu MBM29LV160BE",
710 .uaddr = {
711 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
712 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
713 },
714 .DevSize = SIZE_2MiB,
715 .CmdSet = P_ID_AMD_STD,
716 .NumEraseRegions= 4,
717 .regions = {
718 ERASEINFO(0x04000,1),
719 ERASEINFO(0x02000,2),
720 ERASEINFO(0x08000,1),
721 ERASEINFO(0x10000,31)
722 }
723 }, {
724 .mfr_id = MANUFACTURER_FUJITSU,
725 .dev_id = MBM29LV800BA,
726 .name = "Fujitsu MBM29LV800BA",
727 .uaddr = {
728 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
729 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
730 },
731 .DevSize = SIZE_1MiB,
732 .CmdSet = P_ID_AMD_STD,
733 .NumEraseRegions= 4,
734 .regions = {
735 ERASEINFO(0x04000,1),
736 ERASEINFO(0x02000,2),
737 ERASEINFO(0x08000,1),
738 ERASEINFO(0x10000,15)
739 }
740 }, {
741 .mfr_id = MANUFACTURER_FUJITSU,
742 .dev_id = MBM29LV800TA,
743 .name = "Fujitsu MBM29LV800TA",
744 .uaddr = {
745 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
746 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
747 },
748 .DevSize = SIZE_1MiB,
749 .CmdSet = P_ID_AMD_STD,
750 .NumEraseRegions= 4,
751 .regions = {
752 ERASEINFO(0x10000,15),
753 ERASEINFO(0x08000,1),
754 ERASEINFO(0x02000,2),
755 ERASEINFO(0x04000,1)
756 }
757 }, {
758 .mfr_id = MANUFACTURER_FUJITSU,
759 .dev_id = MBM29LV400BC,
760 .name = "Fujitsu MBM29LV400BC",
761 .uaddr = {
762 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
763 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
764 },
765 .DevSize = SIZE_512KiB,
766 .CmdSet = P_ID_AMD_STD,
767 .NumEraseRegions= 4,
768 .regions = {
769 ERASEINFO(0x04000,1),
770 ERASEINFO(0x02000,2),
771 ERASEINFO(0x08000,1),
772 ERASEINFO(0x10000,7)
773 }
774 }, {
775 .mfr_id = MANUFACTURER_FUJITSU,
776 .dev_id = MBM29LV400TC,
777 .name = "Fujitsu MBM29LV400TC",
778 .uaddr = {
779 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
780 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
781 },
782 .DevSize = SIZE_512KiB,
783 .CmdSet = P_ID_AMD_STD,
784 .NumEraseRegions= 4,
785 .regions = {
786 ERASEINFO(0x10000,7),
787 ERASEINFO(0x08000,1),
788 ERASEINFO(0x02000,2),
789 ERASEINFO(0x04000,1)
790 }
791 }, {
792 .mfr_id = MANUFACTURER_HYUNDAI,
793 .dev_id = HY29F002T,
794 .name = "Hyundai HY29F002T",
795 .uaddr = {
796 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
797 },
798 .DevSize = SIZE_256KiB,
799 .CmdSet = P_ID_AMD_STD,
800 .NumEraseRegions= 4,
801 .regions = {
802 ERASEINFO(0x10000,3),
803 ERASEINFO(0x08000,1),
804 ERASEINFO(0x02000,2),
805 ERASEINFO(0x04000,1),
806 }
807 }, {
808 .mfr_id = MANUFACTURER_INTEL,
809 .dev_id = I28F004B3B,
810 .name = "Intel 28F004B3B",
811 .uaddr = {
812 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
813 },
814 .DevSize = SIZE_512KiB,
815 .CmdSet = P_ID_INTEL_STD,
816 .NumEraseRegions= 2,
817 .regions = {
818 ERASEINFO(0x02000, 8),
819 ERASEINFO(0x10000, 7),
820 }
821 }, {
822 .mfr_id = MANUFACTURER_INTEL,
823 .dev_id = I28F004B3T,
824 .name = "Intel 28F004B3T",
825 .uaddr = {
826 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
827 },
828 .DevSize = SIZE_512KiB,
829 .CmdSet = P_ID_INTEL_STD,
830 .NumEraseRegions= 2,
831 .regions = {
832 ERASEINFO(0x10000, 7),
833 ERASEINFO(0x02000, 8),
834 }
835 }, {
836 .mfr_id = MANUFACTURER_INTEL,
837 .dev_id = I28F400B3B,
838 .name = "Intel 28F400B3B",
839 .uaddr = {
840 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
841 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
842 },
843 .DevSize = SIZE_512KiB,
844 .CmdSet = P_ID_INTEL_STD,
845 .NumEraseRegions= 2,
846 .regions = {
847 ERASEINFO(0x02000, 8),
848 ERASEINFO(0x10000, 7),
849 }
850 }, {
851 .mfr_id = MANUFACTURER_INTEL,
852 .dev_id = I28F400B3T,
853 .name = "Intel 28F400B3T",
854 .uaddr = {
855 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
856 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
857 },
858 .DevSize = SIZE_512KiB,
859 .CmdSet = P_ID_INTEL_STD,
860 .NumEraseRegions= 2,
861 .regions = {
862 ERASEINFO(0x10000, 7),
863 ERASEINFO(0x02000, 8),
864 }
865 }, {
866 .mfr_id = MANUFACTURER_INTEL,
867 .dev_id = I28F008B3B,
868 .name = "Intel 28F008B3B",
869 .uaddr = {
870 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
871 },
872 .DevSize = SIZE_1MiB,
873 .CmdSet = P_ID_INTEL_STD,
874 .NumEraseRegions= 2,
875 .regions = {
876 ERASEINFO(0x02000, 8),
877 ERASEINFO(0x10000, 15),
878 }
879 }, {
880 .mfr_id = MANUFACTURER_INTEL,
881 .dev_id = I28F008B3T,
882 .name = "Intel 28F008B3T",
883 .uaddr = {
884 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
885 },
886 .DevSize = SIZE_1MiB,
887 .CmdSet = P_ID_INTEL_STD,
888 .NumEraseRegions= 2,
889 .regions = {
890 ERASEINFO(0x10000, 15),
891 ERASEINFO(0x02000, 8),
892 }
893 }, {
894 .mfr_id = MANUFACTURER_INTEL,
895 .dev_id = I28F008S5,
896 .name = "Intel 28F008S5",
897 .uaddr = {
898 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
899 },
900 .DevSize = SIZE_1MiB,
901 .CmdSet = P_ID_INTEL_EXT,
902 .NumEraseRegions= 1,
903 .regions = {
904 ERASEINFO(0x10000,16),
905 }
906 }, {
907 .mfr_id = MANUFACTURER_INTEL,
908 .dev_id = I28F016S5,
909 .name = "Intel 28F016S5",
910 .uaddr = {
911 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
912 },
913 .DevSize = SIZE_2MiB,
914 .CmdSet = P_ID_INTEL_EXT,
915 .NumEraseRegions= 1,
916 .regions = {
917 ERASEINFO(0x10000,32),
918 }
919 }, {
920 .mfr_id = MANUFACTURER_INTEL,
921 .dev_id = I28F008SA,
922 .name = "Intel 28F008SA",
923 .uaddr = {
924 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
925 },
926 .DevSize = SIZE_1MiB,
927 .CmdSet = P_ID_INTEL_STD,
928 .NumEraseRegions= 1,
929 .regions = {
930 ERASEINFO(0x10000, 16),
931 }
932 }, {
933 .mfr_id = MANUFACTURER_INTEL,
934 .dev_id = I28F800B3B,
935 .name = "Intel 28F800B3B",
936 .uaddr = {
937 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
938 },
939 .DevSize = SIZE_1MiB,
940 .CmdSet = P_ID_INTEL_STD,
941 .NumEraseRegions= 2,
942 .regions = {
943 ERASEINFO(0x02000, 8),
944 ERASEINFO(0x10000, 15),
945 }
946 }, {
947 .mfr_id = MANUFACTURER_INTEL,
948 .dev_id = I28F800B3T,
949 .name = "Intel 28F800B3T",
950 .uaddr = {
951 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
952 },
953 .DevSize = SIZE_1MiB,
954 .CmdSet = P_ID_INTEL_STD,
955 .NumEraseRegions= 2,
956 .regions = {
957 ERASEINFO(0x10000, 15),
958 ERASEINFO(0x02000, 8),
959 }
960 }, {
961 .mfr_id = MANUFACTURER_INTEL,
962 .dev_id = I28F016B3B,
963 .name = "Intel 28F016B3B",
964 .uaddr = {
965 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
966 },
967 .DevSize = SIZE_2MiB,
968 .CmdSet = P_ID_INTEL_STD,
969 .NumEraseRegions= 2,
970 .regions = {
971 ERASEINFO(0x02000, 8),
972 ERASEINFO(0x10000, 31),
973 }
974 }, {
975 .mfr_id = MANUFACTURER_INTEL,
976 .dev_id = I28F016S3,
977 .name = "Intel I28F016S3",
978 .uaddr = {
979 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
980 },
981 .DevSize = SIZE_2MiB,
982 .CmdSet = P_ID_INTEL_STD,
983 .NumEraseRegions= 1,
984 .regions = {
985 ERASEINFO(0x10000, 32),
986 }
987 }, {
988 .mfr_id = MANUFACTURER_INTEL,
989 .dev_id = I28F016B3T,
990 .name = "Intel 28F016B3T",
991 .uaddr = {
992 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
993 },
994 .DevSize = SIZE_2MiB,
995 .CmdSet = P_ID_INTEL_STD,
996 .NumEraseRegions= 2,
997 .regions = {
998 ERASEINFO(0x10000, 31),
999 ERASEINFO(0x02000, 8),
1001 }, {
1002 .mfr_id = MANUFACTURER_INTEL,
1003 .dev_id = I28F160B3B,
1004 .name = "Intel 28F160B3B",
1005 .uaddr = {
1006 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
1007 },
1008 .DevSize = SIZE_2MiB,
1009 .CmdSet = P_ID_INTEL_STD,
1010 .NumEraseRegions= 2,
1011 .regions = {
1012 ERASEINFO(0x02000, 8),
1013 ERASEINFO(0x10000, 31),
1015 }, {
1016 .mfr_id = MANUFACTURER_INTEL,
1017 .dev_id = I28F160B3T,
1018 .name = "Intel 28F160B3T",
1019 .uaddr = {
1020 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
1021 },
1022 .DevSize = SIZE_2MiB,
1023 .CmdSet = P_ID_INTEL_STD,
1024 .NumEraseRegions= 2,
1025 .regions = {
1026 ERASEINFO(0x10000, 31),
1027 ERASEINFO(0x02000, 8),
1029 }, {
1030 .mfr_id = MANUFACTURER_INTEL,
1031 .dev_id = I28F320B3B,
1032 .name = "Intel 28F320B3B",
1033 .uaddr = {
1034 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
1035 },
1036 .DevSize = SIZE_4MiB,
1037 .CmdSet = P_ID_INTEL_STD,
1038 .NumEraseRegions= 2,
1039 .regions = {
1040 ERASEINFO(0x02000, 8),
1041 ERASEINFO(0x10000, 63),
1043 }, {
1044 .mfr_id = MANUFACTURER_INTEL,
1045 .dev_id = I28F320B3T,
1046 .name = "Intel 28F320B3T",
1047 .uaddr = {
1048 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
1049 },
1050 .DevSize = SIZE_4MiB,
1051 .CmdSet = P_ID_INTEL_STD,
1052 .NumEraseRegions= 2,
1053 .regions = {
1054 ERASEINFO(0x10000, 63),
1055 ERASEINFO(0x02000, 8),
1057 }, {
1058 .mfr_id = MANUFACTURER_INTEL,
1059 .dev_id = I28F640B3B,
1060 .name = "Intel 28F640B3B",
1061 .uaddr = {
1062 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
1063 },
1064 .DevSize = SIZE_8MiB,
1065 .CmdSet = P_ID_INTEL_STD,
1066 .NumEraseRegions= 2,
1067 .regions = {
1068 ERASEINFO(0x02000, 8),
1069 ERASEINFO(0x10000, 127),
1071 }, {
1072 .mfr_id = MANUFACTURER_INTEL,
1073 .dev_id = I28F640B3T,
1074 .name = "Intel 28F640B3T",
1075 .uaddr = {
1076 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
1077 },
1078 .DevSize = SIZE_8MiB,
1079 .CmdSet = P_ID_INTEL_STD,
1080 .NumEraseRegions= 2,
1081 .regions = {
1082 ERASEINFO(0x10000, 127),
1083 ERASEINFO(0x02000, 8),
1085 }, {
1086 .mfr_id = MANUFACTURER_INTEL,
1087 .dev_id = I82802AB,
1088 .name = "Intel 82802AB",
1089 .uaddr = {
1090 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
1091 },
1092 .DevSize = SIZE_512KiB,
1093 .CmdSet = P_ID_INTEL_EXT,
1094 .NumEraseRegions= 1,
1095 .regions = {
1096 ERASEINFO(0x10000,8),
1098 }, {
1099 .mfr_id = MANUFACTURER_INTEL,
1100 .dev_id = I82802AC,
1101 .name = "Intel 82802AC",
1102 .uaddr = {
1103 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
1104 },
1105 .DevSize = SIZE_1MiB,
1106 .CmdSet = P_ID_INTEL_EXT,
1107 .NumEraseRegions= 1,
1108 .regions = {
1109 ERASEINFO(0x10000,16),
1111 }, {
1112 .mfr_id = MANUFACTURER_MACRONIX,
1113 .dev_id = MX29LV040C,
1114 .name = "Macronix MX29LV040C",
1115 .uaddr = {
1116 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
1117 },
1118 .DevSize = SIZE_512KiB,
1119 .CmdSet = P_ID_AMD_STD,
1120 .NumEraseRegions= 1,
1121 .regions = {
1122 ERASEINFO(0x10000,8),
1124 }, {
1125 .mfr_id = MANUFACTURER_MACRONIX,
1126 .dev_id = MX29LV160T,
1127 .name = "MXIC MX29LV160T",
1128 .uaddr = {
1129 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1130 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1131 },
1132 .DevSize = SIZE_2MiB,
1133 .CmdSet = P_ID_AMD_STD,
1134 .NumEraseRegions= 4,
1135 .regions = {
1136 ERASEINFO(0x10000,31),
1137 ERASEINFO(0x08000,1),
1138 ERASEINFO(0x02000,2),
1139 ERASEINFO(0x04000,1)
1141 }, {
1142 .mfr_id = MANUFACTURER_NEC,
1143 .dev_id = UPD29F064115,
1144 .name = "NEC uPD29F064115",
1145 .uaddr = {
1146 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
1147 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1148 },
1149 .DevSize = SIZE_8MiB,
1150 .CmdSet = P_ID_AMD_STD,
1151 .NumEraseRegions= 3,
1152 .regions = {
1153 ERASEINFO(0x2000,8),
1154 ERASEINFO(0x10000,126),
1155 ERASEINFO(0x2000,8),
1157 }, {
1158 .mfr_id = MANUFACTURER_MACRONIX,
1159 .dev_id = MX29LV160B,
1160 .name = "MXIC MX29LV160B",
1161 .uaddr = {
1162 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1163 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1164 },
1165 .DevSize = SIZE_2MiB,
1166 .CmdSet = P_ID_AMD_STD,
1167 .NumEraseRegions= 4,
1168 .regions = {
1169 ERASEINFO(0x04000,1),
1170 ERASEINFO(0x02000,2),
1171 ERASEINFO(0x08000,1),
1172 ERASEINFO(0x10000,31)
1174 }, {
1175 .mfr_id = MANUFACTURER_MACRONIX,
1176 .dev_id = MX29F040,
1177 .name = "Macronix MX29F040",
1178 .uaddr = {
1179 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1180 },
1181 .DevSize = SIZE_512KiB,
1182 .CmdSet = P_ID_AMD_STD,
1183 .NumEraseRegions= 1,
1184 .regions = {
1185 ERASEINFO(0x10000,8),
1187 }, {
1188 .mfr_id = MANUFACTURER_MACRONIX,
1189 .dev_id = MX29F016,
1190 .name = "Macronix MX29F016",
1191 .uaddr = {
1192 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1193 },
1194 .DevSize = SIZE_2MiB,
1195 .CmdSet = P_ID_AMD_STD,
1196 .NumEraseRegions= 1,
1197 .regions = {
1198 ERASEINFO(0x10000,32),
1200 }, {
1201 .mfr_id = MANUFACTURER_MACRONIX,
1202 .dev_id = MX29F004T,
1203 .name = "Macronix MX29F004T",
1204 .uaddr = {
1205 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1206 },
1207 .DevSize = SIZE_512KiB,
1208 .CmdSet = P_ID_AMD_STD,
1209 .NumEraseRegions= 4,
1210 .regions = {
1211 ERASEINFO(0x10000,7),
1212 ERASEINFO(0x08000,1),
1213 ERASEINFO(0x02000,2),
1214 ERASEINFO(0x04000,1),
1216 }, {
1217 .mfr_id = MANUFACTURER_MACRONIX,
1218 .dev_id = MX29F004B,
1219 .name = "Macronix MX29F004B",
1220 .uaddr = {
1221 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1222 },
1223 .DevSize = SIZE_512KiB,
1224 .CmdSet = P_ID_AMD_STD,
1225 .NumEraseRegions= 4,
1226 .regions = {
1227 ERASEINFO(0x04000,1),
1228 ERASEINFO(0x02000,2),
1229 ERASEINFO(0x08000,1),
1230 ERASEINFO(0x10000,7),
1232 }, {
1233 .mfr_id = MANUFACTURER_MACRONIX,
1234 .dev_id = MX29F002T,
1235 .name = "Macronix MX29F002T",
1236 .uaddr = {
1237 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1238 },
1239 .DevSize = SIZE_256KiB,
1240 .CmdSet = P_ID_AMD_STD,
1241 .NumEraseRegions= 4,
1242 .regions = {
1243 ERASEINFO(0x10000,3),
1244 ERASEINFO(0x08000,1),
1245 ERASEINFO(0x02000,2),
1246 ERASEINFO(0x04000,1),
1248 }, {
1249 .mfr_id = MANUFACTURER_PMC,
1250 .dev_id = PM49FL002,
1251 .name = "PMC Pm49FL002",
1252 .uaddr = {
1253 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1254 },
1255 .DevSize = SIZE_256KiB,
1256 .CmdSet = P_ID_AMD_STD,
1257 .NumEraseRegions= 1,
1258 .regions = {
1259 ERASEINFO( 0x01000, 64 )
1261 }, {
1262 .mfr_id = MANUFACTURER_PMC,
1263 .dev_id = PM49FL004,
1264 .name = "PMC Pm49FL004",
1265 .uaddr = {
1266 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1267 },
1268 .DevSize = SIZE_512KiB,
1269 .CmdSet = P_ID_AMD_STD,
1270 .NumEraseRegions= 1,
1271 .regions = {
1272 ERASEINFO( 0x01000, 128 )
1274 }, {
1275 .mfr_id = MANUFACTURER_PMC,
1276 .dev_id = PM49FL008,
1277 .name = "PMC Pm49FL008",
1278 .uaddr = {
1279 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1280 },
1281 .DevSize = SIZE_1MiB,
1282 .CmdSet = P_ID_AMD_STD,
1283 .NumEraseRegions= 1,
1284 .regions = {
1285 ERASEINFO( 0x01000, 256 )
1287 }, {
1288 .mfr_id = MANUFACTURER_SHARP,
1289 .dev_id = LH28F640BF,
1290 .name = "LH28F640BF",
1291 .uaddr = {
1292 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
1293 },
1294 .DevSize = SIZE_4MiB,
1295 .CmdSet = P_ID_INTEL_STD,
1296 .NumEraseRegions= 1,
1297 .regions = {
1298 ERASEINFO(0x40000,16),
1300 }, {
1301 .mfr_id = MANUFACTURER_SST,
1302 .dev_id = SST39LF512,
1303 .name = "SST 39LF512",
1304 .uaddr = {
1305 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1306 },
1307 .DevSize = SIZE_64KiB,
1308 .CmdSet = P_ID_AMD_STD,
1309 .NumEraseRegions= 1,
1310 .regions = {
1311 ERASEINFO(0x01000,16),
1313 }, {
1314 .mfr_id = MANUFACTURER_SST,
1315 .dev_id = SST39LF010,
1316 .name = "SST 39LF010",
1317 .uaddr = {
1318 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1319 },
1320 .DevSize = SIZE_128KiB,
1321 .CmdSet = P_ID_AMD_STD,
1322 .NumEraseRegions= 1,
1323 .regions = {
1324 ERASEINFO(0x01000,32),
1326 }, {
1327 .mfr_id = MANUFACTURER_SST,
1328 .dev_id = SST29EE020,
1329 .name = "SST 29EE020",
1330 .uaddr = {
1331 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1332 },
1333 .DevSize = SIZE_256KiB,
1334 .CmdSet = P_ID_SST_PAGE,
1335 .NumEraseRegions= 1,
1336 .regions = {ERASEINFO(0x01000,64),
1338 }, {
1339 .mfr_id = MANUFACTURER_SST,
1340 .dev_id = SST29LE020,
1341 .name = "SST 29LE020",
1342 .uaddr = {
1343 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1344 },
1345 .DevSize = SIZE_256KiB,
1346 .CmdSet = P_ID_SST_PAGE,
1347 .NumEraseRegions= 1,
1348 .regions = {ERASEINFO(0x01000,64),
1350 }, {
1351 .mfr_id = MANUFACTURER_SST,
1352 .dev_id = SST39LF020,
1353 .name = "SST 39LF020",
1354 .uaddr = {
1355 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1356 },
1357 .DevSize = SIZE_256KiB,
1358 .CmdSet = P_ID_AMD_STD,
1359 .NumEraseRegions= 1,
1360 .regions = {
1361 ERASEINFO(0x01000,64),
1363 }, {
1364 .mfr_id = MANUFACTURER_SST,
1365 .dev_id = SST39LF040,
1366 .name = "SST 39LF040",
1367 .uaddr = {
1368 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1369 },
1370 .DevSize = SIZE_512KiB,
1371 .CmdSet = P_ID_AMD_STD,
1372 .NumEraseRegions= 1,
1373 .regions = {
1374 ERASEINFO(0x01000,128),
1376 }, {
1377 .mfr_id = MANUFACTURER_SST,
1378 .dev_id = SST39SF010A,
1379 .name = "SST 39SF010A",
1380 .uaddr = {
1381 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1382 },
1383 .DevSize = SIZE_128KiB,
1384 .CmdSet = P_ID_AMD_STD,
1385 .NumEraseRegions= 1,
1386 .regions = {
1387 ERASEINFO(0x01000,32),
1389 }, {
1390 .mfr_id = MANUFACTURER_SST,
1391 .dev_id = SST39SF020A,
1392 .name = "SST 39SF020A",
1393 .uaddr = {
1394 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1395 },
1396 .DevSize = SIZE_256KiB,
1397 .CmdSet = P_ID_AMD_STD,
1398 .NumEraseRegions= 1,
1399 .regions = {
1400 ERASEINFO(0x01000,64),
1402 }, {
1403 .mfr_id = MANUFACTURER_SST,
1404 .dev_id = SST49LF004B,
1405 .name = "SST 49LF004B",
1406 .uaddr = {
1407 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1408 },
1409 .DevSize = SIZE_512KiB,
1410 .CmdSet = P_ID_AMD_STD,
1411 .NumEraseRegions= 1,
1412 .regions = {
1413 ERASEINFO(0x01000,128),
1415 }, {
1416 .mfr_id = MANUFACTURER_SST,
1417 .dev_id = SST49LF008A,
1418 .name = "SST 49LF008A",
1419 .uaddr = {
1420 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1421 },
1422 .DevSize = SIZE_1MiB,
1423 .CmdSet = P_ID_AMD_STD,
1424 .NumEraseRegions= 1,
1425 .regions = {
1426 ERASEINFO(0x01000,256),
1428 }, {
1429 .mfr_id = MANUFACTURER_SST,
1430 .dev_id = SST49LF030A,
1431 .name = "SST 49LF030A",
1432 .uaddr = {
1433 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1434 },
1435 .DevSize = SIZE_512KiB,
1436 .CmdSet = P_ID_AMD_STD,
1437 .NumEraseRegions= 1,
1438 .regions = {
1439 ERASEINFO(0x01000,96),
1441 }, {
1442 .mfr_id = MANUFACTURER_SST,
1443 .dev_id = SST49LF040A,
1444 .name = "SST 49LF040A",
1445 .uaddr = {
1446 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1447 },
1448 .DevSize = SIZE_512KiB,
1449 .CmdSet = P_ID_AMD_STD,
1450 .NumEraseRegions= 1,
1451 .regions = {
1452 ERASEINFO(0x01000,128),
1454 }, {
1455 .mfr_id = MANUFACTURER_SST,
1456 .dev_id = SST49LF080A,
1457 .name = "SST 49LF080A",
1458 .uaddr = {
1459 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1460 },
1461 .DevSize = SIZE_1MiB,
1462 .CmdSet = P_ID_AMD_STD,
1463 .NumEraseRegions= 1,
1464 .regions = {
1465 ERASEINFO(0x01000,256),
1467 }, {
1468 .mfr_id = MANUFACTURER_SST, /* should be CFI */
1469 .dev_id = SST39LF160,
1470 .name = "SST 39LF160",
1471 .uaddr = {
1472 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
1473 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
1474 },
1475 .DevSize = SIZE_2MiB,
1476 .CmdSet = P_ID_AMD_STD,
1477 .NumEraseRegions= 2,
1478 .regions = {
1479 ERASEINFO(0x1000,256),
1480 ERASEINFO(0x1000,256)
1482 }, {
1483 .mfr_id = MANUFACTURER_SST, /* should be CFI */
1484 .dev_id = SST39VF1601,
1485 .name = "SST 39VF1601",
1486 .uaddr = {
1487 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
1488 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
1489 },
1490 .DevSize = SIZE_2MiB,
1491 .CmdSet = P_ID_AMD_STD,
1492 .NumEraseRegions= 2,
1493 .regions = {
1494 ERASEINFO(0x1000,256),
1495 ERASEINFO(0x1000,256)
1498 }, {
1499 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1500 .dev_id = M29W800DT,
1501 .name = "ST M29W800DT",
1502 .uaddr = {
1503 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
1504 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
1505 },
1506 .DevSize = SIZE_1MiB,
1507 .CmdSet = P_ID_AMD_STD,
1508 .NumEraseRegions= 4,
1509 .regions = {
1510 ERASEINFO(0x10000,15),
1511 ERASEINFO(0x08000,1),
1512 ERASEINFO(0x02000,2),
1513 ERASEINFO(0x04000,1)
1515 }, {
1516 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1517 .dev_id = M29W800DB,
1518 .name = "ST M29W800DB",
1519 .uaddr = {
1520 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
1521 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
1522 },
1523 .DevSize = SIZE_1MiB,
1524 .CmdSet = P_ID_AMD_STD,
1525 .NumEraseRegions= 4,
1526 .regions = {
1527 ERASEINFO(0x04000,1),
1528 ERASEINFO(0x02000,2),
1529 ERASEINFO(0x08000,1),
1530 ERASEINFO(0x10000,15)
1532 }, {
1533 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1534 .dev_id = M29W160DT,
1535 .name = "ST M29W160DT",
1536 .uaddr = {
1537 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
1538 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1539 },
1540 .DevSize = SIZE_2MiB,
1541 .CmdSet = P_ID_AMD_STD,
1542 .NumEraseRegions= 4,
1543 .regions = {
1544 ERASEINFO(0x10000,31),
1545 ERASEINFO(0x08000,1),
1546 ERASEINFO(0x02000,2),
1547 ERASEINFO(0x04000,1)
1549 }, {
1550 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1551 .dev_id = M29W160DB,
1552 .name = "ST M29W160DB",
1553 .uaddr = {
1554 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
1555 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1556 },
1557 .DevSize = SIZE_2MiB,
1558 .CmdSet = P_ID_AMD_STD,
1559 .NumEraseRegions= 4,
1560 .regions = {
1561 ERASEINFO(0x04000,1),
1562 ERASEINFO(0x02000,2),
1563 ERASEINFO(0x08000,1),
1564 ERASEINFO(0x10000,31)
1566 }, {
1567 .mfr_id = MANUFACTURER_ST,
1568 .dev_id = M29W040B,
1569 .name = "ST M29W040B",
1570 .uaddr = {
1571 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1572 },
1573 .DevSize = SIZE_512KiB,
1574 .CmdSet = P_ID_AMD_STD,
1575 .NumEraseRegions= 1,
1576 .regions = {
1577 ERASEINFO(0x10000,8),
1579 }, {
1580 .mfr_id = MANUFACTURER_ST,
1581 .dev_id = M50FW040,
1582 .name = "ST M50FW040",
1583 .uaddr = {
1584 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
1585 },
1586 .DevSize = SIZE_512KiB,
1587 .CmdSet = P_ID_INTEL_EXT,
1588 .NumEraseRegions= 1,
1589 .regions = {
1590 ERASEINFO(0x10000,8),
1592 }, {
1593 .mfr_id = MANUFACTURER_ST,
1594 .dev_id = M50FW080,
1595 .name = "ST M50FW080",
1596 .uaddr = {
1597 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
1598 },
1599 .DevSize = SIZE_1MiB,
1600 .CmdSet = P_ID_INTEL_EXT,
1601 .NumEraseRegions= 1,
1602 .regions = {
1603 ERASEINFO(0x10000,16),
1605 }, {
1606 .mfr_id = MANUFACTURER_ST,
1607 .dev_id = M50FW016,
1608 .name = "ST M50FW016",
1609 .uaddr = {
1610 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
1611 },
1612 .DevSize = SIZE_2MiB,
1613 .CmdSet = P_ID_INTEL_EXT,
1614 .NumEraseRegions= 1,
1615 .regions = {
1616 ERASEINFO(0x10000,32),
1618 }, {
1619 .mfr_id = MANUFACTURER_ST,
1620 .dev_id = M50LPW080,
1621 .name = "ST M50LPW080",
1622 .uaddr = {
1623 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
1624 },
1625 .DevSize = SIZE_1MiB,
1626 .CmdSet = P_ID_INTEL_EXT,
1627 .NumEraseRegions= 1,
1628 .regions = {
1629 ERASEINFO(0x10000,16),
1631 }, {
1632 .mfr_id = MANUFACTURER_TOSHIBA,
1633 .dev_id = TC58FVT160,
1634 .name = "Toshiba TC58FVT160",
1635 .uaddr = {
1636 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1637 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
1638 },
1639 .DevSize = SIZE_2MiB,
1640 .CmdSet = P_ID_AMD_STD,
1641 .NumEraseRegions= 4,
1642 .regions = {
1643 ERASEINFO(0x10000,31),
1644 ERASEINFO(0x08000,1),
1645 ERASEINFO(0x02000,2),
1646 ERASEINFO(0x04000,1)
1648 }, {
1649 .mfr_id = MANUFACTURER_TOSHIBA,
1650 .dev_id = TC58FVB160,
1651 .name = "Toshiba TC58FVB160",
1652 .uaddr = {
1653 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1654 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
1655 },
1656 .DevSize = SIZE_2MiB,
1657 .CmdSet = P_ID_AMD_STD,
1658 .NumEraseRegions= 4,
1659 .regions = {
1660 ERASEINFO(0x04000,1),
1661 ERASEINFO(0x02000,2),
1662 ERASEINFO(0x08000,1),
1663 ERASEINFO(0x10000,31)
1665 }, {
1666 .mfr_id = MANUFACTURER_TOSHIBA,
1667 .dev_id = TC58FVB321,
1668 .name = "Toshiba TC58FVB321",
1669 .uaddr = {
1670 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1671 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
1672 },
1673 .DevSize = SIZE_4MiB,
1674 .CmdSet = P_ID_AMD_STD,
1675 .NumEraseRegions= 2,
1676 .regions = {
1677 ERASEINFO(0x02000,8),
1678 ERASEINFO(0x10000,63)
1680 }, {
1681 .mfr_id = MANUFACTURER_TOSHIBA,
1682 .dev_id = TC58FVT321,
1683 .name = "Toshiba TC58FVT321",
1684 .uaddr = {
1685 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1686 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
1687 },
1688 .DevSize = SIZE_4MiB,
1689 .CmdSet = P_ID_AMD_STD,
1690 .NumEraseRegions= 2,
1691 .regions = {
1692 ERASEINFO(0x10000,63),
1693 ERASEINFO(0x02000,8)
1695 }, {
1696 .mfr_id = MANUFACTURER_TOSHIBA,
1697 .dev_id = TC58FVB641,
1698 .name = "Toshiba TC58FVB641",
1699 .uaddr = {
1700 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1701 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1702 },
1703 .DevSize = SIZE_8MiB,
1704 .CmdSet = P_ID_AMD_STD,
1705 .NumEraseRegions= 2,
1706 .regions = {
1707 ERASEINFO(0x02000,8),
1708 ERASEINFO(0x10000,127)
1710 }, {
1711 .mfr_id = MANUFACTURER_TOSHIBA,
1712 .dev_id = TC58FVT641,
1713 .name = "Toshiba TC58FVT641",
1714 .uaddr = {
1715 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1716 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1717 },
1718 .DevSize = SIZE_8MiB,
1719 .CmdSet = P_ID_AMD_STD,
1720 .NumEraseRegions= 2,
1721 .regions = {
1722 ERASEINFO(0x10000,127),
1723 ERASEINFO(0x02000,8)
1725 }, {
1726 .mfr_id = MANUFACTURER_WINBOND,
1727 .dev_id = W49V002A,
1728 .name = "Winbond W49V002A",
1729 .uaddr = {
1730 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1731 },
1732 .DevSize = SIZE_256KiB,
1733 .CmdSet = P_ID_AMD_STD,
1734 .NumEraseRegions= 4,
1735 .regions = {
1736 ERASEINFO(0x10000, 3),
1737 ERASEINFO(0x08000, 1),
1738 ERASEINFO(0x02000, 2),
1739 ERASEINFO(0x04000, 1),
1742 };
1745 static int cfi_jedec_setup(struct cfi_private *p_cfi, int index);
1747 static int jedec_probe_chip(struct map_info *map, __u32 base,
1748 unsigned long *chip_map, struct cfi_private *cfi);
1750 static struct mtd_info *jedec_probe(struct map_info *map);
1752 static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
1753 struct cfi_private *cfi)
1755 map_word result;
1756 unsigned long mask;
1757 u32 ofs = cfi_build_cmd_addr(0, cfi_interleave(cfi), cfi->device_type);
1758 mask = (1 << (cfi->device_type * 8)) -1;
1759 result = map_read(map, base + ofs);
1760 return result.x[0] & mask;
1763 static inline u32 jedec_read_id(struct map_info *map, __u32 base,
1764 struct cfi_private *cfi)
1766 map_word result;
1767 unsigned long mask;
1768 u32 ofs = cfi_build_cmd_addr(1, cfi_interleave(cfi), cfi->device_type);
1769 mask = (1 << (cfi->device_type * 8)) -1;
1770 result = map_read(map, base + ofs);
1771 return result.x[0] & mask;
1774 static inline void jedec_reset(u32 base, struct map_info *map,
1775 struct cfi_private *cfi)
1777 /* Reset */
1779 /* after checking the datasheets for SST, MACRONIX and ATMEL
1780 * (oh and incidentaly the jedec spec - 3.5.3.3) the reset
1781 * sequence is *supposed* to be 0xaa at 0x5555, 0x55 at
1782 * 0x2aaa, 0xF0 at 0x5555 this will not affect the AMD chips
1783 * as they will ignore the writes and dont care what address
1784 * the F0 is written to */
1785 if(cfi->addr_unlock1) {
1786 DEBUG( MTD_DEBUG_LEVEL3,
1787 "reset unlock called %x %x \n",
1788 cfi->addr_unlock1,cfi->addr_unlock2);
1789 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
1790 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
1793 cfi_send_gen_cmd(0xF0, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
1794 /* Some misdesigned intel chips do not respond for 0xF0 for a reset,
1795 * so ensure we're in read mode. Send both the Intel and the AMD command
1796 * for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so
1797 * this should be safe.
1798 */
1799 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
1800 /* FIXME - should have reset delay before continuing */
1804 static inline __u8 finfo_uaddr(const struct amd_flash_info *finfo, int device_type)
1806 int uaddr_idx;
1807 __u8 uaddr = MTD_UADDR_NOT_SUPPORTED;
1809 switch ( device_type ) {
1810 case CFI_DEVICETYPE_X8: uaddr_idx = 0; break;
1811 case CFI_DEVICETYPE_X16: uaddr_idx = 1; break;
1812 case CFI_DEVICETYPE_X32: uaddr_idx = 2; break;
1813 default:
1814 printk(KERN_NOTICE "MTD: %s(): unknown device_type %d\n",
1815 __func__, device_type);
1816 goto uaddr_done;
1819 uaddr = finfo->uaddr[uaddr_idx];
1821 if (uaddr != MTD_UADDR_NOT_SUPPORTED ) {
1822 /* ASSERT("The unlock addresses for non-8-bit mode
1823 are bollocks. We don't really need an array."); */
1824 uaddr = finfo->uaddr[0];
1827 uaddr_done:
1828 return uaddr;
1832 static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
1834 int i,num_erase_regions;
1835 __u8 uaddr;
1837 printk("Found: %s\n",jedec_table[index].name);
1839 num_erase_regions = jedec_table[index].NumEraseRegions;
1841 p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
1842 if (!p_cfi->cfiq) {
1843 //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
1844 return 0;
1847 memset(p_cfi->cfiq,0,sizeof(struct cfi_ident));
1849 p_cfi->cfiq->P_ID = jedec_table[index].CmdSet;
1850 p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions;
1851 p_cfi->cfiq->DevSize = jedec_table[index].DevSize;
1852 p_cfi->cfi_mode = CFI_MODE_JEDEC;
1854 for (i=0; i<num_erase_regions; i++){
1855 p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i];
1857 p_cfi->cmdset_priv = NULL;
1859 /* This may be redundant for some cases, but it doesn't hurt */
1860 p_cfi->mfr = jedec_table[index].mfr_id;
1861 p_cfi->id = jedec_table[index].dev_id;
1863 uaddr = finfo_uaddr(&jedec_table[index], p_cfi->device_type);
1864 if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) {
1865 kfree( p_cfi->cfiq );
1866 return 0;
1869 p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1;
1870 p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2;
1872 return 1; /* ok */
1876 /*
1877 * There is a BIG problem properly ID'ing the JEDEC devic and guaranteeing
1878 * the mapped address, unlock addresses, and proper chip ID. This function
1879 * attempts to minimize errors. It is doubtfull that this probe will ever
1880 * be perfect - consequently there should be some module parameters that
1881 * could be manually specified to force the chip info.
1882 */
1883 static inline int jedec_match( __u32 base,
1884 struct map_info *map,
1885 struct cfi_private *cfi,
1886 const struct amd_flash_info *finfo )
1888 int rc = 0; /* failure until all tests pass */
1889 u32 mfr, id;
1890 __u8 uaddr;
1892 /*
1893 * The IDs must match. For X16 and X32 devices operating in
1894 * a lower width ( X8 or X16 ), the device ID's are usually just
1895 * the lower byte(s) of the larger device ID for wider mode. If
1896 * a part is found that doesn't fit this assumption (device id for
1897 * smaller width mode is completely unrealated to full-width mode)
1898 * then the jedec_table[] will have to be augmented with the IDs
1899 * for different widths.
1900 */
1901 switch (cfi->device_type) {
1902 case CFI_DEVICETYPE_X8:
1903 mfr = (__u8)finfo->mfr_id;
1904 id = (__u8)finfo->dev_id;
1906 /* bjd: it seems that if we do this, we can end up
1907 * detecting 16bit flashes as an 8bit device, even though
1908 * there aren't.
1909 */
1910 if (finfo->dev_id > 0xff) {
1911 DEBUG( MTD_DEBUG_LEVEL3, "%s(): ID is not 8bit\n",
1912 __func__);
1913 goto match_done;
1915 break;
1916 case CFI_DEVICETYPE_X16:
1917 mfr = (__u16)finfo->mfr_id;
1918 id = (__u16)finfo->dev_id;
1919 break;
1920 case CFI_DEVICETYPE_X32:
1921 mfr = (__u16)finfo->mfr_id;
1922 id = (__u32)finfo->dev_id;
1923 break;
1924 default:
1925 printk(KERN_WARNING
1926 "MTD %s(): Unsupported device type %d\n",
1927 __func__, cfi->device_type);
1928 goto match_done;
1930 if ( cfi->mfr != mfr || cfi->id != id ) {
1931 goto match_done;
1934 /* the part size must fit in the memory window */
1935 DEBUG( MTD_DEBUG_LEVEL3,
1936 "MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n",
1937 __func__, base, 1 << finfo->DevSize, base + (1 << finfo->DevSize) );
1938 if ( base + cfi_interleave(cfi) * ( 1 << finfo->DevSize ) > map->size ) {
1939 DEBUG( MTD_DEBUG_LEVEL3,
1940 "MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n",
1941 __func__, finfo->mfr_id, finfo->dev_id,
1942 1 << finfo->DevSize );
1943 goto match_done;
1946 uaddr = finfo_uaddr(finfo, cfi->device_type);
1947 if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) {
1948 goto match_done;
1951 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n",
1952 __func__, cfi->addr_unlock1, cfi->addr_unlock2 );
1953 if ( MTD_UADDR_UNNECESSARY != uaddr && MTD_UADDR_DONT_CARE != uaddr
1954 && ( unlock_addrs[uaddr].addr1 != cfi->addr_unlock1 ||
1955 unlock_addrs[uaddr].addr2 != cfi->addr_unlock2 ) ) {
1956 DEBUG( MTD_DEBUG_LEVEL3,
1957 "MTD %s(): 0x%.4x 0x%.4x did not match\n",
1958 __func__,
1959 unlock_addrs[uaddr].addr1,
1960 unlock_addrs[uaddr].addr2);
1961 goto match_done;
1964 /*
1965 * Make sure the ID's dissappear when the device is taken out of
1966 * ID mode. The only time this should fail when it should succeed
1967 * is when the ID's are written as data to the same
1968 * addresses. For this rare and unfortunate case the chip
1969 * cannot be probed correctly.
1970 * FIXME - write a driver that takes all of the chip info as
1971 * module parameters, doesn't probe but forces a load.
1972 */
1973 DEBUG( MTD_DEBUG_LEVEL3,
1974 "MTD %s(): check ID's disappear when not in ID mode\n",
1975 __func__ );
1976 jedec_reset( base, map, cfi );
1977 mfr = jedec_read_mfr( map, base, cfi );
1978 id = jedec_read_id( map, base, cfi );
1979 if ( mfr == cfi->mfr && id == cfi->id ) {
1980 DEBUG( MTD_DEBUG_LEVEL3,
1981 "MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n"
1982 "You might need to manually specify JEDEC parameters.\n",
1983 __func__, cfi->mfr, cfi->id );
1984 goto match_done;
1987 /* all tests passed - mark as success */
1988 rc = 1;
1990 /*
1991 * Put the device back in ID mode - only need to do this if we
1992 * were truly frobbing a real device.
1993 */
1994 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): return to ID mode\n", __func__ );
1995 if(cfi->addr_unlock1) {
1996 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
1997 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
1999 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
2000 /* FIXME - should have a delay before continuing */
2002 match_done:
2003 return rc;
2007 static int jedec_probe_chip(struct map_info *map, __u32 base,
2008 unsigned long *chip_map, struct cfi_private *cfi)
2010 int i;
2011 enum uaddr uaddr_idx = MTD_UADDR_NOT_SUPPORTED;
2012 u32 probe_offset1, probe_offset2;
2014 retry:
2015 if (!cfi->numchips) {
2016 uaddr_idx++;
2018 if (MTD_UADDR_UNNECESSARY == uaddr_idx)
2019 return 0;
2021 cfi->addr_unlock1 = unlock_addrs[uaddr_idx].addr1;
2022 cfi->addr_unlock2 = unlock_addrs[uaddr_idx].addr2;
2025 /* Make certain we aren't probing past the end of map */
2026 if (base >= map->size) {
2027 printk(KERN_NOTICE
2028 "Probe at base(0x%08x) past the end of the map(0x%08lx)\n",
2029 base, map->size -1);
2030 return 0;
2033 /* Ensure the unlock addresses we try stay inside the map */
2034 probe_offset1 = cfi_build_cmd_addr(
2035 cfi->addr_unlock1,
2036 cfi_interleave(cfi),
2037 cfi->device_type);
2038 probe_offset2 = cfi_build_cmd_addr(
2039 cfi->addr_unlock1,
2040 cfi_interleave(cfi),
2041 cfi->device_type);
2042 if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) ||
2043 ((base + probe_offset2 + map_bankwidth(map)) >= map->size))
2045 goto retry;
2048 /* Reset */
2049 jedec_reset(base, map, cfi);
2051 /* Autoselect Mode */
2052 if(cfi->addr_unlock1) {
2053 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
2054 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
2056 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
2057 /* FIXME - should have a delay before continuing */
2059 if (!cfi->numchips) {
2060 /* This is the first time we're called. Set up the CFI
2061 stuff accordingly and return */
2063 cfi->mfr = jedec_read_mfr(map, base, cfi);
2064 cfi->id = jedec_read_id(map, base, cfi);
2065 DEBUG(MTD_DEBUG_LEVEL3,
2066 "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
2067 cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type);
2068 for (i = 0; i < ARRAY_SIZE(jedec_table); i++) {
2069 if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
2070 DEBUG( MTD_DEBUG_LEVEL3,
2071 "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
2072 __func__, cfi->mfr, cfi->id,
2073 cfi->addr_unlock1, cfi->addr_unlock2 );
2074 if (!cfi_jedec_setup(cfi, i))
2075 return 0;
2076 goto ok_out;
2079 goto retry;
2080 } else {
2081 __u16 mfr;
2082 __u16 id;
2084 /* Make sure it is a chip of the same manufacturer and id */
2085 mfr = jedec_read_mfr(map, base, cfi);
2086 id = jedec_read_id(map, base, cfi);
2088 if ((mfr != cfi->mfr) || (id != cfi->id)) {
2089 printk(KERN_DEBUG "%s: Found different chip or no chip at all (mfr 0x%x, id 0x%x) at 0x%x\n",
2090 map->name, mfr, id, base);
2091 jedec_reset(base, map, cfi);
2092 return 0;
2096 /* Check each previous chip locations to see if it's an alias */
2097 for (i=0; i < (base >> cfi->chipshift); i++) {
2098 unsigned long start;
2099 if(!test_bit(i, chip_map)) {
2100 continue; /* Skip location; no valid chip at this address */
2102 start = i << cfi->chipshift;
2103 if (jedec_read_mfr(map, start, cfi) == cfi->mfr &&
2104 jedec_read_id(map, start, cfi) == cfi->id) {
2105 /* Eep. This chip also looks like it's in autoselect mode.
2106 Is it an alias for the new one? */
2107 jedec_reset(start, map, cfi);
2109 /* If the device IDs go away, it's an alias */
2110 if (jedec_read_mfr(map, base, cfi) != cfi->mfr ||
2111 jedec_read_id(map, base, cfi) != cfi->id) {
2112 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
2113 map->name, base, start);
2114 return 0;
2117 /* Yes, it's actually got the device IDs as data. Most
2118 * unfortunate. Stick the new chip in read mode
2119 * too and if it's the same, assume it's an alias. */
2120 /* FIXME: Use other modes to do a proper check */
2121 jedec_reset(base, map, cfi);
2122 if (jedec_read_mfr(map, base, cfi) == cfi->mfr &&
2123 jedec_read_id(map, base, cfi) == cfi->id) {
2124 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
2125 map->name, base, start);
2126 return 0;
2131 /* OK, if we got to here, then none of the previous chips appear to
2132 be aliases for the current one. */
2133 set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
2134 cfi->numchips++;
2136 ok_out:
2137 /* Put it back into Read Mode */
2138 jedec_reset(base, map, cfi);
2140 printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
2141 map->name, cfi_interleave(cfi), cfi->device_type*8, base,
2142 map->bankwidth*8);
2144 return 1;
2147 static struct chip_probe jedec_chip_probe = {
2148 .name = "JEDEC",
2149 .probe_chip = jedec_probe_chip
2150 };
2152 static struct mtd_info *jedec_probe(struct map_info *map)
2154 /*
2155 * Just use the generic probe stuff to call our CFI-specific
2156 * chip_probe routine in all the possible permutations, etc.
2157 */
2158 return mtd_do_chip_probe(map, &jedec_chip_probe);
2161 static struct mtd_chip_driver jedec_chipdrv = {
2162 .probe = jedec_probe,
2163 .name = "jedec_probe",
2164 .module = THIS_MODULE
2165 };
2167 static int __init jedec_probe_init(void)
2169 register_mtd_chip_driver(&jedec_chipdrv);
2170 return 0;
2173 static void __exit jedec_probe_exit(void)
2175 unregister_mtd_chip_driver(&jedec_chipdrv);
2178 module_init(jedec_probe_init);
2179 module_exit(jedec_probe_exit);
2181 MODULE_LICENSE("GPL");
2182 MODULE_AUTHOR("Erwin Authried <eauth@softsys.co.at> et al.");
2183 MODULE_DESCRIPTION("Probe code for JEDEC-compliant flash chips");