All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bjorn Andersson <bjorn.andersson@linaro.org>
To: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Cc: Andy Gross <agross@kernel.org>, Rob Herring <robh+dt@kernel.org>,
	Stephen Boyd <sboyd@kernel.org>, Taniya Das <tdas@codeaurora.org>,
	Jonathan Marek <jonathan@marek.ca>,
	Michael Turquette <mturquette@baylibre.com>,
	linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org,
	linux-clk@vger.kernel.org,
	Bryan O'Donoghue <bryan.odonoghue@linaro.org>,
	Mark Brown <broonie@kernel.org>,
	Ulf Hansson <ulf.hansson@linaro.org>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 3/7] clk: qcom: gdsc: enable optional power domain support
Date: Fri, 9 Jul 2021 19:48:21 -0500	[thread overview]
Message-ID: <YOjuVaaQM8G1rnNf@yoga> (raw)
In-Reply-To: <35110e0e-5223-d3c6-51e4-03d96951bd4a@linaro.org>

On Fri 09 Jul 16:28 CDT 2021, Dmitry Baryshkov wrote:

> On 09/07/2021 21:38, Bjorn Andersson wrote:
> > On Fri 09 Jul 12:31 CDT 2021, Dmitry Baryshkov wrote:
> > 
> > > On sm8250 dispcc and videocc registers are powered up by the MMCX power
> > > domain. Currently we use a regulator to enable this domain on demand,
> > > however this has some consequences, as genpd code is not reentrant.
> > > 
> > > Teach Qualcomm clock controller code about setting up runtime PM and
> > > using specified for gdsc powerup.
> > > 
> > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > > ---
> > >   drivers/clk/qcom/common.c | 37 +++++++++++++++++++++++++++++++------
> > >   drivers/clk/qcom/gdsc.c   |  4 ++++
> > >   2 files changed, 35 insertions(+), 6 deletions(-)
> > > 
> > > diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
> > > index 60d2a78d1395..43d8f8feeb3c 100644
> > > --- a/drivers/clk/qcom/common.c
> > > +++ b/drivers/clk/qcom/common.c
> > > @@ -10,6 +10,7 @@
> > >   #include <linux/clk-provider.h>
> > >   #include <linux/reset-controller.h>
> > >   #include <linux/of.h>
> > > +#include <linux/pm_runtime.h>
> > >   #include "common.h"
> > >   #include "clk-rcg.h"
> > > @@ -224,6 +225,11 @@ static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec,
> > >   	return cc->rclks[idx] ? &cc->rclks[idx]->hw : NULL;
> > >   }
> > > +static void qcom_cc_pm_runtime_disable(void *data)
> > > +{
> > > +	pm_runtime_disable(data);
> > > +}
> > > +
> > >   int qcom_cc_really_probe(struct platform_device *pdev,
> > >   			 const struct qcom_cc_desc *desc, struct regmap *regmap)
> > >   {
> > > @@ -241,6 +247,18 @@ int qcom_cc_really_probe(struct platform_device *pdev,
> > >   	if (!cc)
> > >   		return -ENOMEM;
> > > +	pm_runtime_enable(dev);
> > 
> > In turingcc-qcs404.c I'm using pm_runtime to have the clock framework
> > ensure that the iface clock is enabled during clock operations, so this
> > will result in a "unbalanced enable" warning.
> 
> And later I register the disabler:
> 
>  ret = devm_add_action_or_reset(dev, qcom_cc_pm_runtime_disable, dev);
> 
> You might want to add this to qcs404 code.
> 

Let's land it using the apis that exist, then I think there's plenty of
examples throughout the kernel to make a case for introducing
devm_pm_clk_create() and devm_pm_runtime_enable().

But introducing that would complicate the path your patches would have
to take towards mainline.

> > 
> > > +	ret = pm_runtime_get_sync(dev);
> > 
> > I don't think you should wrap the entire initialization in a
> > pm_runtime_get_sync()/put() region. Instead follow the clock framework
> > and wrap gdsc initialization that needs to touch the hardware in:
> 
> Init should be wrapped in the pm_runtime_get/put calls, so that the MMCX
> domain is on through the fall init sequence. Otherwise it can get turned off
> during it, boom, failed register access and reboot.
> 

Right, we need to wrap init in pm_runtime_get()/put(), to ensure that
the registers are accessible. But the clock code has these surrounding
the initialization and therefor I think you should do the same in
gdsc_init() - instead of here.

> > 
> > 	if (pm_runtime_enabled())
> > 		pm_runtime_get_sync();
> 
> I don't think it's worth doing that. Having single lock for the whole init
> sequence is safer (and cleaner).
> 

Right, you need to cache the pm_runtime_enabled(), just as is done with
core->rpm_enabled in the clock framework.

The majority of the code involved in dispcc's initialization already has
more granular pm_runtime_get()/put() sections, so I don't think you
should override that with a big section here.

> If you check other pm-enabled drivers, they would either call
> pm_runtime_enable at the end of the probe or get_sync in the beginning of
> the probe and put_FOO in the end. In this driver calling pm_runtime_enable()
> at the end of the probe function will not work, since this way clk subsystem
> will not pick up the device for runtime power management (as
> pm_runtime_enabled() would return false).
> 

Right, just as turingcc does, we need to call pm_runtime_enable() early
and gdsc needs to check during initialization if pm_runtime should be
used for the particular clock controller.

> > 
> > I do however think that as of this patch, when probe returns MMCX might
> > very well be turned off, as the only user (this driver) has pm_runtime
> > enabled and it's idle. So I think you should introduce the
> > pm_runtime_get()/put() in the gdsc functions before this patch.
> 
> Maybe I'd just squash them together.
> 

With what I suggest the two patches are reduced to adding pm_runtime
support in the gdsc driver, and then a separate patch adding
pm_runtime_enable() in dispcc and videocc.

> > 
> > 
> > To summarize, I think you should rely on the individual clock drivers to
> > pm_runtime_enable()/disable().
> > 
> > > +	if (ret < 0) {
> > > +		pm_runtime_put(dev);
> > > +		pm_runtime_disable(dev);
> > > +		return ret;
> > > +	}
> > > +
> > > +	ret = devm_add_action_or_reset(dev, qcom_cc_pm_runtime_disable, dev);
> > > +	if (ret)
> > > +		goto err;
> > > +
> > >   	reset = &cc->reset;
> > >   	reset->rcdev.of_node = dev->of_node;
> > >   	reset->rcdev.ops = &qcom_reset_ops;
> > > @@ -251,7 +269,7 @@ int qcom_cc_really_probe(struct platform_device *pdev,
> > >   	ret = devm_reset_controller_register(dev, &reset->rcdev);
> > >   	if (ret)
> > > -		return ret;
> > > +		goto err;
> > >   	if (desc->gdscs && desc->num_gdscs) {
> > >   		scd = devm_kzalloc(dev, sizeof(*scd), GFP_KERNEL);
> > > @@ -262,11 +280,11 @@ int qcom_cc_really_probe(struct platform_device *pdev,
> > >   		scd->num = desc->num_gdscs;
> > >   		ret = gdsc_register(scd, &reset->rcdev, regmap);
> > >   		if (ret)
> > > -			return ret;
> > > +			goto err;
> > >   		ret = devm_add_action_or_reset(dev, qcom_cc_gdsc_unregister,
> > >   					       scd);
> > >   		if (ret)
> > > -			return ret;
> > > +			goto err;
> > >   	}
> > >   	cc->rclks = rclks;
> > > @@ -277,7 +295,7 @@ int qcom_cc_really_probe(struct platform_device *pdev,
> > >   	for (i = 0; i < num_clk_hws; i++) {
> > >   		ret = devm_clk_hw_register(dev, clk_hws[i]);
> > >   		if (ret)
> > > -			return ret;
> > > +			goto err;
> > >   	}
> > >   	for (i = 0; i < num_clks; i++) {
> > > @@ -286,14 +304,21 @@ int qcom_cc_really_probe(struct platform_device *pdev,
> > >   		ret = devm_clk_register_regmap(dev, rclks[i]);
> > >   		if (ret)
> > > -			return ret;
> > > +			goto err;
> > >   	}
> > >   	ret = devm_of_clk_add_hw_provider(dev, qcom_cc_clk_hw_get, cc);
> > >   	if (ret)
> > > -		return ret;
> > > +		goto err;
> > > +
> > > +	pm_runtime_put(dev);
> > >   	return 0;
> > > +
> > > +err:
> > > +	pm_runtime_put(dev);
> > > +
> > > +	return ret;
> > >   }
> > >   EXPORT_SYMBOL_GPL(qcom_cc_really_probe);
> > > diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
> > > index 51ed640e527b..ccd36617d067 100644
> > > --- a/drivers/clk/qcom/gdsc.c
> > > +++ b/drivers/clk/qcom/gdsc.c
> > > @@ -439,6 +439,8 @@ int gdsc_register(struct gdsc_desc *desc,
> > >   			continue;
> > >   		if (scs[i]->parent)
> > >   			pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd);
> > > +		else if (!IS_ERR_OR_NULL(dev->pm_domain))
> > > +			pm_genpd_add_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd);
> > 
> > Nice, I didn't know that we could fish it out of the dev.
> > 
> > Regards,
> > Bjorn
> > 
> > >   	}
> > >   	return of_genpd_add_provider_onecell(dev->of_node, data);
> > > @@ -457,6 +459,8 @@ void gdsc_unregister(struct gdsc_desc *desc)
> > >   			continue;
> > >   		if (scs[i]->parent)
> > >   			pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd);
> > > +		else if (!IS_ERR_OR_NULL(dev->pm_domain))
> > > +			pm_genpd_remove_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd);
> > >   	}
> > >   	of_genpd_del_provider(dev->of_node);
> > >   }
> > > -- 
> > > 2.30.2
> > > 
> 
> 
> -- 
> With best wishes
> Dmitry

  reply	other threads:[~2021-07-10  0:48 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-09 17:31 [PATCH v3 0/7] clk: qcom: use power-domain for sm8250's clock controllers Dmitry Baryshkov
2021-07-09 17:31 ` [PATCH v3 1/7] dt-bindings: clock: qcom,dispcc-sm8x50: add mmcx power domain Dmitry Baryshkov
2021-07-09 18:54   ` Bjorn Andersson
2021-07-09 17:31 ` [PATCH v3 2/7] dt-bindings: clock: qcom,videocc: " Dmitry Baryshkov
2021-07-09 18:55   ` Bjorn Andersson
2021-07-09 17:31 ` [PATCH v3 3/7] clk: qcom: gdsc: enable optional power domain support Dmitry Baryshkov
2021-07-09 18:38   ` Bjorn Andersson
2021-07-09 21:28     ` Dmitry Baryshkov
2021-07-10  0:48       ` Bjorn Andersson [this message]
2021-07-09 17:31 ` [PATCH v3 4/7] clk: qcom: gdsc: call runtime PM functions for the provider device Dmitry Baryshkov
2021-07-09 18:54   ` Bjorn Andersson
2021-07-09 22:10     ` Dmitry Baryshkov
2021-07-10  0:53       ` Bjorn Andersson
2021-07-09 17:32 ` [PATCH v3 5/7] arm64: dts: qcom: sm8250: remove mmcx regulator Dmitry Baryshkov
2021-07-09 18:55   ` Bjorn Andersson
2021-07-09 17:32 ` [PATCH v3 6/7] clk: qcom: dispcc-sm8250: stop using " Dmitry Baryshkov
2021-07-09 18:55   ` Bjorn Andersson
2021-07-09 17:32 ` [PATCH v3 7/7] clk: qcom: videocc-sm8250: " Dmitry Baryshkov
2021-07-09 18:55   ` Bjorn Andersson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YOjuVaaQM8G1rnNf@yoga \
    --to=bjorn.andersson@linaro.org \
    --cc=agross@kernel.org \
    --cc=broonie@kernel.org \
    --cc=bryan.odonoghue@linaro.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dmitry.baryshkov@linaro.org \
    --cc=jonathan@marek.ca \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mturquette@baylibre.com \
    --cc=robh+dt@kernel.org \
    --cc=sboyd@kernel.org \
    --cc=tdas@codeaurora.org \
    --cc=ulf.hansson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.