if (obj &&
            obj->type == DRM_MODE_OBJECT_BLOB)
                obj = NULL;
+
+       if (obj && obj->free_cb) {
+               if (!kref_get_unless_zero(&obj->refcount))
+                       obj = NULL;
+       }
        mutex_unlock(&dev->mode_config.idr_mutex);
 
        return obj;
 
        mutex_lock(&dev->mode_config.fb_lock);
        obj = _object_find(dev, id, DRM_MODE_OBJECT_FB);
-       if (obj) {
+       if (obj)
                fb = obj_to_fb(obj);
-               if (!kref_get_unless_zero(&fb->base.refcount))
-                       fb = NULL;
-       }
        mutex_unlock(&dev->mode_config.fb_lock);
 
        return fb;
 {
        struct drm_framebuffer *fb = NULL;
        struct drm_framebuffer *fbl = NULL;
-       struct drm_mode_object *obj;
        uint32_t *id = data;
        int found = 0;
 
        if (!drm_core_check_feature(dev, DRIVER_MODESET))
                return -EINVAL;
 
+       fb = drm_framebuffer_lookup(dev, *id);
+       if (!fb)
+               return -ENOENT;
+
        mutex_lock(&file_priv->fbs_lock);
-       mutex_lock(&dev->mode_config.fb_lock);
-       obj = _object_find(dev, *id, DRM_MODE_OBJECT_FB);
-       if (!obj)
-               goto fail_lookup;
-       fb = obj_to_fb(obj);
        list_for_each_entry(fbl, &file_priv->fbs, filp_head)
                if (fb == fbl)
                        found = 1;
-       if (!found)
-               goto fail_lookup;
+       if (!found) {
+               mutex_unlock(&file_priv->fbs_lock);
+               goto fail_unref;
+       }
 
        list_del_init(&fb->filp_head);
-       mutex_unlock(&dev->mode_config.fb_lock);
        mutex_unlock(&file_priv->fbs_lock);
 
+       /* we now own the reference that was stored in the fbs list */
        drm_framebuffer_unreference(fb);
 
-       return 0;
+       /* drop the reference we picked up in framebuffer lookup */
+       drm_framebuffer_unreference(fb);
 
-fail_lookup:
-       mutex_unlock(&dev->mode_config.fb_lock);
-       mutex_unlock(&file_priv->fbs_lock);
+       return 0;
 
+fail_unref:
+       drm_framebuffer_unreference(fb);
        return -ENOENT;
 }