[023/262] drm/radeon/kms: handle !force case in connector detect more gracefully

From: Greg KH
Date: Wed Nov 09 2011 - 22:20:32 EST


3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alex Deucher <alexander.deucher@xxxxxxx>

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@xxxxxxx>
Signed-off-by: Dave Airlie <airlied@xxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>

---
drivers/gpu/drm/radeon/radeon_connectors.c | 23 ++++++++++++++++++++---
drivers/gpu/drm/radeon/radeon_mode.h | 1 +
2 files changed, 21 insertions(+), 3 deletions(-)

--- 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 *
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 *
} 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 *
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->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 *
ret = encoder_funcs->detect(encoder, connector);
if (ret == connector_status_connected) {
radeon_connector->use_digital = false;
+ radeon_connector->detected_by_load = true;
}
}
break;
--- 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;


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/