aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pci-driver.c145
1 files changed, 93 insertions, 52 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index ac6c9e493f4c..93eac1423585 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -430,39 +430,22 @@ static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
430 pci_fixup_device(pci_fixup_resume_early, pci_dev); 430 pci_fixup_device(pci_fixup_resume_early, pci_dev);
431} 431}
432 432
433static int pci_pm_default_resume(struct pci_dev *pci_dev) 433static void pci_pm_default_resume(struct pci_dev *pci_dev)
434{ 434{
435 pci_fixup_device(pci_fixup_resume, pci_dev); 435 pci_fixup_device(pci_fixup_resume, pci_dev);
436 436
437 if (pci_is_bridge(pci_dev)) 437 if (!pci_is_bridge(pci_dev))
438 return 0; 438 pci_enable_wake(pci_dev, PCI_D0, false);
439
440 pci_enable_wake(pci_dev, PCI_D0, false);
441 return pci_pm_reenable_device(pci_dev);
442} 439}
443 440
444static void pci_pm_default_suspend_generic(struct pci_dev *pci_dev) 441static void pci_pm_default_suspend(struct pci_dev *pci_dev)
445{ 442{
446 /* If a non-bridge device is enabled at this point, disable it */ 443 /* Disable non-bridge devices without PM support */
447 if (!pci_is_bridge(pci_dev)) 444 if (!pci_is_bridge(pci_dev))
448 pci_disable_enabled_device(pci_dev); 445 pci_disable_enabled_device(pci_dev);
449 /*
450 * Save state with interrupts enabled, because in principle the bus the
451 * device is on may be put into a low power state after this code runs.
452 */
453 pci_save_state(pci_dev); 446 pci_save_state(pci_dev);
454} 447}
455 448
456static void pci_pm_default_suspend(struct pci_dev *pci_dev, bool prepare)
457{
458 pci_pm_default_suspend_generic(pci_dev);
459
460 if (prepare && !pci_is_bridge(pci_dev))
461 pci_prepare_to_sleep(pci_dev);
462
463 pci_fixup_device(pci_fixup_suspend, pci_dev);
464}
465
466static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) 449static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
467{ 450{
468 struct pci_driver *drv = pci_dev->driver; 451 struct pci_driver *drv = pci_dev->driver;
@@ -506,20 +489,48 @@ static int pci_pm_suspend(struct device *dev)
506{ 489{
507 struct pci_dev *pci_dev = to_pci_dev(dev); 490 struct pci_dev *pci_dev = to_pci_dev(dev);
508 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 491 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
509 int error = 0;
510 492
511 if (pci_has_legacy_pm_support(pci_dev)) 493 if (pci_has_legacy_pm_support(pci_dev))
512 return pci_legacy_suspend(dev, PMSG_SUSPEND); 494 return pci_legacy_suspend(dev, PMSG_SUSPEND);
513 495
514 if (pm && pm->suspend) { 496 if (!pm) {
497 pci_pm_default_suspend(pci_dev);
498 goto Fixup;
499 }
500
501 pci_dev->state_saved = false;
502
503 if (pm->suspend) {
504 pci_power_t prev = pci_dev->current_state;
505 int error;
506
515 error = pm->suspend(dev); 507 error = pm->suspend(dev);
516 suspend_report_result(pm->suspend, error); 508 suspend_report_result(pm->suspend, error);
509 if (error)
510 return error;
511
512 if (pci_dev->state_saved)
513 goto Fixup;
514
515 if (pci_dev->current_state != PCI_D0
516 && pci_dev->current_state != PCI_UNKNOWN) {
517 WARN_ONCE(pci_dev->current_state != prev,
518 "PCI PM: State of device not saved by %pF\n",
519 pm->suspend);
520 goto Fixup;
521 }
517 } 522 }
518 523
519 if (!error) 524 if (!pci_dev->state_saved) {
520 pci_pm_default_suspend(pci_dev, !!pm); 525 pci_save_state(pci_dev);
526 if (!pci_is_bridge(pci_dev))
527 pci_prepare_to_sleep(pci_dev);
528 }
521 529
522 return error; 530 Fixup:
531 pci_fixup_device(pci_fixup_suspend, pci_dev);
532
533 return 0;
523} 534}
524 535
525static int pci_pm_suspend_noirq(struct device *dev) 536static int pci_pm_suspend_noirq(struct device *dev)
@@ -562,7 +573,7 @@ static int pci_pm_resume_noirq(struct device *dev)
562static int pci_pm_resume(struct device *dev) 573static int pci_pm_resume(struct device *dev)
563{ 574{
564 struct pci_dev *pci_dev = to_pci_dev(dev); 575 struct pci_dev *pci_dev = to_pci_dev(dev);
565 struct device_driver *drv = dev->driver; 576 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
566 int error = 0; 577 int error = 0;
567 578
568 /* 579 /*
@@ -575,12 +586,16 @@ static int pci_pm_resume(struct device *dev)
575 if (pci_has_legacy_pm_support(pci_dev)) 586 if (pci_has_legacy_pm_support(pci_dev))
576 return pci_legacy_resume(dev); 587 return pci_legacy_resume(dev);
577 588
578 error = pci_pm_default_resume(pci_dev); 589 pci_pm_default_resume(pci_dev);
579 590
580 if (!error && drv && drv->pm && drv->pm->resume) 591 if (pm) {
581 error = drv->pm->resume(dev); 592 if (pm->resume)
593 error = pm->resume(dev);
594 } else {
595 pci_pm_reenable_device(pci_dev);
596 }
582 597
583 return error; 598 return 0;
584} 599}
585 600
586#else /* !CONFIG_SUSPEND */ 601#else /* !CONFIG_SUSPEND */
@@ -597,21 +612,31 @@ static int pci_pm_resume(struct device *dev)
597static int pci_pm_freeze(struct device *dev) 612static int pci_pm_freeze(struct device *dev)
598{ 613{
599 struct pci_dev *pci_dev = to_pci_dev(dev); 614 struct pci_dev *pci_dev = to_pci_dev(dev);
600 struct device_driver *drv = dev->driver; 615 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
601 int error = 0;
602 616
603 if (pci_has_legacy_pm_support(pci_dev)) 617 if (pci_has_legacy_pm_support(pci_dev))
604 return pci_legacy_suspend(dev, PMSG_FREEZE); 618 return pci_legacy_suspend(dev, PMSG_FREEZE);
605 619
606 if (drv && drv->pm && drv->pm->freeze) { 620 if (!pm) {
607 error = drv->pm->freeze(dev); 621 pci_pm_default_suspend(pci_dev);
608 suspend_report_result(drv->pm->freeze, error); 622 return 0;
609 } 623 }
610 624
611 if (!error) 625 pci_dev->state_saved = false;
612 pci_pm_default_suspend_generic(pci_dev);
613 626
614 return error; 627 if (pm->freeze) {
628 int error;
629
630 error = pm->freeze(dev);
631 suspend_report_result(pm->freeze, error);
632 if (error)
633 return error;
634 }
635
636 if (!pci_dev->state_saved)
637 pci_save_state(pci_dev);
638
639 return 0;
615} 640}
616 641
617static int pci_pm_freeze_noirq(struct device *dev) 642static int pci_pm_freeze_noirq(struct device *dev)
@@ -654,16 +679,18 @@ static int pci_pm_thaw_noirq(struct device *dev)
654static int pci_pm_thaw(struct device *dev) 679static int pci_pm_thaw(struct device *dev)
655{ 680{
656 struct pci_dev *pci_dev = to_pci_dev(dev); 681 struct pci_dev *pci_dev = to_pci_dev(dev);
657 struct device_driver *drv = dev->driver; 682 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
658 int error = 0; 683 int error = 0;
659 684
660 if (pci_has_legacy_pm_support(pci_dev)) 685 if (pci_has_legacy_pm_support(pci_dev))
661 return pci_legacy_resume(dev); 686 return pci_legacy_resume(dev);
662 687
663 pci_pm_reenable_device(pci_dev); 688 if (pm) {
664 689 if (pm->thaw)
665 if (drv && drv->pm && drv->pm->thaw) 690 error = pm->thaw(dev);
666 error = drv->pm->thaw(dev); 691 } else {
692 pci_pm_reenable_device(pci_dev);
693 }
667 694
668 return error; 695 return error;
669} 696}
@@ -677,13 +704,23 @@ static int pci_pm_poweroff(struct device *dev)
677 if (pci_has_legacy_pm_support(pci_dev)) 704 if (pci_has_legacy_pm_support(pci_dev))
678 return pci_legacy_suspend(dev, PMSG_HIBERNATE); 705 return pci_legacy_suspend(dev, PMSG_HIBERNATE);
679 706
680 if (pm && pm->poweroff) { 707 if (!pm) {
708 pci_pm_default_suspend(pci_dev);
709 goto Fixup;
710 }
711
712 pci_dev->state_saved = false;
713
714 if (pm->poweroff) {
681 error = pm->poweroff(dev); 715 error = pm->poweroff(dev);
682 suspend_report_result(pm->poweroff, error); 716 suspend_report_result(pm->poweroff, error);
683 } 717 }
684 718
685 if (!error) 719 if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
686 pci_pm_default_suspend(pci_dev, !!pm); 720 pci_prepare_to_sleep(pci_dev);
721
722 Fixup:
723 pci_fixup_device(pci_fixup_suspend, pci_dev);
687 724
688 return error; 725 return error;
689} 726}
@@ -724,7 +761,7 @@ static int pci_pm_restore_noirq(struct device *dev)
724static int pci_pm_restore(struct device *dev) 761static int pci_pm_restore(struct device *dev)
725{ 762{
726 struct pci_dev *pci_dev = to_pci_dev(dev); 763 struct pci_dev *pci_dev = to_pci_dev(dev);
727 struct device_driver *drv = dev->driver; 764 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
728 int error = 0; 765 int error = 0;
729 766
730 /* 767 /*
@@ -737,10 +774,14 @@ static int pci_pm_restore(struct device *dev)
737 if (pci_has_legacy_pm_support(pci_dev)) 774 if (pci_has_legacy_pm_support(pci_dev))
738 return pci_legacy_resume(dev); 775 return pci_legacy_resume(dev);
739 776
740 error = pci_pm_default_resume(pci_dev); 777 pci_pm_default_resume(pci_dev);
741 778
742 if (!error && drv && drv->pm && drv->pm->restore) 779 if (pm) {
743 error = drv->pm->restore(dev); 780 if (pm->restore)
781 error = pm->restore(dev);
782 } else {
783 pci_pm_reenable_device(pci_dev);
784 }
744 785
745 return error; 786 return error;
746} 787}