diff --git a/core/bmi/src/ol_fw.c b/core/bmi/src/ol_fw.c index 8dbc58beba29..198b92e1e93a 100644 --- a/core/bmi/src/ol_fw.c +++ b/core/bmi/src/ol_fw.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -726,6 +726,7 @@ void ol_target_failure(void *instance, QDF_STATUS status) struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx); qdf_device_t qdf_dev = ol_ctx->qdf_dev; int ret; + bool skip_recovering_check = false; enum hif_target_status target_status = hif_get_target_status(scn); if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SNOC) { @@ -733,6 +734,10 @@ void ol_target_failure(void *instance, QDF_STATUS status) return; } + /* If Host driver trigger target failure, skip recovering check */ + if (cds_is_target_asserting()) + skip_recovering_check = true; + qdf_event_set(&wma->recovery_event); if (TARGET_STATUS_RESET == target_status) { @@ -748,11 +753,16 @@ void ol_target_failure(void *instance, QDF_STATUS status) return; } - if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) { + if (!skip_recovering_check && cds_is_driver_recovering()) { BMI_ERR("%s: Recovery in progress, ignore!\n", __func__); return; } + if (cds_is_driver_in_bad_state()) { + BMI_ERR("%s: Driver in bad state, ignore!\n", __func__); + return; + } + if (cds_is_load_or_unload_in_progress()) { BMI_ERR("%s: Loading/Unloading is in progress, ignore!", __func__); diff --git a/core/cds/inc/cds_api.h b/core/cds/inc/cds_api.h index af417eca7d04..6c1099f1a0e8 100644 --- a/core/cds/inc/cds_api.h +++ b/core/cds/inc/cds_api.h @@ -61,6 +61,7 @@ * CDS_DRIVER_STATE_RECOVERING: Recovery in progress. * CDS_DRIVER_STATE_BAD: Driver in bad state. * CDS_DRIVER_STATE_MODULE_STOPPING: Module stop in progress. + * CDS_DRIVER_STATE_ASSERTING_TARGET: Driver assert target in progress. */ enum cds_driver_state { CDS_DRIVER_STATE_UNINITIALIZED = 0, @@ -71,6 +72,7 @@ enum cds_driver_state { CDS_DRIVER_STATE_BAD = BIT(4), CDS_DRIVER_STATE_FW_READY = BIT(5), CDS_DRIVER_STATE_MODULE_STOPPING = BIT(6), + CDS_DRIVER_STATE_ASSERTING_TARGET = BIT(7), }; /** @@ -272,6 +274,33 @@ static inline bool cds_is_driver_loaded(void) return __CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_LOADED); } +/** + * cds_set_assert_target_in_progress() - Setting assert target in progress + * + * @value: value to set + * + * Return: none + */ +static inline void cds_set_assert_target_in_progress(bool value) +{ + if (value) + cds_set_driver_state(CDS_DRIVER_STATE_ASSERTING_TARGET); + else + cds_clear_driver_state(CDS_DRIVER_STATE_ASSERTING_TARGET); +} + +/** + * cds_is_target_asserting() - Is driver asserting target + * + * Return: true if driver is asserting target + */ +static inline bool cds_is_target_asserting(void) +{ + enum cds_driver_state state = cds_get_driver_state(); + + return __CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_ASSERTING_TARGET); +} + /** * cds_init() - Initialize CDS * diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index 6c2155f96892..814c8a425759 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -1904,7 +1904,9 @@ static void cds_trigger_recovery_handler(const char *func, const uint32_t line) } cds_set_recovery_in_progress(true); + cds_set_assert_target_in_progress(true); cds_force_assert_target(qdf); + cds_set_assert_target_in_progress(false); status = qdf_runtime_pm_allow_suspend(&rtl); if (QDF_IS_STATUS_ERROR(status))