aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-11-01 21:04:28 -0400
committerBen Skeggs <bskeggs@redhat.com>2012-11-28 18:58:00 -0500
commit2d8b9ccbcee694c9ce681ec596df642e52ddcb15 (patch)
tree7c68f6881dfebc34d23ccbd7775121ed805a9acd
parentc839d748bdaa4f373368abeef3efc18e21e78313 (diff)
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>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c93
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_vga.c5
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 8244863cc049..f62dbd2733bf 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -395,17 +395,12 @@ nouveau_drm_remove(struct pci_dev *pdev)
395} 395}
396 396
397int 397int
398nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state) 398nouveau_do_suspend(struct drm_device *dev)
399{ 399{
400 struct drm_device *dev = pci_get_drvdata(pdev);
401 struct nouveau_drm *drm = nouveau_drm(dev); 400 struct nouveau_drm *drm = nouveau_drm(dev);
402 struct nouveau_cli *cli; 401 struct nouveau_cli *cli;
403 int ret; 402 int ret;
404 403
405 if (dev->switch_power_state == DRM_SWITCH_POWER_OFF ||
406 pm_state.event == PM_EVENT_PRETHAW)
407 return 0;
408
409 if (dev->mode_config.num_crtc) { 404 if (dev->mode_config.num_crtc) {
410 NV_INFO(drm, "suspending fbcon...\n"); 405 NV_INFO(drm, "suspending fbcon...\n");
411 nouveau_fbcon_set_suspend(dev, 1); 406 nouveau_fbcon_set_suspend(dev, 1);
@@ -436,13 +431,6 @@ nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state)
436 goto fail_client; 431 goto fail_client;
437 432
438 nouveau_agp_fini(drm); 433 nouveau_agp_fini(drm);
439
440 pci_save_state(pdev);
441 if (pm_state.event == PM_EVENT_SUSPEND) {
442 pci_disable_device(pdev);
443 pci_set_power_state(pdev, PCI_D3hot);
444 }
445
446 return 0; 434 return 0;
447 435
448fail_client: 436fail_client:
@@ -457,24 +445,33 @@ fail_client:
457 return ret; 445 return ret;
458} 446}
459 447
460int 448int nouveau_pmops_suspend(struct device *dev)
461nouveau_drm_resume(struct pci_dev *pdev)
462{ 449{
463 struct drm_device *dev = pci_get_drvdata(pdev); 450 struct pci_dev *pdev = to_pci_dev(dev);
464 struct nouveau_drm *drm = nouveau_drm(dev); 451 struct drm_device *drm_dev = pci_get_drvdata(pdev);
465 struct nouveau_cli *cli;
466 int ret; 452 int ret;
467 453
468 if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) 454 if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
469 return 0; 455 return 0;
470 456
471 NV_INFO(drm, "re-enabling device...\n"); 457 ret = nouveau_do_suspend(drm_dev);
472 pci_set_power_state(pdev, PCI_D0);
473 pci_restore_state(pdev);
474 ret = pci_enable_device(pdev);
475 if (ret) 458 if (ret)
476 return ret; 459 return ret;
477 pci_set_master(pdev); 460
461 pci_save_state(pdev);
462 pci_disable_device(pdev);
463 pci_set_power_state(pdev, PCI_D3hot);
464
465 return 0;
466}
467
468int
469nouveau_do_resume(struct drm_device *dev)
470{
471 struct nouveau_drm *drm = nouveau_drm(dev);
472 struct nouveau_cli *cli;
473
474 NV_INFO(drm, "re-enabling device...\n");
478 475
479 nouveau_agp_reset(drm); 476 nouveau_agp_reset(drm);
480 477
@@ -500,6 +497,42 @@ nouveau_drm_resume(struct pci_dev *pdev)
500 return 0; 497 return 0;
501} 498}
502 499
500int nouveau_pmops_resume(struct device *dev)
501{
502 struct pci_dev *pdev = to_pci_dev(dev);
503 struct drm_device *drm_dev = pci_get_drvdata(pdev);
504 int ret;
505
506 if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
507 return 0;
508
509 pci_set_power_state(pdev, PCI_D0);
510 pci_restore_state(pdev);
511 ret = pci_enable_device(pdev);
512 if (ret)
513 return ret;
514 pci_set_master(pdev);
515
516 return nouveau_do_resume(drm_dev);
517}
518
519static int nouveau_pmops_freeze(struct device *dev)
520{
521 struct pci_dev *pdev = to_pci_dev(dev);
522 struct drm_device *drm_dev = pci_get_drvdata(pdev);
523
524 return nouveau_do_suspend(drm_dev);
525}
526
527static int nouveau_pmops_thaw(struct device *dev)
528{
529 struct pci_dev *pdev = to_pci_dev(dev);
530 struct drm_device *drm_dev = pci_get_drvdata(pdev);
531
532 return nouveau_do_resume(drm_dev);
533}
534
535
503static int 536static int
504nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv) 537nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)
505{ 538{
@@ -652,14 +685,22 @@ nouveau_drm_pci_table[] = {
652 {} 685 {}
653}; 686};
654 687
688static const struct dev_pm_ops nouveau_pm_ops = {
689 .suspend = nouveau_pmops_suspend,
690 .resume = nouveau_pmops_resume,
691 .freeze = nouveau_pmops_freeze,
692 .thaw = nouveau_pmops_thaw,
693 .poweroff = nouveau_pmops_freeze,
694 .restore = nouveau_pmops_resume,
695};
696
655static struct pci_driver 697static struct pci_driver
656nouveau_drm_pci_driver = { 698nouveau_drm_pci_driver = {
657 .name = "nouveau", 699 .name = "nouveau",
658 .id_table = nouveau_drm_pci_table, 700 .id_table = nouveau_drm_pci_table,
659 .probe = nouveau_drm_probe, 701 .probe = nouveau_drm_probe,
660 .remove = nouveau_drm_remove, 702 .remove = nouveau_drm_remove,
661 .suspend = nouveau_drm_suspend, 703 .driver.pm = &nouveau_pm_ops,
662 .resume = nouveau_drm_resume,
663}; 704};
664 705
665static int __init 706static int __init
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h
index a10169927086..aa89eb938b47 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)
129 return nv_device(nouveau_drm(dev)->device); 129 return nv_device(nouveau_drm(dev)->device);
130} 130}
131 131
132int nouveau_drm_suspend(struct pci_dev *, pm_message_t); 132int nouveau_pmops_suspend(struct device *);
133int nouveau_drm_resume(struct pci_dev *); 133int nouveau_pmops_resume(struct device *);
134 134
135#define NV_FATAL(cli, fmt, args...) nv_fatal((cli), fmt, ##args) 135#define NV_FATAL(cli, fmt, args...) nv_fatal((cli), fmt, ##args)
136#define NV_ERROR(cli, fmt, args...) nv_error((cli), fmt, ##args) 136#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 6f0ac64873df..25d3495725eb 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,
31 enum vga_switcheroo_state state) 31 enum vga_switcheroo_state state)
32{ 32{
33 struct drm_device *dev = pci_get_drvdata(pdev); 33 struct drm_device *dev = pci_get_drvdata(pdev);
34 pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
35 34
36 if (state == VGA_SWITCHEROO_ON) { 35 if (state == VGA_SWITCHEROO_ON) {
37 printk(KERN_ERR "VGA switcheroo: switched nouveau on\n"); 36 printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
38 dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; 37 dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
39 nouveau_drm_resume(pdev); 38 nouveau_pmops_resume(&pdev->dev);
40 drm_kms_helper_poll_enable(dev); 39 drm_kms_helper_poll_enable(dev);
41 dev->switch_power_state = DRM_SWITCH_POWER_ON; 40 dev->switch_power_state = DRM_SWITCH_POWER_ON;
42 } else { 41 } else {
@@ -44,7 +43,7 @@ nouveau_switcheroo_set_state(struct pci_dev *pdev,
44 dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; 43 dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
45 drm_kms_helper_poll_disable(dev); 44 drm_kms_helper_poll_disable(dev);
46 nouveau_switcheroo_optimus_dsm(); 45 nouveau_switcheroo_optimus_dsm();
47 nouveau_drm_suspend(pdev, pmm); 46 nouveau_pmops_suspend(&pdev->dev);
48 dev->switch_power_state = DRM_SWITCH_POWER_OFF; 47 dev->switch_power_state = DRM_SWITCH_POWER_OFF;
49 } 48 }
50} 49}