diff options
author | Sean Paul <seanpaul@chromium.org> | 2014-01-30 16:19:27 -0500 |
---|---|---|
committer | Inki Dae <daeinki@gmail.com> | 2014-03-23 11:36:36 -0400 |
commit | af65c804877078a58cb02cc0f2ce4198401402fc (patch) | |
tree | 1894a3b77ee5098bafe60f69694ca5d122a1be36 /drivers/gpu/drm/exynos/exynos_drm_fimd.c | |
parent | a43b933bcbbd6c7e2660b672a311345cea9524c1 (diff) |
drm/exynos: Consolidate suspend/resume in drm_drv
This patch removes all of the suspend/resume logic from the individual
drivers and consolidates it in drm_drv. This consolidation reduces the
number of functions which enable/disable the hardware to just one -- the
dpms callback. This ensures that we always power up/down in a consistent
manner.
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_fimd.c')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fimd.c | 86 |
1 files changed, 9 insertions, 77 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 1efdcac4510d..f78fbf4682b4 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) | |||
732 | 732 | ||
733 | ctx->suspended = false; | 733 | ctx->suspended = false; |
734 | 734 | ||
735 | pm_runtime_get_sync(ctx->dev); | ||
736 | |||
735 | ret = clk_prepare_enable(ctx->bus_clk); | 737 | ret = clk_prepare_enable(ctx->bus_clk); |
736 | if (ret < 0) { | 738 | if (ret < 0) { |
737 | DRM_ERROR("Failed to prepare_enable the bus clk [%d]\n", ret); | 739 | 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) | |||
785 | clk_disable_unprepare(ctx->lcd_clk); | 787 | clk_disable_unprepare(ctx->lcd_clk); |
786 | clk_disable_unprepare(ctx->bus_clk); | 788 | clk_disable_unprepare(ctx->bus_clk); |
787 | 789 | ||
790 | pm_runtime_put_sync(ctx->dev); | ||
791 | |||
788 | ctx->suspended = true; | 792 | ctx->suspended = true; |
789 | return 0; | 793 | return 0; |
790 | } | 794 | } |
791 | 795 | ||
792 | static void fimd_dpms(struct exynos_drm_manager *mgr, int mode) | 796 | static void fimd_dpms(struct exynos_drm_manager *mgr, int mode) |
793 | { | 797 | { |
794 | struct fimd_context *ctx = mgr->ctx; | 798 | DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode); |
795 | |||
796 | DRM_DEBUG_KMS("%d\n", mode); | ||
797 | 799 | ||
798 | switch (mode) { | 800 | switch (mode) { |
799 | case DRM_MODE_DPMS_ON: | 801 | case DRM_MODE_DPMS_ON: |
800 | /* | 802 | fimd_poweron(mgr); |
801 | * enable fimd hardware only if suspended status. | ||
802 | * | ||
803 | * P.S. fimd_dpms function would be called at booting time so | ||
804 | * clk_enable could be called double time. | ||
805 | */ | ||
806 | if (ctx->suspended) | ||
807 | pm_runtime_get_sync(ctx->dev); | ||
808 | break; | 803 | break; |
809 | case DRM_MODE_DPMS_STANDBY: | 804 | case DRM_MODE_DPMS_STANDBY: |
810 | case DRM_MODE_DPMS_SUSPEND: | 805 | case DRM_MODE_DPMS_SUSPEND: |
811 | case DRM_MODE_DPMS_OFF: | 806 | case DRM_MODE_DPMS_OFF: |
812 | if (!ctx->suspended) | 807 | fimd_poweroff(mgr); |
813 | pm_runtime_put_sync(ctx->dev); | ||
814 | break; | 808 | break; |
815 | default: | 809 | default: |
816 | DRM_DEBUG_KMS("unspecified mode %d\n", mode); | 810 | DRM_DEBUG_KMS("unspecified mode %d\n", mode); |
@@ -929,7 +923,6 @@ static int fimd_probe(struct platform_device *pdev) | |||
929 | exynos_drm_manager_register(&fimd_manager); | 923 | exynos_drm_manager_register(&fimd_manager); |
930 | 924 | ||
931 | pm_runtime_enable(dev); | 925 | pm_runtime_enable(dev); |
932 | pm_runtime_get_sync(dev); | ||
933 | 926 | ||
934 | for (win = 0; win < WINDOWS_NR; win++) | 927 | for (win = 0; win < WINDOWS_NR; win++) |
935 | fimd_clear_win(ctx, win); | 928 | fimd_clear_win(ctx, win); |
@@ -939,84 +932,23 @@ static int fimd_probe(struct platform_device *pdev) | |||
939 | 932 | ||
940 | static int fimd_remove(struct platform_device *pdev) | 933 | static int fimd_remove(struct platform_device *pdev) |
941 | { | 934 | { |
942 | struct device *dev = &pdev->dev; | ||
943 | struct exynos_drm_manager *mgr = platform_get_drvdata(pdev); | 935 | struct exynos_drm_manager *mgr = platform_get_drvdata(pdev); |
944 | struct fimd_context *ctx = mgr->ctx; | ||
945 | 936 | ||
946 | exynos_drm_manager_unregister(&fimd_manager); | 937 | exynos_drm_manager_unregister(&fimd_manager); |
947 | 938 | ||
948 | if (ctx->suspended) | 939 | fimd_dpms(mgr, DRM_MODE_DPMS_OFF); |
949 | goto out; | ||
950 | |||
951 | pm_runtime_set_suspended(dev); | ||
952 | pm_runtime_put_sync(dev); | ||
953 | 940 | ||
954 | out: | 941 | pm_runtime_disable(&pdev->dev); |
955 | pm_runtime_disable(dev); | ||
956 | |||
957 | return 0; | ||
958 | } | ||
959 | |||
960 | #ifdef CONFIG_PM_SLEEP | ||
961 | static int fimd_suspend(struct device *dev) | ||
962 | { | ||
963 | struct exynos_drm_manager *mgr = get_fimd_manager(dev); | ||
964 | |||
965 | /* | ||
966 | * do not use pm_runtime_suspend(). if pm_runtime_suspend() is | ||
967 | * called here, an error would be returned by that interface | ||
968 | * because the usage_count of pm runtime is more than 1. | ||
969 | */ | ||
970 | if (!pm_runtime_suspended(dev)) | ||
971 | return fimd_poweroff(mgr); | ||
972 | 942 | ||
973 | return 0; | 943 | return 0; |
974 | } | 944 | } |
975 | 945 | ||
976 | static int fimd_resume(struct device *dev) | ||
977 | { | ||
978 | struct exynos_drm_manager *mgr = get_fimd_manager(dev); | ||
979 | |||
980 | /* | ||
981 | * if entered to sleep when lcd panel was on, the usage_count | ||
982 | * of pm runtime would still be 1 so in this case, fimd driver | ||
983 | * should be on directly not drawing on pm runtime interface. | ||
984 | */ | ||
985 | if (pm_runtime_suspended(dev)) | ||
986 | return 0; | ||
987 | |||
988 | return fimd_poweron(mgr); | ||
989 | } | ||
990 | #endif | ||
991 | |||
992 | #ifdef CONFIG_PM_RUNTIME | ||
993 | static int fimd_runtime_suspend(struct device *dev) | ||
994 | { | ||
995 | struct exynos_drm_manager *mgr = get_fimd_manager(dev); | ||
996 | |||
997 | return fimd_poweroff(mgr); | ||
998 | } | ||
999 | |||
1000 | static int fimd_runtime_resume(struct device *dev) | ||
1001 | { | ||
1002 | struct exynos_drm_manager *mgr = get_fimd_manager(dev); | ||
1003 | |||
1004 | return fimd_poweron(mgr); | ||
1005 | } | ||
1006 | #endif | ||
1007 | |||
1008 | static const struct dev_pm_ops fimd_pm_ops = { | ||
1009 | SET_SYSTEM_SLEEP_PM_OPS(fimd_suspend, fimd_resume) | ||
1010 | SET_RUNTIME_PM_OPS(fimd_runtime_suspend, fimd_runtime_resume, NULL) | ||
1011 | }; | ||
1012 | |||
1013 | struct platform_driver fimd_driver = { | 946 | struct platform_driver fimd_driver = { |
1014 | .probe = fimd_probe, | 947 | .probe = fimd_probe, |
1015 | .remove = fimd_remove, | 948 | .remove = fimd_remove, |
1016 | .driver = { | 949 | .driver = { |
1017 | .name = "exynos4-fb", | 950 | .name = "exynos4-fb", |
1018 | .owner = THIS_MODULE, | 951 | .owner = THIS_MODULE, |
1019 | .pm = &fimd_pm_ops, | ||
1020 | .of_match_table = fimd_driver_dt_match, | 952 | .of_match_table = fimd_driver_dt_match, |
1021 | }, | 953 | }, |
1022 | }; | 954 | }; |