diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6335883..907b73e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8223,11 +8223,11 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
 	for_each_intel_encoder(dev, encoder) {
 		switch (encoder->type) {
 		case INTEL_OUTPUT_LVDS:
-			has_panel = true;
+			has_panel = intel_lvds_has_panel(encoder);
 			has_lvds = true;
 			break;
 		case INTEL_OUTPUT_EDP:
-			has_panel = true;
+			has_panel = intel_edp_has_panel(encoder);
 			if (enc_to_dig_port(&encoder->base)->port == PORT_A)
 				has_cpu_edp = true;
 			break;
@@ -14478,15 +14478,44 @@ intel_user_framebuffer_create(struct drm_device *dev,
 	return intel_framebuffer_create(dev, mode_cmd, obj);
 }
 
-#ifndef CONFIG_DRM_I915_FBDEV
-static inline void intel_fbdev_output_poll_changed(struct drm_device *dev)
+static void intel_output_poll_changed(struct drm_device *dev)
 {
-}
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_connector *intel_connector;
+
+	/* Reprobe LVDS and eDP as long as no EDID was retrieved from panel */
+	for_each_intel_connector(dev, intel_connector) {
+		struct drm_connector *connector = &intel_connector->base;
+
+		if ((connector->connector_type != DRM_MODE_CONNECTOR_LVDS &&
+		     connector->connector_type != DRM_MODE_CONNECTOR_eDP) ||
+		    !IS_ERR_OR_NULL(intel_connector->edid))
+			continue;
+
+		if ((connector->connector_type == DRM_MODE_CONNECTOR_LVDS &&
+		     !intel_lvds_probe_modes(connector)) ||
+		    (connector->connector_type == DRM_MODE_CONNECTOR_eDP &&
+		     !intel_edp_init_connector(
+			      enc_to_intel_dp(&intel_connector->encoder->base),
+			      intel_connector)))
+			continue;
+
+		intel_init_pch_refclk(dev);
+		drm_helper_move_panel_connectors_to_head(dev);
+		mutex_lock(&dev_priv->backlight_lock);
+		if (intel_connector->panel.backlight.device == NULL)
+			intel_backlight_device_register(intel_connector);
+		mutex_unlock(&dev_priv->backlight_lock);
+	}
+
+#ifdef CONFIG_DRM_I915_FBDEV
+	intel_fbdev_output_poll_changed(dev);
 #endif
+}
 
 static const struct drm_mode_config_funcs intel_mode_funcs = {
 	.fb_create = intel_user_framebuffer_create,
-	.output_poll_changed = intel_fbdev_output_poll_changed,
+	.output_poll_changed = intel_output_poll_changed,
 	.atomic_check = intel_atomic_check,
 	.atomic_commit = intel_atomic_commit,
 	.atomic_state_alloc = intel_atomic_state_alloc,
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index f1b9f93..23aa4ff 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1998,6 +1998,15 @@ void intel_edp_panel_off(struct intel_dp *intel_dp)
 	pps_unlock(intel_dp);
 }
 
+bool intel_edp_has_panel(struct intel_encoder *intel_encoder)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
+	struct intel_connector *intel_connector = intel_dp->attached_connector;
+
+	return intel_dp->dpcd[DP_DPCD_REV] != 0 &&
+	       intel_connector->panel.fixed_mode != NULL;
+}
+
 /* Enable backlight in the panel power control. */
 static void _intel_edp_backlight_on(struct intel_dp *intel_dp)
 {
@@ -4338,6 +4347,9 @@ edp_detect(struct intel_dp *intel_dp)
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	enum drm_connector_status status;
 
+	if (!intel_edp_has_panel(intel_dp->attached_connector->encoder))
+		return connector_status_disconnected;
+
 	status = intel_panel_detect(dev);
 	if (status == connector_status_unknown)
 		status = connector_status_connected;
@@ -5599,8 +5611,8 @@ intel_dp_drrs_init(struct intel_connector *intel_connector,
 	return downclock_mode;
 }
 
-static bool intel_edp_init_connector(struct intel_dp *intel_dp,
-				     struct intel_connector *intel_connector)
+bool intel_edp_init_connector(struct intel_dp *intel_dp,
+			      struct intel_connector *intel_connector)
 {
 	struct drm_connector *connector = &intel_connector->base;
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
@@ -5614,9 +5626,6 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 	struct edid *edid;
 	enum pipe pipe = INVALID_PIPE;
 
-	if (!is_edp(intel_dp))
-		return true;
-
 	pps_lock(intel_dp);
 	intel_edp_panel_vdd_sanitize(intel_dp);
 	pps_unlock(intel_dp);
@@ -5630,8 +5639,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 				intel_dp->dpcd[DP_MAX_DOWNSPREAD] &
 				DP_NO_AUX_HANDSHAKE_LINK_TRAINING;
 	} else {
-		/* if this fails, presume the device is a ghost */
-		DRM_INFO("failed to retrieve link info, disabling eDP\n");
+		DRM_INFO("failed to retrieve eDP link info\n");
 		return false;
 	}
 
@@ -5676,8 +5684,12 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 	mutex_unlock(&dev->mode_config.mutex);
 
 	if (IS_VALLEYVIEW(dev)) {
-		intel_dp->edp_notifier.notifier_call = edp_notify_handler;
-		register_reboot_notifier(&intel_dp->edp_notifier);
+		if (intel_dp->edp_notifier.notifier_call == NULL) {
+			intel_dp->edp_notifier.notifier_call =
+				edp_notify_handler;
+			if (register_reboot_notifier(&intel_dp->edp_notifier))
+				intel_dp->edp_notifier.notifier_call = NULL;
+		}
 
 		/*
 		 * Figure out the current pipe for the initial backlight setup.
@@ -5817,9 +5829,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 		intel_dp_mst_encoder_init(intel_dig_port,
 					  intel_connector->base.base.id);
 
-	if (!intel_edp_init_connector(intel_dp, intel_connector)) {
-		drm_dp_aux_unregister(&intel_dp->aux);
-		if (is_edp(intel_dp)) {
+	if (is_edp(intel_dp)) {
+		if (!intel_edp_init_connector(intel_dp, intel_connector)) {
 			cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
 			/*
 			 * vdd might still be enabled do to the delayed vdd off.
@@ -5829,9 +5840,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 			edp_panel_vdd_off_sync(intel_dp);
 			pps_unlock(intel_dp);
 		}
-		drm_connector_unregister(connector);
-		drm_connector_cleanup(connector);
-		return false;
 	}
 
 	intel_dp_add_properties(intel_dp, connector);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 47cef0e..361320b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1171,11 +1171,14 @@ bool intel_dp_compute_config(struct intel_encoder *encoder,
 bool intel_dp_is_edp(struct drm_device *dev, enum port port);
 enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port,
 				  bool long_hpd);
+bool intel_edp_init_connector(struct intel_dp *intel_dp,
+			      struct intel_connector *intel_connector);
 void intel_edp_backlight_on(struct intel_dp *intel_dp);
 void intel_edp_backlight_off(struct intel_dp *intel_dp);
 void intel_edp_panel_vdd_on(struct intel_dp *intel_dp);
 void intel_edp_panel_on(struct intel_dp *intel_dp);
 void intel_edp_panel_off(struct intel_dp *intel_dp);
+bool intel_edp_has_panel(struct intel_encoder *intel_encoder);
 void intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector);
 void intel_dp_mst_suspend(struct drm_device *dev);
 void intel_dp_mst_resume(struct drm_device *dev);
@@ -1258,6 +1261,8 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
 
 /* intel_lvds.c */
 void intel_lvds_init(struct drm_device *dev);
+bool intel_lvds_probe_modes(struct drm_connector *connector);
+bool intel_lvds_has_panel(struct intel_encoder *intel_encoder);
 bool intel_is_dual_link_lvds(struct drm_device *dev);
 
 
@@ -1307,6 +1312,7 @@ extern struct drm_display_mode *intel_find_panel_downclock(
 				struct drm_connector *connector);
 void intel_backlight_register(struct drm_device *dev);
 void intel_backlight_unregister(struct drm_device *dev);
+int intel_backlight_device_register(struct intel_connector *connector);
 
 
 /* intel_psr.c */
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index cb634f4..4c7c8a2 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -359,7 +359,7 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
 /**
  * Detect the LVDS connection.
  *
- * Since LVDS doesn't have hotlug, we use the lid as a proxy.  Open means
+ * Since LVDS doesn't have hotplug, we use the lid as a proxy.  Open means
  * connected and closed means disconnected.  We also send hotplug events as
  * needed, using lid status notification from the input layer.
  */
@@ -372,6 +372,9 @@ intel_lvds_detect(struct drm_connector *connector, bool force)
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
 		      connector->base.id, connector->name);
 
+	if (!intel_lvds_has_panel(to_intel_connector(connector)->encoder))
+		return connector_status_disconnected;
+
 	status = intel_panel_detect(dev);
 	if (status != connector_status_unknown)
 		return status;
@@ -936,13 +939,6 @@ void intel_lvds_init(struct drm_device *dev)
 	struct intel_connector *intel_connector;
 	struct drm_connector *connector;
 	struct drm_encoder *encoder;
-	struct drm_display_mode *scan; /* *modes, *bios_mode; */
-	struct drm_display_mode *fixed_mode = NULL;
-	struct drm_display_mode *downclock_mode = NULL;
-	struct edid *edid;
-	struct drm_crtc *crtc;
-	u32 lvds;
-	int pipe;
 	u8 pin;
 
 	/*
@@ -1052,6 +1048,29 @@ void intel_lvds_init(struct drm_device *dev)
 				      dev->mode_config.scaling_mode_property,
 				      DRM_MODE_SCALE_ASPECT);
 	intel_connector->panel.fitting_mode = DRM_MODE_SCALE_ASPECT;
+
+	drm_connector_register(connector);
+	intel_lvds_probe_modes(connector);
+}
+
+bool intel_lvds_probe_modes(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct intel_lvds_connector *lvds_connector = to_lvds_connector(connector);
+	struct intel_encoder *intel_encoder = intel_connector->encoder;
+	struct drm_encoder *encoder = &intel_encoder->base;
+	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
+	struct drm_display_mode *scan;
+	struct drm_display_mode *fixed_mode = NULL;
+	struct drm_display_mode *downclock_mode = NULL;
+	struct edid *edid;
+	struct drm_crtc *crtc;
+	u32 lvds;
+	int pipe;
+	u8 pin = GMBUS_PIN_PANEL;
+
 	/*
 	 * LVDS discovery:
 	 * 1) check for EDID on DDC
@@ -1079,7 +1098,7 @@ void intel_lvds_init(struct drm_device *dev)
 	} else {
 		edid = ERR_PTR(-ENOENT);
 	}
-	lvds_connector->base.edid = edid;
+	intel_connector->edid = edid;
 
 	if (IS_ERR_OR_NULL(edid)) {
 		/* Didn't get an EDID, so
@@ -1155,24 +1174,30 @@ out:
 	lvds_encoder->a3_power = I915_READ(lvds_encoder->reg) &
 				 LVDS_A3_POWER_MASK;
 
-	lvds_connector->lid_notifier.notifier_call = intel_lid_notify;
-	if (acpi_lid_notifier_register(&lvds_connector->lid_notifier)) {
-		DRM_DEBUG_KMS("lid notifier registration failed\n");
-		lvds_connector->lid_notifier.notifier_call = NULL;
+	if (lvds_connector->lid_notifier.notifier_call == NULL) {
+		lvds_connector->lid_notifier.notifier_call = intel_lid_notify;
+		if (acpi_lid_notifier_register(&lvds_connector->lid_notifier)) {
+			DRM_DEBUG_KMS("lid notifier registration failed\n");
+			lvds_connector->lid_notifier.notifier_call = NULL;
+		}
 	}
-	drm_connector_register(connector);
 
 	intel_panel_setup_backlight(connector, INVALID_PIPE);
 
-	return;
+	return true;
 
 failed:
 	mutex_unlock(&dev->mode_config.mutex);
 
-	DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
-	drm_connector_cleanup(connector);
-	drm_encoder_cleanup(encoder);
-	kfree(lvds_encoder);
-	kfree(lvds_connector);
-	return;
+	DRM_DEBUG_KMS("No LVDS modes found\n");
+	return false;
+}
+
+bool intel_lvds_has_panel(struct intel_encoder *intel_encoder)
+{
+	struct intel_lvds_connector *lvds_connector =
+		to_lvds_encoder(&intel_encoder->base)->attached_connector;
+	struct intel_connector *intel_connector = &lvds_connector->base;
+
+	return intel_connector->panel.fixed_mode != NULL;
 }
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index e2ab3f6..4dbfb3df 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -1139,7 +1139,7 @@ static const struct backlight_ops intel_backlight_device_ops = {
 	.get_brightness = intel_backlight_device_get_brightness,
 };
 
-static int intel_backlight_device_register(struct intel_connector *connector)
+int intel_backlight_device_register(struct intel_connector *connector)
 {
 	struct intel_panel *panel = &connector->panel;
 	struct backlight_properties props;
@@ -1202,7 +1202,7 @@ static void intel_backlight_device_unregister(struct intel_connector *connector)
 	}
 }
 #else /* CONFIG_BACKLIGHT_CLASS_DEVICE */
-static int intel_backlight_device_register(struct intel_connector *connector)
+int intel_backlight_device_register(struct intel_connector *connector)
 {
 	return 0;
 }
