On Tue 26 Jan 15:18 CST 2021, Thara Gopinath wrote: > When bam dma is "controlled remotely", thus far clocks were not controlled > from the Linux. In this scenario, Linux was disabling runtime pm in bam dma > driver and not doing any clock management in suspend/resume hooks. > > With introduction of crypto engine bam dma, the clock is a rpmh resource > that can be controlled from both Linux and TZ/remote side. Now bam dma > clock is getting enabled during probe even though the bam dma can be > "controlled remotely". But due to clocks not being handled properly, > bam_suspend generates a unbalanced clk_unprepare warning during system > suspend. > > To fix the above issue and to enable proper clock-management, this patch > enables runtim-pm and handles bam dma clocks in suspend/resume hooks if > the clock node is present irrespective of controlled_remotely property. > > Signed-off-by: Thara Gopinath <thara.gopinath@xxxxxxxxxx> Reviewed-by: Bjorn Andersson <bjorn.andersson@xxxxxxxxxx> And from John on IRC: Tested-by: John Stultz <john.stultz@xxxxxxxxxx> Regards, Bjorn > --- > > v1->v2: > - As per Shawn's suggestion, use devm_clk_get_optional to get the > bam clock if the "controlled_remotely" property is set so that > the clock code takes care of setting the bam clock to NULL if > not specified by dt. > - Remove the check for "controlled_remotely" property in > bam_dma_resume now that clock enable / disable is based on > whether bamclk is NULL or not. > - Rebased to v5.11-rc5 > > drivers/dma/qcom/bam_dma.c | 29 +++++++++++++++-------------- > 1 file changed, 15 insertions(+), 14 deletions(-) > > diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c > index 88579857ca1d..c8a77b428b52 100644 > --- a/drivers/dma/qcom/bam_dma.c > +++ b/drivers/dma/qcom/bam_dma.c > @@ -1270,13 +1270,13 @@ static int bam_dma_probe(struct platform_device *pdev) > dev_err(bdev->dev, "num-ees unspecified in dt\n"); > } > > - bdev->bamclk = devm_clk_get(bdev->dev, "bam_clk"); > - if (IS_ERR(bdev->bamclk)) { > - if (!bdev->controlled_remotely) > - return PTR_ERR(bdev->bamclk); > + if (bdev->controlled_remotely) > + bdev->bamclk = devm_clk_get_optional(bdev->dev, "bam_clk"); > + else > + bdev->bamclk = devm_clk_get(bdev->dev, "bam_clk"); > > - bdev->bamclk = NULL; > - } > + if (IS_ERR(bdev->bamclk)) > + return PTR_ERR(bdev->bamclk); > > ret = clk_prepare_enable(bdev->bamclk); > if (ret) { > @@ -1350,7 +1350,7 @@ static int bam_dma_probe(struct platform_device *pdev) > if (ret) > goto err_unregister_dma; > > - if (bdev->controlled_remotely) { > + if (!bdev->bamclk) { > pm_runtime_disable(&pdev->dev); > return 0; > } > @@ -1438,10 +1438,10 @@ static int __maybe_unused bam_dma_suspend(struct device *dev) > { > struct bam_device *bdev = dev_get_drvdata(dev); > > - if (!bdev->controlled_remotely) > + if (bdev->bamclk) { > pm_runtime_force_suspend(dev); > - > - clk_unprepare(bdev->bamclk); > + clk_unprepare(bdev->bamclk); > + } > > return 0; > } > @@ -1451,12 +1451,13 @@ static int __maybe_unused bam_dma_resume(struct device *dev) > struct bam_device *bdev = dev_get_drvdata(dev); > int ret; > > - ret = clk_prepare(bdev->bamclk); > - if (ret) > - return ret; > + if (bdev->bamclk) { > + ret = clk_prepare(bdev->bamclk); > + if (ret) > + return ret; > > - if (!bdev->controlled_remotely) > pm_runtime_force_resume(dev); > + } > > return 0; > } > -- > 2.25.1 >