drivers/rpmsg/rpmsg_core.c
Source file repositories/reference/linux-study-clean/drivers/rpmsg/rpmsg_core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/rpmsg/rpmsg_core.c- Extension
.c- Size
- 17658 bytes
- Lines
- 639
- Domain
- Driver Families
- Bucket
- drivers/rpmsg
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/module.hlinux/rpmsg.hlinux/of_device.hlinux/pm_domain.hlinux/slab.hrpmsg_internal.h
Detected Declarations
function rpmsg_create_channelfunction rpmsg_release_channelfunction rpmsg_create_eptfunction rpmsg_destroy_eptfunction rpmsg_sendfunction rpmsg_sendtofunction rpmsg_trysendfunction rpmsg_trysendtofunction rpmsg_pollfunction rpmsg_set_flow_controlfunction rpmsg_get_mtufunction rpmsg_device_matchfunction modalias_showfunction rpmsg_id_matchfunction rpmsg_dev_matchfunction rpmsg_ueventfunction processorfunction rpmsg_dev_removefunction rpmsg_register_device_overridefunction rpmsg_register_devicefunction rpmsg_unregister_devicefunction __register_rpmsg_driverfunction unregister_rpmsg_driverfunction rpmsg_initfunction rpmsg_finiexport rpmsg_classexport rpmsg_create_channelexport rpmsg_release_channelexport rpmsg_create_eptexport rpmsg_destroy_eptexport rpmsg_sendexport rpmsg_sendtoexport rpmsg_trysendexport rpmsg_trysendtoexport rpmsg_pollexport rpmsg_set_flow_controlexport rpmsg_get_mtuexport rpmsg_find_deviceexport rpmsg_register_device_overrideexport rpmsg_register_deviceexport rpmsg_unregister_deviceexport __register_rpmsg_driverexport unregister_rpmsg_driver
Annotated Snippet
static int rpmsg_dev_match(struct device *dev, const struct device_driver *drv)
{
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
const struct rpmsg_driver *rpdrv = to_rpmsg_driver(drv);
const struct rpmsg_device_id *ids = rpdrv->id_table;
unsigned int i;
int ret;
ret = device_match_driver_override(dev, drv);
if (ret >= 0)
return ret;
if (ids)
for (i = 0; ids[i].name[0]; i++)
if (rpmsg_id_match(rpdev, &ids[i])) {
rpdev->id.driver_data = ids[i].driver_data;
return 1;
}
return of_driver_match_device(dev, drv);
}
static int rpmsg_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
const struct rpmsg_device *rpdev = to_rpmsg_device(dev);
int ret;
ret = of_device_uevent_modalias(dev, env);
if (ret != -ENODEV)
return ret;
return add_uevent_var(env, "MODALIAS=" RPMSG_DEVICE_MODALIAS_FMT,
rpdev->id.name);
}
/*
* when an rpmsg driver is probed with a channel, we seamlessly create
* it an endpoint, binding its rx callback to a unique local rpmsg
* address.
*
* if we need to, we also announce about this channel to the remote
* processor (needed in case the driver is exposing an rpmsg service).
*/
static int rpmsg_dev_probe(struct device *dev)
{
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver);
struct rpmsg_channel_info chinfo = {};
struct rpmsg_endpoint *ept = NULL;
int err;
err = dev_pm_domain_attach(dev, PD_FLAG_ATTACH_POWER_ON |
PD_FLAG_DETACH_POWER_OFF);
if (err)
goto out;
if (rpdrv->callback) {
strscpy(chinfo.name, rpdev->id.name, sizeof(chinfo.name));
chinfo.src = rpdev->src;
chinfo.dst = RPMSG_ADDR_ANY;
ept = rpmsg_create_ept(rpdev, rpdrv->callback, NULL, chinfo);
if (!ept) {
dev_err(dev, "failed to create endpoint\n");
err = -ENOMEM;
goto out;
}
rpdev->ept = ept;
rpdev->src = ept->addr;
ept->flow_cb = rpdrv->flowcontrol;
}
err = rpdrv->probe(rpdev);
if (err) {
dev_err(dev, "%s: failed: %d\n", __func__, err);
goto destroy_ept;
}
if (ept && rpdev->ops->announce_create) {
err = rpdev->ops->announce_create(rpdev);
if (err) {
dev_err(dev, "failed to announce creation\n");
goto remove_rpdev;
}
}
return 0;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/rpmsg.h`, `linux/of_device.h`, `linux/pm_domain.h`, `linux/slab.h`, `rpmsg_internal.h`.
- Detected declarations: `function rpmsg_create_channel`, `function rpmsg_release_channel`, `function rpmsg_create_ept`, `function rpmsg_destroy_ept`, `function rpmsg_send`, `function rpmsg_sendto`, `function rpmsg_trysend`, `function rpmsg_trysendto`, `function rpmsg_poll`, `function rpmsg_set_flow_control`.
- Atlas domain: Driver Families / drivers/rpmsg.
- Implementation status: pattern 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.