diff --git a/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c b/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c index ada0d391d960..7493d5233d68 100644 --- a/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c +++ b/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c @@ -452,112 +452,114 @@ out: } QDF_STATUS pmo_suspend_all_components(struct wlan_objmgr_psoc *psoc, - enum qdf_suspend_type suspend_type) + enum qdf_suspend_type suspend_type) { - pmo_psoc_suspend_handler handler; - uint8_t index = 0; - QDF_STATUS suspend_status = QDF_STATUS_SUCCESS; - QDF_STATUS resume_status = QDF_STATUS_SUCCESS; - void *arg; + QDF_STATUS status = QDF_STATUS_SUCCESS; + QDF_STATUS resume_status; struct wlan_pmo_ctx *pmo_ctx; + uint8_t i; + pmo_psoc_suspend_handler handler; + void *arg; PMO_ENTER(); + pmo_ctx = pmo_get_context(); if (!pmo_ctx) { - QDF_ASSERT(0); pmo_err("unable to get pmo ctx"); - suspend_status = QDF_STATUS_E_FAILURE; - goto out; + QDF_ASSERT(0); + status = QDF_STATUS_E_FAILURE; + goto exit_with_status; } - /* call all component's Suspend Handler */ - while (index < WLAN_UMAC_MAX_COMPONENTS) { + /* call each component's suspend handler */ + for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) { qdf_spin_lock_bh(&pmo_ctx->lock); - if (pmo_ctx->pmo_suspend_handler[index]) { - handler = pmo_ctx->pmo_suspend_handler[index]; - arg = pmo_ctx->pmo_suspend_handler_arg[index]; - qdf_spin_unlock_bh(&pmo_ctx->lock); - suspend_status = handler(psoc, arg); - if (suspend_status != QDF_STATUS_SUCCESS) { - pmo_err("component id: %d failed to suspend status: %d", - index, suspend_status); - QDF_ASSERT(0); - /* break, no need to suspend next components */ - break; - } - } else { - qdf_spin_unlock_bh(&pmo_ctx->lock); + handler = pmo_ctx->pmo_suspend_handler[i]; + arg = pmo_ctx->pmo_suspend_handler_arg[i]; + qdf_spin_unlock_bh(&pmo_ctx->lock); + + if (!handler) + continue; + + status = handler(psoc, arg); + if (QDF_IS_STATUS_ERROR(status)) { + pmo_err("component %d failed to suspend; status: %d", + i, status); + QDF_ASSERT(0); + goto suspend_recovery; } - index++; } - /* resume the succefully suspended components */ - if (suspend_status != QDF_STATUS_SUCCESS) { - while (index >= 0) { - /* - * index points to id which refuse suspend - * so go to previous id. - */ - index--; - qdf_spin_lock_bh(&pmo_ctx->lock); - handler = pmo_ctx->pmo_resume_handler[index]; - arg = pmo_ctx->pmo_resume_handler_arg[index]; - qdf_spin_unlock_bh(&pmo_ctx->lock); - /* TODO: if resume got failed for some component ?? */ - resume_status = handler(psoc, arg); - if (resume_status != QDF_STATUS_SUCCESS) { - pmo_err("Component id: %d failed to resume status: %d", - index, resume_status); - QDF_ASSERT(0); - } + goto exit_with_status; + +suspend_recovery: + /* resume, starting with the last successfully suspended component */ + for (i -= 1; i >= 0; i--) { + qdf_spin_lock_bh(&pmo_ctx->lock); + handler = pmo_ctx->pmo_resume_handler[i]; + arg = pmo_ctx->pmo_resume_handler_arg[i]; + qdf_spin_unlock_bh(&pmo_ctx->lock); + + if (!handler) + continue; + + resume_status = handler(psoc, arg); + if (QDF_IS_STATUS_ERROR(resume_status)) { + pmo_fatal("Non-recoverable failure occurred!"); + pmo_fatal("component %d failed to resume; status: %d", + i, resume_status); + QDF_BUG(0); } } -out: + +exit_with_status: PMO_EXIT(); - return suspend_status; + return status; } QDF_STATUS pmo_resume_all_components(struct wlan_objmgr_psoc *psoc, - enum qdf_suspend_type suspend_type) + enum qdf_suspend_type suspend_type) { - uint8_t index = 0; - QDF_STATUS component_ret = QDF_STATUS_SUCCESS; - void *arg; + QDF_STATUS status = QDF_STATUS_SUCCESS; struct wlan_pmo_ctx *pmo_ctx; + uint8_t i; pmo_psoc_suspend_handler handler; + void *arg; PMO_ENTER(); + pmo_ctx = pmo_get_context(); if (!pmo_ctx) { - QDF_ASSERT(0); pmo_err("unable to get pmo ctx"); - component_ret = QDF_STATUS_E_FAILURE; - goto out; + QDF_ASSERT(0); + status = QDF_STATUS_E_FAILURE; + goto exit_with_status; } - /* call all components Resume Handler */ - while (index < WLAN_UMAC_MAX_COMPONENTS) { + /* call each component's resume handler */ + for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) { qdf_spin_lock_bh(&pmo_ctx->lock); - if (pmo_ctx->pmo_resume_handler[index]) { - handler = pmo_ctx->pmo_resume_handler[index]; - arg = pmo_ctx->pmo_resume_handler_arg[index]; - qdf_spin_unlock_bh(&pmo_ctx->lock); - component_ret = handler(psoc, arg); - if (component_ret != QDF_STATUS_SUCCESS) { - pmo_err("Component id: %d failed to resume status: %d", - index, component_ret); - QDF_ASSERT(0); - } - } else { - qdf_spin_unlock_bh(&pmo_ctx->lock); + handler = pmo_ctx->pmo_resume_handler[i]; + arg = pmo_ctx->pmo_resume_handler_arg[i]; + qdf_spin_unlock_bh(&pmo_ctx->lock); + + if (!handler) + continue; + + status = handler(psoc, arg); + if (QDF_IS_STATUS_ERROR(status)) { + pmo_fatal("Non-recoverable failure occurred!"); + pmo_fatal("component %d failed to resume; status: %d", + i, status); + QDF_BUG(0); } - index++; -} -out: + } + +exit_with_status: PMO_EXIT(); - return component_ret; + return status; } QDF_STATUS pmo_register_pause_bitmap_notifier(struct wlan_objmgr_psoc *psoc,