.. | .. |
---|
12 | 12 | #include <linux/string.h> |
---|
13 | 13 | #include <linux/slab.h> |
---|
14 | 14 | #include <linux/sched.h> |
---|
| 15 | +#include <linux/sched/isolation.h> |
---|
15 | 16 | #include <linux/cpu.h> |
---|
16 | 17 | #include <linux/pm_runtime.h> |
---|
17 | 18 | #include <linux/suspend.h> |
---|
18 | 19 | #include <linux/kexec.h> |
---|
19 | 20 | #include <linux/of_device.h> |
---|
20 | 21 | #include <linux/acpi.h> |
---|
| 22 | +#include <linux/dma-map-ops.h> |
---|
21 | 23 | #include "pci.h" |
---|
22 | 24 | #include "pcie/portdrv.h" |
---|
23 | 25 | |
---|
.. | .. |
---|
100 | 102 | { |
---|
101 | 103 | struct pci_driver *pdrv = to_pci_driver(driver); |
---|
102 | 104 | const struct pci_device_id *ids = pdrv->id_table; |
---|
103 | | - __u32 vendor, device, subvendor = PCI_ANY_ID, |
---|
| 105 | + u32 vendor, device, subvendor = PCI_ANY_ID, |
---|
104 | 106 | subdevice = PCI_ANY_ID, class = 0, class_mask = 0; |
---|
105 | 107 | unsigned long driver_data = 0; |
---|
106 | 108 | int fields = 0; |
---|
.. | .. |
---|
168 | 170 | { |
---|
169 | 171 | struct pci_dynid *dynid, *n; |
---|
170 | 172 | struct pci_driver *pdrv = to_pci_driver(driver); |
---|
171 | | - __u32 vendor, device, subvendor = PCI_ANY_ID, |
---|
| 173 | + u32 vendor, device, subvendor = PCI_ANY_ID, |
---|
172 | 174 | subdevice = PCI_ANY_ID, class = 0, class_mask = 0; |
---|
173 | 175 | int fields = 0; |
---|
174 | 176 | size_t retval = -ENODEV; |
---|
.. | .. |
---|
315 | 317 | * Probe function should return < 0 for failure, 0 for success |
---|
316 | 318 | * Treat values > 0 as success, but warn. |
---|
317 | 319 | */ |
---|
318 | | - dev_warn(dev, "Driver probe function unexpectedly returned %d\n", rc); |
---|
| 320 | + pci_warn(pci_dev, "Driver probe function unexpectedly returned %d\n", |
---|
| 321 | + rc); |
---|
319 | 322 | return 0; |
---|
320 | 323 | } |
---|
321 | 324 | |
---|
.. | .. |
---|
332 | 335 | const struct pci_device_id *id) |
---|
333 | 336 | { |
---|
334 | 337 | int error, node, cpu; |
---|
| 338 | + int hk_flags = HK_FLAG_DOMAIN | HK_FLAG_WQ; |
---|
335 | 339 | struct drv_dev_and_id ddi = { drv, dev, id }; |
---|
336 | 340 | |
---|
337 | 341 | /* |
---|
.. | .. |
---|
352 | 356 | pci_physfn_is_probed(dev)) |
---|
353 | 357 | cpu = nr_cpu_ids; |
---|
354 | 358 | else |
---|
355 | | - cpu = cpumask_any_and(cpumask_of_node(node), cpu_online_mask); |
---|
| 359 | + cpu = cpumask_any_and(cpumask_of_node(node), |
---|
| 360 | + housekeeping_cpumask(hk_flags)); |
---|
356 | 361 | |
---|
357 | 362 | if (cpu < nr_cpu_ids) |
---|
358 | 363 | error = work_on_cpu(cpu, local_pci_probe, &ddi); |
---|
.. | .. |
---|
517 | 522 | return 0; |
---|
518 | 523 | } |
---|
519 | 524 | |
---|
| 525 | +static void pci_pm_default_resume(struct pci_dev *pci_dev) |
---|
| 526 | +{ |
---|
| 527 | + pci_fixup_device(pci_fixup_resume, pci_dev); |
---|
| 528 | + pci_enable_wake(pci_dev, PCI_D0, false); |
---|
| 529 | +} |
---|
| 530 | + |
---|
520 | 531 | #endif |
---|
521 | 532 | |
---|
522 | 533 | #ifdef CONFIG_PM_SLEEP |
---|
.. | .. |
---|
524 | 535 | static void pci_pm_default_resume_early(struct pci_dev *pci_dev) |
---|
525 | 536 | { |
---|
526 | 537 | pci_power_up(pci_dev); |
---|
| 538 | + pci_update_current_state(pci_dev, PCI_D0); |
---|
527 | 539 | pci_restore_state(pci_dev); |
---|
528 | 540 | pci_pme_restore(pci_dev); |
---|
529 | | - pci_fixup_device(pci_fixup_resume_early, pci_dev); |
---|
530 | 541 | } |
---|
531 | 542 | |
---|
532 | 543 | /* |
---|
.. | .. |
---|
579 | 590 | |
---|
580 | 591 | if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 |
---|
581 | 592 | && pci_dev->current_state != PCI_UNKNOWN) { |
---|
582 | | - WARN_ONCE(pci_dev->current_state != prev, |
---|
583 | | - "PCI PM: Device state not saved by %pF\n", |
---|
584 | | - drv->suspend); |
---|
| 593 | + pci_WARN_ONCE(pci_dev, pci_dev->current_state != prev, |
---|
| 594 | + "PCI PM: Device state not saved by %pS\n", |
---|
| 595 | + drv->suspend); |
---|
585 | 596 | } |
---|
586 | 597 | } |
---|
587 | 598 | |
---|
.. | .. |
---|
593 | 604 | static int pci_legacy_suspend_late(struct device *dev, pm_message_t state) |
---|
594 | 605 | { |
---|
595 | 606 | struct pci_dev *pci_dev = to_pci_dev(dev); |
---|
596 | | - struct pci_driver *drv = pci_dev->driver; |
---|
597 | | - |
---|
598 | | - if (drv && drv->suspend_late) { |
---|
599 | | - pci_power_t prev = pci_dev->current_state; |
---|
600 | | - int error; |
---|
601 | | - |
---|
602 | | - error = drv->suspend_late(pci_dev, state); |
---|
603 | | - suspend_report_result(drv->suspend_late, error); |
---|
604 | | - if (error) |
---|
605 | | - return error; |
---|
606 | | - |
---|
607 | | - if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 |
---|
608 | | - && pci_dev->current_state != PCI_UNKNOWN) { |
---|
609 | | - WARN_ONCE(pci_dev->current_state != prev, |
---|
610 | | - "PCI PM: Device state not saved by %pF\n", |
---|
611 | | - drv->suspend_late); |
---|
612 | | - goto Fixup; |
---|
613 | | - } |
---|
614 | | - } |
---|
615 | 607 | |
---|
616 | 608 | if (!pci_dev->state_saved) |
---|
617 | 609 | pci_save_state(pci_dev); |
---|
618 | 610 | |
---|
619 | 611 | pci_pm_set_unknown_state(pci_dev); |
---|
620 | 612 | |
---|
621 | | -Fixup: |
---|
622 | 613 | pci_fixup_device(pci_fixup_suspend_late, pci_dev); |
---|
623 | 614 | |
---|
624 | 615 | return 0; |
---|
625 | | -} |
---|
626 | | - |
---|
627 | | -static int pci_legacy_resume_early(struct device *dev) |
---|
628 | | -{ |
---|
629 | | - struct pci_dev *pci_dev = to_pci_dev(dev); |
---|
630 | | - struct pci_driver *drv = pci_dev->driver; |
---|
631 | | - |
---|
632 | | - return drv && drv->resume_early ? |
---|
633 | | - drv->resume_early(pci_dev) : 0; |
---|
634 | 616 | } |
---|
635 | 617 | |
---|
636 | 618 | static int pci_legacy_resume(struct device *dev) |
---|
.. | .. |
---|
646 | 628 | |
---|
647 | 629 | /* Auxiliary functions used by the new power management framework */ |
---|
648 | 630 | |
---|
649 | | -static void pci_pm_default_resume(struct pci_dev *pci_dev) |
---|
650 | | -{ |
---|
651 | | - pci_fixup_device(pci_fixup_resume, pci_dev); |
---|
652 | | - pci_enable_wake(pci_dev, PCI_D0, false); |
---|
653 | | -} |
---|
654 | | - |
---|
655 | 631 | static void pci_pm_default_suspend(struct pci_dev *pci_dev) |
---|
656 | 632 | { |
---|
657 | 633 | /* Disable non-bridge devices without PM support */ |
---|
.. | .. |
---|
662 | 638 | static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) |
---|
663 | 639 | { |
---|
664 | 640 | struct pci_driver *drv = pci_dev->driver; |
---|
665 | | - bool ret = drv && (drv->suspend || drv->suspend_late || drv->resume |
---|
666 | | - || drv->resume_early); |
---|
| 641 | + bool ret = drv && (drv->suspend || drv->resume); |
---|
667 | 642 | |
---|
668 | 643 | /* |
---|
669 | 644 | * Legacy PM support is used by default, so warn if the new framework is |
---|
670 | 645 | * supported as well. Drivers are supposed to support either the |
---|
671 | 646 | * former, or the latter, but not both at the same time. |
---|
672 | 647 | */ |
---|
673 | | - WARN(ret && drv->driver.pm, "driver %s device %04x:%04x\n", |
---|
674 | | - drv->name, pci_dev->vendor, pci_dev->device); |
---|
| 648 | + pci_WARN(pci_dev, ret && drv->driver.pm, "device %04x:%04x\n", |
---|
| 649 | + pci_dev->vendor, pci_dev->device); |
---|
675 | 650 | |
---|
676 | 651 | return ret; |
---|
677 | 652 | } |
---|
.. | .. |
---|
680 | 655 | |
---|
681 | 656 | static int pci_pm_prepare(struct device *dev) |
---|
682 | 657 | { |
---|
683 | | - struct device_driver *drv = dev->driver; |
---|
| 658 | + struct pci_dev *pci_dev = to_pci_dev(dev); |
---|
| 659 | + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
---|
684 | 660 | |
---|
685 | | - if (drv && drv->pm && drv->pm->prepare) { |
---|
686 | | - int error = drv->pm->prepare(dev); |
---|
| 661 | + if (pm && pm->prepare) { |
---|
| 662 | + int error = pm->prepare(dev); |
---|
687 | 663 | if (error < 0) |
---|
688 | 664 | return error; |
---|
689 | 665 | |
---|
690 | 666 | if (!error && dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_PREPARE)) |
---|
691 | 667 | return 0; |
---|
692 | 668 | } |
---|
693 | | - return pci_dev_keep_suspended(to_pci_dev(dev)); |
---|
| 669 | + if (pci_dev_need_resume(pci_dev)) |
---|
| 670 | + return 0; |
---|
| 671 | + |
---|
| 672 | + /* |
---|
| 673 | + * The PME setting needs to be adjusted here in case the direct-complete |
---|
| 674 | + * optimization is used with respect to this device. |
---|
| 675 | + */ |
---|
| 676 | + pci_dev_adjust_pme(pci_dev); |
---|
| 677 | + return 1; |
---|
694 | 678 | } |
---|
695 | 679 | |
---|
696 | 680 | static void pci_pm_complete(struct device *dev) |
---|
.. | .. |
---|
704 | 688 | if (pm_runtime_suspended(dev) && pm_resume_via_firmware()) { |
---|
705 | 689 | pci_power_t pre_sleep_state = pci_dev->current_state; |
---|
706 | 690 | |
---|
707 | | - pci_update_current_state(pci_dev, pci_dev->current_state); |
---|
| 691 | + pci_refresh_power_state(pci_dev); |
---|
| 692 | + /* |
---|
| 693 | + * On platforms with ACPI this check may also trigger for |
---|
| 694 | + * devices sharing power resources if one of those power |
---|
| 695 | + * resources has been activated as a result of a change of the |
---|
| 696 | + * power state of another device sharing it. However, in that |
---|
| 697 | + * case it is also better to resume the device, in general. |
---|
| 698 | + */ |
---|
708 | 699 | if (pci_dev->current_state < pre_sleep_state) |
---|
709 | 700 | pm_request_resume(dev); |
---|
710 | 701 | } |
---|
.. | .. |
---|
736 | 727 | struct pci_dev *pci_dev = to_pci_dev(dev); |
---|
737 | 728 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
---|
738 | 729 | |
---|
| 730 | + pci_dev->skip_bus_pm = false; |
---|
| 731 | + |
---|
739 | 732 | if (pci_has_legacy_pm_support(pci_dev)) |
---|
740 | 733 | return pci_legacy_suspend(dev, PMSG_SUSPEND); |
---|
741 | 734 | |
---|
.. | .. |
---|
758 | 751 | * better to resume the device from runtime suspend here. |
---|
759 | 752 | */ |
---|
760 | 753 | if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) || |
---|
761 | | - !pci_dev_keep_suspended(pci_dev)) { |
---|
| 754 | + pci_dev_need_resume(pci_dev)) { |
---|
762 | 755 | pm_runtime_resume(dev); |
---|
763 | 756 | pci_dev->state_saved = false; |
---|
| 757 | + } else { |
---|
| 758 | + pci_dev_adjust_pme(pci_dev); |
---|
764 | 759 | } |
---|
765 | 760 | |
---|
766 | 761 | if (pm->suspend) { |
---|
.. | .. |
---|
774 | 769 | |
---|
775 | 770 | if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 |
---|
776 | 771 | && pci_dev->current_state != PCI_UNKNOWN) { |
---|
777 | | - WARN_ONCE(pci_dev->current_state != prev, |
---|
778 | | - "PCI PM: State of device not saved by %pF\n", |
---|
779 | | - pm->suspend); |
---|
| 772 | + pci_WARN_ONCE(pci_dev, pci_dev->current_state != prev, |
---|
| 773 | + "PCI PM: State of device not saved by %pS\n", |
---|
| 774 | + pm->suspend); |
---|
780 | 775 | } |
---|
781 | 776 | } |
---|
782 | 777 | |
---|
.. | .. |
---|
785 | 780 | |
---|
786 | 781 | static int pci_pm_suspend_late(struct device *dev) |
---|
787 | 782 | { |
---|
788 | | - if (dev_pm_smart_suspend_and_suspended(dev)) |
---|
| 783 | + if (dev_pm_skip_suspend(dev)) |
---|
789 | 784 | return 0; |
---|
790 | 785 | |
---|
791 | 786 | pci_fixup_device(pci_fixup_suspend, to_pci_dev(dev)); |
---|
.. | .. |
---|
798 | 793 | struct pci_dev *pci_dev = to_pci_dev(dev); |
---|
799 | 794 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
---|
800 | 795 | |
---|
801 | | - if (dev_pm_smart_suspend_and_suspended(dev)) { |
---|
802 | | - dev->power.may_skip_resume = true; |
---|
| 796 | + if (dev_pm_skip_suspend(dev)) |
---|
803 | 797 | return 0; |
---|
804 | | - } |
---|
805 | 798 | |
---|
806 | 799 | if (pci_has_legacy_pm_support(pci_dev)) |
---|
807 | 800 | return pci_legacy_suspend_late(dev, PMSG_SUSPEND); |
---|
.. | .. |
---|
822 | 815 | |
---|
823 | 816 | if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 |
---|
824 | 817 | && pci_dev->current_state != PCI_UNKNOWN) { |
---|
825 | | - WARN_ONCE(pci_dev->current_state != prev, |
---|
826 | | - "PCI PM: State of device not saved by %pF\n", |
---|
827 | | - pm->suspend_noirq); |
---|
| 818 | + pci_WARN_ONCE(pci_dev, pci_dev->current_state != prev, |
---|
| 819 | + "PCI PM: State of device not saved by %pS\n", |
---|
| 820 | + pm->suspend_noirq); |
---|
828 | 821 | goto Fixup; |
---|
829 | 822 | } |
---|
830 | 823 | } |
---|
831 | 824 | |
---|
832 | | - /* if d3hot is not supported bail out */ |
---|
833 | | - if (pci_dev->no_d3hot) |
---|
834 | | - return 0; |
---|
835 | | - |
---|
836 | | - if (!pci_dev->state_saved) { |
---|
| 825 | + if (pci_dev->skip_bus_pm) { |
---|
| 826 | + /* |
---|
| 827 | + * Either the device is a bridge with a child in D0 below it, or |
---|
| 828 | + * the function is running for the second time in a row without |
---|
| 829 | + * going through full resume, which is possible only during |
---|
| 830 | + * suspend-to-idle in a spurious wakeup case. The device should |
---|
| 831 | + * be in D0 at this point, but if it is a bridge, it may be |
---|
| 832 | + * necessary to save its state. |
---|
| 833 | + */ |
---|
| 834 | + if (!pci_dev->state_saved) |
---|
| 835 | + pci_save_state(pci_dev); |
---|
| 836 | + } else if (!pci_dev->state_saved) { |
---|
837 | 837 | pci_save_state(pci_dev); |
---|
838 | 838 | if (pci_power_manageable(pci_dev)) |
---|
839 | 839 | pci_prepare_to_sleep(pci_dev); |
---|
840 | 840 | } |
---|
841 | 841 | |
---|
842 | | - dev_dbg(dev, "PCI PM: Suspend power state: %s\n", |
---|
| 842 | + pci_dbg(pci_dev, "PCI PM: Suspend power state: %s\n", |
---|
843 | 843 | pci_power_name(pci_dev->current_state)); |
---|
| 844 | + |
---|
| 845 | + if (pci_dev->current_state == PCI_D0) { |
---|
| 846 | + pci_dev->skip_bus_pm = true; |
---|
| 847 | + /* |
---|
| 848 | + * Per PCI PM r1.2, table 6-1, a bridge must be in D0 if any |
---|
| 849 | + * downstream device is in D0, so avoid changing the power state |
---|
| 850 | + * of the parent bridge by setting the skip_bus_pm flag for it. |
---|
| 851 | + */ |
---|
| 852 | + if (pci_dev->bus->self) |
---|
| 853 | + pci_dev->bus->self->skip_bus_pm = true; |
---|
| 854 | + } |
---|
| 855 | + |
---|
| 856 | + if (pci_dev->skip_bus_pm && pm_suspend_no_platform()) { |
---|
| 857 | + pci_dbg(pci_dev, "PCI PM: Skipped\n"); |
---|
| 858 | + goto Fixup; |
---|
| 859 | + } |
---|
844 | 860 | |
---|
845 | 861 | pci_pm_set_unknown_state(pci_dev); |
---|
846 | 862 | |
---|
.. | .. |
---|
866 | 882 | * pci_pm_complete() to take care of fixing up the device's state |
---|
867 | 883 | * anyway, if need be. |
---|
868 | 884 | */ |
---|
869 | | - dev->power.may_skip_resume = device_may_wakeup(dev) || |
---|
870 | | - !device_can_wakeup(dev); |
---|
| 885 | + if (device_can_wakeup(dev) && !device_may_wakeup(dev)) |
---|
| 886 | + dev->power.may_skip_resume = false; |
---|
871 | 887 | |
---|
872 | 888 | return 0; |
---|
873 | 889 | } |
---|
.. | .. |
---|
875 | 891 | static int pci_pm_resume_noirq(struct device *dev) |
---|
876 | 892 | { |
---|
877 | 893 | struct pci_dev *pci_dev = to_pci_dev(dev); |
---|
878 | | - struct device_driver *drv = dev->driver; |
---|
879 | | - int error = 0; |
---|
| 894 | + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
---|
| 895 | + pci_power_t prev_state = pci_dev->current_state; |
---|
| 896 | + bool skip_bus_pm = pci_dev->skip_bus_pm; |
---|
880 | 897 | |
---|
881 | | - if (dev_pm_may_skip_resume(dev)) |
---|
| 898 | + if (dev_pm_skip_resume(dev)) |
---|
882 | 899 | return 0; |
---|
883 | 900 | |
---|
884 | 901 | /* |
---|
885 | | - * Devices with DPM_FLAG_SMART_SUSPEND may be left in runtime suspend |
---|
886 | | - * during system suspend, so update their runtime PM status to "active" |
---|
887 | | - * as they are going to be put into D0 shortly. |
---|
| 902 | + * In the suspend-to-idle case, devices left in D0 during suspend will |
---|
| 903 | + * stay in D0, so it is not necessary to restore or update their |
---|
| 904 | + * configuration here and attempting to put them into D0 again is |
---|
| 905 | + * pointless, so avoid doing that. |
---|
888 | 906 | */ |
---|
889 | | - if (dev_pm_smart_suspend_and_suspended(dev)) |
---|
890 | | - pm_runtime_set_active(dev); |
---|
891 | | - |
---|
892 | | - if (!pci_dev->no_d3hot) |
---|
| 907 | + if (!(skip_bus_pm && pm_suspend_no_platform())) |
---|
893 | 908 | pci_pm_default_resume_early(pci_dev); |
---|
894 | 909 | |
---|
895 | | - if (pci_has_legacy_pm_support(pci_dev)) |
---|
896 | | - return pci_legacy_resume_early(dev); |
---|
897 | | - |
---|
| 910 | + pci_fixup_device(pci_fixup_resume_early, pci_dev); |
---|
898 | 911 | pcie_pme_root_status_cleanup(pci_dev); |
---|
899 | 912 | |
---|
900 | | - if (drv && drv->pm && drv->pm->resume_noirq) |
---|
901 | | - error = drv->pm->resume_noirq(dev); |
---|
| 913 | + if (!skip_bus_pm && prev_state == PCI_D3cold) |
---|
| 914 | + pci_bridge_wait_for_secondary_bus(pci_dev, "resume", PCI_RESET_WAIT); |
---|
902 | 915 | |
---|
903 | | - return error; |
---|
| 916 | + if (pci_has_legacy_pm_support(pci_dev)) |
---|
| 917 | + return 0; |
---|
| 918 | + |
---|
| 919 | + if (pm && pm->resume_noirq) |
---|
| 920 | + return pm->resume_noirq(dev); |
---|
| 921 | + |
---|
| 922 | + return 0; |
---|
| 923 | +} |
---|
| 924 | + |
---|
| 925 | +static int pci_pm_resume_early(struct device *dev) |
---|
| 926 | +{ |
---|
| 927 | + if (dev_pm_skip_resume(dev)) |
---|
| 928 | + return 0; |
---|
| 929 | + |
---|
| 930 | + return pm_generic_resume_early(dev); |
---|
904 | 931 | } |
---|
905 | 932 | |
---|
906 | 933 | static int pci_pm_resume(struct device *dev) |
---|
907 | 934 | { |
---|
908 | 935 | struct pci_dev *pci_dev = to_pci_dev(dev); |
---|
909 | 936 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
---|
910 | | - int error = 0; |
---|
911 | 937 | |
---|
912 | 938 | /* |
---|
913 | 939 | * This is necessary for the suspend error path in which resume is |
---|
.. | .. |
---|
923 | 949 | |
---|
924 | 950 | if (pm) { |
---|
925 | 951 | if (pm->resume) |
---|
926 | | - error = pm->resume(dev); |
---|
| 952 | + return pm->resume(dev); |
---|
927 | 953 | } else { |
---|
928 | 954 | pci_pm_reenable_device(pci_dev); |
---|
929 | 955 | } |
---|
930 | 956 | |
---|
931 | | - return error; |
---|
| 957 | + return 0; |
---|
932 | 958 | } |
---|
933 | 959 | |
---|
934 | 960 | #else /* !CONFIG_SUSPEND */ |
---|
.. | .. |
---|
937 | 963 | #define pci_pm_suspend_late NULL |
---|
938 | 964 | #define pci_pm_suspend_noirq NULL |
---|
939 | 965 | #define pci_pm_resume NULL |
---|
| 966 | +#define pci_pm_resume_early NULL |
---|
940 | 967 | #define pci_pm_resume_noirq NULL |
---|
941 | 968 | |
---|
942 | 969 | #endif /* !CONFIG_SUSPEND */ |
---|
943 | 970 | |
---|
944 | 971 | #ifdef CONFIG_HIBERNATE_CALLBACKS |
---|
945 | | - |
---|
946 | | - |
---|
947 | | -/* |
---|
948 | | - * pcibios_pm_ops - provide arch-specific hooks when a PCI device is doing |
---|
949 | | - * a hibernate transition |
---|
950 | | - */ |
---|
951 | | -struct dev_pm_ops __weak pcibios_pm_ops; |
---|
952 | 972 | |
---|
953 | 973 | static int pci_pm_freeze(struct device *dev) |
---|
954 | 974 | { |
---|
.. | .. |
---|
986 | 1006 | return 0; |
---|
987 | 1007 | } |
---|
988 | 1008 | |
---|
989 | | -static int pci_pm_freeze_late(struct device *dev) |
---|
990 | | -{ |
---|
991 | | - if (dev_pm_smart_suspend_and_suspended(dev)) |
---|
992 | | - return 0; |
---|
993 | | - |
---|
994 | | - return pm_generic_freeze_late(dev); |
---|
995 | | -} |
---|
996 | | - |
---|
997 | 1009 | static int pci_pm_freeze_noirq(struct device *dev) |
---|
998 | 1010 | { |
---|
999 | 1011 | struct pci_dev *pci_dev = to_pci_dev(dev); |
---|
1000 | | - struct device_driver *drv = dev->driver; |
---|
1001 | | - |
---|
1002 | | - if (dev_pm_smart_suspend_and_suspended(dev)) |
---|
1003 | | - return 0; |
---|
| 1012 | + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
---|
1004 | 1013 | |
---|
1005 | 1014 | if (pci_has_legacy_pm_support(pci_dev)) |
---|
1006 | 1015 | return pci_legacy_suspend_late(dev, PMSG_FREEZE); |
---|
1007 | 1016 | |
---|
1008 | | - if (drv && drv->pm && drv->pm->freeze_noirq) { |
---|
| 1017 | + if (pm && pm->freeze_noirq) { |
---|
1009 | 1018 | int error; |
---|
1010 | 1019 | |
---|
1011 | | - error = drv->pm->freeze_noirq(dev); |
---|
1012 | | - suspend_report_result(drv->pm->freeze_noirq, error); |
---|
| 1020 | + error = pm->freeze_noirq(dev); |
---|
| 1021 | + suspend_report_result(pm->freeze_noirq, error); |
---|
1013 | 1022 | if (error) |
---|
1014 | 1023 | return error; |
---|
1015 | 1024 | } |
---|
.. | .. |
---|
1019 | 1028 | |
---|
1020 | 1029 | pci_pm_set_unknown_state(pci_dev); |
---|
1021 | 1030 | |
---|
1022 | | - if (pcibios_pm_ops.freeze_noirq) |
---|
1023 | | - return pcibios_pm_ops.freeze_noirq(dev); |
---|
1024 | | - |
---|
1025 | 1031 | return 0; |
---|
1026 | 1032 | } |
---|
1027 | 1033 | |
---|
1028 | 1034 | static int pci_pm_thaw_noirq(struct device *dev) |
---|
1029 | 1035 | { |
---|
1030 | 1036 | struct pci_dev *pci_dev = to_pci_dev(dev); |
---|
1031 | | - struct device_driver *drv = dev->driver; |
---|
1032 | | - int error = 0; |
---|
| 1037 | + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
---|
1033 | 1038 | |
---|
1034 | 1039 | /* |
---|
1035 | | - * If the device is in runtime suspend, the code below may not work |
---|
1036 | | - * correctly with it, so skip that code and make the PM core skip all of |
---|
1037 | | - * the subsequent "thaw" callbacks for the device. |
---|
1038 | | - */ |
---|
1039 | | - if (dev_pm_smart_suspend_and_suspended(dev)) { |
---|
1040 | | - dev_pm_skip_next_resume_phases(dev); |
---|
1041 | | - return 0; |
---|
1042 | | - } |
---|
1043 | | - |
---|
1044 | | - if (pcibios_pm_ops.thaw_noirq) { |
---|
1045 | | - error = pcibios_pm_ops.thaw_noirq(dev); |
---|
1046 | | - if (error) |
---|
1047 | | - return error; |
---|
1048 | | - } |
---|
1049 | | - |
---|
1050 | | - /* |
---|
1051 | | - * Both the legacy ->resume_early() and the new pm->thaw_noirq() |
---|
1052 | | - * callbacks assume the device has been returned to D0 and its |
---|
1053 | | - * config state has been restored. |
---|
| 1040 | + * The pm->thaw_noirq() callback assumes the device has been |
---|
| 1041 | + * returned to D0 and its config state has been restored. |
---|
1054 | 1042 | * |
---|
1055 | 1043 | * In addition, pci_restore_state() restores MSI-X state in MMIO |
---|
1056 | 1044 | * space, which requires the device to be in D0, so return it to D0 |
---|
.. | .. |
---|
1061 | 1049 | pci_restore_state(pci_dev); |
---|
1062 | 1050 | |
---|
1063 | 1051 | if (pci_has_legacy_pm_support(pci_dev)) |
---|
1064 | | - return pci_legacy_resume_early(dev); |
---|
| 1052 | + return 0; |
---|
1065 | 1053 | |
---|
1066 | | - if (drv && drv->pm && drv->pm->thaw_noirq) |
---|
1067 | | - error = drv->pm->thaw_noirq(dev); |
---|
| 1054 | + if (pm && pm->thaw_noirq) |
---|
| 1055 | + return pm->thaw_noirq(dev); |
---|
1068 | 1056 | |
---|
1069 | | - return error; |
---|
| 1057 | + return 0; |
---|
1070 | 1058 | } |
---|
1071 | 1059 | |
---|
1072 | 1060 | static int pci_pm_thaw(struct device *dev) |
---|
.. | .. |
---|
1105 | 1093 | |
---|
1106 | 1094 | /* The reason to do that is the same as in pci_pm_suspend(). */ |
---|
1107 | 1095 | if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) || |
---|
1108 | | - !pci_dev_keep_suspended(pci_dev)) |
---|
| 1096 | + pci_dev_need_resume(pci_dev)) { |
---|
1109 | 1097 | pm_runtime_resume(dev); |
---|
| 1098 | + pci_dev->state_saved = false; |
---|
| 1099 | + } else { |
---|
| 1100 | + pci_dev_adjust_pme(pci_dev); |
---|
| 1101 | + } |
---|
1110 | 1102 | |
---|
1111 | | - pci_dev->state_saved = false; |
---|
1112 | 1103 | if (pm->poweroff) { |
---|
1113 | 1104 | int error; |
---|
1114 | 1105 | |
---|
.. | .. |
---|
1123 | 1114 | |
---|
1124 | 1115 | static int pci_pm_poweroff_late(struct device *dev) |
---|
1125 | 1116 | { |
---|
1126 | | - if (dev_pm_smart_suspend_and_suspended(dev)) |
---|
| 1117 | + if (dev_pm_skip_suspend(dev)) |
---|
1127 | 1118 | return 0; |
---|
1128 | 1119 | |
---|
1129 | 1120 | pci_fixup_device(pci_fixup_suspend, to_pci_dev(dev)); |
---|
.. | .. |
---|
1134 | 1125 | static int pci_pm_poweroff_noirq(struct device *dev) |
---|
1135 | 1126 | { |
---|
1136 | 1127 | struct pci_dev *pci_dev = to_pci_dev(dev); |
---|
1137 | | - struct device_driver *drv = dev->driver; |
---|
| 1128 | + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
---|
1138 | 1129 | |
---|
1139 | | - if (dev_pm_smart_suspend_and_suspended(dev)) |
---|
| 1130 | + if (dev_pm_skip_suspend(dev)) |
---|
1140 | 1131 | return 0; |
---|
1141 | 1132 | |
---|
1142 | | - if (pci_has_legacy_pm_support(to_pci_dev(dev))) |
---|
| 1133 | + if (pci_has_legacy_pm_support(pci_dev)) |
---|
1143 | 1134 | return pci_legacy_suspend_late(dev, PMSG_HIBERNATE); |
---|
1144 | 1135 | |
---|
1145 | | - if (!drv || !drv->pm) { |
---|
| 1136 | + if (!pm) { |
---|
1146 | 1137 | pci_fixup_device(pci_fixup_suspend_late, pci_dev); |
---|
1147 | 1138 | return 0; |
---|
1148 | 1139 | } |
---|
1149 | 1140 | |
---|
1150 | | - if (drv->pm->poweroff_noirq) { |
---|
| 1141 | + if (pm->poweroff_noirq) { |
---|
1151 | 1142 | int error; |
---|
1152 | 1143 | |
---|
1153 | | - error = drv->pm->poweroff_noirq(dev); |
---|
1154 | | - suspend_report_result(drv->pm->poweroff_noirq, error); |
---|
| 1144 | + error = pm->poweroff_noirq(dev); |
---|
| 1145 | + suspend_report_result(pm->poweroff_noirq, error); |
---|
1155 | 1146 | if (error) |
---|
1156 | 1147 | return error; |
---|
1157 | 1148 | } |
---|
.. | .. |
---|
1168 | 1159 | |
---|
1169 | 1160 | pci_fixup_device(pci_fixup_suspend_late, pci_dev); |
---|
1170 | 1161 | |
---|
1171 | | - if (pcibios_pm_ops.poweroff_noirq) |
---|
1172 | | - return pcibios_pm_ops.poweroff_noirq(dev); |
---|
1173 | | - |
---|
1174 | 1162 | return 0; |
---|
1175 | 1163 | } |
---|
1176 | 1164 | |
---|
1177 | 1165 | static int pci_pm_restore_noirq(struct device *dev) |
---|
1178 | 1166 | { |
---|
1179 | 1167 | struct pci_dev *pci_dev = to_pci_dev(dev); |
---|
1180 | | - struct device_driver *drv = dev->driver; |
---|
1181 | | - int error = 0; |
---|
1182 | | - |
---|
1183 | | - /* This is analogous to the pci_pm_resume_noirq() case. */ |
---|
1184 | | - if (dev_pm_smart_suspend_and_suspended(dev)) |
---|
1185 | | - pm_runtime_set_active(dev); |
---|
1186 | | - |
---|
1187 | | - if (pcibios_pm_ops.restore_noirq) { |
---|
1188 | | - error = pcibios_pm_ops.restore_noirq(dev); |
---|
1189 | | - if (error) |
---|
1190 | | - return error; |
---|
1191 | | - } |
---|
| 1168 | + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
---|
1192 | 1169 | |
---|
1193 | 1170 | pci_pm_default_resume_early(pci_dev); |
---|
| 1171 | + pci_fixup_device(pci_fixup_resume_early, pci_dev); |
---|
1194 | 1172 | |
---|
1195 | 1173 | if (pci_has_legacy_pm_support(pci_dev)) |
---|
1196 | | - return pci_legacy_resume_early(dev); |
---|
| 1174 | + return 0; |
---|
1197 | 1175 | |
---|
1198 | | - if (drv && drv->pm && drv->pm->restore_noirq) |
---|
1199 | | - error = drv->pm->restore_noirq(dev); |
---|
| 1176 | + if (pm && pm->restore_noirq) |
---|
| 1177 | + return pm->restore_noirq(dev); |
---|
1200 | 1178 | |
---|
1201 | | - return error; |
---|
| 1179 | + return 0; |
---|
1202 | 1180 | } |
---|
1203 | 1181 | |
---|
1204 | 1182 | static int pci_pm_restore(struct device *dev) |
---|
1205 | 1183 | { |
---|
1206 | 1184 | struct pci_dev *pci_dev = to_pci_dev(dev); |
---|
1207 | 1185 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
---|
1208 | | - int error = 0; |
---|
1209 | 1186 | |
---|
1210 | 1187 | /* |
---|
1211 | 1188 | * This is necessary for the hibernation error path in which restore is |
---|
.. | .. |
---|
1221 | 1198 | |
---|
1222 | 1199 | if (pm) { |
---|
1223 | 1200 | if (pm->restore) |
---|
1224 | | - error = pm->restore(dev); |
---|
| 1201 | + return pm->restore(dev); |
---|
1225 | 1202 | } else { |
---|
1226 | 1203 | pci_pm_reenable_device(pci_dev); |
---|
1227 | 1204 | } |
---|
1228 | 1205 | |
---|
1229 | | - return error; |
---|
| 1206 | + return 0; |
---|
1230 | 1207 | } |
---|
1231 | 1208 | |
---|
1232 | 1209 | #else /* !CONFIG_HIBERNATE_CALLBACKS */ |
---|
1233 | 1210 | |
---|
1234 | 1211 | #define pci_pm_freeze NULL |
---|
1235 | | -#define pci_pm_freeze_late NULL |
---|
1236 | 1212 | #define pci_pm_freeze_noirq NULL |
---|
1237 | 1213 | #define pci_pm_thaw NULL |
---|
1238 | 1214 | #define pci_pm_thaw_noirq NULL |
---|
.. | .. |
---|
1272 | 1248 | * log level. |
---|
1273 | 1249 | */ |
---|
1274 | 1250 | if (error == -EBUSY || error == -EAGAIN) { |
---|
1275 | | - dev_dbg(dev, "can't suspend now (%pf returned %d)\n", |
---|
| 1251 | + pci_dbg(pci_dev, "can't suspend now (%ps returned %d)\n", |
---|
1276 | 1252 | pm->runtime_suspend, error); |
---|
1277 | 1253 | return error; |
---|
1278 | 1254 | } else if (error) { |
---|
1279 | | - dev_err(dev, "can't suspend (%pf returned %d)\n", |
---|
| 1255 | + pci_err(pci_dev, "can't suspend (%ps returned %d)\n", |
---|
1280 | 1256 | pm->runtime_suspend, error); |
---|
1281 | 1257 | return error; |
---|
1282 | 1258 | } |
---|
.. | .. |
---|
1287 | 1263 | if (pm && pm->runtime_suspend |
---|
1288 | 1264 | && !pci_dev->state_saved && pci_dev->current_state != PCI_D0 |
---|
1289 | 1265 | && pci_dev->current_state != PCI_UNKNOWN) { |
---|
1290 | | - WARN_ONCE(pci_dev->current_state != prev, |
---|
1291 | | - "PCI PM: State of device not saved by %pF\n", |
---|
1292 | | - pm->runtime_suspend); |
---|
| 1266 | + pci_WARN_ONCE(pci_dev, pci_dev->current_state != prev, |
---|
| 1267 | + "PCI PM: State of device not saved by %pS\n", |
---|
| 1268 | + pm->runtime_suspend); |
---|
1293 | 1269 | return 0; |
---|
1294 | 1270 | } |
---|
1295 | | - |
---|
1296 | | - /* if d3hot is not supported bail out */ |
---|
1297 | | - if (pci_dev->no_d3hot) |
---|
1298 | | - return 0; |
---|
1299 | 1271 | |
---|
1300 | 1272 | if (!pci_dev->state_saved) { |
---|
1301 | 1273 | pci_save_state(pci_dev); |
---|
.. | .. |
---|
1307 | 1279 | |
---|
1308 | 1280 | static int pci_pm_runtime_resume(struct device *dev) |
---|
1309 | 1281 | { |
---|
1310 | | - int rc = 0; |
---|
1311 | 1282 | struct pci_dev *pci_dev = to_pci_dev(dev); |
---|
1312 | 1283 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
---|
1313 | | - |
---|
1314 | | - /* we skipped d3hot processing so skip re-init */ |
---|
1315 | | - if (pci_dev->no_d3hot) |
---|
1316 | | - goto skip_restore; |
---|
| 1284 | + pci_power_t prev_state = pci_dev->current_state; |
---|
| 1285 | + int error = 0; |
---|
1317 | 1286 | |
---|
1318 | 1287 | /* |
---|
1319 | 1288 | * Restoring config space is necessary even if the device is not bound |
---|
.. | .. |
---|
1326 | 1295 | return 0; |
---|
1327 | 1296 | |
---|
1328 | 1297 | pci_fixup_device(pci_fixup_resume_early, pci_dev); |
---|
1329 | | - pci_enable_wake(pci_dev, PCI_D0, false); |
---|
1330 | | - pci_fixup_device(pci_fixup_resume, pci_dev); |
---|
| 1298 | + pci_pm_default_resume(pci_dev); |
---|
1331 | 1299 | |
---|
1332 | | -skip_restore: |
---|
| 1300 | + if (prev_state == PCI_D3cold) |
---|
| 1301 | + pci_bridge_wait_for_secondary_bus(pci_dev, "resume", PCI_RESET_WAIT); |
---|
| 1302 | + |
---|
1333 | 1303 | if (pm && pm->runtime_resume) |
---|
1334 | | - rc = pm->runtime_resume(dev); |
---|
| 1304 | + error = pm->runtime_resume(dev); |
---|
1335 | 1305 | |
---|
1336 | 1306 | pci_dev->runtime_d3cold = false; |
---|
1337 | 1307 | |
---|
1338 | | - return rc; |
---|
| 1308 | + return error; |
---|
1339 | 1309 | } |
---|
1340 | 1310 | |
---|
1341 | 1311 | static int pci_pm_runtime_idle(struct device *dev) |
---|
1342 | 1312 | { |
---|
1343 | 1313 | struct pci_dev *pci_dev = to_pci_dev(dev); |
---|
1344 | 1314 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
---|
1345 | | - int ret = 0; |
---|
1346 | 1315 | |
---|
1347 | 1316 | /* |
---|
1348 | 1317 | * If pci_dev->driver is not set (unbound), the device should |
---|
.. | .. |
---|
1355 | 1324 | return -ENOSYS; |
---|
1356 | 1325 | |
---|
1357 | 1326 | if (pm->runtime_idle) |
---|
1358 | | - ret = pm->runtime_idle(dev); |
---|
| 1327 | + return pm->runtime_idle(dev); |
---|
1359 | 1328 | |
---|
1360 | | - return ret; |
---|
| 1329 | + return 0; |
---|
1361 | 1330 | } |
---|
1362 | 1331 | |
---|
1363 | 1332 | static const struct dev_pm_ops pci_dev_pm_ops = { |
---|
.. | .. |
---|
1366 | 1335 | .suspend = pci_pm_suspend, |
---|
1367 | 1336 | .suspend_late = pci_pm_suspend_late, |
---|
1368 | 1337 | .resume = pci_pm_resume, |
---|
| 1338 | + .resume_early = pci_pm_resume_early, |
---|
1369 | 1339 | .freeze = pci_pm_freeze, |
---|
1370 | | - .freeze_late = pci_pm_freeze_late, |
---|
1371 | 1340 | .thaw = pci_pm_thaw, |
---|
1372 | 1341 | .poweroff = pci_pm_poweroff, |
---|
1373 | 1342 | .poweroff_late = pci_pm_poweroff_late, |
---|
.. | .. |
---|
1618 | 1587 | ret = of_dma_configure(dev, bridge->parent->of_node, true); |
---|
1619 | 1588 | } else if (has_acpi_companion(bridge)) { |
---|
1620 | 1589 | struct acpi_device *adev = to_acpi_device_node(bridge->fwnode); |
---|
1621 | | - enum dev_dma_attr attr = acpi_get_dma_attr(adev); |
---|
1622 | 1590 | |
---|
1623 | | - if (attr != DEV_DMA_NOT_SUPPORTED) |
---|
1624 | | - ret = acpi_dma_configure(dev, attr); |
---|
| 1591 | + ret = acpi_dma_configure(dev, acpi_get_dma_attr(adev)); |
---|
1625 | 1592 | } |
---|
1626 | 1593 | |
---|
1627 | 1594 | pci_put_host_bridge_device(bridge); |
---|