Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
generic_ops.c
Go to the documentation of this file.
1 /*
2  * drivers/base/power/generic_ops.c - Generic PM callbacks for subsystems
3  *
4  * Copyright (c) 2010 Rafael J. Wysocki <[email protected]>, Novell Inc.
5  *
6  * This file is released under the GPLv2.
7  */
8 
9 #include <linux/pm.h>
10 #include <linux/pm_runtime.h>
11 #include <linux/export.h>
12 
13 #ifdef CONFIG_PM_RUNTIME
14 
22 int pm_generic_runtime_idle(struct device *dev)
23 {
24  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
25 
26  if (pm && pm->runtime_idle) {
27  int ret = pm->runtime_idle(dev);
28  if (ret)
29  return ret;
30  }
31 
32  pm_runtime_suspend(dev);
33  return 0;
34 }
35 EXPORT_SYMBOL_GPL(pm_generic_runtime_idle);
36 
45 int pm_generic_runtime_suspend(struct device *dev)
46 {
47  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
48  int ret;
49 
50  ret = pm && pm->runtime_suspend ? pm->runtime_suspend(dev) : 0;
51 
52  return ret;
53 }
54 EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend);
55 
64 int pm_generic_runtime_resume(struct device *dev)
65 {
66  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
67  int ret;
68 
69  ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : 0;
70 
71  return ret;
72 }
73 EXPORT_SYMBOL_GPL(pm_generic_runtime_resume);
74 #endif /* CONFIG_PM_RUNTIME */
75 
76 #ifdef CONFIG_PM_SLEEP
77 
83 int pm_generic_prepare(struct device *dev)
84 {
85  struct device_driver *drv = dev->driver;
86  int ret = 0;
87 
88  if (drv && drv->pm && drv->pm->prepare)
89  ret = drv->pm->prepare(dev);
90 
91  return ret;
92 }
93 
98 int pm_generic_suspend_noirq(struct device *dev)
99 {
100  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
101 
102  return pm && pm->suspend_noirq ? pm->suspend_noirq(dev) : 0;
103 }
104 EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq);
105 
110 int pm_generic_suspend_late(struct device *dev)
111 {
112  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
113 
114  return pm && pm->suspend_late ? pm->suspend_late(dev) : 0;
115 }
116 EXPORT_SYMBOL_GPL(pm_generic_suspend_late);
117 
122 int pm_generic_suspend(struct device *dev)
123 {
124  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
125 
126  return pm && pm->suspend ? pm->suspend(dev) : 0;
127 }
129 
134 int pm_generic_freeze_noirq(struct device *dev)
135 {
136  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
137 
138  return pm && pm->freeze_noirq ? pm->freeze_noirq(dev) : 0;
139 }
140 EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq);
141 
146 int pm_generic_freeze_late(struct device *dev)
147 {
148  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
149 
150  return pm && pm->freeze_late ? pm->freeze_late(dev) : 0;
151 }
152 EXPORT_SYMBOL_GPL(pm_generic_freeze_late);
153 
158 int pm_generic_freeze(struct device *dev)
159 {
160  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
161 
162  return pm && pm->freeze ? pm->freeze(dev) : 0;
163 }
165 
170 int pm_generic_poweroff_noirq(struct device *dev)
171 {
172  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
173 
174  return pm && pm->poweroff_noirq ? pm->poweroff_noirq(dev) : 0;
175 }
176 EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq);
177 
182 int pm_generic_poweroff_late(struct device *dev)
183 {
184  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
185 
186  return pm && pm->poweroff_late ? pm->poweroff_late(dev) : 0;
187 }
188 EXPORT_SYMBOL_GPL(pm_generic_poweroff_late);
189 
194 int pm_generic_poweroff(struct device *dev)
195 {
196  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
197 
198  return pm && pm->poweroff ? pm->poweroff(dev) : 0;
199 }
201 
206 int pm_generic_thaw_noirq(struct device *dev)
207 {
208  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
209 
210  return pm && pm->thaw_noirq ? pm->thaw_noirq(dev) : 0;
211 }
212 EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq);
213 
218 int pm_generic_thaw_early(struct device *dev)
219 {
220  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
221 
222  return pm && pm->thaw_early ? pm->thaw_early(dev) : 0;
223 }
224 EXPORT_SYMBOL_GPL(pm_generic_thaw_early);
225 
230 int pm_generic_thaw(struct device *dev)
231 {
232  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
233 
234  return pm && pm->thaw ? pm->thaw(dev) : 0;
235 }
237 
242 int pm_generic_resume_noirq(struct device *dev)
243 {
244  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
245 
246  return pm && pm->resume_noirq ? pm->resume_noirq(dev) : 0;
247 }
248 EXPORT_SYMBOL_GPL(pm_generic_resume_noirq);
249 
254 int pm_generic_resume_early(struct device *dev)
255 {
256  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
257 
258  return pm && pm->resume_early ? pm->resume_early(dev) : 0;
259 }
260 EXPORT_SYMBOL_GPL(pm_generic_resume_early);
261 
266 int pm_generic_resume(struct device *dev)
267 {
268  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
269 
270  return pm && pm->resume ? pm->resume(dev) : 0;
271 }
273 
278 int pm_generic_restore_noirq(struct device *dev)
279 {
280  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
281 
282  return pm && pm->restore_noirq ? pm->restore_noirq(dev) : 0;
283 }
284 EXPORT_SYMBOL_GPL(pm_generic_restore_noirq);
285 
290 int pm_generic_restore_early(struct device *dev)
291 {
292  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
293 
294  return pm && pm->restore_early ? pm->restore_early(dev) : 0;
295 }
296 EXPORT_SYMBOL_GPL(pm_generic_restore_early);
297 
302 int pm_generic_restore(struct device *dev)
303 {
304  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
305 
306  return pm && pm->restore ? pm->restore(dev) : 0;
307 }
309 
316 void pm_generic_complete(struct device *dev)
317 {
318  struct device_driver *drv = dev->driver;
319 
320  if (drv && drv->pm && drv->pm->complete)
321  drv->pm->complete(dev);
322 
323  /*
324  * Let runtime PM try to suspend devices that haven't been in use before
325  * going into the system-wide sleep state we're resuming from.
326  */
327  pm_runtime_idle(dev);
328 }
329 #endif /* CONFIG_PM_SLEEP */