power_mgmt: Make names consistent with new RFC

Changed names of Kconfig flags, variables, functions, files and
return codes consistent with names used in the RFC. Updated
relevant comments to match the changes.

Origin: Original
Change-Id: Ie7941032d7ad7af61fc02928f74538745e7966e8
Signed-off-by: Ramesh Thomas <ramesh.thomas@intel.com>
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
Ramesh Thomas 2016-03-18 16:43:40 -07:00 committed by Anas Nashif
parent 9241cfc2f0
commit bb19e6f82f
39 changed files with 336 additions and 259 deletions

View file

@ -31,10 +31,32 @@ config ARM
config X86
bool "x86 architecture"
select NANOKERNEL_TICKLESS_IDLE_SUPPORTED
select ADVANCED_IDLE_SUPPORTED
endchoice
#
# Hidden PM feature configs which are to be selected by
# individual SoC.
#
config SYS_POWER_LOW_POWER_STATE_SUPPORTED
# Hidden
bool
default n
help
This option signifies that the target supports the SYS_POWER_LOW_POWER_STATE
configuration option.
config SYS_POWER_DEEP_SLEEP_SUPPORTED
# Hidden
bool
default n
help
This option signifies that the target supports the SYS_POWER_DEEP_SLEEP
configuration option.
#
# End hidden PM feature configs
#
config ARCH
string
help

View file

@ -23,6 +23,7 @@ choice
source "arch/arc/soc/*/Kconfig.soc"
endchoice
menu "ARC Options"
depends on ARC

View file

@ -40,9 +40,9 @@
/* ARCv2-specific tNANO structure member offsets */
GEN_OFFSET_SYM(tNANO, rirq_sp);
GEN_OFFSET_SYM(tNANO, firq_regs);
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
GEN_OFFSET_SYM(tNANO, idle);
#endif /* CONFIG_ADVANCED_POWER_MANAGEMENT */
#endif
/* ARCv2-specific struct tcs structure member offsets */
GEN_OFFSET_SYM(tTCS, intlock_key);

View file

@ -209,7 +209,7 @@ struct s_NANO {
struct tcs *current_fp; /* thread (fiber or task) that owns the FP regs */
#endif
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
int32_t idle; /* Number of ticks for kernel idling */
#endif

View file

@ -1,3 +1,4 @@
config SOC_QUARK_SE_SS
bool "Intel Quark SE - Sensor Sub System"
select SYS_POWER_LOW_POWER_STATE_SUPPORTED

View file

@ -33,7 +33,7 @@
_ASM_FILE_PROLOGUE
GTEXT(_CpuIdleInit)
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
GTEXT(_NanoIdleValGet)
GTEXT(_NanoIdleValClear)
#endif
@ -62,7 +62,7 @@ SECTION_FUNC(TEXT, _CpuIdleInit)
str r2, [r1]
bx lr
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
/**
*
@ -101,7 +101,7 @@ SECTION_FUNC(TEXT, _NanoIdleValClear)
str r1, [r0, #__tNANO_idle_OFFSET]
bx lr
#endif /* CONFIG_ADVANCED_POWER_MANAGEMENT */
#endif /* CONFIG_SYS_POWER_MANAGEMENT */
/**
*

View file

@ -69,7 +69,7 @@ SECTION_FUNC(TEXT, _isr_wrapper)
pop {lr}
#endif
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
/*
* All interrupts are disabled when handling idle wakeup. For tickless
* idle, this ensures that the calculation and programming of the device
@ -90,7 +90,7 @@ SECTION_FUNC(TEXT, _isr_wrapper)
blxne _sys_power_save_idle_exit
cpsie i /* re-enable interrupts (PRIMASK = 0) */
#endif /* CONFIG_ADVANCED_POWER_MANAGEMENT */
#endif
mrs r0, IPSR /* get exception number */
sub r0, r0, #16 /* get IRQ number */

View file

@ -40,9 +40,9 @@
/* ARM-specific tNANO structure member offsets */
GEN_OFFSET_SYM(tNANO, flags);
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
GEN_OFFSET_SYM(tNANO, idle);
#endif /* CONFIG_ADVANCED_POWER_MANAGEMENT */
#endif
/* ARM-specific struct tcs structure member offsets */

View file

@ -155,9 +155,9 @@ struct s_NANO {
struct tcs *current_fp; /* thread (fiber or task) that owns the FP regs */
#endif /* CONFIG_FP_SHARING */
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
int32_t idle; /* Number of ticks for kernel idling */
#endif /* CONFIG_ADVANCED_POWER_MANAGEMENT */
#endif
#if defined(CONFIG_NANO_TIMEOUTS) || defined(CONFIG_NANO_TIMERS)
sys_dlist_t timeout_q;

View file

@ -4,3 +4,4 @@ config SOC_ATMEL_SAM3X8E
select CPU_CORTEX_M
select CPU_CORTEX_M3
select SOC_ATMEL_SAM3
select SYS_POWER_LOW_POWER_STATE_SUPPORTED

View file

@ -3,3 +3,4 @@ config SOC_FSL_FRDM_K64F
bool "Freescale FRDM-K64F"
select CPU_CORTEX_M
select CPU_CORTEX_M4
select SYS_POWER_LOW_POWER_STATE_SUPPORTED

View file

@ -20,5 +20,6 @@ config SOC_STM32F1X
select CPU_CORTEX_M
select CPU_CORTEX_M3
select SOC_STM32
select SYS_POWER_LOW_POWER_STATE_SUPPORTED
help
Enable support for STM32F1 MCU series

View file

@ -237,13 +237,6 @@ config CACHE_FLUSHING
endmenu
menu "Platform Capabilities"
config ADVANCED_IDLE_SUPPORTED
bool "Advanced Idle Supported"
default n
help
This option signifies that the target supports the ADVANCED_IDLE
configuration option.
config NUM_DYNAMIC_STUBS
int "Number of dynamic int stubs"
default 0

View file

@ -42,15 +42,15 @@
#if defined(CONFIG_SSE)
GDATA(_sse_mxcsr_default_value)
#endif /* CONFIG_SSE */
#endif
#if defined(CONFIG_BOOT_TIME_MEASUREMENT)
GDATA(__start_tsc)
#endif
#ifdef CONFIG_ADVANCED_IDLE
#ifdef CONFIG_SYS_POWER_DEEP_SLEEP
GDATA(_sys_soc_resume)
#endif /* CONFIG_ADVANCED_IDLE */
#endif
/* processor is executing in 32-bit protected mode */
@ -192,7 +192,7 @@ __csSet:
andl $0xfffffffc, %esp
#ifdef CONFIG_ADVANCED_IDLE
#ifdef CONFIG_SYS_POWER_DEEP_SLEEP
/*
* Invoke _sys_soc_resume() hook to handle resume from deep sleep.
* It should first check whether system is recovering from
@ -207,7 +207,7 @@ __csSet:
call _sys_soc_resume
#endif /* CONFIG_ADVANCED_IDLE */
#endif
#ifdef CONFIG_XIP
/*

View file

@ -47,13 +47,13 @@
GTEXT(_Swap)
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
#if defined(CONFIG_NANOKERNEL) && defined(CONFIG_TICKLESS_IDLE)
GTEXT(_power_save_idle_exit)
#else
GTEXT(_sys_power_save_idle_exit)
#endif /* CONFIG_NANOKERNEL && CONFIG_TICKLESS_IDLE */
#endif /* CONFIG_ADVANCED_POWER_MANAGEMENT */
#endif
#endif
#ifdef CONFIG_INT_LATENCY_BENCHMARK
@ -185,11 +185,11 @@ SECTION_FUNC(TEXT, _IntEnt)
pushl %edx /* Save stack pointer */
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
cmpl $0, __tNANO_idle_OFFSET(%ecx)
jne _HandleIdle
/* fast path is !idle, in the pipeline */
#endif /* CONFIG_ADVANCED_POWER_MANAGEMENT */
#endif
/* fall through to nested case */
@ -206,7 +206,7 @@ BRANCH_LABEL(alreadyOnIntStack)
#endif
jmp *%eax /* "return" back to stub */
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
BRANCH_LABEL(_HandleIdle)
#if defined(CONFIG_NANOKERNEL) && defined(CONFIG_TICKLESS_IDLE)
pushl %eax
@ -232,7 +232,7 @@ BRANCH_LABEL(_HandleIdle)
sti /* re-enable interrupts */
popl %eax
jmp *%eax /* "return" back to stub */
#endif /* CONFIG_ADVANCED_POWER_MANAGEMENT */
#endif /* CONFIG_SYS_POWER_MANAGEMENT */
/**
* @brief Perform EOI, clean up stack, and do interrupt exit

View file

@ -17,15 +17,15 @@
#include <nano_private.h>
#include <drivers/loapic.h>
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
#if defined(CONFIG_NANOKERNEL) && defined(CONFIG_TICKLESS_IDLE)
extern void _power_save_idle_exit(void);
#else
extern void _sys_power_save_idle_exit(int32_t ticks);
#endif /* CONFIG_NANOKERNEL && CONFIG_TICKLESS_IDLE*/
#endif
#endif /* CONFIG_ADVANCED_POWER_MANAGEMENT */
#endif
#ifdef CONFIG_NESTED_INTERRUPTS
static inline void enable_nested_interrupts(void)
@ -81,7 +81,7 @@ void _execute_handler(int_handler_t function, int context)
}
_nanokernel.nested++;
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
#if defined(CONFIG_NANOKERNEL) && defined(CONFIG_TICKLESS_IDLE)
_power_save_idle_exit();
@ -90,9 +90,9 @@ void _execute_handler(int_handler_t function, int context)
_sys_power_save_idle_exit(_nanokernel.idle);
_nanokernel.idle = 0;
}
#endif /* CONFIG_NANOKERNEL && CONFIG_TICKLESS_IDLE*/
#endif
#endif /* CONFIG_ADVANCED_POWER_MANAGEMENT */
#endif
_int_latency_stop();
enable_nested_interrupts();

View file

@ -46,9 +46,9 @@
GEN_OFFSET_SYM(tNANO, nested);
GEN_OFFSET_SYM(tNANO, common_isp);
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
GEN_OFFSET_SYM(tNANO, idle);
#endif /* CONFIG_ADVANCED_POWER_MANAGEMENT */
#endif
/* Intel-specific struct tcs structure member offsets */

View file

@ -1,134 +0,0 @@
/* advidle.h - header file for custom advanced idle manager */
/*
* Copyright (c) 2012-2014 Wind River Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @brief Power management hooks
*
* This header file specifies the Power Management hook interface.
* All of the APIs declared here must be supplied by the Power Manager
* application, namely the _sys_soc_suspend() and _sys_soc_resume()
* functions.
*/
#ifndef __INCadvidle
#define __INCadvidle
#ifdef __cplusplus
extern "C" {
#endif
#ifdef CONFIG_ADVANCED_IDLE
/**
* @brief Exit deep sleep, low power or tickless idle states
*
* The main purpose of this routine is to notify exit from
* deep sleep, low power or tickless idle. States altered
* at _sys_soc_suspend() should be restored in this function.
* This can be called under following conditions each of which
* require different handling.
*
* Deep sleep recovery:
* App should save information in SoC at _sys_soc_suspend() that
* will persist across deep sleep. This function should check
* that information to identify deep sleep recovery. In this case
* this function will restore states and resume execution at the
* point were system entered deep sleep. In this mode, this
* function is called with the interrupt stack. It is important
* that this function, before interrupts are enabled, restores
* the stack that was in use when system went to deep sleep. This
* is to avoid interfering interrupt handlers use of this stack.
*
* Cold boot:
* Cold boot and deep sleep recovery happen at the same location.
* The function identifies it is a cold boot if it does not find
* state information indicating deep sleep, low power state or
* tickless idle. In this case the function returns immediately.
*
* Low power recovery:
* Low power is entered by turning off peripherals, gating clocks
* and entering a low power CPU state like C2. This state is exited by
* an interrupt. In this case this function would be called from
* the interrupt's context. Any peripherals turned off at
* suspend should be turned back on in this function.
*
* Tickless idle exit:
* This function will also be called at exit of kernel's tickless
* idle. Restore any states altered in _sys_soc_suspend().
*
* @return will not return to caller if deep sleep recovery
*/
extern void _sys_soc_resume(void);
/**
* @brief Enter deep sleep, low power or tickless idle states
*
* This routine is called by the kernel when it is about to idle.
* This routine is passed the number of clock ticks that the kernel
* calculated as available time to idle. This function should compare
* this time with the wake latencies of the various power saving schemes
* and use the best one that fits. The power saving schemes use the
* following modes.
*
* Deep Sleep:
* This turns off the core voltage rail and core clock. This would save
* most power but would also have a high wake latency. CPU loses state
* so this function should save CPU states and the location in this
* function where system should resume execution at resume. Function
* should re-enable interrupts and return a non-zero value.
*
* Low Power:
* Peripherals can be turned off and clocks can be gated depending on
* time available. Then swithes to CPU low power state. In this state
* the CPU is still active but in a low power state and does not lose
* any state. This state is exited by an interrupt from where the
* _sys_soc_resume() will be called. To allow the interrupt,
* this function should ensure that interrupts are atomically
* enabled before going to the low power CPU state. This function
* should return a non-zero value to indicate it was handled and kernel
* should not do its own CPU idle. Interrupts should be enabled on exit.
*
* Tickless Idle:
* This routine can take advantage of the kernel's tickless idle logic
* by turning off peripherals and clocks depending on available time.
* It can return zero to indicate the kernel should do its own CPU idle.
* After the tickless idle wait is completed or if any interrupt occurs,
* the _sys_soc_resume() function will be called to allow restoring
* altered states. Function should return zero. Interrupts should not
* be turned on.
*
* If this function decides to not do any operation then it should
* return zero to let kernel do its idle wait.
*
* This function is entered with interrupts disabled. It should
* re-enable interrupts if it returns non-zero value i.e. if it
* does its own CPU low power wait or deep sleep.
*
* @param ticks the upcoming kernel idle time
*
* @return non-zero value if deep sleep or CPU low power entered
*/
extern int _sys_soc_suspend(int32_t ticks);
#endif /* CONFIG_ADVANCED_IDLE */
#ifdef __cplusplus
}
#endif
#endif /* __INCadvidle */

View file

@ -710,9 +710,9 @@ typedef struct s_NANO {
unsigned nested; /* nested interrupt count */
char *common_isp; /* interrupt stack pointer base */
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
int32_t idle; /* Number of ticks for kernel idling */
#endif /* CONFIG_ADVANCED_POWER_MANAGEMENT */
#endif
#ifdef CONFIG_FP_SHARING

View file

@ -10,3 +10,5 @@ config SOC_QUARK_SE
select BOOTLOADER_UNKNOWN
select XIP
select X86_IAMCU
select SYS_POWER_LOW_POWER_STATE_SUPPORTED
select SYS_POWER_DEEP_SLEEP_SUPPORTED

View file

@ -5,5 +5,7 @@ config SOC_QUARK_X1000
select HPET_TIMER
select BOOTLOADER_UNKNOWN
select PCI
select SYS_POWER_LOW_POWER_STATE_SUPPORTED
select SYS_POWER_DEEP_SLEEP_SUPPORTED
help
Intel Quark X1000 SoC.

View file

@ -89,15 +89,15 @@ static uint32_t clock_accumulated_count;
extern uint32_t _hw_irq_to_c_handler_latency;
#endif
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
extern int32_t _NanoIdleValGet(void);
extern void _NanoIdleValClear(void);
extern void _sys_power_save_idle_exit(int32_t ticks);
#endif /* CONFIG_ADVANCED_POWER_MANAGEMENT */
#endif
#ifdef CONFIG_TICKLESS_IDLE
extern int32_t _sys_idle_elapsed_ticks;
#endif /* CONFIG_TICKLESS_IDLE */
#endif
#ifdef CONFIG_TICKLESS_IDLE
static uint32_t __noinit default_load_value; /* default count */
@ -249,7 +249,7 @@ void _TIMER_INT_HANDLER(void *unused)
}
#endif
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
int32_t numIdleTicks;
/*
@ -333,7 +333,7 @@ void _TIMER_INT_HANDLER(void *unused)
__asm__(" cpsie i"); /* re-enable interrupts (PRIMASK = 0) */
#else /* !CONFIG_ADVANCED_POWER_MANAGEMENT */
#else /* !CONFIG_SYS_POWER_MANAGEMENT */
/* accumulate total counter value */
clock_accumulated_count += sys_clock_hw_cycles_per_tick;
@ -344,7 +344,7 @@ void _TIMER_INT_HANDLER(void *unused)
*/
_sys_clock_tick_announce();
#endif /* CONFIG_ADVANCED_POWER_MANAGEMENT */
#endif /* CONFIG_SYS_POWER_MANAGEMENT */
extern void _ExcExit(void);
_ExcExit();

145
include/power.h Normal file
View file

@ -0,0 +1,145 @@
/*
* Copyright (c) 2012-2014 Wind River Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @brief Power management hooks
*
* This header file specifies the Power Management hook interface.
* All of the APIs declared here must be supplied by the Power Manager
* application, namely the _sys_soc_suspend() and _sys_soc_resume()
* functions.
*/
#ifndef __INCpower
#define __INCpower
#ifdef __cplusplus
extern "C" {
#endif
#ifdef CONFIG_SYS_POWER_MANAGEMENT
/* Constants identifying power policies */
#define SYS_PM_NOT_HANDLED 0 /* No PM operations */
#define SYS_PM_DEVICE_SUSPEND_ONLY 1 /* Only Devices are suspended */
#define SYS_PM_LOW_POWER_STATE 2 /* Low Power State */
#define SYS_PM_DEEP_SLEEP 4 /* Deep Sleep */
/**
* @brief Hook function to notify exit of a power policy
*
* The purpose of this function is to notify exit from
* deep sleep, low power state or device suspend only policy.
* States altered at _sys_soc_suspend() should be restored in this
* function. Exit from each policy requires different handling as
* follows.
*
* Deep sleep policy exit:
* App should save information in SoC at _sys_soc_suspend() that
* will persist across deep sleep. This function should check
* that information to identify deep sleep recovery. In this case
* this function will restore states and resume execution at the
* point were system entered deep sleep. In this mode, this
* function is called with the interrupt stack. It is important
* that this function, before interrupts are enabled, restores
* the stack that was in use when system went to deep sleep. This
* is to avoid interfering interrupt handlers use of this stack.
*
* Cold boot and deep sleep recovery happen at the same location.
* Since kernel does not store deep sleep state, kernel will call
* this function in both cases. It is the responsibility of the
* power manager application to identify whether it is cold boot
* or deep sleep exit using state information that it stores.
* If the function detects cold boot, then it returns immediately.
*
* Low power state policy exit:
* Low power state policy does a CPU idle wait using a low power
* CPU idle state supported by the processor. This state is exited
* by an interrupt. In this case this function would be called
* from the interrupt's ISR context. Any state altered at
* _sys_soc_suspend should be restored and the function should
* return quickly.
*
* Device suspend only policy exit:
* This function will be called at the exit of kernel's CPU idle
* wait if device suspend only policy was used. Resume operations
* should be done for devices that were suspended in _sys_soc_suspend().
* This function is called in ISR context and it should return quickly.
*
* @return will not return to caller in deep sleep recovery
*/
extern void _sys_soc_resume(void);
/**
* @brief Hook function to allow power policy entry
*
* This function is called by the kernel when it is about to idle.
* It is passed the number of clock ticks that the kernel calculated
* as available time to idle. This function should compare this time
* with the wake latency of various power saving schemes that the
* power manager application implements and use the one that fits best.
* The power saving schemes can be mapped to following policies.
*
* Deep sleep policy:
* This turns off the core voltage rail and system clock, while RAM is
* retained. This would save most power but would also have a high wake
* latency. CPU loses state so this function should save CPU states in RAM
* and the location in this function where system should resume execution at
* resume. It should re-enable interrupts and return SYS_PM_DEEP_SLEEP.
*
* Low power state policy:
* Peripherals can be turned off and clocks can be gated depending on
* time available. Then switches to CPU low power state. In this state
* the CPU is still active but in a low power state and does not lose
* any state. This state is exited by an interrupt from where the
* _sys_soc_resume() will be called. To allow interrupts to occur,
* this function should ensure that interrupts are atomically enabled
* before going to the low power CPU idle state. The atomicity of enabling
* interrupts before entering cpu idle wait is essential to avoid a task
* switch away from the kernel idle task before the cpu idle wait is reached.
* This function should return SYS_PM_LOW_POWER_STATE.
*
* Device suspend only policy:
* This function can take advantage of the kernel's idling logic
* by turning off peripherals and clocks depending on available time.
* It can return SYS_PM_DEVICE_SUSPEND_ONLY to indicate the kernel should
* do its own CPU idle wait. After the Kernel's idle wait is completed or if
* any interrupt occurs, the _sys_soc_resume() function will be called to
* allow restoring of altered states. Interrupts should not be turned on in
* this case.
*
* If this function decides to not do any operation then it should
* return SYS_PM_NOT_HANDLED to let kernel do its normal idle processing.
*
* This function is entered with interrupts disabled. It should
* re-enable interrupts if it does CPU low power wait or deep sleep.
*
* @param ticks the upcoming kernel idle time
*
* @retval SYS_PM_NOT_HANDLED If No PM operations done.
* @retval SYS_PM_DEVICE_SUSPEND_ONLY If only devices were suspended.
* @retval SYS_PM_LOW_POWER_STATE If LPS policy entered.
* @retval SYS_PM_DEEP_SLEEP If Deep Sleep policy entered.
*/
extern int _sys_soc_suspend(int32_t ticks);
#endif /* CONFIG_SYS_POWER_MANAGEMENT */
#ifdef __cplusplus
}
#endif
#endif /* __INCpower */

View file

@ -148,7 +148,7 @@ config KERNEL_EVENT_LOGGER_SLEEP
bool
prompt "Sleep event logging point"
default n
depends on KERNEL_EVENT_LOGGER && ((MICROKERNEL && ADVANCED_POWER_MANAGEMENT) || NANOKERNEL)
depends on KERNEL_EVENT_LOGGER && ((MICROKERNEL && SYS_POWER_MANAGEMENT) || NANOKERNEL)
help
Enable low power condition event messages. These messages provide the
following information:
@ -188,30 +188,58 @@ source "kernel/microkernel/Kconfig"
endif
menu "Power Management"
config ADVANCED_POWER_MANAGEMENT
config SYS_POWER_MANAGEMENT
bool
prompt "Advanced power management"
prompt "Power management"
default n
help
This option enables the platform to implement extra power management
policies whenever the kernel becomes idle. The kernel invokes
_sys_power_save_idle() to inform the power management subsystem of the
number of ticks until the next kernel timer is due to expire.
policies whenever the kernel becomes idle. The kernel informs the
power management subsystem of the number of ticks until the next kernel
timer is due to expire.
menu "Advanced Power Management Features"
depends on ADVANCED_POWER_MANAGEMENT
menu "Power Management Features"
depends on SYS_POWER_MANAGEMENT
config ADVANCED_IDLE
config SYS_POWER_LOW_POWER_STATE
bool
prompt "Advanced idle state"
prompt "Low power state"
default n
depends on MICROKERNEL && ADVANCED_POWER_MANAGEMENT && ADVANCED_IDLE_SUPPORTED
depends on MICROKERNEL && SYS_POWER_MANAGEMENT && SYS_POWER_LOW_POWER_STATE_SUPPORTED
help
This option enables the kernel to interface to a custom advanced idle
power saving manager. This permits the system to enter a custom
power saving state when the kernel becomes idle for extended periods,
and then to restore the system to its previous state (rather than
booting up from scratch) when the kernel is re-activated.
This option enables the kernel to interface with a power manager
application. This permits the system to enter a custom CPU low power
state when the kernel becomes idle. The low power state could be any of
the CPU low power states supported by the processor. Generally the one
saving most power.
config SYS_POWER_DEEP_SLEEP
bool
prompt "Deep sleep state"
default n
depends on MICROKERNEL && SYS_POWER_MANAGEMENT && SYS_POWER_DEEP_SLEEP_SUPPORTED
help
This option enables the kernel to interface with a power manager
application. This permits the system to enter a Deep sleep state
supported by the SOC where the system clock is turned off while RAM is
retained. This state would be entered when the kernel becomes idle for
extended periods and would have a high wake latency. Resume would be
from the reset vector same as cold boot. The interface allows
restoration of states that were saved at the time of suspend.
config DEVICE_POWER_MANAGEMENT
bool
prompt "Device power management"
default n
depends on MICROKERNEL && SYS_POWER_MANAGEMENT
help
This option enables the device power management interface. The
interface consists of hook functions implemented by device drivers
that get called by the power manager application when the system
is going to suspend state or resuming from suspend state. This allows
device drivers to do any necessary power management operations
like turning off device clocks and peripherals. The device drivers
may also save and restore states in these hook functions.
config TICKLESS_IDLE
bool

View file

@ -235,12 +235,14 @@ void sys_workload_time_slice_set(int32_t t)
unsigned char _sys_power_save_flag = 1;
#if defined(CONFIG_ADVANCED_POWER_MANAGEMENT)
#if defined(CONFIG_SYS_POWER_MANAGEMENT)
#include <nanokernel.h>
#include <microkernel/base_api.h>
#ifdef CONFIG_ADVANCED_IDLE
#include <advidle.h>
#if (defined(CONFIG_SYS_POWER_LOW_POWER_STATE) || \
defined(CONFIG_SYS_POWER_DEEP_SLEEP) || \
defined(CONFIG_DEVICE_POWER_MANAGEMENT))
#include <power.h>
#endif
#if defined(CONFIG_TICKLESS_IDLE)
#include <drivers/system_timer.h>
@ -280,29 +282,37 @@ void _sys_power_save_idle(int32_t ticks)
#endif /* CONFIG_TICKLESS_IDLE */
nano_cpu_set_idle(ticks);
#ifdef CONFIG_ADVANCED_IDLE
#if (defined(CONFIG_SYS_POWER_LOW_POWER_STATE) || \
defined(CONFIG_SYS_POWER_DEEP_SLEEP) || \
defined(CONFIG_DEVICE_POWER_MANAGEMENT))
/*
* Call the suspend hook function, which checks if the system should
* enter deep sleep or low power state. The function will return a
* non-zero value if system was put in deep sleep or low power state.
* If the time available is too short to go to deep sleep or
* low power state, then the function returns zero immediately
* and we do normal idle processing.
* enter deep sleep, low power state or only suspend devices.
* If the time available is too short for any PM operation then
* the function returns SYS_PM_NOT_HANDLED immediately and kernel
* does normal idle processing. Otherwise it will return the code
* corresponding to the action taken.
*
* This function can turn off devices without entering deep sleep
* or cpu low power state. In this case it should return zero to
* let kernel enter its own tickless idle wait.
* This function can just suspend devices without entering
* deep sleep or cpu low power state. In this case it should return
* SYS_PM_DEVICE_SUSPEND_ONLY and kernel would do normal idle
* processing.
*
* This function is entered with interrupts disabled. If the function
* returns a non-zero value then it should re-enable interrupts before
* returning.
* returns either SYS_PM_LOW_POWER_STATE or SYS_PM_DEEP_SLEEP then
* it should ensure interrupts are re-enabled before returning.
* This is because the kernel does not do its own idle processing in
* these cases i.e. skips nano_cpu_idle(). The kernel's idle
* processing re-enables interrupts which is essential for kernel's
* scheduling logic.
*/
if (_sys_soc_suspend(ticks) == 0) {
if (!(_sys_soc_suspend(ticks) &
(SYS_PM_DEEP_SLEEP | SYS_PM_LOW_POWER_STATE))) {
nano_cpu_idle();
}
#else
nano_cpu_idle();
#endif /* CONFIG_ADVANCED_IDLE */
#endif
}
/**
@ -317,12 +327,14 @@ void _sys_power_save_idle(int32_t ticks)
*/
void _sys_power_save_idle_exit(int32_t ticks)
{
#ifdef CONFIG_ADVANCED_IDLE
#if (defined(CONFIG_SYS_POWER_LOW_POWER_STATE) || \
defined(CONFIG_SYS_POWER_DEEP_SLEEP) || \
defined(CONFIG_DEVICE_POWER_MANAGEMENT))
/* Any idle wait based on CPU low power state will be exited by
* interrupt. This function is called within that interrupt's
* context. _sys_soc_resume() needs to be called here mainly
* ISR context. _sys_soc_resume() needs to be called here
* to handle exit from CPU low power states. This gives an
* oppurtunity for device states altered in _sys_soc_suspend()
* opportunity for device states altered in _sys_soc_suspend()
* to be restored before the kernel schedules another thread.
* _sys_soc_resume() is not called from here for deep sleep
* exit. Deep sleep recovery happens at cold boot path.
@ -378,7 +390,7 @@ static void _power_save(void)
if (_sys_power_save_flag) {
for (;;) {
irq_lock();
#ifdef CONFIG_ADVANCED_POWER_MANAGEMENT
#ifdef CONFIG_SYS_POWER_MANAGEMENT
_sys_power_save_idle(_get_next_timer_expiry());
#else
/*

View file

@ -12,7 +12,7 @@ obj-y = nano_fiber.o nano_lifo.o \
obj-$(CONFIG_INT_LATENCY_BENCHMARK) += int_latency_bench.o
obj-$(CONFIG_NANO_TIMEOUTS) += nano_sleep.o
obj-$(CONFIG_STACK_CANARIES) += compiler_stack_protect.o
obj-$(CONFIG_ADVANCED_POWER_MANAGEMENT) += idle.o
obj-$(CONFIG_SYS_POWER_MANAGEMENT) += idle.o
obj-$(CONFIG_NANO_TIMERS) += nano_timer.o
obj-$(CONFIG_KERNEL_EVENT_LOGGER) += event_logger.o
obj-$(CONFIG_KERNEL_EVENT_LOGGER) += kernel_event_logger.o

View file

@ -6,7 +6,7 @@ CONFIG_KERNEL_EVENT_LOGGER=y
CONFIG_KERNEL_EVENT_LOGGER_BUFFER_SIZE=16
CONFIG_KERNEL_EVENT_LOGGER_CONTEXT_SWITCH=y
CONFIG_KERNEL_EVENT_LOGGER_INTERRUPT=y
CONFIG_ADVANCED_POWER_MANAGEMENT=y
CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_TICKLESS_IDLE=n
CONFIG_KERNEL_EVENT_LOGGER_SLEEP=y
CONFIG_TASK_MONITOR=y

View file

@ -6,7 +6,7 @@ CONFIG_NANO_TIMEOUTS=y
CONFIG_KERNEL_EVENT_LOGGER_BUFFER_SIZE=16
CONFIG_KERNEL_EVENT_LOGGER_CONTEXT_SWITCH=y
CONFIG_KERNEL_EVENT_LOGGER_INTERRUPT=y
CONFIG_ADVANCED_POWER_MANAGEMENT=y
CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_TICKLESS_IDLE=y
CONFIG_KERNEL_EVENT_LOGGER_SLEEP=y
CONFIG_TASK_MONITOR=y

View file

@ -1,4 +1,4 @@
CONFIG_STDOUT_CONSOLE=y
CONFIG_ADVANCED_POWER_MANAGEMENT=y
CONFIG_ADVANCED_IDLE=y
CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_SYS_POWER_LOW_POWER_STATE=y
CONFIG_TICKLESS_IDLE=y

View file

@ -15,7 +15,7 @@
*/
#include <zephyr.h>
#include <advidle.h>
#include <power.h>
#if defined(CONFIG_STDOUT_CONSOLE)
#include <stdio.h>

View file

@ -7,9 +7,10 @@ power management infrastructure.
This app will cycle through the various power schemes at every call
to _sys_soc_suspend() hook function.
It will cycle through following states
It will cycle through following policies
1. Low Power State (LPS) - puts the CPU in C2 state
2. Tickless Idle - demonstrates hooks into tickless idle entry and exit
2. Device suspend only - demonstrates hooks into kernel idle entry and exit
that can be used to only suspend devices without CPU or SOC PM operations.
3. No-op - no operation and letting kernel do its idle
--------------------------------------------------------------------------------
@ -44,13 +45,13 @@ Sample Output:
Power Management Demo
Going to low power state!
Low power state policy entry!
Resume from low power state
Low power state policy exit!
Total Elapsed From Suspend To Resume = 163838 RTC Cycles
Tickless idle power saving!
Device suspend only policy entry!
Exit from tickless idle
Total Elapsed From Suspend To Tickless Resume = 163838 RTC Cycles
Device suspend only policy exit!
Total Elapsed From Suspend To Resume = 163838 RTC Cycles
...
...

View file

@ -1,5 +1,5 @@
CONFIG_ADVANCED_POWER_MANAGEMENT=y
CONFIG_ADVANCED_IDLE=y
CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_SYS_POWER_LOW_POWER_STATE=y
CONFIG_TICKLESS_IDLE=y
CONFIG_RTC=y
CONFIG_STDOUT_CONSOLE=y

View file

@ -15,6 +15,7 @@
*/
#include <zephyr.h>
#include <power.h>
#if defined(CONFIG_STDOUT_CONSOLE)
#include <stdio.h>
@ -28,7 +29,7 @@
#define SLEEPTICKS SECONDS(5)
#define P_LVL2 0xb0800504
static int pm_state; /* 1 = LPS; 2 = Tickless Idle */
static int pm_state; /* 1 = LPS; 2 = Device suspend only */
static void quark_low_power(void);
static struct device *rtc_dev;
static uint32_t start_time, end_time;
@ -65,7 +66,7 @@ static int check_pm_policy(int32_t ticks)
*
* 0 = no power saving operation
* 1 = low power state
* 2 = tickless idle power saving
* 2 = device suspend only
*
*/
policy = (policy > 2 ? 0 : policy);
@ -73,63 +74,63 @@ static int check_pm_policy(int32_t ticks)
return policy++;
}
static int do_low_power(int32_t ticks)
static int low_power_state_entry(int32_t ticks)
{
PRINT("\n\nGoing to low power state!\n");
PRINT("\n\nLow power state policy entry!\n");
/* Turn off peripherals/clocks here */
quark_low_power();
return 1; /* non-zero so kernel does not do idle wait */
return SYS_PM_LOW_POWER_STATE;
}
static int do_tickless_idle(int32_t ticks)
static int device_suspend_only_entry(int32_t ticks)
{
PRINT("Tickless idle power saving!\n");
PRINT("Device suspend only policy entry!\n");
/* Turn off peripherals/clocks here */
return 0; /* zero to let kernel do idle wait */
return SYS_PM_DEVICE_SUSPEND_ONLY;
}
int _sys_soc_suspend(int32_t ticks)
{
int ret = 0;
int ret = SYS_PM_NOT_HANDLED;
pm_state = check_pm_policy(ticks);
switch (pm_state) {
case 1:
start_time = rtc_read(rtc_dev);
ret = do_low_power(ticks);
ret = low_power_state_entry(ticks);
break;
case 2:
start_time = rtc_read(rtc_dev);
ret = do_tickless_idle(ticks);
ret = device_suspend_only_entry(ticks);
break;
default:
/* No PM operations */
ret = 0;
ret = SYS_PM_NOT_HANDLED;
break;
}
return ret;
}
static void low_power_resume(void)
static void low_power_state_exit(void)
{
end_time = rtc_read(rtc_dev);
PRINT("\nResume from low power state\n");
PRINT("\nLow power state policy exit!\n");
PRINT("Total Elapsed From Suspend To Resume = %d RTC Cycles\n",
end_time - start_time);
}
static void tickless_idle_resume(void)
static void device_suspend_only_exit(void)
{
end_time = rtc_read(rtc_dev);
PRINT("\nExit from tickless idle\n");
PRINT("Total Elapsed From Suspend To Tickless Resume = %d RTC Cycles\n",
PRINT("\nDevice suspend only policy exit!\n");
PRINT("Total Elapsed From Suspend To Resume = %d RTC Cycles\n",
end_time - start_time);
}
@ -137,10 +138,10 @@ void _sys_soc_resume(void)
{
switch (pm_state) {
case 1:
low_power_resume();
low_power_state_exit();
break;
case 2:
tickless_idle_resume();
device_suspend_only_exit();
break;
default:
break;

View file

@ -8,7 +8,7 @@ CONFIG_NUM_COMMAND_PACKETS=64
CONFIG_NUM_TIMER_PACKETS=16
CONFIG_MICROKERNEL_SERVER_STACK_SIZE=4096
CONFIG_ADVANCED_POWER_MANAGEMENT=y
CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_MAX_NUM_TASK_IRQS=2

View file

@ -9,7 +9,7 @@ CONFIG_NUM_COMMAND_PACKETS=64
CONFIG_NUM_TIMER_PACKETS=16
CONFIG_MICROKERNEL_SERVER_STACK_SIZE=4096
CONFIG_ADVANCED_POWER_MANAGEMENT=y
CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_MAX_NUM_TASK_IRQS=2

View file

@ -7,6 +7,6 @@ CONFIG_NUM_TASK_PRIORITIES=64
CONFIG_NUM_COMMAND_PACKETS=64
CONFIG_NUM_TIMER_PACKETS=16
CONFIG_MICROKERNEL_SERVER_STACK_SIZE=4096
CONFIG_ADVANCED_POWER_MANAGEMENT=y
CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_MAX_NUM_TASK_IRQS=2
CONFIG_NUM_IRQS=43

View file

@ -8,6 +8,6 @@ CONFIG_NUM_TASK_PRIORITIES=64
CONFIG_NUM_COMMAND_PACKETS=64
CONFIG_NUM_TIMER_PACKETS=16
CONFIG_MICROKERNEL_SERVER_STACK_SIZE=4096
CONFIG_ADVANCED_POWER_MANAGEMENT=y
CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_MAX_NUM_TASK_IRQS=2

View file

@ -1,3 +1,3 @@
CONFIG_ADVANCED_POWER_MANAGEMENT=y
CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_TICKLESS_IDLE=y
CONFIG_SW_ISR_TABLE_DYNAMIC=n

View file

@ -1,4 +1,4 @@
CONFIG_ADVANCED_POWER_MANAGEMENT=y
CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_TICKLESS_IDLE=y
# Let stack canaries use non-random number generator.