diff mbox series

remoteproc: qcom: pas: Add decrypt shutdown support for modem

Message ID 1653031684-14771-1-git-send-email-quic_sibis@quicinc.com (mailing list archive)
State Changes Requested
Headers show
Series remoteproc: qcom: pas: Add decrypt shutdown support for modem | expand

Commit Message

Sibi Sankar May 20, 2022, 7:28 a.m. UTC
The initial shutdown request to modem on SM8450 SoCs would start the
decryption process and will keep returning errors until the modem shutdown
is complete. Fix this by retrying shutdowns in fixed intervals.

Err Logs on modem shutdown:
qcom_q6v5_pas 4080000.remoteproc: failed to shutdown: -22
remoteproc remoteproc3: can't stop rproc: -22

Fixes: 5cef9b48458d ("remoteproc: qcom: pas: Add SM8450 remoteproc support")
Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
---
 drivers/remoteproc/qcom_q6v5_pas.c | 67 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 66 insertions(+), 1 deletion(-)

Comments

Bjorn Andersson June 30, 2022, 7:28 p.m. UTC | #1
On Fri 20 May 02:28 CDT 2022, Sibi Sankar wrote:

> The initial shutdown request to modem on SM8450 SoCs would start the
> decryption process and will keep returning errors until the modem shutdown
> is complete. Fix this by retrying shutdowns in fixed intervals.
> 
> Err Logs on modem shutdown:
> qcom_q6v5_pas 4080000.remoteproc: failed to shutdown: -22
> remoteproc remoteproc3: can't stop rproc: -22
> 
> Fixes: 5cef9b48458d ("remoteproc: qcom: pas: Add SM8450 remoteproc support")
> Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>

Looks reasonable, just two inquiries below.

> ---
>  drivers/remoteproc/qcom_q6v5_pas.c | 67 +++++++++++++++++++++++++++++++++++++-
>  1 file changed, 66 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
> index 6ae39c5653b1..d04c4b877e12 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,20 @@ static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds,
>  	}
>  }
>  
> +static int adsp_decrypt_shutdown(struct qcom_adsp *adsp)
> +{
> +	int retry_num = 50;

Seems unsigned to me.

> +	int ret = -EINVAL;
> +
> +	while (retry_num && ret) {
> +		msleep(ADSP_DECRYPT_SHUTDOWN_DELAY_MS);
> +		ret = qcom_scm_pas_shutdown(adsp->pas_id);
> +		retry_num--;
> +	}

Will qcom_scm_pas_shutdown() ever return any other errors than -EINVAL?

Would it make sense to make this:

	do {
		...;
	} 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 +268,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_decrypt_shutdown(adsp);
> +
>  	if (ret)
>  		dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
>  
> @@ -459,6 +481,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);
> @@ -533,6 +556,7 @@ static const struct adsp_data adsp_resource_init = {
>  		.pas_id = 1,
>  		.has_aggre2_clk = false,
>  		.auto_boot = true,
> +		.decrypt_shutdown = false,

With all these booleans, I would prefer if we cleaned it up to not list
the disabled options. That would make it quicker to spot which features
are actually enabled for each remoteproc.

Regards,
Bjorn
Bjorn Andersson June 30, 2022, 7:29 p.m. UTC | #2
On Fri 20 May 02:28 CDT 2022, Sibi Sankar wrote:
> +static int adsp_decrypt_shutdown(struct qcom_adsp *adsp)

Forgot to write down one comment, how about naming this
adsp_shutdown_poll_decrypt() to make it slightly more clear from the
name what's going on here?

Thanks,
Bjorn

> +{
> +	int retry_num = 50;
> +	int ret = -EINVAL;
> +
> +	while (retry_num && ret) {
> +		msleep(ADSP_DECRYPT_SHUTDOWN_DELAY_MS);
> +		ret = qcom_scm_pas_shutdown(adsp->pas_id);
> +		retry_num--;
> +	}
> +
> +	return ret;
> +}
> +
Sibi Sankar July 5, 2022, 11:53 a.m. UTC | #3
Hey Bjorn,
Thanks for taking time to review the series.

On 7/1/22 12:58 AM, Bjorn Andersson wrote:
> On Fri 20 May 02:28 CDT 2022, Sibi Sankar wrote:
> 
>> The initial shutdown request to modem on SM8450 SoCs would start the
>> decryption process and will keep returning errors until the modem shutdown
>> is complete. Fix this by retrying shutdowns in fixed intervals.
>>
>> Err Logs on modem shutdown:
>> qcom_q6v5_pas 4080000.remoteproc: failed to shutdown: -22
>> remoteproc remoteproc3: can't stop rproc: -22
>>
>> Fixes: 5cef9b48458d ("remoteproc: qcom: pas: Add SM8450 remoteproc support")
>> Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
> 
> Looks reasonable, just two inquiries below.
> 
>> ---
>>   drivers/remoteproc/qcom_q6v5_pas.c | 67 +++++++++++++++++++++++++++++++++++++-
>>   1 file changed, 66 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
>> index 6ae39c5653b1..d04c4b877e12 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,20 @@ static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds,
>>   	}
>>   }
>>   
>> +static int adsp_decrypt_shutdown(struct qcom_adsp *adsp)
>> +{
>> +	int retry_num = 50;
> 
> Seems unsigned to me.

ack

> 
>> +	int ret = -EINVAL;
>> +
>> +	while (retry_num && ret) {
>> +		msleep(ADSP_DECRYPT_SHUTDOWN_DELAY_MS);
>> +		ret = qcom_scm_pas_shutdown(adsp->pas_id);
>> +		retry_num--;
>> +	}
> 
> Will qcom_scm_pas_shutdown() ever return any other errors than -EINVAL?
> 
> Would it make sense to make this:
> 
> 	do {
> 		...;
> 	} while (ret == -EINVAL && --retry_num);
> 

Just checking on ret would cover the -EINVAL case as well but like you
said pas_shutdown() won't return any other error. So I'll just stick
with your suggestion.

>> +
>> +	return ret;
>> +}
>> +
>>   static int adsp_unprepare(struct rproc *rproc)
>>   {
>>   	struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
>> @@ -249,6 +268,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_decrypt_shutdown(adsp);
>> +
>>   	if (ret)
>>   		dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
>>   
>> @@ -459,6 +481,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);
>> @@ -533,6 +556,7 @@ static const struct adsp_data adsp_resource_init = {
>>   		.pas_id = 1,
>>   		.has_aggre2_clk = false,
>>   		.auto_boot = true,
>> +		.decrypt_shutdown = false,
> 
> With all these booleans, I would prefer if we cleaned it up to not list
> the disabled options. That would make it quicker to spot which features
> are actually enabled for each remoteproc.

ack and ack to the adsp_shutdown_poll_decrypt() as well.

> 
> Regards,
> Bjorn
>
diff mbox series

Patch

diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
index 6ae39c5653b1..d04c4b877e12 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,20 @@  static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds,
 	}
 }
 
+static int adsp_decrypt_shutdown(struct qcom_adsp *adsp)
+{
+	int retry_num = 50;
+	int ret = -EINVAL;
+
+	while (retry_num && ret) {
+		msleep(ADSP_DECRYPT_SHUTDOWN_DELAY_MS);
+		ret = qcom_scm_pas_shutdown(adsp->pas_id);
+		retry_num--;
+	}
+
+	return ret;
+}
+
 static int adsp_unprepare(struct rproc *rproc)
 {
 	struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
@@ -249,6 +268,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_decrypt_shutdown(adsp);
+
 	if (ret)
 		dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
 
@@ -459,6 +481,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);
@@ -533,6 +556,7 @@  static const struct adsp_data adsp_resource_init = {
 		.pas_id = 1,
 		.has_aggre2_clk = false,
 		.auto_boot = true,
+		.decrypt_shutdown = false,
 		.ssr_name = "lpass",
 		.sysmon_name = "adsp",
 		.ssctl_id = 0x14,
@@ -544,6 +568,7 @@  static const struct adsp_data sdm845_adsp_resource_init = {
 		.pas_id = 1,
 		.has_aggre2_clk = false,
 		.auto_boot = true,
+		.decrypt_shutdown = false,
 		.load_state = "adsp",
 		.ssr_name = "lpass",
 		.sysmon_name = "adsp",
@@ -556,6 +581,7 @@  static const struct adsp_data sm6350_adsp_resource = {
 	.pas_id = 1,
 	.has_aggre2_clk = false,
 	.auto_boot = true,
+	.decrypt_shutdown = false,
 	.proxy_pd_names = (char*[]){
 		"lcx",
 		"lmx",
@@ -573,6 +599,7 @@  static const struct adsp_data sm8150_adsp_resource = {
 		.pas_id = 1,
 		.has_aggre2_clk = false,
 		.auto_boot = true,
+		.decrypt_shutdown = false,
 		.proxy_pd_names = (char*[]){
 			"cx",
 			NULL
@@ -589,6 +616,7 @@  static const struct adsp_data sm8250_adsp_resource = {
 	.pas_id = 1,
 	.has_aggre2_clk = false,
 	.auto_boot = true,
+	.decrypt_shutdown = false,
 	.proxy_pd_names = (char*[]){
 		"lcx",
 		"lmx",
@@ -606,6 +634,7 @@  static const struct adsp_data sm8350_adsp_resource = {
 	.pas_id = 1,
 	.has_aggre2_clk = false,
 	.auto_boot = true,
+	.decrypt_shutdown = false,
 	.proxy_pd_names = (char*[]){
 		"lcx",
 		"lmx",
@@ -623,6 +652,7 @@  static const struct adsp_data msm8996_adsp_resource = {
 		.pas_id = 1,
 		.has_aggre2_clk = false,
 		.auto_boot = true,
+		.decrypt_shutdown = false,
 		.proxy_pd_names = (char*[]){
 			"cx",
 			NULL
@@ -638,6 +668,7 @@  static const struct adsp_data cdsp_resource_init = {
 	.pas_id = 18,
 	.has_aggre2_clk = false,
 	.auto_boot = true,
+	.decrypt_shutdown = false,
 	.ssr_name = "cdsp",
 	.sysmon_name = "cdsp",
 	.ssctl_id = 0x17,
@@ -649,6 +680,7 @@  static const struct adsp_data sdm845_cdsp_resource_init = {
 	.pas_id = 18,
 	.has_aggre2_clk = false,
 	.auto_boot = true,
+	.decrypt_shutdown = false,
 	.load_state = "cdsp",
 	.ssr_name = "cdsp",
 	.sysmon_name = "cdsp",
@@ -661,6 +693,7 @@  static const struct adsp_data sm6350_cdsp_resource = {
 	.pas_id = 18,
 	.has_aggre2_clk = false,
 	.auto_boot = true,
+	.decrypt_shutdown = false,
 	.proxy_pd_names = (char*[]){
 		"cx",
 		"mx",
@@ -678,6 +711,7 @@  static const struct adsp_data sm8150_cdsp_resource = {
 	.pas_id = 18,
 	.has_aggre2_clk = false,
 	.auto_boot = true,
+	.decrypt_shutdown = false,
 	.proxy_pd_names = (char*[]){
 		"cx",
 		NULL
@@ -694,6 +728,7 @@  static const struct adsp_data sm8250_cdsp_resource = {
 	.pas_id = 18,
 	.has_aggre2_clk = false,
 	.auto_boot = true,
+	.decrypt_shutdown = false,
 	.proxy_pd_names = (char*[]){
 		"cx",
 		NULL
@@ -710,6 +745,7 @@  static const struct adsp_data sc8280xp_nsp0_resource = {
 	.pas_id = 18,
 	.has_aggre2_clk = false,
 	.auto_boot = true,
+	.decrypt_shutdown = false,
 	.proxy_pd_names = (char*[]){
 		"nsp",
 		NULL
@@ -725,6 +761,7 @@  static const struct adsp_data sc8280xp_nsp1_resource = {
 	.pas_id = 30,
 	.has_aggre2_clk = false,
 	.auto_boot = true,
+	.decrypt_shutdown = false,
 	.proxy_pd_names = (char*[]){
 		"nsp",
 		NULL
@@ -740,6 +777,7 @@  static const struct adsp_data sm8350_cdsp_resource = {
 	.pas_id = 18,
 	.has_aggre2_clk = false,
 	.auto_boot = true,
+	.decrypt_shutdown = false,
 	.proxy_pd_names = (char*[]){
 		"cx",
 		"mxc",
@@ -758,6 +796,26 @@  static const struct adsp_data mpss_resource_init = {
 	.minidump_id = 3,
 	.has_aggre2_clk = false,
 	.auto_boot = false,
+	.decrypt_shutdown = false,
+	.proxy_pd_names = (char*[]){
+		"cx",
+		"mss",
+		NULL
+	},
+	.load_state = "modem",
+	.ssr_name = "mpss",
+	.sysmon_name = "modem",
+	.ssctl_id = 0x12,
+};
+
+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",
@@ -775,6 +833,7 @@  static const struct adsp_data sc8180x_mpss_resource = {
 	.pas_id = 4,
 	.has_aggre2_clk = false,
 	.auto_boot = false,
+	.decrypt_shutdown = false,
 	.proxy_pd_names = (char*[]){
 		"cx",
 		NULL
@@ -791,6 +850,7 @@  static const struct adsp_data slpi_resource_init = {
 		.pas_id = 12,
 		.has_aggre2_clk = true,
 		.auto_boot = true,
+		.decrypt_shutdown = false,
 		.proxy_pd_names = (char*[]){
 			"ssc_cx",
 			NULL
@@ -806,6 +866,7 @@  static const struct adsp_data sm8150_slpi_resource = {
 		.pas_id = 12,
 		.has_aggre2_clk = false,
 		.auto_boot = true,
+		.decrypt_shutdown = false,
 		.proxy_pd_names = (char*[]){
 			"lcx",
 			"lmx",
@@ -823,6 +884,7 @@  static const struct adsp_data sm8250_slpi_resource = {
 	.pas_id = 12,
 	.has_aggre2_clk = false,
 	.auto_boot = true,
+	.decrypt_shutdown = false,
 	.proxy_pd_names = (char*[]){
 		"lcx",
 		"lmx",
@@ -840,6 +902,7 @@  static const struct adsp_data sm8350_slpi_resource = {
 	.pas_id = 12,
 	.has_aggre2_clk = false,
 	.auto_boot = true,
+	.decrypt_shutdown = false,
 	.proxy_pd_names = (char*[]){
 		"lcx",
 		"lmx",
@@ -856,6 +919,7 @@  static const struct adsp_data wcss_resource_init = {
 	.firmware_name = "wcnss.mdt",
 	.pas_id = 6,
 	.auto_boot = true,
+	.decrypt_shutdown = false,
 	.ssr_name = "mpss",
 	.sysmon_name = "wcnss",
 	.ssctl_id = 0x12,
@@ -867,6 +931,7 @@  static const struct adsp_data sdx55_mpss_resource = {
 	.pas_id = 4,
 	.has_aggre2_clk = false,
 	.auto_boot = true,
+	.decrypt_shutdown = false,
 	.proxy_pd_names = (char*[]){
 		"cx",
 		"mss",
@@ -916,7 +981,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);