summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-03-19 16:13:51 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-03-19 16:13:51 -0700
commit9b70771216558bffb329c2e69b2fd5fd71133e55 (patch)
treec53dae2ee362f8d94c96efe2a6857829cd49dd63
parenta1d9d8e833781c44ab688708804ce35f20f3cbbd (diff)
parent21647677ba9af2cb6bc460e17d9f29a7132c40c3 (diff)
Merge tag 'pci-v7.0-fixes-4' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci
Pull pci fixes from Bjorn Helgaas: - Create pwrctrl devices only for DT nodes below a PCI controller that describe PCI devices and are related to a power supply; this prevents waiting indefinitely for pwrctrl drivers that will never probe (Manivannan Sadhasivam) - Restore endpoint BAR mapping on subrange setup failure to make selftest reliable (Koichiro Den) * tag 'pci-v7.0-fixes-4' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci: PCI: endpoint: pci-epf-test: Roll back BAR mapping when subrange setup fails PCI/pwrctrl: Create pwrctrl devices only for PCI device nodes PCI/pwrctrl: Ensure that remote endpoint node parent has supply requirement
-rw-r--r--drivers/pci/endpoint/functions/pci-epf-test.c5
-rw-r--r--drivers/pci/pwrctrl/core.c54
2 files changed, 46 insertions, 13 deletions
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 582938b7b4f1..33548935765e 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -894,6 +894,11 @@ static void pci_epf_test_bar_subrange_setup(struct pci_epf_test *epf_test,
dev_err(&epf->dev, "pci_epc_set_bar() failed: %d\n", ret);
bar->submap = old_submap;
bar->num_submap = old_nsub;
+ ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no, bar);
+ if (ret)
+ dev_warn(&epf->dev, "Failed to restore the original BAR mapping: %d\n",
+ ret);
+
kfree(submap);
goto err;
}
diff --git a/drivers/pci/pwrctrl/core.c b/drivers/pci/pwrctrl/core.c
index 6f7dea6746e0..7754baed67f2 100644
--- a/drivers/pci/pwrctrl/core.c
+++ b/drivers/pci/pwrctrl/core.c
@@ -268,6 +268,46 @@ err_power_off:
}
EXPORT_SYMBOL_GPL(pci_pwrctrl_power_on_devices);
+/*
+ * Check whether the pwrctrl device really needs to be created or not. The
+ * pwrctrl device will only be created if the node satisfies below requirements:
+ *
+ * 1. Presence of compatible property with "pci" prefix to match against the
+ * pwrctrl driver (AND)
+ * 2. At least one of the power supplies defined in the devicetree node of the
+ * device (OR) in the remote endpoint parent node to indicate pwrctrl
+ * requirement.
+ */
+static bool pci_pwrctrl_is_required(struct device_node *np)
+{
+ struct device_node *endpoint;
+ const char *compat;
+ int ret;
+
+ ret = of_property_read_string(np, "compatible", &compat);
+ if (ret < 0)
+ return false;
+
+ if (!strstarts(compat, "pci"))
+ return false;
+
+ if (of_pci_supply_present(np))
+ return true;
+
+ if (of_graph_is_present(np)) {
+ for_each_endpoint_of_node(np, endpoint) {
+ struct device_node *remote __free(device_node) =
+ of_graph_get_remote_port_parent(endpoint);
+ if (remote) {
+ if (of_pci_supply_present(remote))
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
static int pci_pwrctrl_create_device(struct device_node *np,
struct device *parent)
{
@@ -287,19 +327,7 @@ static int pci_pwrctrl_create_device(struct device_node *np,
return 0;
}
- /*
- * Sanity check to make sure that the node has the compatible property
- * to allow driver binding.
- */
- if (!of_property_present(np, "compatible"))
- return 0;
-
- /*
- * Check whether the pwrctrl device really needs to be created or not.
- * This is decided based on at least one of the power supplies defined
- * in the devicetree node of the device or the graph property.
- */
- if (!of_pci_supply_present(np) && !of_graph_is_present(np)) {
+ if (!pci_pwrctrl_is_required(np)) {
dev_dbg(parent, "Skipping OF node: %s\n", np->name);
return 0;
}