From 4c66322b9994f8a0f0626480bb07d91ec35bafdc Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Tue, 23 Oct 2018 14:19:36 -0700 Subject: [PATCH] qcacld-3.0: Abstract idle shutdown timer start/stop The code to start and stop the idle shutdown timer in HDD is currently copy-pasted in multiple locations. Abstract this logic behind two new APIs, and call these APIs where appropriate. Change-Id: I73b05e603454a4817cb9c1606c1207d7fe68e5ab CRs-Fixed: 2337755 --- core/hdd/inc/wlan_hdd_main.h | 30 ++++++++---- core/hdd/src/wlan_hdd_driver_ops.c | 2 +- core/hdd/src/wlan_hdd_main.c | 73 ++++++++++++++---------------- core/hdd/src/wlan_hdd_p2p.c | 16 ++----- 4 files changed, 60 insertions(+), 61 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index b4a0366f5d..371148a964 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1711,6 +1711,7 @@ struct hdd_cache_channels { * @psoc: object manager psoc context * @pdev: object manager pdev context * @g_event_flags: a bitmap of hdd_driver_flags + * @psoc_idle_timeout_work: delayed work for psoc idle shutdown */ struct hdd_context { struct wlan_objmgr_psoc *psoc; @@ -1904,8 +1905,7 @@ struct hdd_context { #endif /* Present state of driver cds modules */ enum driver_modules_status driver_status; - /* interface idle work */ - qdf_delayed_work_t iface_idle_work; + qdf_delayed_work_t psoc_idle_timeout_work; /* Interface change lock */ struct mutex iface_change_lock; bool rps; @@ -2784,6 +2784,23 @@ int hdd_configure_cds(struct hdd_context *hdd_ctx); int hdd_set_fw_params(struct hdd_adapter *adapter); int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit); int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode); + +/** + * hdd_psoc_idle_timer_start() - start the idle psoc detection timer + * @hdd_ctx: the hdd context for which the timer should be started + * + * Return: None + */ +void hdd_psoc_idle_timer_start(struct hdd_context *hdd_ctx); + +/** + * hdd_psoc_idle_timer_stop() - stop the idle psoc detection timer + * @hdd_ctx: the hdd context for which the timer should be stopped + * + * Return: None + */ +void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx); + int hdd_start_adapter(struct hdd_adapter *adapter); void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num); /** @@ -2988,15 +3005,12 @@ void wlan_hdd_deinit_chan_info(struct hdd_context *hdd_ctx); void wlan_hdd_start_sap(struct hdd_adapter *ap_adapter, bool reinit); /** - * hdd_check_for_opened_interfaces()- Check for interface up + * hdd_is_any_interface_open() - Check for interface up * @hdd_ctx: HDD context * - * check if there are any wlan interfaces before starting the timer - * to close the modules - * - * Return: 0 if interface was opened else false + * Return: true if any interface is open */ -bool hdd_check_for_opened_interfaces(struct hdd_context *hdd_ctx); +bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx); #ifdef WIFI_POS_CONVERGED /** diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index f027904714..442bb0d198 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/core/hdd/src/wlan_hdd_driver_ops.c @@ -1575,7 +1575,7 @@ static void wlan_hdd_flush_iface_idle_work(void) return; } - qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work); + hdd_psoc_idle_timer_stop(hdd_ctx); } /** diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 70cd15e90d..38b870c66d 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -2647,7 +2647,7 @@ int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit) return -EINVAL; } - qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work); + hdd_psoc_idle_timer_stop(hdd_ctx); mutex_lock(&hdd_ctx->iface_change_lock); if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) { @@ -3119,20 +3119,11 @@ static int __hdd_stop(struct net_device *dev) if (!hdd_is_cli_iface_up(hdd_ctx)) sme_scan_flush_result(mac_handle); - /* - * Find if any iface is up. If any iface is up then can't put device to - * sleep/power save mode - */ - if (hdd_check_for_opened_interfaces(hdd_ctx)) { - hdd_debug("Closing all modules from the hdd_stop"); - qdf_sched_delayed_work(&hdd_ctx->iface_idle_work, - hdd_ctx->config->iface_change_wait_time); - hdd_prevent_suspend_timeout( - hdd_ctx->config->iface_change_wait_time, - WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER); - } + if (!hdd_is_any_interface_open(hdd_ctx)) + hdd_psoc_idle_timer_start(hdd_ctx); hdd_exit(); + return 0; } @@ -5429,26 +5420,22 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) return QDF_STATUS_SUCCESS; } -bool hdd_check_for_opened_interfaces(struct hdd_context *hdd_ctx) +bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx) { struct hdd_adapter *adapter; - bool close_modules = true; - if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { + if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { hdd_info("FTM mode, don't close the module"); - return false; + return true; } hdd_for_each_adapter(hdd_ctx, adapter) { if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) || - test_bit(SME_SESSION_OPENED, &adapter->event_flags)) { - hdd_debug("Still other ifaces are up cannot close modules"); - close_modules = false; - break; - } + test_bit(SME_SESSION_OPENED, &adapter->event_flags)) + return true; } - return close_modules; + return false; } bool hdd_is_interface_up(struct hdd_adapter *adapter) @@ -6874,7 +6861,7 @@ static void hdd_wlan_exit(struct hdd_context *hdd_ctx) hdd_enter(); - qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work); + hdd_psoc_idle_timer_stop(hdd_ctx); hdd_unregister_notifiers(hdd_ctx); @@ -8852,6 +8839,23 @@ list_destroy: return ret; } +void hdd_psoc_idle_timer_start(struct hdd_context *hdd_ctx) +{ + uint32_t timeout_ms = hdd_ctx->config->iface_change_wait_time; + enum wake_lock_reason reason = + WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER; + + hdd_debug("Starting psoc idle timer"); + qdf_sched_delayed_work(&hdd_ctx->psoc_idle_timeout_work, timeout_ms); + hdd_prevent_suspend_timeout(timeout_ms, reason); +} + +void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx) +{ + qdf_cancel_delayed_work(&hdd_ctx->psoc_idle_timeout_work); + hdd_debug("Stopped psoc idle timer"); +} + /** * hdd_iface_change_callback() - Function invoked when stop modules expires * @priv: pointer to hdd context @@ -8999,9 +9003,9 @@ static struct hdd_context *hdd_context_create(struct device *dev) goto err_out; } - qdf_create_delayed_work(&hdd_ctx->iface_idle_work, + qdf_create_delayed_work(&hdd_ctx->psoc_idle_timeout_work, hdd_iface_change_callback, - (void *)hdd_ctx); + hdd_ctx); mutex_init(&hdd_ctx->iface_change_lock); @@ -10915,11 +10919,7 @@ int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode) if (IS_IDLE_STOP && !ftm_mode) { mutex_unlock(&hdd_ctx->iface_change_lock); - qdf_sched_delayed_work(&hdd_ctx->iface_idle_work, - hdd_ctx->config->iface_change_wait_time); - hdd_prevent_suspend_timeout( - hdd_ctx->config->iface_change_wait_time, - WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER); + hdd_psoc_idle_timer_start(hdd_ctx); hdd_ctx->stop_modules_in_progress = false; cds_set_module_stop_in_progress(false); @@ -11446,13 +11446,8 @@ int hdd_wlan_startup(struct device *dev) else hdd_set_idle_ps_config(hdd_ctx, false); - if (QDF_GLOBAL_FTM_MODE != hdd_get_conparam()) { - qdf_sched_delayed_work(&hdd_ctx->iface_idle_work, - hdd_ctx->config->iface_change_wait_time); - hdd_prevent_suspend_timeout( - hdd_ctx->config->iface_change_wait_time, - WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER); - } + if (hdd_get_conparam() != QDF_GLOBAL_FTM_MODE) + hdd_psoc_idle_timer_start(hdd_ctx); goto success; @@ -12940,7 +12935,7 @@ static void hdd_driver_unload(void) "driver unload anyway"); if (hdd_ctx) - qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work); + hdd_psoc_idle_timer_stop(hdd_ctx); wlan_hdd_unregister_driver(); pld_deinit(); diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c index da9a4e20e7..b50e41bfa2 100644 --- a/core/hdd/src/wlan_hdd_p2p.c +++ b/core/hdd/src/wlan_hdd_p2p.c @@ -724,22 +724,12 @@ struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy, hdd_send_rps_ind(adapter); hdd_exit(); + return adapter->dev->ieee80211_ptr; stop_modules: - /* - * Find if any iface is up. If there is not iface which is up - * start the timer to close the modules - */ - if (hdd_check_for_opened_interfaces(hdd_ctx)) { - hdd_debug("Closing all modules from the add_virt_iface"); - qdf_sched_delayed_work(&hdd_ctx->iface_idle_work, - hdd_ctx->config->iface_change_wait_time); - hdd_prevent_suspend_timeout( - hdd_ctx->config->iface_change_wait_time, - WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER); - } else - hdd_debug("Other interfaces are still up dont close modules!"); + if (!hdd_is_any_interface_open(hdd_ctx)) + hdd_psoc_idle_timer_start(hdd_ctx); close_adapter: hdd_close_adapter(hdd_ctx, adapter, true);