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