ath10k assumed all interrupts were directed to it. This isn't the case for legacy shared interrupts. ath10k consumed interrupts for other devices. Check device irq status and return IRQ_NONE when appropriate. Signed-off-by: Michal Kazior <michal.kazior@xxxxxxxxx> --- drivers/net/wireless/ath/ath10k/hw.h | 1 + drivers/net/wireless/ath/ath10k/pci.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 8aeb46d..9535eaa 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -269,6 +269,7 @@ enum ath10k_mcast2ucast_mode { #define CORE_CTRL_CPU_INTR_MASK 0x00002000 #define CORE_CTRL_ADDRESS 0x0000 #define PCIE_INTR_ENABLE_ADDRESS 0x0008 +#define PCIE_INTR_CAUSE_ADDRESS 0x000c #define PCIE_INTR_CLR_ADDRESS 0x0014 #define SCRATCH_3_ADDRESS 0x0030 diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 2457c8b..ed752d6 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -2075,6 +2075,24 @@ static irqreturn_t ath10k_pci_msi_fw_handler(int irq, void *arg) return IRQ_HANDLED; } +static bool ath10k_pci_irq_pending(struct ath10k *ar) +{ + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); + u32 cause; + + /* MSIs are always exclusive */ + if (ar_pci->num_msi_intrs > 0) + return true; + + /* Check if the shared legacy irq is for us */ + cause = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + + PCIE_INTR_CAUSE_ADDRESS); + if (cause & (PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL)) + return true; + + return false; +} + /* * Top-level interrupt handler for all PCI interrupts from a Target. * When a block of MSI interrupts is allocated, this top-level handler @@ -2085,6 +2103,9 @@ static irqreturn_t ath10k_pci_interrupt_handler(int irq, void *arg) struct ath10k *ar = arg; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); + if (!ath10k_pci_irq_pending(ar)) + return IRQ_NONE; + if (ar_pci->num_msi_intrs == 0) { /* * IMPORTANT: INTR_CLR regiser has to be set after -- 1.8.4.rc3 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html