mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-01 00:36:40 +09:00
drm/radeon/kms: handle !force case in connector detect more gracefully
commit d0d0a225e6 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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
e5edf27764
commit
f407df3970
@@ -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)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,8 +975,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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user