diff options
-rw-r--r-- | src/lib/hardwaremain.c | 48 |
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); |