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