diff options
139 files changed, 3434 insertions, 1637 deletions
@@ -2090,7 +2090,7 @@ S: Kuala Lumpur, Malaysia | |||
2090 | 2090 | ||
2091 | N: Mohit Kumar | 2091 | N: Mohit Kumar |
2092 | D: ST Microelectronics SPEAr13xx PCI host bridge driver | 2092 | D: ST Microelectronics SPEAr13xx PCI host bridge driver |
2093 | D: Synopsys Designware PCI host bridge driver | 2093 | D: Synopsys DesignWare PCI host bridge driver |
2094 | 2094 | ||
2095 | N: Gabor Kuti | 2095 | N: Gabor Kuti |
2096 | E: seasons@falcon.sch.bme.hu | 2096 | E: seasons@falcon.sch.bme.hu |
diff --git a/Documentation/devicetree/bindings/pci/83xx-512x-pci.txt b/Documentation/devicetree/bindings/pci/83xx-512x-pci.txt index 35a465362408..b9165b72473c 100644 --- a/Documentation/devicetree/bindings/pci/83xx-512x-pci.txt +++ b/Documentation/devicetree/bindings/pci/83xx-512x-pci.txt | |||
@@ -1,11 +1,11 @@ | |||
1 | * Freescale 83xx and 512x PCI bridges | 1 | * Freescale 83xx and 512x PCI bridges |
2 | 2 | ||
3 | Freescale 83xx and 512x SOCs include the same pci bridge core. | 3 | Freescale 83xx and 512x SOCs include the same PCI bridge core. |
4 | 4 | ||
5 | 83xx/512x specific notes: | 5 | 83xx/512x specific notes: |
6 | - reg: should contain two address length tuples | 6 | - reg: should contain two address length tuples |
7 | The first is for the internal pci bridge registers | 7 | The first is for the internal PCI bridge registers |
8 | The second is for the pci config space access registers | 8 | The second is for the PCI config space access registers |
9 | 9 | ||
10 | Example (MPC8313ERDB) | 10 | Example (MPC8313ERDB) |
11 | pci0: pci@e0008500 { | 11 | pci0: pci@e0008500 { |
diff --git a/Documentation/devicetree/bindings/pci/altera-pcie.txt b/Documentation/devicetree/bindings/pci/altera-pcie.txt index 2951a6a50704..495880193adc 100644 --- a/Documentation/devicetree/bindings/pci/altera-pcie.txt +++ b/Documentation/devicetree/bindings/pci/altera-pcie.txt | |||
@@ -7,21 +7,21 @@ Required properties: | |||
7 | "Txs": TX slave port region | 7 | "Txs": TX slave port region |
8 | "Cra": Control register access region | 8 | "Cra": Control register access region |
9 | - interrupt-parent: interrupt source phandle. | 9 | - interrupt-parent: interrupt source phandle. |
10 | - interrupts: specifies the interrupt source of the parent interrupt controller. | 10 | - interrupts: specifies the interrupt source of the parent interrupt |
11 | The format of the interrupt specifier depends on the parent interrupt | 11 | controller. The format of the interrupt specifier depends |
12 | controller. | 12 | on the parent interrupt controller. |
13 | - device_type: must be "pci" | 13 | - device_type: must be "pci" |
14 | - #address-cells: set to <3> | 14 | - #address-cells: set to <3> |
15 | - #size-cells: set to <2> | 15 | - #size-cells: set to <2> |
16 | - #interrupt-cells: set to <1> | 16 | - #interrupt-cells: set to <1> |
17 | - ranges: describes the translation of addresses for root ports and standard | 17 | - ranges: describes the translation of addresses for root ports and |
18 | PCI regions. | 18 | standard PCI regions. |
19 | - interrupt-map-mask and interrupt-map: standard PCI properties to define the | 19 | - interrupt-map-mask and interrupt-map: standard PCI properties to define the |
20 | mapping of the PCIe interface to interrupt numbers. | 20 | mapping of the PCIe interface to interrupt numbers. |
21 | 21 | ||
22 | Optional properties: | 22 | Optional properties: |
23 | - msi-parent: Link to the hardware entity that serves as the MSI controller for this PCIe | 23 | - msi-parent: Link to the hardware entity that serves as the MSI controller |
24 | controller. | 24 | for this PCIe controller. |
25 | - bus-range: PCI bus numbers covered | 25 | - bus-range: PCI bus numbers covered |
26 | 26 | ||
27 | Example | 27 | Example |
@@ -45,5 +45,5 @@ Example | |||
45 | <0 0 0 3 &pcie_0 3>, | 45 | <0 0 0 3 &pcie_0 3>, |
46 | <0 0 0 4 &pcie_0 4>; | 46 | <0 0 0 4 &pcie_0 4>; |
47 | ranges = <0x82000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x10000000 | 47 | ranges = <0x82000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x10000000 |
48 | 0x82000000 0x00000000 0x10000000 0xd0000000 0x00000000 0x10000000>; | 48 | 0x82000000 0x00000000 0x10000000 0xd0000000 0x00000000 0x10000000>; |
49 | }; | 49 | }; |
diff --git a/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt index 5ecaea1e6eee..4e4aee4439ea 100644 --- a/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt +++ b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt | |||
@@ -6,7 +6,7 @@ and thus inherits all the common properties defined in designware-pcie.txt. | |||
6 | Required properties: | 6 | Required properties: |
7 | - compatible: "axis,artpec6-pcie", "snps,dw-pcie" | 7 | - compatible: "axis,artpec6-pcie", "snps,dw-pcie" |
8 | - reg: base addresses and lengths of the PCIe controller (DBI), | 8 | - reg: base addresses and lengths of the PCIe controller (DBI), |
9 | the phy controller, and configuration address space. | 9 | the PHY controller, and configuration address space. |
10 | - reg-names: Must include the following entries: | 10 | - reg-names: Must include the following entries: |
11 | - "dbi" | 11 | - "dbi" |
12 | - "phy" | 12 | - "phy" |
diff --git a/Documentation/devicetree/bindings/pci/designware-pcie.txt b/Documentation/devicetree/bindings/pci/designware-pcie.txt index b2480dd38c11..1da7ade3183c 100644 --- a/Documentation/devicetree/bindings/pci/designware-pcie.txt +++ b/Documentation/devicetree/bindings/pci/designware-pcie.txt | |||
@@ -1,4 +1,4 @@ | |||
1 | * Synopsys Designware PCIe interface | 1 | * Synopsys DesignWare PCIe interface |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible: should contain "snps,dw-pcie" to identify the core. | 4 | - compatible: should contain "snps,dw-pcie" to identify the core. |
@@ -17,29 +17,27 @@ RC mode: | |||
17 | properties to define the mapping of the PCIe interface to interrupt | 17 | properties to define the mapping of the PCIe interface to interrupt |
18 | numbers. | 18 | numbers. |
19 | EP mode: | 19 | EP mode: |
20 | - num-ib-windows: number of inbound address translation | 20 | - num-ib-windows: number of inbound address translation windows |
21 | windows | 21 | - num-ob-windows: number of outbound address translation windows |
22 | - num-ob-windows: number of outbound address translation | ||
23 | windows | ||
24 | 22 | ||
25 | Optional properties: | 23 | Optional properties: |
26 | - num-lanes: number of lanes to use (this property should be specified unless | 24 | - num-lanes: number of lanes to use (this property should be specified unless |
27 | the link is brought already up in BIOS) | 25 | the link is brought already up in BIOS) |
28 | - reset-gpio: gpio pin number of power good signal | 26 | - reset-gpio: GPIO pin number of power good signal |
29 | - clocks: Must contain an entry for each entry in clock-names. | 27 | - clocks: Must contain an entry for each entry in clock-names. |
30 | See ../clocks/clock-bindings.txt for details. | 28 | See ../clocks/clock-bindings.txt for details. |
31 | - clock-names: Must include the following entries: | 29 | - clock-names: Must include the following entries: |
32 | - "pcie" | 30 | - "pcie" |
33 | - "pcie_bus" | 31 | - "pcie_bus" |
34 | RC mode: | 32 | RC mode: |
35 | - num-viewport: number of view ports configured in | 33 | - num-viewport: number of view ports configured in hardware. If a platform |
36 | hardware. If a platform does not specify it, the driver assumes 2. | 34 | does not specify it, the driver assumes 2. |
37 | - bus-range: PCI bus numbers covered (it is recommended | 35 | - bus-range: PCI bus numbers covered (it is recommended for new devicetrees |
38 | for new devicetrees to specify this property, to keep backwards | 36 | to specify this property, to keep backwards compatibility a range of |
39 | compatibility a range of 0x00-0xff is assumed if not present) | 37 | 0x00-0xff is assumed if not present) |
38 | |||
40 | EP mode: | 39 | EP mode: |
41 | - max-functions: maximum number of functions that can be | 40 | - max-functions: maximum number of functions that can be configured |
42 | configured | ||
43 | 41 | ||
44 | Example configuration: | 42 | Example configuration: |
45 | 43 | ||
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt index cf92d3ba5a26..7b1e48bf172b 100644 --- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt +++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt | |||
@@ -1,6 +1,6 @@ | |||
1 | * Freescale i.MX6 PCIe interface | 1 | * Freescale i.MX6 PCIe interface |
2 | 2 | ||
3 | This PCIe host controller is based on the Synopsis Designware PCIe IP | 3 | This PCIe host controller is based on the Synopsys DesignWare PCIe IP |
4 | and thus inherits all the common properties defined in designware-pcie.txt. | 4 | and thus inherits all the common properties defined in designware-pcie.txt. |
5 | 5 | ||
6 | Required properties: | 6 | Required properties: |
diff --git a/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt b/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt index 7a579c816951..bdb7ab39d2d7 100644 --- a/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt +++ b/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt | |||
@@ -1,7 +1,7 @@ | |||
1 | HiSilicon Hip05 and Hip06 PCIe host bridge DT description | 1 | HiSilicon Hip05 and Hip06 PCIe host bridge DT description |
2 | 2 | ||
3 | HiSilicon PCIe host controller is based on Designware PCI core. | 3 | HiSilicon PCIe host controller is based on the Synopsys DesignWare PCI core. |
4 | It shares common functions with PCIe Designware core driver and inherits | 4 | It shares common functions with the PCIe DesignWare core driver and inherits |
5 | common properties defined in | 5 | common properties defined in |
6 | Documentation/devicetree/bindings/pci/designware-pci.txt. | 6 | Documentation/devicetree/bindings/pci/designware-pci.txt. |
7 | 7 | ||
diff --git a/Documentation/devicetree/bindings/pci/kirin-pcie.txt b/Documentation/devicetree/bindings/pci/kirin-pcie.txt index 68ffa0fbcd73..6e217c63123d 100644 --- a/Documentation/devicetree/bindings/pci/kirin-pcie.txt +++ b/Documentation/devicetree/bindings/pci/kirin-pcie.txt | |||
@@ -1,8 +1,8 @@ | |||
1 | HiSilicon Kirin SoCs PCIe host DT description | 1 | HiSilicon Kirin SoCs PCIe host DT description |
2 | 2 | ||
3 | Kirin PCIe host controller is based on Designware PCI core. | 3 | Kirin PCIe host controller is based on the Synopsys DesignWare PCI core. |
4 | It shares common functions with PCIe Designware core driver | 4 | It shares common functions with the PCIe DesignWare core driver and |
5 | and inherits common properties defined in | 5 | inherits common properties defined in |
6 | Documentation/devicetree/bindings/pci/designware-pci.txt. | 6 | Documentation/devicetree/bindings/pci/designware-pci.txt. |
7 | 7 | ||
8 | Additional properties are described here: | 8 | Additional properties are described here: |
@@ -16,7 +16,7 @@ Required properties | |||
16 | "apb": apb Ctrl register defined by Kirin; | 16 | "apb": apb Ctrl register defined by Kirin; |
17 | "phy": apb PHY register defined by Kirin; | 17 | "phy": apb PHY register defined by Kirin; |
18 | "config": PCIe configuration space registers. | 18 | "config": PCIe configuration space registers. |
19 | - reset-gpios: The gpio to generate PCIe perst assert and deassert signal. | 19 | - reset-gpios: The GPIO to generate PCIe PERST# assert and deassert signal. |
20 | 20 | ||
21 | Optional properties: | 21 | Optional properties: |
22 | 22 | ||
diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci.txt b/Documentation/devicetree/bindings/pci/layerscape-pci.txt index ee1c72d5162e..c0484da0f20d 100644 --- a/Documentation/devicetree/bindings/pci/layerscape-pci.txt +++ b/Documentation/devicetree/bindings/pci/layerscape-pci.txt | |||
@@ -15,8 +15,10 @@ Required properties: | |||
15 | - compatible: should contain the platform identifier such as: | 15 | - compatible: should contain the platform identifier such as: |
16 | "fsl,ls1021a-pcie", "snps,dw-pcie" | 16 | "fsl,ls1021a-pcie", "snps,dw-pcie" |
17 | "fsl,ls2080a-pcie", "fsl,ls2085a-pcie", "snps,dw-pcie" | 17 | "fsl,ls2080a-pcie", "fsl,ls2085a-pcie", "snps,dw-pcie" |
18 | "fsl,ls2088a-pcie" | ||
19 | "fsl,ls1088a-pcie" | ||
18 | "fsl,ls1046a-pcie" | 20 | "fsl,ls1046a-pcie" |
19 | - reg: base addresses and lengths of the PCIe controller | 21 | - reg: base addresses and lengths of the PCIe controller register blocks. |
20 | - interrupts: A list of interrupt outputs of the controller. Must contain an | 22 | - interrupts: A list of interrupt outputs of the controller. Must contain an |
21 | entry for each entry in the interrupt-names property. | 23 | entry for each entry in the interrupt-names property. |
22 | - interrupt-names: Must include the following entries: | 24 | - interrupt-names: Must include the following entries: |
diff --git a/Documentation/devicetree/bindings/pci/mediatek,mt7623-pcie.txt b/Documentation/devicetree/bindings/pci/mediatek,mt7623-pcie.txt deleted file mode 100644 index fe80dda9bf73..000000000000 --- a/Documentation/devicetree/bindings/pci/mediatek,mt7623-pcie.txt +++ /dev/null | |||
@@ -1,130 +0,0 @@ | |||
1 | MediaTek Gen2 PCIe controller which is available on MT7623 series SoCs | ||
2 | |||
3 | PCIe subsys supports single root complex (RC) with 3 Root Ports. Each root | ||
4 | ports supports a Gen2 1-lane Link and has PIPE interface to PHY. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: Should contain "mediatek,mt7623-pcie". | ||
8 | - device_type: Must be "pci" | ||
9 | - reg: Base addresses and lengths of the PCIe controller. | ||
10 | - #address-cells: Address representation for root ports (must be 3) | ||
11 | - #size-cells: Size representation for root ports (must be 2) | ||
12 | - #interrupt-cells: Size representation for interrupts (must be 1) | ||
13 | - interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties | ||
14 | Please refer to the standard PCI bus binding document for a more detailed | ||
15 | explanation. | ||
16 | - clocks: Must contain an entry for each entry in clock-names. | ||
17 | See ../clocks/clock-bindings.txt for details. | ||
18 | - clock-names: Must include the following entries: | ||
19 | - free_ck :for reference clock of PCIe subsys | ||
20 | - sys_ck0 :for clock of Port0 | ||
21 | - sys_ck1 :for clock of Port1 | ||
22 | - sys_ck2 :for clock of Port2 | ||
23 | - resets: Must contain an entry for each entry in reset-names. | ||
24 | See ../reset/reset.txt for details. | ||
25 | - reset-names: Must include the following entries: | ||
26 | - pcie-rst0 :port0 reset | ||
27 | - pcie-rst1 :port1 reset | ||
28 | - pcie-rst2 :port2 reset | ||
29 | - phys: List of PHY specifiers (used by generic PHY framework). | ||
30 | - phy-names : Must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the | ||
31 | number of PHYs as specified in *phys* property. | ||
32 | - power-domains: A phandle and power domain specifier pair to the power domain | ||
33 | which is responsible for collapsing and restoring power to the peripheral. | ||
34 | - bus-range: Range of bus numbers associated with this controller. | ||
35 | - ranges: Ranges for the PCI memory and I/O regions. | ||
36 | |||
37 | In addition, the device tree node must have sub-nodes describing each | ||
38 | PCIe port interface, having the following mandatory properties: | ||
39 | |||
40 | Required properties: | ||
41 | - device_type: Must be "pci" | ||
42 | - reg: Only the first four bytes are used to refer to the correct bus number | ||
43 | and device number. | ||
44 | - #address-cells: Must be 3 | ||
45 | - #size-cells: Must be 2 | ||
46 | - #interrupt-cells: Must be 1 | ||
47 | - interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties | ||
48 | Please refer to the standard PCI bus binding document for a more detailed | ||
49 | explanation. | ||
50 | - ranges: Sub-ranges distributed from the PCIe controller node. An empty | ||
51 | property is sufficient. | ||
52 | - num-lanes: Number of lanes to use for this port. | ||
53 | |||
54 | Examples: | ||
55 | |||
56 | hifsys: syscon@1a000000 { | ||
57 | compatible = "mediatek,mt7623-hifsys", | ||
58 | "mediatek,mt2701-hifsys", | ||
59 | "syscon"; | ||
60 | reg = <0 0x1a000000 0 0x1000>; | ||
61 | #clock-cells = <1>; | ||
62 | #reset-cells = <1>; | ||
63 | }; | ||
64 | |||
65 | pcie: pcie-controller@1a140000 { | ||
66 | compatible = "mediatek,mt7623-pcie"; | ||
67 | device_type = "pci"; | ||
68 | reg = <0 0x1a140000 0 0x1000>, /* PCIe shared registers */ | ||
69 | <0 0x1a142000 0 0x1000>, /* Port0 registers */ | ||
70 | <0 0x1a143000 0 0x1000>, /* Port1 registers */ | ||
71 | <0 0x1a144000 0 0x1000>; /* Port2 registers */ | ||
72 | #address-cells = <3>; | ||
73 | #size-cells = <2>; | ||
74 | #interrupt-cells = <1>; | ||
75 | interrupt-map-mask = <0xf800 0 0 0>; | ||
76 | interrupt-map = <0x0000 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>, | ||
77 | <0x0800 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>, | ||
78 | <0x1000 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; | ||
79 | clocks = <&topckgen CLK_TOP_ETHIF_SEL>, | ||
80 | <&hifsys CLK_HIFSYS_PCIE0>, | ||
81 | <&hifsys CLK_HIFSYS_PCIE1>, | ||
82 | <&hifsys CLK_HIFSYS_PCIE2>; | ||
83 | clock-names = "free_ck", "sys_ck0", "sys_ck1", "sys_ck2"; | ||
84 | resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>, | ||
85 | <&hifsys MT2701_HIFSYS_PCIE1_RST>, | ||
86 | <&hifsys MT2701_HIFSYS_PCIE2_RST>; | ||
87 | reset-names = "pcie-rst0", "pcie-rst1", "pcie-rst2"; | ||
88 | phys = <&pcie0_phy>, <&pcie1_phy>, <&pcie2_phy>; | ||
89 | phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2"; | ||
90 | power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; | ||
91 | bus-range = <0x00 0xff>; | ||
92 | ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000 /* I/O space */ | ||
93 | 0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* memory space */ | ||
94 | |||
95 | pcie@0,0 { | ||
96 | device_type = "pci"; | ||
97 | reg = <0x0000 0 0 0 0>; | ||
98 | #address-cells = <3>; | ||
99 | #size-cells = <2>; | ||
100 | #interrupt-cells = <1>; | ||
101 | interrupt-map-mask = <0 0 0 0>; | ||
102 | interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>; | ||
103 | ranges; | ||
104 | num-lanes = <1>; | ||
105 | }; | ||
106 | |||
107 | pcie@1,0 { | ||
108 | device_type = "pci"; | ||
109 | reg = <0x0800 0 0 0 0>; | ||
110 | #address-cells = <3>; | ||
111 | #size-cells = <2>; | ||
112 | #interrupt-cells = <1>; | ||
113 | interrupt-map-mask = <0 0 0 0>; | ||
114 | interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>; | ||
115 | ranges; | ||
116 | num-lanes = <1>; | ||
117 | }; | ||
118 | |||
119 | pcie@2,0 { | ||
120 | device_type = "pci"; | ||
121 | reg = <0x1000 0 0 0 0>; | ||
122 | #address-cells = <3>; | ||
123 | #size-cells = <2>; | ||
124 | #interrupt-cells = <1>; | ||
125 | interrupt-map-mask = <0 0 0 0>; | ||
126 | interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; | ||
127 | ranges; | ||
128 | num-lanes = <1>; | ||
129 | }; | ||
130 | }; | ||
diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt new file mode 100644 index 000000000000..3a6ce55dd310 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt | |||
@@ -0,0 +1,284 @@ | |||
1 | MediaTek Gen2 PCIe controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should contain one of the following strings: | ||
5 | "mediatek,mt2701-pcie" | ||
6 | "mediatek,mt2712-pcie" | ||
7 | "mediatek,mt7622-pcie" | ||
8 | "mediatek,mt7623-pcie" | ||
9 | - device_type: Must be "pci" | ||
10 | - reg: Base addresses and lengths of the PCIe subsys and root ports. | ||
11 | - reg-names: Names of the above areas to use during resource lookup. | ||
12 | - #address-cells: Address representation for root ports (must be 3) | ||
13 | - #size-cells: Size representation for root ports (must be 2) | ||
14 | - clocks: Must contain an entry for each entry in clock-names. | ||
15 | See ../clocks/clock-bindings.txt for details. | ||
16 | - clock-names: | ||
17 | Mandatory entries: | ||
18 | - sys_ckN :transaction layer and data link layer clock | ||
19 | Required entries for MT2701/MT7623: | ||
20 | - free_ck :for reference clock of PCIe subsys | ||
21 | Required entries for MT2712/MT7622: | ||
22 | - ahb_ckN :AHB slave interface operating clock for CSR access and RC | ||
23 | initiated MMIO access | ||
24 | Required entries for MT7622: | ||
25 | - axi_ckN :application layer MMIO channel operating clock | ||
26 | - aux_ckN :pe2_mac_bridge and pe2_mac_core operating clock when | ||
27 | pcie_mac_ck/pcie_pipe_ck is turned off | ||
28 | - obff_ckN :OBFF functional block operating clock | ||
29 | - pipe_ckN :LTSSM and PHY/MAC layer operating clock | ||
30 | where N starting from 0 to one less than the number of root ports. | ||
31 | - phys: List of PHY specifiers (used by generic PHY framework). | ||
32 | - phy-names : Must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the | ||
33 | number of PHYs as specified in *phys* property. | ||
34 | - power-domains: A phandle and power domain specifier pair to the power domain | ||
35 | which is responsible for collapsing and restoring power to the peripheral. | ||
36 | - bus-range: Range of bus numbers associated with this controller. | ||
37 | - ranges: Ranges for the PCI memory and I/O regions. | ||
38 | |||
39 | Required properties for MT7623/MT2701: | ||
40 | - #interrupt-cells: Size representation for interrupts (must be 1) | ||
41 | - interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties | ||
42 | Please refer to the standard PCI bus binding document for a more detailed | ||
43 | explanation. | ||
44 | - resets: Must contain an entry for each entry in reset-names. | ||
45 | See ../reset/reset.txt for details. | ||
46 | - reset-names: Must be "pcie-rst0", "pcie-rst1", "pcie-rstN".. based on the | ||
47 | number of root ports. | ||
48 | |||
49 | Required properties for MT2712/MT7622: | ||
50 | -interrupts: A list of interrupt outputs of the controller, must have one | ||
51 | entry for each PCIe port | ||
52 | |||
53 | In addition, the device tree node must have sub-nodes describing each | ||
54 | PCIe port interface, having the following mandatory properties: | ||
55 | |||
56 | Required properties: | ||
57 | - device_type: Must be "pci" | ||
58 | - reg: Only the first four bytes are used to refer to the correct bus number | ||
59 | and device number. | ||
60 | - #address-cells: Must be 3 | ||
61 | - #size-cells: Must be 2 | ||
62 | - #interrupt-cells: Must be 1 | ||
63 | - interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties | ||
64 | Please refer to the standard PCI bus binding document for a more detailed | ||
65 | explanation. | ||
66 | - ranges: Sub-ranges distributed from the PCIe controller node. An empty | ||
67 | property is sufficient. | ||
68 | - num-lanes: Number of lanes to use for this port. | ||
69 | |||
70 | Examples for MT7623: | ||
71 | |||
72 | hifsys: syscon@1a000000 { | ||
73 | compatible = "mediatek,mt7623-hifsys", | ||
74 | "mediatek,mt2701-hifsys", | ||
75 | "syscon"; | ||
76 | reg = <0 0x1a000000 0 0x1000>; | ||
77 | #clock-cells = <1>; | ||
78 | #reset-cells = <1>; | ||
79 | }; | ||
80 | |||
81 | pcie: pcie-controller@1a140000 { | ||
82 | compatible = "mediatek,mt7623-pcie"; | ||
83 | device_type = "pci"; | ||
84 | reg = <0 0x1a140000 0 0x1000>, /* PCIe shared registers */ | ||
85 | <0 0x1a142000 0 0x1000>, /* Port0 registers */ | ||
86 | <0 0x1a143000 0 0x1000>, /* Port1 registers */ | ||
87 | <0 0x1a144000 0 0x1000>; /* Port2 registers */ | ||
88 | reg-names = "subsys", "port0", "port1", "port2"; | ||
89 | #address-cells = <3>; | ||
90 | #size-cells = <2>; | ||
91 | #interrupt-cells = <1>; | ||
92 | interrupt-map-mask = <0xf800 0 0 0>; | ||
93 | interrupt-map = <0x0000 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>, | ||
94 | <0x0800 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>, | ||
95 | <0x1000 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; | ||
96 | clocks = <&topckgen CLK_TOP_ETHIF_SEL>, | ||
97 | <&hifsys CLK_HIFSYS_PCIE0>, | ||
98 | <&hifsys CLK_HIFSYS_PCIE1>, | ||
99 | <&hifsys CLK_HIFSYS_PCIE2>; | ||
100 | clock-names = "free_ck", "sys_ck0", "sys_ck1", "sys_ck2"; | ||
101 | resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>, | ||
102 | <&hifsys MT2701_HIFSYS_PCIE1_RST>, | ||
103 | <&hifsys MT2701_HIFSYS_PCIE2_RST>; | ||
104 | reset-names = "pcie-rst0", "pcie-rst1", "pcie-rst2"; | ||
105 | phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>, | ||
106 | <&pcie2_phy PHY_TYPE_PCIE>; | ||
107 | phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2"; | ||
108 | power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; | ||
109 | bus-range = <0x00 0xff>; | ||
110 | ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000 /* I/O space */ | ||
111 | 0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* memory space */ | ||
112 | |||
113 | pcie@0,0 { | ||
114 | device_type = "pci"; | ||
115 | reg = <0x0000 0 0 0 0>; | ||
116 | #address-cells = <3>; | ||
117 | #size-cells = <2>; | ||
118 | #interrupt-cells = <1>; | ||
119 | interrupt-map-mask = <0 0 0 0>; | ||
120 | interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>; | ||
121 | ranges; | ||
122 | num-lanes = <1>; | ||
123 | }; | ||
124 | |||
125 | pcie@1,0 { | ||
126 | device_type = "pci"; | ||
127 | reg = <0x0800 0 0 0 0>; | ||
128 | #address-cells = <3>; | ||
129 | #size-cells = <2>; | ||
130 | #interrupt-cells = <1>; | ||
131 | interrupt-map-mask = <0 0 0 0>; | ||
132 | interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>; | ||
133 | ranges; | ||
134 | num-lanes = <1>; | ||
135 | }; | ||
136 | |||
137 | pcie@2,0 { | ||
138 | device_type = "pci"; | ||
139 | reg = <0x1000 0 0 0 0>; | ||
140 | #address-cells = <3>; | ||
141 | #size-cells = <2>; | ||
142 | #interrupt-cells = <1>; | ||
143 | interrupt-map-mask = <0 0 0 0>; | ||
144 | interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; | ||
145 | ranges; | ||
146 | num-lanes = <1>; | ||
147 | }; | ||
148 | }; | ||
149 | |||
150 | Examples for MT2712: | ||
151 | pcie: pcie@11700000 { | ||
152 | compatible = "mediatek,mt2712-pcie"; | ||
153 | device_type = "pci"; | ||
154 | reg = <0 0x11700000 0 0x1000>, | ||
155 | <0 0x112ff000 0 0x1000>; | ||
156 | reg-names = "port0", "port1"; | ||
157 | #address-cells = <3>; | ||
158 | #size-cells = <2>; | ||
159 | interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>, | ||
160 | <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; | ||
161 | clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>, | ||
162 | <&topckgen CLK_TOP_PE2_MAC_P1_SEL>, | ||
163 | <&pericfg CLK_PERI_PCIE0>, | ||
164 | <&pericfg CLK_PERI_PCIE1>; | ||
165 | clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1"; | ||
166 | phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>; | ||
167 | phy-names = "pcie-phy0", "pcie-phy1"; | ||
168 | bus-range = <0x00 0xff>; | ||
169 | ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; | ||
170 | |||
171 | pcie0: pcie@0,0 { | ||
172 | device_type = "pci"; | ||
173 | reg = <0x0000 0 0 0 0>; | ||
174 | #address-cells = <3>; | ||
175 | #size-cells = <2>; | ||
176 | #interrupt-cells = <1>; | ||
177 | ranges; | ||
178 | num-lanes = <1>; | ||
179 | interrupt-map-mask = <0 0 0 7>; | ||
180 | interrupt-map = <0 0 0 1 &pcie_intc0 0>, | ||
181 | <0 0 0 2 &pcie_intc0 1>, | ||
182 | <0 0 0 3 &pcie_intc0 2>, | ||
183 | <0 0 0 4 &pcie_intc0 3>; | ||
184 | pcie_intc0: interrupt-controller { | ||
185 | interrupt-controller; | ||
186 | #address-cells = <0>; | ||
187 | #interrupt-cells = <1>; | ||
188 | }; | ||
189 | }; | ||
190 | |||
191 | pcie1: pcie@1,0 { | ||
192 | device_type = "pci"; | ||
193 | reg = <0x0800 0 0 0 0>; | ||
194 | #address-cells = <3>; | ||
195 | #size-cells = <2>; | ||
196 | #interrupt-cells = <1>; | ||
197 | ranges; | ||
198 | num-lanes = <1>; | ||
199 | interrupt-map-mask = <0 0 0 7>; | ||
200 | interrupt-map = <0 0 0 1 &pcie_intc1 0>, | ||
201 | <0 0 0 2 &pcie_intc1 1>, | ||
202 | <0 0 0 3 &pcie_intc1 2>, | ||
203 | <0 0 0 4 &pcie_intc1 3>; | ||
204 | pcie_intc1: interrupt-controller { | ||
205 | interrupt-controller; | ||
206 | #address-cells = <0>; | ||
207 | #interrupt-cells = <1>; | ||
208 | }; | ||
209 | }; | ||
210 | }; | ||
211 | |||
212 | Examples for MT7622: | ||
213 | pcie: pcie@1a140000 { | ||
214 | compatible = "mediatek,mt7622-pcie"; | ||
215 | device_type = "pci"; | ||
216 | reg = <0 0x1a140000 0 0x1000>, | ||
217 | <0 0x1a143000 0 0x1000>, | ||
218 | <0 0x1a145000 0 0x1000>; | ||
219 | reg-names = "subsys", "port0", "port1"; | ||
220 | #address-cells = <3>; | ||
221 | #size-cells = <2>; | ||
222 | interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_LOW>, | ||
223 | <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>; | ||
224 | clocks = <&pciesys CLK_PCIE_P0_MAC_EN>, | ||
225 | <&pciesys CLK_PCIE_P1_MAC_EN>, | ||
226 | <&pciesys CLK_PCIE_P0_AHB_EN>, | ||
227 | <&pciesys CLK_PCIE_P1_AHB_EN>, | ||
228 | <&pciesys CLK_PCIE_P0_AUX_EN>, | ||
229 | <&pciesys CLK_PCIE_P1_AUX_EN>, | ||
230 | <&pciesys CLK_PCIE_P0_AXI_EN>, | ||
231 | <&pciesys CLK_PCIE_P1_AXI_EN>, | ||
232 | <&pciesys CLK_PCIE_P0_OBFF_EN>, | ||
233 | <&pciesys CLK_PCIE_P1_OBFF_EN>, | ||
234 | <&pciesys CLK_PCIE_P0_PIPE_EN>, | ||
235 | <&pciesys CLK_PCIE_P1_PIPE_EN>; | ||
236 | clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1", | ||
237 | "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1", | ||
238 | "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1"; | ||
239 | phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>; | ||
240 | phy-names = "pcie-phy0", "pcie-phy1"; | ||
241 | power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; | ||
242 | bus-range = <0x00 0xff>; | ||
243 | ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; | ||
244 | |||
245 | pcie0: pcie@0,0 { | ||
246 | device_type = "pci"; | ||
247 | reg = <0x0000 0 0 0 0>; | ||
248 | #address-cells = <3>; | ||
249 | #size-cells = <2>; | ||
250 | #interrupt-cells = <1>; | ||
251 | ranges; | ||
252 | num-lanes = <1>; | ||
253 | interrupt-map-mask = <0 0 0 7>; | ||
254 | interrupt-map = <0 0 0 1 &pcie_intc0 0>, | ||
255 | <0 0 0 2 &pcie_intc0 1>, | ||
256 | <0 0 0 3 &pcie_intc0 2>, | ||
257 | <0 0 0 4 &pcie_intc0 3>; | ||
258 | pcie_intc0: interrupt-controller { | ||
259 | interrupt-controller; | ||
260 | #address-cells = <0>; | ||
261 | #interrupt-cells = <1>; | ||
262 | }; | ||
263 | }; | ||
264 | |||
265 | pcie1: pcie@1,0 { | ||
266 | device_type = "pci"; | ||
267 | reg = <0x0800 0 0 0 0>; | ||
268 | #address-cells = <3>; | ||
269 | #size-cells = <2>; | ||
270 | #interrupt-cells = <1>; | ||
271 | ranges; | ||
272 | num-lanes = <1>; | ||
273 | interrupt-map-mask = <0 0 0 7>; | ||
274 | interrupt-map = <0 0 0 1 &pcie_intc1 0>, | ||
275 | <0 0 0 2 &pcie_intc1 1>, | ||
276 | <0 0 0 3 &pcie_intc1 2>, | ||
277 | <0 0 0 4 &pcie_intc1 3>; | ||
278 | pcie_intc1: interrupt-controller { | ||
279 | interrupt-controller; | ||
280 | #address-cells = <0>; | ||
281 | #interrupt-cells = <1>; | ||
282 | }; | ||
283 | }; | ||
284 | }; | ||
diff --git a/Documentation/devicetree/bindings/pci/mvebu-pci.txt b/Documentation/devicetree/bindings/pci/mvebu-pci.txt index 9c7fce69570b..127ae1f53e5a 100644 --- a/Documentation/devicetree/bindings/pci/mvebu-pci.txt +++ b/Documentation/devicetree/bindings/pci/mvebu-pci.txt | |||
@@ -77,7 +77,7 @@ and the following optional properties: | |||
77 | - marvell,pcie-lane: the physical PCIe lane number, for ports having | 77 | - marvell,pcie-lane: the physical PCIe lane number, for ports having |
78 | multiple lanes. If this property is not found, we assume that the | 78 | multiple lanes. If this property is not found, we assume that the |
79 | value is 0. | 79 | value is 0. |
80 | - reset-gpios: optional gpio to PERST# | 80 | - reset-gpios: optional GPIO to PERST# |
81 | - reset-delay-us: delay in us to wait after reset de-assertion, if not | 81 | - reset-delay-us: delay in us to wait after reset de-assertion, if not |
82 | specified will default to 100ms, as required by the PCIe specification. | 82 | specified will default to 100ms, as required by the PCIe specification. |
83 | 83 | ||
diff --git a/Documentation/devicetree/bindings/pci/pci-armada8k.txt b/Documentation/devicetree/bindings/pci/pci-armada8k.txt index 6b115fd10fec..c1e4c3d10a74 100644 --- a/Documentation/devicetree/bindings/pci/pci-armada8k.txt +++ b/Documentation/devicetree/bindings/pci/pci-armada8k.txt | |||
@@ -1,6 +1,6 @@ | |||
1 | * Marvell Armada 7K/8K PCIe interface | 1 | * Marvell Armada 7K/8K PCIe interface |
2 | 2 | ||
3 | This PCIe host controller is based on the Synopsis Designware PCIe IP | 3 | This PCIe host controller is based on the Synopsys DesignWare PCIe IP |
4 | and thus inherits all the common properties defined in designware-pcie.txt. | 4 | and thus inherits all the common properties defined in designware-pcie.txt. |
5 | 5 | ||
6 | Required properties: | 6 | Required properties: |
diff --git a/Documentation/devicetree/bindings/pci/pci-keystone.txt b/Documentation/devicetree/bindings/pci/pci-keystone.txt index d08a4d51108f..7e05487544ed 100644 --- a/Documentation/devicetree/bindings/pci/pci-keystone.txt +++ b/Documentation/devicetree/bindings/pci/pci-keystone.txt | |||
@@ -1,12 +1,12 @@ | |||
1 | TI Keystone PCIe interface | 1 | TI Keystone PCIe interface |
2 | 2 | ||
3 | Keystone PCI host Controller is based on Designware PCI h/w version 3.65. | 3 | Keystone PCI host Controller is based on the Synopsys DesignWare PCI |
4 | It shares common functions with PCIe Designware core driver and inherit | 4 | hardware version 3.65. It shares common functions with the PCIe DesignWare |
5 | common properties defined in | 5 | core driver and inherits common properties defined in |
6 | Documentation/devicetree/bindings/pci/designware-pci.txt | 6 | Documentation/devicetree/bindings/pci/designware-pci.txt |
7 | 7 | ||
8 | Please refer to Documentation/devicetree/bindings/pci/designware-pci.txt | 8 | Please refer to Documentation/devicetree/bindings/pci/designware-pci.txt |
9 | for the details of Designware DT bindings. Additional properties are | 9 | for the details of DesignWare DT bindings. Additional properties are |
10 | described here as well as properties that are not applicable. | 10 | described here as well as properties that are not applicable. |
11 | 11 | ||
12 | Required Properties:- | 12 | Required Properties:- |
@@ -52,13 +52,12 @@ pcie_intc: Interrupt controller device node for Legacy IRQ chip | |||
52 | }; | 52 | }; |
53 | 53 | ||
54 | Optional properties:- | 54 | Optional properties:- |
55 | phys: phandle to Generic Keystone SerDes phy for PCI | 55 | phys: phandle to generic Keystone SerDes PHY for PCI |
56 | phy-names: name of the Generic Keystine SerDes phy for PCI | 56 | phy-names: name of the generic Keystone SerDes PHY for PCI |
57 | - If boot loader already does PCI link establishment, then phys and | 57 | - If boot loader already does PCI link establishment, then phys and |
58 | phy-names shouldn't be present. | 58 | phy-names shouldn't be present. |
59 | interrupts: platform interrupt for error interrupts. | 59 | interrupts: platform interrupt for error interrupts. |
60 | 60 | ||
61 | Designware DT Properties not applicable for Keystone PCI | 61 | DesignWare DT Properties not applicable for Keystone PCI |
62 | 62 | ||
63 | 1. pcie_bus clock-names not used. Instead, a phandle to phys is used. | 63 | 1. pcie_bus clock-names not used. Instead, a phandle to phys is used. |
64 | |||
diff --git a/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt b/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt index 07a75094c5a8..3d038638612b 100644 --- a/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt +++ b/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt | |||
@@ -6,11 +6,14 @@ AHB. There is one bridge instance per USB port connected to the internal | |||
6 | OHCI and EHCI controllers. | 6 | OHCI and EHCI controllers. |
7 | 7 | ||
8 | Required properties: | 8 | Required properties: |
9 | - compatible: "renesas,pci-r8a7790" for the R8A7790 SoC; | 9 | - compatible: "renesas,pci-r8a7743" for the R8A7743 SoC; |
10 | "renesas,pci-r8a7745" for the R8A7745 SoC; | ||
11 | "renesas,pci-r8a7790" for the R8A7790 SoC; | ||
10 | "renesas,pci-r8a7791" for the R8A7791 SoC; | 12 | "renesas,pci-r8a7791" for the R8A7791 SoC; |
11 | "renesas,pci-r8a7793" for the R8A7793 SoC; | 13 | "renesas,pci-r8a7793" for the R8A7793 SoC; |
12 | "renesas,pci-r8a7794" for the R8A7794 SoC; | 14 | "renesas,pci-r8a7794" for the R8A7794 SoC; |
13 | "renesas,pci-rcar-gen2" for a generic R-Car Gen2 compatible device | 15 | "renesas,pci-rcar-gen2" for a generic R-Car Gen2 or |
16 | RZ/G1 compatible device. | ||
14 | 17 | ||
15 | 18 | ||
16 | When compatible with the generic version, nodes must list the | 19 | When compatible with the generic version, nodes must list the |
diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.txt b/Documentation/devicetree/bindings/pci/qcom,pcie.txt index 9d418b71774f..3c9d321b3d3b 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie.txt +++ b/Documentation/devicetree/bindings/pci/qcom,pcie.txt | |||
@@ -9,6 +9,7 @@ | |||
9 | - "qcom,pcie-apq8084" for apq8084 | 9 | - "qcom,pcie-apq8084" for apq8084 |
10 | - "qcom,pcie-msm8996" for msm8996 or apq8096 | 10 | - "qcom,pcie-msm8996" for msm8996 or apq8096 |
11 | - "qcom,pcie-ipq4019" for ipq4019 | 11 | - "qcom,pcie-ipq4019" for ipq4019 |
12 | - "qcom,pcie-ipq8074" for ipq8074 | ||
12 | 13 | ||
13 | - reg: | 14 | - reg: |
14 | Usage: required | 15 | Usage: required |
@@ -20,7 +21,7 @@ | |||
20 | Value type: <stringlist> | 21 | Value type: <stringlist> |
21 | Definition: Must include the following entries | 22 | Definition: Must include the following entries |
22 | - "parf" Qualcomm specific registers | 23 | - "parf" Qualcomm specific registers |
23 | - "dbi" Designware PCIe registers | 24 | - "dbi" DesignWare PCIe registers |
24 | - "elbi" External local bus interface registers | 25 | - "elbi" External local bus interface registers |
25 | - "config" PCIe configuration space | 26 | - "config" PCIe configuration space |
26 | 27 | ||
@@ -105,6 +106,16 @@ | |||
105 | - "bus_master" Master AXI clock | 106 | - "bus_master" Master AXI clock |
106 | - "bus_slave" Slave AXI clock | 107 | - "bus_slave" Slave AXI clock |
107 | 108 | ||
109 | - clock-names: | ||
110 | Usage: required for ipq8074 | ||
111 | Value type: <stringlist> | ||
112 | Definition: Should contain the following entries | ||
113 | - "iface" PCIe to SysNOC BIU clock | ||
114 | - "axi_m" AXI Master clock | ||
115 | - "axi_s" AXI Slave clock | ||
116 | - "ahb" AHB clock | ||
117 | - "aux" Auxiliary clock | ||
118 | |||
108 | - resets: | 119 | - resets: |
109 | Usage: required | 120 | Usage: required |
110 | Value type: <prop-encoded-array> | 121 | Value type: <prop-encoded-array> |
@@ -144,6 +155,18 @@ | |||
144 | - "ahb" AHB reset | 155 | - "ahb" AHB reset |
145 | - "phy_ahb" PHY AHB reset | 156 | - "phy_ahb" PHY AHB reset |
146 | 157 | ||
158 | - reset-names: | ||
159 | Usage: required for ipq8074 | ||
160 | Value type: <stringlist> | ||
161 | Definition: Should contain the following entries | ||
162 | - "pipe" PIPE reset | ||
163 | - "sleep" Sleep reset | ||
164 | - "sticky" Core Sticky reset | ||
165 | - "axi_m" AXI Master reset | ||
166 | - "axi_s" AXI Slave reset | ||
167 | - "ahb" AHB Reset | ||
168 | - "axi_m_sticky" AXI Master Sticky reset | ||
169 | |||
147 | - power-domains: | 170 | - power-domains: |
148 | Usage: required for apq8084 and msm8996/apq8096 | 171 | Usage: required for apq8084 and msm8996/apq8096 |
149 | Value type: <prop-encoded-array> | 172 | Value type: <prop-encoded-array> |
@@ -180,7 +203,7 @@ | |||
180 | - <name>-gpios: | 203 | - <name>-gpios: |
181 | Usage: optional | 204 | Usage: optional |
182 | Value type: <prop-encoded-array> | 205 | Value type: <prop-encoded-array> |
183 | Definition: List of phandle and gpio specifier pairs. Should contain | 206 | Definition: List of phandle and GPIO specifier pairs. Should contain |
184 | - "perst-gpios" PCIe endpoint reset signal line | 207 | - "perst-gpios" PCIe endpoint reset signal line |
185 | - "wake-gpios" PCIe endpoint wake signal line | 208 | - "wake-gpios" PCIe endpoint wake signal line |
186 | 209 | ||
diff --git a/Documentation/devicetree/bindings/pci/ralink,rt3883-pci.txt b/Documentation/devicetree/bindings/pci/ralink,rt3883-pci.txt index 8e0a1eb0acbb..a04ab1b76211 100644 --- a/Documentation/devicetree/bindings/pci/ralink,rt3883-pci.txt +++ b/Documentation/devicetree/bindings/pci/ralink,rt3883-pci.txt | |||
@@ -71,7 +71,7 @@ | |||
71 | - interrupt-map: standard PCI properties to define the mapping of the | 71 | - interrupt-map: standard PCI properties to define the mapping of the |
72 | PCI interface to interrupt numbers. | 72 | PCI interface to interrupt numbers. |
73 | 73 | ||
74 | The PCI host bridge node migh have additional sub-nodes representing | 74 | The PCI host bridge node might have additional sub-nodes representing |
75 | the onboard PCI devices/PCI slots. Each such sub-node must have the | 75 | the onboard PCI devices/PCI slots. Each such sub-node must have the |
76 | following mandatory properties: | 76 | following mandatory properties: |
77 | 77 | ||
diff --git a/Documentation/devicetree/bindings/pci/rcar-pci.txt b/Documentation/devicetree/bindings/pci/rcar-pci.txt index a7e3dd43b2a8..76ba3a61d1a3 100644 --- a/Documentation/devicetree/bindings/pci/rcar-pci.txt +++ b/Documentation/devicetree/bindings/pci/rcar-pci.txt | |||
@@ -14,7 +14,7 @@ compatible: "renesas,pcie-r8a7779" for the R8A7779 SoC; | |||
14 | SoC-specific version corresponding to the platform first | 14 | SoC-specific version corresponding to the platform first |
15 | followed by the generic version. | 15 | followed by the generic version. |
16 | 16 | ||
17 | - reg: base address and length of the pcie controller registers. | 17 | - reg: base address and length of the PCIe controller registers. |
18 | - #address-cells: set to <3> | 18 | - #address-cells: set to <3> |
19 | - #size-cells: set to <2> | 19 | - #size-cells: set to <2> |
20 | - bus-range: PCI bus numbers covered | 20 | - bus-range: PCI bus numbers covered |
@@ -25,15 +25,14 @@ compatible: "renesas,pcie-r8a7779" for the R8A7779 SoC; | |||
25 | source for hardware related interrupts (e.g. link speed change). | 25 | source for hardware related interrupts (e.g. link speed change). |
26 | - #interrupt-cells: set to <1> | 26 | - #interrupt-cells: set to <1> |
27 | - interrupt-map-mask and interrupt-map: standard PCI properties | 27 | - interrupt-map-mask and interrupt-map: standard PCI properties |
28 | to define the mapping of the PCIe interface to interrupt | 28 | to define the mapping of the PCIe interface to interrupt numbers. |
29 | numbers. | ||
30 | - clocks: from common clock binding: clock specifiers for the PCIe controller | 29 | - clocks: from common clock binding: clock specifiers for the PCIe controller |
31 | and PCIe bus clocks. | 30 | and PCIe bus clocks. |
32 | - clock-names: from common clock binding: should be "pcie" and "pcie_bus". | 31 | - clock-names: from common clock binding: should be "pcie" and "pcie_bus". |
33 | 32 | ||
34 | Example: | 33 | Example: |
35 | 34 | ||
36 | SoC specific DT Entry: | 35 | SoC-specific DT Entry: |
37 | 36 | ||
38 | pcie: pcie@fe000000 { | 37 | pcie: pcie@fe000000 { |
39 | compatible = "renesas,pcie-r8a7791", "renesas,pcie-rcar-gen2"; | 38 | compatible = "renesas,pcie-r8a7791", "renesas,pcie-rcar-gen2"; |
diff --git a/Documentation/devicetree/bindings/pci/rockchip-pcie.txt b/Documentation/devicetree/bindings/pci/rockchip-pcie.txt index 1453a734c2f5..af34c65773fd 100644 --- a/Documentation/devicetree/bindings/pci/rockchip-pcie.txt +++ b/Documentation/devicetree/bindings/pci/rockchip-pcie.txt | |||
@@ -19,8 +19,6 @@ Required properties: | |||
19 | - "pm" | 19 | - "pm" |
20 | - msi-map: Maps a Requester ID to an MSI controller and associated | 20 | - msi-map: Maps a Requester ID to an MSI controller and associated |
21 | msi-specifier data. See ./pci-msi.txt | 21 | msi-specifier data. See ./pci-msi.txt |
22 | - phys: From PHY bindings: Phandle for the Generic PHY for PCIe. | ||
23 | - phy-names: MUST be "pcie-phy". | ||
24 | - interrupts: Three interrupt entries must be specified. | 22 | - interrupts: Three interrupt entries must be specified. |
25 | - interrupt-names: Must include the following names | 23 | - interrupt-names: Must include the following names |
26 | - "sys" | 24 | - "sys" |
@@ -42,11 +40,24 @@ Required properties: | |||
42 | interrupt source. The value must be 1. | 40 | interrupt source. The value must be 1. |
43 | - interrupt-map-mask and interrupt-map: standard PCI properties | 41 | - interrupt-map-mask and interrupt-map: standard PCI properties |
44 | 42 | ||
43 | Required properties for legacy PHY model (deprecated): | ||
44 | - phys: From PHY bindings: Phandle for the Generic PHY for PCIe. | ||
45 | - phy-names: MUST be "pcie-phy". | ||
46 | |||
47 | Required properties for per-lane PHY model (preferred): | ||
48 | - phys: Must contain an phandle to a PHY for each entry in phy-names. | ||
49 | - phy-names: Must include 4 entries for all 4 lanes even if some of | ||
50 | them won't be used for your cases. Entries are of the form "pcie-phy-N": | ||
51 | where N ranges from 0 to 3. | ||
52 | (see example below and you MUST also refer to ../phy/rockchip-pcie-phy.txt | ||
53 | for changing the #phy-cells of phy node to support it) | ||
54 | |||
45 | Optional Property: | 55 | Optional Property: |
46 | - aspm-no-l0s: RC won't support ASPM L0s. This property is needed if | 56 | - aspm-no-l0s: RC won't support ASPM L0s. This property is needed if |
47 | using 24MHz OSC for RC's PHY. | 57 | using 24MHz OSC for RC's PHY. |
48 | - ep-gpios: contain the entry for pre-reset gpio | 58 | - ep-gpios: contain the entry for pre-reset GPIO |
49 | - num-lanes: number of lanes to use | 59 | - num-lanes: number of lanes to use |
60 | - vpcie12v-supply: The phandle to the 12v regulator to use for PCIe. | ||
50 | - vpcie3v3-supply: The phandle to the 3.3v regulator to use for PCIe. | 61 | - vpcie3v3-supply: The phandle to the 3.3v regulator to use for PCIe. |
51 | - vpcie1v8-supply: The phandle to the 1.8v regulator to use for PCIe. | 62 | - vpcie1v8-supply: The phandle to the 1.8v regulator to use for PCIe. |
52 | - vpcie0v9-supply: The phandle to the 0.9v regulator to use for PCIe. | 63 | - vpcie0v9-supply: The phandle to the 0.9v regulator to use for PCIe. |
@@ -95,6 +106,7 @@ pcie0: pcie@f8000000 { | |||
95 | <&cru SRST_PCIE_PM>, <&cru SRST_P_PCIE>, <&cru SRST_A_PCIE>; | 106 | <&cru SRST_PCIE_PM>, <&cru SRST_P_PCIE>, <&cru SRST_A_PCIE>; |
96 | reset-names = "core", "mgmt", "mgmt-sticky", "pipe", | 107 | reset-names = "core", "mgmt", "mgmt-sticky", "pipe", |
97 | "pm", "pclk", "aclk"; | 108 | "pm", "pclk", "aclk"; |
109 | /* deprecated legacy PHY model */ | ||
98 | phys = <&pcie_phy>; | 110 | phys = <&pcie_phy>; |
99 | phy-names = "pcie-phy"; | 111 | phy-names = "pcie-phy"; |
100 | pinctrl-names = "default"; | 112 | pinctrl-names = "default"; |
@@ -111,3 +123,13 @@ pcie0: pcie@f8000000 { | |||
111 | #interrupt-cells = <1>; | 123 | #interrupt-cells = <1>; |
112 | }; | 124 | }; |
113 | }; | 125 | }; |
126 | |||
127 | pcie0: pcie@f8000000 { | ||
128 | ... | ||
129 | |||
130 | /* preferred per-lane PHY model */ | ||
131 | phys = <&pcie_phy 0>, <&pcie_phy 1>, <&pcie_phy 2>, <&pcie_phy 3>; | ||
132 | phy-names = "pcie-phy-0", "pcie-phy-1", "pcie-phy-2", "pcie-phy-3"; | ||
133 | |||
134 | ... | ||
135 | }; | ||
diff --git a/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt b/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt index 7d3b09474657..34a11bfbfb60 100644 --- a/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt +++ b/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt | |||
@@ -1,29 +1,29 @@ | |||
1 | * Samsung Exynos 5440 PCIe interface | 1 | * Samsung Exynos 5440 PCIe interface |
2 | 2 | ||
3 | This PCIe host controller is based on the Synopsis Designware PCIe IP | 3 | This PCIe host controller is based on the Synopsys DesignWare PCIe IP |
4 | and thus inherits all the common properties defined in designware-pcie.txt. | 4 | and thus inherits all the common properties defined in designware-pcie.txt. |
5 | 5 | ||
6 | Required properties: | 6 | Required properties: |
7 | - compatible: "samsung,exynos5440-pcie" | 7 | - compatible: "samsung,exynos5440-pcie" |
8 | - reg: base addresses and lengths of the pcie controller, | 8 | - reg: base addresses and lengths of the PCIe controller, |
9 | the phy controller, additional register for the phy controller. | 9 | the PHY controller, additional register for the PHY controller. |
10 | (Registers for the phy controller are DEPRECATED. | 10 | (Registers for the PHY controller are DEPRECATED. |
11 | Use the PHY framework.) | 11 | Use the PHY framework.) |
12 | - reg-names : First name should be set to "elbi". | 12 | - reg-names : First name should be set to "elbi". |
13 | And use the "config" instead of getting the confgiruation address space | 13 | And use the "config" instead of getting the configuration address space |
14 | from "ranges". | 14 | from "ranges". |
15 | NOTE: When use the "config" property, reg-names must be set. | 15 | NOTE: When using the "config" property, reg-names must be set. |
16 | - interrupts: A list of interrupt outputs for level interrupt, | 16 | - interrupts: A list of interrupt outputs for level interrupt, |
17 | pulse interrupt, special interrupt. | 17 | pulse interrupt, special interrupt. |
18 | - phys: From PHY binding. Phandle for the Generic PHY. | 18 | - phys: From PHY binding. Phandle for the generic PHY. |
19 | Refer to Documentation/devicetree/bindings/phy/samsung-phy.txt | 19 | Refer to Documentation/devicetree/bindings/phy/samsung-phy.txt |
20 | 20 | ||
21 | Other common properties refer to | 21 | For other common properties, refer to |
22 | Documentation/devicetree/binding/pci/designware-pcie.txt | 22 | Documentation/devicetree/bindings/pci/designware-pcie.txt |
23 | 23 | ||
24 | Example: | 24 | Example: |
25 | 25 | ||
26 | SoC specific DT Entry: | 26 | SoC-specific DT Entry: |
27 | 27 | ||
28 | pcie@290000 { | 28 | pcie@290000 { |
29 | compatible = "samsung,exynos5440-pcie", "snps,dw-pcie"; | 29 | compatible = "samsung,exynos5440-pcie", "snps,dw-pcie"; |
@@ -83,7 +83,7 @@ With using PHY framework: | |||
83 | ... | 83 | ... |
84 | }; | 84 | }; |
85 | 85 | ||
86 | Board specific DT Entry: | 86 | Board-specific DT Entry: |
87 | 87 | ||
88 | pcie@290000 { | 88 | pcie@290000 { |
89 | reset-gpio = <&pin_ctrl 5 0>; | 89 | reset-gpio = <&pin_ctrl 5 0>; |
diff --git a/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt b/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt index 49ea76da7718..d5a14f5dad46 100644 --- a/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt +++ b/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt | |||
@@ -1,12 +1,12 @@ | |||
1 | SPEAr13XX PCIe DT detail: | 1 | SPEAr13XX PCIe DT detail: |
2 | ================================ | 2 | ================================ |
3 | 3 | ||
4 | SPEAr13XX uses synopsis designware PCIe controller and ST MiPHY as phy | 4 | SPEAr13XX uses the Synopsys DesignWare PCIe controller and ST MiPHY as PHY |
5 | controller. | 5 | controller. |
6 | 6 | ||
7 | Required properties: | 7 | Required properties: |
8 | - compatible : should be "st,spear1340-pcie", "snps,dw-pcie". | 8 | - compatible : should be "st,spear1340-pcie", "snps,dw-pcie". |
9 | - phys : phandle to phy node associated with pcie controller | 9 | - phys : phandle to PHY node associated with PCIe controller |
10 | - phy-names : must be "pcie-phy" | 10 | - phy-names : must be "pcie-phy" |
11 | - All other definitions as per generic PCI bindings | 11 | - All other definitions as per generic PCI bindings |
12 | 12 | ||
diff --git a/Documentation/devicetree/bindings/pci/ti-pci.txt b/Documentation/devicetree/bindings/pci/ti-pci.txt index 6a07c96227e0..7f7af3044016 100644 --- a/Documentation/devicetree/bindings/pci/ti-pci.txt +++ b/Documentation/devicetree/bindings/pci/ti-pci.txt | |||
@@ -1,6 +1,6 @@ | |||
1 | TI PCI Controllers | 1 | TI PCI Controllers |
2 | 2 | ||
3 | PCIe Designware Controller | 3 | PCIe DesignWare Controller |
4 | - compatible: Should be "ti,dra7-pcie" for RC | 4 | - compatible: Should be "ti,dra7-pcie" for RC |
5 | Should be "ti,dra7-pcie-ep" for EP | 5 | Should be "ti,dra7-pcie-ep" for EP |
6 | - phys : list of PHY specifiers (used by generic PHY framework) | 6 | - phys : list of PHY specifiers (used by generic PHY framework) |
@@ -13,7 +13,7 @@ PCIe Designware Controller | |||
13 | HOST MODE | 13 | HOST MODE |
14 | ========= | 14 | ========= |
15 | - reg : Two register ranges as listed in the reg-names property | 15 | - reg : Two register ranges as listed in the reg-names property |
16 | - reg-names : The first entry must be "ti-conf" for the TI specific registers | 16 | - reg-names : The first entry must be "ti-conf" for the TI-specific registers |
17 | The second entry must be "rc-dbics" for the DesignWare PCIe | 17 | The second entry must be "rc-dbics" for the DesignWare PCIe |
18 | registers | 18 | registers |
19 | The third entry must be "config" for the PCIe configuration space | 19 | The third entry must be "config" for the PCIe configuration space |
@@ -30,7 +30,7 @@ HOST MODE | |||
30 | DEVICE MODE | 30 | DEVICE MODE |
31 | =========== | 31 | =========== |
32 | - reg : Four register ranges as listed in the reg-names property | 32 | - reg : Four register ranges as listed in the reg-names property |
33 | - reg-names : "ti-conf" for the TI specific registers | 33 | - reg-names : "ti-conf" for the TI-specific registers |
34 | "ep_dbics" for the standard configuration registers as | 34 | "ep_dbics" for the standard configuration registers as |
35 | they are locally accessed within the DIF CS space | 35 | they are locally accessed within the DIF CS space |
36 | "ep_dbics2" for the standard configuration registers as | 36 | "ep_dbics2" for the standard configuration registers as |
@@ -46,7 +46,7 @@ DEVICE MODE | |||
46 | access. | 46 | access. |
47 | 47 | ||
48 | Optional Property: | 48 | Optional Property: |
49 | - gpios : Should be added if a gpio line is required to drive PERST# line | 49 | - gpios : Should be added if a GPIO line is required to drive PERST# line |
50 | 50 | ||
51 | NOTE: Two DT nodes may be added for each PCI controller; one for host | 51 | NOTE: Two DT nodes may be added for each PCI controller; one for host |
52 | mode and another for device mode. So in order for PCI to | 52 | mode and another for device mode. So in order for PCI to |
diff --git a/Documentation/devicetree/bindings/pci/versatile.txt b/Documentation/devicetree/bindings/pci/versatile.txt index ebd1e7d0403e..0a702b13d2ac 100644 --- a/Documentation/devicetree/bindings/pci/versatile.txt +++ b/Documentation/devicetree/bindings/pci/versatile.txt | |||
@@ -5,7 +5,7 @@ PCI host controller found on the ARM Versatile PB board's FPGA. | |||
5 | Required properties: | 5 | Required properties: |
6 | - compatible: should contain "arm,versatile-pci" to identify the Versatile PCI | 6 | - compatible: should contain "arm,versatile-pci" to identify the Versatile PCI |
7 | controller. | 7 | controller. |
8 | - reg: base addresses and lengths of the pci controller. There must be 3 | 8 | - reg: base addresses and lengths of the PCI controller. There must be 3 |
9 | entries: | 9 | entries: |
10 | - Versatile-specific registers | 10 | - Versatile-specific registers |
11 | - Self Config space | 11 | - Self Config space |
diff --git a/Documentation/devicetree/bindings/pci/xgene-pci-msi.txt b/Documentation/devicetree/bindings/pci/xgene-pci-msi.txt index 54bac7f8860c..85d9b95234f7 100644 --- a/Documentation/devicetree/bindings/pci/xgene-pci-msi.txt +++ b/Documentation/devicetree/bindings/pci/xgene-pci-msi.txt | |||
@@ -4,7 +4,7 @@ Required properties: | |||
4 | 4 | ||
5 | - compatible: should be "apm,xgene1-msi" to identify | 5 | - compatible: should be "apm,xgene1-msi" to identify |
6 | X-Gene v1 PCIe MSI controller block. | 6 | X-Gene v1 PCIe MSI controller block. |
7 | - msi-controller: indicates that this is X-Gene v1 PCIe MSI controller node | 7 | - msi-controller: indicates that this is an X-Gene v1 PCIe MSI controller node |
8 | - reg: physical base address (0x79000000) and length (0x900000) for controller | 8 | - reg: physical base address (0x79000000) and length (0x900000) for controller |
9 | registers. These registers include the MSI termination address and data | 9 | registers. These registers include the MSI termination address and data |
10 | registers as well as the MSI interrupt status registers. | 10 | registers as well as the MSI interrupt status registers. |
@@ -13,7 +13,8 @@ Required properties: | |||
13 | interrupt number 0x10 to 0x1f. | 13 | interrupt number 0x10 to 0x1f. |
14 | - interrupt-names: not required | 14 | - interrupt-names: not required |
15 | 15 | ||
16 | Each PCIe node needs to have property msi-parent that points to msi controller node | 16 | Each PCIe node needs to have property msi-parent that points to an MSI |
17 | controller node | ||
17 | 18 | ||
18 | Examples: | 19 | Examples: |
19 | 20 | ||
diff --git a/Documentation/devicetree/bindings/pci/xgene-pci.txt b/Documentation/devicetree/bindings/pci/xgene-pci.txt index 1070b068c7c6..6fd2decfa66c 100644 --- a/Documentation/devicetree/bindings/pci/xgene-pci.txt +++ b/Documentation/devicetree/bindings/pci/xgene-pci.txt | |||
@@ -8,7 +8,7 @@ Required properties: | |||
8 | property. | 8 | property. |
9 | - reg-names: Must include the following entries: | 9 | - reg-names: Must include the following entries: |
10 | "csr": controller configuration registers. | 10 | "csr": controller configuration registers. |
11 | "cfg": pcie configuration space registers. | 11 | "cfg": PCIe configuration space registers. |
12 | - #address-cells: set to <3> | 12 | - #address-cells: set to <3> |
13 | - #size-cells: set to <2> | 13 | - #size-cells: set to <2> |
14 | - ranges: ranges for the outbound memory, I/O regions. | 14 | - ranges: ranges for the outbound memory, I/O regions. |
@@ -21,11 +21,11 @@ Required properties: | |||
21 | 21 | ||
22 | Optional properties: | 22 | Optional properties: |
23 | - status: Either "ok" or "disabled". | 23 | - status: Either "ok" or "disabled". |
24 | - dma-coherent: Present if dma operations are coherent | 24 | - dma-coherent: Present if DMA operations are coherent |
25 | 25 | ||
26 | Example: | 26 | Example: |
27 | 27 | ||
28 | SoC specific DT Entry: | 28 | SoC-specific DT Entry: |
29 | 29 | ||
30 | pcie0: pcie@1f2b0000 { | 30 | pcie0: pcie@1f2b0000 { |
31 | status = "disabled"; | 31 | status = "disabled"; |
@@ -51,7 +51,7 @@ SoC specific DT Entry: | |||
51 | }; | 51 | }; |
52 | 52 | ||
53 | 53 | ||
54 | Board specific DT Entry: | 54 | Board-specific DT Entry: |
55 | &pcie0 { | 55 | &pcie0 { |
56 | status = "ok"; | 56 | status = "ok"; |
57 | }; | 57 | }; |
diff --git a/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt b/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt index 3259798a1192..01bf7fdf4c19 100644 --- a/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt +++ b/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt | |||
@@ -15,9 +15,9 @@ Required properties: | |||
15 | - device_type: must be "pci" | 15 | - device_type: must be "pci" |
16 | - interrupts: Should contain NWL PCIe interrupt | 16 | - interrupts: Should contain NWL PCIe interrupt |
17 | - interrupt-names: Must include the following entries: | 17 | - interrupt-names: Must include the following entries: |
18 | "msi1, msi0": interrupt asserted when MSI is received | 18 | "msi1, msi0": interrupt asserted when an MSI is received |
19 | "intx": interrupt asserted when a legacy interrupt is received | 19 | "intx": interrupt asserted when a legacy interrupt is received |
20 | "misc": interrupt asserted when miscellaneous is received | 20 | "misc": interrupt asserted when miscellaneous interrupt is received |
21 | - interrupt-map-mask and interrupt-map: standard PCI properties to define the | 21 | - interrupt-map-mask and interrupt-map: standard PCI properties to define the |
22 | mapping of the PCI interface to interrupt numbers. | 22 | mapping of the PCI interface to interrupt numbers. |
23 | - ranges: ranges for the PCI memory regions (I/O space region is not | 23 | - ranges: ranges for the PCI memory regions (I/O space region is not |
@@ -26,7 +26,8 @@ Required properties: | |||
26 | detailed explanation | 26 | detailed explanation |
27 | - msi-controller: indicates that this is MSI controller node | 27 | - msi-controller: indicates that this is MSI controller node |
28 | - msi-parent: MSI parent of the root complex itself | 28 | - msi-parent: MSI parent of the root complex itself |
29 | - legacy-interrupt-controller: Interrupt controller device node for Legacy interrupts | 29 | - legacy-interrupt-controller: Interrupt controller device node for Legacy |
30 | interrupts | ||
30 | - interrupt-controller: identifies the node as an interrupt controller | 31 | - interrupt-controller: identifies the node as an interrupt controller |
31 | - #interrupt-cells: should be set to 1 | 32 | - #interrupt-cells: should be set to 1 |
32 | - #address-cells: specifies the number of cells needed to encode an | 33 | - #address-cells: specifies the number of cells needed to encode an |
diff --git a/Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt index 0f6222a672ce..b496042f1f44 100644 --- a/Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt +++ b/Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt | |||
@@ -3,7 +3,6 @@ Rockchip PCIE PHY | |||
3 | 3 | ||
4 | Required properties: | 4 | Required properties: |
5 | - compatible: rockchip,rk3399-pcie-phy | 5 | - compatible: rockchip,rk3399-pcie-phy |
6 | - #phy-cells: must be 0 | ||
7 | - clocks: Must contain an entry in clock-names. | 6 | - clocks: Must contain an entry in clock-names. |
8 | See ../clocks/clock-bindings.txt for details. | 7 | See ../clocks/clock-bindings.txt for details. |
9 | - clock-names: Must be "refclk" | 8 | - clock-names: Must be "refclk" |
@@ -11,6 +10,12 @@ Required properties: | |||
11 | See ../reset/reset.txt for details. | 10 | See ../reset/reset.txt for details. |
12 | - reset-names: Must be "phy" | 11 | - reset-names: Must be "phy" |
13 | 12 | ||
13 | Required properties for legacy PHY mode (deprecated): | ||
14 | - #phy-cells: must be 0 | ||
15 | |||
16 | Required properties for per-lane PHY mode (preferred): | ||
17 | - #phy-cells: must be 1 | ||
18 | |||
14 | Example: | 19 | Example: |
15 | 20 | ||
16 | grf: syscon@ff770000 { | 21 | grf: syscon@ff770000 { |
diff --git a/MAINTAINERS b/MAINTAINERS index 722c7aec88c2..fe7a27ed0bdb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -10244,6 +10244,7 @@ F: drivers/pci/dwc/*imx6* | |||
10244 | 10244 | ||
10245 | PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD) | 10245 | PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD) |
10246 | M: Keith Busch <keith.busch@intel.com> | 10246 | M: Keith Busch <keith.busch@intel.com> |
10247 | M: Jonathan Derrick <jonathan.derrick@intel.com> | ||
10247 | L: linux-pci@vger.kernel.org | 10248 | L: linux-pci@vger.kernel.org |
10248 | S: Supported | 10249 | S: Supported |
10249 | F: drivers/pci/host/vmd.c | 10250 | F: drivers/pci/host/vmd.c |
@@ -10290,7 +10291,7 @@ L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) | |||
10290 | S: Maintained | 10291 | S: Maintained |
10291 | F: drivers/pci/dwc/pci-exynos.c | 10292 | F: drivers/pci/dwc/pci-exynos.c |
10292 | 10293 | ||
10293 | PCI DRIVER FOR SYNOPSIS DESIGNWARE | 10294 | PCI DRIVER FOR SYNOPSYS DESIGNWARE |
10294 | M: Jingoo Han <jingoohan1@gmail.com> | 10295 | M: Jingoo Han <jingoohan1@gmail.com> |
10295 | M: Joao Pinto <Joao.Pinto@synopsys.com> | 10296 | M: Joao Pinto <Joao.Pinto@synopsys.com> |
10296 | L: linux-pci@vger.kernel.org | 10297 | L: linux-pci@vger.kernel.org |
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 8322df174bbf..564114eb85e1 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c | |||
@@ -312,8 +312,9 @@ common_init_pci(void) | |||
312 | { | 312 | { |
313 | struct pci_controller *hose; | 313 | struct pci_controller *hose; |
314 | struct list_head resources; | 314 | struct list_head resources; |
315 | struct pci_host_bridge *bridge; | ||
315 | struct pci_bus *bus; | 316 | struct pci_bus *bus; |
316 | int next_busno; | 317 | int ret, next_busno; |
317 | int need_domain_info = 0; | 318 | int need_domain_info = 0; |
318 | u32 pci_mem_end; | 319 | u32 pci_mem_end; |
319 | u32 sg_base; | 320 | u32 sg_base; |
@@ -336,11 +337,25 @@ common_init_pci(void) | |||
336 | pci_add_resource_offset(&resources, hose->mem_space, | 337 | pci_add_resource_offset(&resources, hose->mem_space, |
337 | hose->mem_space->start); | 338 | hose->mem_space->start); |
338 | 339 | ||
339 | bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops, | 340 | bridge = pci_alloc_host_bridge(0); |
340 | hose, &resources); | 341 | if (!bridge) |
341 | if (!bus) | ||
342 | continue; | 342 | continue; |
343 | hose->bus = bus; | 343 | |
344 | list_splice_init(&resources, &bridge->windows); | ||
345 | bridge->dev.parent = NULL; | ||
346 | bridge->sysdata = hose; | ||
347 | bridge->busnr = next_busno; | ||
348 | bridge->ops = alpha_mv.pci_ops; | ||
349 | bridge->swizzle_irq = alpha_mv.pci_swizzle; | ||
350 | bridge->map_irq = alpha_mv.pci_map_irq; | ||
351 | |||
352 | ret = pci_scan_root_bus_bridge(bridge); | ||
353 | if (ret) { | ||
354 | pci_free_host_bridge(bridge); | ||
355 | continue; | ||
356 | } | ||
357 | |||
358 | bus = hose->bus = bridge->bus; | ||
344 | hose->need_domain_info = need_domain_info; | 359 | hose->need_domain_info = need_domain_info; |
345 | next_busno = bus->busn_res.end + 1; | 360 | next_busno = bus->busn_res.end + 1; |
346 | /* Don't allow 8-bit bus number overflow inside the hose - | 361 | /* Don't allow 8-bit bus number overflow inside the hose - |
@@ -354,7 +369,6 @@ common_init_pci(void) | |||
354 | pcibios_claim_console_setup(); | 369 | pcibios_claim_console_setup(); |
355 | 370 | ||
356 | pci_assign_unassigned_resources(); | 371 | pci_assign_unassigned_resources(); |
357 | pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq); | ||
358 | for (hose = hose_head; hose; hose = hose->next) { | 372 | for (hose = hose_head; hose; hose = hose->next) { |
359 | bus = hose->bus; | 373 | bus = hose->bus; |
360 | if (bus) | 374 | if (bus) |
@@ -362,7 +376,6 @@ common_init_pci(void) | |||
362 | } | 376 | } |
363 | } | 377 | } |
364 | 378 | ||
365 | |||
366 | struct pci_controller * __init | 379 | struct pci_controller * __init |
367 | alloc_pci_controller(void) | 380 | alloc_pci_controller(void) |
368 | { | 381 | { |
diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c index 2cfaa0e5c577..8ae04a121186 100644 --- a/arch/alpha/kernel/sys_nautilus.c +++ b/arch/alpha/kernel/sys_nautilus.c | |||
@@ -194,22 +194,46 @@ static struct resource irongate_mem = { | |||
194 | .name = "Irongate PCI MEM", | 194 | .name = "Irongate PCI MEM", |
195 | .flags = IORESOURCE_MEM, | 195 | .flags = IORESOURCE_MEM, |
196 | }; | 196 | }; |
197 | static struct resource busn_resource = { | ||
198 | .name = "PCI busn", | ||
199 | .start = 0, | ||
200 | .end = 255, | ||
201 | .flags = IORESOURCE_BUS, | ||
202 | }; | ||
197 | 203 | ||
198 | void __init | 204 | void __init |
199 | nautilus_init_pci(void) | 205 | nautilus_init_pci(void) |
200 | { | 206 | { |
201 | struct pci_controller *hose = hose_head; | 207 | struct pci_controller *hose = hose_head; |
208 | struct pci_host_bridge *bridge; | ||
202 | struct pci_bus *bus; | 209 | struct pci_bus *bus; |
203 | struct pci_dev *irongate; | 210 | struct pci_dev *irongate; |
204 | unsigned long bus_align, bus_size, pci_mem; | 211 | unsigned long bus_align, bus_size, pci_mem; |
205 | unsigned long memtop = max_low_pfn << PAGE_SHIFT; | 212 | unsigned long memtop = max_low_pfn << PAGE_SHIFT; |
213 | int ret; | ||
214 | |||
215 | bridge = pci_alloc_host_bridge(0); | ||
216 | if (!bridge) | ||
217 | return; | ||
218 | |||
219 | pci_add_resource(&bridge->windows, &ioport_resource); | ||
220 | pci_add_resource(&bridge->windows, &iomem_resource); | ||
221 | pci_add_resource(&bridge->windows, &busn_resource); | ||
222 | bridge->dev.parent = NULL; | ||
223 | bridge->sysdata = hose; | ||
224 | bridge->busnr = 0; | ||
225 | bridge->ops = alpha_mv.pci_ops; | ||
226 | bridge->swizzle_irq = alpha_mv.pci_swizzle; | ||
227 | bridge->map_irq = alpha_mv.pci_map_irq; | ||
206 | 228 | ||
207 | /* Scan our single hose. */ | 229 | /* Scan our single hose. */ |
208 | bus = pci_scan_bus(0, alpha_mv.pci_ops, hose); | 230 | ret = pci_scan_root_bus_bridge(bridge); |
209 | if (!bus) | 231 | if (ret) { |
232 | pci_free_host_bridge(bridge); | ||
210 | return; | 233 | return; |
234 | } | ||
211 | 235 | ||
212 | hose->bus = bus; | 236 | bus = hose->bus = bridge->bus; |
213 | pcibios_claim_one_bus(bus); | 237 | pcibios_claim_one_bus(bus); |
214 | 238 | ||
215 | irongate = pci_get_bus_and_slot(0, 0); | 239 | irongate = pci_get_bus_and_slot(0, 0); |
@@ -254,7 +278,6 @@ nautilus_init_pci(void) | |||
254 | /* pci_common_swizzle() relies on bus->self being NULL | 278 | /* pci_common_swizzle() relies on bus->self being NULL |
255 | for the root bus, so just clear it. */ | 279 | for the root bus, so just clear it. */ |
256 | bus->self = NULL; | 280 | bus->self = NULL; |
257 | pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq); | ||
258 | pci_bus_add_devices(bus); | 281 | pci_bus_add_devices(bus); |
259 | } | 282 | } |
260 | 283 | ||
diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile index 8942c5c3b4c5..2dc5f4296d44 100644 --- a/arch/arc/kernel/Makefile +++ b/arch/arc/kernel/Makefile | |||
@@ -12,7 +12,6 @@ obj-y := arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o | |||
12 | obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o | 12 | obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o |
13 | obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o | 13 | obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o |
14 | obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o | 14 | obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o |
15 | obj-$(CONFIG_PCI) += pcibios.o | ||
16 | 15 | ||
17 | obj-$(CONFIG_MODULES) += arcksyms.o module.o | 16 | obj-$(CONFIG_MODULES) += arcksyms.o module.o |
18 | obj-$(CONFIG_SMP) += smp.o | 17 | obj-$(CONFIG_SMP) += smp.o |
diff --git a/arch/arc/kernel/pcibios.c b/arch/arc/kernel/pcibios.c deleted file mode 100644 index 72e1d73d0bd6..000000000000 --- a/arch/arc/kernel/pcibios.c +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2015 Synopsys, Inc. (www.synopsys.com) | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/pci.h> | ||
10 | |||
11 | /* | ||
12 | * We don't have to worry about legacy ISA devices, so nothing to do here | ||
13 | */ | ||
14 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, | ||
15 | resource_size_t size, resource_size_t align) | ||
16 | { | ||
17 | return res->start; | ||
18 | } | ||
19 | |||
20 | void pcibios_fixup_bus(struct pci_bus *bus) | ||
21 | { | ||
22 | } | ||
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index 69c56f7316c4..5b78ce16a87e 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi | |||
@@ -238,8 +238,10 @@ | |||
238 | linux,pci-domain = <0>; | 238 | linux,pci-domain = <0>; |
239 | max-link-speed = <1>; | 239 | max-link-speed = <1>; |
240 | msi-map = <0x0 &its 0x0 0x1000>; | 240 | msi-map = <0x0 &its 0x0 0x1000>; |
241 | phys = <&pcie_phy>; | 241 | phys = <&pcie_phy 0>, <&pcie_phy 1>, |
242 | phy-names = "pcie-phy"; | 242 | <&pcie_phy 2>, <&pcie_phy 3>; |
243 | phy-names = "pcie-phy-0", "pcie-phy-1", | ||
244 | "pcie-phy-2", "pcie-phy-3"; | ||
243 | ranges = <0x83000000 0x0 0xfa000000 0x0 0xfa000000 0x0 0x1e00000 | 245 | ranges = <0x83000000 0x0 0xfa000000 0x0 0xfa000000 0x0 0x1e00000 |
244 | 0x81000000 0x0 0xfbe00000 0x0 0xfbe00000 0x0 0x100000>; | 246 | 0x81000000 0x0 0xfbe00000 0x0 0xfbe00000 0x0 0x100000>; |
245 | resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, | 247 | resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, |
@@ -1295,7 +1297,7 @@ | |||
1295 | compatible = "rockchip,rk3399-pcie-phy"; | 1297 | compatible = "rockchip,rk3399-pcie-phy"; |
1296 | clocks = <&cru SCLK_PCIEPHY_REF>; | 1298 | clocks = <&cru SCLK_PCIEPHY_REF>; |
1297 | clock-names = "refclk"; | 1299 | clock-names = "refclk"; |
1298 | #phy-cells = <0>; | 1300 | #phy-cells = <1>; |
1299 | resets = <&cru SRST_PCIEPHY>; | 1301 | resets = <&cru SRST_PCIEPHY>; |
1300 | reset-names = "phy"; | 1302 | reset-names = "phy"; |
1301 | status = "disabled"; | 1303 | status = "disabled"; |
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c index e2b7e4f9cc31..0e2ea1c78542 100644 --- a/arch/arm64/kernel/pci.c +++ b/arch/arm64/kernel/pci.c | |||
@@ -22,23 +22,6 @@ | |||
22 | #include <linux/pci-ecam.h> | 22 | #include <linux/pci-ecam.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | 24 | ||
25 | /* | ||
26 | * Called after each bus is probed, but before its children are examined | ||
27 | */ | ||
28 | void pcibios_fixup_bus(struct pci_bus *bus) | ||
29 | { | ||
30 | /* nothing to do, expected to be removed in the future */ | ||
31 | } | ||
32 | |||
33 | /* | ||
34 | * We don't have to worry about legacy ISA devices, so nothing to do here | ||
35 | */ | ||
36 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, | ||
37 | resource_size_t size, resource_size_t align) | ||
38 | { | ||
39 | return res->start; | ||
40 | } | ||
41 | |||
42 | #ifdef CONFIG_ACPI | 25 | #ifdef CONFIG_ACPI |
43 | /* | 26 | /* |
44 | * Try to assign the IRQ number when probing a new device | 27 | * Try to assign the IRQ number when probing a new device |
diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c index 394c2a73d5e2..5cc622c0225e 100644 --- a/arch/cris/arch-v32/drivers/pci/bios.c +++ b/arch/cris/arch-v32/drivers/pci/bios.c | |||
@@ -2,10 +2,6 @@ | |||
2 | #include <linux/kernel.h> | 2 | #include <linux/kernel.h> |
3 | #include <hwregs/intr_vect.h> | 3 | #include <hwregs/intr_vect.h> |
4 | 4 | ||
5 | void pcibios_fixup_bus(struct pci_bus *b) | ||
6 | { | ||
7 | } | ||
8 | |||
9 | void pcibios_set_master(struct pci_dev *dev) | 5 | void pcibios_set_master(struct pci_dev *dev) |
10 | { | 6 | { |
11 | u8 lat; | 7 | u8 lat; |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 4068bde623dc..f5ec736100ee 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -411,13 +411,6 @@ pcibios_disable_device (struct pci_dev *dev) | |||
411 | acpi_pci_irq_disable(dev); | 411 | acpi_pci_irq_disable(dev); |
412 | } | 412 | } |
413 | 413 | ||
414 | resource_size_t | ||
415 | pcibios_align_resource (void *data, const struct resource *res, | ||
416 | resource_size_t size, resource_size_t align) | ||
417 | { | ||
418 | return res->start; | ||
419 | } | ||
420 | |||
421 | /** | 414 | /** |
422 | * ia64_pci_get_legacy_mem - generic legacy mem routine | 415 | * ia64_pci_get_legacy_mem - generic legacy mem routine |
423 | * @bus: bus to get legacy memory base address for | 416 | * @bus: bus to get legacy memory base address for |
diff --git a/arch/m68k/coldfire/pci.c b/arch/m68k/coldfire/pci.c index 6a640be48568..3097fa2ca746 100644 --- a/arch/m68k/coldfire/pci.c +++ b/arch/m68k/coldfire/pci.c | |||
@@ -243,6 +243,13 @@ static struct resource mcf_pci_io = { | |||
243 | .flags = IORESOURCE_IO, | 243 | .flags = IORESOURCE_IO, |
244 | }; | 244 | }; |
245 | 245 | ||
246 | static struct resource busn_resource = { | ||
247 | .name = "PCI busn", | ||
248 | .start = 0, | ||
249 | .end = 255, | ||
250 | .flags = IORESOURCE_BUS, | ||
251 | }; | ||
252 | |||
246 | /* | 253 | /* |
247 | * Interrupt mapping and setting. | 254 | * Interrupt mapping and setting. |
248 | */ | 255 | */ |
@@ -258,6 +265,13 @@ static int mcf_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |||
258 | 265 | ||
259 | static int __init mcf_pci_init(void) | 266 | static int __init mcf_pci_init(void) |
260 | { | 267 | { |
268 | struct pci_host_bridge *bridge; | ||
269 | int ret; | ||
270 | |||
271 | bridge = pci_alloc_host_bridge(0); | ||
272 | if (!bridge) | ||
273 | return -ENOMEM; | ||
274 | |||
261 | pr_info("ColdFire: PCI bus initialization...\n"); | 275 | pr_info("ColdFire: PCI bus initialization...\n"); |
262 | 276 | ||
263 | /* Reset the external PCI bus */ | 277 | /* Reset the external PCI bus */ |
@@ -312,14 +326,28 @@ static int __init mcf_pci_init(void) | |||
312 | set_current_state(TASK_UNINTERRUPTIBLE); | 326 | set_current_state(TASK_UNINTERRUPTIBLE); |
313 | schedule_timeout(msecs_to_jiffies(200)); | 327 | schedule_timeout(msecs_to_jiffies(200)); |
314 | 328 | ||
315 | rootbus = pci_scan_bus(0, &mcf_pci_ops, NULL); | 329 | |
316 | if (!rootbus) | 330 | pci_add_resource(&bridge->windows, &ioport_resource); |
317 | return -ENODEV; | 331 | pci_add_resource(&bridge->windows, &iomem_resource); |
332 | pci_add_resource(&bridge->windows, &busn_resource); | ||
333 | bridge->dev.parent = NULL; | ||
334 | bridge->sysdata = NULL; | ||
335 | bridge->busnr = 0; | ||
336 | bridge->ops = &mcf_pci_ops; | ||
337 | bridge->swizzle_irq = pci_common_swizzle; | ||
338 | bridge->map_irq = mcf_pci_map_irq; | ||
339 | |||
340 | ret = pci_scan_root_bus_bridge(bridge); | ||
341 | if (ret) { | ||
342 | pci_free_host_bridge(bridge); | ||
343 | return ret; | ||
344 | } | ||
345 | |||
346 | rootbus = bridge->bus; | ||
318 | 347 | ||
319 | rootbus->resource[0] = &mcf_pci_io; | 348 | rootbus->resource[0] = &mcf_pci_io; |
320 | rootbus->resource[1] = &mcf_pci_mem; | 349 | rootbus->resource[1] = &mcf_pci_mem; |
321 | 350 | ||
322 | pci_fixup_irqs(pci_common_swizzle, mcf_pci_map_irq); | ||
323 | pci_bus_size_bridges(rootbus); | 351 | pci_bus_size_bridges(rootbus); |
324 | pci_bus_assign_resources(rootbus); | 352 | pci_bus_assign_resources(rootbus); |
325 | pci_bus_add_devices(rootbus); | 353 | pci_bus_add_devices(rootbus); |
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index efd4983cb697..114b93488193 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h | |||
@@ -81,9 +81,6 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file, | |||
81 | 81 | ||
82 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER | 82 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER |
83 | 83 | ||
84 | extern void pcibios_setup_bus_devices(struct pci_bus *bus); | ||
85 | extern void pcibios_setup_bus_self(struct pci_bus *bus); | ||
86 | |||
87 | /* This part of code was originally in xilinx-pci.h */ | 84 | /* This part of code was originally in xilinx-pci.h */ |
88 | #ifdef CONFIG_PCI_XILINX | 85 | #ifdef CONFIG_PCI_XILINX |
89 | extern void __init xilinx_pci_init(void); | 86 | extern void __init xilinx_pci_init(void); |
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 180f4755ca66..ae79e8638d50 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c | |||
@@ -678,144 +678,6 @@ static void pcibios_fixup_resources(struct pci_dev *dev) | |||
678 | } | 678 | } |
679 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources); | 679 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources); |
680 | 680 | ||
681 | /* This function tries to figure out if a bridge resource has been initialized | ||
682 | * by the firmware or not. It doesn't have to be absolutely bullet proof, but | ||
683 | * things go more smoothly when it gets it right. It should covers cases such | ||
684 | * as Apple "closed" bridge resources and bare-metal pSeries unassigned bridges | ||
685 | */ | ||
686 | static int pcibios_uninitialized_bridge_resource(struct pci_bus *bus, | ||
687 | struct resource *res) | ||
688 | { | ||
689 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
690 | struct pci_dev *dev = bus->self; | ||
691 | resource_size_t offset; | ||
692 | u16 command; | ||
693 | int i; | ||
694 | |||
695 | /* Job is a bit different between memory and IO */ | ||
696 | if (res->flags & IORESOURCE_MEM) { | ||
697 | /* If the BAR is non-0 (res != pci_mem_offset) then it's | ||
698 | * probably been initialized by somebody | ||
699 | */ | ||
700 | if (res->start != hose->pci_mem_offset) | ||
701 | return 0; | ||
702 | |||
703 | /* The BAR is 0, let's check if memory decoding is enabled on | ||
704 | * the bridge. If not, we consider it unassigned | ||
705 | */ | ||
706 | pci_read_config_word(dev, PCI_COMMAND, &command); | ||
707 | if ((command & PCI_COMMAND_MEMORY) == 0) | ||
708 | return 1; | ||
709 | |||
710 | /* Memory decoding is enabled and the BAR is 0. If any of | ||
711 | * the bridge resources covers that starting address (0 then | ||
712 | * it's good enough for us for memory | ||
713 | */ | ||
714 | for (i = 0; i < 3; i++) { | ||
715 | if ((hose->mem_resources[i].flags & IORESOURCE_MEM) && | ||
716 | hose->mem_resources[i].start == hose->pci_mem_offset) | ||
717 | return 0; | ||
718 | } | ||
719 | |||
720 | /* Well, it starts at 0 and we know it will collide so we may as | ||
721 | * well consider it as unassigned. That covers the Apple case. | ||
722 | */ | ||
723 | return 1; | ||
724 | } else { | ||
725 | /* If the BAR is non-0, then we consider it assigned */ | ||
726 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | ||
727 | if (((res->start - offset) & 0xfffffffful) != 0) | ||
728 | return 0; | ||
729 | |||
730 | /* Here, we are a bit different than memory as typically IO | ||
731 | * space starting at low addresses -is- valid. What we do | ||
732 | * instead if that we consider as unassigned anything that | ||
733 | * doesn't have IO enabled in the PCI command register, | ||
734 | * and that's it. | ||
735 | */ | ||
736 | pci_read_config_word(dev, PCI_COMMAND, &command); | ||
737 | if (command & PCI_COMMAND_IO) | ||
738 | return 0; | ||
739 | |||
740 | /* It's starting at 0 and IO is disabled in the bridge, consider | ||
741 | * it unassigned | ||
742 | */ | ||
743 | return 1; | ||
744 | } | ||
745 | } | ||
746 | |||
747 | /* Fixup resources of a PCI<->PCI bridge */ | ||
748 | static void pcibios_fixup_bridge(struct pci_bus *bus) | ||
749 | { | ||
750 | struct resource *res; | ||
751 | int i; | ||
752 | |||
753 | struct pci_dev *dev = bus->self; | ||
754 | |||
755 | pci_bus_for_each_resource(bus, res, i) { | ||
756 | if (!res) | ||
757 | continue; | ||
758 | if (!res->flags) | ||
759 | continue; | ||
760 | if (i >= 3 && bus->self->transparent) | ||
761 | continue; | ||
762 | |||
763 | pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n", | ||
764 | pci_name(dev), i, | ||
765 | (unsigned long long)res->start, | ||
766 | (unsigned long long)res->end, | ||
767 | (unsigned int)res->flags); | ||
768 | |||
769 | /* Try to detect uninitialized P2P bridge resources, | ||
770 | * and clear them out so they get re-assigned later | ||
771 | */ | ||
772 | if (pcibios_uninitialized_bridge_resource(bus, res)) { | ||
773 | res->flags = 0; | ||
774 | pr_debug("PCI:%s (unassigned)\n", | ||
775 | pci_name(dev)); | ||
776 | } else { | ||
777 | pr_debug("PCI:%s %016llx-%016llx\n", | ||
778 | pci_name(dev), | ||
779 | (unsigned long long)res->start, | ||
780 | (unsigned long long)res->end); | ||
781 | } | ||
782 | } | ||
783 | } | ||
784 | |||
785 | void pcibios_setup_bus_self(struct pci_bus *bus) | ||
786 | { | ||
787 | /* Fix up the bus resources for P2P bridges */ | ||
788 | if (bus->self != NULL) | ||
789 | pcibios_fixup_bridge(bus); | ||
790 | } | ||
791 | |||
792 | void pcibios_setup_bus_devices(struct pci_bus *bus) | ||
793 | { | ||
794 | struct pci_dev *dev; | ||
795 | |||
796 | pr_debug("PCI: Fixup bus devices %d (%s)\n", | ||
797 | bus->number, bus->self ? pci_name(bus->self) : "PHB"); | ||
798 | |||
799 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
800 | /* Setup OF node pointer in archdata */ | ||
801 | dev->dev.of_node = pci_device_to_OF_node(dev); | ||
802 | |||
803 | /* Fixup NUMA node as it may not be setup yet by the generic | ||
804 | * code and is needed by the DMA init | ||
805 | */ | ||
806 | set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); | ||
807 | |||
808 | /* Read default IRQs and fixup if necessary */ | ||
809 | dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); | ||
810 | } | ||
811 | } | ||
812 | |||
813 | void pcibios_fixup_bus(struct pci_bus *bus) | ||
814 | { | ||
815 | /* nothing to do */ | ||
816 | } | ||
817 | EXPORT_SYMBOL(pcibios_fixup_bus); | ||
818 | |||
819 | /* | 681 | /* |
820 | * We need to avoid collisions with `mirrored' VGA ports | 682 | * We need to avoid collisions with `mirrored' VGA ports |
821 | * and other strange ISA hardware, so we always want the | 683 | * and other strange ISA hardware, so we always want the |
@@ -829,13 +691,6 @@ EXPORT_SYMBOL(pcibios_fixup_bus); | |||
829 | * but we want to try to avoid allocating at 0x2900-0x2bff | 691 | * but we want to try to avoid allocating at 0x2900-0x2bff |
830 | * which might have be mirrored at 0x0100-0x03ff.. | 692 | * which might have be mirrored at 0x0100-0x03ff.. |
831 | */ | 693 | */ |
832 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, | ||
833 | resource_size_t size, resource_size_t align) | ||
834 | { | ||
835 | return res->start; | ||
836 | } | ||
837 | EXPORT_SYMBOL(pcibios_align_resource); | ||
838 | |||
839 | int pcibios_add_device(struct pci_dev *dev) | 694 | int pcibios_add_device(struct pci_dev *dev) |
840 | { | 695 | { |
841 | dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); | 696 | dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); |
diff --git a/arch/mips/pci/pci-legacy.c b/arch/mips/pci/pci-legacy.c index 174575a9a112..fc7726088103 100644 --- a/arch/mips/pci/pci-legacy.c +++ b/arch/mips/pci/pci-legacy.c | |||
@@ -78,6 +78,12 @@ static void pcibios_scanbus(struct pci_controller *hose) | |||
78 | static int need_domain_info; | 78 | static int need_domain_info; |
79 | LIST_HEAD(resources); | 79 | LIST_HEAD(resources); |
80 | struct pci_bus *bus; | 80 | struct pci_bus *bus; |
81 | struct pci_host_bridge *bridge; | ||
82 | int ret; | ||
83 | |||
84 | bridge = pci_alloc_host_bridge(0); | ||
85 | if (!bridge) | ||
86 | return; | ||
81 | 87 | ||
82 | if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY)) | 88 | if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY)) |
83 | next_busno = (*hose->get_busno)(); | 89 | next_busno = (*hose->get_busno)(); |
@@ -87,18 +93,24 @@ static void pcibios_scanbus(struct pci_controller *hose) | |||
87 | pci_add_resource_offset(&resources, | 93 | pci_add_resource_offset(&resources, |
88 | hose->io_resource, hose->io_offset); | 94 | hose->io_resource, hose->io_offset); |
89 | pci_add_resource(&resources, hose->busn_resource); | 95 | pci_add_resource(&resources, hose->busn_resource); |
90 | bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, | 96 | list_splice_init(&resources, &bridge->windows); |
91 | &resources); | 97 | bridge->dev.parent = NULL; |
92 | hose->bus = bus; | 98 | bridge->sysdata = hose; |
99 | bridge->busnr = next_busno; | ||
100 | bridge->ops = hose->pci_ops; | ||
101 | bridge->swizzle_irq = pci_common_swizzle; | ||
102 | bridge->map_irq = pcibios_map_irq; | ||
103 | ret = pci_scan_root_bus_bridge(bridge); | ||
104 | if (ret) { | ||
105 | pci_free_host_bridge(bridge); | ||
106 | return; | ||
107 | } | ||
108 | |||
109 | hose->bus = bus = bridge->bus; | ||
93 | 110 | ||
94 | need_domain_info = need_domain_info || pci_domain_nr(bus); | 111 | need_domain_info = need_domain_info || pci_domain_nr(bus); |
95 | set_pci_need_domain_info(hose, need_domain_info); | 112 | set_pci_need_domain_info(hose, need_domain_info); |
96 | 113 | ||
97 | if (!bus) { | ||
98 | pci_free_resource_list(&resources); | ||
99 | return; | ||
100 | } | ||
101 | |||
102 | next_busno = bus->busn_res.end + 1; | 114 | next_busno = bus->busn_res.end + 1; |
103 | /* Don't allow 8-bit bus number overflow inside the hose - | 115 | /* Don't allow 8-bit bus number overflow inside the hose - |
104 | reserve some space for bridges. */ | 116 | reserve some space for bridges. */ |
@@ -224,8 +236,6 @@ static int __init pcibios_init(void) | |||
224 | list_for_each_entry(hose, &controllers, list) | 236 | list_for_each_entry(hose, &controllers, list) |
225 | pcibios_scanbus(hose); | 237 | pcibios_scanbus(hose); |
226 | 238 | ||
227 | pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq); | ||
228 | |||
229 | pci_initialized = 1; | 239 | pci_initialized = 1; |
230 | 240 | ||
231 | return 0; | 241 | return 0; |
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 7b30af5da222..ddb9923fb45d 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
@@ -262,10 +262,6 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) | |||
262 | return rc; | 262 | return rc; |
263 | } | 263 | } |
264 | 264 | ||
265 | void pcibios_fixup_bus(struct pci_bus *bus) | ||
266 | { | ||
267 | } | ||
268 | |||
269 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, | 265 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, |
270 | resource_size_t size, | 266 | resource_size_t size, |
271 | resource_size_t align) | 267 | resource_size_t align) |
diff --git a/arch/sh/drivers/pci/fixups-cayman.c b/arch/sh/drivers/pci/fixups-cayman.c index edc2fb7a5bb2..32467884d6f7 100644 --- a/arch/sh/drivers/pci/fixups-cayman.c +++ b/arch/sh/drivers/pci/fixups-cayman.c | |||
@@ -5,7 +5,7 @@ | |||
5 | #include <cpu/irq.h> | 5 | #include <cpu/irq.h> |
6 | #include "pci-sh5.h" | 6 | #include "pci-sh5.h" |
7 | 7 | ||
8 | int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) | 8 | int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) |
9 | { | 9 | { |
10 | int result = -1; | 10 | int result = -1; |
11 | 11 | ||
diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c index 1d1c5a227e50..9d597f7ab8dd 100644 --- a/arch/sh/drivers/pci/fixups-dreamcast.c +++ b/arch/sh/drivers/pci/fixups-dreamcast.c | |||
@@ -76,7 +76,7 @@ static void gapspci_fixup_resources(struct pci_dev *dev) | |||
76 | } | 76 | } |
77 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources); | 77 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources); |
78 | 78 | ||
79 | int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) | 79 | int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) |
80 | { | 80 | { |
81 | /* | 81 | /* |
82 | * The interrupt routing semantics here are quite trivial. | 82 | * The interrupt routing semantics here are quite trivial. |
diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c index 57ed3f09d0c2..2c9b58f848dd 100644 --- a/arch/sh/drivers/pci/fixups-r7780rp.c +++ b/arch/sh/drivers/pci/fixups-r7780rp.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/sh_intc.h> | 15 | #include <linux/sh_intc.h> |
16 | #include "pci-sh4.h" | 16 | #include "pci-sh4.h" |
17 | 17 | ||
18 | int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) | 18 | int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) |
19 | { | 19 | { |
20 | return evt2irq(0xa20) + slot; | 20 | return evt2irq(0xa20) + slot; |
21 | } | 21 | } |
diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c index eaddb56c45c6..358ac104f08c 100644 --- a/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c | |||
@@ -20,18 +20,18 @@ | |||
20 | #define PCIMCR_MRSET_OFF 0xBFFFFFFF | 20 | #define PCIMCR_MRSET_OFF 0xBFFFFFFF |
21 | #define PCIMCR_RFSH_OFF 0xFFFFFFFB | 21 | #define PCIMCR_RFSH_OFF 0xFFFFFFFB |
22 | 22 | ||
23 | static u8 rts7751r2d_irq_tab[] __initdata = { | 23 | static u8 rts7751r2d_irq_tab[] = { |
24 | IRQ_PCI_INTA, | 24 | IRQ_PCI_INTA, |
25 | IRQ_PCI_INTB, | 25 | IRQ_PCI_INTB, |
26 | IRQ_PCI_INTC, | 26 | IRQ_PCI_INTC, |
27 | IRQ_PCI_INTD, | 27 | IRQ_PCI_INTD, |
28 | }; | 28 | }; |
29 | 29 | ||
30 | static char lboxre2_irq_tab[] __initdata = { | 30 | static char lboxre2_irq_tab[] = { |
31 | IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD, | 31 | IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD, |
32 | }; | 32 | }; |
33 | 33 | ||
34 | int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) | 34 | int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) |
35 | { | 35 | { |
36 | if (mach_is_lboxre2()) | 36 | if (mach_is_lboxre2()) |
37 | return lboxre2_irq_tab[slot]; | 37 | return lboxre2_irq_tab[slot]; |
diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c index c0a015ae6ecf..24e96dfbdb22 100644 --- a/arch/sh/drivers/pci/fixups-sdk7780.c +++ b/arch/sh/drivers/pci/fixups-sdk7780.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #define IRQ_INTD evt2irq(0xa80) | 22 | #define IRQ_INTD evt2irq(0xa80) |
23 | 23 | ||
24 | /* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */ | 24 | /* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */ |
25 | static char sdk7780_irq_tab[4][16] __initdata = { | 25 | static char sdk7780_irq_tab[4][16] = { |
26 | /* INTA */ | 26 | /* INTA */ |
27 | { IRQ_INTA, IRQ_INTD, IRQ_INTC, IRQ_INTD, -1, -1, -1, -1, -1, -1, | 27 | { IRQ_INTA, IRQ_INTD, IRQ_INTC, IRQ_INTD, -1, -1, -1, -1, -1, -1, |
28 | -1, -1, -1, -1, -1, -1 }, | 28 | -1, -1, -1, -1, -1, -1 }, |
@@ -37,7 +37,7 @@ static char sdk7780_irq_tab[4][16] __initdata = { | |||
37 | -1, -1, -1 }, | 37 | -1, -1, -1 }, |
38 | }; | 38 | }; |
39 | 39 | ||
40 | int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) | 40 | int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) |
41 | { | 41 | { |
42 | return sdk7780_irq_tab[pin-1][slot]; | 42 | return sdk7780_irq_tab[pin-1][slot]; |
43 | } | 43 | } |
diff --git a/arch/sh/drivers/pci/fixups-se7751.c b/arch/sh/drivers/pci/fixups-se7751.c index 84a88ca92008..1cb8d0ac4fdb 100644 --- a/arch/sh/drivers/pci/fixups-se7751.c +++ b/arch/sh/drivers/pci/fixups-se7751.c | |||
@@ -7,7 +7,7 @@ | |||
7 | #include <linux/sh_intc.h> | 7 | #include <linux/sh_intc.h> |
8 | #include "pci-sh4.h" | 8 | #include "pci-sh4.h" |
9 | 9 | ||
10 | int __init pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin) | 10 | int pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin) |
11 | { | 11 | { |
12 | switch (slot) { | 12 | switch (slot) { |
13 | case 0: return evt2irq(0x3a0); | 13 | case 0: return evt2irq(0x3a0); |
diff --git a/arch/sh/drivers/pci/fixups-sh03.c b/arch/sh/drivers/pci/fixups-sh03.c index 16207bef9f52..55ac1ba2c74f 100644 --- a/arch/sh/drivers/pci/fixups-sh03.c +++ b/arch/sh/drivers/pci/fixups-sh03.c | |||
@@ -4,7 +4,7 @@ | |||
4 | #include <linux/pci.h> | 4 | #include <linux/pci.h> |
5 | #include <linux/sh_intc.h> | 5 | #include <linux/sh_intc.h> |
6 | 6 | ||
7 | int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) | 7 | int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) |
8 | { | 8 | { |
9 | int irq; | 9 | int irq; |
10 | 10 | ||
diff --git a/arch/sh/drivers/pci/fixups-snapgear.c b/arch/sh/drivers/pci/fixups-snapgear.c index 6e33ba4cd076..a931e5928f58 100644 --- a/arch/sh/drivers/pci/fixups-snapgear.c +++ b/arch/sh/drivers/pci/fixups-snapgear.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/sh_intc.h> | 19 | #include <linux/sh_intc.h> |
20 | #include "pci-sh4.h" | 20 | #include "pci-sh4.h" |
21 | 21 | ||
22 | int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) | 22 | int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) |
23 | { | 23 | { |
24 | int irq = -1; | 24 | int irq = -1; |
25 | 25 | ||
diff --git a/arch/sh/drivers/pci/fixups-titan.c b/arch/sh/drivers/pci/fixups-titan.c index bd1addb1b8be..a9d563e479d5 100644 --- a/arch/sh/drivers/pci/fixups-titan.c +++ b/arch/sh/drivers/pci/fixups-titan.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <mach/titan.h> | 19 | #include <mach/titan.h> |
20 | #include "pci-sh4.h" | 20 | #include "pci-sh4.h" |
21 | 21 | ||
22 | static char titan_irq_tab[] __initdata = { | 22 | static char titan_irq_tab[] = { |
23 | TITAN_IRQ_WAN, | 23 | TITAN_IRQ_WAN, |
24 | TITAN_IRQ_LAN, | 24 | TITAN_IRQ_LAN, |
25 | TITAN_IRQ_MPCIA, | 25 | TITAN_IRQ_MPCIA, |
@@ -27,7 +27,7 @@ static char titan_irq_tab[] __initdata = { | |||
27 | TITAN_IRQ_USB, | 27 | TITAN_IRQ_USB, |
28 | }; | 28 | }; |
29 | 29 | ||
30 | int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) | 30 | int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) |
31 | { | 31 | { |
32 | int irq = titan_irq_tab[slot]; | 32 | int irq = titan_irq_tab[slot]; |
33 | 33 | ||
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index c99ee286b69f..5976a2c8a3e3 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c | |||
@@ -39,8 +39,12 @@ static void pcibios_scanbus(struct pci_channel *hose) | |||
39 | LIST_HEAD(resources); | 39 | LIST_HEAD(resources); |
40 | struct resource *res; | 40 | struct resource *res; |
41 | resource_size_t offset; | 41 | resource_size_t offset; |
42 | int i; | 42 | int i, ret; |
43 | struct pci_bus *bus; | 43 | struct pci_host_bridge *bridge; |
44 | |||
45 | bridge = pci_alloc_host_bridge(0); | ||
46 | if (!bridge) | ||
47 | return; | ||
44 | 48 | ||
45 | for (i = 0; i < hose->nr_resources; i++) { | 49 | for (i = 0; i < hose->nr_resources; i++) { |
46 | res = hose->resources + i; | 50 | res = hose->resources + i; |
@@ -52,19 +56,26 @@ static void pcibios_scanbus(struct pci_channel *hose) | |||
52 | pci_add_resource_offset(&resources, res, offset); | 56 | pci_add_resource_offset(&resources, res, offset); |
53 | } | 57 | } |
54 | 58 | ||
55 | bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, | 59 | list_splice_init(&resources, &bridge->windows); |
56 | &resources); | 60 | bridge->dev.parent = NULL; |
57 | hose->bus = bus; | 61 | bridge->sysdata = hose; |
62 | bridge->busnr = next_busno; | ||
63 | bridge->ops = hose->pci_ops; | ||
64 | bridge->swizzle_irq = pci_common_swizzle; | ||
65 | bridge->map_irq = pcibios_map_platform_irq; | ||
66 | |||
67 | ret = pci_scan_root_bus_bridge(bridge); | ||
68 | if (ret) { | ||
69 | pci_free_host_bridge(bridge); | ||
70 | return; | ||
71 | } | ||
72 | |||
73 | hose->bus = bridge->bus; | ||
58 | 74 | ||
59 | need_domain_info = need_domain_info || hose->index; | 75 | need_domain_info = need_domain_info || hose->index; |
60 | hose->need_domain_info = need_domain_info; | 76 | hose->need_domain_info = need_domain_info; |
61 | 77 | ||
62 | if (!bus) { | 78 | next_busno = hose->bus->busn_res.end + 1; |
63 | pci_free_resource_list(&resources); | ||
64 | return; | ||
65 | } | ||
66 | |||
67 | next_busno = bus->busn_res.end + 1; | ||
68 | /* Don't allow 8-bit bus number overflow inside the hose - | 79 | /* Don't allow 8-bit bus number overflow inside the hose - |
69 | reserve some space for bridges. */ | 80 | reserve some space for bridges. */ |
70 | if (next_busno > 224) { | 81 | if (next_busno > 224) { |
@@ -72,9 +83,9 @@ static void pcibios_scanbus(struct pci_channel *hose) | |||
72 | need_domain_info = 1; | 83 | need_domain_info = 1; |
73 | } | 84 | } |
74 | 85 | ||
75 | pci_bus_size_bridges(bus); | 86 | pci_bus_size_bridges(hose->bus); |
76 | pci_bus_assign_resources(bus); | 87 | pci_bus_assign_resources(hose->bus); |
77 | pci_bus_add_devices(bus); | 88 | pci_bus_add_devices(hose->bus); |
78 | } | 89 | } |
79 | 90 | ||
80 | /* | 91 | /* |
@@ -144,8 +155,6 @@ static int __init pcibios_init(void) | |||
144 | for (hose = hose_head; hose; hose = hose->next) | 155 | for (hose = hose_head; hose; hose = hose->next) |
145 | pcibios_scanbus(hose); | 156 | pcibios_scanbus(hose); |
146 | 157 | ||
147 | pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq); | ||
148 | |||
149 | dma_debug_add_bus(&pci_bus_type); | 158 | dma_debug_add_bus(&pci_bus_type); |
150 | 159 | ||
151 | pci_initialized = 1; | 160 | pci_initialized = 1; |
@@ -155,14 +164,6 @@ static int __init pcibios_init(void) | |||
155 | subsys_initcall(pcibios_init); | 164 | subsys_initcall(pcibios_init); |
156 | 165 | ||
157 | /* | 166 | /* |
158 | * Called after each bus is probed, but before its children | ||
159 | * are examined. | ||
160 | */ | ||
161 | void pcibios_fixup_bus(struct pci_bus *bus) | ||
162 | { | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * We need to avoid collisions with `mirrored' VGA ports | 167 | * We need to avoid collisions with `mirrored' VGA ports |
167 | * and other strange ISA hardware, so we always want the | 168 | * and other strange ISA hardware, so we always want the |
168 | * addresses to be allocated in the 0x000-0x0ff region | 169 | * addresses to be allocated in the 0x000-0x0ff region |
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index a162a7f86b2e..0167a7352719 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c | |||
@@ -467,7 +467,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port) | |||
467 | return 0; | 467 | return 0; |
468 | } | 468 | } |
469 | 469 | ||
470 | int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) | 470 | int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) |
471 | { | 471 | { |
472 | return evt2irq(0xae0); | 472 | return evt2irq(0xae0); |
473 | } | 473 | } |
diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c index 4371f72ff025..98c223edac84 100644 --- a/arch/sparc/kernel/leon_pci.c +++ b/arch/sparc/kernel/leon_pci.c | |||
@@ -25,6 +25,12 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) | |||
25 | { | 25 | { |
26 | LIST_HEAD(resources); | 26 | LIST_HEAD(resources); |
27 | struct pci_bus *root_bus; | 27 | struct pci_bus *root_bus; |
28 | struct pci_host_bridge *bridge; | ||
29 | int ret; | ||
30 | |||
31 | bridge = pci_alloc_host_bridge(0); | ||
32 | if (!bridge) | ||
33 | return; | ||
28 | 34 | ||
29 | pci_add_resource_offset(&resources, &info->io_space, | 35 | pci_add_resource_offset(&resources, &info->io_space, |
30 | info->io_space.start - 0x1000); | 36 | info->io_space.start - 0x1000); |
@@ -32,15 +38,21 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) | |||
32 | info->busn.flags = IORESOURCE_BUS; | 38 | info->busn.flags = IORESOURCE_BUS; |
33 | pci_add_resource(&resources, &info->busn); | 39 | pci_add_resource(&resources, &info->busn); |
34 | 40 | ||
35 | root_bus = pci_scan_root_bus(&ofdev->dev, 0, info->ops, info, | 41 | list_splice_init(&resources, &bridge->windows); |
36 | &resources); | 42 | bridge->dev.parent = &ofdev->dev; |
37 | if (!root_bus) { | 43 | bridge->sysdata = info; |
38 | pci_free_resource_list(&resources); | 44 | bridge->busnr = 0; |
45 | bridge->ops = info->ops; | ||
46 | bridge->swizzle_irq = pci_common_swizzle; | ||
47 | bridge->map_irq = info->map_irq; | ||
48 | |||
49 | ret = pci_scan_root_bus_bridge(bridge); | ||
50 | if (ret) { | ||
51 | pci_free_host_bridge(bridge); | ||
39 | return; | 52 | return; |
40 | } | 53 | } |
41 | 54 | ||
42 | /* Setup IRQs of all devices using custom routines */ | 55 | root_bus = bridge->bus; |
43 | pci_fixup_irqs(pci_common_swizzle, info->map_irq); | ||
44 | 56 | ||
45 | /* Assign devices with resources */ | 57 | /* Assign devices with resources */ |
46 | pci_assign_unassigned_resources(); | 58 | pci_assign_unassigned_resources(); |
@@ -94,9 +106,3 @@ void pcibios_fixup_bus(struct pci_bus *pbus) | |||
94 | } | 106 | } |
95 | } | 107 | } |
96 | } | 108 | } |
97 | |||
98 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, | ||
99 | resource_size_t size, resource_size_t align) | ||
100 | { | ||
101 | return res->start; | ||
102 | } | ||
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 7eceaa10836f..3f8670c92951 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c | |||
@@ -690,16 +690,6 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm, | |||
690 | return bus; | 690 | return bus; |
691 | } | 691 | } |
692 | 692 | ||
693 | void pcibios_fixup_bus(struct pci_bus *pbus) | ||
694 | { | ||
695 | } | ||
696 | |||
697 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, | ||
698 | resource_size_t size, resource_size_t align) | ||
699 | { | ||
700 | return res->start; | ||
701 | } | ||
702 | |||
703 | int pcibios_enable_device(struct pci_dev *dev, int mask) | 693 | int pcibios_enable_device(struct pci_dev *dev, int mask) |
704 | { | 694 | { |
705 | u16 cmd, oldcmd; | 695 | u16 cmd, oldcmd; |
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index 732af9a9f6dd..4a133c052af8 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c | |||
@@ -746,12 +746,6 @@ static void watchdog_reset() { | |||
746 | } | 746 | } |
747 | #endif | 747 | #endif |
748 | 748 | ||
749 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, | ||
750 | resource_size_t size, resource_size_t align) | ||
751 | { | ||
752 | return res->start; | ||
753 | } | ||
754 | |||
755 | int pcibios_enable_device(struct pci_dev *pdev, int mask) | 749 | int pcibios_enable_device(struct pci_dev *pdev, int mask) |
756 | { | 750 | { |
757 | return 0; | 751 | return 0; |
diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index bc6656b5708b..bbf81579b1f8 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c | |||
@@ -67,16 +67,6 @@ static struct pci_ops tile_cfg_ops; | |||
67 | 67 | ||
68 | 68 | ||
69 | /* | 69 | /* |
70 | * We don't need to worry about the alignment of resources. | ||
71 | */ | ||
72 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, | ||
73 | resource_size_t size, resource_size_t align) | ||
74 | { | ||
75 | return res->start; | ||
76 | } | ||
77 | EXPORT_SYMBOL(pcibios_align_resource); | ||
78 | |||
79 | /* | ||
80 | * Open a FD to the hypervisor PCI device. | 70 | * Open a FD to the hypervisor PCI device. |
81 | * | 71 | * |
82 | * controller_id is the controller number, config type is 0 or 1 for | 72 | * controller_id is the controller number, config type is 0 or 1 for |
@@ -274,6 +264,7 @@ static void fixup_read_and_payload_sizes(void) | |||
274 | */ | 264 | */ |
275 | int __init pcibios_init(void) | 265 | int __init pcibios_init(void) |
276 | { | 266 | { |
267 | struct pci_host_bridge *bridge; | ||
277 | int i; | 268 | int i; |
278 | 269 | ||
279 | pr_info("PCI: Probing PCI hardware\n"); | 270 | pr_info("PCI: Probing PCI hardware\n"); |
@@ -306,16 +297,26 @@ int __init pcibios_init(void) | |||
306 | 297 | ||
307 | pci_add_resource(&resources, &ioport_resource); | 298 | pci_add_resource(&resources, &ioport_resource); |
308 | pci_add_resource(&resources, &iomem_resource); | 299 | pci_add_resource(&resources, &iomem_resource); |
309 | bus = pci_scan_root_bus(NULL, 0, controller->ops, | 300 | |
310 | controller, &resources); | 301 | bridge = pci_alloc_host_bridge(0); |
302 | if (!bridge) | ||
303 | break; | ||
304 | |||
305 | list_splice_init(&resources, &bridge->windows); | ||
306 | bridge->dev.parent = NULL; | ||
307 | bridge->sysdata = controller; | ||
308 | bridge->busnr = 0; | ||
309 | bridge->ops = controller->ops; | ||
310 | bridge->swizzle_irq = pci_common_swizzle; | ||
311 | bridge->map_irq = tile_map_irq; | ||
312 | |||
313 | pci_scan_root_bus_bridge(bridge); | ||
314 | bus = bridge->bus; | ||
311 | controller->root_bus = bus; | 315 | controller->root_bus = bus; |
312 | controller->last_busno = bus->busn_res.end; | 316 | controller->last_busno = bus->busn_res.end; |
313 | } | 317 | } |
314 | } | 318 | } |
315 | 319 | ||
316 | /* Do machine dependent PCI interrupt routing */ | ||
317 | pci_fixup_irqs(pci_common_swizzle, tile_map_irq); | ||
318 | |||
319 | /* | 320 | /* |
320 | * This comes from the generic Linux PCI driver. | 321 | * This comes from the generic Linux PCI driver. |
321 | * | 322 | * |
@@ -369,14 +370,6 @@ int __init pcibios_init(void) | |||
369 | } | 370 | } |
370 | subsys_initcall(pcibios_init); | 371 | subsys_initcall(pcibios_init); |
371 | 372 | ||
372 | /* | ||
373 | * No bus fixups needed. | ||
374 | */ | ||
375 | void pcibios_fixup_bus(struct pci_bus *bus) | ||
376 | { | ||
377 | /* Nothing needs to be done. */ | ||
378 | } | ||
379 | |||
380 | void pcibios_set_master(struct pci_dev *dev) | 373 | void pcibios_set_master(struct pci_dev *dev) |
381 | { | 374 | { |
382 | /* No special bus mastering setup handling. */ | 375 | /* No special bus mastering setup handling. */ |
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c index b554a68eea1b..9aa238ac7b35 100644 --- a/arch/tile/kernel/pci_gx.c +++ b/arch/tile/kernel/pci_gx.c | |||
@@ -108,15 +108,6 @@ static struct pci_ops tile_cfg_ops; | |||
108 | /* Mask of CPUs that should receive PCIe interrupts. */ | 108 | /* Mask of CPUs that should receive PCIe interrupts. */ |
109 | static struct cpumask intr_cpus_map; | 109 | static struct cpumask intr_cpus_map; |
110 | 110 | ||
111 | /* We don't need to worry about the alignment of resources. */ | ||
112 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, | ||
113 | resource_size_t size, | ||
114 | resource_size_t align) | ||
115 | { | ||
116 | return res->start; | ||
117 | } | ||
118 | EXPORT_SYMBOL(pcibios_align_resource); | ||
119 | |||
120 | /* | 111 | /* |
121 | * Pick a CPU to receive and handle the PCIe interrupts, based on the IRQ #. | 112 | * Pick a CPU to receive and handle the PCIe interrupts, based on the IRQ #. |
122 | * For now, we simply send interrupts to non-dataplane CPUs. | 113 | * For now, we simply send interrupts to non-dataplane CPUs. |
@@ -669,6 +660,7 @@ int __init pcibios_init(void) | |||
669 | resource_size_t offset; | 660 | resource_size_t offset; |
670 | LIST_HEAD(resources); | 661 | LIST_HEAD(resources); |
671 | int next_busno; | 662 | int next_busno; |
663 | struct pci_host_bridge *bridge; | ||
672 | int i; | 664 | int i; |
673 | 665 | ||
674 | tile_pci_init(); | 666 | tile_pci_init(); |
@@ -881,15 +873,25 @@ int __init pcibios_init(void) | |||
881 | controller->mem_offset); | 873 | controller->mem_offset); |
882 | pci_add_resource(&resources, &controller->io_space); | 874 | pci_add_resource(&resources, &controller->io_space); |
883 | controller->first_busno = next_busno; | 875 | controller->first_busno = next_busno; |
884 | bus = pci_scan_root_bus(NULL, next_busno, controller->ops, | 876 | |
885 | controller, &resources); | 877 | bridge = pci_alloc_host_bridge(0); |
878 | if (!bridge) | ||
879 | break; | ||
880 | |||
881 | list_splice_init(&resources, &bridge->windows); | ||
882 | bridge->dev.parent = NULL; | ||
883 | bridge->sysdata = controller; | ||
884 | bridge->busnr = next_busno; | ||
885 | bridge->ops = controller->ops; | ||
886 | bridge->swizzle_irq = pci_common_swizzle; | ||
887 | bridge->map_irq = tile_map_irq; | ||
888 | |||
889 | pci_scan_root_bus_bridge(bridge); | ||
890 | bus = bridge->bus; | ||
886 | controller->root_bus = bus; | 891 | controller->root_bus = bus; |
887 | next_busno = bus->busn_res.end + 1; | 892 | next_busno = bus->busn_res.end + 1; |
888 | } | 893 | } |
889 | 894 | ||
890 | /* Do machine dependent PCI interrupt routing */ | ||
891 | pci_fixup_irqs(pci_common_swizzle, tile_map_irq); | ||
892 | |||
893 | /* | 895 | /* |
894 | * This comes from the generic Linux PCI driver. | 896 | * This comes from the generic Linux PCI driver. |
895 | * | 897 | * |
@@ -1038,11 +1040,6 @@ alloc_mem_map_failed: | |||
1038 | } | 1040 | } |
1039 | subsys_initcall(pcibios_init); | 1041 | subsys_initcall(pcibios_init); |
1040 | 1042 | ||
1041 | /* No bus fixups needed. */ | ||
1042 | void pcibios_fixup_bus(struct pci_bus *bus) | ||
1043 | { | ||
1044 | } | ||
1045 | |||
1046 | /* Process any "pci=" kernel boot arguments. */ | 1043 | /* Process any "pci=" kernel boot arguments. */ |
1047 | char *__init pcibios_setup(char *str) | 1044 | char *__init pcibios_setup(char *str) |
1048 | { | 1045 | { |
diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c index 1053bca1f8aa..9f26840e41b1 100644 --- a/arch/unicore32/kernel/pci.c +++ b/arch/unicore32/kernel/pci.c | |||
@@ -101,7 +101,7 @@ void pci_puv3_preinit(void) | |||
101 | writel(readl(PCIBRI_CMD) | PCIBRI_CMD_IO | PCIBRI_CMD_MEM, PCIBRI_CMD); | 101 | writel(readl(PCIBRI_CMD) | PCIBRI_CMD_IO | PCIBRI_CMD_MEM, PCIBRI_CMD); |
102 | } | 102 | } |
103 | 103 | ||
104 | static int __init pci_puv3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | 104 | static int pci_puv3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) |
105 | { | 105 | { |
106 | if (dev->bus->number == 0) { | 106 | if (dev->bus->number == 0) { |
107 | #ifdef CONFIG_ARCH_FPGA /* 4 pci slots */ | 107 | #ifdef CONFIG_ARCH_FPGA /* 4 pci slots */ |
@@ -252,19 +252,46 @@ void pcibios_fixup_bus(struct pci_bus *bus) | |||
252 | } | 252 | } |
253 | EXPORT_SYMBOL(pcibios_fixup_bus); | 253 | EXPORT_SYMBOL(pcibios_fixup_bus); |
254 | 254 | ||
255 | static struct resource busn_resource = { | ||
256 | .name = "PCI busn", | ||
257 | .start = 0, | ||
258 | .end = 255, | ||
259 | .flags = IORESOURCE_BUS, | ||
260 | }; | ||
261 | |||
255 | static int __init pci_common_init(void) | 262 | static int __init pci_common_init(void) |
256 | { | 263 | { |
257 | struct pci_bus *puv3_bus; | 264 | struct pci_bus *puv3_bus; |
265 | struct pci_host_bridge *bridge; | ||
266 | int ret; | ||
267 | |||
268 | bridge = pci_alloc_host_bridge(0); | ||
269 | if (!bridge) | ||
270 | return -ENOMEM; | ||
258 | 271 | ||
259 | pci_puv3_preinit(); | 272 | pci_puv3_preinit(); |
260 | 273 | ||
261 | puv3_bus = pci_scan_bus(0, &pci_puv3_ops, NULL); | 274 | pci_add_resource(&bridge->windows, &ioport_resource); |
275 | pci_add_resource(&bridge->windows, &iomem_resource); | ||
276 | pci_add_resource(&bridge->windows, &busn_resource); | ||
277 | bridge->sysdata = NULL; | ||
278 | bridge->busnr = 0; | ||
279 | bridge->ops = &pci_puv3_ops; | ||
280 | bridge->swizzle_irq = pci_common_swizzle; | ||
281 | bridge->map_irq = pci_puv3_map_irq; | ||
282 | |||
283 | /* Scan our single hose. */ | ||
284 | ret = pci_scan_root_bus_bridge(bridge); | ||
285 | if (ret) { | ||
286 | pci_free_host_bridge(bridge); | ||
287 | return; | ||
288 | } | ||
289 | |||
290 | puv3_bus = bridge->bus; | ||
262 | 291 | ||
263 | if (!puv3_bus) | 292 | if (!puv3_bus) |
264 | panic("PCI: unable to scan bus!"); | 293 | panic("PCI: unable to scan bus!"); |
265 | 294 | ||
266 | pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq); | ||
267 | |||
268 | pci_bus_size_bridges(puv3_bus); | 295 | pci_bus_size_bridges(puv3_bus); |
269 | pci_bus_assign_resources(puv3_bus); | 296 | pci_bus_assign_resources(puv3_bus); |
270 | pci_bus_add_devices(puv3_bus); | 297 | pci_bus_add_devices(puv3_bus); |
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 11e407489db0..f2228b150faa 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c | |||
@@ -618,3 +618,20 @@ static void quirk_apple_mbp_poweroff(struct pci_dev *pdev) | |||
618 | dev_info(dev, "can't work around MacBook Pro poweroff issue\n"); | 618 | dev_info(dev, "can't work around MacBook Pro poweroff issue\n"); |
619 | } | 619 | } |
620 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x8c10, quirk_apple_mbp_poweroff); | 620 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x8c10, quirk_apple_mbp_poweroff); |
621 | |||
622 | /* | ||
623 | * VMD-enabled root ports will change the source ID for all messages | ||
624 | * to the VMD device. Rather than doing device matching with the source | ||
625 | * ID, the AER driver should traverse the child device tree, reading | ||
626 | * AER registers to find the faulting device. | ||
627 | */ | ||
628 | static void quirk_no_aersid(struct pci_dev *pdev) | ||
629 | { | ||
630 | /* VMD Domain */ | ||
631 | if (is_vmd(pdev->bus)) | ||
632 | pdev->bus->bus_flags |= PCI_BUS_FLAGS_NO_AERSID; | ||
633 | } | ||
634 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2030, quirk_no_aersid); | ||
635 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2031, quirk_no_aersid); | ||
636 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2032, quirk_no_aersid); | ||
637 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2033, quirk_no_aersid); | ||
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 3e8636f1220e..bb05fc50ee2e 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -901,6 +901,13 @@ static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devf | |||
901 | struct pci_dev *pf_pdev; | 901 | struct pci_dev *pf_pdev; |
902 | 902 | ||
903 | pdev = to_pci_dev(dev); | 903 | pdev = to_pci_dev(dev); |
904 | |||
905 | #ifdef CONFIG_X86 | ||
906 | /* VMD child devices currently cannot be handled individually */ | ||
907 | if (is_vmd(pdev->bus)) | ||
908 | return NULL; | ||
909 | #endif | ||
910 | |||
904 | /* VFs aren't listed in scope tables; we need to look up | 911 | /* VFs aren't listed in scope tables; we need to look up |
905 | * the PF instead to find the IOMMU. */ | 912 | * the PF instead to find the IOMMU. */ |
906 | pf_pdev = pci_physfn(pdev); | 913 | pf_pdev = pci_physfn(pdev); |
diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c index 09c10f426b64..deb203026496 100644 --- a/drivers/misc/pci_endpoint_test.c +++ b/drivers/misc/pci_endpoint_test.c | |||
@@ -72,6 +72,11 @@ static DEFINE_IDA(pci_endpoint_test_ida); | |||
72 | 72 | ||
73 | #define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \ | 73 | #define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \ |
74 | miscdev) | 74 | miscdev) |
75 | |||
76 | static bool no_msi; | ||
77 | module_param(no_msi, bool, 0444); | ||
78 | MODULE_PARM_DESC(no_msi, "Disable MSI interrupt in pci_endpoint_test"); | ||
79 | |||
75 | enum pci_barno { | 80 | enum pci_barno { |
76 | BAR_0, | 81 | BAR_0, |
77 | BAR_1, | 82 | BAR_1, |
@@ -90,9 +95,15 @@ struct pci_endpoint_test { | |||
90 | /* mutex to protect the ioctls */ | 95 | /* mutex to protect the ioctls */ |
91 | struct mutex mutex; | 96 | struct mutex mutex; |
92 | struct miscdevice miscdev; | 97 | struct miscdevice miscdev; |
98 | enum pci_barno test_reg_bar; | ||
99 | size_t alignment; | ||
93 | }; | 100 | }; |
94 | 101 | ||
95 | static int bar_size[] = { 4, 512, 1024, 16384, 131072, 1048576 }; | 102 | struct pci_endpoint_test_data { |
103 | enum pci_barno test_reg_bar; | ||
104 | size_t alignment; | ||
105 | bool no_msi; | ||
106 | }; | ||
96 | 107 | ||
97 | static inline u32 pci_endpoint_test_readl(struct pci_endpoint_test *test, | 108 | static inline u32 pci_endpoint_test_readl(struct pci_endpoint_test *test, |
98 | u32 offset) | 109 | u32 offset) |
@@ -141,11 +152,15 @@ static bool pci_endpoint_test_bar(struct pci_endpoint_test *test, | |||
141 | int j; | 152 | int j; |
142 | u32 val; | 153 | u32 val; |
143 | int size; | 154 | int size; |
155 | struct pci_dev *pdev = test->pdev; | ||
144 | 156 | ||
145 | if (!test->bar[barno]) | 157 | if (!test->bar[barno]) |
146 | return false; | 158 | return false; |
147 | 159 | ||
148 | size = bar_size[barno]; | 160 | size = pci_resource_len(pdev, barno); |
161 | |||
162 | if (barno == test->test_reg_bar) | ||
163 | size = 0x4; | ||
149 | 164 | ||
150 | for (j = 0; j < size; j += 4) | 165 | for (j = 0; j < size; j += 4) |
151 | pci_endpoint_test_bar_writel(test, barno, j, 0xA0A0A0A0); | 166 | pci_endpoint_test_bar_writel(test, barno, j, 0xA0A0A0A0); |
@@ -202,16 +217,32 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) | |||
202 | dma_addr_t dst_phys_addr; | 217 | dma_addr_t dst_phys_addr; |
203 | struct pci_dev *pdev = test->pdev; | 218 | struct pci_dev *pdev = test->pdev; |
204 | struct device *dev = &pdev->dev; | 219 | struct device *dev = &pdev->dev; |
220 | void *orig_src_addr; | ||
221 | dma_addr_t orig_src_phys_addr; | ||
222 | void *orig_dst_addr; | ||
223 | dma_addr_t orig_dst_phys_addr; | ||
224 | size_t offset; | ||
225 | size_t alignment = test->alignment; | ||
205 | u32 src_crc32; | 226 | u32 src_crc32; |
206 | u32 dst_crc32; | 227 | u32 dst_crc32; |
207 | 228 | ||
208 | src_addr = dma_alloc_coherent(dev, size, &src_phys_addr, GFP_KERNEL); | 229 | orig_src_addr = dma_alloc_coherent(dev, size + alignment, |
209 | if (!src_addr) { | 230 | &orig_src_phys_addr, GFP_KERNEL); |
231 | if (!orig_src_addr) { | ||
210 | dev_err(dev, "failed to allocate source buffer\n"); | 232 | dev_err(dev, "failed to allocate source buffer\n"); |
211 | ret = false; | 233 | ret = false; |
212 | goto err; | 234 | goto err; |
213 | } | 235 | } |
214 | 236 | ||
237 | if (alignment && !IS_ALIGNED(orig_src_phys_addr, alignment)) { | ||
238 | src_phys_addr = PTR_ALIGN(orig_src_phys_addr, alignment); | ||
239 | offset = src_phys_addr - orig_src_phys_addr; | ||
240 | src_addr = orig_src_addr + offset; | ||
241 | } else { | ||
242 | src_phys_addr = orig_src_phys_addr; | ||
243 | src_addr = orig_src_addr; | ||
244 | } | ||
245 | |||
215 | pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_SRC_ADDR, | 246 | pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_SRC_ADDR, |
216 | lower_32_bits(src_phys_addr)); | 247 | lower_32_bits(src_phys_addr)); |
217 | 248 | ||
@@ -221,11 +252,21 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) | |||
221 | get_random_bytes(src_addr, size); | 252 | get_random_bytes(src_addr, size); |
222 | src_crc32 = crc32_le(~0, src_addr, size); | 253 | src_crc32 = crc32_le(~0, src_addr, size); |
223 | 254 | ||
224 | dst_addr = dma_alloc_coherent(dev, size, &dst_phys_addr, GFP_KERNEL); | 255 | orig_dst_addr = dma_alloc_coherent(dev, size + alignment, |
225 | if (!dst_addr) { | 256 | &orig_dst_phys_addr, GFP_KERNEL); |
257 | if (!orig_dst_addr) { | ||
226 | dev_err(dev, "failed to allocate destination address\n"); | 258 | dev_err(dev, "failed to allocate destination address\n"); |
227 | ret = false; | 259 | ret = false; |
228 | goto err_src_addr; | 260 | goto err_orig_src_addr; |
261 | } | ||
262 | |||
263 | if (alignment && !IS_ALIGNED(orig_dst_phys_addr, alignment)) { | ||
264 | dst_phys_addr = PTR_ALIGN(orig_dst_phys_addr, alignment); | ||
265 | offset = dst_phys_addr - orig_dst_phys_addr; | ||
266 | dst_addr = orig_dst_addr + offset; | ||
267 | } else { | ||
268 | dst_phys_addr = orig_dst_phys_addr; | ||
269 | dst_addr = orig_dst_addr; | ||
229 | } | 270 | } |
230 | 271 | ||
231 | pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_DST_ADDR, | 272 | pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_DST_ADDR, |
@@ -245,10 +286,12 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) | |||
245 | if (dst_crc32 == src_crc32) | 286 | if (dst_crc32 == src_crc32) |
246 | ret = true; | 287 | ret = true; |
247 | 288 | ||
248 | dma_free_coherent(dev, size, dst_addr, dst_phys_addr); | 289 | dma_free_coherent(dev, size + alignment, orig_dst_addr, |
290 | orig_dst_phys_addr); | ||
249 | 291 | ||
250 | err_src_addr: | 292 | err_orig_src_addr: |
251 | dma_free_coherent(dev, size, src_addr, src_phys_addr); | 293 | dma_free_coherent(dev, size + alignment, orig_src_addr, |
294 | orig_src_phys_addr); | ||
252 | 295 | ||
253 | err: | 296 | err: |
254 | return ret; | 297 | return ret; |
@@ -262,15 +305,29 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size) | |||
262 | dma_addr_t phys_addr; | 305 | dma_addr_t phys_addr; |
263 | struct pci_dev *pdev = test->pdev; | 306 | struct pci_dev *pdev = test->pdev; |
264 | struct device *dev = &pdev->dev; | 307 | struct device *dev = &pdev->dev; |
308 | void *orig_addr; | ||
309 | dma_addr_t orig_phys_addr; | ||
310 | size_t offset; | ||
311 | size_t alignment = test->alignment; | ||
265 | u32 crc32; | 312 | u32 crc32; |
266 | 313 | ||
267 | addr = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL); | 314 | orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr, |
268 | if (!addr) { | 315 | GFP_KERNEL); |
316 | if (!orig_addr) { | ||
269 | dev_err(dev, "failed to allocate address\n"); | 317 | dev_err(dev, "failed to allocate address\n"); |
270 | ret = false; | 318 | ret = false; |
271 | goto err; | 319 | goto err; |
272 | } | 320 | } |
273 | 321 | ||
322 | if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) { | ||
323 | phys_addr = PTR_ALIGN(orig_phys_addr, alignment); | ||
324 | offset = phys_addr - orig_phys_addr; | ||
325 | addr = orig_addr + offset; | ||
326 | } else { | ||
327 | phys_addr = orig_phys_addr; | ||
328 | addr = orig_addr; | ||
329 | } | ||
330 | |||
274 | get_random_bytes(addr, size); | 331 | get_random_bytes(addr, size); |
275 | 332 | ||
276 | crc32 = crc32_le(~0, addr, size); | 333 | crc32 = crc32_le(~0, addr, size); |
@@ -293,7 +350,7 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size) | |||
293 | if (reg & STATUS_READ_SUCCESS) | 350 | if (reg & STATUS_READ_SUCCESS) |
294 | ret = true; | 351 | ret = true; |
295 | 352 | ||
296 | dma_free_coherent(dev, size, addr, phys_addr); | 353 | dma_free_coherent(dev, size + alignment, orig_addr, orig_phys_addr); |
297 | 354 | ||
298 | err: | 355 | err: |
299 | return ret; | 356 | return ret; |
@@ -306,15 +363,29 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size) | |||
306 | dma_addr_t phys_addr; | 363 | dma_addr_t phys_addr; |
307 | struct pci_dev *pdev = test->pdev; | 364 | struct pci_dev *pdev = test->pdev; |
308 | struct device *dev = &pdev->dev; | 365 | struct device *dev = &pdev->dev; |
366 | void *orig_addr; | ||
367 | dma_addr_t orig_phys_addr; | ||
368 | size_t offset; | ||
369 | size_t alignment = test->alignment; | ||
309 | u32 crc32; | 370 | u32 crc32; |
310 | 371 | ||
311 | addr = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL); | 372 | orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr, |
312 | if (!addr) { | 373 | GFP_KERNEL); |
374 | if (!orig_addr) { | ||
313 | dev_err(dev, "failed to allocate destination address\n"); | 375 | dev_err(dev, "failed to allocate destination address\n"); |
314 | ret = false; | 376 | ret = false; |
315 | goto err; | 377 | goto err; |
316 | } | 378 | } |
317 | 379 | ||
380 | if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) { | ||
381 | phys_addr = PTR_ALIGN(orig_phys_addr, alignment); | ||
382 | offset = phys_addr - orig_phys_addr; | ||
383 | addr = orig_addr + offset; | ||
384 | } else { | ||
385 | phys_addr = orig_phys_addr; | ||
386 | addr = orig_addr; | ||
387 | } | ||
388 | |||
318 | pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_DST_ADDR, | 389 | pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_DST_ADDR, |
319 | lower_32_bits(phys_addr)); | 390 | lower_32_bits(phys_addr)); |
320 | pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_DST_ADDR, | 391 | pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_DST_ADDR, |
@@ -331,7 +402,7 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size) | |||
331 | if (crc32 == pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CHECKSUM)) | 402 | if (crc32 == pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CHECKSUM)) |
332 | ret = true; | 403 | ret = true; |
333 | 404 | ||
334 | dma_free_coherent(dev, size, addr, phys_addr); | 405 | dma_free_coherent(dev, size + alignment, orig_addr, orig_phys_addr); |
335 | err: | 406 | err: |
336 | return ret; | 407 | return ret; |
337 | } | 408 | } |
@@ -383,13 +454,15 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, | |||
383 | { | 454 | { |
384 | int i; | 455 | int i; |
385 | int err; | 456 | int err; |
386 | int irq; | 457 | int irq = 0; |
387 | int id; | 458 | int id; |
388 | char name[20]; | 459 | char name[20]; |
389 | enum pci_barno bar; | 460 | enum pci_barno bar; |
390 | void __iomem *base; | 461 | void __iomem *base; |
391 | struct device *dev = &pdev->dev; | 462 | struct device *dev = &pdev->dev; |
392 | struct pci_endpoint_test *test; | 463 | struct pci_endpoint_test *test; |
464 | struct pci_endpoint_test_data *data; | ||
465 | enum pci_barno test_reg_bar = BAR_0; | ||
393 | struct miscdevice *misc_device; | 466 | struct miscdevice *misc_device; |
394 | 467 | ||
395 | if (pci_is_bridge(pdev)) | 468 | if (pci_is_bridge(pdev)) |
@@ -399,7 +472,17 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, | |||
399 | if (!test) | 472 | if (!test) |
400 | return -ENOMEM; | 473 | return -ENOMEM; |
401 | 474 | ||
475 | test->test_reg_bar = 0; | ||
476 | test->alignment = 0; | ||
402 | test->pdev = pdev; | 477 | test->pdev = pdev; |
478 | |||
479 | data = (struct pci_endpoint_test_data *)ent->driver_data; | ||
480 | if (data) { | ||
481 | test_reg_bar = data->test_reg_bar; | ||
482 | test->alignment = data->alignment; | ||
483 | no_msi = data->no_msi; | ||
484 | } | ||
485 | |||
403 | init_completion(&test->irq_raised); | 486 | init_completion(&test->irq_raised); |
404 | mutex_init(&test->mutex); | 487 | mutex_init(&test->mutex); |
405 | 488 | ||
@@ -417,9 +500,11 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, | |||
417 | 500 | ||
418 | pci_set_master(pdev); | 501 | pci_set_master(pdev); |
419 | 502 | ||
420 | irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI); | 503 | if (!no_msi) { |
421 | if (irq < 0) | 504 | irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI); |
422 | dev_err(dev, "failed to get MSI interrupts\n"); | 505 | if (irq < 0) |
506 | dev_err(dev, "failed to get MSI interrupts\n"); | ||
507 | } | ||
423 | 508 | ||
424 | err = devm_request_irq(dev, pdev->irq, pci_endpoint_test_irqhandler, | 509 | err = devm_request_irq(dev, pdev->irq, pci_endpoint_test_irqhandler, |
425 | IRQF_SHARED, DRV_MODULE_NAME, test); | 510 | IRQF_SHARED, DRV_MODULE_NAME, test); |
@@ -441,14 +526,15 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, | |||
441 | base = pci_ioremap_bar(pdev, bar); | 526 | base = pci_ioremap_bar(pdev, bar); |
442 | if (!base) { | 527 | if (!base) { |
443 | dev_err(dev, "failed to read BAR%d\n", bar); | 528 | dev_err(dev, "failed to read BAR%d\n", bar); |
444 | WARN_ON(bar == BAR_0); | 529 | WARN_ON(bar == test_reg_bar); |
445 | } | 530 | } |
446 | test->bar[bar] = base; | 531 | test->bar[bar] = base; |
447 | } | 532 | } |
448 | 533 | ||
449 | test->base = test->bar[0]; | 534 | test->base = test->bar[test_reg_bar]; |
450 | if (!test->base) { | 535 | if (!test->base) { |
451 | dev_err(dev, "Cannot perform PCI test without BAR0\n"); | 536 | dev_err(dev, "Cannot perform PCI test without BAR%d\n", |
537 | test_reg_bar); | ||
452 | goto err_iounmap; | 538 | goto err_iounmap; |
453 | } | 539 | } |
454 | 540 | ||
diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig index d275aadc47ee..22ec82fcdea2 100644 --- a/drivers/pci/dwc/Kconfig +++ b/drivers/pci/dwc/Kconfig | |||
@@ -25,7 +25,7 @@ config PCI_DRA7XX | |||
25 | work either as EP or RC. In order to enable host-specific features | 25 | work either as EP or RC. In order to enable host-specific features |
26 | PCI_DRA7XX_HOST must be selected and in order to enable device- | 26 | PCI_DRA7XX_HOST must be selected and in order to enable device- |
27 | specific features PCI_DRA7XX_EP must be selected. This uses | 27 | specific features PCI_DRA7XX_EP must be selected. This uses |
28 | the Designware core. | 28 | the DesignWare core. |
29 | 29 | ||
30 | if PCI_DRA7XX | 30 | if PCI_DRA7XX |
31 | 31 | ||
@@ -97,8 +97,8 @@ config PCI_KEYSTONE | |||
97 | select PCIE_DW_HOST | 97 | select PCIE_DW_HOST |
98 | help | 98 | help |
99 | Say Y here if you want to enable PCI controller support on Keystone | 99 | Say Y here if you want to enable PCI controller support on Keystone |
100 | SoCs. The PCI controller on Keystone is based on Designware hardware | 100 | SoCs. The PCI controller on Keystone is based on DesignWare hardware |
101 | and therefore the driver re-uses the Designware core functions to | 101 | and therefore the driver re-uses the DesignWare core functions to |
102 | implement the driver. | 102 | implement the driver. |
103 | 103 | ||
104 | config PCI_LAYERSCAPE | 104 | config PCI_LAYERSCAPE |
@@ -132,7 +132,7 @@ config PCIE_QCOM | |||
132 | select PCIE_DW_HOST | 132 | select PCIE_DW_HOST |
133 | help | 133 | help |
134 | Say Y here to enable PCIe controller support on Qualcomm SoCs. The | 134 | Say Y here to enable PCIe controller support on Qualcomm SoCs. The |
135 | PCIe controller uses the Designware core plus Qualcomm-specific | 135 | PCIe controller uses the DesignWare core plus Qualcomm-specific |
136 | hardware wrappers. | 136 | hardware wrappers. |
137 | 137 | ||
138 | config PCIE_ARMADA_8K | 138 | config PCIE_ARMADA_8K |
@@ -145,8 +145,8 @@ config PCIE_ARMADA_8K | |||
145 | help | 145 | help |
146 | Say Y here if you want to enable PCIe controller support on | 146 | Say Y here if you want to enable PCIe controller support on |
147 | Armada-8K SoCs. The PCIe controller on Armada-8K is based on | 147 | Armada-8K SoCs. The PCIe controller on Armada-8K is based on |
148 | Designware hardware and therefore the driver re-uses the | 148 | DesignWare hardware and therefore the driver re-uses the |
149 | Designware core functions to implement the driver. | 149 | DesignWare core functions to implement the driver. |
150 | 150 | ||
151 | config PCIE_ARTPEC6 | 151 | config PCIE_ARTPEC6 |
152 | bool "Axis ARTPEC-6 PCIe controller" | 152 | bool "Axis ARTPEC-6 PCIe controller" |
diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c index f2fc5f47064e..34427a6a15af 100644 --- a/drivers/pci/dwc/pci-dra7xx.c +++ b/drivers/pci/dwc/pci-dra7xx.c | |||
@@ -195,7 +195,7 @@ static void dra7xx_pcie_enable_interrupts(struct dra7xx_pcie *dra7xx) | |||
195 | dra7xx_pcie_enable_msi_interrupts(dra7xx); | 195 | dra7xx_pcie_enable_msi_interrupts(dra7xx); |
196 | } | 196 | } |
197 | 197 | ||
198 | static void dra7xx_pcie_host_init(struct pcie_port *pp) | 198 | static int dra7xx_pcie_host_init(struct pcie_port *pp) |
199 | { | 199 | { |
200 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 200 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
201 | struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); | 201 | struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); |
@@ -206,6 +206,8 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp) | |||
206 | dw_pcie_wait_for_link(pci); | 206 | dw_pcie_wait_for_link(pci); |
207 | dw_pcie_msi_init(pp); | 207 | dw_pcie_msi_init(pp); |
208 | dra7xx_pcie_enable_interrupts(dra7xx); | 208 | dra7xx_pcie_enable_interrupts(dra7xx); |
209 | |||
210 | return 0; | ||
209 | } | 211 | } |
210 | 212 | ||
211 | static const struct dw_pcie_host_ops dra7xx_pcie_host_ops = { | 213 | static const struct dw_pcie_host_ops dra7xx_pcie_host_ops = { |
@@ -238,7 +240,7 @@ static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp) | |||
238 | return -ENODEV; | 240 | return -ENODEV; |
239 | } | 241 | } |
240 | 242 | ||
241 | dra7xx->irq_domain = irq_domain_add_linear(pcie_intc_node, 4, | 243 | dra7xx->irq_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, |
242 | &intx_domain_ops, pp); | 244 | &intx_domain_ops, pp); |
243 | if (!dra7xx->irq_domain) { | 245 | if (!dra7xx->irq_domain) { |
244 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); | 246 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); |
@@ -275,7 +277,6 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg) | |||
275 | return IRQ_HANDLED; | 277 | return IRQ_HANDLED; |
276 | } | 278 | } |
277 | 279 | ||
278 | |||
279 | static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg) | 280 | static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg) |
280 | { | 281 | { |
281 | struct dra7xx_pcie *dra7xx = arg; | 282 | struct dra7xx_pcie *dra7xx = arg; |
@@ -335,10 +336,23 @@ static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg) | |||
335 | return IRQ_HANDLED; | 336 | return IRQ_HANDLED; |
336 | } | 337 | } |
337 | 338 | ||
339 | static void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) | ||
340 | { | ||
341 | u32 reg; | ||
342 | |||
343 | reg = PCI_BASE_ADDRESS_0 + (4 * bar); | ||
344 | dw_pcie_writel_dbi2(pci, reg, 0x0); | ||
345 | dw_pcie_writel_dbi(pci, reg, 0x0); | ||
346 | } | ||
347 | |||
338 | static void dra7xx_pcie_ep_init(struct dw_pcie_ep *ep) | 348 | static void dra7xx_pcie_ep_init(struct dw_pcie_ep *ep) |
339 | { | 349 | { |
340 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); | 350 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); |
341 | struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); | 351 | struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); |
352 | enum pci_barno bar; | ||
353 | |||
354 | for (bar = BAR_0; bar <= BAR_5; bar++) | ||
355 | dw_pcie_ep_reset_bar(pci, bar); | ||
342 | 356 | ||
343 | dra7xx_pcie_enable_wrapper_interrupts(dra7xx); | 357 | dra7xx_pcie_enable_wrapper_interrupts(dra7xx); |
344 | } | 358 | } |
@@ -435,7 +449,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx, | |||
435 | pp->irq = platform_get_irq(pdev, 1); | 449 | pp->irq = platform_get_irq(pdev, 1); |
436 | if (pp->irq < 0) { | 450 | if (pp->irq < 0) { |
437 | dev_err(dev, "missing IRQ resource\n"); | 451 | dev_err(dev, "missing IRQ resource\n"); |
438 | return -EINVAL; | 452 | return pp->irq; |
439 | } | 453 | } |
440 | 454 | ||
441 | ret = devm_request_irq(dev, pp->irq, dra7xx_pcie_msi_irq_handler, | 455 | ret = devm_request_irq(dev, pp->irq, dra7xx_pcie_msi_irq_handler, |
@@ -616,8 +630,8 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) | |||
616 | 630 | ||
617 | irq = platform_get_irq(pdev, 0); | 631 | irq = platform_get_irq(pdev, 0); |
618 | if (irq < 0) { | 632 | if (irq < 0) { |
619 | dev_err(dev, "missing IRQ resource\n"); | 633 | dev_err(dev, "missing IRQ resource: %d\n", irq); |
620 | return -EINVAL; | 634 | return irq; |
621 | } | 635 | } |
622 | 636 | ||
623 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ti_conf"); | 637 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ti_conf"); |
diff --git a/drivers/pci/dwc/pci-exynos.c b/drivers/pci/dwc/pci-exynos.c index c78c06552590..5596fdedbb94 100644 --- a/drivers/pci/dwc/pci-exynos.c +++ b/drivers/pci/dwc/pci-exynos.c | |||
@@ -581,13 +581,15 @@ static int exynos_pcie_link_up(struct dw_pcie *pci) | |||
581 | return 0; | 581 | return 0; |
582 | } | 582 | } |
583 | 583 | ||
584 | static void exynos_pcie_host_init(struct pcie_port *pp) | 584 | static int exynos_pcie_host_init(struct pcie_port *pp) |
585 | { | 585 | { |
586 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 586 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
587 | struct exynos_pcie *ep = to_exynos_pcie(pci); | 587 | struct exynos_pcie *ep = to_exynos_pcie(pci); |
588 | 588 | ||
589 | exynos_pcie_establish_link(ep); | 589 | exynos_pcie_establish_link(ep); |
590 | exynos_pcie_enable_interrupts(ep); | 590 | exynos_pcie_enable_interrupts(ep); |
591 | |||
592 | return 0; | ||
591 | } | 593 | } |
592 | 594 | ||
593 | static const struct dw_pcie_host_ops exynos_pcie_host_ops = { | 595 | static const struct dw_pcie_host_ops exynos_pcie_host_ops = { |
@@ -605,9 +607,9 @@ static int __init exynos_add_pcie_port(struct exynos_pcie *ep, | |||
605 | int ret; | 607 | int ret; |
606 | 608 | ||
607 | pp->irq = platform_get_irq(pdev, 1); | 609 | pp->irq = platform_get_irq(pdev, 1); |
608 | if (!pp->irq) { | 610 | if (pp->irq < 0) { |
609 | dev_err(dev, "failed to get irq\n"); | 611 | dev_err(dev, "failed to get irq\n"); |
610 | return -ENODEV; | 612 | return pp->irq; |
611 | } | 613 | } |
612 | ret = devm_request_irq(dev, pp->irq, exynos_pcie_irq_handler, | 614 | ret = devm_request_irq(dev, pp->irq, exynos_pcie_irq_handler, |
613 | IRQF_SHARED, "exynos-pcie", ep); | 615 | IRQF_SHARED, "exynos-pcie", ep); |
@@ -618,9 +620,9 @@ static int __init exynos_add_pcie_port(struct exynos_pcie *ep, | |||
618 | 620 | ||
619 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | 621 | if (IS_ENABLED(CONFIG_PCI_MSI)) { |
620 | pp->msi_irq = platform_get_irq(pdev, 0); | 622 | pp->msi_irq = platform_get_irq(pdev, 0); |
621 | if (!pp->msi_irq) { | 623 | if (pp->msi_irq < 0) { |
622 | dev_err(dev, "failed to get msi irq\n"); | 624 | dev_err(dev, "failed to get msi irq\n"); |
623 | return -ENODEV; | 625 | return pp->msi_irq; |
624 | } | 626 | } |
625 | 627 | ||
626 | ret = devm_request_irq(dev, pp->msi_irq, | 628 | ret = devm_request_irq(dev, pp->msi_irq, |
diff --git a/drivers/pci/dwc/pci-imx6.c b/drivers/pci/dwc/pci-imx6.c index bf5c3616e344..b73483534a5b 100644 --- a/drivers/pci/dwc/pci-imx6.c +++ b/drivers/pci/dwc/pci-imx6.c | |||
@@ -636,7 +636,7 @@ err_reset_phy: | |||
636 | return ret; | 636 | return ret; |
637 | } | 637 | } |
638 | 638 | ||
639 | static void imx6_pcie_host_init(struct pcie_port *pp) | 639 | static int imx6_pcie_host_init(struct pcie_port *pp) |
640 | { | 640 | { |
641 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 641 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
642 | struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci); | 642 | struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci); |
@@ -649,6 +649,8 @@ static void imx6_pcie_host_init(struct pcie_port *pp) | |||
649 | 649 | ||
650 | if (IS_ENABLED(CONFIG_PCI_MSI)) | 650 | if (IS_ENABLED(CONFIG_PCI_MSI)) |
651 | dw_pcie_msi_init(pp); | 651 | dw_pcie_msi_init(pp); |
652 | |||
653 | return 0; | ||
652 | } | 654 | } |
653 | 655 | ||
654 | static int imx6_pcie_link_up(struct dw_pcie *pci) | 656 | static int imx6_pcie_link_up(struct dw_pcie *pci) |
@@ -778,14 +780,15 @@ static int imx6_pcie_probe(struct platform_device *pdev) | |||
778 | } | 780 | } |
779 | break; | 781 | break; |
780 | case IMX7D: | 782 | case IMX7D: |
781 | imx6_pcie->pciephy_reset = devm_reset_control_get(dev, | 783 | imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev, |
782 | "pciephy"); | 784 | "pciephy"); |
783 | if (IS_ERR(imx6_pcie->pciephy_reset)) { | 785 | if (IS_ERR(imx6_pcie->pciephy_reset)) { |
784 | dev_err(dev, "Failed to get PCIEPHY reset control\n"); | 786 | dev_err(dev, "Failed to get PCIEPHY reset control\n"); |
785 | return PTR_ERR(imx6_pcie->pciephy_reset); | 787 | return PTR_ERR(imx6_pcie->pciephy_reset); |
786 | } | 788 | } |
787 | 789 | ||
788 | imx6_pcie->apps_reset = devm_reset_control_get(dev, "apps"); | 790 | imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev, |
791 | "apps"); | ||
789 | if (IS_ERR(imx6_pcie->apps_reset)) { | 792 | if (IS_ERR(imx6_pcie->apps_reset)) { |
790 | dev_err(dev, "Failed to get PCIE APPS reset control\n"); | 793 | dev_err(dev, "Failed to get PCIE APPS reset control\n"); |
791 | return PTR_ERR(imx6_pcie->apps_reset); | 794 | return PTR_ERR(imx6_pcie->apps_reset); |
diff --git a/drivers/pci/dwc/pci-keystone-dw.c b/drivers/pci/dwc/pci-keystone-dw.c index 8bc626e640c8..2fb20b887d2a 100644 --- a/drivers/pci/dwc/pci-keystone-dw.c +++ b/drivers/pci/dwc/pci-keystone-dw.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Designware application register space functions for Keystone PCI controller | 2 | * DesignWare application register space functions for Keystone PCI controller |
3 | * | 3 | * |
4 | * Copyright (C) 2013-2014 Texas Instruments., Ltd. | 4 | * Copyright (C) 2013-2014 Texas Instruments., Ltd. |
5 | * http://www.ti.com | 5 | * http://www.ti.com |
@@ -168,16 +168,12 @@ void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq) | |||
168 | 168 | ||
169 | static void ks_dw_pcie_msi_irq_mask(struct irq_data *d) | 169 | static void ks_dw_pcie_msi_irq_mask(struct irq_data *d) |
170 | { | 170 | { |
171 | struct keystone_pcie *ks_pcie; | ||
172 | struct msi_desc *msi; | 171 | struct msi_desc *msi; |
173 | struct pcie_port *pp; | 172 | struct pcie_port *pp; |
174 | struct dw_pcie *pci; | ||
175 | u32 offset; | 173 | u32 offset; |
176 | 174 | ||
177 | msi = irq_data_get_msi_desc(d); | 175 | msi = irq_data_get_msi_desc(d); |
178 | pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi); | 176 | pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi); |
179 | pci = to_dw_pcie_from_pp(pp); | ||
180 | ks_pcie = to_keystone_pcie(pci); | ||
181 | offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); | 177 | offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); |
182 | 178 | ||
183 | /* Mask the end point if PVM implemented */ | 179 | /* Mask the end point if PVM implemented */ |
@@ -191,16 +187,12 @@ static void ks_dw_pcie_msi_irq_mask(struct irq_data *d) | |||
191 | 187 | ||
192 | static void ks_dw_pcie_msi_irq_unmask(struct irq_data *d) | 188 | static void ks_dw_pcie_msi_irq_unmask(struct irq_data *d) |
193 | { | 189 | { |
194 | struct keystone_pcie *ks_pcie; | ||
195 | struct msi_desc *msi; | 190 | struct msi_desc *msi; |
196 | struct pcie_port *pp; | 191 | struct pcie_port *pp; |
197 | struct dw_pcie *pci; | ||
198 | u32 offset; | 192 | u32 offset; |
199 | 193 | ||
200 | msi = irq_data_get_msi_desc(d); | 194 | msi = irq_data_get_msi_desc(d); |
201 | pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi); | 195 | pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi); |
202 | pci = to_dw_pcie_from_pp(pp); | ||
203 | ks_pcie = to_keystone_pcie(pci); | ||
204 | offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); | 196 | offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); |
205 | 197 | ||
206 | /* Mask the end point if PVM implemented */ | 198 | /* Mask the end point if PVM implemented */ |
@@ -259,7 +251,7 @@ void ks_dw_pcie_enable_legacy_irqs(struct keystone_pcie *ks_pcie) | |||
259 | { | 251 | { |
260 | int i; | 252 | int i; |
261 | 253 | ||
262 | for (i = 0; i < MAX_LEGACY_IRQS; i++) | 254 | for (i = 0; i < PCI_NUM_INTX; i++) |
263 | ks_dw_app_writel(ks_pcie, IRQ_ENABLE_SET + (i << 4), 0x1); | 255 | ks_dw_app_writel(ks_pcie, IRQ_ENABLE_SET + (i << 4), 0x1); |
264 | } | 256 | } |
265 | 257 | ||
@@ -565,7 +557,7 @@ int __init ks_dw_pcie_host_init(struct keystone_pcie *ks_pcie, | |||
565 | /* Create legacy IRQ domain */ | 557 | /* Create legacy IRQ domain */ |
566 | ks_pcie->legacy_irq_domain = | 558 | ks_pcie->legacy_irq_domain = |
567 | irq_domain_add_linear(ks_pcie->legacy_intc_np, | 559 | irq_domain_add_linear(ks_pcie->legacy_intc_np, |
568 | MAX_LEGACY_IRQS, | 560 | PCI_NUM_INTX, |
569 | &ks_dw_pcie_legacy_irq_domain_ops, | 561 | &ks_dw_pcie_legacy_irq_domain_ops, |
570 | NULL); | 562 | NULL); |
571 | if (!ks_pcie->legacy_irq_domain) { | 563 | if (!ks_pcie->legacy_irq_domain) { |
diff --git a/drivers/pci/dwc/pci-keystone.c b/drivers/pci/dwc/pci-keystone.c index 4783cec1f78d..5bee3af47588 100644 --- a/drivers/pci/dwc/pci-keystone.c +++ b/drivers/pci/dwc/pci-keystone.c | |||
@@ -32,10 +32,6 @@ | |||
32 | 32 | ||
33 | #define DRIVER_NAME "keystone-pcie" | 33 | #define DRIVER_NAME "keystone-pcie" |
34 | 34 | ||
35 | /* driver specific constants */ | ||
36 | #define MAX_MSI_HOST_IRQS 8 | ||
37 | #define MAX_LEGACY_HOST_IRQS 4 | ||
38 | |||
39 | /* DEV_STAT_CTRL */ | 35 | /* DEV_STAT_CTRL */ |
40 | #define PCIE_CAP_BASE 0x70 | 36 | #define PCIE_CAP_BASE 0x70 |
41 | 37 | ||
@@ -173,7 +169,7 @@ static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie, | |||
173 | 169 | ||
174 | if (legacy) { | 170 | if (legacy) { |
175 | np_temp = &ks_pcie->legacy_intc_np; | 171 | np_temp = &ks_pcie->legacy_intc_np; |
176 | max_host_irqs = MAX_LEGACY_HOST_IRQS; | 172 | max_host_irqs = PCI_NUM_INTX; |
177 | host_irqs = &ks_pcie->legacy_host_irqs[0]; | 173 | host_irqs = &ks_pcie->legacy_host_irqs[0]; |
178 | } else { | 174 | } else { |
179 | np_temp = &ks_pcie->msi_intc_np; | 175 | np_temp = &ks_pcie->msi_intc_np; |
@@ -261,7 +257,7 @@ static int keystone_pcie_fault(unsigned long addr, unsigned int fsr, | |||
261 | return 0; | 257 | return 0; |
262 | } | 258 | } |
263 | 259 | ||
264 | static void __init ks_pcie_host_init(struct pcie_port *pp) | 260 | static int __init ks_pcie_host_init(struct pcie_port *pp) |
265 | { | 261 | { |
266 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 262 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
267 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); | 263 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); |
@@ -289,6 +285,8 @@ static void __init ks_pcie_host_init(struct pcie_port *pp) | |||
289 | */ | 285 | */ |
290 | hook_fault_code(17, keystone_pcie_fault, SIGBUS, 0, | 286 | hook_fault_code(17, keystone_pcie_fault, SIGBUS, 0, |
291 | "Asynchronous external abort"); | 287 | "Asynchronous external abort"); |
288 | |||
289 | return 0; | ||
292 | } | 290 | } |
293 | 291 | ||
294 | static const struct dw_pcie_host_ops keystone_pcie_host_ops = { | 292 | static const struct dw_pcie_host_ops keystone_pcie_host_ops = { |
diff --git a/drivers/pci/dwc/pci-keystone.h b/drivers/pci/dwc/pci-keystone.h index 74c5825882df..30b7bc2ac380 100644 --- a/drivers/pci/dwc/pci-keystone.h +++ b/drivers/pci/dwc/pci-keystone.h | |||
@@ -12,9 +12,7 @@ | |||
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #define MAX_LEGACY_IRQS 4 | ||
16 | #define MAX_MSI_HOST_IRQS 8 | 15 | #define MAX_MSI_HOST_IRQS 8 |
17 | #define MAX_LEGACY_HOST_IRQS 4 | ||
18 | 16 | ||
19 | struct keystone_pcie { | 17 | struct keystone_pcie { |
20 | struct dw_pcie *pci; | 18 | struct dw_pcie *pci; |
@@ -22,7 +20,7 @@ struct keystone_pcie { | |||
22 | /* PCI Device ID */ | 20 | /* PCI Device ID */ |
23 | u32 device_id; | 21 | u32 device_id; |
24 | int num_legacy_host_irqs; | 22 | int num_legacy_host_irqs; |
25 | int legacy_host_irqs[MAX_LEGACY_HOST_IRQS]; | 23 | int legacy_host_irqs[PCI_NUM_INTX]; |
26 | struct device_node *legacy_intc_np; | 24 | struct device_node *legacy_intc_np; |
27 | 25 | ||
28 | int num_msi_host_irqs; | 26 | int num_msi_host_irqs; |
diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c index fd861289ad8b..87fa486bee2c 100644 --- a/drivers/pci/dwc/pci-layerscape.c +++ b/drivers/pci/dwc/pci-layerscape.c | |||
@@ -33,7 +33,8 @@ | |||
33 | 33 | ||
34 | /* PEX Internal Configuration Registers */ | 34 | /* PEX Internal Configuration Registers */ |
35 | #define PCIE_STRFMR1 0x71c /* Symbol Timer & Filter Mask Register1 */ | 35 | #define PCIE_STRFMR1 0x71c /* Symbol Timer & Filter Mask Register1 */ |
36 | #define PCIE_DBI_RO_WR_EN 0x8bc /* DBI Read-Only Write Enable Register */ | 36 | |
37 | #define PCIE_IATU_NUM 6 | ||
37 | 38 | ||
38 | struct ls_pcie_drvdata { | 39 | struct ls_pcie_drvdata { |
39 | u32 lut_offset; | 40 | u32 lut_offset; |
@@ -72,14 +73,6 @@ static void ls_pcie_clear_multifunction(struct ls_pcie *pcie) | |||
72 | iowrite8(PCI_HEADER_TYPE_BRIDGE, pci->dbi_base + PCI_HEADER_TYPE); | 73 | iowrite8(PCI_HEADER_TYPE_BRIDGE, pci->dbi_base + PCI_HEADER_TYPE); |
73 | } | 74 | } |
74 | 75 | ||
75 | /* Fix class value */ | ||
76 | static void ls_pcie_fix_class(struct ls_pcie *pcie) | ||
77 | { | ||
78 | struct dw_pcie *pci = pcie->pci; | ||
79 | |||
80 | iowrite16(PCI_CLASS_BRIDGE_PCI, pci->dbi_base + PCI_CLASS_DEVICE); | ||
81 | } | ||
82 | |||
83 | /* Drop MSG TLP except for Vendor MSG */ | 76 | /* Drop MSG TLP except for Vendor MSG */ |
84 | static void ls_pcie_drop_msg_tlp(struct ls_pcie *pcie) | 77 | static void ls_pcie_drop_msg_tlp(struct ls_pcie *pcie) |
85 | { | 78 | { |
@@ -91,6 +84,14 @@ static void ls_pcie_drop_msg_tlp(struct ls_pcie *pcie) | |||
91 | iowrite32(val, pci->dbi_base + PCIE_STRFMR1); | 84 | iowrite32(val, pci->dbi_base + PCIE_STRFMR1); |
92 | } | 85 | } |
93 | 86 | ||
87 | static void ls_pcie_disable_outbound_atus(struct ls_pcie *pcie) | ||
88 | { | ||
89 | int i; | ||
90 | |||
91 | for (i = 0; i < PCIE_IATU_NUM; i++) | ||
92 | dw_pcie_disable_atu(pcie->pci, DW_PCIE_REGION_OUTBOUND, i); | ||
93 | } | ||
94 | |||
94 | static int ls1021_pcie_link_up(struct dw_pcie *pci) | 95 | static int ls1021_pcie_link_up(struct dw_pcie *pci) |
95 | { | 96 | { |
96 | u32 state; | 97 | u32 state; |
@@ -108,33 +109,6 @@ static int ls1021_pcie_link_up(struct dw_pcie *pci) | |||
108 | return 1; | 109 | return 1; |
109 | } | 110 | } |
110 | 111 | ||
111 | static void ls1021_pcie_host_init(struct pcie_port *pp) | ||
112 | { | ||
113 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | ||
114 | struct ls_pcie *pcie = to_ls_pcie(pci); | ||
115 | struct device *dev = pci->dev; | ||
116 | u32 index[2]; | ||
117 | |||
118 | pcie->scfg = syscon_regmap_lookup_by_phandle(dev->of_node, | ||
119 | "fsl,pcie-scfg"); | ||
120 | if (IS_ERR(pcie->scfg)) { | ||
121 | dev_err(dev, "No syscfg phandle specified\n"); | ||
122 | pcie->scfg = NULL; | ||
123 | return; | ||
124 | } | ||
125 | |||
126 | if (of_property_read_u32_array(dev->of_node, | ||
127 | "fsl,pcie-scfg", index, 2)) { | ||
128 | pcie->scfg = NULL; | ||
129 | return; | ||
130 | } | ||
131 | pcie->index = index[1]; | ||
132 | |||
133 | dw_pcie_setup_rc(pp); | ||
134 | |||
135 | ls_pcie_drop_msg_tlp(pcie); | ||
136 | } | ||
137 | |||
138 | static int ls_pcie_link_up(struct dw_pcie *pci) | 112 | static int ls_pcie_link_up(struct dw_pcie *pci) |
139 | { | 113 | { |
140 | struct ls_pcie *pcie = to_ls_pcie(pci); | 114 | struct ls_pcie *pcie = to_ls_pcie(pci); |
@@ -150,16 +124,54 @@ static int ls_pcie_link_up(struct dw_pcie *pci) | |||
150 | return 1; | 124 | return 1; |
151 | } | 125 | } |
152 | 126 | ||
153 | static void ls_pcie_host_init(struct pcie_port *pp) | 127 | static int ls_pcie_host_init(struct pcie_port *pp) |
154 | { | 128 | { |
155 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 129 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
156 | struct ls_pcie *pcie = to_ls_pcie(pci); | 130 | struct ls_pcie *pcie = to_ls_pcie(pci); |
157 | 131 | ||
158 | iowrite32(1, pci->dbi_base + PCIE_DBI_RO_WR_EN); | 132 | /* |
159 | ls_pcie_fix_class(pcie); | 133 | * Disable outbound windows configured by the bootloader to avoid |
134 | * one transaction hitting multiple outbound windows. | ||
135 | * dw_pcie_setup_rc() will reconfigure the outbound windows. | ||
136 | */ | ||
137 | ls_pcie_disable_outbound_atus(pcie); | ||
138 | |||
139 | dw_pcie_dbi_ro_wr_en(pci); | ||
160 | ls_pcie_clear_multifunction(pcie); | 140 | ls_pcie_clear_multifunction(pcie); |
141 | dw_pcie_dbi_ro_wr_dis(pci); | ||
142 | |||
161 | ls_pcie_drop_msg_tlp(pcie); | 143 | ls_pcie_drop_msg_tlp(pcie); |
162 | iowrite32(0, pci->dbi_base + PCIE_DBI_RO_WR_EN); | 144 | |
145 | dw_pcie_setup_rc(pp); | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static int ls1021_pcie_host_init(struct pcie_port *pp) | ||
151 | { | ||
152 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | ||
153 | struct ls_pcie *pcie = to_ls_pcie(pci); | ||
154 | struct device *dev = pci->dev; | ||
155 | u32 index[2]; | ||
156 | int ret; | ||
157 | |||
158 | pcie->scfg = syscon_regmap_lookup_by_phandle(dev->of_node, | ||
159 | "fsl,pcie-scfg"); | ||
160 | if (IS_ERR(pcie->scfg)) { | ||
161 | ret = PTR_ERR(pcie->scfg); | ||
162 | dev_err(dev, "No syscfg phandle specified\n"); | ||
163 | pcie->scfg = NULL; | ||
164 | return ret; | ||
165 | } | ||
166 | |||
167 | if (of_property_read_u32_array(dev->of_node, | ||
168 | "fsl,pcie-scfg", index, 2)) { | ||
169 | pcie->scfg = NULL; | ||
170 | return -EINVAL; | ||
171 | } | ||
172 | pcie->index = index[1]; | ||
173 | |||
174 | return ls_pcie_host_init(pp); | ||
163 | } | 175 | } |
164 | 176 | ||
165 | static int ls_pcie_msi_host_init(struct pcie_port *pp, | 177 | static int ls_pcie_msi_host_init(struct pcie_port *pp, |
@@ -232,12 +244,22 @@ static struct ls_pcie_drvdata ls2080_drvdata = { | |||
232 | .dw_pcie_ops = &dw_ls_pcie_ops, | 244 | .dw_pcie_ops = &dw_ls_pcie_ops, |
233 | }; | 245 | }; |
234 | 246 | ||
247 | static struct ls_pcie_drvdata ls2088_drvdata = { | ||
248 | .lut_offset = 0x80000, | ||
249 | .ltssm_shift = 0, | ||
250 | .lut_dbg = 0x407fc, | ||
251 | .ops = &ls_pcie_host_ops, | ||
252 | .dw_pcie_ops = &dw_ls_pcie_ops, | ||
253 | }; | ||
254 | |||
235 | static const struct of_device_id ls_pcie_of_match[] = { | 255 | static const struct of_device_id ls_pcie_of_match[] = { |
236 | { .compatible = "fsl,ls1021a-pcie", .data = &ls1021_drvdata }, | 256 | { .compatible = "fsl,ls1021a-pcie", .data = &ls1021_drvdata }, |
237 | { .compatible = "fsl,ls1043a-pcie", .data = &ls1043_drvdata }, | 257 | { .compatible = "fsl,ls1043a-pcie", .data = &ls1043_drvdata }, |
238 | { .compatible = "fsl,ls1046a-pcie", .data = &ls1046_drvdata }, | 258 | { .compatible = "fsl,ls1046a-pcie", .data = &ls1046_drvdata }, |
239 | { .compatible = "fsl,ls2080a-pcie", .data = &ls2080_drvdata }, | 259 | { .compatible = "fsl,ls2080a-pcie", .data = &ls2080_drvdata }, |
240 | { .compatible = "fsl,ls2085a-pcie", .data = &ls2080_drvdata }, | 260 | { .compatible = "fsl,ls2085a-pcie", .data = &ls2080_drvdata }, |
261 | { .compatible = "fsl,ls2088a-pcie", .data = &ls2088_drvdata }, | ||
262 | { .compatible = "fsl,ls1088a-pcie", .data = &ls2088_drvdata }, | ||
241 | { }, | 263 | { }, |
242 | }; | 264 | }; |
243 | 265 | ||
diff --git a/drivers/pci/dwc/pcie-armada8k.c b/drivers/pci/dwc/pcie-armada8k.c index ea8f34af6a85..370d057c0046 100644 --- a/drivers/pci/dwc/pcie-armada8k.c +++ b/drivers/pci/dwc/pcie-armada8k.c | |||
@@ -134,13 +134,15 @@ static void armada8k_pcie_establish_link(struct armada8k_pcie *pcie) | |||
134 | dev_err(pci->dev, "Link not up after reconfiguration\n"); | 134 | dev_err(pci->dev, "Link not up after reconfiguration\n"); |
135 | } | 135 | } |
136 | 136 | ||
137 | static void armada8k_pcie_host_init(struct pcie_port *pp) | 137 | static int armada8k_pcie_host_init(struct pcie_port *pp) |
138 | { | 138 | { |
139 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 139 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
140 | struct armada8k_pcie *pcie = to_armada8k_pcie(pci); | 140 | struct armada8k_pcie *pcie = to_armada8k_pcie(pci); |
141 | 141 | ||
142 | dw_pcie_setup_rc(pp); | 142 | dw_pcie_setup_rc(pp); |
143 | armada8k_pcie_establish_link(pcie); | 143 | armada8k_pcie_establish_link(pcie); |
144 | |||
145 | return 0; | ||
144 | } | 146 | } |
145 | 147 | ||
146 | static irqreturn_t armada8k_pcie_irq_handler(int irq, void *arg) | 148 | static irqreturn_t armada8k_pcie_irq_handler(int irq, void *arg) |
@@ -176,9 +178,9 @@ static int armada8k_add_pcie_port(struct armada8k_pcie *pcie, | |||
176 | pp->ops = &armada8k_pcie_host_ops; | 178 | pp->ops = &armada8k_pcie_host_ops; |
177 | 179 | ||
178 | pp->irq = platform_get_irq(pdev, 0); | 180 | pp->irq = platform_get_irq(pdev, 0); |
179 | if (!pp->irq) { | 181 | if (pp->irq < 0) { |
180 | dev_err(dev, "failed to get irq for port\n"); | 182 | dev_err(dev, "failed to get irq for port\n"); |
181 | return -ENODEV; | 183 | return pp->irq; |
182 | } | 184 | } |
183 | 185 | ||
184 | ret = devm_request_irq(dev, pp->irq, armada8k_pcie_irq_handler, | 186 | ret = devm_request_irq(dev, pp->irq, armada8k_pcie_irq_handler, |
@@ -226,7 +228,9 @@ static int armada8k_pcie_probe(struct platform_device *pdev) | |||
226 | if (IS_ERR(pcie->clk)) | 228 | if (IS_ERR(pcie->clk)) |
227 | return PTR_ERR(pcie->clk); | 229 | return PTR_ERR(pcie->clk); |
228 | 230 | ||
229 | clk_prepare_enable(pcie->clk); | 231 | ret = clk_prepare_enable(pcie->clk); |
232 | if (ret) | ||
233 | return ret; | ||
230 | 234 | ||
231 | /* Get the dw-pcie unit configuration/control registers base. */ | 235 | /* Get the dw-pcie unit configuration/control registers base. */ |
232 | base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl"); | 236 | base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl"); |
diff --git a/drivers/pci/dwc/pcie-artpec6.c b/drivers/pci/dwc/pcie-artpec6.c index 01c6f7823672..6653619db6a1 100644 --- a/drivers/pci/dwc/pcie-artpec6.c +++ b/drivers/pci/dwc/pcie-artpec6.c | |||
@@ -141,12 +141,6 @@ static int artpec6_pcie_establish_link(struct artpec6_pcie *artpec6_pcie) | |||
141 | artpec6_pcie_writel(artpec6_pcie, PCIECFG, val); | 141 | artpec6_pcie_writel(artpec6_pcie, PCIECFG, val); |
142 | usleep_range(100, 200); | 142 | usleep_range(100, 200); |
143 | 143 | ||
144 | /* | ||
145 | * Enable writing to config regs. This is required as the Synopsys | ||
146 | * driver changes the class code. That register needs DBI write enable. | ||
147 | */ | ||
148 | dw_pcie_writel_dbi(pci, MISC_CONTROL_1_OFF, DBI_RO_WR_EN); | ||
149 | |||
150 | /* setup root complex */ | 144 | /* setup root complex */ |
151 | dw_pcie_setup_rc(pp); | 145 | dw_pcie_setup_rc(pp); |
152 | 146 | ||
@@ -175,13 +169,15 @@ static void artpec6_pcie_enable_interrupts(struct artpec6_pcie *artpec6_pcie) | |||
175 | dw_pcie_msi_init(pp); | 169 | dw_pcie_msi_init(pp); |
176 | } | 170 | } |
177 | 171 | ||
178 | static void artpec6_pcie_host_init(struct pcie_port *pp) | 172 | static int artpec6_pcie_host_init(struct pcie_port *pp) |
179 | { | 173 | { |
180 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 174 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
181 | struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci); | 175 | struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci); |
182 | 176 | ||
183 | artpec6_pcie_establish_link(artpec6_pcie); | 177 | artpec6_pcie_establish_link(artpec6_pcie); |
184 | artpec6_pcie_enable_interrupts(artpec6_pcie); | 178 | artpec6_pcie_enable_interrupts(artpec6_pcie); |
179 | |||
180 | return 0; | ||
185 | } | 181 | } |
186 | 182 | ||
187 | static const struct dw_pcie_host_ops artpec6_pcie_host_ops = { | 183 | static const struct dw_pcie_host_ops artpec6_pcie_host_ops = { |
@@ -207,9 +203,9 @@ static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie, | |||
207 | 203 | ||
208 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | 204 | if (IS_ENABLED(CONFIG_PCI_MSI)) { |
209 | pp->msi_irq = platform_get_irq_byname(pdev, "msi"); | 205 | pp->msi_irq = platform_get_irq_byname(pdev, "msi"); |
210 | if (pp->msi_irq <= 0) { | 206 | if (pp->msi_irq < 0) { |
211 | dev_err(dev, "failed to get MSI irq\n"); | 207 | dev_err(dev, "failed to get MSI irq\n"); |
212 | return -ENODEV; | 208 | return pp->msi_irq; |
213 | } | 209 | } |
214 | 210 | ||
215 | ret = devm_request_irq(dev, pp->msi_irq, | 211 | ret = devm_request_irq(dev, pp->msi_irq, |
diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-designware-ep.c index 398406393f37..d53d5f168363 100644 --- a/drivers/pci/dwc/pcie-designware-ep.c +++ b/drivers/pci/dwc/pcie-designware-ep.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * Synopsys Designware PCIe Endpoint controller driver | 2 | * Synopsys DesignWare PCIe Endpoint controller driver |
3 | * | 3 | * |
4 | * Copyright (C) 2017 Texas Instruments | 4 | * Copyright (C) 2017 Texas Instruments |
5 | * Author: Kishon Vijay Abraham I <kishon@ti.com> | 5 | * Author: Kishon Vijay Abraham I <kishon@ti.com> |
@@ -283,7 +283,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) | |||
283 | { | 283 | { |
284 | int ret; | 284 | int ret; |
285 | void *addr; | 285 | void *addr; |
286 | enum pci_barno bar; | ||
287 | struct pci_epc *epc; | 286 | struct pci_epc *epc; |
288 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); | 287 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); |
289 | struct device *dev = pci->dev; | 288 | struct device *dev = pci->dev; |
@@ -312,9 +311,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) | |||
312 | return -ENOMEM; | 311 | return -ENOMEM; |
313 | ep->outbound_addr = addr; | 312 | ep->outbound_addr = addr; |
314 | 313 | ||
315 | for (bar = BAR_0; bar <= BAR_5; bar++) | ||
316 | dw_pcie_ep_reset_bar(pci, bar); | ||
317 | |||
318 | if (ep->ops->ep_init) | 314 | if (ep->ops->ep_init) |
319 | ep->ops->ep_init(ep); | 315 | ep->ops->ep_init(ep); |
320 | 316 | ||
@@ -328,7 +324,8 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) | |||
328 | if (ret < 0) | 324 | if (ret < 0) |
329 | epc->max_functions = 1; | 325 | epc->max_functions = 1; |
330 | 326 | ||
331 | ret = pci_epc_mem_init(epc, ep->phys_base, ep->addr_size); | 327 | ret = __pci_epc_mem_init(epc, ep->phys_base, ep->addr_size, |
328 | ep->page_size); | ||
332 | if (ret < 0) { | 329 | if (ret < 0) { |
333 | dev_err(dev, "Failed to initialize address space\n"); | 330 | dev_err(dev, "Failed to initialize address space\n"); |
334 | return ret; | 331 | return ret; |
diff --git a/drivers/pci/dwc/pcie-designware-host.c b/drivers/pci/dwc/pcie-designware-host.c index d29c020da082..81e2157a7cfb 100644 --- a/drivers/pci/dwc/pcie-designware-host.c +++ b/drivers/pci/dwc/pcie-designware-host.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Synopsys Designware PCIe host controller driver | 2 | * Synopsys DesignWare PCIe host controller driver |
3 | * | 3 | * |
4 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. |
5 | * http://www.samsung.com | 5 | * http://www.samsung.com |
@@ -71,9 +71,9 @@ irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) | |||
71 | while ((pos = find_next_bit((unsigned long *) &val, 32, | 71 | while ((pos = find_next_bit((unsigned long *) &val, 32, |
72 | pos)) != 32) { | 72 | pos)) != 32) { |
73 | irq = irq_find_mapping(pp->irq_domain, i * 32 + pos); | 73 | irq = irq_find_mapping(pp->irq_domain, i * 32 + pos); |
74 | generic_handle_irq(irq); | ||
74 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + i * 12, | 75 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + i * 12, |
75 | 4, 1 << pos); | 76 | 4, 1 << pos); |
76 | generic_handle_irq(irq); | ||
77 | pos++; | 77 | pos++; |
78 | } | 78 | } |
79 | } | 79 | } |
@@ -401,8 +401,11 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
401 | } | 401 | } |
402 | } | 402 | } |
403 | 403 | ||
404 | if (pp->ops->host_init) | 404 | if (pp->ops->host_init) { |
405 | pp->ops->host_init(pp); | 405 | ret = pp->ops->host_init(pp); |
406 | if (ret) | ||
407 | goto error; | ||
408 | } | ||
406 | 409 | ||
407 | pp->root_bus_nr = pp->busn->start; | 410 | pp->root_bus_nr = pp->busn->start; |
408 | 411 | ||
@@ -594,10 +597,12 @@ void dw_pcie_setup_rc(struct pcie_port *pp) | |||
594 | dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_1, 0x00000000); | 597 | dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_1, 0x00000000); |
595 | 598 | ||
596 | /* setup interrupt pins */ | 599 | /* setup interrupt pins */ |
600 | dw_pcie_dbi_ro_wr_en(pci); | ||
597 | val = dw_pcie_readl_dbi(pci, PCI_INTERRUPT_LINE); | 601 | val = dw_pcie_readl_dbi(pci, PCI_INTERRUPT_LINE); |
598 | val &= 0xffff00ff; | 602 | val &= 0xffff00ff; |
599 | val |= 0x00000100; | 603 | val |= 0x00000100; |
600 | dw_pcie_writel_dbi(pci, PCI_INTERRUPT_LINE, val); | 604 | dw_pcie_writel_dbi(pci, PCI_INTERRUPT_LINE, val); |
605 | dw_pcie_dbi_ro_wr_dis(pci); | ||
601 | 606 | ||
602 | /* setup bus numbers */ | 607 | /* setup bus numbers */ |
603 | val = dw_pcie_readl_dbi(pci, PCI_PRIMARY_BUS); | 608 | val = dw_pcie_readl_dbi(pci, PCI_PRIMARY_BUS); |
@@ -634,8 +639,12 @@ void dw_pcie_setup_rc(struct pcie_port *pp) | |||
634 | 639 | ||
635 | dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); | 640 | dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); |
636 | 641 | ||
642 | /* Enable write permission for the DBI read-only register */ | ||
643 | dw_pcie_dbi_ro_wr_en(pci); | ||
637 | /* program correct class for RC */ | 644 | /* program correct class for RC */ |
638 | dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI); | 645 | dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI); |
646 | /* Better disable write permission right after the update */ | ||
647 | dw_pcie_dbi_ro_wr_dis(pci); | ||
639 | 648 | ||
640 | dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val); | 649 | dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val); |
641 | val |= PORT_LOGIC_SPEED_CHANGE; | 650 | val |= PORT_LOGIC_SPEED_CHANGE; |
diff --git a/drivers/pci/dwc/pcie-designware-plat.c b/drivers/pci/dwc/pcie-designware-plat.c index 091b4e7ad059..168e2380f493 100644 --- a/drivers/pci/dwc/pcie-designware-plat.c +++ b/drivers/pci/dwc/pcie-designware-plat.c | |||
@@ -35,7 +35,7 @@ static irqreturn_t dw_plat_pcie_msi_irq_handler(int irq, void *arg) | |||
35 | return dw_handle_msi_irq(pp); | 35 | return dw_handle_msi_irq(pp); |
36 | } | 36 | } |
37 | 37 | ||
38 | static void dw_plat_pcie_host_init(struct pcie_port *pp) | 38 | static int dw_plat_pcie_host_init(struct pcie_port *pp) |
39 | { | 39 | { |
40 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 40 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
41 | 41 | ||
@@ -44,6 +44,8 @@ static void dw_plat_pcie_host_init(struct pcie_port *pp) | |||
44 | 44 | ||
45 | if (IS_ENABLED(CONFIG_PCI_MSI)) | 45 | if (IS_ENABLED(CONFIG_PCI_MSI)) |
46 | dw_pcie_msi_init(pp); | 46 | dw_pcie_msi_init(pp); |
47 | |||
48 | return 0; | ||
47 | } | 49 | } |
48 | 50 | ||
49 | static const struct dw_pcie_host_ops dw_plat_pcie_host_ops = { | 51 | static const struct dw_pcie_host_ops dw_plat_pcie_host_ops = { |
diff --git a/drivers/pci/dwc/pcie-designware.c b/drivers/pci/dwc/pcie-designware.c index 0e03af279259..88abdddee2ad 100644 --- a/drivers/pci/dwc/pcie-designware.c +++ b/drivers/pci/dwc/pcie-designware.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Synopsys Designware PCIe host controller driver | 2 | * Synopsys DesignWare PCIe host controller driver |
3 | * | 3 | * |
4 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. |
5 | * http://www.samsung.com | 5 | * http://www.samsung.com |
@@ -107,8 +107,9 @@ static void dw_pcie_writel_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg, | |||
107 | dw_pcie_writel_dbi(pci, offset + reg, val); | 107 | dw_pcie_writel_dbi(pci, offset + reg, val); |
108 | } | 108 | } |
109 | 109 | ||
110 | void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index, int type, | 110 | static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index, |
111 | u64 cpu_addr, u64 pci_addr, u32 size) | 111 | int type, u64 cpu_addr, |
112 | u64 pci_addr, u32 size) | ||
112 | { | 113 | { |
113 | u32 retries, val; | 114 | u32 retries, val; |
114 | 115 | ||
@@ -177,7 +178,7 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type, | |||
177 | */ | 178 | */ |
178 | for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) { | 179 | for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) { |
179 | val = dw_pcie_readl_dbi(pci, PCIE_ATU_CR2); | 180 | val = dw_pcie_readl_dbi(pci, PCIE_ATU_CR2); |
180 | if (val == PCIE_ATU_ENABLE) | 181 | if (val & PCIE_ATU_ENABLE) |
181 | return; | 182 | return; |
182 | 183 | ||
183 | usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX); | 184 | usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX); |
@@ -200,8 +201,9 @@ static void dw_pcie_writel_ib_unroll(struct dw_pcie *pci, u32 index, u32 reg, | |||
200 | dw_pcie_writel_dbi(pci, offset + reg, val); | 201 | dw_pcie_writel_dbi(pci, offset + reg, val); |
201 | } | 202 | } |
202 | 203 | ||
203 | int dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, int index, int bar, | 204 | static int dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, int index, |
204 | u64 cpu_addr, enum dw_pcie_as_type as_type) | 205 | int bar, u64 cpu_addr, |
206 | enum dw_pcie_as_type as_type) | ||
205 | { | 207 | { |
206 | int type; | 208 | int type; |
207 | u32 retries, val; | 209 | u32 retries, val; |
diff --git a/drivers/pci/dwc/pcie-designware.h b/drivers/pci/dwc/pcie-designware.h index b4d2a89f8e58..e5d9d77b778e 100644 --- a/drivers/pci/dwc/pcie-designware.h +++ b/drivers/pci/dwc/pcie-designware.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Synopsys Designware PCIe host controller driver | 2 | * Synopsys DesignWare PCIe host controller driver |
3 | * | 3 | * |
4 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. |
5 | * http://www.samsung.com | 5 | * http://www.samsung.com |
@@ -76,6 +76,9 @@ | |||
76 | #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) | 76 | #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) |
77 | #define PCIE_ATU_UPPER_TARGET 0x91C | 77 | #define PCIE_ATU_UPPER_TARGET 0x91C |
78 | 78 | ||
79 | #define PCIE_MISC_CONTROL_1_OFF 0x8BC | ||
80 | #define PCIE_DBI_RO_WR_EN (0x1 << 0) | ||
81 | |||
79 | /* | 82 | /* |
80 | * iATU Unroll-specific register definitions | 83 | * iATU Unroll-specific register definitions |
81 | * From 4.80 core version the address translation will be made by unroll | 84 | * From 4.80 core version the address translation will be made by unroll |
@@ -134,7 +137,7 @@ struct dw_pcie_host_ops { | |||
134 | unsigned int devfn, int where, int size, u32 *val); | 137 | unsigned int devfn, int where, int size, u32 *val); |
135 | int (*wr_other_conf)(struct pcie_port *pp, struct pci_bus *bus, | 138 | int (*wr_other_conf)(struct pcie_port *pp, struct pci_bus *bus, |
136 | unsigned int devfn, int where, int size, u32 val); | 139 | unsigned int devfn, int where, int size, u32 val); |
137 | void (*host_init)(struct pcie_port *pp); | 140 | int (*host_init)(struct pcie_port *pp); |
138 | void (*msi_set_irq)(struct pcie_port *pp, int irq); | 141 | void (*msi_set_irq)(struct pcie_port *pp, int irq); |
139 | void (*msi_clear_irq)(struct pcie_port *pp, int irq); | 142 | void (*msi_clear_irq)(struct pcie_port *pp, int irq); |
140 | phys_addr_t (*get_msi_addr)(struct pcie_port *pp); | 143 | phys_addr_t (*get_msi_addr)(struct pcie_port *pp); |
@@ -186,6 +189,7 @@ struct dw_pcie_ep { | |||
186 | struct dw_pcie_ep_ops *ops; | 189 | struct dw_pcie_ep_ops *ops; |
187 | phys_addr_t phys_base; | 190 | phys_addr_t phys_base; |
188 | size_t addr_size; | 191 | size_t addr_size; |
192 | size_t page_size; | ||
189 | u8 bar_to_atu[6]; | 193 | u8 bar_to_atu[6]; |
190 | phys_addr_t *outbound_addr; | 194 | phys_addr_t *outbound_addr; |
191 | unsigned long ib_window_map; | 195 | unsigned long ib_window_map; |
@@ -279,6 +283,28 @@ static inline u32 dw_pcie_readl_dbi2(struct dw_pcie *pci, u32 reg) | |||
279 | return __dw_pcie_read_dbi(pci, pci->dbi_base2, reg, 0x4); | 283 | return __dw_pcie_read_dbi(pci, pci->dbi_base2, reg, 0x4); |
280 | } | 284 | } |
281 | 285 | ||
286 | static inline void dw_pcie_dbi_ro_wr_en(struct dw_pcie *pci) | ||
287 | { | ||
288 | u32 reg; | ||
289 | u32 val; | ||
290 | |||
291 | reg = PCIE_MISC_CONTROL_1_OFF; | ||
292 | val = dw_pcie_readl_dbi(pci, reg); | ||
293 | val |= PCIE_DBI_RO_WR_EN; | ||
294 | dw_pcie_writel_dbi(pci, reg, val); | ||
295 | } | ||
296 | |||
297 | static inline void dw_pcie_dbi_ro_wr_dis(struct dw_pcie *pci) | ||
298 | { | ||
299 | u32 reg; | ||
300 | u32 val; | ||
301 | |||
302 | reg = PCIE_MISC_CONTROL_1_OFF; | ||
303 | val = dw_pcie_readl_dbi(pci, reg); | ||
304 | val &= ~PCIE_DBI_RO_WR_EN; | ||
305 | dw_pcie_writel_dbi(pci, reg, val); | ||
306 | } | ||
307 | |||
282 | #ifdef CONFIG_PCIE_DW_HOST | 308 | #ifdef CONFIG_PCIE_DW_HOST |
283 | irqreturn_t dw_handle_msi_irq(struct pcie_port *pp); | 309 | irqreturn_t dw_handle_msi_irq(struct pcie_port *pp); |
284 | void dw_pcie_msi_init(struct pcie_port *pp); | 310 | void dw_pcie_msi_init(struct pcie_port *pp); |
diff --git a/drivers/pci/dwc/pcie-hisi.c b/drivers/pci/dwc/pcie-hisi.c index e51acee0ddf3..a20179169e06 100644 --- a/drivers/pci/dwc/pcie-hisi.c +++ b/drivers/pci/dwc/pcie-hisi.c | |||
@@ -223,7 +223,7 @@ static int hisi_pcie_link_up(struct dw_pcie *pci) | |||
223 | return hisi_pcie->soc_ops->hisi_pcie_link_up(hisi_pcie); | 223 | return hisi_pcie->soc_ops->hisi_pcie_link_up(hisi_pcie); |
224 | } | 224 | } |
225 | 225 | ||
226 | static struct dw_pcie_host_ops hisi_pcie_host_ops = { | 226 | static const struct dw_pcie_host_ops hisi_pcie_host_ops = { |
227 | .rd_own_conf = hisi_pcie_cfg_read, | 227 | .rd_own_conf = hisi_pcie_cfg_read, |
228 | .wr_own_conf = hisi_pcie_cfg_write, | 228 | .wr_own_conf = hisi_pcie_cfg_write, |
229 | }; | 229 | }; |
@@ -268,7 +268,6 @@ static int hisi_pcie_probe(struct platform_device *pdev) | |||
268 | struct dw_pcie *pci; | 268 | struct dw_pcie *pci; |
269 | struct hisi_pcie *hisi_pcie; | 269 | struct hisi_pcie *hisi_pcie; |
270 | struct resource *reg; | 270 | struct resource *reg; |
271 | struct device_driver *driver; | ||
272 | int ret; | 271 | int ret; |
273 | 272 | ||
274 | hisi_pcie = devm_kzalloc(dev, sizeof(*hisi_pcie), GFP_KERNEL); | 273 | hisi_pcie = devm_kzalloc(dev, sizeof(*hisi_pcie), GFP_KERNEL); |
@@ -282,8 +281,6 @@ static int hisi_pcie_probe(struct platform_device *pdev) | |||
282 | pci->dev = dev; | 281 | pci->dev = dev; |
283 | pci->ops = &dw_pcie_ops; | 282 | pci->ops = &dw_pcie_ops; |
284 | 283 | ||
285 | driver = dev->driver; | ||
286 | |||
287 | hisi_pcie->pci = pci; | 284 | hisi_pcie->pci = pci; |
288 | 285 | ||
289 | hisi_pcie->soc_ops = of_device_get_match_data(dev); | 286 | hisi_pcie->soc_ops = of_device_get_match_data(dev); |
diff --git a/drivers/pci/dwc/pcie-kirin.c b/drivers/pci/dwc/pcie-kirin.c index 33fddb9f6739..dc3033cf3c19 100644 --- a/drivers/pci/dwc/pcie-kirin.c +++ b/drivers/pci/dwc/pcie-kirin.c | |||
@@ -430,9 +430,11 @@ static int kirin_pcie_establish_link(struct pcie_port *pp) | |||
430 | return 0; | 430 | return 0; |
431 | } | 431 | } |
432 | 432 | ||
433 | static void kirin_pcie_host_init(struct pcie_port *pp) | 433 | static int kirin_pcie_host_init(struct pcie_port *pp) |
434 | { | 434 | { |
435 | kirin_pcie_establish_link(pp); | 435 | kirin_pcie_establish_link(pp); |
436 | |||
437 | return 0; | ||
436 | } | 438 | } |
437 | 439 | ||
438 | static struct dw_pcie_ops kirin_dw_pcie_ops = { | 440 | static struct dw_pcie_ops kirin_dw_pcie_ops = { |
@@ -441,7 +443,7 @@ static struct dw_pcie_ops kirin_dw_pcie_ops = { | |||
441 | .link_up = kirin_pcie_link_up, | 443 | .link_up = kirin_pcie_link_up, |
442 | }; | 444 | }; |
443 | 445 | ||
444 | static struct dw_pcie_host_ops kirin_pcie_host_ops = { | 446 | static const struct dw_pcie_host_ops kirin_pcie_host_ops = { |
445 | .rd_own_conf = kirin_pcie_rd_own_conf, | 447 | .rd_own_conf = kirin_pcie_rd_own_conf, |
446 | .wr_own_conf = kirin_pcie_wr_own_conf, | 448 | .wr_own_conf = kirin_pcie_wr_own_conf, |
447 | .host_init = kirin_pcie_host_init, | 449 | .host_init = kirin_pcie_host_init, |
diff --git a/drivers/pci/dwc/pcie-qcom.c b/drivers/pci/dwc/pcie-qcom.c index 68c5f2ab5bc8..ce7ba5b7552a 100644 --- a/drivers/pci/dwc/pcie-qcom.c +++ b/drivers/pci/dwc/pcie-qcom.c | |||
@@ -37,6 +37,20 @@ | |||
37 | #include "pcie-designware.h" | 37 | #include "pcie-designware.h" |
38 | 38 | ||
39 | #define PCIE20_PARF_SYS_CTRL 0x00 | 39 | #define PCIE20_PARF_SYS_CTRL 0x00 |
40 | #define MST_WAKEUP_EN BIT(13) | ||
41 | #define SLV_WAKEUP_EN BIT(12) | ||
42 | #define MSTR_ACLK_CGC_DIS BIT(10) | ||
43 | #define SLV_ACLK_CGC_DIS BIT(9) | ||
44 | #define CORE_CLK_CGC_DIS BIT(6) | ||
45 | #define AUX_PWR_DET BIT(4) | ||
46 | #define L23_CLK_RMV_DIS BIT(2) | ||
47 | #define L1_CLK_RMV_DIS BIT(1) | ||
48 | |||
49 | #define PCIE20_COMMAND_STATUS 0x04 | ||
50 | #define CMD_BME_VAL 0x4 | ||
51 | #define PCIE20_DEVICE_CONTROL2_STATUS2 0x98 | ||
52 | #define PCIE_CAP_CPL_TIMEOUT_DISABLE 0x10 | ||
53 | |||
40 | #define PCIE20_PARF_PHY_CTRL 0x40 | 54 | #define PCIE20_PARF_PHY_CTRL 0x40 |
41 | #define PCIE20_PARF_PHY_REFCLK 0x4C | 55 | #define PCIE20_PARF_PHY_REFCLK 0x4C |
42 | #define PCIE20_PARF_DBI_BASE_ADDR 0x168 | 56 | #define PCIE20_PARF_DBI_BASE_ADDR 0x168 |
@@ -58,10 +72,22 @@ | |||
58 | #define CFG_BRIDGE_SB_INIT BIT(0) | 72 | #define CFG_BRIDGE_SB_INIT BIT(0) |
59 | 73 | ||
60 | #define PCIE20_CAP 0x70 | 74 | #define PCIE20_CAP 0x70 |
75 | #define PCIE20_CAP_LINK_CAPABILITIES (PCIE20_CAP + 0xC) | ||
76 | #define PCIE20_CAP_ACTIVE_STATE_LINK_PM_SUPPORT (BIT(10) | BIT(11)) | ||
77 | #define PCIE20_CAP_LINK_1 (PCIE20_CAP + 0x14) | ||
78 | #define PCIE_CAP_LINK1_VAL 0x2FD7F | ||
79 | |||
80 | #define PCIE20_PARF_Q2A_FLUSH 0x1AC | ||
81 | |||
82 | #define PCIE20_MISC_CONTROL_1_REG 0x8BC | ||
83 | #define DBI_RO_WR_EN 1 | ||
61 | 84 | ||
62 | #define PERST_DELAY_US 1000 | 85 | #define PERST_DELAY_US 1000 |
63 | 86 | ||
64 | struct qcom_pcie_resources_v0 { | 87 | #define PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE 0x358 |
88 | #define SLV_ADDR_SPACE_SZ 0x10000000 | ||
89 | |||
90 | struct qcom_pcie_resources_2_1_0 { | ||
65 | struct clk *iface_clk; | 91 | struct clk *iface_clk; |
66 | struct clk *core_clk; | 92 | struct clk *core_clk; |
67 | struct clk *phy_clk; | 93 | struct clk *phy_clk; |
@@ -75,7 +101,7 @@ struct qcom_pcie_resources_v0 { | |||
75 | struct regulator *vdda_refclk; | 101 | struct regulator *vdda_refclk; |
76 | }; | 102 | }; |
77 | 103 | ||
78 | struct qcom_pcie_resources_v1 { | 104 | struct qcom_pcie_resources_1_0_0 { |
79 | struct clk *iface; | 105 | struct clk *iface; |
80 | struct clk *aux; | 106 | struct clk *aux; |
81 | struct clk *master_bus; | 107 | struct clk *master_bus; |
@@ -84,7 +110,7 @@ struct qcom_pcie_resources_v1 { | |||
84 | struct regulator *vdda; | 110 | struct regulator *vdda; |
85 | }; | 111 | }; |
86 | 112 | ||
87 | struct qcom_pcie_resources_v2 { | 113 | struct qcom_pcie_resources_2_3_2 { |
88 | struct clk *aux_clk; | 114 | struct clk *aux_clk; |
89 | struct clk *master_clk; | 115 | struct clk *master_clk; |
90 | struct clk *slave_clk; | 116 | struct clk *slave_clk; |
@@ -92,7 +118,7 @@ struct qcom_pcie_resources_v2 { | |||
92 | struct clk *pipe_clk; | 118 | struct clk *pipe_clk; |
93 | }; | 119 | }; |
94 | 120 | ||
95 | struct qcom_pcie_resources_v3 { | 121 | struct qcom_pcie_resources_2_4_0 { |
96 | struct clk *aux_clk; | 122 | struct clk *aux_clk; |
97 | struct clk *master_clk; | 123 | struct clk *master_clk; |
98 | struct clk *slave_clk; | 124 | struct clk *slave_clk; |
@@ -110,11 +136,21 @@ struct qcom_pcie_resources_v3 { | |||
110 | struct reset_control *phy_ahb_reset; | 136 | struct reset_control *phy_ahb_reset; |
111 | }; | 137 | }; |
112 | 138 | ||
139 | struct qcom_pcie_resources_2_3_3 { | ||
140 | struct clk *iface; | ||
141 | struct clk *axi_m_clk; | ||
142 | struct clk *axi_s_clk; | ||
143 | struct clk *ahb_clk; | ||
144 | struct clk *aux_clk; | ||
145 | struct reset_control *rst[7]; | ||
146 | }; | ||
147 | |||
113 | union qcom_pcie_resources { | 148 | union qcom_pcie_resources { |
114 | struct qcom_pcie_resources_v0 v0; | 149 | struct qcom_pcie_resources_1_0_0 v1_0_0; |
115 | struct qcom_pcie_resources_v1 v1; | 150 | struct qcom_pcie_resources_2_1_0 v2_1_0; |
116 | struct qcom_pcie_resources_v2 v2; | 151 | struct qcom_pcie_resources_2_3_2 v2_3_2; |
117 | struct qcom_pcie_resources_v3 v3; | 152 | struct qcom_pcie_resources_2_3_3 v2_3_3; |
153 | struct qcom_pcie_resources_2_4_0 v2_4_0; | ||
118 | }; | 154 | }; |
119 | 155 | ||
120 | struct qcom_pcie; | 156 | struct qcom_pcie; |
@@ -124,6 +160,7 @@ struct qcom_pcie_ops { | |||
124 | int (*init)(struct qcom_pcie *pcie); | 160 | int (*init)(struct qcom_pcie *pcie); |
125 | int (*post_init)(struct qcom_pcie *pcie); | 161 | int (*post_init)(struct qcom_pcie *pcie); |
126 | void (*deinit)(struct qcom_pcie *pcie); | 162 | void (*deinit)(struct qcom_pcie *pcie); |
163 | void (*post_deinit)(struct qcom_pcie *pcie); | ||
127 | void (*ltssm_enable)(struct qcom_pcie *pcie); | 164 | void (*ltssm_enable)(struct qcom_pcie *pcie); |
128 | }; | 165 | }; |
129 | 166 | ||
@@ -141,13 +178,13 @@ struct qcom_pcie { | |||
141 | 178 | ||
142 | static void qcom_ep_reset_assert(struct qcom_pcie *pcie) | 179 | static void qcom_ep_reset_assert(struct qcom_pcie *pcie) |
143 | { | 180 | { |
144 | gpiod_set_value(pcie->reset, 1); | 181 | gpiod_set_value_cansleep(pcie->reset, 1); |
145 | usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500); | 182 | usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500); |
146 | } | 183 | } |
147 | 184 | ||
148 | static void qcom_ep_reset_deassert(struct qcom_pcie *pcie) | 185 | static void qcom_ep_reset_deassert(struct qcom_pcie *pcie) |
149 | { | 186 | { |
150 | gpiod_set_value(pcie->reset, 0); | 187 | gpiod_set_value_cansleep(pcie->reset, 0); |
151 | usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500); | 188 | usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500); |
152 | } | 189 | } |
153 | 190 | ||
@@ -172,7 +209,7 @@ static int qcom_pcie_establish_link(struct qcom_pcie *pcie) | |||
172 | return dw_pcie_wait_for_link(pci); | 209 | return dw_pcie_wait_for_link(pci); |
173 | } | 210 | } |
174 | 211 | ||
175 | static void qcom_pcie_v0_v1_ltssm_enable(struct qcom_pcie *pcie) | 212 | static void qcom_pcie_2_1_0_ltssm_enable(struct qcom_pcie *pcie) |
176 | { | 213 | { |
177 | u32 val; | 214 | u32 val; |
178 | 215 | ||
@@ -182,9 +219,9 @@ static void qcom_pcie_v0_v1_ltssm_enable(struct qcom_pcie *pcie) | |||
182 | writel(val, pcie->elbi + PCIE20_ELBI_SYS_CTRL); | 219 | writel(val, pcie->elbi + PCIE20_ELBI_SYS_CTRL); |
183 | } | 220 | } |
184 | 221 | ||
185 | static int qcom_pcie_get_resources_v0(struct qcom_pcie *pcie) | 222 | static int qcom_pcie_get_resources_2_1_0(struct qcom_pcie *pcie) |
186 | { | 223 | { |
187 | struct qcom_pcie_resources_v0 *res = &pcie->res.v0; | 224 | struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0; |
188 | struct dw_pcie *pci = pcie->pci; | 225 | struct dw_pcie *pci = pcie->pci; |
189 | struct device *dev = pci->dev; | 226 | struct device *dev = pci->dev; |
190 | 227 | ||
@@ -212,29 +249,29 @@ static int qcom_pcie_get_resources_v0(struct qcom_pcie *pcie) | |||
212 | if (IS_ERR(res->phy_clk)) | 249 | if (IS_ERR(res->phy_clk)) |
213 | return PTR_ERR(res->phy_clk); | 250 | return PTR_ERR(res->phy_clk); |
214 | 251 | ||
215 | res->pci_reset = devm_reset_control_get(dev, "pci"); | 252 | res->pci_reset = devm_reset_control_get_exclusive(dev, "pci"); |
216 | if (IS_ERR(res->pci_reset)) | 253 | if (IS_ERR(res->pci_reset)) |
217 | return PTR_ERR(res->pci_reset); | 254 | return PTR_ERR(res->pci_reset); |
218 | 255 | ||
219 | res->axi_reset = devm_reset_control_get(dev, "axi"); | 256 | res->axi_reset = devm_reset_control_get_exclusive(dev, "axi"); |
220 | if (IS_ERR(res->axi_reset)) | 257 | if (IS_ERR(res->axi_reset)) |
221 | return PTR_ERR(res->axi_reset); | 258 | return PTR_ERR(res->axi_reset); |
222 | 259 | ||
223 | res->ahb_reset = devm_reset_control_get(dev, "ahb"); | 260 | res->ahb_reset = devm_reset_control_get_exclusive(dev, "ahb"); |
224 | if (IS_ERR(res->ahb_reset)) | 261 | if (IS_ERR(res->ahb_reset)) |
225 | return PTR_ERR(res->ahb_reset); | 262 | return PTR_ERR(res->ahb_reset); |
226 | 263 | ||
227 | res->por_reset = devm_reset_control_get(dev, "por"); | 264 | res->por_reset = devm_reset_control_get_exclusive(dev, "por"); |
228 | if (IS_ERR(res->por_reset)) | 265 | if (IS_ERR(res->por_reset)) |
229 | return PTR_ERR(res->por_reset); | 266 | return PTR_ERR(res->por_reset); |
230 | 267 | ||
231 | res->phy_reset = devm_reset_control_get(dev, "phy"); | 268 | res->phy_reset = devm_reset_control_get_exclusive(dev, "phy"); |
232 | return PTR_ERR_OR_ZERO(res->phy_reset); | 269 | return PTR_ERR_OR_ZERO(res->phy_reset); |
233 | } | 270 | } |
234 | 271 | ||
235 | static void qcom_pcie_deinit_v0(struct qcom_pcie *pcie) | 272 | static void qcom_pcie_deinit_2_1_0(struct qcom_pcie *pcie) |
236 | { | 273 | { |
237 | struct qcom_pcie_resources_v0 *res = &pcie->res.v0; | 274 | struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0; |
238 | 275 | ||
239 | reset_control_assert(res->pci_reset); | 276 | reset_control_assert(res->pci_reset); |
240 | reset_control_assert(res->axi_reset); | 277 | reset_control_assert(res->axi_reset); |
@@ -249,9 +286,9 @@ static void qcom_pcie_deinit_v0(struct qcom_pcie *pcie) | |||
249 | regulator_disable(res->vdda_refclk); | 286 | regulator_disable(res->vdda_refclk); |
250 | } | 287 | } |
251 | 288 | ||
252 | static int qcom_pcie_init_v0(struct qcom_pcie *pcie) | 289 | static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie) |
253 | { | 290 | { |
254 | struct qcom_pcie_resources_v0 *res = &pcie->res.v0; | 291 | struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0; |
255 | struct dw_pcie *pci = pcie->pci; | 292 | struct dw_pcie *pci = pcie->pci; |
256 | struct device *dev = pci->dev; | 293 | struct device *dev = pci->dev; |
257 | u32 val; | 294 | u32 val; |
@@ -367,9 +404,9 @@ err_refclk: | |||
367 | return ret; | 404 | return ret; |
368 | } | 405 | } |
369 | 406 | ||
370 | static int qcom_pcie_get_resources_v1(struct qcom_pcie *pcie) | 407 | static int qcom_pcie_get_resources_1_0_0(struct qcom_pcie *pcie) |
371 | { | 408 | { |
372 | struct qcom_pcie_resources_v1 *res = &pcie->res.v1; | 409 | struct qcom_pcie_resources_1_0_0 *res = &pcie->res.v1_0_0; |
373 | struct dw_pcie *pci = pcie->pci; | 410 | struct dw_pcie *pci = pcie->pci; |
374 | struct device *dev = pci->dev; | 411 | struct device *dev = pci->dev; |
375 | 412 | ||
@@ -393,13 +430,13 @@ static int qcom_pcie_get_resources_v1(struct qcom_pcie *pcie) | |||
393 | if (IS_ERR(res->slave_bus)) | 430 | if (IS_ERR(res->slave_bus)) |
394 | return PTR_ERR(res->slave_bus); | 431 | return PTR_ERR(res->slave_bus); |
395 | 432 | ||
396 | res->core = devm_reset_control_get(dev, "core"); | 433 | res->core = devm_reset_control_get_exclusive(dev, "core"); |
397 | return PTR_ERR_OR_ZERO(res->core); | 434 | return PTR_ERR_OR_ZERO(res->core); |
398 | } | 435 | } |
399 | 436 | ||
400 | static void qcom_pcie_deinit_v1(struct qcom_pcie *pcie) | 437 | static void qcom_pcie_deinit_1_0_0(struct qcom_pcie *pcie) |
401 | { | 438 | { |
402 | struct qcom_pcie_resources_v1 *res = &pcie->res.v1; | 439 | struct qcom_pcie_resources_1_0_0 *res = &pcie->res.v1_0_0; |
403 | 440 | ||
404 | reset_control_assert(res->core); | 441 | reset_control_assert(res->core); |
405 | clk_disable_unprepare(res->slave_bus); | 442 | clk_disable_unprepare(res->slave_bus); |
@@ -409,9 +446,9 @@ static void qcom_pcie_deinit_v1(struct qcom_pcie *pcie) | |||
409 | regulator_disable(res->vdda); | 446 | regulator_disable(res->vdda); |
410 | } | 447 | } |
411 | 448 | ||
412 | static int qcom_pcie_init_v1(struct qcom_pcie *pcie) | 449 | static int qcom_pcie_init_1_0_0(struct qcom_pcie *pcie) |
413 | { | 450 | { |
414 | struct qcom_pcie_resources_v1 *res = &pcie->res.v1; | 451 | struct qcom_pcie_resources_1_0_0 *res = &pcie->res.v1_0_0; |
415 | struct dw_pcie *pci = pcie->pci; | 452 | struct dw_pcie *pci = pcie->pci; |
416 | struct device *dev = pci->dev; | 453 | struct device *dev = pci->dev; |
417 | int ret; | 454 | int ret; |
@@ -477,7 +514,7 @@ err_res: | |||
477 | return ret; | 514 | return ret; |
478 | } | 515 | } |
479 | 516 | ||
480 | static void qcom_pcie_v2_ltssm_enable(struct qcom_pcie *pcie) | 517 | static void qcom_pcie_2_3_2_ltssm_enable(struct qcom_pcie *pcie) |
481 | { | 518 | { |
482 | u32 val; | 519 | u32 val; |
483 | 520 | ||
@@ -487,9 +524,9 @@ static void qcom_pcie_v2_ltssm_enable(struct qcom_pcie *pcie) | |||
487 | writel(val, pcie->parf + PCIE20_PARF_LTSSM); | 524 | writel(val, pcie->parf + PCIE20_PARF_LTSSM); |
488 | } | 525 | } |
489 | 526 | ||
490 | static int qcom_pcie_get_resources_v2(struct qcom_pcie *pcie) | 527 | static int qcom_pcie_get_resources_2_3_2(struct qcom_pcie *pcie) |
491 | { | 528 | { |
492 | struct qcom_pcie_resources_v2 *res = &pcie->res.v2; | 529 | struct qcom_pcie_resources_2_3_2 *res = &pcie->res.v2_3_2; |
493 | struct dw_pcie *pci = pcie->pci; | 530 | struct dw_pcie *pci = pcie->pci; |
494 | struct device *dev = pci->dev; | 531 | struct device *dev = pci->dev; |
495 | 532 | ||
@@ -513,20 +550,26 @@ static int qcom_pcie_get_resources_v2(struct qcom_pcie *pcie) | |||
513 | return PTR_ERR_OR_ZERO(res->pipe_clk); | 550 | return PTR_ERR_OR_ZERO(res->pipe_clk); |
514 | } | 551 | } |
515 | 552 | ||
516 | static void qcom_pcie_deinit_v2(struct qcom_pcie *pcie) | 553 | static void qcom_pcie_deinit_2_3_2(struct qcom_pcie *pcie) |
517 | { | 554 | { |
518 | struct qcom_pcie_resources_v2 *res = &pcie->res.v2; | 555 | struct qcom_pcie_resources_2_3_2 *res = &pcie->res.v2_3_2; |
519 | 556 | ||
520 | clk_disable_unprepare(res->pipe_clk); | ||
521 | clk_disable_unprepare(res->slave_clk); | 557 | clk_disable_unprepare(res->slave_clk); |
522 | clk_disable_unprepare(res->master_clk); | 558 | clk_disable_unprepare(res->master_clk); |
523 | clk_disable_unprepare(res->cfg_clk); | 559 | clk_disable_unprepare(res->cfg_clk); |
524 | clk_disable_unprepare(res->aux_clk); | 560 | clk_disable_unprepare(res->aux_clk); |
525 | } | 561 | } |
526 | 562 | ||
527 | static int qcom_pcie_init_v2(struct qcom_pcie *pcie) | 563 | static void qcom_pcie_post_deinit_2_3_2(struct qcom_pcie *pcie) |
528 | { | 564 | { |
529 | struct qcom_pcie_resources_v2 *res = &pcie->res.v2; | 565 | struct qcom_pcie_resources_2_3_2 *res = &pcie->res.v2_3_2; |
566 | |||
567 | clk_disable_unprepare(res->pipe_clk); | ||
568 | } | ||
569 | |||
570 | static int qcom_pcie_init_2_3_2(struct qcom_pcie *pcie) | ||
571 | { | ||
572 | struct qcom_pcie_resources_2_3_2 *res = &pcie->res.v2_3_2; | ||
530 | struct dw_pcie *pci = pcie->pci; | 573 | struct dw_pcie *pci = pcie->pci; |
531 | struct device *dev = pci->dev; | 574 | struct device *dev = pci->dev; |
532 | u32 val; | 575 | u32 val; |
@@ -589,9 +632,9 @@ err_cfg_clk: | |||
589 | return ret; | 632 | return ret; |
590 | } | 633 | } |
591 | 634 | ||
592 | static int qcom_pcie_post_init_v2(struct qcom_pcie *pcie) | 635 | static int qcom_pcie_post_init_2_3_2(struct qcom_pcie *pcie) |
593 | { | 636 | { |
594 | struct qcom_pcie_resources_v2 *res = &pcie->res.v2; | 637 | struct qcom_pcie_resources_2_3_2 *res = &pcie->res.v2_3_2; |
595 | struct dw_pcie *pci = pcie->pci; | 638 | struct dw_pcie *pci = pcie->pci; |
596 | struct device *dev = pci->dev; | 639 | struct device *dev = pci->dev; |
597 | int ret; | 640 | int ret; |
@@ -605,9 +648,9 @@ static int qcom_pcie_post_init_v2(struct qcom_pcie *pcie) | |||
605 | return 0; | 648 | return 0; |
606 | } | 649 | } |
607 | 650 | ||
608 | static int qcom_pcie_get_resources_v3(struct qcom_pcie *pcie) | 651 | static int qcom_pcie_get_resources_2_4_0(struct qcom_pcie *pcie) |
609 | { | 652 | { |
610 | struct qcom_pcie_resources_v3 *res = &pcie->res.v3; | 653 | struct qcom_pcie_resources_2_4_0 *res = &pcie->res.v2_4_0; |
611 | struct dw_pcie *pci = pcie->pci; | 654 | struct dw_pcie *pci = pcie->pci; |
612 | struct device *dev = pci->dev; | 655 | struct device *dev = pci->dev; |
613 | 656 | ||
@@ -623,60 +666,64 @@ static int qcom_pcie_get_resources_v3(struct qcom_pcie *pcie) | |||
623 | if (IS_ERR(res->slave_clk)) | 666 | if (IS_ERR(res->slave_clk)) |
624 | return PTR_ERR(res->slave_clk); | 667 | return PTR_ERR(res->slave_clk); |
625 | 668 | ||
626 | res->axi_m_reset = devm_reset_control_get(dev, "axi_m"); | 669 | res->axi_m_reset = devm_reset_control_get_exclusive(dev, "axi_m"); |
627 | if (IS_ERR(res->axi_m_reset)) | 670 | if (IS_ERR(res->axi_m_reset)) |
628 | return PTR_ERR(res->axi_m_reset); | 671 | return PTR_ERR(res->axi_m_reset); |
629 | 672 | ||
630 | res->axi_s_reset = devm_reset_control_get(dev, "axi_s"); | 673 | res->axi_s_reset = devm_reset_control_get_exclusive(dev, "axi_s"); |
631 | if (IS_ERR(res->axi_s_reset)) | 674 | if (IS_ERR(res->axi_s_reset)) |
632 | return PTR_ERR(res->axi_s_reset); | 675 | return PTR_ERR(res->axi_s_reset); |
633 | 676 | ||
634 | res->pipe_reset = devm_reset_control_get(dev, "pipe"); | 677 | res->pipe_reset = devm_reset_control_get_exclusive(dev, "pipe"); |
635 | if (IS_ERR(res->pipe_reset)) | 678 | if (IS_ERR(res->pipe_reset)) |
636 | return PTR_ERR(res->pipe_reset); | 679 | return PTR_ERR(res->pipe_reset); |
637 | 680 | ||
638 | res->axi_m_vmid_reset = devm_reset_control_get(dev, "axi_m_vmid"); | 681 | res->axi_m_vmid_reset = devm_reset_control_get_exclusive(dev, |
682 | "axi_m_vmid"); | ||
639 | if (IS_ERR(res->axi_m_vmid_reset)) | 683 | if (IS_ERR(res->axi_m_vmid_reset)) |
640 | return PTR_ERR(res->axi_m_vmid_reset); | 684 | return PTR_ERR(res->axi_m_vmid_reset); |
641 | 685 | ||
642 | res->axi_s_xpu_reset = devm_reset_control_get(dev, "axi_s_xpu"); | 686 | res->axi_s_xpu_reset = devm_reset_control_get_exclusive(dev, |
687 | "axi_s_xpu"); | ||
643 | if (IS_ERR(res->axi_s_xpu_reset)) | 688 | if (IS_ERR(res->axi_s_xpu_reset)) |
644 | return PTR_ERR(res->axi_s_xpu_reset); | 689 | return PTR_ERR(res->axi_s_xpu_reset); |
645 | 690 | ||
646 | res->parf_reset = devm_reset_control_get(dev, "parf"); | 691 | res->parf_reset = devm_reset_control_get_exclusive(dev, "parf"); |
647 | if (IS_ERR(res->parf_reset)) | 692 | if (IS_ERR(res->parf_reset)) |
648 | return PTR_ERR(res->parf_reset); | 693 | return PTR_ERR(res->parf_reset); |
649 | 694 | ||
650 | res->phy_reset = devm_reset_control_get(dev, "phy"); | 695 | res->phy_reset = devm_reset_control_get_exclusive(dev, "phy"); |
651 | if (IS_ERR(res->phy_reset)) | 696 | if (IS_ERR(res->phy_reset)) |
652 | return PTR_ERR(res->phy_reset); | 697 | return PTR_ERR(res->phy_reset); |
653 | 698 | ||
654 | res->axi_m_sticky_reset = devm_reset_control_get(dev, "axi_m_sticky"); | 699 | res->axi_m_sticky_reset = devm_reset_control_get_exclusive(dev, |
700 | "axi_m_sticky"); | ||
655 | if (IS_ERR(res->axi_m_sticky_reset)) | 701 | if (IS_ERR(res->axi_m_sticky_reset)) |
656 | return PTR_ERR(res->axi_m_sticky_reset); | 702 | return PTR_ERR(res->axi_m_sticky_reset); |
657 | 703 | ||
658 | res->pipe_sticky_reset = devm_reset_control_get(dev, "pipe_sticky"); | 704 | res->pipe_sticky_reset = devm_reset_control_get_exclusive(dev, |
705 | "pipe_sticky"); | ||
659 | if (IS_ERR(res->pipe_sticky_reset)) | 706 | if (IS_ERR(res->pipe_sticky_reset)) |
660 | return PTR_ERR(res->pipe_sticky_reset); | 707 | return PTR_ERR(res->pipe_sticky_reset); |
661 | 708 | ||
662 | res->pwr_reset = devm_reset_control_get(dev, "pwr"); | 709 | res->pwr_reset = devm_reset_control_get_exclusive(dev, "pwr"); |
663 | if (IS_ERR(res->pwr_reset)) | 710 | if (IS_ERR(res->pwr_reset)) |
664 | return PTR_ERR(res->pwr_reset); | 711 | return PTR_ERR(res->pwr_reset); |
665 | 712 | ||
666 | res->ahb_reset = devm_reset_control_get(dev, "ahb"); | 713 | res->ahb_reset = devm_reset_control_get_exclusive(dev, "ahb"); |
667 | if (IS_ERR(res->ahb_reset)) | 714 | if (IS_ERR(res->ahb_reset)) |
668 | return PTR_ERR(res->ahb_reset); | 715 | return PTR_ERR(res->ahb_reset); |
669 | 716 | ||
670 | res->phy_ahb_reset = devm_reset_control_get(dev, "phy_ahb"); | 717 | res->phy_ahb_reset = devm_reset_control_get_exclusive(dev, "phy_ahb"); |
671 | if (IS_ERR(res->phy_ahb_reset)) | 718 | if (IS_ERR(res->phy_ahb_reset)) |
672 | return PTR_ERR(res->phy_ahb_reset); | 719 | return PTR_ERR(res->phy_ahb_reset); |
673 | 720 | ||
674 | return 0; | 721 | return 0; |
675 | } | 722 | } |
676 | 723 | ||
677 | static void qcom_pcie_deinit_v3(struct qcom_pcie *pcie) | 724 | static void qcom_pcie_deinit_2_4_0(struct qcom_pcie *pcie) |
678 | { | 725 | { |
679 | struct qcom_pcie_resources_v3 *res = &pcie->res.v3; | 726 | struct qcom_pcie_resources_2_4_0 *res = &pcie->res.v2_4_0; |
680 | 727 | ||
681 | reset_control_assert(res->axi_m_reset); | 728 | reset_control_assert(res->axi_m_reset); |
682 | reset_control_assert(res->axi_s_reset); | 729 | reset_control_assert(res->axi_s_reset); |
@@ -692,9 +739,9 @@ static void qcom_pcie_deinit_v3(struct qcom_pcie *pcie) | |||
692 | clk_disable_unprepare(res->slave_clk); | 739 | clk_disable_unprepare(res->slave_clk); |
693 | } | 740 | } |
694 | 741 | ||
695 | static int qcom_pcie_init_v3(struct qcom_pcie *pcie) | 742 | static int qcom_pcie_init_2_4_0(struct qcom_pcie *pcie) |
696 | { | 743 | { |
697 | struct qcom_pcie_resources_v3 *res = &pcie->res.v3; | 744 | struct qcom_pcie_resources_2_4_0 *res = &pcie->res.v2_4_0; |
698 | struct dw_pcie *pci = pcie->pci; | 745 | struct dw_pcie *pci = pcie->pci; |
699 | struct device *dev = pci->dev; | 746 | struct device *dev = pci->dev; |
700 | u32 val; | 747 | u32 val; |
@@ -884,6 +931,166 @@ err_rst_phy: | |||
884 | return ret; | 931 | return ret; |
885 | } | 932 | } |
886 | 933 | ||
934 | static int qcom_pcie_get_resources_2_3_3(struct qcom_pcie *pcie) | ||
935 | { | ||
936 | struct qcom_pcie_resources_2_3_3 *res = &pcie->res.v2_3_3; | ||
937 | struct dw_pcie *pci = pcie->pci; | ||
938 | struct device *dev = pci->dev; | ||
939 | int i; | ||
940 | const char *rst_names[] = { "axi_m", "axi_s", "pipe", | ||
941 | "axi_m_sticky", "sticky", | ||
942 | "ahb", "sleep", }; | ||
943 | |||
944 | res->iface = devm_clk_get(dev, "iface"); | ||
945 | if (IS_ERR(res->iface)) | ||
946 | return PTR_ERR(res->iface); | ||
947 | |||
948 | res->axi_m_clk = devm_clk_get(dev, "axi_m"); | ||
949 | if (IS_ERR(res->axi_m_clk)) | ||
950 | return PTR_ERR(res->axi_m_clk); | ||
951 | |||
952 | res->axi_s_clk = devm_clk_get(dev, "axi_s"); | ||
953 | if (IS_ERR(res->axi_s_clk)) | ||
954 | return PTR_ERR(res->axi_s_clk); | ||
955 | |||
956 | res->ahb_clk = devm_clk_get(dev, "ahb"); | ||
957 | if (IS_ERR(res->ahb_clk)) | ||
958 | return PTR_ERR(res->ahb_clk); | ||
959 | |||
960 | res->aux_clk = devm_clk_get(dev, "aux"); | ||
961 | if (IS_ERR(res->aux_clk)) | ||
962 | return PTR_ERR(res->aux_clk); | ||
963 | |||
964 | for (i = 0; i < ARRAY_SIZE(rst_names); i++) { | ||
965 | res->rst[i] = devm_reset_control_get(dev, rst_names[i]); | ||
966 | if (IS_ERR(res->rst[i])) | ||
967 | return PTR_ERR(res->rst[i]); | ||
968 | } | ||
969 | |||
970 | return 0; | ||
971 | } | ||
972 | |||
973 | static void qcom_pcie_deinit_2_3_3(struct qcom_pcie *pcie) | ||
974 | { | ||
975 | struct qcom_pcie_resources_2_3_3 *res = &pcie->res.v2_3_3; | ||
976 | |||
977 | clk_disable_unprepare(res->iface); | ||
978 | clk_disable_unprepare(res->axi_m_clk); | ||
979 | clk_disable_unprepare(res->axi_s_clk); | ||
980 | clk_disable_unprepare(res->ahb_clk); | ||
981 | clk_disable_unprepare(res->aux_clk); | ||
982 | } | ||
983 | |||
984 | static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie) | ||
985 | { | ||
986 | struct qcom_pcie_resources_2_3_3 *res = &pcie->res.v2_3_3; | ||
987 | struct dw_pcie *pci = pcie->pci; | ||
988 | struct device *dev = pci->dev; | ||
989 | int i, ret; | ||
990 | u32 val; | ||
991 | |||
992 | for (i = 0; i < ARRAY_SIZE(res->rst); i++) { | ||
993 | ret = reset_control_assert(res->rst[i]); | ||
994 | if (ret) { | ||
995 | dev_err(dev, "reset #%d assert failed (%d)\n", i, ret); | ||
996 | return ret; | ||
997 | } | ||
998 | } | ||
999 | |||
1000 | usleep_range(2000, 2500); | ||
1001 | |||
1002 | for (i = 0; i < ARRAY_SIZE(res->rst); i++) { | ||
1003 | ret = reset_control_deassert(res->rst[i]); | ||
1004 | if (ret) { | ||
1005 | dev_err(dev, "reset #%d deassert failed (%d)\n", i, | ||
1006 | ret); | ||
1007 | return ret; | ||
1008 | } | ||
1009 | } | ||
1010 | |||
1011 | /* | ||
1012 | * Don't have a way to see if the reset has completed. | ||
1013 | * Wait for some time. | ||
1014 | */ | ||
1015 | usleep_range(2000, 2500); | ||
1016 | |||
1017 | ret = clk_prepare_enable(res->iface); | ||
1018 | if (ret) { | ||
1019 | dev_err(dev, "cannot prepare/enable core clock\n"); | ||
1020 | goto err_clk_iface; | ||
1021 | } | ||
1022 | |||
1023 | ret = clk_prepare_enable(res->axi_m_clk); | ||
1024 | if (ret) { | ||
1025 | dev_err(dev, "cannot prepare/enable core clock\n"); | ||
1026 | goto err_clk_axi_m; | ||
1027 | } | ||
1028 | |||
1029 | ret = clk_prepare_enable(res->axi_s_clk); | ||
1030 | if (ret) { | ||
1031 | dev_err(dev, "cannot prepare/enable axi slave clock\n"); | ||
1032 | goto err_clk_axi_s; | ||
1033 | } | ||
1034 | |||
1035 | ret = clk_prepare_enable(res->ahb_clk); | ||
1036 | if (ret) { | ||
1037 | dev_err(dev, "cannot prepare/enable ahb clock\n"); | ||
1038 | goto err_clk_ahb; | ||
1039 | } | ||
1040 | |||
1041 | ret = clk_prepare_enable(res->aux_clk); | ||
1042 | if (ret) { | ||
1043 | dev_err(dev, "cannot prepare/enable aux clock\n"); | ||
1044 | goto err_clk_aux; | ||
1045 | } | ||
1046 | |||
1047 | writel(SLV_ADDR_SPACE_SZ, | ||
1048 | pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE); | ||
1049 | |||
1050 | val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL); | ||
1051 | val &= ~BIT(0); | ||
1052 | writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL); | ||
1053 | |||
1054 | writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR); | ||
1055 | |||
1056 | writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS | ||
1057 | | SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS | | ||
1058 | AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS, | ||
1059 | pcie->parf + PCIE20_PARF_SYS_CTRL); | ||
1060 | writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH); | ||
1061 | |||
1062 | writel(CMD_BME_VAL, pci->dbi_base + PCIE20_COMMAND_STATUS); | ||
1063 | writel(DBI_RO_WR_EN, pci->dbi_base + PCIE20_MISC_CONTROL_1_REG); | ||
1064 | writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + PCIE20_CAP_LINK_1); | ||
1065 | |||
1066 | val = readl(pci->dbi_base + PCIE20_CAP_LINK_CAPABILITIES); | ||
1067 | val &= ~PCIE20_CAP_ACTIVE_STATE_LINK_PM_SUPPORT; | ||
1068 | writel(val, pci->dbi_base + PCIE20_CAP_LINK_CAPABILITIES); | ||
1069 | |||
1070 | writel(PCIE_CAP_CPL_TIMEOUT_DISABLE, pci->dbi_base + | ||
1071 | PCIE20_DEVICE_CONTROL2_STATUS2); | ||
1072 | |||
1073 | return 0; | ||
1074 | |||
1075 | err_clk_aux: | ||
1076 | clk_disable_unprepare(res->ahb_clk); | ||
1077 | err_clk_ahb: | ||
1078 | clk_disable_unprepare(res->axi_s_clk); | ||
1079 | err_clk_axi_s: | ||
1080 | clk_disable_unprepare(res->axi_m_clk); | ||
1081 | err_clk_axi_m: | ||
1082 | clk_disable_unprepare(res->iface); | ||
1083 | err_clk_iface: | ||
1084 | /* | ||
1085 | * Not checking for failure, will anyway return | ||
1086 | * the original failure in 'ret'. | ||
1087 | */ | ||
1088 | for (i = 0; i < ARRAY_SIZE(res->rst); i++) | ||
1089 | reset_control_assert(res->rst[i]); | ||
1090 | |||
1091 | return ret; | ||
1092 | } | ||
1093 | |||
887 | static int qcom_pcie_link_up(struct dw_pcie *pci) | 1094 | static int qcom_pcie_link_up(struct dw_pcie *pci) |
888 | { | 1095 | { |
889 | u16 val = readw(pci->dbi_base + PCIE20_CAP + PCI_EXP_LNKSTA); | 1096 | u16 val = readw(pci->dbi_base + PCIE20_CAP + PCI_EXP_LNKSTA); |
@@ -891,7 +1098,7 @@ static int qcom_pcie_link_up(struct dw_pcie *pci) | |||
891 | return !!(val & PCI_EXP_LNKSTA_DLLLA); | 1098 | return !!(val & PCI_EXP_LNKSTA_DLLLA); |
892 | } | 1099 | } |
893 | 1100 | ||
894 | static void qcom_pcie_host_init(struct pcie_port *pp) | 1101 | static int qcom_pcie_host_init(struct pcie_port *pp) |
895 | { | 1102 | { |
896 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 1103 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
897 | struct qcom_pcie *pcie = to_qcom_pcie(pci); | 1104 | struct qcom_pcie *pcie = to_qcom_pcie(pci); |
@@ -901,14 +1108,17 @@ static void qcom_pcie_host_init(struct pcie_port *pp) | |||
901 | 1108 | ||
902 | ret = pcie->ops->init(pcie); | 1109 | ret = pcie->ops->init(pcie); |
903 | if (ret) | 1110 | if (ret) |
904 | goto err_deinit; | 1111 | return ret; |
905 | 1112 | ||
906 | ret = phy_power_on(pcie->phy); | 1113 | ret = phy_power_on(pcie->phy); |
907 | if (ret) | 1114 | if (ret) |
908 | goto err_deinit; | 1115 | goto err_deinit; |
909 | 1116 | ||
910 | if (pcie->ops->post_init) | 1117 | if (pcie->ops->post_init) { |
911 | pcie->ops->post_init(pcie); | 1118 | ret = pcie->ops->post_init(pcie); |
1119 | if (ret) | ||
1120 | goto err_disable_phy; | ||
1121 | } | ||
912 | 1122 | ||
913 | dw_pcie_setup_rc(pp); | 1123 | dw_pcie_setup_rc(pp); |
914 | 1124 | ||
@@ -921,12 +1131,17 @@ static void qcom_pcie_host_init(struct pcie_port *pp) | |||
921 | if (ret) | 1131 | if (ret) |
922 | goto err; | 1132 | goto err; |
923 | 1133 | ||
924 | return; | 1134 | return 0; |
925 | err: | 1135 | err: |
926 | qcom_ep_reset_assert(pcie); | 1136 | qcom_ep_reset_assert(pcie); |
1137 | if (pcie->ops->post_deinit) | ||
1138 | pcie->ops->post_deinit(pcie); | ||
1139 | err_disable_phy: | ||
927 | phy_power_off(pcie->phy); | 1140 | phy_power_off(pcie->phy); |
928 | err_deinit: | 1141 | err_deinit: |
929 | pcie->ops->deinit(pcie); | 1142 | pcie->ops->deinit(pcie); |
1143 | |||
1144 | return ret; | ||
930 | } | 1145 | } |
931 | 1146 | ||
932 | static int qcom_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, | 1147 | static int qcom_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, |
@@ -950,37 +1165,50 @@ static const struct dw_pcie_host_ops qcom_pcie_dw_ops = { | |||
950 | .rd_own_conf = qcom_pcie_rd_own_conf, | 1165 | .rd_own_conf = qcom_pcie_rd_own_conf, |
951 | }; | 1166 | }; |
952 | 1167 | ||
953 | static const struct qcom_pcie_ops ops_v0 = { | 1168 | /* Qcom IP rev.: 2.1.0 Synopsys IP rev.: 4.01a */ |
954 | .get_resources = qcom_pcie_get_resources_v0, | 1169 | static const struct qcom_pcie_ops ops_2_1_0 = { |
955 | .init = qcom_pcie_init_v0, | 1170 | .get_resources = qcom_pcie_get_resources_2_1_0, |
956 | .deinit = qcom_pcie_deinit_v0, | 1171 | .init = qcom_pcie_init_2_1_0, |
957 | .ltssm_enable = qcom_pcie_v0_v1_ltssm_enable, | 1172 | .deinit = qcom_pcie_deinit_2_1_0, |
1173 | .ltssm_enable = qcom_pcie_2_1_0_ltssm_enable, | ||
958 | }; | 1174 | }; |
959 | 1175 | ||
960 | static const struct qcom_pcie_ops ops_v1 = { | 1176 | /* Qcom IP rev.: 1.0.0 Synopsys IP rev.: 4.11a */ |
961 | .get_resources = qcom_pcie_get_resources_v1, | 1177 | static const struct qcom_pcie_ops ops_1_0_0 = { |
962 | .init = qcom_pcie_init_v1, | 1178 | .get_resources = qcom_pcie_get_resources_1_0_0, |
963 | .deinit = qcom_pcie_deinit_v1, | 1179 | .init = qcom_pcie_init_1_0_0, |
964 | .ltssm_enable = qcom_pcie_v0_v1_ltssm_enable, | 1180 | .deinit = qcom_pcie_deinit_1_0_0, |
1181 | .ltssm_enable = qcom_pcie_2_1_0_ltssm_enable, | ||
965 | }; | 1182 | }; |
966 | 1183 | ||
967 | static const struct qcom_pcie_ops ops_v2 = { | 1184 | /* Qcom IP rev.: 2.3.2 Synopsys IP rev.: 4.21a */ |
968 | .get_resources = qcom_pcie_get_resources_v2, | 1185 | static const struct qcom_pcie_ops ops_2_3_2 = { |
969 | .init = qcom_pcie_init_v2, | 1186 | .get_resources = qcom_pcie_get_resources_2_3_2, |
970 | .post_init = qcom_pcie_post_init_v2, | 1187 | .init = qcom_pcie_init_2_3_2, |
971 | .deinit = qcom_pcie_deinit_v2, | 1188 | .post_init = qcom_pcie_post_init_2_3_2, |
972 | .ltssm_enable = qcom_pcie_v2_ltssm_enable, | 1189 | .deinit = qcom_pcie_deinit_2_3_2, |
1190 | .post_deinit = qcom_pcie_post_deinit_2_3_2, | ||
1191 | .ltssm_enable = qcom_pcie_2_3_2_ltssm_enable, | ||
973 | }; | 1192 | }; |
974 | 1193 | ||
975 | static const struct dw_pcie_ops dw_pcie_ops = { | 1194 | /* Qcom IP rev.: 2.4.0 Synopsys IP rev.: 4.20a */ |
976 | .link_up = qcom_pcie_link_up, | 1195 | static const struct qcom_pcie_ops ops_2_4_0 = { |
1196 | .get_resources = qcom_pcie_get_resources_2_4_0, | ||
1197 | .init = qcom_pcie_init_2_4_0, | ||
1198 | .deinit = qcom_pcie_deinit_2_4_0, | ||
1199 | .ltssm_enable = qcom_pcie_2_3_2_ltssm_enable, | ||
977 | }; | 1200 | }; |
978 | 1201 | ||
979 | static const struct qcom_pcie_ops ops_v3 = { | 1202 | /* Qcom IP rev.: 2.3.3 Synopsys IP rev.: 4.30a */ |
980 | .get_resources = qcom_pcie_get_resources_v3, | 1203 | static const struct qcom_pcie_ops ops_2_3_3 = { |
981 | .init = qcom_pcie_init_v3, | 1204 | .get_resources = qcom_pcie_get_resources_2_3_3, |
982 | .deinit = qcom_pcie_deinit_v3, | 1205 | .init = qcom_pcie_init_2_3_3, |
983 | .ltssm_enable = qcom_pcie_v2_ltssm_enable, | 1206 | .deinit = qcom_pcie_deinit_2_3_3, |
1207 | .ltssm_enable = qcom_pcie_2_3_2_ltssm_enable, | ||
1208 | }; | ||
1209 | |||
1210 | static const struct dw_pcie_ops dw_pcie_ops = { | ||
1211 | .link_up = qcom_pcie_link_up, | ||
984 | }; | 1212 | }; |
985 | 1213 | ||
986 | static int qcom_pcie_probe(struct platform_device *pdev) | 1214 | static int qcom_pcie_probe(struct platform_device *pdev) |
@@ -1069,11 +1297,12 @@ static int qcom_pcie_probe(struct platform_device *pdev) | |||
1069 | } | 1297 | } |
1070 | 1298 | ||
1071 | static const struct of_device_id qcom_pcie_match[] = { | 1299 | static const struct of_device_id qcom_pcie_match[] = { |
1072 | { .compatible = "qcom,pcie-ipq8064", .data = &ops_v0 }, | 1300 | { .compatible = "qcom,pcie-apq8084", .data = &ops_1_0_0 }, |
1073 | { .compatible = "qcom,pcie-apq8064", .data = &ops_v0 }, | 1301 | { .compatible = "qcom,pcie-ipq8064", .data = &ops_2_1_0 }, |
1074 | { .compatible = "qcom,pcie-apq8084", .data = &ops_v1 }, | 1302 | { .compatible = "qcom,pcie-apq8064", .data = &ops_2_1_0 }, |
1075 | { .compatible = "qcom,pcie-msm8996", .data = &ops_v2 }, | 1303 | { .compatible = "qcom,pcie-msm8996", .data = &ops_2_3_2 }, |
1076 | { .compatible = "qcom,pcie-ipq4019", .data = &ops_v3 }, | 1304 | { .compatible = "qcom,pcie-ipq8074", .data = &ops_2_3_3 }, |
1305 | { .compatible = "qcom,pcie-ipq4019", .data = &ops_2_4_0 }, | ||
1077 | { } | 1306 | { } |
1078 | }; | 1307 | }; |
1079 | 1308 | ||
diff --git a/drivers/pci/dwc/pcie-spear13xx.c b/drivers/pci/dwc/pcie-spear13xx.c index 80897291e0fb..709189d23b31 100644 --- a/drivers/pci/dwc/pcie-spear13xx.c +++ b/drivers/pci/dwc/pcie-spear13xx.c | |||
@@ -177,13 +177,15 @@ static int spear13xx_pcie_link_up(struct dw_pcie *pci) | |||
177 | return 0; | 177 | return 0; |
178 | } | 178 | } |
179 | 179 | ||
180 | static void spear13xx_pcie_host_init(struct pcie_port *pp) | 180 | static int spear13xx_pcie_host_init(struct pcie_port *pp) |
181 | { | 181 | { |
182 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 182 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
183 | struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pci); | 183 | struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pci); |
184 | 184 | ||
185 | spear13xx_pcie_establish_link(spear13xx_pcie); | 185 | spear13xx_pcie_establish_link(spear13xx_pcie); |
186 | spear13xx_pcie_enable_interrupts(spear13xx_pcie); | 186 | spear13xx_pcie_enable_interrupts(spear13xx_pcie); |
187 | |||
188 | return 0; | ||
187 | } | 189 | } |
188 | 190 | ||
189 | static const struct dw_pcie_host_ops spear13xx_pcie_host_ops = { | 191 | static const struct dw_pcie_host_ops spear13xx_pcie_host_ops = { |
@@ -199,9 +201,9 @@ static int spear13xx_add_pcie_port(struct spear13xx_pcie *spear13xx_pcie, | |||
199 | int ret; | 201 | int ret; |
200 | 202 | ||
201 | pp->irq = platform_get_irq(pdev, 0); | 203 | pp->irq = platform_get_irq(pdev, 0); |
202 | if (!pp->irq) { | 204 | if (pp->irq < 0) { |
203 | dev_err(dev, "failed to get irq\n"); | 205 | dev_err(dev, "failed to get irq\n"); |
204 | return -ENODEV; | 206 | return pp->irq; |
205 | } | 207 | } |
206 | ret = devm_request_irq(dev, pp->irq, spear13xx_pcie_irq_handler, | 208 | ret = devm_request_irq(dev, pp->irq, spear13xx_pcie_irq_handler, |
207 | IRQF_SHARED | IRQF_NO_THREAD, | 209 | IRQF_SHARED | IRQF_NO_THREAD, |
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index 53fff8030337..4ddc6e8f9fe7 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c | |||
@@ -54,6 +54,8 @@ static struct workqueue_struct *kpcitest_workqueue; | |||
54 | struct pci_epf_test { | 54 | struct pci_epf_test { |
55 | void *reg[6]; | 55 | void *reg[6]; |
56 | struct pci_epf *epf; | 56 | struct pci_epf *epf; |
57 | enum pci_barno test_reg_bar; | ||
58 | bool linkup_notifier; | ||
57 | struct delayed_work cmd_handler; | 59 | struct delayed_work cmd_handler; |
58 | }; | 60 | }; |
59 | 61 | ||
@@ -74,7 +76,12 @@ static struct pci_epf_header test_header = { | |||
74 | .interrupt_pin = PCI_INTERRUPT_INTA, | 76 | .interrupt_pin = PCI_INTERRUPT_INTA, |
75 | }; | 77 | }; |
76 | 78 | ||
77 | static int bar_size[] = { 512, 1024, 16384, 131072, 1048576 }; | 79 | struct pci_epf_test_data { |
80 | enum pci_barno test_reg_bar; | ||
81 | bool linkup_notifier; | ||
82 | }; | ||
83 | |||
84 | static int bar_size[] = { 512, 512, 1024, 16384, 131072, 1048576 }; | ||
78 | 85 | ||
79 | static int pci_epf_test_copy(struct pci_epf_test *epf_test) | 86 | static int pci_epf_test_copy(struct pci_epf_test *epf_test) |
80 | { | 87 | { |
@@ -86,7 +93,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) | |||
86 | struct pci_epf *epf = epf_test->epf; | 93 | struct pci_epf *epf = epf_test->epf; |
87 | struct device *dev = &epf->dev; | 94 | struct device *dev = &epf->dev; |
88 | struct pci_epc *epc = epf->epc; | 95 | struct pci_epc *epc = epf->epc; |
89 | struct pci_epf_test_reg *reg = epf_test->reg[0]; | 96 | enum pci_barno test_reg_bar = epf_test->test_reg_bar; |
97 | struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar]; | ||
90 | 98 | ||
91 | src_addr = pci_epc_mem_alloc_addr(epc, &src_phys_addr, reg->size); | 99 | src_addr = pci_epc_mem_alloc_addr(epc, &src_phys_addr, reg->size); |
92 | if (!src_addr) { | 100 | if (!src_addr) { |
@@ -145,7 +153,8 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test) | |||
145 | struct pci_epf *epf = epf_test->epf; | 153 | struct pci_epf *epf = epf_test->epf; |
146 | struct device *dev = &epf->dev; | 154 | struct device *dev = &epf->dev; |
147 | struct pci_epc *epc = epf->epc; | 155 | struct pci_epc *epc = epf->epc; |
148 | struct pci_epf_test_reg *reg = epf_test->reg[0]; | 156 | enum pci_barno test_reg_bar = epf_test->test_reg_bar; |
157 | struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar]; | ||
149 | 158 | ||
150 | src_addr = pci_epc_mem_alloc_addr(epc, &phys_addr, reg->size); | 159 | src_addr = pci_epc_mem_alloc_addr(epc, &phys_addr, reg->size); |
151 | if (!src_addr) { | 160 | if (!src_addr) { |
@@ -195,7 +204,8 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test) | |||
195 | struct pci_epf *epf = epf_test->epf; | 204 | struct pci_epf *epf = epf_test->epf; |
196 | struct device *dev = &epf->dev; | 205 | struct device *dev = &epf->dev; |
197 | struct pci_epc *epc = epf->epc; | 206 | struct pci_epc *epc = epf->epc; |
198 | struct pci_epf_test_reg *reg = epf_test->reg[0]; | 207 | enum pci_barno test_reg_bar = epf_test->test_reg_bar; |
208 | struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar]; | ||
199 | 209 | ||
200 | dst_addr = pci_epc_mem_alloc_addr(epc, &phys_addr, reg->size); | 210 | dst_addr = pci_epc_mem_alloc_addr(epc, &phys_addr, reg->size); |
201 | if (!dst_addr) { | 211 | if (!dst_addr) { |
@@ -247,7 +257,8 @@ static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test) | |||
247 | u8 msi_count; | 257 | u8 msi_count; |
248 | struct pci_epf *epf = epf_test->epf; | 258 | struct pci_epf *epf = epf_test->epf; |
249 | struct pci_epc *epc = epf->epc; | 259 | struct pci_epc *epc = epf->epc; |
250 | struct pci_epf_test_reg *reg = epf_test->reg[0]; | 260 | enum pci_barno test_reg_bar = epf_test->test_reg_bar; |
261 | struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar]; | ||
251 | 262 | ||
252 | reg->status |= STATUS_IRQ_RAISED; | 263 | reg->status |= STATUS_IRQ_RAISED; |
253 | msi_count = pci_epc_get_msi(epc); | 264 | msi_count = pci_epc_get_msi(epc); |
@@ -263,22 +274,28 @@ static void pci_epf_test_cmd_handler(struct work_struct *work) | |||
263 | int ret; | 274 | int ret; |
264 | u8 irq; | 275 | u8 irq; |
265 | u8 msi_count; | 276 | u8 msi_count; |
277 | u32 command; | ||
266 | struct pci_epf_test *epf_test = container_of(work, struct pci_epf_test, | 278 | struct pci_epf_test *epf_test = container_of(work, struct pci_epf_test, |
267 | cmd_handler.work); | 279 | cmd_handler.work); |
268 | struct pci_epf *epf = epf_test->epf; | 280 | struct pci_epf *epf = epf_test->epf; |
269 | struct pci_epc *epc = epf->epc; | 281 | struct pci_epc *epc = epf->epc; |
270 | struct pci_epf_test_reg *reg = epf_test->reg[0]; | 282 | enum pci_barno test_reg_bar = epf_test->test_reg_bar; |
283 | struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar]; | ||
271 | 284 | ||
272 | if (!reg->command) | 285 | command = reg->command; |
286 | if (!command) | ||
273 | goto reset_handler; | 287 | goto reset_handler; |
274 | 288 | ||
275 | if (reg->command & COMMAND_RAISE_LEGACY_IRQ) { | 289 | reg->command = 0; |
290 | reg->status = 0; | ||
291 | |||
292 | if (command & COMMAND_RAISE_LEGACY_IRQ) { | ||
276 | reg->status = STATUS_IRQ_RAISED; | 293 | reg->status = STATUS_IRQ_RAISED; |
277 | pci_epc_raise_irq(epc, PCI_EPC_IRQ_LEGACY, 0); | 294 | pci_epc_raise_irq(epc, PCI_EPC_IRQ_LEGACY, 0); |
278 | goto reset_handler; | 295 | goto reset_handler; |
279 | } | 296 | } |
280 | 297 | ||
281 | if (reg->command & COMMAND_WRITE) { | 298 | if (command & COMMAND_WRITE) { |
282 | ret = pci_epf_test_write(epf_test); | 299 | ret = pci_epf_test_write(epf_test); |
283 | if (ret) | 300 | if (ret) |
284 | reg->status |= STATUS_WRITE_FAIL; | 301 | reg->status |= STATUS_WRITE_FAIL; |
@@ -288,7 +305,7 @@ static void pci_epf_test_cmd_handler(struct work_struct *work) | |||
288 | goto reset_handler; | 305 | goto reset_handler; |
289 | } | 306 | } |
290 | 307 | ||
291 | if (reg->command & COMMAND_READ) { | 308 | if (command & COMMAND_READ) { |
292 | ret = pci_epf_test_read(epf_test); | 309 | ret = pci_epf_test_read(epf_test); |
293 | if (!ret) | 310 | if (!ret) |
294 | reg->status |= STATUS_READ_SUCCESS; | 311 | reg->status |= STATUS_READ_SUCCESS; |
@@ -298,7 +315,7 @@ static void pci_epf_test_cmd_handler(struct work_struct *work) | |||
298 | goto reset_handler; | 315 | goto reset_handler; |
299 | } | 316 | } |
300 | 317 | ||
301 | if (reg->command & COMMAND_COPY) { | 318 | if (command & COMMAND_COPY) { |
302 | ret = pci_epf_test_copy(epf_test); | 319 | ret = pci_epf_test_copy(epf_test); |
303 | if (!ret) | 320 | if (!ret) |
304 | reg->status |= STATUS_COPY_SUCCESS; | 321 | reg->status |= STATUS_COPY_SUCCESS; |
@@ -308,9 +325,9 @@ static void pci_epf_test_cmd_handler(struct work_struct *work) | |||
308 | goto reset_handler; | 325 | goto reset_handler; |
309 | } | 326 | } |
310 | 327 | ||
311 | if (reg->command & COMMAND_RAISE_MSI_IRQ) { | 328 | if (command & COMMAND_RAISE_MSI_IRQ) { |
312 | msi_count = pci_epc_get_msi(epc); | 329 | msi_count = pci_epc_get_msi(epc); |
313 | irq = (reg->command & MSI_NUMBER_MASK) >> MSI_NUMBER_SHIFT; | 330 | irq = (command & MSI_NUMBER_MASK) >> MSI_NUMBER_SHIFT; |
314 | if (irq > msi_count || msi_count <= 0) | 331 | if (irq > msi_count || msi_count <= 0) |
315 | goto reset_handler; | 332 | goto reset_handler; |
316 | reg->status = STATUS_IRQ_RAISED; | 333 | reg->status = STATUS_IRQ_RAISED; |
@@ -319,8 +336,6 @@ static void pci_epf_test_cmd_handler(struct work_struct *work) | |||
319 | } | 336 | } |
320 | 337 | ||
321 | reset_handler: | 338 | reset_handler: |
322 | reg->command = 0; | ||
323 | |||
324 | queue_delayed_work(kpcitest_workqueue, &epf_test->cmd_handler, | 339 | queue_delayed_work(kpcitest_workqueue, &epf_test->cmd_handler, |
325 | msecs_to_jiffies(1)); | 340 | msecs_to_jiffies(1)); |
326 | } | 341 | } |
@@ -358,6 +373,7 @@ static int pci_epf_test_set_bar(struct pci_epf *epf) | |||
358 | struct pci_epc *epc = epf->epc; | 373 | struct pci_epc *epc = epf->epc; |
359 | struct device *dev = &epf->dev; | 374 | struct device *dev = &epf->dev; |
360 | struct pci_epf_test *epf_test = epf_get_drvdata(epf); | 375 | struct pci_epf_test *epf_test = epf_get_drvdata(epf); |
376 | enum pci_barno test_reg_bar = epf_test->test_reg_bar; | ||
361 | 377 | ||
362 | flags = PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32; | 378 | flags = PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32; |
363 | if (sizeof(dma_addr_t) == 0x8) | 379 | if (sizeof(dma_addr_t) == 0x8) |
@@ -370,7 +386,7 @@ static int pci_epf_test_set_bar(struct pci_epf *epf) | |||
370 | if (ret) { | 386 | if (ret) { |
371 | pci_epf_free_space(epf, epf_test->reg[bar], bar); | 387 | pci_epf_free_space(epf, epf_test->reg[bar], bar); |
372 | dev_err(dev, "failed to set BAR%d\n", bar); | 388 | dev_err(dev, "failed to set BAR%d\n", bar); |
373 | if (bar == BAR_0) | 389 | if (bar == test_reg_bar) |
374 | return ret; | 390 | return ret; |
375 | } | 391 | } |
376 | } | 392 | } |
@@ -384,17 +400,20 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) | |||
384 | struct device *dev = &epf->dev; | 400 | struct device *dev = &epf->dev; |
385 | void *base; | 401 | void *base; |
386 | int bar; | 402 | int bar; |
403 | enum pci_barno test_reg_bar = epf_test->test_reg_bar; | ||
387 | 404 | ||
388 | base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg), | 405 | base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg), |
389 | BAR_0); | 406 | test_reg_bar); |
390 | if (!base) { | 407 | if (!base) { |
391 | dev_err(dev, "failed to allocated register space\n"); | 408 | dev_err(dev, "failed to allocated register space\n"); |
392 | return -ENOMEM; | 409 | return -ENOMEM; |
393 | } | 410 | } |
394 | epf_test->reg[0] = base; | 411 | epf_test->reg[test_reg_bar] = base; |
395 | 412 | ||
396 | for (bar = BAR_1; bar <= BAR_5; bar++) { | 413 | for (bar = BAR_0; bar <= BAR_5; bar++) { |
397 | base = pci_epf_alloc_space(epf, bar_size[bar - 1], bar); | 414 | if (bar == test_reg_bar) |
415 | continue; | ||
416 | base = pci_epf_alloc_space(epf, bar_size[bar], bar); | ||
398 | if (!base) | 417 | if (!base) |
399 | dev_err(dev, "failed to allocate space for BAR%d\n", | 418 | dev_err(dev, "failed to allocate space for BAR%d\n", |
400 | bar); | 419 | bar); |
@@ -407,6 +426,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) | |||
407 | static int pci_epf_test_bind(struct pci_epf *epf) | 426 | static int pci_epf_test_bind(struct pci_epf *epf) |
408 | { | 427 | { |
409 | int ret; | 428 | int ret; |
429 | struct pci_epf_test *epf_test = epf_get_drvdata(epf); | ||
410 | struct pci_epf_header *header = epf->header; | 430 | struct pci_epf_header *header = epf->header; |
411 | struct pci_epc *epc = epf->epc; | 431 | struct pci_epc *epc = epf->epc; |
412 | struct device *dev = &epf->dev; | 432 | struct device *dev = &epf->dev; |
@@ -432,13 +452,34 @@ static int pci_epf_test_bind(struct pci_epf *epf) | |||
432 | if (ret) | 452 | if (ret) |
433 | return ret; | 453 | return ret; |
434 | 454 | ||
455 | if (!epf_test->linkup_notifier) | ||
456 | queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work); | ||
457 | |||
435 | return 0; | 458 | return 0; |
436 | } | 459 | } |
437 | 460 | ||
461 | static const struct pci_epf_device_id pci_epf_test_ids[] = { | ||
462 | { | ||
463 | .name = "pci_epf_test", | ||
464 | }, | ||
465 | {}, | ||
466 | }; | ||
467 | |||
438 | static int pci_epf_test_probe(struct pci_epf *epf) | 468 | static int pci_epf_test_probe(struct pci_epf *epf) |
439 | { | 469 | { |
440 | struct pci_epf_test *epf_test; | 470 | struct pci_epf_test *epf_test; |
441 | struct device *dev = &epf->dev; | 471 | struct device *dev = &epf->dev; |
472 | const struct pci_epf_device_id *match; | ||
473 | struct pci_epf_test_data *data; | ||
474 | enum pci_barno test_reg_bar = BAR_0; | ||
475 | bool linkup_notifier = true; | ||
476 | |||
477 | match = pci_epf_match_device(pci_epf_test_ids, epf); | ||
478 | data = (struct pci_epf_test_data *)match->driver_data; | ||
479 | if (data) { | ||
480 | test_reg_bar = data->test_reg_bar; | ||
481 | linkup_notifier = data->linkup_notifier; | ||
482 | } | ||
442 | 483 | ||
443 | epf_test = devm_kzalloc(dev, sizeof(*epf_test), GFP_KERNEL); | 484 | epf_test = devm_kzalloc(dev, sizeof(*epf_test), GFP_KERNEL); |
444 | if (!epf_test) | 485 | if (!epf_test) |
@@ -446,6 +487,8 @@ static int pci_epf_test_probe(struct pci_epf *epf) | |||
446 | 487 | ||
447 | epf->header = &test_header; | 488 | epf->header = &test_header; |
448 | epf_test->epf = epf; | 489 | epf_test->epf = epf; |
490 | epf_test->test_reg_bar = test_reg_bar; | ||
491 | epf_test->linkup_notifier = linkup_notifier; | ||
449 | 492 | ||
450 | INIT_DELAYED_WORK(&epf_test->cmd_handler, pci_epf_test_cmd_handler); | 493 | INIT_DELAYED_WORK(&epf_test->cmd_handler, pci_epf_test_cmd_handler); |
451 | 494 | ||
@@ -453,31 +496,15 @@ static int pci_epf_test_probe(struct pci_epf *epf) | |||
453 | return 0; | 496 | return 0; |
454 | } | 497 | } |
455 | 498 | ||
456 | static int pci_epf_test_remove(struct pci_epf *epf) | ||
457 | { | ||
458 | struct pci_epf_test *epf_test = epf_get_drvdata(epf); | ||
459 | |||
460 | kfree(epf_test); | ||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | static struct pci_epf_ops ops = { | 499 | static struct pci_epf_ops ops = { |
465 | .unbind = pci_epf_test_unbind, | 500 | .unbind = pci_epf_test_unbind, |
466 | .bind = pci_epf_test_bind, | 501 | .bind = pci_epf_test_bind, |
467 | .linkup = pci_epf_test_linkup, | 502 | .linkup = pci_epf_test_linkup, |
468 | }; | 503 | }; |
469 | 504 | ||
470 | static const struct pci_epf_device_id pci_epf_test_ids[] = { | ||
471 | { | ||
472 | .name = "pci_epf_test", | ||
473 | }, | ||
474 | {}, | ||
475 | }; | ||
476 | |||
477 | static struct pci_epf_driver test_driver = { | 505 | static struct pci_epf_driver test_driver = { |
478 | .driver.name = "pci_epf_test", | 506 | .driver.name = "pci_epf_test", |
479 | .probe = pci_epf_test_probe, | 507 | .probe = pci_epf_test_probe, |
480 | .remove = pci_epf_test_remove, | ||
481 | .id_table = pci_epf_test_ids, | 508 | .id_table = pci_epf_test_ids, |
482 | .ops = &ops, | 509 | .ops = &ops, |
483 | .owner = THIS_MODULE, | 510 | .owner = THIS_MODULE, |
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c index caa7be10e473..42c2a1156325 100644 --- a/drivers/pci/endpoint/pci-epc-core.c +++ b/drivers/pci/endpoint/pci-epc-core.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/dma-mapping.h> | 21 | #include <linux/dma-mapping.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/of_device.h> | ||
24 | 25 | ||
25 | #include <linux/pci-epc.h> | 26 | #include <linux/pci-epc.h> |
26 | #include <linux/pci-epf.h> | 27 | #include <linux/pci-epf.h> |
@@ -370,6 +371,7 @@ EXPORT_SYMBOL_GPL(pci_epc_write_header); | |||
370 | int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf) | 371 | int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf) |
371 | { | 372 | { |
372 | unsigned long flags; | 373 | unsigned long flags; |
374 | struct device *dev = epc->dev.parent; | ||
373 | 375 | ||
374 | if (epf->epc) | 376 | if (epf->epc) |
375 | return -EBUSY; | 377 | return -EBUSY; |
@@ -381,8 +383,12 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf) | |||
381 | return -EINVAL; | 383 | return -EINVAL; |
382 | 384 | ||
383 | epf->epc = epc; | 385 | epf->epc = epc; |
384 | dma_set_coherent_mask(&epf->dev, epc->dev.coherent_dma_mask); | 386 | if (dev->of_node) { |
385 | epf->dev.dma_mask = epc->dev.dma_mask; | 387 | of_dma_configure(&epf->dev, dev->of_node); |
388 | } else { | ||
389 | dma_set_coherent_mask(&epf->dev, epc->dev.coherent_dma_mask); | ||
390 | epf->dev.dma_mask = epc->dev.dma_mask; | ||
391 | } | ||
386 | 392 | ||
387 | spin_lock_irqsave(&epc->lock, flags); | 393 | spin_lock_irqsave(&epc->lock, flags); |
388 | list_add_tail(&epf->list, &epc->pci_epf); | 394 | list_add_tail(&epf->list, &epc->pci_epf); |
@@ -500,6 +506,7 @@ __pci_epc_create(struct device *dev, const struct pci_epc_ops *ops, | |||
500 | dma_set_coherent_mask(&epc->dev, dev->coherent_dma_mask); | 506 | dma_set_coherent_mask(&epc->dev, dev->coherent_dma_mask); |
501 | epc->dev.class = pci_epc_class; | 507 | epc->dev.class = pci_epc_class; |
502 | epc->dev.dma_mask = dev->dma_mask; | 508 | epc->dev.dma_mask = dev->dma_mask; |
509 | epc->dev.parent = dev; | ||
503 | epc->ops = ops; | 510 | epc->ops = ops; |
504 | 511 | ||
505 | ret = dev_set_name(&epc->dev, "%s", dev_name(dev)); | 512 | ret = dev_set_name(&epc->dev, "%s", dev_name(dev)); |
diff --git a/drivers/pci/endpoint/pci-epc-mem.c b/drivers/pci/endpoint/pci-epc-mem.c index 3a94cc1caf22..83b7d5d3fc3e 100644 --- a/drivers/pci/endpoint/pci-epc-mem.c +++ b/drivers/pci/endpoint/pci-epc-mem.c | |||
@@ -24,21 +24,54 @@ | |||
24 | #include <linux/pci-epc.h> | 24 | #include <linux/pci-epc.h> |
25 | 25 | ||
26 | /** | 26 | /** |
27 | * pci_epc_mem_init() - initialize the pci_epc_mem structure | 27 | * pci_epc_mem_get_order() - determine the allocation order of a memory size |
28 | * @mem: address space of the endpoint controller | ||
29 | * @size: the size for which to get the order | ||
30 | * | ||
31 | * Reimplement get_order() for mem->page_size since the generic get_order | ||
32 | * always gets order with a constant PAGE_SIZE. | ||
33 | */ | ||
34 | static int pci_epc_mem_get_order(struct pci_epc_mem *mem, size_t size) | ||
35 | { | ||
36 | int order; | ||
37 | unsigned int page_shift = ilog2(mem->page_size); | ||
38 | |||
39 | size--; | ||
40 | size >>= page_shift; | ||
41 | #if BITS_PER_LONG == 32 | ||
42 | order = fls(size); | ||
43 | #else | ||
44 | order = fls64(size); | ||
45 | #endif | ||
46 | return order; | ||
47 | } | ||
48 | |||
49 | /** | ||
50 | * __pci_epc_mem_init() - initialize the pci_epc_mem structure | ||
28 | * @epc: the EPC device that invoked pci_epc_mem_init | 51 | * @epc: the EPC device that invoked pci_epc_mem_init |
29 | * @phys_base: the physical address of the base | 52 | * @phys_base: the physical address of the base |
30 | * @size: the size of the address space | 53 | * @size: the size of the address space |
54 | * @page_size: size of each page | ||
31 | * | 55 | * |
32 | * Invoke to initialize the pci_epc_mem structure used by the | 56 | * Invoke to initialize the pci_epc_mem structure used by the |
33 | * endpoint functions to allocate mapped PCI address. | 57 | * endpoint functions to allocate mapped PCI address. |
34 | */ | 58 | */ |
35 | int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base, size_t size) | 59 | int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base, size_t size, |
60 | size_t page_size) | ||
36 | { | 61 | { |
37 | int ret; | 62 | int ret; |
38 | struct pci_epc_mem *mem; | 63 | struct pci_epc_mem *mem; |
39 | unsigned long *bitmap; | 64 | unsigned long *bitmap; |
40 | int pages = size >> PAGE_SHIFT; | 65 | unsigned int page_shift; |
41 | int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); | 66 | int pages; |
67 | int bitmap_size; | ||
68 | |||
69 | if (page_size < PAGE_SIZE) | ||
70 | page_size = PAGE_SIZE; | ||
71 | |||
72 | page_shift = ilog2(page_size); | ||
73 | pages = size >> page_shift; | ||
74 | bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); | ||
42 | 75 | ||
43 | mem = kzalloc(sizeof(*mem), GFP_KERNEL); | 76 | mem = kzalloc(sizeof(*mem), GFP_KERNEL); |
44 | if (!mem) { | 77 | if (!mem) { |
@@ -54,6 +87,7 @@ int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base, size_t size) | |||
54 | 87 | ||
55 | mem->bitmap = bitmap; | 88 | mem->bitmap = bitmap; |
56 | mem->phys_base = phys_base; | 89 | mem->phys_base = phys_base; |
90 | mem->page_size = page_size; | ||
57 | mem->pages = pages; | 91 | mem->pages = pages; |
58 | mem->size = size; | 92 | mem->size = size; |
59 | 93 | ||
@@ -67,7 +101,7 @@ err_mem: | |||
67 | err: | 101 | err: |
68 | return ret; | 102 | return ret; |
69 | } | 103 | } |
70 | EXPORT_SYMBOL_GPL(pci_epc_mem_init); | 104 | EXPORT_SYMBOL_GPL(__pci_epc_mem_init); |
71 | 105 | ||
72 | /** | 106 | /** |
73 | * pci_epc_mem_exit() - cleanup the pci_epc_mem structure | 107 | * pci_epc_mem_exit() - cleanup the pci_epc_mem structure |
@@ -101,13 +135,17 @@ void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc, | |||
101 | int pageno; | 135 | int pageno; |
102 | void __iomem *virt_addr; | 136 | void __iomem *virt_addr; |
103 | struct pci_epc_mem *mem = epc->mem; | 137 | struct pci_epc_mem *mem = epc->mem; |
104 | int order = get_order(size); | 138 | unsigned int page_shift = ilog2(mem->page_size); |
139 | int order; | ||
140 | |||
141 | size = ALIGN(size, mem->page_size); | ||
142 | order = pci_epc_mem_get_order(mem, size); | ||
105 | 143 | ||
106 | pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order); | 144 | pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order); |
107 | if (pageno < 0) | 145 | if (pageno < 0) |
108 | return NULL; | 146 | return NULL; |
109 | 147 | ||
110 | *phys_addr = mem->phys_base + (pageno << PAGE_SHIFT); | 148 | *phys_addr = mem->phys_base + (pageno << page_shift); |
111 | virt_addr = ioremap(*phys_addr, size); | 149 | virt_addr = ioremap(*phys_addr, size); |
112 | if (!virt_addr) | 150 | if (!virt_addr) |
113 | bitmap_release_region(mem->bitmap, pageno, order); | 151 | bitmap_release_region(mem->bitmap, pageno, order); |
@@ -129,11 +167,14 @@ void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr, | |||
129 | void __iomem *virt_addr, size_t size) | 167 | void __iomem *virt_addr, size_t size) |
130 | { | 168 | { |
131 | int pageno; | 169 | int pageno; |
132 | int order = get_order(size); | ||
133 | struct pci_epc_mem *mem = epc->mem; | 170 | struct pci_epc_mem *mem = epc->mem; |
171 | unsigned int page_shift = ilog2(mem->page_size); | ||
172 | int order; | ||
134 | 173 | ||
135 | iounmap(virt_addr); | 174 | iounmap(virt_addr); |
136 | pageno = (phys_addr - mem->phys_base) >> PAGE_SHIFT; | 175 | pageno = (phys_addr - mem->phys_base) >> page_shift; |
176 | size = ALIGN(size, mem->page_size); | ||
177 | order = pci_epc_mem_get_order(mem, size); | ||
137 | bitmap_release_region(mem->bitmap, pageno, order); | 178 | bitmap_release_region(mem->bitmap, pageno, order); |
138 | } | 179 | } |
139 | EXPORT_SYMBOL_GPL(pci_epc_mem_free_addr); | 180 | EXPORT_SYMBOL_GPL(pci_epc_mem_free_addr); |
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c index 6877d6a5bcc9..ae1611a62808 100644 --- a/drivers/pci/endpoint/pci-epf-core.c +++ b/drivers/pci/endpoint/pci-epf-core.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/pci-ep-cfs.h> | 27 | #include <linux/pci-ep-cfs.h> |
28 | 28 | ||
29 | static struct bus_type pci_epf_bus_type; | 29 | static struct bus_type pci_epf_bus_type; |
30 | static struct device_type pci_epf_type; | 30 | static const struct device_type pci_epf_type; |
31 | 31 | ||
32 | /** | 32 | /** |
33 | * pci_epf_linkup() - Notify the function driver that EPC device has | 33 | * pci_epf_linkup() - Notify the function driver that EPC device has |
@@ -267,6 +267,22 @@ err_ret: | |||
267 | } | 267 | } |
268 | EXPORT_SYMBOL_GPL(pci_epf_create); | 268 | EXPORT_SYMBOL_GPL(pci_epf_create); |
269 | 269 | ||
270 | const struct pci_epf_device_id * | ||
271 | pci_epf_match_device(const struct pci_epf_device_id *id, struct pci_epf *epf) | ||
272 | { | ||
273 | if (!id || !epf) | ||
274 | return NULL; | ||
275 | |||
276 | while (*id->name) { | ||
277 | if (strcmp(epf->name, id->name) == 0) | ||
278 | return id; | ||
279 | id++; | ||
280 | } | ||
281 | |||
282 | return NULL; | ||
283 | } | ||
284 | EXPORT_SYMBOL_GPL(pci_epf_match_device); | ||
285 | |||
270 | static void pci_epf_dev_release(struct device *dev) | 286 | static void pci_epf_dev_release(struct device *dev) |
271 | { | 287 | { |
272 | struct pci_epf *epf = to_pci_epf(dev); | 288 | struct pci_epf *epf = to_pci_epf(dev); |
@@ -275,7 +291,7 @@ static void pci_epf_dev_release(struct device *dev) | |||
275 | kfree(epf); | 291 | kfree(epf); |
276 | } | 292 | } |
277 | 293 | ||
278 | static struct device_type pci_epf_type = { | 294 | static const struct device_type pci_epf_type = { |
279 | .release = pci_epf_dev_release, | 295 | .release = pci_epf_dev_release, |
280 | }; | 296 | }; |
281 | 297 | ||
@@ -317,11 +333,12 @@ static int pci_epf_device_probe(struct device *dev) | |||
317 | 333 | ||
318 | static int pci_epf_device_remove(struct device *dev) | 334 | static int pci_epf_device_remove(struct device *dev) |
319 | { | 335 | { |
320 | int ret; | 336 | int ret = 0; |
321 | struct pci_epf *epf = to_pci_epf(dev); | 337 | struct pci_epf *epf = to_pci_epf(dev); |
322 | struct pci_epf_driver *driver = to_pci_epf_driver(dev->driver); | 338 | struct pci_epf_driver *driver = to_pci_epf_driver(dev->driver); |
323 | 339 | ||
324 | ret = driver->remove(epf); | 340 | if (driver->remove) |
341 | ret = driver->remove(epf); | ||
325 | epf->driver = NULL; | 342 | epf->driver = NULL; |
326 | 343 | ||
327 | return ret; | 344 | return ret; |
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 89d61c2cbfaa..b868803792d8 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig | |||
@@ -71,7 +71,7 @@ config PCI_HOST_GENERIC | |||
71 | 71 | ||
72 | config PCIE_XILINX | 72 | config PCIE_XILINX |
73 | bool "Xilinx AXI PCIe host bridge support" | 73 | bool "Xilinx AXI PCIe host bridge support" |
74 | depends on ARCH_ZYNQ || MICROBLAZE | 74 | depends on ARCH_ZYNQ || MICROBLAZE || (MIPS && PCI_DRIVERS_GENERIC) |
75 | help | 75 | help |
76 | Say 'Y' here if you want kernel to support the Xilinx AXI PCIe | 76 | Say 'Y' here if you want kernel to support the Xilinx AXI PCIe |
77 | Host Bridge driver. | 77 | Host Bridge driver. |
@@ -182,14 +182,13 @@ config PCIE_ROCKCHIP | |||
182 | 182 | ||
183 | config PCIE_MEDIATEK | 183 | config PCIE_MEDIATEK |
184 | bool "MediaTek PCIe controller" | 184 | bool "MediaTek PCIe controller" |
185 | depends on ARM && (ARCH_MEDIATEK || COMPILE_TEST) | 185 | depends on (ARM || ARM64) && (ARCH_MEDIATEK || COMPILE_TEST) |
186 | depends on OF | 186 | depends on OF |
187 | depends on PCI | 187 | depends on PCI |
188 | select PCIEPORTBUS | 188 | select PCIEPORTBUS |
189 | help | 189 | help |
190 | Say Y here if you want to enable PCIe controller support on | 190 | Say Y here if you want to enable PCIe controller support on |
191 | MT7623 series SoCs. There is one single root complex with 3 root | 191 | MediaTek SoCs. |
192 | ports available. Each port supports Gen2 lane x1. | ||
193 | 192 | ||
194 | config PCIE_TANGO_SMP8759 | 193 | config PCIE_TANGO_SMP8759 |
195 | bool "Tango SMP8759 PCIe controller (DANGEROUS)" | 194 | bool "Tango SMP8759 PCIe controller (DANGEROUS)" |
diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c index 5fb9b620ac78..89f4e3d072d7 100644 --- a/drivers/pci/host/pci-aardvark.c +++ b/drivers/pci/host/pci-aardvark.c | |||
@@ -191,7 +191,6 @@ | |||
191 | #define LINK_WAIT_USLEEP_MIN 90000 | 191 | #define LINK_WAIT_USLEEP_MIN 90000 |
192 | #define LINK_WAIT_USLEEP_MAX 100000 | 192 | #define LINK_WAIT_USLEEP_MAX 100000 |
193 | 193 | ||
194 | #define LEGACY_IRQ_NUM 4 | ||
195 | #define MSI_IRQ_NUM 32 | 194 | #define MSI_IRQ_NUM 32 |
196 | 195 | ||
197 | struct advk_pcie { | 196 | struct advk_pcie { |
@@ -729,7 +728,7 @@ static int advk_pcie_init_irq_domain(struct advk_pcie *pcie) | |||
729 | irq_chip->irq_unmask = advk_pcie_irq_unmask; | 728 | irq_chip->irq_unmask = advk_pcie_irq_unmask; |
730 | 729 | ||
731 | pcie->irq_domain = | 730 | pcie->irq_domain = |
732 | irq_domain_add_linear(pcie_intc_node, LEGACY_IRQ_NUM, | 731 | irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, |
733 | &advk_pcie_irq_domain_ops, pcie); | 732 | &advk_pcie_irq_domain_ops, pcie); |
734 | if (!pcie->irq_domain) { | 733 | if (!pcie->irq_domain) { |
735 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); | 734 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); |
@@ -786,7 +785,7 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie) | |||
786 | advk_pcie_handle_msi(pcie); | 785 | advk_pcie_handle_msi(pcie); |
787 | 786 | ||
788 | /* Process legacy interrupts */ | 787 | /* Process legacy interrupts */ |
789 | for (i = 0; i < LEGACY_IRQ_NUM; i++) { | 788 | for (i = 0; i < PCI_NUM_INTX; i++) { |
790 | if (!(status & PCIE_ISR0_INTX_ASSERT(i))) | 789 | if (!(status & PCIE_ISR0_INTX_ASSERT(i))) |
791 | continue; | 790 | continue; |
792 | 791 | ||
diff --git a/drivers/pci/host/pci-ftpci100.c b/drivers/pci/host/pci-ftpci100.c index 5162dffc102b..96028f01bc90 100644 --- a/drivers/pci/host/pci-ftpci100.c +++ b/drivers/pci/host/pci-ftpci100.c | |||
@@ -350,12 +350,12 @@ static int faraday_pci_setup_cascaded_irq(struct faraday_pci *p) | |||
350 | 350 | ||
351 | /* All PCI IRQs cascade off this one */ | 351 | /* All PCI IRQs cascade off this one */ |
352 | irq = of_irq_get(intc, 0); | 352 | irq = of_irq_get(intc, 0); |
353 | if (!irq) { | 353 | if (irq <= 0) { |
354 | dev_err(p->dev, "failed to get parent IRQ\n"); | 354 | dev_err(p->dev, "failed to get parent IRQ\n"); |
355 | return -EINVAL; | 355 | return irq ?: -EINVAL; |
356 | } | 356 | } |
357 | 357 | ||
358 | p->irqdomain = irq_domain_add_linear(intc, 4, | 358 | p->irqdomain = irq_domain_add_linear(intc, PCI_NUM_INTX, |
359 | &faraday_pci_irqdomain_ops, p); | 359 | &faraday_pci_irqdomain_ops, p); |
360 | if (!p->irqdomain) { | 360 | if (!p->irqdomain) { |
361 | dev_err(p->dev, "failed to create Gemini PCI IRQ domain\n"); | 361 | dev_err(p->dev, "failed to create Gemini PCI IRQ domain\n"); |
diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c index aba041438566..0fe3ea164ee5 100644 --- a/drivers/pci/host/pci-hyperv.c +++ b/drivers/pci/host/pci-hyperv.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <linux/kernel.h> | 50 | #include <linux/kernel.h> |
51 | #include <linux/module.h> | 51 | #include <linux/module.h> |
52 | #include <linux/pci.h> | 52 | #include <linux/pci.h> |
53 | #include <linux/delay.h> | ||
53 | #include <linux/semaphore.h> | 54 | #include <linux/semaphore.h> |
54 | #include <linux/irqdomain.h> | 55 | #include <linux/irqdomain.h> |
55 | #include <asm/irqdomain.h> | 56 | #include <asm/irqdomain.h> |
@@ -1113,7 +1114,12 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) | |||
1113 | goto free_int_desc; | 1114 | goto free_int_desc; |
1114 | } | 1115 | } |
1115 | 1116 | ||
1116 | wait_for_completion(&comp.comp_pkt.host_event); | 1117 | /* |
1118 | * Since this function is called with IRQ locks held, can't | ||
1119 | * do normal wait for completion; instead poll. | ||
1120 | */ | ||
1121 | while (!try_wait_for_completion(&comp.comp_pkt.host_event)) | ||
1122 | udelay(100); | ||
1117 | 1123 | ||
1118 | if (comp.comp_pkt.completion_status < 0) { | 1124 | if (comp.comp_pkt.completion_status < 0) { |
1119 | dev_err(&hbus->hdev->device, | 1125 | dev_err(&hbus->hdev->device, |
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index f353a6eb2f01..8d88f19dc171 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
@@ -1054,8 +1054,8 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie, | |||
1054 | port->pcie = pcie; | 1054 | port->pcie = pcie; |
1055 | 1055 | ||
1056 | if (of_property_read_u32(child, "marvell,pcie-port", &port->port)) { | 1056 | if (of_property_read_u32(child, "marvell,pcie-port", &port->port)) { |
1057 | dev_warn(dev, "ignoring %s, missing pcie-port property\n", | 1057 | dev_warn(dev, "ignoring %pOF, missing pcie-port property\n", |
1058 | of_node_full_name(child)); | 1058 | child); |
1059 | goto skip; | 1059 | goto skip; |
1060 | } | 1060 | } |
1061 | 1061 | ||
@@ -1106,8 +1106,8 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie, | |||
1106 | } | 1106 | } |
1107 | 1107 | ||
1108 | if (flags & OF_GPIO_ACTIVE_LOW) { | 1108 | if (flags & OF_GPIO_ACTIVE_LOW) { |
1109 | dev_info(dev, "%s: reset gpio is active low\n", | 1109 | dev_info(dev, "%pOF: reset gpio is active low\n", |
1110 | of_node_full_name(child)); | 1110 | child); |
1111 | gpio_flags = GPIOF_ACTIVE_LOW | | 1111 | gpio_flags = GPIOF_ACTIVE_LOW | |
1112 | GPIOF_OUT_INIT_LOW; | 1112 | GPIOF_OUT_INIT_LOW; |
1113 | } else { | 1113 | } else { |
@@ -1186,8 +1186,7 @@ static int mvebu_pcie_powerup(struct mvebu_pcie_port *port) | |||
1186 | */ | 1186 | */ |
1187 | static void mvebu_pcie_powerdown(struct mvebu_pcie_port *port) | 1187 | static void mvebu_pcie_powerdown(struct mvebu_pcie_port *port) |
1188 | { | 1188 | { |
1189 | if (port->reset_gpio) | 1189 | gpiod_set_value_cansleep(port->reset_gpio, 1); |
1190 | gpiod_set_value_cansleep(port->reset_gpio, 1); | ||
1191 | 1190 | ||
1192 | clk_disable_unprepare(port->clk); | 1191 | clk_disable_unprepare(port->clk); |
1193 | } | 1192 | } |
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index b3722b7709df..9c40da54f88a 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
@@ -1147,15 +1147,15 @@ static int tegra_pcie_resets_get(struct tegra_pcie *pcie) | |||
1147 | { | 1147 | { |
1148 | struct device *dev = pcie->dev; | 1148 | struct device *dev = pcie->dev; |
1149 | 1149 | ||
1150 | pcie->pex_rst = devm_reset_control_get(dev, "pex"); | 1150 | pcie->pex_rst = devm_reset_control_get_exclusive(dev, "pex"); |
1151 | if (IS_ERR(pcie->pex_rst)) | 1151 | if (IS_ERR(pcie->pex_rst)) |
1152 | return PTR_ERR(pcie->pex_rst); | 1152 | return PTR_ERR(pcie->pex_rst); |
1153 | 1153 | ||
1154 | pcie->afi_rst = devm_reset_control_get(dev, "afi"); | 1154 | pcie->afi_rst = devm_reset_control_get_exclusive(dev, "afi"); |
1155 | if (IS_ERR(pcie->afi_rst)) | 1155 | if (IS_ERR(pcie->afi_rst)) |
1156 | return PTR_ERR(pcie->afi_rst); | 1156 | return PTR_ERR(pcie->afi_rst); |
1157 | 1157 | ||
1158 | pcie->pcie_xrst = devm_reset_control_get(dev, "pcie_x"); | 1158 | pcie->pcie_xrst = devm_reset_control_get_exclusive(dev, "pcie_x"); |
1159 | if (IS_ERR(pcie->pcie_xrst)) | 1159 | if (IS_ERR(pcie->pcie_xrst)) |
1160 | return PTR_ERR(pcie->pcie_xrst); | 1160 | return PTR_ERR(pcie->pcie_xrst); |
1161 | 1161 | ||
@@ -1703,8 +1703,7 @@ static int tegra_pcie_get_legacy_regulators(struct tegra_pcie *pcie) | |||
1703 | pcie->num_supplies = 2; | 1703 | pcie->num_supplies = 2; |
1704 | 1704 | ||
1705 | if (pcie->num_supplies == 0) { | 1705 | if (pcie->num_supplies == 0) { |
1706 | dev_err(dev, "device %s not supported in legacy mode\n", | 1706 | dev_err(dev, "device %pOF not supported in legacy mode\n", np); |
1707 | np->full_name); | ||
1708 | return -ENODEV; | 1707 | return -ENODEV; |
1709 | } | 1708 | } |
1710 | 1709 | ||
diff --git a/drivers/pci/host/pci-xgene-msi.c b/drivers/pci/host/pci-xgene-msi.c index f1b633bce525..1f42a202b021 100644 --- a/drivers/pci/host/pci-xgene-msi.c +++ b/drivers/pci/host/pci-xgene-msi.c | |||
@@ -489,7 +489,7 @@ static int xgene_msi_probe(struct platform_device *pdev) | |||
489 | if (virt_msir < 0) { | 489 | if (virt_msir < 0) { |
490 | dev_err(&pdev->dev, "Cannot translate IRQ index %d\n", | 490 | dev_err(&pdev->dev, "Cannot translate IRQ index %d\n", |
491 | irq_index); | 491 | irq_index); |
492 | rc = -EINVAL; | 492 | rc = virt_msir; |
493 | goto error; | 493 | goto error; |
494 | } | 494 | } |
495 | xgene_msi->msi_groups[irq_index].gic_irq = virt_msir; | 495 | xgene_msi->msi_groups[irq_index].gic_irq = virt_msir; |
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c index bd897479a215..087645116ecb 100644 --- a/drivers/pci/host/pci-xgene.c +++ b/drivers/pci/host/pci-xgene.c | |||
@@ -61,7 +61,7 @@ | |||
61 | #define SZ_1T (SZ_1G*1024ULL) | 61 | #define SZ_1T (SZ_1G*1024ULL) |
62 | #define PIPE_PHY_RATE_RD(src) ((0xc000 & (u32)(src)) >> 0xe) | 62 | #define PIPE_PHY_RATE_RD(src) ((0xc000 & (u32)(src)) >> 0xe) |
63 | 63 | ||
64 | #define ROOT_CAP_AND_CTRL 0x5C | 64 | #define XGENE_V1_PCI_EXP_CAP 0x40 |
65 | 65 | ||
66 | /* PCIe IP version */ | 66 | /* PCIe IP version */ |
67 | #define XGENE_PCIE_IP_VER_UNKN 0 | 67 | #define XGENE_PCIE_IP_VER_UNKN 0 |
@@ -160,7 +160,7 @@ static bool xgene_pcie_hide_rc_bars(struct pci_bus *bus, int offset) | |||
160 | } | 160 | } |
161 | 161 | ||
162 | static void __iomem *xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, | 162 | static void __iomem *xgene_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, |
163 | int offset) | 163 | int offset) |
164 | { | 164 | { |
165 | if ((pci_is_root_bus(bus) && devfn != 0) || | 165 | if ((pci_is_root_bus(bus) && devfn != 0) || |
166 | xgene_pcie_hide_rc_bars(bus, offset)) | 166 | xgene_pcie_hide_rc_bars(bus, offset)) |
@@ -189,7 +189,7 @@ static int xgene_pcie_config_read32(struct pci_bus *bus, unsigned int devfn, | |||
189 | * Avoid this by not claiming to support CRS. | 189 | * Avoid this by not claiming to support CRS. |
190 | */ | 190 | */ |
191 | if (pci_is_root_bus(bus) && (port->version == XGENE_PCIE_IP_VER_1) && | 191 | if (pci_is_root_bus(bus) && (port->version == XGENE_PCIE_IP_VER_1) && |
192 | ((where & ~0x3) == ROOT_CAP_AND_CTRL)) | 192 | ((where & ~0x3) == XGENE_V1_PCI_EXP_CAP + PCI_EXP_RTCTL)) |
193 | *val &= ~(PCI_EXP_RTCAP_CRSVIS << 16); | 193 | *val &= ~(PCI_EXP_RTCAP_CRSVIS << 16); |
194 | 194 | ||
195 | if (size <= 2) | 195 | if (size <= 2) |
@@ -265,12 +265,12 @@ static int xgene_v1_pcie_ecam_init(struct pci_config_window *cfg) | |||
265 | } | 265 | } |
266 | 266 | ||
267 | struct pci_ecam_ops xgene_v1_pcie_ecam_ops = { | 267 | struct pci_ecam_ops xgene_v1_pcie_ecam_ops = { |
268 | .bus_shift = 16, | 268 | .bus_shift = 16, |
269 | .init = xgene_v1_pcie_ecam_init, | 269 | .init = xgene_v1_pcie_ecam_init, |
270 | .pci_ops = { | 270 | .pci_ops = { |
271 | .map_bus = xgene_pcie_map_bus, | 271 | .map_bus = xgene_pcie_map_bus, |
272 | .read = xgene_pcie_config_read32, | 272 | .read = xgene_pcie_config_read32, |
273 | .write = pci_generic_config_write, | 273 | .write = pci_generic_config_write, |
274 | } | 274 | } |
275 | }; | 275 | }; |
276 | 276 | ||
@@ -280,12 +280,12 @@ static int xgene_v2_pcie_ecam_init(struct pci_config_window *cfg) | |||
280 | } | 280 | } |
281 | 281 | ||
282 | struct pci_ecam_ops xgene_v2_pcie_ecam_ops = { | 282 | struct pci_ecam_ops xgene_v2_pcie_ecam_ops = { |
283 | .bus_shift = 16, | 283 | .bus_shift = 16, |
284 | .init = xgene_v2_pcie_ecam_init, | 284 | .init = xgene_v2_pcie_ecam_init, |
285 | .pci_ops = { | 285 | .pci_ops = { |
286 | .map_bus = xgene_pcie_map_bus, | 286 | .map_bus = xgene_pcie_map_bus, |
287 | .read = xgene_pcie_config_read32, | 287 | .read = xgene_pcie_config_read32, |
288 | .write = pci_generic_config_write, | 288 | .write = pci_generic_config_write, |
289 | } | 289 | } |
290 | }; | 290 | }; |
291 | #endif | 291 | #endif |
@@ -318,7 +318,7 @@ static u64 xgene_pcie_set_ib_mask(struct xgene_pcie_port *port, u32 addr, | |||
318 | } | 318 | } |
319 | 319 | ||
320 | static void xgene_pcie_linkup(struct xgene_pcie_port *port, | 320 | static void xgene_pcie_linkup(struct xgene_pcie_port *port, |
321 | u32 *lanes, u32 *speed) | 321 | u32 *lanes, u32 *speed) |
322 | { | 322 | { |
323 | u32 val32; | 323 | u32 val32; |
324 | 324 | ||
@@ -593,8 +593,7 @@ static void xgene_pcie_clear_config(struct xgene_pcie_port *port) | |||
593 | xgene_pcie_writel(port, i, 0); | 593 | xgene_pcie_writel(port, i, 0); |
594 | } | 594 | } |
595 | 595 | ||
596 | static int xgene_pcie_setup(struct xgene_pcie_port *port, | 596 | static int xgene_pcie_setup(struct xgene_pcie_port *port, struct list_head *res, |
597 | struct list_head *res, | ||
598 | resource_size_t io_base) | 597 | resource_size_t io_base) |
599 | { | 598 | { |
600 | struct device *dev = port->dev; | 599 | struct device *dev = port->dev; |
@@ -706,9 +705,9 @@ static const struct of_device_id xgene_pcie_match_table[] = { | |||
706 | 705 | ||
707 | static struct platform_driver xgene_pcie_driver = { | 706 | static struct platform_driver xgene_pcie_driver = { |
708 | .driver = { | 707 | .driver = { |
709 | .name = "xgene-pcie", | 708 | .name = "xgene-pcie", |
710 | .of_match_table = of_match_ptr(xgene_pcie_match_table), | 709 | .of_match_table = of_match_ptr(xgene_pcie_match_table), |
711 | .suppress_bind_attrs = true, | 710 | .suppress_bind_attrs = true, |
712 | }, | 711 | }, |
713 | .probe = xgene_pcie_probe_bridge, | 712 | .probe = xgene_pcie_probe_bridge, |
714 | }; | 713 | }; |
diff --git a/drivers/pci/host/pcie-altera-msi.c b/drivers/pci/host/pcie-altera-msi.c index 4e5d628e8cd4..d8141f4865de 100644 --- a/drivers/pci/host/pcie-altera-msi.c +++ b/drivers/pci/host/pcie-altera-msi.c | |||
@@ -64,13 +64,11 @@ static void altera_msi_isr(struct irq_desc *desc) | |||
64 | struct irq_chip *chip = irq_desc_get_chip(desc); | 64 | struct irq_chip *chip = irq_desc_get_chip(desc); |
65 | struct altera_msi *msi; | 65 | struct altera_msi *msi; |
66 | unsigned long status; | 66 | unsigned long status; |
67 | u32 num_of_vectors; | ||
68 | u32 bit; | 67 | u32 bit; |
69 | u32 virq; | 68 | u32 virq; |
70 | 69 | ||
71 | chained_irq_enter(chip, desc); | 70 | chained_irq_enter(chip, desc); |
72 | msi = irq_desc_get_handler_data(desc); | 71 | msi = irq_desc_get_handler_data(desc); |
73 | num_of_vectors = msi->num_of_vectors; | ||
74 | 72 | ||
75 | while ((status = msi_readl(msi, MSI_STATUS)) != 0) { | 73 | while ((status = msi_readl(msi, MSI_STATUS)) != 0) { |
76 | for_each_set_bit(bit, &status, msi->num_of_vectors) { | 74 | for_each_set_bit(bit, &status, msi->num_of_vectors) { |
@@ -267,9 +265,9 @@ static int altera_msi_probe(struct platform_device *pdev) | |||
267 | return ret; | 265 | return ret; |
268 | 266 | ||
269 | msi->irq = platform_get_irq(pdev, 0); | 267 | msi->irq = platform_get_irq(pdev, 0); |
270 | if (msi->irq <= 0) { | 268 | if (msi->irq < 0) { |
271 | dev_err(&pdev->dev, "failed to map IRQ: %d\n", msi->irq); | 269 | dev_err(&pdev->dev, "failed to map IRQ: %d\n", msi->irq); |
272 | ret = -ENODEV; | 270 | ret = msi->irq; |
273 | goto err; | 271 | goto err; |
274 | } | 272 | } |
275 | 273 | ||
diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c index 4ea4f8f5dc77..b468b8cccf8d 100644 --- a/drivers/pci/host/pcie-altera.c +++ b/drivers/pci/host/pcie-altera.c | |||
@@ -76,8 +76,6 @@ | |||
76 | #define LINK_UP_TIMEOUT HZ | 76 | #define LINK_UP_TIMEOUT HZ |
77 | #define LINK_RETRAIN_TIMEOUT HZ | 77 | #define LINK_RETRAIN_TIMEOUT HZ |
78 | 78 | ||
79 | #define INTX_NUM 4 | ||
80 | |||
81 | #define DWORD_MASK 3 | 79 | #define DWORD_MASK 3 |
82 | 80 | ||
83 | struct altera_pcie { | 81 | struct altera_pcie { |
@@ -464,6 +462,7 @@ static int altera_pcie_intx_map(struct irq_domain *domain, unsigned int irq, | |||
464 | 462 | ||
465 | static const struct irq_domain_ops intx_domain_ops = { | 463 | static const struct irq_domain_ops intx_domain_ops = { |
466 | .map = altera_pcie_intx_map, | 464 | .map = altera_pcie_intx_map, |
465 | .xlate = pci_irqd_intx_xlate, | ||
467 | }; | 466 | }; |
468 | 467 | ||
469 | static void altera_pcie_isr(struct irq_desc *desc) | 468 | static void altera_pcie_isr(struct irq_desc *desc) |
@@ -481,11 +480,11 @@ static void altera_pcie_isr(struct irq_desc *desc) | |||
481 | 480 | ||
482 | while ((status = cra_readl(pcie, P2A_INT_STATUS) | 481 | while ((status = cra_readl(pcie, P2A_INT_STATUS) |
483 | & P2A_INT_STS_ALL) != 0) { | 482 | & P2A_INT_STS_ALL) != 0) { |
484 | for_each_set_bit(bit, &status, INTX_NUM) { | 483 | for_each_set_bit(bit, &status, PCI_NUM_INTX) { |
485 | /* clear interrupts */ | 484 | /* clear interrupts */ |
486 | cra_writel(pcie, 1 << bit, P2A_INT_STATUS); | 485 | cra_writel(pcie, 1 << bit, P2A_INT_STATUS); |
487 | 486 | ||
488 | virq = irq_find_mapping(pcie->irq_domain, bit + 1); | 487 | virq = irq_find_mapping(pcie->irq_domain, bit); |
489 | if (virq) | 488 | if (virq) |
490 | generic_handle_irq(virq); | 489 | generic_handle_irq(virq); |
491 | else | 490 | else |
@@ -536,7 +535,7 @@ static int altera_pcie_init_irq_domain(struct altera_pcie *pcie) | |||
536 | struct device_node *node = dev->of_node; | 535 | struct device_node *node = dev->of_node; |
537 | 536 | ||
538 | /* Setup INTx */ | 537 | /* Setup INTx */ |
539 | pcie->irq_domain = irq_domain_add_linear(node, INTX_NUM + 1, | 538 | pcie->irq_domain = irq_domain_add_linear(node, PCI_NUM_INTX, |
540 | &intx_domain_ops, pcie); | 539 | &intx_domain_ops, pcie); |
541 | if (!pcie->irq_domain) { | 540 | if (!pcie->irq_domain) { |
542 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); | 541 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); |
@@ -559,9 +558,9 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie) | |||
559 | 558 | ||
560 | /* setup IRQ */ | 559 | /* setup IRQ */ |
561 | pcie->irq = platform_get_irq(pdev, 0); | 560 | pcie->irq = platform_get_irq(pdev, 0); |
562 | if (pcie->irq <= 0) { | 561 | if (pcie->irq < 0) { |
563 | dev_err(dev, "failed to get IRQ: %d\n", pcie->irq); | 562 | dev_err(dev, "failed to get IRQ: %d\n", pcie->irq); |
564 | return -EINVAL; | 563 | return pcie->irq; |
565 | } | 564 | } |
566 | 565 | ||
567 | irq_set_chained_handler_and_data(pcie->irq, altera_pcie_isr, pcie); | 566 | irq_set_chained_handler_and_data(pcie->irq, altera_pcie_isr, pcie); |
diff --git a/drivers/pci/host/pcie-iproc-msi.c b/drivers/pci/host/pcie-iproc-msi.c index 9fad7915f82a..2d0f535a2f69 100644 --- a/drivers/pci/host/pcie-iproc-msi.c +++ b/drivers/pci/host/pcie-iproc-msi.c | |||
@@ -317,7 +317,6 @@ static void iproc_msi_handler(struct irq_desc *desc) | |||
317 | struct irq_chip *chip = irq_desc_get_chip(desc); | 317 | struct irq_chip *chip = irq_desc_get_chip(desc); |
318 | struct iproc_msi_grp *grp; | 318 | struct iproc_msi_grp *grp; |
319 | struct iproc_msi *msi; | 319 | struct iproc_msi *msi; |
320 | struct iproc_pcie *pcie; | ||
321 | u32 eq, head, tail, nr_events; | 320 | u32 eq, head, tail, nr_events; |
322 | unsigned long hwirq; | 321 | unsigned long hwirq; |
323 | int virq; | 322 | int virq; |
@@ -326,7 +325,6 @@ static void iproc_msi_handler(struct irq_desc *desc) | |||
326 | 325 | ||
327 | grp = irq_desc_get_handler_data(desc); | 326 | grp = irq_desc_get_handler_data(desc); |
328 | msi = grp->msi; | 327 | msi = grp->msi; |
329 | pcie = msi->pcie; | ||
330 | eq = grp->eq; | 328 | eq = grp->eq; |
331 | 329 | ||
332 | /* | 330 | /* |
diff --git a/drivers/pci/host/pcie-iproc-platform.c b/drivers/pci/host/pcie-iproc-platform.c index 22531190bc40..a5073a921a04 100644 --- a/drivers/pci/host/pcie-iproc-platform.c +++ b/drivers/pci/host/pcie-iproc-platform.c | |||
@@ -134,6 +134,13 @@ static int iproc_pcie_pltfm_remove(struct platform_device *pdev) | |||
134 | return iproc_pcie_remove(pcie); | 134 | return iproc_pcie_remove(pcie); |
135 | } | 135 | } |
136 | 136 | ||
137 | static void iproc_pcie_pltfm_shutdown(struct platform_device *pdev) | ||
138 | { | ||
139 | struct iproc_pcie *pcie = platform_get_drvdata(pdev); | ||
140 | |||
141 | iproc_pcie_shutdown(pcie); | ||
142 | } | ||
143 | |||
137 | static struct platform_driver iproc_pcie_pltfm_driver = { | 144 | static struct platform_driver iproc_pcie_pltfm_driver = { |
138 | .driver = { | 145 | .driver = { |
139 | .name = "iproc-pcie", | 146 | .name = "iproc-pcie", |
@@ -141,6 +148,7 @@ static struct platform_driver iproc_pcie_pltfm_driver = { | |||
141 | }, | 148 | }, |
142 | .probe = iproc_pcie_pltfm_probe, | 149 | .probe = iproc_pcie_pltfm_probe, |
143 | .remove = iproc_pcie_pltfm_remove, | 150 | .remove = iproc_pcie_pltfm_remove, |
151 | .shutdown = iproc_pcie_pltfm_shutdown, | ||
144 | }; | 152 | }; |
145 | module_platform_driver(iproc_pcie_pltfm_driver); | 153 | module_platform_driver(iproc_pcie_pltfm_driver); |
146 | 154 | ||
diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c index c57486348856..3a8b9d20ee57 100644 --- a/drivers/pci/host/pcie-iproc.c +++ b/drivers/pci/host/pcie-iproc.c | |||
@@ -31,68 +31,71 @@ | |||
31 | 31 | ||
32 | #include "pcie-iproc.h" | 32 | #include "pcie-iproc.h" |
33 | 33 | ||
34 | #define EP_PERST_SOURCE_SELECT_SHIFT 2 | 34 | #define EP_PERST_SOURCE_SELECT_SHIFT 2 |
35 | #define EP_PERST_SOURCE_SELECT BIT(EP_PERST_SOURCE_SELECT_SHIFT) | 35 | #define EP_PERST_SOURCE_SELECT BIT(EP_PERST_SOURCE_SELECT_SHIFT) |
36 | #define EP_MODE_SURVIVE_PERST_SHIFT 1 | 36 | #define EP_MODE_SURVIVE_PERST_SHIFT 1 |
37 | #define EP_MODE_SURVIVE_PERST BIT(EP_MODE_SURVIVE_PERST_SHIFT) | 37 | #define EP_MODE_SURVIVE_PERST BIT(EP_MODE_SURVIVE_PERST_SHIFT) |
38 | #define RC_PCIE_RST_OUTPUT_SHIFT 0 | 38 | #define RC_PCIE_RST_OUTPUT_SHIFT 0 |
39 | #define RC_PCIE_RST_OUTPUT BIT(RC_PCIE_RST_OUTPUT_SHIFT) | 39 | #define RC_PCIE_RST_OUTPUT BIT(RC_PCIE_RST_OUTPUT_SHIFT) |
40 | #define PAXC_RESET_MASK 0x7f | 40 | #define PAXC_RESET_MASK 0x7f |
41 | 41 | ||
42 | #define GIC_V3_CFG_SHIFT 0 | 42 | #define GIC_V3_CFG_SHIFT 0 |
43 | #define GIC_V3_CFG BIT(GIC_V3_CFG_SHIFT) | 43 | #define GIC_V3_CFG BIT(GIC_V3_CFG_SHIFT) |
44 | 44 | ||
45 | #define MSI_ENABLE_CFG_SHIFT 0 | 45 | #define MSI_ENABLE_CFG_SHIFT 0 |
46 | #define MSI_ENABLE_CFG BIT(MSI_ENABLE_CFG_SHIFT) | 46 | #define MSI_ENABLE_CFG BIT(MSI_ENABLE_CFG_SHIFT) |
47 | 47 | ||
48 | #define CFG_IND_ADDR_MASK 0x00001ffc | 48 | #define CFG_IND_ADDR_MASK 0x00001ffc |
49 | 49 | ||
50 | #define CFG_ADDR_BUS_NUM_SHIFT 20 | 50 | #define CFG_ADDR_BUS_NUM_SHIFT 20 |
51 | #define CFG_ADDR_BUS_NUM_MASK 0x0ff00000 | 51 | #define CFG_ADDR_BUS_NUM_MASK 0x0ff00000 |
52 | #define CFG_ADDR_DEV_NUM_SHIFT 15 | 52 | #define CFG_ADDR_DEV_NUM_SHIFT 15 |
53 | #define CFG_ADDR_DEV_NUM_MASK 0x000f8000 | 53 | #define CFG_ADDR_DEV_NUM_MASK 0x000f8000 |
54 | #define CFG_ADDR_FUNC_NUM_SHIFT 12 | 54 | #define CFG_ADDR_FUNC_NUM_SHIFT 12 |
55 | #define CFG_ADDR_FUNC_NUM_MASK 0x00007000 | 55 | #define CFG_ADDR_FUNC_NUM_MASK 0x00007000 |
56 | #define CFG_ADDR_REG_NUM_SHIFT 2 | 56 | #define CFG_ADDR_REG_NUM_SHIFT 2 |
57 | #define CFG_ADDR_REG_NUM_MASK 0x00000ffc | 57 | #define CFG_ADDR_REG_NUM_MASK 0x00000ffc |
58 | #define CFG_ADDR_CFG_TYPE_SHIFT 0 | 58 | #define CFG_ADDR_CFG_TYPE_SHIFT 0 |
59 | #define CFG_ADDR_CFG_TYPE_MASK 0x00000003 | 59 | #define CFG_ADDR_CFG_TYPE_MASK 0x00000003 |
60 | 60 | ||
61 | #define SYS_RC_INTX_MASK 0xf | 61 | #define SYS_RC_INTX_MASK 0xf |
62 | 62 | ||
63 | #define PCIE_PHYLINKUP_SHIFT 3 | 63 | #define PCIE_PHYLINKUP_SHIFT 3 |
64 | #define PCIE_PHYLINKUP BIT(PCIE_PHYLINKUP_SHIFT) | 64 | #define PCIE_PHYLINKUP BIT(PCIE_PHYLINKUP_SHIFT) |
65 | #define PCIE_DL_ACTIVE_SHIFT 2 | 65 | #define PCIE_DL_ACTIVE_SHIFT 2 |
66 | #define PCIE_DL_ACTIVE BIT(PCIE_DL_ACTIVE_SHIFT) | 66 | #define PCIE_DL_ACTIVE BIT(PCIE_DL_ACTIVE_SHIFT) |
67 | 67 | ||
68 | #define APB_ERR_EN_SHIFT 0 | 68 | #define APB_ERR_EN_SHIFT 0 |
69 | #define APB_ERR_EN BIT(APB_ERR_EN_SHIFT) | 69 | #define APB_ERR_EN BIT(APB_ERR_EN_SHIFT) |
70 | |||
71 | #define CFG_RETRY_STATUS 0xffff0001 | ||
72 | #define CFG_RETRY_STATUS_TIMEOUT_US 500000 /* 500 milliseconds */ | ||
70 | 73 | ||
71 | /* derive the enum index of the outbound/inbound mapping registers */ | 74 | /* derive the enum index of the outbound/inbound mapping registers */ |
72 | #define MAP_REG(base_reg, index) ((base_reg) + (index) * 2) | 75 | #define MAP_REG(base_reg, index) ((base_reg) + (index) * 2) |
73 | 76 | ||
74 | /* | 77 | /* |
75 | * Maximum number of outbound mapping window sizes that can be supported by any | 78 | * Maximum number of outbound mapping window sizes that can be supported by any |
76 | * OARR/OMAP mapping pair | 79 | * OARR/OMAP mapping pair |
77 | */ | 80 | */ |
78 | #define MAX_NUM_OB_WINDOW_SIZES 4 | 81 | #define MAX_NUM_OB_WINDOW_SIZES 4 |
79 | 82 | ||
80 | #define OARR_VALID_SHIFT 0 | 83 | #define OARR_VALID_SHIFT 0 |
81 | #define OARR_VALID BIT(OARR_VALID_SHIFT) | 84 | #define OARR_VALID BIT(OARR_VALID_SHIFT) |
82 | #define OARR_SIZE_CFG_SHIFT 1 | 85 | #define OARR_SIZE_CFG_SHIFT 1 |
83 | 86 | ||
84 | /* | 87 | /* |
85 | * Maximum number of inbound mapping region sizes that can be supported by an | 88 | * Maximum number of inbound mapping region sizes that can be supported by an |
86 | * IARR | 89 | * IARR |
87 | */ | 90 | */ |
88 | #define MAX_NUM_IB_REGION_SIZES 9 | 91 | #define MAX_NUM_IB_REGION_SIZES 9 |
89 | 92 | ||
90 | #define IMAP_VALID_SHIFT 0 | 93 | #define IMAP_VALID_SHIFT 0 |
91 | #define IMAP_VALID BIT(IMAP_VALID_SHIFT) | 94 | #define IMAP_VALID BIT(IMAP_VALID_SHIFT) |
92 | 95 | ||
93 | #define PCI_EXP_CAP 0xac | 96 | #define IPROC_PCI_EXP_CAP 0xac |
94 | 97 | ||
95 | #define IPROC_PCIE_REG_INVALID 0xffff | 98 | #define IPROC_PCIE_REG_INVALID 0xffff |
96 | 99 | ||
97 | /** | 100 | /** |
98 | * iProc PCIe outbound mapping controller specific parameters | 101 | * iProc PCIe outbound mapping controller specific parameters |
@@ -304,80 +307,80 @@ enum iproc_pcie_reg { | |||
304 | 307 | ||
305 | /* iProc PCIe PAXB BCMA registers */ | 308 | /* iProc PCIe PAXB BCMA registers */ |
306 | static const u16 iproc_pcie_reg_paxb_bcma[] = { | 309 | static const u16 iproc_pcie_reg_paxb_bcma[] = { |
307 | [IPROC_PCIE_CLK_CTRL] = 0x000, | 310 | [IPROC_PCIE_CLK_CTRL] = 0x000, |
308 | [IPROC_PCIE_CFG_IND_ADDR] = 0x120, | 311 | [IPROC_PCIE_CFG_IND_ADDR] = 0x120, |
309 | [IPROC_PCIE_CFG_IND_DATA] = 0x124, | 312 | [IPROC_PCIE_CFG_IND_DATA] = 0x124, |
310 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, | 313 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, |
311 | [IPROC_PCIE_CFG_DATA] = 0x1fc, | 314 | [IPROC_PCIE_CFG_DATA] = 0x1fc, |
312 | [IPROC_PCIE_INTX_EN] = 0x330, | 315 | [IPROC_PCIE_INTX_EN] = 0x330, |
313 | [IPROC_PCIE_LINK_STATUS] = 0xf0c, | 316 | [IPROC_PCIE_LINK_STATUS] = 0xf0c, |
314 | }; | 317 | }; |
315 | 318 | ||
316 | /* iProc PCIe PAXB registers */ | 319 | /* iProc PCIe PAXB registers */ |
317 | static const u16 iproc_pcie_reg_paxb[] = { | 320 | static const u16 iproc_pcie_reg_paxb[] = { |
318 | [IPROC_PCIE_CLK_CTRL] = 0x000, | 321 | [IPROC_PCIE_CLK_CTRL] = 0x000, |
319 | [IPROC_PCIE_CFG_IND_ADDR] = 0x120, | 322 | [IPROC_PCIE_CFG_IND_ADDR] = 0x120, |
320 | [IPROC_PCIE_CFG_IND_DATA] = 0x124, | 323 | [IPROC_PCIE_CFG_IND_DATA] = 0x124, |
321 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, | 324 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, |
322 | [IPROC_PCIE_CFG_DATA] = 0x1fc, | 325 | [IPROC_PCIE_CFG_DATA] = 0x1fc, |
323 | [IPROC_PCIE_INTX_EN] = 0x330, | 326 | [IPROC_PCIE_INTX_EN] = 0x330, |
324 | [IPROC_PCIE_OARR0] = 0xd20, | 327 | [IPROC_PCIE_OARR0] = 0xd20, |
325 | [IPROC_PCIE_OMAP0] = 0xd40, | 328 | [IPROC_PCIE_OMAP0] = 0xd40, |
326 | [IPROC_PCIE_OARR1] = 0xd28, | 329 | [IPROC_PCIE_OARR1] = 0xd28, |
327 | [IPROC_PCIE_OMAP1] = 0xd48, | 330 | [IPROC_PCIE_OMAP1] = 0xd48, |
328 | [IPROC_PCIE_LINK_STATUS] = 0xf0c, | 331 | [IPROC_PCIE_LINK_STATUS] = 0xf0c, |
329 | [IPROC_PCIE_APB_ERR_EN] = 0xf40, | 332 | [IPROC_PCIE_APB_ERR_EN] = 0xf40, |
330 | }; | 333 | }; |
331 | 334 | ||
332 | /* iProc PCIe PAXB v2 registers */ | 335 | /* iProc PCIe PAXB v2 registers */ |
333 | static const u16 iproc_pcie_reg_paxb_v2[] = { | 336 | static const u16 iproc_pcie_reg_paxb_v2[] = { |
334 | [IPROC_PCIE_CLK_CTRL] = 0x000, | 337 | [IPROC_PCIE_CLK_CTRL] = 0x000, |
335 | [IPROC_PCIE_CFG_IND_ADDR] = 0x120, | 338 | [IPROC_PCIE_CFG_IND_ADDR] = 0x120, |
336 | [IPROC_PCIE_CFG_IND_DATA] = 0x124, | 339 | [IPROC_PCIE_CFG_IND_DATA] = 0x124, |
337 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, | 340 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, |
338 | [IPROC_PCIE_CFG_DATA] = 0x1fc, | 341 | [IPROC_PCIE_CFG_DATA] = 0x1fc, |
339 | [IPROC_PCIE_INTX_EN] = 0x330, | 342 | [IPROC_PCIE_INTX_EN] = 0x330, |
340 | [IPROC_PCIE_OARR0] = 0xd20, | 343 | [IPROC_PCIE_OARR0] = 0xd20, |
341 | [IPROC_PCIE_OMAP0] = 0xd40, | 344 | [IPROC_PCIE_OMAP0] = 0xd40, |
342 | [IPROC_PCIE_OARR1] = 0xd28, | 345 | [IPROC_PCIE_OARR1] = 0xd28, |
343 | [IPROC_PCIE_OMAP1] = 0xd48, | 346 | [IPROC_PCIE_OMAP1] = 0xd48, |
344 | [IPROC_PCIE_OARR2] = 0xd60, | 347 | [IPROC_PCIE_OARR2] = 0xd60, |
345 | [IPROC_PCIE_OMAP2] = 0xd68, | 348 | [IPROC_PCIE_OMAP2] = 0xd68, |
346 | [IPROC_PCIE_OARR3] = 0xdf0, | 349 | [IPROC_PCIE_OARR3] = 0xdf0, |
347 | [IPROC_PCIE_OMAP3] = 0xdf8, | 350 | [IPROC_PCIE_OMAP3] = 0xdf8, |
348 | [IPROC_PCIE_IARR0] = 0xd00, | 351 | [IPROC_PCIE_IARR0] = 0xd00, |
349 | [IPROC_PCIE_IMAP0] = 0xc00, | 352 | [IPROC_PCIE_IMAP0] = 0xc00, |
350 | [IPROC_PCIE_IARR2] = 0xd10, | 353 | [IPROC_PCIE_IARR2] = 0xd10, |
351 | [IPROC_PCIE_IMAP2] = 0xcc0, | 354 | [IPROC_PCIE_IMAP2] = 0xcc0, |
352 | [IPROC_PCIE_IARR3] = 0xe00, | 355 | [IPROC_PCIE_IARR3] = 0xe00, |
353 | [IPROC_PCIE_IMAP3] = 0xe08, | 356 | [IPROC_PCIE_IMAP3] = 0xe08, |
354 | [IPROC_PCIE_IARR4] = 0xe68, | 357 | [IPROC_PCIE_IARR4] = 0xe68, |
355 | [IPROC_PCIE_IMAP4] = 0xe70, | 358 | [IPROC_PCIE_IMAP4] = 0xe70, |
356 | [IPROC_PCIE_LINK_STATUS] = 0xf0c, | 359 | [IPROC_PCIE_LINK_STATUS] = 0xf0c, |
357 | [IPROC_PCIE_APB_ERR_EN] = 0xf40, | 360 | [IPROC_PCIE_APB_ERR_EN] = 0xf40, |
358 | }; | 361 | }; |
359 | 362 | ||
360 | /* iProc PCIe PAXC v1 registers */ | 363 | /* iProc PCIe PAXC v1 registers */ |
361 | static const u16 iproc_pcie_reg_paxc[] = { | 364 | static const u16 iproc_pcie_reg_paxc[] = { |
362 | [IPROC_PCIE_CLK_CTRL] = 0x000, | 365 | [IPROC_PCIE_CLK_CTRL] = 0x000, |
363 | [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0, | 366 | [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0, |
364 | [IPROC_PCIE_CFG_IND_DATA] = 0x1f4, | 367 | [IPROC_PCIE_CFG_IND_DATA] = 0x1f4, |
365 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, | 368 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, |
366 | [IPROC_PCIE_CFG_DATA] = 0x1fc, | 369 | [IPROC_PCIE_CFG_DATA] = 0x1fc, |
367 | }; | 370 | }; |
368 | 371 | ||
369 | /* iProc PCIe PAXC v2 registers */ | 372 | /* iProc PCIe PAXC v2 registers */ |
370 | static const u16 iproc_pcie_reg_paxc_v2[] = { | 373 | static const u16 iproc_pcie_reg_paxc_v2[] = { |
371 | [IPROC_PCIE_MSI_GIC_MODE] = 0x050, | 374 | [IPROC_PCIE_MSI_GIC_MODE] = 0x050, |
372 | [IPROC_PCIE_MSI_BASE_ADDR] = 0x074, | 375 | [IPROC_PCIE_MSI_BASE_ADDR] = 0x074, |
373 | [IPROC_PCIE_MSI_WINDOW_SIZE] = 0x078, | 376 | [IPROC_PCIE_MSI_WINDOW_SIZE] = 0x078, |
374 | [IPROC_PCIE_MSI_ADDR_LO] = 0x07c, | 377 | [IPROC_PCIE_MSI_ADDR_LO] = 0x07c, |
375 | [IPROC_PCIE_MSI_ADDR_HI] = 0x080, | 378 | [IPROC_PCIE_MSI_ADDR_HI] = 0x080, |
376 | [IPROC_PCIE_MSI_EN_CFG] = 0x09c, | 379 | [IPROC_PCIE_MSI_EN_CFG] = 0x09c, |
377 | [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0, | 380 | [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0, |
378 | [IPROC_PCIE_CFG_IND_DATA] = 0x1f4, | 381 | [IPROC_PCIE_CFG_IND_DATA] = 0x1f4, |
379 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, | 382 | [IPROC_PCIE_CFG_ADDR] = 0x1f8, |
380 | [IPROC_PCIE_CFG_DATA] = 0x1fc, | 383 | [IPROC_PCIE_CFG_DATA] = 0x1fc, |
381 | }; | 384 | }; |
382 | 385 | ||
383 | static inline struct iproc_pcie *iproc_data(struct pci_bus *bus) | 386 | static inline struct iproc_pcie *iproc_data(struct pci_bus *bus) |
@@ -448,18 +451,112 @@ static inline void iproc_pcie_apb_err_disable(struct pci_bus *bus, | |||
448 | } | 451 | } |
449 | } | 452 | } |
450 | 453 | ||
454 | static void __iomem *iproc_pcie_map_ep_cfg_reg(struct iproc_pcie *pcie, | ||
455 | unsigned int busno, | ||
456 | unsigned int slot, | ||
457 | unsigned int fn, | ||
458 | int where) | ||
459 | { | ||
460 | u16 offset; | ||
461 | u32 val; | ||
462 | |||
463 | /* EP device access */ | ||
464 | val = (busno << CFG_ADDR_BUS_NUM_SHIFT) | | ||
465 | (slot << CFG_ADDR_DEV_NUM_SHIFT) | | ||
466 | (fn << CFG_ADDR_FUNC_NUM_SHIFT) | | ||
467 | (where & CFG_ADDR_REG_NUM_MASK) | | ||
468 | (1 & CFG_ADDR_CFG_TYPE_MASK); | ||
469 | |||
470 | iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_ADDR, val); | ||
471 | offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_DATA); | ||
472 | |||
473 | if (iproc_pcie_reg_is_invalid(offset)) | ||
474 | return NULL; | ||
475 | |||
476 | return (pcie->base + offset); | ||
477 | } | ||
478 | |||
479 | static unsigned int iproc_pcie_cfg_retry(void __iomem *cfg_data_p) | ||
480 | { | ||
481 | int timeout = CFG_RETRY_STATUS_TIMEOUT_US; | ||
482 | unsigned int data; | ||
483 | |||
484 | /* | ||
485 | * As per PCIe spec r3.1, sec 2.3.2, CRS Software Visibility only | ||
486 | * affects config reads of the Vendor ID. For config writes or any | ||
487 | * other config reads, the Root may automatically reissue the | ||
488 | * configuration request again as a new request. | ||
489 | * | ||
490 | * For config reads, this hardware returns CFG_RETRY_STATUS data | ||
491 | * when it receives a CRS completion, regardless of the address of | ||
492 | * the read or the CRS Software Visibility Enable bit. As a | ||
493 | * partial workaround for this, we retry in software any read that | ||
494 | * returns CFG_RETRY_STATUS. | ||
495 | * | ||
496 | * Note that a non-Vendor ID config register may have a value of | ||
497 | * CFG_RETRY_STATUS. If we read that, we can't distinguish it from | ||
498 | * a CRS completion, so we will incorrectly retry the read and | ||
499 | * eventually return the wrong data (0xffffffff). | ||
500 | */ | ||
501 | data = readl(cfg_data_p); | ||
502 | while (data == CFG_RETRY_STATUS && timeout--) { | ||
503 | udelay(1); | ||
504 | data = readl(cfg_data_p); | ||
505 | } | ||
506 | |||
507 | if (data == CFG_RETRY_STATUS) | ||
508 | data = 0xffffffff; | ||
509 | |||
510 | return data; | ||
511 | } | ||
512 | |||
513 | static int iproc_pcie_config_read(struct pci_bus *bus, unsigned int devfn, | ||
514 | int where, int size, u32 *val) | ||
515 | { | ||
516 | struct iproc_pcie *pcie = iproc_data(bus); | ||
517 | unsigned int slot = PCI_SLOT(devfn); | ||
518 | unsigned int fn = PCI_FUNC(devfn); | ||
519 | unsigned int busno = bus->number; | ||
520 | void __iomem *cfg_data_p; | ||
521 | unsigned int data; | ||
522 | int ret; | ||
523 | |||
524 | /* root complex access */ | ||
525 | if (busno == 0) { | ||
526 | ret = pci_generic_config_read32(bus, devfn, where, size, val); | ||
527 | if (ret != PCIBIOS_SUCCESSFUL) | ||
528 | return ret; | ||
529 | |||
530 | /* Don't advertise CRS SV support */ | ||
531 | if ((where & ~0x3) == IPROC_PCI_EXP_CAP + PCI_EXP_RTCTL) | ||
532 | *val &= ~(PCI_EXP_RTCAP_CRSVIS << 16); | ||
533 | return PCIBIOS_SUCCESSFUL; | ||
534 | } | ||
535 | |||
536 | cfg_data_p = iproc_pcie_map_ep_cfg_reg(pcie, busno, slot, fn, where); | ||
537 | |||
538 | if (!cfg_data_p) | ||
539 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
540 | |||
541 | data = iproc_pcie_cfg_retry(cfg_data_p); | ||
542 | |||
543 | *val = data; | ||
544 | if (size <= 2) | ||
545 | *val = (data >> (8 * (where & 3))) & ((1 << (size * 8)) - 1); | ||
546 | |||
547 | return PCIBIOS_SUCCESSFUL; | ||
548 | } | ||
549 | |||
451 | /** | 550 | /** |
452 | * Note access to the configuration registers are protected at the higher layer | 551 | * Note access to the configuration registers are protected at the higher layer |
453 | * by 'pci_lock' in drivers/pci/access.c | 552 | * by 'pci_lock' in drivers/pci/access.c |
454 | */ | 553 | */ |
455 | static void __iomem *iproc_pcie_map_cfg_bus(struct iproc_pcie *pcie, | 554 | static void __iomem *iproc_pcie_map_cfg_bus(struct iproc_pcie *pcie, |
456 | int busno, | 555 | int busno, unsigned int devfn, |
457 | unsigned int devfn, | ||
458 | int where) | 556 | int where) |
459 | { | 557 | { |
460 | unsigned slot = PCI_SLOT(devfn); | 558 | unsigned slot = PCI_SLOT(devfn); |
461 | unsigned fn = PCI_FUNC(devfn); | 559 | unsigned fn = PCI_FUNC(devfn); |
462 | u32 val; | ||
463 | u16 offset; | 560 | u16 offset; |
464 | 561 | ||
465 | /* root complex access */ | 562 | /* root complex access */ |
@@ -484,18 +581,7 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct iproc_pcie *pcie, | |||
484 | if (slot > 0) | 581 | if (slot > 0) |
485 | return NULL; | 582 | return NULL; |
486 | 583 | ||
487 | /* EP device access */ | 584 | return iproc_pcie_map_ep_cfg_reg(pcie, busno, slot, fn, where); |
488 | val = (busno << CFG_ADDR_BUS_NUM_SHIFT) | | ||
489 | (slot << CFG_ADDR_DEV_NUM_SHIFT) | | ||
490 | (fn << CFG_ADDR_FUNC_NUM_SHIFT) | | ||
491 | (where & CFG_ADDR_REG_NUM_MASK) | | ||
492 | (1 & CFG_ADDR_CFG_TYPE_MASK); | ||
493 | iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_ADDR, val); | ||
494 | offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_DATA); | ||
495 | if (iproc_pcie_reg_is_invalid(offset)) | ||
496 | return NULL; | ||
497 | else | ||
498 | return (pcie->base + offset); | ||
499 | } | 585 | } |
500 | 586 | ||
501 | static void __iomem *iproc_pcie_bus_map_cfg_bus(struct pci_bus *bus, | 587 | static void __iomem *iproc_pcie_bus_map_cfg_bus(struct pci_bus *bus, |
@@ -554,9 +640,13 @@ static int iproc_pcie_config_read32(struct pci_bus *bus, unsigned int devfn, | |||
554 | int where, int size, u32 *val) | 640 | int where, int size, u32 *val) |
555 | { | 641 | { |
556 | int ret; | 642 | int ret; |
643 | struct iproc_pcie *pcie = iproc_data(bus); | ||
557 | 644 | ||
558 | iproc_pcie_apb_err_disable(bus, true); | 645 | iproc_pcie_apb_err_disable(bus, true); |
559 | ret = pci_generic_config_read32(bus, devfn, where, size, val); | 646 | if (pcie->type == IPROC_PCIE_PAXB_V2) |
647 | ret = iproc_pcie_config_read(bus, devfn, where, size, val); | ||
648 | else | ||
649 | ret = pci_generic_config_read32(bus, devfn, where, size, val); | ||
560 | iproc_pcie_apb_err_disable(bus, false); | 650 | iproc_pcie_apb_err_disable(bus, false); |
561 | 651 | ||
562 | return ret; | 652 | return ret; |
@@ -580,7 +670,7 @@ static struct pci_ops iproc_pcie_ops = { | |||
580 | .write = iproc_pcie_config_write32, | 670 | .write = iproc_pcie_config_write32, |
581 | }; | 671 | }; |
582 | 672 | ||
583 | static void iproc_pcie_reset(struct iproc_pcie *pcie) | 673 | static void iproc_pcie_perst_ctrl(struct iproc_pcie *pcie, bool assert) |
584 | { | 674 | { |
585 | u32 val; | 675 | u32 val; |
586 | 676 | ||
@@ -592,26 +682,33 @@ static void iproc_pcie_reset(struct iproc_pcie *pcie) | |||
592 | if (pcie->ep_is_internal) | 682 | if (pcie->ep_is_internal) |
593 | return; | 683 | return; |
594 | 684 | ||
595 | /* | 685 | if (assert) { |
596 | * Select perst_b signal as reset source. Put the device into reset, | 686 | val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL); |
597 | * and then bring it out of reset | 687 | val &= ~EP_PERST_SOURCE_SELECT & ~EP_MODE_SURVIVE_PERST & |
598 | */ | 688 | ~RC_PCIE_RST_OUTPUT; |
599 | val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL); | 689 | iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); |
600 | val &= ~EP_PERST_SOURCE_SELECT & ~EP_MODE_SURVIVE_PERST & | 690 | udelay(250); |
601 | ~RC_PCIE_RST_OUTPUT; | 691 | } else { |
602 | iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); | 692 | val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL); |
603 | udelay(250); | 693 | val |= RC_PCIE_RST_OUTPUT; |
604 | 694 | iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); | |
605 | val |= RC_PCIE_RST_OUTPUT; | 695 | msleep(100); |
606 | iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); | 696 | } |
607 | msleep(100); | 697 | } |
698 | |||
699 | int iproc_pcie_shutdown(struct iproc_pcie *pcie) | ||
700 | { | ||
701 | iproc_pcie_perst_ctrl(pcie, true); | ||
702 | msleep(500); | ||
703 | |||
704 | return 0; | ||
608 | } | 705 | } |
706 | EXPORT_SYMBOL_GPL(iproc_pcie_shutdown); | ||
609 | 707 | ||
610 | static int iproc_pcie_check_link(struct iproc_pcie *pcie) | 708 | static int iproc_pcie_check_link(struct iproc_pcie *pcie) |
611 | { | 709 | { |
612 | struct device *dev = pcie->dev; | 710 | struct device *dev = pcie->dev; |
613 | u32 hdr_type, link_ctrl, link_status, class, val; | 711 | u32 hdr_type, link_ctrl, link_status, class, val; |
614 | u16 pos = PCI_EXP_CAP; | ||
615 | bool link_is_active = false; | 712 | bool link_is_active = false; |
616 | 713 | ||
617 | /* | 714 | /* |
@@ -628,16 +725,16 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie) | |||
628 | } | 725 | } |
629 | 726 | ||
630 | /* make sure we are not in EP mode */ | 727 | /* make sure we are not in EP mode */ |
631 | iproc_pci_raw_config_read32(pcie, 0, PCI_HEADER_TYPE, 1, &hdr_type); | 728 | iproc_pci_raw_config_read32(pcie, 0, PCI_HEADER_TYPE, 1, &hdr_type); |
632 | if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) { | 729 | if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) { |
633 | dev_err(dev, "in EP mode, hdr=%#02x\n", hdr_type); | 730 | dev_err(dev, "in EP mode, hdr=%#02x\n", hdr_type); |
634 | return -EFAULT; | 731 | return -EFAULT; |
635 | } | 732 | } |
636 | 733 | ||
637 | /* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */ | 734 | /* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */ |
638 | #define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c | 735 | #define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c |
639 | #define PCI_CLASS_BRIDGE_MASK 0xffff00 | 736 | #define PCI_CLASS_BRIDGE_MASK 0xffff00 |
640 | #define PCI_CLASS_BRIDGE_SHIFT 8 | 737 | #define PCI_CLASS_BRIDGE_SHIFT 8 |
641 | iproc_pci_raw_config_read32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET, | 738 | iproc_pci_raw_config_read32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET, |
642 | 4, &class); | 739 | 4, &class); |
643 | class &= ~PCI_CLASS_BRIDGE_MASK; | 740 | class &= ~PCI_CLASS_BRIDGE_MASK; |
@@ -646,31 +743,31 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie) | |||
646 | 4, class); | 743 | 4, class); |
647 | 744 | ||
648 | /* check link status to see if link is active */ | 745 | /* check link status to see if link is active */ |
649 | iproc_pci_raw_config_read32(pcie, 0, pos + PCI_EXP_LNKSTA, | 746 | iproc_pci_raw_config_read32(pcie, 0, IPROC_PCI_EXP_CAP + PCI_EXP_LNKSTA, |
650 | 2, &link_status); | 747 | 2, &link_status); |
651 | if (link_status & PCI_EXP_LNKSTA_NLW) | 748 | if (link_status & PCI_EXP_LNKSTA_NLW) |
652 | link_is_active = true; | 749 | link_is_active = true; |
653 | 750 | ||
654 | if (!link_is_active) { | 751 | if (!link_is_active) { |
655 | /* try GEN 1 link speed */ | 752 | /* try GEN 1 link speed */ |
656 | #define PCI_TARGET_LINK_SPEED_MASK 0xf | 753 | #define PCI_TARGET_LINK_SPEED_MASK 0xf |
657 | #define PCI_TARGET_LINK_SPEED_GEN2 0x2 | 754 | #define PCI_TARGET_LINK_SPEED_GEN2 0x2 |
658 | #define PCI_TARGET_LINK_SPEED_GEN1 0x1 | 755 | #define PCI_TARGET_LINK_SPEED_GEN1 0x1 |
659 | iproc_pci_raw_config_read32(pcie, 0, | 756 | iproc_pci_raw_config_read32(pcie, 0, |
660 | pos + PCI_EXP_LNKCTL2, 4, | 757 | IPROC_PCI_EXP_CAP + PCI_EXP_LNKCTL2, |
661 | &link_ctrl); | 758 | 4, &link_ctrl); |
662 | if ((link_ctrl & PCI_TARGET_LINK_SPEED_MASK) == | 759 | if ((link_ctrl & PCI_TARGET_LINK_SPEED_MASK) == |
663 | PCI_TARGET_LINK_SPEED_GEN2) { | 760 | PCI_TARGET_LINK_SPEED_GEN2) { |
664 | link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK; | 761 | link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK; |
665 | link_ctrl |= PCI_TARGET_LINK_SPEED_GEN1; | 762 | link_ctrl |= PCI_TARGET_LINK_SPEED_GEN1; |
666 | iproc_pci_raw_config_write32(pcie, 0, | 763 | iproc_pci_raw_config_write32(pcie, 0, |
667 | pos + PCI_EXP_LNKCTL2, | 764 | IPROC_PCI_EXP_CAP + PCI_EXP_LNKCTL2, |
668 | 4, link_ctrl); | 765 | 4, link_ctrl); |
669 | msleep(100); | 766 | msleep(100); |
670 | 767 | ||
671 | iproc_pci_raw_config_read32(pcie, 0, | 768 | iproc_pci_raw_config_read32(pcie, 0, |
672 | pos + PCI_EXP_LNKSTA, | 769 | IPROC_PCI_EXP_CAP + PCI_EXP_LNKSTA, |
673 | 2, &link_status); | 770 | 2, &link_status); |
674 | if (link_status & PCI_EXP_LNKSTA_NLW) | 771 | if (link_status & PCI_EXP_LNKSTA_NLW) |
675 | link_is_active = true; | 772 | link_is_active = true; |
676 | } | 773 | } |
@@ -1223,6 +1320,8 @@ static int iproc_pcie_rev_init(struct iproc_pcie *pcie) | |||
1223 | pcie->ib.nr_regions = ARRAY_SIZE(paxb_v2_ib_map); | 1320 | pcie->ib.nr_regions = ARRAY_SIZE(paxb_v2_ib_map); |
1224 | pcie->ib_map = paxb_v2_ib_map; | 1321 | pcie->ib_map = paxb_v2_ib_map; |
1225 | pcie->need_msi_steer = true; | 1322 | pcie->need_msi_steer = true; |
1323 | dev_warn(dev, "reads of config registers that contain %#x return incorrect data\n", | ||
1324 | CFG_RETRY_STATUS); | ||
1226 | break; | 1325 | break; |
1227 | case IPROC_PCIE_PAXC: | 1326 | case IPROC_PCIE_PAXC: |
1228 | regs = iproc_pcie_reg_paxc; | 1327 | regs = iproc_pcie_reg_paxc; |
@@ -1286,7 +1385,8 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) | |||
1286 | goto err_exit_phy; | 1385 | goto err_exit_phy; |
1287 | } | 1386 | } |
1288 | 1387 | ||
1289 | iproc_pcie_reset(pcie); | 1388 | iproc_pcie_perst_ctrl(pcie, true); |
1389 | iproc_pcie_perst_ctrl(pcie, false); | ||
1290 | 1390 | ||
1291 | if (pcie->need_ob_cfg) { | 1391 | if (pcie->need_ob_cfg) { |
1292 | ret = iproc_pcie_map_ranges(pcie, res); | 1392 | ret = iproc_pcie_map_ranges(pcie, res); |
diff --git a/drivers/pci/host/pcie-iproc.h b/drivers/pci/host/pcie-iproc.h index 0bbe2ea44f3e..a6b55cec9a66 100644 --- a/drivers/pci/host/pcie-iproc.h +++ b/drivers/pci/host/pcie-iproc.h | |||
@@ -110,6 +110,7 @@ struct iproc_pcie { | |||
110 | 110 | ||
111 | int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res); | 111 | int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res); |
112 | int iproc_pcie_remove(struct iproc_pcie *pcie); | 112 | int iproc_pcie_remove(struct iproc_pcie *pcie); |
113 | int iproc_pcie_shutdown(struct iproc_pcie *pcie); | ||
113 | 114 | ||
114 | #ifdef CONFIG_PCIE_IPROC_MSI | 115 | #ifdef CONFIG_PCIE_IPROC_MSI |
115 | int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node); | 116 | int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node); |
diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c index 5a9d8589ea0b..db93efdf1d63 100644 --- a/drivers/pci/host/pcie-mediatek.c +++ b/drivers/pci/host/pcie-mediatek.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2017 MediaTek Inc. | 4 | * Copyright (c) 2017 MediaTek Inc. |
5 | * Author: Ryder Lee <ryder.lee@mediatek.com> | 5 | * Author: Ryder Lee <ryder.lee@mediatek.com> |
6 | * Honghui Zhang <honghui.zhang@mediatek.com> | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -16,6 +17,9 @@ | |||
16 | 17 | ||
17 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
18 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/iopoll.h> | ||
21 | #include <linux/irq.h> | ||
22 | #include <linux/irqdomain.h> | ||
19 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
20 | #include <linux/of_address.h> | 24 | #include <linux/of_address.h> |
21 | #include <linux/of_pci.h> | 25 | #include <linux/of_pci.h> |
@@ -63,16 +67,104 @@ | |||
63 | #define PCIE_FC_CREDIT_MASK (GENMASK(31, 31) | GENMASK(28, 16)) | 67 | #define PCIE_FC_CREDIT_MASK (GENMASK(31, 31) | GENMASK(28, 16)) |
64 | #define PCIE_FC_CREDIT_VAL(x) ((x) << 16) | 68 | #define PCIE_FC_CREDIT_VAL(x) ((x) << 16) |
65 | 69 | ||
70 | /* PCIe V2 share registers */ | ||
71 | #define PCIE_SYS_CFG_V2 0x0 | ||
72 | #define PCIE_CSR_LTSSM_EN(x) BIT(0 + (x) * 8) | ||
73 | #define PCIE_CSR_ASPM_L1_EN(x) BIT(1 + (x) * 8) | ||
74 | |||
75 | /* PCIe V2 per-port registers */ | ||
76 | #define PCIE_MSI_VECTOR 0x0c0 | ||
77 | #define PCIE_INT_MASK 0x420 | ||
78 | #define INTX_MASK GENMASK(19, 16) | ||
79 | #define INTX_SHIFT 16 | ||
80 | #define PCIE_INT_STATUS 0x424 | ||
81 | #define MSI_STATUS BIT(23) | ||
82 | #define PCIE_IMSI_STATUS 0x42c | ||
83 | #define PCIE_IMSI_ADDR 0x430 | ||
84 | #define MSI_MASK BIT(23) | ||
85 | #define MTK_MSI_IRQS_NUM 32 | ||
86 | |||
87 | #define PCIE_AHB_TRANS_BASE0_L 0x438 | ||
88 | #define PCIE_AHB_TRANS_BASE0_H 0x43c | ||
89 | #define AHB2PCIE_SIZE(x) ((x) & GENMASK(4, 0)) | ||
90 | #define PCIE_AXI_WINDOW0 0x448 | ||
91 | #define WIN_ENABLE BIT(7) | ||
92 | |||
93 | /* PCIe V2 configuration transaction header */ | ||
94 | #define PCIE_CFG_HEADER0 0x460 | ||
95 | #define PCIE_CFG_HEADER1 0x464 | ||
96 | #define PCIE_CFG_HEADER2 0x468 | ||
97 | #define PCIE_CFG_WDATA 0x470 | ||
98 | #define PCIE_APP_TLP_REQ 0x488 | ||
99 | #define PCIE_CFG_RDATA 0x48c | ||
100 | #define APP_CFG_REQ BIT(0) | ||
101 | #define APP_CPL_STATUS GENMASK(7, 5) | ||
102 | |||
103 | #define CFG_WRRD_TYPE_0 4 | ||
104 | #define CFG_WR_FMT 2 | ||
105 | #define CFG_RD_FMT 0 | ||
106 | |||
107 | #define CFG_DW0_LENGTH(length) ((length) & GENMASK(9, 0)) | ||
108 | #define CFG_DW0_TYPE(type) (((type) << 24) & GENMASK(28, 24)) | ||
109 | #define CFG_DW0_FMT(fmt) (((fmt) << 29) & GENMASK(31, 29)) | ||
110 | #define CFG_DW2_REGN(regn) ((regn) & GENMASK(11, 2)) | ||
111 | #define CFG_DW2_FUN(fun) (((fun) << 16) & GENMASK(18, 16)) | ||
112 | #define CFG_DW2_DEV(dev) (((dev) << 19) & GENMASK(23, 19)) | ||
113 | #define CFG_DW2_BUS(bus) (((bus) << 24) & GENMASK(31, 24)) | ||
114 | #define CFG_HEADER_DW0(type, fmt) \ | ||
115 | (CFG_DW0_LENGTH(1) | CFG_DW0_TYPE(type) | CFG_DW0_FMT(fmt)) | ||
116 | #define CFG_HEADER_DW1(where, size) \ | ||
117 | (GENMASK(((size) - 1), 0) << ((where) & 0x3)) | ||
118 | #define CFG_HEADER_DW2(regn, fun, dev, bus) \ | ||
119 | (CFG_DW2_REGN(regn) | CFG_DW2_FUN(fun) | \ | ||
120 | CFG_DW2_DEV(dev) | CFG_DW2_BUS(bus)) | ||
121 | |||
122 | #define PCIE_RST_CTRL 0x510 | ||
123 | #define PCIE_PHY_RSTB BIT(0) | ||
124 | #define PCIE_PIPE_SRSTB BIT(1) | ||
125 | #define PCIE_MAC_SRSTB BIT(2) | ||
126 | #define PCIE_CRSTB BIT(3) | ||
127 | #define PCIE_PERSTB BIT(8) | ||
128 | #define PCIE_LINKDOWN_RST_EN GENMASK(15, 13) | ||
129 | #define PCIE_LINK_STATUS_V2 0x804 | ||
130 | #define PCIE_PORT_LINKUP_V2 BIT(10) | ||
131 | |||
132 | struct mtk_pcie_port; | ||
133 | |||
134 | /** | ||
135 | * struct mtk_pcie_soc - differentiate between host generations | ||
136 | * @has_msi: whether this host supports MSI interrupts or not | ||
137 | * @ops: pointer to configuration access functions | ||
138 | * @startup: pointer to controller setting functions | ||
139 | * @setup_irq: pointer to initialize IRQ functions | ||
140 | */ | ||
141 | struct mtk_pcie_soc { | ||
142 | bool has_msi; | ||
143 | struct pci_ops *ops; | ||
144 | int (*startup)(struct mtk_pcie_port *port); | ||
145 | int (*setup_irq)(struct mtk_pcie_port *port, struct device_node *node); | ||
146 | }; | ||
147 | |||
66 | /** | 148 | /** |
67 | * struct mtk_pcie_port - PCIe port information | 149 | * struct mtk_pcie_port - PCIe port information |
68 | * @base: IO mapped register base | 150 | * @base: IO mapped register base |
69 | * @list: port list | 151 | * @list: port list |
70 | * @pcie: pointer to PCIe host info | 152 | * @pcie: pointer to PCIe host info |
71 | * @reset: pointer to port reset control | 153 | * @reset: pointer to port reset control |
72 | * @sys_ck: pointer to bus clock | 154 | * @sys_ck: pointer to transaction/data link layer clock |
73 | * @phy: pointer to phy control block | 155 | * @ahb_ck: pointer to AHB slave interface operating clock for CSR access |
156 | * and RC initiated MMIO access | ||
157 | * @axi_ck: pointer to application layer MMIO channel operating clock | ||
158 | * @aux_ck: pointer to pe2_mac_bridge and pe2_mac_core operating clock | ||
159 | * when pcie_mac_ck/pcie_pipe_ck is turned off | ||
160 | * @obff_ck: pointer to OBFF functional block operating clock | ||
161 | * @pipe_ck: pointer to LTSSM and PHY/MAC layer operating clock | ||
162 | * @phy: pointer to PHY control block | ||
74 | * @lane: lane count | 163 | * @lane: lane count |
75 | * @index: port index | 164 | * @slot: port slot |
165 | * @irq_domain: legacy INTx IRQ domain | ||
166 | * @msi_domain: MSI IRQ domain | ||
167 | * @msi_irq_in_use: bit map for assigned MSI IRQ | ||
76 | */ | 168 | */ |
77 | struct mtk_pcie_port { | 169 | struct mtk_pcie_port { |
78 | void __iomem *base; | 170 | void __iomem *base; |
@@ -80,9 +172,17 @@ struct mtk_pcie_port { | |||
80 | struct mtk_pcie *pcie; | 172 | struct mtk_pcie *pcie; |
81 | struct reset_control *reset; | 173 | struct reset_control *reset; |
82 | struct clk *sys_ck; | 174 | struct clk *sys_ck; |
175 | struct clk *ahb_ck; | ||
176 | struct clk *axi_ck; | ||
177 | struct clk *aux_ck; | ||
178 | struct clk *obff_ck; | ||
179 | struct clk *pipe_ck; | ||
83 | struct phy *phy; | 180 | struct phy *phy; |
84 | u32 lane; | 181 | u32 lane; |
85 | u32 index; | 182 | u32 slot; |
183 | struct irq_domain *irq_domain; | ||
184 | struct irq_domain *msi_domain; | ||
185 | DECLARE_BITMAP(msi_irq_in_use, MTK_MSI_IRQS_NUM); | ||
86 | }; | 186 | }; |
87 | 187 | ||
88 | /** | 188 | /** |
@@ -96,6 +196,7 @@ struct mtk_pcie_port { | |||
96 | * @busn: bus range | 196 | * @busn: bus range |
97 | * @offset: IO / Memory offset | 197 | * @offset: IO / Memory offset |
98 | * @ports: pointer to PCIe port information | 198 | * @ports: pointer to PCIe port information |
199 | * @soc: pointer to SoC-dependent operations | ||
99 | */ | 200 | */ |
100 | struct mtk_pcie { | 201 | struct mtk_pcie { |
101 | struct device *dev; | 202 | struct device *dev; |
@@ -111,13 +212,9 @@ struct mtk_pcie { | |||
111 | resource_size_t io; | 212 | resource_size_t io; |
112 | } offset; | 213 | } offset; |
113 | struct list_head ports; | 214 | struct list_head ports; |
215 | const struct mtk_pcie_soc *soc; | ||
114 | }; | 216 | }; |
115 | 217 | ||
116 | static inline bool mtk_pcie_link_up(struct mtk_pcie_port *port) | ||
117 | { | ||
118 | return !!(readl(port->base + PCIE_LINK_STATUS) & PCIE_PORT_LINKUP); | ||
119 | } | ||
120 | |||
121 | static void mtk_pcie_subsys_powerdown(struct mtk_pcie *pcie) | 218 | static void mtk_pcie_subsys_powerdown(struct mtk_pcie *pcie) |
122 | { | 219 | { |
123 | struct device *dev = pcie->dev; | 220 | struct device *dev = pcie->dev; |
@@ -146,6 +243,12 @@ static void mtk_pcie_put_resources(struct mtk_pcie *pcie) | |||
146 | 243 | ||
147 | list_for_each_entry_safe(port, tmp, &pcie->ports, list) { | 244 | list_for_each_entry_safe(port, tmp, &pcie->ports, list) { |
148 | phy_power_off(port->phy); | 245 | phy_power_off(port->phy); |
246 | phy_exit(port->phy); | ||
247 | clk_disable_unprepare(port->pipe_ck); | ||
248 | clk_disable_unprepare(port->obff_ck); | ||
249 | clk_disable_unprepare(port->axi_ck); | ||
250 | clk_disable_unprepare(port->aux_ck); | ||
251 | clk_disable_unprepare(port->ahb_ck); | ||
149 | clk_disable_unprepare(port->sys_ck); | 252 | clk_disable_unprepare(port->sys_ck); |
150 | mtk_pcie_port_free(port); | 253 | mtk_pcie_port_free(port); |
151 | } | 254 | } |
@@ -153,11 +256,412 @@ static void mtk_pcie_put_resources(struct mtk_pcie *pcie) | |||
153 | mtk_pcie_subsys_powerdown(pcie); | 256 | mtk_pcie_subsys_powerdown(pcie); |
154 | } | 257 | } |
155 | 258 | ||
259 | static int mtk_pcie_check_cfg_cpld(struct mtk_pcie_port *port) | ||
260 | { | ||
261 | u32 val; | ||
262 | int err; | ||
263 | |||
264 | err = readl_poll_timeout_atomic(port->base + PCIE_APP_TLP_REQ, val, | ||
265 | !(val & APP_CFG_REQ), 10, | ||
266 | 100 * USEC_PER_MSEC); | ||
267 | if (err) | ||
268 | return PCIBIOS_SET_FAILED; | ||
269 | |||
270 | if (readl(port->base + PCIE_APP_TLP_REQ) & APP_CPL_STATUS) | ||
271 | return PCIBIOS_SET_FAILED; | ||
272 | |||
273 | return PCIBIOS_SUCCESSFUL; | ||
274 | } | ||
275 | |||
276 | static int mtk_pcie_hw_rd_cfg(struct mtk_pcie_port *port, u32 bus, u32 devfn, | ||
277 | int where, int size, u32 *val) | ||
278 | { | ||
279 | u32 tmp; | ||
280 | |||
281 | /* Write PCIe configuration transaction header for Cfgrd */ | ||
282 | writel(CFG_HEADER_DW0(CFG_WRRD_TYPE_0, CFG_RD_FMT), | ||
283 | port->base + PCIE_CFG_HEADER0); | ||
284 | writel(CFG_HEADER_DW1(where, size), port->base + PCIE_CFG_HEADER1); | ||
285 | writel(CFG_HEADER_DW2(where, PCI_FUNC(devfn), PCI_SLOT(devfn), bus), | ||
286 | port->base + PCIE_CFG_HEADER2); | ||
287 | |||
288 | /* Trigger h/w to transmit Cfgrd TLP */ | ||
289 | tmp = readl(port->base + PCIE_APP_TLP_REQ); | ||
290 | tmp |= APP_CFG_REQ; | ||
291 | writel(tmp, port->base + PCIE_APP_TLP_REQ); | ||
292 | |||
293 | /* Check completion status */ | ||
294 | if (mtk_pcie_check_cfg_cpld(port)) | ||
295 | return PCIBIOS_SET_FAILED; | ||
296 | |||
297 | /* Read cpld payload of Cfgrd */ | ||
298 | *val = readl(port->base + PCIE_CFG_RDATA); | ||
299 | |||
300 | if (size == 1) | ||
301 | *val = (*val >> (8 * (where & 3))) & 0xff; | ||
302 | else if (size == 2) | ||
303 | *val = (*val >> (8 * (where & 3))) & 0xffff; | ||
304 | |||
305 | return PCIBIOS_SUCCESSFUL; | ||
306 | } | ||
307 | |||
308 | static int mtk_pcie_hw_wr_cfg(struct mtk_pcie_port *port, u32 bus, u32 devfn, | ||
309 | int where, int size, u32 val) | ||
310 | { | ||
311 | /* Write PCIe configuration transaction header for Cfgwr */ | ||
312 | writel(CFG_HEADER_DW0(CFG_WRRD_TYPE_0, CFG_WR_FMT), | ||
313 | port->base + PCIE_CFG_HEADER0); | ||
314 | writel(CFG_HEADER_DW1(where, size), port->base + PCIE_CFG_HEADER1); | ||
315 | writel(CFG_HEADER_DW2(where, PCI_FUNC(devfn), PCI_SLOT(devfn), bus), | ||
316 | port->base + PCIE_CFG_HEADER2); | ||
317 | |||
318 | /* Write Cfgwr data */ | ||
319 | val = val << 8 * (where & 3); | ||
320 | writel(val, port->base + PCIE_CFG_WDATA); | ||
321 | |||
322 | /* Trigger h/w to transmit Cfgwr TLP */ | ||
323 | val = readl(port->base + PCIE_APP_TLP_REQ); | ||
324 | val |= APP_CFG_REQ; | ||
325 | writel(val, port->base + PCIE_APP_TLP_REQ); | ||
326 | |||
327 | /* Check completion status */ | ||
328 | return mtk_pcie_check_cfg_cpld(port); | ||
329 | } | ||
330 | |||
331 | static struct mtk_pcie_port *mtk_pcie_find_port(struct pci_bus *bus, | ||
332 | unsigned int devfn) | ||
333 | { | ||
334 | struct mtk_pcie *pcie = bus->sysdata; | ||
335 | struct mtk_pcie_port *port; | ||
336 | |||
337 | list_for_each_entry(port, &pcie->ports, list) | ||
338 | if (port->slot == PCI_SLOT(devfn)) | ||
339 | return port; | ||
340 | |||
341 | return NULL; | ||
342 | } | ||
343 | |||
344 | static int mtk_pcie_config_read(struct pci_bus *bus, unsigned int devfn, | ||
345 | int where, int size, u32 *val) | ||
346 | { | ||
347 | struct mtk_pcie_port *port; | ||
348 | u32 bn = bus->number; | ||
349 | int ret; | ||
350 | |||
351 | port = mtk_pcie_find_port(bus, devfn); | ||
352 | if (!port) { | ||
353 | *val = ~0; | ||
354 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
355 | } | ||
356 | |||
357 | ret = mtk_pcie_hw_rd_cfg(port, bn, devfn, where, size, val); | ||
358 | if (ret) | ||
359 | *val = ~0; | ||
360 | |||
361 | return ret; | ||
362 | } | ||
363 | |||
364 | static int mtk_pcie_config_write(struct pci_bus *bus, unsigned int devfn, | ||
365 | int where, int size, u32 val) | ||
366 | { | ||
367 | struct mtk_pcie_port *port; | ||
368 | u32 bn = bus->number; | ||
369 | |||
370 | port = mtk_pcie_find_port(bus, devfn); | ||
371 | if (!port) | ||
372 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
373 | |||
374 | return mtk_pcie_hw_wr_cfg(port, bn, devfn, where, size, val); | ||
375 | } | ||
376 | |||
377 | static struct pci_ops mtk_pcie_ops_v2 = { | ||
378 | .read = mtk_pcie_config_read, | ||
379 | .write = mtk_pcie_config_write, | ||
380 | }; | ||
381 | |||
382 | static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port) | ||
383 | { | ||
384 | struct mtk_pcie *pcie = port->pcie; | ||
385 | struct resource *mem = &pcie->mem; | ||
386 | u32 val; | ||
387 | size_t size; | ||
388 | int err; | ||
389 | |||
390 | /* MT7622 platforms need to enable LTSSM and ASPM from PCIe subsys */ | ||
391 | if (pcie->base) { | ||
392 | val = readl(pcie->base + PCIE_SYS_CFG_V2); | ||
393 | val |= PCIE_CSR_LTSSM_EN(port->slot) | | ||
394 | PCIE_CSR_ASPM_L1_EN(port->slot); | ||
395 | writel(val, pcie->base + PCIE_SYS_CFG_V2); | ||
396 | } | ||
397 | |||
398 | /* Assert all reset signals */ | ||
399 | writel(0, port->base + PCIE_RST_CTRL); | ||
400 | |||
401 | /* | ||
402 | * Enable PCIe link down reset, if link status changed from link up to | ||
403 | * link down, this will reset MAC control registers and configuration | ||
404 | * space. | ||
405 | */ | ||
406 | writel(PCIE_LINKDOWN_RST_EN, port->base + PCIE_RST_CTRL); | ||
407 | |||
408 | /* De-assert PHY, PE, PIPE, MAC and configuration reset */ | ||
409 | val = readl(port->base + PCIE_RST_CTRL); | ||
410 | val |= PCIE_PHY_RSTB | PCIE_PERSTB | PCIE_PIPE_SRSTB | | ||
411 | PCIE_MAC_SRSTB | PCIE_CRSTB; | ||
412 | writel(val, port->base + PCIE_RST_CTRL); | ||
413 | |||
414 | /* 100ms timeout value should be enough for Gen1/2 training */ | ||
415 | err = readl_poll_timeout(port->base + PCIE_LINK_STATUS_V2, val, | ||
416 | !!(val & PCIE_PORT_LINKUP_V2), 20, | ||
417 | 100 * USEC_PER_MSEC); | ||
418 | if (err) | ||
419 | return -ETIMEDOUT; | ||
420 | |||
421 | /* Set INTx mask */ | ||
422 | val = readl(port->base + PCIE_INT_MASK); | ||
423 | val &= ~INTX_MASK; | ||
424 | writel(val, port->base + PCIE_INT_MASK); | ||
425 | |||
426 | /* Set AHB to PCIe translation windows */ | ||
427 | size = mem->end - mem->start; | ||
428 | val = lower_32_bits(mem->start) | AHB2PCIE_SIZE(fls(size)); | ||
429 | writel(val, port->base + PCIE_AHB_TRANS_BASE0_L); | ||
430 | |||
431 | val = upper_32_bits(mem->start); | ||
432 | writel(val, port->base + PCIE_AHB_TRANS_BASE0_H); | ||
433 | |||
434 | /* Set PCIe to AXI translation memory space.*/ | ||
435 | val = fls(0xffffffff) | WIN_ENABLE; | ||
436 | writel(val, port->base + PCIE_AXI_WINDOW0); | ||
437 | |||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | static int mtk_pcie_msi_alloc(struct mtk_pcie_port *port) | ||
442 | { | ||
443 | int msi; | ||
444 | |||
445 | msi = find_first_zero_bit(port->msi_irq_in_use, MTK_MSI_IRQS_NUM); | ||
446 | if (msi < MTK_MSI_IRQS_NUM) | ||
447 | set_bit(msi, port->msi_irq_in_use); | ||
448 | else | ||
449 | return -ENOSPC; | ||
450 | |||
451 | return msi; | ||
452 | } | ||
453 | |||
454 | static void mtk_pcie_msi_free(struct mtk_pcie_port *port, unsigned long hwirq) | ||
455 | { | ||
456 | clear_bit(hwirq, port->msi_irq_in_use); | ||
457 | } | ||
458 | |||
459 | static int mtk_pcie_msi_setup_irq(struct msi_controller *chip, | ||
460 | struct pci_dev *pdev, struct msi_desc *desc) | ||
461 | { | ||
462 | struct mtk_pcie_port *port; | ||
463 | struct msi_msg msg; | ||
464 | unsigned int irq; | ||
465 | int hwirq; | ||
466 | phys_addr_t msg_addr; | ||
467 | |||
468 | port = mtk_pcie_find_port(pdev->bus, pdev->devfn); | ||
469 | if (!port) | ||
470 | return -EINVAL; | ||
471 | |||
472 | hwirq = mtk_pcie_msi_alloc(port); | ||
473 | if (hwirq < 0) | ||
474 | return hwirq; | ||
475 | |||
476 | irq = irq_create_mapping(port->msi_domain, hwirq); | ||
477 | if (!irq) { | ||
478 | mtk_pcie_msi_free(port, hwirq); | ||
479 | return -EINVAL; | ||
480 | } | ||
481 | |||
482 | chip->dev = &pdev->dev; | ||
483 | |||
484 | irq_set_msi_desc(irq, desc); | ||
485 | |||
486 | /* MT2712/MT7622 only support 32-bit MSI addresses */ | ||
487 | msg_addr = virt_to_phys(port->base + PCIE_MSI_VECTOR); | ||
488 | msg.address_hi = 0; | ||
489 | msg.address_lo = lower_32_bits(msg_addr); | ||
490 | msg.data = hwirq; | ||
491 | |||
492 | pci_write_msi_msg(irq, &msg); | ||
493 | |||
494 | return 0; | ||
495 | } | ||
496 | |||
497 | static void mtk_msi_teardown_irq(struct msi_controller *chip, unsigned int irq) | ||
498 | { | ||
499 | struct pci_dev *pdev = to_pci_dev(chip->dev); | ||
500 | struct irq_data *d = irq_get_irq_data(irq); | ||
501 | irq_hw_number_t hwirq = irqd_to_hwirq(d); | ||
502 | struct mtk_pcie_port *port; | ||
503 | |||
504 | port = mtk_pcie_find_port(pdev->bus, pdev->devfn); | ||
505 | if (!port) | ||
506 | return; | ||
507 | |||
508 | irq_dispose_mapping(irq); | ||
509 | mtk_pcie_msi_free(port, hwirq); | ||
510 | } | ||
511 | |||
512 | static struct msi_controller mtk_pcie_msi_chip = { | ||
513 | .setup_irq = mtk_pcie_msi_setup_irq, | ||
514 | .teardown_irq = mtk_msi_teardown_irq, | ||
515 | }; | ||
516 | |||
517 | static struct irq_chip mtk_msi_irq_chip = { | ||
518 | .name = "MTK PCIe MSI", | ||
519 | .irq_enable = pci_msi_unmask_irq, | ||
520 | .irq_disable = pci_msi_mask_irq, | ||
521 | .irq_mask = pci_msi_mask_irq, | ||
522 | .irq_unmask = pci_msi_unmask_irq, | ||
523 | }; | ||
524 | |||
525 | static int mtk_pcie_msi_map(struct irq_domain *domain, unsigned int irq, | ||
526 | irq_hw_number_t hwirq) | ||
527 | { | ||
528 | irq_set_chip_and_handler(irq, &mtk_msi_irq_chip, handle_simple_irq); | ||
529 | irq_set_chip_data(irq, domain->host_data); | ||
530 | |||
531 | return 0; | ||
532 | } | ||
533 | |||
534 | static const struct irq_domain_ops msi_domain_ops = { | ||
535 | .map = mtk_pcie_msi_map, | ||
536 | }; | ||
537 | |||
538 | static void mtk_pcie_enable_msi(struct mtk_pcie_port *port) | ||
539 | { | ||
540 | u32 val; | ||
541 | phys_addr_t msg_addr; | ||
542 | |||
543 | msg_addr = virt_to_phys(port->base + PCIE_MSI_VECTOR); | ||
544 | val = lower_32_bits(msg_addr); | ||
545 | writel(val, port->base + PCIE_IMSI_ADDR); | ||
546 | |||
547 | val = readl(port->base + PCIE_INT_MASK); | ||
548 | val &= ~MSI_MASK; | ||
549 | writel(val, port->base + PCIE_INT_MASK); | ||
550 | } | ||
551 | |||
552 | static int mtk_pcie_intx_map(struct irq_domain *domain, unsigned int irq, | ||
553 | irq_hw_number_t hwirq) | ||
554 | { | ||
555 | irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq); | ||
556 | irq_set_chip_data(irq, domain->host_data); | ||
557 | |||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | static const struct irq_domain_ops intx_domain_ops = { | ||
562 | .map = mtk_pcie_intx_map, | ||
563 | }; | ||
564 | |||
565 | static int mtk_pcie_init_irq_domain(struct mtk_pcie_port *port, | ||
566 | struct device_node *node) | ||
567 | { | ||
568 | struct device *dev = port->pcie->dev; | ||
569 | struct device_node *pcie_intc_node; | ||
570 | |||
571 | /* Setup INTx */ | ||
572 | pcie_intc_node = of_get_next_child(node, NULL); | ||
573 | if (!pcie_intc_node) { | ||
574 | dev_err(dev, "no PCIe Intc node found\n"); | ||
575 | return -ENODEV; | ||
576 | } | ||
577 | |||
578 | port->irq_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, | ||
579 | &intx_domain_ops, port); | ||
580 | if (!port->irq_domain) { | ||
581 | dev_err(dev, "failed to get INTx IRQ domain\n"); | ||
582 | return -ENODEV; | ||
583 | } | ||
584 | |||
585 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | ||
586 | port->msi_domain = irq_domain_add_linear(node, MTK_MSI_IRQS_NUM, | ||
587 | &msi_domain_ops, | ||
588 | &mtk_pcie_msi_chip); | ||
589 | if (!port->msi_domain) { | ||
590 | dev_err(dev, "failed to create MSI IRQ domain\n"); | ||
591 | return -ENODEV; | ||
592 | } | ||
593 | mtk_pcie_enable_msi(port); | ||
594 | } | ||
595 | |||
596 | return 0; | ||
597 | } | ||
598 | |||
599 | static irqreturn_t mtk_pcie_intr_handler(int irq, void *data) | ||
600 | { | ||
601 | struct mtk_pcie_port *port = (struct mtk_pcie_port *)data; | ||
602 | unsigned long status; | ||
603 | u32 virq; | ||
604 | u32 bit = INTX_SHIFT; | ||
605 | |||
606 | while ((status = readl(port->base + PCIE_INT_STATUS)) & INTX_MASK) { | ||
607 | for_each_set_bit_from(bit, &status, PCI_NUM_INTX + INTX_SHIFT) { | ||
608 | /* Clear the INTx */ | ||
609 | writel(1 << bit, port->base + PCIE_INT_STATUS); | ||
610 | virq = irq_find_mapping(port->irq_domain, | ||
611 | bit - INTX_SHIFT); | ||
612 | generic_handle_irq(virq); | ||
613 | } | ||
614 | } | ||
615 | |||
616 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | ||
617 | while ((status = readl(port->base + PCIE_INT_STATUS)) & MSI_STATUS) { | ||
618 | unsigned long imsi_status; | ||
619 | |||
620 | while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) { | ||
621 | for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM) { | ||
622 | /* Clear the MSI */ | ||
623 | writel(1 << bit, port->base + PCIE_IMSI_STATUS); | ||
624 | virq = irq_find_mapping(port->msi_domain, bit); | ||
625 | generic_handle_irq(virq); | ||
626 | } | ||
627 | } | ||
628 | /* Clear MSI interrupt status */ | ||
629 | writel(MSI_STATUS, port->base + PCIE_INT_STATUS); | ||
630 | } | ||
631 | } | ||
632 | |||
633 | return IRQ_HANDLED; | ||
634 | } | ||
635 | |||
636 | static int mtk_pcie_setup_irq(struct mtk_pcie_port *port, | ||
637 | struct device_node *node) | ||
638 | { | ||
639 | struct mtk_pcie *pcie = port->pcie; | ||
640 | struct device *dev = pcie->dev; | ||
641 | struct platform_device *pdev = to_platform_device(dev); | ||
642 | int err, irq; | ||
643 | |||
644 | irq = platform_get_irq(pdev, port->slot); | ||
645 | err = devm_request_irq(dev, irq, mtk_pcie_intr_handler, | ||
646 | IRQF_SHARED, "mtk-pcie", port); | ||
647 | if (err) { | ||
648 | dev_err(dev, "unable to request IRQ %d\n", irq); | ||
649 | return err; | ||
650 | } | ||
651 | |||
652 | err = mtk_pcie_init_irq_domain(port, node); | ||
653 | if (err) { | ||
654 | dev_err(dev, "failed to init PCIe IRQ domain\n"); | ||
655 | return err; | ||
656 | } | ||
657 | |||
658 | return 0; | ||
659 | } | ||
660 | |||
156 | static void __iomem *mtk_pcie_map_bus(struct pci_bus *bus, | 661 | static void __iomem *mtk_pcie_map_bus(struct pci_bus *bus, |
157 | unsigned int devfn, int where) | 662 | unsigned int devfn, int where) |
158 | { | 663 | { |
159 | struct pci_host_bridge *host = pci_find_host_bridge(bus); | 664 | struct mtk_pcie *pcie = bus->sysdata; |
160 | struct mtk_pcie *pcie = pci_host_bridge_priv(host); | ||
161 | 665 | ||
162 | writel(PCIE_CONF_ADDR(where, PCI_FUNC(devfn), PCI_SLOT(devfn), | 666 | writel(PCIE_CONF_ADDR(where, PCI_FUNC(devfn), PCI_SLOT(devfn), |
163 | bus->number), pcie->base + PCIE_CFG_ADDR); | 667 | bus->number), pcie->base + PCIE_CFG_ADDR); |
@@ -171,16 +675,34 @@ static struct pci_ops mtk_pcie_ops = { | |||
171 | .write = pci_generic_config_write, | 675 | .write = pci_generic_config_write, |
172 | }; | 676 | }; |
173 | 677 | ||
174 | static void mtk_pcie_configure_rc(struct mtk_pcie_port *port) | 678 | static int mtk_pcie_startup_port(struct mtk_pcie_port *port) |
175 | { | 679 | { |
176 | struct mtk_pcie *pcie = port->pcie; | 680 | struct mtk_pcie *pcie = port->pcie; |
177 | u32 func = PCI_FUNC(port->index << 3); | 681 | u32 func = PCI_FUNC(port->slot << 3); |
178 | u32 slot = PCI_SLOT(port->index << 3); | 682 | u32 slot = PCI_SLOT(port->slot << 3); |
179 | u32 val; | 683 | u32 val; |
684 | int err; | ||
685 | |||
686 | /* assert port PERST_N */ | ||
687 | val = readl(pcie->base + PCIE_SYS_CFG); | ||
688 | val |= PCIE_PORT_PERST(port->slot); | ||
689 | writel(val, pcie->base + PCIE_SYS_CFG); | ||
690 | |||
691 | /* de-assert port PERST_N */ | ||
692 | val = readl(pcie->base + PCIE_SYS_CFG); | ||
693 | val &= ~PCIE_PORT_PERST(port->slot); | ||
694 | writel(val, pcie->base + PCIE_SYS_CFG); | ||
695 | |||
696 | /* 100ms timeout value should be enough for Gen1/2 training */ | ||
697 | err = readl_poll_timeout(port->base + PCIE_LINK_STATUS, val, | ||
698 | !!(val & PCIE_PORT_LINKUP), 20, | ||
699 | 100 * USEC_PER_MSEC); | ||
700 | if (err) | ||
701 | return -ETIMEDOUT; | ||
180 | 702 | ||
181 | /* enable interrupt */ | 703 | /* enable interrupt */ |
182 | val = readl(pcie->base + PCIE_INT_ENABLE); | 704 | val = readl(pcie->base + PCIE_INT_ENABLE); |
183 | val |= PCIE_PORT_INT_EN(port->index); | 705 | val |= PCIE_PORT_INT_EN(port->slot); |
184 | writel(val, pcie->base + PCIE_INT_ENABLE); | 706 | writel(val, pcie->base + PCIE_INT_ENABLE); |
185 | 707 | ||
186 | /* map to all DDR region. We need to set it before cfg operation. */ | 708 | /* map to all DDR region. We need to set it before cfg operation. */ |
@@ -209,67 +731,94 @@ static void mtk_pcie_configure_rc(struct mtk_pcie_port *port) | |||
209 | writel(PCIE_CONF_ADDR(PCIE_FTS_NUM, func, slot, 0), | 731 | writel(PCIE_CONF_ADDR(PCIE_FTS_NUM, func, slot, 0), |
210 | pcie->base + PCIE_CFG_ADDR); | 732 | pcie->base + PCIE_CFG_ADDR); |
211 | writel(val, pcie->base + PCIE_CFG_DATA); | 733 | writel(val, pcie->base + PCIE_CFG_DATA); |
734 | |||
735 | return 0; | ||
212 | } | 736 | } |
213 | 737 | ||
214 | static void mtk_pcie_assert_ports(struct mtk_pcie_port *port) | 738 | static void mtk_pcie_enable_port(struct mtk_pcie_port *port) |
215 | { | 739 | { |
216 | struct mtk_pcie *pcie = port->pcie; | 740 | struct mtk_pcie *pcie = port->pcie; |
217 | u32 val; | 741 | struct device *dev = pcie->dev; |
742 | int err; | ||
218 | 743 | ||
219 | /* assert port PERST_N */ | 744 | err = clk_prepare_enable(port->sys_ck); |
220 | val = readl(pcie->base + PCIE_SYS_CFG); | 745 | if (err) { |
221 | val |= PCIE_PORT_PERST(port->index); | 746 | dev_err(dev, "failed to enable sys_ck%d clock\n", port->slot); |
222 | writel(val, pcie->base + PCIE_SYS_CFG); | 747 | goto err_sys_clk; |
748 | } | ||
223 | 749 | ||
224 | /* de-assert port PERST_N */ | 750 | err = clk_prepare_enable(port->ahb_ck); |
225 | val = readl(pcie->base + PCIE_SYS_CFG); | 751 | if (err) { |
226 | val &= ~PCIE_PORT_PERST(port->index); | 752 | dev_err(dev, "failed to enable ahb_ck%d\n", port->slot); |
227 | writel(val, pcie->base + PCIE_SYS_CFG); | 753 | goto err_ahb_clk; |
754 | } | ||
228 | 755 | ||
229 | /* PCIe v2.0 need at least 100ms delay to train from Gen1 to Gen2 */ | 756 | err = clk_prepare_enable(port->aux_ck); |
230 | msleep(100); | 757 | if (err) { |
231 | } | 758 | dev_err(dev, "failed to enable aux_ck%d\n", port->slot); |
759 | goto err_aux_clk; | ||
760 | } | ||
232 | 761 | ||
233 | static void mtk_pcie_enable_ports(struct mtk_pcie_port *port) | 762 | err = clk_prepare_enable(port->axi_ck); |
234 | { | 763 | if (err) { |
235 | struct device *dev = port->pcie->dev; | 764 | dev_err(dev, "failed to enable axi_ck%d\n", port->slot); |
236 | int err; | 765 | goto err_axi_clk; |
766 | } | ||
237 | 767 | ||
238 | err = clk_prepare_enable(port->sys_ck); | 768 | err = clk_prepare_enable(port->obff_ck); |
239 | if (err) { | 769 | if (err) { |
240 | dev_err(dev, "failed to enable port%d clock\n", port->index); | 770 | dev_err(dev, "failed to enable obff_ck%d\n", port->slot); |
241 | goto err_sys_clk; | 771 | goto err_obff_clk; |
772 | } | ||
773 | |||
774 | err = clk_prepare_enable(port->pipe_ck); | ||
775 | if (err) { | ||
776 | dev_err(dev, "failed to enable pipe_ck%d\n", port->slot); | ||
777 | goto err_pipe_clk; | ||
242 | } | 778 | } |
243 | 779 | ||
244 | reset_control_assert(port->reset); | 780 | reset_control_assert(port->reset); |
245 | reset_control_deassert(port->reset); | 781 | reset_control_deassert(port->reset); |
246 | 782 | ||
783 | err = phy_init(port->phy); | ||
784 | if (err) { | ||
785 | dev_err(dev, "failed to initialize port%d phy\n", port->slot); | ||
786 | goto err_phy_init; | ||
787 | } | ||
788 | |||
247 | err = phy_power_on(port->phy); | 789 | err = phy_power_on(port->phy); |
248 | if (err) { | 790 | if (err) { |
249 | dev_err(dev, "failed to power on port%d phy\n", port->index); | 791 | dev_err(dev, "failed to power on port%d phy\n", port->slot); |
250 | goto err_phy_on; | 792 | goto err_phy_on; |
251 | } | 793 | } |
252 | 794 | ||
253 | mtk_pcie_assert_ports(port); | 795 | if (!pcie->soc->startup(port)) |
254 | |||
255 | /* if link up, then setup root port configuration space */ | ||
256 | if (mtk_pcie_link_up(port)) { | ||
257 | mtk_pcie_configure_rc(port); | ||
258 | return; | 796 | return; |
259 | } | ||
260 | 797 | ||
261 | dev_info(dev, "Port%d link down\n", port->index); | 798 | dev_info(dev, "Port%d link down\n", port->slot); |
262 | 799 | ||
263 | phy_power_off(port->phy); | 800 | phy_power_off(port->phy); |
264 | err_phy_on: | 801 | err_phy_on: |
802 | phy_exit(port->phy); | ||
803 | err_phy_init: | ||
804 | clk_disable_unprepare(port->pipe_ck); | ||
805 | err_pipe_clk: | ||
806 | clk_disable_unprepare(port->obff_ck); | ||
807 | err_obff_clk: | ||
808 | clk_disable_unprepare(port->axi_ck); | ||
809 | err_axi_clk: | ||
810 | clk_disable_unprepare(port->aux_ck); | ||
811 | err_aux_clk: | ||
812 | clk_disable_unprepare(port->ahb_ck); | ||
813 | err_ahb_clk: | ||
265 | clk_disable_unprepare(port->sys_ck); | 814 | clk_disable_unprepare(port->sys_ck); |
266 | err_sys_clk: | 815 | err_sys_clk: |
267 | mtk_pcie_port_free(port); | 816 | mtk_pcie_port_free(port); |
268 | } | 817 | } |
269 | 818 | ||
270 | static int mtk_pcie_parse_ports(struct mtk_pcie *pcie, | 819 | static int mtk_pcie_parse_port(struct mtk_pcie *pcie, |
271 | struct device_node *node, | 820 | struct device_node *node, |
272 | int index) | 821 | int slot) |
273 | { | 822 | { |
274 | struct mtk_pcie_port *port; | 823 | struct mtk_pcie_port *port; |
275 | struct resource *regs; | 824 | struct resource *regs; |
@@ -288,34 +837,87 @@ static int mtk_pcie_parse_ports(struct mtk_pcie *pcie, | |||
288 | return err; | 837 | return err; |
289 | } | 838 | } |
290 | 839 | ||
291 | regs = platform_get_resource(pdev, IORESOURCE_MEM, index + 1); | 840 | snprintf(name, sizeof(name), "port%d", slot); |
841 | regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); | ||
292 | port->base = devm_ioremap_resource(dev, regs); | 842 | port->base = devm_ioremap_resource(dev, regs); |
293 | if (IS_ERR(port->base)) { | 843 | if (IS_ERR(port->base)) { |
294 | dev_err(dev, "failed to map port%d base\n", index); | 844 | dev_err(dev, "failed to map port%d base\n", slot); |
295 | return PTR_ERR(port->base); | 845 | return PTR_ERR(port->base); |
296 | } | 846 | } |
297 | 847 | ||
298 | snprintf(name, sizeof(name), "sys_ck%d", index); | 848 | snprintf(name, sizeof(name), "sys_ck%d", slot); |
299 | port->sys_ck = devm_clk_get(dev, name); | 849 | port->sys_ck = devm_clk_get(dev, name); |
300 | if (IS_ERR(port->sys_ck)) { | 850 | if (IS_ERR(port->sys_ck)) { |
301 | dev_err(dev, "failed to get port%d clock\n", index); | 851 | dev_err(dev, "failed to get sys_ck%d clock\n", slot); |
302 | return PTR_ERR(port->sys_ck); | 852 | return PTR_ERR(port->sys_ck); |
303 | } | 853 | } |
304 | 854 | ||
305 | snprintf(name, sizeof(name), "pcie-rst%d", index); | 855 | /* sys_ck might be divided into the following parts in some chips */ |
306 | port->reset = devm_reset_control_get_optional(dev, name); | 856 | snprintf(name, sizeof(name), "ahb_ck%d", slot); |
857 | port->ahb_ck = devm_clk_get(dev, name); | ||
858 | if (IS_ERR(port->ahb_ck)) { | ||
859 | if (PTR_ERR(port->ahb_ck) == -EPROBE_DEFER) | ||
860 | return -EPROBE_DEFER; | ||
861 | |||
862 | port->ahb_ck = NULL; | ||
863 | } | ||
864 | |||
865 | snprintf(name, sizeof(name), "axi_ck%d", slot); | ||
866 | port->axi_ck = devm_clk_get(dev, name); | ||
867 | if (IS_ERR(port->axi_ck)) { | ||
868 | if (PTR_ERR(port->axi_ck) == -EPROBE_DEFER) | ||
869 | return -EPROBE_DEFER; | ||
870 | |||
871 | port->axi_ck = NULL; | ||
872 | } | ||
873 | |||
874 | snprintf(name, sizeof(name), "aux_ck%d", slot); | ||
875 | port->aux_ck = devm_clk_get(dev, name); | ||
876 | if (IS_ERR(port->aux_ck)) { | ||
877 | if (PTR_ERR(port->aux_ck) == -EPROBE_DEFER) | ||
878 | return -EPROBE_DEFER; | ||
879 | |||
880 | port->aux_ck = NULL; | ||
881 | } | ||
882 | |||
883 | snprintf(name, sizeof(name), "obff_ck%d", slot); | ||
884 | port->obff_ck = devm_clk_get(dev, name); | ||
885 | if (IS_ERR(port->obff_ck)) { | ||
886 | if (PTR_ERR(port->obff_ck) == -EPROBE_DEFER) | ||
887 | return -EPROBE_DEFER; | ||
888 | |||
889 | port->obff_ck = NULL; | ||
890 | } | ||
891 | |||
892 | snprintf(name, sizeof(name), "pipe_ck%d", slot); | ||
893 | port->pipe_ck = devm_clk_get(dev, name); | ||
894 | if (IS_ERR(port->pipe_ck)) { | ||
895 | if (PTR_ERR(port->pipe_ck) == -EPROBE_DEFER) | ||
896 | return -EPROBE_DEFER; | ||
897 | |||
898 | port->pipe_ck = NULL; | ||
899 | } | ||
900 | |||
901 | snprintf(name, sizeof(name), "pcie-rst%d", slot); | ||
902 | port->reset = devm_reset_control_get_optional_exclusive(dev, name); | ||
307 | if (PTR_ERR(port->reset) == -EPROBE_DEFER) | 903 | if (PTR_ERR(port->reset) == -EPROBE_DEFER) |
308 | return PTR_ERR(port->reset); | 904 | return PTR_ERR(port->reset); |
309 | 905 | ||
310 | /* some platforms may use default PHY setting */ | 906 | /* some platforms may use default PHY setting */ |
311 | snprintf(name, sizeof(name), "pcie-phy%d", index); | 907 | snprintf(name, sizeof(name), "pcie-phy%d", slot); |
312 | port->phy = devm_phy_optional_get(dev, name); | 908 | port->phy = devm_phy_optional_get(dev, name); |
313 | if (IS_ERR(port->phy)) | 909 | if (IS_ERR(port->phy)) |
314 | return PTR_ERR(port->phy); | 910 | return PTR_ERR(port->phy); |
315 | 911 | ||
316 | port->index = index; | 912 | port->slot = slot; |
317 | port->pcie = pcie; | 913 | port->pcie = pcie; |
318 | 914 | ||
915 | if (pcie->soc->setup_irq) { | ||
916 | err = pcie->soc->setup_irq(port, node); | ||
917 | if (err) | ||
918 | return err; | ||
919 | } | ||
920 | |||
319 | INIT_LIST_HEAD(&port->list); | 921 | INIT_LIST_HEAD(&port->list); |
320 | list_add_tail(&port->list, &pcie->ports); | 922 | list_add_tail(&port->list, &pcie->ports); |
321 | 923 | ||
@@ -329,12 +931,14 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie) | |||
329 | struct resource *regs; | 931 | struct resource *regs; |
330 | int err; | 932 | int err; |
331 | 933 | ||
332 | /* get shared registers */ | 934 | /* get shared registers, which are optional */ |
333 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 935 | regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "subsys"); |
334 | pcie->base = devm_ioremap_resource(dev, regs); | 936 | if (regs) { |
335 | if (IS_ERR(pcie->base)) { | 937 | pcie->base = devm_ioremap_resource(dev, regs); |
336 | dev_err(dev, "failed to map shared register\n"); | 938 | if (IS_ERR(pcie->base)) { |
337 | return PTR_ERR(pcie->base); | 939 | dev_err(dev, "failed to map shared register\n"); |
940 | return PTR_ERR(pcie->base); | ||
941 | } | ||
338 | } | 942 | } |
339 | 943 | ||
340 | pcie->free_ck = devm_clk_get(dev, "free_ck"); | 944 | pcie->free_ck = devm_clk_get(dev, "free_ck"); |
@@ -422,7 +1026,7 @@ static int mtk_pcie_setup(struct mtk_pcie *pcie) | |||
422 | } | 1026 | } |
423 | 1027 | ||
424 | for_each_available_child_of_node(node, child) { | 1028 | for_each_available_child_of_node(node, child) { |
425 | int index; | 1029 | int slot; |
426 | 1030 | ||
427 | err = of_pci_get_devfn(child); | 1031 | err = of_pci_get_devfn(child); |
428 | if (err < 0) { | 1032 | if (err < 0) { |
@@ -430,9 +1034,9 @@ static int mtk_pcie_setup(struct mtk_pcie *pcie) | |||
430 | return err; | 1034 | return err; |
431 | } | 1035 | } |
432 | 1036 | ||
433 | index = PCI_SLOT(err); | 1037 | slot = PCI_SLOT(err); |
434 | 1038 | ||
435 | err = mtk_pcie_parse_ports(pcie, child, index); | 1039 | err = mtk_pcie_parse_port(pcie, child, slot); |
436 | if (err) | 1040 | if (err) |
437 | return err; | 1041 | return err; |
438 | } | 1042 | } |
@@ -443,7 +1047,7 @@ static int mtk_pcie_setup(struct mtk_pcie *pcie) | |||
443 | 1047 | ||
444 | /* enable each port, and then check link status */ | 1048 | /* enable each port, and then check link status */ |
445 | list_for_each_entry_safe(port, tmp, &pcie->ports, list) | 1049 | list_for_each_entry_safe(port, tmp, &pcie->ports, list) |
446 | mtk_pcie_enable_ports(port); | 1050 | mtk_pcie_enable_port(port); |
447 | 1051 | ||
448 | /* power down PCIe subsys if slots are all empty (link down) */ | 1052 | /* power down PCIe subsys if slots are all empty (link down) */ |
449 | if (list_empty(&pcie->ports)) | 1053 | if (list_empty(&pcie->ports)) |
@@ -480,9 +1084,12 @@ static int mtk_pcie_register_host(struct pci_host_bridge *host) | |||
480 | 1084 | ||
481 | host->busnr = pcie->busn.start; | 1085 | host->busnr = pcie->busn.start; |
482 | host->dev.parent = pcie->dev; | 1086 | host->dev.parent = pcie->dev; |
483 | host->ops = &mtk_pcie_ops; | 1087 | host->ops = pcie->soc->ops; |
484 | host->map_irq = of_irq_parse_and_map_pci; | 1088 | host->map_irq = of_irq_parse_and_map_pci; |
485 | host->swizzle_irq = pci_common_swizzle; | 1089 | host->swizzle_irq = pci_common_swizzle; |
1090 | host->sysdata = pcie; | ||
1091 | if (IS_ENABLED(CONFIG_PCI_MSI) && pcie->soc->has_msi) | ||
1092 | host->msi = &mtk_pcie_msi_chip; | ||
486 | 1093 | ||
487 | err = pci_scan_root_bus_bridge(host); | 1094 | err = pci_scan_root_bus_bridge(host); |
488 | if (err < 0) | 1095 | if (err < 0) |
@@ -513,6 +1120,7 @@ static int mtk_pcie_probe(struct platform_device *pdev) | |||
513 | pcie = pci_host_bridge_priv(host); | 1120 | pcie = pci_host_bridge_priv(host); |
514 | 1121 | ||
515 | pcie->dev = dev; | 1122 | pcie->dev = dev; |
1123 | pcie->soc = of_device_get_match_data(dev); | ||
516 | platform_set_drvdata(pdev, pcie); | 1124 | platform_set_drvdata(pdev, pcie); |
517 | INIT_LIST_HEAD(&pcie->ports); | 1125 | INIT_LIST_HEAD(&pcie->ports); |
518 | 1126 | ||
@@ -537,9 +1145,23 @@ put_resources: | |||
537 | return err; | 1145 | return err; |
538 | } | 1146 | } |
539 | 1147 | ||
1148 | static const struct mtk_pcie_soc mtk_pcie_soc_v1 = { | ||
1149 | .ops = &mtk_pcie_ops, | ||
1150 | .startup = mtk_pcie_startup_port, | ||
1151 | }; | ||
1152 | |||
1153 | static const struct mtk_pcie_soc mtk_pcie_soc_v2 = { | ||
1154 | .has_msi = true, | ||
1155 | .ops = &mtk_pcie_ops_v2, | ||
1156 | .startup = mtk_pcie_startup_port_v2, | ||
1157 | .setup_irq = mtk_pcie_setup_irq, | ||
1158 | }; | ||
1159 | |||
540 | static const struct of_device_id mtk_pcie_ids[] = { | 1160 | static const struct of_device_id mtk_pcie_ids[] = { |
541 | { .compatible = "mediatek,mt7623-pcie"}, | 1161 | { .compatible = "mediatek,mt2701-pcie", .data = &mtk_pcie_soc_v1 }, |
542 | { .compatible = "mediatek,mt2701-pcie"}, | 1162 | { .compatible = "mediatek,mt7623-pcie", .data = &mtk_pcie_soc_v1 }, |
1163 | { .compatible = "mediatek,mt2712-pcie", .data = &mtk_pcie_soc_v2 }, | ||
1164 | { .compatible = "mediatek,mt7622-pcie", .data = &mtk_pcie_soc_v2 }, | ||
543 | {}, | 1165 | {}, |
544 | }; | 1166 | }; |
545 | 1167 | ||
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 246d485b24c6..4e0b25d09b0c 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c | |||
@@ -471,10 +471,8 @@ static int rcar_pcie_enable(struct rcar_pcie *pcie) | |||
471 | bridge->msi = &pcie->msi.chip; | 471 | bridge->msi = &pcie->msi.chip; |
472 | 472 | ||
473 | ret = pci_scan_root_bus_bridge(bridge); | 473 | ret = pci_scan_root_bus_bridge(bridge); |
474 | if (ret < 0) { | 474 | if (ret < 0) |
475 | kfree(bridge); | ||
476 | return ret; | 475 | return ret; |
477 | } | ||
478 | 476 | ||
479 | bus = bridge->bus; | 477 | bus = bridge->bus; |
480 | 478 | ||
@@ -1190,14 +1188,16 @@ static int rcar_pcie_probe(struct platform_device *pdev) | |||
1190 | 1188 | ||
1191 | return 0; | 1189 | return 0; |
1192 | 1190 | ||
1193 | err_free_bridge: | ||
1194 | pci_free_host_bridge(bridge); | ||
1195 | |||
1196 | err_pm_put: | 1191 | err_pm_put: |
1197 | pm_runtime_put(dev); | 1192 | pm_runtime_put(dev); |
1198 | 1193 | ||
1199 | err_pm_disable: | 1194 | err_pm_disable: |
1200 | pm_runtime_disable(dev); | 1195 | pm_runtime_disable(dev); |
1196 | |||
1197 | err_free_bridge: | ||
1198 | pci_free_host_bridge(bridge); | ||
1199 | pci_free_resource_list(&pcie->resources); | ||
1200 | |||
1201 | return err; | 1201 | return err; |
1202 | } | 1202 | } |
1203 | 1203 | ||
diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c index 7bb9870f6d8c..9051c6c8fea4 100644 --- a/drivers/pci/host/pcie-rockchip.c +++ b/drivers/pci/host/pcie-rockchip.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Author: Shawn Lin <shawn.lin@rock-chips.com> | 6 | * Author: Shawn Lin <shawn.lin@rock-chips.com> |
7 | * Wenrui Li <wenrui.li@rock-chips.com> | 7 | * Wenrui Li <wenrui.li@rock-chips.com> |
8 | * | 8 | * |
9 | * Bits taken from Synopsys Designware Host controller driver and | 9 | * Bits taken from Synopsys DesignWare Host controller driver and |
10 | * ARM PCI Host generic driver. | 10 | * ARM PCI Host generic driver. |
11 | * | 11 | * |
12 | * This program is free software: you can redistribute it and/or modify | 12 | * This program is free software: you can redistribute it and/or modify |
@@ -15,6 +15,7 @@ | |||
15 | * (at your option) any later version. | 15 | * (at your option) any later version. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/bitrev.h> | ||
18 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
19 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
20 | #include <linux/gpio/consumer.h> | 21 | #include <linux/gpio/consumer.h> |
@@ -47,6 +48,7 @@ | |||
47 | #define HIWORD_UPDATE_BIT(val) HIWORD_UPDATE(val, val) | 48 | #define HIWORD_UPDATE_BIT(val) HIWORD_UPDATE(val, val) |
48 | 49 | ||
49 | #define ENCODE_LANES(x) ((((x) >> 1) & 3) << 4) | 50 | #define ENCODE_LANES(x) ((((x) >> 1) & 3) << 4) |
51 | #define MAX_LANE_NUM 4 | ||
50 | 52 | ||
51 | #define PCIE_CLIENT_BASE 0x0 | 53 | #define PCIE_CLIENT_BASE 0x0 |
52 | #define PCIE_CLIENT_CONFIG (PCIE_CLIENT_BASE + 0x00) | 54 | #define PCIE_CLIENT_CONFIG (PCIE_CLIENT_BASE + 0x00) |
@@ -111,6 +113,9 @@ | |||
111 | #define PCIE_CORE_TXCREDIT_CFG1_MUI_SHIFT 16 | 113 | #define PCIE_CORE_TXCREDIT_CFG1_MUI_SHIFT 16 |
112 | #define PCIE_CORE_TXCREDIT_CFG1_MUI_ENCODE(x) \ | 114 | #define PCIE_CORE_TXCREDIT_CFG1_MUI_ENCODE(x) \ |
113 | (((x) >> 3) << PCIE_CORE_TXCREDIT_CFG1_MUI_SHIFT) | 115 | (((x) >> 3) << PCIE_CORE_TXCREDIT_CFG1_MUI_SHIFT) |
116 | #define PCIE_CORE_LANE_MAP (PCIE_CORE_CTRL_MGMT_BASE + 0x200) | ||
117 | #define PCIE_CORE_LANE_MAP_MASK 0x0000000f | ||
118 | #define PCIE_CORE_LANE_MAP_REVERSE BIT(16) | ||
114 | #define PCIE_CORE_INT_STATUS (PCIE_CORE_CTRL_MGMT_BASE + 0x20c) | 119 | #define PCIE_CORE_INT_STATUS (PCIE_CORE_CTRL_MGMT_BASE + 0x20c) |
115 | #define PCIE_CORE_INT_PRFPE BIT(0) | 120 | #define PCIE_CORE_INT_PRFPE BIT(0) |
116 | #define PCIE_CORE_INT_CRFPE BIT(1) | 121 | #define PCIE_CORE_INT_CRFPE BIT(1) |
@@ -210,7 +215,8 @@ | |||
210 | struct rockchip_pcie { | 215 | struct rockchip_pcie { |
211 | void __iomem *reg_base; /* DT axi-base */ | 216 | void __iomem *reg_base; /* DT axi-base */ |
212 | void __iomem *apb_base; /* DT apb-base */ | 217 | void __iomem *apb_base; /* DT apb-base */ |
213 | struct phy *phy; | 218 | bool legacy_phy; |
219 | struct phy *phys[MAX_LANE_NUM]; | ||
214 | struct reset_control *core_rst; | 220 | struct reset_control *core_rst; |
215 | struct reset_control *mgmt_rst; | 221 | struct reset_control *mgmt_rst; |
216 | struct reset_control *mgmt_sticky_rst; | 222 | struct reset_control *mgmt_sticky_rst; |
@@ -222,11 +228,13 @@ struct rockchip_pcie { | |||
222 | struct clk *aclk_perf_pcie; | 228 | struct clk *aclk_perf_pcie; |
223 | struct clk *hclk_pcie; | 229 | struct clk *hclk_pcie; |
224 | struct clk *clk_pcie_pm; | 230 | struct clk *clk_pcie_pm; |
231 | struct regulator *vpcie12v; /* 12V power supply */ | ||
225 | struct regulator *vpcie3v3; /* 3.3V power supply */ | 232 | struct regulator *vpcie3v3; /* 3.3V power supply */ |
226 | struct regulator *vpcie1v8; /* 1.8V power supply */ | 233 | struct regulator *vpcie1v8; /* 1.8V power supply */ |
227 | struct regulator *vpcie0v9; /* 0.9V power supply */ | 234 | struct regulator *vpcie0v9; /* 0.9V power supply */ |
228 | struct gpio_desc *ep_gpio; | 235 | struct gpio_desc *ep_gpio; |
229 | u32 lanes; | 236 | u32 lanes; |
237 | u8 lanes_map; | ||
230 | u8 root_bus_nr; | 238 | u8 root_bus_nr; |
231 | int link_gen; | 239 | int link_gen; |
232 | struct device *dev; | 240 | struct device *dev; |
@@ -299,6 +307,24 @@ static int rockchip_pcie_valid_device(struct rockchip_pcie *rockchip, | |||
299 | return 1; | 307 | return 1; |
300 | } | 308 | } |
301 | 309 | ||
310 | static u8 rockchip_pcie_lane_map(struct rockchip_pcie *rockchip) | ||
311 | { | ||
312 | u32 val; | ||
313 | u8 map; | ||
314 | |||
315 | if (rockchip->legacy_phy) | ||
316 | return GENMASK(MAX_LANE_NUM - 1, 0); | ||
317 | |||
318 | val = rockchip_pcie_read(rockchip, PCIE_CORE_LANE_MAP); | ||
319 | map = val & PCIE_CORE_LANE_MAP_MASK; | ||
320 | |||
321 | /* The link may be using a reverse-indexed mapping. */ | ||
322 | if (val & PCIE_CORE_LANE_MAP_REVERSE) | ||
323 | map = bitrev8(map) >> 4; | ||
324 | |||
325 | return map; | ||
326 | } | ||
327 | |||
302 | static int rockchip_pcie_rd_own_conf(struct rockchip_pcie *rockchip, | 328 | static int rockchip_pcie_rd_own_conf(struct rockchip_pcie *rockchip, |
303 | int where, int size, u32 *val) | 329 | int where, int size, u32 *val) |
304 | { | 330 | { |
@@ -514,10 +540,10 @@ static void rockchip_pcie_set_power_limit(struct rockchip_pcie *rockchip) | |||
514 | static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | 540 | static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) |
515 | { | 541 | { |
516 | struct device *dev = rockchip->dev; | 542 | struct device *dev = rockchip->dev; |
517 | int err; | 543 | int err, i; |
518 | u32 status; | 544 | u32 status; |
519 | 545 | ||
520 | gpiod_set_value(rockchip->ep_gpio, 0); | 546 | gpiod_set_value_cansleep(rockchip->ep_gpio, 0); |
521 | 547 | ||
522 | err = reset_control_assert(rockchip->aclk_rst); | 548 | err = reset_control_assert(rockchip->aclk_rst); |
523 | if (err) { | 549 | if (err) { |
@@ -537,34 +563,36 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
537 | return err; | 563 | return err; |
538 | } | 564 | } |
539 | 565 | ||
540 | err = phy_init(rockchip->phy); | 566 | for (i = 0; i < MAX_LANE_NUM; i++) { |
541 | if (err < 0) { | 567 | err = phy_init(rockchip->phys[i]); |
542 | dev_err(dev, "fail to init phy, err %d\n", err); | 568 | if (err) { |
543 | return err; | 569 | dev_err(dev, "init phy%d err %d\n", i, err); |
570 | goto err_exit_phy; | ||
571 | } | ||
544 | } | 572 | } |
545 | 573 | ||
546 | err = reset_control_assert(rockchip->core_rst); | 574 | err = reset_control_assert(rockchip->core_rst); |
547 | if (err) { | 575 | if (err) { |
548 | dev_err(dev, "assert core_rst err %d\n", err); | 576 | dev_err(dev, "assert core_rst err %d\n", err); |
549 | return err; | 577 | goto err_exit_phy; |
550 | } | 578 | } |
551 | 579 | ||
552 | err = reset_control_assert(rockchip->mgmt_rst); | 580 | err = reset_control_assert(rockchip->mgmt_rst); |
553 | if (err) { | 581 | if (err) { |
554 | dev_err(dev, "assert mgmt_rst err %d\n", err); | 582 | dev_err(dev, "assert mgmt_rst err %d\n", err); |
555 | return err; | 583 | goto err_exit_phy; |
556 | } | 584 | } |
557 | 585 | ||
558 | err = reset_control_assert(rockchip->mgmt_sticky_rst); | 586 | err = reset_control_assert(rockchip->mgmt_sticky_rst); |
559 | if (err) { | 587 | if (err) { |
560 | dev_err(dev, "assert mgmt_sticky_rst err %d\n", err); | 588 | dev_err(dev, "assert mgmt_sticky_rst err %d\n", err); |
561 | return err; | 589 | goto err_exit_phy; |
562 | } | 590 | } |
563 | 591 | ||
564 | err = reset_control_assert(rockchip->pipe_rst); | 592 | err = reset_control_assert(rockchip->pipe_rst); |
565 | if (err) { | 593 | if (err) { |
566 | dev_err(dev, "assert pipe_rst err %d\n", err); | 594 | dev_err(dev, "assert pipe_rst err %d\n", err); |
567 | return err; | 595 | goto err_exit_phy; |
568 | } | 596 | } |
569 | 597 | ||
570 | udelay(10); | 598 | udelay(10); |
@@ -572,19 +600,19 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
572 | err = reset_control_deassert(rockchip->pm_rst); | 600 | err = reset_control_deassert(rockchip->pm_rst); |
573 | if (err) { | 601 | if (err) { |
574 | dev_err(dev, "deassert pm_rst err %d\n", err); | 602 | dev_err(dev, "deassert pm_rst err %d\n", err); |
575 | return err; | 603 | goto err_exit_phy; |
576 | } | 604 | } |
577 | 605 | ||
578 | err = reset_control_deassert(rockchip->aclk_rst); | 606 | err = reset_control_deassert(rockchip->aclk_rst); |
579 | if (err) { | 607 | if (err) { |
580 | dev_err(dev, "deassert aclk_rst err %d\n", err); | 608 | dev_err(dev, "deassert aclk_rst err %d\n", err); |
581 | return err; | 609 | goto err_exit_phy; |
582 | } | 610 | } |
583 | 611 | ||
584 | err = reset_control_deassert(rockchip->pclk_rst); | 612 | err = reset_control_deassert(rockchip->pclk_rst); |
585 | if (err) { | 613 | if (err) { |
586 | dev_err(dev, "deassert pclk_rst err %d\n", err); | 614 | dev_err(dev, "deassert pclk_rst err %d\n", err); |
587 | return err; | 615 | goto err_exit_phy; |
588 | } | 616 | } |
589 | 617 | ||
590 | if (rockchip->link_gen == 2) | 618 | if (rockchip->link_gen == 2) |
@@ -602,10 +630,12 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
602 | PCIE_CLIENT_MODE_RC, | 630 | PCIE_CLIENT_MODE_RC, |
603 | PCIE_CLIENT_CONFIG); | 631 | PCIE_CLIENT_CONFIG); |
604 | 632 | ||
605 | err = phy_power_on(rockchip->phy); | 633 | for (i = 0; i < MAX_LANE_NUM; i++) { |
606 | if (err) { | 634 | err = phy_power_on(rockchip->phys[i]); |
607 | dev_err(dev, "fail to power on phy, err %d\n", err); | 635 | if (err) { |
608 | return err; | 636 | dev_err(dev, "power on phy%d err %d\n", i, err); |
637 | goto err_power_off_phy; | ||
638 | } | ||
609 | } | 639 | } |
610 | 640 | ||
611 | /* | 641 | /* |
@@ -615,25 +645,25 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
615 | err = reset_control_deassert(rockchip->mgmt_sticky_rst); | 645 | err = reset_control_deassert(rockchip->mgmt_sticky_rst); |
616 | if (err) { | 646 | if (err) { |
617 | dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err); | 647 | dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err); |
618 | return err; | 648 | goto err_power_off_phy; |
619 | } | 649 | } |
620 | 650 | ||
621 | err = reset_control_deassert(rockchip->core_rst); | 651 | err = reset_control_deassert(rockchip->core_rst); |
622 | if (err) { | 652 | if (err) { |
623 | dev_err(dev, "deassert core_rst err %d\n", err); | 653 | dev_err(dev, "deassert core_rst err %d\n", err); |
624 | return err; | 654 | goto err_power_off_phy; |
625 | } | 655 | } |
626 | 656 | ||
627 | err = reset_control_deassert(rockchip->mgmt_rst); | 657 | err = reset_control_deassert(rockchip->mgmt_rst); |
628 | if (err) { | 658 | if (err) { |
629 | dev_err(dev, "deassert mgmt_rst err %d\n", err); | 659 | dev_err(dev, "deassert mgmt_rst err %d\n", err); |
630 | return err; | 660 | goto err_power_off_phy; |
631 | } | 661 | } |
632 | 662 | ||
633 | err = reset_control_deassert(rockchip->pipe_rst); | 663 | err = reset_control_deassert(rockchip->pipe_rst); |
634 | if (err) { | 664 | if (err) { |
635 | dev_err(dev, "deassert pipe_rst err %d\n", err); | 665 | dev_err(dev, "deassert pipe_rst err %d\n", err); |
636 | return err; | 666 | goto err_power_off_phy; |
637 | } | 667 | } |
638 | 668 | ||
639 | /* Fix the transmitted FTS count desired to exit from L0s. */ | 669 | /* Fix the transmitted FTS count desired to exit from L0s. */ |
@@ -658,7 +688,7 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
658 | rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE, | 688 | rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE, |
659 | PCIE_CLIENT_CONFIG); | 689 | PCIE_CLIENT_CONFIG); |
660 | 690 | ||
661 | gpiod_set_value(rockchip->ep_gpio, 1); | 691 | gpiod_set_value_cansleep(rockchip->ep_gpio, 1); |
662 | 692 | ||
663 | /* 500ms timeout value should be enough for Gen1/2 training */ | 693 | /* 500ms timeout value should be enough for Gen1/2 training */ |
664 | err = readl_poll_timeout(rockchip->apb_base + PCIE_CLIENT_BASIC_STATUS1, | 694 | err = readl_poll_timeout(rockchip->apb_base + PCIE_CLIENT_BASIC_STATUS1, |
@@ -666,7 +696,7 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
666 | 500 * USEC_PER_MSEC); | 696 | 500 * USEC_PER_MSEC); |
667 | if (err) { | 697 | if (err) { |
668 | dev_err(dev, "PCIe link training gen1 timeout!\n"); | 698 | dev_err(dev, "PCIe link training gen1 timeout!\n"); |
669 | return -ETIMEDOUT; | 699 | goto err_power_off_phy; |
670 | } | 700 | } |
671 | 701 | ||
672 | if (rockchip->link_gen == 2) { | 702 | if (rockchip->link_gen == 2) { |
@@ -691,6 +721,15 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
691 | PCIE_CORE_PL_CONF_LANE_SHIFT); | 721 | PCIE_CORE_PL_CONF_LANE_SHIFT); |
692 | dev_dbg(dev, "current link width is x%d\n", status); | 722 | dev_dbg(dev, "current link width is x%d\n", status); |
693 | 723 | ||
724 | /* Power off unused lane(s) */ | ||
725 | rockchip->lanes_map = rockchip_pcie_lane_map(rockchip); | ||
726 | for (i = 0; i < MAX_LANE_NUM; i++) { | ||
727 | if (!(rockchip->lanes_map & BIT(i))) { | ||
728 | dev_dbg(dev, "idling lane %d\n", i); | ||
729 | phy_power_off(rockchip->phys[i]); | ||
730 | } | ||
731 | } | ||
732 | |||
694 | rockchip_pcie_write(rockchip, ROCKCHIP_VENDOR_ID, | 733 | rockchip_pcie_write(rockchip, ROCKCHIP_VENDOR_ID, |
695 | PCIE_CORE_CONFIG_VENDOR); | 734 | PCIE_CORE_CONFIG_VENDOR); |
696 | rockchip_pcie_write(rockchip, | 735 | rockchip_pcie_write(rockchip, |
@@ -715,6 +754,26 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
715 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_DCSR); | 754 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_DCSR); |
716 | 755 | ||
717 | return 0; | 756 | return 0; |
757 | err_power_off_phy: | ||
758 | while (i--) | ||
759 | phy_power_off(rockchip->phys[i]); | ||
760 | i = MAX_LANE_NUM; | ||
761 | err_exit_phy: | ||
762 | while (i--) | ||
763 | phy_exit(rockchip->phys[i]); | ||
764 | return err; | ||
765 | } | ||
766 | |||
767 | static void rockchip_pcie_deinit_phys(struct rockchip_pcie *rockchip) | ||
768 | { | ||
769 | int i; | ||
770 | |||
771 | for (i = 0; i < MAX_LANE_NUM; i++) { | ||
772 | /* inactive lanes are already powered off */ | ||
773 | if (rockchip->lanes_map & BIT(i)) | ||
774 | phy_power_off(rockchip->phys[i]); | ||
775 | phy_exit(rockchip->phys[i]); | ||
776 | } | ||
718 | } | 777 | } |
719 | 778 | ||
720 | static irqreturn_t rockchip_pcie_subsys_irq_handler(int irq, void *arg) | 779 | static irqreturn_t rockchip_pcie_subsys_irq_handler(int irq, void *arg) |
@@ -853,6 +912,91 @@ static void rockchip_pcie_legacy_int_handler(struct irq_desc *desc) | |||
853 | chained_irq_exit(chip, desc); | 912 | chained_irq_exit(chip, desc); |
854 | } | 913 | } |
855 | 914 | ||
915 | static int rockchip_pcie_get_phys(struct rockchip_pcie *rockchip) | ||
916 | { | ||
917 | struct device *dev = rockchip->dev; | ||
918 | struct phy *phy; | ||
919 | char *name; | ||
920 | u32 i; | ||
921 | |||
922 | phy = devm_phy_get(dev, "pcie-phy"); | ||
923 | if (!IS_ERR(phy)) { | ||
924 | rockchip->legacy_phy = true; | ||
925 | rockchip->phys[0] = phy; | ||
926 | dev_warn(dev, "legacy phy model is deprecated!\n"); | ||
927 | return 0; | ||
928 | } | ||
929 | |||
930 | if (PTR_ERR(phy) == -EPROBE_DEFER) | ||
931 | return PTR_ERR(phy); | ||
932 | |||
933 | dev_dbg(dev, "missing legacy phy; search for per-lane PHY\n"); | ||
934 | |||
935 | for (i = 0; i < MAX_LANE_NUM; i++) { | ||
936 | name = kasprintf(GFP_KERNEL, "pcie-phy-%u", i); | ||
937 | if (!name) | ||
938 | return -ENOMEM; | ||
939 | |||
940 | phy = devm_of_phy_get(dev, dev->of_node, name); | ||
941 | kfree(name); | ||
942 | |||
943 | if (IS_ERR(phy)) { | ||
944 | if (PTR_ERR(phy) != -EPROBE_DEFER) | ||
945 | dev_err(dev, "missing phy for lane %d: %ld\n", | ||
946 | i, PTR_ERR(phy)); | ||
947 | return PTR_ERR(phy); | ||
948 | } | ||
949 | |||
950 | rockchip->phys[i] = phy; | ||
951 | } | ||
952 | |||
953 | return 0; | ||
954 | } | ||
955 | |||
956 | static int rockchip_pcie_setup_irq(struct rockchip_pcie *rockchip) | ||
957 | { | ||
958 | int irq, err; | ||
959 | struct device *dev = rockchip->dev; | ||
960 | struct platform_device *pdev = to_platform_device(dev); | ||
961 | |||
962 | irq = platform_get_irq_byname(pdev, "sys"); | ||
963 | if (irq < 0) { | ||
964 | dev_err(dev, "missing sys IRQ resource\n"); | ||
965 | return irq; | ||
966 | } | ||
967 | |||
968 | err = devm_request_irq(dev, irq, rockchip_pcie_subsys_irq_handler, | ||
969 | IRQF_SHARED, "pcie-sys", rockchip); | ||
970 | if (err) { | ||
971 | dev_err(dev, "failed to request PCIe subsystem IRQ\n"); | ||
972 | return err; | ||
973 | } | ||
974 | |||
975 | irq = platform_get_irq_byname(pdev, "legacy"); | ||
976 | if (irq < 0) { | ||
977 | dev_err(dev, "missing legacy IRQ resource\n"); | ||
978 | return irq; | ||
979 | } | ||
980 | |||
981 | irq_set_chained_handler_and_data(irq, | ||
982 | rockchip_pcie_legacy_int_handler, | ||
983 | rockchip); | ||
984 | |||
985 | irq = platform_get_irq_byname(pdev, "client"); | ||
986 | if (irq < 0) { | ||
987 | dev_err(dev, "missing client IRQ resource\n"); | ||
988 | return irq; | ||
989 | } | ||
990 | |||
991 | err = devm_request_irq(dev, irq, rockchip_pcie_client_irq_handler, | ||
992 | IRQF_SHARED, "pcie-client", rockchip); | ||
993 | if (err) { | ||
994 | dev_err(dev, "failed to request PCIe client IRQ\n"); | ||
995 | return err; | ||
996 | } | ||
997 | |||
998 | return 0; | ||
999 | } | ||
856 | 1000 | ||
857 | /** | 1001 | /** |
858 | * rockchip_pcie_parse_dt - Parse Device Tree | 1002 | * rockchip_pcie_parse_dt - Parse Device Tree |
@@ -866,7 +1010,6 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) | |||
866 | struct platform_device *pdev = to_platform_device(dev); | 1010 | struct platform_device *pdev = to_platform_device(dev); |
867 | struct device_node *node = dev->of_node; | 1011 | struct device_node *node = dev->of_node; |
868 | struct resource *regs; | 1012 | struct resource *regs; |
869 | int irq; | ||
870 | int err; | 1013 | int err; |
871 | 1014 | ||
872 | regs = platform_get_resource_byname(pdev, | 1015 | regs = platform_get_resource_byname(pdev, |
@@ -883,12 +1026,9 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) | |||
883 | if (IS_ERR(rockchip->apb_base)) | 1026 | if (IS_ERR(rockchip->apb_base)) |
884 | return PTR_ERR(rockchip->apb_base); | 1027 | return PTR_ERR(rockchip->apb_base); |
885 | 1028 | ||
886 | rockchip->phy = devm_phy_get(dev, "pcie-phy"); | 1029 | err = rockchip_pcie_get_phys(rockchip); |
887 | if (IS_ERR(rockchip->phy)) { | 1030 | if (err) |
888 | if (PTR_ERR(rockchip->phy) != -EPROBE_DEFER) | 1031 | return err; |
889 | dev_err(dev, "missing phy\n"); | ||
890 | return PTR_ERR(rockchip->phy); | ||
891 | } | ||
892 | 1032 | ||
893 | rockchip->lanes = 1; | 1033 | rockchip->lanes = 1; |
894 | err = of_property_read_u32(node, "num-lanes", &rockchip->lanes); | 1034 | err = of_property_read_u32(node, "num-lanes", &rockchip->lanes); |
@@ -903,49 +1043,50 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) | |||
903 | if (rockchip->link_gen < 0 || rockchip->link_gen > 2) | 1043 | if (rockchip->link_gen < 0 || rockchip->link_gen > 2) |
904 | rockchip->link_gen = 2; | 1044 | rockchip->link_gen = 2; |
905 | 1045 | ||
906 | rockchip->core_rst = devm_reset_control_get(dev, "core"); | 1046 | rockchip->core_rst = devm_reset_control_get_exclusive(dev, "core"); |
907 | if (IS_ERR(rockchip->core_rst)) { | 1047 | if (IS_ERR(rockchip->core_rst)) { |
908 | if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER) | 1048 | if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER) |
909 | dev_err(dev, "missing core reset property in node\n"); | 1049 | dev_err(dev, "missing core reset property in node\n"); |
910 | return PTR_ERR(rockchip->core_rst); | 1050 | return PTR_ERR(rockchip->core_rst); |
911 | } | 1051 | } |
912 | 1052 | ||
913 | rockchip->mgmt_rst = devm_reset_control_get(dev, "mgmt"); | 1053 | rockchip->mgmt_rst = devm_reset_control_get_exclusive(dev, "mgmt"); |
914 | if (IS_ERR(rockchip->mgmt_rst)) { | 1054 | if (IS_ERR(rockchip->mgmt_rst)) { |
915 | if (PTR_ERR(rockchip->mgmt_rst) != -EPROBE_DEFER) | 1055 | if (PTR_ERR(rockchip->mgmt_rst) != -EPROBE_DEFER) |
916 | dev_err(dev, "missing mgmt reset property in node\n"); | 1056 | dev_err(dev, "missing mgmt reset property in node\n"); |
917 | return PTR_ERR(rockchip->mgmt_rst); | 1057 | return PTR_ERR(rockchip->mgmt_rst); |
918 | } | 1058 | } |
919 | 1059 | ||
920 | rockchip->mgmt_sticky_rst = devm_reset_control_get(dev, "mgmt-sticky"); | 1060 | rockchip->mgmt_sticky_rst = devm_reset_control_get_exclusive(dev, |
1061 | "mgmt-sticky"); | ||
921 | if (IS_ERR(rockchip->mgmt_sticky_rst)) { | 1062 | if (IS_ERR(rockchip->mgmt_sticky_rst)) { |
922 | if (PTR_ERR(rockchip->mgmt_sticky_rst) != -EPROBE_DEFER) | 1063 | if (PTR_ERR(rockchip->mgmt_sticky_rst) != -EPROBE_DEFER) |
923 | dev_err(dev, "missing mgmt-sticky reset property in node\n"); | 1064 | dev_err(dev, "missing mgmt-sticky reset property in node\n"); |
924 | return PTR_ERR(rockchip->mgmt_sticky_rst); | 1065 | return PTR_ERR(rockchip->mgmt_sticky_rst); |
925 | } | 1066 | } |
926 | 1067 | ||
927 | rockchip->pipe_rst = devm_reset_control_get(dev, "pipe"); | 1068 | rockchip->pipe_rst = devm_reset_control_get_exclusive(dev, "pipe"); |
928 | if (IS_ERR(rockchip->pipe_rst)) { | 1069 | if (IS_ERR(rockchip->pipe_rst)) { |
929 | if (PTR_ERR(rockchip->pipe_rst) != -EPROBE_DEFER) | 1070 | if (PTR_ERR(rockchip->pipe_rst) != -EPROBE_DEFER) |
930 | dev_err(dev, "missing pipe reset property in node\n"); | 1071 | dev_err(dev, "missing pipe reset property in node\n"); |
931 | return PTR_ERR(rockchip->pipe_rst); | 1072 | return PTR_ERR(rockchip->pipe_rst); |
932 | } | 1073 | } |
933 | 1074 | ||
934 | rockchip->pm_rst = devm_reset_control_get(dev, "pm"); | 1075 | rockchip->pm_rst = devm_reset_control_get_exclusive(dev, "pm"); |
935 | if (IS_ERR(rockchip->pm_rst)) { | 1076 | if (IS_ERR(rockchip->pm_rst)) { |
936 | if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER) | 1077 | if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER) |
937 | dev_err(dev, "missing pm reset property in node\n"); | 1078 | dev_err(dev, "missing pm reset property in node\n"); |
938 | return PTR_ERR(rockchip->pm_rst); | 1079 | return PTR_ERR(rockchip->pm_rst); |
939 | } | 1080 | } |
940 | 1081 | ||
941 | rockchip->pclk_rst = devm_reset_control_get(dev, "pclk"); | 1082 | rockchip->pclk_rst = devm_reset_control_get_exclusive(dev, "pclk"); |
942 | if (IS_ERR(rockchip->pclk_rst)) { | 1083 | if (IS_ERR(rockchip->pclk_rst)) { |
943 | if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER) | 1084 | if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER) |
944 | dev_err(dev, "missing pclk reset property in node\n"); | 1085 | dev_err(dev, "missing pclk reset property in node\n"); |
945 | return PTR_ERR(rockchip->pclk_rst); | 1086 | return PTR_ERR(rockchip->pclk_rst); |
946 | } | 1087 | } |
947 | 1088 | ||
948 | rockchip->aclk_rst = devm_reset_control_get(dev, "aclk"); | 1089 | rockchip->aclk_rst = devm_reset_control_get_exclusive(dev, "aclk"); |
949 | if (IS_ERR(rockchip->aclk_rst)) { | 1090 | if (IS_ERR(rockchip->aclk_rst)) { |
950 | if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER) | 1091 | if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER) |
951 | dev_err(dev, "missing aclk reset property in node\n"); | 1092 | dev_err(dev, "missing aclk reset property in node\n"); |
@@ -982,40 +1123,15 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) | |||
982 | return PTR_ERR(rockchip->clk_pcie_pm); | 1123 | return PTR_ERR(rockchip->clk_pcie_pm); |
983 | } | 1124 | } |
984 | 1125 | ||
985 | irq = platform_get_irq_byname(pdev, "sys"); | 1126 | err = rockchip_pcie_setup_irq(rockchip); |
986 | if (irq < 0) { | 1127 | if (err) |
987 | dev_err(dev, "missing sys IRQ resource\n"); | ||
988 | return -EINVAL; | ||
989 | } | ||
990 | |||
991 | err = devm_request_irq(dev, irq, rockchip_pcie_subsys_irq_handler, | ||
992 | IRQF_SHARED, "pcie-sys", rockchip); | ||
993 | if (err) { | ||
994 | dev_err(dev, "failed to request PCIe subsystem IRQ\n"); | ||
995 | return err; | 1128 | return err; |
996 | } | ||
997 | |||
998 | irq = platform_get_irq_byname(pdev, "legacy"); | ||
999 | if (irq < 0) { | ||
1000 | dev_err(dev, "missing legacy IRQ resource\n"); | ||
1001 | return -EINVAL; | ||
1002 | } | ||
1003 | |||
1004 | irq_set_chained_handler_and_data(irq, | ||
1005 | rockchip_pcie_legacy_int_handler, | ||
1006 | rockchip); | ||
1007 | |||
1008 | irq = platform_get_irq_byname(pdev, "client"); | ||
1009 | if (irq < 0) { | ||
1010 | dev_err(dev, "missing client IRQ resource\n"); | ||
1011 | return -EINVAL; | ||
1012 | } | ||
1013 | 1129 | ||
1014 | err = devm_request_irq(dev, irq, rockchip_pcie_client_irq_handler, | 1130 | rockchip->vpcie12v = devm_regulator_get_optional(dev, "vpcie12v"); |
1015 | IRQF_SHARED, "pcie-client", rockchip); | 1131 | if (IS_ERR(rockchip->vpcie12v)) { |
1016 | if (err) { | 1132 | if (PTR_ERR(rockchip->vpcie12v) == -EPROBE_DEFER) |
1017 | dev_err(dev, "failed to request PCIe client IRQ\n"); | 1133 | return -EPROBE_DEFER; |
1018 | return err; | 1134 | dev_info(dev, "no vpcie12v regulator found\n"); |
1019 | } | 1135 | } |
1020 | 1136 | ||
1021 | rockchip->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3"); | 1137 | rockchip->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3"); |
@@ -1047,11 +1163,19 @@ static int rockchip_pcie_set_vpcie(struct rockchip_pcie *rockchip) | |||
1047 | struct device *dev = rockchip->dev; | 1163 | struct device *dev = rockchip->dev; |
1048 | int err; | 1164 | int err; |
1049 | 1165 | ||
1166 | if (!IS_ERR(rockchip->vpcie12v)) { | ||
1167 | err = regulator_enable(rockchip->vpcie12v); | ||
1168 | if (err) { | ||
1169 | dev_err(dev, "fail to enable vpcie12v regulator\n"); | ||
1170 | goto err_out; | ||
1171 | } | ||
1172 | } | ||
1173 | |||
1050 | if (!IS_ERR(rockchip->vpcie3v3)) { | 1174 | if (!IS_ERR(rockchip->vpcie3v3)) { |
1051 | err = regulator_enable(rockchip->vpcie3v3); | 1175 | err = regulator_enable(rockchip->vpcie3v3); |
1052 | if (err) { | 1176 | if (err) { |
1053 | dev_err(dev, "fail to enable vpcie3v3 regulator\n"); | 1177 | dev_err(dev, "fail to enable vpcie3v3 regulator\n"); |
1054 | goto err_out; | 1178 | goto err_disable_12v; |
1055 | } | 1179 | } |
1056 | } | 1180 | } |
1057 | 1181 | ||
@@ -1079,6 +1203,9 @@ err_disable_1v8: | |||
1079 | err_disable_3v3: | 1203 | err_disable_3v3: |
1080 | if (!IS_ERR(rockchip->vpcie3v3)) | 1204 | if (!IS_ERR(rockchip->vpcie3v3)) |
1081 | regulator_disable(rockchip->vpcie3v3); | 1205 | regulator_disable(rockchip->vpcie3v3); |
1206 | err_disable_12v: | ||
1207 | if (!IS_ERR(rockchip->vpcie12v)) | ||
1208 | regulator_disable(rockchip->vpcie12v); | ||
1082 | err_out: | 1209 | err_out: |
1083 | return err; | 1210 | return err; |
1084 | } | 1211 | } |
@@ -1116,7 +1243,7 @@ static int rockchip_pcie_init_irq_domain(struct rockchip_pcie *rockchip) | |||
1116 | return -EINVAL; | 1243 | return -EINVAL; |
1117 | } | 1244 | } |
1118 | 1245 | ||
1119 | rockchip->irq_domain = irq_domain_add_linear(intc, 4, | 1246 | rockchip->irq_domain = irq_domain_add_linear(intc, PCI_NUM_INTX, |
1120 | &intx_domain_ops, rockchip); | 1247 | &intx_domain_ops, rockchip); |
1121 | if (!rockchip->irq_domain) { | 1248 | if (!rockchip->irq_domain) { |
1122 | dev_err(dev, "failed to get a INTx IRQ domain\n"); | 1249 | dev_err(dev, "failed to get a INTx IRQ domain\n"); |
@@ -1270,6 +1397,56 @@ static int rockchip_pcie_wait_l2(struct rockchip_pcie *rockchip) | |||
1270 | return 0; | 1397 | return 0; |
1271 | } | 1398 | } |
1272 | 1399 | ||
1400 | static int rockchip_pcie_enable_clocks(struct rockchip_pcie *rockchip) | ||
1401 | { | ||
1402 | struct device *dev = rockchip->dev; | ||
1403 | int err; | ||
1404 | |||
1405 | err = clk_prepare_enable(rockchip->aclk_pcie); | ||
1406 | if (err) { | ||
1407 | dev_err(dev, "unable to enable aclk_pcie clock\n"); | ||
1408 | return err; | ||
1409 | } | ||
1410 | |||
1411 | err = clk_prepare_enable(rockchip->aclk_perf_pcie); | ||
1412 | if (err) { | ||
1413 | dev_err(dev, "unable to enable aclk_perf_pcie clock\n"); | ||
1414 | goto err_aclk_perf_pcie; | ||
1415 | } | ||
1416 | |||
1417 | err = clk_prepare_enable(rockchip->hclk_pcie); | ||
1418 | if (err) { | ||
1419 | dev_err(dev, "unable to enable hclk_pcie clock\n"); | ||
1420 | goto err_hclk_pcie; | ||
1421 | } | ||
1422 | |||
1423 | err = clk_prepare_enable(rockchip->clk_pcie_pm); | ||
1424 | if (err) { | ||
1425 | dev_err(dev, "unable to enable clk_pcie_pm clock\n"); | ||
1426 | goto err_clk_pcie_pm; | ||
1427 | } | ||
1428 | |||
1429 | return 0; | ||
1430 | |||
1431 | err_clk_pcie_pm: | ||
1432 | clk_disable_unprepare(rockchip->hclk_pcie); | ||
1433 | err_hclk_pcie: | ||
1434 | clk_disable_unprepare(rockchip->aclk_perf_pcie); | ||
1435 | err_aclk_perf_pcie: | ||
1436 | clk_disable_unprepare(rockchip->aclk_pcie); | ||
1437 | return err; | ||
1438 | } | ||
1439 | |||
1440 | static void rockchip_pcie_disable_clocks(void *data) | ||
1441 | { | ||
1442 | struct rockchip_pcie *rockchip = data; | ||
1443 | |||
1444 | clk_disable_unprepare(rockchip->clk_pcie_pm); | ||
1445 | clk_disable_unprepare(rockchip->hclk_pcie); | ||
1446 | clk_disable_unprepare(rockchip->aclk_perf_pcie); | ||
1447 | clk_disable_unprepare(rockchip->aclk_pcie); | ||
1448 | } | ||
1449 | |||
1273 | static int __maybe_unused rockchip_pcie_suspend_noirq(struct device *dev) | 1450 | static int __maybe_unused rockchip_pcie_suspend_noirq(struct device *dev) |
1274 | { | 1451 | { |
1275 | struct rockchip_pcie *rockchip = dev_get_drvdata(dev); | 1452 | struct rockchip_pcie *rockchip = dev_get_drvdata(dev); |
@@ -1286,13 +1463,9 @@ static int __maybe_unused rockchip_pcie_suspend_noirq(struct device *dev) | |||
1286 | return ret; | 1463 | return ret; |
1287 | } | 1464 | } |
1288 | 1465 | ||
1289 | phy_power_off(rockchip->phy); | 1466 | rockchip_pcie_deinit_phys(rockchip); |
1290 | phy_exit(rockchip->phy); | ||
1291 | 1467 | ||
1292 | clk_disable_unprepare(rockchip->clk_pcie_pm); | 1468 | rockchip_pcie_disable_clocks(rockchip); |
1293 | clk_disable_unprepare(rockchip->hclk_pcie); | ||
1294 | clk_disable_unprepare(rockchip->aclk_perf_pcie); | ||
1295 | clk_disable_unprepare(rockchip->aclk_pcie); | ||
1296 | 1469 | ||
1297 | if (!IS_ERR(rockchip->vpcie0v9)) | 1470 | if (!IS_ERR(rockchip->vpcie0v9)) |
1298 | regulator_disable(rockchip->vpcie0v9); | 1471 | regulator_disable(rockchip->vpcie0v9); |
@@ -1313,21 +1486,9 @@ static int __maybe_unused rockchip_pcie_resume_noirq(struct device *dev) | |||
1313 | } | 1486 | } |
1314 | } | 1487 | } |
1315 | 1488 | ||
1316 | err = clk_prepare_enable(rockchip->clk_pcie_pm); | 1489 | err = rockchip_pcie_enable_clocks(rockchip); |
1317 | if (err) | 1490 | if (err) |
1318 | goto err_pcie_pm; | 1491 | goto err_disable_0v9; |
1319 | |||
1320 | err = clk_prepare_enable(rockchip->hclk_pcie); | ||
1321 | if (err) | ||
1322 | goto err_hclk_pcie; | ||
1323 | |||
1324 | err = clk_prepare_enable(rockchip->aclk_perf_pcie); | ||
1325 | if (err) | ||
1326 | goto err_aclk_perf_pcie; | ||
1327 | |||
1328 | err = clk_prepare_enable(rockchip->aclk_pcie); | ||
1329 | if (err) | ||
1330 | goto err_aclk_pcie; | ||
1331 | 1492 | ||
1332 | err = rockchip_pcie_init_port(rockchip); | 1493 | err = rockchip_pcie_init_port(rockchip); |
1333 | if (err) | 1494 | if (err) |
@@ -1335,7 +1496,7 @@ static int __maybe_unused rockchip_pcie_resume_noirq(struct device *dev) | |||
1335 | 1496 | ||
1336 | err = rockchip_pcie_cfg_atu(rockchip); | 1497 | err = rockchip_pcie_cfg_atu(rockchip); |
1337 | if (err) | 1498 | if (err) |
1338 | goto err_pcie_resume; | 1499 | goto err_err_deinit_port; |
1339 | 1500 | ||
1340 | /* Need this to enter L1 again */ | 1501 | /* Need this to enter L1 again */ |
1341 | rockchip_pcie_update_txcredit_mui(rockchip); | 1502 | rockchip_pcie_update_txcredit_mui(rockchip); |
@@ -1343,15 +1504,13 @@ static int __maybe_unused rockchip_pcie_resume_noirq(struct device *dev) | |||
1343 | 1504 | ||
1344 | return 0; | 1505 | return 0; |
1345 | 1506 | ||
1507 | err_err_deinit_port: | ||
1508 | rockchip_pcie_deinit_phys(rockchip); | ||
1346 | err_pcie_resume: | 1509 | err_pcie_resume: |
1347 | clk_disable_unprepare(rockchip->aclk_pcie); | 1510 | rockchip_pcie_disable_clocks(rockchip); |
1348 | err_aclk_pcie: | 1511 | err_disable_0v9: |
1349 | clk_disable_unprepare(rockchip->aclk_perf_pcie); | 1512 | if (!IS_ERR(rockchip->vpcie0v9)) |
1350 | err_aclk_perf_pcie: | 1513 | regulator_disable(rockchip->vpcie0v9); |
1351 | clk_disable_unprepare(rockchip->hclk_pcie); | ||
1352 | err_hclk_pcie: | ||
1353 | clk_disable_unprepare(rockchip->clk_pcie_pm); | ||
1354 | err_pcie_pm: | ||
1355 | return err; | 1514 | return err; |
1356 | } | 1515 | } |
1357 | 1516 | ||
@@ -1385,29 +1544,9 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1385 | if (err) | 1544 | if (err) |
1386 | return err; | 1545 | return err; |
1387 | 1546 | ||
1388 | err = clk_prepare_enable(rockchip->aclk_pcie); | 1547 | err = rockchip_pcie_enable_clocks(rockchip); |
1389 | if (err) { | 1548 | if (err) |
1390 | dev_err(dev, "unable to enable aclk_pcie clock\n"); | 1549 | return err; |
1391 | goto err_aclk_pcie; | ||
1392 | } | ||
1393 | |||
1394 | err = clk_prepare_enable(rockchip->aclk_perf_pcie); | ||
1395 | if (err) { | ||
1396 | dev_err(dev, "unable to enable aclk_perf_pcie clock\n"); | ||
1397 | goto err_aclk_perf_pcie; | ||
1398 | } | ||
1399 | |||
1400 | err = clk_prepare_enable(rockchip->hclk_pcie); | ||
1401 | if (err) { | ||
1402 | dev_err(dev, "unable to enable hclk_pcie clock\n"); | ||
1403 | goto err_hclk_pcie; | ||
1404 | } | ||
1405 | |||
1406 | err = clk_prepare_enable(rockchip->clk_pcie_pm); | ||
1407 | if (err) { | ||
1408 | dev_err(dev, "unable to enable hclk_pcie clock\n"); | ||
1409 | goto err_pcie_pm; | ||
1410 | } | ||
1411 | 1550 | ||
1412 | err = rockchip_pcie_set_vpcie(rockchip); | 1551 | err = rockchip_pcie_set_vpcie(rockchip); |
1413 | if (err) { | 1552 | if (err) { |
@@ -1423,12 +1562,12 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1423 | 1562 | ||
1424 | err = rockchip_pcie_init_irq_domain(rockchip); | 1563 | err = rockchip_pcie_init_irq_domain(rockchip); |
1425 | if (err < 0) | 1564 | if (err < 0) |
1426 | goto err_vpcie; | 1565 | goto err_deinit_port; |
1427 | 1566 | ||
1428 | err = of_pci_get_host_bridge_resources(dev->of_node, 0, 0xff, | 1567 | err = of_pci_get_host_bridge_resources(dev->of_node, 0, 0xff, |
1429 | &res, &io_base); | 1568 | &res, &io_base); |
1430 | if (err) | 1569 | if (err) |
1431 | goto err_vpcie; | 1570 | goto err_remove_irq_domain; |
1432 | 1571 | ||
1433 | err = devm_request_pci_bus_resources(dev, &res); | 1572 | err = devm_request_pci_bus_resources(dev, &res); |
1434 | if (err) | 1573 | if (err) |
@@ -1466,12 +1605,12 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1466 | 1605 | ||
1467 | err = rockchip_pcie_cfg_atu(rockchip); | 1606 | err = rockchip_pcie_cfg_atu(rockchip); |
1468 | if (err) | 1607 | if (err) |
1469 | goto err_free_res; | 1608 | goto err_unmap_iospace; |
1470 | 1609 | ||
1471 | rockchip->msg_region = devm_ioremap(dev, rockchip->msg_bus_addr, SZ_1M); | 1610 | rockchip->msg_region = devm_ioremap(dev, rockchip->msg_bus_addr, SZ_1M); |
1472 | if (!rockchip->msg_region) { | 1611 | if (!rockchip->msg_region) { |
1473 | err = -ENOMEM; | 1612 | err = -ENOMEM; |
1474 | goto err_free_res; | 1613 | goto err_unmap_iospace; |
1475 | } | 1614 | } |
1476 | 1615 | ||
1477 | list_splice_init(&res, &bridge->windows); | 1616 | list_splice_init(&res, &bridge->windows); |
@@ -1484,7 +1623,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1484 | 1623 | ||
1485 | err = pci_scan_root_bus_bridge(bridge); | 1624 | err = pci_scan_root_bus_bridge(bridge); |
1486 | if (err < 0) | 1625 | if (err < 0) |
1487 | goto err_free_res; | 1626 | goto err_unmap_iospace; |
1488 | 1627 | ||
1489 | bus = bridge->bus; | 1628 | bus = bridge->bus; |
1490 | 1629 | ||
@@ -1498,9 +1637,17 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1498 | pci_bus_add_devices(bus); | 1637 | pci_bus_add_devices(bus); |
1499 | return 0; | 1638 | return 0; |
1500 | 1639 | ||
1640 | err_unmap_iospace: | ||
1641 | pci_unmap_iospace(rockchip->io); | ||
1501 | err_free_res: | 1642 | err_free_res: |
1502 | pci_free_resource_list(&res); | 1643 | pci_free_resource_list(&res); |
1644 | err_remove_irq_domain: | ||
1645 | irq_domain_remove(rockchip->irq_domain); | ||
1646 | err_deinit_port: | ||
1647 | rockchip_pcie_deinit_phys(rockchip); | ||
1503 | err_vpcie: | 1648 | err_vpcie: |
1649 | if (!IS_ERR(rockchip->vpcie12v)) | ||
1650 | regulator_disable(rockchip->vpcie12v); | ||
1504 | if (!IS_ERR(rockchip->vpcie3v3)) | 1651 | if (!IS_ERR(rockchip->vpcie3v3)) |
1505 | regulator_disable(rockchip->vpcie3v3); | 1652 | regulator_disable(rockchip->vpcie3v3); |
1506 | if (!IS_ERR(rockchip->vpcie1v8)) | 1653 | if (!IS_ERR(rockchip->vpcie1v8)) |
@@ -1508,14 +1655,7 @@ err_vpcie: | |||
1508 | if (!IS_ERR(rockchip->vpcie0v9)) | 1655 | if (!IS_ERR(rockchip->vpcie0v9)) |
1509 | regulator_disable(rockchip->vpcie0v9); | 1656 | regulator_disable(rockchip->vpcie0v9); |
1510 | err_set_vpcie: | 1657 | err_set_vpcie: |
1511 | clk_disable_unprepare(rockchip->clk_pcie_pm); | 1658 | rockchip_pcie_disable_clocks(rockchip); |
1512 | err_pcie_pm: | ||
1513 | clk_disable_unprepare(rockchip->hclk_pcie); | ||
1514 | err_hclk_pcie: | ||
1515 | clk_disable_unprepare(rockchip->aclk_perf_pcie); | ||
1516 | err_aclk_perf_pcie: | ||
1517 | clk_disable_unprepare(rockchip->aclk_pcie); | ||
1518 | err_aclk_pcie: | ||
1519 | return err; | 1659 | return err; |
1520 | } | 1660 | } |
1521 | 1661 | ||
@@ -1529,14 +1669,12 @@ static int rockchip_pcie_remove(struct platform_device *pdev) | |||
1529 | pci_unmap_iospace(rockchip->io); | 1669 | pci_unmap_iospace(rockchip->io); |
1530 | irq_domain_remove(rockchip->irq_domain); | 1670 | irq_domain_remove(rockchip->irq_domain); |
1531 | 1671 | ||
1532 | phy_power_off(rockchip->phy); | 1672 | rockchip_pcie_deinit_phys(rockchip); |
1533 | phy_exit(rockchip->phy); | ||
1534 | 1673 | ||
1535 | clk_disable_unprepare(rockchip->clk_pcie_pm); | 1674 | rockchip_pcie_disable_clocks(rockchip); |
1536 | clk_disable_unprepare(rockchip->hclk_pcie); | ||
1537 | clk_disable_unprepare(rockchip->aclk_perf_pcie); | ||
1538 | clk_disable_unprepare(rockchip->aclk_pcie); | ||
1539 | 1675 | ||
1676 | if (!IS_ERR(rockchip->vpcie12v)) | ||
1677 | regulator_disable(rockchip->vpcie12v); | ||
1540 | if (!IS_ERR(rockchip->vpcie3v3)) | 1678 | if (!IS_ERR(rockchip->vpcie3v3)) |
1541 | regulator_disable(rockchip->vpcie3v3); | 1679 | regulator_disable(rockchip->vpcie3v3); |
1542 | if (!IS_ERR(rockchip->vpcie1v8)) | 1680 | if (!IS_ERR(rockchip->vpcie1v8)) |
diff --git a/drivers/pci/host/pcie-xilinx-nwl.c b/drivers/pci/host/pcie-xilinx-nwl.c index eec641a34fc5..65dea98b2643 100644 --- a/drivers/pci/host/pcie-xilinx-nwl.c +++ b/drivers/pci/host/pcie-xilinx-nwl.c | |||
@@ -133,7 +133,6 @@ | |||
133 | #define CFG_DMA_REG_BAR GENMASK(2, 0) | 133 | #define CFG_DMA_REG_BAR GENMASK(2, 0) |
134 | 134 | ||
135 | #define INT_PCI_MSI_NR (2 * 32) | 135 | #define INT_PCI_MSI_NR (2 * 32) |
136 | #define INTX_NUM 4 | ||
137 | 136 | ||
138 | /* Readin the PS_LINKUP */ | 137 | /* Readin the PS_LINKUP */ |
139 | #define PS_LINKUP_OFFSET 0x00000238 | 138 | #define PS_LINKUP_OFFSET 0x00000238 |
@@ -334,9 +333,8 @@ static void nwl_pcie_leg_handler(struct irq_desc *desc) | |||
334 | 333 | ||
335 | while ((status = nwl_bridge_readl(pcie, MSGF_LEG_STATUS) & | 334 | while ((status = nwl_bridge_readl(pcie, MSGF_LEG_STATUS) & |
336 | MSGF_LEG_SR_MASKALL) != 0) { | 335 | MSGF_LEG_SR_MASKALL) != 0) { |
337 | for_each_set_bit(bit, &status, INTX_NUM) { | 336 | for_each_set_bit(bit, &status, PCI_NUM_INTX) { |
338 | virq = irq_find_mapping(pcie->legacy_irq_domain, | 337 | virq = irq_find_mapping(pcie->legacy_irq_domain, bit); |
339 | bit + 1); | ||
340 | if (virq) | 338 | if (virq) |
341 | generic_handle_irq(virq); | 339 | generic_handle_irq(virq); |
342 | } | 340 | } |
@@ -436,6 +434,7 @@ static int nwl_legacy_map(struct irq_domain *domain, unsigned int irq, | |||
436 | 434 | ||
437 | static const struct irq_domain_ops legacy_domain_ops = { | 435 | static const struct irq_domain_ops legacy_domain_ops = { |
438 | .map = nwl_legacy_map, | 436 | .map = nwl_legacy_map, |
437 | .xlate = pci_irqd_intx_xlate, | ||
439 | }; | 438 | }; |
440 | 439 | ||
441 | #ifdef CONFIG_PCI_MSI | 440 | #ifdef CONFIG_PCI_MSI |
@@ -559,7 +558,7 @@ static int nwl_pcie_init_irq_domain(struct nwl_pcie *pcie) | |||
559 | } | 558 | } |
560 | 559 | ||
561 | pcie->legacy_irq_domain = irq_domain_add_linear(legacy_intc_node, | 560 | pcie->legacy_irq_domain = irq_domain_add_linear(legacy_intc_node, |
562 | INTX_NUM, | 561 | PCI_NUM_INTX, |
563 | &legacy_domain_ops, | 562 | &legacy_domain_ops, |
564 | pcie); | 563 | pcie); |
565 | 564 | ||
@@ -813,7 +812,7 @@ static int nwl_pcie_parse_dt(struct nwl_pcie *pcie, | |||
813 | pcie->irq_intx = platform_get_irq_byname(pdev, "intx"); | 812 | pcie->irq_intx = platform_get_irq_byname(pdev, "intx"); |
814 | if (pcie->irq_intx < 0) { | 813 | if (pcie->irq_intx < 0) { |
815 | dev_err(dev, "failed to get intx IRQ %d\n", pcie->irq_intx); | 814 | dev_err(dev, "failed to get intx IRQ %d\n", pcie->irq_intx); |
816 | return -EINVAL; | 815 | return pcie->irq_intx; |
817 | } | 816 | } |
818 | 817 | ||
819 | irq_set_chained_handler_and_data(pcie->irq_intx, | 818 | irq_set_chained_handler_and_data(pcie->irq_intx, |
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c index f63fa5e0278c..94e13cb8608f 100644 --- a/drivers/pci/host/pcie-xilinx.c +++ b/drivers/pci/host/pcie-xilinx.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Based on the Tegra PCIe driver | 6 | * Based on the Tegra PCIe driver |
7 | * | 7 | * |
8 | * Bits taken from Synopsys Designware Host controller driver and | 8 | * Bits taken from Synopsys DesignWare Host controller driver and |
9 | * ARM PCI Host generic driver. | 9 | * ARM PCI Host generic driver. |
10 | * | 10 | * |
11 | * This program is free software: you can redistribute it and/or modify | 11 | * This program is free software: you can redistribute it and/or modify |
@@ -60,6 +60,7 @@ | |||
60 | #define XILINX_PCIE_INTR_MST_SLVERR BIT(27) | 60 | #define XILINX_PCIE_INTR_MST_SLVERR BIT(27) |
61 | #define XILINX_PCIE_INTR_MST_ERRP BIT(28) | 61 | #define XILINX_PCIE_INTR_MST_ERRP BIT(28) |
62 | #define XILINX_PCIE_IMR_ALL_MASK 0x1FF30FED | 62 | #define XILINX_PCIE_IMR_ALL_MASK 0x1FF30FED |
63 | #define XILINX_PCIE_IMR_ENABLE_MASK 0x1FF30F0D | ||
63 | #define XILINX_PCIE_IDR_ALL_MASK 0xFFFFFFFF | 64 | #define XILINX_PCIE_IDR_ALL_MASK 0xFFFFFFFF |
64 | 65 | ||
65 | /* Root Port Error FIFO Read Register definitions */ | 66 | /* Root Port Error FIFO Read Register definitions */ |
@@ -369,6 +370,7 @@ static int xilinx_pcie_intx_map(struct irq_domain *domain, unsigned int irq, | |||
369 | /* INTx IRQ Domain operations */ | 370 | /* INTx IRQ Domain operations */ |
370 | static const struct irq_domain_ops intx_domain_ops = { | 371 | static const struct irq_domain_ops intx_domain_ops = { |
371 | .map = xilinx_pcie_intx_map, | 372 | .map = xilinx_pcie_intx_map, |
373 | .xlate = pci_irqd_intx_xlate, | ||
372 | }; | 374 | }; |
373 | 375 | ||
374 | /* PCIe HW Functions */ | 376 | /* PCIe HW Functions */ |
@@ -384,7 +386,7 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data) | |||
384 | { | 386 | { |
385 | struct xilinx_pcie_port *port = (struct xilinx_pcie_port *)data; | 387 | struct xilinx_pcie_port *port = (struct xilinx_pcie_port *)data; |
386 | struct device *dev = port->dev; | 388 | struct device *dev = port->dev; |
387 | u32 val, mask, status, msi_data; | 389 | u32 val, mask, status; |
388 | 390 | ||
389 | /* Read interrupt decode and mask registers */ | 391 | /* Read interrupt decode and mask registers */ |
390 | val = pcie_read(port, XILINX_PCIE_REG_IDR); | 392 | val = pcie_read(port, XILINX_PCIE_REG_IDR); |
@@ -424,8 +426,7 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data) | |||
424 | xilinx_pcie_clear_err_interrupts(port); | 426 | xilinx_pcie_clear_err_interrupts(port); |
425 | } | 427 | } |
426 | 428 | ||
427 | if (status & XILINX_PCIE_INTR_INTX) { | 429 | if (status & (XILINX_PCIE_INTR_INTX | XILINX_PCIE_INTR_MSI)) { |
428 | /* INTx interrupt received */ | ||
429 | val = pcie_read(port, XILINX_PCIE_REG_RPIFR1); | 430 | val = pcie_read(port, XILINX_PCIE_REG_RPIFR1); |
430 | 431 | ||
431 | /* Check whether interrupt valid */ | 432 | /* Check whether interrupt valid */ |
@@ -434,41 +435,24 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data) | |||
434 | goto error; | 435 | goto error; |
435 | } | 436 | } |
436 | 437 | ||
437 | if (!(val & XILINX_PCIE_RPIFR1_MSI_INTR)) { | 438 | /* Decode the IRQ number */ |
438 | /* Clear interrupt FIFO register 1 */ | ||
439 | pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK, | ||
440 | XILINX_PCIE_REG_RPIFR1); | ||
441 | |||
442 | /* Handle INTx Interrupt */ | ||
443 | val = ((val & XILINX_PCIE_RPIFR1_INTR_MASK) >> | ||
444 | XILINX_PCIE_RPIFR1_INTR_SHIFT) + 1; | ||
445 | generic_handle_irq(irq_find_mapping(port->leg_domain, | ||
446 | val)); | ||
447 | } | ||
448 | } | ||
449 | |||
450 | if (status & XILINX_PCIE_INTR_MSI) { | ||
451 | /* MSI Interrupt */ | ||
452 | val = pcie_read(port, XILINX_PCIE_REG_RPIFR1); | ||
453 | |||
454 | if (!(val & XILINX_PCIE_RPIFR1_INTR_VALID)) { | ||
455 | dev_warn(dev, "RP Intr FIFO1 read error\n"); | ||
456 | goto error; | ||
457 | } | ||
458 | |||
459 | if (val & XILINX_PCIE_RPIFR1_MSI_INTR) { | 439 | if (val & XILINX_PCIE_RPIFR1_MSI_INTR) { |
460 | msi_data = pcie_read(port, XILINX_PCIE_REG_RPIFR2) & | 440 | val = pcie_read(port, XILINX_PCIE_REG_RPIFR2) & |
461 | XILINX_PCIE_RPIFR2_MSG_DATA; | 441 | XILINX_PCIE_RPIFR2_MSG_DATA; |
442 | } else { | ||
443 | val = (val & XILINX_PCIE_RPIFR1_INTR_MASK) >> | ||
444 | XILINX_PCIE_RPIFR1_INTR_SHIFT; | ||
445 | val = irq_find_mapping(port->leg_domain, val); | ||
446 | } | ||
462 | 447 | ||
463 | /* Clear interrupt FIFO register 1 */ | 448 | /* Clear interrupt FIFO register 1 */ |
464 | pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK, | 449 | pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK, |
465 | XILINX_PCIE_REG_RPIFR1); | 450 | XILINX_PCIE_REG_RPIFR1); |
466 | 451 | ||
467 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | 452 | /* Handle the interrupt */ |
468 | /* Handle MSI Interrupt */ | 453 | if (IS_ENABLED(CONFIG_PCI_MSI) || |
469 | generic_handle_irq(msi_data); | 454 | !(val & XILINX_PCIE_RPIFR1_MSI_INTR)) |
470 | } | 455 | generic_handle_irq(val); |
471 | } | ||
472 | } | 456 | } |
473 | 457 | ||
474 | if (status & XILINX_PCIE_INTR_SLV_UNSUPP) | 458 | if (status & XILINX_PCIE_INTR_SLV_UNSUPP) |
@@ -524,7 +508,7 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port) | |||
524 | return -ENODEV; | 508 | return -ENODEV; |
525 | } | 509 | } |
526 | 510 | ||
527 | port->leg_domain = irq_domain_add_linear(pcie_intc_node, 4, | 511 | port->leg_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, |
528 | &intx_domain_ops, | 512 | &intx_domain_ops, |
529 | port); | 513 | port); |
530 | if (!port->leg_domain) { | 514 | if (!port->leg_domain) { |
@@ -571,8 +555,8 @@ static void xilinx_pcie_init_port(struct xilinx_pcie_port *port) | |||
571 | XILINX_PCIE_IMR_ALL_MASK, | 555 | XILINX_PCIE_IMR_ALL_MASK, |
572 | XILINX_PCIE_REG_IDR); | 556 | XILINX_PCIE_REG_IDR); |
573 | 557 | ||
574 | /* Enable all interrupts */ | 558 | /* Enable all interrupts we handle */ |
575 | pcie_write(port, XILINX_PCIE_IMR_ALL_MASK, XILINX_PCIE_REG_IMR); | 559 | pcie_write(port, XILINX_PCIE_IMR_ENABLE_MASK, XILINX_PCIE_REG_IMR); |
576 | 560 | ||
577 | /* Enable the Bridge enable bit */ | 561 | /* Enable the Bridge enable bit */ |
578 | pcie_write(port, pcie_read(port, XILINX_PCIE_REG_RPSC) | | 562 | pcie_write(port, pcie_read(port, XILINX_PCIE_REG_RPSC) | |
diff --git a/drivers/pci/host/vmd.c b/drivers/pci/host/vmd.c index 6088c3083194..509893bc3e63 100644 --- a/drivers/pci/host/vmd.c +++ b/drivers/pci/host/vmd.c | |||
@@ -183,7 +183,7 @@ static struct vmd_irq_list *vmd_next_irq(struct vmd_dev *vmd, struct msi_desc *d | |||
183 | int i, best = 1; | 183 | int i, best = 1; |
184 | unsigned long flags; | 184 | unsigned long flags; |
185 | 185 | ||
186 | if (!desc->msi_attrib.is_msix || vmd->msix_count == 1) | 186 | if (pci_is_bridge(msi_desc_to_pci_dev(desc)) || vmd->msix_count == 1) |
187 | return &vmd->irqs[0]; | 187 | return &vmd->irqs[0]; |
188 | 188 | ||
189 | raw_spin_lock_irqsave(&list_lock, flags); | 189 | raw_spin_lock_irqsave(&list_lock, flags); |
@@ -697,7 +697,7 @@ static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
697 | return -ENODEV; | 697 | return -ENODEV; |
698 | 698 | ||
699 | vmd->msix_count = pci_alloc_irq_vectors(dev, 1, vmd->msix_count, | 699 | vmd->msix_count = pci_alloc_irq_vectors(dev, 1, vmd->msix_count, |
700 | PCI_IRQ_MSIX | PCI_IRQ_AFFINITY); | 700 | PCI_IRQ_MSIX); |
701 | if (vmd->msix_count < 0) | 701 | if (vmd->msix_count < 0) |
702 | return vmd->msix_count; | 702 | return vmd->msix_count; |
703 | 703 | ||
@@ -755,6 +755,11 @@ static void vmd_remove(struct pci_dev *dev) | |||
755 | static int vmd_suspend(struct device *dev) | 755 | static int vmd_suspend(struct device *dev) |
756 | { | 756 | { |
757 | struct pci_dev *pdev = to_pci_dev(dev); | 757 | struct pci_dev *pdev = to_pci_dev(dev); |
758 | struct vmd_dev *vmd = pci_get_drvdata(pdev); | ||
759 | int i; | ||
760 | |||
761 | for (i = 0; i < vmd->msix_count; i++) | ||
762 | devm_free_irq(dev, pci_irq_vector(pdev, i), &vmd->irqs[i]); | ||
758 | 763 | ||
759 | pci_save_state(pdev); | 764 | pci_save_state(pdev); |
760 | return 0; | 765 | return 0; |
@@ -763,6 +768,16 @@ static int vmd_suspend(struct device *dev) | |||
763 | static int vmd_resume(struct device *dev) | 768 | static int vmd_resume(struct device *dev) |
764 | { | 769 | { |
765 | struct pci_dev *pdev = to_pci_dev(dev); | 770 | struct pci_dev *pdev = to_pci_dev(dev); |
771 | struct vmd_dev *vmd = pci_get_drvdata(pdev); | ||
772 | int err, i; | ||
773 | |||
774 | for (i = 0; i < vmd->msix_count; i++) { | ||
775 | err = devm_request_irq(dev, pci_irq_vector(pdev, i), | ||
776 | vmd_irq, IRQF_NO_THREAD, | ||
777 | "vmd", &vmd->irqs[i]); | ||
778 | if (err) | ||
779 | return err; | ||
780 | } | ||
766 | 781 | ||
767 | pci_restore_state(pdev); | 782 | pci_restore_state(pdev); |
768 | return 0; | 783 | return 0; |
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c index 5f49c3fd736a..2f8659a148f5 100644 --- a/drivers/pci/hotplug/cpcihp_zt5550.c +++ b/drivers/pci/hotplug/cpcihp_zt5550.c | |||
@@ -280,7 +280,7 @@ static void zt5550_hc_remove_one(struct pci_dev *pdev) | |||
280 | } | 280 | } |
281 | 281 | ||
282 | 282 | ||
283 | static struct pci_device_id zt5550_hc_pci_tbl[] = { | 283 | static const struct pci_device_id zt5550_hc_pci_tbl[] = { |
284 | { PCI_VENDOR_ID_ZIATECH, PCI_DEVICE_ID_ZIATECH_5550_HC, PCI_ANY_ID, PCI_ANY_ID, }, | 284 | { PCI_VENDOR_ID_ZIATECH, PCI_DEVICE_ID_ZIATECH_5550_HC, PCI_ANY_ID, PCI_ANY_ID, }, |
285 | { 0, } | 285 | { 0, } |
286 | }; | 286 | }; |
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 33d300d12411..4d06b8461255 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c | |||
@@ -1417,7 +1417,7 @@ static void __exit unload_cpqphpd(void) | |||
1417 | iounmap(smbios_start); | 1417 | iounmap(smbios_start); |
1418 | } | 1418 | } |
1419 | 1419 | ||
1420 | static struct pci_device_id hpcd_pci_tbl[] = { | 1420 | static const struct pci_device_id hpcd_pci_tbl[] = { |
1421 | { | 1421 | { |
1422 | /* handle any PCI Hotplug controller */ | 1422 | /* handle any PCI Hotplug controller */ |
1423 | .class = ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00), | 1423 | .class = ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00), |
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 5efd01d84498..73cf84645c82 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c | |||
@@ -852,7 +852,7 @@ static int set_bus(struct slot *slot_cur) | |||
852 | u8 speed; | 852 | u8 speed; |
853 | u8 cmd = 0x0; | 853 | u8 cmd = 0x0; |
854 | int retval; | 854 | int retval; |
855 | static struct pci_device_id ciobx[] = { | 855 | static const struct pci_device_id ciobx[] = { |
856 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) }, | 856 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) }, |
857 | { }, | 857 | { }, |
858 | }; | 858 | }; |
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index 43e345ac296b..a6a4dac798e5 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c | |||
@@ -1153,7 +1153,7 @@ void ibmphp_free_ebda_pci_rsrc_queue(void) | |||
1153 | } | 1153 | } |
1154 | } | 1154 | } |
1155 | 1155 | ||
1156 | static struct pci_device_id id_table[] = { | 1156 | static const struct pci_device_id id_table[] = { |
1157 | { | 1157 | { |
1158 | .vendor = PCI_VENDOR_ID_IBM, | 1158 | .vendor = PCI_VENDOR_ID_IBM, |
1159 | .device = HPC_DEVICE_ID, | 1159 | .device = HPC_DEVICE_ID, |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 026830a138ae..e5d5ce9e3010 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -586,6 +586,14 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id) | |||
586 | events = status & (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | | 586 | events = status & (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | |
587 | PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_CC | | 587 | PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_CC | |
588 | PCI_EXP_SLTSTA_DLLSC); | 588 | PCI_EXP_SLTSTA_DLLSC); |
589 | |||
590 | /* | ||
591 | * If we've already reported a power fault, don't report it again | ||
592 | * until we've done something to handle it. | ||
593 | */ | ||
594 | if (ctrl->power_fault_detected) | ||
595 | events &= ~PCI_EXP_SLTSTA_PFD; | ||
596 | |||
589 | if (!events) | 597 | if (!events) |
590 | return IRQ_NONE; | 598 | return IRQ_NONE; |
591 | 599 | ||
diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c index 7c203198b582..74f6a17e4614 100644 --- a/drivers/pci/hotplug/pnv_php.c +++ b/drivers/pci/hotplug/pnv_php.c | |||
@@ -163,8 +163,8 @@ static void pnv_php_detach_device_nodes(struct device_node *parent) | |||
163 | of_node_put(dn); | 163 | of_node_put(dn); |
164 | refcount = kref_read(&dn->kobj.kref); | 164 | refcount = kref_read(&dn->kobj.kref); |
165 | if (refcount != 1) | 165 | if (refcount != 1) |
166 | pr_warn("Invalid refcount %d on <%s>\n", | 166 | pr_warn("Invalid refcount %d on <%pOF>\n", |
167 | refcount, of_node_full_name(dn)); | 167 | refcount, dn); |
168 | 168 | ||
169 | of_detach_node(dn); | 169 | of_detach_node(dn); |
170 | } | 170 | } |
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 3f93a4e79595..a3449d717a99 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c | |||
@@ -150,8 +150,8 @@ static void dlpar_pci_add_bus(struct device_node *dn) | |||
150 | /* Add EADS device to PHB bus, adding new entry to bus->devices */ | 150 | /* Add EADS device to PHB bus, adding new entry to bus->devices */ |
151 | dev = of_create_pci_dev(dn, phb->bus, pdn->devfn); | 151 | dev = of_create_pci_dev(dn, phb->bus, pdn->devfn); |
152 | if (!dev) { | 152 | if (!dev) { |
153 | printk(KERN_ERR "%s: failed to create pci dev for %s\n", | 153 | printk(KERN_ERR "%s: failed to create pci dev for %pOF\n", |
154 | __func__, dn->full_name); | 154 | __func__, dn); |
155 | return; | 155 | return; |
156 | } | 156 | } |
157 | 157 | ||
diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c index a796301ea03f..edb5d8a53020 100644 --- a/drivers/pci/hotplug/rpadlpar_sysfs.c +++ b/drivers/pci/hotplug/rpadlpar_sysfs.c | |||
@@ -102,7 +102,7 @@ static struct attribute *default_attrs[] = { | |||
102 | NULL, | 102 | NULL, |
103 | }; | 103 | }; |
104 | 104 | ||
105 | static struct attribute_group dlpar_attr_group = { | 105 | static const struct attribute_group dlpar_attr_group = { |
106 | .attrs = default_attrs, | 106 | .attrs = default_attrs, |
107 | }; | 107 | }; |
108 | 108 | ||
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 8d132024f06e..1e29abaaea08 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c | |||
@@ -318,7 +318,7 @@ int rpaphp_add_slot(struct device_node *dn) | |||
318 | if (!is_php_dn(dn, &indexes, &names, &types, &power_domains)) | 318 | if (!is_php_dn(dn, &indexes, &names, &types, &power_domains)) |
319 | return 0; | 319 | return 0; |
320 | 320 | ||
321 | dbg("Entry %s: dn->full_name=%s\n", __func__, dn->full_name); | 321 | dbg("Entry %s: dn=%pOF\n", __func__, dn); |
322 | 322 | ||
323 | /* register PCI devices */ | 323 | /* register PCI devices */ |
324 | name = (char *) &names[1]; | 324 | name = (char *) &names[1]; |
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index ea41ea1d3c00..32aabc533be8 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c | |||
@@ -95,7 +95,7 @@ int rpaphp_enable_slot(struct slot *slot) | |||
95 | 95 | ||
96 | bus = pci_find_bus_by_node(slot->dn); | 96 | bus = pci_find_bus_by_node(slot->dn); |
97 | if (!bus) { | 97 | if (!bus) { |
98 | err("%s: no pci_bus for dn %s\n", __func__, slot->dn->full_name); | 98 | err("%s: no pci_bus for dn %pOF\n", __func__, slot->dn); |
99 | return -EINVAL; | 99 | return -EINVAL; |
100 | } | 100 | } |
101 | 101 | ||
@@ -125,7 +125,7 @@ int rpaphp_enable_slot(struct slot *slot) | |||
125 | 125 | ||
126 | if (rpaphp_debug) { | 126 | if (rpaphp_debug) { |
127 | struct pci_dev *dev; | 127 | struct pci_dev *dev; |
128 | dbg("%s: pci_devs of slot[%s]\n", __func__, slot->dn->full_name); | 128 | dbg("%s: pci_devs of slot[%pOF]\n", __func__, slot->dn); |
129 | list_for_each_entry(dev, &bus->devices, bus_list) | 129 | list_for_each_entry(dev, &bus->devices, bus_list) |
130 | dbg("\t%s\n", pci_name(dev)); | 130 | dbg("\t%s\n", pci_name(dev)); |
131 | } | 131 | } |
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index 388c4d8fcdd1..489862360f2c 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c | |||
@@ -122,8 +122,8 @@ int rpaphp_register_slot(struct slot *slot) | |||
122 | int retval; | 122 | int retval; |
123 | int slotno = -1; | 123 | int slotno = -1; |
124 | 124 | ||
125 | dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n", | 125 | dbg("%s registering slot:path[%pOF] index[%x], name[%s] pdomain[%x] type[%d]\n", |
126 | __func__, slot->dn->full_name, slot->index, slot->name, | 126 | __func__, slot->dn, slot->index, slot->name, |
127 | slot->power_domain, slot->type); | 127 | slot->power_domain, slot->type); |
128 | 128 | ||
129 | /* should not try to register the same slot twice */ | 129 | /* should not try to register the same slot twice */ |
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 3454dc7385f1..7bfb87bd2b7e 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c | |||
@@ -351,7 +351,7 @@ static void shpc_remove(struct pci_dev *dev) | |||
351 | kfree(ctrl); | 351 | kfree(ctrl); |
352 | } | 352 | } |
353 | 353 | ||
354 | static struct pci_device_id shpcd_pci_tbl[] = { | 354 | static const struct pci_device_id shpcd_pci_tbl[] = { |
355 | {PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0)}, | 355 | {PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0)}, |
356 | { /* end: all zeroes */ } | 356 | { /* end: all zeroes */ } |
357 | }; | 357 | }; |
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index de0ea474fb73..e5824c7b7b6b 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
@@ -1062,6 +1062,8 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) | |||
1062 | if (rc) { | 1062 | if (rc) { |
1063 | ctrl_info(ctrl, "Can't get msi for the hotplug controller\n"); | 1063 | ctrl_info(ctrl, "Can't get msi for the hotplug controller\n"); |
1064 | ctrl_info(ctrl, "Use INTx for the hotplug controller\n"); | 1064 | ctrl_info(ctrl, "Use INTx for the hotplug controller\n"); |
1065 | } else { | ||
1066 | pci_set_master(pdev); | ||
1065 | } | 1067 | } |
1066 | 1068 | ||
1067 | rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED, | 1069 | rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED, |
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 120485d6f352..ac41c8be9200 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -331,7 +331,6 @@ failed: | |||
331 | while (i--) | 331 | while (i--) |
332 | pci_iov_remove_virtfn(dev, i, 0); | 332 | pci_iov_remove_virtfn(dev, i, 0); |
333 | 333 | ||
334 | pcibios_sriov_disable(dev); | ||
335 | err_pcibios: | 334 | err_pcibios: |
336 | iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); | 335 | iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); |
337 | pci_cfg_access_lock(dev); | 336 | pci_cfg_access_lock(dev); |
@@ -339,6 +338,8 @@ err_pcibios: | |||
339 | ssleep(1); | 338 | ssleep(1); |
340 | pci_cfg_access_unlock(dev); | 339 | pci_cfg_access_unlock(dev); |
341 | 340 | ||
341 | pcibios_sriov_disable(dev); | ||
342 | |||
342 | if (iov->link != dev->devfn) | 343 | if (iov->link != dev->devfn) |
343 | sysfs_remove_link(&dev->dev.kobj, "dep_link"); | 344 | sysfs_remove_link(&dev->dev.kobj, "dep_link"); |
344 | 345 | ||
@@ -357,14 +358,14 @@ static void sriov_disable(struct pci_dev *dev) | |||
357 | for (i = 0; i < iov->num_VFs; i++) | 358 | for (i = 0; i < iov->num_VFs; i++) |
358 | pci_iov_remove_virtfn(dev, i, 0); | 359 | pci_iov_remove_virtfn(dev, i, 0); |
359 | 360 | ||
360 | pcibios_sriov_disable(dev); | ||
361 | |||
362 | iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); | 361 | iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); |
363 | pci_cfg_access_lock(dev); | 362 | pci_cfg_access_lock(dev); |
364 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); | 363 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); |
365 | ssleep(1); | 364 | ssleep(1); |
366 | pci_cfg_access_unlock(dev); | 365 | pci_cfg_access_unlock(dev); |
367 | 366 | ||
367 | pcibios_sriov_disable(dev); | ||
368 | |||
368 | if (iov->link != dev->devfn) | 369 | if (iov->link != dev->devfn) |
369 | sysfs_remove_link(&dev->dev.kobj, "dep_link"); | 370 | sysfs_remove_link(&dev->dev.kobj, "dep_link"); |
370 | 371 | ||
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 2225afc1cbbb..496ed9130600 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -1451,13 +1451,30 @@ struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode, | |||
1451 | } | 1451 | } |
1452 | EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain); | 1452 | EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain); |
1453 | 1453 | ||
1454 | /* | ||
1455 | * Users of the generic MSI infrastructure expect a device to have a single ID, | ||
1456 | * so with DMA aliases we have to pick the least-worst compromise. Devices with | ||
1457 | * DMA phantom functions tend to still emit MSIs from the real function number, | ||
1458 | * so we ignore those and only consider topological aliases where either the | ||
1459 | * alias device or RID appears on a different bus number. We also make the | ||
1460 | * reasonable assumption that bridges are walked in an upstream direction (so | ||
1461 | * the last one seen wins), and the much braver assumption that the most likely | ||
1462 | * case is that of PCI->PCIe so we should always use the alias RID. This echoes | ||
1463 | * the logic from intel_irq_remapping's set_msi_sid(), which presumably works | ||
1464 | * well enough in practice; in the face of the horrible PCIe<->PCI-X conditions | ||
1465 | * for taking ownership all we can really do is close our eyes and hope... | ||
1466 | */ | ||
1454 | static int get_msi_id_cb(struct pci_dev *pdev, u16 alias, void *data) | 1467 | static int get_msi_id_cb(struct pci_dev *pdev, u16 alias, void *data) |
1455 | { | 1468 | { |
1456 | u32 *pa = data; | 1469 | u32 *pa = data; |
1470 | u8 bus = PCI_BUS_NUM(*pa); | ||
1471 | |||
1472 | if (pdev->bus->number != bus || PCI_BUS_NUM(alias) != bus) | ||
1473 | *pa = alias; | ||
1457 | 1474 | ||
1458 | *pa = alias; | ||
1459 | return 0; | 1475 | return 0; |
1460 | } | 1476 | } |
1477 | |||
1461 | /** | 1478 | /** |
1462 | * pci_msi_domain_get_msi_rid - Get the MSI requester id (RID) | 1479 | * pci_msi_domain_get_msi_rid - Get the MSI requester id (RID) |
1463 | * @domain: The interrupt domain | 1480 | * @domain: The interrupt domain |
@@ -1471,7 +1488,7 @@ static int get_msi_id_cb(struct pci_dev *pdev, u16 alias, void *data) | |||
1471 | u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev) | 1488 | u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev) |
1472 | { | 1489 | { |
1473 | struct device_node *of_node; | 1490 | struct device_node *of_node; |
1474 | u32 rid = 0; | 1491 | u32 rid = PCI_DEVID(pdev->bus->number, pdev->devfn); |
1475 | 1492 | ||
1476 | pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); | 1493 | pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); |
1477 | 1494 | ||
@@ -1487,14 +1504,14 @@ u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev) | |||
1487 | * @pdev: The PCI device | 1504 | * @pdev: The PCI device |
1488 | * | 1505 | * |
1489 | * Use the firmware data to find a device-specific MSI domain | 1506 | * Use the firmware data to find a device-specific MSI domain |
1490 | * (i.e. not one that is ste as a default). | 1507 | * (i.e. not one that is set as a default). |
1491 | * | 1508 | * |
1492 | * Returns: The coresponding MSI domain or NULL if none has been found. | 1509 | * Returns: The corresponding MSI domain or NULL if none has been found. |
1493 | */ | 1510 | */ |
1494 | struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev) | 1511 | struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev) |
1495 | { | 1512 | { |
1496 | struct irq_domain *dom; | 1513 | struct irq_domain *dom; |
1497 | u32 rid = 0; | 1514 | u32 rid = PCI_DEVID(pdev->bus->number, pdev->devfn); |
1498 | 1515 | ||
1499 | pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); | 1516 | pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); |
1500 | dom = of_msi_map_get_device_domain(&pdev->dev, rid); | 1517 | dom = of_msi_map_get_device_domain(&pdev->dev, rid); |
diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c index a7a41d9c29df..7e9e79575d93 100644 --- a/drivers/pci/pci-label.c +++ b/drivers/pci/pci-label.c | |||
@@ -123,7 +123,7 @@ static struct attribute *smbios_attributes[] = { | |||
123 | NULL, | 123 | NULL, |
124 | }; | 124 | }; |
125 | 125 | ||
126 | static struct attribute_group smbios_attr_group = { | 126 | static const struct attribute_group smbios_attr_group = { |
127 | .attrs = smbios_attributes, | 127 | .attrs = smbios_attributes, |
128 | .is_visible = smbios_instance_string_exist, | 128 | .is_visible = smbios_instance_string_exist, |
129 | }; | 129 | }; |
@@ -260,7 +260,7 @@ static struct attribute *acpi_attributes[] = { | |||
260 | NULL, | 260 | NULL, |
261 | }; | 261 | }; |
262 | 262 | ||
263 | static struct attribute_group acpi_attr_group = { | 263 | static const struct attribute_group acpi_attr_group = { |
264 | .attrs = acpi_attributes, | 264 | .attrs = acpi_attributes, |
265 | .is_visible = acpi_index_string_exist, | 265 | .is_visible = acpi_index_string_exist, |
266 | }; | 266 | }; |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 2f3780b50723..1eecfa301f7f 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -556,9 +556,9 @@ static ssize_t devspec_show(struct device *dev, | |||
556 | struct pci_dev *pdev = to_pci_dev(dev); | 556 | struct pci_dev *pdev = to_pci_dev(dev); |
557 | struct device_node *np = pci_device_to_OF_node(pdev); | 557 | struct device_node *np = pci_device_to_OF_node(pdev); |
558 | 558 | ||
559 | if (np == NULL || np->full_name == NULL) | 559 | if (np == NULL) |
560 | return 0; | 560 | return 0; |
561 | return sprintf(buf, "%s", np->full_name); | 561 | return sprintf(buf, "%pOF", np); |
562 | } | 562 | } |
563 | static DEVICE_ATTR_RO(devspec); | 563 | static DEVICE_ATTR_RO(devspec); |
564 | #endif | 564 | #endif |
@@ -1211,11 +1211,8 @@ static ssize_t pci_resource_io(struct file *filp, struct kobject *kobj, | |||
1211 | { | 1211 | { |
1212 | struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); | 1212 | struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); |
1213 | int bar = (unsigned long)attr->private; | 1213 | int bar = (unsigned long)attr->private; |
1214 | struct resource *res; | ||
1215 | unsigned long port = off; | 1214 | unsigned long port = off; |
1216 | 1215 | ||
1217 | res = &pdev->resource[bar]; | ||
1218 | |||
1219 | port += pci_resource_start(pdev, bar); | 1216 | port += pci_resource_start(pdev, bar); |
1220 | 1217 | ||
1221 | if (port > pci_resource_end(pdev, bar)) | 1218 | if (port > pci_resource_end(pdev, bar)) |
@@ -1431,7 +1428,7 @@ static ssize_t pci_read_rom(struct file *filp, struct kobject *kobj, | |||
1431 | return count; | 1428 | return count; |
1432 | } | 1429 | } |
1433 | 1430 | ||
1434 | static struct bin_attribute pci_config_attr = { | 1431 | static const struct bin_attribute pci_config_attr = { |
1435 | .attr = { | 1432 | .attr = { |
1436 | .name = "config", | 1433 | .name = "config", |
1437 | .mode = S_IRUGO | S_IWUSR, | 1434 | .mode = S_IRUGO | S_IWUSR, |
@@ -1441,7 +1438,7 @@ static struct bin_attribute pci_config_attr = { | |||
1441 | .write = pci_write_config, | 1438 | .write = pci_write_config, |
1442 | }; | 1439 | }; |
1443 | 1440 | ||
1444 | static struct bin_attribute pcie_config_attr = { | 1441 | static const struct bin_attribute pcie_config_attr = { |
1445 | .attr = { | 1442 | .attr = { |
1446 | .name = "config", | 1443 | .name = "config", |
1447 | .mode = S_IRUGO | S_IWUSR, | 1444 | .mode = S_IRUGO | S_IWUSR, |
@@ -1735,7 +1732,7 @@ const struct attribute_group *pcie_dev_groups[] = { | |||
1735 | NULL, | 1732 | NULL, |
1736 | }; | 1733 | }; |
1737 | 1734 | ||
1738 | static struct attribute_group pci_dev_hp_attr_group = { | 1735 | static const struct attribute_group pci_dev_hp_attr_group = { |
1739 | .attrs = pci_dev_hp_attrs, | 1736 | .attrs = pci_dev_hp_attrs, |
1740 | .is_visible = pci_dev_hp_attrs_are_visible, | 1737 | .is_visible = pci_dev_hp_attrs_are_visible, |
1741 | }; | 1738 | }; |
@@ -1759,23 +1756,23 @@ static umode_t sriov_attrs_are_visible(struct kobject *kobj, | |||
1759 | return a->mode; | 1756 | return a->mode; |
1760 | } | 1757 | } |
1761 | 1758 | ||
1762 | static struct attribute_group sriov_dev_attr_group = { | 1759 | static const struct attribute_group sriov_dev_attr_group = { |
1763 | .attrs = sriov_dev_attrs, | 1760 | .attrs = sriov_dev_attrs, |
1764 | .is_visible = sriov_attrs_are_visible, | 1761 | .is_visible = sriov_attrs_are_visible, |
1765 | }; | 1762 | }; |
1766 | #endif /* CONFIG_PCI_IOV */ | 1763 | #endif /* CONFIG_PCI_IOV */ |
1767 | 1764 | ||
1768 | static struct attribute_group pci_dev_attr_group = { | 1765 | static const struct attribute_group pci_dev_attr_group = { |
1769 | .attrs = pci_dev_dev_attrs, | 1766 | .attrs = pci_dev_dev_attrs, |
1770 | .is_visible = pci_dev_attrs_are_visible, | 1767 | .is_visible = pci_dev_attrs_are_visible, |
1771 | }; | 1768 | }; |
1772 | 1769 | ||
1773 | static struct attribute_group pci_bridge_attr_group = { | 1770 | static const struct attribute_group pci_bridge_attr_group = { |
1774 | .attrs = pci_bridge_attrs, | 1771 | .attrs = pci_bridge_attrs, |
1775 | .is_visible = pci_bridge_attrs_are_visible, | 1772 | .is_visible = pci_bridge_attrs_are_visible, |
1776 | }; | 1773 | }; |
1777 | 1774 | ||
1778 | static struct attribute_group pcie_dev_attr_group = { | 1775 | static const struct attribute_group pcie_dev_attr_group = { |
1779 | .attrs = pcie_dev_attrs, | 1776 | .attrs = pcie_dev_attrs, |
1780 | .is_visible = pcie_dev_attrs_are_visible, | 1777 | .is_visible = pcie_dev_attrs_are_visible, |
1781 | }; | 1778 | }; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 68e3b2b0da93..b0002daa50f3 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -52,6 +52,7 @@ static void pci_pme_list_scan(struct work_struct *work); | |||
52 | static LIST_HEAD(pci_pme_list); | 52 | static LIST_HEAD(pci_pme_list); |
53 | static DEFINE_MUTEX(pci_pme_list_mutex); | 53 | static DEFINE_MUTEX(pci_pme_list_mutex); |
54 | static DECLARE_DELAYED_WORK(pci_pme_work, pci_pme_list_scan); | 54 | static DECLARE_DELAYED_WORK(pci_pme_work, pci_pme_list_scan); |
55 | static DEFINE_MUTEX(pci_bridge_mutex); | ||
55 | 56 | ||
56 | struct pci_pme_device { | 57 | struct pci_pme_device { |
57 | struct list_head list; | 58 | struct list_head list; |
@@ -892,7 +893,9 @@ EXPORT_SYMBOL_GPL(__pci_complete_power_transition); | |||
892 | * -EINVAL if the requested state is invalid. | 893 | * -EINVAL if the requested state is invalid. |
893 | * -EIO if device does not support PCI PM or its PM capabilities register has a | 894 | * -EIO if device does not support PCI PM or its PM capabilities register has a |
894 | * wrong version, or device doesn't support the requested state. | 895 | * wrong version, or device doesn't support the requested state. |
896 | * 0 if the transition is to D1 or D2 but D1 and D2 are not supported. | ||
895 | * 0 if device already is in the requested state. | 897 | * 0 if device already is in the requested state. |
898 | * 0 if the transition is to D3 but D3 is not supported. | ||
896 | * 0 if device's power state has been successfully changed. | 899 | * 0 if device's power state has been successfully changed. |
897 | */ | 900 | */ |
898 | int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | 901 | int pci_set_power_state(struct pci_dev *dev, pci_power_t state) |
@@ -1348,10 +1351,16 @@ static void pci_enable_bridge(struct pci_dev *dev) | |||
1348 | if (bridge) | 1351 | if (bridge) |
1349 | pci_enable_bridge(bridge); | 1352 | pci_enable_bridge(bridge); |
1350 | 1353 | ||
1354 | /* | ||
1355 | * Hold pci_bridge_mutex to prevent a race when enabling two | ||
1356 | * devices below the bridge simultaneously. The race may cause a | ||
1357 | * PCI_COMMAND_MEMORY update to be lost (see changelog). | ||
1358 | */ | ||
1359 | mutex_lock(&pci_bridge_mutex); | ||
1351 | if (pci_is_enabled(dev)) { | 1360 | if (pci_is_enabled(dev)) { |
1352 | if (!dev->is_busmaster) | 1361 | if (!dev->is_busmaster) |
1353 | pci_set_master(dev); | 1362 | pci_set_master(dev); |
1354 | return; | 1363 | goto end; |
1355 | } | 1364 | } |
1356 | 1365 | ||
1357 | retval = pci_enable_device(dev); | 1366 | retval = pci_enable_device(dev); |
@@ -1359,6 +1368,8 @@ static void pci_enable_bridge(struct pci_dev *dev) | |||
1359 | dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n", | 1368 | dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n", |
1360 | retval); | 1369 | retval); |
1361 | pci_set_master(dev); | 1370 | pci_set_master(dev); |
1371 | end: | ||
1372 | mutex_unlock(&pci_bridge_mutex); | ||
1362 | } | 1373 | } |
1363 | 1374 | ||
1364 | static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) | 1375 | static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) |
@@ -1383,7 +1394,7 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) | |||
1383 | return 0; /* already enabled */ | 1394 | return 0; /* already enabled */ |
1384 | 1395 | ||
1385 | bridge = pci_upstream_bridge(dev); | 1396 | bridge = pci_upstream_bridge(dev); |
1386 | if (bridge) | 1397 | if (bridge && !pci_is_enabled(bridge)) |
1387 | pci_enable_bridge(bridge); | 1398 | pci_enable_bridge(bridge); |
1388 | 1399 | ||
1389 | /* only skip sriov related */ | 1400 | /* only skip sriov related */ |
@@ -3818,27 +3829,49 @@ int pci_wait_for_pending_transaction(struct pci_dev *dev) | |||
3818 | } | 3829 | } |
3819 | EXPORT_SYMBOL(pci_wait_for_pending_transaction); | 3830 | EXPORT_SYMBOL(pci_wait_for_pending_transaction); |
3820 | 3831 | ||
3821 | /* | ||
3822 | * We should only need to wait 100ms after FLR, but some devices take longer. | ||
3823 | * Wait for up to 1000ms for config space to return something other than -1. | ||
3824 | * Intel IGD requires this when an LCD panel is attached. We read the 2nd | ||
3825 | * dword because VFs don't implement the 1st dword. | ||
3826 | */ | ||
3827 | static void pci_flr_wait(struct pci_dev *dev) | 3832 | static void pci_flr_wait(struct pci_dev *dev) |
3828 | { | 3833 | { |
3829 | int i = 0; | 3834 | int delay = 1, timeout = 60000; |
3830 | u32 id; | 3835 | u32 id; |
3831 | 3836 | ||
3832 | do { | 3837 | /* |
3833 | msleep(100); | 3838 | * Per PCIe r3.1, sec 6.6.2, a device must complete an FLR within |
3839 | * 100ms, but may silently discard requests while the FLR is in | ||
3840 | * progress. Wait 100ms before trying to access the device. | ||
3841 | */ | ||
3842 | msleep(100); | ||
3843 | |||
3844 | /* | ||
3845 | * After 100ms, the device should not silently discard config | ||
3846 | * requests, but it may still indicate that it needs more time by | ||
3847 | * responding to them with CRS completions. The Root Port will | ||
3848 | * generally synthesize ~0 data to complete the read (except when | ||
3849 | * CRS SV is enabled and the read was for the Vendor ID; in that | ||
3850 | * case it synthesizes 0x0001 data). | ||
3851 | * | ||
3852 | * Wait for the device to return a non-CRS completion. Read the | ||
3853 | * Command register instead of Vendor ID so we don't have to | ||
3854 | * contend with the CRS SV value. | ||
3855 | */ | ||
3856 | pci_read_config_dword(dev, PCI_COMMAND, &id); | ||
3857 | while (id == ~0) { | ||
3858 | if (delay > timeout) { | ||
3859 | dev_warn(&dev->dev, "not ready %dms after FLR; giving up\n", | ||
3860 | 100 + delay - 1); | ||
3861 | return; | ||
3862 | } | ||
3863 | |||
3864 | if (delay > 1000) | ||
3865 | dev_info(&dev->dev, "not ready %dms after FLR; waiting\n", | ||
3866 | 100 + delay - 1); | ||
3867 | |||
3868 | msleep(delay); | ||
3869 | delay *= 2; | ||
3834 | pci_read_config_dword(dev, PCI_COMMAND, &id); | 3870 | pci_read_config_dword(dev, PCI_COMMAND, &id); |
3835 | } while (i++ < 10 && id == ~0); | 3871 | } |
3836 | 3872 | ||
3837 | if (id == ~0) | 3873 | if (delay > 1000) |
3838 | dev_warn(&dev->dev, "Failed to return from FLR\n"); | 3874 | dev_info(&dev->dev, "ready %dms after FLR\n", 100 + delay - 1); |
3839 | else if (i > 1) | ||
3840 | dev_info(&dev->dev, "Required additional %dms to return from FLR\n", | ||
3841 | (i - 1) * 100); | ||
3842 | } | 3875 | } |
3843 | 3876 | ||
3844 | /** | 3877 | /** |
@@ -5405,8 +5438,8 @@ static int of_pci_bus_find_domain_nr(struct device *parent) | |||
5405 | use_dt_domains = 0; | 5438 | use_dt_domains = 0; |
5406 | domain = pci_get_new_domain_nr(); | 5439 | domain = pci_get_new_domain_nr(); |
5407 | } else { | 5440 | } else { |
5408 | dev_err(parent, "Node %s has inconsistent \"linux,pci-domain\" property in DT\n", | 5441 | dev_err(parent, "Node %pOF has inconsistent \"linux,pci-domain\" property in DT\n", |
5409 | parent->of_node->full_name); | 5442 | parent->of_node); |
5410 | domain = -1; | 5443 | domain = -1; |
5411 | } | 5444 | } |
5412 | 5445 | ||
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 22e061738c6f..a6560c9baa52 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -235,6 +235,7 @@ enum pci_bar_type { | |||
235 | pci_bar_mem64, /* A 64-bit memory BAR */ | 235 | pci_bar_mem64, /* A 64-bit memory BAR */ |
236 | }; | 236 | }; |
237 | 237 | ||
238 | int pci_configure_extended_tags(struct pci_dev *dev, void *ign); | ||
238 | bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, | 239 | bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, |
239 | int crs_timeout); | 240 | int crs_timeout); |
240 | int pci_setup_device(struct pci_dev *dev); | 241 | int pci_setup_device(struct pci_dev *dev); |
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index dea186a9d6b6..6ff5f5b4f5e6 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c | |||
@@ -32,16 +32,9 @@ | |||
32 | 32 | ||
33 | static int aer_probe(struct pcie_device *dev); | 33 | static int aer_probe(struct pcie_device *dev); |
34 | static void aer_remove(struct pcie_device *dev); | 34 | static void aer_remove(struct pcie_device *dev); |
35 | static pci_ers_result_t aer_error_detected(struct pci_dev *dev, | ||
36 | enum pci_channel_state error); | ||
37 | static void aer_error_resume(struct pci_dev *dev); | 35 | static void aer_error_resume(struct pci_dev *dev); |
38 | static pci_ers_result_t aer_root_reset(struct pci_dev *dev); | 36 | static pci_ers_result_t aer_root_reset(struct pci_dev *dev); |
39 | 37 | ||
40 | static const struct pci_error_handlers aer_error_handlers = { | ||
41 | .error_detected = aer_error_detected, | ||
42 | .resume = aer_error_resume, | ||
43 | }; | ||
44 | |||
45 | static struct pcie_port_service_driver aerdriver = { | 38 | static struct pcie_port_service_driver aerdriver = { |
46 | .name = "aer", | 39 | .name = "aer", |
47 | .port_type = PCI_EXP_TYPE_ROOT_PORT, | 40 | .port_type = PCI_EXP_TYPE_ROOT_PORT, |
@@ -49,9 +42,7 @@ static struct pcie_port_service_driver aerdriver = { | |||
49 | 42 | ||
50 | .probe = aer_probe, | 43 | .probe = aer_probe, |
51 | .remove = aer_remove, | 44 | .remove = aer_remove, |
52 | 45 | .error_resume = aer_error_resume, | |
53 | .err_handler = &aer_error_handlers, | ||
54 | |||
55 | .reset_link = aer_root_reset, | 46 | .reset_link = aer_root_reset, |
56 | }; | 47 | }; |
57 | 48 | ||
@@ -350,20 +341,6 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev) | |||
350 | } | 341 | } |
351 | 342 | ||
352 | /** | 343 | /** |
353 | * aer_error_detected - update severity status | ||
354 | * @dev: pointer to Root Port's pci_dev data structure | ||
355 | * @error: error severity being notified by port bus | ||
356 | * | ||
357 | * Invoked by Port Bus driver during error recovery. | ||
358 | */ | ||
359 | static pci_ers_result_t aer_error_detected(struct pci_dev *dev, | ||
360 | enum pci_channel_state error) | ||
361 | { | ||
362 | /* Root Port has no impact. Always recovers. */ | ||
363 | return PCI_ERS_RESULT_CAN_RECOVER; | ||
364 | } | ||
365 | |||
366 | /** | ||
367 | * aer_error_resume - clean up corresponding error status bits | 344 | * aer_error_resume - clean up corresponding error status bits |
368 | * @dev: pointer to Root Port's pci_dev data structure | 345 | * @dev: pointer to Root Port's pci_dev data structure |
369 | * | 346 | * |
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index b1303b32053f..890efcc574cb 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -5,10 +5,10 @@ | |||
5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * This file implements the core part of PCI-Express AER. When an pci-express | 8 | * This file implements the core part of PCIe AER. When a PCIe |
9 | * error is delivered, an error message will be collected and printed to | 9 | * error is delivered, an error message will be collected and printed to |
10 | * console, then, an error recovery procedure will be executed by following | 10 | * console, then, an error recovery procedure will be executed by following |
11 | * the pci error recovery rules. | 11 | * the PCI error recovery rules. |
12 | * | 12 | * |
13 | * Copyright (C) 2006 Intel Corp. | 13 | * Copyright (C) 2006 Intel Corp. |
14 | * Tom Long Nguyen (tom.l.nguyen@intel.com) | 14 | * Tom Long Nguyen (tom.l.nguyen@intel.com) |
diff --git a/drivers/pci/pcie/pcie-dpc.c b/drivers/pci/pcie/pcie-dpc.c index c39f32e42b4d..2d976a623ddc 100644 --- a/drivers/pci/pcie/pcie-dpc.c +++ b/drivers/pci/pcie/pcie-dpc.c | |||
@@ -16,17 +16,62 @@ | |||
16 | #include <linux/pcieport_if.h> | 16 | #include <linux/pcieport_if.h> |
17 | #include "../pci.h" | 17 | #include "../pci.h" |
18 | 18 | ||
19 | struct rp_pio_header_log_regs { | ||
20 | u32 dw0; | ||
21 | u32 dw1; | ||
22 | u32 dw2; | ||
23 | u32 dw3; | ||
24 | }; | ||
25 | |||
26 | struct dpc_rp_pio_regs { | ||
27 | u32 status; | ||
28 | u32 mask; | ||
29 | u32 severity; | ||
30 | u32 syserror; | ||
31 | u32 exception; | ||
32 | |||
33 | struct rp_pio_header_log_regs header_log; | ||
34 | u32 impspec_log; | ||
35 | u32 tlp_prefix_log[4]; | ||
36 | u32 log_size; | ||
37 | u16 first_error; | ||
38 | }; | ||
39 | |||
19 | struct dpc_dev { | 40 | struct dpc_dev { |
20 | struct pcie_device *dev; | 41 | struct pcie_device *dev; |
21 | struct work_struct work; | 42 | struct work_struct work; |
22 | int cap_pos; | 43 | int cap_pos; |
23 | bool rp; | 44 | bool rp; |
45 | u32 rp_pio_status; | ||
46 | }; | ||
47 | |||
48 | static const char * const rp_pio_error_string[] = { | ||
49 | "Configuration Request received UR Completion", /* Bit Position 0 */ | ||
50 | "Configuration Request received CA Completion", /* Bit Position 1 */ | ||
51 | "Configuration Request Completion Timeout", /* Bit Position 2 */ | ||
52 | NULL, | ||
53 | NULL, | ||
54 | NULL, | ||
55 | NULL, | ||
56 | NULL, | ||
57 | "I/O Request received UR Completion", /* Bit Position 8 */ | ||
58 | "I/O Request received CA Completion", /* Bit Position 9 */ | ||
59 | "I/O Request Completion Timeout", /* Bit Position 10 */ | ||
60 | NULL, | ||
61 | NULL, | ||
62 | NULL, | ||
63 | NULL, | ||
64 | NULL, | ||
65 | "Memory Request received UR Completion", /* Bit Position 16 */ | ||
66 | "Memory Request received CA Completion", /* Bit Position 17 */ | ||
67 | "Memory Request Completion Timeout", /* Bit Position 18 */ | ||
24 | }; | 68 | }; |
25 | 69 | ||
26 | static int dpc_wait_rp_inactive(struct dpc_dev *dpc) | 70 | static int dpc_wait_rp_inactive(struct dpc_dev *dpc) |
27 | { | 71 | { |
28 | unsigned long timeout = jiffies + HZ; | 72 | unsigned long timeout = jiffies + HZ; |
29 | struct pci_dev *pdev = dpc->dev->port; | 73 | struct pci_dev *pdev = dpc->dev->port; |
74 | struct device *dev = &dpc->dev->device; | ||
30 | u16 status; | 75 | u16 status; |
31 | 76 | ||
32 | pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, &status); | 77 | pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, &status); |
@@ -36,15 +81,17 @@ static int dpc_wait_rp_inactive(struct dpc_dev *dpc) | |||
36 | pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, &status); | 81 | pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, &status); |
37 | } | 82 | } |
38 | if (status & PCI_EXP_DPC_RP_BUSY) { | 83 | if (status & PCI_EXP_DPC_RP_BUSY) { |
39 | dev_warn(&pdev->dev, "DPC root port still busy\n"); | 84 | dev_warn(dev, "DPC root port still busy\n"); |
40 | return -EBUSY; | 85 | return -EBUSY; |
41 | } | 86 | } |
42 | return 0; | 87 | return 0; |
43 | } | 88 | } |
44 | 89 | ||
45 | static void dpc_wait_link_inactive(struct pci_dev *pdev) | 90 | static void dpc_wait_link_inactive(struct dpc_dev *dpc) |
46 | { | 91 | { |
47 | unsigned long timeout = jiffies + HZ; | 92 | unsigned long timeout = jiffies + HZ; |
93 | struct pci_dev *pdev = dpc->dev->port; | ||
94 | struct device *dev = &dpc->dev->device; | ||
48 | u16 lnk_status; | 95 | u16 lnk_status; |
49 | 96 | ||
50 | pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status); | 97 | pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status); |
@@ -54,7 +101,7 @@ static void dpc_wait_link_inactive(struct pci_dev *pdev) | |||
54 | pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status); | 101 | pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status); |
55 | } | 102 | } |
56 | if (lnk_status & PCI_EXP_LNKSTA_DLLLA) | 103 | if (lnk_status & PCI_EXP_LNKSTA_DLLLA) |
57 | dev_warn(&pdev->dev, "Link state not disabled for DPC event\n"); | 104 | dev_warn(dev, "Link state not disabled for DPC event\n"); |
58 | } | 105 | } |
59 | 106 | ||
60 | static void interrupt_event_handler(struct work_struct *work) | 107 | static void interrupt_event_handler(struct work_struct *work) |
@@ -76,17 +123,132 @@ static void interrupt_event_handler(struct work_struct *work) | |||
76 | } | 123 | } |
77 | pci_unlock_rescan_remove(); | 124 | pci_unlock_rescan_remove(); |
78 | 125 | ||
79 | dpc_wait_link_inactive(pdev); | 126 | dpc_wait_link_inactive(dpc); |
80 | if (dpc->rp && dpc_wait_rp_inactive(dpc)) | 127 | if (dpc->rp && dpc_wait_rp_inactive(dpc)) |
81 | return; | 128 | return; |
129 | if (dpc->rp && dpc->rp_pio_status) { | ||
130 | pci_write_config_dword(pdev, | ||
131 | dpc->cap_pos + PCI_EXP_DPC_RP_PIO_STATUS, | ||
132 | dpc->rp_pio_status); | ||
133 | dpc->rp_pio_status = 0; | ||
134 | } | ||
135 | |||
82 | pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, | 136 | pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, |
83 | PCI_EXP_DPC_STATUS_TRIGGER | PCI_EXP_DPC_STATUS_INTERRUPT); | 137 | PCI_EXP_DPC_STATUS_TRIGGER | PCI_EXP_DPC_STATUS_INTERRUPT); |
84 | } | 138 | } |
85 | 139 | ||
140 | static void dpc_rp_pio_print_tlp_header(struct device *dev, | ||
141 | struct rp_pio_header_log_regs *t) | ||
142 | { | ||
143 | dev_err(dev, "TLP Header: %#010x %#010x %#010x %#010x\n", | ||
144 | t->dw0, t->dw1, t->dw2, t->dw3); | ||
145 | } | ||
146 | |||
147 | static void dpc_rp_pio_print_error(struct dpc_dev *dpc, | ||
148 | struct dpc_rp_pio_regs *rp_pio) | ||
149 | { | ||
150 | struct device *dev = &dpc->dev->device; | ||
151 | int i; | ||
152 | u32 status; | ||
153 | |||
154 | dev_err(dev, "rp_pio_status: %#010x, rp_pio_mask: %#010x\n", | ||
155 | rp_pio->status, rp_pio->mask); | ||
156 | |||
157 | dev_err(dev, "RP PIO severity=%#010x, syserror=%#010x, exception=%#010x\n", | ||
158 | rp_pio->severity, rp_pio->syserror, rp_pio->exception); | ||
159 | |||
160 | status = (rp_pio->status & ~rp_pio->mask); | ||
161 | |||
162 | for (i = 0; i < ARRAY_SIZE(rp_pio_error_string); i++) { | ||
163 | if (!(status & (1 << i))) | ||
164 | continue; | ||
165 | |||
166 | dev_err(dev, "[%2d] %s%s\n", i, rp_pio_error_string[i], | ||
167 | rp_pio->first_error == i ? " (First)" : ""); | ||
168 | } | ||
169 | |||
170 | dpc_rp_pio_print_tlp_header(dev, &rp_pio->header_log); | ||
171 | if (rp_pio->log_size == 4) | ||
172 | return; | ||
173 | dev_err(dev, "RP PIO ImpSpec Log %#010x\n", rp_pio->impspec_log); | ||
174 | |||
175 | for (i = 0; i < rp_pio->log_size - 5; i++) | ||
176 | dev_err(dev, "TLP Prefix Header: dw%d, %#010x\n", i, | ||
177 | rp_pio->tlp_prefix_log[i]); | ||
178 | } | ||
179 | |||
180 | static void dpc_rp_pio_get_info(struct dpc_dev *dpc, | ||
181 | struct dpc_rp_pio_regs *rp_pio) | ||
182 | { | ||
183 | struct pci_dev *pdev = dpc->dev->port; | ||
184 | struct device *dev = &dpc->dev->device; | ||
185 | int i; | ||
186 | u16 cap; | ||
187 | u16 status; | ||
188 | |||
189 | pci_read_config_dword(pdev, dpc->cap_pos + PCI_EXP_DPC_RP_PIO_STATUS, | ||
190 | &rp_pio->status); | ||
191 | pci_read_config_dword(pdev, dpc->cap_pos + PCI_EXP_DPC_RP_PIO_MASK, | ||
192 | &rp_pio->mask); | ||
193 | |||
194 | pci_read_config_dword(pdev, dpc->cap_pos + PCI_EXP_DPC_RP_PIO_SEVERITY, | ||
195 | &rp_pio->severity); | ||
196 | pci_read_config_dword(pdev, dpc->cap_pos + PCI_EXP_DPC_RP_PIO_SYSERROR, | ||
197 | &rp_pio->syserror); | ||
198 | pci_read_config_dword(pdev, dpc->cap_pos + PCI_EXP_DPC_RP_PIO_EXCEPTION, | ||
199 | &rp_pio->exception); | ||
200 | |||
201 | /* Get First Error Pointer */ | ||
202 | pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, &status); | ||
203 | rp_pio->first_error = (status & 0x1f00) >> 8; | ||
204 | |||
205 | pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CAP, &cap); | ||
206 | rp_pio->log_size = (cap & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8; | ||
207 | if (rp_pio->log_size < 4 || rp_pio->log_size > 9) { | ||
208 | dev_err(dev, "RP PIO log size %u is invalid\n", | ||
209 | rp_pio->log_size); | ||
210 | return; | ||
211 | } | ||
212 | |||
213 | pci_read_config_dword(pdev, | ||
214 | dpc->cap_pos + PCI_EXP_DPC_RP_PIO_HEADER_LOG, | ||
215 | &rp_pio->header_log.dw0); | ||
216 | pci_read_config_dword(pdev, | ||
217 | dpc->cap_pos + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 4, | ||
218 | &rp_pio->header_log.dw1); | ||
219 | pci_read_config_dword(pdev, | ||
220 | dpc->cap_pos + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 8, | ||
221 | &rp_pio->header_log.dw2); | ||
222 | pci_read_config_dword(pdev, | ||
223 | dpc->cap_pos + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 12, | ||
224 | &rp_pio->header_log.dw3); | ||
225 | if (rp_pio->log_size == 4) | ||
226 | return; | ||
227 | |||
228 | pci_read_config_dword(pdev, | ||
229 | dpc->cap_pos + PCI_EXP_DPC_RP_PIO_IMPSPEC_LOG, | ||
230 | &rp_pio->impspec_log); | ||
231 | for (i = 0; i < rp_pio->log_size - 5; i++) | ||
232 | pci_read_config_dword(pdev, | ||
233 | dpc->cap_pos + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG, | ||
234 | &rp_pio->tlp_prefix_log[i]); | ||
235 | } | ||
236 | |||
237 | static void dpc_process_rp_pio_error(struct dpc_dev *dpc) | ||
238 | { | ||
239 | struct dpc_rp_pio_regs rp_pio_regs; | ||
240 | |||
241 | dpc_rp_pio_get_info(dpc, &rp_pio_regs); | ||
242 | dpc_rp_pio_print_error(dpc, &rp_pio_regs); | ||
243 | |||
244 | dpc->rp_pio_status = rp_pio_regs.status; | ||
245 | } | ||
246 | |||
86 | static irqreturn_t dpc_irq(int irq, void *context) | 247 | static irqreturn_t dpc_irq(int irq, void *context) |
87 | { | 248 | { |
88 | struct dpc_dev *dpc = (struct dpc_dev *)context; | 249 | struct dpc_dev *dpc = (struct dpc_dev *)context; |
89 | struct pci_dev *pdev = dpc->dev->port; | 250 | struct pci_dev *pdev = dpc->dev->port; |
251 | struct device *dev = &dpc->dev->device; | ||
90 | u16 status, source; | 252 | u16 status, source; |
91 | 253 | ||
92 | pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, &status); | 254 | pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, &status); |
@@ -95,20 +257,24 @@ static irqreturn_t dpc_irq(int irq, void *context) | |||
95 | if (!status || status == (u16)(~0)) | 257 | if (!status || status == (u16)(~0)) |
96 | return IRQ_NONE; | 258 | return IRQ_NONE; |
97 | 259 | ||
98 | dev_info(&dpc->dev->device, "DPC containment event, status:%#06x source:%#06x\n", | 260 | dev_info(dev, "DPC containment event, status:%#06x source:%#06x\n", |
99 | status, source); | 261 | status, source); |
100 | 262 | ||
101 | if (status & PCI_EXP_DPC_STATUS_TRIGGER) { | 263 | if (status & PCI_EXP_DPC_STATUS_TRIGGER) { |
102 | u16 reason = (status >> 1) & 0x3; | 264 | u16 reason = (status >> 1) & 0x3; |
103 | u16 ext_reason = (status >> 5) & 0x3; | 265 | u16 ext_reason = (status >> 5) & 0x3; |
104 | 266 | ||
105 | dev_warn(&dpc->dev->device, "DPC %s detected, remove downstream devices\n", | 267 | dev_warn(dev, "DPC %s detected, remove downstream devices\n", |
106 | (reason == 0) ? "unmasked uncorrectable error" : | 268 | (reason == 0) ? "unmasked uncorrectable error" : |
107 | (reason == 1) ? "ERR_NONFATAL" : | 269 | (reason == 1) ? "ERR_NONFATAL" : |
108 | (reason == 2) ? "ERR_FATAL" : | 270 | (reason == 2) ? "ERR_FATAL" : |
109 | (ext_reason == 0) ? "RP PIO error" : | 271 | (ext_reason == 0) ? "RP PIO error" : |
110 | (ext_reason == 1) ? "software trigger" : | 272 | (ext_reason == 1) ? "software trigger" : |
111 | "reserved error"); | 273 | "reserved error"); |
274 | /* show RP PIO error detail information */ | ||
275 | if (reason == 3 && ext_reason == 0) | ||
276 | dpc_process_rp_pio_error(dpc); | ||
277 | |||
112 | schedule_work(&dpc->work); | 278 | schedule_work(&dpc->work); |
113 | } | 279 | } |
114 | return IRQ_HANDLED; | 280 | return IRQ_HANDLED; |
@@ -119,10 +285,11 @@ static int dpc_probe(struct pcie_device *dev) | |||
119 | { | 285 | { |
120 | struct dpc_dev *dpc; | 286 | struct dpc_dev *dpc; |
121 | struct pci_dev *pdev = dev->port; | 287 | struct pci_dev *pdev = dev->port; |
288 | struct device *device = &dev->device; | ||
122 | int status; | 289 | int status; |
123 | u16 ctl, cap; | 290 | u16 ctl, cap; |
124 | 291 | ||
125 | dpc = devm_kzalloc(&dev->device, sizeof(*dpc), GFP_KERNEL); | 292 | dpc = devm_kzalloc(device, sizeof(*dpc), GFP_KERNEL); |
126 | if (!dpc) | 293 | if (!dpc) |
127 | return -ENOMEM; | 294 | return -ENOMEM; |
128 | 295 | ||
@@ -131,10 +298,10 @@ static int dpc_probe(struct pcie_device *dev) | |||
131 | INIT_WORK(&dpc->work, interrupt_event_handler); | 298 | INIT_WORK(&dpc->work, interrupt_event_handler); |
132 | set_service_data(dev, dpc); | 299 | set_service_data(dev, dpc); |
133 | 300 | ||
134 | status = devm_request_irq(&dev->device, dev->irq, dpc_irq, IRQF_SHARED, | 301 | status = devm_request_irq(device, dev->irq, dpc_irq, IRQF_SHARED, |
135 | "pcie-dpc", dpc); | 302 | "pcie-dpc", dpc); |
136 | if (status) { | 303 | if (status) { |
137 | dev_warn(&dev->device, "request IRQ%d failed: %d\n", dev->irq, | 304 | dev_warn(device, "request IRQ%d failed: %d\n", dev->irq, |
138 | status); | 305 | status); |
139 | return status; | 306 | return status; |
140 | } | 307 | } |
@@ -147,7 +314,7 @@ static int dpc_probe(struct pcie_device *dev) | |||
147 | ctl = (ctl & 0xfff4) | PCI_EXP_DPC_CTL_EN_NONFATAL | PCI_EXP_DPC_CTL_INT_EN; | 314 | ctl = (ctl & 0xfff4) | PCI_EXP_DPC_CTL_EN_NONFATAL | PCI_EXP_DPC_CTL_INT_EN; |
148 | pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, ctl); | 315 | pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, ctl); |
149 | 316 | ||
150 | dev_info(&dev->device, "DPC error containment capabilities: Int Msg #%d, RPExt%c PoisonedTLP%c SwTrigger%c RP PIO Log %d, DL_ActiveErr%c\n", | 317 | dev_info(device, "DPC error containment capabilities: Int Msg #%d, RPExt%c PoisonedTLP%c SwTrigger%c RP PIO Log %d, DL_ActiveErr%c\n", |
151 | cap & 0xf, FLAG(cap, PCI_EXP_DPC_CAP_RP_EXT), | 318 | cap & 0xf, FLAG(cap, PCI_EXP_DPC_CAP_RP_EXT), |
152 | FLAG(cap, PCI_EXP_DPC_CAP_POISONED_TLP), | 319 | FLAG(cap, PCI_EXP_DPC_CAP_POISONED_TLP), |
153 | FLAG(cap, PCI_EXP_DPC_CAP_SW_TRIGGER), (cap >> 8) & 0xf, | 320 | FLAG(cap, PCI_EXP_DPC_CAP_SW_TRIGGER), (cap >> 8) & 0xf, |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 8aa3f14bc87d..be635f017756 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -21,7 +21,6 @@ | |||
21 | 21 | ||
22 | #include "../pci.h" | 22 | #include "../pci.h" |
23 | #include "portdrv.h" | 23 | #include "portdrv.h" |
24 | #include "aer/aerdrv.h" | ||
25 | 24 | ||
26 | /* If this switch is set, PCIe port native services should not be enabled. */ | 25 | /* If this switch is set, PCIe port native services should not be enabled. */ |
27 | bool pcie_ports_disabled; | 26 | bool pcie_ports_disabled; |
@@ -177,108 +176,20 @@ static void pcie_portdrv_remove(struct pci_dev *dev) | |||
177 | pcie_port_device_remove(dev); | 176 | pcie_port_device_remove(dev); |
178 | } | 177 | } |
179 | 178 | ||
180 | static int error_detected_iter(struct device *device, void *data) | ||
181 | { | ||
182 | struct pcie_device *pcie_device; | ||
183 | struct pcie_port_service_driver *driver; | ||
184 | struct aer_broadcast_data *result_data; | ||
185 | pci_ers_result_t status; | ||
186 | |||
187 | result_data = (struct aer_broadcast_data *) data; | ||
188 | |||
189 | if (device->bus == &pcie_port_bus_type && device->driver) { | ||
190 | driver = to_service_driver(device->driver); | ||
191 | if (!driver || | ||
192 | !driver->err_handler || | ||
193 | !driver->err_handler->error_detected) | ||
194 | return 0; | ||
195 | |||
196 | pcie_device = to_pcie_device(device); | ||
197 | |||
198 | /* Forward error detected message to service drivers */ | ||
199 | status = driver->err_handler->error_detected( | ||
200 | pcie_device->port, | ||
201 | result_data->state); | ||
202 | result_data->result = | ||
203 | merge_result(result_data->result, status); | ||
204 | } | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, | 179 | static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, |
210 | enum pci_channel_state error) | 180 | enum pci_channel_state error) |
211 | { | 181 | { |
212 | struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER}; | 182 | /* Root Port has no impact. Always recovers. */ |
213 | 183 | return PCI_ERS_RESULT_CAN_RECOVER; | |
214 | /* get true return value from &data */ | ||
215 | device_for_each_child(&dev->dev, &data, error_detected_iter); | ||
216 | return data.result; | ||
217 | } | ||
218 | |||
219 | static int mmio_enabled_iter(struct device *device, void *data) | ||
220 | { | ||
221 | struct pcie_device *pcie_device; | ||
222 | struct pcie_port_service_driver *driver; | ||
223 | pci_ers_result_t status, *result; | ||
224 | |||
225 | result = (pci_ers_result_t *) data; | ||
226 | |||
227 | if (device->bus == &pcie_port_bus_type && device->driver) { | ||
228 | driver = to_service_driver(device->driver); | ||
229 | if (driver && | ||
230 | driver->err_handler && | ||
231 | driver->err_handler->mmio_enabled) { | ||
232 | pcie_device = to_pcie_device(device); | ||
233 | |||
234 | /* Forward error message to service drivers */ | ||
235 | status = driver->err_handler->mmio_enabled( | ||
236 | pcie_device->port); | ||
237 | *result = merge_result(*result, status); | ||
238 | } | ||
239 | } | ||
240 | |||
241 | return 0; | ||
242 | } | 184 | } |
243 | 185 | ||
244 | static pci_ers_result_t pcie_portdrv_mmio_enabled(struct pci_dev *dev) | 186 | static pci_ers_result_t pcie_portdrv_mmio_enabled(struct pci_dev *dev) |
245 | { | 187 | { |
246 | pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; | 188 | return PCI_ERS_RESULT_RECOVERED; |
247 | |||
248 | /* get true return value from &status */ | ||
249 | device_for_each_child(&dev->dev, &status, mmio_enabled_iter); | ||
250 | return status; | ||
251 | } | ||
252 | |||
253 | static int slot_reset_iter(struct device *device, void *data) | ||
254 | { | ||
255 | struct pcie_device *pcie_device; | ||
256 | struct pcie_port_service_driver *driver; | ||
257 | pci_ers_result_t status, *result; | ||
258 | |||
259 | result = (pci_ers_result_t *) data; | ||
260 | |||
261 | if (device->bus == &pcie_port_bus_type && device->driver) { | ||
262 | driver = to_service_driver(device->driver); | ||
263 | if (driver && | ||
264 | driver->err_handler && | ||
265 | driver->err_handler->slot_reset) { | ||
266 | pcie_device = to_pcie_device(device); | ||
267 | |||
268 | /* Forward error message to service drivers */ | ||
269 | status = driver->err_handler->slot_reset( | ||
270 | pcie_device->port); | ||
271 | *result = merge_result(*result, status); | ||
272 | } | ||
273 | } | ||
274 | |||
275 | return 0; | ||
276 | } | 189 | } |
277 | 190 | ||
278 | static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) | 191 | static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) |
279 | { | 192 | { |
280 | pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; | ||
281 | |||
282 | /* If fatal, restore cfg space for possible link reset at upstream */ | 193 | /* If fatal, restore cfg space for possible link reset at upstream */ |
283 | if (dev->error_state == pci_channel_io_frozen) { | 194 | if (dev->error_state == pci_channel_io_frozen) { |
284 | dev->state_saved = true; | 195 | dev->state_saved = true; |
@@ -287,9 +198,7 @@ static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) | |||
287 | pci_enable_pcie_error_reporting(dev); | 198 | pci_enable_pcie_error_reporting(dev); |
288 | } | 199 | } |
289 | 200 | ||
290 | /* get true return value from &status */ | 201 | return PCI_ERS_RESULT_RECOVERED; |
291 | device_for_each_child(&dev->dev, &status, slot_reset_iter); | ||
292 | return status; | ||
293 | } | 202 | } |
294 | 203 | ||
295 | static int resume_iter(struct device *device, void *data) | 204 | static int resume_iter(struct device *device, void *data) |
@@ -299,13 +208,11 @@ static int resume_iter(struct device *device, void *data) | |||
299 | 208 | ||
300 | if (device->bus == &pcie_port_bus_type && device->driver) { | 209 | if (device->bus == &pcie_port_bus_type && device->driver) { |
301 | driver = to_service_driver(device->driver); | 210 | driver = to_service_driver(device->driver); |
302 | if (driver && | 211 | if (driver && driver->error_resume) { |
303 | driver->err_handler && | ||
304 | driver->err_handler->resume) { | ||
305 | pcie_device = to_pcie_device(device); | 212 | pcie_device = to_pcie_device(device); |
306 | 213 | ||
307 | /* Forward error message to service drivers */ | 214 | /* Forward error message to service drivers */ |
308 | driver->err_handler->resume(pcie_device->port); | 215 | driver->error_resume(pcie_device->port); |
309 | } | 216 | } |
310 | } | 217 | } |
311 | 218 | ||
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index e6a917b4acd3..ff94b69738a8 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1745,21 +1745,50 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) | |||
1745 | */ | 1745 | */ |
1746 | } | 1746 | } |
1747 | 1747 | ||
1748 | static void pci_configure_extended_tags(struct pci_dev *dev) | 1748 | int pci_configure_extended_tags(struct pci_dev *dev, void *ign) |
1749 | { | 1749 | { |
1750 | u32 dev_cap; | 1750 | struct pci_host_bridge *host; |
1751 | u32 cap; | ||
1752 | u16 ctl; | ||
1751 | int ret; | 1753 | int ret; |
1752 | 1754 | ||
1753 | if (!pci_is_pcie(dev)) | 1755 | if (!pci_is_pcie(dev)) |
1754 | return; | 1756 | return 0; |
1755 | 1757 | ||
1756 | ret = pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &dev_cap); | 1758 | ret = pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap); |
1757 | if (ret) | 1759 | if (ret) |
1758 | return; | 1760 | return 0; |
1761 | |||
1762 | if (!(cap & PCI_EXP_DEVCAP_EXT_TAG)) | ||
1763 | return 0; | ||
1764 | |||
1765 | ret = pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl); | ||
1766 | if (ret) | ||
1767 | return 0; | ||
1768 | |||
1769 | host = pci_find_host_bridge(dev->bus); | ||
1770 | if (!host) | ||
1771 | return 0; | ||
1759 | 1772 | ||
1760 | if (dev_cap & PCI_EXP_DEVCAP_EXT_TAG) | 1773 | /* |
1774 | * If some device in the hierarchy doesn't handle Extended Tags | ||
1775 | * correctly, make sure they're disabled. | ||
1776 | */ | ||
1777 | if (host->no_ext_tags) { | ||
1778 | if (ctl & PCI_EXP_DEVCTL_EXT_TAG) { | ||
1779 | dev_info(&dev->dev, "disabling Extended Tags\n"); | ||
1780 | pcie_capability_clear_word(dev, PCI_EXP_DEVCTL, | ||
1781 | PCI_EXP_DEVCTL_EXT_TAG); | ||
1782 | } | ||
1783 | return 0; | ||
1784 | } | ||
1785 | |||
1786 | if (!(ctl & PCI_EXP_DEVCTL_EXT_TAG)) { | ||
1787 | dev_info(&dev->dev, "enabling Extended Tags\n"); | ||
1761 | pcie_capability_set_word(dev, PCI_EXP_DEVCTL, | 1788 | pcie_capability_set_word(dev, PCI_EXP_DEVCTL, |
1762 | PCI_EXP_DEVCTL_EXT_TAG); | 1789 | PCI_EXP_DEVCTL_EXT_TAG); |
1790 | } | ||
1791 | return 0; | ||
1763 | } | 1792 | } |
1764 | 1793 | ||
1765 | /** | 1794 | /** |
@@ -1810,7 +1839,7 @@ static void pci_configure_device(struct pci_dev *dev) | |||
1810 | int ret; | 1839 | int ret; |
1811 | 1840 | ||
1812 | pci_configure_mps(dev); | 1841 | pci_configure_mps(dev); |
1813 | pci_configure_extended_tags(dev); | 1842 | pci_configure_extended_tags(dev, NULL); |
1814 | pci_configure_relaxed_ordering(dev); | 1843 | pci_configure_relaxed_ordering(dev); |
1815 | 1844 | ||
1816 | memset(&hpp, 0, sizeof(hpp)); | 1845 | memset(&hpp, 0, sizeof(hpp)); |
@@ -1867,42 +1896,69 @@ struct pci_dev *pci_alloc_dev(struct pci_bus *bus) | |||
1867 | } | 1896 | } |
1868 | EXPORT_SYMBOL(pci_alloc_dev); | 1897 | EXPORT_SYMBOL(pci_alloc_dev); |
1869 | 1898 | ||
1870 | bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l, | 1899 | static bool pci_bus_crs_vendor_id(u32 l) |
1871 | int crs_timeout) | 1900 | { |
1901 | return (l & 0xffff) == 0x0001; | ||
1902 | } | ||
1903 | |||
1904 | static bool pci_bus_wait_crs(struct pci_bus *bus, int devfn, u32 *l, | ||
1905 | int timeout) | ||
1872 | { | 1906 | { |
1873 | int delay = 1; | 1907 | int delay = 1; |
1874 | 1908 | ||
1875 | if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l)) | 1909 | if (!pci_bus_crs_vendor_id(*l)) |
1876 | return false; | 1910 | return true; /* not a CRS completion */ |
1877 | 1911 | ||
1878 | /* some broken boards return 0 or ~0 if a slot is empty: */ | 1912 | if (!timeout) |
1879 | if (*l == 0xffffffff || *l == 0x00000000 || | 1913 | return false; /* CRS, but caller doesn't want to wait */ |
1880 | *l == 0x0000ffff || *l == 0xffff0000) | ||
1881 | return false; | ||
1882 | 1914 | ||
1883 | /* | 1915 | /* |
1884 | * Configuration Request Retry Status. Some root ports return the | 1916 | * We got the reserved Vendor ID that indicates a completion with |
1885 | * actual device ID instead of the synthetic ID (0xFFFF) required | 1917 | * Configuration Request Retry Status (CRS). Retry until we get a |
1886 | * by the PCIe spec. Ignore the device ID and only check for | 1918 | * valid Vendor ID or we time out. |
1887 | * (vendor id == 1). | ||
1888 | */ | 1919 | */ |
1889 | while ((*l & 0xffff) == 0x0001) { | 1920 | while (pci_bus_crs_vendor_id(*l)) { |
1890 | if (!crs_timeout) | 1921 | if (delay > timeout) { |
1922 | pr_warn("pci %04x:%02x:%02x.%d: not ready after %dms; giving up\n", | ||
1923 | pci_domain_nr(bus), bus->number, | ||
1924 | PCI_SLOT(devfn), PCI_FUNC(devfn), delay - 1); | ||
1925 | |||
1891 | return false; | 1926 | return false; |
1927 | } | ||
1928 | if (delay >= 1000) | ||
1929 | pr_info("pci %04x:%02x:%02x.%d: not ready after %dms; waiting\n", | ||
1930 | pci_domain_nr(bus), bus->number, | ||
1931 | PCI_SLOT(devfn), PCI_FUNC(devfn), delay - 1); | ||
1892 | 1932 | ||
1893 | msleep(delay); | 1933 | msleep(delay); |
1894 | delay *= 2; | 1934 | delay *= 2; |
1935 | |||
1895 | if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l)) | 1936 | if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l)) |
1896 | return false; | 1937 | return false; |
1897 | /* Card hasn't responded in 60 seconds? Must be stuck. */ | ||
1898 | if (delay > crs_timeout) { | ||
1899 | printk(KERN_WARNING "pci %04x:%02x:%02x.%d: not responding\n", | ||
1900 | pci_domain_nr(bus), bus->number, PCI_SLOT(devfn), | ||
1901 | PCI_FUNC(devfn)); | ||
1902 | return false; | ||
1903 | } | ||
1904 | } | 1938 | } |
1905 | 1939 | ||
1940 | if (delay >= 1000) | ||
1941 | pr_info("pci %04x:%02x:%02x.%d: ready after %dms\n", | ||
1942 | pci_domain_nr(bus), bus->number, | ||
1943 | PCI_SLOT(devfn), PCI_FUNC(devfn), delay - 1); | ||
1944 | |||
1945 | return true; | ||
1946 | } | ||
1947 | |||
1948 | bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l, | ||
1949 | int timeout) | ||
1950 | { | ||
1951 | if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l)) | ||
1952 | return false; | ||
1953 | |||
1954 | /* some broken boards return 0 or ~0 if a slot is empty: */ | ||
1955 | if (*l == 0xffffffff || *l == 0x00000000 || | ||
1956 | *l == 0x0000ffff || *l == 0xffff0000) | ||
1957 | return false; | ||
1958 | |||
1959 | if (pci_bus_crs_vendor_id(*l)) | ||
1960 | return pci_bus_wait_crs(bus, devfn, l, timeout); | ||
1961 | |||
1906 | return true; | 1962 | return true; |
1907 | } | 1963 | } |
1908 | EXPORT_SYMBOL(pci_bus_read_dev_vendor_id); | 1964 | EXPORT_SYMBOL(pci_bus_read_dev_vendor_id); |
@@ -2331,6 +2387,15 @@ void pcie_bus_configure_settings(struct pci_bus *bus) | |||
2331 | } | 2387 | } |
2332 | EXPORT_SYMBOL_GPL(pcie_bus_configure_settings); | 2388 | EXPORT_SYMBOL_GPL(pcie_bus_configure_settings); |
2333 | 2389 | ||
2390 | /* | ||
2391 | * Called after each bus is probed, but before its children are examined. This | ||
2392 | * is marked as __weak because multiple architectures define it. | ||
2393 | */ | ||
2394 | void __weak pcibios_fixup_bus(struct pci_bus *bus) | ||
2395 | { | ||
2396 | /* nothing to do, expected to be removed in the future */ | ||
2397 | } | ||
2398 | |||
2334 | unsigned int pci_scan_child_bus(struct pci_bus *bus) | 2399 | unsigned int pci_scan_child_bus(struct pci_bus *bus) |
2335 | { | 2400 | { |
2336 | unsigned int devfn, pass, max = bus->busn_res.start; | 2401 | unsigned int devfn, pass, max = bus->busn_res.start; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index a346487a9532..a2afb44fad10 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -2062,7 +2062,7 @@ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, | |||
2062 | 2062 | ||
2063 | /* | 2063 | /* |
2064 | * The 82575 and 82598 may experience data corruption issues when transitioning | 2064 | * The 82575 and 82598 may experience data corruption issues when transitioning |
2065 | * out of L0S. To prevent this we need to disable L0S on the pci-e link | 2065 | * out of L0S. To prevent this we need to disable L0S on the PCIe link. |
2066 | */ | 2066 | */ |
2067 | static void quirk_disable_aspm_l0s(struct pci_dev *dev) | 2067 | static void quirk_disable_aspm_l0s(struct pci_dev *dev) |
2068 | { | 2068 | { |
@@ -4227,6 +4227,18 @@ static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags) | |||
4227 | return acs_flags ? 0 : 1; | 4227 | return acs_flags ? 0 : 1; |
4228 | } | 4228 | } |
4229 | 4229 | ||
4230 | static int pci_quirk_xgene_acs(struct pci_dev *dev, u16 acs_flags) | ||
4231 | { | ||
4232 | /* | ||
4233 | * X-Gene root matching this quirk do not allow peer-to-peer | ||
4234 | * transactions with others, allowing masking out these bits as if they | ||
4235 | * were unimplemented in the ACS capability. | ||
4236 | */ | ||
4237 | acs_flags &= ~(PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); | ||
4238 | |||
4239 | return acs_flags ? 0 : 1; | ||
4240 | } | ||
4241 | |||
4230 | /* | 4242 | /* |
4231 | * Many Intel PCH root ports do provide ACS-like features to disable peer | 4243 | * Many Intel PCH root ports do provide ACS-like features to disable peer |
4232 | * transactions and validate bus numbers in requests, but do not provide an | 4244 | * transactions and validate bus numbers in requests, but do not provide an |
@@ -4475,6 +4487,8 @@ static const struct pci_dev_acs_enabled { | |||
4475 | { 0x10df, 0x720, pci_quirk_mf_endpoint_acs }, /* Emulex Skyhawk-R */ | 4487 | { 0x10df, 0x720, pci_quirk_mf_endpoint_acs }, /* Emulex Skyhawk-R */ |
4476 | /* Cavium ThunderX */ | 4488 | /* Cavium ThunderX */ |
4477 | { PCI_VENDOR_ID_CAVIUM, PCI_ANY_ID, pci_quirk_cavium_acs }, | 4489 | { PCI_VENDOR_ID_CAVIUM, PCI_ANY_ID, pci_quirk_cavium_acs }, |
4490 | /* APM X-Gene */ | ||
4491 | { PCI_VENDOR_ID_AMCC, 0xE004, pci_quirk_xgene_acs }, | ||
4478 | { 0 } | 4492 | { 0 } |
4479 | }; | 4493 | }; |
4480 | 4494 | ||
@@ -4747,23 +4761,6 @@ static void quirk_intel_qat_vf_cap(struct pci_dev *pdev) | |||
4747 | } | 4761 | } |
4748 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap); | 4762 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap); |
4749 | 4763 | ||
4750 | /* | ||
4751 | * VMD-enabled root ports will change the source ID for all messages | ||
4752 | * to the VMD device. Rather than doing device matching with the source | ||
4753 | * ID, the AER driver should traverse the child device tree, reading | ||
4754 | * AER registers to find the faulting device. | ||
4755 | */ | ||
4756 | static void quirk_no_aersid(struct pci_dev *pdev) | ||
4757 | { | ||
4758 | /* VMD Domain */ | ||
4759 | if (pdev->bus->sysdata && pci_domain_nr(pdev->bus) >= 0x10000) | ||
4760 | pdev->bus->bus_flags |= PCI_BUS_FLAGS_NO_AERSID; | ||
4761 | } | ||
4762 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2030, quirk_no_aersid); | ||
4763 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2031, quirk_no_aersid); | ||
4764 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2032, quirk_no_aersid); | ||
4765 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2033, quirk_no_aersid); | ||
4766 | |||
4767 | /* FLR may cause some 82579 devices to hang. */ | 4764 | /* FLR may cause some 82579 devices to hang. */ |
4768 | static void quirk_intel_no_flr(struct pci_dev *dev) | 4765 | static void quirk_intel_no_flr(struct pci_dev *dev) |
4769 | { | 4766 | { |
@@ -4771,3 +4768,34 @@ static void quirk_intel_no_flr(struct pci_dev *dev) | |||
4771 | } | 4768 | } |
4772 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1502, quirk_intel_no_flr); | 4769 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1502, quirk_intel_no_flr); |
4773 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1503, quirk_intel_no_flr); | 4770 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1503, quirk_intel_no_flr); |
4771 | |||
4772 | static void quirk_no_ext_tags(struct pci_dev *pdev) | ||
4773 | { | ||
4774 | struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus); | ||
4775 | |||
4776 | if (!bridge) | ||
4777 | return; | ||
4778 | |||
4779 | bridge->no_ext_tags = 1; | ||
4780 | dev_info(&pdev->dev, "disabling Extended Tags (this device can't handle them)\n"); | ||
4781 | |||
4782 | pci_walk_bus(bridge->bus, pci_configure_extended_tags, NULL); | ||
4783 | } | ||
4784 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0140, quirk_no_ext_tags); | ||
4785 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0142, quirk_no_ext_tags); | ||
4786 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0144, quirk_no_ext_tags); | ||
4787 | |||
4788 | #ifdef CONFIG_PCI_ATS | ||
4789 | /* | ||
4790 | * Some devices have a broken ATS implementation causing IOMMU stalls. | ||
4791 | * Don't use ATS for those devices. | ||
4792 | */ | ||
4793 | static void quirk_no_ats(struct pci_dev *pdev) | ||
4794 | { | ||
4795 | dev_info(&pdev->dev, "disabling ATS (broken on this device)\n"); | ||
4796 | pdev->ats_cap = 0; | ||
4797 | } | ||
4798 | |||
4799 | /* AMD Stoney platform GPU */ | ||
4800 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x98e4, quirk_no_ats); | ||
4801 | #endif /* CONFIG_PCI_ATS */ | ||
diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c index 81eda3d93a5d..86106c44ce94 100644 --- a/drivers/pci/setup-irq.c +++ b/drivers/pci/setup-irq.c | |||
@@ -17,12 +17,6 @@ | |||
17 | #include <linux/cache.h> | 17 | #include <linux/cache.h> |
18 | #include "pci.h" | 18 | #include "pci.h" |
19 | 19 | ||
20 | void __weak pcibios_update_irq(struct pci_dev *dev, int irq) | ||
21 | { | ||
22 | dev_dbg(&dev->dev, "assigning IRQ %02d\n", irq); | ||
23 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | ||
24 | } | ||
25 | |||
26 | void pci_assign_irq(struct pci_dev *dev) | 20 | void pci_assign_irq(struct pci_dev *dev) |
27 | { | 21 | { |
28 | u8 pin; | 22 | u8 pin; |
@@ -65,29 +59,5 @@ void pci_assign_irq(struct pci_dev *dev) | |||
65 | 59 | ||
66 | /* Always tell the device, so the driver knows what is | 60 | /* Always tell the device, so the driver knows what is |
67 | the real IRQ to use; the device does not use it. */ | 61 | the real IRQ to use; the device does not use it. */ |
68 | pcibios_update_irq(dev, irq); | 62 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); |
69 | } | ||
70 | |||
71 | void pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *), | ||
72 | int (*map_irq)(const struct pci_dev *, u8, u8)) | ||
73 | { | ||
74 | /* | ||
75 | * Implement pci_fixup_irqs() through pci_assign_irq(). | ||
76 | * This code should be remove eventually, it is a wrapper | ||
77 | * around pci_assign_irq() interface to keep current | ||
78 | * pci_fixup_irqs() behaviour unchanged on architecture | ||
79 | * code still relying on its interface. | ||
80 | */ | ||
81 | struct pci_dev *dev = NULL; | ||
82 | struct pci_host_bridge *hbrg = NULL; | ||
83 | |||
84 | for_each_pci_dev(dev) { | ||
85 | hbrg = pci_find_host_bridge(dev->bus); | ||
86 | hbrg->swizzle_irq = swizzle; | ||
87 | hbrg->map_irq = map_irq; | ||
88 | pci_assign_irq(dev); | ||
89 | hbrg->swizzle_irq = NULL; | ||
90 | hbrg->map_irq = NULL; | ||
91 | } | ||
92 | } | 63 | } |
93 | EXPORT_SYMBOL_GPL(pci_fixup_irqs); | ||
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 85774b7a316a..e576e1a8d978 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -234,6 +234,19 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, | |||
234 | return 0; | 234 | return 0; |
235 | } | 235 | } |
236 | 236 | ||
237 | /* | ||
238 | * We don't have to worry about legacy ISA devices, so nothing to do here. | ||
239 | * This is marked as __weak because multiple architectures define it; it should | ||
240 | * eventually go away. | ||
241 | */ | ||
242 | resource_size_t __weak pcibios_align_resource(void *data, | ||
243 | const struct resource *res, | ||
244 | resource_size_t size, | ||
245 | resource_size_t align) | ||
246 | { | ||
247 | return res->start; | ||
248 | } | ||
249 | |||
237 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, | 250 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, |
238 | int resno, resource_size_t size, resource_size_t align) | 251 | int resno, resource_size_t size, resource_size_t align) |
239 | { | 252 | { |
diff --git a/drivers/phy/rockchip/phy-rockchip-pcie.c b/drivers/phy/rockchip/phy-rockchip-pcie.c index 6904633cad68..7cbdde029c0a 100644 --- a/drivers/phy/rockchip/phy-rockchip-pcie.c +++ b/drivers/phy/rockchip/phy-rockchip-pcie.c | |||
@@ -73,10 +73,38 @@ struct rockchip_pcie_data { | |||
73 | struct rockchip_pcie_phy { | 73 | struct rockchip_pcie_phy { |
74 | struct rockchip_pcie_data *phy_data; | 74 | struct rockchip_pcie_data *phy_data; |
75 | struct regmap *reg_base; | 75 | struct regmap *reg_base; |
76 | struct phy_pcie_instance { | ||
77 | struct phy *phy; | ||
78 | u32 index; | ||
79 | } phys[PHY_MAX_LANE_NUM]; | ||
80 | struct mutex pcie_mutex; | ||
76 | struct reset_control *phy_rst; | 81 | struct reset_control *phy_rst; |
77 | struct clk *clk_pciephy_ref; | 82 | struct clk *clk_pciephy_ref; |
83 | int pwr_cnt; | ||
84 | int init_cnt; | ||
78 | }; | 85 | }; |
79 | 86 | ||
87 | static struct rockchip_pcie_phy *to_pcie_phy(struct phy_pcie_instance *inst) | ||
88 | { | ||
89 | return container_of(inst, struct rockchip_pcie_phy, | ||
90 | phys[inst->index]); | ||
91 | } | ||
92 | |||
93 | static struct phy *rockchip_pcie_phy_of_xlate(struct device *dev, | ||
94 | struct of_phandle_args *args) | ||
95 | { | ||
96 | struct rockchip_pcie_phy *rk_phy = dev_get_drvdata(dev); | ||
97 | |||
98 | if (args->args_count == 0) | ||
99 | return rk_phy->phys[0].phy; | ||
100 | |||
101 | if (WARN_ON(args->args[0] >= PHY_MAX_LANE_NUM)) | ||
102 | return ERR_PTR(-ENODEV); | ||
103 | |||
104 | return rk_phy->phys[args->args[0]].phy; | ||
105 | } | ||
106 | |||
107 | |||
80 | static inline void phy_wr_cfg(struct rockchip_pcie_phy *rk_phy, | 108 | static inline void phy_wr_cfg(struct rockchip_pcie_phy *rk_phy, |
81 | u32 addr, u32 data) | 109 | u32 addr, u32 data) |
82 | { | 110 | { |
@@ -116,29 +144,59 @@ static inline u32 phy_rd_cfg(struct rockchip_pcie_phy *rk_phy, | |||
116 | 144 | ||
117 | static int rockchip_pcie_phy_power_off(struct phy *phy) | 145 | static int rockchip_pcie_phy_power_off(struct phy *phy) |
118 | { | 146 | { |
119 | struct rockchip_pcie_phy *rk_phy = phy_get_drvdata(phy); | 147 | struct phy_pcie_instance *inst = phy_get_drvdata(phy); |
148 | struct rockchip_pcie_phy *rk_phy = to_pcie_phy(inst); | ||
120 | int err = 0; | 149 | int err = 0; |
121 | 150 | ||
151 | mutex_lock(&rk_phy->pcie_mutex); | ||
152 | |||
153 | regmap_write(rk_phy->reg_base, | ||
154 | rk_phy->phy_data->pcie_laneoff, | ||
155 | HIWORD_UPDATE(PHY_LANE_IDLE_OFF, | ||
156 | PHY_LANE_IDLE_MASK, | ||
157 | PHY_LANE_IDLE_A_SHIFT + inst->index)); | ||
158 | |||
159 | if (--rk_phy->pwr_cnt) | ||
160 | goto err_out; | ||
161 | |||
122 | err = reset_control_assert(rk_phy->phy_rst); | 162 | err = reset_control_assert(rk_phy->phy_rst); |
123 | if (err) { | 163 | if (err) { |
124 | dev_err(&phy->dev, "assert phy_rst err %d\n", err); | 164 | dev_err(&phy->dev, "assert phy_rst err %d\n", err); |
125 | return err; | 165 | goto err_restore; |
126 | } | 166 | } |
127 | 167 | ||
168 | err_out: | ||
169 | mutex_unlock(&rk_phy->pcie_mutex); | ||
128 | return 0; | 170 | return 0; |
171 | |||
172 | err_restore: | ||
173 | rk_phy->pwr_cnt++; | ||
174 | regmap_write(rk_phy->reg_base, | ||
175 | rk_phy->phy_data->pcie_laneoff, | ||
176 | HIWORD_UPDATE(!PHY_LANE_IDLE_OFF, | ||
177 | PHY_LANE_IDLE_MASK, | ||
178 | PHY_LANE_IDLE_A_SHIFT + inst->index)); | ||
179 | mutex_unlock(&rk_phy->pcie_mutex); | ||
180 | return err; | ||
129 | } | 181 | } |
130 | 182 | ||
131 | static int rockchip_pcie_phy_power_on(struct phy *phy) | 183 | static int rockchip_pcie_phy_power_on(struct phy *phy) |
132 | { | 184 | { |
133 | struct rockchip_pcie_phy *rk_phy = phy_get_drvdata(phy); | 185 | struct phy_pcie_instance *inst = phy_get_drvdata(phy); |
186 | struct rockchip_pcie_phy *rk_phy = to_pcie_phy(inst); | ||
134 | int err = 0; | 187 | int err = 0; |
135 | u32 status; | 188 | u32 status; |
136 | unsigned long timeout; | 189 | unsigned long timeout; |
137 | 190 | ||
191 | mutex_lock(&rk_phy->pcie_mutex); | ||
192 | |||
193 | if (rk_phy->pwr_cnt++) | ||
194 | goto err_out; | ||
195 | |||
138 | err = reset_control_deassert(rk_phy->phy_rst); | 196 | err = reset_control_deassert(rk_phy->phy_rst); |
139 | if (err) { | 197 | if (err) { |
140 | dev_err(&phy->dev, "deassert phy_rst err %d\n", err); | 198 | dev_err(&phy->dev, "deassert phy_rst err %d\n", err); |
141 | return err; | 199 | goto err_pwr_cnt; |
142 | } | 200 | } |
143 | 201 | ||
144 | regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf, | 202 | regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf, |
@@ -146,6 +204,12 @@ static int rockchip_pcie_phy_power_on(struct phy *phy) | |||
146 | PHY_CFG_ADDR_MASK, | 204 | PHY_CFG_ADDR_MASK, |
147 | PHY_CFG_ADDR_SHIFT)); | 205 | PHY_CFG_ADDR_SHIFT)); |
148 | 206 | ||
207 | regmap_write(rk_phy->reg_base, | ||
208 | rk_phy->phy_data->pcie_laneoff, | ||
209 | HIWORD_UPDATE(!PHY_LANE_IDLE_OFF, | ||
210 | PHY_LANE_IDLE_MASK, | ||
211 | PHY_LANE_IDLE_A_SHIFT + inst->index)); | ||
212 | |||
149 | /* | 213 | /* |
150 | * No documented timeout value for phy operation below, | 214 | * No documented timeout value for phy operation below, |
151 | * so we make it large enough here. And we use loop-break | 215 | * so we make it large enough here. And we use loop-break |
@@ -214,18 +278,29 @@ static int rockchip_pcie_phy_power_on(struct phy *phy) | |||
214 | goto err_pll_lock; | 278 | goto err_pll_lock; |
215 | } | 279 | } |
216 | 280 | ||
281 | err_out: | ||
282 | mutex_unlock(&rk_phy->pcie_mutex); | ||
217 | return 0; | 283 | return 0; |
218 | 284 | ||
219 | err_pll_lock: | 285 | err_pll_lock: |
220 | reset_control_assert(rk_phy->phy_rst); | 286 | reset_control_assert(rk_phy->phy_rst); |
287 | err_pwr_cnt: | ||
288 | rk_phy->pwr_cnt--; | ||
289 | mutex_unlock(&rk_phy->pcie_mutex); | ||
221 | return err; | 290 | return err; |
222 | } | 291 | } |
223 | 292 | ||
224 | static int rockchip_pcie_phy_init(struct phy *phy) | 293 | static int rockchip_pcie_phy_init(struct phy *phy) |
225 | { | 294 | { |
226 | struct rockchip_pcie_phy *rk_phy = phy_get_drvdata(phy); | 295 | struct phy_pcie_instance *inst = phy_get_drvdata(phy); |
296 | struct rockchip_pcie_phy *rk_phy = to_pcie_phy(inst); | ||
227 | int err = 0; | 297 | int err = 0; |
228 | 298 | ||
299 | mutex_lock(&rk_phy->pcie_mutex); | ||
300 | |||
301 | if (rk_phy->init_cnt++) | ||
302 | goto err_out; | ||
303 | |||
229 | err = clk_prepare_enable(rk_phy->clk_pciephy_ref); | 304 | err = clk_prepare_enable(rk_phy->clk_pciephy_ref); |
230 | if (err) { | 305 | if (err) { |
231 | dev_err(&phy->dev, "Fail to enable pcie ref clock.\n"); | 306 | dev_err(&phy->dev, "Fail to enable pcie ref clock.\n"); |
@@ -238,20 +313,33 @@ static int rockchip_pcie_phy_init(struct phy *phy) | |||
238 | goto err_reset; | 313 | goto err_reset; |
239 | } | 314 | } |
240 | 315 | ||
241 | return err; | 316 | err_out: |
317 | mutex_unlock(&rk_phy->pcie_mutex); | ||
318 | return 0; | ||
242 | 319 | ||
243 | err_reset: | 320 | err_reset: |
321 | |||
244 | clk_disable_unprepare(rk_phy->clk_pciephy_ref); | 322 | clk_disable_unprepare(rk_phy->clk_pciephy_ref); |
245 | err_refclk: | 323 | err_refclk: |
324 | rk_phy->init_cnt--; | ||
325 | mutex_unlock(&rk_phy->pcie_mutex); | ||
246 | return err; | 326 | return err; |
247 | } | 327 | } |
248 | 328 | ||
249 | static int rockchip_pcie_phy_exit(struct phy *phy) | 329 | static int rockchip_pcie_phy_exit(struct phy *phy) |
250 | { | 330 | { |
251 | struct rockchip_pcie_phy *rk_phy = phy_get_drvdata(phy); | 331 | struct phy_pcie_instance *inst = phy_get_drvdata(phy); |
332 | struct rockchip_pcie_phy *rk_phy = to_pcie_phy(inst); | ||
333 | |||
334 | mutex_lock(&rk_phy->pcie_mutex); | ||
335 | |||
336 | if (--rk_phy->init_cnt) | ||
337 | goto err_init_cnt; | ||
252 | 338 | ||
253 | clk_disable_unprepare(rk_phy->clk_pciephy_ref); | 339 | clk_disable_unprepare(rk_phy->clk_pciephy_ref); |
254 | 340 | ||
341 | err_init_cnt: | ||
342 | mutex_unlock(&rk_phy->pcie_mutex); | ||
255 | return 0; | 343 | return 0; |
256 | } | 344 | } |
257 | 345 | ||
@@ -283,10 +371,11 @@ static int rockchip_pcie_phy_probe(struct platform_device *pdev) | |||
283 | { | 371 | { |
284 | struct device *dev = &pdev->dev; | 372 | struct device *dev = &pdev->dev; |
285 | struct rockchip_pcie_phy *rk_phy; | 373 | struct rockchip_pcie_phy *rk_phy; |
286 | struct phy *generic_phy; | ||
287 | struct phy_provider *phy_provider; | 374 | struct phy_provider *phy_provider; |
288 | struct regmap *grf; | 375 | struct regmap *grf; |
289 | const struct of_device_id *of_id; | 376 | const struct of_device_id *of_id; |
377 | int i; | ||
378 | u32 phy_num; | ||
290 | 379 | ||
291 | grf = syscon_node_to_regmap(dev->parent->of_node); | 380 | grf = syscon_node_to_regmap(dev->parent->of_node); |
292 | if (IS_ERR(grf)) { | 381 | if (IS_ERR(grf)) { |
@@ -305,6 +394,8 @@ static int rockchip_pcie_phy_probe(struct platform_device *pdev) | |||
305 | rk_phy->phy_data = (struct rockchip_pcie_data *)of_id->data; | 394 | rk_phy->phy_data = (struct rockchip_pcie_data *)of_id->data; |
306 | rk_phy->reg_base = grf; | 395 | rk_phy->reg_base = grf; |
307 | 396 | ||
397 | mutex_init(&rk_phy->pcie_mutex); | ||
398 | |||
308 | rk_phy->phy_rst = devm_reset_control_get(dev, "phy"); | 399 | rk_phy->phy_rst = devm_reset_control_get(dev, "phy"); |
309 | if (IS_ERR(rk_phy->phy_rst)) { | 400 | if (IS_ERR(rk_phy->phy_rst)) { |
310 | if (PTR_ERR(rk_phy->phy_rst) != -EPROBE_DEFER) | 401 | if (PTR_ERR(rk_phy->phy_rst) != -EPROBE_DEFER) |
@@ -319,14 +410,26 @@ static int rockchip_pcie_phy_probe(struct platform_device *pdev) | |||
319 | return PTR_ERR(rk_phy->clk_pciephy_ref); | 410 | return PTR_ERR(rk_phy->clk_pciephy_ref); |
320 | } | 411 | } |
321 | 412 | ||
322 | generic_phy = devm_phy_create(dev, dev->of_node, &ops); | 413 | /* parse #phy-cells to see if it's legacy PHY model */ |
323 | if (IS_ERR(generic_phy)) { | 414 | if (of_property_read_u32(dev->of_node, "#phy-cells", &phy_num)) |
324 | dev_err(dev, "failed to create PHY\n"); | 415 | return -ENOENT; |
325 | return PTR_ERR(generic_phy); | 416 | |
417 | phy_num = (phy_num == 0) ? 1 : PHY_MAX_LANE_NUM; | ||
418 | dev_dbg(dev, "phy number is %d\n", phy_num); | ||
419 | |||
420 | for (i = 0; i < phy_num; i++) { | ||
421 | rk_phy->phys[i].phy = devm_phy_create(dev, dev->of_node, &ops); | ||
422 | if (IS_ERR(rk_phy->phys[i].phy)) { | ||
423 | dev_err(dev, "failed to create PHY%d\n", i); | ||
424 | return PTR_ERR(rk_phy->phys[i].phy); | ||
425 | } | ||
426 | rk_phy->phys[i].index = i; | ||
427 | phy_set_drvdata(rk_phy->phys[i].phy, &rk_phy->phys[i]); | ||
326 | } | 428 | } |
327 | 429 | ||
328 | phy_set_drvdata(generic_phy, rk_phy); | 430 | platform_set_drvdata(pdev, rk_phy); |
329 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | 431 | phy_provider = devm_of_phy_provider_register(dev, |
432 | rockchip_pcie_phy_of_xlate); | ||
330 | 433 | ||
331 | return PTR_ERR_OR_ZERO(phy_provider); | 434 | return PTR_ERR_OR_ZERO(phy_provider); |
332 | } | 435 | } |
diff --git a/include/linux/aer.h b/include/linux/aer.h index 04602cbe85dc..43799bd17a02 100644 --- a/include/linux/aer.h +++ b/include/linux/aer.h | |||
@@ -39,7 +39,7 @@ struct aer_capability_regs { | |||
39 | }; | 39 | }; |
40 | 40 | ||
41 | #if defined(CONFIG_PCIEAER) | 41 | #if defined(CONFIG_PCIEAER) |
42 | /* pci-e port driver needs this function to enable aer */ | 42 | /* PCIe port driver needs this function to enable AER */ |
43 | int pci_enable_pcie_error_reporting(struct pci_dev *dev); | 43 | int pci_enable_pcie_error_reporting(struct pci_dev *dev); |
44 | int pci_disable_pcie_error_reporting(struct pci_dev *dev); | 44 | int pci_disable_pcie_error_reporting(struct pci_dev *dev); |
45 | int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev); | 45 | int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev); |
@@ -67,7 +67,6 @@ void cper_print_aer(struct pci_dev *dev, int aer_severity, | |||
67 | struct aer_capability_regs *aer); | 67 | struct aer_capability_regs *aer); |
68 | int cper_severity_to_aer(int cper_severity); | 68 | int cper_severity_to_aer(int cper_severity); |
69 | void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, | 69 | void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, |
70 | int severity, | 70 | int severity, struct aer_capability_regs *aer_regs); |
71 | struct aer_capability_regs *aer_regs); | ||
72 | #endif //_AER_H_ | 71 | #endif //_AER_H_ |
73 | 72 | ||
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h index af5edbf3eea3..f7a04e1af112 100644 --- a/include/linux/pci-epc.h +++ b/include/linux/pci-epc.h | |||
@@ -62,11 +62,13 @@ struct pci_epc_ops { | |||
62 | * @size: the size of the PCI address space | 62 | * @size: the size of the PCI address space |
63 | * @bitmap: bitmap to manage the PCI address space | 63 | * @bitmap: bitmap to manage the PCI address space |
64 | * @pages: number of bits representing the address region | 64 | * @pages: number of bits representing the address region |
65 | * @page_size: size of each page | ||
65 | */ | 66 | */ |
66 | struct pci_epc_mem { | 67 | struct pci_epc_mem { |
67 | phys_addr_t phys_base; | 68 | phys_addr_t phys_base; |
68 | size_t size; | 69 | size_t size; |
69 | unsigned long *bitmap; | 70 | unsigned long *bitmap; |
71 | size_t page_size; | ||
70 | int pages; | 72 | int pages; |
71 | }; | 73 | }; |
72 | 74 | ||
@@ -98,6 +100,9 @@ struct pci_epc { | |||
98 | #define devm_pci_epc_create(dev, ops) \ | 100 | #define devm_pci_epc_create(dev, ops) \ |
99 | __devm_pci_epc_create((dev), (ops), THIS_MODULE) | 101 | __devm_pci_epc_create((dev), (ops), THIS_MODULE) |
100 | 102 | ||
103 | #define pci_epc_mem_init(epc, phys_addr, size) \ | ||
104 | __pci_epc_mem_init((epc), (phys_addr), (size), PAGE_SIZE) | ||
105 | |||
101 | static inline void epc_set_drvdata(struct pci_epc *epc, void *data) | 106 | static inline void epc_set_drvdata(struct pci_epc *epc, void *data) |
102 | { | 107 | { |
103 | dev_set_drvdata(&epc->dev, data); | 108 | dev_set_drvdata(&epc->dev, data); |
@@ -135,7 +140,8 @@ void pci_epc_stop(struct pci_epc *epc); | |||
135 | struct pci_epc *pci_epc_get(const char *epc_name); | 140 | struct pci_epc *pci_epc_get(const char *epc_name); |
136 | void pci_epc_put(struct pci_epc *epc); | 141 | void pci_epc_put(struct pci_epc *epc); |
137 | 142 | ||
138 | int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_addr, size_t size); | 143 | int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_addr, size_t size, |
144 | size_t page_size); | ||
139 | void pci_epc_mem_exit(struct pci_epc *epc); | 145 | void pci_epc_mem_exit(struct pci_epc *epc); |
140 | void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc, | 146 | void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc, |
141 | phys_addr_t *phys_addr, size_t size); | 147 | phys_addr_t *phys_addr, size_t size); |
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h index 0d529cb90143..60d551a9a1ba 100644 --- a/include/linux/pci-epf.h +++ b/include/linux/pci-epf.h | |||
@@ -14,17 +14,10 @@ | |||
14 | 14 | ||
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <linux/mod_devicetable.h> | 16 | #include <linux/mod_devicetable.h> |
17 | #include <linux/pci.h> | ||
17 | 18 | ||
18 | struct pci_epf; | 19 | struct pci_epf; |
19 | 20 | ||
20 | enum pci_interrupt_pin { | ||
21 | PCI_INTERRUPT_UNKNOWN, | ||
22 | PCI_INTERRUPT_INTA, | ||
23 | PCI_INTERRUPT_INTB, | ||
24 | PCI_INTERRUPT_INTC, | ||
25 | PCI_INTERRUPT_INTD, | ||
26 | }; | ||
27 | |||
28 | enum pci_barno { | 21 | enum pci_barno { |
29 | BAR_0, | 22 | BAR_0, |
30 | BAR_1, | 23 | BAR_1, |
@@ -149,6 +142,8 @@ static inline void *epf_get_drvdata(struct pci_epf *epf) | |||
149 | return dev_get_drvdata(&epf->dev); | 142 | return dev_get_drvdata(&epf->dev); |
150 | } | 143 | } |
151 | 144 | ||
145 | const struct pci_epf_device_id * | ||
146 | pci_epf_match_device(const struct pci_epf_device_id *id, struct pci_epf *epf); | ||
152 | struct pci_epf *pci_epf_create(const char *name); | 147 | struct pci_epf *pci_epf_create(const char *name); |
153 | void pci_epf_destroy(struct pci_epf *epf); | 148 | void pci_epf_destroy(struct pci_epf *epf); |
154 | int __pci_epf_register_driver(struct pci_epf_driver *driver, | 149 | int __pci_epf_register_driver(struct pci_epf_driver *driver, |
diff --git a/include/linux/pci.h b/include/linux/pci.h index da05e5db06ac..f68c58a93dd0 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -102,6 +102,28 @@ enum { | |||
102 | DEVICE_COUNT_RESOURCE = PCI_NUM_RESOURCES, | 102 | DEVICE_COUNT_RESOURCE = PCI_NUM_RESOURCES, |
103 | }; | 103 | }; |
104 | 104 | ||
105 | /** | ||
106 | * enum pci_interrupt_pin - PCI INTx interrupt values | ||
107 | * @PCI_INTERRUPT_UNKNOWN: Unknown or unassigned interrupt | ||
108 | * @PCI_INTERRUPT_INTA: PCI INTA pin | ||
109 | * @PCI_INTERRUPT_INTB: PCI INTB pin | ||
110 | * @PCI_INTERRUPT_INTC: PCI INTC pin | ||
111 | * @PCI_INTERRUPT_INTD: PCI INTD pin | ||
112 | * | ||
113 | * Corresponds to values for legacy PCI INTx interrupts, as can be found in the | ||
114 | * PCI_INTERRUPT_PIN register. | ||
115 | */ | ||
116 | enum pci_interrupt_pin { | ||
117 | PCI_INTERRUPT_UNKNOWN, | ||
118 | PCI_INTERRUPT_INTA, | ||
119 | PCI_INTERRUPT_INTB, | ||
120 | PCI_INTERRUPT_INTC, | ||
121 | PCI_INTERRUPT_INTD, | ||
122 | }; | ||
123 | |||
124 | /* The number of legacy PCI INTx interrupts */ | ||
125 | #define PCI_NUM_INTX 4 | ||
126 | |||
105 | /* | 127 | /* |
106 | * pci_power_t values must match the bits in the Capabilities PME_Support | 128 | * pci_power_t values must match the bits in the Capabilities PME_Support |
107 | * and Control/Status PowerState fields in the Power Management capability. | 129 | * and Control/Status PowerState fields in the Power Management capability. |
@@ -453,6 +475,7 @@ struct pci_host_bridge { | |||
453 | void *release_data; | 475 | void *release_data; |
454 | struct msi_controller *msi; | 476 | struct msi_controller *msi; |
455 | unsigned int ignore_reset_delay:1; /* for entire hierarchy */ | 477 | unsigned int ignore_reset_delay:1; /* for entire hierarchy */ |
478 | unsigned int no_ext_tags:1; /* no Extended Tags */ | ||
456 | /* Resource alignment requirements */ | 479 | /* Resource alignment requirements */ |
457 | resource_size_t (*align_resource)(struct pci_dev *dev, | 480 | resource_size_t (*align_resource)(struct pci_dev *dev, |
458 | const struct resource *res, | 481 | const struct resource *res, |
@@ -847,7 +870,6 @@ char *pcibios_setup(char *str); | |||
847 | resource_size_t pcibios_align_resource(void *, const struct resource *, | 870 | resource_size_t pcibios_align_resource(void *, const struct resource *, |
848 | resource_size_t, | 871 | resource_size_t, |
849 | resource_size_t); | 872 | resource_size_t); |
850 | void pcibios_update_irq(struct pci_dev *, int irq); | ||
851 | 873 | ||
852 | /* Weak but can be overriden by arch */ | 874 | /* Weak but can be overriden by arch */ |
853 | void pci_fixup_cardbus(struct pci_bus *); | 875 | void pci_fixup_cardbus(struct pci_bus *); |
@@ -1165,8 +1187,6 @@ void pci_assign_unassigned_bus_resources(struct pci_bus *bus); | |||
1165 | void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus); | 1187 | void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus); |
1166 | void pdev_enable_device(struct pci_dev *); | 1188 | void pdev_enable_device(struct pci_dev *); |
1167 | int pci_enable_resources(struct pci_dev *, int mask); | 1189 | int pci_enable_resources(struct pci_dev *, int mask); |
1168 | void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *), | ||
1169 | int (*)(const struct pci_dev *, u8, u8)); | ||
1170 | void pci_assign_irq(struct pci_dev *dev); | 1190 | void pci_assign_irq(struct pci_dev *dev); |
1171 | struct resource *pci_find_resource(struct pci_dev *dev, struct resource *res); | 1191 | struct resource *pci_find_resource(struct pci_dev *dev, struct resource *res); |
1172 | #define HAVE_PCI_REQ_REGIONS 2 | 1192 | #define HAVE_PCI_REQ_REGIONS 2 |
@@ -1399,6 +1419,38 @@ pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, | |||
1399 | NULL); | 1419 | NULL); |
1400 | } | 1420 | } |
1401 | 1421 | ||
1422 | /** | ||
1423 | * pci_irqd_intx_xlate() - Translate PCI INTx value to an IRQ domain hwirq | ||
1424 | * @d: the INTx IRQ domain | ||
1425 | * @node: the DT node for the device whose interrupt we're translating | ||
1426 | * @intspec: the interrupt specifier data from the DT | ||
1427 | * @intsize: the number of entries in @intspec | ||
1428 | * @out_hwirq: pointer at which to write the hwirq number | ||
1429 | * @out_type: pointer at which to write the interrupt type | ||
1430 | * | ||
1431 | * Translate a PCI INTx interrupt number from device tree in the range 1-4, as | ||
1432 | * stored in the standard PCI_INTERRUPT_PIN register, to a value in the range | ||
1433 | * 0-3 suitable for use in a 4 entry IRQ domain. That is, subtract one from the | ||
1434 | * INTx value to obtain the hwirq number. | ||
1435 | * | ||
1436 | * Returns 0 on success, or -EINVAL if the interrupt specifier is out of range. | ||
1437 | */ | ||
1438 | static inline int pci_irqd_intx_xlate(struct irq_domain *d, | ||
1439 | struct device_node *node, | ||
1440 | const u32 *intspec, | ||
1441 | unsigned int intsize, | ||
1442 | unsigned long *out_hwirq, | ||
1443 | unsigned int *out_type) | ||
1444 | { | ||
1445 | const u32 intx = intspec[0]; | ||
1446 | |||
1447 | if (intx < PCI_INTERRUPT_INTA || intx > PCI_INTERRUPT_INTD) | ||
1448 | return -EINVAL; | ||
1449 | |||
1450 | *out_hwirq = intx - PCI_INTERRUPT_INTA; | ||
1451 | return 0; | ||
1452 | } | ||
1453 | |||
1402 | #ifdef CONFIG_PCIEPORTBUS | 1454 | #ifdef CONFIG_PCIEPORTBUS |
1403 | extern bool pcie_ports_disabled; | 1455 | extern bool pcie_ports_disabled; |
1404 | extern bool pcie_ports_auto; | 1456 | extern bool pcie_ports_auto; |
@@ -2064,7 +2116,7 @@ static inline u16 pci_vpd_lrdt_tag(const u8 *lrdt) | |||
2064 | 2116 | ||
2065 | /** | 2117 | /** |
2066 | * pci_vpd_srdt_size - Extracts the Small Resource Data Type length | 2118 | * pci_vpd_srdt_size - Extracts the Small Resource Data Type length |
2067 | * @lrdt: Pointer to the beginning of the Small Resource Data Type tag | 2119 | * @srdt: Pointer to the beginning of the Small Resource Data Type tag |
2068 | * | 2120 | * |
2069 | * Returns the extracted Small Resource Data Type length. | 2121 | * Returns the extracted Small Resource Data Type length. |
2070 | */ | 2122 | */ |
@@ -2075,7 +2127,7 @@ static inline u8 pci_vpd_srdt_size(const u8 *srdt) | |||
2075 | 2127 | ||
2076 | /** | 2128 | /** |
2077 | * pci_vpd_srdt_tag - Extracts the Small Resource Data Type Tag Item | 2129 | * pci_vpd_srdt_tag - Extracts the Small Resource Data Type Tag Item |
2078 | * @lrdt: Pointer to the beginning of the Small Resource Data Type tag | 2130 | * @srdt: Pointer to the beginning of the Small Resource Data Type tag |
2079 | * | 2131 | * |
2080 | * Returns the extracted Small Resource Data Type Tag Item. | 2132 | * Returns the extracted Small Resource Data Type Tag Item. |
2081 | */ | 2133 | */ |
diff --git a/include/linux/pcieport_if.h b/include/linux/pcieport_if.h index afcd130ab3a9..e8f3f7479224 100644 --- a/include/linux/pcieport_if.h +++ b/include/linux/pcieport_if.h | |||
@@ -38,7 +38,7 @@ static inline void set_service_data(struct pcie_device *dev, void *data) | |||
38 | dev->priv_data = data; | 38 | dev->priv_data = data; |
39 | } | 39 | } |
40 | 40 | ||
41 | static inline void* get_service_data(struct pcie_device *dev) | 41 | static inline void *get_service_data(struct pcie_device *dev) |
42 | { | 42 | { |
43 | return dev->priv_data; | 43 | return dev->priv_data; |
44 | } | 44 | } |
@@ -50,8 +50,8 @@ struct pcie_port_service_driver { | |||
50 | int (*suspend) (struct pcie_device *dev); | 50 | int (*suspend) (struct pcie_device *dev); |
51 | int (*resume) (struct pcie_device *dev); | 51 | int (*resume) (struct pcie_device *dev); |
52 | 52 | ||
53 | /* Service Error Recovery Handler */ | 53 | /* Device driver may resume normal operations */ |
54 | const struct pci_error_handlers *err_handler; | 54 | void (*error_resume)(struct pci_dev *dev); |
55 | 55 | ||
56 | /* Link Reset Capability - AER service driver specific */ | 56 | /* Link Reset Capability - AER service driver specific */ |
57 | pci_ers_result_t (*reset_link) (struct pci_dev *dev); | 57 | pci_ers_result_t (*reset_link) (struct pci_dev *dev); |
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index c22d3ebaca20..f8d58045926f 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h | |||
@@ -513,6 +513,7 @@ | |||
513 | #define PCI_EXP_DEVSTA_URD 0x0008 /* Unsupported Request Detected */ | 513 | #define PCI_EXP_DEVSTA_URD 0x0008 /* Unsupported Request Detected */ |
514 | #define PCI_EXP_DEVSTA_AUXPD 0x0010 /* AUX Power Detected */ | 514 | #define PCI_EXP_DEVSTA_AUXPD 0x0010 /* AUX Power Detected */ |
515 | #define PCI_EXP_DEVSTA_TRPND 0x0020 /* Transactions Pending */ | 515 | #define PCI_EXP_DEVSTA_TRPND 0x0020 /* Transactions Pending */ |
516 | #define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V1 12 /* v1 endpoints without link end here */ | ||
516 | #define PCI_EXP_LNKCAP 12 /* Link Capabilities */ | 517 | #define PCI_EXP_LNKCAP 12 /* Link Capabilities */ |
517 | #define PCI_EXP_LNKCAP_SLS 0x0000000f /* Supported Link Speeds */ | 518 | #define PCI_EXP_LNKCAP_SLS 0x0000000f /* Supported Link Speeds */ |
518 | #define PCI_EXP_LNKCAP_SLS_2_5GB 0x00000001 /* LNKCAP2 SLS Vector bit 0 */ | 519 | #define PCI_EXP_LNKCAP_SLS_2_5GB 0x00000001 /* LNKCAP2 SLS Vector bit 0 */ |
@@ -556,7 +557,7 @@ | |||
556 | #define PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */ | 557 | #define PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */ |
557 | #define PCI_EXP_LNKSTA_LBMS 0x4000 /* Link Bandwidth Management Status */ | 558 | #define PCI_EXP_LNKSTA_LBMS 0x4000 /* Link Bandwidth Management Status */ |
558 | #define PCI_EXP_LNKSTA_LABS 0x8000 /* Link Autonomous Bandwidth Status */ | 559 | #define PCI_EXP_LNKSTA_LABS 0x8000 /* Link Autonomous Bandwidth Status */ |
559 | #define PCI_CAP_EXP_ENDPOINT_SIZEOF_V1 20 /* v1 endpoints end here */ | 560 | #define PCI_CAP_EXP_ENDPOINT_SIZEOF_V1 20 /* v1 endpoints with link end here */ |
560 | #define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ | 561 | #define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ |
561 | #define PCI_EXP_SLTCAP_ABP 0x00000001 /* Attention Button Present */ | 562 | #define PCI_EXP_SLTCAP_ABP 0x00000001 /* Attention Button Present */ |
562 | #define PCI_EXP_SLTCAP_PCP 0x00000002 /* Power Controller Present */ | 563 | #define PCI_EXP_SLTCAP_PCP 0x00000002 /* Power Controller Present */ |
@@ -639,7 +640,7 @@ | |||
639 | #define PCI_EXP_DEVCTL2_OBFF_MSGB_EN 0x4000 /* Enable OBFF Message type B */ | 640 | #define PCI_EXP_DEVCTL2_OBFF_MSGB_EN 0x4000 /* Enable OBFF Message type B */ |
640 | #define PCI_EXP_DEVCTL2_OBFF_WAKE_EN 0x6000 /* OBFF using WAKE# signaling */ | 641 | #define PCI_EXP_DEVCTL2_OBFF_WAKE_EN 0x6000 /* OBFF using WAKE# signaling */ |
641 | #define PCI_EXP_DEVSTA2 42 /* Device Status 2 */ | 642 | #define PCI_EXP_DEVSTA2 42 /* Device Status 2 */ |
642 | #define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 44 /* v2 endpoints end here */ | 643 | #define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V2 44 /* v2 endpoints without link end here */ |
643 | #define PCI_EXP_LNKCAP2 44 /* Link Capabilities 2 */ | 644 | #define PCI_EXP_LNKCAP2 44 /* Link Capabilities 2 */ |
644 | #define PCI_EXP_LNKCAP2_SLS_2_5GB 0x00000002 /* Supported Speed 2.5GT/s */ | 645 | #define PCI_EXP_LNKCAP2_SLS_2_5GB 0x00000002 /* Supported Speed 2.5GT/s */ |
645 | #define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004 /* Supported Speed 5.0GT/s */ | 646 | #define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004 /* Supported Speed 5.0GT/s */ |
@@ -647,6 +648,7 @@ | |||
647 | #define PCI_EXP_LNKCAP2_CROSSLINK 0x00000100 /* Crosslink supported */ | 648 | #define PCI_EXP_LNKCAP2_CROSSLINK 0x00000100 /* Crosslink supported */ |
648 | #define PCI_EXP_LNKCTL2 48 /* Link Control 2 */ | 649 | #define PCI_EXP_LNKCTL2 48 /* Link Control 2 */ |
649 | #define PCI_EXP_LNKSTA2 50 /* Link Status 2 */ | 650 | #define PCI_EXP_LNKSTA2 50 /* Link Status 2 */ |
651 | #define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 52 /* v2 endpoints with link end here */ | ||
650 | #define PCI_EXP_SLTCAP2 52 /* Slot Capabilities 2 */ | 652 | #define PCI_EXP_SLTCAP2 52 /* Slot Capabilities 2 */ |
651 | #define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */ | 653 | #define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */ |
652 | #define PCI_EXP_SLTSTA2 58 /* Slot Status 2 */ | 654 | #define PCI_EXP_SLTSTA2 58 /* Slot Status 2 */ |
@@ -733,23 +735,17 @@ | |||
733 | #define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */ | 735 | #define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */ |
734 | #define PCI_ERR_HEADER_LOG 28 /* Header Log Register (16 bytes) */ | 736 | #define PCI_ERR_HEADER_LOG 28 /* Header Log Register (16 bytes) */ |
735 | #define PCI_ERR_ROOT_COMMAND 44 /* Root Error Command */ | 737 | #define PCI_ERR_ROOT_COMMAND 44 /* Root Error Command */ |
736 | /* Correctable Err Reporting Enable */ | 738 | #define PCI_ERR_ROOT_CMD_COR_EN 0x00000001 /* Correctable Err Reporting Enable */ |
737 | #define PCI_ERR_ROOT_CMD_COR_EN 0x00000001 | 739 | #define PCI_ERR_ROOT_CMD_NONFATAL_EN 0x00000002 /* Non-Fatal Err Reporting Enable */ |
738 | /* Non-fatal Err Reporting Enable */ | 740 | #define PCI_ERR_ROOT_CMD_FATAL_EN 0x00000004 /* Fatal Err Reporting Enable */ |
739 | #define PCI_ERR_ROOT_CMD_NONFATAL_EN 0x00000002 | ||
740 | /* Fatal Err Reporting Enable */ | ||
741 | #define PCI_ERR_ROOT_CMD_FATAL_EN 0x00000004 | ||
742 | #define PCI_ERR_ROOT_STATUS 48 | 741 | #define PCI_ERR_ROOT_STATUS 48 |
743 | #define PCI_ERR_ROOT_COR_RCV 0x00000001 /* ERR_COR Received */ | 742 | #define PCI_ERR_ROOT_COR_RCV 0x00000001 /* ERR_COR Received */ |
744 | /* Multi ERR_COR Received */ | 743 | #define PCI_ERR_ROOT_MULTI_COR_RCV 0x00000002 /* Multiple ERR_COR */ |
745 | #define PCI_ERR_ROOT_MULTI_COR_RCV 0x00000002 | 744 | #define PCI_ERR_ROOT_UNCOR_RCV 0x00000004 /* ERR_FATAL/NONFATAL */ |
746 | /* ERR_FATAL/NONFATAL Received */ | 745 | #define PCI_ERR_ROOT_MULTI_UNCOR_RCV 0x00000008 /* Multiple FATAL/NONFATAL */ |
747 | #define PCI_ERR_ROOT_UNCOR_RCV 0x00000004 | 746 | #define PCI_ERR_ROOT_FIRST_FATAL 0x00000010 /* First UNC is Fatal */ |
748 | /* Multi ERR_FATAL/NONFATAL Received */ | 747 | #define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020 /* Non-Fatal Received */ |
749 | #define PCI_ERR_ROOT_MULTI_UNCOR_RCV 0x00000008 | 748 | #define PCI_ERR_ROOT_FATAL_RCV 0x00000040 /* Fatal Received */ |
750 | #define PCI_ERR_ROOT_FIRST_FATAL 0x00000010 /* First Fatal */ | ||
751 | #define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020 /* Non-Fatal Received */ | ||
752 | #define PCI_ERR_ROOT_FATAL_RCV 0x00000040 /* Fatal Received */ | ||
753 | #define PCI_ERR_ROOT_ERR_SRC 52 /* Error Source Identification */ | 749 | #define PCI_ERR_ROOT_ERR_SRC 52 /* Error Source Identification */ |
754 | 750 | ||
755 | /* Virtual Channel */ | 751 | /* Virtual Channel */ |
@@ -967,6 +963,7 @@ | |||
967 | #define PCI_EXP_DPC_CAP_RP_EXT 0x20 /* Root Port Extensions for DPC */ | 963 | #define PCI_EXP_DPC_CAP_RP_EXT 0x20 /* Root Port Extensions for DPC */ |
968 | #define PCI_EXP_DPC_CAP_POISONED_TLP 0x40 /* Poisoned TLP Egress Blocking Supported */ | 964 | #define PCI_EXP_DPC_CAP_POISONED_TLP 0x40 /* Poisoned TLP Egress Blocking Supported */ |
969 | #define PCI_EXP_DPC_CAP_SW_TRIGGER 0x80 /* Software Triggering Supported */ | 965 | #define PCI_EXP_DPC_CAP_SW_TRIGGER 0x80 /* Software Triggering Supported */ |
966 | #define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0xF00 /* RP PIO log size */ | ||
970 | #define PCI_EXP_DPC_CAP_DL_ACTIVE 0x1000 /* ERR_COR signal on DL_Active supported */ | 967 | #define PCI_EXP_DPC_CAP_DL_ACTIVE 0x1000 /* ERR_COR signal on DL_Active supported */ |
971 | 968 | ||
972 | #define PCI_EXP_DPC_CTL 6 /* DPC control */ | 969 | #define PCI_EXP_DPC_CTL 6 /* DPC control */ |
@@ -980,6 +977,15 @@ | |||
980 | 977 | ||
981 | #define PCI_EXP_DPC_SOURCE_ID 10 /* DPC Source Identifier */ | 978 | #define PCI_EXP_DPC_SOURCE_ID 10 /* DPC Source Identifier */ |
982 | 979 | ||
980 | #define PCI_EXP_DPC_RP_PIO_STATUS 0x0C /* RP PIO Status */ | ||
981 | #define PCI_EXP_DPC_RP_PIO_MASK 0x10 /* RP PIO MASK */ | ||
982 | #define PCI_EXP_DPC_RP_PIO_SEVERITY 0x14 /* RP PIO Severity */ | ||
983 | #define PCI_EXP_DPC_RP_PIO_SYSERROR 0x18 /* RP PIO SysError */ | ||
984 | #define PCI_EXP_DPC_RP_PIO_EXCEPTION 0x1C /* RP PIO Exception */ | ||
985 | #define PCI_EXP_DPC_RP_PIO_HEADER_LOG 0x20 /* RP PIO Header Log */ | ||
986 | #define PCI_EXP_DPC_RP_PIO_IMPSPEC_LOG 0x30 /* RP PIO ImpSpec Log */ | ||
987 | #define PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG 0x34 /* RP PIO TLP Prefix Log */ | ||
988 | |||
983 | /* Precision Time Measurement */ | 989 | /* Precision Time Measurement */ |
984 | #define PCI_PTM_CAP 0x04 /* PTM Capability */ | 990 | #define PCI_PTM_CAP 0x04 /* PTM Capability */ |
985 | #define PCI_PTM_CAP_REQ 0x00000001 /* Requester capable */ | 991 | #define PCI_PTM_CAP_REQ 0x00000001 /* Requester capable */ |
diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c index ad54a58d7dda..9074b477bff0 100644 --- a/tools/pci/pcitest.c +++ b/tools/pci/pcitest.c | |||
@@ -173,6 +173,7 @@ usage: | |||
173 | "\t-D <dev> PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n" | 173 | "\t-D <dev> PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n" |
174 | "\t-b <bar num> BAR test (bar number between 0..5)\n" | 174 | "\t-b <bar num> BAR test (bar number between 0..5)\n" |
175 | "\t-m <msi num> MSI test (msi number between 1..32)\n" | 175 | "\t-m <msi num> MSI test (msi number between 1..32)\n" |
176 | "\t-l Legacy IRQ test\n" | ||
176 | "\t-r Read buffer test\n" | 177 | "\t-r Read buffer test\n" |
177 | "\t-w Write buffer test\n" | 178 | "\t-w Write buffer test\n" |
178 | "\t-c Copy buffer test\n" | 179 | "\t-c Copy buffer test\n" |