summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2009-09-15 22:57:37 +0200
committerEric Anholt <eric@anholt.net>2009-11-05 14:47:09 -0800
commit03f77ea5972e6a2363152aec692744cac824daba (patch)
treead63609747a62f22f2117c62bce38f17532f72ed /drivers/gpu/drm/i915/intel_display.c
parent5a5a0c64a99d7542c48c99d1a8bbb49e665842be (diff)
downloadlwn-03f77ea5972e6a2363152aec692744cac824daba.tar.gz
lwn-03f77ea5972e6a2363152aec692744cac824daba.zip
drm/i915: implement interruptible sleeps in the overlay code
At least for the common case of userspace ioctls. When doing a modeset operation, the wait is still uninterruptible. But considering that failing to turn off the overlay when switching off the crtc it's running on hangs the chip, it doesn't complicate matters _very_ much. There's just an unkillable X in addition to a black screen. BUG() about it and explain in the code. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6f818fadcbe3..7d3309bc0fd2 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1784,11 +1784,26 @@ static void igdng_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);
- intel_overlay_switch_off(overlay);
+ for (;;) {
+ ret = intel_overlay_switch_off(overlay);
+ if (ret == 0)
+ break;
+
+ 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_unlock(&overlay->dev->struct_mutex);
}
/* Let userspace switch the overlay on again. In most cases userspace