Add the capability for a rpmsg local endpoint to receive information of a remote endpoint state using the flow control channel. The virtio_rpmsg_remote_flowctrl function calls the endpoint which matches with the chinfo. Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@xxxxxxxxxxx> --- drivers/rpmsg/virtio_rpmsg_bus.c | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 0db8043e6c49..785fda77984e 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -305,6 +305,7 @@ __rpmsg_destroy_ept(struct virtproc_info *vrp, struct rpmsg_endpoint *ept) /* make sure in-flight inbound messages won't invoke cb anymore */ mutex_lock(&ept->cb_lock); ept->cb = NULL; + ept->sig_cb = NULL; mutex_unlock(&ept->cb_lock); kref_put(&ept->refcount, __ept_release); @@ -365,12 +366,49 @@ static int virtio_rpmsg_announce_destroy(struct rpmsg_device *rpdev) return err; } +static int virtio_rpmsg_remote_flowctrl(struct rpmsg_device *rpdev, + struct rpmsg_channel_info *chinfo, + bool enable) +{ + struct virtio_rpmsg_channel *vch = to_virtio_rpmsg_channel(rpdev); + struct virtproc_info *vrp = vch->vrp; + struct rpmsg_endpoint *ept; + + /* Use the dst addr to fetch the callback of the appropriate user */ + mutex_lock(&vrp->endpoints_lock); + + ept = idr_find(&vrp->endpoints, chinfo->dst); + + /* Let's make sure no one deallocates ept while we use it */ + if (ept) + kref_get(&ept->refcount); + + mutex_unlock(&vrp->endpoints_lock); + + if (!ept) + return -EINVAL; + + /* Make sure ept->sig_cb doesn't go away while we use it */ + mutex_lock(&ept->cb_lock); + + if (ept->sig_cb) + ept->sig_cb(ept->rpdev, ept->priv, enable); + + mutex_unlock(&ept->cb_lock); + + /* Farewell, ept, we don't need you anymore */ + kref_put(&ept->refcount, __ept_release); + + return 0; +} + static const struct rpmsg_device_ops virtio_rpmsg_ops = { .create_channel = virtio_rpmsg_create_channel, .release_channel = virtio_rpmsg_release_channel, .create_ept = virtio_rpmsg_create_ept, .announce_create = virtio_rpmsg_announce_create, .announce_destroy = virtio_rpmsg_announce_destroy, + .announce_remote_fc = virtio_rpmsg_remote_flowctrl, }; static void virtio_rpmsg_release_device(struct device *dev) -- 2.25.1