drivers/nvmem/zynqmp_nvmem.c
Source file repositories/reference/linux-study-clean/drivers/nvmem/zynqmp_nvmem.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/nvmem/zynqmp_nvmem.c- Extension
.c- Size
- 5995 bytes
- Lines
- 237
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/dma-mapping.hlinux/module.hlinux/nvmem-provider.hlinux/of.hlinux/platform_device.hlinux/firmware/xlnx-zynqmp.h
Detected Declarations
struct xilinx_efuseenum efuse_accessfunction zynqmp_efuse_accessfunction zynqmp_nvmem_readfunction zynqmp_nvmem_writefunction zynqmp_nvmem_probe
Annotated Snippet
struct xilinx_efuse {
u64 src;
u32 size;
u32 offset;
enum efuse_access flag;
u32 pufuserfuse;
};
static int zynqmp_efuse_access(void *context, unsigned int offset,
void *val, size_t bytes, enum efuse_access flag,
unsigned int pufflag)
{
struct device *dev = context;
struct xilinx_efuse *efuse;
dma_addr_t dma_addr;
dma_addr_t dma_buf;
size_t words = bytes / WORD_INBYTES;
int ret;
unsigned int value;
char *data;
if (bytes % WORD_INBYTES != 0) {
dev_err(dev, "Bytes requested should be word aligned\n");
return -EOPNOTSUPP;
}
if (pufflag == 0 && offset % WORD_INBYTES) {
dev_err(dev, "Offset requested should be word aligned\n");
return -EOPNOTSUPP;
}
if (pufflag == 1 && flag == EFUSE_WRITE) {
memcpy(&value, val, sizeof(value));
if ((offset == EFUSE_PUF_START_OFFSET ||
offset == EFUSE_PUF_MID_OFFSET) &&
value & P_USER_0_64_UPPER_MASK) {
dev_err(dev, "Only lower 4 bytes are allowed to be programmed in P_USER_0 & P_USER_64\n");
return -EOPNOTSUPP;
}
if (offset == EFUSE_PUF_END_OFFSET &&
(value & P_USER_127_LOWER_4_BIT_MASK)) {
dev_err(dev, "Only MSB 28 bits are allowed to be programmed for P_USER_127\n");
return -EOPNOTSUPP;
}
}
efuse = dma_alloc_coherent(dev, sizeof(struct xilinx_efuse),
&dma_addr, GFP_KERNEL);
if (!efuse)
return -ENOMEM;
data = dma_alloc_coherent(dev, bytes,
&dma_buf, GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
goto efuse_data_fail;
}
if (flag == EFUSE_WRITE) {
memcpy(data, val, bytes);
efuse->flag = EFUSE_WRITE;
} else {
efuse->flag = EFUSE_READ;
}
efuse->src = dma_buf;
efuse->size = words;
efuse->offset = offset;
efuse->pufuserfuse = pufflag;
zynqmp_pm_efuse_access(dma_addr, (u32 *)&ret);
if (ret != 0) {
if (ret == EFUSE_NOT_ENABLED) {
dev_err(dev, "efuse access is not enabled\n");
ret = -EOPNOTSUPP;
} else {
dev_err(dev, "Error in efuse read %x\n", ret);
ret = -EPERM;
}
goto efuse_access_err;
}
if (flag == EFUSE_READ)
memcpy(val, data, bytes);
efuse_access_err:
dma_free_coherent(dev, bytes,
data, dma_buf);
efuse_data_fail:
dma_free_coherent(dev, sizeof(struct xilinx_efuse),
Annotation
- Immediate include surface: `linux/dma-mapping.h`, `linux/module.h`, `linux/nvmem-provider.h`, `linux/of.h`, `linux/platform_device.h`, `linux/firmware/xlnx-zynqmp.h`.
- Detected declarations: `struct xilinx_efuse`, `enum efuse_access`, `function zynqmp_efuse_access`, `function zynqmp_nvmem_read`, `function zynqmp_nvmem_write`, `function zynqmp_nvmem_probe`.
- Atlas domain: Driver Families / drivers/nvmem.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.