From 0434d3f4525af32bc29f858f71300351041f552d Mon Sep 17 00:00:00 2001 From: Brandon Maier Date: Sun, 17 Nov 2019 14:36:49 -0600 Subject: mailbox/omap: Handle if CONFIG_PM is disabled If CONFIG_PM is disabled, pm_runtime_put_sync() returns -ENOSYS. Signed-off-by: Brandon Maier Signed-off-by: Jassi Brar --- drivers/mailbox/omap-mailbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c index a3cd63583cf7..5978a35aac6d 100644 --- a/drivers/mailbox/omap-mailbox.c +++ b/drivers/mailbox/omap-mailbox.c @@ -868,7 +868,7 @@ static int omap_mbox_probe(struct platform_device *pdev) dev_info(mdev->dev, "omap mailbox rev 0x%x\n", l); ret = pm_runtime_put_sync(mdev->dev); - if (ret < 0) + if (ret < 0 && ret != -ENOSYS) goto unregister; devm_kfree(&pdev->dev, finfoblk); -- cgit From 41c9479903c5bd91bb0cb7240a1227d00c42b41f Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Tue, 29 Oct 2019 08:51:04 +0800 Subject: mailbox: no need to set .owner platform_driver_register the platform_driver_register will set the .owner to THIS_MODULE Signed-off-by: Tian Tao Signed-off-by: Jassi Brar --- drivers/mailbox/hi6220-mailbox.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mailbox/hi6220-mailbox.c b/drivers/mailbox/hi6220-mailbox.c index 8b9eb56e4311..cc236ac7a0b5 100644 --- a/drivers/mailbox/hi6220-mailbox.c +++ b/drivers/mailbox/hi6220-mailbox.c @@ -354,7 +354,6 @@ static int hi6220_mbox_probe(struct platform_device *pdev) static struct platform_driver hi6220_mbox_driver = { .driver = { .name = "hi6220-mbox", - .owner = THIS_MODULE, .of_match_table = hi6220_mbox_of_match, }, .probe = hi6220_mbox_probe, -- cgit From 69269446ccbf2b44fd2595ecfa57e29fb656788d Mon Sep 17 00:00:00 2001 From: Fabien Dessenne Date: Wed, 30 Oct 2019 14:57:01 +0100 Subject: mailbox: stm32-ipcc: Update wakeup management The wakeup specific IRQ management is no more needed to wake up the stm32 platform. A relationship has been established between the EXTI and the RX IRQ, just need to declare the EXTI interrupt instead of the IPCC RX IRQ. Signed-off-by: Alexandre Torgue Signed-off-by: Fabien Dessenne Signed-off-by: Jassi Brar --- drivers/mailbox/stm32-ipcc.c | 36 +++++++----------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/mailbox/stm32-ipcc.c b/drivers/mailbox/stm32-ipcc.c index 5c2d1e1f988b..ef966887aa15 100644 --- a/drivers/mailbox/stm32-ipcc.c +++ b/drivers/mailbox/stm32-ipcc.c @@ -52,7 +52,6 @@ struct stm32_ipcc { struct clk *clk; spinlock_t lock; /* protect access to IPCC registers */ int irqs[IPCC_IRQ_NUM]; - int wkp; u32 proc_id; u32 n_chans; u32 xcr; @@ -282,16 +281,9 @@ static int stm32_ipcc_probe(struct platform_device *pdev) /* wakeup */ if (of_property_read_bool(np, "wakeup-source")) { - ipcc->wkp = platform_get_irq_byname(pdev, "wakeup"); - if (ipcc->wkp < 0) { - if (ipcc->wkp != -EPROBE_DEFER) - dev_err(dev, "could not get wakeup IRQ\n"); - ret = ipcc->wkp; - goto err_clk; - } - device_set_wakeup_capable(dev, true); - ret = dev_pm_set_dedicated_wake_irq(dev, ipcc->wkp); + + ret = dev_pm_set_wake_irq(dev, ipcc->irqs[IPCC_IRQ_RX]); if (ret) { dev_err(dev, "Failed to set wake up irq\n"); goto err_init_wkp; @@ -334,10 +326,10 @@ static int stm32_ipcc_probe(struct platform_device *pdev) return 0; err_irq_wkp: - if (ipcc->wkp) + if (of_property_read_bool(np, "wakeup-source")) dev_pm_clear_wake_irq(dev); err_init_wkp: - device_init_wakeup(dev, false); + device_set_wakeup_capable(dev, false); err_clk: clk_disable_unprepare(ipcc->clk); return ret; @@ -345,27 +337,17 @@ err_clk: static int stm32_ipcc_remove(struct platform_device *pdev) { - struct stm32_ipcc *ipcc = platform_get_drvdata(pdev); + struct device *dev = &pdev->dev; - if (ipcc->wkp) + if (of_property_read_bool(dev->of_node, "wakeup-source")) dev_pm_clear_wake_irq(&pdev->dev); - device_init_wakeup(&pdev->dev, false); + device_set_wakeup_capable(dev, false); return 0; } #ifdef CONFIG_PM_SLEEP -static void stm32_ipcc_set_irq_wake(struct device *dev, bool enable) -{ - struct stm32_ipcc *ipcc = dev_get_drvdata(dev); - unsigned int i; - - if (device_may_wakeup(dev)) - for (i = 0; i < IPCC_IRQ_NUM; i++) - irq_set_irq_wake(ipcc->irqs[i], enable); -} - static int stm32_ipcc_suspend(struct device *dev) { struct stm32_ipcc *ipcc = dev_get_drvdata(dev); @@ -373,8 +355,6 @@ static int stm32_ipcc_suspend(struct device *dev) ipcc->xmr = readl_relaxed(ipcc->reg_proc + IPCC_XMR); ipcc->xcr = readl_relaxed(ipcc->reg_proc + IPCC_XCR); - stm32_ipcc_set_irq_wake(dev, true); - return 0; } @@ -382,8 +362,6 @@ static int stm32_ipcc_resume(struct device *dev) { struct stm32_ipcc *ipcc = dev_get_drvdata(dev); - stm32_ipcc_set_irq_wake(dev, false); - writel_relaxed(ipcc->xmr, ipcc->reg_proc + IPCC_XMR); writel_relaxed(ipcc->xcr, ipcc->reg_proc + IPCC_XCR); -- cgit From bf159d151a0b844be28882f39e316b5800acaa2b Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Wed, 9 Oct 2019 16:07:18 +0800 Subject: mailbox: imx: Fix Tx doorbell shutdown path Tx doorbell is handled by txdb_tasklet and doesn't have an associated IRQ. Anyhow, imx_mu_shutdown ignores this and tries to free an IRQ that wasn't requested for Tx DB resulting in the following warning: [ 1.967644] Trying to free already-free IRQ 26 [ 1.972108] WARNING: CPU: 2 PID: 157 at kernel/irq/manage.c:1708 __free_irq+0xc0/0x358 [ 1.980024] Modules linked in: [ 1.983088] CPU: 2 PID: 157 Comm: kworker/2:1 Tainted: G [ 1.993524] Hardware name: Freescale i.MX8QXP MEK (DT) [ 1.998668] Workqueue: events deferred_probe_work_func [ 2.003812] pstate: 60000085 (nZCv daIf -PAN -UAO) [ 2.008607] pc : __free_irq+0xc0/0x358 [ 2.012364] lr : __free_irq+0xc0/0x358 [ 2.016111] sp : ffff00001179b7e0 [ 2.019422] x29: ffff00001179b7e0 x28: 0000000000000018 [ 2.024736] x27: ffff000011233000 x26: 0000000000000004 [ 2.030053] x25: 000000000000001a x24: ffff80083bec74d4 [ 2.035369] x23: 0000000000000000 x22: ffff80083bec7588 [ 2.040686] x21: ffff80083b1fe8d8 x20: ffff80083bec7400 [ 2.046003] x19: 0000000000000000 x18: ffffffffffffffff [ 2.051320] x17: 0000000000000000 x16: 0000000000000000 [ 2.056637] x15: ffff0000111296c8 x14: ffff00009179b517 [ 2.061953] x13: ffff00001179b525 x12: ffff000011142000 [ 2.067270] x11: ffff000011129f20 x10: ffff0000105da970 [ 2.072587] x9 : 00000000ffffffd0 x8 : 0000000000000194 [ 2.077903] x7 : 612065657266206f x6 : ffff0000111e7b09 [ 2.083220] x5 : 0000000000000003 x4 : 0000000000000000 [ 2.088537] x3 : 0000000000000000 x2 : 00000000ffffffff [ 2.093854] x1 : 28b70f0a2b60a500 x0 : 0000000000000000 [ 2.099173] Call trace: [ 2.101618] __free_irq+0xc0/0x358 [ 2.105021] free_irq+0x38/0x98 [ 2.108170] imx_mu_shutdown+0x90/0xb0 [ 2.111921] mbox_free_channel.part.2+0x24/0xb8 [ 2.116453] mbox_free_channel+0x18/0x28 This bug is present from the beginning of times. Cc: Oleksij Rempel Signed-off-by: Daniel Baluta Signed-off-by: Richard Zhu Reviewed-by: Dong Aisheng Signed-off-by: Jassi Brar --- drivers/mailbox/imx-mailbox.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c index 9f74dee1a58c..957c10c4e674 100644 --- a/drivers/mailbox/imx-mailbox.c +++ b/drivers/mailbox/imx-mailbox.c @@ -214,8 +214,10 @@ static void imx_mu_shutdown(struct mbox_chan *chan) struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox); struct imx_mu_con_priv *cp = chan->con_priv; - if (cp->type == IMX_MU_TYPE_TXDB) + if (cp->type == IMX_MU_TYPE_TXDB) { tasklet_kill(&cp->txdb_tasklet); + return; + } imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_TIEn(cp->idx) | IMX_MU_xCR_RIEn(cp->idx) | IMX_MU_xCR_GIEn(cp->idx)); -- cgit From 5f0af07e89199ac51cdd4f25bc303bdc703f4e9c Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Wed, 9 Oct 2019 16:07:19 +0800 Subject: mailbox: imx: Clear the right interrupts at shutdown Make sure to only clear enabled interrupts keeping count of the connection type. Suggested-by: Oleksij Rempel Signed-off-by: Daniel Baluta Signed-off-by: Richard Zhu Reviewed-by: Dong Aisheng Signed-off-by: Jassi Brar --- drivers/mailbox/imx-mailbox.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c index 957c10c4e674..afe625e88a5c 100644 --- a/drivers/mailbox/imx-mailbox.c +++ b/drivers/mailbox/imx-mailbox.c @@ -219,8 +219,19 @@ static void imx_mu_shutdown(struct mbox_chan *chan) return; } - imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_TIEn(cp->idx) | - IMX_MU_xCR_RIEn(cp->idx) | IMX_MU_xCR_GIEn(cp->idx)); + switch (cp->type) { + case IMX_MU_TYPE_TX: + imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_TIEn(cp->idx)); + break; + case IMX_MU_TYPE_RX: + imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_RIEn(cp->idx)); + break; + case IMX_MU_TYPE_RXDB: + imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_GIEn(cp->idx)); + break; + default: + break; + } free_irq(priv->irq, chan); } -- cgit From c6c6bc6ea9fce31baaca053befc31215cfcb3dd9 Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Wed, 9 Oct 2019 16:07:21 +0800 Subject: mailbox: imx: add support for imx v1 mu There is a version 1.0 MU on i.MX7ULP platform. One new version ID register is added, and it's offset is 0. TRn registers are defined at the offset 0x20 ~ 0x2C. RRn registers are defined at the offset 0x40 ~ 0x4C. SR/CR registers are defined at 0x60/0x64. Extend this driver to support it. Signed-off-by: Richard Zhu Suggested-by: Oleksij Rempel Reviewed-by: Dong Aisheng Reviewed-by: Oleksij Rempel Reviewed-by: Daniel Baluta Signed-off-by: Jassi Brar --- drivers/mailbox/imx-mailbox.c | 55 ++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c index afe625e88a5c..2cdcdc5f1119 100644 --- a/drivers/mailbox/imx-mailbox.c +++ b/drivers/mailbox/imx-mailbox.c @@ -12,19 +12,11 @@ #include #include -/* Transmit Register */ -#define IMX_MU_xTRn(x) (0x00 + 4 * (x)) -/* Receive Register */ -#define IMX_MU_xRRn(x) (0x10 + 4 * (x)) -/* Status Register */ -#define IMX_MU_xSR 0x20 #define IMX_MU_xSR_GIPn(x) BIT(28 + (3 - (x))) #define IMX_MU_xSR_RFn(x) BIT(24 + (3 - (x))) #define IMX_MU_xSR_TEn(x) BIT(20 + (3 - (x))) #define IMX_MU_xSR_BRDIP BIT(9) -/* Control Register */ -#define IMX_MU_xCR 0x24 /* General Purpose Interrupt Enable */ #define IMX_MU_xCR_GIEn(x) BIT(28 + (3 - (x))) /* Receive Interrupt Enable */ @@ -44,6 +36,13 @@ enum imx_mu_chan_type { IMX_MU_TYPE_RXDB, /* Rx doorbell */ }; +struct imx_mu_dcfg { + u32 xTR[4]; /* Transmit Registers */ + u32 xRR[4]; /* Receive Registers */ + u32 xSR; /* Status Register */ + u32 xCR; /* Control Register */ +}; + struct imx_mu_con_priv { unsigned int idx; char irq_desc[IMX_MU_CHAN_NAME_SIZE]; @@ -61,12 +60,27 @@ struct imx_mu_priv { struct mbox_chan mbox_chans[IMX_MU_CHANS]; struct imx_mu_con_priv con_priv[IMX_MU_CHANS]; + const struct imx_mu_dcfg *dcfg; struct clk *clk; int irq; bool side_b; }; +static const struct imx_mu_dcfg imx_mu_cfg_imx6sx = { + .xTR = {0x0, 0x4, 0x8, 0xc}, + .xRR = {0x10, 0x14, 0x18, 0x1c}, + .xSR = 0x20, + .xCR = 0x24, +}; + +static const struct imx_mu_dcfg imx_mu_cfg_imx7ulp = { + .xTR = {0x20, 0x24, 0x28, 0x2c}, + .xRR = {0x40, 0x44, 0x48, 0x4c}, + .xSR = 0x60, + .xCR = 0x64, +}; + static struct imx_mu_priv *to_imx_mu_priv(struct mbox_controller *mbox) { return container_of(mbox, struct imx_mu_priv, mbox); @@ -88,10 +102,10 @@ static u32 imx_mu_xcr_rmw(struct imx_mu_priv *priv, u32 set, u32 clr) u32 val; spin_lock_irqsave(&priv->xcr_lock, flags); - val = imx_mu_read(priv, IMX_MU_xCR); + val = imx_mu_read(priv, priv->dcfg->xCR); val &= ~clr; val |= set; - imx_mu_write(priv, val, IMX_MU_xCR); + imx_mu_write(priv, val, priv->dcfg->xCR); spin_unlock_irqrestore(&priv->xcr_lock, flags); return val; @@ -111,8 +125,8 @@ static irqreturn_t imx_mu_isr(int irq, void *p) struct imx_mu_con_priv *cp = chan->con_priv; u32 val, ctrl, dat; - ctrl = imx_mu_read(priv, IMX_MU_xCR); - val = imx_mu_read(priv, IMX_MU_xSR); + ctrl = imx_mu_read(priv, priv->dcfg->xCR); + val = imx_mu_read(priv, priv->dcfg->xSR); switch (cp->type) { case IMX_MU_TYPE_TX: @@ -138,10 +152,10 @@ static irqreturn_t imx_mu_isr(int irq, void *p) imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_TIEn(cp->idx)); mbox_chan_txdone(chan, 0); } else if (val == IMX_MU_xSR_RFn(cp->idx)) { - dat = imx_mu_read(priv, IMX_MU_xRRn(cp->idx)); + dat = imx_mu_read(priv, priv->dcfg->xRR[cp->idx]); mbox_chan_received_data(chan, (void *)&dat); } else if (val == IMX_MU_xSR_GIPn(cp->idx)) { - imx_mu_write(priv, IMX_MU_xSR_GIPn(cp->idx), IMX_MU_xSR); + imx_mu_write(priv, IMX_MU_xSR_GIPn(cp->idx), priv->dcfg->xSR); mbox_chan_received_data(chan, NULL); } else { dev_warn_ratelimited(priv->dev, "Not handled interrupt\n"); @@ -159,7 +173,7 @@ static int imx_mu_send_data(struct mbox_chan *chan, void *data) switch (cp->type) { case IMX_MU_TYPE_TX: - imx_mu_write(priv, *arg, IMX_MU_xTRn(cp->idx)); + imx_mu_write(priv, *arg, priv->dcfg->xTR[cp->idx]); imx_mu_xcr_rmw(priv, IMX_MU_xCR_TIEn(cp->idx), 0); break; case IMX_MU_TYPE_TXDB: @@ -270,7 +284,7 @@ static void imx_mu_init_generic(struct imx_mu_priv *priv) return; /* Set default MU configuration */ - imx_mu_write(priv, 0, IMX_MU_xCR); + imx_mu_write(priv, 0, priv->dcfg->xCR); } static int imx_mu_probe(struct platform_device *pdev) @@ -278,6 +292,7 @@ static int imx_mu_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct imx_mu_priv *priv; + const struct imx_mu_dcfg *dcfg; unsigned int i; int ret; @@ -295,6 +310,11 @@ static int imx_mu_probe(struct platform_device *pdev) if (priv->irq < 0) return priv->irq; + dcfg = of_device_get_match_data(dev); + if (!dcfg) + return -EINVAL; + priv->dcfg = dcfg; + priv->clk = devm_clk_get(dev, NULL); if (IS_ERR(priv->clk)) { if (PTR_ERR(priv->clk) != -ENOENT) @@ -348,7 +368,8 @@ static int imx_mu_remove(struct platform_device *pdev) } static const struct of_device_id imx_mu_dt_ids[] = { - { .compatible = "fsl,imx6sx-mu" }, + { .compatible = "fsl,imx7ulp-mu", .data = &imx_mu_cfg_imx7ulp }, + { .compatible = "fsl,imx6sx-mu", .data = &imx_mu_cfg_imx6sx }, { }, }; MODULE_DEVICE_TABLE(of, imx_mu_dt_ids); -- cgit