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>
Aligning with the rest of PM API, replace pm_power_state_exit_post_ops
with pm_state_exit_post_ops.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
A common pattern here was to take the work item as the subfield of a
containing object. But the contained field is not a k_work, it's a
k_work_delayable.
Things were working only because the work field was first, so the
pointers had the same value. Do things right and fix things to
produce correct code if/when that field ever moves within delayable.
Signed-off-by: Yong Cong Sin <yongcong.sin@gmail.com>
Now that the forced flag is cleared with the kernel locked in the
suspend path, we need to clear it out when the suspend process fails.
This is being done before jump to the end label because in the
successful path the flag is already cleared.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
The "state forced" flag has to be cleared with the scheduler locked,
otherwise the idle thread can be scheduled out without clear it and
the next call to force a state will fail.
Fixes#41911
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
The CPU power states were declared with a typecast array literal,
which is a GNU extension.
Unfortunately some compilers (xt-xcc even in very recent versions,
when used with -fdata-sections) will die with a compiler error when
those rvalues are used in an expression that also takes their address,
e.g.:
/* this all by itself crashes xcc -fdata-sections */
int *foo = (int[]){0};
Declare the array elments in two steps, making the code standard C.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
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>
Add a function to tell runtime power management that the device is
starting in the off state instead of active or suspended.
Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
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>
Add a Kconfig symbol to enable/disable power domain on Zephyr.
Disabling power domain save some memory / space.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Add support for power domains on Zephyr. Power domains are implemented
as simple devices so they can use the existent Zephyr API, for resume
and suspend sync and async and also reference count.
The pm subsystem will ensure that domains are resumed before and
suspended after devices using them. For device runtime power
management, every time the device is got or released the same actions
is done to the domain it belongs.
As domains are implemented as simple devices, it is totally acceptable
a domain belongs to another domain.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
The PM state code is in practice useless when no cpus are defined in DT,
so require this node to be defined.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Return a constant reference to the next state instead of a copy of
struct pm_state_info. When the next state should be active, just return
NULL. Struct copying should be in general avoided, specially in code
paths executed frequently as is this one.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Use the pm_state_cpu_get_all API to obtain the list of available CPU
states. This changes reduces the need for non-interesting code within
the policy codebase.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
The usage count and device power state has to be restored when the
device action callback fails in the async operation. Otherwise it will
lead to an inconsistent state.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
The pm_device_runtime_enable did not suspend devices, so it assumed that
the device was in a physically suspended state. This change makes sure
that device is left in a suspended state if the device is initially
active.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
In case runtime PM is not enabled (or not built-in), the get/put
functions always return 0 (instead of -ENOTSUP/-ENOSYS). When runtime PM
is disabled, a device is left into active state. Similarly, when device
runtime PM is not built-in, it is safe to assume that a device will
be active when it is called. If a user implements a custom solution, it
is its responsability to make sure that a device is active when using
it. For all these reasons, the -ENOTSUP/-ENOSYS are error codes that
should always be ignored by devices using get/put, since in practice it
means that: device is active, function is a no-op. The example below
illustrates how error handling is simplified:
```c
/* before: safe to ignore -ENOSYS/-ENOTSUP since device is active (we
* can continue)
*/
ret = pm_device_runtime_get(dev);
if ((ret < 0) && (ret != -ENOSYS) && (ret != -ENOTSUP)) {
return ret;
}
/* now */
ret = pm_device_runtime_get(dev);
if (ret < 0) {
return ret;
}
```
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Incorrect address was being taken for cpus_states variable, causing
transition to low power modes to fail with an assertion (since the data
in the pm_state_info struct is no longer valid). Fix the address.
Fixes#41244
Signed-off-by: Daniel DeGrasse <daniel.degrasse@nxp.com>
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>
Kconfig choice allows to set a default, so there is no need for an extra
hidden Kconfig option.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Check that minimum residency time is greater than exit latency time for
all CPUs power states at compile time.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
The values contained by the array are const, and number of states is
usually far below 255, so uint8_t can be used.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Change the function pm_device_runtime_enable() to return 0 on
success or an error code in case of error.
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>
Since enabling runtime pm on a device sets the device state to
suspended. The usage count has to be zeroed otherwise we may
have an inconsistency.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
It is not possible to rely on pm->dev to do lazy initialization of
some components. For example, in the follow sequence of commands:
1 - pm_device_runtime_enable()
pm->state == PM_DEVICE_STATE_SUSPENDED;
2 - pm_device_runtime_disable()
pm->state == PM_DEVICE_STATE_ACTIVE;
3 - pm_device_runtime_enable()
pm->state == PM_DEVICE_STATE_ACTIVE
After the first time pm_device_runtime_enable(), the device state will
be suspended, but after the second time this function executes the state
will be active. That is not consistent.
It is just easier to remove the branch check and always set those
fields for the sake of consistent.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Although we are declaring `pm->enable`as bitfield, it ends up using
more memory due memory alignment.
Since we already have an atomic variable for device flags, this commit
adds a new flag to indicates whether or not device runtime is enabled.
Doing it we are saving some extra bits and avoiding need to lock the
mutex in several situations since we can atomically check if pm
runtime is enabled on a given device.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Rename PM_STATE_DT_ITEMS_LEN to DT_NUM_CPU_POWER_STATES to make its
purpose more clear. This macro could be made part of a Devicetree API
for PM in the future.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>