Lines Matching full:nor
3 * OTP support for SPI NOR flashes
11 #include <linux/mtd/spi-nor.h>
15 #define spi_nor_otp_region_len(nor) ((nor)->params->otp.org->len) argument
16 #define spi_nor_otp_n_regions(nor) ((nor)->params->otp.org->n_regions) argument
20 * @nor: pointer to 'struct spi_nor'
37 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
44 read_opcode = nor->read_opcode; in spi_nor_otp_read_secr()
45 addr_nbytes = nor->addr_nbytes; in spi_nor_otp_read_secr()
46 read_dummy = nor->read_dummy; in spi_nor_otp_read_secr()
47 read_proto = nor->read_proto; in spi_nor_otp_read_secr()
48 rdesc = nor->dirmap.rdesc; in spi_nor_otp_read_secr()
50 nor->read_opcode = SPINOR_OP_RSECR; in spi_nor_otp_read_secr()
51 nor->read_dummy = 8; in spi_nor_otp_read_secr()
52 nor->read_proto = SNOR_PROTO_1_1_1; in spi_nor_otp_read_secr()
53 nor->dirmap.rdesc = NULL; in spi_nor_otp_read_secr()
55 ret = spi_nor_read_data(nor, addr, len, buf); in spi_nor_otp_read_secr()
57 nor->read_opcode = read_opcode; in spi_nor_otp_read_secr()
58 nor->addr_nbytes = addr_nbytes; in spi_nor_otp_read_secr()
59 nor->read_dummy = read_dummy; in spi_nor_otp_read_secr()
60 nor->read_proto = read_proto; in spi_nor_otp_read_secr()
61 nor->dirmap.rdesc = rdesc; in spi_nor_otp_read_secr()
68 * @nor: pointer to 'struct spi_nor'
84 int spi_nor_otp_write_secr(struct spi_nor *nor, loff_t addr, size_t len, in spi_nor_otp_write_secr() argument
92 program_opcode = nor->program_opcode; in spi_nor_otp_write_secr()
93 addr_nbytes = nor->addr_nbytes; in spi_nor_otp_write_secr()
94 write_proto = nor->write_proto; in spi_nor_otp_write_secr()
95 wdesc = nor->dirmap.wdesc; in spi_nor_otp_write_secr()
97 nor->program_opcode = SPINOR_OP_PSECR; in spi_nor_otp_write_secr()
98 nor->write_proto = SNOR_PROTO_1_1_1; in spi_nor_otp_write_secr()
99 nor->dirmap.wdesc = NULL; in spi_nor_otp_write_secr()
105 ret = spi_nor_write_enable(nor); in spi_nor_otp_write_secr()
109 written = spi_nor_write_data(nor, addr, len, buf); in spi_nor_otp_write_secr()
113 ret = spi_nor_wait_till_ready(nor); in spi_nor_otp_write_secr()
116 nor->program_opcode = program_opcode; in spi_nor_otp_write_secr()
117 nor->addr_nbytes = addr_nbytes; in spi_nor_otp_write_secr()
118 nor->write_proto = write_proto; in spi_nor_otp_write_secr()
119 nor->dirmap.wdesc = wdesc; in spi_nor_otp_write_secr()
126 * @nor: pointer to 'struct spi_nor'
138 int spi_nor_otp_erase_secr(struct spi_nor *nor, loff_t addr) in spi_nor_otp_erase_secr() argument
140 u8 erase_opcode = nor->erase_opcode; in spi_nor_otp_erase_secr()
143 ret = spi_nor_write_enable(nor); in spi_nor_otp_erase_secr()
147 nor->erase_opcode = SPINOR_OP_ESECR; in spi_nor_otp_erase_secr()
148 ret = spi_nor_erase_sector(nor, addr); in spi_nor_otp_erase_secr()
149 nor->erase_opcode = erase_opcode; in spi_nor_otp_erase_secr()
153 return spi_nor_wait_till_ready(nor); in spi_nor_otp_erase_secr()
168 * @nor: pointer to 'struct spi_nor'
176 int spi_nor_otp_lock_sr2(struct spi_nor *nor, unsigned int region) in spi_nor_otp_lock_sr2() argument
178 u8 *cr = nor->bouncebuf; in spi_nor_otp_lock_sr2()
185 ret = spi_nor_read_cr(nor, cr); in spi_nor_otp_lock_sr2()
195 return spi_nor_write_16bit_cr_and_check(nor, cr[0]); in spi_nor_otp_lock_sr2()
200 * @nor: pointer to 'struct spi_nor'
208 int spi_nor_otp_is_locked_sr2(struct spi_nor *nor, unsigned int region) in spi_nor_otp_is_locked_sr2() argument
210 u8 *cr = nor->bouncebuf; in spi_nor_otp_is_locked_sr2()
217 ret = spi_nor_read_cr(nor, cr); in spi_nor_otp_is_locked_sr2()
224 static loff_t spi_nor_otp_region_start(const struct spi_nor *nor, unsigned int region) in spi_nor_otp_region_start() argument
226 const struct spi_nor_otp_organization *org = nor->params->otp.org; in spi_nor_otp_region_start()
231 static size_t spi_nor_otp_size(struct spi_nor *nor) in spi_nor_otp_size() argument
233 return spi_nor_otp_n_regions(nor) * spi_nor_otp_region_len(nor); in spi_nor_otp_size()
237 static loff_t spi_nor_otp_region_to_offset(struct spi_nor *nor, unsigned int region) in spi_nor_otp_region_to_offset() argument
239 return region * spi_nor_otp_region_len(nor); in spi_nor_otp_region_to_offset()
242 static unsigned int spi_nor_otp_offset_to_region(struct spi_nor *nor, loff_t ofs) in spi_nor_otp_offset_to_region() argument
244 return div64_u64(ofs, spi_nor_otp_region_len(nor)); in spi_nor_otp_offset_to_region()
250 struct spi_nor *nor = mtd_to_spi_nor(mtd); in spi_nor_mtd_otp_info() local
251 const struct spi_nor_otp_ops *ops = nor->params->otp.ops; in spi_nor_mtd_otp_info()
252 unsigned int n_regions = spi_nor_otp_n_regions(nor); in spi_nor_mtd_otp_info()
259 ret = spi_nor_prep_and_lock(nor); in spi_nor_mtd_otp_info()
264 buf->start = spi_nor_otp_region_to_offset(nor, i); in spi_nor_mtd_otp_info()
265 buf->length = spi_nor_otp_region_len(nor); in spi_nor_mtd_otp_info()
267 locked = ops->is_locked(nor, i); in spi_nor_mtd_otp_info()
280 spi_nor_unlock_and_unprep(nor); in spi_nor_mtd_otp_info()
285 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
288 const struct spi_nor_otp_ops *ops = nor->params->otp.ops; in spi_nor_mtd_otp_range_is_locked()
296 for (region = spi_nor_otp_offset_to_region(nor, ofs); in spi_nor_mtd_otp_range_is_locked()
297 region <= spi_nor_otp_offset_to_region(nor, ofs + len - 1); in spi_nor_mtd_otp_range_is_locked()
299 locked = ops->is_locked(nor, region); in spi_nor_mtd_otp_range_is_locked()
312 struct spi_nor *nor = mtd_to_spi_nor(mtd); in spi_nor_mtd_otp_read_write() local
313 const struct spi_nor_otp_ops *ops = nor->params->otp.ops; in spi_nor_mtd_otp_read_write()
314 const size_t rlen = spi_nor_otp_region_len(nor); in spi_nor_mtd_otp_read_write()
320 if (ofs < 0 || ofs >= spi_nor_otp_size(nor)) in spi_nor_mtd_otp_read_write()
324 total_len = min_t(size_t, total_len, spi_nor_otp_size(nor) - ofs); in spi_nor_mtd_otp_read_write()
329 ret = spi_nor_prep_and_lock(nor); in spi_nor_mtd_otp_read_write()
334 ret = spi_nor_mtd_otp_range_is_locked(nor, ofs, total_len); in spi_nor_mtd_otp_read_write()
350 region = spi_nor_otp_offset_to_region(nor, ofs); in spi_nor_mtd_otp_read_write()
351 rstart = spi_nor_otp_region_start(nor, region); in spi_nor_mtd_otp_read_write()
364 ret = ops->write(nor, rstart + rofs, len, buf); in spi_nor_mtd_otp_read_write()
366 ret = ops->read(nor, rstart + rofs, len, (u8 *)buf); in spi_nor_mtd_otp_read_write()
380 spi_nor_unlock_and_unprep(nor); in spi_nor_mtd_otp_read_write()
398 struct spi_nor *nor = mtd_to_spi_nor(mtd); in spi_nor_mtd_otp_erase() local
399 const struct spi_nor_otp_ops *ops = nor->params->otp.ops; in spi_nor_mtd_otp_erase()
400 const size_t rlen = spi_nor_otp_region_len(nor); in spi_nor_mtd_otp_erase()
412 if (from < 0 || (from + len) > spi_nor_otp_size(nor)) in spi_nor_mtd_otp_erase()
419 ret = spi_nor_prep_and_lock(nor); in spi_nor_mtd_otp_erase()
423 ret = spi_nor_mtd_otp_range_is_locked(nor, from, len); in spi_nor_mtd_otp_erase()
432 region = spi_nor_otp_offset_to_region(nor, from); in spi_nor_mtd_otp_erase()
433 rstart = spi_nor_otp_region_start(nor, region); in spi_nor_mtd_otp_erase()
435 ret = ops->erase(nor, rstart); in spi_nor_mtd_otp_erase()
444 spi_nor_unlock_and_unprep(nor); in spi_nor_mtd_otp_erase()
451 struct spi_nor *nor = mtd_to_spi_nor(mtd); in spi_nor_mtd_otp_lock() local
452 const struct spi_nor_otp_ops *ops = nor->params->otp.ops; in spi_nor_mtd_otp_lock()
453 const size_t rlen = spi_nor_otp_region_len(nor); in spi_nor_mtd_otp_lock()
457 if (from < 0 || (from + len) > spi_nor_otp_size(nor)) in spi_nor_mtd_otp_lock()
464 ret = spi_nor_prep_and_lock(nor); in spi_nor_mtd_otp_lock()
469 region = spi_nor_otp_offset_to_region(nor, from); in spi_nor_mtd_otp_lock()
470 ret = ops->lock(nor, region); in spi_nor_mtd_otp_lock()
479 spi_nor_unlock_and_unprep(nor); in spi_nor_mtd_otp_lock()
484 void spi_nor_set_mtd_otp_ops(struct spi_nor *nor) in spi_nor_set_mtd_otp_ops() argument
486 struct mtd_info *mtd = &nor->mtd; in spi_nor_set_mtd_otp_ops()
488 if (!nor->params->otp.ops) in spi_nor_set_mtd_otp_ops()
491 if (WARN_ON(!is_power_of_2(spi_nor_otp_region_len(nor)))) in spi_nor_set_mtd_otp_ops()
497 * Some SPI NOR flashes like Macronix ones can be ordered in two in spi_nor_set_mtd_otp_ops()