mirror of https://gitee.com/openkylin/linux.git
drm/i915: fix the "ghost eDP" encoder unwind path
Because calling intel_dp_encoder_destroy inside intel_edp_init_connector is just wrong. This is the initialization path, so we should properly unwind all the initialization through the whole caller stack. On the intel_dp_encoder_destroy function we do the following: 1 - Call i2c_del_adapter 2 - Call drm_encoder_cleanup 3 - If edp: 3.1 - Cancel panel_vdd_work 3.2 - Call ironlake_panel_vdd_of_sync 4 - Free the encoder And here is how we unwind each specific step: 1 - We have intel_dp_init_connector -> intel_dp_i2c_init -> i2c_dp_aux_add_bus -> i2c_add_adapter, so we call i2c_del_dapter at intel_dp_init_connector 2 - Call it in the same function that called drm_encoder_init 3 - Call it in the same function that called INIT_DELAYED_WORK 4 - Free it in the same function that allocated it Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Zoltan Nyul <zoltan.nyul@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
b2f246a899
commit
15b1d171d8
|
@ -1357,6 +1357,8 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
|
|||
intel_encoder->hot_plug = intel_ddi_hot_plug;
|
||||
|
||||
if (!intel_dp_init_connector(intel_dig_port, dp_connector)) {
|
||||
drm_encoder_cleanup(encoder);
|
||||
kfree(intel_dig_port);
|
||||
kfree(dp_connector);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2986,7 +2986,6 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
|
|||
} else {
|
||||
/* if this fails, presume the device is a ghost */
|
||||
DRM_INFO("failed to retrieve link info, disabling eDP\n");
|
||||
intel_dp_encoder_destroy(&intel_dig_port->base.base);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3146,6 +3145,13 @@ 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)) {
|
||||
i2c_del_adapter(&intel_dp->adapter);
|
||||
if (is_edp(intel_dp)) {
|
||||
cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
ironlake_panel_vdd_off_sync(intel_dp);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
}
|
||||
drm_sysfs_connector_remove(connector);
|
||||
drm_connector_cleanup(connector);
|
||||
return false;
|
||||
|
@ -3208,6 +3214,9 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
|
|||
intel_encoder->cloneable = false;
|
||||
intel_encoder->hot_plug = intel_dp_hot_plug;
|
||||
|
||||
if (!intel_dp_init_connector(intel_dig_port, intel_connector))
|
||||
if (!intel_dp_init_connector(intel_dig_port, intel_connector)) {
|
||||
drm_encoder_cleanup(encoder);
|
||||
kfree(intel_dig_port);
|
||||
kfree(intel_connector);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue