remoteproc: Pass type of shutdown to subdev remove
authorBjorn Andersson <bjorn.andersson@linaro.org>
Tue, 31 Oct 2017 06:11:14 +0000 (23:11 -0700)
committerBjorn Andersson <bjorn.andersson@linaro.org>
Tue, 13 Feb 2018 00:57:22 +0000 (16:57 -0800)
remoteproc instances can be stopped either by invoking shutdown or by an
attempt to recover from a crash. For some subdev types it's expected to
clean up gracefully during a shutdown, but are unable to do so during a
crash - so pass this information to the subdev remove functions.

Acked-By: Chris Lew <clew@codeaurora.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
drivers/remoteproc/qcom_common.c
drivers/remoteproc/remoteproc_core.c
include/linux/remoteproc.h

index b7d53a9cf21ff75fe65df9eda17681bfa76368b4..9e47a147c1318f95f65db2dc5a61e7c85ac21856 100644 (file)
@@ -42,7 +42,7 @@ static int glink_subdev_probe(struct rproc_subdev *subdev)
        return PTR_ERR_OR_ZERO(glink->edge);
 }
 
-static void glink_subdev_remove(struct rproc_subdev *subdev)
+static void glink_subdev_remove(struct rproc_subdev *subdev, bool crashed)
 {
        struct qcom_rproc_glink *glink = to_glink_subdev(subdev);
 
@@ -132,7 +132,7 @@ static int smd_subdev_probe(struct rproc_subdev *subdev)
        return PTR_ERR_OR_ZERO(smd->edge);
 }
 
-static void smd_subdev_remove(struct rproc_subdev *subdev)
+static void smd_subdev_remove(struct rproc_subdev *subdev, bool crashed)
 {
        struct qcom_rproc_subdev *smd = to_smd_subdev(subdev);
 
@@ -201,7 +201,7 @@ static int ssr_notify_start(struct rproc_subdev *subdev)
        return  0;
 }
 
-static void ssr_notify_stop(struct rproc_subdev *subdev)
+static void ssr_notify_stop(struct rproc_subdev *subdev, bool crashed)
 {
        struct qcom_rproc_ssr *ssr = to_ssr_subdev(subdev);
 
index fd257607a578f17a48b7b32b84a4e17264a06969..6d9c5832ce47d3052568f10794652686237c00e8 100644 (file)
@@ -308,7 +308,7 @@ static int rproc_vdev_do_probe(struct rproc_subdev *subdev)
        return rproc_add_virtio_dev(rvdev, rvdev->id);
 }
 
-static void rproc_vdev_do_remove(struct rproc_subdev *subdev)
+static void rproc_vdev_do_remove(struct rproc_subdev *subdev, bool crashed)
 {
        struct rproc_vdev *rvdev = container_of(subdev, struct rproc_vdev, subdev);
 
@@ -789,17 +789,17 @@ static int rproc_probe_subdevices(struct rproc *rproc)
 
 unroll_registration:
        list_for_each_entry_continue_reverse(subdev, &rproc->subdevs, node)
-               subdev->remove(subdev);
+               subdev->remove(subdev, true);
 
        return ret;
 }
 
-static void rproc_remove_subdevices(struct rproc *rproc)
+static void rproc_remove_subdevices(struct rproc *rproc, bool crashed)
 {
        struct rproc_subdev *subdev;
 
        list_for_each_entry_reverse(subdev, &rproc->subdevs, node)
-               subdev->remove(subdev);
+               subdev->remove(subdev, crashed);
 }
 
 /**
@@ -1009,13 +1009,13 @@ static int rproc_trigger_auto_boot(struct rproc *rproc)
        return ret;
 }
 
-static int rproc_stop(struct rproc *rproc)
+static int rproc_stop(struct rproc *rproc, bool crashed)
 {
        struct device *dev = &rproc->dev;
        int ret;
 
        /* remove any subdevices for the remote processor */
-       rproc_remove_subdevices(rproc);
+       rproc_remove_subdevices(rproc, crashed);
 
        /* the installed resource table is no longer accessible */
        rproc->table_ptr = rproc->cached_table;
@@ -1163,7 +1163,7 @@ int rproc_trigger_recovery(struct rproc *rproc)
        if (ret)
                return ret;
 
-       ret = rproc_stop(rproc);
+       ret = rproc_stop(rproc, false);
        if (ret)
                goto unlock_mutex;
 
@@ -1316,7 +1316,7 @@ void rproc_shutdown(struct rproc *rproc)
        if (!atomic_dec_and_test(&rproc->power))
                goto out;
 
-       ret = rproc_stop(rproc);
+       ret = rproc_stop(rproc, true);
        if (ret) {
                atomic_inc(&rproc->power);
                goto out;
@@ -1663,7 +1663,7 @@ EXPORT_SYMBOL(rproc_del);
 void rproc_add_subdev(struct rproc *rproc,
                      struct rproc_subdev *subdev,
                      int (*probe)(struct rproc_subdev *subdev),
-                     void (*remove)(struct rproc_subdev *subdev))
+                     void (*remove)(struct rproc_subdev *subdev, bool crashed))
 {
        subdev->probe = probe;
        subdev->remove = remove;
index f16864acedada980955172d3a241e6aaee12bdcf..d09a9c7af109fbb27324d9f4f7f83c60843c9110 100644 (file)
@@ -478,13 +478,14 @@ struct rproc {
  * struct rproc_subdev - subdevice tied to a remoteproc
  * @node: list node related to the rproc subdevs list
  * @probe: probe function, called as the rproc is started
- * @remove: remove function, called as the rproc is stopped
+ * @remove: remove function, called as the rproc is being stopped, the @crashed
+ *         parameter indicates if this originates from the a recovery
  */
 struct rproc_subdev {
        struct list_head node;
 
        int (*probe)(struct rproc_subdev *subdev);
-       void (*remove)(struct rproc_subdev *subdev);
+       void (*remove)(struct rproc_subdev *subdev, bool crashed);
 };
 
 /* we currently support only two vrings per rvdev */
@@ -568,7 +569,7 @@ static inline struct rproc *vdev_to_rproc(struct virtio_device *vdev)
 void rproc_add_subdev(struct rproc *rproc,
                      struct rproc_subdev *subdev,
                      int (*probe)(struct rproc_subdev *subdev),
-                     void (*remove)(struct rproc_subdev *subdev));
+                     void (*remove)(struct rproc_subdev *subdev, bool graceful));
 
 void rproc_remove_subdev(struct rproc *rproc, struct rproc_subdev *subdev);