mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
drm/mode: move framebuffer reference into object.
This is the initial code to add references to some mode objects. In the future we need to start reference counting connectors so firstly I want to reorganise the code so the framebuffer ref counting uses the same paths. This patch shouldn't change any functionality, just moves the kref. [airlied: move kerneldoc as well] Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
747a598ffa
commit
d0f37cf629
@ -275,7 +275,8 @@ EXPORT_SYMBOL(drm_get_format_name);
|
||||
static int drm_mode_object_get_reg(struct drm_device *dev,
|
||||
struct drm_mode_object *obj,
|
||||
uint32_t obj_type,
|
||||
bool register_obj)
|
||||
bool register_obj,
|
||||
void (*obj_free_cb)(struct kref *kref))
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -288,6 +289,10 @@ static int drm_mode_object_get_reg(struct drm_device *dev,
|
||||
*/
|
||||
obj->id = ret;
|
||||
obj->type = obj_type;
|
||||
if (obj_free_cb) {
|
||||
obj->free_cb = obj_free_cb;
|
||||
kref_init(&obj->refcount);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&dev->mode_config.idr_mutex);
|
||||
|
||||
@ -311,7 +316,7 @@ static int drm_mode_object_get_reg(struct drm_device *dev,
|
||||
int drm_mode_object_get(struct drm_device *dev,
|
||||
struct drm_mode_object *obj, uint32_t obj_type)
|
||||
{
|
||||
return drm_mode_object_get_reg(dev, obj, obj_type, true);
|
||||
return drm_mode_object_get_reg(dev, obj, obj_type, true, NULL);
|
||||
}
|
||||
|
||||
static void drm_mode_object_register(struct drm_device *dev,
|
||||
@ -389,10 +394,35 @@ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_object_find);
|
||||
|
||||
void drm_mode_object_unreference(struct drm_mode_object *obj)
|
||||
{
|
||||
if (obj->free_cb) {
|
||||
DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount));
|
||||
kref_put(&obj->refcount, obj->free_cb);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_object_unreference);
|
||||
|
||||
/**
|
||||
* drm_mode_object_reference - incr the fb refcnt
|
||||
* @obj: mode_object
|
||||
*
|
||||
* This function operates only on refcounted objects.
|
||||
* This functions increments the object's refcount.
|
||||
*/
|
||||
void drm_mode_object_reference(struct drm_mode_object *obj)
|
||||
{
|
||||
if (obj->free_cb) {
|
||||
DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount));
|
||||
kref_get(&obj->refcount);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_object_reference);
|
||||
|
||||
static void drm_framebuffer_free(struct kref *kref)
|
||||
{
|
||||
struct drm_framebuffer *fb =
|
||||
container_of(kref, struct drm_framebuffer, refcount);
|
||||
container_of(kref, struct drm_framebuffer, base.refcount);
|
||||
struct drm_device *dev = fb->dev;
|
||||
|
||||
/*
|
||||
@ -430,12 +460,12 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev->mode_config.fb_lock);
|
||||
kref_init(&fb->refcount);
|
||||
INIT_LIST_HEAD(&fb->filp_head);
|
||||
fb->dev = dev;
|
||||
fb->funcs = funcs;
|
||||
|
||||
ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
|
||||
ret = drm_mode_object_get_reg(dev, &fb->base, DRM_MODE_OBJECT_FB,
|
||||
true, drm_framebuffer_free);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
@ -482,7 +512,7 @@ struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
|
||||
mutex_lock(&dev->mode_config.fb_lock);
|
||||
fb = __drm_framebuffer_lookup(dev, id);
|
||||
if (fb) {
|
||||
if (!kref_get_unless_zero(&fb->refcount))
|
||||
if (!kref_get_unless_zero(&fb->base.refcount))
|
||||
fb = NULL;
|
||||
}
|
||||
mutex_unlock(&dev->mode_config.fb_lock);
|
||||
@ -491,32 +521,6 @@ struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL(drm_framebuffer_lookup);
|
||||
|
||||
/**
|
||||
* drm_framebuffer_unreference - unref a framebuffer
|
||||
* @fb: framebuffer to unref
|
||||
*
|
||||
* This functions decrements the fb's refcount and frees it if it drops to zero.
|
||||
*/
|
||||
void drm_framebuffer_unreference(struct drm_framebuffer *fb)
|
||||
{
|
||||
DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, atomic_read(&fb->refcount.refcount));
|
||||
kref_put(&fb->refcount, drm_framebuffer_free);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_framebuffer_unreference);
|
||||
|
||||
/**
|
||||
* drm_framebuffer_reference - incr the fb refcnt
|
||||
* @fb: framebuffer
|
||||
*
|
||||
* This functions increments the fb's refcount.
|
||||
*/
|
||||
void drm_framebuffer_reference(struct drm_framebuffer *fb)
|
||||
{
|
||||
DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, atomic_read(&fb->refcount.refcount));
|
||||
kref_get(&fb->refcount);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_framebuffer_reference);
|
||||
|
||||
/**
|
||||
* drm_framebuffer_unregister_private - unregister a private fb from the lookup idr
|
||||
* @fb: fb to unregister
|
||||
@ -902,7 +906,7 @@ int drm_connector_init(struct drm_device *dev,
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
|
||||
ret = drm_mode_object_get_reg(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR, false);
|
||||
ret = drm_mode_object_get_reg(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR, false, NULL);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
@ -5971,7 +5975,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
|
||||
*/
|
||||
WARN_ON(!list_empty(&dev->mode_config.fb_list));
|
||||
list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
|
||||
drm_framebuffer_free(&fb->refcount);
|
||||
drm_framebuffer_free(&fb->base.refcount);
|
||||
}
|
||||
|
||||
ida_destroy(&dev->mode_config.connector_ida);
|
||||
|
@ -49,6 +49,8 @@ struct drm_mode_object {
|
||||
uint32_t id;
|
||||
uint32_t type;
|
||||
struct drm_object_properties *properties;
|
||||
struct kref refcount;
|
||||
void (*free_cb)(struct kref *kref);
|
||||
};
|
||||
|
||||
#define DRM_OBJECT_MAX_PROPERTY 24
|
||||
@ -223,8 +225,8 @@ struct drm_framebuffer {
|
||||
* should be deferred. In cases like this, the driver would like to
|
||||
* hold a ref to the fb even though it has already been removed from
|
||||
* userspace perspective.
|
||||
* The refcount is stored inside the mode object.
|
||||
*/
|
||||
struct kref refcount;
|
||||
/*
|
||||
* Place on the dev->mode_config.fb_list, access protected by
|
||||
* dev->mode_config.fb_lock.
|
||||
@ -2377,8 +2379,6 @@ extern int drm_framebuffer_init(struct drm_device *dev,
|
||||
const struct drm_framebuffer_funcs *funcs);
|
||||
extern struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
|
||||
uint32_t id);
|
||||
extern void drm_framebuffer_unreference(struct drm_framebuffer *fb);
|
||||
extern void drm_framebuffer_reference(struct drm_framebuffer *fb);
|
||||
extern void drm_framebuffer_remove(struct drm_framebuffer *fb);
|
||||
extern void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
|
||||
extern void drm_framebuffer_unregister_private(struct drm_framebuffer *fb);
|
||||
@ -2436,6 +2436,8 @@ extern int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
|
||||
int gamma_size);
|
||||
extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
|
||||
uint32_t id, uint32_t type);
|
||||
void drm_mode_object_reference(struct drm_mode_object *obj);
|
||||
void drm_mode_object_unreference(struct drm_mode_object *obj);
|
||||
|
||||
/* IOCTLs */
|
||||
extern int drm_mode_getresources(struct drm_device *dev,
|
||||
@ -2605,6 +2607,28 @@ static inline uint32_t drm_color_lut_extract(uint32_t user_input,
|
||||
return clamp_val(val, 0, max);
|
||||
}
|
||||
|
||||
/*
|
||||
* drm_framebuffer_reference - incr the fb refcnt
|
||||
* @fb: framebuffer
|
||||
*
|
||||
* This functions increments the fb's refcount.
|
||||
*/
|
||||
static inline void drm_framebuffer_reference(struct drm_framebuffer *fb)
|
||||
{
|
||||
drm_mode_object_reference(&fb->base);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_framebuffer_unreference - unref a framebuffer
|
||||
* @fb: framebuffer to unref
|
||||
*
|
||||
* This functions decrements the fb's refcount and frees it if it drops to zero.
|
||||
*/
|
||||
static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb)
|
||||
{
|
||||
drm_mode_object_unreference(&fb->base);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_framebuffer_read_refcount - read the framebuffer reference count.
|
||||
* @fb: framebuffer
|
||||
@ -2613,7 +2637,7 @@ static inline uint32_t drm_color_lut_extract(uint32_t user_input,
|
||||
*/
|
||||
static inline uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb)
|
||||
{
|
||||
return atomic_read(&fb->refcount.refcount);
|
||||
return atomic_read(&fb->base.refcount.refcount);
|
||||
}
|
||||
|
||||
/* Plane list iterator for legacy (overlay only) planes. */
|
||||
|
Loading…
Reference in New Issue
Block a user