Actually there's a reason this stuff is there, and it's called commit e58f637bb96d5a0ae0919b9998b891d1ba7e47c9 Author: Chris Wilson <chris at chris-wilson.co.uk> Date: Fri Aug 20 09:13:36 2010 +0100 drm/kms: Add a module parameter to disable polling The idea has been that users can enable/disable polling at runtime. So the quick hack has been to just re-enable the output polling if xrandr asks for the latest state of the connectors. The problem with that hack is that when we force connectors to another state than what would be detected, we nicely ping-pong: - Userspace calls probe, gets the forced state, but polling starts again. - Polling notices that the state is actually different, wakes up userspace. - Repeat. As that commit already explains, the right fix would be to make the locking more fine-grained, so that hotplug detection on one output does not interfere with cursor updates on another crtc. But that is way too much work. So let's just safe this gross hack by caching the last-seen state of drm_kms_helper_poll for that driver, and only fire up the poll engine again if it changed from off to on. v2: Fixup the edge detection of drm_kms_helper_poll. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=49907 Tested-by: Tvrtko Ursulin <tvrtko.ursulin at onelan.co.uk> Signed-Off-by: Daniel Vetter <daniel.vetter at ffwll.ch> --- drivers/gpu/drm/drm_crtc_helper.c | 7 ++++++- include/drm/drm_crtc.h | 1 + 2 files changed, 7 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index db93e4d..f17953e 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -110,9 +110,14 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, } else if (connector->polled & DRM_CONNECTOR_POLL_FORCE || connector->status == connector_status_unknown) { connector->status = connector->funcs->detect(connector, true); - drm_kms_helper_poll_enable(dev); } + /* Re-enable polling in case the global poll config changed. */ + if (drm_kms_helper_poll != dev->mode_config.poll_running) + drm_kms_helper_poll_enable(dev); + + dev->mode_config.poll_running = drm_kms_helper_poll; + if (connector->status == connector_status_disconnected) { DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", connector->base.id, drm_get_connector_name(connector)); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 4417da2..fb21121 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -783,6 +783,7 @@ struct drm_mode_config { /* output poll support */ bool poll_enabled; + bool poll_running; struct delayed_work output_poll_work; /* pointers to standard properties */ -- 1.7.7.6