Moves the PCI-specific portions of nouveau_pmops to NVKM, leaving the
DRM pieces where they are.  The NVKM functions are called through the
the nvkm_device_pci_driver struct from DRM for now, but will be fully
separated once the DRM driver is implemented on an auxiliary device.

Signed-off-by: Ben Skeggs <bske...@nvidia.com>
---
 drivers/gpu/drm/nouveau/nouveau_acpi.h    |  3 -
 drivers/gpu/drm/nouveau/nouveau_drm.c     | 24 ++-----
 drivers/gpu/drm/nouveau/nvkm/device/pci.c | 76 +++++++++++++++++++++++
 3 files changed, 80 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.h 
b/drivers/gpu/drm/nouveau/nouveau_acpi.h
index be1b218cb921..b4c7ae78cedc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.h
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.h
@@ -5,13 +5,10 @@
 #define ROM_BIOS_PAGE 4096
 
 #if defined(CONFIG_ACPI) && defined(CONFIG_X86)
-#include <device/acpi.h>
-static inline void nouveau_switcheroo_optimus_dsm(void) { 
nvkm_acpi_switcheroo_set_powerdown(); }
 void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
 bool nouveau_acpi_video_backlight_use_native(void);
 void nouveau_acpi_video_register_backlight(void);
 #else
-static inline void nouveau_switcheroo_optimus_dsm(void) {}
 static inline void *nouveau_acpi_edid(struct drm_device *dev, struct 
drm_connector *connector) { return NULL; }
 static inline bool nouveau_acpi_video_backlight_use_native(void) { return 
true; }
 static inline void nouveau_acpi_video_register_backlight(void) {}
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c 
b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 76eddf172bb5..aa54aee23814 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -901,11 +901,7 @@ nouveau_pmops_suspend(struct device *dev)
        if (ret)
                return ret;
 
-       pci_save_state(pdev);
-       pci_disable_device(pdev);
-       pci_set_power_state(pdev, PCI_D3hot);
-       udelay(200);
-       return 0;
+       return nvkm_device_pci_driver.driver.pm->suspend(dev);
 }
 
 int
@@ -919,12 +915,9 @@ nouveau_pmops_resume(struct device *dev)
            drm->dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF)
                return 0;
 
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-       ret = pci_enable_device(pdev);
+       ret = nvkm_device_pci_driver.driver.pm->resume(dev);
        if (ret)
                return ret;
-       pci_set_master(pdev);
 
        ret = nouveau_do_resume(drm, false);
 
@@ -973,12 +966,8 @@ nouveau_pmops_runtime_suspend(struct device *dev)
                return -EBUSY;
        }
 
-       nouveau_switcheroo_optimus_dsm();
        ret = nouveau_do_suspend(drm, true);
-       pci_save_state(pdev);
-       pci_disable_device(pdev);
-       pci_ignore_hotplug(pdev);
-       pci_set_power_state(pdev, PCI_D3cold);
+       ret = nvkm_device_pci_driver.driver.pm->runtime_suspend(dev);
        drm->dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF;
        return ret;
 }
@@ -995,12 +984,9 @@ nouveau_pmops_runtime_resume(struct device *dev)
                return -EBUSY;
        }
 
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-       ret = pci_enable_device(pdev);
+       ret = nvkm_device_pci_driver.driver.pm->runtime_resume(dev);
        if (ret)
                return ret;
-       pci_set_master(pdev);
 
        ret = nouveau_do_resume(drm, true);
        if (ret) {
@@ -1008,8 +994,6 @@ nouveau_pmops_runtime_resume(struct device *dev)
                return ret;
        }
 
-       /* do magic */
-       nvif_mask(&drm->device, 0x088488, (1 << 25), (1 << 25));
        drm->dev->switch_power_state = DRM_SWITCH_POWER_ON;
 
        /* Monitors may have been connected / disconnected during suspend */
diff --git a/drivers/gpu/drm/nouveau/nvkm/device/pci.c 
b/drivers/gpu/drm/nouveau/nvkm/device/pci.c
index d454d56a7909..a66cb9d474d5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/device/pci.c
+++ b/drivers/gpu/drm/nouveau/nvkm/device/pci.c
@@ -1620,6 +1620,81 @@ nvkm_device_pci_func = {
 
 #include "nouveau_drv.h"
 
+static int
+nvkm_device_pci_pm_runtime_resume(struct device *dev)
+{
+       struct nvkm_device *device = ((struct nouveau_drm 
*)dev_get_drvdata(dev))->nvkm;
+       struct pci_dev *pdev = nvkm_device_pci(device)->pdev;
+       int ret;
+
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+
+       ret = pci_enable_device(pdev);
+       if (ret)
+               return ret;
+
+       pci_set_master(pdev);
+
+       /* do magic */
+       nvkm_mask(device, 0x088488, (1 << 25), (1 << 25));
+       return 0;
+}
+
+static int
+nvkm_device_pci_pm_runtime_suspend(struct device *dev)
+{
+       struct nvkm_device *device = ((struct nouveau_drm 
*)dev_get_drvdata(dev))->nvkm;
+       struct pci_dev *pdev = nvkm_device_pci(device)->pdev;
+
+       nvkm_acpi_switcheroo_set_powerdown();
+
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+       pci_ignore_hotplug(pdev);
+       pci_set_power_state(pdev, PCI_D3cold);
+       return 0;
+}
+
+static int
+nvkm_device_pci_pm_resume(struct device *dev)
+{
+       struct nvkm_device *device = ((struct nouveau_drm 
*)dev_get_drvdata(dev))->nvkm;
+       struct pci_dev *pdev = nvkm_device_pci(device)->pdev;
+       int ret;
+
+       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 0;
+}
+
+static int
+nvkm_device_pci_pm_suspend(struct device *dev)
+{
+       struct nvkm_device *device = ((struct nouveau_drm 
*)dev_get_drvdata(dev))->nvkm;
+       struct pci_dev *pdev = nvkm_device_pci(device)->pdev;
+
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, PCI_D3hot);
+       udelay(200);
+       return 0;
+}
+
+static const struct dev_pm_ops
+nvkm_device_pci_pm = {
+       .suspend = nvkm_device_pci_pm_suspend,
+       .resume = nvkm_device_pci_pm_resume,
+       .runtime_suspend = nvkm_device_pci_pm_runtime_suspend,
+       .runtime_resume = nvkm_device_pci_pm_runtime_resume,
+};
+
 static void
 nvkm_device_pci_remove(struct pci_dev *dev)
 {
@@ -1787,4 +1862,5 @@ struct pci_driver
 nvkm_device_pci_driver = {
        .probe = nvkm_device_pci_probe,
        .remove = nvkm_device_pci_remove,
+       .driver.pm = &nvkm_device_pci_pm,
 };
-- 
2.44.0

Reply via email to