aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pci-driver.c')
-rw-r--r--drivers/pci/pci-driver.c177
1 files changed, 112 insertions, 65 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 93eac1423585..267de88551c9 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -352,53 +352,60 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state)
352{ 352{
353 struct pci_dev * pci_dev = to_pci_dev(dev); 353 struct pci_dev * pci_dev = to_pci_dev(dev);
354 struct pci_driver * drv = pci_dev->driver; 354 struct pci_driver * drv = pci_dev->driver;
355 int i = 0; 355
356 pci_dev->state_saved = false;
356 357
357 if (drv && drv->suspend) { 358 if (drv && drv->suspend) {
358 pci_power_t prev = pci_dev->current_state; 359 pci_power_t prev = pci_dev->current_state;
360 int error;
359 361
360 pci_dev->state_saved = false; 362 error = drv->suspend(pci_dev, state);
361 363 suspend_report_result(drv->suspend, error);
362 i = drv->suspend(pci_dev, state); 364 if (error)
363 suspend_report_result(drv->suspend, i); 365 return error;
364 if (i)
365 return i;
366
367 if (pci_dev->state_saved)
368 goto Fixup;
369 366
370 if (pci_dev->current_state != PCI_D0 367 if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
371 && pci_dev->current_state != PCI_UNKNOWN) { 368 && pci_dev->current_state != PCI_UNKNOWN) {
372 WARN_ONCE(pci_dev->current_state != prev, 369 WARN_ONCE(pci_dev->current_state != prev,
373 "PCI PM: Device state not saved by %pF\n", 370 "PCI PM: Device state not saved by %pF\n",
374 drv->suspend); 371 drv->suspend);
375 goto Fixup;
376 } 372 }
377 } 373 }
378 374
379 pci_save_state(pci_dev);
380 /*
381 * This is for compatibility with existing code with legacy PM support.
382 */
383 pci_pm_set_unknown_state(pci_dev);
384
385 Fixup:
386 pci_fixup_device(pci_fixup_suspend, pci_dev); 375 pci_fixup_device(pci_fixup_suspend, pci_dev);
387 376
388 return i; 377 return 0;
389} 378}
390 379
391static int pci_legacy_suspend_late(struct device *dev, pm_message_t state) 380static int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
392{ 381{
393 struct pci_dev * pci_dev = to_pci_dev(dev); 382 struct pci_dev * pci_dev = to_pci_dev(dev);
394 struct pci_driver * drv = pci_dev->driver; 383 struct pci_driver * drv = pci_dev->driver;
395 int i = 0;
396 384
397 if (drv && drv->suspend_late) { 385 if (drv && drv->suspend_late) {
398 i = drv->suspend_late(pci_dev, state); 386 pci_power_t prev = pci_dev->current_state;
399 suspend_report_result(drv->suspend_late, i); 387 int error;
388
389 error = drv->suspend_late(pci_dev, state);
390 suspend_report_result(drv->suspend_late, error);
391 if (error)
392 return error;
393
394 if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
395 && pci_dev->current_state != PCI_UNKNOWN) {
396 WARN_ONCE(pci_dev->current_state != prev,
397 "PCI PM: Device state not saved by %pF\n",
398 drv->suspend_late);
399 return 0;
400 }
400 } 401 }
401 return i; 402
403 if (!pci_dev->state_saved)
404 pci_save_state(pci_dev);
405
406 pci_pm_set_unknown_state(pci_dev);
407
408 return 0;
402} 409}
403 410
404static int pci_legacy_resume_early(struct device *dev) 411static int pci_legacy_resume_early(struct device *dev)
@@ -423,6 +430,23 @@ static int pci_legacy_resume(struct device *dev)
423 430
424/* Auxiliary functions used by the new power management framework */ 431/* Auxiliary functions used by the new power management framework */
425 432
433/**
434 * pci_restore_standard_config - restore standard config registers of PCI device
435 * @pci_dev: PCI device to handle
436 */
437static int pci_restore_standard_config(struct pci_dev *pci_dev)
438{
439 pci_update_current_state(pci_dev, PCI_UNKNOWN);
440
441 if (pci_dev->current_state != PCI_D0) {
442 int error = pci_set_power_state(pci_dev, PCI_D0);
443 if (error)
444 return error;
445 }
446
447 return pci_dev->state_saved ? pci_restore_state(pci_dev) : 0;
448}
449
426static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) 450static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
427{ 451{
428 pci_restore_standard_config(pci_dev); 452 pci_restore_standard_config(pci_dev);
@@ -443,7 +467,6 @@ static void pci_pm_default_suspend(struct pci_dev *pci_dev)
443 /* Disable non-bridge devices without PM support */ 467 /* Disable non-bridge devices without PM support */
444 if (!pci_is_bridge(pci_dev)) 468 if (!pci_is_bridge(pci_dev))
445 pci_disable_enabled_device(pci_dev); 469 pci_disable_enabled_device(pci_dev);
446 pci_save_state(pci_dev);
447} 470}
448 471
449static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) 472static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
@@ -493,13 +516,13 @@ static int pci_pm_suspend(struct device *dev)
493 if (pci_has_legacy_pm_support(pci_dev)) 516 if (pci_has_legacy_pm_support(pci_dev))
494 return pci_legacy_suspend(dev, PMSG_SUSPEND); 517 return pci_legacy_suspend(dev, PMSG_SUSPEND);
495 518
519 pci_dev->state_saved = false;
520
496 if (!pm) { 521 if (!pm) {
497 pci_pm_default_suspend(pci_dev); 522 pci_pm_default_suspend(pci_dev);
498 goto Fixup; 523 goto Fixup;
499 } 524 }
500 525
501 pci_dev->state_saved = false;
502
503 if (pm->suspend) { 526 if (pm->suspend) {
504 pci_power_t prev = pci_dev->current_state; 527 pci_power_t prev = pci_dev->current_state;
505 int error; 528 int error;
@@ -509,24 +532,14 @@ static int pci_pm_suspend(struct device *dev)
509 if (error) 532 if (error)
510 return error; 533 return error;
511 534
512 if (pci_dev->state_saved) 535 if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
513 goto Fixup;
514
515 if (pci_dev->current_state != PCI_D0
516 && pci_dev->current_state != PCI_UNKNOWN) { 536 && pci_dev->current_state != PCI_UNKNOWN) {
517 WARN_ONCE(pci_dev->current_state != prev, 537 WARN_ONCE(pci_dev->current_state != prev,
518 "PCI PM: State of device not saved by %pF\n", 538 "PCI PM: State of device not saved by %pF\n",
519 pm->suspend); 539 pm->suspend);
520 goto Fixup;
521 } 540 }
522 } 541 }
523 542
524 if (!pci_dev->state_saved) {
525 pci_save_state(pci_dev);
526 if (!pci_is_bridge(pci_dev))
527 pci_prepare_to_sleep(pci_dev);
528 }
529
530 Fixup: 543 Fixup:
531 pci_fixup_device(pci_fixup_suspend, pci_dev); 544 pci_fixup_device(pci_fixup_suspend, pci_dev);
532 545
@@ -536,21 +549,43 @@ static int pci_pm_suspend(struct device *dev)
536static int pci_pm_suspend_noirq(struct device *dev) 549static int pci_pm_suspend_noirq(struct device *dev)
537{ 550{
538 struct pci_dev *pci_dev = to_pci_dev(dev); 551 struct pci_dev *pci_dev = to_pci_dev(dev);
539 struct device_driver *drv = dev->driver; 552 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
540 int error = 0;
541 553
542 if (pci_has_legacy_pm_support(pci_dev)) 554 if (pci_has_legacy_pm_support(pci_dev))
543 return pci_legacy_suspend_late(dev, PMSG_SUSPEND); 555 return pci_legacy_suspend_late(dev, PMSG_SUSPEND);
544 556
545 if (drv && drv->pm && drv->pm->suspend_noirq) { 557 if (!pm) {
546 error = drv->pm->suspend_noirq(dev); 558 pci_save_state(pci_dev);
547 suspend_report_result(drv->pm->suspend_noirq, error); 559 return 0;
548 } 560 }
549 561
550 if (!error) 562 if (pm->suspend_noirq) {
551 pci_pm_set_unknown_state(pci_dev); 563 pci_power_t prev = pci_dev->current_state;
564 int error;
552 565
553 return error; 566 error = pm->suspend_noirq(dev);
567 suspend_report_result(pm->suspend_noirq, error);
568 if (error)
569 return error;
570
571 if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
572 && pci_dev->current_state != PCI_UNKNOWN) {
573 WARN_ONCE(pci_dev->current_state != prev,
574 "PCI PM: State of device not saved by %pF\n",
575 pm->suspend_noirq);
576 return 0;
577 }
578 }
579
580 if (!pci_dev->state_saved) {
581 pci_save_state(pci_dev);
582 if (!pci_is_bridge(pci_dev))
583 pci_prepare_to_sleep(pci_dev);
584 }
585
586 pci_pm_set_unknown_state(pci_dev);
587
588 return 0;
554} 589}
555 590
556static int pci_pm_resume_noirq(struct device *dev) 591static int pci_pm_resume_noirq(struct device *dev)
@@ -617,13 +652,13 @@ static int pci_pm_freeze(struct device *dev)
617 if (pci_has_legacy_pm_support(pci_dev)) 652 if (pci_has_legacy_pm_support(pci_dev))
618 return pci_legacy_suspend(dev, PMSG_FREEZE); 653 return pci_legacy_suspend(dev, PMSG_FREEZE);
619 654
655 pci_dev->state_saved = false;
656
620 if (!pm) { 657 if (!pm) {
621 pci_pm_default_suspend(pci_dev); 658 pci_pm_default_suspend(pci_dev);
622 return 0; 659 return 0;
623 } 660 }
624 661
625 pci_dev->state_saved = false;
626
627 if (pm->freeze) { 662 if (pm->freeze) {
628 int error; 663 int error;
629 664
@@ -633,9 +668,6 @@ static int pci_pm_freeze(struct device *dev)
633 return error; 668 return error;
634 } 669 }
635 670
636 if (!pci_dev->state_saved)
637 pci_save_state(pci_dev);
638
639 return 0; 671 return 0;
640} 672}
641 673
@@ -643,20 +675,25 @@ static int pci_pm_freeze_noirq(struct device *dev)
643{ 675{
644 struct pci_dev *pci_dev = to_pci_dev(dev); 676 struct pci_dev *pci_dev = to_pci_dev(dev);
645 struct device_driver *drv = dev->driver; 677 struct device_driver *drv = dev->driver;
646 int error = 0;
647 678
648 if (pci_has_legacy_pm_support(pci_dev)) 679 if (pci_has_legacy_pm_support(pci_dev))
649 return pci_legacy_suspend_late(dev, PMSG_FREEZE); 680 return pci_legacy_suspend_late(dev, PMSG_FREEZE);
650 681
651 if (drv && drv->pm && drv->pm->freeze_noirq) { 682 if (drv && drv->pm && drv->pm->freeze_noirq) {
683 int error;
684
652 error = drv->pm->freeze_noirq(dev); 685 error = drv->pm->freeze_noirq(dev);
653 suspend_report_result(drv->pm->freeze_noirq, error); 686 suspend_report_result(drv->pm->freeze_noirq, error);
687 if (error)
688 return error;
654 } 689 }
655 690
656 if (!error) 691 if (!pci_dev->state_saved)
657 pci_pm_set_unknown_state(pci_dev); 692 pci_save_state(pci_dev);
658 693
659 return error; 694 pci_pm_set_unknown_state(pci_dev);
695
696 return 0;
660} 697}
661 698
662static int pci_pm_thaw_noirq(struct device *dev) 699static int pci_pm_thaw_noirq(struct device *dev)
@@ -699,46 +736,56 @@ static int pci_pm_poweroff(struct device *dev)
699{ 736{
700 struct pci_dev *pci_dev = to_pci_dev(dev); 737 struct pci_dev *pci_dev = to_pci_dev(dev);
701 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 738 struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
702 int error = 0;
703 739
704 if (pci_has_legacy_pm_support(pci_dev)) 740 if (pci_has_legacy_pm_support(pci_dev))
705 return pci_legacy_suspend(dev, PMSG_HIBERNATE); 741 return pci_legacy_suspend(dev, PMSG_HIBERNATE);
706 742
743 pci_dev->state_saved = false;
744
707 if (!pm) { 745 if (!pm) {
708 pci_pm_default_suspend(pci_dev); 746 pci_pm_default_suspend(pci_dev);
709 goto Fixup; 747 goto Fixup;
710 } 748 }
711 749
712 pci_dev->state_saved = false;
713
714 if (pm->poweroff) { 750 if (pm->poweroff) {
751 int error;
752
715 error = pm->poweroff(dev); 753 error = pm->poweroff(dev);
716 suspend_report_result(pm->poweroff, error); 754 suspend_report_result(pm->poweroff, error);
755 if (error)
756 return error;
717 } 757 }
718 758
719 if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
720 pci_prepare_to_sleep(pci_dev);
721
722 Fixup: 759 Fixup:
723 pci_fixup_device(pci_fixup_suspend, pci_dev); 760 pci_fixup_device(pci_fixup_suspend, pci_dev);
724 761
725 return error; 762 return 0;
726} 763}
727 764
728static int pci_pm_poweroff_noirq(struct device *dev) 765static int pci_pm_poweroff_noirq(struct device *dev)
729{ 766{
767 struct pci_dev *pci_dev = to_pci_dev(dev);
730 struct device_driver *drv = dev->driver; 768 struct device_driver *drv = dev->driver;
731 int error = 0;
732 769
733 if (pci_has_legacy_pm_support(to_pci_dev(dev))) 770 if (pci_has_legacy_pm_support(to_pci_dev(dev)))
734 return pci_legacy_suspend_late(dev, PMSG_HIBERNATE); 771 return pci_legacy_suspend_late(dev, PMSG_HIBERNATE);
735 772
736 if (drv && drv->pm && drv->pm->poweroff_noirq) { 773 if (!drv || !drv->pm)
774 return 0;
775
776 if (drv->pm->poweroff_noirq) {
777 int error;
778
737 error = drv->pm->poweroff_noirq(dev); 779 error = drv->pm->poweroff_noirq(dev);
738 suspend_report_result(drv->pm->poweroff_noirq, error); 780 suspend_report_result(drv->pm->poweroff_noirq, error);
781 if (error)
782 return error;
739 } 783 }
740 784
741 return error; 785 if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
786 pci_prepare_to_sleep(pci_dev);
787
788 return 0;
742} 789}
743 790
744static int pci_pm_restore_noirq(struct device *dev) 791static int pci_pm_restore_noirq(struct device *dev)