diff options
Diffstat (limited to 'drivers/remoteproc/remoteproc_virtio.c')
-rw-r--r-- | drivers/remoteproc/remoteproc_virtio.c | 34 |
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 = { | |||
228 | static void rproc_vdev_release(struct device *dev) | 234 | static 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) | |||
245 | int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id) | 255 | int 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 | } |