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

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=41561Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@kernel.org
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 5f0a2612
...@@ -724,6 +724,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force) ...@@ -724,6 +724,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
dret = radeon_ddc_probe(radeon_connector, dret = radeon_ddc_probe(radeon_connector,
radeon_connector->requires_extended_probe); radeon_connector->requires_extended_probe);
if (dret) { if (dret) {
radeon_connector->detected_by_load = false;
if (radeon_connector->edid) { if (radeon_connector->edid) {
kfree(radeon_connector->edid); kfree(radeon_connector->edid);
radeon_connector->edid = NULL; radeon_connector->edid = NULL;
...@@ -750,12 +751,21 @@ radeon_vga_detect(struct drm_connector *connector, bool force) ...@@ -750,12 +751,21 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
} else { } else {
/* if we aren't forcing don't do destructive polling */ /* if we aren't forcing don't do destructive polling */
if (!force) if (!force) {
return connector->status; /* 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) { if (radeon_connector->dac_load_detect && encoder) {
encoder_funcs = encoder->helper_private; encoder_funcs = encoder->helper_private;
ret = encoder_funcs->detect(encoder, connector); 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) ...@@ -897,6 +907,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
dret = radeon_ddc_probe(radeon_connector, dret = radeon_ddc_probe(radeon_connector,
radeon_connector->requires_extended_probe); radeon_connector->requires_extended_probe);
if (dret) { if (dret) {
radeon_connector->detected_by_load = false;
if (radeon_connector->edid) { if (radeon_connector->edid) {
kfree(radeon_connector->edid); kfree(radeon_connector->edid);
radeon_connector->edid = NULL; radeon_connector->edid = NULL;
...@@ -964,8 +975,13 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) ...@@ -964,8 +975,13 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
(connector->connector_type == DRM_MODE_CONNECTOR_HDMIA)) (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))
goto out; goto out;
/* if we aren't forcing don't do destructive polling */
if (!force) { if (!force) {
ret = connector->status; /* only return the previous status if we last
* detected a monitor via load.
*/
if (radeon_connector->detected_by_load)
ret = connector->status;
goto out; goto out;
} }
...@@ -989,6 +1005,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) ...@@ -989,6 +1005,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
ret = encoder_funcs->detect(encoder, connector); ret = encoder_funcs->detect(encoder, connector);
if (ret == connector_status_connected) { if (ret == connector_status_connected) {
radeon_connector->use_digital = false; radeon_connector->use_digital = false;
radeon_connector->detected_by_load = true;
} }
} }
break; break;
......
...@@ -447,6 +447,7 @@ struct radeon_connector { ...@@ -447,6 +447,7 @@ struct radeon_connector {
struct edid *edid; struct edid *edid;
void *con_priv; void *con_priv;
bool dac_load_detect; bool dac_load_detect;
bool detected_by_load; /* if the connection status was determined by load */
uint16_t connector_object_id; uint16_t connector_object_id;
struct radeon_hpd hpd; struct radeon_hpd hpd;
struct radeon_router router; struct radeon_router router;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment