Skip to content

Commit

Permalink
PM / Domains: Save OPP table pointer in genpd
Browse files Browse the repository at this point in the history
dev_pm_genpd_set_performance_state() will be required to call
dev_pm_opp_xlate_performance_state() going forward to translate from
performance state of a sub-domain to performance state of its master.
And dev_pm_opp_xlate_performance_state() needs pointers to the OPP
tables of both genpd and its master.

Lets fetch and save them while the OPP tables are added. Fetching the
OPP tables should never fail as we just added the OPP tables and so add
a WARN_ON() for such a bug instead of full error paths.

Tested-by: Rajendra Nayak <rnayak@codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
  • Loading branch information
Viresh Kumar committed Dec 14, 2018
1 parent 2feb5a8 commit 1067ae3
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
23 changes: 21 additions & 2 deletions drivers/base/power/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -1896,12 +1896,21 @@ int of_genpd_add_provider_simple(struct device_node *np,
ret);
goto unlock;
}

/*
* Save table for faster processing while setting performance
* state.
*/
genpd->opp_table = dev_pm_opp_get_opp_table(&genpd->dev);
WARN_ON(!genpd->opp_table);
}

ret = genpd_add_provider(np, genpd_xlate_simple, genpd);
if (ret) {
if (genpd->set_performance_state)
if (genpd->set_performance_state) {
dev_pm_opp_put_opp_table(genpd->opp_table);
dev_pm_opp_of_remove_table(&genpd->dev);
}

goto unlock;
}
Expand Down Expand Up @@ -1954,6 +1963,13 @@ int of_genpd_add_provider_onecell(struct device_node *np,
i, ret);
goto error;
}

/*
* Save table for faster processing while setting
* performance state.
*/
genpd->opp_table = dev_pm_opp_get_opp_table_indexed(&genpd->dev, i);
WARN_ON(!genpd->opp_table);
}

genpd->provider = &np->fwnode;
Expand All @@ -1978,8 +1994,10 @@ int of_genpd_add_provider_onecell(struct device_node *np,
genpd->provider = NULL;
genpd->has_provider = false;

if (genpd->set_performance_state)
if (genpd->set_performance_state) {
dev_pm_opp_put_opp_table(genpd->opp_table);
dev_pm_opp_of_remove_table(&genpd->dev);
}
}

mutex_unlock(&gpd_list_lock);
Expand Down Expand Up @@ -2013,6 +2031,7 @@ void of_genpd_del_provider(struct device_node *np)
if (!gpd->set_performance_state)
continue;

dev_pm_opp_put_opp_table(gpd->opp_table);
dev_pm_opp_of_remove_table(&gpd->dev);
}
}
Expand Down
2 changes: 2 additions & 0 deletions include/linux/pm_domain.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ struct genpd_power_state {

struct genpd_lock_ops;
struct dev_pm_opp;
struct opp_table;

struct generic_pm_domain {
struct device dev;
Expand All @@ -94,6 +95,7 @@ struct generic_pm_domain {
unsigned int performance_state; /* Aggregated max performance state */
int (*power_off)(struct generic_pm_domain *domain);
int (*power_on)(struct generic_pm_domain *domain);
struct opp_table *opp_table; /* OPP table of the genpd */
unsigned int (*opp_to_performance_state)(struct generic_pm_domain *genpd,
struct dev_pm_opp *opp);
int (*set_performance_state)(struct generic_pm_domain *genpd,
Expand Down

0 comments on commit 1067ae3

Please sign in to comment.