pm: Disable device pm per power state

Make it possible to disble device power management individually per
power state.  This allows targets tuning which states should
(and which should not) trigger device power management.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
This commit is contained in:
Flavio Ceolin 2023-07-28 13:39:52 -07:00 committed by Anas Nashif
commit 2f99ff51cc
5 changed files with 23 additions and 4 deletions

View file

@ -31,3 +31,9 @@ properties:
type: int type: int
description: | description: |
Worst case latency in microseconds required to exit the idle state. Worst case latency in microseconds required to exit the idle state.
zephyr,pm-device-disabled:
type: boolean
description: |
Disable system managed device power management for this state. When set,
the power management subsystem will not suspend devices before entering
this state.

View file

@ -134,12 +134,22 @@ struct pm_state_info {
* substate-id = <2>; * substate-id = <2>;
* min-residency-us = <20000>; * min-residency-us = <20000>;
* exit-latency-us = <200>; * exit-latency-us = <200>;
* zephyr,pm-device-disabled;
* }; * };
* }; * };
* @endcode * @endcode
*/ */
uint8_t substate_id; uint8_t substate_id;
/**
* Whether or not this state triggers device power management.
*
* When this property is false the power management subsystem
* will suspend devices before entering this state and will
* properly resume them when leaving it.
*/
bool pm_device_disabled;
/** /**
* Minimum residency duration in microseconds. It is the minimum * Minimum residency duration in microseconds. It is the minimum
* time for a given idle state to be worthwhile energywise. * time for a given idle state to be worthwhile energywise.
@ -209,6 +219,7 @@ struct pm_state_info {
.substate_id = DT_PROP_OR(node_id, substate_id, 0), \ .substate_id = DT_PROP_OR(node_id, substate_id, 0), \
.min_residency_us = DT_PROP_OR(node_id, min_residency_us, 0), \ .min_residency_us = DT_PROP_OR(node_id, min_residency_us, 0), \
.exit_latency_us = DT_PROP_OR(node_id, exit_latency_us, 0), \ .exit_latency_us = DT_PROP_OR(node_id, exit_latency_us, 0), \
.pm_device_disabled = DT_PROP(node_id, zephyr_pm_device_disabled), \
} }
/** /**
@ -260,6 +271,7 @@ struct pm_state_info {
* power-state-name = "suspend-to-ram"; * power-state-name = "suspend-to-ram";
* min-residency-us = <50000>; * min-residency-us = <50000>;
* exit-latency-us = <500>; * exit-latency-us = <500>;
* zephyr,pm-device-disabled;
* }; * };
* }; * };
* }; * };

View file

@ -205,7 +205,8 @@ bool pm_system_suspend(int32_t ticks)
#if defined(CONFIG_PM_DEVICE) && !defined(CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE) #if defined(CONFIG_PM_DEVICE) && !defined(CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE)
if (atomic_sub(&_cpus_active, 1) == 1) { if (atomic_sub(&_cpus_active, 1) == 1) {
if (z_cpus_pm_state[id].state != PM_STATE_RUNTIME_IDLE) { if ((z_cpus_pm_state[id].state != PM_STATE_RUNTIME_IDLE) &&
!z_cpus_pm_state[id].pm_device_disabled) {
if (pm_suspend_devices()) { if (pm_suspend_devices()) {
pm_resume_devices(); pm_resume_devices();
z_cpus_pm_state[id].state = PM_STATE_ACTIVE; z_cpus_pm_state[id].state = PM_STATE_ACTIVE;

View file

@ -61,7 +61,7 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks) const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks)
{ {
static const struct pm_state_info state = { static const struct pm_state_info state = {
.state = PM_STATE_SUSPEND_TO_RAM .state = PM_STATE_SUSPEND_TO_RAM,
}; };
ARG_UNUSED(cpu); ARG_UNUSED(cpu);

View file

@ -11,8 +11,8 @@
/* Last state has not declared a minimum residency, so it should be /* Last state has not declared a minimum residency, so it should be
* set the default 0 value * set the default 0 value
*/ */
static struct pm_state_info infos[] = {{PM_STATE_SUSPEND_TO_IDLE, 0, 10000, 100}, static struct pm_state_info infos[] = {{PM_STATE_SUSPEND_TO_IDLE, 0, false, 10000, 100},
{PM_STATE_SUSPEND_TO_RAM, 0, 50000, 500}, {PM_STATE_STANDBY, 0, 0}}; {PM_STATE_SUSPEND_TO_RAM, 0, false, 50000, 500}, {PM_STATE_STANDBY, 0, false, 0}};
static enum pm_state states[] = {PM_STATE_SUSPEND_TO_IDLE, static enum pm_state states[] = {PM_STATE_SUSPEND_TO_IDLE,
PM_STATE_SUSPEND_TO_RAM, PM_STATE_STANDBY}; PM_STATE_SUSPEND_TO_RAM, PM_STATE_STANDBY};
static enum pm_state wrong_states[] = {PM_STATE_SUSPEND_TO_DISK, static enum pm_state wrong_states[] = {PM_STATE_SUSPEND_TO_DISK,