Add the capability for a rpmsg local endpoint to informs the remote of its state using the flow control channel. If the feature is not supported by the remote processor, no message is sent. Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@xxxxxxxxxxx> --- drivers/rpmsg/virtio_rpmsg_bus.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 40d2ab86b395..96bd12095c8c 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -154,6 +154,8 @@ 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 const struct rpmsg_endpoint_ops virtio_endpoint_ops = { .destroy_ept = virtio_rpmsg_destroy_ept, .send = virtio_rpmsg_send, @@ -163,6 +165,7 @@ static const struct rpmsg_endpoint_ops virtio_endpoint_ops = { .trysendto = virtio_rpmsg_trysendto, .trysend_offchannel = virtio_rpmsg_trysend_offchannel, .get_mtu = virtio_rpmsg_get_mtu, + .set_flow_control = virtio_rpmsg_set_flow_control, }; /** @@ -745,6 +748,34 @@ 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) +{ + struct rpmsg_device *rpdev; + struct virtio_rpmsg_channel *vch; + int err = 0; + + if (!ept) + return -EINVAL; + + rpdev = ept->rpdev; + vch = to_virtio_rpmsg_channel(rpdev); + + if (virtio_has_feature(vch->vrp->vdev, VIRTIO_RPMSG_F_FC)) { + struct rpmsg_ept_msg msg; + + msg.src = cpu_to_rpmsg32(rpdev, ept->addr); + msg.dst = cpu_to_rpmsg32(rpdev, rpdev->dst); + msg.flags = cpu_to_rpmsg32(rpdev, enable ? RPMSG_EPT_FC_ON : 0); + + err = rpmsg_sendto(ept, &msg, sizeof(msg), RPMSG_FC_ADDR); + if (err) + dev_err(&rpdev->dev, "Failed to set endpoint 0x%x state %sable (%d)\n", + ept->addr, enable ? "en" : "dis", err); + } + + return err; +} + static int rpmsg_recv_single(struct virtproc_info *vrp, struct device *dev, struct rpmsg_hdr *msg, unsigned int len) { -- 2.25.1