Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d0d0a225 authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie
Browse files

drm/radeon/kms: handle !force case in connector detect more gracefully

When force == false, we don't do load detection in the connector
detect functions.  Unforunately, we also return the previous
connector state so we never get disconnect events for DVI-I, DVI-A,
or VGA.  Save whether we detected the monitor via load detection
previously and use that to determine whether we return the previous
state or not.

Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=41561



Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@kernel.org
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 5f0a2612
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
@@ -724,6 +724,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
		dret = radeon_ddc_probe(radeon_connector,
					radeon_connector->requires_extended_probe);
	if (dret) {
		radeon_connector->detected_by_load = false;
		if (radeon_connector->edid) {
			kfree(radeon_connector->edid);
			radeon_connector->edid = NULL;
@@ -750,12 +751,21 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
	} else {

		/* if we aren't forcing don't do destructive polling */
		if (!force)
		if (!force) {
			/* only return the previous status if we last
			 * detected a monitor via load.
			 */
			if (radeon_connector->detected_by_load)
				return connector->status;
			else
				return ret;
		}

		if (radeon_connector->dac_load_detect && encoder) {
			encoder_funcs = encoder->helper_private;
			ret = encoder_funcs->detect(encoder, connector);
			if (ret == connector_status_connected)
				radeon_connector->detected_by_load = true;
		}
	}

@@ -897,6 +907,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
		dret = radeon_ddc_probe(radeon_connector,
					radeon_connector->requires_extended_probe);
	if (dret) {
		radeon_connector->detected_by_load = false;
		if (radeon_connector->edid) {
			kfree(radeon_connector->edid);
			radeon_connector->edid = NULL;
@@ -964,7 +975,12 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
	    (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))
		goto out;

	/* if we aren't forcing don't do destructive polling */
	if (!force) {
		/* only return the previous status if we last
		 * detected a monitor via load.
		 */
		if (radeon_connector->detected_by_load)
			ret = connector->status;
		goto out;
	}
@@ -989,6 +1005,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
					ret = encoder_funcs->detect(encoder, connector);
					if (ret == connector_status_connected) {
						radeon_connector->use_digital = false;
						radeon_connector->detected_by_load = true;
					}
				}
				break;
+1 −0
Original line number Diff line number Diff line
@@ -447,6 +447,7 @@ struct radeon_connector {
	struct edid *edid;
	void *con_priv;
	bool dac_load_detect;
	bool detected_by_load; /* if the connection status was determined by load */
	uint16_t connector_object_id;
	struct radeon_hpd hpd;
	struct radeon_router router;