aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power
diff options
context:
space:
mode:
authorJon Hunter <jonathanh@nvidia.com>2016-09-12 07:01:14 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-09-12 20:49:34 -0400
commit17926551c98a4ff5d7fa3a574c60534fedb3f2c6 (patch)
tree8f51ba0eb167423bf3913d8b2608000b88217437 /drivers/base/power
parent3fe577107ccf1974958701df710e0b07ef16db75 (diff)
PM / Domains: Add support for removing nested PM domains by provider
If a device supports PM domains that are subdomains of another PM domain, then the PM domains should be removed in reverse order to ensure that the subdomains are removed first. Furthermore, if there is more than one provider, then there needs to be a way to remove the domains in reverse order for a specific provider. Add the function of_genpd_remove_last() to remove the last PM domain added by a given PM domain provider and return the generic_pm_domain structure for the PM domain that was removed. Signed-off-by: Jon Hunter <jonathanh@nvidia.com> Acked-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/base/power')
-rw-r--r--drivers/base/power/domain.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 7481e3e316a2..b0cf46dcae73 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1745,6 +1745,41 @@ out:
1745EXPORT_SYMBOL_GPL(of_genpd_add_subdomain); 1745EXPORT_SYMBOL_GPL(of_genpd_add_subdomain);
1746 1746
1747/** 1747/**
1748 * of_genpd_remove_last - Remove the last PM domain registered for a provider
1749 * @provider: Pointer to device structure associated with provider
1750 *
1751 * Find the last PM domain that was added by a particular provider and
1752 * remove this PM domain from the list of PM domains. The provider is
1753 * identified by the 'provider' device structure that is passed. The PM
1754 * domain will only be removed, if the provider associated with domain
1755 * has been removed.
1756 *
1757 * Returns a valid pointer to struct generic_pm_domain on success or
1758 * ERR_PTR() on failure.
1759 */
1760struct generic_pm_domain *of_genpd_remove_last(struct device_node *np)
1761{
1762 struct generic_pm_domain *gpd, *genpd = ERR_PTR(-ENOENT);
1763 int ret;
1764
1765 if (IS_ERR_OR_NULL(np))
1766 return ERR_PTR(-EINVAL);
1767
1768 mutex_lock(&gpd_list_lock);
1769 list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
1770 if (gpd->provider == &np->fwnode) {
1771 ret = genpd_remove(gpd);
1772 genpd = ret ? ERR_PTR(ret) : gpd;
1773 break;
1774 }
1775 }
1776 mutex_unlock(&gpd_list_lock);
1777
1778 return genpd;
1779}
1780EXPORT_SYMBOL_GPL(of_genpd_remove_last);
1781
1782/**
1748 * genpd_dev_pm_detach - Detach a device from its PM domain. 1783 * genpd_dev_pm_detach - Detach a device from its PM domain.
1749 * @dev: Device to detach. 1784 * @dev: Device to detach.
1750 * @power_off: Currently not used 1785 * @power_off: Currently not used