mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 14:27:37 +08:00
pm: remove pm global, make per domain isolated
After change, when CONFIG_PM_NDOMAINS > 1, the pm_register will not able to get notificaion from not PM_IDLE_DOMAIN. Should use pm_domain_register as a replacement. Isolate domains from global callbacks can decrease not necessary execution, and reduce the lock instruction requirements. Signed-off-by: buxiasen <buxiasen@xiaomi.com>
This commit is contained in:
@@ -317,7 +317,7 @@ static void governor_update(int domain, int16_t accum)
|
|||||||
|
|
||||||
DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
|
DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
|
||||||
pdomstate = &g_pm_activity_governor.domain_states[domain];
|
pdomstate = &g_pm_activity_governor.domain_states[domain];
|
||||||
state = g_pmglobals.domain[domain].state;
|
state = g_pmdomains[domain].state;
|
||||||
|
|
||||||
#if CONFIG_PM_GOVERNOR_MEMORY > 1
|
#if CONFIG_PM_GOVERNOR_MEMORY > 1
|
||||||
/* We won't bother to do anything until we have accumulated
|
/* We won't bother to do anything until we have accumulated
|
||||||
@@ -469,7 +469,7 @@ static enum pm_state_e governor_checkstate(int domain)
|
|||||||
/* Get a convenience pointer to minimize all of the indexing */
|
/* Get a convenience pointer to minimize all of the indexing */
|
||||||
|
|
||||||
pdomstate = &g_pm_activity_governor.domain_states[domain];
|
pdomstate = &g_pm_activity_governor.domain_states[domain];
|
||||||
pdom = &g_pmglobals.domain[domain];
|
pdom = &g_pmdomains[domain];
|
||||||
|
|
||||||
/* Check for the end of the current time slice. This must be performed
|
/* Check for the end of the current time slice. This must be performed
|
||||||
* with interrupts disabled so that it does not conflict with the similar
|
* with interrupts disabled so that it does not conflict with the similar
|
||||||
@@ -563,7 +563,7 @@ static void governor_timer(int domain, enum pm_state_e newstate)
|
|||||||
TIME_SLICE_TICKS * CONFIG_PM_GOVERNOR_SLEEPENTER_COUNT
|
TIME_SLICE_TICKS * CONFIG_PM_GOVERNOR_SLEEPENTER_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
pdom = &g_pmglobals.domain[domain];
|
pdom = &g_pmdomains[domain];
|
||||||
pdomstate = &g_pm_activity_governor.domain_states[domain];
|
pdomstate = &g_pm_activity_governor.domain_states[domain];
|
||||||
|
|
||||||
if (newstate < PM_SLEEP && dq_empty(&pdom->wakelock[newstate]))
|
if (newstate < PM_SLEEP && dq_empty(&pdom->wakelock[newstate]))
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ static enum pm_state_e greedy_governor_checkstate(int domain)
|
|||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
pdom = &g_pmglobals.domain[domain];
|
pdom = &g_pmdomains[domain];
|
||||||
state = PM_NORMAL;
|
state = PM_NORMAL;
|
||||||
|
|
||||||
/* We disable interrupts since pm_stay()/pm_relax() could be simultaneously
|
/* We disable interrupts since pm_stay()/pm_relax() could be simultaneously
|
||||||
|
|||||||
+7
-23
@@ -53,6 +53,12 @@ struct pm_domain_s
|
|||||||
|
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
|
|
||||||
|
/* Registry is a doubly-linked list of registered power management
|
||||||
|
* callback structures.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dq_queue_t registry;
|
||||||
|
|
||||||
/* The power state lock count */
|
/* The power state lock count */
|
||||||
|
|
||||||
struct dq_queue_s wakelock[PM_COUNT];
|
struct dq_queue_s wakelock[PM_COUNT];
|
||||||
@@ -87,28 +93,6 @@ struct pm_domain_s
|
|||||||
rmutex_t lock;
|
rmutex_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This structure encapsulates all of the global data used by the PM system */
|
|
||||||
|
|
||||||
struct pm_global_s
|
|
||||||
{
|
|
||||||
/* This rmutex manages mutually exclusive access to the power management
|
|
||||||
* registry. It must be initialized to the value 1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
rmutex_t reglock;
|
|
||||||
|
|
||||||
/* registry is a doubly-linked list of registered power management
|
|
||||||
* callback structures. To ensure mutually exclusive access, this list
|
|
||||||
* must be locked by calling pm_lock() before it is accessed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
dq_queue_t registry;
|
|
||||||
|
|
||||||
/* The state information for each PM domain */
|
|
||||||
|
|
||||||
struct pm_domain_s domain[CONFIG_PM_NDOMAINS];
|
|
||||||
};
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Data
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -124,7 +108,7 @@ extern "C"
|
|||||||
|
|
||||||
/* All PM global data: */
|
/* All PM global data: */
|
||||||
|
|
||||||
EXTERN struct pm_global_s g_pmglobals;
|
EXTERN struct pm_domain_s g_pmdomains[CONFIG_PM_NDOMAINS];
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
|
|||||||
@@ -54,14 +54,14 @@ static void pm_waklock_cb(wdparm_t arg)
|
|||||||
#ifdef CONFIG_PM_PROCFS
|
#ifdef CONFIG_PM_PROCFS
|
||||||
static void pm_wakelock_stats_rm(FAR struct pm_wakelock_s *wakelock)
|
static void pm_wakelock_stats_rm(FAR struct pm_wakelock_s *wakelock)
|
||||||
{
|
{
|
||||||
FAR struct pm_domain_s *pdom = &g_pmglobals.domain[wakelock->domain];
|
FAR struct pm_domain_s *pdom = &g_pmdomains[wakelock->domain];
|
||||||
|
|
||||||
dq_rem(&wakelock->fsnode, &pdom->wakelockall);
|
dq_rem(&wakelock->fsnode, &pdom->wakelockall);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pm_wakelock_stats(FAR struct pm_wakelock_s *wakelock, bool stay)
|
static void pm_wakelock_stats(FAR struct pm_wakelock_s *wakelock, bool stay)
|
||||||
{
|
{
|
||||||
FAR struct pm_domain_s *pdom = &g_pmglobals.domain[wakelock->domain];
|
FAR struct pm_domain_s *pdom = &g_pmdomains[wakelock->domain];
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
|
||||||
if (stay)
|
if (stay)
|
||||||
@@ -121,9 +121,9 @@ void pm_activity(int domain, int priority)
|
|||||||
{
|
{
|
||||||
DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
|
DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
|
||||||
|
|
||||||
if (g_pmglobals.domain[domain].governor->activity)
|
if (g_pmdomains[domain].governor->activity)
|
||||||
{
|
{
|
||||||
g_pmglobals.domain[domain].governor->activity(domain, priority);
|
g_pmdomains[domain].governor->activity(domain, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
pm_auto_updatestate(domain);
|
pm_auto_updatestate(domain);
|
||||||
@@ -301,7 +301,7 @@ void pm_wakelock_uninit(FAR struct pm_wakelock_s *wakelock)
|
|||||||
/* Get a convenience pointer to minimize all of the indexing */
|
/* Get a convenience pointer to minimize all of the indexing */
|
||||||
|
|
||||||
domain = wakelock->domain;
|
domain = wakelock->domain;
|
||||||
pdom = &g_pmglobals.domain[domain];
|
pdom = &g_pmdomains[domain];
|
||||||
dq = &pdom->wakelock[wakelock->state];
|
dq = &pdom->wakelock[wakelock->state];
|
||||||
wdog = &wakelock->wdog;
|
wdog = &wakelock->wdog;
|
||||||
|
|
||||||
@@ -350,7 +350,7 @@ void pm_wakelock_stay(FAR struct pm_wakelock_s *wakelock)
|
|||||||
/* Get a convenience pointer to minimize all of the indexing */
|
/* Get a convenience pointer to minimize all of the indexing */
|
||||||
|
|
||||||
domain = wakelock->domain;
|
domain = wakelock->domain;
|
||||||
pdom = &g_pmglobals.domain[domain];
|
pdom = &g_pmdomains[domain];
|
||||||
dq = &pdom->wakelock[wakelock->state];
|
dq = &pdom->wakelock[wakelock->state];
|
||||||
|
|
||||||
flags = pm_domain_lock(domain);
|
flags = pm_domain_lock(domain);
|
||||||
@@ -397,7 +397,7 @@ void pm_wakelock_relax(FAR struct pm_wakelock_s *wakelock)
|
|||||||
/* Get a convenience pointer to minimize all of the indexing */
|
/* Get a convenience pointer to minimize all of the indexing */
|
||||||
|
|
||||||
domain = wakelock->domain;
|
domain = wakelock->domain;
|
||||||
pdom = &g_pmglobals.domain[domain];
|
pdom = &g_pmdomains[domain];
|
||||||
dq = &pdom->wakelock[wakelock->state];
|
dq = &pdom->wakelock[wakelock->state];
|
||||||
|
|
||||||
flags = pm_domain_lock(domain);
|
flags = pm_domain_lock(domain);
|
||||||
@@ -448,7 +448,7 @@ void pm_wakelock_staytimeout(FAR struct pm_wakelock_s *wakelock, int ms)
|
|||||||
/* Get a convenience pointer to minimize all of the indexing */
|
/* Get a convenience pointer to minimize all of the indexing */
|
||||||
|
|
||||||
domain = wakelock->domain;
|
domain = wakelock->domain;
|
||||||
pdom = &g_pmglobals.domain[domain];
|
pdom = &g_pmdomains[domain];
|
||||||
dq = &pdom->wakelock[wakelock->state];
|
dq = &pdom->wakelock[wakelock->state];
|
||||||
wdog = &wakelock->wdog;
|
wdog = &wakelock->wdog;
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ static void pm_auto_updatestate_cb(FAR void *arg)
|
|||||||
void pm_auto_updatestate(int domain)
|
void pm_auto_updatestate(int domain)
|
||||||
{
|
{
|
||||||
FAR struct pm_domain_s *pdom;
|
FAR struct pm_domain_s *pdom;
|
||||||
pdom = &g_pmglobals.domain[domain];
|
pdom = &g_pmdomains[domain];
|
||||||
|
|
||||||
if (pdom->auto_update)
|
if (pdom->auto_update)
|
||||||
{
|
{
|
||||||
@@ -113,7 +113,7 @@ void pm_auto_update(int domain, bool auto_update)
|
|||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
|
DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
|
||||||
pdom = &g_pmglobals.domain[domain];
|
pdom = &g_pmdomains[domain];
|
||||||
|
|
||||||
flags = pm_domain_lock(domain);
|
flags = pm_domain_lock(domain);
|
||||||
pdom->auto_update = auto_update;
|
pdom->auto_update = auto_update;
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ static void pm_stats_preparefail(int domain,
|
|||||||
int newstate, int ret)
|
int newstate, int ret)
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
FAR struct pm_preparefail_s *pf = &callback->preparefail[domain];
|
FAR struct pm_preparefail_s *pf = &callback->preparefail;
|
||||||
|
|
||||||
if (pf->state != PM_RESTORE)
|
if (pf->state != PM_RESTORE)
|
||||||
{
|
{
|
||||||
@@ -153,20 +153,23 @@ static void pm_stats_preparefail(int domain,
|
|||||||
|
|
||||||
static int pm_prepall(int domain, enum pm_state_e newstate, bool restore)
|
static int pm_prepall(int domain, enum pm_state_e newstate, bool restore)
|
||||||
{
|
{
|
||||||
|
FAR struct pm_domain_s *pdom;
|
||||||
|
FAR struct pm_callback_s *cb;
|
||||||
FAR dq_entry_t *entry;
|
FAR dq_entry_t *entry;
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
|
||||||
if (newstate <= g_pmglobals.domain[domain].state)
|
pdom = &g_pmdomains[domain];
|
||||||
|
if (newstate <= pdom->state)
|
||||||
{
|
{
|
||||||
/* Visit each registered callback structure in normal order. */
|
/* Visit each registered callback structure in normal order. */
|
||||||
|
|
||||||
for (entry = dq_peek(&g_pmglobals.registry);
|
for (entry = dq_peek(&pdom->registry);
|
||||||
entry && ret == OK;
|
entry && ret == OK;
|
||||||
entry = dq_next(entry))
|
entry = dq_next(entry))
|
||||||
{
|
{
|
||||||
/* Is the prepare callback supported? */
|
/* Is the prepare callback supported? */
|
||||||
|
|
||||||
FAR struct pm_callback_s *cb = (FAR struct pm_callback_s *)entry;
|
cb = (FAR struct pm_callback_s *)entry;
|
||||||
if (cb->prepare)
|
if (cb->prepare)
|
||||||
{
|
{
|
||||||
/* Yes.. prepare the driver */
|
/* Yes.. prepare the driver */
|
||||||
@@ -183,13 +186,13 @@ static int pm_prepall(int domain, enum pm_state_e newstate, bool restore)
|
|||||||
{
|
{
|
||||||
/* Visit each registered callback structure in reverse order. */
|
/* Visit each registered callback structure in reverse order. */
|
||||||
|
|
||||||
for (entry = dq_tail(&g_pmglobals.registry);
|
for (entry = dq_tail(&pdom->registry);
|
||||||
entry && ret == OK;
|
entry && ret == OK;
|
||||||
entry = dq_prev(entry))
|
entry = dq_prev(entry))
|
||||||
{
|
{
|
||||||
/* Is the prepare callback supported? */
|
/* Is the prepare callback supported? */
|
||||||
|
|
||||||
FAR struct pm_callback_s *cb = (FAR struct pm_callback_s *)entry;
|
cb = (FAR struct pm_callback_s *)entry;
|
||||||
if (cb->prepare)
|
if (cb->prepare)
|
||||||
{
|
{
|
||||||
/* Yes.. prepare the driver */
|
/* Yes.. prepare the driver */
|
||||||
@@ -227,18 +230,21 @@ static int pm_prepall(int domain, enum pm_state_e newstate, bool restore)
|
|||||||
|
|
||||||
static inline void pm_changeall(int domain, enum pm_state_e newstate)
|
static inline void pm_changeall(int domain, enum pm_state_e newstate)
|
||||||
{
|
{
|
||||||
|
FAR struct pm_domain_s *pdom;
|
||||||
|
FAR struct pm_callback_s *cb;
|
||||||
FAR dq_entry_t *entry;
|
FAR dq_entry_t *entry;
|
||||||
|
|
||||||
if (newstate <= g_pmglobals.domain[domain].state)
|
pdom = &g_pmdomains[domain];
|
||||||
|
if (newstate <= pdom->state)
|
||||||
{
|
{
|
||||||
/* Visit each registered callback structure in normal order. */
|
/* Visit each registered callback structure in normal order. */
|
||||||
|
|
||||||
for (entry = dq_peek(&g_pmglobals.registry);
|
for (entry = dq_peek(&pdom->registry);
|
||||||
entry; entry = dq_next(entry))
|
entry; entry = dq_next(entry))
|
||||||
{
|
{
|
||||||
/* Is the notification callback supported? */
|
/* Is the notification callback supported? */
|
||||||
|
|
||||||
FAR struct pm_callback_s *cb = (FAR struct pm_callback_s *)entry;
|
cb = (FAR struct pm_callback_s *)entry;
|
||||||
if (cb->notify)
|
if (cb->notify)
|
||||||
{
|
{
|
||||||
/* Yes.. notify the driver */
|
/* Yes.. notify the driver */
|
||||||
@@ -251,12 +257,12 @@ static inline void pm_changeall(int domain, enum pm_state_e newstate)
|
|||||||
{
|
{
|
||||||
/* Visit each registered callback structure in reverse order. */
|
/* Visit each registered callback structure in reverse order. */
|
||||||
|
|
||||||
for (entry = dq_tail(&g_pmglobals.registry);
|
for (entry = dq_tail(&pdom->registry);
|
||||||
entry; entry = dq_prev(entry))
|
entry; entry = dq_prev(entry))
|
||||||
{
|
{
|
||||||
/* Is the notification callback supported? */
|
/* Is the notification callback supported? */
|
||||||
|
|
||||||
FAR struct pm_callback_s *cb = (FAR struct pm_callback_s *)entry;
|
cb = (FAR struct pm_callback_s *)entry;
|
||||||
if (cb->notify)
|
if (cb->notify)
|
||||||
{
|
{
|
||||||
/* Yes.. notify the driver */
|
/* Yes.. notify the driver */
|
||||||
@@ -327,15 +333,15 @@ int pm_changestate(int domain, enum pm_state_e newstate)
|
|||||||
* Revert to the preceding state.
|
* Revert to the preceding state.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
newstate = g_pmglobals.domain[domain].state;
|
newstate = g_pmdomains[domain].state;
|
||||||
pm_prepall(domain, newstate, true);
|
pm_prepall(domain, newstate, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Statistics */
|
/* Statistics */
|
||||||
|
|
||||||
pm_stats(&g_pmglobals.domain[domain],
|
pm_stats(&g_pmdomains[domain],
|
||||||
g_pmglobals.domain[domain].state, newstate);
|
g_pmdomains[domain].state, newstate);
|
||||||
|
|
||||||
/* All drivers have agreed to the state change (or, one or more have
|
/* All drivers have agreed to the state change (or, one or more have
|
||||||
* disagreed and the state has been reverted). Set the new state.
|
* disagreed and the state has been reverted). Set the new state.
|
||||||
@@ -345,16 +351,16 @@ int pm_changestate(int domain, enum pm_state_e newstate)
|
|||||||
|
|
||||||
/* Notify governor of (possible) state change */
|
/* Notify governor of (possible) state change */
|
||||||
|
|
||||||
if (g_pmglobals.domain[domain].governor->statechanged)
|
if (g_pmdomains[domain].governor->statechanged)
|
||||||
{
|
{
|
||||||
g_pmglobals.domain[domain].governor->statechanged(domain, newstate);
|
g_pmdomains[domain].governor->statechanged(domain, newstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Domain state update after statechanged done */
|
/* Domain state update after statechanged done */
|
||||||
|
|
||||||
if (newstate != PM_RESTORE)
|
if (newstate != PM_RESTORE)
|
||||||
{
|
{
|
||||||
g_pmglobals.domain[domain].state = newstate;
|
g_pmdomains[domain].state = newstate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore the interrupt state */
|
/* Restore the interrupt state */
|
||||||
@@ -380,7 +386,7 @@ int pm_changestate(int domain, enum pm_state_e newstate)
|
|||||||
enum pm_state_e pm_querystate(int domain)
|
enum pm_state_e pm_querystate(int domain)
|
||||||
{
|
{
|
||||||
DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
|
DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
|
||||||
return g_pmglobals.domain[domain].state;
|
return g_pmdomains[domain].state;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_PM */
|
||||||
|
|||||||
@@ -73,9 +73,9 @@ enum pm_state_e pm_checkstate(int domain)
|
|||||||
{
|
{
|
||||||
DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
|
DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
|
||||||
|
|
||||||
if (g_pmglobals.domain[domain].governor->checkstate)
|
if (g_pmdomains[domain].governor->checkstate)
|
||||||
{
|
{
|
||||||
return g_pmglobals.domain[domain].governor->checkstate(domain);
|
return g_pmdomains[domain].governor->checkstate(domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PM_NORMAL;
|
return PM_NORMAL;
|
||||||
|
|||||||
@@ -75,17 +75,17 @@ int pm_set_governor(int domain, FAR const struct pm_governor_s *gov)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_pmglobals.domain[domain].governor &&
|
if (g_pmdomains[domain].governor &&
|
||||||
g_pmglobals.domain[domain].governor->deinitialize)
|
g_pmdomains[domain].governor->deinitialize)
|
||||||
{
|
{
|
||||||
g_pmglobals.domain[domain].governor->deinitialize();
|
g_pmdomains[domain].governor->deinitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pmglobals.domain[domain].governor = gov;
|
g_pmdomains[domain].governor = gov;
|
||||||
|
|
||||||
if (g_pmglobals.domain[domain].governor->initialize)
|
if (g_pmdomains[domain].governor->initialize)
|
||||||
{
|
{
|
||||||
g_pmglobals.domain[domain].governor->initialize();
|
g_pmdomains[domain].governor->initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -38,16 +38,7 @@
|
|||||||
|
|
||||||
/* All PM global data: */
|
/* All PM global data: */
|
||||||
|
|
||||||
/* Initialize the registry and the PM global data structures. The PM
|
struct pm_domain_s g_pmdomains[CONFIG_PM_NDOMAINS];
|
||||||
* global data structure resides in .data which is zeroed at boot time. So
|
|
||||||
* it is only required to initialize non-zero elements of the PM global
|
|
||||||
* data structure here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct pm_global_s g_pmglobals =
|
|
||||||
{
|
|
||||||
NXRMUTEX_INITIALIZER
|
|
||||||
};
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
@@ -98,10 +89,10 @@ void pm_initialize(void)
|
|||||||
pm_set_governor(i, gov);
|
pm_set_governor(i, gov);
|
||||||
|
|
||||||
#if defined(CONFIG_PM_PROCFS)
|
#if defined(CONFIG_PM_PROCFS)
|
||||||
clock_systime_timespec(&g_pmglobals.domain[i].start);
|
clock_systime_timespec(&g_pmdomains[i].start);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nxrmutex_init(&g_pmglobals.domain[i].lock);
|
nxrmutex_init(&g_pmdomains[i].lock);
|
||||||
|
|
||||||
#if CONFIG_PM_GOVERNOR_EXPLICIT_RELAX
|
#if CONFIG_PM_GOVERNOR_EXPLICIT_RELAX
|
||||||
for (state = 0; state < PM_COUNT; state++)
|
for (state = 0; state < PM_COUNT; state++)
|
||||||
|
|||||||
@@ -59,12 +59,12 @@ void pm_unlock(FAR rmutex_t *lock, irqstate_t flags)
|
|||||||
|
|
||||||
irqstate_t pm_domain_lock(int domain)
|
irqstate_t pm_domain_lock(int domain)
|
||||||
{
|
{
|
||||||
return pm_lock(&g_pmglobals.domain[domain].lock);
|
return pm_lock(&g_pmdomains[domain].lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pm_domain_unlock(int domain, irqstate_t flags)
|
void pm_domain_unlock(int domain, irqstate_t flags)
|
||||||
{
|
{
|
||||||
pm_unlock(&g_pmglobals.domain[domain].lock, flags);
|
pm_unlock(&g_pmdomains[domain].lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_PM */
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ static ssize_t pm_read_state(FAR struct file *filep, FAR char *buffer,
|
|||||||
/* Recover our private data from the struct file instance */
|
/* Recover our private data from the struct file instance */
|
||||||
|
|
||||||
pmfile = (FAR struct pm_file_s *)filep->f_priv;
|
pmfile = (FAR struct pm_file_s *)filep->f_priv;
|
||||||
dom = &g_pmglobals.domain[pmfile->domain];
|
dom = &g_pmdomains[pmfile->domain];
|
||||||
DEBUGASSERT(pmfile);
|
DEBUGASSERT(pmfile);
|
||||||
DEBUGASSERT(dom);
|
DEBUGASSERT(dom);
|
||||||
|
|
||||||
@@ -378,7 +378,7 @@ static ssize_t pm_read_wakelock(FAR struct file *filep, FAR char *buffer,
|
|||||||
/* Recover our private data from the struct file instance */
|
/* Recover our private data from the struct file instance */
|
||||||
|
|
||||||
pmfile = (FAR struct pm_file_s *)filep->f_priv;
|
pmfile = (FAR struct pm_file_s *)filep->f_priv;
|
||||||
dom = &g_pmglobals.domain[pmfile->domain];
|
dom = &g_pmdomains[pmfile->domain];
|
||||||
DEBUGASSERT(pmfile);
|
DEBUGASSERT(pmfile);
|
||||||
DEBUGASSERT(dom);
|
DEBUGASSERT(dom);
|
||||||
|
|
||||||
@@ -464,7 +464,7 @@ static ssize_t pm_read_preparefail(FAR struct file *filep, FAR char *buffer,
|
|||||||
/* Recover our private data from the struct file instance */
|
/* Recover our private data from the struct file instance */
|
||||||
|
|
||||||
pmfile = (FAR struct pm_file_s *)filep->f_priv;
|
pmfile = (FAR struct pm_file_s *)filep->f_priv;
|
||||||
dom = &g_pmglobals.domain[pmfile->domain];
|
dom = &g_pmdomains[pmfile->domain];
|
||||||
DEBUGASSERT(pmfile);
|
DEBUGASSERT(pmfile);
|
||||||
DEBUGASSERT(dom);
|
DEBUGASSERT(dom);
|
||||||
|
|
||||||
@@ -480,11 +480,12 @@ static ssize_t pm_read_preparefail(FAR struct file *filep, FAR char *buffer,
|
|||||||
totalsize += copysize;
|
totalsize += copysize;
|
||||||
|
|
||||||
flags = pm_domain_lock(pmfile->domain);
|
flags = pm_domain_lock(pmfile->domain);
|
||||||
for (entry = dq_peek(&g_pmglobals.registry);
|
|
||||||
|
for (entry = dq_peek(&dom->registry);
|
||||||
entry; entry = dq_next(entry))
|
entry; entry = dq_next(entry))
|
||||||
{
|
{
|
||||||
cb = (FAR struct pm_callback_s *)entry;
|
cb = (FAR struct pm_callback_s *)entry;
|
||||||
pf = &cb->preparefail[pmfile->domain];
|
pf = &cb->preparefail;
|
||||||
for (state = 0; state < PM_COUNT; state++)
|
for (state = 0; state < PM_COUNT; state++)
|
||||||
{
|
{
|
||||||
sum += pf->duration[state].tv_sec;
|
sum += pf->duration[state].tv_sec;
|
||||||
@@ -492,13 +493,13 @@ static ssize_t pm_read_preparefail(FAR struct file *filep, FAR char *buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sum = sum ? sum : 1;
|
sum = sum ? sum : 1;
|
||||||
for (entry = dq_peek(&g_pmglobals.registry);
|
for (entry = dq_peek(&dom->registry);
|
||||||
entry; entry = dq_next(entry))
|
entry; entry = dq_next(entry))
|
||||||
{
|
{
|
||||||
time_t total = 0;
|
time_t total = 0;
|
||||||
|
|
||||||
cb = (FAR struct pm_callback_s *)entry;
|
cb = (FAR struct pm_callback_s *)entry;
|
||||||
pf = &cb->preparefail[pmfile->domain];
|
pf = &cb->preparefail;
|
||||||
for (state = 0; state < PM_COUNT; state++)
|
for (state = 0; state < PM_COUNT; state++)
|
||||||
{
|
{
|
||||||
total += pf->duration[state].tv_sec;
|
total += pf->duration[state].tv_sec;
|
||||||
|
|||||||
@@ -39,14 +39,15 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: pm_register
|
* Name: pm_domain_register
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function is called by a device driver in order to register to
|
* This function is called by a device driver in order to register to
|
||||||
* receive power management event callbacks.
|
* receive power management event callbacks.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* callbacks - An instance of struct pm_callback_s providing the driver
|
* domain - Target register domain.
|
||||||
|
* cb - An instance of struct pm_callback_s providing the driver
|
||||||
* callback functions.
|
* callback functions.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@@ -54,27 +55,20 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int pm_register(FAR struct pm_callback_s *callbacks)
|
int pm_domain_register(int domain, FAR struct pm_callback_s *cb)
|
||||||
{
|
{
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
FAR struct pm_domain_s *pdom = &g_pmdomains[domain];
|
||||||
DEBUGASSERT(callbacks);
|
flags = pm_lock(&pdom->lock);
|
||||||
|
|
||||||
/* 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(&g_pmglobals.reglock);
|
dq_addlast(&cb->entry, &pdom->registry);
|
||||||
dq_addlast(&callbacks->entry, &g_pmglobals.registry);
|
#if defined (CONFIG_PM_PROCFS)
|
||||||
|
cb->preparefail.state = PM_RESTORE;
|
||||||
#ifdef CONFIG_PM_PROCFS
|
|
||||||
for (int domain = 0; domain < CONFIG_PM_NDOMAINS; domain++)
|
|
||||||
{
|
|
||||||
callbacks->preparefail[domain].state = PM_RESTORE;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
pm_unlock(&pdom->lock, flags);
|
||||||
pm_unlock(&g_pmglobals.reglock, flags);
|
return OK;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_PM */
|
||||||
|
|||||||
@@ -38,14 +38,15 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: pm_unregister
|
* Name: pm_domain_unregister
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function is called by a device driver in order to unregister
|
* This function is called by a device driver in order to unregister
|
||||||
* previously registered power management event callbacks.
|
* previously registered power management event callbacks.
|
||||||
*
|
*
|
||||||
* Input parameters:
|
* Input parameters:
|
||||||
* callbacks - An instance of struct pm_callback_s providing the driver
|
* domain - Target unregister domain.
|
||||||
|
* cb - An instance of struct pm_callback_s providing the driver
|
||||||
* callback functions.
|
* callback functions.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@@ -53,19 +54,17 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int pm_unregister(FAR struct pm_callback_s *callbacks)
|
int pm_domain_unregister(int domain, FAR struct pm_callback_s *cb)
|
||||||
{
|
{
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
struct pm_domain_s *pdom = &g_pmdomains[domain];
|
||||||
DEBUGASSERT(callbacks);
|
flags = pm_lock(&pdom->lock);
|
||||||
|
|
||||||
/* Remove entry from the list of registered callbacks. */
|
/* Remove entry from the list of registered callbacks. */
|
||||||
|
|
||||||
flags = pm_lock(&g_pmglobals.reglock);
|
dq_rem(&cb->entry, &pdom->registry);
|
||||||
dq_rem(&callbacks->entry, &g_pmglobals.registry);
|
pm_unlock(&pdom->lock, flags);
|
||||||
pm_unlock(&g_pmglobals.reglock, flags);
|
return OK;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_PM */
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ static enum pm_state_e stability_governor_checkstate(int domain)
|
|||||||
bool wdog_wakeup;
|
bool wdog_wakeup;
|
||||||
|
|
||||||
gdom = &g_stability_governor.domain[domain];
|
gdom = &g_stability_governor.domain[domain];
|
||||||
pdom = &g_pmglobals.domain[domain];
|
pdom = &g_pmdomains[domain];
|
||||||
state = PM_NORMAL;
|
state = PM_NORMAL;
|
||||||
|
|
||||||
/* We disable interrupts since pm_stay()/pm_relax() could be simultaneously
|
/* We disable interrupts since pm_stay()/pm_relax() could be simultaneously
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ struct pm_callback_s
|
|||||||
enum pm_state_e pmstate);
|
enum pm_state_e pmstate);
|
||||||
|
|
||||||
#ifdef CONFIG_PM_PROCFS
|
#ifdef CONFIG_PM_PROCFS
|
||||||
struct pm_preparefail_s preparefail[CONFIG_PM_NDOMAINS];
|
struct pm_preparefail_s preparefail;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -440,14 +440,15 @@ int pm_set_governor(int domain, FAR const struct pm_governor_s *gov);
|
|||||||
void pm_auto_update(int domain, bool auto_update);
|
void pm_auto_update(int domain, bool auto_update);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: pm_register
|
* Name: pm_domain_register
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function is called by a device driver in order to register to
|
* This function is called by a device driver in order to register to
|
||||||
* receive power management event callbacks.
|
* receive power management event callbacks.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* callbacks - An instance of struct pm_callback_s providing the driver
|
* domain - Target register domain.
|
||||||
|
* cb - An instance of struct pm_callback_s providing the driver
|
||||||
* callback functions.
|
* callback functions.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@@ -455,17 +456,20 @@ void pm_auto_update(int domain, bool auto_update);
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int pm_register(FAR struct pm_callback_s *callbacks);
|
int pm_domain_register(int domain, FAR struct pm_callback_s *cb);
|
||||||
|
|
||||||
|
#define pm_register(cb) pm_domain_register(PM_IDLE_DOMAIN, cb)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: pm_unregister
|
* Name: pm_domain_unregister
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function is called by a device driver in order to unregister
|
* This function is called by a device driver in order to unregister
|
||||||
* previously registered power management event callbacks.
|
* previously registered power management event callbacks.
|
||||||
*
|
*
|
||||||
* Input parameters:
|
* Input parameters:
|
||||||
* callbacks - An instance of struct pm_callback_s providing the driver
|
* domain - Target unregister domain.
|
||||||
|
* cb - An instance of struct pm_callback_s providing the driver
|
||||||
* callback functions.
|
* callback functions.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@@ -473,7 +477,9 @@ int pm_register(FAR struct pm_callback_s *callbacks);
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int pm_unregister(FAR struct pm_callback_s *callbacks);
|
int pm_domain_unregister(int domain, FAR struct pm_callback_s *cb);
|
||||||
|
|
||||||
|
#define pm_unregister(cb) pm_domain_unregister(PM_IDLE_DOMAIN, cb)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: pm_activity
|
* Name: pm_activity
|
||||||
|
|||||||
Reference in New Issue
Block a user