diff mbox series

[5/8] clk: qcom: lpasscc-sc7280: fix missing resume during probe

Message ID 20230718132902.21430-6-johan+linaro@kernel.org (mailing list archive)
State Accepted
Commit 66af5339d4f8e20c6d89a490570bd94d40f1a7f6
Headers show
Series clk: qcom: fix runtime PM bugs | expand

Commit Message

Johan Hovold July 18, 2023, 1:28 p.m. UTC
Drivers that enable runtime PM must make sure that the controller is
runtime resumed before accessing its registers to prevent the power
domain from being disabled.

Fixes: 4ab43d171181 ("clk: qcom: Add lpass clock controller driver for SC7280")
Cc: stable@vger.kernel.org      # 5.16
Cc: Taniya Das <quic_tdas@quicinc.com>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
 drivers/clk/qcom/lpasscc-sc7280.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

Comments

Bjorn Andersson July 18, 2023, 2:58 p.m. UTC | #1
On Tue, Jul 18, 2023 at 03:28:59PM +0200, Johan Hovold wrote:
> Drivers that enable runtime PM must make sure that the controller is
> runtime resumed before accessing its registers to prevent the power
> domain from being disabled.
> 

NB: the clock framework will runtime resume the controller surrounding
operations, even so during probe. But this is not done for resets and
gdscs - and in some clock drivers we poke registers directly from
probe...

The one time this really matters is where we associate the ahb clock
with the runtime state, e.g. in qcs404 turingcc. On most other platforms
we just mark these clocks always-on in gcc...

Regards,
Bjorn

> Fixes: 4ab43d171181 ("clk: qcom: Add lpass clock controller driver for SC7280")
> Cc: stable@vger.kernel.org      # 5.16
> Cc: Taniya Das <quic_tdas@quicinc.com>
> Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
> ---
>  drivers/clk/qcom/lpasscc-sc7280.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/clk/qcom/lpasscc-sc7280.c b/drivers/clk/qcom/lpasscc-sc7280.c
> index 0df2b29e95e3..e6b815aec46a 100644
> --- a/drivers/clk/qcom/lpasscc-sc7280.c
> +++ b/drivers/clk/qcom/lpasscc-sc7280.c
> @@ -118,9 +118,13 @@ static int lpass_cc_sc7280_probe(struct platform_device *pdev)
>  	ret = pm_clk_add(&pdev->dev, "iface");
>  	if (ret < 0) {
>  		dev_err(&pdev->dev, "failed to acquire iface clock\n");
> -		goto destroy_pm_clk;
> +		goto err_destroy_pm_clk;
>  	}
>  
> +	ret = pm_runtime_resume_and_get(&pdev->dev);
> +	if (ret)
> +		goto err_destroy_pm_clk;
> +
>  	if (!of_property_read_bool(pdev->dev.of_node, "qcom,adsp-pil-mode")) {
>  		lpass_regmap_config.name = "qdsp6ss";
>  		lpass_regmap_config.max_register = 0x3f;
> @@ -128,7 +132,7 @@ static int lpass_cc_sc7280_probe(struct platform_device *pdev)
>  
>  		ret = qcom_cc_probe_by_index(pdev, 0, desc);
>  		if (ret)
> -			goto destroy_pm_clk;
> +			goto err_put_rpm;
>  	}
>  
>  	lpass_regmap_config.name = "top_cc";
> @@ -137,11 +141,15 @@ static int lpass_cc_sc7280_probe(struct platform_device *pdev)
>  
>  	ret = qcom_cc_probe_by_index(pdev, 1, desc);
>  	if (ret)
> -		goto destroy_pm_clk;
> +		goto err_put_rpm;
> +
> +	pm_runtime_put(&pdev->dev);
>  
>  	return 0;
>  
> -destroy_pm_clk:
> +err_put_rpm:
> +	pm_runtime_put_sync(&pdev->dev);
> +err_destroy_pm_clk:
>  	pm_clk_destroy(&pdev->dev);
>  
>  	return ret;
> -- 
> 2.41.0
>
Johan Hovold July 18, 2023, 3:39 p.m. UTC | #2
On Tue, Jul 18, 2023 at 07:58:41AM -0700, Bjorn Andersson wrote:
> On Tue, Jul 18, 2023 at 03:28:59PM +0200, Johan Hovold wrote:
> > Drivers that enable runtime PM must make sure that the controller is
> > runtime resumed before accessing its registers to prevent the power
> > domain from being disabled.
> > 
> 
> NB: the clock framework will runtime resume the controller surrounding
> operations, even so during probe. But this is not done for resets and
> gdscs - and in some clock drivers we poke registers directly from
> probe...
> 
> The one time this really matters is where we associate the ahb clock
> with the runtime state, e.g. in qcs404 turingcc. On most other platforms
> we just mark these clocks always-on in gcc...

Right, I started looking at this with respect to the PM domain, but
my initial commit message only mentioned the need to make sure the
controller is resumed, which would have covered such interface clocks as
well. 

And while ending up with a concurrent request to disable the PM domain
is not that likely, there is currently nothing preventing it so it still
needs to be fixed.

Johan
diff mbox series

Patch

diff --git a/drivers/clk/qcom/lpasscc-sc7280.c b/drivers/clk/qcom/lpasscc-sc7280.c
index 0df2b29e95e3..e6b815aec46a 100644
--- a/drivers/clk/qcom/lpasscc-sc7280.c
+++ b/drivers/clk/qcom/lpasscc-sc7280.c
@@ -118,9 +118,13 @@  static int lpass_cc_sc7280_probe(struct platform_device *pdev)
 	ret = pm_clk_add(&pdev->dev, "iface");
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to acquire iface clock\n");
-		goto destroy_pm_clk;
+		goto err_destroy_pm_clk;
 	}
 
+	ret = pm_runtime_resume_and_get(&pdev->dev);
+	if (ret)
+		goto err_destroy_pm_clk;
+
 	if (!of_property_read_bool(pdev->dev.of_node, "qcom,adsp-pil-mode")) {
 		lpass_regmap_config.name = "qdsp6ss";
 		lpass_regmap_config.max_register = 0x3f;
@@ -128,7 +132,7 @@  static int lpass_cc_sc7280_probe(struct platform_device *pdev)
 
 		ret = qcom_cc_probe_by_index(pdev, 0, desc);
 		if (ret)
-			goto destroy_pm_clk;
+			goto err_put_rpm;
 	}
 
 	lpass_regmap_config.name = "top_cc";
@@ -137,11 +141,15 @@  static int lpass_cc_sc7280_probe(struct platform_device *pdev)
 
 	ret = qcom_cc_probe_by_index(pdev, 1, desc);
 	if (ret)
-		goto destroy_pm_clk;
+		goto err_put_rpm;
+
+	pm_runtime_put(&pdev->dev);
 
 	return 0;
 
-destroy_pm_clk:
+err_put_rpm:
+	pm_runtime_put_sync(&pdev->dev);
+err_destroy_pm_clk:
 	pm_clk_destroy(&pdev->dev);
 
 	return ret;