aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/wil6210/interrupt.c
diff options
context:
space:
mode:
authorAlexei Avshalom Lazar <ailizaro@codeaurora.org>2018-07-24 10:44:29 +0300
committerKalle Valo <kvalo@codeaurora.org>2018-07-31 11:00:33 +0300
commitaea2f8b781b2a76fb0af4de2273d0c56c6d256a4 (patch)
tree048161a7409d021a06f7a129178cf6f5d89de9a7 /drivers/net/wireless/ath/wil6210/interrupt.c
parentb5aeff16b20f65e6bb9ebafd06c1c96c2b503089 (diff)
downloadkernel_replicant_linux-aea2f8b781b2a76fb0af4de2273d0c56c6d256a4.tar.gz
kernel_replicant_linux-aea2f8b781b2a76fb0af4de2273d0c56c6d256a4.tar.bz2
kernel_replicant_linux-aea2f8b781b2a76fb0af4de2273d0c56c6d256a4.zip
wil6210: add 3-MSI support
Extend MSI support to 3-MSI in order to load balance the tx\rx interrupts between different cores. use_msi module parameter has changed to n_msi. Usage: - Set n_msi to 0 for using INTx - Set n_msi to 1 for using single MSI - Set n_msi to 3 for using 3-MSI In 3-MSI configuration MSI 0 is used for TX interrupts, MSI 1 is used for RX interrupts and MSI 2 is used for MISC interrupts. Signed-off-by: Alexei Avshalom Lazar <ailizaro@codeaurora.org> Signed-off-by: Maya Erez <merez@codeaurora.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/interrupt.c')
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c64
1 files changed, 58 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index d7e112da6a8d..5d287a8e1b45 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -625,6 +625,15 @@ static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie)
wil6210_unmask_irq_misc(wil, false);
+ /* in non-triple MSI case, this is done inside wil6210_thread_irq
+ * because it has to be done after unmasking the pseudo.
+ */
+ if (wil->n_msi == 3 && wil->suspend_resp_rcvd) {
+ wil_dbg_irq(wil, "set suspend_resp_comp to true\n");
+ wil->suspend_resp_comp = true;
+ wake_up_interruptible(&wil->wq);
+ }
+
return IRQ_HANDLED;
}
@@ -782,6 +791,40 @@ static irqreturn_t wil6210_hardirq(int irq, void *cookie)
return rc;
}
+static int wil6210_request_3msi(struct wil6210_priv *wil, int irq)
+{
+ int rc;
+
+ /* IRQ's are in the following order:
+ * - Tx
+ * - Rx
+ * - Misc
+ */
+ rc = request_irq(irq, wil->txrx_ops.irq_tx, IRQF_SHARED,
+ WIL_NAME "_tx", wil);
+ if (rc)
+ return rc;
+
+ rc = request_irq(irq + 1, wil->txrx_ops.irq_rx, IRQF_SHARED,
+ WIL_NAME "_rx", wil);
+ if (rc)
+ goto free0;
+
+ rc = request_threaded_irq(irq + 2, wil6210_irq_misc,
+ wil6210_irq_misc_thread,
+ IRQF_SHARED, WIL_NAME "_misc", wil);
+ if (rc)
+ goto free1;
+
+ return 0;
+free1:
+ free_irq(irq + 1, wil);
+free0:
+ free_irq(irq, wil);
+
+ return rc;
+}
+
/* can't use wil_ioread32_and_clear because ICC value is not set yet */
static inline void wil_clear32(void __iomem *addr)
{
@@ -822,11 +865,12 @@ void wil6210_clear_halp(struct wil6210_priv *wil)
wil6210_unmask_halp(wil);
}
-int wil6210_init_irq(struct wil6210_priv *wil, int irq, bool use_msi)
+int wil6210_init_irq(struct wil6210_priv *wil, int irq)
{
int rc;
- wil_dbg_misc(wil, "init_irq: %s\n", use_msi ? "MSI" : "INTx");
+ wil_dbg_misc(wil, "init_irq: %s, n_msi=%d\n",
+ wil->n_msi ? "MSI" : "INTx", wil->n_msi);
if (wil->use_enhanced_dma_hw) {
wil->txrx_ops.irq_tx = wil6210_irq_tx_edma;
@@ -835,10 +879,14 @@ int wil6210_init_irq(struct wil6210_priv *wil, int irq, bool use_msi)
wil->txrx_ops.irq_tx = wil6210_irq_tx;
wil->txrx_ops.irq_rx = wil6210_irq_rx;
}
- rc = request_threaded_irq(irq, wil6210_hardirq,
- wil6210_thread_irq,
- use_msi ? 0 : IRQF_SHARED,
- WIL_NAME, wil);
+
+ if (wil->n_msi == 3)
+ rc = wil6210_request_3msi(wil, irq);
+ else
+ rc = request_threaded_irq(irq, wil6210_hardirq,
+ wil6210_thread_irq,
+ wil->n_msi ? 0 : IRQF_SHARED,
+ WIL_NAME, wil);
return rc;
}
@@ -848,4 +896,8 @@ void wil6210_fini_irq(struct wil6210_priv *wil, int irq)
wil_mask_irq(wil);
free_irq(irq, wil);
+ if (wil->n_msi == 3) {
+ free_irq(irq + 1, wil);
+ free_irq(irq + 2, wil);
+ }
}