Commit 321a1b30 authored by Egbert Eich's avatar Egbert Eich Committed by Daniel Vetter

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: default avatarEgbert Eich <eich@suse.de>
Reviewed-by: default avatarJani Nikula <jani.nikula@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 142e2398
...@@ -541,6 +541,21 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, ...@@ -541,6 +541,21 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
crtc); 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. * Handle hotplug events outside the interrupt handler proper.
*/ */
...@@ -557,6 +572,7 @@ static void i915_hotplug_work_func(struct work_struct *work) ...@@ -557,6 +572,7 @@ static void i915_hotplug_work_func(struct work_struct *work)
struct drm_connector *connector; struct drm_connector *connector;
unsigned long irqflags; unsigned long irqflags;
bool hpd_disabled = false; bool hpd_disabled = false;
bool changed = false;
u32 hpd_event_bits; u32 hpd_event_bits;
/* HPD irq before everything is fully set up. */ /* HPD irq before everything is fully set up. */
...@@ -600,14 +616,20 @@ static void i915_hotplug_work_func(struct work_struct *work) ...@@ -600,14 +616,20 @@ static void i915_hotplug_work_func(struct work_struct *work)
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head) list_for_each_entry(connector, &mode_config->connector_list, head) {
if (intel_encoder->hot_plug) intel_connector = to_intel_connector(connector);
intel_encoder->hot_plug(intel_encoder); 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); mutex_unlock(&mode_config->mutex);
/* Just fire off a uevent and let userspace tell us what to do */ if (changed)
drm_helper_hpd_irq_event(dev); drm_kms_helper_hotplug_event(dev);
} }
static void ironlake_handle_rps_change(struct drm_device *dev) static void ironlake_handle_rps_change(struct drm_device *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment