From 086e843e7f0ad3f5900f3bb28753f1d595b26e22 Mon Sep 17 00:00:00 2001 From: Richard Maina Date: Wed, 29 May 2024 11:09:58 -0700 Subject: [PATCH] remoteproc: qcom_q6v5_pas: Add hwspinlock bust on stop BugLink: https://bugs.launchpad.net/bugs/2084941 [ Upstream commit 568b13b65078e2b557ccf47674a354cecd1db641 ] When remoteproc goes down unexpectedly this results in a state where any acquired hwspinlocks will remain locked possibly resulting in deadlock. In order to ensure all locks are freed we include a call to qcom_smem_bust_hwspin_lock_by_host() during remoteproc shutdown. For qcom_q6v5_pas remoteprocs, each remoteproc has an assigned smem host_id. Remoteproc can pass this id to smem to try and bust the lock on remoteproc stop. This edge case only occurs with q6v5_pas watchdog crashes. The error fatal case has handling to clear the hwspinlock before the error fatal interrupt is triggered. Signed-off-by: Richard Maina Reviewed-by: Bjorn Andersson Signed-off-by: Chris Lew Link: https://lore.kernel.org/r/20240529-hwspinlock-bust-v3-4-c8b924ffa5a2@quicinc.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin Signed-off-by: Manuel Diewald Signed-off-by: Stefan Bader --- drivers/remoteproc/qcom_q6v5_pas.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index a9dd58608052..f069591bc0d8 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -49,6 +49,7 @@ struct adsp_data { const char *ssr_name; const char *sysmon_name; int ssctl_id; + unsigned int smem_host_id; int region_assign_idx; }; @@ -74,6 +75,7 @@ struct qcom_adsp { int dtb_pas_id; unsigned int minidump_id; int crash_reason_smem; + unsigned int smem_host_id; bool decrypt_shutdown; const char *info_name; @@ -386,6 +388,9 @@ static int adsp_stop(struct rproc *rproc) if (handover) qcom_pas_handover(&adsp->q6v5); + if (adsp->smem_host_id) + ret = qcom_smem_bust_hwspin_lock_by_host(adsp->smem_host_id); + return ret; } @@ -694,6 +699,7 @@ static int adsp_probe(struct platform_device *pdev) adsp->minidump_id = desc->minidump_id; adsp->pas_id = desc->pas_id; adsp->info_name = desc->sysmon_name; + adsp->smem_host_id = desc->smem_host_id; adsp->decrypt_shutdown = desc->decrypt_shutdown; adsp->region_assign_idx = desc->region_assign_idx; if (dtb_fw_name) { @@ -1122,6 +1128,7 @@ static const struct adsp_data sm8550_adsp_resource = { .ssr_name = "lpass", .sysmon_name = "adsp", .ssctl_id = 0x14, + .smem_host_id = 2, }; static const struct adsp_data sm8550_cdsp_resource = { @@ -1142,6 +1149,7 @@ static const struct adsp_data sm8550_cdsp_resource = { .ssr_name = "cdsp", .sysmon_name = "cdsp", .ssctl_id = 0x17, + .smem_host_id = 5, }; static const struct adsp_data sm8550_mpss_resource = { @@ -1162,6 +1170,7 @@ static const struct adsp_data sm8550_mpss_resource = { .ssr_name = "mpss", .sysmon_name = "modem", .ssctl_id = 0x12, + .smem_host_id = 1, .region_assign_idx = 2, };