summaryrefslogtreecommitdiffstats
path: root/drivers/base/power/main.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-08-06 01:46:39 +0200
committerRafael J. Wysocki <rjw@sisk.pl>2012-09-04 01:36:04 +0200
commitdbf374142dd7a3c394ec124ebe7339a6c412d9b6 (patch)
tree593b26dff2da2f364ed1ad97e667d691487d7e69 /drivers/base/power/main.c
parentPM / Domains: Rename the always_on device flag to syscore (diff)
downloadlinux-dbf374142dd7a3c394ec124ebe7339a6c412d9b6.tar.xz
linux-dbf374142dd7a3c394ec124ebe7339a6c412d9b6.zip
PM / Domains: Move syscore flag from subsys data to struct device
The syscore device PM flag is used to mark the devices (belonging to a PM domain) that should never be turned off, except for the system core (syscore) suspend/hibernation and resume stages. That flag is stored in the device's struct pm_subsys_data object whose address is available from struct device. However, in some situations it may be convenient to set that flag before the device is added to a PM domain, so it is better to move it directly to the "power" member of struct device. Then, it can be checked by the routines in drivers/base/power/runtime.c and drivers/base/power/main.c, which is more straightforward. This also reduces the number of dev_gpd_data() invocations in the generic PM domains framework, so the overhead related to the syscore flag is slightly smaller. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Magnus Damm <damm@opensource.se>
Diffstat (limited to 'drivers/base/power/main.c')
-rw-r--r--drivers/base/power/main.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 7bd1fe400549..57f5814c2732 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -405,6 +405,9 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
TRACE_DEVICE(dev);
TRACE_RESUME(0);
+ if (dev->power.syscore)
+ goto Out;
+
if (dev->pm_domain) {
info = "noirq power domain ";
callback = pm_noirq_op(&dev->pm_domain->ops, state);
@@ -426,6 +429,7 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
error = dpm_run_callback(callback, dev, state, info);
+ Out:
TRACE_RESUME(error);
return error;
}
@@ -483,6 +487,9 @@ static int device_resume_early(struct device *dev, pm_message_t state)
TRACE_DEVICE(dev);
TRACE_RESUME(0);
+ if (dev->power.syscore)
+ goto Out;
+
if (dev->pm_domain) {
info = "early power domain ";
callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -504,6 +511,7 @@ static int device_resume_early(struct device *dev, pm_message_t state)
error = dpm_run_callback(callback, dev, state, info);
+ Out:
TRACE_RESUME(error);
return error;
}
@@ -567,6 +575,9 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
TRACE_DEVICE(dev);
TRACE_RESUME(0);
+ if (dev->power.syscore)
+ goto Complete;
+
dpm_wait(dev->parent, async);
device_lock(dev);
@@ -629,6 +640,8 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
Unlock:
device_unlock(dev);
+
+ Complete:
complete_all(&dev->power.completion);
TRACE_RESUME(error);
@@ -719,6 +732,9 @@ static void device_complete(struct device *dev, pm_message_t state)
void (*callback)(struct device *) = NULL;
char *info = NULL;
+ if (dev->power.syscore)
+ return;
+
device_lock(dev);
if (dev->pm_domain) {
@@ -831,6 +847,9 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
pm_callback_t callback = NULL;
char *info = NULL;
+ if (dev->power.syscore)
+ return 0;
+
if (dev->pm_domain) {
info = "noirq power domain ";
callback = pm_noirq_op(&dev->pm_domain->ops, state);
@@ -914,6 +933,9 @@ static int device_suspend_late(struct device *dev, pm_message_t state)
pm_callback_t callback = NULL;
char *info = NULL;
+ if (dev->power.syscore)
+ return 0;
+
if (dev->pm_domain) {
info = "late power domain ";
callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -1050,6 +1072,9 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
goto Complete;
}
+ if (dev->power.syscore)
+ goto Complete;
+
device_lock(dev);
if (dev->pm_domain) {
@@ -1206,6 +1231,9 @@ static int device_prepare(struct device *dev, pm_message_t state)
char *info = NULL;
int error = 0;
+ if (dev->power.syscore)
+ return 0;
+
device_lock(dev);
dev->power.wakeup_path = device_may_wakeup(dev);