diff options
author | Dave Airlie <airlied@redhat.com> | 2012-11-01 21:04:28 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-11-28 18:58:00 -0500 |
commit | 2d8b9ccbcee694c9ce681ec596df642e52ddcb15 (patch) | |
tree | 7c68f6881dfebc34d23ccbd7775121ed805a9acd | |
parent | c839d748bdaa4f373368abeef3efc18e21e78313 (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.c | 93 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drm.h | 4 | ||||
-rw-r--r-- | 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 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 | ||
397 | int | 397 | int |
398 | nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state) | 398 | nouveau_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 | ||
448 | fail_client: | 436 | fail_client: |
@@ -457,24 +445,33 @@ fail_client: | |||
457 | return ret; | 445 | return ret; |
458 | } | 446 | } |
459 | 447 | ||
460 | int | 448 | int nouveau_pmops_suspend(struct device *dev) |
461 | nouveau_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 | |||
468 | int | ||
469 | nouveau_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 | ||
500 | int 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 | |||
519 | static 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 | |||
527 | static 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 | |||
503 | static int | 536 | static int |
504 | nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv) | 537 | nouveau_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 | ||
688 | static 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 | |||
655 | static struct pci_driver | 697 | static struct pci_driver |
656 | nouveau_drm_pci_driver = { | 698 | nouveau_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 | ||
665 | static int __init | 706 | static 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 | ||
132 | int nouveau_drm_suspend(struct pci_dev *, pm_message_t); | 132 | int nouveau_pmops_suspend(struct device *); |
133 | int nouveau_drm_resume(struct pci_dev *); | 133 | int 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 | } |