diff options
author | Bjorn Andersson <bjorn.andersson@linaro.org> | 2017-10-31 02:11:14 -0400 |
---|---|---|
committer | Bjorn Andersson <bjorn.andersson@linaro.org> | 2018-02-12 19:57:22 -0500 |
commit | 880f5b388252fedb26c70bb80ad1d7c8abbc0607 (patch) | |
tree | 90908a2cea6f8f71c8966b6b638c3b880bf9f440 | |
parent | dcb57ed43d9ec5e16628c337143cd6b387f42778 (diff) |
remoteproc: Pass type of shutdown to subdev remove
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>
-rw-r--r-- | drivers/remoteproc/qcom_common.c | 6 | ||||
-rw-r--r-- | drivers/remoteproc/remoteproc_core.c | 18 | ||||
-rw-r--r-- | include/linux/remoteproc.h | 7 |
3 files changed, 16 insertions, 15 deletions
diff --git a/drivers/remoteproc/qcom_common.c b/drivers/remoteproc/qcom_common.c index b7d53a9cf21f..9e47a147c131 100644 --- a/drivers/remoteproc/qcom_common.c +++ b/drivers/remoteproc/qcom_common.c | |||
@@ -42,7 +42,7 @@ static int glink_subdev_probe(struct rproc_subdev *subdev) | |||
42 | return PTR_ERR_OR_ZERO(glink->edge); | 42 | return PTR_ERR_OR_ZERO(glink->edge); |
43 | } | 43 | } |
44 | 44 | ||
45 | static void glink_subdev_remove(struct rproc_subdev *subdev) | 45 | static void glink_subdev_remove(struct rproc_subdev *subdev, bool crashed) |
46 | { | 46 | { |
47 | struct qcom_rproc_glink *glink = to_glink_subdev(subdev); | 47 | struct qcom_rproc_glink *glink = to_glink_subdev(subdev); |
48 | 48 | ||
@@ -132,7 +132,7 @@ static int smd_subdev_probe(struct rproc_subdev *subdev) | |||
132 | return PTR_ERR_OR_ZERO(smd->edge); | 132 | return PTR_ERR_OR_ZERO(smd->edge); |
133 | } | 133 | } |
134 | 134 | ||
135 | static void smd_subdev_remove(struct rproc_subdev *subdev) | 135 | static void smd_subdev_remove(struct rproc_subdev *subdev, bool crashed) |
136 | { | 136 | { |
137 | struct qcom_rproc_subdev *smd = to_smd_subdev(subdev); | 137 | struct qcom_rproc_subdev *smd = to_smd_subdev(subdev); |
138 | 138 | ||
@@ -201,7 +201,7 @@ static int ssr_notify_start(struct rproc_subdev *subdev) | |||
201 | return 0; | 201 | return 0; |
202 | } | 202 | } |
203 | 203 | ||
204 | static void ssr_notify_stop(struct rproc_subdev *subdev) | 204 | static void ssr_notify_stop(struct rproc_subdev *subdev, bool crashed) |
205 | { | 205 | { |
206 | struct qcom_rproc_ssr *ssr = to_ssr_subdev(subdev); | 206 | struct qcom_rproc_ssr *ssr = to_ssr_subdev(subdev); |
207 | 207 | ||
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index fd257607a578..6d9c5832ce47 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c | |||
@@ -308,7 +308,7 @@ static int rproc_vdev_do_probe(struct rproc_subdev *subdev) | |||
308 | return rproc_add_virtio_dev(rvdev, rvdev->id); | 308 | return rproc_add_virtio_dev(rvdev, rvdev->id); |
309 | } | 309 | } |
310 | 310 | ||
311 | static void rproc_vdev_do_remove(struct rproc_subdev *subdev) | 311 | static void rproc_vdev_do_remove(struct rproc_subdev *subdev, bool crashed) |
312 | { | 312 | { |
313 | struct rproc_vdev *rvdev = container_of(subdev, struct rproc_vdev, subdev); | 313 | struct rproc_vdev *rvdev = container_of(subdev, struct rproc_vdev, subdev); |
314 | 314 | ||
@@ -789,17 +789,17 @@ static int rproc_probe_subdevices(struct rproc *rproc) | |||
789 | 789 | ||
790 | unroll_registration: | 790 | unroll_registration: |
791 | list_for_each_entry_continue_reverse(subdev, &rproc->subdevs, node) | 791 | list_for_each_entry_continue_reverse(subdev, &rproc->subdevs, node) |
792 | subdev->remove(subdev); | 792 | subdev->remove(subdev, true); |
793 | 793 | ||
794 | return ret; | 794 | return ret; |
795 | } | 795 | } |
796 | 796 | ||
797 | static void rproc_remove_subdevices(struct rproc *rproc) | 797 | static void rproc_remove_subdevices(struct rproc *rproc, bool crashed) |
798 | { | 798 | { |
799 | struct rproc_subdev *subdev; | 799 | struct rproc_subdev *subdev; |
800 | 800 | ||
801 | list_for_each_entry_reverse(subdev, &rproc->subdevs, node) | 801 | list_for_each_entry_reverse(subdev, &rproc->subdevs, node) |
802 | subdev->remove(subdev); | 802 | subdev->remove(subdev, crashed); |
803 | } | 803 | } |
804 | 804 | ||
805 | /** | 805 | /** |
@@ -1009,13 +1009,13 @@ static int rproc_trigger_auto_boot(struct rproc *rproc) | |||
1009 | return ret; | 1009 | return ret; |
1010 | } | 1010 | } |
1011 | 1011 | ||
1012 | static int rproc_stop(struct rproc *rproc) | 1012 | static int rproc_stop(struct rproc *rproc, bool crashed) |
1013 | { | 1013 | { |
1014 | struct device *dev = &rproc->dev; | 1014 | struct device *dev = &rproc->dev; |
1015 | int ret; | 1015 | int ret; |
1016 | 1016 | ||
1017 | /* remove any subdevices for the remote processor */ | 1017 | /* remove any subdevices for the remote processor */ |
1018 | rproc_remove_subdevices(rproc); | 1018 | rproc_remove_subdevices(rproc, crashed); |
1019 | 1019 | ||
1020 | /* the installed resource table is no longer accessible */ | 1020 | /* the installed resource table is no longer accessible */ |
1021 | rproc->table_ptr = rproc->cached_table; | 1021 | rproc->table_ptr = rproc->cached_table; |
@@ -1163,7 +1163,7 @@ int rproc_trigger_recovery(struct rproc *rproc) | |||
1163 | if (ret) | 1163 | if (ret) |
1164 | return ret; | 1164 | return ret; |
1165 | 1165 | ||
1166 | ret = rproc_stop(rproc); | 1166 | ret = rproc_stop(rproc, false); |
1167 | if (ret) | 1167 | if (ret) |
1168 | goto unlock_mutex; | 1168 | goto unlock_mutex; |
1169 | 1169 | ||
@@ -1316,7 +1316,7 @@ void rproc_shutdown(struct rproc *rproc) | |||
1316 | if (!atomic_dec_and_test(&rproc->power)) | 1316 | if (!atomic_dec_and_test(&rproc->power)) |
1317 | goto out; | 1317 | goto out; |
1318 | 1318 | ||
1319 | ret = rproc_stop(rproc); | 1319 | ret = rproc_stop(rproc, true); |
1320 | if (ret) { | 1320 | if (ret) { |
1321 | atomic_inc(&rproc->power); | 1321 | atomic_inc(&rproc->power); |
1322 | goto out; | 1322 | goto out; |
@@ -1663,7 +1663,7 @@ EXPORT_SYMBOL(rproc_del); | |||
1663 | void rproc_add_subdev(struct rproc *rproc, | 1663 | void rproc_add_subdev(struct rproc *rproc, |
1664 | struct rproc_subdev *subdev, | 1664 | struct rproc_subdev *subdev, |
1665 | int (*probe)(struct rproc_subdev *subdev), | 1665 | int (*probe)(struct rproc_subdev *subdev), |
1666 | void (*remove)(struct rproc_subdev *subdev)) | 1666 | void (*remove)(struct rproc_subdev *subdev, bool crashed)) |
1667 | { | 1667 | { |
1668 | subdev->probe = probe; | 1668 | subdev->probe = probe; |
1669 | subdev->remove = remove; | 1669 | subdev->remove = remove; |
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index f16864acedad..d09a9c7af109 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h | |||
@@ -478,13 +478,14 @@ struct rproc { | |||
478 | * struct rproc_subdev - subdevice tied to a remoteproc | 478 | * struct rproc_subdev - subdevice tied to a remoteproc |
479 | * @node: list node related to the rproc subdevs list | 479 | * @node: list node related to the rproc subdevs list |
480 | * @probe: probe function, called as the rproc is started | 480 | * @probe: probe function, called as the rproc is started |
481 | * @remove: remove function, called as the rproc is stopped | 481 | * @remove: remove function, called as the rproc is being stopped, the @crashed |
482 | * parameter indicates if this originates from the a recovery | ||
482 | */ | 483 | */ |
483 | struct rproc_subdev { | 484 | struct rproc_subdev { |
484 | struct list_head node; | 485 | struct list_head node; |
485 | 486 | ||
486 | int (*probe)(struct rproc_subdev *subdev); | 487 | int (*probe)(struct rproc_subdev *subdev); |
487 | void (*remove)(struct rproc_subdev *subdev); | 488 | void (*remove)(struct rproc_subdev *subdev, bool crashed); |
488 | }; | 489 | }; |
489 | 490 | ||
490 | /* we currently support only two vrings per rvdev */ | 491 | /* we currently support only two vrings per rvdev */ |
@@ -568,7 +569,7 @@ static inline struct rproc *vdev_to_rproc(struct virtio_device *vdev) | |||
568 | void rproc_add_subdev(struct rproc *rproc, | 569 | void rproc_add_subdev(struct rproc *rproc, |
569 | struct rproc_subdev *subdev, | 570 | struct rproc_subdev *subdev, |
570 | int (*probe)(struct rproc_subdev *subdev), | 571 | int (*probe)(struct rproc_subdev *subdev), |
571 | void (*remove)(struct rproc_subdev *subdev)); | 572 | void (*remove)(struct rproc_subdev *subdev, bool graceful)); |
572 | 573 | ||
573 | void rproc_remove_subdev(struct rproc *rproc, struct rproc_subdev *subdev); | 574 | void rproc_remove_subdev(struct rproc *rproc, struct rproc_subdev *subdev); |
574 | 575 | ||