diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2012-03-31 08:28:38 -0700 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2012-04-23 14:19:47 -0700 |
commit | 218733cf7d01fb6225e37a16818870d20c1d8771 (patch) | |
tree | f5b2afb03ced78868a9cad0599a1fb6b0aa4f8bd /drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | |
parent | d23f78e61f6b37159df6bfce7023500d731f61f3 (diff) |
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.c | 37 |
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 8e1cf97dfad..2a9fb984526 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, |