diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2011-10-07 14:23:48 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-11-11 09:35:21 -0800 |
commit | 12bc1875cccdb601083183961533f64a0386370b (patch) | |
tree | 58a511fbe41ab2a5c22434010249536d875796fa /drivers/gpu/drm/radeon | |
parent | c271809eb4a52643cb5618678c81d682c20ad501 (diff) |
drm/radeon/kms: handle !force case in connector detect more gracefully
commit d0d0a225e6ad43314c9aa7ea081f76adc5098ad4 upstream.
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: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 1 |
2 files changed, 21 insertions, 3 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index c063da3dd86..404a220a570 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -715,6 +715,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; @@ -741,12 +742,21 @@ radeon_vga_detect(struct drm_connector *connector, bool force) } else { /* if we aren't forcing don't do destructive polling */ - if (!force) - return connector->status; + 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; } } @@ -888,6 +898,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; @@ -955,8 +966,13 @@ 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) { - 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; } @@ -980,6 +996,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; diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 68820f5f630..ed0178f0323 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -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; |