[PATCH] of: property: Create devlink between PCI Host bridge and Root Port suppliers

Manivannan Sadhasivam posted 1 patch 3 days, 8 hours ago
drivers/of/property.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
[PATCH] of: property: Create devlink between PCI Host bridge and Root Port suppliers
Posted by Manivannan Sadhasivam 3 days, 8 hours ago
In the recent times, devicetree started to represent the PCI Host bridge
supplies like PHY in the Root Port nodes as seen in commit 38fcbfbd4207
("dt-bindings: PCI: qcom: Move PHY & reset GPIO to Root Port node"). But
the Host bridge drivers still need to control these supplies as a part of
their controller initialization/deinitialization sequence.

So the Host bridge drivers end up parsing the Root Port supplies in their
probe() and controlled them. A downside to this approach is that the
devlink dependency between the suppliers and Host bridge is completely
broken. Due to this, the driver core probes the Host bridge drivers even if
the suppliers are not ready, causing probe deferrals and setup teardowns in
probe().

These probe deferrals sometime happen over 1000 times (as reported in Qcom
Glymur platform) leading to a waste of CPU resources and increase in boot
time. So to fix these unnecessary deferrals, create devlink between the
Host bridge and Root Port suppliers in of_fwnode_add_links(). This will
allow the driver core to probe the Host bridge drivers only when all Root
Port suppliers are available.

Reported-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
---
 drivers/of/property.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/of/property.c b/drivers/of/property.c
index 50d95d512bf5..10d041ea61f7 100644
--- a/drivers/of/property.c
+++ b/drivers/of/property.c
@@ -1561,6 +1561,7 @@ static const struct supplier_bindings of_supplier_bindings[] = {
 /**
  * of_link_property - Create device links to suppliers listed in a property
  * @con_np: The consumer device tree node which contains the property
+ * @parent_np: Optional parent device tree node requiring child's supplies
  * @prop_name: Name of property to be parsed
  *
  * This function checks if the property @prop_name that is present in the
@@ -1577,7 +1578,8 @@ static const struct supplier_bindings of_supplier_bindings[] = {
  * device tree nodes even when attempts to create a link to one or more
  * suppliers fail.
  */
-static int of_link_property(struct device_node *con_np, const char *prop_name)
+static int of_link_property(struct device_node *con_np, struct device_node *parent_np,
+			    const char *prop_name)
 {
 	struct device_node *phandle;
 	const struct supplier_bindings *s = of_supplier_bindings;
@@ -1598,6 +1600,10 @@ static int of_link_property(struct device_node *con_np, const char *prop_name)
 			matched = true;
 			i++;
 			of_link_to_phandle(con_dev_np, phandle, s->fwlink_flags);
+
+			/* Link the child's supplies to parent if needed */
+			if (parent_np)
+				of_link_to_phandle(parent_np, phandle, s->fwlink_flags);
 			of_node_put(phandle);
 		}
 		s++;
@@ -1632,7 +1638,21 @@ static int of_fwnode_add_links(struct fwnode_handle *fwnode)
 		return -EINVAL;
 
 	for_each_property_of_node(con_np, p)
-		of_link_property(con_np, p->name);
+		of_link_property(con_np, NULL, p->name);
+
+	/*
+	 * Supplies for the PCI host bridges are typically present in the Root
+	 * Port nodes. So parse the Root Port supplies and link them to Host
+	 * bridges (identified by the presence of "linux,pci-domain" property).
+	 */
+	if (of_property_present(con_np, "linux,pci-domain")) {
+		for_each_available_child_of_node_scoped(con_np, child) {
+			if (of_node_is_type(child, "pci")) {
+				for_each_property_of_node(child, p)
+					of_link_property(child, con_np, p->name);
+			}
+		}
+	}
 
 	return 0;
 }
-- 
2.51.0
Re: [PATCH] of: property: Create devlink between PCI Host bridge and Root Port suppliers
Posted by Konrad Dybcio 3 days, 6 hours ago
On 2/5/26 8:06 AM, Manivannan Sadhasivam wrote:
> In the recent times, devicetree started to represent the PCI Host bridge
> supplies like PHY in the Root Port nodes as seen in commit 38fcbfbd4207
> ("dt-bindings: PCI: qcom: Move PHY & reset GPIO to Root Port node"). But
> the Host bridge drivers still need to control these supplies as a part of
> their controller initialization/deinitialization sequence.
> 
> So the Host bridge drivers end up parsing the Root Port supplies in their
> probe() and controlled them. A downside to this approach is that the
> devlink dependency between the suppliers and Host bridge is completely
> broken. Due to this, the driver core probes the Host bridge drivers even if
> the suppliers are not ready, causing probe deferrals and setup teardowns in
> probe().
> 
> These probe deferrals sometime happen over 1000 times (as reported in Qcom
> Glymur platform) leading to a waste of CPU resources and increase in boot
> time. So to fix these unnecessary deferrals, create devlink between the
> Host bridge and Root Port suppliers in of_fwnode_add_links(). This will
> allow the driver core to probe the Host bridge drivers only when all Root
> Port suppliers are available.
> 
> Reported-by: Bjorn Andersson <andersson@kernel.org>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---

[...]

This is not 'required' in bindings and device_type="pci" doesn't uniquely
identify root complexes (as can be seen below).. but I suppose this is the
best delimiter we've got

Perhaps it could be made 'required'?

Konrad

> +		for_each_available_child_of_node_scoped(con_np, child) {
> +			if (of_node_is_type(child, "pci")) {
> +				for_each_property_of_node(child, p)
> +					of_link_property(child, con_np, p->name);
> +			}
> +		}
> +	}
>  
>  	return 0;
>  }
Re: [PATCH] of: property: Create devlink between PCI Host bridge and Root Port suppliers
Posted by Manivannan Sadhasivam 3 days, 6 hours ago
On Thu, Feb 05, 2026 at 09:50:20AM +0100, Konrad Dybcio wrote:
> On 2/5/26 8:06 AM, Manivannan Sadhasivam wrote:
> > In the recent times, devicetree started to represent the PCI Host bridge
> > supplies like PHY in the Root Port nodes as seen in commit 38fcbfbd4207
> > ("dt-bindings: PCI: qcom: Move PHY & reset GPIO to Root Port node"). But
> > the Host bridge drivers still need to control these supplies as a part of
> > their controller initialization/deinitialization sequence.
> > 
> > So the Host bridge drivers end up parsing the Root Port supplies in their
> > probe() and controlled them. A downside to this approach is that the
> > devlink dependency between the suppliers and Host bridge is completely
> > broken. Due to this, the driver core probes the Host bridge drivers even if
> > the suppliers are not ready, causing probe deferrals and setup teardowns in
> > probe().
> > 
> > These probe deferrals sometime happen over 1000 times (as reported in Qcom
> > Glymur platform) leading to a waste of CPU resources and increase in boot
> > time. So to fix these unnecessary deferrals, create devlink between the
> > Host bridge and Root Port suppliers in of_fwnode_add_links(). This will
> > allow the driver core to probe the Host bridge drivers only when all Root
> > Port suppliers are available.
> > 
> > Reported-by: Bjorn Andersson <andersson@kernel.org>
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> > ---
> 
> [...]
> 
> This is not 'required' in bindings and device_type="pci" doesn't uniquely
> identify root complexes (as can be seen below).. but I suppose this is the
> best delimiter we've got
> 

Yeah. There is no way to uniquely identify the Host bridges in DT. So I had to
settle for this.

Maybe I can check for 'device_type', but that will create devlink between switch
port supplies and Root Ports.

> Perhaps it could be made 'required'?
> 

Nah. Linux will generate domain numbers on its own. Also, this is a Linux
specific property, so we cannot make it mandatory in dtschema.

- Mani

-- 
மணிவண்ணன் சதாசிவம்
Re: [PATCH] of: property: Create devlink between PCI Host bridge and Root Port suppliers
Posted by Saravana Kannan 13 hours ago
On Thu, Feb 5, 2026 at 1:01 AM Manivannan Sadhasivam
<manivannan.sadhasivam@oss.qualcomm.com> wrote:
>
> On Thu, Feb 05, 2026 at 09:50:20AM +0100, Konrad Dybcio wrote:
> > On 2/5/26 8:06 AM, Manivannan Sadhasivam wrote:
> > > In the recent times, devicetree started to represent the PCI Host bridge
> > > supplies like PHY in the Root Port nodes as seen in commit 38fcbfbd4207
> > > ("dt-bindings: PCI: qcom: Move PHY & reset GPIO to Root Port node"). But
> > > the Host bridge drivers still need to control these supplies as a part of
> > > their controller initialization/deinitialization sequence.
> > >
> > > So the Host bridge drivers end up parsing the Root Port supplies in their
> > > probe() and controlled them. A downside to this approach is that the
> > > devlink dependency between the suppliers and Host bridge is completely
> > > broken. Due to this, the driver core probes the Host bridge drivers even if
> > > the suppliers are not ready, causing probe deferrals and setup teardowns in
> > > probe().
> > >
> > > These probe deferrals sometime happen over 1000 times (as reported in Qcom
> > > Glymur platform) leading to a waste of CPU resources and increase in boot
> > > time. So to fix these unnecessary deferrals, create devlink between the
> > > Host bridge and Root Port suppliers in of_fwnode_add_links(). This will
> > > allow the driver core to probe the Host bridge drivers only when all Root
> > > Port suppliers are available.
> > >
> > > Reported-by: Bjorn Andersson <andersson@kernel.org>
> > > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> > > ---
> >

100% NACK to this patch. You are touching a core part of the
fw_devlink code to fix it for one specific case. This is not the place
to special case for a property or a framework.

Please fix it on the PCI framework level please. Couple of options:
1. Revert the original patch causing the issue. The patch was from
Qualcomm and they didn't test it on their own devices?

2. PCI does this weird thing of setting the of_node of two different
devices to the same of_node. Now that you have this new node, I think
fixing that behavior to use different of_nodes for the two devices
might be a solution that might work here. I forget the technical terms
used in the PCI framework, but I think one was a the bus device and
the other was the root node.

3. Just create device links if you know you have a weird case of
dependency that fw_devlink doesn't pick up? It's generally more
painful to get fw_devlink to ignore what it thinks is a dependency,
but thankfully that's not the case here.

Please continue cc'ing me in future patches trying to address this.
I'm happy to give guidance if you get stuck.

-Saravana

> > [...]
> >
> > This is not 'required' in bindings and device_type="pci" doesn't uniquely
> > identify root complexes (as can be seen below).. but I suppose this is the
> > best delimiter we've got
> >
>
> Yeah. There is no way to uniquely identify the Host bridges in DT. So I had to
> settle for this.
>
> Maybe I can check for 'device_type', but that will create devlink between switch
> port supplies and Root Ports.
>
> > Perhaps it could be made 'required'?
> >
>
> Nah. Linux will generate domain numbers on its own. Also, this is a Linux
> specific property, so we cannot make it mandatory in dtschema.
>
> - Mani
>
> --
> மணிவண்ணன் சதாசிவம்
Re: [PATCH] of: property: Create devlink between PCI Host bridge and Root Port suppliers
Posted by Konrad Dybcio 3 days, 6 hours ago
On 2/5/26 9:50 AM, Konrad Dybcio wrote:
> On 2/5/26 8:06 AM, Manivannan Sadhasivam wrote:
>> In the recent times, devicetree started to represent the PCI Host bridge
>> supplies like PHY in the Root Port nodes as seen in commit 38fcbfbd4207
>> ("dt-bindings: PCI: qcom: Move PHY & reset GPIO to Root Port node"). But
>> the Host bridge drivers still need to control these supplies as a part of
>> their controller initialization/deinitialization sequence.
>>
>> So the Host bridge drivers end up parsing the Root Port supplies in their
>> probe() and controlled them. A downside to this approach is that the
>> devlink dependency between the suppliers and Host bridge is completely
>> broken. Due to this, the driver core probes the Host bridge drivers even if
>> the suppliers are not ready, causing probe deferrals and setup teardowns in
>> probe().
>>
>> These probe deferrals sometime happen over 1000 times (as reported in Qcom
>> Glymur platform) leading to a waste of CPU resources and increase in boot
>> time. So to fix these unnecessary deferrals, create devlink between the
>> Host bridge and Root Port suppliers in of_fwnode_add_links(). This will
>> allow the driver core to probe the Host bridge drivers only when all Root
>> Port suppliers are available.
>>
>> Reported-by: Bjorn Andersson <andersson@kernel.org>
>> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
>> ---
> 
> [...]
> 
> This is not 'required' in bindings and device_type="pci" doesn't uniquely
> identify root complexes (as can be seen below).. but I suppose this is the
> best delimiter we've got
> 
> Perhaps it could be made 'required'?

I cut out the line where it said:

if (of_property_present(con_np, "linux,pci-domain")) {

Konrad
> 
> Konrad
> 
>> +		for_each_available_child_of_node_scoped(con_np, child) {
>> +			if (of_node_is_type(child, "pci")) {
>> +				for_each_property_of_node(child, p)
>> +					of_link_property(child, con_np, p->name);
>> +			}
>> +		}
>> +	}
>>  
>>  	return 0;
>>  }