diff --git a/dsp/q6core.c b/dsp/q6core.c index 0bb767896f8a..c6b8f3a712f9 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -33,6 +33,8 @@ #define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define ADSP_MODULES_READY_AVS_STATE 5 + #define APR_ENOTREADY 10 #define MEMPOOL_ID_MASK 0xFF #define MDF_MAP_TOKEN 0xF000 @@ -973,12 +975,39 @@ int32_t q6core_avcs_load_unload_modules(struct avcs_load_unload_modules_payload size_t packet_size = 0, payload_size = 0; struct avcs_cmd_dynamic_modules *mod = NULL; int num_modules; + unsigned long timeout; if (payload == NULL) { pr_err("%s: payload is null\n", __func__); return -EINVAL; } + if ((q6core_lcl.avs_state != ADSP_MODULES_READY_AVS_STATE) + && (preload_type == AVCS_LOAD_MODULES)) { + timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + + do { + q6core_is_adsp_ready(); + if (q6core_lcl.param == ADSP_MODULES_READY_AVS_STATE) { + pr_debug("%s: ADSP state up with all modules loaded\n", + __func__); + q6core_lcl.avs_state = ADSP_MODULES_READY_AVS_STATE; + break; + } + + /* + * ADSP will be coming up after boot up and AVS might + * not be fully up with all modules when the control reaches here. + * So, wait for 50msec before checking ADSP state again. + */ + msleep(50); + } while (time_after(timeout, jiffies)); + + if (q6core_lcl.param != ADSP_MODULES_READY_AVS_STATE) + pr_err("%s: all modules might be not loaded yet on ADSP\n", + __func__); + } mutex_lock(&(q6core_lcl.cmd_lock)); num_modules = payload->num_modules; ocm_core_open(); @@ -1989,7 +2018,7 @@ static int q6core_is_avs_up(int32_t *avs_state) msleep(50); } while (time_after(timeout, jiffies)); - *avs_state = adsp_ready; + *avs_state = q6core_lcl.param; pr_debug("%s: ADSP Audio is %s\n", __func__, adsp_ready ? "ready" : "not ready");