lkml.org 
[lkml]   [2018]   [Apr]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL for 4.9 192/293] PCI/PM: Avoid using device_may_wakeup() for runtime PM
    Date
    From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

    [ Upstream commit 666ff6f83e1db6ed847abf44eb5e3402d82b9350 ]

    pci_target_state() calls device_may_wakeup() which checks whether or not
    the device may wake up the system from sleep states, but pci_target_state()
    is used for runtime PM too.

    Since runtime PM is expected to always enable remote wakeup if possible,
    modify pci_target_state() to take additional argument indicating whether or
    not it should look for a state from which the device can signal wakeup and
    pass either the return value of device_can_wakeup(), or "false" (if the
    device itself is not wakeup-capable) to it from the code related to runtime
    PM.

    While at it, fix the comment in pci_dev_run_wake() which is not about sleep
    states.

    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    ---
    drivers/pci/pci.c | 22 +++++++++++++---------
    1 file changed, 13 insertions(+), 9 deletions(-)

    diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
    index 774b0e2d117b..d6480b30ea8a 100644
    --- a/drivers/pci/pci.c
    +++ b/drivers/pci/pci.c
    @@ -1958,12 +1958,13 @@ EXPORT_SYMBOL(pci_wake_from_d3);
    /**
    * pci_target_state - find an appropriate low power state for a given PCI dev
    * @dev: PCI device
    + * @wakeup: Whether or not wakeup functionality will be enabled for the device.
    *
    * Use underlying platform code to find a supported low power state for @dev.
    * If the platform can't manage @dev, return the deepest state from which it
    * can generate wake events, based on any available PME info.
    */
    -static pci_power_t pci_target_state(struct pci_dev *dev)
    +static pci_power_t pci_target_state(struct pci_dev *dev, bool wakeup)
    {
    pci_power_t target_state = PCI_D3hot;

    @@ -2000,7 +2001,7 @@ static pci_power_t pci_target_state(struct pci_dev *dev)
    if (dev->current_state == PCI_D3cold)
    target_state = PCI_D3cold;

    - if (device_may_wakeup(&dev->dev)) {
    + if (wakeup) {
    /*
    * Find the deepest state from which the device can generate
    * wake-up events, make it the target state and enable device
    @@ -2026,13 +2027,14 @@ static pci_power_t pci_target_state(struct pci_dev *dev)
    */
    int pci_prepare_to_sleep(struct pci_dev *dev)
    {
    - pci_power_t target_state = pci_target_state(dev);
    + bool wakeup = device_may_wakeup(&dev->dev);
    + pci_power_t target_state = pci_target_state(dev, wakeup);
    int error;

    if (target_state == PCI_POWER_ERROR)
    return -EIO;

    - pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev));
    + pci_enable_wake(dev, target_state, wakeup);

    error = pci_set_power_state(dev, target_state);

    @@ -2065,9 +2067,10 @@ EXPORT_SYMBOL(pci_back_from_sleep);
    */
    int pci_finish_runtime_suspend(struct pci_dev *dev)
    {
    - pci_power_t target_state = pci_target_state(dev);
    + pci_power_t target_state;
    int error;

    + target_state = pci_target_state(dev, device_can_wakeup(&dev->dev));
    if (target_state == PCI_POWER_ERROR)
    return -EIO;

    @@ -2103,8 +2106,8 @@ bool pci_dev_run_wake(struct pci_dev *dev)
    if (!dev->pme_support)
    return false;

    - /* PME-capable in principle, but not from the intended sleep state */
    - if (!pci_pme_capable(dev, pci_target_state(dev)))
    + /* PME-capable in principle, but not from the target power state */
    + if (!pci_pme_capable(dev, pci_target_state(dev, false)))
    return false;

    while (bus->parent) {
    @@ -2139,9 +2142,10 @@ EXPORT_SYMBOL_GPL(pci_dev_run_wake);
    bool pci_dev_keep_suspended(struct pci_dev *pci_dev)
    {
    struct device *dev = &pci_dev->dev;
    + bool wakeup = device_may_wakeup(dev);

    if (!pm_runtime_suspended(dev)
    - || pci_target_state(pci_dev) != pci_dev->current_state
    + || pci_target_state(pci_dev, wakeup) != pci_dev->current_state
    || platform_pci_need_resume(pci_dev)
    || (pci_dev->dev_flags & PCI_DEV_FLAGS_NEEDS_RESUME))
    return false;
    @@ -2159,7 +2163,7 @@ bool pci_dev_keep_suspended(struct pci_dev *pci_dev)
    spin_lock_irq(&dev->power.lock);

    if (pm_runtime_suspended(dev) && pci_dev->current_state < PCI_D3cold &&
    - !device_may_wakeup(dev))
    + !wakeup)
    __pci_pme_active(pci_dev, false);

    spin_unlock_irq(&dev->power.lock);
    --
    2.15.1
    \
     
     \ /
      Last update: 2018-04-09 04:03    [W:4.168 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site