diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2011-10-07 14:23:48 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-10-10 04:04:26 -0400 |
commit | d0d0a225e6ad43314c9aa7ea081f76adc5098ad4 (patch) | |
tree | 8f15ee7cb6c32f9c9970006d4d9a55549f764776 /drivers | |
parent | 5f0a26128d66ef81613fe923d5c288942844ccdc (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.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 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; |