drm/nouveau: convert to dev_pm_ops
authorDave Airlie <airlied@redhat.com>
Fri, 2 Nov 2012 01:04:28 +0000 (11:04 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 28 Nov 2012 23:58:00 +0000 (09:58 +1000)
This is a precursor to dynamic power management support for nouveau,

we need to use pm ops for that, so first convert the driver to using pm ops
interfaces.

Signed-off-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_drm.c
drivers/gpu/drm/nouveau/nouveau_drm.h
drivers/gpu/drm/nouveau/nouveau_vga.c

index 8244863cc04989deca0958ed997aaf45f9a1c1a4..f62dbd2733bf77ec948a58db78e8afe724394fd8 100644 (file)
@@ -395,17 +395,12 @@ nouveau_drm_remove(struct pci_dev *pdev)
 }
 
 int
-nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state)
+nouveau_do_suspend(struct drm_device *dev)
 {
-       struct drm_device *dev = pci_get_drvdata(pdev);
        struct nouveau_drm *drm = nouveau_drm(dev);
        struct nouveau_cli *cli;
        int ret;
 
-       if (dev->switch_power_state == DRM_SWITCH_POWER_OFF ||
-           pm_state.event == PM_EVENT_PRETHAW)
-               return 0;
-
        if (dev->mode_config.num_crtc) {
                NV_INFO(drm, "suspending fbcon...\n");
                nouveau_fbcon_set_suspend(dev, 1);
@@ -436,13 +431,6 @@ nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state)
                goto fail_client;
 
        nouveau_agp_fini(drm);
-
-       pci_save_state(pdev);
-       if (pm_state.event == PM_EVENT_SUSPEND) {
-               pci_disable_device(pdev);
-               pci_set_power_state(pdev, PCI_D3hot);
-       }
-
        return 0;
 
 fail_client:
@@ -457,24 +445,33 @@ fail_client:
        return ret;
 }
 
-int
-nouveau_drm_resume(struct pci_dev *pdev)
+int nouveau_pmops_suspend(struct device *dev)
 {
-       struct drm_device *dev = pci_get_drvdata(pdev);
-       struct nouveau_drm *drm = nouveau_drm(dev);
-       struct nouveau_cli *cli;
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct drm_device *drm_dev = pci_get_drvdata(pdev);
        int ret;
 
-       if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+       if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
                return 0;
 
-       NV_INFO(drm, "re-enabling device...\n");
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-       ret = pci_enable_device(pdev);
+       ret = nouveau_do_suspend(drm_dev);
        if (ret)
                return ret;
-       pci_set_master(pdev);
+
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, PCI_D3hot);
+
+       return 0;
+}
+
+int
+nouveau_do_resume(struct drm_device *dev)
+{
+       struct nouveau_drm *drm = nouveau_drm(dev);
+       struct nouveau_cli *cli;
+
+       NV_INFO(drm, "re-enabling device...\n");
 
        nouveau_agp_reset(drm);
 
@@ -500,6 +497,42 @@ nouveau_drm_resume(struct pci_dev *pdev)
        return 0;
 }
 
+int nouveau_pmops_resume(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct drm_device *drm_dev = pci_get_drvdata(pdev);
+       int ret;
+
+       if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+               return 0;
+
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+       ret = pci_enable_device(pdev);
+       if (ret)
+               return ret;
+       pci_set_master(pdev);
+
+       return nouveau_do_resume(drm_dev);
+}
+
+static int nouveau_pmops_freeze(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct drm_device *drm_dev = pci_get_drvdata(pdev);
+
+       return nouveau_do_suspend(drm_dev);
+}
+
+static int nouveau_pmops_thaw(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct drm_device *drm_dev = pci_get_drvdata(pdev);
+
+       return nouveau_do_resume(drm_dev);
+}
+
+
 static int
 nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)
 {
@@ -652,14 +685,22 @@ nouveau_drm_pci_table[] = {
        {}
 };
 
+static const struct dev_pm_ops nouveau_pm_ops = {
+       .suspend = nouveau_pmops_suspend,
+       .resume = nouveau_pmops_resume,
+       .freeze = nouveau_pmops_freeze,
+       .thaw = nouveau_pmops_thaw,
+       .poweroff = nouveau_pmops_freeze,
+       .restore = nouveau_pmops_resume,
+};
+
 static struct pci_driver
 nouveau_drm_pci_driver = {
        .name = "nouveau",
        .id_table = nouveau_drm_pci_table,
        .probe = nouveau_drm_probe,
        .remove = nouveau_drm_remove,
-       .suspend = nouveau_drm_suspend,
-       .resume = nouveau_drm_resume,
+       .driver.pm = &nouveau_pm_ops,
 };
 
 static int __init
index a10169927086dfea6c826dac0378ae1d2c82ffb3..aa89eb938b47441049034117790ec614cc771fbc 100644 (file)
@@ -129,8 +129,8 @@ nouveau_dev(struct drm_device *dev)
        return nv_device(nouveau_drm(dev)->device);
 }
 
-int nouveau_drm_suspend(struct pci_dev *, pm_message_t);
-int nouveau_drm_resume(struct pci_dev *);
+int nouveau_pmops_suspend(struct device *);
+int nouveau_pmops_resume(struct device *);
 
 #define NV_FATAL(cli, fmt, args...) nv_fatal((cli), fmt, ##args)
 #define NV_ERROR(cli, fmt, args...) nv_error((cli), fmt, ##args)
index 6f0ac64873dfb9983351159d141851fa15cd06ba..25d3495725ebc3c4d8b243e84b8714a929c20b12 100644 (file)
@@ -31,12 +31,11 @@ nouveau_switcheroo_set_state(struct pci_dev *pdev,
                             enum vga_switcheroo_state state)
 {
        struct drm_device *dev = pci_get_drvdata(pdev);
-       pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
 
        if (state == VGA_SWITCHEROO_ON) {
                printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
                dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
-               nouveau_drm_resume(pdev);
+               nouveau_pmops_resume(&pdev->dev);
                drm_kms_helper_poll_enable(dev);
                dev->switch_power_state = DRM_SWITCH_POWER_ON;
        } else {
@@ -44,7 +43,7 @@ nouveau_switcheroo_set_state(struct pci_dev *pdev,
                dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
                drm_kms_helper_poll_disable(dev);
                nouveau_switcheroo_optimus_dsm();
-               nouveau_drm_suspend(pdev, pmm);
+               nouveau_pmops_suspend(&pdev->dev);
                dev->switch_power_state = DRM_SWITCH_POWER_OFF;
        }
 }