From dbf374142dd7a3c394ec124ebe7339a6c412d9b6 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 6 Aug 2012 01:46:39 +0200 Subject: 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 Acked-by: Magnus Damm --- drivers/base/power/main.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers/base/power/main.c') diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 7bd1fe4..57f5814 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); -- cgit v1.1