wakeirq.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. /*
  2. * wakeirq.c - Device wakeirq helper functions
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  9. * kind, whether express or implied; without even the implied warranty
  10. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/device.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/irq.h>
  16. #include <linux/slab.h>
  17. #include <linux/pm_runtime.h>
  18. #include <linux/pm_wakeirq.h>
  19. #include "power.h"
  20. /**
  21. * dev_pm_attach_wake_irq - Attach device interrupt as a wake IRQ
  22. * @dev: Device entry
  23. * @irq: Device wake-up capable interrupt
  24. * @wirq: Wake irq specific data
  25. *
  26. * Internal function to attach either a device IO interrupt or a
  27. * dedicated wake-up interrupt as a wake IRQ.
  28. */
  29. static int dev_pm_attach_wake_irq(struct device *dev, int irq,
  30. struct wake_irq *wirq)
  31. {
  32. unsigned long flags;
  33. if (!dev || !wirq)
  34. return -EINVAL;
  35. spin_lock_irqsave(&dev->power.lock, flags);
  36. if (dev_WARN_ONCE(dev, dev->power.wakeirq,
  37. "wake irq already initialized\n")) {
  38. spin_unlock_irqrestore(&dev->power.lock, flags);
  39. return -EEXIST;
  40. }
  41. dev->power.wakeirq = wirq;
  42. device_wakeup_attach_irq(dev, wirq);
  43. spin_unlock_irqrestore(&dev->power.lock, flags);
  44. return 0;
  45. }
  46. /**
  47. * dev_pm_set_wake_irq - Attach device IO interrupt as wake IRQ
  48. * @dev: Device entry
  49. * @irq: Device IO interrupt
  50. *
  51. * Attach a device IO interrupt as a wake IRQ. The wake IRQ gets
  52. * automatically configured for wake-up from suspend based
  53. * on the device specific sysfs wakeup entry. Typically called
  54. * during driver probe after calling device_init_wakeup().
  55. */
  56. int dev_pm_set_wake_irq(struct device *dev, int irq)
  57. {
  58. struct wake_irq *wirq;
  59. int err;
  60. if (irq < 0)
  61. return -EINVAL;
  62. wirq = kzalloc(sizeof(*wirq), GFP_KERNEL);
  63. if (!wirq)
  64. return -ENOMEM;
  65. wirq->dev = dev;
  66. wirq->irq = irq;
  67. err = dev_pm_attach_wake_irq(dev, irq, wirq);
  68. if (err)
  69. kfree(wirq);
  70. return err;
  71. }
  72. EXPORT_SYMBOL_GPL(dev_pm_set_wake_irq);
  73. /**
  74. * dev_pm_clear_wake_irq - Detach a device IO interrupt wake IRQ
  75. * @dev: Device entry
  76. *
  77. * Detach a device wake IRQ and free resources.
  78. *
  79. * Note that it's OK for drivers to call this without calling
  80. * dev_pm_set_wake_irq() as all the driver instances may not have
  81. * a wake IRQ configured. This avoid adding wake IRQ specific
  82. * checks into the drivers.
  83. */
  84. void dev_pm_clear_wake_irq(struct device *dev)
  85. {
  86. struct wake_irq *wirq = dev->power.wakeirq;
  87. unsigned long flags;
  88. if (!wirq)
  89. return;
  90. spin_lock_irqsave(&dev->power.lock, flags);
  91. device_wakeup_detach_irq(dev);
  92. dev->power.wakeirq = NULL;
  93. spin_unlock_irqrestore(&dev->power.lock, flags);
  94. if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED) {
  95. free_irq(wirq->irq, wirq);
  96. wirq->status &= ~WAKE_IRQ_DEDICATED_MASK;
  97. }
  98. kfree(wirq->name);
  99. kfree(wirq);
  100. }
  101. EXPORT_SYMBOL_GPL(dev_pm_clear_wake_irq);
  102. /**
  103. * handle_threaded_wake_irq - Handler for dedicated wake-up interrupts
  104. * @irq: Device specific dedicated wake-up interrupt
  105. * @_wirq: Wake IRQ data
  106. *
  107. * Some devices have a separate wake-up interrupt in addition to the
  108. * device IO interrupt. The wake-up interrupt signals that a device
  109. * should be woken up from it's idle state. This handler uses device
  110. * specific pm_runtime functions to wake the device, and then it's
  111. * up to the device to do whatever it needs to. Note that as the
  112. * device may need to restore context and start up regulators, we
  113. * use a threaded IRQ.
  114. *
  115. * Also note that we are not resending the lost device interrupts.
  116. * We assume that the wake-up interrupt just needs to wake-up the
  117. * device, and then device's pm_runtime_resume() can deal with the
  118. * situation.
  119. */
  120. static irqreturn_t handle_threaded_wake_irq(int irq, void *_wirq)
  121. {
  122. struct wake_irq *wirq = _wirq;
  123. int res;
  124. /* Maybe abort suspend? */
  125. if (irqd_is_wakeup_set(irq_get_irq_data(irq))) {
  126. pm_wakeup_event(wirq->dev, 0);
  127. return IRQ_HANDLED;
  128. }
  129. /* We don't want RPM_ASYNC or RPM_NOWAIT here */
  130. res = pm_runtime_resume(wirq->dev);
  131. if (res < 0)
  132. dev_warn(wirq->dev,
  133. "wake IRQ with no resume: %i\n", res);
  134. return IRQ_HANDLED;
  135. }
  136. /**
  137. * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt
  138. * @dev: Device entry
  139. * @irq: Device wake-up interrupt
  140. *
  141. * Unless your hardware has separate wake-up interrupts in addition
  142. * to the device IO interrupts, you don't need this.
  143. *
  144. * Sets up a threaded interrupt handler for a device that has
  145. * a dedicated wake-up interrupt in addition to the device IO
  146. * interrupt.
  147. *
  148. * The interrupt starts disabled, and needs to be managed for
  149. * the device by the bus code or the device driver using
  150. * dev_pm_enable_wake_irq() and dev_pm_disable_wake_irq()
  151. * functions.
  152. */
  153. int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
  154. {
  155. struct wake_irq *wirq;
  156. int err;
  157. if (irq < 0)
  158. return -EINVAL;
  159. wirq = kzalloc(sizeof(*wirq), GFP_KERNEL);
  160. if (!wirq)
  161. return -ENOMEM;
  162. wirq->name = kasprintf(GFP_KERNEL, "%s:wakeup", dev_name(dev));
  163. if (!wirq->name) {
  164. err = -ENOMEM;
  165. goto err_free;
  166. }
  167. wirq->dev = dev;
  168. wirq->irq = irq;
  169. irq_set_status_flags(irq, IRQ_NOAUTOEN);
  170. /* Prevent deferred spurious wakeirqs with disable_irq_nosync() */
  171. irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY);
  172. /*
  173. * Consumer device may need to power up and restore state
  174. * so we use a threaded irq.
  175. */
  176. err = request_threaded_irq(irq, NULL, handle_threaded_wake_irq,
  177. IRQF_ONESHOT, wirq->name, wirq);
  178. if (err)
  179. goto err_free_name;
  180. err = dev_pm_attach_wake_irq(dev, irq, wirq);
  181. if (err)
  182. goto err_free_irq;
  183. wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED;
  184. return err;
  185. err_free_irq:
  186. free_irq(irq, wirq);
  187. err_free_name:
  188. kfree(wirq->name);
  189. err_free:
  190. kfree(wirq);
  191. return err;
  192. }
  193. EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq);
  194. /**
  195. * dev_pm_enable_wake_irq - Enable device wake-up interrupt
  196. * @dev: Device
  197. *
  198. * Optionally called from the bus code or the device driver for
  199. * runtime_resume() to override the PM runtime core managed wake-up
  200. * interrupt handling to enable the wake-up interrupt.
  201. *
  202. * Note that for runtime_suspend()) the wake-up interrupts
  203. * should be unconditionally enabled unlike for suspend()
  204. * that is conditional.
  205. */
  206. void dev_pm_enable_wake_irq(struct device *dev)
  207. {
  208. struct wake_irq *wirq = dev->power.wakeirq;
  209. if (wirq && (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED))
  210. enable_irq(wirq->irq);
  211. }
  212. EXPORT_SYMBOL_GPL(dev_pm_enable_wake_irq);
  213. /**
  214. * dev_pm_disable_wake_irq - Disable device wake-up interrupt
  215. * @dev: Device
  216. *
  217. * Optionally called from the bus code or the device driver for
  218. * runtime_suspend() to override the PM runtime core managed wake-up
  219. * interrupt handling to disable the wake-up interrupt.
  220. */
  221. void dev_pm_disable_wake_irq(struct device *dev)
  222. {
  223. struct wake_irq *wirq = dev->power.wakeirq;
  224. if (wirq && (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED))
  225. disable_irq_nosync(wirq->irq);
  226. }
  227. EXPORT_SYMBOL_GPL(dev_pm_disable_wake_irq);
  228. /**
  229. * dev_pm_enable_wake_irq_check - Checks and enables wake-up interrupt
  230. * @dev: Device
  231. * @can_change_status: Can change wake-up interrupt status
  232. *
  233. * Enables wakeirq conditionally. We need to enable wake-up interrupt
  234. * lazily on the first rpm_suspend(). This is needed as the consumer device
  235. * starts in RPM_SUSPENDED state, and the the first pm_runtime_get() would
  236. * otherwise try to disable already disabled wakeirq. The wake-up interrupt
  237. * starts disabled with IRQ_NOAUTOEN set.
  238. *
  239. * Should be only called from rpm_suspend() and rpm_resume() path.
  240. * Caller must hold &dev->power.lock to change wirq->status
  241. */
  242. void dev_pm_enable_wake_irq_check(struct device *dev,
  243. bool can_change_status)
  244. {
  245. struct wake_irq *wirq = dev->power.wakeirq;
  246. if (!wirq || !((wirq->status & WAKE_IRQ_DEDICATED_MASK)))
  247. return;
  248. if (likely(wirq->status & WAKE_IRQ_DEDICATED_MANAGED)) {
  249. goto enable;
  250. } else if (can_change_status) {
  251. wirq->status |= WAKE_IRQ_DEDICATED_MANAGED;
  252. goto enable;
  253. }
  254. return;
  255. enable:
  256. enable_irq(wirq->irq);
  257. }
  258. /**
  259. * dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt
  260. * @dev: Device
  261. *
  262. * Disables wake-up interrupt conditionally based on status.
  263. * Should be only called from rpm_suspend() and rpm_resume() path.
  264. */
  265. void dev_pm_disable_wake_irq_check(struct device *dev)
  266. {
  267. struct wake_irq *wirq = dev->power.wakeirq;
  268. if (!wirq || !((wirq->status & WAKE_IRQ_DEDICATED_MASK)))
  269. return;
  270. if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED)
  271. disable_irq_nosync(wirq->irq);
  272. }
  273. /**
  274. * dev_pm_arm_wake_irq - Arm device wake-up
  275. * @wirq: Device wake-up interrupt
  276. *
  277. * Sets up the wake-up event conditionally based on the
  278. * device_may_wake().
  279. */
  280. void dev_pm_arm_wake_irq(struct wake_irq *wirq)
  281. {
  282. if (!wirq)
  283. return;
  284. if (device_may_wakeup(wirq->dev)) {
  285. if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
  286. !pm_runtime_status_suspended(wirq->dev))
  287. enable_irq(wirq->irq);
  288. enable_irq_wake(wirq->irq);
  289. }
  290. }
  291. /**
  292. * dev_pm_disarm_wake_irq - Disarm device wake-up
  293. * @wirq: Device wake-up interrupt
  294. *
  295. * Clears up the wake-up event conditionally based on the
  296. * device_may_wake().
  297. */
  298. void dev_pm_disarm_wake_irq(struct wake_irq *wirq)
  299. {
  300. if (!wirq)
  301. return;
  302. if (device_may_wakeup(wirq->dev)) {
  303. disable_irq_wake(wirq->irq);
  304. if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
  305. !pm_runtime_status_suspended(wirq->dev))
  306. disable_irq_nosync(wirq->irq);
  307. }
  308. }