drm/i915: implement interruptible sleeps in the overlay code
[sfrench/cifs-2.6.git] / drivers / gpu / drm / i915 / intel_display.c
index 6f818fadcbe3c39baaee845c34dbc058368e74eb..7d3309bc0fd2c5083ffc24f9f18b5b74d53e2ce7 100644 (file)
@@ -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