struct intel_encoder *encoder;
        bool storm_detected = false;
        bool queue_dig = false, queue_hp = false;
+       u32 long_hpd_pulse_mask = 0;
+       u32 short_hpd_pulse_mask = 0;
+       enum hpd_pin pin;
 
        if (!pin_mask)
                return;
 
        spin_lock(&dev_priv->irq_lock);
+
+       /*
+        * Determine whether ->hpd_pulse() exists for each pin, and
+        * whether we have a short or a long pulse. This is needed
+        * as each pin may have up to two encoders (HDMI and DP) and
+        * only the one of them (DP) will have ->hpd_pulse().
+        */
        for_each_intel_encoder(&dev_priv->drm, encoder) {
-               enum hpd_pin pin = encoder->hpd_pin;
                bool has_hpd_pulse = intel_encoder_has_hpd_pulse(encoder);
-               bool long_hpd = true;
+               enum port port = encoder->port;
+               bool long_hpd;
 
+               pin = encoder->hpd_pin;
                if (!(BIT(pin) & pin_mask))
                        continue;
 
-               if (has_hpd_pulse) {
-                       enum port port = encoder->port;
+               if (!has_hpd_pulse)
+                       continue;
 
-                       long_hpd = long_mask & BIT(pin);
+               long_hpd = long_mask & BIT(pin);
 
-                       DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", port_name(port),
-                                        long_hpd ? "long" : "short");
-                       queue_dig = true;
-                       if (long_hpd)
-                               dev_priv->hotplug.long_port_mask |= (1 << port);
-                       else
-                               dev_priv->hotplug.short_port_mask |= (1 << port);
+               DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", port_name(port),
+                                long_hpd ? "long" : "short");
+               queue_dig = true;
 
+               if (long_hpd) {
+                       long_hpd_pulse_mask |= BIT(pin);
+                       dev_priv->hotplug.long_port_mask |= BIT(port);
+               } else {
+                       short_hpd_pulse_mask |= BIT(pin);
+                       dev_priv->hotplug.short_port_mask |= BIT(port);
                }
+       }
+
+       /* Now process each pin just once */
+       for_each_hpd_pin(pin) {
+               bool long_hpd;
+
+               if (!(BIT(pin) & pin_mask))
+                       continue;
 
                if (dev_priv->hotplug.stats[pin].state == HPD_DISABLED) {
                        /*
                if (dev_priv->hotplug.stats[pin].state != HPD_ENABLED)
                        continue;
 
-               if (!has_hpd_pulse) {
+               /*
+                * Delegate to ->hpd_pulse() if one of the encoders for this
+                * pin has it, otherwise let the hotplug_work deal with this
+                * pin directly.
+                */
+               if (((short_hpd_pulse_mask | long_hpd_pulse_mask) & BIT(pin))) {
+                       long_hpd = long_hpd_pulse_mask & BIT(pin);
+               } else {
                        dev_priv->hotplug.event_bits |= BIT(pin);
+                       long_hpd = true;
                        queue_hp = true;
                }