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