pm: Introduce CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE

Sometimes we want to entirely decouple the system PM from the device PM,
leaving the devices to manage its own power states using the runtime PM.

This is currently not possible because the suspend / resume code path is
triggering the device PM hooks even when the runtime PM is enabled.

Introduce a new PM_DEVICE_RUNTIME_EXCLUSIVE symbol to allow the platform
to skip the device PM triggers on suspend / resume.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
This commit is contained in:
Carlo Caione 2022-06-15 11:36:53 +02:00 committed by Carles Cufí
parent e757f188c8
commit 1608c8adba
3 changed files with 14 additions and 3 deletions

View file

@ -103,6 +103,14 @@ config PM_DEVICE_RUNTIME
enabled, devices can be suspended or resumed based on the device
usage even while the CPU or system is running.
config PM_DEVICE_RUNTIME_EXCLUSIVE
depends on PM_DEVICE_RUNTIME
bool "Use only on Runtime Power Management on system suspend / resume"
default y
help
On system suspend / resume do not trigger the Device PM hooks but
only rely on Runtime PM to manage the devices power states.
endif # PM_DEVICE
endmenu

View file

@ -43,7 +43,7 @@ static struct pm_state_info z_cpus_pm_forced_state[] = {
static struct k_spinlock pm_forced_state_lock;
#ifdef CONFIG_PM_DEVICE
#if defined(CONFIG_PM_DEVICE) && !defined(CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE)
static atomic_t z_cpus_active = ATOMIC_INIT(CONFIG_MP_NUM_CPUS);
#endif
static struct k_spinlock pm_notifier_lock;
@ -52,6 +52,7 @@ static struct k_spinlock pm_notifier_lock;
#ifdef CONFIG_PM_DEVICE
extern const struct device *__pm_device_slots_start[];
#if !defined(CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE)
/* Number of devices successfully suspended. */
static size_t num_susp;
@ -105,6 +106,7 @@ static void pm_resume_devices(void)
num_susp = 0;
}
#endif /* !CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE */
#endif /* CONFIG_PM_DEVICE */
static inline void pm_exit_pos_ops(struct pm_state_info *info)
@ -238,7 +240,7 @@ bool pm_system_suspend(int32_t ticks)
true);
}
#if CONFIG_PM_DEVICE
#if defined(CONFIG_PM_DEVICE) && !defined(CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE)
if ((z_cpus_pm_state[id].state != PM_STATE_RUNTIME_IDLE) &&
(atomic_sub(&z_cpus_active, 1) == 1)) {
if (pm_suspend_devices()) {
@ -269,7 +271,7 @@ bool pm_system_suspend(int32_t ticks)
pm_stats_stop();
/* Wake up sequence starts here */
#if CONFIG_PM_DEVICE
#if defined(CONFIG_PM_DEVICE) && !defined(CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE)
if (atomic_add(&z_cpus_active, 1) == 0) {
pm_resume_devices();
}

View file

@ -4,3 +4,4 @@ CONFIG_PM_DEVICE=y
CONFIG_PM_DEVICE_RUNTIME=y
CONFIG_PM_POLICY_CUSTOM=y
CONFIG_MP_NUM_CPUS=1
CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE=n