summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/qcom/gdsc.c23
-rw-r--r--drivers/clk/qcom/gdsc.h4
2 files changed, 27 insertions, 0 deletions
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index a250f59708d8..04944f11659b 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -11,6 +11,7 @@
#include <linux/ktime.h>
#include <linux/pm_domain.h>
#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
#include <linux/reset-controller.h>
#include <linux/slab.h>
#include "gdsc.h"
@@ -112,6 +113,12 @@ static int gdsc_toggle_logic(struct gdsc *sc, enum gdsc_status status)
int ret;
u32 val = (status == GDSC_ON) ? 0 : SW_COLLAPSE_MASK;
+ if (status == GDSC_ON && sc->rsupply) {
+ ret = regulator_enable(sc->rsupply);
+ if (ret < 0)
+ return ret;
+ }
+
ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val);
if (ret)
return ret;
@@ -143,6 +150,13 @@ 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;
+ }
+
return ret;
}
@@ -371,6 +385,15 @@ int gdsc_register(struct gdsc_desc *desc,
if (!data->domains)
return -ENOMEM;
+ for (i = 0; i < num; i++) {
+ if (!scs[i] || !scs[i]->supply)
+ continue;
+
+ scs[i]->rsupply = devm_regulator_get(dev, scs[i]->supply);
+ if (IS_ERR(scs[i]->rsupply))
+ return PTR_ERR(scs[i]->rsupply);
+ }
+
data->num_domains = num;
for (i = 0; i < num; i++) {
if (!scs[i])
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index 64cdc8cf0d4d..c36fc26dcdff 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -10,6 +10,7 @@
#include <linux/pm_domain.h>
struct regmap;
+struct regulator;
struct reset_controller_dev;
/**
@@ -52,6 +53,9 @@ struct gdsc {
struct reset_controller_dev *rcdev;
unsigned int *resets;
unsigned int reset_count;
+
+ const char *supply;
+ struct regulator *rsupply;
};
struct gdsc_desc {