pm: use pm_lock/unlock with domain lock
Signed-off-by: zhuyanlin <zhuyanlin1@xiaomi.com>
This commit is contained in:
parent
01aa0c2d46
commit
4329967a01
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user