Re: [PATCH] driver core: platform: Setup device MSI domain just before driver probe

From: Anup Patel

Date: Wed Jun 03 2026 - 02:45:09 EST


On Tue, May 26, 2026 at 8:53 PM Robin Murphy <robin.murphy@xxxxxxx> wrote:
>
> On 26/05/2026 3:52 pm, 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 work-around the problem of missing device MSI domain,
> > 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@xxxxxxxxxxxxxxxx>
> > Signed-off-by: Sunil V L <sunilvl@xxxxxxxxxxxxxxxx>
> > Signed-off-by: Anup Patel <anup.patel@xxxxxxxxxxxxxxxx>
> > ---
> > 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 530547cda8b2..e50e5d246a54 100644
> > --- a/drivers/acpi/scan.c
> > +++ b/drivers/acpi/scan.c
> > @@ -1648,6 +1648,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 a19dd22deef2..225e33080bc6 100644
> > --- a/drivers/base/platform.c
> > +++ b/drivers/base/platform.c
> > @@ -1470,8 +1470,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);
>
> But surely this needs to handle the deferral case that's being removed
> from some of the users below?

The deferral cases removed by this patch are redundant because:
1) For device tree, the fw_devlink support in Linux DD core takes
case of probe ordering and individual driver don't need to explicitly
do EPROBE_DEFER
2) For ACPI, the _DEP objects helps us ensure probe ordering.

In other words, the issue of probe ordering or deferral is already
handled for both device tree and ACPI.

The only problem which remains is msi_domain pointer not set
in struct device before the driver is probed. This happens because
MSI controller driver is a regular platform driver hence MSI domain
pointer is not set when platform devices are created.

>
> Also I'm not really convinced about bundling it into dma_configure,
> since it's mroe about IRQs than DMA. I wonder if overall it wouldn't be

Using platform_dma_configure() to update the MSI domain
in struct device is appropriate because:
1) MSIs are device initiated writes just like DMA writes
initiated by the device.
2) The iommu_device_use_default_domain() called by
platform_dma_configure() will override MSI domain
in struct device for architectures (such as x86 and
RISC-V) where IOMMU driver implements a IRQ
remap MSI domain for MSI capable devices.

> better with a flow closer to regular request_irq(), with
> msi_create_device_irq_domain() growing the ability to distingush between
> "there is no domain" and "there is no domain now, but could be if we try
> again later", such that drivers can handle deferral at the point where
> they request MSI vectors?

Like mentioned above, the problem is not about probe deferral
(aka returning EPROBE_DEFER) from request_irq() or
msi_create_device_irq_domain() rather about updating the
MSI domain pointer in struct device before driver probe.

Regards,
Anup