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

Commit c1f8c113 authored by Maya Erez's avatar Maya Erez Committed by Lior David
Browse files

wil6210: ignore HALP ICR if already handled



HALP ICR is set as long as the FW should stay awake.
To prevent its multiple handling the driver masks this IRQ bit.
However, if there is a different MISC ICR before the driver clears
this bit, there is a risk of race condition between HALP mask and
unmask. This race leads to HALP timeout, in case it is mistakenly
masked.
Add an atomic flag to indicate if HALP ICR should be handled.

Change-Id: Ieb8765615de87001aaacd2e6ae6c0dbf96811614
Signed-off-by: default avatarMaya Erez <merez@codeaurora.org>
[liord@codeaurora.org: SPDX license]
Signed-off-by: default avatarLior David <liord@codeaurora.org>
parent c9d18cbc
Loading
Loading
Loading
Loading
+9 −16
Original line number Diff line number Diff line
// SPDX-License-Identifier: ISC
/*
 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
 * Copyright (c) 2018, 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
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 */

#include <linux/interrupt.h>
@@ -575,11 +564,15 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
	}

	if (isr & BIT_DMA_EP_MISC_ICR_HALP) {
		isr &= ~BIT_DMA_EP_MISC_ICR_HALP;
		if (atomic_read(&wil->halp.handle_icr)) {
			/* no need to handle HALP ICRs until next vote */
			atomic_set(&wil->halp.handle_icr, 0);
			wil_dbg_irq(wil, "irq_misc: HALP IRQ invoked\n");
			wil6210_mask_halp(wil);
		isr &= ~BIT_DMA_EP_MISC_ICR_HALP;
			complete(&wil->halp.comp);
		}
	}

	wil->isr_misc = isr;

+2 −0
Original line number Diff line number Diff line
@@ -1843,6 +1843,8 @@ void wil_halp_vote(struct wil6210_priv *wil)

	if (++wil->halp.ref_cnt == 1) {
		reinit_completion(&wil->halp.comp);
		/* mark to IRQ context to handle HALP ICR */
		atomic_set(&wil->halp.handle_icr, 1);
		wil6210_set_halp(wil);
		rc = wait_for_completion_timeout(&wil->halp.comp, to_jiffies);
		if (!rc) {
+1 −0
Original line number Diff line number Diff line
@@ -784,6 +784,7 @@ struct wil_halp {
	struct mutex		lock; /* protect halp ref_cnt */
	unsigned int		ref_cnt;
	struct completion	comp;
	atomic_t		handle_icr;
};

struct wil_blob_wrapper {