drivers/irqchip/irq-gic-its-msi-parent.c | 34 ++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-)
In some legacy platforms the MSI controller for a PCI host bridge is
identified by an msi-parent property whose phandle points at an MSI
controller node with no #msi-cells property, that implicitly
means #msi-cells == 0.
For such platforms, mapping a device ID and retrieving the MSI controller
node becomes simply a matter of checking whether in the device hierarchy
there is an msi-parent property pointing at an MSI controller node with
such characteristics.
Add a helper function to its_v5_pci_msi_prepare() to check the msi-parent
property in addition to msi-map and retrieve the MSI controller node (with
a 1:1 ID deviceID-IN<->deviceID-OUT mapping) to provide support for
deviceID mapping and MSI controller node retrieval for such platforms.
Fixes: 57d72196dfc8 ("irqchip/gic-v5: Add GICv5 ITS support")
Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
Cc: Sascha Bischoff <sascha.bischoff@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>
---
Follow-up to [1] in that it is a fix and too risky to fix generic OF code at
this stage of development since it might affect other platforms.
Apply a fix to GIC ITS v5 MSI parent code - follow-up will clean up
the msi-parent parsing in the kernel tree.
[1] https://lore.kernel.org/lkml/20250916091858.257868-1-lpieralisi@kernel.org/
drivers/irqchip/irq-gic-its-msi-parent.c | 34 ++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
diff --git a/drivers/irqchip/irq-gic-its-msi-parent.c b/drivers/irqchip/irq-gic-its-msi-parent.c
index eb1473f1448a..198fb4e9a22d 100644
--- a/drivers/irqchip/irq-gic-its-msi-parent.c
+++ b/drivers/irqchip/irq-gic-its-msi-parent.c
@@ -101,6 +101,33 @@ static int its_pci_msi_prepare(struct irq_domain *domain, struct device *dev,
return msi_info->ops->msi_prepare(domain->parent, dev, nvec, info);
}
+static int its_v5_get_msi_parent(struct device *dev, struct device_node **msi_np)
+{
+ struct of_phandle_args out_msi;
+ struct device *parent_dev;
+ int ret;
+
+ /*
+ * Walk up the device parent links looking for one with a
+ * "msi-parent" property.
+ */
+ for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) {
+ ret = of_parse_phandle_with_optional_args(parent_dev->of_node, "msi-parent",
+ "#msi-cells",
+ 0, &out_msi);
+ if (!ret) {
+ if (!out_msi.args_count) {
+ /* Return with a node reference held */
+ *msi_np = out_msi.np;
+ return 0;
+ }
+ of_node_put(out_msi.np);
+ }
+ }
+
+ return -ENODEV;
+}
+
static int its_v5_pci_msi_prepare(struct irq_domain *domain, struct device *dev,
int nvec, msi_alloc_info_t *info)
{
@@ -117,8 +144,11 @@ static int its_v5_pci_msi_prepare(struct irq_domain *domain, struct device *dev,
pdev = to_pci_dev(dev);
rid = pci_msi_map_rid_ctlr_node(pdev, &msi_node);
- if (!msi_node)
- return -ENODEV;
+ if (!msi_node) {
+ ret = its_v5_get_msi_parent(&pdev->dev, &msi_node);
+ if (ret)
+ return ret;
+ }
ret = its_translate_frame_address(msi_node, &pa);
if (ret)
--
2.48.0
On Mon, 2025-09-22 at 16:26 +0200, Lorenzo Pieralisi wrote: > In some legacy platforms the MSI controller for a PCI host bridge is > identified by an msi-parent property whose phandle points at an MSI > controller node with no #msi-cells property, that implicitly > means #msi-cells == 0. > > For such platforms, mapping a device ID and retrieving the MSI > controller > node becomes simply a matter of checking whether in the device > hierarchy > there is an msi-parent property pointing at an MSI controller node > with > such characteristics. > > Add a helper function to its_v5_pci_msi_prepare() to check the msi- > parent > property in addition to msi-map and retrieve the MSI controller node > (with > a 1:1 ID deviceID-IN<->deviceID-OUT mapping) to provide support for > deviceID mapping and MSI controller node retrieval for such > platforms. > > Fixes: 57d72196dfc8 ("irqchip/gic-v5: Add GICv5 ITS support") > Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org> > Cc: Sascha Bischoff <sascha.bischoff@arm.com> > Cc: Thomas Gleixner <tglx@linutronix.de> > Cc: Rob Herring <robh@kernel.org> > Cc: Marc Zyngier <maz@kernel.org> > --- > Follow-up to [1] in that it is a fix and too risky to fix generic OF > code at > this stage of development since it might affect other platforms. > > Apply a fix to GIC ITS v5 MSI parent code - follow-up will clean up > the msi-parent parsing in the kernel tree. > > [1] > https://lore.kernel.org/lkml/20250916091858.257868-1-lpieralisi@kernel.org/ > > drivers/irqchip/irq-gic-its-msi-parent.c | 34 > ++++++++++++++++++++++-- > 1 file changed, 32 insertions(+), 2 deletions(-) > > diff --git a/drivers/irqchip/irq-gic-its-msi-parent.c > b/drivers/irqchip/irq-gic-its-msi-parent.c > index eb1473f1448a..198fb4e9a22d 100644 > --- a/drivers/irqchip/irq-gic-its-msi-parent.c > +++ b/drivers/irqchip/irq-gic-its-msi-parent.c > @@ -101,6 +101,33 @@ static int its_pci_msi_prepare(struct irq_domain > *domain, struct device *dev, > return msi_info->ops->msi_prepare(domain->parent, dev, nvec, > info); > } > > +static int its_v5_get_msi_parent(struct device *dev, struct > device_node **msi_np) > +{ > + struct of_phandle_args out_msi; > + struct device *parent_dev; > + int ret; > + > + /* > + * Walk up the device parent links looking for one with a > + * "msi-parent" property. > + */ > + for (parent_dev = dev; parent_dev; parent_dev = parent_dev- > >parent) { > + ret = > of_parse_phandle_with_optional_args(parent_dev->of_node, "msi- > parent", > + "#msi- > cells", > + 0, > &out_msi); > + if (!ret) { > + if (!out_msi.args_count) { > + /* Return with a node reference held > */ > + *msi_np = out_msi.np; > + return 0; > + } > + of_node_put(out_msi.np); > + } > + } > + > + return -ENODEV; > +} > + > static int its_v5_pci_msi_prepare(struct irq_domain *domain, struct > device *dev, > int nvec, msi_alloc_info_t *info) > { > @@ -117,8 +144,11 @@ static int its_v5_pci_msi_prepare(struct > irq_domain *domain, struct device *dev, > pdev = to_pci_dev(dev); > > rid = pci_msi_map_rid_ctlr_node(pdev, &msi_node); > - if (!msi_node) > - return -ENODEV; > + if (!msi_node) { > + ret = its_v5_get_msi_parent(&pdev->dev, &msi_node); > + if (ret) > + return ret; > + } > > ret = its_translate_frame_address(msi_node, &pa); > if (ret) Tested-by: Sascha Bischoff <sascha.bischoff@arm.com> Thanks, Sascha
© 2016 - 2025 Red Hat, Inc.