On Mon, Nov 18, 2024 at 02:24:33AM +0000, Bryan O'Donoghue wrote: > Introduce pm_runtime_get() and pm_runtime_put_sync() on the > gdsc_toggle_logic(). > > This allows for the switching of the GDSC on/off to propagate to the parent > clock controller and consequently for any list of power-domains powering > that controller to be switched on/off. What is the end result of this patch? Does it bring up a single PM domain or all of them? Or should it be a part of the driver's PM callbacks? If the CC has multiple parent PM domains, shouldn't we also use some of them as GDSC's parents? > > Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@xxxxxxxxxx> > --- > drivers/clk/qcom/gdsc.c | 26 ++++++++++++++++++-------- > drivers/clk/qcom/gdsc.h | 2 ++ > 2 files changed, 20 insertions(+), 8 deletions(-) > > diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c > index fa5fe4c2a2ee7786c2e8858f3e41301f639e5d59..ff5df942147f87e0df24a70cf9ee53bb2df36e54 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> > @@ -141,10 +142,14 @@ static int gdsc_toggle_logic(struct gdsc *sc, enum gdsc_status status, > { > int ret; > > - if (status == GDSC_ON && sc->rsupply) { > - ret = regulator_enable(sc->rsupply); > - if (ret < 0) > - return ret; > + if (status == GDSC_ON) { > + if (sc->rsupply) { > + ret = regulator_enable(sc->rsupply); > + if (ret < 0) > + return ret; > + } > + if (pm_runtime_enabled(sc->dev)) > + pm_runtime_resume_and_get(sc->dev); > } > > ret = gdsc_update_collapse_bit(sc, status == GDSC_OFF); > @@ -177,10 +182,14 @@ static int gdsc_toggle_logic(struct gdsc *sc, enum gdsc_status status, > ret = gdsc_poll_status(sc, status); > WARN(ret, "%s status stuck at 'o%s'", sc->pd.name, status ? "ff" : "n"); > > - if (!ret && status == GDSC_OFF && sc->rsupply) { > - ret = regulator_disable(sc->rsupply); > - if (ret < 0) > - return ret; > + if (!ret && status == GDSC_OFF) { > + if (pm_runtime_enabled(sc->dev)) > + pm_runtime_put_sync(sc->dev); > + if (sc->rsupply) { > + ret = regulator_disable(sc->rsupply); > + if (ret < 0) > + return ret; > + } > } > > return ret; > @@ -544,6 +553,7 @@ int gdsc_register(struct gdsc_desc *desc, > continue; > scs[i]->regmap = regmap; > scs[i]->rcdev = rcdev; > + scs[i]->dev = dev; > ret = gdsc_init(scs[i]); > if (ret) > return ret; > diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h > index 1e2779b823d1c8ca077c9b4cd0a0dbdf5f9457ef..71ca02c78c5d089cdf96deadc417982ad6079255 100644 > --- a/drivers/clk/qcom/gdsc.h > +++ b/drivers/clk/qcom/gdsc.h > @@ -30,6 +30,7 @@ struct reset_controller_dev; > * @resets: ids of resets associated with this gdsc > * @reset_count: number of @resets > * @rcdev: reset controller > + * @dev: device associated with this gdsc > */ > struct gdsc { > struct generic_pm_domain pd; > @@ -74,6 +75,7 @@ struct gdsc { > > const char *supply; > struct regulator *rsupply; > + struct device *dev; > }; > > struct gdsc_desc { > > -- > 2.45.2 > -- With best wishes Dmitry