Merge tag 'pci-v6.4-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 27 Apr 2023 17:45:30 +0000 (10:45 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 27 Apr 2023 17:45:30 +0000 (10:45 -0700)
Pull pci updates from Bjorn Helgaas:
 "Resource management:

   - Add pci_dev_for_each_resource() and pci_bus_for_each_resource()
     iterators

  PCIe native device hotplug:

   - Fix AB-BA deadlock between reset_lock and device_lock

  Power management:

   - Wait longer for devices to become ready after resume (as we do for
     reset) to accommodate Intel Titan Ridge xHCI devices

   - Extend D3hot delay for NVIDIA HDA controllers to avoid
     unrecoverable devices after a bus reset

  Error handling:

   - Clear PCIe Device Status after EDR since generic error recovery now
     only clears it when AER is native

  ASPM:

   - Work around Chromebook firmware defect that clobbers Capability
     list (including ASPM L1 PM Substates Cap) when returning from
     D3cold to D0

  Freescale i.MX6 PCIe controller driver:

   - Install imprecise external abort handler only when DT indicates
     PCIe support

  Freescale Layerscape PCIe controller driver:

   - Add ls1028a endpoint mode support

  Qualcomm PCIe controller driver:

   - Add SM8550 DT binding and driver support

   - Add SDX55 DT binding and driver support

   - Use bulk APIs for clocks of IP 1.0.0, 2.3.2, 2.3.3

   - Use bulk APIs for reset of IP 2.1.0, 2.3.3, 2.4.0

   - Add DT "mhi" register region for supported SoCs

   - Expose link transition counts via debugfs to help debug low power
     issues

   - Support system suspend and resume; reduce interconnect bandwidth
     and turn off clock and PHY if there are no active devices

   - Enable async probe by default to reduce boot time

  Miscellaneous:

   - Sort controller Kconfig entries by vendor"

* tag 'pci-v6.4-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci: (56 commits)
  PCI: xilinx: Drop obsolete dependency on COMPILE_TEST
  PCI: mobiveil: Sort Kconfig entries by vendor
  PCI: dwc: Sort Kconfig entries by vendor
  PCI: Sort controller Kconfig entries by vendor
  PCI: Use consistent controller Kconfig menu entry language
  PCI: xilinx-nwl: Add 'Xilinx' to Kconfig prompt
  PCI: hv: Add 'Microsoft' to Kconfig prompt
  PCI: meson: Add 'Amlogic' to Kconfig prompt
  PCI: Use of_property_present() for testing DT property presence
  PCI/PM: Extend D3hot delay for NVIDIA HDA controllers
  dt-bindings: PCI: qcom: Document msi-map and msi-map-mask properties
  PCI: qcom: Add SM8550 PCIe support
  dt-bindings: PCI: qcom: Add SM8550 compatible
  PCI: qcom: Add support for SDX55 SoC
  dt-bindings: PCI: qcom-ep: Fix the unit address used in example
  dt-bindings: PCI: qcom: Add SDX55 SoC
  dt-bindings: PCI: qcom: Update maintainers entry
  PCI: qcom: Enable async probe by default
  PCI: qcom: Add support for system suspend and resume
  PCI/PM: Drop pci_bridge_wait_for_secondary_bus() timeout parameter
  ...

60 files changed:
.clang-format
Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/pci/amlogic,meson-pcie.txt [deleted file]
Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml
Documentation/devicetree/bindings/pci/qcom,pcie.yaml
MAINTAINERS
arch/alpha/kernel/pci.c
arch/arm/kernel/bios32.c
arch/arm/mach-dove/pcie.c
arch/arm/mach-mv78xx0/pcie.c
arch/arm/mach-orion5x/pci.c
arch/mips/pci/ops-bcm63xx.c
arch/mips/pci/pci-legacy.c
arch/powerpc/kernel/pci-common.c
arch/powerpc/platforms/4xx/pci.c
arch/powerpc/platforms/52xx/mpc52xx_pci.c
arch/powerpc/platforms/pseries/pci.c
arch/sh/drivers/pci/pcie-sh7786.c
arch/sparc/kernel/leon_pci.c
arch/sparc/kernel/pci.c
arch/sparc/kernel/pcic.c
arch/x86/pci/fixup.c
drivers/eisa/pci_eisa.c
drivers/firmware/efi/cper-arm.c
drivers/pci/bus.c
drivers/pci/controller/Kconfig
drivers/pci/controller/cadence/Kconfig
drivers/pci/controller/dwc/Kconfig
drivers/pci/controller/dwc/pci-imx6.c
drivers/pci/controller/dwc/pci-layerscape-ep.c
drivers/pci/controller/dwc/pcie-qcom.c
drivers/pci/controller/mobiveil/Kconfig
drivers/pci/controller/pci-ixp4xx.c
drivers/pci/controller/pci-tegra.c
drivers/pci/controller/pcie-mediatek.c
drivers/pci/controller/pcie-mt7621.c
drivers/pci/controller/pcie-rcar-host.c
drivers/pci/controller/pcie-rcar.h
drivers/pci/hotplug/pciehp_pci.c
drivers/pci/hotplug/rpaphp_core.c
drivers/pci/hotplug/shpchp_sysfs.c
drivers/pci/of.c
drivers/pci/p2pdma.c
drivers/pci/pci-driver.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/pcie/dpc.c
drivers/pci/pcie/edr.c
drivers/pci/probe.c
drivers/pci/quirks.c
drivers/pci/remove.c
drivers/pci/setup-bus.c
drivers/pci/setup-res.c
drivers/pci/vgaarb.c
drivers/pci/xen-pcifront.c
drivers/pnp/quirks.c
include/linux/pci.h

index d988e9fa9b265324df3f8d637f7d21fbd6f08776..2048b0296d76f142d10df3ef5bf1f277fbfbeffa 100644 (file)
@@ -520,6 +520,7 @@ ForEachMacros:
   - 'of_property_for_each_string'
   - 'of_property_for_each_u32'
   - 'pci_bus_for_each_resource'
+  - 'pci_dev_for_each_resource'
   - 'pci_doe_for_each_off'
   - 'pcl_for_each_chunk'
   - 'pcl_for_each_segment'
diff --git a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml
new file mode 100644 (file)
index 0000000..a5bd90b
--- /dev/null
@@ -0,0 +1,134 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/amlogic,axg-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic Meson AXG DWC PCIe SoC controller
+
+maintainers:
+  - Neil Armstrong <neil.armstrong@linaro.org>
+
+description:
+  Amlogic Meson PCIe host controller is based on the Synopsys DesignWare PCI core.
+
+allOf:
+  - $ref: /schemas/pci/pci-bus.yaml#
+  - $ref: /schemas/pci/snps,dw-pcie-common.yaml#
+
+# We need a select here so we don't match all nodes with 'snps,dw-pcie'
+select:
+  properties:
+    compatible:
+      enum:
+        - amlogic,axg-pcie
+        - amlogic,g12a-pcie
+  required:
+    - compatible
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - amlogic,axg-pcie
+          - amlogic,g12a-pcie
+      - const: snps,dw-pcie
+
+  reg:
+    items:
+      - description: External local bus interface registers
+      - description: Meson designed configuration registers
+      - description: PCIe configuration space
+
+  reg-names:
+    items:
+      - const: elbi
+      - const: cfg
+      - const: config
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: PCIe GEN 100M PLL clock
+      - description: PCIe RC clock gate
+      - description: PCIe PHY clock
+
+  clock-names:
+    items:
+      - const: pclk
+      - const: port
+      - const: general
+
+  phys:
+    maxItems: 1
+
+  phy-names:
+    const: pcie
+
+  resets:
+    items:
+      - description: Port Reset
+      - description: Shared APB reset
+
+  reset-names:
+    items:
+      - const: port
+      - const: apb
+
+  num-lanes:
+    const: 1
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - clock
+  - clock-names
+  - "#address-cells"
+  - "#size-cells"
+  - "#interrupt-cells"
+  - interrupt-map
+  - interrupt-map-mask
+  - ranges
+  - bus-range
+  - device_type
+  - num-lanes
+  - phys
+  - phy-names
+  - resets
+  - reset-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    pcie: pcie@f9800000 {
+        compatible = "amlogic,axg-pcie", "snps,dw-pcie";
+        reg = <0xf9800000 0x400000>, <0xff646000 0x2000>, <0xf9f00000 0x100000>;
+        reg-names = "elbi", "cfg", "config";
+        interrupts = <GIC_SPI 177 IRQ_TYPE_EDGE_RISING>;
+        clocks = <&pclk>, <&clk_port>, <&clk_phy>;
+        clock-names = "pclk", "port", "general";
+        resets = <&reset_pcie_port>, <&reset_pcie_apb>;
+        reset-names = "port", "apb";
+        phys = <&pcie_phy>;
+        phy-names = "pcie";
+        #interrupt-cells = <1>;
+        interrupt-map-mask = <0 0 0 0>;
+        interrupt-map = <0 0 0 0 &gic GIC_SPI 179 IRQ_TYPE_EDGE_RISING>;
+        bus-range = <0x0 0xff>;
+        #address-cells = <3>;
+        #size-cells = <2>;
+        device_type = "pci";
+        num-lanes = <1>;
+        ranges = <0x82000000 0 0 0xf9c00000 0 0x00300000>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/pci/amlogic,meson-pcie.txt b/Documentation/devicetree/bindings/pci/amlogic,meson-pcie.txt
deleted file mode 100644 (file)
index c3a75ac..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-Amlogic Meson AXG DWC PCIE SoC controller
-
-Amlogic Meson PCIe host controller is based on the Synopsys DesignWare PCI core.
-It shares common functions with the PCIe DesignWare core driver and
-inherits common properties defined in
-Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml.
-
-Additional properties are described here:
-
-Required properties:
-- compatible:
-       should contain :
-       - "amlogic,axg-pcie" for AXG SoC Family
-       - "amlogic,g12a-pcie" for G12A SoC Family
-       to identify the core.
-- reg:
-       should contain the configuration address space.
-- reg-names: Must be
-       - "elbi"        External local bus interface registers
-       - "cfg"         Meson specific registers
-       - "config"      PCIe configuration space
-- reset-gpios: The GPIO to generate PCIe PERST# assert and deassert signal.
-- clocks: Must contain an entry for each entry in clock-names.
-- clock-names: Must include the following entries:
-       - "pclk"       PCIe GEN 100M PLL clock
-       - "port"       PCIe_x(A or B) RC clock gate
-       - "general"    PCIe Phy clock
-- resets: phandle to the reset lines.
-- reset-names: must contain "port" and "apb"
-       - "port"        Port A or B reset
-       - "apb"         Share APB reset
-- phys: should contain a phandle to the PCIE phy
-- phy-names: must contain "pcie"
-
-- device_type:
-       should be "pci". As specified in snps,dw-pcie.yaml
-
-
-Example configuration:
-
-       pcie: pcie@f9800000 {
-                       compatible = "amlogic,axg-pcie", "snps,dw-pcie";
-                       reg = <0x0 0xf9800000 0x0 0x400000
-                                       0x0 0xff646000 0x0 0x2000
-                                       0x0 0xf9f00000 0x0 0x100000>;
-                       reg-names = "elbi", "cfg", "config";
-                       reset-gpios = <&gpio GPIOX_19 GPIO_ACTIVE_HIGH>;
-                       interrupts = <GIC_SPI 177 IRQ_TYPE_EDGE_RISING>;
-                       #interrupt-cells = <1>;
-                       interrupt-map-mask = <0 0 0 0>;
-                       interrupt-map = <0 0 0 0 &gic GIC_SPI 179 IRQ_TYPE_EDGE_RISING>;
-                       bus-range = <0x0 0xff>;
-                       #address-cells = <3>;
-                       #size-cells = <2>;
-                       device_type = "pci";
-                       ranges = <0x82000000 0 0 0x0 0xf9c00000 0 0x00300000>;
-
-                       clocks = <&clkc CLKID_USB
-                                       &clkc CLKID_PCIE_A
-                                       &clkc CLKID_PCIE_CML_EN0>;
-                       clock-names = "general",
-                                       "pclk",
-                                       "port";
-                       resets = <&reset RESET_PCIE_A>,
-                               <&reset RESET_PCIE_APB>;
-                       reset-names = "port",
-                                       "apb";
-                       phys = <&pcie_phy>;
-                       phy-names = "pcie";
-       };
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
new file mode 100644 (file)
index 0000000..9bff8ec
--- /dev/null
@@ -0,0 +1,279 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/fsl,imx6q-pcie-common.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX6 PCIe RC/EP controller
+
+maintainers:
+  - Lucas Stach <l.stach@pengutronix.de>
+  - Richard Zhu <hongxing.zhu@nxp.com>
+
+description:
+  Generic Freescale i.MX PCIe Root Port and Endpoint controller
+  properties.
+
+properties:
+  clocks:
+    minItems: 3
+    items:
+      - description: PCIe bridge clock.
+      - description: PCIe bus clock.
+      - description: PCIe PHY clock.
+      - description: Additional required clock entry for imx6sx-pcie,
+           imx6sx-pcie-ep, imx8mq-pcie, imx8mq-pcie-ep.
+
+  clock-names:
+    minItems: 3
+    items:
+      - const: pcie
+      - const: pcie_bus
+      - enum: [ pcie_phy, pcie_aux ]
+      - enum: [ pcie_inbound_axi, pcie_aux ]
+
+  num-lanes:
+    const: 1
+
+  fsl,imx7d-pcie-phy:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: A phandle to an fsl,imx7d-pcie-phy node. Additional
+      required properties for imx7d-pcie, imx7d-pcie-ep, imx8mq-pcie,
+      and imx8mq-pcie-ep.
+
+  power-domains:
+    minItems: 1
+    items:
+      - description: The phandle pointing to the DISPLAY domain for
+          imx6sx-pcie, imx6sx-pcie-ep, to PCIE_PHY power domain for
+          imx7d-pcie, imx7d-pcie-ep, imx8mq-pcie and imx8mq-pcie-ep.
+      - description: The phandle pointing to the PCIE_PHY power domains
+          for imx6sx-pcie and imx6sx-pcie-ep.
+
+  power-domain-names:
+    minItems: 1
+    items:
+      - const: pcie
+      - const: pcie_phy
+
+  resets:
+    minItems: 2
+    maxItems: 3
+    description: Phandles to PCIe-related reset lines exposed by SRC
+      IP block. Additional required by imx7d-pcie, imx7d-pcie-ep,
+      imx8mq-pcie, and imx8mq-pcie-ep.
+
+  reset-names:
+    minItems: 2
+    maxItems: 3
+
+  fsl,tx-deemph-gen1:
+    description: Gen1 De-emphasis value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+
+  fsl,tx-deemph-gen2-3p5db:
+    description: Gen2 (3.5db) De-emphasis value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+
+  fsl,tx-deemph-gen2-6db:
+    description: Gen2 (6db) De-emphasis value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 20
+
+  fsl,tx-swing-full:
+    description: Gen2 TX SWING FULL value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 127
+
+  fsl,tx-swing-low:
+    description: TX launch amplitude swing_low value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 127
+
+  fsl,max-link-speed:
+    description: Specify PCI Gen for link capability (optional required).
+      Note that the IMX6 LVDS clock outputs do not meet gen2 jitter
+      requirements and thus for gen2 capability a gen2 compliant clock
+      generator should be used and configured.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [1, 2, 3, 4]
+    default: 1
+
+  phys:
+    maxItems: 1
+
+  phy-names:
+    const: pcie-phy
+
+  vpcie-supply:
+    description: Should specify the regulator in charge of PCIe port power.
+      The regulator will be enabled when initializing the PCIe host and
+      disabled either as part of the init process or when shutting down
+      the host (optional required).
+
+  vph-supply:
+    description: Should specify the regulator in charge of VPH one of
+      the three PCIe PHY powers. This regulator can be supplied by both
+      1.8v and 3.3v voltage supplies (optional required).
+
+required:
+  - clocks
+  - clock-names
+  - num-lanes
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx6sx-pcie
+              - fsl,imx6sx-pcie-ep
+    then:
+      properties:
+        clock-names:
+          items:
+            - {}
+            - {}
+            - const: pcie_phy
+            - const: pcie_inbound_axi
+        power-domains:
+          minItems: 2
+        power-domain-names:
+          minItems: 2
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx8mq-pcie
+              - fsl,imx8mq-pcie-ep
+    then:
+      properties:
+        clock-names:
+          items:
+            - {}
+            - {}
+            - const: pcie_phy
+            - const: pcie_aux
+  - if:
+      properties:
+        compatible:
+          not:
+            contains:
+              enum:
+                - fsl,imx6sx-pcie
+                - fsl,imx8mq-pcie
+                - fsl,imx6sx-pcie-ep
+                - fsl,imx8mq-pcie-ep
+    then:
+      properties:
+        clocks:
+          maxItems: 3
+        clock-names:
+          maxItems: 3
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx6q-pcie
+              - fsl,imx6qp-pcie
+              - fsl,imx7d-pcie
+              - fsl,imx6q-pcie-ep
+              - fsl,imx6qp-pcie-ep
+              - fsl,imx7d-pcie-ep
+    then:
+      properties:
+        clock-names:
+          maxItems: 3
+          contains:
+            const: pcie_phy
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx8mm-pcie
+              - fsl,imx8mp-pcie
+              - fsl,imx8mm-pcie-ep
+              - fsl,imx8mp-pcie-ep
+    then:
+      properties:
+        clock-names:
+          maxItems: 3
+          contains:
+            const: pcie_aux
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx6q-pcie
+              - fsl,imx6qp-pcie
+              - fsl,imx6q-pcie-ep
+              - fsl,imx6qp-pcie-ep
+    then:
+      properties:
+        power-domains: false
+        power-domain-names: false
+
+  - if:
+      not:
+        properties:
+          compatible:
+            contains:
+              enum:
+                - fsl,imx6sx-pcie
+                - fsl,imx6q-pcie
+                - fsl,imx6qp-pcie
+                - fsl,imx6sx-pcie-ep
+                - fsl,imx6q-pcie-ep
+                - fsl,imx6qp-pcie-ep
+    then:
+      properties:
+        power-domains:
+          maxItems: 1
+        power-domain-names: false
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx6q-pcie
+              - fsl,imx6sx-pcie
+              - fsl,imx6qp-pcie
+              - fsl,imx7d-pcie
+              - fsl,imx8mq-pcie
+              - fsl,imx6q-pcie-ep
+              - fsl,imx6sx-pcie-ep
+              - fsl,imx6qp-pcie-ep
+              - fsl,imx7d-pcie-ep
+              - fsl,imx8mq-pcie-ep
+    then:
+      properties:
+        resets:
+          minItems: 3
+        reset-names:
+          items:
+            - const: pciephy
+            - const: apps
+            - const: turnoff
+    else:
+      properties:
+        resets:
+          maxItems: 2
+        reset-names:
+          items:
+            - const: apps
+            - const: turnoff
+
+additionalProperties: true
+
+...
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml
new file mode 100644 (file)
index 0000000..f4a328e
--- /dev/null
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/fsl,imx6q-pcie-ep.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX6 PCIe Endpoint controller
+
+maintainers:
+  - Lucas Stach <l.stach@pengutronix.de>
+  - Richard Zhu <hongxing.zhu@nxp.com>
+
+description: |+
+  This PCIe controller is based on the Synopsys DesignWare PCIe IP and
+  thus inherits all the common properties defined in snps,dw-pcie-ep.yaml.
+  The controller instances are dual mode where in they can work either in
+  Root Port mode or Endpoint mode but one at a time.
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8mm-pcie-ep
+      - fsl,imx8mq-pcie-ep
+      - fsl,imx8mp-pcie-ep
+
+  reg:
+    minItems: 2
+
+  reg-names:
+    items:
+      - const: dbi
+      - const: addr_space
+
+  interrupts:
+    items:
+      - description: builtin eDMA interrupter.
+
+  interrupt-names:
+    items:
+      - const: dma
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - interrupt-names
+
+allOf:
+  - $ref: /schemas/pci/snps,dw-pcie-ep.yaml#
+  - $ref: /schemas/pci/fsl,imx6q-pcie-common.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mp-clock.h>
+    #include <dt-bindings/power/imx8mp-power.h>
+    #include <dt-bindings/reset/imx8mp-reset.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    pcie_ep: pcie-ep@33800000 {
+      compatible = "fsl,imx8mp-pcie-ep";
+      reg = <0x33800000 0x000400000>, <0x18000000 0x08000000>;
+      reg-names = "dbi", "addr_space";
+      clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
+               <&clk IMX8MP_CLK_HSIO_AXI>,
+               <&clk IMX8MP_CLK_PCIE_ROOT>;
+      clock-names = "pcie", "pcie_bus", "pcie_aux";
+      assigned-clocks = <&clk IMX8MP_CLK_PCIE_AUX>;
+      assigned-clock-rates = <10000000>;
+      assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_50M>;
+      num-lanes = <1>;
+      interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; /* eDMA */
+      interrupt-names = "dma";
+      fsl,max-link-speed = <3>;
+      power-domains = <&hsio_blk_ctrl IMX8MP_HSIOBLK_PD_PCIE>;
+      resets = <&src IMX8MP_RESET_PCIE_CTRL_APPS_EN>,
+               <&src IMX8MP_RESET_PCIE_CTRL_APPS_TURNOFF>;
+      reset-names = "apps", "turnoff";
+      phys = <&pcie_phy>;
+      phy-names = "pcie-phy";
+      num-ib-windows = <4>;
+      num-ob-windows = <4>;
+    };
index f13f87fddb3d70470af74209a0352f35b62829bb..2443641754d3fac2507a61af2406316c67636cf1 100644 (file)
@@ -13,6 +13,11 @@ maintainers:
 description: |+
   This PCIe host controller is based on the Synopsys DesignWare PCIe IP
   and thus inherits all the common properties defined in snps,dw-pcie.yaml.
+  The controller instances are dual mode where in they can work either in
+  Root Port mode or Endpoint mode but one at a time.
+
+  See fsl,imx6q-pcie-ep.yaml for details on the Endpoint mode device tree
+  bindings.
 
 properties:
   compatible:
@@ -24,9 +29,6 @@ properties:
       - fsl,imx8mq-pcie
       - fsl,imx8mm-pcie
       - fsl,imx8mp-pcie
-      - fsl,imx8mm-pcie-ep
-      - fsl,imx8mq-pcie-ep
-      - fsl,imx8mp-pcie-ep
 
   reg:
     items:
@@ -46,96 +48,6 @@ properties:
     items:
       - const: msi
 
-  clocks:
-    minItems: 3
-    items:
-      - description: PCIe bridge clock.
-      - description: PCIe bus clock.
-      - description: PCIe PHY clock.
-      - description: Additional required clock entry for imx6sx-pcie,
-          imx8mq-pcie.
-
-  clock-names:
-    minItems: 3
-    items:
-      - const: pcie
-      - const: pcie_bus
-      - enum: [ pcie_phy, pcie_aux ]
-      - enum: [ pcie_inbound_axi, pcie_aux ]
-
-  num-lanes:
-    const: 1
-
-  fsl,imx7d-pcie-phy:
-    $ref: /schemas/types.yaml#/definitions/phandle
-    description: A phandle to an fsl,imx7d-pcie-phy node. Additional
-      required properties for imx7d-pcie and imx8mq-pcie.
-
-  power-domains:
-    minItems: 1
-    items:
-      - description: The phandle pointing to the DISPLAY domain for
-          imx6sx-pcie, to PCIE_PHY power domain for imx7d-pcie and
-          imx8mq-pcie.
-      - description: The phandle pointing to the PCIE_PHY power domains
-          for imx6sx-pcie.
-
-  power-domain-names:
-    minItems: 1
-    items:
-      - const: pcie
-      - const: pcie_phy
-
-  resets:
-    minItems: 2
-    maxItems: 3
-    description: Phandles to PCIe-related reset lines exposed by SRC
-      IP block. Additional required by imx7d-pcie and imx8mq-pcie.
-
-  reset-names:
-    minItems: 2
-    maxItems: 3
-
-  fsl,tx-deemph-gen1:
-    description: Gen1 De-emphasis value (optional required).
-    $ref: /schemas/types.yaml#/definitions/uint32
-    default: 0
-
-  fsl,tx-deemph-gen2-3p5db:
-    description: Gen2 (3.5db) De-emphasis value (optional required).
-    $ref: /schemas/types.yaml#/definitions/uint32
-    default: 0
-
-  fsl,tx-deemph-gen2-6db:
-    description: Gen2 (6db) De-emphasis value (optional required).
-    $ref: /schemas/types.yaml#/definitions/uint32
-    default: 20
-
-  fsl,tx-swing-full:
-    description: Gen2 TX SWING FULL value (optional required).
-    $ref: /schemas/types.yaml#/definitions/uint32
-    default: 127
-
-  fsl,tx-swing-low:
-    description: TX launch amplitude swing_low value (optional required).
-    $ref: /schemas/types.yaml#/definitions/uint32
-    default: 127
-
-  fsl,max-link-speed:
-    description: Specify PCI Gen for link capability (optional required).
-      Note that the IMX6 LVDS clock outputs do not meet gen2 jitter
-      requirements and thus for gen2 capability a gen2 compliant clock
-      generator should be used and configured.
-    $ref: /schemas/types.yaml#/definitions/uint32
-    enum: [1, 2, 3, 4]
-    default: 1
-
-  phys:
-    maxItems: 1
-
-  phy-names:
-    const: pcie-phy
-
   reset-gpio:
     description: Should specify the GPIO for controlling the PCI bus device
       reset signal. It's not polarity aware and defaults to active-low reset
@@ -147,17 +59,6 @@ properties:
       L=operation state) (optional required).
     type: boolean
 
-  vpcie-supply:
-    description: Should specify the regulator in charge of PCIe port power.
-      The regulator will be enabled when initializing the PCIe host and
-      disabled either as part of the init process or when shutting down
-      the host (optional required).
-
-  vph-supply:
-    description: Should specify the regulator in charge of VPH one of
-      the three PCIe PHY powers. This regulator can be supplied by both
-      1.8v and 3.3v voltage supplies (optional required).
-
 required:
   - compatible
   - reg
@@ -167,144 +68,15 @@ required:
   - device_type
   - bus-range
   - ranges
-  - num-lanes
   - interrupts
   - interrupt-names
   - "#interrupt-cells"
   - interrupt-map-mask
   - interrupt-map
-  - clocks
-  - clock-names
 
 allOf:
   - $ref: /schemas/pci/snps,dw-pcie.yaml#
-  - if:
-      properties:
-        compatible:
-          contains:
-            const: fsl,imx6sx-pcie
-    then:
-      properties:
-        clock-names:
-          items:
-            - {}
-            - {}
-            - const: pcie_phy
-            - const: pcie_inbound_axi
-        power-domains:
-          minItems: 2
-        power-domain-names:
-          minItems: 2
-  - if:
-      properties:
-        compatible:
-          contains:
-            const: fsl,imx8mq-pcie
-    then:
-      properties:
-        clock-names:
-          items:
-            - {}
-            - {}
-            - const: pcie_phy
-            - const: pcie_aux
-  - if:
-      properties:
-        compatible:
-          not:
-            contains:
-              enum:
-                - fsl,imx6sx-pcie
-                - fsl,imx8mq-pcie
-    then:
-      properties:
-        clocks:
-          maxItems: 3
-        clock-names:
-          maxItems: 3
-
-  - if:
-      properties:
-        compatible:
-          contains:
-            enum:
-              - fsl,imx6q-pcie
-              - fsl,imx6qp-pcie
-              - fsl,imx7d-pcie
-    then:
-      properties:
-        clock-names:
-          maxItems: 3
-          contains:
-            const: pcie_phy
-
-  - if:
-      properties:
-        compatible:
-          contains:
-            enum:
-              - fsl,imx8mm-pcie
-              - fsl,imx8mp-pcie
-    then:
-      properties:
-        clock-names:
-          maxItems: 3
-          contains:
-            const: pcie_aux
-  - if:
-      properties:
-        compatible:
-          contains:
-            enum:
-              - fsl,imx6q-pcie
-              - fsl,imx6qp-pcie
-    then:
-      properties:
-        power-domains: false
-        power-domain-names: false
-
-  - if:
-      not:
-        properties:
-          compatible:
-            contains:
-              enum:
-                - fsl,imx6sx-pcie
-                - fsl,imx6q-pcie
-                - fsl,imx6qp-pcie
-    then:
-      properties:
-        power-domains:
-          maxItems: 1
-        power-domain-names: false
-
-  - if:
-      properties:
-        compatible:
-          contains:
-            enum:
-              - fsl,imx6q-pcie
-              - fsl,imx6sx-pcie
-              - fsl,imx6qp-pcie
-              - fsl,imx7d-pcie
-              - fsl,imx8mq-pcie
-    then:
-      properties:
-        resets:
-          minItems: 3
-        reset-names:
-          items:
-            - const: pciephy
-            - const: apps
-            - const: turnoff
-    else:
-      properties:
-        resets:
-          maxItems: 2
-        reset-names:
-          items:
-            - const: apps
-            - const: turnoff
+  - $ref: /schemas/pci/fsl,imx6q-pcie-common.yaml#
 
 unevaluatedProperties: false
 
index 523b1542875207076c65c72a0d790ccbaad0533c..b3c22ebd156c0bac9c1f945406c9bf5959b532c9 100644 (file)
@@ -166,7 +166,7 @@ examples:
     #include <dt-bindings/clock/qcom,gcc-sdx55.h>
     #include <dt-bindings/gpio/gpio.h>
     #include <dt-bindings/interrupt-controller/arm-gic.h>
-    pcie_ep: pcie-ep@40000000 {
+    pcie_ep: pcie-ep@1c00000 {
         compatible = "qcom,sdx55-pcie-ep";
         reg = <0x01c00000 0x3000>,
               <0x40000000 0xf1d>,
index fb32c43dd12dedf32406b0bba35a6a3c943fa2b0..81971be4e55446119b400aa3a42a7700b979f0a5 100644 (file)
@@ -8,7 +8,7 @@ title: Qualcomm PCI express root complex
 
 maintainers:
   - Bjorn Andersson <bjorn.andersson@linaro.org>
-  - Stanimir Varbanov <svarbanov@mm-sol.com>
+  - Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
 
 description: |
   Qualcomm PCIe root complex controller is based on the Synopsys DesignWare
@@ -33,22 +33,24 @@ properties:
           - qcom,pcie-sc8180x
           - qcom,pcie-sc8280xp
           - qcom,pcie-sdm845
+          - qcom,pcie-sdx55
           - qcom,pcie-sm8150
           - qcom,pcie-sm8250
           - qcom,pcie-sm8350
           - qcom,pcie-sm8450-pcie0
           - qcom,pcie-sm8450-pcie1
+          - qcom,pcie-sm8550
       - items:
           - const: qcom,pcie-msm8998
           - const: qcom,pcie-msm8996
 
   reg:
     minItems: 4
-    maxItems: 5
+    maxItems: 6
 
   reg-names:
     minItems: 4
-    maxItems: 5
+    maxItems: 6
 
   interrupts:
     minItems: 1
@@ -58,6 +60,9 @@ properties:
     minItems: 1
     maxItems: 8
 
+  iommu-map:
+    maxItems: 2
+
   # Common definitions for clocks, clock-names and reset.
   # Platform constraints are described later.
   clocks:
@@ -120,14 +125,20 @@ required:
   - compatible
   - reg
   - reg-names
-  - interrupts
-  - interrupt-names
-  - "#interrupt-cells"
   - interrupt-map-mask
   - interrupt-map
   - clocks
   - clock-names
 
+anyOf:
+  - required:
+      - interrupts
+      - interrupt-names
+      - "#interrupt-cells"
+  - required:
+      - msi-map
+      - msi-map-mask
+
 allOf:
   - $ref: /schemas/pci/pci-bus.yaml#
   - if:
@@ -185,13 +196,15 @@ allOf:
       properties:
         reg:
           minItems: 4
-          maxItems: 4
+          maxItems: 5
         reg-names:
+          minItems: 4
           items:
             - const: parf # Qualcomm specific registers
             - const: dbi # DesignWare PCIe registers
             - const: elbi # External local bus interface registers
             - const: config # PCIe configuration space
+            - const: mhi # MHI registers
 
   - if:
       properties:
@@ -201,22 +214,26 @@ allOf:
               - qcom,pcie-sc7280
               - qcom,pcie-sc8180x
               - qcom,pcie-sc8280xp
+              - qcom,pcie-sdx55
               - qcom,pcie-sm8250
               - qcom,pcie-sm8350
               - qcom,pcie-sm8450-pcie0
               - qcom,pcie-sm8450-pcie1
+              - qcom,pcie-sm8550
     then:
       properties:
         reg:
           minItems: 5
-          maxItems: 5
+          maxItems: 6
         reg-names:
+          minItems: 5
           items:
             - const: parf # Qualcomm specific registers
             - const: dbi # DesignWare PCIe registers
             - const: elbi # External local bus interface registers
             - const: atu # ATU address space
             - const: config # PCIe configuration space
+            - const: mhi # MHI registers
 
   - if:
       properties:
@@ -639,6 +656,37 @@ allOf:
           items:
             - const: pci # PCIe core reset
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,pcie-sm8550
+    then:
+      properties:
+        clocks:
+          minItems: 7
+          maxItems: 8
+        clock-names:
+          minItems: 7
+          items:
+            - const: aux # Auxiliary clock
+            - const: cfg # Configuration clock
+            - const: bus_master # Master AXI clock
+            - const: bus_slave # Slave AXI clock
+            - const: slave_q2a # Slave Q2A clock
+            - const: ddrss_sf_tbu # PCIe SF TBU clock
+            - const: noc_aggr # Aggre NoC PCIe AXI clock
+            - const: cnoc_sf_axi # Config NoC PCIe1 AXI clock
+        resets:
+          minItems: 1
+          maxItems: 2
+        reset-names:
+          minItems: 1
+          items:
+            - const: pci # PCIe core reset
+            - const: link_down # PCIe link down reset
+
   - if:
       properties:
         compatible:
@@ -669,6 +717,32 @@ allOf:
           items:
             - const: pci # PCIe core reset
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,pcie-sdx55
+    then:
+      properties:
+        clocks:
+          minItems: 7
+          maxItems: 7
+        clock-names:
+          items:
+            - const: pipe # PIPE clock
+            - const: aux # Auxiliary clock
+            - const: cfg # Configuration clock
+            - const: bus_master # Master AXI clock
+            - const: bus_slave # Slave AXI clock
+            - const: slave_q2a # Slave Q2A clock
+            - const: sleep # PCIe Sleep clock
+        resets:
+          maxItems: 1
+        reset-names:
+          items:
+            - const: pci # PCIe core reset
+
   - if:
       properties:
         compatible:
@@ -724,6 +798,7 @@ allOf:
               - qcom,pcie-sm8350
               - qcom,pcie-sm8450-pcie0
               - qcom,pcie-sm8450-pcie1
+              - qcom,pcie-sm8550
     then:
       oneOf:
         - properties:
index 5e11a9e9c4a089476ebb0601a8ac73e2422abcec..a9b604a796fcabc84c1e8dbfd789773e8c4b1566 100644 (file)
@@ -16035,6 +16035,8 @@ M:      Lucas Stach <l.stach@pengutronix.de>
 L:     linux-pci@vger.kernel.org
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
+F:     Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-common.yaml
+F:     Documentation/devicetree/bindings/pci/fsl,imx6q-pcie-ep.yaml
 F:     Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
 F:     drivers/pci/controller/dwc/*imx6*
 
index 64fbfb0763b292975ce8fa47d1e2b2bc17be29bb..4458eb7f44f0ca0a8fd90d32c8f8f9b637de4b14 100644 (file)
@@ -288,11 +288,10 @@ pcibios_claim_one_bus(struct pci_bus *b)
        struct pci_bus *child_bus;
 
        list_for_each_entry(dev, &b->devices, bus_list) {
+               struct resource *r;
                int i;
 
-               for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-                       struct resource *r = &dev->resource[i];
-
+               pci_dev_for_each_resource(dev, r, i) {
                        if (r->parent || !r->start || !r->flags)
                                continue;
                        if (pci_has_flag(PCI_PROBE_ONLY) ||
index e7ef2b5bea9c224b4a3d6c6812b70a9404cf3818..d334c7fb672b7cec30c2a5af06260960af2a8dda 100644 (file)
@@ -142,15 +142,15 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940F,
  */
 static void pci_fixup_dec21285(struct pci_dev *dev)
 {
-       int i;
-
        if (dev->devfn == 0) {
+               struct resource *r;
+
                dev->class &= 0xff;
                dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
-               for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-                       dev->resource[i].start = 0;
-                       dev->resource[i].end   = 0;
-                       dev->resource[i].flags = 0;
+               pci_dev_for_each_resource(dev, r) {
+                       r->start = 0;
+                       r->end = 0;
+                       r->flags = 0;
                }
        }
 }
@@ -162,13 +162,11 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, pci_fixup_d
 static void pci_fixup_ide_bases(struct pci_dev *dev)
 {
        struct resource *r;
-       int i;
 
        if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
                return;
 
-       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-               r = dev->resource + i;
+       pci_dev_for_each_resource(dev, r) {
                if ((r->start & ~0x80) == 0x374) {
                        r->start |= 2;
                        r->end = r->start;
index 754ca381f600ab9e6f8e4aebb2d89185497a25bc..3044b7e038901628486179194ae3515d88be1dba 100644 (file)
@@ -142,14 +142,14 @@ static struct pci_ops pcie_ops = {
 static void rc_pci_fixup(struct pci_dev *dev)
 {
        if (dev->bus->parent == NULL && dev->devfn == 0) {
-               int i;
+               struct resource *r;
 
                dev->class &= 0xff;
                dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
-               for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-                       dev->resource[i].start = 0;
-                       dev->resource[i].end   = 0;
-                       dev->resource[i].flags = 0;
+               pci_dev_for_each_resource(dev, r) {
+                       r->start = 0;
+                       r->end   = 0;
+                       r->flags = 0;
                }
        }
 }
index fa68b63941b153a2a8e0cdf2edc8528f7d21ee37..533cb78569432188de24339411e05a6b39a42212 100644 (file)
@@ -186,14 +186,14 @@ static struct pci_ops pcie_ops = {
 static void rc_pci_fixup(struct pci_dev *dev)
 {
        if (dev->bus->parent == NULL && dev->devfn == 0) {
-               int i;
+               struct resource *r;
 
                dev->class &= 0xff;
                dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
-               for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-                       dev->resource[i].start = 0;
-                       dev->resource[i].end   = 0;
-                       dev->resource[i].flags = 0;
+               pci_dev_for_each_resource(dev, r) {
+                       r->start = 0;
+                       r->end   = 0;
+                       r->flags = 0;
                }
        }
 }
index 888fdc9099c528944d79ea0f49e92e6bb3522e10..3313bc5a63ea6797abd60b3b4806e80af538a541 100644 (file)
@@ -522,14 +522,14 @@ static int __init pci_setup(struct pci_sys_data *sys)
 static void rc_pci_fixup(struct pci_dev *dev)
 {
        if (dev->bus->parent == NULL && dev->devfn == 0) {
-               int i;
+               struct resource *r;
 
                dev->class &= 0xff;
                dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
-               for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-                       dev->resource[i].start = 0;
-                       dev->resource[i].end   = 0;
-                       dev->resource[i].flags = 0;
+               pci_dev_for_each_resource(dev, r) {
+                       r->start        = 0;
+                       r->end          = 0;
+                       r->flags        = 0;
                }
        }
 }
index dc6dc2741272ea92b3b292750a3c54c10346da2b..b0ea023c47c021115ece845e235af52436174b69 100644 (file)
@@ -413,18 +413,18 @@ struct pci_ops bcm63xx_cb_ops = {
 static void bcm63xx_fixup(struct pci_dev *dev)
 {
        static int io_window = -1;
-       int i, found, new_io_window;
+       int found, new_io_window;
+       struct resource *r;
        u32 val;
 
        /* look for any io resource */
        found = 0;
-       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-               if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
+       pci_dev_for_each_resource(dev, r) {
+               if (resource_type(r) == IORESOURCE_IO) {
                        found = 1;
                        break;
                }
        }
-
        if (!found)
                return;
 
index 468722c8a5c6185a6164a5226fb8805ebbd28ac8..ec2567f8efd83bff7b106cbbd9ec7a6de0308c4c 100644 (file)
@@ -249,12 +249,11 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask)
 
        pci_read_config_word(dev, PCI_COMMAND, &cmd);
        old_cmd = cmd;
-       for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
+       pci_dev_for_each_resource(dev, r, idx) {
                /* Only set up the requested stuff */
                if (!(mask & (1<<idx)))
                        continue;
 
-               r = &dev->resource[idx];
                if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
                        continue;
                if ((idx == PCI_ROM_RESOURCE) &&
index d67cf79bf5d03456fbfc8aae5544b40c21de388c..e88d7c9feeec337c5704d9971b3a236ec0651870 100644 (file)
@@ -880,6 +880,7 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
 static void pcibios_fixup_resources(struct pci_dev *dev)
 {
        struct pci_controller *hose = pci_bus_to_host(dev->bus);
+       struct resource *res;
        int i;
 
        if (!hose) {
@@ -891,9 +892,9 @@ static void pcibios_fixup_resources(struct pci_dev *dev)
        if (dev->is_virtfn)
                return;
 
-       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-               struct resource *res = dev->resource + i;
+       pci_dev_for_each_resource(dev, res, i) {
                struct pci_bus_region reg;
+
                if (!res->flags)
                        continue;
 
@@ -1452,11 +1453,10 @@ void pcibios_claim_one_bus(struct pci_bus *bus)
        struct pci_bus *child_bus;
 
        list_for_each_entry(dev, &bus->devices, bus_list) {
+               struct resource *r;
                int i;
 
-               for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-                       struct resource *r = &dev->resource[i];
-
+               pci_dev_for_each_resource(dev, r, i) {
                        if (r->parent || !r->start || !r->flags)
                                continue;
 
@@ -1705,19 +1705,20 @@ EXPORT_SYMBOL_GPL(pcibios_scan_phb);
 
 static void fixup_hide_host_resource_fsl(struct pci_dev *dev)
 {
-       int i, class = dev->class >> 8;
+       int class = dev->class >> 8;
        /* When configured as agent, programming interface = 1 */
        int prog_if = dev->class & 0xf;
+       struct resource *r;
 
        if ((class == PCI_CLASS_PROCESSOR_POWERPC ||
             class == PCI_CLASS_BRIDGE_OTHER) &&
                (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) &&
                (prog_if == 0) &&
                (dev->bus->parent == NULL)) {
-               for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-                       dev->resource[i].start = 0;
-                       dev->resource[i].end = 0;
-                       dev->resource[i].flags = 0;
+               pci_dev_for_each_resource(dev, r) {
+                       r->start = 0;
+                       r->end = 0;
+                       r->flags = 0;
                }
        }
 }
index ca5dd7a5842ac8c19f05a01f84afc8ce0619c271..07dcc2b8007f97054bc9afa43747ece65782eeec 100644 (file)
@@ -57,7 +57,7 @@ static inline int ppc440spe_revA(void)
 static void fixup_ppc4xx_pci_bridge(struct pci_dev *dev)
 {
        struct pci_controller *hose;
-       int i;
+       struct resource *r;
 
        if (dev->devfn != 0 || dev->bus->self != NULL)
                return;
@@ -79,9 +79,9 @@ static void fixup_ppc4xx_pci_bridge(struct pci_dev *dev)
        /* Hide the PCI host BARs from the kernel as their content doesn't
         * fit well in the resource management
         */
-       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-               dev->resource[i].start = dev->resource[i].end = 0;
-               dev->resource[i].flags = 0;
+       pci_dev_for_each_resource(dev, r) {
+               r->start = r->end = 0;
+               r->flags = 0;
        }
 
        printk(KERN_INFO "PCI: Hiding 4xx host bridge resources %s\n",
index 859e2818c43d5736aa15d8e242ced26c4b78adb0..0ca4401ba7819211bc2c52793b094216f30e39a8 100644 (file)
@@ -327,14 +327,13 @@ mpc52xx_pci_setup(struct pci_controller *hose,
 static void
 mpc52xx_pci_fixup_resources(struct pci_dev *dev)
 {
-       int i;
+       struct resource *res;
 
        pr_debug("%s() %.4x:%.4x\n", __func__, dev->vendor, dev->device);
 
        /* We don't rely on boot loader for PCI and resets all
           devices */
-       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-               struct resource *res = &dev->resource[i];
+       pci_dev_for_each_resource(dev, res) {
                if (res->end > res->start) {    /* Only valid resources */
                        res->end -= res->start;
                        res->start = 0;
index 60e0a58928ef4d3be457398a281e4dd577ec6150..1772ae3d193d0373e351796d93c3a8798f7126cd 100644 (file)
@@ -240,7 +240,7 @@ void __init pSeries_final_fixup(void)
  */
 static void fixup_winbond_82c105(struct pci_dev* dev)
 {
-       int i;
+       struct resource *r;
        unsigned int reg;
 
        if (!machine_is(pseries))
@@ -251,14 +251,14 @@ static void fixup_winbond_82c105(struct pci_dev* dev)
        /* Enable LEGIRQ to use INTC instead of ISA interrupts */
        pci_write_config_dword(dev, 0x40, reg | (1<<11));
 
-       for (i = 0; i < DEVICE_COUNT_RESOURCE; ++i) {
+       pci_dev_for_each_resource(dev, r) {
                /* zap the 2nd function of the winbond chip */
-               if (dev->resource[i].flags & IORESOURCE_IO
-                   && dev->bus->number == 0 && dev->devfn == 0x81)
-                       dev->resource[i].flags &= ~IORESOURCE_IO;
-               if (dev->resource[i].start == 0 && dev->resource[i].end) {
-                       dev->resource[i].flags = 0;
-                       dev->resource[i].end = 0;
+               if (dev->bus->number == 0 && dev->devfn == 0x81 &&
+                   r->flags & IORESOURCE_IO)
+                       r->flags &= ~IORESOURCE_IO;
+               if (r->start == 0 && r->end) {
+                       r->flags = 0;
+                       r->end = 0;
                }
        }
 }
index b0c2a5238d04974c206cd2eef0642a412c73804c..4f5e49f10805e819b90153dda29f90fb9a4c66d4 100644 (file)
@@ -140,12 +140,12 @@ static void sh7786_pci_fixup(struct pci_dev *dev)
         * Prevent enumeration of root complex resources.
         */
        if (pci_is_root_bus(dev->bus) && dev->devfn == 0) {
-               int i;
+               struct resource *r;
 
-               for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-                       dev->resource[i].start  = 0;
-                       dev->resource[i].end    = 0;
-                       dev->resource[i].flags  = 0;
+               pci_dev_for_each_resource(dev, r) {
+                       r->start        = 0;
+                       r->end          = 0;
+                       r->flags        = 0;
                }
        }
 }
index e5e5ff6b9a5c5a3d5aa144e797973d30c459479b..b6663a3fbae9299bc0110164bb4dff54a6795bc7 100644 (file)
@@ -62,15 +62,14 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
 
 int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
+       struct resource *res;
        u16 cmd, oldcmd;
        int i;
 
        pci_read_config_word(dev, PCI_COMMAND, &cmd);
        oldcmd = cmd;
 
-       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-               struct resource *res = &dev->resource[i];
-
+       pci_dev_for_each_resource(dev, res, i) {
                /* Only set up the requested stuff */
                if (!(mask & (1<<i)))
                        continue;
index cb1ef25116e943436c83d68ae033dbb7d7161b25..a948a49817c7aec86a3dd5be765dda5f8e5ca4ef 100644 (file)
@@ -663,11 +663,10 @@ static void pci_claim_bus_resources(struct pci_bus *bus)
        struct pci_dev *dev;
 
        list_for_each_entry(dev, &bus->devices, bus_list) {
+               struct resource *r;
                int i;
 
-               for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-                       struct resource *r = &dev->resource[i];
-
+               pci_dev_for_each_resource(dev, r, i) {
                        if (r->parent || !r->start || !r->flags)
                                continue;
 
@@ -724,15 +723,14 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
 
 int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
+       struct resource *res;
        u16 cmd, oldcmd;
        int i;
 
        pci_read_config_word(dev, PCI_COMMAND, &cmd);
        oldcmd = cmd;
 
-       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-               struct resource *res = &dev->resource[i];
-
+       pci_dev_for_each_resource(dev, res, i) {
                /* Only set up the requested stuff */
                if (!(mask & (1<<i)))
                        continue;
index ee4c9a9a171cc094273d1dc5b5949c778f68035c..25fe0a06173256816137a0862750bf751dde0767 100644 (file)
@@ -643,15 +643,14 @@ void pcibios_fixup_bus(struct pci_bus *bus)
 
 int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
+       struct resource *res;
        u16 cmd, oldcmd;
        int i;
 
        pci_read_config_word(dev, PCI_COMMAND, &cmd);
        oldcmd = cmd;
 
-       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-               struct resource *res = &dev->resource[i];
-
+       pci_dev_for_each_resource(dev, res, i) {
                /* Only set up the requested stuff */
                if (!(mask & (1<<i)))
                        continue;
index bf5161dcf89e7ebf9c454456252a856c8aa9bfab..e3ec02e6ac9febaca0b4606ed126dbd182f410fc 100644 (file)
@@ -845,3 +845,62 @@ static void quirk_clear_strap_no_soft_reset_dev2_f0(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15b8, quirk_clear_strap_no_soft_reset_dev2_f0);
 #endif
+
+/*
+ * When returning from D3cold to D0, firmware on some Google Coral and Reef
+ * family Chromebooks with Intel Apollo Lake SoC clobbers the headers of
+ * both the L1 PM Substates capability and the previous capability for the
+ * "Celeron N3350/Pentium N4200/Atom E3900 Series PCI Express Port B #1".
+ *
+ * Save those values at enumeration-time and restore them at resume.
+ */
+
+static u16 prev_cap, l1ss_cap;
+static u32 prev_header, l1ss_header;
+
+static void chromeos_save_apl_pci_l1ss_capability(struct pci_dev *dev)
+{
+       int pos = PCI_CFG_SPACE_SIZE, prev = 0;
+       u32 header, pheader = 0;
+
+       while (pos) {
+               pci_read_config_dword(dev, pos, &header);
+               if (PCI_EXT_CAP_ID(header) == PCI_EXT_CAP_ID_L1SS) {
+                       prev_cap = prev;
+                       prev_header = pheader;
+                       l1ss_cap = pos;
+                       l1ss_header = header;
+                       return;
+               }
+
+               prev = pos;
+               pheader = header;
+               pos = PCI_EXT_CAP_NEXT(header);
+       }
+}
+
+static void chromeos_fixup_apl_pci_l1ss_capability(struct pci_dev *dev)
+{
+       u32 header;
+
+       if (!prev_cap || !prev_header || !l1ss_cap || !l1ss_header)
+               return;
+
+       /* Fixup the header of L1SS Capability if missing */
+       pci_read_config_dword(dev, l1ss_cap, &header);
+       if (header != l1ss_header) {
+               pci_write_config_dword(dev, l1ss_cap, l1ss_header);
+               pci_info(dev, "restore L1SS Capability header (was %#010x now %#010x)\n",
+                        header, l1ss_header);
+       }
+
+       /* Fixup the link to L1SS Capability if missing */
+       pci_read_config_dword(dev, prev_cap, &header);
+       if (header != prev_header) {
+               pci_write_config_dword(dev, prev_cap, prev_header);
+               pci_info(dev, "restore previous Capability header (was %#010x now %#010x)\n",
+                        header, prev_header);
+       }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x5ad6, chromeos_save_apl_pci_l1ss_capability);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, 0x5ad6, chromeos_fixup_apl_pci_l1ss_capability);
index 930c2332c3c42be2d691a64368ca8d40a232e1e6..8173e60bb8081dbf00941a3c554ddfe2ec87cd3d 100644 (file)
@@ -20,8 +20,8 @@ static struct eisa_root_device pci_eisa_root;
 
 static int __init pci_eisa_init(struct pci_dev *pdev)
 {
-       int rc, i;
        struct resource *res, *bus_res = NULL;
+       int rc;
 
        if ((rc = pci_enable_device (pdev))) {
                dev_err(&pdev->dev, "Could not enable device\n");
@@ -38,7 +38,7 @@ static int __init pci_eisa_init(struct pci_dev *pdev)
         * eisa_root_register() can only deal with a single io port resource,
        *  so we use the first valid io port resource.
         */
-       pci_bus_for_each_resource(pdev->bus, res, i)
+       pci_bus_for_each_resource(pdev->bus, res)
                if (res && (res->flags & IORESOURCE_IO)) {
                        bus_res = res;
                        break;
index 36d3b8b9da47eb48abd3a21099dc7ee172aaea3b..fa9c1c3bf168b0d06303a2d1ccaa24b18318ef9a 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/dmi.h>
 #include <linux/acpi.h>
 #include <linux/pci.h>
-#include <linux/aer.h>
 #include <linux/printk.h>
 #include <linux/bcd.h>
 #include <acpi/ghes.h>
index 549c4bd5caecafd925692f308d45fa6c40a3387f..5bc81cc0a2de4d392052bb068b10075a9ceb0055 100644 (file)
@@ -182,13 +182,13 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
                void *alignf_data,
                struct pci_bus_region *region)
 {
-       int i, ret;
        struct resource *r, avail;
        resource_size_t max;
+       int ret;
 
        type_mask |= IORESOURCE_TYPE_BITS;
 
-       pci_bus_for_each_resource(bus, r, i) {
+       pci_bus_for_each_resource(bus, r) {
                resource_size_t min_used = min;
 
                if (!r)
@@ -289,9 +289,8 @@ bool pci_bus_clip_resource(struct pci_dev *dev, int idx)
        struct resource *res = &dev->resource[idx];
        struct resource orig_res = *res;
        struct resource *r;
-       int i;
 
-       pci_bus_for_each_resource(bus, r, i) {
+       pci_bus_for_each_resource(bus, r) {
                resource_size_t start, end;
 
                if (!r)
index 42654035654a1ffab0c68642ca31b77ea446a812..8d49bad7f84728add52a9f3b53d6f189de69813b 100644 (file)
@@ -3,19 +3,6 @@
 menu "PCI controller drivers"
        depends on PCI
 
-config PCI_MVEBU
-       tristate "Marvell EBU PCIe controller"
-       depends on ARCH_MVEBU || ARCH_DOVE || COMPILE_TEST
-       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
-        is used on 32-bit Marvell ARM SoCs: Dove, Kirkwood, Armada 370,
-        Armada XP, Armada 375, Armada 38x and Armada 39x.
-
 config PCI_AARDVARK
        tristate "Aardvark PCIe controller"
        depends on (ARCH_MVEBU && ARM64) || COMPILE_TEST
@@ -27,120 +14,54 @@ config PCI_AARDVARK
         controller is part of the South Bridge of the Marvel Armada
         3700 SoC.
 
-config PCIE_XILINX_NWL
-       bool "NWL PCIe Core"
-       depends on ARCH_ZYNQMP || COMPILE_TEST
-       depends on PCI_MSI
-       help
-        Say 'Y' here if you want kernel support for Xilinx
-        NWL PCIe controller. The controller can act as Root Port
-        or End Point. The current option selection will only
-        support root port enabling.
-
-config PCI_FTPCI100
-       bool "Faraday Technology FTPCI100 PCI controller"
-       depends on OF
-       default ARCH_GEMINI
-
-config PCI_IXP4XX
-       bool "Intel IXP4xx PCI controller"
-       depends on ARM && OF
-       depends on ARCH_IXP4XX || COMPILE_TEST
-       default ARCH_IXP4XX
-       help
-         Say Y here if you want support for the PCI host controller found
-         in the Intel IXP4xx XScale-based network processor SoC.
-
-config PCI_TEGRA
-       bool "NVIDIA Tegra PCIe controller"
-       depends on ARCH_TEGRA || COMPILE_TEST
-       depends on PCI_MSI
-       help
-         Say Y here if you want support for the PCIe host controller found
-         on NVIDIA Tegra SoCs.
-
-config PCI_RCAR_GEN2
-       bool "Renesas R-Car Gen2 Internal PCI controller"
-       depends on ARCH_RENESAS || COMPILE_TEST
-       depends on ARM
+config PCIE_ALTERA
+       tristate "Altera PCIe controller"
+       depends on ARM || NIOS2 || ARM64 || COMPILE_TEST
        help
-         Say Y here if you want internal PCI support on R-Car Gen2 SoC.
-         There are 3 internal PCI controllers available with a single
-         built-in EHCI/OHCI host controller present on each one.
+         Say Y here if you want to enable PCIe controller support on Altera
+         FPGA.
 
-config PCIE_RCAR_HOST
-       bool "Renesas R-Car PCIe host controller"
-       depends on ARCH_RENESAS || COMPILE_TEST
+config PCIE_ALTERA_MSI
+       tristate "Altera PCIe MSI feature"
+       depends on PCIE_ALTERA
        depends on PCI_MSI
        help
-         Say Y here if you want PCIe controller support on R-Car SoCs in host
-         mode.
-
-config PCIE_RCAR_EP
-       bool "Renesas R-Car PCIe endpoint controller"
-       depends on ARCH_RENESAS || COMPILE_TEST
-       depends on PCI_ENDPOINT
-       help
-         Say Y here if you want PCIe controller support on R-Car SoCs in
-         endpoint mode.
+         Say Y here if you want PCIe MSI support for the Altera FPGA.
+         This MSI driver supports Altera MSI to GIC controller IP.
 
-config PCI_HOST_COMMON
-       tristate
-       select PCI_ECAM
+config PCIE_APPLE_MSI_DOORBELL_ADDR
+       hex
+       default 0xfffff000
+       depends on PCIE_APPLE
 
-config PCI_HOST_GENERIC
-       tristate "Generic PCI host controller"
+config PCIE_APPLE
+       tristate "Apple PCIe controller"
+       depends on ARCH_APPLE || COMPILE_TEST
        depends on OF
-       select PCI_HOST_COMMON
-       select IRQ_DOMAIN
-       help
-         Say Y here if you want to support a simple generic PCI host
-         controller, such as the one emulated by kvmtool.
-
-config PCIE_XILINX
-       bool "Xilinx AXI PCIe host bridge support"
-       depends on OF || COMPILE_TEST
        depends on PCI_MSI
-       help
-         Say 'Y' here if you want kernel to support the Xilinx AXI PCIe
-         Host Bridge driver.
-
-config PCIE_XILINX_CPM
-       bool "Xilinx Versal CPM host bridge support"
-       depends on ARCH_ZYNQMP || COMPILE_TEST
        select PCI_HOST_COMMON
        help
-         Say 'Y' here if you want kernel support for the
-         Xilinx Versal CPM host bridge.
-
-config PCI_XGENE
-       bool "X-Gene PCIe controller"
-       depends on ARM64 || COMPILE_TEST
-       depends on OF || (ACPI && PCI_QUIRKS)
-       help
-         Say Y here if you want internal PCI support on APM X-Gene SoC.
-         There are 5 internal PCIe ports available. Each port is GEN3 capable
-         and have varied lanes from x1 to x8.
-
-config PCI_XGENE_MSI
-       bool "X-Gene v1 PCIe MSI feature"
-       depends on PCI_XGENE
-       depends on PCI_MSI
-       default y
-       help
-         Say Y here if you want PCIe MSI support for the APM X-Gene v1 SoC.
-         This MSI driver supports 5 PCIe ports on the APM X-Gene v1 SoC.
+         Say Y here if you want to enable PCIe controller support on Apple
+         system-on-chips, like the Apple M1. This is required for the USB
+         type-A ports, Ethernet, Wi-Fi, and Bluetooth.
 
-config PCI_V3_SEMI
-       bool "V3 Semiconductor PCI controller"
-       depends on OF
-       depends on ARM || COMPILE_TEST
-       default ARCH_INTEGRATOR_AP
+         If unsure, say Y if you have an Apple Silicon system.
 
 config PCI_VERSATILE
        bool "ARM Versatile PB PCI controller"
        depends on ARCH_VERSATILE || COMPILE_TEST
 
+config PCIE_BRCMSTB
+       tristate "Broadcom Brcmstb PCIe controller"
+       depends on ARCH_BRCMSTB || ARCH_BCM2835 || ARCH_BCMBCA || \
+                  BMIPS_GENERIC || COMPILE_TEST
+       depends on OF
+       depends on PCI_MSI
+       default ARCH_BRCMSTB || BMIPS_GENERIC
+       help
+         Say Y here to enable PCIe host controller support for
+         Broadcom STB based SoCs, like the Raspberry Pi 4.
+
 config PCIE_IPROC
        tristate
        help
@@ -159,7 +80,7 @@ config PCIE_IPROC_PLATFORM
          through the generic platform bus interface
 
 config PCIE_IPROC_BCMA
-       tristate "Broadcom iProc PCIe BCMA bus driver"
+       tristate "Broadcom iProc BCMA PCIe controller"
        depends on ARM && (ARCH_BCM_IPROC || COMPILE_TEST)
        select PCIE_IPROC
        select BCMA
@@ -177,21 +98,6 @@ config PCIE_IPROC_MSI
          Say Y here if you want to enable MSI support for Broadcom's iProc
          PCIe controller
 
-config PCIE_ALTERA
-       tristate "Altera PCIe controller"
-       depends on ARM || NIOS2 || ARM64 || COMPILE_TEST
-       help
-         Say Y here if you want to enable PCIe controller support on Altera
-         FPGA.
-
-config PCIE_ALTERA_MSI
-       tristate "Altera PCIe MSI feature"
-       depends on PCIE_ALTERA
-       depends on PCI_MSI
-       help
-         Say Y here if you want PCIe MSI support for the Altera FPGA.
-         This MSI driver supports Altera MSI to GIC controller IP.
-
 config PCI_HOST_THUNDER_PEM
        bool "Cavium Thunder PCIe controller to off-chip devices"
        depends on ARM64 || COMPILE_TEST
@@ -208,33 +114,77 @@ config PCI_HOST_THUNDER_ECAM
        help
          Say Y here if you want ECAM support for CN88XX-Pass-1.x Cavium Thunder SoCs.
 
-config PCIE_ROCKCHIP
-       bool
-       depends on PCI
+config PCI_FTPCI100
+       bool "Faraday Technology FTPCI100 PCI controller"
+       depends on OF
+       default ARCH_GEMINI
 
-config PCIE_ROCKCHIP_HOST
-       tristate "Rockchip PCIe host controller"
-       depends on ARCH_ROCKCHIP || COMPILE_TEST
+config PCI_HOST_COMMON
+       tristate
+       select PCI_ECAM
+
+config PCI_HOST_GENERIC
+       tristate "Generic PCI host controller"
        depends on OF
-       depends on PCI_MSI
-       select MFD_SYSCON
-       select PCIE_ROCKCHIP
+       select PCI_HOST_COMMON
+       select IRQ_DOMAIN
        help
-         Say Y here if you want internal PCI support on Rockchip SoC.
-         There is 1 internal PCIe port available to support GEN2 with
-         4 slots.
+         Say Y here if you want to support a simple generic PCI host
+         controller, such as the one emulated by kvmtool.
 
-config PCIE_ROCKCHIP_EP
-       bool "Rockchip PCIe endpoint controller"
-       depends on ARCH_ROCKCHIP || COMPILE_TEST
+config PCIE_HISI_ERR
+       depends on ACPI_APEI_GHES && (ARM64 || COMPILE_TEST)
+       bool "HiSilicon HIP PCIe controller error handling driver"
+       help
+         Say Y here if you want error handling support
+         for the PCIe controller's errors on HiSilicon HIP SoCs
+
+config PCI_IXP4XX
+       bool "Intel IXP4xx PCI controller"
+       depends on ARM && OF
+       depends on ARCH_IXP4XX || COMPILE_TEST
+       default ARCH_IXP4XX
+       help
+         Say Y here if you want support for the PCI host controller found
+         in the Intel IXP4xx XScale-based network processor SoC.
+
+config VMD
+       depends on PCI_MSI && X86_64 && !UML
+       tristate "Intel Volume Management Device Driver"
+       help
+         Adds support for the Intel Volume Management Device (VMD). VMD is a
+         secondary PCI host bridge that allows PCI Express root ports,
+         and devices attached to them, to be removed from the default
+         PCI domain and placed within the VMD domain. This provides
+         more bus resources than are otherwise possible with a
+         single domain. If you know your system provides one of these and
+         has devices attached to it, say Y; if you are not sure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called vmd.
+
+config PCI_LOONGSON
+       bool "LOONGSON PCIe controller"
+       depends on MACH_LOONGSON64 || COMPILE_TEST
+       depends on OF || ACPI
+       depends on PCI_QUIRKS
+       default MACH_LOONGSON64
+       help
+         Say Y here if you want to enable PCI controller support on
+         Loongson systems.
+
+config PCI_MVEBU
+       tristate "Marvell EBU PCIe controller"
+       depends on ARCH_MVEBU || ARCH_DOVE || COMPILE_TEST
+       depends on MVEBU_MBUS
+       depends on ARM
        depends on OF
-       depends on PCI_ENDPOINT
-       select MFD_SYSCON
-       select PCIE_ROCKCHIP
+       depends on BROKEN
+       select PCI_BRIDGE_EMUL
        help
-         Say Y here if you want to support Rockchip PCIe controller in
-         endpoint mode on Rockchip SoC. There is 1 internal PCIe port
-         available to support GEN2 with 4 slots.
+        Add support for Marvell EBU PCIe controller. This PCIe controller
+        is used on 32-bit Marvell ARM SoCs: Dove, Kirkwood, Armada 370,
+        Armada XP, Armada 375, Armada 38x and Armada 39x.
 
 config PCIE_MEDIATEK
        tristate "MediaTek PCIe controller"
@@ -258,91 +208,142 @@ config PCIE_MEDIATEK_GEN3
          Say Y here if you want to enable Gen3 PCIe controller support on
          MediaTek SoCs.
 
-config VMD
-       depends on PCI_MSI && X86_64 && !UML
-       tristate "Intel Volume Management Device Driver"
+config PCIE_MT7621
+       tristate "MediaTek MT7621 PCIe controller"
+       depends on SOC_MT7621 || COMPILE_TEST
+       select PHY_MT7621_PCI
+       default SOC_MT7621
        help
-         Adds support for the Intel Volume Management Device (VMD). VMD is a
-         secondary PCI host bridge that allows PCI Express root ports,
-         and devices attached to them, to be removed from the default
-         PCI domain and placed within the VMD domain. This provides
-         more bus resources than are otherwise possible with a
-         single domain. If you know your system provides one of these and
-         has devices attached to it, say Y; if you are not sure, say N.
-
-         To compile this driver as a module, choose M here: the
-         module will be called vmd.
+         This selects a driver for the MediaTek MT7621 PCIe Controller.
 
-config PCIE_BRCMSTB
-       tristate "Broadcom Brcmstb PCIe host controller"
-       depends on ARCH_BRCMSTB || ARCH_BCM2835 || ARCH_BCMBCA || \
-                  BMIPS_GENERIC || COMPILE_TEST
-       depends on OF
-       depends on PCI_MSI
-       default ARCH_BRCMSTB || BMIPS_GENERIC
+config PCIE_MICROCHIP_HOST
+       bool "Microchip AXI PCIe controller"
+       depends on PCI_MSI && OF
+       select PCI_HOST_COMMON
        help
-         Say Y here to enable PCIe host controller support for
-         Broadcom STB based SoCs, like the Raspberry Pi 4.
+         Say Y here if you want kernel to support the Microchip AXI PCIe
+         Host Bridge driver.
 
 config PCI_HYPERV_INTERFACE
-       tristate "Hyper-V PCI Interface"
+       tristate "Microsoft Hyper-V PCI Interface"
        depends on ((X86 && X86_64) || ARM64) && HYPERV && PCI_MSI
        help
-         The Hyper-V PCI Interface is a helper driver allows other drivers to
-         have a common interface with the Hyper-V PCI frontend driver.
+         The Hyper-V PCI Interface is a helper driver that allows other
+         drivers to have a common interface with the Hyper-V PCI frontend
+         driver.
 
-config PCI_LOONGSON
-       bool "LOONGSON PCI Controller"
-       depends on MACH_LOONGSON64 || COMPILE_TEST
-       depends on OF || ACPI
-       depends on PCI_QUIRKS
-       default MACH_LOONGSON64
+config PCI_TEGRA
+       bool "NVIDIA Tegra PCIe controller"
+       depends on ARCH_TEGRA || COMPILE_TEST
+       depends on PCI_MSI
        help
-         Say Y here if you want to enable PCI controller support on
-         Loongson systems.
+         Say Y here if you want support for the PCIe host controller found
+         on NVIDIA Tegra SoCs.
 
-config PCIE_MICROCHIP_HOST
-       bool "Microchip AXI PCIe host bridge support"
-       depends on PCI_MSI && OF
-       select PCI_HOST_COMMON
+config PCIE_RCAR_HOST
+       bool "Renesas R-Car PCIe controller (host mode)"
+       depends on ARCH_RENESAS || COMPILE_TEST
+       depends on PCI_MSI
        help
-         Say Y here if you want kernel to support the Microchip AXI PCIe
-         Host Bridge driver.
+         Say Y here if you want PCIe controller support on R-Car SoCs in host
+         mode.
 
-config PCIE_HISI_ERR
-       depends on ACPI_APEI_GHES && (ARM64 || COMPILE_TEST)
-       bool "HiSilicon HIP PCIe controller error handling driver"
+config PCIE_RCAR_EP
+       bool "Renesas R-Car PCIe controller (endpoint mode)"
+       depends on ARCH_RENESAS || COMPILE_TEST
+       depends on PCI_ENDPOINT
        help
-         Say Y here if you want error handling support
-         for the PCIe controller's errors on HiSilicon HIP SoCs
+         Say Y here if you want PCIe controller support on R-Car SoCs in
+         endpoint mode.
 
-config PCIE_APPLE_MSI_DOORBELL_ADDR
-       hex
-       default 0xfffff000
-       depends on PCIE_APPLE
+config PCI_RCAR_GEN2
+       bool "Renesas R-Car Gen2 Internal PCI controller"
+       depends on ARCH_RENESAS || COMPILE_TEST
+       depends on ARM
+       help
+         Say Y here if you want internal PCI support on R-Car Gen2 SoC.
+         There are 3 internal PCI controllers available with a single
+         built-in EHCI/OHCI host controller present on each one.
 
-config PCIE_APPLE
-       tristate "Apple PCIe controller"
-       depends on ARCH_APPLE || COMPILE_TEST
+config PCIE_ROCKCHIP
+       bool
+       depends on PCI
+
+config PCIE_ROCKCHIP_HOST
+       tristate "Rockchip PCIe controller (host mode)"
+       depends on ARCH_ROCKCHIP || COMPILE_TEST
        depends on OF
        depends on PCI_MSI
-       select PCI_HOST_COMMON
+       select MFD_SYSCON
+       select PCIE_ROCKCHIP
        help
-         Say Y here if you want to enable PCIe controller support on Apple
-         system-on-chips, like the Apple M1. This is required for the USB
-         type-A ports, Ethernet, Wi-Fi, and Bluetooth.
+         Say Y here if you want internal PCI support on Rockchip SoC.
+         There is 1 internal PCIe port available to support GEN2 with
+         4 slots.
 
-         If unsure, say Y if you have an Apple Silicon system.
+config PCIE_ROCKCHIP_EP
+       bool "Rockchip PCIe controller (endpoint mode)"
+       depends on ARCH_ROCKCHIP || COMPILE_TEST
+       depends on OF
+       depends on PCI_ENDPOINT
+       select MFD_SYSCON
+       select PCIE_ROCKCHIP
+       help
+         Say Y here if you want to support Rockchip PCIe controller in
+         endpoint mode on Rockchip SoC. There is 1 internal PCIe port
+         available to support GEN2 with 4 slots.
 
-config PCIE_MT7621
-       tristate "MediaTek MT7621 PCIe Controller"
-       depends on SOC_MT7621 || COMPILE_TEST
-       select PHY_MT7621_PCI
-       default SOC_MT7621
+config PCI_V3_SEMI
+       bool "V3 Semiconductor PCI controller"
+       depends on OF
+       depends on ARM || COMPILE_TEST
+       default ARCH_INTEGRATOR_AP
+
+config PCI_XGENE
+       bool "X-Gene PCIe controller"
+       depends on ARM64 || COMPILE_TEST
+       depends on OF || (ACPI && PCI_QUIRKS)
        help
-         This selects a driver for the MediaTek MT7621 PCIe Controller.
+         Say Y here if you want internal PCI support on APM X-Gene SoC.
+         There are 5 internal PCIe ports available. Each port is GEN3 capable
+         and have varied lanes from x1 to x8.
+
+config PCI_XGENE_MSI
+       bool "X-Gene v1 PCIe MSI feature"
+       depends on PCI_XGENE
+       depends on PCI_MSI
+       default y
+       help
+         Say Y here if you want PCIe MSI support for the APM X-Gene v1 SoC.
+         This MSI driver supports 5 PCIe ports on the APM X-Gene v1 SoC.
+
+config PCIE_XILINX
+       bool "Xilinx AXI PCIe controller"
+       depends on OF
+       depends on PCI_MSI
+       help
+         Say 'Y' here if you want kernel to support the Xilinx AXI PCIe
+         Host Bridge driver.
+
+config PCIE_XILINX_NWL
+       bool "Xilinx NWL PCIe controller"
+       depends on ARCH_ZYNQMP || COMPILE_TEST
+       depends on PCI_MSI
+       help
+        Say 'Y' here if you want kernel support for Xilinx
+        NWL PCIe controller. The controller can act as Root Port
+        or End Point. The current option selection will only
+        support root port enabling.
+
+config PCIE_XILINX_CPM
+       bool "Xilinx Versal CPM PCI controller"
+       depends on ARCH_ZYNQMP || COMPILE_TEST
+       select PCI_HOST_COMMON
+       help
+         Say 'Y' here if you want kernel support for the
+         Xilinx Versal CPM host bridge.
 
+source "drivers/pci/controller/cadence/Kconfig"
 source "drivers/pci/controller/dwc/Kconfig"
 source "drivers/pci/controller/mobiveil/Kconfig"
-source "drivers/pci/controller/cadence/Kconfig"
 endmenu
index 5d30564190e1f4a456106d04e6ff998843320b90..291d127113632040ae7991998129973a8ddb1a9c 100644 (file)
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-menu "Cadence PCIe controllers support"
+menu "Cadence-based PCIe controllers"
        depends on PCI
 
 config PCIE_CADENCE
@@ -22,7 +22,7 @@ config PCIE_CADENCE_PLAT
        bool
 
 config PCIE_CADENCE_PLAT_HOST
-       bool "Cadence PCIe platform host controller"
+       bool "Cadence platform PCIe controller (host mode)"
        depends on OF
        select PCIE_CADENCE_HOST
        select PCIE_CADENCE_PLAT
@@ -32,7 +32,7 @@ config PCIE_CADENCE_PLAT_HOST
          vendors SoCs.
 
 config PCIE_CADENCE_PLAT_EP
-       bool "Cadence PCIe platform endpoint controller"
+       bool "Cadence platform PCIe controller (endpoint mode)"
        depends on OF
        depends on PCI_ENDPOINT
        select PCIE_CADENCE_EP
@@ -46,7 +46,7 @@ config PCI_J721E
        bool
 
 config PCI_J721E_HOST
-       bool "TI J721E PCIe platform host controller"
+       bool "TI J721E PCIe controller (host mode)"
        depends on OF
        select PCIE_CADENCE_HOST
        select PCI_J721E
@@ -56,7 +56,7 @@ config PCI_J721E_HOST
          core.
 
 config PCI_J721E_EP
-       bool "TI J721E PCIe platform endpoint controller"
+       bool "TI J721E PCIe controller (endpoint mode)"
        depends on OF
        depends on PCI_ENDPOINT
        select PCIE_CADENCE_EP
index 434f6a4f404114c995be47011621b8963657a598..ab96da43e0c2edd5b69eacd40496d4d7dced48a2 100644 (file)
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-menu "DesignWare PCI Core Support"
+menu "DesignWare-based PCIe controllers"
        depends on PCI
 
 config PCIE_DW
@@ -14,88 +14,67 @@ config PCIE_DW_EP
        bool
        select PCIE_DW
 
-config PCI_DRA7XX
-       tristate
-
-config PCI_DRA7XX_HOST
-       tristate "TI DRA7xx PCIe controller Host Mode"
-       depends on SOC_DRA7XX || COMPILE_TEST
-       depends on OF && HAS_IOMEM && TI_PIPE3
+config PCIE_AL
+       bool "Amazon Annapurna Labs PCIe controller"
+       depends on OF && (ARM64 || COMPILE_TEST)
        depends on PCI_MSI
        select PCIE_DW_HOST
-       select PCI_DRA7XX
-       default y if SOC_DRA7XX
+       select PCI_ECAM
        help
-         Enables support for the PCIe controller in the DRA7xx SoC to work in
-         host mode. There are two instances of PCIe controller in DRA7xx.
-         This controller can work either as EP or RC. In order to enable
-         host-specific features PCI_DRA7XX_HOST must be selected and in order
-         to enable device-specific features PCI_DRA7XX_EP must be selected.
-         This uses the DesignWare core.
+         Say Y here to enable support of the Amazon's Annapurna Labs PCIe
+         controller IP on Amazon SoCs. The PCIe controller uses the DesignWare
+         core plus Annapurna Labs proprietary hardware wrappers. This is
+         required only for DT-based platforms. ACPI platforms with the
+         Annapurna Labs PCIe controller don't need to enable this.
 
-config PCI_DRA7XX_EP
-       tristate "TI DRA7xx PCIe controller Endpoint Mode"
-       depends on SOC_DRA7XX || COMPILE_TEST
-       depends on OF && HAS_IOMEM && TI_PIPE3
-       depends on PCI_ENDPOINT
-       select PCIE_DW_EP
-       select PCI_DRA7XX
+config PCI_MESON
+       tristate "Amlogic Meson PCIe controller"
+       default m if ARCH_MESON
+       depends on PCI_MSI
+       select PCIE_DW_HOST
        help
-         Enables support for the PCIe controller in the DRA7xx SoC to work in
-         endpoint mode. There are two instances of PCIe controller in DRA7xx.
-         This controller can work either as EP or RC. In order to enable
-         host-specific features PCI_DRA7XX_HOST must be selected and in order
-         to enable device-specific features PCI_DRA7XX_EP must be selected.
-         This uses the DesignWare core.
+         Say Y here if you want to enable PCI controller support on Amlogic
+         SoCs. The PCI controller on Amlogic is based on DesignWare hardware
+         and therefore the driver re-uses the DesignWare core functions to
+         implement the driver.
 
-config PCIE_DW_PLAT
+config PCIE_ARTPEC6
        bool
 
-config PCIE_DW_PLAT_HOST
-       bool "Platform bus based DesignWare PCIe Controller - Host mode"
+config PCIE_ARTPEC6_HOST
+       bool "Axis ARTPEC-6 PCIe controller (host mode)"
+       depends on MACH_ARTPEC6 || COMPILE_TEST
        depends on PCI_MSI
        select PCIE_DW_HOST
-       select PCIE_DW_PLAT
+       select PCIE_ARTPEC6
        help
-         Enables support for the PCIe controller in the Designware IP to
-         work in host mode. There are two instances of PCIe controller in
-         Designware IP.
-         This controller can work either as EP or RC. In order to enable
-         host-specific features PCIE_DW_PLAT_HOST must be selected and in
-         order to enable device-specific features PCI_DW_PLAT_EP must be
-         selected.
+         Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
+         host mode. This uses the DesignWare core.
 
-config PCIE_DW_PLAT_EP
-       bool "Platform bus based DesignWare PCIe Controller - Endpoint mode"
-       depends on PCI && PCI_MSI
+config PCIE_ARTPEC6_EP
+       bool "Axis ARTPEC-6 PCIe controller (endpoint mode)"
+       depends on MACH_ARTPEC6 || COMPILE_TEST
        depends on PCI_ENDPOINT
        select PCIE_DW_EP
-       select PCIE_DW_PLAT
+       select PCIE_ARTPEC6
        help
-         Enables support for the PCIe controller in the Designware IP to
-         work in endpoint mode. There are two instances of PCIe controller
-         in Designware IP.
-         This controller can work either as EP or RC. In order to enable
-         host-specific features PCIE_DW_PLAT_HOST must be selected and in
-         order to enable device-specific features PCI_DW_PLAT_EP must be
-         selected.
+         Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
+         endpoint mode. This uses the DesignWare core.
 
-config PCI_EXYNOS
-       tristate "Samsung Exynos PCIe controller"
-       depends on ARCH_EXYNOS || COMPILE_TEST
+config PCIE_BT1
+       tristate "Baikal-T1 PCIe controller"
+       depends on MIPS_BAIKAL_T1 || COMPILE_TEST
        depends on PCI_MSI
        select PCIE_DW_HOST
        help
-         Enables support for the PCIe controller in the Samsung Exynos SoCs
-         to work in host mode. The PCI controller is based on the DesignWare
-         hardware and therefore the driver re-uses the DesignWare core
-         functions to implement the driver.
+         Enables support for the PCIe controller in the Baikal-T1 SoC to work
+         in host mode. It's based on the Synopsys DWC PCIe v4.60a IP-core.
 
 config PCI_IMX6
        bool
 
 config PCI_IMX6_HOST
-       bool "Freescale i.MX6/7/8 PCIe controller host mode"
+       bool "Freescale i.MX6/7/8 PCIe controller (host mode)"
        depends on ARCH_MXC || COMPILE_TEST
        depends on PCI_MSI
        select PCIE_DW_HOST
@@ -107,7 +86,7 @@ config PCI_IMX6_HOST
          DesignWare core functions to implement the driver.
 
 config PCI_IMX6_EP
-       bool "Freescale i.MX6/7/8 PCIe controller endpoint mode"
+       bool "Freescale i.MX6/7/8 PCIe controller (endpoint mode)"
        depends on ARCH_MXC || COMPILE_TEST
        depends on PCI_ENDPOINT
        select PCIE_DW_EP
@@ -118,43 +97,8 @@ config PCI_IMX6_EP
          on DesignWare hardware and therefore the driver re-uses the
          DesignWare core functions to implement the driver.
 
-config PCIE_SPEAR13XX
-       bool "STMicroelectronics SPEAr PCIe controller"
-       depends on ARCH_SPEAR13XX || COMPILE_TEST
-       depends on PCI_MSI
-       select PCIE_DW_HOST
-       help
-         Say Y here if you want PCIe support on SPEAr13XX SoCs.
-
-config PCI_KEYSTONE
-       bool
-
-config PCI_KEYSTONE_HOST
-       bool "PCI Keystone Host Mode"
-       depends on ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST
-       depends on PCI_MSI
-       select PCIE_DW_HOST
-       select PCI_KEYSTONE
-       help
-         Enables support for the PCIe controller in the Keystone SoC to
-         work in host mode. The PCI controller on Keystone is based on
-         DesignWare hardware and therefore the driver re-uses the
-         DesignWare core functions to implement the driver.
-
-config PCI_KEYSTONE_EP
-       bool "PCI Keystone Endpoint Mode"
-       depends on ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST
-       depends on PCI_ENDPOINT
-       select PCIE_DW_EP
-       select PCI_KEYSTONE
-       help
-         Enables support for the PCIe controller in the Keystone SoC to
-         work in endpoint mode. The PCI controller on Keystone is based
-         on DesignWare hardware and therefore the driver re-uses the
-         DesignWare core functions to implement the driver.
-
 config PCI_LAYERSCAPE
-       bool "Freescale Layerscape PCIe controller - Host mode"
+       bool "Freescale Layerscape PCIe controller (host mode)"
        depends on OF && (ARM || ARCH_LAYERSCAPE || COMPILE_TEST)
        depends on PCI_MSI
        select PCIE_DW_HOST
@@ -167,7 +111,7 @@ config PCI_LAYERSCAPE
          controller works in RC mode.
 
 config PCI_LAYERSCAPE_EP
-       bool "Freescale Layerscape PCIe controller - Endpoint mode"
+       bool "Freescale Layerscape PCIe controller (endpoint mode)"
        depends on OF && (ARM || ARCH_LAYERSCAPE || COMPILE_TEST)
        depends on PCI_ENDPOINT
        select PCIE_DW_EP
@@ -180,7 +124,7 @@ config PCI_LAYERSCAPE_EP
 
 config PCI_HISI
        depends on OF && (ARM64 || COMPILE_TEST)
-       bool "HiSilicon Hip05 and Hip06 SoCs PCIe controllers"
+       bool "HiSilicon Hip05 and Hip06 SoCs PCIe controller"
        depends on PCI_MSI
        select PCIE_DW_HOST
        select PCI_HOST_COMMON
@@ -188,83 +132,26 @@ config PCI_HISI
          Say Y here if you want PCIe controller support on HiSilicon
          Hip05 and Hip06 SoCs
 
-config PCIE_QCOM
-       bool "Qualcomm PCIe controller"
-       depends on OF && (ARCH_QCOM || COMPILE_TEST)
-       depends on PCI_MSI
-       select PCIE_DW_HOST
-       select CRC8
-       help
-         Say Y here to enable PCIe controller support on Qualcomm SoCs. The
-         PCIe controller uses the DesignWare core plus Qualcomm-specific
-         hardware wrappers.
-
-config PCIE_QCOM_EP
-       tristate "Qualcomm PCIe controller - Endpoint mode"
-       depends on OF && (ARCH_QCOM || COMPILE_TEST)
-       depends on PCI_ENDPOINT
-       select PCIE_DW_EP
-       help
-         Say Y here to enable support for the PCIe controllers on Qualcomm SoCs
-         to work in endpoint mode. The PCIe controller uses the DesignWare core
-         plus Qualcomm-specific hardware wrappers.
-
-config PCIE_ARMADA_8K
-       bool "Marvell Armada-8K PCIe controller"
-       depends on ARCH_MVEBU || COMPILE_TEST
-       depends on PCI_MSI
-       select PCIE_DW_HOST
-       help
-         Say Y here if you want to enable PCIe controller support on
-         Armada-8K SoCs. The PCIe controller on Armada-8K is based on
-         DesignWare hardware and therefore the driver re-uses the
-         DesignWare core functions to implement the driver.
-
-config PCIE_ARTPEC6
-       bool
-
-config PCIE_ARTPEC6_HOST
-       bool "Axis ARTPEC-6 PCIe controller Host Mode"
-       depends on MACH_ARTPEC6 || COMPILE_TEST
+config PCIE_KIRIN
+       depends on OF && (ARM64 || COMPILE_TEST)
+       tristate "HiSilicon Kirin PCIe controller"
        depends on PCI_MSI
        select PCIE_DW_HOST
-       select PCIE_ARTPEC6
-       help
-         Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
-         host mode. This uses the DesignWare core.
-
-config PCIE_ARTPEC6_EP
-       bool "Axis ARTPEC-6 PCIe controller Endpoint Mode"
-       depends on MACH_ARTPEC6 || COMPILE_TEST
-       depends on PCI_ENDPOINT
-       select PCIE_DW_EP
-       select PCIE_ARTPEC6
+       select REGMAP_MMIO
        help
-         Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
-         endpoint mode. This uses the DesignWare core.
+         Say Y here if you want PCIe controller support
+         on HiSilicon Kirin series SoCs.
 
-config PCIE_BT1
-       tristate "Baikal-T1 PCIe controller"
-       depends on MIPS_BAIKAL_T1 || COMPILE_TEST
+config PCIE_HISI_STB
+       bool "HiSilicon STB PCIe controller"
+       depends on ARCH_HISI || COMPILE_TEST
        depends on PCI_MSI
        select PCIE_DW_HOST
        help
-         Enables support for the PCIe controller in the Baikal-T1 SoC to work
-         in host mode. It's based on the Synopsys DWC PCIe v4.60a IP-core.
-
-config PCIE_ROCKCHIP_DW_HOST
-       bool "Rockchip DesignWare PCIe controller"
-       select PCIE_DW
-       select PCIE_DW_HOST
-       depends on PCI_MSI
-       depends on ARCH_ROCKCHIP || COMPILE_TEST
-       depends on OF
-       help
-         Enables support for the DesignWare PCIe controller in the
-         Rockchip SoC except RK3399.
+         Say Y here if you want PCIe controller support on HiSilicon STB SoCs
 
 config PCIE_INTEL_GW
-       bool "Intel Gateway PCIe host controller support"
+       bool "Intel Gateway PCIe controller "
        depends on OF && (X86 || COMPILE_TEST)
        depends on PCI_MSI
        select PCIE_DW_HOST
@@ -278,7 +165,7 @@ config PCIE_KEEMBAY
        bool
 
 config PCIE_KEEMBAY_HOST
-       bool "Intel Keem Bay PCIe controller - Host mode"
+       bool "Intel Keem Bay PCIe controller (host mode)"
        depends on ARCH_KEEMBAY || COMPILE_TEST
        depends on PCI_MSI
        select PCIE_DW_HOST
@@ -290,7 +177,7 @@ config PCIE_KEEMBAY_HOST
          DesignWare core functions.
 
 config PCIE_KEEMBAY_EP
-       bool "Intel Keem Bay PCIe controller - Endpoint mode"
+       bool "Intel Keem Bay PCIe controller (endpoint mode)"
        depends on ARCH_KEEMBAY || COMPILE_TEST
        depends on PCI_MSI
        depends on PCI_ENDPOINT
@@ -302,39 +189,22 @@ config PCIE_KEEMBAY_EP
          The PCIe controller is based on DesignWare Hardware and uses
          DesignWare core functions.
 
-config PCIE_KIRIN
-       depends on OF && (ARM64 || COMPILE_TEST)
-       tristate "HiSilicon Kirin series SoCs PCIe controllers"
-       depends on PCI_MSI
-       select PCIE_DW_HOST
-       help
-         Say Y here if you want PCIe controller support
-         on HiSilicon Kirin series SoCs.
-
-config PCIE_HISI_STB
-       bool "HiSilicon STB SoCs PCIe controllers"
-       depends on ARCH_HISI || COMPILE_TEST
-       depends on PCI_MSI
-       select PCIE_DW_HOST
-       help
-         Say Y here if you want PCIe controller support on HiSilicon STB SoCs
-
-config PCI_MESON
-       tristate "MESON PCIe controller"
-       default m if ARCH_MESON
+config PCIE_ARMADA_8K
+       bool "Marvell Armada-8K PCIe controller"
+       depends on ARCH_MVEBU || COMPILE_TEST
        depends on PCI_MSI
        select PCIE_DW_HOST
        help
-         Say Y here if you want to enable PCI controller support on Amlogic
-         SoCs. The PCI controller on Amlogic is based on DesignWare hardware
-         and therefore the driver re-uses the DesignWare core functions to
-         implement the driver.
+         Say Y here if you want to enable PCIe controller support on
+         Armada-8K SoCs. The PCIe controller on Armada-8K is based on
+         DesignWare hardware and therefore the driver re-uses the
+         DesignWare core functions to implement the driver.
 
 config PCIE_TEGRA194
        tristate
 
 config PCIE_TEGRA194_HOST
-       tristate "NVIDIA Tegra194 (and later) PCIe controller - Host Mode"
+       tristate "NVIDIA Tegra194 (and later) PCIe controller (host mode)"
        depends on ARCH_TEGRA_194_SOC || COMPILE_TEST
        depends on PCI_MSI
        select PCIE_DW_HOST
@@ -349,7 +219,7 @@ config PCIE_TEGRA194_HOST
          selected. This uses the DesignWare core.
 
 config PCIE_TEGRA194_EP
-       tristate "NVIDIA Tegra194 (and later) PCIe controller - Endpoint Mode"
+       tristate "NVIDIA Tegra194 (and later) PCIe controller (endpoint mode)"
        depends on ARCH_TEGRA_194_SOC || COMPILE_TEST
        depends on PCI_ENDPOINT
        select PCIE_DW_EP
@@ -363,17 +233,92 @@ config PCIE_TEGRA194_EP
          in order to enable device-specific features PCIE_TEGRA194_EP must be
          selected. This uses the DesignWare core.
 
-config PCIE_VISCONTI_HOST
-       bool "Toshiba Visconti PCIe controllers"
-       depends on ARCH_VISCONTI || COMPILE_TEST
+config PCIE_DW_PLAT
+       bool
+
+config PCIE_DW_PLAT_HOST
+       bool "Platform bus based DesignWare PCIe controller (host mode)"
        depends on PCI_MSI
        select PCIE_DW_HOST
+       select PCIE_DW_PLAT
        help
-         Say Y here if you want PCIe controller support on Toshiba Visconti SoC.
-         This driver supports TMPV7708 SoC.
+         Enables support for the PCIe controller in the Designware IP to
+         work in host mode. There are two instances of PCIe controller in
+         Designware IP.
+         This controller can work either as EP or RC. In order to enable
+         host-specific features PCIE_DW_PLAT_HOST must be selected and in
+         order to enable device-specific features PCI_DW_PLAT_EP must be
+         selected.
+
+config PCIE_DW_PLAT_EP
+       bool "Platform bus based DesignWare PCIe controller (endpoint mode)"
+       depends on PCI && PCI_MSI
+       depends on PCI_ENDPOINT
+       select PCIE_DW_EP
+       select PCIE_DW_PLAT
+       help
+         Enables support for the PCIe controller in the Designware IP to
+         work in endpoint mode. There are two instances of PCIe controller
+         in Designware IP.
+         This controller can work either as EP or RC. In order to enable
+         host-specific features PCIE_DW_PLAT_HOST must be selected and in
+         order to enable device-specific features PCI_DW_PLAT_EP must be
+         selected.
+
+config PCIE_QCOM
+       bool "Qualcomm PCIe controller (host mode)"
+       depends on OF && (ARCH_QCOM || COMPILE_TEST)
+       depends on PCI_MSI
+       select PCIE_DW_HOST
+       select CRC8
+       help
+         Say Y here to enable PCIe controller support on Qualcomm SoCs. The
+         PCIe controller uses the DesignWare core plus Qualcomm-specific
+         hardware wrappers.
+
+config PCIE_QCOM_EP
+       tristate "Qualcomm PCIe controller (endpoint mode)"
+       depends on OF && (ARCH_QCOM || COMPILE_TEST)
+       depends on PCI_ENDPOINT
+       select PCIE_DW_EP
+       help
+         Say Y here to enable support for the PCIe controllers on Qualcomm SoCs
+         to work in endpoint mode. The PCIe controller uses the DesignWare core
+         plus Qualcomm-specific hardware wrappers.
+
+config PCIE_ROCKCHIP_DW_HOST
+       bool "Rockchip DesignWare PCIe controller"
+       select PCIE_DW
+       select PCIE_DW_HOST
+       depends on PCI_MSI
+       depends on ARCH_ROCKCHIP || COMPILE_TEST
+       depends on OF
+       help
+         Enables support for the DesignWare PCIe controller in the
+         Rockchip SoC except RK3399.
+
+config PCI_EXYNOS
+       tristate "Samsung Exynos PCIe controller"
+       depends on ARCH_EXYNOS || COMPILE_TEST
+       depends on PCI_MSI
+       select PCIE_DW_HOST
+       help
+         Enables support for the PCIe controller in the Samsung Exynos SoCs
+         to work in host mode. The PCI controller is based on the DesignWare
+         hardware and therefore the driver re-uses the DesignWare core
+         functions to implement the driver.
+
+config PCIE_FU740
+       bool "SiFive FU740 PCIe controller"
+       depends on PCI_MSI
+       depends on SOC_SIFIVE || COMPILE_TEST
+       select PCIE_DW_HOST
+       help
+         Say Y here if you want PCIe controller support for the SiFive
+         FU740.
 
 config PCIE_UNIPHIER
-       bool "Socionext UniPhier PCIe host controllers"
+       bool "Socionext UniPhier PCIe controller (host mode)"
        depends on ARCH_UNIPHIER || COMPILE_TEST
        depends on OF && HAS_IOMEM
        depends on PCI_MSI
@@ -383,7 +328,7 @@ config PCIE_UNIPHIER
          This driver supports LD20 and PXs3 SoCs.
 
 config PCIE_UNIPHIER_EP
-       bool "Socionext UniPhier PCIe endpoint controllers"
+       bool "Socionext UniPhier PCIe controller (endpoint mode)"
        depends on ARCH_UNIPHIER || COMPILE_TEST
        depends on OF && HAS_IOMEM
        depends on PCI_ENDPOINT
@@ -392,26 +337,82 @@ config PCIE_UNIPHIER_EP
          Say Y here if you want PCIe endpoint controller support on
          UniPhier SoCs. This driver supports Pro5 SoC.
 
-config PCIE_AL
-       bool "Amazon Annapurna Labs PCIe controller"
-       depends on OF && (ARM64 || COMPILE_TEST)
+config PCIE_SPEAR13XX
+       bool "STMicroelectronics SPEAr PCIe controller"
+       depends on ARCH_SPEAR13XX || COMPILE_TEST
        depends on PCI_MSI
        select PCIE_DW_HOST
-       select PCI_ECAM
        help
-         Say Y here to enable support of the Amazon's Annapurna Labs PCIe
-         controller IP on Amazon SoCs. The PCIe controller uses the DesignWare
-         core plus Annapurna Labs proprietary hardware wrappers. This is
-         required only for DT-based platforms. ACPI platforms with the
-         Annapurna Labs PCIe controller don't need to enable this.
+         Say Y here if you want PCIe support on SPEAr13XX SoCs.
 
-config PCIE_FU740
-       bool "SiFive FU740 PCIe host controller"
+config PCI_DRA7XX
+       tristate
+
+config PCI_DRA7XX_HOST
+       tristate "TI DRA7xx PCIe controller (host mode)"
+       depends on SOC_DRA7XX || COMPILE_TEST
+       depends on OF && HAS_IOMEM && TI_PIPE3
        depends on PCI_MSI
-       depends on SOC_SIFIVE || COMPILE_TEST
        select PCIE_DW_HOST
+       select PCI_DRA7XX
+       default y if SOC_DRA7XX
        help
-         Say Y here if you want PCIe controller support for the SiFive
-         FU740.
+         Enables support for the PCIe controller in the DRA7xx SoC to work in
+         host mode. There are two instances of PCIe controller in DRA7xx.
+         This controller can work either as EP or RC. In order to enable
+         host-specific features PCI_DRA7XX_HOST must be selected and in order
+         to enable device-specific features PCI_DRA7XX_EP must be selected.
+         This uses the DesignWare core.
+
+config PCI_DRA7XX_EP
+       tristate "TI DRA7xx PCIe controller (endpoint mode)"
+       depends on SOC_DRA7XX || COMPILE_TEST
+       depends on OF && HAS_IOMEM && TI_PIPE3
+       depends on PCI_ENDPOINT
+       select PCIE_DW_EP
+       select PCI_DRA7XX
+       help
+         Enables support for the PCIe controller in the DRA7xx SoC to work in
+         endpoint mode. There are two instances of PCIe controller in DRA7xx.
+         This controller can work either as EP or RC. In order to enable
+         host-specific features PCI_DRA7XX_HOST must be selected and in order
+         to enable device-specific features PCI_DRA7XX_EP must be selected.
+         This uses the DesignWare core.
+
+config PCI_KEYSTONE
+       bool
+
+config PCI_KEYSTONE_HOST
+       bool "TI Keystone PCIe controller (host mode)"
+       depends on ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST
+       depends on PCI_MSI
+       select PCIE_DW_HOST
+       select PCI_KEYSTONE
+       help
+         Enables support for the PCIe controller in the Keystone SoC to
+         work in host mode. The PCI controller on Keystone is based on
+         DesignWare hardware and therefore the driver re-uses the
+         DesignWare core functions to implement the driver.
+
+config PCI_KEYSTONE_EP
+       bool "TI Keystone PCIe controller (endpoint mode)"
+       depends on ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST
+       depends on PCI_ENDPOINT
+       select PCIE_DW_EP
+       select PCI_KEYSTONE
+       help
+         Enables support for the PCIe controller in the Keystone SoC to
+         work in endpoint mode. The PCI controller on Keystone is based
+         on DesignWare hardware and therefore the driver re-uses the
+         DesignWare core functions to implement the driver.
+
+config PCIE_VISCONTI_HOST
+       bool "Toshiba Visconti PCIe controller"
+       depends on ARCH_VISCONTI || COMPILE_TEST
+       depends on PCI_MSI
+       select PCIE_DW_HOST
+       help
+         Say Y here if you want PCIe controller support on Toshiba Visconti SoC.
+         This driver supports TMPV7708 SoC.
 
 endmenu
index 55a0405b921d685cfee9ec67f3e44d0e937cf78c..52906f999f2bb8fc20e0e216a23d585619281d8e 100644 (file)
@@ -1566,6 +1566,13 @@ DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_SYNOPSYS, 0xabcd,
 static int __init imx6_pcie_init(void)
 {
 #ifdef CONFIG_ARM
+       struct device_node *np;
+
+       np = of_find_matching_node(NULL, imx6_pcie_of_match);
+       if (!np)
+               return -ENODEV;
+       of_node_put(np);
+
        /*
         * Since probe() can be deferred we need to make sure that
         * hook_fault_code is not called after __init memory is freed
index ad99707b3b994f26da992e6ecb736518f2ae6553..c640db60edc6a597440d8ea44ec053f28d2213e5 100644 (file)
@@ -110,6 +110,7 @@ static const struct ls_pcie_ep_drvdata lx2_ep_drvdata = {
 };
 
 static const struct of_device_id ls_pcie_ep_of_match[] = {
+       { .compatible = "fsl,ls1028a-pcie-ep", .data = &ls1_ep_drvdata },
        { .compatible = "fsl,ls1046a-pcie-ep", .data = &ls1_ep_drvdata },
        { .compatible = "fsl,ls1088a-pcie-ep", .data = &ls2_ep_drvdata },
        { .compatible = "fsl,ls2088a-pcie-ep", .data = &ls2_ep_drvdata },
index a232b04af048c1ebb18d122e505523633d9f9742..4ab30892f6efbc70e8cf5b1f3475b9fed16cbccb 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/clk.h>
 #include <linux/crc8.h>
+#include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
 #include <linux/interconnect.h>
 #include "../../pci.h"
 #include "pcie-designware.h"
 
-#define PCIE20_PARF_SYS_CTRL                   0x00
+/* PARF registers */
+#define PARF_SYS_CTRL                          0x00
+#define PARF_PM_CTRL                           0x20
+#define PARF_PCS_DEEMPH                                0x34
+#define PARF_PCS_SWING                         0x38
+#define PARF_PHY_CTRL                          0x40
+#define PARF_PHY_REFCLK                                0x4c
+#define PARF_CONFIG_BITS                       0x50
+#define PARF_DBI_BASE_ADDR                     0x168
+#define PARF_SLV_ADDR_SPACE_SIZE_2_3_3         0x16c /* Register offset specific to IP ver 2.3.3 */
+#define PARF_MHI_CLOCK_RESET_CTRL              0x174
+#define PARF_AXI_MSTR_WR_ADDR_HALT             0x178
+#define PARF_AXI_MSTR_WR_ADDR_HALT_V2          0x1a8
+#define PARF_Q2A_FLUSH                         0x1ac
+#define PARF_LTSSM                             0x1b0
+#define PARF_SID_OFFSET                                0x234
+#define PARF_BDF_TRANSLATE_CFG                 0x24c
+#define PARF_SLV_ADDR_SPACE_SIZE               0x358
+#define PARF_DEVICE_TYPE                       0x1000
+#define PARF_BDF_TO_SID_TABLE_N                        0x2000
+
+/* ELBI registers */
+#define ELBI_SYS_CTRL                          0x04
+
+/* DBI registers */
+#define AXI_MSTR_RESP_COMP_CTRL0               0x818
+#define AXI_MSTR_RESP_COMP_CTRL1               0x81c
+#define MISC_CONTROL_1_REG                     0x8bc
+
+/* MHI registers */
+#define PARF_DEBUG_CNT_PM_LINKST_IN_L2         0xc04
+#define PARF_DEBUG_CNT_PM_LINKST_IN_L1         0xc0c
+#define PARF_DEBUG_CNT_PM_LINKST_IN_L0S                0xc10
+#define PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L1     0xc84
+#define PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L2     0xc88
+
+/* PARF_SYS_CTRL register fields */
+#define MAC_PHY_POWERDOWN_IN_P2_D_MUX_EN       BIT(29)
 #define MST_WAKEUP_EN                          BIT(13)
 #define SLV_WAKEUP_EN                          BIT(12)
 #define MSTR_ACLK_CGC_DIS                      BIT(10)
 #define L23_CLK_RMV_DIS                                BIT(2)
 #define L1_CLK_RMV_DIS                         BIT(1)
 
-#define PCIE20_PARF_PM_CTRL                    0x20
+/* PARF_PM_CTRL register fields */
 #define REQ_NOT_ENTR_L1                                BIT(5)
 
-#define PCIE20_PARF_PHY_CTRL                   0x40
+/* PARF_PCS_DEEMPH register fields */
+#define PCS_DEEMPH_TX_DEEMPH_GEN1(x)           FIELD_PREP(GENMASK(21, 16), x)
+#define PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x)     FIELD_PREP(GENMASK(13, 8), x)
+#define PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x)       FIELD_PREP(GENMASK(5, 0), x)
+
+/* PARF_PCS_SWING register fields */
+#define PCS_SWING_TX_SWING_FULL(x)             FIELD_PREP(GENMASK(14, 8), x)
+#define PCS_SWING_TX_SWING_LOW(x)              FIELD_PREP(GENMASK(6, 0), x)
+
+/* PARF_PHY_CTRL register fields */
 #define PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK      GENMASK(20, 16)
-#define PHY_CTRL_PHY_TX0_TERM_OFFSET(x)                ((x) << 16)
+#define PHY_CTRL_PHY_TX0_TERM_OFFSET(x)                FIELD_PREP(PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK, x)
+#define PHY_TEST_PWR_DOWN                      BIT(0)
 
-#define PCIE20_PARF_PHY_REFCLK                 0x4C
+/* PARF_PHY_REFCLK register fields */
 #define PHY_REFCLK_SSP_EN                      BIT(16)
 #define PHY_REFCLK_USE_PAD                     BIT(12)
 
-#define PCIE20_PARF_DBI_BASE_ADDR              0x168
-#define PCIE20_PARF_SLV_ADDR_SPACE_SIZE                0x16C
-#define PCIE20_PARF_MHI_CLOCK_RESET_CTRL       0x174
+/* PARF_CONFIG_BITS register fields */
+#define PHY_RX0_EQ(x)                          FIELD_PREP(GENMASK(26, 24), x)
+
+/* PARF_SLV_ADDR_SPACE_SIZE register value */
+#define SLV_ADDR_SPACE_SZ                      0x10000000
+
+/* PARF_MHI_CLOCK_RESET_CTRL register fields */
 #define AHB_CLK_EN                             BIT(0)
 #define MSTR_AXI_CLK_EN                                BIT(1)
 #define BYPASS                                 BIT(4)
 
-#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT      0x178
-#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2   0x1A8
-#define PCIE20_PARF_LTSSM                      0x1B0
-#define PCIE20_PARF_SID_OFFSET                 0x234
-#define PCIE20_PARF_BDF_TRANSLATE_CFG          0x24C
-#define PCIE20_PARF_DEVICE_TYPE                        0x1000
-#define PCIE20_PARF_BDF_TO_SID_TABLE_N         0x2000
+/* PARF_AXI_MSTR_WR_ADDR_HALT register fields */
+#define EN                                     BIT(31)
+
+/* PARF_LTSSM register fields */
+#define LTSSM_EN                               BIT(8)
 
-#define PCIE20_ELBI_SYS_CTRL                   0x04
-#define PCIE20_ELBI_SYS_CTRL_LT_ENABLE         BIT(0)
+/* PARF_DEVICE_TYPE register fields */
+#define DEVICE_TYPE_RC                         0x4
+
+/* ELBI_SYS_CTRL register fields */
+#define ELBI_SYS_CTRL_LT_ENABLE                        BIT(0)
 
-#define PCIE20_AXI_MSTR_RESP_COMP_CTRL0                0x818
+/* AXI_MSTR_RESP_COMP_CTRL0 register fields */
 #define CFG_REMOTE_RD_REQ_BRIDGE_SIZE_2K       0x4
 #define CFG_REMOTE_RD_REQ_BRIDGE_SIZE_4K       0x5
-#define PCIE20_AXI_MSTR_RESP_COMP_CTRL1                0x81c
+
+/* AXI_MSTR_RESP_COMP_CTRL1 register fields */
 #define CFG_BRIDGE_SB_INIT                     BIT(0)
 
-#define PCIE_CAP_SLOT_POWER_LIMIT_VAL          FIELD_PREP(PCI_EXP_SLTCAP_SPLV, \
-                                               250)
-#define PCIE_CAP_SLOT_POWER_LIMIT_SCALE                FIELD_PREP(PCI_EXP_SLTCAP_SPLS, \
-                                               1)
+/* MISC_CONTROL_1_REG register fields */
+#define DBI_RO_WR_EN                           1
+
+/* PCI_EXP_SLTCAP register fields */
+#define PCIE_CAP_SLOT_POWER_LIMIT_VAL          FIELD_PREP(PCI_EXP_SLTCAP_SPLV, 250)
+#define PCIE_CAP_SLOT_POWER_LIMIT_SCALE                FIELD_PREP(PCI_EXP_SLTCAP_SPLS, 1)
 #define PCIE_CAP_SLOT_VAL                      (PCI_EXP_SLTCAP_ABP | \
                                                PCI_EXP_SLTCAP_PCP | \
                                                PCI_EXP_SLTCAP_MRLSP | \
                                                PCIE_CAP_SLOT_POWER_LIMIT_VAL | \
                                                PCIE_CAP_SLOT_POWER_LIMIT_SCALE)
 
-#define PCIE20_PARF_Q2A_FLUSH                  0x1AC
-
-#define PCIE20_MISC_CONTROL_1_REG              0x8BC
-#define DBI_RO_WR_EN                           1
-
 #define PERST_DELAY_US                         1000
-/* PARF registers */
-#define PCIE20_PARF_PCS_DEEMPH                 0x34
-#define PCS_DEEMPH_TX_DEEMPH_GEN1(x)           ((x) << 16)
-#define PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x)     ((x) << 8)
-#define PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x)       ((x) << 0)
 
-#define PCIE20_PARF_PCS_SWING                  0x38
-#define PCS_SWING_TX_SWING_FULL(x)             ((x) << 8)
-#define PCS_SWING_TX_SWING_LOW(x)              ((x) << 0)
+#define QCOM_PCIE_CRC8_POLYNOMIAL              (BIT(2) | BIT(1) | BIT(0))
 
-#define PCIE20_PARF_CONFIG_BITS                0x50
-#define PHY_RX0_EQ(x)                          ((x) << 24)
-
-#define PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE     0x358
-#define SLV_ADDR_SPACE_SZ                      0x10000000
-
-#define PCIE20_LNK_CONTROL2_LINK_STATUS2       0xa0
-
-#define DEVICE_TYPE_RC                         0x4
-
-#define QCOM_PCIE_2_1_0_MAX_SUPPLY     3
-#define QCOM_PCIE_2_1_0_MAX_CLOCKS     5
-
-#define QCOM_PCIE_CRC8_POLYNOMIAL (BIT(2) | BIT(1) | BIT(0))
+#define QCOM_PCIE_1_0_0_MAX_CLOCKS             4
+struct qcom_pcie_resources_1_0_0 {
+       struct clk_bulk_data clks[QCOM_PCIE_1_0_0_MAX_CLOCKS];
+       struct reset_control *core;
+       struct regulator *vdda;
+};
 
+#define QCOM_PCIE_2_1_0_MAX_CLOCKS             5
+#define QCOM_PCIE_2_1_0_MAX_RESETS             6
+#define QCOM_PCIE_2_1_0_MAX_SUPPLY             3
 struct qcom_pcie_resources_2_1_0 {
        struct clk_bulk_data clks[QCOM_PCIE_2_1_0_MAX_CLOCKS];
-       struct reset_control *pci_reset;
-       struct reset_control *axi_reset;
-       struct reset_control *ahb_reset;
-       struct reset_control *por_reset;
-       struct reset_control *phy_reset;
-       struct reset_control *ext_reset;
+       struct reset_control_bulk_data resets[QCOM_PCIE_2_1_0_MAX_RESETS];
+       int num_resets;
        struct regulator_bulk_data supplies[QCOM_PCIE_2_1_0_MAX_SUPPLY];
 };
 
-struct qcom_pcie_resources_1_0_0 {
-       struct clk *iface;
-       struct clk *aux;
-       struct clk *master_bus;
-       struct clk *slave_bus;
-       struct reset_control *core;
-       struct regulator *vdda;
-};
-
-#define QCOM_PCIE_2_3_2_MAX_SUPPLY     2
+#define QCOM_PCIE_2_3_2_MAX_CLOCKS             4
+#define QCOM_PCIE_2_3_2_MAX_SUPPLY             2
 struct qcom_pcie_resources_2_3_2 {
-       struct clk *aux_clk;
-       struct clk *master_clk;
-       struct clk *slave_clk;
-       struct clk *cfg_clk;
+       struct clk_bulk_data clks[QCOM_PCIE_2_3_2_MAX_CLOCKS];
        struct regulator_bulk_data supplies[QCOM_PCIE_2_3_2_MAX_SUPPLY];
 };
 
-#define QCOM_PCIE_2_4_0_MAX_CLOCKS     4
+#define QCOM_PCIE_2_3_3_MAX_CLOCKS             5
+#define QCOM_PCIE_2_3_3_MAX_RESETS             7
+struct qcom_pcie_resources_2_3_3 {
+       struct clk_bulk_data clks[QCOM_PCIE_2_3_3_MAX_CLOCKS];
+       struct reset_control_bulk_data rst[QCOM_PCIE_2_3_3_MAX_RESETS];
+};
+
+#define QCOM_PCIE_2_4_0_MAX_CLOCKS             4
+#define QCOM_PCIE_2_4_0_MAX_RESETS             12
 struct qcom_pcie_resources_2_4_0 {
        struct clk_bulk_data clks[QCOM_PCIE_2_4_0_MAX_CLOCKS];
        int num_clks;
-       struct reset_control *axi_m_reset;
-       struct reset_control *axi_s_reset;
-       struct reset_control *pipe_reset;
-       struct reset_control *axi_m_vmid_reset;
-       struct reset_control *axi_s_xpu_reset;
-       struct reset_control *parf_reset;
-       struct reset_control *phy_reset;
-       struct reset_control *axi_m_sticky_reset;
-       struct reset_control *pipe_sticky_reset;
-       struct reset_control *pwr_reset;
-       struct reset_control *ahb_reset;
-       struct reset_control *phy_ahb_reset;
-};
-
-struct qcom_pcie_resources_2_3_3 {
-       struct clk *iface;
-       struct clk *axi_m_clk;
-       struct clk *axi_s_clk;
-       struct clk *ahb_clk;
-       struct clk *aux_clk;
-       struct reset_control *rst[7];
+       struct reset_control_bulk_data resets[QCOM_PCIE_2_4_0_MAX_RESETS];
+       int num_resets;
 };
 
-/* 6 clocks typically, 7 for sm8250 */
+#define QCOM_PCIE_2_7_0_MAX_CLOCKS             15
+#define QCOM_PCIE_2_7_0_MAX_SUPPLIES           2
 struct qcom_pcie_resources_2_7_0 {
-       struct clk_bulk_data clks[12];
+       struct clk_bulk_data clks[QCOM_PCIE_2_7_0_MAX_CLOCKS];
        int num_clks;
-       struct regulator_bulk_data supplies[2];
-       struct reset_control *pci_reset;
+       struct regulator_bulk_data supplies[QCOM_PCIE_2_7_0_MAX_SUPPLIES];
+       struct reset_control *rst;
 };
 
+#define QCOM_PCIE_2_9_0_MAX_CLOCKS             5
 struct qcom_pcie_resources_2_9_0 {
-       struct clk_bulk_data clks[5];
+       struct clk_bulk_data clks[QCOM_PCIE_2_9_0_MAX_CLOCKS];
        struct reset_control *rst;
 };
 
@@ -222,11 +237,14 @@ struct qcom_pcie {
        struct dw_pcie *pci;
        void __iomem *parf;                     /* DT parf */
        void __iomem *elbi;                     /* DT elbi */
+       void __iomem *mhi;
        union qcom_pcie_resources res;
        struct phy *phy;
        struct gpio_desc *reset;
        struct icc_path *icc_mem;
        const struct qcom_pcie_cfg *cfg;
+       struct dentry *debugfs;
+       bool suspended;
 };
 
 #define to_qcom_pcie(x)                dev_get_drvdata((x)->dev)
@@ -261,9 +279,9 @@ static void qcom_pcie_2_1_0_ltssm_enable(struct qcom_pcie *pcie)
        u32 val;
 
        /* enable link training */
-       val = readl(pcie->elbi + PCIE20_ELBI_SYS_CTRL);
-       val |= PCIE20_ELBI_SYS_CTRL_LT_ENABLE;
-       writel(val, pcie->elbi + PCIE20_ELBI_SYS_CTRL);
+       val = readl(pcie->elbi + ELBI_SYS_CTRL);
+       val |= ELBI_SYS_CTRL_LT_ENABLE;
+       writel(val, pcie->elbi + ELBI_SYS_CTRL);
 }
 
 static int qcom_pcie_get_resources_2_1_0(struct qcom_pcie *pcie)
@@ -271,6 +289,7 @@ static int qcom_pcie_get_resources_2_1_0(struct qcom_pcie *pcie)
        struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0;
        struct dw_pcie *pci = pcie->pci;
        struct device *dev = pci->dev;
+       bool is_apq = of_device_is_compatible(dev->of_node, "qcom,pcie-apq8064");
        int ret;
 
        res->supplies[0].supply = "vdda";
@@ -297,28 +316,20 @@ static int qcom_pcie_get_resources_2_1_0(struct qcom_pcie *pcie)
        if (ret < 0)
                return ret;
 
-       res->pci_reset = devm_reset_control_get_exclusive(dev, "pci");
-       if (IS_ERR(res->pci_reset))
-               return PTR_ERR(res->pci_reset);
-
-       res->axi_reset = devm_reset_control_get_exclusive(dev, "axi");
-       if (IS_ERR(res->axi_reset))
-               return PTR_ERR(res->axi_reset);
-
-       res->ahb_reset = devm_reset_control_get_exclusive(dev, "ahb");
-       if (IS_ERR(res->ahb_reset))
-               return PTR_ERR(res->ahb_reset);
+       res->resets[0].id = "pci";
+       res->resets[1].id = "axi";
+       res->resets[2].id = "ahb";
+       res->resets[3].id = "por";
+       res->resets[4].id = "phy";
+       res->resets[5].id = "ext";
 
-       res->por_reset = devm_reset_control_get_exclusive(dev, "por");
-       if (IS_ERR(res->por_reset))
-               return PTR_ERR(res->por_reset);
-
-       res->ext_reset = devm_reset_control_get_optional_exclusive(dev, "ext");
-       if (IS_ERR(res->ext_reset))
-               return PTR_ERR(res->ext_reset);
+       /* ext is optional on APQ8016 */
+       res->num_resets = is_apq ? 5 : 6;
+       ret = devm_reset_control_bulk_get_exclusive(dev, res->num_resets, res->resets);
+       if (ret < 0)
+               return ret;
 
-       res->phy_reset = devm_reset_control_get_exclusive(dev, "phy");
-       return PTR_ERR_OR_ZERO(res->phy_reset);
+       return 0;
 }
 
 static void qcom_pcie_deinit_2_1_0(struct qcom_pcie *pcie)
@@ -326,14 +337,9 @@ static void qcom_pcie_deinit_2_1_0(struct qcom_pcie *pcie)
        struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0;
 
        clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
-       reset_control_assert(res->pci_reset);
-       reset_control_assert(res->axi_reset);
-       reset_control_assert(res->ahb_reset);
-       reset_control_assert(res->por_reset);
-       reset_control_assert(res->ext_reset);
-       reset_control_assert(res->phy_reset);
+       reset_control_bulk_assert(res->num_resets, res->resets);
 
-       writel(1, pcie->parf + PCIE20_PARF_PHY_CTRL);
+       writel(1, pcie->parf + PARF_PHY_CTRL);
 
        regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
 }
@@ -346,12 +352,11 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
        int ret;
 
        /* reset the PCIe interface as uboot can leave it undefined state */
-       reset_control_assert(res->pci_reset);
-       reset_control_assert(res->axi_reset);
-       reset_control_assert(res->ahb_reset);
-       reset_control_assert(res->por_reset);
-       reset_control_assert(res->ext_reset);
-       reset_control_assert(res->phy_reset);
+       ret = reset_control_bulk_assert(res->num_resets, res->resets);
+       if (ret < 0) {
+               dev_err(dev, "cannot assert resets\n");
+               return ret;
+       }
 
        ret = regulator_bulk_enable(ARRAY_SIZE(res->supplies), res->supplies);
        if (ret < 0) {
@@ -359,58 +364,14 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
                return ret;
        }
 
-       ret = reset_control_deassert(res->ahb_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert ahb reset\n");
-               goto err_deassert_ahb;
-       }
-
-       ret = reset_control_deassert(res->ext_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert ext reset\n");
-               goto err_deassert_ext;
-       }
-
-       ret = reset_control_deassert(res->phy_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert phy reset\n");
-               goto err_deassert_phy;
-       }
-
-       ret = reset_control_deassert(res->pci_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert pci reset\n");
-               goto err_deassert_pci;
-       }
-
-       ret = reset_control_deassert(res->por_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert por reset\n");
-               goto err_deassert_por;
-       }
-
-       ret = reset_control_deassert(res->axi_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert axi reset\n");
-               goto err_deassert_axi;
+       ret = reset_control_bulk_deassert(res->num_resets, res->resets);
+       if (ret < 0) {
+               dev_err(dev, "cannot deassert resets\n");
+               regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
+               return ret;
        }
 
        return 0;
-
-err_deassert_axi:
-       reset_control_assert(res->por_reset);
-err_deassert_por:
-       reset_control_assert(res->pci_reset);
-err_deassert_pci:
-       reset_control_assert(res->phy_reset);
-err_deassert_phy:
-       reset_control_assert(res->ext_reset);
-err_deassert_ext:
-       reset_control_assert(res->ahb_reset);
-err_deassert_ahb:
-       regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
-
-       return ret;
 }
 
 static int qcom_pcie_post_init_2_1_0(struct qcom_pcie *pcie)
@@ -423,9 +384,9 @@ static int qcom_pcie_post_init_2_1_0(struct qcom_pcie *pcie)
        int ret;
 
        /* enable PCIe clocks and resets */
-       val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
-       val &= ~BIT(0);
-       writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
+       val = readl(pcie->parf + PARF_PHY_CTRL);
+       val &= ~PHY_TEST_PWR_DOWN;
+       writel(val, pcie->parf + PARF_PHY_CTRL);
 
        ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
        if (ret)
@@ -436,37 +397,37 @@ static int qcom_pcie_post_init_2_1_0(struct qcom_pcie *pcie)
                writel(PCS_DEEMPH_TX_DEEMPH_GEN1(24) |
                               PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(24) |
                               PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(34),
-                      pcie->parf + PCIE20_PARF_PCS_DEEMPH);
+                      pcie->parf + PARF_PCS_DEEMPH);
                writel(PCS_SWING_TX_SWING_FULL(120) |
                               PCS_SWING_TX_SWING_LOW(120),
-                      pcie->parf + PCIE20_PARF_PCS_SWING);
-               writel(PHY_RX0_EQ(4), pcie->parf + PCIE20_PARF_CONFIG_BITS);
+                      pcie->parf + PARF_PCS_SWING);
+               writel(PHY_RX0_EQ(4), pcie->parf + PARF_CONFIG_BITS);
        }
 
        if (of_device_is_compatible(node, "qcom,pcie-ipq8064")) {
                /* set TX termination offset */
-               val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
+               val = readl(pcie->parf + PARF_PHY_CTRL);
                val &= ~PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK;
                val |= PHY_CTRL_PHY_TX0_TERM_OFFSET(7);
-               writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
+               writel(val, pcie->parf + PARF_PHY_CTRL);
        }
 
        /* enable external reference clock */
-       val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK);
+       val = readl(pcie->parf + PARF_PHY_REFCLK);
        /* USE_PAD is required only for ipq806x */
        if (!of_device_is_compatible(node, "qcom,pcie-apq8064"))
                val &= ~PHY_REFCLK_USE_PAD;
        val |= PHY_REFCLK_SSP_EN;
-       writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK);
+       writel(val, pcie->parf + PARF_PHY_REFCLK);
 
        /* wait for clock acquisition */
        usleep_range(1000, 1500);
 
        /* Set the Max TLP size to 2K, instead of using default of 4K */
        writel(CFG_REMOTE_RD_REQ_BRIDGE_SIZE_2K,
-              pci->dbi_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL0);
+              pci->dbi_base + AXI_MSTR_RESP_COMP_CTRL0);
        writel(CFG_BRIDGE_SB_INIT,
-              pci->dbi_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL1);
+              pci->dbi_base + AXI_MSTR_RESP_COMP_CTRL1);
 
        return 0;
 }
@@ -476,26 +437,20 @@ static int qcom_pcie_get_resources_1_0_0(struct qcom_pcie *pcie)
        struct qcom_pcie_resources_1_0_0 *res = &pcie->res.v1_0_0;
        struct dw_pcie *pci = pcie->pci;
        struct device *dev = pci->dev;
+       int ret;
 
        res->vdda = devm_regulator_get(dev, "vdda");
        if (IS_ERR(res->vdda))
                return PTR_ERR(res->vdda);
 
-       res->iface = devm_clk_get(dev, "iface");
-       if (IS_ERR(res->iface))
-               return PTR_ERR(res->iface);
-
-       res->aux = devm_clk_get(dev, "aux");
-       if (IS_ERR(res->aux))
-               return PTR_ERR(res->aux);
-
-       res->master_bus = devm_clk_get(dev, "master_bus");
-       if (IS_ERR(res->master_bus))
-               return PTR_ERR(res->master_bus);
+       res->clks[0].id = "iface";
+       res->clks[1].id = "aux";
+       res->clks[2].id = "master_bus";
+       res->clks[3].id = "slave_bus";
 
-       res->slave_bus = devm_clk_get(dev, "slave_bus");
-       if (IS_ERR(res->slave_bus))
-               return PTR_ERR(res->slave_bus);
+       ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
+       if (ret < 0)
+               return ret;
 
        res->core = devm_reset_control_get_exclusive(dev, "core");
        return PTR_ERR_OR_ZERO(res->core);
@@ -506,10 +461,7 @@ static void qcom_pcie_deinit_1_0_0(struct qcom_pcie *pcie)
        struct qcom_pcie_resources_1_0_0 *res = &pcie->res.v1_0_0;
 
        reset_control_assert(res->core);
-       clk_disable_unprepare(res->slave_bus);
-       clk_disable_unprepare(res->master_bus);
-       clk_disable_unprepare(res->iface);
-       clk_disable_unprepare(res->aux);
+       clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
        regulator_disable(res->vdda);
 }
 
@@ -526,46 +478,23 @@ static int qcom_pcie_init_1_0_0(struct qcom_pcie *pcie)
                return ret;
        }
 
-       ret = clk_prepare_enable(res->aux);
-       if (ret) {
-               dev_err(dev, "cannot prepare/enable aux clock\n");
-               goto err_res;
-       }
-
-       ret = clk_prepare_enable(res->iface);
-       if (ret) {
-               dev_err(dev, "cannot prepare/enable iface clock\n");
-               goto err_aux;
-       }
-
-       ret = clk_prepare_enable(res->master_bus);
-       if (ret) {
-               dev_err(dev, "cannot prepare/enable master_bus clock\n");
-               goto err_iface;
-       }
-
-       ret = clk_prepare_enable(res->slave_bus);
+       ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
        if (ret) {
-               dev_err(dev, "cannot prepare/enable slave_bus clock\n");
-               goto err_master;
+               dev_err(dev, "cannot prepare/enable clocks\n");
+               goto err_assert_reset;
        }
 
        ret = regulator_enable(res->vdda);
        if (ret) {
                dev_err(dev, "cannot enable vdda regulator\n");
-               goto err_slave;
+               goto err_disable_clks;
        }
 
        return 0;
-err_slave:
-       clk_disable_unprepare(res->slave_bus);
-err_master:
-       clk_disable_unprepare(res->master_bus);
-err_iface:
-       clk_disable_unprepare(res->iface);
-err_aux:
-       clk_disable_unprepare(res->aux);
-err_res:
+
+err_disable_clks:
+       clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
+err_assert_reset:
        reset_control_assert(res->core);
 
        return ret;
@@ -574,13 +503,13 @@ err_res:
 static int qcom_pcie_post_init_1_0_0(struct qcom_pcie *pcie)
 {
        /* change DBI base address */
-       writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
+       writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
 
        if (IS_ENABLED(CONFIG_PCI_MSI)) {
-               u32 val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
+               u32 val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT);
 
-               val |= BIT(31);
-               writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
+               val |= EN;
+               writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT);
        }
 
        return 0;
@@ -591,9 +520,9 @@ static void qcom_pcie_2_3_2_ltssm_enable(struct qcom_pcie *pcie)
        u32 val;
 
        /* enable link training */
-       val = readl(pcie->parf + PCIE20_PARF_LTSSM);
-       val |= BIT(8);
-       writel(val, pcie->parf + PCIE20_PARF_LTSSM);
+       val = readl(pcie->parf + PARF_LTSSM);
+       val |= LTSSM_EN;
+       writel(val, pcie->parf + PARF_LTSSM);
 }
 
 static int qcom_pcie_get_resources_2_3_2(struct qcom_pcie *pcie)
@@ -610,21 +539,14 @@ static int qcom_pcie_get_resources_2_3_2(struct qcom_pcie *pcie)
        if (ret)
                return ret;
 
-       res->aux_clk = devm_clk_get(dev, "aux");
-       if (IS_ERR(res->aux_clk))
-               return PTR_ERR(res->aux_clk);
-
-       res->cfg_clk = devm_clk_get(dev, "cfg");
-       if (IS_ERR(res->cfg_clk))
-               return PTR_ERR(res->cfg_clk);
-
-       res->master_clk = devm_clk_get(dev, "bus_master");
-       if (IS_ERR(res->master_clk))
-               return PTR_ERR(res->master_clk);
+       res->clks[0].id = "aux";
+       res->clks[1].id = "cfg";
+       res->clks[2].id = "bus_master";
+       res->clks[3].id = "bus_slave";
 
-       res->slave_clk = devm_clk_get(dev, "bus_slave");
-       if (IS_ERR(res->slave_clk))
-               return PTR_ERR(res->slave_clk);
+       ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
+       if (ret < 0)
+               return ret;
 
        return 0;
 }
@@ -633,11 +555,7 @@ static void qcom_pcie_deinit_2_3_2(struct qcom_pcie *pcie)
 {
        struct qcom_pcie_resources_2_3_2 *res = &pcie->res.v2_3_2;
 
-       clk_disable_unprepare(res->slave_clk);
-       clk_disable_unprepare(res->master_clk);
-       clk_disable_unprepare(res->cfg_clk);
-       clk_disable_unprepare(res->aux_clk);
-
+       clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
        regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
 }
 
@@ -654,43 +572,14 @@ static int qcom_pcie_init_2_3_2(struct qcom_pcie *pcie)
                return ret;
        }
 
-       ret = clk_prepare_enable(res->aux_clk);
-       if (ret) {
-               dev_err(dev, "cannot prepare/enable aux clock\n");
-               goto err_aux_clk;
-       }
-
-       ret = clk_prepare_enable(res->cfg_clk);
-       if (ret) {
-               dev_err(dev, "cannot prepare/enable cfg clock\n");
-               goto err_cfg_clk;
-       }
-
-       ret = clk_prepare_enable(res->master_clk);
-       if (ret) {
-               dev_err(dev, "cannot prepare/enable master clock\n");
-               goto err_master_clk;
-       }
-
-       ret = clk_prepare_enable(res->slave_clk);
+       ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
        if (ret) {
-               dev_err(dev, "cannot prepare/enable slave clock\n");
-               goto err_slave_clk;
+               dev_err(dev, "cannot prepare/enable clocks\n");
+               regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
+               return ret;
        }
 
        return 0;
-
-err_slave_clk:
-       clk_disable_unprepare(res->master_clk);
-err_master_clk:
-       clk_disable_unprepare(res->cfg_clk);
-err_cfg_clk:
-       clk_disable_unprepare(res->aux_clk);
-
-err_aux_clk:
-       regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
-
-       return ret;
 }
 
 static int qcom_pcie_post_init_2_3_2(struct qcom_pcie *pcie)
@@ -698,25 +587,25 @@ static int qcom_pcie_post_init_2_3_2(struct qcom_pcie *pcie)
        u32 val;
 
        /* enable PCIe clocks and resets */
-       val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
-       val &= ~BIT(0);
-       writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
+       val = readl(pcie->parf + PARF_PHY_CTRL);
+       val &= ~PHY_TEST_PWR_DOWN;
+       writel(val, pcie->parf + PARF_PHY_CTRL);
 
        /* change DBI base address */
-       writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
+       writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
 
        /* MAC PHY_POWERDOWN MUX DISABLE  */
-       val = readl(pcie->parf + PCIE20_PARF_SYS_CTRL);
-       val &= ~BIT(29);
-       writel(val, pcie->parf + PCIE20_PARF_SYS_CTRL);
+       val = readl(pcie->parf + PARF_SYS_CTRL);
+       val &= ~MAC_PHY_POWERDOWN_IN_P2_D_MUX_EN;
+       writel(val, pcie->parf + PARF_SYS_CTRL);
 
-       val = readl(pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
-       val |= BIT(4);
-       writel(val, pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
+       val = readl(pcie->parf + PARF_MHI_CLOCK_RESET_CTRL);
+       val |= BYPASS;
+       writel(val, pcie->parf + PARF_MHI_CLOCK_RESET_CTRL);
 
-       val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
-       val |= BIT(31);
-       writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
+       val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
+       val |= EN;
+       writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
 
        return 0;
 }
@@ -741,65 +630,24 @@ static int qcom_pcie_get_resources_2_4_0(struct qcom_pcie *pcie)
        if (ret < 0)
                return ret;
 
-       res->axi_m_reset = devm_reset_control_get_exclusive(dev, "axi_m");
-       if (IS_ERR(res->axi_m_reset))
-               return PTR_ERR(res->axi_m_reset);
-
-       res->axi_s_reset = devm_reset_control_get_exclusive(dev, "axi_s");
-       if (IS_ERR(res->axi_s_reset))
-               return PTR_ERR(res->axi_s_reset);
-
-       if (is_ipq) {
-               /*
-                * These resources relates to the PHY or are secure clocks, but
-                * are controlled here for IPQ4019
-                */
-               res->pipe_reset = devm_reset_control_get_exclusive(dev, "pipe");
-               if (IS_ERR(res->pipe_reset))
-                       return PTR_ERR(res->pipe_reset);
-
-               res->axi_m_vmid_reset = devm_reset_control_get_exclusive(dev,
-                                                                        "axi_m_vmid");
-               if (IS_ERR(res->axi_m_vmid_reset))
-                       return PTR_ERR(res->axi_m_vmid_reset);
-
-               res->axi_s_xpu_reset = devm_reset_control_get_exclusive(dev,
-                                                                       "axi_s_xpu");
-               if (IS_ERR(res->axi_s_xpu_reset))
-                       return PTR_ERR(res->axi_s_xpu_reset);
-
-               res->parf_reset = devm_reset_control_get_exclusive(dev, "parf");
-               if (IS_ERR(res->parf_reset))
-                       return PTR_ERR(res->parf_reset);
-
-               res->phy_reset = devm_reset_control_get_exclusive(dev, "phy");
-               if (IS_ERR(res->phy_reset))
-                       return PTR_ERR(res->phy_reset);
-       }
-
-       res->axi_m_sticky_reset = devm_reset_control_get_exclusive(dev,
-                                                                  "axi_m_sticky");
-       if (IS_ERR(res->axi_m_sticky_reset))
-               return PTR_ERR(res->axi_m_sticky_reset);
-
-       res->pipe_sticky_reset = devm_reset_control_get_exclusive(dev,
-                                                                 "pipe_sticky");
-       if (IS_ERR(res->pipe_sticky_reset))
-               return PTR_ERR(res->pipe_sticky_reset);
-
-       res->pwr_reset = devm_reset_control_get_exclusive(dev, "pwr");
-       if (IS_ERR(res->pwr_reset))
-               return PTR_ERR(res->pwr_reset);
-
-       res->ahb_reset = devm_reset_control_get_exclusive(dev, "ahb");
-       if (IS_ERR(res->ahb_reset))
-               return PTR_ERR(res->ahb_reset);
-
-       if (is_ipq) {
-               res->phy_ahb_reset = devm_reset_control_get_exclusive(dev, "phy_ahb");
-               if (IS_ERR(res->phy_ahb_reset))
-                       return PTR_ERR(res->phy_ahb_reset);
-       }
+       res->resets[0].id = "axi_m";
+       res->resets[1].id = "axi_s";
+       res->resets[2].id = "axi_m_sticky";
+       res->resets[3].id = "pipe_sticky";
+       res->resets[4].id = "pwr";
+       res->resets[5].id = "ahb";
+       res->resets[6].id = "pipe";
+       res->resets[7].id = "axi_m_vmid";
+       res->resets[8].id = "axi_s_xpu";
+       res->resets[9].id = "parf";
+       res->resets[10].id = "phy";
+       res->resets[11].id = "phy_ahb";
+
+       res->num_resets = is_ipq ? 12 : 6;
+
+       ret = devm_reset_control_bulk_get_exclusive(dev, res->num_resets, res->resets);
+       if (ret < 0)
+               return ret;
 
        return 0;
 }
@@ -808,15 +656,7 @@ static void qcom_pcie_deinit_2_4_0(struct qcom_pcie *pcie)
 {
        struct qcom_pcie_resources_2_4_0 *res = &pcie->res.v2_4_0;
 
-       reset_control_assert(res->axi_m_reset);
-       reset_control_assert(res->axi_s_reset);
-       reset_control_assert(res->pipe_reset);
-       reset_control_assert(res->pipe_sticky_reset);
-       reset_control_assert(res->phy_reset);
-       reset_control_assert(res->phy_ahb_reset);
-       reset_control_assert(res->axi_m_sticky_reset);
-       reset_control_assert(res->pwr_reset);
-       reset_control_assert(res->ahb_reset);
+       reset_control_bulk_assert(res->num_resets, res->resets);
        clk_bulk_disable_unprepare(res->num_clks, res->clks);
 }
 
@@ -827,149 +667,29 @@ static int qcom_pcie_init_2_4_0(struct qcom_pcie *pcie)
        struct device *dev = pci->dev;
        int ret;
 
-       ret = reset_control_assert(res->axi_m_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert axi master reset\n");
-               return ret;
-       }
-
-       ret = reset_control_assert(res->axi_s_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert axi slave reset\n");
-               return ret;
-       }
-
-       usleep_range(10000, 12000);
-
-       ret = reset_control_assert(res->pipe_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert pipe reset\n");
-               return ret;
-       }
-
-       ret = reset_control_assert(res->pipe_sticky_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert pipe sticky reset\n");
-               return ret;
-       }
-
-       ret = reset_control_assert(res->phy_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert phy reset\n");
-               return ret;
-       }
-
-       ret = reset_control_assert(res->phy_ahb_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert phy ahb reset\n");
+       ret = reset_control_bulk_assert(res->num_resets, res->resets);
+       if (ret < 0) {
+               dev_err(dev, "cannot assert resets\n");
                return ret;
        }
 
        usleep_range(10000, 12000);
 
-       ret = reset_control_assert(res->axi_m_sticky_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert axi master sticky reset\n");
-               return ret;
-       }
-
-       ret = reset_control_assert(res->pwr_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert power reset\n");
-               return ret;
-       }
-
-       ret = reset_control_assert(res->ahb_reset);
-       if (ret) {
-               dev_err(dev, "cannot assert ahb reset\n");
+       ret = reset_control_bulk_deassert(res->num_resets, res->resets);
+       if (ret < 0) {
+               dev_err(dev, "cannot deassert resets\n");
                return ret;
        }
 
        usleep_range(10000, 12000);
 
-       ret = reset_control_deassert(res->phy_ahb_reset);
+       ret = clk_bulk_prepare_enable(res->num_clks, res->clks);
        if (ret) {
-               dev_err(dev, "cannot deassert phy ahb reset\n");
+               reset_control_bulk_assert(res->num_resets, res->resets);
                return ret;
        }
 
-       ret = reset_control_deassert(res->phy_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert phy reset\n");
-               goto err_rst_phy;
-       }
-
-       ret = reset_control_deassert(res->pipe_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert pipe reset\n");
-               goto err_rst_pipe;
-       }
-
-       ret = reset_control_deassert(res->pipe_sticky_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert pipe sticky reset\n");
-               goto err_rst_pipe_sticky;
-       }
-
-       usleep_range(10000, 12000);
-
-       ret = reset_control_deassert(res->axi_m_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert axi master reset\n");
-               goto err_rst_axi_m;
-       }
-
-       ret = reset_control_deassert(res->axi_m_sticky_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert axi master sticky reset\n");
-               goto err_rst_axi_m_sticky;
-       }
-
-       ret = reset_control_deassert(res->axi_s_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert axi slave reset\n");
-               goto err_rst_axi_s;
-       }
-
-       ret = reset_control_deassert(res->pwr_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert power reset\n");
-               goto err_rst_pwr;
-       }
-
-       ret = reset_control_deassert(res->ahb_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert ahb reset\n");
-               goto err_rst_ahb;
-       }
-
-       usleep_range(10000, 12000);
-
-       ret = clk_bulk_prepare_enable(res->num_clks, res->clks);
-       if (ret)
-               goto err_clks;
-
        return 0;
-
-err_clks:
-       reset_control_assert(res->ahb_reset);
-err_rst_ahb:
-       reset_control_assert(res->pwr_reset);
-err_rst_pwr:
-       reset_control_assert(res->axi_s_reset);
-err_rst_axi_s:
-       reset_control_assert(res->axi_m_sticky_reset);
-err_rst_axi_m_sticky:
-       reset_control_assert(res->axi_m_reset);
-err_rst_axi_m:
-       reset_control_assert(res->pipe_sticky_reset);
-err_rst_pipe_sticky:
-       reset_control_assert(res->pipe_reset);
-err_rst_pipe:
-       reset_control_assert(res->phy_reset);
-err_rst_phy:
-       reset_control_assert(res->phy_ahb_reset);
-       return ret;
 }
 
 static int qcom_pcie_post_init_2_4_0(struct qcom_pcie *pcie)
@@ -977,25 +697,25 @@ static int qcom_pcie_post_init_2_4_0(struct qcom_pcie *pcie)
        u32 val;
 
        /* enable PCIe clocks and resets */
-       val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
-       val &= ~BIT(0);
-       writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
+       val = readl(pcie->parf + PARF_PHY_CTRL);
+       val &= ~PHY_TEST_PWR_DOWN;
+       writel(val, pcie->parf + PARF_PHY_CTRL);
 
        /* change DBI base address */
-       writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
+       writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
 
        /* MAC PHY_POWERDOWN MUX DISABLE  */
-       val = readl(pcie->parf + PCIE20_PARF_SYS_CTRL);
-       val &= ~BIT(29);
-       writel(val, pcie->parf + PCIE20_PARF_SYS_CTRL);
+       val = readl(pcie->parf + PARF_SYS_CTRL);
+       val &= ~MAC_PHY_POWERDOWN_IN_P2_D_MUX_EN;
+       writel(val, pcie->parf + PARF_SYS_CTRL);
 
-       val = readl(pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
-       val |= BIT(4);
-       writel(val, pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
+       val = readl(pcie->parf + PARF_MHI_CLOCK_RESET_CTRL);
+       val |= BYPASS;
+       writel(val, pcie->parf + PARF_MHI_CLOCK_RESET_CTRL);
 
-       val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
-       val |= BIT(31);
-       writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
+       val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
+       val |= EN;
+       writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
 
        return 0;
 }
@@ -1005,36 +725,29 @@ static int qcom_pcie_get_resources_2_3_3(struct qcom_pcie *pcie)
        struct qcom_pcie_resources_2_3_3 *res = &pcie->res.v2_3_3;
        struct dw_pcie *pci = pcie->pci;
        struct device *dev = pci->dev;
-       int i;
-       const char *rst_names[] = { "axi_m", "axi_s", "pipe",
-                                   "axi_m_sticky", "sticky",
-                                   "ahb", "sleep", };
-
-       res->iface = devm_clk_get(dev, "iface");
-       if (IS_ERR(res->iface))
-               return PTR_ERR(res->iface);
-
-       res->axi_m_clk = devm_clk_get(dev, "axi_m");
-       if (IS_ERR(res->axi_m_clk))
-               return PTR_ERR(res->axi_m_clk);
-
-       res->axi_s_clk = devm_clk_get(dev, "axi_s");
-       if (IS_ERR(res->axi_s_clk))
-               return PTR_ERR(res->axi_s_clk);
-
-       res->ahb_clk = devm_clk_get(dev, "ahb");
-       if (IS_ERR(res->ahb_clk))
-               return PTR_ERR(res->ahb_clk);
-
-       res->aux_clk = devm_clk_get(dev, "aux");
-       if (IS_ERR(res->aux_clk))
-               return PTR_ERR(res->aux_clk);
-
-       for (i = 0; i < ARRAY_SIZE(rst_names); i++) {
-               res->rst[i] = devm_reset_control_get(dev, rst_names[i]);
-               if (IS_ERR(res->rst[i]))
-                       return PTR_ERR(res->rst[i]);
-       }
+       int ret;
+
+       res->clks[0].id = "iface";
+       res->clks[1].id = "axi_m";
+       res->clks[2].id = "axi_s";
+       res->clks[3].id = "ahb";
+       res->clks[4].id = "aux";
+
+       ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
+       if (ret < 0)
+               return ret;
+
+       res->rst[0].id = "axi_m";
+       res->rst[1].id = "axi_s";
+       res->rst[2].id = "pipe";
+       res->rst[3].id = "axi_m_sticky";
+       res->rst[4].id = "sticky";
+       res->rst[5].id = "ahb";
+       res->rst[6].id = "sleep";
+
+       ret = devm_reset_control_bulk_get_exclusive(dev, ARRAY_SIZE(res->rst), res->rst);
+       if (ret < 0)
+               return ret;
 
        return 0;
 }
@@ -1043,11 +756,7 @@ static void qcom_pcie_deinit_2_3_3(struct qcom_pcie *pcie)
 {
        struct qcom_pcie_resources_2_3_3 *res = &pcie->res.v2_3_3;
 
-       clk_disable_unprepare(res->iface);
-       clk_disable_unprepare(res->axi_m_clk);
-       clk_disable_unprepare(res->axi_s_clk);
-       clk_disable_unprepare(res->ahb_clk);
-       clk_disable_unprepare(res->aux_clk);
+       clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
 }
 
 static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie)
@@ -1055,25 +764,20 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie)
        struct qcom_pcie_resources_2_3_3 *res = &pcie->res.v2_3_3;
        struct dw_pcie *pci = pcie->pci;
        struct device *dev = pci->dev;
-       int i, ret;
+       int ret;
 
-       for (i = 0; i < ARRAY_SIZE(res->rst); i++) {
-               ret = reset_control_assert(res->rst[i]);
-               if (ret) {
-                       dev_err(dev, "reset #%d assert failed (%d)\n", i, ret);
-                       return ret;
-               }
+       ret = reset_control_bulk_assert(ARRAY_SIZE(res->rst), res->rst);
+       if (ret < 0) {
+               dev_err(dev, "cannot assert resets\n");
+               return ret;
        }
 
        usleep_range(2000, 2500);
 
-       for (i = 0; i < ARRAY_SIZE(res->rst); i++) {
-               ret = reset_control_deassert(res->rst[i]);
-               if (ret) {
-                       dev_err(dev, "reset #%d deassert failed (%d)\n", i,
-                               ret);
-                       return ret;
-               }
+       ret = reset_control_bulk_deassert(ARRAY_SIZE(res->rst), res->rst);
+       if (ret < 0) {
+               dev_err(dev, "cannot deassert resets\n");
+               return ret;
        }
 
        /*
@@ -1082,53 +786,20 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie)
         */
        usleep_range(2000, 2500);
 
-       ret = clk_prepare_enable(res->iface);
-       if (ret) {
-               dev_err(dev, "cannot prepare/enable core clock\n");
-               goto err_clk_iface;
-       }
-
-       ret = clk_prepare_enable(res->axi_m_clk);
-       if (ret) {
-               dev_err(dev, "cannot prepare/enable core clock\n");
-               goto err_clk_axi_m;
-       }
-
-       ret = clk_prepare_enable(res->axi_s_clk);
-       if (ret) {
-               dev_err(dev, "cannot prepare/enable axi slave clock\n");
-               goto err_clk_axi_s;
-       }
-
-       ret = clk_prepare_enable(res->ahb_clk);
-       if (ret) {
-               dev_err(dev, "cannot prepare/enable ahb clock\n");
-               goto err_clk_ahb;
-       }
-
-       ret = clk_prepare_enable(res->aux_clk);
+       ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
        if (ret) {
-               dev_err(dev, "cannot prepare/enable aux clock\n");
-               goto err_clk_aux;
+               dev_err(dev, "cannot prepare/enable clocks\n");
+               goto err_assert_resets;
        }
 
        return 0;
 
-err_clk_aux:
-       clk_disable_unprepare(res->ahb_clk);
-err_clk_ahb:
-       clk_disable_unprepare(res->axi_s_clk);
-err_clk_axi_s:
-       clk_disable_unprepare(res->axi_m_clk);
-err_clk_axi_m:
-       clk_disable_unprepare(res->iface);
-err_clk_iface:
+err_assert_resets:
        /*
         * Not checking for failure, will anyway return
         * the original failure in 'ret'.
         */
-       for (i = 0; i < ARRAY_SIZE(res->rst); i++)
-               reset_control_assert(res->rst[i]);
+       reset_control_bulk_assert(ARRAY_SIZE(res->rst), res->rst);
 
        return ret;
 }
@@ -1140,22 +811,22 @@ static int qcom_pcie_post_init_2_3_3(struct qcom_pcie *pcie)
        u32 val;
 
        writel(SLV_ADDR_SPACE_SZ,
-               pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
+               pcie->parf + PARF_SLV_ADDR_SPACE_SIZE_2_3_3);
 
-       val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
-       val &= ~BIT(0);
-       writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
+       val = readl(pcie->parf + PARF_PHY_CTRL);
+       val &= ~PHY_TEST_PWR_DOWN;
+       writel(val, pcie->parf + PARF_PHY_CTRL);
 
-       writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
+       writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
 
        writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
                | SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
                AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
-               pcie->parf + PCIE20_PARF_SYS_CTRL);
-       writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
+               pcie->parf + PARF_SYS_CTRL);
+       writel(0, pcie->parf + PARF_Q2A_FLUSH);
 
        writel(PCI_COMMAND_MASTER, pci->dbi_base + PCI_COMMAND);
-       writel(DBI_RO_WR_EN, pci->dbi_base + PCIE20_MISC_CONTROL_1_REG);
+       writel(DBI_RO_WR_EN, pci->dbi_base + MISC_CONTROL_1_REG);
        writel(PCIE_CAP_SLOT_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
 
        val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
@@ -1177,9 +848,9 @@ static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie)
        unsigned int idx;
        int ret;
 
-       res->pci_reset = devm_reset_control_get_exclusive(dev, "pci");
-       if (IS_ERR(res->pci_reset))
-               return PTR_ERR(res->pci_reset);
+       res->rst = devm_reset_control_array_get_exclusive(dev);
+       if (IS_ERR(res->rst))
+               return PTR_ERR(res->rst);
 
        res->supplies[0].supply = "vdda";
        res->supplies[1].supply = "vddpe-3v3";
@@ -1205,9 +876,12 @@ static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie)
        res->clks[idx++].id = "ddrss_sf_tbu";
        res->clks[idx++].id = "aggre0";
        res->clks[idx++].id = "aggre1";
+       res->clks[idx++].id = "noc_aggr";
        res->clks[idx++].id = "noc_aggr_4";
        res->clks[idx++].id = "noc_aggr_south_sf";
        res->clks[idx++].id = "cnoc_qx";
+       res->clks[idx++].id = "sleep";
+       res->clks[idx++].id = "cnoc_sf_axi";
 
        num_opt_clks = idx - num_clks;
        res->num_clks = idx;
@@ -1237,17 +911,17 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
        if (ret < 0)
                goto err_disable_regulators;
 
-       ret = reset_control_assert(res->pci_reset);
-       if (ret < 0) {
-               dev_err(dev, "cannot assert pci reset\n");
+       ret = reset_control_assert(res->rst);
+       if (ret) {
+               dev_err(dev, "reset assert failed (%d)\n", ret);
                goto err_disable_clocks;
        }
 
        usleep_range(1000, 1500);
 
-       ret = reset_control_deassert(res->pci_reset);
-       if (ret < 0) {
-               dev_err(dev, "cannot deassert pci reset\n");
+       ret = reset_control_deassert(res->rst);
+       if (ret) {
+               dev_err(dev, "reset deassert failed (%d)\n", ret);
                goto err_disable_clocks;
        }
 
@@ -1255,35 +929,33 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
        usleep_range(1000, 1500);
 
        /* configure PCIe to RC mode */
-       writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
+       writel(DEVICE_TYPE_RC, pcie->parf + PARF_DEVICE_TYPE);
 
        /* enable PCIe clocks and resets */
-       val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
-       val &= ~BIT(0);
-       writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
+       val = readl(pcie->parf + PARF_PHY_CTRL);
+       val &= ~PHY_TEST_PWR_DOWN;
+       writel(val, pcie->parf + PARF_PHY_CTRL);
 
        /* change DBI base address */
-       writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
+       writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
 
        /* MAC PHY_POWERDOWN MUX DISABLE  */
-       val = readl(pcie->parf + PCIE20_PARF_SYS_CTRL);
-       val &= ~BIT(29);
-       writel(val, pcie->parf + PCIE20_PARF_SYS_CTRL);
+       val = readl(pcie->parf + PARF_SYS_CTRL);
+       val &= ~MAC_PHY_POWERDOWN_IN_P2_D_MUX_EN;
+       writel(val, pcie->parf + PARF_SYS_CTRL);
 
-       val = readl(pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
-       val |= BIT(4);
-       writel(val, pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
+       val = readl(pcie->parf + PARF_MHI_CLOCK_RESET_CTRL);
+       val |= BYPASS;
+       writel(val, pcie->parf + PARF_MHI_CLOCK_RESET_CTRL);
 
        /* Enable L1 and L1SS */
-       val = readl(pcie->parf + PCIE20_PARF_PM_CTRL);
+       val = readl(pcie->parf + PARF_PM_CTRL);
        val &= ~REQ_NOT_ENTR_L1;
-       writel(val, pcie->parf + PCIE20_PARF_PM_CTRL);
+       writel(val, pcie->parf + PARF_PM_CTRL);
 
-       if (IS_ENABLED(CONFIG_PCI_MSI)) {
-               val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
-               val |= BIT(31);
-               writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
-       }
+       val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
+       val |= EN;
+       writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
 
        return 0;
 err_disable_clocks:
@@ -1303,6 +975,76 @@ static void qcom_pcie_deinit_2_7_0(struct qcom_pcie *pcie)
        regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
 }
 
+static int qcom_pcie_config_sid_1_9_0(struct qcom_pcie *pcie)
+{
+       /* iommu map structure */
+       struct {
+               u32 bdf;
+               u32 phandle;
+               u32 smmu_sid;
+               u32 smmu_sid_len;
+       } *map;
+       void __iomem *bdf_to_sid_base = pcie->parf + PARF_BDF_TO_SID_TABLE_N;
+       struct device *dev = pcie->pci->dev;
+       u8 qcom_pcie_crc8_table[CRC8_TABLE_SIZE];
+       int i, nr_map, size = 0;
+       u32 smmu_sid_base;
+
+       of_get_property(dev->of_node, "iommu-map", &size);
+       if (!size)
+               return 0;
+
+       map = kzalloc(size, GFP_KERNEL);
+       if (!map)
+               return -ENOMEM;
+
+       of_property_read_u32_array(dev->of_node, "iommu-map", (u32 *)map,
+                                  size / sizeof(u32));
+
+       nr_map = size / (sizeof(*map));
+
+       crc8_populate_msb(qcom_pcie_crc8_table, QCOM_PCIE_CRC8_POLYNOMIAL);
+
+       /* Registers need to be zero out first */
+       memset_io(bdf_to_sid_base, 0, CRC8_TABLE_SIZE * sizeof(u32));
+
+       /* Extract the SMMU SID base from the first entry of iommu-map */
+       smmu_sid_base = map[0].smmu_sid;
+
+       /* Look for an available entry to hold the mapping */
+       for (i = 0; i < nr_map; i++) {
+               __be16 bdf_be = cpu_to_be16(map[i].bdf);
+               u32 val;
+               u8 hash;
+
+               hash = crc8(qcom_pcie_crc8_table, (u8 *)&bdf_be, sizeof(bdf_be), 0);
+
+               val = readl(bdf_to_sid_base + hash * sizeof(u32));
+
+               /* If the register is already populated, look for next available entry */
+               while (val) {
+                       u8 current_hash = hash++;
+                       u8 next_mask = 0xff;
+
+                       /* If NEXT field is NULL then update it with next hash */
+                       if (!(val & next_mask)) {
+                               val |= (u32)hash;
+                               writel(val, bdf_to_sid_base + current_hash * sizeof(u32));
+                       }
+
+                       val = readl(bdf_to_sid_base + hash * sizeof(u32));
+               }
+
+               /* BDF [31:16] | SID [15:8] | NEXT [7:0] */
+               val = map[i].bdf << 16 | (map[i].smmu_sid - smmu_sid_base) << 8 | 0;
+               writel(val, bdf_to_sid_base + hash * sizeof(u32));
+       }
+
+       kfree(map);
+
+       return 0;
+}
+
 static int qcom_pcie_get_resources_2_9_0(struct qcom_pcie *pcie)
 {
        struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
@@ -1371,17 +1113,17 @@ static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
        int i;
 
        writel(SLV_ADDR_SPACE_SZ,
-               pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
+               pcie->parf + PARF_SLV_ADDR_SPACE_SIZE);
 
-       val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
-       val &= ~BIT(0);
-       writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
+       val = readl(pcie->parf + PARF_PHY_CTRL);
+       val &= ~PHY_TEST_PWR_DOWN;
+       writel(val, pcie->parf + PARF_PHY_CTRL);
 
-       writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
+       writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
 
-       writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
+       writel(DEVICE_TYPE_RC, pcie->parf + PARF_DEVICE_TYPE);
        writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
-               pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
+               pcie->parf + PARF_MHI_CLOCK_RESET_CTRL);
        writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS |
                GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
                pci->dbi_base + GEN3_RELATED_OFF);
@@ -1389,9 +1131,9 @@ static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
        writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS |
                SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
                AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
-               pcie->parf + PCIE20_PARF_SYS_CTRL);
+               pcie->parf + PARF_SYS_CTRL);
 
-       writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
+       writel(0, pcie->parf + PARF_Q2A_FLUSH);
 
        dw_pcie_dbi_ro_wr_en(pci);
        writel(PCIE_CAP_SLOT_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
@@ -1404,7 +1146,7 @@ static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
                        PCI_EXP_DEVCTL2);
 
        for (i = 0; i < 256; i++)
-               writel(0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N + (4 * i));
+               writel(0, pcie->parf + PARF_BDF_TO_SID_TABLE_N + (4 * i));
 
        return 0;
 }
@@ -1417,77 +1159,6 @@ static int qcom_pcie_link_up(struct dw_pcie *pci)
        return !!(val & PCI_EXP_LNKSTA_DLLLA);
 }
 
-static int qcom_pcie_config_sid_sm8250(struct qcom_pcie *pcie)
-{
-       /* iommu map structure */
-       struct {
-               u32 bdf;
-               u32 phandle;
-               u32 smmu_sid;
-               u32 smmu_sid_len;
-       } *map;
-       void __iomem *bdf_to_sid_base = pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N;
-       struct device *dev = pcie->pci->dev;
-       u8 qcom_pcie_crc8_table[CRC8_TABLE_SIZE];
-       int i, nr_map, size = 0;
-       u32 smmu_sid_base;
-
-       of_get_property(dev->of_node, "iommu-map", &size);
-       if (!size)
-               return 0;
-
-       map = kzalloc(size, GFP_KERNEL);
-       if (!map)
-               return -ENOMEM;
-
-       of_property_read_u32_array(dev->of_node,
-               "iommu-map", (u32 *)map, size / sizeof(u32));
-
-       nr_map = size / (sizeof(*map));
-
-       crc8_populate_msb(qcom_pcie_crc8_table, QCOM_PCIE_CRC8_POLYNOMIAL);
-
-       /* Registers need to be zero out first */
-       memset_io(bdf_to_sid_base, 0, CRC8_TABLE_SIZE * sizeof(u32));
-
-       /* Extract the SMMU SID base from the first entry of iommu-map */
-       smmu_sid_base = map[0].smmu_sid;
-
-       /* Look for an available entry to hold the mapping */
-       for (i = 0; i < nr_map; i++) {
-               __be16 bdf_be = cpu_to_be16(map[i].bdf);
-               u32 val;
-               u8 hash;
-
-               hash = crc8(qcom_pcie_crc8_table, (u8 *)&bdf_be, sizeof(bdf_be),
-                       0);
-
-               val = readl(bdf_to_sid_base + hash * sizeof(u32));
-
-               /* If the register is already populated, look for next available entry */
-               while (val) {
-                       u8 current_hash = hash++;
-                       u8 next_mask = 0xff;
-
-                       /* If NEXT field is NULL then update it with next hash */
-                       if (!(val & next_mask)) {
-                               val |= (u32)hash;
-                               writel(val, bdf_to_sid_base + current_hash * sizeof(u32));
-                       }
-
-                       val = readl(bdf_to_sid_base + hash * sizeof(u32));
-               }
-
-               /* BDF [31:16] | SID [15:8] | NEXT [7:0] */
-               val = map[i].bdf << 16 | (map[i].smmu_sid - smmu_sid_base) << 8 | 0;
-               writel(val, bdf_to_sid_base + hash * sizeof(u32));
-       }
-
-       kfree(map);
-
-       return 0;
-}
-
 static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
 {
        struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -1608,7 +1279,7 @@ static const struct qcom_pcie_ops ops_1_9_0 = {
        .init = qcom_pcie_init_2_7_0,
        .deinit = qcom_pcie_deinit_2_7_0,
        .ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
-       .config_sid = qcom_pcie_config_sid_sm8250,
+       .config_sid = qcom_pcie_config_sid_1_9_0,
 };
 
 /* Qcom IP rev.: 2.9.0  Synopsys IP rev.: 5.00a */
@@ -1725,13 +1396,51 @@ static void qcom_pcie_icc_update(struct qcom_pcie *pcie)
        }
 }
 
+static int qcom_pcie_link_transition_count(struct seq_file *s, void *data)
+{
+       struct qcom_pcie *pcie = (struct qcom_pcie *)dev_get_drvdata(s->private);
+
+       seq_printf(s, "L0s transition count: %u\n",
+                  readl_relaxed(pcie->mhi + PARF_DEBUG_CNT_PM_LINKST_IN_L0S));
+
+       seq_printf(s, "L1 transition count: %u\n",
+                  readl_relaxed(pcie->mhi + PARF_DEBUG_CNT_PM_LINKST_IN_L1));
+
+       seq_printf(s, "L1.1 transition count: %u\n",
+                  readl_relaxed(pcie->mhi + PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L1));
+
+       seq_printf(s, "L1.2 transition count: %u\n",
+                  readl_relaxed(pcie->mhi + PARF_DEBUG_CNT_AUX_CLK_IN_L1SUB_L2));
+
+       seq_printf(s, "L2 transition count: %u\n",
+                  readl_relaxed(pcie->mhi + PARF_DEBUG_CNT_PM_LINKST_IN_L2));
+
+       return 0;
+}
+
+static void qcom_pcie_init_debugfs(struct qcom_pcie *pcie)
+{
+       struct dw_pcie *pci = pcie->pci;
+       struct device *dev = pci->dev;
+       char *name;
+
+       name = devm_kasprintf(dev, GFP_KERNEL, "%pOFP", dev->of_node);
+       if (!name)
+               return;
+
+       pcie->debugfs = debugfs_create_dir(name, NULL);
+       debugfs_create_devm_seqfile(dev, "link_transition_count", pcie->debugfs,
+                                   qcom_pcie_link_transition_count);
+}
+
 static int qcom_pcie_probe(struct platform_device *pdev)
 {
+       const struct qcom_pcie_cfg *pcie_cfg;
        struct device *dev = &pdev->dev;
+       struct qcom_pcie *pcie;
        struct dw_pcie_rp *pp;
+       struct resource *res;
        struct dw_pcie *pci;
-       struct qcom_pcie *pcie;
-       const struct qcom_pcie_cfg *pcie_cfg;
        int ret;
 
        pcie_cfg = of_device_get_match_data(dev);
@@ -1779,6 +1488,16 @@ static int qcom_pcie_probe(struct platform_device *pdev)
                goto err_pm_runtime_put;
        }
 
+       /* MHI region is optional */
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mhi");
+       if (res) {
+               pcie->mhi = devm_ioremap_resource(dev, res);
+               if (IS_ERR(pcie->mhi)) {
+                       ret = PTR_ERR(pcie->mhi);
+                       goto err_pm_runtime_put;
+               }
+       }
+
        pcie->phy = devm_phy_optional_get(dev, "pciephy");
        if (IS_ERR(pcie->phy)) {
                ret = PTR_ERR(pcie->phy);
@@ -1809,6 +1528,9 @@ static int qcom_pcie_probe(struct platform_device *pdev)
 
        qcom_pcie_icc_update(pcie);
 
+       if (pcie->mhi)
+               qcom_pcie_init_debugfs(pcie);
+
        return 0;
 
 err_phy_exit:
@@ -1820,6 +1542,62 @@ err_pm_runtime_put:
        return ret;
 }
 
+static int qcom_pcie_suspend_noirq(struct device *dev)
+{
+       struct qcom_pcie *pcie = dev_get_drvdata(dev);
+       int ret;
+
+       /*
+        * Set minimum bandwidth required to keep data path functional during
+        * suspend.
+        */
+       ret = icc_set_bw(pcie->icc_mem, 0, kBps_to_icc(1));
+       if (ret) {
+               dev_err(dev, "Failed to set interconnect bandwidth: %d\n", ret);
+               return ret;
+       }
+
+       /*
+        * Turn OFF the resources only for controllers without active PCIe
+        * devices. For controllers with active devices, the resources are kept
+        * ON and the link is expected to be in L0/L1 (sub)states.
+        *
+        * Turning OFF the resources for controllers with active PCIe devices
+        * will trigger access violation during the end of the suspend cycle,
+        * as kernel tries to access the PCIe devices config space for masking
+        * MSIs.
+        *
+        * Also, it is not desirable to put the link into L2/L3 state as that
+        * implies VDD supply will be removed and the devices may go into
+        * powerdown state. This will affect the lifetime of the storage devices
+        * like NVMe.
+        */
+       if (!dw_pcie_link_up(pcie->pci)) {
+               qcom_pcie_host_deinit(&pcie->pci->pp);
+               pcie->suspended = true;
+       }
+
+       return 0;
+}
+
+static int qcom_pcie_resume_noirq(struct device *dev)
+{
+       struct qcom_pcie *pcie = dev_get_drvdata(dev);
+       int ret;
+
+       if (pcie->suspended) {
+               ret = qcom_pcie_host_init(&pcie->pci->pp);
+               if (ret)
+                       return ret;
+
+               pcie->suspended = false;
+       }
+
+       qcom_pcie_icc_update(pcie);
+
+       return 0;
+}
+
 static const struct of_device_id qcom_pcie_match[] = {
        { .compatible = "qcom,pcie-apq8064", .data = &cfg_2_1_0 },
        { .compatible = "qcom,pcie-apq8084", .data = &cfg_1_0_0 },
@@ -1836,11 +1614,13 @@ static const struct of_device_id qcom_pcie_match[] = {
        { .compatible = "qcom,pcie-sc8180x", .data = &cfg_1_9_0 },
        { .compatible = "qcom,pcie-sc8280xp", .data = &cfg_1_9_0 },
        { .compatible = "qcom,pcie-sdm845", .data = &cfg_2_7_0 },
+       { .compatible = "qcom,pcie-sdx55", .data = &cfg_1_9_0 },
        { .compatible = "qcom,pcie-sm8150", .data = &cfg_1_9_0 },
        { .compatible = "qcom,pcie-sm8250", .data = &cfg_1_9_0 },
        { .compatible = "qcom,pcie-sm8350", .data = &cfg_1_9_0 },
        { .compatible = "qcom,pcie-sm8450-pcie0", .data = &cfg_1_9_0 },
        { .compatible = "qcom,pcie-sm8450-pcie1", .data = &cfg_1_9_0 },
+       { .compatible = "qcom,pcie-sm8550", .data = &cfg_1_9_0 },
        { }
 };
 
@@ -1856,12 +1636,18 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x0302, qcom_fixup_class);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x1000, qcom_fixup_class);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x1001, qcom_fixup_class);
 
+static const struct dev_pm_ops qcom_pcie_pm_ops = {
+       NOIRQ_SYSTEM_SLEEP_PM_OPS(qcom_pcie_suspend_noirq, qcom_pcie_resume_noirq)
+};
+
 static struct platform_driver qcom_pcie_driver = {
        .probe = qcom_pcie_probe,
        .driver = {
                .name = "qcom-pcie",
                .suppress_bind_attrs = true,
                .of_match_table = qcom_pcie_match,
+               .pm = &qcom_pcie_pm_ops,
+               .probe_type = PROBE_PREFER_ASYNCHRONOUS,
        },
 };
 builtin_platform_driver(qcom_pcie_driver);
index 1d7a07ba9ccdea64e6393715803308706b0fade0..58ce034f701ab8f2e7c3025e4eb571cdbe60c432 100644 (file)
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-menu "Mobiveil PCIe Core Support"
+menu "Mobiveil-based PCIe controllers"
        depends on PCI
 
 config PCIE_MOBIVEIL
@@ -11,6 +11,15 @@ config PCIE_MOBIVEIL_HOST
        depends on PCI_MSI
        select PCIE_MOBIVEIL
 
+config PCIE_LAYERSCAPE_GEN4
+       bool "Freescale Layerscape Gen4 PCIe controller"
+       depends on ARCH_LAYERSCAPE || COMPILE_TEST
+       depends on PCI_MSI
+       select PCIE_MOBIVEIL_HOST
+       help
+         Say Y here if you want PCIe Gen4 controller support on
+         Layerscape SoCs.
+
 config PCIE_MOBIVEIL_PLAT
        bool "Mobiveil AXI PCIe controller"
        depends on ARCH_ZYNQMP || COMPILE_TEST
@@ -22,12 +31,4 @@ config PCIE_MOBIVEIL_PLAT
          Soft IP. It has up to 8 outbound and inbound windows
          for address translation and it is a PCIe Gen4 IP.
 
-config PCIE_LAYERSCAPE_GEN4
-       bool "Freescale Layerscape PCIe Gen4 controller"
-       depends on ARCH_LAYERSCAPE || COMPILE_TEST
-       depends on PCI_MSI
-       select PCIE_MOBIVEIL_HOST
-       help
-         Say Y here if you want PCIe Gen4 controller support on
-         Layerscape SoCs.
 endmenu
index 654ac4a82beb984bb038b30456eb147c227f0e6f..e44252db6085a94b19c6a6e96198d1df233b47bc 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/bits.h>
+#include "../pci.h"
 
 /* Register offsets */
 #define IXP4XX_PCI_NP_AD               0x00
@@ -188,12 +189,13 @@ static u32 ixp4xx_config_addr(u8 bus_num, u16 devfn, int where)
        /* Root bus is always 0 in this hardware */
        if (bus_num == 0) {
                /* type 0 */
-               return BIT(32-PCI_SLOT(devfn)) | ((PCI_FUNC(devfn)) << 8) |
-                       (where & ~3);
+               return (PCI_CONF1_ADDRESS(0, 0, PCI_FUNC(devfn), where) &
+                       ~PCI_CONF1_ENABLE) | BIT(32-PCI_SLOT(devfn));
        } else {
                /* type 1 */
-               return (bus_num << 16) | ((PCI_SLOT(devfn)) << 11) |
-                       ((PCI_FUNC(devfn)) << 8) | (where & ~3) | 1;
+               return (PCI_CONF1_ADDRESS(bus_num, PCI_SLOT(devfn),
+                                         PCI_FUNC(devfn), where) &
+                       ~PCI_CONF1_ENABLE) | 1;
        }
 }
 
index 74c109f14ff0023bf7f6335f4f975dd7220c27af..79630885b9c823afb09df210b98615d422e0fb06 100644 (file)
@@ -1375,7 +1375,7 @@ static int tegra_pcie_phys_get(struct tegra_pcie *pcie)
        struct tegra_pcie_port *port;
        int err;
 
-       if (!soc->has_gen2 || of_find_property(np, "phys", NULL) != NULL)
+       if (!soc->has_gen2 || of_property_present(np, "phys"))
                return tegra_pcie_phys_get_legacy(pcie);
 
        list_for_each_entry(port, &pcie->ports, list) {
@@ -1944,7 +1944,7 @@ static bool of_regulator_bulk_available(struct device_node *np,
        for (i = 0; i < num_supplies; i++) {
                snprintf(property, 32, "%s-supply", supplies[i].supply);
 
-               if (of_find_property(np, property, NULL) == NULL)
+               if (!of_property_present(np, property))
                        return false;
        }
 
index ae5ad05ddc1d44dfba4a1e4cfd761322b81a6cf2..31de7a29192c8fda5f78802a55bda5aa73d62312 100644 (file)
@@ -643,7 +643,7 @@ static int mtk_pcie_setup_irq(struct mtk_pcie_port *port,
                return err;
        }
 
-       if (of_find_property(dev->of_node, "interrupt-names", NULL))
+       if (of_property_present(dev->of_node, "interrupt-names"))
                port->irq = platform_get_irq_byname(pdev, "pcie_irq");
        else
                port->irq = platform_get_irq(pdev, port->slot);
index 63a5f4463a9f6964e453598eee56f61f6950344a..a445ec314375d4a8adcc79e2fd1eab6662c805bd 100644 (file)
@@ -378,8 +378,8 @@ static int mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
                u32 slot = port->slot;
 
                if (!mt7621_pcie_port_is_linkup(port)) {
-                       dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n",
-                               slot);
+                       dev_info(dev, "pcie%d no card, disable it (RST & CLK)\n",
+                                slot);
                        mt7621_control_assert(port);
                        port->enabled = false;
                        num_disabled++;
index e4faf90feaf5cf1730ed8d081d581da894092764..e80e56b2a84243e56f072b2c0ae7ebfa7dba1ed4 100644 (file)
@@ -219,9 +219,9 @@ static int rcar_pcie_config_access(struct rcar_pcie_host *host,
 
        /* Enable the configuration access */
        if (pci_is_root_bus(bus->parent))
-               rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE0, PCIECCTLR);
+               rcar_pci_write_reg(pcie, PCIECCTLR_CCIE | TYPE0, PCIECCTLR);
        else
-               rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE1, PCIECCTLR);
+               rcar_pci_write_reg(pcie, PCIECCTLR_CCIE | TYPE1, PCIECCTLR);
 
        /* Check for errors */
        if (rcar_pci_read_reg(pcie, PCIEERRFR) & UNSUPPORTED_REQUEST)
index 9bb125db85c62058caf77a91c69ed48cbab2b043..6799f81392fc6b927e8e98d3bb118721b8ba4f49 100644 (file)
@@ -11,7 +11,7 @@
 
 #define PCIECAR                        0x000010
 #define PCIECCTLR              0x000018
-#define  CONFIG_SEND_ENABLE    BIT(31)
+#define  PCIECCTLR_CCIE                BIT(31)
 #define  TYPE0                 (0 << 8)
 #define  TYPE1                 BIT(8)
 #define PCIECDR                        0x000020
index d17f3bf36f70913f7f12713389aa4faab324105f..ad12515a4a121fe08a1d84f8c03d67676a207c2a 100644 (file)
@@ -63,7 +63,14 @@ int pciehp_configure_device(struct controller *ctrl)
 
        pci_assign_unassigned_bridge_resources(bridge);
        pcie_bus_configure_settings(parent);
+
+       /*
+        * Release reset_lock during driver binding
+        * to avoid AB-BA deadlock with device_lock.
+        */
+       up_read(&ctrl->reset_lock);
        pci_bus_add_devices(parent);
+       down_read_nested(&ctrl->reset_lock, ctrl->depth);
 
  out:
        pci_unlock_rescan_remove();
@@ -104,7 +111,15 @@ void pciehp_unconfigure_device(struct controller *ctrl, bool presence)
        list_for_each_entry_safe_reverse(dev, temp, &parent->devices,
                                         bus_list) {
                pci_dev_get(dev);
+
+               /*
+                * Release reset_lock during driver unbinding
+                * to avoid AB-BA deadlock with device_lock.
+                */
+               up_read(&ctrl->reset_lock);
                pci_stop_and_remove_bus_device(dev);
+               down_read_nested(&ctrl->reset_lock, ctrl->depth);
+
                /*
                 * Ensure that no new Requests will be generated from
                 * the device.
index 491986197c4791ba08b13eee1f7ef1ce11e5ae8d..2316de0fd19827c3c70fc030a9da4767700ee2ae 100644 (file)
@@ -278,7 +278,7 @@ int rpaphp_check_drc_props(struct device_node *dn, char *drc_name,
                return -EINVAL;
        }
 
-       if (of_find_property(dn->parent, "ibm,drc-info", NULL))
+       if (of_property_present(dn->parent, "ibm,drc-info"))
                return rpaphp_check_drc_props_v2(dn, drc_name, drc_type,
                                                be32_to_cpu(*my_index));
        else
@@ -440,7 +440,7 @@ int rpaphp_add_slot(struct device_node *dn)
        if (!of_node_name_eq(dn, "pci"))
                return 0;
 
-       if (of_find_property(dn, "ibm,drc-info", NULL))
+       if (of_property_present(dn, "ibm,drc-info"))
                return rpaphp_drc_info_add_slot(dn);
        else
                return rpaphp_drc_add_slot(dn);
index 64beed7a26bed140bd974337856a16a50aac25b0..01d47a42da045a156bd871afee974e09c657fe62 100644 (file)
 static ssize_t show_ctrl(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct pci_dev *pdev;
-       int index, busnr;
        struct resource *res;
        struct pci_bus *bus;
        size_t len = 0;
+       int busnr;
 
        pdev = to_pci_dev(dev);
        bus = pdev->subordinate;
 
        len += sysfs_emit_at(buf, len, "Free resources: memory\n");
-       pci_bus_for_each_resource(bus, res, index) {
+       pci_bus_for_each_resource(bus, res) {
                if (res && (res->flags & IORESOURCE_MEM) &&
                                !(res->flags & IORESOURCE_PREFETCH)) {
                        len += sysfs_emit_at(buf, len,
@@ -43,7 +43,7 @@ static ssize_t show_ctrl(struct device *dev, struct device_attribute *attr, char
                }
        }
        len += sysfs_emit_at(buf, len, "Free resources: prefetchable memory\n");
-       pci_bus_for_each_resource(bus, res, index) {
+       pci_bus_for_each_resource(bus, res) {
                if (res && (res->flags & IORESOURCE_MEM) &&
                               (res->flags & IORESOURCE_PREFETCH)) {
                        len += sysfs_emit_at(buf, len,
@@ -53,7 +53,7 @@ static ssize_t show_ctrl(struct device *dev, struct device_attribute *attr, char
                }
        }
        len += sysfs_emit_at(buf, len, "Free resources: IO\n");
-       pci_bus_for_each_resource(bus, res, index) {
+       pci_bus_for_each_resource(bus, res) {
                if (res && (res->flags & IORESOURCE_IO)) {
                        len += sysfs_emit_at(buf, len,
                                             "start = %8.8llx, length = %8.8llx\n",
index 4c2ef2e28fb5e9030a0e8ed41d2bcd883a00c16c..2c25f4fa0225aeed064b7c103ee0f7c7b801011b 100644 (file)
@@ -465,7 +465,7 @@ static int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *
                return -ENODEV;
 
        /* Local interrupt-map in the device node? Use it! */
-       if (of_get_property(dn, "interrupt-map", NULL)) {
+       if (of_property_present(dn, "interrupt-map")) {
                pin = pci_swizzle_interrupt_pin(pdev, pin);
                ppnode = dn;
        }
index 9e8205572830f4d1210dd0c3513ec207c3cc9e8b..6cd98ffca198406628d57df85577a3c755508704 100644 (file)
@@ -746,8 +746,7 @@ EXPORT_SYMBOL_GPL(pci_has_p2pmem);
 
 /**
  * pci_p2pmem_find_many - find a peer-to-peer DMA memory device compatible with
- *     the specified list of clients and shortest distance (as determined
- *     by pci_p2pmem_dma())
+ *     the specified list of clients and shortest distance
  * @clients: array of devices to check (NULL-terminated)
  * @num_clients: number of client devices in the list
  *
index 57ddcc59af3047970cbf143867b386cb8365ef05..ae9baf801681d0bda21f721c569c93a162848d1a 100644 (file)
@@ -572,7 +572,8 @@ static void pci_pm_default_resume_early(struct pci_dev *pci_dev)
 
 static void pci_pm_bridge_power_up_actions(struct pci_dev *pci_dev)
 {
-       pci_bridge_wait_for_secondary_bus(pci_dev, "resume", PCI_RESET_WAIT);
+       pci_bridge_wait_for_secondary_bus(pci_dev, "resume");
+
        /*
         * When powering on a bridge from D3cold, the whole hierarchy may be
         * powered on into D0uninitialized state, resume them to give them a
index 7a67611dc5f48f1b4cdc89c154bf4a4ce01ba483..199024beaee967a7d0ab200eb6cfecf0e95f7a54 100644 (file)
@@ -64,6 +64,14 @@ struct pci_pme_device {
 
 #define PME_TIMEOUT 1000 /* How long between PME checks */
 
+/*
+ * Devices may extend the 1 sec period through Request Retry Status
+ * completions (PCIe r6.0 sec 2.3.1).  The spec does not provide an upper
+ * limit, but 60 sec ought to be enough for any device to become
+ * responsive.
+ */
+#define PCIE_RESET_READY_POLL_MS 60000 /* msec */
+
 static void pci_dev_d3_sleep(struct pci_dev *dev)
 {
        unsigned int delay_ms = max(dev->d3hot_delay, pci_pm_d3hot_delay);
@@ -779,9 +787,8 @@ struct resource *pci_find_parent_resource(const struct pci_dev *dev,
 {
        const struct pci_bus *bus = dev->bus;
        struct resource *r;
-       int i;
 
-       pci_bus_for_each_resource(bus, r, i) {
+       pci_bus_for_each_resource(bus, r) {
                if (!r)
                        continue;
                if (resource_contains(r, res)) {
@@ -4939,7 +4946,6 @@ static int pci_bus_max_d3cold_delay(const struct pci_bus *bus)
  * pci_bridge_wait_for_secondary_bus - Wait for secondary bus to be accessible
  * @dev: PCI bridge
  * @reset_type: reset type in human-readable form
- * @timeout: maximum time to wait for devices on secondary bus (milliseconds)
  *
  * Handle necessary delays before access to the devices on the secondary
  * side of the bridge are permitted after D3cold to D0 transition
@@ -4952,8 +4958,7 @@ static int pci_bus_max_d3cold_delay(const struct pci_bus *bus)
  * Return 0 on success or -ENOTTY if the first device on the secondary bus
  * failed to become accessible.
  */
-int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type,
-                                     int timeout)
+int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type)
 {
        struct pci_dev *child;
        int delay;
@@ -5031,7 +5036,8 @@ int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type,
                }
        }
 
-       return pci_dev_wait(child, reset_type, timeout - delay);
+       return pci_dev_wait(child, reset_type,
+                           PCIE_RESET_READY_POLL_MS - delay);
 }
 
 void pci_reset_secondary_bus(struct pci_dev *dev)
@@ -5068,8 +5074,7 @@ int pci_bridge_secondary_bus_reset(struct pci_dev *dev)
 {
        pcibios_reset_secondary_bus(dev);
 
-       return pci_bridge_wait_for_secondary_bus(dev, "bus reset",
-                                                PCIE_RESET_READY_POLL_MS);
+       return pci_bridge_wait_for_secondary_bus(dev, "bus reset");
 }
 EXPORT_SYMBOL_GPL(pci_bridge_secondary_bus_reset);
 
index 2b48a0aa8008e5547ee258ad83759fb3177e2dd4..67005a0ee3816c718ef2bbc2344eb55f3ebe2eca 100644 (file)
@@ -70,12 +70,6 @@ struct pci_cap_saved_state *pci_find_saved_ext_cap(struct pci_dev *dev,
  * Reset (PCIe r6.0 sec 5.8).
  */
 #define PCI_RESET_WAIT         1000    /* msec */
-/*
- * Devices may extend the 1 sec period through Request Retry Status completions
- * (PCIe r6.0 sec 2.3.1).  The spec does not provide an upper limit, but 60 sec
- * ought to be enough for any device to become responsive.
- */
-#define PCIE_RESET_READY_POLL_MS 60000 /* msec */
 
 void pci_update_current_state(struct pci_dev *dev, pci_power_t state);
 void pci_refresh_power_state(struct pci_dev *dev);
@@ -100,8 +94,7 @@ void pci_msix_init(struct pci_dev *dev);
 bool pci_bridge_d3_possible(struct pci_dev *dev);
 void pci_bridge_d3_update(struct pci_dev *dev);
 void pci_bridge_reconfigure_ltr(struct pci_dev *dev);
-int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type,
-                                     int timeout);
+int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type);
 
 static inline void pci_wakeup_event(struct pci_dev *dev)
 {
index a5d7c69b764e05654b1dba1bfdd5b46fb9033715..3ceed8e3de4167a6c81a334f94fde125c5e832b5 100644 (file)
@@ -170,8 +170,7 @@ pci_ers_result_t dpc_reset_link(struct pci_dev *pdev)
        pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS,
                              PCI_EXP_DPC_STATUS_TRIGGER);
 
-       if (pci_bridge_wait_for_secondary_bus(pdev, "DPC",
-                                             PCIE_RESET_READY_POLL_MS)) {
+       if (pci_bridge_wait_for_secondary_bus(pdev, "DPC")) {
                clear_bit(PCI_DPC_RECOVERED, &pdev->priv_flags);
                ret = PCI_ERS_RESULT_DISCONNECT;
        } else {
index a6b9b479b97ad0c778820e366f814378d50e3177..5f4914d313a17404dd4c61f9145a3a76ac1a2375 100644 (file)
@@ -151,9 +151,18 @@ static void edr_handle_event(acpi_handle handle, u32 event, void *data)
        if (event != ACPI_NOTIFY_DISCONNECT_RECOVER)
                return;
 
+       /*
+        * pdev is a Root Port or Downstream Port that is still present and
+        * has triggered a containment event, e.g., DPC, so its child
+        * devices have been disconnected (ACPI r6.5, sec 5.6.6).
+        */
        pci_info(pdev, "EDR event received\n");
 
-       /* Locate the port which issued EDR event */
+       /*
+        * Locate the port that experienced the containment event.  pdev
+        * may be that port or a parent of it (PCI Firmware r3.3, sec
+        * 4.6.13).
+        */
        edev = acpi_dpc_port_get(pdev);
        if (!edev) {
                pci_err(pdev, "Firmware failed to locate DPC port\n");
@@ -193,6 +202,7 @@ send_ost:
         */
        if (estate == PCI_ERS_RESULT_RECOVERED) {
                pci_dbg(edev, "DPC port successfully recovered\n");
+               pcie_clear_device_status(edev);
                acpi_send_edr_status(pdev, edev, EDR_OST_SUCCESS);
        } else {
                pci_dbg(edev, "DPC port recovery failed\n");
index f96fa83f2627386677a4efcf10c7a971873dbd99..9123bafab451a90c2a7bb9799ed1c637d7c9fb13 100644 (file)
@@ -533,7 +533,7 @@ void pci_read_bridge_bases(struct pci_bus *child)
        pci_read_bridge_mmio_pref(child);
 
        if (dev->transparent) {
-               pci_bus_for_each_resource(child->parent, res, i) {
+               pci_bus_for_each_resource(child->parent, res) {
                        if (res && res->flags) {
                                pci_bus_add_resource(child, res,
                                                     PCI_SUBTRACTIVE_DECODE);
index 44cab813bf95120fbe591227a2d89d14a845102e..f4e2a88729fd144bfa125a7378153b4cd26fd34c 100644 (file)
@@ -1939,6 +1939,19 @@ static void quirk_radeon_pm(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x6741, quirk_radeon_pm);
 
+/*
+ * NVIDIA Ampere-based HDA controllers can wedge the whole device if a bus
+ * reset is performed too soon after transition to D0, extend d3hot_delay
+ * to previous effective default for all NVIDIA HDA controllers.
+ */
+static void quirk_nvidia_hda_pm(struct pci_dev *dev)
+{
+       quirk_d3hot_delay(dev, 20);
+}
+DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
+                             PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8,
+                             quirk_nvidia_hda_pm);
+
 /*
  * Ryzen5/7 XHCI controllers fail upon resume from runtime suspend or s2idle.
  * https://bugzilla.kernel.org/show_bug.cgi?id=205587
index 22d39e12b236a69901628e580bccc4b8ee403bcd..30a787d45d2e5c3e65277092f0f0115024ffe172 100644 (file)
@@ -5,10 +5,9 @@
 
 static void pci_free_resources(struct pci_dev *dev)
 {
-       int i;
+       struct resource *res;
 
-       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-               struct resource *res = dev->resource + i;
+       pci_dev_for_each_resource(dev, res) {
                if (res->parent)
                        release_resource(res);
        }
index c690572b10ce7b9d5bf672256f4e52dfa8de52e8..fdeb121e91756ef452c20e70a660178dfad7cbbd 100644 (file)
@@ -124,20 +124,17 @@ static resource_size_t get_res_add_align(struct list_head *head,
        return dev_res ? dev_res->min_align : 0;
 }
 
-
 /* Sort resources by alignment */
 static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head)
 {
+       struct resource *r;
        int i;
 
-       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-               struct resource *r;
+       pci_dev_for_each_resource(dev, r, i) {
                struct pci_dev_resource *dev_res, *tmp;
                resource_size_t r_align;
                struct list_head *n;
 
-               r = &dev->resource[i];
-
                if (r->flags & IORESOURCE_PCI_FIXED)
                        continue;
 
@@ -773,9 +770,8 @@ static struct resource *find_bus_resource_of_type(struct pci_bus *bus,
                                                  unsigned long type)
 {
        struct resource *r, *r_assigned = NULL;
-       int i;
 
-       pci_bus_for_each_resource(bus, r, i) {
+       pci_bus_for_each_resource(bus, r) {
                if (r == &ioport_resource || r == &iomem_resource)
                        continue;
                if (r && (r->flags & type_mask) == type && !r->parent)
@@ -895,10 +891,9 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
 
        min_align = window_alignment(bus, IORESOURCE_IO);
        list_for_each_entry(dev, &bus->devices, bus_list) {
-               int i;
+               struct resource *r;
 
-               for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-                       struct resource *r = &dev->resource[i];
+               pci_dev_for_each_resource(dev, r) {
                        unsigned long r_size;
 
                        if (r->parent || !(r->flags & IORESOURCE_IO))
@@ -1014,10 +1009,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
        size = 0;
 
        list_for_each_entry(dev, &bus->devices, bus_list) {
+               struct resource *r;
                int i;
 
-               for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-                       struct resource *r = &dev->resource[i];
+               pci_dev_for_each_resource(dev, r, i) {
                        resource_size_t r_size;
 
                        if (r->parent || (r->flags & IORESOURCE_PCI_FIXED) ||
@@ -1208,7 +1203,7 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head)
                        additional_mmio_pref_size = 0;
        struct resource *pref;
        struct pci_host_bridge *host;
-       int hdr_type, i, ret;
+       int hdr_type, ret;
 
        list_for_each_entry(dev, &bus->devices, bus_list) {
                struct pci_bus *b = dev->subordinate;
@@ -1232,7 +1227,7 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head)
                host = to_pci_host_bridge(bus->bridge);
                if (!host->size_windows)
                        return;
-               pci_bus_for_each_resource(bus, pref, i)
+               pci_bus_for_each_resource(bus, pref)
                        if (pref && (pref->flags & IORESOURCE_PREFETCH))
                                break;
                hdr_type = -1;  /* Intentionally invalid - not a PCI device. */
@@ -1337,12 +1332,11 @@ EXPORT_SYMBOL(pci_bus_size_bridges);
 
 static void assign_fixed_resource_on_bus(struct pci_bus *b, struct resource *r)
 {
-       int i;
        struct resource *parent_r;
        unsigned long mask = IORESOURCE_IO | IORESOURCE_MEM |
                             IORESOURCE_PREFETCH;
 
-       pci_bus_for_each_resource(b, parent_r, i) {
+       pci_bus_for_each_resource(b, parent_r) {
                if (!parent_r)
                        continue;
 
@@ -1358,11 +1352,10 @@ static void assign_fixed_resource_on_bus(struct pci_bus *b, struct resource *r)
  */
 static void pdev_assign_fixed_resources(struct pci_dev *dev)
 {
-       int i;
+       struct resource *r;
 
-       for (i = 0; i <  PCI_NUM_RESOURCES; i++) {
+       pci_dev_for_each_resource(dev, r) {
                struct pci_bus *b;
-               struct resource *r = &dev->resource[i];
 
                if (r->parent || !(r->flags & IORESOURCE_PCI_FIXED) ||
                    !(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
@@ -1795,11 +1788,9 @@ static void remove_dev_resources(struct pci_dev *dev, struct resource *io,
                                 struct resource *mmio,
                                 struct resource *mmio_pref)
 {
-       int i;
-
-       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-               struct resource *res = &dev->resource[i];
+       struct resource *res;
 
+       pci_dev_for_each_resource(dev, res) {
                if (resource_type(res) == IORESOURCE_IO) {
                        remove_dev_resource(io, dev, res);
                } else if (resource_type(res) == IORESOURCE_MEM) {
index b492e67c3d871747ec73d69dbb1dc1d1fc774dca..967f9a7589239244d17d8026ced56af473b6fadc 100644 (file)
@@ -484,12 +484,10 @@ int pci_enable_resources(struct pci_dev *dev, int mask)
        pci_read_config_word(dev, PCI_COMMAND, &cmd);
        old_cmd = cmd;
 
-       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+       pci_dev_for_each_resource(dev, r, i) {
                if (!(mask & (1 << i)))
                        continue;
 
-               r = &dev->resource[i];
-
                if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
                        continue;
                if ((i == PCI_ROM_RESOURCE) &&
index f80b6ec88dc301e04603995226a205e04d7375f0..5a696078b382bbd49da8a08dea2cce7b51600b32 100644 (file)
@@ -548,10 +548,8 @@ static bool vga_is_firmware_default(struct pci_dev *pdev)
 #if defined(CONFIG_X86) || defined(CONFIG_IA64)
        u64 base = screen_info.lfb_base;
        u64 size = screen_info.lfb_size;
+       struct resource *r;
        u64 limit;
-       resource_size_t start, end;
-       unsigned long flags;
-       int i;
 
        /* Select the device owning the boot framebuffer if there is one */
 
@@ -561,19 +559,14 @@ static bool vga_is_firmware_default(struct pci_dev *pdev)
        limit = base + size;
 
        /* Does firmware framebuffer belong to us? */
-       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-               flags = pci_resource_flags(pdev, i);
-
-               if ((flags & IORESOURCE_MEM) == 0)
+       pci_dev_for_each_resource(pdev, r) {
+               if (resource_type(r) != IORESOURCE_MEM)
                        continue;
 
-               start = pci_resource_start(pdev, i);
-               end  = pci_resource_end(pdev, i);
-
-               if (!start || !end)
+               if (!r->start || !r->end)
                        continue;
 
-               if (base < start || limit >= end)
+               if (base < r->start || limit >= r->end)
                        continue;
 
                return true;
index fcd029ca2eb184a9e4ee48773c1dd1e906be8fd1..83c0ab50676dff18c656e30dba58004949637bf7 100644 (file)
@@ -390,9 +390,7 @@ static int pcifront_claim_resource(struct pci_dev *dev, void *data)
        int i;
        struct resource *r;
 
-       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-               r = &dev->resource[i];
-
+       pci_dev_for_each_resource(dev, r, i) {
                if (!r->parent && r->start && r->flags) {
                        dev_info(&pdev->xdev->dev, "claiming resource %s/%d\n",
                                pci_name(dev), i);
index ac98b9919029c89d1431b90c0d7b2a56e76e0bee..6085a1471de21f3904628a04375812027fbba410 100644 (file)
@@ -229,8 +229,7 @@ static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
 static void quirk_system_pci_resources(struct pnp_dev *dev)
 {
        struct pci_dev *pdev = NULL;
-       struct resource *res;
-       resource_size_t pnp_start, pnp_end, pci_start, pci_end;
+       struct resource *res, *r;
        int i, j;
 
        /*
@@ -243,32 +242,26 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
         * so they won't be claimed by the PNP system driver.
         */
        for_each_pci_dev(pdev) {
-               for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-                       unsigned long flags, type;
+               pci_dev_for_each_resource(pdev, r, i) {
+                       unsigned long type = resource_type(r);
 
-                       flags = pci_resource_flags(pdev, i);
-                       type = flags & (IORESOURCE_IO | IORESOURCE_MEM);
-                       if (!type || pci_resource_len(pdev, i) == 0)
+                       if (!(type == IORESOURCE_IO || type == IORESOURCE_MEM) ||
+                           resource_size(r) == 0)
                                continue;
 
-                       if (flags & IORESOURCE_UNSET)
+                       if (r->flags & IORESOURCE_UNSET)
                                continue;
 
-                       pci_start = pci_resource_start(pdev, i);
-                       pci_end = pci_resource_end(pdev, i);
                        for (j = 0;
                             (res = pnp_get_resource(dev, type, j)); j++) {
                                if (res->start == 0 && res->end == 0)
                                        continue;
 
-                               pnp_start = res->start;
-                               pnp_end = res->end;
-
                                /*
                                 * If the PNP region doesn't overlap the PCI
                                 * region at all, there's no problem.
                                 */
-                               if (pnp_end < pci_start || pnp_start > pci_end)
+                               if (!resource_overlaps(res, r))
                                        continue;
 
                                /*
@@ -278,8 +271,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
                                 * PNP device describes a bridge with PCI
                                 * behind it.
                                 */
-                               if (pnp_start <= pci_start &&
-                                   pnp_end >= pci_end)
+                               if (res->start <= r->start && res->end >= r->end)
                                        continue;
 
                                /*
@@ -288,9 +280,8 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
                                 * driver from requesting its resources.
                                 */
                                dev_warn(&dev->dev,
-                                        "disabling %pR because it overlaps "
-                                        "%s BAR %d %pR\n", res,
-                                        pci_name(pdev), i, &pdev->resource[i]);
+                                        "disabling %pR because it overlaps %s BAR %d %pR\n",
+                                        res, pci_name(pdev), i, r);
                                res->flags |= IORESOURCE_DISABLED;
                        }
                }
index a5dda515fcd1d4f7fe2cd4b6e384797c0083027d..0b57e37d8e779c08b1d31418076efa35e68705fc 100644 (file)
@@ -1445,10 +1445,44 @@ int devm_request_pci_bus_resources(struct device *dev,
 /* Temporary until new and working PCI SBR API in place */
 int pci_bridge_secondary_bus_reset(struct pci_dev *dev);
 
-#define pci_bus_for_each_resource(bus, res, i)                         \
-       for (i = 0;                                                     \
-           (res = pci_bus_resource_n(bus, i)) || i < PCI_BRIDGE_RESOURCE_NUM; \
-            i++)
+#define __pci_bus_for_each_res0(bus, res, ...)                         \
+       for (unsigned int __b = 0;                                      \
+            (res = pci_bus_resource_n(bus, __b)) || __b < PCI_BRIDGE_RESOURCE_NUM; \
+            __b++)
+
+#define __pci_bus_for_each_res1(bus, res, __b)                         \
+       for (__b = 0;                                                   \
+            (res = pci_bus_resource_n(bus, __b)) || __b < PCI_BRIDGE_RESOURCE_NUM; \
+            __b++)
+
+/**
+ * pci_bus_for_each_resource - iterate over PCI bus resources
+ * @bus: the PCI bus
+ * @res: pointer to the current resource
+ * @...: optional index of the current resource
+ *
+ * Iterate over PCI bus resources. The first part is to go over PCI bus
+ * resource array, which has at most the %PCI_BRIDGE_RESOURCE_NUM entries.
+ * After that continue with the separate list of the additional resources,
+ * if not empty. That's why the Logical OR is being used.
+ *
+ * Possible usage:
+ *
+ *     struct pci_bus *bus = ...;
+ *     struct resource *res;
+ *     unsigned int i;
+ *
+ *     // With optional index
+ *     pci_bus_for_each_resource(bus, res, i)
+ *             pr_info("PCI bus resource[%u]: %pR\n", i, res);
+ *
+ *     // Without index
+ *     pci_bus_for_each_resource(bus, res)
+ *             _do_something_(res);
+ */
+#define pci_bus_for_each_resource(bus, res, ...)                       \
+       CONCATENATE(__pci_bus_for_each_res, COUNT_ARGS(__VA_ARGS__))    \
+                   (bus, res, __VA_ARGS__)
 
 int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
                        struct resource *res, resource_size_t size,
@@ -1997,14 +2031,27 @@ int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma);
  * These helpers provide future and backwards compatibility
  * for accessing popular PCI BAR info
  */
-#define pci_resource_start(dev, bar)   ((dev)->resource[(bar)].start)
-#define pci_resource_end(dev, bar)     ((dev)->resource[(bar)].end)
-#define pci_resource_flags(dev, bar)   ((dev)->resource[(bar)].flags)
-#define pci_resource_len(dev,bar) \
-       ((pci_resource_end((dev), (bar)) == 0) ? 0 :    \
-                                                       \
-        (pci_resource_end((dev), (bar)) -              \
-         pci_resource_start((dev), (bar)) + 1))
+#define pci_resource_n(dev, bar)       (&(dev)->resource[(bar)])
+#define pci_resource_start(dev, bar)   (pci_resource_n(dev, bar)->start)
+#define pci_resource_end(dev, bar)     (pci_resource_n(dev, bar)->end)
+#define pci_resource_flags(dev, bar)   (pci_resource_n(dev, bar)->flags)
+#define pci_resource_len(dev,bar)                                      \
+       (pci_resource_end((dev), (bar)) ?                               \
+        resource_size(pci_resource_n((dev), (bar))) : 0)
+
+#define __pci_dev_for_each_res0(dev, res, ...)                         \
+       for (unsigned int __b = 0;                                      \
+            res = pci_resource_n(dev, __b), __b < PCI_NUM_RESOURCES;   \
+            __b++)
+
+#define __pci_dev_for_each_res1(dev, res, __b)                         \
+       for (__b = 0;                                                   \
+            res = pci_resource_n(dev, __b), __b < PCI_NUM_RESOURCES;   \
+            __b++)
+
+#define pci_dev_for_each_resource(dev, res, ...)                       \
+       CONCATENATE(__pci_dev_for_each_res, COUNT_ARGS(__VA_ARGS__))    \
+                   (dev, res, __VA_ARGS__)
 
 /*
  * Similar to the helpers above, these manipulate per-pci_dev