Skip to content

Commit bc69d10

Browse files
arnopoandersson
authored andcommitted
rpmsg: char: Introduce the "rpmsg-raw" channel
For the rpmsg virtio backend, the current implementation of the rpmsg char only allows to instantiate static(i.e. prefixed source and destination addresses) end points, and only on the Linux user space initiative. This patch defines the "rpmsg-raw" channel and registers it to the rpmsg bus. This registration allows: - To create the channel at the initiative of the remote processor relying on the name service announcement mechanism. In other words the /dev/rpmsgX interface is instantiate by the remote processor. - To use the channel object instead of the endpoint, thus preventing the user space from having the knowledge of the remote processor's endpoint addresses. - To rely on udev to be inform when a /dev/rpmsgX is created on remote processor request, indicating that the remote processor is ready to communicate. Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org> Link: https://lore.kernel.org/r/20220124102524.295783-11-arnaud.pouliquen@foss.st.com
1 parent bea9b79 commit bc69d10

1 file changed

Lines changed: 60 additions & 0 deletions

File tree

drivers/rpmsg/rpmsg_char.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,54 @@ int rpmsg_chrdev_eptdev_create(struct rpmsg_device *rpdev, struct device *parent
431431
}
432432
EXPORT_SYMBOL(rpmsg_chrdev_eptdev_create);
433433

434+
static int rpmsg_chrdev_probe(struct rpmsg_device *rpdev)
435+
{
436+
struct rpmsg_channel_info chinfo;
437+
struct rpmsg_eptdev *eptdev;
438+
struct device *dev = &rpdev->dev;
439+
440+
memcpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE);
441+
chinfo.src = rpdev->src;
442+
chinfo.dst = rpdev->dst;
443+
444+
eptdev = rpmsg_chrdev_eptdev_alloc(rpdev, dev);
445+
if (IS_ERR(eptdev))
446+
return PTR_ERR(eptdev);
447+
448+
/* Set the default_ept to the rpmsg device endpoint */
449+
eptdev->default_ept = rpdev->ept;
450+
451+
/*
452+
* The rpmsg_ept_cb uses *priv parameter to get its rpmsg_eptdev context.
453+
* Storedit in default_ept *priv field.
454+
*/
455+
eptdev->default_ept->priv = eptdev;
456+
457+
return rpmsg_chrdev_eptdev_add(eptdev, chinfo);
458+
}
459+
460+
static void rpmsg_chrdev_remove(struct rpmsg_device *rpdev)
461+
{
462+
int ret;
463+
464+
ret = device_for_each_child(&rpdev->dev, NULL, rpmsg_chrdev_eptdev_destroy);
465+
if (ret)
466+
dev_warn(&rpdev->dev, "failed to destroy endpoints: %d\n", ret);
467+
}
468+
469+
static struct rpmsg_device_id rpmsg_chrdev_id_table[] = {
470+
{ .name = "rpmsg-raw" },
471+
{ },
472+
};
473+
474+
static struct rpmsg_driver rpmsg_chrdev_driver = {
475+
.probe = rpmsg_chrdev_probe,
476+
.remove = rpmsg_chrdev_remove,
477+
.callback = rpmsg_ept_cb,
478+
.id_table = rpmsg_chrdev_id_table,
479+
.drv.name = "rpmsg_chrdev",
480+
};
481+
434482
static int rpmsg_chrdev_init(void)
435483
{
436484
int ret;
@@ -441,12 +489,24 @@ static int rpmsg_chrdev_init(void)
441489
return ret;
442490
}
443491

492+
ret = register_rpmsg_driver(&rpmsg_chrdev_driver);
493+
if (ret < 0) {
494+
pr_err("rpmsg: failed to register rpmsg raw driver\n");
495+
goto free_region;
496+
}
497+
444498
return 0;
499+
500+
free_region:
501+
unregister_chrdev_region(rpmsg_major, RPMSG_DEV_MAX);
502+
503+
return ret;
445504
}
446505
postcore_initcall(rpmsg_chrdev_init);
447506

448507
static void rpmsg_chrdev_exit(void)
449508
{
509+
unregister_rpmsg_driver(&rpmsg_chrdev_driver);
450510
unregister_chrdev_region(rpmsg_major, RPMSG_DEV_MAX);
451511
}
452512
module_exit(rpmsg_chrdev_exit);

0 commit comments

Comments
 (0)