drivers/soc/qcom/rmtfs_mem.c
Source file repositories/reference/linux-study-clean/drivers/soc/qcom/rmtfs_mem.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/soc/qcom/rmtfs_mem.c- Extension
.c- Size
- 9239 bytes
- Lines
- 367
- Domain
- Driver Families
- Bucket
- drivers/soc
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/kernel.hlinux/cdev.hlinux/err.hlinux/module.hlinux/platform_device.hlinux/of.hlinux/of_reserved_mem.hlinux/dma-mapping.hlinux/slab.hlinux/uaccess.hlinux/io.hlinux/firmware/qcom/qcom_scm.h
Detected Declarations
struct qcom_rmtfs_memfunction qcom_rmtfs_mem_showfunction qcom_rmtfs_mem_openfunction qcom_rmtfs_mem_readfunction qcom_rmtfs_mem_writefunction qcom_rmtfs_mem_releasefunction qcom_rmtfs_mem_mmapfunction qcom_rmtfs_mem_release_devicefunction qcom_rmtfs_mem_probefunction qcom_rmtfs_mem_removefunction qcom_rmtfs_mem_initfunction qcom_rmtfs_mem_exitmodule init qcom_rmtfs_mem_init
Annotated Snippet
static const struct file_operations qcom_rmtfs_mem_fops = {
.owner = THIS_MODULE,
.open = qcom_rmtfs_mem_open,
.read = qcom_rmtfs_mem_read,
.write = qcom_rmtfs_mem_write,
.release = qcom_rmtfs_mem_release,
.llseek = default_llseek,
.mmap = qcom_rmtfs_mem_mmap,
};
static void qcom_rmtfs_mem_release_device(struct device *dev)
{
struct qcom_rmtfs_mem *rmtfs_mem = container_of(dev,
struct qcom_rmtfs_mem,
dev);
kfree(rmtfs_mem);
}
static int qcom_rmtfs_mem_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
struct qcom_scm_vmperm perms[NUM_MAX_VMIDS + 1];
struct reserved_mem *rmem;
struct qcom_rmtfs_mem *rmtfs_mem;
u32 client_id;
u32 vmid[NUM_MAX_VMIDS];
int num_vmids;
int ret, i;
rmem = of_reserved_mem_lookup(node);
if (!rmem) {
dev_err(&pdev->dev, "failed to acquire memory region\n");
return -EINVAL;
}
ret = of_property_read_u32(node, "qcom,client-id", &client_id);
if (ret) {
dev_err(&pdev->dev, "failed to parse \"qcom,client-id\"\n");
return ret;
}
rmtfs_mem = kzalloc_obj(*rmtfs_mem);
if (!rmtfs_mem)
return -ENOMEM;
rmtfs_mem->addr = rmem->base;
rmtfs_mem->client_id = client_id;
rmtfs_mem->size = rmem->size;
/*
* If requested, discard the first and last 4k block in order to ensure
* that the rmtfs region isn't adjacent to other protected regions.
*/
if (of_property_read_bool(node, "qcom,use-guard-pages")) {
rmtfs_mem->addr += SZ_4K;
rmtfs_mem->size -= 2 * SZ_4K;
}
device_initialize(&rmtfs_mem->dev);
rmtfs_mem->dev.parent = &pdev->dev;
rmtfs_mem->dev.groups = qcom_rmtfs_mem_groups;
rmtfs_mem->dev.release = qcom_rmtfs_mem_release_device;
rmtfs_mem->base = devm_memremap(&rmtfs_mem->dev, rmtfs_mem->addr,
rmtfs_mem->size, MEMREMAP_WC);
if (IS_ERR(rmtfs_mem->base)) {
dev_err(&pdev->dev, "failed to remap rmtfs_mem region\n");
ret = PTR_ERR(rmtfs_mem->base);
goto put_device;
}
cdev_init(&rmtfs_mem->cdev, &qcom_rmtfs_mem_fops);
rmtfs_mem->cdev.owner = THIS_MODULE;
dev_set_name(&rmtfs_mem->dev, "qcom_rmtfs_mem%d", client_id);
rmtfs_mem->dev.id = client_id;
rmtfs_mem->dev.class = &rmtfs_class;
rmtfs_mem->dev.devt = MKDEV(MAJOR(qcom_rmtfs_mem_major), client_id);
ret = cdev_device_add(&rmtfs_mem->cdev, &rmtfs_mem->dev);
if (ret) {
dev_err(&pdev->dev, "failed to add cdev: %d\n", ret);
goto put_device;
}
num_vmids = of_property_count_u32_elems(node, "qcom,vmid");
if (num_vmids == -EINVAL) {
/* qcom,vmid is optional */
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/cdev.h`, `linux/err.h`, `linux/module.h`, `linux/platform_device.h`, `linux/of.h`, `linux/of_reserved_mem.h`, `linux/dma-mapping.h`.
- Detected declarations: `struct qcom_rmtfs_mem`, `function qcom_rmtfs_mem_show`, `function qcom_rmtfs_mem_open`, `function qcom_rmtfs_mem_read`, `function qcom_rmtfs_mem_write`, `function qcom_rmtfs_mem_release`, `function qcom_rmtfs_mem_mmap`, `function qcom_rmtfs_mem_release_device`, `function qcom_rmtfs_mem_probe`, `function qcom_rmtfs_mem_remove`.
- Atlas domain: Driver Families / drivers/soc.
- Implementation status: pattern 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.