On Thu, Nov 30, 2023 at 05:56:59PM +0100, Herve Codina wrote:
The commit 407d1a51921e ("PCI: Create device tree node for bridge") creates of_node for PCI devices. During the insertion handling of these new DT nodes done by of_platform, new devices (struct device) are created. For each PCI devices a struct device is already present (created and handled by the PCI core). Having a second struct device to represent the exact same PCI device is not correct.
Can you rewrap this or, if you intend multiple paragraphs, add blank lines between them?
On the of_node creation, tell the of_platform that there is no need to create a device for this node (OF_POPULATED flag), link this newly created of_node to the already present device and tell fwnode that the device attached to this of_node is ready (fwnode_dev_initialized()).
With this fix, the of_node are available in the sysfs device tree: /sys/devices/platform/soc/d0070000.pcie/
- of_node -> .../devicetree/base/soc/pcie@d0070000
- pci0000:00
- 0000:00:00.0
- of_node -> .../devicetree/base/soc/pcie@d0070000/pci@0,0
- 0000:01:00.0
- of_node -> .../devicetree/base/soc/pcie@d0070000/pci@0,0/dev@0,0
On the of_node removal, revert the operations.
Fixes: 407d1a51921e ("PCI: Create device tree node for bridge") Cc: stable@vger.kernel.org Signed-off-by: Herve Codina herve.codina@bootlin.com
drivers/pci/of.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/of.c b/drivers/pci/of.c index 51e3dd0ea5ab..5afd2731e876 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -615,7 +615,8 @@ void of_pci_remove_node(struct pci_dev *pdev) np = pci_device_to_OF_node(pdev); if (!np || !of_node_check_flag(np, OF_DYNAMIC)) return;
- pdev->dev.of_node = NULL;
- device_remove_of_node(&pdev->dev);
of_changeset_revert(np->data); of_changeset_destroy(np->data); @@ -668,12 +669,22 @@ void of_pci_make_dev_node(struct pci_dev *pdev) if (ret) goto out_free_node;
- /*
* This of_node will be added to an existing device.
* Avoid any device creation and use the existing device
*/
- of_node_set_flag(np, OF_POPULATED);
- np->fwnode.dev = &pdev->dev;
- fwnode_dev_initialized(&np->fwnode, true);
- ret = of_changeset_apply(cset); if (ret) goto out_free_node;
np->data = cset;
- pdev->dev.of_node = np;
- /* Add the of_node to the existing device */
- device_add_of_node(&pdev->dev, np); kfree(name);
return; -- 2.42.0