Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'mailbox-v6.20' of git://git.kernel.org/pub/scm/linux/kernel/git/jassibrar/mailbox

Pull mailbox updates from Jassi Brar:
"Platform and core updates

PCC:
- Updates to transmission and interrupt handling, including dynamic
txdone configuration, ->last_tx_done() wiring, and SHMEM
initialization fixes. Reverted previous shared buffer patch

MediaTek
- Introduce mtk-vcp-mailbox driver and bindings for MT8196 VCP
- Expand mtk-cmdq for MT8196 with GCE virtualization, mminfra_offset,
and instruction generation data

Spreadtrum (SPRD)
- Add Mailbox Revision 2 support and UMS9230 bindings
- Fix unhandled interrupt masking and TX done delivery flags

Microchip
- Add pic64gx compatibility to MPFS
- Fix out-of-bounds access and smatch warnings in mchp-ipc-sbi

Core & Misc Platform Updates
- Prevent out-of-bounds access in fw_mbox_index_xlate()
- Add bindings for Qualcomm CPUCP (Kaanapali)
- Simplify mtk-cmdq and zynqmp-ipi with scoped OF child iterators
- Consolidate various minor fixes, dead code removal, and typo
corrections across Broadcom, NXP, Samsung, Xilinx, ARM, and core
headers"

* tag 'mailbox-v6.20' of git://git.kernel.org/pub/scm/linux/kernel/git/jassibrar/mailbox: (34 commits)
mailbox: sprd: mask interrupts that are not handled
mailbox: sprd: add support for mailbox revision 2
mailbox: sprd: clear delivery flag before handling TX done
dt-bindings: mailbox: sprd: add compatible for UMS9230
mailbox: bcm-ferxrm-mailbox: Use default primary handler
mailbox: Remove mailbox_client.h from controller drivers
mailbox: zynqmp-ipi: Simplify with scoped for each OF child loop
mailbox: mtk-cmdq: Simplify with scoped for each OF child loop
dt-bindings: mailbox: xlnx,zynqmp-ipi-mailbox: Document msg region requirement
mailbox: Improve RISCV_SBI_MPXY_MBOX guidance
mailbox: mchp-ipc-sbi: fix uninitialized symbol and other smatch warnings
mailbox: arm_mhuv3: fix typo in comment
mailbox: cix: fix typo in error message
mailbox: imx: Skip the suspend flag for i.MX7ULP
mailbox: exynos: drop unneeded runtime pointer (pclk)
mailbox: pcc: Remove spurious IRQF_ONESHOT usage
mailbox: mtk-cmdq: Add driver data to support for MT8196
mailbox: mtk-cmdq: Add mminfra_offset configuration for DRAM transaction
mailbox: mtk-cmdq: Add GCE hardware virtualization configuration
mailbox: mtk-cmdq: Add cmdq private data to cmdq_pkt for generating instruction
...

+434 -208
+49
Documentation/devicetree/bindings/mailbox/mediatek,mt8196-vcp-mbox.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mailbox/mediatek,mt8196-vcp-mbox.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: MediaTek Video Companion Processor (VCP) mailbox 8 + 9 + maintainers: 10 + - Jjian Zhou <Jjian.Zhou@mediatek.com> 11 + 12 + description: 13 + The MTK VCP mailbox enables the SoC to communicate with the VCP by passing 14 + messages through 64 32-bit wide registers. It has 32 interrupt vectors in 15 + either direction for signalling purposes. 16 + 17 + properties: 18 + compatible: 19 + enum: 20 + - mediatek,mt8196-vcp-mbox 21 + 22 + reg: 23 + maxItems: 1 24 + 25 + interrupts: 26 + maxItems: 1 27 + 28 + "#mbox-cells": 29 + const: 0 30 + 31 + required: 32 + - compatible 33 + - reg 34 + - interrupts 35 + - "#mbox-cells" 36 + 37 + additionalProperties: false 38 + 39 + examples: 40 + - | 41 + #include <dt-bindings/interrupt-controller/arm-gic.h> 42 + #include <dt-bindings/interrupt-controller/irq.h> 43 + 44 + mailbox@31b80000 { 45 + compatible = "mediatek,mt8196-vcp-mbox"; 46 + reg = <0x31b80000 0x1000>; 47 + interrupts = <GIC_SPI 789 IRQ_TYPE_LEVEL_HIGH 0>; 48 + #mbox-cells = <0>; 49 + };
+5 -1
Documentation/devicetree/bindings/mailbox/microchip,mpfs-mailbox.yaml
··· 11 11 12 12 properties: 13 13 compatible: 14 - const: microchip,mpfs-mailbox 14 + oneOf: 15 + - items: 16 + - const: microchip,pic64gx-mailbox 17 + - const: microchip,mpfs-mailbox 18 + - const: microchip,mpfs-mailbox 15 19 16 20 reg: 17 21 oneOf:
+1
Documentation/devicetree/bindings/mailbox/sprd-mailbox.yaml
··· 16 16 enum: 17 17 - sprd,sc9860-mailbox 18 18 - sprd,sc9863a-mailbox 19 + - sprd,ums9230-mailbox 19 20 20 21 reg: 21 22 items:
+11
Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.yaml
··· 11 11 messaging between two Xilinx Zynq UltraScale+ MPSoC IPI agents. Each IPI 12 12 agent owns registers used for notification and buffers for message. 13 13 14 + For Versal devices, there are two types of IPI channels: 15 + - Buffered channels: Support message passing and require the "msg" 16 + register region to be present on both the host and remote IPI agents. 17 + - Buffer-less channels: Support notification only and do not require the 18 + "msg" register region. For these channels, the "msg" region should be 19 + omitted. 20 + 21 + For message passing, both the host and remote IPI agents must define the "msg" 22 + register region. If either agent omits the "msg" region, only notification 23 + based communication is possible. 24 + 14 25 +-------------------------------------+ 15 26 | Xilinx ZynqMP IPI Controller | 16 27 +-------------------------------------+
+13 -4
drivers/mailbox/Kconfig
··· 199 199 tristate "PolarFire SoC (MPFS) Mailbox" 200 200 depends on HAS_IOMEM 201 201 depends on MFD_SYSCON 202 - depends on ARCH_MICROCHIP_POLARFIRE || COMPILE_TEST 202 + depends on ARCH_MICROCHIP || COMPILE_TEST 203 203 help 204 204 This driver adds support for the PolarFire SoC (MPFS) mailbox controller. 205 205 ··· 279 279 tristate "MediaTek ADSP Mailbox Controller" 280 280 depends on ARCH_MEDIATEK || COMPILE_TEST 281 281 help 282 - Say yes here to add support for "MediaTek ADSP Mailbox Controller. 282 + Say yes here to add support for MediaTek ADSP Mailbox Controller. 283 283 This mailbox driver is used to send notification or short message 284 284 between processors with ADSP. It will place the message to share 285 285 buffer and will access the ipc control. ··· 303 303 MediaTek SoCs, such as the MT8196. 304 304 Say Y or m here if you want to support the MT8196 SoC in your kernel 305 305 build. 306 + 307 + config MTK_VCP_MBOX 308 + tristate "MediaTek VCP Mailbox Support" 309 + depends on ARCH_MEDIATEK || COMPILE_TEST 310 + help 311 + Say yes here to add support for the MediaTek VCP mailbox driver. 312 + The mailbox implementation provides access from the application 313 + processor to Video Companion Processor Unit. 314 + If unsure say N. 306 315 307 316 config ZYNQMP_IPI_MBOX 308 317 tristate "Xilinx ZynqMP IPI Mailbox" ··· 396 387 Mailbox driver implementation for RISC-V SBI Message Proxy (MPXY) 397 388 extension. This mailbox driver is used to send messages to the 398 389 remote processor through the SBI implementation (M-mode firmware 399 - or HS-mode hypervisor). Say Y here if you want to have this support. 400 - If unsure say N. 390 + or HS-mode hypervisor). Say Y here, unless you are sure you do not 391 + need this. 401 392 402 393 endif
+2
drivers/mailbox/Makefile
··· 65 65 66 66 obj-$(CONFIG_MTK_GPUEB_MBOX) += mtk-gpueb-mailbox.o 67 67 68 + obj-$(CONFIG_MTK_VCP_MBOX) += mtk-vcp-mailbox.o 69 + 68 70 obj-$(CONFIG_ZYNQMP_IPI_MBOX) += zynqmp-ipi-mailbox.o 69 71 70 72 obj-$(CONFIG_SUN6I_MSGBOX) += sun6i-msgbox.o
+1 -1
drivers/mailbox/arm_mhuv3.c
··· 333 333 * @rev: MHUv3 controller IIDR revision. 334 334 * @var: MHUv3 controller IIDR variant. 335 335 * @prod_id: MHUv3 controller IIDR product_id. 336 - * @num_chans: The total number of channnels discovered across all extensions. 336 + * @num_chans: The total number of channels discovered across all extensions. 337 337 * @cmb_irq: Combined IRQ number if any found defined. 338 338 * @ctrl: A reference to the MHUv3 control page for this block. 339 339 * @pbx: Base address of the PBX register mapping region.
-1
drivers/mailbox/bcm-flexrm-mailbox.c
··· 26 26 #include <linux/interrupt.h> 27 27 #include <linux/kernel.h> 28 28 #include <linux/mailbox_controller.h> 29 - #include <linux/mailbox_client.h> 30 29 #include <linux/mailbox/brcm-message.h> 31 30 #include <linux/module.h> 32 31 #include <linux/msi.h>
+1 -1
drivers/mailbox/cix-mailbox.c
··· 346 346 /* FIFO overflow is generated */ 347 347 if (int_status & CIX_FIFO_OFLOW_INT) { 348 348 status = cix_mbox_read(priv, CIX_FIFO_STAS); 349 - dev_err(priv->dev, "fifo overlow: int_stats %d\n", status); 349 + dev_err(priv->dev, "fifo overflow: int_stats %d\n", status); 350 350 cix_mbox_write(priv, CIX_FIFO_OFLOW_INT, CIX_INT_CLEAR); 351 351 } 352 352 }
-1
drivers/mailbox/cv1800-mailbox.c
··· 11 11 #include <linux/interrupt.h> 12 12 #include <linux/io.h> 13 13 #include <linux/kfifo.h> 14 - #include <linux/mailbox_client.h> 15 14 #include <linux/mailbox_controller.h> 16 15 #include <linux/module.h> 17 16 #include <linux/platform_device.h>
+4 -5
drivers/mailbox/exynos-mailbox.c
··· 35 35 * struct exynos_mbox - driver's private data. 36 36 * @regs: mailbox registers base address. 37 37 * @mbox: pointer to the mailbox controller. 38 - * @pclk: pointer to the mailbox peripheral clock. 39 38 */ 40 39 struct exynos_mbox { 41 40 void __iomem *regs; 42 41 struct mbox_controller *mbox; 43 - struct clk *pclk; 44 42 }; 45 43 46 44 static int exynos_mbox_send_data(struct mbox_chan *chan, void *data) ··· 98 100 struct exynos_mbox *exynos_mbox; 99 101 struct mbox_controller *mbox; 100 102 struct mbox_chan *chans; 103 + struct clk *pclk; 101 104 int i; 102 105 103 106 exynos_mbox = devm_kzalloc(dev, sizeof(*exynos_mbox), GFP_KERNEL); ··· 118 119 if (IS_ERR(exynos_mbox->regs)) 119 120 return PTR_ERR(exynos_mbox->regs); 120 121 121 - exynos_mbox->pclk = devm_clk_get_enabled(dev, "pclk"); 122 - if (IS_ERR(exynos_mbox->pclk)) 123 - return dev_err_probe(dev, PTR_ERR(exynos_mbox->pclk), 122 + pclk = devm_clk_get_enabled(dev, "pclk"); 123 + if (IS_ERR(pclk)) 124 + return dev_err_probe(dev, PTR_ERR(pclk), 124 125 "Failed to enable clock.\n"); 125 126 126 127 mbox->num_chans = EXYNOS_MBOX_CHAN_COUNT;
+6 -2
drivers/mailbox/imx-mailbox.c
··· 122 122 u32 xRR; /* Receive Register0 */ 123 123 u32 xSR[IMX_MU_xSR_MAX]; /* Status Registers */ 124 124 u32 xCR[IMX_MU_xCR_MAX]; /* Control Registers */ 125 + bool skip_suspend_flag; 125 126 }; 126 127 127 128 #define IMX_MU_xSR_GIPn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(28 + (3 - (x)))) ··· 989 988 .xRR = 0x40, 990 989 .xSR = {0x60, 0x60, 0x60, 0x60}, 991 990 .xCR = {0x64, 0x64, 0x64, 0x64, 0x64}, 991 + .skip_suspend_flag = true, 992 992 }; 993 993 994 994 static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = { ··· 1073 1071 priv->xcr[i] = imx_mu_read(priv, priv->dcfg->xCR[i]); 1074 1072 } 1075 1073 1076 - priv->suspend = true; 1074 + if (!priv->dcfg->skip_suspend_flag) 1075 + priv->suspend = true; 1077 1076 1078 1077 return 0; 1079 1078 } ··· 1097 1094 imx_mu_write(priv, priv->xcr[i], priv->dcfg->xCR[i]); 1098 1095 } 1099 1096 1100 - priv->suspend = false; 1097 + if (!priv->dcfg->skip_suspend_flag) 1098 + priv->suspend = false; 1101 1099 1102 1100 return 0; 1103 1101 }
+19 -22
drivers/mailbox/mailbox-mchp-ipc-sbi.c
··· 174 174 struct mchp_ipc_msg ipc_msg; 175 175 struct mchp_ipc_status status_msg; 176 176 int ret; 177 - unsigned long hartid; 178 177 u32 i, chan_index, chan_id; 178 + bool found = false; 179 179 180 180 /* Find out the hart that originated the irq */ 181 181 for_each_online_cpu(i) { 182 - hartid = cpuid_to_hartid_map(i); 183 - if (irq == ipc->cluster_cfg[hartid].irq) 182 + if (irq == ipc->cluster_cfg[i].irq) { 183 + found = true; 184 184 break; 185 + } 185 186 } 186 187 187 - status_msg.cluster = hartid; 188 - memcpy(ipc->cluster_cfg[hartid].buf_base, &status_msg, sizeof(struct mchp_ipc_status)); 188 + if (unlikely(!found)) 189 + return IRQ_NONE; 189 190 190 - ret = mchp_ipc_sbi_send(SBI_EXT_IPC_STATUS, ipc->cluster_cfg[hartid].buf_base_addr); 191 + status_msg.cluster = cpuid_to_hartid_map(i); 192 + memcpy(ipc->cluster_cfg[i].buf_base, &status_msg, sizeof(struct mchp_ipc_status)); 193 + 194 + ret = mchp_ipc_sbi_send(SBI_EXT_IPC_STATUS, ipc->cluster_cfg[i].buf_base_addr); 191 195 if (ret < 0) { 192 196 dev_err_ratelimited(ipc->dev, "could not get IHC irq status ret=%d\n", ret); 193 197 return IRQ_HANDLED; 194 198 } 195 199 196 - memcpy(&status_msg, ipc->cluster_cfg[hartid].buf_base, sizeof(struct mchp_ipc_status)); 200 + memcpy(&status_msg, ipc->cluster_cfg[i].buf_base, sizeof(struct mchp_ipc_status)); 197 201 198 202 /* 199 203 * Iterate over each bit set in the IHC interrupt status register (IRQ_STATUS) to identify ··· 325 321 goto fail_free_buf_msg_rx; 326 322 } 327 323 328 - if (ret) { 329 - dev_err(ipc->dev, "failed to register interrupt(s)\n"); 330 - goto fail_free_buf_msg_rx; 331 - } 332 - 333 - return ret; 334 - 335 324 fail_free_buf_msg_rx: 336 325 kfree(chan_info->msg_buf_rx); 337 326 fail_free_buf_msg_tx: ··· 382 385 if (ret <= 0) 383 386 continue; 384 387 385 - ipc->cluster_cfg[hartid].irq = ret; 386 - ret = devm_request_irq(ipc->dev, ipc->cluster_cfg[hartid].irq, 388 + ipc->cluster_cfg[cpuid].irq = ret; 389 + ret = devm_request_irq(ipc->dev, ipc->cluster_cfg[cpuid].irq, 387 390 mchp_ipc_cluster_aggr_isr, IRQF_SHARED, 388 391 "miv-ihc-irq", ipc); 389 392 if (ret) 390 393 return ret; 391 394 392 - ipc->cluster_cfg[hartid].buf_base = devm_kmalloc(ipc->dev, 393 - sizeof(struct mchp_ipc_status), 394 - GFP_KERNEL); 395 + ipc->cluster_cfg[cpuid].buf_base = devm_kmalloc(ipc->dev, 396 + sizeof(struct mchp_ipc_status), 397 + GFP_KERNEL); 395 398 396 - if (!ipc->cluster_cfg[hartid].buf_base) 399 + if (!ipc->cluster_cfg[cpuid].buf_base) 397 400 return -ENOMEM; 398 401 399 - ipc->cluster_cfg[hartid].buf_base_addr = __pa(ipc->cluster_cfg[hartid].buf_base); 402 + ipc->cluster_cfg[cpuid].buf_base_addr = __pa(ipc->cluster_cfg[cpuid].buf_base); 400 403 401 404 irq_found = true; 402 405 } ··· 416 419 417 420 ret = sbi_probe_extension(SBI_EXT_MICROCHIP_TECHNOLOGY); 418 421 if (ret <= 0) 419 - return dev_err_probe(dev, ret, "Microchip SBI extension not detected\n"); 422 + return dev_err_probe(dev, -ENODEV, "Microchip SBI extension not detected\n"); 420 423 421 424 ipc = devm_kzalloc(dev, sizeof(*ipc), GFP_KERNEL); 422 425 if (!ipc)
+2 -4
drivers/mailbox/mailbox.c
··· 489 489 static struct mbox_chan *fw_mbox_index_xlate(struct mbox_controller *mbox, 490 490 const struct fwnode_reference_args *sp) 491 491 { 492 - int ind = sp->args[0]; 493 - 494 - if (ind >= mbox->num_chans) 492 + if (sp->nargs < 1 || sp->args[0] >= mbox->num_chans) 495 493 return ERR_PTR(-EINVAL); 496 494 497 - return &mbox->chans[ind]; 495 + return &mbox->chans[sp->args[0]]; 498 496 } 499 497 500 498 /**
+4 -8
drivers/mailbox/mtk-cmdq-mailbox.c
··· 636 636 static int cmdq_get_clocks(struct device *dev, struct cmdq *cmdq) 637 637 { 638 638 static const char * const gce_name = "gce"; 639 - struct device_node *node, *parent = dev->of_node->parent; 639 + struct device_node *parent = dev->of_node->parent; 640 640 struct clk_bulk_data *clks; 641 641 642 642 cmdq->clocks = devm_kcalloc(dev, cmdq->pdata->gce_num, ··· 661 661 * as the clock of the main GCE must be enabled for additional IPs 662 662 * to be reachable. 663 663 */ 664 - for_each_child_of_node(parent, node) { 664 + for_each_child_of_node_scoped(parent, node) { 665 665 int alias_id = of_alias_get_id(node, gce_name); 666 666 667 667 if (alias_id < 0 || alias_id >= cmdq->pdata->gce_num) ··· 670 670 clks = &cmdq->clocks[alias_id]; 671 671 672 672 clks->id = devm_kasprintf(dev, GFP_KERNEL, "gce%d", alias_id); 673 - if (!clks->id) { 674 - of_node_put(node); 673 + if (!clks->id) 675 674 return -ENOMEM; 676 - } 677 675 678 676 clks->clk = of_clk_get(node, 0); 679 - if (IS_ERR(clks->clk)) { 680 - of_node_put(node); 677 + if (IS_ERR(clks->clk)) 681 678 return dev_err_probe(dev, PTR_ERR(clks->clk), 682 679 "failed to get gce%d clock\n", alias_id); 683 - } 684 680 } 685 681 686 682 return 0;
+170
drivers/mailbox/mtk-vcp-mailbox.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2025 MediaTek Corporation. All rights reserved. 4 + * Author: Jjian Zhou <jjian.zhou.@mediatek.com> 5 + */ 6 + 7 + #include <linux/interrupt.h> 8 + #include <linux/io.h> 9 + #include <linux/kernel.h> 10 + #include <linux/mailbox_controller.h> 11 + #include <linux/mailbox/mtk-vcp-mailbox.h> 12 + #include <linux/module.h> 13 + #include <linux/of.h> 14 + #include <linux/platform_device.h> 15 + #include <linux/slab.h> 16 + 17 + struct mtk_vcp_mbox { 18 + struct mbox_controller mbox; 19 + void __iomem *base; 20 + struct device *dev; 21 + const struct mtk_vcp_mbox_cfg *cfg; 22 + struct mtk_ipi_info ipi_recv; 23 + struct mbox_chan chans; 24 + }; 25 + 26 + struct mtk_vcp_mbox_cfg { 27 + u16 set_in; 28 + u16 clr_out; 29 + }; 30 + 31 + static irqreturn_t mtk_vcp_mbox_irq_thread(int irq, void *data) 32 + { 33 + struct mtk_vcp_mbox *priv = data; 34 + 35 + /* get irq status */ 36 + priv->ipi_recv.irq_status = readl(priv->base + priv->cfg->clr_out); 37 + 38 + __ioread32_copy(priv->ipi_recv.msg, priv->base, 39 + MTK_VCP_MBOX_SLOT_MAX_SIZE / 4); 40 + 41 + mbox_chan_received_data(&priv->chans, &priv->ipi_recv); 42 + 43 + /* clear irq status */ 44 + writel(priv->ipi_recv.irq_status, priv->base + priv->cfg->clr_out); 45 + 46 + return IRQ_HANDLED; 47 + } 48 + 49 + static struct mbox_chan *mtk_vcp_mbox_xlate(struct mbox_controller *mbox, 50 + const struct of_phandle_args *sp) 51 + { 52 + if (sp->args_count) 53 + return NULL; 54 + 55 + return &mbox->chans[0]; 56 + } 57 + 58 + static int mtk_vcp_mbox_send_data(struct mbox_chan *chan, void *data) 59 + { 60 + struct mtk_vcp_mbox *priv = chan->con_priv; 61 + struct mtk_ipi_info *ipi_info = data; 62 + u32 status; 63 + 64 + if (!ipi_info->msg) { 65 + dev_err(priv->dev, "msg buffer is NULL.\n"); 66 + return -EINVAL; 67 + } 68 + 69 + status = readl(priv->base + priv->cfg->set_in); 70 + if (status & BIT(ipi_info->index)) { 71 + dev_warn(priv->dev, "mailbox IPI %d is busy.\n", ipi_info->id); 72 + return -EBUSY; 73 + } 74 + 75 + if (ipi_info->slot_ofs + ipi_info->len > MTK_VCP_MBOX_SLOT_MAX_SIZE) 76 + return -EINVAL; 77 + __iowrite32_copy(priv->base + ipi_info->slot_ofs, ipi_info->msg, 78 + ipi_info->len); 79 + 80 + writel(BIT(ipi_info->index), priv->base + priv->cfg->set_in); 81 + 82 + return 0; 83 + } 84 + 85 + static bool mtk_vcp_mbox_last_tx_done(struct mbox_chan *chan) 86 + { 87 + struct mtk_ipi_info *ipi_info = chan->active_req; 88 + struct mtk_vcp_mbox *priv = chan->con_priv; 89 + 90 + return !(readl(priv->base + priv->cfg->set_in) & BIT(ipi_info->index)); 91 + } 92 + 93 + static const struct mbox_chan_ops mtk_vcp_mbox_chan_ops = { 94 + .send_data = mtk_vcp_mbox_send_data, 95 + .last_tx_done = mtk_vcp_mbox_last_tx_done, 96 + }; 97 + 98 + static int mtk_vcp_mbox_probe(struct platform_device *pdev) 99 + { 100 + struct device *dev = &pdev->dev; 101 + struct mtk_vcp_mbox *priv; 102 + struct mbox_controller *mbox; 103 + int ret, irq; 104 + 105 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 106 + if (!priv) 107 + return -ENOMEM; 108 + 109 + priv->dev = dev; 110 + priv->chans.con_priv = priv; 111 + mbox = &priv->mbox; 112 + mbox->dev = dev; 113 + mbox->ops = &mtk_vcp_mbox_chan_ops; 114 + mbox->txdone_irq = false; 115 + mbox->txdone_poll = true; 116 + mbox->of_xlate = mtk_vcp_mbox_xlate; 117 + mbox->num_chans = 1; 118 + mbox->chans = &priv->chans; 119 + 120 + priv->ipi_recv.msg = devm_kzalloc(dev, MTK_VCP_MBOX_SLOT_MAX_SIZE, 121 + GFP_KERNEL); 122 + if (!priv->ipi_recv.msg) 123 + return -ENOMEM; 124 + 125 + priv->base = devm_platform_ioremap_resource(pdev, 0); 126 + if (IS_ERR(priv->base)) 127 + return PTR_ERR(priv->base); 128 + 129 + priv->cfg = of_device_get_match_data(dev); 130 + if (!priv->cfg) 131 + return -EINVAL; 132 + 133 + platform_set_drvdata(pdev, priv); 134 + 135 + irq = platform_get_irq(pdev, 0); 136 + if (irq < 0) 137 + return irq; 138 + 139 + ret = devm_request_threaded_irq(dev, irq, NULL, 140 + mtk_vcp_mbox_irq_thread, IRQF_ONESHOT, 141 + dev_name(dev), priv); 142 + if (ret < 0) 143 + return ret; 144 + 145 + return devm_mbox_controller_register(dev, &priv->mbox); 146 + } 147 + 148 + static const struct mtk_vcp_mbox_cfg mt8196_cfg = { 149 + .set_in = 0x100, 150 + .clr_out = 0x10c, 151 + }; 152 + 153 + static const struct of_device_id mtk_vcp_mbox_of_match[] = { 154 + { .compatible = "mediatek,mt8196-vcp-mbox", .data = &mt8196_cfg }, 155 + {}, 156 + }; 157 + MODULE_DEVICE_TABLE(of, mtk_vcp_mbox_of_match); 158 + 159 + static struct platform_driver mtk_vcp_mbox_driver = { 160 + .probe = mtk_vcp_mbox_probe, 161 + .driver = { 162 + .name = "mtk_vcp_mbox", 163 + .of_match_table = mtk_vcp_mbox_of_match, 164 + }, 165 + }; 166 + module_platform_driver(mtk_vcp_mbox_driver); 167 + 168 + MODULE_AUTHOR("Jjian Zhou <jjian.zhou@mediatek.com>"); 169 + MODULE_DESCRIPTION("MTK VCP Mailbox Controller"); 170 + MODULE_LICENSE("GPL");
-1
drivers/mailbox/omap-mailbox.c
··· 21 21 #include <linux/platform_device.h> 22 22 #include <linux/pm_runtime.h> 23 23 #include <linux/mailbox_controller.h> 24 - #include <linux/mailbox_client.h> 25 24 26 25 #include "mailbox.h" 27 26
+24 -96
drivers/mailbox/pcc.c
··· 305 305 pcc_chan_reg_read_modify_write(&pchan->db); 306 306 } 307 307 308 - static void *write_response(struct pcc_chan_info *pchan) 309 - { 310 - struct pcc_header pcc_header; 311 - void *buffer; 312 - int data_len; 313 - 314 - memcpy_fromio(&pcc_header, pchan->chan.shmem, 315 - sizeof(pcc_header)); 316 - data_len = pcc_header.length - sizeof(u32) + sizeof(struct pcc_header); 317 - 318 - buffer = pchan->chan.rx_alloc(pchan->chan.mchan->cl, data_len); 319 - if (buffer != NULL) 320 - memcpy_fromio(buffer, pchan->chan.shmem, data_len); 321 - return buffer; 322 - } 323 - 324 308 /** 325 309 * pcc_mbox_irq - PCC mailbox interrupt handler 326 310 * @irq: interrupt number ··· 316 332 { 317 333 struct pcc_chan_info *pchan; 318 334 struct mbox_chan *chan = p; 319 - struct pcc_header *pcc_header = chan->active_req; 320 - void *handle = NULL; 321 335 322 336 pchan = chan->con_priv; 323 337 ··· 339 357 * required to avoid any possible race in updatation of this flag. 340 358 */ 341 359 pchan->chan_in_use = false; 342 - 343 - if (pchan->chan.rx_alloc) 344 - handle = write_response(pchan); 345 - 346 - if (chan->active_req) { 347 - pcc_header = chan->active_req; 348 - if (pcc_header->flags & PCC_CMD_COMPLETION_NOTIFY) 349 - mbox_chan_txdone(chan, 0); 350 - } 351 - 352 - mbox_chan_received_data(chan, handle); 360 + mbox_chan_received_data(chan, NULL); 361 + mbox_chan_txdone(chan, 0); 353 362 354 363 pcc_chan_acknowledge(pchan); 355 364 ··· 377 404 return ERR_PTR(-EBUSY); 378 405 } 379 406 380 - rc = mbox_bind_client(chan, cl); 381 - if (rc) 382 - return ERR_PTR(rc); 383 - 384 407 pcc_mchan = &pchan->chan; 385 408 pcc_mchan->shmem = acpi_os_ioremap(pcc_mchan->shmem_base_addr, 386 409 pcc_mchan->shmem_size); 387 410 if (!pcc_mchan->shmem) 388 - goto err; 411 + return ERR_PTR(-ENXIO); 389 412 390 - pcc_mchan->manage_writes = false; 391 - 392 - /* This indicates that the channel is ready to accept messages. 393 - * This needs to happen after the channel has registered 394 - * its callback. There is no access point to do that in 395 - * the mailbox API. That implies that the mailbox client must 396 - * have set the allocate callback function prior to 397 - * sending any messages. 398 - */ 399 - if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE) 400 - pcc_chan_reg_read_modify_write(&pchan->cmd_update); 413 + rc = mbox_bind_client(chan, cl); 414 + if (rc) { 415 + iounmap(pcc_mchan->shmem); 416 + pcc_mchan->shmem = NULL; 417 + return ERR_PTR(rc); 418 + } 401 419 402 420 return pcc_mchan; 403 - 404 - err: 405 - mbox_free_channel(chan); 406 - return ERR_PTR(-ENXIO); 407 421 } 408 422 EXPORT_SYMBOL_GPL(pcc_mbox_request_channel); 409 423 ··· 419 459 } 420 460 EXPORT_SYMBOL_GPL(pcc_mbox_free_channel); 421 461 422 - static int pcc_write_to_buffer(struct mbox_chan *chan, void *data) 423 - { 424 - struct pcc_chan_info *pchan = chan->con_priv; 425 - struct pcc_mbox_chan *pcc_mbox_chan = &pchan->chan; 426 - struct pcc_header *pcc_header = data; 427 - 428 - if (!pchan->chan.manage_writes) 429 - return 0; 430 - 431 - /* The PCC header length includes the command field 432 - * but not the other values from the header. 433 - */ 434 - int len = pcc_header->length - sizeof(u32) + sizeof(struct pcc_header); 435 - u64 val; 436 - 437 - pcc_chan_reg_read(&pchan->cmd_complete, &val); 438 - if (!val) { 439 - pr_info("%s pchan->cmd_complete not set", __func__); 440 - return -1; 441 - } 442 - memcpy_toio(pcc_mbox_chan->shmem, data, len); 443 - return 0; 444 - } 445 - 446 - 447 462 /** 448 - * pcc_send_data - Called from Mailbox Controller code. If 449 - * pchan->chan.rx_alloc is set, then the command complete 450 - * flag is checked and the data is written to the shared 451 - * buffer io memory. 452 - * 453 - * If pchan->chan.rx_alloc is not set, then it is used 463 + * pcc_send_data - Called from Mailbox Controller code. Used 454 464 * here only to ring the channel doorbell. The PCC client 455 465 * specific read/write is done in the client driver in 456 466 * order to maintain atomicity over PCC channel once ··· 436 506 int ret; 437 507 struct pcc_chan_info *pchan = chan->con_priv; 438 508 439 - ret = pcc_write_to_buffer(chan, data); 440 - if (ret) 441 - return ret; 442 - 443 509 ret = pcc_chan_reg_read_modify_write(&pchan->cmd_update); 444 510 if (ret) 445 511 return ret; 446 512 447 513 ret = pcc_chan_reg_read_modify_write(&pchan->db); 448 - 449 514 if (!ret && pchan->plat_irq > 0) 450 515 pchan->chan_in_use = true; 451 516 452 517 return ret; 453 518 } 454 519 455 - 456 520 static bool pcc_last_tx_done(struct mbox_chan *chan) 457 521 { 458 522 struct pcc_chan_info *pchan = chan->con_priv; 459 - u64 val; 460 523 461 - pcc_chan_reg_read(&pchan->cmd_complete, &val); 462 - if (!val) 463 - return false; 464 - else 465 - return true; 524 + return pcc_mbox_cmd_complete_check(pchan); 466 525 } 467 - 468 - 469 526 470 527 /** 471 528 * pcc_startup - Called from Mailbox Controller code. Used here ··· 467 550 unsigned long irqflags; 468 551 int rc; 469 552 553 + /* 554 + * Clear and acknowledge any pending interrupts on responder channel 555 + * before enabling the interrupt 556 + */ 557 + pcc_chan_acknowledge(pchan); 558 + 470 559 if (pchan->plat_irq > 0) { 471 560 irqflags = pcc_chan_plat_irq_can_be_shared(pchan) ? 472 - IRQF_SHARED | IRQF_ONESHOT : 0; 561 + IRQF_SHARED : 0; 473 562 rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq, 474 563 irqflags, MBOX_IRQ_NAME, chan); 475 564 if (unlikely(rc)) { ··· 800 877 (unsigned long) pcct_tbl + sizeof(struct acpi_table_pcct)); 801 878 802 879 acpi_pcct_tbl = (struct acpi_table_pcct *) pcct_tbl; 803 - if (acpi_pcct_tbl->flags & ACPI_PCCT_DOORBELL) 880 + if (acpi_pcct_tbl->flags & ACPI_PCCT_DOORBELL) { 804 881 pcc_mbox_ctrl->txdone_irq = true; 882 + pcc_mbox_ctrl->txdone_poll = false; 883 + } else { 884 + pcc_mbox_ctrl->txdone_irq = false; 885 + pcc_mbox_ctrl->txdone_poll = true; 886 + } 805 887 806 888 for (i = 0; i < count; i++) { 807 889 struct pcc_chan_info *pchan = chan_info + i;
+88 -29
drivers/mailbox/sprd-mailbox.c
··· 24 24 #define SPRD_MBOX_IRQ_STS 0x18 25 25 #define SPRD_MBOX_IRQ_MSK 0x1c 26 26 #define SPRD_MBOX_LOCK 0x20 27 - #define SPRD_MBOX_FIFO_DEPTH 0x24 27 + #define SPRD_MBOX_FIFO_DEPTH 0x24 /* outbox only */ 28 + #define SPRD_MBOX_IN_FIFO_STS2 0x24 /* inbox only, revision 2 */ 28 29 29 30 /* Bit and mask definition for inbox's SPRD_MBOX_FIFO_STS register */ 30 31 #define SPRD_INBOX_FIFO_DELIVER_MASK GENMASK(23, 16) ··· 33 32 #define SPRD_INBOX_FIFO_DELIVER_SHIFT 16 34 33 #define SPRD_INBOX_FIFO_BUSY_MASK GENMASK(7, 0) 35 34 35 + /* Bit and mask definition for R2 inbox's SPRD_MBOX_FIFO_RST register */ 36 + #define SPRD_INBOX_R2_FIFO_OVERFLOW_DELIVER_RST GENMASK(31, 0) 37 + 38 + /* Bit and mask definition for R2 inbox's SPRD_MBOX_FIFO_STS register */ 39 + #define SPRD_INBOX_R2_FIFO_DELIVER_MASK GENMASK(15, 0) 40 + 41 + /* Bit and mask definition for SPRD_MBOX_IN_FIFO_STS2 register */ 42 + #define SPRD_INBOX_R2_FIFO_OVERFLOW_MASK GENMASK(31, 16) 43 + #define SPRD_INBOX_R2_FIFO_BUSY_MASK GENMASK(15, 0) 44 + 36 45 /* Bit and mask definition for SPRD_MBOX_IRQ_STS register */ 37 - #define SPRD_MBOX_IRQ_CLR BIT(0) 46 + #define SPRD_MBOX_IRQ_CLR GENMASK(31, 0) 38 47 39 48 /* Bit and mask definition for outbox's SPRD_MBOX_FIFO_STS register */ 40 49 #define SPRD_OUTBOX_FIFO_FULL BIT(2) ··· 63 52 #define SPRD_OUTBOX_FIFO_IRQ_MASK GENMASK(4, 0) 64 53 65 54 #define SPRD_OUTBOX_BASE_SPAN 0x1000 66 - #define SPRD_MBOX_CHAN_MAX 8 67 - #define SPRD_SUPP_INBOX_ID_SC9863A 7 55 + #define SPRD_MBOX_R1_CHAN_MAX 8 56 + #define SPRD_MBOX_R2_CHAN_MAX 16 57 + 58 + enum sprd_mbox_version { 59 + SPRD_MBOX_R1, 60 + SPRD_MBOX_R2, 61 + }; 62 + 63 + struct sprd_mbox_info { 64 + enum sprd_mbox_version version; 65 + unsigned long supp_id; 66 + }; 68 67 69 68 struct sprd_mbox_priv { 70 69 struct mbox_controller mbox; ··· 85 64 void __iomem *supp_base; 86 65 u32 outbox_fifo_depth; 87 66 67 + const struct sprd_mbox_info *info; 68 + 88 69 struct mutex lock; 89 70 u32 refcnt; 90 - struct mbox_chan chan[SPRD_MBOX_CHAN_MAX]; 71 + struct mbox_chan chan[SPRD_MBOX_R2_CHAN_MAX]; 91 72 }; 92 73 93 74 static struct sprd_mbox_priv *to_sprd_mbox_priv(struct mbox_controller *mbox) ··· 177 154 { 178 155 struct sprd_mbox_priv *priv = data; 179 156 struct mbox_chan *chan; 180 - u32 fifo_sts, send_sts, busy, id; 157 + u32 fifo_sts, fifo_sts2, send_sts, busy, id; 181 158 182 159 fifo_sts = readl(priv->inbox_base + SPRD_MBOX_FIFO_STS); 183 160 161 + if (priv->info->version == SPRD_MBOX_R2) 162 + fifo_sts2 = readl(priv->inbox_base + SPRD_MBOX_IN_FIFO_STS2); 163 + 184 164 /* Get the inbox data delivery status */ 185 - send_sts = (fifo_sts & SPRD_INBOX_FIFO_DELIVER_MASK) >> 186 - SPRD_INBOX_FIFO_DELIVER_SHIFT; 165 + if (priv->info->version == SPRD_MBOX_R2) { 166 + send_sts = fifo_sts & SPRD_INBOX_R2_FIFO_DELIVER_MASK; 167 + } else { 168 + send_sts = (fifo_sts & SPRD_INBOX_FIFO_DELIVER_MASK) >> 169 + SPRD_INBOX_FIFO_DELIVER_SHIFT; 170 + } 171 + 187 172 if (!send_sts) { 188 173 dev_warn_ratelimited(priv->dev, "spurious inbox interrupt\n"); 189 174 return IRQ_NONE; 175 + } 176 + 177 + /* Clear FIFO delivery and overflow status first */ 178 + if (priv->info->version == SPRD_MBOX_R2) { 179 + writel(SPRD_INBOX_R2_FIFO_OVERFLOW_DELIVER_RST, 180 + priv->inbox_base + SPRD_MBOX_FIFO_RST); 181 + } else { 182 + writel(fifo_sts & (SPRD_INBOX_FIFO_DELIVER_MASK | SPRD_INBOX_FIFO_OVERLOW_MASK), 183 + priv->inbox_base + SPRD_MBOX_FIFO_RST); 190 184 } 191 185 192 186 while (send_sts) { ··· 216 176 * Check if the message was fetched by remote target, if yes, 217 177 * that means the transmission has been completed. 218 178 */ 219 - busy = fifo_sts & SPRD_INBOX_FIFO_BUSY_MASK; 179 + if (priv->info->version == SPRD_MBOX_R2) 180 + busy = fifo_sts2 & SPRD_INBOX_R2_FIFO_BUSY_MASK; 181 + else 182 + busy = fifo_sts & SPRD_INBOX_FIFO_BUSY_MASK; 183 + 220 184 if (!(busy & BIT(id))) 221 185 mbox_chan_txdone(chan, 0); 222 186 } 223 - 224 - /* Clear FIFO delivery and overflow status */ 225 - writel(fifo_sts & 226 - (SPRD_INBOX_FIFO_DELIVER_MASK | SPRD_INBOX_FIFO_OVERLOW_MASK), 227 - priv->inbox_base + SPRD_MBOX_FIFO_RST); 228 187 229 188 /* Clear irq status */ 230 189 writel(SPRD_MBOX_IRQ_CLR, priv->inbox_base + SPRD_MBOX_IRQ_STS); ··· 282 243 /* Select outbox FIFO mode and reset the outbox FIFO status */ 283 244 writel(0x0, priv->outbox_base + SPRD_MBOX_FIFO_RST); 284 245 285 - /* Enable inbox FIFO overflow and delivery interrupt */ 286 - val = readl(priv->inbox_base + SPRD_MBOX_IRQ_MSK); 287 - val &= ~(SPRD_INBOX_FIFO_OVERFLOW_IRQ | SPRD_INBOX_FIFO_DELIVER_IRQ); 246 + /* Enable inbox FIFO delivery interrupt */ 247 + val = SPRD_INBOX_FIFO_IRQ_MASK; 248 + val &= ~SPRD_INBOX_FIFO_DELIVER_IRQ; 288 249 writel(val, priv->inbox_base + SPRD_MBOX_IRQ_MSK); 289 250 290 251 /* Enable outbox FIFO not empty interrupt */ 291 - val = readl(priv->outbox_base + SPRD_MBOX_IRQ_MSK); 252 + val = SPRD_OUTBOX_FIFO_IRQ_MASK; 292 253 val &= ~SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ; 293 254 writel(val, priv->outbox_base + SPRD_MBOX_IRQ_MSK); 294 255 295 256 /* Enable supplementary outbox as the fundamental one */ 296 257 if (priv->supp_base) { 297 258 writel(0x0, priv->supp_base + SPRD_MBOX_FIFO_RST); 298 - val = readl(priv->supp_base + SPRD_MBOX_IRQ_MSK); 299 - val &= ~SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ; 300 259 writel(val, priv->supp_base + SPRD_MBOX_IRQ_MSK); 301 260 } 302 261 } ··· 332 295 struct device *dev = &pdev->dev; 333 296 struct sprd_mbox_priv *priv; 334 297 int ret, inbox_irq, outbox_irq, supp_irq; 335 - unsigned long id, supp; 298 + unsigned long id; 336 299 struct clk *clk; 337 300 338 301 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ··· 341 304 342 305 priv->dev = dev; 343 306 mutex_init(&priv->lock); 307 + 308 + priv->info = of_device_get_match_data(dev); 309 + if (!priv->info) 310 + return -EINVAL; 344 311 345 312 /* 346 313 * Unisoc mailbox uses an inbox to send messages to the target ··· 403 362 return ret; 404 363 } 405 364 406 - supp = (unsigned long) of_device_get_match_data(dev); 407 - if (!supp) { 365 + if (!priv->info->supp_id) { 408 366 dev_err(dev, "no supplementary outbox specified\n"); 409 367 return -ENODEV; 410 368 } 411 - priv->supp_base = priv->outbox_base + (SPRD_OUTBOX_BASE_SPAN * supp); 369 + priv->supp_base = priv->outbox_base + 370 + (SPRD_OUTBOX_BASE_SPAN * priv->info->supp_id); 412 371 } 413 372 414 373 /* Get the default outbox FIFO depth */ ··· 416 375 readl(priv->outbox_base + SPRD_MBOX_FIFO_DEPTH) + 1; 417 376 priv->mbox.dev = dev; 418 377 priv->mbox.chans = &priv->chan[0]; 419 - priv->mbox.num_chans = SPRD_MBOX_CHAN_MAX; 420 378 priv->mbox.ops = &sprd_mbox_ops; 421 379 priv->mbox.txdone_irq = true; 422 380 423 - for (id = 0; id < SPRD_MBOX_CHAN_MAX; id++) 381 + if (priv->info->version == SPRD_MBOX_R2) 382 + priv->mbox.num_chans = SPRD_MBOX_R2_CHAN_MAX; 383 + else 384 + priv->mbox.num_chans = SPRD_MBOX_R1_CHAN_MAX; 385 + 386 + for (id = 0; id < priv->mbox.num_chans; id++) 424 387 priv->chan[id].con_priv = (void *)id; 425 388 426 389 ret = devm_mbox_controller_register(dev, &priv->mbox); ··· 436 391 return 0; 437 392 } 438 393 394 + static const struct sprd_mbox_info sc9860_mbox_info = { 395 + .version = SPRD_MBOX_R1, 396 + }; 397 + 398 + static const struct sprd_mbox_info sc9863a_mbox_info = { 399 + .version = SPRD_MBOX_R1, 400 + .supp_id = 7, 401 + }; 402 + 403 + static const struct sprd_mbox_info ums9230_mbox_info = { 404 + .version = SPRD_MBOX_R2, 405 + .supp_id = 6, 406 + }; 407 + 439 408 static const struct of_device_id sprd_mbox_of_match[] = { 440 - { .compatible = "sprd,sc9860-mailbox" }, 441 - { .compatible = "sprd,sc9863a-mailbox", 442 - .data = (void *)SPRD_SUPP_INBOX_ID_SC9863A }, 409 + { .compatible = "sprd,sc9860-mailbox", .data = &sc9860_mbox_info }, 410 + { .compatible = "sprd,sc9863a-mailbox", .data = &sc9863a_mbox_info }, 411 + { .compatible = "sprd,ums9230-mailbox", .data = &ums9230_mbox_info }, 443 412 { }, 444 413 }; 445 414 MODULE_DEVICE_TABLE(of, sprd_mbox_of_match);
+2 -3
drivers/mailbox/zynqmp-ipi-mailbox.c
··· 904 904 static int zynqmp_ipi_probe(struct platform_device *pdev) 905 905 { 906 906 struct device *dev = &pdev->dev; 907 - struct device_node *nc, *np = pdev->dev.of_node; 907 + struct device_node *np = pdev->dev.of_node; 908 908 struct zynqmp_ipi_pdata *pdata; 909 909 struct of_phandle_args out_irq; 910 910 struct zynqmp_ipi_mbox *mbox; ··· 940 940 pdata->num_mboxes = num_mboxes; 941 941 942 942 mbox = pdata->ipi_mboxes; 943 - for_each_available_child_of_node(np, nc) { 943 + for_each_available_child_of_node_scoped(np, nc) { 944 944 mbox->pdata = pdata; 945 945 mbox->setup_ipi_fn = ipi_fn; 946 946 947 947 ret = zynqmp_ipi_mbox_probe(mbox, nc); 948 948 if (ret) { 949 - of_node_put(nc); 950 949 dev_err(dev, "failed to probe subdev.\n"); 951 950 ret = -EINVAL; 952 951 goto free_mbox_dev;
-29
include/acpi/pcc.h
··· 17 17 u32 latency; 18 18 u32 max_access_rate; 19 19 u16 min_turnaround_time; 20 - 21 - /* Set to true to indicate that the mailbox should manage 22 - * writing the dat to the shared buffer. This differs from 23 - * the case where the drivesr are writing to the buffer and 24 - * using send_data only to ring the doorbell. If this flag 25 - * is set, then the void * data parameter of send_data must 26 - * point to a kernel-memory buffer formatted in accordance with 27 - * the PCC specification. 28 - * 29 - * The active buffer management will include reading the 30 - * notify_on_completion flag, and will then 31 - * call mbox_chan_txdone when the acknowledgment interrupt is 32 - * received. 33 - */ 34 - bool manage_writes; 35 - 36 - /* Optional callback that allows the driver 37 - * to allocate the memory used for receiving 38 - * messages. The return value is the location 39 - * inside the buffer where the mailbox should write the data. 40 - */ 41 - void *(*rx_alloc)(struct mbox_client *cl, int size); 42 - }; 43 - 44 - struct pcc_header { 45 - u32 signature; 46 - u32 flags; 47 - u32 length; 48 - u32 command; 49 20 }; 50 21 51 22 /* Generic Communications Channel Shared Memory Region */
+32
include/linux/mailbox/mtk-vcp-mailbox.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ 2 + /* 3 + * Copyright (c) 2025 MediaTek Inc. 4 + */ 5 + 6 + #ifndef __MTK_VCP_MAILBOX_H__ 7 + #define __MTK_VCP_MAILBOX_H__ 8 + 9 + #define MTK_VCP_MBOX_SLOT_MAX_SIZE 0x100 /* mbox max slot size */ 10 + 11 + /** 12 + * struct mtk_ipi_info - mailbox message info for mtk-vcp-mailbox 13 + * @msg: The share buffer between IPC and mailbox driver 14 + * @len: Message length 15 + * @id: This is for identification purposes and not actually used 16 + * by the mailbox hardware. 17 + * @index: The signal number of the mailbox message. 18 + * @slot_ofs: Data slot offset. 19 + * @irq_status: Captures incoming signals for the RX path. 20 + * 21 + * It is used between IPC with mailbox driver. 22 + */ 23 + struct mtk_ipi_info { 24 + void *msg; 25 + u32 len; 26 + u32 id; 27 + u32 index; 28 + u32 slot_ofs; 29 + u32 irq_status; 30 + }; 31 + 32 + #endif