blob: 0992e67e862b7d7e8a154ae9319f48be171fe2e7 [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>
Paul Gortmaker1b6bc322011-05-27 07:12:15 -040021#include <linux/export.h>
Matthias Kaehlcke11048dc2007-05-23 14:19:41 -070022#include <linux/mutex.h>
Alan Sterncd59abf2007-09-21 15:36:56 -040023#include <linux/pm.h>
Rafael J. Wysocki5e928f72009-08-18 23:38:32 +020024#include <linux/pm_runtime.h>
Zhonghui Fu431d4522015-03-18 15:54:27 +010025#include <linux/pm-trace.h>
Tony Lindgren4990d4f2015-05-18 15:40:29 -070026#include <linux/pm_wakeirq.h>
Rafael J. Wysocki2ed8d2b2009-03-16 22:34:06 +010027#include <linux/interrupt.h>
Arjan van de Venf2511772009-12-13 20:29:01 +010028#include <linux/sched.h>
Ingo Molnarb17b0152017-02-08 18:51:35 +010029#include <linux/sched/debug.h>
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +010030#include <linux/async.h>
Rafael J. Wysocki1e75227e2010-12-03 22:58:05 +010031#include <linux/suspend.h>
Shuah Khan53644672013-07-26 13:30:20 -060032#include <trace/events/power.h>
Viresh Kumar2f0aea92014-03-04 11:00:26 +080033#include <linux/cpufreq.h>
Preeti U Murthy8651f972012-07-09 10:12:56 +020034#include <linux/cpuidle.h>
Lukasz Luba6e863842018-12-05 12:05:55 +010035#include <linux/devfreq.h>
Benoit Goby70fea602013-10-17 10:48:46 -070036#include <linux/timer.h>
37
Alan Sterncd59abf2007-09-21 15:36:56 -040038#include "../base.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070039#include "power.h"
40
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +010041typedef int (*pm_callback_t)(struct device *);
42
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +010043/*
Rafael J. Wysocki1eede072008-05-20 23:00:01 +020044 * The entries in the dpm_list list are in a depth first order, simply
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +010045 * because children are guaranteed to be discovered after parents, and
46 * are inserted at the back of the list on discovery.
47 *
Greg Kroah-Hartman8e9394c2010-02-17 10:57:05 -080048 * Since device_pm_add() may be called with a device lock held,
49 * we must never try to acquire a device lock while holding
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +010050 * dpm_list_mutex.
51 */
52
Rafael J. Wysocki1eede072008-05-20 23:00:01 +020053LIST_HEAD(dpm_list);
Sachin Kamat7664e962012-07-17 22:38:08 +020054static LIST_HEAD(dpm_prepared_list);
55static LIST_HEAD(dpm_suspended_list);
56static LIST_HEAD(dpm_late_early_list);
57static LIST_HEAD(dpm_noirq_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
ShuoX Liu2a77c462011-08-10 23:01:26 +020059struct suspend_stats suspend_stats;
Alan Sterncd59abf2007-09-21 15:36:56 -040060static DEFINE_MUTEX(dpm_list_mtx);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +010061static pm_message_t pm_transition;
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
Rafael J. Wysocki098dff72010-09-22 22:10:57 +020063static int async_error;
64
Krzysztof Kozlowski952856d2017-06-12 17:19:31 +020065static const char *pm_verb(int event)
Shuah Khan53644672013-07-26 13:30:20 -060066{
67 switch (event) {
68 case PM_EVENT_SUSPEND:
69 return "suspend";
70 case PM_EVENT_RESUME:
71 return "resume";
72 case PM_EVENT_FREEZE:
73 return "freeze";
74 case PM_EVENT_QUIESCE:
75 return "quiesce";
76 case PM_EVENT_HIBERNATE:
77 return "hibernate";
78 case PM_EVENT_THAW:
79 return "thaw";
80 case PM_EVENT_RESTORE:
81 return "restore";
82 case PM_EVENT_RECOVER:
83 return "recover";
84 default:
85 return "(unknown PM event)";
86 }
87}
88
Rafael J. Wysocki1eede072008-05-20 23:00:01 +020089/**
Rafael J. Wysockie91c11b2012-08-06 01:44:28 +020090 * device_pm_sleep_init - Initialize system suspend-related device fields.
Rafael J. Wysocki5e928f72009-08-18 23:38:32 +020091 * @dev: Device object being initialized.
92 */
Rafael J. Wysockie91c11b2012-08-06 01:44:28 +020093void device_pm_sleep_init(struct device *dev)
Rafael J. Wysocki5e928f72009-08-18 23:38:32 +020094{
Alan Sternf76b168b2011-06-18 20:22:23 +020095 dev->power.is_prepared = false;
Alan Stern6d0e0e82011-06-18 22:42:09 +020096 dev->power.is_suspended = false;
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +080097 dev->power.is_noirq_suspended = false;
98 dev->power.is_late_suspended = false;
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +010099 init_completion(&dev->power.completion);
Colin Cross152e1d52010-09-03 01:24:07 +0200100 complete_all(&dev->power.completion);
Rafael J. Wysocki074037e2010-09-22 22:09:10 +0200101 dev->power.wakeup = NULL;
Rafael J. Wysocki22110fa2011-04-26 11:33:09 +0200102 INIT_LIST_HEAD(&dev->power.entry);
Rafael J. Wysocki5e928f72009-08-18 23:38:32 +0200103}
104
105/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200106 * device_pm_lock - Lock the list of active devices used by the PM core.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200107 */
108void device_pm_lock(void)
109{
110 mutex_lock(&dpm_list_mtx);
111}
112
113/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200114 * device_pm_unlock - Unlock the list of active devices used by the PM core.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200115 */
116void device_pm_unlock(void)
117{
118 mutex_unlock(&dpm_list_mtx);
119}
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100120
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100121/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200122 * device_pm_add - Add a device to the PM core's list of active devices.
123 * @dev: Device to add to the list.
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100124 */
Alan Stern3b98aea2008-08-07 13:06:12 -0400125void device_pm_add(struct device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127 pr_debug("PM: Adding info for %s:%s\n",
Rafael J. Wysocki5c1a07a2010-12-24 15:03:34 +0100128 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
Tomeu Vizosoaa8e54b52016-01-07 16:46:14 +0100129 device_pm_check_callbacks(dev);
Matthias Kaehlcke11048dc2007-05-23 14:19:41 -0700130 mutex_lock(&dpm_list_mtx);
Alan Sternf76b168b2011-06-18 20:22:23 +0200131 if (dev->parent && dev->parent->power.is_prepared)
Rafael J. Wysockib64959e2010-12-16 17:11:45 +0100132 dev_warn(dev, "parent %s should not be sleeping\n",
133 dev_name(dev->parent));
Alan Stern3b98aea2008-08-07 13:06:12 -0400134 list_add_tail(&dev->power.entry, &dpm_list);
Rafael J. Wysocki9ed98952016-10-30 17:32:16 +0100135 dev->power.in_dpm_list = true;
Rafael J. Wysocki1a9a9152011-09-29 22:29:44 +0200136 mutex_unlock(&dpm_list_mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137}
138
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100139/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200140 * device_pm_remove - Remove a device from the PM core's list of active devices.
141 * @dev: Device to be removed from the list.
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100142 */
Rafael J. Wysocki9cddad72007-06-13 15:53:34 +0200143void device_pm_remove(struct device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144{
145 pr_debug("PM: Removing info for %s:%s\n",
Rafael J. Wysocki5c1a07a2010-12-24 15:03:34 +0100146 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100147 complete_all(&dev->power.completion);
Matthias Kaehlcke11048dc2007-05-23 14:19:41 -0700148 mutex_lock(&dpm_list_mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 list_del_init(&dev->power.entry);
Rafael J. Wysocki9ed98952016-10-30 17:32:16 +0100150 dev->power.in_dpm_list = false;
Matthias Kaehlcke11048dc2007-05-23 14:19:41 -0700151 mutex_unlock(&dpm_list_mtx);
Rafael J. Wysocki074037e2010-09-22 22:09:10 +0200152 device_wakeup_disable(dev);
Rafael J. Wysocki5e928f72009-08-18 23:38:32 +0200153 pm_runtime_remove(dev);
Tomeu Vizosoaa8e54b52016-01-07 16:46:14 +0100154 device_pm_check_callbacks(dev);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100155}
156
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200157/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200158 * device_pm_move_before - Move device in the PM core's list of active devices.
159 * @deva: Device to move in dpm_list.
160 * @devb: Device @deva should come before.
Cornelia Huckffa6a702009-03-04 12:44:00 +0100161 */
162void device_pm_move_before(struct device *deva, struct device *devb)
163{
164 pr_debug("PM: Moving %s:%s before %s:%s\n",
Rafael J. Wysocki5c1a07a2010-12-24 15:03:34 +0100165 deva->bus ? deva->bus->name : "No Bus", dev_name(deva),
166 devb->bus ? devb->bus->name : "No Bus", dev_name(devb));
Cornelia Huckffa6a702009-03-04 12:44:00 +0100167 /* Delete deva from dpm_list and reinsert before devb. */
168 list_move_tail(&deva->power.entry, &devb->power.entry);
169}
170
171/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200172 * device_pm_move_after - Move device in the PM core's list of active devices.
173 * @deva: Device to move in dpm_list.
174 * @devb: Device @deva should come after.
Cornelia Huckffa6a702009-03-04 12:44:00 +0100175 */
176void device_pm_move_after(struct device *deva, struct device *devb)
177{
178 pr_debug("PM: Moving %s:%s after %s:%s\n",
Rafael J. Wysocki5c1a07a2010-12-24 15:03:34 +0100179 deva->bus ? deva->bus->name : "No Bus", dev_name(deva),
180 devb->bus ? devb->bus->name : "No Bus", dev_name(devb));
Cornelia Huckffa6a702009-03-04 12:44:00 +0100181 /* Delete deva from dpm_list and reinsert after devb. */
182 list_move(&deva->power.entry, &devb->power.entry);
183}
184
185/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200186 * device_pm_move_last - Move device to end of the PM core's list of devices.
187 * @dev: Device to move in dpm_list.
Cornelia Huckffa6a702009-03-04 12:44:00 +0100188 */
189void device_pm_move_last(struct device *dev)
190{
191 pr_debug("PM: Moving %s:%s to end of list\n",
Rafael J. Wysocki5c1a07a2010-12-24 15:03:34 +0100192 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
Cornelia Huckffa6a702009-03-04 12:44:00 +0100193 list_move_tail(&dev->power.entry, &dpm_list);
194}
195
Bjorn Helgaas7f817ba2018-04-26 16:36:41 -0500196static ktime_t initcall_debug_start(struct device *dev, void *cb)
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +0100197{
Bjorn Helgaas143711f2018-04-26 16:36:34 -0500198 if (!pm_print_times_enabled)
199 return 0;
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +0100200
Bjorn Helgaas7f817ba2018-04-26 16:36:41 -0500201 dev_info(dev, "calling %pF @ %i, parent: %s\n", cb,
202 task_pid_nr(current),
203 dev->parent ? dev_name(dev->parent) : "none");
Bjorn Helgaas143711f2018-04-26 16:36:34 -0500204 return ktime_get();
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +0100205}
206
207static void initcall_debug_report(struct device *dev, ktime_t calltime,
Bjorn Helgaas7f817ba2018-04-26 16:36:41 -0500208 void *cb, int error)
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +0100209{
Shuah Khan53644672013-07-26 13:30:20 -0600210 ktime_t rettime;
211 s64 nsecs;
212
Bjorn Helgaas143711f2018-04-26 16:36:34 -0500213 if (!pm_print_times_enabled)
214 return;
215
Shuah Khan53644672013-07-26 13:30:20 -0600216 rettime = ktime_get();
217 nsecs = (s64) ktime_to_ns(ktime_sub(rettime, calltime));
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +0100218
Bjorn Helgaas7f817ba2018-04-26 16:36:41 -0500219 dev_info(dev, "%pF returned %d after %Ld usecs\n", cb, error,
220 (unsigned long long)nsecs >> 10);
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +0100221}
222
Cornelia Huckffa6a702009-03-04 12:44:00 +0100223/**
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100224 * dpm_wait - Wait for a PM operation to complete.
225 * @dev: Device to wait for.
226 * @async: If unset, wait only if the device's power.async_suspend flag is set.
227 */
228static void dpm_wait(struct device *dev, bool async)
229{
230 if (!dev)
231 return;
232
Rafael J. Wysocki0e06b4a2010-01-23 22:25:15 +0100233 if (async || (pm_async_enabled && dev->power.async_suspend))
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100234 wait_for_completion(&dev->power.completion);
235}
236
237static int dpm_wait_fn(struct device *dev, void *async_ptr)
238{
239 dpm_wait(dev, *((bool *)async_ptr));
240 return 0;
241}
242
243static void dpm_wait_for_children(struct device *dev, bool async)
244{
245 device_for_each_child(dev, &async, dpm_wait_fn);
246}
247
Rafael J. Wysocki8c73b422016-10-30 17:28:49 +0100248static void dpm_wait_for_suppliers(struct device *dev, bool async)
249{
250 struct device_link *link;
251 int idx;
252
253 idx = device_links_read_lock();
254
255 /*
256 * If the supplier goes away right after we've checked the link to it,
257 * we'll wait for its completion to change the state, but that's fine,
258 * because the only things that will block as a result are the SRCU
259 * callbacks freeing the link objects for the links in the list we're
260 * walking.
261 */
262 list_for_each_entry_rcu(link, &dev->links.suppliers, c_node)
263 if (READ_ONCE(link->status) != DL_STATE_DORMANT)
264 dpm_wait(link->supplier, async);
265
266 device_links_read_unlock(idx);
267}
268
269static void dpm_wait_for_superior(struct device *dev, bool async)
270{
271 dpm_wait(dev->parent, async);
272 dpm_wait_for_suppliers(dev, async);
273}
274
275static void dpm_wait_for_consumers(struct device *dev, bool async)
276{
277 struct device_link *link;
278 int idx;
279
280 idx = device_links_read_lock();
281
282 /*
283 * The status of a device link can only be changed from "dormant" by a
284 * probe, but that cannot happen during system suspend/resume. In
285 * theory it can change to "dormant" at that time, but then it is
286 * reasonable to wait for the target device anyway (eg. if it goes
287 * away, it's better to wait for it to go away completely and then
288 * continue instead of trying to continue in parallel with its
289 * unregistration).
290 */
291 list_for_each_entry_rcu(link, &dev->links.consumers, s_node)
292 if (READ_ONCE(link->status) != DL_STATE_DORMANT)
293 dpm_wait(link->consumer, async);
294
295 device_links_read_unlock(idx);
296}
297
298static void dpm_wait_for_subordinate(struct device *dev, bool async)
299{
300 dpm_wait_for_children(dev, async);
301 dpm_wait_for_consumers(dev, async);
302}
303
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100304/**
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100305 * pm_op - Return the PM operation appropriate for given PM event.
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200306 * @ops: PM operations to choose from.
307 * @state: PM transition of the system being carried out.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200308 */
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100309static pm_callback_t pm_op(const struct dev_pm_ops *ops, pm_message_t state)
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200310{
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200311 switch (state.event) {
312#ifdef CONFIG_SUSPEND
313 case PM_EVENT_SUSPEND:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100314 return ops->suspend;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200315 case PM_EVENT_RESUME:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100316 return ops->resume;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200317#endif /* CONFIG_SUSPEND */
Rafael J. Wysocki1f112ce2011-04-11 22:54:42 +0200318#ifdef CONFIG_HIBERNATE_CALLBACKS
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200319 case PM_EVENT_FREEZE:
320 case PM_EVENT_QUIESCE:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100321 return ops->freeze;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200322 case PM_EVENT_HIBERNATE:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100323 return ops->poweroff;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200324 case PM_EVENT_THAW:
325 case PM_EVENT_RECOVER:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100326 return ops->thaw;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200327 break;
328 case PM_EVENT_RESTORE:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100329 return ops->restore;
Rafael J. Wysocki1f112ce2011-04-11 22:54:42 +0200330#endif /* CONFIG_HIBERNATE_CALLBACKS */
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200331 }
Arjan van de Venf2511772009-12-13 20:29:01 +0100332
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100333 return NULL;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200334}
335
336/**
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100337 * pm_late_early_op - Return the PM operation appropriate for given PM event.
338 * @ops: PM operations to choose from.
339 * @state: PM transition of the system being carried out.
340 *
341 * Runtime PM is disabled for @dev while this function is being executed.
342 */
343static pm_callback_t pm_late_early_op(const struct dev_pm_ops *ops,
344 pm_message_t state)
345{
346 switch (state.event) {
347#ifdef CONFIG_SUSPEND
348 case PM_EVENT_SUSPEND:
349 return ops->suspend_late;
350 case PM_EVENT_RESUME:
351 return ops->resume_early;
352#endif /* CONFIG_SUSPEND */
353#ifdef CONFIG_HIBERNATE_CALLBACKS
354 case PM_EVENT_FREEZE:
355 case PM_EVENT_QUIESCE:
356 return ops->freeze_late;
357 case PM_EVENT_HIBERNATE:
358 return ops->poweroff_late;
359 case PM_EVENT_THAW:
360 case PM_EVENT_RECOVER:
361 return ops->thaw_early;
362 case PM_EVENT_RESTORE:
363 return ops->restore_early;
364#endif /* CONFIG_HIBERNATE_CALLBACKS */
365 }
366
367 return NULL;
368}
369
370/**
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100371 * pm_noirq_op - Return the PM operation appropriate for given PM event.
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200372 * @ops: PM operations to choose from.
373 * @state: PM transition of the system being carried out.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200374 *
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200375 * The driver of @dev will not receive interrupts while this function is being
376 * executed.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200377 */
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100378static pm_callback_t pm_noirq_op(const struct dev_pm_ops *ops, pm_message_t state)
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200379{
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200380 switch (state.event) {
381#ifdef CONFIG_SUSPEND
382 case PM_EVENT_SUSPEND:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100383 return ops->suspend_noirq;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200384 case PM_EVENT_RESUME:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100385 return ops->resume_noirq;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200386#endif /* CONFIG_SUSPEND */
Rafael J. Wysocki1f112ce2011-04-11 22:54:42 +0200387#ifdef CONFIG_HIBERNATE_CALLBACKS
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200388 case PM_EVENT_FREEZE:
389 case PM_EVENT_QUIESCE:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100390 return ops->freeze_noirq;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200391 case PM_EVENT_HIBERNATE:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100392 return ops->poweroff_noirq;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200393 case PM_EVENT_THAW:
394 case PM_EVENT_RECOVER:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100395 return ops->thaw_noirq;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200396 case PM_EVENT_RESTORE:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100397 return ops->restore_noirq;
Rafael J. Wysocki1f112ce2011-04-11 22:54:42 +0200398#endif /* CONFIG_HIBERNATE_CALLBACKS */
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200399 }
Arjan van de Venf2511772009-12-13 20:29:01 +0100400
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100401 return NULL;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200402}
403
Krzysztof Kozlowskie3771fa2017-06-12 17:19:32 +0200404static void pm_dev_dbg(struct device *dev, pm_message_t state, const char *info)
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200405{
406 dev_dbg(dev, "%s%s%s\n", info, pm_verb(state.event),
407 ((state.event & PM_EVENT_SLEEP) && device_may_wakeup(dev)) ?
408 ", may wakeup" : "");
409}
410
Krzysztof Kozlowskie3771fa2017-06-12 17:19:32 +0200411static void pm_dev_err(struct device *dev, pm_message_t state, const char *info,
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200412 int error)
413{
414 printk(KERN_ERR "PM: Device %s failed to %s%s: error %d\n",
Rafael J. Wysocki5c1a07a2010-12-24 15:03:34 +0100415 dev_name(dev), pm_verb(state.event), info, error);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200416}
417
Rafael J. Wysocki48059c092017-07-21 02:10:22 +0200418static void dpm_show_time(ktime_t starttime, pm_message_t state, int error,
Krzysztof Kozlowskie3771fa2017-06-12 17:19:32 +0200419 const char *info)
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +0100420{
421 ktime_t calltime;
Kevin Cernekee0702d9ee2010-09-20 22:32:10 +0200422 u64 usecs64;
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +0100423 int usecs;
424
425 calltime = ktime_get();
426 usecs64 = ktime_to_ns(ktime_sub(calltime, starttime));
427 do_div(usecs64, NSEC_PER_USEC);
428 usecs = usecs64;
429 if (usecs == 0)
430 usecs = 1;
Rafael J. Wysocki8d8b2442017-07-19 02:38:44 +0200431
Rafael J. Wysocki48059c092017-07-21 02:10:22 +0200432 pm_pr_dbg("%s%s%s of devices %s after %ld.%03ld msecs\n",
Rafael J. Wysocki8d8b2442017-07-19 02:38:44 +0200433 info ?: "", info ? " " : "", pm_verb(state.event),
Rafael J. Wysocki48059c092017-07-21 02:10:22 +0200434 error ? "aborted" : "complete",
Rafael J. Wysocki8d8b2442017-07-19 02:38:44 +0200435 usecs / USEC_PER_MSEC, usecs % USEC_PER_MSEC);
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +0100436}
437
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100438static int dpm_run_callback(pm_callback_t cb, struct device *dev,
Krzysztof Kozlowskie3771fa2017-06-12 17:19:32 +0200439 pm_message_t state, const char *info)
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100440{
441 ktime_t calltime;
442 int error;
443
444 if (!cb)
445 return 0;
446
Bjorn Helgaas7f817ba2018-04-26 16:36:41 -0500447 calltime = initcall_debug_start(dev, cb);
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100448
449 pm_dev_dbg(dev, state, info);
Todd E Brandte8bca472014-06-10 07:31:22 -0700450 trace_device_pm_callback_start(dev, info, state.event);
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100451 error = cb(dev);
Todd E Brandte8bca472014-06-10 07:31:22 -0700452 trace_device_pm_callback_end(dev, error);
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100453 suspend_report_result(cb, error);
454
Bjorn Helgaas7f817ba2018-04-26 16:36:41 -0500455 initcall_debug_report(dev, calltime, cb, error);
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100456
457 return error;
458}
459
Benoit Goby70fea602013-10-17 10:48:46 -0700460#ifdef CONFIG_DPM_WATCHDOG
461struct dpm_watchdog {
462 struct device *dev;
463 struct task_struct *tsk;
464 struct timer_list timer;
465};
466
467#define DECLARE_DPM_WATCHDOG_ON_STACK(wd) \
468 struct dpm_watchdog wd
469
470/**
471 * dpm_watchdog_handler - Driver suspend / resume watchdog handler.
472 * @data: Watchdog object address.
473 *
474 * Called when a driver has timed out suspending or resuming.
475 * There's not much we can do here to recover so panic() to
476 * capture a crash-dump in pstore.
477 */
Kees Cook9c6c2732017-10-04 16:26:57 -0700478static void dpm_watchdog_handler(struct timer_list *t)
Benoit Goby70fea602013-10-17 10:48:46 -0700479{
Kees Cook9c6c2732017-10-04 16:26:57 -0700480 struct dpm_watchdog *wd = from_timer(wd, t, timer);
Benoit Goby70fea602013-10-17 10:48:46 -0700481
482 dev_emerg(wd->dev, "**** DPM device timeout ****\n");
483 show_stack(wd->tsk, NULL);
484 panic("%s %s: unrecoverable failure\n",
485 dev_driver_string(wd->dev), dev_name(wd->dev));
486}
487
488/**
489 * dpm_watchdog_set - Enable pm watchdog for given device.
490 * @wd: Watchdog. Must be allocated on the stack.
491 * @dev: Device to handle.
492 */
493static void dpm_watchdog_set(struct dpm_watchdog *wd, struct device *dev)
494{
495 struct timer_list *timer = &wd->timer;
496
497 wd->dev = dev;
498 wd->tsk = current;
499
Kees Cook9c6c2732017-10-04 16:26:57 -0700500 timer_setup_on_stack(timer, dpm_watchdog_handler, 0);
Benoit Goby70fea602013-10-17 10:48:46 -0700501 /* use same timeout value for both suspend and resume */
502 timer->expires = jiffies + HZ * CONFIG_DPM_WATCHDOG_TIMEOUT;
Benoit Goby70fea602013-10-17 10:48:46 -0700503 add_timer(timer);
504}
505
506/**
507 * dpm_watchdog_clear - Disable suspend/resume watchdog.
508 * @wd: Watchdog to disable.
509 */
510static void dpm_watchdog_clear(struct dpm_watchdog *wd)
511{
512 struct timer_list *timer = &wd->timer;
513
514 del_timer_sync(timer);
515 destroy_timer_on_stack(timer);
516}
517#else
518#define DECLARE_DPM_WATCHDOG_ON_STACK(wd)
519#define dpm_watchdog_set(x, y)
520#define dpm_watchdog_clear(x)
521#endif
522
Alan Sterncd59abf2007-09-21 15:36:56 -0400523/*------------------------- Resume routines -------------------------*/
524
525/**
Rafael J. Wysocki34879722017-12-07 02:41:18 +0100526 * dev_pm_skip_next_resume_phases - Skip next system resume phases for device.
527 * @dev: Target device.
528 *
529 * Make the core skip the "early resume" and "resume" phases for @dev.
530 *
531 * This function can be called by middle-layer code during the "noirq" phase of
532 * system resume if necessary, but not by device drivers.
533 */
534void dev_pm_skip_next_resume_phases(struct device *dev)
535{
536 dev->power.is_late_suspended = false;
537 dev->power.is_suspended = false;
538}
539
540/**
Rafael J. Wysocki75e94642017-12-10 01:00:45 +0100541 * suspend_event - Return a "suspend" message for given "resume" one.
542 * @resume_msg: PM message representing a system-wide resume transition.
543 */
544static pm_message_t suspend_event(pm_message_t resume_msg)
545{
546 switch (resume_msg.event) {
547 case PM_EVENT_RESUME:
548 return PMSG_SUSPEND;
549 case PM_EVENT_THAW:
550 case PM_EVENT_RESTORE:
551 return PMSG_FREEZE;
552 case PM_EVENT_RECOVER:
553 return PMSG_HIBERNATE;
554 }
555 return PMSG_ON;
556}
557
558/**
Rafael J. Wysocki0d4b54c2017-11-18 15:31:49 +0100559 * dev_pm_may_skip_resume - System-wide device resume optimization check.
560 * @dev: Target device.
561 *
562 * Checks whether or not the device may be left in suspend after a system-wide
563 * transition to the working state.
564 */
565bool dev_pm_may_skip_resume(struct device *dev)
566{
567 return !dev->power.must_resume && pm_transition.event != PM_EVENT_RESTORE;
568}
569
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +0100570static pm_callback_t dpm_subsys_resume_noirq_cb(struct device *dev,
571 pm_message_t state,
572 const char **info_p)
Alan Sterncd59abf2007-09-21 15:36:56 -0400573{
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +0100574 pm_callback_t callback;
575 const char *info;
Liu, Chuansheng76569fa2014-02-18 10:28:45 +0800576
Rafael J. Wysocki564b9052011-06-23 01:52:55 +0200577 if (dev->pm_domain) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100578 info = "noirq power domain ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100579 callback = pm_noirq_op(&dev->pm_domain->ops, state);
Rafael J. Wysocki4d27e9d2011-04-29 00:35:50 +0200580 } else if (dev->type && dev->type->pm) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100581 info = "noirq type ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100582 callback = pm_noirq_op(dev->type->pm, state);
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +0100583 } else if (dev->class && dev->class->pm) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100584 info = "noirq class ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100585 callback = pm_noirq_op(dev->class->pm, state);
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +0100586 } else if (dev->bus && dev->bus->pm) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100587 info = "noirq bus ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100588 callback = pm_noirq_op(dev->bus->pm, state);
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +0100589 } else {
590 return NULL;
Dominik Brodowskie7176a32010-03-15 21:43:11 +0100591 }
592
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +0100593 if (info_p)
594 *info_p = info;
595
596 return callback;
597}
598
Rafael J. Wysocki75e94642017-12-10 01:00:45 +0100599static pm_callback_t dpm_subsys_suspend_noirq_cb(struct device *dev,
600 pm_message_t state,
601 const char **info_p);
602
603static pm_callback_t dpm_subsys_suspend_late_cb(struct device *dev,
604 pm_message_t state,
605 const char **info_p);
606
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +0100607/**
608 * device_resume_noirq - Execute a "noirq resume" callback for given device.
609 * @dev: Device to handle.
610 * @state: PM transition of the system being carried out.
611 * @async: If true, the device is being resumed asynchronously.
612 *
613 * The driver of @dev will not receive interrupts while this function is being
614 * executed.
615 */
616static int device_resume_noirq(struct device *dev, pm_message_t state, bool async)
617{
618 pm_callback_t callback;
619 const char *info;
Rafael J. Wysocki32bfa562017-12-10 01:02:13 +0100620 bool skip_resume;
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +0100621 int error = 0;
622
623 TRACE_DEVICE(dev);
624 TRACE_RESUME(0);
625
626 if (dev->power.syscore || dev->power.direct_complete)
627 goto Out;
628
629 if (!dev->power.is_noirq_suspended)
630 goto Out;
631
632 dpm_wait_for_superior(dev, async);
633
Rafael J. Wysocki32bfa562017-12-10 01:02:13 +0100634 skip_resume = dev_pm_may_skip_resume(dev);
635
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +0100636 callback = dpm_subsys_resume_noirq_cb(dev, state, &info);
Rafael J. Wysocki75e94642017-12-10 01:00:45 +0100637 if (callback)
638 goto Run;
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +0100639
Rafael J. Wysocki32bfa562017-12-10 01:02:13 +0100640 if (skip_resume)
641 goto Skip;
642
Rafael J. Wysocki75e94642017-12-10 01:00:45 +0100643 if (dev_pm_smart_suspend_and_suspended(dev)) {
644 pm_message_t suspend_msg = suspend_event(state);
645
646 /*
647 * If "freeze" callbacks have been skipped during a transition
648 * related to hibernation, the subsequent "thaw" callbacks must
649 * be skipped too or bad things may happen. Otherwise, resume
650 * callbacks are going to be run for the device, so its runtime
651 * PM status must be changed to reflect the new state after the
652 * transition under way.
653 */
654 if (!dpm_subsys_suspend_late_cb(dev, suspend_msg, NULL) &&
655 !dpm_subsys_suspend_noirq_cb(dev, suspend_msg, NULL)) {
656 if (state.event == PM_EVENT_THAW) {
Rafael J. Wysocki32bfa562017-12-10 01:02:13 +0100657 skip_resume = true;
Rafael J. Wysocki75e94642017-12-10 01:00:45 +0100658 goto Skip;
659 } else {
660 pm_runtime_set_active(dev);
661 }
662 }
663 }
664
665 if (dev->driver && dev->driver->pm) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100666 info = "noirq driver ";
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100667 callback = pm_noirq_op(dev->driver->pm, state);
668 }
669
Rafael J. Wysocki75e94642017-12-10 01:00:45 +0100670Run:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100671 error = dpm_run_callback(callback, dev, state, info);
Rafael J. Wysocki75e94642017-12-10 01:00:45 +0100672
673Skip:
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +0800674 dev->power.is_noirq_suspended = false;
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100675
Rafael J. Wysocki32bfa562017-12-10 01:02:13 +0100676 if (skip_resume) {
Rafael J. Wysocki0d4b54c2017-11-18 15:31:49 +0100677 /*
678 * The device is going to be left in suspend, but it might not
679 * have been in runtime suspend before the system suspended, so
680 * its runtime PM status needs to be updated to avoid confusing
681 * the runtime PM framework when runtime PM is enabled for the
682 * device again.
683 */
684 pm_runtime_set_suspended(dev);
Rafael J. Wysocki34fb8f02017-12-10 00:56:50 +0100685 dev_pm_skip_next_resume_phases(dev);
Rafael J. Wysocki0d4b54c2017-11-18 15:31:49 +0100686 }
687
Rafael J. Wysocki75e94642017-12-10 01:00:45 +0100688Out:
Liu, Chuansheng76569fa2014-02-18 10:28:45 +0800689 complete_all(&dev->power.completion);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100690 TRACE_RESUME(error);
691 return error;
692}
693
Liu, Chuansheng76569fa2014-02-18 10:28:45 +0800694static bool is_async(struct device *dev)
695{
696 return dev->power.async_suspend && pm_async_enabled
697 && !pm_trace_is_enabled();
698}
699
700static void async_resume_noirq(void *data, async_cookie_t cookie)
701{
702 struct device *dev = (struct device *)data;
703 int error;
704
705 error = device_resume_noirq(dev, pm_transition, true);
706 if (error)
707 pm_dev_err(dev, pm_transition, " async", error);
708
709 put_device(dev);
710}
711
Rafael J. Wysocki786f41f2017-07-21 02:09:22 +0200712void dpm_noirq_resume_devices(pm_message_t state)
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100713{
Liu, Chuansheng76569fa2014-02-18 10:28:45 +0800714 struct device *dev;
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +0100715 ktime_t starttime = ktime_get();
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100716
Todd E Brandtbb3632c2014-06-06 05:40:17 -0700717 trace_suspend_resume(TPS("dpm_resume_noirq"), state.event, true);
Rafael J. Wysocki32bdfac2009-05-24 21:15:07 +0200718 mutex_lock(&dpm_list_mtx);
Liu, Chuansheng76569fa2014-02-18 10:28:45 +0800719 pm_transition = state;
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +0100720
Liu, Chuansheng76569fa2014-02-18 10:28:45 +0800721 /*
722 * Advanced the async threads upfront,
723 * in case the starting of async threads is
724 * delayed by non-async resuming devices.
725 */
726 list_for_each_entry(dev, &dpm_noirq_list, power.entry) {
727 reinit_completion(&dev->power.completion);
728 if (is_async(dev)) {
729 get_device(dev);
730 async_schedule(async_resume_noirq, dev);
731 }
732 }
733
734 while (!list_empty(&dpm_noirq_list)) {
735 dev = to_device(dpm_noirq_list.next);
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +0100736 get_device(dev);
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100737 list_move_tail(&dev->power.entry, &dpm_late_early_list);
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +0100738 mutex_unlock(&dpm_list_mtx);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100739
Liu, Chuansheng76569fa2014-02-18 10:28:45 +0800740 if (!is_async(dev)) {
741 int error;
742
743 error = device_resume_noirq(dev, state, false);
744 if (error) {
745 suspend_stats.failed_resume_noirq++;
746 dpm_save_failed_step(SUSPEND_RESUME_NOIRQ);
747 dpm_save_failed_dev(dev_name(dev));
748 pm_dev_err(dev, state, " noirq", error);
749 }
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100750 }
751
752 mutex_lock(&dpm_list_mtx);
753 put_device(dev);
754 }
755 mutex_unlock(&dpm_list_mtx);
Liu, Chuansheng76569fa2014-02-18 10:28:45 +0800756 async_synchronize_full();
Rafael J. Wysocki48059c092017-07-21 02:10:22 +0200757 dpm_show_time(starttime, state, 0, "noirq");
Rafael J. Wysocki786f41f2017-07-21 02:09:22 +0200758 trace_suspend_resume(TPS("dpm_resume_noirq"), state.event, false);
759}
760
761void dpm_noirq_end(void)
762{
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100763 resume_device_irqs();
Tony Lindgren4990d4f2015-05-18 15:40:29 -0700764 device_wakeup_disarm_wake_irqs();
Preeti U Murthy8651f972012-07-09 10:12:56 +0200765 cpuidle_resume();
Rafael J. Wysocki786f41f2017-07-21 02:09:22 +0200766}
767
768/**
769 * dpm_resume_noirq - Execute "noirq resume" callbacks for all devices.
770 * @state: PM transition of the system being carried out.
771 *
772 * Invoke the "noirq" resume callbacks for all devices in dpm_noirq_list and
773 * allow device drivers' interrupt handlers to be called.
774 */
775void dpm_resume_noirq(pm_message_t state)
776{
777 dpm_noirq_resume_devices(state);
778 dpm_noirq_end();
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100779}
780
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +0100781static pm_callback_t dpm_subsys_resume_early_cb(struct device *dev,
782 pm_message_t state,
783 const char **info_p)
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100784{
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +0100785 pm_callback_t callback;
786 const char *info;
Liu, Chuansheng9e5e7912014-02-18 10:28:46 +0800787
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100788 if (dev->pm_domain) {
789 info = "early power domain ";
790 callback = pm_late_early_op(&dev->pm_domain->ops, state);
791 } else if (dev->type && dev->type->pm) {
792 info = "early type ";
793 callback = pm_late_early_op(dev->type->pm, state);
794 } else if (dev->class && dev->class->pm) {
795 info = "early class ";
796 callback = pm_late_early_op(dev->class->pm, state);
797 } else if (dev->bus && dev->bus->pm) {
798 info = "early bus ";
799 callback = pm_late_early_op(dev->bus->pm, state);
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +0100800 } else {
801 return NULL;
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100802 }
803
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +0100804 if (info_p)
805 *info_p = info;
806
807 return callback;
808}
809
810/**
811 * device_resume_early - Execute an "early resume" callback for given device.
812 * @dev: Device to handle.
813 * @state: PM transition of the system being carried out.
814 * @async: If true, the device is being resumed asynchronously.
815 *
816 * Runtime PM is disabled for @dev while this function is being executed.
817 */
818static int device_resume_early(struct device *dev, pm_message_t state, bool async)
819{
820 pm_callback_t callback;
821 const char *info;
822 int error = 0;
823
824 TRACE_DEVICE(dev);
825 TRACE_RESUME(0);
826
827 if (dev->power.syscore || dev->power.direct_complete)
828 goto Out;
829
830 if (!dev->power.is_late_suspended)
831 goto Out;
832
833 dpm_wait_for_superior(dev, async);
834
835 callback = dpm_subsys_resume_early_cb(dev, state, &info);
836
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100837 if (!callback && dev->driver && dev->driver->pm) {
838 info = "early driver ";
839 callback = pm_late_early_op(dev->driver->pm, state);
840 }
841
842 error = dpm_run_callback(callback, dev, state, info);
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +0800843 dev->power.is_late_suspended = false;
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100844
Rafael J. Wysockidbf37412012-08-06 01:46:39 +0200845 Out:
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100846 TRACE_RESUME(error);
Rafael J. Wysocki9f6d8f62012-12-22 23:59:01 +0100847
848 pm_runtime_enable(dev);
Liu, Chuansheng9e5e7912014-02-18 10:28:46 +0800849 complete_all(&dev->power.completion);
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100850 return error;
851}
852
Liu, Chuansheng9e5e7912014-02-18 10:28:46 +0800853static void async_resume_early(void *data, async_cookie_t cookie)
854{
855 struct device *dev = (struct device *)data;
856 int error;
857
858 error = device_resume_early(dev, pm_transition, true);
859 if (error)
860 pm_dev_err(dev, pm_transition, " async", error);
861
862 put_device(dev);
863}
864
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100865/**
866 * dpm_resume_early - Execute "early resume" callbacks for all devices.
867 * @state: PM transition of the system being carried out.
868 */
Rafael J. Wysocki2a8a8ce2014-09-30 02:21:34 +0200869void dpm_resume_early(pm_message_t state)
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100870{
Liu, Chuansheng9e5e7912014-02-18 10:28:46 +0800871 struct device *dev;
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100872 ktime_t starttime = ktime_get();
873
Todd E Brandtbb3632c2014-06-06 05:40:17 -0700874 trace_suspend_resume(TPS("dpm_resume_early"), state.event, true);
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100875 mutex_lock(&dpm_list_mtx);
Liu, Chuansheng9e5e7912014-02-18 10:28:46 +0800876 pm_transition = state;
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100877
Liu, Chuansheng9e5e7912014-02-18 10:28:46 +0800878 /*
879 * Advanced the async threads upfront,
880 * in case the starting of async threads is
881 * delayed by non-async resuming devices.
882 */
883 list_for_each_entry(dev, &dpm_late_early_list, power.entry) {
884 reinit_completion(&dev->power.completion);
885 if (is_async(dev)) {
886 get_device(dev);
887 async_schedule(async_resume_early, dev);
888 }
889 }
890
891 while (!list_empty(&dpm_late_early_list)) {
892 dev = to_device(dpm_late_early_list.next);
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100893 get_device(dev);
894 list_move_tail(&dev->power.entry, &dpm_suspended_list);
895 mutex_unlock(&dpm_list_mtx);
896
Liu, Chuansheng9e5e7912014-02-18 10:28:46 +0800897 if (!is_async(dev)) {
898 int error;
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +0100899
Liu, Chuansheng9e5e7912014-02-18 10:28:46 +0800900 error = device_resume_early(dev, state, false);
901 if (error) {
902 suspend_stats.failed_resume_early++;
903 dpm_save_failed_step(SUSPEND_RESUME_EARLY);
904 dpm_save_failed_dev(dev_name(dev));
905 pm_dev_err(dev, state, " early", error);
906 }
907 }
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +0100908 mutex_lock(&dpm_list_mtx);
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +0100909 put_device(dev);
910 }
Rafael J. Wysocki32bdfac2009-05-24 21:15:07 +0200911 mutex_unlock(&dpm_list_mtx);
Liu, Chuansheng9e5e7912014-02-18 10:28:46 +0800912 async_synchronize_full();
Rafael J. Wysocki48059c092017-07-21 02:10:22 +0200913 dpm_show_time(starttime, state, 0, "early");
Todd E Brandtbb3632c2014-06-06 05:40:17 -0700914 trace_suspend_resume(TPS("dpm_resume_early"), state.event, false);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100915}
Rafael J. Wysockicf579df2012-01-29 20:38:29 +0100916
917/**
918 * dpm_resume_start - Execute "noirq" and "early" device callbacks.
919 * @state: PM transition of the system being carried out.
920 */
921void dpm_resume_start(pm_message_t state)
922{
923 dpm_resume_noirq(state);
924 dpm_resume_early(state);
925}
926EXPORT_SYMBOL_GPL(dpm_resume_start);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100927
928/**
Rafael J. Wysocki97df8c12010-01-23 22:25:31 +0100929 * device_resume - Execute "resume" callbacks for given device.
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +0200930 * @dev: Device to handle.
931 * @state: PM transition of the system being carried out.
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +0100932 * @async: If true, the device is being resumed asynchronously.
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100933 */
Rafael J. Wysocki97df8c12010-01-23 22:25:31 +0100934static int device_resume(struct device *dev, pm_message_t state, bool async)
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100935{
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100936 pm_callback_t callback = NULL;
Krzysztof Kozlowskie3771fa2017-06-12 17:19:32 +0200937 const char *info = NULL;
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100938 int error = 0;
Benoit Goby70fea602013-10-17 10:48:46 -0700939 DECLARE_DPM_WATCHDOG_ON_STACK(wd);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +0100940
941 TRACE_DEVICE(dev);
942 TRACE_RESUME(0);
Alan Sterncd59abf2007-09-21 15:36:56 -0400943
Rafael J. Wysockidbf37412012-08-06 01:46:39 +0200944 if (dev->power.syscore)
945 goto Complete;
946
Rafael J. Wysockiaae45182014-05-16 02:46:50 +0200947 if (dev->power.direct_complete) {
948 /* Match the pm_runtime_disable() in __device_suspend(). */
949 pm_runtime_enable(dev);
950 goto Complete;
951 }
952
Rafael J. Wysocki8c73b422016-10-30 17:28:49 +0100953 dpm_wait_for_superior(dev, async);
Benoit Goby70fea602013-10-17 10:48:46 -0700954 dpm_watchdog_set(&wd, dev);
Greg Kroah-Hartman8e9394c2010-02-17 10:57:05 -0800955 device_lock(dev);
Rafael J. Wysocki7a8d37a2008-02-25 00:35:04 +0100956
Alan Sternf76b168b2011-06-18 20:22:23 +0200957 /*
958 * This is a fib. But we'll allow new children to be added below
959 * a resumed device, even if the device hasn't been completed yet.
960 */
961 dev->power.is_prepared = false;
Rafael J. Wysocki97df8c12010-01-23 22:25:31 +0100962
Alan Stern6d0e0e82011-06-18 22:42:09 +0200963 if (!dev->power.is_suspended)
964 goto Unlock;
965
Rafael J. Wysocki564b9052011-06-23 01:52:55 +0200966 if (dev->pm_domain) {
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100967 info = "power domain ";
968 callback = pm_op(&dev->pm_domain->ops, state);
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100969 goto Driver;
Rafael J. Wysocki7538e3d2011-02-16 21:53:17 +0100970 }
971
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +0100972 if (dev->type && dev->type->pm) {
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100973 info = "type ";
974 callback = pm_op(dev->type->pm, state);
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100975 goto Driver;
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +0100976 }
977
Rafael J. Wysockia380f2e2017-09-25 14:56:44 +0200978 if (dev->class && dev->class->pm) {
979 info = "class ";
980 callback = pm_op(dev->class->pm, state);
981 goto Driver;
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +0100982 }
983
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200984 if (dev->bus) {
985 if (dev->bus->pm) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100986 info = "bus ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100987 callback = pm_op(dev->bus->pm, state);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200988 } else if (dev->bus->resume) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100989 info = "legacy bus ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +0100990 callback = dev->bus->resume;
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100991 goto End;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +0200992 }
Alan Sterncd59abf2007-09-21 15:36:56 -0400993 }
994
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +0100995 Driver:
996 if (!callback && dev->driver && dev->driver->pm) {
997 info = "driver ";
998 callback = pm_op(dev->driver->pm, state);
999 }
1000
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001001 End:
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +01001002 error = dpm_run_callback(callback, dev, state, info);
Alan Stern6d0e0e82011-06-18 22:42:09 +02001003 dev->power.is_suspended = false;
1004
1005 Unlock:
Greg Kroah-Hartman8e9394c2010-02-17 10:57:05 -08001006 device_unlock(dev);
Benoit Goby70fea602013-10-17 10:48:46 -07001007 dpm_watchdog_clear(&wd);
Rafael J. Wysockidbf37412012-08-06 01:46:39 +02001008
1009 Complete:
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001010 complete_all(&dev->power.completion);
Rafael J. Wysocki7a8d37a2008-02-25 00:35:04 +01001011
Alan Sterncd59abf2007-09-21 15:36:56 -04001012 TRACE_RESUME(error);
Rafael J. Wysocki1e2ef052011-07-06 10:51:58 +02001013
Alan Sterncd59abf2007-09-21 15:36:56 -04001014 return error;
1015}
1016
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001017static void async_resume(void *data, async_cookie_t cookie)
1018{
1019 struct device *dev = (struct device *)data;
1020 int error;
1021
Rafael J. Wysocki97df8c12010-01-23 22:25:31 +01001022 error = device_resume(dev, pm_transition, true);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001023 if (error)
1024 pm_dev_err(dev, pm_transition, " async", error);
1025 put_device(dev);
1026}
1027
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001028/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001029 * dpm_resume - Execute "resume" callbacks for non-sysdev devices.
1030 * @state: PM transition of the system being carried out.
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001031 *
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001032 * Execute the appropriate "resume" callback for all devices whose status
1033 * indicates that they are suspended.
Alan Sterncd59abf2007-09-21 15:36:56 -04001034 */
Rafael J. Wysocki91e7c752011-05-17 23:26:00 +02001035void dpm_resume(pm_message_t state)
Alan Sterncd59abf2007-09-21 15:36:56 -04001036{
Rafael J. Wysocki97df8c12010-01-23 22:25:31 +01001037 struct device *dev;
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +01001038 ktime_t starttime = ktime_get();
Alan Sterncd59abf2007-09-21 15:36:56 -04001039
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001040 trace_suspend_resume(TPS("dpm_resume"), state.event, true);
Rafael J. Wysocki91e7c752011-05-17 23:26:00 +02001041 might_sleep();
1042
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001043 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001044 pm_transition = state;
Rafael J. Wysocki098dff72010-09-22 22:10:57 +02001045 async_error = 0;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001046
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +01001047 list_for_each_entry(dev, &dpm_suspended_list, power.entry) {
Wolfram Sang16735d02013-11-14 14:32:02 -08001048 reinit_completion(&dev->power.completion);
Rafael J. Wysocki97df8c12010-01-23 22:25:31 +01001049 if (is_async(dev)) {
1050 get_device(dev);
1051 async_schedule(async_resume, dev);
1052 }
1053 }
1054
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +01001055 while (!list_empty(&dpm_suspended_list)) {
1056 dev = to_device(dpm_suspended_list.next);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001057 get_device(dev);
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +01001058 if (!is_async(dev)) {
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001059 int error;
1060
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001061 mutex_unlock(&dpm_list_mtx);
1062
Rafael J. Wysocki97df8c12010-01-23 22:25:31 +01001063 error = device_resume(dev, state, false);
ShuoX Liu2a77c462011-08-10 23:01:26 +02001064 if (error) {
1065 suspend_stats.failed_resume++;
1066 dpm_save_failed_step(SUSPEND_RESUME);
1067 dpm_save_failed_dev(dev_name(dev));
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001068 pm_dev_err(dev, state, "", error);
ShuoX Liu2a77c462011-08-10 23:01:26 +02001069 }
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +01001070
1071 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001072 }
1073 if (!list_empty(&dev->power.entry))
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +01001074 list_move_tail(&dev->power.entry, &dpm_prepared_list);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001075 put_device(dev);
Alan Sterncd59abf2007-09-21 15:36:56 -04001076 }
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001077 mutex_unlock(&dpm_list_mtx);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001078 async_synchronize_full();
Rafael J. Wysocki48059c092017-07-21 02:10:22 +02001079 dpm_show_time(starttime, state, 0, NULL);
Viresh Kumar2f0aea92014-03-04 11:00:26 +08001080
1081 cpufreq_resume();
Lukasz Luba6e863842018-12-05 12:05:55 +01001082 devfreq_resume();
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001083 trace_suspend_resume(TPS("dpm_resume"), state.event, false);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001084}
1085
1086/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001087 * device_complete - Complete a PM transition for given device.
1088 * @dev: Device to handle.
1089 * @state: PM transition of the system being carried out.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001090 */
Alan Sternd1616302009-05-24 22:05:42 +02001091static void device_complete(struct device *dev, pm_message_t state)
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001092{
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001093 void (*callback)(struct device *) = NULL;
Krzysztof Kozlowskie3771fa2017-06-12 17:19:32 +02001094 const char *info = NULL;
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001095
Rafael J. Wysockidbf37412012-08-06 01:46:39 +02001096 if (dev->power.syscore)
1097 return;
1098
Greg Kroah-Hartman8e9394c2010-02-17 10:57:05 -08001099 device_lock(dev);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001100
Rafael J. Wysocki564b9052011-06-23 01:52:55 +02001101 if (dev->pm_domain) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001102 info = "completing power domain ";
1103 callback = dev->pm_domain->ops.complete;
Rafael J. Wysocki4d27e9d2011-04-29 00:35:50 +02001104 } else if (dev->type && dev->type->pm) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001105 info = "completing type ";
1106 callback = dev->type->pm->complete;
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +01001107 } else if (dev->class && dev->class->pm) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001108 info = "completing class ";
1109 callback = dev->class->pm->complete;
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +01001110 } else if (dev->bus && dev->bus->pm) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001111 info = "completing bus ";
1112 callback = dev->bus->pm->complete;
1113 }
1114
1115 if (!callback && dev->driver && dev->driver->pm) {
1116 info = "completing driver ";
1117 callback = dev->driver->pm->complete;
1118 }
1119
1120 if (callback) {
1121 pm_dev_dbg(dev, state, info);
1122 callback(dev);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001123 }
1124
Greg Kroah-Hartman8e9394c2010-02-17 10:57:05 -08001125 device_unlock(dev);
Alan Stern88d26132012-09-19 21:59:02 +02001126
Ulf Hanssonaf939332013-04-12 09:41:06 +00001127 pm_runtime_put(dev);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001128}
1129
1130/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001131 * dpm_complete - Complete a PM transition for all non-sysdev devices.
1132 * @state: PM transition of the system being carried out.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001133 *
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001134 * Execute the ->complete() callbacks for all devices whose PM status is not
1135 * DPM_ON (this allows new devices to be registered).
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001136 */
Rafael J. Wysocki91e7c752011-05-17 23:26:00 +02001137void dpm_complete(pm_message_t state)
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001138{
1139 struct list_head list;
1140
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001141 trace_suspend_resume(TPS("dpm_complete"), state.event, true);
Rafael J. Wysocki91e7c752011-05-17 23:26:00 +02001142 might_sleep();
1143
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001144 INIT_LIST_HEAD(&list);
1145 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +01001146 while (!list_empty(&dpm_prepared_list)) {
1147 struct device *dev = to_device(dpm_prepared_list.prev);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001148
1149 get_device(dev);
Alan Sternf76b168b2011-06-18 20:22:23 +02001150 dev->power.is_prepared = false;
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +01001151 list_move(&dev->power.entry, &list);
1152 mutex_unlock(&dpm_list_mtx);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001153
Todd E Brandt32e8d682015-05-28 12:55:53 -07001154 trace_device_pm_callback_start(dev, "", state.event);
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +01001155 device_complete(dev, state);
Todd E Brandt32e8d682015-05-28 12:55:53 -07001156 trace_device_pm_callback_end(dev, 0);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001157
Rafael J. Wysocki5b219a52010-12-16 00:51:08 +01001158 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001159 put_device(dev);
1160 }
1161 list_splice(&list, &dpm_list);
Alan Sterncd59abf2007-09-21 15:36:56 -04001162 mutex_unlock(&dpm_list_mtx);
Strashko, Grygorii013c0742015-11-10 11:42:34 +02001163
1164 /* Allow device probing and trigger re-probing of deferred devices */
1165 device_unblock_probing();
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001166 trace_suspend_resume(TPS("dpm_complete"), state.event, false);
Alan Sterncd59abf2007-09-21 15:36:56 -04001167}
1168
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001169/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001170 * dpm_resume_end - Execute "resume" callbacks and complete system transition.
1171 * @state: PM transition of the system being carried out.
Alan Sterncd59abf2007-09-21 15:36:56 -04001172 *
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001173 * Execute "resume" callbacks for all devices and complete the PM transition of
1174 * the system.
Alan Sterncd59abf2007-09-21 15:36:56 -04001175 */
Alan Sternd1616302009-05-24 22:05:42 +02001176void dpm_resume_end(pm_message_t state)
Alan Sterncd59abf2007-09-21 15:36:56 -04001177{
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001178 dpm_resume(state);
1179 dpm_complete(state);
Alan Sterncd59abf2007-09-21 15:36:56 -04001180}
Alan Sternd1616302009-05-24 22:05:42 +02001181EXPORT_SYMBOL_GPL(dpm_resume_end);
Alan Sterncd59abf2007-09-21 15:36:56 -04001182
1183
Alan Sterncd59abf2007-09-21 15:36:56 -04001184/*------------------------- Suspend routines -------------------------*/
1185
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001186/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001187 * resume_event - Return a "resume" message for given "suspend" sleep state.
1188 * @sleep_state: PM message representing a sleep state.
1189 *
1190 * Return a PM message representing the resume event corresponding to given
1191 * sleep state.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001192 */
1193static pm_message_t resume_event(pm_message_t sleep_state)
Alan Sterncd59abf2007-09-21 15:36:56 -04001194{
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001195 switch (sleep_state.event) {
1196 case PM_EVENT_SUSPEND:
1197 return PMSG_RESUME;
1198 case PM_EVENT_FREEZE:
1199 case PM_EVENT_QUIESCE:
1200 return PMSG_RECOVER;
1201 case PM_EVENT_HIBERNATE:
1202 return PMSG_RESTORE;
Alan Sterncd59abf2007-09-21 15:36:56 -04001203 }
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001204 return PMSG_ON;
Alan Sterncd59abf2007-09-21 15:36:56 -04001205}
1206
Rafael J. Wysocki0d4b54c2017-11-18 15:31:49 +01001207static void dpm_superior_set_must_resume(struct device *dev)
1208{
1209 struct device_link *link;
1210 int idx;
1211
1212 if (dev->parent)
1213 dev->parent->power.must_resume = true;
1214
1215 idx = device_links_read_lock();
1216
1217 list_for_each_entry_rcu(link, &dev->links.suppliers, c_node)
1218 link->supplier->power.must_resume = true;
1219
1220 device_links_read_unlock(idx);
1221}
1222
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +01001223static pm_callback_t dpm_subsys_suspend_noirq_cb(struct device *dev,
1224 pm_message_t state,
1225 const char **info_p)
1226{
1227 pm_callback_t callback;
1228 const char *info;
1229
1230 if (dev->pm_domain) {
1231 info = "noirq power domain ";
1232 callback = pm_noirq_op(&dev->pm_domain->ops, state);
1233 } else if (dev->type && dev->type->pm) {
1234 info = "noirq type ";
1235 callback = pm_noirq_op(dev->type->pm, state);
1236 } else if (dev->class && dev->class->pm) {
1237 info = "noirq class ";
1238 callback = pm_noirq_op(dev->class->pm, state);
1239 } else if (dev->bus && dev->bus->pm) {
1240 info = "noirq bus ";
1241 callback = pm_noirq_op(dev->bus->pm, state);
1242 } else {
1243 return NULL;
1244 }
1245
1246 if (info_p)
1247 *info_p = info;
1248
1249 return callback;
1250}
1251
Rafael J. Wysocki32bfa562017-12-10 01:02:13 +01001252static bool device_must_resume(struct device *dev, pm_message_t state,
1253 bool no_subsys_suspend_noirq)
1254{
1255 pm_message_t resume_msg = resume_event(state);
1256
1257 /*
1258 * If all of the device driver's "noirq", "late" and "early" callbacks
1259 * are invoked directly by the core, the decision to allow the device to
1260 * stay in suspend can be based on its current runtime PM status and its
1261 * wakeup settings.
1262 */
1263 if (no_subsys_suspend_noirq &&
1264 !dpm_subsys_suspend_late_cb(dev, state, NULL) &&
1265 !dpm_subsys_resume_early_cb(dev, resume_msg, NULL) &&
1266 !dpm_subsys_resume_noirq_cb(dev, resume_msg, NULL))
1267 return !pm_runtime_status_suspended(dev) &&
1268 (resume_msg.event != PM_EVENT_RESUME ||
1269 (device_can_wakeup(dev) && !device_may_wakeup(dev)));
1270
1271 /*
1272 * The only safe strategy here is to require that if the device may not
1273 * be left in suspend, resume callbacks must be invoked for it.
1274 */
1275 return !dev->power.may_skip_resume;
1276}
1277
Alan Sterncd59abf2007-09-21 15:36:56 -04001278/**
Rafael J. Wysockib082ddd2017-10-13 15:25:39 +02001279 * __device_suspend_noirq - Execute a "noirq suspend" callback for given device.
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001280 * @dev: Device to handle.
1281 * @state: PM transition of the system being carried out.
Randy Dunlap58c256a2014-07-27 16:17:15 -07001282 * @async: If true, the device is being suspended asynchronously.
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001283 *
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001284 * The driver of @dev will not receive interrupts while this function is being
1285 * executed.
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001286 */
Liu, Chuansheng28b6fd62014-02-18 10:28:47 +08001287static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool async)
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001288{
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +01001289 pm_callback_t callback;
1290 const char *info;
Rafael J. Wysocki32bfa562017-12-10 01:02:13 +01001291 bool no_subsys_cb = false;
Liu, Chuansheng28b6fd62014-02-18 10:28:47 +08001292 int error = 0;
1293
Zhonghui Fu431d4522015-03-18 15:54:27 +01001294 TRACE_DEVICE(dev);
1295 TRACE_SUSPEND(0);
1296
Linus Torvalds098c3052016-12-13 11:42:18 -08001297 dpm_wait_for_subordinate(dev, async);
Brian Norris6f75c3f2016-11-09 17:21:08 -08001298
Liu, Chuansheng28b6fd62014-02-18 10:28:47 +08001299 if (async_error)
1300 goto Complete;
1301
Rafael J. Wysocki9a3ebe32017-07-21 02:12:10 +02001302 if (pm_wakeup_pending()) {
1303 async_error = -EBUSY;
1304 goto Complete;
1305 }
1306
Rafael J. Wysockiaae45182014-05-16 02:46:50 +02001307 if (dev->power.syscore || dev->power.direct_complete)
Liu, Chuansheng28b6fd62014-02-18 10:28:47 +08001308 goto Complete;
1309
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +01001310 callback = dpm_subsys_suspend_noirq_cb(dev, state, &info);
Rafael J. Wysocki75e94642017-12-10 01:00:45 +01001311 if (callback)
1312 goto Run;
Rafael J. Wysocki7538e3d2011-02-16 21:53:17 +01001313
Rafael J. Wysocki32bfa562017-12-10 01:02:13 +01001314 no_subsys_cb = !dpm_subsys_suspend_late_cb(dev, state, NULL);
1315
1316 if (dev_pm_smart_suspend_and_suspended(dev) && no_subsys_cb)
Rafael J. Wysocki75e94642017-12-10 01:00:45 +01001317 goto Skip;
1318
1319 if (dev->driver && dev->driver->pm) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001320 info = "noirq driver ";
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001321 callback = pm_noirq_op(dev->driver->pm, state);
1322 }
1323
Rafael J. Wysocki75e94642017-12-10 01:00:45 +01001324Run:
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +08001325 error = dpm_run_callback(callback, dev, state, info);
Rafael J. Wysocki0d4b54c2017-11-18 15:31:49 +01001326 if (error) {
Liu, Chuansheng28b6fd62014-02-18 10:28:47 +08001327 async_error = error;
Rafael J. Wysocki0d4b54c2017-11-18 15:31:49 +01001328 goto Complete;
1329 }
1330
Rafael J. Wysocki75e94642017-12-10 01:00:45 +01001331Skip:
Rafael J. Wysocki0d4b54c2017-11-18 15:31:49 +01001332 dev->power.is_noirq_suspended = true;
1333
1334 if (dev_pm_test_driver_flags(dev, DPM_FLAG_LEAVE_SUSPENDED)) {
Rafael J. Wysocki0d4b54c2017-11-18 15:31:49 +01001335 dev->power.must_resume = dev->power.must_resume ||
Rafael J. Wysocki32bfa562017-12-10 01:02:13 +01001336 atomic_read(&dev->power.usage_count) > 1 ||
1337 device_must_resume(dev, state, no_subsys_cb);
Rafael J. Wysocki0d4b54c2017-11-18 15:31:49 +01001338 } else {
1339 dev->power.must_resume = true;
1340 }
1341
1342 if (dev->power.must_resume)
1343 dpm_superior_set_must_resume(dev);
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +08001344
Liu, Chuansheng28b6fd62014-02-18 10:28:47 +08001345Complete:
1346 complete_all(&dev->power.completion);
Zhonghui Fu431d4522015-03-18 15:54:27 +01001347 TRACE_SUSPEND(error);
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +08001348 return error;
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001349}
1350
Liu, Chuansheng28b6fd62014-02-18 10:28:47 +08001351static void async_suspend_noirq(void *data, async_cookie_t cookie)
1352{
1353 struct device *dev = (struct device *)data;
1354 int error;
1355
1356 error = __device_suspend_noirq(dev, pm_transition, true);
1357 if (error) {
1358 dpm_save_failed_dev(dev_name(dev));
1359 pm_dev_err(dev, pm_transition, " async", error);
1360 }
1361
1362 put_device(dev);
1363}
1364
1365static int device_suspend_noirq(struct device *dev)
1366{
1367 reinit_completion(&dev->power.completion);
1368
Zhonghui Fu431d4522015-03-18 15:54:27 +01001369 if (is_async(dev)) {
Liu, Chuansheng28b6fd62014-02-18 10:28:47 +08001370 get_device(dev);
1371 async_schedule(async_suspend_noirq, dev);
1372 return 0;
1373 }
1374 return __device_suspend_noirq(dev, pm_transition, false);
1375}
1376
Rafael J. Wysocki786f41f2017-07-21 02:09:22 +02001377void dpm_noirq_begin(void)
1378{
1379 cpuidle_pause();
1380 device_wakeup_arm_wake_irqs();
1381 suspend_device_irqs();
1382}
1383
1384int dpm_noirq_suspend_devices(pm_message_t state)
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001385{
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +01001386 ktime_t starttime = ktime_get();
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001387 int error = 0;
1388
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001389 trace_suspend_resume(TPS("dpm_suspend_noirq"), state.event, true);
Rafael J. Wysocki32bdfac2009-05-24 21:15:07 +02001390 mutex_lock(&dpm_list_mtx);
Liu, Chuansheng28b6fd62014-02-18 10:28:47 +08001391 pm_transition = state;
1392 async_error = 0;
1393
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001394 while (!list_empty(&dpm_late_early_list)) {
1395 struct device *dev = to_device(dpm_late_early_list.prev);
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +01001396
1397 get_device(dev);
1398 mutex_unlock(&dpm_list_mtx);
1399
Liu, Chuansheng28b6fd62014-02-18 10:28:47 +08001400 error = device_suspend_noirq(dev);
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +01001401
1402 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001403 if (error) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001404 pm_dev_err(dev, state, " noirq", error);
ShuoX Liu2a77c462011-08-10 23:01:26 +02001405 dpm_save_failed_dev(dev_name(dev));
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +01001406 put_device(dev);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001407 break;
1408 }
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +01001409 if (!list_empty(&dev->power.entry))
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +01001410 list_move(&dev->power.entry, &dpm_noirq_list);
Rafael J. Wysockid08a5ac2010-11-11 01:50:53 +01001411 put_device(dev);
Rafael J. Wysocki52d136c2012-04-29 22:52:19 +02001412
Liu, Chuansheng28b6fd62014-02-18 10:28:47 +08001413 if (async_error)
Rafael J. Wysocki52d136c2012-04-29 22:52:19 +02001414 break;
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001415 }
Rafael J. Wysocki32bdfac2009-05-24 21:15:07 +02001416 mutex_unlock(&dpm_list_mtx);
Liu, Chuansheng28b6fd62014-02-18 10:28:47 +08001417 async_synchronize_full();
1418 if (!error)
1419 error = async_error;
1420
1421 if (error) {
1422 suspend_stats.failed_suspend_noirq++;
1423 dpm_save_failed_step(SUSPEND_SUSPEND_NOIRQ);
Liu, Chuansheng28b6fd62014-02-18 10:28:47 +08001424 }
Rafael J. Wysocki48059c092017-07-21 02:10:22 +02001425 dpm_show_time(starttime, state, error, "noirq");
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001426 trace_suspend_resume(TPS("dpm_suspend_noirq"), state.event, false);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001427 return error;
1428}
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001429
1430/**
Rafael J. Wysocki786f41f2017-07-21 02:09:22 +02001431 * dpm_suspend_noirq - Execute "noirq suspend" callbacks for all devices.
1432 * @state: PM transition of the system being carried out.
1433 *
1434 * Prevent device drivers' interrupt handlers from being called and invoke
1435 * "noirq" suspend callbacks for all non-sysdev devices.
1436 */
1437int dpm_suspend_noirq(pm_message_t state)
1438{
1439 int ret;
1440
1441 dpm_noirq_begin();
1442 ret = dpm_noirq_suspend_devices(state);
1443 if (ret)
1444 dpm_resume_noirq(resume_event(state));
1445
1446 return ret;
1447}
1448
Ulf Hansson0a99d762018-01-09 10:03:40 +01001449static void dpm_propagate_wakeup_to_parent(struct device *dev)
1450{
1451 struct device *parent = dev->parent;
1452
1453 if (!parent)
1454 return;
1455
1456 spin_lock_irq(&parent->power.lock);
1457
1458 if (dev->power.wakeup_path && !parent->power.ignore_children)
1459 parent->power.wakeup_path = true;
1460
1461 spin_unlock_irq(&parent->power.lock);
1462}
1463
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +01001464static pm_callback_t dpm_subsys_suspend_late_cb(struct device *dev,
1465 pm_message_t state,
1466 const char **info_p)
1467{
1468 pm_callback_t callback;
1469 const char *info;
1470
1471 if (dev->pm_domain) {
1472 info = "late power domain ";
1473 callback = pm_late_early_op(&dev->pm_domain->ops, state);
1474 } else if (dev->type && dev->type->pm) {
1475 info = "late type ";
1476 callback = pm_late_early_op(dev->type->pm, state);
1477 } else if (dev->class && dev->class->pm) {
1478 info = "late class ";
1479 callback = pm_late_early_op(dev->class->pm, state);
1480 } else if (dev->bus && dev->bus->pm) {
1481 info = "late bus ";
1482 callback = pm_late_early_op(dev->bus->pm, state);
1483 } else {
1484 return NULL;
1485 }
1486
1487 if (info_p)
1488 *info_p = info;
1489
1490 return callback;
1491}
1492
Rafael J. Wysocki786f41f2017-07-21 02:09:22 +02001493/**
Rafael J. Wysockib082ddd2017-10-13 15:25:39 +02001494 * __device_suspend_late - Execute a "late suspend" callback for given device.
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001495 * @dev: Device to handle.
1496 * @state: PM transition of the system being carried out.
Randy Dunlap58c256a2014-07-27 16:17:15 -07001497 * @async: If true, the device is being suspended asynchronously.
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001498 *
1499 * Runtime PM is disabled for @dev while this function is being executed.
1500 */
Liu, Chuanshengde377b32014-02-18 10:28:48 +08001501static int __device_suspend_late(struct device *dev, pm_message_t state, bool async)
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001502{
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +01001503 pm_callback_t callback;
1504 const char *info;
Liu, Chuanshengde377b32014-02-18 10:28:48 +08001505 int error = 0;
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001506
Zhonghui Fu431d4522015-03-18 15:54:27 +01001507 TRACE_DEVICE(dev);
1508 TRACE_SUSPEND(0);
1509
Rafael J. Wysocki9f6d8f62012-12-22 23:59:01 +01001510 __pm_runtime_disable(dev, false);
1511
Linus Torvalds098c3052016-12-13 11:42:18 -08001512 dpm_wait_for_subordinate(dev, async);
Brian Norris6f75c3f2016-11-09 17:21:08 -08001513
Liu, Chuanshengde377b32014-02-18 10:28:48 +08001514 if (async_error)
1515 goto Complete;
1516
1517 if (pm_wakeup_pending()) {
1518 async_error = -EBUSY;
1519 goto Complete;
1520 }
1521
Rafael J. Wysockiaae45182014-05-16 02:46:50 +02001522 if (dev->power.syscore || dev->power.direct_complete)
Liu, Chuanshengde377b32014-02-18 10:28:48 +08001523 goto Complete;
1524
Rafael J. Wysocki4fa30612017-12-10 00:58:18 +01001525 callback = dpm_subsys_suspend_late_cb(dev, state, &info);
Rafael J. Wysocki75e94642017-12-10 01:00:45 +01001526 if (callback)
1527 goto Run;
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001528
Rafael J. Wysocki75e94642017-12-10 01:00:45 +01001529 if (dev_pm_smart_suspend_and_suspended(dev) &&
1530 !dpm_subsys_suspend_noirq_cb(dev, state, NULL))
1531 goto Skip;
1532
1533 if (dev->driver && dev->driver->pm) {
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001534 info = "late driver ";
1535 callback = pm_late_early_op(dev->driver->pm, state);
1536 }
1537
Rafael J. Wysocki75e94642017-12-10 01:00:45 +01001538Run:
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +08001539 error = dpm_run_callback(callback, dev, state, info);
Rafael J. Wysocki75e94642017-12-10 01:00:45 +01001540 if (error) {
Liu, Chuanshengde377b32014-02-18 10:28:48 +08001541 async_error = error;
Rafael J. Wysocki75e94642017-12-10 01:00:45 +01001542 goto Complete;
1543 }
Ulf Hansson0a99d762018-01-09 10:03:40 +01001544 dpm_propagate_wakeup_to_parent(dev);
Rafael J. Wysocki75e94642017-12-10 01:00:45 +01001545
1546Skip:
1547 dev->power.is_late_suspended = true;
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +08001548
Liu, Chuanshengde377b32014-02-18 10:28:48 +08001549Complete:
Zhonghui Fu431d4522015-03-18 15:54:27 +01001550 TRACE_SUSPEND(error);
Liu, Chuanshengde377b32014-02-18 10:28:48 +08001551 complete_all(&dev->power.completion);
Liu, Chuansheng3d2699b2014-02-18 10:28:44 +08001552 return error;
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001553}
1554
Liu, Chuanshengde377b32014-02-18 10:28:48 +08001555static void async_suspend_late(void *data, async_cookie_t cookie)
1556{
1557 struct device *dev = (struct device *)data;
1558 int error;
1559
1560 error = __device_suspend_late(dev, pm_transition, true);
1561 if (error) {
1562 dpm_save_failed_dev(dev_name(dev));
1563 pm_dev_err(dev, pm_transition, " async", error);
1564 }
1565 put_device(dev);
1566}
1567
1568static int device_suspend_late(struct device *dev)
1569{
1570 reinit_completion(&dev->power.completion);
1571
Zhonghui Fu431d4522015-03-18 15:54:27 +01001572 if (is_async(dev)) {
Liu, Chuanshengde377b32014-02-18 10:28:48 +08001573 get_device(dev);
1574 async_schedule(async_suspend_late, dev);
1575 return 0;
1576 }
1577
1578 return __device_suspend_late(dev, pm_transition, false);
1579}
1580
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001581/**
1582 * dpm_suspend_late - Execute "late suspend" callbacks for all devices.
1583 * @state: PM transition of the system being carried out.
1584 */
Rafael J. Wysocki2a8a8ce2014-09-30 02:21:34 +02001585int dpm_suspend_late(pm_message_t state)
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001586{
1587 ktime_t starttime = ktime_get();
1588 int error = 0;
1589
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001590 trace_suspend_resume(TPS("dpm_suspend_late"), state.event, true);
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001591 mutex_lock(&dpm_list_mtx);
Liu, Chuanshengde377b32014-02-18 10:28:48 +08001592 pm_transition = state;
1593 async_error = 0;
1594
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001595 while (!list_empty(&dpm_suspended_list)) {
1596 struct device *dev = to_device(dpm_suspended_list.prev);
1597
1598 get_device(dev);
1599 mutex_unlock(&dpm_list_mtx);
1600
Liu, Chuanshengde377b32014-02-18 10:28:48 +08001601 error = device_suspend_late(dev);
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001602
1603 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki3a17fb32016-05-20 23:09:49 +02001604 if (!list_empty(&dev->power.entry))
1605 list_move(&dev->power.entry, &dpm_late_early_list);
1606
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001607 if (error) {
1608 pm_dev_err(dev, state, " late", error);
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001609 dpm_save_failed_dev(dev_name(dev));
1610 put_device(dev);
1611 break;
1612 }
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001613 put_device(dev);
Rafael J. Wysocki52d136c2012-04-29 22:52:19 +02001614
Liu, Chuanshengde377b32014-02-18 10:28:48 +08001615 if (async_error)
Rafael J. Wysocki52d136c2012-04-29 22:52:19 +02001616 break;
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001617 }
1618 mutex_unlock(&dpm_list_mtx);
Liu, Chuanshengde377b32014-02-18 10:28:48 +08001619 async_synchronize_full();
Imre Deak246ef762014-10-24 20:29:09 +03001620 if (!error)
1621 error = async_error;
Liu, Chuanshengde377b32014-02-18 10:28:48 +08001622 if (error) {
1623 suspend_stats.failed_suspend_late++;
1624 dpm_save_failed_step(SUSPEND_SUSPEND_LATE);
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001625 dpm_resume_early(resume_event(state));
Liu, Chuanshengde377b32014-02-18 10:28:48 +08001626 }
Rafael J. Wysocki48059c092017-07-21 02:10:22 +02001627 dpm_show_time(starttime, state, error, "late");
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001628 trace_suspend_resume(TPS("dpm_suspend_late"), state.event, false);
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001629 return error;
1630}
1631
1632/**
1633 * dpm_suspend_end - Execute "late" and "noirq" device suspend callbacks.
1634 * @state: PM transition of the system being carried out.
1635 */
1636int dpm_suspend_end(pm_message_t state)
1637{
1638 int error = dpm_suspend_late(state);
Colin Cross064b0212012-07-19 10:38:06 +02001639 if (error)
1640 return error;
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001641
Colin Cross064b0212012-07-19 10:38:06 +02001642 error = dpm_suspend_noirq(state);
1643 if (error) {
Feng Hong997a0312012-09-19 14:16:00 +02001644 dpm_resume_early(resume_event(state));
Colin Cross064b0212012-07-19 10:38:06 +02001645 return error;
1646 }
1647
1648 return 0;
Rafael J. Wysockicf579df2012-01-29 20:38:29 +01001649}
1650EXPORT_SYMBOL_GPL(dpm_suspend_end);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001651
1652/**
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +01001653 * legacy_suspend - Execute a legacy (bus or class) suspend callback for device.
Randy Dunlap0a884222010-01-08 14:42:57 -08001654 * @dev: Device to suspend.
1655 * @state: PM transition of the system being carried out.
1656 * @cb: Suspend callback to execute.
Randy Dunlap58c256a2014-07-27 16:17:15 -07001657 * @info: string description of caller.
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +01001658 */
1659static int legacy_suspend(struct device *dev, pm_message_t state,
Shuah Khan53644672013-07-26 13:30:20 -06001660 int (*cb)(struct device *dev, pm_message_t state),
Krzysztof Kozlowskie3771fa2017-06-12 17:19:32 +02001661 const char *info)
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +01001662{
1663 int error;
1664 ktime_t calltime;
1665
Bjorn Helgaas7f817ba2018-04-26 16:36:41 -05001666 calltime = initcall_debug_start(dev, cb);
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +01001667
Todd E Brandte8bca472014-06-10 07:31:22 -07001668 trace_device_pm_callback_start(dev, info, state.event);
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +01001669 error = cb(dev, state);
Todd E Brandte8bca472014-06-10 07:31:22 -07001670 trace_device_pm_callback_end(dev, error);
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +01001671 suspend_report_result(cb, error);
1672
Bjorn Helgaas7f817ba2018-04-26 16:36:41 -05001673 initcall_debug_report(dev, calltime, cb, error);
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +01001674
1675 return error;
1676}
1677
Ulf Hanssonc23bd382018-01-09 10:03:39 +01001678static void dpm_clear_superiors_direct_complete(struct device *dev)
Rafael J. Wysocki8c73b422016-10-30 17:28:49 +01001679{
1680 struct device_link *link;
1681 int idx;
1682
Ulf Hanssonc23bd382018-01-09 10:03:39 +01001683 if (dev->parent) {
1684 spin_lock_irq(&dev->parent->power.lock);
1685 dev->parent->power.direct_complete = false;
1686 spin_unlock_irq(&dev->parent->power.lock);
1687 }
1688
Rafael J. Wysocki8c73b422016-10-30 17:28:49 +01001689 idx = device_links_read_lock();
1690
1691 list_for_each_entry_rcu(link, &dev->links.suppliers, c_node) {
1692 spin_lock_irq(&link->supplier->power.lock);
1693 link->supplier->power.direct_complete = false;
1694 spin_unlock_irq(&link->supplier->power.lock);
1695 }
1696
1697 device_links_read_unlock(idx);
1698}
1699
Rafael J. Wysocki875ab0b2009-12-18 01:57:31 +01001700/**
Rafael J. Wysockib082ddd2017-10-13 15:25:39 +02001701 * __device_suspend - Execute "suspend" callbacks for given device.
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001702 * @dev: Device to handle.
1703 * @state: PM transition of the system being carried out.
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001704 * @async: If true, the device is being suspended asynchronously.
Alan Sterncd59abf2007-09-21 15:36:56 -04001705 */
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001706static int __device_suspend(struct device *dev, pm_message_t state, bool async)
Alan Sterncd59abf2007-09-21 15:36:56 -04001707{
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +01001708 pm_callback_t callback = NULL;
Krzysztof Kozlowskie3771fa2017-06-12 17:19:32 +02001709 const char *info = NULL;
Alan Sterncd59abf2007-09-21 15:36:56 -04001710 int error = 0;
Benoit Goby70fea602013-10-17 10:48:46 -07001711 DECLARE_DPM_WATCHDOG_ON_STACK(wd);
Alan Sterncd59abf2007-09-21 15:36:56 -04001712
Zhonghui Fu431d4522015-03-18 15:54:27 +01001713 TRACE_DEVICE(dev);
1714 TRACE_SUSPEND(0);
1715
Rafael J. Wysocki8c73b422016-10-30 17:28:49 +01001716 dpm_wait_for_subordinate(dev, async);
Rafael J. Wysocki7a8d37a2008-02-25 00:35:04 +01001717
Rafael J. Wysocki69e445a2018-10-04 11:08:12 +02001718 if (async_error) {
1719 dev->power.direct_complete = false;
Mandeep Singh Baines1f758b22012-06-24 23:31:09 +02001720 goto Complete;
Rafael J. Wysocki69e445a2018-10-04 11:08:12 +02001721 }
Rafael J. Wysocki1e2ef052011-07-06 10:51:58 +02001722
Alan Stern88d26132012-09-19 21:59:02 +02001723 /*
1724 * If a device configured to wake up the system from sleep states
1725 * has been suspended at run time and there's a resume request pending
1726 * for it, this is equivalent to the device signaling wakeup, so the
1727 * system suspend operation should be aborted.
1728 */
Rafael J. Wysocki1e2ef052011-07-06 10:51:58 +02001729 if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
1730 pm_wakeup_event(dev, 0);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001731
Rafael J. Wysockid83f9052010-12-03 23:14:26 +01001732 if (pm_wakeup_pending()) {
Rafael J. Wysocki69e445a2018-10-04 11:08:12 +02001733 dev->power.direct_complete = false;
Rafael J. Wysockid83f9052010-12-03 23:14:26 +01001734 async_error = -EBUSY;
Mandeep Singh Baines1f758b22012-06-24 23:31:09 +02001735 goto Complete;
Rafael J. Wysockid83f9052010-12-03 23:14:26 +01001736 }
1737
Rafael J. Wysockidbf37412012-08-06 01:46:39 +02001738 if (dev->power.syscore)
1739 goto Complete;
1740
Rafael J. Wysockiaae45182014-05-16 02:46:50 +02001741 if (dev->power.direct_complete) {
1742 if (pm_runtime_status_suspended(dev)) {
1743 pm_runtime_disable(dev);
Alan Stern019d8812015-07-15 14:40:06 +02001744 if (pm_runtime_status_suspended(dev))
Rafael J. Wysockiaae45182014-05-16 02:46:50 +02001745 goto Complete;
1746
1747 pm_runtime_enable(dev);
1748 }
1749 dev->power.direct_complete = false;
1750 }
1751
Rafael J. Wysocki0d4b54c2017-11-18 15:31:49 +01001752 dev->power.may_skip_resume = false;
1753 dev->power.must_resume = false;
1754
Benoit Goby70fea602013-10-17 10:48:46 -07001755 dpm_watchdog_set(&wd, dev);
Rafael J. Wysocki1e2ef052011-07-06 10:51:58 +02001756 device_lock(dev);
1757
Rafael J. Wysocki564b9052011-06-23 01:52:55 +02001758 if (dev->pm_domain) {
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +01001759 info = "power domain ";
1760 callback = pm_op(&dev->pm_domain->ops, state);
1761 goto Run;
Rafael J. Wysocki4d27e9d2011-04-29 00:35:50 +02001762 }
1763
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +01001764 if (dev->type && dev->type->pm) {
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +01001765 info = "type ";
1766 callback = pm_op(dev->type->pm, state);
1767 goto Run;
Rafael J. Wysocki9659cc02011-02-18 23:20:21 +01001768 }
1769
Rafael J. Wysockia380f2e2017-09-25 14:56:44 +02001770 if (dev->class && dev->class->pm) {
1771 info = "class ";
1772 callback = pm_op(dev->class->pm, state);
1773 goto Run;
Alan Sterncd59abf2007-09-21 15:36:56 -04001774 }
1775
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001776 if (dev->bus) {
1777 if (dev->bus->pm) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001778 info = "bus ";
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +01001779 callback = pm_op(dev->bus->pm, state);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001780 } else if (dev->bus->suspend) {
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001781 pm_dev_dbg(dev, state, "legacy bus ");
Shuah Khan53644672013-07-26 13:30:20 -06001782 error = legacy_suspend(dev, state, dev->bus->suspend,
1783 "legacy bus ");
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +01001784 goto End;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001785 }
Rafael J. Wysocki7538e3d2011-02-16 21:53:17 +01001786 }
1787
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +01001788 Run:
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001789 if (!callback && dev->driver && dev->driver->pm) {
1790 info = "driver ";
1791 callback = pm_op(dev->driver->pm, state);
1792 }
1793
Rafael J. Wysocki9cf519d2011-12-18 00:34:01 +01001794 error = dpm_run_callback(callback, dev, state, info);
1795
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001796 End:
Rafael J. Wysocki4ca46ff2011-10-16 23:34:36 +02001797 if (!error) {
1798 dev->power.is_suspended = true;
Ulf Hansson8512220c2018-01-02 17:08:50 +01001799 if (device_may_wakeup(dev))
1800 dev->power.wakeup_path = true;
1801
Ulf Hanssonc23bd382018-01-09 10:03:39 +01001802 dpm_propagate_wakeup_to_parent(dev);
1803 dpm_clear_superiors_direct_complete(dev);
Rafael J. Wysocki4ca46ff2011-10-16 23:34:36 +02001804 }
Alan Stern6d0e0e82011-06-18 22:42:09 +02001805
Greg Kroah-Hartman8e9394c2010-02-17 10:57:05 -08001806 device_unlock(dev);
Benoit Goby70fea602013-10-17 10:48:46 -07001807 dpm_watchdog_clear(&wd);
Mandeep Singh Baines1f758b22012-06-24 23:31:09 +02001808
1809 Complete:
Alan Stern88d26132012-09-19 21:59:02 +02001810 if (error)
Rafael J. Wysocki098dff72010-09-22 22:10:57 +02001811 async_error = error;
1812
Sahitya Tummala05a92622016-12-07 20:10:32 +05301813 complete_all(&dev->power.completion);
Zhonghui Fu431d4522015-03-18 15:54:27 +01001814 TRACE_SUSPEND(error);
Alan Sterncd59abf2007-09-21 15:36:56 -04001815 return error;
1816}
1817
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001818static void async_suspend(void *data, async_cookie_t cookie)
1819{
1820 struct device *dev = (struct device *)data;
1821 int error;
1822
1823 error = __device_suspend(dev, pm_transition, true);
ShuoX Liu2a77c462011-08-10 23:01:26 +02001824 if (error) {
1825 dpm_save_failed_dev(dev_name(dev));
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001826 pm_dev_err(dev, pm_transition, " async", error);
ShuoX Liu2a77c462011-08-10 23:01:26 +02001827 }
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001828
1829 put_device(dev);
1830}
1831
1832static int device_suspend(struct device *dev)
1833{
Wolfram Sang16735d02013-11-14 14:32:02 -08001834 reinit_completion(&dev->power.completion);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001835
Zhonghui Fu431d4522015-03-18 15:54:27 +01001836 if (is_async(dev)) {
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001837 get_device(dev);
1838 async_schedule(async_suspend, dev);
1839 return 0;
1840 }
1841
1842 return __device_suspend(dev, pm_transition, false);
1843}
1844
Alan Sterncd59abf2007-09-21 15:36:56 -04001845/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001846 * dpm_suspend - Execute "suspend" callbacks for all non-sysdev devices.
1847 * @state: PM transition of the system being carried out.
Alan Sterncd59abf2007-09-21 15:36:56 -04001848 */
Rafael J. Wysocki91e7c752011-05-17 23:26:00 +02001849int dpm_suspend(pm_message_t state)
Alan Sterncd59abf2007-09-21 15:36:56 -04001850{
Rafael J. Wysockiecf762b2009-12-18 01:57:47 +01001851 ktime_t starttime = ktime_get();
Alan Sterncd59abf2007-09-21 15:36:56 -04001852 int error = 0;
1853
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001854 trace_suspend_resume(TPS("dpm_suspend"), state.event, true);
Rafael J. Wysocki91e7c752011-05-17 23:26:00 +02001855 might_sleep();
1856
Lukasz Luba6e863842018-12-05 12:05:55 +01001857 devfreq_suspend();
Viresh Kumar2f0aea92014-03-04 11:00:26 +08001858 cpufreq_suspend();
1859
Alan Sterncd59abf2007-09-21 15:36:56 -04001860 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001861 pm_transition = state;
1862 async_error = 0;
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +01001863 while (!list_empty(&dpm_prepared_list)) {
1864 struct device *dev = to_device(dpm_prepared_list.prev);
Alan Sterncd59abf2007-09-21 15:36:56 -04001865
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001866 get_device(dev);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001867 mutex_unlock(&dpm_list_mtx);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001868
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001869 error = device_suspend(dev);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001870
Alan Stern1b3cbec2008-02-29 11:50:22 -05001871 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001872 if (error) {
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001873 pm_dev_err(dev, state, "", error);
ShuoX Liu2a77c462011-08-10 23:01:26 +02001874 dpm_save_failed_dev(dev_name(dev));
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001875 put_device(dev);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001876 break;
1877 }
Rafael J. Wysocki7a8d37a2008-02-25 00:35:04 +01001878 if (!list_empty(&dev->power.entry))
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +01001879 list_move(&dev->power.entry, &dpm_suspended_list);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001880 put_device(dev);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001881 if (async_error)
1882 break;
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001883 }
1884 mutex_unlock(&dpm_list_mtx);
Rafael J. Wysocki5af84b82010-01-23 22:23:32 +01001885 async_synchronize_full();
1886 if (!error)
1887 error = async_error;
ShuoX Liu2a77c462011-08-10 23:01:26 +02001888 if (error) {
1889 suspend_stats.failed_suspend++;
1890 dpm_save_failed_step(SUSPEND_SUSPEND);
Rafael J. Wysocki48059c092017-07-21 02:10:22 +02001891 }
1892 dpm_show_time(starttime, state, error, NULL);
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001893 trace_suspend_resume(TPS("dpm_suspend"), state.event, false);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001894 return error;
1895}
1896
1897/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001898 * device_prepare - Prepare a device for system power transition.
1899 * @dev: Device to handle.
1900 * @state: PM transition of the system being carried out.
1901 *
1902 * Execute the ->prepare() callback(s) for given device. No new children of the
1903 * device may be registered after this function has returned.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001904 */
Alan Sternd1616302009-05-24 22:05:42 +02001905static int device_prepare(struct device *dev, pm_message_t state)
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001906{
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001907 int (*callback)(struct device *) = NULL;
Rafael J. Wysockiaae45182014-05-16 02:46:50 +02001908 int ret = 0;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001909
Rafael J. Wysockidbf37412012-08-06 01:46:39 +02001910 if (dev->power.syscore)
1911 return 0;
1912
Rafael J. Wysocki0d4b54c2017-11-18 15:31:49 +01001913 WARN_ON(!pm_runtime_enabled(dev) &&
1914 dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND |
1915 DPM_FLAG_LEAVE_SUSPENDED));
Rafael J. Wysocki0eab11c92017-10-26 12:12:08 +02001916
Alan Stern88d26132012-09-19 21:59:02 +02001917 /*
1918 * If a device's parent goes into runtime suspend at the wrong time,
1919 * it won't be possible to resume the device. To prevent this we
1920 * block runtime suspend here, during the prepare phase, and allow
1921 * it again during the complete phase.
1922 */
1923 pm_runtime_get_noresume(dev);
1924
Greg Kroah-Hartman8e9394c2010-02-17 10:57:05 -08001925 device_lock(dev);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001926
Ulf Hansson8512220c2018-01-02 17:08:50 +01001927 dev->power.wakeup_path = false;
Rafael J. Wysocki4ca46ff2011-10-16 23:34:36 +02001928
Rafael J. Wysockic62ec462018-05-22 13:02:17 +02001929 if (dev->power.no_pm_callbacks)
Tomeu Vizosoaa8e54b52016-01-07 16:46:14 +01001930 goto unlock;
Tomeu Vizosoaa8e54b52016-01-07 16:46:14 +01001931
Thierry Redingfba1fbf2016-04-28 14:42:34 +02001932 if (dev->pm_domain)
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001933 callback = dev->pm_domain->ops.prepare;
Thierry Redingfba1fbf2016-04-28 14:42:34 +02001934 else if (dev->type && dev->type->pm)
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001935 callback = dev->type->pm->prepare;
Thierry Redingfba1fbf2016-04-28 14:42:34 +02001936 else if (dev->class && dev->class->pm)
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001937 callback = dev->class->pm->prepare;
Thierry Redingfba1fbf2016-04-28 14:42:34 +02001938 else if (dev->bus && dev->bus->pm)
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001939 callback = dev->bus->pm->prepare;
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001940
Thierry Redingfba1fbf2016-04-28 14:42:34 +02001941 if (!callback && dev->driver && dev->driver->pm)
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001942 callback = dev->driver->pm->prepare;
Rafael J. Wysocki35cd1332011-12-18 00:34:13 +01001943
Todd E Brandt32e8d682015-05-28 12:55:53 -07001944 if (callback)
Rafael J. Wysockiaae45182014-05-16 02:46:50 +02001945 ret = callback(dev);
Rafael J. Wysocki7538e3d2011-02-16 21:53:17 +01001946
Tomeu Vizosoaa8e54b52016-01-07 16:46:14 +01001947unlock:
Greg Kroah-Hartman8e9394c2010-02-17 10:57:05 -08001948 device_unlock(dev);
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001949
Rafael J. Wysockiaae45182014-05-16 02:46:50 +02001950 if (ret < 0) {
1951 suspend_report_result(callback, ret);
Ulf Hanssonaa1b9f12013-11-13 15:45:03 +01001952 pm_runtime_put(dev);
Rafael J. Wysockiaae45182014-05-16 02:46:50 +02001953 return ret;
1954 }
1955 /*
1956 * A positive return value from ->prepare() means "this device appears
1957 * to be runtime-suspended and its state is fine, so if it really is
1958 * runtime-suspended, you can leave it in that state provided that you
1959 * will do the same thing with all of its descendants". This only
1960 * applies to suspend transitions, however.
1961 */
1962 spin_lock_irq(&dev->power.lock);
Rafael J. Wysocki08810a412017-10-25 14:12:29 +02001963 dev->power.direct_complete = state.event == PM_EVENT_SUSPEND &&
Rafael J. Wysockic62ec462018-05-22 13:02:17 +02001964 ((pm_runtime_suspended(dev) && ret > 0) ||
1965 dev->power.no_pm_callbacks) &&
Rafael J. Wysocki08810a412017-10-25 14:12:29 +02001966 !dev_pm_test_driver_flags(dev, DPM_FLAG_NEVER_SKIP);
Rafael J. Wysockiaae45182014-05-16 02:46:50 +02001967 spin_unlock_irq(&dev->power.lock);
1968 return 0;
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01001969}
1970
1971/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001972 * dpm_prepare - Prepare all non-sysdev devices for a system PM transition.
1973 * @state: PM transition of the system being carried out.
Alan Sterncd59abf2007-09-21 15:36:56 -04001974 *
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02001975 * Execute the ->prepare() callback(s) for all devices.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001976 */
Rafael J. Wysocki91e7c752011-05-17 23:26:00 +02001977int dpm_prepare(pm_message_t state)
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001978{
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001979 int error = 0;
1980
Todd E Brandtbb3632c2014-06-06 05:40:17 -07001981 trace_suspend_resume(TPS("dpm_prepare"), state.event, true);
Rafael J. Wysocki91e7c752011-05-17 23:26:00 +02001982 might_sleep();
1983
Strashko, Grygorii013c0742015-11-10 11:42:34 +02001984 /*
1985 * Give a chance for the known devices to complete their probes, before
1986 * disable probing of devices. This sync point is important at least
1987 * at boot time + hibernation restore.
1988 */
1989 wait_for_device_probe();
1990 /*
1991 * It is unsafe if probing of devices will happen during suspend or
1992 * hibernation and system behavior will be unpredictable in this case.
1993 * So, let's prohibit device's probing here and defer their probes
1994 * instead. The normal behavior will be restored in dpm_complete().
1995 */
1996 device_block_probing();
1997
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001998 mutex_lock(&dpm_list_mtx);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02001999 while (!list_empty(&dpm_list)) {
2000 struct device *dev = to_device(dpm_list.next);
2001
2002 get_device(dev);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02002003 mutex_unlock(&dpm_list_mtx);
2004
Todd E Brandt32e8d682015-05-28 12:55:53 -07002005 trace_device_pm_callback_start(dev, "", state.event);
Rafael J. Wysocki1e2ef052011-07-06 10:51:58 +02002006 error = device_prepare(dev, state);
Todd E Brandt32e8d682015-05-28 12:55:53 -07002007 trace_device_pm_callback_end(dev, error);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02002008
2009 mutex_lock(&dpm_list_mtx);
2010 if (error) {
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02002011 if (error == -EAGAIN) {
2012 put_device(dev);
Sebastian Ott886a7a32009-07-08 13:26:05 +02002013 error = 0;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02002014 continue;
2015 }
Rafael J. Wysocki1e75227e2010-12-03 22:58:05 +01002016 printk(KERN_INFO "PM: Device %s not prepared "
2017 "for power transition: code %d\n",
Rafael J. Wysocki5c1a07a2010-12-24 15:03:34 +01002018 dev_name(dev), error);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02002019 put_device(dev);
2020 break;
2021 }
Alan Sternf76b168b2011-06-18 20:22:23 +02002022 dev->power.is_prepared = true;
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02002023 if (!list_empty(&dev->power.entry))
Rafael J. Wysocki8a43a9a2010-12-16 00:50:30 +01002024 list_move_tail(&dev->power.entry, &dpm_prepared_list);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02002025 put_device(dev);
2026 }
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02002027 mutex_unlock(&dpm_list_mtx);
Todd E Brandtbb3632c2014-06-06 05:40:17 -07002028 trace_suspend_resume(TPS("dpm_prepare"), state.event, false);
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02002029 return error;
2030}
2031
2032/**
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02002033 * dpm_suspend_start - Prepare devices for PM transition and suspend them.
2034 * @state: PM transition of the system being carried out.
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02002035 *
Rafael J. Wysocki20d652d2009-08-20 20:25:52 +02002036 * Prepare all non-sysdev devices for system PM transition and execute "suspend"
2037 * callbacks for them.
Alan Sterncd59abf2007-09-21 15:36:56 -04002038 */
Alan Sternd1616302009-05-24 22:05:42 +02002039int dpm_suspend_start(pm_message_t state)
Alan Sterncd59abf2007-09-21 15:36:56 -04002040{
Rafael J. Wysocki775b64d2008-01-12 20:40:46 +01002041 int error;
Alan Sterncd59abf2007-09-21 15:36:56 -04002042
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02002043 error = dpm_prepare(state);
ShuoX Liu2a77c462011-08-10 23:01:26 +02002044 if (error) {
2045 suspend_stats.failed_prepare++;
2046 dpm_save_failed_step(SUSPEND_PREPARE);
2047 } else
Rafael J. Wysocki1eede072008-05-20 23:00:01 +02002048 error = dpm_suspend(state);
Alan Sterncd59abf2007-09-21 15:36:56 -04002049 return error;
Alan Sterncd59abf2007-09-21 15:36:56 -04002050}
Alan Sternd1616302009-05-24 22:05:42 +02002051EXPORT_SYMBOL_GPL(dpm_suspend_start);
Alan Sterncd59abf2007-09-21 15:36:56 -04002052
2053void __suspend_report_result(const char *function, void *fn, int ret)
2054{
Bjorn Helgaasc80cfb02008-10-15 22:01:35 -07002055 if (ret)
2056 printk(KERN_ERR "%s(): %pF returns %d\n", function, fn, ret);
Alan Sterncd59abf2007-09-21 15:36:56 -04002057}
2058EXPORT_SYMBOL_GPL(__suspend_report_result);
Rafael J. Wysockif8824ce2010-01-27 23:47:38 +01002059
2060/**
2061 * device_pm_wait_for_dev - Wait for suspend/resume of a device to complete.
2062 * @dev: Device to wait for.
2063 * @subordinate: Device that needs to wait for @dev.
2064 */
Rafael J. Wysocki098dff72010-09-22 22:10:57 +02002065int device_pm_wait_for_dev(struct device *subordinate, struct device *dev)
Rafael J. Wysockif8824ce2010-01-27 23:47:38 +01002066{
2067 dpm_wait(dev, subordinate->power.async_suspend);
Rafael J. Wysocki098dff72010-09-22 22:10:57 +02002068 return async_error;
Rafael J. Wysockif8824ce2010-01-27 23:47:38 +01002069}
2070EXPORT_SYMBOL_GPL(device_pm_wait_for_dev);
Ming Leidfe32122012-08-17 22:06:59 +08002071
2072/**
2073 * dpm_for_each_dev - device iterator.
2074 * @data: data for the callback.
2075 * @fn: function to be called for each device.
2076 *
2077 * Iterate over devices in dpm_list, and call @fn for each device,
2078 * passing it @data.
2079 */
2080void dpm_for_each_dev(void *data, void (*fn)(struct device *, void *))
2081{
2082 struct device *dev;
2083
2084 if (!fn)
2085 return;
2086
2087 device_pm_lock();
2088 list_for_each_entry(dev, &dpm_list, power.entry)
2089 fn(dev, data);
2090 device_pm_unlock();
2091}
2092EXPORT_SYMBOL_GPL(dpm_for_each_dev);
Tomeu Vizosoaa8e54b52016-01-07 16:46:14 +01002093
2094static bool pm_ops_is_empty(const struct dev_pm_ops *ops)
2095{
2096 if (!ops)
2097 return true;
2098
2099 return !ops->prepare &&
2100 !ops->suspend &&
2101 !ops->suspend_late &&
2102 !ops->suspend_noirq &&
2103 !ops->resume_noirq &&
2104 !ops->resume_early &&
2105 !ops->resume &&
2106 !ops->complete;
2107}
2108
2109void device_pm_check_callbacks(struct device *dev)
2110{
2111 spin_lock_irq(&dev->power.lock);
2112 dev->power.no_pm_callbacks =
Rafael J. Wysocki157c4602017-09-19 02:22:39 +02002113 (!dev->bus || (pm_ops_is_empty(dev->bus->pm) &&
2114 !dev->bus->suspend && !dev->bus->resume)) &&
Rafael J. Wysockia380f2e2017-09-25 14:56:44 +02002115 (!dev->class || pm_ops_is_empty(dev->class->pm)) &&
Tomeu Vizosoaa8e54b52016-01-07 16:46:14 +01002116 (!dev->type || pm_ops_is_empty(dev->type->pm)) &&
2117 (!dev->pm_domain || pm_ops_is_empty(&dev->pm_domain->ops)) &&
Rafael J. Wysocki157c4602017-09-19 02:22:39 +02002118 (!dev->driver || (pm_ops_is_empty(dev->driver->pm) &&
2119 !dev->driver->suspend && !dev->driver->resume));
Tomeu Vizosoaa8e54b52016-01-07 16:46:14 +01002120 spin_unlock_irq(&dev->power.lock);
2121}
Rafael J. Wysockic4b65152017-10-26 12:12:22 +02002122
2123bool dev_pm_smart_suspend_and_suspended(struct device *dev)
2124{
2125 return dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) &&
2126 pm_runtime_status_suspended(dev);
2127}