drivers/mtd/spi-nor/otp.c
Source file repositories/reference/linux-study-clean/drivers/mtd/spi-nor/otp.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mtd/spi-nor/otp.c- Extension
.c- Size
- 12442 bytes
- Lines
- 509
- Domain
- Driver Families
- Bucket
- drivers/mtd
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/log2.hlinux/math64.hlinux/mtd/mtd.hlinux/mtd/spi-nor.hcore.h
Detected Declarations
function Copyrightfunction spi_nor_otp_write_secrfunction spi_nor_otp_erase_secrfunction spi_nor_otp_lock_bit_crfunction spi_nor_otp_lock_sr2function spi_nor_otp_is_locked_sr2function spi_nor_otp_region_startfunction spi_nor_otp_sizefunction spi_nor_otp_region_to_offsetfunction spi_nor_otp_offset_to_regionfunction spi_nor_mtd_otp_infofunction spi_nor_mtd_otp_range_is_lockedfunction spi_nor_mtd_otp_read_writefunction spi_nor_mtd_otp_readfunction spi_nor_mtd_otp_writefunction spi_nor_mtd_otp_erasefunction spi_nor_mtd_otp_lockfunction spi_nor_set_mtd_otp_ops
Annotated Snippet
if (locked < 0) {
ret = locked;
goto out;
}
buf->locked = !!locked;
buf++;
}
*retlen = n_regions * sizeof(*buf);
out:
spi_nor_unlock_and_unprep(nor);
return ret;
}
static int spi_nor_mtd_otp_range_is_locked(struct spi_nor *nor, loff_t ofs,
size_t len)
{
const struct spi_nor_otp_ops *ops = nor->params->otp.ops;
unsigned int region;
int locked;
/*
* If any of the affected OTP regions are locked the entire range is
* considered locked.
*/
for (region = spi_nor_otp_offset_to_region(nor, ofs);
region <= spi_nor_otp_offset_to_region(nor, ofs + len - 1);
region++) {
locked = ops->is_locked(nor, region);
/* take the branch it is locked or in case of an error */
if (locked)
return locked;
}
return 0;
}
static int spi_nor_mtd_otp_read_write(struct mtd_info *mtd, loff_t ofs,
size_t total_len, size_t *retlen,
const u8 *buf, bool is_write)
{
struct spi_nor *nor = mtd_to_spi_nor(mtd);
const struct spi_nor_otp_ops *ops = nor->params->otp.ops;
const size_t rlen = spi_nor_otp_region_len(nor);
loff_t rstart, rofs;
unsigned int region;
size_t len;
int ret;
if (ofs < 0 || ofs >= spi_nor_otp_size(nor))
return 0;
/* don't access beyond the end */
total_len = min_t(size_t, total_len, spi_nor_otp_size(nor) - ofs);
if (!total_len)
return 0;
ret = spi_nor_prep_and_lock(nor);
if (ret)
return ret;
if (is_write) {
ret = spi_nor_mtd_otp_range_is_locked(nor, ofs, total_len);
if (ret < 0) {
goto out;
} else if (ret) {
ret = -EROFS;
goto out;
}
}
while (total_len) {
/*
* The OTP regions are mapped into a contiguous area starting
* at 0 as expected by the MTD layer. This will map the MTD
* file offsets to the address of an OTP region as used in the
* actual SPI commands.
*/
region = spi_nor_otp_offset_to_region(nor, ofs);
rstart = spi_nor_otp_region_start(nor, region);
/*
* The size of a OTP region is expected to be a power of two,
* thus we can just mask the lower bits and get the offset into
* a region.
*/
Annotation
- Immediate include surface: `linux/log2.h`, `linux/math64.h`, `linux/mtd/mtd.h`, `linux/mtd/spi-nor.h`, `core.h`.
- Detected declarations: `function Copyright`, `function spi_nor_otp_write_secr`, `function spi_nor_otp_erase_secr`, `function spi_nor_otp_lock_bit_cr`, `function spi_nor_otp_lock_sr2`, `function spi_nor_otp_is_locked_sr2`, `function spi_nor_otp_region_start`, `function spi_nor_otp_size`, `function spi_nor_otp_region_to_offset`, `function spi_nor_otp_offset_to_region`.
- Atlas domain: Driver Families / drivers/mtd.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.