summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_crtc.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-12-02 15:24:10 +0100
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-01-20 22:16:57 +0100
commitdac35663cef4ca7f572d430bb54b14be8f03cb10 (patch)
treed7b1c8b5717ff9efbf867535d493b308610af680 /drivers/gpu/drm/drm_crtc.c
parentdrm: only take the crtc lock for ->cursor_set (diff)
downloadlinux-dac35663cef4ca7f572d430bb54b14be8f03cb10.tar.xz
linux-dac35663cef4ca7f572d430bb54b14be8f03cb10.zip
drm: only take the crtc lock for ->cursor_move
->cursor_move uses mostly the same facilities in drivers as ->cursor_set, so pretty much nothing to fix up: - ast/gma500/i915: They all use per-crtc registers to update the cursor position. ast again touches the global cursor cache, but that's ok since there's only one crtc. - nouveau: nv50+ is again special, updates happen through the per-crtc channel (without pushbufs), so it's not protected by the new evo lock introduced earlier. But since this channel is per-crtc, we should be fine anyway. - radeon: A bit a mess: avivo asics need a workaround when both output pipes are enabled, which means it'll access the crtc list. Just reading that flag is ok though as long as radeon _always_ grabs all locks when changing the crtc configuration. Which means with the current scheme it cannot do an optimized modeset which only locks the relevant crtcs. This can be fixed though by introducing a bit of global state with separate locks and ensure in the modeset code that the cursor will be updated appropriately when enabling the 2nd pipe (on affected asics). - vmwgfx: I still don't understand what it's doing exactly, so apply the same trick for now. v2: Fixup unlocking for the error cases, spotted by Richard Wilbur. v3: Another error-case fixup. Reviewed-by: Rob Clark <rob@ti.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r--drivers/gpu/drm/drm_crtc.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 58fa69e5ff4c..4af6a3d5c9a1 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2039,34 +2039,32 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
if (!obj) {
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
- ret = -EINVAL;
- goto out;
+ return -EINVAL;
}
crtc = obj_to_crtc(obj);
+ mutex_lock(&crtc->mutex);
if (req->flags & DRM_MODE_CURSOR_BO) {
if (!crtc->funcs->cursor_set) {
ret = -ENXIO;
goto out;
}
/* Turns off the cursor if handle is 0 */
- mutex_lock(&crtc->mutex);
ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
req->width, req->height);
- mutex_unlock(&crtc->mutex);
}
if (req->flags & DRM_MODE_CURSOR_MOVE) {
if (crtc->funcs->cursor_move) {
- drm_modeset_lock_all(dev);
ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
- drm_modeset_unlock_all(dev);
} else {
ret = -EFAULT;
goto out;
}
}
out:
+ mutex_unlock(&crtc->mutex);
+
return ret;
}