PM: Introduce core framework for run-time PM of I/O devices (rev. 17)

Introduce a core framework for run-time power management of I/O
devices.  Add device run-time PM fields to 'struct dev_pm_info'
and device run-time PM callbacks to 'struct dev_pm_ops'.  Introduce
a run-time PM workqueue and define some device run-time PM helper
functions at the core level.  Document all these things.

Special thanks to Alan Stern for his help with the design and
multiple detailed reviews of the pereceding versions of this patch
and to Magnus Damm for testing feedback.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Magnus Damm <damm@igel.co.jp>
This commit is contained in:
Rafael J. Wysocki
2009-08-18 23:38:32 +02:00
parent 8400146d0d
commit 5e928f77a0
10 changed files with 1689 additions and 11 deletions

View File

@@ -21,6 +21,7 @@
#include <linux/kallsyms.h>
#include <linux/mutex.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/resume-trace.h>
#include <linux/rwsem.h>
#include <linux/interrupt.h>
@@ -48,6 +49,16 @@ static DEFINE_MUTEX(dpm_list_mtx);
*/
static bool transition_started;
/**
* device_pm_init - Initialize the PM-related part of a device object
* @dev: Device object being initialized.
*/
void device_pm_init(struct device *dev)
{
dev->power.status = DPM_ON;
pm_runtime_init(dev);
}
/**
* device_pm_lock - lock the list of active devices used by the PM core
*/
@@ -105,6 +116,7 @@ void device_pm_remove(struct device *dev)
mutex_lock(&dpm_list_mtx);
list_del_init(&dev->power.entry);
mutex_unlock(&dpm_list_mtx);
pm_runtime_remove(dev);
}
/**
@@ -512,6 +524,7 @@ static void dpm_complete(pm_message_t state)
mutex_unlock(&dpm_list_mtx);
device_complete(dev, state);
pm_runtime_put_noidle(dev);
mutex_lock(&dpm_list_mtx);
}
@@ -757,7 +770,14 @@ static int dpm_prepare(pm_message_t state)
dev->power.status = DPM_PREPARING;
mutex_unlock(&dpm_list_mtx);
error = device_prepare(dev, state);
pm_runtime_get_noresume(dev);
if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) {
/* Wake-up requested during system sleep transition. */
pm_runtime_put_noidle(dev);
error = -EBUSY;
} else {
error = device_prepare(dev, state);
}
mutex_lock(&dpm_list_mtx);
if (error) {