Commit 1056dda8 authored by Manikanta Maddireddy's avatar Manikanta Maddireddy Committed by Lorenzo Pieralisi
Browse files

PCI: tegra: Handle failure cases in tegra_pcie_power_on()



Unroll the PCIe power on sequence if any one of the steps fails in
tegra_pcie_power_on().

Signed-off-by: default avatarManikanta Maddireddy <mmaddireddy@nvidia.com>
Signed-off-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: default avatarThierry Reding <treding@nvidia.com>
parent e3b09c18
Loading
Loading
Loading
Loading
+21 −5
Original line number Diff line number Diff line
@@ -1052,7 +1052,7 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
		err = clk_prepare_enable(pcie->pex_clk);
		if (err) {
			dev_err(dev, "failed to enable PEX clock: %d\n", err);
			return err;
			goto regulator_disable;
		}
		reset_control_deassert(pcie->pex_rst);
	} else {
@@ -1061,7 +1061,7 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
							pcie->pex_rst);
		if (err) {
			dev_err(dev, "powerup sequence failed: %d\n", err);
			return err;
			goto regulator_disable;
		}
	}

@@ -1070,24 +1070,40 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
	err = clk_prepare_enable(pcie->afi_clk);
	if (err < 0) {
		dev_err(dev, "failed to enable AFI clock: %d\n", err);
		return err;
		goto powergate;
	}

	if (soc->has_cml_clk) {
		err = clk_prepare_enable(pcie->cml_clk);
		if (err < 0) {
			dev_err(dev, "failed to enable CML clock: %d\n", err);
			return err;
			goto disable_afi_clk;
		}
	}

	err = clk_prepare_enable(pcie->pll_e);
	if (err < 0) {
		dev_err(dev, "failed to enable PLLE clock: %d\n", err);
		return err;
		goto disable_cml_clk;
	}

	return 0;

disable_cml_clk:
	if (soc->has_cml_clk)
		clk_disable_unprepare(pcie->cml_clk);
disable_afi_clk:
	clk_disable_unprepare(pcie->afi_clk);
powergate:
	reset_control_assert(pcie->afi_rst);
	reset_control_assert(pcie->pex_rst);
	clk_disable_unprepare(pcie->pex_clk);
	if (!dev->pm_domain)
		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
regulator_disable:
	regulator_bulk_disable(pcie->num_supplies, pcie->supplies);

	return err;
}

static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)