From e523cd9f23309b386000b9005681004df4567f0f Mon Sep 17 00:00:00 2001 From: Alan Chen Date: Mon, 15 Jul 2019 16:45:09 -0700 Subject: [PATCH] qcacld-3.0: Add lock/unlock for idle restart to prevent suspend During idle restart, system suspend is happening, which is leading to timeout because idle restart task is frozen during system suspend. To avoid the timeout, add a wakelock for idle restart to prevent system suspend. Change-Id: Iffb6151452680df8cb4fb98e8646112e780881f8 CRs-Fixed: 2490321 --- core/hdd/inc/wlan_hdd_driver_ops.h | 20 +++++++++++++++++++- core/hdd/src/wlan_hdd_driver_ops.c | 10 ++++++++++ core/hdd/src/wlan_hdd_main.c | 18 ++++++++++++++++-- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_driver_ops.h b/core/hdd/inc/wlan_hdd_driver_ops.h index d1cc09d82a050..7ca3cf22d2238 100644 --- a/core/hdd/inc/wlan_hdd_driver_ops.h +++ b/core/hdd/inc/wlan_hdd_driver_ops.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2017, 2019 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 @@ -118,4 +118,22 @@ void hdd_hif_close(struct hdd_context *hdd_ctx, void *hif_ctx); int hdd_hif_open(struct device *dev, void *bdev, const struct hif_bus_id *bid, enum qdf_bus_type bus_type, bool reinit); +/** + * hdd_soc_idle_restart_lock() - Takes wakelock for idle restart + * + * This function takes wakelock to prevent suspend during idle restart + * + * Return: none + */ +void hdd_soc_idle_restart_lock(void); + +/** + * hdd_soc_idle_restart_unlock() - Releases wakelock for idle restart + * + * This function releases wakelock to allow suspend after idle restart + * + * Return: none + */ +void hdd_soc_idle_restart_unlock(void); + #endif /* __WLAN_HDD_DRIVER_OPS_H__ */ diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index 9b44e4d03d745..29e127861a9cb 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/core/hdd/src/wlan_hdd_driver_ops.c @@ -375,6 +375,16 @@ static int check_for_probe_defer(int ret) } #endif +void hdd_soc_idle_restart_lock(void) +{ + hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_RESTART); +} + +void hdd_soc_idle_restart_unlock(void) +{ + hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_IDLE_RESTART); +} + static void hdd_soc_load_lock(struct device *dev) { hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index bcb926eb3ad52..23a6b24bfa7c1 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -9406,7 +9406,15 @@ int hdd_psoc_idle_shutdown(struct device *dev) static int __hdd_psoc_idle_restart(struct hdd_context *hdd_ctx) { - return hdd_wlan_start_modules(hdd_ctx, false); + int ret; + + hdd_soc_idle_restart_lock(); + + ret = hdd_wlan_start_modules(hdd_ctx, false); + + hdd_soc_idle_restart_unlock(); + + return ret; } int hdd_psoc_idle_restart(struct device *dev) @@ -9433,7 +9441,9 @@ int hdd_trigger_psoc_idle_restart(struct hdd_context *hdd_ctx) return 0; } + hdd_soc_idle_restart_lock(); ret = pld_idle_restart(hdd_ctx->parent_dev, hdd_psoc_idle_restart); + hdd_soc_idle_restart_unlock(); return ret; } @@ -13693,11 +13703,15 @@ static int hdd_mode_change_psoc_idle_shutdown(struct device *dev) static int hdd_mode_change_psoc_idle_restart(struct device *dev) { struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + int ret; if (!hdd_ctx) return -EINVAL; + hdd_soc_idle_restart_lock(); + ret = hdd_wlan_start_modules(hdd_ctx, false); + hdd_soc_idle_restart_unlock(); - return hdd_wlan_start_modules(hdd_ctx, false); + return ret; } /**