aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2009-09-15 16:57:37 -0400
committerEric Anholt <eric@anholt.net>2009-11-05 17:47:09 -0500
commit03f77ea5972e6a2363152aec692744cac824daba (patch)
treead63609747a62f22f2117c62bce38f17532f72ed /drivers/gpu/drm/i915/intel_display.c
parent5a5a0c64a99d7542c48c99d1a8bbb49e665842be (diff)
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)
1784static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) 1784static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
1785{ 1785{
1786 struct intel_overlay *overlay; 1786 struct intel_overlay *overlay;
1787 int ret;
1787 1788
1788 if (!enable && intel_crtc->overlay) { 1789 if (!enable && intel_crtc->overlay) {
1789 overlay = intel_crtc->overlay; 1790 overlay = intel_crtc->overlay;
1790 mutex_lock(&overlay->dev->struct_mutex); 1791 mutex_lock(&overlay->dev->struct_mutex);
1791 intel_overlay_switch_off(overlay); 1792 for (;;) {
1793 ret = intel_overlay_switch_off(overlay);
1794 if (ret == 0)
1795 break;
1796
1797 ret = intel_overlay_recover_from_interrupt(overlay, 0);
1798 if (ret != 0) {
1799 /* overlay doesn't react anymore. Usually
1800 * results in a black screen and an unkillable
1801 * X server. */
1802 BUG();
1803 overlay->hw_wedged = HW_WEDGED;
1804 break;
1805 }
1806 }
1792 mutex_unlock(&overlay->dev->struct_mutex); 1807 mutex_unlock(&overlay->dev->struct_mutex);
1793 } 1808 }
1794 /* Let userspace switch the overlay on again. In most cases userspace 1809 /* Let userspace switch the overlay on again. In most cases userspace