diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-10-08 10:30:44 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-10-08 10:30:44 -0700 |
commit | a6afa4199d3d038fbfdff5511f7523b0e30cb774 (patch) | |
tree | b093a529f5e9c0de573d1e1f6418c421e031baf8 /drivers | |
parent | bdc753c7fcb4eb009ae246a188ea7ac6dac98ce1 (diff) | |
parent | b8ae88e1e75e5cb7a6df5298ab75334362ed631c (diff) |
Merge tag 'mailbox-v6.1' of git://git.linaro.org/landing-teams/working/fujitsu/integration
Pull mailbox updates from Jassi Brar:
- apple: implement poll and flush callbacks
- qcom: fix clocks for IPQ6018 and IPQ8074 irq handler as not-a-thread
- microchip: split reg-space into two
- imx: RST channel fix
- bcm: fix dma_map_sg error handling
- misc: spelling fix in pcc driver
* tag 'mailbox-v6.1' of git://git.linaro.org/landing-teams/working/fujitsu/integration:
mailbox: qcom-ipcc: flag IRQ NO_THREAD
mailbox: pcc: Fix spelling mistake "Plaform" -> "Platform"
mailbox: bcm-ferxrm-mailbox: Fix error check for dma_map_sg
mailbox: qcom-apcs-ipc: add IPQ8074 APSS clock support
dt-bindings: mailbox: qcom: correct clocks for IPQ6018 and IPQ8074
dt-bindings: mailbox: qcom: set correct #clock-cells
mailbox: mpfs: account for mbox offsets while sending
mailbox: mpfs: fix handling of the reg property
dt-bindings: mailbox: fix the mpfs' reg property
mailbox: imx: fix RST channel support
mailbox: apple: Implement poll_data() operation
mailbox: apple: Implement flush() operation
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mailbox/apple-mailbox.c | 63 | ||||
-rw-r--r-- | drivers/mailbox/bcm-flexrm-mailbox.c | 8 | ||||
-rw-r--r-- | drivers/mailbox/imx-mailbox.c | 10 | ||||
-rw-r--r-- | drivers/mailbox/mailbox-mpfs.c | 25 | ||||
-rw-r--r-- | drivers/mailbox/pcc.c | 2 | ||||
-rw-r--r-- | drivers/mailbox/qcom-apcs-ipc-mailbox.c | 2 | ||||
-rw-r--r-- | drivers/mailbox/qcom-ipcc.c | 3 |
7 files changed, 87 insertions, 26 deletions
diff --git a/drivers/mailbox/apple-mailbox.c b/drivers/mailbox/apple-mailbox.c index 496c4951ccb1..2a3e8d8ff8b5 100644 --- a/drivers/mailbox/apple-mailbox.c +++ b/drivers/mailbox/apple-mailbox.c @@ -17,6 +17,7 @@ */ #include <linux/apple-mailbox.h> +#include <linux/delay.h> #include <linux/device.h> #include <linux/gfp.h> #include <linux/interrupt.h> @@ -25,6 +26,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/spinlock.h> #include <linux/types.h> #define APPLE_ASC_MBOX_CONTROL_FULL BIT(16) @@ -100,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[]; @@ -112,6 +115,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) { @@ -195,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 @@ -216,9 +229,50 @@ 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; + 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 +304,8 @@ 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, }; @@ -304,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) 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; 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[] = { diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c index 4e34854d1238..cfacb3f320a6 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,29 +100,27 @@ 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 + 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 + - MAILBOX_REG_OFFSET + 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 + MAILBOX_REG_OFFSET + index * 0x4); + writel_relaxed(val, mbox->mbox_base + msg->mbox_offset + 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 +140,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 +199,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; 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; } 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 }, 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; |