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

Commit facd1e46 authored by Jilai Wang's avatar Jilai Wang
Browse files

msm: npu: Fix missing interrupt issue when sending packet to firmware



It is possible that qhdr_rx_req is changed by firmware while
driver is writing the command packet to the IPC queue. Then driver
may not send an interrupt to fw at the end but fw does require
an interrupt. This change is to fix this potential racing condition
by checking if an interrupt is requested by firmware after
qhdr_write_idx is updated.

Change-Id: Ia6890d515a3eee778742113b77c3a08d60f4b4f2
Signed-off-by: default avatarJilai Wang <jilaiw@codeaurora.org>
parent 4ba47fa8
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 */

/* -------------------------------------------------------------------------
@@ -367,8 +367,6 @@ static int ipc_queue_write(struct npu_device *npu_dev,
	/* Update qhdr_write_idx */
	queue.qhdr_write_idx = new_write_idx;

	*is_rx_req_set = (queue.qhdr_rx_req == 1) ? 1 : 0;

	/* Update Write pointer -- queue.qhdr_write_idx */
exit:
	/* Update TX request -- queue.qhdr_tx_req */
@@ -379,6 +377,13 @@ static int ipc_queue_write(struct npu_device *npu_dev,
		(size_t)&(queue.qhdr_write_idx) - (size_t)&queue))),
		&queue.qhdr_write_idx, sizeof(queue.qhdr_write_idx));

	/* check if irq is required after write_idx is updated */
	MEMR(npu_dev, (void *)((size_t)(offset + (uint32_t)(
		(size_t)&(queue.qhdr_rx_req) - (size_t)&queue))),
		(uint8_t *)&queue.qhdr_rx_req,
		sizeof(queue.qhdr_rx_req));
	*is_rx_req_set = (queue.qhdr_rx_req == 1) ? 1 : 0;

	return status;
}