qcacld-3.0: Allow suspend in deep sleep or Hibernate

Deep Sleep or Hibernate are system level mode power
modes in which wlan firmware is shutdown gracefully
and linux kernel is suspended. Currently, suspend
is not allowed if firmware is down, with this change
suspend is allowed if firmware is down due to Deep
Sleep or Hibernate low power state.

A new pld api is introduced to know the low power
state from platform driver, this api is enabled based
on CONFIG_ENABLE_LOW_POWER_MODE flag. Currently, this
feature is enabled only for wearable targets.

Change-Id: Iddaa4da8ee4880a4223420f59cbe9c365c30344a
CRs-Fixed: 3090481
This commit is contained in:
Surabhi Vishnoi
2021-11-29 15:13:15 +05:30
committed by Madan Koyyalamudi
parent e02a370ef5
commit 0320907b1e
5 changed files with 69 additions and 2 deletions

View File

@@ -1053,3 +1053,6 @@ CONFIG_WLAN_HANG_EVENT := y
#Enable VDEV Response wakelock feature #Enable VDEV Response wakelock feature
CONFIG_FEATURE_VDEV_RSP_WAKELOCK := y CONFIG_FEATURE_VDEV_RSP_WAKELOCK := y
#Enable Low Power Modes: Deep Sleep/Hibernate
CONFIG_ENABLE_LOW_POWER_MODE := y

View File

@@ -2503,8 +2503,12 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
} }
rc = wlan_hdd_validate_context(hdd_ctx); rc = wlan_hdd_validate_context(hdd_ctx);
if (0 != rc) if (0 != rc) {
return rc; if (pld_is_low_power_mode(hdd_ctx->parent_dev))
hdd_debug("low power mode (Deep Sleep/Hibernate)");
else
return rc;
}
if (ucfg_pmo_get_suspend_mode(hdd_ctx->psoc) == PMO_SUSPEND_NONE) { if (ucfg_pmo_get_suspend_mode(hdd_ctx->psoc) == PMO_SUSPEND_NONE) {
hdd_info_rl("Suspend is not supported"); hdd_info_rl("Suspend is not supported");

View File

@@ -893,6 +893,15 @@ int pld_qmi_send(struct device *dev, int type, void *cmd,
int (*cb)(void *ctx, void *event, int event_len)); int (*cb)(void *ctx, void *event, int event_len));
bool pld_is_fw_dump_skipped(struct device *dev); bool pld_is_fw_dump_skipped(struct device *dev);
#ifdef CONFIG_ENABLE_LOW_POWER_MODE
int pld_is_low_power_mode(struct device *dev);
#else
static inline int pld_is_low_power_mode(struct device *dev)
{
return 0;
}
#endif
/** /**
* pld_is_pdr() - Check WLAN PD is Restarted * pld_is_pdr() - Check WLAN PD is Restarted
* *

View File

@@ -2818,6 +2818,38 @@ int pld_is_fw_down(struct device *dev)
return ret; return ret;
} }
#ifdef CONFIG_ENABLE_LOW_POWER_MODE
/**
* pld_is_low_power_mode() - Check WLAN fw is in low power
* @dev: device
*
* This API will be called to check if WLAN FW is in low power or not.
* Low power means either Deep Sleep or Hibernate state.
*
* Return: 0 FW is not in low power mode
* Otherwise FW is low power mode
* Always return 0 for unsupported bus type
*/
int pld_is_low_power_mode(struct device *dev)
{
int ret = 0;
enum pld_bus_type type = pld_get_bus_type(dev);
switch (type) {
case PLD_BUS_TYPE_SNOC:
ret = pld_snoc_is_low_power_mode(dev);
break;
case PLD_BUS_TYPE_PCIE_FW_SIM:
case PLD_BUS_TYPE_IPCI_FW_SIM:
case PLD_BUS_TYPE_SNOC_FW_SIM:
case PLD_BUS_TYPE_IPCI:
default:
break;
}
return ret;
}
#endif
/** /**
* pld_force_assert_target() - Send a force assert request to FW. * pld_force_assert_target() - Send a force assert request to FW.
* @dev: device pointer * @dev: device pointer

View File

@@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -149,6 +150,12 @@ static inline int pld_snoc_is_fw_down(struct device *dev)
{ {
return 0; return 0;
} }
static inline int pld_snoc_is_low_power_mode(struct device *dev)
{
return 0;
}
static inline int pld_snoc_set_fw_log_mode(struct device *dev, u8 fw_log_mode) static inline int pld_snoc_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
{ {
return 0; return 0;
@@ -329,6 +336,18 @@ static inline int pld_snoc_is_fw_down(struct device *dev)
return icnss_is_fw_down(); return icnss_is_fw_down();
} }
#ifdef CONFIG_ENABLE_LOW_POWER_MODE
static inline int pld_snoc_is_low_power_mode(struct device *dev)
{
return icnss_is_low_power();
}
#else
static inline int pld_snoc_is_low_power_mode(struct device *dev)
{
return 0;
}
#endif
static inline int pld_snoc_is_qmi_disable(struct device *dev) static inline int pld_snoc_is_qmi_disable(struct device *dev)
{ {
if (!dev) if (!dev)