diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1f675a8..b2e2e0c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -500,6 +500,16 @@ struct cxsr_latency {
 #define to_intel_plane(x) container_of(x, struct intel_plane, base)
 #define intel_fb_obj(x) (x ? to_intel_framebuffer(x)->obj : NULL)
 
+/* DisplayPort/HDMI Hotplug line status bit mask */
+#define VLV_HDMIB_HOTPLUG_LIVE_STATUS   (1 << 29)
+#define VLV_HDMIC_HOTPLUG_LIVE_STATUS   (1 << 28)
+#define VLV_HDMID_HOTPLUG_LIVE_STATUS   (1 << 27)
+
+/* DisplayPort/HDMI/DVI Hotplug line status bit mask */
+#define CORE_HDMIB_HOTPLUG_LIVE_STATUS  (1 << 21)
+#define CORE_HDMIC_HOTPLUG_LIVE_STATUS  (1 << 22)
+#define CORE_HDMID_HOTPLUG_LIVE_STATUS  (1 << 23)
+
 struct intel_hdmi {
 	u32 hdmi_reg;
 	int ddc_bus;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index f9151f6..1920e4e 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -962,6 +962,61 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
 	return true;
 }
 
+static int get_hdmi_hotplug_live_status(struct drm_device *dev,
+					struct intel_hdmi *intel_hdmi)
+{
+	uint32_t bit, reg;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_digital_port *intel_dig_port =
+				hdmi_to_dig_port(intel_hdmi);
+
+	DRM_DEBUG_KMS("Reading Live status");
+
+	/* Live status is available from Gen 6 onwards */
+	if (INTEL_INFO(dev)->gen < 6)
+		return connector_status_connected;
+
+	if (IS_VALLEYVIEW(dev)) {
+		switch (intel_dig_port->port) {
+		case PORT_B:
+			bit = VLV_HDMIB_HOTPLUG_LIVE_STATUS;
+			break;
+		case PORT_C:
+			bit = VLV_HDMIC_HOTPLUG_LIVE_STATUS;
+			break;
+		case PORT_D:
+			bit = VLV_HDMID_HOTPLUG_LIVE_STATUS;
+			break;
+		default:
+			DRM_ERROR("Unrecognized port is encountered\n");
+			return connector_status_unknown;
+		}
+		reg = I915_READ(PORT_HOTPLUG_STAT);
+
+	} else {
+		switch (intel_dig_port->port) {
+		case PORT_B:
+			bit = CORE_HDMIB_HOTPLUG_LIVE_STATUS;
+			break;
+		case PORT_C:
+			bit = CORE_HDMIC_HOTPLUG_LIVE_STATUS;
+			break;
+		case PORT_D:
+			bit = CORE_HDMID_HOTPLUG_LIVE_STATUS;
+			break;
+		default:
+			DRM_ERROR("Unrecognized port is encountered\n");
+			return connector_status_unknown;
+		}
+
+		reg = I915_READ(SDEISR);
+	}
+
+	/* Return connector status */
+	return ((reg & bit) ?
+		connector_status_connected : connector_status_disconnected);
+}
+
 static enum drm_connector_status
 intel_hdmi_detect(struct drm_connector *connector, bool force)
 {
@@ -981,24 +1036,32 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
 	power_domain = intel_display_port_power_domain(intel_encoder);
 	intel_display_power_get(dev_priv, power_domain);
 
+	status = get_hdmi_hotplug_live_status(dev, intel_hdmi);
+
 	intel_hdmi->has_hdmi_sink = false;
 	intel_hdmi->has_audio = false;
 	intel_hdmi->rgb_quant_range_selectable = false;
-	edid = drm_get_edid(connector,
-			    intel_gmbus_get_adapter(dev_priv,
-						    intel_hdmi->ddc_bus));
 
-	if (edid) {
-		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
-			status = connector_status_connected;
-			if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI)
-				intel_hdmi->has_hdmi_sink =
+	if (status == connector_status_connected) {
+		edid = drm_get_edid(connector,
+				intel_gmbus_get_adapter(dev_priv,
+						intel_hdmi->ddc_bus));
+		if (edid) {
+			if (edid->input & DRM_EDID_INPUT_DIGITAL) {
+				status = connector_status_connected;
+				if (intel_hdmi->force_audio !=
+							HDMI_AUDIO_OFF_DVI)
+					intel_hdmi->has_hdmi_sink =
 						drm_detect_hdmi_monitor(edid);
-			intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
-			intel_hdmi->rgb_quant_range_selectable =
-				drm_rgb_quant_range_selectable(edid);
+				intel_hdmi->has_audio =
+						drm_detect_monitor_audio(edid);
+				intel_hdmi->rgb_quant_range_selectable =
+					drm_rgb_quant_range_selectable(edid);
+			}
+			kfree(edid);
+		} else {
+			status = connector_status_disconnected;
 		}
-		kfree(edid);
 	}
 
 	if (status == connector_status_connected) {
