|
@@ -402,6 +402,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
|
|
mvm->sf_state = SF_UNINIT;
|
|
|
|
|
|
mutex_init(&mvm->mutex);
|
|
|
+ mutex_init(&mvm->d0i3_suspend_mutex);
|
|
|
spin_lock_init(&mvm->async_handlers_lock);
|
|
|
INIT_LIST_HEAD(&mvm->time_event_list);
|
|
|
INIT_LIST_HEAD(&mvm->async_handlers_list);
|
|
@@ -1174,18 +1175,27 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
|
|
|
iwl_free_resp(&get_status_cmd);
|
|
|
out:
|
|
|
iwl_mvm_d0i3_enable_tx(mvm, qos_seq);
|
|
|
+ iwl_mvm_unref(mvm, IWL_MVM_REF_EXIT_WORK);
|
|
|
mutex_unlock(&mvm->mutex);
|
|
|
}
|
|
|
|
|
|
-static int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode)
|
|
|
+int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm)
|
|
|
{
|
|
|
- struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
|
|
|
u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE |
|
|
|
CMD_WAKE_UP_TRANS;
|
|
|
int ret;
|
|
|
|
|
|
IWL_DEBUG_RPM(mvm, "MVM exiting D0i3\n");
|
|
|
|
|
|
+ mutex_lock(&mvm->d0i3_suspend_mutex);
|
|
|
+ if (test_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags)) {
|
|
|
+ IWL_DEBUG_RPM(mvm, "Deferring d0i3 exit until resume\n");
|
|
|
+ __set_bit(D0I3_PENDING_WAKEUP, &mvm->d0i3_suspend_flags);
|
|
|
+ mutex_unlock(&mvm->d0i3_suspend_mutex);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ mutex_unlock(&mvm->d0i3_suspend_mutex);
|
|
|
+
|
|
|
ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, flags, 0, NULL);
|
|
|
if (ret)
|
|
|
goto out;
|
|
@@ -1199,6 +1209,14 @@ out:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode)
|
|
|
+{
|
|
|
+ struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
|
|
|
+
|
|
|
+ iwl_mvm_ref(mvm, IWL_MVM_REF_EXIT_WORK);
|
|
|
+ return _iwl_mvm_exit_d0i3(mvm);
|
|
|
+}
|
|
|
+
|
|
|
static void iwl_mvm_napi_add(struct iwl_op_mode *op_mode,
|
|
|
struct napi_struct *napi,
|
|
|
struct net_device *napi_dev,
|