summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2012-03-31 08:28:38 -0700
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2012-04-23 14:19:47 -0700
commit218733cf7d01fb6225e37a16818870d20c1d8771 (patch)
treef5b2afb03ced78868a9cad0599a1fb6b0aa4f8bd /drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
parentd23f78e61f6b37159df6bfce7023500d731f61f3 (diff)
downloadop-kernel-dev-218733cf7d01fb6225e37a16818870d20c1d8771.zip
op-kernel-dev-218733cf7d01fb6225e37a16818870d20c1d8771.tar.gz
iwlwifi: provide proper API to disable all interrupts
Since the op_mode may go away, the transport needs to be able to be told not to update the op_mode at all (even for RF kill). Provide this API and use it in the proper places. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-trans-pcie.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index 8e1cf97..2a9fb98 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -1210,6 +1210,8 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
iwl_disable_interrupts(trans);
spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
+ iwl_enable_rfkill_int(trans);
+
/* wait to make sure we flush pending tasklet*/
synchronize_irq(trans_pcie->irq);
tasklet_kill(&trans_pcie->irq_tasklet);
@@ -1436,24 +1438,37 @@ error:
return err;
}
-static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans)
+static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans,
+ bool op_mode_leaving)
{
bool hw_rfkill;
+ unsigned long flags;
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
iwl_apm_stop(trans);
- iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
+ spin_lock_irqsave(&trans_pcie->irq_lock, flags);
+ iwl_disable_interrupts(trans);
+ spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
- /* Even if we stop the HW, we still want the RF kill interrupt */
- iwl_enable_rfkill_int(trans);
+ iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
- /*
- * Check again since the RF kill state may have changed while all the
- * interrupts were disabled, in this case we couldn't receive the
- * RF kill interrupt and update the state in the op_mode.
- */
- hw_rfkill = iwl_is_rfkill_set(trans);
- iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
+ if (!op_mode_leaving) {
+ /*
+ * Even if we stop the HW, we still want the RF kill
+ * interrupt
+ */
+ iwl_enable_rfkill_int(trans);
+
+ /*
+ * Check again since the RF kill state may have changed while
+ * all the interrupts were disabled, in this case we couldn't
+ * receive the RF kill interrupt and update the state in the
+ * op_mode.
+ */
+ hw_rfkill = iwl_is_rfkill_set(trans);
+ iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
+ }
}
static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
OpenPOWER on IntegriCloud