drm: review locking for drm_fb_helper_restore_fbdev_mode
... it's required. Fix up exynos and the cma helper, and add a corresponding WARN_ON to drm_fb_helper_restore_fbdev_mode. Note that tegra calls the fbdev cma helper restore function also from it's driver-load callback. Which is a bit against current practice, since usually the call is only from ->lastclose, and initial setup is done by drm_fb_helper_initial_config. Also add the relevant drm DocBook entry. v2: Add promised WARN to restore_fbdev_mode. Reviewed-by: Rob Clark <robdclark@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
		
							parent
							
								
									b9e5071386
								
							
						
					
					
						commit
						6aed8ec3f7
					
				| @ -68,9 +68,23 @@ void drm_modeset_unlock_all(struct drm_device *dev) | ||||
| 
 | ||||
| 	mutex_unlock(&dev->mode_config.mutex); | ||||
| } | ||||
| 
 | ||||
| EXPORT_SYMBOL(drm_modeset_unlock_all); | ||||
| 
 | ||||
| /**
 | ||||
|  * drm_warn_on_modeset_not_all_locked - check that all modeset locks are locked | ||||
|  * @dev: device | ||||
|  */ | ||||
| void drm_warn_on_modeset_not_all_locked(struct drm_device *dev) | ||||
| { | ||||
| 	struct drm_crtc *crtc; | ||||
| 
 | ||||
| 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | ||||
| 		WARN_ON(!mutex_is_locked(&crtc->mutex)); | ||||
| 
 | ||||
| 	WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); | ||||
| } | ||||
| EXPORT_SYMBOL(drm_warn_on_modeset_not_all_locked); | ||||
| 
 | ||||
| /* Avoid boilerplate.  I'm tired of typing. */ | ||||
| #define DRM_ENUM_NAME_FN(fnname, list)				\ | ||||
| 	char *fnname(int val)					\ | ||||
|  | ||||
| @ -389,8 +389,10 @@ EXPORT_SYMBOL_GPL(drm_fbdev_cma_fini); | ||||
|  */ | ||||
| void drm_fbdev_cma_restore_mode(struct drm_fbdev_cma *fbdev_cma) | ||||
| { | ||||
| 	drm_modeset_lock_all(dev); | ||||
| 	if (fbdev_cma) | ||||
| 		drm_fb_helper_restore_fbdev_mode(&fbdev_cma->fb_helper); | ||||
| 	drm_modeset_unlock_all(dev); | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(drm_fbdev_cma_restore_mode); | ||||
| 
 | ||||
|  | ||||
| @ -239,10 +239,21 @@ int drm_fb_helper_debug_leave(struct fb_info *info) | ||||
| } | ||||
| EXPORT_SYMBOL(drm_fb_helper_debug_leave); | ||||
| 
 | ||||
| /**
 | ||||
|  * drm_fb_helper_restore_fbdev_mode - restore fbdev configuration | ||||
|  * @fb_helper: fbcon to restore | ||||
|  * | ||||
|  * This should be called from driver's drm->lastclose callback when implementing | ||||
|  * an fbcon on top of kms using this helper. This ensures that the user isn't | ||||
|  * greeted with a black screen when e.g. X dies. | ||||
|  */ | ||||
| bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper) | ||||
| { | ||||
| 	bool error = false; | ||||
| 	int i, ret; | ||||
| 
 | ||||
| 	drm_warn_on_modeset_not_all_locked(fb_helper->dev); | ||||
| 
 | ||||
| 	for (i = 0; i < fb_helper->crtc_count; i++) { | ||||
| 		struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; | ||||
| 		ret = drm_mode_set_config_internal(mode_set); | ||||
|  | ||||
| @ -376,5 +376,7 @@ void exynos_drm_fbdev_restore_mode(struct drm_device *dev) | ||||
| 	if (!private || !private->fb_helper) | ||||
| 		return; | ||||
| 
 | ||||
| 	drm_modeset_lock_all(dev); | ||||
| 	drm_fb_helper_restore_fbdev_mode(private->fb_helper); | ||||
| 	drm_modeset_unlock_all(dev); | ||||
| } | ||||
|  | ||||
| @ -867,6 +867,7 @@ struct drm_prop_enum_list { | ||||
| 
 | ||||
| extern void drm_modeset_lock_all(struct drm_device *dev); | ||||
| extern void drm_modeset_unlock_all(struct drm_device *dev); | ||||
| extern void drm_warn_on_modeset_not_all_locked(struct drm_device *dev); | ||||
| 
 | ||||
| extern int drm_crtc_init(struct drm_device *dev, | ||||
| 			 struct drm_crtc *crtc, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user