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
This commit is contained in:
Michał Winiarski 2024-01-15 18:13:47 +01:00 committed by Maxime Ripard
parent aabf5c412f
commit 42d6196f6a
No known key found for this signature in database
GPG Key ID: E3EF0D6F671851C5
2 changed files with 43 additions and 0 deletions

View File

@ -176,6 +176,45 @@ int __drmm_add_action_or_reset(struct drm_device *dev,
} }
EXPORT_SYMBOL(__drmm_add_action_or_reset); 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() * drmm_kmalloc - &drm_device managed kmalloc()
* @dev: DRM device * @dev: DRM device

View File

@ -45,6 +45,10 @@ int __must_check __drmm_add_action_or_reset(struct drm_device *dev,
drmres_release_t action, drmres_release_t action,
void *data, const char *name); 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; void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
/** /**