* If all of the @genpd's devices have been suspended and all of its subdomains
* have been powered down, remove power from @genpd.
*/
-static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on)
+static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on,
+ unsigned int depth)
{
struct pm_domain_data *pdd;
struct gpd_link *link;
list_for_each_entry(link, &genpd->slave_links, slave_node) {
genpd_sd_counter_dec(link->master);
- genpd_queue_power_off_work(link->master);
+ genpd_lock_nested(link->master, depth + 1);
+ genpd_power_off(link->master, false, depth + 1);
+ genpd_unlock(link->master);
}
return 0;
&genpd->slave_links,
slave_node) {
genpd_sd_counter_dec(link->master);
- genpd_queue_power_off_work(link->master);
+ genpd_lock_nested(link->master, depth + 1);
+ genpd_power_off(link->master, false, depth + 1);
+ genpd_unlock(link->master);
}
return ret;
genpd = container_of(work, struct generic_pm_domain, power_off_work);
genpd_lock(genpd);
- genpd_power_off(genpd, false);
+ genpd_power_off(genpd, false, 0);
genpd_unlock(genpd);
}
return 0;
genpd_lock(genpd);
- genpd_power_off(genpd, true);
+ genpd_power_off(genpd, true, 0);
genpd_unlock(genpd);
return 0;
if (!pm_runtime_is_irq_safe(dev) ||
(pm_runtime_is_irq_safe(dev) && genpd_is_irq_safe(genpd))) {
genpd_lock(genpd);
- genpd_power_off(genpd, true);
+ genpd_power_off(genpd, true, 0);
genpd_unlock(genpd);
}