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