aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorRahul Sharma <rahul.sharma@samsung.com>2012-11-28 01:00:23 -0500
committerInki Dae <inki.dae@samsung.com>2012-12-14 01:40:47 -0500
commit64327cb35acea0e3046d7c08d90b84ab83d5e7d1 (patch)
tree39493765a9598f24a005e817c0c18ea65f65d339 /drivers/gpu
parent1169af218010ec7420c2f66c10284047774ba96c (diff)
drm/exynos: added runtime pm support for hdmi
This patch adds runtime power management support for exynos drm hdmi driver. Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com> Signed-off-by: Shirish S <s.shirish@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c60
1 files changed, 52 insertions, 8 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index bafb65389562..98c587321521 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -2171,8 +2171,6 @@ static void hdmi_poweron(struct hdmi_context *hdata)
2171 2171
2172 mutex_unlock(&hdata->hdmi_mutex); 2172 mutex_unlock(&hdata->hdmi_mutex);
2173 2173
2174 pm_runtime_get_sync(hdata->dev);
2175
2176 regulator_bulk_enable(res->regul_count, res->regul_bulk); 2174 regulator_bulk_enable(res->regul_count, res->regul_bulk);
2177 clk_enable(res->hdmiphy); 2175 clk_enable(res->hdmiphy);
2178 clk_enable(res->hdmi); 2176 clk_enable(res->hdmi);
@@ -2201,8 +2199,6 @@ static void hdmi_poweroff(struct hdmi_context *hdata)
2201 clk_disable(res->hdmiphy); 2199 clk_disable(res->hdmiphy);
2202 regulator_bulk_disable(res->regul_count, res->regul_bulk); 2200 regulator_bulk_disable(res->regul_count, res->regul_bulk);
2203 2201
2204 pm_runtime_put_sync(hdata->dev);
2205
2206 mutex_lock(&hdata->hdmi_mutex); 2202 mutex_lock(&hdata->hdmi_mutex);
2207 2203
2208 hdata->powered = false; 2204 hdata->powered = false;
@@ -2215,16 +2211,18 @@ static void hdmi_dpms(void *ctx, int mode)
2215{ 2211{
2216 struct hdmi_context *hdata = ctx; 2212 struct hdmi_context *hdata = ctx;
2217 2213
2218 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 2214 DRM_DEBUG_KMS("[%d] %s mode %d\n", __LINE__, __func__, mode);
2219 2215
2220 switch (mode) { 2216 switch (mode) {
2221 case DRM_MODE_DPMS_ON: 2217 case DRM_MODE_DPMS_ON:
2222 hdmi_poweron(hdata); 2218 if (pm_runtime_suspended(hdata->dev))
2219 pm_runtime_get_sync(hdata->dev);
2223 break; 2220 break;
2224 case DRM_MODE_DPMS_STANDBY: 2221 case DRM_MODE_DPMS_STANDBY:
2225 case DRM_MODE_DPMS_SUSPEND: 2222 case DRM_MODE_DPMS_SUSPEND:
2226 case DRM_MODE_DPMS_OFF: 2223 case DRM_MODE_DPMS_OFF:
2227 hdmi_poweroff(hdata); 2224 if (!pm_runtime_suspended(hdata->dev))
2225 pm_runtime_put_sync(hdata->dev);
2228 break; 2226 break;
2229 default: 2227 default:
2230 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode); 2228 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
@@ -2612,6 +2610,8 @@ static int hdmi_suspend(struct device *dev)
2612 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev); 2610 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2613 struct hdmi_context *hdata = ctx->ctx; 2611 struct hdmi_context *hdata = ctx->ctx;
2614 2612
2613 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2614
2615 disable_irq(hdata->internal_irq); 2615 disable_irq(hdata->internal_irq);
2616 disable_irq(hdata->external_irq); 2616 disable_irq(hdata->external_irq);
2617 2617
@@ -2619,6 +2619,11 @@ static int hdmi_suspend(struct device *dev)
2619 if (ctx->drm_dev) 2619 if (ctx->drm_dev)
2620 drm_helper_hpd_irq_event(ctx->drm_dev); 2620 drm_helper_hpd_irq_event(ctx->drm_dev);
2621 2621
2622 if (pm_runtime_suspended(dev)) {
2623 DRM_DEBUG_KMS("%s : Already suspended\n", __func__);
2624 return 0;
2625 }
2626
2622 hdmi_poweroff(hdata); 2627 hdmi_poweroff(hdata);
2623 2628
2624 return 0; 2629 return 0;
@@ -2629,13 +2634,52 @@ static int hdmi_resume(struct device *dev)
2629 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev); 2634 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2630 struct hdmi_context *hdata = ctx->ctx; 2635 struct hdmi_context *hdata = ctx->ctx;
2631 2636
2637 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2638
2639 hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2640
2632 enable_irq(hdata->external_irq); 2641 enable_irq(hdata->external_irq);
2633 enable_irq(hdata->internal_irq); 2642 enable_irq(hdata->internal_irq);
2643
2644 if (!pm_runtime_suspended(dev)) {
2645 DRM_DEBUG_KMS("%s : Already resumed\n", __func__);
2646 return 0;
2647 }
2648
2649 hdmi_poweron(hdata);
2650
2651 return 0;
2652}
2653#endif
2654
2655#ifdef CONFIG_PM_RUNTIME
2656static int hdmi_runtime_suspend(struct device *dev)
2657{
2658 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2659 struct hdmi_context *hdata = ctx->ctx;
2660 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2661
2662 hdmi_poweroff(hdata);
2663
2664 return 0;
2665}
2666
2667static int hdmi_runtime_resume(struct device *dev)
2668{
2669 struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
2670 struct hdmi_context *hdata = ctx->ctx;
2671 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
2672
2673 hdmi_poweron(hdata);
2674
2634 return 0; 2675 return 0;
2635} 2676}
2636#endif 2677#endif
2637 2678
2638static SIMPLE_DEV_PM_OPS(hdmi_pm_ops, hdmi_suspend, hdmi_resume); 2679static const struct dev_pm_ops hdmi_pm_ops = {
2680 SET_SYSTEM_SLEEP_PM_OPS(hdmi_suspend, hdmi_resume)
2681 SET_RUNTIME_PM_OPS(hdmi_runtime_suspend, hdmi_runtime_resume, NULL)
2682};
2639 2683
2640struct platform_driver hdmi_driver = { 2684struct platform_driver hdmi_driver = {
2641 .probe = hdmi_probe, 2685 .probe = hdmi_probe,