diff options
author | Rajendra Nayak <rnayak@codeaurora.org> | 2019-01-10 05:02:05 +0100 |
---|---|---|
committer | Andy Gross <andy.gross@linaro.org> | 2019-01-22 22:06:13 +0100 |
commit | 075d3db8d10d82bb86777df3f81e1b83caeb630a (patch) | |
tree | 329ea2c8c1f9204561cb05a372fdc18d6e1b6558 /drivers/soc | |
parent | soc: qcom: rpmpd: Add a Power domain driver to model corners (diff) | |
download | linux-075d3db8d10d82bb86777df3f81e1b83caeb630a.tar.xz linux-075d3db8d10d82bb86777df3f81e1b83caeb630a.zip |
soc: qcom: rpmpd: Add support for get/set performance state
Add support for the .set_performace_state() and .opp_to_performance_state()
callbacks in the rpmpd driver.
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Andy Gross <andy.gross@linaro.org>
Diffstat (limited to 'drivers/soc')
-rw-r--r-- | drivers/soc/qcom/rpmpd.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index 7715ba7c9157..35a711017d6f 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -10,6 +10,7 @@ #include <linux/of.h> #include <linux/of_device.h> #include <linux/platform_device.h> +#include <linux/pm_opp.h> #include <linux/soc/qcom/smd-rpm.h> #include <dt-bindings/mfd/qcom-rpm.h> @@ -26,6 +27,8 @@ #define KEY_ENABLE 0x6e657773 /* swen */ #define KEY_FLOOR_CORNER 0x636676 /* vfc */ +#define MAX_RPMPD_STATE 6 + #define DEFINE_RPMPD_CORNER_SMPA(_platform, _name, _active, r_id) \ static struct rpmpd _platform##_##_active; \ static struct rpmpd _platform##_##_name = { \ @@ -218,6 +221,36 @@ static int rpmpd_power_off(struct generic_pm_domain *domain) return ret; } +static int rpmpd_set_performance(struct generic_pm_domain *domain, + unsigned int state) +{ + int ret = 0; + struct rpmpd *pd = domain_to_rpmpd(domain); + + if (state > MAX_RPMPD_STATE) + goto out; + + mutex_lock(&rpmpd_lock); + + pd->corner = state; + + if (!pd->enabled && pd->key != KEY_FLOOR_CORNER) + goto out; + + ret = rpmpd_aggregate_corner(pd); + +out: + mutex_unlock(&rpmpd_lock); + + return ret; +} + +static unsigned int rpmpd_get_performance(struct generic_pm_domain *genpd, + struct dev_pm_opp *opp) +{ + return dev_pm_opp_get_level(opp); +} + static int rpmpd_probe(struct platform_device *pdev) { int i; @@ -258,6 +291,8 @@ static int rpmpd_probe(struct platform_device *pdev) rpmpds[i]->rpm = rpm; rpmpds[i]->pd.power_off = rpmpd_power_off; rpmpds[i]->pd.power_on = rpmpd_power_on; + rpmpds[i]->pd.set_performance_state = rpmpd_set_performance; + rpmpds[i]->pd.opp_to_performance_state = rpmpd_get_performance; pm_genpd_init(&rpmpds[i]->pd, NULL, true); data->domains[i] = &rpmpds[i]->pd; |