diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index be0f2d65db3a7340bad97430a0d798fb4a7ae757..0c6e25e979dd7eb4b0c7005656196824e6c0c181 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -305,6 +305,24 @@ void drm_fb_helper_restore(void) } EXPORT_SYMBOL(drm_fb_helper_restore); +static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper) +{ + struct drm_device *dev = fb_helper->dev; + struct drm_crtc *crtc; + int bound = 0, crtcs_bound = 0; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + if (crtc->fb) + crtcs_bound++; + if (crtc->fb == fb_helper->fb) + bound++; + } + + if (bound < crtcs_bound) + return false; + return true; +} + #ifdef CONFIG_MAGIC_SYSRQ static void drm_fb_helper_restore_work_fn(struct work_struct *ignored) { @@ -338,6 +356,11 @@ static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode) * For each CRTC in this fb, turn the connectors on/off. */ drm_modeset_lock_all(dev); + if (!drm_fb_helper_is_bound(fb_helper)) { + drm_modeset_unlock_all(dev); + return; + } + for (i = 0; i < fb_helper->crtc_count; i++) { crtc = fb_helper->crtc_info[i].mode_set.crtc; @@ -702,6 +725,11 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, int i; drm_modeset_lock_all(dev); + if (!drm_fb_helper_is_bound(fb_helper)) { + drm_modeset_unlock_all(dev); + return -EBUSY; + } + for (i = 0; i < fb_helper->crtc_count; i++) { crtc = fb_helper->crtc_info[i].mode_set.crtc; @@ -1369,21 +1397,12 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) struct drm_device *dev = fb_helper->dev; int count = 0; u32 max_width, max_height, bpp_sel; - int bound = 0, crtcs_bound = 0; - struct drm_crtc *crtc; if (!fb_helper->fb) return 0; drm_modeset_lock_all(dev); - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (crtc->fb) - crtcs_bound++; - if (crtc->fb == fb_helper->fb) - bound++; - } - - if (bound < crtcs_bound) { + if (!drm_fb_helper_is_bound(fb_helper)) { fb_helper->delayed_hotplug = true; drm_modeset_unlock_all(dev); return 0;