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 <[email protected]>
Tested-by: Nicolas Chauvet <[email protected]>
Tested-by: Matt Merhar <[email protected]>
[tested on NVIDIA Tegra20/30/124 SoCs]
Suggested-by: Ulf Hansson <[email protected]>
Signed-off-by: Dmitry Osipenko <[email protected]>
---
 drivers/base/power/domain.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 9a14eedacb92..0bd0cdc30393 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -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 *src_genpd,
+                                         struct generic_pm_domain *dst_genpd,
+                                         unsigned int pstate)
+{
+       if (!dst_genpd->set_performance_state)
+               return pstate;
+
+       return dev_pm_opp_xlate_performance_state(src_genpd->opp_table,
+                                                 dst_genpd->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 @@ static int _genpd_set_performance_state(struct 
generic_pm_domain *genpd,
                                             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;
-- 
2.29.2

Reply via email to