aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
authorEgbert Eich <eich@suse.de>2013-04-11 10:00:26 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-04-23 08:25:06 -0400
commit321a1b3026ea194dd084cf3bda1e235b2986b0af (patch)
treeac95e40aec1a003359c9368910985319f5c1b992 /drivers/gpu/drm/i915/i915_irq.c
parent142e239849c800f9dc23f828762873073f612d3f (diff)
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>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index e37820199b26..7c81f0fb721a 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -541,6 +541,21 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
541 crtc); 541 crtc);
542} 542}
543 543
544static int intel_hpd_irq_event(struct drm_device *dev, struct drm_connector *connector)
545{
546 enum drm_connector_status old_status;
547
548 WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
549 old_status = connector->status;
550
551 connector->status = connector->funcs->detect(connector, false);
552 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
553 connector->base.id,
554 drm_get_connector_name(connector),
555 old_status, connector->status);
556 return (old_status != connector->status);
557}
558
544/* 559/*
545 * Handle hotplug events outside the interrupt handler proper. 560 * Handle hotplug events outside the interrupt handler proper.
546 */ 561 */
@@ -557,6 +572,7 @@ static void i915_hotplug_work_func(struct work_struct *work)
557 struct drm_connector *connector; 572 struct drm_connector *connector;
558 unsigned long irqflags; 573 unsigned long irqflags;
559 bool hpd_disabled = false; 574 bool hpd_disabled = false;
575 bool changed = false;
560 u32 hpd_event_bits; 576 u32 hpd_event_bits;
561 577
562 /* HPD irq before everything is fully set up. */ 578 /* HPD irq before everything is fully set up. */
@@ -600,14 +616,20 @@ static void i915_hotplug_work_func(struct work_struct *work)
600 616
601 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); 617 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
602 618
603 list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head) 619 list_for_each_entry(connector, &mode_config->connector_list, head) {
604 if (intel_encoder->hot_plug) 620 intel_connector = to_intel_connector(connector);
605 intel_encoder->hot_plug(intel_encoder); 621 intel_encoder = intel_connector->encoder;
606 622 if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
623 if (intel_encoder->hot_plug)
624 intel_encoder->hot_plug(intel_encoder);
625 if (intel_hpd_irq_event(dev, connector))
626 changed = true;
627 }
628 }
607 mutex_unlock(&mode_config->mutex); 629 mutex_unlock(&mode_config->mutex);
608 630
609 /* Just fire off a uevent and let userspace tell us what to do */ 631 if (changed)
610 drm_helper_hpd_irq_event(dev); 632 drm_kms_helper_hotplug_event(dev);
611} 633}
612 634
613static void ironlake_handle_rps_change(struct drm_device *dev) 635static void ironlake_handle_rps_change(struct drm_device *dev)