]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
pmdomain: core: Set the required dev for a required OPP during genpd attach
authorUlf Hansson <ulf.hansson@linaro.org>
Wed, 2 Oct 2024 12:22:27 +0000 (14:22 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Thu, 10 Oct 2024 12:15:10 +0000 (14:15 +0200)
In the single PM domain case there is no need for platform code to specify
the index of the corresponding required OPP in DT, as the index must be
zero. This allows us to assign a required dev for the required OPP from
genpd, while attaching a device to its PM domain.

In this way, we can remove some of the genpd specific code in the OPP core
for the single PM domain case. Although, this cleanup is made from a
subsequent change.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Link: https://lore.kernel.org/r/20241002122232.194245-7-ulf.hansson@linaro.org
drivers/pmdomain/core.c
include/linux/pm_domain.h

index 259abd338f4cc8adfb3db87521757b00632473c7..76490f0bf1e2eb4da95a3dbb739f0001a73bc58c 100644 (file)
@@ -1722,6 +1722,7 @@ static void genpd_free_dev_data(struct device *dev,
 
        spin_unlock_irq(&dev->power.lock);
 
+       dev_pm_opp_clear_config(gpd_data->opp_token);
        kfree(gpd_data->td);
        kfree(gpd_data);
        dev_pm_put_subsys_data(dev);
@@ -2884,6 +2885,29 @@ static void genpd_dev_pm_sync(struct device *dev)
        genpd_queue_power_off_work(pd);
 }
 
+static int genpd_set_required_opp_dev(struct device *dev,
+                                     struct device *base_dev)
+{
+       struct dev_pm_opp_config config = {
+               .required_dev = dev,
+       };
+       int ret;
+
+       /* Limit support to non-providers for now. */
+       if (of_property_present(base_dev->of_node, "#power-domain-cells"))
+               return 0;
+
+       if (!dev_pm_opp_of_has_required_opp(base_dev))
+               return 0;
+
+       ret = dev_pm_opp_set_config(base_dev, &config);
+       if (ret < 0)
+               return ret;
+
+       dev_gpd_data(dev)->opp_token = ret;
+       return 0;
+}
+
 static int genpd_set_required_opp(struct device *dev, unsigned int index)
 {
        int ret, pstate;
@@ -2908,7 +2932,8 @@ err:
 }
 
 static int __genpd_dev_pm_attach(struct device *dev, struct device *base_dev,
-                                unsigned int index, bool power_on)
+                                unsigned int index, unsigned int num_domains,
+                                bool power_on)
 {
        struct of_phandle_args pd_args;
        struct generic_pm_domain *pd;
@@ -2940,6 +2965,17 @@ static int __genpd_dev_pm_attach(struct device *dev, struct device *base_dev,
        dev->pm_domain->detach = genpd_dev_pm_detach;
        dev->pm_domain->sync = genpd_dev_pm_sync;
 
+       /*
+        * For a single PM domain the index of the required OPP must be zero, so
+        * let's try to assign a required dev in that case. In the multiple PM
+        * domains case, we need platform code to specify the index.
+        */
+       if (num_domains == 1) {
+               ret = genpd_set_required_opp_dev(dev, base_dev);
+               if (ret)
+                       goto err;
+       }
+
        ret = genpd_set_required_opp(dev, index);
        if (ret)
                goto err;
@@ -2994,7 +3030,7 @@ int genpd_dev_pm_attach(struct device *dev)
                                       "#power-domain-cells") != 1)
                return 0;
 
-       return __genpd_dev_pm_attach(dev, dev, 0, true);
+       return __genpd_dev_pm_attach(dev, dev, 0, 1, true);
 }
 EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
 
@@ -3047,7 +3083,7 @@ struct device *genpd_dev_pm_attach_by_id(struct device *dev,
        }
 
        /* Try to attach the device to the PM domain at the specified index. */
-       ret = __genpd_dev_pm_attach(virt_dev, dev, index, false);
+       ret = __genpd_dev_pm_attach(virt_dev, dev, index, num_domains, false);
        if (ret < 1) {
                device_unregister(virt_dev);
                return ret ? ERR_PTR(ret) : NULL;
index 92f9d56f623dc722db8f3e7fea40bba95f2e51c6..76775ab3889839a880260d9b27138fca19289081 100644 (file)
@@ -252,6 +252,7 @@ struct generic_pm_domain_data {
        unsigned int performance_state;
        unsigned int default_pstate;
        unsigned int rpm_pstate;
+       unsigned int opp_token;
        bool hw_mode;
        void *data;
 };