devm-helpers.h 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. #ifndef __LINUX_DEVM_HELPERS_H
  3. #define __LINUX_DEVM_HELPERS_H
  4. /*
  5. * Functions which do automatically cancel operations or release resources upon
  6. * driver detach.
  7. *
  8. * These should be helpful to avoid mixing the manual and devm-based resource
  9. * management which can be source of annoying, rarely occurring,
  10. * hard-to-reproduce bugs.
  11. *
  12. * Please take into account that devm based cancellation may be performed some
  13. * time after the remove() is ran.
  14. *
  15. * Thus mixing devm and manual resource management can easily cause problems
  16. * when unwinding operations with dependencies. IRQ scheduling a work in a queue
  17. * is typical example where IRQs are often devm-managed and WQs are manually
  18. * cleaned at remove(). If IRQs are not manually freed at remove() (and this is
  19. * often the case when we use devm for IRQs) we have a period of time after
  20. * remove() - and before devm managed IRQs are freed - where new IRQ may fire
  21. * and schedule a work item which won't be cancelled because remove() was
  22. * already ran.
  23. */
  24. #include <linux/device.h>
  25. #include <linux/workqueue.h>
  26. static inline void devm_delayed_work_drop(void *res)
  27. {
  28. cancel_delayed_work_sync(res);
  29. }
  30. /**
  31. * devm_delayed_work_autocancel - Resource-managed delayed work allocation
  32. * @dev: Device which lifetime work is bound to
  33. * @w: Work item to be queued
  34. * @worker: Worker function
  35. *
  36. * Initialize delayed work which is automatically cancelled when driver is
  37. * detached. A few drivers need delayed work which must be cancelled before
  38. * driver is detached to avoid accessing removed resources.
  39. * devm_delayed_work_autocancel() can be used to omit the explicit
  40. * cancelleation when driver is detached.
  41. */
  42. static inline int devm_delayed_work_autocancel(struct device *dev,
  43. struct delayed_work *w,
  44. work_func_t worker)
  45. {
  46. INIT_DELAYED_WORK(w, worker);
  47. return devm_add_action(dev, devm_delayed_work_drop, w);
  48. }
  49. static inline void devm_work_drop(void *res)
  50. {
  51. cancel_work_sync(res);
  52. }
  53. /**
  54. * devm_work_autocancel - Resource-managed work allocation
  55. * @dev: Device which lifetime work is bound to
  56. * @w: Work to be added (and automatically cancelled)
  57. * @worker: Worker function
  58. *
  59. * Initialize work which is automatically cancelled when driver is detached.
  60. * A few drivers need to queue work which must be cancelled before driver
  61. * is detached to avoid accessing removed resources.
  62. * devm_work_autocancel() can be used to omit the explicit
  63. * cancelleation when driver is detached.
  64. */
  65. static inline int devm_work_autocancel(struct device *dev,
  66. struct work_struct *w,
  67. work_func_t worker)
  68. {
  69. INIT_WORK(w, worker);
  70. return devm_add_action(dev, devm_work_drop, w);
  71. }
  72. #endif