micron-st.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2005, Intec Automation Inc.
  4. * Copyright (C) 2014, Freescale Semiconductor, Inc.
  5. */
  6. #include <linux/mtd/spi-nor.h>
  7. #include "core.h"
  8. /* flash_info mfr_flag. Used to read proprietary FSR register. */
  9. #define USE_FSR BIT(0)
  10. #define SPINOR_OP_RDFSR 0x70 /* Read flag status register */
  11. #define SPINOR_OP_CLFSR 0x50 /* Clear flag status register */
  12. #define SPINOR_OP_MT_DTR_RD 0xfd /* Fast Read opcode in DTR mode */
  13. #define SPINOR_OP_MT_RD_ANY_REG 0x85 /* Read volatile register */
  14. #define SPINOR_OP_MT_WR_ANY_REG 0x81 /* Write volatile register */
  15. #define SPINOR_REG_MT_CFR0V 0x00 /* For setting octal DTR mode */
  16. #define SPINOR_REG_MT_CFR1V 0x01 /* For setting dummy cycles */
  17. #define SPINOR_REG_MT_CFR1V_DEF 0x1f /* Default dummy cycles */
  18. #define SPINOR_MT_OCT_DTR 0xe7 /* Enable Octal DTR. */
  19. #define SPINOR_MT_EXSPI 0xff /* Enable Extended SPI (default) */
  20. /* Flag Status Register bits */
  21. #define FSR_READY BIT(7) /* Device status, 0 = Busy, 1 = Ready */
  22. #define FSR_E_ERR BIT(5) /* Erase operation status */
  23. #define FSR_P_ERR BIT(4) /* Program operation status */
  24. #define FSR_PT_ERR BIT(1) /* Protection error bit */
  25. /* Micron ST SPI NOR flash operations. */
  26. #define MICRON_ST_NOR_WR_ANY_REG_OP(naddr, addr, ndata, buf) \
  27. SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_MT_WR_ANY_REG, 0), \
  28. SPI_MEM_OP_ADDR(naddr, addr, 0), \
  29. SPI_MEM_OP_NO_DUMMY, \
  30. SPI_MEM_OP_DATA_OUT(ndata, buf, 0))
  31. #define MICRON_ST_RDFSR_OP(buf) \
  32. SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDFSR, 0), \
  33. SPI_MEM_OP_NO_ADDR, \
  34. SPI_MEM_OP_NO_DUMMY, \
  35. SPI_MEM_OP_DATA_IN(1, buf, 0))
  36. #define MICRON_ST_CLFSR_OP \
  37. SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLFSR, 0), \
  38. SPI_MEM_OP_NO_ADDR, \
  39. SPI_MEM_OP_NO_DUMMY, \
  40. SPI_MEM_OP_NO_DATA)
  41. static int micron_st_nor_octal_dtr_en(struct spi_nor *nor)
  42. {
  43. struct spi_mem_op op;
  44. u8 *buf = nor->bouncebuf;
  45. int ret;
  46. /* Use 20 dummy cycles for memory array reads. */
  47. *buf = 20;
  48. op = (struct spi_mem_op)
  49. MICRON_ST_NOR_WR_ANY_REG_OP(3, SPINOR_REG_MT_CFR1V, 1, buf);
  50. ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
  51. if (ret)
  52. return ret;
  53. buf[0] = SPINOR_MT_OCT_DTR;
  54. op = (struct spi_mem_op)
  55. MICRON_ST_NOR_WR_ANY_REG_OP(3, SPINOR_REG_MT_CFR0V, 1, buf);
  56. ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
  57. if (ret)
  58. return ret;
  59. /* Read flash ID to make sure the switch was successful. */
  60. ret = spi_nor_read_id(nor, 0, 8, buf, SNOR_PROTO_8_8_8_DTR);
  61. if (ret) {
  62. dev_dbg(nor->dev, "error %d reading JEDEC ID after enabling 8D-8D-8D mode\n", ret);
  63. return ret;
  64. }
  65. if (memcmp(buf, nor->info->id, nor->info->id_len))
  66. return -EINVAL;
  67. return 0;
  68. }
  69. static int micron_st_nor_octal_dtr_dis(struct spi_nor *nor)
  70. {
  71. struct spi_mem_op op;
  72. u8 *buf = nor->bouncebuf;
  73. int ret;
  74. /*
  75. * The register is 1-byte wide, but 1-byte transactions are not allowed
  76. * in 8D-8D-8D mode. The next register is the dummy cycle configuration
  77. * register. Since the transaction needs to be at least 2 bytes wide,
  78. * set the next register to its default value. This also makes sense
  79. * because the value was changed when enabling 8D-8D-8D mode, it should
  80. * be reset when disabling.
  81. */
  82. buf[0] = SPINOR_MT_EXSPI;
  83. buf[1] = SPINOR_REG_MT_CFR1V_DEF;
  84. op = (struct spi_mem_op)
  85. MICRON_ST_NOR_WR_ANY_REG_OP(4, SPINOR_REG_MT_CFR0V, 2, buf);
  86. ret = spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR);
  87. if (ret)
  88. return ret;
  89. /* Read flash ID to make sure the switch was successful. */
  90. ret = spi_nor_read_id(nor, 0, 0, buf, SNOR_PROTO_1_1_1);
  91. if (ret) {
  92. dev_dbg(nor->dev, "error %d reading JEDEC ID after disabling 8D-8D-8D mode\n", ret);
  93. return ret;
  94. }
  95. if (memcmp(buf, nor->info->id, nor->info->id_len))
  96. return -EINVAL;
  97. return 0;
  98. }
  99. static int micron_st_nor_octal_dtr_enable(struct spi_nor *nor, bool enable)
  100. {
  101. return enable ? micron_st_nor_octal_dtr_en(nor) :
  102. micron_st_nor_octal_dtr_dis(nor);
  103. }
  104. static void mt35xu512aba_default_init(struct spi_nor *nor)
  105. {
  106. nor->params->octal_dtr_enable = micron_st_nor_octal_dtr_enable;
  107. }
  108. static void mt35xu512aba_post_sfdp_fixup(struct spi_nor *nor)
  109. {
  110. /* Set the Fast Read settings. */
  111. nor->params->hwcaps.mask |= SNOR_HWCAPS_READ_8_8_8_DTR;
  112. spi_nor_set_read_settings(&nor->params->reads[SNOR_CMD_READ_8_8_8_DTR],
  113. 0, 20, SPINOR_OP_MT_DTR_RD,
  114. SNOR_PROTO_8_8_8_DTR);
  115. nor->cmd_ext_type = SPI_NOR_EXT_REPEAT;
  116. nor->params->rdsr_dummy = 8;
  117. nor->params->rdsr_addr_nbytes = 0;
  118. /*
  119. * The BFPT quad enable field is set to a reserved value so the quad
  120. * enable function is ignored by spi_nor_parse_bfpt(). Make sure we
  121. * disable it.
  122. */
  123. nor->params->quad_enable = NULL;
  124. }
  125. static const struct spi_nor_fixups mt35xu512aba_fixups = {
  126. .default_init = mt35xu512aba_default_init,
  127. .post_sfdp = mt35xu512aba_post_sfdp_fixup,
  128. };
  129. static const struct flash_info micron_nor_parts[] = {
  130. { "mt35xu512aba", INFO(0x2c5b1a, 0, 128 * 1024, 512)
  131. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_OCTAL_READ |
  132. SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP)
  133. FIXUP_FLAGS(SPI_NOR_4B_OPCODES | SPI_NOR_IO_MODE_EN_VOLATILE)
  134. MFR_FLAGS(USE_FSR)
  135. .fixups = &mt35xu512aba_fixups
  136. },
  137. { "mt35xu02g", INFO(0x2c5b1c, 0, 128 * 1024, 2048)
  138. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_OCTAL_READ)
  139. FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
  140. MFR_FLAGS(USE_FSR)
  141. },
  142. };
  143. static const struct flash_info st_nor_parts[] = {
  144. { "n25q016a", INFO(0x20bb15, 0, 64 * 1024, 32)
  145. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) },
  146. { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64)
  147. NO_SFDP_FLAGS(SPI_NOR_QUAD_READ) },
  148. { "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64)
  149. NO_SFDP_FLAGS(SPI_NOR_QUAD_READ) },
  150. { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128)
  151. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) },
  152. { "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128)
  153. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ) },
  154. { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256)
  155. FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
  156. SPI_NOR_BP3_SR_BIT6)
  157. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ)
  158. MFR_FLAGS(USE_FSR)
  159. },
  160. { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256)
  161. FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
  162. SPI_NOR_BP3_SR_BIT6)
  163. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ)
  164. MFR_FLAGS(USE_FSR)
  165. },
  166. { "mt25ql256a", INFO6(0x20ba19, 0x104400, 64 * 1024, 512)
  167. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  168. FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
  169. MFR_FLAGS(USE_FSR)
  170. },
  171. { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512)
  172. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
  173. SPI_NOR_QUAD_READ)
  174. MFR_FLAGS(USE_FSR)
  175. },
  176. { "mt25qu256a", INFO6(0x20bb19, 0x104400, 64 * 1024, 512)
  177. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  178. FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
  179. MFR_FLAGS(USE_FSR)
  180. },
  181. { "n25q256ax1", INFO(0x20bb19, 0, 64 * 1024, 512)
  182. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ)
  183. MFR_FLAGS(USE_FSR)
  184. },
  185. { "mt25ql512a", INFO6(0x20ba20, 0x104400, 64 * 1024, 1024)
  186. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  187. FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
  188. MFR_FLAGS(USE_FSR)
  189. },
  190. { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024)
  191. FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
  192. SPI_NOR_BP3_SR_BIT6)
  193. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ)
  194. MFR_FLAGS(USE_FSR)
  195. },
  196. { "mt25qu512a", INFO6(0x20bb20, 0x104400, 64 * 1024, 1024)
  197. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
  198. FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
  199. MFR_FLAGS(USE_FSR)
  200. },
  201. { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024)
  202. FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
  203. SPI_NOR_BP3_SR_BIT6)
  204. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ)
  205. MFR_FLAGS(USE_FSR)
  206. },
  207. { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048)
  208. FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
  209. SPI_NOR_BP3_SR_BIT6 | NO_CHIP_ERASE)
  210. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ)
  211. MFR_FLAGS(USE_FSR)
  212. },
  213. { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048)
  214. FLAGS(NO_CHIP_ERASE)
  215. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ)
  216. MFR_FLAGS(USE_FSR)
  217. },
  218. { "mt25ql02g", INFO(0x20ba22, 0, 64 * 1024, 4096)
  219. FLAGS(NO_CHIP_ERASE)
  220. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ)
  221. MFR_FLAGS(USE_FSR)
  222. },
  223. { "mt25qu02g", INFO(0x20bb22, 0, 64 * 1024, 4096)
  224. FLAGS(NO_CHIP_ERASE)
  225. NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
  226. SPI_NOR_QUAD_READ)
  227. MFR_FLAGS(USE_FSR)
  228. },
  229. { "m25p05", INFO(0x202010, 0, 32 * 1024, 2) },
  230. { "m25p10", INFO(0x202011, 0, 32 * 1024, 4) },
  231. { "m25p20", INFO(0x202012, 0, 64 * 1024, 4) },
  232. { "m25p40", INFO(0x202013, 0, 64 * 1024, 8) },
  233. { "m25p80", INFO(0x202014, 0, 64 * 1024, 16) },
  234. { "m25p16", INFO(0x202015, 0, 64 * 1024, 32) },
  235. { "m25p32", INFO(0x202016, 0, 64 * 1024, 64) },
  236. { "m25p64", INFO(0x202017, 0, 64 * 1024, 128) },
  237. { "m25p128", INFO(0x202018, 0, 256 * 1024, 64) },
  238. { "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2) },
  239. { "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4) },
  240. { "m25p20-nonjedec", INFO(0, 0, 64 * 1024, 4) },
  241. { "m25p40-nonjedec", INFO(0, 0, 64 * 1024, 8) },
  242. { "m25p80-nonjedec", INFO(0, 0, 64 * 1024, 16) },
  243. { "m25p16-nonjedec", INFO(0, 0, 64 * 1024, 32) },
  244. { "m25p32-nonjedec", INFO(0, 0, 64 * 1024, 64) },
  245. { "m25p64-nonjedec", INFO(0, 0, 64 * 1024, 128) },
  246. { "m25p128-nonjedec", INFO(0, 0, 256 * 1024, 64) },
  247. { "m45pe10", INFO(0x204011, 0, 64 * 1024, 2) },
  248. { "m45pe80", INFO(0x204014, 0, 64 * 1024, 16) },
  249. { "m45pe16", INFO(0x204015, 0, 64 * 1024, 32) },
  250. { "m25pe20", INFO(0x208012, 0, 64 * 1024, 4) },
  251. { "m25pe80", INFO(0x208014, 0, 64 * 1024, 16) },
  252. { "m25pe16", INFO(0x208015, 0, 64 * 1024, 32)
  253. NO_SFDP_FLAGS(SECT_4K) },
  254. { "m25px16", INFO(0x207115, 0, 64 * 1024, 32)
  255. NO_SFDP_FLAGS(SECT_4K) },
  256. { "m25px32", INFO(0x207116, 0, 64 * 1024, 64)
  257. NO_SFDP_FLAGS(SECT_4K) },
  258. { "m25px32-s0", INFO(0x207316, 0, 64 * 1024, 64)
  259. NO_SFDP_FLAGS(SECT_4K) },
  260. { "m25px32-s1", INFO(0x206316, 0, 64 * 1024, 64)
  261. NO_SFDP_FLAGS(SECT_4K) },
  262. { "m25px64", INFO(0x207117, 0, 64 * 1024, 128) },
  263. { "m25px80", INFO(0x207114, 0, 64 * 1024, 16) },
  264. };
  265. /**
  266. * micron_st_nor_set_4byte_addr_mode() - Set 4-byte address mode for ST and
  267. * Micron flashes.
  268. * @nor: pointer to 'struct spi_nor'.
  269. * @enable: true to enter the 4-byte address mode, false to exit the 4-byte
  270. * address mode.
  271. *
  272. * Return: 0 on success, -errno otherwise.
  273. */
  274. static int micron_st_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable)
  275. {
  276. int ret;
  277. ret = spi_nor_write_enable(nor);
  278. if (ret)
  279. return ret;
  280. ret = spi_nor_set_4byte_addr_mode(nor, enable);
  281. if (ret)
  282. return ret;
  283. return spi_nor_write_disable(nor);
  284. }
  285. /**
  286. * micron_st_nor_read_fsr() - Read the Flag Status Register.
  287. * @nor: pointer to 'struct spi_nor'
  288. * @fsr: pointer to a DMA-able buffer where the value of the
  289. * Flag Status Register will be written. Should be at least 2
  290. * bytes.
  291. *
  292. * Return: 0 on success, -errno otherwise.
  293. */
  294. static int micron_st_nor_read_fsr(struct spi_nor *nor, u8 *fsr)
  295. {
  296. int ret;
  297. if (nor->spimem) {
  298. struct spi_mem_op op = MICRON_ST_RDFSR_OP(fsr);
  299. if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) {
  300. op.addr.nbytes = nor->params->rdsr_addr_nbytes;
  301. op.dummy.nbytes = nor->params->rdsr_dummy;
  302. /*
  303. * We don't want to read only one byte in DTR mode. So,
  304. * read 2 and then discard the second byte.
  305. */
  306. op.data.nbytes = 2;
  307. }
  308. spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
  309. ret = spi_mem_exec_op(nor->spimem, &op);
  310. } else {
  311. ret = spi_nor_controller_ops_read_reg(nor, SPINOR_OP_RDFSR, fsr,
  312. 1);
  313. }
  314. if (ret)
  315. dev_dbg(nor->dev, "error %d reading FSR\n", ret);
  316. return ret;
  317. }
  318. /**
  319. * micron_st_nor_clear_fsr() - Clear the Flag Status Register.
  320. * @nor: pointer to 'struct spi_nor'.
  321. */
  322. static void micron_st_nor_clear_fsr(struct spi_nor *nor)
  323. {
  324. int ret;
  325. if (nor->spimem) {
  326. struct spi_mem_op op = MICRON_ST_CLFSR_OP;
  327. spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
  328. ret = spi_mem_exec_op(nor->spimem, &op);
  329. } else {
  330. ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLFSR,
  331. NULL, 0);
  332. }
  333. if (ret)
  334. dev_dbg(nor->dev, "error %d clearing FSR\n", ret);
  335. }
  336. /**
  337. * micron_st_nor_ready() - Query the Status Register as well as the Flag Status
  338. * Register to see if the flash is ready for new commands. If there are any
  339. * errors in the FSR clear them.
  340. * @nor: pointer to 'struct spi_nor'.
  341. *
  342. * Return: 1 if ready, 0 if not ready, -errno on errors.
  343. */
  344. static int micron_st_nor_ready(struct spi_nor *nor)
  345. {
  346. int sr_ready, ret;
  347. sr_ready = spi_nor_sr_ready(nor);
  348. if (sr_ready < 0)
  349. return sr_ready;
  350. ret = micron_st_nor_read_fsr(nor, nor->bouncebuf);
  351. if (ret) {
  352. /*
  353. * Some controllers, such as Intel SPI, do not support low
  354. * level operations such as reading the flag status
  355. * register. They only expose small amount of high level
  356. * operations to the software. If this is the case we use
  357. * only the status register value.
  358. */
  359. return ret == -EOPNOTSUPP ? sr_ready : ret;
  360. }
  361. if (nor->bouncebuf[0] & (FSR_E_ERR | FSR_P_ERR)) {
  362. if (nor->bouncebuf[0] & FSR_E_ERR)
  363. dev_err(nor->dev, "Erase operation failed.\n");
  364. else
  365. dev_err(nor->dev, "Program operation failed.\n");
  366. if (nor->bouncebuf[0] & FSR_PT_ERR)
  367. dev_err(nor->dev,
  368. "Attempted to modify a protected sector.\n");
  369. micron_st_nor_clear_fsr(nor);
  370. /*
  371. * WEL bit remains set to one when an erase or page program
  372. * error occurs. Issue a Write Disable command to protect
  373. * against inadvertent writes that can possibly corrupt the
  374. * contents of the memory.
  375. */
  376. ret = spi_nor_write_disable(nor);
  377. if (ret)
  378. return ret;
  379. return -EIO;
  380. }
  381. return sr_ready && !!(nor->bouncebuf[0] & FSR_READY);
  382. }
  383. static void micron_st_nor_default_init(struct spi_nor *nor)
  384. {
  385. nor->flags |= SNOR_F_HAS_LOCK;
  386. nor->flags &= ~SNOR_F_HAS_16BIT_SR;
  387. nor->params->quad_enable = NULL;
  388. nor->params->set_4byte_addr_mode = micron_st_nor_set_4byte_addr_mode;
  389. }
  390. static void micron_st_nor_late_init(struct spi_nor *nor)
  391. {
  392. if (nor->info->mfr_flags & USE_FSR)
  393. nor->params->ready = micron_st_nor_ready;
  394. }
  395. static const struct spi_nor_fixups micron_st_nor_fixups = {
  396. .default_init = micron_st_nor_default_init,
  397. .late_init = micron_st_nor_late_init,
  398. };
  399. const struct spi_nor_manufacturer spi_nor_micron = {
  400. .name = "micron",
  401. .parts = micron_nor_parts,
  402. .nparts = ARRAY_SIZE(micron_nor_parts),
  403. .fixups = &micron_st_nor_fixups,
  404. };
  405. const struct spi_nor_manufacturer spi_nor_st = {
  406. .name = "st",
  407. .parts = st_nor_parts,
  408. .nparts = ARRAY_SIZE(st_nor_parts),
  409. .fixups = &micron_st_nor_fixups,
  410. };