]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
PM: domains: Make set_performance_state() callback optional
authorDmitry Osipenko <digetx@gmail.com>
Wed, 20 Jan 2021 21:12:30 +0000 (00:12 +0300)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 22 Jan 2021 16:12:59 +0000 (17:12 +0100)
Make set_performance_state() callback optional in order to remove the
need from power domain drivers to implement a dummy callback. If callback
isn't implemented by a GENPD driver, then the performance state is passed
to the parent domain.

Tested-by: Peter Geis <pgwipeout@gmail.com>
Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Tested-by: Matt Merhar <mattmerhar@protonmail.com>
[tested on NVIDIA Tegra20/30/124 SoCs]
Suggested-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/base/power/domain.c

index 014033c7c287754e476616dcf8aa1072061b61b9..4878c824e66c0e29c635a77d93776f2e8e56280d 100644 (file)
@@ -297,6 +297,18 @@ static int _genpd_reeval_performance_state(struct generic_pm_domain *genpd,
        return state;
 }
 
+static int genpd_xlate_performance_state(struct generic_pm_domain *genpd,
+                                        struct generic_pm_domain *parent,
+                                        unsigned int pstate)
+{
+       if (!parent->set_performance_state)
+               return pstate;
+
+       return dev_pm_opp_xlate_performance_state(genpd->opp_table,
+                                                 parent->opp_table,
+                                                 pstate);
+}
+
 static int _genpd_set_performance_state(struct generic_pm_domain *genpd,
                                        unsigned int state, int depth)
 {
@@ -311,13 +323,8 @@ static int _genpd_set_performance_state(struct generic_pm_domain *genpd,
        list_for_each_entry(link, &genpd->child_links, child_node) {
                parent = link->parent;
 
-               if (!parent->set_performance_state)
-                       continue;
-
                /* Find parent's performance state */
-               ret = dev_pm_opp_xlate_performance_state(genpd->opp_table,
-                                                        parent->opp_table,
-                                                        state);
+               ret = genpd_xlate_performance_state(genpd, parent, state);
                if (unlikely(ret < 0))
                        goto err;
 
@@ -339,9 +346,11 @@ static int _genpd_set_performance_state(struct generic_pm_domain *genpd,
                        goto err;
        }
 
-       ret = genpd->set_performance_state(genpd, state);
-       if (ret)
-               goto err;
+       if (genpd->set_performance_state) {
+               ret = genpd->set_performance_state(genpd, state);
+               if (ret)
+                       goto err;
+       }
 
        genpd->performance_state = state;
        return 0;
@@ -352,9 +361,6 @@ err:
                                             child_node) {
                parent = link->parent;
 
-               if (!parent->set_performance_state)
-                       continue;
-
                genpd_lock_nested(parent, depth + 1);
 
                parent_state = link->prev_performance_state;
@@ -399,9 +405,6 @@ int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state)
        if (!genpd)
                return -ENODEV;
 
-       if (unlikely(!genpd->set_performance_state))
-               return -EINVAL;
-
        if (WARN_ON(!dev->power.subsys_data ||
                     !dev->power.subsys_data->domain_data))
                return -EINVAL;