Commit 11c632e1 authored by Thierry Reding's avatar Thierry Reding

drm/tegra: sor: Implement acquire/release for reset

By implementing the acquire/release protocol, the SOR reset can be
shared with other drivers that also adhere to this protocol, such as the
PMC driver that uses the same reset as part of the powergate and -ungate
implementation using generic power domains.

Runtime PM makes sure that the operations are executed in the right
order, and the reset core has error handling and WARNs in place to make
sure the acquire/release protocol is followed.
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent ee222c5d
...@@ -2871,6 +2871,13 @@ static int tegra_sor_init(struct host1x_client *client) ...@@ -2871,6 +2871,13 @@ static int tegra_sor_init(struct host1x_client *client)
* kernel is possible. * kernel is possible.
*/ */
if (sor->rst) { if (sor->rst) {
err = reset_control_acquire(sor->rst);
if (err < 0) {
dev_err(sor->dev, "failed to acquire SOR reset: %d\n",
err);
return err;
}
err = reset_control_assert(sor->rst); err = reset_control_assert(sor->rst);
if (err < 0) { if (err < 0) {
dev_err(sor->dev, "failed to assert SOR reset: %d\n", dev_err(sor->dev, "failed to assert SOR reset: %d\n",
...@@ -2894,6 +2901,8 @@ static int tegra_sor_init(struct host1x_client *client) ...@@ -2894,6 +2901,8 @@ static int tegra_sor_init(struct host1x_client *client)
err); err);
return err; return err;
} }
reset_control_release(sor->rst);
} }
err = clk_prepare_enable(sor->clk_safe); err = clk_prepare_enable(sor->clk_safe);
...@@ -3331,7 +3340,7 @@ static int tegra_sor_probe(struct platform_device *pdev) ...@@ -3331,7 +3340,7 @@ static int tegra_sor_probe(struct platform_device *pdev)
goto remove; goto remove;
} }
sor->rst = devm_reset_control_get(&pdev->dev, "sor"); sor->rst = devm_reset_control_get_exclusive_released(&pdev->dev, "sor");
if (IS_ERR(sor->rst)) { if (IS_ERR(sor->rst)) {
err = PTR_ERR(sor->rst); err = PTR_ERR(sor->rst);
...@@ -3519,6 +3528,8 @@ static int tegra_sor_suspend(struct device *dev) ...@@ -3519,6 +3528,8 @@ static int tegra_sor_suspend(struct device *dev)
dev_err(dev, "failed to assert reset: %d\n", err); dev_err(dev, "failed to assert reset: %d\n", err);
return err; return err;
} }
reset_control_release(sor->rst);
} }
usleep_range(1000, 2000); usleep_range(1000, 2000);
...@@ -3542,9 +3553,17 @@ static int tegra_sor_resume(struct device *dev) ...@@ -3542,9 +3553,17 @@ static int tegra_sor_resume(struct device *dev)
usleep_range(1000, 2000); usleep_range(1000, 2000);
if (sor->rst) { if (sor->rst) {
err = reset_control_acquire(sor->rst);
if (err < 0) {
dev_err(dev, "failed to acquire reset: %d\n", err);
clk_disable_unprepare(sor->clk);
return err;
}
err = reset_control_deassert(sor->rst); err = reset_control_deassert(sor->rst);
if (err < 0) { if (err < 0) {
dev_err(dev, "failed to deassert reset: %d\n", err); dev_err(dev, "failed to deassert reset: %d\n", err);
reset_control_release(sor->rst);
clk_disable_unprepare(sor->clk); clk_disable_unprepare(sor->clk);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment