]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
PCI: histb: Add an optional regulator for PCIe port power control
authorShawn Guo <shawn.guo@linaro.org>
Fri, 2 Mar 2018 01:12:01 +0000 (09:12 +0800)
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Wed, 7 Mar 2018 16:24:27 +0000 (16:24 +0000)
The power supplies to PCIe port are often controlled by GPIO on some board
designs.  Let's add an optional regulator which can be backed by GPIO to
control the power.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Rob Herring <robh@kernel.org>
Documentation/devicetree/bindings/pci/hisilicon-histb-pcie.txt
drivers/pci/dwc/pcie-histb.c

index c84bc027930b903bfaa3413f00daff061f39c366..760b4d7406162ddb45f922d0777fbde962d08d72 100644 (file)
@@ -34,6 +34,7 @@ Required properties
 
 Optional properties:
 - reset-gpios: The gpio to generate PCIe PERST# assert and deassert signal.
+- vpcie-supply: The regulator in charge of PCIe port power.
 - phys: List of phandle and phy mode specifier, should be 0.
 - phy-names: Must be "phy".
 
index 17ed604f57410c45e08fcc0785d3d557cd0dbd0d..4cef0a5149442242e95844c0db9662b4f2c45444 100644 (file)
@@ -61,6 +61,7 @@ struct histb_pcie {
        struct reset_control *bus_reset;
        void __iomem *ctrl;
        int reset_gpio;
+       struct regulator *vpcie;
 };
 
 static u32 histb_pcie_readl(struct histb_pcie *histb_pcie, u32 reg)
@@ -227,6 +228,9 @@ static void histb_pcie_host_disable(struct histb_pcie *hipcie)
 
        if (gpio_is_valid(hipcie->reset_gpio))
                gpio_set_value_cansleep(hipcie->reset_gpio, 0);
+
+       if (hipcie->vpcie)
+               regulator_disable(hipcie->vpcie);
 }
 
 static int histb_pcie_host_enable(struct pcie_port *pp)
@@ -237,6 +241,14 @@ static int histb_pcie_host_enable(struct pcie_port *pp)
        int ret;
 
        /* power on PCIe device if have */
+       if (hipcie->vpcie) {
+               ret = regulator_enable(hipcie->vpcie);
+               if (ret) {
+                       dev_err(dev, "failed to enable regulator: %d\n", ret);
+                       return ret;
+               }
+       }
+
        if (gpio_is_valid(hipcie->reset_gpio))
                gpio_set_value_cansleep(hipcie->reset_gpio, 1);
 
@@ -282,6 +294,8 @@ static int histb_pcie_host_enable(struct pcie_port *pp)
 err_sys_clk:
        clk_disable_unprepare(hipcie->bus_clk);
 err_bus_clk:
+       if (hipcie->vpcie)
+               regulator_disable(hipcie->vpcie);
 
        return ret;
 }
@@ -331,6 +345,13 @@ static int histb_pcie_probe(struct platform_device *pdev)
                return PTR_ERR(pci->dbi_base);
        }
 
+       hipcie->vpcie = devm_regulator_get_optional(dev, "vpcie");
+       if (IS_ERR(hipcie->vpcie)) {
+               if (PTR_ERR(hipcie->vpcie) == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+               hipcie->vpcie = NULL;
+       }
+
        hipcie->reset_gpio = of_get_named_gpio_flags(np,
                                "reset-gpios", 0, &of_flags);
        if (of_flags & OF_GPIO_ACTIVE_LOW)