From: Peng Fan <peng.fan@xxxxxxx> 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 - Add i.MX93 S401 MU cfg Signed-off-by: Peng Fan <peng.fan@xxxxxxx> --- drivers/mailbox/imx-mailbox.c | 47 ++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c index 03699843a6fd..da1c6ca8bee2 100644 --- a/drivers/mailbox/imx-mailbox.c +++ b/drivers/mailbox/imx-mailbox.c @@ -28,6 +28,7 @@ #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 */ @@ -92,6 +93,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 +538,8 @@ 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 irq; int ret; pm_runtime_get_sync(priv->dev); @@ -551,11 +554,16 @@ 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 = priv->irq[cp->type]; + } else { + irq = priv->irq[0]; + irq_flag |= IRQF_SHARED; + } + + ret = request_irq(irq, 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", irq); return ret; } @@ -762,14 +770,23 @@ 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, "txirq"); + 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, "rxirq"); + if (priv->irq[IMX_MU_TYPE_RX] < 0) + return priv->irq[IMX_MU_TYPE_RX]; + } else { + priv->irq[0] = platform_get_irq(pdev, 0); + if (priv->irq[0] < 0) + return priv->irq[0]; + + } if (priv->dcfg->type & IMX_MU_V2_S4) size = sizeof(struct imx_s4_rpc_msg_max); @@ -890,6 +907,17 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp_s4 = { .xCR = {0x110, 0x114, 0x120, 0x128}, }; +static const struct imx_mu_dcfg imx_mu_cfg_imx93_s4 = { + .tx = imx_mu_specific_tx, + .rx = imx_mu_specific_rx, + .init = imx_mu_init_specific, + .type = IMX_MU_V2 | IMX_MU_V2_S4 | IMX_MU_V2_IRQ, + .xTR = 0x200, + .xRR = 0x280, + .xSR = {0xC, 0x118, 0x124, 0x12C}, + .xCR = {0x110, 0x114, 0x120, 0x128}, +}; + static const struct imx_mu_dcfg imx_mu_cfg_imx8_scu = { .tx = imx_mu_specific_tx, .rx = imx_mu_specific_rx, @@ -917,6 +945,7 @@ static const struct of_device_id imx_mu_dt_ids[] = { { .compatible = "fsl,imx6sx-mu", .data = &imx_mu_cfg_imx6sx }, { .compatible = "fsl,imx8ulp-mu", .data = &imx_mu_cfg_imx8ulp }, { .compatible = "fsl,imx8ulp-mu-s4", .data = &imx_mu_cfg_imx8ulp_s4 }, + { .compatible = "fsl,imx93-mu-s4", .data = &imx_mu_cfg_imx93_s4 }, { .compatible = "fsl,imx8-mu-scu", .data = &imx_mu_cfg_imx8_scu }, { .compatible = "fsl,imx8-mu-seco", .data = &imx_mu_cfg_imx8_seco }, { }, -- 2.25.1