PM: Allow pm_runtime_suspend() to succeed during system suspend

The dpm_prepare() function increments the runtime PM reference
counters of all devices to prevent pm_runtime_suspend() from
executing subsystem-level callbacks.  However, this was supposed to
guard against a specific race condition that cannot happen, because
the power management workqueue is freezable, so pm_runtime_suspend()
can only be called synchronously during system suspend and we can
rely on subsystems and device drivers to avoid doing that
unnecessarily.

Make dpm_prepare() drop the runtime PM reference to each device
after making sure that runtime resume is not pending for it.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Kevin Hilman <khilman@ti.com>
This commit is contained in:
Rafael J. Wysocki 2011-02-12 01:42:41 +01:00
parent 88a6f33e4d
commit e866500247

View File

@ -669,7 +669,6 @@ static void dpm_complete(pm_message_t state)
mutex_unlock(&dpm_list_mtx);
device_complete(dev, state);
pm_runtime_put_sync(dev);
mutex_lock(&dpm_list_mtx);
put_device(dev);
@ -1005,12 +1004,9 @@ static int dpm_prepare(pm_message_t state)
if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
pm_wakeup_event(dev, 0);
if (pm_wakeup_pending()) {
pm_runtime_put_sync(dev);
error = -EBUSY;
} else {
error = device_prepare(dev, state);
}
pm_runtime_put_sync(dev);
error = pm_wakeup_pending() ?
-EBUSY : device_prepare(dev, state);
mutex_lock(&dpm_list_mtx);
if (error) {