summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index 294fbc1e89ab..ffdd4b995f33 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -481,6 +481,15 @@ static inline void ath10k_ce_engine_int_status_clear(struct ath10k *ar,
ath10k_ce_write32(ar, ce_ctrl_addr + wm_regs->addr, mask);
}
+static inline bool ath10k_ce_engine_int_status_check(struct ath10k *ar,
+ u32 ce_ctrl_addr,
+ unsigned int mask)
+{
+ struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs;
+
+ return ath10k_ce_read32(ar, ce_ctrl_addr + wm_regs->addr) & mask;
+}
+
/*
* Guts of ath10k_ce_send.
* The caller takes responsibility for any needed locking.
@@ -1301,19 +1310,22 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
spin_lock_bh(&ce->ce_lock);
- /* Clear the copy-complete interrupts that will be handled here. */
- ath10k_ce_engine_int_status_clear(ar, ctrl_addr,
- wm_regs->cc_mask);
+ if (ath10k_ce_engine_int_status_check(ar, ctrl_addr,
+ wm_regs->cc_mask)) {
+ /* Clear before handling */
+ ath10k_ce_engine_int_status_clear(ar, ctrl_addr,
+ wm_regs->cc_mask);
- spin_unlock_bh(&ce->ce_lock);
+ spin_unlock_bh(&ce->ce_lock);
- if (ce_state->recv_cb)
- ce_state->recv_cb(ce_state);
+ if (ce_state->recv_cb)
+ ce_state->recv_cb(ce_state);
- if (ce_state->send_cb)
- ce_state->send_cb(ce_state);
+ if (ce_state->send_cb)
+ ce_state->send_cb(ce_state);
- spin_lock_bh(&ce->ce_lock);
+ spin_lock_bh(&ce->ce_lock);
+ }
/*
* Misc CE interrupts are not being handled, but still need