*/
 void intel_plane_destroy(struct drm_plane *plane)
 {
-       if (!plane)
-               return;
-
        drm_plane_cleanup(plane);
        kfree(to_intel_plane(plane));
 }
        .atomic_set_property = intel_plane_atomic_set_property,
        .atomic_duplicate_state = intel_plane_duplicate_state,
        .atomic_destroy_state = intel_plane_destroy_state,
-
 };
 
-static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
-                                                   int pipe)
+static struct intel_plane *
+intel_primary_plane_create(struct drm_device *dev, enum pipe pipe)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_plane *primary = NULL;
        int ret;
 
        primary = kzalloc(sizeof(*primary), GFP_KERNEL);
-       if (!primary)
+       if (!primary) {
+               ret = -ENOMEM;
                goto fail;
+       }
 
        state = intel_create_plane_state(&primary->base);
-       if (!state)
+       if (!state) {
+               ret = -ENOMEM;
                goto fail;
+       }
+
        primary->base.state = &state->base;
 
        primary->can_scale = false;
 
        drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs);
 
-       return &primary->base;
+       return primary;
 
 fail:
        kfree(state);
        kfree(primary);
 
-       return NULL;
+       return ERR_PTR(ret);
 }
 
 static int
        intel_crtc_update_cursor(crtc, state);
 }
 
-static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
-                                                  int pipe)
+static struct intel_plane *
+intel_cursor_plane_create(struct drm_device *dev, enum pipe pipe)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_plane *cursor = NULL;
        int ret;
 
        cursor = kzalloc(sizeof(*cursor), GFP_KERNEL);
-       if (!cursor)
+       if (!cursor) {
+               ret = -ENOMEM;
                goto fail;
+       }
 
        state = intel_create_plane_state(&cursor->base);
-       if (!state)
+       if (!state) {
+               ret = -ENOMEM;
                goto fail;
+       }
+
        cursor->base.state = &state->base;
 
        cursor->can_scale = false;
 
        drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs);
 
-       return &cursor->base;
+       return cursor;
 
 fail:
        kfree(state);
        kfree(cursor);
 
-       return NULL;
+       return ERR_PTR(ret);
 }
 
 static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc,
        scaler_state->scaler_id = -1;
 }
 
-static void intel_crtc_init(struct drm_device *dev, int pipe)
+static int intel_crtc_init(struct drm_device *dev, enum pipe pipe)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_crtc *intel_crtc;
        struct intel_crtc_state *crtc_state = NULL;
-       struct drm_plane *primary = NULL;
-       struct drm_plane *cursor = NULL;
+       struct intel_plane *primary = NULL;
+       struct intel_plane *cursor = NULL;
        int sprite, ret;
 
        intel_crtc = kzalloc(sizeof(*intel_crtc), GFP_KERNEL);
-       if (intel_crtc == NULL)
-               return;
+       if (!intel_crtc)
+               return -ENOMEM;
 
        crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
-       if (!crtc_state)
+       if (!crtc_state) {
+               ret = -ENOMEM;
                goto fail;
+       }
        intel_crtc->config = crtc_state;
        intel_crtc->base.state = &crtc_state->base;
        crtc_state->base.crtc = &intel_crtc->base;
        }
 
        primary = intel_primary_plane_create(dev, pipe);
-       if (!primary)
+       if (IS_ERR(primary)) {
+               ret = PTR_ERR(primary);
                goto fail;
+       }
 
        for_each_sprite(dev_priv, pipe, sprite) {
-               ret = intel_plane_init(dev, pipe, sprite);
-               if (ret)
-                       DRM_DEBUG_KMS("pipe %c sprite %c init failed: %d\n",
-                                     pipe_name(pipe), sprite_name(pipe, sprite), ret);
+               struct intel_plane *plane;
+
+               plane = intel_sprite_plane_create(dev, pipe, sprite);
+               if (!plane) {
+                       ret = PTR_ERR(plane);
+                       goto fail;
+               }
        }
 
        cursor = intel_cursor_plane_create(dev, pipe);
-       if (!cursor)
+       if (!cursor) {
+               ret = PTR_ERR(cursor);
                goto fail;
+       }
 
-       ret = drm_crtc_init_with_planes(dev, &intel_crtc->base, primary,
-                                       cursor, &intel_crtc_funcs,
+       ret = drm_crtc_init_with_planes(dev, &intel_crtc->base,
+                                       &primary->base, &cursor->base,
+                                       &intel_crtc_funcs,
                                        "pipe %c", pipe_name(pipe));
        if (ret)
                goto fail;
         * is hooked to pipe B. Hence we want plane A feeding pipe B.
         */
        intel_crtc->pipe = pipe;
-       intel_crtc->plane = pipe;
+       intel_crtc->plane = (enum plane) pipe;
        if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4) {
                DRM_DEBUG_KMS("swapping pipes & planes for FBC\n");
                intel_crtc->plane = !pipe;
        intel_color_init(&intel_crtc->base);
 
        WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe);
-       return;
+
+       return 0;
 
 fail:
-       intel_plane_destroy(primary);
-       intel_plane_destroy(cursor);
+       /*
+        * drm_mode_config_cleanup() will free up any
+        * crtcs/planes already initialized.
+        */
        kfree(crtc_state);
        kfree(intel_crtc);
+
+       return ret;
 }
 
 enum pipe intel_get_pipe_from_connector(struct intel_connector *connector)
        drm_modeset_acquire_fini(&ctx);
 }
 
-void intel_modeset_init(struct drm_device *dev)
+int intel_modeset_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct i915_ggtt *ggtt = &dev_priv->ggtt;
        intel_init_pm(dev);
 
        if (INTEL_INFO(dev)->num_pipes == 0)
-               return;
+               return 0;
 
        /*
         * There may be no VBT; and if the BIOS enabled SSC we can
                      INTEL_INFO(dev)->num_pipes > 1 ? "s" : "");
 
        for_each_pipe(dev_priv, pipe) {
-               intel_crtc_init(dev, pipe);
+               int ret;
+
+               ret = intel_crtc_init(dev, pipe);
+               if (ret) {
+                       drm_mode_config_cleanup(dev);
+                       return ret;
+               }
        }
 
        intel_update_czclk(dev_priv);
         * since the watermark calculation done here will use pstate->fb.
         */
        sanitize_watermarks(dev);
+
+       return 0;
 }
 
 static void intel_enable_pipe_a(struct drm_device *dev)