Instead of reusing the polling code for hdp handling, split them up.
This has a few consequences:
- Don't touch HDP capable connectors in the poll loop.
- Only touch HDP capable connectors in drm_helper_hpd_irq_event.
- Run the HDP handling directly instead of going through a work item -
all callers already call drm_helper_hpd_irq_event from process
context without holding the mode_config mutex.
The ultimate goal is that drivers grow some smarts about which
connectors have received a hotplug event and only call the detect code
of that connector. But that's a second step.
Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch
---
drivers/gpu/drm/drm_crtc_helper.c | 39
1 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/drm_crtc_helper.c
b/drivers/gpu/drm/drm_crtc_helper.c
index 909a85c..b1d643d 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -942,9 +942,9 @@ static void output_poll_execute(struct work_struct *work)
mutex_lock(dev-mode_config.mutex);
list_for_each_entry(connector, dev-mode_config.connector_list, head) {
- /* if this is HPD or polled don't check it -
- TV out for instance */
- if (!connector-polled)
+ /* Ignore HDP capable connectors and connectors where we don't
+* want any hotplug detection at all for polling. */
+ if (!connector-polled || connector-polled ==
DRM_CONNECTOR_POLL_HPD)
continue;
else if (connector-polled (DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT))
@@ -954,8 +954,7 @@ static void output_poll_execute(struct work_struct *work)
/* if we are connected and don't want to poll for disconnect
skip it */
if (old_status == connector_status_connected
- !(connector-polled DRM_CONNECTOR_POLL_DISCONNECT)
- !(connector-polled DRM_CONNECTOR_POLL_HPD))
+ !(connector-polled DRM_CONNECTOR_POLL_DISCONNECT))
continue;
connector-status = connector-funcs-detect(connector, false);
@@ -1019,12 +1018,34 @@ EXPORT_SYMBOL(drm_kms_helper_poll_fini);
void drm_helper_hpd_irq_event(struct drm_device *dev)
{
+ struct drm_connector *connector;
+ enum drm_connector_status old_status;
+ bool changed = false;
+
if (!dev-mode_config.poll_enabled)
return;
- /* kill timer and schedule immediate execution, this doesn't block */
- cancel_delayed_work(dev-mode_config.output_poll_work);
- if (drm_kms_helper_poll)
- queue_delayed_work(system_nrt_wq,
dev-mode_config.output_poll_work, 0);
+ mutex_lock(dev-mode_config.mutex);
+ list_for_each_entry(connector, dev-mode_config.connector_list, head) {
+
+ /* Only handle HPD capable connectors. */
+ if (connector-polled != DRM_CONNECTOR_POLL_HPD)
+ continue;
+
+ old_status = connector-status;
+
+ connector-status = connector-funcs-detect(connector, false);
+ DRM_DEBUG_KMS([CONNECTOR:%d:%s] status updated from %d to
%d\n,
+ connector-base.id,
+ drm_get_connector_name(connector),
+ old_status, connector-status);
+ if (old_status != connector-status)
+ changed = true;
+ }
+
+ mutex_unlock(dev-mode_config.mutex);
+
+ if (changed)
+ drm_kms_helper_hotplug_event(dev);
}
EXPORT_SYMBOL(drm_helper_hpd_irq_event);
--
1.7.7.6
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel