mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 01:32:21 +02:00
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 <peng.fan@nxp.com> Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
This commit is contained in:
parent
3225a745f5
commit
36cac4b510
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user