Skip to contentSkip to conversation

lan966x pci device: Add support for SFPs, PCI part

PATCH Superseded Herve Codina 3 participants 20 messages Jun 30 – Jul 2

Subsystems (11)
Stable branch Sound ACPI PCI +7 more subsystems

v8 of 14 Superseded Latest is v14 →

lore
Share & tools
lore
#0 lore raw

v8 cover lan966x pci device: Add support for SFPs, PCI part

Hi,

Previously, I sent a big picture series adding support for SFP ports available on the LAN966x PCI device [0].

In this series patches touch several parts and sub-system in the kernel. Reviews have be done and it makes sense to split the series and send parts separately.

This current series is the extraction of patches related to issues in the PCI subsystem. It has to be seen as a continuation of the big picture series but related to this specific core part.

Patches 1 to 6 introduce and use fw_devlink_set_device() in already existing code. No functional change but the introduction of the fw_devlink_set_device() wrapper.

Patches 7 and 8 fix fw_devlink issues specific to PCI and the device-tree nodes created during enumeration.

[0] https://lore.kernel.org/all/[email protected]/

Best regards,
Hervé

Changes:

v7 -> v8
v7: https://lore.kernel.org/all/[email protected]/

Rebase on top of v7.2-rc1

- patches 4 and 5
Add 'Reviewed-by: Andy Shevchenko'

- Other Patches
No other changes

v6 -> v7

Rebase on top of v7.1-rc1

- Patch 1
Add Cc stable. Needed for patches 11 and 12

- Patches 2 to 5
No changes

- Patch 6
Add Cc stable. Needed for patch 13
Add 'Acked-by: Bjorn Helgaas'

- Patch 7
Fix a typo in commit log
Add Fixes tag + Cc stable
Add 'Acked-by: Bjorn Helgaas'

- Patch 8
Add Fixes tag + Cc stable
Add 'Acked-by: Bjorn Helgaas'

Older iterations:
Patches 6 to 13 in the big picture series
https://lore.kernel.org/all/[email protected]/

Herve Codina (8):
driver core: fw_devlink: Introduce fw_devlink_set_device()
drivers: core: Use fw_devlink_set_device()
pinctrl: cs42l43: Use fw_devlink_set_device()
cxl/test: Use device_set_node()
cxl/test: Use fw_devlink_set_device()
PCI: of: Use fw_devlink_set_device()
PCI: of: Set fwnode device of newly created PCI device nodes
PCI: of: Remove fwnode_dev_initialized() call for a PCI root bridge
node

 drivers/base/core.c                      |  4 ++--
 drivers/pci/of.c                         | 10 ++++++++--
 drivers/pinctrl/cirrus/pinctrl-cs42l43.c |  2 +-
 include/linux/fwnode.h                   |  6 ++++++
 tools/testing/cxl/test/cxl.c             |  4 ++--
 5 files changed, 19 insertions(+), 7 deletions(-)
Signature · 1 line
2.54.0
#1 lore raw

PATCH v8 1/8 driver core: fw_devlink: Introduce fw_devlink_set_device()

Setting fwnode->dev is specific to fw_devlink.

In order to avoid having a direct 'fwnode->dev = dev;' in several place in the kernel, introduce fw_devlink_set_device() helper to perform this operation.

Having this helper allows to hide the fwnode devlink related stuff behind the helper.

---
Cc stable because used by other patches with Fixes + Cc stable

---
 include/linux/fwnode.h | 6 ++++++
 1 file changed, 6 insertions(+)
include/linux/fwnode.h +6 -0
index 4e86e6990d28..31538f54b1ca 100644
@@ -256,4 +256,10 @@ void fw_devlink_purge_absent_suppliers(struct fwnode_handle *fwnode);
 void fw_devlink_refresh_fwnode(struct fwnode_handle *fwnode);
 bool fw_devlink_is_strict(void);
 
+static inline void fw_devlink_set_device(struct fwnode_handle *fwnode,
+					 struct device *dev)
+{
+	fwnode->dev = dev;
+}
+
 #endif
Signature · 1 line
2.54.0
#2 lore raw

Re: [PATCH v8 1/8] driver core: fw_devlink: Introduce fw_devlink_set_device()

Sashiko has reviewed this patch and found no issues. It looks great!
Quoted 11 lines

Setting fwnode->dev is specific to fw_devlink.

In order to avoid having a direct 'fwnode->dev = dev;' in several place in the kernel, introduce fw_devlink_set_device() helper to perform this operation.

Having this helper allows to hide the fwnode devlink related stuff behind the helper.

Sashiko has reviewed this patch and found no issues. It looks great!

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
#3 lore raw

PATCH v8 2/8 drivers: core: Use fw_devlink_set_device()

In reply to Herve Codina

The code set directly fwnode->dev field.

Use the dedicated fw_devlink_set_device() helper to perform this operation.

---
 drivers/base/core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/base/core.c +2 -2
index 4d026682944f..c205125344cf 100644
@@ -3750,7 +3750,7 @@ int device_add(struct device *dev)
 	 * device and the driver sync_state callback is called for this device.
 	 */
 	if (dev->fwnode && !dev->fwnode->dev) {
-		dev->fwnode->dev = dev;
+		fw_devlink_set_device(dev->fwnode, dev);
 		fw_devlink_link_device(dev);
 	}
 
@@ -3925,7 +3925,7 @@ void device_del(struct device *dev)
 	device_unlock(dev);
 
 	if (dev->fwnode && dev->fwnode->dev == dev)
-		dev->fwnode->dev = NULL;
+		fw_devlink_set_device(dev->fwnode, NULL);
 
 	/* Notify clients of device removal.  This call must come
 	 * before dpm_sysfs_remove().
Signature · 1 line
2.54.0
#4 lore raw

Re: [PATCH v8 2/8] drivers: core: Use fw_devlink_set_device()

Sashiko has reviewed this patch and found no issues. It looks great!
Quoted 6 lines

The code set directly fwnode->dev field.

Use the dedicated fw_devlink_set_device() helper to perform this operation.

Sashiko has reviewed this patch and found no issues. It looks great!

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
#5 lore raw

PATCH v8 3/8 pinctrl: cs42l43: Use fw_devlink_set_device()

In reply to Herve Codina

The code set directly fwnode->dev field.

Use the dedicated fw_devlink_set_device() helper to perform this operation.

---
 drivers/pinctrl/cirrus/pinctrl-cs42l43.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pinctrl/cirrus/pinctrl-cs42l43.c +1 -1
index 8990fab0446c..563070aba3d8 100644
@@ -576,7 +576,7 @@ static int cs42l43_pin_probe(struct platform_device *pdev)
 				return ret;
 
 			if (!child->dev)
-				child->dev = priv->dev;
+				fw_devlink_set_device(child, priv->dev);
 			fwnode = child;
 		}
 	}
Signature · 1 line
2.54.0
#6 lore raw

Re: [PATCH v8 3/8] pinctrl: cs42l43: Use fw_devlink_set_device()

Sashiko has reviewed this patch and found no issues. It looks great!
Quoted 6 lines

The code set directly fwnode->dev field.

Use the dedicated fw_devlink_set_device() helper to perform this operation.

Sashiko has reviewed this patch and found no issues. It looks great!

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=3
#7 lore raw

PATCH v8 4/8 cxl/test: Use device_set_node()

In reply to Herve Codina

The code set directly dev->fwnode.

Use the dedicated helper to perform this operation.

---
 tools/testing/cxl/test/cxl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/cxl/test/cxl.c +1 -1
index ef92dd35e030..69da0727362b 100644
@@ -1528,7 +1528,7 @@ static void mock_companion(struct acpi_device *adev, struct device *dev)
 {
 	device_initialize(&adev->dev);
 	fwnode_init(&adev->fwnode, NULL);
-	dev->fwnode = &adev->fwnode;
+	device_set_node(dev, &adev->fwnode);
 	adev->fwnode.dev = dev;
 }
 
Signature · 1 line
2.54.0
#8 lore raw

Re: [PATCH v8 4/8] cxl/test: Use device_set_node()

Sashiko has reviewed this patch and found no issues. It looks great!
Quoted 5 lines

The code set directly dev->fwnode.

Use the dedicated helper to perform this operation.

Sashiko has reviewed this patch and found no issues. It looks great!

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=4
#9 lore raw

PATCH v8 5/8 cxl/test: Use fw_devlink_set_device()

In reply to Herve Codina

The code set directly fwnode.dev field.

Use the dedicated fw_devlink_set_device() helper to perform this operation.

---
 tools/testing/cxl/test/cxl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/cxl/test/cxl.c +1 -1
index 69da0727362b..95e39dfc6ec9 100644
@@ -1529,7 +1529,7 @@ static void mock_companion(struct acpi_device *adev, struct device *dev)
 	device_initialize(&adev->dev);
 	fwnode_init(&adev->fwnode, NULL);
 	device_set_node(dev, &adev->fwnode);
-	adev->fwnode.dev = dev;
+	fw_devlink_set_device(&adev->fwnode, dev);
 }
 
 #ifndef SZ_64G
Signature · 1 line
2.54.0
#10 lore raw

Re: [PATCH v8 5/8] cxl/test: Use fw_devlink_set_device()

Sashiko has reviewed this patch and found no issues. It looks great!
Quoted 6 lines

The code set directly fwnode.dev field.

Use the dedicated fw_devlink_set_device() helper to perform this operation.

Sashiko has reviewed this patch and found no issues. It looks great!

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=5
#11 lore raw

PATCH v8 6/8 PCI: of: Use fw_devlink_set_device()

In reply to Herve Codina

The code set directly fwnode.dev field.

Use the dedicated fw_devlink_set_device() helper to perform this operation.

---
Cc stable because used by other patches with Fixes + Cc stable

---
 drivers/pci/of.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/of.c +1 -1
index 8b18c4ba845c..ee9eb384b377 100644
@@ -803,7 +803,7 @@ void of_pci_make_host_bridge_node(struct pci_host_bridge *bridge)
 	 * bus. Avoid any new device creation.
 	 */
 	of_node_set_flag(np, OF_POPULATED);
-	np->fwnode.dev = &bridge->dev;
+	fw_devlink_set_device(&np->fwnode, &bridge->dev);
 	fwnode_dev_initialized(&np->fwnode, true);
 
 	ret = of_changeset_apply(cset);
Signature · 1 line
2.54.0
#12 lore raw

Re: [PATCH v8 6/8] PCI: of: Use fw_devlink_set_device()

Sashiko has reviewed this patch and found no issues. It looks great!
Quoted 7 lines

The code set directly fwnode.dev field.

Use the dedicated fw_devlink_set_device() helper to perform this operation.

Sashiko has reviewed this patch and found no issues. It looks great!

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=6
#13 lore raw

PATCH v8 7/8 PCI: of: Set fwnode device of newly created PCI device nodes

In reply to Herve Codina

Device-tree node can be created when CONFIG_PCI_DYNAMIC_OF_NODES. Those nodes are created and filled based on PCI core information but the fwnode device field is not set.

When later an overlay is applied, this confuses fw_devlink. Indeed, without any device attached to the node, fw_devlink considers that this node will never become a device. When this node is pointed as a supplier, devlink looks at its ancestors in order to find a node with a device that could be used as the supplier.

In the PCI use case, this leads to links that wrongly use the PCI root bridge device as the supplier instead of the expected PCI device.

Setting the fwnode device to the device of the PCI device allows devlink to use this device as a supplier and so, correct links are created.

Fixes 407d1a51921e ("PCI: Create device tree node for bridge")
---
 drivers/pci/of.c | 7 +++++++
 1 file changed, 7 insertions(+)
drivers/pci/of.c +7 -0
index ee9eb384b377..eda14cefca5e 100644
@@ -709,6 +709,13 @@ void of_pci_make_dev_node(struct pci_dev *pdev)
 	if (ret)
 		goto out_free_node;
 
+	/*
+	 * Set the fwnode device in order to have fw_devlink creating links
+	 * pointing to this PCI device instead of walking up to the PCI host
+	 * bridge.
+	 */
+	fw_devlink_set_device(&np->fwnode, &pdev->dev);
+
 	ret = of_changeset_apply(cset);
 	if (ret)
 		goto out_free_node;
Signature · 1 line
2.54.0
#14 lore raw

Re: [PATCH v8 7/8] PCI: of: Set fwnode device of newly created PCI device nodes

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] Dangling `fwnode->dev` pointer leads to Use-After-Free during PCI device or host bridge removal. --

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Dangling fwnode->dev pointer leads to Use-After-Free during PCI device or host bridge removal. --

commit 282379de7d271ef07bfe62ea73e0c684092059cd
Author: Herve Codina <[email protected]>

PCI: of: Set fwnode device of newly created PCI device nodes

This commit sets the fwnode device field for dynamically created PCI device nodes. This ensures fw_devlink uses the correct PCI device as a supplier rather than walking up to the PCI root bridge device.

Quoted 5 lines
drivers/pci/of.c +0 -0
index ee9eb384b377a..eda14cefca5e7 100644

drivers/pci/of.c void of_pci_make_dev_node(struct pci_dev *pdev) · line 717

Quoted 9 lines
drivers/pci/of.c +6 -0
@@ -709,6 +709,13 @@ void of_pci_make_dev_node(struct pci_dev *pdev)
 	if (ret)
 		goto out_free_node;
 
+	/*
+	 * Set the fwnode device in order to have fw_devlink creating links
+	 * pointing to this PCI device instead of walking up to the PCI host
+	 * bridge.
+	 */
+	fw_devlink_set_device(&np->fwnode, &pdev->dev);

[Severity: High]
Could this leave a dangling pointer in np->fwnode.dev resulting in a use-after-free during device removal?

When of_pci_remove_node() is called during teardown, it executes device_remove_of_node(&pdev->dev) which clears pdev->dev.fwnode early.

When device_del() runs later, its standard cleanup logic relies on the fwnode pointer still being intact on the device:

    if (dev->fwnode && dev->fwnode->dev == dev)
        fw_devlink_set_device(dev->fwnode, NULL);

Since pdev->dev.fwnode is already NULL from the earlier call, this cleanup is bypassed. If any reference to the OF node is held after the PCI device is freed, np->fwnode.dev will still point to the freed pdev->dev structure.

Does of_pci_remove_node() (and similarly of_pci_remove_host_bridge_node()) need to manually call fw_devlink_set_device(&np->fwnode, NULL) to clear this safely before the node is removed?

Quoted 4 lines
drivers/pci/of.c +1 -0
+
 	ret = of_changeset_apply(cset);
 	if (ret)
 		goto out_free_node;
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=7
#15 lore raw

Re: [PATCH v8 7/8] PCI: of: Set fwnode device of newly created PCI device nodes

Quoted 2 lines · On Tue, Jun 30, 2026 at 11:23:33AM +0800, [email protected] wrote:

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Dangling fwnode->dev pointer leads to Use-After-Free during PCI device or host bridge removal.

Seems that sashiko also find the same issue.

--Richard

Quoted 55 lines

--

commit 282379de7d271ef07bfe62ea73e0c684092059cd
Author: Herve Codina <[email protected]>

PCI: of: Set fwnode device of newly created PCI device nodes

This commit sets the fwnode device field for dynamically created PCI device nodes. This ensures fw_devlink uses the correct PCI device as a supplier rather than walking up to the PCI root bridge device.

Quoted 5 lines
drivers/pci/of.c +0 -0
index ee9eb384b377a..eda14cefca5e7 100644

drivers/pci/of.c void of_pci_make_dev_node(struct pci_dev *pdev) · line 717

Quoted 9 lines
drivers/pci/of.c +6 -0
@@ -709,6 +709,13 @@ void of_pci_make_dev_node(struct pci_dev *pdev)
 	if (ret)
 		goto out_free_node;
 
+	/*
+	 * Set the fwnode device in order to have fw_devlink creating links
+	 * pointing to this PCI device instead of walking up to the PCI host
+	 * bridge.
+	 */
+	fw_devlink_set_device(&np->fwnode, &pdev->dev);

[Severity: High]
Could this leave a dangling pointer in np->fwnode.dev resulting in a use-after-free during device removal?

When of_pci_remove_node() is called during teardown, it executes device_remove_of_node(&pdev->dev) which clears pdev->dev.fwnode early.

When device_del() runs later, its standard cleanup logic relies on the fwnode pointer still being intact on the device:

    if (dev->fwnode && dev->fwnode->dev == dev)
        fw_devlink_set_device(dev->fwnode, NULL);

Since pdev->dev.fwnode is already NULL from the earlier call, this cleanup is bypassed. If any reference to the OF node is held after the PCI device is freed, np->fwnode.dev will still point to the freed pdev->dev structure.

Does of_pci_remove_node() (and similarly of_pci_remove_host_bridge_node()) need to manually call fw_devlink_set_device(&np->fwnode, NULL) to clear this safely before the node is removed?

Quoted 4 lines
drivers/pci/of.c +1 -0
+
 	ret = of_changeset_apply(cset);
 	if (ret)
 		goto out_free_node;
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=7
#16 lore raw

Re: [PATCH v8 7/8] PCI: of: Set fwnode device of newly created PCI device nodes

In reply to Herve Codina
Quoted 46 lines · Herve Codina

Device-tree node can be created when CONFIG_PCI_DYNAMIC_OF_NODES. Those nodes are created and filled based on PCI core information but the fwnode device field is not set.

When later an overlay is applied, this confuses fw_devlink. Indeed, without any device attached to the node, fw_devlink considers that this node will never become a device. When this node is pointed as a supplier, devlink looks at its ancestors in order to find a node with a device that could be used as the supplier.

In the PCI use case, this leads to links that wrongly use the PCI root bridge device as the supplier instead of the expected PCI device.

Setting the fwnode device to the device of the PCI device allows devlink to use this device as a supplier and so, correct links are created.

Fixes 407d1a51921e ("PCI: Create device tree node for bridge")
---
 drivers/pci/of.c | 7 +++++++
 1 file changed, 7 insertions(+)
drivers/pci/of.c +7 -0
index ee9eb384b377..eda14cefca5e 100644
@@ -709,6 +709,13 @@ void of_pci_make_dev_node(struct pci_dev *pdev)
 	if (ret)
 		goto out_free_node;
 
+	/*
+	 * Set the fwnode device in order to have fw_devlink creating links
+	 * pointing to this PCI device instead of walking up to the PCI host
+	 * bridge.
+	 */
+	fw_devlink_set_device(&np->fwnode, &pdev->dev);
+
 	ret = of_changeset_apply(cset);
 	if (ret)
 		goto out_free_node;
Signature · 1 line
2.54.0

Hi Herve,

I wonder if this part has some issue, it sets np->fwnode.dev = &pdev->dev, but I don't see am matching clear on removal path, I doubt the back-pointer can outlive the pci_dev.

device_del() do the check
"""
if (dev->fwnode && dev->fwnode->dev == dev)

    fw_devlink_set_device(dev->fwnode, NULL);

"""

On removal, pci_stop_dev() calls of_pci_remove_node() before pci_destroy_dev()
calls device_del(), and of_pci_remove_node() -> device_remove_of_node() has already NULLed pdev->dev.fwnode by then, so the "dev->fwnode" guard is false, and of_pci_remove_node() itself never clears np->fwnode.dev

If something holds an extra ref on np past removal, e.g. a DT overlay applied via configfs that pins np through its gragment targets, np survives, the pci_dev is freed, and np->fwnode.dev dnalges into freed memory.
Then fw_devlink walker that resolve it via get_dev_from_fwnode() -> get_device() would hit a use-after-free .

I think of_pci_remove_node() should cleaer the back-pointer it set, before dropping the node's ref, e.g.

"""
np = pci_device_to_OF_node(pdev);
if (!np || !of_node_check_flag(np, OF_DYNAMIC))

    return;

fw_devlink_set_device(&np->fwnode, NULL);
device_remove_of_node(&pdev->dev);
of_changeset_revert(np->data);
"""

Does that make sense to you ?

Best regards,
Richard Cheng.

#17 lore raw

Re: [PATCH v8 7/8] PCI: of: Set fwnode device of newly created PCI device nodes

Hi Richard,

Quoted 45 lines · On Thu, 2 Jul 2026 12:02:35 +0800 Richard Cheng <[email protected]> wrote:
Quoted 18 lines
drivers/pci/of.c +7 -0
@@ -709,6 +709,13 @@ void of_pci_make_dev_node(struct pci_dev *pdev)
 	if (ret)
 		goto out_free_node;
 
+	/*
+	 * Set the fwnode device in order to have fw_devlink creating links
+	 * pointing to this PCI device instead of walking up to the PCI host
+	 * bridge.
+	 */
+	fw_devlink_set_device(&np->fwnode, &pdev->dev);
+
 	ret = of_changeset_apply(cset);
 	if (ret)
 		goto out_free_node;
Signature · 1 line
2.54.0

Hi Herve,

I wonder if this part has some issue, it sets np->fwnode.dev = &pdev->dev, but I don't see am matching clear on removal path, I doubt the back-pointer can outlive the pci_dev.

device_del() do the check
"""
if (dev->fwnode && dev->fwnode->dev == dev)

    fw_devlink_set_device(dev->fwnode, NULL);

"""

On removal, pci_stop_dev() calls of_pci_remove_node() before pci_destroy_dev()
calls device_del(), and of_pci_remove_node() -> device_remove_of_node() has already NULLed pdev->dev.fwnode by then, so the "dev->fwnode" guard is false, and of_pci_remove_node() itself never clears np->fwnode.dev

If something holds an extra ref on np past removal, e.g. a DT overlay applied via configfs that pins np through its gragment targets, np survives, the pci_dev is freed, and np->fwnode.dev dnalges into freed memory.
Then fw_devlink walker that resolve it via get_dev_from_fwnode() -> get_device() would hit a use-after-free .

I think of_pci_remove_node() should cleaer the back-pointer it set, before dropping the node's ref, e.g.

"""
np = pci_device_to_OF_node(pdev);
if (!np || !of_node_check_flag(np, OF_DYNAMIC))

Quoted 9 lines
    return;

fw_devlink_set_device(&np->fwnode, NULL);
device_remove_of_node(&pdev->dev);
of_changeset_revert(np->data);
"""

Does that make sense to you ?

Thanks for pointed out this issue.

I am not sure that the scenario you proposed using configfs which can lead to the use-after-free is relevant but anyway this use-after-free is possible.

The fwnode->dev is set by of_pci_make_dev_node() and so it is consistent to unset it (set to NULL) in of_pci_remove_node().

I will update this patch to add the fw_devlink_set_device(&np->fwnode, NULL); call in the next iteration.

Also I will had a new patch in the next iteration to perform same operation for PCI root bridge. Same kind of code path, and so same issue but with of_pci_make_host_bridge_node() and of_pci_remove_host_bridge_node().

Best regards,
Hervé

#18 lore raw

PATCH v8 8/8 PCI: of: Remove fwnode_dev_initialized() call for a PCI root bridge node

In reply to Herve Codina

During the instantiation of devices described by a device-tree overlay applied on a PCI device, devlink displays the following kind of debug messages instead of creating the expected links:
'Not linking xxxx - might never become dev'

Without those expected links, the device removal order cannot be correct.

Those debug traces are printed by fw_devlink_create_devlink(). In our use case, they are all printed because the supplier of the link has at least one of its ancestor with its fwnode flag FWNODE_FLAG_INITIALIZED set.

The culprit ancestor is the PCI root bridge.

The fwnode related to the PCI root bridge is created dynamically by the of_pci_make_host_bridge_node() function. During this creation fwnode_dev_initialized() is called which set the FWNODE_FLAG_INITIALIZED flag.

Calling fwnode_dev_initialized() tells devlink that the device related to this node is handled out of the driver core. This is not correct in our case. Indeed the device related to this firmware node is handled using driver core mechanisms and is fully compliant devlink expectations.

Simply remove the fwnode_dev_initialized() call. With that done, the devlink debug messages are no more displayed and links that were missing are correctly created.

Fixes 1f340724419e ("PCI: of: Create device tree PCI host bridge node")
---
 drivers/pci/of.c | 1 -
 1 file changed, 1 deletion(-)
drivers/pci/of.c +0 -1
index eda14cefca5e..3e12f70fe538 100644
@@ -811,7 +811,6 @@ void of_pci_make_host_bridge_node(struct pci_host_bridge *bridge)
 	 */
 	of_node_set_flag(np, OF_POPULATED);
 	fw_devlink_set_device(&np->fwnode, &bridge->dev);
-	fwnode_dev_initialized(&np->fwnode, true);
 
 	ret = of_changeset_apply(cset);
 	if (ret)
Signature · 1 line
2.54.0
#19 lore raw

Re: [PATCH v8 8/8] PCI: of: Remove fwnode_dev_initialized() call for a PCI root bridge node

Sashiko has reviewed this patch and found no issues. It looks great!
Quoted 13 lines

During the instantiation of devices described by a device-tree overlay applied on a PCI device, devlink displays the following kind of debug messages instead of creating the expected links:
'Not linking xxxx - might never become dev'

Without those expected links, the device removal order cannot be correct.

Those debug traces are printed by fw_devlink_create_devlink(). In our use case, they are all printed because the supplier of the link has at least one of its ancestor with its fwnode flag FWNODE_FLAG_INITIALIZED set.

Quoted 8 lines

The culprit ancestor is the PCI root bridge.

[ ... ]
are correctly created.

Fixes 1f340724419e ("PCI: of: Create device tree PCI host bridge node")

Sashiko has reviewed this patch and found no issues. It looks great!

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=8