1c6603c74SDaniel Vetter // SPDX-License-Identifier: GPL-2.0 2c6603c74SDaniel Vetter 3c6603c74SDaniel Vetter #ifndef _DRM_MANAGED_H_ 4c6603c74SDaniel Vetter #define _DRM_MANAGED_H_ 5c6603c74SDaniel Vetter 6c6603c74SDaniel Vetter #include <linux/gfp.h> 7c23d686fSDaniel Vetter #include <linux/overflow.h> 8c6603c74SDaniel Vetter #include <linux/types.h> 9c6603c74SDaniel Vetter 10c6603c74SDaniel Vetter struct drm_device; 11*e13f13e0SThomas Zimmermann struct mutex; 12c6603c74SDaniel Vetter 13c6603c74SDaniel Vetter typedef void (*drmres_release_t)(struct drm_device *dev, void *res); 14c6603c74SDaniel Vetter 159e1ed9fbSDaniel Vetter /** 169e1ed9fbSDaniel Vetter * drmm_add_action - add a managed release action to a &drm_device 179e1ed9fbSDaniel Vetter * @dev: DRM device 189e1ed9fbSDaniel Vetter * @action: function which should be called when @dev is released 199e1ed9fbSDaniel Vetter * @data: opaque pointer, passed to @action 209e1ed9fbSDaniel Vetter * 219e1ed9fbSDaniel Vetter * This function adds the @release action with optional parameter @data to the 229e1ed9fbSDaniel Vetter * list of cleanup actions for @dev. The cleanup actions will be run in reverse 239e1ed9fbSDaniel Vetter * order in the final drm_dev_put() call for @dev. 249e1ed9fbSDaniel Vetter */ 25c6603c74SDaniel Vetter #define drmm_add_action(dev, action, data) \ 26c6603c74SDaniel Vetter __drmm_add_action(dev, action, data, #action) 27c6603c74SDaniel Vetter 28c6603c74SDaniel Vetter int __must_check __drmm_add_action(struct drm_device *dev, 29c6603c74SDaniel Vetter drmres_release_t action, 30c6603c74SDaniel Vetter void *data, const char *name); 31c6603c74SDaniel Vetter 329e1ed9fbSDaniel Vetter /** 339e1ed9fbSDaniel Vetter * drmm_add_action_or_reset - add a managed release action to a &drm_device 349e1ed9fbSDaniel Vetter * @dev: DRM device 359e1ed9fbSDaniel Vetter * @action: function which should be called when @dev is released 369e1ed9fbSDaniel Vetter * @data: opaque pointer, passed to @action 379e1ed9fbSDaniel Vetter * 389e1ed9fbSDaniel Vetter * Similar to drmm_add_action(), with the only difference that upon failure 399e1ed9fbSDaniel Vetter * @action is directly called for any cleanup work necessary on failures. 409e1ed9fbSDaniel Vetter */ 41f96306f9SDaniel Vetter #define drmm_add_action_or_reset(dev, action, data) \ 42f96306f9SDaniel Vetter __drmm_add_action_or_reset(dev, action, data, #action) 43f96306f9SDaniel Vetter 44f96306f9SDaniel Vetter int __must_check __drmm_add_action_or_reset(struct drm_device *dev, 45f96306f9SDaniel Vetter drmres_release_t action, 46f96306f9SDaniel Vetter void *data, const char *name); 47f96306f9SDaniel Vetter 48c6603c74SDaniel Vetter void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc; 499e1ed9fbSDaniel Vetter 509e1ed9fbSDaniel Vetter /** 519e1ed9fbSDaniel Vetter * drmm_kzalloc - &drm_device managed kzalloc() 529e1ed9fbSDaniel Vetter * @dev: DRM device 539e1ed9fbSDaniel Vetter * @size: size of the memory allocation 549e1ed9fbSDaniel Vetter * @gfp: GFP allocation flags 559e1ed9fbSDaniel Vetter * 569e1ed9fbSDaniel Vetter * This is a &drm_device managed version of kzalloc(). The allocated memory is 579e1ed9fbSDaniel Vetter * automatically freed on the final drm_dev_put(). Memory can also be freed 589e1ed9fbSDaniel Vetter * before the final drm_dev_put() by calling drmm_kfree(). 599e1ed9fbSDaniel Vetter */ 60c6603c74SDaniel Vetter static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp) 61c6603c74SDaniel Vetter { 62c6603c74SDaniel Vetter return drmm_kmalloc(dev, size, gfp | __GFP_ZERO); 63c6603c74SDaniel Vetter } 649e1ed9fbSDaniel Vetter 659e1ed9fbSDaniel Vetter /** 669e1ed9fbSDaniel Vetter * drmm_kmalloc_array - &drm_device managed kmalloc_array() 679e1ed9fbSDaniel Vetter * @dev: DRM device 689e1ed9fbSDaniel Vetter * @n: number of array elements to allocate 699e1ed9fbSDaniel Vetter * @size: size of array member 709e1ed9fbSDaniel Vetter * @flags: GFP allocation flags 719e1ed9fbSDaniel Vetter * 729e1ed9fbSDaniel Vetter * This is a &drm_device managed version of kmalloc_array(). The allocated 739e1ed9fbSDaniel Vetter * memory is automatically freed on the final drm_dev_put() and works exactly 749e1ed9fbSDaniel Vetter * like a memory allocation obtained by drmm_kmalloc(). 759e1ed9fbSDaniel Vetter */ 76c23d686fSDaniel Vetter static inline void *drmm_kmalloc_array(struct drm_device *dev, 77c23d686fSDaniel Vetter size_t n, size_t size, gfp_t flags) 78c23d686fSDaniel Vetter { 79c23d686fSDaniel Vetter size_t bytes; 80c23d686fSDaniel Vetter 81c23d686fSDaniel Vetter if (unlikely(check_mul_overflow(n, size, &bytes))) 82c23d686fSDaniel Vetter return NULL; 83c23d686fSDaniel Vetter 84c23d686fSDaniel Vetter return drmm_kmalloc(dev, bytes, flags); 85c23d686fSDaniel Vetter } 869e1ed9fbSDaniel Vetter 879e1ed9fbSDaniel Vetter /** 889e1ed9fbSDaniel Vetter * drmm_kcalloc - &drm_device managed kcalloc() 899e1ed9fbSDaniel Vetter * @dev: DRM device 909e1ed9fbSDaniel Vetter * @n: number of array elements to allocate 919e1ed9fbSDaniel Vetter * @size: size of array member 929e1ed9fbSDaniel Vetter * @flags: GFP allocation flags 939e1ed9fbSDaniel Vetter * 949e1ed9fbSDaniel Vetter * This is a &drm_device managed version of kcalloc(). The allocated memory is 959e1ed9fbSDaniel Vetter * automatically freed on the final drm_dev_put() and works exactly like a 969e1ed9fbSDaniel Vetter * memory allocation obtained by drmm_kmalloc(). 979e1ed9fbSDaniel Vetter */ 98c23d686fSDaniel Vetter static inline void *drmm_kcalloc(struct drm_device *dev, 99c23d686fSDaniel Vetter size_t n, size_t size, gfp_t flags) 100c23d686fSDaniel Vetter { 101c23d686fSDaniel Vetter return drmm_kmalloc_array(dev, n, size, flags | __GFP_ZERO); 102c23d686fSDaniel Vetter } 1039e1ed9fbSDaniel Vetter 104a5c71fdbSDaniel Vetter char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp); 105c6603c74SDaniel Vetter 106c6603c74SDaniel Vetter void drmm_kfree(struct drm_device *dev, void *data); 107c6603c74SDaniel Vetter 108*e13f13e0SThomas Zimmermann int drmm_mutex_init(struct drm_device *dev, struct mutex *lock); 109*e13f13e0SThomas Zimmermann 110c6603c74SDaniel Vetter #endif 111