summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSibi Sankar <quic_sibis@quicinc.com>2022-07-05 15:08:19 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-08-21 16:16:08 +0300
commit5a0e3350c29ee3e80b38bbf93dfad0754ae14706 (patch)
tree70a9e6379a7790a8d6de815312e3521fbe7d95db
parent3487aa558a664cb062a5b4cda0e9a31eb0451820 (diff)
downloadlinux-5a0e3350c29ee3e80b38bbf93dfad0754ae14706.tar.xz
remoteproc: sysmon: Wait for SSCTL service to come up
[ Upstream commit 47c04e00eff86a81cd357c3feed04c86089bcb85 ] The SSCTL service comes up after a finite time when the remote Q6 comes out of reset. Any graceful shutdowns requested during this period will be a NOP and abrupt tearing down of the glink channel might lead to pending transactions on the remote Q6 side and will ultimately lead to a fatal error. Fix this by waiting for the SSCTL service when a graceful shutdown is requested. Fixes: 1fb82ee806d1 ("remoteproc: qcom: Introduce sysmon") Reviewed-by: Matthias Kaehlcke <mka@chromium.org> Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org> Link: https://lore.kernel.org/r/1657022900-2049-7-git-send-email-quic_sibis@quicinc.com Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/remoteproc/qcom_sysmon.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/remoteproc/qcom_sysmon.c b/drivers/remoteproc/qcom_sysmon.c
index b37b111b15b3..a26221a6f6c2 100644
--- a/drivers/remoteproc/qcom_sysmon.c
+++ b/drivers/remoteproc/qcom_sysmon.c
@@ -41,6 +41,7 @@ struct qcom_sysmon {
struct completion comp;
struct completion ind_comp;
struct completion shutdown_comp;
+ struct completion ssctl_comp;
struct mutex lock;
bool ssr_ack;
@@ -422,6 +423,8 @@ static int ssctl_new_server(struct qmi_handle *qmi, struct qmi_service *svc)
svc->priv = sysmon;
+ complete(&sysmon->ssctl_comp);
+
return 0;
}
@@ -478,6 +481,7 @@ static int sysmon_start(struct rproc_subdev *subdev)
.ssr_event = SSCTL_SSR_EVENT_AFTER_POWERUP
};
+ reinit_completion(&sysmon->ssctl_comp);
mutex_lock(&sysmon->state_lock);
sysmon->state = SSCTL_SSR_EVENT_AFTER_POWERUP;
blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)&event);
@@ -520,6 +524,11 @@ static void sysmon_stop(struct rproc_subdev *subdev, bool crashed)
if (crashed)
return;
+ if (sysmon->ssctl_instance) {
+ if (!wait_for_completion_timeout(&sysmon->ssctl_comp, HZ / 2))
+ dev_err(sysmon->dev, "timeout waiting for ssctl service\n");
+ }
+
if (sysmon->ssctl_version)
ssctl_request_shutdown(sysmon);
else if (sysmon->ept)
@@ -606,6 +615,7 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
init_completion(&sysmon->comp);
init_completion(&sysmon->ind_comp);
init_completion(&sysmon->shutdown_comp);
+ init_completion(&sysmon->ssctl_comp);
mutex_init(&sysmon->lock);
mutex_init(&sysmon->state_lock);