You need to sign in or sign up before continuing.
  • R
    PCI/PM: Do not call pci_update_current_state() from pci_power_up() · 0b591935
    Rafael J. Wysocki 提交于
    Notice that calling pci_update_current_state() from pci_power_up() is
    redundant and may be harmful in some cases.
    
    First, if the device is in a low-power state before pci_power_up()
    gets called for it and platform_pci_set_power_state() successfully
    changes its power state to D0, pci_update_current_state() will update
    current_state to reflect that and pci_power_up() will return success
    right away without restoring the device's BARs or reconfiguring ASPM
    which may be necessary.  This is arguably incorrect and definitely
    inconsistent with the case when platform_pci_set_power_state() returns
    an error (for example, because the device is not power-manageable by
    the platform firmware).
    
    Second, current_state should not be overwritten until the decision
    whether or not to restore the device's BARs is made, because that
    decision generally depends on its value.  Again, calling
    pci_update_current_state() in pci_power_up() is not consistent with
    this observation.
    
    Next, pci_power_up() attempts to read from the device's PCI_PM_CTRL
    register regardless of the current_state value unless it is PCI_D0,
    including the case when pci_update_current_state() sets current_state
    to PCI_D3cold to indicate that the device is not accessible.  If the
    register read is not successful, current_state will be set to
    PCI_D3cold anyway, so that pci_update_current_state() action is
    redundant.
    
    Further, if pci_update_current_state() reads the device's PCI_PM_CTRL
    register, pci_power_up() will repeat that read going forward and
    it is not necessary to update current_state in the meantime.
    
    Finally, if pm_cap is not set (in which case the PCI_PM_CTRL register
    is not present), the power state of the device should be determined
    with the help of the platform firmware or set to D0 if that's not
    possible and pci_update_current_state() does not do that.
    
    Accordingly, rearrange pci_power_up() so as to address the above
    shortcomings.
    
    Link: https://lore.kernel.org/r/3695055.kQq0lBPeGt@kreacherSigned-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
    Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
    0b591935
pci.c 180.4 KB