summaryrefslogtreecommitdiffstats
path: root/drivers/rpmsg
diff options
context:
space:
mode:
authorBjorn Andersson <bjorn.andersson@linaro.org>2016-10-08 00:23:13 -0400
committerBjorn Andersson <bjorn.andersson@linaro.org>2016-10-31 18:41:55 -0400
commitbbd188092e3bd7536583b37e7d7d2e38a65de74d (patch)
treeb815146f5b7d48a1a90f5e6b49265ae27d3defda /drivers/rpmsg
parente950604782440c8635d289552bb5db58658fcbe9 (diff)
rpmsg: Support drivers without primary endpoint
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>
Diffstat (limited to 'drivers/rpmsg')
-rw-r--r--drivers/rpmsg/rpmsg_core.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c
index 087d4db896c8..7561941ba413 100644
--- a/drivers/rpmsg/rpmsg_core.c
+++ b/drivers/rpmsg/rpmsg_core.c
@@ -347,27 +347,30 @@ static int rpmsg_dev_probe(struct device *dev)
347 struct rpmsg_device *rpdev = to_rpmsg_device(dev); 347 struct rpmsg_device *rpdev = to_rpmsg_device(dev);
348 struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver); 348 struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver);
349 struct rpmsg_channel_info chinfo = {}; 349 struct rpmsg_channel_info chinfo = {};
350 struct rpmsg_endpoint *ept; 350 struct rpmsg_endpoint *ept = NULL;
351 int err; 351 int err;
352 352
353 strncpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE); 353 if (rpdrv->callback) {
354 chinfo.src = rpdev->src; 354 strncpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE);
355 chinfo.dst = RPMSG_ADDR_ANY; 355 chinfo.src = rpdev->src;
356 chinfo.dst = RPMSG_ADDR_ANY;
356 357
357 ept = rpmsg_create_ept(rpdev, rpdrv->callback, NULL, chinfo); 358 ept = rpmsg_create_ept(rpdev, rpdrv->callback, NULL, chinfo);
358 if (!ept) { 359 if (!ept) {
359 dev_err(dev, "failed to create endpoint\n"); 360 dev_err(dev, "failed to create endpoint\n");
360 err = -ENOMEM; 361 err = -ENOMEM;
361 goto out; 362 goto out;
362 } 363 }
363 364
364 rpdev->ept = ept; 365 rpdev->ept = ept;
365 rpdev->src = ept->addr; 366 rpdev->src = ept->addr;
367 }
366 368
367 err = rpdrv->probe(rpdev); 369 err = rpdrv->probe(rpdev);
368 if (err) { 370 if (err) {
369 dev_err(dev, "%s: failed: %d\n", __func__, err); 371 dev_err(dev, "%s: failed: %d\n", __func__, err);
370 rpmsg_destroy_ept(ept); 372 if (ept)
373 rpmsg_destroy_ept(ept);
371 goto out; 374 goto out;
372 } 375 }
373 376
@@ -388,7 +391,8 @@ static int rpmsg_dev_remove(struct device *dev)
388 391
389 rpdrv->remove(rpdev); 392 rpdrv->remove(rpdev);
390 393
391 rpmsg_destroy_ept(rpdev->ept); 394 if (rpdev->ept)
395 rpmsg_destroy_ept(rpdev->ept);
392 396
393 return err; 397 return err;
394} 398}