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

Commit 89857a8a authored by Madalin Bucur's avatar Madalin Bucur Committed by Li Yang
Browse files

soc: fsl: qbman: avoid race in clearing QMan interrupt



By clearing all interrupt sources, not only those that
already occurred, the existing code may acknowledge by
mistake interrupts that occurred after the code checks
for them.

Signed-off-by: default avatarMadalin Bucur <madalin.bucur@nxp.com>
Signed-off-by: default avatarRoy Pledge <roy.pledge@nxp.com>
Signed-off-by: default avatarLi Yang <leoyang.li@nxp.com>
parent bfeffd15
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -1143,18 +1143,19 @@ static void qm_mr_process_task(struct work_struct *work);
static irqreturn_t portal_isr(int irq, void *ptr)
{
	struct qman_portal *p = ptr;

	u32 clear = QM_DQAVAIL_MASK | p->irq_sources;
	u32 is = qm_in(&p->p, QM_REG_ISR) & p->irq_sources;
	u32 clear = 0;

	if (unlikely(!is))
		return IRQ_NONE;

	/* DQRR-handling if it's interrupt-driven */
	if (is & QM_PIRQ_DQRI)
	if (is & QM_PIRQ_DQRI) {
		__poll_portal_fast(p, QMAN_POLL_LIMIT);
		clear = QM_DQAVAIL_MASK | QM_PIRQ_DQRI;
	}
	/* Handling of anything else that's interrupt-driven */
	clear |= __poll_portal_slow(p, is);
	clear |= __poll_portal_slow(p, is) & QM_PIRQ_SLOW;
	qm_out(&p->p, QM_REG_ISR, clear);
	return IRQ_HANDLED;
}