Linux Audio

Check our new training course

Embedded Linux Audio

Check our new training course
with Creative Commons CC-BY-SA
lecture materials

Bootlin logo

Elixir Cross Referencer

/*
 * 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.
 */

#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 Power Management Hook Interface
 *
 * @defgroup power_management_hook_interface Power Management Hook Interface
 * @ingroup power_management_api
 * @{
 */

/**
 * @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 */