From: Paulo Zanoni Date: Wed, 12 Jun 2013 20:27:25 +0000 (-0300) Subject: drm/i915: propagate errors from intel_dp_init_connector X-Git-Url: https://rtime.felk.cvut.cz/gitweb/linux-imx.git/commitdiff_plain/16c255335b0ec39b4e5e976f4b260978aeed5a68?hp=ed92f0b239ac971edc509169ae3d6955fbe0a188 drm/i915: propagate errors from intel_dp_init_connector 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 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 Reviewed-by: Zoltan Nyul Signed-off-by: Daniel Vetter --- diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 224ce25129ce..0f835d15c18b 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 30514e58269b..1a429cf55291 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 ffe9d35b37b4..9ddbe3b49fef 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -586,7 +586,7 @@ extern void 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);