generic_ops.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /*
  2. * drivers/base/power/generic_ops.c - Generic PM callbacks for subsystems
  3. *
  4. * Copyright (c) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
  5. *
  6. * This file is released under the GPLv2.
  7. */
  8. #include <linux/pm.h>
  9. #include <linux/pm_runtime.h>
  10. #include <linux/export.h>
  11. #ifdef CONFIG_PM_RUNTIME
  12. /**
  13. * pm_generic_runtime_idle - Generic runtime idle callback for subsystems.
  14. * @dev: Device to handle.
  15. *
  16. * If PM operations are defined for the @dev's driver and they include
  17. * ->runtime_idle(), execute it and return its error code, if nonzero.
  18. * Otherwise, execute pm_runtime_suspend() for the device and return 0.
  19. */
  20. int pm_generic_runtime_idle(struct device *dev)
  21. {
  22. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  23. if (pm && pm->runtime_idle) {
  24. int ret = pm->runtime_idle(dev);
  25. if (ret)
  26. return ret;
  27. }
  28. pm_runtime_suspend(dev);
  29. return 0;
  30. }
  31. EXPORT_SYMBOL_GPL(pm_generic_runtime_idle);
  32. /**
  33. * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems.
  34. * @dev: Device to suspend.
  35. *
  36. * If PM operations are defined for the @dev's driver and they include
  37. * ->runtime_suspend(), execute it and return its error code. Otherwise,
  38. * return 0.
  39. */
  40. int pm_generic_runtime_suspend(struct device *dev)
  41. {
  42. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  43. int ret;
  44. ret = pm && pm->runtime_suspend ? pm->runtime_suspend(dev) : 0;
  45. return ret;
  46. }
  47. EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend);
  48. /**
  49. * pm_generic_runtime_resume - Generic runtime resume callback for subsystems.
  50. * @dev: Device to resume.
  51. *
  52. * If PM operations are defined for the @dev's driver and they include
  53. * ->runtime_resume(), execute it and return its error code. Otherwise,
  54. * return 0.
  55. */
  56. int pm_generic_runtime_resume(struct device *dev)
  57. {
  58. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  59. int ret;
  60. ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : 0;
  61. return ret;
  62. }
  63. EXPORT_SYMBOL_GPL(pm_generic_runtime_resume);
  64. #endif /* CONFIG_PM_RUNTIME */
  65. #ifdef CONFIG_PM_SLEEP
  66. /**
  67. * pm_generic_prepare - Generic routine preparing a device for power transition.
  68. * @dev: Device to prepare.
  69. *
  70. * Prepare a device for a system-wide power transition.
  71. */
  72. int pm_generic_prepare(struct device *dev)
  73. {
  74. struct device_driver *drv = dev->driver;
  75. int ret = 0;
  76. if (drv && drv->pm && drv->pm->prepare)
  77. ret = drv->pm->prepare(dev);
  78. return ret;
  79. }
  80. /**
  81. * pm_generic_suspend_noirq - Generic suspend_noirq callback for subsystems.
  82. * @dev: Device to suspend.
  83. */
  84. int pm_generic_suspend_noirq(struct device *dev)
  85. {
  86. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  87. return pm && pm->suspend_noirq ? pm->suspend_noirq(dev) : 0;
  88. }
  89. EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq);
  90. /**
  91. * pm_generic_suspend_late - Generic suspend_late callback for subsystems.
  92. * @dev: Device to suspend.
  93. */
  94. int pm_generic_suspend_late(struct device *dev)
  95. {
  96. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  97. return pm && pm->suspend_late ? pm->suspend_late(dev) : 0;
  98. }
  99. EXPORT_SYMBOL_GPL(pm_generic_suspend_late);
  100. /**
  101. * pm_generic_suspend - Generic suspend callback for subsystems.
  102. * @dev: Device to suspend.
  103. */
  104. int pm_generic_suspend(struct device *dev)
  105. {
  106. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  107. return pm && pm->suspend ? pm->suspend(dev) : 0;
  108. }
  109. EXPORT_SYMBOL_GPL(pm_generic_suspend);
  110. /**
  111. * pm_generic_freeze_noirq - Generic freeze_noirq callback for subsystems.
  112. * @dev: Device to freeze.
  113. */
  114. int pm_generic_freeze_noirq(struct device *dev)
  115. {
  116. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  117. return pm && pm->freeze_noirq ? pm->freeze_noirq(dev) : 0;
  118. }
  119. EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq);
  120. /**
  121. * pm_generic_freeze_late - Generic freeze_late callback for subsystems.
  122. * @dev: Device to freeze.
  123. */
  124. int pm_generic_freeze_late(struct device *dev)
  125. {
  126. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  127. return pm && pm->freeze_late ? pm->freeze_late(dev) : 0;
  128. }
  129. EXPORT_SYMBOL_GPL(pm_generic_freeze_late);
  130. /**
  131. * pm_generic_freeze - Generic freeze callback for subsystems.
  132. * @dev: Device to freeze.
  133. */
  134. int pm_generic_freeze(struct device *dev)
  135. {
  136. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  137. return pm && pm->freeze ? pm->freeze(dev) : 0;
  138. }
  139. EXPORT_SYMBOL_GPL(pm_generic_freeze);
  140. /**
  141. * pm_generic_poweroff_noirq - Generic poweroff_noirq callback for subsystems.
  142. * @dev: Device to handle.
  143. */
  144. int pm_generic_poweroff_noirq(struct device *dev)
  145. {
  146. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  147. return pm && pm->poweroff_noirq ? pm->poweroff_noirq(dev) : 0;
  148. }
  149. EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq);
  150. /**
  151. * pm_generic_poweroff_late - Generic poweroff_late callback for subsystems.
  152. * @dev: Device to handle.
  153. */
  154. int pm_generic_poweroff_late(struct device *dev)
  155. {
  156. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  157. return pm && pm->poweroff_late ? pm->poweroff_late(dev) : 0;
  158. }
  159. EXPORT_SYMBOL_GPL(pm_generic_poweroff_late);
  160. /**
  161. * pm_generic_poweroff - Generic poweroff callback for subsystems.
  162. * @dev: Device to handle.
  163. */
  164. int pm_generic_poweroff(struct device *dev)
  165. {
  166. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  167. return pm && pm->poweroff ? pm->poweroff(dev) : 0;
  168. }
  169. EXPORT_SYMBOL_GPL(pm_generic_poweroff);
  170. /**
  171. * pm_generic_thaw_noirq - Generic thaw_noirq callback for subsystems.
  172. * @dev: Device to thaw.
  173. */
  174. int pm_generic_thaw_noirq(struct device *dev)
  175. {
  176. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  177. return pm && pm->thaw_noirq ? pm->thaw_noirq(dev) : 0;
  178. }
  179. EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq);
  180. /**
  181. * pm_generic_thaw_early - Generic thaw_early callback for subsystems.
  182. * @dev: Device to thaw.
  183. */
  184. int pm_generic_thaw_early(struct device *dev)
  185. {
  186. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  187. return pm && pm->thaw_early ? pm->thaw_early(dev) : 0;
  188. }
  189. EXPORT_SYMBOL_GPL(pm_generic_thaw_early);
  190. /**
  191. * pm_generic_thaw - Generic thaw callback for subsystems.
  192. * @dev: Device to thaw.
  193. */
  194. int pm_generic_thaw(struct device *dev)
  195. {
  196. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  197. return pm && pm->thaw ? pm->thaw(dev) : 0;
  198. }
  199. EXPORT_SYMBOL_GPL(pm_generic_thaw);
  200. /**
  201. * pm_generic_resume_noirq - Generic resume_noirq callback for subsystems.
  202. * @dev: Device to resume.
  203. */
  204. int pm_generic_resume_noirq(struct device *dev)
  205. {
  206. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  207. return pm && pm->resume_noirq ? pm->resume_noirq(dev) : 0;
  208. }
  209. EXPORT_SYMBOL_GPL(pm_generic_resume_noirq);
  210. /**
  211. * pm_generic_resume_early - Generic resume_early callback for subsystems.
  212. * @dev: Device to resume.
  213. */
  214. int pm_generic_resume_early(struct device *dev)
  215. {
  216. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  217. return pm && pm->resume_early ? pm->resume_early(dev) : 0;
  218. }
  219. EXPORT_SYMBOL_GPL(pm_generic_resume_early);
  220. /**
  221. * pm_generic_resume - Generic resume callback for subsystems.
  222. * @dev: Device to resume.
  223. */
  224. int pm_generic_resume(struct device *dev)
  225. {
  226. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  227. return pm && pm->resume ? pm->resume(dev) : 0;
  228. }
  229. EXPORT_SYMBOL_GPL(pm_generic_resume);
  230. /**
  231. * pm_generic_restore_noirq - Generic restore_noirq callback for subsystems.
  232. * @dev: Device to restore.
  233. */
  234. int pm_generic_restore_noirq(struct device *dev)
  235. {
  236. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  237. return pm && pm->restore_noirq ? pm->restore_noirq(dev) : 0;
  238. }
  239. EXPORT_SYMBOL_GPL(pm_generic_restore_noirq);
  240. /**
  241. * pm_generic_restore_early - Generic restore_early callback for subsystems.
  242. * @dev: Device to resume.
  243. */
  244. int pm_generic_restore_early(struct device *dev)
  245. {
  246. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  247. return pm && pm->restore_early ? pm->restore_early(dev) : 0;
  248. }
  249. EXPORT_SYMBOL_GPL(pm_generic_restore_early);
  250. /**
  251. * pm_generic_restore - Generic restore callback for subsystems.
  252. * @dev: Device to restore.
  253. */
  254. int pm_generic_restore(struct device *dev)
  255. {
  256. const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  257. return pm && pm->restore ? pm->restore(dev) : 0;
  258. }
  259. EXPORT_SYMBOL_GPL(pm_generic_restore);
  260. /**
  261. * pm_generic_complete - Generic routine competing a device power transition.
  262. * @dev: Device to handle.
  263. *
  264. * Complete a device power transition during a system-wide power transition.
  265. */
  266. void pm_generic_complete(struct device *dev)
  267. {
  268. struct device_driver *drv = dev->driver;
  269. if (drv && drv->pm && drv->pm->complete)
  270. drv->pm->complete(dev);
  271. /*
  272. * Let runtime PM try to suspend devices that haven't been in use before
  273. * going into the system-wide sleep state we're resuming from.
  274. */
  275. pm_runtime_idle(dev);
  276. }
  277. #endif /* CONFIG_PM_SLEEP */