|
11 | 11 | #include <linux/ktime.h> |
12 | 12 | #include <linux/pm_domain.h> |
13 | 13 | #include <linux/regmap.h> |
| 14 | +#include <linux/regulator/consumer.h> |
14 | 15 | #include <linux/reset-controller.h> |
15 | 16 | #include <linux/slab.h> |
16 | 17 | #include "gdsc.h" |
@@ -112,6 +113,12 @@ static int gdsc_toggle_logic(struct gdsc *sc, enum gdsc_status status) |
112 | 113 | int ret; |
113 | 114 | u32 val = (status == GDSC_ON) ? 0 : SW_COLLAPSE_MASK; |
114 | 115 |
|
| 116 | + if (status == GDSC_ON && sc->rsupply) { |
| 117 | + ret = regulator_enable(sc->rsupply); |
| 118 | + if (ret < 0) |
| 119 | + return ret; |
| 120 | + } |
| 121 | + |
115 | 122 | ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val); |
116 | 123 | if (ret) |
117 | 124 | return ret; |
@@ -143,6 +150,13 @@ static int gdsc_toggle_logic(struct gdsc *sc, enum gdsc_status status) |
143 | 150 |
|
144 | 151 | ret = gdsc_poll_status(sc, status); |
145 | 152 | WARN(ret, "%s status stuck at 'o%s'", sc->pd.name, status ? "ff" : "n"); |
| 153 | + |
| 154 | + if (!ret && status == GDSC_OFF && sc->rsupply) { |
| 155 | + ret = regulator_disable(sc->rsupply); |
| 156 | + if (ret < 0) |
| 157 | + return ret; |
| 158 | + } |
| 159 | + |
146 | 160 | return ret; |
147 | 161 | } |
148 | 162 |
|
@@ -371,6 +385,15 @@ int gdsc_register(struct gdsc_desc *desc, |
371 | 385 | if (!data->domains) |
372 | 386 | return -ENOMEM; |
373 | 387 |
|
| 388 | + for (i = 0; i < num; i++) { |
| 389 | + if (!scs[i] || !scs[i]->supply) |
| 390 | + continue; |
| 391 | + |
| 392 | + scs[i]->rsupply = devm_regulator_get(dev, scs[i]->supply); |
| 393 | + if (IS_ERR(scs[i]->rsupply)) |
| 394 | + return PTR_ERR(scs[i]->rsupply); |
| 395 | + } |
| 396 | + |
374 | 397 | data->num_domains = num; |
375 | 398 | for (i = 0; i < num; i++) { |
376 | 399 | if (!scs[i]) |
|
0 commit comments