Commit 5ef5f72f authored by Dave Airlie's avatar Dave Airlie

drm/kms: teardown crtc correctly when fb is destroyed.

If userspace destroys a framebuffer that is in use on a crtc,
don't just null it out, tear down the crtc properly so the
hw gets turned off.
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 6a719e05
...@@ -257,31 +257,6 @@ void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type) ...@@ -257,31 +257,6 @@ void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type)
} }
EXPORT_SYMBOL(drm_mode_object_find); EXPORT_SYMBOL(drm_mode_object_find);
/**
* drm_crtc_from_fb - find the CRTC structure associated with an fb
* @dev: DRM device
* @fb: framebuffer in question
*
* LOCKING:
* Caller must hold mode_config lock.
*
* Find CRTC in the mode_config structure that matches @fb.
*
* RETURNS:
* Pointer to the CRTC or NULL if it wasn't found.
*/
struct drm_crtc *drm_crtc_from_fb(struct drm_device *dev,
struct drm_framebuffer *fb)
{
struct drm_crtc *crtc;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
if (crtc->fb == fb)
return crtc;
}
return NULL;
}
/** /**
* drm_framebuffer_init - initialize a framebuffer * drm_framebuffer_init - initialize a framebuffer
* @dev: DRM device * @dev: DRM device
...@@ -328,11 +303,20 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb) ...@@ -328,11 +303,20 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
{ {
struct drm_device *dev = fb->dev; struct drm_device *dev = fb->dev;
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_mode_set set;
int ret;
/* remove from any CRTC */ /* remove from any CRTC */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
if (crtc->fb == fb) if (crtc->fb == fb) {
crtc->fb = NULL; /* should turn off the crtc */
memset(&set, 0, sizeof(struct drm_mode_set));
set.crtc = crtc;
set.fb = NULL;
ret = crtc->funcs->set_config(&set);
if (ret)
DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc);
}
} }
drm_mode_object_put(dev, &fb->base); drm_mode_object_put(dev, &fb->base);
...@@ -1511,7 +1495,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, ...@@ -1511,7 +1495,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
set.mode = mode; set.mode = mode;
set.connectors = connector_set; set.connectors = connector_set;
set.num_connectors = crtc_req->count_connectors; set.num_connectors = crtc_req->count_connectors;
set.fb =fb; set.fb = fb;
ret = crtc->funcs->set_config(&set); ret = crtc->funcs->set_config(&set);
out: out:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment