diff options
author | Michał Winiarski <michal.winiarski@intel.com> | 2024-01-15 20:13:47 +0300 |
---|---|---|
committer | Maxime Ripard <mripard@kernel.org> | 2024-01-17 12:38:39 +0300 |
commit | 42d6196f6a948aaecfedf72326925dcbd054f9db (patch) | |
tree | 9d5a9311532c760e3ee1c73e7c08fdee38bfaee6 | |
parent | aabf5c412f0435b676b668283d1aba1da10a32b9 (diff) | |
download | linux-42d6196f6a948aaecfedf72326925dcbd054f9db.tar.xz |
drm/managed: Add drmm_release_action
Similar to devres equivalent, it allows to call the "release" action
directly and remove the resource from the managed resources list.
Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240115171351.504264-2-michal.winiarski@intel.com
-rw-r--r-- | drivers/gpu/drm/drm_managed.c | 39 | ||||
-rw-r--r-- | include/drm/drm_managed.h | 4 |
2 files changed, 43 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c index bcd111404b12..7646f67bda4e 100644 --- a/drivers/gpu/drm/drm_managed.c +++ b/drivers/gpu/drm/drm_managed.c @@ -177,6 +177,45 @@ int __drmm_add_action_or_reset(struct drm_device *dev, EXPORT_SYMBOL(__drmm_add_action_or_reset); /** + * drmm_release_action - release a managed action from a &drm_device + * @dev: DRM device + * @action: function which would be called when @dev is released + * @data: opaque pointer, passed to @action + * + * This function calls the @action previously added by drmm_add_action() + * immediately. + * The @action is removed from the list of cleanup actions for @dev, + * which means that it won't be called in the final drm_dev_put(). + */ +void drmm_release_action(struct drm_device *dev, + drmres_release_t action, + void *data) +{ + struct drmres *dr_match = NULL, *dr; + unsigned long flags; + + spin_lock_irqsave(&dev->managed.lock, flags); + list_for_each_entry_reverse(dr, &dev->managed.resources, node.entry) { + if (dr->node.release == action) { + if (!data || (data && *(void **)dr->data == data)) { + dr_match = dr; + del_dr(dev, dr_match); + break; + } + } + } + spin_unlock_irqrestore(&dev->managed.lock, flags); + + if (WARN_ON(!dr_match)) + return; + + action(dev, data); + + free_dr(dr_match); +} +EXPORT_SYMBOL(drmm_release_action); + +/** * drmm_kmalloc - &drm_device managed kmalloc() * @dev: DRM device * @size: size of the memory allocation diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h index ad08f834af40..f547b09ca023 100644 --- a/include/drm/drm_managed.h +++ b/include/drm/drm_managed.h @@ -45,6 +45,10 @@ int __must_check __drmm_add_action_or_reset(struct drm_device *dev, drmres_release_t action, void *data, const char *name); +void drmm_release_action(struct drm_device *dev, + drmres_release_t action, + void *data); + void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc; /** |