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. */
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;
}

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
*/
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 */

View File

@ -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)

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -25,6 +25,7 @@
#include <nuttx/config.h>
#include <nuttx/power/pm.h>
#include <nuttx/semaphore.h>
#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);
}
}

View File

@ -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);
}
}

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 */
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;
}

View File

@ -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;
}