Merge branch 'pm-runtime'

Merge updates related to runtime PM for 7.4:

 - Update and improve runtime PM documentation and add a kunit test for
   supplier idle/suspend (Brian Norris)

 - Add a pm_runtime_dont_use_autosuspend() call to pm_runtime_reinit()
   to ensure autosuspend disabling on driver teardown (Joshua Crofts)

* pm-runtime:
  PM: runtime: Expand introduction with core concepts and structure
  PM: runtime: Clarify driver callback expectations and structure Section 2
  PM: runtime: Clarify ->runtime_idle() callback return value handling
  PM: runtime: Add "Section" hyperlinks
  PM: runtime: Misc improvements to runtime_pm.rst
  PM: runtime: More kerneldoc formatting
  PM: runtime: Correct pm_runtime_autosuspend_expiration() doc
  PM: runtime: call pm_runtime_dont_use_autosuspend() on reinit()
  PM: core: Document struct dev_pm_info with kerneldoc
  PM: runtime: Pull API docs from kerneldoc
  PM: runtime: kerneldoc wording improvements
  PM: runtime: Improve set_{status,active,suspended} docs
  PM: runtime: kerneldoc fixes
  PM: runtime: Add kunit test for supplier idle/suspend
  PM: runtime: Only queue an idle check for RPM-linked suppliers
This commit is contained in:
Rafael J. Wysocki 2026-10-19 14:52:22 +02:00
commit dc2021eae5
5 changed files with 620 additions and 635 deletions

View File

@ -8,34 +8,114 @@ Runtime Power Management Framework for I/O Devices
(C) 2014 Intel Corp., Rafael J. Wysocki <rafael.j.wysocki@intel.com>
.. _Section 1:
1. Introduction
===============
Support for runtime power management (runtime PM) of I/O devices is provided
at the power management core (PM core) level by means of:
Runtime power management (or runtime PM, sometimes also referred to as RPM)
allows individual I/O devices that are not in active use to be put into
low-power states, in which they may not be operational or even accessible, and
go back to the fully operational state as needed. Power can be reduced this
way without waiting for a transition into a system-wide sleep state.
* The 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.
Core Concepts
-------------
* A 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.
Runtime PM operates around a few device-level concepts — whether a device is
**active** or **suspended**; whether runtime PM is **enabled** or **disabled**;
whether runtime PM is **allowed** or **forbidden**; and whether a device is
**in use**.
* **Active**: Runtime PM tracks whether or not devices are in active use, which
generally means that they are accessible and operational, and may be depended
on by something (for example, other devices or user space). This is
represented by the **active** meta-state. By contrast, the **suspended**
meta-state represents a promise that the given device will not be accessed.
This covers devices in low-power states, but it also may include devices that
are not fully operational. There are also two transient meta-states,
**suspending** and **resuming**, representing transitions between **active**
and **suspended** often referred to as *runtime suspend* and *runtime
resume*, or just *suspend* and *resume*, respectively. Every device handled
by runtime PM is in one of these four meta-states at any time, and its
meta-state is expected to reflect its actual physical configuration (that is,
for instance, if the device is not accessible, it must not be **active**).
The term "runtime PM status" used in what follows refers to the meta-states
described above.
* **Enabled**: In order to track the runtime PM status and carry out
transitions between **active** and **suspended**, runtime PM needs to be
**enabled** for the given device. If it is **disabled**, runtime PM
generally leaves the device alone. This means in particular that the runtime
PM status of a device and its actual physical configuration may get out of
sync after disabling runtime PM for it. Additionally, the runtime PM status
of a device may need to be explicitly adjusted to reflect its current
physical configuration before enabling runtime PM for it (e.g., during device
probe). Once runtime PM is **enabled**, it begins managing PM status —
performing *runtime suspend* and *runtime resume* transitions based on its
understanding of whether a device is in use.
As a rule, all devices are initialized with runtime PM **disabled**, though
some bus types (such as PCI) manage some RPM initialization automatically,
and therefore probe devices in an **enabled** state. For other devices,
drivers must enable runtime PM on their own to opt in.
* **Allowed**: Runtime PM may be **forbidden** even though it has been enabled.
Doing so causes the given device to transition into the **active** meta-state
and prevents it from being suspended. In other words, a device with
forbidden runtime PM remains **active** at least until runtime PM is
**allowed** for it again. This mechanism can be managed by in-kernel APIs,
but more importantly, it is also available to user space via the
``/sys/devices/.../power/control`` sysfs attribute of the given device.
Namely, writing ``on`` to that attribute forbids runtime PM, and writing
``auto`` allows it. User space may modify that attribute at any time, so the
ability to transition a device into the **suspended** meta-state via runtime
PM must not be relied on for correctness.
* **In use**: Runtime PM determines whether a device should be transitioned to
an **active** state by its understanding of whether a device is in use. The
first way a device is considered **in use** is by its own usage count — a
reference counter driven by a variety of get()/put() APIs. Additionally, a
device may be considered **in use** by having active dependents — either
child devices, or device-linked consumers. When a device is no longer in
use, runtime PM may choose to transition it to the **suspended** state.
Thus, when a device moves from **suspended** to **active**, it may also cause
its dependencies to resume, unless they are **active** already. Conversely,
suspending a device may also cause its otherwise-unused dependencies to
suspend.
* **Autosuspend**: Runtime PM also supports a feature called "autosuspend."
This is different than the ``control`` notion of "auto" (i.e., **allowed**).
Autosuspend is covered in `Section 9`_.
Implementation Structure
------------------------
Support for runtime power management is provided at the power management core
(PM core) level by means of:
* Three device runtime PM callbacks in 'struct dev_pm_ops' (defined in
include/linux/pm.h).
include/linux/pm.h). See `Section 2`_.
* A number of runtime PM fields in the 'power' member of 'struct device' that
can be used for synchronizing runtime PM operations with one another. These
are covered in `Section 3`_.
* A 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.
synchronization between them is taken care of by the PM core. Bus types and
device drivers are encouraged to use these functions. They are covered in
`Section 4`_.
The 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.
* The 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.
.. _Section 2:
2. Device Runtime PM Callbacks
==============================
@ -50,6 +130,14 @@ There are three device runtime PM callbacks defined in 'struct dev_pm_ops'::
...
};
Most device drivers only need to implement ->runtime_suspend() and
->runtime_resume(). The ->runtime_idle() callback is optional and rarely
implemented by peripheral device drivers, as the PM core automatically handles
suspension and autosuspend when ->runtime_idle() is omitted (or returns 0).
Subsystem and Driver Callbacks
------------------------------
The ->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:
@ -80,8 +168,11 @@ 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.
listed at the end of `Section 4`_ may be used for that device within an
interrupt handler or generally in an atomic context.
Callback Semantics
------------------
The subsystem-level suspend callback, if present, is _entirely_ _responsible_
for handling the suspend of the device as appropriate, which may, but need not
@ -105,9 +196,9 @@ knows what to do to handle the device).
* 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).
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).
In 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
@ -132,10 +223,10 @@ what to do to handle the device).
'active'.
* 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).
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).
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
@ -154,13 +245,21 @@ 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(). 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.
call to pm_runtime_autosuspend().
The 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:
To prevent this suspension (for example, if the callback routine has scheduled
a delayed suspend or determined the device cannot be idle), the routine must
return a non-zero value (typically -EBUSY or -EAGAIN). Unlike
->runtime_suspend() and ->runtime_resume(), the PM core does not treat negative
return codes from ->runtime_idle() as a fatal device error; any non-zero value
simply stops the PM core from suspending the device.
Core Guarantees and Synchronization Rules
-----------------------------------------
The 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:
(1) The callbacks are mutually exclusive (e.g. it is forbidden to execute
->runtime_suspend() in parallel with ->runtime_resume() or with another
@ -200,106 +299,19 @@ rules:
scheduled requests to execute the other callbacks for the same device,
except for scheduled autosuspends.
.. _Section 3:
3. Runtime PM Device Fields
===========================
The following device runtime PM fields are present in 'struct dev_pm_info', as
defined in include/linux/pm.h:
Device PM fields are found in 'struct dev_pm_info', as defined in
include/linux/pm.h. Many of those fields track runtime PM configuration and
state.
`struct timer_list suspend_timer;`
- timer used for scheduling (delayed) suspend and autosuspend requests
.. kernel-doc:: include/linux/pm.h
:identifiers: dev_pm_info
`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)
`struct work_struct work;`
- work structure used for queuing up requests (i.e. work items in pm_wq)
`wait_queue_head_t wait_queue;`
- wait queue used if any of the helper functions needs to wait for another
one to complete
`spinlock_t lock;`
- lock used for synchronization
`atomic_t usage_count;`
- the usage counter of the device
`atomic_t child_count;`
- the count of 'active' children of the device
`unsigned int ignore_children;`
- if set, the value of child_count is ignored (but still updated)
`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)
`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
`unsigned int idle_notification;`
- if set, ->runtime_idle() is being executed
`unsigned int request_pending;`
- if set, there's a pending request (i.e. a work item queued up into pm_wq)
`enum rpm_request request;`
- type of request that's pending (valid if request_pending is set)
`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"
`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
`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)
`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
`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
`unsigned int irq_safe;`
- indicates that the ->runtime_suspend() and ->runtime_resume() callbacks
will be invoked with the spinlock held and interrupts disabled
`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
`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
`int autosuspend_delay;`
- the delay time (in milliseconds) to be used for autosuspend
`unsigned long last_busy;`
- the time (in jiffies) when the pm_runtime_mark_last_busy() helper
function was last called for this device; used in calculating inactivity
periods for autosuspend
All of the above fields are members of the 'power' member of 'struct device'.
.. _Section 4:
4. Runtime PM Device Helper Functions
=====================================
@ -307,219 +319,10 @@ All of the above fields are members of the 'power' member of 'struct device'.
The following runtime PM helper functions are defined in
drivers/base/power/runtime.c and include/linux/pm_runtime.h:
`void pm_runtime_init(struct device *dev);`
- initialize the device runtime PM fields in 'struct dev_pm_info'
.. kernel-doc:: drivers/base/power/runtime.c
:export:
`void pm_runtime_remove(struct device *dev);`
- make sure that the runtime PM of the device will be disabled after
removing the device from device hierarchy
`int pm_runtime_idle(struct device *dev);`
- execute 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
`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
`int pm_runtime_autosuspend(struct device *dev);`
- same as pm_runtime_suspend() except that a call to
pm_runtime_mark_last_busy() is made and an autosuspend is scheduled for
the appropriate time and 0 is returned
`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
`int pm_runtime_resume_and_get(struct device *dev);`
- run pm_runtime_resume(dev) and if successful, increment the device's
usage counter; returns 0 on success (whether or not the device's
runtime PM status was already 'active') or the error code from
pm_runtime_resume() on failure.
`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
`int pm_request_autosuspend(struct device *dev);`
- Call pm_runtime_mark_last_busy() and schedule the execution of the
subsystem-level suspend callback for the device when the autosuspend delay
expires
`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
`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
`void pm_runtime_get_noresume(struct device *dev);`
- increment the device's usage counter
`int pm_runtime_get(struct device *dev);`
- increment the device's usage counter, run pm_request_resume(dev) and
return its result
`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.
`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
`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
`void pm_runtime_put_noidle(struct device *dev);`
- decrement the device's usage counter
`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
`int pm_runtime_put_autosuspend(struct device *dev);`
- set the power.last_busy field to the current time and decrement the
device's usage counter; if the result is 0 then run
pm_request_autosuspend(dev) and return its result
`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
`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
`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
`int pm_runtime_put_sync_autosuspend(struct device *dev);`
- set the power.last_busy field to the current time and decrement the
device's usage counter; if the result is 0 then run
pm_runtime_autosuspend(dev) and return its result
`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
`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
`void 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
`void pm_suspend_ignore_children(struct device *dev, bool enable);`
- set/unset the power.ignore_children flag of the device
`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
`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)
`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
`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
`bool pm_runtime_status_suspended(struct device *dev);`
- return true if the device's runtime PM status is 'suspended'
`void pm_runtime_no_callbacks(struct device *dev);`
- set the power.no_callbacks flag for the device and remove the runtime
PM attributes from /sys/devices/.../power (or prevent them from being
added when the device is registered)
`void pm_runtime_irq_safe(struct device *dev);`
- set the power.irq_safe flag for the device, causing the runtime-PM
callbacks to be invoked with interrupts off
`bool pm_runtime_is_irq_safe(struct device *dev);`
- return true if power.irq_safe flag was set for the device, causing
the runtime-PM callbacks to be invoked with interrupts off
`void pm_runtime_mark_last_busy(struct device *dev);`
- set the power.last_busy field to the current time
`void pm_runtime_use_autosuspend(struct device *dev);`
- set the power.use_autosuspend flag, enabling autosuspend delays; call
pm_runtime_get_sync if the flag was previously cleared and
power.autosuspend_delay is negative
`void pm_runtime_dont_use_autosuspend(struct device *dev);`
- clear the power.use_autosuspend flag, disabling autosuspend delays;
decrement the device's usage counter if the flag was previously set and
power.autosuspend_delay is negative; call pm_runtime_idle
`void pm_runtime_set_autosuspend_delay(struct device *dev, int delay);`
- set the power.autosuspend_delay value to 'delay' (expressed in
milliseconds); if 'delay' is negative then runtime suspends are
prevented; if power.use_autosuspend is set, pm_runtime_get_sync may be
called or the device's usage counter may be decremented and
pm_runtime_idle called depending on if power.autosuspend_delay is
changed to or from a negative value; if power.use_autosuspend is clear,
pm_runtime_idle is called
`unsigned long pm_runtime_autosuspend_expiration(struct device *dev);`
- calculate the time when the current autosuspend delay period will expire,
based on power.last_busy and power.autosuspend_delay; if the delay time
is 1000 ms or larger then the expiration time is rounded up to the
nearest second; returns 0 if the delay period has already expired or
power.use_autosuspend isn't set, otherwise returns the expiration time
in jiffies
.. kernel-doc:: include/linux/pm_runtime.h
It is safe to execute the following helper functions from interrupt context:
@ -529,6 +332,8 @@ It is safe to execute the following helper functions from interrupt context:
- pm_request_resume()
- pm_runtime_get_noresume()
- pm_runtime_get()
- pm_runtime_get_if_active()
- pm_runtime_get_if_in_use()
- pm_runtime_put_noidle()
- pm_runtime_put()
- pm_runtime_put_autosuspend()
@ -538,6 +343,9 @@ It is safe to execute the following helper functions from interrupt context:
- pm_runtime_set_active()
- pm_runtime_set_suspended()
- pm_runtime_suspended()
- pm_runtime_active()
- pm_runtime_status_suspended()
- pm_runtime_enabled()
- pm_runtime_mark_last_busy()
- pm_runtime_autosuspend_expiration()
@ -549,16 +357,19 @@ functions may also be used in interrupt context:
- pm_runtime_autosuspend()
- pm_runtime_resume()
- pm_runtime_get_sync()
- pm_runtime_resume_and_get()
- pm_runtime_put_sync()
- pm_runtime_put_sync_suspend()
- pm_runtime_put_sync_autosuspend()
.. _Section 5:
5. Runtime PM Initialization, Device Probing and Removal
========================================================
Initially, the runtime PM is disabled for all devices, which means that the
majority of the runtime PM helper functions described in Section 4 will return
-EAGAIN until pm_runtime_enable() is called for the device.
majority of the runtime PM helper functions described in `Section 4`_ will
return -EACCES until pm_runtime_enable() is called for the device.
In addition to that, the initial runtime PM status of all devices is
'suspended', but it need not reflect the actual physical state of the device.
@ -581,13 +392,13 @@ pm_runtime_set_suspended().
If 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()
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().
Note, 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
pm_runtime_resume_and_get() 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.
@ -615,7 +426,10 @@ removal of their drivers.
Drivers 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.
pm_runtime_dont_use_autosuspend() etc. Alternatively, drivers can use
devm_pm_runtime_enable() during probe, which automatically takes care of
calling pm_runtime_disable() and pm_runtime_dont_use_autosuspend() upon driver
detachment.
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
@ -629,6 +443,8 @@ 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.
.. _Section 6:
6. Runtime PM and System Sleep
==============================
@ -721,74 +537,17 @@ out the following operations:
callback and right after executing the subsystem-level .complete() callback
for it, respectively.
.. _Section 7:
7. Generic subsystem callbacks
==============================
Subsystems 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:
drivers/base/power/generic_ops.c:
`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
`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
`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
`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
`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'
`int pm_generic_resume_noirq(struct device *dev);`
- invoke the ->resume_noirq() callback provided by the driver of this device
`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
`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
`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
`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
`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
`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
`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'
`int pm_generic_restore_noirq(struct device *dev);`
- invoke the ->restore_noirq() callback provided by the device's driver
.. kernel-doc:: drivers/base/power/generic_ops.c
:export:
These functions are the defaults used by the PM core if a subsystem doesn't
provide its own callbacks for ->runtime_idle(), ->runtime_suspend(),
@ -800,8 +559,10 @@ subsystem-level dev_pm_ops structure.
Device 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 similar behaviour with the help of the
DEFINE_RUNTIME_DEV_PM_OPS() defined in include/linux/pm_runtime.h (possibly setting its
last argument to NULL).
DEFINE_RUNTIME_DEV_PM_OPS() macro defined in include/linux/pm_runtime.h
(possibly setting its last argument to NULL).
.. _Section 8:
8. "No-Callback" Devices
========================
@ -839,6 +600,8 @@ 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.
.. _Section 9:
9. Autosuspend, or automatically-delayed suspends
=================================================
@ -864,7 +627,7 @@ registration the length should be controlled by user space, using the
In 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
thereafter they should use the various \*_autosuspend() helper functions
instead of the non-autosuspend counterparts::
Instead of: pm_runtime_suspend use: pm_runtime_autosuspend;
@ -874,7 +637,7 @@ instead of the non-autosuspend counterparts::
Drivers 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). The autosuspend variants of the functions also
account (see pm_runtime_idle()). The autosuspend variants of the functions also
call pm_runtime_mark_last_busy().
Under some circumstances a driver or subsystem may want to prevent a device
@ -917,7 +680,7 @@ Here is a schematic pseudo-code example::
int foo_runtime_suspend(struct device *dev)
{
struct foo_priv foo = container_of(dev, ...);
struct foo_priv *foo = container_of(dev, ...);
int ret = 0;
lock(&foo->private_lock);
@ -933,7 +696,7 @@ Here is a schematic pseudo-code example::
int foo_runtime_resume(struct device *dev)
{
struct foo_priv foo = container_of(dev, ...);
struct foo_priv *foo = container_of(dev, ...);
lock(&foo->private_lock);
/* ... resume the device ... */

View File

@ -5,6 +5,7 @@
#include <linux/cleanup.h>
#include <linux/pm_runtime.h>
#include <linux/workqueue.h>
#include <kunit/device.h>
#include <kunit/test.h>
@ -229,6 +230,61 @@ static void pm_runtime_probe_active_test(struct kunit *test)
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
}
static void pm_runtime_supplier_suspend_test(struct kunit *test)
{
struct device *dev = kunit_device_register(test, DEVICE_NAME);
struct device *supplier = kunit_device_register(test, DEVICE_NAME "_supplier");
struct device *norpm_supplier = kunit_device_register(test, DEVICE_NAME "_norpm_supplier");
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, supplier);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, norpm_supplier);
KUNIT_ASSERT_NOT_NULL(test, device_link_add(dev, supplier, DL_FLAG_PM_RUNTIME));
KUNIT_ASSERT_NOT_NULL(test, device_link_add(dev, norpm_supplier, 0));
pm_runtime_enable(dev);
pm_runtime_enable(supplier);
pm_runtime_enable(norpm_supplier);
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(supplier));
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(norpm_supplier));
/*
* Resume the device and RPM-linked supplier; non-RPM-linked supplier
* stays suspended.
*/
KUNIT_EXPECT_EQ(test, 0, pm_runtime_get_sync(dev));
KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
KUNIT_EXPECT_TRUE(test, pm_runtime_active(supplier));
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(norpm_supplier));
/* Also resume the non-RPM-linked supplier. */
KUNIT_EXPECT_EQ(test, 0, pm_runtime_get_sync(norpm_supplier));
KUNIT_EXPECT_TRUE(test, pm_runtime_active(norpm_supplier));
pm_runtime_put_noidle(norpm_supplier);
KUNIT_EXPECT_TRUE(test, pm_runtime_active(norpm_supplier));
/*
* Suspend device. This should only suspend the device and its
* RPM-linked supplier, not the non-RPM-linked supplier.
*/
KUNIT_EXPECT_EQ(test, 0, pm_runtime_put_sync(dev));
/* Note: supplier suspend is async, so we have to flush the queue. */
flush_workqueue(pm_wq);
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(supplier));
KUNIT_EXPECT_TRUE(test, pm_runtime_active(norpm_supplier));
/* Now suspend non-RPM-linked supplier. */
KUNIT_EXPECT_EQ(test, 0, pm_runtime_suspend(norpm_supplier));
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(supplier));
KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(norpm_supplier));
}
static struct kunit_case pm_runtime_test_cases[] = {
KUNIT_CASE(pm_runtime_depth_test),
KUNIT_CASE(pm_runtime_already_suspended_test),
@ -236,6 +292,7 @@ static struct kunit_case pm_runtime_test_cases[] = {
KUNIT_CASE(pm_runtime_disabled_test),
KUNIT_CASE(pm_runtime_error_test),
KUNIT_CASE(pm_runtime_probe_active_test),
KUNIT_CASE(pm_runtime_supplier_suspend_test),
{}
};

View File

@ -162,14 +162,14 @@ static void pm_runtime_cancel_pending(struct device *dev)
dev->power.request = RPM_REQ_NONE;
}
/*
/**
* pm_runtime_autosuspend_expiration - Get a device's autosuspend-delay expiration time.
* @dev: Device to handle.
*
* Compute the autosuspend-delay expiration time based on the device's
* power.last_busy time. If the delay has already expired or is disabled
* (negative) or the power.use_autosuspend flag isn't set, return 0.
* Otherwise return the expiration time in nanoseconds (adjusted to be nonzero).
* Otherwise return the expiration time in nanoseconds.
*
* This function may be called either with or without dev->power.lock held.
* Either way it can be racy, since power.last_busy may be updated at any time.
@ -200,7 +200,7 @@ static int dev_memalloc_noio(struct device *dev, void *data)
return dev->power.memalloc_noio;
}
/*
/**
* pm_runtime_set_memalloc_noio - Set a device's memalloc_noio flag.
* @dev: Device to handle.
* @enable: True for setting the flag and False for clearing the flag.
@ -361,7 +361,8 @@ static void rpm_suspend_suppliers(struct device *dev)
list_for_each_entry_rcu(link, &dev->links.suppliers, c_node,
device_links_read_lock_held())
pm_request_idle(link->supplier);
if (device_link_test(link, DL_FLAG_PM_RUNTIME))
pm_request_idle(link->supplier);
device_links_read_unlock(idx);
}
@ -1043,6 +1044,11 @@ static enum hrtimer_restart pm_suspend_timer_fn(struct hrtimer *timer)
* pm_schedule_suspend - Set up a timer to submit a suspend request in future.
* @dev: Device to suspend.
* @delay: Time to wait before submitting a suspend request, in milliseconds.
*
* Return:
* * %1: Success; @dev is already %RPM_SUSPENDED.
* * %0: Success.
* * Error code on failure.
*/
int pm_schedule_suspend(struct device *dev, unsigned int delay)
{
@ -1096,16 +1102,15 @@ static int rpm_drop_usage_count(struct device *dev)
}
/**
* __pm_runtime_idle - Entry point for runtime idle operations.
* __pm_runtime_idle - Core entry point for runtime idle operations.
* @dev: Device to send idle notification for.
* @rpmflags: Flag bits.
*
* If the RPM_GET_PUT flag is set, decrement the device's usage count and
* return immediately if it is larger than zero (if it becomes negative, log a
* warning, increment it, and return an error). Then carry out an idle
* notification, either synchronous or asynchronous.
* Carry out an idle check for @dev, either synchronous or asynchronous.
* If %RPM_GET_PUT is set in @rpmflags, decrement the device's usage count
* first, proceeding with idle notification only if the counter drops to zero.
*
* This routine may be called in atomic context if the RPM_ASYNC flag is set,
* This routine may be called in atomic context if the %RPM_ASYNC flag is set,
* or if pm_runtime_irq_safe() has been called.
*/
int __pm_runtime_idle(struct device *dev, int rpmflags)
@ -1134,16 +1139,15 @@ int __pm_runtime_idle(struct device *dev, int rpmflags)
EXPORT_SYMBOL_GPL(__pm_runtime_idle);
/**
* __pm_runtime_suspend - Entry point for runtime put/suspend operations.
* __pm_runtime_suspend - Core entry point for runtime put/suspend operations.
* @dev: Device to suspend.
* @rpmflags: Flag bits.
*
* If the RPM_GET_PUT flag is set, decrement the device's usage count and
* return immediately if it is larger than zero (if it becomes negative, log a
* warning, increment it, and return an error). Then carry out a suspend,
* either synchronous or asynchronous.
* Carry out a suspend operation for @dev, either synchronous or asynchronous.
* If %RPM_GET_PUT is set in @rpmflags, decrement the device's usage count
* first, proceeding with suspend only if the counter drops to zero.
*
* This routine may be called in atomic context if the RPM_ASYNC flag is set,
* This routine may be called in atomic context if the %RPM_ASYNC flag is set,
* or if pm_runtime_irq_safe() has been called.
*/
int __pm_runtime_suspend(struct device *dev, int rpmflags)
@ -1172,14 +1176,15 @@ int __pm_runtime_suspend(struct device *dev, int rpmflags)
EXPORT_SYMBOL_GPL(__pm_runtime_suspend);
/**
* __pm_runtime_resume - Entry point for runtime resume operations.
* __pm_runtime_resume - Core entry point for runtime resume operations.
* @dev: Device to resume.
* @rpmflags: Flag bits.
*
* If the RPM_GET_PUT flag is set, increment the device's usage count. Then
* carry out a resume, either synchronous or asynchronous.
* Carry out a runtime resume operation for @dev, either synchronous or
* asynchronous. If %RPM_GET_PUT is set in @rpmflags, increment the device's
* usage count first, then bring the device to %RPM_ACTIVE state.
*
* This routine may be called in atomic context if the RPM_ASYNC flag is set,
* This routine may be called in atomic context if the %RPM_ASYNC flag is set,
* or if pm_runtime_irq_safe() has been called.
*/
int __pm_runtime_resume(struct device *dev, int rpmflags)
@ -1249,14 +1254,16 @@ static int pm_runtime_get_conditional(struct device *dev, bool ign_usage_count)
}
/**
* pm_runtime_get_if_active - Bump up runtime PM usage counter if the device is
* in active state
* pm_runtime_get_if_active - Conditionally bump up runtime PM usage counter.
* @dev: Target device.
*
* Increment the runtime PM usage counter of @dev if its runtime PM status is
* %RPM_ACTIVE, in which case it returns 1. If the device is in a different
* state, 0 is returned. -EINVAL is returned if runtime PM is disabled for the
* device, in which case also the usage_count will remain unmodified.
* already %RPM_ACTIVE.
*
* Return:
* * %-EINVAL: Runtime PM is disabled for @dev. The usage counter is not incremented.
* * %1: Success; usage counter is incremented.
* * %0: @dev was not active.
*/
int pm_runtime_get_if_active(struct device *dev)
{
@ -1268,17 +1275,15 @@ EXPORT_SYMBOL_GPL(pm_runtime_get_if_active);
* pm_runtime_get_if_in_use - Conditionally bump up runtime PM usage counter.
* @dev: Target device.
*
* Increment the runtime PM usage counter of @dev if its runtime PM status is
* %RPM_ACTIVE and its runtime PM usage counter is greater than 0 or it is not
* ignoring children and its active child count is nonzero. 1 is returned in
* this case.
* Increment the runtime PM usage counter of @dev if it is "in use." A device
* is considered in use if its runtime PM status is %RPM_ACTIVE and its runtime
* PM usage counter is greater than 0, or if it is not ignoring children and
* its active child count is nonzero.
*
* If @dev is in a different state or it is not in use (that is, its usage
* counter is 0, or it is ignoring children, or its active child count is 0),
* 0 is returned.
*
* -EINVAL is returned if runtime PM is disabled for the device, in which case
* also the usage counter of @dev is not updated.
* Return:
* * %-EINVAL: Runtime PM is disabled for @dev. The usage counter is not incremented.
* * %1: Success; usage counter is incremented.
* * %0: @dev was not in use; usage counter is not incremented.
*/
int pm_runtime_get_if_in_use(struct device *dev)
{
@ -1287,7 +1292,7 @@ int pm_runtime_get_if_in_use(struct device *dev)
EXPORT_SYMBOL_GPL(pm_runtime_get_if_in_use);
/**
* __pm_runtime_set_status - Set runtime PM status of a device.
* __pm_runtime_set_status - Set runtime PM status of a device and clear errors.
* @dev: Device to handle.
* @status: New runtime PM status of the device.
*
@ -1306,7 +1311,7 @@ EXPORT_SYMBOL_GPL(pm_runtime_get_if_in_use);
* If @dev has any suppliers (as reflected by device links to them), and @status
* is RPM_ACTIVE, they will be activated upfront and if the activation of one
* of them fails, the status of @dev will be changed to RPM_SUSPENDED (instead
* of the @status value) and the suppliers will be deacticated on exit. The
* of the @status value) and the suppliers will be deactivated on exit. The
* error returned by the failing supplier activation will be returned in that
* case.
*/
@ -1462,11 +1467,13 @@ static void __pm_runtime_barrier(struct device *dev)
* pm_runtime_barrier - Flush pending requests and wait for completions.
* @dev: Device to handle.
*
* Prevent the device from being suspended by incrementing its usage counter and
* if there's a pending resume request for the device, wake the device up.
* Next, make sure that all pending requests for the device have been flushed
* from pm_wq and wait for all runtime PM operations involving the device in
* progress to complete.
* If the device has a pending resume request, resume it synchronously. For all
* other request types, cancel any queued request, and wait for running
* operations to complete.
*
* Note that this is intentionally asymmetric, as it guarantees any queued
* asynchronous resume request will complete, but it may cancel asynchronous
* suspend requests.
*/
void pm_runtime_barrier(struct device *dev)
{
@ -1550,8 +1557,16 @@ void __pm_runtime_disable(struct device *dev, bool check_resume)
EXPORT_SYMBOL_GPL(__pm_runtime_disable);
/**
* pm_runtime_enable - Enable runtime PM of a device.
* pm_runtime_enable - Enable runtime PM for a device.
* @dev: Device to handle.
*
* Enable runtime PM transitions for @dev by decrementing its disable counter.
* Once the counter reaches zero, the PM core is permitted to execute runtime
* PM callbacks for @dev as power conditions change.
*
* Callers should ensure that the device's runtime PM status accurately reflects
* its physical hardware state (via pm_runtime_set_active() or
* pm_runtime_set_suspended()) before enabling runtime PM.
*/
void pm_runtime_enable(struct device *dev)
{
@ -1591,7 +1606,6 @@ static void pm_runtime_set_suspended_action(void *data)
/**
* devm_pm_runtime_set_active_enabled - set_active version of devm_pm_runtime_enable.
*
* @dev: Device to handle.
*/
int devm_pm_runtime_set_active_enabled(struct device *dev)
@ -1618,11 +1632,10 @@ static void pm_runtime_disable_action(void *data)
/**
* devm_pm_runtime_enable - devres-enabled version of pm_runtime_enable.
* @dev: Device to handle.
*
* NOTE: this will also handle calling pm_runtime_dont_use_autosuspend() for
* you at driver exit time if needed.
*
* @dev: Device to handle.
*/
int devm_pm_runtime_enable(struct device *dev)
{
@ -1639,7 +1652,6 @@ static void pm_runtime_put_noidle_action(void *data)
/**
* devm_pm_runtime_get_noresume - devres-enabled version of pm_runtime_get_noresume.
*
* @dev: Device to handle.
*/
int devm_pm_runtime_get_noresume(struct device *dev)
@ -1874,6 +1886,9 @@ void pm_runtime_reinit(struct device *dev)
if (dev->power.runtime_status == RPM_ACTIVE)
pm_runtime_set_suspended(dev);
if (dev->power.use_autosuspend)
pm_runtime_dont_use_autosuspend(dev);
if (dev->power.irq_safe) {
spin_lock_irq(&dev->power.lock);
dev->power.irq_safe = 0;

View File

@ -663,6 +663,99 @@ struct pm_subsys_data {
#define DPM_FLAG_SMART_SUSPEND BIT(2)
#define DPM_FLAG_MAY_SKIP_RESUME BIT(3)
/**
* struct dev_pm_info - Device power management information.
*
* @power_state: Legacy power state (mostly unused in modern kernels).
* @can_wakeup: Device is capable of generating wakeup signals.
* @async_suspend: Device can be suspended and resumed asynchronously.
* @in_dpm_list: Device is on the dpm_list.
* @is_prepared: Device's ->prepare() callback has run successfully.
* @is_suspended: Device is suspended during a system sleep transition.
* @is_noirq_suspended: Device's noirq suspend callback has run successfully.
* @is_late_suspended: Device's late suspend callback has run successfully.
* @no_pm: Device does not participate in power management transitions.
* @early_init: Device was initialized before standard PM initialization.
* @direct_complete: Device can skip suspend/resume callbacks and remain
* runtime-suspended during system sleep.
* @driver_flags: Driver flags (e.g. %DPM_FLAG_SMART_SUSPEND) set at probe time.
* @lock: Spinlock used for synchronizing PM state transitions and runtime PM
* operations.
* @entry: List head for device power management lists.
* @completion: Completion for synchronization during asynchronous system
* suspend/resume.
* @wakeup: Wakeup source object associated with the device.
* @work_in_progress: Asynchronous PM operation in progress.
* @wakeup_path: Device is in the wakeup path or can wake the system up.
* @syscore: Device participates in syscore power management operations.
* @no_pm_callbacks: Device has no PM callbacks; handled by parent or subsystem.
* @smart_suspend: Driver requested smart-suspend behavior.
* @must_resume: Device must be resumed during system resume.
* @may_skip_resume: Set by subsystems to indicate driver resume callbacks may
* be skipped.
* @out_band_wakeup: Out-of-band wakeup is supported.
* @strict_midlayer: Middle layer code does not want callbacks invoked via
* pm_runtime_force_suspend() / pm_runtime_force_resume().
* @should_wakeup: Wakeup flag when system sleep is not enabled.
* @suspend_timer: High-resolution timer used for scheduling delayed runtime
* suspend and autosuspend requests.
* @timer_expires: Timer expiration time in nanoseconds monotonic time
* (runtime PM).
* @work: Work structure used for queuing up requests into pm_wq (runtime PM).
* @wait_queue: Wait queue used if any helper functions need to wait for another
* state change to complete (runtime PM).
* @wakeirq: Dedicated wakeup interrupt for the device.
* @usage_count: Device runtime PM usage counter.
* @child_count: Count of active children of the device (runtime PM).
* @disable_depth: Disable counter for runtime PM (runtime PM is enabled when
* this is 0; initial value is 1).
* @idle_notification: Set if ->runtime_idle() is being executed.
* @request_pending: Set if a work item is queued into pm_wq (runtime PM).
* @deferred_resume: Set if ->runtime_resume() should run as soon as
* ->runtime_suspend() completes.
* @needs_force_resume: Indicates the device was forced into suspend by
* pm_runtime_force_suspend() and must be resumed by
* pm_runtime_force_resume().
* @runtime_auto: User space has allowed the driver to power manage the device
* at runtime via sysfs control attribute; also can be set by
* pm_runtime_allow() or pm_runtime_forbid().
* @ignore_children: If set, the value of child_count is ignored for runtime
* suspend and idle decisions.
* @no_callbacks: Indicates the device does not use runtime PM callbacks.
* @irq_safe: Indicates runtime PM callbacks will be invoked with the spinlock
* held and interrupts disabled.
* @use_autosuspend: Indicates the device driver supports delayed runtime
* autosuspend.
* @timer_autosuspends: Indicates the runtime PM core should attempt an
* autosuspend rather than a normal suspend when the timer expires.
* @memalloc_noio: Indicates memory allocation during runtime PM transitions
* must avoid I/O (GFP_NOIO).
* @links_count: Number of device links that require runtime PM coordination.
* @request: Type of pending runtime PM request (valid if request_pending is
* set).
* @runtime_status: Runtime PM status of the device.
* @last_status: Last status captured before disabling runtime PM, or
* %RPM_BLOCKED / %RPM_INVALID.
* @runtime_error: Fatal error code returned by a failing callback, blocking
* helpers until cleared.
* @autosuspend_delay: Delay time in milliseconds to be used for runtime
* autosuspend.
* @last_busy: Timestamp in nanoseconds when pm_runtime_mark_last_busy() was
* last called. Used in calculating inactivity periods for autosuspend.
* @active_time: Accumulated time in nanoseconds spent in %RPM_ACTIVE state.
* @suspended_time: Accumulated time in nanoseconds spent in %RPM_SUSPENDED
* state.
* @accounting_timestamp: Timestamp in nanoseconds of the last runtime PM state
* accounting update.
* @subsys_data: Subsystem-specific power management data.
* @set_latency_tolerance: Callback for setting latency tolerance.
* @qos: Per-device PM Quality of Service (QoS) constraints.
* @detach_power_off: Indicates device should be detached from PM domain on
* power off.
*
* Device power management information stored in the "power" member of struct
* device.
*/
struct dev_pm_info {
pm_message_t power_state;
bool can_wakeup:1;

View File

@ -137,13 +137,14 @@ static inline void pm_runtime_put_noidle(struct device *dev)
* pm_runtime_suspended - Check whether or not a device is runtime-suspended.
* @dev: Target device.
*
* Return %true if runtime PM is enabled for @dev and its runtime PM status is
* %RPM_SUSPENDED, or %false otherwise.
*
* Note that the return value of this function can only be trusted if it is
* called under the runtime PM lock of @dev or under conditions in which
* runtime PM cannot be either disabled or enabled for @dev and its runtime PM
* status cannot change.
*
* Return:
* * %true: @dev has runtime PM enabled and its status is %RPM_SUSPENDED.
* * %false: Otherwise.
*/
static inline bool pm_runtime_suspended(struct device *dev)
{
@ -155,13 +156,14 @@ static inline bool pm_runtime_suspended(struct device *dev)
* pm_runtime_active - Check whether or not a device is runtime-active.
* @dev: Target device.
*
* Return %true if runtime PM is disabled for @dev or its runtime PM status is
* %RPM_ACTIVE, or %false otherwise.
*
* Note that the return value of this function can only be trusted if it is
* called under the runtime PM lock of @dev or under conditions in which
* runtime PM cannot be either disabled or enabled for @dev and its runtime PM
* status cannot change.
*
* Return:
* * %true: Runtime PM is disabled for @dev or its status is %RPM_ACTIVE.
* * %false: Otherwise.
*/
static inline bool pm_runtime_active(struct device *dev)
{
@ -173,12 +175,13 @@ static inline bool pm_runtime_active(struct device *dev)
* pm_runtime_status_suspended - Check if runtime PM status is "suspended".
* @dev: Target device.
*
* Return %true if the runtime PM status of @dev is %RPM_SUSPENDED, or %false
* otherwise, regardless of whether or not runtime PM has been enabled for @dev.
*
* Note that the return value of this function can only be trusted if it is
* called under the runtime PM lock of @dev or under conditions in which the
* runtime PM status of @dev cannot change.
*
* Return:
* * %true: Runtime PM status of @dev is %RPM_SUSPENDED.
* * %false: Otherwise.
*/
static inline bool pm_runtime_status_suspended(struct device *dev)
{
@ -189,11 +192,13 @@ static inline bool pm_runtime_status_suspended(struct device *dev)
* pm_runtime_enabled - Check if runtime PM is enabled.
* @dev: Target device.
*
* Return %true if runtime PM is enabled for @dev or %false otherwise.
*
* Note that the return value of this function can only be trusted if it is
* called under the runtime PM lock of @dev or under conditions in which
* runtime PM cannot be either disabled or enabled for @dev.
*
* Return:
* * %true: Runtime PM is enabled for @dev.
* * %false: Otherwise.
*/
static inline bool pm_runtime_enabled(struct device *dev)
{
@ -205,6 +210,10 @@ static inline bool pm_runtime_enabled(struct device *dev)
* @dev: Target device.
*
* Do not call this function outside system suspend/resume code paths.
*
* Return:
* * %true: Runtime PM enabling is blocked for @dev.
* * %false: Otherwise.
*/
static inline bool pm_runtime_blocked(struct device *dev)
{
@ -215,8 +224,9 @@ static inline bool pm_runtime_blocked(struct device *dev)
* pm_runtime_has_no_callbacks - Check if runtime PM callbacks may be present.
* @dev: Target device.
*
* Return %true if @dev is a special device without runtime PM callbacks or
* %false otherwise.
* Return:
* * %true: @dev is marked as having no runtime PM callbacks.
* * %false: Otherwise.
*/
static inline bool pm_runtime_has_no_callbacks(struct device *dev)
{
@ -239,9 +249,11 @@ static inline void pm_runtime_mark_last_busy(struct device *dev)
* pm_runtime_is_irq_safe - Check if runtime PM can work in interrupt context.
* @dev: Target device.
*
* Return %true if @dev has been marked as an "IRQ-safe" device (with respect
* to runtime PM), in which case its runtime PM callabcks can be expected to
* work correctly when invoked from interrupt handlers.
* Return:
* * %true: @dev has been marked as an "IRQ-safe" device, in which case its
* runtime PM callbacks can be expected to work correctly from interrupt
* handlers.
* * %false: Otherwise.
*/
static inline bool pm_runtime_is_irq_safe(struct device *dev)
{
@ -340,25 +352,25 @@ static inline int pm_runtime_force_resume(struct device *dev) { return -ENXIO; }
#endif /* CONFIG_PM_SLEEP */
/**
* pm_runtime_idle - Conditionally set up autosuspend of a device or suspend it.
* pm_runtime_idle - Conditionally initiate autosuspend of a device or suspend it.
* @dev: Target device.
*
* Invoke the "idle check" callback of @dev and, depending on its return value,
* set up autosuspend of @dev or suspend it (depending on whether or not
* initiate autosuspend of @dev or suspend it (depending on whether or not
* autosuspend has been enabled for it).
*
* Return:
* * 0: Success.
* * -EINVAL: Runtime PM error.
* * -EACCES: Runtime PM disabled.
* * -EAGAIN: Runtime PM usage counter non-zero, Runtime PM status change
* ongoing or device not in %RPM_ACTIVE state.
* * -EBUSY: Runtime PM child_count non-zero.
* * -EPERM: Device PM QoS resume latency 0.
* * -EINPROGRESS: Suspend already in progress.
* * -ENOSYS: CONFIG_PM not enabled.
* Other values and conditions for the above values are possible as returned by
* Runtime PM idle and suspend callbacks.
* * %0: Success.
* * %-EINVAL: Runtime PM error.
* * %-EACCES: Runtime PM disabled.
* * %-EAGAIN: Runtime PM usage counter non-zero, Runtime PM status change
* ongoing or device not in %RPM_ACTIVE state.
* * %-EBUSY: Runtime PM child_count non-zero.
* * %-EPERM: Device PM QoS resume latency 0.
* * %-EINPROGRESS: Suspend already in progress.
* * %-ENOSYS: %CONFIG_PM not enabled.
* * Other values and conditions for the above values are possible as returned
* by Runtime PM idle and suspend callbacks.
*/
static inline int pm_runtime_idle(struct device *dev)
{
@ -370,17 +382,17 @@ static inline int pm_runtime_idle(struct device *dev)
* @dev: Target device.
*
* Return:
* * 1: Success; device was already suspended.
* * 0: Success.
* * -EINVAL: Runtime PM error.
* * -EACCES: Runtime PM disabled.
* * -EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change
* ongoing.
* * -EBUSY: Runtime PM child_count non-zero.
* * -EPERM: Device PM QoS resume latency 0.
* * -ENOSYS: CONFIG_PM not enabled.
* Other values and conditions for the above values are possible as returned by
* Runtime PM suspend callbacks.
* * %1: Success; device was already suspended.
* * %0: Success.
* * %-EINVAL: Runtime PM error.
* * %-EACCES: Runtime PM disabled.
* * %-EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change
* ongoing.
* * %-EBUSY: Runtime PM child_count non-zero.
* * %-EPERM: Device PM QoS resume latency 0.
* * %-ENOSYS: %CONFIG_PM not enabled.
* * Other values and conditions for the above values are possible as returned
* by Runtime PM suspend callbacks.
*/
static inline int pm_runtime_suspend(struct device *dev)
{
@ -388,26 +400,26 @@ static inline int pm_runtime_suspend(struct device *dev)
}
/**
* pm_runtime_autosuspend - Update the last access time and set up autosuspend
* pm_runtime_autosuspend - Update the last access time and initiate autosuspend
* of a device.
* @dev: Target device.
*
* First update the last access time, then set up autosuspend of @dev or suspend
* it (depending on whether or not autosuspend is enabled for it) without
* engaging its "idle check" callback.
* First update the last access time, then initiate autosuspend of @dev or
* suspend it (depending on whether or not autosuspend is enabled for it)
* without engaging its "idle check" callback.
*
* Return:
* * 1: Success; device was already suspended.
* * 0: Success.
* * -EINVAL: Runtime PM error.
* * -EACCES: Runtime PM disabled.
* * -EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change
* ongoing.
* * -EBUSY: Runtime PM child_count non-zero.
* * -EPERM: Device PM QoS resume latency 0.
* * -ENOSYS: CONFIG_PM not enabled.
* Other values and conditions for the above values are possible as returned by
* Runtime PM suspend callbacks.
* * %1: Success; device was already suspended.
* * %0: Success.
* * %-EINVAL: Runtime PM error.
* * %-EACCES: Runtime PM disabled.
* * %-EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change
* ongoing.
* * %-EBUSY: Runtime PM child_count non-zero.
* * %-EPERM: Device PM QoS resume latency 0.
* * %-ENOSYS: %CONFIG_PM not enabled.
* * Other values and conditions for the above values are possible as returned
* by Runtime PM suspend callbacks.
*/
static inline int pm_runtime_autosuspend(struct device *dev)
{
@ -418,6 +430,11 @@ static inline int pm_runtime_autosuspend(struct device *dev)
/**
* pm_runtime_resume - Resume a device synchronously.
* @dev: Target device.
*
* Return:
* * %1: Success; @dev is already %RPM_ACTIVE.
* * %0: Success.
* * Error code on failure.
*/
static inline int pm_runtime_resume(struct device *dev)
{
@ -425,22 +442,22 @@ static inline int pm_runtime_resume(struct device *dev)
}
/**
* pm_request_idle - Queue up "idle check" execution for a device.
* pm_request_idle - Request an asynchronous idle check for a device.
* @dev: Target device.
*
* Queue up a work item to run an equivalent of pm_runtime_idle() for @dev
* asynchronously.
* Asynchronously request the PM core to evaluate whether @dev can be idled
* or suspended, invoking its ->runtime_idle() callback if provided.
*
* Return:
* * 0: Success.
* * -EINVAL: Runtime PM error.
* * -EACCES: Runtime PM disabled.
* * -EAGAIN: Runtime PM usage counter non-zero, Runtime PM status change
* ongoing or device not in %RPM_ACTIVE state.
* * -EBUSY: Runtime PM child_count non-zero.
* * -EPERM: Device PM QoS resume latency 0.
* * -EINPROGRESS: Suspend already in progress.
* * -ENOSYS: CONFIG_PM not enabled.
* * %0: Success.
* * %-EINVAL: Runtime PM error.
* * %-EACCES: Runtime PM disabled.
* * %-EAGAIN: Runtime PM usage counter non-zero, Runtime PM status change
* ongoing or device not in %RPM_ACTIVE state.
* * %-EBUSY: Runtime PM child_count non-zero.
* * %-EPERM: Device PM QoS resume latency 0.
* * %-EINPROGRESS: Suspend already in progress.
* * %-ENOSYS: %CONFIG_PM not enabled.
*/
static inline int pm_request_idle(struct device *dev)
{
@ -448,8 +465,16 @@ static inline int pm_request_idle(struct device *dev)
}
/**
* pm_request_resume - Queue up runtime-resume of a device.
* pm_request_resume - Request an asynchronous runtime resume for a device.
* @dev: Target device.
*
* Asynchronously request the PM core to resume @dev to %RPM_ACTIVE state
* without modifying its usage counter.
*
* Return:
* * %1: Success; @dev is already %RPM_ACTIVE.
* * %0: Success.
* * Error code on failure.
*/
static inline int pm_request_resume(struct device *dev)
{
@ -457,24 +482,23 @@ static inline int pm_request_resume(struct device *dev)
}
/**
* pm_request_autosuspend - Update the last access time and queue up autosuspend
* of a device.
* pm_request_autosuspend - Update access time and request delayed suspension.
* @dev: Target device.
*
* Update the last access time of a device and queue up a work item to run an
* equivalent pm_runtime_autosuspend() for @dev asynchronously.
* Update the last access time of @dev and asynchronously request the PM core
* to suspend it after the autosuspend delay has elapsed.
*
* Return:
* * 1: Success; device was already suspended.
* * 0: Success.
* * -EINVAL: Runtime PM error.
* * -EACCES: Runtime PM disabled.
* * -EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change
* ongoing.
* * -EBUSY: Runtime PM child_count non-zero.
* * -EPERM: Device PM QoS resume latency 0.
* * -EINPROGRESS: Suspend already in progress.
* * -ENOSYS: CONFIG_PM not enabled.
* * %1: Success; device was already suspended.
* * %0: Success.
* * %-EINVAL: Runtime PM error.
* * %-EACCES: Runtime PM disabled.
* * %-EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change
* ongoing.
* * %-EBUSY: Runtime PM child_count non-zero.
* * %-EPERM: Device PM QoS resume latency 0.
* * %-EINPROGRESS: Suspend already in progress.
* * %-ENOSYS: %CONFIG_PM not enabled.
*/
static inline int pm_request_autosuspend(struct device *dev)
{
@ -483,11 +507,16 @@ static inline int pm_request_autosuspend(struct device *dev)
}
/**
* pm_runtime_get - Bump up usage counter and queue up resume of a device.
* pm_runtime_get - Increment usage counter and request asynchronous resume.
* @dev: Target device.
*
* Bump up the runtime PM usage counter of @dev and queue up a work item to
* carry out runtime-resume of it.
* Increment the runtime PM usage counter of @dev and, if the device is
* currently suspended, asynchronously request the PM core to resume it.
*
* Return:
* * %1: Success; @dev is already %RPM_ACTIVE.
* * %0: Success; runtime-resume was queued.
* * Error code on failure.
*/
static inline int pm_runtime_get(struct device *dev)
{
@ -501,12 +530,15 @@ static inline int pm_runtime_get(struct device *dev)
* Bump up the runtime PM usage counter of @dev and carry out runtime-resume of
* it synchronously.
*
* The possible return values of this function are the same as for
* pm_runtime_resume() and the runtime PM usage counter of @dev remains
* incremented in all cases, even if it returns an error code.
* 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.
* Note that the runtime PM usage counter of @dev remains incremented in all
* cases, even if it returns an error code. Consider using
* pm_runtime_resume_and_get() instead, especially if the return value is
* checked by the caller, as this is likely to result in cleaner code.
*
* Return:
* * %1: Success; @dev is already %RPM_ACTIVE.
* * %0: Success.
* * Error code on failure.
*/
static inline int pm_runtime_get_sync(struct device *dev)
{
@ -531,8 +563,11 @@ static inline int pm_runtime_get_active(struct device *dev, int rpmflags)
* @dev: Target device.
*
* Resume @dev synchronously and if that is successful, increment its runtime
* PM usage counter. Return 0 if the runtime PM usage counter of @dev has been
* incremented or a negative error code otherwise.
* PM usage counter.
*
* Return:
* * %0: Success; @dev is active and its usage counter has been incremented.
* * Negative error code on failure; usage counter is unchanged.
*/
static inline int pm_runtime_resume_and_get(struct device *dev)
{
@ -540,11 +575,12 @@ static inline int pm_runtime_resume_and_get(struct device *dev)
}
/**
* pm_runtime_put - Drop device usage counter and queue up "idle check" if 0.
* pm_runtime_put - Drop device usage counter and request asynchronous idle check.
* @dev: Target device.
*
* Decrement the runtime PM usage counter of @dev and if it turns out to be
* equal to 0, queue up a work item for @dev like in pm_request_idle().
* Decrement the runtime PM usage counter of @dev. If the counter reaches zero
* and the device has no active child dependencies, asynchronously request the
* PM core to idle or suspend the device.
*/
static inline void pm_runtime_put(struct device *dev)
{
@ -559,16 +595,16 @@ static inline void pm_runtime_put(struct device *dev)
* equal to 0, queue up a work item for @dev like in pm_request_autosuspend().
*
* Return:
* * 1: Success. Usage counter dropped to zero, but device was already suspended.
* * 0: Success.
* * -EINVAL: Runtime PM error.
* * -EACCES: Runtime PM disabled.
* * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
* change ongoing.
* * -EBUSY: Runtime PM child_count non-zero.
* * -EPERM: Device PM QoS resume latency 0.
* * -EINPROGRESS: Suspend already in progress.
* * -ENOSYS: CONFIG_PM not enabled.
* * %1: Success. Usage counter dropped to zero, but device was already suspended.
* * %0: Success.
* * %-EINVAL: Runtime PM error.
* * %-EACCES: Runtime PM disabled.
* * %-EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
* change ongoing.
* * %-EBUSY: Runtime PM child_count non-zero.
* * %-EPERM: Device PM QoS resume latency 0.
* * %-EINPROGRESS: Suspend already in progress.
* * %-ENOSYS: %CONFIG_PM not enabled.
*/
static inline int __pm_runtime_put_autosuspend(struct device *dev)
{
@ -576,25 +612,25 @@ static inline int __pm_runtime_put_autosuspend(struct device *dev)
}
/**
* pm_runtime_put_autosuspend - Update the last access time of a device, drop
* its usage counter and queue autosuspend if the usage counter becomes 0.
* pm_runtime_put_autosuspend - Update the last access time, drop usage counter
* and request autosuspend.
* @dev: Target device.
*
* Update the last access time of @dev, decrement runtime PM usage counter of
* @dev and if it turns out to be equal to 0, queue up a work item for @dev like
* in pm_request_autosuspend().
* Update the last access time of @dev and decrement its runtime PM usage
* counter. If the counter drops to zero, asynchronously request the PM core to
* suspend the device once its autosuspend delay has elapsed.
*
* Return:
* * 1: Success. Usage counter dropped to zero, but device was already suspended.
* * 0: Success.
* * -EINVAL: Runtime PM error.
* * -EACCES: Runtime PM disabled.
* * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
* change ongoing.
* * -EBUSY: Runtime PM child_count non-zero.
* * -EPERM: Device PM QoS resume latency 0.
* * -EINPROGRESS: Suspend already in progress.
* * -ENOSYS: CONFIG_PM not enabled.
* * %1: Success. Usage counter dropped to zero, but device was already suspended.
* * %0: Success.
* * %-EINVAL: Runtime PM error.
* * %-EACCES: Runtime PM disabled.
* * %-EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
* change ongoing.
* * %-EBUSY: Runtime PM child_count non-zero.
* * %-EPERM: Device PM QoS resume latency 0.
* * %-EINPROGRESS: Suspend already in progress.
* * %-ENOSYS: %CONFIG_PM not enabled.
*/
static inline int pm_runtime_put_autosuspend(struct device *dev)
{
@ -653,26 +689,28 @@ DEFINE_GUARD_COND(pm_runtime_active_auto, _try_enabled,
* pm_runtime_put_sync - Drop device usage counter and run "idle check" if 0.
* @dev: Target device.
*
* Decrement the runtime PM usage counter of @dev and if it turns out to be
* equal to 0, invoke the "idle check" callback of @dev and, depending on its
* return value, set up autosuspend of @dev or suspend it (depending on whether
* or not autosuspend has been enabled for it).
* Decrement the runtime PM usage counter of @dev. If the counter drops to zero,
* synchronously evaluate and trigger idle/suspend handling.
*
* Note that this does not update the last access time, but it does respect
* existing autosuspend timers. If @dev uses autosuspend, consider using
* pm_runtime_put_sync_autosuspend() or pm_runtime_put_sync_suspend() instead.
*
* The runtime PM usage counter of @dev remains decremented in all cases, even
* if it returns an error code.
*
* Return:
* * 1: Success. Usage counter dropped to zero, but device was already suspended.
* * 0: Success.
* * -EINVAL: Runtime PM error.
* * -EACCES: Runtime PM disabled.
* * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
* change ongoing.
* * -EBUSY: Runtime PM child_count non-zero.
* * -EPERM: Device PM QoS resume latency 0.
* * -ENOSYS: CONFIG_PM not enabled.
* Other values and conditions for the above values are possible as returned by
* Runtime PM suspend callbacks.
* * %1: Success. Usage counter dropped to zero, but device was already suspended.
* * %0: Success.
* * %-EINVAL: Runtime PM error.
* * %-EACCES: Runtime PM disabled.
* * %-EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
* change ongoing.
* * %-EBUSY: Runtime PM child_count non-zero.
* * %-EPERM: Device PM QoS resume latency 0.
* * %-ENOSYS: %CONFIG_PM not enabled.
* * Other values and conditions for the above values are possible as returned
* by Runtime PM suspend callbacks.
*/
static inline int pm_runtime_put_sync(struct device *dev)
{
@ -683,24 +721,28 @@ static inline int pm_runtime_put_sync(struct device *dev)
* pm_runtime_put_sync_suspend - Drop device usage counter and suspend if 0.
* @dev: Target device.
*
* Decrement the runtime PM usage counter of @dev and if it turns out to be
* equal to 0, carry out runtime-suspend of @dev synchronously.
* Decrement the runtime PM usage counter of @dev. If the counter drops to zero,
* suspend the device synchronously.
*
* This API differs from pm_runtime_put_sync() and
* pm_runtime_put_sync_autosuspend() in that it ignores any outstanding
* autosuspend delays.
*
* The runtime PM usage counter of @dev remains decremented in all cases, even
* if it returns an error code.
*
* Return:
* * 1: Success. Usage counter dropped to zero, but device was already suspended.
* * 0: Success.
* * -EINVAL: Runtime PM error.
* * -EACCES: Runtime PM disabled.
* * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
* change ongoing.
* * -EBUSY: Runtime PM child_count non-zero.
* * -EPERM: Device PM QoS resume latency 0.
* * -ENOSYS: CONFIG_PM not enabled.
* Other values and conditions for the above values are possible as returned by
* Runtime PM suspend callbacks.
* * %1: Success. Usage counter dropped to zero, but device was already suspended.
* * %0: Success.
* * %-EINVAL: Runtime PM error.
* * %-EACCES: Runtime PM disabled.
* * %-EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
* change ongoing.
* * %-EBUSY: Runtime PM child_count non-zero.
* * %-EPERM: Device PM QoS resume latency 0.
* * %-ENOSYS: %CONFIG_PM not enabled.
* * Other values and conditions for the above values are possible as returned
* by Runtime PM suspend callbacks.
*/
static inline int pm_runtime_put_sync_suspend(struct device *dev)
{
@ -712,27 +754,28 @@ static inline int pm_runtime_put_sync_suspend(struct device *dev)
* drop device usage counter and autosuspend if 0.
* @dev: Target device.
*
* Update the last access time of @dev, decrement the runtime PM usage counter
* of @dev and if it turns out to be equal to 0, set up autosuspend of @dev or
* suspend it synchronously (depending on whether or not autosuspend has been
* enabled for it).
* Update the last access time of @dev and decrement its runtime PM usage
* counter. If the counter drops to zero, synchronously suspend the device (or
* schedule autosuspend if the delay has not elapsed).
*
* Prefer this API over pm_runtime_put_sync() for devices that use autosuspend.
*
* The runtime PM usage counter of @dev remains decremented in all cases, even
* if it returns an error code.
*
* Return:
* * 1: Success. Usage counter dropped to zero, but device was already suspended.
* * 0: Success.
* * -EINVAL: Runtime PM error.
* * -EACCES: Runtime PM disabled.
* * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
* change ongoing.
* * -EBUSY: Runtime PM child_count non-zero.
* * -EPERM: Device PM QoS resume latency 0.
* * -EINPROGRESS: Suspend already in progress.
* * -ENOSYS: CONFIG_PM not enabled.
* Other values and conditions for the above values are possible as returned by
* Runtime PM suspend callbacks.
* * %1: Success. Usage counter dropped to zero, but device was already suspended.
* * %0: Success.
* * %-EINVAL: Runtime PM error.
* * %-EACCES: Runtime PM disabled.
* * %-EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status
* change ongoing.
* * %-EBUSY: Runtime PM child_count non-zero.
* * %-EPERM: Device PM QoS resume latency 0.
* * %-EINPROGRESS: Suspend already in progress.
* * %-ENOSYS: %CONFIG_PM not enabled.
* * Other values and conditions for the above values are possible as returned
* by Runtime PM suspend callbacks.
*/
static inline int pm_runtime_put_sync_autosuspend(struct device *dev)
{
@ -741,13 +784,22 @@ static inline int pm_runtime_put_sync_autosuspend(struct device *dev)
}
/**
* pm_runtime_set_active - Set runtime PM status to "active".
* pm_runtime_set_active - Set runtime PM status to "active" and clear errors.
* @dev: Target device.
*
* Set the runtime PM status of @dev to %RPM_ACTIVE and ensure that dependencies
* of it will be taken into account.
* Set the runtime PM status of @dev to %RPM_ACTIVE and ensure that its
* dependencies will be taken into account. Also clear the device's error
* status (@dev->power.runtime_error).
*
* It is not valid to call this function for devices with runtime PM enabled.
* It is only valid to call this function if runtime PM is disabled or if
* @dev->power.runtime_error is set.
*
* This will fail if suppliers cannot be resumed, or if the parent is not in
* the correct state.
*
* Return:
* * %0: Success.
* * Error code on failure.
*/
static inline int pm_runtime_set_active(struct device *dev)
{
@ -755,13 +807,19 @@ static inline int pm_runtime_set_active(struct device *dev)
}
/**
* pm_runtime_set_suspended - Set runtime PM status to "suspended".
* pm_runtime_set_suspended - Set runtime PM status to "suspended" and clear errors.
* @dev: Target device.
*
* Set the runtime PM status of @dev to %RPM_SUSPENDED and ensure that
* dependencies of it will be taken into account.
* Set the runtime PM status of @dev to %RPM_SUSPENDED and ensure that its
* dependencies will be taken into account. Also clear the device's error
* status (@dev->power.runtime_error).
*
* It is not valid to call this function for devices with runtime PM enabled.
* It is only valid to call this function if runtime PM is disabled or if
* @dev->power.runtime_error is set.
*
* Return:
* * %0: Success.
* * Error code on failure.
*/
static inline int pm_runtime_set_suspended(struct device *dev)
{
@ -777,9 +835,8 @@ static inline int pm_runtime_set_suspended(struct device *dev)
*
* If the counter is zero when this function runs and there is a pending runtime
* resume request for @dev, it will be resumed. If the counter is still zero at
* that point, all of the pending runtime PM requests for @dev will be canceled
* and all runtime PM operations in progress involving it will be waited for to
* complete.
* that point, this function cancels all pending runtime PM requests for @dev
* and waits for its runtime PM operations to complete (if any).
*
* For each invocation of this function for @dev, there must be a matching
* pm_runtime_enable() call, so that runtime PM is eventually enabled for it