Call the dev_pm_domain_attach_list() and dev_pm_domain_detach_list()
helpers instead of open-coding multi PM Domain handling.

This changes behavior slightly:
  - The new handling is also applied in case of a single PM Domain,
  - PM Domains are now referred to by index instead of by name, but
    "make dtbs_check" enforces the actual naming and ordering anyway,
  - There are no longer device links created between virtual domain
    devices, only between virtual devices and the parent device.
None of this should have an actual impact on functionality.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
Tested lightly on R-Car M3-W: driver probes and firmware is loaded.
---
 drivers/gpu/drm/imagination/pvr_device.h |  13 +--
 drivers/gpu/drm/imagination/pvr_power.c  | 105 ++---------------------
 2 files changed, 9 insertions(+), 109 deletions(-)

diff --git a/drivers/gpu/drm/imagination/pvr_device.h 
b/drivers/gpu/drm/imagination/pvr_device.h
index 491718fb87a1b608..a823f6f7e0b659c6 100644
--- a/drivers/gpu/drm/imagination/pvr_device.h
+++ b/drivers/gpu/drm/imagination/pvr_device.h
@@ -148,19 +148,12 @@ struct pvr_device {
        struct clk *mem_clk;
 
        /**
-        * @power: Optional power domain devices.
+        * @pds: Optional power domain devices.
         *
         * On platforms with more than one power domain for the GPU, they are
-        * stored here in @domain_devs, along with links between them in
-        * @domain_links. The size of @domain_devs is given by @domain_count,
-        * while the size of @domain_links is (2 * @domain_count) - 1.
+        * stored here, along with links between them.
         */
-       struct pvr_device_power {
-               struct device **domain_devs;
-               struct device_link **domain_links;
-
-               u32 domain_count;
-       } power;
+       struct dev_pm_domain_list *pds;
 
        /**
         * @reset: Optional reset line.
diff --git a/drivers/gpu/drm/imagination/pvr_power.c 
b/drivers/gpu/drm/imagination/pvr_power.c
index b9f801c63260cb81..cc6efab3c8b015ce 100644
--- a/drivers/gpu/drm/imagination/pvr_power.c
+++ b/drivers/gpu/drm/imagination/pvr_power.c
@@ -594,110 +594,17 @@ pvr_watchdog_fini(struct pvr_device *pvr_dev)
 int pvr_power_domains_init(struct pvr_device *pvr_dev)
 {
        struct device *dev = from_pvr_device(pvr_dev)->dev;
+       int ret;
 
-       struct device_link **domain_links __free(kfree) = NULL;
-       struct device **domain_devs __free(kfree) = NULL;
-       int domain_count;
-       int link_count;
-
-       char dev_name[2] = "a";
-       int err;
-       int i;
-
-       domain_count = of_count_phandle_with_args(dev->of_node, "power-domains",
-                                                 "#power-domain-cells");
-       if (domain_count < 0)
-               return domain_count;
-
-       if (domain_count <= 1)
-               return 0;
-
-       link_count = domain_count + (domain_count - 1);
-
-       domain_devs = kcalloc(domain_count, sizeof(*domain_devs), GFP_KERNEL);
-       if (!domain_devs)
-               return -ENOMEM;
-
-       domain_links = kcalloc(link_count, sizeof(*domain_links), GFP_KERNEL);
-       if (!domain_links)
-               return -ENOMEM;
-
-       for (i = 0; i < domain_count; i++) {
-               struct device *domain_dev;
-
-               dev_name[0] = 'a' + i;
-               domain_dev = dev_pm_domain_attach_by_name(dev, dev_name);
-               if (IS_ERR_OR_NULL(domain_dev)) {
-                       err = domain_dev ? PTR_ERR(domain_dev) : -ENODEV;
-                       goto err_detach;
-               }
-
-               domain_devs[i] = domain_dev;
-       }
-
-       for (i = 0; i < domain_count; i++) {
-               struct device_link *link;
-
-               link = device_link_add(dev, domain_devs[i], DL_FLAG_STATELESS | 
DL_FLAG_PM_RUNTIME);
-               if (!link) {
-                       err = -ENODEV;
-                       goto err_unlink;
-               }
-
-               domain_links[i] = link;
-       }
-
-       for (i = domain_count; i < link_count; i++) {
-               struct device_link *link;
-
-               link = device_link_add(domain_devs[i - domain_count + 1],
-                                      domain_devs[i - domain_count],
-                                      DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
-               if (!link) {
-                       err = -ENODEV;
-                       goto err_unlink;
-               }
-
-               domain_links[i] = link;
-       }
-
-       pvr_dev->power = (struct pvr_device_power){
-               .domain_devs = no_free_ptr(domain_devs),
-               .domain_links = no_free_ptr(domain_links),
-               .domain_count = domain_count,
-       };
+       ret = dev_pm_domain_attach_list(dev, NULL, &pvr_dev->pds);
+       if (ret < 0)
+               return ret;
 
        return 0;
-
-err_unlink:
-       while (--i >= 0)
-               device_link_del(domain_links[i]);
-
-       i = domain_count;
-
-err_detach:
-       while (--i >= 0)
-               dev_pm_domain_detach(domain_devs[i], true);
-
-       return err;
 }
 
 void pvr_power_domains_fini(struct pvr_device *pvr_dev)
 {
-       const int domain_count = pvr_dev->power.domain_count;
-
-       int i = domain_count + (domain_count - 1);
-
-       while (--i >= 0)
-               device_link_del(pvr_dev->power.domain_links[i]);
-
-       i = domain_count;
-
-       while (--i >= 0)
-               dev_pm_domain_detach(pvr_dev->power.domain_devs[i], true);
-
-       kfree(pvr_dev->power.domain_links);
-       kfree(pvr_dev->power.domain_devs);
-
-       pvr_dev->power = (struct pvr_device_power){ 0 };
+       dev_pm_domain_detach_list(pvr_dev->pds);
+       pvr_dev->pds = NULL;
 }
-- 
2.43.0

Reply via email to