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>
This commit is contained in:
Bjorn Andersson 2017-10-30 23:11:14 -07:00
parent dcb57ed43d
commit 880f5b3882
3 changed files with 16 additions and 15 deletions

View File

@ -42,7 +42,7 @@ static int glink_subdev_probe(struct rproc_subdev *subdev)
return PTR_ERR_OR_ZERO(glink->edge); 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); 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); 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); struct qcom_rproc_subdev *smd = to_smd_subdev(subdev);
@ -201,7 +201,7 @@ static int ssr_notify_start(struct rproc_subdev *subdev)
return 0; 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); struct qcom_rproc_ssr *ssr = to_ssr_subdev(subdev);

View File

@ -308,7 +308,7 @@ static int rproc_vdev_do_probe(struct rproc_subdev *subdev)
return rproc_add_virtio_dev(rvdev, rvdev->id); 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); 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: unroll_registration:
list_for_each_entry_continue_reverse(subdev, &rproc->subdevs, node) list_for_each_entry_continue_reverse(subdev, &rproc->subdevs, node)
subdev->remove(subdev); subdev->remove(subdev, true);
return ret; return ret;
} }
static void rproc_remove_subdevices(struct rproc *rproc) static void rproc_remove_subdevices(struct rproc *rproc, bool crashed)
{ {
struct rproc_subdev *subdev; struct rproc_subdev *subdev;
list_for_each_entry_reverse(subdev, &rproc->subdevs, node) 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; return ret;
} }
static int rproc_stop(struct rproc *rproc) static int rproc_stop(struct rproc *rproc, bool crashed)
{ {
struct device *dev = &rproc->dev; struct device *dev = &rproc->dev;
int ret; int ret;
/* remove any subdevices for the remote processor */ /* remove any subdevices for the remote processor */
rproc_remove_subdevices(rproc); rproc_remove_subdevices(rproc, crashed);
/* the installed resource table is no longer accessible */ /* the installed resource table is no longer accessible */
rproc->table_ptr = rproc->cached_table; rproc->table_ptr = rproc->cached_table;
@ -1163,7 +1163,7 @@ int rproc_trigger_recovery(struct rproc *rproc)
if (ret) if (ret)
return ret; return ret;
ret = rproc_stop(rproc); ret = rproc_stop(rproc, false);
if (ret) if (ret)
goto unlock_mutex; goto unlock_mutex;
@ -1316,7 +1316,7 @@ void rproc_shutdown(struct rproc *rproc)
if (!atomic_dec_and_test(&rproc->power)) if (!atomic_dec_and_test(&rproc->power))
goto out; goto out;
ret = rproc_stop(rproc); ret = rproc_stop(rproc, true);
if (ret) { if (ret) {
atomic_inc(&rproc->power); atomic_inc(&rproc->power);
goto out; goto out;
@ -1663,7 +1663,7 @@ EXPORT_SYMBOL(rproc_del);
void rproc_add_subdev(struct rproc *rproc, void rproc_add_subdev(struct rproc *rproc,
struct rproc_subdev *subdev, struct rproc_subdev *subdev,
int (*probe)(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->probe = probe;
subdev->remove = remove; subdev->remove = remove;

View File

@ -478,13 +478,14 @@ struct rproc {
* struct rproc_subdev - subdevice tied to a remoteproc * struct rproc_subdev - subdevice tied to a remoteproc
* @node: list node related to the rproc subdevs list * @node: list node related to the rproc subdevs list
* @probe: probe function, called as the rproc is started * @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 rproc_subdev {
struct list_head node; struct list_head node;
int (*probe)(struct rproc_subdev *subdev); 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 */ /* 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, void rproc_add_subdev(struct rproc *rproc,
struct rproc_subdev *subdev, struct rproc_subdev *subdev,
int (*probe)(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); void rproc_remove_subdev(struct rproc *rproc, struct rproc_subdev *subdev);