Glink transport support signals to exchange state notification between
local and remote side clients. Adding support to send/receive the signal
command and notify the clients through callback and POLL notification.
Changes since v1:
- Split the patches as per functional areas like core, char, glink
- Add set, clear mask for TIOCMSET
- Merge the char signal callback and POLLPRI patches
Changes since v2:
- Modify the rpmsg_get_signals function prototype
Changes since v3:
- Correct the TICOMGET case handling as per new rpmsg_get_signals prototype
- Update the rpmsg_get_signals function header
Arun Kumar Neelakantam (4):
rpmsg: core: Add signal API support
rpmsg: glink: Add support to handle signals command
rpmsg: char: Add TIOCMGET/TIOCMSET ioctl support
rpmsg: char: Add signal callback and POLLPRI support
drivers/rpmsg/qcom_glink_native.c | 126 ++++++++++++++++++++++++++++++++++++++
drivers/rpmsg/rpmsg_char.c | 74 +++++++++++++++++++++-
drivers/rpmsg/rpmsg_core.c | 41 +++++++++++++
drivers/rpmsg/rpmsg_internal.h | 5 ++
include/linux/rpmsg.h | 26 ++++++++
5 files changed, 269 insertions(+), 3 deletions(-)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
Remote peripherals send signal notifications over glink with commandID 15.
Add support to send and receive the signal command and convert the signals
from NATIVE to TIOCM while receiving and vice versa while sending.
Signed-off-by: Chris Lew <[email protected]>
Signed-off-by: Arun Kumar Neelakantam <[email protected]>
---
drivers/rpmsg/qcom_glink_native.c | 126 ++++++++++++++++++++++++++++++++++++++
1 file changed, 126 insertions(+)
diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c
index e2ce4e6..e90f543 100644
--- a/drivers/rpmsg/qcom_glink_native.c
+++ b/drivers/rpmsg/qcom_glink_native.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
+ * Copyright (c) 2018, The Linux Foundation.
* Copyright (c) 2016-2017, Linaro Ltd
*/
@@ -17,6 +18,7 @@
#include <linux/rpmsg.h>
#include <linux/sizes.h>
#include <linux/slab.h>
+#include <linux/termios.h>
#include <linux/workqueue.h>
#include <linux/mailbox_client.h>
@@ -150,6 +152,8 @@ enum {
* @intent_req_lock: Synchronises multiple intent requests
* @intent_req_result: Result of intent request
* @intent_req_comp: Completion for intent_req signalling
+ * @lsigs: local side signals
+ * @rsigs: remote side signals
*/
struct glink_channel {
struct rpmsg_endpoint ept;
@@ -181,6 +185,10 @@ struct glink_channel {
struct mutex intent_req_lock;
bool intent_req_result;
struct completion intent_req_comp;
+
+ unsigned int lsigs;
+ unsigned int rsigs;
+
};
#define to_glink_channel(_ept) container_of(_ept, struct glink_channel, ept)
@@ -201,9 +209,15 @@ struct glink_channel {
#define RPM_CMD_TX_DATA_CONT 12
#define RPM_CMD_READ_NOTIF 13
#define RPM_CMD_RX_DONE_W_REUSE 14
+#define RPM_CMD_SIGNALS 15
#define GLINK_FEATURE_INTENTLESS BIT(1)
+#define NATIVE_DTR_SIG BIT(31)
+#define NATIVE_CTS_SIG BIT(30)
+#define NATIVE_CD_SIG BIT(29)
+#define NATIVE_RI_SIG BIT(28)
+
static void qcom_glink_rx_done_work(struct work_struct *work);
static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink,
@@ -957,6 +971,76 @@ static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid)
return 0;
}
+/**
+ * qcom_glink_send_signals() - convert a signal cmd to wire format and transmit
+ * @glink: The transport to transmit on.
+ * @channel: The glink channel
+ * @sigs: The signals to encode.
+ *
+ * Return: 0 on success or standard Linux error code.
+ */
+static int qcom_glink_send_signals(struct qcom_glink *glink,
+ struct glink_channel *channel,
+ u32 sigs)
+{
+ struct glink_msg msg;
+
+ /* convert signals from TIOCM to NATIVE */
+ sigs &= 0x0fff;
+ if (sigs & TIOCM_DTR)
+ sigs |= NATIVE_DTR_SIG;
+ if (sigs & TIOCM_RTS)
+ sigs |= NATIVE_CTS_SIG;
+ if (sigs & TIOCM_CD)
+ sigs |= NATIVE_CD_SIG;
+ if (sigs & TIOCM_RI)
+ sigs |= NATIVE_RI_SIG;
+
+ msg.cmd = cpu_to_le16(RPM_CMD_SIGNALS);
+ msg.param1 = cpu_to_le16(channel->lcid);
+ msg.param2 = cpu_to_le32(sigs);
+
+ return qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true);
+}
+
+static int qcom_glink_handle_signals(struct qcom_glink *glink,
+ unsigned int rcid, unsigned int signals)
+{
+ struct glink_channel *channel;
+ unsigned long flags;
+ u32 old;
+
+ spin_lock_irqsave(&glink->idr_lock, flags);
+ channel = idr_find(&glink->rcids, rcid);
+ spin_unlock_irqrestore(&glink->idr_lock, flags);
+ if (!channel) {
+ dev_err(glink->dev, "signal for non-existing channel\n");
+ return -EINVAL;
+ }
+
+ old = channel->rsigs;
+
+ /* convert signals from NATIVE to TIOCM */
+ if (signals & NATIVE_DTR_SIG)
+ signals |= TIOCM_DSR;
+ if (signals & NATIVE_CTS_SIG)
+ signals |= TIOCM_CTS;
+ if (signals & NATIVE_CD_SIG)
+ signals |= TIOCM_CD;
+ if (signals & NATIVE_RI_SIG)
+ signals |= TIOCM_RI;
+ signals &= 0x0fff;
+
+ channel->rsigs = signals;
+
+ if (channel->ept.sig_cb) {
+ channel->ept.sig_cb(channel->ept.rpdev, channel->ept.priv,
+ old, channel->rsigs);
+ }
+
+ return 0;
+}
+
static irqreturn_t qcom_glink_native_intr(int irq, void *data)
{
struct qcom_glink *glink = data;
@@ -1018,6 +1102,10 @@ static irqreturn_t qcom_glink_native_intr(int irq, void *data)
qcom_glink_handle_intent_req_ack(glink, param1, param2);
qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
break;
+ case RPM_CMD_SIGNALS:
+ qcom_glink_handle_signals(glink, param1, param2);
+ qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
+ break;
default:
dev_err(glink->dev, "unhandled rx cmd: %d\n", cmd);
ret = -EINVAL;
@@ -1315,6 +1403,42 @@ static int qcom_glink_trysend(struct rpmsg_endpoint *ept, void *data, int len)
return __qcom_glink_send(channel, data, len, false);
}
+static int qcom_glink_get_sigs(struct rpmsg_endpoint *ept)
+{
+ struct glink_channel *channel = to_glink_channel(ept);
+
+ return channel->rsigs;
+}
+
+static int qcom_glink_set_sigs(struct rpmsg_endpoint *ept, u32 set, u32 clear)
+{
+ struct glink_channel *channel = to_glink_channel(ept);
+ struct qcom_glink *glink = channel->glink;
+ u32 sigs = channel->lsigs;
+
+ if (set & TIOCM_DTR)
+ sigs |= TIOCM_DTR;
+ if (set & TIOCM_RTS)
+ sigs |= TIOCM_RTS;
+ if (set & TIOCM_CD)
+ sigs |= TIOCM_CD;
+ if (set & TIOCM_RI)
+ sigs |= TIOCM_RI;
+
+ if (clear & TIOCM_DTR)
+ sigs &= ~TIOCM_DTR;
+ if (clear & TIOCM_RTS)
+ sigs &= ~TIOCM_RTS;
+ if (clear & TIOCM_CD)
+ sigs &= ~TIOCM_CD;
+ if (clear & TIOCM_RI)
+ sigs &= ~TIOCM_RI;
+
+ channel->lsigs = sigs;
+
+ return qcom_glink_send_signals(glink, channel, sigs);
+}
+
/*
* Finds the device_node for the glink child interested in this channel.
*/
@@ -1348,6 +1472,8 @@ static struct device_node *qcom_glink_match_channel(struct device_node *node,
.destroy_ept = qcom_glink_destroy_ept,
.send = qcom_glink_send,
.trysend = qcom_glink_trysend,
+ .get_signals = qcom_glink_get_sigs,
+ .set_signals = qcom_glink_set_sigs,
};
static void qcom_glink_rpdev_release(struct device *dev)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
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 <[email protected]>
---
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 a76b963..b136684 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 <[email protected]>
* 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>
@@ -266,15 +268,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 = {
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
Some transports like Glink support the state notifications between
clients using signals similar to serial protocol signals.
Signed-off-by: Chris Lew <[email protected]>
Signed-off-by: Arun Kumar Neelakantam <[email protected]>
---
drivers/rpmsg/rpmsg_core.c | 41 +++++++++++++++++++++++++++++++++++++++++
drivers/rpmsg/rpmsg_internal.h | 5 +++++
include/linux/rpmsg.h | 26 ++++++++++++++++++++++++++
3 files changed, 72 insertions(+)
diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c
index 8122807..3d7458a 100644
--- a/drivers/rpmsg/rpmsg_core.c
+++ b/drivers/rpmsg/rpmsg_core.c
@@ -2,6 +2,7 @@
/*
* remote processor messaging bus
*
+ * Copyright (c) 2018, The Linux Foundation.
* Copyright (C) 2011 Texas Instruments, Inc.
* Copyright (C) 2011 Google, Inc.
*
@@ -283,6 +284,42 @@ int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst,
}
EXPORT_SYMBOL(rpmsg_trysend_offchannel);
+/**
+ * rpmsg_get_signals() - get the signals for this endpoint
+ * @ept: the rpmsg endpoint
+ *
+ * Returns signal bits on success and an appropriate error value on failure.
+ */
+int rpmsg_get_signals(struct rpmsg_endpoint *ept)
+{
+ if (WARN_ON(!ept))
+ return -EINVAL;
+ if (!ept->ops->get_signals)
+ return -EOPNOTSUPP;
+
+ return ept->ops->get_signals(ept);
+}
+EXPORT_SYMBOL(rpmsg_get_signals);
+
+/**
+ * rpmsg_set_signals() - set the remote signals for this endpoint
+ * @ept: the rpmsg endpoint
+ * @set: set mask for signals
+ * @clear: clear mask for signals
+ *
+ * Returns 0 on success and an appropriate error value on failure.
+ */
+int rpmsg_set_signals(struct rpmsg_endpoint *ept, u32 set, u32 clear)
+{
+ if (WARN_ON(!ept))
+ return -EINVAL;
+ if (!ept->ops->set_signals)
+ return -EOPNOTSUPP;
+
+ return ept->ops->set_signals(ept, set, clear);
+}
+EXPORT_SYMBOL(rpmsg_set_signals);
+
/*
* match an rpmsg channel with a channel info struct.
* this is used to make sure we're not creating rpmsg devices for channels
@@ -468,6 +505,10 @@ static int rpmsg_dev_probe(struct device *dev)
rpdev->ept = ept;
rpdev->src = ept->addr;
+
+ if (rpdrv->signals)
+ ept->sig_cb = rpdrv->signals;
+
}
err = rpdrv->probe(rpdev);
diff --git a/drivers/rpmsg/rpmsg_internal.h b/drivers/rpmsg/rpmsg_internal.h
index 0d791c3..033656d 100644
--- a/drivers/rpmsg/rpmsg_internal.h
+++ b/drivers/rpmsg/rpmsg_internal.h
@@ -2,6 +2,7 @@
/*
* remote processor messaging bus internals
*
+ * Copyright (c) 2018, The Linux Foundation.
* Copyright (C) 2011 Texas Instruments, Inc.
* Copyright (C) 2011 Google, Inc.
*
@@ -46,6 +47,8 @@ struct rpmsg_device_ops {
* @trysend: see @rpmsg_trysend(), required
* @trysendto: see @rpmsg_trysendto(), optional
* @trysend_offchannel: see @rpmsg_trysend_offchannel(), optional
+ * @get_signals: see @rpmsg_get_signals(), optional
+ * @set_signals: see @rpmsg_set_signals(), optional
*
* Indirection table for the operations that a rpmsg backend should implement.
* In addition to @destroy_ept, the backend must at least implement @send and
@@ -65,6 +68,8 @@ struct rpmsg_endpoint_ops {
void *data, int len);
__poll_t (*poll)(struct rpmsg_endpoint *ept, struct file *filp,
poll_table *wait);
+ int (*get_signals)(struct rpmsg_endpoint *ept);
+ int (*set_signals)(struct rpmsg_endpoint *ept, u32 set, u32 clear);
};
int rpmsg_register_device(struct rpmsg_device *rpdev);
diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h
index 9fe156d..48c8ae3 100644
--- a/include/linux/rpmsg.h
+++ b/include/linux/rpmsg.h
@@ -2,6 +2,7 @@
/*
* Remote processor messaging
*
+ * Copyright (c) 2018 The Linux Foundation.
* Copyright (C) 2011 Texas Instruments, Inc.
* Copyright (C) 2011 Google, Inc.
* All rights reserved.
@@ -60,6 +61,7 @@ struct rpmsg_device {
};
typedef int (*rpmsg_rx_cb_t)(struct rpmsg_device *, void *, int, void *, u32);
+typedef int (*rpmsg_rx_sig_t)(struct rpmsg_device *, void *, u32, u32);
/**
* struct rpmsg_endpoint - binds a local rpmsg address to its user
@@ -67,6 +69,7 @@ struct rpmsg_device {
* @refcount: when this drops to zero, the ept is deallocated
* @cb: rx callback handler
* @cb_lock: must be taken before accessing/changing @cb
+ * @sig_cb: rx serial signal handler
* @addr: local rpmsg address
* @priv: private data for the driver's use
*
@@ -89,6 +92,7 @@ struct rpmsg_endpoint {
struct kref refcount;
rpmsg_rx_cb_t cb;
struct mutex cb_lock;
+ rpmsg_rx_sig_t sig_cb;
u32 addr;
void *priv;
@@ -102,6 +106,7 @@ struct rpmsg_endpoint {
* @probe: invoked when a matching rpmsg channel (i.e. device) is found
* @remove: invoked when the rpmsg channel is removed
* @callback: invoked when an inbound message is received on the channel
+ * @signals: invoked when a serial signal change is received on the channel
*/
struct rpmsg_driver {
struct device_driver drv;
@@ -109,6 +114,7 @@ struct rpmsg_driver {
int (*probe)(struct rpmsg_device *dev);
void (*remove)(struct rpmsg_device *dev);
int (*callback)(struct rpmsg_device *, void *, int, void *, u32);
+ int (*signals)(struct rpmsg_device *, void *, u32, u32);
};
#if IS_ENABLED(CONFIG_RPMSG)
@@ -135,6 +141,9 @@ int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst,
__poll_t rpmsg_poll(struct rpmsg_endpoint *ept, struct file *filp,
poll_table *wait);
+int rpmsg_get_signals(struct rpmsg_endpoint *ept);
+int rpmsg_set_signals(struct rpmsg_endpoint *ept, u32 set, u32 clear);
+
#else
static inline int register_rpmsg_device(struct rpmsg_device *dev)
@@ -242,6 +251,23 @@ static inline __poll_t rpmsg_poll(struct rpmsg_endpoint *ept,
return 0;
}
+static inline int rpmsg_get_signals(struct rpmsg_endpoint *ept)
+{
+ /* This shouldn't be possible */
+ WARN_ON(1);
+
+ return -ENXIO;
+}
+
+static inline int rpmsg_set_signals(struct rpmsg_endpoint *ept,
+ u32 set, u32 clear)
+{
+ /* This shouldn't be possible */
+ WARN_ON(1);
+
+ return -ENXIO;
+}
+
#endif /* IS_ENABLED(CONFIG_RPMSG) */
/* use a macro to avoid include chaining to get THIS_MODULE */
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
Register a callback to get the signal notifications from rpmsg and
send POLLPRI mask to indicate the signal change in POLL system call.
Signed-off-by: Arun Kumar Neelakantam <[email protected]>
---
drivers/rpmsg/rpmsg_char.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
index b136684..8a3cbe9 100644
--- a/drivers/rpmsg/rpmsg_char.c
+++ b/drivers/rpmsg/rpmsg_char.c
@@ -64,6 +64,7 @@ struct rpmsg_ctrldev {
* @queue_lock: synchronization of @queue operations
* @queue: incoming message queue
* @readq: wait object for incoming queue
+ * @sig_pending:state of signal notification
*/
struct rpmsg_eptdev {
struct device dev;
@@ -78,6 +79,8 @@ struct rpmsg_eptdev {
spinlock_t queue_lock;
struct sk_buff_head queue;
wait_queue_head_t readq;
+
+ bool sig_pending;
};
static int rpmsg_eptdev_destroy(struct device *dev, void *data)
@@ -122,6 +125,18 @@ static int rpmsg_ept_cb(struct rpmsg_device *rpdev, void *buf, int len,
return 0;
}
+static int rpmsg_sigs_cb(struct rpmsg_device *rpdev, void *priv,
+ u32 old, u32 new)
+{
+ struct rpmsg_eptdev *eptdev = priv;
+
+ eptdev->sig_pending = true;
+
+ /* wake up any blocking processes, waiting for signal notification */
+ wake_up_interruptible(&eptdev->readq);
+ return 0;
+}
+
static int rpmsg_eptdev_open(struct inode *inode, struct file *filp)
{
struct rpmsg_eptdev *eptdev = cdev_to_eptdev(inode->i_cdev);
@@ -138,6 +153,7 @@ static int rpmsg_eptdev_open(struct inode *inode, struct file *filp)
return -EINVAL;
}
+ ept->sig_cb = rpmsg_sigs_cb;
eptdev->ept = ept;
filp->private_data = eptdev;
@@ -157,6 +173,7 @@ static int rpmsg_eptdev_release(struct inode *inode, struct file *filp)
eptdev->ept = NULL;
}
mutex_unlock(&eptdev->ept_lock);
+ eptdev->sig_pending = false;
/* Discard all SKBs */
while (!skb_queue_empty(&eptdev->queue)) {
@@ -263,6 +280,9 @@ static __poll_t rpmsg_eptdev_poll(struct file *filp, poll_table *wait)
if (!skb_queue_empty(&eptdev->queue))
mask |= EPOLLIN | EPOLLRDNORM;
+ if (eptdev->sig_pending)
+ mask |= POLLPRI;
+
mask |= rpmsg_poll(eptdev->ept, filp, wait);
return mask;
@@ -306,6 +326,7 @@ static long rpmsg_eptdev_ioctl(struct file *fp, unsigned int cmd,
switch (cmd) {
case TIOCMGET:
+ eptdev->sig_pending = false;
ret = rpmsg_get_signals(eptdev->ept);
if (ret >= 0)
ret = put_user(ret, (int __user *)arg);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
Hi Arun, Bjorn,
On 10/08/2018 08:38 AM, Arun Kumar Neelakantam wrote:
> Glink transport support signals to exchange state notification between
> local and remote side clients. Adding support to send/receive the signal
> command and notify the clients through callback and POLL notification.
Please correct me if i'm wrong...My concern here is that this patchset
implements a rpmsg service in the rpmsg core. I would separate this from
the rpmsg core, as this is not part of the rpmsg protocol but seems
linked to the serial protocol itself.
Could it be implemented in rpmsg_char, using a dedicated channel...?
Regards
Arnaud
>
> Changes since v1:
> - Split the patches as per functional areas like core, char, glink
> - Add set, clear mask for TIOCMSET
> - Merge the char signal callback and POLLPRI patches
>
> Changes since v2:
> - Modify the rpmsg_get_signals function prototype
>
> Changes since v3:
> - Correct the TICOMGET case handling as per new rpmsg_get_signals prototype
> - Update the rpmsg_get_signals function header
>
> Arun Kumar Neelakantam (4):
> rpmsg: core: Add signal API support
> rpmsg: glink: Add support to handle signals command
> rpmsg: char: Add TIOCMGET/TIOCMSET ioctl support
> rpmsg: char: Add signal callback and POLLPRI support
>
> drivers/rpmsg/qcom_glink_native.c | 126 ++++++++++++++++++++++++++++++++++++++
> drivers/rpmsg/rpmsg_char.c | 74 +++++++++++++++++++++-
> drivers/rpmsg/rpmsg_core.c | 41 +++++++++++++
> drivers/rpmsg/rpmsg_internal.h | 5 ++
> include/linux/rpmsg.h | 26 ++++++++
> 5 files changed, 269 insertions(+), 3 deletions(-)
>
On Mon 08 Oct 06:08 PDT 2018, Arnaud Pouliquen wrote:
> Hi Arun, Bjorn,
>
> On 10/08/2018 08:38 AM, Arun Kumar Neelakantam wrote:
> > Glink transport support signals to exchange state notification between
> > local and remote side clients. Adding support to send/receive the signal
> > command and notify the clients through callback and POLL notification.
>
> Please correct me if i'm wrong...My concern here is that this patchset
> implements a rpmsg service in the rpmsg core. I would separate this from
> the rpmsg core, as this is not part of the rpmsg protocol but seems
> linked to the serial protocol itself.
> Could it be implemented in rpmsg_char, using a dedicated channel...?
>
rpmsg_char does expose a rpmsg channel (be it virtio, smd or glink) to
user space. This patch series add support for invoking TIOCMGET and
TIOCMSET on these channels.
In addition to adding the client side of this to rpmsg_char it provides
this support for glink, but the same mechanism exists in smd - while
this is not supported (today) by the virtio rpmsg.
I'm uncertain of how we could implement this mechanism for virtio rpmsg,
given that it as a transport doesn't really have a concept of
channels/flows - but it's really useful to have!
PS. rpmsg_set_signals() can be called from any rpmsg device to perform
flow control of the communication channel.
Regards,
Bjorn
> Regards
> Arnaud
>
> >
> > Changes since v1:
> > - Split the patches as per functional areas like core, char, glink
> > - Add set, clear mask for TIOCMSET
> > - Merge the char signal callback and POLLPRI patches
> >
> > Changes since v2:
> > - Modify the rpmsg_get_signals function prototype
> >
> > Changes since v3:
> > - Correct the TICOMGET case handling as per new rpmsg_get_signals prototype
> > - Update the rpmsg_get_signals function header
> >
> > Arun Kumar Neelakantam (4):
> > rpmsg: core: Add signal API support
> > rpmsg: glink: Add support to handle signals command
> > rpmsg: char: Add TIOCMGET/TIOCMSET ioctl support
> > rpmsg: char: Add signal callback and POLLPRI support
> >
> > drivers/rpmsg/qcom_glink_native.c | 126 ++++++++++++++++++++++++++++++++++++++
> > drivers/rpmsg/rpmsg_char.c | 74 +++++++++++++++++++++-
> > drivers/rpmsg/rpmsg_core.c | 41 +++++++++++++
> > drivers/rpmsg/rpmsg_internal.h | 5 ++
> > include/linux/rpmsg.h | 26 ++++++++
> > 5 files changed, 269 insertions(+), 3 deletions(-)
> >
hello Bjorn,
On 10/08/2018 06:23 PM, Bjorn Andersson wrote:
> On Mon 08 Oct 06:08 PDT 2018, Arnaud Pouliquen wrote:
>
>> Hi Arun, Bjorn,
>>
>> On 10/08/2018 08:38 AM, Arun Kumar Neelakantam wrote:
>>> Glink transport support signals to exchange state notification between
>>> local and remote side clients. Adding support to send/receive the signal
>>> command and notify the clients through callback and POLL notification.
>>
>> Please correct me if i'm wrong...My concern here is that this patchset
>> implements a rpmsg service in the rpmsg core. I would separate this from
>> the rpmsg core, as this is not part of the rpmsg protocol but seems
>> linked to the serial protocol itself.
>> Could it be implemented in rpmsg_char, using a dedicated channel...?
>>
>
> rpmsg_char does expose a rpmsg channel (be it virtio, smd or glink) to
> user space. This patch series add support for invoking TIOCMGET and
> TIOCMSET on these channels.
I'm not familiar with this concept, that could explain that i don't
understand this patchset...
TIOCMGET and TIOCMSET is related to the serial/console flow control, to
control remote modem/processor, right?
it seems be implemented only to support the rpmsg_char ioctl interface.
When i have a look to the glink code, signal is treated by a message
sent to remote processor. Therefore it seems that it could be treated as
a service on top of rpmsg (so treat it in rpmsg_char instead of extend
the rpmsg protocol to treat it in glink driver).
>
> In addition to adding the client side of this to rpmsg_char it provides
> this support for glink, but the same mechanism exists in smd - while
> this is not supported (today) by the virtio rpmsg.
This is my main concern, i would like to be sure that this service is
not related to specific needs introduced by the rmpsg char implementation:
In this case this should not be part of the rpmsg core but perhaps some
ops directly provided to the rpmsg_char on registration
(rpmsg_chrdev_register_device?)...
>
>
> I'm uncertain of how we could implement this mechanism for virtio rpmsg,
> given that it as a transport doesn't really have a concept of
> channels/flows - but it's really useful to have!
>
> PS. rpmsg_set_signals() can be called from any rpmsg device to perform
> flow control of the communication channel.
For my point of view this patch-set extends the rpmsg protocol to add
channel flow control.
Does it make sense to have a flow control in rpmsg protocol?
if yes, should it be linked to a channel or to the remote processor itself?
Extra comment: associated documentation update is missing.
Regards,
Arnaud
>
> Regards,
> Bjorn
>
>> Regards
>> Arnaud
>>
>>>
>>> Changes since v1:
>>> - Split the patches as per functional areas like core, char, glink
>>> - Add set, clear mask for TIOCMSET
>>> - Merge the char signal callback and POLLPRI patches
>>>
>>> Changes since v2:
>>> - Modify the rpmsg_get_signals function prototype
>>>
>>> Changes since v3:
>>> - Correct the TICOMGET case handling as per new rpmsg_get_signals prototype
>>> - Update the rpmsg_get_signals function header
>>>
>>> Arun Kumar Neelakantam (4):
>>> rpmsg: core: Add signal API support
>>> rpmsg: glink: Add support to handle signals command
>>> rpmsg: char: Add TIOCMGET/TIOCMSET ioctl support
>>> rpmsg: char: Add signal callback and POLLPRI support
>>>
>>> drivers/rpmsg/qcom_glink_native.c | 126 ++++++++++++++++++++++++++++++++++++++
>>> drivers/rpmsg/rpmsg_char.c | 74 +++++++++++++++++++++-
>>> drivers/rpmsg/rpmsg_core.c | 41 +++++++++++++
>>> drivers/rpmsg/rpmsg_internal.h | 5 ++
>>> include/linux/rpmsg.h | 26 ++++++++
>>> 5 files changed, 269 insertions(+), 3 deletions(-)
>>>
On Tue 09 Oct 09:02 PDT 2018, Arnaud Pouliquen wrote:
> hello Bjorn,
>
> On 10/08/2018 06:23 PM, Bjorn Andersson wrote:
> > On Mon 08 Oct 06:08 PDT 2018, Arnaud Pouliquen wrote:
> >
> >> Hi Arun, Bjorn,
> >>
> >> On 10/08/2018 08:38 AM, Arun Kumar Neelakantam wrote:
> >>> Glink transport support signals to exchange state notification between
> >>> local and remote side clients. Adding support to send/receive the signal
> >>> command and notify the clients through callback and POLL notification.
> >>
> >> Please correct me if i'm wrong...My concern here is that this patchset
> >> implements a rpmsg service in the rpmsg core. I would separate this from
> >> the rpmsg core, as this is not part of the rpmsg protocol but seems
> >> linked to the serial protocol itself.
> >> Could it be implemented in rpmsg_char, using a dedicated channel...?
> >>
> >
> > rpmsg_char does expose a rpmsg channel (be it virtio, smd or glink) to
> > user space. This patch series add support for invoking TIOCMGET and
> > TIOCMSET on these channels.
>
> I'm not familiar with this concept, that could explain that i don't
> understand this patchset...
>
> TIOCMGET and TIOCMSET is related to the serial/console flow control, to
> control remote modem/processor, right?
>
Correct, using the known tty ioctls for flow control we allow userspace
to communicate flow control information to the rpmsg_char driver.
> it seems be implemented only to support the rpmsg_char ioctl interface.
> When i have a look to the glink code, signal is treated by a message
> sent to remote processor. Therefore it seems that it could be treated as
> a service on top of rpmsg (so treat it in rpmsg_char instead of extend
> the rpmsg protocol to treat it in glink driver).
>
The glink message is a control message, so it's not possible to pass
this inside a channel. As such it's not possible to solve this entirely
in rpmsg_char.
Looking at SMD, this is a set of bits in a per-channel control
structure. So there it's clearer that it's some side-band control
information.
Further more, the rpmsg_char driver just exposes a channel to user
space, it does not care about the data inside. As such it's not possible
to generically extend it to support this with in-band messages.
> >
> > In addition to adding the client side of this to rpmsg_char it provides
> > this support for glink, but the same mechanism exists in smd - while
> > this is not supported (today) by the virtio rpmsg.
> This is my main concern, i would like to be sure that this service is
> not related to specific needs introduced by the rmpsg char implementation:
> In this case this should not be part of the rpmsg core but perhaps some
> ops directly provided to the rpmsg_char on registration
> (rpmsg_chrdev_register_device?)...
>
Arun's imminent need is for a user space client that needs to flow
control the incoming data stream. But the possibility of controlling the
incoming flow of data is useful in a number of situations.
> >
> >
> > I'm uncertain of how we could implement this mechanism for virtio rpmsg,
> > given that it as a transport doesn't really have a concept of
> > channels/flows - but it's really useful to have!
> >
> > PS. rpmsg_set_signals() can be called from any rpmsg device to perform
> > flow control of the communication channel.
>
> For my point of view this patch-set extends the rpmsg protocol to add
> channel flow control.
> Does it make sense to have a flow control in rpmsg protocol?
> if yes, should it be linked to a channel or to the remote processor itself?
>
Having per-channel flow control particularly useful in scenarios where
one has multiple types of data flowing over a shared underlying FIFO -
such as virtio rpmsg. As this allows these different applications to
limit the data rate without having to use application specific side band
controls.
> Extra comment: associated documentation update is missing.
>
Good catch, we should have a section in Documentation/rpmsg.txt
describing this mechanism.
Regards,
Bjorn
> Regards,
> Arnaud
>
> >
> > Regards,
> > Bjorn
> >
> >> Regards
> >> Arnaud
> >>
> >>>
> >>> Changes since v1:
> >>> - Split the patches as per functional areas like core, char, glink
> >>> - Add set, clear mask for TIOCMSET
> >>> - Merge the char signal callback and POLLPRI patches
> >>>
> >>> Changes since v2:
> >>> - Modify the rpmsg_get_signals function prototype
> >>>
> >>> Changes since v3:
> >>> - Correct the TICOMGET case handling as per new rpmsg_get_signals prototype
> >>> - Update the rpmsg_get_signals function header
> >>>
> >>> Arun Kumar Neelakantam (4):
> >>> rpmsg: core: Add signal API support
> >>> rpmsg: glink: Add support to handle signals command
> >>> rpmsg: char: Add TIOCMGET/TIOCMSET ioctl support
> >>> rpmsg: char: Add signal callback and POLLPRI support
> >>>
> >>> drivers/rpmsg/qcom_glink_native.c | 126 ++++++++++++++++++++++++++++++++++++++
> >>> drivers/rpmsg/rpmsg_char.c | 74 +++++++++++++++++++++-
> >>> drivers/rpmsg/rpmsg_core.c | 41 +++++++++++++
> >>> drivers/rpmsg/rpmsg_internal.h | 5 ++
> >>> include/linux/rpmsg.h | 26 ++++++++
> >>> 5 files changed, 269 insertions(+), 3 deletions(-)
> >>>
On 10/09/2018 08:27 PM, Bjorn Andersson wrote:
> On Tue 09 Oct 09:02 PDT 2018, Arnaud Pouliquen wrote:
>
>> hello Bjorn,
>>
>> On 10/08/2018 06:23 PM, Bjorn Andersson wrote:
>>> On Mon 08 Oct 06:08 PDT 2018, Arnaud Pouliquen wrote:
>>>
>>>> Hi Arun, Bjorn,
>>>>
>>>> On 10/08/2018 08:38 AM, Arun Kumar Neelakantam wrote:
>>>>> Glink transport support signals to exchange state notification between
>>>>> local and remote side clients. Adding support to send/receive the signal
>>>>> command and notify the clients through callback and POLL notification.
>>>>
>>>> Please correct me if i'm wrong...My concern here is that this patchset
>>>> implements a rpmsg service in the rpmsg core. I would separate this from
>>>> the rpmsg core, as this is not part of the rpmsg protocol but seems
>>>> linked to the serial protocol itself.
>>>> Could it be implemented in rpmsg_char, using a dedicated channel...?
>>>>
>>>
>>> rpmsg_char does expose a rpmsg channel (be it virtio, smd or glink) to
>>> user space. This patch series add support for invoking TIOCMGET and
>>> TIOCMSET on these channels.
>>
>> I'm not familiar with this concept, that could explain that i don't
>> understand this patchset...
>>
>> TIOCMGET and TIOCMSET is related to the serial/console flow control, to
>> control remote modem/processor, right?
>>
>
> Correct, using the known tty ioctls for flow control we allow userspace
> to communicate flow control information to the rpmsg_char driver.
>
>> it seems be implemented only to support the rpmsg_char ioctl interface.
>> When i have a look to the glink code, signal is treated by a message
>> sent to remote processor. Therefore it seems that it could be treated as
>> a service on top of rpmsg (so treat it in rpmsg_char instead of extend
>> the rpmsg protocol to treat it in glink driver).
>>
>
> The glink message is a control message, so it's not possible to pass
> this inside a channel. As such it's not possible to solve this entirely
> in rpmsg_char.
>
> Looking at SMD, this is a set of bits in a per-channel control
> structure. So there it's clearer that it's some side-band control
> information.
>
>
> Further more, the rpmsg_char driver just exposes a channel to user
> space, it does not care about the data inside. As such it's not possible
> to generically extend it to support this with in-band messages.
>
>>>
>>> In addition to adding the client side of this to rpmsg_char it provides
>>> this support for glink, but the same mechanism exists in smd - while
>>> this is not supported (today) by the virtio rpmsg.
>> This is my main concern, i would like to be sure that this service is
>> not related to specific needs introduced by the rmpsg char implementation:
>> In this case this should not be part of the rpmsg core but perhaps some
>> ops directly provided to the rpmsg_char on registration
>> (rpmsg_chrdev_register_device?)...
>>
>
> Arun's imminent need is for a user space client that needs to flow
> control the incoming data stream. But the possibility of controlling the
> incoming flow of data is useful in a number of situations.
>
>>>
>>>
>>> I'm uncertain of how we could implement this mechanism for virtio rpmsg,
>>> given that it as a transport doesn't really have a concept of
>>> channels/flows - but it's really useful to have!
>>>
>>> PS. rpmsg_set_signals() can be called from any rpmsg device to perform
>>> flow control of the communication channel.
>>
>> For my point of view this patch-set extends the rpmsg protocol to add
>> channel flow control.
>> Does it make sense to have a flow control in rpmsg protocol?
>> if yes, should it be linked to a channel or to the remote processor itself?
>>
>
> Having per-channel flow control particularly useful in scenarios where
> one has multiple types of data flowing over a shared underlying FIFO -
> such as virtio rpmsg. As this allows these different applications to
> limit the data rate without having to use application specific side band
> controls.
Agree that per-channel flow control could be useful to give priorities
an limit data flow rate. And as discussed yesterday in Openamp meeting,
rpmsg seems the well place to add a kind of channel controller.
That's means than we should probably need a generic way to configure
flow control, not based on TTY ioctl protocol, but compatible with its
associated feature.
If you need a short term solution, perhaps, a first step could be to
define a more generic API, that would be bypassed to the rpmsg backend
driver...
From my POV, a blocking point in current patch is that rpmsg_set_signals
and rpmsg_get_signals create dependency between the client the back-end
driver in term of parameters. Both have to know the signification of
these parameters, that are not defined in the interface, but in user
ioctl API. This seems not suitable for non rpmsg_char client that would
use flow control.
Other concern is that the term "signals" seems too generic if it is
dedicated to flow control.
Regards,
Arnaud
>
>> Extra comment: associated documentation update is missing.
>>
>
> Good catch, we should have a section in Documentation/rpmsg.txt
> describing this mechanism.
>
> Regards,
> Bjorn
>
>> Regards,
>> Arnaud
>>
>>>
>>> Regards,
>>> Bjorn
>>>
>>>> Regards
>>>> Arnaud
>>>>
>>>>>
>>>>> Changes since v1:
>>>>> - Split the patches as per functional areas like core, char, glink
>>>>> - Add set, clear mask for TIOCMSET
>>>>> - Merge the char signal callback and POLLPRI patches
>>>>>
>>>>> Changes since v2:
>>>>> - Modify the rpmsg_get_signals function prototype
>>>>>
>>>>> Changes since v3:
>>>>> - Correct the TICOMGET case handling as per new rpmsg_get_signals prototype
>>>>> - Update the rpmsg_get_signals function header
>>>>>
>>>>> Arun Kumar Neelakantam (4):
>>>>> rpmsg: core: Add signal API support
>>>>> rpmsg: glink: Add support to handle signals command
>>>>> rpmsg: char: Add TIOCMGET/TIOCMSET ioctl support
>>>>> rpmsg: char: Add signal callback and POLLPRI support
>>>>>
>>>>> drivers/rpmsg/qcom_glink_native.c | 126 ++++++++++++++++++++++++++++++++++++++
>>>>> drivers/rpmsg/rpmsg_char.c | 74 +++++++++++++++++++++-
>>>>> drivers/rpmsg/rpmsg_core.c | 41 +++++++++++++
>>>>> drivers/rpmsg/rpmsg_internal.h | 5 ++
>>>>> include/linux/rpmsg.h | 26 ++++++++
>>>>> 5 files changed, 269 insertions(+), 3 deletions(-)
>>>>>