remoteproc: Assign kref to rproc_vdev
authorBjorn Andersson <bjorn.andersson@linaro.org>
Thu, 20 Oct 2016 02:40:06 +0000 (19:40 -0700)
committerBjorn Andersson <bjorn.andersson@linaro.org>
Tue, 15 Nov 2016 05:52:15 +0000 (21:52 -0800)
No functional change

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
drivers/remoteproc/remoteproc_core.c
drivers/remoteproc/remoteproc_internal.h
drivers/remoteproc/remoteproc_virtio.c
include/linux/remoteproc.h

index b5e314f..67f581d 100644 (file)
@@ -356,6 +356,8 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
        if (!rvdev)
                return -ENOMEM;
 
+       kref_init(&rvdev->refcount);
+
        rvdev->rproc = rproc;
 
        /* parse the vrings */
@@ -384,6 +386,14 @@ free_rvdev:
        return ret;
 }
 
+void rproc_vdev_release(struct kref *ref)
+{
+       struct rproc_vdev *rvdev = container_of(ref, struct rproc_vdev, refcount);
+
+       list_del(&rvdev->node);
+       kfree(rvdev);
+}
+
 /**
  * rproc_handle_trace() - handle a shared trace buffer resource
  * @rproc: the remote processor
index c2c3e47..1e9e5b3 100644 (file)
@@ -49,6 +49,7 @@ struct rproc_fw_ops {
 void rproc_release(struct kref *kref);
 irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int vq_id);
 int rproc_boot_nowait(struct rproc *rproc);
+void rproc_vdev_release(struct kref *ref);
 
 /* from remoteproc_virtio.c */
 int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id);
index 01870a1..0d1ad3e 100644 (file)
@@ -282,14 +282,13 @@ static const struct virtio_config_ops rproc_virtio_config_ops = {
  * Never call this function directly; it will be called by the driver
  * core when needed.
  */
-static void rproc_vdev_release(struct device *dev)
+static void rproc_virtio_dev_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(&rvdev->refcount, rproc_vdev_release);
 
        put_device(&rproc->dev);
 }
@@ -313,7 +312,7 @@ int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
        vdev->id.device = id,
        vdev->config = &rproc_virtio_config_ops,
        vdev->dev.parent = dev;
-       vdev->dev.release = rproc_vdev_release;
+       vdev->dev.release = rproc_virtio_dev_release;
 
        /*
         * We're indirectly making a non-temporary copy of the rproc pointer
@@ -325,6 +324,9 @@ int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
         */
        get_device(&rproc->dev);
 
+       /* Reference the vdev and vring allocations */
+       kref_get(&rvdev->refcount);
+
        ret = register_virtio_device(vdev);
        if (ret) {
                put_device(&rproc->dev);
index f6d5e66..5def5c8 100644 (file)
@@ -487,6 +487,7 @@ struct rproc_vring {
 
 /**
  * struct rproc_vdev - remoteproc state for a supported virtio device
+ * @refcount: reference counter for the vdev and vring allocations
  * @node: list node
  * @rproc: the rproc handle
  * @vdev: the virio device
@@ -494,6 +495,8 @@ struct rproc_vring {
  * @rsc_offset: offset of the vdev's resource entry
  */
 struct rproc_vdev {
+       struct kref refcount;
+
        struct list_head node;
        struct rproc *rproc;
        struct virtio_device vdev;