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