Lines Matching +full:otp +full:- +full:1

1 // SPDX-License-Identifier: GPL-2.0
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)
16 #define spi_nor_otp_n_regions(nor) ((nor)->params->otp.org->n_regions)
19 * spi_nor_otp_read_secr() - read security register
28 * an one-time-programmable memory area, consisting of multiple bytes (usually
29 * 256). Thus one "security register" maps to one OTP region.
35 * Return: number of bytes read successfully, -errno otherwise
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()
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()
67 * spi_nor_otp_write_secr() - write security register
82 * Return: number of bytes written successfully, -errno otherwise
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()
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()
125 * spi_nor_otp_erase_secr() - erase a security register
136 * Return: 0 on success, -errno otherwise
140 u8 erase_opcode = nor->erase_opcode; in spi_nor_otp_erase_secr()
147 nor->erase_opcode = SPINOR_OP_ESECR; in spi_nor_otp_erase_secr()
149 nor->erase_opcode = erase_opcode; in spi_nor_otp_erase_secr()
161 return -EINVAL; in spi_nor_otp_lock_bit_cr()
167 * spi_nor_otp_lock_sr2() - lock the OTP region
169 * @region: OTP region
171 * Lock the OTP region by writing the status register-2. This method is used on
174 * Return: 0 on success, -errno otherwise.
178 u8 *cr = nor->bouncebuf; in spi_nor_otp_lock_sr2()
199 * spi_nor_otp_is_locked_sr2() - get the OTP region lock status
201 * @region: OTP region
203 * Retrieve the OTP region lock bit by reading the status register-2. This
206 * Return: 0 on success, -errno otherwise.
210 u8 *cr = nor->bouncebuf; in spi_nor_otp_is_locked_sr2()
226 const struct spi_nor_otp_organization *org = nor->params->otp.org; in spi_nor_otp_region_start()
228 return org->base + region * org->offset; in spi_nor_otp_region_start()
236 /* Translate the file offsets from and to OTP regions. */
251 const struct spi_nor_otp_ops *ops = nor->params->otp.ops; in spi_nor_mtd_otp_info()
257 return -ENOSPC; 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()
273 buf->locked = !!locked; in spi_nor_mtd_otp_info()
288 const struct spi_nor_otp_ops *ops = nor->params->otp.ops; in spi_nor_mtd_otp_range_is_locked()
293 * If any of the affected OTP regions are locked the entire range is 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()
313 const struct spi_nor_otp_ops *ops = nor->params->otp.ops; 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()
338 ret = -EROFS; in spi_nor_mtd_otp_read_write()
345 * The OTP regions are mapped into a contiguous area starting in spi_nor_mtd_otp_read_write()
347 * file offsets to the address of an OTP region as used in the in spi_nor_mtd_otp_read_write()
354 * The size of a OTP region is expected to be a power of two, in spi_nor_mtd_otp_read_write()
358 rofs = ofs & (rlen - 1); in spi_nor_mtd_otp_read_write()
360 /* don't access beyond one OTP region */ in spi_nor_mtd_otp_read_write()
361 len = min_t(size_t, total_len, rlen - rofs); 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()
368 ret = -EIO; in spi_nor_mtd_otp_read_write()
375 total_len -= ret; in spi_nor_mtd_otp_read_write()
399 const struct spi_nor_otp_ops *ops = nor->params->otp.ops; in spi_nor_mtd_otp_erase()
405 /* OTP erase is optional */ in spi_nor_mtd_otp_erase()
406 if (!ops->erase) in spi_nor_mtd_otp_erase()
407 return -EOPNOTSUPP; in spi_nor_mtd_otp_erase()
413 return -EINVAL; in spi_nor_mtd_otp_erase()
417 return -EINVAL; in spi_nor_mtd_otp_erase()
427 ret = -EROFS; in spi_nor_mtd_otp_erase()
435 ret = ops->erase(nor, rstart); in spi_nor_mtd_otp_erase()
439 len -= rlen; in spi_nor_mtd_otp_erase()
452 const struct spi_nor_otp_ops *ops = nor->params->otp.ops; in spi_nor_mtd_otp_lock()
458 return -EINVAL; in spi_nor_mtd_otp_lock()
462 return -EINVAL; in spi_nor_mtd_otp_lock()
470 ret = ops->lock(nor, region); in spi_nor_mtd_otp_lock()
474 len -= rlen; in spi_nor_mtd_otp_lock()
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()
498 * different variants. One with a factory locked OTP area and one where in spi_nor_set_mtd_otp_ops()
499 * it is left to the user to write to it. The factory locked OTP is in spi_nor_set_mtd_otp_ops()
503 mtd->_get_user_prot_info = spi_nor_mtd_otp_info; in spi_nor_set_mtd_otp_ops()
504 mtd->_read_user_prot_reg = spi_nor_mtd_otp_read; in spi_nor_set_mtd_otp_ops()
505 mtd->_write_user_prot_reg = spi_nor_mtd_otp_write; in spi_nor_set_mtd_otp_ops()
506 mtd->_lock_user_prot_reg = spi_nor_mtd_otp_lock; in spi_nor_set_mtd_otp_ops()
507 mtd->_erase_user_prot_reg = spi_nor_mtd_otp_erase; in spi_nor_set_mtd_otp_ops()