diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-04-11 14:26:55 +0000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-04-12 14:21:12 +1000 |
commit | 89ced125472b8551c65526934b7f6c733a6864fa (patch) | |
tree | 33fb230e4392878537e19a01d724b9a7a00eb313 | |
parent | 1baee58638fc58248625255f5c5fcdb987f11b1f (diff) | |
download | linux-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.c | 8 |
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; |