06.10.2021 15:38, Ulf Hansson пишет:
In principle what you ask for, is if we can avoid calling __pm_runtime_disable() in __device_suspend_late() (and vice versa in device_resume_early()).
I think the short answer is no, at least from a generic point of view. Maybe we can figure out a way to allow this on a per device basis, as an opt-in solution. I am not sure what Rafael would think about this, let's see.
Another option to address the problem is already available to use for these kinds of cases. This would be to add also a pair of ->suspend|resume() callbacks to I2C driver. Along the lines of the below.
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index c883044715f3..589bf872ab25 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -1918,6 +1918,7 @@ static int __maybe_unused tegra_i2c_resume(struct device *dev) }
static const struct dev_pm_ops tegra_i2c_pm = {
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_put_noidle, pm_runtime_get_sync) SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(tegra_i2c_suspend, tegra_i2c_resume) SET_RUNTIME_PM_OPS(tegra_i2c_runtime_suspend, tegra_i2c_runtime_resume, NULL)
In this way, the device would already be runtime resumed, if there is call to pm_runtime_get_sync() from the clock framework due to the clk_prepare|unprepare() being called. If that also turns out to happen *after* runtime PM has been disabled for the device, the call to pm_runtime_get_sync() would still succeed (returning 1, see rpm_resume()), rather than a negative error code.
Yes, we may end up runtime resuming the device during system suspend, even if it turns out not to be needed. Although, that doesn't seem to be the case for the Tegra I2C driver, right?
Tegra I2C will turn off clocks on suspend regardless of RPM state. Overall, it's a plausible solution, thank you!
As I said in the other reply, I'll simply remove the suspend ops from clk driver, they are not needed anymore. The problem is gone.