aboutsummaryrefslogtreecommitdiff
path: root/drivers/base/power/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/power/main.c')
-rw-r--r--drivers/base/power/main.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 58a3e572f2c..86990011277 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -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>
@@ -49,6 +50,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
*/
void device_pm_lock(void)
@@ -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);
}
/**
@@ -157,8 +169,9 @@ void device_pm_move_last(struct device *dev)
* @ops: PM operations to choose from.
* @state: PM transition of the system being carried out.
*/
-static int pm_op(struct device *dev, struct dev_pm_ops *ops,
- pm_message_t state)
+static int pm_op(struct device *dev,
+ const struct dev_pm_ops *ops,
+ pm_message_t state)
{
int error = 0;
@@ -220,7 +233,8 @@ static int pm_op(struct device *dev, struct dev_pm_ops *ops,
* The operation is executed with interrupts disabled by the only remaining
* functional CPU in the system.
*/
-static int pm_noirq_op(struct device *dev, struct dev_pm_ops *ops,
+static int pm_noirq_op(struct device *dev,
+ const struct dev_pm_ops *ops,
pm_message_t state)
{
int error = 0;
@@ -510,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);
}
@@ -755,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) {