Message ID | 20240528-pwrseq-v8-13-d354d52b763c@linaro.org |
---|---|
State | New |
Headers | show |
Series | power: sequencing: implement the subsystem and add first users | expand |
On Tue, May 28, 2024 at 09:03:21PM +0200, Bartosz Golaszewski wrote: > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > > With PCI power control we deal with two struct device objects bound to > two different drivers but consuming the same OF node. We must not bind > the pinctrl twice. To that end: before setting the OF node of the newly > instantiated PCI device, check if a platform device consuming the same > OF node doesn't already exist on the platform bus and - if so - mark the > PCI device as reusing the OF node. > > Tested-by: Amit Pundir <amit.pundir@linaro.org> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> With s/reuse/Reuse/ in subject to match history, Acked-by: Bjorn Helgaas <bhelgaas@google.com> Would be good to get Rob's ack as well. > --- > drivers/pci/of.c | 14 ++++++++++---- > 1 file changed, 10 insertions(+), 4 deletions(-) > > diff --git a/drivers/pci/of.c b/drivers/pci/of.c > index 51e3dd0ea5ab..b908fe1ae951 100644 > --- a/drivers/pci/of.c > +++ b/drivers/pci/of.c > @@ -6,6 +6,7 @@ > */ > #define pr_fmt(fmt) "PCI: OF: " fmt > > +#include <linux/cleanup.h> > #include <linux/irqdomain.h> > #include <linux/kernel.h> > #include <linux/pci.h> > @@ -13,6 +14,7 @@ > #include <linux/of_irq.h> > #include <linux/of_address.h> > #include <linux/of_pci.h> > +#include <linux/platform_device.h> > #include "pci.h" > > #ifdef CONFIG_PCI > @@ -25,16 +27,20 @@ > */ > int pci_set_of_node(struct pci_dev *dev) > { > - struct device_node *node; > - > if (!dev->bus->dev.of_node) > return 0; > > - node = of_pci_find_child_device(dev->bus->dev.of_node, dev->devfn); > + struct device_node *node __free(device_node) = > + of_pci_find_child_device(dev->bus->dev.of_node, dev->devfn); > if (!node) > return 0; > > - device_set_node(&dev->dev, of_fwnode_handle(node)); > + struct device *pdev __free(put_device) = > + bus_find_device_by_of_node(&platform_bus_type, node); > + if (pdev) > + dev->bus->dev.of_node_reused = true; > + > + device_set_node(&dev->dev, of_fwnode_handle(no_free_ptr(node))); > return 0; > } > > > -- > 2.43.0 >
diff --git a/drivers/pci/of.c b/drivers/pci/of.c index 51e3dd0ea5ab..b908fe1ae951 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -6,6 +6,7 @@ */ #define pr_fmt(fmt) "PCI: OF: " fmt +#include <linux/cleanup.h> #include <linux/irqdomain.h> #include <linux/kernel.h> #include <linux/pci.h> @@ -13,6 +14,7 @@ #include <linux/of_irq.h> #include <linux/of_address.h> #include <linux/of_pci.h> +#include <linux/platform_device.h> #include "pci.h" #ifdef CONFIG_PCI @@ -25,16 +27,20 @@ */ int pci_set_of_node(struct pci_dev *dev) { - struct device_node *node; - if (!dev->bus->dev.of_node) return 0; - node = of_pci_find_child_device(dev->bus->dev.of_node, dev->devfn); + struct device_node *node __free(device_node) = + of_pci_find_child_device(dev->bus->dev.of_node, dev->devfn); if (!node) return 0; - device_set_node(&dev->dev, of_fwnode_handle(node)); + struct device *pdev __free(put_device) = + bus_find_device_by_of_node(&platform_bus_type, node); + if (pdev) + dev->bus->dev.of_node_reused = true; + + device_set_node(&dev->dev, of_fwnode_handle(no_free_ptr(node))); return 0; }