aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power/generic_ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/power/generic_ops.c')
-rw-r--r--drivers/base/power/generic_ops.c91
1 files changed, 14 insertions, 77 deletions
diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c
index 265a0ee3b49e..10bdd793f0bd 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 PM callback corresponding to @event 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) {
@@ -119,9 +119,15 @@ static int __pm_generic_call(struct device *dev, int event, bool noirq)
119 case PM_EVENT_HIBERNATE: 119 case PM_EVENT_HIBERNATE:
120 callback = noirq ? pm->poweroff_noirq : pm->poweroff; 120 callback = noirq ? pm->poweroff_noirq : pm->poweroff;
121 break; 121 break;
122 case PM_EVENT_RESUME:
123 callback = noirq ? pm->resume_noirq : pm->resume;
124 break;
122 case PM_EVENT_THAW: 125 case PM_EVENT_THAW:
123 callback = noirq ? pm->thaw_noirq : pm->thaw; 126 callback = noirq ? pm->thaw_noirq : pm->thaw;
124 break; 127 break;
128 case PM_EVENT_RESTORE:
129 callback = noirq ? pm->restore_noirq : pm->restore;
130 break;
125 default: 131 default:
126 callback = NULL; 132 callback = NULL;
127 break; 133 break;
@@ -211,56 +217,12 @@ int pm_generic_thaw(struct device *dev)
211EXPORT_SYMBOL_GPL(pm_generic_thaw); 217EXPORT_SYMBOL_GPL(pm_generic_thaw);
212 218
213/** 219/**
214 * __pm_generic_resume - Generic resume/restore callback for subsystems.
215 * @dev: Device to handle.
216 * @event: PM transition of the system under way.
217 * @bool: Whether or not this is the "noirq" stage.
218 *
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'.
221 * Return the callback's error code.
222 */
223static int __pm_generic_resume(struct device *dev, int event, bool noirq)
224{
225 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
226 int (*callback)(struct device *);
227 int ret;
228
229 if (!pm)
230 return 0;
231
232 switch (event) {
233 case PM_EVENT_RESUME:
234 callback = noirq ? pm->resume_noirq : pm->resume;
235 break;
236 case PM_EVENT_RESTORE:
237 callback = noirq ? pm->restore_noirq : pm->restore;
238 break;
239 default:
240 callback = NULL;
241 break;
242 }
243
244 if (!callback)
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}
256
257/**
258 * pm_generic_resume_noirq - Generic resume_noirq callback for subsystems. 220 * pm_generic_resume_noirq - Generic resume_noirq callback for subsystems.
259 * @dev: Device to resume. 221 * @dev: Device to resume.
260 */ 222 */
261int pm_generic_resume_noirq(struct device *dev) 223int pm_generic_resume_noirq(struct device *dev)
262{ 224{
263 return __pm_generic_resume(dev, PM_EVENT_RESUME, true); 225 return __pm_generic_call(dev, PM_EVENT_RESUME, true);
264} 226}
265EXPORT_SYMBOL_GPL(pm_generic_resume_noirq); 227EXPORT_SYMBOL_GPL(pm_generic_resume_noirq);
266 228
@@ -270,7 +232,7 @@ EXPORT_SYMBOL_GPL(pm_generic_resume_noirq);
270 */ 232 */
271int pm_generic_resume(struct device *dev) 233int pm_generic_resume(struct device *dev)
272{ 234{
273 return __pm_generic_resume(dev, PM_EVENT_RESUME, false); 235 return __pm_generic_call(dev, PM_EVENT_RESUME, false);
274} 236}
275EXPORT_SYMBOL_GPL(pm_generic_resume); 237EXPORT_SYMBOL_GPL(pm_generic_resume);
276 238
@@ -280,7 +242,7 @@ EXPORT_SYMBOL_GPL(pm_generic_resume);
280 */ 242 */
281int pm_generic_restore_noirq(struct device *dev) 243int pm_generic_restore_noirq(struct device *dev)
282{ 244{
283 return __pm_generic_resume(dev, PM_EVENT_RESTORE, true); 245 return __pm_generic_call(dev, PM_EVENT_RESTORE, true);
284} 246}
285EXPORT_SYMBOL_GPL(pm_generic_restore_noirq); 247EXPORT_SYMBOL_GPL(pm_generic_restore_noirq);
286 248
@@ -290,7 +252,7 @@ EXPORT_SYMBOL_GPL(pm_generic_restore_noirq);
290 */ 252 */
291int pm_generic_restore(struct device *dev) 253int pm_generic_restore(struct device *dev)
292{ 254{
293 return __pm_generic_resume(dev, PM_EVENT_RESTORE, false); 255 return __pm_generic_call(dev, PM_EVENT_RESTORE, false);
294} 256}
295EXPORT_SYMBOL_GPL(pm_generic_restore); 257EXPORT_SYMBOL_GPL(pm_generic_restore);
296 258
@@ -314,28 +276,3 @@ void pm_generic_complete(struct device *dev)
314 pm_runtime_idle(dev); 276 pm_runtime_idle(dev);
315} 277}
316#endif /* CONFIG_PM_SLEEP */ 278#endif /* CONFIG_PM_SLEEP */
317
318struct dev_pm_ops generic_subsys_pm_ops = {
319#ifdef CONFIG_PM_SLEEP
320 .prepare = pm_generic_prepare,
321 .suspend = pm_generic_suspend,
322 .suspend_noirq = pm_generic_suspend_noirq,
323 .resume = pm_generic_resume,
324 .resume_noirq = pm_generic_resume_noirq,
325 .freeze = pm_generic_freeze,
326 .freeze_noirq = pm_generic_freeze_noirq,
327 .thaw = pm_generic_thaw,
328 .thaw_noirq = pm_generic_thaw_noirq,
329 .poweroff = pm_generic_poweroff,
330 .poweroff_noirq = pm_generic_poweroff_noirq,
331 .restore = pm_generic_restore,
332 .restore_noirq = pm_generic_restore_noirq,
333 .complete = pm_generic_complete,
334#endif
335#ifdef CONFIG_PM_RUNTIME
336 .runtime_suspend = pm_generic_runtime_suspend,
337 .runtime_resume = pm_generic_runtime_resume,
338 .runtime_idle = pm_generic_runtime_idle,
339#endif
340};
341EXPORT_SYMBOL_GPL(generic_subsys_pm_ops);