diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 87ac369..c8869de 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -11,6 +11,7 @@
  * option) any later version.
  */
 
+#include <linux/pm_runtime.h>
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
 
@@ -53,6 +54,7 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
 		return -ENOMEM;
 
 	INIT_LIST_HEAD(&private->pageflip_event_list);
+	dev_set_drvdata(dev->dev, dev);
 	dev->dev_private = (void *)private;
 
 	/*
@@ -163,6 +165,41 @@ static const struct file_operations exynos_drm_gem_fops = {
 	.mmap = exynos_drm_gem_mmap_buffer,
 };
 
+static int exynos_drm_suspend(struct drm_device *dev, pm_message_t state)
+{
+	struct drm_connector *connector;
+
+	drm_modeset_lock_all(dev);
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		int old_dpms = connector->dpms;
+
+		if (connector->funcs->dpms)
+			connector->funcs->dpms(connector, DRM_MODE_DPMS_OFF);
+
+		/* Set the old mode back to the connector for resume */
+		connector->dpms = old_dpms;
+	}
+	drm_modeset_unlock_all(dev);
+
+	return 0;
+}
+
+static int exynos_drm_resume(struct drm_device *dev)
+{
+	struct drm_connector *connector;
+
+	drm_modeset_lock_all(dev);
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		if (connector->funcs->dpms)
+			connector->funcs->dpms(connector, connector->dpms);
+	}
+
+	drm_helper_resume_force_mode(dev);
+	drm_modeset_unlock_all(dev);
+
+	return 0;
+}
+
 static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
 {
 	struct drm_exynos_file_private *file_priv;
@@ -296,6 +333,8 @@ static struct drm_driver exynos_drm_driver = {
 					DRIVER_GEM | DRIVER_PRIME,
 	.load			= exynos_drm_load,
 	.unload			= exynos_drm_unload,
+	.suspend		= exynos_drm_suspend,
+	.resume			= exynos_drm_resume,
 	.open			= exynos_drm_open,
 	.preclose		= exynos_drm_preclose,
 	.lastclose		= exynos_drm_lastclose,
@@ -330,6 +369,9 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_get_sync(&pdev->dev);
+
 	return drm_platform_init(&exynos_drm_driver, pdev);
 }
 
@@ -340,12 +382,67 @@ static int exynos_drm_platform_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int exynos_drm_sys_suspend(struct device *dev)
+{
+	struct drm_device *drm_dev = dev_get_drvdata(dev);
+	pm_message_t message;
+
+	if (pm_runtime_suspended(dev))
+		return 0;
+
+	message.event = PM_EVENT_SUSPEND;
+	return exynos_drm_suspend(drm_dev, message);
+}
+
+static int exynos_drm_sys_resume(struct device *dev)
+{
+	struct drm_device *drm_dev = dev_get_drvdata(dev);
+
+	if (pm_runtime_suspended(dev))
+		return 0;
+
+	return exynos_drm_resume(drm_dev);
+}
+#endif
+
+#ifdef CONFIG_PM_RUNTIME
+static int exynos_drm_runtime_suspend(struct device *dev)
+{
+	struct drm_device *drm_dev = dev_get_drvdata(dev);
+	pm_message_t message;
+
+	if (pm_runtime_suspended(dev))
+		return 0;
+
+	message.event = PM_EVENT_SUSPEND;
+	return exynos_drm_suspend(drm_dev, message);
+}
+
+static int exynos_drm_runtime_resume(struct device *dev)
+{
+	struct drm_device *drm_dev = dev_get_drvdata(dev);
+
+	if (!pm_runtime_suspended(dev))
+		return 0;
+
+	return exynos_drm_resume(drm_dev);
+}
+#endif
+
+static const struct dev_pm_ops exynos_drm_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(exynos_drm_sys_suspend, exynos_drm_sys_resume)
+	SET_RUNTIME_PM_OPS(exynos_drm_runtime_suspend,
+			exynos_drm_runtime_resume, NULL)
+};
+
 static struct platform_driver exynos_drm_platform_driver = {
 	.probe		= exynos_drm_platform_probe,
 	.remove		= exynos_drm_platform_remove,
 	.driver		= {
 		.owner	= THIS_MODULE,
 		.name	= "exynos-drm",
+		.pm	= &exynos_drm_pm_ops,
 	},
 };
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 1efdcac..f78fbf4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -732,6 +732,8 @@ static int fimd_poweron(struct exynos_drm_manager *mgr)
 
 	ctx->suspended = false;
 
+	pm_runtime_get_sync(ctx->dev);
+
 	ret = clk_prepare_enable(ctx->bus_clk);
 	if (ret < 0) {
 		DRM_ERROR("Failed to prepare_enable the bus clk [%d]\n", ret);
@@ -785,32 +787,24 @@ static int fimd_poweroff(struct exynos_drm_manager *mgr)
 	clk_disable_unprepare(ctx->lcd_clk);
 	clk_disable_unprepare(ctx->bus_clk);
 
+	pm_runtime_put_sync(ctx->dev);
+
 	ctx->suspended = true;
 	return 0;
 }
 
 static void fimd_dpms(struct exynos_drm_manager *mgr, int mode)
 {
-	struct fimd_context *ctx = mgr->ctx;
-
-	DRM_DEBUG_KMS("%d\n", mode);
+	DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode);
 
 	switch (mode) {
 	case DRM_MODE_DPMS_ON:
-		/*
-		 * enable fimd hardware only if suspended status.
-		 *
-		 * P.S. fimd_dpms function would be called at booting time so
-		 * clk_enable could be called double time.
-		 */
-		if (ctx->suspended)
-			pm_runtime_get_sync(ctx->dev);
+		fimd_poweron(mgr);
 		break;
 	case DRM_MODE_DPMS_STANDBY:
 	case DRM_MODE_DPMS_SUSPEND:
 	case DRM_MODE_DPMS_OFF:
-		if (!ctx->suspended)
-			pm_runtime_put_sync(ctx->dev);
+		fimd_poweroff(mgr);
 		break;
 	default:
 		DRM_DEBUG_KMS("unspecified mode %d\n", mode);
@@ -929,7 +923,6 @@ static int fimd_probe(struct platform_device *pdev)
 	exynos_drm_manager_register(&fimd_manager);
 
 	pm_runtime_enable(dev);
-	pm_runtime_get_sync(dev);
 
 	for (win = 0; win < WINDOWS_NR; win++)
 		fimd_clear_win(ctx, win);
@@ -939,84 +932,23 @@ static int fimd_probe(struct platform_device *pdev)
 
 static int fimd_remove(struct platform_device *pdev)
 {
-	struct device *dev = &pdev->dev;
 	struct exynos_drm_manager *mgr = platform_get_drvdata(pdev);
-	struct fimd_context *ctx = mgr->ctx;
 
 	exynos_drm_manager_unregister(&fimd_manager);
 
-	if (ctx->suspended)
-		goto out;
-
-	pm_runtime_set_suspended(dev);
-	pm_runtime_put_sync(dev);
+	fimd_dpms(mgr, DRM_MODE_DPMS_OFF);
 
-out:
-	pm_runtime_disable(dev);
-
-	return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int fimd_suspend(struct device *dev)
-{
-	struct exynos_drm_manager *mgr = get_fimd_manager(dev);
-
-	/*
-	 * do not use pm_runtime_suspend(). if pm_runtime_suspend() is
-	 * called here, an error would be returned by that interface
-	 * because the usage_count of pm runtime is more than 1.
-	 */
-	if (!pm_runtime_suspended(dev))
-		return fimd_poweroff(mgr);
+	pm_runtime_disable(&pdev->dev);
 
 	return 0;
 }
 
-static int fimd_resume(struct device *dev)
-{
-	struct exynos_drm_manager *mgr = get_fimd_manager(dev);
-
-	/*
-	 * if entered to sleep when lcd panel was on, the usage_count
-	 * of pm runtime would still be 1 so in this case, fimd driver
-	 * should be on directly not drawing on pm runtime interface.
-	 */
-	if (pm_runtime_suspended(dev))
-		return 0;
-
-	return fimd_poweron(mgr);
-}
-#endif
-
-#ifdef CONFIG_PM_RUNTIME
-static int fimd_runtime_suspend(struct device *dev)
-{
-	struct exynos_drm_manager *mgr = get_fimd_manager(dev);
-
-	return fimd_poweroff(mgr);
-}
-
-static int fimd_runtime_resume(struct device *dev)
-{
-	struct exynos_drm_manager *mgr = get_fimd_manager(dev);
-
-	return fimd_poweron(mgr);
-}
-#endif
-
-static const struct dev_pm_ops fimd_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(fimd_suspend, fimd_resume)
-	SET_RUNTIME_PM_OPS(fimd_runtime_suspend, fimd_runtime_resume, NULL)
-};
-
 struct platform_driver fimd_driver = {
 	.probe		= fimd_probe,
 	.remove		= fimd_remove,
 	.driver		= {
 		.name	= "exynos4-fb",
 		.owner	= THIS_MODULE,
-		.pm	= &fimd_pm_ops,
 		.of_match_table = fimd_driver_dt_match,
 	},
 };
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index f6f4438..5d0b5cd 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -140,31 +140,6 @@ static struct exynos_drm_display vidi_display = {
 	.ops = &vidi_display_ops,
 };
 
-static void vidi_dpms(struct exynos_drm_manager *mgr, int mode)
-{
-	struct vidi_context *ctx = mgr->ctx;
-
-	DRM_DEBUG_KMS("%d\n", mode);
-
-	mutex_lock(&ctx->lock);
-
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		/* TODO. */
-		break;
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-	case DRM_MODE_DPMS_OFF:
-		/* TODO. */
-		break;
-	default:
-		DRM_DEBUG_KMS("unspecified mode %d\n", mode);
-		break;
-	}
-
-	mutex_unlock(&ctx->lock);
-}
-
 static void vidi_apply(struct exynos_drm_manager *mgr)
 {
 	struct vidi_context *ctx = mgr->ctx;
@@ -319,6 +294,55 @@ static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos)
 	/* TODO. */
 }
 
+static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable)
+{
+	struct vidi_context *ctx = mgr->ctx;
+
+	DRM_DEBUG_KMS("%s\n", __FILE__);
+
+	if (enable != false && enable != true)
+		return -EINVAL;
+
+	if (enable) {
+		ctx->suspended = false;
+
+		/* if vblank was enabled status, enable it again. */
+		if (test_and_clear_bit(0, &ctx->irq_flags))
+			vidi_enable_vblank(mgr);
+
+		vidi_apply(mgr);
+	} else {
+		ctx->suspended = true;
+	}
+
+	return 0;
+}
+
+static void vidi_dpms(struct exynos_drm_manager *mgr, int mode)
+{
+	struct vidi_context *ctx = mgr->ctx;
+
+	DRM_DEBUG_KMS("%d\n", mode);
+
+	mutex_lock(&ctx->lock);
+
+	switch (mode) {
+	case DRM_MODE_DPMS_ON:
+		vidi_power_on(mgr, true);
+		break;
+	case DRM_MODE_DPMS_STANDBY:
+	case DRM_MODE_DPMS_SUSPEND:
+	case DRM_MODE_DPMS_OFF:
+		vidi_power_on(mgr, false);
+		break;
+	default:
+		DRM_DEBUG_KMS("unspecified mode %d\n", mode);
+		break;
+	}
+
+	mutex_unlock(&ctx->lock);
+}
+
 static int vidi_mgr_initialize(struct exynos_drm_manager *mgr,
 			struct drm_device *drm_dev, int pipe)
 {
@@ -390,30 +414,6 @@ static void vidi_fake_vblank_handler(struct work_struct *work)
 	exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
 }
 
-static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable)
-{
-	struct vidi_context *ctx = mgr->ctx;
-
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
-	if (enable != false && enable != true)
-		return -EINVAL;
-
-	if (enable) {
-		ctx->suspended = false;
-
-		/* if vblank was enabled status, enable it again. */
-		if (test_and_clear_bit(0, &ctx->irq_flags))
-			vidi_enable_vblank(mgr);
-
-		vidi_apply(mgr);
-	} else {
-		ctx->suspended = true;
-	}
-
-	return 0;
-}
-
 static int vidi_show_connection(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
@@ -578,32 +578,11 @@ static int vidi_remove(struct platform_device *pdev)
 	return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int vidi_suspend(struct device *dev)
-{
-	struct exynos_drm_manager *mgr = get_vidi_mgr(dev);
-
-	return vidi_power_on(mgr, false);
-}
-
-static int vidi_resume(struct device *dev)
-{
-	struct exynos_drm_manager *mgr = get_vidi_mgr(dev);
-
-	return vidi_power_on(mgr, true);
-}
-#endif
-
-static const struct dev_pm_ops vidi_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(vidi_suspend, vidi_resume)
-};
-
 struct platform_driver vidi_driver = {
 	.probe		= vidi_probe,
 	.remove		= vidi_remove,
 	.driver		= {
 		.name	= "exynos-drm-vidi",
 		.owner	= THIS_MODULE,
-		.pm	= &vidi_pm_ops,
 	},
 };
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 3faea8f..3313743 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1737,6 +1737,8 @@ static void hdmi_poweron(struct exynos_drm_display *display)
 
 	mutex_unlock(&hdata->hdmi_mutex);
 
+	pm_runtime_get_sync(hdata->dev);
+
 	if (regulator_bulk_enable(res->regul_count, res->regul_bulk))
 		DRM_DEBUG_KMS("failed to enable regulator bulk\n");
 
@@ -1770,8 +1772,9 @@ static void hdmi_poweroff(struct exynos_drm_display *display)
 	clk_disable_unprepare(res->hdmiphy);
 	regulator_bulk_disable(res->regul_count, res->regul_bulk);
 
-	mutex_lock(&hdata->hdmi_mutex);
+	pm_runtime_put_sync(hdata->dev);
 
+	mutex_lock(&hdata->hdmi_mutex);
 	hdata->powered = false;
 
 out:
@@ -1780,20 +1783,16 @@ out:
 
 static void hdmi_dpms(struct exynos_drm_display *display, int mode)
 {
-	struct hdmi_context *hdata = display->ctx;
-
 	DRM_DEBUG_KMS("mode %d\n", mode);
 
 	switch (mode) {
 	case DRM_MODE_DPMS_ON:
-		if (pm_runtime_suspended(hdata->dev))
-			pm_runtime_get_sync(hdata->dev);
+		hdmi_poweron(display);
 		break;
 	case DRM_MODE_DPMS_STANDBY:
 	case DRM_MODE_DPMS_SUSPEND:
 	case DRM_MODE_DPMS_OFF:
-		if (!pm_runtime_suspended(hdata->dev))
-			pm_runtime_put_sync(hdata->dev);
+		hdmi_poweroff(display);
 		break;
 	default:
 		DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
@@ -2033,11 +2032,11 @@ static int hdmi_probe(struct platform_device *pdev)
 		goto err_hdmiphy;
 	}
 
+	pm_runtime_enable(dev);
+
 	hdmi_display.ctx = hdata;
 	exynos_drm_display_register(&hdmi_display);
 
-	pm_runtime_enable(dev);
-
 	return 0;
 
 err_hdmiphy:
@@ -2053,88 +2052,19 @@ static int hdmi_remove(struct platform_device *pdev)
 	struct exynos_drm_display *display = get_hdmi_display(dev);
 	struct hdmi_context *hdata = display->ctx;
 
-	pm_runtime_disable(dev);
-
 	put_device(&hdata->hdmiphy_port->dev);
 	put_device(&hdata->ddc_port->dev);
+	pm_runtime_disable(&pdev->dev);
 
 	return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int hdmi_suspend(struct device *dev)
-{
-	struct exynos_drm_display *display = get_hdmi_display(dev);
-	struct hdmi_context *hdata = display->ctx;
-
-	disable_irq(hdata->irq);
-
-	hdata->hpd = false;
-	if (hdata->drm_dev)
-		drm_helper_hpd_irq_event(hdata->drm_dev);
-
-	if (pm_runtime_suspended(dev)) {
-		DRM_DEBUG_KMS("Already suspended\n");
-		return 0;
-	}
-
-	hdmi_poweroff(display);
-
-	return 0;
-}
-
-static int hdmi_resume(struct device *dev)
-{
-	struct exynos_drm_display *display = get_hdmi_display(dev);
-	struct hdmi_context *hdata = display->ctx;
-
-	hdata->hpd = gpio_get_value(hdata->hpd_gpio);
-
-	enable_irq(hdata->irq);
-
-	if (!pm_runtime_suspended(dev)) {
-		DRM_DEBUG_KMS("Already resumed\n");
-		return 0;
-	}
-
-	hdmi_poweron(display);
-
-	return 0;
-}
-#endif
-
-#ifdef CONFIG_PM_RUNTIME
-static int hdmi_runtime_suspend(struct device *dev)
-{
-	struct exynos_drm_display *display = get_hdmi_display(dev);
-
-	hdmi_poweroff(display);
-
-	return 0;
-}
-
-static int hdmi_runtime_resume(struct device *dev)
-{
-	struct exynos_drm_display *display = get_hdmi_display(dev);
-
-	hdmi_poweron(display);
-
-	return 0;
-}
-#endif
-
-static const struct dev_pm_ops hdmi_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(hdmi_suspend, hdmi_resume)
-	SET_RUNTIME_PM_OPS(hdmi_runtime_suspend, hdmi_runtime_resume, NULL)
-};
-
 struct platform_driver hdmi_driver = {
 	.probe		= hdmi_probe,
 	.remove		= hdmi_remove,
 	.driver		= {
 		.name	= "exynos-hdmi",
 		.owner	= THIS_MODULE,
-		.pm	= &hdmi_pm_ops,
 		.of_match_table = hdmi_match_types,
 	},
 };
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index d522857..ce28881 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1061,6 +1061,8 @@ static void mixer_poweron(struct exynos_drm_manager *mgr)
 	ctx->powered = true;
 	mutex_unlock(&ctx->mixer_mutex);
 
+	pm_runtime_get_sync(ctx->dev);
+
 	clk_prepare_enable(res->mixer);
 	if (ctx->vp_enabled) {
 		clk_prepare_enable(res->vp);
@@ -1093,6 +1095,8 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr)
 		clk_disable_unprepare(res->sclk_mixer);
 	}
 
+	pm_runtime_put_sync(ctx->dev);
+
 	mutex_lock(&ctx->mixer_mutex);
 	ctx->powered = false;
 
@@ -1102,18 +1106,14 @@ out:
 
 static void mixer_dpms(struct exynos_drm_manager *mgr, int mode)
 {
-	struct mixer_context *mixer_ctx = mgr->ctx;
-
 	switch (mode) {
 	case DRM_MODE_DPMS_ON:
-		if (pm_runtime_suspended(mixer_ctx->dev))
-			pm_runtime_get_sync(mixer_ctx->dev);
+		mixer_poweron(mgr);
 		break;
 	case DRM_MODE_DPMS_STANDBY:
 	case DRM_MODE_DPMS_SUSPEND:
 	case DRM_MODE_DPMS_OFF:
-		if (!pm_runtime_suspended(mixer_ctx->dev))
-			pm_runtime_put_sync(mixer_ctx->dev);
+		mixer_poweroff(mgr);
 		break;
 	default:
 		DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
@@ -1250,66 +1250,10 @@ static int mixer_remove(struct platform_device *pdev)
 	return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int mixer_suspend(struct device *dev)
-{
-	struct exynos_drm_manager *mgr = get_mixer_manager(dev);
-
-	if (pm_runtime_suspended(dev)) {
-		DRM_DEBUG_KMS("Already suspended\n");
-		return 0;
-	}
-
-	mixer_poweroff(mgr);
-
-	return 0;
-}
-
-static int mixer_resume(struct device *dev)
-{
-	struct exynos_drm_manager *mgr = get_mixer_manager(dev);
-
-	if (!pm_runtime_suspended(dev)) {
-		DRM_DEBUG_KMS("Already resumed\n");
-		return 0;
-	}
-
-	mixer_poweron(mgr);
-
-	return 0;
-}
-#endif
-
-#ifdef CONFIG_PM_RUNTIME
-static int mixer_runtime_suspend(struct device *dev)
-{
-	struct exynos_drm_manager *mgr = get_mixer_manager(dev);
-
-	mixer_poweroff(mgr);
-
-	return 0;
-}
-
-static int mixer_runtime_resume(struct device *dev)
-{
-	struct exynos_drm_manager *mgr = get_mixer_manager(dev);
-
-	mixer_poweron(mgr);
-
-	return 0;
-}
-#endif
-
-static const struct dev_pm_ops mixer_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(mixer_suspend, mixer_resume)
-	SET_RUNTIME_PM_OPS(mixer_runtime_suspend, mixer_runtime_resume, NULL)
-};
-
 struct platform_driver mixer_driver = {
 	.driver = {
 		.name = "exynos-mixer",
 		.owner = THIS_MODULE,
-		.pm = &mixer_pm_ops,
 		.of_match_table = mixer_match_types,
 	},
 	.probe = mixer_probe,
