In preparation of the migration of the management of rvdev in rproc_virtio, this patch spins off new functions to manage the virtio device. Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@xxxxxx> --- drivers/remoteproc/remoteproc_core.c | 149 +++++++++++++++------------ 1 file changed, 83 insertions(+), 66 deletions(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 2a0425ab82a7..5c90d569c0f7 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -441,6 +441,86 @@ static void rproc_rvdev_release(struct device *dev) kfree(rvdev); } +static int rproc_rvdev_add_device(struct rproc_vdev *rvdev) +{ + struct rproc *rproc = rvdev->rproc; + struct fw_rsc_vdev *rsc = rvdev->rsc; + char name[16]; + int ret, i; + + /* Initialise vdev subdevice */ + snprintf(name, sizeof(name), "vdev%dbuffer", rvdev->index); + rvdev->dev.parent = &rproc->dev; + rvdev->dev.dma_pfn_offset = rproc->dev.parent->dma_pfn_offset; + rvdev->dev.release = rproc_rvdev_release; + dev_set_name(&rvdev->dev, "%s#%s", dev_name(rvdev->dev.parent), name); + dev_set_drvdata(&rvdev->dev, rvdev); + + ret = device_register(&rvdev->dev); + if (ret) { + put_device(&rvdev->dev); + return ret; + } + /* Make device dma capable by inheriting from parent's capabilities */ + set_dma_ops(&rvdev->dev, get_dma_ops(rproc->dev.parent)); + + ret = dma_coerce_mask_and_coherent(&rvdev->dev, + dma_get_mask(rproc->dev.parent)); + if (ret) { + dev_warn(&rvdev->dev, + "Failed to set DMA mask %llx. Trying to continue... %x\n", + dma_get_mask(rproc->dev.parent), ret); + } + + /* parse the vrings */ + for (i = 0; i < rsc->num_of_vrings; i++) { + ret = rproc_parse_vring(rvdev, rsc, i); + if (ret) + goto free_rvdev; + } + + /* allocate the vring resources */ + for (i = 0; i < rsc->num_of_vrings; i++) { + ret = rproc_alloc_vring(rvdev, i); + if (ret) + goto free_vg; + } + + rvdev->subdev.start = rproc_vdev_do_start; + rvdev->subdev.stop = rproc_vdev_do_stop; + + rproc_add_subdev(rproc, &rvdev->subdev); + + return 0; + +free_vg: + for (i--; i >= 0; i--) { + struct rproc_vring *rvring = &rvdev->vring[i]; + + rproc_free_vring(rvring); + } + +free_rvdev: + device_unregister(&rvdev->dev); + + return ret; +} + +static void rproc_rvdev_remove_device(struct rproc_vdev *rvdev) +{ + struct rproc *rproc = rvdev->rproc; + struct rproc_vring *rvring; + int id; + + for (id = 0; id < ARRAY_SIZE(rvdev->vring); id++) { + rvring = &rvdev->vring[id]; + rproc_free_vring(rvring); + } + + rproc_remove_subdev(rproc, &rvdev->subdev); + device_unregister(&rvdev->dev); +} + /** * rproc_handle_vdev() - handle a vdev fw resource * @rproc: the remote processor @@ -473,8 +553,6 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc, { struct device *dev = &rproc->dev; struct rproc_vdev *rvdev; - int i, ret; - char name[16]; /* make sure resource isn't truncated */ if (struct_size(rsc, vring, rsc->num_of_vrings) + rsc->config_len > @@ -505,83 +583,22 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc, kref_init(&rvdev->refcount); rvdev->rsc = rsc; + rvdev->rsc_offset = offset; rvdev->id = rsc->id; rvdev->rproc = rproc; rvdev->index = rproc->nb_vdev++; - /* Initialise vdev subdevice */ - snprintf(name, sizeof(name), "vdev%dbuffer", rvdev->index); - rvdev->dev.parent = rproc->dev.parent; - rvdev->dev.dma_pfn_offset = rproc->dev.parent->dma_pfn_offset; - rvdev->dev.release = rproc_rvdev_release; - dev_set_name(&rvdev->dev, "%s#%s", dev_name(rvdev->dev.parent), name); - dev_set_drvdata(&rvdev->dev, rvdev); - - ret = device_register(&rvdev->dev); - if (ret) { - put_device(&rvdev->dev); - return ret; - } - /* Make device dma capable by inheriting from parent's capabilities */ - set_dma_ops(&rvdev->dev, get_dma_ops(rproc->dev.parent)); - - ret = dma_coerce_mask_and_coherent(&rvdev->dev, - dma_get_mask(rproc->dev.parent)); - if (ret) { - dev_warn(dev, - "Failed to set DMA mask %llx. Trying to continue... %x\n", - dma_get_mask(rproc->dev.parent), ret); - } - - /* parse the vrings */ - for (i = 0; i < rsc->num_of_vrings; i++) { - ret = rproc_parse_vring(rvdev, rsc, i); - if (ret) - goto free_rvdev; - } - - /* remember the resource offset*/ - rvdev->rsc_offset = offset; - - /* allocate the vring resources */ - for (i = 0; i < rsc->num_of_vrings; i++) { - ret = rproc_alloc_vring(rvdev, i); - if (ret) - goto unwind_vring_allocations; - } - list_add_tail(&rvdev->node, &rproc->rvdevs); - rvdev->subdev.start = rproc_vdev_do_start; - rvdev->subdev.stop = rproc_vdev_do_stop; - - rproc_add_subdev(rproc, &rvdev->subdev); - - return 0; - -unwind_vring_allocations: - for (i--; i >= 0; i--) - rproc_free_vring(&rvdev->vring[i]); -free_rvdev: - device_unregister(&rvdev->dev); - return ret; + return rproc_rvdev_add_device(rvdev); } void rproc_vdev_release(struct kref *ref) { struct rproc_vdev *rvdev = container_of(ref, struct rproc_vdev, refcount); - struct rproc_vring *rvring; - struct rproc *rproc = rvdev->rproc; - int id; - - for (id = 0; id < ARRAY_SIZE(rvdev->vring); id++) { - rvring = &rvdev->vring[id]; - rproc_free_vring(rvring); - } - rproc_remove_subdev(rproc, &rvdev->subdev); + rproc_rvdev_remove_device(rvdev); list_del(&rvdev->node); - device_unregister(&rvdev->dev); } /** -- 2.17.1