Skip to content

Commit 1792655

Browse files
jonhunterrafaeljw
authored andcommitted
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 <[email protected]> Acked-by: Ulf Hansson <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 3fe5771 commit 1792655

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

drivers/base/power/domain.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,6 +1744,41 @@ int of_genpd_add_subdomain(struct of_phandle_args *parent_spec,
17441744
}
17451745
EXPORT_SYMBOL_GPL(of_genpd_add_subdomain);
17461746

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+
*/
1760+
struct 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+
}
1780+
EXPORT_SYMBOL_GPL(of_genpd_remove_last);
1781+
17471782
/**
17481783
* genpd_dev_pm_detach - Detach a device from its PM domain.
17491784
* @dev: Device to detach.

include/linux/pm_domain.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ extern int of_genpd_add_device(struct of_phandle_args *args,
204204
struct device *dev);
205205
extern int of_genpd_add_subdomain(struct of_phandle_args *parent,
206206
struct of_phandle_args *new_subdomain);
207+
extern struct generic_pm_domain *of_genpd_remove_last(struct device_node *np);
207208

208209
int genpd_dev_pm_attach(struct device *dev);
209210
#else /* !CONFIG_PM_GENERIC_DOMAINS_OF */
@@ -237,6 +238,12 @@ static inline int genpd_dev_pm_attach(struct device *dev)
237238
{
238239
return -ENODEV;
239240
}
241+
242+
static inline
243+
struct generic_pm_domain *of_genpd_remove_last(struct device_node *np)
244+
{
245+
return ERR_PTR(-ENOTSUPP);
246+
}
240247
#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
241248

242249
#ifdef CONFIG_PM

0 commit comments

Comments
 (0)