drivers/nvmem/rmem.c
Source file repositories/reference/linux-study-clean/drivers/nvmem/rmem.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/nvmem/rmem.c- Extension
.c- Size
- 4367 bytes
- Lines
- 179
- 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/crc32.hlinux/io.hlinux/module.hlinux/nvmem-provider.hlinux/of_reserved_mem.hlinux/platform_device.hlinux/slab.h
Detected Declarations
struct rmemstruct rmem_match_datafunction rmem_readfunction rmem_eyeq5_checksumfunction rmem_probe
Annotated Snippet
struct rmem {
struct device *dev;
struct nvmem_device *nvmem;
struct reserved_mem *mem;
};
struct rmem_match_data {
int (*checksum)(struct rmem *priv);
};
struct __packed rmem_eyeq5_header {
u32 magic;
u32 version;
u32 size;
};
#define RMEM_EYEQ5_MAGIC ((u32)0xDABBAD00)
static int rmem_read(void *context, unsigned int offset,
void *val, size_t bytes)
{
struct rmem *priv = context;
void *addr;
if ((phys_addr_t)offset + bytes > priv->mem->size)
return -EIO;
/*
* Only map the reserved memory at this point to avoid potential rogue
* kernel threads inadvertently modifying it. Based on the current
* uses-cases for this driver, the performance hit isn't a concern.
* Nor is likely to be, given the nature of the subsystem. Most nvmem
* devices operate over slow buses to begin with.
*
* An alternative would be setting the memory as RO, set_memory_ro(),
* but as of Dec 2020 this isn't possible on arm64.
*/
addr = memremap(priv->mem->base, priv->mem->size, MEMREMAP_WB);
if (!addr) {
dev_err(priv->dev, "Failed to remap memory region\n");
return -ENOMEM;
}
memcpy(val, addr + offset, bytes);
memunmap(addr);
return 0;
}
static int rmem_eyeq5_checksum(struct rmem *priv)
{
void *buf __free(kfree) = NULL;
struct rmem_eyeq5_header header;
u32 computed_crc, *target_crc;
size_t data_size;
int ret;
ret = rmem_read(priv, 0, &header, sizeof(header));
if (ret)
return ret;
if (header.magic != RMEM_EYEQ5_MAGIC)
return -EINVAL;
/*
* Avoid massive kmalloc() if header read is invalid;
* the check would be done by the next rmem_read() anyway.
*/
if (header.size > priv->mem->size)
return -EINVAL;
/*
* 0 +-------------------+
* | Header (12 bytes) | \
* +-------------------+ |
* | | | data to be CRCed
* | ... | |
* | | /
* data_size +-------------------+
* | CRC (4 bytes) |
* header.size +-------------------+
*/
buf = kmalloc(header.size, GFP_KERNEL);
if (!buf)
return -ENOMEM;
ret = rmem_read(priv, 0, buf, header.size);
if (ret)
Annotation
- Immediate include surface: `linux/crc32.h`, `linux/io.h`, `linux/module.h`, `linux/nvmem-provider.h`, `linux/of_reserved_mem.h`, `linux/platform_device.h`, `linux/slab.h`.
- Detected declarations: `struct rmem`, `struct rmem_match_data`, `function rmem_read`, `function rmem_eyeq5_checksum`, `function rmem_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.