11a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 21da177e4SLinus Torvalds /* 31da177e4SLinus Torvalds * pm.h - Power management interface 41da177e4SLinus Torvalds * 51da177e4SLinus Torvalds * Copyright (C) 2000 Andrew Henroid 61da177e4SLinus Torvalds */ 71da177e4SLinus Torvalds 81da177e4SLinus Torvalds #ifndef _LINUX_PM_H 91da177e4SLinus Torvalds #define _LINUX_PM_H 101da177e4SLinus Torvalds 111da177e4SLinus Torvalds #include <linux/list.h> 125e928f77SRafael J. Wysocki #include <linux/workqueue.h> 135e928f77SRafael J. Wysocki #include <linux/spinlock.h> 145e928f77SRafael J. Wysocki #include <linux/wait.h> 155e928f77SRafael J. Wysocki #include <linux/timer.h> 168234f673SVincent Guittot #include <linux/hrtimer.h> 175af84b82SRafael J. Wysocki #include <linux/completion.h> 181da177e4SLinus Torvalds 191da177e4SLinus Torvalds /* 201da177e4SLinus Torvalds * Callbacks for platform drivers to implement. 211da177e4SLinus Torvalds */ 221da177e4SLinus Torvalds extern void (*pm_power_off)(void); 23bd804ebaSRafael J. Wysocki extern void (*pm_power_off_prepare)(void); 241da177e4SLinus Torvalds 25f43f627dSJesse Barnes struct device; /* we have a circular dep with device.h */ 26f43f627dSJesse Barnes #ifdef CONFIG_VT_CONSOLE_SLEEP 27f43f627dSJesse Barnes extern void pm_vt_switch_required(struct device *dev, bool required); 28f43f627dSJesse Barnes extern void pm_vt_switch_unregister(struct device *dev); 29f43f627dSJesse Barnes #else 30f43f627dSJesse Barnes static inline void pm_vt_switch_required(struct device *dev, bool required) 31f43f627dSJesse Barnes { 32f43f627dSJesse Barnes } 33f43f627dSJesse Barnes static inline void pm_vt_switch_unregister(struct device *dev) 34f43f627dSJesse Barnes { 35f43f627dSJesse Barnes } 36f43f627dSJesse Barnes #endif /* CONFIG_VT_CONSOLE_SLEEP */ 37f43f627dSJesse Barnes 381da177e4SLinus Torvalds /* 391da177e4SLinus Torvalds * Device power management 401da177e4SLinus Torvalds */ 411da177e4SLinus Torvalds 421da177e4SLinus Torvalds 437490e442SAlan Stern #ifdef CONFIG_PM 447490e442SAlan Stern extern const char power_group_name[]; /* = "power" */ 457490e442SAlan Stern #else 467490e442SAlan Stern #define power_group_name NULL 477490e442SAlan Stern #endif 487490e442SAlan Stern 49ca078baeSPavel Machek typedef struct pm_message { 50ca078baeSPavel Machek int event; 51ca078baeSPavel Machek } pm_message_t; 521da177e4SLinus Torvalds 531eede070SRafael J. Wysocki /** 544d29b2e5SRafael J. Wysocki * struct dev_pm_ops - device PM callbacks. 551eede070SRafael J. Wysocki * 56f7bc83d8SRafael J. Wysocki * @prepare: The principal role of this callback is to prevent new children of 57f7bc83d8SRafael J. Wysocki * the device from being registered after it has returned (the driver's 58f7bc83d8SRafael J. Wysocki * subsystem and generally the rest of the kernel is supposed to prevent 59f7bc83d8SRafael J. Wysocki * new calls to the probe method from being made too once @prepare() has 60f7bc83d8SRafael J. Wysocki * succeeded). If @prepare() detects a situation it cannot handle (e.g. 61f7bc83d8SRafael J. Wysocki * registration of a child already in progress), it may return -EAGAIN, so 62f7bc83d8SRafael J. Wysocki * that the PM core can execute it once again (e.g. after a new child has 63f7bc83d8SRafael J. Wysocki * been registered) to recover from the race condition. 64f7bc83d8SRafael J. Wysocki * This method is executed for all kinds of suspend transitions and is 65f7bc83d8SRafael J. Wysocki * followed by one of the suspend callbacks: @suspend(), @freeze(), or 66aae4518bSRafael J. Wysocki * @poweroff(). If the transition is a suspend to memory or standby (that 67aae4518bSRafael J. Wysocki * is, not related to hibernation), the return value of @prepare() may be 68aae4518bSRafael J. Wysocki * used to indicate to the PM core to leave the device in runtime suspend 69aae4518bSRafael J. Wysocki * if applicable. Namely, if @prepare() returns a positive number, the PM 70aae4518bSRafael J. Wysocki * core will understand that as a declaration that the device appears to be 71aae4518bSRafael J. Wysocki * runtime-suspended and it may be left in that state during the entire 72aae4518bSRafael J. Wysocki * transition and during the subsequent resume if all of its descendants 73aae4518bSRafael J. Wysocki * are left in runtime suspend too. If that happens, @complete() will be 74aae4518bSRafael J. Wysocki * executed directly after @prepare() and it must ensure the proper 75aae4518bSRafael J. Wysocki * functioning of the device after the system resume. 76aae4518bSRafael J. Wysocki * The PM core executes subsystem-level @prepare() for all devices before 77aae4518bSRafael J. Wysocki * starting to invoke suspend callbacks for any of them, so generally 78aae4518bSRafael J. Wysocki * devices may be assumed to be functional or to respond to runtime resume 79aae4518bSRafael J. Wysocki * requests while @prepare() is being executed. However, device drivers 80aae4518bSRafael J. Wysocki * may NOT assume anything about the availability of user space at that 81aae4518bSRafael J. Wysocki * time and it is NOT valid to request firmware from within @prepare() 82aae4518bSRafael J. Wysocki * (it's too late to do that). It also is NOT valid to allocate 83f7bc83d8SRafael J. Wysocki * substantial amounts of memory from @prepare() in the GFP_KERNEL mode. 84f7bc83d8SRafael J. Wysocki * [To work around these limitations, drivers may register suspend and 85f7bc83d8SRafael J. Wysocki * hibernation notifiers to be executed before the freezing of tasks.] 861eede070SRafael J. Wysocki * 871eede070SRafael J. Wysocki * @complete: Undo the changes made by @prepare(). This method is executed for 881eede070SRafael J. Wysocki * all kinds of resume transitions, following one of the resume callbacks: 891eede070SRafael J. Wysocki * @resume(), @thaw(), @restore(). Also called if the state transition 90f7bc83d8SRafael J. Wysocki * fails before the driver's suspend callback: @suspend(), @freeze() or 91f7bc83d8SRafael J. Wysocki * @poweroff(), can be executed (e.g. if the suspend callback fails for one 921eede070SRafael J. Wysocki * of the other devices that the PM core has unsuccessfully attempted to 931eede070SRafael J. Wysocki * suspend earlier). 94f7bc83d8SRafael J. Wysocki * The PM core executes subsystem-level @complete() after it has executed 95aae4518bSRafael J. Wysocki * the appropriate resume callbacks for all devices. If the corresponding 96aae4518bSRafael J. Wysocki * @prepare() at the beginning of the suspend transition returned a 97aae4518bSRafael J. Wysocki * positive number and the device was left in runtime suspend (without 98aae4518bSRafael J. Wysocki * executing any suspend and resume callbacks for it), @complete() will be 99aae4518bSRafael J. Wysocki * the only callback executed for the device during resume. In that case, 100aae4518bSRafael J. Wysocki * @complete() must be prepared to do whatever is necessary to ensure the 101aae4518bSRafael J. Wysocki * proper functioning of the device after the system resume. To this end, 102aae4518bSRafael J. Wysocki * @complete() can check the power.direct_complete flag of the device to 103aae4518bSRafael J. Wysocki * learn whether (unset) or not (set) the previous suspend and resume 104aae4518bSRafael J. Wysocki * callbacks have been executed for it. 1051eede070SRafael J. Wysocki * 1061eede070SRafael J. Wysocki * @suspend: Executed before putting the system into a sleep state in which the 107f7bc83d8SRafael J. Wysocki * contents of main memory are preserved. The exact action to perform 108f7bc83d8SRafael J. Wysocki * depends on the device's subsystem (PM domain, device type, class or bus 109f7bc83d8SRafael J. Wysocki * type), but generally the device must be quiescent after subsystem-level 110f7bc83d8SRafael J. Wysocki * @suspend() has returned, so that it doesn't do any I/O or DMA. 111f7bc83d8SRafael J. Wysocki * Subsystem-level @suspend() is executed for all devices after invoking 112f7bc83d8SRafael J. Wysocki * subsystem-level @prepare() for all of them. 1131eede070SRafael J. Wysocki * 114cf579dfbSRafael J. Wysocki * @suspend_late: Continue operations started by @suspend(). For a number of 115cf579dfbSRafael J. Wysocki * devices @suspend_late() may point to the same callback routine as the 116cf579dfbSRafael J. Wysocki * runtime suspend callback. 117cf579dfbSRafael J. Wysocki * 1181eede070SRafael J. Wysocki * @resume: Executed after waking the system up from a sleep state in which the 119f7bc83d8SRafael J. Wysocki * contents of main memory were preserved. The exact action to perform 120f7bc83d8SRafael J. Wysocki * depends on the device's subsystem, but generally the driver is expected 121f7bc83d8SRafael J. Wysocki * to start working again, responding to hardware events and software 122f7bc83d8SRafael J. Wysocki * requests (the device itself may be left in a low-power state, waiting 123f7bc83d8SRafael J. Wysocki * for a runtime resume to occur). The state of the device at the time its 124f7bc83d8SRafael J. Wysocki * driver's @resume() callback is run depends on the platform and subsystem 125f7bc83d8SRafael J. Wysocki * the device belongs to. On most platforms, there are no restrictions on 126f7bc83d8SRafael J. Wysocki * availability of resources like clocks during @resume(). 127f7bc83d8SRafael J. Wysocki * Subsystem-level @resume() is executed for all devices after invoking 128f7bc83d8SRafael J. Wysocki * subsystem-level @resume_noirq() for all of them. 1291eede070SRafael J. Wysocki * 130cf579dfbSRafael J. Wysocki * @resume_early: Prepare to execute @resume(). For a number of devices 131cf579dfbSRafael J. Wysocki * @resume_early() may point to the same callback routine as the runtime 132cf579dfbSRafael J. Wysocki * resume callback. 133cf579dfbSRafael J. Wysocki * 1341eede070SRafael J. Wysocki * @freeze: Hibernation-specific, executed before creating a hibernation image. 135f7bc83d8SRafael J. Wysocki * Analogous to @suspend(), but it should not enable the device to signal 136f7bc83d8SRafael J. Wysocki * wakeup events or change its power state. The majority of subsystems 137f7bc83d8SRafael J. Wysocki * (with the notable exception of the PCI bus type) expect the driver-level 138f7bc83d8SRafael J. Wysocki * @freeze() to save the device settings in memory to be used by @restore() 139f7bc83d8SRafael J. Wysocki * during the subsequent resume from hibernation. 140f7bc83d8SRafael J. Wysocki * Subsystem-level @freeze() is executed for all devices after invoking 141f7bc83d8SRafael J. Wysocki * subsystem-level @prepare() for all of them. 1421eede070SRafael J. Wysocki * 143cf579dfbSRafael J. Wysocki * @freeze_late: Continue operations started by @freeze(). Analogous to 144cf579dfbSRafael J. Wysocki * @suspend_late(), but it should not enable the device to signal wakeup 145cf579dfbSRafael J. Wysocki * events or change its power state. 146cf579dfbSRafael J. Wysocki * 1471eede070SRafael J. Wysocki * @thaw: Hibernation-specific, executed after creating a hibernation image OR 148f7bc83d8SRafael J. Wysocki * if the creation of an image has failed. Also executed after a failing 1491eede070SRafael J. Wysocki * attempt to restore the contents of main memory from such an image. 1501eede070SRafael J. Wysocki * Undo the changes made by the preceding @freeze(), so the device can be 1511eede070SRafael J. Wysocki * operated in the same way as immediately before the call to @freeze(). 152f7bc83d8SRafael J. Wysocki * Subsystem-level @thaw() is executed for all devices after invoking 153f7bc83d8SRafael J. Wysocki * subsystem-level @thaw_noirq() for all of them. It also may be executed 154f7bc83d8SRafael J. Wysocki * directly after @freeze() in case of a transition error. 1551eede070SRafael J. Wysocki * 156cf579dfbSRafael J. Wysocki * @thaw_early: Prepare to execute @thaw(). Undo the changes made by the 157cf579dfbSRafael J. Wysocki * preceding @freeze_late(). 158cf579dfbSRafael J. Wysocki * 1591eede070SRafael J. Wysocki * @poweroff: Hibernation-specific, executed after saving a hibernation image. 160f7bc83d8SRafael J. Wysocki * Analogous to @suspend(), but it need not save the device's settings in 161f7bc83d8SRafael J. Wysocki * memory. 162f7bc83d8SRafael J. Wysocki * Subsystem-level @poweroff() is executed for all devices after invoking 163f7bc83d8SRafael J. Wysocki * subsystem-level @prepare() for all of them. 1641eede070SRafael J. Wysocki * 165cf579dfbSRafael J. Wysocki * @poweroff_late: Continue operations started by @poweroff(). Analogous to 166cf579dfbSRafael J. Wysocki * @suspend_late(), but it need not save the device's settings in memory. 167cf579dfbSRafael J. Wysocki * 1681eede070SRafael J. Wysocki * @restore: Hibernation-specific, executed after restoring the contents of main 169f7bc83d8SRafael J. Wysocki * memory from a hibernation image, analogous to @resume(). 1701eede070SRafael J. Wysocki * 171cf579dfbSRafael J. Wysocki * @restore_early: Prepare to execute @restore(), analogous to @resume_early(). 172cf579dfbSRafael J. Wysocki * 173f7bc83d8SRafael J. Wysocki * @suspend_noirq: Complete the actions started by @suspend(). Carry out any 174f7bc83d8SRafael J. Wysocki * additional operations required for suspending the device that might be 175f7bc83d8SRafael J. Wysocki * racing with its driver's interrupt handler, which is guaranteed not to 176f7bc83d8SRafael J. Wysocki * run while @suspend_noirq() is being executed. 177f7bc83d8SRafael J. Wysocki * It generally is expected that the device will be in a low-power state 178f7bc83d8SRafael J. Wysocki * (appropriate for the target system sleep state) after subsystem-level 179f7bc83d8SRafael J. Wysocki * @suspend_noirq() has returned successfully. If the device can generate 180f7bc83d8SRafael J. Wysocki * system wakeup signals and is enabled to wake up the system, it should be 181f7bc83d8SRafael J. Wysocki * configured to do so at that time. However, depending on the platform 182cf579dfbSRafael J. Wysocki * and device's subsystem, @suspend() or @suspend_late() may be allowed to 183cf579dfbSRafael J. Wysocki * put the device into the low-power state and configure it to generate 184cf579dfbSRafael J. Wysocki * wakeup signals, in which case it generally is not necessary to define 185cf579dfbSRafael J. Wysocki * @suspend_noirq(). 1861eede070SRafael J. Wysocki * 187f7bc83d8SRafael J. Wysocki * @resume_noirq: Prepare for the execution of @resume() by carrying out any 188f7bc83d8SRafael J. Wysocki * operations required for resuming the device that might be racing with 189f7bc83d8SRafael J. Wysocki * its driver's interrupt handler, which is guaranteed not to run while 190f7bc83d8SRafael J. Wysocki * @resume_noirq() is being executed. 1911eede070SRafael J. Wysocki * 192f7bc83d8SRafael J. Wysocki * @freeze_noirq: Complete the actions started by @freeze(). Carry out any 193f7bc83d8SRafael J. Wysocki * additional operations required for freezing the device that might be 194f7bc83d8SRafael J. Wysocki * racing with its driver's interrupt handler, which is guaranteed not to 195f7bc83d8SRafael J. Wysocki * run while @freeze_noirq() is being executed. 196cf579dfbSRafael J. Wysocki * The power state of the device should not be changed by either @freeze(), 197cf579dfbSRafael J. Wysocki * or @freeze_late(), or @freeze_noirq() and it should not be configured to 198cf579dfbSRafael J. Wysocki * signal system wakeup by any of these callbacks. 1991eede070SRafael J. Wysocki * 200f7bc83d8SRafael J. Wysocki * @thaw_noirq: Prepare for the execution of @thaw() by carrying out any 201f7bc83d8SRafael J. Wysocki * operations required for thawing the device that might be racing with its 202f7bc83d8SRafael J. Wysocki * driver's interrupt handler, which is guaranteed not to run while 203f7bc83d8SRafael J. Wysocki * @thaw_noirq() is being executed. 2041eede070SRafael J. Wysocki * 205f7bc83d8SRafael J. Wysocki * @poweroff_noirq: Complete the actions started by @poweroff(). Analogous to 206f7bc83d8SRafael J. Wysocki * @suspend_noirq(), but it need not save the device's settings in memory. 2071eede070SRafael J. Wysocki * 208f7bc83d8SRafael J. Wysocki * @restore_noirq: Prepare for the execution of @restore() by carrying out any 209f7bc83d8SRafael J. Wysocki * operations required for thawing the device that might be racing with its 210f7bc83d8SRafael J. Wysocki * driver's interrupt handler, which is guaranteed not to run while 211f7bc83d8SRafael J. Wysocki * @restore_noirq() is being executed. Analogous to @resume_noirq(). 2121eede070SRafael J. Wysocki * 2135e928f77SRafael J. Wysocki * @runtime_suspend: Prepare the device for a condition in which it won't be 2145e928f77SRafael J. Wysocki * able to communicate with the CPU(s) and RAM due to power management. 215f7bc83d8SRafael J. Wysocki * This need not mean that the device should be put into a low-power state. 2165e928f77SRafael J. Wysocki * For example, if the device is behind a link which is about to be turned 2175e928f77SRafael J. Wysocki * off, the device may remain at full power. If the device does go to low 218f7bc83d8SRafael J. Wysocki * power and is capable of generating runtime wakeup events, remote wakeup 219f7bc83d8SRafael J. Wysocki * (i.e., a hardware mechanism allowing the device to request a change of 220f7bc83d8SRafael J. Wysocki * its power state via an interrupt) should be enabled for it. 2215e928f77SRafael J. Wysocki * 2225e928f77SRafael J. Wysocki * @runtime_resume: Put the device into the fully active state in response to a 223f7bc83d8SRafael J. Wysocki * wakeup event generated by hardware or at the request of software. If 224f7bc83d8SRafael J. Wysocki * necessary, put the device into the full-power state and restore its 2255e928f77SRafael J. Wysocki * registers, so that it is fully operational. 2265e928f77SRafael J. Wysocki * 227f7bc83d8SRafael J. Wysocki * @runtime_idle: Device appears to be inactive and it might be put into a 228651665dbSGeert Uytterhoeven * low-power state if all of the necessary conditions are satisfied. 229651665dbSGeert Uytterhoeven * Check these conditions, and return 0 if it's appropriate to let the PM 230651665dbSGeert Uytterhoeven * core queue a suspend request for the device. 231f7bc83d8SRafael J. Wysocki * 2324d29b2e5SRafael J. Wysocki * Several device power state transitions are externally visible, affecting 2334d29b2e5SRafael J. Wysocki * the state of pending I/O queues and (for drivers that touch hardware) 2344d29b2e5SRafael J. Wysocki * interrupts, wakeups, DMA, and other hardware state. There may also be 2354d29b2e5SRafael J. Wysocki * internal transitions to various low-power modes which are transparent 2364d29b2e5SRafael J. Wysocki * to the rest of the driver stack (such as a driver that's ON gating off 2374d29b2e5SRafael J. Wysocki * clocks which are not in active use). 238f7bc83d8SRafael J. Wysocki * 2394d29b2e5SRafael J. Wysocki * The externally visible transitions are handled with the help of callbacks 2404d29b2e5SRafael J. Wysocki * included in this structure in such a way that, typically, two levels of 2414d29b2e5SRafael J. Wysocki * callbacks are involved. First, the PM core executes callbacks provided by PM 2424d29b2e5SRafael J. Wysocki * domains, device types, classes and bus types. They are the subsystem-level 2434d29b2e5SRafael J. Wysocki * callbacks expected to execute callbacks provided by device drivers, although 2444d29b2e5SRafael J. Wysocki * they may choose not to do that. If the driver callbacks are executed, they 2454d29b2e5SRafael J. Wysocki * have to collaborate with the subsystem-level callbacks to achieve the goals 2464d29b2e5SRafael J. Wysocki * appropriate for the given system transition, given transition phase and the 2474d29b2e5SRafael J. Wysocki * subsystem the device belongs to. 2484d29b2e5SRafael J. Wysocki * 2494d29b2e5SRafael J. Wysocki * All of the above callbacks, except for @complete(), return error codes. 2504d29b2e5SRafael J. Wysocki * However, the error codes returned by @resume(), @thaw(), @restore(), 2514d29b2e5SRafael J. Wysocki * @resume_noirq(), @thaw_noirq(), and @restore_noirq(), do not cause the PM 2524d29b2e5SRafael J. Wysocki * core to abort the resume transition during which they are returned. The 2534d29b2e5SRafael J. Wysocki * error codes returned in those cases are only printed to the system logs for 2544d29b2e5SRafael J. Wysocki * debugging purposes. Still, it is recommended that drivers only return error 2554d29b2e5SRafael J. Wysocki * codes from their resume methods in case of an unrecoverable failure (i.e. 2564d29b2e5SRafael J. Wysocki * when the device being handled refuses to resume and becomes unusable) to 2574d29b2e5SRafael J. Wysocki * allow the PM core to be modified in the future, so that it can avoid 2584d29b2e5SRafael J. Wysocki * attempting to handle devices that failed to resume and their children. 2594d29b2e5SRafael J. Wysocki * 2604d29b2e5SRafael J. Wysocki * It is allowed to unregister devices while the above callbacks are being 2614d29b2e5SRafael J. Wysocki * executed. However, a callback routine MUST NOT try to unregister the device 2624d29b2e5SRafael J. Wysocki * it was called for, although it may unregister children of that device (for 2634d29b2e5SRafael J. Wysocki * example, if it detects that a child was unplugged while the system was 2644d29b2e5SRafael J. Wysocki * asleep). 2654d29b2e5SRafael J. Wysocki * 2664d29b2e5SRafael J. Wysocki * There also are callbacks related to runtime power management of devices. 2674d29b2e5SRafael J. Wysocki * Again, as a rule these callbacks are executed by the PM core for subsystems 2684d29b2e5SRafael J. Wysocki * (PM domains, device types, classes and bus types) and the subsystem-level 2694d29b2e5SRafael J. Wysocki * callbacks are expected to invoke the driver callbacks. Moreover, the exact 2704d29b2e5SRafael J. Wysocki * actions to be performed by a device driver's callbacks generally depend on 2714d29b2e5SRafael J. Wysocki * the platform and subsystem the device belongs to. 2724d29b2e5SRafael J. Wysocki * 273151f4e2bSMauro Carvalho Chehab * Refer to Documentation/power/runtime_pm.rst for more information about the 2744d29b2e5SRafael J. Wysocki * role of the @runtime_suspend(), @runtime_resume() and @runtime_idle() 2754d29b2e5SRafael J. Wysocki * callbacks in device runtime power management. 2761eede070SRafael J. Wysocki */ 277adf09493SRafael J. Wysocki struct dev_pm_ops { 278adf09493SRafael J. Wysocki int (*prepare)(struct device *dev); 279adf09493SRafael J. Wysocki void (*complete)(struct device *dev); 280adf09493SRafael J. Wysocki int (*suspend)(struct device *dev); 281adf09493SRafael J. Wysocki int (*resume)(struct device *dev); 282adf09493SRafael J. Wysocki int (*freeze)(struct device *dev); 283adf09493SRafael J. Wysocki int (*thaw)(struct device *dev); 284adf09493SRafael J. Wysocki int (*poweroff)(struct device *dev); 285adf09493SRafael J. Wysocki int (*restore)(struct device *dev); 286cf579dfbSRafael J. Wysocki int (*suspend_late)(struct device *dev); 287cf579dfbSRafael J. Wysocki int (*resume_early)(struct device *dev); 288cf579dfbSRafael J. Wysocki int (*freeze_late)(struct device *dev); 289cf579dfbSRafael J. Wysocki int (*thaw_early)(struct device *dev); 290cf579dfbSRafael J. Wysocki int (*poweroff_late)(struct device *dev); 291cf579dfbSRafael J. Wysocki int (*restore_early)(struct device *dev); 2921eede070SRafael J. Wysocki int (*suspend_noirq)(struct device *dev); 2931eede070SRafael J. Wysocki int (*resume_noirq)(struct device *dev); 2941eede070SRafael J. Wysocki int (*freeze_noirq)(struct device *dev); 2951eede070SRafael J. Wysocki int (*thaw_noirq)(struct device *dev); 2961eede070SRafael J. Wysocki int (*poweroff_noirq)(struct device *dev); 2971eede070SRafael J. Wysocki int (*restore_noirq)(struct device *dev); 2985e928f77SRafael J. Wysocki int (*runtime_suspend)(struct device *dev); 2995e928f77SRafael J. Wysocki int (*runtime_resume)(struct device *dev); 3005e928f77SRafael J. Wysocki int (*runtime_idle)(struct device *dev); 3011eede070SRafael J. Wysocki }; 3021eede070SRafael J. Wysocki 3031a3c7bb0SPaul Cercueil #define SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ 3041a3c7bb0SPaul Cercueil .suspend = pm_sleep_ptr(suspend_fn), \ 3051a3c7bb0SPaul Cercueil .resume = pm_sleep_ptr(resume_fn), \ 3061a3c7bb0SPaul Cercueil .freeze = pm_sleep_ptr(suspend_fn), \ 3071a3c7bb0SPaul Cercueil .thaw = pm_sleep_ptr(resume_fn), \ 3081a3c7bb0SPaul Cercueil .poweroff = pm_sleep_ptr(suspend_fn), \ 3091a3c7bb0SPaul Cercueil .restore = pm_sleep_ptr(resume_fn), 3101a3c7bb0SPaul Cercueil 3111a3c7bb0SPaul Cercueil #define LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ 3121a3c7bb0SPaul Cercueil .suspend_late = pm_sleep_ptr(suspend_fn), \ 3131a3c7bb0SPaul Cercueil .resume_early = pm_sleep_ptr(resume_fn), \ 3141a3c7bb0SPaul Cercueil .freeze_late = pm_sleep_ptr(suspend_fn), \ 3151a3c7bb0SPaul Cercueil .thaw_early = pm_sleep_ptr(resume_fn), \ 3161a3c7bb0SPaul Cercueil .poweroff_late = pm_sleep_ptr(suspend_fn), \ 3171a3c7bb0SPaul Cercueil .restore_early = pm_sleep_ptr(resume_fn), 3181a3c7bb0SPaul Cercueil 3191a3c7bb0SPaul Cercueil #define NOIRQ_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ 3201a3c7bb0SPaul Cercueil .suspend_noirq = pm_sleep_ptr(suspend_fn), \ 3211a3c7bb0SPaul Cercueil .resume_noirq = pm_sleep_ptr(resume_fn), \ 3221a3c7bb0SPaul Cercueil .freeze_noirq = pm_sleep_ptr(suspend_fn), \ 3231a3c7bb0SPaul Cercueil .thaw_noirq = pm_sleep_ptr(resume_fn), \ 3241a3c7bb0SPaul Cercueil .poweroff_noirq = pm_sleep_ptr(suspend_fn), \ 3251a3c7bb0SPaul Cercueil .restore_noirq = pm_sleep_ptr(resume_fn), 3261a3c7bb0SPaul Cercueil 3271a3c7bb0SPaul Cercueil #define RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ 3281a3c7bb0SPaul Cercueil .runtime_suspend = suspend_fn, \ 3291a3c7bb0SPaul Cercueil .runtime_resume = resume_fn, \ 3301a3c7bb0SPaul Cercueil .runtime_idle = idle_fn, 3311a3c7bb0SPaul Cercueil 332d690b2cdSRafael J. Wysocki #ifdef CONFIG_PM_SLEEP 333d690b2cdSRafael J. Wysocki #define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ 3341a3c7bb0SPaul Cercueil SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) 335d690b2cdSRafael J. Wysocki #else 336d690b2cdSRafael J. Wysocki #define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) 337d690b2cdSRafael J. Wysocki #endif 338d690b2cdSRafael J. Wysocki 339f78c4cffSUlf Hansson #ifdef CONFIG_PM_SLEEP 340f78c4cffSUlf Hansson #define SET_LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ 3411a3c7bb0SPaul Cercueil LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) 342f78c4cffSUlf Hansson #else 343f78c4cffSUlf Hansson #define SET_LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) 344f78c4cffSUlf Hansson #endif 345f78c4cffSUlf Hansson 346020af89aSGrygorii Strashko #ifdef CONFIG_PM_SLEEP 347020af89aSGrygorii Strashko #define SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ 3481a3c7bb0SPaul Cercueil NOIRQ_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) 349020af89aSGrygorii Strashko #else 350020af89aSGrygorii Strashko #define SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) 351020af89aSGrygorii Strashko #endif 352020af89aSGrygorii Strashko 3536ed23b80SRafael J. Wysocki #ifdef CONFIG_PM 354d690b2cdSRafael J. Wysocki #define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ 3551a3c7bb0SPaul Cercueil RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) 356d690b2cdSRafael J. Wysocki #else 357d690b2cdSRafael J. Wysocki #define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) 358d690b2cdSRafael J. Wysocki #endif 359d690b2cdSRafael J. Wysocki 3609d62ec6cSAlbin Tonnerre /* 3619d62ec6cSAlbin Tonnerre * Use this if you want to use the same suspend and resume callbacks for suspend 3629d62ec6cSAlbin Tonnerre * to RAM and hibernation. 3639d62ec6cSAlbin Tonnerre */ 3641a3c7bb0SPaul Cercueil #define DEFINE_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ 3651a3c7bb0SPaul Cercueil static const struct dev_pm_ops name = { \ 3661a3c7bb0SPaul Cercueil SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ 3679d62ec6cSAlbin Tonnerre } 3689d62ec6cSAlbin Tonnerre 369d690b2cdSRafael J. Wysocki /* 370d690b2cdSRafael J. Wysocki * Use this for defining a set of PM operations to be used in all situations 3713e54d151SLad, Prabhakar * (system suspend, hibernation or runtime PM). 372c4882525SRafael J. Wysocki * NOTE: In general, system suspend callbacks, .suspend() and .resume(), should 373c4882525SRafael J. Wysocki * be different from the corresponding runtime PM callbacks, .runtime_suspend(), 374c4882525SRafael J. Wysocki * and .runtime_resume(), because .runtime_suspend() always works on an already 375c4882525SRafael J. Wysocki * quiescent device, while .suspend() should assume that the device may be doing 376c4882525SRafael J. Wysocki * something when it is called (it should ensure that the device will be 377c4882525SRafael J. Wysocki * quiescent after it has returned). Therefore it's better to point the "late" 378c4882525SRafael J. Wysocki * suspend and "early" resume callback pointers, .suspend_late() and 379c4882525SRafael J. Wysocki * .resume_early(), to the same routines as .runtime_suspend() and 380c4882525SRafael J. Wysocki * .runtime_resume(), respectively (and analogously for hibernation). 381d690b2cdSRafael J. Wysocki */ 3821a3c7bb0SPaul Cercueil #define DEFINE_UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \ 3831a3c7bb0SPaul Cercueil static const struct dev_pm_ops name = { \ 3841a3c7bb0SPaul Cercueil SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ 3851a3c7bb0SPaul Cercueil RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ 3861a3c7bb0SPaul Cercueil } 3871a3c7bb0SPaul Cercueil 3881a3c7bb0SPaul Cercueil /* Deprecated. Use DEFINE_SIMPLE_DEV_PM_OPS() instead. */ 3891a3c7bb0SPaul Cercueil #define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ 3901a3c7bb0SPaul Cercueil const struct dev_pm_ops __maybe_unused name = { \ 3911a3c7bb0SPaul Cercueil SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ 3921a3c7bb0SPaul Cercueil } 3931a3c7bb0SPaul Cercueil 3941a3c7bb0SPaul Cercueil /* Deprecated. Use DEFINE_UNIVERSAL_DEV_PM_OPS() instead. */ 395d690b2cdSRafael J. Wysocki #define UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \ 396756a64ceSPaul Cercueil const struct dev_pm_ops __maybe_unused name = { \ 397d690b2cdSRafael J. Wysocki SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ 398d690b2cdSRafael J. Wysocki SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ 399d690b2cdSRafael J. Wysocki } 400d690b2cdSRafael J. Wysocki 401c06ef740SPaul Cercueil #define pm_ptr(_ptr) PTR_IF(IS_ENABLED(CONFIG_PM), (_ptr)) 4021a3c7bb0SPaul Cercueil #define pm_sleep_ptr(_ptr) PTR_IF(IS_ENABLED(CONFIG_PM_SLEEP), (_ptr)) 4037a82e97aSPaul Cercueil 4044d29b2e5SRafael J. Wysocki /* 4051eede070SRafael J. Wysocki * PM_EVENT_ messages 4061eede070SRafael J. Wysocki * 4071eede070SRafael J. Wysocki * The following PM_EVENT_ messages are defined for the internal use of the PM 4081eede070SRafael J. Wysocki * core, in order to provide a mechanism allowing the high level suspend and 4091eede070SRafael J. Wysocki * hibernation code to convey the necessary information to the device PM core 4101eede070SRafael J. Wysocki * code: 4111eede070SRafael J. Wysocki * 4121eede070SRafael J. Wysocki * ON No transition. 4131eede070SRafael J. Wysocki * 4141eede070SRafael J. Wysocki * FREEZE System is going to hibernate, call ->prepare() and ->freeze() 4151eede070SRafael J. Wysocki * for all devices. 4161eede070SRafael J. Wysocki * 4171eede070SRafael J. Wysocki * SUSPEND System is going to suspend, call ->prepare() and ->suspend() 4181eede070SRafael J. Wysocki * for all devices. 4191eede070SRafael J. Wysocki * 4201eede070SRafael J. Wysocki * HIBERNATE Hibernation image has been saved, call ->prepare() and 4211eede070SRafael J. Wysocki * ->poweroff() for all devices. 4221eede070SRafael J. Wysocki * 4231eede070SRafael J. Wysocki * QUIESCE Contents of main memory are going to be restored from a (loaded) 4241eede070SRafael J. Wysocki * hibernation image, call ->prepare() and ->freeze() for all 4251eede070SRafael J. Wysocki * devices. 4261eede070SRafael J. Wysocki * 4271eede070SRafael J. Wysocki * RESUME System is resuming, call ->resume() and ->complete() for all 4281eede070SRafael J. Wysocki * devices. 4291eede070SRafael J. Wysocki * 4301eede070SRafael J. Wysocki * THAW Hibernation image has been created, call ->thaw() and 4311eede070SRafael J. Wysocki * ->complete() for all devices. 4321eede070SRafael J. Wysocki * 4331eede070SRafael J. Wysocki * RESTORE Contents of main memory have been restored from a hibernation 4341eede070SRafael J. Wysocki * image, call ->restore() and ->complete() for all devices. 4351eede070SRafael J. Wysocki * 4361eede070SRafael J. Wysocki * RECOVER Creation of a hibernation image or restoration of the main 4371eede070SRafael J. Wysocki * memory contents from a hibernation image has failed, call 4381eede070SRafael J. Wysocki * ->thaw() and ->complete() for all devices. 4398111d1b5SAlan Stern * 4408111d1b5SAlan Stern * The following PM_EVENT_ messages are defined for internal use by 4418111d1b5SAlan Stern * kernel subsystems. They are never issued by the PM core. 4428111d1b5SAlan Stern * 4438111d1b5SAlan Stern * USER_SUSPEND Manual selective suspend was issued by userspace. 4448111d1b5SAlan Stern * 4458111d1b5SAlan Stern * USER_RESUME Manual selective resume was issued by userspace. 4468111d1b5SAlan Stern * 4478111d1b5SAlan Stern * REMOTE_WAKEUP Remote-wakeup request was received from the device. 4488111d1b5SAlan Stern * 4498111d1b5SAlan Stern * AUTO_SUSPEND Automatic (device idle) runtime suspend was 4508111d1b5SAlan Stern * initiated by the subsystem. 4518111d1b5SAlan Stern * 4528111d1b5SAlan Stern * AUTO_RESUME Automatic (device needed) runtime resume was 4538111d1b5SAlan Stern * requested by a driver. 4541eede070SRafael J. Wysocki */ 4551eede070SRafael J. Wysocki 4561a9a9152SRafael J. Wysocki #define PM_EVENT_INVALID (-1) 4571eede070SRafael J. Wysocki #define PM_EVENT_ON 0x0000 4581eede070SRafael J. Wysocki #define PM_EVENT_FREEZE 0x0001 4591eede070SRafael J. Wysocki #define PM_EVENT_SUSPEND 0x0002 4601eede070SRafael J. Wysocki #define PM_EVENT_HIBERNATE 0x0004 4611eede070SRafael J. Wysocki #define PM_EVENT_QUIESCE 0x0008 4621eede070SRafael J. Wysocki #define PM_EVENT_RESUME 0x0010 4631eede070SRafael J. Wysocki #define PM_EVENT_THAW 0x0020 4641eede070SRafael J. Wysocki #define PM_EVENT_RESTORE 0x0040 4651eede070SRafael J. Wysocki #define PM_EVENT_RECOVER 0x0080 4668111d1b5SAlan Stern #define PM_EVENT_USER 0x0100 4678111d1b5SAlan Stern #define PM_EVENT_REMOTE 0x0200 4688111d1b5SAlan Stern #define PM_EVENT_AUTO 0x0400 4691eede070SRafael J. Wysocki 4701eede070SRafael J. Wysocki #define PM_EVENT_SLEEP (PM_EVENT_SUSPEND | PM_EVENT_HIBERNATE) 4718111d1b5SAlan Stern #define PM_EVENT_USER_SUSPEND (PM_EVENT_USER | PM_EVENT_SUSPEND) 4728111d1b5SAlan Stern #define PM_EVENT_USER_RESUME (PM_EVENT_USER | PM_EVENT_RESUME) 4737f4f5d45SAlan Stern #define PM_EVENT_REMOTE_RESUME (PM_EVENT_REMOTE | PM_EVENT_RESUME) 4748111d1b5SAlan Stern #define PM_EVENT_AUTO_SUSPEND (PM_EVENT_AUTO | PM_EVENT_SUSPEND) 4758111d1b5SAlan Stern #define PM_EVENT_AUTO_RESUME (PM_EVENT_AUTO | PM_EVENT_RESUME) 4761eede070SRafael J. Wysocki 4771a9a9152SRafael J. Wysocki #define PMSG_INVALID ((struct pm_message){ .event = PM_EVENT_INVALID, }) 4788111d1b5SAlan Stern #define PMSG_ON ((struct pm_message){ .event = PM_EVENT_ON, }) 4791eede070SRafael J. Wysocki #define PMSG_FREEZE ((struct pm_message){ .event = PM_EVENT_FREEZE, }) 4801eede070SRafael J. Wysocki #define PMSG_QUIESCE ((struct pm_message){ .event = PM_EVENT_QUIESCE, }) 4811eede070SRafael J. Wysocki #define PMSG_SUSPEND ((struct pm_message){ .event = PM_EVENT_SUSPEND, }) 4821eede070SRafael J. Wysocki #define PMSG_HIBERNATE ((struct pm_message){ .event = PM_EVENT_HIBERNATE, }) 4831eede070SRafael J. Wysocki #define PMSG_RESUME ((struct pm_message){ .event = PM_EVENT_RESUME, }) 4841eede070SRafael J. Wysocki #define PMSG_THAW ((struct pm_message){ .event = PM_EVENT_THAW, }) 4851eede070SRafael J. Wysocki #define PMSG_RESTORE ((struct pm_message){ .event = PM_EVENT_RESTORE, }) 4861eede070SRafael J. Wysocki #define PMSG_RECOVER ((struct pm_message){ .event = PM_EVENT_RECOVER, }) 4877f4f5d45SAlan Stern #define PMSG_USER_SUSPEND ((struct pm_message) \ 4888111d1b5SAlan Stern { .event = PM_EVENT_USER_SUSPEND, }) 4897f4f5d45SAlan Stern #define PMSG_USER_RESUME ((struct pm_message) \ 4908111d1b5SAlan Stern { .event = PM_EVENT_USER_RESUME, }) 4917f4f5d45SAlan Stern #define PMSG_REMOTE_RESUME ((struct pm_message) \ 4928111d1b5SAlan Stern { .event = PM_EVENT_REMOTE_RESUME, }) 4937f4f5d45SAlan Stern #define PMSG_AUTO_SUSPEND ((struct pm_message) \ 4948111d1b5SAlan Stern { .event = PM_EVENT_AUTO_SUSPEND, }) 4957f4f5d45SAlan Stern #define PMSG_AUTO_RESUME ((struct pm_message) \ 4968111d1b5SAlan Stern { .event = PM_EVENT_AUTO_RESUME, }) 4971eede070SRafael J. Wysocki 4985b1b0b81SAlan Stern #define PMSG_IS_AUTO(msg) (((msg).event & PM_EVENT_AUTO) != 0) 4995b1b0b81SAlan Stern 5004d29b2e5SRafael J. Wysocki /* 5015e928f77SRafael J. Wysocki * Device run-time power management status. 5025e928f77SRafael J. Wysocki * 5035e928f77SRafael J. Wysocki * These status labels are used internally by the PM core to indicate the 5045e928f77SRafael J. Wysocki * current status of a device with respect to the PM core operations. They do 5055e928f77SRafael J. Wysocki * not reflect the actual power state of the device or its status as seen by the 5065e928f77SRafael J. Wysocki * driver. 5075e928f77SRafael J. Wysocki * 5085e928f77SRafael J. Wysocki * RPM_ACTIVE Device is fully operational. Indicates that the device 5095e928f77SRafael J. Wysocki * bus type's ->runtime_resume() callback has completed 5105e928f77SRafael J. Wysocki * successfully. 5115e928f77SRafael J. Wysocki * 5125e928f77SRafael J. Wysocki * RPM_SUSPENDED Device bus type's ->runtime_suspend() callback has 5135e928f77SRafael J. Wysocki * completed successfully. The device is regarded as 5145e928f77SRafael J. Wysocki * suspended. 5155e928f77SRafael J. Wysocki * 5165e928f77SRafael J. Wysocki * RPM_RESUMING Device bus type's ->runtime_resume() callback is being 5175e928f77SRafael J. Wysocki * executed. 5185e928f77SRafael J. Wysocki * 5195e928f77SRafael J. Wysocki * RPM_SUSPENDING Device bus type's ->runtime_suspend() callback is being 5205e928f77SRafael J. Wysocki * executed. 5215e928f77SRafael J. Wysocki */ 5225e928f77SRafael J. Wysocki 5235e928f77SRafael J. Wysocki enum rpm_status { 524*c24efa67SRafael J. Wysocki RPM_INVALID = -1, 5255e928f77SRafael J. Wysocki RPM_ACTIVE = 0, 5265e928f77SRafael J. Wysocki RPM_RESUMING, 5275e928f77SRafael J. Wysocki RPM_SUSPENDED, 5285e928f77SRafael J. Wysocki RPM_SUSPENDING, 5295e928f77SRafael J. Wysocki }; 5305e928f77SRafael J. Wysocki 5314d29b2e5SRafael J. Wysocki /* 5325e928f77SRafael J. Wysocki * Device run-time power management request types. 5335e928f77SRafael J. Wysocki * 5345e928f77SRafael J. Wysocki * RPM_REQ_NONE Do nothing. 5355e928f77SRafael J. Wysocki * 5365e928f77SRafael J. Wysocki * RPM_REQ_IDLE Run the device bus type's ->runtime_idle() callback 5375e928f77SRafael J. Wysocki * 5385e928f77SRafael J. Wysocki * RPM_REQ_SUSPEND Run the device bus type's ->runtime_suspend() callback 5395e928f77SRafael J. Wysocki * 54015bcb91dSAlan Stern * RPM_REQ_AUTOSUSPEND Same as RPM_REQ_SUSPEND, but not until the device has 54115bcb91dSAlan Stern * been inactive for as long as power.autosuspend_delay 54215bcb91dSAlan Stern * 5435e928f77SRafael J. Wysocki * RPM_REQ_RESUME Run the device bus type's ->runtime_resume() callback 5445e928f77SRafael J. Wysocki */ 5455e928f77SRafael J. Wysocki 5465e928f77SRafael J. Wysocki enum rpm_request { 5475e928f77SRafael J. Wysocki RPM_REQ_NONE = 0, 5485e928f77SRafael J. Wysocki RPM_REQ_IDLE, 5495e928f77SRafael J. Wysocki RPM_REQ_SUSPEND, 55015bcb91dSAlan Stern RPM_REQ_AUTOSUSPEND, 5515e928f77SRafael J. Wysocki RPM_REQ_RESUME, 5525e928f77SRafael J. Wysocki }; 5535e928f77SRafael J. Wysocki 554074037ecSRafael J. Wysocki struct wakeup_source; 5554990d4feSTony Lindgren struct wake_irq; 55600e7c295SUlf Hansson struct pm_domain_data; 5574605ab65SRafael J. Wysocki 5585c095a0eSRafael J. Wysocki struct pm_subsys_data { 5595c095a0eSRafael J. Wysocki spinlock_t lock; 560ef27bed1SRafael J. Wysocki unsigned int refcount; 5615c095a0eSRafael J. Wysocki #ifdef CONFIG_PM_CLK 5620bfa0820SNicolas Pitre unsigned int clock_op_might_sleep; 5630bfa0820SNicolas Pitre struct mutex clock_mutex; 5645c095a0eSRafael J. Wysocki struct list_head clock_list; 5655c095a0eSRafael J. Wysocki #endif 5664605ab65SRafael J. Wysocki #ifdef CONFIG_PM_GENERIC_DOMAINS 567cd0ea672SRafael J. Wysocki struct pm_domain_data *domain_data; 5684605ab65SRafael J. Wysocki #endif 5695c095a0eSRafael J. Wysocki }; 5705c095a0eSRafael J. Wysocki 57108810a41SRafael J. Wysocki /* 57208810a41SRafael J. Wysocki * Driver flags to control system suspend/resume behavior. 57308810a41SRafael J. Wysocki * 57408810a41SRafael J. Wysocki * These flags can be set by device drivers at the probe time. They need not be 57508810a41SRafael J. Wysocki * cleared by the drivers as the driver core will take care of that. 57608810a41SRafael J. Wysocki * 577e0751556SRafael J. Wysocki * NO_DIRECT_COMPLETE: Do not apply direct-complete optimization to the device. 5782fff3f73SRafael J. Wysocki * SMART_PREPARE: Take the driver ->prepare callback return value into account. 5792fff3f73SRafael J. Wysocki * SMART_SUSPEND: Avoid resuming the device from runtime suspend. 5802fff3f73SRafael J. Wysocki * MAY_SKIP_RESUME: Allow driver "noirq" and "early" callbacks to be skipped. 58108810a41SRafael J. Wysocki * 5822fff3f73SRafael J. Wysocki * See Documentation/driver-api/pm/devices.rst for details. 58308810a41SRafael J. Wysocki */ 584e0751556SRafael J. Wysocki #define DPM_FLAG_NO_DIRECT_COMPLETE BIT(0) 58508810a41SRafael J. Wysocki #define DPM_FLAG_SMART_PREPARE BIT(1) 5860eab11c9SRafael J. Wysocki #define DPM_FLAG_SMART_SUSPEND BIT(2) 5872a3f3475SRafael J. Wysocki #define DPM_FLAG_MAY_SKIP_RESUME BIT(3) 58808810a41SRafael J. Wysocki 5891eede070SRafael J. Wysocki struct dev_pm_info { 5901eede070SRafael J. Wysocki pm_message_t power_state; 5915e928f77SRafael J. Wysocki unsigned int can_wakeup:1; 592b8c76f6aSRafael J. Wysocki unsigned int async_suspend:1; 5939ed98953SRafael J. Wysocki bool in_dpm_list:1; /* Owned by the PM core */ 594f76b168bSAlan Stern bool is_prepared:1; /* Owned by the PM core */ 5956d0e0e84SAlan Stern bool is_suspended:1; /* Ditto */ 5963d2699bcSLiu, Chuansheng bool is_noirq_suspended:1; 5973d2699bcSLiu, Chuansheng bool is_late_suspended:1; 59885945c28SSudeep Holla bool no_pm:1; 599bed2b42dSRafael J. Wysocki bool early_init:1; /* Owned by the PM core */ 600aae4518bSRafael J. Wysocki bool direct_complete:1; /* Owned by the PM core */ 60108810a41SRafael J. Wysocki u32 driver_flags; 602074037ecSRafael J. Wysocki spinlock_t lock; 6031eede070SRafael J. Wysocki #ifdef CONFIG_PM_SLEEP 6041eede070SRafael J. Wysocki struct list_head entry; 6055af84b82SRafael J. Wysocki struct completion completion; 606074037ecSRafael J. Wysocki struct wakeup_source *wakeup; 6074ca46ff3SRafael J. Wysocki bool wakeup_path:1; 608feb70af0SRafael J. Wysocki bool syscore:1; 609aa8e54b5STomeu Vizoso bool no_pm_callbacks:1; /* Owned by the PM core */ 6100d4b54c6SRafael J. Wysocki unsigned int must_resume:1; /* Owned by the PM core */ 6110d4b54c6SRafael J. Wysocki unsigned int may_skip_resume:1; /* Set by subsystems */ 612805bdaecSRafael J. Wysocki #else 613805bdaecSRafael J. Wysocki unsigned int should_wakeup:1; 6141eede070SRafael J. Wysocki #endif 615d30d819dSRafael J. Wysocki #ifdef CONFIG_PM 6168234f673SVincent Guittot struct hrtimer suspend_timer; 6176b61d49aSGrygorii Strashko u64 timer_expires; 6185e928f77SRafael J. Wysocki struct work_struct work; 6195e928f77SRafael J. Wysocki wait_queue_head_t wait_queue; 6204990d4feSTony Lindgren struct wake_irq *wakeirq; 6215e928f77SRafael J. Wysocki atomic_t usage_count; 6225e928f77SRafael J. Wysocki atomic_t child_count; 6235e928f77SRafael J. Wysocki unsigned int disable_depth:3; 6245e928f77SRafael J. Wysocki unsigned int idle_notification:1; 6255e928f77SRafael J. Wysocki unsigned int request_pending:1; 6265e928f77SRafael J. Wysocki unsigned int deferred_resume:1; 627c745253eSTony Lindgren unsigned int needs_force_resume:1; 62853823639SRafael J. Wysocki unsigned int runtime_auto:1; 629372a12edSUlf Hansson bool ignore_children:1; 6307490e442SAlan Stern unsigned int no_callbacks:1; 631c7b61de5SAlan Stern unsigned int irq_safe:1; 63215bcb91dSAlan Stern unsigned int use_autosuspend:1; 63315bcb91dSAlan Stern unsigned int timer_autosuspends:1; 634e823407fSMing Lei unsigned int memalloc_noio:1; 635baa8809fSRafael J. Wysocki unsigned int links_count; 6365e928f77SRafael J. Wysocki enum rpm_request request; 6375e928f77SRafael J. Wysocki enum rpm_status runtime_status; 638*c24efa67SRafael J. Wysocki enum rpm_status last_status; 6395e928f77SRafael J. Wysocki int runtime_error; 64015bcb91dSAlan Stern int autosuspend_delay; 6418234f673SVincent Guittot u64 last_busy; 642a08c2a5aSThara Gopinath u64 active_time; 643a08c2a5aSThara Gopinath u64 suspended_time; 644a08c2a5aSThara Gopinath u64 accounting_timestamp; 6455e928f77SRafael J. Wysocki #endif 6465c095a0eSRafael J. Wysocki struct pm_subsys_data *subsys_data; /* Owned by the subsystem. */ 6472d984ad1SRafael J. Wysocki void (*set_latency_tolerance)(struct device *, s32); 6485f986c59SRafael J. Wysocki struct dev_pm_qos *qos; 6491eede070SRafael J. Wysocki }; 6501eede070SRafael J. Wysocki 651ef27bed1SRafael J. Wysocki extern int dev_pm_get_subsys_data(struct device *dev); 6521e95e3b2SUlf Hansson extern void dev_pm_put_subsys_data(struct device *dev); 6538d4b9d1bSArjan van de Ven 6544d29b2e5SRafael J. Wysocki /** 6554d29b2e5SRafael J. Wysocki * struct dev_pm_domain - power management domain representation. 656e90d5532SRafael J. Wysocki * 6574d29b2e5SRafael J. Wysocki * @ops: Power management operations associated with this domain. 658ca765a8cSUlf Hansson * @start: Called when a user needs to start the device via the domain. 659e90d5532SRafael J. Wysocki * @detach: Called when removing a device from the domain. 660e90d5532SRafael J. Wysocki * @activate: Called before executing probe routines for bus types and drivers. 661e90d5532SRafael J. Wysocki * @sync: Called after successful driver probe. 662e90d5532SRafael J. Wysocki * @dismiss: Called after unsuccessful driver probe and after driver removal. 6634d29b2e5SRafael J. Wysocki * 6644d29b2e5SRafael J. Wysocki * Power domains provide callbacks that are executed during system suspend, 6654d29b2e5SRafael J. Wysocki * hibernation, system resume and during runtime PM transitions instead of 6664d29b2e5SRafael J. Wysocki * subsystem-level and driver-level callbacks. 6677538e3dbSRafael J. Wysocki */ 668564b905aSRafael J. Wysocki struct dev_pm_domain { 6697538e3dbSRafael J. Wysocki struct dev_pm_ops ops; 670ca765a8cSUlf Hansson int (*start)(struct device *dev); 671c3099a52SUlf Hansson void (*detach)(struct device *dev, bool power_off); 672e90d5532SRafael J. Wysocki int (*activate)(struct device *dev); 673e90d5532SRafael J. Wysocki void (*sync)(struct device *dev); 674e90d5532SRafael J. Wysocki void (*dismiss)(struct device *dev); 6757538e3dbSRafael J. Wysocki }; 6768d4b9d1bSArjan van de Ven 6771eede070SRafael J. Wysocki /* 6781eede070SRafael J. Wysocki * The PM_EVENT_ messages are also used by drivers implementing the legacy 6791eede070SRafael J. Wysocki * suspend framework, based on the ->suspend() and ->resume() callbacks common 6801eede070SRafael J. Wysocki * for suspend and hibernation transitions, according to the rules below. 6811eede070SRafael J. Wysocki */ 6821eede070SRafael J. Wysocki 6831eede070SRafael J. Wysocki /* Necessary, because several drivers use PM_EVENT_PRETHAW */ 6841eede070SRafael J. Wysocki #define PM_EVENT_PRETHAW PM_EVENT_QUIESCE 6851eede070SRafael J. Wysocki 6861eede070SRafael J. Wysocki /* 68782bb67f2SDavid Brownell * One transition is triggered by resume(), after a suspend() call; the 68882bb67f2SDavid Brownell * message is implicit: 68982bb67f2SDavid Brownell * 69082bb67f2SDavid Brownell * ON Driver starts working again, responding to hardware events 69182bb67f2SDavid Brownell * and software requests. The hardware may have gone through 69282bb67f2SDavid Brownell * a power-off reset, or it may have maintained state from the 69382bb67f2SDavid Brownell * previous suspend() which the driver will rely on while 69482bb67f2SDavid Brownell * resuming. On most platforms, there are no restrictions on 69582bb67f2SDavid Brownell * availability of resources like clocks during resume(). 69682bb67f2SDavid Brownell * 69782bb67f2SDavid Brownell * Other transitions are triggered by messages sent using suspend(). All 69882bb67f2SDavid Brownell * these transitions quiesce the driver, so that I/O queues are inactive. 69982bb67f2SDavid Brownell * That commonly entails turning off IRQs and DMA; there may be rules 70082bb67f2SDavid Brownell * about how to quiesce that are specific to the bus or the device's type. 70182bb67f2SDavid Brownell * (For example, network drivers mark the link state.) Other details may 70282bb67f2SDavid Brownell * differ according to the message: 70382bb67f2SDavid Brownell * 70482bb67f2SDavid Brownell * SUSPEND Quiesce, enter a low power device state appropriate for 70582bb67f2SDavid Brownell * the upcoming system state (such as PCI_D3hot), and enable 70682bb67f2SDavid Brownell * wakeup events as appropriate. 70782bb67f2SDavid Brownell * 7083a2d5b70SRafael J. Wysocki * HIBERNATE Enter a low power device state appropriate for the hibernation 7093a2d5b70SRafael J. Wysocki * state (eg. ACPI S4) and enable wakeup events as appropriate. 7103a2d5b70SRafael J. Wysocki * 71182bb67f2SDavid Brownell * FREEZE Quiesce operations so that a consistent image can be saved; 71282bb67f2SDavid Brownell * but do NOT otherwise enter a low power device state, and do 71382bb67f2SDavid Brownell * NOT emit system wakeup events. 71482bb67f2SDavid Brownell * 71582bb67f2SDavid Brownell * PRETHAW Quiesce as if for FREEZE; additionally, prepare for restoring 71682bb67f2SDavid Brownell * the system from a snapshot taken after an earlier FREEZE. 71782bb67f2SDavid Brownell * Some drivers will need to reset their hardware state instead 71882bb67f2SDavid Brownell * of preserving it, to ensure that it's never mistaken for the 71982bb67f2SDavid Brownell * state which that earlier snapshot had set up. 72082bb67f2SDavid Brownell * 72182bb67f2SDavid Brownell * A minimally power-aware driver treats all messages as SUSPEND, fully 72282bb67f2SDavid Brownell * reinitializes its device during resume() -- whether or not it was reset 72382bb67f2SDavid Brownell * during the suspend/resume cycle -- and can't issue wakeup events. 72482bb67f2SDavid Brownell * 72582bb67f2SDavid Brownell * More power-aware drivers may also use low power states at runtime as 72682bb67f2SDavid Brownell * well as during system sleep states like PM_SUSPEND_STANDBY. They may 72782bb67f2SDavid Brownell * be able to use wakeup events to exit from runtime low-power states, 72882bb67f2SDavid Brownell * or from system low-power states such as standby or suspend-to-RAM. 7291da177e4SLinus Torvalds */ 7301da177e4SLinus Torvalds 731296699deSRafael J. Wysocki #ifdef CONFIG_PM_SLEEP 732d47d81c0SRafael J. Wysocki extern void device_pm_lock(void); 733cf579dfbSRafael J. Wysocki extern void dpm_resume_start(pm_message_t state); 734d1616302SAlan Stern extern void dpm_resume_end(pm_message_t state); 7352a8a8ce6SRafael J. Wysocki extern void dpm_resume_noirq(pm_message_t state); 7362a8a8ce6SRafael J. Wysocki extern void dpm_resume_early(pm_message_t state); 73791e7c75bSRafael J. Wysocki extern void dpm_resume(pm_message_t state); 73891e7c75bSRafael J. Wysocki extern void dpm_complete(pm_message_t state); 7391da177e4SLinus Torvalds 7401eede070SRafael J. Wysocki extern void device_pm_unlock(void); 741cf579dfbSRafael J. Wysocki extern int dpm_suspend_end(pm_message_t state); 742d1616302SAlan Stern extern int dpm_suspend_start(pm_message_t state); 7432a8a8ce6SRafael J. Wysocki extern int dpm_suspend_noirq(pm_message_t state); 7442a8a8ce6SRafael J. Wysocki extern int dpm_suspend_late(pm_message_t state); 74591e7c75bSRafael J. Wysocki extern int dpm_suspend(pm_message_t state); 74691e7c75bSRafael J. Wysocki extern int dpm_prepare(pm_message_t state); 7470ac85241SDavid Brownell 74802669492SAndrew Morton extern void __suspend_report_result(const char *function, void *fn, int ret); 74902669492SAndrew Morton 75002669492SAndrew Morton #define suspend_report_result(fn, ret) \ 75102669492SAndrew Morton do { \ 752d5c003b4SHarvey Harrison __suspend_report_result(__func__, fn, ret); \ 75302669492SAndrew Morton } while (0) 7549a7834d0SAndrew Morton 755098dff73SRafael J. Wysocki extern int device_pm_wait_for_dev(struct device *sub, struct device *dev); 756dfe3212eSMing Lei extern void dpm_for_each_dev(void *data, void (*fn)(struct device *, void *)); 7576538df80SRafael J. Wysocki 7586538df80SRafael J. Wysocki extern int pm_generic_prepare(struct device *dev); 759e470d066SRafael J. Wysocki extern int pm_generic_suspend_late(struct device *dev); 760e5291928SRafael J. Wysocki extern int pm_generic_suspend_noirq(struct device *dev); 7616538df80SRafael J. Wysocki extern int pm_generic_suspend(struct device *dev); 762e470d066SRafael J. Wysocki extern int pm_generic_resume_early(struct device *dev); 763e5291928SRafael J. Wysocki extern int pm_generic_resume_noirq(struct device *dev); 7646538df80SRafael J. Wysocki extern int pm_generic_resume(struct device *dev); 765e5291928SRafael J. Wysocki extern int pm_generic_freeze_noirq(struct device *dev); 766e470d066SRafael J. Wysocki extern int pm_generic_freeze_late(struct device *dev); 7676538df80SRafael J. Wysocki extern int pm_generic_freeze(struct device *dev); 768e5291928SRafael J. Wysocki extern int pm_generic_thaw_noirq(struct device *dev); 769e470d066SRafael J. Wysocki extern int pm_generic_thaw_early(struct device *dev); 7706538df80SRafael J. Wysocki extern int pm_generic_thaw(struct device *dev); 771e5291928SRafael J. Wysocki extern int pm_generic_restore_noirq(struct device *dev); 772e470d066SRafael J. Wysocki extern int pm_generic_restore_early(struct device *dev); 7736538df80SRafael J. Wysocki extern int pm_generic_restore(struct device *dev); 774e5291928SRafael J. Wysocki extern int pm_generic_poweroff_noirq(struct device *dev); 775e470d066SRafael J. Wysocki extern int pm_generic_poweroff_late(struct device *dev); 7766538df80SRafael J. Wysocki extern int pm_generic_poweroff(struct device *dev); 7776538df80SRafael J. Wysocki extern void pm_generic_complete(struct device *dev); 7786538df80SRafael J. Wysocki 77976c70cb5SRafael J. Wysocki extern bool dev_pm_skip_resume(struct device *dev); 780fa2bfeadSRafael J. Wysocki extern bool dev_pm_skip_suspend(struct device *dev); 781c4b65157SRafael J. Wysocki 782d288e47cSAlan Stern #else /* !CONFIG_PM_SLEEP */ 783d288e47cSAlan Stern 784ffa6a705SCornelia Huck #define device_pm_lock() do {} while (0) 785ffa6a705SCornelia Huck #define device_pm_unlock() do {} while (0) 786ffa6a705SCornelia Huck 787d1616302SAlan Stern static inline int dpm_suspend_start(pm_message_t state) 788d288e47cSAlan Stern { 789d288e47cSAlan Stern return 0; 790d288e47cSAlan Stern } 791d288e47cSAlan Stern 792d288e47cSAlan Stern #define suspend_report_result(fn, ret) do {} while (0) 793d288e47cSAlan Stern 794098dff73SRafael J. Wysocki static inline int device_pm_wait_for_dev(struct device *a, struct device *b) 795098dff73SRafael J. Wysocki { 796098dff73SRafael J. Wysocki return 0; 797098dff73SRafael J. Wysocki } 7986538df80SRafael J. Wysocki 799dfe3212eSMing Lei static inline void dpm_for_each_dev(void *data, void (*fn)(struct device *, void *)) 800dfe3212eSMing Lei { 801dfe3212eSMing Lei } 802dfe3212eSMing Lei 8036538df80SRafael J. Wysocki #define pm_generic_prepare NULL 8040a9efc4dSUlf Hansson #define pm_generic_suspend_late NULL 8050a9efc4dSUlf Hansson #define pm_generic_suspend_noirq NULL 8066538df80SRafael J. Wysocki #define pm_generic_suspend NULL 8070a9efc4dSUlf Hansson #define pm_generic_resume_early NULL 8080a9efc4dSUlf Hansson #define pm_generic_resume_noirq NULL 8096538df80SRafael J. Wysocki #define pm_generic_resume NULL 8100a9efc4dSUlf Hansson #define pm_generic_freeze_noirq NULL 8110a9efc4dSUlf Hansson #define pm_generic_freeze_late NULL 8126538df80SRafael J. Wysocki #define pm_generic_freeze NULL 8130a9efc4dSUlf Hansson #define pm_generic_thaw_noirq NULL 8140a9efc4dSUlf Hansson #define pm_generic_thaw_early NULL 8156538df80SRafael J. Wysocki #define pm_generic_thaw NULL 8160a9efc4dSUlf Hansson #define pm_generic_restore_noirq NULL 8170a9efc4dSUlf Hansson #define pm_generic_restore_early NULL 8186538df80SRafael J. Wysocki #define pm_generic_restore NULL 8190a9efc4dSUlf Hansson #define pm_generic_poweroff_noirq NULL 8200a9efc4dSUlf Hansson #define pm_generic_poweroff_late NULL 8216538df80SRafael J. Wysocki #define pm_generic_poweroff NULL 8226538df80SRafael J. Wysocki #define pm_generic_complete NULL 823d288e47cSAlan Stern #endif /* !CONFIG_PM_SLEEP */ 8240ac85241SDavid Brownell 825ffa6a705SCornelia Huck /* How to reorder dpm_list after device_move() */ 826ffa6a705SCornelia Huck enum dpm_order { 827ffa6a705SCornelia Huck DPM_ORDER_NONE, 828ffa6a705SCornelia Huck DPM_ORDER_DEV_AFTER_PARENT, 829ffa6a705SCornelia Huck DPM_ORDER_PARENT_BEFORE_DEV, 830ffa6a705SCornelia Huck DPM_ORDER_DEV_LAST, 831ffa6a705SCornelia Huck }; 832ffa6a705SCornelia Huck 8331da177e4SLinus Torvalds #endif /* _LINUX_PM_H */ 834