aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Andersson <bjorn.andersson@linaro.org>2017-10-31 02:11:14 -0400
committerBjorn Andersson <bjorn.andersson@linaro.org>2018-02-12 19:57:22 -0500
commit880f5b388252fedb26c70bb80ad1d7c8abbc0607 (patch)
tree90908a2cea6f8f71c8966b6b638c3b880bf9f440
parentdcb57ed43d9ec5e16628c337143cd6b387f42778 (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.c6
-rw-r--r--drivers/remoteproc/remoteproc_core.c18
-rw-r--r--include/linux/remoteproc.h7
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
45static void glink_subdev_remove(struct rproc_subdev *subdev) 45static 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
135static void smd_subdev_remove(struct rproc_subdev *subdev) 135static 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
204static void ssr_notify_stop(struct rproc_subdev *subdev) 204static 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
311static void rproc_vdev_do_remove(struct rproc_subdev *subdev) 311static 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
790unroll_registration: 790unroll_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
797static void rproc_remove_subdevices(struct rproc *rproc) 797static 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
1012static int rproc_stop(struct rproc *rproc) 1012static 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);
1663void rproc_add_subdev(struct rproc *rproc, 1663void 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 */
483struct rproc_subdev { 484struct 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)
568void rproc_add_subdev(struct rproc *rproc, 569void 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
573void rproc_remove_subdev(struct rproc *rproc, struct rproc_subdev *subdev); 574void rproc_remove_subdev(struct rproc *rproc, struct rproc_subdev *subdev);
574 575