pci-v6.4-changes

-----BEGIN PGP SIGNATURE-----
 
 iQJIBAABCgAyFiEEgMe7l+5h9hnxdsnuWYigwDrT+vwFAmRIKooUHGJoZWxnYWFz
 QGdvb2dsZS5jb20ACgkQWYigwDrT+vxq7A/9G0sInrqvqH2I9/Set/FnmMfCtGDH
 YcEjHYYxL+pztSiXTavDV+ib9iaut83oYtcV9p1bUMhJoZdKNZhrNdIGzRFSemI4
 0/ShtklPzNEu6nPPL24CnEzgbrODBU56ZvzrIE/tShEoOjkKa1triBnOA/JMxYTL
 cUwqDQlDkdpYniCgxy05QfcFZ0mmSOkbl7runGfTMTiUKKC3xSRiaW5YN9KZe3i7
 G5YHu1VVCjeQdQSICHYwyFmkyiqosCoajQNp1IHBkWqSwilzyZMg0NWJobVSA7M/
 mXXnzLtFcC60oT58/9MaggQwDTaSGDE8mG+sWv05bB2u5TQVyZEZqZ4c2FzmZIZT
 WLZYLB6PFRW0zePEuMnVkSLS2npkX+aGaBv28bf88sjorpaYNG01uYijnLEceolQ
 yBPFRN3bsRuOyHvYY/tiZX/BP7z/DS++XXwA8zQWZnYsXSlncJdwCNquV0xIwUt+
 hij4/Yu7o9SgV1LbuwtkMFAn3C9Szc65Eer+IvRRdnMZYphjVHbA5F2msRFyiCeR
 HxECtMQ1jBnVrpQAcBX1Sz+Vu5MrwCqzc2n6tvTQHDvVNjXfkG3NaFhxYPc1IL9Z
 NJMeCKfK1qzw7TtbvWXCluTTIM9N/bNJXrJhQbjNY7V6IaBZY1QNYW0ZFfGgj6Gb
 UUPgndidRy4/hzw=
 =HPXl
 -----END PGP SIGNATURE-----

Merge tag 'pci-v6.4-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci

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
  ...
This commit is contained in:
Linus Torvalds 2023-04-27 10:45:30 -07:00
commit 34b62f186d
60 changed files with 1923 additions and 1745 deletions

View 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'

View File

@ -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>;
};
...

View File

@ -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";
};

View File

@ -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
...

View File

@ -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>;
};

View 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

View 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>,

View 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:

View 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*

View 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) ||

View 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;

View 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;
}
}
}

View 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;
}
}
}

View 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;
}
}
}

View 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;

View 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) &&

View 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;
}
}
}

View 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",

View 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;

View 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;
}
}
}

View 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;
}
}
}

View 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;

View 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;

View 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;

View 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);

View 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;

View 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>

View 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)

View 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
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 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.
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_FTPCI100
bool "Faraday Technology FTPCI100 PCI controller"
config PCIE_APPLE_MSI_DOORBELL_ADDR
hex
default 0xfffff000
depends on PCIE_APPLE
config PCIE_APPLE
tristate "Apple PCIe controller"
depends on ARCH_APPLE || COMPILE_TEST
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
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_RCAR_HOST
bool "Renesas R-Car PCIe host controller"
depends on ARCH_RENESAS || COMPILE_TEST
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.
config PCI_HOST_COMMON
tristate
select PCI_ECAM
config PCI_HOST_GENERIC
tristate "Generic PCI host controller"
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.
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_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.
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 PCIE_ROCKCHIP_HOST
tristate "Rockchip PCIe host controller"
depends on ARCH_ROCKCHIP || COMPILE_TEST
config PCI_FTPCI100
bool "Faraday Technology FTPCI100 PCI controller"
depends on OF
depends on PCI_MSI
select MFD_SYSCON
select PCIE_ROCKCHIP
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.
default ARCH_GEMINI
config PCIE_ROCKCHIP_EP
bool "Rockchip PCIe endpoint 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_ENDPOINT
select MFD_SYSCON
select PCIE_ROCKCHIP
select PCI_HOST_COMMON
select IRQ_DOMAIN
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.
Say Y here if you want to support a simple generic PCI host
controller, such as the one emulated by kvmtool.
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 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 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"
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 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
help
Say Y here to enable PCIe host controller support for
Broadcom STB based SoCs, like the Raspberry Pi 4.
config PCI_HYPERV_INTERFACE
tristate "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.
config PCI_LOONGSON
bool "LOONGSON PCI 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 PCIE_MICROCHIP_HOST
bool "Microchip AXI PCIe host bridge support"
depends on PCI_MSI && OF
select PCI_HOST_COMMON
help
Say Y here if you want kernel to support the Microchip AXI PCIe
Host Bridge driver.
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 PCIE_APPLE_MSI_DOORBELL_ADDR
hex
default 0xfffff000
depends on PCIE_APPLE
config PCIE_APPLE
tristate "Apple PCIe controller"
depends on ARCH_APPLE || COMPILE_TEST
depends on OF
depends on PCI_MSI
select PCI_HOST_COMMON
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.
If unsure, say Y if you have an Apple Silicon system.
config PCIE_MT7621
tristate "MediaTek MT7621 PCIe Controller"
tristate "MediaTek MT7621 PCIe controller"
depends on SOC_MT7621 || COMPILE_TEST
select PHY_MT7621_PCI
default SOC_MT7621
help
This selects a driver for the MediaTek MT7621 PCIe Controller.
config PCIE_MICROCHIP_HOST
bool "Microchip AXI PCIe controller"
depends on PCI_MSI && OF
select PCI_HOST_COMMON
help
Say Y here if you want kernel to support the Microchip AXI PCIe
Host Bridge driver.
config PCI_HYPERV_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 that allows other
drivers to have a common interface with the Hyper-V PCI frontend
driver.
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 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 PCIe controller support on R-Car SoCs in host
mode.
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 PCIe controller support on R-Car SoCs in
endpoint mode.
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_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 MFD_SYSCON
select PCIE_ROCKCHIP
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.
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 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
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

View 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

View 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,217 +14,35 @@ 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
depends on PCI_MSI
select PCIE_DW_HOST
select PCI_DRA7XX
default y if SOC_DRA7XX
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.
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 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
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 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 PCI_IMX6
bool
config PCI_IMX6_HOST
bool "Freescale i.MX6/7/8 PCIe controller host mode"
depends on ARCH_MXC || COMPILE_TEST
depends on PCI_MSI
select PCIE_DW_HOST
select PCI_IMX6
help
Enables support for the PCIe controller in the i.MX SoCs to
work in Root Complex mode. The PCI controller on i.MX is based
on DesignWare hardware and therefore the driver re-uses the
DesignWare core functions to implement the driver.
config PCI_IMX6_EP
bool "Freescale i.MX6/7/8 PCIe controller endpoint mode"
depends on ARCH_MXC || COMPILE_TEST
depends on PCI_ENDPOINT
select PCIE_DW_EP
select PCI_IMX6
help
Enables support for the PCIe controller in the i.MX SoCs to
work in endpoint mode. The PCI controller on i.MX is based
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"
depends on OF && (ARM || ARCH_LAYERSCAPE || COMPILE_TEST)
depends on PCI_MSI
select PCIE_DW_HOST
select MFD_SYSCON
help
Say Y here if you want to enable PCIe controller support on Layerscape
SoCs to work in Host mode.
This controller can work either as EP or RC. The RCW[HOST_AGT_PEX]
determines which PCIe controller works in EP mode and which PCIe
controller works in RC mode.
config PCI_LAYERSCAPE_EP
bool "Freescale Layerscape PCIe controller - Endpoint mode"
depends on OF && (ARM || ARCH_LAYERSCAPE || COMPILE_TEST)
depends on PCI_ENDPOINT
select PCIE_DW_EP
help
Say Y here if you want to enable PCIe controller support on Layerscape
SoCs to work in Endpoint mode.
This controller can work either as EP or RC. The RCW[HOST_AGT_PEX]
determines which PCIe controller works in EP mode and which PCIe
controller works in RC mode.
config PCI_HISI
config PCIE_AL
bool "Amazon Annapurna Labs PCIe controller"
depends on OF && (ARM64 || COMPILE_TEST)
bool "HiSilicon Hip05 and Hip06 SoCs PCIe controllers"
depends on PCI_MSI
select PCIE_DW_HOST
select PCI_HOST_COMMON
select PCI_ECAM
help
Say Y here if you want PCIe controller support on HiSilicon
Hip05 and Hip06 SoCs
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 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
config PCI_MESON
tristate "Amlogic Meson PCIe controller"
default m if ARCH_MESON
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.
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_ARTPEC6
bool
config PCIE_ARTPEC6_HOST
bool "Axis ARTPEC-6 PCIe controller Host Mode"
bool "Axis ARTPEC-6 PCIe controller (host mode)"
depends on MACH_ARTPEC6 || COMPILE_TEST
depends on PCI_MSI
select PCIE_DW_HOST
@ -234,7 +52,7 @@ config PCIE_ARTPEC6_HOST
host mode. This uses the DesignWare core.
config PCIE_ARTPEC6_EP
bool "Axis ARTPEC-6 PCIe controller Endpoint Mode"
bool "Axis ARTPEC-6 PCIe controller (endpoint mode)"
depends on MACH_ARTPEC6 || COMPILE_TEST
depends on PCI_ENDPOINT
select PCIE_DW_EP
@ -252,19 +70,88 @@ config PCIE_BT1
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
config PCI_IMX6
bool
config PCI_IMX6_HOST
bool "Freescale i.MX6/7/8 PCIe controller (host mode)"
depends on ARCH_MXC || COMPILE_TEST
depends on PCI_MSI
depends on ARCH_ROCKCHIP || COMPILE_TEST
depends on OF
select PCIE_DW_HOST
select PCI_IMX6
help
Enables support for the DesignWare PCIe controller in the
Rockchip SoC except RK3399.
Enables support for the PCIe controller in the i.MX SoCs to
work in Root Complex mode. The PCI controller on i.MX is based
on DesignWare hardware and therefore the driver re-uses the
DesignWare core functions to implement the driver.
config PCI_IMX6_EP
bool "Freescale i.MX6/7/8 PCIe controller (endpoint mode)"
depends on ARCH_MXC || COMPILE_TEST
depends on PCI_ENDPOINT
select PCIE_DW_EP
select PCI_IMX6
help
Enables support for the PCIe controller in the i.MX SoCs to
work in endpoint mode. The PCI controller on i.MX 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)"
depends on OF && (ARM || ARCH_LAYERSCAPE || COMPILE_TEST)
depends on PCI_MSI
select PCIE_DW_HOST
select MFD_SYSCON
help
Say Y here if you want to enable PCIe controller support on Layerscape
SoCs to work in Host mode.
This controller can work either as EP or RC. The RCW[HOST_AGT_PEX]
determines which PCIe controller works in EP mode and which PCIe
controller works in RC mode.
config PCI_LAYERSCAPE_EP
bool "Freescale Layerscape PCIe controller (endpoint mode)"
depends on OF && (ARM || ARCH_LAYERSCAPE || COMPILE_TEST)
depends on PCI_ENDPOINT
select PCIE_DW_EP
help
Say Y here if you want to enable PCIe controller support on Layerscape
SoCs to work in Endpoint mode.
This controller can work either as EP or RC. The RCW[HOST_AGT_PEX]
determines which PCIe controller works in EP mode and which PCIe
controller works in RC mode.
config PCI_HISI
depends on OF && (ARM64 || COMPILE_TEST)
bool "HiSilicon Hip05 and Hip06 SoCs PCIe controller"
depends on PCI_MSI
select PCIE_DW_HOST
select PCI_HOST_COMMON
help
Say Y here if you want PCIe controller support on HiSilicon
Hip05 and Hip06 SoCs
config PCIE_KIRIN
depends on OF && (ARM64 || COMPILE_TEST)
tristate "HiSilicon Kirin PCIe controller"
depends on PCI_MSI
select PCIE_DW_HOST
select REGMAP_MMIO
help
Say Y here if you want PCIe controller support
on HiSilicon Kirin series SoCs.
config PCIE_HISI_STB
bool "HiSilicon STB PCIe controller"
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 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"
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 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
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
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
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 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
select PCIE_DW_HOST
select PCI_DRA7XX
default y if SOC_DRA7XX
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.
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
depends on SOC_SIFIVE || COMPILE_TEST
select PCIE_DW_HOST
help
Say Y here if you want PCIe controller support for the SiFive
FU740.
Say Y here if you want PCIe controller support on Toshiba Visconti SoC.
This driver supports TMPV7708 SoC.
endmenu

View 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

View 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 },

File diff suppressed because it is too large Load Diff

View 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

View 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;
}
}

View 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;
}

View 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);

View 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++;

View 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)

View 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

View 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.

View 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);

View File

@ -24,16 +24,16 @@
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",

View 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;
}

View 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
*

View 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

View 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);

View 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)
{

View 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 {

View 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");

View 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);

View 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

View 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);
}

View 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) {

View 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) &&

View 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;

View 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);

View 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;
}
}

View 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