pm: use pm_lock/unlock with domain lock

Signed-off-by: zhuyanlin <zhuyanlin1@xiaomi.com>
This commit is contained in:
zhuyanlin 2022-05-06 14:35:54 +08:00 committed by Xiang Xiao
parent 01aa0c2d46
commit 4329967a01
10 changed files with 45 additions and 28 deletions

View File

@ -235,7 +235,7 @@ static void governor_activity(int domain, int count)
{ {
/* Add the activity count to the accumulated counts. */ /* Add the activity count to the accumulated counts. */
flags = pm_lock(); flags = pm_lock(domain);
accum = (uint32_t)pdomstate->accum + count; accum = (uint32_t)pdomstate->accum + count;
/* Make sure that we do not overflow the underlying representation */ /* 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); 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(). * logic in governor_activity().
*/ */
flags = pm_lock(); flags = pm_lock(domain);
/* Check the elapsed time. In periods of low activity, time slicing is /* Check the elapsed time. In periods of low activity, time slicing is
* controlled by IDLE loop polling; in periods of higher activity, time * 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; return pdomstate->recommended;
} }

View File

@ -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 * 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. */ /* Find the lowest power-level which is not locked. */
@ -131,7 +131,7 @@ static enum pm_state_e greedy_governor_checkstate(int domain)
state++; state++;
} }
pm_unlock(flags); pm_unlock(domain, flags);
/* Return the found state */ /* Return the found state */

View File

@ -72,6 +72,12 @@ struct pm_domain_s
/* A pointer to the PM governor instance */ /* A pointer to the PM governor instance */
FAR const struct pm_governor_s *governor; 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 */ /* 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: * Description:
* Lock the power management operation. * 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 * Name: pm_unlock
@ -133,9 +142,12 @@ irqstate_t pm_lock(void);
* Description: * Description:
* Unlock the power management operation. * 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 #undef EXTERN
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@ -111,11 +111,11 @@ void pm_stay(int domain, enum pm_state_e state)
DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS); DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
pdom = &g_pmglobals.domain[domain]; pdom = &g_pmglobals.domain[domain];
flags = pm_lock(); flags = pm_lock(domain);
DEBUGASSERT(state < PM_COUNT); DEBUGASSERT(state < PM_COUNT);
DEBUGASSERT(pdom->stay[state] < UINT16_MAX); DEBUGASSERT(pdom->stay[state] < UINT16_MAX);
pdom->stay[state]++; pdom->stay[state]++;
pm_unlock(flags); pm_unlock(domain, flags);
pm_auto_updatestate(domain); 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); DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
pdom = &g_pmglobals.domain[domain]; pdom = &g_pmglobals.domain[domain];
flags = pm_lock(); flags = pm_lock(domain);
DEBUGASSERT(state < PM_COUNT); DEBUGASSERT(state < PM_COUNT);
DEBUGASSERT(pdom->stay[state] > 0); DEBUGASSERT(pdom->stay[state] > 0);
pdom->stay[state]--; pdom->stay[state]--;
pm_unlock(flags); pm_unlock(domain, flags);
pm_auto_updatestate(domain); pm_auto_updatestate(domain);
} }

View File

@ -109,9 +109,9 @@ void pm_auto_update(int domain, bool auto_update)
DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS); DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
pdom = &g_pmglobals.domain[domain]; pdom = &g_pmglobals.domain[domain];
flags = pm_lock(); flags = pm_lock(domain);
pdom->auto_update = auto_update; pdom->auto_update = auto_update;
pm_unlock(flags); pm_unlock(domain, flags);
} }
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */

View File

@ -213,7 +213,7 @@ int pm_changestate(int domain, enum pm_state_e newstate)
* re-enabled. * re-enabled.
*/ */
flags = pm_lock(); flags = pm_lock(domain);
/* First, prepare the drivers for the state change. In this phase, /* First, prepare the drivers for the state change. In this phase,
* drivers may refuse the state state change. * 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 */ /* Restore the interrupt state */
pm_unlock(flags); pm_unlock(domain, flags);
return ret; return ret;
} }

View File

@ -25,6 +25,7 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <nuttx/power/pm.h> #include <nuttx/power/pm.h>
#include <nuttx/semaphore.h>
#include "pm.h" #include "pm.h"
@ -87,6 +88,8 @@ void pm_initialize(void)
gov = &null; gov = &null;
#endif #endif
pm_set_governor(i, gov); pm_set_governor(i, gov);
nxsem_init(&g_pmglobals.domain[i].sem, 0, 1);
} }
} }

View File

@ -42,13 +42,16 @@
* Description: * Description:
* Lock the power management operation. * 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()) if (!up_interrupt_context() && !sched_idletask())
{ {
nxsem_wait_uninterruptible(&g_pmglobals.regsem); nxsem_wait_uninterruptible(&g_pmglobals.domain[domain].sem);
} }
return enter_critical_section(); return enter_critical_section();
@ -60,15 +63,18 @@ irqstate_t pm_lock(void)
* Description: * Description:
* Unlock the power management operation. * 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); leave_critical_section(flags);
if (!up_interrupt_context() && !sched_idletask()) if (!up_interrupt_context() && !sched_idletask())
{ {
nxsem_post(&g_pmglobals.regsem); nxsem_post(&g_pmglobals.domain[domain].sem);
} }
} }

View File

@ -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 */ /* 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); dq_addlast(&callbacks->entry, &g_pmglobals.registry);
nxsem_post(&g_pmglobals.regsem);
pm_unlock(flags);
return 0; return 0;
} }

View File

@ -55,15 +55,13 @@
int pm_unregister(FAR struct pm_callback_s *callbacks) int pm_unregister(FAR struct pm_callback_s *callbacks)
{ {
irqstate_t flags;
DEBUGASSERT(callbacks); DEBUGASSERT(callbacks);
/* Remove entry from the list of registered callbacks. */ /* Remove entry from the list of registered callbacks. */
flags = pm_lock(); nxsem_wait(&g_pmglobals.regsem);
dq_rem(&callbacks->entry, &g_pmglobals.registry); dq_rem(&callbacks->entry, &g_pmglobals.registry);
pm_unlock(flags); nxsem_post(&g_pmglobals.regsem);
return 0; return 0;
} }