From: Chris Wilson Date: Thu, 12 Aug 2010 12:50:28 +0000 (+0100) Subject: drm/i915/overlay: Pass interruptible to switch_off() X-Git-Url: http://drtracing.org/?a=commitdiff_plain;ds=sidebyside;h=5dcdbcb06badbdf2faa698bf3198e421a1e12840;p=deliverable%2Flinux.git drm/i915/overlay: Pass interruptible to switch_off() During DPMS we currently do not want the overlay code to be interruptible, so pass that information down and only take the uninterrruptible paths. Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter --- diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 120a9c0c2da6..e4fb5364a533 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2223,33 +2223,17 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) { - struct intel_overlay *overlay; - int ret; - if (!enable && intel_crtc->overlay) { - overlay = intel_crtc->overlay; - mutex_lock(&overlay->dev->struct_mutex); - for (;;) { - ret = intel_overlay_switch_off(overlay); - if (ret == 0) - break; + struct intel_overlay *overlay = intel_crtc->overlay; - ret = intel_overlay_recover_from_interrupt(overlay, 0); - if (ret != 0) { - /* overlay doesn't react anymore. Usually - * results in a black screen and an unkillable - * X server. */ - BUG(); - overlay->hw_wedged = HW_WEDGED; - break; - } - } + mutex_lock(&overlay->dev->struct_mutex); + (void) intel_overlay_switch_off(overlay, false); mutex_unlock(&overlay->dev->struct_mutex); } - /* Let userspace switch the overlay on again. In most cases userspace - * has to recompute where to put it anyway. */ - return; + /* Let userspace switch the overlay on again. In most cases userspace + * has to recompute where to put it anyway. + */ } static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 01ca494c6d87..44744537a0cf 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -287,9 +287,8 @@ extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane); extern void intel_setup_overlay(struct drm_device *dev); extern void intel_cleanup_overlay(struct drm_device *dev); -extern int intel_overlay_switch_off(struct intel_overlay *overlay); -extern int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, - bool interruptible); +extern int intel_overlay_switch_off(struct intel_overlay *overlay, + bool interruptible); extern int intel_overlay_put_image(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int intel_overlay_attrs(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 389690d36b59..3533355c5ea3 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -365,7 +365,8 @@ static int intel_overlay_continue(struct intel_overlay *overlay, } /* overlay needs to be disabled in OCMD reg */ -static int intel_overlay_off(struct intel_overlay *overlay) +static int intel_overlay_off(struct intel_overlay *overlay, + bool interruptible) { struct drm_device *dev = overlay->dev; u32 flip_addr = overlay->flip_addr; @@ -394,7 +395,7 @@ static int intel_overlay_off(struct intel_overlay *overlay) OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); ADVANCE_LP_RING(); - return intel_overlay_do_wait_request(overlay, request, true, + return intel_overlay_do_wait_request(overlay, request, interruptible, SWITCH_OFF); } @@ -427,8 +428,8 @@ static void intel_overlay_off_tail(struct intel_overlay *overlay) /* recover from an interruption due to a signal * We have to be careful not to repeat work forever an make forward progess. */ -int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, - bool interruptible) +static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, + bool interruptible) { struct drm_device *dev = overlay->dev; drm_i915_private_t *dev_priv = dev->dev_private; @@ -855,17 +856,19 @@ out_unpin: return ret; } -int intel_overlay_switch_off(struct intel_overlay *overlay) +int intel_overlay_switch_off(struct intel_overlay *overlay, + bool interruptible) { - int ret; struct overlay_registers *regs; struct drm_device *dev = overlay->dev; + int ret; BUG_ON(!mutex_is_locked(&dev->struct_mutex)); BUG_ON(!mutex_is_locked(&dev->mode_config.mutex)); if (overlay->hw_wedged) { - ret = intel_overlay_recover_from_interrupt(overlay, 1); + ret = intel_overlay_recover_from_interrupt(overlay, + interruptible); if (ret != 0) return ret; } @@ -881,7 +884,7 @@ int intel_overlay_switch_off(struct intel_overlay *overlay) regs->OCMD = 0; intel_overlay_unmap_regs(overlay, regs); - ret = intel_overlay_off(overlay); + ret = intel_overlay_off(overlay, interruptible); if (ret != 0) return ret; @@ -1097,7 +1100,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, mutex_lock(&dev->mode_config.mutex); mutex_lock(&dev->struct_mutex); - ret = intel_overlay_switch_off(overlay); + ret = intel_overlay_switch_off(overlay, true); mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->mode_config.mutex); @@ -1135,7 +1138,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, if (overlay->crtc != crtc) { struct drm_display_mode *mode = &crtc->base.mode; - ret = intel_overlay_switch_off(overlay); + ret = intel_overlay_switch_off(overlay, true); if (ret != 0) goto out_unlock;