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