aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/remoteproc/remoteproc_virtio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/remoteproc/remoteproc_virtio.c')
-rw-r--r--drivers/remoteproc/remoteproc_virtio.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
index ecf612130750..3541b4492f64 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -36,7 +36,7 @@ static void rproc_virtio_notify(struct virtqueue *vq)
36 struct rproc *rproc = rvring->rvdev->rproc; 36 struct rproc *rproc = rvring->rvdev->rproc;
37 int notifyid = rvring->notifyid; 37 int notifyid = rvring->notifyid;
38 38
39 dev_dbg(rproc->dev, "kicking vq index: %d\n", notifyid); 39 dev_dbg(&rproc->dev, "kicking vq index: %d\n", notifyid);
40 40
41 rproc->ops->kick(rproc, notifyid); 41 rproc->ops->kick(rproc, notifyid);
42} 42}
@@ -57,7 +57,7 @@ irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int notifyid)
57{ 57{
58 struct rproc_vring *rvring; 58 struct rproc_vring *rvring;
59 59
60 dev_dbg(rproc->dev, "vq index %d is interrupted\n", notifyid); 60 dev_dbg(&rproc->dev, "vq index %d is interrupted\n", notifyid);
61 61
62 rvring = idr_find(&rproc->notifyids, notifyid); 62 rvring = idr_find(&rproc->notifyids, notifyid);
63 if (!rvring || !rvring->vq) 63 if (!rvring || !rvring->vq)
@@ -74,17 +74,21 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
74{ 74{
75 struct rproc_vdev *rvdev = vdev_to_rvdev(vdev); 75 struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
76 struct rproc *rproc = vdev_to_rproc(vdev); 76 struct rproc *rproc = vdev_to_rproc(vdev);
77 struct device *dev = &rproc->dev;
77 struct rproc_vring *rvring; 78 struct rproc_vring *rvring;
78 struct virtqueue *vq; 79 struct virtqueue *vq;
79 void *addr; 80 void *addr;
80 int len, size; 81 int len, size, ret;
81 82
82 /* we're temporarily limited to two virtqueues per rvdev */ 83 /* we're temporarily limited to two virtqueues per rvdev */
83 if (id >= ARRAY_SIZE(rvdev->vring)) 84 if (id >= ARRAY_SIZE(rvdev->vring))
84 return ERR_PTR(-EINVAL); 85 return ERR_PTR(-EINVAL);
85 86
86 rvring = &rvdev->vring[id]; 87 ret = rproc_alloc_vring(rvdev, id);
88 if (ret)
89 return ERR_PTR(ret);
87 90
91 rvring = &rvdev->vring[id];
88 addr = rvring->va; 92 addr = rvring->va;
89 len = rvring->len; 93 len = rvring->len;
90 94
@@ -92,7 +96,7 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
92 size = vring_size(len, rvring->align); 96 size = vring_size(len, rvring->align);
93 memset(addr, 0, size); 97 memset(addr, 0, size);
94 98
95 dev_dbg(rproc->dev, "vring%d: va %p qsz %d notifyid %d\n", 99 dev_dbg(dev, "vring%d: va %p qsz %d notifyid %d\n",
96 id, addr, len, rvring->notifyid); 100 id, addr, len, rvring->notifyid);
97 101
98 /* 102 /*
@@ -102,7 +106,8 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
102 vq = vring_new_virtqueue(len, rvring->align, vdev, false, addr, 106 vq = vring_new_virtqueue(len, rvring->align, vdev, false, addr,
103 rproc_virtio_notify, callback, name); 107 rproc_virtio_notify, callback, name);
104 if (!vq) { 108 if (!vq) {
105 dev_err(rproc->dev, "vring_new_virtqueue %s failed\n", name); 109 dev_err(dev, "vring_new_virtqueue %s failed\n", name);
110 rproc_free_vring(rvring);
106 return ERR_PTR(-ENOMEM); 111 return ERR_PTR(-ENOMEM);
107 } 112 }
108 113
@@ -125,6 +130,7 @@ static void rproc_virtio_del_vqs(struct virtio_device *vdev)
125 rvring = vq->priv; 130 rvring = vq->priv;
126 rvring->vq = NULL; 131 rvring->vq = NULL;
127 vring_del_virtqueue(vq); 132 vring_del_virtqueue(vq);
133 rproc_free_vring(rvring);
128 } 134 }
129} 135}
130 136
@@ -147,7 +153,7 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
147 /* now that the vqs are all set, boot the remote processor */ 153 /* now that the vqs are all set, boot the remote processor */
148 ret = rproc_boot(rproc); 154 ret = rproc_boot(rproc);
149 if (ret) { 155 if (ret) {
150 dev_err(rproc->dev, "rproc_boot() failed %d\n", ret); 156 dev_err(&rproc->dev, "rproc_boot() failed %d\n", ret);
151 goto error; 157 goto error;
152 } 158 }
153 159
@@ -219,7 +225,7 @@ static struct virtio_config_ops rproc_virtio_config_ops = {
219 225
220/* 226/*
221 * This function is called whenever vdev is released, and is responsible 227 * This function is called whenever vdev is released, and is responsible
222 * to decrement the remote processor's refcount taken when vdev was 228 * to decrement the remote processor's refcount which was taken when vdev was
223 * added. 229 * added.
224 * 230 *
225 * Never call this function directly; it will be called by the driver 231 * Never call this function directly; it will be called by the driver
@@ -228,9 +234,13 @@ static struct virtio_config_ops rproc_virtio_config_ops = {
228static void rproc_vdev_release(struct device *dev) 234static void rproc_vdev_release(struct device *dev)
229{ 235{
230 struct virtio_device *vdev = dev_to_virtio(dev); 236 struct virtio_device *vdev = dev_to_virtio(dev);
237 struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
231 struct rproc *rproc = vdev_to_rproc(vdev); 238 struct rproc *rproc = vdev_to_rproc(vdev);
232 239
233 kref_put(&rproc->refcount, rproc_release); 240 list_del(&rvdev->node);
241 kfree(rvdev);
242
243 put_device(&rproc->dev);
234} 244}
235 245
236/** 246/**
@@ -245,7 +255,7 @@ static void rproc_vdev_release(struct device *dev)
245int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id) 255int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
246{ 256{
247 struct rproc *rproc = rvdev->rproc; 257 struct rproc *rproc = rvdev->rproc;
248 struct device *dev = rproc->dev; 258 struct device *dev = &rproc->dev;
249 struct virtio_device *vdev = &rvdev->vdev; 259 struct virtio_device *vdev = &rvdev->vdev;
250 int ret; 260 int ret;
251 261
@@ -262,11 +272,11 @@ int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
262 * Therefore we must increment the rproc refcount here, and decrement 272 * Therefore we must increment the rproc refcount here, and decrement
263 * it _only_ when the vdev is released. 273 * it _only_ when the vdev is released.
264 */ 274 */
265 kref_get(&rproc->refcount); 275 get_device(&rproc->dev);
266 276
267 ret = register_virtio_device(vdev); 277 ret = register_virtio_device(vdev);
268 if (ret) { 278 if (ret) {
269 kref_put(&rproc->refcount, rproc_release); 279 put_device(&rproc->dev);
270 dev_err(dev, "failed to register vdev: %d\n", ret); 280 dev_err(dev, "failed to register vdev: %d\n", ret);
271 goto out; 281 goto out;
272 } 282 }