From c592ab722f97fd45b686d1475d7ce35b218d7a77 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 2 Jul 2013 16:55:58 +0100 Subject: [PATCH] drm/i915: Listen for ACPI dock event and check for new hotplug connections References: https://bugs.freedesktop.org/show_bug.cgi?id=66494 Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 2 ++ drivers/gpu/drm/i915/i915_drv.c | 34 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_drv.h | 4 ++++ 3 files changed, 40 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9293528..baac647 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1352,6 +1352,7 @@ static int i915_load_modeset_init(struct drm_device *dev) * tiny window where we will loose hotplug notifactions. */ intel_fbdev_initial_config(dev); + intel_dock_register(dev); /* Only enable hotplug handling once the fbdev is fully set up. */ dev_priv->enable_hotplug_processing = true; @@ -1713,6 +1714,7 @@ int i915_driver_unload(struct drm_device *dev) io_mapping_free(dev_priv->gtt.mappable); arch_phys_wc_del(dev_priv->gtt.mtrr); + intel_dock_unregister(dev); acpi_video_unregister(); if (drm_core_check_feature(dev, DRIVER_MODESET)) { diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 1a425be..0fe2bee 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -37,6 +37,7 @@ #include #include #include +#include /* for ACPI dock notification */ static int i915_modeset __read_mostly = -1; module_param_named(modeset, i915_modeset, int, 0400); @@ -648,6 +649,39 @@ static void intel_resume_hotplug(struct drm_device *dev) drm_helper_hpd_irq_event(dev); } +static int intel_dock_notify(struct notifier_block *nb, + unsigned long event, + void *unused) +{ + struct drm_i915_private *dev_priv = + container_of(nb, struct drm_i915_private, dock_notifier); + + DRM_DEBUG_KMS("event=%lu\n", event); + intel_resume_hotplug(dev_priv->dev); + + return 0; +} + +void intel_dock_register(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + dev_priv->dock_notifier.notifier_call = intel_dock_notify; + if (register_dock_notifier(&dev_priv->dock_notifier)) + dev_priv->dock_notifier.notifier_call = NULL; +} + +void intel_dock_unregister(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (dev_priv->dock_notifier.notifier_call == NULL) + return; + + unregister_dock_notifier(&dev_priv->dock_notifier); + dev_priv->dock_notifier.notifier_call = NULL; +} + static int __i915_drm_thaw(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6978422..90e2351 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1069,6 +1069,7 @@ typedef struct drm_i915_private { u32 irq_mask; u32 gt_irq_mask; + struct notifier_block dock_notifier; struct work_struct hotplug_work; bool enable_hotplug_processing; struct { @@ -2036,6 +2037,9 @@ extern void intel_detect_pch(struct drm_device *dev); extern int intel_trans_dp_port_sel(struct drm_crtc *crtc); extern int intel_enable_rc6(const struct drm_device *dev); +void intel_dock_register(struct drm_device *dev); +void intel_dock_unregister(struct drm_device *dev); + extern bool i915_semaphore_is_enabled(struct drm_device *dev); int i915_reg_read_ioctl(struct drm_device *dev, void *data, struct drm_file *file); -- 1.8.3.1