mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 22:14:04 +02:00
Revert "drm/atomic_helper: Stop modesets on unregistered connectors harder"
This reverts commit72289dc23cwhich is commitde9f8eea5aupstream. It breaks the current drm abi and for Android devices, should not be an issue as modesetting isn't a big deal for them. Bug: 161946584 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I74a8e98a755dcd68a79a9fe6c50d92806cb7a1f2
This commit is contained in:
parent
08bed51f55
commit
1309a09163
|
|
@ -1706,6 +1706,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;
|
||||
|
||||
|
|
|
|||
|
|
@ -307,26 +307,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 (drm_connector_is_unregistered(connector) && 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)
|
||||
|
|
@ -371,6 +351,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",
|
||||
|
|
|
|||
|
|
@ -391,8 +391,7 @@ void drm_connector_cleanup(struct drm_connector *connector)
|
|||
/* The connector should have been removed from userspace long before
|
||||
* it is finally destroyed.
|
||||
*/
|
||||
if (WARN_ON(connector->registration_state ==
|
||||
DRM_CONNECTOR_REGISTERED))
|
||||
if (WARN_ON(connector->registered))
|
||||
drm_connector_unregister(connector);
|
||||
|
||||
if (connector->tile_group) {
|
||||
|
|
@ -449,7 +448,7 @@ int drm_connector_register(struct drm_connector *connector)
|
|||
return 0;
|
||||
|
||||
mutex_lock(&connector->mutex);
|
||||
if (connector->registration_state != DRM_CONNECTOR_INITIALIZING)
|
||||
if (connector->registered)
|
||||
goto unlock;
|
||||
|
||||
ret = drm_sysfs_connector_add(connector);
|
||||
|
|
@ -469,7 +468,7 @@ int drm_connector_register(struct drm_connector *connector)
|
|||
|
||||
drm_mode_object_register(connector->dev, &connector->base);
|
||||
|
||||
connector->registration_state = DRM_CONNECTOR_REGISTERED;
|
||||
connector->registered = true;
|
||||
goto unlock;
|
||||
|
||||
err_debugfs:
|
||||
|
|
@ -491,7 +490,7 @@ EXPORT_SYMBOL(drm_connector_register);
|
|||
void drm_connector_unregister(struct drm_connector *connector)
|
||||
{
|
||||
mutex_lock(&connector->mutex);
|
||||
if (connector->registration_state != DRM_CONNECTOR_REGISTERED) {
|
||||
if (!connector->registered) {
|
||||
mutex_unlock(&connector->mutex);
|
||||
return;
|
||||
}
|
||||
|
|
@ -502,7 +501,7 @@ void drm_connector_unregister(struct drm_connector *connector)
|
|||
drm_sysfs_connector_remove(connector);
|
||||
drm_debugfs_connector_remove(connector);
|
||||
|
||||
connector->registration_state = DRM_CONNECTOR_UNREGISTERED;
|
||||
connector->registered = false;
|
||||
mutex_unlock(&connector->mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_connector_unregister);
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
|
|||
pipe_config->pbn = mst_pbn;
|
||||
|
||||
/* Zombie connectors can't have VCPI slots */
|
||||
if (!drm_connector_is_unregistered(connector)) {
|
||||
if (READ_ONCE(connector->registered)) {
|
||||
slots = drm_dp_atomic_find_vcpi_slots(state,
|
||||
&intel_dp->mst_mgr,
|
||||
port,
|
||||
|
|
@ -317,7 +317,7 @@ static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector)
|
|||
struct edid *edid;
|
||||
int ret;
|
||||
|
||||
if (drm_connector_is_unregistered(connector))
|
||||
if (!READ_ONCE(connector->registered))
|
||||
return intel_connector_update_modes(connector, NULL);
|
||||
|
||||
edid = drm_dp_mst_get_edid(connector, &intel_dp->mst_mgr, intel_connector->port);
|
||||
|
|
@ -333,7 +333,7 @@ intel_dp_mst_detect(struct drm_connector *connector, bool force)
|
|||
struct intel_connector *intel_connector = to_intel_connector(connector);
|
||||
struct intel_dp *intel_dp = intel_connector->mst_port;
|
||||
|
||||
if (drm_connector_is_unregistered(connector))
|
||||
if (!READ_ONCE(connector->registered))
|
||||
return connector_status_disconnected;
|
||||
return drm_dp_mst_detect_port(connector, &intel_dp->mst_mgr,
|
||||
intel_connector->port);
|
||||
|
|
@ -376,7 +376,7 @@ intel_dp_mst_mode_valid(struct drm_connector *connector,
|
|||
int bpp = 24; /* MST uses fixed bpp */
|
||||
int max_rate, mode_rate, max_lanes, max_link_clock;
|
||||
|
||||
if (drm_connector_is_unregistered(connector))
|
||||
if (!READ_ONCE(connector->registered))
|
||||
return MODE_ERROR;
|
||||
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
|
|
|
|||
|
|
@ -82,53 +82,6 @@ enum drm_connector_status {
|
|||
connector_status_unknown = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum drm_connector_registration_status - userspace registration status for
|
||||
* a &drm_connector
|
||||
*
|
||||
* This enum is used to track the status of initializing a connector and
|
||||
* registering it with userspace, so that DRM can prevent bogus modesets on
|
||||
* connectors that no longer exist.
|
||||
*/
|
||||
enum drm_connector_registration_state {
|
||||
/**
|
||||
* @DRM_CONNECTOR_INITIALIZING: The connector has just been created,
|
||||
* but has yet to be exposed to userspace. There should be no
|
||||
* additional restrictions to how the state of this connector may be
|
||||
* modified.
|
||||
*/
|
||||
DRM_CONNECTOR_INITIALIZING = 0,
|
||||
|
||||
/**
|
||||
* @DRM_CONNECTOR_REGISTERED: The connector has been fully initialized
|
||||
* and registered with sysfs, as such it has been exposed to
|
||||
* userspace. There should be no additional restrictions to how the
|
||||
* state of this connector may be modified.
|
||||
*/
|
||||
DRM_CONNECTOR_REGISTERED = 1,
|
||||
|
||||
/**
|
||||
* @DRM_CONNECTOR_UNREGISTERED: The connector has either been exposed
|
||||
* to userspace and has since been unregistered and removed from
|
||||
* userspace, or the connector was unregistered before it had a chance
|
||||
* to be exposed to userspace (e.g. still in the
|
||||
* @DRM_CONNECTOR_INITIALIZING state). When a connector is
|
||||
* unregistered, there are additional restrictions to how its state
|
||||
* may be modified:
|
||||
*
|
||||
* - An unregistered connector may only have its DPMS changed from
|
||||
* On->Off. Once DPMS is changed to Off, it may not be switched back
|
||||
* to On.
|
||||
* - Modesets are not allowed on unregistered connectors, unless they
|
||||
* would result in disabling its assigned CRTCs. This means
|
||||
* disabling a CRTC on an unregistered connector is OK, but enabling
|
||||
* one is not.
|
||||
* - Removing a CRTC from an unregistered connector is OK, but new
|
||||
* CRTCs may never be assigned to an unregistered connector.
|
||||
*/
|
||||
DRM_CONNECTOR_UNREGISTERED = 2,
|
||||
};
|
||||
|
||||
enum subpixel_order {
|
||||
SubPixelUnknown = 0,
|
||||
SubPixelHorizontalRGB,
|
||||
|
|
@ -941,12 +894,10 @@ struct drm_connector {
|
|||
bool ycbcr_420_allowed;
|
||||
|
||||
/**
|
||||
* @registration_state: Is this connector initializing, exposed
|
||||
* (registered) with userspace, or unregistered?
|
||||
*
|
||||
* @registered: Is this connector exposed (registered) with userspace?
|
||||
* Protected by @mutex.
|
||||
*/
|
||||
enum drm_connector_registration_state registration_state;
|
||||
bool registered;
|
||||
|
||||
/**
|
||||
* @modes:
|
||||
|
|
@ -1325,24 +1276,6 @@ static inline void drm_connector_unreference(struct drm_connector *connector)
|
|||
drm_connector_put(connector);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_connector_is_unregistered - has the connector been unregistered from
|
||||
* userspace?
|
||||
* @connector: DRM connector
|
||||
*
|
||||
* Checks whether or not @connector has been unregistered from userspace.
|
||||
*
|
||||
* Returns:
|
||||
* True if the connector was unregistered, false if the connector is
|
||||
* registered or has not yet been registered with userspace.
|
||||
*/
|
||||
static inline bool
|
||||
drm_connector_is_unregistered(struct drm_connector *connector)
|
||||
{
|
||||
return READ_ONCE(connector->registration_state) ==
|
||||
DRM_CONNECTOR_UNREGISTERED;
|
||||
}
|
||||
|
||||
const char *drm_get_connector_status_name(enum drm_connector_status status);
|
||||
const char *drm_get_subpixel_order_name(enum subpixel_order order);
|
||||
const char *drm_get_dpms_name(int val);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user