diff options
author | Bjorn Andersson <bjorn.andersson@linaro.org> | 2016-10-19 22:40:09 -0400 |
---|---|---|
committer | Bjorn Andersson <bjorn.andersson@linaro.org> | 2016-11-15 00:52:17 -0500 |
commit | f5bcb35387efc994cfd88f87039d7cdb6c1a06a2 (patch) | |
tree | aff942879db6443d15176992cdeedf6f310c0b8f | |
parent | 2b45cef5868a9ad012121f4f7f11c700bfb7f2e4 (diff) |
remoteproc: Decouple vdev resources and devices
Represent the virtio device part of the vdev resources as remoteproc
subdevices to finalize the decoupling of the virtio resource and device
handling.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
-rw-r--r-- | drivers/remoteproc/remoteproc_core.c | 35 | ||||
-rw-r--r-- | include/linux/remoteproc.h | 5 |
2 files changed, 25 insertions, 15 deletions
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 62de765a9498..57c66397f31f 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c | |||
@@ -296,6 +296,20 @@ void rproc_free_vring(struct rproc_vring *rvring) | |||
296 | rsc->vring[idx].notifyid = -1; | 296 | rsc->vring[idx].notifyid = -1; |
297 | } | 297 | } |
298 | 298 | ||
299 | static int rproc_vdev_do_probe(struct rproc_subdev *subdev) | ||
300 | { | ||
301 | struct rproc_vdev *rvdev = container_of(subdev, struct rproc_vdev, subdev); | ||
302 | |||
303 | return rproc_add_virtio_dev(rvdev, rvdev->id); | ||
304 | } | ||
305 | |||
306 | static void rproc_vdev_do_remove(struct rproc_subdev *subdev) | ||
307 | { | ||
308 | struct rproc_vdev *rvdev = container_of(subdev, struct rproc_vdev, subdev); | ||
309 | |||
310 | rproc_remove_virtio_dev(rvdev); | ||
311 | } | ||
312 | |||
299 | /** | 313 | /** |
300 | * rproc_handle_vdev() - handle a vdev fw resource | 314 | * rproc_handle_vdev() - handle a vdev fw resource |
301 | * @rproc: the remote processor | 315 | * @rproc: the remote processor |
@@ -358,6 +372,7 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc, | |||
358 | 372 | ||
359 | kref_init(&rvdev->refcount); | 373 | kref_init(&rvdev->refcount); |
360 | 374 | ||
375 | rvdev->id = rsc->id; | ||
361 | rvdev->rproc = rproc; | 376 | rvdev->rproc = rproc; |
362 | 377 | ||
363 | /* parse the vrings */ | 378 | /* parse the vrings */ |
@@ -382,18 +397,14 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc, | |||
382 | 397 | ||
383 | list_add_tail(&rvdev->node, &rproc->rvdevs); | 398 | list_add_tail(&rvdev->node, &rproc->rvdevs); |
384 | 399 | ||
385 | /* it is now safe to add the virtio device */ | 400 | rproc_add_subdev(rproc, &rvdev->subdev, |
386 | ret = rproc_add_virtio_dev(rvdev, rsc->id); | 401 | rproc_vdev_do_probe, rproc_vdev_do_remove); |
387 | if (ret) | ||
388 | goto remove_rvdev; | ||
389 | 402 | ||
390 | return 0; | 403 | return 0; |
391 | 404 | ||
392 | unwind_vring_allocations: | 405 | unwind_vring_allocations: |
393 | for (i--; i >= 0; i--) | 406 | for (i--; i >= 0; i--) |
394 | rproc_free_vring(&rvdev->vring[i]); | 407 | rproc_free_vring(&rvdev->vring[i]); |
395 | remove_rvdev: | ||
396 | list_del(&rvdev->node); | ||
397 | free_rvdev: | 408 | free_rvdev: |
398 | kfree(rvdev); | 409 | kfree(rvdev); |
399 | return ret; | 410 | return ret; |
@@ -403,6 +414,7 @@ void rproc_vdev_release(struct kref *ref) | |||
403 | { | 414 | { |
404 | struct rproc_vdev *rvdev = container_of(ref, struct rproc_vdev, refcount); | 415 | struct rproc_vdev *rvdev = container_of(ref, struct rproc_vdev, refcount); |
405 | struct rproc_vring *rvring; | 416 | struct rproc_vring *rvring; |
417 | struct rproc *rproc = rvdev->rproc; | ||
406 | int id; | 418 | int id; |
407 | 419 | ||
408 | for (id = 0; id < ARRAY_SIZE(rvdev->vring); id++) { | 420 | for (id = 0; id < ARRAY_SIZE(rvdev->vring); id++) { |
@@ -413,6 +425,7 @@ void rproc_vdev_release(struct kref *ref) | |||
413 | rproc_free_vring(rvring); | 425 | rproc_free_vring(rvring); |
414 | } | 426 | } |
415 | 427 | ||
428 | rproc_remove_subdev(rproc, &rvdev->subdev); | ||
416 | list_del(&rvdev->node); | 429 | list_del(&rvdev->node); |
417 | kfree(rvdev); | 430 | kfree(rvdev); |
418 | } | 431 | } |
@@ -842,10 +855,8 @@ static void rproc_resource_cleanup(struct rproc *rproc) | |||
842 | } | 855 | } |
843 | 856 | ||
844 | /* clean up remote vdev entries */ | 857 | /* clean up remote vdev entries */ |
845 | list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node) { | 858 | list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node) |
846 | rproc_remove_virtio_dev(rvdev); | ||
847 | kref_put(&rvdev->refcount, rproc_vdev_release); | 859 | kref_put(&rvdev->refcount, rproc_vdev_release); |
848 | } | ||
849 | } | 860 | } |
850 | 861 | ||
851 | /* | 862 | /* |
@@ -1507,8 +1518,6 @@ EXPORT_SYMBOL(rproc_put); | |||
1507 | */ | 1518 | */ |
1508 | int rproc_del(struct rproc *rproc) | 1519 | int rproc_del(struct rproc *rproc) |
1509 | { | 1520 | { |
1510 | struct rproc_vdev *rvdev, *tmp; | ||
1511 | |||
1512 | if (!rproc) | 1521 | if (!rproc) |
1513 | return -EINVAL; | 1522 | return -EINVAL; |
1514 | 1523 | ||
@@ -1520,10 +1529,6 @@ int rproc_del(struct rproc *rproc) | |||
1520 | if (rproc->auto_boot) | 1529 | if (rproc->auto_boot) |
1521 | rproc_shutdown(rproc); | 1530 | rproc_shutdown(rproc); |
1522 | 1531 | ||
1523 | /* clean up remote vdev entries */ | ||
1524 | list_for_each_entry_safe(rvdev, tmp, &rproc->rvdevs, node) | ||
1525 | rproc_remove_virtio_dev(rvdev); | ||
1526 | |||
1527 | /* the rproc is downref'ed as soon as it's removed from the klist */ | 1532 | /* the rproc is downref'ed as soon as it's removed from the klist */ |
1528 | mutex_lock(&rproc_list_mutex); | 1533 | mutex_lock(&rproc_list_mutex); |
1529 | list_del(&rproc->node); | 1534 | list_del(&rproc->node); |
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 5def5c84b9c0..8265d351c9f0 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h | |||
@@ -488,6 +488,8 @@ struct rproc_vring { | |||
488 | /** | 488 | /** |
489 | * struct rproc_vdev - remoteproc state for a supported virtio device | 489 | * struct rproc_vdev - remoteproc state for a supported virtio device |
490 | * @refcount: reference counter for the vdev and vring allocations | 490 | * @refcount: reference counter for the vdev and vring allocations |
491 | * @subdev: handle for registering the vdev as a rproc subdevice | ||
492 | * @id: virtio device id (as in virtio_ids.h) | ||
491 | * @node: list node | 493 | * @node: list node |
492 | * @rproc: the rproc handle | 494 | * @rproc: the rproc handle |
493 | * @vdev: the virio device | 495 | * @vdev: the virio device |
@@ -497,6 +499,9 @@ struct rproc_vring { | |||
497 | struct rproc_vdev { | 499 | struct rproc_vdev { |
498 | struct kref refcount; | 500 | struct kref refcount; |
499 | 501 | ||
502 | struct rproc_subdev subdev; | ||
503 | |||
504 | unsigned int id; | ||
500 | struct list_head node; | 505 | struct list_head node; |
501 | struct rproc *rproc; | 506 | struct rproc *rproc; |
502 | struct virtio_device vdev; | 507 | struct virtio_device vdev; |