Merge tag 'mailbox-v6.20' of git://git.kernel.org/pub/scm/linux/kernel/git/jassibrar/mailbox
Merge commit. Changes below are compared with the first parent: dd530598.
Changes
22 files changed · +434 −208
Only the first 600 diff lines are shown. Download the complete patch.
Documentation/devicetree/bindings/mailbox/mediatek,mt8196-vcp-mbox.yaml
View filediff --git a/Documentation/devicetree/bindings/mailbox/mediatek,mt8196-vcp-mbox.yaml b/Documentation/devicetree/bindings/mailbox/mediatek,mt8196-vcp-mbox.yaml
new file mode 100644
index 0000000..7b1c516
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/mediatek,mt8196-vcp-mbox.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/mediatek,mt8196-vcp-mbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek Video Companion Processor (VCP) mailbox
+
+maintainers:
+ - Jjian Zhou <[email protected]>
+
+description:
+ The MTK VCP mailbox enables the SoC to communicate with the VCP by passing
+ messages through 64 32-bit wide registers. It has 32 interrupt vectors in
+ either direction for signalling purposes.
+
+properties:
+ compatible:
+ enum:
+ - mediatek,mt8196-vcp-mbox
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ "#mbox-cells":
+ const: 0
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - "#mbox-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ mailbox@31b80000 {
+ compatible = "mediatek,mt8196-vcp-mbox";
+ reg = <0x31b80000 0x1000>;
+ interrupts = <GIC_SPI 789 IRQ_TYPE_LEVEL_HIGH 0>;
+ #mbox-cells = <0>;
+ };
Documentation/devicetree/bindings/mailbox/microchip,mpfs-mailbox.yaml
View filediff --git a/Documentation/devicetree/bindings/mailbox/microchip,mpfs-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/microchip,mpfs-mailbox.yaml
index 1332aab..5f2ec74 100644
--- a/Documentation/devicetree/bindings/mailbox/microchip,mpfs-mailbox.yaml
+++ b/Documentation/devicetree/bindings/mailbox/microchip,mpfs-mailbox.yaml
@@ -11,7 +11,11 @@ maintainers:
properties:
compatible:
- const: microchip,mpfs-mailbox
+ oneOf:
+ - items:
+ - const: microchip,pic64gx-mailbox
+ - const: microchip,mpfs-mailbox
+ - const: microchip,mpfs-mailbox
reg:
oneOf:
Documentation/devicetree/bindings/mailbox/sprd-mailbox.yaml
View filediff --git a/Documentation/devicetree/bindings/mailbox/sprd-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/sprd-mailbox.yaml
index b526f9c..bf6ab4e 100644
--- a/Documentation/devicetree/bindings/mailbox/sprd-mailbox.yaml
+++ b/Documentation/devicetree/bindings/mailbox/sprd-mailbox.yaml
@@ -16,6 +16,7 @@ properties:
enum:
- sprd,sc9860-mailbox
- sprd,sc9863a-mailbox
+ - sprd,ums9230-mailbox
reg:
items:
Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.yaml
View filediff --git a/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.yaml
index 04d6473..a5205ee 100644
--- a/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.yaml
+++ b/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.yaml
@@ -11,6 +11,17 @@ description: |
messaging between two Xilinx Zynq UltraScale+ MPSoC IPI agents. Each IPI
agent owns registers used for notification and buffers for message.
+ For Versal devices, there are two types of IPI channels:
+ - Buffered channels: Support message passing and require the "msg"
+ register region to be present on both the host and remote IPI agents.
+ - Buffer-less channels: Support notification only and do not require the
+ "msg" register region. For these channels, the "msg" region should be
+ omitted.
+
+ For message passing, both the host and remote IPI agents must define the "msg"
+ register region. If either agent omits the "msg" region, only notification
+ based communication is possible.
+
+-------------------------------------+
| Xilinx ZynqMP IPI Controller |
+-------------------------------------+
drivers/mailbox/Kconfig
View filediff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 29f16f2..5bf4155 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -199,7 +199,7 @@ config POLARFIRE_SOC_MAILBOX
tristate "PolarFire SoC (MPFS) Mailbox"
depends on HAS_IOMEM
depends on MFD_SYSCON
- depends on ARCH_MICROCHIP_POLARFIRE || COMPILE_TEST
+ depends on ARCH_MICROCHIP || COMPILE_TEST
help
This driver adds support for the PolarFire SoC (MPFS) mailbox controller.
@@ -279,7 +279,7 @@ config MTK_ADSP_MBOX
tristate "MediaTek ADSP Mailbox Controller"
depends on ARCH_MEDIATEK || COMPILE_TEST
help
- Say yes here to add support for "MediaTek ADSP Mailbox Controller.
+ Say yes here to add support for MediaTek ADSP Mailbox Controller.
This mailbox driver is used to send notification or short message
between processors with ADSP. It will place the message to share
buffer and will access the ipc control.
@@ -304,6 +304,15 @@ config MTK_GPUEB_MBOX
Say Y or m here if you want to support the MT8196 SoC in your kernel
build.
+config MTK_VCP_MBOX
+ tristate "MediaTek VCP Mailbox Support"
+ depends on ARCH_MEDIATEK || COMPILE_TEST
+ help
+ Say yes here to add support for the MediaTek VCP mailbox driver.
+ The mailbox implementation provides access from the application
+ processor to Video Companion Processor Unit.
+ If unsure say N.
+
config ZYNQMP_IPI_MBOX
tristate "Xilinx ZynqMP IPI Mailbox"
depends on ARCH_ZYNQMP && OF
@@ -387,7 +396,7 @@ config RISCV_SBI_MPXY_MBOX
Mailbox driver implementation for RISC-V SBI Message Proxy (MPXY)
extension. This mailbox driver is used to send messages to the
remote processor through the SBI implementation (M-mode firmware
- or HS-mode hypervisor). Say Y here if you want to have this support.
- If unsure say N.
+ or HS-mode hypervisor). Say Y here, unless you are sure you do not
+ need this.
endif
drivers/mailbox/Makefile
View filediff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 81820a4..944d8ea 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -65,6 +65,8 @@ obj-$(CONFIG_MTK_CMDQ_MBOX) += mtk-cmdq-mailbox.o
obj-$(CONFIG_MTK_GPUEB_MBOX) += mtk-gpueb-mailbox.o
+obj-$(CONFIG_MTK_VCP_MBOX) += mtk-vcp-mailbox.o
+
obj-$(CONFIG_ZYNQMP_IPI_MBOX) += zynqmp-ipi-mailbox.o
obj-$(CONFIG_SUN6I_MSGBOX) += sun6i-msgbox.o
drivers/mailbox/arm_mhuv3.c
View filediff --git a/drivers/mailbox/arm_mhuv3.c b/drivers/mailbox/arm_mhuv3.c
index 0910da6..a1c528b 100644
--- a/drivers/mailbox/arm_mhuv3.c
+++ b/drivers/mailbox/arm_mhuv3.c
@@ -333,7 +333,7 @@ struct mhuv3_extension {
* @rev: MHUv3 controller IIDR revision.
* @var: MHUv3 controller IIDR variant.
* @prod_id: MHUv3 controller IIDR product_id.
- * @num_chans: The total number of channnels discovered across all extensions.
+ * @num_chans: The total number of channels discovered across all extensions.
* @cmb_irq: Combined IRQ number if any found defined.
* @ctrl: A reference to the MHUv3 control page for this block.
* @pbx: Base address of the PBX register mapping region.
drivers/mailbox/bcm-flexrm-mailbox.c
View filediff --git a/drivers/mailbox/bcm-flexrm-mailbox.c b/drivers/mailbox/bcm-flexrm-mailbox.c
index 4255fef..04c47ea 100644
--- a/drivers/mailbox/bcm-flexrm-mailbox.c
+++ b/drivers/mailbox/bcm-flexrm-mailbox.c
@@ -26,7 +26,6 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mailbox_controller.h>
-#include <linux/mailbox_client.h>
#include <linux/mailbox/brcm-message.h>
#include <linux/module.h>
#include <linux/msi.h>
drivers/mailbox/cix-mailbox.c
View filediff --git a/drivers/mailbox/cix-mailbox.c b/drivers/mailbox/cix-mailbox.c
index 5bb1416..443620e 100644
--- a/drivers/mailbox/cix-mailbox.c
+++ b/drivers/mailbox/cix-mailbox.c
@@ -346,7 +346,7 @@ static void cix_mbox_isr_fifo(struct mbox_chan *chan)
/* FIFO overflow is generated */
if (int_status & CIX_FIFO_OFLOW_INT) {
status = cix_mbox_read(priv, CIX_FIFO_STAS);
- dev_err(priv->dev, "fifo overlow: int_stats %d\n", status);
+ dev_err(priv->dev, "fifo overflow: int_stats %d\n", status);
cix_mbox_write(priv, CIX_FIFO_OFLOW_INT, CIX_INT_CLEAR);
}
}
drivers/mailbox/cv1800-mailbox.c
View filediff --git a/drivers/mailbox/cv1800-mailbox.c b/drivers/mailbox/cv1800-mailbox.c
index 4761191..4bca9d8 100644
--- a/drivers/mailbox/cv1800-mailbox.c
+++ b/drivers/mailbox/cv1800-mailbox.c
@@ -11,7 +11,6 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kfifo.h>
-#include <linux/mailbox_client.h>
#include <linux/mailbox_controller.h>
#include <linux/module.h>
#include <linux/platform_device.h>
drivers/mailbox/exynos-mailbox.c
View filediff --git a/drivers/mailbox/exynos-mailbox.c b/drivers/mailbox/exynos-mailbox.c
index 2320649..5f2d3b8 100644
--- a/drivers/mailbox/exynos-mailbox.c
+++ b/drivers/mailbox/exynos-mailbox.c
@@ -35,12 +35,10 @@
* struct exynos_mbox - driver's private data.
* @regs: mailbox registers base address.
* @mbox: pointer to the mailbox controller.
- * @pclk: pointer to the mailbox peripheral clock.
*/
struct exynos_mbox {
void __iomem *regs;
struct mbox_controller *mbox;
- struct clk *pclk;
};
static int exynos_mbox_send_data(struct mbox_chan *chan, void *data)
@@ -100,6 +98,7 @@ static int exynos_mbox_probe(struct platform_device *pdev)
struct exynos_mbox *exynos_mbox;
struct mbox_controller *mbox;
struct mbox_chan *chans;
+ struct clk *pclk;
int i;
exynos_mbox = devm_kzalloc(dev, sizeof(*exynos_mbox), GFP_KERNEL);
@@ -119,9 +118,9 @@ static int exynos_mbox_probe(struct platform_device *pdev)
if (IS_ERR(exynos_mbox->regs))
return PTR_ERR(exynos_mbox->regs);
- exynos_mbox->pclk = devm_clk_get_enabled(dev, "pclk");
- if (IS_ERR(exynos_mbox->pclk))
- return dev_err_probe(dev, PTR_ERR(exynos_mbox->pclk),
+ pclk = devm_clk_get_enabled(dev, "pclk");
+ if (IS_ERR(pclk))
+ return dev_err_probe(dev, PTR_ERR(pclk),
"Failed to enable clock.\n");
mbox->num_chans = EXYNOS_MBOX_CHAN_COUNT;
drivers/mailbox/imx-mailbox.c
View filediff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index 6778afc..003f923 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -122,6 +122,7 @@ struct imx_mu_dcfg {
u32 xRR; /* Receive Register0 */
u32 xSR[IMX_MU_xSR_MAX]; /* Status Registers */
u32 xCR[IMX_MU_xCR_MAX]; /* Control Registers */
+ bool skip_suspend_flag;
};
#define IMX_MU_xSR_GIPn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(28 + (3 - (x))))
@@ -988,6 +989,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx7ulp = {
.xRR = 0x40,
.xSR = {0x60, 0x60, 0x60, 0x60},
.xCR = {0x64, 0x64, 0x64, 0x64, 0x64},
+ .skip_suspend_flag = true,
};
static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = {
@@ -1071,7 +1073,8 @@ static int __maybe_unused imx_mu_suspend_noirq(struct device *dev)
priv->xcr[i] = imx_mu_read(priv, priv->dcfg->xCR[i]);
}
- priv->suspend = true;
+ if (!priv->dcfg->skip_suspend_flag)
+ priv->suspend = true;
return 0;
}
@@ -1094,7 +1097,8 @@ static int __maybe_unused imx_mu_resume_noirq(struct device *dev)
imx_mu_write(priv, priv->xcr[i], priv->dcfg->xCR[i]);
}
- priv->suspend = false;
+ if (!priv->dcfg->skip_suspend_flag)
+ priv->suspend = false;
return 0;
}
drivers/mailbox/mailbox-mchp-ipc-sbi.c
View filediff --git a/drivers/mailbox/mailbox-mchp-ipc-sbi.c b/drivers/mailbox/mailbox-mchp-ipc-sbi.c
index a6e5200..b87bf2f 100644
--- a/drivers/mailbox/mailbox-mchp-ipc-sbi.c
+++ b/drivers/mailbox/mailbox-mchp-ipc-sbi.c
@@ -174,26 +174,30 @@ static irqreturn_t mchp_ipc_cluster_aggr_isr(int irq, void *data)
struct mchp_ipc_msg ipc_msg;
struct mchp_ipc_status status_msg;
int ret;
- unsigned long hartid;
u32 i, chan_index, chan_id;
+ bool found = false;
/* Find out the hart that originated the irq */
for_each_online_cpu(i) {
- hartid = cpuid_to_hartid_map(i);
- if (irq == ipc->cluster_cfg[hartid].irq)
+ if (irq == ipc->cluster_cfg[i].irq) {
+ found = true;
break;
+ }
}
- status_msg.cluster = hartid;
- memcpy(ipc->cluster_cfg[hartid].buf_base, &status_msg, sizeof(struct mchp_ipc_status));
+ if (unlikely(!found))
+ return IRQ_NONE;
- ret = mchp_ipc_sbi_send(SBI_EXT_IPC_STATUS, ipc->cluster_cfg[hartid].buf_base_addr);
+ status_msg.cluster = cpuid_to_hartid_map(i);
+ memcpy(ipc->cluster_cfg[i].buf_base, &status_msg, sizeof(struct mchp_ipc_status));
+
+ ret = mchp_ipc_sbi_send(SBI_EXT_IPC_STATUS, ipc->cluster_cfg[i].buf_base_addr);
if (ret < 0) {
dev_err_ratelimited(ipc->dev, "could not get IHC irq status ret=%d\n", ret);
return IRQ_HANDLED;
}
- memcpy(&status_msg, ipc->cluster_cfg[hartid].buf_base, sizeof(struct mchp_ipc_status));
+ memcpy(&status_msg, ipc->cluster_cfg[i].buf_base, sizeof(struct mchp_ipc_status));
/*
* Iterate over each bit set in the IHC interrupt status register (IRQ_STATUS) to identify
@@ -321,13 +325,6 @@ static int mchp_ipc_startup(struct mbox_chan *chan)
goto fail_free_buf_msg_rx;
}
- if (ret) {
- dev_err(ipc->dev, "failed to register interrupt(s)\n");
- goto fail_free_buf_msg_rx;
- }
-
- return ret;
-
fail_free_buf_msg_rx:
kfree(chan_info->msg_buf_rx);
fail_free_buf_msg_tx:
@@ -385,21 +382,21 @@ static int mchp_ipc_get_cluster_aggr_irq(struct mchp_ipc_sbi_mbox *ipc)
if (ret <= 0)
continue;
- ipc->cluster_cfg[hartid].irq = ret;
- ret = devm_request_irq(ipc->dev, ipc->cluster_cfg[hartid].irq,
+ ipc->cluster_cfg[cpuid].irq = ret;
+ ret = devm_request_irq(ipc->dev, ipc->cluster_cfg[cpuid].irq,
mchp_ipc_cluster_aggr_isr, IRQF_SHARED,
"miv-ihc-irq", ipc);
if (ret)
return ret;
- ipc->cluster_cfg[hartid].buf_base = devm_kmalloc(ipc->dev,
- sizeof(struct mchp_ipc_status),
- GFP_KERNEL);
+ ipc->cluster_cfg[cpuid].buf_base = devm_kmalloc(ipc->dev,
+ sizeof(struct mchp_ipc_status),
+ GFP_KERNEL);
- if (!ipc->cluster_cfg[hartid].buf_base)
+ if (!ipc->cluster_cfg[cpuid].buf_base)
return -ENOMEM;
- ipc->cluster_cfg[hartid].buf_base_addr = __pa(ipc->cluster_cfg[hartid].buf_base);
+ ipc->cluster_cfg[cpuid].buf_base_addr = __pa(ipc->cluster_cfg[cpuid].buf_base);
irq_found = true;
}
@@ -419,7 +416,7 @@ static int mchp_ipc_probe(struct platform_device *pdev)
ret = sbi_probe_extension(SBI_EXT_MICROCHIP_TECHNOLOGY);
if (ret <= 0)
- return dev_err_probe(dev, ret, "Microchip SBI extension not detected\n");
+ return dev_err_probe(dev, -ENODEV, "Microchip SBI extension not detected\n");
ipc = devm_kzalloc(dev, sizeof(*ipc), GFP_KERNEL);
if (!ipc)
drivers/mailbox/mailbox.c
View filediff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index 2acc6ec..617ba50 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -489,12 +489,10 @@ EXPORT_SYMBOL_GPL(mbox_free_channel);
static struct mbox_chan *fw_mbox_index_xlate(struct mbox_controller *mbox,
const struct fwnode_reference_args *sp)
{
- int ind = sp->args[0];
-
- if (ind >= mbox->num_chans)
+ if (sp->nargs < 1 || sp->args[0] >= mbox->num_chans)
return ERR_PTR(-EINVAL);
- return &mbox->chans[ind];
+ return &mbox->chans[sp->args[0]];
}
/**
drivers/mailbox/mtk-cmdq-mailbox.c
View filediff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 1bf6984..9da16b3 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -636,7 +636,7 @@ static struct mbox_chan *cmdq_xlate(struct mbox_controller *mbox,
static int cmdq_get_clocks(struct device *dev, struct cmdq *cmdq)
{
static const char * const gce_name = "gce";
- struct device_node *node, *parent = dev->of_node->parent;
+ struct device_node *parent = dev->of_node->parent;
struct clk_bulk_data *clks;
cmdq->clocks = devm_kcalloc(dev, cmdq->pdata->gce_num,
@@ -661,7 +661,7 @@ static int cmdq_get_clocks(struct device *dev, struct cmdq *cmdq)
* as the clock of the main GCE must be enabled for additional IPs
* to be reachable.
*/
- for_each_child_of_node(parent, node) {
+ for_each_child_of_node_scoped(parent, node) {
int alias_id = of_alias_get_id(node, gce_name);
if (alias_id < 0 || alias_id >= cmdq->pdata->gce_num)
@@ -670,17 +670,13 @@ static int cmdq_get_clocks(struct device *dev, struct cmdq *cmdq)
clks = &cmdq->clocks[alias_id];
clks->id = devm_kasprintf(dev, GFP_KERNEL, "gce%d", alias_id);
- if (!clks->id) {
- of_node_put(node);
+ if (!clks->id)
return -ENOMEM;
- }
clks->clk = of_clk_get(node, 0);
- if (IS_ERR(clks->clk)) {
- of_node_put(node);
+ if (IS_ERR(clks->clk))
return dev_err_probe(dev, PTR_ERR(clks->clk),
"failed to get gce%d clock\n", alias_id);
- }
}
return 0;
drivers/mailbox/mtk-vcp-mailbox.c
View filediff --git a/drivers/mailbox/mtk-vcp-mailbox.c b/drivers/mailbox/mtk-vcp-mailbox.c
new file mode 100644
index 0000000..cedad57
--- /dev/null
+++ b/drivers/mailbox/mtk-vcp-mailbox.c
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025 MediaTek Corporation. All rights reserved.
+ * Author: Jjian Zhou <[email protected]>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox/mtk-vcp-mailbox.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+struct mtk_vcp_mbox {
+ struct mbox_controller mbox;
+ void __iomem *base;
+ struct device *dev;
+ const struct mtk_vcp_mbox_cfg *cfg;
+ struct mtk_ipi_info ipi_recv;
+ struct mbox_chan chans;
+};
+
+struct mtk_vcp_mbox_cfg {
+ u16 set_in;
+ u16 clr_out;
+};
+
+static irqreturn_t mtk_vcp_mbox_irq_thread(int irq, void *data)
+{
+ struct mtk_vcp_mbox *priv = data;
+
+ /* get irq status */
+ priv->ipi_recv.irq_status = readl(priv->base + priv->cfg->clr_out);
+
+ __ioread32_copy(priv->ipi_recv.msg, priv->base,
+ MTK_VCP_MBOX_SLOT_MAX_SIZE / 4);
+
+ mbox_chan_received_data(&priv->chans, &priv->ipi_recv);
+
+ /* clear irq status */
+ writel(priv->ipi_recv.irq_status, priv->base + priv->cfg->clr_out);
+
+ return IRQ_HANDLED;
+}
+
+static struct mbox_chan *mtk_vcp_mbox_xlate(struct mbox_controller *mbox,
+ const struct of_phandle_args *sp)
+{
+ if (sp->args_count)
+ return NULL;
+
+ return &mbox->chans[0];
+}
+
+static int mtk_vcp_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+ struct mtk_vcp_mbox *priv = chan->con_priv;
+ struct mtk_ipi_info *ipi_info = data;
+ u32 status;
+
+ if (!ipi_info->msg) {
+ dev_err(priv->dev, "msg buffer is NULL.\n");
+ return -EINVAL;
+ }
+
+ status = readl(priv->base + priv->cfg->set_in);
+ if (status & BIT(ipi_info->index)) {
+ dev_warn(priv->dev, "mailbox IPI %d is busy.\n", ipi_info->id);
+ return -EBUSY;
+ }
+
+ if (ipi_info->slot_ofs + ipi_info->len > MTK_VCP_MBOX_SLOT_MAX_SIZE)
+ return -EINVAL;
+ __iowrite32_copy(priv->base + ipi_info->slot_ofs, ipi_info->msg,
+ ipi_info->len);
+
+ writel(BIT(ipi_info->index), priv->base + priv->cfg->set_in);
+
+ return 0;
+}
+
+static bool mtk_vcp_mbox_last_tx_done(struct mbox_chan *chan)
+{
+ struct mtk_ipi_info *ipi_info = chan->active_req;
+ struct mtk_vcp_mbox *priv = chan->con_priv;
+
+ return !(readl(priv->base + priv->cfg->set_in) & BIT(ipi_info->index));
+}
+
+static const struct mbox_chan_ops mtk_vcp_mbox_chan_ops = {
+ .send_data = mtk_vcp_mbox_send_data,
+ .last_tx_done = mtk_vcp_mbox_last_tx_done,
+};
+
+static int mtk_vcp_mbox_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mtk_vcp_mbox *priv;
+ struct mbox_controller *mbox;
+ int ret, irq;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = dev;
+ priv->chans.con_priv = priv;
+ mbox = &priv->mbox;
+ mbox->dev = dev;
+ mbox->ops = &mtk_vcp_mbox_chan_ops;
+ mbox->txdone_irq = false;
+ mbox->txdone_poll = true;
+ mbox->of_xlate = mtk_vcp_mbox_xlate;
+ mbox->num_chans = 1;
+ mbox->chans = &priv->chans;
+
+ priv->ipi_recv.msg = devm_kzalloc(dev, MTK_VCP_MBOX_SLOT_MAX_SIZE,
+ GFP_KERNEL);
+ if (!priv->ipi_recv.msg)
+ return -ENOMEM;
+
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
+
+ priv->cfg = of_device_get_match_data(dev);
+ if (!priv->cfg)
+ return -EINVAL;
+
+ platform_set_drvdata(pdev, priv);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
+ ret = devm_request_threaded_irq(dev, irq, NULL,
+ mtk_vcp_mbox_irq_thread, IRQF_ONESHOT,
+ dev_name(dev), priv);
+ if (ret < 0)
+ return ret;
+
This diff is incomplete. Download the complete patch.
drivers/mailbox/omap-mailbox.c
View fileThis diff is incomplete. Download the complete patch.
drivers/mailbox/pcc.c
View fileThis diff is incomplete. Download the complete patch.
drivers/mailbox/sprd-mailbox.c
View fileThis diff is incomplete. Download the complete patch.
drivers/mailbox/zynqmp-ipi-mailbox.c
View fileThis diff is incomplete. Download the complete patch.
include/acpi/pcc.h
View fileThis diff is incomplete. Download the complete patch.
include/linux/mailbox/mtk-vcp-mailbox.h
View fileThis diff is incomplete. Download the complete patch.