rpmsg: Support drivers without primary endpoint
authorBjorn Andersson <bjorn.andersson@linaro.org>
Sat, 8 Oct 2016 04:23:13 +0000 (21:23 -0700)
committerBjorn Andersson <bjorn.andersson@linaro.org>
Mon, 31 Oct 2016 22:41:55 +0000 (15:41 -0700)
Some types of rpmsg drivers does not have a primary endpoint to tie
their existence upon, but wishes to create and destroy endpoints
dynamically, e.g. based on user interactions.

Allow rpmsg drivers to omit a driver callback to signal this case and
make the probe path not create a primary endpoint in this case.

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
drivers/rpmsg/rpmsg_core.c

index 087d4db..7561941 100644 (file)
@@ -347,27 +347,30 @@ 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;
+       struct rpmsg_endpoint *ept = NULL;
        int err;
 
-       strncpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE);
-       chinfo.src = rpdev->src;
-       chinfo.dst = RPMSG_ADDR_ANY;
+       if (rpdrv->callback) {
+               strncpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE);
+               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;
-       }
+               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;
+               rpdev->ept = ept;
+               rpdev->src = ept->addr;
+       }
 
        err = rpdrv->probe(rpdev);
        if (err) {
                dev_err(dev, "%s: failed: %d\n", __func__, err);
-               rpmsg_destroy_ept(ept);
+               if (ept)
+                       rpmsg_destroy_ept(ept);
                goto out;
        }
 
@@ -388,7 +391,8 @@ static int rpmsg_dev_remove(struct device *dev)
 
        rpdrv->remove(rpdev);
 
-       rpmsg_destroy_ept(rpdev->ept);
+       if (rpdev->ept)
+               rpmsg_destroy_ept(rpdev->ept);
 
        return err;
 }