drm: atmel-hlcdc: Add PM suspend/resume support
authorSylvain Rochet <sylvain.rochet@finsecur.com>
Sun, 22 Feb 2015 17:51:03 +0000 (18:51 +0100)
committerBoris Brezillon <boris.brezillon@free-electrons.com>
Tue, 24 Feb 2015 10:23:07 +0000 (11:23 +0100)
On suspend: switch off CRTC if not already suspended with runtime PM

On resume: switch on CRTC if we were not already suspended from runtime
PM while suspending.

Signed-off-by: Sylvain Rochet <sylvain.rochet@finsecur.com>
Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c

index 47fd1470f755d5edd7bef48a97275f8480b43f3a..01afeafe17b1cda0143caf652adb70e131b7464f 100644 (file)
@@ -561,6 +561,52 @@ static int atmel_hlcdc_dc_drm_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int atmel_hlcdc_dc_drm_suspend(struct device *dev)
+{
+       struct drm_device *drm_dev = dev_get_drvdata(dev);
+       struct drm_crtc *crtc;
+
+       if (pm_runtime_suspended(dev))
+               return 0;
+
+       drm_modeset_lock_all(drm_dev);
+       list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) {
+               struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+               if (crtc->enabled) {
+                       crtc_funcs->disable(crtc);
+                       /* save enable state for resume */
+                       crtc->enabled = true;
+               }
+       }
+       drm_modeset_unlock_all(drm_dev);
+       return 0;
+}
+
+static int atmel_hlcdc_dc_drm_resume(struct device *dev)
+{
+       struct drm_device *drm_dev = dev_get_drvdata(dev);
+       struct drm_crtc *crtc;
+
+       if (pm_runtime_suspended(dev))
+               return 0;
+
+       drm_modeset_lock_all(drm_dev);
+       list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) {
+               struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+               if (crtc->enabled) {
+                       crtc->enabled = false;
+                       crtc_funcs->enable(crtc);
+               }
+       }
+       drm_modeset_unlock_all(drm_dev);
+       return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(atmel_hlcdc_dc_drm_pm_ops,
+               atmel_hlcdc_dc_drm_suspend, atmel_hlcdc_dc_drm_resume);
+
 static const struct of_device_id atmel_hlcdc_dc_of_match[] = {
        { .compatible = "atmel,hlcdc-display-controller" },
        { },
@@ -571,6 +617,7 @@ static struct platform_driver atmel_hlcdc_dc_platform_driver = {
        .remove = atmel_hlcdc_dc_drm_remove,
        .driver = {
                .name   = "atmel-hlcdc-display-controller",
+               .pm     = &atmel_hlcdc_dc_drm_pm_ops,
                .of_match_table = atmel_hlcdc_dc_of_match,
        },
 };