/* event related only access by event thread */
        struct mutex event_mutex;
        wait_queue_head_t event_q;
-       atomic_t hpd_state;
+       u32 hpd_state;
        u32 event_pndx;
        u32 event_gndx;
        struct dp_event event_list[DP_EVENT_Q_MAX];
        spinlock_t event_lock;
 
-       struct completion resume_comp;
-
        struct dp_audio *audio;
 };
 
        dp->core_initialized = true;
 }
 
+static void dp_display_host_deinit(struct dp_display_private *dp)
+{
+       if (!dp->core_initialized) {
+               DRM_DEBUG_DP("DP core not initialized\n");
+               return;
+       }
+
+       dp_ctrl_host_deinit(dp->ctrl);
+       dp_aux_deinit(dp->aux);
+       dp_power_deinit(dp->power);
+
+       dp->core_initialized = false;
+}
+
 static int dp_display_usbpd_configure_cb(struct device *dev)
 {
        int rc = 0;
 
        mutex_lock(&dp->event_mutex);
 
-       state =  atomic_read(&dp->hpd_state);
+       state =  dp->hpd_state;
        if (state == ST_SUSPEND_PENDING) {
                mutex_unlock(&dp->event_mutex);
                return 0;
                return 0;
        }
 
-       if (state == ST_SUSPENDED)
-               tout = DP_TIMEOUT_NONE;
-
-       atomic_set(&dp->hpd_state, ST_CONNECT_PENDING);
+       dp->hpd_state = ST_CONNECT_PENDING;
 
        hpd->hpd_high = 1;
 
        ret = dp_display_usbpd_configure_cb(&dp->pdev->dev);
        if (ret) {      /* failed */
                hpd->hpd_high = 0;
-               atomic_set(&dp->hpd_state, ST_DISCONNECTED);
+               dp->hpd_state = ST_DISCONNECTED;
        }
 
        /* start sanity checking */
 
        mutex_lock(&dp->event_mutex);
 
-       state =  atomic_read(&dp->hpd_state);
+       state = dp->hpd_state;
        if (state == ST_CONNECT_PENDING) {
                dp_display_enable(dp, 0);
-               atomic_set(&dp->hpd_state, ST_CONNECTED);
+               dp->hpd_state = ST_CONNECTED;
        }
 
        mutex_unlock(&dp->event_mutex);
 
        mutex_lock(&dp->event_mutex);
 
-       state = atomic_read(&dp->hpd_state);
+       state = dp->hpd_state;
        if (state == ST_SUSPEND_PENDING) {
                mutex_unlock(&dp->event_mutex);
                return 0;
                return 0;
        }
 
-       atomic_set(&dp->hpd_state, ST_DISCONNECT_PENDING);
+       dp->hpd_state = ST_DISCONNECT_PENDING;
 
        /* disable HPD plug interrupt until disconnect is done */
        dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK
 
        mutex_lock(&dp->event_mutex);
 
-       state =  atomic_read(&dp->hpd_state);
+       state =  dp->hpd_state;
        if (state == ST_DISCONNECT_PENDING) {
                dp_display_disable(dp, 0);
-               atomic_set(&dp->hpd_state, ST_DISCONNECTED);
+               dp->hpd_state = ST_DISCONNECTED;
        }
 
        mutex_unlock(&dp->event_mutex);
        mutex_lock(&dp->event_mutex);
 
        /* irq_hpd can happen at either connected or disconnected state */
-       state =  atomic_read(&dp->hpd_state);
+       state =  dp->hpd_state;
        if (state == ST_SUSPEND_PENDING) {
                mutex_unlock(&dp->event_mutex);
                return 0;
 
        dp_display = g_dp_display;
 
-       if (dp_display->power_on) {
-               DRM_DEBUG_DP("Link already setup, return\n");
-               return 0;
-       }
-
        rc = dp_ctrl_on_stream(dp->ctrl);
        if (!rc)
                dp_display->power_on = true;
 
-       /* complete resume_comp regardless it is armed or not */
-       complete(&dp->resume_comp);
        return rc;
 }
 
 
        dp_display = g_dp_display;
 
-       if (!dp_display->power_on)
-               return -EINVAL;
-
        /* wait only if audio was enabled */
        if (dp_display->audio_enabled) {
                if (!wait_for_completion_timeout(&dp->audio_comp,
        }
 
        mutex_init(&dp->event_mutex);
-
-       init_completion(&dp->resume_comp);
-
        g_dp_display = &dp->dp_display;
 
        /* Store DP audio handle inside DP display */
 
 static int dp_pm_resume(struct device *dev)
 {
+       struct platform_device *pdev = to_platform_device(dev);
+       struct msm_dp *dp_display = platform_get_drvdata(pdev);
+       struct dp_display_private *dp;
+       u32 status;
+
+       dp = container_of(dp_display, struct dp_display_private, dp_display);
+
+       mutex_lock(&dp->event_mutex);
+
+       /* start from disconnected state */
+       dp->hpd_state = ST_DISCONNECTED;
+
+       /* turn on dp ctrl/phy */
+       dp_display_host_init(dp);
+
+       dp_catalog_ctrl_hpd_config(dp->catalog);
+
+       status = dp_catalog_hpd_get_state_status(dp->catalog);
+
+       if (status) {
+               dp->dp_display.is_connected = true;
+       } else {
+               dp->dp_display.is_connected = false;
+               /* make sure next resume host_init be called */
+               dp->core_initialized = false;
+       }
+
+       mutex_unlock(&dp->event_mutex);
+
        return 0;
 }
 
 static int dp_pm_suspend(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
-       struct dp_display_private *dp = platform_get_drvdata(pdev);
+       struct msm_dp *dp_display = platform_get_drvdata(pdev);
+       struct dp_display_private *dp;
 
-       if (!dp) {
-               DRM_ERROR("DP driver bind failed. Invalid driver data\n");
-               return -EINVAL;
-       }
+       dp = container_of(dp_display, struct dp_display_private, dp_display);
 
-       atomic_set(&dp->hpd_state, ST_SUSPENDED);
+       mutex_lock(&dp->event_mutex);
+
+       if (dp->core_initialized == true)
+               dp_display_host_deinit(dp);
+
+       dp->hpd_state = ST_SUSPENDED;
+
+       mutex_unlock(&dp->event_mutex);
 
        return 0;
 }
        return 0;
 }
 
-static int dp_display_wait4resume_done(struct dp_display_private *dp)
-{
-       int ret = 0;
-
-       reinit_completion(&dp->resume_comp);
-       if (!wait_for_completion_timeout(&dp->resume_comp,
-                               WAIT_FOR_RESUME_TIMEOUT_JIFFIES)) {
-               DRM_ERROR("wait4resume_done timedout\n");
-               ret = -ETIMEDOUT;
-       }
-       return ret;
-}
-
 int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder *encoder)
 {
        int rc = 0;
 
        mutex_lock(&dp_display->event_mutex);
 
+       dp_del_event(dp_display, EV_CONNECT_PENDING_TIMEOUT);
+
        rc = dp_display_set_mode(dp, &dp_display->dp_mode);
        if (rc) {
                DRM_ERROR("Failed to perform a mode set, rc=%d\n", rc);
                return rc;
        }
 
-       state =  atomic_read(&dp_display->hpd_state);
-       if (state == ST_SUSPENDED) {
-               /* start link training */
-               dp_add_event(dp_display, EV_HPD_PLUG_INT, 0, 0);
-               mutex_unlock(&dp_display->event_mutex);
+       state =  dp_display->hpd_state;
 
-               /* wait until dp interface is up */
-               goto resume_done;
-       }
+       if (state == ST_SUSPEND_PENDING)
+               dp_display_host_init(dp_display);
 
        dp_display_enable(dp_display, 0);
 
                dp_display_unprepare(dp);
        }
 
-       dp_del_event(dp_display, EV_CONNECT_PENDING_TIMEOUT);
-
        if (state == ST_SUSPEND_PENDING)
                dp_add_event(dp_display, EV_IRQ_HPD_INT, 0, 0);
 
        /* completed connection */
-       atomic_set(&dp_display->hpd_state, ST_CONNECTED);
+       dp_display->hpd_state = ST_CONNECTED;
 
        mutex_unlock(&dp_display->event_mutex);
 
        return rc;
-
-resume_done:
-       dp_display_wait4resume_done(dp_display);
-       return rc;
 }
 
 int msm_dp_display_pre_disable(struct msm_dp *dp, struct drm_encoder *encoder)
 
        mutex_lock(&dp_display->event_mutex);
 
+       dp_del_event(dp_display, EV_DISCONNECT_PENDING_TIMEOUT);
+
        dp_display_disable(dp_display, 0);
 
        rc = dp_display_unprepare(dp);
        if (rc)
                DRM_ERROR("DP display unprepare failed, rc=%d\n", rc);
 
-       dp_del_event(dp_display, EV_DISCONNECT_PENDING_TIMEOUT);
-
-       state =  atomic_read(&dp_display->hpd_state);
+       state =  dp_display->hpd_state;
        if (state == ST_DISCONNECT_PENDING) {
                /* completed disconnection */
-               atomic_set(&dp_display->hpd_state, ST_DISCONNECTED);
+               dp_display->hpd_state = ST_DISCONNECTED;
        } else {
-               atomic_set(&dp_display->hpd_state, ST_SUSPEND_PENDING);
+               dp_display->hpd_state = ST_SUSPEND_PENDING;
        }
 
        mutex_unlock(&dp_display->event_mutex);