summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/display/intel_crt.c6
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c6
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdmi.c6
-rw-r--r--drivers/gpu/drm/i915/display/intel_hotplug.c22
4 files changed, 21 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c
index 809074758687..f66340b4caf0 100644
--- a/drivers/gpu/drm/i915/display/intel_crt.c
+++ b/drivers/gpu/drm/i915/display/intel_crt.c
@@ -907,12 +907,6 @@ load_detect:
out:
intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
- /*
- * Make sure the refs for power wells enabled during detect are
- * dropped to avoid a new detect cycle triggered by HPD polling.
- */
- intel_display_power_flush_work(dev_priv);
-
return status;
}
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 12bd2f322e62..964bf0551bdc 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4957,12 +4957,6 @@ out:
if (status != connector_status_connected && !intel_dp->is_mst)
intel_dp_unset_edid(intel_dp);
- /*
- * Make sure the refs for power wells enabled during detect are
- * dropped to avoid a new detect cycle triggered by HPD polling.
- */
- intel_display_power_flush_work(dev_priv);
-
if (!intel_dp_is_edp(intel_dp))
drm_dp_set_subconnector_property(connector,
status,
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 94a7e1537f42..9442bf43550e 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2522,12 +2522,6 @@ out:
if (status != connector_status_connected)
cec_notifier_phys_addr_invalidate(intel_hdmi->cec_notifier);
- /*
- * Make sure the refs for power wells enabled during detect are
- * dropped to avoid a new detect cycle triggered by HPD polling.
- */
- intel_display_power_flush_work(dev_priv);
-
return status;
}
diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c
index 0ff5ed46ae1e..dd7eb9fc7861 100644
--- a/drivers/gpu/drm/i915/display/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/display/intel_hotplug.c
@@ -25,6 +25,7 @@
#include "i915_drv.h"
#include "i915_irq.h"
+#include "intel_display_power.h"
#include "intel_display_types.h"
#include "intel_hotplug.h"
#include "intel_hotplug_irq.h"
@@ -638,11 +639,25 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
display.hotplug.poll_init_work);
struct drm_connector_list_iter conn_iter;
struct intel_connector *connector;
+ intel_wakeref_t wakeref;
bool enabled;
mutex_lock(&dev_priv->drm.mode_config.mutex);
enabled = READ_ONCE(dev_priv->display.hotplug.poll_enabled);
+ /*
+ * Prevent taking a power reference from this sequence of
+ * i915_hpd_poll_init_work() -> drm_helper_hpd_irq_event() ->
+ * connector detect which would requeue i915_hpd_poll_init_work()
+ * and so risk an endless loop of this same sequence.
+ */
+ if (!enabled) {
+ wakeref = intel_display_power_get(dev_priv,
+ POWER_DOMAIN_DISPLAY_CORE);
+ drm_WARN_ON(&dev_priv->drm,
+ READ_ONCE(dev_priv->display.hotplug.poll_enabled));
+ cancel_work(&dev_priv->display.hotplug.poll_init_work);
+ }
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
for_each_intel_connector_iter(connector, &conn_iter) {
@@ -669,8 +684,13 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
* We might have missed any hotplugs that happened while we were
* in the middle of disabling polling
*/
- if (!enabled)
+ if (!enabled) {
drm_helper_hpd_irq_event(&dev_priv->drm);
+
+ intel_display_power_put(dev_priv,
+ POWER_DOMAIN_DISPLAY_CORE,
+ wakeref);
+ }
}
/**