qcacld-3.0: Shutdown WLAN in system suspend prepare
This re-introduces the orignal patch which shutdowns WLAN in system suspend prepare. Orignal patch Id1f5172a7fc1792c83c8c1c20127de815f7e4980 is reverted by Ic82db9dc0ca9d6686df99926335af27abc61cdb5 for deadlock issue. However, deadlock between cnss_pm_notify and unregister_pm_notifier is not caused by Id1f5172a7fc1792c83c8c1c20127de815f7e4980. So restore it and add flag to enable/disable feature shutdown wlan in system suspend. Deadlock issue is caused by "up_write(&cnss_pm_sem) is invoked before down_write(&cnss_pm_sem) in function cnss_pm_notify". The issue can be fixed by changes I533c373b85f554fbcceb562d9f56c6b88e5155bb and I7768fdbeb1fa8cd6ef3b260eb0aafb231aeed324. Change-Id: I25e4398a8d3b1a52cf7bc554af74d123ec797c6e CRs-Fixed: 3287742
This commit is contained in:

committed by
Madan Koyyalamudi

parent
8fa3cbbba8
commit
85f34a3bb9
2
Kbuild
2
Kbuild
@@ -4573,6 +4573,8 @@ endif
|
|||||||
|
|
||||||
cppflags-$(CONFIG_WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET) += -DWLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET
|
cppflags-$(CONFIG_WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET) += -DWLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET
|
||||||
|
|
||||||
|
ccflags-$(CONFIG_SHUTDOWN_WLAN_IN_SYSTEM_SUSPEND) += -DSHUTDOWN_WLAN_IN_SYSTEM_SUSPEND
|
||||||
|
|
||||||
ifeq ($(CONFIG_WLAN_FEATURE_MCC_QUOTA), y)
|
ifeq ($(CONFIG_WLAN_FEATURE_MCC_QUOTA), y)
|
||||||
cppflags-y += -DWLAN_FEATURE_MCC_QUOTA
|
cppflags-y += -DWLAN_FEATURE_MCC_QUOTA
|
||||||
ifdef CONFIG_WLAN_MCC_MIN_CHANNEL_QUOTA
|
ifdef CONFIG_WLAN_MCC_MIN_CHANNEL_QUOTA
|
||||||
|
@@ -340,13 +340,14 @@
|
|||||||
* <ini>
|
* <ini>
|
||||||
* gSuspendMode - Suspend mode configuration
|
* gSuspendMode - Suspend mode configuration
|
||||||
* @Min: 0
|
* @Min: 0
|
||||||
* @Max: 2
|
* @Max: 3
|
||||||
* @Default: 2
|
* @Default: 2
|
||||||
*
|
*
|
||||||
* This ini is used to set suspend mode. Configurations are as follows:
|
* This ini is used to set suspend mode. Configurations are as follows:
|
||||||
* 0 - Does not support suspend.
|
* 0 - Does not support suspend.
|
||||||
* 1 - Legency suspend mode, PDEV suspend.
|
* 1 - Legency suspend mode, PDEV suspend.
|
||||||
* 2 - WOW suspend mode.
|
* 2 - WOW suspend mode.
|
||||||
|
* 3 - Shutdown wlan while suspend.
|
||||||
*
|
*
|
||||||
* Related: None
|
* Related: None
|
||||||
*
|
*
|
||||||
@@ -357,7 +358,7 @@
|
|||||||
* </ini>
|
* </ini>
|
||||||
*/
|
*/
|
||||||
#define CFG_PMO_SUSPEND_MODE CFG_INI_UINT("gSuspendMode", \
|
#define CFG_PMO_SUSPEND_MODE CFG_INI_UINT("gSuspendMode", \
|
||||||
0, 2, 2, \
|
0, 3, 2, \
|
||||||
CFG_VALUE_OR_DEFAULT, \
|
CFG_VALUE_OR_DEFAULT, \
|
||||||
"Suspend mode")
|
"Suspend mode")
|
||||||
|
|
||||||
|
@@ -175,7 +175,7 @@ enum powersave_mode {
|
|||||||
* @PMO_SUSPEND_NONE: Does not support suspend
|
* @PMO_SUSPEND_NONE: Does not support suspend
|
||||||
* @PMO_SUSPEND_LEGENCY: Legency PDEV suspend mode
|
* @PMO_SUSPEND_LEGENCY: Legency PDEV suspend mode
|
||||||
* @PMO_SUSPEND_WOW: WoW suspend mode
|
* @PMO_SUSPEND_WOW: WoW suspend mode
|
||||||
* @PMO_SUSPEND_SHUTDOWN: shutdown while suspend mode
|
* @PMO_SUSPEND_SHUTDOWN: Shutdown suspend mode. Shutdown while suspend
|
||||||
*/
|
*/
|
||||||
enum pmo_suspend_mode {
|
enum pmo_suspend_mode {
|
||||||
PMO_SUSPEND_NONE = 0,
|
PMO_SUSPEND_NONE = 0,
|
||||||
|
@@ -1710,6 +1710,7 @@ enum wlan_state_ctrl_str_id {
|
|||||||
* @dump_in_progress: Stores value of dump in progress
|
* @dump_in_progress: Stores value of dump in progress
|
||||||
* @hdd_dual_sta_policy: Concurrent STA policy configuration
|
* @hdd_dual_sta_policy: Concurrent STA policy configuration
|
||||||
* @is_wlan_disabled: if wlan is disabled by userspace
|
* @is_wlan_disabled: if wlan is disabled by userspace
|
||||||
|
* @pm_notifier: PM notifier of hdd modules
|
||||||
*/
|
*/
|
||||||
struct hdd_context {
|
struct hdd_context {
|
||||||
struct wlan_objmgr_psoc *psoc;
|
struct wlan_objmgr_psoc *psoc;
|
||||||
@@ -1889,6 +1890,7 @@ struct hdd_context {
|
|||||||
/* Present state of driver cds modules */
|
/* Present state of driver cds modules */
|
||||||
enum driver_modules_status driver_status;
|
enum driver_modules_status driver_status;
|
||||||
struct qdf_delayed_work psoc_idle_timeout_work;
|
struct qdf_delayed_work psoc_idle_timeout_work;
|
||||||
|
struct notifier_block pm_notifier;
|
||||||
struct acs_dfs_policy acs_policy;
|
struct acs_dfs_policy acs_policy;
|
||||||
uint16_t wmi_max_len;
|
uint16_t wmi_max_len;
|
||||||
struct suspend_resume_stats suspend_resume_stats;
|
struct suspend_resume_stats suspend_resume_stats;
|
||||||
|
@@ -83,6 +83,7 @@
|
|||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#include <linux/ethtool.h>
|
#include <linux/ethtool.h>
|
||||||
|
#include <linux/suspend.h>
|
||||||
|
|
||||||
#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
|
#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
|
||||||
#include "qdf_periodic_work.h"
|
#include "qdf_periodic_work.h"
|
||||||
@@ -9395,6 +9396,79 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SHUTDOWN_WLAN_IN_SYSTEM_SUSPEND
|
||||||
|
static QDF_STATUS
|
||||||
|
hdd_shutdown_wlan_in_suspend_prepare(struct hdd_context *hdd_ctx)
|
||||||
|
{
|
||||||
|
#define SHUTDOWN_IN_SUSPEND_RETRY 10
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (ucfg_pmo_get_suspend_mode(hdd_ctx->psoc) != PMO_SUSPEND_SHUTDOWN) {
|
||||||
|
hdd_debug("shutdown in suspend not supported");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (hdd_is_any_interface_open(hdd_ctx) &&
|
||||||
|
count < SHUTDOWN_IN_SUSPEND_RETRY) {
|
||||||
|
count++;
|
||||||
|
hdd_debug_rl("sleep 50ms to wait adapters stopped, #%d", count);
|
||||||
|
msleep(50);
|
||||||
|
}
|
||||||
|
if (count >= SHUTDOWN_IN_SUSPEND_RETRY) {
|
||||||
|
hdd_err("some adapters not stopped");
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdd_debug("call pld idle shutdown directly");
|
||||||
|
return pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hdd_pm_notify(struct notifier_block *b,
|
||||||
|
unsigned long event, void *p)
|
||||||
|
{
|
||||||
|
struct hdd_context *hdd_ctx = container_of(b, struct hdd_context,
|
||||||
|
pm_notifier);
|
||||||
|
|
||||||
|
if (wlan_hdd_validate_context(hdd_ctx) != 0)
|
||||||
|
return NOTIFY_STOP;
|
||||||
|
|
||||||
|
hdd_debug("got PM event: %lu", event);
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case PM_SUSPEND_PREPARE:
|
||||||
|
case PM_HIBERNATION_PREPARE:
|
||||||
|
if (0 != hdd_shutdown_wlan_in_suspend_prepare(hdd_ctx))
|
||||||
|
return NOTIFY_STOP;
|
||||||
|
break;
|
||||||
|
case PM_POST_SUSPEND:
|
||||||
|
case PM_POST_HIBERNATION:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NOTIFY_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hdd_pm_notifier_init(struct hdd_context *hdd_ctx)
|
||||||
|
{
|
||||||
|
hdd_ctx->pm_notifier.notifier_call = hdd_pm_notify;
|
||||||
|
register_pm_notifier(&hdd_ctx->pm_notifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hdd_pm_notifier_deinit(struct hdd_context *hdd_ctx)
|
||||||
|
{
|
||||||
|
unregister_pm_notifier(&hdd_ctx->pm_notifier);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline void hdd_pm_notifier_init(struct hdd_context *hdd_ctx)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hdd_pm_notifier_deinit(struct hdd_context *hdd_ctx)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hdd_context_deinit() - Deinitialize HDD context
|
* hdd_context_deinit() - Deinitialize HDD context
|
||||||
* @hdd_ctx: HDD context.
|
* @hdd_ctx: HDD context.
|
||||||
@@ -9438,6 +9512,7 @@ void hdd_context_destroy(struct hdd_context *hdd_ctx)
|
|||||||
hdd_ctx->config = NULL;
|
hdd_ctx->config = NULL;
|
||||||
cfg_release();
|
cfg_release();
|
||||||
|
|
||||||
|
hdd_pm_notifier_deinit(hdd_ctx);
|
||||||
qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work);
|
qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work);
|
||||||
wiphy_free(hdd_ctx->wiphy);
|
wiphy_free(hdd_ctx->wiphy);
|
||||||
}
|
}
|
||||||
@@ -12631,6 +12706,8 @@ struct hdd_context *hdd_context_create(struct device *dev)
|
|||||||
goto wiphy_dealloc;
|
goto wiphy_dealloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hdd_pm_notifier_init(hdd_ctx);
|
||||||
|
|
||||||
hdd_ctx->parent_dev = dev;
|
hdd_ctx->parent_dev = dev;
|
||||||
hdd_ctx->last_scan_reject_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
|
hdd_ctx->last_scan_reject_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user