From 4329967a014f8d010638ce540805fb145e3fb5f1 Mon Sep 17 00:00:00 2001 From: zhuyanlin Date: Fri, 6 May 2022 14:35:54 +0800 Subject: [PATCH] pm: use pm_lock/unlock with domain lock Signed-off-by: zhuyanlin --- drivers/power/activity_governor.c | 8 ++++---- drivers/power/greedy_governor.c | 4 ++-- drivers/power/pm.h | 16 ++++++++++++++-- drivers/power/pm_activity.c | 8 ++++---- drivers/power/pm_autoupdate.c | 4 ++-- drivers/power/pm_changestate.c | 4 ++-- drivers/power/pm_initialize.c | 3 +++ drivers/power/pm_lock.c | 14 ++++++++++---- drivers/power/pm_register.c | 6 ++---- drivers/power/pm_unregister.c | 6 ++---- 10 files changed, 45 insertions(+), 28 deletions(-) diff --git a/drivers/power/activity_governor.c b/drivers/power/activity_governor.c index 254892ab9e..44eb83c1e5 100644 --- a/drivers/power/activity_governor.c +++ b/drivers/power/activity_governor.c @@ -235,7 +235,7 @@ static void governor_activity(int domain, int count) { /* Add the activity count to the accumulated counts. */ - flags = pm_lock(); + flags = pm_lock(domain); accum = (uint32_t)pdomstate->accum + count; /* Make sure that we do not overflow the underlying representation */ @@ -275,7 +275,7 @@ static void governor_activity(int domain, int count) governor_update(domain, tmp); } - pm_unlock(flags); + pm_unlock(domain, flags); } } @@ -476,7 +476,7 @@ static enum pm_state_e governor_checkstate(int domain) * logic in governor_activity(). */ - flags = pm_lock(); + flags = pm_lock(domain); /* Check the elapsed time. In periods of low activity, time slicing is * controlled by IDLE loop polling; in periods of higher activity, time @@ -515,7 +515,7 @@ static enum pm_state_e governor_checkstate(int domain) } } - pm_unlock(flags); + pm_unlock(domain, flags); return pdomstate->recommended; } diff --git a/drivers/power/greedy_governor.c b/drivers/power/greedy_governor.c index aa2225bf70..5a234eec59 100644 --- a/drivers/power/greedy_governor.c +++ b/drivers/power/greedy_governor.c @@ -122,7 +122,7 @@ static enum pm_state_e greedy_governor_checkstate(int domain) * invoked, which modifies the stay count which we are about to read */ - flags = pm_lock(); + flags = pm_lock(domain); /* Find the lowest power-level which is not locked. */ @@ -131,7 +131,7 @@ static enum pm_state_e greedy_governor_checkstate(int domain) state++; } - pm_unlock(flags); + pm_unlock(domain, flags); /* Return the found state */ diff --git a/drivers/power/pm.h b/drivers/power/pm.h index 1814f70ec7..7c4e0668b7 100644 --- a/drivers/power/pm.h +++ b/drivers/power/pm.h @@ -72,6 +72,12 @@ struct pm_domain_s /* A pointer to the PM governor instance */ FAR const struct pm_governor_s *governor; + + /* This semaphore manages mutually exclusive access to the domain state. + * It must be initialized to the value 1. + */ + + sem_t sem; }; /* This structure encapsulates all of the global data used by the PM system */ @@ -123,9 +129,12 @@ EXTERN struct pm_global_s g_pmglobals; * Description: * Lock the power management operation. * + * Input Parameters: + * domain - The PM domain to lock + * ****************************************************************************/ -irqstate_t pm_lock(void); +irqstate_t pm_lock(int domain); /**************************************************************************** * Name: pm_unlock @@ -133,9 +142,12 @@ irqstate_t pm_lock(void); * Description: * Unlock the power management operation. * + * Input Parameters: + * domain - The PM domain to unlock + * ****************************************************************************/ -void pm_unlock(irqstate_t flags); +void pm_unlock(int domain, irqstate_t flags); #undef EXTERN #if defined(__cplusplus) diff --git a/drivers/power/pm_activity.c b/drivers/power/pm_activity.c index e0f4a7f644..4958542f9a 100644 --- a/drivers/power/pm_activity.c +++ b/drivers/power/pm_activity.c @@ -111,11 +111,11 @@ void pm_stay(int domain, enum pm_state_e state) DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS); pdom = &g_pmglobals.domain[domain]; - flags = pm_lock(); + flags = pm_lock(domain); DEBUGASSERT(state < PM_COUNT); DEBUGASSERT(pdom->stay[state] < UINT16_MAX); pdom->stay[state]++; - pm_unlock(flags); + pm_unlock(domain, flags); pm_auto_updatestate(domain); } @@ -151,11 +151,11 @@ void pm_relax(int domain, enum pm_state_e state) DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS); pdom = &g_pmglobals.domain[domain]; - flags = pm_lock(); + flags = pm_lock(domain); DEBUGASSERT(state < PM_COUNT); DEBUGASSERT(pdom->stay[state] > 0); pdom->stay[state]--; - pm_unlock(flags); + pm_unlock(domain, flags); pm_auto_updatestate(domain); } diff --git a/drivers/power/pm_autoupdate.c b/drivers/power/pm_autoupdate.c index 78463f0d4d..0f59b10d0d 100644 --- a/drivers/power/pm_autoupdate.c +++ b/drivers/power/pm_autoupdate.c @@ -109,9 +109,9 @@ void pm_auto_update(int domain, bool auto_update) DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS); pdom = &g_pmglobals.domain[domain]; - flags = pm_lock(); + flags = pm_lock(domain); pdom->auto_update = auto_update; - pm_unlock(flags); + pm_unlock(domain, flags); } #endif /* CONFIG_PM */ diff --git a/drivers/power/pm_changestate.c b/drivers/power/pm_changestate.c index e9d804c4df..2741998077 100644 --- a/drivers/power/pm_changestate.c +++ b/drivers/power/pm_changestate.c @@ -213,7 +213,7 @@ int pm_changestate(int domain, enum pm_state_e newstate) * re-enabled. */ - flags = pm_lock(); + flags = pm_lock(domain); /* First, prepare the drivers for the state change. In this phase, * drivers may refuse the state state change. @@ -249,7 +249,7 @@ int pm_changestate(int domain, enum pm_state_e newstate) /* Restore the interrupt state */ - pm_unlock(flags); + pm_unlock(domain, flags); return ret; } diff --git a/drivers/power/pm_initialize.c b/drivers/power/pm_initialize.c index 0207bb79ff..a2b376dc08 100644 --- a/drivers/power/pm_initialize.c +++ b/drivers/power/pm_initialize.c @@ -25,6 +25,7 @@ #include #include +#include #include "pm.h" @@ -87,6 +88,8 @@ void pm_initialize(void) gov = &null; #endif pm_set_governor(i, gov); + + nxsem_init(&g_pmglobals.domain[i].sem, 0, 1); } } diff --git a/drivers/power/pm_lock.c b/drivers/power/pm_lock.c index 0e12224cbd..fe496ea320 100644 --- a/drivers/power/pm_lock.c +++ b/drivers/power/pm_lock.c @@ -42,13 +42,16 @@ * Description: * Lock the power management operation. * + * Input Parameters: + * domain - The PM domain to lock + * ****************************************************************************/ -irqstate_t pm_lock(void) +irqstate_t pm_lock(int domain) { if (!up_interrupt_context() && !sched_idletask()) { - nxsem_wait_uninterruptible(&g_pmglobals.regsem); + nxsem_wait_uninterruptible(&g_pmglobals.domain[domain].sem); } return enter_critical_section(); @@ -60,15 +63,18 @@ irqstate_t pm_lock(void) * Description: * Unlock the power management operation. * + * Input Parameters: + * domain - The PM domain to unlock + * ****************************************************************************/ -void pm_unlock(irqstate_t flags) +void pm_unlock(int domain, irqstate_t flags) { leave_critical_section(flags); if (!up_interrupt_context() && !sched_idletask()) { - nxsem_post(&g_pmglobals.regsem); + nxsem_post(&g_pmglobals.domain[domain].sem); } } diff --git a/drivers/power/pm_register.c b/drivers/power/pm_register.c index f676e8cb5c..897d557134 100644 --- a/drivers/power/pm_register.c +++ b/drivers/power/pm_register.c @@ -62,11 +62,9 @@ int pm_register(FAR struct pm_callback_s *callbacks) /* Add the new entry to the end of the list of registered callbacks */ - flags = pm_lock(); - + nxsem_wait(&g_pmglobals.regsem); dq_addlast(&callbacks->entry, &g_pmglobals.registry); - - pm_unlock(flags); + nxsem_post(&g_pmglobals.regsem); return 0; } diff --git a/drivers/power/pm_unregister.c b/drivers/power/pm_unregister.c index cf3a96393f..cb786e5db4 100644 --- a/drivers/power/pm_unregister.c +++ b/drivers/power/pm_unregister.c @@ -55,15 +55,13 @@ int pm_unregister(FAR struct pm_callback_s *callbacks) { - irqstate_t flags; - DEBUGASSERT(callbacks); /* Remove entry from the list of registered callbacks. */ - flags = pm_lock(); + nxsem_wait(&g_pmglobals.regsem); dq_rem(&callbacks->entry, &g_pmglobals.registry); - pm_unlock(flags); + nxsem_post(&g_pmglobals.regsem); return 0; }