]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/remoteproc/remoteproc_virtio.c
remoteproc: maintain a generic child device for each rproc
[mirror_ubuntu-artful-kernel.git] / drivers / remoteproc / remoteproc_virtio.c
index ecf61213075069cd5719da4bfe2536bd9abf0aa1..b6621831a58aafa28eb62d79c1f18dda1a326a01 100644 (file)
@@ -36,7 +36,7 @@ static void rproc_virtio_notify(struct virtqueue *vq)
        struct rproc *rproc = rvring->rvdev->rproc;
        int notifyid = rvring->notifyid;
 
-       dev_dbg(rproc->dev, "kicking vq index: %d\n", notifyid);
+       dev_dbg(&rproc->dev, "kicking vq index: %d\n", notifyid);
 
        rproc->ops->kick(rproc, notifyid);
 }
@@ -57,7 +57,7 @@ irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int notifyid)
 {
        struct rproc_vring *rvring;
 
-       dev_dbg(rproc->dev, "vq index %d is interrupted\n", notifyid);
+       dev_dbg(&rproc->dev, "vq index %d is interrupted\n", notifyid);
 
        rvring = idr_find(&rproc->notifyids, notifyid);
        if (!rvring || !rvring->vq)
@@ -74,17 +74,21 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
 {
        struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
        struct rproc *rproc = vdev_to_rproc(vdev);
+       struct device *dev = &rproc->dev;
        struct rproc_vring *rvring;
        struct virtqueue *vq;
        void *addr;
-       int len, size;
+       int len, size, ret;
 
        /* we're temporarily limited to two virtqueues per rvdev */
        if (id >= ARRAY_SIZE(rvdev->vring))
                return ERR_PTR(-EINVAL);
 
-       rvring = &rvdev->vring[id];
+       ret = rproc_alloc_vring(rvdev, id);
+       if (ret)
+               return ERR_PTR(ret);
 
+       rvring = &rvdev->vring[id];
        addr = rvring->va;
        len = rvring->len;
 
@@ -92,7 +96,7 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
        size = vring_size(len, rvring->align);
        memset(addr, 0, size);
 
-       dev_dbg(rproc->dev, "vring%d: va %p qsz %d notifyid %d\n",
+       dev_dbg(dev, "vring%d: va %p qsz %d notifyid %d\n",
                                        id, addr, len, rvring->notifyid);
 
        /*
@@ -102,7 +106,8 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
        vq = vring_new_virtqueue(len, rvring->align, vdev, false, addr,
                                        rproc_virtio_notify, callback, name);
        if (!vq) {
-               dev_err(rproc->dev, "vring_new_virtqueue %s failed\n", name);
+               dev_err(dev, "vring_new_virtqueue %s failed\n", name);
+               rproc_free_vring(rvring);
                return ERR_PTR(-ENOMEM);
        }
 
@@ -125,6 +130,7 @@ static void rproc_virtio_del_vqs(struct virtio_device *vdev)
                rvring = vq->priv;
                rvring->vq = NULL;
                vring_del_virtqueue(vq);
+               rproc_free_vring(rvring);
        }
 }
 
@@ -147,7 +153,7 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
        /* now that the vqs are all set, boot the remote processor */
        ret = rproc_boot(rproc);
        if (ret) {
-               dev_err(rproc->dev, "rproc_boot() failed %d\n", ret);
+               dev_err(&rproc->dev, "rproc_boot() failed %d\n", ret);
                goto error;
        }
 
@@ -228,8 +234,12 @@ static struct virtio_config_ops rproc_virtio_config_ops = {
 static void rproc_vdev_release(struct device *dev)
 {
        struct virtio_device *vdev = dev_to_virtio(dev);
+       struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
        struct rproc *rproc = vdev_to_rproc(vdev);
 
+       list_del(&rvdev->node);
+       kfree(rvdev);
+
        kref_put(&rproc->refcount, rproc_release);
 }
 
@@ -245,7 +255,7 @@ static void rproc_vdev_release(struct device *dev)
 int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
 {
        struct rproc *rproc = rvdev->rproc;
-       struct device *dev = rproc->dev;
+       struct device *dev = &rproc->dev;
        struct virtio_device *vdev = &rvdev->vdev;
        int ret;