generic_ops.c 8.7 KB

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