aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/power/pci.txt14
-rw-r--r--drivers/base/power/main.c6
-rw-r--r--drivers/pci/pci-driver.c103
-rw-r--r--include/linux/pm.h2
4 files changed, 108 insertions, 17 deletions
diff --git a/Documentation/power/pci.txt b/Documentation/power/pci.txt
index ab4e7d0540c1..304162ea377e 100644
--- a/Documentation/power/pci.txt
+++ b/Documentation/power/pci.txt
@@ -980,6 +980,20 @@ positive value from pci_pm_prepare() if the ->prepare callback provided by the
980driver of the device returns a positive value. That allows the driver to opt 980driver of the device returns a positive value. That allows the driver to opt
981out from using the direct-complete mechanism dynamically. 981out from using the direct-complete mechanism dynamically.
982 982
983The DPM_FLAG_SMART_SUSPEND flag tells the PCI bus type that from the driver's
984perspective the device can be safely left in runtime suspend during system
985suspend. That causes pci_pm_suspend(), pci_pm_freeze() and pci_pm_poweroff()
986to skip resuming the device from runtime suspend unless there are PCI-specific
987reasons for doing that. Also, it causes pci_pm_suspend_late/noirq(),
988pci_pm_freeze_late/noirq() and pci_pm_poweroff_late/noirq() to return early
989if the device remains in runtime suspend in the beginning of the "late" phase
990of the system-wide transition under way. Moreover, if the device is in
991runtime suspend in pci_pm_resume_noirq() or pci_pm_restore_noirq(), its runtime
992power management status will be changed to "active" (as it is going to be put
993into D0 going forward), but if it is in runtime suspend in pci_pm_thaw_noirq(),
994the function will set the power.direct_complete flag for it (to make the PM core
995skip the subsequent "thaw" callbacks for it) and return.
996
9833.2. Device Runtime Power Management 9973.2. Device Runtime Power Management
984------------------------------------ 998------------------------------------
985In addition to providing device power management callbacks PCI device drivers 999In addition to providing device power management callbacks PCI device drivers
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 8d9024017645..6c6f1c74c24c 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -1861,3 +1861,9 @@ void device_pm_check_callbacks(struct device *dev)
1861 !dev->driver->suspend && !dev->driver->resume)); 1861 !dev->driver->suspend && !dev->driver->resume));
1862 spin_unlock_irq(&dev->power.lock); 1862 spin_unlock_irq(&dev->power.lock);
1863} 1863}
1864
1865bool dev_pm_smart_suspend_and_suspended(struct device *dev)
1866{
1867 return dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) &&
1868 pm_runtime_status_suspended(dev);
1869}
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index c1aeeb10539e..d19bd54d337e 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -734,18 +734,25 @@ static int pci_pm_suspend(struct device *dev)
734 734
735 if (!pm) { 735 if (!pm) {
736 pci_pm_default_suspend(pci_dev); 736 pci_pm_default_suspend(pci_dev);
737 goto Fixup; 737 return 0;
738 } 738 }
739 739
740 /* 740 /*
741 * PCI devices suspended at run time need to be resumed at this point, 741 * PCI devices suspended at run time may need to be resumed at this
742 * because in general it is necessary to reconfigure them for system 742 * point, because in general it may be necessary to reconfigure them for
743 * suspend. Namely, if the device is supposed to wake up the system 743 * system suspend. Namely, if the device is expected to wake up the
744 * from the sleep state, we may need to reconfigure it for this purpose. 744 * system from the sleep state, it may have to be reconfigured for this
745 * In turn, if the device is not supposed to wake up the system from the 745 * purpose, or if the device is not expected to wake up the system from
746 * sleep state, we'll have to prevent it from signaling wake-up. 746 * the sleep state, it should be prevented from signaling wakeup events
747 * going forward.
748 *
749 * Also if the driver of the device does not indicate that its system
750 * suspend callbacks can cope with runtime-suspended devices, it is
751 * better to resume the device from runtime suspend here.
747 */ 752 */
748 pm_runtime_resume(dev); 753 if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) ||
754 !pci_dev_keep_suspended(pci_dev))
755 pm_runtime_resume(dev);
749 756
750 pci_dev->state_saved = false; 757 pci_dev->state_saved = false;
751 if (pm->suspend) { 758 if (pm->suspend) {
@@ -765,17 +772,27 @@ static int pci_pm_suspend(struct device *dev)
765 } 772 }
766 } 773 }
767 774
768 Fixup:
769 pci_fixup_device(pci_fixup_suspend, pci_dev);
770
771 return 0; 775 return 0;
772} 776}
773 777
778static int pci_pm_suspend_late(struct device *dev)
779{
780 if (dev_pm_smart_suspend_and_suspended(dev))
781 return 0;
782
783 pci_fixup_device(pci_fixup_suspend, to_pci_dev(dev));
784
785 return pm_generic_suspend_late(dev);
786}
787
774static int pci_pm_suspend_noirq(struct device *dev) 788static int pci_pm_suspend_noirq(struct device *dev)
775{ 789{
776 struct pci_dev *pci_dev = to_pci_dev(dev); 790 struct pci_dev *pci_dev = to_pci_dev(dev);
777 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 791 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
778 792
793 if (dev_pm_smart_suspend_and_suspended(dev))
794 return 0;
795
779 if (pci_has_legacy_pm_support(pci_dev)) 796 if (pci_has_legacy_pm_support(pci_dev))
780 return pci_legacy_suspend_late(dev, PMSG_SUSPEND); 797 return pci_legacy_suspend_late(dev, PMSG_SUSPEND);
781 798
@@ -834,6 +851,14 @@ static int pci_pm_resume_noirq(struct device *dev)
834 struct device_driver *drv = dev->driver; 851 struct device_driver *drv = dev->driver;
835 int error = 0; 852 int error = 0;
836 853
854 /*
855 * Devices with DPM_FLAG_SMART_SUSPEND may be left in runtime suspend
856 * during system suspend, so update their runtime PM status to "active"
857 * as they are going to be put into D0 shortly.
858 */
859 if (dev_pm_smart_suspend_and_suspended(dev))
860 pm_runtime_set_active(dev);
861
837 pci_pm_default_resume_early(pci_dev); 862 pci_pm_default_resume_early(pci_dev);
838 863
839 if (pci_has_legacy_pm_support(pci_dev)) 864 if (pci_has_legacy_pm_support(pci_dev))
@@ -876,6 +901,7 @@ static int pci_pm_resume(struct device *dev)
876#else /* !CONFIG_SUSPEND */ 901#else /* !CONFIG_SUSPEND */
877 902
878#define pci_pm_suspend NULL 903#define pci_pm_suspend NULL
904#define pci_pm_suspend_late NULL
879#define pci_pm_suspend_noirq NULL 905#define pci_pm_suspend_noirq NULL
880#define pci_pm_resume NULL 906#define pci_pm_resume NULL
881#define pci_pm_resume_noirq NULL 907#define pci_pm_resume_noirq NULL
@@ -910,7 +936,8 @@ static int pci_pm_freeze(struct device *dev)
910 * devices should not be touched during freeze/thaw transitions, 936 * devices should not be touched during freeze/thaw transitions,
911 * however. 937 * however.
912 */ 938 */
913 pm_runtime_resume(dev); 939 if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND))
940 pm_runtime_resume(dev);
914 941
915 pci_dev->state_saved = false; 942 pci_dev->state_saved = false;
916 if (pm->freeze) { 943 if (pm->freeze) {
@@ -925,11 +952,22 @@ static int pci_pm_freeze(struct device *dev)
925 return 0; 952 return 0;
926} 953}
927 954
955static int pci_pm_freeze_late(struct device *dev)
956{
957 if (dev_pm_smart_suspend_and_suspended(dev))
958 return 0;
959
960 return pm_generic_freeze_late(dev);;
961}
962
928static int pci_pm_freeze_noirq(struct device *dev) 963static int pci_pm_freeze_noirq(struct device *dev)
929{ 964{
930 struct pci_dev *pci_dev = to_pci_dev(dev); 965 struct pci_dev *pci_dev = to_pci_dev(dev);
931 struct device_driver *drv = dev->driver; 966 struct device_driver *drv = dev->driver;
932 967
968 if (dev_pm_smart_suspend_and_suspended(dev))
969 return 0;
970
933 if (pci_has_legacy_pm_support(pci_dev)) 971 if (pci_has_legacy_pm_support(pci_dev))
934 return pci_legacy_suspend_late(dev, PMSG_FREEZE); 972 return pci_legacy_suspend_late(dev, PMSG_FREEZE);
935 973
@@ -959,6 +997,16 @@ static int pci_pm_thaw_noirq(struct device *dev)
959 struct device_driver *drv = dev->driver; 997 struct device_driver *drv = dev->driver;
960 int error = 0; 998 int error = 0;
961 999
1000 /*
1001 * If the device is in runtime suspend, the code below may not work
1002 * correctly with it, so skip that code and make the PM core skip all of
1003 * the subsequent "thaw" callbacks for the device.
1004 */
1005 if (dev_pm_smart_suspend_and_suspended(dev)) {
1006 dev->power.direct_complete = true;
1007 return 0;
1008 }
1009
962 if (pcibios_pm_ops.thaw_noirq) { 1010 if (pcibios_pm_ops.thaw_noirq) {
963 error = pcibios_pm_ops.thaw_noirq(dev); 1011 error = pcibios_pm_ops.thaw_noirq(dev);
964 if (error) 1012 if (error)
@@ -1008,11 +1056,13 @@ static int pci_pm_poweroff(struct device *dev)
1008 1056
1009 if (!pm) { 1057 if (!pm) {
1010 pci_pm_default_suspend(pci_dev); 1058 pci_pm_default_suspend(pci_dev);
1011 goto Fixup; 1059 return 0;
1012 } 1060 }
1013 1061
1014 /* The reason to do that is the same as in pci_pm_suspend(). */ 1062 /* The reason to do that is the same as in pci_pm_suspend(). */
1015 pm_runtime_resume(dev); 1063 if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) ||
1064 !pci_dev_keep_suspended(pci_dev))
1065 pm_runtime_resume(dev);
1016 1066
1017 pci_dev->state_saved = false; 1067 pci_dev->state_saved = false;
1018 if (pm->poweroff) { 1068 if (pm->poweroff) {
@@ -1024,17 +1074,27 @@ static int pci_pm_poweroff(struct device *dev)
1024 return error; 1074 return error;
1025 } 1075 }
1026 1076
1027 Fixup:
1028 pci_fixup_device(pci_fixup_suspend, pci_dev);
1029
1030 return 0; 1077 return 0;
1031} 1078}
1032 1079
1080static int pci_pm_poweroff_late(struct device *dev)
1081{
1082 if (dev_pm_smart_suspend_and_suspended(dev))
1083 return 0;
1084
1085 pci_fixup_device(pci_fixup_suspend, to_pci_dev(dev));
1086
1087 return pm_generic_poweroff_late(dev);
1088}
1089
1033static int pci_pm_poweroff_noirq(struct device *dev) 1090static int pci_pm_poweroff_noirq(struct device *dev)
1034{ 1091{
1035 struct pci_dev *pci_dev = to_pci_dev(dev); 1092 struct pci_dev *pci_dev = to_pci_dev(dev);
1036 struct device_driver *drv = dev->driver; 1093 struct device_driver *drv = dev->driver;
1037 1094
1095 if (dev_pm_smart_suspend_and_suspended(dev))
1096 return 0;
1097
1038 if (pci_has_legacy_pm_support(to_pci_dev(dev))) 1098 if (pci_has_legacy_pm_support(to_pci_dev(dev)))
1039 return pci_legacy_suspend_late(dev, PMSG_HIBERNATE); 1099 return pci_legacy_suspend_late(dev, PMSG_HIBERNATE);
1040 1100
@@ -1076,6 +1136,10 @@ static int pci_pm_restore_noirq(struct device *dev)
1076 struct device_driver *drv = dev->driver; 1136 struct device_driver *drv = dev->driver;
1077 int error = 0; 1137 int error = 0;
1078 1138
1139 /* This is analogous to the pci_pm_resume_noirq() case. */
1140 if (dev_pm_smart_suspend_and_suspended(dev))
1141 pm_runtime_set_active(dev);
1142
1079 if (pcibios_pm_ops.restore_noirq) { 1143 if (pcibios_pm_ops.restore_noirq) {
1080 error = pcibios_pm_ops.restore_noirq(dev); 1144 error = pcibios_pm_ops.restore_noirq(dev);
1081 if (error) 1145 if (error)
@@ -1124,10 +1188,12 @@ static int pci_pm_restore(struct device *dev)
1124#else /* !CONFIG_HIBERNATE_CALLBACKS */ 1188#else /* !CONFIG_HIBERNATE_CALLBACKS */
1125 1189
1126#define pci_pm_freeze NULL 1190#define pci_pm_freeze NULL
1191#define pci_pm_freeze_late NULL
1127#define pci_pm_freeze_noirq NULL 1192#define pci_pm_freeze_noirq NULL
1128#define pci_pm_thaw NULL 1193#define pci_pm_thaw NULL
1129#define pci_pm_thaw_noirq NULL 1194#define pci_pm_thaw_noirq NULL
1130#define pci_pm_poweroff NULL 1195#define pci_pm_poweroff NULL
1196#define pci_pm_poweroff_late NULL
1131#define pci_pm_poweroff_noirq NULL 1197#define pci_pm_poweroff_noirq NULL
1132#define pci_pm_restore NULL 1198#define pci_pm_restore NULL
1133#define pci_pm_restore_noirq NULL 1199#define pci_pm_restore_noirq NULL
@@ -1243,10 +1309,13 @@ static const struct dev_pm_ops pci_dev_pm_ops = {
1243 .prepare = pci_pm_prepare, 1309 .prepare = pci_pm_prepare,
1244 .complete = pci_pm_complete, 1310 .complete = pci_pm_complete,
1245 .suspend = pci_pm_suspend, 1311 .suspend = pci_pm_suspend,
1312 .suspend_late = pci_pm_suspend_late,
1246 .resume = pci_pm_resume, 1313 .resume = pci_pm_resume,
1247 .freeze = pci_pm_freeze, 1314 .freeze = pci_pm_freeze,
1315 .freeze_late = pci_pm_freeze_late,
1248 .thaw = pci_pm_thaw, 1316 .thaw = pci_pm_thaw,
1249 .poweroff = pci_pm_poweroff, 1317 .poweroff = pci_pm_poweroff,
1318 .poweroff_late = pci_pm_poweroff_late,
1250 .restore = pci_pm_restore, 1319 .restore = pci_pm_restore,
1251 .suspend_noirq = pci_pm_suspend_noirq, 1320 .suspend_noirq = pci_pm_suspend_noirq,
1252 .resume_noirq = pci_pm_resume_noirq, 1321 .resume_noirq = pci_pm_resume_noirq,
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 43b5418e05bb..65d39115f06d 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -765,6 +765,8 @@ extern int pm_generic_poweroff_late(struct device *dev);
765extern int pm_generic_poweroff(struct device *dev); 765extern int pm_generic_poweroff(struct device *dev);
766extern void pm_generic_complete(struct device *dev); 766extern void pm_generic_complete(struct device *dev);
767 767
768extern bool dev_pm_smart_suspend_and_suspended(struct device *dev);
769
768#else /* !CONFIG_PM_SLEEP */ 770#else /* !CONFIG_PM_SLEEP */
769 771
770#define device_pm_lock() do {} while (0) 772#define device_pm_lock() do {} while (0)