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
