On Monday, October 14, 2019 8:18:06 AM CEST Daniel Drake wrote: > On Fri, Oct 11, 2019 at 6:14 PM Rafael J. Wysocki <rjw@xxxxxxxxxxxxx> wrote: > > So I think that we can use pci_restore_standard_config() in the system resume > > patch too, which should address the issue as well. > > > > Basically, there is no reason for the PM-runtime and system-wide resume code > > paths to be different in that respect. > > Your patch works without modification when combined with > https://patchwork.kernel.org/patch/11187815/ Great, thanks for the confirmation! > Can you push this directly or would it be helpful if I update the > commit message and submit it by email? It would be prudent if I submitted it properly with a changelog etc. However, I noticed that it might cause the ACPI power state to get out of sync during resume from suspend-to-RAM in some (arguably theoretical only) cases. Specifically, that may happen if the kernel puts a device into D3hot on suspend and the platform firmware powers it up during system wakeup, because in that case the pci_update_current_state() in pci_restore_standard_config() will notice D0 and the pci_set_power_state() in there will not be called, so the ACPI layer will still hold on to the stale D3hot power state value. While I still think that both the system resume and runtime resume code paths should be as similar as reasonably possible, the above needs to be taken into account IMO, so it is better to retain pci_pm_default_resume_early(), but make it do a conditional "ACPI power state refresh" and then call pci_restore_standard_config(). So something like the patch below (can you please test it too?). --- drivers/pci/pci-driver.c | 8 +++++--- drivers/pci/pci.c | 15 --------------- drivers/pci/pci.h | 1 - 3 files changed, 5 insertions(+), 19 deletions(-) Index: linux-pm/drivers/pci/pci-driver.c =================================================================== --- linux-pm.orig/drivers/pci/pci-driver.c +++ linux-pm/drivers/pci/pci-driver.c @@ -523,9 +523,10 @@ static int pci_restore_standard_config(s static void pci_pm_default_resume_early(struct pci_dev *pci_dev) { - pci_power_up(pci_dev); - pci_restore_state(pci_dev); - pci_pme_restore(pci_dev); + if (pm_resume_via_firmware()) + pci_refresh_power_state(pci_dev); + + pci_restore_standard_config(pci_dev); } /* @@ -713,6 +714,7 @@ static void pci_pm_complete(struct devic pci_power_t pre_sleep_state = pci_dev->current_state; pci_refresh_power_state(pci_dev); + pci_update_current_state(pci_dev, pci_dev->current_state); /* * On platforms with ACPI this check may also trigger for * devices sharing power resources if one of those power Index: linux-pm/drivers/pci/pci.c =================================================================== --- linux-pm.orig/drivers/pci/pci.c +++ linux-pm/drivers/pci/pci.c @@ -954,21 +954,6 @@ void pci_refresh_power_state(struct pci_ { if (platform_pci_power_manageable(dev)) platform_pci_refresh_power_state(dev); - - pci_update_current_state(dev, dev->current_state); -} - -/** - * pci_power_up - Put the given device into D0 forcibly - * @dev: PCI device to power up - */ -void pci_power_up(struct pci_dev *dev) -{ - if (platform_pci_power_manageable(dev)) - platform_pci_set_power_state(dev, PCI_D0); - - pci_raw_set_power_state(dev, PCI_D0); - pci_update_current_state(dev, PCI_D0); } /** Index: linux-pm/drivers/pci/pci.h =================================================================== --- linux-pm.orig/drivers/pci/pci.h +++ linux-pm/drivers/pci/pci.h @@ -85,7 +85,6 @@ struct pci_platform_pm_ops { int pci_set_platform_pm(const struct pci_platform_pm_ops *ops); void pci_update_current_state(struct pci_dev *dev, pci_power_t state); void pci_refresh_power_state(struct pci_dev *dev); -void pci_power_up(struct pci_dev *dev); void pci_disable_enabled_device(struct pci_dev *dev); int pci_finish_runtime_suspend(struct pci_dev *dev); void pcie_clear_root_pme_status(struct pci_dev *dev);