Skip to content

Commit 8ce49c2

Browse files
quic-deesinandersson
authored andcommitted
rpmsg: core: Add signal API support
Some transports like Glink support the state notifications between clients using flow control signals similar to serial protocol signals. Local glink client drivers can send and receive flow control status to glink clients running on remote processors. Add APIs to support sending and receiving of flow control status by rpmsg clients. 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-2-git-send-email-quic_sarannya@quicinc.com Signed-off-by: Bjorn Andersson <andersson@kernel.org>
1 parent 06c2afb commit 8ce49c2

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

drivers/rpmsg/rpmsg_core.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,25 @@ int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept, u32 src, u32 dst,
330330
}
331331
EXPORT_SYMBOL(rpmsg_trysend_offchannel);
332332

333+
/**
334+
* rpmsg_set_flow_control() - request remote to pause/resume transmission
335+
* @ept: the rpmsg endpoint
336+
* @pause: pause transmission
337+
* @dst: destination address of the endpoint
338+
*
339+
* Return: 0 on success and an appropriate error value on failure.
340+
*/
341+
int rpmsg_set_flow_control(struct rpmsg_endpoint *ept, bool pause, u32 dst)
342+
{
343+
if (WARN_ON(!ept))
344+
return -EINVAL;
345+
if (!ept->ops->set_flow_control)
346+
return -EOPNOTSUPP;
347+
348+
return ept->ops->set_flow_control(ept, pause, dst);
349+
}
350+
EXPORT_SYMBOL_GPL(rpmsg_set_flow_control);
351+
333352
/**
334353
* rpmsg_get_mtu() - get maximum transmission buffer size for sending message.
335354
* @ept: the rpmsg endpoint
@@ -539,6 +558,8 @@ static int rpmsg_dev_probe(struct device *dev)
539558

540559
rpdev->ept = ept;
541560
rpdev->src = ept->addr;
561+
562+
ept->flow_cb = rpdrv->flowcontrol;
542563
}
543564

544565
err = rpdrv->probe(rpdev);

drivers/rpmsg/rpmsg_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct rpmsg_device_ops {
5555
* @trysendto: see @rpmsg_trysendto(), optional
5656
* @trysend_offchannel: see @rpmsg_trysend_offchannel(), optional
5757
* @poll: see @rpmsg_poll(), optional
58+
* @set_flow_control: see @rpmsg_set_flow_control(), optional
5859
* @get_mtu: see @rpmsg_get_mtu(), optional
5960
*
6061
* Indirection table for the operations that a rpmsg backend should implement.
@@ -75,6 +76,7 @@ struct rpmsg_endpoint_ops {
7576
void *data, int len);
7677
__poll_t (*poll)(struct rpmsg_endpoint *ept, struct file *filp,
7778
poll_table *wait);
79+
int (*set_flow_control)(struct rpmsg_endpoint *ept, bool pause, u32 dst);
7880
ssize_t (*get_mtu)(struct rpmsg_endpoint *ept);
7981
};
8082

include/linux/rpmsg.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,14 @@ struct rpmsg_device {
6464
};
6565

6666
typedef int (*rpmsg_rx_cb_t)(struct rpmsg_device *, void *, int, void *, u32);
67+
typedef int (*rpmsg_flowcontrol_cb_t)(struct rpmsg_device *, void *, bool);
6768

6869
/**
6970
* struct rpmsg_endpoint - binds a local rpmsg address to its user
7071
* @rpdev: rpmsg channel device
7172
* @refcount: when this drops to zero, the ept is deallocated
7273
* @cb: rx callback handler
74+
* @flow_cb: remote flow control callback handler
7375
* @cb_lock: must be taken before accessing/changing @cb
7476
* @addr: local rpmsg address
7577
* @priv: private data for the driver's use
@@ -92,6 +94,7 @@ struct rpmsg_endpoint {
9294
struct rpmsg_device *rpdev;
9395
struct kref refcount;
9496
rpmsg_rx_cb_t cb;
97+
rpmsg_flowcontrol_cb_t flow_cb;
9598
struct mutex cb_lock;
9699
u32 addr;
97100
void *priv;
@@ -106,13 +109,15 @@ struct rpmsg_endpoint {
106109
* @probe: invoked when a matching rpmsg channel (i.e. device) is found
107110
* @remove: invoked when the rpmsg channel is removed
108111
* @callback: invoked when an inbound message is received on the channel
112+
* @flowcontrol: invoked when remote side flow control request is received
109113
*/
110114
struct rpmsg_driver {
111115
struct device_driver drv;
112116
const struct rpmsg_device_id *id_table;
113117
int (*probe)(struct rpmsg_device *dev);
114118
void (*remove)(struct rpmsg_device *dev);
115119
int (*callback)(struct rpmsg_device *, void *, int, void *, u32);
120+
int (*flowcontrol)(struct rpmsg_device *, void *, bool);
116121
};
117122

118123
static inline u16 rpmsg16_to_cpu(struct rpmsg_device *rpdev, __rpmsg16 val)
@@ -192,6 +197,8 @@ __poll_t rpmsg_poll(struct rpmsg_endpoint *ept, struct file *filp,
192197

193198
ssize_t rpmsg_get_mtu(struct rpmsg_endpoint *ept);
194199

200+
int rpmsg_set_flow_control(struct rpmsg_endpoint *ept, bool pause, u32 dst);
201+
195202
#else
196203

197204
static inline int rpmsg_register_device_override(struct rpmsg_device *rpdev,
@@ -316,6 +323,14 @@ static inline ssize_t rpmsg_get_mtu(struct rpmsg_endpoint *ept)
316323
return -ENXIO;
317324
}
318325

326+
static inline int rpmsg_set_flow_control(struct rpmsg_endpoint *ept, bool pause, u32 dst)
327+
{
328+
/* This shouldn't be possible */
329+
WARN_ON(1);
330+
331+
return -ENXIO;
332+
}
333+
319334
#endif /* IS_ENABLED(CONFIG_RPMSG) */
320335

321336
/* use a macro to avoid include chaining to get THIS_MODULE */

0 commit comments

Comments
 (0)