summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
authorRichard Zhu <hongxing.zhu@nxp.com>2022-07-14 10:31:09 +0300
committerBjorn Helgaas <bhelgaas@google.com>2022-08-01 23:34:09 +0300
commit835a345b18b013cc03b0fc392394fbccd61d4efb (patch)
tree41f160778536d4fbb90c4d3f5b04c92f7c8de25d /drivers/pci
parent1c5e761565c10945049e5d52fb17540cda23690e (diff)
downloadlinux-835a345b18b013cc03b0fc392394fbccd61d4efb.tar.xz
PCI: imx6: Reformat suspend callback to keep symmetric with resume
Create imx6_pcie_stop_link() and imx6_pcie_host_exit() functions. Encapsulate clocks, regulators disables and PHY uninitialization into imx6_pcie_host_exit(). To keep suspend/resume symmetric as much as possible, invoke these two new created functions in suspend callback. To be symmetric with imx6_pcie_host_exit(), move imx6_pcie_clk_enable() to imx6_pcie_host_init() from imx6_pcie_deassert_core_reset(). Link: https://lore.kernel.org/r/1657783869-19194-18-git-send-email-hongxing.zhu@nxp.com Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/controller/dwc/pci-imx6.c62
1 files changed, 37 insertions, 25 deletions
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 1f5347bd694b..81ab6ddb0d59 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -703,13 +703,6 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
{
struct dw_pcie *pci = imx6_pcie->pci;
struct device *dev = pci->dev;
- int ret;
-
- ret = imx6_pcie_clk_enable(imx6_pcie);
- if (ret) {
- dev_err(dev, "unable to enable pcie clocks: %d\n", ret);
- return ret;
- }
switch (imx6_pcie->drvdata->variant) {
case IMX8MQ:
@@ -904,6 +897,14 @@ err_reset_phy:
return 0;
}
+static void imx6_pcie_stop_link(struct dw_pcie *pci)
+{
+ struct device *dev = pci->dev;
+
+ /* Turn off PCIe LTSSM */
+ imx6_pcie_ltssm_disable(dev);
+}
+
static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -923,11 +924,17 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
imx6_pcie_assert_core_reset(imx6_pcie);
imx6_pcie_init_phy(imx6_pcie);
+ ret = imx6_pcie_clk_enable(imx6_pcie);
+ if (ret) {
+ dev_err(dev, "unable to enable pcie clocks: %d\n", ret);
+ goto err_reg_disable;
+ }
+
if (imx6_pcie->phy) {
ret = phy_power_on(imx6_pcie->phy);
if (ret) {
dev_err(dev, "pcie PHY power up failed\n");
- goto err_reg_disable;
+ goto err_clk_disable;
}
}
@@ -941,24 +948,40 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
ret = phy_init(imx6_pcie->phy);
if (ret) {
dev_err(dev, "waiting for PHY ready timeout!\n");
- goto err_clk_disable;
+ goto err_phy_off;
}
}
imx6_setup_phy_mpll(imx6_pcie);
return 0;
-err_clk_disable:
- imx6_pcie_clk_disable(imx6_pcie);
err_phy_off:
if (imx6_pcie->phy)
phy_power_off(imx6_pcie->phy);
+err_clk_disable:
+ imx6_pcie_clk_disable(imx6_pcie);
err_reg_disable:
if (imx6_pcie->vpcie)
regulator_disable(imx6_pcie->vpcie);
return ret;
}
+static void imx6_pcie_host_exit(struct dw_pcie_rp *pp)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
+
+ if (imx6_pcie->phy) {
+ if (phy_power_off(imx6_pcie->phy))
+ dev_err(pci->dev, "unable to power off PHY\n");
+ phy_exit(imx6_pcie->phy);
+ }
+ imx6_pcie_clk_disable(imx6_pcie);
+
+ if (imx6_pcie->vpcie)
+ regulator_disable(imx6_pcie->vpcie);
+}
+
static const struct dw_pcie_host_ops imx6_pcie_host_ops = {
.host_init = imx6_pcie_host_init,
};
@@ -1007,25 +1030,14 @@ pm_turnoff_sleep:
static int imx6_pcie_suspend_noirq(struct device *dev)
{
struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
+ struct dw_pcie_rp *pp = &imx6_pcie->pci->pp;
if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_SUPPORTS_SUSPEND))
return 0;
imx6_pcie_pm_turnoff(imx6_pcie);
- imx6_pcie_ltssm_disable(dev);
- imx6_pcie_clk_disable(imx6_pcie);
- switch (imx6_pcie->drvdata->variant) {
- case IMX8MM:
- if (phy_power_off(imx6_pcie->phy))
- dev_err(dev, "unable to power off PHY\n");
- phy_exit(imx6_pcie->phy);
- break;
- default:
- break;
- }
-
- if (imx6_pcie->vpcie)
- regulator_disable(imx6_pcie->vpcie);
+ imx6_pcie_stop_link(imx6_pcie->pci);
+ imx6_pcie_host_exit(pp);
return 0;
}