diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2009-09-15 16:57:37 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-11-05 17:47:09 -0500 |
commit | 03f77ea5972e6a2363152aec692744cac824daba (patch) | |
tree | ad63609747a62f22f2117c62bce38f17532f72ed /drivers/gpu/drm/i915/intel_display.c | |
parent | 5a5a0c64a99d7542c48c99d1a8bbb49e665842be (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.c | 17 |
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) | |||
1784 | static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) | 1784 | static 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 |