From: Dave Airlie airl...@redhat.com
After thinking it over a lot it made more sense for the core to deal with
the output polling especially so it can notify X.
v2: drop plans for fake connector - per Michel's comments - fix X patch sent to
xorg-devel, add intel polled/hpd setting, add initial nouveau polled/hpd
settings.
v3: add config lock take inside polling, add intel/nouveau poll init/fini calls
Signed-off-by: Dave Airlie airl...@redhat.com
---
drivers/gpu/drm/Kconfig |2 +-
drivers/gpu/drm/drm_crtc_helper.c | 93
drivers/gpu/drm/drm_fb_helper.c | 123 ---
drivers/gpu/drm/i915/i915_dma.c |2 +-
drivers/gpu/drm/i915/i915_irq.c |3 +-
drivers/gpu/drm/i915/intel_crt.c|5 +
drivers/gpu/drm/i915/intel_display.c|2 +
drivers/gpu/drm/i915/intel_dp.c |2 +
drivers/gpu/drm/i915/intel_drv.h|2 +-
drivers/gpu/drm/i915/intel_fb.c | 14 ++--
drivers/gpu/drm/i915/intel_hdmi.c |1 +
drivers/gpu/drm/i915/intel_sdvo.c |2 +
drivers/gpu/drm/nouveau/nouveau_connector.c | 12 +++
drivers/gpu/drm/nouveau/nouveau_display.c |1 +
drivers/gpu/drm/nouveau/nouveau_fbcon.c | 14 +--
drivers/gpu/drm/nouveau/nouveau_fbcon.h |2 +-
drivers/gpu/drm/nouveau/nouveau_state.c |5 +-
drivers/gpu/drm/nouveau/nv50_display.c |2 +-
drivers/gpu/drm/radeon/radeon_connectors.c | 13 +++
drivers/gpu/drm/radeon/radeon_display.c | 10 ++
drivers/gpu/drm/radeon/radeon_fb.c | 15 +---
drivers/gpu/drm/radeon/radeon_irq_kms.c |5 +-
drivers/gpu/drm/radeon/radeon_mode.h|3 +-
include/drm/drm_crtc.h | 17
include/drm/drm_crtc_helper.h |3 +
include/drm/drm_fb_helper.h | 13 +---
26 files changed, 209 insertions(+), 157 deletions(-)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index be5aa7d..2583ddf 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -9,6 +9,7 @@ menuconfig DRM
depends on (AGP || AGP=n) PCI !EMULATED_CMPXCHG MMU
select I2C
select I2C_ALGOBIT
+ select SLOW_WORK
help
Kernel-level support for the Direct Rendering Infrastructure (DRI)
introduced in XFree86 4.0. If you say Y here, you need to select
@@ -23,7 +24,6 @@ config DRM_KMS_HELPER
depends on DRM
select FB
select FRAMEBUFFER_CONSOLE if !EMBEDDED
- select SLOW_WORK
help
FB and CRTC helpers for KMS drivers.
diff --git a/drivers/gpu/drm/drm_crtc_helper.c
b/drivers/gpu/drm/drm_crtc_helper.c
index b142ac2..13574b1 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -807,3 +807,96 @@ int drm_helper_resume_force_mode(struct drm_device *dev)
return 0;
}
EXPORT_SYMBOL(drm_helper_resume_force_mode);
+
+static struct slow_work_ops output_poll_ops;
+
+#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
+static void output_poll_execute(struct slow_work *work)
+{
+ struct delayed_slow_work *delayed_work = container_of(work, struct
delayed_slow_work, work);
+ struct drm_device *dev = container_of(delayed_work, struct drm_device,
mode_config.output_poll_slow_work);
+ struct drm_connector *connector;
+ enum drm_connector_status old_status, status;
+ bool repoll = false, changed = false;
+ int ret;
+
+ 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)
+ continue;
+
+ else if (connector-polled (DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT))
+ repoll = true;
+
+ old_status = connector-status;
+ /* 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))
+ continue;
+
+ status = connector-funcs-detect(connector);
+ if (old_status != status)
+ changed = true;
+ }
+
+ if (changed) {
+ /* send a uevent + call fbdev */
+ drm_sysfs_hotplug_event(dev);
+ if (dev-mode_config.funcs-output_poll_changed)
+ dev-mode_config.funcs-output_poll_changed(dev);
+ }
+
+ mutex_unlock(dev-mode_config.mutex);
+
+ if (repoll) {
+ ret = delayed_slow_work_enqueue(delayed_work,
DRM_OUTPUT_POLL_PERIOD);
+ if (ret)
+