iwlwifi: pcie: track interrupt mask in SW
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 9 Dec 2013 09:09:47 +0000 (11:09 +0200)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Tue, 17 Dec 2013 20:32:58 +0000 (22:32 +0200)
Track the interrupt mask in software, making it exactly
what is configured in the interrupt mask register in the
hardware.
This allows not to access the register from the interrupt
handler. This was the case for ICT interrupt already, but
not for non-ICT interrupt.

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/pcie/internal.h
drivers/net/wireless/iwlwifi/pcie/rx.c

index 674c75b0d002f23244f12de07d66f35aa7254073..53c523735332c1836ebfea5cd3eb4eead4301c57 100644 (file)
@@ -397,13 +397,17 @@ static inline void iwl_enable_interrupts(struct iwl_trans *trans)
 
        IWL_DEBUG_ISR(trans, "Enabling interrupts\n");
        set_bit(STATUS_INT_ENABLED, &trans->status);
+       trans_pcie->inta_mask = CSR_INI_SET_MASK;
        iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask);
 }
 
 static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
 {
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
        IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n");
-       iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
+       trans_pcie->inta_mask = CSR_INT_BIT_RF_KILL;
+       iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask);
 }
 
 static inline void iwl_wake_queue(struct iwl_trans *trans,
index b3e6564af537a199d6240c3d7eaaf70b81ead29c..7e4836f376a2bb3153c2fea1a53ee446785c9b59 100644 (file)
@@ -1115,7 +1115,7 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data)
 {
        struct iwl_trans *trans = data;
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-       u32 inta, inta_mask;
+       u32 inta;
 
        lockdep_assert_held(&trans_pcie->irq_lock);
 
@@ -1125,18 +1125,17 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data)
         *    back-to-back ISRs and sporadic interrupts from our NIC.
         * If we have something to service, the irq thread will re-enable ints.
         * If we *don't* have something, we'll re-enable before leaving here. */
-       inta_mask = iwl_read32(trans, CSR_INT_MASK);
        iwl_write32(trans, CSR_INT_MASK, 0x00000000);
 
        /* Discover which interrupts are active/pending */
        inta = iwl_read32(trans, CSR_INT);
 
-       if (inta & (~inta_mask)) {
+       if (inta & (~trans_pcie->inta_mask)) {
                IWL_DEBUG_ISR(trans,
                              "We got a masked interrupt (0x%08x)...Ack and ignore\n",
-                             inta & (~inta_mask));
-               iwl_write32(trans, CSR_INT, inta & (~inta_mask));
-               inta &= inta_mask;
+                             inta & (~trans_pcie->inta_mask));
+               iwl_write32(trans, CSR_INT, inta & (~trans_pcie->inta_mask));
+               inta &= trans_pcie->inta_mask;
        }
 
        /* Ignore interrupt if there's nothing in NIC to service.
@@ -1166,7 +1165,7 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data)
        if (iwl_have_debug_level(IWL_DL_ISR))
                IWL_DEBUG_ISR(trans,
                              "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
-                             inta, inta_mask,
+                             inta, trans_pcie->inta_mask,
                              iwl_read32(trans, CSR_FH_INT_STATUS));
 
        trans_pcie->inta |= inta;