From f0a1a2dc0b934769ead66d3405a333c4a288b067 Mon Sep 17 00:00:00 2001 From: ligd Date: Fri, 10 Jun 2022 20:34:20 +0800 Subject: [PATCH] power: add pm_stay_timeout API Signed-off-by: ligd --- drivers/power/pm.h | 1 + drivers/power/pm_activity.c | 93 +++++++++++++++++++++++++++++++++++++ include/nuttx/power/pm.h | 24 ++++++++++ 3 files changed, 118 insertions(+) diff --git a/drivers/power/pm.h b/drivers/power/pm.h index 0ae9a934738..ee05f221cbb 100644 --- a/drivers/power/pm.h +++ b/drivers/power/pm.h @@ -58,6 +58,7 @@ struct pm_domain_s /* The power state lock count */ uint16_t stay[PM_COUNT]; + struct wdog_s wdog[PM_COUNT]; /* Auto update or not */ diff --git a/drivers/power/pm_activity.c b/drivers/power/pm_activity.c index 4958542f9a4..f965327084a 100644 --- a/drivers/power/pm_activity.c +++ b/drivers/power/pm_activity.c @@ -35,6 +35,30 @@ #ifdef CONFIG_PM +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void pm_stay_normal_cb(wdparm_t arg) +{ + pm_relax(arg, PM_NORMAL); +} + +static void pm_stay_idle_cb(wdparm_t arg) +{ + pm_relax(arg, PM_IDLE); +} + +static void pm_stay_standby_cb(wdparm_t arg) +{ + pm_relax(arg, PM_STANDBY); +} + +static void pm_stay_sleep_cb(wdparm_t arg) +{ + pm_relax(arg, PM_SLEEP); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -160,6 +184,75 @@ void pm_relax(int domain, enum pm_state_e state) pm_auto_updatestate(domain); } +/**************************************************************************** + * Name: pm_stay_timeout + * + * Description: + * This function is called by a device driver to indicate that it is + * performing meaningful activities (non-idle), needs the power at kept + * last the specified level. + * And this will be timeout after time (ms), menas auto pm_relax + * + * Input Parameters: + * domain - The domain of the PM activity + * state - The state want to stay. + * ms - The timeout value ms + * + * Returned Value: + * None. + * + * Assumptions: + * This function may be called from an interrupt handler. + * + ****************************************************************************/ + +void pm_stay_timeout(int domain, enum pm_state_e state, int ms) +{ + FAR struct pm_domain_s *pdom; + FAR struct wdog_s *wdog; + wdentry_t wdentry; + irqstate_t flags; + + DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS); + DEBUGASSERT(state < PM_COUNT); + + pdom = &g_pmglobals.domain[domain]; + wdog = &pdom->wdog[state]; + + flags = pm_lock(domain); + + if (!WDOG_ISACTIVE(wdog)) + { + DEBUGASSERT(pdom->stay[state] < UINT16_MAX); + pdom->stay[state]++; + } + + switch (state) + { + case PM_NORMAL: + wdentry = pm_stay_normal_cb; + break; + case PM_IDLE: + wdentry = pm_stay_idle_cb; + break; + case PM_STANDBY: + wdentry = pm_stay_standby_cb; + break; + default: + wdentry = pm_stay_sleep_cb; + break; + } + + if (TICK2MSEC(wd_gettime(wdog)) < ms) + { + wd_start(wdog, MSEC2TICK(ms), wdentry, domain); + } + + pm_unlock(domain, flags); + + pm_auto_updatestate(domain); +} + /**************************************************************************** * Name: pm_staycount * diff --git a/include/nuttx/power/pm.h b/include/nuttx/power/pm.h index 29cc0cfb37c..97021df7e93 100644 --- a/include/nuttx/power/pm.h +++ b/include/nuttx/power/pm.h @@ -499,6 +499,30 @@ void pm_stay(int domain, enum pm_state_e state); void pm_relax(int domain, enum pm_state_e state); +/**************************************************************************** + * Name: pm_stay_timeout + * + * Description: + * This function is called by a device driver to indicate that it is + * performing meaningful activities (non-idle), needs the power at kept + * last the specified level. + * And this will be timeout after time (ms), menas auto pm_relax + * + * Input Parameters: + * domain - The domain of the PM activity + * state - The state want to stay. + * ms - The timeout value ms + * + * Returned Value: + * None. + * + * Assumptions: + * This function may be called from an interrupt handler. + * + ****************************************************************************/ + +void pm_stay_timeout(int domain, enum pm_state_e state, int ms); + /**************************************************************************** * Name: pm_staycount *