Skip to content

Commit 9711759

Browse files
anderssonbebarino
authored andcommitted
clk: qcom: gdsc: Ensure regulator init state matches GDSC state
As GDSCs are registered and found to be already enabled gdsc_init() ensures that 1) the kernel state matches the hardware state, and 2) votable GDSCs are properly enabled from this master as well. But as the (optional) supply regulator is enabled deep into gdsc_toggle_logic(), which is only executed for votable GDSCs, the kernel's state of the regulator might not match the hardware. The regulator might be automatically turned off if no other users are present or the next call to gdsc_disable() would cause an unbalanced regulator_disable(). Given that the votable case deals with an already enabled GDSC, most of gdsc_enable() and gdsc_toggle_logic() can be skipped. Reduce it to just clearing the SW_COLLAPSE_MASK and enabling hardware control to simply call regulator_enable() in both cases. The enablement of hardware control seems to be an independent property from the GDSC being enabled, so this is moved outside that conditional segment. Lastly, as the propagation of ALWAYS_ON to GENPD_FLAG_ALWAYS_ON needs to happen regardless of the initial state this is grouped together with the other sc->pd updates at the end of the function. Cc: [email protected] Fixes: 37416e5 ("clk: qcom: gdsc: Handle GDSC regulator supplies") Signed-off-by: Bjorn Andersson <[email protected]> Link: https://lore.kernel.org/r/[email protected] [[email protected]: Rephrase commit text] Signed-off-by: Stephen Boyd <[email protected]>
1 parent 283f1b9 commit 9711759

File tree

1 file changed

+36
-18
lines changed

1 file changed

+36
-18
lines changed

drivers/clk/qcom/gdsc.c

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -357,34 +357,52 @@ static int gdsc_init(struct gdsc *sc)
357357
if (on < 0)
358358
return on;
359359

360-
/*
361-
* Votable GDSCs can be ON due to Vote from other masters.
362-
* If a Votable GDSC is ON, make sure we have a Vote.
363-
*/
364-
if ((sc->flags & VOTABLE) && on)
365-
gdsc_enable(&sc->pd);
360+
if (on) {
361+
/* The regulator must be on, sync the kernel state */
362+
if (sc->rsupply) {
363+
ret = regulator_enable(sc->rsupply);
364+
if (ret < 0)
365+
return ret;
366+
}
366367

367-
/*
368-
* Make sure the retain bit is set if the GDSC is already on, otherwise
369-
* we end up turning off the GDSC and destroying all the register
370-
* contents that we thought we were saving.
371-
*/
372-
if ((sc->flags & RETAIN_FF_ENABLE) && on)
373-
gdsc_retain_ff_on(sc);
368+
/*
369+
* Votable GDSCs can be ON due to Vote from other masters.
370+
* If a Votable GDSC is ON, make sure we have a Vote.
371+
*/
372+
if (sc->flags & VOTABLE) {
373+
ret = regmap_update_bits(sc->regmap, sc->gdscr,
374+
SW_COLLAPSE_MASK, val);
375+
if (ret)
376+
return ret;
377+
}
378+
379+
/* Turn on HW trigger mode if supported */
380+
if (sc->flags & HW_CTRL) {
381+
ret = gdsc_hwctrl(sc, true);
382+
if (ret < 0)
383+
return ret;
384+
}
374385

375-
/* If ALWAYS_ON GDSCs are not ON, turn them ON */
376-
if (sc->flags & ALWAYS_ON) {
377-
if (!on)
378-
gdsc_enable(&sc->pd);
386+
/*
387+
* Make sure the retain bit is set if the GDSC is already on,
388+
* otherwise we end up turning off the GDSC and destroying all
389+
* the register contents that we thought we were saving.
390+
*/
391+
if (sc->flags & RETAIN_FF_ENABLE)
392+
gdsc_retain_ff_on(sc);
393+
} else if (sc->flags & ALWAYS_ON) {
394+
/* If ALWAYS_ON GDSCs are not ON, turn them ON */
395+
gdsc_enable(&sc->pd);
379396
on = true;
380-
sc->pd.flags |= GENPD_FLAG_ALWAYS_ON;
381397
}
382398

383399
if (on || (sc->pwrsts & PWRSTS_RET))
384400
gdsc_force_mem_on(sc);
385401
else
386402
gdsc_clear_mem_on(sc);
387403

404+
if (sc->flags & ALWAYS_ON)
405+
sc->pd.flags |= GENPD_FLAG_ALWAYS_ON;
388406
if (!sc->pd.power_off)
389407
sc->pd.power_off = gdsc_disable;
390408
if (!sc->pd.power_on)

0 commit comments

Comments
 (0)