Skip to content

Commit 5550201

Browse files
quic-clewandersson
authored andcommitted
rpmsg: char: Add RPMSG GET/SET FLOWCONTROL IOCTL support
Add RPMSG_GET_OUTGOING_FLOWCONTROL and RPMSG_SET_INCOMING_FLOWCONTROL IOCTL support for rpmsg char device nodes to get/set the low level transport signals. Signed-off-by: Chris Lew <quic_clew@quicinc.com> Signed-off-by: Deepak Kumar Singh <quic_deesin@quicinc.com> Signed-off-by: Sarannya S <quic_sarannya@quicinc.com> Acked-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> Link: https://lore.kernel.org/r/1688679698-31274-4-git-send-email-quic_sarannya@quicinc.com Signed-off-by: Bjorn Andersson <andersson@kernel.org>
1 parent a2b73aa commit 5550201

File tree

2 files changed

+58
-6
lines changed

2 files changed

+58
-6
lines changed

drivers/rpmsg/rpmsg_char.c

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ static DEFINE_IDA(rpmsg_minor_ida);
5252
* @readq: wait object for incoming queue
5353
* @default_ept: set to channel default endpoint if the default endpoint should be re-used
5454
* on device open to prevent endpoint address update.
55+
* remote_flow_restricted: to indicate if the remote has requested for flow to be limited
56+
* remote_flow_updated: to indicate if the flow control has been requested
5557
*/
5658
struct rpmsg_eptdev {
5759
struct device dev;
@@ -68,6 +70,8 @@ struct rpmsg_eptdev {
6870
struct sk_buff_head queue;
6971
wait_queue_head_t readq;
7072

73+
bool remote_flow_restricted;
74+
bool remote_flow_updated;
7175
};
7276

7377
int rpmsg_chrdev_eptdev_destroy(struct device *dev, void *data)
@@ -116,6 +120,18 @@ static int rpmsg_ept_cb(struct rpmsg_device *rpdev, void *buf, int len,
116120
return 0;
117121
}
118122

123+
static int rpmsg_ept_flow_cb(struct rpmsg_device *rpdev, void *priv, bool enable)
124+
{
125+
struct rpmsg_eptdev *eptdev = priv;
126+
127+
eptdev->remote_flow_restricted = enable;
128+
eptdev->remote_flow_updated = true;
129+
130+
wake_up_interruptible(&eptdev->readq);
131+
132+
return 0;
133+
}
134+
119135
static int rpmsg_eptdev_open(struct inode *inode, struct file *filp)
120136
{
121137
struct rpmsg_eptdev *eptdev = cdev_to_eptdev(inode->i_cdev);
@@ -152,6 +168,7 @@ static int rpmsg_eptdev_open(struct inode *inode, struct file *filp)
152168
return -EINVAL;
153169
}
154170

171+
ept->flow_cb = rpmsg_ept_flow_cb;
155172
eptdev->ept = ept;
156173
filp->private_data = eptdev;
157174
mutex_unlock(&eptdev->ept_lock);
@@ -172,6 +189,7 @@ static int rpmsg_eptdev_release(struct inode *inode, struct file *filp)
172189
eptdev->ept = NULL;
173190
}
174191
mutex_unlock(&eptdev->ept_lock);
192+
eptdev->remote_flow_updated = false;
175193

176194
/* Discard all SKBs */
177195
skb_queue_purge(&eptdev->queue);
@@ -285,6 +303,9 @@ static __poll_t rpmsg_eptdev_poll(struct file *filp, poll_table *wait)
285303
if (!skb_queue_empty(&eptdev->queue))
286304
mask |= EPOLLIN | EPOLLRDNORM;
287305

306+
if (eptdev->remote_flow_updated)
307+
mask |= EPOLLPRI;
308+
288309
mutex_lock(&eptdev->ept_lock);
289310
mask |= rpmsg_poll(eptdev->ept, filp, wait);
290311
mutex_unlock(&eptdev->ept_lock);
@@ -297,14 +318,35 @@ static long rpmsg_eptdev_ioctl(struct file *fp, unsigned int cmd,
297318
{
298319
struct rpmsg_eptdev *eptdev = fp->private_data;
299320

300-
if (cmd != RPMSG_DESTROY_EPT_IOCTL)
301-
return -EINVAL;
321+
bool set;
322+
int ret;
302323

303-
/* Don't allow to destroy a default endpoint. */
304-
if (eptdev->default_ept)
305-
return -EINVAL;
324+
switch (cmd) {
325+
case RPMSG_GET_OUTGOING_FLOWCONTROL:
326+
eptdev->remote_flow_updated = false;
327+
ret = put_user(eptdev->remote_flow_restricted, (int __user *)arg);
328+
break;
329+
case RPMSG_SET_INCOMING_FLOWCONTROL:
330+
if (arg > 1) {
331+
ret = -EINVAL;
332+
break;
333+
}
334+
set = !!arg;
335+
ret = rpmsg_set_flow_control(eptdev->ept, set, eptdev->chinfo.dst);
336+
break;
337+
case RPMSG_DESTROY_EPT_IOCTL:
338+
/* Don't allow to destroy a default endpoint. */
339+
if (eptdev->default_ept) {
340+
ret = -EINVAL;
341+
break;
342+
}
343+
ret = rpmsg_chrdev_eptdev_destroy(&eptdev->dev, NULL);
344+
break;
345+
default:
346+
ret = -EINVAL;
347+
}
306348

307-
return rpmsg_chrdev_eptdev_destroy(&eptdev->dev, NULL);
349+
return ret;
308350
}
309351

310352
static const struct file_operations rpmsg_eptdev_fops = {

include/uapi/linux/rpmsg.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,14 @@ struct rpmsg_endpoint_info {
4343
*/
4444
#define RPMSG_RELEASE_DEV_IOCTL _IOW(0xb5, 0x4, struct rpmsg_endpoint_info)
4545

46+
/**
47+
* Get the flow control state of the remote rpmsg char device.
48+
*/
49+
#define RPMSG_GET_OUTGOING_FLOWCONTROL _IOR(0xb5, 0x5, int)
50+
51+
/**
52+
* Set the flow control state of the local rpmsg char device.
53+
*/
54+
#define RPMSG_SET_INCOMING_FLOWCONTROL _IOR(0xb5, 0x6, int)
55+
4656
#endif

0 commit comments

Comments
 (0)