Commit 7fe5719b authored by Thierry Reding's avatar Thierry Reding
Browse files

soc/tegra: pmc: Implement acquire/release for resets



By implementing the acquire/release protocol, the resets can be shared
with other drivers that also adhere to this protocol. This will be used
for example by the SOR driver to put hardware into a known good state,
irrespective of whether or not the power domain can be reset.

Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent 41c4f599
Loading
Loading
Loading
Loading
+33 −6
Original line number Diff line number Diff line
@@ -656,10 +656,15 @@ static int tegra_genpd_power_on(struct generic_pm_domain *domain)
	int err;

	err = tegra_powergate_power_up(pg, true);
	if (err)
	if (err) {
		dev_err(dev, "failed to turn on PM domain %s: %d\n",
			pg->genpd.name, err);
		goto out;
	}

	reset_control_release(pg->reset);

out:
	return err;
}

@@ -669,10 +674,18 @@ static int tegra_genpd_power_off(struct generic_pm_domain *domain)
	struct device *dev = pg->pmc->dev;
	int err;

	err = reset_control_acquire(pg->reset);
	if (err < 0) {
		pr_err("failed to acquire resets: %d\n", err);
		return err;
	}

	err = tegra_powergate_power_down(pg);
	if (err)
	if (err) {
		dev_err(dev, "failed to turn off PM domain %s: %d\n",
			pg->genpd.name, err);
		reset_control_release(pg->reset);
	}

	return err;
}
@@ -937,20 +950,34 @@ static int tegra_powergate_of_get_resets(struct tegra_powergate *pg,
	struct device *dev = pg->pmc->dev;
	int err;

	pg->reset = of_reset_control_array_get_exclusive(np);
	pg->reset = of_reset_control_array_get_exclusive_released(np);
	if (IS_ERR(pg->reset)) {
		err = PTR_ERR(pg->reset);
		dev_err(dev, "failed to get device resets: %d\n", err);
		return err;
	}

	if (off)
	err = reset_control_acquire(pg->reset);
	if (err < 0) {
		pr_err("failed to acquire resets: %d\n", err);
		goto out;
	}

	if (off) {
		err = reset_control_assert(pg->reset);
	else
	} else {
		err = reset_control_deassert(pg->reset);
		if (err < 0)
			goto out;

	if (err)
		reset_control_release(pg->reset);
	}

out:
	if (err) {
		reset_control_release(pg->reset);
		reset_control_put(pg->reset);
	}

	return err;
}