diff options
-rw-r--r-- | drivers/base/power/domain.c | 12 | ||||
-rw-r--r-- | include/linux/pm_domain.h | 1 |
2 files changed, 5 insertions, 8 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index cf4950d92937..c785f2e398b9 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -315,11 +315,12 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, | |||
315 | /** | 315 | /** |
316 | * pm_genpd_poweroff - Remove power from a given PM domain. | 316 | * pm_genpd_poweroff - Remove power from a given PM domain. |
317 | * @genpd: PM domain to power down. | 317 | * @genpd: PM domain to power down. |
318 | * @is_async: PM domain is powered down from a scheduled work | ||
318 | * | 319 | * |
319 | * If all of the @genpd's devices have been suspended and all of its subdomains | 320 | * If all of the @genpd's devices have been suspended and all of its subdomains |
320 | * have been powered down, remove power from @genpd. | 321 | * have been powered down, remove power from @genpd. |
321 | */ | 322 | */ |
322 | static int pm_genpd_poweroff(struct generic_pm_domain *genpd) | 323 | static int pm_genpd_poweroff(struct generic_pm_domain *genpd, bool is_async) |
323 | { | 324 | { |
324 | struct pm_domain_data *pdd; | 325 | struct pm_domain_data *pdd; |
325 | struct gpd_link *link; | 326 | struct gpd_link *link; |
@@ -351,7 +352,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd) | |||
351 | not_suspended++; | 352 | not_suspended++; |
352 | } | 353 | } |
353 | 354 | ||
354 | if (not_suspended > genpd->in_progress) | 355 | if (not_suspended > 1 || (not_suspended == 1 && is_async)) |
355 | return -EBUSY; | 356 | return -EBUSY; |
356 | 357 | ||
357 | if (genpd->gov && genpd->gov->power_down_ok) { | 358 | if (genpd->gov && genpd->gov->power_down_ok) { |
@@ -399,7 +400,7 @@ static void genpd_power_off_work_fn(struct work_struct *work) | |||
399 | genpd = container_of(work, struct generic_pm_domain, power_off_work); | 400 | genpd = container_of(work, struct generic_pm_domain, power_off_work); |
400 | 401 | ||
401 | mutex_lock(&genpd->lock); | 402 | mutex_lock(&genpd->lock); |
402 | pm_genpd_poweroff(genpd); | 403 | pm_genpd_poweroff(genpd, true); |
403 | mutex_unlock(&genpd->lock); | 404 | mutex_unlock(&genpd->lock); |
404 | } | 405 | } |
405 | 406 | ||
@@ -445,9 +446,7 @@ static int pm_genpd_runtime_suspend(struct device *dev) | |||
445 | return 0; | 446 | return 0; |
446 | 447 | ||
447 | mutex_lock(&genpd->lock); | 448 | mutex_lock(&genpd->lock); |
448 | genpd->in_progress++; | 449 | pm_genpd_poweroff(genpd, false); |
449 | pm_genpd_poweroff(genpd); | ||
450 | genpd->in_progress--; | ||
451 | mutex_unlock(&genpd->lock); | 450 | mutex_unlock(&genpd->lock); |
452 | 451 | ||
453 | return 0; | 452 | return 0; |
@@ -1462,7 +1461,6 @@ void pm_genpd_init(struct generic_pm_domain *genpd, | |||
1462 | mutex_init(&genpd->lock); | 1461 | mutex_init(&genpd->lock); |
1463 | genpd->gov = gov; | 1462 | genpd->gov = gov; |
1464 | INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn); | 1463 | INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn); |
1465 | genpd->in_progress = 0; | ||
1466 | atomic_set(&genpd->sd_count, 0); | 1464 | atomic_set(&genpd->sd_count, 0); |
1467 | genpd->status = is_off ? GPD_STATE_POWER_OFF : GPD_STATE_ACTIVE; | 1465 | genpd->status = is_off ? GPD_STATE_POWER_OFF : GPD_STATE_ACTIVE; |
1468 | genpd->device_count = 0; | 1466 | genpd->device_count = 0; |
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 384b1d193707..0eaa730c890d 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h | |||
@@ -47,7 +47,6 @@ struct generic_pm_domain { | |||
47 | struct dev_power_governor *gov; | 47 | struct dev_power_governor *gov; |
48 | struct work_struct power_off_work; | 48 | struct work_struct power_off_work; |
49 | const char *name; | 49 | const char *name; |
50 | unsigned int in_progress; /* Number of devices being suspended now */ | ||
51 | atomic_t sd_count; /* Number of subdomains with power "on" */ | 50 | atomic_t sd_count; /* Number of subdomains with power "on" */ |
52 | enum gpd_status status; /* Current state of the domain */ | 51 | enum gpd_status status; /* Current state of the domain */ |
53 | unsigned int device_count; /* Number of devices */ | 52 | unsigned int device_count; /* Number of devices */ |