From: Sebastian Andrzej Siewior Date: Wed, 17 Jun 2026 06:55:34 +0000 (+0200) Subject: mailbox: imx: Don't force-thread the primary handler X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=36cac4b5101f8ecbc851356df175b99543c84ec6;p=thirdparty%2Fkernel%2Flinux.git mailbox: imx: Don't force-thread the primary handler The primary interrupt handler (imx_mu_isr()) no longer invokes any callbacks it only masks the interrupt source and returns. In a forced-threaded environment the IRQ-core will force-thread the primary handler which can be avoided. The primary handler uses a spinlock_t to protect the RMW operation in imx_mu_xcr_rmw() - nothing that may introduce long latencies. The lock can be turned into a raw_spinlock_t and then the primary handler can run in hardirq context even on PREEMPT_RT skipping one thread. Make struct imx_mu_priv::xcr_lock a raw_spinlock_t and skip force-threading the primrary handler by marking it IRQF_NO_THREAD. Reviewed-by: Peng Fan Reviewed-by: Mathieu Poirier Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Jassi Brar --- diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c index 1bd434bdff87..40bad2b3e4d1 100644 --- a/drivers/mailbox/imx-mailbox.c +++ b/drivers/mailbox/imx-mailbox.c @@ -87,7 +87,7 @@ struct imx_mu_priv { struct device *dev; void __iomem *base; void *msg; - spinlock_t xcr_lock; /* control register lock */ + raw_spinlock_t xcr_lock; /* control register lock */ struct mbox_controller mbox; struct mbox_chan mbox_chans[IMX_MU_CHANS]; @@ -207,15 +207,14 @@ static int imx_mu_rx_waiting_read(struct imx_mu_priv *priv, u32 *val, u32 idx) static u32 imx_mu_xcr_rmw(struct imx_mu_priv *priv, enum imx_mu_xcr type, u32 set, u32 clr) { - unsigned long flags; u32 val; - spin_lock_irqsave(&priv->xcr_lock, flags); + guard(raw_spinlock_irqsave)(&priv->xcr_lock); + val = imx_mu_read(priv, priv->dcfg->xCR[type]); val &= ~clr; val |= set; imx_mu_write(priv, val, priv->dcfg->xCR[type]); - spin_unlock_irqrestore(&priv->xcr_lock, flags); return val; } @@ -223,31 +222,27 @@ static u32 imx_mu_xcr_rmw(struct imx_mu_priv *priv, enum imx_mu_xcr type, u32 se static void imx_mu_xcr_clr_shut(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp, enum imx_mu_xcr type, u32 clr) { - unsigned long flags; u32 val; - spin_lock_irqsave(&priv->xcr_lock, flags); + guard(raw_spinlock_irqsave)(&priv->xcr_lock); cp->shutdown = true; val = imx_mu_read(priv, priv->dcfg->xCR[type]); val &= ~clr; imx_mu_write(priv, val, priv->dcfg->xCR[type]); - spin_unlock_irqrestore(&priv->xcr_lock, flags); } static void imx_mu_xcr_set_act(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp, enum imx_mu_xcr type, u32 set) { - unsigned long flags; u32 val; - spin_lock_irqsave(&priv->xcr_lock, flags); + guard(raw_spinlock_irqsave)(&priv->xcr_lock); if (!cp->shutdown) { val = imx_mu_read(priv, priv->dcfg->xCR[type]); val |= set; imx_mu_write(priv, val, priv->dcfg->xCR[type]); } - spin_unlock_irqrestore(&priv->xcr_lock, flags); } static int imx_mu_generic_tx(struct imx_mu_priv *priv, @@ -640,7 +635,7 @@ static int imx_mu_startup(struct mbox_chan *chan) { struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox); struct imx_mu_con_priv *cp = chan->con_priv; - unsigned long irq_flag = 0; + unsigned long irq_flag = IRQF_NO_THREAD; int ret; pm_runtime_get_sync(priv->dev); @@ -988,7 +983,7 @@ static int imx_mu_probe(struct platform_device *pdev) goto disable_clk; } - spin_lock_init(&priv->xcr_lock); + raw_spin_lock_init(&priv->xcr_lock); priv->mbox.dev = dev; priv->mbox.ops = &imx_mu_ops;