| From 8a85a19825edd287c64c597e0b1c51292cd2ceeb Mon Sep 17 00:00:00 2001 |
| From: Egbert Eich <eich@suse.de> |
| Date: Thu, 11 Apr 2013 16:00:26 +0200 |
| Subject: drm/i915: Only reprobe display on encoder which has received an HPD |
| event (v2) |
| |
| Instead of calling into the DRM helper layer to poll all connectors for |
| changes in connected displays probe only those connectors which have |
| received a hotplug event. |
| |
| v2: Resolved conflicts with changes in previous commits. |
| Renamed function and and added a WARN_ON() to warn of |
| intel_hpd_irq_event() from being called without |
| mode_config.mutex held - suggested by Jani Nikula. |
| |
| Signed-off-by: Egbert Eich <eich@suse.de> |
| Reviewed-by: Jani Nikula <jani.nikula@intel.com> |
| Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| (cherry picked from commit 321a1b3026ea194dd084cf3bda1e235b2986b0af) |
| Signed-off-by: Darren Hart <dvhart@linux.intel.com> |
| --- |
| drivers/gpu/drm/i915/i915_irq.c | 34 ++++++++++++++++++++++++++++------ |
| 1 file changed, 28 insertions(+), 6 deletions(-) |
| |
| diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c |
| index 66aa4dacd83f..1d42446e287c 100644 |
| --- a/drivers/gpu/drm/i915/i915_irq.c |
| +++ b/drivers/gpu/drm/i915/i915_irq.c |
| @@ -532,6 +532,21 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, |
| crtc); |
| } |
| |
| +static int intel_hpd_irq_event(struct drm_device *dev, struct drm_connector *connector) |
| +{ |
| + enum drm_connector_status old_status; |
| + |
| + WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); |
| + 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); |
| + return (old_status != connector->status); |
| +} |
| + |
| /* |
| * Handle hotplug events outside the interrupt handler proper. |
| */ |
| @@ -548,6 +563,7 @@ static void i915_hotplug_work_func(struct work_struct *work) |
| struct drm_connector *connector; |
| unsigned long irqflags; |
| bool hpd_disabled = false; |
| + bool changed = false; |
| u32 hpd_event_bits; |
| |
| /* HPD irq before everything is fully set up. */ |
| @@ -591,14 +607,20 @@ static void i915_hotplug_work_func(struct work_struct *work) |
| |
| spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
| |
| - list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head) |
| - if (intel_encoder->hot_plug) |
| - intel_encoder->hot_plug(intel_encoder); |
| - |
| + list_for_each_entry(connector, &mode_config->connector_list, head) { |
| + intel_connector = to_intel_connector(connector); |
| + intel_encoder = intel_connector->encoder; |
| + if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) { |
| + if (intel_encoder->hot_plug) |
| + intel_encoder->hot_plug(intel_encoder); |
| + if (intel_hpd_irq_event(dev, connector)) |
| + changed = true; |
| + } |
| + } |
| mutex_unlock(&mode_config->mutex); |
| |
| - /* Just fire off a uevent and let userspace tell us what to do */ |
| - drm_helper_hpd_irq_event(dev); |
| + if (changed) |
| + drm_kms_helper_hotplug_event(dev); |
| } |
| |
| static void ironlake_handle_rps_change(struct drm_device *dev) |
| -- |
| 1.8.5.rc3 |
| |