On 1/22/26 4:35 PM, Geert Uytterhoeven wrote:

Hello Geert,

Can you please test this change and see if it fixes the problem ?

The barrier should guarantee that the domain is settled and no more
callbacks are still running.

Thank you, that indeed fixes the issue!

However, I am not so sure this barrier belongs in the .detach_dev()
callback.  The documentation for almost all dev_pm_domain_{at,de}tach*()
functions states:

      * Callers must ensure proper synchronization of this function with power
      * management callbacks.

Isn't cpg_mssr_detach_dev() the caller in this case ?

However, I couldn't find any user that calls pm_runtime_barrier() first.

In case of multiple PM domains, it is even more complicated, as
dev_pm_domain_attach_list() (and pvr_power_domains_init(), which is
basically an open-coded variant of the former) creates a list of virtual
devices, which all need synchronization.  For the devres-enabled version
(devm_pm_domain_attach_list()), the caller cannot take care of calling
pm_runtime_barrier() anyway, so it has to be handled by the PM core?

I am also a bit surprised the PM core does not handle it.

--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -24,6 +24,7 @@
   #include <linux/platform_device.h>
   #include <linux/pm_clock.h>
   #include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
   #include <linux/psci.h>
   #include <linux/reset-controller.h>
   #include <linux/slab.h>
@@ -656,8 +657,10 @@ int cpg_mssr_attach_dev(struct generic_pm_domain
*unused, struct device *dev)

   void cpg_mssr_detach_dev(struct generic_pm_domain *unused, struct
device *dev)
   {
-       if (!pm_clk_no_clocks(dev))
+       if (!pm_clk_no_clocks(dev)) {
+               pm_runtime_barrier(dev);
                 pm_clk_destroy(dev);
+       }
   }

   static void cpg_mssr_genpd_remove(void *data)

--
Best regards,
Marek Vasut

Reply via email to