Example #1
0
/**
 *
 * @brief Power management policy when kernel begins idling
 *
 * This routine implements the power management policy based on the time
 * until the timer expires, in system ticks.
 * Routine is invoked from the idle task with interrupts disabled
 *
 * @return N/A
 */
void _sys_power_save_idle(int32_t ticks)
{
#if defined(CONFIG_TICKLESS_IDLE)
	if ((ticks == TICKS_UNLIMITED) || ticks >= _sys_idle_threshold_ticks) {
		/*
		 * Stop generating system timer interrupts until it's time for
		 * the next scheduled microkernel timer to expire.
		 */

		_timer_idle_enter(ticks);
	}
#endif /* CONFIG_TICKLESS_IDLE */

	nano_cpu_set_idle(ticks);
#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, 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 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 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) &
			(SYS_PM_DEEP_SLEEP | SYS_PM_LOW_POWER_STATE))) {
		nano_cpu_idle();
	}
#else
	nano_cpu_idle();
#endif
}
Example #2
0
static void _sys_power_save_idle(int32_t ticks __unused)
{
#if defined(CONFIG_TICKLESS_IDLE)
	if ((ticks == K_FOREVER) || ticks >= _sys_idle_threshold_ticks) {
		/*
		 * Stop generating system timer interrupts until it's time for
		 * the next scheduled kernel timer to expire.
		 */

		_timer_idle_enter(ticks);
	}
#endif /* CONFIG_TICKLESS_IDLE */

	set_kernel_idle_time_in_ticks(ticks);
#if (defined(CONFIG_SYS_POWER_LOW_POWER_STATE) || \
	defined(CONFIG_SYS_POWER_DEEP_SLEEP))

	_sys_pm_idle_exit_notify = 1;

	/*
	 * Call the suspend hook function of the soc interface to allow
	 * entry into a low power state. The function returns
	 * SYS_PM_NOT_HANDLED if low power state was not entered, in which
	 * case, kernel does normal idle processing.
	 *
	 * This function is entered with interrupts disabled. If a low power
	 * state was entered, then the hook function should enable inerrupts
	 * before exiting. This is because the kernel does not do its own idle
	 * processing in those cases i.e. skips k_cpu_idle(). The kernel's
	 * idle processing re-enables interrupts which is essential for
	 * the kernel's scheduling logic.
	 */
	if (_sys_soc_suspend(ticks) == SYS_PM_NOT_HANDLED) {
		_sys_pm_idle_exit_notify = 0;
		k_cpu_idle();
	}
#else
	k_cpu_idle();
#endif
}