diff options
author | Dave Airlie <airlied@redhat.com> | 2016-04-15 08:10:36 +0300 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-04-22 03:34:28 +0300 |
commit | d0f37cf62979e65558c1b7bd4d4c221c5281bae1 (patch) | |
tree | f2dc3655e89c07c096d5a4fd36efcff04109c3bf /drivers/gpu/drm | |
parent | 747a598ffa7dff499ee93d414b74a08af6ec657e (diff) | |
download | linux-d0f37cf62979e65558c1b7bd4d4c221c5281bae1.tar.xz |
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>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 72 |
1 files changed, 38 insertions, 34 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 158bdcaf93c4..8cee833edc6e 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -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); @@ -492,32 +522,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); |