aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2011-10-07 14:23:48 -0400
committerDave Airlie <airlied@redhat.com>2011-10-10 04:04:26 -0400
commitd0d0a225e6ad43314c9aa7ea081f76adc5098ad4 (patch)
tree8f15ee7cb6c32f9c9970006d4d9a55549f764776 /drivers
parent5f0a26128d66ef81613fe923d5c288942844ccdc (diff)
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: Alex Deucher <alexander.deucher@amd.com> Cc: stable@kernel.org Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c23
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h1
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 fbcf21dd2c23..9b5b3e4d2386 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -724,6 +724,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
724 dret = radeon_ddc_probe(radeon_connector, 724 dret = radeon_ddc_probe(radeon_connector,
725 radeon_connector->requires_extended_probe); 725 radeon_connector->requires_extended_probe);
726 if (dret) { 726 if (dret) {
727 radeon_connector->detected_by_load = false;
727 if (radeon_connector->edid) { 728 if (radeon_connector->edid) {
728 kfree(radeon_connector->edid); 729 kfree(radeon_connector->edid);
729 radeon_connector->edid = NULL; 730 radeon_connector->edid = NULL;
@@ -750,12 +751,21 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
750 } else { 751 } else {
751 752
752 /* if we aren't forcing don't do destructive polling */ 753 /* if we aren't forcing don't do destructive polling */
753 if (!force) 754 if (!force) {
754 return connector->status; 755 /* only return the previous status if we last
756 * detected a monitor via load.
757 */
758 if (radeon_connector->detected_by_load)
759 return connector->status;
760 else
761 return ret;
762 }
755 763
756 if (radeon_connector->dac_load_detect && encoder) { 764 if (radeon_connector->dac_load_detect && encoder) {
757 encoder_funcs = encoder->helper_private; 765 encoder_funcs = encoder->helper_private;
758 ret = encoder_funcs->detect(encoder, connector); 766 ret = encoder_funcs->detect(encoder, connector);
767 if (ret == connector_status_connected)
768 radeon_connector->detected_by_load = true;
759 } 769 }
760 } 770 }
761 771
@@ -897,6 +907,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
897 dret = radeon_ddc_probe(radeon_connector, 907 dret = radeon_ddc_probe(radeon_connector,
898 radeon_connector->requires_extended_probe); 908 radeon_connector->requires_extended_probe);
899 if (dret) { 909 if (dret) {
910 radeon_connector->detected_by_load = false;
900 if (radeon_connector->edid) { 911 if (radeon_connector->edid) {
901 kfree(radeon_connector->edid); 912 kfree(radeon_connector->edid);
902 radeon_connector->edid = NULL; 913 radeon_connector->edid = NULL;
@@ -964,8 +975,13 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
964 (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA)) 975 (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))
965 goto out; 976 goto out;
966 977
978 /* if we aren't forcing don't do destructive polling */
967 if (!force) { 979 if (!force) {
968 ret = connector->status; 980 /* only return the previous status if we last
981 * detected a monitor via load.
982 */
983 if (radeon_connector->detected_by_load)
984 ret = connector->status;
969 goto out; 985 goto out;
970 } 986 }
971 987
@@ -989,6 +1005,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
989 ret = encoder_funcs->detect(encoder, connector); 1005 ret = encoder_funcs->detect(encoder, connector);
990 if (ret == connector_status_connected) { 1006 if (ret == connector_status_connected) {
991 radeon_connector->use_digital = false; 1007 radeon_connector->use_digital = false;
1008 radeon_connector->detected_by_load = true;
992 } 1009 }
993 } 1010 }
994 break; 1011 break;
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 68820f5f6303..ed0178f03235 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -447,6 +447,7 @@ struct radeon_connector {
447 struct edid *edid; 447 struct edid *edid;
448 void *con_priv; 448 void *con_priv;
449 bool dac_load_detect; 449 bool dac_load_detect;
450 bool detected_by_load; /* if the connection status was determined by load */
450 uint16_t connector_object_id; 451 uint16_t connector_object_id;
451 struct radeon_hpd hpd; 452 struct radeon_hpd hpd;
452 struct radeon_router router; 453 struct radeon_router router;