From 10d47061ef88e793c061afde6a69ca74c8b7ff92 Mon Sep 17 00:00:00 2001 From: Surabhi Vishnoi Date: Mon, 10 Jan 2022 15:51:49 +0530 Subject: [PATCH] qcacld-3.0: Allow suspend in Deep Sleep/Hibernate in wearables Deep Sleep or Hibernate are system level mode power modes wearable targets in which wlan firmware is shutdown gracefully and linux kernel and platform are suspended. Currently, wlan suspend and pm_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. Change-Id: Ide7b8957d1cfe455d57769c30f0bb3d6e564cddc CRs-Fixed: 3108081 --- core/hdd/src/wlan_hdd_driver_ops.c | 19 ++++++++++++++----- core/hdd/src/wlan_hdd_power.c | 17 +++++++++++++---- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index aba1d4b8a194..85fbcedbabb0 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/core/hdd/src/wlan_hdd_driver_ops.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -1201,9 +1202,12 @@ static int __wlan_hdd_bus_suspend(struct wow_enable_params wow_params) hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); err = wlan_hdd_validate_context(hdd_ctx); - if (err) - return err; - + if (0 != err) { + if (pld_is_low_power_mode(hdd_ctx->parent_dev)) + hdd_debug("low power mode (Deep Sleep/Hibernate)"); + else + return err; + } /* If Wifi is off, return success for system suspend */ if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { @@ -1910,8 +1914,13 @@ static int wlan_hdd_pld_suspend(struct device *dev, hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); errno = wlan_hdd_validate_context(hdd_ctx); - if (errno) - return errno; + if (0 != errno) { + if (pld_is_low_power_mode(hdd_ctx->parent_dev)) + hdd_debug("low power mode (Deep Sleep/Hibernate)"); + else + return errno; + } + /* * Flush the idle shutdown before ops start.This is done here to avoid * the deadlock as idle shutdown waits for the dsc ops diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index 4c63bfabf304..760f862045de 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -2457,8 +2458,12 @@ static int _wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, } errno = wlan_hdd_validate_context(hdd_ctx); - if (errno) - return errno; + if (0 != errno) { + if (pld_is_low_power_mode(hdd_ctx->parent_dev)) + hdd_debug("low power mode (Deep Sleep/Hibernate)"); + else + return errno; + } hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); if (!hif_ctx) @@ -2485,8 +2490,12 @@ int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, struct hdd_context *hdd_ctx = wiphy_priv(wiphy); errno = wlan_hdd_validate_context(hdd_ctx); - if (0 != errno) - return errno; + if (0 != errno) { + if (pld_is_low_power_mode(hdd_ctx->parent_dev)) + hdd_debug("low power mode (Deep Sleep/Hibernate)"); + else + return errno; + } /* * Flush the idle shutdown before ops start.This is done here to avoid