From ae21df2ed3c560d4ea4ed1f1446fd1f2a396861a Mon Sep 17 00:00:00 2001 From: zhuyanlin Date: Tue, 15 Mar 2022 20:42:34 +0800 Subject: [PATCH] power: unify lock states unify critical_section and nxsem with pm_lock/pm_unlock Signed-off-by: zhuyanlin --- drivers/power/Make.defs | 2 +- drivers/power/activity_governor.c | 8 ++-- drivers/power/greedy_governor.c | 4 +- drivers/power/pm.h | 41 +++++++++-------- drivers/power/pm_activity.c | 8 ++-- drivers/power/pm_autoupdate.c | 4 +- drivers/power/pm_changestate.c | 4 +- drivers/power/pm_lock.c | 75 +++++++++++++++++++++++++++++++ drivers/power/pm_register.c | 15 +++---- drivers/power/pm_unregister.c | 13 +++--- 10 files changed, 122 insertions(+), 52 deletions(-) create mode 100644 drivers/power/pm_lock.c diff --git a/drivers/power/Make.defs b/drivers/power/Make.defs index e012547332..7c1ecb0f43 100644 --- a/drivers/power/Make.defs +++ b/drivers/power/Make.defs @@ -23,7 +23,7 @@ ifeq ($(CONFIG_PM),y) CSRCS += pm_initialize.c pm_activity.c pm_changestate.c pm_checkstate.c -CSRCS += pm_register.c pm_unregister.c pm_autoupdate.c pm_governor.c +CSRCS += pm_register.c pm_unregister.c pm_autoupdate.c pm_governor.c pm_lock.c # Governor implementations diff --git a/drivers/power/activity_governor.c b/drivers/power/activity_governor.c index 05b40463c5..dcd44c1bfc 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 = enter_critical_section(); + flags = pm_lock(); 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); } - leave_critical_section(flags); + pm_unlock(flags); } } @@ -476,7 +476,7 @@ static enum pm_state_e governor_checkstate(int domain) * logic in governor_activity(). */ - flags = enter_critical_section(); + flags = pm_lock(); /* 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) } } - leave_critical_section(flags); + pm_unlock(flags); return pdomstate->recommended; } diff --git a/drivers/power/greedy_governor.c b/drivers/power/greedy_governor.c index 09b35c01b2..43c839db05 100644 --- a/drivers/power/greedy_governor.c +++ b/drivers/power/greedy_governor.c @@ -123,7 +123,7 @@ static enum pm_state_e greedy_governor_checkstate(int domain) * invoked, which modifies the stay count which we are about to read */ - flags = enter_critical_section(); + flags = pm_lock(); /* Find the lowest power-level which is not locked. */ @@ -132,7 +132,7 @@ static enum pm_state_e greedy_governor_checkstate(int domain) state++; } - leave_critical_section(flags); + pm_unlock(flags); /* Return the found state */ diff --git a/drivers/power/pm.h b/drivers/power/pm.h index 42821bf93b..c067e12e79 100644 --- a/drivers/power/pm.h +++ b/drivers/power/pm.h @@ -41,27 +41,6 @@ * Pre-processor Definitions ****************************************************************************/ -/**************************************************************************** - * Name: pm_lock - * - * Description: - * Lock the power management registry. NOTE: This function may return - * an error if a signal is received while what (errno == EINTR). - * - ****************************************************************************/ - -#define pm_lock() nxsem_wait(&g_pmglobals.regsem); - -/**************************************************************************** - * Name: pm_unlock - * - * Description: - * Unlock the power management registry. - * - ****************************************************************************/ - -#define pm_unlock() nxsem_post(&g_pmglobals.regsem); - /**************************************************************************** * Public Types ****************************************************************************/ @@ -154,6 +133,26 @@ EXTERN struct pm_global_s g_pmglobals; void pm_auto_updatestate(int domain); +/**************************************************************************** + * Name: pm_lock + * + * Description: + * Lock the power management operation. + * + ****************************************************************************/ + +irqstate_t pm_lock(void); + +/**************************************************************************** + * Name: pm_unlock + * + * Description: + * Unlock the power management operation. + * + ****************************************************************************/ + +void pm_unlock(irqstate_t flags); + #undef EXTERN #if defined(__cplusplus) } diff --git a/drivers/power/pm_activity.c b/drivers/power/pm_activity.c index d3c73dcb8e..e0f4a7f644 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 = enter_critical_section(); + flags = pm_lock(); DEBUGASSERT(state < PM_COUNT); DEBUGASSERT(pdom->stay[state] < UINT16_MAX); pdom->stay[state]++; - leave_critical_section(flags); + pm_unlock(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 = enter_critical_section(); + flags = pm_lock(); DEBUGASSERT(state < PM_COUNT); DEBUGASSERT(pdom->stay[state] > 0); pdom->stay[state]--; - leave_critical_section(flags); + pm_unlock(flags); pm_auto_updatestate(domain); } diff --git a/drivers/power/pm_autoupdate.c b/drivers/power/pm_autoupdate.c index b0d7601af7..78463f0d4d 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 = enter_critical_section(); + flags = pm_lock(); pdom->auto_update = auto_update; - leave_critical_section(flags); + pm_unlock(flags); } #endif /* CONFIG_PM */ diff --git a/drivers/power/pm_changestate.c b/drivers/power/pm_changestate.c index d38dd0d596..e9d804c4df 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 = enter_critical_section(); + flags = pm_lock(); /* 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 */ - leave_critical_section(flags); + pm_unlock(flags); return ret; } diff --git a/drivers/power/pm_lock.c b/drivers/power/pm_lock.c new file mode 100644 index 0000000000..0e12224cbd --- /dev/null +++ b/drivers/power/pm_lock.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * drivers/power/pm_lock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include "pm.h" + +#if defined(CONFIG_PM) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pm_lock + * + * Description: + * Lock the power management operation. + * + ****************************************************************************/ + +irqstate_t pm_lock(void) +{ + if (!up_interrupt_context() && !sched_idletask()) + { + nxsem_wait_uninterruptible(&g_pmglobals.regsem); + } + + return enter_critical_section(); +} + +/**************************************************************************** + * Name: pm_unlock + * + * Description: + * Unlock the power management operation. + * + ****************************************************************************/ + +void pm_unlock(irqstate_t flags) +{ + leave_critical_section(flags); + + if (!up_interrupt_context() && !sched_idletask()) + { + nxsem_post(&g_pmglobals.regsem); + } +} + +#endif /* CONFIG_PM */ diff --git a/drivers/power/pm_register.c b/drivers/power/pm_register.c index fa95b8efa3..f676e8cb5c 100644 --- a/drivers/power/pm_register.c +++ b/drivers/power/pm_register.c @@ -56,20 +56,19 @@ int pm_register(FAR struct pm_callback_s *callbacks) { - int ret; + irqstate_t flags; DEBUGASSERT(callbacks); /* Add the new entry to the end of the list of registered callbacks */ - ret = pm_lock(); - if (ret == OK) - { - dq_addlast(&callbacks->entry, &g_pmglobals.registry); - pm_unlock(); - } + flags = pm_lock(); - return ret; + dq_addlast(&callbacks->entry, &g_pmglobals.registry); + + pm_unlock(flags); + + return 0; } #endif /* CONFIG_PM */ diff --git a/drivers/power/pm_unregister.c b/drivers/power/pm_unregister.c index bc9d0a61ed..cf3a96393f 100644 --- a/drivers/power/pm_unregister.c +++ b/drivers/power/pm_unregister.c @@ -55,20 +55,17 @@ int pm_unregister(FAR struct pm_callback_s *callbacks) { - int ret; + irqstate_t flags; DEBUGASSERT(callbacks); /* Remove entry from the list of registered callbacks. */ - ret = pm_lock(); - if (ret == OK) - { - dq_rem(&callbacks->entry, &g_pmglobals.registry); - pm_unlock(); - } + flags = pm_lock(); + dq_rem(&callbacks->entry, &g_pmglobals.registry); + pm_unlock(flags); - return ret; + return 0; } #endif /* CONFIG_PM */