drm/nouveau: convert to dev_pm_ops
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>
This commit is contained in:
Родитель
c839d748bd
Коммит
2d8b9ccbce
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче