summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/stm/drv.c
diff options
context:
space:
mode:
authorYannick Fertré <yannick.fertre@st.com>2019-06-03 10:32:02 +0200
committerBenjamin Gaignard <benjamin.gaignard@linaro.org>2019-06-07 14:45:22 +0200
commit35ab6cfbf21178d4dd93d1fe4cb1416c1d6b566d (patch)
treebacdb0f3003ae4a1d59520587780151940d7d6c3 /drivers/gpu/drm/stm/drv.c
parent630bec0c16ee0a003d5f1f55f228b7a495c1d938 (diff)
drm/stm: support runtime power management
This patch enables runtime power management (runtime PM) support for the display controller. pm_runtime_enable() and pm_runtime_disable() are added during ltdc load and unload respectively. pm_runtime_get_sync() and pm_runtime_put_sync() are added for ltdc register access. Signed-off-by: Yannick Fertré <yannick.fertre@st.com> Acked-by: Philippe Cornu <philippe.cornu@st.com> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/1559550722-14091-1-git-send-email-yannick.fertre@st.com
Diffstat (limited to 'drivers/gpu/drm/stm/drv.c')
-rw-r--r--drivers/gpu/drm/stm/drv.c43
1 files changed, 35 insertions, 8 deletions
diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index 5834ef56fbaa..5659572151a8 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -12,6 +12,7 @@
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
@@ -135,14 +136,15 @@ static __maybe_unused int drv_suspend(struct device *dev)
struct ltdc_device *ldev = ddev->dev_private;
struct drm_atomic_state *state;
- drm_kms_helper_poll_disable(ddev);
+ if (WARN_ON(!ldev->suspend_state))
+ return -ENOENT;
+
state = drm_atomic_helper_suspend(ddev);
- if (IS_ERR(state)) {
- drm_kms_helper_poll_enable(ddev);
+ if (IS_ERR(state))
return PTR_ERR(state);
- }
+
ldev->suspend_state = state;
- ltdc_suspend(ddev);
+ pm_runtime_force_suspend(dev);
return 0;
}
@@ -151,16 +153,41 @@ static __maybe_unused int drv_resume(struct device *dev)
{
struct drm_device *ddev = dev_get_drvdata(dev);
struct ltdc_device *ldev = ddev->dev_private;
+ int ret;
- ltdc_resume(ddev);
- drm_atomic_helper_resume(ddev, ldev->suspend_state);
- drm_kms_helper_poll_enable(ddev);
+ pm_runtime_force_resume(dev);
+ ret = drm_atomic_helper_resume(ddev, ldev->suspend_state);
+ if (ret) {
+ pm_runtime_force_suspend(dev);
+ ldev->suspend_state = NULL;
+ return ret;
+ }
return 0;
}
+static __maybe_unused int drv_runtime_suspend(struct device *dev)
+{
+ struct drm_device *ddev = dev_get_drvdata(dev);
+
+ DRM_DEBUG_DRIVER("\n");
+ ltdc_suspend(ddev);
+
+ return 0;
+}
+
+static __maybe_unused int drv_runtime_resume(struct device *dev)
+{
+ struct drm_device *ddev = dev_get_drvdata(dev);
+
+ DRM_DEBUG_DRIVER("\n");
+ return ltdc_resume(ddev);
+}
+
static const struct dev_pm_ops drv_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(drv_suspend, drv_resume)
+ SET_RUNTIME_PM_OPS(drv_runtime_suspend,
+ drv_runtime_resume, NULL)
};
static int stm_drm_platform_probe(struct platform_device *pdev)