blob: 530798721622f190408d5f466a6897b0b634f16d [file] [log] [blame]
From 4c61b19b8fd1ed30b80dbd6dba91146e71c532d0 Mon Sep 17 00:00:00 2001
From: Paulo Zanoni <paulo.r.zanoni@intel.com>
Date: Wed, 12 Jun 2013 17:27:26 -0300
Subject: drm/i915: fix the "ghost eDP" connector unwind path
Because calling intel_dp_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_destroy function we do the following:
1 - Free edid if it exists
2 - Call intel_panel_fini in case it's eDP
3 - Call drm_sysfs_connector_remove
4 - Call drm_connector_cleanup
5 - Free the connector
And here is how we unwind each specific step:
1 - No need as we still didn't assign anything
2 - No need as we still didn't call intel_panel_init
3 - Call it in the same function that called drm_sysfs_connector_add
4 - Call it in the same function that called drm_connector_init
5 - 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>
(cherry picked from commit b2f246a8998ccf9e00477c8829a62139804e9857)
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
---
drivers/gpu/drm/i915/intel_ddi.c | 4 +++-
drivers/gpu/drm/i915/intel_dp.c | 9 ++++++---
2 files changed, 9 insertions(+), 4 deletions(-)
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1366,8 +1366,10 @@ void intel_ddi_init(struct drm_device *d
intel_encoder->cloneable = false;
intel_encoder->hot_plug = intel_ddi_hot_plug;
- if (!intel_dp_init_connector(intel_dig_port, dp_connector))
+ if (!intel_dp_init_connector(intel_dig_port, dp_connector)) {
+ kfree(dp_connector);
return;
+ }
if (intel_encoder->type != INTEL_OUTPUT_EDP) {
hdmi_connector = kzalloc(sizeof(struct intel_connector),
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3014,7 +3014,6 @@ static bool intel_edp_init_connector(str
/* 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);
- intel_dp_destroy(connector);
return false;
}
@@ -3173,8 +3172,11 @@ intel_dp_init_connector(struct intel_dig
intel_dp_i2c_init(intel_dp, intel_connector, name);
- if (!intel_edp_init_connector(intel_dp, intel_connector))
+ if (!intel_edp_init_connector(intel_dp, intel_connector)) {
+ drm_sysfs_connector_remove(connector);
+ drm_connector_cleanup(connector);
return false;
+ }
intel_dp_add_properties(intel_dp, connector);
@@ -3233,5 +3235,6 @@ intel_dp_init(struct drm_device *dev, in
intel_encoder->cloneable = false;
intel_encoder->hot_plug = intel_dp_hot_plug;
- intel_dp_init_connector(intel_dig_port, intel_connector);
+ if (!intel_dp_init_connector(intel_dig_port, intel_connector))
+ kfree(intel_connector);
}