Merge branch 'for-linus' of git://git.kernel.dk/linux-block
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / gpu / drm / gma500 / cdv_intel_display.c
index 3cfd0931fbfb1ce41013475ef70c62343b8b4cd8..82430ad8ba623934fd74a3f12059c5d180c92fae 100644 (file)
@@ -1462,7 +1462,7 @@ static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc,
        size_t addr = 0;
        struct gtt_range *gt;
        struct drm_gem_object *obj;
-       int ret;
+       int ret = 0;
 
        /* if we want to turn of the cursor ignore width and height */
        if (!handle) {
@@ -1499,7 +1499,8 @@ static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc,
 
        if (obj->size < width * height * 4) {
                dev_dbg(dev->dev, "buffer is to small\n");
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto unref_cursor;
        }
 
        gt = container_of(obj, struct gtt_range, gem);
@@ -1508,7 +1509,7 @@ static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc,
        ret = psb_gtt_pin(gt);
        if (ret) {
                dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
-               return ret;
+               goto unref_cursor;
        }
 
        addr = gt->offset;      /* Or resource.start ??? */
@@ -1532,9 +1533,14 @@ static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc,
                                                        struct gtt_range, gem);
                psb_gtt_unpin(gt);
                drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-               psb_intel_crtc->cursor_obj = obj;
        }
-       return 0;
+
+       psb_intel_crtc->cursor_obj = obj;
+       return ret;
+
+unref_cursor:
+       drm_gem_object_unreference(obj);
+       return ret;
 }
 
 static int cdv_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
@@ -1750,6 +1756,19 @@ static void cdv_intel_crtc_destroy(struct drm_crtc *crtc)
        kfree(psb_intel_crtc);
 }
 
+static void cdv_intel_crtc_disable(struct drm_crtc *crtc)
+{
+       struct gtt_range *gt;
+       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+
+       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+
+       if (crtc->fb) {
+               gt = to_psb_fb(crtc->fb)->gtt;
+               psb_gtt_unpin(gt);
+       }
+}
+
 const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = {
        .dpms = cdv_intel_crtc_dpms,
        .mode_fixup = cdv_intel_crtc_mode_fixup,
@@ -1757,6 +1776,7 @@ const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = {
        .mode_set_base = cdv_intel_pipe_set_base,
        .prepare = cdv_intel_crtc_prepare,
        .commit = cdv_intel_crtc_commit,
+       .disable = cdv_intel_crtc_disable,
 };
 
 const struct drm_crtc_funcs cdv_intel_crtc_funcs = {