mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
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:
commit
dc2021eae5
|
|
@ -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 ... */
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user