power: fix condition for available starting state 88/285388/4
authorYoungjae Cho <y0.cho@samsung.com>
Mon, 12 Dec 2022 02:17:00 +0000 (11:17 +0900)
committerYoungjae Cho <y0.cho@samsung.com>
Mon, 12 Dec 2022 04:37:18 +0000 (13:37 +0900)
 The condition for checking queue should have come first. This matters
during a system haven't been initialized, that is before the call of
delayed_init_callback(). Before the delayed_init_callback(), all
requests are enqueued even though transition is not underway. In this
case, it is possible to meet the both condtitions below:
  1. there is no ongoing transition
  2. there are some enqueued transitions
In this situation, we must select the last state of transition as an
available state. But the previous condition chooses the current state.

Change-Id: If6285e2ca78734378ac9b626947b24ebb3d8594d
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
src/power/power.c

index e44b7ed..e9b2a02 100644 (file)
@@ -324,15 +324,17 @@ static uint64_t available_starting_state(void)
 {
        struct trans_info *ti = NULL;
 
-       // If there is no ongoing transition, the available state is the current state.
-       if (!transition_context.ongoing)
-               return current;
-
-       // If there is ongoing transition and there are also some pending transitions,
-       // the available state is the last state of pending transitions.
-       // Otherwise, if there is ongoing transition but there are no pending transitions,
-       // the available state is the destination of ongoing transition.
-       return (ti = g_queue_peek_head(transition_queue)) ? ti->next : transition_context.ti.next;
+       // If there is pending transition,
+       // the available state is the last state of pendiong transitions.
+       ti = g_queue_peek_head(transition_queue);
+       if (ti)
+               return ti->next;
+
+       // If a transition is underway and there is no other queued transitions,
+       // the available state is the destination of the ongoing transition.
+       // Otherwise, if there neither ongoing nor queued transitions are,
+       // the available state is the current state.
+       return transition_context.ongoing ? transition_context.ti.next : current;
 }
 
 static int dequeue_transition(struct trans_info *ti)
@@ -646,6 +648,12 @@ static int transition_request_callback(void *data)
        // TODO: immediate handling of poweroff?
 
        if (!delayed_init_done || transition_context.ongoing) {
+               // Processes starting later than the deviced wanted to be informed
+               // about power transition that has happend before the process start. To
+               // this end, all transitions are delayed after the delayed_init_callback(),
+               // which is called on completing delayed.target. Therefore it is guaranteed
+               // that all processes that starts before delayed.target can receieve all
+               // power transition information.
                enqueue_transition(&ti);
                return 0;
        }