Commit 23a43cc4 authored by Diogo Ivo's avatar Diogo Ivo Committed by Thierry Reding
Browse files

clk: tegra: Add missing reset deassertion



Commit 4782c0a5 ("clk: tegra: Don't deassert reset on enabling
clocks") removed deassertion of reset lines when enabling peripheral
clocks. This breaks the initialization of the DFLL driver which relied
on this behaviour.

Fix this problem by adding explicit deassert/assert requests to the
driver. Tested on Google Pixel C.

Cc: stable@vger.kernel.org
Fixes: 4782c0a5 ("clk: tegra: Don't deassert reset on enabling clocks")
Signed-off-by: default avatarDiogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent 31231092
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -271,6 +271,7 @@ struct tegra_dfll {
	struct clk			*ref_clk;
	struct clk			*i2c_clk;
	struct clk			*dfll_clk;
	struct reset_control		*dfll_rst;
	struct reset_control		*dvco_rst;
	unsigned long			ref_rate;
	unsigned long			i2c_clk_rate;
@@ -1464,6 +1465,7 @@ static int dfll_init(struct tegra_dfll *td)
		return -EINVAL;
	}

	reset_control_deassert(td->dfll_rst);
	reset_control_deassert(td->dvco_rst);

	ret = clk_prepare(td->ref_clk);
@@ -1509,6 +1511,7 @@ static int dfll_init(struct tegra_dfll *td)
	clk_unprepare(td->ref_clk);

	reset_control_assert(td->dvco_rst);
	reset_control_assert(td->dfll_rst);

	return ret;
}
@@ -1530,6 +1533,7 @@ int tegra_dfll_suspend(struct device *dev)
	}

	reset_control_assert(td->dvco_rst);
	reset_control_assert(td->dfll_rst);

	return 0;
}
@@ -1548,6 +1552,7 @@ int tegra_dfll_resume(struct device *dev)
{
	struct tegra_dfll *td = dev_get_drvdata(dev);

	reset_control_deassert(td->dfll_rst);
	reset_control_deassert(td->dvco_rst);

	pm_runtime_get_sync(td->dev);
@@ -1951,6 +1956,12 @@ int tegra_dfll_register(struct platform_device *pdev,

	td->soc = soc;

	td->dfll_rst = devm_reset_control_get_optional(td->dev, "dfll");
	if (IS_ERR(td->dfll_rst)) {
		dev_err(td->dev, "couldn't get dfll reset\n");
		return PTR_ERR(td->dfll_rst);
	}

	td->dvco_rst = devm_reset_control_get(td->dev, "dvco");
	if (IS_ERR(td->dvco_rst)) {
		dev_err(td->dev, "couldn't get dvco reset\n");
@@ -2087,6 +2098,7 @@ struct tegra_dfll_soc_data *tegra_dfll_unregister(struct platform_device *pdev)
	clk_unprepare(td->i2c_clk);

	reset_control_assert(td->dvco_rst);
	reset_control_assert(td->dfll_rst);

	return td->soc;
}