summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-04-11 14:26:55 +0000
committerDave Airlie <airlied@redhat.com>2013-04-12 14:21:12 +1000
commit89ced125472b8551c65526934b7f6c733a6864fa (patch)
tree33fb230e4392878537e19a01d724b9a7a00eb313
parent1baee58638fc58248625255f5c5fcdb987f11b1f (diff)
downloadlinux-stable-89ced125472b8551c65526934b7f6c733a6864fa.tar.gz
linux-stable-89ced125472b8551c65526934b7f6c733a6864fa.tar.bz2
linux-stable-89ced125472b8551c65526934b7f6c733a6864fa.zip
drm/fb-helper: Fix locking in drm_fb_helper_hotplug_event
Driver's and ->fill_modes functions are allowed to grab crtc mutexes (for e.g. load detect). Hence we need to first only grab the general kms mutex, and only in a second step grab all locks to do the modesets. This prevents a deadlock on my gm45 in the tv load detect code called by drm_helper_probe_single_connector_modes. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 59d6b9bf204b..892ff9f95975 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1544,10 +1544,10 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
if (!fb_helper->fb)
return 0;
- drm_modeset_lock_all(dev);
+ mutex_lock(&fb_helper->dev->mode_config.mutex);
if (!drm_fb_helper_is_bound(fb_helper)) {
fb_helper->delayed_hotplug = true;
- drm_modeset_unlock_all(dev);
+ mutex_unlock(&fb_helper->dev->mode_config.mutex);
return 0;
}
DRM_DEBUG_KMS("\n");
@@ -1558,9 +1558,11 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
count = drm_fb_helper_probe_connector_modes(fb_helper, max_width,
max_height);
+ mutex_unlock(&fb_helper->dev->mode_config.mutex);
+
+ drm_modeset_lock_all(dev);
drm_setup_crtcs(fb_helper);
drm_modeset_unlock_all(dev);
-
drm_fb_helper_set_par(fb_helper->fbdev);
return 0;