@@ -316,7 +316,7 @@ static long rpmsg_eptdev_ioctl(struct file *fp, unsigned int cmd,
if (ret)
break;
set = (val & TIOCM_DTR) ? true : false;
- ret = rpmsg_set_flow_control(eptdev->ept, set);
+ ret = rpmsg_set_flow_control(eptdev->ept, eptdev->chinfo.dst, set);
break;
case RPMSG_DESTROY_EPT_IOCTL:
/* Don't allow to destroy a default endpoint. */
@@ -357,18 +357,20 @@ EXPORT_SYMBOL(rpmsg_trysend_offchannel);
/**
* rpmsg_set_flow_control() - sets/clears serial flow control signals
* @ept: the rpmsg endpoint
+ * @dst: the remote endpoint destination addr, set to RPMSG_ADDR_ANY to send to the default
+ * remote endpoint associated to the rpmsg device.
* @enable: enable or disable serial flow control
*
* Return: 0 on success and an appropriate error value on failure.
*/
-int rpmsg_set_flow_control(struct rpmsg_endpoint *ept, bool enable)
+int rpmsg_set_flow_control(struct rpmsg_endpoint *ept, u32 dst, bool enable)
{
if (WARN_ON(!ept))
return -EINVAL;
if (!ept->ops->set_flow_control)
return -ENXIO;
- return ept->ops->set_flow_control(ept, enable);
+ return ept->ops->set_flow_control(ept, dst, enable);
}
EXPORT_SYMBOL(rpmsg_set_flow_control);
@@ -79,7 +79,7 @@ struct rpmsg_endpoint_ops {
void *data, int len);
__poll_t (*poll)(struct rpmsg_endpoint *ept, struct file *filp,
poll_table *wait);
- int (*set_flow_control)(struct rpmsg_endpoint *ept, bool enable);
+ int (*set_flow_control)(struct rpmsg_endpoint *ept, u32 dst, bool enable);
ssize_t (*get_mtu)(struct rpmsg_endpoint *ept);
};
@@ -154,7 +154,7 @@ static ssize_t virtio_rpmsg_get_mtu(struct rpmsg_endpoint *ept);
static struct rpmsg_device *__rpmsg_create_channel(struct virtproc_info *vrp,
struct rpmsg_channel_info *chinfo);
-static int virtio_rpmsg_set_flow_control(struct rpmsg_endpoint *ept, bool enable);
+static int virtio_rpmsg_set_flow_control(struct rpmsg_endpoint *ept, u32 dst, bool enable);
static const struct rpmsg_endpoint_ops virtio_endpoint_ops = {
.destroy_ept = virtio_rpmsg_destroy_ept,
@@ -748,7 +748,7 @@ static ssize_t virtio_rpmsg_get_mtu(struct rpmsg_endpoint *ept)
return vch->vrp->buf_size - sizeof(struct rpmsg_hdr);
}
-static int virtio_rpmsg_set_flow_control(struct rpmsg_endpoint *ept, bool enable)
+static int virtio_rpmsg_set_flow_control(struct rpmsg_endpoint *ept, u32 dst, bool enable)
{
struct rpmsg_device *rpdev;
struct virtio_rpmsg_channel *vch;
@@ -764,7 +764,7 @@ static int virtio_rpmsg_set_flow_control(struct rpmsg_endpoint *ept, bool enable
struct rpmsg_ept_msg msg;
msg.src = cpu_to_rpmsg32(rpdev, ept->addr);
- msg.dst = cpu_to_rpmsg32(rpdev, rpdev->dst);
+ msg.dst = cpu_to_rpmsg32(rpdev, dst == RPMSG_ADDR_ANY ? rpdev->dst : dst);
msg.flags = cpu_to_rpmsg32(rpdev, enable ? RPMSG_EPT_FC_ON : 0);
err = rpmsg_sendto(ept, &msg, sizeof(msg), RPMSG_FC_ADDR);
@@ -193,7 +193,7 @@ __poll_t rpmsg_poll(struct rpmsg_endpoint *ept, struct file *filp,
ssize_t rpmsg_get_mtu(struct rpmsg_endpoint *ept);
-int rpmsg_set_flow_control(struct rpmsg_endpoint *ept, bool enable);
+int rpmsg_set_flow_control(struct rpmsg_endpoint *ept, u32 dst, bool enable);
#else
@@ -313,7 +313,7 @@ static inline ssize_t rpmsg_get_mtu(struct rpmsg_endpoint *ept)
return -ENXIO;
}
-static inline int rpmsg_set_flow_control(struct rpmsg_endpoint *ept, bool enable)
+static inline int rpmsg_set_flow_control(struct rpmsg_endpoint *ept, u32 dst, bool enable)
{
/* This shouldn't be possible */
WARN_ON(1);
The destination address is not part of the rpmsg_endpoint structure. For static endpoint without channel, we need to specify the destination address for backend such as the rpmsg virtio. It is also needed for endpoint to multi endpoint communication. Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> --- drivers/rpmsg/rpmsg_char.c | 2 +- drivers/rpmsg/rpmsg_core.c | 6 ++++-- drivers/rpmsg/rpmsg_internal.h | 2 +- drivers/rpmsg/virtio_rpmsg_bus.c | 6 +++--- include/linux/rpmsg.h | 4 ++-- 5 files changed, 11 insertions(+), 9 deletions(-)