summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/cirrus/cirrus_drv.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2014-04-25 01:46:58 +0400
committerArnd Bergmann <arnd@arndb.de>2014-04-25 01:46:58 +0400
commit1fc52762e33cc905331681364d79424d921f60f2 (patch)
treed7347407cbbdb7a0565e3b4d09aaf40f0705491a /drivers/gpu/drm/cirrus/cirrus_drv.c
parent9ef1af9ea28c23d0eaed97f7f5142788b6cf570a (diff)
parentcf2e0a73ca9ad376825c013ebaa145608abc27d7 (diff)
downloadlinux-1fc52762e33cc905331681364d79424d921f60f2.tar.xz
Merge tag 'vexpress/fixes-for-3.15' of git://git.linaro.org/people/pawel.moll/linux into fixes
ARM Versatile Express fixes for 3.15 This series contains straight-forward fixes for different Versatile Express infrastructure drivers: - NULL pointer dereference on the error path in the clk driver - out of boundary array access in the dcscb driver - broken restart/power off implementation - mis-interpreted voltage unit in the spc driver * tag 'vexpress/fixes-for-3.15' of git://git.linaro.org/people/pawel.moll/linux: ARM: vexpress/TC2: Convert OPP voltage to uV before storing power/reset: vexpress: Fix restart/power off operation arm/mach-vexpress: array accessed out of bounds clk: vexpress: NULL dereference on error path Includes an update to 3.15-rc2 Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/gpu/drm/cirrus/cirrus_drv.c')
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_drv.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c
index 953fc8aea69c..08ce520f61a5 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.c
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/console.h>
#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#include "cirrus_drv.h"
@@ -75,6 +76,41 @@ static void cirrus_pci_remove(struct pci_dev *pdev)
drm_put_dev(dev);
}
+static int cirrus_pm_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct drm_device *drm_dev = pci_get_drvdata(pdev);
+ struct cirrus_device *cdev = drm_dev->dev_private;
+
+ drm_kms_helper_poll_disable(drm_dev);
+
+ if (cdev->mode_info.gfbdev) {
+ console_lock();
+ fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 1);
+ console_unlock();
+ }
+
+ return 0;
+}
+
+static int cirrus_pm_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct drm_device *drm_dev = pci_get_drvdata(pdev);
+ struct cirrus_device *cdev = drm_dev->dev_private;
+
+ drm_helper_resume_force_mode(drm_dev);
+
+ if (cdev->mode_info.gfbdev) {
+ console_lock();
+ fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 0);
+ console_unlock();
+ }
+
+ drm_kms_helper_poll_enable(drm_dev);
+ return 0;
+}
+
static const struct file_operations cirrus_driver_fops = {
.owner = THIS_MODULE,
.open = drm_open,
@@ -103,11 +139,17 @@ static struct drm_driver driver = {
.dumb_destroy = drm_gem_dumb_destroy,
};
+static const struct dev_pm_ops cirrus_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(cirrus_pm_suspend,
+ cirrus_pm_resume)
+};
+
static struct pci_driver cirrus_pci_driver = {
.name = DRIVER_NAME,
.id_table = pciidlist,
.probe = cirrus_pci_probe,
.remove = cirrus_pci_remove,
+ .driver.pm = &cirrus_pm_ops,
};
static int __init cirrus_init(void)