summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanley Chu <yschu@nuvoton.com>2026-04-13 08:50:39 +0800
committerAlexandre Belloni <alexandre.belloni@bootlin.com>2026-04-30 12:00:36 +0200
commitfa1d4fa118f4229168e9ca88cea260c5e5a94652 (patch)
tree4924668367a22d7d533845c55e5bb8c102567468
parent254f49634ee16a731174d2ae34bc50bd5f45e731 (diff)
downloadlinux-fa1d4fa118f4229168e9ca88cea260c5e5a94652.tar.gz
linux-fa1d4fa118f4229168e9ca88cea260c5e5a94652.zip
i3c: master: svc: Fix missed IBI after false SLVSTART on NPCM845
The NPCM845 I3C controller may raise a false SLVSTART interrupt. The handler first latches MSTATUS and then clears SLVSTART. If a real IBI request arrives after the handler latches MSTATUS but before it clears the SLVSTART interrupt status, HW sets the SLVREQ state. However, the handler still relies on the stale MSTATUS snapshot, returns early, and misses the real IBI. No further interrupt is generated for this pending IBI. Re-read MSTATUS to obtain the latest state and avoid missing a real IBI due to this race condition. Fixes: 4dd12e944f07 ("i3c: master: svc: Fix npcm845 invalid slvstart event") Signed-off-by: Stanley Chu <yschu@nuvoton.com> Reviewed-by: Frank Li <Frank.Li@nxp.com> Link: https://patch.msgid.link/20260413005040.1211107-2-yschu@nuvoton.com Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
-rw-r--r--drivers/i3c/master/svc-i3c-master.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c
index e2d99a3ac07d..63063741fbd1 100644
--- a/drivers/i3c/master/svc-i3c-master.c
+++ b/drivers/i3c/master/svc-i3c-master.c
@@ -672,10 +672,18 @@ static irqreturn_t svc_i3c_master_irq_handler(int irq, void *dev_id)
/* Clear the interrupt status */
writel(SVC_I3C_MINT_SLVSTART, master->regs + SVC_I3C_MSTATUS);
- /* Ignore the false event */
- if (svc_has_quirk(master, SVC_I3C_QUIRK_FALSE_SLVSTART) &&
- !SVC_I3C_MSTATUS_STATE_SLVREQ(active))
- return IRQ_HANDLED;
+ if (svc_has_quirk(master, SVC_I3C_QUIRK_FALSE_SLVSTART)) {
+ /*
+ * Re-read MSTATUS to obtain the latest state and avoid
+ * missing an IBI that arrives after MSTATUS is latched
+ * but before SLVSTART is cleared.
+ */
+ active = readl(master->regs + SVC_I3C_MSTATUS);
+
+ /* Ignore the false event */
+ if (!SVC_I3C_MSTATUS_STATE_SLVREQ(active))
+ return IRQ_HANDLED;
+ }
/*
* The SDA line remains low until the request is processed.