1. 18 11月, 2016 5 次提交
    • L
      PCI: Consolidate conditions to allow runtime PM on PCIe ports · 97a90aee
      Lukas Wunner 提交于
      The conditions to allow runtime PM on PCIe ports are currently spread
      across two different files:  The condition relating to hotplug ports is
      located in portdrv_pci.c whereas all other conditions are located in pci.c.
      
      Consolidate all conditions in a single place in pci.c, thus making it
      easier to follow the logic and amend conditions down the road.
      
      Note that the condition relating to hotplug ports is inserted *before* the
      condition relating to the "pcie_port_pm=force" command line option, so
      runtime PM is not afforded to hotplug ports even if this option is given.
      That's exactly how the code behaved up until now.  If this is not desired,
      the ordering of the conditions can simply be reversed.
      
      No functional change intended.
      Tested-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Signed-off-by: NLukas Wunner <lukas@wunner.de>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Reviewed-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      97a90aee
    • L
      PCI: Activate runtime PM on a PCIe port only if it can suspend · c6a63307
      Lukas Wunner 提交于
      Currently pcie_portdrv_probe() activates runtime PM on a PCIe port even
      if it will never actually suspend because the BIOS is too old or the
      "pcie_port_pm=off" option was specified on the kernel command line.
      
      A few CPU cycles can be saved by not activating runtime PM at all in these
      cases, because rpm_idle() and rpm_suspend() will bail out right at the
      beginning when calling rpm_check_suspend_allowed(), instead of carrying out
      various locking and assignments, invoking rpm_callback(), getting back
      -EBUSY and rolling everything back.
      
      The conditions checked in pci_bridge_d3_possible() are all static, they
      never change during uptime of the system, hence it's safe to call this to
      determine if runtime PM should be activated.
      
      No functional change intended.
      Tested-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Signed-off-by: NLukas Wunner <lukas@wunner.de>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Reviewed-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      c6a63307
    • L
      PCI: Speed up algorithm in pci_bridge_d3_update() · e8559b71
      Lukas Wunner 提交于
      After a device has been added, removed or had its D3cold attributes
      changed, we recheck whether its parent bridge may runtime suspend to D3hot
      with pci_bridge_d3_update().
      
      The most naive algorithm would be to iterate over the bridge's children and
      check if any of them are blocking D3.
      
      The function already tries to be a bit smarter than that by first checking
      the device that was changed.  If this device already blocks D3 on the
      bridge, then walking over all the other children can be skipped.  A
      drawback of this approach is that if the device is *not* blocking D3, it
      will be checked a second time by pci_walk_bus().  But that's cheap and is
      outweighed by the performance gain of potentially skipping pci_walk_bus()
      altogether.
      
      The algorithm can be optimized further by taking into account if D3 is
      currently allowed for the bridge, as shown in the following truth table:
      
      (a)  remove &&  bridge_d3:  D3 is currently allowed for the bridge and
                                  removing one of its children won't change
                                  that.  No action necessary.
      (b)  remove && !bridge_d3:  D3 may now be allowed for the bridge if the
                                  removed child was the only one blocking it.
                                  Check all its siblings to verify that.
      (c) !remove &&  bridge_d3:  D3 may now be disallowed but this can only
                                  be caused by the added/changed child, not
                                  any of its siblings.  Check only that single
                                  device.
      (d) !remove && !bridge_d3:  D3 may now be allowed for the bridge if the
                                  changed child was the only one blocking it.
                                  Check all its siblings to verify that.
                                  By checking beforehand if the changed child
                                  is blocking D3, we may be able to skip
                                  checking its siblings.
      
      Currently we do not special-case option (a) and in case of option (c) we
      gratuitously call pci_walk_bus().  Speed up the algorithm by adding these
      optimizations.  Reword the comments a bit in an attempt to improve clarity.
      
      No functional change intended.
      Tested-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Signed-off-by: NLukas Wunner <lukas@wunner.de>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Reviewed-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      e8559b71
    • L
      PCI: Autosense device removal in pci_bridge_d3_update() · 1ed276a7
      Lukas Wunner 提交于
      The algorithm to update the flag indicating whether a bridge may go to D3
      makes a few optimizations based on whether the update was caused by the
      removal of a device on the one hand, versus the addition of a device or the
      change of its D3cold flags on the other hand.
      
      The information whether the update pertains to a removal is currently
      passed in by the caller, but the function may as well determine that itself
      by examining the device in question, thereby allowing for a considerable
      simplification and reduction of the code.
      
      Out of several options to determine removal, I've chosen the function
      device_is_registered() because it's cheap:  It merely returns the
      dev->kobj.state_in_sysfs flag.  That flag is set through device_add() when
      the root bus is scanned and cleared through device_remove().  The call to
      pci_bridge_d3_update() happens after each of these calls, respectively, so
      the ordering is correct.
      
      No functional change intended.
      Tested-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Signed-off-by: NLukas Wunner <lukas@wunner.de>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Reviewed-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      1ed276a7
    • L
      PCI: Don't acquire ref on parent in pci_bridge_d3_update() · 738a7edb
      Lukas Wunner 提交于
      This function is always called with an existing pci_dev struct, which
      holds a reference on the pci_bus struct it resides on, which in turn
      holds a reference on pci_bus->bridge, which is the pci_dev's parent.
      
      Hence there's no need to acquire an additional ref on the parent.
      
      More specifically, the pci_dev exists until pci_destroy_dev() drops the
      final reference on it, so all calls to pci_bridge_d3_update() must be
      finished before that.  It is arguably the caller's responsibility to ensure
      that it doesn't call pci_bridge_d3_update() with a pci_dev that might
      suddenly disappear, but in any case the existing callers are all safe:
      
      - The call in pci_destroy_dev() happens before the call to put_device().
      - The call in pci_bus_add_device() is synchronized with pci_destroy_dev()
        using pci_lock_rescan_remove().
      - The calls to pci_d3cold_disable() from the xhci and nouveau drivers
        are safe because a ref on the pci_dev is held as long as it's bound to
        a driver.
      - The calls to pci_d3cold_enable() / pci_d3cold_disable() when modifying
        the sysfs "d3cold_allowed" entry are also safe because kernfs_drain()
        waits for existing sysfs users to finish before removing the entry,
        and pci_destroy_dev() is called way after that.
      
      No functional change intended.
      Tested-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Signed-off-by: NLukas Wunner <lukas@wunner.de>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Reviewed-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      738a7edb
  2. 12 11月, 2016 2 次提交
  3. 15 10月, 2016 10 次提交
  4. 14 10月, 2016 4 次提交
  5. 13 10月, 2016 18 次提交
  6. 12 10月, 2016 1 次提交