Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pm-5.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management fix from Rafael Wysocki:
"Avoid skipping bus-level PCI power management during system resume for
PCIe ports left in D0 during the preceding suspend transition on
platforms where the power states of those ports can change out of the
PCI layer's control"

* tag 'pm-5.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
PCI: PM: Avoid skipping bus-level PM on platforms without ACPI

+31 -6
+4 -4
drivers/pci/pci-driver.c
··· 859 859 pci_dev->bus->self->skip_bus_pm = true; 860 860 } 861 861 862 - if (pci_dev->skip_bus_pm && !pm_suspend_via_firmware()) { 862 + if (pci_dev->skip_bus_pm && pm_suspend_no_platform()) { 863 863 dev_dbg(dev, "PCI PM: Skipped\n"); 864 864 goto Fixup; 865 865 } ··· 914 914 /* 915 915 * In the suspend-to-idle case, devices left in D0 during suspend will 916 916 * stay in D0, so it is not necessary to restore or update their 917 - * configuration here and attempting to put them into D0 again may 918 - * confuse some firmware, so avoid doing that. 917 + * configuration here and attempting to put them into D0 again is 918 + * pointless, so avoid doing that. 919 919 */ 920 - if (!pci_dev->skip_bus_pm || pm_suspend_via_firmware()) 920 + if (!(pci_dev->skip_bus_pm && pm_suspend_no_platform())) 921 921 pci_pm_default_resume_early(pci_dev); 922 922 923 923 pci_fixup_device(pci_fixup_resume_early, pci_dev);
+24 -2
include/linux/suspend.h
··· 209 209 210 210 extern unsigned int pm_suspend_global_flags; 211 211 212 - #define PM_SUSPEND_FLAG_FW_SUSPEND (1 << 0) 213 - #define PM_SUSPEND_FLAG_FW_RESUME (1 << 1) 212 + #define PM_SUSPEND_FLAG_FW_SUSPEND BIT(0) 213 + #define PM_SUSPEND_FLAG_FW_RESUME BIT(1) 214 + #define PM_SUSPEND_FLAG_NO_PLATFORM BIT(2) 214 215 215 216 static inline void pm_suspend_clear_flags(void) 216 217 { ··· 226 225 static inline void pm_set_resume_via_firmware(void) 227 226 { 228 227 pm_suspend_global_flags |= PM_SUSPEND_FLAG_FW_RESUME; 228 + } 229 + 230 + static inline void pm_set_suspend_no_platform(void) 231 + { 232 + pm_suspend_global_flags |= PM_SUSPEND_FLAG_NO_PLATFORM; 229 233 } 230 234 231 235 /** ··· 272 266 static inline bool pm_resume_via_firmware(void) 273 267 { 274 268 return !!(pm_suspend_global_flags & PM_SUSPEND_FLAG_FW_RESUME); 269 + } 270 + 271 + /** 272 + * pm_suspend_no_platform - Check if platform may change device power states. 273 + * 274 + * To be called during system-wide power management transitions to sleep states 275 + * or during the subsequent system-wide transitions back to the working state. 276 + * 277 + * Return 'true' if the power states of devices remain under full control of the 278 + * kernel throughout the system-wide suspend and resume cycle in progress (that 279 + * is, if a device is put into a certain power state during suspend, it can be 280 + * expected to remain in that state during resume). 281 + */ 282 + static inline bool pm_suspend_no_platform(void) 283 + { 284 + return !!(pm_suspend_global_flags & PM_SUSPEND_FLAG_NO_PLATFORM); 275 285 } 276 286 277 287 /* Suspend-to-idle state machnine. */
+3
kernel/power/suspend.c
··· 493 493 494 494 pm_suspend_target_state = state; 495 495 496 + if (state == PM_SUSPEND_TO_IDLE) 497 + pm_set_suspend_no_platform(); 498 + 496 499 error = platform_suspend_begin(state); 497 500 if (error) 498 501 goto Close;