static void up_idlepm(void) { #ifdef CONFIG_RTC_ALARM struct timespec alarmtime; #endif static enum pm_state_e oldstate = PM_NORMAL; enum pm_state_e newstate; irqstate_t flags; int ret; /* Decide, which power saving level can be obtained */ newstate = pm_checkstate(); /* Check for state changes */ if (newstate != oldstate) { lldbg("newstate= %d oldstate=%d\n", newstate, oldstate); flags = irqsave(); /* Force the global state change */ ret = pm_changestate(newstate); if (ret < 0) { /* The new state change failed, revert to the preceding state */ (void)pm_changestate(oldstate); /* No state change... */ goto errout; } /* Then perform board-specific, state-dependent logic here */ switch (newstate) { case PM_NORMAL: { } break; case PM_IDLE: { } break; case PM_STANDBY: { #ifdef CONFIG_RTC_ALARM /* Disable RTC Alarm interrupt */ #warning "missing logic" /* Configure the RTC alarm to Auto Wake the system */ #warning "missing logic" /* The tv_nsec value must not exceed 1,000,000,000. That * would be an invalid time. */ #warning "missing logic" /* Set the alarm */ #warning "missing logic" #endif /* Call the STM32 stop mode */ stm32_pmstop(true); /* We have been re-awakened by some even: A button press? * An alarm? Cancel any pending alarm and resume the normal * operation. */ #ifdef CONFIG_RTC_ALARM #warning "missing logic" #endif /* Resume normal operation */ pm_changestate(PM_NORMAL); newstate = PM_NORMAL; } break; case PM_SLEEP: { /* We should not return from standby mode. The only way out * of standby is via the reset path. */ (void)stm32_pmstandby(); } break; default: break; } /* Save the new state */ oldstate = newstate; errout: irqrestore(flags); } }
static void stm32_idlepm(void) { static enum pm_state_e oldstate = PM_NORMAL; enum pm_state_e newstate; int ret; /* The following is logic that is done after the wake-up from PM_STANDBY * state. It decides whether to go back to the PM_NORMAL or to the deeper * power-saving mode PM_SLEEP: If the alarm expired with no "normal" * wake-up event, then PM_SLEEP is entered. * * Logically, this code belongs at the end of the PM_STANDBY case below, * does not work in the position for some unkown reason. */ if (oldstate == PM_STANDBY) { /* Were we awakened by the alarm? */ #ifdef CONFIG_RTC_ALARM if (g_alarmwakeup) { /* Yes.. Go to SLEEP mode */ newstate = PM_SLEEP; } else #endif { /* Resume normal operation */ newstate = PM_NORMAL; } } else { /* Let the PM system decide, which power saving level can be obtained */ newstate = pm_checkstate(); } /* Check for state changes */ if (newstate != oldstate) { llvdbg("newstate= %d oldstate=%d\n", newstate, oldstate); sched_lock(); /* Force the global state change */ ret = pm_changestate(newstate); if (ret < 0) { /* The new state change failed, revert to the preceding state */ (void)pm_changestate(oldstate); /* No state change... */ goto errout; } /* Then perform board-specific, state-dependent logic here */ switch (newstate) { case PM_NORMAL: { /* If we just awakened from PM_STANDBY mode, then reconfigure * clocking. */ if (oldstate == PM_STANDBY) { /* Re-enable clocking */ stm32_clockenable(); /* The system timer was disabled while in PM_STANDBY or * PM_SLEEP modes. But the RTC has still be running: Reset * the system time the current RTC time. */ #ifdef CONFIG_RTC clock_synchronize(); #endif } } break; case PM_IDLE: { } break; case PM_STANDBY: { /* Set the alarm as an EXTI Line */ #ifdef CONFIG_RTC_ALARM stm32_rtc_alarm(CONFIG_PM_ALARM_SEC, CONFIG_PM_ALARM_NSEC, true); #endif /* Wait 10ms */ up_mdelay(10); /* Enter the STM32 stop mode */ (void)stm32_pmstop(false); /* We have been re-awakened by some even: A button press? * An alarm? Cancel any pending alarm and resume the normal * operation. */ #ifdef CONFIG_RTC_ALARM stm32_exti_cancel(); ret = stm32_rtc_cancelalarm(); if (ret < 0) { lldbg("Warning: Cancel alarm failed\n"); } #endif /* Note: See the additional PM_STANDBY related logic at the * beginning of this function. That logic is executed after * this point. */ } break; case PM_SLEEP: { /* We should not return from standby mode. The only way out * of standby is via the reset path. */ /* Configure the RTC alarm to Auto Reset the system */ #ifdef CONFIG_PM_SLEEP_WAKEUP stm32_rtc_alarm(CONFIG_PM_SLEEP_WAKEUP_SEC, CONFIG_PM_SLEEP_WAKEUP_NSEC, false); #endif /* Wait 10ms */ up_mdelay(10); /* Enter the STM32 standby mode */ (void)stm32_pmstandby(); } break; default: break; } /* Save the new state */ oldstate = newstate; errout: sched_unlock(); } }
static void up_idlepm(void) { static enum pm_state_e oldstate = PM_NORMAL; enum pm_state_e newstate; irqstate_t flags; int ret; /* Decide, which power saving level can be obtained */ newstate = pm_checkstate(); /* Check for state changes */ if (newstate != oldstate) { flags = irqsave(); /* Perform board-specific, state-dependent logic here */ llvdbg("newstate= %d oldstate=%d\n", newstate, oldstate); /* Then force the global state change */ ret = pm_changestate(newstate); if (ret < 0) { /* The new state change failed, revert to the preceding state */ (void)pm_changestate(oldstate); } else { /* Save the new state */ oldstate = newstate; } /* MCU-specific power management logic */ switch (newstate) { case PM_NORMAL: break; case PM_IDLE: break; case PM_STANDBY: stm32_pmstop(true); break; case PM_SLEEP: (void)stm32_pmstandby(); break; default: break; } irqrestore(flags); } }