Skip to content

Commit f153658

Browse files
Bartosz Golaszewskibjorn-helgaas
authored andcommitted
PCI: Don't rely on of_platform_depopulate() for reused OF-nodes
of_platform_depopulate() doesn't play nicely with reused OF nodes - it ignores the ones that are not marked explicitly as populated and it may happen that the PCI device goes away before the platform device in which case the PCI core clears the OF_POPULATED bit. Unconditionally unregister the platform devices for child nodes when stopping the PCI device. Link: https://lore.kernel.org/r/[email protected] Fixes: 8fb1861 ("PCI/pwrctl: Create platform devices for child OF nodes of the port node") Signed-off-by: Bartosz Golaszewski <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]> Acked-by: Manivannan Sadhasivam <[email protected]>
1 parent 8400291 commit f153658

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

drivers/pci/remove.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
// SPDX-License-Identifier: GPL-2.0
22
#include <linux/pci.h>
33
#include <linux/module.h>
4+
#include <linux/of.h>
45
#include <linux/of_platform.h>
6+
#include <linux/platform_device.h>
7+
58
#include "pci.h"
69

710
static void pci_free_resources(struct pci_dev *dev)
@@ -14,12 +17,25 @@ static void pci_free_resources(struct pci_dev *dev)
1417
}
1518
}
1619

20+
static int pci_pwrctl_unregister(struct device *dev, void *data)
21+
{
22+
struct device_node *pci_node = data, *plat_node = dev_of_node(dev);
23+
24+
if (dev_is_platform(dev) && plat_node && plat_node == pci_node) {
25+
of_device_unregister(to_platform_device(dev));
26+
of_node_clear_flag(plat_node, OF_POPULATED);
27+
}
28+
29+
return 0;
30+
}
31+
1732
static void pci_stop_dev(struct pci_dev *dev)
1833
{
1934
pci_pme_active(dev, false);
2035

2136
if (pci_dev_is_added(dev)) {
22-
of_platform_depopulate(&dev->dev);
37+
device_for_each_child(dev->dev.parent, dev_of_node(&dev->dev),
38+
pci_pwrctl_unregister);
2339
device_release_driver(&dev->dev);
2440
pci_proc_detach_device(dev);
2541
pci_remove_sysfs_dev_files(dev);

0 commit comments

Comments
 (0)