4 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
23 #include <linux/input.h>
24 #include <libsyscommon/libgdbus.h>
25 #include <libsyscommon/list.h>
26 #include <libsyscommon/proc.h>
27 #include <device/power-internal.h>
29 #include "shared/devices.h"
30 #include "shared/device-notifier.h"
31 #include "shared/log.h"
32 #include "shared/common.h"
34 #include "power-suspend.h"
35 #include "power-dbus.h"
36 #include "power-boot.h"
37 #include "power-off.h"
38 #include "power-event-lock.h"
40 #define POWER_CONF_FILE "/etc/deviced/power.conf"
41 #define DEFAULT_MAX_WAIT_SECOND 5 /* second */
42 #define MAX_DESC_LEN 256
43 #define TRANSITION_CONFIRM 0
44 #define TRANSITION_CANCEL 1
46 static int delayed_init_done = 0;
47 static uint64_t current = DEVICED_POWER_STATE_START; /* current power state */
48 static int max_wait_timeout = DEFAULT_MAX_WAIT_SECOND;
49 static GQueue *transition_queue;
53 struct syscommon_plugin_deviced_power_trans_info ti;
58 * If the cancel is set during a transition,
59 * undo the transition instead of doing action
60 * on reaching the destination state.
70 static GList *proc_list;
72 struct change_state_wait {
74 guint64 transition_id;
78 static const uint64_t transient_scenario_suspending[] = {
79 DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_EARLY,
80 DEVICED_POWER_TRANSIENT_STATE_SUSPENDING,
81 DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_LATE,
84 static const uint64_t transient_scenario_resuming[] = {
85 DEVICED_POWER_TRANSIENT_STATE_RESUMING_EARLY,
86 DEVICED_POWER_TRANSIENT_STATE_RESUMING,
87 DEVICED_POWER_TRANSIENT_STATE_RESUMING_LATE,
92 const uint64_t *scenario;
93 } transient[DEVICED_POWER_STATE_MAX_INDEX][DEVICED_POWER_STATE_MAX_INDEX] = {
94 [DEVICED_POWER_STATE_START_INDEX][DEVICED_POWER_STATE_SLEEP_INDEX] = {
95 .max_step = ARRAY_SIZE(transient_scenario_suspending),
96 .scenario = transient_scenario_suspending,
98 [DEVICED_POWER_STATE_NORMAL_INDEX][DEVICED_POWER_STATE_SLEEP_INDEX] = {
99 .max_step = ARRAY_SIZE(transient_scenario_suspending),
100 .scenario = transient_scenario_suspending,
102 [DEVICED_POWER_STATE_SLEEP_INDEX][DEVICED_POWER_STATE_NORMAL_INDEX] = {
103 .max_step = ARRAY_SIZE(transient_scenario_resuming),
104 .scenario = transient_scenario_resuming,
108 static int transition_request_callback(void *data);
109 static void prepare_transition(const struct syscommon_plugin_deviced_power_trans_info *ti);
110 static void action_transition(void);
111 static uint64_t get_next_state(void);
113 static void pre_action_normal(const void *data);
114 static void pre_action_poweroff(const void *data);
115 static void (*const pre_action_state[DEVICED_POWER_STATE_MAX_INDEX]) (const void *) = {
116 [DEVICED_POWER_STATE_NORMAL_INDEX] = pre_action_normal,
117 [DEVICED_POWER_STATE_POWEROFF_INDEX] = pre_action_poweroff,
118 [DEVICED_POWER_STATE_REBOOT_INDEX] = pre_action_poweroff,
119 [DEVICED_POWER_STATE_EXIT_INDEX] = pre_action_poweroff,
122 static void post_action_sleep(const void *data);
123 static void post_action_poweroff(const void *data);
124 static void (*const post_action_state[DEVICED_POWER_STATE_MAX_INDEX]) (const void *) = {
125 [DEVICED_POWER_STATE_SLEEP_INDEX] = post_action_sleep,
126 [DEVICED_POWER_STATE_POWEROFF_INDEX] = post_action_poweroff,
127 [DEVICED_POWER_STATE_REBOOT_INDEX] = post_action_poweroff,
128 [DEVICED_POWER_STATE_EXIT_INDEX] = post_action_poweroff,
132 uint64_t power_get_state(void)
137 static void cleanup_waiting_list(gpointer data)
139 struct change_state_wait *csw = (struct change_state_wait *) data;
141 _E("%s(pid=%d) hasn't confirmed id=%"PRIu64"(%s)",
142 csw->pi->comm, csw->pi->pid, csw->transition_id, state_name(csw->state));
144 if (kill(csw->pi->pid, 0) != 0) {
145 _E("cleanup not existing process: %s(pid=%d)", csw->pi->comm, csw->pi->pid);
146 proc_list = g_list_remove(proc_list, csw->pi);
153 static gboolean max_wait_expired_cb(void *data)
155 transition_context.max_wait_timer = 0;
157 g_list_free_full(g_steal_pointer(&transition_context.waitings), cleanup_waiting_list);
161 return G_SOURCE_REMOVE;
164 static gint find_pi_by_pid(gconstpointer data, gconstpointer udata)
166 const struct proc_info *pi = (const struct proc_info *) data;
167 const pid_t pid = *(const pid_t *) udata;
175 int add_change_state_wait(pid_t pid, guint64 state)
177 struct proc_info *pi = NULL;
180 l = g_list_find_custom(proc_list, &pid, find_pi_by_pid);
183 pi->state_bitmap |= state;
184 _D("pid=%d(%s) updated csw for %#"PRIx64, pi->pid, pi->comm, state);
188 pi = calloc(1, sizeof(struct proc_info));
193 pi->state_bitmap = state;
194 syscommon_proc_get_comm(pid, pi->comm, sizeof(pi->comm));
195 proc_list = g_list_append(proc_list, pi);
197 _D("pid=%d(%s) added csw for %#"PRIx64, pid, pi->comm, state);
202 void remove_change_state_wait(pid_t pid, guint64 state)
204 struct proc_info *pi = NULL;
207 l = g_list_find_custom(proc_list, &pid, find_pi_by_pid);
216 _D("pid=%d(%s) removed csw for %#"PRIx64, pi->pid, pi->comm, state);
218 pi->state_bitmap &= ~state;
219 if (pi->state_bitmap == 0) {
220 proc_list = g_list_remove_link(proc_list, l);
221 free(g_steal_pointer(&l->data));
226 static gint find_csw_by_pid_id(gconstpointer data, gconstpointer udata)
228 const struct change_state_wait *csw = (const struct change_state_wait *) data;
229 const struct change_state_wait *target = (const struct change_state_wait *) udata;
231 if (csw->pi->pid == target->pi->pid && csw->transition_id == target->transition_id)
237 static int handle_change_state_wait(pid_t pid, guint64 transition_id, int transition_cancel)
239 struct proc_info target_pi = { .pid = pid };
240 struct change_state_wait target_csw = { .pi = &target_pi, .transition_id = transition_id };
241 struct change_state_wait *csw = NULL;
244 l = g_list_find_custom(transition_context.waitings, &target_csw, find_csw_by_pid_id);
252 if (transition_cancel == TRANSITION_CANCEL)
253 CRITICAL_LOG("pid=%d(%s) cancelled id=%"PRIu64"(%s)", csw->pi->pid, csw->pi->comm, csw->transition_id, state_name(csw->state));
255 _D("pid=%d(%s) confirmed id=%"PRIu64"(%s)", csw->pi->pid, csw->pi->comm, csw->transition_id, state_name(csw->state));
257 transition_context.waitings = g_list_remove_link(transition_context.waitings, l);
258 free(g_steal_pointer(&l->data));
262 if (g_list_length(transition_context.waitings) != 0)
265 // the last csw is cleared
266 g_source_remove(transition_context.max_wait_timer);
267 transition_context.max_wait_timer = 0;
274 int confirm_change_state_wait(pid_t pid, guint64 transition_id)
276 return handle_change_state_wait(pid, transition_id, TRANSITION_CONFIRM);
279 int cancel_change_state_wait(pid_t pid, guint64 transition_id)
281 /* do not allow cancelling poweroff transition */
282 if (is_poweroff_state(transition_context.ti.next))
283 return handle_change_state_wait(pid, transition_id, TRANSITION_CONFIRM);
285 transition_context.cancel = 1;
287 return handle_change_state_wait(pid, transition_id, TRANSITION_CANCEL);
290 static uint64_t alloc_unique_id(void)
292 static uint64_t id = 0;
297 static void pre_action_normal(const void *udata)
299 if (transition_context.ti.curr == DEVICED_POWER_STATE_SLEEP)
300 power_resume(transition_context.ti.reason);
303 static void post_action_sleep(const void *udata)
305 power_suspend(transition_context.ti.reason);
308 static void pre_action_poweroff(const void *data)
310 // do not transition anymore after poweroff
311 syscommon_notifier_unsubscribe_notify(DEVICED_NOTIFIER_REQUEST_TRANSITION_STATE, transition_request_callback);
312 poweroff_prepare(current);
315 static void post_action_poweroff(const void *data)
317 poweroff_main((void *)(intptr_t) current);
320 static void broadcast_transition_info(void)
322 uint64_t curr = DEVICED_POWER_STATE_INDEX(transition_context.ti.curr);
323 uint64_t next = DEVICED_POWER_STATE_INDEX(get_next_state());
325 assert(DEVICED_POWER_STATE_MIN_INDEX <= curr && curr < DEVICED_POWER_TRANSIENT_STATE_MAX_INDEX);
326 assert(DEVICED_POWER_STATE_MIN_INDEX <= next && next < DEVICED_POWER_TRANSIENT_STATE_MAX_INDEX);
328 static const char* mapping_signame[DEVICED_POWER_TRANSIENT_STATE_MAX_INDEX] = {
329 [DEVICED_POWER_STATE_START_INDEX] = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_START,
330 [DEVICED_POWER_STATE_NORMAL_INDEX] = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_NORMAL,
331 [DEVICED_POWER_STATE_SLEEP_INDEX] = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_SLEEP,
332 [DEVICED_POWER_STATE_POWEROFF_INDEX] = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_POWEROFF,
333 [DEVICED_POWER_STATE_REBOOT_INDEX] = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_REBOOT,
334 [DEVICED_POWER_STATE_EXIT_INDEX] = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_EXIT,
335 [DEVICED_POWER_TRANSIENT_STATE_RESUMING_EARLY_INDEX] = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_RESUMING_EARLY,
336 [DEVICED_POWER_TRANSIENT_STATE_RESUMING_INDEX] = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_RESUMING,
337 [DEVICED_POWER_TRANSIENT_STATE_RESUMING_LATE_INDEX] = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_RESUMING_LATE,
338 [DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_EARLY_INDEX] = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_SUSPENDING_EARLY,
339 [DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_INDEX] = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_SUSPENDING,
340 [DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_LATE_INDEX] = DEVICED_SIGNAL_POWER_CHANGE_STATE_TO_SUSPENDING_LATE,
343 // convert deviced state to a correspond device enum
344 static const uint64_t mapping_device_state[DEVICED_POWER_TRANSIENT_STATE_MAX_INDEX] = {
345 [DEVICED_POWER_STATE_START_INDEX] = DEVICE_POWER_STATE_START,
346 [DEVICED_POWER_STATE_NORMAL_INDEX] = DEVICE_POWER_STATE_NORMAL,
347 [DEVICED_POWER_STATE_SLEEP_INDEX] = DEVICE_POWER_STATE_SLEEP,
348 [DEVICED_POWER_STATE_POWEROFF_INDEX] = DEVICE_POWER_STATE_POWEROFF,
349 [DEVICED_POWER_STATE_REBOOT_INDEX] = DEVICE_POWER_STATE_REBOOT,
350 [DEVICED_POWER_STATE_EXIT_INDEX] = DEVICE_POWER_STATE_EXIT,
351 [DEVICED_POWER_TRANSIENT_STATE_RESUMING_EARLY_INDEX] = DEVICE_POWER_TRANSIENT_STATE_RESUMING_EARLY,
352 [DEVICED_POWER_TRANSIENT_STATE_RESUMING_INDEX] = DEVICE_POWER_TRANSIENT_STATE_RESUMING,
353 [DEVICED_POWER_TRANSIENT_STATE_RESUMING_LATE_INDEX] = DEVICE_POWER_TRANSIENT_STATE_RESUMING_LATE,
354 [DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_EARLY_INDEX] = DEVICE_POWER_TRANSIENT_STATE_SUSPENDING_EARLY,
355 [DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_INDEX] = DEVICE_POWER_TRANSIENT_STATE_SUSPENDING,
356 [DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_LATE_INDEX] = DEVICE_POWER_TRANSIENT_STATE_SUSPENDING_LATE,
359 gdbus_signal_emit(NULL, DEVICED_PATH_POWER, DEVICED_INTERFACE_POWER, mapping_signame[next],
360 g_variant_new("(ttti)",
361 mapping_device_state[curr],
362 mapping_device_state[next],
363 transition_context.id,
364 transition_context.ti.reason));
367 int is_there_pending_transition(void)
369 return (g_queue_peek_tail(transition_queue) != NULL);
372 static uint64_t available_starting_state(void)
374 struct syscommon_plugin_deviced_power_trans_info *ti = NULL;
376 // If there is pending transition,
377 // the available state is the last state of pendiong transitions.
378 ti = g_queue_peek_head(transition_queue);
382 // If a transition is underway and there is no other queued transitions,
383 // the available state is the destination of the ongoing transition.
384 // Otherwise, if there neither ongoing nor queued transitions are,
385 // the available state is the current state.
386 return transition_context.ongoing ? transition_context.ti.next : current;
389 static int dequeue_transition(struct syscommon_plugin_deviced_power_trans_info *ti)
391 struct syscommon_plugin_deviced_power_trans_info *tail = NULL;
393 tail = g_queue_pop_tail(transition_queue);
405 static void enqueue_transition(const struct syscommon_plugin_deviced_power_trans_info *ti)
407 struct syscommon_plugin_deviced_power_trans_info *ti_new = NULL;
412 ti_new = calloc(1, sizeof(struct syscommon_plugin_deviced_power_trans_info));
418 g_queue_push_head(transition_queue, ti_new);
421 // intermediate state of ongoing transition
422 // it might be a transient state or a destination state
423 static uint64_t get_next_state(void)
425 int curr = DEVICED_POWER_STATE_INDEX(transition_context.ti.curr);
426 int next = DEVICED_POWER_STATE_INDEX(transition_context.ti.next);
427 int step = transition_context.transient_step;
429 if (step >= transient[curr][next].max_step)
430 return transition_context.ti.next;
432 return transient[curr][next].scenario[step];
435 static void init_waiting_list(gpointer data, gpointer udata)
437 uint64_t waiting_state;
438 struct proc_info *pi = (struct proc_info *) data;
439 struct change_state_wait *csw = NULL;
441 waiting_state = get_next_state();
443 if ((pi->state_bitmap & waiting_state) == 0)
446 csw = calloc(1, sizeof(struct change_state_wait));
450 *csw = (struct change_state_wait) {
452 .transition_id = transition_context.id,
453 .state = waiting_state,
458 transition_context.waitings = g_list_append(transition_context.waitings, csw);
461 static char *state_abbr_name(uint64_t state)
463 if (state == DEVICED_POWER_STATE_START)
465 if (state == DEVICED_POWER_STATE_NORMAL)
467 if (state == DEVICED_POWER_STATE_SLEEP)
469 if (state == DEVICED_POWER_STATE_POWEROFF)
471 if (state == DEVICED_POWER_STATE_REBOOT)
473 if (state == DEVICED_POWER_STATE_EXIT)
475 if (state == DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_EARLY)
476 return "SUSPENDING_EARLY";
477 if (state == DEVICED_POWER_TRANSIENT_STATE_SUSPENDING)
479 if (state == DEVICED_POWER_TRANSIENT_STATE_SUSPENDING_LATE)
480 return "SUSPENDING_LATE";
481 if (state == DEVICED_POWER_TRANSIENT_STATE_RESUMING_EARLY)
482 return "RESUMING_EARLY";
483 if (state == DEVICED_POWER_TRANSIENT_STATE_RESUMING)
485 if (state == DEVICED_POWER_TRANSIENT_STATE_RESUMING_LATE)
486 return "RESUMING_LATE";
491 static void reload_transition_sequence(GList **sequence)
493 GList *new_sequence = NULL;
494 int curr, next, step;
496 g_list_free(g_steal_pointer(sequence));
498 curr = DEVICED_POWER_STATE_INDEX(transition_context.ti.curr);
499 next = DEVICED_POWER_STATE_INDEX(transition_context.ti.next);
501 new_sequence = g_list_append(new_sequence, state_abbr_name(transition_context.ti.curr));
502 for (step = 0; step < transient[curr][next].max_step; ++step)
503 new_sequence = g_list_append(new_sequence, state_abbr_name(transient[curr][next].scenario[step]));
504 new_sequence = g_list_append(new_sequence, state_abbr_name(transition_context.ti.next));
506 *sequence = new_sequence;
509 static const char* build_description(GList *sequence, const int seqnum)
511 static char buffer[MAX_DESC_LEN] = { 0, };
513 // leave 1 byte for terminating null character
514 char *const tail = buffer + sizeof(buffer) - 1;
516 // additional (length-1) placeholders for transitioning arrow between each state
517 int max_sequence = g_list_length(sequence) * 2 - 1;
519 GList *iter = sequence;
522 memset(buffer, 0, sizeof(buffer));
525 GList *next = iter->next;
528 head += snprintf(head, tail - head, "[%s] ", (const char *) iter->data);
530 head += snprintf(head, tail - head, " %s ", (const char *) iter->data);
536 if (n >= max_sequence)
540 head += snprintf(head, tail - head, "[=>] ");
542 head += snprintf(head, tail - head, " => ");
554 static void transition_description(int reload)
556 static GList *transition_sequence = NULL;
557 static int seqnum = 0;
561 reload_transition_sequence(&transition_sequence);
564 _D("%s", build_description(transition_sequence, seqnum++));
567 static void trigger_transition(void)
571 assert(current != DEVICED_POWER_STATE_POWEROFF);
572 assert(current != DEVICED_POWER_STATE_REBOOT);
573 assert(current != DEVICED_POWER_STATE_EXIT);
574 assert(transition_context.max_wait_timer == 0);
576 transition_context.id = alloc_unique_id();
578 if (!transition_context.ongoing) {
579 // hold secondary wakelock not to fall asleep during transition
580 event_wake_lock(EL_POWER_TRANSITION_STATE);
581 transition_context.ongoing = 1;
584 transition_description(0);
586 broadcast_transition_info();
587 g_list_foreach(proc_list, init_waiting_list, &waiting);
589 transition_context.max_wait_timer = g_timeout_add_seconds(max_wait_timeout, max_wait_expired_cb, NULL);
594 static void cancel_transition(void)
596 struct syscommon_plugin_deviced_power_trans_info *ti = NULL;
598 struct syscommon_plugin_deviced_power_trans_info poweroff = { .next = DEVICED_POWER_STATE_UNDEFINED };
599 struct syscommon_plugin_deviced_power_trans_info undo = {
600 .curr = transition_context.ti.next,
601 .next = transition_context.ti.curr,
603 * TODO: Is it needed that a reason for this cancelling transition, such as
604 * DEVICE_POWER_TRANSITION_REASON_CANCEL_TRANSITION. Or use the previous
607 .reason = transition_context.ti.reason,
608 .data = transition_context.ti.data,
611 assert(transition_context.ongoing);
612 assert(transition_context.cancel);
615 * Discard all pending transitions except transition to the poweroff/reboot/exit state.
616 * Transition to the powerff/reboot/exit must remain intact in any case.
618 while ((ti = g_queue_peek_tail(transition_queue))) {
619 if (is_poweroff_state(ti->next)) {
621 * Save the transition.
623 * Fix the poweroff.curr to next of the previous one. This is because the transition_queue always
624 * manage its entries be chaining each other by matching those previous and next state in order.
626 dequeue_transition(&poweroff);
627 poweroff.curr = undo.next;
629 /* Discard the transition */
630 CRITICAL_LOG("Discard pending transition, curr=%s, next=%s, reason=%d",
631 state_abbr_name(ti->curr), state_abbr_name(ti->next), ti->reason);
632 dequeue_transition(NULL);
636 /* Reserve transition for undoing. */
637 enqueue_transition(&undo);
638 /* Reserve transition for poweroff. */
639 if (is_poweroff_state(poweroff.next))
640 enqueue_transition(&poweroff);
643 static void action_transition(void)
645 uint64_t state = get_next_state();
646 struct syscommon_plugin_deviced_power_trans_info ti = { 0 , };
650 transition_description(0);
652 if (state != transition_context.ti.next) {
653 // step into the next transient state
654 ++transition_context.transient_step;
655 trigger_transition();
659 /* it reached the destination state */
660 index = DEVICED_POWER_STATE_INDEX(transition_context.ti.next);
661 if (transition_context.cancel) {
666 if (pre_action_state[index])
667 pre_action_state[index](transition_context.ti.data);
669 current = transition_context.ti.next;
671 if (post_action_state[index])
672 post_action_state[index](transition_context.ti.data);
676 * transition_context.ongiong must be reset after the post_action_state().
677 * This prevents the post_action_state() from triggering another transition
678 * that might have been requested during its execution. Transition will be
679 * enqueued, not executed, if transition_context.ongoing is 1.
681 transition_context.ongoing = 0;
682 event_wake_unlock(EL_POWER_TRANSITION_STATE);
684 retval = dequeue_transition(&ti);
686 prepare_transition(&ti);
687 trigger_transition();
691 static void prepare_transition(const struct syscommon_plugin_deviced_power_trans_info *ti)
693 assert(transition_context.waitings == NULL);
694 assert(transition_context.max_wait_timer == 0);
697 transition_context.ti = (struct syscommon_plugin_deviced_power_trans_info) {
700 .reason = ti->reason,
705 transition_context.ongoing = 0;
706 transition_context.transient_step = 0;
707 transition_context.cancel = 0;
709 transition_description(1);
712 static gint find_ti_by_state(gconstpointer data, gconstpointer udata)
714 const struct syscommon_plugin_deviced_power_trans_info *ti =
715 (const struct syscommon_plugin_deviced_power_trans_info *) data;
716 const uint64_t state = *(const uint64_t *) udata;
718 if (ti->curr & state)
724 static int transition_request_callback(void *data)
727 const struct syscommon_plugin_deviced_power_trans_info *t = NULL;
728 struct syscommon_plugin_deviced_power_trans_info ti = { 0 , };
734 available = available_starting_state();
736 ti_list = (GList *) data;
738 l = g_list_find_custom(ti_list, &available, find_ti_by_state);
747 // check invalid next state
748 if (__builtin_popcountll(t->next & DEVICED_POWER_STATE_ALL) != 1) {
749 _E("Invalid next state, curr=%"PRIx64", next=%"PRIx64", reason=%d", t->curr, t->next, t->reason);
753 ti = (struct syscommon_plugin_deviced_power_trans_info) {
760 // TODO: immediate handling of poweroff?
762 if (!delayed_init_done || transition_context.ongoing) {
763 // Processes starting later than the deviced wanted to be informed
764 // about power transition that has happend before the process start. To
765 // this end, all transitions are delayed after the delayed_init_callback(),
766 // which is called on completing delayed.target. Therefore it is guaranteed
767 // that all processes that starts before delayed.target can receieve all
768 // power transition information.
769 enqueue_transition(&ti);
773 prepare_transition(&ti);
774 trigger_transition();
779 static int delayed_init_callback(void *data)
782 struct syscommon_plugin_deviced_power_trans_info ti = { 0 , };
784 delayed_init_done = 1;
786 _D("Start deferred state transition.");
788 retval = dequeue_transition(&ti);
790 prepare_transition(&ti);
791 trigger_transition();
794 power_init_autosleep();
799 static int load_max_wait_timeout(struct parse_result *result, void *user_data)
801 if (MATCH(result->section, "PowerState")
802 && MATCH(result->name, "ChangeStateMaxWaitSecond"))
803 max_wait_timeout = atoi(result->value);
808 void power_state_init(void *data)
811 transition_queue = g_queue_new();
813 ret = config_parse(POWER_CONF_FILE, load_max_wait_timeout, NULL);
815 _W("Failed to load '%s'(%d)", POWER_CONF_FILE, ret);
817 syscommon_notifier_subscribe_notify(DEVICED_NOTIFIER_DELAYED_INIT, delayed_init_callback);
818 syscommon_notifier_subscribe_notify(DEVICED_NOTIFIER_REQUEST_TRANSITION_STATE, transition_request_callback);
822 power_suspend_init();
823 power_event_lock_init();
825 /* Take the first transition.
827 * It is determined by bootreason and bootmode to which state to transition, DEVICED_POWER_STATE_NORMAL
828 * or DEVICED_POWER_STATE_SLEEP. it may stay in DEVICED_POWER_STATE_START if there is no defined action for the
829 * matching bootreason and bootmode.
831 initial_transition_by_boot_condition();
834 static const struct device_ops power_state_device_ops = {
835 DECLARE_NAME_LEN("power-state"),
836 .init = power_state_init,
837 /* It should be initilalized earlier than the almost other modules so that
838 * it can receive and handle power request from the other modules. Therefore
839 * give a high enough priority. */
843 DEVICE_OPS_REGISTER(&power_state_device_ops)