Merge tag 'locks-v3.20-2' of git://git.samba.org/jlayton/linux
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / drm_atomic.c
index 1e38dfc8e462fde168de1d8316ff237a8e4f8568..c2e9c5283136bc62f9b4baf18f46d204c41bc6d9 100644 (file)
@@ -134,6 +134,7 @@ void drm_atomic_state_clear(struct drm_atomic_state *state)
 
                connector->funcs->atomic_destroy_state(connector,
                                                       state->connector_states[i]);
+               state->connector_states[i] = NULL;
        }
 
        for (i = 0; i < config->num_crtc; i++) {
@@ -144,6 +145,7 @@ void drm_atomic_state_clear(struct drm_atomic_state *state)
 
                crtc->funcs->atomic_destroy_state(crtc,
                                                  state->crtc_states[i]);
+               state->crtc_states[i] = NULL;
        }
 
        for (i = 0; i < config->num_total_plane; i++) {
@@ -154,6 +156,7 @@ void drm_atomic_state_clear(struct drm_atomic_state *state)
 
                plane->funcs->atomic_destroy_state(plane,
                                                   state->plane_states[i]);
+               state->plane_states[i] = NULL;
        }
 }
 EXPORT_SYMBOL(drm_atomic_state_clear);
@@ -241,7 +244,13 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
                struct drm_crtc_state *state, struct drm_property *property,
                uint64_t val)
 {
-       if (crtc->funcs->atomic_set_property)
+       struct drm_device *dev = crtc->dev;
+       struct drm_mode_config *config = &dev->mode_config;
+
+       /* FIXME: Mode prop is missing, which also controls ->enable. */
+       if (property == config->prop_active) {
+               state->active = val;
+       } else if (crtc->funcs->atomic_set_property)
                return crtc->funcs->atomic_set_property(crtc, state, property, val);
        return -EINVAL;
 }
@@ -282,6 +291,13 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
         *
         * TODO: Add generic modeset state checks once we support those.
         */
+
+       if (state->active && !state->enable) {
+               DRM_DEBUG_KMS("[CRTC:%d] active without enabled\n",
+                             crtc->base.id);
+               return -EINVAL;
+       }
+
        return 0;
 }
 
@@ -387,6 +403,8 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
                state->src_w = val;
        } else if (property == config->prop_src_h) {
                state->src_h = val;
+       } else if (property == config->rotation_property) {
+               state->rotation = val;
        } else if (plane->funcs->atomic_set_property) {
                return plane->funcs->atomic_set_property(plane, state,
                                property, val);
@@ -976,7 +994,8 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
                        if (!crtc)
                                continue;
 
-                       if (crtc_state->mode_changed) {
+                       if (crtc_state->mode_changed ||
+                           crtc_state->active_changed) {
                                DRM_DEBUG_KMS("[CRTC:%d] requires full modeset\n",
                                              crtc->base.id);
                                return -EINVAL;
@@ -1259,7 +1278,9 @@ retry:
                                goto fail;
                        }
 
-                       if (get_user(prop_value, prop_values_ptr + copied_props)) {
+                       if (copy_from_user(&prop_value,
+                                          prop_values_ptr + copied_props,
+                                          sizeof(prop_value))) {
                                ret = -EFAULT;
                                goto fail;
                        }