If a driver doesn't support PM, as indicated by setting the
pm_control_fn parameter to NULL, no need to manage busy or wakeup state.
This also prepares the PM support for issue #39286, which will allocate
PM structures only for the devices that request it.
Signed-off-by: Keith Short <keithshort@google.com>
Devices need to be resumed in the reverse order they are suspended.
e.g: devA +---> devB ---> devD
|
+---> devC
They are initialized in the following order, devA -> devB -> devC ->
devD, and suspended starting from the end of the list, devD -> devC ->
devB -> devA. When they are suspended they are temporary put in a list
that is used later to resume them.
This list has to be iterated from the end to the beginning, otherwise a
device may be resumed before its parent.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Previously stats were kept in a single static but would be updated by an
idle thread per cpu core. Stats/debug info is now kept per cpu core.
Signed-off-by: Tom Burdick <thomas.burdick@intel.com>
According to the state documentation, this state does not need to handle
devices:
> Runtime idle is a system sleep state in which all of the cores enter
deepest possible idle state and wait for interrupts, no requirements for
the devices, leaving them at the states where they are.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
In order to be able to make a "choice" from any other
Kconfig.defconfig (-ish) file, the choice needs to be named.
This commit names a few choices.
Signed-off-by: Emil Lindqvist <emil@lindq.gr>
Implement constraint API as weak symbols so applications or platform
can override them. Constraints are a high-level abstraction to inhibit
the power subsystem of using certain power states. Some platforms can
have their own way to set/release constraints in their drivers that
are not part of Zephyr's code base.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
PM_DEVICE_STATE_RESUMING and PM_DEVICE_STATE_SUSPENDING
are transitional states and are only used in device runtime. Remove it
and use device flag to keep track of a transition.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
The runtime API is referenced count and uses a uint32_t.
Avoid underflow when dealing with put requests.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Return 0 in cases where the request does not trigger a device state
change, only incremented or to decremented the reference count.
Fixes#37821
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Suspend devices when the system goes to STATE_SOFT_OFF.
This state was not triggering any device power management. This should
at least suspend devices as it is done for SUSPEND_TO_RAM and
SUSPEND_TO_DISK.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
_pm_devices, pm_suspend_devices, pm_low_power_devices and
pm_resume_devices are only used if CONFIG_PM_DEVICE is defined and not
CONFIG_PM.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Introduce a new API to allow devices capable of wake up the system
register themselves was wake up sources. This permits applications to
select the most appropriate way to wake up the system when it is
suspended.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Just using a simple atomic for flags instead of using an array.
While is neat using ATOMIC_DEFINE for future proof. The reality is
that it brings some problem for the wakeup source implementation
that needs to statically initialize it during the device definition.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Use the internal function z_device_get_all_static helper function
instead of using __device_start and __device_end directly. Some other
minor adjustments have been done (e.g. reduce *dev scope to the for
loop). An issue on the range of the for loop in _pm_devices has also
been fixed.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
The shared _pm_devices function used should_suspend check function to
see if a device had to be suspended or not. Some of the logic inside
that function was redundant since the pm_device_state_set function
already performs similar checks, e.g. if the device is already at the
given state or the state transition is not supported it will return
error codes appropriately.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
A device that is turned off should not be suspended. A device that has
been turned off can only be resumed. This action is currently forbidden
by the "should_suspend" function in the device PM code.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Add support for FORCE_SUSPEND and LOW_POWER actions. Even though these
actions have no clear meaning, they are added for compatibility until
their associated states are discussed. Their usage in new code should be
discouraged until the associated states are clarified.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
If a device does not support, for example, the suspend action the
subsystem should just ignore the device.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Instead of passing target states, use actions for device PM control.
Actions represent better the meaning of the callback argument.
Furthermore, they are more future proof as they can be suitable for
other PM actions that have no direct mapping to a state. If we compare
with Linux, we could have a multi-stage suspend/resume. Such scenario
would not have a good mapping when using target states.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
The verb tense for the suspended state was not consistent with other
states. The likely reason: state was being used as a command/action.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
If the device is already at the given state, do not call the device PM
control function. This makes sure that devices are only called to change
from one state to another.
Even though asynchronous device PM is completely broken, transitional
states are considered too.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Improve the docstrings of the pm_device_state_set function and change to
shorter argument variable names.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Since the state is no longer modified by the device PM callback, just
use the state value.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
The device PM subsystem already holds the device state, so there is no
need to keep duplicates inside the device. The pm_device_state_get has
been refactored to just return the device state. Note that this is still
not safe, but the same applied to the previous implementation. This
problem will be addressed later.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Busy check APIs now return boolean type. Due to that change, the
function names have also been adjusted. The common name pattern for
boolean check type APIs is "PREFIX_is_CONDITION". For example,
"pm_device_is_busy". pm_device_busy_check has been renamed to
pm_device_is_busy and pm_device_any_busy_check to pm_device_is_any_busy.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
- Use an enum for the available flags
- Use ATOMIC_DEFINE macro to declare the flag bit field
- Improve naming
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
The following device busy APIs:
- device_busy_set()
- device_busy_clear()
- device_busy_check()
- device_any_busy_check()
were used for device PM, so they have been moved to the pm subsystem.
This means they are now prefixed with `pm_` and are defined in
`pm/device.h`.
If device PM is not enabled dummy functions are now provided that do
nothing or return `-ENOSYS`, meaning that the functionality is not
available.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
SoC hooks are defined as weak functions for the case where they are
not implemented by a SoC. The problem that may happen is when an
application define it as weak as well. In this case, no compilation
error is issued but the version that will be used depends on the build
order. Just remove the weak placeholder implementation.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
cc13x2_cc26x2 had its own power policy that was implementing the same
logic available in the default residency policy. Also, this policy was
unnecessarily setting up a timeout to wakeup the system. This is not
necessary, the power subsystem takes care of this.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
The callback is not used anymore, so just delete it from the pm_control
callback signature.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
The callback used by the device runtime PM can be easily replaced by a
simple state set after calling the state set/get calls. Broadcast logic
is simplified too, leading to the same previous behavior.
Since this is the only place where this callback was used, it can now be
removed from all devices and so pm_control callback signature
simplified.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Move all PM_DEVICE_STATE_* definitions to an enum. The
PM_DEVICE_STATE_SET and PM_DEVICE_STATE_GET definitions have been kept
out of the enum since they do not represent any state. However, their
name has not been changed since they will be removed soon.
All drivers and tests have been adjusted accordingly.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Policy manager header has to be in the include for applications.
Also it had several function prototypes that are not part of the policy.
These functions were moved from the policy header to a dedicated private
header.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
When a device is defined a new pointer to a device will be created in
the "z_pm_device_slots" region, effectively creating a device array with
the same size as the number of system devices. This array is then used
by the device PM subsystem to keep track of suspended devices during
power transitions.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
It was just making the code hard to read. Also it was not following
the code guideline because the type was not telling us the sign
and size.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
z_pm_core_devices was hack to set some priority between devices. It
was doing it hardcoding some devices that were the first to bring up
and the last to power down. Remove it and use the same list used to
initialize devices.
Fixes#34214
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
pm_device_runtime_state_set takes care of the check the reference count
and take the right action. It is not necessary check it in
pm_device_request.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Assuming that pm_device_state_set is synchronous it is possible to
simplify the mutex usage. Now there are two places where the lock is
held, one in the worqueue handler and other in pm_device_request to
cover the synchronous path. It is no longer needed held the lock in the
pm_device_state_set callback and not needed to wait on the conditional
variable after set the state in the synchronous path.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Most APIs have the default synchronous and an asynchronous version
with the sufix _async because that is the most common use.
All devices in tree right now are using the synchronous version, so
just change it to be consistent with the rest of the system.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Since we are using mutex to protect critical sections and mutexes are
reentrant, it is possible to get rid of atomic for the state because
we can lock the mutex in device_pm_callback.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Protect critical sections using the mutex.
The mutex is required to use the conditional variable and since we
need to atomically check the pm state and the workqueue before wait
the condition, it is necessary to protect them using the same mutex.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>