Devicetree
 help / color / mirror / Atom feed
* [PATCH v2] driver core: platform: Setup device MSI domain just before driver probe
@ 2026-07-27  8:40 Anup Patel
  2026-07-27  8:57 ` sashiko-bot
  2026-07-27 12:16 ` Robin Murphy
  0 siblings, 2 replies; 3+ messages in thread
From: Anup Patel @ 2026-07-27  8:40 UTC (permalink / raw)
  To: Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti, Thomas Gleixner,
	Greg Kroah-Hartman, Danilo Krummrich, Tomasz Jeznach,
	Joerg Roedel, Will Deacon, Robin Murphy, Jassi Brar, Rob Herring,
	Krzysztof Kozlowski, Rafael J . Wysocki, Len Brown
  Cc: Saket Dumbre, Rahul Pathak, Atish Patra, Anup Patel, Andrew Jones,
	linux-acpi, linux-riscv, linux-kernel, devicetree, driver-core,
	iommu, acpica-devel, Anup Patel, Sunil V L

On RISC-V, the MSI controller (aka RISC-V IMSIC) is probed as a regular
platform device and MSI client drivers are always probed after the MSI
controller driver using fw_devlink. Unfortunately, this is not sufficient
to ensure device MSI domain is set for MSI client devices before driver
probe because OF framework sets device MSI domain at the time of platform
device creation whereas ACPI framework expects arch specific code to set
the device MSI domain at the time of platform device creation.

Currently, to address the problem of device MSI domain being not set
correctly, various RISC-V MSI client drivers explicitly set device
MSI domain in the driver probe function using below code pattern:

	/*
	 * The device MSI domain for platform devices on RISC-V architecture
	 * is only available after the MSI controller driver is probed so,
	 * explicitly configure here.
	 */
	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 (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))
			return -EPROBE_DEFER;
	}

Instead of the above approach, extend the platform_dma_configure() to set
device MSI domain for both OF and ACPI based platform devices before driver
probe and remove the duplicate code pattern from RISC-V MSI client drivers.

Co-developed-by: Sunil V L <sunilvl@oss.qualcomm.com>
Signed-off-by: Sunil V L <sunilvl@oss.qualcomm.com>
Signed-off-by: Anup Patel <anup.patel@oss.qualcomm.com>
---
Changes since v1:
 - Rebased on Linux-7.2-rc5
 - Minor improvement to commit description
---
 drivers/acpi/riscv/irq.c                | 13 +++++++++++
 drivers/acpi/scan.c                     | 10 +++++++++
 drivers/base/platform.c                 |  4 ++++
 drivers/iommu/riscv/iommu-platform.c    |  9 --------
 drivers/irqchip/irq-riscv-aplic-msi.c   | 27 -----------------------
 drivers/irqchip/irq-riscv-rpmi-sysmsi.c | 29 -------------------------
 drivers/mailbox/riscv-sbi-mpxy-mbox.c   | 29 -------------------------
 include/acpi/acpi_bus.h                 |  1 +
 include/linux/acpi.h                    | 10 +++++++++
 9 files changed, 38 insertions(+), 94 deletions(-)

diff --git a/drivers/acpi/riscv/irq.c b/drivers/acpi/riscv/irq.c
index 9b88d0993e88..17fa5dcdd2c0 100644
--- a/drivers/acpi/riscv/irq.c
+++ b/drivers/acpi/riscv/irq.c
@@ -5,8 +5,11 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/device.h>
 #include <linux/sort.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip/riscv-imsic.h>
 
 #include "init.h"
 
@@ -397,6 +400,16 @@ static u32 riscv_acpi_add_irq_dep(acpi_handle handle)
 	return count;
 }
 
+void acpi_arch_msi_configure(struct device *dev)
+{
+	struct irq_domain *msi_domain;
+
+	msi_domain = irq_find_matching_fwnode(imsic_acpi_get_fwnode(dev),
+					      DOMAIN_BUS_PLATFORM_MSI);
+	if (msi_domain)
+		dev_set_msi_domain(dev, msi_domain);
+}
+
 u32 arch_acpi_add_auto_dep(acpi_handle handle)
 {
 	if (acpi_has_method(handle, "_PRT"))
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 9a7ac2eb9ce0..75c52f6bbbe8 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1650,6 +1650,16 @@ static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 
 #endif /* !CONFIG_IOMMU_API */
 
+/**
+ * acpi_msi_configure - Set-up MSI domain for the device.
+ * @dev: The pointer to the device
+ */
+void acpi_msi_configure(struct device *dev)
+{
+	acpi_arch_msi_configure(dev);
+}
+EXPORT_SYMBOL_GPL(acpi_msi_configure);
+
 /**
  * acpi_dma_configure_id - Set-up DMA configuration for the device.
  * @dev: The pointer to the device
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index fb9120b0bcfe..965ed6ae5bb5 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -1477,8 +1477,12 @@ static int platform_dma_configure(struct device *dev)
 	int ret = 0;
 
 	if (is_of_node(fwnode)) {
+		if (!dev_get_msi_domain(dev))
+			of_msi_configure(dev, dev->of_node);
 		ret = of_dma_configure(dev, to_of_node(fwnode), true);
 	} else if (is_acpi_device_node(fwnode)) {
+		if (!dev_get_msi_domain(dev))
+			acpi_msi_configure(dev);
 		attr = acpi_get_dma_attr(to_acpi_device_node(fwnode));
 		ret = acpi_dma_configure(dev, attr);
 	}
diff --git a/drivers/iommu/riscv/iommu-platform.c b/drivers/iommu/riscv/iommu-platform.c
index 399ba8fe1b3e..ddc6370b96b0 100644
--- a/drivers/iommu/riscv/iommu-platform.c
+++ b/drivers/iommu/riscv/iommu-platform.c
@@ -48,7 +48,6 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 	enum riscv_iommu_igs_settings igs;
 	struct device *dev = &pdev->dev;
 	struct riscv_iommu_device *iommu = NULL;
-	struct irq_domain *msi_domain;
 	struct resource *res = NULL;
 	int vec, ret;
 
@@ -74,14 +73,6 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
 	switch (igs) {
 	case RISCV_IOMMU_CAPABILITIES_IGS_BOTH:
 	case RISCV_IOMMU_CAPABILITIES_IGS_MSI:
-		if (is_of_node(dev_fwnode(dev))) {
-			of_msi_configure(dev, to_of_node(dev->fwnode));
-		} else {
-			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)) {
 			dev_warn(dev, "failed to find an MSI domain\n");
 			goto msi_fail;
diff --git a/drivers/irqchip/irq-riscv-aplic-msi.c b/drivers/irqchip/irq-riscv-aplic-msi.c
index fb8d1838609f..2cf5d42cd66a 100644
--- a/drivers/irqchip/irq-riscv-aplic-msi.c
+++ b/drivers/irqchip/irq-riscv-aplic-msi.c
@@ -175,7 +175,6 @@ static const struct msi_domain_template aplic_msi_template = {
 int aplic_msi_setup(struct device *dev, void __iomem *regs)
 {
 	const struct imsic_global_config *imsic_global;
-	struct irq_domain *msi_domain;
 	struct aplic_priv *priv;
 	struct aplic_msicfg *mc;
 	phys_addr_t pa;
@@ -245,32 +244,6 @@ int aplic_msi_setup(struct device *dev, void __iomem *regs)
 	/* Setup global config and interrupt delivery */
 	aplic_init_hw_global(priv, true);
 
-	/* Set the APLIC 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.
-		 *
-		 * In case of APLIC device, the parent MSI domain is always
-		 * IMSIC and the IMSIC MSI domains are created later through
-		 * the platform driver probing so we set it explicitly here.
-		 */
-		if (is_of_node(dev->fwnode)) {
-			of_msi_configure(dev, to_of_node(dev->fwnode));
-		} else {
-			msi_domain = irq_find_matching_fwnode(imsic_acpi_get_fwnode(dev),
-							      DOMAIN_BUS_PLATFORM_MSI);
-			if (msi_domain)
-				dev_set_msi_domain(dev, msi_domain);
-		}
-
-		if (!dev_get_msi_domain(dev))
-			return -EPROBE_DEFER;
-	}
-
 	if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN, &aplic_msi_template,
 					  priv->nr_irqs + 1, priv, priv)) {
 		dev_err(dev, "failed to create MSI irq domain\n");
diff --git a/drivers/irqchip/irq-riscv-rpmi-sysmsi.c b/drivers/irqchip/irq-riscv-rpmi-sysmsi.c
index 612f3972f7af..e6cdb4b635a6 100644
--- a/drivers/irqchip/irq-riscv-rpmi-sysmsi.c
+++ b/drivers/irqchip/irq-riscv-rpmi-sysmsi.c
@@ -260,35 +260,6 @@ static int rpmi_sysmsi_probe(struct platform_device *pdev)
 			riscv_acpi_update_gsi_range(priv->gsi_base, priv->nr_irqs);
 	}
 
-	/*
-	 * The device MSI domain for platform devices on RISC-V architecture
-	 * is only available after the MSI controller driver is probed so,
-	 * explicitly configure here.
-	 */
-	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 (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);
-			return -EPROBE_DEFER;
-		}
-	}
-
 	if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN,
 					  &rpmi_sysmsi_template,
 					  priv->nr_irqs, priv, priv)) {
diff --git a/drivers/mailbox/riscv-sbi-mpxy-mbox.c b/drivers/mailbox/riscv-sbi-mpxy-mbox.c
index 7c9c006b7244..759512aba19f 100644
--- a/drivers/mailbox/riscv-sbi-mpxy-mbox.c
+++ b/drivers/mailbox/riscv-sbi-mpxy-mbox.c
@@ -902,35 +902,6 @@ static int mpxy_mbox_probe(struct platform_device *pdev)
 
 	/* Setup MSIs for mailbox (if required) */
 	if (mbox->msi_count) {
-		/*
-		 * The device MSI domain for platform devices on RISC-V architecture
-		 * is only available after the MSI controller driver is probed so,
-		 * explicitly configure here.
-		 */
-		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
-			 * domain is discovered later after the OF device is created
-			 * then we need to set it explicitly before using any platform
-			 * MSI functions.
-			 */
-			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))
-				return -EPROBE_DEFER;
-		}
-
 		mbox->msi_index_to_channel = devm_kcalloc(dev, mbox->msi_count,
 							  sizeof(*mbox->msi_index_to_channel),
 							  GFP_KERNEL);
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 714d111d8053..d971d6bc14d7 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -750,6 +750,7 @@ bool acpi_dma_supported(const struct acpi_device *adev);
 enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
 int acpi_iommu_fwspec_init(struct device *dev, u32 id,
 			   struct fwnode_handle *fwnode);
+void acpi_msi_configure(struct device *dev);
 int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
 int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
 			   const u32 *input_id);
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 60ab50cb8930..5e2e377c48b4 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -260,6 +260,12 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) { }
 
 void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa);
 
+#if defined(CONFIG_RISCV)
+void acpi_arch_msi_configure(struct device *dev);
+#else
+static inline void acpi_arch_msi_configure(struct device *dev) { }
+#endif
+
 #if defined(CONFIG_ARM64) || defined(CONFIG_LOONGARCH)
 void acpi_arch_dma_setup(struct device *dev);
 #else
@@ -1060,6 +1066,10 @@ static inline int acpi_dma_get_range(struct device *dev, const struct bus_dma_re
 	return -ENODEV;
 }
 
+static inline void acpi_msi_configure(struct device *dev)
+{
+}
+
 static inline int acpi_dma_configure(struct device *dev,
 				     enum dev_dma_attr attr)
 {
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] driver core: platform: Setup device MSI domain just before driver probe
  2026-07-27  8:40 [PATCH v2] driver core: platform: Setup device MSI domain just before driver probe Anup Patel
@ 2026-07-27  8:57 ` sashiko-bot
  2026-07-27 12:16 ` Robin Murphy
  1 sibling, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-07-27  8:57 UTC (permalink / raw)
  To: Anup Patel; +Cc: robh, conor+dt, devicetree

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Removal of explicit `-EPROBE_DEFER` fallbacks causes permanent probe failures for MSI client drivers.
- [High] Inconsistent and unsafe use of `dev->of_node` instead of `to_of_node(fwnode)` in `platform_dma_configure()`.
--

--- Patch [1]: [PATCH v2] driver core: platform: Setup device MSI domain just before driver probe ---
commit af1d054c0ea0f493a963d5cdb4333c67d265bf5a
Author: Anup Patel <anup.patel@oss.qualcomm.com>

driver core: platform: Setup device MSI domain just before driver probe

This commit extends platform_dma_configure() to configure device MSI
domains for both OF and ACPI devices prior to driver probe. It also
removes the duplicate MSI domain setup and probe deferral logic from
several RISC-V MSI client drivers.

> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index fb9120b0bcfe0..965ed6ae5bb54 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -1477,8 +1477,12 @@ static int platform_dma_configure(struct device *dev)
>  	int ret = 0;
>  
>  	if (is_of_node(fwnode)) {
> +		if (!dev_get_msi_domain(dev))
> +			of_msi_configure(dev, dev->of_node);

[Severity: High]
Should this use to_of_node(fwnode) instead of dev->of_node?

If a platform device has a valid fwnode but dev->of_node is NULL (which can
happen with dynamically instantiated MFD children), passing dev->of_node to
of_msi_configure() will silently fail to configure the MSI domain. 

The very next line uses to_of_node(fwnode) safely for of_dma_configure().

>  		ret = of_dma_configure(dev, to_of_node(fwnode), true);
>  	} else if (is_acpi_device_node(fwnode)) {

[ ... ]

> diff --git a/drivers/irqchip/irq-riscv-aplic-msi.c b/drivers/irqchip/irq-riscv-aplic-msi.c
> index fb8d1838609fb..2cf5d42cd66a8 100644
> --- a/drivers/irqchip/irq-riscv-aplic-msi.c
> +++ b/drivers/irqchip/irq-riscv-aplic-msi.c

[ ... ]

> @@ -245,32 +244,6 @@ int aplic_msi_setup(struct device *dev, void __iomem *regs)
>  	/* Setup global config and interrupt delivery */
>  	aplic_init_hw_global(priv, true);
>  
> -	/* Set the APLIC device MSI domain if not available */
> -	if (!dev_get_msi_domain(dev)) {

[ ... ]

> -		if (!dev_get_msi_domain(dev))
> -			return -EPROBE_DEFER;
> -	}
> -
>  	if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN, &aplic_msi_template,
>  					  priv->nr_irqs + 1, priv, priv)) {
>  		dev_err(dev, "failed to create MSI irq domain\n");

[Severity: High]
Does removing the explicit -EPROBE_DEFER fallback cause a permanent probe
failure here?

If the IMSIC controller isn't probed first (for example, if fw_devlink is
disabled or fails to guarantee probe ordering), the parent MSI domain won't
be set yet in platform_dma_configure().

Without the -EPROBE_DEFER path, msi_create_device_irq_domain() will fail
with -ENOMEM because the parent domain is missing, and the driver probe
will permanently fail instead of deferring.

This same probe deferral removal appears to cause similar permanent probe
failures in rpmi_sysmsi_probe() in drivers/irqchip/irq-riscv-rpmi-sysmsi.c
and mpxy_mbox_probe() in drivers/mailbox/riscv-sbi-mpxy-mbox.c.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260727084003.1951324-1-anup.patel@oss.qualcomm.com?part=1

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] driver core: platform: Setup device MSI domain just before driver probe
  2026-07-27  8:40 [PATCH v2] driver core: platform: Setup device MSI domain just before driver probe Anup Patel
  2026-07-27  8:57 ` sashiko-bot
@ 2026-07-27 12:16 ` Robin Murphy
  1 sibling, 0 replies; 3+ messages in thread
From: Robin Murphy @ 2026-07-27 12:16 UTC (permalink / raw)
  To: Anup Patel, Palmer Dabbelt, Paul Walmsley, Alexandre Ghiti,
	Thomas Gleixner, Greg Kroah-Hartman, Danilo Krummrich,
	Tomasz Jeznach, Joerg Roedel, Will Deacon, Jassi Brar,
	Rob Herring, Krzysztof Kozlowski, Rafael J . Wysocki, Len Brown
  Cc: Saket Dumbre, Rahul Pathak, Atish Patra, Anup Patel, Andrew Jones,
	linux-acpi, linux-riscv, linux-kernel, devicetree, driver-core,
	iommu, acpica-devel, Sunil V L

On 27/07/2026 9:40 am, Anup Patel wrote:
> On RISC-V, the MSI controller (aka RISC-V IMSIC) is probed as a regular
> platform device and MSI client drivers are always probed after the MSI
> controller driver using fw_devlink. Unfortunately, this is not sufficient
> to ensure device MSI domain is set for MSI client devices before driver
> probe because OF framework sets device MSI domain at the time of platform
> device creation whereas ACPI framework expects arch specific code to set
> the device MSI domain at the time of platform device creation.
> 
> Currently, to address the problem of device MSI domain being not set
> correctly, various RISC-V MSI client drivers explicitly set device
> MSI domain in the driver probe function using below code pattern:
> 
> 	/*
> 	 * The device MSI domain for platform devices on RISC-V architecture
> 	 * is only available after the MSI controller driver is probed so,
> 	 * explicitly configure here.
> 	 */
> 	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 (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))
> 			return -EPROBE_DEFER;

I stand by my previous comment that relying on ACPI initcall order and 
assuming fw_devlink is enabled doesn't really seem robust enough to 
justify dropping proper handling of this case, especially if pretending 
it's a generic interface.

Thanks,
Robin.

> 	}
> 
> Instead of the above approach, extend the platform_dma_configure() to set
> device MSI domain for both OF and ACPI based platform devices before driver
> probe and remove the duplicate code pattern from RISC-V MSI client drivers.
> 
> Co-developed-by: Sunil V L <sunilvl@oss.qualcomm.com>
> Signed-off-by: Sunil V L <sunilvl@oss.qualcomm.com>
> Signed-off-by: Anup Patel <anup.patel@oss.qualcomm.com>
> ---
> Changes since v1:
>   - Rebased on Linux-7.2-rc5
>   - Minor improvement to commit description
> ---
>   drivers/acpi/riscv/irq.c                | 13 +++++++++++
>   drivers/acpi/scan.c                     | 10 +++++++++
>   drivers/base/platform.c                 |  4 ++++
>   drivers/iommu/riscv/iommu-platform.c    |  9 --------
>   drivers/irqchip/irq-riscv-aplic-msi.c   | 27 -----------------------
>   drivers/irqchip/irq-riscv-rpmi-sysmsi.c | 29 -------------------------
>   drivers/mailbox/riscv-sbi-mpxy-mbox.c   | 29 -------------------------
>   include/acpi/acpi_bus.h                 |  1 +
>   include/linux/acpi.h                    | 10 +++++++++
>   9 files changed, 38 insertions(+), 94 deletions(-)
> 
> diff --git a/drivers/acpi/riscv/irq.c b/drivers/acpi/riscv/irq.c
> index 9b88d0993e88..17fa5dcdd2c0 100644
> --- a/drivers/acpi/riscv/irq.c
> +++ b/drivers/acpi/riscv/irq.c
> @@ -5,8 +5,11 @@
>    */
>   
>   #include <linux/acpi.h>
> +#include <linux/device.h>
>   #include <linux/sort.h>
>   #include <linux/irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/irqchip/riscv-imsic.h>
>   
>   #include "init.h"
>   
> @@ -397,6 +400,16 @@ static u32 riscv_acpi_add_irq_dep(acpi_handle handle)
>   	return count;
>   }
>   
> +void acpi_arch_msi_configure(struct device *dev)
> +{
> +	struct irq_domain *msi_domain;
> +
> +	msi_domain = irq_find_matching_fwnode(imsic_acpi_get_fwnode(dev),
> +					      DOMAIN_BUS_PLATFORM_MSI);
> +	if (msi_domain)
> +		dev_set_msi_domain(dev, msi_domain);
> +}
> +
>   u32 arch_acpi_add_auto_dep(acpi_handle handle)
>   {
>   	if (acpi_has_method(handle, "_PRT"))
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index 9a7ac2eb9ce0..75c52f6bbbe8 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -1650,6 +1650,16 @@ static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>   
>   #endif /* !CONFIG_IOMMU_API */
>   
> +/**
> + * acpi_msi_configure - Set-up MSI domain for the device.
> + * @dev: The pointer to the device
> + */
> +void acpi_msi_configure(struct device *dev)
> +{
> +	acpi_arch_msi_configure(dev);
> +}
> +EXPORT_SYMBOL_GPL(acpi_msi_configure);
> +
>   /**
>    * acpi_dma_configure_id - Set-up DMA configuration for the device.
>    * @dev: The pointer to the device
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index fb9120b0bcfe..965ed6ae5bb5 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -1477,8 +1477,12 @@ static int platform_dma_configure(struct device *dev)
>   	int ret = 0;
>   
>   	if (is_of_node(fwnode)) {
> +		if (!dev_get_msi_domain(dev))
> +			of_msi_configure(dev, dev->of_node);
>   		ret = of_dma_configure(dev, to_of_node(fwnode), true);
>   	} else if (is_acpi_device_node(fwnode)) {
> +		if (!dev_get_msi_domain(dev))
> +			acpi_msi_configure(dev);
>   		attr = acpi_get_dma_attr(to_acpi_device_node(fwnode));
>   		ret = acpi_dma_configure(dev, attr);
>   	}
> diff --git a/drivers/iommu/riscv/iommu-platform.c b/drivers/iommu/riscv/iommu-platform.c
> index 399ba8fe1b3e..ddc6370b96b0 100644
> --- a/drivers/iommu/riscv/iommu-platform.c
> +++ b/drivers/iommu/riscv/iommu-platform.c
> @@ -48,7 +48,6 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
>   	enum riscv_iommu_igs_settings igs;
>   	struct device *dev = &pdev->dev;
>   	struct riscv_iommu_device *iommu = NULL;
> -	struct irq_domain *msi_domain;
>   	struct resource *res = NULL;
>   	int vec, ret;
>   
> @@ -74,14 +73,6 @@ static int riscv_iommu_platform_probe(struct platform_device *pdev)
>   	switch (igs) {
>   	case RISCV_IOMMU_CAPABILITIES_IGS_BOTH:
>   	case RISCV_IOMMU_CAPABILITIES_IGS_MSI:
> -		if (is_of_node(dev_fwnode(dev))) {
> -			of_msi_configure(dev, to_of_node(dev->fwnode));
> -		} else {
> -			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)) {
>   			dev_warn(dev, "failed to find an MSI domain\n");
>   			goto msi_fail;
> diff --git a/drivers/irqchip/irq-riscv-aplic-msi.c b/drivers/irqchip/irq-riscv-aplic-msi.c
> index fb8d1838609f..2cf5d42cd66a 100644
> --- a/drivers/irqchip/irq-riscv-aplic-msi.c
> +++ b/drivers/irqchip/irq-riscv-aplic-msi.c
> @@ -175,7 +175,6 @@ static const struct msi_domain_template aplic_msi_template = {
>   int aplic_msi_setup(struct device *dev, void __iomem *regs)
>   {
>   	const struct imsic_global_config *imsic_global;
> -	struct irq_domain *msi_domain;
>   	struct aplic_priv *priv;
>   	struct aplic_msicfg *mc;
>   	phys_addr_t pa;
> @@ -245,32 +244,6 @@ int aplic_msi_setup(struct device *dev, void __iomem *regs)
>   	/* Setup global config and interrupt delivery */
>   	aplic_init_hw_global(priv, true);
>   
> -	/* Set the APLIC 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.
> -		 *
> -		 * In case of APLIC device, the parent MSI domain is always
> -		 * IMSIC and the IMSIC MSI domains are created later through
> -		 * the platform driver probing so we set it explicitly here.
> -		 */
> -		if (is_of_node(dev->fwnode)) {
> -			of_msi_configure(dev, to_of_node(dev->fwnode));
> -		} else {
> -			msi_domain = irq_find_matching_fwnode(imsic_acpi_get_fwnode(dev),
> -							      DOMAIN_BUS_PLATFORM_MSI);
> -			if (msi_domain)
> -				dev_set_msi_domain(dev, msi_domain);
> -		}
> -
> -		if (!dev_get_msi_domain(dev))
> -			return -EPROBE_DEFER;
> -	}
> -
>   	if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN, &aplic_msi_template,
>   					  priv->nr_irqs + 1, priv, priv)) {
>   		dev_err(dev, "failed to create MSI irq domain\n");
> diff --git a/drivers/irqchip/irq-riscv-rpmi-sysmsi.c b/drivers/irqchip/irq-riscv-rpmi-sysmsi.c
> index 612f3972f7af..e6cdb4b635a6 100644
> --- a/drivers/irqchip/irq-riscv-rpmi-sysmsi.c
> +++ b/drivers/irqchip/irq-riscv-rpmi-sysmsi.c
> @@ -260,35 +260,6 @@ static int rpmi_sysmsi_probe(struct platform_device *pdev)
>   			riscv_acpi_update_gsi_range(priv->gsi_base, priv->nr_irqs);
>   	}
>   
> -	/*
> -	 * The device MSI domain for platform devices on RISC-V architecture
> -	 * is only available after the MSI controller driver is probed so,
> -	 * explicitly configure here.
> -	 */
> -	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 (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);
> -			return -EPROBE_DEFER;
> -		}
> -	}
> -
>   	if (!msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN,
>   					  &rpmi_sysmsi_template,
>   					  priv->nr_irqs, priv, priv)) {
> diff --git a/drivers/mailbox/riscv-sbi-mpxy-mbox.c b/drivers/mailbox/riscv-sbi-mpxy-mbox.c
> index 7c9c006b7244..759512aba19f 100644
> --- a/drivers/mailbox/riscv-sbi-mpxy-mbox.c
> +++ b/drivers/mailbox/riscv-sbi-mpxy-mbox.c
> @@ -902,35 +902,6 @@ static int mpxy_mbox_probe(struct platform_device *pdev)
>   
>   	/* Setup MSIs for mailbox (if required) */
>   	if (mbox->msi_count) {
> -		/*
> -		 * The device MSI domain for platform devices on RISC-V architecture
> -		 * is only available after the MSI controller driver is probed so,
> -		 * explicitly configure here.
> -		 */
> -		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
> -			 * domain is discovered later after the OF device is created
> -			 * then we need to set it explicitly before using any platform
> -			 * MSI functions.
> -			 */
> -			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))
> -				return -EPROBE_DEFER;
> -		}
> -
>   		mbox->msi_index_to_channel = devm_kcalloc(dev, mbox->msi_count,
>   							  sizeof(*mbox->msi_index_to_channel),
>   							  GFP_KERNEL);
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index 714d111d8053..d971d6bc14d7 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -750,6 +750,7 @@ bool acpi_dma_supported(const struct acpi_device *adev);
>   enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
>   int acpi_iommu_fwspec_init(struct device *dev, u32 id,
>   			   struct fwnode_handle *fwnode);
> +void acpi_msi_configure(struct device *dev);
>   int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
>   int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
>   			   const u32 *input_id);
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 60ab50cb8930..5e2e377c48b4 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -260,6 +260,12 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) { }
>   
>   void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa);
>   
> +#if defined(CONFIG_RISCV)
> +void acpi_arch_msi_configure(struct device *dev);
> +#else
> +static inline void acpi_arch_msi_configure(struct device *dev) { }
> +#endif
> +
>   #if defined(CONFIG_ARM64) || defined(CONFIG_LOONGARCH)
>   void acpi_arch_dma_setup(struct device *dev);
>   #else
> @@ -1060,6 +1066,10 @@ static inline int acpi_dma_get_range(struct device *dev, const struct bus_dma_re
>   	return -ENODEV;
>   }
>   
> +static inline void acpi_msi_configure(struct device *dev)
> +{
> +}
> +
>   static inline int acpi_dma_configure(struct device *dev,
>   				     enum dev_dma_attr attr)
>   {


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-07-27 12:16 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-27  8:40 [PATCH v2] driver core: platform: Setup device MSI domain just before driver probe Anup Patel
2026-07-27  8:57 ` sashiko-bot
2026-07-27 12:16 ` Robin Murphy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox