mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 13:11:40 +00:00
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: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
6a719e0533
commit
5ef5f72feb
@ -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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @dev: DRM device
|
||||
@ -328,11 +303,20 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
|
||||
{
|
||||
struct drm_device *dev = fb->dev;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_mode_set set;
|
||||
int ret;
|
||||
|
||||
/* remove from any CRTC */
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
if (crtc->fb == fb)
|
||||
crtc->fb = NULL;
|
||||
if (crtc->fb == fb) {
|
||||
/* 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);
|
||||
@ -1511,7 +1495,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
|
||||
set.mode = mode;
|
||||
set.connectors = connector_set;
|
||||
set.num_connectors = crtc_req->count_connectors;
|
||||
set.fb =fb;
|
||||
set.fb = fb;
|
||||
ret = crtc->funcs->set_config(&set);
|
||||
|
||||
out:
|
||||
|
Loading…
Reference in New Issue
Block a user