diff options
Diffstat (limited to 'drivers/pci/pci-driver.c')
-rw-r--r-- | drivers/pci/pci-driver.c | 134 |
1 files changed, 92 insertions, 42 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 11bd267fc137..07b8a9b385ab 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -680,17 +680,13 @@ static int pci_pm_prepare(struct device *dev) | |||
680 | { | 680 | { |
681 | struct device_driver *drv = dev->driver; | 681 | struct device_driver *drv = dev->driver; |
682 | 682 | ||
683 | /* | ||
684 | * Devices having power.ignore_children set may still be necessary for | ||
685 | * suspending their children in the next phase of device suspend. | ||
686 | */ | ||
687 | if (dev->power.ignore_children) | ||
688 | pm_runtime_resume(dev); | ||
689 | |||
690 | if (drv && drv->pm && drv->pm->prepare) { | 683 | if (drv && drv->pm && drv->pm->prepare) { |
691 | int error = drv->pm->prepare(dev); | 684 | int error = drv->pm->prepare(dev); |
692 | if (error) | 685 | if (error < 0) |
693 | return error; | 686 | return error; |
687 | |||
688 | if (!error && dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_PREPARE)) | ||
689 | return 0; | ||
694 | } | 690 | } |
695 | return pci_dev_keep_suspended(to_pci_dev(dev)); | 691 | return pci_dev_keep_suspended(to_pci_dev(dev)); |
696 | } | 692 | } |
@@ -731,18 +727,25 @@ static int pci_pm_suspend(struct device *dev) | |||
731 | 727 | ||
732 | if (!pm) { | 728 | if (!pm) { |
733 | pci_pm_default_suspend(pci_dev); | 729 | pci_pm_default_suspend(pci_dev); |
734 | goto Fixup; | 730 | return 0; |
735 | } | 731 | } |
736 | 732 | ||
737 | /* | 733 | /* |
738 | * PCI devices suspended at run time need to be resumed at this point, | 734 | * PCI devices suspended at run time may need to be resumed at this |
739 | * because in general it is necessary to reconfigure them for system | 735 | * point, because in general it may be necessary to reconfigure them for |
740 | * suspend. Namely, if the device is supposed to wake up the system | 736 | * system suspend. Namely, if the device is expected to wake up the |
741 | * from the sleep state, we may need to reconfigure it for this purpose. | 737 | * system from the sleep state, it may have to be reconfigured for this |
742 | * In turn, if the device is not supposed to wake up the system from the | 738 | * purpose, or if the device is not expected to wake up the system from |
743 | * sleep state, we'll have to prevent it from signaling wake-up. | 739 | * the sleep state, it should be prevented from signaling wakeup events |
740 | * going forward. | ||
741 | * | ||
742 | * Also if the driver of the device does not indicate that its system | ||
743 | * suspend callbacks can cope with runtime-suspended devices, it is | ||
744 | * better to resume the device from runtime suspend here. | ||
744 | */ | 745 | */ |
745 | pm_runtime_resume(dev); | 746 | if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) || |
747 | !pci_dev_keep_suspended(pci_dev)) | ||
748 | pm_runtime_resume(dev); | ||
746 | 749 | ||
747 | pci_dev->state_saved = false; | 750 | pci_dev->state_saved = false; |
748 | if (pm->suspend) { | 751 | if (pm->suspend) { |
@@ -762,17 +765,27 @@ static int pci_pm_suspend(struct device *dev) | |||
762 | } | 765 | } |
763 | } | 766 | } |
764 | 767 | ||
765 | Fixup: | ||
766 | pci_fixup_device(pci_fixup_suspend, pci_dev); | ||
767 | |||
768 | return 0; | 768 | return 0; |
769 | } | 769 | } |
770 | 770 | ||
771 | static int pci_pm_suspend_late(struct device *dev) | ||
772 | { | ||
773 | if (dev_pm_smart_suspend_and_suspended(dev)) | ||
774 | return 0; | ||
775 | |||
776 | pci_fixup_device(pci_fixup_suspend, to_pci_dev(dev)); | ||
777 | |||
778 | return pm_generic_suspend_late(dev); | ||
779 | } | ||
780 | |||
771 | static int pci_pm_suspend_noirq(struct device *dev) | 781 | static int pci_pm_suspend_noirq(struct device *dev) |
772 | { | 782 | { |
773 | struct pci_dev *pci_dev = to_pci_dev(dev); | 783 | struct pci_dev *pci_dev = to_pci_dev(dev); |
774 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | 784 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
775 | 785 | ||
786 | if (dev_pm_smart_suspend_and_suspended(dev)) | ||
787 | return 0; | ||
788 | |||
776 | if (pci_has_legacy_pm_support(pci_dev)) | 789 | if (pci_has_legacy_pm_support(pci_dev)) |
777 | return pci_legacy_suspend_late(dev, PMSG_SUSPEND); | 790 | return pci_legacy_suspend_late(dev, PMSG_SUSPEND); |
778 | 791 | ||
@@ -805,6 +818,9 @@ static int pci_pm_suspend_noirq(struct device *dev) | |||
805 | pci_prepare_to_sleep(pci_dev); | 818 | pci_prepare_to_sleep(pci_dev); |
806 | } | 819 | } |
807 | 820 | ||
821 | dev_dbg(dev, "PCI PM: Suspend power state: %s\n", | ||
822 | pci_power_name(pci_dev->current_state)); | ||
823 | |||
808 | pci_pm_set_unknown_state(pci_dev); | 824 | pci_pm_set_unknown_state(pci_dev); |
809 | 825 | ||
810 | /* | 826 | /* |
@@ -831,6 +847,14 @@ static int pci_pm_resume_noirq(struct device *dev) | |||
831 | struct device_driver *drv = dev->driver; | 847 | struct device_driver *drv = dev->driver; |
832 | int error = 0; | 848 | int error = 0; |
833 | 849 | ||
850 | /* | ||
851 | * Devices with DPM_FLAG_SMART_SUSPEND may be left in runtime suspend | ||
852 | * during system suspend, so update their runtime PM status to "active" | ||
853 | * as they are going to be put into D0 shortly. | ||
854 | */ | ||
855 | if (dev_pm_smart_suspend_and_suspended(dev)) | ||
856 | pm_runtime_set_active(dev); | ||
857 | |||
834 | pci_pm_default_resume_early(pci_dev); | 858 | pci_pm_default_resume_early(pci_dev); |
835 | 859 | ||
836 | if (pci_has_legacy_pm_support(pci_dev)) | 860 | if (pci_has_legacy_pm_support(pci_dev)) |
@@ -873,6 +897,7 @@ static int pci_pm_resume(struct device *dev) | |||
873 | #else /* !CONFIG_SUSPEND */ | 897 | #else /* !CONFIG_SUSPEND */ |
874 | 898 | ||
875 | #define pci_pm_suspend NULL | 899 | #define pci_pm_suspend NULL |
900 | #define pci_pm_suspend_late NULL | ||
876 | #define pci_pm_suspend_noirq NULL | 901 | #define pci_pm_suspend_noirq NULL |
877 | #define pci_pm_resume NULL | 902 | #define pci_pm_resume NULL |
878 | #define pci_pm_resume_noirq NULL | 903 | #define pci_pm_resume_noirq NULL |
@@ -907,7 +932,8 @@ static int pci_pm_freeze(struct device *dev) | |||
907 | * devices should not be touched during freeze/thaw transitions, | 932 | * devices should not be touched during freeze/thaw transitions, |
908 | * however. | 933 | * however. |
909 | */ | 934 | */ |
910 | pm_runtime_resume(dev); | 935 | if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND)) |
936 | pm_runtime_resume(dev); | ||
911 | 937 | ||
912 | pci_dev->state_saved = false; | 938 | pci_dev->state_saved = false; |
913 | if (pm->freeze) { | 939 | if (pm->freeze) { |
@@ -919,17 +945,25 @@ static int pci_pm_freeze(struct device *dev) | |||
919 | return error; | 945 | return error; |
920 | } | 946 | } |
921 | 947 | ||
922 | if (pcibios_pm_ops.freeze) | ||
923 | return pcibios_pm_ops.freeze(dev); | ||
924 | |||
925 | return 0; | 948 | return 0; |
926 | } | 949 | } |
927 | 950 | ||
951 | static int pci_pm_freeze_late(struct device *dev) | ||
952 | { | ||
953 | if (dev_pm_smart_suspend_and_suspended(dev)) | ||
954 | return 0; | ||
955 | |||
956 | return pm_generic_freeze_late(dev);; | ||
957 | } | ||
958 | |||
928 | static int pci_pm_freeze_noirq(struct device *dev) | 959 | static int pci_pm_freeze_noirq(struct device *dev) |
929 | { | 960 | { |
930 | struct pci_dev *pci_dev = to_pci_dev(dev); | 961 | struct pci_dev *pci_dev = to_pci_dev(dev); |
931 | struct device_driver *drv = dev->driver; | 962 | struct device_driver *drv = dev->driver; |
932 | 963 | ||
964 | if (dev_pm_smart_suspend_and_suspended(dev)) | ||
965 | return 0; | ||
966 | |||
933 | if (pci_has_legacy_pm_support(pci_dev)) | 967 | if (pci_has_legacy_pm_support(pci_dev)) |
934 | return pci_legacy_suspend_late(dev, PMSG_FREEZE); | 968 | return pci_legacy_suspend_late(dev, PMSG_FREEZE); |
935 | 969 | ||
@@ -959,6 +993,16 @@ static int pci_pm_thaw_noirq(struct device *dev) | |||
959 | struct device_driver *drv = dev->driver; | 993 | struct device_driver *drv = dev->driver; |
960 | int error = 0; | 994 | int error = 0; |
961 | 995 | ||
996 | /* | ||
997 | * If the device is in runtime suspend, the code below may not work | ||
998 | * correctly with it, so skip that code and make the PM core skip all of | ||
999 | * the subsequent "thaw" callbacks for the device. | ||
1000 | */ | ||
1001 | if (dev_pm_smart_suspend_and_suspended(dev)) { | ||
1002 | dev->power.direct_complete = true; | ||
1003 | return 0; | ||
1004 | } | ||
1005 | |||
962 | if (pcibios_pm_ops.thaw_noirq) { | 1006 | if (pcibios_pm_ops.thaw_noirq) { |
963 | error = pcibios_pm_ops.thaw_noirq(dev); | 1007 | error = pcibios_pm_ops.thaw_noirq(dev); |
964 | if (error) | 1008 | if (error) |
@@ -983,12 +1027,6 @@ static int pci_pm_thaw(struct device *dev) | |||
983 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | 1027 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
984 | int error = 0; | 1028 | int error = 0; |
985 | 1029 | ||
986 | if (pcibios_pm_ops.thaw) { | ||
987 | error = pcibios_pm_ops.thaw(dev); | ||
988 | if (error) | ||
989 | return error; | ||
990 | } | ||
991 | |||
992 | if (pci_has_legacy_pm_support(pci_dev)) | 1030 | if (pci_has_legacy_pm_support(pci_dev)) |
993 | return pci_legacy_resume(dev); | 1031 | return pci_legacy_resume(dev); |
994 | 1032 | ||
@@ -1014,11 +1052,13 @@ static int pci_pm_poweroff(struct device *dev) | |||
1014 | 1052 | ||
1015 | if (!pm) { | 1053 | if (!pm) { |
1016 | pci_pm_default_suspend(pci_dev); | 1054 | pci_pm_default_suspend(pci_dev); |
1017 | goto Fixup; | 1055 | return 0; |
1018 | } | 1056 | } |
1019 | 1057 | ||
1020 | /* The reason to do that is the same as in pci_pm_suspend(). */ | 1058 | /* The reason to do that is the same as in pci_pm_suspend(). */ |
1021 | pm_runtime_resume(dev); | 1059 | if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) || |
1060 | !pci_dev_keep_suspended(pci_dev)) | ||
1061 | pm_runtime_resume(dev); | ||
1022 | 1062 | ||
1023 | pci_dev->state_saved = false; | 1063 | pci_dev->state_saved = false; |
1024 | if (pm->poweroff) { | 1064 | if (pm->poweroff) { |
@@ -1030,13 +1070,17 @@ static int pci_pm_poweroff(struct device *dev) | |||
1030 | return error; | 1070 | return error; |
1031 | } | 1071 | } |
1032 | 1072 | ||
1033 | Fixup: | 1073 | return 0; |
1034 | pci_fixup_device(pci_fixup_suspend, pci_dev); | 1074 | } |
1035 | 1075 | ||
1036 | if (pcibios_pm_ops.poweroff) | 1076 | static int pci_pm_poweroff_late(struct device *dev) |
1037 | return pcibios_pm_ops.poweroff(dev); | 1077 | { |
1078 | if (dev_pm_smart_suspend_and_suspended(dev)) | ||
1079 | return 0; | ||
1038 | 1080 | ||
1039 | return 0; | 1081 | pci_fixup_device(pci_fixup_suspend, to_pci_dev(dev)); |
1082 | |||
1083 | return pm_generic_poweroff_late(dev); | ||
1040 | } | 1084 | } |
1041 | 1085 | ||
1042 | static int pci_pm_poweroff_noirq(struct device *dev) | 1086 | static int pci_pm_poweroff_noirq(struct device *dev) |
@@ -1044,6 +1088,9 @@ static int pci_pm_poweroff_noirq(struct device *dev) | |||
1044 | struct pci_dev *pci_dev = to_pci_dev(dev); | 1088 | struct pci_dev *pci_dev = to_pci_dev(dev); |
1045 | struct device_driver *drv = dev->driver; | 1089 | struct device_driver *drv = dev->driver; |
1046 | 1090 | ||
1091 | if (dev_pm_smart_suspend_and_suspended(dev)) | ||
1092 | return 0; | ||
1093 | |||
1047 | if (pci_has_legacy_pm_support(to_pci_dev(dev))) | 1094 | if (pci_has_legacy_pm_support(to_pci_dev(dev))) |
1048 | return pci_legacy_suspend_late(dev, PMSG_HIBERNATE); | 1095 | return pci_legacy_suspend_late(dev, PMSG_HIBERNATE); |
1049 | 1096 | ||
@@ -1085,6 +1132,10 @@ static int pci_pm_restore_noirq(struct device *dev) | |||
1085 | struct device_driver *drv = dev->driver; | 1132 | struct device_driver *drv = dev->driver; |
1086 | int error = 0; | 1133 | int error = 0; |
1087 | 1134 | ||
1135 | /* This is analogous to the pci_pm_resume_noirq() case. */ | ||
1136 | if (dev_pm_smart_suspend_and_suspended(dev)) | ||
1137 | pm_runtime_set_active(dev); | ||
1138 | |||
1088 | if (pcibios_pm_ops.restore_noirq) { | 1139 | if (pcibios_pm_ops.restore_noirq) { |
1089 | error = pcibios_pm_ops.restore_noirq(dev); | 1140 | error = pcibios_pm_ops.restore_noirq(dev); |
1090 | if (error) | 1141 | if (error) |
@@ -1108,12 +1159,6 @@ static int pci_pm_restore(struct device *dev) | |||
1108 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | 1159 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
1109 | int error = 0; | 1160 | int error = 0; |
1110 | 1161 | ||
1111 | if (pcibios_pm_ops.restore) { | ||
1112 | error = pcibios_pm_ops.restore(dev); | ||
1113 | if (error) | ||
1114 | return error; | ||
1115 | } | ||
1116 | |||
1117 | /* | 1162 | /* |
1118 | * This is necessary for the hibernation error path in which restore is | 1163 | * This is necessary for the hibernation error path in which restore is |
1119 | * called without restoring the standard config registers of the device. | 1164 | * called without restoring the standard config registers of the device. |
@@ -1139,10 +1184,12 @@ static int pci_pm_restore(struct device *dev) | |||
1139 | #else /* !CONFIG_HIBERNATE_CALLBACKS */ | 1184 | #else /* !CONFIG_HIBERNATE_CALLBACKS */ |
1140 | 1185 | ||
1141 | #define pci_pm_freeze NULL | 1186 | #define pci_pm_freeze NULL |
1187 | #define pci_pm_freeze_late NULL | ||
1142 | #define pci_pm_freeze_noirq NULL | 1188 | #define pci_pm_freeze_noirq NULL |
1143 | #define pci_pm_thaw NULL | 1189 | #define pci_pm_thaw NULL |
1144 | #define pci_pm_thaw_noirq NULL | 1190 | #define pci_pm_thaw_noirq NULL |
1145 | #define pci_pm_poweroff NULL | 1191 | #define pci_pm_poweroff NULL |
1192 | #define pci_pm_poweroff_late NULL | ||
1146 | #define pci_pm_poweroff_noirq NULL | 1193 | #define pci_pm_poweroff_noirq NULL |
1147 | #define pci_pm_restore NULL | 1194 | #define pci_pm_restore NULL |
1148 | #define pci_pm_restore_noirq NULL | 1195 | #define pci_pm_restore_noirq NULL |
@@ -1258,10 +1305,13 @@ static const struct dev_pm_ops pci_dev_pm_ops = { | |||
1258 | .prepare = pci_pm_prepare, | 1305 | .prepare = pci_pm_prepare, |
1259 | .complete = pci_pm_complete, | 1306 | .complete = pci_pm_complete, |
1260 | .suspend = pci_pm_suspend, | 1307 | .suspend = pci_pm_suspend, |
1308 | .suspend_late = pci_pm_suspend_late, | ||
1261 | .resume = pci_pm_resume, | 1309 | .resume = pci_pm_resume, |
1262 | .freeze = pci_pm_freeze, | 1310 | .freeze = pci_pm_freeze, |
1311 | .freeze_late = pci_pm_freeze_late, | ||
1263 | .thaw = pci_pm_thaw, | 1312 | .thaw = pci_pm_thaw, |
1264 | .poweroff = pci_pm_poweroff, | 1313 | .poweroff = pci_pm_poweroff, |
1314 | .poweroff_late = pci_pm_poweroff_late, | ||
1265 | .restore = pci_pm_restore, | 1315 | .restore = pci_pm_restore, |
1266 | .suspend_noirq = pci_pm_suspend_noirq, | 1316 | .suspend_noirq = pci_pm_suspend_noirq, |
1267 | .resume_noirq = pci_pm_resume_noirq, | 1317 | .resume_noirq = pci_pm_resume_noirq, |