Some devices, e.g. SoC level devices like I2C peripheral, can never be
powerd off as they are always energized. Such devices can only go from an
active state or to a low power state (suspended). Allow them to simply
return -ENOTSUP when called with TURN_ON (or TURN_OFF).
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Refactor pm_device_driver_init code to keep the normal execution path
inline and the early exit branches at a single indentation, this is
commonly done throughout the code base.
Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
This API is not widely used and it is actually broken since device
runtime power management is not checking it when suspending and
resuming.
On top of that, this API is very close to pm_device_busy* API,
close enough to consolidate in only one API.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
In many cases suspending or resuming of a device is limited to
just a few register writes. Current solution assumes that those
operations may be blocking, asynchronous and take a lot of time.
Due to this assumption runtime PM API cannot be effectively used
from the interrupt context. Zephyr has few driver APIs which
can be used from an interrupt context and now use of runtime PM
is limited in those cases.
Patch introduces a new type of PM device - synchronous PM. If
device is specified as capable of synchronous PM operations then
device runtime getting and putting is executed in the critical
section. In that case, runtime API can be used from an interrupt
context. Additionally, this approach reduces RAM needed for
PM device (104 -> 20 bytes of RAM on ARM Cortex-M).
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Enable the automatic power domain management to release the domain as
many times as it was claimed, instead of only once.
This fixes the domain being permanently enabled if the supported device
is claimed more than once.
Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
Adds a helper function for initializing devices into the expected power
state, through the devices `pm_device_action_cb_t`. This eliminates code
duplication between the init functions and the PM callback.
The expected device states in order of priority are:
* No power applied to device, `OFF`
* `zephyr,pm-device-runtime-auto` enabled, `SUSPEND`
* Otherwise, `ACTIVE`
Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
Adds a helper function for initializing devices into the expected power
state, through the devices `pm_device_action_cb_t`. This eliminates code
duplication between the init functions and the PM callback.
The expected device states in order of priority are:
* No power applied to device, `OFF`
* `zephyr,pm-device-runtime-auto` enabled, `SUSPEND`
* Otherwise, `ACTIVE`
Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
Device dependencies are not always required, so make them optional via
CONFIG_DEVICE_DEPS. When enabled, the gen_device_deps script will run so
that dependencies are collected and part of the final image. Related
APIs will be also made available. Since device dependencies are used in
just a few places (power domains), disable the feature by default. When
not enabled, a second linking pass will not be required.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Rename the Kconfig option to be in line with recent renamings in device
handles/dependencies.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Rename struct device `handles` member to `deps`, in line with previous
renamings in the device API.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Rename multiple internal device macros to use the DEVICE_DEPS naming, so
that it is clear they belong to the device dependencies APIs.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
These macros are used internally by the device dependencies functions.
There's no need to expose them publicly, so prefix them with Z_ and add
them under INTERNAL_HIDDEN docs section.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Until now iterable sections APIs have been part of the toolchain
(common) headers. They are not strictly related to a toolchain, they
just rely on linker providing support for sections. Most files relied on
indirect includes to access the API, now, it is included as needed.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Use iterable sections to handle devices list. This simplifies devices
implementation by using standard APIs.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Rework the implementation of `pm_device_children_action_run` to use the
common `device_supported_foreach` iterator.
Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
Store errors powering up devices in a flag in the PM struct. This is
required as the `pm->state` variable always transitions to
`PM_DEVICE_STATE_SUSPENDED`, even when `PM_DEVICE_ACTION_TURN_ON`
returns an error. Marking the transition as failed will allow the
transition logic in `pm_device_runtime_get` to detect the problem.
Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
Update the internal power state tracking for `PM_DEVICE_ACTION_TURN_ON`
and `PM_DEVICE_ACTION_TURN_OFF` even when the transition function fails.
Just because the driver couldn't perform some action does not mean the
device is still powered/unpowered.
Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
Add state checking to every transition to ensure that the device is in
the state we think it is before running the action.
Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
PM_DEVICE_ACTION_FORCE_SUSPEND has been equivalent to
PM_DEVICE_ACTION_SUSPEND for a while. Release notes for Zephyr 2.7
mentioned its removal (see 76702e8ff3) but
for some reason it was kept.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Adds a helper function to query whether a device is currently powered.
This can be used to determine if the chip can be initialised now, or if
it needs to be deferred.
Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
In order to bring consistency in-tree, migrate all subsystems code to
the new prefix <zephyr/...>. Note that the conversion has been scripted,
refer to zephyrproject-rtos#45388 for more details.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Add API to add devices to a power domain in runtime. The number of
devices that can be added is defined in build time.
The script gen_handles.py will check the number defined in
`CONFIG_PM_DEVICE_POWER_DOMAIN_DYNAMIC` to resize the handles vector,
adding empty slots in the supported sector to be used later.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Remove deprecated functions in the previous release. Note that PM API is
not marked as stable.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
When a device returns -ENOTSUP for actions TURN_ON or TURN_OFF
the device state still has to be updated since the domain will
cut or restore the energy.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Adds a helper for devices to check if they are on a power-domain or not.
Drivers can use this information to determine if they will be turned on
at some point in the future, or if they are already turned on.
Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
Adds a helper function for running PM actions on child devices. A custom
implementation of `device_supported_foreach` is used as we don't
necessarily want the early exit behaviour of that function in the power
domain context.
The early exit behaviour can be obained through a return value in the
failure callback if that is desired.
Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
Adds `PM_DEVICE_ACTION_TURN_ON` to transition from `PM_DEVICE_STATE_OFF`
to `PM_DEVICE_STATE_SUSPENDED`.
Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
Similar what is done in pm_device_state_set, checking if the power
state for a given device in pm_device_action_run is locked.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Add a new API to lock a device pm state.
When the device has its state locked, the kernel will no longer
suspend / resume devices when the system goes to sleep and device
runtime power management operations will fail.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Devices PM callback receive an action and not a state. Add a new API
that receives an action instead of a state.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
It is well known that PM subsystem has never been optimized in terms of
resource usage. The situation is particularly bad in case the PM runtime
API is enabled. What this patch does is to move the responsability of PM
resource definition to the device like this:
- Device is responsible to define PM resources, using a new set of
macros: PM_DEVICE_*DEFINE().
- DEVICE_*DEFINE macro accepts a reference to the device PM state, which
can be obtained using PM_DEVICE_*REF() set of macros. This
allows device to initialize the dev->pm reference.
This method decouples a bit more PM from devices since devices just keep
a reference to the device PM state. It also means that future PM changes
will have less chances to impact all devices, but only devices that
support PM.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This patch refactors the runtime API to make it more clear and simple.
Relevant changes:
- API uses the action callback in a direct manner, avoiding unnecessary
overhead.
- API documentation has been improved to include detailed return error
codes.
- pm_runtime_disable() is now synchronous (to simplify possible error
paths) and returns error in case it fails. It is also safe to disable
in pre-kernel now.
- pm_runtime_put(_async)() will return -EALREADY if called with usage
count at zero (result of an unbalanced get/put call sequence)
- A transitional state has been added back. This makes code more
readable, and avoids using atomics (not required).
TODO:
- Solve in a better manner the asynchronous suspend error path (now
"solved" using asserts).
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Move functions around so it is not necessary to keep a header
that with functions declaration that is just used in one single
place.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
List of improvements:
- The PM logging module was only available if CONFIG_PM=y, however, it
was also used by Device PM (which can be selected without PM). A new
logging module has been created for Device PM.
- Log level is passed to LOG_MODULE_(DECLARE|REGISTER)
- Logger name has been adjusted to `pm` (was `power`)
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
As discussed in issues/38619, this commit aims to simplify device
power management. It was removed PM_DEVICE_SATE_LOW_POWER.
The power subsystem now doesn't need to figure out which device state to
use of a given system power state. It just suspend and resume devices.
Devices now just need to respond to ACTIVE and SUSPEND and OFF actions
and they are free to use any particular substate they have when the
subsystem asks to suspend. They also don't need to worry about states
transitions (unless they have multiple substates) because the system
will just request them to suspend if they are active and vice-versa.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
rebase
- Rename to "action" to make its purpose more clear
- Use the _cb suffix to align with naming used for callbacks in other
areas.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Accessing members from pm_device improves code readability, since it
removes dev-> from most accesses.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Some includes were already performed by the device(_runtime).h header/s,
others like were not necessary.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
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>
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>
_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>