power: Add OS Power Management debug hooks

Add the necessary PM hooks like Low Power state entry
count and residencies for logging and debugging purposes.

Signed-off-by: Ramakrishna Pallala <ramakrishna.pallala@intel.com>
This commit is contained in:
Ramakrishna Pallala 2018-10-24 13:54:20 +05:30 committed by Anas Nashif
commit 359341203f
3 changed files with 64 additions and 0 deletions

View file

@ -4,5 +4,10 @@ menu "OS Power Management"
source "subsys/power/policy/Kconfig"
config PM_CONTROL_OS_DEBUG
bool "Enable OS Power Management debug hooks"
help
Enable OS Power Management debugging hooks.
endmenu
endif # PM_CONTROL_OS

View file

@ -55,6 +55,13 @@ extern void sys_pm_notify_lps_entry(enum power_states state);
*/
extern void sys_pm_notify_lps_exit(enum power_states state);
/**
* @brief Dump Low Power states related debug info
*
* Dump Low Power states debug info like LPS entry count and residencies.
*/
extern void sys_pm_dump_debug_info(void);
#ifdef __cplusplus
}
#endif

View file

@ -18,6 +18,51 @@ LOG_MODULE_REGISTER(power);
static int post_ops_done = 1;
static enum power_states pm_state;
#ifdef CONFIG_PM_CONTROL_OS_DEBUG
struct pm_debug_info {
u32_t count;
u32_t last_res;
u32_t total_res;
};
static struct pm_debug_info pm_dbg_info[SYS_POWER_STATE_MAX];
static u32_t timer_start, timer_end;
static inline void sys_pm_debug_start_timer(void)
{
timer_start = k_cycle_get_32();
}
static inline void sys_pm_debug_stop_timer(void)
{
timer_end = k_cycle_get_32();
}
static void sys_pm_log_debug_info(enum power_states state)
{
u32_t res = timer_end - timer_start;
pm_dbg_info[state].count++;
pm_dbg_info[state].last_res = res;
pm_dbg_info[state].total_res += res;
}
void sys_pm_dump_debug_info(void)
{
for (int i = 0; i < SYS_POWER_STATE_MAX; i++) {
LOG_DBG("PM:state = %d, count = %d last_res = %d, "
"total_res = %d\n", i, pm_dbg_info[i].count,
pm_dbg_info[i].last_res, pm_dbg_info[i].total_res);
}
}
#else
static inline void sys_pm_debug_start_timer(void) { }
static inline void sys_pm_debug_stop_timer(void) { }
static void sys_pm_log_debug_info(enum power_states state) { }
void sys_pm_dump_debug_info(void) { }
#endif
int _sys_soc_suspend(s32_t ticks)
{
int sys_state;
@ -29,8 +74,11 @@ int _sys_soc_suspend(s32_t ticks)
switch (sys_state) {
case SYS_PM_LOW_POWER_STATE:
sys_pm_notify_lps_entry(pm_state);
/* Do CPU LPS operations */
sys_pm_debug_start_timer();
_sys_soc_set_power_state(pm_state);
sys_pm_debug_stop_timer();
break;
case SYS_PM_DEEP_SLEEP:
/* Don't need pm idle exit event notification */
@ -45,7 +93,9 @@ int _sys_soc_suspend(s32_t ticks)
}
/* Enter CPU deep sleep state */
sys_pm_debug_start_timer();
_sys_soc_set_power_state(pm_state);
sys_pm_debug_stop_timer();
/* Turn on peripherals and restore device states as necessary */
sys_pm_resume_devices();
@ -57,6 +107,8 @@ int _sys_soc_suspend(s32_t ticks)
}
if (sys_state != SYS_PM_NOT_HANDLED) {
sys_pm_log_debug_info(pm_state);
/*
* Do any arch or soc specific post operations specific to the
* power state.