From 38ed8c888e94f10e3a74a931760e77c0ab9d2e48 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Wed, 14 Sep 2022 09:34:21 +0100 Subject: mailbox: apple: Implement flush() operation This allows clients to use the atomic-safe mailbox API style. Signed-off-by: Hector Martin Signed-off-by: Russell King (Oracle) Signed-off-by: Jassi Brar --- drivers/mailbox/apple-mailbox.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'drivers') diff --git a/drivers/mailbox/apple-mailbox.c b/drivers/mailbox/apple-mailbox.c index 496c4951ccb1..33e7acf71e3e 100644 --- a/drivers/mailbox/apple-mailbox.c +++ b/drivers/mailbox/apple-mailbox.c @@ -17,6 +17,7 @@ */ #include +#include #include #include #include @@ -112,6 +113,14 @@ static bool apple_mbox_hw_can_send(struct apple_mbox *apple_mbox) return !(mbox_ctrl & apple_mbox->hw->control_full); } +static bool apple_mbox_hw_send_empty(struct apple_mbox *apple_mbox) +{ + u32 mbox_ctrl = + readl_relaxed(apple_mbox->regs + apple_mbox->hw->a2i_control); + + return mbox_ctrl & apple_mbox->hw->control_empty; +} + static int apple_mbox_hw_send(struct apple_mbox *apple_mbox, struct apple_mbox_msg *msg) { @@ -219,6 +228,23 @@ static irqreturn_t apple_mbox_recv_irq(int irq, void *data) return IRQ_HANDLED; } +static int apple_mbox_chan_flush(struct mbox_chan *chan, unsigned long timeout) +{ + struct apple_mbox *apple_mbox = chan->con_priv; + unsigned long deadline = jiffies + msecs_to_jiffies(timeout); + + while (time_before(jiffies, deadline)) { + if (apple_mbox_hw_send_empty(apple_mbox)) { + mbox_chan_txdone(&apple_mbox->chan, 0); + return 0; + } + + udelay(1); + } + + return -ETIME; +} + static int apple_mbox_chan_startup(struct mbox_chan *chan) { struct apple_mbox *apple_mbox = chan->con_priv; @@ -250,6 +276,7 @@ static void apple_mbox_chan_shutdown(struct mbox_chan *chan) static const struct mbox_chan_ops apple_mbox_ops = { .send_data = apple_mbox_chan_send_data, + .flush = apple_mbox_chan_flush, .startup = apple_mbox_chan_startup, .shutdown = apple_mbox_chan_shutdown, }; -- cgit v1.2.3 From 68584e380ef54fb1e7d97710a0fdd7e31212fd65 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Wed, 14 Sep 2022 09:34:26 +0100 Subject: mailbox: apple: Implement poll_data() operation This allows clients running in atomic context to poll for messages to arrive. Signed-off-by: Hector Martin Signed-off-by: Russell King (Oracle) Signed-off-by: Jassi Brar --- drivers/mailbox/apple-mailbox.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mailbox/apple-mailbox.c b/drivers/mailbox/apple-mailbox.c index 33e7acf71e3e..2a3e8d8ff8b5 100644 --- a/drivers/mailbox/apple-mailbox.c +++ b/drivers/mailbox/apple-mailbox.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #define APPLE_ASC_MBOX_CONTROL_FULL BIT(16) @@ -101,6 +102,7 @@ struct apple_mbox { struct device *dev; struct mbox_controller controller; + spinlock_t rx_lock; }; static const struct of_device_id apple_mbox_of_match[]; @@ -204,13 +206,15 @@ static irqreturn_t apple_mbox_send_empty_irq(int irq, void *data) return IRQ_HANDLED; } -static irqreturn_t apple_mbox_recv_irq(int irq, void *data) +static int apple_mbox_poll(struct apple_mbox *apple_mbox) { - struct apple_mbox *apple_mbox = data; struct apple_mbox_msg msg; + int ret = 0; - while (apple_mbox_hw_recv(apple_mbox, &msg) == 0) + while (apple_mbox_hw_recv(apple_mbox, &msg) == 0) { mbox_chan_received_data(&apple_mbox->chan, (void *)&msg); + ret++; + } /* * The interrupt will keep firing even if there are no more messages @@ -225,9 +229,33 @@ static irqreturn_t apple_mbox_recv_irq(int irq, void *data) apple_mbox->regs + apple_mbox->hw->irq_ack); } + return ret; +} + +static irqreturn_t apple_mbox_recv_irq(int irq, void *data) +{ + struct apple_mbox *apple_mbox = data; + + spin_lock(&apple_mbox->rx_lock); + apple_mbox_poll(apple_mbox); + spin_unlock(&apple_mbox->rx_lock); + return IRQ_HANDLED; } +static bool apple_mbox_chan_peek_data(struct mbox_chan *chan) +{ + struct apple_mbox *apple_mbox = chan->con_priv; + unsigned long flags; + int ret; + + spin_lock_irqsave(&apple_mbox->rx_lock, flags); + ret = apple_mbox_poll(apple_mbox); + spin_unlock_irqrestore(&apple_mbox->rx_lock, flags); + + return ret > 0; +} + static int apple_mbox_chan_flush(struct mbox_chan *chan, unsigned long timeout) { struct apple_mbox *apple_mbox = chan->con_priv; @@ -276,6 +304,7 @@ static void apple_mbox_chan_shutdown(struct mbox_chan *chan) static const struct mbox_chan_ops apple_mbox_ops = { .send_data = apple_mbox_chan_send_data, + .peek_data = apple_mbox_chan_peek_data, .flush = apple_mbox_chan_flush, .startup = apple_mbox_chan_startup, .shutdown = apple_mbox_chan_shutdown, @@ -331,6 +360,7 @@ static int apple_mbox_probe(struct platform_device *pdev) mbox->controller.txdone_irq = true; mbox->controller.of_xlate = apple_mbox_of_xlate; mbox->chan.con_priv = mbox; + spin_lock_init(&mbox->rx_lock); irqname = devm_kasprintf(dev, GFP_KERNEL, "%s-recv", dev_name(dev)); if (!irqname) -- cgit v1.2.3 From 7e5cd064f73ccecd2ac1aadca078394bd25ea3ce Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 19 Sep 2022 11:01:36 +0800 Subject: mailbox: imx: fix RST channel support Because IMX_MU_xCR_MAX was increased to 5, some mu cfgs were not updated to include the CR register. Add the missed CR register to xcr array. Fixes: 82ab513baed5 ("mailbox: imx: support RST channel") Reported-by: Liu Ying Signed-off-by: Peng Fan Tested-by: Liu Ying # i.MX8qm/qxp MEK boards boot Signed-off-by: Jassi Brar --- drivers/mailbox/imx-mailbox.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c index 02922073c9ef..20f2ec880ad6 100644 --- a/drivers/mailbox/imx-mailbox.c +++ b/drivers/mailbox/imx-mailbox.c @@ -904,7 +904,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx7ulp = { .xTR = 0x20, .xRR = 0x40, .xSR = {0x60, 0x60, 0x60, 0x60}, - .xCR = {0x64, 0x64, 0x64, 0x64}, + .xCR = {0x64, 0x64, 0x64, 0x64, 0x64}, }; static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = { @@ -927,7 +927,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp_s4 = { .xTR = 0x200, .xRR = 0x280, .xSR = {0xC, 0x118, 0x124, 0x12C}, - .xCR = {0x110, 0x114, 0x120, 0x128}, + .xCR = {0x8, 0x110, 0x114, 0x120, 0x128}, }; static const struct imx_mu_dcfg imx_mu_cfg_imx93_s4 = { @@ -938,7 +938,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx93_s4 = { .xTR = 0x200, .xRR = 0x280, .xSR = {0xC, 0x118, 0x124, 0x12C}, - .xCR = {0x110, 0x114, 0x120, 0x128}, + .xCR = {0x8, 0x110, 0x114, 0x120, 0x128}, }; static const struct imx_mu_dcfg imx_mu_cfg_imx8_scu = { @@ -949,7 +949,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8_scu = { .xTR = 0x0, .xRR = 0x10, .xSR = {0x20, 0x20, 0x20, 0x20}, - .xCR = {0x24, 0x24, 0x24, 0x24}, + .xCR = {0x24, 0x24, 0x24, 0x24, 0x24}, }; static const struct imx_mu_dcfg imx_mu_cfg_imx8_seco = { @@ -960,7 +960,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8_seco = { .xTR = 0x0, .xRR = 0x10, .xSR = {0x20, 0x20, 0x20, 0x20}, - .xCR = {0x24, 0x24, 0x24, 0x24}, + .xCR = {0x24, 0x24, 0x24, 0x24, 0x24}, }; static const struct of_device_id imx_mu_dt_ids[] = { -- cgit v1.2.3 From 2e10289d1f304f5082a4dda55a677b72b3bdb581 Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Wed, 24 Aug 2022 08:08:11 +0100 Subject: mailbox: mpfs: fix handling of the reg property The "data" region of the PolarFire SoC's system controller mailbox is not one continuous register space - the system controller's QSPI sits between the control and data registers. Split the "data" reg into two parts: "data" & "control". Optionally get the "data" register address from the 3rd reg property in the devicetree & fall back to using the old base + MAILBOX_REG_OFFSET that the current code uses. Fixes: 83d7b1560810 ("mbox: add polarfire soc system controller mailbox") Signed-off-by: Conor Dooley Signed-off-by: Jassi Brar --- drivers/mailbox/mailbox-mpfs.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c index 4e34854d1238..e432a8f0d148 100644 --- a/drivers/mailbox/mailbox-mpfs.c +++ b/drivers/mailbox/mailbox-mpfs.c @@ -62,6 +62,7 @@ struct mpfs_mbox { struct mbox_controller controller; struct device *dev; int irq; + void __iomem *ctrl_base; void __iomem *mbox_base; void __iomem *int_reg; struct mbox_chan chans[1]; @@ -73,7 +74,7 @@ static bool mpfs_mbox_busy(struct mpfs_mbox *mbox) { u32 status; - status = readl_relaxed(mbox->mbox_base + SERVICES_SR_OFFSET); + status = readl_relaxed(mbox->ctrl_base + SERVICES_SR_OFFSET); return status & SCB_STATUS_BUSY_MASK; } @@ -99,14 +100,13 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data) for (index = 0; index < (msg->cmd_data_size / 4); index++) writel_relaxed(word_buf[index], - mbox->mbox_base + MAILBOX_REG_OFFSET + index * 0x4); + mbox->mbox_base + index * 0x4); if (extra_bits) { u8 i; u8 byte_off = ALIGN_DOWN(msg->cmd_data_size, 4); u8 *byte_buf = msg->cmd_data + byte_off; - val = readl_relaxed(mbox->mbox_base + - MAILBOX_REG_OFFSET + index * 0x4); + val = readl_relaxed(mbox->mbox_base + index * 0x4); for (i = 0u; i < extra_bits; i++) { val &= ~(0xffu << (i * 8u)); @@ -114,14 +114,14 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data) } writel_relaxed(val, - mbox->mbox_base + MAILBOX_REG_OFFSET + index * 0x4); + mbox->mbox_base + index * 0x4); } } opt_sel = ((msg->mbox_offset << 7u) | (msg->cmd_opcode & 0x7fu)); tx_trigger = (opt_sel << SCB_CTRL_POS) & SCB_CTRL_MASK; tx_trigger |= SCB_CTRL_REQ_MASK | SCB_STATUS_NOTIFY_MASK; - writel_relaxed(tx_trigger, mbox->mbox_base + SERVICES_CR_OFFSET); + writel_relaxed(tx_trigger, mbox->ctrl_base + SERVICES_CR_OFFSET); return 0; } @@ -141,7 +141,7 @@ static void mpfs_mbox_rx_data(struct mbox_chan *chan) if (!mpfs_mbox_busy(mbox)) { for (i = 0; i < num_words; i++) { response->resp_msg[i] = - readl_relaxed(mbox->mbox_base + MAILBOX_REG_OFFSET + readl_relaxed(mbox->mbox_base + mbox->resp_offset + i * 0x4); } } @@ -200,14 +200,18 @@ static int mpfs_mbox_probe(struct platform_device *pdev) if (!mbox) return -ENOMEM; - mbox->mbox_base = devm_platform_get_and_ioremap_resource(pdev, 0, ®s); - if (IS_ERR(mbox->mbox_base)) - return PTR_ERR(mbox->mbox_base); + mbox->ctrl_base = devm_platform_get_and_ioremap_resource(pdev, 0, ®s); + if (IS_ERR(mbox->ctrl_base)) + return PTR_ERR(mbox->ctrl_base); mbox->int_reg = devm_platform_get_and_ioremap_resource(pdev, 1, ®s); if (IS_ERR(mbox->int_reg)) return PTR_ERR(mbox->int_reg); + mbox->mbox_base = devm_platform_get_and_ioremap_resource(pdev, 2, ®s); + if (IS_ERR(mbox->mbox_base)) // account for the old dt-binding w/ 2 regs + mbox->mbox_base = mbox->ctrl_base + MAILBOX_REG_OFFSET; + mbox->irq = platform_get_irq(pdev, 0); if (mbox->irq < 0) return mbox->irq; -- cgit v1.2.3 From 0d1aadfe10ba17ebdeb96abb9638eb0f623f9b55 Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Wed, 24 Aug 2022 08:08:12 +0100 Subject: mailbox: mpfs: account for mbox offsets while sending The mailbox offset is not only used for receiving messages, but it is also used by messages sent to the system controller by Linux that have a payload, such as the "digital signature service". It is also overloaded by certain other services (reprogramming of the FPGA fabric, see Link:) to have a meaning other than the offset the system controller should read from. When the driver was written, no such services of the latter type were in use & those of the former used an offset of zero so this has gone un-noticed. Link: https://www.microsemi.com/document-portal/doc_download/1245815-polarfire-fpga-and-polarfire-soc-fpga-system-services-user-guide # Section 5.2 Fixes: 83d7b1560810 ("mbox: add polarfire soc system controller mailbox") Signed-off-by: Conor Dooley Signed-off-by: Jassi Brar --- drivers/mailbox/mailbox-mpfs.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c index e432a8f0d148..cfacb3f320a6 100644 --- a/drivers/mailbox/mailbox-mpfs.c +++ b/drivers/mailbox/mailbox-mpfs.c @@ -100,21 +100,20 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data) for (index = 0; index < (msg->cmd_data_size / 4); index++) writel_relaxed(word_buf[index], - mbox->mbox_base + index * 0x4); + mbox->mbox_base + msg->mbox_offset + index * 0x4); if (extra_bits) { u8 i; u8 byte_off = ALIGN_DOWN(msg->cmd_data_size, 4); u8 *byte_buf = msg->cmd_data + byte_off; - val = readl_relaxed(mbox->mbox_base + index * 0x4); + val = readl_relaxed(mbox->mbox_base + msg->mbox_offset + index * 0x4); for (i = 0u; i < extra_bits; i++) { val &= ~(0xffu << (i * 8u)); val |= (byte_buf[i] << (i * 8u)); } - writel_relaxed(val, - mbox->mbox_base + index * 0x4); + writel_relaxed(val, mbox->mbox_base + msg->mbox_offset + index * 0x4); } } -- cgit v1.2.3 From f5fe925df802eb3c7a71a97c01cf371eea24ea6a Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Fri, 19 Aug 2022 00:08:48 +0200 Subject: mailbox: qcom-apcs-ipc: add IPQ8074 APSS clock support IPQ8074 has the APSS clock controller utilizing the same register space as the APCS, so provide access to the APSS utilizing a child device like IPQ6018. IPQ6018 and IPQ8074 use the same controller and driver, so just utilize IPQ6018 match data for IPQ8074. Signed-off-by: Robert Marko Reviewed-by: Dmitry Baryshkov Signed-off-by: Jassi Brar --- drivers/mailbox/qcom-apcs-ipc-mailbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mailbox/qcom-apcs-ipc-mailbox.c b/drivers/mailbox/qcom-apcs-ipc-mailbox.c index 80a54d81412e..f1f0e87a79e6 100644 --- a/drivers/mailbox/qcom-apcs-ipc-mailbox.c +++ b/drivers/mailbox/qcom-apcs-ipc-mailbox.c @@ -142,7 +142,7 @@ static int qcom_apcs_ipc_remove(struct platform_device *pdev) /* .data is the offset of the ipc register within the global block */ static const struct of_device_id qcom_apcs_ipc_of_match[] = { { .compatible = "qcom,ipq6018-apcs-apps-global", .data = &ipq6018_apcs_data }, - { .compatible = "qcom,ipq8074-apcs-apps-global", .data = &msm8994_apcs_data }, + { .compatible = "qcom,ipq8074-apcs-apps-global", .data = &ipq6018_apcs_data }, { .compatible = "qcom,msm8916-apcs-kpss-global", .data = &msm8916_apcs_data }, { .compatible = "qcom,msm8939-apcs-kpss-global", .data = &msm8916_apcs_data }, { .compatible = "qcom,msm8953-apcs-kpss-global", .data = &msm8994_apcs_data }, -- cgit v1.2.3 From 6b207ce8a96a71e966831e3a13c38143ba9a73c1 Mon Sep 17 00:00:00 2001 From: Jack Wang Date: Fri, 26 Aug 2022 12:13:35 +0200 Subject: mailbox: bcm-ferxrm-mailbox: Fix error check for dma_map_sg dma_map_sg return 0 on error, fix the error check, and return -EIO to caller. Fixes: dbc049eee730 ("mailbox: Add driver for Broadcom FlexRM ring manager") Signed-off-by: Jack Wang Signed-off-by: Jassi Brar --- drivers/mailbox/bcm-flexrm-mailbox.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mailbox/bcm-flexrm-mailbox.c b/drivers/mailbox/bcm-flexrm-mailbox.c index fda16f76401e..bf6e86b0ed09 100644 --- a/drivers/mailbox/bcm-flexrm-mailbox.c +++ b/drivers/mailbox/bcm-flexrm-mailbox.c @@ -622,15 +622,15 @@ static int flexrm_spu_dma_map(struct device *dev, struct brcm_message *msg) rc = dma_map_sg(dev, msg->spu.src, sg_nents(msg->spu.src), DMA_TO_DEVICE); - if (rc < 0) - return rc; + if (!rc) + return -EIO; rc = dma_map_sg(dev, msg->spu.dst, sg_nents(msg->spu.dst), DMA_FROM_DEVICE); - if (rc < 0) { + if (!rc) { dma_unmap_sg(dev, msg->spu.src, sg_nents(msg->spu.src), DMA_TO_DEVICE); - return rc; + return -EIO; } return 0; -- cgit v1.2.3 From 8ac1111055afc863c78e389b051d843babbf2ca9 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 28 Sep 2022 22:22:57 +0100 Subject: mailbox: pcc: Fix spelling mistake "Plaform" -> "Platform" There is a spelling mistake in a pr_err message. Fix it. Signed-off-by: Colin Ian King Signed-off-by: Jassi Brar --- drivers/mailbox/pcc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index ebfa33a40fce..3c2bc0ca454c 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c @@ -676,7 +676,7 @@ static int pcc_mbox_probe(struct platform_device *pdev) if (pcct_entry->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE && !pcc_mbox_ctrl->txdone_irq) { - pr_err("Plaform Interrupt flag must be set to 1"); + pr_err("Platform Interrupt flag must be set to 1"); rc = -EINVAL; goto err; } -- cgit v1.2.3 From b8ae88e1e75e5cb7a6df5298ab75334362ed631c Mon Sep 17 00:00:00 2001 From: Eric Chanudet Date: Mon, 3 Oct 2022 13:08:49 -0400 Subject: mailbox: qcom-ipcc: flag IRQ NO_THREAD PREEMPT_RT forces qcom-ipcc's handler to be threaded with interrupts enabled, which triggers a warning in __handle_irq_event_percpu(): irq 173 handler irq_default_primary_handler+0x0/0x10 enabled interrupts WARNING: CPU: 0 PID: 77 at kernel/irq/handle.c:161 __handle_irq_event_percpu+0x4c4/0x4d0 Mark it IRQF_NO_THREAD to avoid running the handler in a threaded context with threadirqs or PREEMPT_RT enabled. Signed-off-by: Eric Chanudet Acked-by: Sebastian Andrzej Siewior Signed-off-by: Jassi Brar --- drivers/mailbox/qcom-ipcc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mailbox/qcom-ipcc.c b/drivers/mailbox/qcom-ipcc.c index 31d58b7d55fe..7e27acf6c0cc 100644 --- a/drivers/mailbox/qcom-ipcc.c +++ b/drivers/mailbox/qcom-ipcc.c @@ -308,7 +308,8 @@ static int qcom_ipcc_probe(struct platform_device *pdev) goto err_mbox; ret = devm_request_irq(&pdev->dev, ipcc->irq, qcom_ipcc_irq_fn, - IRQF_TRIGGER_HIGH | IRQF_NO_SUSPEND, name, ipcc); + IRQF_TRIGGER_HIGH | IRQF_NO_SUSPEND | + IRQF_NO_THREAD, name, ipcc); if (ret < 0) { dev_err(&pdev->dev, "Failed to register the irq: %d\n", ret); goto err_req_irq; -- cgit v1.2.3