Probe the rpmsg_ctl driver on virtio rpmsg bus creation. This provides the possibility to expose an ioctrl to create RPMsg channels. Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@xxxxxxxxxxx> --- drivers/rpmsg/virtio_rpmsg_bus.c | 37 +++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index c1d4bc08b2a5..e8caccb2d298 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -814,6 +814,35 @@ static void rpmsg_xmit_done(struct virtqueue *svq) wake_up_interruptible(&vrp->sendq); } +static struct rpmsg_device *rpmsg_virtio_add_char_dev(struct virtio_device *vdev) +{ + struct virtproc_info *vrp = vdev->priv; + struct virtio_rpmsg_channel *vch; + struct rpmsg_device *rpdev_ctrl; + int err = 0; + + vch = kzalloc(sizeof(*vch), GFP_KERNEL); + if (!vch) + return ERR_PTR(-ENOMEM); + + /* Link the channel to our vrp */ + vch->vrp = vrp; + + /* Assign public information to the rpmsg_device */ + rpdev_ctrl = &vch->rpdev; + rpdev_ctrl->ops = &virtio_rpmsg_ops; + + rpdev_ctrl->dev.parent = &vrp->vdev->dev; + rpdev_ctrl->dev.release = virtio_rpmsg_release_device; + rpdev_ctrl->little_endian = virtio_is_little_endian(vrp->vdev); + + err = rpmsg_ctl_register_device(rpdev_ctrl); + if (err) + return ERR_PTR(err); + + return rpdev_ctrl; +} + static int rpmsg_probe(struct virtio_device *vdev) { vq_callback_t *vq_cbs[] = { rpmsg_recv_done, rpmsg_xmit_done }; @@ -821,7 +850,7 @@ static int rpmsg_probe(struct virtio_device *vdev) struct virtqueue *vqs[2]; struct virtproc_info *vrp; struct virtio_rpmsg_channel *vch; - struct rpmsg_device *rpdev_ns; + struct rpmsg_device *rpdev_ns, *rpdev_ctrl; void *bufs_va; int err = 0, i; size_t total_buf_space; @@ -919,6 +948,11 @@ static int rpmsg_probe(struct virtio_device *vdev) goto free_coherent; } + rpdev_ctrl = rpmsg_virtio_add_char_dev(vdev); + if (IS_ERR(rpdev_ctrl)) { + err = PTR_ERR(rpdev_ctrl); + goto free_coherent; + } /* * Prepare to kick but don't notify yet - we can't do this before * device is ready. @@ -942,6 +976,7 @@ static int rpmsg_probe(struct virtio_device *vdev) free_coherent: kfree(vch); + kfree(to_virtio_rpmsg_channel(rpdev_ctrl)); dma_free_coherent(vdev->dev.parent, total_buf_space, bufs_va, vrp->bufs_dma); vqs_del: -- 2.17.1