aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c21
-rw-r--r--drivers/gpu/drm/drm_atomic_uapi.c21
2 files changed, 22 insertions, 20 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 20bd176138a0..e49b22381048 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -308,26 +308,6 @@ update_connector_routing(struct drm_atomic_state *state,
return 0;
}
- crtc_state = drm_atomic_get_new_crtc_state(state,
- new_connector_state->crtc);
- /*
- * For compatibility with legacy users, we want to make sure that
- * we allow DPMS On->Off modesets on unregistered connectors. Modesets
- * which would result in anything else must be considered invalid, to
- * avoid turning on new displays on dead connectors.
- *
- * Since the connector can be unregistered at any point during an
- * atomic check or commit, this is racy. But that's OK: all we care
- * about is ensuring that userspace can't do anything but shut off the
- * display on a connector that was destroyed after its been notified,
- * not before.
- */
- if (!READ_ONCE(connector->registered) && crtc_state->active) {
- DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] is not registered\n",
- connector->base.id, connector->name);
- return -EINVAL;
- }
-
funcs = connector->helper_private;
if (funcs->atomic_best_encoder)
@@ -372,6 +352,7 @@ update_connector_routing(struct drm_atomic_state *state,
set_best_encoder(state, new_connector_state, new_encoder);
+ crtc_state = drm_atomic_get_new_crtc_state(state, new_connector_state->crtc);
crtc_state->connectors_changed = true;
DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d:%s]\n",
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index d5b7f315098c..a22d6f269b07 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -299,6 +299,27 @@ drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
struct drm_connector *connector = conn_state->connector;
struct drm_crtc_state *crtc_state;
+ /*
+ * For compatibility with legacy users, we want to make sure that
+ * we allow DPMS On<->Off modesets on unregistered connectors, since
+ * legacy modesetting users will not be expecting these to fail. We do
+ * not however, want to allow legacy users to assign a connector
+ * that's been unregistered from sysfs to another CRTC, since doing
+ * this with a now non-existent connector could potentially leave us
+ * in an invalid state.
+ *
+ * Since the connector can be unregistered at any point during an
+ * atomic check or commit, this is racy. But that's OK: all we care
+ * about is ensuring that userspace can't use this connector for new
+ * configurations after it's been notified that the connector is no
+ * longer present.
+ */
+ if (!READ_ONCE(connector->registered) && crtc) {
+ DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] is not registered\n",
+ connector->base.id, connector->name);
+ return -EINVAL;
+ }
+
if (conn_state->crtc == crtc)
return 0;