From: Paulo Zanoni <paulo.r.zan...@intel.com>

In case we detect a "ghost eDP", intel_edp_init_connector frees both
the connector and encoder and then returns. On Haswell, intel_ddi_init
then tries to use the freed encoder on the HDMI initialization path
since the following commit:

commit 21a8e6a4853b2ed39fa4c5188a710f2cf1b92026
Author: Daniel Vetter <daniel.vet...@ffwll.ch>
Date:   Wed Apr 10 23:28:35 2013 +0200
    drm/i915: don't setup hdmi for port D edp in ddi_init

So now on intel_ddi_init we check for the "ghost eDP" case and return
without trying to initialize HDMI. This way we won't try to read the
freed "intel_encoder" struct in the next "if" statement.

Signed-off-by: Paulo Zanoni <paulo.r.zan...@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 3 ++-
 drivers/gpu/drm/i915/intel_dp.c  | 6 ++++--
 drivers/gpu/drm/i915/intel_drv.h | 2 +-
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 224ce25..0f835d1 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1356,7 +1356,8 @@ void intel_ddi_init(struct drm_device *dev, enum port 
port)
        intel_encoder->cloneable = false;
        intel_encoder->hot_plug = intel_ddi_hot_plug;
 
-       intel_dp_init_connector(intel_dig_port, dp_connector);
+       if (!intel_dp_init_connector(intel_dig_port, dp_connector))
+               return;
 
        if (intel_encoder->type != INTEL_OUTPUT_EDP) {
                hdmi_connector = kzalloc(sizeof(struct intel_connector),
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 90b01f5..46b3e3b 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3035,7 +3035,7 @@ static bool intel_edp_init_connector(struct intel_dp 
*intel_dp,
        return true;
 }
 
-void
+bool
 intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
                        struct intel_connector *intel_connector)
 {
@@ -3147,7 +3147,7 @@ intel_dp_init_connector(struct intel_digital_port 
*intel_dig_port,
        intel_dp_i2c_init(intel_dp, intel_connector, name);
 
        if (!intel_edp_init_connector(intel_dp, intel_connector))
-               return;
+               return false;
 
        intel_dp_add_properties(intel_dp, connector);
 
@@ -3159,6 +3159,8 @@ intel_dp_init_connector(struct intel_digital_port 
*intel_dig_port,
                u32 temp = I915_READ(PEG_BAND_GAP_DATA);
                I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
        }
+
+       return true;
 }
 
 void
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 02e5d65..d100bee 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -586,7 +586,7 @@ extern bool intel_lvds_init(struct drm_device *dev);
 extern bool intel_is_dual_link_lvds(struct drm_device *dev);
 extern void intel_dp_init(struct drm_device *dev, int output_reg,
                          enum port port);
-extern void intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
+extern bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
                                    struct intel_connector *intel_connector);
 extern void intel_dp_init_link_config(struct intel_dp *intel_dp);
 extern void intel_dp_start_link_train(struct intel_dp *intel_dp);
-- 
1.8.1.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to