Lines Matching full:nor

3  * OTP support for SPI NOR flashes
10 #include <linux/mtd/spi-nor.h>
14 #define spi_nor_otp_region_len(nor) ((nor)->params->otp.org->len) argument
15 #define spi_nor_otp_n_regions(nor) ((nor)->params->otp.org->n_regions) argument
19 * @nor: pointer to 'struct spi_nor'
36 int spi_nor_otp_read_secr(struct spi_nor *nor, loff_t addr, size_t len, u8 *buf) in spi_nor_otp_read_secr() argument
43 read_opcode = nor->read_opcode; in spi_nor_otp_read_secr()
44 addr_nbytes = nor->addr_nbytes; in spi_nor_otp_read_secr()
45 read_dummy = nor->read_dummy; in spi_nor_otp_read_secr()
46 read_proto = nor->read_proto; in spi_nor_otp_read_secr()
47 rdesc = nor->dirmap.rdesc; in spi_nor_otp_read_secr()
49 nor->read_opcode = SPINOR_OP_RSECR; in spi_nor_otp_read_secr()
50 nor->read_dummy = 8; in spi_nor_otp_read_secr()
51 nor->read_proto = SNOR_PROTO_1_1_1; in spi_nor_otp_read_secr()
52 nor->dirmap.rdesc = NULL; in spi_nor_otp_read_secr()
54 ret = spi_nor_read_data(nor, addr, len, buf); in spi_nor_otp_read_secr()
56 nor->read_opcode = read_opcode; in spi_nor_otp_read_secr()
57 nor->addr_nbytes = addr_nbytes; in spi_nor_otp_read_secr()
58 nor->read_dummy = read_dummy; in spi_nor_otp_read_secr()
59 nor->read_proto = read_proto; in spi_nor_otp_read_secr()
60 nor->dirmap.rdesc = rdesc; in spi_nor_otp_read_secr()
67 * @nor: pointer to 'struct spi_nor'
83 int spi_nor_otp_write_secr(struct spi_nor *nor, loff_t addr, size_t len, in spi_nor_otp_write_secr() argument
91 program_opcode = nor->program_opcode; in spi_nor_otp_write_secr()
92 addr_nbytes = nor->addr_nbytes; in spi_nor_otp_write_secr()
93 write_proto = nor->write_proto; in spi_nor_otp_write_secr()
94 wdesc = nor->dirmap.wdesc; in spi_nor_otp_write_secr()
96 nor->program_opcode = SPINOR_OP_PSECR; in spi_nor_otp_write_secr()
97 nor->write_proto = SNOR_PROTO_1_1_1; in spi_nor_otp_write_secr()
98 nor->dirmap.wdesc = NULL; in spi_nor_otp_write_secr()
104 ret = spi_nor_write_enable(nor); in spi_nor_otp_write_secr()
108 written = spi_nor_write_data(nor, addr, len, buf); in spi_nor_otp_write_secr()
112 ret = spi_nor_wait_till_ready(nor); in spi_nor_otp_write_secr()
115 nor->program_opcode = program_opcode; in spi_nor_otp_write_secr()
116 nor->addr_nbytes = addr_nbytes; in spi_nor_otp_write_secr()
117 nor->write_proto = write_proto; in spi_nor_otp_write_secr()
118 nor->dirmap.wdesc = wdesc; in spi_nor_otp_write_secr()
125 * @nor: pointer to 'struct spi_nor'
137 int spi_nor_otp_erase_secr(struct spi_nor *nor, loff_t addr) in spi_nor_otp_erase_secr() argument
139 u8 erase_opcode = nor->erase_opcode; in spi_nor_otp_erase_secr()
142 ret = spi_nor_write_enable(nor); in spi_nor_otp_erase_secr()
146 nor->erase_opcode = SPINOR_OP_ESECR; in spi_nor_otp_erase_secr()
147 ret = spi_nor_erase_sector(nor, addr); in spi_nor_otp_erase_secr()
148 nor->erase_opcode = erase_opcode; in spi_nor_otp_erase_secr()
152 return spi_nor_wait_till_ready(nor); in spi_nor_otp_erase_secr()
167 * @nor: pointer to 'struct spi_nor'
175 int spi_nor_otp_lock_sr2(struct spi_nor *nor, unsigned int region) in spi_nor_otp_lock_sr2() argument
177 u8 *cr = nor->bouncebuf; in spi_nor_otp_lock_sr2()
184 ret = spi_nor_read_cr(nor, cr); in spi_nor_otp_lock_sr2()
194 return spi_nor_write_16bit_cr_and_check(nor, cr[0]); in spi_nor_otp_lock_sr2()
199 * @nor: pointer to 'struct spi_nor'
207 int spi_nor_otp_is_locked_sr2(struct spi_nor *nor, unsigned int region) in spi_nor_otp_is_locked_sr2() argument
209 u8 *cr = nor->bouncebuf; in spi_nor_otp_is_locked_sr2()
216 ret = spi_nor_read_cr(nor, cr); in spi_nor_otp_is_locked_sr2()
223 static loff_t spi_nor_otp_region_start(const struct spi_nor *nor, unsigned int region) in spi_nor_otp_region_start() argument
225 const struct spi_nor_otp_organization *org = nor->params->otp.org; in spi_nor_otp_region_start()
230 static size_t spi_nor_otp_size(struct spi_nor *nor) in spi_nor_otp_size() argument
232 return spi_nor_otp_n_regions(nor) * spi_nor_otp_region_len(nor); in spi_nor_otp_size()
236 static loff_t spi_nor_otp_region_to_offset(struct spi_nor *nor, unsigned int region) in spi_nor_otp_region_to_offset() argument
238 return region * spi_nor_otp_region_len(nor); in spi_nor_otp_region_to_offset()
241 static unsigned int spi_nor_otp_offset_to_region(struct spi_nor *nor, loff_t ofs) in spi_nor_otp_offset_to_region() argument
243 return div64_u64(ofs, spi_nor_otp_region_len(nor)); in spi_nor_otp_offset_to_region()
249 struct spi_nor *nor = mtd_to_spi_nor(mtd); in spi_nor_mtd_otp_info() local
250 const struct spi_nor_otp_ops *ops = nor->params->otp.ops; in spi_nor_mtd_otp_info()
251 unsigned int n_regions = spi_nor_otp_n_regions(nor); in spi_nor_mtd_otp_info()
258 ret = spi_nor_prep_and_lock(nor); in spi_nor_mtd_otp_info()
263 buf->start = spi_nor_otp_region_to_offset(nor, i); in spi_nor_mtd_otp_info()
264 buf->length = spi_nor_otp_region_len(nor); in spi_nor_mtd_otp_info()
266 locked = ops->is_locked(nor, i); in spi_nor_mtd_otp_info()
279 spi_nor_unlock_and_unprep(nor); in spi_nor_mtd_otp_info()
284 static int spi_nor_mtd_otp_range_is_locked(struct spi_nor *nor, loff_t ofs, in spi_nor_mtd_otp_range_is_locked() argument
287 const struct spi_nor_otp_ops *ops = nor->params->otp.ops; in spi_nor_mtd_otp_range_is_locked()
295 for (region = spi_nor_otp_offset_to_region(nor, ofs); in spi_nor_mtd_otp_range_is_locked()
296 region <= spi_nor_otp_offset_to_region(nor, ofs + len - 1); in spi_nor_mtd_otp_range_is_locked()
298 locked = ops->is_locked(nor, region); in spi_nor_mtd_otp_range_is_locked()
311 struct spi_nor *nor = mtd_to_spi_nor(mtd); in spi_nor_mtd_otp_read_write() local
312 const struct spi_nor_otp_ops *ops = nor->params->otp.ops; in spi_nor_mtd_otp_read_write()
313 const size_t rlen = spi_nor_otp_region_len(nor); in spi_nor_mtd_otp_read_write()
319 if (ofs < 0 || ofs >= spi_nor_otp_size(nor)) in spi_nor_mtd_otp_read_write()
323 total_len = min_t(size_t, total_len, spi_nor_otp_size(nor) - ofs); in spi_nor_mtd_otp_read_write()
328 ret = spi_nor_prep_and_lock(nor); in spi_nor_mtd_otp_read_write()
333 ret = spi_nor_mtd_otp_range_is_locked(nor, ofs, total_len); in spi_nor_mtd_otp_read_write()
349 region = spi_nor_otp_offset_to_region(nor, ofs); in spi_nor_mtd_otp_read_write()
350 rstart = spi_nor_otp_region_start(nor, region); in spi_nor_mtd_otp_read_write()
363 ret = ops->write(nor, rstart + rofs, len, buf); in spi_nor_mtd_otp_read_write()
365 ret = ops->read(nor, rstart + rofs, len, (u8 *)buf); in spi_nor_mtd_otp_read_write()
379 spi_nor_unlock_and_unprep(nor); in spi_nor_mtd_otp_read_write()
397 struct spi_nor *nor = mtd_to_spi_nor(mtd); in spi_nor_mtd_otp_erase() local
398 const struct spi_nor_otp_ops *ops = nor->params->otp.ops; in spi_nor_mtd_otp_erase()
399 const size_t rlen = spi_nor_otp_region_len(nor); in spi_nor_mtd_otp_erase()
411 if (from < 0 || (from + len) > spi_nor_otp_size(nor)) in spi_nor_mtd_otp_erase()
418 ret = spi_nor_prep_and_lock(nor); in spi_nor_mtd_otp_erase()
422 ret = spi_nor_mtd_otp_range_is_locked(nor, from, len); in spi_nor_mtd_otp_erase()
431 region = spi_nor_otp_offset_to_region(nor, from); in spi_nor_mtd_otp_erase()
432 rstart = spi_nor_otp_region_start(nor, region); in spi_nor_mtd_otp_erase()
434 ret = ops->erase(nor, rstart); in spi_nor_mtd_otp_erase()
443 spi_nor_unlock_and_unprep(nor); in spi_nor_mtd_otp_erase()
450 struct spi_nor *nor = mtd_to_spi_nor(mtd); in spi_nor_mtd_otp_lock() local
451 const struct spi_nor_otp_ops *ops = nor->params->otp.ops; in spi_nor_mtd_otp_lock()
452 const size_t rlen = spi_nor_otp_region_len(nor); in spi_nor_mtd_otp_lock()
456 if (from < 0 || (from + len) > spi_nor_otp_size(nor)) in spi_nor_mtd_otp_lock()
463 ret = spi_nor_prep_and_lock(nor); in spi_nor_mtd_otp_lock()
468 region = spi_nor_otp_offset_to_region(nor, from); in spi_nor_mtd_otp_lock()
469 ret = ops->lock(nor, region); in spi_nor_mtd_otp_lock()
478 spi_nor_unlock_and_unprep(nor); in spi_nor_mtd_otp_lock()
483 void spi_nor_set_mtd_otp_ops(struct spi_nor *nor) in spi_nor_set_mtd_otp_ops() argument
485 struct mtd_info *mtd = &nor->mtd; in spi_nor_set_mtd_otp_ops()
487 if (!nor->params->otp.ops) in spi_nor_set_mtd_otp_ops()
490 if (WARN_ON(!is_power_of_2(spi_nor_otp_region_len(nor)))) in spi_nor_set_mtd_otp_ops()
496 * Some SPI NOR flashes like Macronix ones can be ordered in two in spi_nor_set_mtd_otp_ops()