diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h index e57ff92a68ae2062721e3ad9bbec32997a263e79..3da468d2cc92f50697649adc7cc12d63c473ccb3 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h @@ -75,6 +75,20 @@ static inline void iwl_fw_cancel_timestamp(struct iwl_fw_runtime *fwrt) cancel_delayed_work_sync(&fwrt->timestamp.wk); } +static inline void iwl_fw_suspend_timestamp(struct iwl_fw_runtime *fwrt) +{ + cancel_delayed_work_sync(&fwrt->timestamp.wk); +} + +static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) +{ + if (!fwrt->timestamp.delay) + return; + + schedule_delayed_work(&fwrt->timestamp.wk, + round_jiffies_relative(fwrt->timestamp.delay)); +} + #else static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, struct dentry *dbgfs_dir) @@ -84,4 +98,8 @@ static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, static inline void iwl_fw_cancel_timestamp(struct iwl_fw_runtime *fwrt) {} +static inline void iwl_fw_suspend_timestamp(struct iwl_fw_runtime *fwrt) {} + +static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {} + #endif /* CONFIG_IWLWIFI_DEBUGFS */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/init.c b/drivers/net/wireless/intel/iwlwifi/fw/init.c index 45f21acbd842786dfd4bd0a18668a97d37bb1b11..2efac307909e1c6cfae6b7d80ac28eaa555c1100 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/init.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/init.c @@ -76,3 +76,15 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, iwl_fwrt_dbgfs_register(fwrt, dbgfs_dir); } IWL_EXPORT_SYMBOL(iwl_fw_runtime_init); + +void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt) +{ + iwl_fw_suspend_timestamp(fwrt); +} +IWL_EXPORT_SYMBOL(iwl_fw_runtime_suspend); + +void iwl_fw_runtime_resume(struct iwl_fw_runtime *fwrt) +{ + iwl_fw_resume_timestamp(fwrt); +} +IWL_EXPORT_SYMBOL(iwl_fw_runtime_resume); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index e25c049f980f27e33bb90e2234b5015f5f52b298..f3197f7c13b6df02cd1a59f711b2d65fc12aa66a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -150,6 +150,10 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, void iwl_fw_runtime_exit(struct iwl_fw_runtime *fwrt); +void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt); + +void iwl_fw_runtime_resume(struct iwl_fw_runtime *fwrt); + static inline void iwl_fw_set_current_image(struct iwl_fw_runtime *fwrt, enum iwl_ucode_type cur_fw_img) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 0e6cf39285f405d8c42e65ea2d0ef7d4e86179f0..2efe9b099556d862c946f2aeaff9746cfc3dded5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1098,6 +1098,8 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) /* make sure the d0i3 exit work is not pending */ flush_work(&mvm->d0i3_exit_work); + iwl_fw_runtime_suspend(&mvm->fwrt); + ret = iwl_trans_suspend(trans); if (ret) return ret; @@ -2012,6 +2014,8 @@ int iwl_mvm_resume(struct ieee80211_hw *hw) mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; + iwl_fw_runtime_resume(&mvm->fwrt); + return ret; } @@ -2038,6 +2042,8 @@ static int iwl_mvm_d3_test_open(struct inode *inode, struct file *file) mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3; + iwl_fw_runtime_suspend(&mvm->fwrt); + /* start pseudo D3 */ rtnl_lock(); err = __iwl_mvm_suspend(mvm->hw, mvm->hw->wiphy->wowlan_config, true); @@ -2098,6 +2104,8 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file) __iwl_mvm_resume(mvm, true); rtnl_unlock(); + iwl_fw_runtime_resume(&mvm->fwrt); + mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; iwl_abort_notification_waits(&mvm->notif_wait);