drivers/pm: PM: Decrease the power state in the reverse order. Since the child driver need power off before parent driver.
This commit is contained in:
parent
af284c1e23
commit
7f4064e511
@ -154,12 +154,12 @@ struct pm_global_s
|
|||||||
|
|
||||||
sem_t regsem;
|
sem_t regsem;
|
||||||
|
|
||||||
/* registry is a singly-linked list of registered power management
|
/* registry is a doubly-linked list of registered power management
|
||||||
* callback structures. To ensure mutually exclusive access, this list
|
* callback structures. To ensure mutually exclusive access, this list
|
||||||
* must be locked by calling pm_lock() before it is accessed.
|
* must be locked by calling pm_lock() before it is accessed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sq_queue_t registry;
|
dq_queue_t registry;
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -76,14 +76,16 @@
|
|||||||
|
|
||||||
static int pm_prepall(int domain, enum pm_state_e newstate)
|
static int pm_prepall(int domain, enum pm_state_e newstate)
|
||||||
{
|
{
|
||||||
FAR sq_entry_t *entry;
|
FAR dq_entry_t *entry;
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
|
||||||
/* Visit each registered callback structure. */
|
if (newstate <= g_pmglobals.domain[domain].state)
|
||||||
|
{
|
||||||
|
/* Visit each registered callback structure in normal order. */
|
||||||
|
|
||||||
for (entry = sq_peek(&g_pmglobals.registry);
|
for (entry = dq_peek(&g_pmglobals.registry);
|
||||||
entry && ret == OK;
|
entry && ret == OK;
|
||||||
entry = sq_next(entry))
|
entry = dq_next(entry))
|
||||||
{
|
{
|
||||||
/* Is the prepare callback supported? */
|
/* Is the prepare callback supported? */
|
||||||
|
|
||||||
@ -95,6 +97,26 @@ static int pm_prepall(int domain, enum pm_state_e newstate)
|
|||||||
ret = cb->prepare(cb, domain, newstate);
|
ret = cb->prepare(cb, domain, newstate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Visit each registered callback structure in reverse order. */
|
||||||
|
|
||||||
|
for (entry = dq_tail(&g_pmglobals.registry);
|
||||||
|
entry && ret == OK;
|
||||||
|
entry = dq_prev(entry))
|
||||||
|
{
|
||||||
|
/* Is the prepare callback supported? */
|
||||||
|
|
||||||
|
FAR struct pm_callback_s *cb = (FAR struct pm_callback_s *)entry;
|
||||||
|
if (cb->prepare)
|
||||||
|
{
|
||||||
|
/* Yes.. prepare the driver */
|
||||||
|
|
||||||
|
ret = cb->prepare(cb, domain, newstate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -120,11 +142,13 @@ static int pm_prepall(int domain, enum pm_state_e newstate)
|
|||||||
|
|
||||||
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 sq_entry_t *entry;
|
FAR dq_entry_t *entry;
|
||||||
|
|
||||||
/* Visit each registered callback structure. */
|
if (newstate <= g_pmglobals.domain[domain].state)
|
||||||
|
{
|
||||||
|
/* Visit each registered callback structure in normal order. */
|
||||||
|
|
||||||
for (entry = sq_peek(&g_pmglobals.registry); entry; entry = sq_next(entry))
|
for (entry = dq_peek(&g_pmglobals.registry); entry; entry = dq_next(entry))
|
||||||
{
|
{
|
||||||
/* Is the notification callback supported? */
|
/* Is the notification callback supported? */
|
||||||
|
|
||||||
@ -136,6 +160,24 @@ static inline void pm_changeall(int domain, enum pm_state_e newstate)
|
|||||||
cb->notify(cb, domain, newstate);
|
cb->notify(cb, domain, newstate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Visit each registered callback structure in reverse order. */
|
||||||
|
|
||||||
|
for (entry = dq_tail(&g_pmglobals.registry); entry; entry = dq_prev(entry))
|
||||||
|
{
|
||||||
|
/* Is the notification callback supported? */
|
||||||
|
|
||||||
|
FAR struct pm_callback_s *cb = (FAR struct pm_callback_s *)entry;
|
||||||
|
if (cb->notify)
|
||||||
|
{
|
||||||
|
/* Yes.. notify the driver */
|
||||||
|
|
||||||
|
cb->notify(cb, domain, newstate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -86,7 +86,7 @@ void pm_initialize(void)
|
|||||||
* data structure here.
|
* data structure here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sq_init(&g_pmglobals.registry);
|
dq_init(&g_pmglobals.registry);
|
||||||
nxsem_init(&g_pmglobals.regsem, 0, 1);
|
nxsem_init(&g_pmglobals.regsem, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ int pm_register(FAR struct pm_callback_s *callbacks)
|
|||||||
ret = pm_lock();
|
ret = pm_lock();
|
||||||
if (ret == OK)
|
if (ret == OK)
|
||||||
{
|
{
|
||||||
sq_addlast(&callbacks->entry, &g_pmglobals.registry);
|
dq_addlast(&callbacks->entry, &g_pmglobals.registry);
|
||||||
pm_unlock();
|
pm_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ int pm_unregister(FAR struct pm_callback_s *callbacks)
|
|||||||
ret = pm_lock();
|
ret = pm_lock();
|
||||||
if (ret == OK)
|
if (ret == OK)
|
||||||
{
|
{
|
||||||
sq_rem(&callbacks->entry, &g_pmglobals.registry);
|
dq_rem(&callbacks->entry, &g_pmglobals.registry);
|
||||||
pm_unlock();
|
pm_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +277,7 @@ enum pm_state_e
|
|||||||
|
|
||||||
struct pm_callback_s
|
struct pm_callback_s
|
||||||
{
|
{
|
||||||
struct sq_entry_s entry; /* Supports a singly linked list */
|
struct dq_entry_s entry; /* Supports a doubly linked list */
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* Name: prepare
|
* Name: prepare
|
||||||
|
Loading…
x
Reference in New Issue
Block a user