diff options
| author | Sascha Hauer <s.hauer@pengutronix.de> | 2015-11-30 05:41:40 -0500 |
|---|---|---|
| committer | Matthias Brugger <matthias.bgg@gmail.com> | 2015-12-18 03:41:42 -0500 |
| commit | 4688f3856dc1a739ef8a1063abf1e91a657db251 (patch) | |
| tree | c3db87ac46e0d5f6185da130da96d15632f4356f /drivers/soc/mediatek | |
| parent | 8005c49d9aea74d382f474ce11afbbc7d7130bec (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.c | 27 |
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 | ||
| 184 | struct scp { | 186 | struct 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 | } |
| 301 | err_clk: | 309 | err_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 | ||
| 384 | out: | 398 | out: |
| @@ -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++) { |
