Skip to content

Commit

Permalink
PCI/pwrctl: Create pwrctl device only if at least one power supply is…
Browse files Browse the repository at this point in the history
… 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: 8fb1861 ("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>
[kwilczynski: drop the NULL check in of_pci_is_supply_present()]
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
[bhelgaas: rename of_pci_is_supply_present() to of_pci_supply_present() for
readability]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Cc: stable+noautosel@kernel.org		# Depends on of_platform_device_create() rework
  • Loading branch information
Mani-Sadhasivam authored and bjorn-helgaas committed Nov 20, 2024
1 parent 68374ed commit 30ccf07
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 0 deletions.
11 changes: 11 additions & 0 deletions drivers/pci/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,17 @@ void pci_bus_add_device(struct pci_dev *dev)

if (dev_of_node(&dev->dev) && pci_is_bridge(dev)) {
for_each_available_child_of_node_scoped(dn, child) {
/*
* First check whether the pwrctl device needs to be
* created or not. This is decided based on at least
* one of the power supplies being defined in the
* devicetree node of the device.
*/
if (!of_pci_supply_present(child)) {
pci_dbg(dev, "skipping OF node: %s\n", child->name);
continue;
}

pdev = of_platform_device_create(child, NULL, &dev->dev);
if (!pdev)
pci_err(dev, "failed to create OF node: %s\n", child->name);
Expand Down
24 changes: 24 additions & 0 deletions drivers/pci/of.c
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,30 @@ void of_pci_make_dev_node(struct pci_dev *pdev)
}
#endif

/**
* of_pci_supply_present() - Check if the power supply is present for the PCI
* device
* @np: Device tree node
*
* Check if the power supply for the PCI device is present in the device tree
* node or not.
*
* Return: true if at least one power supply exists; false otherwise.
*/
bool of_pci_supply_present(struct device_node *np)
{
struct property *prop;
char *supply;

for_each_property_of_node(np, prop) {
supply = strrchr(prop->name, '-');
if (supply && !strcmp(supply, "-supply"))
return true;
}

return false;
}

#endif /* CONFIG_PCI */

/**
Expand Down
5 changes: 5 additions & 0 deletions drivers/pci/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,7 @@ void pci_set_bus_of_node(struct pci_bus *bus);
void pci_release_bus_of_node(struct pci_bus *bus);

int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge *bridge);
bool of_pci_supply_present(struct device_node *np);

#else
static inline int
Expand Down Expand Up @@ -793,6 +794,10 @@ static inline int devm_of_pci_bridge_init(struct device *dev, struct pci_host_br
return 0;
}

static inline bool of_pci_supply_present(struct device_node *np)
{
return false;
}
#endif /* CONFIG_OF */

struct of_changeset;
Expand Down

0 comments on commit 30ccf07

Please sign in to comment.