Do not dynamically manage the default endpoint associated to the rpmsg
device. The ept address must not change.

This update is needed to manage the rpmsg-raw channel. In this
case a default endpoint is used and its address must not change or
been reused by another service.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliq...@foss.st.com>
---
 drivers/rpmsg/rpmsg_char.c | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
index 4606787b7011..fa59abfa8878 100644
--- a/drivers/rpmsg/rpmsg_char.c
+++ b/drivers/rpmsg/rpmsg_char.c
@@ -112,17 +112,26 @@ static int rpmsg_eptdev_open(struct inode *inode, struct 
file *filp)
        struct rpmsg_endpoint *ept;
        struct rpmsg_device *rpdev = eptdev->rpdev;
        struct device *dev = &eptdev->dev;
+       u32 addr = eptdev->chinfo.src;
 
        if (eptdev->ept)
                return -EBUSY;
 
        get_device(dev);
 
-       ept = rpmsg_create_ept(rpdev, rpmsg_ept_cb, eptdev, eptdev->chinfo);
-       if (!ept) {
-               dev_err(dev, "failed to open %s\n", eptdev->chinfo.name);
-               put_device(dev);
-               return -EINVAL;
+       /*
+        * The RPMsg device can has been created by a ns announcement. In this
+        * case a default endpoint has been created. Reuse it to avoid to manage
+        * a new address on each open/close.
+        */
+       ept = rpdev->ept;
+       if (!ept || addr != ept->addr) {
+               ept = rpmsg_create_ept(rpdev, rpmsg_ept_cb, eptdev, 
eptdev->chinfo);
+               if (!ept) {
+                       dev_err(dev, "failed to open %s\n", 
eptdev->chinfo.name);
+                       put_device(dev);
+                       return -EINVAL;
+               }
        }
 
        eptdev->ept = ept;
@@ -134,12 +143,17 @@ static int rpmsg_eptdev_open(struct inode *inode, struct 
file *filp)
 static int rpmsg_eptdev_release(struct inode *inode, struct file *filp)
 {
        struct rpmsg_eptdev *eptdev = cdev_to_eptdev(inode->i_cdev);
+       struct rpmsg_device *rpdev = eptdev->rpdev;
        struct device *dev = &eptdev->dev;
 
-       /* Close the endpoint, if it's not already destroyed by the parent */
+       /*
+        * Close the endpoint, if it's not already destroyed by the parent and 
it is not the
+        * default one.
+        */
        mutex_lock(&eptdev->ept_lock);
        if (eptdev->ept) {
-               rpmsg_destroy_ept(eptdev->ept);
+               if (eptdev->ept != rpdev->ept)
+                       rpmsg_destroy_ept(eptdev->ept);
                eptdev->ept = NULL;
        }
        mutex_unlock(&eptdev->ept_lock);
-- 
2.17.1

Reply via email to