aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-12-15 14:59:23 -0500
committerRafael J. Wysocki <rjw@sisk.pl>2011-12-17 18:27:35 -0500
commit8ca6d9bcc8d33c592c0855b4b1481bc723ac7e85 (patch)
tree2a80c117586c12bf475cd828ffdeeb67ba9e647f /drivers/base/power
parentcf007e3526a785a95a738d5a8fba44f1f4fe33e0 (diff)
PM / Sleep: Simplify generic system suspend callbacks
The pm_runtime_suspended() check in __pm_generic_call() doesn't really help and may cause problems to happen, because in some cases the system suspend callbacks need to be called even if the given device has been suspended by runtime PM. For example, if the device generally supports remote wakeup and is not enabled to wake up the system from sleep, it should be prevented from generating wakeup signals during system suspend and that has to be done by the suspend callbacks that the pm_runtime_suspended() check prevents from being executed. Similarly, it may not be a good idea to unconditionally change the runtime PM status of the device to 'active' in __pm_generic_resume(), because the driver may want to leave the device in the 'suspended' state, depending on what happened to it before the system suspend and whether or not it is enabled to wake up the system. For the above reasons, remove the pm_runtime_suspended() check from __pm_generic_call() and remove the code changing the device's runtime PM status from __pm_generic_resume(). Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers/base/power')
-rw-r--r--drivers/base/power/generic_ops.c24
1 files changed, 6 insertions, 18 deletions
diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c
index 265a0ee3b49e..1b878b955c8a 100644
--- a/drivers/base/power/generic_ops.c
+++ b/drivers/base/power/generic_ops.c
@@ -97,16 +97,16 @@ int pm_generic_prepare(struct device *dev)
97 * @event: PM transition of the system under way. 97 * @event: PM transition of the system under way.
98 * @bool: Whether or not this is the "noirq" stage. 98 * @bool: Whether or not this is the "noirq" stage.
99 * 99 *
100 * If the device has not been suspended at run time, execute the 100 * Execute the suspend/freeze/poweroff/thaw callback provided by the driver of
101 * suspend/freeze/poweroff/thaw callback provided by its driver, if defined, and 101 * @dev, if defined, and return its error code. Return 0 if the callback is
102 * return its error code. Otherwise, return zero. 102 * not present.
103 */ 103 */
104static int __pm_generic_call(struct device *dev, int event, bool noirq) 104static int __pm_generic_call(struct device *dev, int event, bool noirq)
105{ 105{
106 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 106 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
107 int (*callback)(struct device *); 107 int (*callback)(struct device *);
108 108
109 if (!pm || pm_runtime_suspended(dev)) 109 if (!pm)
110 return 0; 110 return 0;
111 111
112 switch (event) { 112 switch (event) {
@@ -217,14 +217,12 @@ EXPORT_SYMBOL_GPL(pm_generic_thaw);
217 * @bool: Whether or not this is the "noirq" stage. 217 * @bool: Whether or not this is the "noirq" stage.
218 * 218 *
219 * Execute the resume/resotre callback provided by the @dev's driver, if 219 * Execute the resume/resotre callback provided by the @dev's driver, if
220 * defined. If it returns 0, change the device's runtime PM status to 'active'. 220 * defined, and return its error code. Return 0 if the callback is not present.
221 * Return the callback's error code.
222 */ 221 */
223static int __pm_generic_resume(struct device *dev, int event, bool noirq) 222static int __pm_generic_resume(struct device *dev, int event, bool noirq)
224{ 223{
225 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 224 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
226 int (*callback)(struct device *); 225 int (*callback)(struct device *);
227 int ret;
228 226
229 if (!pm) 227 if (!pm)
230 return 0; 228 return 0;
@@ -241,17 +239,7 @@ static int __pm_generic_resume(struct device *dev, int event, bool noirq)
241 break; 239 break;
242 } 240 }
243 241
244 if (!callback) 242 return callback ? callback(dev) : 0;
245 return 0;
246
247 ret = callback(dev);
248 if (!ret && !noirq && pm_runtime_enabled(dev)) {
249 pm_runtime_disable(dev);
250 pm_runtime_set_active(dev);
251 pm_runtime_enable(dev);
252 }
253
254 return ret;
255} 243}
256 244
257/** 245/**