aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/soc/mediatek
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2015-11-30 05:41:40 -0500
committerMatthias Brugger <matthias.bgg@gmail.com>2015-12-18 03:41:42 -0500
commit4688f3856dc1a739ef8a1063abf1e91a657db251 (patch)
treec3db87ac46e0d5f6185da130da96d15632f4356f /drivers/soc/mediatek
parent8005c49d9aea74d382f474ce11afbbc7d7130bec (diff)
soc: mediatek: SCPSYS: Add regulator support
The power domains are supplied by regulators. Add support for them so that the regulators are properly turned on before a domain is powered up and turned off when a domain is powered down. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
Diffstat (limited to 'drivers/soc/mediatek')
-rw-r--r--drivers/soc/mediatek/mtk-scpsys.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index 4d4203c896c4..e4256190bab5 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -21,6 +21,7 @@
21#include <linux/pm_domain.h> 21#include <linux/pm_domain.h>
22#include <linux/regmap.h> 22#include <linux/regmap.h>
23#include <linux/soc/mediatek/infracfg.h> 23#include <linux/soc/mediatek/infracfg.h>
24#include <linux/regulator/consumer.h>
24#include <dt-bindings/power/mt8173-power.h> 25#include <dt-bindings/power/mt8173-power.h>
25 26
26#define SPM_VDE_PWR_CON 0x0210 27#define SPM_VDE_PWR_CON 0x0210
@@ -179,6 +180,7 @@ struct scp_domain {
179 u32 sram_pdn_ack_bits; 180 u32 sram_pdn_ack_bits;
180 u32 bus_prot_mask; 181 u32 bus_prot_mask;
181 bool active_wakeup; 182 bool active_wakeup;
183 struct regulator *supply;
182}; 184};
183 185
184struct scp { 186struct scp {
@@ -221,6 +223,12 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
221 int ret; 223 int ret;
222 int i; 224 int i;
223 225
226 if (scpd->supply) {
227 ret = regulator_enable(scpd->supply);
228 if (ret)
229 return ret;
230 }
231
224 for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) { 232 for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) {
225 ret = clk_prepare_enable(scpd->clk[i]); 233 ret = clk_prepare_enable(scpd->clk[i]);
226 if (ret) { 234 if (ret) {
@@ -299,6 +307,9 @@ err_pwr_ack:
299 clk_disable_unprepare(scpd->clk[i]); 307 clk_disable_unprepare(scpd->clk[i]);
300 } 308 }
301err_clk: 309err_clk:
310 if (scpd->supply)
311 regulator_disable(scpd->supply);
312
302 dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name); 313 dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
303 314
304 return ret; 315 return ret;
@@ -379,6 +390,9 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
379 for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) 390 for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++)
380 clk_disable_unprepare(scpd->clk[i]); 391 clk_disable_unprepare(scpd->clk[i]);
381 392
393 if (scpd->supply)
394 regulator_disable(scpd->supply);
395
382 return 0; 396 return 0;
383 397
384out: 398out:
@@ -448,6 +462,19 @@ static int __init scpsys_probe(struct platform_device *pdev)
448 return PTR_ERR(scp->infracfg); 462 return PTR_ERR(scp->infracfg);
449 } 463 }
450 464
465 for (i = 0; i < NUM_DOMAINS; i++) {
466 struct scp_domain *scpd = &scp->domains[i];
467 const struct scp_domain_data *data = &scp_domain_data[i];
468
469 scpd->supply = devm_regulator_get_optional(&pdev->dev, data->name);
470 if (IS_ERR(scpd->supply)) {
471 if (PTR_ERR(scpd->supply) == -ENODEV)
472 scpd->supply = NULL;
473 else
474 return PTR_ERR(scpd->supply);
475 }
476 }
477
451 pd_data->num_domains = NUM_DOMAINS; 478 pd_data->num_domains = NUM_DOMAINS;
452 479
453 for (i = 0; i < NUM_DOMAINS; i++) { 480 for (i = 0; i < NUM_DOMAINS; i++) {