spansion.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092
  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/bitfield.h>
  7. #include <linux/device.h>
  8. #include <linux/errno.h>
  9. #include <linux/mtd/spi-nor.h>
  10. #include "core.h"
  11. /* flash_info mfr_flag. Used to clear sticky prorietary SR bits. */
  12. #define USE_CLSR BIT(0)
  13. #define USE_CLPEF BIT(1)
  14. #define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */
  15. #define SPINOR_OP_CLPEF 0x82 /* Clear program/erase failure flags */
  16. #define SPINOR_OP_CYPRESS_DIE_ERASE 0x61 /* Chip (die) erase */
  17. #define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */
  18. #define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */
  19. #define SPINOR_REG_CYPRESS_VREG 0x00800000
  20. #define SPINOR_REG_CYPRESS_STR1 0x0
  21. #define SPINOR_REG_CYPRESS_STR1V \
  22. (SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_STR1)
  23. #define SPINOR_REG_CYPRESS_CFR1 0x2
  24. #define SPINOR_REG_CYPRESS_CFR1_QUAD_EN BIT(1) /* Quad Enable */
  25. #define SPINOR_REG_CYPRESS_CFR2 0x3
  26. #define SPINOR_REG_CYPRESS_CFR2V \
  27. (SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_CFR2)
  28. #define SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK GENMASK(3, 0)
  29. #define SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24 0xb
  30. #define SPINOR_REG_CYPRESS_CFR2_ADRBYT BIT(7)
  31. #define SPINOR_REG_CYPRESS_CFR3 0x4
  32. #define SPINOR_REG_CYPRESS_CFR3_PGSZ BIT(4) /* Page size. */
  33. #define SPINOR_REG_CYPRESS_CFR5 0x6
  34. #define SPINOR_REG_CYPRESS_CFR5_BIT6 BIT(6)
  35. #define SPINOR_REG_CYPRESS_CFR5_DDR BIT(1)
  36. #define SPINOR_REG_CYPRESS_CFR5_OPI BIT(0)
  37. #define SPINOR_REG_CYPRESS_CFR5_OCT_DTR_EN \
  38. (SPINOR_REG_CYPRESS_CFR5_BIT6 | SPINOR_REG_CYPRESS_CFR5_DDR | \
  39. SPINOR_REG_CYPRESS_CFR5_OPI)
  40. #define SPINOR_REG_CYPRESS_CFR5_OCT_DTR_DS SPINOR_REG_CYPRESS_CFR5_BIT6
  41. #define SPINOR_OP_CYPRESS_RD_FAST 0xee
  42. #define SPINOR_REG_CYPRESS_ARCFN 0x00000006
  43. /* Cypress SPI NOR flash operations. */
  44. #define CYPRESS_NOR_WR_ANY_REG_OP(naddr, addr, ndata, buf) \
  45. SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 0), \
  46. SPI_MEM_OP_ADDR(naddr, addr, 0), \
  47. SPI_MEM_OP_NO_DUMMY, \
  48. SPI_MEM_OP_DATA_OUT(ndata, buf, 0))
  49. #define CYPRESS_NOR_RD_ANY_REG_OP(naddr, addr, ndummy, buf) \
  50. SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 0), \
  51. SPI_MEM_OP_ADDR(naddr, addr, 0), \
  52. SPI_MEM_OP_DUMMY(ndummy, 0), \
  53. SPI_MEM_OP_DATA_IN(1, buf, 0))
  54. #define SPANSION_OP(opcode) \
  55. SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), \
  56. SPI_MEM_OP_NO_ADDR, \
  57. SPI_MEM_OP_NO_DUMMY, \
  58. SPI_MEM_OP_NO_DATA)
  59. /**
  60. * struct spansion_nor_params - Spansion private parameters.
  61. * @clsr: Clear Status Register or Clear Program and Erase Failure Flag
  62. * opcode.
  63. */
  64. struct spansion_nor_params {
  65. u8 clsr;
  66. };
  67. /**
  68. * spansion_nor_clear_sr() - Clear the Status Register.
  69. * @nor: pointer to 'struct spi_nor'.
  70. */
  71. static void spansion_nor_clear_sr(struct spi_nor *nor)
  72. {
  73. const struct spansion_nor_params *priv_params = nor->params->priv;
  74. int ret;
  75. if (nor->spimem) {
  76. struct spi_mem_op op = SPANSION_OP(priv_params->clsr);
  77. spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
  78. ret = spi_mem_exec_op(nor->spimem, &op);
  79. } else {
  80. ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLSR,
  81. NULL, 0);
  82. }
  83. if (ret)
  84. dev_dbg(nor->dev, "error %d clearing SR\n", ret);
  85. }
  86. static int cypress_nor_sr_ready_and_clear_reg(struct spi_nor *nor, u64 addr)
  87. {
  88. struct spi_nor_flash_parameter *params = nor->params;
  89. struct spi_mem_op op =
  90. CYPRESS_NOR_RD_ANY_REG_OP(params->addr_mode_nbytes, addr,
  91. 0, nor->bouncebuf);
  92. int ret;
  93. if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) {
  94. op.addr.nbytes = nor->addr_nbytes;
  95. op.dummy.nbytes = params->rdsr_dummy;
  96. op.data.nbytes = 2;
  97. }
  98. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  99. if (ret)
  100. return ret;
  101. if (nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
  102. if (nor->bouncebuf[0] & SR_E_ERR)
  103. dev_err(nor->dev, "Erase Error occurred\n");
  104. else
  105. dev_err(nor->dev, "Programming Error occurred\n");
  106. spansion_nor_clear_sr(nor);
  107. ret = spi_nor_write_disable(nor);
  108. if (ret)
  109. return ret;
  110. return -EIO;
  111. }
  112. return !(nor->bouncebuf[0] & SR_WIP);
  113. }
  114. /**
  115. * cypress_nor_sr_ready_and_clear() - Query the Status Register of each die by
  116. * using Read Any Register command to see if the whole flash is ready for new
  117. * commands and clear it if there are any errors.
  118. * @nor: pointer to 'struct spi_nor'.
  119. *
  120. * Return: 1 if ready, 0 if not ready, -errno on errors.
  121. */
  122. static int cypress_nor_sr_ready_and_clear(struct spi_nor *nor)
  123. {
  124. struct spi_nor_flash_parameter *params = nor->params;
  125. u64 addr;
  126. int ret;
  127. u8 i;
  128. for (i = 0; i < params->n_dice; i++) {
  129. addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_STR1;
  130. ret = cypress_nor_sr_ready_and_clear_reg(nor, addr);
  131. if (ret < 0)
  132. return ret;
  133. else if (ret == 0)
  134. return 0;
  135. }
  136. return 1;
  137. }
  138. static int cypress_nor_set_memlat(struct spi_nor *nor, u64 addr)
  139. {
  140. struct spi_mem_op op;
  141. u8 *buf = nor->bouncebuf;
  142. int ret;
  143. u8 addr_mode_nbytes = nor->params->addr_mode_nbytes;
  144. op = (struct spi_mem_op)
  145. CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, addr, 0, buf);
  146. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  147. if (ret)
  148. return ret;
  149. /* Use 24 dummy cycles for memory array reads. */
  150. *buf &= ~SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK;
  151. *buf |= FIELD_PREP(SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK,
  152. SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24);
  153. op = (struct spi_mem_op)
  154. CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, addr, 1, buf);
  155. ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
  156. if (ret)
  157. return ret;
  158. nor->read_dummy = 24;
  159. return 0;
  160. }
  161. static int cypress_nor_set_octal_dtr_bits(struct spi_nor *nor, u64 addr)
  162. {
  163. struct spi_mem_op op;
  164. u8 *buf = nor->bouncebuf;
  165. /* Set the octal and DTR enable bits. */
  166. buf[0] = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_EN;
  167. op = (struct spi_mem_op)
  168. CYPRESS_NOR_WR_ANY_REG_OP(nor->params->addr_mode_nbytes,
  169. addr, 1, buf);
  170. return spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
  171. }
  172. static int cypress_nor_octal_dtr_en(struct spi_nor *nor)
  173. {
  174. const struct spi_nor_flash_parameter *params = nor->params;
  175. u8 *buf = nor->bouncebuf;
  176. u64 addr;
  177. int i, ret;
  178. for (i = 0; i < params->n_dice; i++) {
  179. addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR2;
  180. ret = cypress_nor_set_memlat(nor, addr);
  181. if (ret)
  182. return ret;
  183. addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR5;
  184. ret = cypress_nor_set_octal_dtr_bits(nor, addr);
  185. if (ret)
  186. return ret;
  187. }
  188. /* Read flash ID to make sure the switch was successful. */
  189. ret = spi_nor_read_id(nor, nor->addr_nbytes, 3, buf,
  190. SNOR_PROTO_8_8_8_DTR);
  191. if (ret) {
  192. dev_dbg(nor->dev, "error %d reading JEDEC ID after enabling 8D-8D-8D mode\n", ret);
  193. return ret;
  194. }
  195. if (memcmp(buf, nor->info->id->bytes, nor->info->id->len))
  196. return -EINVAL;
  197. return 0;
  198. }
  199. static int cypress_nor_set_single_spi_bits(struct spi_nor *nor, u64 addr)
  200. {
  201. struct spi_mem_op op;
  202. u8 *buf = nor->bouncebuf;
  203. /*
  204. * The register is 1-byte wide, but 1-byte transactions are not allowed
  205. * in 8D-8D-8D mode. Since there is no register at the next location,
  206. * just initialize the value to 0 and let the transaction go on.
  207. */
  208. buf[0] = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_DS;
  209. buf[1] = 0;
  210. op = (struct spi_mem_op)
  211. CYPRESS_NOR_WR_ANY_REG_OP(nor->addr_nbytes, addr, 2, buf);
  212. return spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR);
  213. }
  214. static int cypress_nor_octal_dtr_dis(struct spi_nor *nor)
  215. {
  216. const struct spi_nor_flash_parameter *params = nor->params;
  217. u8 *buf = nor->bouncebuf;
  218. u64 addr;
  219. int i, ret;
  220. for (i = 0; i < params->n_dice; i++) {
  221. addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR5;
  222. ret = cypress_nor_set_single_spi_bits(nor, addr);
  223. if (ret)
  224. return ret;
  225. }
  226. /* Read flash ID to make sure the switch was successful. */
  227. ret = spi_nor_read_id(nor, 0, 0, buf, SNOR_PROTO_1_1_1);
  228. if (ret) {
  229. dev_dbg(nor->dev, "error %d reading JEDEC ID after disabling 8D-8D-8D mode\n", ret);
  230. return ret;
  231. }
  232. if (memcmp(buf, nor->info->id->bytes, nor->info->id->len))
  233. return -EINVAL;
  234. return 0;
  235. }
  236. static int cypress_nor_quad_enable_volatile_reg(struct spi_nor *nor, u64 addr)
  237. {
  238. struct spi_mem_op op;
  239. u8 addr_mode_nbytes = nor->params->addr_mode_nbytes;
  240. u8 cfr1v_written;
  241. int ret;
  242. op = (struct spi_mem_op)
  243. CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, addr, 0,
  244. nor->bouncebuf);
  245. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  246. if (ret)
  247. return ret;
  248. if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR1_QUAD_EN)
  249. return 0;
  250. /* Update the Quad Enable bit. */
  251. nor->bouncebuf[0] |= SPINOR_REG_CYPRESS_CFR1_QUAD_EN;
  252. op = (struct spi_mem_op)
  253. CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, addr, 1,
  254. nor->bouncebuf);
  255. ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
  256. if (ret)
  257. return ret;
  258. cfr1v_written = nor->bouncebuf[0];
  259. /* Read back and check it. */
  260. op = (struct spi_mem_op)
  261. CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, addr, 0,
  262. nor->bouncebuf);
  263. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  264. if (ret)
  265. return ret;
  266. if (nor->bouncebuf[0] != cfr1v_written) {
  267. dev_err(nor->dev, "CFR1: Read back test failed\n");
  268. return -EIO;
  269. }
  270. return 0;
  271. }
  272. /**
  273. * cypress_nor_quad_enable_volatile() - enable Quad I/O mode in volatile
  274. * register.
  275. * @nor: pointer to a 'struct spi_nor'
  276. *
  277. * It is recommended to update volatile registers in the field application due
  278. * to a risk of the non-volatile registers corruption by power interrupt. This
  279. * function sets Quad Enable bit in CFR1 volatile. If users set the Quad Enable
  280. * bit in the CFR1 non-volatile in advance (typically by a Flash programmer
  281. * before mounting Flash on PCB), the Quad Enable bit in the CFR1 volatile is
  282. * also set during Flash power-up.
  283. *
  284. * Return: 0 on success, -errno otherwise.
  285. */
  286. static int cypress_nor_quad_enable_volatile(struct spi_nor *nor)
  287. {
  288. struct spi_nor_flash_parameter *params = nor->params;
  289. u64 addr;
  290. u8 i;
  291. int ret;
  292. for (i = 0; i < params->n_dice; i++) {
  293. addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR1;
  294. ret = cypress_nor_quad_enable_volatile_reg(nor, addr);
  295. if (ret)
  296. return ret;
  297. }
  298. return 0;
  299. }
  300. /**
  301. * cypress_nor_determine_addr_mode_by_sr1() - Determine current address mode
  302. * (3 or 4-byte) by querying status
  303. * register 1 (SR1).
  304. * @nor: pointer to a 'struct spi_nor'
  305. * @addr_mode: ponter to a buffer where we return the determined
  306. * address mode.
  307. *
  308. * This function tries to determine current address mode by comparing SR1 value
  309. * from RDSR1(no address), RDAR(3-byte address), and RDAR(4-byte address).
  310. *
  311. * Return: 0 on success, -errno otherwise.
  312. */
  313. static int cypress_nor_determine_addr_mode_by_sr1(struct spi_nor *nor,
  314. u8 *addr_mode)
  315. {
  316. struct spi_mem_op op =
  317. CYPRESS_NOR_RD_ANY_REG_OP(3, SPINOR_REG_CYPRESS_STR1V, 0,
  318. nor->bouncebuf);
  319. bool is3byte, is4byte;
  320. int ret;
  321. ret = spi_nor_read_sr(nor, &nor->bouncebuf[1]);
  322. if (ret)
  323. return ret;
  324. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  325. if (ret)
  326. return ret;
  327. is3byte = (nor->bouncebuf[0] == nor->bouncebuf[1]);
  328. op = (struct spi_mem_op)
  329. CYPRESS_NOR_RD_ANY_REG_OP(4, SPINOR_REG_CYPRESS_STR1V, 0,
  330. nor->bouncebuf);
  331. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  332. if (ret)
  333. return ret;
  334. is4byte = (nor->bouncebuf[0] == nor->bouncebuf[1]);
  335. if (is3byte == is4byte)
  336. return -EIO;
  337. if (is3byte)
  338. *addr_mode = 3;
  339. else
  340. *addr_mode = 4;
  341. return 0;
  342. }
  343. /**
  344. * cypress_nor_set_addr_mode_nbytes() - Set the number of address bytes mode of
  345. * current address mode.
  346. * @nor: pointer to a 'struct spi_nor'
  347. *
  348. * Determine current address mode by reading SR1 with different methods, then
  349. * query CFR2V[7] to confirm. If determination is failed, force enter to 4-byte
  350. * address mode.
  351. *
  352. * Return: 0 on success, -errno otherwise.
  353. */
  354. static int cypress_nor_set_addr_mode_nbytes(struct spi_nor *nor)
  355. {
  356. struct spi_mem_op op;
  357. u8 addr_mode;
  358. int ret;
  359. /*
  360. * Read SR1 by RDSR1 and RDAR(3- AND 4-byte addr). Use write enable
  361. * that sets bit-1 in SR1.
  362. */
  363. ret = spi_nor_write_enable(nor);
  364. if (ret)
  365. return ret;
  366. ret = cypress_nor_determine_addr_mode_by_sr1(nor, &addr_mode);
  367. if (ret) {
  368. ret = spi_nor_set_4byte_addr_mode(nor, true);
  369. if (ret)
  370. return ret;
  371. return spi_nor_write_disable(nor);
  372. }
  373. ret = spi_nor_write_disable(nor);
  374. if (ret)
  375. return ret;
  376. /*
  377. * Query CFR2V and make sure no contradiction between determined address
  378. * mode and CFR2V[7].
  379. */
  380. op = (struct spi_mem_op)
  381. CYPRESS_NOR_RD_ANY_REG_OP(addr_mode, SPINOR_REG_CYPRESS_CFR2V,
  382. 0, nor->bouncebuf);
  383. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  384. if (ret)
  385. return ret;
  386. if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR2_ADRBYT) {
  387. if (addr_mode != 4)
  388. return spi_nor_set_4byte_addr_mode(nor, true);
  389. } else {
  390. if (addr_mode != 3)
  391. return spi_nor_set_4byte_addr_mode(nor, true);
  392. }
  393. nor->params->addr_nbytes = addr_mode;
  394. nor->params->addr_mode_nbytes = addr_mode;
  395. return 0;
  396. }
  397. /**
  398. * cypress_nor_get_page_size() - Get flash page size configuration.
  399. * @nor: pointer to a 'struct spi_nor'
  400. *
  401. * The BFPT table advertises a 512B or 256B page size depending on part but the
  402. * page size is actually configurable (with the default being 256B). Read from
  403. * CFR3V[4] and set the correct size.
  404. *
  405. * Return: 0 on success, -errno otherwise.
  406. */
  407. static int cypress_nor_get_page_size(struct spi_nor *nor)
  408. {
  409. struct spi_mem_op op =
  410. CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes,
  411. 0, 0, nor->bouncebuf);
  412. struct spi_nor_flash_parameter *params = nor->params;
  413. int ret;
  414. u8 i;
  415. /*
  416. * Use the minimum common page size configuration. Programming 256-byte
  417. * under 512-byte page size configuration is safe.
  418. */
  419. params->page_size = 256;
  420. for (i = 0; i < params->n_dice; i++) {
  421. op.addr.val = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR3;
  422. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  423. if (ret)
  424. return ret;
  425. if (!(nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR3_PGSZ))
  426. return 0;
  427. }
  428. params->page_size = 512;
  429. return 0;
  430. }
  431. static void cypress_nor_ecc_init(struct spi_nor *nor)
  432. {
  433. /*
  434. * Programming is supported only in 16-byte ECC data unit granularity.
  435. * Byte-programming, bit-walking, or multiple program operations to the
  436. * same ECC data unit without an erase are not allowed.
  437. */
  438. nor->params->writesize = 16;
  439. nor->flags |= SNOR_F_ECC;
  440. }
  441. static int
  442. s25fs256t_post_bfpt_fixup(struct spi_nor *nor,
  443. const struct sfdp_parameter_header *bfpt_header,
  444. const struct sfdp_bfpt *bfpt)
  445. {
  446. struct spi_mem_op op;
  447. int ret;
  448. ret = cypress_nor_set_addr_mode_nbytes(nor);
  449. if (ret)
  450. return ret;
  451. /* Read Architecture Configuration Register (ARCFN) */
  452. op = (struct spi_mem_op)
  453. CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes,
  454. SPINOR_REG_CYPRESS_ARCFN, 1,
  455. nor->bouncebuf);
  456. ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
  457. if (ret)
  458. return ret;
  459. /* ARCFN value must be 0 if uniform sector is selected */
  460. if (nor->bouncebuf[0])
  461. return -ENODEV;
  462. return 0;
  463. }
  464. static int s25fs256t_post_sfdp_fixup(struct spi_nor *nor)
  465. {
  466. struct spi_nor_flash_parameter *params = nor->params;
  467. /*
  468. * S25FS256T does not define the SCCR map, but we would like to use the
  469. * same code base for both single and multi chip package devices, thus
  470. * set the vreg_offset and n_dice to be able to do so.
  471. */
  472. params->vreg_offset = devm_kmalloc(nor->dev, sizeof(u32), GFP_KERNEL);
  473. if (!params->vreg_offset)
  474. return -ENOMEM;
  475. params->vreg_offset[0] = SPINOR_REG_CYPRESS_VREG;
  476. params->n_dice = 1;
  477. /* PP_1_1_4_4B is supported but missing in 4BAIT. */
  478. params->hwcaps.mask |= SNOR_HWCAPS_PP_1_1_4;
  479. spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_1_1_4],
  480. SPINOR_OP_PP_1_1_4_4B,
  481. SNOR_PROTO_1_1_4);
  482. return cypress_nor_get_page_size(nor);
  483. }
  484. static int s25fs256t_late_init(struct spi_nor *nor)
  485. {
  486. cypress_nor_ecc_init(nor);
  487. return 0;
  488. }
  489. static struct spi_nor_fixups s25fs256t_fixups = {
  490. .post_bfpt = s25fs256t_post_bfpt_fixup,
  491. .post_sfdp = s25fs256t_post_sfdp_fixup,
  492. .late_init = s25fs256t_late_init,
  493. };
  494. static int
  495. s25hx_t_post_bfpt_fixup(struct spi_nor *nor,
  496. const struct sfdp_parameter_header *bfpt_header,
  497. const struct sfdp_bfpt *bfpt)
  498. {
  499. int ret;
  500. ret = cypress_nor_set_addr_mode_nbytes(nor);
  501. if (ret)
  502. return ret;
  503. /* Replace Quad Enable with volatile version */
  504. nor->params->quad_enable = cypress_nor_quad_enable_volatile;
  505. return 0;
  506. }
  507. static int s25hx_t_post_sfdp_fixup(struct spi_nor *nor)
  508. {
  509. struct spi_nor_flash_parameter *params = nor->params;
  510. struct spi_nor_erase_type *erase_type = params->erase_map.erase_type;
  511. unsigned int i;
  512. if (!params->n_dice || !params->vreg_offset) {
  513. dev_err(nor->dev, "%s failed. The volatile register offset could not be retrieved from SFDP.\n",
  514. __func__);
  515. return -EOPNOTSUPP;
  516. }
  517. /* The 2 Gb parts duplicate info and advertise 4 dice instead of 2. */
  518. if (params->size == SZ_256M)
  519. params->n_dice = 2;
  520. /*
  521. * In some parts, 3byte erase opcodes are advertised by 4BAIT.
  522. * Convert them to 4byte erase opcodes.
  523. */
  524. for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) {
  525. switch (erase_type[i].opcode) {
  526. case SPINOR_OP_SE:
  527. erase_type[i].opcode = SPINOR_OP_SE_4B;
  528. break;
  529. case SPINOR_OP_BE_4K:
  530. erase_type[i].opcode = SPINOR_OP_BE_4K_4B;
  531. break;
  532. default:
  533. break;
  534. }
  535. }
  536. return cypress_nor_get_page_size(nor);
  537. }
  538. static int s25hx_t_late_init(struct spi_nor *nor)
  539. {
  540. struct spi_nor_flash_parameter *params = nor->params;
  541. /* Fast Read 4B requires mode cycles */
  542. params->reads[SNOR_CMD_READ_FAST].num_mode_clocks = 8;
  543. params->ready = cypress_nor_sr_ready_and_clear;
  544. cypress_nor_ecc_init(nor);
  545. params->die_erase_opcode = SPINOR_OP_CYPRESS_DIE_ERASE;
  546. return 0;
  547. }
  548. static struct spi_nor_fixups s25hx_t_fixups = {
  549. .post_bfpt = s25hx_t_post_bfpt_fixup,
  550. .post_sfdp = s25hx_t_post_sfdp_fixup,
  551. .late_init = s25hx_t_late_init,
  552. };
  553. /**
  554. * cypress_nor_set_octal_dtr() - Enable or disable octal DTR on Cypress flashes.
  555. * @nor: pointer to a 'struct spi_nor'
  556. * @enable: whether to enable or disable Octal DTR
  557. *
  558. * This also sets the memory access latency cycles to 24 to allow the flash to
  559. * run at up to 200MHz.
  560. *
  561. * Return: 0 on success, -errno otherwise.
  562. */
  563. static int cypress_nor_set_octal_dtr(struct spi_nor *nor, bool enable)
  564. {
  565. return enable ? cypress_nor_octal_dtr_en(nor) :
  566. cypress_nor_octal_dtr_dis(nor);
  567. }
  568. static int s28hx_t_post_sfdp_fixup(struct spi_nor *nor)
  569. {
  570. struct spi_nor_flash_parameter *params = nor->params;
  571. if (!params->n_dice || !params->vreg_offset) {
  572. dev_err(nor->dev, "%s failed. The volatile register offset could not be retrieved from SFDP.\n",
  573. __func__);
  574. return -EOPNOTSUPP;
  575. }
  576. /* The 2 Gb parts duplicate info and advertise 4 dice instead of 2. */
  577. if (params->size == SZ_256M)
  578. params->n_dice = 2;
  579. /*
  580. * On older versions of the flash the xSPI Profile 1.0 table has the
  581. * 8D-8D-8D Fast Read opcode as 0x00. But it actually should be 0xEE.
  582. */
  583. if (params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode == 0)
  584. params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode =
  585. SPINOR_OP_CYPRESS_RD_FAST;
  586. /* This flash is also missing the 4-byte Page Program opcode bit. */
  587. spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP],
  588. SPINOR_OP_PP_4B, SNOR_PROTO_1_1_1);
  589. /*
  590. * Since xSPI Page Program opcode is backward compatible with
  591. * Legacy SPI, use Legacy SPI opcode there as well.
  592. */
  593. spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_8_8_8_DTR],
  594. SPINOR_OP_PP_4B, SNOR_PROTO_8_8_8_DTR);
  595. /*
  596. * The xSPI Profile 1.0 table advertises the number of additional
  597. * address bytes needed for Read Status Register command as 0 but the
  598. * actual value for that is 4.
  599. */
  600. params->rdsr_addr_nbytes = 4;
  601. return cypress_nor_get_page_size(nor);
  602. }
  603. static int s28hx_t_post_bfpt_fixup(struct spi_nor *nor,
  604. const struct sfdp_parameter_header *bfpt_header,
  605. const struct sfdp_bfpt *bfpt)
  606. {
  607. return cypress_nor_set_addr_mode_nbytes(nor);
  608. }
  609. static int s28hx_t_late_init(struct spi_nor *nor)
  610. {
  611. struct spi_nor_flash_parameter *params = nor->params;
  612. params->set_octal_dtr = cypress_nor_set_octal_dtr;
  613. params->ready = cypress_nor_sr_ready_and_clear;
  614. cypress_nor_ecc_init(nor);
  615. return 0;
  616. }
  617. static const struct spi_nor_fixups s28hx_t_fixups = {
  618. .post_sfdp = s28hx_t_post_sfdp_fixup,
  619. .post_bfpt = s28hx_t_post_bfpt_fixup,
  620. .late_init = s28hx_t_late_init,
  621. };
  622. static int
  623. s25fs_s_nor_post_bfpt_fixups(struct spi_nor *nor,
  624. const struct sfdp_parameter_header *bfpt_header,
  625. const struct sfdp_bfpt *bfpt)
  626. {
  627. /*
  628. * The S25FS-S chip family reports 512-byte pages in BFPT but
  629. * in reality the write buffer still wraps at the safe default
  630. * of 256 bytes. Overwrite the page size advertised by BFPT
  631. * to get the writes working.
  632. */
  633. nor->params->page_size = 256;
  634. return 0;
  635. }
  636. static const struct spi_nor_fixups s25fs_s_nor_fixups = {
  637. .post_bfpt = s25fs_s_nor_post_bfpt_fixups,
  638. };
  639. static const struct flash_info spansion_nor_parts[] = {
  640. {
  641. .id = SNOR_ID(0x01, 0x02, 0x12),
  642. .name = "s25sl004a",
  643. .size = SZ_512K,
  644. }, {
  645. .id = SNOR_ID(0x01, 0x02, 0x13),
  646. .name = "s25sl008a",
  647. .size = SZ_1M,
  648. }, {
  649. .id = SNOR_ID(0x01, 0x02, 0x14),
  650. .name = "s25sl016a",
  651. .size = SZ_2M,
  652. }, {
  653. .id = SNOR_ID(0x01, 0x02, 0x15, 0x4d, 0x00),
  654. .name = "s25sl032p",
  655. .size = SZ_4M,
  656. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  657. }, {
  658. .id = SNOR_ID(0x01, 0x02, 0x15),
  659. .name = "s25sl032a",
  660. .size = SZ_4M,
  661. }, {
  662. .id = SNOR_ID(0x01, 0x02, 0x16, 0x4d, 0x00),
  663. .name = "s25sl064p",
  664. .size = SZ_8M,
  665. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  666. }, {
  667. .id = SNOR_ID(0x01, 0x02, 0x16),
  668. .name = "s25sl064a",
  669. .size = SZ_8M,
  670. }, {
  671. .id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x00, 0x80),
  672. .name = "s25fl256s0",
  673. .size = SZ_32M,
  674. .sector_size = SZ_256K,
  675. .no_sfdp_flags = SPI_NOR_SKIP_SFDP | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  676. .mfr_flags = USE_CLSR,
  677. }, {
  678. .id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x00, 0x81),
  679. .name = "s25fs256s0",
  680. .size = SZ_32M,
  681. .sector_size = SZ_256K,
  682. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  683. .mfr_flags = USE_CLSR,
  684. }, {
  685. .id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x01, 0x80),
  686. .name = "s25fl256s1",
  687. .size = SZ_32M,
  688. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  689. .mfr_flags = USE_CLSR,
  690. }, {
  691. .id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x01, 0x81),
  692. .name = "s25fs256s1",
  693. .size = SZ_32M,
  694. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  695. .mfr_flags = USE_CLSR,
  696. }, {
  697. .id = SNOR_ID(0x01, 0x02, 0x20, 0x4d, 0x00, 0x80),
  698. .name = "s25fl512s",
  699. .size = SZ_64M,
  700. .sector_size = SZ_256K,
  701. .flags = SPI_NOR_HAS_LOCK,
  702. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  703. .mfr_flags = USE_CLSR,
  704. }, {
  705. .id = SNOR_ID(0x01, 0x02, 0x20, 0x4d, 0x00, 0x81),
  706. .name = "s25fs512s",
  707. .size = SZ_64M,
  708. .sector_size = SZ_256K,
  709. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  710. .mfr_flags = USE_CLSR,
  711. .fixups = &s25fs_s_nor_fixups,
  712. }, {
  713. .id = SNOR_ID(0x01, 0x20, 0x18, 0x03, 0x00),
  714. .name = "s25sl12800",
  715. .size = SZ_16M,
  716. .sector_size = SZ_256K,
  717. }, {
  718. .id = SNOR_ID(0x01, 0x20, 0x18, 0x03, 0x01),
  719. .name = "s25sl12801",
  720. .size = SZ_16M,
  721. }, {
  722. .id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x00, 0x80),
  723. .name = "s25fl128s0",
  724. .size = SZ_16M,
  725. .sector_size = SZ_256K,
  726. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  727. .mfr_flags = USE_CLSR,
  728. }, {
  729. .id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x00),
  730. .name = "s25fl129p0",
  731. .size = SZ_16M,
  732. .sector_size = SZ_256K,
  733. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  734. .mfr_flags = USE_CLSR,
  735. }, {
  736. .id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x01, 0x80),
  737. .name = "s25fl128s1",
  738. .size = SZ_16M,
  739. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  740. .mfr_flags = USE_CLSR,
  741. }, {
  742. .id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x01, 0x81),
  743. .name = "s25fs128s1",
  744. .size = SZ_16M,
  745. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  746. .mfr_flags = USE_CLSR,
  747. .fixups = &s25fs_s_nor_fixups,
  748. }, {
  749. .id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x01),
  750. .name = "s25fl129p1",
  751. .size = SZ_16M,
  752. .no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  753. .mfr_flags = USE_CLSR,
  754. }, {
  755. .id = SNOR_ID(0x01, 0x40, 0x13),
  756. .name = "s25fl204k",
  757. .size = SZ_512K,
  758. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ,
  759. }, {
  760. .id = SNOR_ID(0x01, 0x40, 0x14),
  761. .name = "s25fl208k",
  762. .size = SZ_1M,
  763. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ,
  764. }, {
  765. .id = SNOR_ID(0x01, 0x40, 0x15),
  766. .name = "s25fl116k",
  767. .size = SZ_2M,
  768. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  769. }, {
  770. .id = SNOR_ID(0x01, 0x40, 0x16),
  771. .name = "s25fl132k",
  772. .size = SZ_4M,
  773. .no_sfdp_flags = SECT_4K,
  774. }, {
  775. .id = SNOR_ID(0x01, 0x40, 0x17),
  776. .name = "s25fl164k",
  777. .size = SZ_8M,
  778. .no_sfdp_flags = SECT_4K,
  779. }, {
  780. .id = SNOR_ID(0x01, 0x60, 0x17),
  781. .name = "s25fl064l",
  782. .size = SZ_8M,
  783. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  784. .fixup_flags = SPI_NOR_4B_OPCODES,
  785. }, {
  786. .id = SNOR_ID(0x01, 0x60, 0x18),
  787. .name = "s25fl128l",
  788. .size = SZ_16M,
  789. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  790. .fixup_flags = SPI_NOR_4B_OPCODES,
  791. }, {
  792. .id = SNOR_ID(0x01, 0x60, 0x19),
  793. .name = "s25fl256l",
  794. .size = SZ_32M,
  795. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  796. .fixup_flags = SPI_NOR_4B_OPCODES,
  797. }, {
  798. .id = SNOR_ID(0x04, 0x2c, 0xc2, 0x7f, 0x7f, 0x7f),
  799. .name = "cy15x104q",
  800. .size = SZ_512K,
  801. .sector_size = SZ_512K,
  802. .flags = SPI_NOR_NO_ERASE,
  803. }, {
  804. .id = SNOR_ID(0x34, 0x2a, 0x1a, 0x0f, 0x03, 0x90),
  805. .name = "s25hl512t",
  806. .mfr_flags = USE_CLPEF,
  807. .fixups = &s25hx_t_fixups
  808. }, {
  809. .id = SNOR_ID(0x34, 0x2a, 0x1b, 0x0f, 0x03, 0x90),
  810. .name = "s25hl01gt",
  811. .mfr_flags = USE_CLPEF,
  812. .fixups = &s25hx_t_fixups
  813. }, {
  814. .id = SNOR_ID(0x34, 0x2a, 0x1c, 0x0f, 0x00, 0x90),
  815. .name = "s25hl02gt",
  816. .mfr_flags = USE_CLPEF,
  817. .fixups = &s25hx_t_fixups
  818. }, {
  819. .id = SNOR_ID(0x34, 0x2b, 0x19, 0x0f, 0x08, 0x90),
  820. .name = "s25fs256t",
  821. .mfr_flags = USE_CLPEF,
  822. .fixups = &s25fs256t_fixups
  823. }, {
  824. .id = SNOR_ID(0x34, 0x2b, 0x1a, 0x0f, 0x03, 0x90),
  825. .name = "s25hs512t",
  826. .mfr_flags = USE_CLPEF,
  827. .fixups = &s25hx_t_fixups
  828. }, {
  829. .id = SNOR_ID(0x34, 0x2b, 0x1b, 0x0f, 0x03, 0x90),
  830. .name = "s25hs01gt",
  831. .mfr_flags = USE_CLPEF,
  832. .fixups = &s25hx_t_fixups
  833. }, {
  834. .id = SNOR_ID(0x34, 0x2b, 0x1c, 0x0f, 0x00, 0x90),
  835. .name = "s25hs02gt",
  836. .mfr_flags = USE_CLPEF,
  837. .fixups = &s25hx_t_fixups
  838. }, {
  839. .id = SNOR_ID(0x34, 0x5a, 0x1a),
  840. .name = "s28hl512t",
  841. .mfr_flags = USE_CLPEF,
  842. .fixups = &s28hx_t_fixups,
  843. }, {
  844. .id = SNOR_ID(0x34, 0x5a, 0x1b),
  845. .name = "s28hl01gt",
  846. .mfr_flags = USE_CLPEF,
  847. .fixups = &s28hx_t_fixups,
  848. }, {
  849. .id = SNOR_ID(0x34, 0x5b, 0x19),
  850. .mfr_flags = USE_CLPEF,
  851. .fixups = &s28hx_t_fixups,
  852. }, {
  853. .id = SNOR_ID(0x34, 0x5b, 0x1a),
  854. .name = "s28hs512t",
  855. .mfr_flags = USE_CLPEF,
  856. .fixups = &s28hx_t_fixups,
  857. }, {
  858. .id = SNOR_ID(0x34, 0x5b, 0x1b),
  859. .name = "s28hs01gt",
  860. .mfr_flags = USE_CLPEF,
  861. .fixups = &s28hx_t_fixups,
  862. }, {
  863. .id = SNOR_ID(0x34, 0x5b, 0x1c),
  864. .name = "s28hs02gt",
  865. .mfr_flags = USE_CLPEF,
  866. .fixups = &s28hx_t_fixups,
  867. }, {
  868. .id = SNOR_ID(0xef, 0x40, 0x13),
  869. .name = "s25fl004k",
  870. .size = SZ_512K,
  871. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  872. }, {
  873. .id = SNOR_ID(0xef, 0x40, 0x14),
  874. .name = "s25fl008k",
  875. .size = SZ_1M,
  876. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  877. }, {
  878. .id = SNOR_ID(0xef, 0x40, 0x15),
  879. .name = "s25fl016k",
  880. .size = SZ_2M,
  881. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  882. }, {
  883. .id = SNOR_ID(0xef, 0x40, 0x17),
  884. .name = "s25fl064k",
  885. .size = SZ_8M,
  886. .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
  887. }
  888. };
  889. /**
  890. * spansion_nor_sr_ready_and_clear() - Query the Status Register to see if the
  891. * flash is ready for new commands and clear it if there are any errors.
  892. * @nor: pointer to 'struct spi_nor'.
  893. *
  894. * Return: 1 if ready, 0 if not ready, -errno on errors.
  895. */
  896. static int spansion_nor_sr_ready_and_clear(struct spi_nor *nor)
  897. {
  898. int ret;
  899. ret = spi_nor_read_sr(nor, nor->bouncebuf);
  900. if (ret)
  901. return ret;
  902. if (nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
  903. if (nor->bouncebuf[0] & SR_E_ERR)
  904. dev_err(nor->dev, "Erase Error occurred\n");
  905. else
  906. dev_err(nor->dev, "Programming Error occurred\n");
  907. spansion_nor_clear_sr(nor);
  908. /*
  909. * WEL bit remains set to one when an erase or page program
  910. * error occurs. Issue a Write Disable command to protect
  911. * against inadvertent writes that can possibly corrupt the
  912. * contents of the memory.
  913. */
  914. ret = spi_nor_write_disable(nor);
  915. if (ret)
  916. return ret;
  917. return -EIO;
  918. }
  919. return !(nor->bouncebuf[0] & SR_WIP);
  920. }
  921. static int spansion_nor_late_init(struct spi_nor *nor)
  922. {
  923. struct spi_nor_flash_parameter *params = nor->params;
  924. struct spansion_nor_params *priv_params;
  925. u8 mfr_flags = nor->info->mfr_flags;
  926. if (params->size > SZ_16M) {
  927. nor->flags |= SNOR_F_4B_OPCODES;
  928. /* No small sector erase for 4-byte command set */
  929. nor->erase_opcode = SPINOR_OP_SE;
  930. nor->mtd.erasesize = nor->info->sector_size ?:
  931. SPI_NOR_DEFAULT_SECTOR_SIZE;
  932. }
  933. if (mfr_flags & (USE_CLSR | USE_CLPEF)) {
  934. priv_params = devm_kmalloc(nor->dev, sizeof(*priv_params),
  935. GFP_KERNEL);
  936. if (!priv_params)
  937. return -ENOMEM;
  938. if (mfr_flags & USE_CLSR)
  939. priv_params->clsr = SPINOR_OP_CLSR;
  940. else if (mfr_flags & USE_CLPEF)
  941. priv_params->clsr = SPINOR_OP_CLPEF;
  942. params->priv = priv_params;
  943. params->ready = spansion_nor_sr_ready_and_clear;
  944. }
  945. return 0;
  946. }
  947. static const struct spi_nor_fixups spansion_nor_fixups = {
  948. .late_init = spansion_nor_late_init,
  949. };
  950. const struct spi_nor_manufacturer spi_nor_spansion = {
  951. .name = "spansion",
  952. .parts = spansion_nor_parts,
  953. .nparts = ARRAY_SIZE(spansion_nor_parts),
  954. .fixups = &spansion_nor_fixups,
  955. };