Add TICOMGET and TIOCMSET ioctl support for rpmsg char device nodes
to get/set the low level transport signals.

Signed-off-by: Arun Kumar Neelakantam <ane...@codeaurora.org>
---
 drivers/rpmsg/rpmsg_char.c | 53 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 50 insertions(+), 3 deletions(-)

diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
index 4bbbacd..e2f92f3 100644
--- a/drivers/rpmsg/rpmsg_char.c
+++ b/drivers/rpmsg/rpmsg_char.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
+ * Copyright (c) 2018, The Linux Foundation.
  * Copyright (c) 2016, Linaro Ltd.
  * Copyright (c) 2012, Michal Simek <mon...@monstr.eu>
  * Copyright (c) 2012, PetaLogix
@@ -19,6 +20,7 @@
 #include <linux/rpmsg.h>
 #include <linux/skbuff.h>
 #include <linux/slab.h>
+#include <linux/termios.h>
 #include <linux/uaccess.h>
 #include <uapi/linux/rpmsg.h>
 
@@ -269,15 +271,60 @@ static __poll_t rpmsg_eptdev_poll(struct file *filp, 
poll_table *wait)
        return mask;
 }
 
+static int rpmsg_eptdev_tiocmset(struct file *fp, unsigned int cmd,
+                                int __user *arg)
+{
+       struct rpmsg_eptdev *eptdev = fp->private_data;
+       u32 set, clear, val;
+       int ret;
+
+       ret = get_user(val, arg);
+       if (ret)
+               return ret;
+       set = clear = 0;
+       switch (cmd) {
+       case TIOCMBIS:
+               set = val;
+               break;
+       case TIOCMBIC:
+               clear = val;
+               break;
+       case TIOCMSET:
+               set = val;
+               clear = ~val;
+               break;
+       }
+
+       set &= TIOCM_DTR | TIOCM_RTS | TIOCM_CD | TIOCM_RI;
+       clear &= TIOCM_DTR | TIOCM_RTS | TIOCM_CD | TIOCM_RI;
+
+       return rpmsg_set_signals(eptdev->ept, set, clear);
+}
+
 static long rpmsg_eptdev_ioctl(struct file *fp, unsigned int cmd,
                               unsigned long arg)
 {
        struct rpmsg_eptdev *eptdev = fp->private_data;
+       int ret;
 
-       if (cmd != RPMSG_DESTROY_EPT_IOCTL)
-               return -EINVAL;
+       switch (cmd) {
+       case TIOCMGET:
+               ret = rpmsg_get_signals(eptdev->ept);
+               if (ret >= 0)
+                       ret = put_user(ret, (int __user *)arg);
+               break;
+       case TIOCMSET:
+       case TIOCMBIS:
+       case TIOCMBIC:
+               ret = rpmsg_eptdev_tiocmset(fp, cmd, (int __user *)arg);
+               break;
+       case RPMSG_DESTROY_EPT_IOCTL:
+               ret = rpmsg_eptdev_destroy(&eptdev->dev, NULL);
+       default:
+               ret = -EINVAL;
+       }
 
-       return rpmsg_eptdev_destroy(&eptdev->dev, NULL);
+       return ret;
 }
 
 static const struct file_operations rpmsg_eptdev_fops = {
-- 
2.7.4

Reply via email to