diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2012-03-31 11:28:38 -0400 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2012-04-23 17:19:47 -0400 |
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 8e1cf97dfad2..2a9fb984526f 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) | |||
1210 | iwl_disable_interrupts(trans); | 1210 | iwl_disable_interrupts(trans); |
1211 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 1211 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
1212 | 1212 | ||
1213 | iwl_enable_rfkill_int(trans); | ||
1214 | |||
1213 | /* wait to make sure we flush pending tasklet*/ | 1215 | /* wait to make sure we flush pending tasklet*/ |
1214 | synchronize_irq(trans_pcie->irq); | 1216 | synchronize_irq(trans_pcie->irq); |
1215 | tasklet_kill(&trans_pcie->irq_tasklet); | 1217 | tasklet_kill(&trans_pcie->irq_tasklet); |
@@ -1436,24 +1438,37 @@ error: | |||
1436 | return err; | 1438 | return err; |
1437 | } | 1439 | } |
1438 | 1440 | ||
1439 | static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans) | 1441 | static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, |
1442 | bool op_mode_leaving) | ||
1440 | { | 1443 | { |
1441 | bool hw_rfkill; | 1444 | bool hw_rfkill; |
1445 | unsigned long flags; | ||
1446 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1442 | 1447 | ||
1443 | iwl_apm_stop(trans); | 1448 | iwl_apm_stop(trans); |
1444 | 1449 | ||
1445 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); | 1450 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); |
1451 | iwl_disable_interrupts(trans); | ||
1452 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | ||
1446 | 1453 | ||
1447 | /* Even if we stop the HW, we still want the RF kill interrupt */ | 1454 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); |
1448 | iwl_enable_rfkill_int(trans); | ||
1449 | 1455 | ||
1450 | /* | 1456 | if (!op_mode_leaving) { |
1451 | * Check again since the RF kill state may have changed while all the | 1457 | /* |
1452 | * interrupts were disabled, in this case we couldn't receive the | 1458 | * Even if we stop the HW, we still want the RF kill |
1453 | * RF kill interrupt and update the state in the op_mode. | 1459 | * interrupt |
1454 | */ | 1460 | */ |
1455 | hw_rfkill = iwl_is_rfkill_set(trans); | 1461 | iwl_enable_rfkill_int(trans); |
1456 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); | 1462 | |
1463 | /* | ||
1464 | * Check again since the RF kill state may have changed while | ||
1465 | * all the interrupts were disabled, in this case we couldn't | ||
1466 | * receive the RF kill interrupt and update the state in the | ||
1467 | * op_mode. | ||
1468 | */ | ||
1469 | hw_rfkill = iwl_is_rfkill_set(trans); | ||
1470 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); | ||
1471 | } | ||
1457 | } | 1472 | } |
1458 | 1473 | ||
1459 | static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, | 1474 | static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, |