]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
PCI: imx6: Integrate new pwrctrl API
authorSherry Sun <sherry.sun@nxp.com>
Wed, 20 May 2026 08:48:57 +0000 (16:48 +0800)
committerManivannan Sadhasivam <mani@kernel.org>
Wed, 10 Jun 2026 13:41:15 +0000 (19:11 +0530)
Integrate the PCI pwrctrl framework into the pci-imx6 driver to provide
standardized power management for PCI devices.

Legacy regulator handling (vpcie-supply at controller level) is maintained
for backward compatibility with existing device trees. New device trees
should specify power supplies at the Root Port level to utilize the pwrctrl
framework.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260520084904.2424253-2-sherry.sun@oss.nxp.com
drivers/pci/controller/dwc/Kconfig
drivers/pci/controller/dwc/pci-imx6.c

index f2fde13107f2e4b9fee42be21a2d8c10f5b31541..327b0dc65550f2b75e31d696659b1aebfee4a088 100644 (file)
@@ -114,6 +114,7 @@ config PCI_IMX6_HOST
        depends on PCI_MSI
        select PCIE_DW_HOST
        select PCI_IMX6
+       select PCI_PWRCTRL_GENERIC
        help
          Enables support for the PCIe controller in the i.MX SoCs to
          work in Root Complex mode. The PCI controller on i.MX is based
index cce78a7a1624569a2c492290a99c898fde660596..63637fa5f10896b0f907a72842d00abbaed9d7d9 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/pci.h>
+#include <linux/pci-pwrctrl.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
@@ -1363,6 +1364,7 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
                        return ret;
        }
 
+       /* Legacy regulator handling for DT backward compatibility. */
        if (imx_pcie->vpcie) {
                ret = regulator_enable(imx_pcie->vpcie);
                if (ret) {
@@ -1372,10 +1374,22 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
                }
        }
 
+       ret = pci_pwrctrl_create_devices(dev);
+       if (ret) {
+               dev_err(dev, "failed to create pwrctrl devices\n");
+               goto err_reg_disable;
+       }
+
+       ret = pci_pwrctrl_power_on_devices(dev);
+       if (ret) {
+               dev_err(dev, "failed to power on pwrctrl devices\n");
+               goto err_pwrctrl_destroy;
+       }
+
        ret = imx_pcie_clk_enable(imx_pcie);
        if (ret) {
                dev_err(dev, "unable to enable pcie clocks: %d\n", ret);
-               goto err_reg_disable;
+               goto err_pwrctrl_power_off;
        }
 
        if (pp->bridge && imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT)) {
@@ -1437,6 +1451,11 @@ err_phy_exit:
        phy_exit(imx_pcie->phy);
 err_clk_disable:
        imx_pcie_clk_disable(imx_pcie);
+err_pwrctrl_power_off:
+       pci_pwrctrl_power_off_devices(dev);
+err_pwrctrl_destroy:
+       if (ret != -EPROBE_DEFER)
+               pci_pwrctrl_destroy_devices(dev);
 err_reg_disable:
        if (imx_pcie->vpcie)
                regulator_disable(imx_pcie->vpcie);
@@ -1455,6 +1474,7 @@ static void imx_pcie_host_exit(struct dw_pcie_rp *pp)
        }
        imx_pcie_clk_disable(imx_pcie);
 
+       pci_pwrctrl_power_off_devices(pci->dev);
        if (imx_pcie->vpcie)
                regulator_disable(imx_pcie->vpcie);
 }
@@ -1966,6 +1986,8 @@ static void imx_pcie_shutdown(struct platform_device *pdev)
        /* bring down link, so bootloader gets clean state in case of reboot */
        imx_pcie_assert_core_reset(imx_pcie);
        imx_pcie_assert_perst(imx_pcie, true);
+       pci_pwrctrl_power_off_devices(&pdev->dev);
+       pci_pwrctrl_destroy_devices(&pdev->dev);
 }
 
 static const struct imx_pcie_drvdata drvdata[] = {