[PATCH 4/6] PCI: tegra264: Power endpoint devices before enumeration

From: Mikko Perttunen

Date: Wed Oct 28 2026 - 23:37:46 EST


Add calls into the PCI pwrctrl framework to do required power sequencing
for endpoint devices before attempting to enumerate them, and select
PCI_PWRCTRL_GENERIC in Kconfig.

This is required for the integrated GB10B GPU on Tegra264 that requires
a power domain to be enabled before it appears on the PCI bus.

Signed-off-by: Mikko Perttunen <mperttunen@xxxxxxxxxx>
---
drivers/pci/controller/Kconfig | 1 +
drivers/pci/controller/pcie-tegra264.c | 22 ++++++++++++++++++++--
2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index d246bbe37948..ab8cb1be28ba 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -261,6 +261,7 @@ config PCIE_TEGRA264
tristate "NVIDIA Tegra264 PCIe controller"
depends on ARCH_TEGRA || COMPILE_TEST
select PCI_ECAM
+ select PCI_PWRCTRL_GENERIC
help
Say Y here if you want support for the PCIe Host Controller found
on NVIDIA Tegra264 SoCs.
diff --git a/drivers/pci/controller/pcie-tegra264.c b/drivers/pci/controller/pcie-tegra264.c
index c97576ab4a31..1d65ed5d0381 100644
--- a/drivers/pci/controller/pcie-tegra264.c
+++ b/drivers/pci/controller/pcie-tegra264.c
@@ -17,6 +17,7 @@
#include <linux/of_pci.h>
#include <linux/of_platform.h>
#include <linux/pci-ecam.h>
+#include <linux/pci-pwrctrl.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -391,6 +392,14 @@ static int tegra264_pcie_probe(struct platform_device *pdev)
bridge->sysdata = pcie->cfg;
pcie->ecam = pcie->cfg->win;

+ err = pci_pwrctrl_create_devices(dev);
+ if (err)
+ goto err_free_ecam;
+
+ err = pci_pwrctrl_power_on_devices(dev);
+ if (err)
+ goto err_destroy_pwrctrl;
+
tegra264_pcie_init(pcie);

/*
@@ -402,17 +411,23 @@ static int tegra264_pcie_probe(struct platform_device *pdev)
"PCIe #%u link is down and not hotplug-capable, turning off\n",
pcie->ctl_id);
tegra264_pcie_power_off(pcie);
- goto err_free_ecam;
+ goto err_power_off;
}

err = pci_host_probe(bridge);
if (err < 0) {
dev_err_probe(dev, err, "failed to register Host Bridge\n");
- goto err_free_ecam;
+ goto err_power_off;
}

return 0;

+err_power_off:
+ pci_pwrctrl_power_off_devices(dev);
+err_destroy_pwrctrl:
+ /* Keep devices registered so their drivers can bind before we retry. */
+ if (err != -EPROBE_DEFER)
+ pci_pwrctrl_destroy_devices(dev);
err_free_ecam:
pci_ecam_free(pcie->cfg);
err_put_pm:
@@ -437,6 +452,9 @@ static void tegra264_pcie_remove(struct platform_device *pdev)
pci_remove_root_bus(pcie->bridge->bus);
pci_unlock_rescan_remove();

+ pci_pwrctrl_power_off_devices(&pdev->dev);
+ pci_pwrctrl_destroy_devices(&pdev->dev);
+
pm_runtime_put_sync(&pdev->dev);
tegra_bpmp_put(pcie->bpmp);
pci_ecam_free(pcie->cfg);

--
2.55.0