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>
This commit is contained in:
Egbert Eich 2013-04-11 16:00:26 +02:00 committed by Daniel Vetter
parent 142e239849
commit 321a1b3026

View File

@ -541,6 +541,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.
*/
@ -557,6 +572,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. */
@ -600,14 +616,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)