summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/hardwaremain.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/src/lib/hardwaremain.c b/src/lib/hardwaremain.c
index 7bf0237f91..8e5481e398 100644
--- a/src/lib/hardwaremain.c
+++ b/src/lib/hardwaremain.c
@@ -78,23 +78,27 @@ struct boot_state {
struct boot_state_callback *seq_callbacks[2];
boot_state_t (*run_state)(void *arg);
void *arg;
- int complete;
+ int complete : 1;
+ int timers_drain : 1;
#if CONFIG_HAVE_MONOTONIC_TIMER
struct boot_state_times times;
#endif
};
-#define BS_INIT(state_, run_func_) \
- { \
- .name = #state_, \
- .id = state_, \
- .seq_callbacks = { NULL, NULL },\
- .run_state = run_func_, \
- .arg = NULL, \
- .complete = 0 \
+#define BS_INIT(state_, run_func_, drain_timers_) \
+ { \
+ .name = #state_, \
+ .id = state_, \
+ .seq_callbacks = { NULL, NULL }, \
+ .run_state = run_func_, \
+ .arg = NULL, \
+ .complete = 0, \
+ .timers_drain = drain_timers_, \
}
#define BS_INIT_ENTRY(state_, run_func_) \
- [state_] = BS_INIT(state_, run_func_)
+ [state_] = BS_INIT(state_, run_func_, 0)
+#define BS_INIT_ENTRY_DRAIN_TIMERS(state_, run_func_) \
+ [state_] = BS_INIT(state_, run_func_, 1)
static struct boot_state boot_states[] = {
BS_INIT_ENTRY(BS_PRE_DEVICE, bs_pre_device),
@@ -105,10 +109,10 @@ static struct boot_state boot_states[] = {
BS_INIT_ENTRY(BS_DEV_INIT, bs_dev_init),
BS_INIT_ENTRY(BS_POST_DEVICE, bs_post_device),
BS_INIT_ENTRY(BS_OS_RESUME_CHECK, bs_os_resume_check),
- BS_INIT_ENTRY(BS_OS_RESUME, bs_os_resume),
- BS_INIT_ENTRY(BS_WRITE_TABLES, bs_write_tables),
- BS_INIT_ENTRY(BS_PAYLOAD_LOAD, bs_payload_load),
- BS_INIT_ENTRY(BS_PAYLOAD_BOOT, bs_payload_boot),
+ BS_INIT_ENTRY_DRAIN_TIMERS(BS_OS_RESUME, bs_os_resume),
+ BS_INIT_ENTRY_DRAIN_TIMERS(BS_WRITE_TABLES, bs_write_tables),
+ BS_INIT_ENTRY_DRAIN_TIMERS(BS_PAYLOAD_LOAD, bs_payload_load),
+ BS_INIT_ENTRY_DRAIN_TIMERS(BS_PAYLOAD_BOOT, bs_payload_boot),
};
static boot_state_t bs_pre_device(void *arg)
@@ -278,6 +282,20 @@ static inline void bs_sample_time(struct boot_state *state) {}
static inline void bs_report_time(struct boot_state *state) {}
#endif
+#if CONFIG_TIMER_QUEUE
+static void bs_run_timers(int drain)
+{
+ /* Drain all timer callbacks until none are left, if directed.
+ * Otherwise run the timers only once. */
+ do {
+ if (!timers_run())
+ break;
+ } while (drain);
+}
+#else
+static void bs_run_timers(int drain) {}
+#endif
+
static void bs_call_callbacks(struct boot_state *state,
boot_state_sequence_t seq)
{
@@ -313,6 +331,8 @@ static void bs_walk_state_machine(boot_state_t current_state_id)
printk(BS_DEBUG_LVL, "BS: Entering %s state.\n", state->name);
+ bs_run_timers(state->timers_drain);
+
bs_sample_time(state);
bs_call_callbacks(state, BS_ON_ENTRY);