Skip to content

Commit 212b218

Browse files
Ramakrishna Pallalanashif
Ramakrishna Pallala
authored andcommitted
power: Add API's to enable/disable System PM states
Add API's to enable/disable System PM states so that an an application can enable/disable system from entering certain Low Power states. Signed-off-by: Ramakrishna Pallala <[email protected]>
1 parent dc7e8a9 commit 212b218

File tree

5 files changed

+118
-0
lines changed

5 files changed

+118
-0
lines changed

subsys/power/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ zephyr_sources(
22
power.c
33
device.c
44
)
5+
zephyr_sources_ifdef(CONFIG_PM_CONTROL_STATE_LOCK pm_ctrl.c)
56
add_subdirectory(policy)

subsys/power/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ menu "OS Power Management"
44

55
source "subsys/power/policy/Kconfig"
66

7+
config PM_CONTROL_STATE_LOCK
8+
bool "Enable PM state locking capability"
9+
help
10+
Enable OS Power Management state locking capability
11+
if any application wants to temporarily disable certain
12+
System Low Power states while doing any critical work
13+
or needs quick response from hardware resources.
14+
715
config PM_CONTROL_OS_DEBUG
816
bool "Enable OS Power Management debug hooks"
917
help

subsys/power/pm_ctrl.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright (c) 2018 Intel Corporation.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr.h>
8+
#include <string.h>
9+
#include <soc.h>
10+
#include <device.h>
11+
#include <atomic.h>
12+
#include "policy/pm_policy.h"
13+
14+
#define LOG_LEVEL CONFIG_PM_LOG_LEVEL /* From power module Kconfig */
15+
#include <logging/log.h>
16+
LOG_MODULE_DECLARE(power);
17+
18+
struct pm_ctrl_info {
19+
int pm_state;
20+
atomic_t count;
21+
};
22+
23+
static struct pm_ctrl_info pm_ctrl[] = {
24+
{SYS_PM_LOW_POWER_STATE, ATOMIC_INIT(0)},
25+
{SYS_PM_DEEP_SLEEP, ATOMIC_INIT(0)},
26+
};
27+
28+
void sys_pm_ctrl_disable_state(int state)
29+
{
30+
if (state == SYS_PM_LOW_POWER_STATE) {
31+
__ASSERT(pm_ctrl[0].count < UINT_MAX,
32+
"Low Power state count overflowed\n");
33+
atomic_inc(&pm_ctrl[0].count);
34+
} else if (state == SYS_PM_DEEP_SLEEP) {
35+
__ASSERT(pm_ctrl[1].count < UINT_MAX,
36+
"Deep Sleep state count overflowed\n");
37+
atomic_inc(&pm_ctrl[1].count);
38+
} else {
39+
LOG_WRN("\nInvalid PM state");
40+
}
41+
}
42+
43+
void sys_pm_ctrl_enable_state(int state)
44+
{
45+
if (state == SYS_PM_LOW_POWER_STATE) {
46+
__ASSERT(pm_ctrl[0].count > 0,
47+
"Low Power state count underflowed\n");
48+
atomic_dec(&pm_ctrl[0].count);
49+
} else if (state == SYS_PM_DEEP_SLEEP) {
50+
__ASSERT(pm_ctrl[1].count > 0,
51+
"Deep Sleep state count underflowed\n");
52+
atomic_dec(&pm_ctrl[1].count);
53+
} else {
54+
LOG_WRN("\nInvalid PM state");
55+
}
56+
}
57+
58+
bool sys_pm_ctrl_is_state_enabled(int state)
59+
{
60+
bool enabled = true;
61+
62+
switch (state) {
63+
case SYS_PM_LOW_POWER_STATE:
64+
if (pm_ctrl[0].count) {
65+
enabled = false;
66+
}
67+
break;
68+
case SYS_PM_DEEP_SLEEP:
69+
if (pm_ctrl[1].count) {
70+
enabled = false;
71+
}
72+
break;
73+
default:
74+
LOG_WRN("\nInvalid PM state");
75+
enabled = false;
76+
}
77+
78+
return enabled;
79+
}

subsys/power/policy/pm_policy.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,27 @@ extern void sys_pm_notify_lps_exit(enum power_states state);
6262
*/
6363
extern void sys_pm_dump_debug_info(void);
6464

65+
/**
66+
* @brief Disable system PM state
67+
*
68+
* Disable system Low power states like LPS or Deep Sleep states.
69+
*/
70+
extern void sys_pm_ctrl_disable_state(int state);
71+
72+
/**
73+
* @brief Enable system PM state
74+
*
75+
* Enable system Low power states like LPS or Deep Sleep states.
76+
*/
77+
extern void sys_pm_ctrl_enable_state(int state);
78+
79+
/**
80+
* @brief Get enable status of a PM state
81+
*
82+
* Get enable status of a system PM state.
83+
*/
84+
extern bool sys_pm_ctrl_is_state_enabled(int state);
85+
6586
#ifdef __cplusplus
6687
}
6788
#endif

subsys/power/power.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ int _sys_soc_suspend(s32_t ticks)
7171

7272
sys_state = sys_pm_policy_next_state(ticks, &pm_state);
7373

74+
#ifdef CONFIG_PM_CONTROL_STATE_LOCK
75+
/* Check if PM state is locked */
76+
if ((sys_state != SYS_PM_NOT_HANDLED) &&
77+
!sys_pm_ctrl_is_state_enabled(sys_state)) {
78+
LOG_DBG("PM state locked %d\n", sys_state);
79+
return SYS_PM_NOT_HANDLED;
80+
}
81+
#endif
82+
7483
switch (sys_state) {
7584
case SYS_PM_LOW_POWER_STATE:
7685
sys_pm_notify_lps_entry(pm_state);

0 commit comments

Comments
 (0)