drm_managed.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // SPDX-License-Identifier: GPL-2.0
  2. #ifndef _DRM_MANAGED_H_
  3. #define _DRM_MANAGED_H_
  4. #include <linux/gfp.h>
  5. #include <linux/overflow.h>
  6. #include <linux/types.h>
  7. struct drm_device;
  8. struct mutex;
  9. typedef void (*drmres_release_t)(struct drm_device *dev, void *res);
  10. /**
  11. * drmm_add_action - add a managed release action to a &drm_device
  12. * @dev: DRM device
  13. * @action: function which should be called when @dev is released
  14. * @data: opaque pointer, passed to @action
  15. *
  16. * This function adds the @release action with optional parameter @data to the
  17. * list of cleanup actions for @dev. The cleanup actions will be run in reverse
  18. * order in the final drm_dev_put() call for @dev.
  19. */
  20. #define drmm_add_action(dev, action, data) \
  21. __drmm_add_action(dev, action, data, #action)
  22. int __must_check __drmm_add_action(struct drm_device *dev,
  23. drmres_release_t action,
  24. void *data, const char *name);
  25. /**
  26. * drmm_add_action_or_reset - add a managed release action to a &drm_device
  27. * @dev: DRM device
  28. * @action: function which should be called when @dev is released
  29. * @data: opaque pointer, passed to @action
  30. *
  31. * Similar to drmm_add_action(), with the only difference that upon failure
  32. * @action is directly called for any cleanup work necessary on failures.
  33. */
  34. #define drmm_add_action_or_reset(dev, action, data) \
  35. __drmm_add_action_or_reset(dev, action, data, #action)
  36. int __must_check __drmm_add_action_or_reset(struct drm_device *dev,
  37. drmres_release_t action,
  38. void *data, const char *name);
  39. void drmm_release_action(struct drm_device *dev,
  40. drmres_release_t action,
  41. void *data);
  42. void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
  43. /**
  44. * drmm_kzalloc - &drm_device managed kzalloc()
  45. * @dev: DRM device
  46. * @size: size of the memory allocation
  47. * @gfp: GFP allocation flags
  48. *
  49. * This is a &drm_device managed version of kzalloc(). The allocated memory is
  50. * automatically freed on the final drm_dev_put(). Memory can also be freed
  51. * before the final drm_dev_put() by calling drmm_kfree().
  52. */
  53. static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)
  54. {
  55. return drmm_kmalloc(dev, size, gfp | __GFP_ZERO);
  56. }
  57. /**
  58. * drmm_kmalloc_array - &drm_device managed kmalloc_array()
  59. * @dev: DRM device
  60. * @n: number of array elements to allocate
  61. * @size: size of array member
  62. * @flags: GFP allocation flags
  63. *
  64. * This is a &drm_device managed version of kmalloc_array(). The allocated
  65. * memory is automatically freed on the final drm_dev_put() and works exactly
  66. * like a memory allocation obtained by drmm_kmalloc().
  67. */
  68. static inline void *drmm_kmalloc_array(struct drm_device *dev,
  69. size_t n, size_t size, gfp_t flags)
  70. {
  71. size_t bytes;
  72. if (unlikely(check_mul_overflow(n, size, &bytes)))
  73. return NULL;
  74. return drmm_kmalloc(dev, bytes, flags);
  75. }
  76. /**
  77. * drmm_kcalloc - &drm_device managed kcalloc()
  78. * @dev: DRM device
  79. * @n: number of array elements to allocate
  80. * @size: size of array member
  81. * @flags: GFP allocation flags
  82. *
  83. * This is a &drm_device managed version of kcalloc(). The allocated memory is
  84. * automatically freed on the final drm_dev_put() and works exactly like a
  85. * memory allocation obtained by drmm_kmalloc().
  86. */
  87. static inline void *drmm_kcalloc(struct drm_device *dev,
  88. size_t n, size_t size, gfp_t flags)
  89. {
  90. return drmm_kmalloc_array(dev, n, size, flags | __GFP_ZERO);
  91. }
  92. char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp);
  93. void drmm_kfree(struct drm_device *dev, void *data);
  94. void __drmm_mutex_release(struct drm_device *dev, void *res);
  95. /**
  96. * drmm_mutex_init - &drm_device-managed mutex_init()
  97. * @dev: DRM device
  98. * @lock: lock to be initialized
  99. *
  100. * Returns:
  101. * 0 on success, or a negative errno code otherwise.
  102. *
  103. * This is a &drm_device-managed version of mutex_init(). The initialized
  104. * lock is automatically destroyed on the final drm_dev_put().
  105. */
  106. #define drmm_mutex_init(dev, lock) ({ \
  107. mutex_init(lock); \
  108. drmm_add_action_or_reset(dev, __drmm_mutex_release, lock); \
  109. }) \
  110. void __drmm_workqueue_release(struct drm_device *device, void *wq);
  111. /**
  112. * drmm_alloc_ordered_workqueue - &drm_device managed alloc_ordered_workqueue()
  113. * @dev: DRM device
  114. * @fmt: printf format for the name of the workqueue
  115. * @flags: WQ_* flags (only WQ_FREEZABLE and WQ_MEM_RECLAIM are meaningful)
  116. * @args: args for @fmt
  117. *
  118. * This is a &drm_device-managed version of alloc_ordered_workqueue(). The
  119. * allocated workqueue is automatically destroyed on the final drm_dev_put().
  120. *
  121. * Returns: workqueue on success, negative ERR_PTR otherwise.
  122. */
  123. #define drmm_alloc_ordered_workqueue(dev, fmt, flags, args...) \
  124. ({ \
  125. struct workqueue_struct *wq = alloc_ordered_workqueue(fmt, flags, ##args); \
  126. wq ? ({ \
  127. int ret = drmm_add_action_or_reset(dev, __drmm_workqueue_release, wq); \
  128. ret ? ERR_PTR(ret) : wq; \
  129. }) : ERR_PTR(-ENOMEM); \
  130. })
  131. #endif