On Wed, 1 Jun 2011, Kevin Hilman wrote:
> In the process of experimenting with other solutions, I found an
> interesting discovery:
>
> In the driver's ->suspend() hook, I did something like this:
>
> priv->forced_suspend = false;
> if (!pm_runtime_suspended(dev)) {
> pm_runtime_put_sync(dev);
> priv->forced_suspend = true;
> }
>
> and in the resume hook I did this:
>
> if (priv->forced_suspend)
> pm_runtime_get_sync(dev);
>
> Even after disabling runtime PM from userspace via
> /sys/devices/.../power/control, the ->suspend() hook triggered an actual
> transition. This is because pm_runtime_forbid() just uses the usage
> counter, so the _put_sync() in the ->suspend callback decrements the
> counter and triggers an rpm_idle(). Is this expected behavior?
Not really. In fact it is a bug in your experimental code -- you are
decrementing the usage counter in a context where you did not
previously increment it. In principle, the counter might already be 0
when the suspend hook runs.
Yes, it is indeed possible for a device to be active while the usage
counter is 0. For example (assuming the counter is initially 0), this
will happen if you call
pm_runtime_get_sync(dev);
pm_runtime_put_noidle(dev);
or even if you simply call
pm_runtime_resume(dev);
Of course, the drivers you're talking about may never do this. Still,
it's a logical mistake to do a *_put without previously doing a *_get.
Alan Stern
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html