Skip to content

Commit

Permalink
PM / Domain: Add support to parse domain's OPP table
Browse files Browse the repository at this point in the history
The generic power domains can have an OPP table for themselves now, and
phandle of their OPP nodes can be used by the devices powered by the
domain. In order for the OPP core to translate requirements between the
devices and their power domains, both need to have an OPP table in
kernel.

Parse the OPP table for power domains
if they have their
set_performance_state() callback set.

With this patch, an OPP table would be created for the genpd in kernel
based on the OPP table present in DT, if the genpd have its
set_performance_state() callback set.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
  • Loading branch information
Viresh Kumar committed May 9, 2018
1 parent 401ea15 commit 6a0ae73
Showing 1 changed file with 62 additions and 14 deletions.
76 changes: 62 additions & 14 deletions drivers/base/power/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h>
#include <linux/pm_runtime.h>
#include <linux/pm_domain.h>
#include <linux/pm_qos.h>
Expand Down Expand Up @@ -1895,14 +1896,33 @@ int of_genpd_add_provider_simple(struct device_node *np,

mutex_lock(&gpd_list_lock);

if (genpd_present(genpd)) {
ret = genpd_add_provider(np, genpd_xlate_simple, genpd);
if (!ret) {
genpd->provider = &np->fwnode;
genpd->has_provider = true;
if (!genpd_present(genpd))
goto unlock;

genpd->dev.of_node = np;

/* Parse genpd OPP table */
if (genpd->set_performance_state) {
ret = dev_pm_opp_of_add_table(&genpd->dev);
if (ret) {
dev_err(&genpd->dev, "Failed to add OPP table: %d\n",
ret);
goto unlock;
}
}

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

goto unlock;
}

genpd->provider = &np->fwnode;
genpd->has_provider = true;

unlock:
mutex_unlock(&gpd_list_lock);

return ret;
Expand All @@ -1917,6 +1937,7 @@ EXPORT_SYMBOL_GPL(of_genpd_add_provider_simple);
int of_genpd_add_provider_onecell(struct device_node *np,
struct genpd_onecell_data *data)
{
struct generic_pm_domain *genpd;
unsigned int i;
int ret = -EINVAL;

Expand All @@ -1929,13 +1950,27 @@ int of_genpd_add_provider_onecell(struct device_node *np,
data->xlate = genpd_xlate_onecell;

for (i = 0; i < data->num_domains; i++) {
if (!data->domains[i])
genpd = data->domains[i];

if (!genpd)
continue;
if (!genpd_present(data->domains[i]))
if (!genpd_present(genpd))
goto error;

data->domains[i]->provider = &np->fwnode;
data->domains[i]->has_provider = true;
genpd->dev.of_node = np;

/* Parse genpd OPP table */
if (genpd->set_performance_state) {
ret = dev_pm_opp_of_add_table_indexed(&genpd->dev, i);
if (ret) {
dev_err(&genpd->dev, "Failed to add OPP table for index %d: %d\n",
i, ret);
goto error;
}
}

genpd->provider = &np->fwnode;
genpd->has_provider = true;
}

ret = genpd_add_provider(np, data->xlate, data);
Expand All @@ -1948,10 +1983,16 @@ int of_genpd_add_provider_onecell(struct device_node *np,

error:
while (i--) {
if (!data->domains[i])
genpd = data->domains[i];

if (!genpd)
continue;
data->domains[i]->provider = NULL;
data->domains[i]->has_provider = false;

genpd->provider = NULL;
genpd->has_provider = false;

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

mutex_unlock(&gpd_list_lock);
Expand All @@ -1978,10 +2019,17 @@ void of_genpd_del_provider(struct device_node *np)
* provider, set the 'has_provider' to false
* so that the PM domain can be safely removed.
*/
list_for_each_entry(gpd, &gpd_list, gpd_list_node)
if (gpd->provider == &np->fwnode)
list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
if (gpd->provider == &np->fwnode) {
gpd->has_provider = false;

if (!gpd->set_performance_state)
continue;

dev_pm_opp_of_remove_table(&gpd->dev);
}
}

list_del(&cp->link);
of_node_put(cp->node);
kfree(cp);
Expand Down

0 comments on commit 6a0ae73

Please sign in to comment.