diff --git a/[refs] b/[refs] index 5dbedb27c344..5c09665e5b97 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d5d2636ed7990b93c7216f6a4d323f6b0eee08af +refs/heads/master: 29494c174dc4793ebd236aa522a2a1ed73b7180e diff --git a/trunk/drivers/gpu/drm/drm_crtc.c b/trunk/drivers/gpu/drm/drm_crtc.c index a82ec05dee23..b7c6168fae7e 100644 --- a/trunk/drivers/gpu/drm/drm_crtc.c +++ b/trunk/drivers/gpu/drm/drm_crtc.c @@ -46,7 +46,12 @@ */ void drm_modeset_lock_all(struct drm_device *dev) { + struct drm_crtc *crtc; + mutex_lock(&dev->mode_config.mutex); + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + mutex_lock_nest_lock(&crtc->mutex, &dev->mode_config.mutex); } EXPORT_SYMBOL(drm_modeset_lock_all); @@ -56,6 +61,11 @@ EXPORT_SYMBOL(drm_modeset_lock_all); */ void drm_modeset_unlock_all(struct drm_device *dev) { + struct drm_crtc *crtc; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + mutex_unlock(&crtc->mutex); + mutex_unlock(&dev->mode_config.mutex); } EXPORT_SYMBOL(drm_modeset_unlock_all); @@ -449,6 +459,8 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, crtc->invert_dimensions = false; drm_modeset_lock_all(dev); + mutex_init(&crtc->mutex); + mutex_lock_nest_lock(&crtc->mutex, &dev->mode_config.mutex); ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC); if (ret) diff --git a/trunk/include/drm/drm_crtc.h b/trunk/include/drm/drm_crtc.h index 9f0524d507f0..c89b1161f0be 100644 --- a/trunk/include/drm/drm_crtc.h +++ b/trunk/include/drm/drm_crtc.h @@ -390,6 +390,15 @@ struct drm_crtc { struct drm_device *dev; struct list_head head; + /** + * crtc mutex + * + * This provides a read lock for the overall crtc state (mode, dpms + * state, ...) and a write lock for everything which can be update + * without a full modeset (fb, cursor data, ...) + */ + struct mutex mutex; + struct drm_mode_object base; /* framebuffer the connector is currently bound to */