sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}(hhparenthuba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget$/translations/zh_CN/power/runtime_pmmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}(hhhh2ubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/zh_TW/power/runtime_pmmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}(hhhhFubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/it_IT/power/runtime_pmmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}(hhhhZubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/ja_JP/power/runtime_pmmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}(hhhhnubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/ko_KR/power/runtime_pmmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}(hhhhubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/sp_SP/power/runtime_pmmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhsection)}(hhh](htitle)}(h2Runtime Power Management Framework for I/O Devicesh]h2Runtime Power Management Framework for I/O Devices}(hhhhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhh>/var/lib/git/docbuild/linux/Documentation/power/runtime_pm.rsthKubhenumerated_list)}(hhh]h list_item)}(h72009-2011 Rafael J. Wysocki , Novell Inc. h]h paragraph)}(h62009-2011 Rafael J. Wysocki , Novell Inc.h](h2009-2011 Rafael J. Wysocki <}(h2009-2011 Rafael J. Wysocki , Novell Inc.}(h>, Novell Inc.hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubah}(h]h ]h"]h$]h&]enumtype upperalphaprefix(suffix)startKuh1hhhhhhhhKubh)}(hhh]h)}(h,2010 Alan Stern h]h)}(h+2010 Alan Stern h](h2010 Alan Stern <}(h2010 Alan Stern }(h>hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubah}(h]h ]h"]h$]h&]hhhhhhhKuh1hhhhhhhhKubh)}(hhh]h)}(hA2014 Intel Corp., Rafael J. Wysocki h]h)}(h@2014 Intel Corp., Rafael J. Wysocki h](h%2014 Intel Corp., Rafael J. Wysocki <}(h%2014 Intel Corp., Rafael J. Wysocki }(hj!hj;hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hj7ubah}(h]h ]h"]h$]h&]uh1hhj4hhhhhNubah}(h]h ]h"]h$]h&]hhhhhhhKuh1hhhhhhhhK ubh)}(hhh](h)}(h1. Introductionh]h1. Introduction}(hjohjmhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjjhhhhhK ubh)}(hSupport for runtime power management (runtime PM) of I/O devices is provided at the power management core (PM core) level by means of:h]hSupport for runtime power management (runtime PM) of I/O devices is provided at the power management core (PM core) level by means of:}(hj}hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjjhhubh bullet_list)}(hhh](h)}(hXThe power management workqueue pm_wq in which bus types and device drivers can put their PM-related work items. It is strongly recommended that pm_wq be used for queuing all work items related to runtime PM, because this allows them to be synchronized with system-wide power transitions (suspend to RAM, hibernation and resume from system sleep states). pm_wq is declared in include/linux/pm_runtime.h and defined in kernel/power/main.c. h]h)}(hXThe power management workqueue pm_wq in which bus types and device drivers can put their PM-related work items. It is strongly recommended that pm_wq be used for queuing all work items related to runtime PM, because this allows them to be synchronized with system-wide power transitions (suspend to RAM, hibernation and resume from system sleep states). pm_wq is declared in include/linux/pm_runtime.h and defined in kernel/power/main.c.h]hXThe power management workqueue pm_wq in which bus types and device drivers can put their PM-related work items. It is strongly recommended that pm_wq be used for queuing all work items related to runtime PM, because this allows them to be synchronized with system-wide power transitions (suspend to RAM, hibernation and resume from system sleep states). pm_wq is declared in include/linux/pm_runtime.h and defined in kernel/power/main.c.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjhhhhhNubh)}(hA number of runtime PM fields in the 'power' member of 'struct device' (which is of the type 'struct dev_pm_info', defined in include/linux/pm.h) that can be used for synchronizing runtime PM operations with one another. h]h)}(hA number of runtime PM fields in the 'power' member of 'struct device' (which is of the type 'struct dev_pm_info', defined in include/linux/pm.h) that can be used for synchronizing runtime PM operations with one another.h]hA number of runtime PM fields in the ‘power’ member of ‘struct device’ (which is of the type ‘struct dev_pm_info’, defined in include/linux/pm.h) that can be used for synchronizing runtime PM operations with one another.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjhhhhhNubh)}(hZThree device runtime PM callbacks in 'struct dev_pm_ops' (defined in include/linux/pm.h). h]h)}(hYThree device runtime PM callbacks in 'struct dev_pm_ops' (defined in include/linux/pm.h).h]h]Three device runtime PM callbacks in ‘struct dev_pm_ops’ (defined in include/linux/pm.h).}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjhhhhhNubh)}(hXA set of helper functions defined in drivers/base/power/runtime.c that can be used for carrying out runtime PM operations in such a way that the synchronization between them is taken care of by the PM core. Bus types and device drivers are encouraged to use these functions. h]h)}(hXA set of helper functions defined in drivers/base/power/runtime.c that can be used for carrying out runtime PM operations in such a way that the synchronization between them is taken care of by the PM core. Bus types and device drivers are encouraged to use these functions.h]hXA set of helper functions defined in drivers/base/power/runtime.c that can be used for carrying out runtime PM operations in such a way that the synchronization between them is taken care of by the PM core. Bus types and device drivers are encouraged to use these functions.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjhhhhhNubeh}(h]h ]h"]h$]h&]bullet*uh1jhhhKhjjhhubh)}(hThe runtime PM callbacks present in 'struct dev_pm_ops', the device runtime PM fields of 'struct dev_pm_info' and the core helper functions provided for runtime PM are described below.h]hThe runtime PM callbacks present in ‘struct dev_pm_ops’, the device runtime PM fields of ‘struct dev_pm_info’ and the core helper functions provided for runtime PM are described below.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK$hjjhhubeh}(h] introductionah ]h"]1. introductionah$]h&]uh1hhhhhhhhK ubh)}(hhh](h)}(h2. Device Runtime PM Callbacksh]h2. Device Runtime PM Callbacks}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhK)ubh)}(hLThere are three device runtime PM callbacks defined in 'struct dev_pm_ops'::h]hOThere are three device runtime PM callbacks defined in ‘struct dev_pm_ops’:}(hKThere are three device runtime PM callbacks defined in 'struct dev_pm_ops':hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK+hj hhubh literal_block)}(hstruct dev_pm_ops { ... int (*runtime_suspend)(struct device *dev); int (*runtime_resume)(struct device *dev); int (*runtime_idle)(struct device *dev); ... };h]hstruct dev_pm_ops { ... int (*runtime_suspend)(struct device *dev); int (*runtime_resume)(struct device *dev); int (*runtime_idle)(struct device *dev); ... };}(hhhj.ubah}(h]h ]h"]h$]h&] xml:spacepreserveuh1j,hhhK-hj hhubh)}(hThe ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks are executed by the PM core for the device's subsystem that may be either of the following:h]hThe ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks are executed by the PM core for the device’s subsystem that may be either of the following:}(hj@hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK5hj hhubh block_quote)}(hhh]h)}(hhh](h)}(hWPM domain of the device, if the device's PM domain object, dev->pm_domain, is present. h]h)}(hVPM domain of the device, if the device's PM domain object, dev->pm_domain, is present.h]hXPM domain of the device, if the device’s PM domain object, dev->pm_domain, is present.}(hjZhjXhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK9hjTubah}(h]h ]h"]h$]h&]uh1hhjQubh)}(hLDevice type of the device, if both dev->type and dev->type->pm are present. h]h)}(hKDevice type of the device, if both dev->type and dev->type->pm are present.h]hKDevice type of the device, if both dev->type and dev->type->pm are present.}(hjrhjphhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKclass and dev->class->pm are present. h]h)}(hNDevice class of the device, if both dev->class and dev->class->pm are present.h]hNDevice class of the device, if both dev->class and dev->class->pm are present.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK>hjubah}(h]h ]h"]h$]h&]uh1hhjQubh)}(hGBus type of the device, if both dev->bus and dev->bus->pm are present. h]h)}(hFBus type of the device, if both dev->bus and dev->bus->pm are present.h]hFBus type of the device, if both dev->bus and dev->bus->pm are present.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKAhjubah}(h]h ]h"]h$]h&]uh1hhjQubeh}(h]h ]h"]h$]h&]harabichhh.uh1hhjNubah}(h]h ]h"]h$]h&]uh1jLhj hhhNhNubh)}(hIf the subsystem chosen by applying the above rules doesn't provide the relevant callback, the PM core will invoke the corresponding driver callback stored in dev->driver->pm directly (if present).h]hIf the subsystem chosen by applying the above rules doesn’t provide the relevant callback, the PM core will invoke the corresponding driver callback stored in dev->driver->pm directly (if present).}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKChj hhubh)}(hX{The PM core always checks which callback to use in the order given above, so the priority order of callbacks from high to low is: PM domain, device type, class and bus type. Moreover, the high-priority one will always take precedence over a low-priority one. The PM domain, bus type, device type and class callbacks are referred to as subsystem-level callbacks in what follows.h]hX{The PM core always checks which callback to use in the order given above, so the priority order of callbacks from high to low is: PM domain, device type, class and bus type. Moreover, the high-priority one will always take precedence over a low-priority one. The PM domain, bus type, device type and class callbacks are referred to as subsystem-level callbacks in what follows.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKGhj hhubh)}(hXOBy default, the callbacks are always invoked in process context with interrupts enabled. However, the pm_runtime_irq_safe() helper function can be used to tell the PM core that it is safe to run the ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks for the given device in atomic context with interrupts disabled. This implies that the callback routines in question must not block or sleep, but it also means that the synchronous helper functions listed at the end of Section 4 may be used for that device within an interrupt handler or generally in an atomic context.h]hXOBy default, the callbacks are always invoked in process context with interrupts enabled. However, the pm_runtime_irq_safe() helper function can be used to tell the PM core that it is safe to run the ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks for the given device in atomic context with interrupts disabled. This implies that the callback routines in question must not block or sleep, but it also means that the synchronous helper functions listed at the end of Section 4 may be used for that device within an interrupt handler or generally in an atomic context.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKMhj hhubh)}(hXThe subsystem-level suspend callback, if present, is _entirely_ _responsible_ for handling the suspend of the device as appropriate, which may, but need not include executing the device driver's own ->runtime_suspend() callback (from the PM core's point of view it is not necessary to implement a ->runtime_suspend() callback in a device driver as long as the subsystem-level suspend callback knows what to do to handle the device).h]hXThe subsystem-level suspend callback, if present, is _entirely_ _responsible_ for handling the suspend of the device as appropriate, which may, but need not include executing the device driver’s own ->runtime_suspend() callback (from the PM core’s point of view it is not necessary to implement a ->runtime_suspend() callback in a device driver as long as the subsystem-level suspend callback knows what to do to handle the device).}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKVhj hhubjM)}(hhh]j)}(hhh](h)}(hXOnce the subsystem-level suspend callback (or the driver suspend callback, if invoked directly) has completed successfully for the given device, the PM core regards the device as suspended, which need not mean that it has been put into a low power state. It is supposed to mean, however, that the device will not process data and will not communicate with the CPU(s) and RAM until the appropriate resume callback is executed for it. The runtime PM status of a device after successful execution of the suspend callback is 'suspended'. h]h)}(hXOnce the subsystem-level suspend callback (or the driver suspend callback, if invoked directly) has completed successfully for the given device, the PM core regards the device as suspended, which need not mean that it has been put into a low power state. It is supposed to mean, however, that the device will not process data and will not communicate with the CPU(s) and RAM until the appropriate resume callback is executed for it. The runtime PM status of a device after successful execution of the suspend callback is 'suspended'.h]hXOnce the subsystem-level suspend callback (or the driver suspend callback, if invoked directly) has completed successfully for the given device, the PM core regards the device as suspended, which need not mean that it has been put into a low power state. It is supposed to mean, however, that the device will not process data and will not communicate with the CPU(s) and RAM until the appropriate resume callback is executed for it. The runtime PM status of a device after successful execution of the suspend callback is ‘suspended’.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK]hjubah}(h]h ]h"]h$]h&]uh1hhjubh)}(hIf the suspend callback returns -EBUSY or -EAGAIN, the device's runtime PM status remains 'active', which means that the device _must_ be fully operational afterwards. h]h)}(hIf the suspend callback returns -EBUSY or -EAGAIN, the device's runtime PM status remains 'active', which means that the device _must_ be fully operational afterwards.h]hIf the suspend callback returns -EBUSY or -EAGAIN, the device’s runtime PM status remains ‘active’, which means that the device _must_ be fully operational afterwards.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKfhjubah}(h]h ]h"]h$]h&]uh1hhjubh)}(hXTIf the suspend callback returns an error code different from -EBUSY and -EAGAIN, the PM core regards this as a fatal error and will refuse to run the helper functions described in Section 4 for the device until its status is directly set to either 'active', or 'suspended' (the PM core provides special helper functions for this purpose). h]h)}(hXSIf the suspend callback returns an error code different from -EBUSY and -EAGAIN, the PM core regards this as a fatal error and will refuse to run the helper functions described in Section 4 for the device until its status is directly set to either 'active', or 'suspended' (the PM core provides special helper functions for this purpose).h]hX[If the suspend callback returns an error code different from -EBUSY and -EAGAIN, the PM core regards this as a fatal error and will refuse to run the helper functions described in Section 4 for the device until its status is directly set to either ‘active’, or ‘suspended’ (the PM core provides special helper functions for this purpose).}(hj6hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKjhj0ubah}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]jjuh1jhhhK]hjubah}(h]h ]h"]h$]h&]uh1jLhj hhhNhNubh)}(hXqIn particular, if the driver requires remote wakeup capability (i.e. hardware mechanism allowing the device to request a change of its power state, such as PCI PME) for proper functioning and device_can_wakeup() returns 'false' for the device, then ->runtime_suspend() should return -EBUSY. On the other hand, if device_can_wakeup() returns 'true' for the device and the device is put into a low-power state during the execution of the suspend callback, it is expected that remote wakeup will be enabled for the device. Generally, remote wakeup should be enabled for all input devices put into low-power states at run time.h]hXyIn particular, if the driver requires remote wakeup capability (i.e. hardware mechanism allowing the device to request a change of its power state, such as PCI PME) for proper functioning and device_can_wakeup() returns ‘false’ for the device, then ->runtime_suspend() should return -EBUSY. On the other hand, if device_can_wakeup() returns ‘true’ for the device and the device is put into a low-power state during the execution of the suspend callback, it is expected that remote wakeup will be enabled for the device. Generally, remote wakeup should be enabled for all input devices put into low-power states at run time.}(hjVhjThhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKphj hhubh)}(hXThe subsystem-level resume callback, if present, is **entirely responsible** for handling the resume of the device as appropriate, which may, but need not include executing the device driver's own ->runtime_resume() callback (from the PM core's point of view it is not necessary to implement a ->runtime_resume() callback in a device driver as long as the subsystem-level resume callback knows what to do to handle the device).h](h4The subsystem-level resume callback, if present, is }(h4The subsystem-level resume callback, if present, is hjbhhhNhNubhstrong)}(h**entirely responsible**h]hentirely responsible}(hhhjmhhhNhNubah}(h]h ]h"]h$]h&]uh1jkhjbubhXc for handling the resume of the device as appropriate, which may, but need not include executing the device driver’s own ->runtime_resume() callback (from the PM core’s point of view it is not necessary to implement a ->runtime_resume() callback in a device driver as long as the subsystem-level resume callback knows what to do to handle the device).}(hX_ for handling the resume of the device as appropriate, which may, but need not include executing the device driver's own ->runtime_resume() callback (from the PM core's point of view it is not necessary to implement a ->runtime_resume() callback in a device driver as long as the subsystem-level resume callback knows what to do to handle the device).hjbhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKyhj hhubjM)}(hhh]j)}(hhh](h)}(hX7Once the subsystem-level resume callback (or the driver resume callback, if invoked directly) has completed successfully, the PM core regards the device as fully operational, which means that the device _must_ be able to complete I/O operations as needed. The runtime PM status of the device is then 'active'. h]h)}(hX6Once the subsystem-level resume callback (or the driver resume callback, if invoked directly) has completed successfully, the PM core regards the device as fully operational, which means that the device _must_ be able to complete I/O operations as needed. The runtime PM status of the device is then 'active'.h]hX:Once the subsystem-level resume callback (or the driver resume callback, if invoked directly) has completed successfully, the PM core regards the device as fully operational, which means that the device _must_ be able to complete I/O operations as needed. The runtime PM status of the device is then ‘active’.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjubh)}(hX@If the resume callback returns an error code, the PM core regards this as a fatal error and will refuse to run the helper functions described in Section 4 for the device, until its status is directly set to either 'active', or 'suspended' (by means of special helper functions provided by the PM core for this purpose). h]h)}(hX?If the resume callback returns an error code, the PM core regards this as a fatal error and will refuse to run the helper functions described in Section 4 for the device, until its status is directly set to either 'active', or 'suspended' (by means of special helper functions provided by the PM core for this purpose).h]hXGIf the resume callback returns an error code, the PM core regards this as a fatal error and will refuse to run the helper functions described in Section 4 for the device, until its status is directly set to either ‘active’, or ‘suspended’ (by means of special helper functions provided by the PM core for this purpose).}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]jjuh1jhhhKhjubah}(h]h ]h"]h$]h&]uh1jLhj hhhNhNubh)}(hX The idle callback (a subsystem-level one, if present, or the driver one) is executed by the PM core whenever the device appears to be idle, which is indicated to the PM core by two counters, the device's usage counter and the counter of 'active' children of the device.h]hXThe idle callback (a subsystem-level one, if present, or the driver one) is executed by the PM core whenever the device appears to be idle, which is indicated to the PM core by two counters, the device’s usage counter and the counter of ‘active’ children of the device.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubjM)}(hhh]j)}(hhh]h)}(hX If any of these counters is decreased using a helper function provided by the PM core and it turns out to be equal to zero, the other counter is checked. If that counter also is equal to zero, the PM core executes the idle callback with the device as its argument. h]h)}(hX If any of these counters is decreased using a helper function provided by the PM core and it turns out to be equal to zero, the other counter is checked. If that counter also is equal to zero, the PM core executes the idle callback with the device as its argument.h]hX If any of these counters is decreased using a helper function provided by the PM core and it turns out to be equal to zero, the other counter is checked. If that counter also is equal to zero, the PM core executes the idle callback with the device as its argument.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jjuh1jhhhKhjubah}(h]h ]h"]h$]h&]uh1jLhj hhhNhNubh)}(hXThe action performed by the idle callback is totally dependent on the subsystem (or driver) in question, but the expected and recommended action is to check if the device can be suspended (i.e. if all of the conditions necessary for suspending the device are satisfied) and to queue up a suspend request for the device in that case. If there is no idle callback, or if the callback returns 0, then the PM core will attempt to carry out a runtime suspend of the device, also respecting devices configured for autosuspend. In essence this means a call to __pm_runtime_autosuspend() (do note that drivers needs to update the device last busy mark, pm_runtime_mark_last_busy(), to control the delay under this circumstance). To prevent this (for example, if the callback routine has started a delayed suspend), the routine must return a non-zero value. Negative error return codes are ignored by the PM core.h]hXThe action performed by the idle callback is totally dependent on the subsystem (or driver) in question, but the expected and recommended action is to check if the device can be suspended (i.e. if all of the conditions necessary for suspending the device are satisfied) and to queue up a suspend request for the device in that case. If there is no idle callback, or if the callback returns 0, then the PM core will attempt to carry out a runtime suspend of the device, also respecting devices configured for autosuspend. In essence this means a call to __pm_runtime_autosuspend() (do note that drivers needs to update the device last busy mark, pm_runtime_mark_last_busy(), to control the delay under this circumstance). To prevent this (for example, if the callback routine has started a delayed suspend), the routine must return a non-zero value. Negative error return codes are ignored by the PM core.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(hThe helper functions provided by the PM core, described in Section 4, guarantee that the following constraints are met with respect to runtime PM callbacks for one device:h]hThe helper functions provided by the PM core, described in Section 4, guarantee that the following constraints are met with respect to runtime PM callbacks for one device:}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(hhh](h)}(hXThe callbacks are mutually exclusive (e.g. it is forbidden to execute ->runtime_suspend() in parallel with ->runtime_resume() or with another instance of ->runtime_suspend() for the same device) with the exception that ->runtime_suspend() or ->runtime_resume() can be executed in parallel with ->runtime_idle() (although ->runtime_idle() will not be started while any of the other callbacks is being executed for the same device). h]h)}(hXThe callbacks are mutually exclusive (e.g. it is forbidden to execute ->runtime_suspend() in parallel with ->runtime_resume() or with another instance of ->runtime_suspend() for the same device) with the exception that ->runtime_suspend() or ->runtime_resume() can be executed in parallel with ->runtime_idle() (although ->runtime_idle() will not be started while any of the other callbacks is being executed for the same device).h]hXThe callbacks are mutually exclusive (e.g. it is forbidden to execute ->runtime_suspend() in parallel with ->runtime_resume() or with another instance of ->runtime_suspend() for the same device) with the exception that ->runtime_suspend() or ->runtime_resume() can be executed in parallel with ->runtime_idle() (although ->runtime_idle() will not be started while any of the other callbacks is being executed for the same device).}(hj%hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjhhhhhNubh)}(h->runtime_idle() and ->runtime_suspend() can only be executed for 'active' devices (i.e. the PM core will only execute ->runtime_idle() or ->runtime_suspend() for the devices the runtime PM status of which is 'active'). h]h)}(h->runtime_idle() and ->runtime_suspend() can only be executed for 'active' devices (i.e. the PM core will only execute ->runtime_idle() or ->runtime_suspend() for the devices the runtime PM status of which is 'active').h]h->runtime_idle() and ->runtime_suspend() can only be executed for ‘active’ devices (i.e. the PM core will only execute ->runtime_idle() or ->runtime_suspend() for the devices the runtime PM status of which is ‘active’).}(hj=hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj7ubah}(h]h ]h"]h$]h&]uh1hhjhhhhhNubh)}(h->runtime_idle() and ->runtime_suspend() can only be executed for a device the usage counter of which is equal to zero _and_ either the counter of 'active' children of which is equal to zero, or the 'power.ignore_children' flag of which is set. h]h)}(h->runtime_idle() and ->runtime_suspend() can only be executed for a device the usage counter of which is equal to zero _and_ either the counter of 'active' children of which is equal to zero, or the 'power.ignore_children' flag of which is set.h]h->runtime_idle() and ->runtime_suspend() can only be executed for a device the usage counter of which is equal to zero _and_ either the counter of ‘active’ children of which is equal to zero, or the ‘power.ignore_children’ flag of which is set.}(hjUhjShhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjOubah}(h]h ]h"]h$]h&]uh1hhjhhhhhNubh)}(h->runtime_resume() can only be executed for 'suspended' devices (i.e. the PM core will only execute ->runtime_resume() for the devices the runtime PM status of which is 'suspended'). h]h)}(h->runtime_resume() can only be executed for 'suspended' devices (i.e. the PM core will only execute ->runtime_resume() for the devices the runtime PM status of which is 'suspended').h]h->runtime_resume() can only be executed for ‘suspended’ devices (i.e. the PM core will only execute ->runtime_resume() for the devices the runtime PM status of which is ‘suspended’).}(hjmhjkhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjgubah}(h]h ]h"]h$]h&]uh1hhjhhhhhNubeh}(h]h ]h"]h$]h&]hjhhhhuh1hhj hhhhhKubh)}(hTAdditionally, the helper functions provided by the PM core obey the following rules:h]hTAdditionally, the helper functions provided by the PM core obey the following rules:}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubjM)}(hhh]j)}(hhh](h)}(hIf ->runtime_suspend() is about to be executed or there's a pending request to execute it, ->runtime_idle() will not be executed for the same device. h]h)}(hIf ->runtime_suspend() is about to be executed or there's a pending request to execute it, ->runtime_idle() will not be executed for the same device.h]hIf ->runtime_suspend() is about to be executed or there’s a pending request to execute it, ->runtime_idle() will not be executed for the same device.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjubh)}(hA request to execute or to schedule the execution of ->runtime_suspend() will cancel any pending requests to execute ->runtime_idle() for the same device. h]h)}(hA request to execute or to schedule the execution of ->runtime_suspend() will cancel any pending requests to execute ->runtime_idle() for the same device.h]hA request to execute or to schedule the execution of ->runtime_suspend() will cancel any pending requests to execute ->runtime_idle() for the same device.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjubh)}(hIf ->runtime_resume() is about to be executed or there's a pending request to execute it, the other callbacks will not be executed for the same device. h]h)}(hIf ->runtime_resume() is about to be executed or there's a pending request to execute it, the other callbacks will not be executed for the same device.h]hIf ->runtime_resume() is about to be executed or there’s a pending request to execute it, the other callbacks will not be executed for the same device.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjubh)}(hA request to execute ->runtime_resume() will cancel any pending or scheduled requests to execute the other callbacks for the same device, except for scheduled autosuspends. h]h)}(hA request to execute ->runtime_resume() will cancel any pending or scheduled requests to execute the other callbacks for the same device, except for scheduled autosuspends.h]hA request to execute ->runtime_resume() will cancel any pending or scheduled requests to execute the other callbacks for the same device, except for scheduled autosuspends.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]jjuh1jhhhKhjubah}(h]h ]h"]h$]h&]uh1jLhj hhhNhNubeh}(h]device-runtime-pm-callbacksah ]h"]2. device runtime pm callbacksah$]h&]uh1hhhhhhhhK)ubh)}(hhh](h)}(h3. Runtime PM Device Fieldsh]h3. Runtime PM Device Fields}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hmThe following device runtime PM fields are present in 'struct dev_pm_info', as defined in include/linux/pm.h:h]hqThe following device runtime PM fields are present in ‘struct dev_pm_info’, as defined in include/linux/pm.h:}(hj hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubjM)}(hhh]hdefinition_list)}(hhh](hdefinition_list_item)}(hj`struct timer_list suspend_timer;` - timer used for scheduling (delayed) suspend and autosuspend requests h](hterm)}(h"`struct timer_list suspend_timer;`h]htitle_reference)}(hj>h]h struct timer_list suspend_timer;}(hhhjBhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj<ubah}(h]h ]h"]h$]h&]uh1j:hhhKhj6ubh definition)}(hhh]j)}(hhh]h)}(hEtimer used for scheduling (delayed) suspend and autosuspend requests h]h)}(hDtimer used for scheduling (delayed) suspend and autosuspend requestsh]hDtimer used for scheduling (delayed) suspend and autosuspend requests}(hjchjahhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj]ubah}(h]h ]h"]h$]h&]uh1hhjZubah}(h]h ]h"]h$]h&]j-uh1jhhhKhjWubah}(h]h ]h"]h$]h&]uh1jUhj6ubeh}(h]h ]h"]h$]h&]uh1j4hhhKhj1ubj5)}(h`unsigned long timer_expires;` - timer expiration time, in jiffies (if this is different from zero, the timer is running and will expire at that time, otherwise the timer is not running) h](j;)}(h`unsigned long timer_expires;`h]jA)}(hjh]hunsigned long timer_expires;}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhKhjubjV)}(hhh]j)}(hhh]h)}(htimer expiration time, in jiffies (if this is different from zero, the timer is running and will expire at that time, otherwise the timer is not running) h]h)}(htimer expiration time, in jiffies (if this is different from zero, the timer is running and will expire at that time, otherwise the timer is not running)h]htimer expiration time, in jiffies (if this is different from zero, the timer is running and will expire at that time, otherwise the timer is not running)}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhKhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhKhj1ubj5)}(hd`struct work_struct work;` - work structure used for queuing up requests (i.e. work items in pm_wq) h](j;)}(h`struct work_struct work;`h]jA)}(hjh]hstruct work_struct work;}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhKhjubjV)}(hhh]j)}(hhh]h)}(hGwork structure used for queuing up requests (i.e. work items in pm_wq) h]h)}(hFwork structure used for queuing up requests (i.e. work items in pm_wq)h]hFwork structure used for queuing up requests (i.e. work items in pm_wq)}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhKhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhKhj1ubj5)}(h}`wait_queue_head_t wait_queue;` - wait queue used if any of the helper functions needs to wait for another one to complete h](j;)}(h`wait_queue_head_t wait_queue;`h]jA)}(hj$h]hwait_queue_head_t wait_queue;}(hhhj&hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj"ubah}(h]h ]h"]h$]h&]uh1j:hhhKhjubjV)}(hhh]j)}(hhh]h)}(hYwait queue used if any of the helper functions needs to wait for another one to complete h]h)}(hXwait queue used if any of the helper functions needs to wait for another one to completeh]hXwait queue used if any of the helper functions needs to wait for another one to complete}(hjEhjChhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj?ubah}(h]h ]h"]h$]h&]uh1hhj<ubah}(h]h ]h"]h$]h&]jj{uh1jhhhKhj9ubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhKhj1ubj5)}(h3`spinlock_t lock;` - lock used for synchronization h](j;)}(h`spinlock_t lock;`h]jA)}(hjoh]hspinlock_t lock;}(hhhjqhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjmubah}(h]h ]h"]h$]h&]uh1j:hhhKhjiubjV)}(hhh]j)}(hhh]h)}(hlock used for synchronization h]h)}(hlock used for synchronizationh]hlock used for synchronization}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhKhjubah}(h]h ]h"]h$]h&]uh1jUhjiubeh}(h]h ]h"]h$]h&]uh1j4hhhKhj1ubj5)}(h:`atomic_t usage_count;` - the usage counter of the device h](j;)}(h`atomic_t usage_count;`h]jA)}(hjh]hatomic_t usage_count;}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhKhjubjV)}(hhh]j)}(hhh]h)}(h the usage counter of the device h]h)}(hthe usage counter of the deviceh]hthe usage counter of the device}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhKhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhKhj1ubj5)}(hG`atomic_t child_count;` - the count of 'active' children of the device h](j;)}(h`atomic_t child_count;`h]jA)}(hjh]hatomic_t child_count;}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhKhjubjV)}(hhh]j)}(hhh]h)}(h-the count of 'active' children of the device h]h)}(h,the count of 'active' children of the deviceh]h0the count of ‘active’ children of the device}(hj&hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhKhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhKhj1ubj5)}(hb`unsigned int ignore_children;` - if set, the value of child_count is ignored (but still updated) h](j;)}(h`unsigned int ignore_children;`h]jA)}(hjPh]hunsigned int ignore_children;}(hhhjRhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjNubah}(h]h ]h"]h$]h&]uh1j:hhhKhjJubjV)}(hhh]j)}(hhh]h)}(h@if set, the value of child_count is ignored (but still updated) h]h)}(h?if set, the value of child_count is ignored (but still updated)h]h?if set, the value of child_count is ignored (but still updated)}(hjqhjohhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjkubah}(h]h ]h"]h$]h&]uh1hhjhubah}(h]h ]h"]h$]h&]jj{uh1jhhhKhjeubah}(h]h ]h"]h$]h&]uh1jUhjJubeh}(h]h ]h"]h$]h&]uh1j4hhhKhj1ubj5)}(h`unsigned int disable_depth;` - used for disabling the helper functions (they work normally if this is equal to zero); the initial value of it is 1 (i.e. runtime PM is initially disabled for all devices) h](j;)}(h`unsigned int disable_depth;`h]jA)}(hjh]hunsigned int disable_depth;}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhKhjubjV)}(hhh]j)}(hhh]h)}(hused for disabling the helper functions (they work normally if this is equal to zero); the initial value of it is 1 (i.e. runtime PM is initially disabled for all devices) h]h)}(hused for disabling the helper functions (they work normally if this is equal to zero); the initial value of it is 1 (i.e. runtime PM is initially disabled for all devices)h]hused for disabling the helper functions (they work normally if this is equal to zero); the initial value of it is 1 (i.e. runtime PM is initially disabled for all devices)}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhKhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhKhj1ubj5)}(h`int runtime_error;` - if set, there was a fatal error (one of the callbacks returned error code as described in Section 2), so the helper functions will not work until this flag is cleared; this is the error code returned by the failing callback h](j;)}(h`int runtime_error;`h]jA)}(hjh]hint runtime_error;}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhKhjubjV)}(hhh]j)}(hhh]h)}(hif set, there was a fatal error (one of the callbacks returned error code as described in Section 2), so the helper functions will not work until this flag is cleared; this is the error code returned by the failing callback h]h)}(hif set, there was a fatal error (one of the callbacks returned error code as described in Section 2), so the helper functions will not work until this flag is cleared; this is the error code returned by the failing callbackh]hif set, there was a fatal error (one of the callbacks returned error code as described in Section 2), so the helper functions will not work until this flag is cleared; this is the error code returned by the failing callback}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhKhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhKhj1ubj5)}(hO`unsigned int idle_notification;` - if set, ->runtime_idle() is being executed h](j;)}(h!`unsigned int idle_notification;`h]jA)}(hj1h]hunsigned int idle_notification;}(hhhj3hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj/ubah}(h]h ]h"]h$]h&]uh1j:hhhKhj+ubjV)}(hhh]j)}(hhh]h)}(h+if set, ->runtime_idle() is being executed h]h)}(h*if set, ->runtime_idle() is being executedh]h*if set, ->runtime_idle() is being executed}(hjRhjPhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjLubah}(h]h ]h"]h$]h&]uh1hhjIubah}(h]h ]h"]h$]h&]jj{uh1jhhhKhjFubah}(h]h ]h"]h$]h&]uh1jUhj+ubeh}(h]h ]h"]h$]h&]uh1j4hhhKhj1ubj5)}(hl`unsigned int request_pending;` - if set, there's a pending request (i.e. a work item queued up into pm_wq) h](j;)}(h`unsigned int request_pending;`h]jA)}(hj|h]hunsigned int request_pending;}(hhhj~hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjzubah}(h]h ]h"]h$]h&]uh1j:hhhKhjvubjV)}(hhh]j)}(hhh]h)}(hJif set, there's a pending request (i.e. a work item queued up into pm_wq) h]h)}(hIif set, there's a pending request (i.e. a work item queued up into pm_wq)h]hKif set, there’s a pending request (i.e. a work item queued up into pm_wq)}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhKhjubah}(h]h ]h"]h$]h&]uh1jUhjvubeh}(h]h ]h"]h$]h&]uh1j4hhhKhj1ubj5)}(h_`enum rpm_request request;` - type of request that's pending (valid if request_pending is set) h](j;)}(h`enum rpm_request request;`h]jA)}(hjh]henum rpm_request request;}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(hAtype of request that's pending (valid if request_pending is set) h]h)}(h@type of request that's pending (valid if request_pending is set)h]hBtype of request that’s pending (valid if request_pending is set)}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhj1ubj5)}(h`unsigned int deferred_resume;` - set if ->runtime_resume() is about to be run while ->runtime_suspend() is being executed for that device and it is not practical to wait for the suspend to complete; means "start a resume as soon as you've suspended" h](j;)}(h`unsigned int deferred_resume;`h]jA)}(hj h]hunsigned int deferred_resume;}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj ubah}(h]h ]h"]h$]h&]uh1j:hhhMhj ubjV)}(hhh]j)}(hhh]h)}(hset if ->runtime_resume() is about to be run while ->runtime_suspend() is being executed for that device and it is not practical to wait for the suspend to complete; means "start a resume as soon as you've suspended" h]h)}(hset if ->runtime_resume() is about to be run while ->runtime_suspend() is being executed for that device and it is not practical to wait for the suspend to complete; means "start a resume as soon as you've suspended"h]hset if ->runtime_resume() is about to be run while ->runtime_suspend() is being executed for that device and it is not practical to wait for the suspend to complete; means “start a resume as soon as you’ve suspended”}(hj3 hj1 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj- ubah}(h]h ]h"]h$]h&]uh1hhj* ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhj' ubah}(h]h ]h"]h$]h&]uh1jUhj ubeh}(h]h ]h"]h$]h&]uh1j4hhhMhj1ubj5)}(h`enum rpm_status runtime_status;` - the runtime PM status of the device; this field's initial value is RPM_SUSPENDED, which means that each device is initially regarded by the PM core as 'suspended', regardless of its real hardware status h](j;)}(h!`enum rpm_status runtime_status;`h]jA)}(hj] h]henum rpm_status runtime_status;}(hhhj_ hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj[ ubah}(h]h ]h"]h$]h&]uh1j:hhhM hjW ubjV)}(hhh]j)}(hhh]h)}(hthe runtime PM status of the device; this field's initial value is RPM_SUSPENDED, which means that each device is initially regarded by the PM core as 'suspended', regardless of its real hardware status h]h)}(hthe runtime PM status of the device; this field's initial value is RPM_SUSPENDED, which means that each device is initially regarded by the PM core as 'suspended', regardless of its real hardware statush]hthe runtime PM status of the device; this field’s initial value is RPM_SUSPENDED, which means that each device is initially regarded by the PM core as ‘suspended’, regardless of its real hardware status}(hj~ hj| hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjx ubah}(h]h ]h"]h$]h&]uh1hhju ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjr ubah}(h]h ]h"]h$]h&]uh1jUhjW ubeh}(h]h ]h"]h$]h&]uh1j4hhhM hj1ubj5)}(h`enum rpm_status last_status;` - the last runtime PM status of the device captured before disabling runtime PM for it (invalid initially and when disable_depth is 0) h](j;)}(h`enum rpm_status last_status;`h]jA)}(hj h]henum rpm_status last_status;}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj ubah}(h]h ]h"]h$]h&]uh1j:hhhMhj ubjV)}(hhh]j)}(hhh]h)}(hthe last runtime PM status of the device captured before disabling runtime PM for it (invalid initially and when disable_depth is 0) h]h)}(hthe last runtime PM status of the device captured before disabling runtime PM for it (invalid initially and when disable_depth is 0)h]hthe last runtime PM status of the device captured before disabling runtime PM for it (invalid initially and when disable_depth is 0)}(hj hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hj ubah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]jj{uh1jhhhM hj ubah}(h]h ]h"]h$]h&]uh1jUhj ubeh}(h]h ]h"]h$]h&]uh1j4hhhMhj1ubj5)}(hX-`unsigned int runtime_auto;` - if set, indicates that the user space has allowed the device driver to power manage the device at run time via the /sys/devices/.../power/control `interface;` it may only be modified with the help of the pm_runtime_allow() and pm_runtime_forbid() helper functions h](j;)}(h`unsigned int runtime_auto;`h]jA)}(hj h]hunsigned int runtime_auto;}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj ubah}(h]h ]h"]h$]h&]uh1j:hhhMhj ubjV)}(hhh]j)}(hhh]h)}(hXif set, indicates that the user space has allowed the device driver to power manage the device at run time via the /sys/devices/.../power/control `interface;` it may only be modified with the help of the pm_runtime_allow() and pm_runtime_forbid() helper functions h]h)}(hXif set, indicates that the user space has allowed the device driver to power manage the device at run time via the /sys/devices/.../power/control `interface;` it may only be modified with the help of the pm_runtime_allow() and pm_runtime_forbid() helper functionsh](hif set, indicates that the user space has allowed the device driver to power manage the device at run time via the /sys/devices/.../power/control }(hif set, indicates that the user space has allowed the device driver to power manage the device at run time via the /sys/devices/.../power/control hj hhhNhNubjA)}(h `interface;`h]h interface;}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj ubhi it may only be modified with the help of the pm_runtime_allow() and pm_runtime_forbid() helper functions}(hi it may only be modified with the help of the pm_runtime_allow() and pm_runtime_forbid() helper functionshj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhj ubah}(h]h ]h"]h$]h&]uh1jUhj ubeh}(h]h ]h"]h$]h&]uh1j4hhhMhj1ubj5)}(h`unsigned int no_callbacks;` - indicates that the device does not use the runtime PM callbacks (see Section 8); it may be modified only by the pm_runtime_no_callbacks() helper function h](j;)}(h`unsigned int no_callbacks;`h]jA)}(hjR h]hunsigned int no_callbacks;}(hhhjT hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjP ubah}(h]h ]h"]h$]h&]uh1j:hhhMhjL ubjV)}(hhh]j)}(hhh]h)}(hindicates that the device does not use the runtime PM callbacks (see Section 8); it may be modified only by the pm_runtime_no_callbacks() helper function h]h)}(hindicates that the device does not use the runtime PM callbacks (see Section 8); it may be modified only by the pm_runtime_no_callbacks() helper functionh]hindicates that the device does not use the runtime PM callbacks (see Section 8); it may be modified only by the pm_runtime_no_callbacks() helper function}(hjs hjq hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjm ubah}(h]h ]h"]h$]h&]uh1hhjj ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjg ubah}(h]h ]h"]h$]h&]uh1jUhjL ubeh}(h]h ]h"]h$]h&]uh1j4hhhMhj1ubj5)}(h`unsigned int irq_safe;` - indicates that the ->runtime_suspend() and ->runtime_resume() callbacks will be invoked with the spinlock held and interrupts disabled h](j;)}(h`unsigned int irq_safe;`h]jA)}(hj h]hunsigned int irq_safe;}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj ubah}(h]h ]h"]h$]h&]uh1j:hhhMhj ubjV)}(hhh]j)}(hhh]h)}(hindicates that the ->runtime_suspend() and ->runtime_resume() callbacks will be invoked with the spinlock held and interrupts disabled h]h)}(hindicates that the ->runtime_suspend() and ->runtime_resume() callbacks will be invoked with the spinlock held and interrupts disabledh]hindicates that the ->runtime_suspend() and ->runtime_resume() callbacks will be invoked with the spinlock held and interrupts disabled}(hj hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhj ubah}(h]h ]h"]h$]h&]uh1jUhj ubeh}(h]h ]h"]h$]h&]uh1j4hhhMhj1ubj5)}(h`unsigned int use_autosuspend;` - indicates that the device's driver supports delayed autosuspend (see Section 9); it may be modified only by the pm_runtime{_dont}_use_autosuspend() helper functions h](j;)}(h`unsigned int use_autosuspend;`h]jA)}(hj h]hunsigned int use_autosuspend;}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj ubah}(h]h ]h"]h$]h&]uh1j:hhhM"hj ubjV)}(hhh]j)}(hhh]h)}(hindicates that the device's driver supports delayed autosuspend (see Section 9); it may be modified only by the pm_runtime{_dont}_use_autosuspend() helper functions h]h)}(hindicates that the device's driver supports delayed autosuspend (see Section 9); it may be modified only by the pm_runtime{_dont}_use_autosuspend() helper functionsh]hindicates that the device’s driver supports delayed autosuspend (see Section 9); it may be modified only by the pm_runtime{_dont}_use_autosuspend() helper functions}(hj hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hj ubah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]jj{uh1jhhhM hj ubah}(h]h ]h"]h$]h&]uh1jUhj ubeh}(h]h ]h"]h$]h&]uh1j4hhhM"hj1ubj5)}(h`unsigned int timer_autosuspends;` - indicates that the PM core should attempt to carry out an autosuspend when the timer expires rather than a normal suspend h](j;)}(h"`unsigned int timer_autosuspends;`h]jA)}(hj3 h]h unsigned int timer_autosuspends;}(hhhj5 hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj1 ubah}(h]h ]h"]h$]h&]uh1j:hhhM&hj- ubjV)}(hhh]j)}(hhh]h)}(hzindicates that the PM core should attempt to carry out an autosuspend when the timer expires rather than a normal suspend h]h)}(hyindicates that the PM core should attempt to carry out an autosuspend when the timer expires rather than a normal suspendh]hyindicates that the PM core should attempt to carry out an autosuspend when the timer expires rather than a normal suspend}(hjT hjR hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM%hjN ubah}(h]h ]h"]h$]h&]uh1hhjK ubah}(h]h ]h"]h$]h&]jj{uh1jhhhM%hjH ubah}(h]h ]h"]h$]h&]uh1jUhj- ubeh}(h]h ]h"]h$]h&]uh1j4hhhM&hj1ubj5)}(hW`int autosuspend_delay;` - the delay time (in milliseconds) to be used for autosuspend h](j;)}(h`int autosuspend_delay;`h]jA)}(hj~ h]hint autosuspend_delay;}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj| ubah}(h]h ]h"]h$]h&]uh1j:hhhM)hjx ubjV)}(hhh]j)}(hhh]h)}(hruntime_idle() is already being executed; if there is no callback or the callback returns 0 then run pm_runtime_autosuspend(dev) and return its result h](j;)}(h*`int pm_runtime_idle(struct device *dev);`h]jA)}(hj h]h(int pm_runtime_idle(struct device *dev);}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj ubah}(h]h ]h"]h$]h&]uh1j:hhhMChj ubjV)}(hhh]j)}(hhh]h)}(hXexecute the subsystem-level idle callback for the device; returns an error code on failure, where -EINPROGRESS means that ->runtime_idle() is already being executed; if there is no callback or the callback returns 0 then run pm_runtime_autosuspend(dev) and return its result h]h)}(hXexecute the subsystem-level idle callback for the device; returns an error code on failure, where -EINPROGRESS means that ->runtime_idle() is already being executed; if there is no callback or the callback returns 0 then run pm_runtime_autosuspend(dev) and return its resulth]hXexecute the subsystem-level idle callback for the device; returns an error code on failure, where -EINPROGRESS means that ->runtime_idle() is already being executed; if there is no callback or the callback returns 0 then run pm_runtime_autosuspend(dev) and return its result}(hj hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM@hj ubah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]jj{uh1jhhhM@hj ubah}(h]h ]h"]h$]h&]uh1jUhj ubeh}(h]h ]h"]h$]h&]uh1j4hhhMChjR ubj5)}(hX}`int pm_runtime_suspend(struct device *dev);` - execute the subsystem-level suspend callback for the device; returns 0 on success, 1 if the device's runtime PM status was already 'suspended', or error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt to suspend the device again in future and -EACCES means that 'power.disable_depth' is different from 0 h](j;)}(h-`int pm_runtime_suspend(struct device *dev);`h]jA)}(hj< h]h+int pm_runtime_suspend(struct device *dev);}(hhhj> hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj: ubah}(h]h ]h"]h$]h&]uh1j:hhhMJhj6 ubjV)}(hhh]j)}(hhh]h)}(hXEexecute the subsystem-level suspend callback for the device; returns 0 on success, 1 if the device's runtime PM status was already 'suspended', or error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt to suspend the device again in future and -EACCES means that 'power.disable_depth' is different from 0 h]h)}(hXDexecute the subsystem-level suspend callback for the device; returns 0 on success, 1 if the device's runtime PM status was already 'suspended', or error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt to suspend the device again in future and -EACCES means that 'power.disable_depth' is different from 0h]hXNexecute the subsystem-level suspend callback for the device; returns 0 on success, 1 if the device’s runtime PM status was already ‘suspended’, or error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt to suspend the device again in future and -EACCES means that ‘power.disable_depth’ is different from 0}(hj] hj[ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMFhjW ubah}(h]h ]h"]h$]h&]uh1hhjT ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMFhjQ ubah}(h]h ]h"]h$]h&]uh1jUhj6 ubeh}(h]h ]h"]h$]h&]uh1j4hhhMJhjR ubj5)}(hX(`int pm_runtime_autosuspend(struct device *dev);` - same as pm_runtime_suspend() except that the autosuspend delay is taken `into account;` if pm_runtime_autosuspend_expiration() says the delay has not yet expired then an autosuspend is scheduled for the appropriate time and 0 is returned h](j;)}(h1`int pm_runtime_autosuspend(struct device *dev);`h]jA)}(hj h]h/int pm_runtime_autosuspend(struct device *dev);}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj ubah}(h]h ]h"]h$]h&]uh1j:hhhMPhj ubjV)}(hhh]j)}(hhh]h)}(hsame as pm_runtime_suspend() except that the autosuspend delay is taken `into account;` if pm_runtime_autosuspend_expiration() says the delay has not yet expired then an autosuspend is scheduled for the appropriate time and 0 is returned h]h)}(hsame as pm_runtime_suspend() except that the autosuspend delay is taken `into account;` if pm_runtime_autosuspend_expiration() says the delay has not yet expired then an autosuspend is scheduled for the appropriate time and 0 is returnedh](hHsame as pm_runtime_suspend() except that the autosuspend delay is taken }(hHsame as pm_runtime_suspend() except that the autosuspend delay is taken hj hhhNhNubjA)}(h`into account;`h]h into account;}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj ubh if pm_runtime_autosuspend_expiration() says the delay has not yet expired then an autosuspend is scheduled for the appropriate time and 0 is returned}(h if pm_runtime_autosuspend_expiration() says the delay has not yet expired then an autosuspend is scheduled for the appropriate time and 0 is returnedhj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMMhj ubah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMMhj ubah}(h]h ]h"]h$]h&]uh1jUhj ubeh}(h]h ]h"]h$]h&]uh1j4hhhMPhjR ubj5)}(hXA`int pm_runtime_resume(struct device *dev);` - execute the subsystem-level resume callback for the device; returns 0 on success, 1 if the device's runtime PM status is already 'active' (also if 'power.disable_depth' is nonzero, but the status was 'active' when it was changing from 0 to 1) or error code on failure, where -EAGAIN means it may be safe to attempt to resume the device again in future, but 'power.runtime_error' should be checked additionally, and -EACCES means that the callback could not be run, because 'power.disable_depth' was different from 0 h](j;)}(h,`int pm_runtime_resume(struct device *dev);`h]jA)}(hj h]h*int pm_runtime_resume(struct device *dev);}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj ubah}(h]h ]h"]h$]h&]uh1j:hhhMZhj ubjV)}(hhh]j)}(hhh]h)}(hXexecute the subsystem-level resume callback for the device; returns 0 on success, 1 if the device's runtime PM status is already 'active' (also if 'power.disable_depth' is nonzero, but the status was 'active' when it was changing from 0 to 1) or error code on failure, where -EAGAIN means it may be safe to attempt to resume the device again in future, but 'power.runtime_error' should be checked additionally, and -EACCES means that the callback could not be run, because 'power.disable_depth' was different from 0 h]h)}(hXexecute the subsystem-level resume callback for the device; returns 0 on success, 1 if the device's runtime PM status is already 'active' (also if 'power.disable_depth' is nonzero, but the status was 'active' when it was changing from 0 to 1) or error code on failure, where -EAGAIN means it may be safe to attempt to resume the device again in future, but 'power.runtime_error' should be checked additionally, and -EACCES means that the callback could not be run, because 'power.disable_depth' was different from 0h]hXexecute the subsystem-level resume callback for the device; returns 0 on success, 1 if the device’s runtime PM status is already ‘active’ (also if ‘power.disable_depth’ is nonzero, but the status was ‘active’ when it was changing from 0 to 1) or error code on failure, where -EAGAIN means it may be safe to attempt to resume the device again in future, but ‘power.runtime_error’ should be checked additionally, and -EACCES means that the callback could not be run, because ‘power.disable_depth’ was different from 0}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMShjubah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMShj ubah}(h]h ]h"]h$]h&]uh1jUhj ubeh}(h]h ]h"]h$]h&]uh1j4hhhMZhjR ubj5)}(h`int pm_runtime_resume_and_get(struct device *dev);` - run pm_runtime_resume(dev) and if successful, increment the device's usage counter; return the result of pm_runtime_resume h](j;)}(h4`int pm_runtime_resume_and_get(struct device *dev);`h]jA)}(hj1h]h2int pm_runtime_resume_and_get(struct device *dev);}(hhhj3hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj/ubah}(h]h ]h"]h$]h&]uh1j:hhhM^hj+ubjV)}(hhh]j)}(hhh]h)}(h{run pm_runtime_resume(dev) and if successful, increment the device's usage counter; return the result of pm_runtime_resume h]h)}(hzrun pm_runtime_resume(dev) and if successful, increment the device's usage counter; return the result of pm_runtime_resumeh]h|run pm_runtime_resume(dev) and if successful, increment the device’s usage counter; return the result of pm_runtime_resume}(hjRhjPhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM]hjLubah}(h]h ]h"]h$]h&]uh1hhjIubah}(h]h ]h"]h$]h&]jj{uh1jhhhM]hjFubah}(h]h ]h"]h$]h&]uh1jUhj+ubeh}(h]h ]h"]h$]h&]uh1j4hhhM^hjR ubj5)}(h`int pm_request_idle(struct device *dev);` - submit a request to execute the subsystem-level idle callback for the device (the request is represented by a work item in pm_wq); returns 0 on success or error code if the request has not been queued up h](j;)}(h*`int pm_request_idle(struct device *dev);`h]jA)}(hj|h]h(int pm_request_idle(struct device *dev);}(hhhj~hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjzubah}(h]h ]h"]h$]h&]uh1j:hhhMchjvubjV)}(hhh]j)}(hhh]h)}(hsubmit a request to execute the subsystem-level idle callback for the device (the request is represented by a work item in pm_wq); returns 0 on success or error code if the request has not been queued up h]h)}(hsubmit a request to execute the subsystem-level idle callback for the device (the request is represented by a work item in pm_wq); returns 0 on success or error code if the request has not been queued uph]hsubmit a request to execute the subsystem-level idle callback for the device (the request is represented by a work item in pm_wq); returns 0 on success or error code if the request has not been queued up}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMahjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMahjubah}(h]h ]h"]h$]h&]uh1jUhjvubeh}(h]h ]h"]h$]h&]uh1j4hhhMchjR ubj5)}(h`int pm_request_autosuspend(struct device *dev);` - schedule the execution of the subsystem-level suspend callback for the device when the autosuspend delay has expired; if the delay has already expired then the work item is queued up immediately h](j;)}(h1`int pm_request_autosuspend(struct device *dev);`h]jA)}(hjh]h/int pm_request_autosuspend(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhhjubjV)}(hhh]j)}(hhh]h)}(hschedule the execution of the subsystem-level suspend callback for the device when the autosuspend delay has expired; if the delay has already expired then the work item is queued up immediately h]h)}(hschedule the execution of the subsystem-level suspend callback for the device when the autosuspend delay has expired; if the delay has already expired then the work item is queued up immediatelyh]hschedule the execution of the subsystem-level suspend callback for the device when the autosuspend delay has expired; if the delay has already expired then the work item is queued up immediately}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMfhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMfhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhhjR ubj5)}(hX~`int pm_schedule_suspend(struct device *dev, unsigned int delay);` - schedule the execution of the subsystem-level suspend callback for the device in future, where 'delay' is the time to wait before queuing up a suspend work item in pm_wq, in milliseconds (if 'delay' is zero, the work item is queued up immediately); returns 0 on success, 1 if the device's PM runtime status was already 'suspended', or error code if the request hasn't been scheduled (or queued up if 'delay' is 0); if the execution of ->runtime_suspend() is already scheduled and not yet expired, the new value of 'delay' will be used as the time to wait h](j;)}(hB`int pm_schedule_suspend(struct device *dev, unsigned int delay);`h]jA)}(hjh]h@int pm_schedule_suspend(struct device *dev, unsigned int delay);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMrhj ubjV)}(hhh]j)}(hhh]h)}(hX+schedule the execution of the subsystem-level suspend callback for the device in future, where 'delay' is the time to wait before queuing up a suspend work item in pm_wq, in milliseconds (if 'delay' is zero, the work item is queued up immediately); returns 0 on success, 1 if the device's PM runtime status was already 'suspended', or error code if the request hasn't been scheduled (or queued up if 'delay' is 0); if the execution of ->runtime_suspend() is already scheduled and not yet expired, the new value of 'delay' will be used as the time to wait h]h)}(hX*schedule the execution of the subsystem-level suspend callback for the device in future, where 'delay' is the time to wait before queuing up a suspend work item in pm_wq, in milliseconds (if 'delay' is zero, the work item is queued up immediately); returns 0 on success, 1 if the device's PM runtime status was already 'suspended', or error code if the request hasn't been scheduled (or queued up if 'delay' is 0); if the execution of ->runtime_suspend() is already scheduled and not yet expired, the new value of 'delay' will be used as the time to waith]hXBschedule the execution of the subsystem-level suspend callback for the device in future, where ‘delay’ is the time to wait before queuing up a suspend work item in pm_wq, in milliseconds (if ‘delay’ is zero, the work item is queued up immediately); returns 0 on success, 1 if the device’s PM runtime status was already ‘suspended’, or error code if the request hasn’t been scheduled (or queued up if ‘delay’ is 0); if the execution of ->runtime_suspend() is already scheduled and not yet expired, the new value of ‘delay’ will be used as the time to wait}(hj3hj1hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMkhj-ubah}(h]h ]h"]h$]h&]uh1hhj*ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMkhj'ubah}(h]h ]h"]h$]h&]uh1jUhj ubeh}(h]h ]h"]h$]h&]uh1j4hhhMrhjR ubj5)}(hX=`int pm_request_resume(struct device *dev);` - submit a request to execute the subsystem-level resume callback for the device (the request is represented by a work item in pm_wq); returns 0 on success, 1 if the device's runtime PM status was already 'active', or error code if the request hasn't been queued up h](j;)}(h,`int pm_request_resume(struct device *dev);`h]jA)}(hj]h]h*int pm_request_resume(struct device *dev);}(hhhj_hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj[ubah}(h]h ]h"]h$]h&]uh1j:hhhMxhjWubjV)}(hhh]j)}(hhh]h)}(hXsubmit a request to execute the subsystem-level resume callback for the device (the request is represented by a work item in pm_wq); returns 0 on success, 1 if the device's runtime PM status was already 'active', or error code if the request hasn't been queued up h]h)}(hXsubmit a request to execute the subsystem-level resume callback for the device (the request is represented by a work item in pm_wq); returns 0 on success, 1 if the device's runtime PM status was already 'active', or error code if the request hasn't been queued uph]hXsubmit a request to execute the subsystem-level resume callback for the device (the request is represented by a work item in pm_wq); returns 0 on success, 1 if the device’s runtime PM status was already ‘active’, or error code if the request hasn’t been queued up}(hj~hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMuhjxubah}(h]h ]h"]h$]h&]uh1hhjuubah}(h]h ]h"]h$]h&]jj{uh1jhhhMuhjrubah}(h]h ]h"]h$]h&]uh1jUhjWubeh}(h]h ]h"]h$]h&]uh1j4hhhMxhjR ubj5)}(h[`void pm_runtime_get_noresume(struct device *dev);` - increment the device's usage counter h](j;)}(h3`void pm_runtime_get_noresume(struct device *dev);`h]jA)}(hjh]h1void pm_runtime_get_noresume(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhM{hjubjV)}(hhh]j)}(hhh]h)}(h%increment the device's usage counter h]h)}(h$increment the device's usage counterh]h&increment the device’s usage counter}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM{hjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhM{hjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhM{hjR ubj5)}(h`int pm_runtime_get(struct device *dev);` - increment the device's usage counter, run pm_request_resume(dev) and return its result h](j;)}(h)`int pm_runtime_get(struct device *dev);`h]jA)}(hjh]h'int pm_runtime_get(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(hWincrement the device's usage counter, run pm_request_resume(dev) and return its result h]h)}(hVincrement the device's usage counter, run pm_request_resume(dev) and return its resulth]hXincrement the device’s usage counter, run pm_request_resume(dev) and return its result}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM~hjubah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]jj{uh1jhhhM~hjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(hXw`int pm_runtime_get_sync(struct device *dev);` - increment the device's usage counter, run pm_runtime_resume(dev) and return its result; note that it does not drop the device's usage counter on errors, so consider using pm_runtime_resume_and_get() instead of it, especially if its return value is checked by the caller, as this is likely to result in cleaner code. h](j;)}(h.`int pm_runtime_get_sync(struct device *dev);`h]jA)}(hj>h]h,int pm_runtime_get_sync(struct device *dev);}(hhhj@hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj<ubah}(h]h ]h"]h$]h&]uh1j:hhhMhj8ubjV)}(hhh]j)}(hhh]h)}(hX<increment the device's usage counter, run pm_runtime_resume(dev) and return its result; note that it does not drop the device's usage counter on errors, so consider using pm_runtime_resume_and_get() instead of it, especially if its return value is checked by the caller, as this is likely to result in cleaner code. h]h)}(hX;increment the device's usage counter, run pm_runtime_resume(dev) and return its result; note that it does not drop the device's usage counter on errors, so consider using pm_runtime_resume_and_get() instead of it, especially if its return value is checked by the caller, as this is likely to result in cleaner code.h]hX?increment the device’s usage counter, run pm_runtime_resume(dev) and return its result; note that it does not drop the device’s usage counter on errors, so consider using pm_runtime_resume_and_get() instead of it, especially if its return value is checked by the caller, as this is likely to result in cleaner code.}(hj_hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjYubah}(h]h ]h"]h$]h&]uh1hhjVubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjSubah}(h]h ]h"]h$]h&]uh1jUhj8ubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(hX#`int pm_runtime_get_if_in_use(struct device *dev);` - return -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the runtime PM status is RPM_ACTIVE and the runtime PM usage counter is nonzero, increment the counter and return 1; otherwise return 0 without changing the counter h](j;)}(h3`int pm_runtime_get_if_in_use(struct device *dev);`h]jA)}(hjh]h1int pm_runtime_get_if_in_use(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(hreturn -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the runtime PM status is RPM_ACTIVE and the runtime PM usage counter is nonzero, increment the counter and return 1; otherwise return 0 without changing the counter h]h)}(hreturn -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the runtime PM status is RPM_ACTIVE and the runtime PM usage counter is nonzero, increment the counter and return 1; otherwise return 0 without changing the counterh]hreturn -EINVAL if ‘power.disable_depth’ is nonzero; otherwise, if the runtime PM status is RPM_ACTIVE and the runtime PM usage counter is nonzero, increment the counter and return 1; otherwise return 0 without changing the counter}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(h`int pm_runtime_get_if_active(struct device *dev);` - return -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the runtime PM status is RPM_ACTIVE, increment the counter and return 1; otherwise return 0 without changing the counter h](j;)}(h3`int pm_runtime_get_if_active(struct device *dev);`h]jA)}(hjh]h1int pm_runtime_get_if_active(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(hreturn -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the runtime PM status is RPM_ACTIVE, increment the counter and return 1; otherwise return 0 without changing the counter h]h)}(hreturn -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the runtime PM status is RPM_ACTIVE, increment the counter and return 1; otherwise return 0 without changing the counterh]hreturn -EINVAL if ‘power.disable_depth’ is nonzero; otherwise, if the runtime PM status is RPM_ACTIVE, increment the counter and return 1; otherwise return 0 without changing the counter}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(hY`void pm_runtime_put_noidle(struct device *dev);` - decrement the device's usage counter h](j;)}(h1`void pm_runtime_put_noidle(struct device *dev);`h]jA)}(hjh]h/void pm_runtime_put_noidle(struct device *dev);}(hhhj!hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(h%decrement the device's usage counter h]h)}(h$decrement the device's usage counterh]h&decrement the device’s usage counter}(hj@hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj:ubah}(h]h ]h"]h$]h&]uh1hhj7ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhj4ubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(h`int pm_runtime_put(struct device *dev);` - decrement the device's usage counter; if the result is 0 then run pm_request_idle(dev) and return its result h](j;)}(h)`int pm_runtime_put(struct device *dev);`h]jA)}(hjjh]h'int pm_runtime_put(struct device *dev);}(hhhjlhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjhubah}(h]h ]h"]h$]h&]uh1j:hhhMhjdubjV)}(hhh]j)}(hhh]h)}(hmdecrement the device's usage counter; if the result is 0 then run pm_request_idle(dev) and return its result h]h)}(hldecrement the device's usage counter; if the result is 0 then run pm_request_idle(dev) and return its resulth]hndecrement the device’s usage counter; if the result is 0 then run pm_request_idle(dev) and return its result}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjdubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(h`int pm_runtime_put_autosuspend(struct device *dev);` - does the same as __pm_runtime_put_autosuspend() for now, but in the future, will also call pm_runtime_mark_last_busy() as well, DO NOT USE! h](j;)}(h5`int pm_runtime_put_autosuspend(struct device *dev);`h]jA)}(hjh]h3int pm_runtime_put_autosuspend(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(hdoes the same as __pm_runtime_put_autosuspend() for now, but in the future, will also call pm_runtime_mark_last_busy() as well, DO NOT USE! h]h)}(hdoes the same as __pm_runtime_put_autosuspend() for now, but in the future, will also call pm_runtime_mark_last_busy() as well, DO NOT USE!h]hdoes the same as __pm_runtime_put_autosuspend() for now, but in the future, will also call pm_runtime_mark_last_busy() as well, DO NOT USE!}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(h`int __pm_runtime_put_autosuspend(struct device *dev);` - decrement the device's usage counter; if the result is 0 then run pm_request_autosuspend(dev) and return its result h](j;)}(h7`int __pm_runtime_put_autosuspend(struct device *dev);`h]jA)}(hjh]h5int __pm_runtime_put_autosuspend(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(htdecrement the device's usage counter; if the result is 0 then run pm_request_autosuspend(dev) and return its result h]h)}(hsdecrement the device's usage counter; if the result is 0 then run pm_request_autosuspend(dev) and return its resulth]hudecrement the device’s usage counter; if the result is 0 then run pm_request_autosuspend(dev) and return its result}(hj!hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(h`int pm_runtime_put_sync(struct device *dev);` - decrement the device's usage counter; if the result is 0 then run pm_runtime_idle(dev) and return its result h](j;)}(h.`int pm_runtime_put_sync(struct device *dev);`h]jA)}(hjKh]h,int pm_runtime_put_sync(struct device *dev);}(hhhjMhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjIubah}(h]h ]h"]h$]h&]uh1j:hhhMhjEubjV)}(hhh]j)}(hhh]h)}(hmdecrement the device's usage counter; if the result is 0 then run pm_runtime_idle(dev) and return its result h]h)}(hldecrement the device's usage counter; if the result is 0 then run pm_runtime_idle(dev) and return its resulth]hndecrement the device’s usage counter; if the result is 0 then run pm_runtime_idle(dev) and return its result}(hjlhjjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjfubah}(h]h ]h"]h$]h&]uh1hhjcubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhj`ubah}(h]h ]h"]h$]h&]uh1jUhjEubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(h`int pm_runtime_put_sync_suspend(struct device *dev);` - decrement the device's usage counter; if the result is 0 then run pm_runtime_suspend(dev) and return its result h](j;)}(h6`int pm_runtime_put_sync_suspend(struct device *dev);`h]jA)}(hjh]h4int pm_runtime_put_sync_suspend(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(hpdecrement the device's usage counter; if the result is 0 then run pm_runtime_suspend(dev) and return its result h]h)}(hodecrement the device's usage counter; if the result is 0 then run pm_runtime_suspend(dev) and return its resulth]hqdecrement the device’s usage counter; if the result is 0 then run pm_runtime_suspend(dev) and return its result}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(h`int pm_runtime_put_sync_autosuspend(struct device *dev);` - decrement the device's usage counter; if the result is 0 then run pm_runtime_autosuspend(dev) and return its result h](j;)}(h:`int pm_runtime_put_sync_autosuspend(struct device *dev);`h]jA)}(hjh]h8int pm_runtime_put_sync_autosuspend(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(htdecrement the device's usage counter; if the result is 0 then run pm_runtime_autosuspend(dev) and return its result h]h)}(hsdecrement the device's usage counter; if the result is 0 then run pm_runtime_autosuspend(dev) and return its resulth]hudecrement the device’s usage counter; if the result is 0 then run pm_runtime_autosuspend(dev) and return its result}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(h`void pm_runtime_enable(struct device *dev);` - decrement the device's 'power.disable_depth' field; if that field is equal to zero, the runtime PM helper functions can execute subsystem-level callbacks described in Section 2 for the device h](j;)}(h-`void pm_runtime_enable(struct device *dev);`h]jA)}(hj,h]h+void pm_runtime_enable(struct device *dev);}(hhhj.hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj*ubah}(h]h ]h"]h$]h&]uh1j:hhhMhj&ubjV)}(hhh]j)}(hhh]h)}(hdecrement the device's 'power.disable_depth' field; if that field is equal to zero, the runtime PM helper functions can execute subsystem-level callbacks described in Section 2 for the device h]h)}(hdecrement the device's 'power.disable_depth' field; if that field is equal to zero, the runtime PM helper functions can execute subsystem-level callbacks described in Section 2 for the deviceh]hdecrement the device’s ‘power.disable_depth’ field; if that field is equal to zero, the runtime PM helper functions can execute subsystem-level callbacks described in Section 2 for the device}(hjMhjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjGubah}(h]h ]h"]h$]h&]uh1hhjDubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjAubah}(h]h ]h"]h$]h&]uh1jUhj&ubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(hX`int pm_runtime_disable(struct device *dev);` - increment the device's 'power.disable_depth' field (if the value of that field was previously zero, this prevents subsystem-level runtime PM callbacks from being run for the device), make sure that all of the pending runtime PM operations on the device are either completed or canceled; returns 1 if there was a resume request pending and it was necessary to execute the subsystem-level resume callback for the device to satisfy that request, otherwise 0 is returned h](j;)}(h-`int pm_runtime_disable(struct device *dev);`h]jA)}(hjwh]h+int pm_runtime_disable(struct device *dev);}(hhhjyhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjuubah}(h]h ]h"]h$]h&]uh1j:hhhMhjqubjV)}(hhh]j)}(hhh]h)}(hXincrement the device's 'power.disable_depth' field (if the value of that field was previously zero, this prevents subsystem-level runtime PM callbacks from being run for the device), make sure that all of the pending runtime PM operations on the device are either completed or canceled; returns 1 if there was a resume request pending and it was necessary to execute the subsystem-level resume callback for the device to satisfy that request, otherwise 0 is returned h]h)}(hXincrement the device's 'power.disable_depth' field (if the value of that field was previously zero, this prevents subsystem-level runtime PM callbacks from being run for the device), make sure that all of the pending runtime PM operations on the device are either completed or canceled; returns 1 if there was a resume request pending and it was necessary to execute the subsystem-level resume callback for the device to satisfy that request, otherwise 0 is returnedh]hXincrement the device’s ‘power.disable_depth’ field (if the value of that field was previously zero, this prevents subsystem-level runtime PM callbacks from being run for the device), make sure that all of the pending runtime PM operations on the device are either completed or canceled; returns 1 if there was a resume request pending and it was necessary to execute the subsystem-level resume callback for the device to satisfy that request, otherwise 0 is returned}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjqubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(hX`int pm_runtime_barrier(struct device *dev);` - check if there's a resume request pending for the device and resume it (synchronously) in that case, cancel any other pending runtime PM requests regarding it and wait for all runtime PM operations on it in progress to complete; returns 1 if there was a resume request pending and it was necessary to execute the subsystem-level resume callback for the device to satisfy that request, otherwise 0 is returned h](j;)}(h-`int pm_runtime_barrier(struct device *dev);`h]jA)}(hjh]h+int pm_runtime_barrier(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(hXcheck if there's a resume request pending for the device and resume it (synchronously) in that case, cancel any other pending runtime PM requests regarding it and wait for all runtime PM operations on it in progress to complete; returns 1 if there was a resume request pending and it was necessary to execute the subsystem-level resume callback for the device to satisfy that request, otherwise 0 is returned h]h)}(hXcheck if there's a resume request pending for the device and resume it (synchronously) in that case, cancel any other pending runtime PM requests regarding it and wait for all runtime PM operations on it in progress to complete; returns 1 if there was a resume request pending and it was necessary to execute the subsystem-level resume callback for the device to satisfy that request, otherwise 0 is returnedh]hXcheck if there’s a resume request pending for the device and resume it (synchronously) in that case, cancel any other pending runtime PM requests regarding it and wait for all runtime PM operations on it in progress to complete; returns 1 if there was a resume request pending and it was necessary to execute the subsystem-level resume callback for the device to satisfy that request, otherwise 0 is returned}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(h}`void pm_suspend_ignore_children(struct device *dev, bool enable);` - set/unset the power.ignore_children flag of the device h](j;)}(hC`void pm_suspend_ignore_children(struct device *dev, bool enable);`h]jA)}(hj h]hAvoid pm_suspend_ignore_children(struct device *dev, bool enable);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj ubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(h7set/unset the power.ignore_children flag of the device h]h)}(h6set/unset the power.ignore_children flag of the deviceh]h6set/unset the power.ignore_children flag of the device}(hj.hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj(ubah}(h]h ]h"]h$]h&]uh1hhj%ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhj"ubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(hX`int pm_runtime_set_active(struct device *dev);` - clear the device's 'power.runtime_error' flag, set the device's runtime PM status to 'active' and update its parent's counter of 'active' children as appropriate (it is only valid to use this function if 'power.runtime_error' is set or 'power.disable_depth' is greater than zero); it will fail and return error code if the device has a parent which is not active and the 'power.ignore_children' flag of which is unset h](j;)}(h0`int pm_runtime_set_active(struct device *dev);`h]jA)}(hjXh]h.int pm_runtime_set_active(struct device *dev);}(hhhjZhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjVubah}(h]h ]h"]h$]h&]uh1j:hhhMhjRubjV)}(hhh]j)}(hhh]h)}(hXclear the device's 'power.runtime_error' flag, set the device's runtime PM status to 'active' and update its parent's counter of 'active' children as appropriate (it is only valid to use this function if 'power.runtime_error' is set or 'power.disable_depth' is greater than zero); it will fail and return error code if the device has a parent which is not active and the 'power.ignore_children' flag of which is unset h]h)}(hXclear the device's 'power.runtime_error' flag, set the device's runtime PM status to 'active' and update its parent's counter of 'active' children as appropriate (it is only valid to use this function if 'power.runtime_error' is set or 'power.disable_depth' is greater than zero); it will fail and return error code if the device has a parent which is not active and the 'power.ignore_children' flag of which is unseth]hXclear the device’s ‘power.runtime_error’ flag, set the device’s runtime PM status to ‘active’ and update its parent’s counter of ‘active’ children as appropriate (it is only valid to use this function if ‘power.runtime_error’ is set or ‘power.disable_depth’ is greater than zero); it will fail and return error code if the device has a parent which is not active and the ‘power.ignore_children’ flag of which is unset}(hjyhjwhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjsubah}(h]h ]h"]h$]h&]uh1hhjpubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjmubah}(h]h ]h"]h$]h&]uh1jUhjRubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(hXZ`void pm_runtime_set_suspended(struct device *dev);` - clear the device's 'power.runtime_error' flag, set the device's runtime PM status to 'suspended' and update its parent's counter of 'active' children as appropriate (it is only valid to use this function if 'power.runtime_error' is set or 'power.disable_depth' is greater than zero) h](j;)}(h4`void pm_runtime_set_suspended(struct device *dev);`h]jA)}(hjh]h2void pm_runtime_set_suspended(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(hXclear the device's 'power.runtime_error' flag, set the device's runtime PM status to 'suspended' and update its parent's counter of 'active' children as appropriate (it is only valid to use this function if 'power.runtime_error' is set or 'power.disable_depth' is greater than zero) h]h)}(hXclear the device's 'power.runtime_error' flag, set the device's runtime PM status to 'suspended' and update its parent's counter of 'active' children as appropriate (it is only valid to use this function if 'power.runtime_error' is set or 'power.disable_depth' is greater than zero)h]hX4clear the device’s ‘power.runtime_error’ flag, set the device’s runtime PM status to ‘suspended’ and update its parent’s counter of ‘active’ children as appropriate (it is only valid to use this function if ‘power.runtime_error’ is set or ‘power.disable_depth’ is greater than zero)}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(h`bool pm_runtime_active(struct device *dev);` - return true if the device's runtime PM status is 'active' or its 'power.disable_depth' field is not equal to zero, or false otherwise h](j;)}(h-`bool pm_runtime_active(struct device *dev);`h]jA)}(hjh]h+bool pm_runtime_active(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(hreturn true if the device's runtime PM status is 'active' or its 'power.disable_depth' field is not equal to zero, or false otherwise h]h)}(hreturn true if the device's runtime PM status is 'active' or its 'power.disable_depth' field is not equal to zero, or false otherwiseh]hreturn true if the device’s runtime PM status is ‘active’ or its ‘power.disable_depth’ field is not equal to zero, or false otherwise}(hjhj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(h`bool pm_runtime_suspended(struct device *dev);` - return true if the device's runtime PM status is 'suspended' and its 'power.disable_depth' field is equal to zero, or false otherwise h](j;)}(h0`bool pm_runtime_suspended(struct device *dev);`h]jA)}(hj9h]h.bool pm_runtime_suspended(struct device *dev);}(hhhj;hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj7ubah}(h]h ]h"]h$]h&]uh1j:hhhMhj3ubjV)}(hhh]j)}(hhh]h)}(hreturn true if the device's runtime PM status is 'suspended' and its 'power.disable_depth' field is equal to zero, or false otherwise h]h)}(hreturn true if the device's runtime PM status is 'suspended' and its 'power.disable_depth' field is equal to zero, or false otherwiseh]hreturn true if the device’s runtime PM status is ‘suspended’ and its ‘power.disable_depth’ field is equal to zero, or false otherwise}(hjZhjXhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjTubah}(h]h ]h"]h$]h&]uh1hhjQubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjNubah}(h]h ]h"]h$]h&]uh1jUhj3ubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjR ubj5)}(hw`bool pm_runtime_status_suspended(struct device *dev);` - return true if the device's runtime PM status is 'suspended' h](j;)}(h7`bool pm_runtime_status_suspended(struct device *dev);`h]jA)}(hjh]h5bool pm_runtime_status_suspended(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhj~ubjV)}(hhh]j)}(hhh]h)}(h=return true if the device's runtime PM status is 'suspended' h]h)}(hhj:hhubh)}(hXHowever, if the device has a parent and the parent's runtime PM is enabled, calling pm_runtime_set_active() for the device will affect the parent, unless the parent's 'power.ignore_children' flag is set. Namely, in that case the parent won't be able to suspend at run time, using the PM core's helper functions, as long as the child's status is 'active', even if the child's runtime PM is still disabled (i.e. pm_runtime_enable() hasn't been called for the child yet or pm_runtime_disable() has been called for it). For this reason, once pm_runtime_set_active() has been called for the device, pm_runtime_enable() should be called for it too as soon as reasonably possible or its runtime PM status should be changed back to 'suspended' with the help of pm_runtime_set_suspended().h]hX(However, if the device has a parent and the parent’s runtime PM is enabled, calling pm_runtime_set_active() for the device will affect the parent, unless the parent’s ‘power.ignore_children’ flag is set. Namely, in that case the parent won’t be able to suspend at run time, using the PM core’s helper functions, as long as the child’s status is ‘active’, even if the child’s runtime PM is still disabled (i.e. pm_runtime_enable() hasn’t been called for the child yet or pm_runtime_disable() has been called for it). For this reason, once pm_runtime_set_active() has been called for the device, pm_runtime_enable() should be called for it too as soon as reasonably possible or its runtime PM status should be changed back to ‘suspended’ with the help of pm_runtime_set_suspended().}(hjihjghhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMDhj:hhubh)}(hXIf the default initial runtime PM status of the device (i.e. 'suspended') reflects the actual state of the device, its bus type's or its driver's ->probe() callback will likely need to wake it up using one of the PM core's helper functions described in Section 4. In that case, pm_runtime_resume() should be used. Of course, for this purpose the device's runtime PM has to be enabled earlier by calling pm_runtime_enable().h]hXIf the default initial runtime PM status of the device (i.e. ‘suspended’) reflects the actual state of the device, its bus type’s or its driver’s ->probe() callback will likely need to wake it up using one of the PM core’s helper functions described in Section 4. In that case, pm_runtime_resume() should be used. Of course, for this purpose the device’s runtime PM has to be enabled earlier by calling pm_runtime_enable().}(hjwhjuhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMPhj:hhubh)}(hXfNote, if the device may execute pm_runtime calls during the probe (such as if it is registered with a subsystem that may call back in) then the pm_runtime_get_sync() call paired with a pm_runtime_put() call will be appropriate to ensure that the device is not put back to sleep during the probe. This can happen with systems such as the network device layer.h]hXfNote, if the device may execute pm_runtime calls during the probe (such as if it is registered with a subsystem that may call back in) then the pm_runtime_get_sync() call paired with a pm_runtime_put() call will be appropriate to ensure that the device is not put back to sleep during the probe. This can happen with systems such as the network device layer.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMWhj:hhubh)}(hXiIt may be desirable to suspend the device once ->probe() has finished. Therefore the driver core uses the asynchronous pm_request_idle() to submit a request to execute the subsystem-level idle callback for the device at that time. A driver that makes use of the runtime autosuspend feature may want to update the last busy mark before returning from ->probe().h]hXiIt may be desirable to suspend the device once ->probe() has finished. Therefore the driver core uses the asynchronous pm_request_idle() to submit a request to execute the subsystem-level idle callback for the device at that time. A driver that makes use of the runtime autosuspend feature may want to update the last busy mark before returning from ->probe().}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM]hj:hhubh)}(hX Moreover, the driver core prevents runtime PM callbacks from racing with the bus notifier callback in __device_release_driver(), which is necessary because the notifier is used by some subsystems to carry out operations affecting the runtime PM functionality. It does so by calling pm_runtime_get_sync() before driver_sysfs_remove() and the BUS_NOTIFY_UNBIND_DRIVER notifications. This resumes the device if it's in the suspended state and prevents it from being suspended again while those routines are being executed.h]hX Moreover, the driver core prevents runtime PM callbacks from racing with the bus notifier callback in __device_release_driver(), which is necessary because the notifier is used by some subsystems to carry out operations affecting the runtime PM functionality. It does so by calling pm_runtime_get_sync() before driver_sysfs_remove() and the BUS_NOTIFY_UNBIND_DRIVER notifications. This resumes the device if it’s in the suspended state and prevents it from being suspended again while those routines are being executed.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMchj:hhubh)}(hXTo allow bus types and drivers to put devices into the suspended state by calling pm_runtime_suspend() from their ->remove() routines, the driver core executes pm_runtime_put_sync() after running the BUS_NOTIFY_UNBIND_DRIVER notifications in __device_release_driver(). This requires bus types and drivers to make their ->remove() callbacks avoid races with runtime PM directly, but it also allows more flexibility in the handling of devices during the removal of their drivers.h]hXTo allow bus types and drivers to put devices into the suspended state by calling pm_runtime_suspend() from their ->remove() routines, the driver core executes pm_runtime_put_sync() after running the BUS_NOTIFY_UNBIND_DRIVER notifications in __device_release_driver(). This requires bus types and drivers to make their ->remove() callbacks avoid races with runtime PM directly, but it also allows more flexibility in the handling of devices during the removal of their drivers.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMkhj:hhubh)}(hDrivers in ->remove() callback should undo the runtime PM changes done in ->probe(). Usually this means calling pm_runtime_disable(), pm_runtime_dont_use_autosuspend() etc.h]hDrivers in ->remove() callback should undo the runtime PM changes done in ->probe(). Usually this means calling pm_runtime_disable(), pm_runtime_dont_use_autosuspend() etc.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMshj:hhubh)}(hXThe user space can effectively disallow the driver of the device to power manage it at run time by changing the value of its /sys/devices/.../power/control attribute to "on", which causes pm_runtime_forbid() to be called. In principle, this mechanism may also be used by the driver to effectively turn off the runtime power management of the device until the user space turns it on. Namely, during the initialization the driver can make sure that the runtime PM status of the device is 'active' and call pm_runtime_forbid(). It should be noted, however, that if the user space has already intentionally changed the value of /sys/devices/.../power/control to "auto" to allow the driver to power manage the device at run time, the driver may confuse it by using pm_runtime_forbid() this way.h]hX#The user space can effectively disallow the driver of the device to power manage it at run time by changing the value of its /sys/devices/.../power/control attribute to “on”, which causes pm_runtime_forbid() to be called. In principle, this mechanism may also be used by the driver to effectively turn off the runtime power management of the device until the user space turns it on. Namely, during the initialization the driver can make sure that the runtime PM status of the device is ‘active’ and call pm_runtime_forbid(). It should be noted, however, that if the user space has already intentionally changed the value of /sys/devices/.../power/control to “auto” to allow the driver to power manage the device at run time, the driver may confuse it by using pm_runtime_forbid() this way.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMwhj:hhubeh}(h]4runtime-pm-initialization-device-probing-and-removalah ]h"]85. runtime pm initialization, device probing and removalah$]h&]uh1hhhhhhhhM8ubh)}(hhh](h)}(h6. Runtime PM and System Sleeph]h6. Runtime PM and System Sleep}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(hX0Runtime PM and system sleep (i.e., system suspend and hibernation, also known as suspend-to-RAM and suspend-to-disk) interact with each other in a couple of ways. If a device is active when a system sleep starts, everything is straightforward. But what should happen if the device is already suspended?h]hX0Runtime PM and system sleep (i.e., system suspend and hibernation, also known as suspend-to-RAM and suspend-to-disk) interact with each other in a couple of ways. If a device is active when a system sleep starts, everything is straightforward. But what should happen if the device is already suspended?}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hXZThe device may have different wake-up settings for runtime PM and system sleep. For example, remote wake-up may be enabled for runtime suspend but disallowed for system sleep (device_may_wakeup(dev) returns 'false'). When this happens, the subsystem-level system suspend callback is responsible for changing the device's wake-up setting (it may leave that to the device driver's system suspend routine). It may be necessary to resume the device and suspend it again in order to do so. The same is true if the driver uses different power levels or other settings for runtime suspend and system sleep.h]hXbThe device may have different wake-up settings for runtime PM and system sleep. For example, remote wake-up may be enabled for runtime suspend but disallowed for system sleep (device_may_wakeup(dev) returns ‘false’). When this happens, the subsystem-level system suspend callback is responsible for changing the device’s wake-up setting (it may leave that to the device driver’s system suspend routine). It may be necessary to resume the device and suspend it again in order to do so. The same is true if the driver uses different power levels or other settings for runtime suspend and system sleep.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hDuring system resume, the simplest approach is to bring all devices back to full power, even if they had been suspended before the system suspend began. There are several reasons for this, including:h]hDuring system resume, the simplest approach is to bring all devices back to full power, even if they had been suspended before the system suspend began. There are several reasons for this, including:}(hjhj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubjM)}(hhh]j)}(hhh](h)}(hEThe device might need to switch power levels, wake-up settings, etc. h]h)}(hDThe device might need to switch power levels, wake-up settings, etc.h]hDThe device might need to switch power levels, wake-up settings, etc.}(hj&hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1hhjubh)}(hhj<hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj8ubah}(h]h ]h"]h$]h&]uh1hhjubh)}(h]The device's children may need the device to be at full power in order to resume themselves. h]h)}(h\The device's children may need the device to be at full power in order to resume themselves.h]h^The device’s children may need the device to be at full power in order to resume themselves.}(hjVhjThhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjPubah}(h]h ]h"]h$]h&]uh1hhjubh)}(hThe driver's idea of the device state may not agree with the device's physical state. This can happen during resume from hibernation. h]h)}(hThe driver's idea of the device state may not agree with the device's physical state. This can happen during resume from hibernation.h]hThe driver’s idea of the device state may not agree with the device’s physical state. This can happen during resume from hibernation.}(hjnhjlhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhubah}(h]h ]h"]h$]h&]uh1hhjubh)}(h#The device might need to be reset. h]h)}(h"The device might need to be reset.h]h"The device might need to be reset.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubh)}(hEven though the device was suspended, if its usage counter was > 0 then most likely it would need a runtime resume in the near future anyway. h]h)}(hEven though the device was suspended, if its usage counter was > 0 then most likely it would need a runtime resume in the near future anyway.h]hEven though the device was suspended, if its usage counter was > 0 then most likely it would need a runtime resume in the near future anyway.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]jjuh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jLhjhhhNhNubh)}(hIf the device had been suspended before the system suspend began and it's brought back to full power during resume, then its runtime PM status will have to be updated to reflect the actual post-system sleep status. The way to do this is:h]hIf the device had been suspended before the system suspend began and it’s brought back to full power during resume, then its runtime PM status will have to be updated to reflect the actual post-system sleep status. The way to do this is:}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubjM)}(hhh]j)}(hhh](h)}(hpm_runtime_disable(dev);h]h)}(hjh]hpm_runtime_disable(dev);}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubh)}(hpm_runtime_set_active(dev);h]h)}(hjh]hpm_runtime_set_active(dev);}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubh)}(hpm_runtime_enable(dev); h]h)}(hpm_runtime_enable(dev);h]hpm_runtime_enable(dev);}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jLhjhhhNhNubh)}(hXThe PM core always increments the runtime usage counter before calling the ->suspend() callback and decrements it after calling the ->resume() callback. Hence disabling runtime PM temporarily like this will not cause any runtime suspend attempts to be permanently lost. If the usage count goes to zero following the return of the ->resume() callback, the ->runtime_idle() callback will be invoked as usual.h]hXThe PM core always increments the runtime usage counter before calling the ->suspend() callback and decrements it after calling the ->resume() callback. Hence disabling runtime PM temporarily like this will not cause any runtime suspend attempts to be permanently lost. If the usage count goes to zero following the return of the ->resume() callback, the ->runtime_idle() callback will be invoked as usual.}(hj$hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hX8On some systems, however, system sleep is not entered through a global firmware or hardware operation. Instead, all hardware components are put into low-power states directly by the kernel in a coordinated way. Then, the system sleep state effectively follows from the states the hardware components end up in and the system is woken up from that state by a hardware interrupt or a similar mechanism entirely under the kernel's control. As a result, the kernel never gives control away and the states of all devices during resume are precisely known to it. If that is the case and none of the situations listed above takes place (in particular, if the system is not waking up from hibernation), it may be more efficient to leave the devices that had been suspended before the system suspend began in the suspended state.h]hX:On some systems, however, system sleep is not entered through a global firmware or hardware operation. Instead, all hardware components are put into low-power states directly by the kernel in a coordinated way. Then, the system sleep state effectively follows from the states the hardware components end up in and the system is woken up from that state by a hardware interrupt or a similar mechanism entirely under the kernel’s control. As a result, the kernel never gives control away and the states of all devices during resume are precisely known to it. If that is the case and none of the situations listed above takes place (in particular, if the system is not waking up from hibernation), it may be more efficient to leave the devices that had been suspended before the system suspend began in the suspended state.}(hj2hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hXTo this end, the PM core provides a mechanism allowing some coordination between different levels of device hierarchy. Namely, if a system suspend .prepare() callback returns a positive number for a device, that indicates to the PM core that the device appears to be runtime-suspended and its state is fine, so it may be left in runtime suspend provided that all of its descendants are also left in runtime suspend. If that happens, the PM core will not execute any system suspend and resume callbacks for all of those devices, except for the .complete() callback, which is then entirely responsible for handling the device as appropriate. This only applies to system suspend transitions that are not related to hibernation (see Documentation/driver-api/pm/devices.rst for more information).h]hXTo this end, the PM core provides a mechanism allowing some coordination between different levels of device hierarchy. Namely, if a system suspend .prepare() callback returns a positive number for a device, that indicates to the PM core that the device appears to be runtime-suspended and its state is fine, so it may be left in runtime suspend provided that all of its descendants are also left in runtime suspend. If that happens, the PM core will not execute any system suspend and resume callbacks for all of those devices, except for the .complete() callback, which is then entirely responsible for handling the device as appropriate. This only applies to system suspend transitions that are not related to hibernation (see Documentation/driver-api/pm/devices.rst for more information).}(hj@hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hThe PM core does its best to reduce the probability of race conditions between the runtime PM and system suspend/resume (and hibernation) callbacks by carrying out the following operations:h]hThe PM core does its best to reduce the probability of race conditions between the runtime PM and system suspend/resume (and hibernation) callbacks by carrying out the following operations:}(hjNhjLhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubjM)}(hhh]j)}(hhh](h)}(hXDuring system suspend pm_runtime_get_noresume() is called for every device right before executing the subsystem-level .prepare() callback for it and pm_runtime_barrier() is called for every device right before executing the subsystem-level .suspend() callback for it. In addition to that the PM core calls __pm_runtime_disable() with 'false' as the second argument for every device right before executing the subsystem-level .suspend_late() callback for it. h]h)}(hXDuring system suspend pm_runtime_get_noresume() is called for every device right before executing the subsystem-level .prepare() callback for it and pm_runtime_barrier() is called for every device right before executing the subsystem-level .suspend() callback for it. In addition to that the PM core calls __pm_runtime_disable() with 'false' as the second argument for every device right before executing the subsystem-level .suspend_late() callback for it.h]hXDuring system suspend pm_runtime_get_noresume() is called for every device right before executing the subsystem-level .prepare() callback for it and pm_runtime_barrier() is called for every device right before executing the subsystem-level .suspend() callback for it. In addition to that the PM core calls __pm_runtime_disable() with ‘false’ as the second argument for every device right before executing the subsystem-level .suspend_late() callback for it.}(hjfhjdhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj`ubah}(h]h ]h"]h$]h&]uh1hhj]ubh)}(hDuring system resume pm_runtime_enable() and pm_runtime_put() are called for every device right after executing the subsystem-level .resume_early() callback and right after executing the subsystem-level .complete() callback for it, respectively. h]h)}(hDuring system resume pm_runtime_enable() and pm_runtime_put() are called for every device right after executing the subsystem-level .resume_early() callback and right after executing the subsystem-level .complete() callback for it, respectively.h]hDuring system resume pm_runtime_enable() and pm_runtime_put() are called for every device right after executing the subsystem-level .resume_early() callback and right after executing the subsystem-level .complete() callback for it, respectively.}(hj~hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjxubah}(h]h ]h"]h$]h&]uh1hhj]ubeh}(h]h ]h"]h$]h&]jjuh1jhhhMhjZubah}(h]h ]h"]h$]h&]uh1jLhjhhhNhNubeh}(h]runtime-pm-and-system-sleepah ]h"]6. runtime pm and system sleepah$]h&]uh1hhhhhhhhMubh)}(hhh](h)}(h7. Generic subsystem callbacksh]h7. Generic subsystem callbacks}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(hSubsystems may wish to conserve code space by using the set of generic power management callbacks provided by the PM core, defined in driver/base/power/generic_ops.c:h]hSubsystems may wish to conserve code space by using the set of generic power management callbacks provided by the PM core, defined in driver/base/power/generic_ops.c:}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubjM)}(hhh]j0)}(hhh](j5)}(h`int pm_generic_runtime_suspend(struct device *dev);` - invoke the ->runtime_suspend() callback provided by the driver of this device and return its result, or return 0 if not defined h](j;)}(h5`int pm_generic_runtime_suspend(struct device *dev);`h]jA)}(hjh]h3int pm_generic_runtime_suspend(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(hinvoke the ->runtime_suspend() callback provided by the driver of this device and return its result, or return 0 if not defined h]h)}(hinvoke the ->runtime_suspend() callback provided by the driver of this device and return its result, or return 0 if not definedh]hinvoke the ->runtime_suspend() callback provided by the driver of this device and return its result, or return 0 if not defined}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjubj5)}(h`int pm_generic_runtime_resume(struct device *dev);` - invoke the ->runtime_resume() callback provided by the driver of this device and return its result, or return 0 if not defined h](j;)}(h4`int pm_generic_runtime_resume(struct device *dev);`h]jA)}(hjh]h2int pm_generic_runtime_resume(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(hinvoke the ->runtime_resume() callback provided by the driver of this device and return its result, or return 0 if not defined h]h)}(h~invoke the ->runtime_resume() callback provided by the driver of this device and return its result, or return 0 if not definedh]h~invoke the ->runtime_resume() callback provided by the driver of this device and return its result, or return 0 if not defined}(hj;hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj5ubah}(h]h ]h"]h$]h&]uh1hhj2ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhj/ubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjubj5)}(h`int pm_generic_suspend(struct device *dev);` - if the device has not been suspended at run time, invoke the ->suspend() callback provided by its driver and return its result, or return 0 if not defined h](j;)}(h-`int pm_generic_suspend(struct device *dev);`h]jA)}(hjeh]h+int pm_generic_suspend(struct device *dev);}(hhhjghhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjcubah}(h]h ]h"]h$]h&]uh1j:hhhMhj_ubjV)}(hhh]j)}(hhh]h)}(hif the device has not been suspended at run time, invoke the ->suspend() callback provided by its driver and return its result, or return 0 if not defined h]h)}(hif the device has not been suspended at run time, invoke the ->suspend() callback provided by its driver and return its result, or return 0 if not definedh]hif the device has not been suspended at run time, invoke the ->suspend() callback provided by its driver and return its result, or return 0 if not defined}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhj}ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjzubah}(h]h ]h"]h$]h&]uh1jUhj_ubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjubj5)}(h`int pm_generic_suspend_noirq(struct device *dev);` - if pm_runtime_suspended(dev) returns "false", invoke the ->suspend_noirq() callback provided by the device's driver and return its result, or return 0 if not defined h](j;)}(h3`int pm_generic_suspend_noirq(struct device *dev);`h]jA)}(hjh]h1int pm_generic_suspend_noirq(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(hif pm_runtime_suspended(dev) returns "false", invoke the ->suspend_noirq() callback provided by the device's driver and return its result, or return 0 if not defined h]h)}(hif pm_runtime_suspended(dev) returns "false", invoke the ->suspend_noirq() callback provided by the device's driver and return its result, or return 0 if not definedh]hif pm_runtime_suspended(dev) returns “false”, invoke the ->suspend_noirq() callback provided by the device’s driver and return its result, or return 0 if not defined}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjubj5)}(h`int pm_generic_resume(struct device *dev);` - invoke the ->resume() callback provided by the driver of this device and, if successful, change the device's runtime PM status to 'active' h](j;)}(h,`int pm_generic_resume(struct device *dev);`h]jA)}(hjh]h*int pm_generic_resume(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(hinvoke the ->resume() callback provided by the driver of this device and, if successful, change the device's runtime PM status to 'active' h]h)}(hinvoke the ->resume() callback provided by the driver of this device and, if successful, change the device's runtime PM status to 'active'h]hinvoke the ->resume() callback provided by the driver of this device and, if successful, change the device’s runtime PM status to ‘active’}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjubj5)}(h`int pm_generic_resume_noirq(struct device *dev);` - invoke the ->resume_noirq() callback provided by the driver of this device h](j;)}(h2`int pm_generic_resume_noirq(struct device *dev);`h]jA)}(hjFh]h0int pm_generic_resume_noirq(struct device *dev);}(hhhjHhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjDubah}(h]h ]h"]h$]h&]uh1j:hhhMhj@ubjV)}(hhh]j)}(hhh]h)}(hKinvoke the ->resume_noirq() callback provided by the driver of this device h]h)}(hJinvoke the ->resume_noirq() callback provided by the driver of this deviceh]hJinvoke the ->resume_noirq() callback provided by the driver of this device}(hjghjehhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjaubah}(h]h ]h"]h$]h&]uh1hhj^ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhj[ubah}(h]h ]h"]h$]h&]uh1jUhj@ubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjubj5)}(h`int pm_generic_freeze(struct device *dev);` - if the device has not been suspended at run time, invoke the ->freeze() callback provided by its driver and return its result, or return 0 if not defined h](j;)}(h,`int pm_generic_freeze(struct device *dev);`h]jA)}(hjh]h*int pm_generic_freeze(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(hif the device has not been suspended at run time, invoke the ->freeze() callback provided by its driver and return its result, or return 0 if not defined h]h)}(hif the device has not been suspended at run time, invoke the ->freeze() callback provided by its driver and return its result, or return 0 if not definedh]hif the device has not been suspended at run time, invoke the ->freeze() callback provided by its driver and return its result, or return 0 if not defined}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjubj5)}(h`int pm_generic_freeze_noirq(struct device *dev);` - if pm_runtime_suspended(dev) returns "false", invoke the ->freeze_noirq() callback provided by the device's driver and return its result, or return 0 if not defined h](j;)}(h2`int pm_generic_freeze_noirq(struct device *dev);`h]jA)}(hjh]h0int pm_generic_freeze_noirq(struct device *dev);}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1j:hhhMhjubjV)}(hhh]j)}(hhh]h)}(hif pm_runtime_suspended(dev) returns "false", invoke the ->freeze_noirq() callback provided by the device's driver and return its result, or return 0 if not defined h]h)}(hif pm_runtime_suspended(dev) returns "false", invoke the ->freeze_noirq() callback provided by the device's driver and return its result, or return 0 if not definedh]hif pm_runtime_suspended(dev) returns “false”, invoke the ->freeze_noirq() callback provided by the device’s driver and return its result, or return 0 if not defined}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjubah}(h]h ]h"]h$]h&]uh1jUhjubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjubj5)}(h`int pm_generic_thaw(struct device *dev);` - if the device has not been suspended at run time, invoke the ->thaw() callback provided by its driver and return its result, or return 0 if not defined h](j;)}(h*`int pm_generic_thaw(struct device *dev);`h]jA)}(hj' h]h(int pm_generic_thaw(struct device *dev);}(hhhj) hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj% ubah}(h]h ]h"]h$]h&]uh1j:hhhM hj! ubjV)}(hhh]j)}(hhh]h)}(hif the device has not been suspended at run time, invoke the ->thaw() callback provided by its driver and return its result, or return 0 if not defined h]h)}(hif the device has not been suspended at run time, invoke the ->thaw() callback provided by its driver and return its result, or return 0 if not definedh]hif the device has not been suspended at run time, invoke the ->thaw() callback provided by its driver and return its result, or return 0 if not defined}(hjH hjF hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hjB ubah}(h]h ]h"]h$]h&]uh1hhj? ubah}(h]h ]h"]h$]h&]jj{uh1jhhhM hj< ubah}(h]h ]h"]h$]h&]uh1jUhj! ubeh}(h]h ]h"]h$]h&]uh1j4hhhM hjubj5)}(h`int pm_generic_thaw_noirq(struct device *dev);` - if pm_runtime_suspended(dev) returns "false", invoke the ->thaw_noirq() callback provided by the device's driver and return its result, or return 0 if not defined h](j;)}(h0`int pm_generic_thaw_noirq(struct device *dev);`h]jA)}(hjr h]h.int pm_generic_thaw_noirq(struct device *dev);}(hhhjt hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjp ubah}(h]h ]h"]h$]h&]uh1j:hhhMhjl ubjV)}(hhh]j)}(hhh]h)}(hif pm_runtime_suspended(dev) returns "false", invoke the ->thaw_noirq() callback provided by the device's driver and return its result, or return 0 if not defined h]h)}(hif pm_runtime_suspended(dev) returns "false", invoke the ->thaw_noirq() callback provided by the device's driver and return its result, or return 0 if not definedh]hif pm_runtime_suspended(dev) returns “false”, invoke the ->thaw_noirq() callback provided by the device’s driver and return its result, or return 0 if not defined}(hj hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhj ubah}(h]h ]h"]h$]h&]uh1jUhjl ubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjubj5)}(h`int pm_generic_poweroff(struct device *dev);` - if the device has not been suspended at run time, invoke the ->poweroff() callback provided by its driver and return its result, or return 0 if not defined h](j;)}(h.`int pm_generic_poweroff(struct device *dev);`h]jA)}(hj h]h,int pm_generic_poweroff(struct device *dev);}(hhhj hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj ubah}(h]h ]h"]h$]h&]uh1j:hhhMhj ubjV)}(hhh]j)}(hhh]h)}(hif the device has not been suspended at run time, invoke the ->poweroff() callback provided by its driver and return its result, or return 0 if not defined h]h)}(hif the device has not been suspended at run time, invoke the ->poweroff() callback provided by its driver and return its result, or return 0 if not definedh]hif the device has not been suspended at run time, invoke the ->poweroff() callback provided by its driver and return its result, or return 0 if not defined}(hj hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhj ubah}(h]h ]h"]h$]h&]uh1jUhj ubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjubj5)}(h`int pm_generic_poweroff_noirq(struct device *dev);` - if pm_runtime_suspended(dev) returns "false", run the ->poweroff_noirq() callback provided by the device's driver and return its result, or return 0 if not defined h](j;)}(h4`int pm_generic_poweroff_noirq(struct device *dev);`h]jA)}(hj!h]h2int pm_generic_poweroff_noirq(struct device *dev);}(hhhj !hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj!ubah}(h]h ]h"]h$]h&]uh1j:hhhMhj!ubjV)}(hhh]j)}(hhh]h)}(hif pm_runtime_suspended(dev) returns "false", run the ->poweroff_noirq() callback provided by the device's driver and return its result, or return 0 if not defined h]h)}(hif pm_runtime_suspended(dev) returns "false", run the ->poweroff_noirq() callback provided by the device's driver and return its result, or return 0 if not definedh]hif pm_runtime_suspended(dev) returns “false”, run the ->poweroff_noirq() callback provided by the device’s driver and return its result, or return 0 if not defined}(hj)!hj'!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj#!ubah}(h]h ]h"]h$]h&]uh1hhj !ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhj!ubah}(h]h ]h"]h$]h&]uh1jUhj!ubeh}(h]h ]h"]h$]h&]uh1j4hhhMhjubj5)}(h`int pm_generic_restore(struct device *dev);` - invoke the ->restore() callback provided by the driver of this device and, if successful, change the device's runtime PM status to 'active' h](j;)}(h-`int pm_generic_restore(struct device *dev);`h]jA)}(hjS!h]h+int pm_generic_restore(struct device *dev);}(hhhjU!hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjQ!ubah}(h]h ]h"]h$]h&]uh1j:hhhM hjM!ubjV)}(hhh]j)}(hhh]h)}(hinvoke the ->restore() callback provided by the driver of this device and, if successful, change the device's runtime PM status to 'active' h]h)}(hinvoke the ->restore() callback provided by the driver of this device and, if successful, change the device's runtime PM status to 'active'h]hinvoke the ->restore() callback provided by the driver of this device and, if successful, change the device’s runtime PM status to ‘active’}(hjt!hjr!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjn!ubah}(h]h ]h"]h$]h&]uh1hhjk!ubah}(h]h ]h"]h$]h&]jj{uh1jhhhMhjh!ubah}(h]h ]h"]h$]h&]uh1jUhjM!ubeh}(h]h ]h"]h$]h&]uh1j4hhhM hjubj5)}(h|`int pm_generic_restore_noirq(struct device *dev);` - invoke the ->restore_noirq() callback provided by the device's driver h](j;)}(h3`int pm_generic_restore_noirq(struct device *dev);`h]jA)}(hj!h]h1int pm_generic_restore_noirq(struct device *dev);}(hhhj!hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj!ubah}(h]h ]h"]h$]h&]uh1j:hhhM#hj!ubjV)}(hhh]j)}(hhh]h)}(hFinvoke the ->restore_noirq() callback provided by the device's driver h]h)}(hEinvoke the ->restore_noirq() callback provided by the device's driverh]hGinvoke the ->restore_noirq() callback provided by the device’s driver}(hj!hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM#hj!ubah}(h]h ]h"]h$]h&]uh1hhj!ubah}(h]h ]h"]h$]h&]jj{uh1jhhhM#hj!ubah}(h]h ]h"]h$]h&]uh1jUhj!ubeh}(h]h ]h"]h$]h&]uh1j4hhhM#hjubeh}(h]h ]h"]h$]h&]uh1j/hjubah}(h]h ]h"]h$]h&]uh1jLhjhhhNhNubh)}(hXThese functions are the defaults used by the PM core if a subsystem doesn't provide its own callbacks for ->runtime_idle(), ->runtime_suspend(), ->runtime_resume(), ->suspend(), ->suspend_noirq(), ->resume(), ->resume_noirq(), ->freeze(), ->freeze_noirq(), ->thaw(), ->thaw_noirq(), ->poweroff(), ->poweroff_noirq(), ->restore(), ->restore_noirq() in the subsystem-level dev_pm_ops structure.h]hXThese functions are the defaults used by the PM core if a subsystem doesn’t provide its own callbacks for ->runtime_idle(), ->runtime_suspend(), ->runtime_resume(), ->suspend(), ->suspend_noirq(), ->resume(), ->resume_noirq(), ->freeze(), ->freeze_noirq(), ->thaw(), ->thaw_noirq(), ->poweroff(), ->poweroff_noirq(), ->restore(), ->restore_noirq() in the subsystem-level dev_pm_ops structure.}(hj!hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM%hjhhubh)}(hXFDevice drivers that wish to use the same function as a system suspend, freeze, poweroff and runtime suspend callback, and similarly for system resume, thaw, restore, and runtime resume, can achieve this with the help of the UNIVERSAL_DEV_PM_OPS macro defined in include/linux/pm.h (possibly setting its last argument to NULL).h]hXFDevice drivers that wish to use the same function as a system suspend, freeze, poweroff and runtime suspend callback, and similarly for system resume, thaw, restore, and runtime resume, can achieve this with the help of the UNIVERSAL_DEV_PM_OPS macro defined in include/linux/pm.h (possibly setting its last argument to NULL).}(hj!hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM,hjhhubeh}(h]generic-subsystem-callbacksah ]h"]7. generic subsystem callbacksah$]h&]uh1hhhhhhhhMubh)}(hhh](h)}(h8. "No-Callback" Devicesh]h8. “No-Callback” Devices}(hj"hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj"hhhhhM3ubh)}(hX Some "devices" are only logical sub-devices of their parent and cannot be power-managed on their own. (The prototype example is a USB interface. Entire USB devices can go into low-power mode or send wake-up requests, but neither is possible for individual interfaces.) The drivers for these devices have no need of runtime PM callbacks; if the callbacks did exist, ->runtime_suspend() and ->runtime_resume() would always return 0 without doing anything else and ->runtime_idle() would always call pm_runtime_suspend().h]hX Some “devices” are only logical sub-devices of their parent and cannot be power-managed on their own. (The prototype example is a USB interface. Entire USB devices can go into low-power mode or send wake-up requests, but neither is possible for individual interfaces.) The drivers for these devices have no need of runtime PM callbacks; if the callbacks did exist, ->runtime_suspend() and ->runtime_resume() would always return 0 without doing anything else and ->runtime_idle() would always call pm_runtime_suspend().}(hj&"hj$"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM5hj"hhubh)}(hXpSubsystems can tell the PM core about these devices by calling pm_runtime_no_callbacks(). This should be done after the device structure is initialized and before it is registered (although after device registration is also okay). The routine will set the device's power.no_callbacks flag and prevent the non-debugging runtime PM sysfs attributes from being created.h]hXrSubsystems can tell the PM core about these devices by calling pm_runtime_no_callbacks(). This should be done after the device structure is initialized and before it is registered (although after device registration is also okay). The routine will set the device’s power.no_callbacks flag and prevent the non-debugging runtime PM sysfs attributes from being created.}(hj4"hj2"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM=hj"hhubh)}(hWhen power.no_callbacks is set, the PM core will not invoke the ->runtime_idle(), ->runtime_suspend(), or ->runtime_resume() callbacks. Instead it will assume that suspends and resumes always succeed and that idle devices should be suspended.h]hWhen power.no_callbacks is set, the PM core will not invoke the ->runtime_idle(), ->runtime_suspend(), or ->runtime_resume() callbacks. Instead it will assume that suspends and resumes always succeed and that idle devices should be suspended.}(hjB"hj@"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMChj"hhubh)}(hXAs a consequence, the PM core will never directly inform the device's subsystem or driver about runtime power changes. Instead, the driver for the device's parent must take responsibility for telling the device's driver when the parent's power state changes.h]hX As a consequence, the PM core will never directly inform the device’s subsystem or driver about runtime power changes. Instead, the driver for the device’s parent must take responsibility for telling the device’s driver when the parent’s power state changes.}(hjP"hjN"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMHhj"hhubh)}(hXKNote that, in some cases it may not be desirable for subsystems/drivers to call pm_runtime_no_callbacks() for their devices. This could be because a subset of the runtime PM callbacks needs to be implemented, a platform dependent PM domain could get attached to the device or that the device is power managed through a supplier device link. For these reasons and to avoid boilerplate code in subsystems/drivers, the PM core allows runtime PM callbacks to be unassigned. More precisely, if a callback pointer is NULL, the PM core will act as though there was a callback and it returned 0.h]hXKNote that, in some cases it may not be desirable for subsystems/drivers to call pm_runtime_no_callbacks() for their devices. This could be because a subset of the runtime PM callbacks needs to be implemented, a platform dependent PM domain could get attached to the device or that the device is power managed through a supplier device link. For these reasons and to avoid boilerplate code in subsystems/drivers, the PM core allows runtime PM callbacks to be unassigned. More precisely, if a callback pointer is NULL, the PM core will act as though there was a callback and it returned 0.}(hj^"hj\"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMMhj"hhubeh}(h]no-callback-devicesah ]h"]8. "no-callback" devicesah$]h&]uh1hhhhhhhhM3ubh)}(hhh](h)}(h19. Autosuspend, or automatically-delayed suspendsh]h19. Autosuspend, or automatically-delayed suspends}(hjw"hju"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjr"hhhhhMWubh)}(hX\Changing a device's power state isn't free; it requires both time and energy. A device should be put in a low-power state only when there's some reason to think it will remain in that state for a substantial time. A common heuristic says that a device which hasn't been used for a while is liable to remain unused; following this advice, drivers should not allow devices to be suspended at runtime until they have been inactive for some minimum period. Even when the heuristic ends up being non-optimal, it will still prevent devices from "bouncing" too rapidly between low-power and full-power states.h]hXhChanging a device’s power state isn’t free; it requires both time and energy. A device should be put in a low-power state only when there’s some reason to think it will remain in that state for a substantial time. A common heuristic says that a device which hasn’t been used for a while is liable to remain unused; following this advice, drivers should not allow devices to be suspended at runtime until they have been inactive for some minimum period. Even when the heuristic ends up being non-optimal, it will still prevent devices from “bouncing” too rapidly between low-power and full-power states.}(hj"hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMYhjr"hhubh)}(hX-The term "autosuspend" is an historical remnant. It doesn't mean that the device is automatically suspended (the subsystem or driver still has to call the appropriate PM routines); rather it means that runtime suspends will automatically be delayed until the desired period of inactivity has elapsed.h]hX3The term “autosuspend” is an historical remnant. It doesn’t mean that the device is automatically suspended (the subsystem or driver still has to call the appropriate PM routines); rather it means that runtime suspends will automatically be delayed until the desired period of inactivity has elapsed.}(hj"hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMbhjr"hhubh)}(hXInactivity is determined based on the power.last_busy field. Drivers should call pm_runtime_mark_last_busy() to update this field after carrying out I/O, typically just before calling __pm_runtime_put_autosuspend(). The desired length of the inactivity period is a matter of policy. Subsystems can set this length initially by calling pm_runtime_set_autosuspend_delay(), but after device registration the length should be controlled by user space, using the /sys/devices/.../power/autosuspend_delay_ms attribute.h]hXInactivity is determined based on the power.last_busy field. Drivers should call pm_runtime_mark_last_busy() to update this field after carrying out I/O, typically just before calling __pm_runtime_put_autosuspend(). The desired length of the inactivity period is a matter of policy. Subsystems can set this length initially by calling pm_runtime_set_autosuspend_delay(), but after device registration the length should be controlled by user space, using the /sys/devices/.../power/autosuspend_delay_ms attribute.}(hj"hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMghjr"hhubh)}(hXIn order to use autosuspend, subsystems or drivers must call pm_runtime_use_autosuspend() (preferably before registering the device), and thereafter they should use the various `*_autosuspend()` helper functions instead of the non-autosuspend counterparts::h](hIn order to use autosuspend, subsystems or drivers must call pm_runtime_use_autosuspend() (preferably before registering the device), and thereafter they should use the various }(hIn order to use autosuspend, subsystems or drivers must call pm_runtime_use_autosuspend() (preferably before registering the device), and thereafter they should use the various hj"hhhNhNubjA)}(h`*_autosuspend()`h]h*_autosuspend()}(hhhj"hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj"ubh> helper functions instead of the non-autosuspend counterparts:}(h> helper functions instead of the non-autosuspend counterparts:hj"hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMohjr"hhubj-)}(hX Instead of: pm_runtime_suspend use: pm_runtime_autosuspend; Instead of: pm_schedule_suspend use: pm_request_autosuspend; Instead of: pm_runtime_put use: __pm_runtime_put_autosuspend; Instead of: pm_runtime_put_sync use: pm_runtime_put_sync_autosuspend.h]hX Instead of: pm_runtime_suspend use: pm_runtime_autosuspend; Instead of: pm_schedule_suspend use: pm_request_autosuspend; Instead of: pm_runtime_put use: __pm_runtime_put_autosuspend; Instead of: pm_runtime_put_sync use: pm_runtime_put_sync_autosuspend.}(hhhj"ubah}(h]h ]h"]h$]h&]j<j=uh1j,hhhMthjr"hhubh)}(hDrivers may also continue to use the non-autosuspend helper functions; they will behave normally, which means sometimes taking the autosuspend delay into account (see pm_runtime_idle).h]hDrivers may also continue to use the non-autosuspend helper functions; they will behave normally, which means sometimes taking the autosuspend delay into account (see pm_runtime_idle).}(hj"hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMyhjr"hhubh)}(hXUnder some circumstances a driver or subsystem may want to prevent a device from autosuspending immediately, even though the usage counter is zero and the autosuspend delay time has expired. If the ->runtime_suspend() callback returns -EAGAIN or -EBUSY, and if the next autosuspend delay expiration time is in the future (as it normally would be if the callback invoked pm_runtime_mark_last_busy()), the PM core will automatically reschedule the autosuspend. The ->runtime_suspend() callback can't do this rescheduling itself because no suspend requests of any kind are accepted while the device is suspending (i.e., while the callback is running).h]hXUnder some circumstances a driver or subsystem may want to prevent a device from autosuspending immediately, even though the usage counter is zero and the autosuspend delay time has expired. If the ->runtime_suspend() callback returns -EAGAIN or -EBUSY, and if the next autosuspend delay expiration time is in the future (as it normally would be if the callback invoked pm_runtime_mark_last_busy()), the PM core will automatically reschedule the autosuspend. The ->runtime_suspend() callback can’t do this rescheduling itself because no suspend requests of any kind are accepted while the device is suspending (i.e., while the callback is running).}(hj"hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM}hjr"hhubh)}(hXUThe implementation is well suited for asynchronous use in interrupt contexts. However such use inevitably involves races, because the PM core can't synchronize ->runtime_suspend() callbacks with the arrival of I/O requests. This synchronization must be handled by the driver, using its private lock. Here is a schematic pseudo-code example::h]hXVThe implementation is well suited for asynchronous use in interrupt contexts. However such use inevitably involves races, because the PM core can’t synchronize ->runtime_suspend() callbacks with the arrival of I/O requests. This synchronization must be handled by the driver, using its private lock. Here is a schematic pseudo-code example:}(hXTThe implementation is well suited for asynchronous use in interrupt contexts. However such use inevitably involves races, because the PM core can't synchronize ->runtime_suspend() callbacks with the arrival of I/O requests. This synchronization must be handled by the driver, using its private lock. Here is a schematic pseudo-code example:hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjr"hhubj-)}(hXfoo_read_or_write(struct foo_priv *foo, void *data) { lock(&foo->private_lock); add_request_to_io_queue(foo, data); if (foo->num_pending_requests++ == 0) pm_runtime_get(&foo->dev); if (!foo->is_suspended) foo_process_next_request(foo); unlock(&foo->private_lock); } foo_io_completion(struct foo_priv *foo, void *req) { lock(&foo->private_lock); if (--foo->num_pending_requests == 0) { pm_runtime_mark_last_busy(&foo->dev); __pm_runtime_put_autosuspend(&foo->dev); } else { foo_process_next_request(foo); } unlock(&foo->private_lock); /* Send req result back to the user ... */ } int foo_runtime_suspend(struct device *dev) { struct foo_priv foo = container_of(dev, ...); int ret = 0; lock(&foo->private_lock); if (foo->num_pending_requests > 0) { ret = -EBUSY; } else { /* ... suspend the device ... */ foo->is_suspended = 1; } unlock(&foo->private_lock); return ret; } int foo_runtime_resume(struct device *dev) { struct foo_priv foo = container_of(dev, ...); lock(&foo->private_lock); /* ... resume the device ... */ foo->is_suspended = 0; pm_runtime_mark_last_busy(&foo->dev); if (foo->num_pending_requests > 0) foo_process_next_request(foo); unlock(&foo->private_lock); return 0; }h]hXfoo_read_or_write(struct foo_priv *foo, void *data) { lock(&foo->private_lock); add_request_to_io_queue(foo, data); if (foo->num_pending_requests++ == 0) pm_runtime_get(&foo->dev); if (!foo->is_suspended) foo_process_next_request(foo); unlock(&foo->private_lock); } foo_io_completion(struct foo_priv *foo, void *req) { lock(&foo->private_lock); if (--foo->num_pending_requests == 0) { pm_runtime_mark_last_busy(&foo->dev); __pm_runtime_put_autosuspend(&foo->dev); } else { foo_process_next_request(foo); } unlock(&foo->private_lock); /* Send req result back to the user ... */ } int foo_runtime_suspend(struct device *dev) { struct foo_priv foo = container_of(dev, ...); int ret = 0; lock(&foo->private_lock); if (foo->num_pending_requests > 0) { ret = -EBUSY; } else { /* ... suspend the device ... */ foo->is_suspended = 1; } unlock(&foo->private_lock); return ret; } int foo_runtime_resume(struct device *dev) { struct foo_priv foo = container_of(dev, ...); lock(&foo->private_lock); /* ... resume the device ... */ foo->is_suspended = 0; pm_runtime_mark_last_busy(&foo->dev); if (foo->num_pending_requests > 0) foo_process_next_request(foo); unlock(&foo->private_lock); return 0; }}(hhhj#ubah}(h]h ]h"]h$]h&]j<j=uh1j,hhhMhjr"hhubh)}(hX5The important point is that after foo_io_completion() asks for an autosuspend, the foo_runtime_suspend() callback may race with foo_read_or_write(). Therefore foo_runtime_suspend() has to check whether there are any pending I/O requests (while holding the private lock) before allowing the suspend to proceed.h]hX5The important point is that after foo_io_completion() asks for an autosuspend, the foo_runtime_suspend() callback may race with foo_read_or_write(). Therefore foo_runtime_suspend() has to check whether there are any pending I/O requests (while holding the private lock) before allowing the suspend to proceed.}(hj#hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjr"hhubh)}(hXhIn addition, the power.autosuspend_delay field can be changed by user space at any time. If a driver cares about this, it can call pm_runtime_autosuspend_expiration() from within the ->runtime_suspend() callback while holding its private lock. If the function returns a nonzero value then the delay has not yet expired and the callback should return -EAGAIN.h]hXhIn addition, the power.autosuspend_delay field can be changed by user space at any time. If a driver cares about this, it can call pm_runtime_autosuspend_expiration() from within the ->runtime_suspend() callback while holding its private lock. If the function returns a nonzero value then the delay has not yet expired and the callback should return -EAGAIN.}(hj&#hj$#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjr"hhubeh}(h]-autosuspend-or-automatically-delayed-suspendsah ]h"]19. autosuspend, or automatically-delayed suspendsah$]h&]uh1hhhhhhhhMWubeh}(h]2runtime-power-management-framework-for-i-o-devicesah ]h"]2runtime power management framework for i/o devicesah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerje#error_encodingUTF-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confapep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacefile_insertion_enabled raw_enabledKline_length_limitM'syntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_link embed_imagesenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(j?#j<#j jj jj- j* j7j4jjjjj"j "jo"jl"j7#j4#u nametypes}(j?#Nj Nj Nj- Nj7NjNjNj"Njo"Nj7#Nuh}(j<#hjjjjj j* j j4j0 jj:jjj "jjl"j"j4#jr"u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages](hsystem_message)}(hhh]h)}(h:Enumerated list start value not ordinal-1: "C" (ordinal 3)h]h>Enumerated list start value not ordinal-1: “C” (ordinal 3)}(hhhj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj#ubah}(h]h ]h"]h$]h&]levelKtypeINFOsourcehlineKuh1j#hhhhhhhKubj#)}(hhh]h)}(h:Enumerated list start value not ordinal-1: "C" (ordinal 3)h]h>Enumerated list start value not ordinal-1: “C” (ordinal 3)}(hhhj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj#ubah}(h]h ]h"]h$]h&]levelKtypej#sourcehlineKuh1j#hhhhhhhKubj#)}(hhh]h)}(h:Enumerated list start value not ordinal-1: "C" (ordinal 3)h]h>Enumerated list start value not ordinal-1: “C” (ordinal 3)}(hhhj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj$ubah}(h]h ]h"]h$]h&]levelKtypej#sourcehlineKuh1j#hhhhhhhK ubetransform_messages] transformerN include_log] decorationNhhub.