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

Revert "drm: kms_helper: don't lose hotplug event"

This reverts commit 160954b7bca43da7cd3cfbce310e6df919a8216e.

This was rearming the workqueue with a 0 timeout, causing
a WARN_ON, and possible loop.

Daniel writes:
"I've looked a bit into this and I think we need to have a separate
work struct for recovering these lost hotplug events since the
continuous self-rearming case is a real risk (e.g. if a connector
flip-flops all the time). At least I don't see a sane way to block out
re-arming with the current code in a simple way. So reverting the
offender seems like the right thing and I'll go back to the drawing
board for 3.12."

Signed-off-by: Dave Airlie <airlied@redhat.com>

+1 -32
+1 -31
drivers/gpu/drm/drm_crtc_helper.c
··· 122 122 int count = 0; 123 123 int mode_flags = 0; 124 124 bool verbose_prune = true; 125 - enum drm_connector_status old_status; 126 125 127 126 DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, 128 127 drm_get_connector_name(connector)); ··· 137 138 if (connector->funcs->force) 138 139 connector->funcs->force(connector); 139 140 } else { 140 - old_status = connector->status; 141 - 142 141 connector->status = connector->funcs->detect(connector, true); 143 - 144 - /* 145 - * Normally either the driver's hpd code or the poll loop should 146 - * pick up any changes and fire the hotplug event. But if 147 - * userspace sneaks in a probe, we might miss a change. Hence 148 - * check here, and if anything changed start the hotplug code. 149 - */ 150 - if (old_status != connector->status) { 151 - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n", 152 - connector->base.id, 153 - drm_get_connector_name(connector), 154 - old_status, connector->status); 155 - 156 - /* 157 - * The hotplug event code might call into the fb 158 - * helpers, and so expects that we do not hold any 159 - * locks. Fire up the poll struct instead, it will 160 - * disable itself again. 161 - */ 162 - dev->mode_config.delayed_event = true; 163 - schedule_delayed_work(&dev->mode_config.output_poll_work, 164 - 0); 165 - } 166 142 } 167 143 168 144 /* Re-enable polling in case the global poll config changed. */ ··· 985 1011 struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work); 986 1012 struct drm_connector *connector; 987 1013 enum drm_connector_status old_status; 988 - bool repoll = false, changed; 989 - 990 - /* Pick up any changes detected by the probe functions. */ 991 - changed = dev->mode_config.delayed_event; 992 - dev->mode_config.delayed_event = false; 1014 + bool repoll = false, changed = false; 993 1015 994 1016 if (!drm_kms_helper_poll) 995 1017 return;
-1
include/drm/drm_crtc.h
··· 811 811 /* output poll support */ 812 812 bool poll_enabled; 813 813 bool poll_running; 814 - bool delayed_event; 815 814 struct delayed_work output_poll_work; 816 815 817 816 /* pointers to standard properties */