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 4/7] clk: qcom: gdsc: call runtime PM functions for the provider device
Date: Fri, 9 Jul 2021 19:53:10 -0500	[thread overview]
Message-ID: <YOjvdmCAhVC+s2OP@yoga> (raw)
In-Reply-To: <613b2f07-ffea-9c65-ebd0-6ad3b4fe10b8@linaro.org>

On Fri 09 Jul 17:10 CDT 2021, Dmitry Baryshkov wrote:

> On 09/07/2021 21:54, Bjorn Andersson wrote:
> > On Fri 09 Jul 12:31 CDT 2021, Dmitry Baryshkov wrote:
> > 
> > > In order to properly handle runtime PM status of the provider device,
> > > call pm_runtime_get/pm_runtime_put on the clock controller device.
> > > 
> > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > > ---
> > >   drivers/clk/qcom/gdsc.c | 66 ++++++++++++++++++++++++++++++++++++++---
> > >   drivers/clk/qcom/gdsc.h |  2 ++
> > >   2 files changed, 64 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
> > > index ccd36617d067..6bec31fccb09 100644
> > > --- a/drivers/clk/qcom/gdsc.c
> > > +++ b/drivers/clk/qcom/gdsc.c
> > > @@ -11,6 +11,7 @@
> > >   #include <linux/kernel.h>
> > >   #include <linux/ktime.h>
> > >   #include <linux/pm_domain.h>
> > > +#include <linux/pm_runtime.h>
> > >   #include <linux/regmap.h>
> > >   #include <linux/regulator/consumer.h>
> > >   #include <linux/reset-controller.h>
> > > @@ -50,6 +51,30 @@ enum gdsc_status {
> > >   	GDSC_ON
> > >   };
> > > +static int gdsc_pm_runtime_get(struct gdsc *sc)
> > > +{
> > > +	int ret;
> > > +
> > > +	if (!sc->rpm_dev)
> > > +		return 0;
> > > +
> > > +	ret = pm_runtime_get_sync(sc->rpm_dev);
> > > +	if (ret < 0) {
> > > +		pm_runtime_put_noidle(sc->rpm_dev);
> > > +		return ret;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int gdsc_pm_runtime_put(struct gdsc *sc)
> > > +{
> > > +	if (!sc->rpm_dev)
> > > +		return 0;
> > > +
> > > +	return pm_runtime_put_sync(sc->rpm_dev);
> > > +}
> > > +
> > >   /* Returns 1 if GDSC status is status, 0 if not, and < 0 on error */
> > >   static int gdsc_check_status(struct gdsc *sc, enum gdsc_status status)
> > >   {
> > > @@ -232,9 +257,8 @@ static void gdsc_retain_ff_on(struct gdsc *sc)
> > >   	regmap_update_bits(sc->regmap, sc->gdscr, mask, mask);
> > >   }
> > > -static int gdsc_enable(struct generic_pm_domain *domain)
> > > +static int _gdsc_enable(struct gdsc *sc)
> > >   {
> > > -	struct gdsc *sc = domain_to_gdsc(domain);
> > >   	int ret;
> > >   	if (sc->pwrsts == PWRSTS_ON)
> > > @@ -290,11 +314,28 @@ static int gdsc_enable(struct generic_pm_domain *domain)
> > >   	return 0;
> > >   }
> > > -static int gdsc_disable(struct generic_pm_domain *domain)
> > > +static int gdsc_enable(struct generic_pm_domain *domain)
> > >   {
> > >   	struct gdsc *sc = domain_to_gdsc(domain);
> > >   	int ret;
> > > +	ret = gdsc_pm_runtime_get(sc);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	ret = _gdsc_enable(sc);
> > > +	if (ret) {
> > > +		gdsc_pm_runtime_put(sc);
> > 
> > I presume what you do here is to leave the pm_runtime state of dispcc
> > active if we succeeded in enabling the gdsc. But the gdsc is a subdomain
> > of the parent domain, so the framework should take case of its
> > dependency.
> > 
> > So the reason for gdsc_pm_runtime_get()/put() in this code path is so
> > that you can access the dispcc registers, i.e. I think you should
> > get()/put() regardless of the return value.
> 
> pm domain code will handle enabling MMCX, so this code is not required
> strictly speaking. Ulf suggested adding it back, so I followed the
> suggestion. Maybe I misunderstood his suggestion.
> 
> putting pm_runtime after gdsc_enable does not sound like a logical case.
> However it would simplify code a bit. Let me try...
> 

If you consider this device's and the individual gdsc's power state as
separate consumers of MMCX, then it perhaps makes more sense?

Similar to how a regulator driver would rely on the regulator framework
to deal with parent regulators...

Regards,
Bjorn

> > 
> > > +		return ret;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int _gdsc_disable(struct gdsc *sc)
> > > +{
> > > +	int ret;
> > > +
> > >   	if (sc->pwrsts == PWRSTS_ON)
> > >   		return gdsc_assert_reset(sc);
> > > @@ -329,6 +370,18 @@ static int gdsc_disable(struct generic_pm_domain *domain)
> > >   	return 0;
> > >   }
> > > +static int gdsc_disable(struct generic_pm_domain *domain)
> > > +{
> > > +	struct gdsc *sc = domain_to_gdsc(domain);
> > > +	int ret;
> > > +
> > 
> > If the gdsc is found to be on at initialization, the next operation that
> > will happen is gdsc_disable() and as you didn't activate the pm_runtime
> > state in gdsc_init() you would in theory get here with registers
> > unaccessible.
> > 
> > In practice though, the active gdsc should through the being a subdomain
> > of the parent domain keep power on for you, so you won't notice this
> > issue.
> 
> Nice catch.
> 
> > 
> > But as above, I think you should wrap _gdsc_disable() in a get()/put()
> > pair.
> > 
> > > +	ret = _gdsc_disable(sc);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	return gdsc_pm_runtime_put(sc);
> > > +}
> > > +
> > >   static int gdsc_init(struct gdsc *sc)
> > >   {
> > >   	u32 mask, val;
> > > @@ -425,6 +478,8 @@ int gdsc_register(struct gdsc_desc *desc,
> > >   	for (i = 0; i < num; i++) {
> > >   		if (!scs[i])
> > >   			continue;
> > > +		if (pm_runtime_enabled(dev))
> > > +			scs[i]->rpm_dev = dev;
> > >   		scs[i]->regmap = regmap;
> > >   		scs[i]->rcdev = rcdev;
> > >   		ret = gdsc_init(scs[i]);
> > > @@ -486,7 +541,10 @@ void gdsc_unregister(struct gdsc_desc *desc)
> > >    */
> > >   int gdsc_gx_do_nothing_enable(struct generic_pm_domain *domain)
> > >   {
> > > +	struct gdsc *sc = domain_to_gdsc(domain);
> > > +
> > >   	/* Do nothing but give genpd the impression that we were successful */
> > > -	return 0;
> > > +	/* Get the runtime PM device only */
> > > +	return gdsc_pm_runtime_get(sc);
> > 
> > Per above, if you let the framework deal with the gdsc's dependencies on
> > the parent domain and you only get()/put() for the sake of dispcc then
> > you don't need you don't need to do this to keep the subsequent
> > gdsc_disable() in balance.
> > 
> > >   }
> > >   EXPORT_SYMBOL_GPL(gdsc_gx_do_nothing_enable);
> > > diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
> > > index 5bb396b344d1..a82982df0a55 100644
> > > --- a/drivers/clk/qcom/gdsc.h
> > > +++ b/drivers/clk/qcom/gdsc.h
> > > @@ -25,6 +25,7 @@ struct reset_controller_dev;
> > >    * @resets: ids of resets associated with this gdsc
> > >    * @reset_count: number of @resets
> > >    * @rcdev: reset controller
> > > + * @rpm_dev: runtime PM device
> > >    */
> > >   struct gdsc {
> > >   	struct generic_pm_domain	pd;
> > > @@ -58,6 +59,7 @@ struct gdsc {
> > >   	const char 			*supply;
> > >   	struct regulator		*rsupply;
> > > +	struct device 			*rpm_dev;
> > 
> > This isn't just the "runtime pm device", it's the device this gdsc is
> > associated with. So "dev" sounds sufficient to me, but that requires
> > that you have a separate bool rpm_enabled to remember if
> > pm_runtime_enabled() was true during probe.
> > 
> > So unless we need "dev" for something else this might be sufficient.
> > 
> > Regards,
> > Bjorn
> > 
> > >   };
> > >   struct gdsc_desc {
> > > -- 
> > > 2.30.2
> > > 
> 
> 
> -- 
> With best wishes
> Dmitry

  reply	other threads:[~2021-07-10  0:53 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
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 [this message]
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=YOjvdmCAhVC+s2OP@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.