blob: e4e283ceb842dc260b728c0cb50472f2aed4ca73 [file] [log] [blame]
developer41370d52022-03-16 16:01:59 +08001--- a/drivers/mtd/nand/spi/core.c
2+++ b/drivers/mtd/nand/spi/core.c
3@@ -16,6 +16,7 @@
4 #include <linux/mtd/spinand.h>
5 #include <linux/of.h>
6 #include <linux/slab.h>
7+#include <linux/string.h>
8 #include <linux/spi/spi.h>
9 #include <linux/spi/spi-mem.h>
10
11@@ -370,10 +371,11 @@ out:
12 return status & STATUS_BUSY ? -ETIMEDOUT : 0;
13 }
14
15-static int spinand_read_id_op(struct spinand_device *spinand, u8 *buf)
16+static int spinand_read_id_op(struct spinand_device *spinand, u8 naddr,
17+ u8 ndummy, u8 *buf)
18 {
19- struct spi_mem_op op = SPINAND_READID_OP(0, spinand->scratchbuf,
20- SPINAND_MAX_ID_LEN);
21+ struct spi_mem_op op = SPINAND_READID_OP(
22+ naddr, ndummy, spinand->scratchbuf, SPINAND_MAX_ID_LEN);
23 int ret;
24
25 ret = spi_mem_exec_op(spinand->spimem, &op);
26@@ -760,24 +762,62 @@ static const struct spinand_manufacturer
27 &winbond_spinand_manufacturer,
28 };
29
30-static int spinand_manufacturer_detect(struct spinand_device *spinand)
31+static int spinand_manufacturer_match(struct spinand_device *spinand,
32+ enum spinand_readid_method rdid_method)
33 {
34+ u8 *id = spinand->id.data;
35 unsigned int i;
36 int ret;
37
38 for (i = 0; i < ARRAY_SIZE(spinand_manufacturers); i++) {
39- ret = spinand_manufacturers[i]->ops->detect(spinand);
40- if (ret > 0) {
41- spinand->manufacturer = spinand_manufacturers[i];
42- return 0;
43- } else if (ret < 0) {
44- return ret;
45- }
46- }
47+ const struct spinand_manufacturer *manufacturer =
48+ spinand_manufacturers[i];
49+
50+ if (id[0] != manufacturer->id)
51+ continue;
52
53+ ret = spinand_match_and_init(spinand,
54+ manufacturer->chips,
55+ manufacturer->nchips,
56+ rdid_method);
57+ if (ret < 0)
58+ continue;
59+
60+ spinand->manufacturer = manufacturer;
61+ return 0;
62+ }
63 return -ENOTSUPP;
64 }
65
66+static int spinand_id_detect(struct spinand_device *spinand)
67+{
68+ u8 *id = spinand->id.data;
69+ int ret;
70+
71+ ret = spinand_read_id_op(spinand, 0, 0, id);
72+ if (ret)
73+ return ret;
74+ ret = spinand_manufacturer_match(spinand, SPINAND_READID_METHOD_OPCODE);
75+ if (!ret)
76+ return 0;
77+
78+ ret = spinand_read_id_op(spinand, 1, 0, id);
79+ if (ret)
80+ return ret;
81+ ret = spinand_manufacturer_match(spinand,
82+ SPINAND_READID_METHOD_OPCODE_ADDR);
83+ if (!ret)
84+ return 0;
85+
86+ ret = spinand_read_id_op(spinand, 0, 1, id);
87+ if (ret)
88+ return ret;
89+ ret = spinand_manufacturer_match(spinand,
90+ SPINAND_READID_METHOD_OPCODE_DUMMY);
91+
92+ return ret;
93+}
94+
95 static int spinand_manufacturer_init(struct spinand_device *spinand)
96 {
97 if (spinand->manufacturer->ops->init)
98@@ -833,9 +873,9 @@ spinand_select_op_variant(struct spinand
99 * @spinand: SPI NAND object
100 * @table: SPI NAND device description table
101 * @table_size: size of the device description table
102+ * @rdid_method: read id method to match
103 *
104- * Should be used by SPI NAND manufacturer drivers when they want to find a
105- * match between a device ID retrieved through the READ_ID command and an
106+ * Match between a device ID retrieved through the READ_ID command and an
107 * entry in the SPI NAND description table. If a match is found, the spinand
108 * object will be initialized with information provided by the matching
109 * spinand_info entry.
110@@ -844,8 +884,10 @@ spinand_select_op_variant(struct spinand
111 */
112 int spinand_match_and_init(struct spinand_device *spinand,
113 const struct spinand_info *table,
114- unsigned int table_size, u16 devid)
115+ unsigned int table_size,
116+ enum spinand_readid_method rdid_method)
117 {
118+ u8 *id = spinand->id.data;
119 struct nand_device *nand = spinand_to_nand(spinand);
120 unsigned int i;
121
122@@ -853,13 +895,17 @@ int spinand_match_and_init(struct spinan
123 const struct spinand_info *info = &table[i];
124 const struct spi_mem_op *op;
125
126- if (devid != info->devid)
127+ if (rdid_method != info->devid.method)
128+ continue;
129+
130+ if (memcmp(id + 1, info->devid.id, info->devid.len))
131 continue;
132
133 nand->memorg = table[i].memorg;
134 nand->eccreq = table[i].eccreq;
135 spinand->eccinfo = table[i].eccinfo;
136 spinand->flags = table[i].flags;
137+ spinand->id.len = 1 + table[i].devid.len;
138 spinand->select_target = table[i].select_target;
139
140 op = spinand_select_op_variant(spinand,
141@@ -896,13 +942,7 @@ static int spinand_detect(struct spinand
142 if (ret)
143 return ret;
144
145- ret = spinand_read_id_op(spinand, spinand->id.data);
146- if (ret)
147- return ret;
148-
149- spinand->id.len = SPINAND_MAX_ID_LEN;
150-
151- ret = spinand_manufacturer_detect(spinand);
152+ ret = spinand_id_detect(spinand);
153 if (ret) {
154 dev_err(dev, "unknown raw ID %*phN\n", SPINAND_MAX_ID_LEN,
155 spinand->id.data);
156--- a/drivers/mtd/nand/spi/gigadevice.c
157+++ b/drivers/mtd/nand/spi/gigadevice.c
158@@ -195,7 +195,8 @@ static int gd5fxgq4ufxxg_ecc_get_status(
159 }
160
161 static const struct spinand_info gigadevice_spinand_table[] = {
162- SPINAND_INFO("GD5F1GQ4xA", 0xF1,
163+ SPINAND_INFO("GD5F1GQ4xA",
164+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
165 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
166 NAND_ECCREQ(8, 512),
167 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
168@@ -204,7 +205,8 @@ static const struct spinand_info gigadev
169 SPINAND_HAS_QE_BIT,
170 SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
171 gd5fxgq4xa_ecc_get_status)),
172- SPINAND_INFO("GD5F2GQ4xA", 0xF2,
173+ SPINAND_INFO("GD5F2GQ4xA",
174+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2),
175 NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
176 NAND_ECCREQ(8, 512),
177 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
178@@ -213,7 +215,8 @@ static const struct spinand_info gigadev
179 SPINAND_HAS_QE_BIT,
180 SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
181 gd5fxgq4xa_ecc_get_status)),
182- SPINAND_INFO("GD5F4GQ4xA", 0xF4,
183+ SPINAND_INFO("GD5F4GQ4xA",
184+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4),
185 NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1),
186 NAND_ECCREQ(8, 512),
187 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
188@@ -222,7 +225,8 @@ static const struct spinand_info gigadev
189 SPINAND_HAS_QE_BIT,
190 SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
191 gd5fxgq4xa_ecc_get_status)),
192- SPINAND_INFO("GD5F1GQ4UExxG", 0xd1,
193+ SPINAND_INFO("GD5F1GQ4UExxG",
194+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
195 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
196 NAND_ECCREQ(8, 512),
197 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
198@@ -231,7 +235,8 @@ static const struct spinand_info gigadev
199 SPINAND_HAS_QE_BIT,
200 SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout,
201 gd5fxgq4uexxg_ecc_get_status)),
202- SPINAND_INFO("GD5F1GQ4UFxxG", 0xb148,
203+ SPINAND_INFO("GD5F1GQ4UFxxG",
204+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
205 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
206 NAND_ECCREQ(8, 512),
207 SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
208@@ -242,39 +247,13 @@ static const struct spinand_info gigadev
209 gd5fxgq4ufxxg_ecc_get_status)),
210 };
211
212-static int gigadevice_spinand_detect(struct spinand_device *spinand)
213-{
214- u8 *id = spinand->id.data;
215- u16 did;
216- int ret;
217-
218- /*
219- * Earlier GDF5-series devices (A,E) return [0][MID][DID]
220- * Later (F) devices return [MID][DID1][DID2]
221- */
222-
223- if (id[0] == SPINAND_MFR_GIGADEVICE)
224- did = (id[1] << 8) + id[2];
225- else if (id[0] == 0 && id[1] == SPINAND_MFR_GIGADEVICE)
226- did = id[2];
227- else
228- return 0;
229-
230- ret = spinand_match_and_init(spinand, gigadevice_spinand_table,
231- ARRAY_SIZE(gigadevice_spinand_table),
232- did);
233- if (ret)
234- return ret;
235-
236- return 1;
237-}
238-
239 static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
240- .detect = gigadevice_spinand_detect,
241 };
242
243 const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
244 .id = SPINAND_MFR_GIGADEVICE,
245 .name = "GigaDevice",
246+ .chips = gigadevice_spinand_table,
247+ .nchips = ARRAY_SIZE(gigadevice_spinand_table),
248 .ops = &gigadevice_spinand_manuf_ops,
249 };
250--- a/drivers/mtd/nand/spi/macronix.c
251+++ b/drivers/mtd/nand/spi/macronix.c
252@@ -99,7 +99,8 @@ static int mx35lf1ge4ab_ecc_get_status(s
253 }
254
255 static const struct spinand_info macronix_spinand_table[] = {
256- SPINAND_INFO("MX35LF1GE4AB", 0x12,
257+ SPINAND_INFO("MX35LF1GE4AB",
258+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x12),
259 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
260 NAND_ECCREQ(4, 512),
261 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
262@@ -108,7 +109,8 @@ static const struct spinand_info macroni
263 SPINAND_HAS_QE_BIT,
264 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
265 mx35lf1ge4ab_ecc_get_status)),
266- SPINAND_INFO("MX35LF2GE4AB", 0x22,
267+ SPINAND_INFO("MX35LF2GE4AB",
268+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22),
269 NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
270 NAND_ECCREQ(4, 512),
271 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
272@@ -118,33 +120,13 @@ static const struct spinand_info macroni
273 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
274 };
275
276-static int macronix_spinand_detect(struct spinand_device *spinand)
277-{
278- u8 *id = spinand->id.data;
279- int ret;
280-
281- /*
282- * Macronix SPI NAND read ID needs a dummy byte, so the first byte in
283- * raw_id is garbage.
284- */
285- if (id[1] != SPINAND_MFR_MACRONIX)
286- return 0;
287-
288- ret = spinand_match_and_init(spinand, macronix_spinand_table,
289- ARRAY_SIZE(macronix_spinand_table),
290- id[2]);
291- if (ret)
292- return ret;
293-
294- return 1;
295-}
296-
297 static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
298- .detect = macronix_spinand_detect,
299 };
300
301 const struct spinand_manufacturer macronix_spinand_manufacturer = {
302 .id = SPINAND_MFR_MACRONIX,
303 .name = "Macronix",
304+ .chips = macronix_spinand_table,
305+ .nchips = ARRAY_SIZE(macronix_spinand_table),
306 .ops = &macronix_spinand_manuf_ops,
307 };
308--- a/drivers/mtd/nand/spi/micron.c
309+++ b/drivers/mtd/nand/spi/micron.c
310@@ -91,7 +91,8 @@ static int mt29f2g01abagd_ecc_get_status
311 }
312
313 static const struct spinand_info micron_spinand_table[] = {
314- SPINAND_INFO("MT29F2G01ABAGD", 0x24,
315+ SPINAND_INFO("MT29F2G01ABAGD",
316+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
317 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
318 NAND_ECCREQ(8, 512),
319 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
320@@ -102,32 +103,13 @@ static const struct spinand_info micron_
321 mt29f2g01abagd_ecc_get_status)),
322 };
323
324-static int micron_spinand_detect(struct spinand_device *spinand)
325-{
326- u8 *id = spinand->id.data;
327- int ret;
328-
329- /*
330- * Micron SPI NAND read ID need a dummy byte,
331- * so the first byte in raw_id is dummy.
332- */
333- if (id[1] != SPINAND_MFR_MICRON)
334- return 0;
335-
336- ret = spinand_match_and_init(spinand, micron_spinand_table,
337- ARRAY_SIZE(micron_spinand_table), id[2]);
338- if (ret)
339- return ret;
340-
341- return 1;
342-}
343-
344 static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = {
345- .detect = micron_spinand_detect,
346 };
347
348 const struct spinand_manufacturer micron_spinand_manufacturer = {
349 .id = SPINAND_MFR_MICRON,
350 .name = "Micron",
351+ .chips = micron_spinand_table,
352+ .nchips = ARRAY_SIZE(micron_spinand_table),
353 .ops = &micron_spinand_manuf_ops,
354 };
355--- a/drivers/mtd/nand/spi/paragon.c
356+++ b/drivers/mtd/nand/spi/paragon.c
357@@ -97,7 +97,8 @@ static const struct mtd_ooblayout_ops pn
358
359
360 static const struct spinand_info paragon_spinand_table[] = {
361- SPINAND_INFO("PN26G01A", 0xe1,
362+ SPINAND_INFO("PN26G01A",
363+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xe1),
364 NAND_MEMORG(1, 2048, 128, 64, 1024, 21, 1, 1, 1),
365 NAND_ECCREQ(8, 512),
366 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
367@@ -106,7 +107,8 @@ static const struct spinand_info paragon
368 0,
369 SPINAND_ECCINFO(&pn26g0xa_ooblayout,
370 pn26g0xa_ecc_get_status)),
371- SPINAND_INFO("PN26G02A", 0xe2,
372+ SPINAND_INFO("PN26G02A",
373+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xe2),
374 NAND_MEMORG(1, 2048, 128, 64, 2048, 41, 1, 1, 1),
375 NAND_ECCREQ(8, 512),
376 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
377@@ -117,31 +119,13 @@ static const struct spinand_info paragon
378 pn26g0xa_ecc_get_status)),
379 };
380
381-static int paragon_spinand_detect(struct spinand_device *spinand)
382-{
383- u8 *id = spinand->id.data;
384- int ret;
385-
386- /* Read ID returns [0][MID][DID] */
387-
388- if (id[1] != SPINAND_MFR_PARAGON)
389- return 0;
390-
391- ret = spinand_match_and_init(spinand, paragon_spinand_table,
392- ARRAY_SIZE(paragon_spinand_table),
393- id[2]);
394- if (ret)
395- return ret;
396-
397- return 1;
398-}
399-
400 static const struct spinand_manufacturer_ops paragon_spinand_manuf_ops = {
401- .detect = paragon_spinand_detect,
402 };
403
404 const struct spinand_manufacturer paragon_spinand_manufacturer = {
405 .id = SPINAND_MFR_PARAGON,
406 .name = "Paragon",
407+ .chips = paragon_spinand_table,
408+ .nchips = ARRAY_SIZE(paragon_spinand_table),
409 .ops = &paragon_spinand_manuf_ops,
410 };
411--- a/drivers/mtd/nand/spi/toshiba.c
412+++ b/drivers/mtd/nand/spi/toshiba.c
413@@ -95,7 +95,8 @@ static int tc58cxgxsx_ecc_get_status(str
414
415 static const struct spinand_info toshiba_spinand_table[] = {
416 /* 3.3V 1Gb */
417- SPINAND_INFO("TC58CVG0S3", 0xC2,
418+ SPINAND_INFO("TC58CVG0S3",
419+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC2),
420 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
421 NAND_ECCREQ(8, 512),
422 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
423@@ -105,7 +106,8 @@ static const struct spinand_info toshiba
424 SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
425 tc58cxgxsx_ecc_get_status)),
426 /* 3.3V 2Gb */
427- SPINAND_INFO("TC58CVG1S3", 0xCB,
428+ SPINAND_INFO("TC58CVG1S3",
429+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB),
430 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
431 NAND_ECCREQ(8, 512),
432 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
433@@ -115,7 +117,8 @@ static const struct spinand_info toshiba
434 SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
435 tc58cxgxsx_ecc_get_status)),
436 /* 3.3V 4Gb */
437- SPINAND_INFO("TC58CVG2S0", 0xCD,
438+ SPINAND_INFO("TC58CVG2S0",
439+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD),
440 NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
441 NAND_ECCREQ(8, 512),
442 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
443@@ -125,7 +128,8 @@ static const struct spinand_info toshiba
444 SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
445 tc58cxgxsx_ecc_get_status)),
446 /* 1.8V 1Gb */
447- SPINAND_INFO("TC58CYG0S3", 0xB2,
448+ SPINAND_INFO("TC58CYG0S3",
449+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2),
450 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
451 NAND_ECCREQ(8, 512),
452 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
453@@ -135,7 +139,8 @@ static const struct spinand_info toshiba
454 SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
455 tc58cxgxsx_ecc_get_status)),
456 /* 1.8V 2Gb */
457- SPINAND_INFO("TC58CYG1S3", 0xBB,
458+ SPINAND_INFO("TC58CYG1S3",
459+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB),
460 NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
461 NAND_ECCREQ(8, 512),
462 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
463@@ -145,7 +150,8 @@ static const struct spinand_info toshiba
464 SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
465 tc58cxgxsx_ecc_get_status)),
466 /* 1.8V 4Gb */
467- SPINAND_INFO("TC58CYG2S0", 0xBD,
468+ SPINAND_INFO("TC58CYG2S0",
469+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD),
470 NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
471 NAND_ECCREQ(8, 512),
472 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
473@@ -156,33 +162,13 @@ static const struct spinand_info toshiba
474 tc58cxgxsx_ecc_get_status)),
475 };
476
477-static int toshiba_spinand_detect(struct spinand_device *spinand)
478-{
479- u8 *id = spinand->id.data;
480- int ret;
481-
482- /*
483- * Toshiba SPI NAND read ID needs a dummy byte,
484- * so the first byte in id is garbage.
485- */
486- if (id[1] != SPINAND_MFR_TOSHIBA)
487- return 0;
488-
489- ret = spinand_match_and_init(spinand, toshiba_spinand_table,
490- ARRAY_SIZE(toshiba_spinand_table),
491- id[2]);
492- if (ret)
493- return ret;
494-
495- return 1;
496-}
497-
498 static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = {
499- .detect = toshiba_spinand_detect,
500 };
501
502 const struct spinand_manufacturer toshiba_spinand_manufacturer = {
503 .id = SPINAND_MFR_TOSHIBA,
504 .name = "Toshiba",
505+ .chips = toshiba_spinand_table,
506+ .nchips = ARRAY_SIZE(toshiba_spinand_table),
507 .ops = &toshiba_spinand_manuf_ops,
508 };
509--- a/drivers/mtd/nand/spi/winbond.c
510+++ b/drivers/mtd/nand/spi/winbond.c
511@@ -75,7 +75,8 @@ static int w25m02gv_select_target(struct
512 }
513
514 static const struct spinand_info winbond_spinand_table[] = {
515- SPINAND_INFO("W25M02GV", 0xAB,
516+ SPINAND_INFO("W25M02GV",
517+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab),
518 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2),
519 NAND_ECCREQ(1, 512),
520 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
521@@ -84,7 +85,8 @@ static const struct spinand_info winbond
522 0,
523 SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
524 SPINAND_SELECT_TARGET(w25m02gv_select_target)),
525- SPINAND_INFO("W25N01GV", 0xAA,
526+ SPINAND_INFO("W25N01GV",
527+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa),
528 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
529 NAND_ECCREQ(1, 512),
530 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
531@@ -94,31 +96,6 @@ static const struct spinand_info winbond
532 SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
533 };
534
535-/**
536- * winbond_spinand_detect - initialize device related part in spinand_device
537- * struct if it is a Winbond device.
538- * @spinand: SPI NAND device structure
539- */
540-static int winbond_spinand_detect(struct spinand_device *spinand)
541-{
542- u8 *id = spinand->id.data;
543- int ret;
544-
545- /*
546- * Winbond SPI NAND read ID need a dummy byte,
547- * so the first byte in raw_id is dummy.
548- */
549- if (id[1] != SPINAND_MFR_WINBOND)
550- return 0;
551-
552- ret = spinand_match_and_init(spinand, winbond_spinand_table,
553- ARRAY_SIZE(winbond_spinand_table), id[2]);
554- if (ret)
555- return ret;
556-
557- return 1;
558-}
559-
560 static int winbond_spinand_init(struct spinand_device *spinand)
561 {
562 struct nand_device *nand = spinand_to_nand(spinand);
563@@ -138,12 +115,13 @@ static int winbond_spinand_init(struct s
564 }
565
566 static const struct spinand_manufacturer_ops winbond_spinand_manuf_ops = {
567- .detect = winbond_spinand_detect,
568 .init = winbond_spinand_init,
569 };
570
571 const struct spinand_manufacturer winbond_spinand_manufacturer = {
572 .id = SPINAND_MFR_WINBOND,
573 .name = "Winbond",
574+ .chips = winbond_spinand_table,
575+ .nchips = ARRAY_SIZE(winbond_spinand_table),
576 .ops = &winbond_spinand_manuf_ops,
577 };
578--- a/include/linux/mtd/spinand.h
579+++ b/include/linux/mtd/spinand.h
580@@ -32,9 +32,9 @@
581 SPI_MEM_OP_NO_DUMMY, \
582 SPI_MEM_OP_NO_DATA)
583
584-#define SPINAND_READID_OP(ndummy, buf, len) \
585+#define SPINAND_READID_OP(naddr, ndummy, buf, len) \
586 SPI_MEM_OP(SPI_MEM_OP_CMD(0x9f, 1), \
587- SPI_MEM_OP_NO_ADDR, \
588+ SPI_MEM_OP_ADDR(naddr, 0, 1), \
589 SPI_MEM_OP_DUMMY(ndummy, 1), \
590 SPI_MEM_OP_DATA_IN(len, buf, 1))
591
592@@ -176,37 +176,46 @@ struct spinand_device;
593 * @data: buffer containing the id bytes. Currently 4 bytes large, but can
594 * be extended if required
595 * @len: ID length
596- *
597- * struct_spinand_id->data contains all bytes returned after a READ_ID command,
598- * including dummy bytes if the chip does not emit ID bytes right after the
599- * READ_ID command. The responsibility to extract real ID bytes is left to
600- * struct_manufacurer_ops->detect().
601 */
602 struct spinand_id {
603 u8 data[SPINAND_MAX_ID_LEN];
604 int len;
605 };
606
607+enum spinand_readid_method {
608+ SPINAND_READID_METHOD_OPCODE,
609+ SPINAND_READID_METHOD_OPCODE_ADDR,
610+ SPINAND_READID_METHOD_OPCODE_DUMMY,
611+};
612+
613+/**
614+ * struct spinand_devid - SPI NAND device id structure
615+ * @id: device id of current chip
616+ * @len: number of bytes in device id
617+ * @method: method to read chip id
618+ * There are 3 possible variants:
619+ * SPINAND_READID_METHOD_OPCODE: chip id is returned immediately
620+ * after read_id opcode.
621+ * SPINAND_READID_METHOD_OPCODE_ADDR: chip id is returned after
622+ * read_id opcode + 1-byte address.
623+ * SPINAND_READID_METHOD_OPCODE_DUMMY: chip id is returned after
624+ * read_id opcode + 1 dummy byte.
625+ */
626+struct spinand_devid {
627+ const u8 *id;
628+ const u8 len;
629+ const enum spinand_readid_method method;
630+};
631+
632 /**
633 * struct manufacurer_ops - SPI NAND manufacturer specific operations
634- * @detect: detect a SPI NAND device. Every time a SPI NAND device is probed
635- * the core calls the struct_manufacurer_ops->detect() hook of each
636- * registered manufacturer until one of them return 1. Note that
637- * the first thing to check in this hook is that the manufacturer ID
638- * in struct_spinand_device->id matches the manufacturer whose
639- * ->detect() hook has been called. Should return 1 if there's a
640- * match, 0 if the manufacturer ID does not match and a negative
641- * error code otherwise. When true is returned, the core assumes
642- * that properties of the NAND chip (spinand->base.memorg and
643- * spinand->base.eccreq) have been filled
644 * @init: initialize a SPI NAND device
645 * @cleanup: cleanup a SPI NAND device
646 *
647 * Each SPI NAND manufacturer driver should implement this interface so that
648- * NAND chips coming from this vendor can be detected and initialized properly.
649+ * NAND chips coming from this vendor can be initialized properly.
650 */
651 struct spinand_manufacturer_ops {
652- int (*detect)(struct spinand_device *spinand);
653 int (*init)(struct spinand_device *spinand);
654 void (*cleanup)(struct spinand_device *spinand);
655 };
656@@ -215,11 +224,16 @@ struct spinand_manufacturer_ops {
657 * struct spinand_manufacturer - SPI NAND manufacturer instance
658 * @id: manufacturer ID
659 * @name: manufacturer name
660+ * @devid_len: number of bytes in device ID
661+ * @chips: supported SPI NANDs under current manufacturer
662+ * @nchips: number of SPI NANDs available in chips array
663 * @ops: manufacturer operations
664 */
665 struct spinand_manufacturer {
666 u8 id;
667 char *name;
668+ const struct spinand_info *chips;
669+ const size_t nchips;
670 const struct spinand_manufacturer_ops *ops;
671 };
672
673@@ -291,7 +305,7 @@ struct spinand_ecc_info {
674 */
675 struct spinand_info {
676 const char *model;
677- u16 devid;
678+ struct spinand_devid devid;
679 u32 flags;
680 struct nand_memory_organization memorg;
681 struct nand_ecc_req eccreq;
682@@ -305,6 +319,13 @@ struct spinand_info {
683 unsigned int target);
684 };
685
686+#define SPINAND_ID(__method, ...) \
687+ { \
688+ .id = (const u8[]){ __VA_ARGS__ }, \
689+ .len = sizeof((u8[]){ __VA_ARGS__ }), \
690+ .method = __method, \
691+ }
692+
693 #define SPINAND_INFO_OP_VARIANTS(__read, __write, __update) \
694 { \
695 .read_cache = __read, \
696@@ -451,9 +472,10 @@ static inline void spinand_set_of_node(s
697 nanddev_set_of_node(&spinand->base, np);
698 }
699
700-int spinand_match_and_init(struct spinand_device *dev,
701+int spinand_match_and_init(struct spinand_device *spinand,
702 const struct spinand_info *table,
703- unsigned int table_size, u16 devid);
704+ unsigned int table_size,
705+ enum spinand_readid_method rdid_method);
706
707 int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val);
708 int spinand_select_target(struct spinand_device *spinand, unsigned int target);