Merge tag 'pci-v6.6-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 31 Aug 2023 03:23:07 +0000 (20:23 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 31 Aug 2023 03:23:07 +0000 (20:23 -0700)
Pull PCI updates from Bjorn Helgaas:
 "Enumeration:
   - Add locking to read/modify/write PCIe Capability Register accessors
     for Link Control and Root Control
   - Use pci_dev_id() when possible instead of manually composing ID
     from dev->bus->number and dev->devfn

  Resource management:
   - Move prototypes for __weak sysfs resource files to linux/pci.h to
     fix 'no previous prototype' warnings
   - Make more I/O port accesses depend on HAS_IOPORT
   - Use devm_platform_get_and_ioremap_resource() instead of open-coding
     platform_get_resource() followed by devm_ioremap_resource()

  Power management:
   - Ensure devices are powered up while accessing VPD
   - If device is powered-up, keep it that way while polling for PME
   - Only read PCI_PM_CTRL register when available, to avoid reading the
     wrong register and corrupting dev->current_state

  Virtualization:
   - Avoid Secondary Bus Reset on NVIDIA T4 GPUs

  Error handling:
   - Remove unused pci_disable_pcie_error_reporting()
   - Unexport pci_enable_pcie_error_reporting(), used only by aer.c
   - Unexport pcie_port_bus_type, used only by PCI core

  VGA:
   - Simplify and clean up typos in VGA arbiter

  Apple PCIe controller driver:
   - Initialize pcie->nvecs (number of available MSIs) before use

  Broadcom iProc PCIe controller driver:
   - Use of_property_read_bool() instead of low-level accessors for
     boolean properties

  Broadcom STB PCIe controller driver:
   - Assert PERST# when probing BCM2711 because some bootloaders don't
     do it

  Freescale i.MX6 PCIe controller driver:
   - Add .host_deinit() callback so we can clean up things like
     regulators on probe failure or driver unload

  Freescale Layerscape PCIe controller driver:
   - Add support for link-down notification so the endpoint driver can
     process LINK_DOWN events
   - Add suspend/resume support, including manual
     PME_Turn_off/PME_TO_Ack handshake
   - Save Link Capabilities during probe so they can be restored when
     handling a link-up event, since the controller loses the Link Width
     and Link Speed values during reset

  Intel VMD host bridge driver:
   - Fix disable of bridge windows during domain reset; previously we
     cleared the base/limit registers, which actually left the windows
     enabled

  Marvell MVEBU PCIe controller driver:
   - Remove unused busn member

  Microchip PolarFlare PCIe controller driver:
   - Fix interrupt bit definitions so the SEC and DED interrupt handlers
     work correctly
   - Make driver buildable as a module
   - Read FPGA MSI configuration parameters from hardware instead of
     hard-coding them

  Microsoft Hyper-V host bridge driver:
   - To avoid a NULL pointer dereference, skip MSI restore after
     hibernate if MSI/MSI-X hasn't been enabled

  NVIDIA Tegra194 PCIe controller driver:
   - Revert 'PCI: tegra194: Enable support for 256 Byte payload' because
     Linux doesn't know how to reduce MPS from to 256 to 128 bytes for
     endpoints below a switch (because other devices below the switch
     might already be operating), which leads to 'Malformed TLP' errors

  Qualcomm PCIe controller driver:
   - Add DT and driver support for interconnect bandwidth voting for
     'pcie-mem' and 'cpu-pcie' interconnects
   - Fix broken SDX65 'compatible' DT property
   - Configure controller so MHI bus master clock will be switched off
     while in ASPM L1.x states
   - Use alignment restriction from EPF core in EPF MHI driver
   - Add Endpoint eDMA support
   - Add MHI eDMA support
   - Add Snapdragon SM8450 support to the EPF MHI driversupport
   - Add MHI eDMA support
   - Add Snapdragon SM8450 support to the EPF MHI driversupport
   - Add MHI eDMA support
   - Add Snapdragon SM8450 support to the EPF MHI driversupport
   - Add MHI eDMA support
   - Add Snapdragon SM8450 support to the EPF MHI driver
   - Use iATU for EPF MHI transfers smaller than 4K to avoid eDMA setup
     latency
   - Add sa8775p DT binding and driver support

  Rockchip PCIe controller driver:
   - Use 64-bit mask on MSI 64-bit PCI address to avoid zeroing out the
     upper 32 bits

  SiFive FU740 PCIe controller driver:
   - Set the supported number of MSI vectors so we can use all available
     MSI interrupts

  Synopsys DesignWare PCIe controller driver:
   - Add generic dwc suspend/resume APIs (dw_pcie_suspend_noirq() and
     dw_pcie_resume_noirq()) to be called by controller driver
     suspend/resume ops, and a controller callback to send PME_Turn_Off

  MicroSemi Switchtec management driver:
   - Add support for PCIe Gen5 devices

  Miscellaneous:
   - Reorder and compress to reduce size of struct pci_dev
   - Fix race in DOE destroy_work_on_stack()
   - Add stubs to avoid casts between incompatible function types
   - Explicitly include correct DT includes to untangle headers"

* tag 'pci-v6.6-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci: (96 commits)
  PCI: qcom-ep: Add ICC bandwidth voting support
  dt-bindings: PCI: qcom: ep: Add interconnects path
  PCI: qcom-ep: Treat unknown IRQ events as an error
  dt-bindings: PCI: qcom: Fix SDX65 compatible
  PCI: endpoint: Add kernel-doc for pci_epc_mem_init() API
  PCI: epf-mhi: Use iATU for small transfers
  PCI: epf-mhi: Add support for SM8450
  PCI: epf-mhi: Add eDMA support
  PCI: qcom-ep: Add eDMA support
  PCI: epf-mhi: Make use of the alignment restriction from EPF core
  PCI/PM: Only read PCI_PM_CTRL register when available
  PCI: qcom: Add support for sa8775p SoC
  dt-bindings: PCI: qcom: Add sa8775p compatible
  PCI: qcom-ep: Pass alignment restriction to the EPF core
  PCI: Simplify pcie_capability_clear_and_set_word() control flow
  PCI: Tidy config space save/restore messages
  PCI: Fix code formatting inconsistencies
  PCI: Fix typos in docs and comments
  PCI: Fix pci_bus_resetable(), pci_slot_resetable() name typos
  PCI: Simplify pci_dev_driver()
  ...

12 files changed:
1  2 
drivers/gpu/drm/radeon/cik.c
drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
drivers/net/wireless/ath/ath10k/pci.c
drivers/net/wireless/ath/ath11k/pci.c
drivers/net/wireless/ath/ath12k/pci.c
drivers/pci/controller/Kconfig
drivers/pci/controller/dwc/pcie-designware-host.c
drivers/pci/controller/dwc/pcie-designware.c
drivers/pci/controller/dwc/pcie-designware.h
drivers/pci/pci.h
drivers/pci/quirks.c
include/linux/pci.h

@@@ -3603,7 -3603,7 +3603,7 @@@ void cik_fence_compute_ring_emit(struc
   * @rdev: radeon_device pointer
   * @ring: radeon ring buffer object
   * @semaphore: radeon semaphore object
 - * @emit_wait: Is this a sempahore wait?
 + * @emit_wait: Is this a semaphore wait?
   *
   * Emits a semaphore signal/wait packet to the CP ring and prevents the PFP
   * from running ahead of semaphore waits.
@@@ -9534,17 -9534,8 +9534,8 @@@ static void cik_pcie_gen3_enable(struc
                        u16 bridge_cfg2, gpu_cfg2;
                        u32 max_lw, current_lw, tmp;
  
-                       pcie_capability_read_word(root, PCI_EXP_LNKCTL,
-                                                 &bridge_cfg);
-                       pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL,
-                                                 &gpu_cfg);
-                       tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
-                       pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16);
-                       tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
-                       pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL,
-                                                  tmp16);
+                       pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
+                       pcie_capability_set_word(rdev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
  
                        tmp = RREG32_PCIE_PORT(PCIE_LC_STATUS1);
                        max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
                                msleep(100);
  
                                /* linkctl */
-                               pcie_capability_read_word(root, PCI_EXP_LNKCTL,
-                                                         &tmp16);
-                               tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
-                               tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
-                               pcie_capability_write_word(root, PCI_EXP_LNKCTL,
-                                                          tmp16);
-                               pcie_capability_read_word(rdev->pdev,
-                                                         PCI_EXP_LNKCTL,
-                                                         &tmp16);
-                               tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
-                               tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
-                               pcie_capability_write_word(rdev->pdev,
-                                                          PCI_EXP_LNKCTL,
-                                                          tmp16);
+                               pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL,
+                                                                  PCI_EXP_LNKCTL_HAWD,
+                                                                  bridge_cfg &
+                                                                  PCI_EXP_LNKCTL_HAWD);
+                               pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL,
+                                                                  PCI_EXP_LNKCTL_HAWD,
+                                                                  gpu_cfg &
+                                                                  PCI_EXP_LNKCTL_HAWD);
  
                                /* linkctl2 */
                                pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
@@@ -127,23 -127,17 +127,23 @@@ static int mlx5_fw_reset_get_reset_stat
        if (mlx5_reg_mfrl_query(dev, NULL, NULL, &reset_state))
                goto out;
  
 +      if (!reset_state)
 +              return 0;
 +
        switch (reset_state) {
        case MLX5_MFRL_REG_RESET_STATE_IN_NEGOTIATION:
        case MLX5_MFRL_REG_RESET_STATE_RESET_IN_PROGRESS:
 -              NL_SET_ERR_MSG_MOD(extack, "Sync reset was already triggered");
 +              NL_SET_ERR_MSG_MOD(extack, "Sync reset still in progress");
                return -EBUSY;
 -      case MLX5_MFRL_REG_RESET_STATE_TIMEOUT:
 -              NL_SET_ERR_MSG_MOD(extack, "Sync reset got timeout");
 +      case MLX5_MFRL_REG_RESET_STATE_NEG_TIMEOUT:
 +              NL_SET_ERR_MSG_MOD(extack, "Sync reset negotiation timeout");
                return -ETIMEDOUT;
        case MLX5_MFRL_REG_RESET_STATE_NACK:
                NL_SET_ERR_MSG_MOD(extack, "One of the hosts disabled reset");
                return -EPERM;
 +      case MLX5_MFRL_REG_RESET_STATE_UNLOAD_TIMEOUT:
 +              NL_SET_ERR_MSG_MOD(extack, "Sync reset unload timeout");
 +              return -ETIMEDOUT;
        }
  
  out:
@@@ -157,7 -151,7 +157,7 @@@ int mlx5_fw_reset_set_reset_sync(struc
        struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
        u32 out[MLX5_ST_SZ_DW(mfrl_reg)] = {};
        u32 in[MLX5_ST_SZ_DW(mfrl_reg)] = {};
 -      int err;
 +      int err, rst_res;
  
        set_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags);
  
                return 0;
  
        clear_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags);
 -      if (err == -EREMOTEIO && MLX5_CAP_MCAM_FEATURE(dev, reset_state))
 -              return mlx5_fw_reset_get_reset_state_err(dev, extack);
 +      if (err == -EREMOTEIO && MLX5_CAP_MCAM_FEATURE(dev, reset_state)) {
 +              rst_res = mlx5_fw_reset_get_reset_state_err(dev, extack);
 +              return rst_res ? rst_res : err;
 +      }
  
        NL_SET_ERR_MSG_MOD(extack, "Sync reset command failed");
        return mlx5_cmd_check(dev, err, in, out);
  }
  
 +int mlx5_fw_reset_verify_fw_complete(struct mlx5_core_dev *dev,
 +                                   struct netlink_ext_ack *extack)
 +{
 +      u8 rst_state;
 +      int err;
 +
 +      err = mlx5_fw_reset_get_reset_state_err(dev, extack);
 +      if (err)
 +              return err;
 +
 +      rst_state = mlx5_get_fw_rst_state(dev);
 +      if (!rst_state)
 +              return 0;
 +
 +      mlx5_core_err(dev, "Sync reset did not complete, state=%d\n", rst_state);
 +      NL_SET_ERR_MSG_MOD(extack, "Sync reset did not complete successfully");
 +      return rst_state;
 +}
 +
  int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev)
  {
        return mlx5_reg_mfrl_set(dev, MLX5_MFRL_REG_RESET_LEVEL0, 0, 0, false);
@@@ -338,7 -311,7 +338,7 @@@ static int mlx5_check_dev_ids(struct ml
        list_for_each_entry(sdev, &bridge_bus->devices, bus_list) {
                err = pci_read_config_word(sdev, PCI_DEVICE_ID, &sdev_id);
                if (err)
-                       return err;
+                       return pcibios_err_to_errno(err);
                if (sdev_id != dev_id) {
                        mlx5_core_warn(dev, "unrecognized dev_id (0x%x)\n", sdev_id);
                        return -EPERM;
@@@ -398,7 -371,7 +398,7 @@@ static int mlx5_pci_link_toggle(struct 
  
        err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &dev_id);
        if (err)
-               return err;
+               return pcibios_err_to_errno(err);
        err = mlx5_check_dev_ids(dev, dev_id);
        if (err)
                return err;
                pci_cfg_access_lock(sdev);
        }
        /* PCI link toggle */
-       err = pci_read_config_word(bridge, cap + PCI_EXP_LNKCTL, &reg16);
-       if (err)
-               return err;
-       reg16 |= PCI_EXP_LNKCTL_LD;
-       err = pci_write_config_word(bridge, cap + PCI_EXP_LNKCTL, reg16);
+       err = pcie_capability_set_word(bridge, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_LD);
        if (err)
-               return err;
+               return pcibios_err_to_errno(err);
        msleep(500);
-       reg16 &= ~PCI_EXP_LNKCTL_LD;
-       err = pci_write_config_word(bridge, cap + PCI_EXP_LNKCTL, reg16);
+       err = pcie_capability_clear_word(bridge, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_LD);
        if (err)
-               return err;
+               return pcibios_err_to_errno(err);
  
        /* Check link */
        if (!bridge->link_active_reporting) {
        do {
                err = pci_read_config_word(bridge, cap + PCI_EXP_LNKSTA, &reg16);
                if (err)
-                       return err;
+                       return pcibios_err_to_errno(err);
                if (reg16 & PCI_EXP_LNKSTA_DLLLA)
                        break;
                msleep(20);
        do {
                err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &reg16);
                if (err)
-                       return err;
+                       return pcibios_err_to_errno(err);
                if (reg16 == dev_id)
                        break;
                msleep(20);
@@@ -1636,7 -1636,7 +1636,7 @@@ static int ath10k_pci_dump_memory_gener
                                                      buf,
                                                      current_region->len);
  
 -      /* No individiual memory sections defined so we can
 +      /* No individual memory sections defined so we can
         * copy the entire memory region.
         */
        ret = ath10k_pci_diag_read_mem(ar,
@@@ -1963,8 -1963,9 +1963,9 @@@ static int ath10k_pci_hif_start(struct 
        ath10k_pci_irq_enable(ar);
        ath10k_pci_rx_post(ar);
  
-       pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL,
-                                  ar_pci->link_ctl);
+       pcie_capability_clear_and_set_word(ar_pci->pdev, PCI_EXP_LNKCTL,
+                                          PCI_EXP_LNKCTL_ASPMC,
+                                          ar_pci->link_ctl & PCI_EXP_LNKCTL_ASPMC);
  
        return 0;
  }
@@@ -2821,8 -2822,8 +2822,8 @@@ static int ath10k_pci_hif_power_up(stru
  
        pcie_capability_read_word(ar_pci->pdev, PCI_EXP_LNKCTL,
                                  &ar_pci->link_ctl);
-       pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL,
-                                  ar_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC);
+       pcie_capability_clear_word(ar_pci->pdev, PCI_EXP_LNKCTL,
+                                  PCI_EXP_LNKCTL_ASPMC);
  
        /*
         * Bring the target up cleanly.
@@@ -3816,7 -3817,7 +3817,7 @@@ static void __exit ath10k_pci_exit(void
  module_exit(ath10k_pci_exit);
  
  MODULE_AUTHOR("Qualcomm Atheros");
 -MODULE_DESCRIPTION("Driver support for Qualcomm Atheros 802.11ac WLAN PCIe/AHB devices");
 +MODULE_DESCRIPTION("Driver support for Qualcomm Atheros PCIe/AHB 802.11ac WLAN devices");
  MODULE_LICENSE("Dual BSD/GPL");
  
  /* QCA988x 2.0 firmware files */
@@@ -15,7 -15,6 +15,7 @@@
  #include "mhi.h"
  #include "debug.h"
  #include "pcic.h"
 +#include "qmi.h"
  
  #define ATH11K_PCI_BAR_NUM            0
  #define ATH11K_PCI_DMA_MASK           32
@@@ -582,8 -581,8 +582,8 @@@ static void ath11k_pci_aspm_disable(str
                   u16_get_bits(ab_pci->link_ctl, PCI_EXP_LNKCTL_ASPM_L1));
  
        /* disable L0s and L1 */
-       pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL,
-                                  ab_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC);
+       pcie_capability_clear_word(ab_pci->pdev, PCI_EXP_LNKCTL,
+                                  PCI_EXP_LNKCTL_ASPMC);
  
        set_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags);
  }
  static void ath11k_pci_aspm_restore(struct ath11k_pci *ab_pci)
  {
        if (test_and_clear_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags))
-               pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL,
-                                          ab_pci->link_ctl);
+               pcie_capability_clear_and_set_word(ab_pci->pdev, PCI_EXP_LNKCTL,
+                                                  PCI_EXP_LNKCTL_ASPMC,
+                                                  ab_pci->link_ctl &
+                                                  PCI_EXP_LNKCTL_ASPMC);
  }
  
  static int ath11k_pci_power_up(struct ath11k_base *ab)
@@@ -898,7 -899,6 +900,7 @@@ unsupported_wcn6855_soc
                ath11k_err(ab, "failed to init core: %d\n", ret);
                goto err_irq_affinity_cleanup;
        }
 +      ath11k_qmi_fwreset_from_cold_boot(ab);
        return 0;
  
  err_irq_affinity_cleanup:
@@@ -1036,7 -1036,7 +1038,7 @@@ static void ath11k_pci_exit(void
  
  module_exit(ath11k_pci_exit);
  
 -MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11ax WLAN PCIe devices");
 +MODULE_DESCRIPTION("Driver support for Qualcomm Technologies PCIe 802.11ax WLAN devices");
  MODULE_LICENSE("Dual BSD/GPL");
  
  /* firmware files */
@@@ -794,8 -794,8 +794,8 @@@ static void ath12k_pci_aspm_disable(str
                   u16_get_bits(ab_pci->link_ctl, PCI_EXP_LNKCTL_ASPM_L1));
  
        /* disable L0s and L1 */
-       pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL,
-                                  ab_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC);
+       pcie_capability_clear_word(ab_pci->pdev, PCI_EXP_LNKCTL,
+                                  PCI_EXP_LNKCTL_ASPMC);
  
        set_bit(ATH12K_PCI_ASPM_RESTORE, &ab_pci->flags);
  }
  static void ath12k_pci_aspm_restore(struct ath12k_pci *ab_pci)
  {
        if (test_and_clear_bit(ATH12K_PCI_ASPM_RESTORE, &ab_pci->flags))
-               pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL,
-                                          ab_pci->link_ctl);
+               pcie_capability_clear_and_set_word(ab_pci->pdev, PCI_EXP_LNKCTL,
+                                                  PCI_EXP_LNKCTL_ASPMC,
+                                                  ab_pci->link_ctl &
+                                                  PCI_EXP_LNKCTL_ASPMC);
  }
  
  static void ath12k_pci_kill_tasklets(struct ath12k_base *ab)
@@@ -1409,5 -1411,5 +1411,5 @@@ static void ath12k_pci_exit(void
  
  module_exit(ath12k_pci_exit);
  
 -MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11be WLAN PCIe devices");
 +MODULE_DESCRIPTION("Driver support for Qualcomm Technologies PCIe 802.11be WLAN devices");
  MODULE_LICENSE("Dual BSD/GPL");
@@@ -179,6 -179,7 +179,6 @@@ config PCI_MVEB
        depends on MVEBU_MBUS
        depends on ARM
        depends on OF
 -      depends on BROKEN
        select PCI_BRIDGE_EMUL
        help
         Add support for Marvell EBU PCIe controller. This PCIe controller
@@@ -216,7 -217,7 +216,7 @@@ config PCIE_MT762
          This selects a driver for the MediaTek MT7621 PCIe Controller.
  
  config PCIE_MICROCHIP_HOST
-       bool "Microchip AXI PCIe controller"
+       tristate "Microchip AXI PCIe controller"
        depends on PCI_MSI && OF
        select PCI_HOST_COMMON
        help
@@@ -8,6 -8,7 +8,7 @@@
   * Author: Jingoo Han <jg1.han@samsung.com>
   */
  
+ #include <linux/iopoll.h>
  #include <linux/irqchip/chained_irq.h>
  #include <linux/irqdomain.h>
  #include <linux/msi.h>
@@@ -16,6 -17,7 +17,7 @@@
  #include <linux/pci_regs.h>
  #include <linux/platform_device.h>
  
+ #include "../../pci.h"
  #include "pcie-designware.h"
  
  static struct pci_ops dw_pcie_ops;
@@@ -485,15 -487,20 +487,15 @@@ int dw_pcie_host_init(struct dw_pcie_r
        if (ret)
                goto err_remove_edma;
  
 -      if (dw_pcie_link_up(pci)) {
 -              dw_pcie_print_link_status(pci);
 -      } else {
 +      if (!dw_pcie_link_up(pci)) {
                ret = dw_pcie_start_link(pci);
                if (ret)
                        goto err_remove_edma;
 -
 -              if (pci->ops && pci->ops->start_link) {
 -                      ret = dw_pcie_wait_for_link(pci);
 -                      if (ret)
 -                              goto err_stop_link;
 -              }
        }
  
 +      /* Ignore errors, the link may come up later */
 +      dw_pcie_wait_for_link(pci);
 +
        bridge->sysdata = pp;
  
        ret = pci_host_probe(bridge);
@@@ -807,3 -814,72 +809,72 @@@ int dw_pcie_setup_rc(struct dw_pcie_rp 
        return 0;
  }
  EXPORT_SYMBOL_GPL(dw_pcie_setup_rc);
+ int dw_pcie_suspend_noirq(struct dw_pcie *pci)
+ {
+       u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+       u32 val;
+       int ret;
+       /*
+        * If L1SS is supported, then do not put the link into L2 as some
+        * devices such as NVMe expect low resume latency.
+        */
+       if (dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKCTL) & PCI_EXP_LNKCTL_ASPM_L1)
+               return 0;
+       if (dw_pcie_get_ltssm(pci) <= DW_PCIE_LTSSM_DETECT_ACT)
+               return 0;
+       if (!pci->pp.ops->pme_turn_off)
+               return 0;
+       pci->pp.ops->pme_turn_off(&pci->pp);
+       ret = read_poll_timeout(dw_pcie_get_ltssm, val, val == DW_PCIE_LTSSM_L2_IDLE,
+                               PCIE_PME_TO_L2_TIMEOUT_US/10,
+                               PCIE_PME_TO_L2_TIMEOUT_US, false, pci);
+       if (ret) {
+               dev_err(pci->dev, "Timeout waiting for L2 entry! LTSSM: 0x%x\n", val);
+               return ret;
+       }
+       if (pci->pp.ops->host_deinit)
+               pci->pp.ops->host_deinit(&pci->pp);
+       pci->suspended = true;
+       return ret;
+ }
+ EXPORT_SYMBOL_GPL(dw_pcie_suspend_noirq);
+ int dw_pcie_resume_noirq(struct dw_pcie *pci)
+ {
+       int ret;
+       if (!pci->suspended)
+               return 0;
+       pci->suspended = false;
+       if (pci->pp.ops->host_init) {
+               ret = pci->pp.ops->host_init(&pci->pp);
+               if (ret) {
+                       dev_err(pci->dev, "Host init failed: %d\n", ret);
+                       return ret;
+               }
+       }
+       dw_pcie_setup_rc(&pci->pp);
+       ret = dw_pcie_start_link(pci);
+       if (ret)
+               return ret;
+       ret = dw_pcie_wait_for_link(pci);
+       if (ret)
+               return ret;
+       return ret;
+ }
+ EXPORT_SYMBOL_GPL(dw_pcie_resume_noirq);
@@@ -16,7 -16,7 +16,7 @@@
  #include <linux/gpio/consumer.h>
  #include <linux/ioport.h>
  #include <linux/of.h>
- #include <linux/of_platform.h>
+ #include <linux/platform_device.h>
  #include <linux/sizes.h>
  #include <linux/types.h>
  
@@@ -644,9 -644,20 +644,9 @@@ void dw_pcie_disable_atu(struct dw_pci
        dw_pcie_writel_atu(pci, dir, index, PCIE_ATU_REGION_CTRL2, 0);
  }
  
 -void dw_pcie_print_link_status(struct dw_pcie *pci)
 -{
 -      u32 offset, val;
 -
 -      offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
 -      val = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA);
 -
 -      dev_info(pci->dev, "PCIe Gen.%u x%u link up\n",
 -               FIELD_GET(PCI_EXP_LNKSTA_CLS, val),
 -               FIELD_GET(PCI_EXP_LNKSTA_NLW, val));
 -}
 -
  int dw_pcie_wait_for_link(struct dw_pcie *pci)
  {
 +      u32 offset, val;
        int retries;
  
        /* Check if the link is up or not */
                return -ETIMEDOUT;
        }
  
 -      dw_pcie_print_link_status(pci);
 +      offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
 +      val = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA);
 +
 +      dev_info(pci->dev, "PCIe Gen.%u x%u link up\n",
 +               FIELD_GET(PCI_EXP_LNKSTA_CLS, val),
 +               FIELD_GET(PCI_EXP_LNKSTA_NLW, val));
  
        return 0;
  }
@@@ -288,10 -288,21 +288,21 @@@ enum dw_pcie_core_rst 
        DW_PCIE_NUM_CORE_RSTS
  };
  
+ enum dw_pcie_ltssm {
+       /* Need to align with PCIE_PORT_DEBUG0 bits 0:5 */
+       DW_PCIE_LTSSM_DETECT_QUIET = 0x0,
+       DW_PCIE_LTSSM_DETECT_ACT = 0x1,
+       DW_PCIE_LTSSM_L0 = 0x11,
+       DW_PCIE_LTSSM_L2_IDLE = 0x15,
+       DW_PCIE_LTSSM_UNKNOWN = 0xFFFFFFFF,
+ };
  struct dw_pcie_host_ops {
        int (*host_init)(struct dw_pcie_rp *pp);
        void (*host_deinit)(struct dw_pcie_rp *pp);
        int (*msi_host_init)(struct dw_pcie_rp *pp);
+       void (*pme_turn_off)(struct dw_pcie_rp *pp);
  };
  
  struct dw_pcie_rp {
@@@ -364,6 -375,7 +375,7 @@@ struct dw_pcie_ops 
        void    (*write_dbi2)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
                              size_t size, u32 val);
        int     (*link_up)(struct dw_pcie *pcie);
+       enum dw_pcie_ltssm (*get_ltssm)(struct dw_pcie *pcie);
        int     (*start_link)(struct dw_pcie *pcie);
        void    (*stop_link)(struct dw_pcie *pcie);
  };
@@@ -393,6 -405,7 +405,7 @@@ struct dw_pcie 
        struct reset_control_bulk_data  app_rsts[DW_PCIE_NUM_APP_RSTS];
        struct reset_control_bulk_data  core_rsts[DW_PCIE_NUM_CORE_RSTS];
        struct gpio_desc                *pe_rst;
+       bool                    suspended;
  };
  
  #define to_dw_pcie_from_pp(port) container_of((port), struct dw_pcie, pp)
@@@ -429,7 -442,11 +442,10 @@@ void dw_pcie_setup(struct dw_pcie *pci)
  void dw_pcie_iatu_detect(struct dw_pcie *pci);
  int dw_pcie_edma_detect(struct dw_pcie *pci);
  void dw_pcie_edma_remove(struct dw_pcie *pci);
 -void dw_pcie_print_link_status(struct dw_pcie *pci);
  
+ int dw_pcie_suspend_noirq(struct dw_pcie *pci);
+ int dw_pcie_resume_noirq(struct dw_pcie *pci);
  static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val)
  {
        dw_pcie_write_dbi(pci, reg, 0x4, val);
@@@ -501,6 -518,18 +517,18 @@@ static inline void dw_pcie_stop_link(st
                pci->ops->stop_link(pci);
  }
  
+ static inline enum dw_pcie_ltssm dw_pcie_get_ltssm(struct dw_pcie *pci)
+ {
+       u32 val;
+       if (pci->ops && pci->ops->get_ltssm)
+               return pci->ops->get_ltssm(pci);
+       val = dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG0);
+       return (enum dw_pcie_ltssm)FIELD_GET(PORT_LOGIC_LTSSM_STATE_MASK, val);
+ }
  #ifdef CONFIG_PCIE_DW_HOST
  irqreturn_t dw_handle_msi_irq(struct dw_pcie_rp *pp);
  int dw_pcie_setup_rc(struct dw_pcie_rp *pp);
diff --combined drivers/pci/pci.h
  
  #define PCIE_LINK_RETRAIN_TIMEOUT_MS  1000
  
+ /*
+  * PCIe r6.0, sec 5.3.3.2.1 <PME Synchronization>
+  * Recommends 1ms to 10ms timeout to check L2 ready.
+  */
+ #define PCIE_PME_TO_L2_TIMEOUT_US     10000
  extern const unsigned char pcie_link_speed[];
  extern bool pci_early_dump;
  
@@@ -147,8 -153,8 +153,8 @@@ int pci_hp_add_bridge(struct pci_dev *d
  void pci_create_legacy_files(struct pci_bus *bus);
  void pci_remove_legacy_files(struct pci_bus *bus);
  #else
- static inline void pci_create_legacy_files(struct pci_bus *bus) { return; }
- static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; }
+ static inline void pci_create_legacy_files(struct pci_bus *bus) { }
+ static inline void pci_remove_legacy_files(struct pci_bus *bus) { }
  #endif
  
  /* Lock for read/write access to pci device and bus lists */
@@@ -422,9 -428,9 +428,9 @@@ void dpc_process_error(struct pci_dev *
  pci_ers_result_t dpc_reset_link(struct pci_dev *pdev);
  bool pci_dpc_recovered(struct pci_dev *pdev);
  #else
- static inline void pci_save_dpc_state(struct pci_dev *dev) {}
- static inline void pci_restore_dpc_state(struct pci_dev *dev) {}
- static inline void pci_dpc_init(struct pci_dev *pdev) {}
+ static inline void pci_save_dpc_state(struct pci_dev *dev) { }
+ static inline void pci_restore_dpc_state(struct pci_dev *dev) { }
+ static inline void pci_dpc_init(struct pci_dev *pdev) { }
  static inline bool pci_dpc_recovered(struct pci_dev *pdev) { return false; }
  #endif
  
@@@ -436,12 -442,12 +442,12 @@@ void pcie_walk_rcec(struct pci_dev *rce
                    int (*cb)(struct pci_dev *, void *),
                    void *userdata);
  #else
- static inline void pci_rcec_init(struct pci_dev *dev) {}
- static inline void pci_rcec_exit(struct pci_dev *dev) {}
- static inline void pcie_link_rcec(struct pci_dev *rcec) {}
+ static inline void pci_rcec_init(struct pci_dev *dev) { }
+ static inline void pci_rcec_exit(struct pci_dev *dev) { }
+ static inline void pcie_link_rcec(struct pci_dev *rcec) { }
  static inline void pcie_walk_rcec(struct pci_dev *rcec,
                                  int (*cb)(struct pci_dev *, void *),
-                                 void *userdata) {}
+                                 void *userdata) { }
  #endif
  
  #ifdef CONFIG_PCI_ATS
@@@ -484,16 -490,9 +490,9 @@@ static inline int pci_iov_init(struct p
  {
        return -ENODEV;
  }
- static inline void pci_iov_release(struct pci_dev *dev)
- {
- }
- static inline void pci_iov_remove(struct pci_dev *dev)
- {
- }
- static inline void pci_restore_iov_state(struct pci_dev *dev)
- {
- }
+ static inline void pci_iov_release(struct pci_dev *dev) { }
+ static inline void pci_iov_remove(struct pci_dev *dev) { }
+ static inline void pci_restore_iov_state(struct pci_dev *dev) { }
  static inline int pci_iov_bus_range(struct pci_bus *bus)
  {
        return 0;
@@@ -679,18 -678,6 +678,18 @@@ static inline int devm_of_pci_bridge_in
  
  #endif /* CONFIG_OF */
  
 +struct of_changeset;
 +
 +#ifdef CONFIG_PCI_DYNAMIC_OF_NODES
 +void of_pci_make_dev_node(struct pci_dev *pdev);
 +void of_pci_remove_node(struct pci_dev *pdev);
 +int of_pci_add_properties(struct pci_dev *pdev, struct of_changeset *ocs,
 +                        struct device_node *np);
 +#else
 +static inline void of_pci_make_dev_node(struct pci_dev *pdev) { }
 +static inline void of_pci_remove_node(struct pci_dev *pdev) { }
 +#endif
 +
  #ifdef CONFIG_PCIEAER
  void pci_no_aer(void);
  void pci_aer_init(struct pci_dev *dev);
@@@ -730,7 -717,7 +729,7 @@@ static inline int pci_dev_acpi_reset(st
  {
        return -ENOTTY;
  }
- static inline void pci_set_acpi_fwnode(struct pci_dev *dev) {}
+ static inline void pci_set_acpi_fwnode(struct pci_dev *dev) { }
  static inline int pci_acpi_program_hp_params(struct pci_dev *dev)
  {
        return -ENODEV;
@@@ -751,7 -738,7 +750,7 @@@ static inline pci_power_t acpi_pci_get_
  {
        return PCI_UNKNOWN;
  }
- static inline void acpi_pci_refresh_power_state(struct pci_dev *dev) {}
+ static inline void acpi_pci_refresh_power_state(struct pci_dev *dev) { }
  static inline int acpi_pci_wakeup(struct pci_dev *dev, bool enable)
  {
        return -ENODEV;
diff --combined drivers/pci/quirks.c
@@@ -361,8 -361,9 +361,9 @@@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_N
  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC,    PCI_DEVICE_ID_NEC_CBUS_3,       quirk_isa_dma_hangs);
  #endif
  
+ #ifdef CONFIG_HAS_IOPORT
  /*
-  * Intel NM10 "TigerPoint" LPC PM1a_STS.BM_STS must be clear
+  * Intel NM10 "Tiger Point" LPC PM1a_STS.BM_STS must be clear
   * for some HT machines to use C4 w/o hanging.
   */
  static void quirk_tigerpoint_bm_sts(struct pci_dev *dev)
        pm1a = inw(pmbase);
  
        if (pm1a & 0x10) {
-               pci_info(dev, FW_BUG "TigerPoint LPC.BM_STS cleared\n");
+               pci_info(dev, FW_BUG "Tiger Point LPC.BM_STS cleared\n");
                outw(0x10, pmbase);
        }
  }
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGP_LPC, quirk_tigerpoint_bm_sts);
+ #endif
  
  /* Chipsets where PCI->PCI transfers vanish or hang */
  static void quirk_nopcipci(struct pci_dev *dev)
@@@ -3073,7 -3075,7 +3075,7 @@@ static void __nv_msi_ht_cap_quirk(struc
  
        /*
         * HT MSI mapping should be disabled on devices that are below
-        * a non-Hypertransport host bridge. Locate the host bridge...
+        * a non-HyperTransport host bridge. Locate the host bridge.
         */
        host_bridge = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus), 0,
                                                  PCI_DEVFN(0, 0));
@@@ -3724,7 -3726,7 +3726,7 @@@ static void quirk_no_bus_reset(struct p
   */
  static void quirk_nvidia_no_bus_reset(struct pci_dev *dev)
  {
-       if ((dev->device & 0xffc0) == 0x2340)
+       if ((dev->device & 0xffc0) == 0x2340 || dev->device == 0x1eb8)
                quirk_no_bus_reset(dev);
  }
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
@@@ -5729,7 -5731,7 +5731,7 @@@ int pci_idt_bus_quirk(struct pci_bus *b
  /*
   * Microsemi Switchtec NTB uses devfn proxy IDs to move TLPs between
   * NT endpoints via the internal switch fabric. These IDs replace the
-  * originating requestor ID TLPs which access host memory on peer NTB
+  * originating Requester ID TLPs which access host memory on peer NTB
   * ports. Therefore, all proxy IDs must be aliased to the NTB device
   * to permit access when the IOMMU is turned on.
   */
@@@ -5867,6 -5869,42 +5869,42 @@@ SWITCHTEC_QUIRK(0x4428);  /* PSXA 28XG
  SWITCHTEC_QUIRK(0x4552);  /* PAXA 52XG4 */
  SWITCHTEC_QUIRK(0x4536);  /* PAXA 36XG4 */
  SWITCHTEC_QUIRK(0x4528);  /* PAXA 28XG4 */
+ SWITCHTEC_QUIRK(0x5000);  /* PFX 100XG5 */
+ SWITCHTEC_QUIRK(0x5084);  /* PFX 84XG5 */
+ SWITCHTEC_QUIRK(0x5068);  /* PFX 68XG5 */
+ SWITCHTEC_QUIRK(0x5052);  /* PFX 52XG5 */
+ SWITCHTEC_QUIRK(0x5036);  /* PFX 36XG5 */
+ SWITCHTEC_QUIRK(0x5028);  /* PFX 28XG5 */
+ SWITCHTEC_QUIRK(0x5100);  /* PSX 100XG5 */
+ SWITCHTEC_QUIRK(0x5184);  /* PSX 84XG5 */
+ SWITCHTEC_QUIRK(0x5168);  /* PSX 68XG5 */
+ SWITCHTEC_QUIRK(0x5152);  /* PSX 52XG5 */
+ SWITCHTEC_QUIRK(0x5136);  /* PSX 36XG5 */
+ SWITCHTEC_QUIRK(0x5128);  /* PSX 28XG5 */
+ SWITCHTEC_QUIRK(0x5200);  /* PAX 100XG5 */
+ SWITCHTEC_QUIRK(0x5284);  /* PAX 84XG5 */
+ SWITCHTEC_QUIRK(0x5268);  /* PAX 68XG5 */
+ SWITCHTEC_QUIRK(0x5252);  /* PAX 52XG5 */
+ SWITCHTEC_QUIRK(0x5236);  /* PAX 36XG5 */
+ SWITCHTEC_QUIRK(0x5228);  /* PAX 28XG5 */
+ SWITCHTEC_QUIRK(0x5300);  /* PFXA 100XG5 */
+ SWITCHTEC_QUIRK(0x5384);  /* PFXA 84XG5 */
+ SWITCHTEC_QUIRK(0x5368);  /* PFXA 68XG5 */
+ SWITCHTEC_QUIRK(0x5352);  /* PFXA 52XG5 */
+ SWITCHTEC_QUIRK(0x5336);  /* PFXA 36XG5 */
+ SWITCHTEC_QUIRK(0x5328);  /* PFXA 28XG5 */
+ SWITCHTEC_QUIRK(0x5400);  /* PSXA 100XG5 */
+ SWITCHTEC_QUIRK(0x5484);  /* PSXA 84XG5 */
+ SWITCHTEC_QUIRK(0x5468);  /* PSXA 68XG5 */
+ SWITCHTEC_QUIRK(0x5452);  /* PSXA 52XG5 */
+ SWITCHTEC_QUIRK(0x5436);  /* PSXA 36XG5 */
+ SWITCHTEC_QUIRK(0x5428);  /* PSXA 28XG5 */
+ SWITCHTEC_QUIRK(0x5500);  /* PAXA 100XG5 */
+ SWITCHTEC_QUIRK(0x5584);  /* PAXA 84XG5 */
+ SWITCHTEC_QUIRK(0x5568);  /* PAXA 68XG5 */
+ SWITCHTEC_QUIRK(0x5552);  /* PAXA 52XG5 */
+ SWITCHTEC_QUIRK(0x5536);  /* PAXA 36XG5 */
+ SWITCHTEC_QUIRK(0x5528);  /* PAXA 28XG5 */
  
  /*
   * The PLX NTB uses devfn proxy IDs to move TLPs between NT endpoints.
@@@ -6138,15 -6176,3 +6176,15 @@@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2f, dpc_log_size);
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a31, dpc_log_size);
  #endif
 +
 +/*
 + * For a PCI device with multiple downstream devices, its driver may use
 + * a flattened device tree to describe the downstream devices.
 + * To overlay the flattened device tree, the PCI device and all its ancestor
 + * devices need to have device tree nodes on system base device tree. Thus,
 + * before driver probing, it might need to add a device tree node as the final
 + * fixup.
 + */
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5020, of_pci_make_dev_node);
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5021, of_pci_make_dev_node);
 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REDHAT, 0x0005, of_pci_make_dev_node);
diff --combined include/linux/pci.h
@@@ -23,7 -23,7 +23,7 @@@
  #ifndef LINUX_PCI_H
  #define LINUX_PCI_H
  
 -
 +#include <linux/args.h>
  #include <linux/mod_devicetable.h>
  
  #include <linux/types.h>
@@@ -366,8 -366,8 +366,8 @@@ struct pci_dev 
        pci_power_t     current_state;  /* Current operating state. In ACPI,
                                           this is D0-D3, D0 being fully
                                           functional, and D3 being off. */
-       unsigned int    imm_ready:1;    /* Supports Immediate Readiness */
        u8              pm_cap;         /* PM capability offset */
+       unsigned int    imm_ready:1;    /* Supports Immediate Readiness */
        unsigned int    pme_support:5;  /* Bitmask of states from which PME#
                                           can be generated */
        unsigned int    pme_poll:1;     /* Poll device's PME status bit */
  
  #ifdef CONFIG_PCIEASPM
        struct pcie_link_state  *link_state;    /* ASPM link state */
+       u16             l1ss;           /* L1SS Capability pointer */
        unsigned int    ltr_path:1;     /* Latency Tolerance Reporting
                                           supported from root to here */
-       u16             l1ss;           /* L1SS Capability pointer */
  #endif
        unsigned int    pasid_no_tlp:1;         /* PASID works without TLP Prefix */
        unsigned int    eetlp_prefix_path:1;    /* End-to-End TLP Prefix */
        unsigned int    no_vf_scan:1;           /* Don't scan for VFs after IOV enablement */
        unsigned int    no_command_memory:1;    /* No PCI_COMMAND_MEMORY */
        unsigned int    rom_bar_overlap:1;      /* ROM BAR disable broken */
+       unsigned int    rom_attr_enabled:1;     /* Display of ROM attribute enabled? */
        pci_dev_flags_t dev_flags;
        atomic_t        enable_cnt;     /* pci_enable_device has been called */
  
+       spinlock_t      pcie_cap_lock;          /* Protects RMW ops in capability accessors */
        u32             saved_config_space[16]; /* Config space saved at suspend time */
        struct hlist_head saved_cap_space;
-       int             rom_attr_enabled;       /* Display of ROM attribute enabled? */
        struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
        struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
  
@@@ -1217,11 -1218,40 +1218,40 @@@ int pcie_capability_read_word(struct pc
  int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val);
  int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val);
  int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val);
- int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos,
-                                      u16 clear, u16 set);
+ int pcie_capability_clear_and_set_word_unlocked(struct pci_dev *dev, int pos,
+                                               u16 clear, u16 set);
+ int pcie_capability_clear_and_set_word_locked(struct pci_dev *dev, int pos,
+                                             u16 clear, u16 set);
  int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos,
                                        u32 clear, u32 set);
  
+ /**
+  * pcie_capability_clear_and_set_word - RMW accessor for PCI Express Capability Registers
+  * @dev:      PCI device structure of the PCI Express device
+  * @pos:      PCI Express Capability Register
+  * @clear:    Clear bitmask
+  * @set:      Set bitmask
+  *
+  * Perform a Read-Modify-Write (RMW) operation using @clear and @set
+  * bitmasks on PCI Express Capability Register at @pos. Certain PCI Express
+  * Capability Registers are accessed concurrently in RMW fashion, hence
+  * require locking which is handled transparently to the caller.
+  */
+ static inline int pcie_capability_clear_and_set_word(struct pci_dev *dev,
+                                                    int pos,
+                                                    u16 clear, u16 set)
+ {
+       switch (pos) {
+       case PCI_EXP_LNKCTL:
+       case PCI_EXP_RTCTL:
+               return pcie_capability_clear_and_set_word_locked(dev, pos,
+                                                                clear, set);
+       default:
+               return pcie_capability_clear_and_set_word_unlocked(dev, pos,
+                                                                  clear, set);
+       }
+ }
  static inline int pcie_capability_set_word(struct pci_dev *dev, int pos,
                                           u16 set)
  {
@@@ -1403,7 -1433,6 +1433,6 @@@ void pci_assign_unassigned_bridge_resou
  void pci_assign_unassigned_bus_resources(struct pci_bus *bus);
  void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus);
  int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type);
- void pdev_enable_device(struct pci_dev *);
  int pci_enable_resources(struct pci_dev *, int mask);
  void pci_assign_irq(struct pci_dev *dev);
  struct resource *pci_find_resource(struct pci_dev *dev, struct resource *res);
@@@ -2260,6 -2289,11 +2289,11 @@@ int pcibios_alloc_irq(struct pci_dev *d
  void pcibios_free_irq(struct pci_dev *dev);
  resource_size_t pcibios_default_alignment(void);
  
+ #if !defined(HAVE_PCI_MMAP) && !defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
+ extern int pci_create_resource_files(struct pci_dev *dev);
+ extern void pci_remove_resource_files(struct pci_dev *dev);
+ #endif
  #if defined(CONFIG_PCI_MMCONFIG) || defined(CONFIG_ACPI_MCFG)
  void __init pci_mmcfg_early_init(void);
  void __init pci_mmcfg_late_init(void);