diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/remoteproc/qcom_q6v5_pas.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 6ae39c5653b1..297700f87fe8 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -8,6 +8,7 @@ */ #include <linux/clk.h> +#include <linux/delay.h> #include <linux/firmware.h> #include <linux/interrupt.h> #include <linux/kernel.h> @@ -29,6 +30,8 @@ #include "qcom_q6v5.h" #include "remoteproc_internal.h" +#define ADSP_DECRYPT_SHUTDOWN_DELAY_MS 100 + struct adsp_data { int crash_reason_smem; const char *firmware_name; @@ -36,6 +39,7 @@ struct adsp_data { unsigned int minidump_id; bool has_aggre2_clk; bool auto_boot; + bool decrypt_shutdown; char **proxy_pd_names; @@ -65,6 +69,7 @@ struct qcom_adsp { unsigned int minidump_id; int crash_reason_smem; bool has_aggre2_clk; + bool decrypt_shutdown; const char *info_name; struct completion start_done; @@ -128,6 +133,19 @@ static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds, } } +static int adsp_shutdown_poll_decrypt(struct qcom_adsp *adsp) +{ + unsigned int retry_num = 50; + int ret; + + do { + msleep(ADSP_DECRYPT_SHUTDOWN_DELAY_MS); + ret = qcom_scm_pas_shutdown(adsp->pas_id); + } while (ret == -EINVAL && --retry_num); + + return ret; +} + static int adsp_unprepare(struct rproc *rproc) { struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; @@ -249,6 +267,9 @@ static int adsp_stop(struct rproc *rproc) dev_err(adsp->dev, "timed out on wait\n"); ret = qcom_scm_pas_shutdown(adsp->pas_id); + if (ret && adsp->decrypt_shutdown) + ret = adsp_shutdown_poll_decrypt(adsp); + if (ret) dev_err(adsp->dev, "failed to shutdown: %d\n", ret); @@ -459,6 +480,7 @@ static int adsp_probe(struct platform_device *pdev) adsp->pas_id = desc->pas_id; adsp->has_aggre2_clk = desc->has_aggre2_clk; adsp->info_name = desc->sysmon_name; + adsp->decrypt_shutdown = desc->decrypt_shutdown; platform_set_drvdata(pdev, adsp); device_wakeup_enable(adsp->dev); @@ -877,6 +899,25 @@ static const struct adsp_data sdx55_mpss_resource = { .ssctl_id = 0x22, }; +static const struct adsp_data sm8450_mpss_resource = { + .crash_reason_smem = 421, + .firmware_name = "modem.mdt", + .pas_id = 4, + .minidump_id = 3, + .has_aggre2_clk = false, + .auto_boot = false, + .decrypt_shutdown = true, + .proxy_pd_names = (char*[]){ + "cx", + "mss", + NULL + }, + .load_state = "modem", + .ssr_name = "mpss", + .sysmon_name = "modem", + .ssctl_id = 0x12, +}; + static const struct of_device_id adsp_of_match[] = { { .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init}, { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init}, @@ -916,7 +957,7 @@ static const struct of_device_id adsp_of_match[] = { { .compatible = "qcom,sm8450-adsp-pas", .data = &sm8350_adsp_resource}, { .compatible = "qcom,sm8450-cdsp-pas", .data = &sm8350_cdsp_resource}, { .compatible = "qcom,sm8450-slpi-pas", .data = &sm8350_slpi_resource}, - { .compatible = "qcom,sm8450-mpss-pas", .data = &mpss_resource_init}, + { .compatible = "qcom,sm8450-mpss-pas", .data = &sm8450_mpss_resource}, { }, }; MODULE_DEVICE_TABLE(of, adsp_of_match); |