drivers/nvmem/sunplus-ocotp.c
Source file repositories/reference/linux-study-clean/drivers/nvmem/sunplus-ocotp.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/nvmem/sunplus-ocotp.c- Extension
.c- Size
- 5813 bytes
- Lines
- 230
- Domain
- Driver Families
- Bucket
- drivers/nvmem
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/clk.hlinux/delay.hlinux/device.hlinux/io.hlinux/iopoll.hlinux/module.hlinux/mod_devicetable.hlinux/nvmem-provider.hlinux/platform_device.h
Detected Declarations
struct sp_ocotp_privstruct sp_ocotp_dataenum base_typefunction sp_otp_read_realfunction sp_ocotp_readfunction sp_ocotp_probe
Annotated Snippet
struct sp_ocotp_priv {
struct device *dev;
void __iomem *base[BASEMAX];
struct clk *clk;
};
struct sp_ocotp_data {
int size;
};
static const struct sp_ocotp_data sp_otp_v0 = {
.size = QAC628_OTP_SIZE,
};
static int sp_otp_read_real(struct sp_ocotp_priv *otp, int addr, char *value)
{
unsigned int addr_data;
unsigned int byte_shift;
unsigned int status;
int ret;
addr_data = addr % (OTP_WORD_SIZE * OTP_WORDS_PER_BANK);
addr_data = addr_data / OTP_WORD_SIZE;
byte_shift = addr % (OTP_WORD_SIZE * OTP_WORDS_PER_BANK);
byte_shift = byte_shift % OTP_WORD_SIZE;
addr = addr / (OTP_WORD_SIZE * OTP_WORDS_PER_BANK);
addr = addr * OTP_BIT_ADDR_OF_BANK;
writel(readl(otp->base[OTPRX] + OTP_STATUS) & OTP_READ_DONE_MASK &
OTP_LOAD_SECURE_DONE_MASK, otp->base[OTPRX] + OTP_STATUS);
writel(addr, otp->base[OTPRX] + OTP_READ_ADDRESS);
writel(readl(otp->base[OTPRX] + OTP_CONTROL_2) | OTP_READ,
otp->base[OTPRX] + OTP_CONTROL_2);
writel(readl(otp->base[OTPRX] + OTP_CONTROL_2) & SEL_BAK_KEY2_MASK & SW_TRIM_EN_MASK
& SEL_BAK_KEY_MASK & OTP_LOAD_SECURE_DATA_MASK & OTP_DO_CRC_MASK,
otp->base[OTPRX] + OTP_CONTROL_2);
writel((readl(otp->base[OTPRX] + OTP_CONTROL_2) & OTP_RD_PERIOD_MASK) | CPU_CLOCK,
otp->base[OTPRX] + OTP_CONTROL_2);
ret = readl_poll_timeout(otp->base[OTPRX] + OTP_STATUS, status,
status & OTP_READ_DONE, 10, OTP_READ_TIMEOUT_US);
if (ret < 0)
return ret;
*value = (readl(otp->base[HB_GPIO] + ADDRESS_8_DATA + addr_data * OTP_WORD_SIZE)
>> (8 * byte_shift)) & 0xff;
return ret;
}
static int sp_ocotp_read(void *priv, unsigned int offset, void *value, size_t bytes)
{
struct sp_ocotp_priv *otp = priv;
unsigned int addr;
char *buf = value;
char val[4];
int ret;
ret = clk_enable(otp->clk);
if (ret)
return ret;
*buf = 0;
for (addr = offset; addr < (offset + bytes); addr++) {
ret = sp_otp_read_real(otp, addr, val);
if (ret < 0) {
dev_err(otp->dev, "OTP read fail:%d at %d", ret, addr);
goto disable_clk;
}
*buf++ = *val;
}
disable_clk:
clk_disable(otp->clk);
return ret;
}
static struct nvmem_config sp_ocotp_nvmem_config = {
.name = "sp-ocotp",
.add_legacy_fixed_of_cells = true,
.read_only = true,
.word_size = 1,
.size = QAC628_OTP_SIZE,
.stride = 1,
.reg_read = sp_ocotp_read,
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/clk.h`, `linux/delay.h`, `linux/device.h`, `linux/io.h`, `linux/iopoll.h`, `linux/module.h`, `linux/mod_devicetable.h`.
- Detected declarations: `struct sp_ocotp_priv`, `struct sp_ocotp_data`, `enum base_type`, `function sp_otp_read_real`, `function sp_ocotp_read`, `function sp_ocotp_probe`.
- Atlas domain: Driver Families / drivers/nvmem.
- Implementation status: source implementation candidate.
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.