blob: 00c53eb8ebca7735cca8134f6db6653d87320807 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * drivers/base/power/main.c - Where the driver meets power management.
3 *
4 * Copyright (c) 2003 Patrick Mochel
5 * Copyright (c) 2003 Open Source Development Lab
6 *
7 * This file is released under the GPLv2
8 *
9 *
10 * The driver model core calls device_pm_add() when a device is registered.
Uwe Kleine-Königb5950762010-11-01 15:38:34 -040011 * This will initialize the embedded device_pm_info object in the device
Linus Torvalds1da177e2005-04-16 15:20:36 -070012 * and add it to the list of power-controlled devices. sysfs entries for
13 * controlling device power management will also be added.
14 *
Rafael J. Wysocki1eede072008-05-20 23:00:01 +020015 * A separate list is used for keeping track of power info, because the power
16 * domain dependencies may differ from the ancestral dependencies that the
17 * subsystem list maintains.
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 */
19
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <linux/device.h>
Alan Sterncd59abf2007-09-21 15:36:56 -040021#include <linux/kallsyms.h>
Paul Gortmaker1b6bc322011-05-27 07:12:15 -040022#include <linux/export.h>
Matthias Kaehlcke11048dc2007-05-23 14:19:41 -070023#include <linux/mutex.h>
Alan Sterncd59abf2007-09-21 15:36:56 -040024#include <linux/pm.h>
Rafael J. Wysocki5e928f72009-08-18 23:38:32 +020025#include <linux/pm_runtime.h>
Alan Sterncd59abf2007-09-21 15:36:56 -040026#include <linux/resume-trace.h>
Rafael J. Wysocki2ed8d2b32009-03-16 22:34:06 +010027#include <linux/interrupt.h>
Arjan van de Venf2511772009-12-13 20:29:01 +010028#include <linux/sched.h>
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +010029#include <linux/async.h>
Rafael J. Wysocki1e752272010-12-03 22:58:05 +010030#include <linux/suspend.h>
Shuah Khan53644672013-07-26 13:30:20 -060031#include <trace/events/power.h>
Preeti U Murthy8651f972012-07-09 10:12:56 +020032#include <linux/cpuidle.h>
Benoit Goby70fea602013-10-17 10:48:46 -070033#include <linux/timer.h>
34
Alan Sterncd59abf2007-09-21 15:36:56 -040035#include "../base.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070036#include "power.h"
37
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +010038typedef int (*pm_callback_t)(struct device *);
39
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +010040/*
Rafael J. Wysocki1eede072008-05-20 23:00:01 +020041 * The entries in the dpm_list list are in a depth first order, simply
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +010042 * because children are guaranteed to be discovered after parents, and
43 * are inserted at the back of the list on discovery.
44 *
Greg Kroah-Hartman8e9394c2010-02-17 10:57:05 -080045 * Since device_pm_add() may be called with a device lock held,
46 * we must never try to acquire a device lock while holding
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +010047 * dpm_list_mutex.
48 */
49
Rafael J. Wysocki1eede072008-05-20 23:00:01 +020050LIST_HEAD(dpm_list);
Sachin Kamat7664e962012-07-17 22:38:08 +020051static LIST_HEAD(dpm_prepared_list);
52static LIST_HEAD(dpm_suspended_list);
53static LIST_HEAD(dpm_late_early_list);
54static LIST_HEAD(dpm_noirq_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
ShuoX Liu2a77c462011-08-10 23:01:26 +020056struct suspend_stats suspend_stats;
Alan Sterncd59abf2007-09-21 15:36:56 -040057static DEFINE_MUTEX(dpm_list_mtx);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +010058static pm_message_t pm_transition;
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
Rafael J. Wysocki098dff72010-09-22 22:10:57 +020060static int async_error;
61
Shuah Khan53644672013-07-26 13:30:20 -060062static char *pm_verb(int event)
63{
64 switch (event) {
65 case PM_EVENT_SUSPEND:
66 return "suspend";
67 case PM_EVENT_RESUME:
68 return "resume";
69 case PM_EVENT_FREEZE:
70 return "freeze";
71 case PM_EVENT_QUIESCE:
72 return "quiesce";
73 case PM_EVENT_HIBERNATE:
74 return "hibernate";
75 case PM_EVENT_THAW:
76 return "thaw";
77 case PM_EVENT_RESTORE:
78 return "restore";
79 case PM_EVENT_RECOVER:
80 return "recover";
81 default:
82 return "(unknown PM event)";
83 }
84}
85
Rafael J. Wysocki1eede072008-05-20 23:00:01 +020086/**
Rafael J. Wysockie91c11b2012-08-06 01:44:28 +020087 * device_pm_sleep_init - Initialize system suspend-related device fields.
Rafael J. Wysocki5e928f72009-08-18 23:38:32 +020088 * @dev: Device object being initialized.
89 */
Rafael J. Wysockie91c11b2012-08-06 01:44:28 +020090void device_pm_sleep_init(struct device *dev)
Rafael J. Wysocki5e928f72009-08-18 23:38:32 +020091{
Alan Sternf76b168b2011-06-18 20:22:23 +020092 dev->power.is_prepared = false;
Alan Stern6d0e0e82011-06-18 22:42:09 +020093 dev->power.is_suspended = false;
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +080094 dev->power.is_noirq_suspended = false;
95 dev->power.is_late_suspended = false;
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +010096 init_completion(&dev->power.completion);
Colin Cross152e1d52010-09-03 01:24:07 +020097 complete_all(&dev->power.completion);
Rafael J. Wysocki074037e2010-09-22 22:09:10 +020098 dev->power.wakeup = NULL;
Rafael J. Wysocki22110fa2011-04-26 11:33:09 +020099 INIT_LIST_HEAD(&dev->power.entry);
Rafael J. Wysocki5e928f72009-08-18 23:38:32 +0200100}
101
102/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200103 * device_pm_lock - Lock the list of active devices used by the PM core.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200104 */
105void device_pm_lock(void)
106{
107 mutex_lock(&dpm_list_mtx);
108}
109
110/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200111 * device_pm_unlock - Unlock the list of active devices used by the PM core.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200112 */
113void device_pm_unlock(void)
114{
115 mutex_unlock(&dpm_list_mtx);
116}
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100117
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100118/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200119 * device_pm_add - Add a device to the PM core's list of active devices.
120 * @dev: Device to add to the list.
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100121 */
Alan Stern3b98aea2008-08-07 13:06:12 -0400122void device_pm_add(struct device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 pr_debug("PM: Adding info for %s:%s\n",
Rafael J. Wysocki5c1a07a2010-12-24 15:03:34 +0100125 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
Matthias Kaehlcke11048dc2007-05-23 14:19:41 -0700126 mutex_lock(&dpm_list_mtx);
Alan Sternf76b168b2011-06-18 20:22:23 +0200127 if (dev->parent && dev->parent->power.is_prepared)
Rafael J. Wysockib64959e2010-12-16 17:11:45 +0100128 dev_warn(dev, "parent %s should not be sleeping\n",
129 dev_name(dev->parent));
Alan Stern3b98aea2008-08-07 13:06:12 -0400130 list_add_tail(&dev->power.entry, &dpm_list);
Rafael J. Wysocki1a9a9152011-09-29 22:29:44 +0200131 mutex_unlock(&dpm_list_mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132}
133
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100134/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200135 * device_pm_remove - Remove a device from the PM core's list of active devices.
136 * @dev: Device to be removed from the list.
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100137 */
Rafael J. Wysocki9cddad72007-06-13 15:53:34 +0200138void device_pm_remove(struct device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139{
140 pr_debug("PM: Removing info for %s:%s\n",
Rafael J. Wysocki5c1a07a2010-12-24 15:03:34 +0100141 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100142 complete_all(&dev->power.completion);
Matthias Kaehlcke11048dc2007-05-23 14:19:41 -0700143 mutex_lock(&dpm_list_mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 list_del_init(&dev->power.entry);
Matthias Kaehlcke11048dc2007-05-23 14:19:41 -0700145 mutex_unlock(&dpm_list_mtx);
Rafael J. Wysocki074037e2010-09-22 22:09:10 +0200146 device_wakeup_disable(dev);
Rafael J. Wysocki5e928f72009-08-18 23:38:32 +0200147 pm_runtime_remove(dev);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100148}
149
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200150/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200151 * device_pm_move_before - Move device in the PM core's list of active devices.
152 * @deva: Device to move in dpm_list.
153 * @devb: Device @deva should come before.
Cornelia Huckffa6a702009-03-04 12:44:00 +0100154 */
155void device_pm_move_before(struct device *deva, struct device *devb)
156{
157 pr_debug("PM: Moving %s:%s before %s:%s\n",
Rafael J. Wysocki5c1a07a2010-12-24 15:03:34 +0100158 deva->bus ? deva->bus->name : "No Bus", dev_name(deva),
159 devb->bus ? devb->bus->name : "No Bus", dev_name(devb));
Cornelia Huckffa6a702009-03-04 12:44:00 +0100160 /* Delete deva from dpm_list and reinsert before devb. */
161 list_move_tail(&deva->power.entry, &devb->power.entry);
162}
163
164/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200165 * device_pm_move_after - Move device in the PM core's list of active devices.
166 * @deva: Device to move in dpm_list.
167 * @devb: Device @deva should come after.
Cornelia Huckffa6a702009-03-04 12:44:00 +0100168 */
169void device_pm_move_after(struct device *deva, struct device *devb)
170{
171 pr_debug("PM: Moving %s:%s after %s:%s\n",
Rafael J. Wysocki5c1a07a2010-12-24 15:03:34 +0100172 deva->bus ? deva->bus->name : "No Bus", dev_name(deva),
173 devb->bus ? devb->bus->name : "No Bus", dev_name(devb));
Cornelia Huckffa6a702009-03-04 12:44:00 +0100174 /* Delete deva from dpm_list and reinsert after devb. */
175 list_move(&deva->power.entry, &devb->power.entry);
176}
177
178/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200179 * device_pm_move_last - Move device to end of the PM core's list of devices.
180 * @dev: Device to move in dpm_list.
Cornelia Huckffa6a702009-03-04 12:44:00 +0100181 */
182void device_pm_move_last(struct device *dev)
183{
184 pr_debug("PM: Moving %s:%s to end of list\n",
Rafael J. Wysocki5c1a07a2010-12-24 15:03:34 +0100185 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
Cornelia Huckffa6a702009-03-04 12:44:00 +0100186 list_move_tail(&dev->power.entry, &dpm_list);
187}
188
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +0100189static ktime_t initcall_debug_start(struct device *dev)
190{
191 ktime_t calltime = ktime_set(0, 0);
192
Rafael J. Wysockib2df1d42012-06-21 00:19:33 +0200193 if (pm_print_times_enabled) {
Rafael J. Wysocki0c6aebe2011-12-03 00:23:43 +0100194 pr_info("calling %s+ @ %i, parent: %s\n",
195 dev_name(dev), task_pid_nr(current),
196 dev->parent ? dev_name(dev->parent) : "none");
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +0100197 calltime = ktime_get();
198 }
199
200 return calltime;
201}
202
203static void initcall_debug_report(struct device *dev, ktime_t calltime,
Shuah Khan53644672013-07-26 13:30:20 -0600204 int error, pm_message_t state, char *info)
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +0100205{
Shuah Khan53644672013-07-26 13:30:20 -0600206 ktime_t rettime;
207 s64 nsecs;
208
209 rettime = ktime_get();
210 nsecs = (s64) ktime_to_ns(ktime_sub(rettime, calltime));
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +0100211
Rafael J. Wysockib2df1d42012-06-21 00:19:33 +0200212 if (pm_print_times_enabled) {
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +0100213 pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev),
Shuah Khan53644672013-07-26 13:30:20 -0600214 error, (unsigned long long)nsecs >> 10);
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +0100215 }
Shuah Khan53644672013-07-26 13:30:20 -0600216
217 trace_device_pm_report_time(dev, info, nsecs, pm_verb(state.event),
218 error);
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +0100219}
220
Cornelia Huckffa6a702009-03-04 12:44:00 +0100221/**
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100222 * dpm_wait - Wait for a PM operation to complete.
223 * @dev: Device to wait for.
224 * @async: If unset, wait only if the device's power.async_suspend flag is set.
225 */
226static void dpm_wait(struct device *dev, bool async)
227{
228 if (!dev)
229 return;
230
Rafael J. Wysocki0e06b4a2010-01-23 22:25:15 +0100231 if (async || (pm_async_enabled && dev->power.async_suspend))
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100232 wait_for_completion(&dev->power.completion);
233}
234
235static int dpm_wait_fn(struct device *dev, void *async_ptr)
236{
237 dpm_wait(dev, *((bool *)async_ptr));
238 return 0;
239}
240
241static void dpm_wait_for_children(struct device *dev, bool async)
242{
243 device_for_each_child(dev, &async, dpm_wait_fn);
244}
245
246/**
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100247 * pm_op - Return the PM operation appropriate for given PM event.
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200248 * @ops: PM operations to choose from.
249 * @state: PM transition of the system being carried out.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200250 */
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100251static pm_callback_t pm_op(const struct dev_pm_ops *ops, pm_message_t state)
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200252{
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200253 switch (state.event) {
254#ifdef CONFIG_SUSPEND
255 case PM_EVENT_SUSPEND:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100256 return ops->suspend;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200257 case PM_EVENT_RESUME:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100258 return ops->resume;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200259#endif /* CONFIG_SUSPEND */
Rafael J. Wysocki1f112ce2011-04-11 22:54:42 +0200260#ifdef CONFIG_HIBERNATE_CALLBACKS
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200261 case PM_EVENT_FREEZE:
262 case PM_EVENT_QUIESCE:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100263 return ops->freeze;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200264 case PM_EVENT_HIBERNATE:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100265 return ops->poweroff;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200266 case PM_EVENT_THAW:
267 case PM_EVENT_RECOVER:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100268 return ops->thaw;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200269 break;
270 case PM_EVENT_RESTORE:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100271 return ops->restore;
Rafael J. Wysocki1f112ce2011-04-11 22:54:42 +0200272#endif /* CONFIG_HIBERNATE_CALLBACKS */
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200273 }
Arjan van de Venf2511772009-12-13 20:29:01 +0100274
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100275 return NULL;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200276}
277
278/**
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100279 * pm_late_early_op - Return the PM operation appropriate for given PM event.
280 * @ops: PM operations to choose from.
281 * @state: PM transition of the system being carried out.
282 *
283 * Runtime PM is disabled for @dev while this function is being executed.
284 */
285static pm_callback_t pm_late_early_op(const struct dev_pm_ops *ops,
286 pm_message_t state)
287{
288 switch (state.event) {
289#ifdef CONFIG_SUSPEND
290 case PM_EVENT_SUSPEND:
291 return ops->suspend_late;
292 case PM_EVENT_RESUME:
293 return ops->resume_early;
294#endif /* CONFIG_SUSPEND */
295#ifdef CONFIG_HIBERNATE_CALLBACKS
296 case PM_EVENT_FREEZE:
297 case PM_EVENT_QUIESCE:
298 return ops->freeze_late;
299 case PM_EVENT_HIBERNATE:
300 return ops->poweroff_late;
301 case PM_EVENT_THAW:
302 case PM_EVENT_RECOVER:
303 return ops->thaw_early;
304 case PM_EVENT_RESTORE:
305 return ops->restore_early;
306#endif /* CONFIG_HIBERNATE_CALLBACKS */
307 }
308
309 return NULL;
310}
311
312/**
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100313 * pm_noirq_op - Return the PM operation appropriate for given PM event.
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200314 * @ops: PM operations to choose from.
315 * @state: PM transition of the system being carried out.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200316 *
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200317 * The driver of @dev will not receive interrupts while this function is being
318 * executed.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200319 */
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100320static pm_callback_t pm_noirq_op(const struct dev_pm_ops *ops, pm_message_t state)
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200321{
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200322 switch (state.event) {
323#ifdef CONFIG_SUSPEND
324 case PM_EVENT_SUSPEND:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100325 return ops->suspend_noirq;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200326 case PM_EVENT_RESUME:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100327 return ops->resume_noirq;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200328#endif /* CONFIG_SUSPEND */
Rafael J. Wysocki1f112ce2011-04-11 22:54:42 +0200329#ifdef CONFIG_HIBERNATE_CALLBACKS
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200330 case PM_EVENT_FREEZE:
331 case PM_EVENT_QUIESCE:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100332 return ops->freeze_noirq;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200333 case PM_EVENT_HIBERNATE:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100334 return ops->poweroff_noirq;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200335 case PM_EVENT_THAW:
336 case PM_EVENT_RECOVER:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100337 return ops->thaw_noirq;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200338 case PM_EVENT_RESTORE:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100339 return ops->restore_noirq;
Rafael J. Wysocki1f112ce2011-04-11 22:54:42 +0200340#endif /* CONFIG_HIBERNATE_CALLBACKS */
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200341 }
Arjan van de Venf2511772009-12-13 20:29:01 +0100342
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100343 return NULL;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200344}
345
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200346static void pm_dev_dbg(struct device *dev, pm_message_t state, char *info)
347{
348 dev_dbg(dev, "%s%s%s\n", info, pm_verb(state.event),
349 ((state.event & PM_EVENT_SLEEP) && device_may_wakeup(dev)) ?
350 ", may wakeup" : "");
351}
352
353static void pm_dev_err(struct device *dev, pm_message_t state, char *info,
354 int error)
355{
356 printk(KERN_ERR "PM: Device %s failed to %s%s: error %d\n",
Rafael J. Wysocki5c1a07a2010-12-24 15:03:34 +0100357 dev_name(dev), pm_verb(state.event), info, error);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200358}
359
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +0100360static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info)
361{
362 ktime_t calltime;
Kevin Cernekee0702d9ee2010-09-20 22:32:10 +0200363 u64 usecs64;
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +0100364 int usecs;
365
366 calltime = ktime_get();
367 usecs64 = ktime_to_ns(ktime_sub(calltime, starttime));
368 do_div(usecs64, NSEC_PER_USEC);
369 usecs = usecs64;
370 if (usecs == 0)
371 usecs = 1;
372 pr_info("PM: %s%s%s of devices complete after %ld.%03ld msecs\n",
373 info ?: "", info ? " " : "", pm_verb(state.event),
374 usecs / USEC_PER_MSEC, usecs % USEC_PER_MSEC);
375}
376
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100377static int dpm_run_callback(pm_callback_t cb, struct device *dev,
378 pm_message_t state, char *info)
379{
380 ktime_t calltime;
381 int error;
382
383 if (!cb)
384 return 0;
385
386 calltime = initcall_debug_start(dev);
387
388 pm_dev_dbg(dev, state, info);
389 error = cb(dev);
390 suspend_report_result(cb, error);
391
Shuah Khan53644672013-07-26 13:30:20 -0600392 initcall_debug_report(dev, calltime, error, state, info);
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100393
394 return error;
395}
396
Benoit Goby70fea602013-10-17 10:48:46 -0700397#ifdef CONFIG_DPM_WATCHDOG
398struct dpm_watchdog {
399 struct device *dev;
400 struct task_struct *tsk;
401 struct timer_list timer;
402};
403
404#define DECLARE_DPM_WATCHDOG_ON_STACK(wd) \
405 struct dpm_watchdog wd
406
407/**
408 * dpm_watchdog_handler - Driver suspend / resume watchdog handler.
409 * @data: Watchdog object address.
410 *
411 * Called when a driver has timed out suspending or resuming.
412 * There's not much we can do here to recover so panic() to
413 * capture a crash-dump in pstore.
414 */
415static void dpm_watchdog_handler(unsigned long data)
416{
417 struct dpm_watchdog *wd = (void *)data;
418
419 dev_emerg(wd->dev, "**** DPM device timeout ****\n");
420 show_stack(wd->tsk, NULL);
421 panic("%s %s: unrecoverable failure\n",
422 dev_driver_string(wd->dev), dev_name(wd->dev));
423}
424
425/**
426 * dpm_watchdog_set - Enable pm watchdog for given device.
427 * @wd: Watchdog. Must be allocated on the stack.
428 * @dev: Device to handle.
429 */
430static void dpm_watchdog_set(struct dpm_watchdog *wd, struct device *dev)
431{
432 struct timer_list *timer = &wd->timer;
433
434 wd->dev = dev;
435 wd->tsk = current;
436
437 init_timer_on_stack(timer);
438 /* use same timeout value for both suspend and resume */
439 timer->expires = jiffies + HZ * CONFIG_DPM_WATCHDOG_TIMEOUT;
440 timer->function = dpm_watchdog_handler;
441 timer->data = (unsigned long)wd;
442 add_timer(timer);
443}
444
445/**
446 * dpm_watchdog_clear - Disable suspend/resume watchdog.
447 * @wd: Watchdog to disable.
448 */
449static void dpm_watchdog_clear(struct dpm_watchdog *wd)
450{
451 struct timer_list *timer = &wd->timer;
452
453 del_timer_sync(timer);
454 destroy_timer_on_stack(timer);
455}
456#else
457#define DECLARE_DPM_WATCHDOG_ON_STACK(wd)
458#define dpm_watchdog_set(x, y)
459#define dpm_watchdog_clear(x)
460#endif
461
Alan Sterncd59abf2007-09-21 15:36:56 -0400462/*------------------------- Resume routines -------------------------*/
463
464/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200465 * device_resume_noirq - Execute an "early resume" callback for given device.
466 * @dev: Device to handle.
467 * @state: PM transition of the system being carried out.
Alan Sterncd59abf2007-09-21 15:36:56 -0400468 *
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200469 * The driver of @dev will not receive interrupts while this function is being
470 * executed.
Alan Sterncd59abf2007-09-21 15:36:56 -0400471 */
Alan Sternd1616302009-05-24 22:05:42 +0200472static int device_resume_noirq(struct device *dev, pm_message_t state)
Alan Sterncd59abf2007-09-21 15:36:56 -0400473{
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100474 pm_callback_t callback = NULL;
475 char *info = NULL;
Alan Sterncd59abf2007-09-21 15:36:56 -0400476 int error = 0;
477
478 TRACE_DEVICE(dev);
479 TRACE_RESUME(0);
480
Rafael J. Wysockidbf37412012-08-06 01:46:39 +0200481 if (dev->power.syscore)
482 goto Out;
483
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +0800484 if (!dev->power.is_noirq_suspended)
485 goto Out;
486
Rafael J. Wysocki564b9052011-06-23 01:52:55 +0200487 if (dev->pm_domain) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100488 info = "noirq power domain ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100489 callback = pm_noirq_op(&dev->pm_domain->ops, state);
Rafael J. Wysocki4d27e9d2011-04-29 00:35:50 +0200490 } else if (dev->type && dev->type->pm) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100491 info = "noirq type ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100492 callback = pm_noirq_op(dev->type->pm, state);
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +0100493 } else if (dev->class && dev->class->pm) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100494 info = "noirq class ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100495 callback = pm_noirq_op(dev->class->pm, state);
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +0100496 } else if (dev->bus && dev->bus->pm) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100497 info = "noirq bus ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100498 callback = pm_noirq_op(dev->bus->pm, state);
Dominik Brodowskie7176a32010-03-15 21:43:11 +0100499 }
500
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100501 if (!callback && dev->driver && dev->driver->pm) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100502 info = "noirq driver ";
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100503 callback = pm_noirq_op(dev->driver->pm, state);
504 }
505
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100506 error = dpm_run_callback(callback, dev, state, info);
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +0800507 dev->power.is_noirq_suspended = false;
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100508
Rafael J. Wysockidbf37412012-08-06 01:46:39 +0200509 Out:
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100510 TRACE_RESUME(error);
511 return error;
512}
513
514/**
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100515 * dpm_resume_noirq - Execute "noirq resume" callbacks for all devices.
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200516 * @state: PM transition of the system being carried out.
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100517 *
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100518 * Call the "noirq" resume handlers for all devices in dpm_noirq_list and
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200519 * enable device drivers to receive interrupts.
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100520 */
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100521static void dpm_resume_noirq(pm_message_t state)
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100522{
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +0100523 ktime_t starttime = ktime_get();
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100524
Rafael J. Wysocki32bdfac2009-05-24 21:15:07 +0200525 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +0100526 while (!list_empty(&dpm_noirq_list)) {
527 struct device *dev = to_device(dpm_noirq_list.next);
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +0100528 int error;
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +0100529
530 get_device(dev);
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100531 list_move_tail(&dev->power.entry, &dpm_late_early_list);
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +0100532 mutex_unlock(&dpm_list_mtx);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100533
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +0100534 error = device_resume_noirq(dev, state);
ShuoX Liu2a77c462011-08-10 23:01:26 +0200535 if (error) {
536 suspend_stats.failed_resume_noirq++;
537 dpm_save_failed_step(SUSPEND_RESUME_NOIRQ);
538 dpm_save_failed_dev(dev_name(dev));
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100539 pm_dev_err(dev, state, " noirq", error);
540 }
541
542 mutex_lock(&dpm_list_mtx);
543 put_device(dev);
544 }
545 mutex_unlock(&dpm_list_mtx);
546 dpm_show_time(starttime, state, "noirq");
547 resume_device_irqs();
Preeti U Murthy8651f972012-07-09 10:12:56 +0200548 cpuidle_resume();
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100549}
550
551/**
552 * device_resume_early - Execute an "early resume" callback for given device.
553 * @dev: Device to handle.
554 * @state: PM transition of the system being carried out.
555 *
556 * Runtime PM is disabled for @dev while this function is being executed.
557 */
558static int device_resume_early(struct device *dev, pm_message_t state)
559{
560 pm_callback_t callback = NULL;
561 char *info = NULL;
562 int error = 0;
563
564 TRACE_DEVICE(dev);
565 TRACE_RESUME(0);
566
Rafael J. Wysockidbf37412012-08-06 01:46:39 +0200567 if (dev->power.syscore)
568 goto Out;
569
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +0800570 if (!dev->power.is_late_suspended)
571 goto Out;
572
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100573 if (dev->pm_domain) {
574 info = "early power domain ";
575 callback = pm_late_early_op(&dev->pm_domain->ops, state);
576 } else if (dev->type && dev->type->pm) {
577 info = "early type ";
578 callback = pm_late_early_op(dev->type->pm, state);
579 } else if (dev->class && dev->class->pm) {
580 info = "early class ";
581 callback = pm_late_early_op(dev->class->pm, state);
582 } else if (dev->bus && dev->bus->pm) {
583 info = "early bus ";
584 callback = pm_late_early_op(dev->bus->pm, state);
585 }
586
587 if (!callback && dev->driver && dev->driver->pm) {
588 info = "early driver ";
589 callback = pm_late_early_op(dev->driver->pm, state);
590 }
591
592 error = dpm_run_callback(callback, dev, state, info);
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +0800593 dev->power.is_late_suspended = false;
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100594
Rafael J. Wysockidbf37412012-08-06 01:46:39 +0200595 Out:
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100596 TRACE_RESUME(error);
Rafael J. Wysocki9f6d8f62012-12-22 23:59:01 +0100597
598 pm_runtime_enable(dev);
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100599 return error;
600}
601
602/**
603 * dpm_resume_early - Execute "early resume" callbacks for all devices.
604 * @state: PM transition of the system being carried out.
605 */
606static void dpm_resume_early(pm_message_t state)
607{
608 ktime_t starttime = ktime_get();
609
610 mutex_lock(&dpm_list_mtx);
611 while (!list_empty(&dpm_late_early_list)) {
612 struct device *dev = to_device(dpm_late_early_list.next);
613 int error;
614
615 get_device(dev);
616 list_move_tail(&dev->power.entry, &dpm_suspended_list);
617 mutex_unlock(&dpm_list_mtx);
618
619 error = device_resume_early(dev, state);
620 if (error) {
621 suspend_stats.failed_resume_early++;
622 dpm_save_failed_step(SUSPEND_RESUME_EARLY);
623 dpm_save_failed_dev(dev_name(dev));
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +0100624 pm_dev_err(dev, state, " early", error);
ShuoX Liu2a77c462011-08-10 23:01:26 +0200625 }
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +0100626
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +0100627 mutex_lock(&dpm_list_mtx);
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +0100628 put_device(dev);
629 }
Rafael J. Wysocki32bdfac2009-05-24 21:15:07 +0200630 mutex_unlock(&dpm_list_mtx);
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +0100631 dpm_show_time(starttime, state, "early");
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100632}
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100633
634/**
635 * dpm_resume_start - Execute "noirq" and "early" device callbacks.
636 * @state: PM transition of the system being carried out.
637 */
638void dpm_resume_start(pm_message_t state)
639{
640 dpm_resume_noirq(state);
641 dpm_resume_early(state);
642}
643EXPORT_SYMBOL_GPL(dpm_resume_start);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100644
645/**
Rafael J. Wysocki97df8c12010-01-23 22:25:31 +0100646 * device_resume - Execute "resume" callbacks for given device.
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200647 * @dev: Device to handle.
648 * @state: PM transition of the system being carried out.
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100649 * @async: If true, the device is being resumed asynchronously.
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100650 */
Rafael J. Wysocki97df8c12010-01-23 22:25:31 +0100651static int device_resume(struct device *dev, pm_message_t state, bool async)
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100652{
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100653 pm_callback_t callback = NULL;
654 char *info = NULL;
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100655 int error = 0;
Benoit Goby70fea602013-10-17 10:48:46 -0700656 DECLARE_DPM_WATCHDOG_ON_STACK(wd);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100657
658 TRACE_DEVICE(dev);
659 TRACE_RESUME(0);
Alan Sterncd59abf2007-09-21 15:36:56 -0400660
Rafael J. Wysockidbf37412012-08-06 01:46:39 +0200661 if (dev->power.syscore)
662 goto Complete;
663
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100664 dpm_wait(dev->parent, async);
Benoit Goby70fea602013-10-17 10:48:46 -0700665 dpm_watchdog_set(&wd, dev);
Greg Kroah-Hartman8e9394c2010-02-17 10:57:05 -0800666 device_lock(dev);
Rafael J. Wysocki7a8d37a2008-02-25 00:35:04 +0100667
Alan Sternf76b168b2011-06-18 20:22:23 +0200668 /*
669 * This is a fib. But we'll allow new children to be added below
670 * a resumed device, even if the device hasn't been completed yet.
671 */
672 dev->power.is_prepared = false;
Rafael J. Wysocki97df8c12010-01-23 22:25:31 +0100673
Alan Stern6d0e0e82011-06-18 22:42:09 +0200674 if (!dev->power.is_suspended)
675 goto Unlock;
676
Rafael J. Wysocki564b9052011-06-23 01:52:55 +0200677 if (dev->pm_domain) {
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100678 info = "power domain ";
679 callback = pm_op(&dev->pm_domain->ops, state);
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100680 goto Driver;
Rafael J. Wysocki7538e3d2011-02-16 21:53:17 +0100681 }
682
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +0100683 if (dev->type && dev->type->pm) {
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100684 info = "type ";
685 callback = pm_op(dev->type->pm, state);
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100686 goto Driver;
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +0100687 }
688
689 if (dev->class) {
690 if (dev->class->pm) {
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100691 info = "class ";
692 callback = pm_op(dev->class->pm, state);
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100693 goto Driver;
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +0100694 } else if (dev->class->resume) {
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100695 info = "legacy class ";
696 callback = dev->class->resume;
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +0100697 goto End;
698 }
699 }
700
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200701 if (dev->bus) {
702 if (dev->bus->pm) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100703 info = "bus ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100704 callback = pm_op(dev->bus->pm, state);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200705 } else if (dev->bus->resume) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100706 info = "legacy bus ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100707 callback = dev->bus->resume;
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100708 goto End;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200709 }
Alan Sterncd59abf2007-09-21 15:36:56 -0400710 }
711
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100712 Driver:
713 if (!callback && dev->driver && dev->driver->pm) {
714 info = "driver ";
715 callback = pm_op(dev->driver->pm, state);
716 }
717
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200718 End:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100719 error = dpm_run_callback(callback, dev, state, info);
Alan Stern6d0e0e82011-06-18 22:42:09 +0200720 dev->power.is_suspended = false;
721
722 Unlock:
Greg Kroah-Hartman8e9394c2010-02-17 10:57:05 -0800723 device_unlock(dev);
Benoit Goby70fea602013-10-17 10:48:46 -0700724 dpm_watchdog_clear(&wd);
Rafael J. Wysockidbf37412012-08-06 01:46:39 +0200725
726 Complete:
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100727 complete_all(&dev->power.completion);
Rafael J. Wysocki7a8d37a2008-02-25 00:35:04 +0100728
Alan Sterncd59abf2007-09-21 15:36:56 -0400729 TRACE_RESUME(error);
Rafael J. Wysocki1e2ef052011-07-06 10:51:58 +0200730
Alan Sterncd59abf2007-09-21 15:36:56 -0400731 return error;
732}
733
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100734static void async_resume(void *data, async_cookie_t cookie)
735{
736 struct device *dev = (struct device *)data;
737 int error;
738
Rafael J. Wysocki97df8c12010-01-23 22:25:31 +0100739 error = device_resume(dev, pm_transition, true);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100740 if (error)
741 pm_dev_err(dev, pm_transition, " async", error);
742 put_device(dev);
743}
744
Rafael J. Wysocki97df8c12010-01-23 22:25:31 +0100745static bool is_async(struct device *dev)
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100746{
Rafael J. Wysocki97df8c12010-01-23 22:25:31 +0100747 return dev->power.async_suspend && pm_async_enabled
748 && !pm_trace_is_enabled();
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100749}
750
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100751/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200752 * dpm_resume - Execute "resume" callbacks for non-sysdev devices.
753 * @state: PM transition of the system being carried out.
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100754 *
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200755 * Execute the appropriate "resume" callback for all devices whose status
756 * indicates that they are suspended.
Alan Sterncd59abf2007-09-21 15:36:56 -0400757 */
Rafael J. Wysocki91e7c752011-05-17 23:26:00 +0200758void dpm_resume(pm_message_t state)
Alan Sterncd59abf2007-09-21 15:36:56 -0400759{
Rafael J. Wysocki97df8c12010-01-23 22:25:31 +0100760 struct device *dev;
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +0100761 ktime_t starttime = ktime_get();
Alan Sterncd59abf2007-09-21 15:36:56 -0400762
Rafael J. Wysocki91e7c752011-05-17 23:26:00 +0200763 might_sleep();
764
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200765 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100766 pm_transition = state;
Rafael J. Wysocki098dff72010-09-22 22:10:57 +0200767 async_error = 0;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200768
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +0100769 list_for_each_entry(dev, &dpm_suspended_list, power.entry) {
Wolfram Sang16735d02013-11-14 14:32:02 -0800770 reinit_completion(&dev->power.completion);
Rafael J. Wysocki97df8c12010-01-23 22:25:31 +0100771 if (is_async(dev)) {
772 get_device(dev);
773 async_schedule(async_resume, dev);
774 }
775 }
776
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +0100777 while (!list_empty(&dpm_suspended_list)) {
778 dev = to_device(dpm_suspended_list.next);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200779 get_device(dev);
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +0100780 if (!is_async(dev)) {
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200781 int error;
782
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200783 mutex_unlock(&dpm_list_mtx);
784
Rafael J. Wysocki97df8c12010-01-23 22:25:31 +0100785 error = device_resume(dev, state, false);
ShuoX Liu2a77c462011-08-10 23:01:26 +0200786 if (error) {
787 suspend_stats.failed_resume++;
788 dpm_save_failed_step(SUSPEND_RESUME);
789 dpm_save_failed_dev(dev_name(dev));
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200790 pm_dev_err(dev, state, "", error);
ShuoX Liu2a77c462011-08-10 23:01:26 +0200791 }
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +0100792
793 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200794 }
795 if (!list_empty(&dev->power.entry))
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +0100796 list_move_tail(&dev->power.entry, &dpm_prepared_list);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200797 put_device(dev);
Alan Sterncd59abf2007-09-21 15:36:56 -0400798 }
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200799 mutex_unlock(&dpm_list_mtx);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100800 async_synchronize_full();
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +0100801 dpm_show_time(starttime, state, NULL);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200802}
803
804/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200805 * device_complete - Complete a PM transition for given device.
806 * @dev: Device to handle.
807 * @state: PM transition of the system being carried out.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200808 */
Alan Sternd1616302009-05-24 22:05:42 +0200809static void device_complete(struct device *dev, pm_message_t state)
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200810{
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100811 void (*callback)(struct device *) = NULL;
812 char *info = NULL;
813
Rafael J. Wysockidbf37412012-08-06 01:46:39 +0200814 if (dev->power.syscore)
815 return;
816
Greg Kroah-Hartman8e9394c2010-02-17 10:57:05 -0800817 device_lock(dev);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200818
Rafael J. Wysocki564b9052011-06-23 01:52:55 +0200819 if (dev->pm_domain) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100820 info = "completing power domain ";
821 callback = dev->pm_domain->ops.complete;
Rafael J. Wysocki4d27e9d2011-04-29 00:35:50 +0200822 } else if (dev->type && dev->type->pm) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100823 info = "completing type ";
824 callback = dev->type->pm->complete;
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +0100825 } else if (dev->class && dev->class->pm) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100826 info = "completing class ";
827 callback = dev->class->pm->complete;
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +0100828 } else if (dev->bus && dev->bus->pm) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100829 info = "completing bus ";
830 callback = dev->bus->pm->complete;
831 }
832
833 if (!callback && dev->driver && dev->driver->pm) {
834 info = "completing driver ";
835 callback = dev->driver->pm->complete;
836 }
837
838 if (callback) {
839 pm_dev_dbg(dev, state, info);
840 callback(dev);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200841 }
842
Greg Kroah-Hartman8e9394c2010-02-17 10:57:05 -0800843 device_unlock(dev);
Alan Stern88d26132012-09-19 21:59:02 +0200844
Ulf Hanssonaf939332013-04-12 09:41:06 +0000845 pm_runtime_put(dev);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200846}
847
848/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200849 * dpm_complete - Complete a PM transition for all non-sysdev devices.
850 * @state: PM transition of the system being carried out.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200851 *
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200852 * Execute the ->complete() callbacks for all devices whose PM status is not
853 * DPM_ON (this allows new devices to be registered).
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200854 */
Rafael J. Wysocki91e7c752011-05-17 23:26:00 +0200855void dpm_complete(pm_message_t state)
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200856{
857 struct list_head list;
858
Rafael J. Wysocki91e7c752011-05-17 23:26:00 +0200859 might_sleep();
860
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200861 INIT_LIST_HEAD(&list);
862 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +0100863 while (!list_empty(&dpm_prepared_list)) {
864 struct device *dev = to_device(dpm_prepared_list.prev);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200865
866 get_device(dev);
Alan Sternf76b168b2011-06-18 20:22:23 +0200867 dev->power.is_prepared = false;
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +0100868 list_move(&dev->power.entry, &list);
869 mutex_unlock(&dpm_list_mtx);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200870
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +0100871 device_complete(dev, state);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200872
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +0100873 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200874 put_device(dev);
875 }
876 list_splice(&list, &dpm_list);
Alan Sterncd59abf2007-09-21 15:36:56 -0400877 mutex_unlock(&dpm_list_mtx);
878}
879
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100880/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200881 * dpm_resume_end - Execute "resume" callbacks and complete system transition.
882 * @state: PM transition of the system being carried out.
Alan Sterncd59abf2007-09-21 15:36:56 -0400883 *
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200884 * Execute "resume" callbacks for all devices and complete the PM transition of
885 * the system.
Alan Sterncd59abf2007-09-21 15:36:56 -0400886 */
Alan Sternd1616302009-05-24 22:05:42 +0200887void dpm_resume_end(pm_message_t state)
Alan Sterncd59abf2007-09-21 15:36:56 -0400888{
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200889 dpm_resume(state);
890 dpm_complete(state);
Alan Sterncd59abf2007-09-21 15:36:56 -0400891}
Alan Sternd1616302009-05-24 22:05:42 +0200892EXPORT_SYMBOL_GPL(dpm_resume_end);
Alan Sterncd59abf2007-09-21 15:36:56 -0400893
894
Alan Sterncd59abf2007-09-21 15:36:56 -0400895/*------------------------- Suspend routines -------------------------*/
896
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200897/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200898 * resume_event - Return a "resume" message for given "suspend" sleep state.
899 * @sleep_state: PM message representing a sleep state.
900 *
901 * Return a PM message representing the resume event corresponding to given
902 * sleep state.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200903 */
904static pm_message_t resume_event(pm_message_t sleep_state)
Alan Sterncd59abf2007-09-21 15:36:56 -0400905{
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200906 switch (sleep_state.event) {
907 case PM_EVENT_SUSPEND:
908 return PMSG_RESUME;
909 case PM_EVENT_FREEZE:
910 case PM_EVENT_QUIESCE:
911 return PMSG_RECOVER;
912 case PM_EVENT_HIBERNATE:
913 return PMSG_RESTORE;
Alan Sterncd59abf2007-09-21 15:36:56 -0400914 }
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200915 return PMSG_ON;
Alan Sterncd59abf2007-09-21 15:36:56 -0400916}
917
918/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200919 * device_suspend_noirq - Execute a "late suspend" callback for given device.
920 * @dev: Device to handle.
921 * @state: PM transition of the system being carried out.
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100922 *
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200923 * The driver of @dev will not receive interrupts while this function is being
924 * executed.
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100925 */
Alan Sternd1616302009-05-24 22:05:42 +0200926static int device_suspend_noirq(struct device *dev, pm_message_t state)
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100927{
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100928 pm_callback_t callback = NULL;
929 char *info = NULL;
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +0800930 int error;
Dominik Brodowskie7176a32010-03-15 21:43:11 +0100931
Rafael J. Wysockidbf37412012-08-06 01:46:39 +0200932 if (dev->power.syscore)
933 return 0;
934
Rafael J. Wysocki564b9052011-06-23 01:52:55 +0200935 if (dev->pm_domain) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100936 info = "noirq power domain ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100937 callback = pm_noirq_op(&dev->pm_domain->ops, state);
Rafael J. Wysocki4d27e9d2011-04-29 00:35:50 +0200938 } else if (dev->type && dev->type->pm) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100939 info = "noirq type ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100940 callback = pm_noirq_op(dev->type->pm, state);
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +0100941 } else if (dev->class && dev->class->pm) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100942 info = "noirq class ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100943 callback = pm_noirq_op(dev->class->pm, state);
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +0100944 } else if (dev->bus && dev->bus->pm) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100945 info = "noirq bus ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100946 callback = pm_noirq_op(dev->bus->pm, state);
Rafael J. Wysocki7538e3d2011-02-16 21:53:17 +0100947 }
948
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100949 if (!callback && dev->driver && dev->driver->pm) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100950 info = "noirq driver ";
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100951 callback = pm_noirq_op(dev->driver->pm, state);
952 }
953
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +0800954 error = dpm_run_callback(callback, dev, state, info);
955 if (!error)
956 dev->power.is_noirq_suspended = true;
957
958 return error;
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100959}
960
961/**
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100962 * dpm_suspend_noirq - Execute "noirq suspend" callbacks for all devices.
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200963 * @state: PM transition of the system being carried out.
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100964 *
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200965 * Prevent device drivers from receiving interrupts and call the "noirq" suspend
966 * handlers for all non-sysdev devices.
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100967 */
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100968static int dpm_suspend_noirq(pm_message_t state)
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100969{
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +0100970 ktime_t starttime = ktime_get();
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100971 int error = 0;
972
Preeti U Murthy8651f972012-07-09 10:12:56 +0200973 cpuidle_pause();
Rafael J. Wysocki2ed8d2b32009-03-16 22:34:06 +0100974 suspend_device_irqs();
Rafael J. Wysocki32bdfac2009-05-24 21:15:07 +0200975 mutex_lock(&dpm_list_mtx);
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100976 while (!list_empty(&dpm_late_early_list)) {
977 struct device *dev = to_device(dpm_late_early_list.prev);
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +0100978
979 get_device(dev);
980 mutex_unlock(&dpm_list_mtx);
981
Alan Sternd1616302009-05-24 22:05:42 +0200982 error = device_suspend_noirq(dev, state);
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +0100983
984 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100985 if (error) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100986 pm_dev_err(dev, state, " noirq", error);
ShuoX Liu2a77c462011-08-10 23:01:26 +0200987 suspend_stats.failed_suspend_noirq++;
988 dpm_save_failed_step(SUSPEND_SUSPEND_NOIRQ);
989 dpm_save_failed_dev(dev_name(dev));
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +0100990 put_device(dev);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100991 break;
992 }
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +0100993 if (!list_empty(&dev->power.entry))
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +0100994 list_move(&dev->power.entry, &dpm_noirq_list);
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +0100995 put_device(dev);
Rafael J. Wysocki52d136c2012-04-29 22:52:19 +0200996
997 if (pm_wakeup_pending()) {
998 error = -EBUSY;
999 break;
1000 }
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001001 }
Rafael J. Wysocki32bdfac2009-05-24 21:15:07 +02001002 mutex_unlock(&dpm_list_mtx);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001003 if (error)
Alan Sternd1616302009-05-24 22:05:42 +02001004 dpm_resume_noirq(resume_event(state));
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +01001005 else
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001006 dpm_show_time(starttime, state, "noirq");
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001007 return error;
1008}
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001009
1010/**
1011 * device_suspend_late - Execute a "late suspend" callback for given device.
1012 * @dev: Device to handle.
1013 * @state: PM transition of the system being carried out.
1014 *
1015 * Runtime PM is disabled for @dev while this function is being executed.
1016 */
1017static int device_suspend_late(struct device *dev, pm_message_t state)
1018{
1019 pm_callback_t callback = NULL;
1020 char *info = NULL;
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +08001021 int error;
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001022
Rafael J. Wysocki9f6d8f62012-12-22 23:59:01 +01001023 __pm_runtime_disable(dev, false);
1024
Rafael J. Wysockidbf37412012-08-06 01:46:39 +02001025 if (dev->power.syscore)
1026 return 0;
1027
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001028 if (dev->pm_domain) {
1029 info = "late power domain ";
1030 callback = pm_late_early_op(&dev->pm_domain->ops, state);
1031 } else if (dev->type && dev->type->pm) {
1032 info = "late type ";
1033 callback = pm_late_early_op(dev->type->pm, state);
1034 } else if (dev->class && dev->class->pm) {
1035 info = "late class ";
1036 callback = pm_late_early_op(dev->class->pm, state);
1037 } else if (dev->bus && dev->bus->pm) {
1038 info = "late bus ";
1039 callback = pm_late_early_op(dev->bus->pm, state);
1040 }
1041
1042 if (!callback && dev->driver && dev->driver->pm) {
1043 info = "late driver ";
1044 callback = pm_late_early_op(dev->driver->pm, state);
1045 }
1046
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +08001047 error = dpm_run_callback(callback, dev, state, info);
1048 if (!error)
1049 dev->power.is_late_suspended = true;
1050
1051 return error;
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001052}
1053
1054/**
1055 * dpm_suspend_late - Execute "late suspend" callbacks for all devices.
1056 * @state: PM transition of the system being carried out.
1057 */
1058static int dpm_suspend_late(pm_message_t state)
1059{
1060 ktime_t starttime = ktime_get();
1061 int error = 0;
1062
1063 mutex_lock(&dpm_list_mtx);
1064 while (!list_empty(&dpm_suspended_list)) {
1065 struct device *dev = to_device(dpm_suspended_list.prev);
1066
1067 get_device(dev);
1068 mutex_unlock(&dpm_list_mtx);
1069
1070 error = device_suspend_late(dev, state);
1071
1072 mutex_lock(&dpm_list_mtx);
1073 if (error) {
1074 pm_dev_err(dev, state, " late", error);
1075 suspend_stats.failed_suspend_late++;
1076 dpm_save_failed_step(SUSPEND_SUSPEND_LATE);
1077 dpm_save_failed_dev(dev_name(dev));
1078 put_device(dev);
1079 break;
1080 }
1081 if (!list_empty(&dev->power.entry))
1082 list_move(&dev->power.entry, &dpm_late_early_list);
1083 put_device(dev);
Rafael J. Wysocki52d136c2012-04-29 22:52:19 +02001084
1085 if (pm_wakeup_pending()) {
1086 error = -EBUSY;
1087 break;
1088 }
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001089 }
1090 mutex_unlock(&dpm_list_mtx);
1091 if (error)
1092 dpm_resume_early(resume_event(state));
1093 else
1094 dpm_show_time(starttime, state, "late");
1095
1096 return error;
1097}
1098
1099/**
1100 * dpm_suspend_end - Execute "late" and "noirq" device suspend callbacks.
1101 * @state: PM transition of the system being carried out.
1102 */
1103int dpm_suspend_end(pm_message_t state)
1104{
1105 int error = dpm_suspend_late(state);
Colin Cross064b0212012-07-19 10:38:06 +02001106 if (error)
1107 return error;
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001108
Colin Cross064b0212012-07-19 10:38:06 +02001109 error = dpm_suspend_noirq(state);
1110 if (error) {
Feng Hong997a0312012-09-19 14:16:00 +02001111 dpm_resume_early(resume_event(state));
Colin Cross064b0212012-07-19 10:38:06 +02001112 return error;
1113 }
1114
1115 return 0;
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001116}
1117EXPORT_SYMBOL_GPL(dpm_suspend_end);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001118
1119/**
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +01001120 * legacy_suspend - Execute a legacy (bus or class) suspend callback for device.
Randy Dunlap0a884222010-01-08 14:42:57 -08001121 * @dev: Device to suspend.
1122 * @state: PM transition of the system being carried out.
1123 * @cb: Suspend callback to execute.
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +01001124 */
1125static int legacy_suspend(struct device *dev, pm_message_t state,
Shuah Khan53644672013-07-26 13:30:20 -06001126 int (*cb)(struct device *dev, pm_message_t state),
1127 char *info)
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +01001128{
1129 int error;
1130 ktime_t calltime;
1131
1132 calltime = initcall_debug_start(dev);
1133
1134 error = cb(dev, state);
1135 suspend_report_result(cb, error);
1136
Shuah Khan53644672013-07-26 13:30:20 -06001137 initcall_debug_report(dev, calltime, error, state, info);
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +01001138
1139 return error;
1140}
1141
1142/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001143 * device_suspend - Execute "suspend" callbacks for given device.
1144 * @dev: Device to handle.
1145 * @state: PM transition of the system being carried out.
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001146 * @async: If true, the device is being suspended asynchronously.
Alan Sterncd59abf2007-09-21 15:36:56 -04001147 */
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001148static int __device_suspend(struct device *dev, pm_message_t state, bool async)
Alan Sterncd59abf2007-09-21 15:36:56 -04001149{
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +01001150 pm_callback_t callback = NULL;
1151 char *info = NULL;
Alan Sterncd59abf2007-09-21 15:36:56 -04001152 int error = 0;
Benoit Goby70fea602013-10-17 10:48:46 -07001153 DECLARE_DPM_WATCHDOG_ON_STACK(wd);
Alan Sterncd59abf2007-09-21 15:36:56 -04001154
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001155 dpm_wait_for_children(dev, async);
Rafael J. Wysocki7a8d37a2008-02-25 00:35:04 +01001156
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001157 if (async_error)
Mandeep Singh Baines1f758b22012-06-24 23:31:09 +02001158 goto Complete;
Rafael J. Wysocki1e2ef052011-07-06 10:51:58 +02001159
Alan Stern88d26132012-09-19 21:59:02 +02001160 /*
1161 * If a device configured to wake up the system from sleep states
1162 * has been suspended at run time and there's a resume request pending
1163 * for it, this is equivalent to the device signaling wakeup, so the
1164 * system suspend operation should be aborted.
1165 */
Rafael J. Wysocki1e2ef052011-07-06 10:51:58 +02001166 if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
1167 pm_wakeup_event(dev, 0);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001168
Rafael J. Wysockid83f9052010-12-03 23:14:26 +01001169 if (pm_wakeup_pending()) {
1170 async_error = -EBUSY;
Mandeep Singh Baines1f758b22012-06-24 23:31:09 +02001171 goto Complete;
Rafael J. Wysockid83f9052010-12-03 23:14:26 +01001172 }
1173
Rafael J. Wysockidbf37412012-08-06 01:46:39 +02001174 if (dev->power.syscore)
1175 goto Complete;
1176
Benoit Goby70fea602013-10-17 10:48:46 -07001177 dpm_watchdog_set(&wd, dev);
Rafael J. Wysocki1e2ef052011-07-06 10:51:58 +02001178 device_lock(dev);
1179
Rafael J. Wysocki564b9052011-06-23 01:52:55 +02001180 if (dev->pm_domain) {
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +01001181 info = "power domain ";
1182 callback = pm_op(&dev->pm_domain->ops, state);
1183 goto Run;
Rafael J. Wysocki4d27e9d2011-04-29 00:35:50 +02001184 }
1185
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +01001186 if (dev->type && dev->type->pm) {
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +01001187 info = "type ";
1188 callback = pm_op(dev->type->pm, state);
1189 goto Run;
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +01001190 }
1191
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001192 if (dev->class) {
1193 if (dev->class->pm) {
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +01001194 info = "class ";
1195 callback = pm_op(dev->class->pm, state);
1196 goto Run;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001197 } else if (dev->class->suspend) {
1198 pm_dev_dbg(dev, state, "legacy class ");
Shuah Khan53644672013-07-26 13:30:20 -06001199 error = legacy_suspend(dev, state, dev->class->suspend,
1200 "legacy class ");
Rafael J. Wysocki4d27e9d2011-04-29 00:35:50 +02001201 goto End;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001202 }
Alan Sterncd59abf2007-09-21 15:36:56 -04001203 }
1204
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001205 if (dev->bus) {
1206 if (dev->bus->pm) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001207 info = "bus ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +01001208 callback = pm_op(dev->bus->pm, state);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001209 } else if (dev->bus->suspend) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001210 pm_dev_dbg(dev, state, "legacy bus ");
Shuah Khan53644672013-07-26 13:30:20 -06001211 error = legacy_suspend(dev, state, dev->bus->suspend,
1212 "legacy bus ");
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +01001213 goto End;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001214 }
Rafael J. Wysocki7538e3d2011-02-16 21:53:17 +01001215 }
1216
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +01001217 Run:
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001218 if (!callback && dev->driver && dev->driver->pm) {
1219 info = "driver ";
1220 callback = pm_op(dev->driver->pm, state);
1221 }
1222
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +01001223 error = dpm_run_callback(callback, dev, state, info);
1224
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001225 End:
Rafael J. Wysocki4ca46ff2011-10-16 23:34:36 +02001226 if (!error) {
1227 dev->power.is_suspended = true;
Rafael J. Wysocki8b258cc2011-11-17 21:39:33 +01001228 if (dev->power.wakeup_path
1229 && dev->parent && !dev->parent->power.ignore_children)
Rafael J. Wysocki4ca46ff2011-10-16 23:34:36 +02001230 dev->parent->power.wakeup_path = true;
1231 }
Alan Stern6d0e0e82011-06-18 22:42:09 +02001232
Greg Kroah-Hartman8e9394c2010-02-17 10:57:05 -08001233 device_unlock(dev);
Benoit Goby70fea602013-10-17 10:48:46 -07001234 dpm_watchdog_clear(&wd);
Mandeep Singh Baines1f758b22012-06-24 23:31:09 +02001235
1236 Complete:
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001237 complete_all(&dev->power.completion);
Alan Stern88d26132012-09-19 21:59:02 +02001238 if (error)
Rafael J. Wysocki098dff72010-09-22 22:10:57 +02001239 async_error = error;
1240
Alan Sterncd59abf2007-09-21 15:36:56 -04001241 return error;
1242}
1243
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001244static void async_suspend(void *data, async_cookie_t cookie)
1245{
1246 struct device *dev = (struct device *)data;
1247 int error;
1248
1249 error = __device_suspend(dev, pm_transition, true);
ShuoX Liu2a77c462011-08-10 23:01:26 +02001250 if (error) {
1251 dpm_save_failed_dev(dev_name(dev));
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001252 pm_dev_err(dev, pm_transition, " async", error);
ShuoX Liu2a77c462011-08-10 23:01:26 +02001253 }
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001254
1255 put_device(dev);
1256}
1257
1258static int device_suspend(struct device *dev)
1259{
Wolfram Sang16735d02013-11-14 14:32:02 -08001260 reinit_completion(&dev->power.completion);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001261
Rafael J. Wysocki0e06b4a2010-01-23 22:25:15 +01001262 if (pm_async_enabled && dev->power.async_suspend) {
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001263 get_device(dev);
1264 async_schedule(async_suspend, dev);
1265 return 0;
1266 }
1267
1268 return __device_suspend(dev, pm_transition, false);
1269}
1270
Alan Sterncd59abf2007-09-21 15:36:56 -04001271/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001272 * dpm_suspend - Execute "suspend" callbacks for all non-sysdev devices.
1273 * @state: PM transition of the system being carried out.
Alan Sterncd59abf2007-09-21 15:36:56 -04001274 */
Rafael J. Wysocki91e7c752011-05-17 23:26:00 +02001275int dpm_suspend(pm_message_t state)
Alan Sterncd59abf2007-09-21 15:36:56 -04001276{
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +01001277 ktime_t starttime = ktime_get();
Alan Sterncd59abf2007-09-21 15:36:56 -04001278 int error = 0;
1279
Rafael J. Wysocki91e7c752011-05-17 23:26:00 +02001280 might_sleep();
1281
Alan Sterncd59abf2007-09-21 15:36:56 -04001282 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001283 pm_transition = state;
1284 async_error = 0;
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +01001285 while (!list_empty(&dpm_prepared_list)) {
1286 struct device *dev = to_device(dpm_prepared_list.prev);
Alan Sterncd59abf2007-09-21 15:36:56 -04001287
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001288 get_device(dev);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001289 mutex_unlock(&dpm_list_mtx);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001290
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001291 error = device_suspend(dev);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001292
Alan Stern1b3cbec2008-02-29 11:50:22 -05001293 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001294 if (error) {
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001295 pm_dev_err(dev, state, "", error);
ShuoX Liu2a77c462011-08-10 23:01:26 +02001296 dpm_save_failed_dev(dev_name(dev));
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001297 put_device(dev);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001298 break;
1299 }
Rafael J. Wysocki7a8d37a2008-02-25 00:35:04 +01001300 if (!list_empty(&dev->power.entry))
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +01001301 list_move(&dev->power.entry, &dpm_suspended_list);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001302 put_device(dev);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001303 if (async_error)
1304 break;
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001305 }
1306 mutex_unlock(&dpm_list_mtx);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001307 async_synchronize_full();
1308 if (!error)
1309 error = async_error;
ShuoX Liu2a77c462011-08-10 23:01:26 +02001310 if (error) {
1311 suspend_stats.failed_suspend++;
1312 dpm_save_failed_step(SUSPEND_SUSPEND);
1313 } else
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +01001314 dpm_show_time(starttime, state, NULL);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001315 return error;
1316}
1317
1318/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001319 * device_prepare - Prepare a device for system power transition.
1320 * @dev: Device to handle.
1321 * @state: PM transition of the system being carried out.
1322 *
1323 * Execute the ->prepare() callback(s) for given device. No new children of the
1324 * device may be registered after this function has returned.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001325 */
Alan Sternd1616302009-05-24 22:05:42 +02001326static int device_prepare(struct device *dev, pm_message_t state)
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001327{
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001328 int (*callback)(struct device *) = NULL;
1329 char *info = NULL;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001330 int error = 0;
1331
Rafael J. Wysockidbf37412012-08-06 01:46:39 +02001332 if (dev->power.syscore)
1333 return 0;
1334
Alan Stern88d26132012-09-19 21:59:02 +02001335 /*
1336 * If a device's parent goes into runtime suspend at the wrong time,
1337 * it won't be possible to resume the device. To prevent this we
1338 * block runtime suspend here, during the prepare phase, and allow
1339 * it again during the complete phase.
1340 */
1341 pm_runtime_get_noresume(dev);
1342
Greg Kroah-Hartman8e9394c2010-02-17 10:57:05 -08001343 device_lock(dev);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001344
Rafael J. Wysocki4ca46ff2011-10-16 23:34:36 +02001345 dev->power.wakeup_path = device_may_wakeup(dev);
1346
Rafael J. Wysocki564b9052011-06-23 01:52:55 +02001347 if (dev->pm_domain) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001348 info = "preparing power domain ";
1349 callback = dev->pm_domain->ops.prepare;
Rafael J. Wysocki4d27e9d2011-04-29 00:35:50 +02001350 } else if (dev->type && dev->type->pm) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001351 info = "preparing type ";
1352 callback = dev->type->pm->prepare;
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +01001353 } else if (dev->class && dev->class->pm) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001354 info = "preparing class ";
1355 callback = dev->class->pm->prepare;
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +01001356 } else if (dev->bus && dev->bus->pm) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001357 info = "preparing bus ";
1358 callback = dev->bus->pm->prepare;
1359 }
1360
1361 if (!callback && dev->driver && dev->driver->pm) {
1362 info = "preparing driver ";
1363 callback = dev->driver->pm->prepare;
1364 }
1365
1366 if (callback) {
1367 error = callback(dev);
1368 suspend_report_result(callback, error);
Rafael J. Wysocki7538e3d2011-02-16 21:53:17 +01001369 }
1370
Greg Kroah-Hartman8e9394c2010-02-17 10:57:05 -08001371 device_unlock(dev);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001372
Ulf Hanssonaa1b9f12013-11-13 15:45:03 +01001373 if (error)
1374 pm_runtime_put(dev);
1375
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001376 return error;
1377}
1378
1379/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001380 * dpm_prepare - Prepare all non-sysdev devices for a system PM transition.
1381 * @state: PM transition of the system being carried out.
Alan Sterncd59abf2007-09-21 15:36:56 -04001382 *
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001383 * Execute the ->prepare() callback(s) for all devices.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001384 */
Rafael J. Wysocki91e7c752011-05-17 23:26:00 +02001385int dpm_prepare(pm_message_t state)
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001386{
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001387 int error = 0;
1388
Rafael J. Wysocki91e7c752011-05-17 23:26:00 +02001389 might_sleep();
1390
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001391 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001392 while (!list_empty(&dpm_list)) {
1393 struct device *dev = to_device(dpm_list.next);
1394
1395 get_device(dev);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001396 mutex_unlock(&dpm_list_mtx);
1397
Rafael J. Wysocki1e2ef052011-07-06 10:51:58 +02001398 error = device_prepare(dev, state);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001399
1400 mutex_lock(&dpm_list_mtx);
1401 if (error) {
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001402 if (error == -EAGAIN) {
1403 put_device(dev);
Sebastian Ott886a7a32009-07-08 13:26:05 +02001404 error = 0;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001405 continue;
1406 }
Rafael J. Wysocki1e752272010-12-03 22:58:05 +01001407 printk(KERN_INFO "PM: Device %s not prepared "
1408 "for power transition: code %d\n",
Rafael J. Wysocki5c1a07a2010-12-24 15:03:34 +01001409 dev_name(dev), error);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001410 put_device(dev);
1411 break;
1412 }
Alan Sternf76b168b2011-06-18 20:22:23 +02001413 dev->power.is_prepared = true;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001414 if (!list_empty(&dev->power.entry))
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +01001415 list_move_tail(&dev->power.entry, &dpm_prepared_list);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001416 put_device(dev);
1417 }
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001418 mutex_unlock(&dpm_list_mtx);
1419 return error;
1420}
1421
1422/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001423 * dpm_suspend_start - Prepare devices for PM transition and suspend them.
1424 * @state: PM transition of the system being carried out.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001425 *
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001426 * Prepare all non-sysdev devices for system PM transition and execute "suspend"
1427 * callbacks for them.
Alan Sterncd59abf2007-09-21 15:36:56 -04001428 */
Alan Sternd1616302009-05-24 22:05:42 +02001429int dpm_suspend_start(pm_message_t state)
Alan Sterncd59abf2007-09-21 15:36:56 -04001430{
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001431 int error;
Alan Sterncd59abf2007-09-21 15:36:56 -04001432
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001433 error = dpm_prepare(state);
ShuoX Liu2a77c462011-08-10 23:01:26 +02001434 if (error) {
1435 suspend_stats.failed_prepare++;
1436 dpm_save_failed_step(SUSPEND_PREPARE);
1437 } else
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001438 error = dpm_suspend(state);
Alan Sterncd59abf2007-09-21 15:36:56 -04001439 return error;
Alan Sterncd59abf2007-09-21 15:36:56 -04001440}
Alan Sternd1616302009-05-24 22:05:42 +02001441EXPORT_SYMBOL_GPL(dpm_suspend_start);
Alan Sterncd59abf2007-09-21 15:36:56 -04001442
1443void __suspend_report_result(const char *function, void *fn, int ret)
1444{
Bjorn Helgaasc80cfb02008-10-15 22:01:35 -07001445 if (ret)
1446 printk(KERN_ERR "%s(): %pF returns %d\n", function, fn, ret);
Alan Sterncd59abf2007-09-21 15:36:56 -04001447}
1448EXPORT_SYMBOL_GPL(__suspend_report_result);
Rafael J. Wysockif8824ce2010-01-27 23:47:38 +01001449
1450/**
1451 * device_pm_wait_for_dev - Wait for suspend/resume of a device to complete.
1452 * @dev: Device to wait for.
1453 * @subordinate: Device that needs to wait for @dev.
1454 */
Rafael J. Wysocki098dff72010-09-22 22:10:57 +02001455int device_pm_wait_for_dev(struct device *subordinate, struct device *dev)
Rafael J. Wysockif8824ce2010-01-27 23:47:38 +01001456{
1457 dpm_wait(dev, subordinate->power.async_suspend);
Rafael J. Wysocki098dff72010-09-22 22:10:57 +02001458 return async_error;
Rafael J. Wysockif8824ce2010-01-27 23:47:38 +01001459}
1460EXPORT_SYMBOL_GPL(device_pm_wait_for_dev);
Ming Leidfe32122012-08-17 22:06:59 +08001461
1462/**
1463 * dpm_for_each_dev - device iterator.
1464 * @data: data for the callback.
1465 * @fn: function to be called for each device.
1466 *
1467 * Iterate over devices in dpm_list, and call @fn for each device,
1468 * passing it @data.
1469 */
1470void dpm_for_each_dev(void *data, void (*fn)(struct device *, void *))
1471{
1472 struct device *dev;
1473
1474 if (!fn)
1475 return;
1476
1477 device_pm_lock();
1478 list_for_each_entry(dev, &dpm_list, power.entry)
1479 fn(dev, data);
1480 device_pm_unlock();
1481}
1482EXPORT_SYMBOL_GPL(dpm_for_each_dev);