diff options
Diffstat (limited to 'drivers/clk/qcom/gdsc.c')
-rw-r--r-- | drivers/clk/qcom/gdsc.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index e6bbb7608b57..da9fad8b642b 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -18,6 +18,7 @@ #include <linux/kernel.h> #include <linux/pm_domain.h> #include <linux/regmap.h> +#include <linux/reset-controller.h> #include <linux/slab.h> #include "gdsc.h" @@ -84,6 +85,24 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en) return -ETIMEDOUT; } +static inline int gdsc_deassert_reset(struct gdsc *sc) +{ + int i; + + for (i = 0; i < sc->reset_count; i++) + sc->rcdev->ops->deassert(sc->rcdev, sc->resets[i]); + return 0; +} + +static inline int gdsc_assert_reset(struct gdsc *sc) +{ + int i; + + for (i = 0; i < sc->reset_count; i++) + sc->rcdev->ops->assert(sc->rcdev, sc->resets[i]); + return 0; +} + static inline void gdsc_force_mem_on(struct gdsc *sc) { int i; @@ -107,6 +126,9 @@ static int gdsc_enable(struct generic_pm_domain *domain) struct gdsc *sc = domain_to_gdsc(domain); int ret; + if (sc->pwrsts == PWRSTS_ON) + return gdsc_deassert_reset(sc); + ret = gdsc_toggle_logic(sc, true); if (ret) return ret; @@ -130,6 +152,9 @@ static int gdsc_disable(struct generic_pm_domain *domain) { struct gdsc *sc = domain_to_gdsc(domain); + if (sc->pwrsts == PWRSTS_ON) + return gdsc_assert_reset(sc); + if (sc->pwrsts & PWRSTS_OFF) gdsc_clear_mem_on(sc); @@ -153,6 +178,13 @@ static int gdsc_init(struct gdsc *sc) if (ret) return ret; + /* Force gdsc ON if only ON state is supported */ + if (sc->pwrsts == PWRSTS_ON) { + ret = gdsc_toggle_logic(sc, true); + if (ret) + return ret; + } + on = gdsc_is_enabled(sc); if (on < 0) return on; @@ -170,7 +202,7 @@ static int gdsc_init(struct gdsc *sc) } int gdsc_register(struct device *dev, struct gdsc **scs, size_t num, - struct regmap *regmap) + struct reset_controller_dev *rcdev, struct regmap *regmap) { int i, ret; struct genpd_onecell_data *data; @@ -189,6 +221,7 @@ int gdsc_register(struct device *dev, struct gdsc **scs, size_t num, if (!scs[i]) continue; scs[i]->regmap = regmap; + scs[i]->rcdev = rcdev; ret = gdsc_init(scs[i]); if (ret) return ret; |