aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/power/domain.c12
-rw-r--r--include/linux/pm_domain.h1
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 */
322static int pm_genpd_poweroff(struct generic_pm_domain *genpd) 323static 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 */