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 | olio-linux-3.10-89ced125472b8551c65526934b7f6c733a6864fa.tar.xz olio-linux-3.10-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 59d6b9bf204..892ff9f9597 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;  |