PM / Domains: Queue up power off work only if it is not pending
In theory it is possible that pm_genpd_poweroff() for two different subdomains of the same parent domain will attempt to queue up the execution of pm_genpd_poweroff() for the parent twice in a row. This would lead to unpleasant consequences, so prevent it from happening by checking if genpd->power_off_work is pending before attempting to queue it up. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
This commit is contained in:
parent
4ecd6e651d
commit
56375fd420
|
@ -212,6 +212,19 @@ static bool genpd_abort_poweroff(struct generic_pm_domain *genpd)
|
|||
return genpd->status == GPD_STATE_ACTIVE || genpd->resume_count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* genpd_queue_power_off_work - Queue up the execution of pm_genpd_poweroff().
|
||||
* @genpd: PM domait to power off.
|
||||
*
|
||||
* Queue up the execution of pm_genpd_poweroff() unless it's already been done
|
||||
* before.
|
||||
*/
|
||||
static void genpd_queue_power_off_work(struct generic_pm_domain *genpd)
|
||||
{
|
||||
if (!work_pending(&genpd->power_off_work))
|
||||
queue_work(pm_wq, &genpd->power_off_work);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_genpd_poweroff - Remove power from a given PM domain.
|
||||
* @genpd: PM domain to power down.
|
||||
|
@ -304,7 +317,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
|
|||
if (parent) {
|
||||
genpd_sd_counter_dec(parent);
|
||||
if (parent->sd_count == 0)
|
||||
queue_work(pm_wq, &parent->power_off_work);
|
||||
genpd_queue_power_off_work(parent);
|
||||
|
||||
genpd_release_lock(parent);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue