diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 618894ecfd22..ba8a81cb0e2b 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -784,13 +784,14 @@ static int iwl_pci_resume(struct device *device) /* * Enable rfkill interrupt (in order to keep track of - * the rfkill status) + * the rfkill status). Must be locked to avoid processing + * a possible rfkill interrupt between reading the state + * and calling iwl_trans_pcie_rf_kill() with it. */ + mutex_lock(&trans_pcie->mutex); iwl_enable_rfkill_int(trans); hw_rfkill = iwl_is_rfkill_set(trans); - - mutex_lock(&trans_pcie->mutex); iwl_trans_pcie_rf_kill(trans, hw_rfkill); mutex_unlock(&trans_pcie->mutex); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index cac6d99012b3..cf5bda06042c 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -670,6 +670,8 @@ static inline u8 get_cmd_index(struct iwl_txq *q, u32 index) static inline bool iwl_is_rfkill_set(struct iwl_trans *trans) { + lockdep_assert_held(&IWL_TRANS_GET_PCIE_TRANS(trans)->mutex); + return !(iwl_read32(trans, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); } diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 6fe5546dc773..e1bf6da20909 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1607,13 +1607,13 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) if (inta & CSR_INT_BIT_RF_KILL) { bool hw_rfkill; + mutex_lock(&trans_pcie->mutex); hw_rfkill = iwl_is_rfkill_set(trans); IWL_WARN(trans, "RF_KILL bit toggled to %s.\n", hw_rfkill ? "disable radio" : "enable radio"); isr_stats->rfkill++; - mutex_lock(&trans_pcie->mutex); iwl_trans_pcie_rf_kill(trans, hw_rfkill); mutex_unlock(&trans_pcie->mutex); if (hw_rfkill) { @@ -1952,13 +1952,13 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id) if (inta_hw & MSIX_HW_INT_CAUSES_REG_RF_KILL) { bool hw_rfkill; + mutex_lock(&trans_pcie->mutex); hw_rfkill = iwl_is_rfkill_set(trans); IWL_WARN(trans, "RF_KILL bit toggled to %s.\n", hw_rfkill ? "disable radio" : "enable radio"); isr_stats->rfkill++; - mutex_lock(&trans_pcie->mutex); iwl_trans_pcie_rf_kill(trans, hw_rfkill); mutex_unlock(&trans_pcie->mutex); if (hw_rfkill) {