From: Dave Airlie <airl...@redhat.com>

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 <airl...@redhat.com>
---
 drivers/gpu/drm/nouveau/nouveau_drm.c | 93 +++++++++++++++++++++++++----------
 drivers/gpu/drm/nouveau/nouveau_drm.h |  4 +-
 drivers/gpu/drm/nouveau/nouveau_vga.c |  5 +-
 3 files changed, 71 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c 
b/drivers/gpu/drm/nouveau/nouveau_drm.c
index ccae8c2..85aa1a6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -392,17 +392,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;
-
        NV_INFO(drm, "suspending fbcon...\n");
        nouveau_fbcon_set_suspend(dev, 1);
 
@@ -431,13 +426,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:
@@ -450,24 +438,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);
 
@@ -491,6 +488,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)
 {
@@ -643,14 +676,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
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h 
b/drivers/gpu/drm/nouveau/nouveau_drm.h
index 8194712..e0c99aa 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.h
@@ -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)
diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c 
b/drivers/gpu/drm/nouveau/nouveau_vga.c
index 6f0ac64..25d3495 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vga.c
+++ b/drivers/gpu/drm/nouveau/nouveau_vga.c
@@ -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;
        }
 }
-- 
1.7.12.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to