[PSM_REBOOT] = "PSM_REBOOT",
};
+static int delayed_init_done = 0;
static guint64 state_transition_counter = 0;
static enum psm_state current = PSM_START;
+/* hold trans_info until booting done */
+static GList *deferred_transition_list;
+
static void psm_wake_unlock(void)
{
/* for PSM_NORMAL, PSM_POWEROFF, do not wake unlock */
psm_trigger_poweroff();
}
-static int psm_transition_state_cb(void *data)
+static void transition_state(const struct trans_info *ti)
{
- GList *action_list, *elem;
- const struct trans_info *ti = NULL;
enum psm_state next;
- if (!data)
- return 0;
-
- action_list = (GList *) data;
-
- /* look for transition defined on the current state */
- SYS_G_LIST_FOREACH(action_list, elem, ti) {
- if (ti->curr == current)
- break;
- }
-
- if (!ti)
- return 0;
-
next = ti->next;
_D("Transition power state: %s -> %s, reason=%d",
else if (next == PSM_SLEEP)
psm_transition_sleep_to_sleep(ti);
}
+}
+
+static void deferred_transition_state(gpointer data)
+{
+ transition_state(data);
+}
+
+static int psm_transition_state_cb(void *data)
+{
+ GList *action_list, *elem;
+ const struct trans_info *ti = NULL;
+
+ if (!data)
+ return 0;
+
+ action_list = (GList *) data;
+
+ /* look for transition defined on the current state */
+ SYS_G_LIST_FOREACH(action_list, elem, ti) {
+ if (ti->curr == current)
+ break;
+ }
+
+ if (!ti)
+ return 0;
+
+ /* defer state transition until booting done */
+ if (!delayed_init_done) {
+ struct trans_info *deferred_ti = calloc(1, sizeof(struct trans_info));
+ if (!deferred_ti) {
+ CRITICAL_LOG("Failed to defer transition");
+ return 0;
+ }
+
+ // mocking state transition
+ current = ti->next;
+
+ memcpy(deferred_ti, ti, sizeof(struct trans_info));
+ deferred_transition_list = g_list_append(deferred_transition_list, deferred_ti);
+ _D("Defer state transition %s->%s until booting done", psm_name[ti->curr], psm_name[ti->next]);
+
+ return 0;
+ }
+
+ transition_state(ti);
return 0;
}
-static int defer_autosleep_enable(void *data)
+static int delayed_init_cb(void *data)
{
+ delayed_init_done = 1;
+
+ _D("Start deferred state transition");
+ /* rewind current state to initial state and do the deferred transition */
+ current = PSM_START;
+ g_list_free_full(deferred_transition_list, deferred_transition_state);
+ deferred_transition_list = NULL;
+ _D("Finished deferred state transition");
+
/* Deferred autosleep enable,
* This prevents system go suspend during booting */
device_notify(DEVICE_NOTIFIER_REQUEST_ENABLE_AUTOSLEEP, NULL);
{
GList *initial_ti = NULL;
- register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, defer_autosleep_enable);
+ register_notifier(DEVICE_NOTIFIER_DELAYED_INIT, delayed_init_cb);
register_notifier(DEVICE_NOTIFIER_REQUEST_TRANSITION_STATE, psm_transition_state_cb);
power_plugin_dbus_init(NULL);