From a5cb407a7af4d825bbf8c299db155dc58848ecc5 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 9 Mar 2022 18:03:44 +0800 Subject: mailbox: imx: support dual interrupts i.MX93 S401 MU support two interrupts: tx empty and rx full. - Introduce a new flag IMX_MU_V2_IRQ for the dual interrupt case - Update Copyright Signed-off-by: Peng Fan Signed-off-by: Jassi Brar --- drivers/mailbox/imx-mailbox.c | 45 ++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) (limited to 'drivers/mailbox') diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c index 03699843a6fd..24977d66bfb9 100644 --- a/drivers/mailbox/imx-mailbox.c +++ b/drivers/mailbox/imx-mailbox.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018 Pengutronix, Oleksij Rempel + * Copyright 2022 NXP, Peng Fan */ #include @@ -28,11 +29,12 @@ #define IMX_MU_SECO_TX_TOUT (msecs_to_jiffies(3000)) #define IMX_MU_SECO_RX_TOUT (msecs_to_jiffies(3000)) +/* Please not change TX & RX */ enum imx_mu_chan_type { - IMX_MU_TYPE_TX, /* Tx */ - IMX_MU_TYPE_RX, /* Rx */ - IMX_MU_TYPE_TXDB, /* Tx doorbell */ - IMX_MU_TYPE_RXDB, /* Rx doorbell */ + IMX_MU_TYPE_TX = 0, /* Tx */ + IMX_MU_TYPE_RX = 1, /* Rx */ + IMX_MU_TYPE_TXDB = 2, /* Tx doorbell */ + IMX_MU_TYPE_RXDB = 3, /* Rx doorbell */ }; enum imx_mu_xcr { @@ -92,6 +94,7 @@ enum imx_mu_type { IMX_MU_V1, IMX_MU_V2 = BIT(1), IMX_MU_V2_S4 = BIT(15), + IMX_MU_V2_IRQ = BIT(16), }; struct imx_mu_dcfg { @@ -536,7 +539,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 = IRQF_SHARED; + unsigned long irq_flag = 0; int ret; pm_runtime_get_sync(priv->dev); @@ -551,11 +554,12 @@ static int imx_mu_startup(struct mbox_chan *chan) if (!priv->dev->pm_domain) irq_flag |= IRQF_NO_SUSPEND; - ret = request_irq(priv->irq[0], imx_mu_isr, irq_flag, - cp->irq_desc, chan); + if (!(priv->dcfg->type & IMX_MU_V2_IRQ)) + irq_flag |= IRQF_SHARED; + + ret = request_irq(priv->irq[cp->type], imx_mu_isr, irq_flag, cp->irq_desc, chan); if (ret) { - dev_err(priv->dev, - "Unable to acquire IRQ %d\n", priv->irq[0]); + dev_err(priv->dev, "Unable to acquire IRQ %d\n", priv->irq[cp->type]); return ret; } @@ -598,7 +602,7 @@ static void imx_mu_shutdown(struct mbox_chan *chan) break; } - free_irq(priv->irq[0], chan); + free_irq(priv->irq[cp->type], chan); pm_runtime_put_sync(priv->dev); } @@ -749,7 +753,7 @@ static int imx_mu_probe(struct platform_device *pdev) struct device_node *np = dev->of_node; struct imx_mu_priv *priv; const struct imx_mu_dcfg *dcfg; - int ret; + int i, ret; u32 size; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -762,14 +766,25 @@ static int imx_mu_probe(struct platform_device *pdev) if (IS_ERR(priv->base)) return PTR_ERR(priv->base); - priv->irq[0] = platform_get_irq(pdev, 0); - if (priv->irq[0] < 0) - return priv->irq[0]; - dcfg = of_device_get_match_data(dev); if (!dcfg) return -EINVAL; priv->dcfg = dcfg; + if (priv->dcfg->type & IMX_MU_V2_IRQ) { + priv->irq[IMX_MU_TYPE_TX] = platform_get_irq_byname(pdev, "tx"); + if (priv->irq[IMX_MU_TYPE_TX] < 0) + return priv->irq[IMX_MU_TYPE_TX]; + priv->irq[IMX_MU_TYPE_RX] = platform_get_irq_byname(pdev, "rx"); + if (priv->irq[IMX_MU_TYPE_RX] < 0) + return priv->irq[IMX_MU_TYPE_RX]; + } else { + ret = platform_get_irq(pdev, 0); + if (ret < 0) + return ret; + + for (i = 0; i < IMX_MU_CHANS; i++) + priv->irq[i] = ret; + } if (priv->dcfg->type & IMX_MU_V2_S4) size = sizeof(struct imx_s4_rpc_msg_max); -- cgit v1.2.3