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

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

Pull mailbox updates from Jassi Brar:

- samsung: add gs101-mbox driver

- microchip: add sbi-ipc driver

- zynqmp: fix invalid __percpu annotation

- qcom: add IPQ5424 APCS compatible

- mpfs fix copy and paste bug

- th1520: Fix NULL vs IS_ERR() and a memory corruption bug

- tegra-hsp: clear mailbox before using message

* tag 'mailbox-v6.14' of git://git.kernel.org/pub/scm/linux/kernel/git/jassibrar/mailbox:
riscv: export __cpuid_to_hartid_map
riscv: sbi: vendorid_list: Add Microchip Technology to the vendor list
mailbox: th1520: Fix memory corruption due to incorrect array size
mailbox: zynqmp: Remove invalid __percpu annotation in zynqmp_ipi_probe()
MAINTAINERS: add entry for Samsung Exynos mailbox driver
mailbox: add Samsung Exynos driver
dt-bindings: mailbox: add google,gs101-mbox
mailbox: qcom: Add support for IPQ5424 APCS IPC
dt-bindings: mailbox: qcom: Add IPQ5424 APCS compatible
mailbox: qcom-ipcc: Reset CLEAR_ON_RECV_RD if set from boot firmware
mailbox: add Microchip IPC support
dt-bindings: mailbox: add binding for Microchip IPC mailbox controller
mailbox: tegra-hsp: Clear mailbox before using message
mailbox: mpfs: fix copy and paste bug in probe
mailbox: th1520: Fix a NULL vs IS_ERR() bug

+973 -6
+69
Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + # Copyright 2024 Linaro Ltd. 3 + %YAML 1.2 4 + --- 5 + $id: http://devicetree.org/schemas/mailbox/google,gs101-mbox.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: Samsung Exynos Mailbox Controller 9 + 10 + maintainers: 11 + - Tudor Ambarus <tudor.ambarus@linaro.org> 12 + 13 + description: 14 + The Samsung Exynos mailbox controller, used on Google GS101 SoC, has 16 flag 15 + bits for hardware interrupt generation and a shared register for passing 16 + mailbox messages. When the controller is used by the ACPM interface 17 + the shared register is ignored and the mailbox controller acts as a doorbell. 18 + The controller just raises the interrupt to the firmware after the 19 + ACPM interface has written the message to SRAM. 20 + 21 + properties: 22 + compatible: 23 + const: google,gs101-mbox 24 + 25 + reg: 26 + maxItems: 1 27 + 28 + clocks: 29 + maxItems: 1 30 + 31 + clock-names: 32 + items: 33 + - const: pclk 34 + 35 + interrupts: 36 + description: IRQ line for the RX mailbox. 37 + maxItems: 1 38 + 39 + '#mbox-cells': 40 + const: 0 41 + 42 + required: 43 + - compatible 44 + - reg 45 + - clocks 46 + - clock-names 47 + - interrupts 48 + - '#mbox-cells' 49 + 50 + additionalProperties: false 51 + 52 + examples: 53 + - | 54 + #include <dt-bindings/interrupt-controller/arm-gic.h> 55 + #include <dt-bindings/clock/google,gs101.h> 56 + 57 + soc { 58 + #address-cells = <1>; 59 + #size-cells = <1>; 60 + 61 + ap2apm_mailbox: mailbox@17610000 { 62 + compatible = "google,gs101-mbox"; 63 + reg = <0x17610000 0x1000>; 64 + clocks = <&cmu_apm CLK_GOUT_APM_MAILBOX_APM_AP_PCLK>; 65 + clock-names = "pclk"; 66 + interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH 0>; 67 + #mbox-cells = <0>; 68 + }; 69 + };
+123
Documentation/devicetree/bindings/mailbox/microchip,sbi-ipc.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/microchip,sbi-ipc.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Microchip Inter-processor communication (IPC) mailbox controller 8 + 9 + maintainers: 10 + - Valentina Fernandez <valentina.fernandezalanis@microchip.com> 11 + 12 + description: 13 + The Microchip Inter-processor Communication (IPC) facilitates 14 + message passing between processors using an interrupt signaling 15 + mechanism. 16 + 17 + properties: 18 + compatible: 19 + oneOf: 20 + - description: 21 + Intended for use by software running in supervisor privileged 22 + mode (s-mode). This SBI interface is compatible with the Mi-V 23 + Inter-hart Communication (IHC) IP. 24 + const: microchip,sbi-ipc 25 + 26 + - description: 27 + Intended for use by the SBI implementation in machine mode 28 + (m-mode), this compatible string is for the MIV_IHC Soft-IP. 29 + const: microchip,miv-ihc-rtl-v2 30 + 31 + reg: 32 + maxItems: 1 33 + 34 + interrupts: 35 + minItems: 1 36 + maxItems: 5 37 + 38 + interrupt-names: 39 + minItems: 1 40 + maxItems: 5 41 + items: 42 + enum: 43 + - hart-0 44 + - hart-1 45 + - hart-2 46 + - hart-3 47 + - hart-4 48 + - hart-5 49 + 50 + "#mbox-cells": 51 + description: > 52 + For "microchip,sbi-ipc", the cell represents the global "logical" 53 + channel IDs. The meaning of channel IDs are platform firmware dependent. 54 + 55 + For "microchip,miv-ihc-rtl-v2", the cell represents the physical 56 + channel and does not vary based on the platform firmware. 57 + const: 1 58 + 59 + microchip,ihc-chan-disabled-mask: 60 + description: > 61 + Represents the enable/disable state of the bi-directional IHC 62 + channels within the MIV-IHC IP configuration. 63 + 64 + A bit set to '1' indicates that the corresponding channel is disabled, 65 + and any read or write operations to that channel will return zero. 66 + 67 + A bit set to '0' indicates that the corresponding channel is enabled 68 + and will be accessible through its dedicated address range registers. 69 + 70 + The actual enable/disable state of each channel is determined by the 71 + IP block’s configuration. 72 + $ref: /schemas/types.yaml#/definitions/uint16 73 + maximum: 0x7fff 74 + default: 0 75 + 76 + required: 77 + - compatible 78 + - interrupts 79 + - interrupt-names 80 + - "#mbox-cells" 81 + 82 + allOf: 83 + - if: 84 + properties: 85 + compatible: 86 + contains: 87 + const: microchip,sbi-ipc 88 + then: 89 + properties: 90 + reg: 91 + not: {} 92 + description: 93 + The 'microchip,sbi-ipc' operates in a programming model 94 + that does not require memory-mapped I/O (MMIO) registers 95 + since it uses SBI ecalls provided by the m-mode/firmware 96 + SBI implementation to access hardware registers. 97 + microchip,ihc-chan-disabled-mask: false 98 + else: 99 + required: 100 + - reg 101 + - microchip,ihc-chan-disabled-mask 102 + 103 + additionalProperties: false 104 + 105 + examples: 106 + - | 107 + mailbox { 108 + compatible = "microchip,sbi-ipc"; 109 + interrupt-parent = <&plic>; 110 + interrupts = <180>, <179>, <178>; 111 + interrupt-names = "hart-1", "hart-2", "hart-3"; 112 + #mbox-cells = <1>; 113 + }; 114 + - | 115 + mailbox@50000000 { 116 + compatible = "microchip,miv-ihc-rtl-v2"; 117 + microchip,ihc-chan-disabled-mask = /bits/ 16 <0>; 118 + reg = <0x50000000 0x1c000>; 119 + interrupt-parent = <&plic>; 120 + interrupts = <180>, <179>, <178>; 121 + interrupt-names = "hart-1", "hart-2", "hart-3"; 122 + #mbox-cells = <1>; 123 + };
+1
Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml
··· 20 20 - enum: 21 21 - qcom,ipq5018-apcs-apps-global 22 22 - qcom,ipq5332-apcs-apps-global 23 + - qcom,ipq5424-apcs-apps-global 23 24 - qcom,ipq8074-apcs-apps-global 24 25 - qcom,ipq9574-apcs-apps-global 25 26 - const: qcom,ipq6018-apcs-apps-global
+10
MAINTAINERS
··· 3064 3064 F: drivers/*/*s3c64xx* 3065 3065 F: drivers/*/*s5pv210* 3066 3066 F: drivers/clocksource/samsung_pwm_timer.c 3067 + F: drivers/mailbox/exynos-mailbox.c 3067 3068 F: drivers/memory/samsung/ 3068 3069 F: drivers/pwm/pwm-samsung.c 3069 3070 F: drivers/soc/samsung/ ··· 20826 20825 F: arch/arm64/boot/dts/exynos/exynos850* 20827 20826 F: drivers/clk/samsung/clk-exynos850.c 20828 20827 F: include/dt-bindings/clock/exynos850.h 20828 + 20829 + SAMSUNG EXYNOS MAILBOX DRIVER 20830 + M: Tudor Ambarus <tudor.ambarus@linaro.org> 20831 + L: linux-kernel@vger.kernel.org 20832 + L: linux-samsung-soc@vger.kernel.org 20833 + S: Supported 20834 + F: Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml 20835 + F: drivers/mailbox/exynos-mailbox.c 20836 + F: include/linux/mailbox/exynos-message.h 20829 20837 20830 20838 SAMSUNG EXYNOS PSEUDO RANDOM NUMBER GENERATOR (RNG) DRIVER 20831 20839 M: Krzysztof Kozlowski <krzk@kernel.org>
+1
arch/riscv/include/asm/vendorid_list.h
··· 6 6 #define ASM_VENDOR_LIST_H 7 7 8 8 #define ANDES_VENDOR_ID 0x31e 9 + #define MICROCHIP_VENDOR_ID 0x029 9 10 #define SIFIVE_VENDOR_ID 0x489 10 11 #define THEAD_VENDOR_ID 0x5b7 11 12
+1
arch/riscv/kernel/smp.c
··· 43 43 unsigned long __cpuid_to_hartid_map[NR_CPUS] __ro_after_init = { 44 44 [0 ... NR_CPUS-1] = INVALID_HARTID 45 45 }; 46 + EXPORT_SYMBOL_GPL(__cpuid_to_hartid_map); 46 47 47 48 void __init smp_setup_processor_id(void) 48 49 {
+24
drivers/mailbox/Kconfig
··· 36 36 that provides different means of transports: supported extensions 37 37 will be discovered and possibly managed at probe-time. 38 38 39 + config EXYNOS_MBOX 40 + tristate "Exynos Mailbox" 41 + depends on ARCH_EXYNOS || COMPILE_TEST 42 + help 43 + Say Y here if you want to build the Samsung Exynos Mailbox controller 44 + driver. The controller has 16 flag bits for hardware interrupt 45 + generation and a shared register for passing mailbox messages. 46 + When the controller is used by the ACPM interface the shared register 47 + is ignored and the mailbox controller acts as a doorbell that raises 48 + the interrupt to the ACPM firmware. 49 + 39 50 config IMX_MBOX 40 51 tristate "i.MX Mailbox" 41 52 depends on ARCH_MXC || COMPILE_TEST ··· 186 175 187 176 To compile this driver as a module, choose M here. the 188 177 module will be called mailbox-mpfs. 178 + 179 + If unsure, say N. 180 + 181 + config MCHP_SBI_IPC_MBOX 182 + tristate "Microchip Inter-processor Communication (IPC) SBI driver" 183 + depends on RISCV_SBI || COMPILE_TEST 184 + depends on ARCH_MICROCHIP 185 + help 186 + Mailbox implementation for Microchip devices with an 187 + Inter-process communication (IPC) controller. 188 + 189 + To compile this driver as a module, choose M here. the 190 + module will be called mailbox-mchp-ipc-sbi. 189 191 190 192 If unsure, say N. 191 193
+4
drivers/mailbox/Makefile
··· 11 11 12 12 obj-$(CONFIG_ARM_MHU_V3) += arm_mhuv3.o 13 13 14 + obj-$(CONFIG_EXYNOS_MBOX) += exynos-mailbox.o 15 + 14 16 obj-$(CONFIG_IMX_MBOX) += imx-mailbox.o 15 17 16 18 obj-$(CONFIG_ARMADA_37XX_RWTM_MBOX) += armada-37xx-rwtm-mailbox.o ··· 46 44 obj-$(CONFIG_BCM_FLEXRM_MBOX) += bcm-flexrm-mailbox.o 47 45 48 46 obj-$(CONFIG_POLARFIRE_SOC_MAILBOX) += mailbox-mpfs.o 47 + 48 + obj-$(CONFIG_MCHP_SBI_IPC_MBOX) += mailbox-mchp-ipc-sbi.o 49 49 50 50 obj-$(CONFIG_QCOM_APCS_IPC) += qcom-apcs-ipc-mailbox.o 51 51
+157
drivers/mailbox/exynos-mailbox.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2020 Samsung Electronics Co., Ltd. 4 + * Copyright 2020 Google LLC. 5 + * Copyright 2024 Linaro Ltd. 6 + */ 7 + 8 + #include <linux/bitops.h> 9 + #include <linux/bits.h> 10 + #include <linux/clk.h> 11 + #include <linux/io.h> 12 + #include <linux/mailbox_controller.h> 13 + #include <linux/mailbox/exynos-message.h> 14 + #include <linux/module.h> 15 + #include <linux/of.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/slab.h> 18 + 19 + #define EXYNOS_MBOX_MCUCTRL 0x0 /* Mailbox Control Register */ 20 + #define EXYNOS_MBOX_INTCR0 0x24 /* Interrupt Clear Register 0 */ 21 + #define EXYNOS_MBOX_INTMR0 0x28 /* Interrupt Mask Register 0 */ 22 + #define EXYNOS_MBOX_INTSR0 0x2c /* Interrupt Status Register 0 */ 23 + #define EXYNOS_MBOX_INTMSR0 0x30 /* Interrupt Mask Status Register 0 */ 24 + #define EXYNOS_MBOX_INTGR1 0x40 /* Interrupt Generation Register 1 */ 25 + #define EXYNOS_MBOX_INTMR1 0x48 /* Interrupt Mask Register 1 */ 26 + #define EXYNOS_MBOX_INTSR1 0x4c /* Interrupt Status Register 1 */ 27 + #define EXYNOS_MBOX_INTMSR1 0x50 /* Interrupt Mask Status Register 1 */ 28 + 29 + #define EXYNOS_MBOX_INTMR0_MASK GENMASK(15, 0) 30 + #define EXYNOS_MBOX_INTGR1_MASK GENMASK(15, 0) 31 + 32 + #define EXYNOS_MBOX_CHAN_COUNT HWEIGHT32(EXYNOS_MBOX_INTGR1_MASK) 33 + 34 + /** 35 + * struct exynos_mbox - driver's private data. 36 + * @regs: mailbox registers base address. 37 + * @mbox: pointer to the mailbox controller. 38 + * @pclk: pointer to the mailbox peripheral clock. 39 + */ 40 + struct exynos_mbox { 41 + void __iomem *regs; 42 + struct mbox_controller *mbox; 43 + struct clk *pclk; 44 + }; 45 + 46 + static int exynos_mbox_send_data(struct mbox_chan *chan, void *data) 47 + { 48 + struct device *dev = chan->mbox->dev; 49 + struct exynos_mbox *exynos_mbox = dev_get_drvdata(dev); 50 + struct exynos_mbox_msg *msg = data; 51 + 52 + if (msg->chan_id >= exynos_mbox->mbox->num_chans) { 53 + dev_err(dev, "Invalid channel ID %d\n", msg->chan_id); 54 + return -EINVAL; 55 + } 56 + 57 + if (msg->chan_type != EXYNOS_MBOX_CHAN_TYPE_DOORBELL) { 58 + dev_err(dev, "Unsupported channel type [%d]\n", msg->chan_type); 59 + return -EINVAL; 60 + }; 61 + 62 + writel(BIT(msg->chan_id), exynos_mbox->regs + EXYNOS_MBOX_INTGR1); 63 + 64 + return 0; 65 + } 66 + 67 + static const struct mbox_chan_ops exynos_mbox_chan_ops = { 68 + .send_data = exynos_mbox_send_data, 69 + }; 70 + 71 + static struct mbox_chan *exynos_mbox_of_xlate(struct mbox_controller *mbox, 72 + const struct of_phandle_args *sp) 73 + { 74 + int i; 75 + 76 + if (sp->args_count != 0) 77 + return ERR_PTR(-EINVAL); 78 + 79 + /* 80 + * Return the first available channel. When we don't pass the 81 + * channel ID from device tree, each channel populated by the driver is 82 + * just a software construct or a virtual channel. We use 'void *data' 83 + * in send_data() to pass the channel identifiers. 84 + */ 85 + for (i = 0; i < mbox->num_chans; i++) 86 + if (mbox->chans[i].cl == NULL) 87 + return &mbox->chans[i]; 88 + return ERR_PTR(-EINVAL); 89 + } 90 + 91 + static const struct of_device_id exynos_mbox_match[] = { 92 + { .compatible = "google,gs101-mbox" }, 93 + {}, 94 + }; 95 + MODULE_DEVICE_TABLE(of, exynos_mbox_match); 96 + 97 + static int exynos_mbox_probe(struct platform_device *pdev) 98 + { 99 + struct device *dev = &pdev->dev; 100 + struct exynos_mbox *exynos_mbox; 101 + struct mbox_controller *mbox; 102 + struct mbox_chan *chans; 103 + int i; 104 + 105 + exynos_mbox = devm_kzalloc(dev, sizeof(*exynos_mbox), GFP_KERNEL); 106 + if (!exynos_mbox) 107 + return -ENOMEM; 108 + 109 + mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL); 110 + if (!mbox) 111 + return -ENOMEM; 112 + 113 + chans = devm_kcalloc(dev, EXYNOS_MBOX_CHAN_COUNT, sizeof(*chans), 114 + GFP_KERNEL); 115 + if (!chans) 116 + return -ENOMEM; 117 + 118 + exynos_mbox->regs = devm_platform_ioremap_resource(pdev, 0); 119 + if (IS_ERR(exynos_mbox->regs)) 120 + return PTR_ERR(exynos_mbox->regs); 121 + 122 + exynos_mbox->pclk = devm_clk_get_enabled(dev, "pclk"); 123 + if (IS_ERR(exynos_mbox->pclk)) 124 + return dev_err_probe(dev, PTR_ERR(exynos_mbox->pclk), 125 + "Failed to enable clock.\n"); 126 + 127 + mbox->num_chans = EXYNOS_MBOX_CHAN_COUNT; 128 + mbox->chans = chans; 129 + mbox->dev = dev; 130 + mbox->ops = &exynos_mbox_chan_ops; 131 + mbox->of_xlate = exynos_mbox_of_xlate; 132 + 133 + for (i = 0; i < EXYNOS_MBOX_CHAN_COUNT; i++) 134 + chans[i].mbox = mbox; 135 + 136 + exynos_mbox->mbox = mbox; 137 + 138 + platform_set_drvdata(pdev, exynos_mbox); 139 + 140 + /* Mask out all interrupts. We support just polling channels for now. */ 141 + writel(EXYNOS_MBOX_INTMR0_MASK, exynos_mbox->regs + EXYNOS_MBOX_INTMR0); 142 + 143 + return devm_mbox_controller_register(dev, mbox); 144 + } 145 + 146 + static struct platform_driver exynos_mbox_driver = { 147 + .probe = exynos_mbox_probe, 148 + .driver = { 149 + .name = "exynos-acpm-mbox", 150 + .of_match_table = exynos_mbox_match, 151 + }, 152 + }; 153 + module_platform_driver(exynos_mbox_driver); 154 + 155 + MODULE_AUTHOR("Tudor Ambarus <tudor.ambarus@linaro.org>"); 156 + MODULE_DESCRIPTION("Samsung Exynos mailbox driver"); 157 + MODULE_LICENSE("GPL");
+504
drivers/mailbox/mailbox-mchp-ipc-sbi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Microchip Inter-Processor communication (IPC) driver 4 + * 5 + * Copyright (c) 2021 - 2024 Microchip Technology Inc. All rights reserved. 6 + * 7 + * Author: Valentina Fernandez <valentina.fernandezalanis@microchip.com> 8 + * 9 + */ 10 + 11 + #include <linux/io.h> 12 + #include <linux/err.h> 13 + #include <linux/smp.h> 14 + #include <linux/init.h> 15 + #include <linux/module.h> 16 + #include <linux/kernel.h> 17 + #include <linux/of_device.h> 18 + #include <linux/interrupt.h> 19 + #include <linux/dma-mapping.h> 20 + #include <linux/platform_device.h> 21 + #include <linux/mailbox/mchp-ipc.h> 22 + #include <asm/sbi.h> 23 + #include <asm/vendorid_list.h> 24 + 25 + #define IRQ_STATUS_BITS 12 26 + #define NUM_CHANS_PER_CLUSTER 5 27 + #define IPC_DMA_BIT_MASK 32 28 + #define SBI_EXT_MICROCHIP_TECHNOLOGY (SBI_EXT_VENDOR_START | \ 29 + MICROCHIP_VENDOR_ID) 30 + 31 + enum { 32 + SBI_EXT_IPC_PROBE = 0x100, 33 + SBI_EXT_IPC_CH_INIT, 34 + SBI_EXT_IPC_SEND, 35 + SBI_EXT_IPC_RECEIVE, 36 + SBI_EXT_IPC_STATUS, 37 + }; 38 + 39 + enum ipc_hw { 40 + MIV_IHC, 41 + }; 42 + 43 + /** 44 + * struct mchp_ipc_mbox_info - IPC probe message format 45 + * 46 + * @hw_type: IPC implementation available in the hardware 47 + * @num_channels: number of IPC channels available in the hardware 48 + * 49 + * Used to retrieve information on the IPC implementation 50 + * using the SBI_EXT_IPC_PROBE SBI function id. 51 + */ 52 + struct mchp_ipc_mbox_info { 53 + enum ipc_hw hw_type; 54 + u8 num_channels; 55 + }; 56 + 57 + /** 58 + * struct mchp_ipc_init - IPC channel init message format 59 + * 60 + * @max_msg_size: maxmimum message size in bytes of a given channel 61 + * 62 + * struct used by the SBI_EXT_IPC_CH_INIT SBI function id to get 63 + * the max message size in bytes of the initialized channel. 64 + */ 65 + struct mchp_ipc_init { 66 + u16 max_msg_size; 67 + }; 68 + 69 + /** 70 + * struct mchp_ipc_status - IPC status message format 71 + * 72 + * @status: interrupt status for all channels associated to a cluster 73 + * @cluster: specifies the cluster instance that originated an irq 74 + * 75 + * struct used by the SBI_EXT_IPC_STATUS SBI function id to get 76 + * the message present and message clear interrupt status for all the 77 + * channels associated to a cluster. 78 + */ 79 + struct mchp_ipc_status { 80 + u32 status; 81 + u8 cluster; 82 + }; 83 + 84 + /** 85 + * struct mchp_ipc_sbi_msg - IPC SBI payload message 86 + * 87 + * @buf_addr: physical address where the received data should be copied to 88 + * @size: maximum size(in bytes) that can be stored in the buffer pointed to by `buf` 89 + * @irq_type: mask representing the irq types that triggered an irq 90 + * 91 + * struct used by the SBI_EXT_IPC_SEND/SBI_EXT_IPC_RECEIVE SBI function 92 + * ids to send/receive a message from an associated processor using 93 + * the IPC. 94 + */ 95 + struct mchp_ipc_sbi_msg { 96 + u64 buf_addr; 97 + u16 size; 98 + u8 irq_type; 99 + }; 100 + 101 + struct mchp_ipc_cluster_cfg { 102 + void *buf_base; 103 + phys_addr_t buf_base_addr; 104 + int irq; 105 + }; 106 + 107 + struct mchp_ipc_sbi_mbox { 108 + struct device *dev; 109 + struct mbox_chan *chans; 110 + struct mchp_ipc_cluster_cfg *cluster_cfg; 111 + void *buf_base; 112 + unsigned long buf_base_addr; 113 + struct mbox_controller controller; 114 + enum ipc_hw hw_type; 115 + }; 116 + 117 + static int mchp_ipc_sbi_chan_send(u32 command, u32 channel, unsigned long address) 118 + { 119 + struct sbiret ret; 120 + 121 + ret = sbi_ecall(SBI_EXT_MICROCHIP_TECHNOLOGY, command, channel, 122 + address, 0, 0, 0, 0); 123 + 124 + if (ret.error) 125 + return sbi_err_map_linux_errno(ret.error); 126 + else 127 + return ret.value; 128 + } 129 + 130 + static int mchp_ipc_sbi_send(u32 command, unsigned long address) 131 + { 132 + struct sbiret ret; 133 + 134 + ret = sbi_ecall(SBI_EXT_MICROCHIP_TECHNOLOGY, command, address, 135 + 0, 0, 0, 0, 0); 136 + 137 + if (ret.error) 138 + return sbi_err_map_linux_errno(ret.error); 139 + else 140 + return ret.value; 141 + } 142 + 143 + static struct mchp_ipc_sbi_mbox *to_mchp_ipc_mbox(struct mbox_controller *mbox) 144 + { 145 + return container_of(mbox, struct mchp_ipc_sbi_mbox, controller); 146 + } 147 + 148 + static inline void mchp_ipc_prepare_receive_req(struct mbox_chan *chan) 149 + { 150 + struct mchp_ipc_sbi_chan *chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv; 151 + struct mchp_ipc_sbi_msg request; 152 + 153 + request.buf_addr = chan_info->msg_buf_rx_addr; 154 + request.size = chan_info->max_msg_size; 155 + memcpy(chan_info->buf_base_rx, &request, sizeof(struct mchp_ipc_sbi_msg)); 156 + } 157 + 158 + static inline void mchp_ipc_process_received_data(struct mbox_chan *chan, 159 + struct mchp_ipc_msg *ipc_msg) 160 + { 161 + struct mchp_ipc_sbi_chan *chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv; 162 + struct mchp_ipc_sbi_msg sbi_msg; 163 + 164 + memcpy(&sbi_msg, chan_info->buf_base_rx, sizeof(struct mchp_ipc_sbi_msg)); 165 + ipc_msg->buf = (u32 *)chan_info->msg_buf_rx; 166 + ipc_msg->size = sbi_msg.size; 167 + } 168 + 169 + static irqreturn_t mchp_ipc_cluster_aggr_isr(int irq, void *data) 170 + { 171 + struct mbox_chan *chan; 172 + struct mchp_ipc_sbi_chan *chan_info; 173 + struct mchp_ipc_sbi_mbox *ipc = (struct mchp_ipc_sbi_mbox *)data; 174 + struct mchp_ipc_msg ipc_msg; 175 + struct mchp_ipc_status status_msg; 176 + int ret; 177 + unsigned long hartid; 178 + u32 i, chan_index, chan_id; 179 + 180 + /* Find out the hart that originated the irq */ 181 + for_each_online_cpu(i) { 182 + hartid = cpuid_to_hartid_map(i); 183 + if (irq == ipc->cluster_cfg[hartid].irq) 184 + break; 185 + } 186 + 187 + status_msg.cluster = hartid; 188 + memcpy(ipc->cluster_cfg[hartid].buf_base, &status_msg, sizeof(struct mchp_ipc_status)); 189 + 190 + ret = mchp_ipc_sbi_send(SBI_EXT_IPC_STATUS, ipc->cluster_cfg[hartid].buf_base_addr); 191 + if (ret < 0) { 192 + dev_err_ratelimited(ipc->dev, "could not get IHC irq status ret=%d\n", ret); 193 + return IRQ_HANDLED; 194 + } 195 + 196 + memcpy(&status_msg, ipc->cluster_cfg[hartid].buf_base, sizeof(struct mchp_ipc_status)); 197 + 198 + /* 199 + * Iterate over each bit set in the IHC interrupt status register (IRQ_STATUS) to identify 200 + * the channel(s) that have a message to be processed/acknowledged. 201 + * The bits are organized in alternating format, where each pair of bits represents 202 + * the status of the message present and message clear interrupts for each cluster/hart 203 + * (from hart 0 to hart 5). Each cluster can have up to 5 fixed channels associated. 204 + */ 205 + 206 + for_each_set_bit(i, (unsigned long *)&status_msg.status, IRQ_STATUS_BITS) { 207 + /* Find out the destination hart that triggered the interrupt */ 208 + chan_index = i / 2; 209 + 210 + /* 211 + * The IP has no loopback channels, so we need to decrement the index when 212 + * the target hart has a greater index than our own 213 + */ 214 + if (chan_index >= status_msg.cluster) 215 + chan_index--; 216 + 217 + /* 218 + * Calculate the channel id given the hart and channel index. Channel IDs 219 + * are unique across all clusters of an IPC, and iterate contiguously 220 + * across all clusters. 221 + */ 222 + chan_id = status_msg.cluster * (NUM_CHANS_PER_CLUSTER + chan_index); 223 + 224 + chan = &ipc->chans[chan_id]; 225 + chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv; 226 + 227 + if (i % 2 == 0) { 228 + mchp_ipc_prepare_receive_req(chan); 229 + ret = mchp_ipc_sbi_chan_send(SBI_EXT_IPC_RECEIVE, chan_id, 230 + chan_info->buf_base_rx_addr); 231 + if (ret < 0) 232 + continue; 233 + 234 + mchp_ipc_process_received_data(chan, &ipc_msg); 235 + mbox_chan_received_data(&ipc->chans[chan_id], (void *)&ipc_msg); 236 + 237 + } else { 238 + ret = mchp_ipc_sbi_chan_send(SBI_EXT_IPC_RECEIVE, chan_id, 239 + chan_info->buf_base_rx_addr); 240 + mbox_chan_txdone(&ipc->chans[chan_id], ret); 241 + } 242 + } 243 + return IRQ_HANDLED; 244 + } 245 + 246 + static int mchp_ipc_send_data(struct mbox_chan *chan, void *data) 247 + { 248 + struct mchp_ipc_sbi_chan *chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv; 249 + const struct mchp_ipc_msg *msg = data; 250 + struct mchp_ipc_sbi_msg sbi_payload; 251 + 252 + memcpy(chan_info->msg_buf_tx, msg->buf, msg->size); 253 + sbi_payload.buf_addr = chan_info->msg_buf_tx_addr; 254 + sbi_payload.size = msg->size; 255 + memcpy(chan_info->buf_base_tx, &sbi_payload, sizeof(sbi_payload)); 256 + 257 + return mchp_ipc_sbi_chan_send(SBI_EXT_IPC_SEND, chan_info->id, chan_info->buf_base_tx_addr); 258 + } 259 + 260 + static int mchp_ipc_startup(struct mbox_chan *chan) 261 + { 262 + struct mchp_ipc_sbi_chan *chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv; 263 + struct mchp_ipc_sbi_mbox *ipc = to_mchp_ipc_mbox(chan->mbox); 264 + struct mchp_ipc_init ch_init_msg; 265 + int ret; 266 + 267 + /* 268 + * The TX base buffer is used to transmit two types of messages: 269 + * - struct mchp_ipc_init to initialize the channel 270 + * - struct mchp_ipc_sbi_msg to transmit user data/payload 271 + * Ensure the TX buffer size is large enough to accommodate either message type. 272 + */ 273 + size_t max_size = max(sizeof(struct mchp_ipc_init), sizeof(struct mchp_ipc_sbi_msg)); 274 + 275 + chan_info->buf_base_tx = kmalloc(max_size, GFP_KERNEL); 276 + if (!chan_info->buf_base_tx) { 277 + ret = -ENOMEM; 278 + goto fail; 279 + } 280 + 281 + chan_info->buf_base_tx_addr = __pa(chan_info->buf_base_tx); 282 + 283 + chan_info->buf_base_rx = kmalloc(max_size, GFP_KERNEL); 284 + if (!chan_info->buf_base_rx) { 285 + ret = -ENOMEM; 286 + goto fail_free_buf_base_tx; 287 + } 288 + 289 + chan_info->buf_base_rx_addr = __pa(chan_info->buf_base_rx); 290 + 291 + ret = mchp_ipc_sbi_chan_send(SBI_EXT_IPC_CH_INIT, chan_info->id, 292 + chan_info->buf_base_tx_addr); 293 + if (ret < 0) { 294 + dev_err(ipc->dev, "channel %u init failed\n", chan_info->id); 295 + goto fail_free_buf_base_rx; 296 + } 297 + 298 + memcpy(&ch_init_msg, chan_info->buf_base_tx, sizeof(struct mchp_ipc_init)); 299 + chan_info->max_msg_size = ch_init_msg.max_msg_size; 300 + 301 + chan_info->msg_buf_tx = kmalloc(chan_info->max_msg_size, GFP_KERNEL); 302 + if (!chan_info->msg_buf_tx) { 303 + ret = -ENOMEM; 304 + goto fail_free_buf_base_rx; 305 + } 306 + 307 + chan_info->msg_buf_tx_addr = __pa(chan_info->msg_buf_tx); 308 + 309 + chan_info->msg_buf_rx = kmalloc(chan_info->max_msg_size, GFP_KERNEL); 310 + if (!chan_info->msg_buf_rx) { 311 + ret = -ENOMEM; 312 + goto fail_free_buf_msg_tx; 313 + } 314 + 315 + chan_info->msg_buf_rx_addr = __pa(chan_info->msg_buf_rx); 316 + 317 + switch (ipc->hw_type) { 318 + case MIV_IHC: 319 + return 0; 320 + default: 321 + goto fail_free_buf_msg_rx; 322 + } 323 + 324 + if (ret) { 325 + dev_err(ipc->dev, "failed to register interrupt(s)\n"); 326 + goto fail_free_buf_msg_rx; 327 + } 328 + 329 + return ret; 330 + 331 + fail_free_buf_msg_rx: 332 + kfree(chan_info->msg_buf_rx); 333 + fail_free_buf_msg_tx: 334 + kfree(chan_info->msg_buf_tx); 335 + fail_free_buf_base_rx: 336 + kfree(chan_info->buf_base_rx); 337 + fail_free_buf_base_tx: 338 + kfree(chan_info->buf_base_tx); 339 + fail: 340 + return ret; 341 + } 342 + 343 + static void mchp_ipc_shutdown(struct mbox_chan *chan) 344 + { 345 + struct mchp_ipc_sbi_chan *chan_info = (struct mchp_ipc_sbi_chan *)chan->con_priv; 346 + 347 + kfree(chan_info->buf_base_tx); 348 + kfree(chan_info->buf_base_rx); 349 + kfree(chan_info->msg_buf_tx); 350 + kfree(chan_info->msg_buf_rx); 351 + } 352 + 353 + static const struct mbox_chan_ops mchp_ipc_ops = { 354 + .startup = mchp_ipc_startup, 355 + .send_data = mchp_ipc_send_data, 356 + .shutdown = mchp_ipc_shutdown, 357 + }; 358 + 359 + static struct mbox_chan *mchp_ipc_mbox_xlate(struct mbox_controller *controller, 360 + const struct of_phandle_args *spec) 361 + { 362 + struct mchp_ipc_sbi_mbox *ipc = to_mchp_ipc_mbox(controller); 363 + unsigned int chan_id = spec->args[0]; 364 + 365 + if (chan_id >= ipc->controller.num_chans) { 366 + dev_err(ipc->dev, "invalid channel id %d\n", chan_id); 367 + return ERR_PTR(-EINVAL); 368 + } 369 + 370 + return &ipc->chans[chan_id]; 371 + } 372 + 373 + static int mchp_ipc_get_cluster_aggr_irq(struct mchp_ipc_sbi_mbox *ipc) 374 + { 375 + struct platform_device *pdev = to_platform_device(ipc->dev); 376 + char *irq_name; 377 + int cpuid, ret; 378 + unsigned long hartid; 379 + bool irq_found = false; 380 + 381 + for_each_online_cpu(cpuid) { 382 + hartid = cpuid_to_hartid_map(cpuid); 383 + irq_name = devm_kasprintf(ipc->dev, GFP_KERNEL, "hart-%lu", hartid); 384 + ret = platform_get_irq_byname_optional(pdev, irq_name); 385 + if (ret <= 0) 386 + continue; 387 + 388 + ipc->cluster_cfg[hartid].irq = ret; 389 + ret = devm_request_irq(ipc->dev, ipc->cluster_cfg[hartid].irq, 390 + mchp_ipc_cluster_aggr_isr, IRQF_SHARED, 391 + "miv-ihc-irq", ipc); 392 + if (ret) 393 + return ret; 394 + 395 + ipc->cluster_cfg[hartid].buf_base = devm_kmalloc(ipc->dev, 396 + sizeof(struct mchp_ipc_status), 397 + GFP_KERNEL); 398 + 399 + if (!ipc->cluster_cfg[hartid].buf_base) 400 + return -ENOMEM; 401 + 402 + ipc->cluster_cfg[hartid].buf_base_addr = __pa(ipc->cluster_cfg[hartid].buf_base); 403 + 404 + irq_found = true; 405 + } 406 + 407 + return irq_found; 408 + } 409 + 410 + static int mchp_ipc_probe(struct platform_device *pdev) 411 + { 412 + struct device *dev = &pdev->dev; 413 + struct mchp_ipc_mbox_info ipc_info; 414 + struct mchp_ipc_sbi_mbox *ipc; 415 + struct mchp_ipc_sbi_chan *priv; 416 + bool irq_avail = false; 417 + int ret; 418 + u32 chan_id; 419 + 420 + ret = sbi_probe_extension(SBI_EXT_MICROCHIP_TECHNOLOGY); 421 + if (ret <= 0) 422 + return dev_err_probe(dev, ret, "Microchip SBI extension not detected\n"); 423 + 424 + ipc = devm_kzalloc(dev, sizeof(*ipc), GFP_KERNEL); 425 + if (!ipc) 426 + return -ENOMEM; 427 + 428 + platform_set_drvdata(pdev, ipc); 429 + 430 + ipc->buf_base = devm_kmalloc(dev, sizeof(struct mchp_ipc_mbox_info), GFP_KERNEL); 431 + if (!ipc->buf_base) 432 + return -ENOMEM; 433 + 434 + ipc->buf_base_addr = __pa(ipc->buf_base); 435 + 436 + ret = mchp_ipc_sbi_send(SBI_EXT_IPC_PROBE, ipc->buf_base_addr); 437 + if (ret < 0) 438 + return dev_err_probe(dev, ret, "could not probe IPC SBI service\n"); 439 + 440 + memcpy(&ipc_info, ipc->buf_base, sizeof(struct mchp_ipc_mbox_info)); 441 + ipc->controller.num_chans = ipc_info.num_channels; 442 + ipc->hw_type = ipc_info.hw_type; 443 + 444 + ipc->chans = devm_kcalloc(dev, ipc->controller.num_chans, sizeof(*ipc->chans), GFP_KERNEL); 445 + if (!ipc->chans) 446 + return -ENOMEM; 447 + 448 + ipc->dev = dev; 449 + ipc->controller.txdone_irq = true; 450 + ipc->controller.dev = ipc->dev; 451 + ipc->controller.ops = &mchp_ipc_ops; 452 + ipc->controller.chans = ipc->chans; 453 + ipc->controller.of_xlate = mchp_ipc_mbox_xlate; 454 + 455 + for (chan_id = 0; chan_id < ipc->controller.num_chans; chan_id++) { 456 + priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL); 457 + if (!priv) 458 + return -ENOMEM; 459 + 460 + ipc->chans[chan_id].con_priv = priv; 461 + priv->id = chan_id; 462 + } 463 + 464 + if (ipc->hw_type == MIV_IHC) { 465 + ipc->cluster_cfg = devm_kcalloc(dev, num_online_cpus(), 466 + sizeof(struct mchp_ipc_cluster_cfg), 467 + GFP_KERNEL); 468 + if (!ipc->cluster_cfg) 469 + return -ENOMEM; 470 + 471 + if (mchp_ipc_get_cluster_aggr_irq(ipc)) 472 + irq_avail = true; 473 + } 474 + 475 + if (!irq_avail) 476 + return dev_err_probe(dev, -ENODEV, "missing interrupt property\n"); 477 + 478 + ret = devm_mbox_controller_register(dev, &ipc->controller); 479 + if (ret) 480 + return dev_err_probe(dev, ret, 481 + "Inter-Processor communication (IPC) registration failed\n"); 482 + 483 + return 0; 484 + } 485 + 486 + static const struct of_device_id mchp_ipc_of_match[] = { 487 + {.compatible = "microchip,sbi-ipc", }, 488 + {} 489 + }; 490 + MODULE_DEVICE_TABLE(of, mchp_ipc_of_match); 491 + 492 + static struct platform_driver mchp_ipc_driver = { 493 + .driver = { 494 + .name = "microchip_ipc", 495 + .of_match_table = mchp_ipc_of_match, 496 + }, 497 + .probe = mchp_ipc_probe, 498 + }; 499 + 500 + module_platform_driver(mchp_ipc_driver); 501 + 502 + MODULE_LICENSE("GPL"); 503 + MODULE_AUTHOR("Valentina Fernandez <valentina.fernandezalanis@microchip.com>"); 504 + MODULE_DESCRIPTION("Microchip Inter-Processor Communication (IPC) driver");
+1 -1
drivers/mailbox/mailbox-mpfs.c
··· 251 251 return PTR_ERR(mbox->sysreg_scb); 252 252 253 253 mbox->mbox_base = devm_platform_ioremap_resource(pdev, 0); 254 - if (IS_ERR(mbox->ctrl_base)) 254 + if (IS_ERR(mbox->mbox_base)) 255 255 return PTR_ERR(mbox->mbox_base); 256 256 257 257 return 0;
+4 -2
drivers/mailbox/mailbox-th1520.c
··· 41 41 #ifdef CONFIG_PM_SLEEP 42 42 /* store MBOX context across system-wide suspend/resume transitions */ 43 43 struct th1520_mbox_context { 44 - u32 intr_mask[TH_1520_MBOX_CHANS - 1]; 44 + u32 intr_mask[TH_1520_MBOX_CHANS]; 45 45 }; 46 46 #endif 47 47 ··· 387 387 388 388 mapped = devm_ioremap(&pdev->dev, res->start + offset, 389 389 resource_size(res) - offset); 390 - if (IS_ERR(mapped)) 390 + if (!mapped) { 391 391 dev_err(&pdev->dev, "Failed to map resource: %s\n", res_name); 392 + return ERR_PTR(-ENOMEM); 393 + } 392 394 393 395 return mapped; 394 396 }
+1
drivers/mailbox/qcom-apcs-ipc-mailbox.c
··· 157 157 { .compatible = "qcom,sm6125-apcs-hmss-global", .data = &msm8994_apcs_data }, 158 158 { .compatible = "qcom,sm6115-apcs-hmss-global", .data = &msm8994_apcs_data }, 159 159 { .compatible = "qcom,ipq5332-apcs-apps-global", .data = &ipq6018_apcs_data }, 160 + { .compatible = "qcom,ipq5424-apcs-apps-global", .data = &msm8994_apcs_data }, 160 161 { .compatible = "qcom,ipq8074-apcs-apps-global", .data = &ipq6018_apcs_data }, 161 162 { .compatible = "qcom,sc7180-apss-shared", .data = &apps_shared_apcs_data }, 162 163 { .compatible = "qcom,sc8180x-apss-shared", .data = &apps_shared_apcs_data },
+16
drivers/mailbox/qcom-ipcc.c
··· 14 14 #include <dt-bindings/mailbox/qcom-ipcc.h> 15 15 16 16 /* IPCC Register offsets */ 17 + #define IPCC_REG_CONFIG 0x08 17 18 #define IPCC_REG_SEND_ID 0x0c 18 19 #define IPCC_REG_RECV_ID 0x10 19 20 #define IPCC_REG_RECV_SIGNAL_ENABLE 0x14 ··· 22 21 #define IPCC_REG_RECV_SIGNAL_CLEAR 0x1c 23 22 #define IPCC_REG_CLIENT_CLEAR 0x38 24 23 24 + #define IPCC_CLEAR_ON_RECV_RD BIT(0) 25 25 #define IPCC_SIGNAL_ID_MASK GENMASK(15, 0) 26 26 #define IPCC_CLIENT_ID_MASK GENMASK(31, 16) 27 27 ··· 276 274 static int qcom_ipcc_probe(struct platform_device *pdev) 277 275 { 278 276 struct qcom_ipcc *ipcc; 277 + u32 config_value; 279 278 static int id; 280 279 char *name; 281 280 int ret; ··· 290 287 ipcc->base = devm_platform_ioremap_resource(pdev, 0); 291 288 if (IS_ERR(ipcc->base)) 292 289 return PTR_ERR(ipcc->base); 290 + 291 + /* 292 + * It is possible that boot firmware is using the same IPCC instance 293 + * as of the HLOS and it has kept CLEAR_ON_RECV_RD set which basically 294 + * means Interrupt pending registers are cleared when RECV_ID is read. 295 + * The register automatically updates to the next pending interrupt/client 296 + * status based on priority. 297 + */ 298 + config_value = readl(ipcc->base + IPCC_REG_CONFIG); 299 + if (config_value & IPCC_CLEAR_ON_RECV_RD) { 300 + config_value &= ~(IPCC_CLEAR_ON_RECV_RD); 301 + writel(config_value, ipcc->base + IPCC_REG_CONFIG); 302 + } 293 303 294 304 ipcc->irq = platform_get_irq(pdev, 0); 295 305 if (ipcc->irq < 0)
+4 -2
drivers/mailbox/tegra-hsp.c
··· 388 388 value = tegra_hsp_channel_readl(channel, HSP_SM_SHRD_MBOX); 389 389 value &= ~HSP_SM_SHRD_MBOX_FULL; 390 390 msg = (void *)(unsigned long)value; 391 - mbox_chan_received_data(channel->chan, msg); 392 391 393 392 /* 394 393 * Need to clear all bits here since some producers, such as TCU, depend ··· 397 398 * explicitly, so we have to make sure we cover all possible cases. 398 399 */ 399 400 tegra_hsp_channel_writel(channel, 0x0, HSP_SM_SHRD_MBOX); 401 + 402 + mbox_chan_received_data(channel->chan, msg); 400 403 } 401 404 402 405 static const struct tegra_hsp_sm_ops tegra_hsp_sm_32bit_ops = { ··· 434 433 value[3] = tegra_hsp_channel_readl(channel, HSP_SHRD_MBOX_TYPE1_DATA3); 435 434 436 435 msg = (void *)(unsigned long)value; 437 - mbox_chan_received_data(channel->chan, msg); 438 436 439 437 /* 440 438 * Clear data registers and tag. ··· 443 443 tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_DATA2); 444 444 tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_DATA3); 445 445 tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_TAG); 446 + 447 + mbox_chan_received_data(channel->chan, msg); 446 448 } 447 449 448 450 static const struct tegra_hsp_sm_ops tegra_hsp_sm_128bit_ops = {
+1 -1
drivers/mailbox/zynqmp-ipi-mailbox.c
··· 905 905 { 906 906 struct device *dev = &pdev->dev; 907 907 struct device_node *nc, *np = pdev->dev.of_node; 908 - struct zynqmp_ipi_pdata __percpu *pdata; 908 + struct zynqmp_ipi_pdata *pdata; 909 909 struct of_phandle_args out_irq; 910 910 struct zynqmp_ipi_mbox *mbox; 911 911 int num_mboxes, ret = -EINVAL;
+19
include/linux/mailbox/exynos-message.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Exynos mailbox message. 4 + * 5 + * Copyright 2024 Linaro Ltd. 6 + */ 7 + 8 + #ifndef _LINUX_EXYNOS_MESSAGE_H_ 9 + #define _LINUX_EXYNOS_MESSAGE_H_ 10 + 11 + #define EXYNOS_MBOX_CHAN_TYPE_DOORBELL 0 12 + #define EXYNOS_MBOX_CHAN_TYPE_DATA 1 13 + 14 + struct exynos_mbox_msg { 15 + unsigned int chan_id; 16 + unsigned int chan_type; 17 + }; 18 + 19 + #endif /* _LINUX_EXYNOS_MESSAGE_H_ */
+33
include/linux/mailbox/mchp-ipc.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + *Copyright (c) 2024 Microchip Technology Inc. All rights reserved. 4 + */ 5 + 6 + #ifndef _LINUX_MCHP_IPC_H_ 7 + #define _LINUX_MCHP_IPC_H_ 8 + 9 + #include <linux/mailbox_controller.h> 10 + #include <linux/types.h> 11 + 12 + struct mchp_ipc_msg { 13 + u32 *buf; 14 + u16 size; 15 + }; 16 + 17 + struct mchp_ipc_sbi_chan { 18 + void *buf_base_tx; 19 + void *buf_base_rx; 20 + void *msg_buf_tx; 21 + void *msg_buf_rx; 22 + phys_addr_t buf_base_tx_addr; 23 + phys_addr_t buf_base_rx_addr; 24 + phys_addr_t msg_buf_tx_addr; 25 + phys_addr_t msg_buf_rx_addr; 26 + int chan_aggregated_irq; 27 + int mp_irq; 28 + int mc_irq; 29 + u32 id; 30 + u32 max_msg_size; 31 + }; 32 + 33 + #endif /* _LINUX_MCHP_IPC_H_ */