[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <194465eda54d1f852a9226cf691ddc5aa208e0a3.1769097977.git.geert+renesas@glider.be>
Date: Thu, 22 Jan 2026 17:08:32 +0100
From: Geert Uytterhoeven <geert+renesas@...der.be>
To: Frank Binns <frank.binns@...tec.com>,
Matt Coster <matt.coster@...tec.com>,
Marek Vasut <marek.vasut@...lbox.org>,
Maarten Lankhorst <maarten.lankhorst@...ux.intel.com>,
Maxime Ripard <mripard@...nel.org>,
Thomas Zimmermann <tzimmermann@...e.de>,
David Airlie <airlied@...il.com>,
Simona Vetter <simona@...ll.ch>
Cc: dri-devel@...ts.freedesktop.org,
linux-pm@...r.kernel.org,
linux-renesas-soc@...r.kernel.org,
linux-kernel@...r.kernel.org,
Geert Uytterhoeven <geert+renesas@...der.be>
Subject: [PATCH] drm/imagination: Convert to dev_pm_domain_{at,de}tach_list()
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 <geert+renesas@...der.be>
---
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
Powered by blists - more mailing lists