Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 154aa474 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "wil6210: fix spurious interrupts in 3-msi"

parents ce7befb4 fafecaa3
Loading
Loading
Loading
Loading
+41 −26
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
@@ -296,21 +296,24 @@ void wil_configure_interrupt_moderation(struct wil6210_priv *wil)
static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
{
	struct wil6210_priv *wil = cookie;
	u32 isr = wil_ioread32_and_clear(wil->csr +
	u32 isr;
	bool need_unmask = true;

	wil6210_mask_irq_rx(wil);

	isr = wil_ioread32_and_clear(wil->csr +
				     HOSTADDR(RGF_DMA_EP_RX_ICR) +
				     offsetof(struct RGF_ICR, ICR));
	bool need_unmask = true;

	trace_wil6210_irq_rx(isr);
	wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr);

	if (unlikely(!isr)) {
		wil_err_ratelimited(wil, "spurious IRQ: RX\n");
		wil6210_unmask_irq_rx(wil);
		return IRQ_NONE;
	}

	wil6210_mask_irq_rx(wil);

	/* RX_DONE and RX_HTRSH interrupts are the same if interrupt
	 * moderation is not used. Interrupt moderation may cause RX
	 * buffer overflow while RX_DONE is delayed. The required
@@ -355,21 +358,24 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
static irqreturn_t wil6210_irq_rx_edma(int irq, void *cookie)
{
	struct wil6210_priv *wil = cookie;
	u32 isr = wil_ioread32_and_clear(wil->csr +
	u32 isr;
	bool need_unmask = true;

	wil6210_mask_irq_rx_edma(wil);

	isr = wil_ioread32_and_clear(wil->csr +
				     HOSTADDR(RGF_INT_GEN_RX_ICR) +
				     offsetof(struct RGF_ICR, ICR));
	bool need_unmask = true;

	trace_wil6210_irq_rx(isr);
	wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr);

	if (unlikely(!isr)) {
		wil_err(wil, "spurious IRQ: RX\n");
		wil6210_unmask_irq_rx_edma(wil);
		return IRQ_NONE;
	}

	wil6210_mask_irq_rx_edma(wil);

	if (likely(isr & BIT_RX_STATUS_IRQ)) {
		wil_dbg_irq(wil, "RX status ring\n");
		isr &= ~BIT_RX_STATUS_IRQ;
@@ -403,21 +409,24 @@ static irqreturn_t wil6210_irq_rx_edma(int irq, void *cookie)
static irqreturn_t wil6210_irq_tx_edma(int irq, void *cookie)
{
	struct wil6210_priv *wil = cookie;
	u32 isr = wil_ioread32_and_clear(wil->csr +
	u32 isr;
	bool need_unmask = true;

	wil6210_mask_irq_tx_edma(wil);

	isr = wil_ioread32_and_clear(wil->csr +
				     HOSTADDR(RGF_INT_GEN_TX_ICR) +
				     offsetof(struct RGF_ICR, ICR));
	bool need_unmask = true;

	trace_wil6210_irq_tx(isr);
	wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr);

	if (unlikely(!isr)) {
		wil_err(wil, "spurious IRQ: TX\n");
		wil6210_unmask_irq_tx_edma(wil);
		return IRQ_NONE;
	}

	wil6210_mask_irq_tx_edma(wil);

	if (likely(isr & BIT_TX_STATUS_IRQ)) {
		wil_dbg_irq(wil, "TX status ring\n");
		isr &= ~BIT_TX_STATUS_IRQ;
@@ -446,21 +455,24 @@ static irqreturn_t wil6210_irq_tx_edma(int irq, void *cookie)
static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
{
	struct wil6210_priv *wil = cookie;
	u32 isr = wil_ioread32_and_clear(wil->csr +
	u32 isr;
	bool need_unmask = true;

	wil6210_mask_irq_tx(wil);

	isr = wil_ioread32_and_clear(wil->csr +
				     HOSTADDR(RGF_DMA_EP_TX_ICR) +
				     offsetof(struct RGF_ICR, ICR));
	bool need_unmask = true;

	trace_wil6210_irq_tx(isr);
	wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr);

	if (unlikely(!isr)) {
		wil_err_ratelimited(wil, "spurious IRQ: TX\n");
		wil6210_unmask_irq_tx(wil);
		return IRQ_NONE;
	}

	wil6210_mask_irq_tx(wil);

	if (likely(isr & BIT_DMA_EP_TX_ICR_TX_DONE)) {
		wil_dbg_irq(wil, "TX done\n");
		isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE;
@@ -532,7 +544,11 @@ static bool wil_validate_mbox_regs(struct wil6210_priv *wil)
static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
{
	struct wil6210_priv *wil = cookie;
	u32 isr = wil_ioread32_and_clear(wil->csr +
	u32 isr;

	wil6210_mask_irq_misc(wil, false);

	isr = wil_ioread32_and_clear(wil->csr +
				     HOSTADDR(RGF_DMA_EP_MISC_ICR) +
				     offsetof(struct RGF_ICR, ICR));

@@ -541,11 +557,10 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)

	if (!isr) {
		wil_err(wil, "spurious IRQ: MISC\n");
		wil6210_unmask_irq_misc(wil, false);
		return IRQ_NONE;
	}

	wil6210_mask_irq_misc(wil, false);

	if (isr & ISR_MISC_FW_ERROR) {
		u32 fw_assert_code = wil_r(wil, wil->rgf_fw_assert_code_addr);
		u32 ucode_assert_code =