* [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers
@ 2025-07-02 5:13 Anup Patel
2025-07-02 5:13 ` [PATCH v7 01/24] dt-bindings: mailbox: Add bindings for RPMI shared memory transport Anup Patel
` (23 more replies)
0 siblings, 24 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
The SBI v3.0 (MPXY extension) [1] and RPMI v1.0 [2] specifications
are frozen and in public review at the RISC-V International.
Currently, most of the RPMI and MPXY drivers are in OpenSBI whereas
Linux only has SBI MPXY mailbox controller driver, RPMI clock driver
and RPMI system MSI driver This series also includes ACPI support
for SBI MPXY mailbox controller and RPMI system MSI drivers.
These patches can be found in the riscv_sbi_mpxy_mailbox_v7 branch
at: https://github.com/avpatel/linux.git
To test these patches, boot Linux on "virt,rpmi=on,aia=aplic-imsic"
machine with OpenSBI and QEMU from the dev-upstream branch at:
https://github.com/ventanamicro/opensbi.git
https://github.com/ventanamicro/qemu.git
[1] https://github.com/riscv-non-isa/riscv-sbi-doc/releases
[2] https://github.com/riscv-non-isa/riscv-rpmi/releases
Changes since v6:
- Rebased the series on Linux-6.16-rc4
- Added Stephen's Reviewed-by in appropriate patches
- Addressed Andy's comments on PATCH5, PATCH6, PATCH9, and PATCH14
- New PATCH6 in this series which is factored-out from PATCH7
Changes since v5:
- Rebased the series on Linux-6.16-rc2
- Added Conor's Reviewed-by in all DT binding patches
- Addressed Andy's comments on PATCH5
- Addressed Tglx's comments on PATCH12 and PATCH21
Changes since v4:
- Rebased the series on Linux-6.16-rc1
- Dropped PATCH1 since a similar change is already merged
https://lore.kernel.org/linux-riscv/20250523101932.1594077-4-cleger@rivosinc.com/
- Addressed Andy's comments on PATCH4, PATCH5, PATCH6, PATCH7,
PATCH13, and PATCH17
- Addressed Atish's comments on PATCH11 and PATCH12
- Addressed Conor's comments on PATCH9
Changes since v3:
- Rebased the series on Linux-6.15-rc7
- Updated PATCH2 DT bindings as-per Rob's suggestion
- Improved request_threaded_irq() usage in PATCH7
- Updated PATCH10 clk-rpmi driver as-per commments from Andy
- Updated PATCH13 irq-riscv-rpmi-sysmsi driver as-per comments
from Andy and Tglx
- Addressed ACPI related comments in PATCH14, PATCH15, PATCH18,
PATCH20 and PATCH21
Changes since v2:
- Dropped the "RFC" tag from series since the SBI v3.0 and
RPMI v1.0 specifications are now frozen
- Rebased the series on Linux-6.15-rc5
- Split PATCH8 of v2 into two patches adding separate DT
bindings for "riscv,rpmi-mpxy-clock" and "riscv,rpmi-clock"
- Split PATCH10 of v2 into two patches adding separate DT
bindings for "riscv,rpmi-mpxy-system-msi" and
"riscv,rpmi-system-msi"
- Addressed comments from TGLX on PATCH11 of v2 adding irqchip
driver for RPMI system MSI
- Addressed ACPI related comments in PATCH15 and PATCH16 of v2
- New PATCH17 and PATCH18 in this series
Changes since v1:
- Addressed DT bindings related comments in PATCH2, PATCH3, and
PATCH7 of v1 series
- Addressed comments in PATCH6 and PATCH8 of v1 series
- New PATCH6 in v2 series to allow fwnode based mailbox channel
request
- New PATCH10 and PATCH11 to add RPMI system MSI based interrupt
controller driver
- New PATCH12 to PATCH16 which adds ACPI support in SBI MPXY
mailbox driver and RPMI system MSI driver
- New PATCH17 to enable required kconfig option to allow graceful
shutdown on QEMU virt machine
Anup Patel (14):
dt-bindings: mailbox: Add bindings for RPMI shared memory transport
dt-bindings: mailbox: Add bindings for RISC-V SBI MPXY extension
RISC-V: Add defines for the SBI message proxy extension
mailbox: Add common header for RPMI messages sent via mailbox
mailbox: Allow controller specific mapping using fwnode
byteorder: Add memcpy_to_le32() and memcpy_from_le32()
mailbox: Add RISC-V SBI message proxy (MPXY) based mailbox driver
dt-bindings: clock: Add RPMI clock service message proxy bindings
dt-bindings: clock: Add RPMI clock service controller bindings
dt-bindings: Add RPMI system MSI message proxy bindings
dt-bindings: Add RPMI system MSI interrupt controller bindings
irqchip: Add driver for the RPMI system MSI service group
RISC-V: Enable GPIO keyboard and event device in RV64 defconfig
MAINTAINERS: Add entry for RISC-V RPMI and MPXY drivers
Rahul Pathak (1):
clk: Add clock driver for the RISC-V RPMI clock service group
Sunil V L (9):
ACPI: property: Refactor acpi_fwnode_get_reference_args()
ACPI: property: Add support for cells property
ACPI: scan: Update honor list for RPMI System MSI
ACPI: RISC-V: Create interrupt controller list in sorted order
ACPI: RISC-V: Add support to update gsi range
ACPI: RISC-V: Add RPMI System MSI to GSI mapping
irqchip/irq-riscv-imsic-early: Export imsic_acpi_get_fwnode()
mailbox/riscv-sbi-mpxy: Add ACPI support
irqchip/riscv-rpmi-sysmsi: Add ACPI support
.../bindings/clock/riscv,rpmi-clock.yaml | 64 ++
.../bindings/clock/riscv,rpmi-mpxy-clock.yaml | 64 ++
.../riscv,rpmi-mpxy-system-msi.yaml | 67 ++
.../riscv,rpmi-system-msi.yaml | 74 ++
.../mailbox/riscv,rpmi-shmem-mbox.yaml | 124 ++
.../bindings/mailbox/riscv,sbi-mpxy-mbox.yaml | 51 +
MAINTAINERS | 15 +
arch/riscv/configs/defconfig | 2 +
arch/riscv/include/asm/irq.h | 6 +
arch/riscv/include/asm/sbi.h | 63 +
drivers/acpi/property.c | 119 +-
drivers/acpi/riscv/irq.c | 75 +-
drivers/acpi/scan.c | 2 +
drivers/base/property.c | 2 +-
drivers/clk/Kconfig | 8 +
drivers/clk/Makefile | 1 +
drivers/clk/clk-rpmi.c | 616 ++++++++++
drivers/irqchip/Kconfig | 7 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-riscv-imsic-early.c | 2 +
drivers/irqchip/irq-riscv-rpmi-sysmsi.c | 324 ++++++
drivers/mailbox/Kconfig | 11 +
drivers/mailbox/Makefile | 2 +
drivers/mailbox/mailbox.c | 65 +-
drivers/mailbox/riscv-sbi-mpxy-mbox.c | 1012 +++++++++++++++++
include/linux/byteorder/generic.h | 16 +
include/linux/mailbox/riscv-rpmi-message.h | 243 ++++
include/linux/mailbox_controller.h | 3 +
include/linux/wordpart.h | 16 +
29 files changed, 2973 insertions(+), 82 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/riscv,rpmi-clock.yaml
create mode 100644 Documentation/devicetree/bindings/clock/riscv,rpmi-mpxy-clock.yaml
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,rpmi-mpxy-system-msi.yaml
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,rpmi-system-msi.yaml
create mode 100644 Documentation/devicetree/bindings/mailbox/riscv,rpmi-shmem-mbox.yaml
create mode 100644 Documentation/devicetree/bindings/mailbox/riscv,sbi-mpxy-mbox.yaml
create mode 100644 drivers/clk/clk-rpmi.c
create mode 100644 drivers/irqchip/irq-riscv-rpmi-sysmsi.c
create mode 100644 drivers/mailbox/riscv-sbi-mpxy-mbox.c
create mode 100644 include/linux/mailbox/riscv-rpmi-message.h
--
2.43.0
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH v7 01/24] dt-bindings: mailbox: Add bindings for RPMI shared memory transport
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 02/24] dt-bindings: mailbox: Add bindings for RISC-V SBI MPXY extension Anup Patel
` (22 subsequent siblings)
23 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel, Conor Dooley
Add device tree bindings for the common RISC-V Platform Management
Interface (RPMI) shared memory transport as a mailbox controller.
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
.../mailbox/riscv,rpmi-shmem-mbox.yaml | 124 ++++++++++++++++++
1 file changed, 124 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mailbox/riscv,rpmi-shmem-mbox.yaml
diff --git a/Documentation/devicetree/bindings/mailbox/riscv,rpmi-shmem-mbox.yaml b/Documentation/devicetree/bindings/mailbox/riscv,rpmi-shmem-mbox.yaml
new file mode 100644
index 000000000000..3aabc52a0c03
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/riscv,rpmi-shmem-mbox.yaml
@@ -0,0 +1,124 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/riscv,rpmi-shmem-mbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V Platform Management Interface (RPMI) shared memory mailbox
+
+maintainers:
+ - Anup Patel <anup@brainfault.org>
+
+description: |
+ The RISC-V Platform Management Interface (RPMI) [1] defines a common shared
+ memory based RPMI transport. This RPMI shared memory transport integrates as
+ mailbox controller in the SBI implementation or supervisor software whereas
+ each RPMI service group is mailbox client in the SBI implementation and
+ supervisor software.
+
+ ===========================================
+ References
+ ===========================================
+
+ [1] RISC-V Platform Management Interface (RPMI) v1.0 (or higher)
+ https://github.com/riscv-non-isa/riscv-rpmi/releases
+
+properties:
+ compatible:
+ const: riscv,rpmi-shmem-mbox
+
+ reg:
+ minItems: 2
+ items:
+ - description: A2P request queue base address
+ - description: P2A acknowledgment queue base address
+ - description: P2A request queue base address
+ - description: A2P acknowledgment queue base address
+ - description: A2P doorbell address
+
+ reg-names:
+ minItems: 2
+ items:
+ - const: a2p-req
+ - const: p2a-ack
+ - enum: [ p2a-req, a2p-doorbell ]
+ - const: a2p-ack
+ - const: a2p-doorbell
+
+ interrupts:
+ maxItems: 1
+ description:
+ The RPMI shared memory transport supports P2A doorbell as a wired
+ interrupt and this property specifies the interrupt source.
+
+ msi-parent:
+ description:
+ The RPMI shared memory transport supports P2A doorbell as a system MSI
+ and this property specifies the target MSI controller.
+
+ riscv,slot-size:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 64
+ description:
+ Power-of-2 RPMI slot size of the RPMI shared memory transport.
+
+ riscv,a2p-doorbell-value:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ default: 0x1
+ description:
+ Value written to the 32-bit A2P doorbell register.
+
+ riscv,p2a-doorbell-sysmsi-index:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ The RPMI shared memory transport supports P2A doorbell as a system MSI
+ and this property specifies system MSI index to be used for configuring
+ the P2A doorbell MSI.
+
+ "#mbox-cells":
+ const: 1
+ description:
+ The first cell specifies RPMI service group ID.
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - riscv,slot-size
+ - "#mbox-cells"
+
+anyOf:
+ - required:
+ - interrupts
+ - required:
+ - msi-parent
+
+additionalProperties: false
+
+examples:
+ - |
+ // Example 1 (RPMI shared memory with only 2 queues):
+ mailbox@10080000 {
+ compatible = "riscv,rpmi-shmem-mbox";
+ reg = <0x10080000 0x10000>,
+ <0x10090000 0x10000>;
+ reg-names = "a2p-req", "p2a-ack";
+ msi-parent = <&imsic_mlevel>;
+ riscv,slot-size = <64>;
+ #mbox-cells = <1>;
+ };
+ - |
+ // Example 2 (RPMI shared memory with only 4 queues):
+ mailbox@10001000 {
+ compatible = "riscv,rpmi-shmem-mbox";
+ reg = <0x10001000 0x800>,
+ <0x10001800 0x800>,
+ <0x10002000 0x800>,
+ <0x10002800 0x800>,
+ <0x10003000 0x4>;
+ reg-names = "a2p-req", "p2a-ack", "p2a-req", "a2p-ack", "a2p-doorbell";
+ msi-parent = <&imsic_mlevel>;
+ riscv,slot-size = <64>;
+ riscv,a2p-doorbell-value = <0x00008000>;
+ #mbox-cells = <1>;
+ };
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 02/24] dt-bindings: mailbox: Add bindings for RISC-V SBI MPXY extension
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
2025-07-02 5:13 ` [PATCH v7 01/24] dt-bindings: mailbox: Add bindings for RPMI shared memory transport Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 03/24] RISC-V: Add defines for the SBI message proxy extension Anup Patel
` (21 subsequent siblings)
23 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel, Conor Dooley
Add device tree bindings for the RISC-V SBI Message Proxy (MPXY)
extension as a mailbox controller.
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
.../bindings/mailbox/riscv,sbi-mpxy-mbox.yaml | 51 +++++++++++++++++++
1 file changed, 51 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mailbox/riscv,sbi-mpxy-mbox.yaml
diff --git a/Documentation/devicetree/bindings/mailbox/riscv,sbi-mpxy-mbox.yaml b/Documentation/devicetree/bindings/mailbox/riscv,sbi-mpxy-mbox.yaml
new file mode 100644
index 000000000000..061437a0b45a
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/riscv,sbi-mpxy-mbox.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/riscv,sbi-mpxy-mbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V SBI Message Proxy (MPXY) extension based mailbox
+
+maintainers:
+ - Anup Patel <anup@brainfault.org>
+
+description: |
+ The RISC-V SBI Message Proxy (MPXY) extension [1] allows supervisor
+ software to send messages through the SBI implementation (M-mode
+ firmware or HS-mode hypervisor). The underlying message protocol
+ and message format used by the supervisor software could be some
+ other standard protocol compatible with the SBI MPXY extension
+ (such as RISC-V Platform Management Interface (RPMI) [2]).
+
+ ===========================================
+ References
+ ===========================================
+
+ [1] RISC-V Supervisor Binary Interface (SBI) v3.0 (or higher)
+ https://github.com/riscv-non-isa/riscv-sbi-doc/releases
+
+ [2] RISC-V Platform Management Interface (RPMI) v1.0 (or higher)
+ https://github.com/riscv-non-isa/riscv-rpmi/releases
+
+properties:
+ compatible:
+ const: riscv,sbi-mpxy-mbox
+
+ "#mbox-cells":
+ const: 2
+ description:
+ The first cell specifies channel_id of the SBI MPXY channel,
+ the second cell specifies MSG_PROT_ID of the SBI MPXY channel
+
+required:
+ - compatible
+ - "#mbox-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ mailbox {
+ compatible = "riscv,sbi-mpxy-mbox";
+ #mbox-cells = <2>;
+ };
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 03/24] RISC-V: Add defines for the SBI message proxy extension
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
2025-07-02 5:13 ` [PATCH v7 01/24] dt-bindings: mailbox: Add bindings for RPMI shared memory transport Anup Patel
2025-07-02 5:13 ` [PATCH v7 02/24] dt-bindings: mailbox: Add bindings for RISC-V SBI MPXY extension Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 12:03 ` Andy Shevchenko
2025-07-02 12:06 ` Andy Shevchenko
2025-07-02 5:13 ` [PATCH v7 04/24] mailbox: Add common header for RPMI messages sent via mailbox Anup Patel
` (20 subsequent siblings)
23 siblings, 2 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel, Atish Patra
Add defines for the new SBI message proxy extension which is part
of the SBI v3.0 specification.
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Co-developed-by: Rahul Pathak <rpathak@ventanamicro.com>
Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
arch/riscv/include/asm/sbi.h | 63 ++++++++++++++++++++++++++++++++++++
include/linux/wordpart.h | 8 +++++
2 files changed, 71 insertions(+)
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index 341e74238aa0..59a7285ff956 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -10,6 +10,7 @@
#include <linux/types.h>
#include <linux/cpumask.h>
#include <linux/jump_label.h>
+#include <linux/wordpart.h>
#ifdef CONFIG_RISCV_SBI
enum sbi_ext_id {
@@ -36,6 +37,7 @@ enum sbi_ext_id {
SBI_EXT_STA = 0x535441,
SBI_EXT_NACL = 0x4E41434C,
SBI_EXT_FWFT = 0x46574654,
+ SBI_EXT_MPXY = 0x4D505859,
/* Experimentals extensions must lie within this range */
SBI_EXT_EXPERIMENTAL_START = 0x08000000,
@@ -430,6 +432,67 @@ enum sbi_fwft_feature_t {
#define SBI_FWFT_SET_FLAG_LOCK BIT(0)
+enum sbi_ext_mpxy_fid {
+ SBI_EXT_MPXY_GET_SHMEM_SIZE,
+ SBI_EXT_MPXY_SET_SHMEM,
+ SBI_EXT_MPXY_GET_CHANNEL_IDS,
+ SBI_EXT_MPXY_READ_ATTRS,
+ SBI_EXT_MPXY_WRITE_ATTRS,
+ SBI_EXT_MPXY_SEND_MSG_WITH_RESP,
+ SBI_EXT_MPXY_SEND_MSG_WITHOUT_RESP,
+ SBI_EXT_MPXY_GET_NOTIFICATION_EVENTS
+};
+
+enum sbi_mpxy_attribute_id {
+ /* Standard channel attributes managed by MPXY framework */
+ SBI_MPXY_ATTR_MSG_PROT_ID = 0x00000000,
+ SBI_MPXY_ATTR_MSG_PROT_VER = 0x00000001,
+ SBI_MPXY_ATTR_MSG_MAX_LEN = 0x00000002,
+ SBI_MPXY_ATTR_MSG_SEND_TIMEOUT = 0x00000003,
+ SBI_MPXY_ATTR_MSG_COMPLETION_TIMEOUT = 0x00000004,
+ SBI_MPXY_ATTR_CHANNEL_CAPABILITY = 0x00000005,
+ SBI_MPXY_ATTR_SSE_EVENT_ID = 0x00000006,
+ SBI_MPXY_ATTR_MSI_CONTROL = 0x00000007,
+ SBI_MPXY_ATTR_MSI_ADDR_LO = 0x00000008,
+ SBI_MPXY_ATTR_MSI_ADDR_HI = 0x00000009,
+ SBI_MPXY_ATTR_MSI_DATA = 0x0000000A,
+ SBI_MPXY_ATTR_EVENTS_STATE_CONTROL = 0x0000000B,
+ SBI_MPXY_ATTR_STD_ATTR_MAX_IDX,
+ /*
+ * Message protocol specific attributes, managed by
+ * the message protocol specification.
+ */
+ SBI_MPXY_ATTR_MSGPROTO_ATTR_START = 0x80000000,
+ SBI_MPXY_ATTR_MSGPROTO_ATTR_END = 0xffffffff
+};
+
+/* Possible values of MSG_PROT_ID attribute */
+enum sbi_mpxy_msgproto_id {
+ SBI_MPXY_MSGPROTO_RPMI_ID = 0x0
+};
+
+/* RPMI message protocol specific MPXY attributes */
+enum sbi_mpxy_rpmi_attribute_id {
+ SBI_MPXY_RPMI_ATTR_SERVICEGROUP_ID = SBI_MPXY_ATTR_MSGPROTO_ATTR_START,
+ SBI_MPXY_RPMI_ATTR_SERVICEGROUP_VERSION,
+ SBI_MPXY_RPMI_ATTR_IMPL_ID,
+ SBI_MPXY_RPMI_ATTR_IMPL_VERSION,
+ SBI_MPXY_RPMI_ATTR_MAX_ID
+};
+
+/* Encoding of MSG_PROT_VER attribute */
+#define SBI_MPXY_MSG_PROT_VER_MAJOR(__ver) upper_16_bits(__ver)
+#define SBI_MPXY_MSG_PROT_VER_MINOR(__ver) lower_16_bits(__ver)
+#define SBI_MPXY_MSG_PROT_MKVER(__maj, __min) make_u32_from_two_u16(__maj, __min)
+
+/* Capabilities available through CHANNEL_CAPABILITY attribute */
+#define SBI_MPXY_CHAN_CAP_MSI BIT(0)
+#define SBI_MPXY_CHAN_CAP_SSE BIT(1)
+#define SBI_MPXY_CHAN_CAP_EVENTS_STATE BIT(2)
+#define SBI_MPXY_CHAN_CAP_SEND_WITH_RESP BIT(3)
+#define SBI_MPXY_CHAN_CAP_SEND_WITHOUT_RESP BIT(4)
+#define SBI_MPXY_CHAN_CAP_GET_NOTIFICATIONS BIT(5)
+
/* SBI spec version fields */
#define SBI_SPEC_VERSION_DEFAULT 0x1
#define SBI_SPEC_VERSION_MAJOR_SHIFT 24
diff --git a/include/linux/wordpart.h b/include/linux/wordpart.h
index 5a7b97bb7c95..ed8717730037 100644
--- a/include/linux/wordpart.h
+++ b/include/linux/wordpart.h
@@ -31,6 +31,14 @@
*/
#define lower_16_bits(n) ((u16)((n) & 0xffff))
+/**
+ * make_u32_from_two_u16 - return u32 number by combining
+ * two u16 numbers.
+ * @hi: upper 16 bit number
+ * @lo: lower 16 bit number
+ */
+#define make_u32_from_two_u16(hi, lo) (((u32)(hi) << 16) | (u32)(lo))
+
/**
* REPEAT_BYTE - repeat the value @x multiple times as an unsigned long value
* @x: value to repeat
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 04/24] mailbox: Add common header for RPMI messages sent via mailbox
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (2 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 03/24] RISC-V: Add defines for the SBI message proxy extension Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 05/24] mailbox: Allow controller specific mapping using fwnode Anup Patel
` (19 subsequent siblings)
23 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
The RPMI based mailbox controller drivers and mailbox clients need to
share defines related to RPMI messages over mailbox interface so add
a common header for this purpose.
Co-developed-by: Rahul Pathak <rpathak@ventanamicro.com>
Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
include/linux/mailbox/riscv-rpmi-message.h | 214 +++++++++++++++++++++
1 file changed, 214 insertions(+)
create mode 100644 include/linux/mailbox/riscv-rpmi-message.h
diff --git a/include/linux/mailbox/riscv-rpmi-message.h b/include/linux/mailbox/riscv-rpmi-message.h
new file mode 100644
index 000000000000..3f4c73529aa5
--- /dev/null
+++ b/include/linux/mailbox/riscv-rpmi-message.h
@@ -0,0 +1,214 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (C) 2025 Ventana Micro Systems Inc. */
+
+#ifndef _LINUX_RISCV_RPMI_MESSAGE_H_
+#define _LINUX_RISCV_RPMI_MESSAGE_H_
+
+#include <linux/errno.h>
+#include <linux/mailbox_client.h>
+#include <linux/types.h>
+#include <linux/wordpart.h>
+
+/* RPMI version encode/decode macros */
+#define RPMI_VER_MAJOR(__ver) upper_16_bits(__ver)
+#define RPMI_VER_MINOR(__ver) lower_16_bits(__ver)
+#define RPMI_MKVER(__maj, __min) make_u32_from_two_u16(__maj, __min)
+
+/* RPMI message header */
+struct rpmi_message_header {
+ __le16 servicegroup_id;
+ u8 service_id;
+ u8 flags;
+ __le16 datalen;
+ __le16 token;
+};
+
+/* RPMI message */
+struct rpmi_message {
+ struct rpmi_message_header header;
+ u8 data[];
+};
+
+/* RPMI notification event */
+struct rpmi_notification_event {
+ __le16 event_datalen;
+ u8 event_id;
+ u8 reserved;
+ u8 event_data[];
+};
+
+/* RPMI error codes */
+enum rpmi_error_codes {
+ RPMI_SUCCESS = 0,
+ RPMI_ERR_FAILED = -1,
+ RPMI_ERR_NOTSUPP = -2,
+ RPMI_ERR_INVALID_PARAM = -3,
+ RPMI_ERR_DENIED = -4,
+ RPMI_ERR_INVALID_ADDR = -5,
+ RPMI_ERR_ALREADY = -6,
+ RPMI_ERR_EXTENSION = -7,
+ RPMI_ERR_HW_FAULT = -8,
+ RPMI_ERR_BUSY = -9,
+ RPMI_ERR_INVALID_STATE = -10,
+ RPMI_ERR_BAD_RANGE = -11,
+ RPMI_ERR_TIMEOUT = -12,
+ RPMI_ERR_IO = -13,
+ RPMI_ERR_NO_DATA = -14,
+ RPMI_ERR_RESERVED_START = -15,
+ RPMI_ERR_RESERVED_END = -127,
+ RPMI_ERR_VENDOR_START = -128,
+};
+
+static inline int rpmi_to_linux_error(int rpmi_error)
+{
+ switch (rpmi_error) {
+ case RPMI_SUCCESS:
+ return 0;
+ case RPMI_ERR_INVALID_PARAM:
+ case RPMI_ERR_BAD_RANGE:
+ case RPMI_ERR_INVALID_STATE:
+ return -EINVAL;
+ case RPMI_ERR_DENIED:
+ return -EPERM;
+ case RPMI_ERR_INVALID_ADDR:
+ case RPMI_ERR_HW_FAULT:
+ return -EFAULT;
+ case RPMI_ERR_ALREADY:
+ return -EALREADY;
+ case RPMI_ERR_BUSY:
+ return -EBUSY;
+ case RPMI_ERR_TIMEOUT:
+ return -ETIMEDOUT;
+ case RPMI_ERR_IO:
+ return -ECOMM;
+ case RPMI_ERR_FAILED:
+ case RPMI_ERR_NOTSUPP:
+ case RPMI_ERR_NO_DATA:
+ case RPMI_ERR_EXTENSION:
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+/* RPMI Linux mailbox attribute IDs */
+enum rpmi_mbox_attribute_id {
+ RPMI_MBOX_ATTR_SPEC_VERSION,
+ RPMI_MBOX_ATTR_MAX_MSG_DATA_SIZE,
+ RPMI_MBOX_ATTR_SERVICEGROUP_ID,
+ RPMI_MBOX_ATTR_SERVICEGROUP_VERSION,
+ RPMI_MBOX_ATTR_IMPL_ID,
+ RPMI_MBOX_ATTR_IMPL_VERSION,
+ RPMI_MBOX_ATTR_MAX_ID
+};
+
+/* RPMI Linux mailbox message types */
+enum rpmi_mbox_message_type {
+ RPMI_MBOX_MSG_TYPE_GET_ATTRIBUTE,
+ RPMI_MBOX_MSG_TYPE_SET_ATTRIBUTE,
+ RPMI_MBOX_MSG_TYPE_SEND_WITH_RESPONSE,
+ RPMI_MBOX_MSG_TYPE_SEND_WITHOUT_RESPONSE,
+ RPMI_MBOX_MSG_TYPE_NOTIFICATION_EVENT,
+ RPMI_MBOX_MSG_MAX_TYPE
+};
+
+/* RPMI Linux mailbox message instance */
+struct rpmi_mbox_message {
+ enum rpmi_mbox_message_type type;
+ union {
+ struct {
+ enum rpmi_mbox_attribute_id id;
+ u32 value;
+ } attr;
+
+ struct {
+ u32 service_id;
+ void *request;
+ unsigned long request_len;
+ void *response;
+ unsigned long max_response_len;
+ unsigned long out_response_len;
+ } data;
+
+ struct {
+ u16 event_datalen;
+ u8 event_id;
+ u8 *event_data;
+ } notif;
+ };
+ int error;
+};
+
+/* RPMI Linux mailbox message helper routines */
+static inline void rpmi_mbox_init_get_attribute(struct rpmi_mbox_message *msg,
+ enum rpmi_mbox_attribute_id id)
+{
+ msg->type = RPMI_MBOX_MSG_TYPE_GET_ATTRIBUTE;
+ msg->attr.id = id;
+ msg->attr.value = 0;
+ msg->error = 0;
+}
+
+static inline void rpmi_mbox_init_set_attribute(struct rpmi_mbox_message *msg,
+ enum rpmi_mbox_attribute_id id,
+ u32 value)
+{
+ msg->type = RPMI_MBOX_MSG_TYPE_SET_ATTRIBUTE;
+ msg->attr.id = id;
+ msg->attr.value = value;
+ msg->error = 0;
+}
+
+static inline void rpmi_mbox_init_send_with_response(struct rpmi_mbox_message *msg,
+ u32 service_id,
+ void *request,
+ unsigned long request_len,
+ void *response,
+ unsigned long max_response_len)
+{
+ msg->type = RPMI_MBOX_MSG_TYPE_SEND_WITH_RESPONSE;
+ msg->data.service_id = service_id;
+ msg->data.request = request;
+ msg->data.request_len = request_len;
+ msg->data.response = response;
+ msg->data.max_response_len = max_response_len;
+ msg->data.out_response_len = 0;
+ msg->error = 0;
+}
+
+static inline void rpmi_mbox_init_send_without_response(struct rpmi_mbox_message *msg,
+ u32 service_id,
+ void *request,
+ unsigned long request_len)
+{
+ msg->type = RPMI_MBOX_MSG_TYPE_SEND_WITHOUT_RESPONSE;
+ msg->data.service_id = service_id;
+ msg->data.request = request;
+ msg->data.request_len = request_len;
+ msg->data.response = NULL;
+ msg->data.max_response_len = 0;
+ msg->data.out_response_len = 0;
+ msg->error = 0;
+}
+
+static inline void *rpmi_mbox_get_msg_response(struct rpmi_mbox_message *msg)
+{
+ return msg ? msg->data.response : NULL;
+}
+
+static inline int rpmi_mbox_send_message(struct mbox_chan *chan,
+ struct rpmi_mbox_message *msg)
+{
+ int ret;
+
+ /* Send message for the underlying mailbox channel */
+ ret = mbox_send_message(chan, msg);
+ if (ret < 0)
+ return ret;
+
+ /* Explicitly signal txdone for mailbox channel */
+ ret = msg->error;
+ mbox_client_txdone(chan, ret);
+ return ret;
+}
+
+#endif /* _LINUX_RISCV_RPMI_MESSAGE_H_ */
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 05/24] mailbox: Allow controller specific mapping using fwnode
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (3 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 04/24] mailbox: Add common header for RPMI messages sent via mailbox Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 12:32 ` Andy Shevchenko
2025-07-02 5:13 ` [PATCH v7 06/24] byteorder: Add memcpy_to_le32() and memcpy_from_le32() Anup Patel
` (18 subsequent siblings)
23 siblings, 1 reply; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
Introduce optional fw_node() callback which allows a mailbox controller
driver to provide controller specific mapping using fwnode.
The Linux OF framework already implements fwnode operations for the
Linux DD framework so the fw_xlate() callback works fine with device
tree as well.
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
drivers/mailbox/mailbox.c | 65 ++++++++++++++++++------------
include/linux/mailbox_controller.h | 3 ++
2 files changed, 43 insertions(+), 25 deletions(-)
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index 5cd8ae222073..2acc6ec229a4 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
+#include <linux/property.h>
#include <linux/spinlock.h>
#include "mailbox.h"
@@ -383,34 +384,56 @@ EXPORT_SYMBOL_GPL(mbox_bind_client);
*/
struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)
{
- struct device *dev = cl->dev;
+ struct fwnode_reference_args fwspec;
+ struct fwnode_handle *fwnode;
struct mbox_controller *mbox;
struct of_phandle_args spec;
struct mbox_chan *chan;
+ struct device *dev;
+ unsigned int i;
int ret;
- if (!dev || !dev->of_node) {
- pr_debug("%s: No owner device node\n", __func__);
+ dev = cl->dev;
+ if (!dev) {
+ pr_debug("No owner device\n");
return ERR_PTR(-ENODEV);
}
- ret = of_parse_phandle_with_args(dev->of_node, "mboxes", "#mbox-cells",
- index, &spec);
+ fwnode = dev_fwnode(dev);
+ if (!fwnode) {
+ dev_dbg(dev, "No owner fwnode\n");
+ return ERR_PTR(-ENODEV);
+ }
+
+ ret = fwnode_property_get_reference_args(fwnode, "mboxes", "#mbox-cells",
+ 0, index, &fwspec);
if (ret) {
- dev_err(dev, "%s: can't parse \"mboxes\" property\n", __func__);
+ dev_err(dev, "%s: can't parse \"%s\" property\n", __func__, "mboxes");
return ERR_PTR(ret);
}
+ spec.np = to_of_node(fwspec.fwnode);
+ spec.args_count = fwspec.nargs;
+ for (i = 0; i < spec.args_count; i++)
+ spec.args[i] = fwspec.args[i];
+
scoped_guard(mutex, &con_mutex) {
chan = ERR_PTR(-EPROBE_DEFER);
- list_for_each_entry(mbox, &mbox_cons, node)
- if (mbox->dev->of_node == spec.np) {
- chan = mbox->of_xlate(mbox, &spec);
- if (!IS_ERR(chan))
- break;
+ list_for_each_entry(mbox, &mbox_cons, node) {
+ if (device_match_fwnode(mbox->dev, fwspec.fwnode)) {
+ if (mbox->fw_xlate) {
+ chan = mbox->fw_xlate(mbox, &fwspec);
+ if (!IS_ERR(chan))
+ break;
+ } else if (mbox->of_xlate) {
+ chan = mbox->of_xlate(mbox, &spec);
+ if (!IS_ERR(chan))
+ break;
+ }
}
+ }
- of_node_put(spec.np);
+ fwnode_handle_put(fwspec.fwnode);
if (IS_ERR(chan))
return chan;
@@ -427,15 +450,8 @@ EXPORT_SYMBOL_GPL(mbox_request_channel);
struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
const char *name)
{
- struct device_node *np = cl->dev->of_node;
- int index;
-
- if (!np) {
- dev_err(cl->dev, "%s() currently only supports DT\n", __func__);
- return ERR_PTR(-EINVAL);
- }
+ int index = device_property_match_string(cl->dev, "mbox-names", name);
- index = of_property_match_string(np, "mbox-names", name);
if (index < 0) {
dev_err(cl->dev, "%s() could not locate channel named \"%s\"\n",
__func__, name);
@@ -470,9 +486,8 @@ void mbox_free_channel(struct mbox_chan *chan)
}
EXPORT_SYMBOL_GPL(mbox_free_channel);
-static struct mbox_chan *
-of_mbox_index_xlate(struct mbox_controller *mbox,
- const struct of_phandle_args *sp)
+static struct mbox_chan *fw_mbox_index_xlate(struct mbox_controller *mbox,
+ const struct fwnode_reference_args *sp)
{
int ind = sp->args[0];
@@ -523,8 +538,8 @@ int mbox_controller_register(struct mbox_controller *mbox)
spin_lock_init(&chan->lock);
}
- if (!mbox->of_xlate)
- mbox->of_xlate = of_mbox_index_xlate;
+ if (!mbox->fw_xlate && !mbox->of_xlate)
+ mbox->fw_xlate = fw_mbox_index_xlate;
scoped_guard(mutex, &con_mutex)
list_add_tail(&mbox->node, &mbox_cons);
diff --git a/include/linux/mailbox_controller.h b/include/linux/mailbox_controller.h
index ad01c4082358..80a427c7ca29 100644
--- a/include/linux/mailbox_controller.h
+++ b/include/linux/mailbox_controller.h
@@ -66,6 +66,7 @@ struct mbox_chan_ops {
* no interrupt rises. Ignored if 'txdone_irq' is set.
* @txpoll_period: If 'txdone_poll' is in effect, the API polls for
* last TX's status after these many millisecs
+ * @fw_xlate: Controller driver specific mapping of channel via fwnode
* @of_xlate: Controller driver specific mapping of channel via DT
* @poll_hrt: API private. hrtimer used to poll for TXDONE on all
* channels.
@@ -79,6 +80,8 @@ struct mbox_controller {
bool txdone_irq;
bool txdone_poll;
unsigned txpoll_period;
+ struct mbox_chan *(*fw_xlate)(struct mbox_controller *mbox,
+ const struct fwnode_reference_args *sp);
struct mbox_chan *(*of_xlate)(struct mbox_controller *mbox,
const struct of_phandle_args *sp);
/* Internal to API */
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 06/24] byteorder: Add memcpy_to_le32() and memcpy_from_le32()
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (4 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 05/24] mailbox: Allow controller specific mapping using fwnode Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 11:30 ` Andy Shevchenko
2025-07-04 8:16 ` Linus Walleij
2025-07-02 5:13 ` [PATCH v7 07/24] mailbox: Add RISC-V SBI message proxy (MPXY) based mailbox driver Anup Patel
` (17 subsequent siblings)
23 siblings, 2 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
Add common memcpy APIs for copying u32 array to/from __le32 array.
Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
include/linux/byteorder/generic.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/include/linux/byteorder/generic.h b/include/linux/byteorder/generic.h
index c9a4c96c9943..b3705e8bbe2b 100644
--- a/include/linux/byteorder/generic.h
+++ b/include/linux/byteorder/generic.h
@@ -173,6 +173,22 @@ static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
}
}
+static inline void memcpy_from_le32(u32 *dst, const __le32 *src, size_t words)
+{
+ size_t i;
+
+ for (i = 0; i < words; i++)
+ dst[i] = le32_to_cpu(src[i]);
+}
+
+static inline void memcpy_to_le32(__le32 *dst, const u32 *src, size_t words)
+{
+ size_t i;
+
+ for (i = 0; i < words; i++)
+ dst[i] = cpu_to_le32(src[i]);
+}
+
static inline void be16_add_cpu(__be16 *var, u16 val)
{
*var = cpu_to_be16(be16_to_cpu(*var) + val);
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 07/24] mailbox: Add RISC-V SBI message proxy (MPXY) based mailbox driver
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (5 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 06/24] byteorder: Add memcpy_to_le32() and memcpy_from_le32() Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 12:50 ` Andy Shevchenko
2025-07-02 5:13 ` [PATCH v7 08/24] dt-bindings: clock: Add RPMI clock service message proxy bindings Anup Patel
` (16 subsequent siblings)
23 siblings, 1 reply; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
Add a mailbox controller driver for the new SBI message proxy extension
which is part of the SBI v3.0 specification.
Co-developed-by: Rahul Pathak <rpathak@ventanamicro.com>
Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
drivers/mailbox/Kconfig | 11 +
drivers/mailbox/Makefile | 2 +
drivers/mailbox/riscv-sbi-mpxy-mbox.c | 988 ++++++++++++++++++++++++++
3 files changed, 1001 insertions(+)
create mode 100644 drivers/mailbox/riscv-sbi-mpxy-mbox.c
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 68eeed660a4a..eb5e0384fec6 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -340,4 +340,15 @@ config THEAD_TH1520_MBOX
kernel is running, and E902 core used for power management among other
things.
+config RISCV_SBI_MPXY_MBOX
+ tristate "RISC-V SBI Message Proxy (MPXY) Mailbox"
+ depends on RISCV_SBI
+ default RISCV
+ help
+ 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.
+
endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 13a3448b3271..46689c1277f8 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -72,3 +72,5 @@ obj-$(CONFIG_QCOM_CPUCP_MBOX) += qcom-cpucp-mbox.o
obj-$(CONFIG_QCOM_IPCC) += qcom-ipcc.o
obj-$(CONFIG_THEAD_TH1520_MBOX) += mailbox-th1520.o
+
+obj-$(CONFIG_RISCV_SBI_MPXY_MBOX) += riscv-sbi-mpxy-mbox.o
diff --git a/drivers/mailbox/riscv-sbi-mpxy-mbox.c b/drivers/mailbox/riscv-sbi-mpxy-mbox.c
new file mode 100644
index 000000000000..129710f947ae
--- /dev/null
+++ b/drivers/mailbox/riscv-sbi-mpxy-mbox.c
@@ -0,0 +1,988 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RISC-V SBI Message Proxy (MPXY) mailbox controller driver
+ *
+ * Copyright (C) 2025 Ventana Micro Systems Inc.
+ */
+
+#include <linux/cpu.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox/riscv-rpmi-message.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_irq.h>
+#include <linux/percpu.h>
+#include <linux/platform_device.h>
+#include <linux/smp.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <asm/sbi.h>
+
+/* ====== SBI MPXY extension data structures ====== */
+
+/* SBI MPXY MSI related channel attributes */
+struct sbi_mpxy_msi_info {
+ /* Lower 32-bits of the MSI target address */
+ u32 msi_addr_lo;
+ /* Upper 32-bits of the MSI target address */
+ u32 msi_addr_hi;
+ /* MSI data value */
+ u32 msi_data;
+};
+
+/*
+ * SBI MPXY standard channel attributes.
+ *
+ * NOTE: The sequence of attribute fields are as-per the
+ * defined sequence in the attribute table in spec (or
+ * as-per the enum sbi_mpxy_attribute_id).
+ */
+struct sbi_mpxy_channel_attrs {
+ /* Message protocol ID */
+ u32 msg_proto_id;
+ /* Message protocol version */
+ u32 msg_proto_version;
+ /* Message protocol maximum message length */
+ u32 msg_max_len;
+ /* Message protocol message send timeout in microseconds */
+ u32 msg_send_timeout;
+ /* Message protocol message completion timeout in microseconds */
+ u32 msg_completion_timeout;
+ /* Bit array for channel capabilities */
+ u32 capability;
+ /* SSE event ID */
+ u32 sse_event_id;
+ /* MSI enable/disable control knob */
+ u32 msi_control;
+ /* Channel MSI info */
+ struct sbi_mpxy_msi_info msi_info;
+ /* Events state control */
+ u32 events_state_ctrl;
+};
+
+/*
+ * RPMI specific SBI MPXY channel attributes.
+ *
+ * NOTE: The sequence of attribute fields are as-per the
+ * defined sequence in the attribute table in spec (or
+ * as-per the enum sbi_mpxy_rpmi_attribute_id).
+ */
+struct sbi_mpxy_rpmi_channel_attrs {
+ /* RPMI service group ID */
+ u32 servicegroup_id;
+ /* RPMI service group version */
+ u32 servicegroup_version;
+ /* RPMI implementation ID */
+ u32 impl_id;
+ /* RPMI implementation version */
+ u32 impl_version;
+};
+
+/* SBI MPXY channel IDs data in shared memory */
+struct sbi_mpxy_channel_ids_data {
+ /* Remaining number of channel ids */
+ __le32 remaining;
+ /* Returned channel ids in current function call */
+ __le32 returned;
+ /* Returned channel id array */
+ __le32 channel_array[];
+};
+
+/* SBI MPXY notification data in shared memory */
+struct sbi_mpxy_notification_data {
+ /* Remaining number of notification events */
+ __le32 remaining;
+ /* Number of notification events returned */
+ __le32 returned;
+ /* Number of notification events lost */
+ __le32 lost;
+ /* Reserved for future use */
+ __le32 reserved;
+ /* Returned channel id array */
+ u8 events_data[];
+};
+
+/* ====== MPXY data structures & helper routines ====== */
+
+/* MPXY Per-CPU or local context */
+struct mpxy_local {
+ /* Shared memory base address */
+ void *shmem;
+ /* Shared memory physical address */
+ phys_addr_t shmem_phys_addr;
+ /* Flag representing whether shared memory is active or not */
+ bool shmem_active;
+};
+
+static DEFINE_PER_CPU(struct mpxy_local, mpxy_local);
+static unsigned long mpxy_shmem_size;
+static bool mpxy_shmem_init_done;
+
+static int mpxy_get_channel_count(u32 *channel_count)
+{
+ struct mpxy_local *mpxy = this_cpu_ptr(&mpxy_local);
+ struct sbi_mpxy_channel_ids_data *sdata = mpxy->shmem;
+ u32 remaining, returned;
+ struct sbiret sret;
+
+ if (!mpxy->shmem_active)
+ return -ENODEV;
+ if (!channel_count)
+ return -EINVAL;
+
+ get_cpu();
+
+ /* Get the remaining and returned fields to calculate total */
+ sret = sbi_ecall(SBI_EXT_MPXY, SBI_EXT_MPXY_GET_CHANNEL_IDS,
+ 0, 0, 0, 0, 0, 0);
+ if (sret.error)
+ goto err_put_cpu;
+
+ remaining = le32_to_cpu(sdata->remaining);
+ returned = le32_to_cpu(sdata->returned);
+ *channel_count = remaining + returned;
+
+err_put_cpu:
+ put_cpu();
+ return sbi_err_map_linux_errno(sret.error);
+}
+
+static int mpxy_get_channel_ids(u32 channel_count, u32 *channel_ids)
+{
+ struct mpxy_local *mpxy = this_cpu_ptr(&mpxy_local);
+ struct sbi_mpxy_channel_ids_data *sdata = mpxy->shmem;
+ u32 remaining, returned, count, start_index = 0;
+ struct sbiret sret;
+
+ if (!mpxy->shmem_active)
+ return -ENODEV;
+ if (!channel_count || !channel_ids)
+ return -EINVAL;
+
+ get_cpu();
+
+ do {
+ sret = sbi_ecall(SBI_EXT_MPXY, SBI_EXT_MPXY_GET_CHANNEL_IDS,
+ start_index, 0, 0, 0, 0, 0);
+ if (sret.error)
+ goto err_put_cpu;
+
+ remaining = le32_to_cpu(sdata->remaining);
+ returned = le32_to_cpu(sdata->returned);
+
+ count = returned < (channel_count - start_index) ?
+ returned : (channel_count - start_index);
+ memcpy_from_le32(&channel_ids[start_index], sdata->channel_array, count);
+ start_index += count;
+ } while (remaining && start_index < channel_count);
+
+err_put_cpu:
+ put_cpu();
+ return sbi_err_map_linux_errno(sret.error);
+}
+
+static int mpxy_read_attrs(u32 channel_id, u32 base_attrid, u32 attr_count,
+ u32 *attrs_buf)
+{
+ struct mpxy_local *mpxy = this_cpu_ptr(&mpxy_local);
+ struct sbiret sret;
+
+ if (!mpxy->shmem_active)
+ return -ENODEV;
+ if (!attr_count || !attrs_buf)
+ return -EINVAL;
+
+ get_cpu();
+
+ sret = sbi_ecall(SBI_EXT_MPXY, SBI_EXT_MPXY_READ_ATTRS,
+ channel_id, base_attrid, attr_count, 0, 0, 0);
+ if (sret.error)
+ goto err_put_cpu;
+
+ memcpy_from_le32(attrs_buf, (__le32 *)mpxy->shmem, attr_count);
+
+err_put_cpu:
+ put_cpu();
+ return sbi_err_map_linux_errno(sret.error);
+}
+
+static int mpxy_write_attrs(u32 channel_id, u32 base_attrid, u32 attr_count,
+ u32 *attrs_buf)
+{
+ struct mpxy_local *mpxy = this_cpu_ptr(&mpxy_local);
+ struct sbiret sret;
+
+ if (!mpxy->shmem_active)
+ return -ENODEV;
+ if (!attr_count || !attrs_buf)
+ return -EINVAL;
+
+ get_cpu();
+
+ memcpy_to_le32((__le32 *)mpxy->shmem, attrs_buf, attr_count);
+ sret = sbi_ecall(SBI_EXT_MPXY, SBI_EXT_MPXY_WRITE_ATTRS,
+ channel_id, base_attrid, attr_count, 0, 0, 0);
+
+ put_cpu();
+ return sbi_err_map_linux_errno(sret.error);
+}
+
+static int mpxy_send_message_with_resp(u32 channel_id, u32 msg_id,
+ void *tx, unsigned long tx_len,
+ void *rx, unsigned long max_rx_len,
+ unsigned long *rx_len)
+{
+ struct mpxy_local *mpxy = this_cpu_ptr(&mpxy_local);
+ unsigned long rx_bytes;
+ struct sbiret sret;
+
+ if (!mpxy->shmem_active)
+ return -ENODEV;
+ if (!tx && tx_len)
+ return -EINVAL;
+
+ get_cpu();
+
+ /* Message protocols allowed to have no data in messages */
+ if (tx_len)
+ memcpy(mpxy->shmem, tx, tx_len);
+
+ sret = sbi_ecall(SBI_EXT_MPXY, SBI_EXT_MPXY_SEND_MSG_WITH_RESP,
+ channel_id, msg_id, tx_len, 0, 0, 0);
+ if (rx && !sret.error) {
+ rx_bytes = sret.value;
+ if (rx_bytes > max_rx_len) {
+ put_cpu();
+ return -ENOSPC;
+ }
+
+ memcpy(rx, mpxy->shmem, rx_bytes);
+ if (rx_len)
+ *rx_len = rx_bytes;
+ }
+
+ put_cpu();
+ return sbi_err_map_linux_errno(sret.error);
+}
+
+static int mpxy_send_message_without_resp(u32 channel_id, u32 msg_id,
+ void *tx, unsigned long tx_len)
+{
+ struct mpxy_local *mpxy = this_cpu_ptr(&mpxy_local);
+ struct sbiret sret;
+
+ if (!mpxy->shmem_active)
+ return -ENODEV;
+ if (!tx && tx_len)
+ return -EINVAL;
+
+ get_cpu();
+
+ /* Message protocols allowed to have no data in messages */
+ if (tx_len)
+ memcpy(mpxy->shmem, tx, tx_len);
+
+ sret = sbi_ecall(SBI_EXT_MPXY, SBI_EXT_MPXY_SEND_MSG_WITHOUT_RESP,
+ channel_id, msg_id, tx_len, 0, 0, 0);
+
+ put_cpu();
+ return sbi_err_map_linux_errno(sret.error);
+}
+
+static int mpxy_get_notifications(u32 channel_id,
+ struct sbi_mpxy_notification_data *notif_data,
+ unsigned long *events_data_len)
+{
+ struct mpxy_local *mpxy = this_cpu_ptr(&mpxy_local);
+ struct sbiret sret;
+
+ if (!mpxy->shmem_active)
+ return -ENODEV;
+ if (!notif_data || !events_data_len)
+ return -EINVAL;
+
+ get_cpu();
+
+ sret = sbi_ecall(SBI_EXT_MPXY, SBI_EXT_MPXY_GET_NOTIFICATION_EVENTS,
+ channel_id, 0, 0, 0, 0, 0);
+ if (sret.error)
+ goto err_put_cpu;
+
+ memcpy(notif_data, mpxy->shmem, sret.value + 16);
+ *events_data_len = sret.value;
+
+err_put_cpu:
+ put_cpu();
+ return sbi_err_map_linux_errno(sret.error);
+}
+
+static int mpxy_get_shmem_size(unsigned long *shmem_size)
+{
+ struct sbiret sret;
+
+ sret = sbi_ecall(SBI_EXT_MPXY, SBI_EXT_MPXY_GET_SHMEM_SIZE,
+ 0, 0, 0, 0, 0, 0);
+ if (sret.error)
+ return sbi_err_map_linux_errno(sret.error);
+ if (shmem_size)
+ *shmem_size = sret.value;
+ return 0;
+}
+
+static int mpxy_setup_shmem(unsigned int cpu)
+{
+ struct page *shmem_page;
+ struct mpxy_local *mpxy;
+ struct sbiret sret;
+
+ mpxy = per_cpu_ptr(&mpxy_local, cpu);
+ if (mpxy->shmem_active)
+ return 0;
+
+ shmem_page = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(mpxy_shmem_size));
+ if (!shmem_page)
+ return -ENOMEM;
+
+ /*
+ * Linux setup of shmem is done in mpxy OVERWRITE mode.
+ * flags[1:0] = 00b
+ */
+ sret = sbi_ecall(SBI_EXT_MPXY, SBI_EXT_MPXY_SET_SHMEM,
+ page_to_phys(shmem_page), 0, 0, 0, 0, 0);
+ if (sret.error) {
+ free_pages((unsigned long)page_to_virt(shmem_page),
+ get_order(mpxy_shmem_size));
+ return sbi_err_map_linux_errno(sret.error);
+ }
+
+ mpxy->shmem = page_to_virt(shmem_page);
+ mpxy->shmem_phys_addr = page_to_phys(shmem_page);
+ mpxy->shmem_active = true;
+
+ return 0;
+}
+
+/* ====== MPXY mailbox data structures ====== */
+
+/* MPXY mailbox channel */
+struct mpxy_mbox_channel {
+ struct mpxy_mbox *mbox;
+ u32 channel_id;
+ struct sbi_mpxy_channel_attrs attrs;
+ struct sbi_mpxy_rpmi_channel_attrs rpmi_attrs;
+ struct sbi_mpxy_notification_data *notif;
+ u32 max_xfer_len;
+ bool have_events_state;
+ u32 msi_index;
+ u32 msi_irq;
+ bool started;
+};
+
+/* MPXY mailbox */
+struct mpxy_mbox {
+ struct device *dev;
+ u32 channel_count;
+ struct mpxy_mbox_channel *channels;
+ u32 msi_count;
+ struct mpxy_mbox_channel **msi_index_to_channel;
+ struct mbox_controller controller;
+};
+
+/* ====== MPXY RPMI processing ====== */
+
+static void mpxy_mbox_send_rpmi_data(struct mpxy_mbox_channel *mchan,
+ struct rpmi_mbox_message *msg)
+{
+ int rc = 0;
+
+ switch (msg->type) {
+ case RPMI_MBOX_MSG_TYPE_GET_ATTRIBUTE:
+ switch (msg->attr.id) {
+ case RPMI_MBOX_ATTR_SPEC_VERSION:
+ msg->attr.value = mchan->attrs.msg_proto_version;
+ break;
+ case RPMI_MBOX_ATTR_MAX_MSG_DATA_SIZE:
+ msg->attr.value = mchan->max_xfer_len;
+ break;
+ case RPMI_MBOX_ATTR_SERVICEGROUP_ID:
+ msg->attr.value = mchan->rpmi_attrs.servicegroup_id;
+ break;
+ case RPMI_MBOX_ATTR_SERVICEGROUP_VERSION:
+ msg->attr.value = mchan->rpmi_attrs.servicegroup_version;
+ break;
+ case RPMI_MBOX_ATTR_IMPL_ID:
+ msg->attr.value = mchan->rpmi_attrs.impl_id;
+ break;
+ case RPMI_MBOX_ATTR_IMPL_VERSION:
+ msg->attr.value = mchan->rpmi_attrs.impl_version;
+ break;
+ default:
+ rc = -EOPNOTSUPP;
+ break;
+ }
+ break;
+ case RPMI_MBOX_MSG_TYPE_SET_ATTRIBUTE:
+ /* None of the RPMI linux mailbox attributes are writeable */
+ rc = -EOPNOTSUPP;
+ break;
+ case RPMI_MBOX_MSG_TYPE_SEND_WITH_RESPONSE:
+ if ((!msg->data.request && msg->data.request_len) ||
+ (msg->data.request &&
+ msg->data.request_len > mchan->max_xfer_len) ||
+ (!msg->data.response && msg->data.max_response_len)) {
+ rc = -EINVAL;
+ break;
+ }
+ if (!(mchan->attrs.capability & SBI_MPXY_CHAN_CAP_SEND_WITH_RESP)) {
+ rc = -EIO;
+ break;
+ }
+ rc = mpxy_send_message_with_resp(mchan->channel_id,
+ msg->data.service_id,
+ msg->data.request,
+ msg->data.request_len,
+ msg->data.response,
+ msg->data.max_response_len,
+ &msg->data.out_response_len);
+ break;
+ case RPMI_MBOX_MSG_TYPE_SEND_WITHOUT_RESPONSE:
+ if ((!msg->data.request && msg->data.request_len) ||
+ (msg->data.request &&
+ msg->data.request_len > mchan->max_xfer_len)) {
+ rc = -EINVAL;
+ break;
+ }
+ if (!(mchan->attrs.capability & SBI_MPXY_CHAN_CAP_SEND_WITHOUT_RESP)) {
+ rc = -EIO;
+ break;
+ }
+ rc = mpxy_send_message_without_resp(mchan->channel_id,
+ msg->data.service_id,
+ msg->data.request,
+ msg->data.request_len);
+ break;
+ default:
+ rc = -EOPNOTSUPP;
+ break;
+ }
+
+ msg->error = rc;
+}
+
+static void mpxy_mbox_peek_rpmi_data(struct mbox_chan *chan,
+ struct mpxy_mbox_channel *mchan,
+ struct sbi_mpxy_notification_data *notif,
+ unsigned long events_data_len)
+{
+ struct rpmi_notification_event *event;
+ unsigned long pos = 0, event_size;
+ struct rpmi_mbox_message msg;
+
+ while ((pos < events_data_len) && !(pos & 0x3) &&
+ ((events_data_len - pos) <= sizeof(*event))) {
+ event = (struct rpmi_notification_event *)(notif->events_data + pos);
+
+ msg.type = RPMI_MBOX_MSG_TYPE_NOTIFICATION_EVENT;
+ msg.notif.event_datalen = le16_to_cpu(event->event_datalen);
+ msg.notif.event_id = event->event_id;
+ msg.notif.event_data = event->event_data;
+ msg.error = 0;
+
+ event_size = sizeof(*event) + msg.notif.event_datalen;
+ if (event_size > (events_data_len - pos)) {
+ event_size = events_data_len - pos;
+ goto skip_event;
+ }
+ if (event_size & 0x3)
+ goto skip_event;
+
+ mbox_chan_received_data(chan, &msg);
+
+skip_event:
+ pos += event_size;
+ }
+}
+
+static int mpxy_mbox_read_rpmi_attrs(struct mpxy_mbox_channel *mchan)
+{
+ return mpxy_read_attrs(mchan->channel_id,
+ SBI_MPXY_ATTR_MSGPROTO_ATTR_START,
+ sizeof(mchan->rpmi_attrs) / sizeof(u32),
+ (u32 *)&mchan->rpmi_attrs);
+}
+
+/* ====== MPXY mailbox callbacks ====== */
+
+static int mpxy_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+ struct mpxy_mbox_channel *mchan = chan->con_priv;
+
+ if (mchan->attrs.msg_proto_id == SBI_MPXY_MSGPROTO_RPMI_ID) {
+ mpxy_mbox_send_rpmi_data(mchan, data);
+ return 0;
+ }
+
+ return -EOPNOTSUPP;
+}
+
+static bool mpxy_mbox_peek_data(struct mbox_chan *chan)
+{
+ struct mpxy_mbox_channel *mchan = chan->con_priv;
+ struct sbi_mpxy_notification_data *notif = mchan->notif;
+ bool have_notifications = false;
+ unsigned long data_len;
+ int rc;
+
+ if (!(mchan->attrs.capability & SBI_MPXY_CHAN_CAP_GET_NOTIFICATIONS))
+ return false;
+
+ do {
+ rc = mpxy_get_notifications(mchan->channel_id, notif, &data_len);
+ if (rc || !data_len)
+ break;
+
+ if (mchan->attrs.msg_proto_id == SBI_MPXY_MSGPROTO_RPMI_ID)
+ mpxy_mbox_peek_rpmi_data(chan, mchan, notif, data_len);
+
+ have_notifications = true;
+ } while (1);
+
+ return have_notifications;
+}
+
+static irqreturn_t mpxy_mbox_irq_thread(int irq, void *dev_id)
+{
+ mpxy_mbox_peek_data(dev_id);
+ return IRQ_HANDLED;
+}
+
+static int mpxy_mbox_setup_msi(struct mbox_chan *chan,
+ struct mpxy_mbox_channel *mchan)
+{
+ struct device *dev = mchan->mbox->dev;
+ int rc;
+
+ /* Do nothing if MSI not supported */
+ if (mchan->msi_irq == U32_MAX)
+ return 0;
+
+ /* Fail if MSI already enabled */
+ if (mchan->attrs.msi_control)
+ return -EALREADY;
+
+ /* Request channel MSI handler */
+ rc = request_threaded_irq(mchan->msi_irq, NULL, mpxy_mbox_irq_thread,
+ 0, dev_name(dev), chan);
+ if (rc) {
+ dev_err(dev, "failed to request MPXY channel 0x%x IRQ\n",
+ mchan->channel_id);
+ return rc;
+ }
+
+ /* Enable channel MSI control */
+ mchan->attrs.msi_control = 1;
+ rc = mpxy_write_attrs(mchan->channel_id, SBI_MPXY_ATTR_MSI_CONTROL,
+ 1, &mchan->attrs.msi_control);
+ if (rc) {
+ dev_err(dev, "enable MSI control failed for MPXY channel 0x%x\n",
+ mchan->channel_id);
+ mchan->attrs.msi_control = 0;
+ free_irq(mchan->msi_irq, chan);
+ return rc;
+ }
+
+ return 0;
+}
+
+static void mpxy_mbox_cleanup_msi(struct mbox_chan *chan,
+ struct mpxy_mbox_channel *mchan)
+{
+ struct device *dev = mchan->mbox->dev;
+ int rc;
+
+ /* Do nothing if MSI not supported */
+ if (mchan->msi_irq == U32_MAX)
+ return;
+
+ /* Do nothing if MSI already disabled */
+ if (!mchan->attrs.msi_control)
+ return;
+
+ /* Disable channel MSI control */
+ mchan->attrs.msi_control = 0;
+ rc = mpxy_write_attrs(mchan->channel_id, SBI_MPXY_ATTR_MSI_CONTROL,
+ 1, &mchan->attrs.msi_control);
+ if (rc) {
+ dev_err(dev, "disable MSI control failed for MPXY channel 0x%x\n",
+ mchan->channel_id);
+ }
+
+ /* Free channel MSI handler */
+ free_irq(mchan->msi_irq, chan);
+}
+
+static int mpxy_mbox_setup_events(struct mpxy_mbox_channel *mchan)
+{
+ struct device *dev = mchan->mbox->dev;
+ int rc;
+
+ /* Do nothing if events state not supported */
+ if (!mchan->have_events_state)
+ return 0;
+
+ /* Fail if events state already enabled */
+ if (mchan->attrs.events_state_ctrl)
+ return -EALREADY;
+
+ /* Enable channel events state */
+ mchan->attrs.events_state_ctrl = 1;
+ rc = mpxy_write_attrs(mchan->channel_id, SBI_MPXY_ATTR_EVENTS_STATE_CONTROL,
+ 1, &mchan->attrs.events_state_ctrl);
+ if (rc) {
+ dev_err(dev, "enable events state failed for MPXY channel 0x%x\n",
+ mchan->channel_id);
+ mchan->attrs.events_state_ctrl = 0;
+ return rc;
+ }
+
+ return 0;
+}
+
+static void mpxy_mbox_cleanup_events(struct mpxy_mbox_channel *mchan)
+{
+ struct device *dev = mchan->mbox->dev;
+ int rc;
+
+ /* Do nothing if events state not supported */
+ if (!mchan->have_events_state)
+ return;
+
+ /* Do nothing if events state already disabled */
+ if (!mchan->attrs.events_state_ctrl)
+ return;
+
+ /* Disable channel events state */
+ mchan->attrs.events_state_ctrl = 0;
+ rc = mpxy_write_attrs(mchan->channel_id, SBI_MPXY_ATTR_EVENTS_STATE_CONTROL,
+ 1, &mchan->attrs.events_state_ctrl);
+ if (rc)
+ dev_err(dev, "disable events state failed for MPXY channel 0x%x\n",
+ mchan->channel_id);
+}
+
+static int mpxy_mbox_startup(struct mbox_chan *chan)
+{
+ struct mpxy_mbox_channel *mchan = chan->con_priv;
+ int rc;
+
+ if (mchan->started)
+ return -EALREADY;
+
+ /* Setup channel MSI */
+ rc = mpxy_mbox_setup_msi(chan, mchan);
+ if (rc)
+ return rc;
+
+ /* Setup channel notification events */
+ rc = mpxy_mbox_setup_events(mchan);
+ if (rc) {
+ mpxy_mbox_cleanup_msi(chan, mchan);
+ return rc;
+ }
+
+ /* Mark the channel as started */
+ mchan->started = true;
+
+ return 0;
+}
+
+static void mpxy_mbox_shutdown(struct mbox_chan *chan)
+{
+ struct mpxy_mbox_channel *mchan = chan->con_priv;
+
+ if (!mchan->started)
+ return;
+
+ /* Mark the channel as stopped */
+ mchan->started = false;
+
+ /* Cleanup channel notification events */
+ mpxy_mbox_cleanup_events(mchan);
+
+ /* Cleanup channel MSI */
+ mpxy_mbox_cleanup_msi(chan, mchan);
+}
+
+static const struct mbox_chan_ops mpxy_mbox_ops = {
+ .send_data = mpxy_mbox_send_data,
+ .peek_data = mpxy_mbox_peek_data,
+ .startup = mpxy_mbox_startup,
+ .shutdown = mpxy_mbox_shutdown,
+};
+
+/* ====== MPXY platform driver ===== */
+
+static void mpxy_mbox_msi_write(struct msi_desc *desc, struct msi_msg *msg)
+{
+ struct device *dev = msi_desc_to_dev(desc);
+ struct mpxy_mbox *mbox = dev_get_drvdata(dev);
+ struct mpxy_mbox_channel *mchan;
+ struct sbi_mpxy_msi_info *minfo;
+ int rc;
+
+ mchan = mbox->msi_index_to_channel[desc->msi_index];
+ if (!mchan) {
+ dev_warn(dev, "MPXY channel not available for MSI index %d\n",
+ desc->msi_index);
+ return;
+ }
+
+ minfo = &mchan->attrs.msi_info;
+ minfo->msi_addr_lo = msg->address_lo;
+ minfo->msi_addr_hi = msg->address_hi;
+ minfo->msi_data = msg->data;
+
+ rc = mpxy_write_attrs(mchan->channel_id, SBI_MPXY_ATTR_MSI_ADDR_LO,
+ sizeof(*minfo) / sizeof(u32), (u32 *)minfo);
+ if (rc) {
+ dev_warn(dev, "failed to write MSI info for MPXY channel 0x%x\n",
+ mchan->channel_id);
+ }
+}
+
+static struct mbox_chan *mpxy_mbox_fw_xlate(struct mbox_controller *ctlr,
+ const struct fwnode_reference_args *pa)
+{
+ struct mpxy_mbox *mbox = container_of(ctlr, struct mpxy_mbox, controller);
+ struct mpxy_mbox_channel *mchan;
+ u32 i;
+
+ if (pa->nargs != 2)
+ return ERR_PTR(-EINVAL);
+
+ for (i = 0; i < mbox->channel_count; i++) {
+ mchan = &mbox->channels[i];
+ if (mchan->channel_id == pa->args[0] &&
+ mchan->attrs.msg_proto_id == pa->args[1])
+ return &mbox->controller.chans[i];
+ }
+
+ return ERR_PTR(-ENOENT);
+}
+
+static int mpxy_mbox_probe(struct platform_device *pdev)
+{
+ u32 i, *channel_ids __free(kfree) = NULL;
+ struct device *dev = &pdev->dev;
+ struct mpxy_mbox_channel *mchan;
+ struct mpxy_mbox *mbox;
+ int msi_idx, rc;
+
+ /*
+ * Initialize MPXY shared memory only once. This also ensures
+ * that SBI MPXY mailbox is probed only once.
+ */
+ if (mpxy_shmem_init_done) {
+ dev_err(dev, "SBI MPXY mailbox already initialized\n");
+ return -EALREADY;
+ }
+
+ /* Probe for SBI MPXY extension */
+ if (sbi_spec_version < sbi_mk_version(1, 0) ||
+ sbi_probe_extension(SBI_EXT_MPXY) <= 0) {
+ dev_info(dev, "SBI MPXY extension not available\n");
+ return -ENODEV;
+ }
+
+ /* Find-out shared memory size */
+ rc = mpxy_get_shmem_size(&mpxy_shmem_size);
+ if (rc)
+ return dev_err_probe(dev, rc, "failed to get MPXY shared memory size\n");
+
+ /*
+ * Setup MPXY shared memory on each CPU
+ *
+ * Note: Don't cleanup MPXY shared memory upon CPU power-down
+ * because the RPMI System MSI irqchip driver needs it to be
+ * available when migrating IRQs in CPU power-down path.
+ */
+ cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "riscv/sbi-mpxy-shmem",
+ mpxy_setup_shmem, NULL);
+
+ /* Mark as MPXY shared memory initialization done */
+ mpxy_shmem_init_done = true;
+
+ /* Allocate mailbox instance */
+ mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
+ if (!mbox)
+ return -ENOMEM;
+ mbox->dev = dev;
+ platform_set_drvdata(pdev, mbox);
+
+ /* Find-out of number of channels */
+ rc = mpxy_get_channel_count(&mbox->channel_count);
+ if (rc)
+ return dev_err_probe(dev, rc, "failed to get number of MPXY channels\n");
+ if (!mbox->channel_count)
+ dev_err_probe(dev, -ENODEV, "no MPXY channels available\n");
+
+ /* Allocate and fetch all channel IDs */
+ channel_ids = kcalloc(mbox->channel_count, sizeof(*channel_ids), GFP_KERNEL);
+ if (!channel_ids)
+ return -ENOMEM;
+ rc = mpxy_get_channel_ids(mbox->channel_count, channel_ids);
+ if (rc)
+ return dev_err_probe(dev, rc, "failed to get MPXY channel IDs\n");
+
+ /* Populate all channels */
+ mbox->channels = devm_kcalloc(dev, mbox->channel_count,
+ sizeof(*mbox->channels), GFP_KERNEL);
+ if (!mbox->channels)
+ return -ENOMEM;
+ for (i = 0; i < mbox->channel_count; i++) {
+ mchan = &mbox->channels[i];
+ mchan->mbox = mbox;
+ mchan->channel_id = channel_ids[i];
+
+ rc = mpxy_read_attrs(mchan->channel_id, SBI_MPXY_ATTR_MSG_PROT_ID,
+ sizeof(mchan->attrs) / sizeof(u32),
+ (u32 *)&mchan->attrs);
+ if (rc) {
+ return dev_err_probe(dev, rc,
+ "MPXY channel 0x%x read attrs failed\n",
+ mchan->channel_id);
+ }
+
+ if (mchan->attrs.msg_proto_id == SBI_MPXY_MSGPROTO_RPMI_ID) {
+ rc = mpxy_mbox_read_rpmi_attrs(mchan);
+ if (rc) {
+ return dev_err_probe(dev, rc,
+ "MPXY channel 0x%x read RPMI attrs failed\n",
+ mchan->channel_id);
+ }
+ }
+
+ mchan->notif = devm_kzalloc(dev, mpxy_shmem_size, GFP_KERNEL);
+ if (!mchan->notif)
+ return -ENOMEM;
+
+ mchan->max_xfer_len = min(mpxy_shmem_size, mchan->attrs.msg_max_len);
+
+ if ((mchan->attrs.capability & SBI_MPXY_CHAN_CAP_GET_NOTIFICATIONS) &&
+ (mchan->attrs.capability & SBI_MPXY_CHAN_CAP_EVENTS_STATE))
+ mchan->have_events_state = true;
+
+ if ((mchan->attrs.capability & SBI_MPXY_CHAN_CAP_GET_NOTIFICATIONS) &&
+ (mchan->attrs.capability & SBI_MPXY_CHAN_CAP_MSI))
+ mchan->msi_index = mbox->msi_count++;
+ else
+ mchan->msi_index = U32_MAX;
+ mchan->msi_irq = U32_MAX;
+ }
+
+ /* Initialize mailbox controller */
+ mbox->controller.txdone_irq = false;
+ mbox->controller.txdone_poll = false;
+ mbox->controller.ops = &mpxy_mbox_ops;
+ mbox->controller.dev = dev;
+ mbox->controller.num_chans = mbox->channel_count;
+ mbox->controller.fw_xlate = mpxy_mbox_fw_xlate;
+ mbox->controller.chans = devm_kcalloc(dev, mbox->channel_count,
+ sizeof(*mbox->controller.chans),
+ GFP_KERNEL);
+ if (!mbox->controller.chans)
+ return -ENOMEM;
+ for (i = 0; i < mbox->channel_count; i++)
+ mbox->controller.chans[i].con_priv = &mbox->channels[i];
+
+ /* Set the MSI domain if not available */
+ if (!dev_get_msi_domain(dev)) {
+ /*
+ * The device MSI domain for OF devices is only set at the
+ * time of populating/creating OF device. If the device MSI
+ * domain is discovered later after the OF device is created
+ * then we need to set it explicitly before using any platform
+ * MSI functions.
+ */
+ if (dev_of_node(dev))
+ of_msi_configure(dev, dev_of_node(dev));
+ }
+
+ /* Setup MSIs for mailbox (if required) */
+ if (mbox->msi_count) {
+ mbox->msi_index_to_channel = devm_kcalloc(dev, mbox->msi_count,
+ sizeof(*mbox->msi_index_to_channel),
+ GFP_KERNEL);
+ if (!mbox->msi_index_to_channel)
+ return -ENOMEM;
+
+ for (msi_idx = 0; msi_idx < mbox->msi_count; msi_idx++) {
+ for (i = 0; i < mbox->channel_count; i++) {
+ mchan = &mbox->channels[i];
+ if (mchan->msi_index == msi_idx) {
+ mbox->msi_index_to_channel[msi_idx] = mchan;
+ break;
+ }
+ }
+ }
+
+ rc = platform_device_msi_init_and_alloc_irqs(dev, mbox->msi_count,
+ mpxy_mbox_msi_write);
+ if (rc) {
+ return dev_err_probe(dev, rc, "Failed to allocate %d MSIs\n",
+ mbox->msi_count);
+ }
+
+ for (i = 0; i < mbox->channel_count; i++) {
+ mchan = &mbox->channels[i];
+ if (mchan->msi_index == U32_MAX)
+ continue;
+ mchan->msi_irq = msi_get_virq(dev, mchan->msi_index);
+ }
+ }
+
+ /* Register mailbox controller */
+ rc = devm_mbox_controller_register(dev, &mbox->controller);
+ if (rc) {
+ dev_err_probe(dev, rc, "Registering SBI MPXY mailbox failed\n");
+ if (mbox->msi_count)
+ platform_device_msi_free_irqs_all(dev);
+ return rc;
+ }
+
+ dev_info(dev, "mailbox registered with %d channels\n",
+ mbox->channel_count);
+ return 0;
+}
+
+static void mpxy_mbox_remove(struct platform_device *pdev)
+{
+ struct mpxy_mbox *mbox = platform_get_drvdata(pdev);
+
+ if (mbox->msi_count)
+ platform_device_msi_free_irqs_all(mbox->dev);
+}
+
+static const struct of_device_id mpxy_mbox_of_match[] = {
+ { .compatible = "riscv,sbi-mpxy-mbox" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, mpxy_mbox_of_match);
+
+static struct platform_driver mpxy_mbox_driver = {
+ .driver = {
+ .name = "riscv-sbi-mpxy-mbox",
+ .of_match_table = mpxy_mbox_of_match,
+ },
+ .probe = mpxy_mbox_probe,
+ .remove = mpxy_mbox_remove,
+};
+module_platform_driver(mpxy_mbox_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Anup Patel <apatel@ventanamicro.com>");
+MODULE_DESCRIPTION("RISC-V SBI MPXY mailbox controller driver");
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 08/24] dt-bindings: clock: Add RPMI clock service message proxy bindings
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (6 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 07/24] mailbox: Add RISC-V SBI message proxy (MPXY) based mailbox driver Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 09/24] dt-bindings: clock: Add RPMI clock service controller bindings Anup Patel
` (15 subsequent siblings)
23 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel, Conor Dooley
Add device tree bindings for the RPMI clock service group based
message proxy implemented by the SBI implementation (machine mode
firmware or hypervisor).
The RPMI clock service group is defined by the RISC-V platform
management interface (RPMI) specification.
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
.../bindings/clock/riscv,rpmi-mpxy-clock.yaml | 64 +++++++++++++++++++
1 file changed, 64 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/riscv,rpmi-mpxy-clock.yaml
diff --git a/Documentation/devicetree/bindings/clock/riscv,rpmi-mpxy-clock.yaml b/Documentation/devicetree/bindings/clock/riscv,rpmi-mpxy-clock.yaml
new file mode 100644
index 000000000000..70ffc88d0110
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/riscv,rpmi-mpxy-clock.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/riscv,rpmi-mpxy-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V RPMI clock service group based message proxy
+
+maintainers:
+ - Anup Patel <anup@brainfault.org>
+
+description: |
+ The RISC-V Platform Management Interface (RPMI) [1] defines a
+ messaging protocol which is modular and extensible. The supervisor
+ software can send/receive RPMI messages via SBI MPXY extension [2]
+ or some dedicated supervisor-mode RPMI transport.
+
+ The RPMI specification [1] defines clock service group for accessing
+ system clocks managed by a platform microcontroller. The SBI implementation
+ (machine mode firmware or hypervisor) can implement an SBI MPXY channel
+ to allow RPMI clock service group access to the supervisor software.
+
+ ===========================================
+ References
+ ===========================================
+
+ [1] RISC-V Platform Management Interface (RPMI) v1.0 (or higher)
+ https://github.com/riscv-non-isa/riscv-rpmi/releases
+
+ [2] RISC-V Supervisor Binary Interface (SBI) v3.0 (or higher)
+ https://github.com/riscv-non-isa/riscv-sbi-doc/releases
+
+properties:
+ compatible:
+ description:
+ Intended for use by the SBI implementation.
+ const: riscv,rpmi-mpxy-clock
+
+ mboxes:
+ maxItems: 1
+ description:
+ Mailbox channel of the underlying RPMI transport.
+
+ riscv,sbi-mpxy-channel-id:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ The SBI MPXY channel id to be used for providing RPMI access to
+ the supervisor software.
+
+required:
+ - compatible
+ - mboxes
+ - riscv,sbi-mpxy-channel-id
+
+additionalProperties: false
+
+examples:
+ - |
+ clock-controller {
+ compatible = "riscv,rpmi-mpxy-clock";
+ mboxes = <&rpmi_shmem_mbox 0x8>;
+ riscv,sbi-mpxy-channel-id = <0x1000>;
+ };
+...
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 09/24] dt-bindings: clock: Add RPMI clock service controller bindings
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (7 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 08/24] dt-bindings: clock: Add RPMI clock service message proxy bindings Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 10/24] clk: Add clock driver for the RISC-V RPMI clock service group Anup Patel
` (14 subsequent siblings)
23 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel, Conor Dooley
Add device tree bindings for the RPMI clock service group based
controller for the supervisor software.
The RPMI clock service group is defined by the RISC-V platform
management interface (RPMI) specification.
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
.../bindings/clock/riscv,rpmi-clock.yaml | 64 +++++++++++++++++++
1 file changed, 64 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/riscv,rpmi-clock.yaml
diff --git a/Documentation/devicetree/bindings/clock/riscv,rpmi-clock.yaml b/Documentation/devicetree/bindings/clock/riscv,rpmi-clock.yaml
new file mode 100644
index 000000000000..5d62bf8215c8
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/riscv,rpmi-clock.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/riscv,rpmi-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V RPMI clock service group based clock controller
+
+maintainers:
+ - Anup Patel <anup@brainfault.org>
+
+description: |
+ The RISC-V Platform Management Interface (RPMI) [1] defines a
+ messaging protocol which is modular and extensible. The supervisor
+ software can send/receive RPMI messages via SBI MPXY extension [2]
+ or some dedicated supervisor-mode RPMI transport.
+
+ The RPMI specification [1] defines clock service group for accessing
+ system clocks managed by a platform microcontroller. The supervisor
+ software can access RPMI clock service group via SBI MPXY channel or
+ some dedicated supervisor-mode RPMI transport.
+
+ ===========================================
+ References
+ ===========================================
+
+ [1] RISC-V Platform Management Interface (RPMI) v1.0 (or higher)
+ https://github.com/riscv-non-isa/riscv-rpmi/releases
+
+ [2] RISC-V Supervisor Binary Interface (SBI) v3.0 (or higher)
+ https://github.com/riscv-non-isa/riscv-sbi-doc/releases
+
+properties:
+ compatible:
+ description:
+ Intended for use by the supervisor software.
+ const: riscv,rpmi-clock
+
+ mboxes:
+ maxItems: 1
+ description:
+ Mailbox channel of the underlying RPMI transport or SBI message proxy channel.
+
+ "#clock-cells":
+ const: 1
+ description:
+ Platform specific CLOCK_ID as defined by the RISC-V Platform Management
+ Interface (RPMI) specification.
+
+required:
+ - compatible
+ - mboxes
+ - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ clock-controller {
+ compatible = "riscv,rpmi-clock";
+ mboxes = <&mpxy_mbox 0x1000 0x0>;
+ #clock-cells = <1>;
+ };
+...
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 10/24] clk: Add clock driver for the RISC-V RPMI clock service group
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (8 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 09/24] dt-bindings: clock: Add RPMI clock service controller bindings Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 13:08 ` Andy Shevchenko
2025-07-02 5:13 ` [PATCH v7 11/24] dt-bindings: Add RPMI system MSI message proxy bindings Anup Patel
` (13 subsequent siblings)
23 siblings, 1 reply; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
From: Rahul Pathak <rpathak@ventanamicro.com>
The RPMI specification defines a clock service group which can be
accessed via SBI MPXY extension or dedicated S-mode RPMI transport.
Add mailbox client based clock driver for the RISC-V RPMI clock
service group.
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Co-developed-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
---
drivers/clk/Kconfig | 8 +
drivers/clk/Makefile | 1 +
drivers/clk/clk-rpmi.c | 616 +++++++++++++++++++++
include/linux/mailbox/riscv-rpmi-message.h | 16 +
include/linux/wordpart.h | 8 +
5 files changed, 649 insertions(+)
create mode 100644 drivers/clk/clk-rpmi.c
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 19c1ed280fd7..2e385b146f8b 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -493,6 +493,14 @@ config COMMON_CLK_SP7021
Not all features of the PLL are currently supported
by the driver.
+config COMMON_CLK_RPMI
+ tristate "Clock driver based on RISC-V RPMI"
+ depends on MAILBOX
+ default RISCV
+ help
+ Support for clocks based on the clock service group defined by
+ the RISC-V platform management interface (RPMI) specification.
+
source "drivers/clk/actions/Kconfig"
source "drivers/clk/analogbits/Kconfig"
source "drivers/clk/baikal-t1/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 42867cd37c33..48866e429a40 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -84,6 +84,7 @@ obj-$(CONFIG_CLK_LS1028A_PLLDIG) += clk-plldig.o
obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o
obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o
obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o
+obj-$(CONFIG_COMMON_CLK_RPMI) += clk-rpmi.o
obj-$(CONFIG_COMMON_CLK_HI655X) += clk-hi655x.o
obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o
obj-$(CONFIG_COMMON_CLK_SCMI) += clk-scmi.o
diff --git a/drivers/clk/clk-rpmi.c b/drivers/clk/clk-rpmi.c
new file mode 100644
index 000000000000..e3ed130ffc0b
--- /dev/null
+++ b/drivers/clk/clk-rpmi.c
@@ -0,0 +1,616 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RISC-V MPXY Based Clock Driver
+ *
+ * Copyright (C) 2025 Ventana Micro Systems Ltd.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/mailbox_client.h>
+#include <linux/mailbox/riscv-rpmi-message.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/wordpart.h>
+
+#define RPMI_CLK_DISCRETE_MAX_NUM_RATES 16
+#define RPMI_CLK_NAME_LEN 16
+
+#define to_rpmi_clk(clk) container_of(clk, struct rpmi_clk, hw)
+
+#define rpmi_clkrate_u64(hi, lo) make_u64_from_two_u32(hi, lo)
+
+enum rpmi_clk_config {
+ RPMI_CLK_DISABLE = 0,
+ RPMI_CLK_ENABLE = 1,
+ RPMI_CLK_CONFIG_MAX_IDX
+};
+
+enum rpmi_clk_type {
+ RPMI_CLK_DISCRETE = 0,
+ RPMI_CLK_LINEAR = 1,
+ RPMI_CLK_TYPE_MAX_IDX
+};
+
+struct rpmi_clk_context {
+ struct device *dev;
+ struct mbox_chan *chan;
+ struct mbox_client client;
+ u32 max_msg_data_size;
+};
+
+/*
+ * rpmi_clk_rates represents the rates format
+ * as specified by the RPMI specification.
+ * No other format conversion(eg. linear_range) is
+ * required to avoid to and fro conversion.
+ */
+union rpmi_clk_rates {
+ u64 discrete[RPMI_CLK_DISCRETE_MAX_NUM_RATES];
+ struct {
+ u64 min;
+ u64 max;
+ u64 step;
+ } linear;
+};
+
+struct rpmi_clk {
+ struct rpmi_clk_context *context;
+ u32 id;
+ u32 num_rates;
+ u32 transition_latency;
+ enum rpmi_clk_type type;
+ union rpmi_clk_rates *rates;
+ char name[RPMI_CLK_NAME_LEN];
+ struct clk_hw hw;
+};
+
+struct rpmi_clk_rate_discrete {
+ __le32 lo;
+ __le32 hi;
+};
+
+struct rpmi_clk_rate_linear {
+ __le32 min_lo;
+ __le32 min_hi;
+ __le32 max_lo;
+ __le32 max_hi;
+ __le32 step_lo;
+ __le32 step_hi;
+};
+
+struct rpmi_get_num_clocks_rx {
+ __le32 status;
+ __le32 num_clocks;
+};
+
+struct rpmi_get_attrs_tx {
+ __le32 clkid;
+};
+
+struct rpmi_get_attrs_rx {
+ __le32 status;
+ __le32 flags;
+ __le32 num_rates;
+ __le32 transition_latency;
+ char name[RPMI_CLK_NAME_LEN];
+};
+
+struct rpmi_get_supp_rates_tx {
+ __le32 clkid;
+ __le32 clk_rate_idx;
+};
+
+struct rpmi_get_supp_rates_rx {
+ __le32 status;
+ __le32 flags;
+ __le32 remaining;
+ __le32 returned;
+ __le32 rates[];
+};
+
+struct rpmi_get_rate_tx {
+ __le32 clkid;
+};
+
+struct rpmi_get_rate_rx {
+ __le32 status;
+ __le32 lo;
+ __le32 hi;
+};
+
+struct rpmi_set_rate_tx {
+ __le32 clkid;
+ __le32 flags;
+ __le32 lo;
+ __le32 hi;
+};
+
+struct rpmi_set_rate_rx {
+ __le32 status;
+};
+
+struct rpmi_set_config_tx {
+ __le32 clkid;
+ __le32 config;
+};
+
+struct rpmi_set_config_rx {
+ __le32 status;
+};
+
+static u32 rpmi_clk_get_num_clocks(struct rpmi_clk_context *context)
+{
+ struct rpmi_get_num_clocks_rx rx, *resp;
+ struct rpmi_mbox_message msg;
+ int ret;
+
+ rpmi_mbox_init_send_with_response(&msg, RPMI_CLK_SRV_GET_NUM_CLOCKS,
+ NULL, 0, &rx, sizeof(rx));
+
+ ret = rpmi_mbox_send_message(context->chan, &msg);
+ if (ret)
+ return 0;
+
+ resp = rpmi_mbox_get_msg_response(&msg);
+ if (!resp || resp->status)
+ return 0;
+
+ return le32_to_cpu(resp->num_clocks);
+}
+
+static int rpmi_clk_get_attrs(u32 clkid, struct rpmi_clk *rpmi_clk)
+{
+ struct rpmi_clk_context *context = rpmi_clk->context;
+ struct rpmi_mbox_message msg;
+ struct rpmi_get_attrs_tx tx;
+ struct rpmi_get_attrs_rx rx, *resp;
+ u8 format;
+ int ret;
+
+ tx.clkid = cpu_to_le32(clkid);
+ rpmi_mbox_init_send_with_response(&msg, RPMI_CLK_SRV_GET_ATTRIBUTES,
+ &tx, sizeof(tx), &rx, sizeof(rx));
+
+ ret = rpmi_mbox_send_message(context->chan, &msg);
+ if (ret)
+ return ret;
+
+ resp = rpmi_mbox_get_msg_response(&msg);
+ if (!resp)
+ return -EINVAL;
+ if (resp->status)
+ return rpmi_to_linux_error(le32_to_cpu(resp->status));
+
+ rpmi_clk->id = clkid;
+ rpmi_clk->num_rates = le32_to_cpu(resp->num_rates);
+ rpmi_clk->transition_latency = le32_to_cpu(resp->transition_latency);
+ strscpy(rpmi_clk->name, resp->name, RPMI_CLK_NAME_LEN);
+
+ format = le32_to_cpu(resp->flags) & 3U;
+ if (format >= RPMI_CLK_TYPE_MAX_IDX)
+ return -EINVAL;
+
+ rpmi_clk->type = format;
+
+ return 0;
+}
+
+static int rpmi_clk_get_supported_rates(u32 clkid, struct rpmi_clk *rpmi_clk)
+{
+ struct rpmi_clk_context *context = rpmi_clk->context;
+ struct rpmi_clk_rate_discrete *rate_discrete;
+ struct rpmi_clk_rate_linear *rate_linear;
+ struct rpmi_get_supp_rates_tx tx;
+ struct rpmi_get_supp_rates_rx *resp;
+ struct rpmi_mbox_message msg;
+ size_t clk_rate_idx;
+ int ret, rateidx, j;
+
+ tx.clkid = cpu_to_le32(clkid);
+ tx.clk_rate_idx = 0;
+
+ /*
+ * Make sure we allocate rx buffer sufficient to be accommodate all
+ * the rates sent in one RPMI message.
+ */
+ struct rpmi_get_supp_rates_rx *rx __free(kfree) =
+ kzalloc(context->max_msg_data_size, GFP_KERNEL);
+ if (!rx)
+ return -ENOMEM;
+
+ rpmi_mbox_init_send_with_response(&msg, RPMI_CLK_SRV_GET_SUPPORTED_RATES,
+ &tx, sizeof(tx), rx, context->max_msg_data_size);
+
+ ret = rpmi_mbox_send_message(context->chan, &msg);
+ if (ret)
+ return ret;
+
+ resp = rpmi_mbox_get_msg_response(&msg);
+ if (!resp)
+ return -EINVAL;
+ if (resp->status)
+ return rpmi_to_linux_error(le32_to_cpu(resp->status));
+ if (!le32_to_cpu(resp->returned))
+ return -EINVAL;
+
+ if (rpmi_clk->type == RPMI_CLK_DISCRETE) {
+ rate_discrete = (struct rpmi_clk_rate_discrete *)resp->rates;
+
+ for (rateidx = 0; rateidx < le32_to_cpu(resp->returned); rateidx++) {
+ rpmi_clk->rates->discrete[rateidx] =
+ rpmi_clkrate_u64(le32_to_cpu(rate_discrete[rateidx].hi),
+ le32_to_cpu(rate_discrete[rateidx].lo));
+ }
+
+ /*
+ * Keep sending the request message until all
+ * the rates are received.
+ */
+ clk_rate_idx = 0;
+ while (le32_to_cpu(resp->remaining)) {
+ clk_rate_idx += le32_to_cpu(resp->returned);
+ tx.clk_rate_idx = cpu_to_le32(clk_rate_idx);
+
+ rpmi_mbox_init_send_with_response(&msg,
+ RPMI_CLK_SRV_GET_SUPPORTED_RATES,
+ &tx, sizeof(tx),
+ rx, context->max_msg_data_size);
+
+ ret = rpmi_mbox_send_message(context->chan, &msg);
+ if (ret)
+ return ret;
+
+ resp = rpmi_mbox_get_msg_response(&msg);
+ if (!resp)
+ return -EINVAL;
+ if (resp->status)
+ return rpmi_to_linux_error(le32_to_cpu(resp->status));
+ if (!le32_to_cpu(resp->returned))
+ return -EINVAL;
+
+ for (j = 0; j < le32_to_cpu(resp->returned); j++) {
+ if (rateidx >= clk_rate_idx + le32_to_cpu(resp->returned))
+ break;
+ rpmi_clk->rates->discrete[rateidx++] =
+ rpmi_clkrate_u64(le32_to_cpu(rate_discrete[j].hi),
+ le32_to_cpu(rate_discrete[j].lo));
+ }
+ }
+ } else if (rpmi_clk->type == RPMI_CLK_LINEAR) {
+ rate_linear = (struct rpmi_clk_rate_linear *)resp->rates;
+
+ rpmi_clk->rates->linear.min = rpmi_clkrate_u64(le32_to_cpu(rate_linear->min_hi),
+ le32_to_cpu(rate_linear->min_lo));
+ rpmi_clk->rates->linear.max = rpmi_clkrate_u64(le32_to_cpu(rate_linear->max_hi),
+ le32_to_cpu(rate_linear->max_lo));
+ rpmi_clk->rates->linear.step = rpmi_clkrate_u64(le32_to_cpu(rate_linear->step_hi),
+ le32_to_cpu(rate_linear->step_lo));
+ }
+
+ return 0;
+}
+
+static unsigned long rpmi_clk_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct rpmi_clk *rpmi_clk = to_rpmi_clk(hw);
+ struct rpmi_clk_context *context = rpmi_clk->context;
+ struct rpmi_mbox_message msg;
+ struct rpmi_get_rate_tx tx;
+ struct rpmi_get_rate_rx rx, *resp;
+ int ret;
+
+ tx.clkid = cpu_to_le32(rpmi_clk->id);
+
+ rpmi_mbox_init_send_with_response(&msg, RPMI_CLK_SRV_GET_RATE,
+ &tx, sizeof(tx), &rx, sizeof(rx));
+
+ ret = rpmi_mbox_send_message(context->chan, &msg);
+ if (ret)
+ return ret;
+
+ resp = rpmi_mbox_get_msg_response(&msg);
+ if (!resp)
+ return -EINVAL;
+ if (resp->status)
+ return rpmi_to_linux_error(le32_to_cpu(resp->status));
+
+ return rpmi_clkrate_u64(le32_to_cpu(resp->hi), le32_to_cpu(resp->lo));
+}
+
+static int rpmi_clk_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct rpmi_clk *rpmi_clk = to_rpmi_clk(hw);
+ u64 fmin, fmax, ftmp;
+
+ /*
+ * Keep the requested rate if the clock format
+ * is of discrete type. Let the platform which
+ * is actually controlling the clock handle that.
+ */
+ if (rpmi_clk->type == RPMI_CLK_DISCRETE)
+ return 0;
+
+ fmin = rpmi_clk->rates->linear.min;
+ fmax = rpmi_clk->rates->linear.max;
+
+ if (req->rate <= fmin) {
+ req->rate = fmin;
+ return 0;
+ } else if (req->rate >= fmax) {
+ req->rate = fmax;
+ return 0;
+ }
+
+ ftmp = req->rate - fmin;
+ ftmp += rpmi_clk->rates->linear.step - 1;
+ do_div(ftmp, rpmi_clk->rates->linear.step);
+
+ req->rate = ftmp * rpmi_clk->rates->linear.step + fmin;
+
+ return 0;
+}
+
+static int rpmi_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct rpmi_clk *rpmi_clk = to_rpmi_clk(hw);
+ struct rpmi_clk_context *context = rpmi_clk->context;
+ struct rpmi_mbox_message msg;
+ struct rpmi_set_rate_tx tx;
+ struct rpmi_set_rate_rx rx, *resp;
+ int ret;
+
+ tx.clkid = cpu_to_le32(rpmi_clk->id);
+ tx.lo = cpu_to_le32(lower_32_bits(rate));
+ tx.hi = cpu_to_le32(upper_32_bits(rate));
+
+ rpmi_mbox_init_send_with_response(&msg, RPMI_CLK_SRV_SET_RATE,
+ &tx, sizeof(tx), &rx, sizeof(rx));
+
+ ret = rpmi_mbox_send_message(context->chan, &msg);
+ if (ret)
+ return ret;
+
+ resp = rpmi_mbox_get_msg_response(&msg);
+ if (!resp)
+ return -EINVAL;
+ if (resp->status)
+ return rpmi_to_linux_error(le32_to_cpu(resp->status));
+
+ return 0;
+}
+
+static int rpmi_clk_enable(struct clk_hw *hw)
+{
+ struct rpmi_clk *rpmi_clk = to_rpmi_clk(hw);
+ struct rpmi_clk_context *context = rpmi_clk->context;
+ struct rpmi_mbox_message msg;
+ struct rpmi_set_config_tx tx;
+ struct rpmi_set_config_rx rx, *resp;
+ int ret;
+
+ tx.config = cpu_to_le32(RPMI_CLK_ENABLE);
+ tx.clkid = cpu_to_le32(rpmi_clk->id);
+
+ rpmi_mbox_init_send_with_response(&msg, RPMI_CLK_SRV_SET_CONFIG,
+ &tx, sizeof(tx), &rx, sizeof(rx));
+
+ ret = rpmi_mbox_send_message(context->chan, &msg);
+ if (ret)
+ return ret;
+
+ resp = rpmi_mbox_get_msg_response(&msg);
+ if (!resp)
+ return -EINVAL;
+ if (resp->status)
+ return rpmi_to_linux_error(le32_to_cpu(resp->status));
+
+ return 0;
+}
+
+static void rpmi_clk_disable(struct clk_hw *hw)
+{
+ struct rpmi_clk *rpmi_clk = to_rpmi_clk(hw);
+ struct rpmi_clk_context *context = rpmi_clk->context;
+ struct rpmi_mbox_message msg;
+ struct rpmi_set_config_tx tx;
+ struct rpmi_set_config_rx rx;
+
+ tx.config = cpu_to_le32(RPMI_CLK_DISABLE);
+ tx.clkid = cpu_to_le32(rpmi_clk->id);
+
+ rpmi_mbox_init_send_with_response(&msg, RPMI_CLK_SRV_SET_CONFIG,
+ &tx, sizeof(tx), &rx, sizeof(rx));
+
+ rpmi_mbox_send_message(context->chan, &msg);
+}
+
+static const struct clk_ops rpmi_clk_ops = {
+ .recalc_rate = rpmi_clk_recalc_rate,
+ .determine_rate = rpmi_clk_determine_rate,
+ .set_rate = rpmi_clk_set_rate,
+ .prepare = rpmi_clk_enable,
+ .unprepare = rpmi_clk_disable,
+};
+
+static struct clk_hw *rpmi_clk_enumerate(struct rpmi_clk_context *context, u32 clkid)
+{
+ struct device *dev = context->dev;
+ unsigned long min_rate, max_rate;
+ union rpmi_clk_rates *rates;
+ struct rpmi_clk *rpmi_clk;
+ struct clk_init_data init = {};
+ struct clk_hw *clk_hw;
+ int ret;
+
+ rates = devm_kzalloc(dev, sizeof(*rates), GFP_KERNEL);
+ if (!rates)
+ return ERR_PTR(-ENOMEM);
+
+ rpmi_clk = devm_kzalloc(dev, sizeof(*rpmi_clk), GFP_KERNEL);
+ if (!rpmi_clk)
+ return ERR_PTR(-ENOMEM);
+
+ rpmi_clk->context = context;
+ rpmi_clk->rates = rates;
+
+ ret = rpmi_clk_get_attrs(clkid, rpmi_clk);
+ if (ret)
+ return dev_err_ptr_probe(dev, ret,
+ "Failed to get clk-%u attributes\n",
+ clkid);
+
+ ret = rpmi_clk_get_supported_rates(clkid, rpmi_clk);
+ if (ret)
+ return dev_err_ptr_probe(dev, ret,
+ "Get supported rates failed for clk-%u\n",
+ clkid);
+
+ init.flags = CLK_GET_RATE_NOCACHE;
+ init.num_parents = 0;
+ init.ops = &rpmi_clk_ops;
+ init.name = rpmi_clk->name;
+ clk_hw = &rpmi_clk->hw;
+ clk_hw->init = &init;
+
+ ret = devm_clk_hw_register(dev, clk_hw);
+ if (ret)
+ return dev_err_ptr_probe(dev, ret,
+ "Unable to register clk-%u\n",
+ clkid);
+
+ if (rpmi_clk->type == RPMI_CLK_DISCRETE) {
+ min_rate = rpmi_clk->rates->discrete[0];
+ max_rate = rpmi_clk->rates->discrete[rpmi_clk->num_rates - 1];
+ } else {
+ min_rate = rpmi_clk->rates->linear.min;
+ max_rate = rpmi_clk->rates->linear.max;
+ }
+
+ clk_hw_set_rate_range(clk_hw, min_rate, max_rate);
+
+ return clk_hw;
+}
+
+static void rpmi_clk_mbox_chan_release(void *data)
+{
+ struct mbox_chan *chan = data;
+
+ mbox_free_channel(chan);
+}
+
+static int rpmi_clk_probe(struct platform_device *pdev)
+{
+ int ret;
+ unsigned int num_clocks, i;
+ struct clk_hw_onecell_data *clk_data;
+ struct rpmi_clk_context *context;
+ struct rpmi_mbox_message msg;
+ struct clk_hw *hw_ptr;
+ struct device *dev = &pdev->dev;
+
+ context = devm_kzalloc(dev, sizeof(*context), GFP_KERNEL);
+ if (!context)
+ return -ENOMEM;
+ context->dev = dev;
+ platform_set_drvdata(pdev, context);
+
+ context->client.dev = context->dev;
+ context->client.rx_callback = NULL;
+ context->client.tx_block = false;
+ context->client.knows_txdone = true;
+ context->client.tx_tout = 0;
+
+ context->chan = mbox_request_channel(&context->client, 0);
+ if (IS_ERR(context->chan))
+ return PTR_ERR(context->chan);
+
+ ret = devm_add_action_or_reset(dev, rpmi_clk_mbox_chan_release, context->chan);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add rpmi mbox channel cleanup\n");
+
+ rpmi_mbox_init_get_attribute(&msg, RPMI_MBOX_ATTR_SPEC_VERSION);
+ ret = rpmi_mbox_send_message(context->chan, &msg);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get spec version\n");
+ if (msg.attr.value < RPMI_MKVER(1, 0)) {
+ return dev_err_probe(dev, -EINVAL,
+ "msg protocol version mismatch, expected 0x%x, found 0x%x\n",
+ RPMI_MKVER(1, 0), msg.attr.value);
+ }
+
+ rpmi_mbox_init_get_attribute(&msg, RPMI_MBOX_ATTR_SERVICEGROUP_ID);
+ ret = rpmi_mbox_send_message(context->chan, &msg);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get service group ID\n");
+ if (msg.attr.value != RPMI_SRVGRP_CLOCK) {
+ return dev_err_probe(dev, -EINVAL,
+ "service group match failed, expected 0x%x, found 0x%x\n",
+ RPMI_SRVGRP_CLOCK, msg.attr.value);
+ }
+
+ rpmi_mbox_init_get_attribute(&msg, RPMI_MBOX_ATTR_SERVICEGROUP_VERSION);
+ ret = rpmi_mbox_send_message(context->chan, &msg);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get service group version\n");
+ if (msg.attr.value < RPMI_MKVER(1, 0)) {
+ return dev_err_probe(dev, -EINVAL,
+ "service group version failed, expected 0x%x, found 0x%x\n",
+ RPMI_MKVER(1, 0), msg.attr.value);
+ }
+
+ rpmi_mbox_init_get_attribute(&msg, RPMI_MBOX_ATTR_MAX_MSG_DATA_SIZE);
+ ret = rpmi_mbox_send_message(context->chan, &msg);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get max message data size\n");
+
+ context->max_msg_data_size = msg.attr.value;
+ num_clocks = rpmi_clk_get_num_clocks(context);
+ if (!num_clocks)
+ return dev_err_probe(dev, -ENODEV, "No clocks found\n");
+
+ clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, num_clocks),
+ GFP_KERNEL);
+ if (!clk_data)
+ return dev_err_probe(dev, -ENOMEM, "No memory for clock data\n");
+ clk_data->num = num_clocks;
+
+ for (i = 0; i < clk_data->num; i++) {
+ hw_ptr = rpmi_clk_enumerate(context, i);
+ if (IS_ERR(hw_ptr)) {
+ return dev_err_probe(dev, PTR_ERR(hw_ptr),
+ "Failed to register clk-%d\n", i);
+ }
+ clk_data->hws[i] = hw_ptr;
+ }
+
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to register clock HW provider\n");
+
+ return 0;
+}
+
+static const struct of_device_id rpmi_clk_of_match[] = {
+ { .compatible = "riscv,rpmi-clock" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, rpmi_clk_of_match);
+
+static struct platform_driver rpmi_clk_driver = {
+ .driver = {
+ .name = "riscv-rpmi-clock",
+ .of_match_table = rpmi_clk_of_match,
+ },
+ .probe = rpmi_clk_probe,
+};
+module_platform_driver(rpmi_clk_driver);
+
+MODULE_AUTHOR("Rahul Pathak <rpathak@ventanamicro.com>");
+MODULE_DESCRIPTION("Clock Driver based on RPMI message protocol");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mailbox/riscv-rpmi-message.h b/include/linux/mailbox/riscv-rpmi-message.h
index 3f4c73529aa5..c90918dca367 100644
--- a/include/linux/mailbox/riscv-rpmi-message.h
+++ b/include/linux/mailbox/riscv-rpmi-message.h
@@ -90,6 +90,22 @@ static inline int rpmi_to_linux_error(int rpmi_error)
}
}
+/* RPMI service group IDs */
+#define RPMI_SRVGRP_CLOCK 0x00008
+
+/* RPMI clock service IDs */
+enum rpmi_clock_service_id {
+ RPMI_CLK_SRV_ENABLE_NOTIFICATION = 0x01,
+ RPMI_CLK_SRV_GET_NUM_CLOCKS = 0x02,
+ RPMI_CLK_SRV_GET_ATTRIBUTES = 0x03,
+ RPMI_CLK_SRV_GET_SUPPORTED_RATES = 0x04,
+ RPMI_CLK_SRV_SET_CONFIG = 0x05,
+ RPMI_CLK_SRV_GET_CONFIG = 0x06,
+ RPMI_CLK_SRV_SET_RATE = 0x07,
+ RPMI_CLK_SRV_GET_RATE = 0x08,
+ RPMI_CLK_SRV_ID_MAX_COUNT
+};
+
/* RPMI Linux mailbox attribute IDs */
enum rpmi_mbox_attribute_id {
RPMI_MBOX_ATTR_SPEC_VERSION,
diff --git a/include/linux/wordpart.h b/include/linux/wordpart.h
index ed8717730037..5cad9c244bf2 100644
--- a/include/linux/wordpart.h
+++ b/include/linux/wordpart.h
@@ -39,6 +39,14 @@
*/
#define make_u32_from_two_u16(hi, lo) (((u32)(hi) << 16) | (u32)(lo))
+/**
+ * make_u64_from_two_u32 - return u64 number by combining
+ * two u32 numbers.
+ * @hi: upper 32 bit number
+ * @lo: lower 32 bit number
+ */
+#define make_u64_from_two_u32(hi, lo) (((u64)(hi) << 32) | (u32)(lo))
+
/**
* REPEAT_BYTE - repeat the value @x multiple times as an unsigned long value
* @x: value to repeat
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 11/24] dt-bindings: Add RPMI system MSI message proxy bindings
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (9 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 10/24] clk: Add clock driver for the RISC-V RPMI clock service group Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 12/24] dt-bindings: Add RPMI system MSI interrupt controller bindings Anup Patel
` (12 subsequent siblings)
23 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel, Atish Patra, Conor Dooley
Add device tree bindings for the RPMI system MSI service group
based message proxy implemented by the SBI implementation (machine
mode firmware or hypervisor).
The RPMI system MSI service group is defined by the RISC-V
platform management interface (RPMI) specification.
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
.../riscv,rpmi-mpxy-system-msi.yaml | 67 +++++++++++++++++++
1 file changed, 67 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,rpmi-mpxy-system-msi.yaml
diff --git a/Documentation/devicetree/bindings/interrupt-controller/riscv,rpmi-mpxy-system-msi.yaml b/Documentation/devicetree/bindings/interrupt-controller/riscv,rpmi-mpxy-system-msi.yaml
new file mode 100644
index 000000000000..1991f5c7446a
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/riscv,rpmi-mpxy-system-msi.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/riscv,rpmi-mpxy-system-msi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V RPMI system MSI service group based message proxy
+
+maintainers:
+ - Anup Patel <anup@brainfault.org>
+
+description: |
+ The RISC-V Platform Management Interface (RPMI) [1] defines a
+ messaging protocol which is modular and extensible. The supervisor
+ software can send/receive RPMI messages via SBI MPXY extension [2]
+ or some dedicated supervisor-mode RPMI transport.
+
+ The RPMI specification [1] defines system MSI service group which
+ allow application processors to receive MSIs upon system events
+ such as P2A doorbell, graceful shutdown/reboot request, CPU hotplug
+ event, memory hotplug event, etc from the platform microcontroller.
+ The SBI implementation (machine mode firmware or hypervisor) can
+ implement an SBI MPXY channel to allow RPMI system MSI service
+ group access to the supervisor software.
+
+ ===========================================
+ References
+ ===========================================
+
+ [1] RISC-V Platform Management Interface (RPMI) v1.0 (or higher)
+ https://github.com/riscv-non-isa/riscv-rpmi/releases
+
+ [2] RISC-V Supervisor Binary Interface (SBI) v3.0 (or higher)
+ https://github.com/riscv-non-isa/riscv-sbi-doc/releases
+
+properties:
+ compatible:
+ description:
+ Intended for use by the SBI implementation.
+ const: riscv,rpmi-mpxy-system-msi
+
+ mboxes:
+ maxItems: 1
+ description:
+ Mailbox channel of the underlying RPMI transport.
+
+ riscv,sbi-mpxy-channel-id:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ The SBI MPXY channel id to be used for providing RPMI access to
+ the supervisor software.
+
+required:
+ - compatible
+ - mboxes
+ - riscv,sbi-mpxy-channel-id
+
+additionalProperties: false
+
+examples:
+ - |
+ interrupt-controller {
+ compatible = "riscv,rpmi-mpxy-system-msi";
+ mboxes = <&rpmi_shmem_mbox 0x2>;
+ riscv,sbi-mpxy-channel-id = <0x2000>;
+ };
+...
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 12/24] dt-bindings: Add RPMI system MSI interrupt controller bindings
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (10 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 11/24] dt-bindings: Add RPMI system MSI message proxy bindings Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 13/24] irqchip: Add driver for the RPMI system MSI service group Anup Patel
` (11 subsequent siblings)
23 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel, Atish Patra, Conor Dooley
Add device tree bindings for the RPMI system MSI service group
based interrupt controller for the supervisor software.
The RPMI system MSI service group is defined by the RISC-V
platform management interface (RPMI) specification.
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
.../riscv,rpmi-system-msi.yaml | 74 +++++++++++++++++++
1 file changed, 74 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/riscv,rpmi-system-msi.yaml
diff --git a/Documentation/devicetree/bindings/interrupt-controller/riscv,rpmi-system-msi.yaml b/Documentation/devicetree/bindings/interrupt-controller/riscv,rpmi-system-msi.yaml
new file mode 100644
index 000000000000..b10a0532e586
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/riscv,rpmi-system-msi.yaml
@@ -0,0 +1,74 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/riscv,rpmi-system-msi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V RPMI system MSI service group based interrupt controller
+
+maintainers:
+ - Anup Patel <anup@brainfault.org>
+
+description: |
+ The RISC-V Platform Management Interface (RPMI) [1] defines a
+ messaging protocol which is modular and extensible. The supervisor
+ software can send/receive RPMI messages via SBI MPXY extension [2]
+ or some dedicated supervisor-mode RPMI transport.
+
+ The RPMI specification [1] defines system MSI service group which
+ allow application processors to receive MSIs upon system events
+ such as P2A doorbell, graceful shutdown/reboot request, CPU hotplug
+ event, memory hotplug event, etc from the platform microcontroller.
+ The supervisor software can access RPMI system MSI service group via
+ SBI MPXY channel or some dedicated supervisor-mode RPMI transport.
+
+ ===========================================
+ References
+ ===========================================
+
+ [1] RISC-V Platform Management Interface (RPMI) v1.0 (or higher)
+ https://github.com/riscv-non-isa/riscv-rpmi/releases
+
+ [2] RISC-V Supervisor Binary Interface (SBI) v3.0 (or higher)
+ https://github.com/riscv-non-isa/riscv-sbi-doc/releases
+
+allOf:
+ - $ref: /schemas/interrupt-controller.yaml#
+
+properties:
+ compatible:
+ description:
+ Intended for use by the supervisor software.
+ const: riscv,rpmi-system-msi
+
+ mboxes:
+ maxItems: 1
+ description:
+ Mailbox channel of the underlying RPMI transport or SBI message proxy channel.
+
+ msi-parent: true
+
+ interrupt-controller: true
+
+ "#interrupt-cells":
+ const: 1
+
+required:
+ - compatible
+ - mboxes
+ - msi-parent
+ - interrupt-controller
+ - "#interrupt-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ interrupt-controller {
+ compatible = "riscv,rpmi-system-msi";
+ mboxes = <&mpxy_mbox 0x2000 0x0>;
+ msi-parent = <&imsic_slevel>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+...
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 13/24] irqchip: Add driver for the RPMI system MSI service group
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (11 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 12/24] dt-bindings: Add RPMI system MSI interrupt controller bindings Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 14/24] ACPI: property: Refactor acpi_fwnode_get_reference_args() Anup Patel
` (10 subsequent siblings)
23 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
The RPMI specification defines a system MSI service group which
allows application processors to receive MSIs upon system events
such as graceful shutdown/reboot request, CPU hotplug event, memory
hotplug event, etc.
Add an irqchip driver for the RISC-V RPMI system MSI service group
to directly receive system MSIs in Linux kernel.
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
drivers/irqchip/Kconfig | 7 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-riscv-rpmi-sysmsi.c | 283 +++++++++++++++++++++
include/linux/mailbox/riscv-rpmi-message.h | 13 +
4 files changed, 304 insertions(+)
create mode 100644 drivers/irqchip/irq-riscv-rpmi-sysmsi.c
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 0d196e447142..96bf6aa55681 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -617,6 +617,13 @@ config RISCV_IMSIC
select GENERIC_MSI_IRQ
select IRQ_MSI_LIB
+config RISCV_RPMI_SYSMSI
+ bool
+ depends on MAILBOX
+ select IRQ_DOMAIN_HIERARCHY
+ select GENERIC_MSI_IRQ
+ default RISCV
+
config SIFIVE_PLIC
bool
depends on RISCV
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 23ca4959e6ce..4fd966aa78ab 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -103,6 +103,7 @@ obj-$(CONFIG_RISCV_INTC) += irq-riscv-intc.o
obj-$(CONFIG_RISCV_APLIC) += irq-riscv-aplic-main.o irq-riscv-aplic-direct.o
obj-$(CONFIG_RISCV_APLIC_MSI) += irq-riscv-aplic-msi.o
obj-$(CONFIG_RISCV_IMSIC) += irq-riscv-imsic-state.o irq-riscv-imsic-early.o irq-riscv-imsic-platform.o
+obj-$(CONFIG_RISCV_RPMI_SYSMSI) += irq-riscv-rpmi-sysmsi.o
obj-$(CONFIG_SIFIVE_PLIC) += irq-sifive-plic.o
obj-$(CONFIG_STARFIVE_JH8100_INTC) += irq-starfive-jh8100-intc.o
obj-$(CONFIG_THEAD_C900_ACLINT_SSWI) += irq-thead-c900-aclint-sswi.o
diff --git a/drivers/irqchip/irq-riscv-rpmi-sysmsi.c b/drivers/irqchip/irq-riscv-rpmi-sysmsi.c
new file mode 100644
index 000000000000..c42fceab71fa
--- /dev/null
+++ b/drivers/irqchip/irq-riscv-rpmi-sysmsi.c
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2025 Ventana Micro Systems Inc. */
+
+#include <linux/bits.h>
+#include <linux/bug.h>
+#include <linux/device.h>
+#include <linux/device/devres.h>
+#include <linux/dev_printk.h>
+#include <linux/errno.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/mailbox_client.h>
+#include <linux/mailbox/riscv-rpmi-message.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+struct rpmi_sysmsi_get_attrs_rx {
+ __le32 status;
+ __le32 sys_num_msi;
+ __le32 flag0;
+ __le32 flag1;
+};
+
+#define RPMI_SYSMSI_MSI_ATTRIBUTES_FLAG0_PREF_PRIV BIT(0)
+
+struct rpmi_sysmsi_set_msi_state_tx {
+ __le32 sys_msi_index;
+ __le32 sys_msi_state;
+};
+
+struct rpmi_sysmsi_set_msi_state_rx {
+ __le32 status;
+};
+
+#define RPMI_SYSMSI_MSI_STATE_ENABLE BIT(0)
+#define RPMI_SYSMSI_MSI_STATE_PENDING BIT(1)
+
+struct rpmi_sysmsi_set_msi_target_tx {
+ __le32 sys_msi_index;
+ __le32 sys_msi_address_low;
+ __le32 sys_msi_address_high;
+ __le32 sys_msi_data;
+};
+
+struct rpmi_sysmsi_set_msi_target_rx {
+ __le32 status;
+};
+
+struct rpmi_sysmsi_priv {
+ struct device *dev;
+ struct mbox_client client;
+ struct mbox_chan *chan;
+ u32 nr_irqs;
+ u32 gsi_base;
+};
+
+static int rpmi_sysmsi_get_num_msi(struct rpmi_sysmsi_priv *priv)
+{
+ struct rpmi_sysmsi_get_attrs_rx rx;
+ struct rpmi_mbox_message msg;
+ int ret;
+
+ rpmi_mbox_init_send_with_response(&msg, RPMI_SYSMSI_SRV_GET_ATTRIBUTES,
+ NULL, 0, &rx, sizeof(rx));
+ ret = rpmi_mbox_send_message(priv->chan, &msg);
+ if (ret)
+ return ret;
+ if (rx.status)
+ return rpmi_to_linux_error(le32_to_cpu(rx.status));
+
+ return le32_to_cpu(rx.sys_num_msi);
+}
+
+static int rpmi_sysmsi_set_msi_state(struct rpmi_sysmsi_priv *priv,
+ u32 sys_msi_index, u32 sys_msi_state)
+{
+ struct rpmi_sysmsi_set_msi_state_tx tx;
+ struct rpmi_sysmsi_set_msi_state_rx rx;
+ struct rpmi_mbox_message msg;
+ int ret;
+
+ tx.sys_msi_index = cpu_to_le32(sys_msi_index);
+ tx.sys_msi_state = cpu_to_le32(sys_msi_state);
+ rpmi_mbox_init_send_with_response(&msg, RPMI_SYSMSI_SRV_SET_MSI_STATE,
+ &tx, sizeof(tx), &rx, sizeof(rx));
+ ret = rpmi_mbox_send_message(priv->chan, &msg);
+ if (ret)
+ return ret;
+ if (rx.status)
+ return rpmi_to_linux_error(le32_to_cpu(rx.status));
+
+ return 0;
+}
+
+static int rpmi_sysmsi_set_msi_target(struct rpmi_sysmsi_priv *priv,
+ u32 sys_msi_index, struct msi_msg *m)
+{
+ struct rpmi_sysmsi_set_msi_target_tx tx;
+ struct rpmi_sysmsi_set_msi_target_rx rx;
+ struct rpmi_mbox_message msg;
+ int ret;
+
+ tx.sys_msi_index = cpu_to_le32(sys_msi_index);
+ tx.sys_msi_address_low = cpu_to_le32(m->address_lo);
+ tx.sys_msi_address_high = cpu_to_le32(m->address_hi);
+ tx.sys_msi_data = cpu_to_le32(m->data);
+ rpmi_mbox_init_send_with_response(&msg, RPMI_SYSMSI_SRV_SET_MSI_TARGET,
+ &tx, sizeof(tx), &rx, sizeof(rx));
+ ret = rpmi_mbox_send_message(priv->chan, &msg);
+ if (ret)
+ return ret;
+ if (rx.status)
+ return rpmi_to_linux_error(le32_to_cpu(rx.status));
+
+ return 0;
+}
+
+static void rpmi_sysmsi_irq_mask(struct irq_data *d)
+{
+ struct rpmi_sysmsi_priv *priv = irq_data_get_irq_chip_data(d);
+ irq_hw_number_t hwirq = irqd_to_hwirq(d);
+ int ret;
+
+ ret = rpmi_sysmsi_set_msi_state(priv, hwirq, 0);
+ if (ret)
+ dev_warn(priv->dev, "Failed to mask hwirq %lu (error %d)\n", hwirq, ret);
+ irq_chip_mask_parent(d);
+}
+
+static void rpmi_sysmsi_irq_unmask(struct irq_data *d)
+{
+ struct rpmi_sysmsi_priv *priv = irq_data_get_irq_chip_data(d);
+ irq_hw_number_t hwirq = irqd_to_hwirq(d);
+ int ret;
+
+ irq_chip_unmask_parent(d);
+ ret = rpmi_sysmsi_set_msi_state(priv, hwirq, RPMI_SYSMSI_MSI_STATE_ENABLE);
+ if (ret)
+ dev_warn(priv->dev, "Failed to unmask hwirq %lu (error %d)\n", hwirq, ret);
+}
+
+static void rpmi_sysmsi_write_msg(struct irq_data *d, struct msi_msg *msg)
+{
+ struct rpmi_sysmsi_priv *priv = irq_data_get_irq_chip_data(d);
+ irq_hw_number_t hwirq = irqd_to_hwirq(d);
+ int ret;
+
+ /* For zeroed MSI, do nothing as of now */
+ if (!msg->address_hi && !msg->address_lo && !msg->data)
+ return;
+
+ ret = rpmi_sysmsi_set_msi_target(priv, hwirq, msg);
+ if (ret)
+ dev_warn(priv->dev, "Failed to set target for hwirq %lu (error %d)\n", hwirq, ret);
+}
+
+static void rpmi_sysmsi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+{
+ arg->desc = desc;
+ arg->hwirq = desc->data.icookie.value;
+}
+
+static int rpmi_sysmsi_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
+ unsigned long *hwirq, unsigned int *type)
+{
+ struct msi_domain_info *info = d->host_data;
+ struct rpmi_sysmsi_priv *priv = info->data;
+
+ if (WARN_ON(fwspec->param_count < 1))
+ return -EINVAL;
+
+ /* For DT, gsi_base is always zero. */
+ *hwirq = fwspec->param[0] - priv->gsi_base;
+ *type = IRQ_TYPE_NONE;
+ return 0;
+}
+
+static const struct msi_domain_template rpmi_sysmsi_template = {
+ .chip = {
+ .name = "RPMI-SYSMSI",
+ .irq_mask = rpmi_sysmsi_irq_mask,
+ .irq_unmask = rpmi_sysmsi_irq_unmask,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = irq_chip_set_affinity_parent,
+#endif
+ .irq_write_msi_msg = rpmi_sysmsi_write_msg,
+ .flags = IRQCHIP_SET_TYPE_MASKED |
+ IRQCHIP_SKIP_SET_WAKE |
+ IRQCHIP_MASK_ON_SUSPEND,
+ },
+
+ .ops = {
+ .set_desc = rpmi_sysmsi_set_desc,
+ .msi_translate = rpmi_sysmsi_translate,
+ },
+
+ .info = {
+ .bus_token = DOMAIN_BUS_WIRED_TO_MSI,
+ .flags = MSI_FLAG_USE_DEV_FWNODE,
+ .handler = handle_simple_irq,
+ .handler_name = "simple",
+ },
+};
+
+static int rpmi_sysmsi_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct rpmi_sysmsi_priv *priv;
+ int rc;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+ priv->dev = dev;
+
+ /* Setup mailbox client */
+ priv->client.dev = priv->dev;
+ priv->client.rx_callback = NULL;
+ priv->client.tx_block = false;
+ priv->client.knows_txdone = true;
+ priv->client.tx_tout = 0;
+
+ /* Request mailbox channel */
+ priv->chan = mbox_request_channel(&priv->client, 0);
+ if (IS_ERR(priv->chan))
+ return PTR_ERR(priv->chan);
+
+ /* Get number of system MSIs */
+ rc = rpmi_sysmsi_get_num_msi(priv);
+ if (rc < 1) {
+ mbox_free_channel(priv->chan);
+ if (rc)
+ return dev_err_probe(dev, rc, "Failed to get number of system MSIs\n");
+ else
+ return dev_err_probe(dev, -ENODEV, "No system MSIs found\n");
+ }
+ priv->nr_irqs = rc;
+
+ /* Set the device MSI domain if not available */
+ if (!dev_get_msi_domain(dev)) {
+ /*
+ * The device MSI domain for OF devices is only set at the
+ * time of populating/creating OF device. If the device MSI
+ * domain is discovered later after the OF device is created
+ * then we need to set it explicitly before using any platform
+ * MSI functions.
+ */
+ if (dev_of_node(dev))
+ of_msi_configure(dev, dev_of_node(dev));
+
+ if (!dev_get_msi_domain(dev)) {
+ mbox_free_channel(priv->chan);
+ return -EPROBE_DEFER;
+ }
+ }
+
+ if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN,
+ &rpmi_sysmsi_template,
+ priv->nr_irqs, priv, priv)) {
+ mbox_free_channel(priv->chan);
+ return dev_err_probe(dev, -ENOMEM, "failed to create MSI irq domain\n");
+ }
+
+ dev_info(dev, "%u system MSIs registered\n", priv->nr_irqs);
+ return 0;
+}
+
+static const struct of_device_id rpmi_sysmsi_match[] = {
+ { .compatible = "riscv,rpmi-system-msi" },
+ {}
+};
+
+static struct platform_driver rpmi_sysmsi_driver = {
+ .driver = {
+ .name = "rpmi-sysmsi",
+ .of_match_table = rpmi_sysmsi_match,
+ },
+ .probe = rpmi_sysmsi_probe,
+};
+builtin_platform_driver(rpmi_sysmsi_driver);
diff --git a/include/linux/mailbox/riscv-rpmi-message.h b/include/linux/mailbox/riscv-rpmi-message.h
index c90918dca367..521a0c9b9b90 100644
--- a/include/linux/mailbox/riscv-rpmi-message.h
+++ b/include/linux/mailbox/riscv-rpmi-message.h
@@ -91,6 +91,7 @@ static inline int rpmi_to_linux_error(int rpmi_error)
}
/* RPMI service group IDs */
+#define RPMI_SRVGRP_SYSTEM_MSI 0x00002
#define RPMI_SRVGRP_CLOCK 0x00008
/* RPMI clock service IDs */
@@ -106,6 +107,18 @@ enum rpmi_clock_service_id {
RPMI_CLK_SRV_ID_MAX_COUNT
};
+/* RPMI system MSI service IDs */
+enum rpmi_sysmsi_service_id {
+ RPMI_SYSMSI_SRV_ENABLE_NOTIFICATION = 0x01,
+ RPMI_SYSMSI_SRV_GET_ATTRIBUTES = 0x02,
+ RPMI_SYSMSI_SRV_GET_MSI_ATTRIBUTES = 0x03,
+ RPMI_SYSMSI_SRV_SET_MSI_STATE = 0x04,
+ RPMI_SYSMSI_SRV_GET_MSI_STATE = 0x05,
+ RPMI_SYSMSI_SRV_SET_MSI_TARGET = 0x06,
+ RPMI_SYSMSI_SRV_GET_MSI_TARGET = 0x07,
+ RPMI_SYSMSI_SRV_ID_MAX_COUNT
+};
+
/* RPMI Linux mailbox attribute IDs */
enum rpmi_mbox_attribute_id {
RPMI_MBOX_ATTR_SPEC_VERSION,
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 14/24] ACPI: property: Refactor acpi_fwnode_get_reference_args()
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (12 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 13/24] irqchip: Add driver for the RPMI system MSI service group Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 10:07 ` Rafael J. Wysocki
2025-07-02 5:13 ` [PATCH v7 15/24] ACPI: property: Add support for cells property Anup Patel
` (9 subsequent siblings)
23 siblings, 1 reply; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
From: Sunil V L <sunilvl@ventanamicro.com>
Currently acpi_fwnode_get_reference_args() calls the public function
__acpi_node_get_property_reference() which ignores the nargs_prop
parameter. To fix this, make __acpi_node_get_property_reference() to
call the static acpi_fwnode_get_reference() so that callers of
fwnode_get_reference_args() can still pass a valid property name to
fetch the number of arguments.
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
drivers/acpi/property.c | 101 ++++++++++++++++++++--------------------
1 file changed, 50 insertions(+), 51 deletions(-)
diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index 436019d96027..d4863746fb11 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -882,45 +882,10 @@ static struct fwnode_handle *acpi_parse_string_ref(const struct fwnode_handle *f
return &dn->fwnode;
}
-/**
- * __acpi_node_get_property_reference - returns handle to the referenced object
- * @fwnode: Firmware node to get the property from
- * @propname: Name of the property
- * @index: Index of the reference to return
- * @num_args: Maximum number of arguments after each reference
- * @args: Location to store the returned reference with optional arguments
- * (may be NULL)
- *
- * Find property with @name, verifify that it is a package containing at least
- * one object reference and if so, store the ACPI device object pointer to the
- * target object in @args->adev. If the reference includes arguments, store
- * them in the @args->args[] array.
- *
- * If there's more than one reference in the property value package, @index is
- * used to select the one to return.
- *
- * It is possible to leave holes in the property value set like in the
- * example below:
- *
- * Package () {
- * "cs-gpios",
- * Package () {
- * ^GPIO, 19, 0, 0,
- * ^GPIO, 20, 0, 0,
- * 0,
- * ^GPIO, 21, 0, 0,
- * }
- * }
- *
- * Calling this function with index %2 or index %3 return %-ENOENT. If the
- * property does not contain any more values %-ENOENT is returned. The NULL
- * entry must be single integer and preferably contain value %0.
- *
- * Return: %0 on success, negative error code on failure.
- */
-int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
- const char *propname, size_t index, size_t num_args,
- struct fwnode_reference_args *args)
+static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
+ const char *propname, const char *nargs_prop,
+ unsigned int args_count, unsigned int index,
+ struct fwnode_reference_args *args)
{
const union acpi_object *element, *end;
const union acpi_object *obj;
@@ -999,7 +964,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
ret = acpi_get_ref_args(idx == index ? args : NULL,
acpi_fwnode_handle(device),
- &element, end, num_args);
+ &element, end, args_count);
if (ret < 0)
return ret;
@@ -1017,7 +982,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
ret = acpi_get_ref_args(idx == index ? args : NULL,
ref_fwnode, &element, end,
- num_args);
+ args_count);
if (ret < 0)
return ret;
@@ -1039,6 +1004,50 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
return -ENOENT;
}
+
+/**
+ * __acpi_node_get_property_reference - returns handle to the referenced object
+ * @fwnode: Firmware node to get the property from
+ * @propname: Name of the property
+ * @index: Index of the reference to return
+ * @num_args: Maximum number of arguments after each reference
+ * @args: Location to store the returned reference with optional arguments
+ * (may be NULL)
+ *
+ * Find property with @name, verifify that it is a package containing at least
+ * one object reference and if so, store the ACPI device object pointer to the
+ * target object in @args->adev. If the reference includes arguments, store
+ * them in the @args->args[] array.
+ *
+ * If there's more than one reference in the property value package, @index is
+ * used to select the one to return.
+ *
+ * It is possible to leave holes in the property value set like in the
+ * example below:
+ *
+ * Package () {
+ * "cs-gpios",
+ * Package () {
+ * ^GPIO, 19, 0, 0,
+ * ^GPIO, 20, 0, 0,
+ * 0,
+ * ^GPIO, 21, 0, 0,
+ * }
+ * }
+ *
+ * Calling this function with index %2 or index %3 return %-ENOENT. If the
+ * property does not contain any more values %-ENOENT is returned. The NULL
+ * entry must be single integer and preferably contain value %0.
+ *
+ * Return: %0 on success, negative error code on failure.
+ */
+int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
+ const char *propname, size_t index,
+ size_t num_args,
+ struct fwnode_reference_args *args)
+{
+ return acpi_fwnode_get_reference_args(fwnode, propname, NULL, index, num_args, args);
+}
EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference);
static int acpi_data_prop_read_single(const struct acpi_device_data *data,
@@ -1558,16 +1567,6 @@ acpi_fwnode_property_read_string_array(const struct fwnode_handle *fwnode,
val, nval);
}
-static int
-acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
- const char *prop, const char *nargs_prop,
- unsigned int args_count, unsigned int index,
- struct fwnode_reference_args *args)
-{
- return __acpi_node_get_property_reference(fwnode, prop, index,
- args_count, args);
-}
-
static const char *acpi_fwnode_get_name(const struct fwnode_handle *fwnode)
{
const struct acpi_device *adev;
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 15/24] ACPI: property: Add support for cells property
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (13 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 14/24] ACPI: property: Refactor acpi_fwnode_get_reference_args() Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 10:20 ` Rafael J. Wysocki
2025-07-02 11:44 ` Andy Shevchenko
2025-07-02 5:13 ` [PATCH v7 16/24] ACPI: scan: Update honor list for RPMI System MSI Anup Patel
` (8 subsequent siblings)
23 siblings, 2 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
From: Sunil V L <sunilvl@ventanamicro.com>
Currently, ACPI doesn't support cells property when
fwnode_property_get_reference_args() is called. ACPI always expects
the number of arguments to be passed. However, the above mentioned
call being a common interface for OF and ACPI, it is better to have
single calling convention which works for both. Hence, add support
for cells property on the reference device to get the number of
arguments dynamically.
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
drivers/acpi/property.c | 22 ++++++++++++++++++----
drivers/base/property.c | 2 +-
2 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index d4863746fb11..d08b0ea5c915 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -882,6 +882,17 @@ static struct fwnode_handle *acpi_parse_string_ref(const struct fwnode_handle *f
return &dn->fwnode;
}
+static unsigned int acpi_fwnode_get_args_count(const struct acpi_device *device,
+ const char *nargs_prop)
+{
+ const union acpi_object *obj;
+
+ if (acpi_dev_get_property(device, nargs_prop, ACPI_TYPE_INTEGER, &obj))
+ return 0;
+
+ return obj->integer.value;
+}
+
static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
const char *propname, const char *nargs_prop,
unsigned int args_count, unsigned int index,
@@ -892,6 +903,7 @@ static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
const struct acpi_device_data *data;
struct fwnode_handle *ref_fwnode;
struct acpi_device *device;
+ unsigned int nargs_count;
int ret, idx = 0;
data = acpi_device_data_of_node(fwnode);
@@ -960,11 +972,12 @@ static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
if (!device)
return -EINVAL;
+ nargs_count = acpi_fwnode_get_args_count(device, nargs_prop);
element++;
-
ret = acpi_get_ref_args(idx == index ? args : NULL,
acpi_fwnode_handle(device),
- &element, end, args_count);
+ &element, end,
+ nargs_count ? nargs_count : args_count);
if (ret < 0)
return ret;
@@ -978,11 +991,12 @@ static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
if (!ref_fwnode)
return -EINVAL;
+ device = to_acpi_device_node(ref_fwnode);
+ nargs_count = acpi_fwnode_get_args_count(device, nargs_prop);
element++;
-
ret = acpi_get_ref_args(idx == index ? args : NULL,
ref_fwnode, &element, end,
- args_count);
+ nargs_count ? nargs_count : args_count);
if (ret < 0)
return ret;
diff --git a/drivers/base/property.c b/drivers/base/property.c
index f626d5bbe806..6a63860579dd 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -578,7 +578,7 @@ EXPORT_SYMBOL_GPL(fwnode_property_match_property_string);
* @prop: The name of the property
* @nargs_prop: The name of the property telling the number of
* arguments in the referred node. NULL if @nargs is known,
- * otherwise @nargs is ignored. Only relevant on OF.
+ * otherwise @nargs is ignored.
* @nargs: Number of arguments. Ignored if @nargs_prop is non-NULL.
* @index: Index of the reference, from zero onwards.
* @args: Result structure with reference and integer arguments.
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 16/24] ACPI: scan: Update honor list for RPMI System MSI
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (14 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 15/24] ACPI: property: Add support for cells property Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 10:21 ` Rafael J. Wysocki
2025-07-02 11:45 ` Andy Shevchenko
2025-07-02 5:13 ` [PATCH v7 17/24] ACPI: RISC-V: Create interrupt controller list in sorted order Anup Patel
` (7 subsequent siblings)
23 siblings, 2 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Atish Patra, Anup Patel
From: Sunil V L <sunilvl@ventanamicro.com>
The RPMI System MSI interrupt controller (just like PLIC and APLIC)
needs to probed prior to devices like GED which use interrupts provided
by it. Also, it has dependency on the SBI MPXY mailbox device.
Add HIDs of RPMI System MSI and SBI MPXY mailbox devices to the honor
list so that those dependencies are handled.
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
drivers/acpi/scan.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index fb1fe9f3b1a3..54181b03b345 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -858,6 +858,8 @@ static const char * const acpi_honor_dep_ids[] = {
"INTC10CF", /* IVSC (MTL) driver must be loaded to allow i2c access to camera sensors */
"RSCV0001", /* RISC-V PLIC */
"RSCV0002", /* RISC-V APLIC */
+ "RSCV0005", /* RISC-V SBI MPXY MBOX */
+ "RSCV0006", /* RISC-V RPMI SYSMSI */
"PNP0C0F", /* PCI Link Device */
NULL
};
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 17/24] ACPI: RISC-V: Create interrupt controller list in sorted order
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (15 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 16/24] ACPI: scan: Update honor list for RPMI System MSI Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 18/24] ACPI: RISC-V: Add support to update gsi range Anup Patel
` (6 subsequent siblings)
23 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
From: Sunil V L <sunilvl@ventanamicro.com>
Currently, the interrupt controller list is created without any order.
Create the list sorted with the GSI base of the interrupt controllers.
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
drivers/acpi/riscv/irq.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/riscv/irq.c b/drivers/acpi/riscv/irq.c
index cced960c2aef..33c073e2e71d 100644
--- a/drivers/acpi/riscv/irq.c
+++ b/drivers/acpi/riscv/irq.c
@@ -115,7 +115,7 @@ struct fwnode_handle *riscv_acpi_get_gsi_domain_id(u32 gsi)
static int __init riscv_acpi_register_ext_intc(u32 gsi_base, u32 nr_irqs, u32 nr_idcs,
u32 id, u32 type)
{
- struct riscv_ext_intc_list *ext_intc_element;
+ struct riscv_ext_intc_list *ext_intc_element, *node;
ext_intc_element = kzalloc(sizeof(*ext_intc_element), GFP_KERNEL);
if (!ext_intc_element)
@@ -125,7 +125,12 @@ static int __init riscv_acpi_register_ext_intc(u32 gsi_base, u32 nr_irqs, u32 nr
ext_intc_element->nr_irqs = nr_irqs;
ext_intc_element->nr_idcs = nr_idcs;
ext_intc_element->id = id;
- list_add_tail(&ext_intc_element->list, &ext_intc_list);
+ list_for_each_entry(node, &ext_intc_list, list) {
+ if (node->gsi_base < ext_intc_element->gsi_base)
+ break;
+ }
+
+ list_add_tail(&ext_intc_element->list, &node->list);
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 18/24] ACPI: RISC-V: Add support to update gsi range
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (16 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 17/24] ACPI: RISC-V: Create interrupt controller list in sorted order Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 19/24] ACPI: RISC-V: Add RPMI System MSI to GSI mapping Anup Patel
` (5 subsequent siblings)
23 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
From: Sunil V L <sunilvl@ventanamicro.com>
Some RISC-V interrupt controllers like RPMI based system MSI interrupt
controllers do not have MADT entry defined. These interrupt controllers
exist only in the namespace. ACPI spec defines _GSB method to get the
GSI base of the interrupt controller, However, there is no such standard
method to get the GSI range. To support such interrupt controllers, set
the GSI range of such interrupt controllers to non-overlapping range and
provide API for interrupt controller driver to update it with proper
value.
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
arch/riscv/include/asm/irq.h | 5 +++++
drivers/acpi/riscv/irq.c | 38 ++++++++++++++++++++++++++++++++++--
2 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/include/asm/irq.h b/arch/riscv/include/asm/irq.h
index 7b038f3b7cb0..2caf049f09c8 100644
--- a/arch/riscv/include/asm/irq.h
+++ b/arch/riscv/include/asm/irq.h
@@ -40,6 +40,7 @@ unsigned long acpi_rintc_ext_parent_to_hartid(unsigned int plic_id, unsigned int
unsigned int acpi_rintc_get_plic_nr_contexts(unsigned int plic_id);
unsigned int acpi_rintc_get_plic_context(unsigned int plic_id, unsigned int ctxt_idx);
int __init acpi_rintc_get_imsic_mmio_info(u32 index, struct resource *res);
+int riscv_acpi_update_gsi_range(u32 gsi_base, u32 nr_irqs);
#else
static inline int riscv_acpi_get_gsi_info(struct fwnode_handle *fwnode, u32 *gsi_base,
@@ -74,6 +75,10 @@ static inline int __init acpi_rintc_get_imsic_mmio_info(u32 index, struct resour
return 0;
}
+static inline int riscv_acpi_update_gsi_range(u32 gsi_base, u32 nr_irqs)
+{
+ return -ENODEV;
+}
#endif /* CONFIG_ACPI */
#endif /* _ASM_RISCV_IRQ_H */
diff --git a/drivers/acpi/riscv/irq.c b/drivers/acpi/riscv/irq.c
index 33c073e2e71d..cc1928422418 100644
--- a/drivers/acpi/riscv/irq.c
+++ b/drivers/acpi/riscv/irq.c
@@ -10,6 +10,8 @@
#include "init.h"
+#define RISCV_ACPI_INTC_FLAG_PENDING BIT(0)
+
struct riscv_ext_intc_list {
acpi_handle handle;
u32 gsi_base;
@@ -17,6 +19,7 @@ struct riscv_ext_intc_list {
u32 nr_idcs;
u32 id;
u32 type;
+ u32 flag;
struct list_head list;
};
@@ -69,6 +72,22 @@ static acpi_status riscv_acpi_update_gsi_handle(u32 gsi_base, acpi_handle handle
return AE_NOT_FOUND;
}
+int riscv_acpi_update_gsi_range(u32 gsi_base, u32 nr_irqs)
+{
+ struct riscv_ext_intc_list *ext_intc_element;
+
+ list_for_each_entry(ext_intc_element, &ext_intc_list, list) {
+ if (gsi_base == ext_intc_element->gsi_base &&
+ (ext_intc_element->flag & RISCV_ACPI_INTC_FLAG_PENDING)) {
+ ext_intc_element->nr_irqs = nr_irqs;
+ ext_intc_element->flag &= ~RISCV_ACPI_INTC_FLAG_PENDING;
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
int riscv_acpi_get_gsi_info(struct fwnode_handle *fwnode, u32 *gsi_base,
u32 *id, u32 *nr_irqs, u32 *nr_idcs)
{
@@ -115,14 +134,22 @@ struct fwnode_handle *riscv_acpi_get_gsi_domain_id(u32 gsi)
static int __init riscv_acpi_register_ext_intc(u32 gsi_base, u32 nr_irqs, u32 nr_idcs,
u32 id, u32 type)
{
- struct riscv_ext_intc_list *ext_intc_element, *node;
+ struct riscv_ext_intc_list *ext_intc_element, *node, *prev;
ext_intc_element = kzalloc(sizeof(*ext_intc_element), GFP_KERNEL);
if (!ext_intc_element)
return -ENOMEM;
ext_intc_element->gsi_base = gsi_base;
- ext_intc_element->nr_irqs = nr_irqs;
+
+ /* If nr_irqs is zero, indicate it in flag and set to max range possible */
+ if (nr_irqs) {
+ ext_intc_element->nr_irqs = nr_irqs;
+ } else {
+ ext_intc_element->flag |= RISCV_ACPI_INTC_FLAG_PENDING;
+ ext_intc_element->nr_irqs = U32_MAX - ext_intc_element->gsi_base;
+ }
+
ext_intc_element->nr_idcs = nr_idcs;
ext_intc_element->id = id;
list_for_each_entry(node, &ext_intc_list, list) {
@@ -130,6 +157,13 @@ static int __init riscv_acpi_register_ext_intc(u32 gsi_base, u32 nr_irqs, u32 nr
break;
}
+ /* Adjust the previous node's GSI range if that has pending registration */
+ prev = list_prev_entry(node, list);
+ if (!list_entry_is_head(prev, &ext_intc_list, list)) {
+ if (prev->flag & RISCV_ACPI_INTC_FLAG_PENDING)
+ prev->nr_irqs = ext_intc_element->gsi_base - prev->gsi_base;
+ }
+
list_add_tail(&ext_intc_element->list, &node->list);
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 19/24] ACPI: RISC-V: Add RPMI System MSI to GSI mapping
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (17 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 18/24] ACPI: RISC-V: Add support to update gsi range Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 20/24] irqchip/irq-riscv-imsic-early: Export imsic_acpi_get_fwnode() Anup Patel
` (4 subsequent siblings)
23 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
From: Sunil V L <sunilvl@ventanamicro.com>
The RPMI System MSI device will provide GSIs to downstream devices
(such as GED) so add it to the RISC-V GSI to fwnode mapping.
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
arch/riscv/include/asm/irq.h | 1 +
drivers/acpi/riscv/irq.c | 30 ++++++++++++++++++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/arch/riscv/include/asm/irq.h b/arch/riscv/include/asm/irq.h
index 2caf049f09c8..9c9d22f5165e 100644
--- a/arch/riscv/include/asm/irq.h
+++ b/arch/riscv/include/asm/irq.h
@@ -30,6 +30,7 @@ enum riscv_irqchip_type {
ACPI_RISCV_IRQCHIP_IMSIC = 0x01,
ACPI_RISCV_IRQCHIP_PLIC = 0x02,
ACPI_RISCV_IRQCHIP_APLIC = 0x03,
+ ACPI_RISCV_IRQCHIP_SMSI = 0x04,
};
int riscv_acpi_get_gsi_info(struct fwnode_handle *fwnode, u32 *gsi_base,
diff --git a/drivers/acpi/riscv/irq.c b/drivers/acpi/riscv/irq.c
index cc1928422418..d9a2154d6c6a 100644
--- a/drivers/acpi/riscv/irq.c
+++ b/drivers/acpi/riscv/irq.c
@@ -168,6 +168,33 @@ static int __init riscv_acpi_register_ext_intc(u32 gsi_base, u32 nr_irqs, u32 nr
return 0;
}
+static acpi_status __init riscv_acpi_create_gsi_map_smsi(acpi_handle handle, u32 level,
+ void *context, void **return_value)
+{
+ acpi_status status;
+ u64 gbase;
+
+ if (!acpi_has_method(handle, "_GSB")) {
+ acpi_handle_err(handle, "_GSB method not found\n");
+ return AE_ERROR;
+ }
+
+ status = acpi_evaluate_integer(handle, "_GSB", NULL, &gbase);
+ if (ACPI_FAILURE(status)) {
+ acpi_handle_err(handle, "failed to evaluate _GSB method\n");
+ return status;
+ }
+
+ riscv_acpi_register_ext_intc(gbase, 0, 0, 0, ACPI_RISCV_IRQCHIP_SMSI);
+ status = riscv_acpi_update_gsi_handle((u32)gbase, handle);
+ if (ACPI_FAILURE(status)) {
+ acpi_handle_err(handle, "failed to find the GSI mapping entry\n");
+ return status;
+ }
+
+ return AE_OK;
+}
+
static acpi_status __init riscv_acpi_create_gsi_map(acpi_handle handle, u32 level,
void *context, void **return_value)
{
@@ -222,6 +249,9 @@ void __init riscv_acpi_init_gsi_mapping(void)
if (acpi_table_parse_madt(ACPI_MADT_TYPE_APLIC, riscv_acpi_aplic_parse_madt, 0) > 0)
acpi_get_devices("RSCV0002", riscv_acpi_create_gsi_map, NULL, NULL);
+
+ /* Unlike PLIC/APLIC, SYSMSI doesn't have MADT */
+ acpi_get_devices("RSCV0006", riscv_acpi_create_gsi_map_smsi, NULL, NULL);
}
static acpi_handle riscv_acpi_get_gsi_handle(u32 gsi)
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 20/24] irqchip/irq-riscv-imsic-early: Export imsic_acpi_get_fwnode()
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (18 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 19/24] ACPI: RISC-V: Add RPMI System MSI to GSI mapping Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 21/24] mailbox/riscv-sbi-mpxy: Add ACPI support Anup Patel
` (3 subsequent siblings)
23 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
From: Sunil V L <sunilvl@ventanamicro.com>
ACPI based loadable drivers which need MSIs will also need
imsic_acpi_get_fwnode() to update the device MSI domain so
export this function.
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
drivers/irqchip/irq-riscv-imsic-early.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/irqchip/irq-riscv-imsic-early.c b/drivers/irqchip/irq-riscv-imsic-early.c
index d9ae87808651..1dbc41d7fe80 100644
--- a/drivers/irqchip/irq-riscv-imsic-early.c
+++ b/drivers/irqchip/irq-riscv-imsic-early.c
@@ -7,6 +7,7 @@
#define pr_fmt(fmt) "riscv-imsic: " fmt
#include <linux/acpi.h>
#include <linux/cpu.h>
+#include <linux/export.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
@@ -215,6 +216,7 @@ struct fwnode_handle *imsic_acpi_get_fwnode(struct device *dev)
{
return imsic_acpi_fwnode;
}
+EXPORT_SYMBOL_GPL(imsic_acpi_get_fwnode);
static int __init imsic_early_acpi_init(union acpi_subtable_headers *header,
const unsigned long end)
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 21/24] mailbox/riscv-sbi-mpxy: Add ACPI support
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (19 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 20/24] irqchip/irq-riscv-imsic-early: Export imsic_acpi_get_fwnode() Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 12:28 ` Andy Shevchenko
2025-07-02 5:13 ` [PATCH v7 22/24] irqchip/riscv-rpmi-sysmsi: " Anup Patel
` (2 subsequent siblings)
23 siblings, 1 reply; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
From: Sunil V L <sunilvl@ventanamicro.com>
Add ACPI support for the RISC-V SBI message proxy (MPXY) based
mailbox driver.
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
drivers/mailbox/riscv-sbi-mpxy-mbox.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/drivers/mailbox/riscv-sbi-mpxy-mbox.c b/drivers/mailbox/riscv-sbi-mpxy-mbox.c
index 129710f947ae..deb269a9a844 100644
--- a/drivers/mailbox/riscv-sbi-mpxy-mbox.c
+++ b/drivers/mailbox/riscv-sbi-mpxy-mbox.c
@@ -5,9 +5,11 @@
* Copyright (C) 2025 Ventana Micro Systems Inc.
*/
+#include <linux/acpi.h>
#include <linux/cpu.h>
#include <linux/errno.h>
#include <linux/init.h>
+#include <linux/irqchip/riscv-imsic.h>
#include <linux/mailbox_controller.h>
#include <linux/mailbox/riscv-rpmi-message.h>
#include <linux/mm.h>
@@ -779,6 +781,7 @@ static int mpxy_mbox_probe(struct platform_device *pdev)
u32 i, *channel_ids __free(kfree) = NULL;
struct device *dev = &pdev->dev;
struct mpxy_mbox_channel *mchan;
+ struct irq_domain *msi_domain;
struct mpxy_mbox *mbox;
int msi_idx, rc;
@@ -901,6 +904,8 @@ static int mpxy_mbox_probe(struct platform_device *pdev)
/* Set the MSI domain if not available */
if (!dev_get_msi_domain(dev)) {
+ struct fwnode_handle *fwnode = dev_fwnode(dev);
+
/*
* The device MSI domain for OF devices is only set at the
* time of populating/creating OF device. If the device MSI
@@ -908,8 +913,13 @@ static int mpxy_mbox_probe(struct platform_device *pdev)
* then we need to set it explicitly before using any platform
* MSI functions.
*/
- if (dev_of_node(dev))
+ if (is_of_node(fwnode)) {
of_msi_configure(dev, dev_of_node(dev));
+ } else if (is_acpi_device_node(fwnode)) {
+ msi_domain = irq_find_matching_fwnode(imsic_acpi_get_fwnode(dev),
+ DOMAIN_BUS_PLATFORM_MSI);
+ dev_set_msi_domain(dev, msi_domain);
+ }
}
/* Setup MSIs for mailbox (if required) */
@@ -954,6 +964,13 @@ static int mpxy_mbox_probe(struct platform_device *pdev)
return rc;
}
+#ifdef CONFIG_ACPI
+ struct acpi_device *adev = ACPI_COMPANION(dev);
+
+ if (adev)
+ acpi_dev_clear_dependencies(adev);
+#endif
+
dev_info(dev, "mailbox registered with %d channels\n",
mbox->channel_count);
return 0;
@@ -973,10 +990,17 @@ static const struct of_device_id mpxy_mbox_of_match[] = {
};
MODULE_DEVICE_TABLE(of, mpxy_mbox_of_match);
+static const struct acpi_device_id mpxy_mbox_acpi_match[] = {
+ { "RSCV0005" },
+ {}
+};
+MODULE_DEVICE_TABLE(acpi, mpxy_mbox_acpi_match);
+
static struct platform_driver mpxy_mbox_driver = {
.driver = {
.name = "riscv-sbi-mpxy-mbox",
.of_match_table = mpxy_mbox_of_match,
+ .acpi_match_table = mpxy_mbox_acpi_match,
},
.probe = mpxy_mbox_probe,
.remove = mpxy_mbox_remove,
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 22/24] irqchip/riscv-rpmi-sysmsi: Add ACPI support
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (20 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 21/24] mailbox/riscv-sbi-mpxy: Add ACPI support Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 23/24] RISC-V: Enable GPIO keyboard and event device in RV64 defconfig Anup Patel
2025-07-02 5:13 ` [PATCH v7 24/24] MAINTAINERS: Add entry for RISC-V RPMI and MPXY drivers Anup Patel
23 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
From: Sunil V L <sunilvl@ventanamicro.com>
Add ACPI support for the RISC-V RPMI system MSI based irqchip driver.
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
drivers/irqchip/Kconfig | 2 +-
drivers/irqchip/irq-riscv-rpmi-sysmsi.c | 47 +++++++++++++++++++++++--
2 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 96bf6aa55681..dfa8cc0e23dd 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -619,7 +619,7 @@ config RISCV_IMSIC
config RISCV_RPMI_SYSMSI
bool
- depends on MAILBOX
+ depends on RISCV && MAILBOX
select IRQ_DOMAIN_HIERARCHY
select GENERIC_MSI_IRQ
default RISCV
diff --git a/drivers/irqchip/irq-riscv-rpmi-sysmsi.c b/drivers/irqchip/irq-riscv-rpmi-sysmsi.c
index c42fceab71fa..6b64a93d3c87 100644
--- a/drivers/irqchip/irq-riscv-rpmi-sysmsi.c
+++ b/drivers/irqchip/irq-riscv-rpmi-sysmsi.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2025 Ventana Micro Systems Inc. */
+#include <linux/acpi.h>
#include <linux/bits.h>
#include <linux/bug.h>
#include <linux/device.h>
@@ -9,6 +10,7 @@
#include <linux/errno.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
+#include <linux/irqchip/riscv-imsic.h>
#include <linux/mailbox_client.h>
#include <linux/mailbox/riscv-rpmi-message.h>
#include <linux/module.h>
@@ -209,6 +211,8 @@ static int rpmi_sysmsi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct rpmi_sysmsi_priv *priv;
+ struct fwnode_handle *fwnode;
+ u32 id;
int rc;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -239,6 +243,22 @@ static int rpmi_sysmsi_probe(struct platform_device *pdev)
}
priv->nr_irqs = rc;
+ fwnode = dev_fwnode(dev);
+ if (is_acpi_node(fwnode)) {
+ u32 nr_irqs;
+
+ rc = riscv_acpi_get_gsi_info(fwnode, &priv->gsi_base, &id,
+ &nr_irqs, NULL);
+ if (rc) {
+ dev_err(dev, "failed to find GSI mapping\n");
+ return rc;
+ }
+
+ /* Update with actual GSI range */
+ if (nr_irqs != priv->nr_irqs)
+ riscv_acpi_update_gsi_range(priv->gsi_base, priv->nr_irqs);
+ }
+
/* Set the device MSI domain if not available */
if (!dev_get_msi_domain(dev)) {
/*
@@ -248,8 +268,15 @@ static int rpmi_sysmsi_probe(struct platform_device *pdev)
* then we need to set it explicitly before using any platform
* MSI functions.
*/
- if (dev_of_node(dev))
+ if (is_of_node(fwnode)) {
of_msi_configure(dev, dev_of_node(dev));
+ } else if (is_acpi_device_node(fwnode)) {
+ struct irq_domain *msi_domain;
+
+ msi_domain = irq_find_matching_fwnode(imsic_acpi_get_fwnode(dev),
+ DOMAIN_BUS_PLATFORM_MSI);
+ dev_set_msi_domain(dev, msi_domain);
+ }
if (!dev_get_msi_domain(dev)) {
mbox_free_channel(priv->chan);
@@ -264,6 +291,13 @@ static int rpmi_sysmsi_probe(struct platform_device *pdev)
return dev_err_probe(dev, -ENOMEM, "failed to create MSI irq domain\n");
}
+#ifdef CONFIG_ACPI
+ struct acpi_device *adev = ACPI_COMPANION(dev);
+
+ if (adev)
+ acpi_dev_clear_dependencies(adev);
+#endif
+
dev_info(dev, "%u system MSIs registered\n", priv->nr_irqs);
return 0;
}
@@ -273,10 +307,17 @@ static const struct of_device_id rpmi_sysmsi_match[] = {
{}
};
+static const struct acpi_device_id acpi_rpmi_sysmsi_match[] = {
+ { "RSCV0006" },
+ {}
+};
+MODULE_DEVICE_TABLE(acpi, acpi_rpmi_sysmsi_match);
+
static struct platform_driver rpmi_sysmsi_driver = {
.driver = {
- .name = "rpmi-sysmsi",
- .of_match_table = rpmi_sysmsi_match,
+ .name = "rpmi-sysmsi",
+ .of_match_table = rpmi_sysmsi_match,
+ .acpi_match_table = acpi_rpmi_sysmsi_match,
},
.probe = rpmi_sysmsi_probe,
};
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 23/24] RISC-V: Enable GPIO keyboard and event device in RV64 defconfig
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (21 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 22/24] irqchip/riscv-rpmi-sysmsi: " Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 24/24] MAINTAINERS: Add entry for RISC-V RPMI and MPXY drivers Anup Patel
23 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
The GPIO keyboard and event device can be used to receive graceful
shutdown or reboot input keys so let us enable it by default for
RV64 (just like ARM64).
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
arch/riscv/configs/defconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index fe8bd8afb418..bd5f97e1d1a0 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -138,6 +138,8 @@ CONFIG_MICREL_PHY=y
CONFIG_MICROSEMI_PHY=y
CONFIG_MOTORCOMM_PHY=y
CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_SUN4I_LRADC=m
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v7 24/24] MAINTAINERS: Add entry for RISC-V RPMI and MPXY drivers
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
` (22 preceding siblings ...)
2025-07-02 5:13 ` [PATCH v7 23/24] RISC-V: Enable GPIO keyboard and event device in RV64 defconfig Anup Patel
@ 2025-07-02 5:13 ` Anup Patel
23 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-02 5:13 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König
Cc: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Len Brown,
Sunil V L, Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Anup Patel
Add Rahul and myself as maintainers for RISC-V RPMI and MPXY drivers.
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
---
MAINTAINERS | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 4bac4ea21b64..c22434a2756b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21397,6 +21397,21 @@ F: drivers/perf/riscv_pmu.c
F: drivers/perf/riscv_pmu_legacy.c
F: drivers/perf/riscv_pmu_sbi.c
+RISC-V RPMI AND MPXY DRIVERS
+M: Rahul Pathak <rahul@summations.net>
+M: Anup Patel <anup@brainfault.org>
+L: linux-riscv@lists.infradead.org
+F: Documentation/devicetree/bindings/clock/riscv,rpmi-clock.yaml
+F: Documentation/devicetree/bindings/clock/riscv,rpmi-mpxy-clock.yaml
+F: Documentation/devicetree/bindings/interrupt-controller/riscv,rpmi-mpxy-system-msi.yaml
+F: Documentation/devicetree/bindings/interrupt-controller/riscv,rpmi-system-msi.yaml
+F: Documentation/devicetree/bindings/mailbox/riscv,rpmi-shmem-mbox.yaml
+F: Documentation/devicetree/bindings/mailbox/riscv,sbi-mpxy-mbox.yaml
+F: drivers/clk/clk-rpmi.c
+F: drivers/irqchip/irq-riscv-rpmi-sysmsi.c
+F: drivers/mailbox/riscv-sbi-mpxy-mbox.c
+F: include/linux/mailbox/riscv-rpmi-message.h
+
RISC-V SPACEMIT SoC Support
M: Yixun Lan <dlan@gentoo.org>
L: linux-riscv@lists.infradead.org
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* Re: [PATCH v7 14/24] ACPI: property: Refactor acpi_fwnode_get_reference_args()
2025-07-02 5:13 ` [PATCH v7 14/24] ACPI: property: Refactor acpi_fwnode_get_reference_args() Anup Patel
@ 2025-07-02 10:07 ` Rafael J. Wysocki
2025-07-02 14:45 ` Sunil V L
0 siblings, 1 reply; 55+ messages in thread
From: Rafael J. Wysocki @ 2025-07-02 10:07 UTC (permalink / raw)
To: Anup Patel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König, Palmer Dabbelt,
Paul Walmsley, Alexandre Ghiti, Len Brown, Sunil V L,
Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel
On Wed, Jul 2, 2025 at 7:15 AM Anup Patel <apatel@ventanamicro.com> wrote:
>
> From: Sunil V L <sunilvl@ventanamicro.com>
>
> Currently acpi_fwnode_get_reference_args() calls the public function
> __acpi_node_get_property_reference() which ignores the nargs_prop
> parameter.
Which I suppose is a problem. Why is it so?
> To fix this, make __acpi_node_get_property_reference() to
> call the static acpi_fwnode_get_reference() so that callers of
> fwnode_get_reference_args() can still pass a valid property name to
> fetch the number of arguments.
Are the current callers of acpi_fwnode_get_reference_args() going to
be affected by this change and if so, then how?
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> Signed-off-by: Anup Patel <apatel@ventanamicro.com>
> ---
> drivers/acpi/property.c | 101 ++++++++++++++++++++--------------------
> 1 file changed, 50 insertions(+), 51 deletions(-)
>
> diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
> index 436019d96027..d4863746fb11 100644
> --- a/drivers/acpi/property.c
> +++ b/drivers/acpi/property.c
> @@ -882,45 +882,10 @@ static struct fwnode_handle *acpi_parse_string_ref(const struct fwnode_handle *f
> return &dn->fwnode;
> }
>
> -/**
> - * __acpi_node_get_property_reference - returns handle to the referenced object
> - * @fwnode: Firmware node to get the property from
> - * @propname: Name of the property
> - * @index: Index of the reference to return
> - * @num_args: Maximum number of arguments after each reference
> - * @args: Location to store the returned reference with optional arguments
> - * (may be NULL)
> - *
> - * Find property with @name, verifify that it is a package containing at least
> - * one object reference and if so, store the ACPI device object pointer to the
> - * target object in @args->adev. If the reference includes arguments, store
> - * them in the @args->args[] array.
> - *
> - * If there's more than one reference in the property value package, @index is
> - * used to select the one to return.
> - *
> - * It is possible to leave holes in the property value set like in the
> - * example below:
> - *
> - * Package () {
> - * "cs-gpios",
> - * Package () {
> - * ^GPIO, 19, 0, 0,
> - * ^GPIO, 20, 0, 0,
> - * 0,
> - * ^GPIO, 21, 0, 0,
> - * }
> - * }
> - *
> - * Calling this function with index %2 or index %3 return %-ENOENT. If the
> - * property does not contain any more values %-ENOENT is returned. The NULL
> - * entry must be single integer and preferably contain value %0.
> - *
> - * Return: %0 on success, negative error code on failure.
> - */
> -int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
> - const char *propname, size_t index, size_t num_args,
> - struct fwnode_reference_args *args)
> +static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
> + const char *propname, const char *nargs_prop,
> + unsigned int args_count, unsigned int index,
> + struct fwnode_reference_args *args)
> {
> const union acpi_object *element, *end;
> const union acpi_object *obj;
> @@ -999,7 +964,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
>
> ret = acpi_get_ref_args(idx == index ? args : NULL,
> acpi_fwnode_handle(device),
> - &element, end, num_args);
> + &element, end, args_count);
> if (ret < 0)
> return ret;
>
> @@ -1017,7 +982,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
>
> ret = acpi_get_ref_args(idx == index ? args : NULL,
> ref_fwnode, &element, end,
> - num_args);
> + args_count);
> if (ret < 0)
> return ret;
>
> @@ -1039,6 +1004,50 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
>
> return -ENOENT;
> }
> +
> +/**
> + * __acpi_node_get_property_reference - returns handle to the referenced object
> + * @fwnode: Firmware node to get the property from
> + * @propname: Name of the property
> + * @index: Index of the reference to return
> + * @num_args: Maximum number of arguments after each reference
> + * @args: Location to store the returned reference with optional arguments
> + * (may be NULL)
> + *
> + * Find property with @name, verifify that it is a package containing at least
> + * one object reference and if so, store the ACPI device object pointer to the
> + * target object in @args->adev. If the reference includes arguments, store
> + * them in the @args->args[] array.
> + *
> + * If there's more than one reference in the property value package, @index is
> + * used to select the one to return.
> + *
> + * It is possible to leave holes in the property value set like in the
> + * example below:
> + *
> + * Package () {
> + * "cs-gpios",
> + * Package () {
> + * ^GPIO, 19, 0, 0,
> + * ^GPIO, 20, 0, 0,
> + * 0,
> + * ^GPIO, 21, 0, 0,
> + * }
> + * }
> + *
> + * Calling this function with index %2 or index %3 return %-ENOENT. If the
> + * property does not contain any more values %-ENOENT is returned. The NULL
> + * entry must be single integer and preferably contain value %0.
> + *
> + * Return: %0 on success, negative error code on failure.
> + */
> +int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
> + const char *propname, size_t index,
> + size_t num_args,
> + struct fwnode_reference_args *args)
> +{
> + return acpi_fwnode_get_reference_args(fwnode, propname, NULL, index, num_args, args);
> +}
> EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference);
>
> static int acpi_data_prop_read_single(const struct acpi_device_data *data,
> @@ -1558,16 +1567,6 @@ acpi_fwnode_property_read_string_array(const struct fwnode_handle *fwnode,
> val, nval);
> }
>
> -static int
> -acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
> - const char *prop, const char *nargs_prop,
> - unsigned int args_count, unsigned int index,
> - struct fwnode_reference_args *args)
> -{
> - return __acpi_node_get_property_reference(fwnode, prop, index,
> - args_count, args);
> -}
> -
> static const char *acpi_fwnode_get_name(const struct fwnode_handle *fwnode)
> {
> const struct acpi_device *adev;
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 15/24] ACPI: property: Add support for cells property
2025-07-02 5:13 ` [PATCH v7 15/24] ACPI: property: Add support for cells property Anup Patel
@ 2025-07-02 10:20 ` Rafael J. Wysocki
2025-07-02 11:37 ` Andy Shevchenko
2025-07-02 11:44 ` Andy Shevchenko
1 sibling, 1 reply; 55+ messages in thread
From: Rafael J. Wysocki @ 2025-07-02 10:20 UTC (permalink / raw)
To: Anup Patel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König, Palmer Dabbelt,
Paul Walmsley, Alexandre Ghiti, Len Brown, Sunil V L,
Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel
On Wed, Jul 2, 2025 at 7:16 AM Anup Patel <apatel@ventanamicro.com> wrote:
>
> From: Sunil V L <sunilvl@ventanamicro.com>
>
> Currently, ACPI doesn't support cells property when
> fwnode_property_get_reference_args() is called.
What exactly do you mean by "cells property" here and below?
> ACPI always expects
> the number of arguments to be passed. However, the above mentioned
> call being a common interface for OF and ACPI, it is better to have
> single calling convention which works for both. Hence, add support
> for cells property on the reference device to get the number of
> arguments dynamically.
>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> Signed-off-by: Anup Patel <apatel@ventanamicro.com>
> ---
> drivers/acpi/property.c | 22 ++++++++++++++++++----
> drivers/base/property.c | 2 +-
> 2 files changed, 19 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
> index d4863746fb11..d08b0ea5c915 100644
> --- a/drivers/acpi/property.c
> +++ b/drivers/acpi/property.c
> @@ -882,6 +882,17 @@ static struct fwnode_handle *acpi_parse_string_ref(const struct fwnode_handle *f
> return &dn->fwnode;
> }
>
> +static unsigned int acpi_fwnode_get_args_count(const struct acpi_device *device,
> + const char *nargs_prop)
> +{
> + const union acpi_object *obj;
> +
> + if (acpi_dev_get_property(device, nargs_prop, ACPI_TYPE_INTEGER, &obj))
> + return 0;
> +
> + return obj->integer.value;
> +}
> +
> static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
> const char *propname, const char *nargs_prop,
> unsigned int args_count, unsigned int index,
> @@ -892,6 +903,7 @@ static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
> const struct acpi_device_data *data;
> struct fwnode_handle *ref_fwnode;
> struct acpi_device *device;
> + unsigned int nargs_count;
> int ret, idx = 0;
>
> data = acpi_device_data_of_node(fwnode);
> @@ -960,11 +972,12 @@ static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
> if (!device)
> return -EINVAL;
>
> + nargs_count = acpi_fwnode_get_args_count(device, nargs_prop);
I think it should work the same way as it used to for the callers that
pass args_count, so maybe
if (!args_count)
args_count = acpi_fwnode_get_args_count(device, nargs_prop);
> element++;
> -
> ret = acpi_get_ref_args(idx == index ? args : NULL,
> acpi_fwnode_handle(device),
> - &element, end, args_count);
> + &element, end,
> + nargs_count ? nargs_count : args_count);
And this change would not be necessary?
And analogously below.
> if (ret < 0)
> return ret;
>
> @@ -978,11 +991,12 @@ static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
> if (!ref_fwnode)
> return -EINVAL;
>
> + device = to_acpi_device_node(ref_fwnode);
> + nargs_count = acpi_fwnode_get_args_count(device, nargs_prop);
> element++;
> -
> ret = acpi_get_ref_args(idx == index ? args : NULL,
> ref_fwnode, &element, end,
> - args_count);
> + nargs_count ? nargs_count : args_count);
> if (ret < 0)
> return ret;
>
> diff --git a/drivers/base/property.c b/drivers/base/property.c
> index f626d5bbe806..6a63860579dd 100644
> --- a/drivers/base/property.c
> +++ b/drivers/base/property.c
> @@ -578,7 +578,7 @@ EXPORT_SYMBOL_GPL(fwnode_property_match_property_string);
> * @prop: The name of the property
> * @nargs_prop: The name of the property telling the number of
> * arguments in the referred node. NULL if @nargs is known,
> - * otherwise @nargs is ignored. Only relevant on OF.
> + * otherwise @nargs is ignored.
> * @nargs: Number of arguments. Ignored if @nargs_prop is non-NULL.
> * @index: Index of the reference, from zero onwards.
> * @args: Result structure with reference and integer arguments.
> --
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 16/24] ACPI: scan: Update honor list for RPMI System MSI
2025-07-02 5:13 ` [PATCH v7 16/24] ACPI: scan: Update honor list for RPMI System MSI Anup Patel
@ 2025-07-02 10:21 ` Rafael J. Wysocki
2025-07-02 11:45 ` Andy Shevchenko
1 sibling, 0 replies; 55+ messages in thread
From: Rafael J. Wysocki @ 2025-07-02 10:21 UTC (permalink / raw)
To: Anup Patel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König, Palmer Dabbelt,
Paul Walmsley, Alexandre Ghiti, Len Brown, Sunil V L,
Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel, Atish Patra
On Wed, Jul 2, 2025 at 7:16 AM Anup Patel <apatel@ventanamicro.com> wrote:
>
> From: Sunil V L <sunilvl@ventanamicro.com>
>
> The RPMI System MSI interrupt controller (just like PLIC and APLIC)
> needs to probed prior to devices like GED which use interrupts provided
> by it. Also, it has dependency on the SBI MPXY mailbox device.
>
> Add HIDs of RPMI System MSI and SBI MPXY mailbox devices to the honor
> list so that those dependencies are handled.
>
> Reviewed-by: Atish Patra <atishp@rivosinc.com>
> Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
> Signed-off-by: Anup Patel <apatel@ventanamicro.com>
This is fine by me, so
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
> drivers/acpi/scan.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index fb1fe9f3b1a3..54181b03b345 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -858,6 +858,8 @@ static const char * const acpi_honor_dep_ids[] = {
> "INTC10CF", /* IVSC (MTL) driver must be loaded to allow i2c access to camera sensors */
> "RSCV0001", /* RISC-V PLIC */
> "RSCV0002", /* RISC-V APLIC */
> + "RSCV0005", /* RISC-V SBI MPXY MBOX */
> + "RSCV0006", /* RISC-V RPMI SYSMSI */
> "PNP0C0F", /* PCI Link Device */
> NULL
> };
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 06/24] byteorder: Add memcpy_to_le32() and memcpy_from_le32()
2025-07-02 5:13 ` [PATCH v7 06/24] byteorder: Add memcpy_to_le32() and memcpy_from_le32() Anup Patel
@ 2025-07-02 11:30 ` Andy Shevchenko
2025-07-04 8:16 ` Linus Walleij
1 sibling, 0 replies; 55+ messages in thread
From: Andy Shevchenko @ 2025-07-02 11:30 UTC (permalink / raw)
To: Anup Patel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Linus Walleij, Bartosz Golaszewski,
Uwe Kleine-König, Palmer Dabbelt, Paul Walmsley,
Alexandre Ghiti, Len Brown, Sunil V L, Rahul Pathak, Leyfoon Tan,
Atish Patra, Andrew Jones, Samuel Holland, Anup Patel, linux-clk,
devicetree, linux-acpi, linux-riscv, linux-kernel
On Wed, Jul 02, 2025 at 10:43:27AM +0530, Anup Patel wrote:
> Add common memcpy APIs for copying u32 array to/from __le32 array.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 15/24] ACPI: property: Add support for cells property
2025-07-02 10:20 ` Rafael J. Wysocki
@ 2025-07-02 11:37 ` Andy Shevchenko
2025-07-02 11:39 ` Andy Shevchenko
2025-07-02 12:39 ` Rafael J. Wysocki
0 siblings, 2 replies; 55+ messages in thread
From: Andy Shevchenko @ 2025-07-02 11:37 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Anup Patel, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jassi Brar, Thomas Gleixner,
Mika Westerberg, Linus Walleij, Bartosz Golaszewski,
Uwe Kleine-König, Palmer Dabbelt, Paul Walmsley,
Alexandre Ghiti, Len Brown, Sunil V L, Rahul Pathak, Leyfoon Tan,
Atish Patra, Andrew Jones, Samuel Holland, Anup Patel, linux-clk,
devicetree, linux-acpi, linux-riscv, linux-kernel
On Wed, Jul 02, 2025 at 12:20:55PM +0200, Rafael J. Wysocki wrote:
> On Wed, Jul 2, 2025 at 7:16 AM Anup Patel <apatel@ventanamicro.com> wrote:
...
> > static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
> > const char *propname, const char *nargs_prop,
> > unsigned int args_count, unsigned int index,
> > const struct acpi_device_data *data;
> > struct fwnode_handle *ref_fwnode;
> > struct acpi_device *device;
> > + unsigned int nargs_count;
> > int ret, idx = 0;
> > + nargs_count = acpi_fwnode_get_args_count(device, nargs_prop);
>
> I think it should work the same way as it used to for the callers that
> pass args_count, so maybe
>
> if (!args_count)
> args_count = acpi_fwnode_get_args_count(device, nargs_prop);
But this is different variable.
> > element++;
> > -
> > ret = acpi_get_ref_args(idx == index ? args : NULL,
> > acpi_fwnode_handle(device),
> > - &element, end, args_count);
> > + &element, end,
> > + nargs_count ? nargs_count : args_count);
>
> And this change would not be necessary?
This is not the same check as proposed above.
But this can be made shorter with Elvis in use:
&element, end, nargs_count ?: args_count);
> And analogously below.
And below. And in case if there is a new proposal to have
if (!nargs_count)
args_count = acpi_fwnode_get_args_count(device, nargs_prop);
that is exactly what I asked to drop as it's included in the
acpi_fwnode_get_args_count() already, i.e. no need to check this in
the caller and in the callee.
> > if (ret < 0)
> > return ret;
...
> > if (!ref_fwnode)
> > return -EINVAL;
> >
> > + device = to_acpi_device_node(ref_fwnode);
> > + nargs_count = acpi_fwnode_get_args_count(device, nargs_prop);
> > element++;
> > -
> > ret = acpi_get_ref_args(idx == index ? args : NULL,
> > ref_fwnode, &element, end,
> > - args_count);
> > + nargs_count ? nargs_count : args_count);
> > if (ret < 0)
> > return ret;
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 15/24] ACPI: property: Add support for cells property
2025-07-02 11:37 ` Andy Shevchenko
@ 2025-07-02 11:39 ` Andy Shevchenko
2025-07-02 12:39 ` Rafael J. Wysocki
1 sibling, 0 replies; 55+ messages in thread
From: Andy Shevchenko @ 2025-07-02 11:39 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Anup Patel, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jassi Brar, Thomas Gleixner,
Mika Westerberg, Linus Walleij, Bartosz Golaszewski,
Uwe Kleine-König, Palmer Dabbelt, Paul Walmsley,
Alexandre Ghiti, Len Brown, Sunil V L, Rahul Pathak, Leyfoon Tan,
Atish Patra, Andrew Jones, Samuel Holland, Anup Patel, linux-clk,
devicetree, linux-acpi, linux-riscv, linux-kernel
On Wed, Jul 02, 2025 at 02:37:58PM +0300, Andy Shevchenko wrote:
> On Wed, Jul 02, 2025 at 12:20:55PM +0200, Rafael J. Wysocki wrote:
> > On Wed, Jul 2, 2025 at 7:16 AM Anup Patel <apatel@ventanamicro.com> wrote:
...
> > > static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
> > > const char *propname, const char *nargs_prop,
> > > unsigned int args_count, unsigned int index,
>
> > > const struct acpi_device_data *data;
> > > struct fwnode_handle *ref_fwnode;
> > > struct acpi_device *device;
> > > + unsigned int nargs_count;
> > > int ret, idx = 0;
>
> > > + nargs_count = acpi_fwnode_get_args_count(device, nargs_prop);
> >
> > I think it should work the same way as it used to for the callers that
> > pass args_count, so maybe
> >
> > if (!args_count)
> > args_count = acpi_fwnode_get_args_count(device, nargs_prop);
>
> But this is different variable.
>
> > > element++;
> > > -
> > > ret = acpi_get_ref_args(idx == index ? args : NULL,
> > > acpi_fwnode_handle(device),
> > > - &element, end, args_count);
> > > + &element, end,
> > > + nargs_count ? nargs_count : args_count);
> >
> > And this change would not be necessary?
>
> This is not the same check as proposed above.
> But this can be made shorter with Elvis in use:
>
> &element, end, nargs_count ?: args_count);
>
> > And analogously below.
>
> And below. And in case if there is a new proposal to have
>
> if (!nargs_count)
I meant
if (!nargs_prop)
here of course.
> args_count = acpi_fwnode_get_args_count(device, nargs_prop);
>
> that is exactly what I asked to drop as it's included in the
> acpi_fwnode_get_args_count() already, i.e. no need to check this in
> the caller and in the callee.
>
> > > if (ret < 0)
> > > return ret;
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 15/24] ACPI: property: Add support for cells property
2025-07-02 5:13 ` [PATCH v7 15/24] ACPI: property: Add support for cells property Anup Patel
2025-07-02 10:20 ` Rafael J. Wysocki
@ 2025-07-02 11:44 ` Andy Shevchenko
1 sibling, 0 replies; 55+ messages in thread
From: Andy Shevchenko @ 2025-07-02 11:44 UTC (permalink / raw)
To: Anup Patel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Linus Walleij, Bartosz Golaszewski,
Uwe Kleine-König, Palmer Dabbelt, Paul Walmsley,
Alexandre Ghiti, Len Brown, Sunil V L, Rahul Pathak, Leyfoon Tan,
Atish Patra, Andrew Jones, Samuel Holland, Anup Patel, linux-clk,
devicetree, linux-acpi, linux-riscv, linux-kernel
On Wed, Jul 02, 2025 at 10:43:36AM +0530, Anup Patel wrote:
> From: Sunil V L <sunilvl@ventanamicro.com>
>
> Currently, ACPI doesn't support cells property when
> fwnode_property_get_reference_args() is called. ACPI always expects
> the number of arguments to be passed. However, the above mentioned
> call being a common interface for OF and ACPI, it is better to have
> single calling convention which works for both. Hence, add support
> for cells property on the reference device to get the number of
> arguments dynamically.
You can use Elvis to shorten lines, but in my opinion this is okay change
overall. FWIW,
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
>
> + nargs_count = acpi_fwnode_get_args_count(device, nargs_prop);
> element++;
> -
u probably want to leave this blank line and rather move the new code here
element++;
nargs_count = acpi_fwnode_get_args_count(device, nargs_prop);
> ret = acpi_get_ref_args(idx == index ? args : NULL,
> acpi_fwnode_handle(device),
> - &element, end, args_count);
> + &element, end,
> + nargs_count ? nargs_count : args_count);
&element, end, nargs_count ?: args_count);
> if (ret < 0)
> return ret;
...
> + device = to_acpi_device_node(ref_fwnode);
> + nargs_count = acpi_fwnode_get_args_count(device, nargs_prop);
> element++;
> -
> ret = acpi_get_ref_args(idx == index ? args : NULL,
> ref_fwnode, &element, end,
> - args_count);
> + nargs_count ? nargs_count : args_count);
> if (ret < 0)
> return ret;
As per above.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 16/24] ACPI: scan: Update honor list for RPMI System MSI
2025-07-02 5:13 ` [PATCH v7 16/24] ACPI: scan: Update honor list for RPMI System MSI Anup Patel
2025-07-02 10:21 ` Rafael J. Wysocki
@ 2025-07-02 11:45 ` Andy Shevchenko
1 sibling, 0 replies; 55+ messages in thread
From: Andy Shevchenko @ 2025-07-02 11:45 UTC (permalink / raw)
To: Anup Patel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Linus Walleij, Bartosz Golaszewski,
Uwe Kleine-König, Palmer Dabbelt, Paul Walmsley,
Alexandre Ghiti, Len Brown, Sunil V L, Rahul Pathak, Leyfoon Tan,
Atish Patra, Andrew Jones, Samuel Holland, Anup Patel, linux-clk,
devicetree, linux-acpi, linux-riscv, linux-kernel, Atish Patra
On Wed, Jul 02, 2025 at 10:43:37AM +0530, Anup Patel wrote:
>
> The RPMI System MSI interrupt controller (just like PLIC and APLIC)
> needs to probed prior to devices like GED which use interrupts provided
> by it. Also, it has dependency on the SBI MPXY mailbox device.
>
> Add HIDs of RPMI System MSI and SBI MPXY mailbox devices to the honor
> list so that those dependencies are handled.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 03/24] RISC-V: Add defines for the SBI message proxy extension
2025-07-02 5:13 ` [PATCH v7 03/24] RISC-V: Add defines for the SBI message proxy extension Anup Patel
@ 2025-07-02 12:03 ` Andy Shevchenko
2025-07-02 12:06 ` Andy Shevchenko
1 sibling, 0 replies; 55+ messages in thread
From: Andy Shevchenko @ 2025-07-02 12:03 UTC (permalink / raw)
To: Anup Patel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Linus Walleij, Bartosz Golaszewski,
Uwe Kleine-König, Palmer Dabbelt, Paul Walmsley,
Alexandre Ghiti, Len Brown, Sunil V L, Rahul Pathak, Leyfoon Tan,
Atish Patra, Andrew Jones, Samuel Holland, Anup Patel, linux-clk,
devicetree, linux-acpi, linux-riscv, linux-kernel, Atish Patra
On Wed, Jul 02, 2025 at 10:43:24AM +0530, Anup Patel wrote:
> Add defines for the new SBI message proxy extension which is part
> of the SBI v3.0 specification.
LGTM,
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 03/24] RISC-V: Add defines for the SBI message proxy extension
2025-07-02 5:13 ` [PATCH v7 03/24] RISC-V: Add defines for the SBI message proxy extension Anup Patel
2025-07-02 12:03 ` Andy Shevchenko
@ 2025-07-02 12:06 ` Andy Shevchenko
2025-07-03 5:16 ` Anup Patel
1 sibling, 1 reply; 55+ messages in thread
From: Andy Shevchenko @ 2025-07-02 12:06 UTC (permalink / raw)
To: Anup Patel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Linus Walleij, Bartosz Golaszewski,
Uwe Kleine-König, Palmer Dabbelt, Paul Walmsley,
Alexandre Ghiti, Len Brown, Sunil V L, Rahul Pathak, Leyfoon Tan,
Atish Patra, Andrew Jones, Samuel Holland, Anup Patel, linux-clk,
devicetree, linux-acpi, linux-riscv, linux-kernel, Atish Patra
On Wed, Jul 02, 2025 at 10:43:24AM +0530, Anup Patel wrote:
> Add defines for the new SBI message proxy extension which is part
> of the SBI v3.0 specification.
Actually a few nit-picks.
...
> +enum sbi_ext_mpxy_fid {
> + SBI_EXT_MPXY_GET_SHMEM_SIZE,
> + SBI_EXT_MPXY_SET_SHMEM,
> + SBI_EXT_MPXY_GET_CHANNEL_IDS,
> + SBI_EXT_MPXY_READ_ATTRS,
> + SBI_EXT_MPXY_WRITE_ATTRS,
> + SBI_EXT_MPXY_SEND_MSG_WITH_RESP,
> + SBI_EXT_MPXY_SEND_MSG_WITHOUT_RESP,
> + SBI_EXT_MPXY_GET_NOTIFICATION_EVENTS
Add a trailing comma.
> +};
...
> +/* Possible values of MSG_PROT_ID attribute */
> +enum sbi_mpxy_msgproto_id {
> + SBI_MPXY_MSGPROTO_RPMI_ID = 0x0
Add a trailing comma, and you might want to drop 0x. I don't know what else can
be here, esp. in the future, but some kind of the description of this in TRM
can shed a light on what is better pattern to use.
> +};
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 21/24] mailbox/riscv-sbi-mpxy: Add ACPI support
2025-07-02 5:13 ` [PATCH v7 21/24] mailbox/riscv-sbi-mpxy: Add ACPI support Anup Patel
@ 2025-07-02 12:28 ` Andy Shevchenko
2025-07-03 10:54 ` Sunil V L
0 siblings, 1 reply; 55+ messages in thread
From: Andy Shevchenko @ 2025-07-02 12:28 UTC (permalink / raw)
To: Anup Patel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Linus Walleij, Bartosz Golaszewski,
Uwe Kleine-König, Palmer Dabbelt, Paul Walmsley,
Alexandre Ghiti, Len Brown, Sunil V L, Rahul Pathak, Leyfoon Tan,
Atish Patra, Andrew Jones, Samuel Holland, Anup Patel, linux-clk,
devicetree, linux-acpi, linux-riscv, linux-kernel
On Wed, Jul 02, 2025 at 10:43:42AM +0530, Anup Patel wrote:
> From: Sunil V L <sunilvl@ventanamicro.com>
>
> Add ACPI support for the RISC-V SBI message proxy (MPXY) based
> mailbox driver.
...
> - if (dev_of_node(dev))
> + if (is_of_node(fwnode)) {
> of_msi_configure(dev, dev_of_node(dev));
> + } else if (is_acpi_device_node(fwnode)) {
> + msi_domain = irq_find_matching_fwnode(imsic_acpi_get_fwnode(dev),
> + DOMAIN_BUS_PLATFORM_MSI);
> + dev_set_msi_domain(dev, msi_domain);
> + }
Actually you don't need to have the if-else-if if I am not mistaken.
The OF does almost the same as it's done in the second branch for ACPI case.
How many MSI parents this may have?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 05/24] mailbox: Allow controller specific mapping using fwnode
2025-07-02 5:13 ` [PATCH v7 05/24] mailbox: Allow controller specific mapping using fwnode Anup Patel
@ 2025-07-02 12:32 ` Andy Shevchenko
0 siblings, 0 replies; 55+ messages in thread
From: Andy Shevchenko @ 2025-07-02 12:32 UTC (permalink / raw)
To: Anup Patel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Linus Walleij, Bartosz Golaszewski,
Uwe Kleine-König, Palmer Dabbelt, Paul Walmsley,
Alexandre Ghiti, Len Brown, Sunil V L, Rahul Pathak, Leyfoon Tan,
Atish Patra, Andrew Jones, Samuel Holland, Anup Patel, linux-clk,
devicetree, linux-acpi, linux-riscv, linux-kernel
On Wed, Jul 02, 2025 at 10:43:26AM +0530, Anup Patel wrote:
> Introduce optional fw_node() callback which allows a mailbox controller
> driver to provide controller specific mapping using fwnode.
>
> The Linux OF framework already implements fwnode operations for the
> Linux DD framework so the fw_xlate() callback works fine with device
> tree as well.
Looks okay to me, FWIW,
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 15/24] ACPI: property: Add support for cells property
2025-07-02 11:37 ` Andy Shevchenko
2025-07-02 11:39 ` Andy Shevchenko
@ 2025-07-02 12:39 ` Rafael J. Wysocki
2025-07-02 12:56 ` Andy Shevchenko
2025-07-02 15:06 ` Sunil V L
1 sibling, 2 replies; 55+ messages in thread
From: Rafael J. Wysocki @ 2025-07-02 12:39 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Rafael J. Wysocki, Anup Patel, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jassi Brar,
Thomas Gleixner, Mika Westerberg, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König, Palmer Dabbelt,
Paul Walmsley, Alexandre Ghiti, Len Brown, Sunil V L,
Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel
On Wed, Jul 2, 2025 at 1:38 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> On Wed, Jul 02, 2025 at 12:20:55PM +0200, Rafael J. Wysocki wrote:
> > On Wed, Jul 2, 2025 at 7:16 AM Anup Patel <apatel@ventanamicro.com> wrote:
>
> ...
>
> > > static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
> > > const char *propname, const char *nargs_prop,
> > > unsigned int args_count, unsigned int index,
>
> > > const struct acpi_device_data *data;
> > > struct fwnode_handle *ref_fwnode;
> > > struct acpi_device *device;
> > > + unsigned int nargs_count;
> > > int ret, idx = 0;
>
> > > + nargs_count = acpi_fwnode_get_args_count(device, nargs_prop);
> >
> > I think it should work the same way as it used to for the callers that
> > pass args_count, so maybe
> >
> > if (!args_count)
> > args_count = acpi_fwnode_get_args_count(device, nargs_prop);
>
> But this is different variable.
Of course it is different. It is an acpi_fwnode_get_reference_args() parameter.
> > > element++;
> > > -
> > > ret = acpi_get_ref_args(idx == index ? args : NULL,
> > > acpi_fwnode_handle(device),
> > > - &element, end, args_count);
> > > + &element, end,
> > > + nargs_count ? nargs_count : args_count);
> >
> > And this change would not be necessary?
>
> This is not the same check as proposed above.
No, it is not.
It just makes the function work the same way it did before the change
for the callers who passed nozero args_count and so they might be
forgiven expecting that it would be taken into account.
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 07/24] mailbox: Add RISC-V SBI message proxy (MPXY) based mailbox driver
2025-07-02 5:13 ` [PATCH v7 07/24] mailbox: Add RISC-V SBI message proxy (MPXY) based mailbox driver Anup Patel
@ 2025-07-02 12:50 ` Andy Shevchenko
2025-07-03 6:52 ` Anup Patel
0 siblings, 1 reply; 55+ messages in thread
From: Andy Shevchenko @ 2025-07-02 12:50 UTC (permalink / raw)
To: Anup Patel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Linus Walleij, Bartosz Golaszewski,
Uwe Kleine-König, Palmer Dabbelt, Paul Walmsley,
Alexandre Ghiti, Len Brown, Sunil V L, Rahul Pathak, Leyfoon Tan,
Atish Patra, Andrew Jones, Samuel Holland, Anup Patel, linux-clk,
devicetree, linux-acpi, linux-riscv, linux-kernel
On Wed, Jul 02, 2025 at 10:43:28AM +0530, Anup Patel wrote:
> Add a mailbox controller driver for the new SBI message proxy extension
> which is part of the SBI v3.0 specification.
...
> +#include <linux/cpu.h>
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/mailbox_controller.h>
> +#include <linux/mailbox/riscv-rpmi-message.h>
+ minmax.h
> +#include <linux/mm.h>
> +#include <linux/module.h>
> +#include <linux/msi.h>
> +#include <linux/of_irq.h>
> +#include <linux/percpu.h>
> +#include <linux/platform_device.h>
> +#include <linux/smp.h>
> +#include <linux/string.h>
> +#include <linux/types.h>
> +#include <asm/byteorder.h>
> +#include <asm/sbi.h>
...
> +static void mpxy_mbox_send_rpmi_data(struct mpxy_mbox_channel *mchan,
> + struct rpmi_mbox_message *msg)
> +{
> + int rc = 0;
Is it useful? I mean can you assign msg.error directly in each case?
(Just asking)
> + switch (msg->type) {
> + case RPMI_MBOX_MSG_TYPE_GET_ATTRIBUTE:
> + switch (msg->attr.id) {
> + case RPMI_MBOX_ATTR_SPEC_VERSION:
> + msg->attr.value = mchan->attrs.msg_proto_version;
> + break;
> + case RPMI_MBOX_ATTR_MAX_MSG_DATA_SIZE:
> + msg->attr.value = mchan->max_xfer_len;
> + break;
> + case RPMI_MBOX_ATTR_SERVICEGROUP_ID:
> + msg->attr.value = mchan->rpmi_attrs.servicegroup_id;
> + break;
> + case RPMI_MBOX_ATTR_SERVICEGROUP_VERSION:
> + msg->attr.value = mchan->rpmi_attrs.servicegroup_version;
> + break;
> + case RPMI_MBOX_ATTR_IMPL_ID:
> + msg->attr.value = mchan->rpmi_attrs.impl_id;
> + break;
> + case RPMI_MBOX_ATTR_IMPL_VERSION:
> + msg->attr.value = mchan->rpmi_attrs.impl_version;
> + break;
> + default:
> + rc = -EOPNOTSUPP;
> + break;
> + }
> + break;
> + case RPMI_MBOX_MSG_TYPE_SET_ATTRIBUTE:
> + /* None of the RPMI linux mailbox attributes are writeable */
> + rc = -EOPNOTSUPP;
> + break;
> + case RPMI_MBOX_MSG_TYPE_SEND_WITH_RESPONSE:
> + if ((!msg->data.request && msg->data.request_len) ||
> + (msg->data.request &&
> + msg->data.request_len > mchan->max_xfer_len) ||
> + (!msg->data.response && msg->data.max_response_len)) {
> + rc = -EINVAL;
> + break;
> + }
> + if (!(mchan->attrs.capability & SBI_MPXY_CHAN_CAP_SEND_WITH_RESP)) {
> + rc = -EIO;
> + break;
> + }
> + rc = mpxy_send_message_with_resp(mchan->channel_id,
> + msg->data.service_id,
> + msg->data.request,
> + msg->data.request_len,
> + msg->data.response,
> + msg->data.max_response_len,
> + &msg->data.out_response_len);
> + break;
> + case RPMI_MBOX_MSG_TYPE_SEND_WITHOUT_RESPONSE:
> + if ((!msg->data.request && msg->data.request_len) ||
> + (msg->data.request &&
> + msg->data.request_len > mchan->max_xfer_len)) {
> + rc = -EINVAL;
> + break;
> + }
> + if (!(mchan->attrs.capability & SBI_MPXY_CHAN_CAP_SEND_WITHOUT_RESP)) {
> + rc = -EIO;
> + break;
> + }
> + rc = mpxy_send_message_without_resp(mchan->channel_id,
> + msg->data.service_id,
> + msg->data.request,
> + msg->data.request_len);
> + break;
> + default:
> + rc = -EOPNOTSUPP;
> + break;
> + }
> +
> + msg->error = rc;
> +}
...
> +static void mpxy_mbox_peek_rpmi_data(struct mbox_chan *chan,
> + struct mpxy_mbox_channel *mchan,
> + struct sbi_mpxy_notification_data *notif,
> + unsigned long events_data_len)
> +{
> + struct rpmi_notification_event *event;
> + unsigned long pos = 0, event_size;
> + struct rpmi_mbox_message msg;
> +
> + while ((pos < events_data_len) && !(pos & 0x3) &&
0x3 looks like a magic used for the non-aligned data.
> + ((events_data_len - pos) <= sizeof(*event))) {
> + event = (struct rpmi_notification_event *)(notif->events_data + pos);
> +
> + msg.type = RPMI_MBOX_MSG_TYPE_NOTIFICATION_EVENT;
> + msg.notif.event_datalen = le16_to_cpu(event->event_datalen);
> + msg.notif.event_id = event->event_id;
> + msg.notif.event_data = event->event_data;
> + msg.error = 0;
> +
> + event_size = sizeof(*event) + msg.notif.event_datalen;
Do you trust the source? This may wrap-around...
> + if (event_size > (events_data_len - pos)) {
> + event_size = events_data_len - pos;
> + goto skip_event;
> + }
> + if (event_size & 0x3)
> + goto skip_event;
...and these checks be skipped. Is it a problem?
> + mbox_chan_received_data(chan, &msg);
> +skip_event:
I think this may be replaced by a continue inside if you make a loop to be
do {} while (). But it's just a thought, you can check if it gives a better
readability after all.
> + pos += event_size;
> + }
> +}
...
> +static int mpxy_mbox_probe(struct platform_device *pdev)
> +{
> + u32 i, *channel_ids __free(kfree) = NULL;
It's not recommended. Can you split channel_ids to the actual scope where it's
used? Somewhere...
> + struct device *dev = &pdev->dev;
> + struct mpxy_mbox_channel *mchan;
> + struct mpxy_mbox *mbox;
> + int msi_idx, rc;
> +
> + /*
> + * Initialize MPXY shared memory only once. This also ensures
> + * that SBI MPXY mailbox is probed only once.
> + */
> + if (mpxy_shmem_init_done) {
> + dev_err(dev, "SBI MPXY mailbox already initialized\n");
> + return -EALREADY;
> + }
> +
> + /* Probe for SBI MPXY extension */
> + if (sbi_spec_version < sbi_mk_version(1, 0) ||
> + sbi_probe_extension(SBI_EXT_MPXY) <= 0) {
> + dev_info(dev, "SBI MPXY extension not available\n");
> + return -ENODEV;
> + }
> +
> + /* Find-out shared memory size */
> + rc = mpxy_get_shmem_size(&mpxy_shmem_size);
> + if (rc)
> + return dev_err_probe(dev, rc, "failed to get MPXY shared memory size\n");
> +
> + /*
> + * Setup MPXY shared memory on each CPU
> + *
> + * Note: Don't cleanup MPXY shared memory upon CPU power-down
> + * because the RPMI System MSI irqchip driver needs it to be
> + * available when migrating IRQs in CPU power-down path.
> + */
> + cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "riscv/sbi-mpxy-shmem",
> + mpxy_setup_shmem, NULL);
> +
> + /* Mark as MPXY shared memory initialization done */
> + mpxy_shmem_init_done = true;
> +
> + /* Allocate mailbox instance */
> + mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
> + if (!mbox)
> + return -ENOMEM;
> + mbox->dev = dev;
> + platform_set_drvdata(pdev, mbox);
> +
> + /* Find-out of number of channels */
> + rc = mpxy_get_channel_count(&mbox->channel_count);
> + if (rc)
> + return dev_err_probe(dev, rc, "failed to get number of MPXY channels\n");
> + if (!mbox->channel_count)
> + dev_err_probe(dev, -ENODEV, "no MPXY channels available\n");
> +
> + /* Allocate and fetch all channel IDs */
> + channel_ids = kcalloc(mbox->channel_count, sizeof(*channel_ids), GFP_KERNEL);
...here.
> + if (!channel_ids)
> + return -ENOMEM;
> + rc = mpxy_get_channel_ids(mbox->channel_count, channel_ids);
> + if (rc)
> + return dev_err_probe(dev, rc, "failed to get MPXY channel IDs\n");
> +
> + /* Populate all channels */
> + mbox->channels = devm_kcalloc(dev, mbox->channel_count,
> + sizeof(*mbox->channels), GFP_KERNEL);
> + if (!mbox->channels)
> + return -ENOMEM;
> + for (i = 0; i < mbox->channel_count; i++) {
> + mchan = &mbox->channels[i];
> + mchan->mbox = mbox;
> + mchan->channel_id = channel_ids[i];
> +
> + rc = mpxy_read_attrs(mchan->channel_id, SBI_MPXY_ATTR_MSG_PROT_ID,
> + sizeof(mchan->attrs) / sizeof(u32),
> + (u32 *)&mchan->attrs);
> + if (rc) {
> + return dev_err_probe(dev, rc,
> + "MPXY channel 0x%x read attrs failed\n",
> + mchan->channel_id);
> + }
> +
> + if (mchan->attrs.msg_proto_id == SBI_MPXY_MSGPROTO_RPMI_ID) {
> + rc = mpxy_mbox_read_rpmi_attrs(mchan);
> + if (rc) {
> + return dev_err_probe(dev, rc,
> + "MPXY channel 0x%x read RPMI attrs failed\n",
> + mchan->channel_id);
> + }
> + }
> +
> + mchan->notif = devm_kzalloc(dev, mpxy_shmem_size, GFP_KERNEL);
> + if (!mchan->notif)
> + return -ENOMEM;
> +
> + mchan->max_xfer_len = min(mpxy_shmem_size, mchan->attrs.msg_max_len);
> +
> + if ((mchan->attrs.capability & SBI_MPXY_CHAN_CAP_GET_NOTIFICATIONS) &&
> + (mchan->attrs.capability & SBI_MPXY_CHAN_CAP_EVENTS_STATE))
> + mchan->have_events_state = true;
> +
> + if ((mchan->attrs.capability & SBI_MPXY_CHAN_CAP_GET_NOTIFICATIONS) &&
> + (mchan->attrs.capability & SBI_MPXY_CHAN_CAP_MSI))
> + mchan->msi_index = mbox->msi_count++;
> + else
> + mchan->msi_index = U32_MAX;
> + mchan->msi_irq = U32_MAX;
> + }
> +
> + /* Initialize mailbox controller */
> + mbox->controller.txdone_irq = false;
> + mbox->controller.txdone_poll = false;
> + mbox->controller.ops = &mpxy_mbox_ops;
> + mbox->controller.dev = dev;
> + mbox->controller.num_chans = mbox->channel_count;
> + mbox->controller.fw_xlate = mpxy_mbox_fw_xlate;
> + mbox->controller.chans = devm_kcalloc(dev, mbox->channel_count,
> + sizeof(*mbox->controller.chans),
> + GFP_KERNEL);
> + if (!mbox->controller.chans)
> + return -ENOMEM;
> + for (i = 0; i < mbox->channel_count; i++)
> + mbox->controller.chans[i].con_priv = &mbox->channels[i];
> +
> + /* Set the MSI domain if not available */
> + if (!dev_get_msi_domain(dev)) {
> + /*
> + * The device MSI domain for OF devices is only set at the
> + * time of populating/creating OF device. If the device MSI
> + * domain is discovered later after the OF device is created
> + * then we need to set it explicitly before using any platform
> + * MSI functions.
> + */
> + if (dev_of_node(dev))
Do you really need this check? What about ACPI?
> + of_msi_configure(dev, dev_of_node(dev));
> + }
> +
> + /* Setup MSIs for mailbox (if required) */
> + if (mbox->msi_count) {
> + mbox->msi_index_to_channel = devm_kcalloc(dev, mbox->msi_count,
> + sizeof(*mbox->msi_index_to_channel),
> + GFP_KERNEL);
> + if (!mbox->msi_index_to_channel)
> + return -ENOMEM;
> +
> + for (msi_idx = 0; msi_idx < mbox->msi_count; msi_idx++) {
> + for (i = 0; i < mbox->channel_count; i++) {
> + mchan = &mbox->channels[i];
> + if (mchan->msi_index == msi_idx) {
> + mbox->msi_index_to_channel[msi_idx] = mchan;
> + break;
> + }
> + }
> + }
> +
> + rc = platform_device_msi_init_and_alloc_irqs(dev, mbox->msi_count,
> + mpxy_mbox_msi_write);
> + if (rc) {
> + return dev_err_probe(dev, rc, "Failed to allocate %d MSIs\n",
> + mbox->msi_count);
> + }
> +
> + for (i = 0; i < mbox->channel_count; i++) {
> + mchan = &mbox->channels[i];
> + if (mchan->msi_index == U32_MAX)
> + continue;
> + mchan->msi_irq = msi_get_virq(dev, mchan->msi_index);
> + }
> + }
> +
> + /* Register mailbox controller */
> + rc = devm_mbox_controller_register(dev, &mbox->controller);
> + if (rc) {
> + dev_err_probe(dev, rc, "Registering SBI MPXY mailbox failed\n");
> + if (mbox->msi_count)
> + platform_device_msi_free_irqs_all(dev);
> + return rc;
> + }
> + dev_info(dev, "mailbox registered with %d channels\n",
> + mbox->channel_count);
Working driver doesn't need to issue a message.
> + return 0;
> +}
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 15/24] ACPI: property: Add support for cells property
2025-07-02 12:39 ` Rafael J. Wysocki
@ 2025-07-02 12:56 ` Andy Shevchenko
2025-07-02 13:16 ` Rafael J. Wysocki
2025-07-02 15:06 ` Sunil V L
1 sibling, 1 reply; 55+ messages in thread
From: Andy Shevchenko @ 2025-07-02 12:56 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Anup Patel, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jassi Brar, Thomas Gleixner,
Mika Westerberg, Linus Walleij, Bartosz Golaszewski,
Uwe Kleine-König, Palmer Dabbelt, Paul Walmsley,
Alexandre Ghiti, Len Brown, Sunil V L, Rahul Pathak, Leyfoon Tan,
Atish Patra, Andrew Jones, Samuel Holland, Anup Patel, linux-clk,
devicetree, linux-acpi, linux-riscv, linux-kernel
On Wed, Jul 02, 2025 at 02:39:30PM +0200, Rafael J. Wysocki wrote:
> On Wed, Jul 2, 2025 at 1:38 PM Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
> > On Wed, Jul 02, 2025 at 12:20:55PM +0200, Rafael J. Wysocki wrote:
> > > On Wed, Jul 2, 2025 at 7:16 AM Anup Patel <apatel@ventanamicro.com> wrote:
...
> > > > static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
> > > > const char *propname, const char *nargs_prop,
> > > > unsigned int args_count, unsigned int index,
> >
> > > > const struct acpi_device_data *data;
> > > > struct fwnode_handle *ref_fwnode;
> > > > struct acpi_device *device;
> > > > + unsigned int nargs_count;
> > > > int ret, idx = 0;
> >
> > > > + nargs_count = acpi_fwnode_get_args_count(device, nargs_prop);
> > >
> > > I think it should work the same way as it used to for the callers that
> > > pass args_count, so maybe
> > >
> > > if (!args_count)
> > > args_count = acpi_fwnode_get_args_count(device, nargs_prop);
> >
> > But this is different variable.
>
> Of course it is different. It is an acpi_fwnode_get_reference_args() parameter.
>
> > > > element++;
> > > > -
> > > > ret = acpi_get_ref_args(idx == index ? args : NULL,
> > > > acpi_fwnode_handle(device),
> > > > - &element, end, args_count);
> > > > + &element, end,
> > > > + nargs_count ? nargs_count : args_count);
> > >
> > > And this change would not be necessary?
> >
> > This is not the same check as proposed above.
>
> No, it is not.
>
> It just makes the function work the same way it did before the change
> for the callers who passed nozero args_count and so they might be
> forgiven expecting that it would be taken into account.
I see your point now. But do we have such a user? I dunno.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 10/24] clk: Add clock driver for the RISC-V RPMI clock service group
2025-07-02 5:13 ` [PATCH v7 10/24] clk: Add clock driver for the RISC-V RPMI clock service group Anup Patel
@ 2025-07-02 13:08 ` Andy Shevchenko
2025-07-04 4:15 ` Anup Patel
0 siblings, 1 reply; 55+ messages in thread
From: Andy Shevchenko @ 2025-07-02 13:08 UTC (permalink / raw)
To: Anup Patel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Linus Walleij, Bartosz Golaszewski,
Uwe Kleine-König, Palmer Dabbelt, Paul Walmsley,
Alexandre Ghiti, Len Brown, Sunil V L, Rahul Pathak, Leyfoon Tan,
Atish Patra, Andrew Jones, Samuel Holland, Anup Patel, linux-clk,
devicetree, linux-acpi, linux-riscv, linux-kernel
On Wed, Jul 02, 2025 at 10:43:31AM +0530, Anup Patel wrote:
>
> The RPMI specification defines a clock service group which can be
> accessed via SBI MPXY extension or dedicated S-mode RPMI transport.
>
> Add mailbox client based clock driver for the RISC-V RPMI clock
> service group.
Now it looks much better!
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
One nit-pick below.
...
> +/*
> + * rpmi_clk_rates represents the rates format
> + * as specified by the RPMI specification.
> + * No other format conversion(eg. linear_range) is
> + * required to avoid to and fro conversion.
conversion appears twice. I would suggest use this:
* No other data format (e.g., struct linear_range) is
* required to avoid to and from conversion.
> + */
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 15/24] ACPI: property: Add support for cells property
2025-07-02 12:56 ` Andy Shevchenko
@ 2025-07-02 13:16 ` Rafael J. Wysocki
0 siblings, 0 replies; 55+ messages in thread
From: Rafael J. Wysocki @ 2025-07-02 13:16 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Rafael J. Wysocki, Anup Patel, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jassi Brar,
Thomas Gleixner, Mika Westerberg, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König, Palmer Dabbelt,
Paul Walmsley, Alexandre Ghiti, Len Brown, Sunil V L,
Rahul Pathak, Leyfoon Tan, Atish Patra, Andrew Jones,
Samuel Holland, Anup Patel, linux-clk, devicetree, linux-acpi,
linux-riscv, linux-kernel
On Wed, Jul 2, 2025 at 2:56 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> On Wed, Jul 02, 2025 at 02:39:30PM +0200, Rafael J. Wysocki wrote:
> > On Wed, Jul 2, 2025 at 1:38 PM Andy Shevchenko
> > <andriy.shevchenko@linux.intel.com> wrote:
> > > On Wed, Jul 02, 2025 at 12:20:55PM +0200, Rafael J. Wysocki wrote:
> > > > On Wed, Jul 2, 2025 at 7:16 AM Anup Patel <apatel@ventanamicro.com> wrote:
>
> ...
>
> > > > > static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
> > > > > const char *propname, const char *nargs_prop,
> > > > > unsigned int args_count, unsigned int index,
> > >
> > > > > const struct acpi_device_data *data;
> > > > > struct fwnode_handle *ref_fwnode;
> > > > > struct acpi_device *device;
> > > > > + unsigned int nargs_count;
> > > > > int ret, idx = 0;
> > >
> > > > > + nargs_count = acpi_fwnode_get_args_count(device, nargs_prop);
> > > >
> > > > I think it should work the same way as it used to for the callers that
> > > > pass args_count, so maybe
> > > >
> > > > if (!args_count)
> > > > args_count = acpi_fwnode_get_args_count(device, nargs_prop);
> > >
> > > But this is different variable.
> >
> > Of course it is different. It is an acpi_fwnode_get_reference_args() parameter.
> >
> > > > > element++;
> > > > > -
> > > > > ret = acpi_get_ref_args(idx == index ? args : NULL,
> > > > > acpi_fwnode_handle(device),
> > > > > - &element, end, args_count);
> > > > > + &element, end,
> > > > > + nargs_count ? nargs_count : args_count);
> > > >
> > > > And this change would not be necessary?
> > >
> > > This is not the same check as proposed above.
> >
> > No, it is not.
> >
> > It just makes the function work the same way it did before the change
> > for the callers who passed nozero args_count and so they might be
> > forgiven expecting that it would be taken into account.
>
> I see your point now. But do we have such a user? I dunno.
Well, __acpi_node_get_property_reference() gets called in a couple of places.
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 14/24] ACPI: property: Refactor acpi_fwnode_get_reference_args()
2025-07-02 10:07 ` Rafael J. Wysocki
@ 2025-07-02 14:45 ` Sunil V L
2025-07-02 17:01 ` Rafael J. Wysocki
0 siblings, 1 reply; 55+ messages in thread
From: Sunil V L @ 2025-07-02 14:45 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Anup Patel, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jassi Brar, Thomas Gleixner,
Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König, Palmer Dabbelt,
Paul Walmsley, Alexandre Ghiti, Len Brown, Rahul Pathak,
Leyfoon Tan, Atish Patra, Andrew Jones, Samuel Holland,
Anup Patel, linux-clk, devicetree, linux-acpi, linux-riscv,
linux-kernel
On Wed, Jul 02, 2025 at 12:07:36PM +0200, Rafael J. Wysocki wrote:
> On Wed, Jul 2, 2025 at 7:15 AM Anup Patel <apatel@ventanamicro.com> wrote:
> >
> > From: Sunil V L <sunilvl@ventanamicro.com>
> >
> > Currently acpi_fwnode_get_reference_args() calls the public function
> > __acpi_node_get_property_reference() which ignores the nargs_prop
> > parameter.
>
> Which I suppose is a problem. Why is it so?
>
fwnode_property_get_reference_args() documents as below.
* @nargs_prop: The name of the property telling the number of
* arguments in the referred node. NULL if @nargs is known,
* otherwise @nargs is ignored. Only relevant on OF.
* @nargs: Number of arguments. Ignored if @nargs_prop is non-NULL.
You can see that nargs_prop is not supported with ACPI currently. Since
fwnode_property_get_reference_args() calls
__acpi_node_get_property_reference(), there is no way to determine the
nargs from the nargs_prop currently with ACPI. Since
fwnode_property_get_reference_args() is a common API across DT and ACPI,
it is a problem for users.
> > To fix this, make __acpi_node_get_property_reference() to
> > call the static acpi_fwnode_get_reference() so that callers of
> > fwnode_get_reference_args() can still pass a valid property name to
> > fetch the number of arguments.
>
> Are the current callers of acpi_fwnode_get_reference_args() going to
> be affected by this change and if so, then how?
>
Good question!. If some one is currently passing both valid nargs_prop and
nargs with ACPI, now with this change it will start getting the value
from nargs_prop which was simply ignored earlier. However, I see only 2
combinations how fwnode_property_get_reference_args() is being used.
(nargs_prop = NULL) && (args_count !=0)
or
(nargs_prop != NULL) && (args_count = 0)
So, IMO it should be safe to make this change. But let me know if I am
missing something.
Thanks!
Sunil
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 15/24] ACPI: property: Add support for cells property
2025-07-02 12:39 ` Rafael J. Wysocki
2025-07-02 12:56 ` Andy Shevchenko
@ 2025-07-02 15:06 ` Sunil V L
2025-07-02 16:56 ` Rafael J. Wysocki
1 sibling, 1 reply; 55+ messages in thread
From: Sunil V L @ 2025-07-02 15:06 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Andy Shevchenko, Anup Patel, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jassi Brar,
Thomas Gleixner, Mika Westerberg, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König, Palmer Dabbelt,
Paul Walmsley, Alexandre Ghiti, Len Brown, Rahul Pathak,
Leyfoon Tan, Atish Patra, Andrew Jones, Samuel Holland,
Anup Patel, linux-clk, devicetree, linux-acpi, linux-riscv,
linux-kernel
On Wed, Jul 02, 2025 at 02:39:30PM +0200, Rafael J. Wysocki wrote:
> On Wed, Jul 2, 2025 at 1:38 PM Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
> >
> > On Wed, Jul 02, 2025 at 12:20:55PM +0200, Rafael J. Wysocki wrote:
> > > On Wed, Jul 2, 2025 at 7:16 AM Anup Patel <apatel@ventanamicro.com> wrote:
> >
> > ...
> >
> > > > static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
> > > > const char *propname, const char *nargs_prop,
> > > > unsigned int args_count, unsigned int index,
> >
> > > > const struct acpi_device_data *data;
> > > > struct fwnode_handle *ref_fwnode;
> > > > struct acpi_device *device;
> > > > + unsigned int nargs_count;
> > > > int ret, idx = 0;
> >
> > > > + nargs_count = acpi_fwnode_get_args_count(device, nargs_prop);
> > >
> > > I think it should work the same way as it used to for the callers that
> > > pass args_count, so maybe
> > >
> > > if (!args_count)
> > > args_count = acpi_fwnode_get_args_count(device, nargs_prop);
> >
> > But this is different variable.
>
> Of course it is different. It is an acpi_fwnode_get_reference_args() parameter.
>
> > > > element++;
> > > > -
> > > > ret = acpi_get_ref_args(idx == index ? args : NULL,
> > > > acpi_fwnode_handle(device),
> > > > - &element, end, args_count);
> > > > + &element, end,
> > > > + nargs_count ? nargs_count : args_count);
> > >
> > > And this change would not be necessary?
> >
> > This is not the same check as proposed above.
>
> No, it is not.
>
> It just makes the function work the same way it did before the change
> for the callers who passed nozero args_count and so they might be
> forgiven expecting that it would be taken into account.
But if we do like this, the expectation of
fwnode_property_get_reference_args() will differ for DT and ACPI, right?
I mean nargs_prop should take higher precedence than nargs.
Thanks!
Sunil
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 15/24] ACPI: property: Add support for cells property
2025-07-02 15:06 ` Sunil V L
@ 2025-07-02 16:56 ` Rafael J. Wysocki
2025-07-03 9:31 ` Sunil V L
0 siblings, 1 reply; 55+ messages in thread
From: Rafael J. Wysocki @ 2025-07-02 16:56 UTC (permalink / raw)
To: Sunil V L
Cc: Rafael J. Wysocki, Andy Shevchenko, Anup Patel, Michael Turquette,
Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jassi Brar, Thomas Gleixner, Mika Westerberg, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König, Palmer Dabbelt,
Paul Walmsley, Alexandre Ghiti, Len Brown, Rahul Pathak,
Leyfoon Tan, Atish Patra, Andrew Jones, Samuel Holland,
Anup Patel, linux-clk, devicetree, linux-acpi, linux-riscv,
linux-kernel
On Wed, Jul 2, 2025 at 5:06 PM Sunil V L <sunilvl@ventanamicro.com> wrote:
>
> On Wed, Jul 02, 2025 at 02:39:30PM +0200, Rafael J. Wysocki wrote:
> > On Wed, Jul 2, 2025 at 1:38 PM Andy Shevchenko
> > <andriy.shevchenko@linux.intel.com> wrote:
> > >
> > > On Wed, Jul 02, 2025 at 12:20:55PM +0200, Rafael J. Wysocki wrote:
> > > > On Wed, Jul 2, 2025 at 7:16 AM Anup Patel <apatel@ventanamicro.com> wrote:
> > >
> > > ...
> > >
> > > > > static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
> > > > > const char *propname, const char *nargs_prop,
> > > > > unsigned int args_count, unsigned int index,
> > >
> > > > > const struct acpi_device_data *data;
> > > > > struct fwnode_handle *ref_fwnode;
> > > > > struct acpi_device *device;
> > > > > + unsigned int nargs_count;
> > > > > int ret, idx = 0;
> > >
> > > > > + nargs_count = acpi_fwnode_get_args_count(device, nargs_prop);
> > > >
> > > > I think it should work the same way as it used to for the callers that
> > > > pass args_count, so maybe
> > > >
> > > > if (!args_count)
> > > > args_count = acpi_fwnode_get_args_count(device, nargs_prop);
> > >
> > > But this is different variable.
> >
> > Of course it is different. It is an acpi_fwnode_get_reference_args() parameter.
> >
> > > > > element++;
> > > > > -
> > > > > ret = acpi_get_ref_args(idx == index ? args : NULL,
> > > > > acpi_fwnode_handle(device),
> > > > > - &element, end, args_count);
> > > > > + &element, end,
> > > > > + nargs_count ? nargs_count : args_count);
> > > >
> > > > And this change would not be necessary?
> > >
> > > This is not the same check as proposed above.
> >
> > No, it is not.
> >
> > It just makes the function work the same way it did before the change
> > for the callers who passed nozero args_count and so they might be
> > forgiven expecting that it would be taken into account.
>
> But if we do like this, the expectation of
> fwnode_property_get_reference_args() will differ for DT and ACPI, right?
> I mean nargs_prop should take higher precedence than nargs.
So you basically want acpi_fwnode_get_reference_args() to take
nargs_prop into account (which could be explained much cleaner in the
patch changelogs).
Also, your changes don't modify the behavior of
__acpi_node_get_property_reference() AFAICS, so this is OK.
Never mind then, but you could pass nargs_prop along with the
additional device parameter to acpi_get_ref_args() and make that
function obtain the nargs_prop value. In the patch, you need to get
the nargs_prop value before calling it anyway in both places in which
it is used.
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 14/24] ACPI: property: Refactor acpi_fwnode_get_reference_args()
2025-07-02 14:45 ` Sunil V L
@ 2025-07-02 17:01 ` Rafael J. Wysocki
0 siblings, 0 replies; 55+ messages in thread
From: Rafael J. Wysocki @ 2025-07-02 17:01 UTC (permalink / raw)
To: Sunil V L
Cc: Rafael J. Wysocki, Anup Patel, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jassi Brar,
Thomas Gleixner, Mika Westerberg, Andy Shevchenko, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König, Palmer Dabbelt,
Paul Walmsley, Alexandre Ghiti, Len Brown, Rahul Pathak,
Leyfoon Tan, Atish Patra, Andrew Jones, Samuel Holland,
Anup Patel, linux-clk, devicetree, linux-acpi, linux-riscv,
linux-kernel
On Wed, Jul 2, 2025 at 4:45 PM Sunil V L <sunilvl@ventanamicro.com> wrote:
>
> On Wed, Jul 02, 2025 at 12:07:36PM +0200, Rafael J. Wysocki wrote:
> > On Wed, Jul 2, 2025 at 7:15 AM Anup Patel <apatel@ventanamicro.com> wrote:
> > >
> > > From: Sunil V L <sunilvl@ventanamicro.com>
> > >
> > > Currently acpi_fwnode_get_reference_args() calls the public function
> > > __acpi_node_get_property_reference() which ignores the nargs_prop
> > > parameter.
> >
> > Which I suppose is a problem. Why is it so?
> >
> fwnode_property_get_reference_args() documents as below.
>
> * @nargs_prop: The name of the property telling the number of
> * arguments in the referred node. NULL if @nargs is known,
> * otherwise @nargs is ignored. Only relevant on OF.
> * @nargs: Number of arguments. Ignored if @nargs_prop is non-NULL.
>
> You can see that nargs_prop is not supported with ACPI currently. Since
> fwnode_property_get_reference_args() calls
> __acpi_node_get_property_reference(), there is no way to determine the
> nargs from the nargs_prop currently with ACPI. Since
> fwnode_property_get_reference_args() is a common API across DT and ACPI,
> it is a problem for users.
So the problem is that if nargs_prop is passed to
fwnode_property_get_reference_args() and it is a valid "cells"
property, OF will use it to obtain the number of reference arguments
and ACPI will ignore it. To make it work the same way in both cases,
acpi_fwnode_get_reference_args() needs to be modified to take
nargs_prop into account properly. This is the key information that
needs to go into the patch changelog.
> > > To fix this, make __acpi_node_get_property_reference() to
> > > call the static acpi_fwnode_get_reference() so that callers of
> > > fwnode_get_reference_args() can still pass a valid property name to
> > > fetch the number of arguments.
> >
> > Are the current callers of acpi_fwnode_get_reference_args() going to
> > be affected by this change and if so, then how?
> >
> Good question!. If some one is currently passing both valid nargs_prop and
> nargs with ACPI, now with this change it will start getting the value
> from nargs_prop which was simply ignored earlier. However, I see only 2
> combinations how fwnode_property_get_reference_args() is being used.
>
> (nargs_prop = NULL) && (args_count !=0)
> or
> (nargs_prop != NULL) && (args_count = 0)
OK
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 03/24] RISC-V: Add defines for the SBI message proxy extension
2025-07-02 12:06 ` Andy Shevchenko
@ 2025-07-03 5:16 ` Anup Patel
0 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-03 5:16 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Linus Walleij, Bartosz Golaszewski,
Uwe Kleine-König, Palmer Dabbelt, Paul Walmsley,
Alexandre Ghiti, Len Brown, Sunil V L, Rahul Pathak, Leyfoon Tan,
Atish Patra, Andrew Jones, Samuel Holland, Anup Patel, linux-clk,
devicetree, linux-acpi, linux-riscv, linux-kernel, Atish Patra
On Wed, Jul 2, 2025 at 5:37 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> On Wed, Jul 02, 2025 at 10:43:24AM +0530, Anup Patel wrote:
> > Add defines for the new SBI message proxy extension which is part
> > of the SBI v3.0 specification.
>
> Actually a few nit-picks.
>
> ...
>
> > +enum sbi_ext_mpxy_fid {
> > + SBI_EXT_MPXY_GET_SHMEM_SIZE,
> > + SBI_EXT_MPXY_SET_SHMEM,
> > + SBI_EXT_MPXY_GET_CHANNEL_IDS,
> > + SBI_EXT_MPXY_READ_ATTRS,
> > + SBI_EXT_MPXY_WRITE_ATTRS,
> > + SBI_EXT_MPXY_SEND_MSG_WITH_RESP,
> > + SBI_EXT_MPXY_SEND_MSG_WITHOUT_RESP,
> > + SBI_EXT_MPXY_GET_NOTIFICATION_EVENTS
>
> Add a trailing comma.
Okay, I will update.
>
> > +};
>
> ...
>
> > +/* Possible values of MSG_PROT_ID attribute */
> > +enum sbi_mpxy_msgproto_id {
> > + SBI_MPXY_MSGPROTO_RPMI_ID = 0x0
>
> Add a trailing comma, and you might want to drop 0x. I don't know what else can
> be here, esp. in the future, but some kind of the description of this in TRM
> can shed a light on what is better pattern to use.
Sure, I will update.
Regards,
Anup
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 07/24] mailbox: Add RISC-V SBI message proxy (MPXY) based mailbox driver
2025-07-02 12:50 ` Andy Shevchenko
@ 2025-07-03 6:52 ` Anup Patel
0 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-03 6:52 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Linus Walleij, Bartosz Golaszewski,
Uwe Kleine-König, Palmer Dabbelt, Paul Walmsley,
Alexandre Ghiti, Len Brown, Sunil V L, Rahul Pathak, Leyfoon Tan,
Atish Patra, Andrew Jones, Samuel Holland, Anup Patel, linux-clk,
devicetree, linux-acpi, linux-riscv, linux-kernel
On Wed, Jul 2, 2025 at 6:20 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> On Wed, Jul 02, 2025 at 10:43:28AM +0530, Anup Patel wrote:
> > Add a mailbox controller driver for the new SBI message proxy extension
> > which is part of the SBI v3.0 specification.
>
> ...
>
> > +#include <linux/cpu.h>
> > +#include <linux/errno.h>
> > +#include <linux/init.h>
> > +#include <linux/mailbox_controller.h>
> > +#include <linux/mailbox/riscv-rpmi-message.h>
>
> + minmax.h
Okay, I will add this.
>
> > +#include <linux/mm.h>
> > +#include <linux/module.h>
> > +#include <linux/msi.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/percpu.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/smp.h>
> > +#include <linux/string.h>
> > +#include <linux/types.h>
> > +#include <asm/byteorder.h>
> > +#include <asm/sbi.h>
>
> ...
>
> > +static void mpxy_mbox_send_rpmi_data(struct mpxy_mbox_channel *mchan,
> > + struct rpmi_mbox_message *msg)
> > +{
> > + int rc = 0;
>
> Is it useful? I mean can you assign msg.error directly in each case?
> (Just asking)
I think it is more readable with a local variable for errors
but I don't mind directly assigning msg->error.
>
> > + switch (msg->type) {
> > + case RPMI_MBOX_MSG_TYPE_GET_ATTRIBUTE:
> > + switch (msg->attr.id) {
> > + case RPMI_MBOX_ATTR_SPEC_VERSION:
> > + msg->attr.value = mchan->attrs.msg_proto_version;
> > + break;
> > + case RPMI_MBOX_ATTR_MAX_MSG_DATA_SIZE:
> > + msg->attr.value = mchan->max_xfer_len;
> > + break;
> > + case RPMI_MBOX_ATTR_SERVICEGROUP_ID:
> > + msg->attr.value = mchan->rpmi_attrs.servicegroup_id;
> > + break;
> > + case RPMI_MBOX_ATTR_SERVICEGROUP_VERSION:
> > + msg->attr.value = mchan->rpmi_attrs.servicegroup_version;
> > + break;
> > + case RPMI_MBOX_ATTR_IMPL_ID:
> > + msg->attr.value = mchan->rpmi_attrs.impl_id;
> > + break;
> > + case RPMI_MBOX_ATTR_IMPL_VERSION:
> > + msg->attr.value = mchan->rpmi_attrs.impl_version;
> > + break;
> > + default:
> > + rc = -EOPNOTSUPP;
> > + break;
> > + }
> > + break;
> > + case RPMI_MBOX_MSG_TYPE_SET_ATTRIBUTE:
> > + /* None of the RPMI linux mailbox attributes are writeable */
> > + rc = -EOPNOTSUPP;
> > + break;
> > + case RPMI_MBOX_MSG_TYPE_SEND_WITH_RESPONSE:
> > + if ((!msg->data.request && msg->data.request_len) ||
> > + (msg->data.request &&
> > + msg->data.request_len > mchan->max_xfer_len) ||
> > + (!msg->data.response && msg->data.max_response_len)) {
> > + rc = -EINVAL;
> > + break;
> > + }
> > + if (!(mchan->attrs.capability & SBI_MPXY_CHAN_CAP_SEND_WITH_RESP)) {
> > + rc = -EIO;
> > + break;
> > + }
> > + rc = mpxy_send_message_with_resp(mchan->channel_id,
> > + msg->data.service_id,
> > + msg->data.request,
> > + msg->data.request_len,
> > + msg->data.response,
> > + msg->data.max_response_len,
> > + &msg->data.out_response_len);
> > + break;
> > + case RPMI_MBOX_MSG_TYPE_SEND_WITHOUT_RESPONSE:
> > + if ((!msg->data.request && msg->data.request_len) ||
> > + (msg->data.request &&
> > + msg->data.request_len > mchan->max_xfer_len)) {
> > + rc = -EINVAL;
> > + break;
> > + }
> > + if (!(mchan->attrs.capability & SBI_MPXY_CHAN_CAP_SEND_WITHOUT_RESP)) {
> > + rc = -EIO;
> > + break;
> > + }
> > + rc = mpxy_send_message_without_resp(mchan->channel_id,
> > + msg->data.service_id,
> > + msg->data.request,
> > + msg->data.request_len);
> > + break;
> > + default:
> > + rc = -EOPNOTSUPP;
> > + break;
> > + }
> > +
> > + msg->error = rc;
> > +}
>
> ...
>
> > +static void mpxy_mbox_peek_rpmi_data(struct mbox_chan *chan,
> > + struct mpxy_mbox_channel *mchan,
> > + struct sbi_mpxy_notification_data *notif,
> > + unsigned long events_data_len)
> > +{
> > + struct rpmi_notification_event *event;
> > + unsigned long pos = 0, event_size;
> > + struct rpmi_mbox_message msg;
> > +
> > + while ((pos < events_data_len) && !(pos & 0x3) &&
>
> 0x3 looks like a magic used for the non-aligned data.
This is paranoide check and can be dropped. I will update.
The RPMI spec clearly states that "An RPMI event may have associated
data whose size is specified in the EVENT_DATALEN field of the header
and this data size must be a multiple of 4-byte."
>
> > + ((events_data_len - pos) <= sizeof(*event))) {
> > + event = (struct rpmi_notification_event *)(notif->events_data + pos);
> > +
> > + msg.type = RPMI_MBOX_MSG_TYPE_NOTIFICATION_EVENT;
> > + msg.notif.event_datalen = le16_to_cpu(event->event_datalen);
> > + msg.notif.event_id = event->event_id;
> > + msg.notif.event_data = event->event_data;
> > + msg.error = 0;
> > +
> > + event_size = sizeof(*event) + msg.notif.event_datalen;
>
> Do you trust the source? This may wrap-around...
>
> > + if (event_size > (events_data_len - pos)) {
> > + event_size = events_data_len - pos;
> > + goto skip_event;
> > + }
> > + if (event_size & 0x3)
> > + goto skip_event;
>
> ...and these checks be skipped. Is it a problem?
I agree these checks can be skipped.
>
> > + mbox_chan_received_data(chan, &msg);
>
> > +skip_event:
>
> I think this may be replaced by a continue inside if you make a loop to be
> do {} while (). But it's just a thought, you can check if it gives a better
> readability after all.
I am more comfortable with "while ()" over here.
>
> > + pos += event_size;
> > + }
> > +}
>
> ...
>
> > +static int mpxy_mbox_probe(struct platform_device *pdev)
> > +{
> > + u32 i, *channel_ids __free(kfree) = NULL;
>
> It's not recommended. Can you split channel_ids to the actual scope where it's
> used? Somewhere...
Let me create a separate function to populate channels
so that channel_ids will be used only in a limited scope.
>
> > + struct device *dev = &pdev->dev;
> > + struct mpxy_mbox_channel *mchan;
> > + struct mpxy_mbox *mbox;
> > + int msi_idx, rc;
> > +
> > + /*
> > + * Initialize MPXY shared memory only once. This also ensures
> > + * that SBI MPXY mailbox is probed only once.
> > + */
> > + if (mpxy_shmem_init_done) {
> > + dev_err(dev, "SBI MPXY mailbox already initialized\n");
> > + return -EALREADY;
> > + }
> > +
> > + /* Probe for SBI MPXY extension */
> > + if (sbi_spec_version < sbi_mk_version(1, 0) ||
> > + sbi_probe_extension(SBI_EXT_MPXY) <= 0) {
> > + dev_info(dev, "SBI MPXY extension not available\n");
> > + return -ENODEV;
> > + }
> > +
> > + /* Find-out shared memory size */
> > + rc = mpxy_get_shmem_size(&mpxy_shmem_size);
> > + if (rc)
> > + return dev_err_probe(dev, rc, "failed to get MPXY shared memory size\n");
> > +
> > + /*
> > + * Setup MPXY shared memory on each CPU
> > + *
> > + * Note: Don't cleanup MPXY shared memory upon CPU power-down
> > + * because the RPMI System MSI irqchip driver needs it to be
> > + * available when migrating IRQs in CPU power-down path.
> > + */
> > + cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "riscv/sbi-mpxy-shmem",
> > + mpxy_setup_shmem, NULL);
> > +
> > + /* Mark as MPXY shared memory initialization done */
> > + mpxy_shmem_init_done = true;
> > +
> > + /* Allocate mailbox instance */
> > + mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
> > + if (!mbox)
> > + return -ENOMEM;
> > + mbox->dev = dev;
> > + platform_set_drvdata(pdev, mbox);
> > +
> > + /* Find-out of number of channels */
> > + rc = mpxy_get_channel_count(&mbox->channel_count);
> > + if (rc)
> > + return dev_err_probe(dev, rc, "failed to get number of MPXY channels\n");
> > + if (!mbox->channel_count)
> > + dev_err_probe(dev, -ENODEV, "no MPXY channels available\n");
> > +
> > + /* Allocate and fetch all channel IDs */
> > + channel_ids = kcalloc(mbox->channel_count, sizeof(*channel_ids), GFP_KERNEL);
>
> ...here.
>
> > + if (!channel_ids)
> > + return -ENOMEM;
> > + rc = mpxy_get_channel_ids(mbox->channel_count, channel_ids);
> > + if (rc)
> > + return dev_err_probe(dev, rc, "failed to get MPXY channel IDs\n");
> > +
> > + /* Populate all channels */
> > + mbox->channels = devm_kcalloc(dev, mbox->channel_count,
> > + sizeof(*mbox->channels), GFP_KERNEL);
> > + if (!mbox->channels)
> > + return -ENOMEM;
> > + for (i = 0; i < mbox->channel_count; i++) {
> > + mchan = &mbox->channels[i];
> > + mchan->mbox = mbox;
> > + mchan->channel_id = channel_ids[i];
> > +
> > + rc = mpxy_read_attrs(mchan->channel_id, SBI_MPXY_ATTR_MSG_PROT_ID,
> > + sizeof(mchan->attrs) / sizeof(u32),
> > + (u32 *)&mchan->attrs);
> > + if (rc) {
> > + return dev_err_probe(dev, rc,
> > + "MPXY channel 0x%x read attrs failed\n",
> > + mchan->channel_id);
> > + }
> > +
> > + if (mchan->attrs.msg_proto_id == SBI_MPXY_MSGPROTO_RPMI_ID) {
> > + rc = mpxy_mbox_read_rpmi_attrs(mchan);
> > + if (rc) {
> > + return dev_err_probe(dev, rc,
> > + "MPXY channel 0x%x read RPMI attrs failed\n",
> > + mchan->channel_id);
> > + }
> > + }
> > +
> > + mchan->notif = devm_kzalloc(dev, mpxy_shmem_size, GFP_KERNEL);
> > + if (!mchan->notif)
> > + return -ENOMEM;
> > +
> > + mchan->max_xfer_len = min(mpxy_shmem_size, mchan->attrs.msg_max_len);
> > +
> > + if ((mchan->attrs.capability & SBI_MPXY_CHAN_CAP_GET_NOTIFICATIONS) &&
> > + (mchan->attrs.capability & SBI_MPXY_CHAN_CAP_EVENTS_STATE))
> > + mchan->have_events_state = true;
> > +
> > + if ((mchan->attrs.capability & SBI_MPXY_CHAN_CAP_GET_NOTIFICATIONS) &&
> > + (mchan->attrs.capability & SBI_MPXY_CHAN_CAP_MSI))
> > + mchan->msi_index = mbox->msi_count++;
> > + else
> > + mchan->msi_index = U32_MAX;
> > + mchan->msi_irq = U32_MAX;
> > + }
> > +
> > + /* Initialize mailbox controller */
> > + mbox->controller.txdone_irq = false;
> > + mbox->controller.txdone_poll = false;
> > + mbox->controller.ops = &mpxy_mbox_ops;
> > + mbox->controller.dev = dev;
> > + mbox->controller.num_chans = mbox->channel_count;
> > + mbox->controller.fw_xlate = mpxy_mbox_fw_xlate;
> > + mbox->controller.chans = devm_kcalloc(dev, mbox->channel_count,
> > + sizeof(*mbox->controller.chans),
> > + GFP_KERNEL);
> > + if (!mbox->controller.chans)
> > + return -ENOMEM;
> > + for (i = 0; i < mbox->channel_count; i++)
> > + mbox->controller.chans[i].con_priv = &mbox->channels[i];
> > +
> > + /* Set the MSI domain if not available */
> > + if (!dev_get_msi_domain(dev)) {
> > + /*
> > + * The device MSI domain for OF devices is only set at the
> > + * time of populating/creating OF device. If the device MSI
> > + * domain is discovered later after the OF device is created
> > + * then we need to set it explicitly before using any platform
> > + * MSI functions.
> > + */
>
> > + if (dev_of_node(dev))
>
> Do you really need this check? What about ACPI?
Yes, this check is needed because of_msi_configure() only
works for OF does. For ACPI, we have a different way of
to re-configure MSI domain which is in a later patch.
In general, there is no generic fwnode API to find and
re-configure MSI domain in a bus independent way.
>
> > + of_msi_configure(dev, dev_of_node(dev));
> > + }
> > +
> > + /* Setup MSIs for mailbox (if required) */
> > + if (mbox->msi_count) {
> > + mbox->msi_index_to_channel = devm_kcalloc(dev, mbox->msi_count,
> > + sizeof(*mbox->msi_index_to_channel),
> > + GFP_KERNEL);
> > + if (!mbox->msi_index_to_channel)
> > + return -ENOMEM;
> > +
> > + for (msi_idx = 0; msi_idx < mbox->msi_count; msi_idx++) {
> > + for (i = 0; i < mbox->channel_count; i++) {
> > + mchan = &mbox->channels[i];
> > + if (mchan->msi_index == msi_idx) {
> > + mbox->msi_index_to_channel[msi_idx] = mchan;
> > + break;
> > + }
> > + }
> > + }
> > +
> > + rc = platform_device_msi_init_and_alloc_irqs(dev, mbox->msi_count,
> > + mpxy_mbox_msi_write);
> > + if (rc) {
> > + return dev_err_probe(dev, rc, "Failed to allocate %d MSIs\n",
> > + mbox->msi_count);
> > + }
> > +
> > + for (i = 0; i < mbox->channel_count; i++) {
> > + mchan = &mbox->channels[i];
> > + if (mchan->msi_index == U32_MAX)
> > + continue;
> > + mchan->msi_irq = msi_get_virq(dev, mchan->msi_index);
> > + }
> > + }
> > +
> > + /* Register mailbox controller */
> > + rc = devm_mbox_controller_register(dev, &mbox->controller);
> > + if (rc) {
> > + dev_err_probe(dev, rc, "Registering SBI MPXY mailbox failed\n");
> > + if (mbox->msi_count)
> > + platform_device_msi_free_irqs_all(dev);
> > + return rc;
> > + }
>
> > + dev_info(dev, "mailbox registered with %d channels\n",
> > + mbox->channel_count);
>
> Working driver doesn't need to issue a message.
The expected mailbox channels available to Linux will
vary based on platform. If there is a firmware bug then
Linux will not see all expected mailbox channels but the
probe of this driver will succeed.
From the end user perspective (or user space), there
is no direct way of knowing the number of channels
details of each channel. In fact, the Linux mailbox
framework does not have common sysfs interface
to allow users know the mailbox controller instances
and their mailbox channels.
Regards,
Anup
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 15/24] ACPI: property: Add support for cells property
2025-07-02 16:56 ` Rafael J. Wysocki
@ 2025-07-03 9:31 ` Sunil V L
0 siblings, 0 replies; 55+ messages in thread
From: Sunil V L @ 2025-07-03 9:31 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Andy Shevchenko, Anup Patel, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jassi Brar,
Thomas Gleixner, Mika Westerberg, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König, Palmer Dabbelt,
Paul Walmsley, Alexandre Ghiti, Len Brown, Rahul Pathak,
Leyfoon Tan, Atish Patra, Andrew Jones, Samuel Holland,
Anup Patel, linux-clk, devicetree, linux-acpi, linux-riscv,
linux-kernel
On Wed, Jul 02, 2025 at 06:56:48PM +0200, Rafael J. Wysocki wrote:
> On Wed, Jul 2, 2025 at 5:06 PM Sunil V L <sunilvl@ventanamicro.com> wrote:
> >
> > On Wed, Jul 02, 2025 at 02:39:30PM +0200, Rafael J. Wysocki wrote:
> > > On Wed, Jul 2, 2025 at 1:38 PM Andy Shevchenko
> > > <andriy.shevchenko@linux.intel.com> wrote:
> > > >
> > > > On Wed, Jul 02, 2025 at 12:20:55PM +0200, Rafael J. Wysocki wrote:
> > > > > On Wed, Jul 2, 2025 at 7:16 AM Anup Patel <apatel@ventanamicro.com> wrote:
> > > >
> > > > ...
> > > >
> > > > > > static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
> > > > > > const char *propname, const char *nargs_prop,
> > > > > > unsigned int args_count, unsigned int index,
> > > >
> > > > > > const struct acpi_device_data *data;
> > > > > > struct fwnode_handle *ref_fwnode;
> > > > > > struct acpi_device *device;
> > > > > > + unsigned int nargs_count;
> > > > > > int ret, idx = 0;
> > > >
> > > > > > + nargs_count = acpi_fwnode_get_args_count(device, nargs_prop);
> > > > >
> > > > > I think it should work the same way as it used to for the callers that
> > > > > pass args_count, so maybe
> > > > >
> > > > > if (!args_count)
> > > > > args_count = acpi_fwnode_get_args_count(device, nargs_prop);
> > > >
> > > > But this is different variable.
> > >
> > > Of course it is different. It is an acpi_fwnode_get_reference_args() parameter.
> > >
> > > > > > element++;
> > > > > > -
> > > > > > ret = acpi_get_ref_args(idx == index ? args : NULL,
> > > > > > acpi_fwnode_handle(device),
> > > > > > - &element, end, args_count);
> > > > > > + &element, end,
> > > > > > + nargs_count ? nargs_count : args_count);
> > > > >
> > > > > And this change would not be necessary?
> > > >
> > > > This is not the same check as proposed above.
> > >
> > > No, it is not.
> > >
> > > It just makes the function work the same way it did before the change
> > > for the callers who passed nozero args_count and so they might be
> > > forgiven expecting that it would be taken into account.
> >
> > But if we do like this, the expectation of
> > fwnode_property_get_reference_args() will differ for DT and ACPI, right?
> > I mean nargs_prop should take higher precedence than nargs.
>
> So you basically want acpi_fwnode_get_reference_args() to take
> nargs_prop into account (which could be explained much cleaner in the
> patch changelogs).
>
Sure. Let me improve the commit message in the next version.
.
> Also, your changes don't modify the behavior of
> __acpi_node_get_property_reference() AFAICS, so this is OK.
>
That's correct.
> Never mind then, but you could pass nargs_prop along with the
> additional device parameter to acpi_get_ref_args() and make that
> function obtain the nargs_prop value. In the patch, you need to get
> the nargs_prop value before calling it anyway in both places in which
> it is used.
That's better. Let me update acpi_get_ref_args() itself in the next
version.
Thanks!
Sunil
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 21/24] mailbox/riscv-sbi-mpxy: Add ACPI support
2025-07-02 12:28 ` Andy Shevchenko
@ 2025-07-03 10:54 ` Sunil V L
2025-07-03 13:54 ` Andy Shevchenko
0 siblings, 1 reply; 55+ messages in thread
From: Sunil V L @ 2025-07-03 10:54 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Anup Patel, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jassi Brar, Thomas Gleixner,
Rafael J . Wysocki, Mika Westerberg, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König, Palmer Dabbelt,
Paul Walmsley, Alexandre Ghiti, Len Brown, Rahul Pathak,
Leyfoon Tan, Atish Patra, Andrew Jones, Samuel Holland,
Anup Patel, linux-clk, devicetree, linux-acpi, linux-riscv,
linux-kernel
On Wed, Jul 02, 2025 at 03:28:45PM +0300, Andy Shevchenko wrote:
> On Wed, Jul 02, 2025 at 10:43:42AM +0530, Anup Patel wrote:
> > From: Sunil V L <sunilvl@ventanamicro.com>
> >
> > Add ACPI support for the RISC-V SBI message proxy (MPXY) based
> > mailbox driver.
>
> ...
>
> > - if (dev_of_node(dev))
> > + if (is_of_node(fwnode)) {
> > of_msi_configure(dev, dev_of_node(dev));
> > + } else if (is_acpi_device_node(fwnode)) {
> > + msi_domain = irq_find_matching_fwnode(imsic_acpi_get_fwnode(dev),
> > + DOMAIN_BUS_PLATFORM_MSI);
> > + dev_set_msi_domain(dev, msi_domain);
> > + }
>
> Actually you don't need to have the if-else-if if I am not mistaken.
> The OF does almost the same as it's done in the second branch for ACPI case.
> How many MSI parents this may have?
>
OF already has a well defined interface to configure the MSI domain. The
mechanisms existing today are different for DT vs ACPI to find out the
fwnode of the MSI controller. So, it is done differently.
In RISC-V case at least, there will be only one MSI parent.
Thanks,
Sunil
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 21/24] mailbox/riscv-sbi-mpxy: Add ACPI support
2025-07-03 10:54 ` Sunil V L
@ 2025-07-03 13:54 ` Andy Shevchenko
2025-07-03 14:26 ` Anup Patel
0 siblings, 1 reply; 55+ messages in thread
From: Andy Shevchenko @ 2025-07-03 13:54 UTC (permalink / raw)
To: Sunil V L
Cc: Anup Patel, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jassi Brar, Thomas Gleixner,
Rafael J . Wysocki, Mika Westerberg, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König, Palmer Dabbelt,
Paul Walmsley, Alexandre Ghiti, Len Brown, Rahul Pathak,
Leyfoon Tan, Atish Patra, Andrew Jones, Samuel Holland,
Anup Patel, linux-clk, devicetree, linux-acpi, linux-riscv,
linux-kernel
On Thu, Jul 03, 2025 at 04:24:18PM +0530, Sunil V L wrote:
> On Wed, Jul 02, 2025 at 03:28:45PM +0300, Andy Shevchenko wrote:
> > On Wed, Jul 02, 2025 at 10:43:42AM +0530, Anup Patel wrote:
...
> > > - if (dev_of_node(dev))
> > > + if (is_of_node(fwnode)) {
> > > of_msi_configure(dev, dev_of_node(dev));
> > > + } else if (is_acpi_device_node(fwnode)) {
> > > + msi_domain = irq_find_matching_fwnode(imsic_acpi_get_fwnode(dev),
> > > + DOMAIN_BUS_PLATFORM_MSI);
> > > + dev_set_msi_domain(dev, msi_domain);
> > > + }
> >
> > Actually you don't need to have the if-else-if if I am not mistaken.
> > The OF does almost the same as it's done in the second branch for ACPI case.
> > How many MSI parents this may have?
> >
> OF already has a well defined interface to configure the MSI domain. The
> mechanisms existing today are different for DT vs ACPI to find out the
> fwnode of the MSI controller. So, it is done differently.
I don't see how. The only difference I see is that OF iterates over all listed
parents, if any, ACPI tries only one.
So, perhaps it's a time to have a common API somewhere for this to be agnostic?
Something like fwnode_msi_configure() in somewhere of IRQ MSI core?
> In RISC-V case at least, there will be only one MSI parent.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 21/24] mailbox/riscv-sbi-mpxy: Add ACPI support
2025-07-03 13:54 ` Andy Shevchenko
@ 2025-07-03 14:26 ` Anup Patel
2025-07-03 14:32 ` Andy Shevchenko
0 siblings, 1 reply; 55+ messages in thread
From: Anup Patel @ 2025-07-03 14:26 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Sunil V L, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jassi Brar, Thomas Gleixner,
Rafael J . Wysocki, Mika Westerberg, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König, Palmer Dabbelt,
Paul Walmsley, Alexandre Ghiti, Len Brown, Rahul Pathak,
Leyfoon Tan, Atish Patra, Andrew Jones, Samuel Holland,
Anup Patel, linux-clk, devicetree, linux-acpi, linux-riscv,
linux-kernel
On Thu, Jul 3, 2025 at 7:24 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> On Thu, Jul 03, 2025 at 04:24:18PM +0530, Sunil V L wrote:
> > On Wed, Jul 02, 2025 at 03:28:45PM +0300, Andy Shevchenko wrote:
> > > On Wed, Jul 02, 2025 at 10:43:42AM +0530, Anup Patel wrote:
>
> ...
>
> > > > - if (dev_of_node(dev))
> > > > + if (is_of_node(fwnode)) {
> > > > of_msi_configure(dev, dev_of_node(dev));
> > > > + } else if (is_acpi_device_node(fwnode)) {
> > > > + msi_domain = irq_find_matching_fwnode(imsic_acpi_get_fwnode(dev),
> > > > + DOMAIN_BUS_PLATFORM_MSI);
> > > > + dev_set_msi_domain(dev, msi_domain);
> > > > + }
> > >
> > > Actually you don't need to have the if-else-if if I am not mistaken.
> > > The OF does almost the same as it's done in the second branch for ACPI case.
> > > How many MSI parents this may have?
> > >
> > OF already has a well defined interface to configure the MSI domain. The
> > mechanisms existing today are different for DT vs ACPI to find out the
> > fwnode of the MSI controller. So, it is done differently.
>
> I don't see how. The only difference I see is that OF iterates over all listed
> parents, if any, ACPI tries only one.
>
> So, perhaps it's a time to have a common API somewhere for this to be agnostic?
> Something like fwnode_msi_configure() in somewhere of IRQ MSI core?
>
There is an issue/gap in the DD framework which is being work-around
here. This issue manifest mostly in RISC-V land because in RISC-V both
MSI controller driver and drivers using MSI are regular platform drivers
while the probe ordering is ensured by dev_link support of DD framework
or the frameworks (like ACPI) creating the device.
As-per this issue, when platform devices (DT or ACPI) are created the
MSI domain instance is not available and hence set to NULL. The MSI
domain instance is only available after MSI controller driver is probed
so currently we explicitly do of_msi_configure() or dev_set_msi_domain()
in the driver using MSI as a work-around. Adding a common
fwnode_msi_configure() is only going to be an improvement to the
existing work-around which we should not have in the first place
hence not the right approach IMO.
In the long run, we need a clean fix for the above issue in the DD
framework such that platform drivers using MSI don't have to explicitly
do of_msi_configure() or dev_set_msi_domain().
Regards,
Anup
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 21/24] mailbox/riscv-sbi-mpxy: Add ACPI support
2025-07-03 14:26 ` Anup Patel
@ 2025-07-03 14:32 ` Andy Shevchenko
0 siblings, 0 replies; 55+ messages in thread
From: Andy Shevchenko @ 2025-07-03 14:32 UTC (permalink / raw)
To: Anup Patel
Cc: Sunil V L, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jassi Brar, Thomas Gleixner,
Rafael J . Wysocki, Mika Westerberg, Linus Walleij,
Bartosz Golaszewski, Uwe Kleine-König, Palmer Dabbelt,
Paul Walmsley, Alexandre Ghiti, Len Brown, Rahul Pathak,
Leyfoon Tan, Atish Patra, Andrew Jones, Samuel Holland,
Anup Patel, linux-clk, devicetree, linux-acpi, linux-riscv,
linux-kernel
On Thu, Jul 03, 2025 at 07:56:52PM +0530, Anup Patel wrote:
> On Thu, Jul 3, 2025 at 7:24 PM Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
> > On Thu, Jul 03, 2025 at 04:24:18PM +0530, Sunil V L wrote:
> > > On Wed, Jul 02, 2025 at 03:28:45PM +0300, Andy Shevchenko wrote:
> > > > On Wed, Jul 02, 2025 at 10:43:42AM +0530, Anup Patel wrote:
...
> > > > > - if (dev_of_node(dev))
> > > > > + if (is_of_node(fwnode)) {
> > > > > of_msi_configure(dev, dev_of_node(dev));
> > > > > + } else if (is_acpi_device_node(fwnode)) {
> > > > > + msi_domain = irq_find_matching_fwnode(imsic_acpi_get_fwnode(dev),
> > > > > + DOMAIN_BUS_PLATFORM_MSI);
> > > > > + dev_set_msi_domain(dev, msi_domain);
> > > > > + }
> > > >
> > > > Actually you don't need to have the if-else-if if I am not mistaken.
> > > > The OF does almost the same as it's done in the second branch for ACPI case.
> > > > How many MSI parents this may have?
> > > >
> > > OF already has a well defined interface to configure the MSI domain. The
> > > mechanisms existing today are different for DT vs ACPI to find out the
> > > fwnode of the MSI controller. So, it is done differently.
> >
> > I don't see how. The only difference I see is that OF iterates over all listed
> > parents, if any, ACPI tries only one.
> >
> > So, perhaps it's a time to have a common API somewhere for this to be agnostic?
> > Something like fwnode_msi_configure() in somewhere of IRQ MSI core?
>
> There is an issue/gap in the DD framework which is being work-around
> here. This issue manifest mostly in RISC-V land because in RISC-V both
> MSI controller driver and drivers using MSI are regular platform drivers
> while the probe ordering is ensured by dev_link support of DD framework
> or the frameworks (like ACPI) creating the device.
>
> As-per this issue, when platform devices (DT or ACPI) are created the
> MSI domain instance is not available and hence set to NULL. The MSI
> domain instance is only available after MSI controller driver is probed
> so currently we explicitly do of_msi_configure() or dev_set_msi_domain()
> in the driver using MSI as a work-around. Adding a common
> fwnode_msi_configure() is only going to be an improvement to the
> existing work-around which we should not have in the first place
> hence not the right approach IMO.
>
> In the long run, we need a clean fix for the above issue in the DD
> framework such that platform drivers using MSI don't have to explicitly
> do of_msi_configure() or dev_set_msi_domain().
I see, thanks a lot for this explanation. Can you add a summary as a comment on
top of the if-else-if in case it's not there already?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 10/24] clk: Add clock driver for the RISC-V RPMI clock service group
2025-07-02 13:08 ` Andy Shevchenko
@ 2025-07-04 4:15 ` Anup Patel
0 siblings, 0 replies; 55+ messages in thread
From: Anup Patel @ 2025-07-04 4:15 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Linus Walleij, Bartosz Golaszewski,
Uwe Kleine-König, Palmer Dabbelt, Paul Walmsley,
Alexandre Ghiti, Len Brown, Sunil V L, Rahul Pathak, Leyfoon Tan,
Atish Patra, Andrew Jones, Samuel Holland, Anup Patel, linux-clk,
devicetree, linux-acpi, linux-riscv, linux-kernel
On Wed, Jul 2, 2025 at 6:38 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> On Wed, Jul 02, 2025 at 10:43:31AM +0530, Anup Patel wrote:
> >
> > The RPMI specification defines a clock service group which can be
> > accessed via SBI MPXY extension or dedicated S-mode RPMI transport.
> >
> > Add mailbox client based clock driver for the RISC-V RPMI clock
> > service group.
>
> Now it looks much better!
>
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> One nit-pick below.
>
> ...
>
> > +/*
> > + * rpmi_clk_rates represents the rates format
> > + * as specified by the RPMI specification.
> > + * No other format conversion(eg. linear_range) is
> > + * required to avoid to and fro conversion.
>
> conversion appears twice. I would suggest use this:
>
> * No other data format (e.g., struct linear_range) is
> * required to avoid to and from conversion.
>
I will update it in the next revision.
Thanks,
Anup
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v7 06/24] byteorder: Add memcpy_to_le32() and memcpy_from_le32()
2025-07-02 5:13 ` [PATCH v7 06/24] byteorder: Add memcpy_to_le32() and memcpy_from_le32() Anup Patel
2025-07-02 11:30 ` Andy Shevchenko
@ 2025-07-04 8:16 ` Linus Walleij
1 sibling, 0 replies; 55+ messages in thread
From: Linus Walleij @ 2025-07-04 8:16 UTC (permalink / raw)
To: Anup Patel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jassi Brar, Thomas Gleixner, Rafael J . Wysocki,
Mika Westerberg, Andy Shevchenko, Bartosz Golaszewski,
Uwe Kleine-König, Palmer Dabbelt, Paul Walmsley,
Alexandre Ghiti, Len Brown, Sunil V L, Rahul Pathak, Leyfoon Tan,
Atish Patra, Andrew Jones, Samuel Holland, Anup Patel, linux-clk,
devicetree, linux-acpi, linux-riscv, linux-kernel
On Wed, Jul 2, 2025 at 7:14 AM Anup Patel <apatel@ventanamicro.com> wrote:
> Add common memcpy APIs for copying u32 array to/from __le32 array.
>
> Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Signed-off-by: Anup Patel <apatel@ventanamicro.com>
That looks useful.
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 55+ messages in thread
end of thread, other threads:[~2025-07-04 8:16 UTC | newest]
Thread overview: 55+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-02 5:13 [PATCH v7 00/24] Linux SBI MPXY and RPMI drivers Anup Patel
2025-07-02 5:13 ` [PATCH v7 01/24] dt-bindings: mailbox: Add bindings for RPMI shared memory transport Anup Patel
2025-07-02 5:13 ` [PATCH v7 02/24] dt-bindings: mailbox: Add bindings for RISC-V SBI MPXY extension Anup Patel
2025-07-02 5:13 ` [PATCH v7 03/24] RISC-V: Add defines for the SBI message proxy extension Anup Patel
2025-07-02 12:03 ` Andy Shevchenko
2025-07-02 12:06 ` Andy Shevchenko
2025-07-03 5:16 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 04/24] mailbox: Add common header for RPMI messages sent via mailbox Anup Patel
2025-07-02 5:13 ` [PATCH v7 05/24] mailbox: Allow controller specific mapping using fwnode Anup Patel
2025-07-02 12:32 ` Andy Shevchenko
2025-07-02 5:13 ` [PATCH v7 06/24] byteorder: Add memcpy_to_le32() and memcpy_from_le32() Anup Patel
2025-07-02 11:30 ` Andy Shevchenko
2025-07-04 8:16 ` Linus Walleij
2025-07-02 5:13 ` [PATCH v7 07/24] mailbox: Add RISC-V SBI message proxy (MPXY) based mailbox driver Anup Patel
2025-07-02 12:50 ` Andy Shevchenko
2025-07-03 6:52 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 08/24] dt-bindings: clock: Add RPMI clock service message proxy bindings Anup Patel
2025-07-02 5:13 ` [PATCH v7 09/24] dt-bindings: clock: Add RPMI clock service controller bindings Anup Patel
2025-07-02 5:13 ` [PATCH v7 10/24] clk: Add clock driver for the RISC-V RPMI clock service group Anup Patel
2025-07-02 13:08 ` Andy Shevchenko
2025-07-04 4:15 ` Anup Patel
2025-07-02 5:13 ` [PATCH v7 11/24] dt-bindings: Add RPMI system MSI message proxy bindings Anup Patel
2025-07-02 5:13 ` [PATCH v7 12/24] dt-bindings: Add RPMI system MSI interrupt controller bindings Anup Patel
2025-07-02 5:13 ` [PATCH v7 13/24] irqchip: Add driver for the RPMI system MSI service group Anup Patel
2025-07-02 5:13 ` [PATCH v7 14/24] ACPI: property: Refactor acpi_fwnode_get_reference_args() Anup Patel
2025-07-02 10:07 ` Rafael J. Wysocki
2025-07-02 14:45 ` Sunil V L
2025-07-02 17:01 ` Rafael J. Wysocki
2025-07-02 5:13 ` [PATCH v7 15/24] ACPI: property: Add support for cells property Anup Patel
2025-07-02 10:20 ` Rafael J. Wysocki
2025-07-02 11:37 ` Andy Shevchenko
2025-07-02 11:39 ` Andy Shevchenko
2025-07-02 12:39 ` Rafael J. Wysocki
2025-07-02 12:56 ` Andy Shevchenko
2025-07-02 13:16 ` Rafael J. Wysocki
2025-07-02 15:06 ` Sunil V L
2025-07-02 16:56 ` Rafael J. Wysocki
2025-07-03 9:31 ` Sunil V L
2025-07-02 11:44 ` Andy Shevchenko
2025-07-02 5:13 ` [PATCH v7 16/24] ACPI: scan: Update honor list for RPMI System MSI Anup Patel
2025-07-02 10:21 ` Rafael J. Wysocki
2025-07-02 11:45 ` Andy Shevchenko
2025-07-02 5:13 ` [PATCH v7 17/24] ACPI: RISC-V: Create interrupt controller list in sorted order Anup Patel
2025-07-02 5:13 ` [PATCH v7 18/24] ACPI: RISC-V: Add support to update gsi range Anup Patel
2025-07-02 5:13 ` [PATCH v7 19/24] ACPI: RISC-V: Add RPMI System MSI to GSI mapping Anup Patel
2025-07-02 5:13 ` [PATCH v7 20/24] irqchip/irq-riscv-imsic-early: Export imsic_acpi_get_fwnode() Anup Patel
2025-07-02 5:13 ` [PATCH v7 21/24] mailbox/riscv-sbi-mpxy: Add ACPI support Anup Patel
2025-07-02 12:28 ` Andy Shevchenko
2025-07-03 10:54 ` Sunil V L
2025-07-03 13:54 ` Andy Shevchenko
2025-07-03 14:26 ` Anup Patel
2025-07-03 14:32 ` Andy Shevchenko
2025-07-02 5:13 ` [PATCH v7 22/24] irqchip/riscv-rpmi-sysmsi: " Anup Patel
2025-07-02 5:13 ` [PATCH v7 23/24] RISC-V: Enable GPIO keyboard and event device in RV64 defconfig Anup Patel
2025-07-02 5:13 ` [PATCH v7 24/24] MAINTAINERS: Add entry for RISC-V RPMI and MPXY drivers Anup Patel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).