summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-03-14 01:39:31 +0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-03-17 00:44:41 +0400
commitcc85b20780562d404e18a47b9b55b4a5102ae53e (patch)
treee7d481ea6f435e90c59cda9433fd68d944070c19 /drivers
parentb642631d38c28fefd1232a6b96713eb54b60130d (diff)
downloadlinux-cc85b20780562d404e18a47b9b55b4a5102ae53e.tar.xz
PM / Domains: Fix handling of wakeup devices during system resume
During system suspend pm_genpd_suspend_noirq() checks if the given device is in a wakeup path (i.e. it appears to be needed for one or more wakeup devices to work or is a wakeup device itself) and if it needs to be "active" for wakeup to work. If that is the case, the function returns 0 without incrementing the device domain's counter of suspended devices and without executing genpd_stop_dev() for the device. In consequence, the device is not stopped (e.g. its clock isn't disabled) and power is always supplied to its domain in the resulting system sleep state. However, pm_genpd_resume_noirq() doesn't repeat that check and it runs genpd_start_dev() and decrements the domain's counter of suspended devices even for the wakeup device that weren't stopped by pm_genpd_suspend_noirq(). As a result, the start callback may be run unnecessarily for them and their domains' counters of suspended devices may become negative. Both outcomes aren't desirable, so fix pm_genpd_resume_noirq() to look for wakeup devices that might not be stopped by during system suspend. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Tested-by: Simon Horman <horms@verge.net.au> Cc: stable@vger.kernel.org
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/power/domain.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index d2c03239abcf..e79228c597f1 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -890,7 +890,8 @@ static int pm_genpd_resume_noirq(struct device *dev)
if (IS_ERR(genpd))
return -EINVAL;
- if (genpd->suspend_power_off)
+ if (genpd->suspend_power_off
+ || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)))
return 0;
/*