Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI/pwrctl: Create pwrctl device only if at least one power supply is present

Currently, pwrctl devices are created if the corresponding PCI nodes are
defined in devicetree. But this is not correct, because not all PCI nodes
require pwrctl support. Pwrctl comes into the picture only when the device
requires kernel to manage its power state. This can be determined using the
power supply properties present in the devicetree node of the device.

Add of_pci_supply_present() to check whether the devicetree contains at
least one power supply property for a device. If one is present, create a
pwrctl device for that PCI node.

Suggested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Fixes: 8fb18619d910 ("PCI/pwrctl: Create platform devices for child OF nodes of the port node")
Link: https://lore.kernel.org/r/20241025-pci-pwrctl-rework-v2-2-568756156cbe@linaro.org
Tested-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Tested-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
[bhelgaas: rename of_pci_is_supply_present() to of_pci_supply_present() for
readability]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Cc: stable+noautosel@kernel.org # Depends on of_platform_device_create() rework

authored by

Manivannan Sadhasivam and committed by
Krzysztof Wilczyński
278dd091 7582fe07

+43
+11
drivers/pci/bus.c
··· 354 354 355 355 if (dev_of_node(&dev->dev) && pci_is_bridge(dev)) { 356 356 for_each_available_child_of_node_scoped(dn, child) { 357 + /* 358 + * First check whether the pwrctl device needs to be 359 + * created or not. This is decided based on at least 360 + * one of the power supplies being defined in the 361 + * devicetree node of the device. 362 + */ 363 + if (!of_pci_supply_present(child)) { 364 + pci_dbg(dev, "skipping OF node: %s\n", child->name); 365 + continue; 366 + } 367 + 357 368 pdev = of_platform_device_create(child, NULL, &dev->dev); 358 369 if (!pdev) 359 370 pci_err(dev, "failed to create OF node: %s\n", child->name);
+27
drivers/pci/of.c
··· 728 728 } 729 729 #endif 730 730 731 + /** 732 + * of_pci_supply_present() - Check if the power supply is present for the PCI 733 + * device 734 + * @np: Device tree node 735 + * 736 + * Check if the power supply for the PCI device is present in the device tree 737 + * node or not. 738 + * 739 + * Return: true if at least one power supply exists; false otherwise. 740 + */ 741 + bool of_pci_supply_present(struct device_node *np) 742 + { 743 + struct property *prop; 744 + char *supply; 745 + 746 + if (!np) 747 + return false; 748 + 749 + for_each_property_of_node(np, prop) { 750 + supply = strrchr(prop->name, '-'); 751 + if (supply && !strcmp(supply, "-supply")) 752 + return true; 753 + } 754 + 755 + return false; 756 + } 757 + 731 758 #endif /* CONFIG_PCI */ 732 759 733 760 /**
+5
drivers/pci/pci.h
··· 746 746 void pci_release_bus_of_node(struct pci_bus *bus); 747 747 748 748 int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge *bridge); 749 + bool of_pci_supply_present(struct device_node *np); 749 750 750 751 #else 751 752 static inline int ··· 794 793 return 0; 795 794 } 796 795 796 + static inline bool of_pci_supply_present(struct device_node *np) 797 + { 798 + return false; 799 + } 797 800 #endif /* CONFIG_OF */ 798 801 799 802 struct of_changeset;