diff options
Diffstat (limited to 'drivers/gpu/drm/drm_framebuffer.c')
| -rw-r--r-- | drivers/gpu/drm/drm_framebuffer.c | 31 | 
1 files changed, 29 insertions, 2 deletions
| diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index b781601946db..63a70f285cce 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -862,11 +862,23 @@ EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_framebuffer_free);  int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,  			 const struct drm_framebuffer_funcs *funcs)  { +	unsigned int i;  	int ret; +	bool exists;  	if (WARN_ON_ONCE(fb->dev != dev || !fb->format))  		return -EINVAL; +	for (i = 0; i < fb->format->num_planes; i++) { +		if (drm_WARN_ON_ONCE(dev, fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i))) +			fb->internal_flags &= ~DRM_FRAMEBUFFER_HAS_HANDLE_REF(i); +		if (fb->obj[i]) { +			exists = drm_gem_object_handle_get_if_exists_unlocked(fb->obj[i]); +			if (exists) +				fb->internal_flags |= DRM_FRAMEBUFFER_HAS_HANDLE_REF(i); +		} +	} +  	INIT_LIST_HEAD(&fb->filp_head);  	fb->funcs = funcs; @@ -875,7 +887,7 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,  	ret = __drm_mode_object_add(dev, &fb->base, DRM_MODE_OBJECT_FB,  				    false, drm_framebuffer_free);  	if (ret) -		goto out; +		goto err;  	mutex_lock(&dev->mode_config.fb_lock);  	dev->mode_config.num_fb++; @@ -883,7 +895,16 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,  	mutex_unlock(&dev->mode_config.fb_lock);  	drm_mode_object_register(dev, &fb->base); -out: + +	return 0; + +err: +	for (i = 0; i < fb->format->num_planes; i++) { +		if (fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i)) { +			drm_gem_object_handle_put_unlocked(fb->obj[i]); +			fb->internal_flags &= ~DRM_FRAMEBUFFER_HAS_HANDLE_REF(i); +		} +	}  	return ret;  }  EXPORT_SYMBOL(drm_framebuffer_init); @@ -960,6 +981,12 @@ EXPORT_SYMBOL(drm_framebuffer_unregister_private);  void drm_framebuffer_cleanup(struct drm_framebuffer *fb)  {  	struct drm_device *dev = fb->dev; +	unsigned int i; + +	for (i = 0; i < fb->format->num_planes; i++) { +		if (fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i)) +			drm_gem_object_handle_put_unlocked(fb->obj[i]); +	}  	mutex_lock(&dev->mode_config.fb_lock);  	list_del(&fb->head); | 
