Also the reset driver maintainer didn't like my way of abstracting two resets ("GPU" and and SoC specific"CLKGEN") into one reset to make it seem to the consumer driver drm/imagination like there is only one reset and suggested and attempt to code the re-setting in the clock driver [2]. Even though he suggested a different way of achieving that: "In my mind it shouldn't be much: the GPU clocks could all share the same refcounted implementation. The first clock to get enabled would ungate both GPU_CORE and GPU_CFG_ACLK gates and deassert GPU_SW_CLKGEN_RST, all in one place. The remaining enable(s) would be no-ops. Would that work?" The above would have similar effect, but I felt like enabling both clocks in single .enable callback could be confusing so I ended up with the current approach. This could be easily re-done if you feel this would be better. I agree that using spinlocks here is dangerous, but looking at the code of the reset_control_deassert and reset_control_assert, it doesn't seem like any spinlocks are acquired/relased in that code flow, unless the driver ops would introduce that. So in this specific case deadlock shouldn't happen ? [1] - https://lore.kernel.org/all/816db99d-7088-4c1a-af03-b9a825ac09dc@xxxxxxxxxx/ [2] - https://lore.kernel.org/all/945fb7e913a9c3dcb40697328b7e9842b75fea5c.camel@xxxxxxxxxxxxxx/ > > I see the commit text talks about this being a workaround. I'm not sure > what the workaround is though. I've seen designs where the reset doesn't > work unless the clk is enabled because the flops have to be clocking for > the reset to propagate a few cycles, or the clk has to be disabled so > that the reset controller can do the clocking, or vice versa for the clk > not working unless the reset is deasserted. Long story short, it's > different between SoCs. OK, so this is how GPU initialization needs to happen for this specific SoC: drm/imagination consumer driver: pvr_power_device_resume(): clk_prepare_enable(pvr_dev->core_clk); clk_prepare_enable(pvr_dev->sys_clk); clk_prepare_enable(pvr_dev->mem_clk); // Then deassert reset introduced in [3] // [3] - https://lore.kernel.org/all/20250128194816.2185326-11-m.wilczynski@xxxxxxxxxxx/ // Eventually this would get called in the SoC specific reset driver static void th1520_rst_gpu_enable(struct regmap *reg, struct mutex *gpu_seq_lock) { int val; mutex_lock(gpu_seq_lock); /* if the GPU is not in a reset state it, put it into one */ regmap_read(reg, TH1520_GPU_RST_CFG, &val); if (val) regmap_update_bits(reg, TH1520_GPU_RST_CFG, TH1520_GPU_RST_CFG_MASK, 0x0); /* rst gpu clkgen */ regmap_set_bits(reg, TH1520_GPU_RST_CFG, TH1520_GPU_SW_CLKGEN_RST); /* * According to the hardware manual, a delay of at least 32 clock * cycles is required between de-asserting the clkgen reset and * de-asserting the GPU reset. Assuming a worst-case scenario with * a very high GPU clock frequency, a delay of 1 microsecond is * sufficient to ensure this requirement is met across all * feasible GPU clock speeds. */ udelay(1); /* rst gpu */ regmap_set_bits(reg, TH1520_GPU_RST_CFG, TH1520_GPU_SW_GPU_RST); mutex_unlock(gpu_seq_lock); } Based on my testing this is exactly how the resets should happen, else the GPU fails to initialize, and the drm/imagination driver hangs. To reiterate: first power ON the GPU using power-domain driver. Then drm/imagination enable all three clocks, then deassert reset of the GPU CLKGEN (SoC specific), delay for 32 cycles, and then deassert the GPU reset. > > Likely the reset and clk control should be coordinated in a PM domain > for the device so that when the device is active, the clks are enabled > and the reset is deasserted in the correct order for the SoC. Can you do > that? Obviously this would work, but I'm worried, the drm/imagination driver maintainers would reject it, as for them this is a special case, from their perspective there is only one reset line to their hardware, and there are three clocks which they manage in driver already. And the PM maintainers probably wouldn't be happy to take this as well. At the very end maybe we could go back to abstracting the resets in the reset driver, as the reset maintainer seemed to be open to it, if the alternatives proves to be too problematic [4]. "I won't object to carry this in the reset driver if the clock implementation turns out to be unreasonably complex, but I currently don't expect that to be the case. Please give it a shot." [4] - https://lore.kernel.org/all/945fb7e913a9c3dcb40697328b7e9842b75fea5c.camel@xxxxxxxxxxxxxx/ > >> + >> + spin_unlock_irqrestore(&gpu_reset_lock, flags); >> +} >