Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon: Poll for both connect/disconnect on analog connectors

DRM_CONNECTOR_POLL_CONNECT only enables polling for connections, not
disconnections. Because of this, we end up losing hotplug polling for
analog connectors once they get connected.

Easy way to reproduce:
- Grab a machine with a radeon GPU and a VGA port
- Plug a monitor into the VGA port, wait for it to update the connector
from disconnected to connected
- Disconnect the monitor on VGA, a hotplug event is never sent for the
removal of the connector.

Originally, only using DRM_CONNECTOR_POLL_CONNECT might have been a good
idea since doing VGA polling can sometimes result in having to mess with
the DAC voltages to figure out whether or not there's actually something
there since VGA doesn't have HPD. Doing this would have the potential of
showing visible artifacts on the screen every time we ran a poll while a
VGA display was connected. Luckily, radeon_vga_detect() only resorts to
this sort of polling if the poll is forced, and DRM's polling helper
doesn't force it's polls.

Additionally, this removes some assignments to connector->polled that
weren't actually doing anything.

Cc: stable@vger.kernel.org
Signed-off-by: Lyude <cpaul@redhat.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Lyude and committed by
Alex Deucher
14ff8d48 f1aa7e08

+9 -6
+9 -6
drivers/gpu/drm/radeon/radeon_connectors.c
··· 2064 2064 RADEON_OUTPUT_CSC_BYPASS); 2065 2065 /* no HPD on analog connectors */ 2066 2066 radeon_connector->hpd.hpd = RADEON_HPD_NONE; 2067 - connector->polled = DRM_CONNECTOR_POLL_CONNECT; 2068 2067 connector->interlace_allowed = true; 2069 2068 connector->doublescan_allowed = true; 2070 2069 break; ··· 2313 2314 } 2314 2315 2315 2316 if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { 2316 - if (i2c_bus->valid) 2317 - connector->polled = DRM_CONNECTOR_POLL_CONNECT; 2317 + if (i2c_bus->valid) { 2318 + connector->polled = DRM_CONNECTOR_POLL_CONNECT | 2319 + DRM_CONNECTOR_POLL_DISCONNECT; 2320 + } 2318 2321 } else 2319 2322 connector->polled = DRM_CONNECTOR_POLL_HPD; 2320 2323 ··· 2392 2391 1); 2393 2392 /* no HPD on analog connectors */ 2394 2393 radeon_connector->hpd.hpd = RADEON_HPD_NONE; 2395 - connector->polled = DRM_CONNECTOR_POLL_CONNECT; 2396 2394 connector->interlace_allowed = true; 2397 2395 connector->doublescan_allowed = true; 2398 2396 break; ··· 2476 2476 } 2477 2477 2478 2478 if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { 2479 - if (i2c_bus->valid) 2480 - connector->polled = DRM_CONNECTOR_POLL_CONNECT; 2479 + if (i2c_bus->valid) { 2480 + connector->polled = DRM_CONNECTOR_POLL_CONNECT | 2481 + DRM_CONNECTOR_POLL_DISCONNECT; 2482 + } 2481 2483 } else 2482 2484 connector->polled = DRM_CONNECTOR_POLL_HPD; 2485 + 2483 2486 connector->display_info.subpixel_order = subpixel_order; 2484 2487 drm_connector_register(connector); 2485 2488 }