diff options
Diffstat (limited to 'drivers/pci/controller/cadence/pci-j721e.c')
| -rw-r--r-- | drivers/pci/controller/cadence/pci-j721e.c | 24 | 
1 files changed, 22 insertions, 2 deletions
| diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c index 849f1e416ea5..35e61048e133 100644 --- a/drivers/pci/controller/cadence/pci-j721e.c +++ b/drivers/pci/controller/cadence/pci-j721e.c @@ -1,11 +1,12 @@  // SPDX-License-Identifier: GPL-2.0 -/** +/*   * pci-j721e - PCIe controller driver for TI's J721E SoCs   *   * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com   * Author: Kishon Vijay Abraham I <kishon@ti.com>   */ +#include <linux/clk.h>  #include <linux/delay.h>  #include <linux/gpio/consumer.h>  #include <linux/io.h> @@ -50,6 +51,7 @@ enum link_status {  struct j721e_pcie {  	struct device		*dev; +	struct clk		*refclk;  	u32			mode;  	u32			num_lanes;  	struct cdns_pcie	*cdns_pcie; @@ -312,6 +314,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)  	struct cdns_pcie_ep *ep;  	struct gpio_desc *gpiod;  	void __iomem *base; +	struct clk *clk;  	u32 num_lanes;  	u32 mode;  	int ret; @@ -411,6 +414,20 @@ static int j721e_pcie_probe(struct platform_device *pdev)  			goto err_get_sync;  		} +		clk = devm_clk_get_optional(dev, "pcie_refclk"); +		if (IS_ERR(clk)) { +			ret = PTR_ERR(clk); +			dev_err(dev, "failed to get pcie_refclk\n"); +			goto err_pcie_setup; +		} + +		ret = clk_prepare_enable(clk); +		if (ret) { +			dev_err(dev, "failed to enable pcie_refclk\n"); +			goto err_get_sync; +		} +		pcie->refclk = clk; +  		/*  		 * "Power Sequencing and Reset Signal Timings" table in  		 * PCI EXPRESS CARD ELECTROMECHANICAL SPECIFICATION, REV. 3.0 @@ -425,8 +442,10 @@ static int j721e_pcie_probe(struct platform_device *pdev)  		}  		ret = cdns_pcie_host_setup(rc); -		if (ret < 0) +		if (ret < 0) { +			clk_disable_unprepare(pcie->refclk);  			goto err_pcie_setup; +		}  		break;  	case PCI_MODE_EP: @@ -479,6 +498,7 @@ static int j721e_pcie_remove(struct platform_device *pdev)  	struct cdns_pcie *cdns_pcie = pcie->cdns_pcie;  	struct device *dev = &pdev->dev; +	clk_disable_unprepare(pcie->refclk);  	cdns_pcie_disable_phy(cdns_pcie);  	pm_runtime_put(dev);  	pm_runtime_disable(dev); | 
