Skip to content

Commit 119aaee

Browse files
Lorenzo Pieralisirobherring
authored andcommitted
of/irq: Add msi-parent check to of_msi_xlate()
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 of_msi_xlate() 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: 57d7219 ("irqchip/gic-v5: Add GICv5 ITS support") Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org> Reviewed-by: Frank Li <Frank.Li@nxp.com> Cc: Sascha Bischoff <sascha.bischoff@arm.com> Cc: Rob Herring <robh@kernel.org> Cc: Marc Zyngier <maz@kernel.org> Link: https://patch.msgid.link/20251021124103.198419-2-lpieralisi@kernel.org Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
1 parent 3a86608 commit 119aaee

File tree

1 file changed

+36
-3
lines changed

1 file changed

+36
-3
lines changed

drivers/of/irq.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -671,14 +671,44 @@ void __init of_irq_init(const struct of_device_id *matches)
671671
}
672672
}
673673

674+
static int of_check_msi_parent(struct device_node *dev_node, struct device_node **msi_node)
675+
{
676+
struct of_phandle_args msi_spec;
677+
int ret;
678+
679+
/*
680+
* An msi-parent phandle with a missing or == 0 #msi-cells
681+
* property identifies a 1:1 ID translation mapping.
682+
*
683+
* Set the msi controller node if the firmware matches this
684+
* condition.
685+
*/
686+
ret = of_parse_phandle_with_optional_args(dev_node, "msi-parent", "#msi-cells",
687+
0, &msi_spec);
688+
if (ret)
689+
return ret;
690+
691+
if ((*msi_node && *msi_node != msi_spec.np) || msi_spec.args_count != 0)
692+
ret = -EINVAL;
693+
694+
if (!ret) {
695+
/* Return with a node reference held */
696+
*msi_node = msi_spec.np;
697+
return 0;
698+
}
699+
of_node_put(msi_spec.np);
700+
701+
return ret;
702+
}
703+
674704
/**
675705
* of_msi_xlate - map a MSI ID and find relevant MSI controller node
676706
* @dev: device for which the mapping is to be done.
677707
* @msi_np: Pointer to target MSI controller node
678708
* @id_in: Device ID.
679709
*
680710
* Walk up the device hierarchy looking for devices with a "msi-map"
681-
* property. If found, apply the mapping to @id_in.
711+
* or "msi-parent" property. If found, apply the mapping to @id_in.
682712
* If @msi_np points to a non-NULL device node pointer, only entries targeting
683713
* that node will be matched; if it points to a NULL value, it will receive the
684714
* device node of the first matching target phandle, with a reference held.
@@ -692,12 +722,15 @@ u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_in)
692722

693723
/*
694724
* Walk up the device parent links looking for one with a
695-
* "msi-map" property.
725+
* "msi-map" or an "msi-parent" property.
696726
*/
697-
for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent)
727+
for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) {
698728
if (!of_map_id(parent_dev->of_node, id_in, "msi-map",
699729
"msi-map-mask", msi_np, &id_out))
700730
break;
731+
if (!of_check_msi_parent(parent_dev->of_node, msi_np))
732+
break;
733+
}
701734
return id_out;
702735
}
703736

0 commit comments

Comments
 (0)