aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/mac.c
diff options
context:
space:
mode:
authorRajkumar Manoharan <rmanohar@qca.qualcomm.com>2011-08-05 09:29:41 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-08-09 15:52:06 -0400
commite8fe7336849e469978c9bbcc435903595912c4d3 (patch)
treebed38f150ef777fdaac6a8ff90b1cd7cd0fbe216 /drivers/net/wireless/ath/ath9k/mac.c
parenta844adfd7bee4edc66d337de6c33b348e83552a8 (diff)
ath9k: Use atomic reference count for interrupt ops
Let us enable/disable interrupts based on reference count. By doing this we can ensure that interrupts are never be enabled in the middle of tasklet processing. Instead of addressing corner cases like "ath9k: avoid enabling interrupts while processing rx", this approach handles it in generic manner. Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/mac.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index c3af61e38bd5..0f90e1521ffe 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -800,6 +800,11 @@ void ath9k_hw_disable_interrupts(struct ath_hw *ah)
800{ 800{
801 struct ath_common *common = ath9k_hw_common(ah); 801 struct ath_common *common = ath9k_hw_common(ah);
802 802
803 if (!(ah->imask & ATH9K_INT_GLOBAL))
804 atomic_set(&ah->intr_ref_cnt, -1);
805 else
806 atomic_dec(&ah->intr_ref_cnt);
807
803 ath_dbg(common, ATH_DBG_INTERRUPT, "disable IER\n"); 808 ath_dbg(common, ATH_DBG_INTERRUPT, "disable IER\n");
804 REG_WRITE(ah, AR_IER, AR_IER_DISABLE); 809 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
805 (void) REG_READ(ah, AR_IER); 810 (void) REG_READ(ah, AR_IER);
@@ -821,6 +826,13 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)
821 if (!(ah->imask & ATH9K_INT_GLOBAL)) 826 if (!(ah->imask & ATH9K_INT_GLOBAL))
822 return; 827 return;
823 828
829 if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
830 ath_dbg(common, ATH_DBG_INTERRUPT,
831 "Do not enable IER ref count %d\n",
832 atomic_read(&ah->intr_ref_cnt));
833 return;
834 }
835
824 if (AR_SREV_9340(ah)) 836 if (AR_SREV_9340(ah))
825 sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; 837 sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
826 838
@@ -852,7 +864,6 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
852 864
853 ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); 865 ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
854 866
855 /* TODO: global int Ref count */
856 mask = ints & ATH9K_INT_COMMON; 867 mask = ints & ATH9K_INT_COMMON;
857 mask2 = 0; 868 mask2 = 0;
858 869