diff options
111 files changed, 4911 insertions, 1333 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci index 6615fda0abfb..ee6c04036492 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci | |||
| @@ -65,6 +65,16 @@ Description: | |||
| 65 | force a rescan of all PCI buses in the system, and | 65 | force a rescan of all PCI buses in the system, and |
| 66 | re-discover previously removed devices. | 66 | re-discover previously removed devices. |
| 67 | 67 | ||
| 68 | What: /sys/bus/pci/devices/.../msi_bus | ||
| 69 | Date: September 2014 | ||
| 70 | Contact: Linux PCI developers <linux-pci@vger.kernel.org> | ||
| 71 | Description: | ||
| 72 | Writing a zero value to this attribute disallows MSI and | ||
| 73 | MSI-X for any future drivers of the device. If the device | ||
| 74 | is a bridge, MSI and MSI-X will be disallowed for future | ||
| 75 | drivers of all child devices under the bridge. Drivers | ||
| 76 | must be reloaded for the new setting to take effect. | ||
| 77 | |||
| 68 | What: /sys/bus/pci/devices/.../msi_irqs/ | 78 | What: /sys/bus/pci/devices/.../msi_irqs/ |
| 69 | Date: September, 2011 | 79 | Date: September, 2011 |
| 70 | Contact: Neil Horman <nhorman@tuxdriver.com> | 80 | Contact: Neil Horman <nhorman@tuxdriver.com> |
diff --git a/Documentation/devicetree/bindings/pci/designware-pcie.txt b/Documentation/devicetree/bindings/pci/designware-pcie.txt index ed0d9b9fff2b..9f4faa8e8d00 100644 --- a/Documentation/devicetree/bindings/pci/designware-pcie.txt +++ b/Documentation/devicetree/bindings/pci/designware-pcie.txt | |||
| @@ -23,3 +23,6 @@ Required properties: | |||
| 23 | 23 | ||
| 24 | Optional properties: | 24 | Optional properties: |
| 25 | - reset-gpio: gpio pin number of power good signal | 25 | - reset-gpio: gpio pin number of power good signal |
| 26 | - bus-range: PCI bus numbers covered (it is recommended for new devicetrees to | ||
| 27 | specify this property, to keep backwards compatibility a range of 0x00-0xff | ||
| 28 | is assumed if not present) | ||
diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt index 0823362548dc..d763e047c6ae 100644 --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | |||
| @@ -1,7 +1,10 @@ | |||
| 1 | NVIDIA Tegra PCIe controller | 1 | NVIDIA Tegra PCIe controller |
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: "nvidia,tegra20-pcie" or "nvidia,tegra30-pcie" | 4 | - compatible: Must be one of: |
| 5 | - "nvidia,tegra20-pcie" | ||
| 6 | - "nvidia,tegra30-pcie" | ||
| 7 | - "nvidia,tegra124-pcie" | ||
| 5 | - device_type: Must be "pci" | 8 | - device_type: Must be "pci" |
| 6 | - reg: A list of physical base address and length for each set of controller | 9 | - reg: A list of physical base address and length for each set of controller |
| 7 | registers. Must contain an entry for each entry in the reg-names property. | 10 | registers. Must contain an entry for each entry in the reg-names property. |
| @@ -57,6 +60,11 @@ Required properties: | |||
| 57 | - afi | 60 | - afi |
| 58 | - pcie_x | 61 | - pcie_x |
| 59 | 62 | ||
| 63 | Required properties on Tegra124 and later: | ||
| 64 | - phys: Must contain an entry for each entry in phy-names. | ||
| 65 | - phy-names: Must include the following entries: | ||
| 66 | - pcie | ||
| 67 | |||
| 60 | Power supplies for Tegra20: | 68 | Power supplies for Tegra20: |
| 61 | - avdd-pex-supply: Power supply for analog PCIe logic. Must supply 1.05 V. | 69 | - avdd-pex-supply: Power supply for analog PCIe logic. Must supply 1.05 V. |
| 62 | - vdd-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V. | 70 | - vdd-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V. |
| @@ -84,6 +92,21 @@ Power supplies for Tegra30: | |||
| 84 | - avdd-pexb-supply: Power supply for analog PCIe logic. Must supply 1.05 V. | 92 | - avdd-pexb-supply: Power supply for analog PCIe logic. Must supply 1.05 V. |
| 85 | - vdd-pexb-supply: Power supply for digital PCIe I/O. Must supply 1.05 V. | 93 | - vdd-pexb-supply: Power supply for digital PCIe I/O. Must supply 1.05 V. |
| 86 | 94 | ||
| 95 | Power supplies for Tegra124: | ||
| 96 | - Required: | ||
| 97 | - avddio-pex-supply: Power supply for analog PCIe logic. Must supply 1.05 V. | ||
| 98 | - dvddio-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V. | ||
| 99 | - avdd-pex-pll-supply: Power supply for dedicated (internal) PCIe PLL. Must | ||
| 100 | supply 1.05 V. | ||
| 101 | - hvdd-pex-supply: High-voltage supply for PCIe I/O and PCIe output clocks. | ||
| 102 | Must supply 3.3 V. | ||
| 103 | - hvdd-pex-pll-e-supply: High-voltage supply for PLLE (shared with USB3). | ||
| 104 | Must supply 3.3 V. | ||
| 105 | - vddio-pex-ctl-supply: Power supply for PCIe control I/O partition. Must | ||
| 106 | supply 2.8-3.3 V. | ||
| 107 | - avdd-pll-erefe-supply: Power supply for PLLE (shared with USB3). Must | ||
| 108 | supply 1.05 V. | ||
| 109 | |||
| 87 | Root ports are defined as subnodes of the PCIe controller node. | 110 | Root ports are defined as subnodes of the PCIe controller node. |
| 88 | 111 | ||
| 89 | Required properties: | 112 | Required properties: |
diff --git a/Documentation/devicetree/bindings/pci/pci-keystone.txt b/Documentation/devicetree/bindings/pci/pci-keystone.txt new file mode 100644 index 000000000000..54eae2938174 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/pci-keystone.txt | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | TI Keystone PCIe interface | ||
| 2 | |||
| 3 | Keystone PCI host Controller is based on Designware PCI h/w version 3.65. | ||
| 4 | It shares common functions with PCIe Designware core driver and inherit | ||
| 5 | common properties defined in | ||
| 6 | Documentation/devicetree/bindings/pci/designware-pci.txt | ||
| 7 | |||
| 8 | Please refer to Documentation/devicetree/bindings/pci/designware-pci.txt | ||
| 9 | for the details of Designware DT bindings. Additional properties are | ||
| 10 | described here as well as properties that are not applicable. | ||
| 11 | |||
| 12 | Required Properties:- | ||
| 13 | |||
| 14 | compatibility: "ti,keystone-pcie" | ||
| 15 | reg: index 1 is the base address and length of DW application registers. | ||
| 16 | index 2 is the base address and length of PCI device ID register. | ||
| 17 | |||
| 18 | pcie_msi_intc : Interrupt controller device node for MSI IRQ chip | ||
| 19 | interrupt-cells: should be set to 1 | ||
| 20 | interrupt-parent: Parent interrupt controller phandle | ||
| 21 | interrupts: GIC interrupt lines connected to PCI MSI interrupt lines | ||
| 22 | |||
| 23 | Example: | ||
| 24 | pcie_msi_intc: msi-interrupt-controller { | ||
| 25 | interrupt-controller; | ||
| 26 | #interrupt-cells = <1>; | ||
| 27 | interrupt-parent = <&gic>; | ||
| 28 | interrupts = <GIC_SPI 30 IRQ_TYPE_EDGE_RISING>, | ||
| 29 | <GIC_SPI 31 IRQ_TYPE_EDGE_RISING>, | ||
| 30 | <GIC_SPI 32 IRQ_TYPE_EDGE_RISING>, | ||
| 31 | <GIC_SPI 33 IRQ_TYPE_EDGE_RISING>, | ||
| 32 | <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>, | ||
| 33 | <GIC_SPI 35 IRQ_TYPE_EDGE_RISING>, | ||
| 34 | <GIC_SPI 36 IRQ_TYPE_EDGE_RISING>, | ||
| 35 | <GIC_SPI 37 IRQ_TYPE_EDGE_RISING>; | ||
| 36 | }; | ||
| 37 | |||
| 38 | pcie_intc: Interrupt controller device node for Legacy IRQ chip | ||
| 39 | interrupt-cells: should be set to 1 | ||
| 40 | interrupt-parent: Parent interrupt controller phandle | ||
| 41 | interrupts: GIC interrupt lines connected to PCI Legacy interrupt lines | ||
| 42 | |||
| 43 | Example: | ||
| 44 | pcie_intc: legacy-interrupt-controller { | ||
| 45 | interrupt-controller; | ||
| 46 | #interrupt-cells = <1>; | ||
| 47 | interrupt-parent = <&gic>; | ||
| 48 | interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>, | ||
| 49 | <GIC_SPI 27 IRQ_TYPE_EDGE_RISING>, | ||
| 50 | <GIC_SPI 28 IRQ_TYPE_EDGE_RISING>, | ||
| 51 | <GIC_SPI 29 IRQ_TYPE_EDGE_RISING>; | ||
| 52 | }; | ||
| 53 | |||
| 54 | Optional properties:- | ||
| 55 | phys: phandle to Generic Keystone SerDes phy for PCI | ||
| 56 | phy-names: name of the Generic Keystine SerDes phy for PCI | ||
| 57 | - If boot loader already does PCI link establishment, then phys and | ||
| 58 | phy-names shouldn't be present. | ||
| 59 | |||
| 60 | Designware DT Properties not applicable for Keystone PCI | ||
| 61 | |||
| 62 | 1. pcie_bus clock-names not used. Instead, a phandle to phys is used. | ||
| 63 | |||
diff --git a/Documentation/devicetree/bindings/pci/xgene-pci.txt b/Documentation/devicetree/bindings/pci/xgene-pci.txt new file mode 100644 index 000000000000..1070b068c7c6 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/xgene-pci.txt | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | * AppliedMicro X-Gene PCIe interface | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - device_type: set to "pci" | ||
| 5 | - compatible: should contain "apm,xgene-pcie" to identify the core. | ||
| 6 | - reg: A list of physical base address and length for each set of controller | ||
| 7 | registers. Must contain an entry for each entry in the reg-names | ||
| 8 | property. | ||
| 9 | - reg-names: Must include the following entries: | ||
| 10 | "csr": controller configuration registers. | ||
| 11 | "cfg": pcie configuration space registers. | ||
| 12 | - #address-cells: set to <3> | ||
| 13 | - #size-cells: set to <2> | ||
| 14 | - ranges: ranges for the outbound memory, I/O regions. | ||
| 15 | - dma-ranges: ranges for the inbound memory regions. | ||
| 16 | - #interrupt-cells: set to <1> | ||
| 17 | - interrupt-map-mask and interrupt-map: standard PCI properties | ||
| 18 | to define the mapping of the PCIe interface to interrupt | ||
| 19 | numbers. | ||
| 20 | - clocks: from common clock binding: handle to pci clock. | ||
| 21 | |||
| 22 | Optional properties: | ||
| 23 | - status: Either "ok" or "disabled". | ||
| 24 | - dma-coherent: Present if dma operations are coherent | ||
| 25 | |||
| 26 | Example: | ||
| 27 | |||
| 28 | SoC specific DT Entry: | ||
| 29 | |||
| 30 | pcie0: pcie@1f2b0000 { | ||
| 31 | status = "disabled"; | ||
| 32 | device_type = "pci"; | ||
| 33 | compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie"; | ||
| 34 | #interrupt-cells = <1>; | ||
| 35 | #size-cells = <2>; | ||
| 36 | #address-cells = <3>; | ||
| 37 | reg = < 0x00 0x1f2b0000 0x0 0x00010000 /* Controller registers */ | ||
| 38 | 0xe0 0xd0000000 0x0 0x00040000>; /* PCI config space */ | ||
| 39 | reg-names = "csr", "cfg"; | ||
| 40 | ranges = <0x01000000 0x00 0x00000000 0xe0 0x10000000 0x00 0x00010000 /* io */ | ||
| 41 | 0x02000000 0x00 0x80000000 0xe1 0x80000000 0x00 0x80000000>; /* mem */ | ||
| 42 | dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 | ||
| 43 | 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; | ||
| 44 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
| 45 | interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc2 0x1 | ||
| 46 | 0x0 0x0 0x0 0x2 &gic 0x0 0xc3 0x1 | ||
| 47 | 0x0 0x0 0x0 0x3 &gic 0x0 0xc4 0x1 | ||
| 48 | 0x0 0x0 0x0 0x4 &gic 0x0 0xc5 0x1>; | ||
| 49 | dma-coherent; | ||
| 50 | clocks = <&pcie0clk 0>; | ||
| 51 | }; | ||
| 52 | |||
| 53 | |||
| 54 | Board specific DT Entry: | ||
| 55 | &pcie0 { | ||
| 56 | status = "ok"; | ||
| 57 | }; | ||
diff --git a/Documentation/devicetree/bindings/pci/xilinx-pcie.txt b/Documentation/devicetree/bindings/pci/xilinx-pcie.txt new file mode 100644 index 000000000000..3e2c88d97ad4 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/xilinx-pcie.txt | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | * Xilinx AXI PCIe Root Port Bridge DT description | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - #address-cells: Address representation for root ports, set to <3> | ||
| 5 | - #size-cells: Size representation for root ports, set to <2> | ||
| 6 | - #interrupt-cells: specifies the number of cells needed to encode an | ||
| 7 | interrupt source. The value must be 1. | ||
| 8 | - compatible: Should contain "xlnx,axi-pcie-host-1.00.a" | ||
| 9 | - reg: Should contain AXI PCIe registers location and length | ||
| 10 | - device_type: must be "pci" | ||
| 11 | - interrupts: Should contain AXI PCIe interrupt | ||
| 12 | - interrupt-map-mask, | ||
| 13 | interrupt-map: standard PCI properties to define the mapping of the | ||
| 14 | PCI interface to interrupt numbers. | ||
| 15 | - ranges: ranges for the PCI memory regions (I/O space region is not | ||
| 16 | supported by hardware) | ||
| 17 | Please refer to the standard PCI bus binding document for a more | ||
| 18 | detailed explanation | ||
| 19 | |||
| 20 | Optional properties: | ||
| 21 | - bus-range: PCI bus numbers covered | ||
| 22 | |||
| 23 | Interrupt controller child node | ||
| 24 | +++++++++++++++++++++++++++++++ | ||
| 25 | Required properties: | ||
| 26 | - interrupt-controller: identifies the node as an interrupt controller | ||
| 27 | - #address-cells: specifies the number of cells needed to encode an | ||
| 28 | address. The value must be 0. | ||
| 29 | - #interrupt-cells: specifies the number of cells needed to encode an | ||
| 30 | interrupt source. The value must be 1. | ||
| 31 | |||
| 32 | NOTE: | ||
| 33 | The core provides a single interrupt for both INTx/MSI messages. So, | ||
| 34 | created a interrupt controller node to support 'interrupt-map' DT | ||
| 35 | functionality. The driver will create an IRQ domain for this map, decode | ||
| 36 | the four INTx interrupts in ISR and route them to this domain. | ||
| 37 | |||
| 38 | |||
| 39 | Example: | ||
| 40 | ++++++++ | ||
| 41 | |||
| 42 | pci_express: axi-pcie@50000000 { | ||
| 43 | #address-cells = <3>; | ||
| 44 | #size-cells = <2>; | ||
| 45 | #interrupt-cells = <1>; | ||
| 46 | compatible = "xlnx,axi-pcie-host-1.00.a"; | ||
| 47 | reg = < 0x50000000 0x10000000 >; | ||
| 48 | device_type = "pci"; | ||
| 49 | interrupts = < 0 52 4 >; | ||
| 50 | interrupt-map-mask = <0 0 0 7>; | ||
| 51 | interrupt-map = <0 0 0 1 &pcie_intc 1>, | ||
| 52 | <0 0 0 2 &pcie_intc 2>, | ||
| 53 | <0 0 0 3 &pcie_intc 3>, | ||
| 54 | <0 0 0 4 &pcie_intc 4>; | ||
| 55 | ranges = < 0x02000000 0 0x60000000 0x60000000 0 0x10000000 >; | ||
| 56 | |||
| 57 | pcie_intc: interrupt-controller { | ||
| 58 | interrupt-controller; | ||
| 59 | #address-cells = <0>; | ||
| 60 | #interrupt-cells = <1>; | ||
| 61 | } | ||
| 62 | }; | ||
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 40677443c0c5..b5ab416cd53a 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt | |||
| @@ -264,8 +264,10 @@ IIO | |||
| 264 | IO region | 264 | IO region |
| 265 | devm_release_mem_region() | 265 | devm_release_mem_region() |
| 266 | devm_release_region() | 266 | devm_release_region() |
| 267 | devm_release_resource() | ||
| 267 | devm_request_mem_region() | 268 | devm_request_mem_region() |
| 268 | devm_request_region() | 269 | devm_request_region() |
| 270 | devm_request_resource() | ||
| 269 | 271 | ||
| 270 | IOMAP | 272 | IOMAP |
| 271 | devm_ioport_map() | 273 | devm_ioport_map() |
diff --git a/MAINTAINERS b/MAINTAINERS index 0b23084070c2..75b98b4958c8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -6939,6 +6939,14 @@ F: include/linux/pci* | |||
| 6939 | F: arch/x86/pci/ | 6939 | F: arch/x86/pci/ |
| 6940 | F: arch/x86/kernel/quirks.c | 6940 | F: arch/x86/kernel/quirks.c |
| 6941 | 6941 | ||
| 6942 | PCI DRIVER FOR APPLIEDMICRO XGENE | ||
| 6943 | M: Tanmay Inamdar <tinamdar@apm.com> | ||
| 6944 | L: linux-pci@vger.kernel.org | ||
| 6945 | L: linux-arm-kernel@lists.infradead.org | ||
| 6946 | S: Maintained | ||
| 6947 | F: Documentation/devicetree/bindings/pci/xgene-pci.txt | ||
| 6948 | F: drivers/pci/host/pci-xgene.c | ||
| 6949 | |||
| 6942 | PCI DRIVER FOR IMX6 | 6950 | PCI DRIVER FOR IMX6 |
| 6943 | M: Richard Zhu <r65037@freescale.com> | 6951 | M: Richard Zhu <r65037@freescale.com> |
| 6944 | M: Lucas Stach <l.stach@pengutronix.de> | 6952 | M: Lucas Stach <l.stach@pengutronix.de> |
| @@ -6947,6 +6955,13 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |||
| 6947 | S: Maintained | 6955 | S: Maintained |
| 6948 | F: drivers/pci/host/*imx6* | 6956 | F: drivers/pci/host/*imx6* |
| 6949 | 6957 | ||
| 6958 | PCI DRIVER FOR TI KEYSTONE | ||
| 6959 | M: Murali Karicheri <m-karicheri2@ti.com> | ||
| 6960 | L: linux-pci@vger.kernel.org | ||
| 6961 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
| 6962 | S: Maintained | ||
| 6963 | F: drivers/pci/host/*keystone* | ||
| 6964 | |||
| 6950 | PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support) | 6965 | PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support) |
| 6951 | M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | 6966 | M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> |
| 6952 | M: Jason Cooper <jason@lakedaemon.net> | 6967 | M: Jason Cooper <jason@lakedaemon.net> |
diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi index fa5f2bb5f106..9d342920695a 100644 --- a/arch/arm/boot/dts/spear1310.dtsi +++ b/arch/arm/boot/dts/spear1310.dtsi | |||
| @@ -85,7 +85,8 @@ | |||
| 85 | 85 | ||
| 86 | pcie0: pcie@b1000000 { | 86 | pcie0: pcie@b1000000 { |
| 87 | compatible = "st,spear1340-pcie", "snps,dw-pcie"; | 87 | compatible = "st,spear1340-pcie", "snps,dw-pcie"; |
| 88 | reg = <0xb1000000 0x4000>; | 88 | reg = <0xb1000000 0x4000>, <0x80000000 0x20000>; |
| 89 | reg-names = "dbi", "config"; | ||
| 89 | interrupts = <0 68 0x4>; | 90 | interrupts = <0 68 0x4>; |
| 90 | interrupt-map-mask = <0 0 0 0>; | 91 | interrupt-map-mask = <0 0 0 0>; |
| 91 | interrupt-map = <0x0 0 &gic 0 68 0x4>; | 92 | interrupt-map = <0x0 0 &gic 0 68 0x4>; |
| @@ -95,15 +96,15 @@ | |||
| 95 | #address-cells = <3>; | 96 | #address-cells = <3>; |
| 96 | #size-cells = <2>; | 97 | #size-cells = <2>; |
| 97 | device_type = "pci"; | 98 | device_type = "pci"; |
| 98 | ranges = <0x00000800 0 0x80000000 0x80000000 0 0x00020000 /* configuration space */ | 99 | ranges = <0x81000000 0 0 0x80020000 0 0x00010000 /* downstream I/O */ |
| 99 | 0x81000000 0 0 0x80020000 0 0x00010000 /* downstream I/O */ | ||
| 100 | 0x82000000 0 0x80030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */ | 100 | 0x82000000 0 0x80030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */ |
| 101 | status = "disabled"; | 101 | status = "disabled"; |
| 102 | }; | 102 | }; |
| 103 | 103 | ||
| 104 | pcie1: pcie@b1800000 { | 104 | pcie1: pcie@b1800000 { |
| 105 | compatible = "st,spear1340-pcie", "snps,dw-pcie"; | 105 | compatible = "st,spear1340-pcie", "snps,dw-pcie"; |
| 106 | reg = <0xb1800000 0x4000>; | 106 | reg = <0xb1800000 0x4000>, <0x90000000 0x20000>; |
| 107 | reg-names = "dbi", "config"; | ||
| 107 | interrupts = <0 69 0x4>; | 108 | interrupts = <0 69 0x4>; |
| 108 | interrupt-map-mask = <0 0 0 0>; | 109 | interrupt-map-mask = <0 0 0 0>; |
| 109 | interrupt-map = <0x0 0 &gic 0 69 0x4>; | 110 | interrupt-map = <0x0 0 &gic 0 69 0x4>; |
| @@ -113,15 +114,15 @@ | |||
| 113 | #address-cells = <3>; | 114 | #address-cells = <3>; |
| 114 | #size-cells = <2>; | 115 | #size-cells = <2>; |
| 115 | device_type = "pci"; | 116 | device_type = "pci"; |
| 116 | ranges = <0x00000800 0 0x90000000 0x90000000 0 0x00020000 /* configuration space */ | 117 | ranges = <0x81000000 0 0 0x90020000 0 0x00010000 /* downstream I/O */ |
| 117 | 0x81000000 0 0 0x90020000 0 0x00010000 /* downstream I/O */ | ||
| 118 | 0x82000000 0 0x90030000 0x90030000 0 0x0ffd0000>; /* non-prefetchable memory */ | 118 | 0x82000000 0 0x90030000 0x90030000 0 0x0ffd0000>; /* non-prefetchable memory */ |
| 119 | status = "disabled"; | 119 | status = "disabled"; |
| 120 | }; | 120 | }; |
| 121 | 121 | ||
| 122 | pcie2: pcie@b4000000 { | 122 | pcie2: pcie@b4000000 { |
| 123 | compatible = "st,spear1340-pcie", "snps,dw-pcie"; | 123 | compatible = "st,spear1340-pcie", "snps,dw-pcie"; |
| 124 | reg = <0xb4000000 0x4000>; | 124 | reg = <0xb4000000 0x4000>, <0xc0000000 0x20000>; |
| 125 | reg-names = "dbi", "config"; | ||
| 125 | interrupts = <0 70 0x4>; | 126 | interrupts = <0 70 0x4>; |
| 126 | interrupt-map-mask = <0 0 0 0>; | 127 | interrupt-map-mask = <0 0 0 0>; |
| 127 | interrupt-map = <0x0 0 &gic 0 70 0x4>; | 128 | interrupt-map = <0x0 0 &gic 0 70 0x4>; |
| @@ -131,8 +132,7 @@ | |||
| 131 | #address-cells = <3>; | 132 | #address-cells = <3>; |
| 132 | #size-cells = <2>; | 133 | #size-cells = <2>; |
| 133 | device_type = "pci"; | 134 | device_type = "pci"; |
| 134 | ranges = <0x00000800 0 0xc0000000 0xc0000000 0 0x00020000 /* configuration space */ | 135 | ranges = <0x81000000 0 0 0xc0020000 0 0x00010000 /* downstream I/O */ |
| 135 | 0x81000000 0 0 0xc0020000 0 0x00010000 /* downstream I/O */ | ||
| 136 | 0x82000000 0 0xc0030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */ | 136 | 0x82000000 0 0xc0030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */ |
| 137 | status = "disabled"; | 137 | status = "disabled"; |
| 138 | }; | 138 | }; |
diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi index e71df0f2cb52..13e1aa33daa2 100644 --- a/arch/arm/boot/dts/spear1340.dtsi +++ b/arch/arm/boot/dts/spear1340.dtsi | |||
| @@ -50,7 +50,8 @@ | |||
| 50 | 50 | ||
| 51 | pcie0: pcie@b1000000 { | 51 | pcie0: pcie@b1000000 { |
| 52 | compatible = "st,spear1340-pcie", "snps,dw-pcie"; | 52 | compatible = "st,spear1340-pcie", "snps,dw-pcie"; |
| 53 | reg = <0xb1000000 0x4000>; | 53 | reg = <0xb1000000 0x4000>, <0x80000000 0x20000>; |
| 54 | reg-names = "dbi", "config"; | ||
| 54 | interrupts = <0 68 0x4>; | 55 | interrupts = <0 68 0x4>; |
| 55 | interrupt-map-mask = <0 0 0 0>; | 56 | interrupt-map-mask = <0 0 0 0>; |
| 56 | interrupt-map = <0x0 0 &gic 0 68 0x4>; | 57 | interrupt-map = <0x0 0 &gic 0 68 0x4>; |
| @@ -60,8 +61,7 @@ | |||
| 60 | #address-cells = <3>; | 61 | #address-cells = <3>; |
| 61 | #size-cells = <2>; | 62 | #size-cells = <2>; |
| 62 | device_type = "pci"; | 63 | device_type = "pci"; |
| 63 | ranges = <0x00000800 0 0x80000000 0x80000000 0 0x00020000 /* configuration space */ | 64 | ranges = <0x81000000 0 0 0x80020000 0 0x00010000 /* downstream I/O */ |
| 64 | 0x81000000 0 0 0x80020000 0 0x00010000 /* downstream I/O */ | ||
| 65 | 0x82000000 0 0x80030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */ | 65 | 0x82000000 0 0x80030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */ |
| 66 | status = "disabled"; | 66 | status = "disabled"; |
| 67 | }; | 67 | }; |
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 3d23418cbddd..180567408ee8 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h | |||
| @@ -178,6 +178,7 @@ static inline void __iomem *__typesafe_io(unsigned long addr) | |||
| 178 | 178 | ||
| 179 | /* PCI fixed i/o mapping */ | 179 | /* PCI fixed i/o mapping */ |
| 180 | #define PCI_IO_VIRT_BASE 0xfee00000 | 180 | #define PCI_IO_VIRT_BASE 0xfee00000 |
| 181 | #define PCI_IOBASE ((void __iomem *)PCI_IO_VIRT_BASE) | ||
| 181 | 182 | ||
| 182 | #if defined(CONFIG_PCI) | 183 | #if defined(CONFIG_PCI) |
| 183 | void pci_ioremap_set_mem_type(int mem_type); | 184 | void pci_ioremap_set_mem_type(int mem_type); |
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index 05e1f73a1e8d..c186a17c2cff 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c | |||
| @@ -660,6 +660,7 @@ static void __init pci_v3_preinit(void) | |||
| 660 | { | 660 | { |
| 661 | unsigned long flags; | 661 | unsigned long flags; |
| 662 | unsigned int temp; | 662 | unsigned int temp; |
| 663 | phys_addr_t io_address = pci_pio_to_address(io_mem.start); | ||
| 663 | 664 | ||
| 664 | pcibios_min_mem = 0x00100000; | 665 | pcibios_min_mem = 0x00100000; |
| 665 | 666 | ||
| @@ -701,7 +702,7 @@ static void __init pci_v3_preinit(void) | |||
| 701 | /* | 702 | /* |
| 702 | * Setup window 2 - PCI IO | 703 | * Setup window 2 - PCI IO |
| 703 | */ | 704 | */ |
| 704 | v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_mem.start) | | 705 | v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_address) | |
| 705 | V3_LB_BASE_ENABLE); | 706 | V3_LB_BASE_ENABLE); |
| 706 | v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0)); | 707 | v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0)); |
| 707 | 708 | ||
| @@ -742,6 +743,7 @@ static void __init pci_v3_preinit(void) | |||
| 742 | static void __init pci_v3_postinit(void) | 743 | static void __init pci_v3_postinit(void) |
| 743 | { | 744 | { |
| 744 | unsigned int pci_cmd; | 745 | unsigned int pci_cmd; |
| 746 | phys_addr_t io_address = pci_pio_to_address(io_mem.start); | ||
| 745 | 747 | ||
| 746 | pci_cmd = PCI_COMMAND_MEMORY | | 748 | pci_cmd = PCI_COMMAND_MEMORY | |
| 747 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; | 749 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; |
| @@ -758,7 +760,7 @@ static void __init pci_v3_postinit(void) | |||
| 758 | "interrupt: %d\n", ret); | 760 | "interrupt: %d\n", ret); |
| 759 | #endif | 761 | #endif |
| 760 | 762 | ||
| 761 | register_isa_ports(non_mem.start, io_mem.start, 0); | 763 | register_isa_ports(non_mem.start, io_address, 0); |
| 762 | } | 764 | } |
| 763 | 765 | ||
| 764 | /* | 766 | /* |
| @@ -867,33 +869,32 @@ static int __init pci_v3_probe(struct platform_device *pdev) | |||
| 867 | 869 | ||
| 868 | for_each_of_pci_range(&parser, &range) { | 870 | for_each_of_pci_range(&parser, &range) { |
| 869 | if (!range.flags) { | 871 | if (!range.flags) { |
| 870 | of_pci_range_to_resource(&range, np, &conf_mem); | 872 | ret = of_pci_range_to_resource(&range, np, &conf_mem); |
| 871 | conf_mem.name = "PCIv3 config"; | 873 | conf_mem.name = "PCIv3 config"; |
| 872 | } | 874 | } |
| 873 | if (range.flags & IORESOURCE_IO) { | 875 | if (range.flags & IORESOURCE_IO) { |
| 874 | of_pci_range_to_resource(&range, np, &io_mem); | 876 | ret = of_pci_range_to_resource(&range, np, &io_mem); |
| 875 | io_mem.name = "PCIv3 I/O"; | 877 | io_mem.name = "PCIv3 I/O"; |
| 876 | } | 878 | } |
| 877 | if ((range.flags & IORESOURCE_MEM) && | 879 | if ((range.flags & IORESOURCE_MEM) && |
| 878 | !(range.flags & IORESOURCE_PREFETCH)) { | 880 | !(range.flags & IORESOURCE_PREFETCH)) { |
| 879 | non_mem_pci = range.pci_addr; | 881 | non_mem_pci = range.pci_addr; |
| 880 | non_mem_pci_sz = range.size; | 882 | non_mem_pci_sz = range.size; |
| 881 | of_pci_range_to_resource(&range, np, &non_mem); | 883 | ret = of_pci_range_to_resource(&range, np, &non_mem); |
| 882 | non_mem.name = "PCIv3 non-prefetched mem"; | 884 | non_mem.name = "PCIv3 non-prefetched mem"; |
| 883 | } | 885 | } |
| 884 | if ((range.flags & IORESOURCE_MEM) && | 886 | if ((range.flags & IORESOURCE_MEM) && |
| 885 | (range.flags & IORESOURCE_PREFETCH)) { | 887 | (range.flags & IORESOURCE_PREFETCH)) { |
| 886 | pre_mem_pci = range.pci_addr; | 888 | pre_mem_pci = range.pci_addr; |
| 887 | pre_mem_pci_sz = range.size; | 889 | pre_mem_pci_sz = range.size; |
| 888 | of_pci_range_to_resource(&range, np, &pre_mem); | 890 | ret = of_pci_range_to_resource(&range, np, &pre_mem); |
| 889 | pre_mem.name = "PCIv3 prefetched mem"; | 891 | pre_mem.name = "PCIv3 prefetched mem"; |
| 890 | } | 892 | } |
| 891 | } | ||
| 892 | 893 | ||
| 893 | if (!conf_mem.start || !io_mem.start || | 894 | if (ret < 0) { |
| 894 | !non_mem.start || !pre_mem.start) { | 895 | dev_err(&pdev->dev, "missing ranges in device node\n"); |
| 895 | dev_err(&pdev->dev, "missing ranges in device node\n"); | 896 | return ret; |
| 896 | return -EINVAL; | 897 | } |
| 897 | } | 898 | } |
| 898 | 899 | ||
| 899 | pci_v3.map_irq = of_irq_parse_and_map_pci; | 900 | pci_v3.map_irq = of_irq_parse_and_map_pci; |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 9746dc24a117..3f0e854d0ff4 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
| @@ -83,7 +83,7 @@ config MMU | |||
| 83 | def_bool y | 83 | def_bool y |
| 84 | 84 | ||
| 85 | config NO_IOPORT_MAP | 85 | config NO_IOPORT_MAP |
| 86 | def_bool y | 86 | def_bool y if !PCI |
| 87 | 87 | ||
| 88 | config STACKTRACE_SUPPORT | 88 | config STACKTRACE_SUPPORT |
| 89 | def_bool y | 89 | def_bool y |
| @@ -163,6 +163,26 @@ menu "Bus support" | |||
| 163 | config ARM_AMBA | 163 | config ARM_AMBA |
| 164 | bool | 164 | bool |
| 165 | 165 | ||
| 166 | config PCI | ||
| 167 | bool "PCI support" | ||
| 168 | help | ||
| 169 | This feature enables support for PCI bus system. If you say Y | ||
| 170 | here, the kernel will include drivers and infrastructure code | ||
| 171 | to support PCI bus devices. | ||
| 172 | |||
| 173 | config PCI_DOMAINS | ||
| 174 | def_bool PCI | ||
| 175 | |||
| 176 | config PCI_DOMAINS_GENERIC | ||
| 177 | def_bool PCI | ||
| 178 | |||
| 179 | config PCI_SYSCALL | ||
| 180 | def_bool PCI | ||
| 181 | |||
| 182 | source "drivers/pci/Kconfig" | ||
| 183 | source "drivers/pci/pcie/Kconfig" | ||
| 184 | source "drivers/pci/hotplug/Kconfig" | ||
| 185 | |||
| 166 | endmenu | 186 | endmenu |
| 167 | 187 | ||
| 168 | menu "Kernel Features" | 188 | menu "Kernel Features" |
diff --git a/arch/arm64/boot/dts/apm-mustang.dts b/arch/arm64/boot/dts/apm-mustang.dts index b2f56229aa5e..f64900052f4e 100644 --- a/arch/arm64/boot/dts/apm-mustang.dts +++ b/arch/arm64/boot/dts/apm-mustang.dts | |||
| @@ -25,6 +25,14 @@ | |||
| 25 | }; | 25 | }; |
| 26 | }; | 26 | }; |
| 27 | 27 | ||
| 28 | &pcie0clk { | ||
| 29 | status = "ok"; | ||
| 30 | }; | ||
| 31 | |||
| 32 | &pcie0 { | ||
| 33 | status = "ok"; | ||
| 34 | }; | ||
| 35 | |||
| 28 | &serial0 { | 36 | &serial0 { |
| 29 | status = "ok"; | 37 | status = "ok"; |
| 30 | }; | 38 | }; |
diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi index f391972ad135..4f6d04d52cca 100644 --- a/arch/arm64/boot/dts/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm-storm.dtsi | |||
| @@ -282,6 +282,171 @@ | |||
| 282 | enable-mask = <0x10>; | 282 | enable-mask = <0x10>; |
| 283 | clock-output-names = "rngpkaclk"; | 283 | clock-output-names = "rngpkaclk"; |
| 284 | }; | 284 | }; |
| 285 | |||
| 286 | pcie0clk: pcie0clk@1f2bc000 { | ||
| 287 | status = "disabled"; | ||
| 288 | compatible = "apm,xgene-device-clock"; | ||
| 289 | #clock-cells = <1>; | ||
| 290 | clocks = <&socplldiv2 0>; | ||
| 291 | reg = <0x0 0x1f2bc000 0x0 0x1000>; | ||
| 292 | reg-names = "csr-reg"; | ||
| 293 | clock-output-names = "pcie0clk"; | ||
| 294 | }; | ||
| 295 | |||
| 296 | pcie1clk: pcie1clk@1f2cc000 { | ||
| 297 | status = "disabled"; | ||
| 298 | compatible = "apm,xgene-device-clock"; | ||
| 299 | #clock-cells = <1>; | ||
| 300 | clocks = <&socplldiv2 0>; | ||
| 301 | reg = <0x0 0x1f2cc000 0x0 0x1000>; | ||
| 302 | reg-names = "csr-reg"; | ||
| 303 | clock-output-names = "pcie1clk"; | ||
| 304 | }; | ||
| 305 | |||
| 306 | pcie2clk: pcie2clk@1f2dc000 { | ||
| 307 | status = "disabled"; | ||
| 308 | compatible = "apm,xgene-device-clock"; | ||
| 309 | #clock-cells = <1>; | ||
| 310 | clocks = <&socplldiv2 0>; | ||
| 311 | reg = <0x0 0x1f2dc000 0x0 0x1000>; | ||
| 312 | reg-names = "csr-reg"; | ||
| 313 | clock-output-names = "pcie2clk"; | ||
| 314 | }; | ||
| 315 | |||
| 316 | pcie3clk: pcie3clk@1f50c000 { | ||
| 317 | status = "disabled"; | ||
| 318 | compatible = "apm,xgene-device-clock"; | ||
| 319 | #clock-cells = <1>; | ||
| 320 | clocks = <&socplldiv2 0>; | ||
| 321 | reg = <0x0 0x1f50c000 0x0 0x1000>; | ||
| 322 | reg-names = "csr-reg"; | ||
| 323 | clock-output-names = "pcie3clk"; | ||
| 324 | }; | ||
| 325 | |||
| 326 | pcie4clk: pcie4clk@1f51c000 { | ||
| 327 | status = "disabled"; | ||
| 328 | compatible = "apm,xgene-device-clock"; | ||
| 329 | #clock-cells = <1>; | ||
| 330 | clocks = <&socplldiv2 0>; | ||
| 331 | reg = <0x0 0x1f51c000 0x0 0x1000>; | ||
| 332 | reg-names = "csr-reg"; | ||
| 333 | clock-output-names = "pcie4clk"; | ||
| 334 | }; | ||
| 335 | }; | ||
| 336 | |||
| 337 | pcie0: pcie@1f2b0000 { | ||
| 338 | status = "disabled"; | ||
| 339 | device_type = "pci"; | ||
| 340 | compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie"; | ||
| 341 | #interrupt-cells = <1>; | ||
| 342 | #size-cells = <2>; | ||
| 343 | #address-cells = <3>; | ||
| 344 | reg = < 0x00 0x1f2b0000 0x0 0x00010000 /* Controller registers */ | ||
| 345 | 0xe0 0xd0000000 0x0 0x00040000>; /* PCI config space */ | ||
| 346 | reg-names = "csr", "cfg"; | ||
| 347 | ranges = <0x01000000 0x00 0x00000000 0xe0 0x10000000 0x00 0x00010000 /* io */ | ||
| 348 | 0x02000000 0x00 0x80000000 0xe1 0x80000000 0x00 0x80000000>; /* mem */ | ||
| 349 | dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 | ||
| 350 | 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; | ||
| 351 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
| 352 | interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc2 0x1 | ||
| 353 | 0x0 0x0 0x0 0x2 &gic 0x0 0xc3 0x1 | ||
| 354 | 0x0 0x0 0x0 0x3 &gic 0x0 0xc4 0x1 | ||
| 355 | 0x0 0x0 0x0 0x4 &gic 0x0 0xc5 0x1>; | ||
| 356 | dma-coherent; | ||
| 357 | clocks = <&pcie0clk 0>; | ||
| 358 | }; | ||
| 359 | |||
| 360 | pcie1: pcie@1f2c0000 { | ||
| 361 | status = "disabled"; | ||
| 362 | device_type = "pci"; | ||
| 363 | compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie"; | ||
| 364 | #interrupt-cells = <1>; | ||
| 365 | #size-cells = <2>; | ||
| 366 | #address-cells = <3>; | ||
| 367 | reg = < 0x00 0x1f2c0000 0x0 0x00010000 /* Controller registers */ | ||
| 368 | 0xd0 0xd0000000 0x0 0x00040000>; /* PCI config space */ | ||
| 369 | reg-names = "csr", "cfg"; | ||
| 370 | ranges = <0x01000000 0x0 0x00000000 0xd0 0x10000000 0x00 0x00010000 /* io */ | ||
| 371 | 0x02000000 0x0 0x80000000 0xd1 0x80000000 0x00 0x80000000>; /* mem */ | ||
| 372 | dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 | ||
| 373 | 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; | ||
| 374 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
| 375 | interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc8 0x1 | ||
| 376 | 0x0 0x0 0x0 0x2 &gic 0x0 0xc9 0x1 | ||
| 377 | 0x0 0x0 0x0 0x3 &gic 0x0 0xca 0x1 | ||
| 378 | 0x0 0x0 0x0 0x4 &gic 0x0 0xcb 0x1>; | ||
| 379 | dma-coherent; | ||
| 380 | clocks = <&pcie1clk 0>; | ||
| 381 | }; | ||
| 382 | |||
| 383 | pcie2: pcie@1f2d0000 { | ||
| 384 | status = "disabled"; | ||
| 385 | device_type = "pci"; | ||
| 386 | compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie"; | ||
| 387 | #interrupt-cells = <1>; | ||
| 388 | #size-cells = <2>; | ||
| 389 | #address-cells = <3>; | ||
| 390 | reg = < 0x00 0x1f2d0000 0x0 0x00010000 /* Controller registers */ | ||
| 391 | 0x90 0xd0000000 0x0 0x00040000>; /* PCI config space */ | ||
| 392 | reg-names = "csr", "cfg"; | ||
| 393 | ranges = <0x01000000 0x0 0x00000000 0x90 0x10000000 0x0 0x00010000 /* io */ | ||
| 394 | 0x02000000 0x0 0x80000000 0x91 0x80000000 0x0 0x80000000>; /* mem */ | ||
| 395 | dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 | ||
| 396 | 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; | ||
| 397 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
| 398 | interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xce 0x1 | ||
| 399 | 0x0 0x0 0x0 0x2 &gic 0x0 0xcf 0x1 | ||
| 400 | 0x0 0x0 0x0 0x3 &gic 0x0 0xd0 0x1 | ||
| 401 | 0x0 0x0 0x0 0x4 &gic 0x0 0xd1 0x1>; | ||
| 402 | dma-coherent; | ||
| 403 | clocks = <&pcie2clk 0>; | ||
| 404 | }; | ||
| 405 | |||
| 406 | pcie3: pcie@1f500000 { | ||
| 407 | status = "disabled"; | ||
| 408 | device_type = "pci"; | ||
| 409 | compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie"; | ||
| 410 | #interrupt-cells = <1>; | ||
| 411 | #size-cells = <2>; | ||
| 412 | #address-cells = <3>; | ||
| 413 | reg = < 0x00 0x1f500000 0x0 0x00010000 /* Controller registers */ | ||
| 414 | 0xa0 0xd0000000 0x0 0x00040000>; /* PCI config space */ | ||
| 415 | reg-names = "csr", "cfg"; | ||
| 416 | ranges = <0x01000000 0x0 0x00000000 0xa0 0x10000000 0x0 0x00010000 /* io */ | ||
| 417 | 0x02000000 0x0 0x80000000 0xa1 0x80000000 0x0 0x80000000>; /* mem */ | ||
| 418 | dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 | ||
| 419 | 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; | ||
| 420 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
| 421 | interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xd4 0x1 | ||
| 422 | 0x0 0x0 0x0 0x2 &gic 0x0 0xd5 0x1 | ||
| 423 | 0x0 0x0 0x0 0x3 &gic 0x0 0xd6 0x1 | ||
| 424 | 0x0 0x0 0x0 0x4 &gic 0x0 0xd7 0x1>; | ||
| 425 | dma-coherent; | ||
| 426 | clocks = <&pcie3clk 0>; | ||
| 427 | }; | ||
| 428 | |||
| 429 | pcie4: pcie@1f510000 { | ||
| 430 | status = "disabled"; | ||
| 431 | device_type = "pci"; | ||
| 432 | compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie"; | ||
| 433 | #interrupt-cells = <1>; | ||
| 434 | #size-cells = <2>; | ||
| 435 | #address-cells = <3>; | ||
| 436 | reg = < 0x00 0x1f510000 0x0 0x00010000 /* Controller registers */ | ||
| 437 | 0xc0 0xd0000000 0x0 0x00200000>; /* PCI config space */ | ||
| 438 | reg-names = "csr", "cfg"; | ||
| 439 | ranges = <0x01000000 0x0 0x00000000 0xc0 0x10000000 0x0 0x00010000 /* io */ | ||
| 440 | 0x02000000 0x0 0x80000000 0xc1 0x80000000 0x0 0x80000000>; /* mem */ | ||
| 441 | dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 | ||
| 442 | 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; | ||
| 443 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
| 444 | interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xda 0x1 | ||
| 445 | 0x0 0x0 0x0 0x2 &gic 0x0 0xdb 0x1 | ||
| 446 | 0x0 0x0 0x0 0x3 &gic 0x0 0xdc 0x1 | ||
| 447 | 0x0 0x0 0x0 0x4 &gic 0x0 0xdd 0x1>; | ||
| 448 | dma-coherent; | ||
| 449 | clocks = <&pcie4clk 0>; | ||
| 285 | }; | 450 | }; |
| 286 | 451 | ||
| 287 | serial0: serial@1c020000 { | 452 | serial0: serial@1c020000 { |
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index c1968475cc4e..774a7c85e70f 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild | |||
| @@ -29,6 +29,7 @@ generic-y += mman.h | |||
| 29 | generic-y += msgbuf.h | 29 | generic-y += msgbuf.h |
| 30 | generic-y += mutex.h | 30 | generic-y += mutex.h |
| 31 | generic-y += pci.h | 31 | generic-y += pci.h |
| 32 | generic-y += pci-bridge.h | ||
| 32 | generic-y += poll.h | 33 | generic-y += poll.h |
| 33 | generic-y += preempt.h | 34 | generic-y += preempt.h |
| 34 | generic-y += resource.h | 35 | generic-y += resource.h |
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index f771e8bcad4a..79f1d519221f 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h | |||
| @@ -121,7 +121,8 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) | |||
| 121 | /* | 121 | /* |
| 122 | * I/O port access primitives. | 122 | * I/O port access primitives. |
| 123 | */ | 123 | */ |
| 124 | #define IO_SPACE_LIMIT 0xffff | 124 | #define arch_has_dev_port() (1) |
| 125 | #define IO_SPACE_LIMIT (SZ_32M - 1) | ||
| 125 | #define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_32M)) | 126 | #define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_32M)) |
| 126 | 127 | ||
| 127 | static inline u8 inb(unsigned long addr) | 128 | static inline u8 inb(unsigned long addr) |
diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h new file mode 100644 index 000000000000..872ba939fcb2 --- /dev/null +++ b/arch/arm64/include/asm/pci.h | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | #ifndef __ASM_PCI_H | ||
| 2 | #define __ASM_PCI_H | ||
| 3 | #ifdef __KERNEL__ | ||
| 4 | |||
| 5 | #include <linux/types.h> | ||
| 6 | #include <linux/slab.h> | ||
| 7 | #include <linux/dma-mapping.h> | ||
| 8 | |||
| 9 | #include <asm/io.h> | ||
| 10 | #include <asm-generic/pci-bridge.h> | ||
| 11 | #include <asm-generic/pci-dma-compat.h> | ||
| 12 | |||
| 13 | #define PCIBIOS_MIN_IO 0x1000 | ||
| 14 | #define PCIBIOS_MIN_MEM 0 | ||
| 15 | |||
| 16 | /* | ||
| 17 | * Set to 1 if the kernel should re-assign all PCI bus numbers | ||
| 18 | */ | ||
| 19 | #define pcibios_assign_all_busses() \ | ||
| 20 | (pci_has_flag(PCI_REASSIGN_ALL_BUS)) | ||
| 21 | |||
| 22 | /* | ||
| 23 | * PCI address space differs from physical memory address space | ||
| 24 | */ | ||
| 25 | #define PCI_DMA_BUS_IS_PHYS (0) | ||
| 26 | |||
| 27 | extern int isa_dma_bridge_buggy; | ||
| 28 | |||
| 29 | #ifdef CONFIG_PCI | ||
| 30 | static inline int pci_proc_domain(struct pci_bus *bus) | ||
| 31 | { | ||
| 32 | return 1; | ||
| 33 | } | ||
| 34 | #endif /* CONFIG_PCI */ | ||
| 35 | |||
| 36 | #endif /* __KERNEL__ */ | ||
| 37 | #endif /* __ASM_PCI_H */ | ||
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index d58e40cde88e..77dbe1e6398d 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h | |||
| @@ -301,6 +301,8 @@ static inline int has_transparent_hugepage(void) | |||
| 301 | __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN) | 301 | __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN) |
| 302 | #define pgprot_writecombine(prot) \ | 302 | #define pgprot_writecombine(prot) \ |
| 303 | __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN) | 303 | __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN) |
| 304 | #define pgprot_device(prot) \ | ||
| 305 | __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN) | ||
| 304 | #define __HAVE_PHYS_MEM_ACCESS_PROT | 306 | #define __HAVE_PHYS_MEM_ACCESS_PROT |
| 305 | struct file; | 307 | struct file; |
| 306 | extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | 308 | extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, |
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 6e9538c2d28a..5bd029b43644 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile | |||
| @@ -30,6 +30,7 @@ arm64-obj-$(CONFIG_CPU_IDLE) += cpuidle.o | |||
| 30 | arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o | 30 | arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o |
| 31 | arm64-obj-$(CONFIG_KGDB) += kgdb.o | 31 | arm64-obj-$(CONFIG_KGDB) += kgdb.o |
| 32 | arm64-obj-$(CONFIG_EFI) += efi.o efi-stub.o efi-entry.o | 32 | arm64-obj-$(CONFIG_EFI) += efi.o efi-stub.o efi-entry.o |
| 33 | arm64-obj-$(CONFIG_PCI) += pci.o | ||
| 33 | 34 | ||
| 34 | obj-y += $(arm64-obj-y) vdso/ | 35 | obj-y += $(arm64-obj-y) vdso/ |
| 35 | obj-m += $(arm64-obj-m) | 36 | obj-m += $(arm64-obj-m) |
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c new file mode 100644 index 000000000000..ce5836c14ec1 --- /dev/null +++ b/arch/arm64/kernel/pci.c | |||
| @@ -0,0 +1,70 @@ | |||
| 1 | /* | ||
| 2 | * Code borrowed from powerpc/kernel/pci-common.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM | ||
| 5 | * Copyright (C) 2014 ARM Ltd. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * version 2 as published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/io.h> | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/mm.h> | ||
| 17 | #include <linux/of_pci.h> | ||
| 18 | #include <linux/of_platform.h> | ||
| 19 | #include <linux/slab.h> | ||
| 20 | |||
| 21 | #include <asm/pci-bridge.h> | ||
| 22 | |||
| 23 | /* | ||
| 24 | * Called after each bus is probed, but before its children are examined | ||
| 25 | */ | ||
| 26 | void pcibios_fixup_bus(struct pci_bus *bus) | ||
| 27 | { | ||
| 28 | /* nothing to do, expected to be removed in the future */ | ||
| 29 | } | ||
| 30 | |||
| 31 | /* | ||
| 32 | * We don't have to worry about legacy ISA devices, so nothing to do here | ||
| 33 | */ | ||
| 34 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, | ||
| 35 | resource_size_t size, resource_size_t align) | ||
| 36 | { | ||
| 37 | return res->start; | ||
| 38 | } | ||
| 39 | |||
| 40 | /* | ||
| 41 | * Try to assign the IRQ number from DT when adding a new device | ||
| 42 | */ | ||
| 43 | int pcibios_add_device(struct pci_dev *dev) | ||
| 44 | { | ||
| 45 | dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); | ||
| 46 | |||
| 47 | return 0; | ||
| 48 | } | ||
| 49 | |||
| 50 | |||
| 51 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | ||
| 52 | static bool dt_domain_found = false; | ||
| 53 | |||
| 54 | void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent) | ||
| 55 | { | ||
| 56 | int domain = of_get_pci_domain_nr(parent->of_node); | ||
| 57 | |||
| 58 | if (domain >= 0) { | ||
| 59 | dt_domain_found = true; | ||
| 60 | } else if (dt_domain_found == true) { | ||
| 61 | dev_err(parent, "Node %s is missing \"linux,pci-domain\" property in DT\n", | ||
| 62 | parent->of_node->full_name); | ||
| 63 | return; | ||
| 64 | } else { | ||
| 65 | domain = pci_get_new_domain_nr(); | ||
| 66 | } | ||
| 67 | |||
| 68 | bus->domain_nr = domain; | ||
| 69 | } | ||
| 70 | #endif | ||
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c index c430f9198d1b..8c3730c3c63d 100644 --- a/arch/ia64/kernel/msi_ia64.c +++ b/arch/ia64/kernel/msi_ia64.c | |||
| @@ -23,7 +23,7 @@ static int ia64_set_msi_irq_affinity(struct irq_data *idata, | |||
| 23 | if (irq_prepare_move(irq, cpu)) | 23 | if (irq_prepare_move(irq, cpu)) |
| 24 | return -1; | 24 | return -1; |
| 25 | 25 | ||
| 26 | get_cached_msi_msg(irq, &msg); | 26 | __get_cached_msi_msg(idata->msi_desc, &msg); |
| 27 | 27 | ||
| 28 | addr = msg.address_lo; | 28 | addr = msg.address_lo; |
| 29 | addr &= MSI_ADDR_DEST_ID_MASK; | 29 | addr &= MSI_ADDR_DEST_ID_MASK; |
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c index afc58d2799ad..446e7799928c 100644 --- a/arch/ia64/sn/kernel/msi_sn.c +++ b/arch/ia64/sn/kernel/msi_sn.c | |||
| @@ -175,8 +175,8 @@ static int sn_set_msi_irq_affinity(struct irq_data *data, | |||
| 175 | * Release XIO resources for the old MSI PCI address | 175 | * Release XIO resources for the old MSI PCI address |
| 176 | */ | 176 | */ |
| 177 | 177 | ||
| 178 | get_cached_msi_msg(irq, &msg); | 178 | __get_cached_msi_msg(data->msi_desc, &msg); |
| 179 | sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; | 179 | sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; |
| 180 | pdev = sn_pdev->pdi_linux_pcidev; | 180 | pdev = sn_pdev->pdi_linux_pcidev; |
| 181 | provider = SN_PCIDEV_BUSPROVIDER(pdev); | 181 | provider = SN_PCIDEV_BUSPROVIDER(pdev); |
| 182 | 182 | ||
diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c index ab0c5d14c6f7..63bbe07a1ccd 100644 --- a/arch/mips/pci/msi-octeon.c +++ b/arch/mips/pci/msi-octeon.c | |||
| @@ -73,8 +73,7 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) | |||
| 73 | * wants. Most devices only want 1, which will give | 73 | * wants. Most devices only want 1, which will give |
| 74 | * configured_private_bits and request_private_bits equal 0. | 74 | * configured_private_bits and request_private_bits equal 0. |
| 75 | */ | 75 | */ |
| 76 | pci_read_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS, | 76 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); |
| 77 | &control); | ||
| 78 | 77 | ||
| 79 | /* | 78 | /* |
| 80 | * If the number of private bits has been configured then use | 79 | * If the number of private bits has been configured then use |
| @@ -176,8 +175,7 @@ msi_irq_allocated: | |||
| 176 | /* Update the number of IRQs the device has available to it */ | 175 | /* Update the number of IRQs the device has available to it */ |
| 177 | control &= ~PCI_MSI_FLAGS_QSIZE; | 176 | control &= ~PCI_MSI_FLAGS_QSIZE; |
| 178 | control |= request_private_bits << 4; | 177 | control |= request_private_bits << 4; |
| 179 | pci_write_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS, | 178 | pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); |
| 180 | control); | ||
| 181 | 179 | ||
| 182 | irq_set_msi_desc(irq, desc); | 180 | irq_set_msi_desc(irq, desc); |
| 183 | write_msi_msg(irq, &msg); | 181 | write_msi_msg(irq, &msg); |
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index b125ceab149c..3af721633618 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h | |||
| @@ -136,8 +136,6 @@ struct machdep_calls { | |||
| 136 | int (*pci_setup_phb)(struct pci_controller *host); | 136 | int (*pci_setup_phb)(struct pci_controller *host); |
| 137 | 137 | ||
| 138 | #ifdef CONFIG_PCI_MSI | 138 | #ifdef CONFIG_PCI_MSI |
| 139 | int (*msi_check_device)(struct pci_dev* dev, | ||
| 140 | int nvec, int type); | ||
| 141 | int (*setup_msi_irqs)(struct pci_dev *dev, | 139 | int (*setup_msi_irqs)(struct pci_dev *dev, |
| 142 | int nvec, int type); | 140 | int nvec, int type); |
| 143 | void (*teardown_msi_irqs)(struct pci_dev *dev); | 141 | void (*teardown_msi_irqs)(struct pci_dev *dev); |
diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c index 8bbc12d20f5c..71bd161640cf 100644 --- a/arch/powerpc/kernel/msi.c +++ b/arch/powerpc/kernel/msi.c | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | #include <asm/machdep.h> | 14 | #include <asm/machdep.h> |
| 15 | 15 | ||
| 16 | int arch_msi_check_device(struct pci_dev* dev, int nvec, int type) | 16 | int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) |
| 17 | { | 17 | { |
| 18 | if (!ppc_md.setup_msi_irqs || !ppc_md.teardown_msi_irqs) { | 18 | if (!ppc_md.setup_msi_irqs || !ppc_md.teardown_msi_irqs) { |
| 19 | pr_debug("msi: Platform doesn't provide MSI callbacks.\n"); | 19 | pr_debug("msi: Platform doesn't provide MSI callbacks.\n"); |
| @@ -24,16 +24,6 @@ int arch_msi_check_device(struct pci_dev* dev, int nvec, int type) | |||
| 24 | if (type == PCI_CAP_ID_MSI && nvec > 1) | 24 | if (type == PCI_CAP_ID_MSI && nvec > 1) |
| 25 | return 1; | 25 | return 1; |
| 26 | 26 | ||
| 27 | if (ppc_md.msi_check_device) { | ||
| 28 | pr_debug("msi: Using platform check routine.\n"); | ||
| 29 | return ppc_md.msi_check_device(dev, nvec, type); | ||
| 30 | } | ||
| 31 | |||
| 32 | return 0; | ||
| 33 | } | ||
| 34 | |||
| 35 | int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | ||
| 36 | { | ||
| 37 | return ppc_md.setup_msi_irqs(dev, nvec, type); | 27 | return ppc_md.setup_msi_irqs(dev, nvec, type); |
| 38 | } | 28 | } |
| 39 | 29 | ||
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 85825b5401e5..862b32702d29 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c | |||
| @@ -199,14 +199,6 @@ out_error: | |||
| 199 | return msic; | 199 | return msic; |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | static int axon_msi_check_device(struct pci_dev *dev, int nvec, int type) | ||
| 203 | { | ||
| 204 | if (!find_msi_translator(dev)) | ||
| 205 | return -ENODEV; | ||
| 206 | |||
| 207 | return 0; | ||
| 208 | } | ||
| 209 | |||
| 210 | static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg) | 202 | static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg) |
| 211 | { | 203 | { |
| 212 | struct device_node *dn; | 204 | struct device_node *dn; |
| @@ -416,7 +408,6 @@ static int axon_msi_probe(struct platform_device *device) | |||
| 416 | 408 | ||
| 417 | ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs; | 409 | ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs; |
| 418 | ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs; | 410 | ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs; |
| 419 | ppc_md.msi_check_device = axon_msi_check_device; | ||
| 420 | 411 | ||
| 421 | axon_msi_debug_setup(dn, msic); | 412 | axon_msi_debug_setup(dn, msic); |
| 422 | 413 | ||
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index b854b57ed5e1..b45c49249a5d 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
| @@ -46,29 +46,21 @@ | |||
| 46 | //#define cfg_dbg(fmt...) printk(fmt) | 46 | //#define cfg_dbg(fmt...) printk(fmt) |
| 47 | 47 | ||
| 48 | #ifdef CONFIG_PCI_MSI | 48 | #ifdef CONFIG_PCI_MSI |
| 49 | static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type) | ||
| 50 | { | ||
| 51 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | ||
| 52 | struct pnv_phb *phb = hose->private_data; | ||
| 53 | struct pci_dn *pdn = pci_get_pdn(pdev); | ||
| 54 | |||
| 55 | if (pdn && pdn->force_32bit_msi && !phb->msi32_support) | ||
| 56 | return -ENODEV; | ||
| 57 | |||
| 58 | return (phb && phb->msi_bmp.bitmap) ? 0 : -ENODEV; | ||
| 59 | } | ||
| 60 | |||
| 61 | static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | 49 | static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) |
| 62 | { | 50 | { |
| 63 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | 51 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); |
| 64 | struct pnv_phb *phb = hose->private_data; | 52 | struct pnv_phb *phb = hose->private_data; |
| 53 | struct pci_dn *pdn = pci_get_pdn(pdev); | ||
| 65 | struct msi_desc *entry; | 54 | struct msi_desc *entry; |
| 66 | struct msi_msg msg; | 55 | struct msi_msg msg; |
| 67 | int hwirq; | 56 | int hwirq; |
| 68 | unsigned int virq; | 57 | unsigned int virq; |
| 69 | int rc; | 58 | int rc; |
| 70 | 59 | ||
| 71 | if (WARN_ON(!phb)) | 60 | if (WARN_ON(!phb) || !phb->msi_bmp.bitmap) |
| 61 | return -ENODEV; | ||
| 62 | |||
| 63 | if (pdn && pdn->force_32bit_msi && !phb->msi32_support) | ||
| 72 | return -ENODEV; | 64 | return -ENODEV; |
| 73 | 65 | ||
| 74 | list_for_each_entry(entry, &pdev->msi_list, list) { | 66 | list_for_each_entry(entry, &pdev->msi_list, list) { |
| @@ -860,7 +852,6 @@ void __init pnv_pci_init(void) | |||
| 860 | 852 | ||
| 861 | /* Configure MSIs */ | 853 | /* Configure MSIs */ |
| 862 | #ifdef CONFIG_PCI_MSI | 854 | #ifdef CONFIG_PCI_MSI |
| 863 | ppc_md.msi_check_device = pnv_msi_check_device; | ||
| 864 | ppc_md.setup_msi_irqs = pnv_setup_msi_irqs; | 855 | ppc_md.setup_msi_irqs = pnv_setup_msi_irqs; |
| 865 | ppc_md.teardown_msi_irqs = pnv_teardown_msi_irqs; | 856 | ppc_md.teardown_msi_irqs = pnv_teardown_msi_irqs; |
| 866 | #endif | 857 | #endif |
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index 18ff4626d74e..8ab5add4ac82 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c | |||
| @@ -336,26 +336,6 @@ out: | |||
| 336 | return request; | 336 | return request; |
| 337 | } | 337 | } |
| 338 | 338 | ||
| 339 | static int rtas_msi_check_device(struct pci_dev *pdev, int nvec, int type) | ||
| 340 | { | ||
| 341 | int quota, rc; | ||
| 342 | |||
| 343 | if (type == PCI_CAP_ID_MSIX) | ||
| 344 | rc = check_req_msix(pdev, nvec); | ||
| 345 | else | ||
| 346 | rc = check_req_msi(pdev, nvec); | ||
| 347 | |||
| 348 | if (rc) | ||
| 349 | return rc; | ||
| 350 | |||
| 351 | quota = msi_quota_for_device(pdev, nvec); | ||
| 352 | |||
| 353 | if (quota && quota < nvec) | ||
| 354 | return quota; | ||
| 355 | |||
| 356 | return 0; | ||
| 357 | } | ||
| 358 | |||
| 359 | static int check_msix_entries(struct pci_dev *pdev) | 339 | static int check_msix_entries(struct pci_dev *pdev) |
| 360 | { | 340 | { |
| 361 | struct msi_desc *entry; | 341 | struct msi_desc *entry; |
| @@ -397,15 +377,24 @@ static void rtas_hack_32bit_msi_gen2(struct pci_dev *pdev) | |||
| 397 | static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) | 377 | static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) |
| 398 | { | 378 | { |
| 399 | struct pci_dn *pdn; | 379 | struct pci_dn *pdn; |
| 400 | int hwirq, virq, i, rc; | 380 | int hwirq, virq, i, quota, rc; |
| 401 | struct msi_desc *entry; | 381 | struct msi_desc *entry; |
| 402 | struct msi_msg msg; | 382 | struct msi_msg msg; |
| 403 | int nvec = nvec_in; | 383 | int nvec = nvec_in; |
| 404 | int use_32bit_msi_hack = 0; | 384 | int use_32bit_msi_hack = 0; |
| 405 | 385 | ||
| 406 | pdn = pci_get_pdn(pdev); | 386 | if (type == PCI_CAP_ID_MSIX) |
| 407 | if (!pdn) | 387 | rc = check_req_msix(pdev, nvec); |
| 408 | return -ENODEV; | 388 | else |
| 389 | rc = check_req_msi(pdev, nvec); | ||
| 390 | |||
| 391 | if (rc) | ||
| 392 | return rc; | ||
| 393 | |||
| 394 | quota = msi_quota_for_device(pdev, nvec); | ||
| 395 | |||
| 396 | if (quota && quota < nvec) | ||
| 397 | return quota; | ||
| 409 | 398 | ||
| 410 | if (type == PCI_CAP_ID_MSIX && check_msix_entries(pdev)) | 399 | if (type == PCI_CAP_ID_MSIX && check_msix_entries(pdev)) |
| 411 | return -EINVAL; | 400 | return -EINVAL; |
| @@ -416,12 +405,14 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) | |||
| 416 | */ | 405 | */ |
| 417 | if (type == PCI_CAP_ID_MSIX) { | 406 | if (type == PCI_CAP_ID_MSIX) { |
| 418 | int m = roundup_pow_of_two(nvec); | 407 | int m = roundup_pow_of_two(nvec); |
| 419 | int quota = msi_quota_for_device(pdev, m); | 408 | quota = msi_quota_for_device(pdev, m); |
| 420 | 409 | ||
| 421 | if (quota >= m) | 410 | if (quota >= m) |
| 422 | nvec = m; | 411 | nvec = m; |
| 423 | } | 412 | } |
| 424 | 413 | ||
| 414 | pdn = pci_get_pdn(pdev); | ||
| 415 | |||
| 425 | /* | 416 | /* |
| 426 | * Try the new more explicit firmware interface, if that fails fall | 417 | * Try the new more explicit firmware interface, if that fails fall |
| 427 | * back to the old interface. The old interface is known to never | 418 | * back to the old interface. The old interface is known to never |
| @@ -485,7 +476,7 @@ again: | |||
| 485 | irq_set_msi_desc(virq, entry); | 476 | irq_set_msi_desc(virq, entry); |
| 486 | 477 | ||
| 487 | /* Read config space back so we can restore after reset */ | 478 | /* Read config space back so we can restore after reset */ |
| 488 | read_msi_msg(virq, &msg); | 479 | __read_msi_msg(entry, &msg); |
| 489 | entry->msg = msg; | 480 | entry->msg = msg; |
| 490 | } | 481 | } |
| 491 | 482 | ||
| @@ -526,7 +517,6 @@ static int rtas_msi_init(void) | |||
| 526 | WARN_ON(ppc_md.setup_msi_irqs); | 517 | WARN_ON(ppc_md.setup_msi_irqs); |
| 527 | ppc_md.setup_msi_irqs = rtas_setup_msi_irqs; | 518 | ppc_md.setup_msi_irqs = rtas_setup_msi_irqs; |
| 528 | ppc_md.teardown_msi_irqs = rtas_teardown_msi_irqs; | 519 | ppc_md.teardown_msi_irqs = rtas_teardown_msi_irqs; |
| 529 | ppc_md.msi_check_device = rtas_msi_check_device; | ||
| 530 | 520 | ||
| 531 | WARN_ON(ppc_md.pci_irq_fixup); | 521 | WARN_ON(ppc_md.pci_irq_fixup); |
| 532 | ppc_md.pci_irq_fixup = rtas_msi_pci_irq_fixup; | 522 | ppc_md.pci_irq_fixup = rtas_msi_pci_irq_fixup; |
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 77efbaec7b9c..b32e79dbef4f 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c | |||
| @@ -109,14 +109,6 @@ static int fsl_msi_init_allocator(struct fsl_msi *msi_data) | |||
| 109 | return 0; | 109 | return 0; |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type) | ||
| 113 | { | ||
| 114 | if (type == PCI_CAP_ID_MSIX) | ||
| 115 | pr_debug("fslmsi: MSI-X untested, trying anyway.\n"); | ||
| 116 | |||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | |||
| 120 | static void fsl_teardown_msi_irqs(struct pci_dev *pdev) | 112 | static void fsl_teardown_msi_irqs(struct pci_dev *pdev) |
| 121 | { | 113 | { |
| 122 | struct msi_desc *entry; | 114 | struct msi_desc *entry; |
| @@ -173,6 +165,9 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
| 173 | struct msi_msg msg; | 165 | struct msi_msg msg; |
| 174 | struct fsl_msi *msi_data; | 166 | struct fsl_msi *msi_data; |
| 175 | 167 | ||
| 168 | if (type == PCI_CAP_ID_MSIX) | ||
| 169 | pr_debug("fslmsi: MSI-X untested, trying anyway.\n"); | ||
| 170 | |||
| 176 | /* | 171 | /* |
| 177 | * If the PCI node has an fsl,msi property, then we need to use it | 172 | * If the PCI node has an fsl,msi property, then we need to use it |
| 178 | * to find the specific MSI. | 173 | * to find the specific MSI. |
| @@ -527,7 +522,6 @@ static int fsl_of_msi_probe(struct platform_device *dev) | |||
| 527 | if (!ppc_md.setup_msi_irqs) { | 522 | if (!ppc_md.setup_msi_irqs) { |
| 528 | ppc_md.setup_msi_irqs = fsl_setup_msi_irqs; | 523 | ppc_md.setup_msi_irqs = fsl_setup_msi_irqs; |
| 529 | ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs; | 524 | ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs; |
| 530 | ppc_md.msi_check_device = fsl_msi_check_device; | ||
| 531 | } else if (ppc_md.setup_msi_irqs != fsl_setup_msi_irqs) { | 525 | } else if (ppc_md.setup_msi_irqs != fsl_setup_msi_irqs) { |
| 532 | dev_err(&dev->dev, "Different MSI driver already installed!\n"); | 526 | dev_err(&dev->dev, "Different MSI driver already installed!\n"); |
| 533 | err = -ENODEV; | 527 | err = -ENODEV; |
diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c index 38e62382070c..15dccd35fa11 100644 --- a/arch/powerpc/sysdev/mpic_pasemi_msi.c +++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c | |||
| @@ -63,14 +63,6 @@ static struct irq_chip mpic_pasemi_msi_chip = { | |||
| 63 | .name = "PASEMI-MSI", | 63 | .name = "PASEMI-MSI", |
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| 66 | static int pasemi_msi_check_device(struct pci_dev *pdev, int nvec, int type) | ||
| 67 | { | ||
| 68 | if (type == PCI_CAP_ID_MSIX) | ||
| 69 | pr_debug("pasemi_msi: MSI-X untested, trying anyway\n"); | ||
| 70 | |||
| 71 | return 0; | ||
| 72 | } | ||
| 73 | |||
| 74 | static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev) | 66 | static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev) |
| 75 | { | 67 | { |
| 76 | struct msi_desc *entry; | 68 | struct msi_desc *entry; |
| @@ -97,6 +89,8 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
| 97 | struct msi_msg msg; | 89 | struct msi_msg msg; |
| 98 | int hwirq; | 90 | int hwirq; |
| 99 | 91 | ||
| 92 | if (type == PCI_CAP_ID_MSIX) | ||
| 93 | pr_debug("pasemi_msi: MSI-X untested, trying anyway\n"); | ||
| 100 | pr_debug("pasemi_msi_setup_msi_irqs, pdev %p nvec %d type %d\n", | 94 | pr_debug("pasemi_msi_setup_msi_irqs, pdev %p nvec %d type %d\n", |
| 101 | pdev, nvec, type); | 95 | pdev, nvec, type); |
| 102 | 96 | ||
| @@ -169,7 +163,6 @@ int mpic_pasemi_msi_init(struct mpic *mpic) | |||
| 169 | WARN_ON(ppc_md.setup_msi_irqs); | 163 | WARN_ON(ppc_md.setup_msi_irqs); |
| 170 | ppc_md.setup_msi_irqs = pasemi_msi_setup_msi_irqs; | 164 | ppc_md.setup_msi_irqs = pasemi_msi_setup_msi_irqs; |
| 171 | ppc_md.teardown_msi_irqs = pasemi_msi_teardown_msi_irqs; | 165 | ppc_md.teardown_msi_irqs = pasemi_msi_teardown_msi_irqs; |
| 172 | ppc_md.msi_check_device = pasemi_msi_check_device; | ||
| 173 | 166 | ||
| 174 | return 0; | 167 | return 0; |
| 175 | } | 168 | } |
diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c index 9a7aa0ed9c1c..623d7fba15b4 100644 --- a/arch/powerpc/sysdev/mpic_u3msi.c +++ b/arch/powerpc/sysdev/mpic_u3msi.c | |||
| @@ -105,22 +105,6 @@ static u64 find_u4_magic_addr(struct pci_dev *pdev, unsigned int hwirq) | |||
| 105 | return 0; | 105 | return 0; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | static int u3msi_msi_check_device(struct pci_dev *pdev, int nvec, int type) | ||
| 109 | { | ||
| 110 | if (type == PCI_CAP_ID_MSIX) | ||
| 111 | pr_debug("u3msi: MSI-X untested, trying anyway.\n"); | ||
| 112 | |||
| 113 | /* If we can't find a magic address then MSI ain't gonna work */ | ||
| 114 | if (find_ht_magic_addr(pdev, 0) == 0 && | ||
| 115 | find_u4_magic_addr(pdev, 0) == 0) { | ||
| 116 | pr_debug("u3msi: no magic address found for %s\n", | ||
| 117 | pci_name(pdev)); | ||
| 118 | return -ENXIO; | ||
| 119 | } | ||
| 120 | |||
| 121 | return 0; | ||
| 122 | } | ||
| 123 | |||
| 124 | static void u3msi_teardown_msi_irqs(struct pci_dev *pdev) | 108 | static void u3msi_teardown_msi_irqs(struct pci_dev *pdev) |
| 125 | { | 109 | { |
| 126 | struct msi_desc *entry; | 110 | struct msi_desc *entry; |
| @@ -146,6 +130,17 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
| 146 | u64 addr; | 130 | u64 addr; |
| 147 | int hwirq; | 131 | int hwirq; |
| 148 | 132 | ||
| 133 | if (type == PCI_CAP_ID_MSIX) | ||
| 134 | pr_debug("u3msi: MSI-X untested, trying anyway.\n"); | ||
| 135 | |||
| 136 | /* If we can't find a magic address then MSI ain't gonna work */ | ||
| 137 | if (find_ht_magic_addr(pdev, 0) == 0 && | ||
| 138 | find_u4_magic_addr(pdev, 0) == 0) { | ||
| 139 | pr_debug("u3msi: no magic address found for %s\n", | ||
| 140 | pci_name(pdev)); | ||
| 141 | return -ENXIO; | ||
| 142 | } | ||
| 143 | |||
| 149 | list_for_each_entry(entry, &pdev->msi_list, list) { | 144 | list_for_each_entry(entry, &pdev->msi_list, list) { |
| 150 | hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1); | 145 | hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1); |
| 151 | if (hwirq < 0) { | 146 | if (hwirq < 0) { |
| @@ -202,7 +197,6 @@ int mpic_u3msi_init(struct mpic *mpic) | |||
| 202 | WARN_ON(ppc_md.setup_msi_irqs); | 197 | WARN_ON(ppc_md.setup_msi_irqs); |
| 203 | ppc_md.setup_msi_irqs = u3msi_setup_msi_irqs; | 198 | ppc_md.setup_msi_irqs = u3msi_setup_msi_irqs; |
| 204 | ppc_md.teardown_msi_irqs = u3msi_teardown_msi_irqs; | 199 | ppc_md.teardown_msi_irqs = u3msi_teardown_msi_irqs; |
| 205 | ppc_md.msi_check_device = u3msi_msi_check_device; | ||
| 206 | 200 | ||
| 207 | return 0; | 201 | return 0; |
| 208 | } | 202 | } |
diff --git a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c index 11c888416f0a..a6a4dbda9078 100644 --- a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c +++ b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c | |||
| @@ -44,6 +44,12 @@ static int hsta_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
| 44 | int irq, hwirq; | 44 | int irq, hwirq; |
| 45 | u64 addr; | 45 | u64 addr; |
| 46 | 46 | ||
| 47 | /* We don't support MSI-X */ | ||
| 48 | if (type == PCI_CAP_ID_MSIX) { | ||
| 49 | pr_debug("%s: MSI-X not supported.\n", __func__); | ||
| 50 | return -EINVAL; | ||
| 51 | } | ||
| 52 | |||
| 47 | list_for_each_entry(entry, &dev->msi_list, list) { | 53 | list_for_each_entry(entry, &dev->msi_list, list) { |
| 48 | irq = msi_bitmap_alloc_hwirqs(&ppc4xx_hsta_msi.bmp, 1); | 54 | irq = msi_bitmap_alloc_hwirqs(&ppc4xx_hsta_msi.bmp, 1); |
| 49 | if (irq < 0) { | 55 | if (irq < 0) { |
| @@ -117,17 +123,6 @@ static void hsta_teardown_msi_irqs(struct pci_dev *dev) | |||
| 117 | } | 123 | } |
| 118 | } | 124 | } |
| 119 | 125 | ||
| 120 | static int hsta_msi_check_device(struct pci_dev *pdev, int nvec, int type) | ||
| 121 | { | ||
| 122 | /* We don't support MSI-X */ | ||
| 123 | if (type == PCI_CAP_ID_MSIX) { | ||
| 124 | pr_debug("%s: MSI-X not supported.\n", __func__); | ||
| 125 | return -EINVAL; | ||
| 126 | } | ||
| 127 | |||
| 128 | return 0; | ||
| 129 | } | ||
| 130 | |||
| 131 | static int hsta_msi_probe(struct platform_device *pdev) | 126 | static int hsta_msi_probe(struct platform_device *pdev) |
| 132 | { | 127 | { |
| 133 | struct device *dev = &pdev->dev; | 128 | struct device *dev = &pdev->dev; |
| @@ -178,7 +173,6 @@ static int hsta_msi_probe(struct platform_device *pdev) | |||
| 178 | 173 | ||
| 179 | ppc_md.setup_msi_irqs = hsta_setup_msi_irqs; | 174 | ppc_md.setup_msi_irqs = hsta_setup_msi_irqs; |
| 180 | ppc_md.teardown_msi_irqs = hsta_teardown_msi_irqs; | 175 | ppc_md.teardown_msi_irqs = hsta_teardown_msi_irqs; |
| 181 | ppc_md.msi_check_device = hsta_msi_check_device; | ||
| 182 | return 0; | 176 | return 0; |
| 183 | 177 | ||
| 184 | out2: | 178 | out2: |
diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/sysdev/ppc4xx_msi.c index 43948da837a7..22b5200636e7 100644 --- a/arch/powerpc/sysdev/ppc4xx_msi.c +++ b/arch/powerpc/sysdev/ppc4xx_msi.c | |||
| @@ -85,8 +85,12 @@ static int ppc4xx_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
| 85 | struct msi_desc *entry; | 85 | struct msi_desc *entry; |
| 86 | struct ppc4xx_msi *msi_data = &ppc4xx_msi; | 86 | struct ppc4xx_msi *msi_data = &ppc4xx_msi; |
| 87 | 87 | ||
| 88 | msi_data->msi_virqs = kmalloc((msi_irqs) * sizeof(int), | 88 | dev_dbg(&dev->dev, "PCIE-MSI:%s called. vec %x type %d\n", |
| 89 | GFP_KERNEL); | 89 | __func__, nvec, type); |
| 90 | if (type == PCI_CAP_ID_MSIX) | ||
| 91 | pr_debug("ppc4xx msi: MSI-X untested, trying anyway.\n"); | ||
| 92 | |||
| 93 | msi_data->msi_virqs = kmalloc((msi_irqs) * sizeof(int), GFP_KERNEL); | ||
| 90 | if (!msi_data->msi_virqs) | 94 | if (!msi_data->msi_virqs) |
| 91 | return -ENOMEM; | 95 | return -ENOMEM; |
| 92 | 96 | ||
| @@ -134,16 +138,6 @@ void ppc4xx_teardown_msi_irqs(struct pci_dev *dev) | |||
| 134 | } | 138 | } |
| 135 | } | 139 | } |
| 136 | 140 | ||
| 137 | static int ppc4xx_msi_check_device(struct pci_dev *pdev, int nvec, int type) | ||
| 138 | { | ||
| 139 | dev_dbg(&pdev->dev, "PCIE-MSI:%s called. vec %x type %d\n", | ||
| 140 | __func__, nvec, type); | ||
| 141 | if (type == PCI_CAP_ID_MSIX) | ||
| 142 | pr_debug("ppc4xx msi: MSI-X untested, trying anyway.\n"); | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | static int ppc4xx_setup_pcieh_hw(struct platform_device *dev, | 141 | static int ppc4xx_setup_pcieh_hw(struct platform_device *dev, |
| 148 | struct resource res, struct ppc4xx_msi *msi) | 142 | struct resource res, struct ppc4xx_msi *msi) |
| 149 | { | 143 | { |
| @@ -259,7 +253,6 @@ static int ppc4xx_msi_probe(struct platform_device *dev) | |||
| 259 | 253 | ||
| 260 | ppc_md.setup_msi_irqs = ppc4xx_setup_msi_irqs; | 254 | ppc_md.setup_msi_irqs = ppc4xx_setup_msi_irqs; |
| 261 | ppc_md.teardown_msi_irqs = ppc4xx_teardown_msi_irqs; | 255 | ppc_md.teardown_msi_irqs = ppc4xx_teardown_msi_irqs; |
| 262 | ppc_md.msi_check_device = ppc4xx_msi_check_device; | ||
| 263 | return err; | 256 | return err; |
| 264 | 257 | ||
| 265 | error_out: | 258 | error_out: |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 059a76c29739..7b20bccf3648 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
| @@ -81,14 +81,14 @@ struct pci_ops pci_root_ops = { | |||
| 81 | */ | 81 | */ |
| 82 | DEFINE_RAW_SPINLOCK(pci_config_lock); | 82 | DEFINE_RAW_SPINLOCK(pci_config_lock); |
| 83 | 83 | ||
| 84 | static int can_skip_ioresource_align(const struct dmi_system_id *d) | 84 | static int __init can_skip_ioresource_align(const struct dmi_system_id *d) |
| 85 | { | 85 | { |
| 86 | pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; | 86 | pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; |
| 87 | printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident); | 87 | printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident); |
| 88 | return 0; | 88 | return 0; |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | static const struct dmi_system_id can_skip_pciprobe_dmi_table[] = { | 91 | static const struct dmi_system_id can_skip_pciprobe_dmi_table[] __initconst = { |
| 92 | /* | 92 | /* |
| 93 | * Systems where PCI IO resource ISA alignment can be skipped | 93 | * Systems where PCI IO resource ISA alignment can be skipped |
| 94 | * when the ISA enable bit in the bridge control is not set | 94 | * when the ISA enable bit in the bridge control is not set |
| @@ -186,7 +186,7 @@ void pcibios_remove_bus(struct pci_bus *bus) | |||
| 186 | * on the kernel command line (which was parsed earlier). | 186 | * on the kernel command line (which was parsed earlier). |
| 187 | */ | 187 | */ |
| 188 | 188 | ||
| 189 | static int set_bf_sort(const struct dmi_system_id *d) | 189 | static int __init set_bf_sort(const struct dmi_system_id *d) |
| 190 | { | 190 | { |
| 191 | if (pci_bf_sort == pci_bf_sort_default) { | 191 | if (pci_bf_sort == pci_bf_sort_default) { |
| 192 | pci_bf_sort = pci_dmi_bf; | 192 | pci_bf_sort = pci_dmi_bf; |
| @@ -195,8 +195,8 @@ static int set_bf_sort(const struct dmi_system_id *d) | |||
| 195 | return 0; | 195 | return 0; |
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | static void read_dmi_type_b1(const struct dmi_header *dm, | 198 | static void __init read_dmi_type_b1(const struct dmi_header *dm, |
| 199 | void *private_data) | 199 | void *private_data) |
| 200 | { | 200 | { |
| 201 | u8 *d = (u8 *)dm + 4; | 201 | u8 *d = (u8 *)dm + 4; |
| 202 | 202 | ||
| @@ -217,7 +217,7 @@ static void read_dmi_type_b1(const struct dmi_header *dm, | |||
| 217 | } | 217 | } |
| 218 | } | 218 | } |
| 219 | 219 | ||
| 220 | static int find_sort_method(const struct dmi_system_id *d) | 220 | static int __init find_sort_method(const struct dmi_system_id *d) |
| 221 | { | 221 | { |
| 222 | dmi_walk(read_dmi_type_b1, NULL); | 222 | dmi_walk(read_dmi_type_b1, NULL); |
| 223 | 223 | ||
| @@ -232,7 +232,7 @@ static int find_sort_method(const struct dmi_system_id *d) | |||
| 232 | * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus) | 232 | * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus) |
| 233 | */ | 233 | */ |
| 234 | #ifdef __i386__ | 234 | #ifdef __i386__ |
| 235 | static int assign_all_busses(const struct dmi_system_id *d) | 235 | static int __init assign_all_busses(const struct dmi_system_id *d) |
| 236 | { | 236 | { |
| 237 | pci_probe |= PCI_ASSIGN_ALL_BUSSES; | 237 | pci_probe |= PCI_ASSIGN_ALL_BUSSES; |
| 238 | printk(KERN_INFO "%s detected: enabling PCI bus# renumbering" | 238 | printk(KERN_INFO "%s detected: enabling PCI bus# renumbering" |
| @@ -241,7 +241,7 @@ static int assign_all_busses(const struct dmi_system_id *d) | |||
| 241 | } | 241 | } |
| 242 | #endif | 242 | #endif |
| 243 | 243 | ||
| 244 | static int set_scan_all(const struct dmi_system_id *d) | 244 | static int __init set_scan_all(const struct dmi_system_id *d) |
| 245 | { | 245 | { |
| 246 | printk(KERN_INFO "PCI: %s detected, enabling pci=pcie_scan_all\n", | 246 | printk(KERN_INFO "PCI: %s detected, enabling pci=pcie_scan_all\n", |
| 247 | d->ident); | 247 | d->ident); |
| @@ -249,7 +249,7 @@ static int set_scan_all(const struct dmi_system_id *d) | |||
| 249 | return 0; | 249 | return 0; |
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | static const struct dmi_system_id pciprobe_dmi_table[] = { | 252 | static const struct dmi_system_id pciprobe_dmi_table[] __initconst = { |
| 253 | #ifdef __i386__ | 253 | #ifdef __i386__ |
| 254 | /* | 254 | /* |
| 255 | * Laptops which need pci=assign-busses to see Cardbus cards | 255 | * Laptops which need pci=assign-busses to see Cardbus cards |
| @@ -512,7 +512,7 @@ int __init pcibios_init(void) | |||
| 512 | return 0; | 512 | return 0; |
| 513 | } | 513 | } |
| 514 | 514 | ||
| 515 | char * __init pcibios_setup(char *str) | 515 | char *__init pcibios_setup(char *str) |
| 516 | { | 516 | { |
| 517 | if (!strcmp(str, "off")) { | 517 | if (!strcmp(str, "off")) { |
| 518 | pci_probe = 0; | 518 | pci_probe = 0; |
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 248642f4bab7..326198a4434e 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
| @@ -31,7 +31,7 @@ static DEFINE_MUTEX(pci_mmcfg_lock); | |||
| 31 | 31 | ||
| 32 | LIST_HEAD(pci_mmcfg_list); | 32 | LIST_HEAD(pci_mmcfg_list); |
| 33 | 33 | ||
| 34 | static __init void pci_mmconfig_remove(struct pci_mmcfg_region *cfg) | 34 | static void __init pci_mmconfig_remove(struct pci_mmcfg_region *cfg) |
| 35 | { | 35 | { |
| 36 | if (cfg->res.parent) | 36 | if (cfg->res.parent) |
| 37 | release_resource(&cfg->res); | 37 | release_resource(&cfg->res); |
| @@ -39,7 +39,7 @@ static __init void pci_mmconfig_remove(struct pci_mmcfg_region *cfg) | |||
| 39 | kfree(cfg); | 39 | kfree(cfg); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | static __init void free_all_mmcfg(void) | 42 | static void __init free_all_mmcfg(void) |
| 43 | { | 43 | { |
| 44 | struct pci_mmcfg_region *cfg, *tmp; | 44 | struct pci_mmcfg_region *cfg, *tmp; |
| 45 | 45 | ||
| @@ -93,7 +93,7 @@ static struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start, | |||
| 93 | return new; | 93 | return new; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start, | 96 | static struct pci_mmcfg_region *__init pci_mmconfig_add(int segment, int start, |
| 97 | int end, u64 addr) | 97 | int end, u64 addr) |
| 98 | { | 98 | { |
| 99 | struct pci_mmcfg_region *new; | 99 | struct pci_mmcfg_region *new; |
| @@ -125,7 +125,7 @@ struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus) | |||
| 125 | return NULL; | 125 | return NULL; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | static const char __init *pci_mmcfg_e7520(void) | 128 | static const char *__init pci_mmcfg_e7520(void) |
| 129 | { | 129 | { |
| 130 | u32 win; | 130 | u32 win; |
| 131 | raw_pci_ops->read(0, 0, PCI_DEVFN(0, 0), 0xce, 2, &win); | 131 | raw_pci_ops->read(0, 0, PCI_DEVFN(0, 0), 0xce, 2, &win); |
| @@ -140,7 +140,7 @@ static const char __init *pci_mmcfg_e7520(void) | |||
| 140 | return "Intel Corporation E7520 Memory Controller Hub"; | 140 | return "Intel Corporation E7520 Memory Controller Hub"; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | static const char __init *pci_mmcfg_intel_945(void) | 143 | static const char *__init pci_mmcfg_intel_945(void) |
| 144 | { | 144 | { |
| 145 | u32 pciexbar, mask = 0, len = 0; | 145 | u32 pciexbar, mask = 0, len = 0; |
| 146 | 146 | ||
| @@ -184,7 +184,7 @@ static const char __init *pci_mmcfg_intel_945(void) | |||
| 184 | return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub"; | 184 | return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub"; |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | static const char __init *pci_mmcfg_amd_fam10h(void) | 187 | static const char *__init pci_mmcfg_amd_fam10h(void) |
| 188 | { | 188 | { |
| 189 | u32 low, high, address; | 189 | u32 low, high, address; |
| 190 | u64 base, msr; | 190 | u64 base, msr; |
| @@ -235,21 +235,25 @@ static const char __init *pci_mmcfg_amd_fam10h(void) | |||
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | static bool __initdata mcp55_checked; | 237 | static bool __initdata mcp55_checked; |
| 238 | static const char __init *pci_mmcfg_nvidia_mcp55(void) | 238 | static const char *__init pci_mmcfg_nvidia_mcp55(void) |
| 239 | { | 239 | { |
| 240 | int bus; | 240 | int bus; |
| 241 | int mcp55_mmconf_found = 0; | 241 | int mcp55_mmconf_found = 0; |
| 242 | 242 | ||
| 243 | static const u32 extcfg_regnum = 0x90; | 243 | static const u32 extcfg_regnum __initconst = 0x90; |
| 244 | static const u32 extcfg_regsize = 4; | 244 | static const u32 extcfg_regsize __initconst = 4; |
| 245 | static const u32 extcfg_enable_mask = 1<<31; | 245 | static const u32 extcfg_enable_mask __initconst = 1 << 31; |
| 246 | static const u32 extcfg_start_mask = 0xff<<16; | 246 | static const u32 extcfg_start_mask __initconst = 0xff << 16; |
| 247 | static const int extcfg_start_shift = 16; | 247 | static const int extcfg_start_shift __initconst = 16; |
| 248 | static const u32 extcfg_size_mask = 0x3<<28; | 248 | static const u32 extcfg_size_mask __initconst = 0x3 << 28; |
| 249 | static const int extcfg_size_shift = 28; | 249 | static const int extcfg_size_shift __initconst = 28; |
| 250 | static const int extcfg_sizebus[] = {0x100, 0x80, 0x40, 0x20}; | 250 | static const int extcfg_sizebus[] __initconst = { |
| 251 | static const u32 extcfg_base_mask[] = {0x7ff8, 0x7ffc, 0x7ffe, 0x7fff}; | 251 | 0x100, 0x80, 0x40, 0x20 |
| 252 | static const int extcfg_base_lshift = 25; | 252 | }; |
| 253 | static const u32 extcfg_base_mask[] __initconst = { | ||
| 254 | 0x7ff8, 0x7ffc, 0x7ffe, 0x7fff | ||
| 255 | }; | ||
| 256 | static const int extcfg_base_lshift __initconst = 25; | ||
| 253 | 257 | ||
| 254 | /* | 258 | /* |
| 255 | * do check if amd fam10h already took over | 259 | * do check if amd fam10h already took over |
| @@ -302,7 +306,7 @@ struct pci_mmcfg_hostbridge_probe { | |||
| 302 | const char *(*probe)(void); | 306 | const char *(*probe)(void); |
| 303 | }; | 307 | }; |
| 304 | 308 | ||
| 305 | static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = { | 309 | static const struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initconst = { |
| 306 | { 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID_INTEL, | 310 | { 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID_INTEL, |
| 307 | PCI_DEVICE_ID_INTEL_E7520_MCH, pci_mmcfg_e7520 }, | 311 | PCI_DEVICE_ID_INTEL_E7520_MCH, pci_mmcfg_e7520 }, |
| 308 | { 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID_INTEL, | 312 | { 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID_INTEL, |
diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c index c77b24a8b2da..9b83b9051ae7 100644 --- a/arch/x86/pci/pcbios.c +++ b/arch/x86/pci/pcbios.c | |||
| @@ -79,13 +79,13 @@ union bios32 { | |||
| 79 | static struct { | 79 | static struct { |
| 80 | unsigned long address; | 80 | unsigned long address; |
| 81 | unsigned short segment; | 81 | unsigned short segment; |
| 82 | } bios32_indirect = { 0, __KERNEL_CS }; | 82 | } bios32_indirect __initdata = { 0, __KERNEL_CS }; |
| 83 | 83 | ||
| 84 | /* | 84 | /* |
| 85 | * Returns the entry point for the given service, NULL on error | 85 | * Returns the entry point for the given service, NULL on error |
| 86 | */ | 86 | */ |
| 87 | 87 | ||
| 88 | static unsigned long bios32_service(unsigned long service) | 88 | static unsigned long __init bios32_service(unsigned long service) |
| 89 | { | 89 | { |
| 90 | unsigned char return_code; /* %al */ | 90 | unsigned char return_code; /* %al */ |
| 91 | unsigned long address; /* %ebx */ | 91 | unsigned long address; /* %ebx */ |
| @@ -124,7 +124,7 @@ static struct { | |||
| 124 | 124 | ||
| 125 | static int pci_bios_present; | 125 | static int pci_bios_present; |
| 126 | 126 | ||
| 127 | static int check_pcibios(void) | 127 | static int __init check_pcibios(void) |
| 128 | { | 128 | { |
| 129 | u32 signature, eax, ebx, ecx; | 129 | u32 signature, eax, ebx, ecx; |
| 130 | u8 status, major_ver, minor_ver, hw_mech; | 130 | u8 status, major_ver, minor_ver, hw_mech; |
| @@ -312,7 +312,7 @@ static const struct pci_raw_ops pci_bios_access = { | |||
| 312 | * Try to find PCI BIOS. | 312 | * Try to find PCI BIOS. |
| 313 | */ | 313 | */ |
| 314 | 314 | ||
| 315 | static const struct pci_raw_ops *pci_find_bios(void) | 315 | static const struct pci_raw_ops *__init pci_find_bios(void) |
| 316 | { | 316 | { |
| 317 | union bios32 *check; | 317 | union bios32 *check; |
| 318 | unsigned char sum; | 318 | unsigned char sum; |
diff --git a/drivers/gpu/drm/vmwgfx/svga_reg.h b/drivers/gpu/drm/vmwgfx/svga_reg.h index 11323dd5196f..e4259c2c1acc 100644 --- a/drivers/gpu/drm/vmwgfx/svga_reg.h +++ b/drivers/gpu/drm/vmwgfx/svga_reg.h | |||
| @@ -35,7 +35,6 @@ | |||
| 35 | /* | 35 | /* |
| 36 | * PCI device IDs. | 36 | * PCI device IDs. |
| 37 | */ | 37 | */ |
| 38 | #define PCI_VENDOR_ID_VMWARE 0x15AD | ||
| 39 | #define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405 | 38 | #define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405 |
| 40 | 39 | ||
| 41 | /* | 40 | /* |
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index fa75a29a0408..3e238cd049e6 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c | |||
| @@ -136,6 +136,10 @@ static int armada_370_xp_setup_msi_irq(struct msi_chip *chip, | |||
| 136 | struct msi_msg msg; | 136 | struct msi_msg msg; |
| 137 | int virq, hwirq; | 137 | int virq, hwirq; |
| 138 | 138 | ||
| 139 | /* We support MSI, but not MSI-X */ | ||
| 140 | if (desc->msi_attrib.is_msix) | ||
| 141 | return -EINVAL; | ||
| 142 | |||
| 139 | hwirq = armada_370_xp_alloc_msi(); | 143 | hwirq = armada_370_xp_alloc_msi(); |
| 140 | if (hwirq < 0) | 144 | if (hwirq < 0) |
| 141 | return hwirq; | 145 | return hwirq; |
| @@ -166,15 +170,6 @@ static void armada_370_xp_teardown_msi_irq(struct msi_chip *chip, | |||
| 166 | armada_370_xp_free_msi(hwirq); | 170 | armada_370_xp_free_msi(hwirq); |
| 167 | } | 171 | } |
| 168 | 172 | ||
| 169 | static int armada_370_xp_check_msi_device(struct msi_chip *chip, struct pci_dev *dev, | ||
| 170 | int nvec, int type) | ||
| 171 | { | ||
| 172 | /* We support MSI, but not MSI-X */ | ||
| 173 | if (type == PCI_CAP_ID_MSI) | ||
| 174 | return 0; | ||
| 175 | return -EINVAL; | ||
| 176 | } | ||
| 177 | |||
| 178 | static struct irq_chip armada_370_xp_msi_irq_chip = { | 173 | static struct irq_chip armada_370_xp_msi_irq_chip = { |
| 179 | .name = "armada_370_xp_msi_irq", | 174 | .name = "armada_370_xp_msi_irq", |
| 180 | .irq_enable = unmask_msi_irq, | 175 | .irq_enable = unmask_msi_irq, |
| @@ -213,7 +208,6 @@ static int armada_370_xp_msi_init(struct device_node *node, | |||
| 213 | 208 | ||
| 214 | msi_chip->setup_irq = armada_370_xp_setup_msi_irq; | 209 | msi_chip->setup_irq = armada_370_xp_setup_msi_irq; |
| 215 | msi_chip->teardown_irq = armada_370_xp_teardown_msi_irq; | 210 | msi_chip->teardown_irq = armada_370_xp_teardown_msi_irq; |
| 216 | msi_chip->check_device = armada_370_xp_check_msi_device; | ||
| 217 | msi_chip->of_node = node; | 211 | msi_chip->of_node = node; |
| 218 | 212 | ||
| 219 | armada_370_xp_msi_domain = | 213 | armada_370_xp_msi_domain = |
diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c index 248399a881af..189b32519748 100644 --- a/drivers/misc/vmw_vmci/vmci_guest.c +++ b/drivers/misc/vmw_vmci/vmci_guest.c | |||
| @@ -35,7 +35,6 @@ | |||
| 35 | #include "vmci_driver.h" | 35 | #include "vmci_driver.h" |
| 36 | #include "vmci_event.h" | 36 | #include "vmci_event.h" |
| 37 | 37 | ||
| 38 | #define PCI_VENDOR_ID_VMWARE 0x15AD | ||
| 39 | #define PCI_DEVICE_ID_VMWARE_VMCI 0x0740 | 38 | #define PCI_DEVICE_ID_VMWARE_VMCI 0x0740 |
| 40 | 39 | ||
| 41 | #define VMCI_UTIL_NUM_RESOURCES 1 | 40 | #define VMCI_UTIL_NUM_RESOURCES 1 |
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index 3759479f959a..5f0199f6c31e 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h | |||
| @@ -117,7 +117,6 @@ enum { | |||
| 117 | /* | 117 | /* |
| 118 | * PCI vendor and device IDs. | 118 | * PCI vendor and device IDs. |
| 119 | */ | 119 | */ |
| 120 | #define PCI_VENDOR_ID_VMWARE 0x15AD | ||
| 121 | #define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0 | 120 | #define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0 |
| 122 | #define MAX_ETHERNET_CARDS 10 | 121 | #define MAX_ETHERNET_CARDS 10 |
| 123 | #define MAX_PCI_PASSTHRU_DEVICE 6 | 122 | #define MAX_PCI_PASSTHRU_DEVICE 6 |
diff --git a/drivers/of/address.c b/drivers/of/address.c index e3718250d66e..afdb78299f61 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | #include <linux/module.h> | 5 | #include <linux/module.h> |
| 6 | #include <linux/of_address.h> | 6 | #include <linux/of_address.h> |
| 7 | #include <linux/pci_regs.h> | 7 | #include <linux/pci_regs.h> |
| 8 | #include <linux/sizes.h> | ||
| 9 | #include <linux/slab.h> | ||
| 8 | #include <linux/string.h> | 10 | #include <linux/string.h> |
| 9 | 11 | ||
| 10 | /* Max address size we deal with */ | 12 | /* Max address size we deal with */ |
| @@ -293,6 +295,51 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser, | |||
| 293 | } | 295 | } |
| 294 | EXPORT_SYMBOL_GPL(of_pci_range_parser_one); | 296 | EXPORT_SYMBOL_GPL(of_pci_range_parser_one); |
| 295 | 297 | ||
| 298 | /* | ||
| 299 | * of_pci_range_to_resource - Create a resource from an of_pci_range | ||
| 300 | * @range: the PCI range that describes the resource | ||
| 301 | * @np: device node where the range belongs to | ||
| 302 | * @res: pointer to a valid resource that will be updated to | ||
| 303 | * reflect the values contained in the range. | ||
| 304 | * | ||
| 305 | * Returns EINVAL if the range cannot be converted to resource. | ||
| 306 | * | ||
| 307 | * Note that if the range is an IO range, the resource will be converted | ||
| 308 | * using pci_address_to_pio() which can fail if it is called too early or | ||
| 309 | * if the range cannot be matched to any host bridge IO space (our case here). | ||
| 310 | * To guard against that we try to register the IO range first. | ||
| 311 | * If that fails we know that pci_address_to_pio() will do too. | ||
| 312 | */ | ||
| 313 | int of_pci_range_to_resource(struct of_pci_range *range, | ||
| 314 | struct device_node *np, struct resource *res) | ||
| 315 | { | ||
| 316 | int err; | ||
| 317 | res->flags = range->flags; | ||
| 318 | res->parent = res->child = res->sibling = NULL; | ||
| 319 | res->name = np->full_name; | ||
| 320 | |||
| 321 | if (res->flags & IORESOURCE_IO) { | ||
| 322 | unsigned long port; | ||
| 323 | err = pci_register_io_range(range->cpu_addr, range->size); | ||
| 324 | if (err) | ||
| 325 | goto invalid_range; | ||
| 326 | port = pci_address_to_pio(range->cpu_addr); | ||
| 327 | if (port == (unsigned long)-1) { | ||
| 328 | err = -EINVAL; | ||
| 329 | goto invalid_range; | ||
| 330 | } | ||
| 331 | res->start = port; | ||
| 332 | } else { | ||
| 333 | res->start = range->cpu_addr; | ||
| 334 | } | ||
| 335 | res->end = res->start + range->size - 1; | ||
| 336 | return 0; | ||
| 337 | |||
| 338 | invalid_range: | ||
| 339 | res->start = (resource_size_t)OF_BAD_ADDR; | ||
| 340 | res->end = (resource_size_t)OF_BAD_ADDR; | ||
| 341 | return err; | ||
| 342 | } | ||
| 296 | #endif /* CONFIG_PCI */ | 343 | #endif /* CONFIG_PCI */ |
| 297 | 344 | ||
| 298 | /* | 345 | /* |
| @@ -601,12 +648,119 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, | |||
| 601 | } | 648 | } |
| 602 | EXPORT_SYMBOL(of_get_address); | 649 | EXPORT_SYMBOL(of_get_address); |
| 603 | 650 | ||
| 651 | #ifdef PCI_IOBASE | ||
| 652 | struct io_range { | ||
| 653 | struct list_head list; | ||
| 654 | phys_addr_t start; | ||
| 655 | resource_size_t size; | ||
| 656 | }; | ||
| 657 | |||
| 658 | static LIST_HEAD(io_range_list); | ||
| 659 | static DEFINE_SPINLOCK(io_range_lock); | ||
| 660 | #endif | ||
| 661 | |||
| 662 | /* | ||
| 663 | * Record the PCI IO range (expressed as CPU physical address + size). | ||
| 664 | * Return a negative value if an error has occured, zero otherwise | ||
| 665 | */ | ||
| 666 | int __weak pci_register_io_range(phys_addr_t addr, resource_size_t size) | ||
| 667 | { | ||
| 668 | int err = 0; | ||
| 669 | |||
| 670 | #ifdef PCI_IOBASE | ||
| 671 | struct io_range *range; | ||
| 672 | resource_size_t allocated_size = 0; | ||
| 673 | |||
| 674 | /* check if the range hasn't been previously recorded */ | ||
| 675 | spin_lock(&io_range_lock); | ||
| 676 | list_for_each_entry(range, &io_range_list, list) { | ||
| 677 | if (addr >= range->start && addr + size <= range->start + size) { | ||
| 678 | /* range already registered, bail out */ | ||
| 679 | goto end_register; | ||
| 680 | } | ||
| 681 | allocated_size += range->size; | ||
| 682 | } | ||
| 683 | |||
| 684 | /* range not registed yet, check for available space */ | ||
| 685 | if (allocated_size + size - 1 > IO_SPACE_LIMIT) { | ||
| 686 | /* if it's too big check if 64K space can be reserved */ | ||
| 687 | if (allocated_size + SZ_64K - 1 > IO_SPACE_LIMIT) { | ||
| 688 | err = -E2BIG; | ||
| 689 | goto end_register; | ||
| 690 | } | ||
| 691 | |||
| 692 | size = SZ_64K; | ||
| 693 | pr_warn("Requested IO range too big, new size set to 64K\n"); | ||
| 694 | } | ||
| 695 | |||
| 696 | /* add the range to the list */ | ||
| 697 | range = kzalloc(sizeof(*range), GFP_KERNEL); | ||
| 698 | if (!range) { | ||
| 699 | err = -ENOMEM; | ||
| 700 | goto end_register; | ||
| 701 | } | ||
| 702 | |||
| 703 | range->start = addr; | ||
| 704 | range->size = size; | ||
| 705 | |||
| 706 | list_add_tail(&range->list, &io_range_list); | ||
| 707 | |||
| 708 | end_register: | ||
| 709 | spin_unlock(&io_range_lock); | ||
| 710 | #endif | ||
| 711 | |||
| 712 | return err; | ||
| 713 | } | ||
| 714 | |||
| 715 | phys_addr_t pci_pio_to_address(unsigned long pio) | ||
| 716 | { | ||
| 717 | phys_addr_t address = (phys_addr_t)OF_BAD_ADDR; | ||
| 718 | |||
| 719 | #ifdef PCI_IOBASE | ||
| 720 | struct io_range *range; | ||
| 721 | resource_size_t allocated_size = 0; | ||
| 722 | |||
| 723 | if (pio > IO_SPACE_LIMIT) | ||
| 724 | return address; | ||
| 725 | |||
| 726 | spin_lock(&io_range_lock); | ||
| 727 | list_for_each_entry(range, &io_range_list, list) { | ||
| 728 | if (pio >= allocated_size && pio < allocated_size + range->size) { | ||
| 729 | address = range->start + pio - allocated_size; | ||
| 730 | break; | ||
| 731 | } | ||
| 732 | allocated_size += range->size; | ||
| 733 | } | ||
| 734 | spin_unlock(&io_range_lock); | ||
| 735 | #endif | ||
| 736 | |||
| 737 | return address; | ||
| 738 | } | ||
| 739 | |||
| 604 | unsigned long __weak pci_address_to_pio(phys_addr_t address) | 740 | unsigned long __weak pci_address_to_pio(phys_addr_t address) |
| 605 | { | 741 | { |
| 742 | #ifdef PCI_IOBASE | ||
| 743 | struct io_range *res; | ||
| 744 | resource_size_t offset = 0; | ||
| 745 | unsigned long addr = -1; | ||
| 746 | |||
| 747 | spin_lock(&io_range_lock); | ||
| 748 | list_for_each_entry(res, &io_range_list, list) { | ||
| 749 | if (address >= res->start && address < res->start + res->size) { | ||
| 750 | addr = res->start - address + offset; | ||
| 751 | break; | ||
| 752 | } | ||
| 753 | offset += res->size; | ||
| 754 | } | ||
| 755 | spin_unlock(&io_range_lock); | ||
| 756 | |||
| 757 | return addr; | ||
| 758 | #else | ||
| 606 | if (address > IO_SPACE_LIMIT) | 759 | if (address > IO_SPACE_LIMIT) |
| 607 | return (unsigned long)-1; | 760 | return (unsigned long)-1; |
| 608 | 761 | ||
| 609 | return (unsigned long) address; | 762 | return (unsigned long) address; |
| 763 | #endif | ||
| 610 | } | 764 | } |
| 611 | 765 | ||
| 612 | static int __of_address_to_resource(struct device_node *dev, | 766 | static int __of_address_to_resource(struct device_node *dev, |
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c index 848199633798..8882b467be95 100644 --- a/drivers/of/of_pci.c +++ b/drivers/of/of_pci.c | |||
| @@ -1,7 +1,9 @@ | |||
| 1 | #include <linux/kernel.h> | 1 | #include <linux/kernel.h> |
| 2 | #include <linux/export.h> | 2 | #include <linux/export.h> |
| 3 | #include <linux/of.h> | 3 | #include <linux/of.h> |
| 4 | #include <linux/of_address.h> | ||
| 4 | #include <linux/of_pci.h> | 5 | #include <linux/of_pci.h> |
| 6 | #include <linux/slab.h> | ||
| 5 | 7 | ||
| 6 | static inline int __of_pci_pci_compare(struct device_node *node, | 8 | static inline int __of_pci_pci_compare(struct device_node *node, |
| 7 | unsigned int data) | 9 | unsigned int data) |
| @@ -89,6 +91,146 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res) | |||
| 89 | } | 91 | } |
| 90 | EXPORT_SYMBOL_GPL(of_pci_parse_bus_range); | 92 | EXPORT_SYMBOL_GPL(of_pci_parse_bus_range); |
| 91 | 93 | ||
| 94 | /** | ||
| 95 | * This function will try to obtain the host bridge domain number by | ||
| 96 | * finding a property called "linux,pci-domain" of the given device node. | ||
| 97 | * | ||
| 98 | * @node: device tree node with the domain information | ||
| 99 | * | ||
| 100 | * Returns the associated domain number from DT in the range [0-0xffff], or | ||
| 101 | * a negative value if the required property is not found. | ||
| 102 | */ | ||
| 103 | int of_get_pci_domain_nr(struct device_node *node) | ||
| 104 | { | ||
| 105 | const __be32 *value; | ||
| 106 | int len; | ||
| 107 | u16 domain; | ||
| 108 | |||
| 109 | value = of_get_property(node, "linux,pci-domain", &len); | ||
| 110 | if (!value || len < sizeof(*value)) | ||
| 111 | return -EINVAL; | ||
| 112 | |||
| 113 | domain = (u16)be32_to_cpup(value); | ||
| 114 | |||
| 115 | return domain; | ||
| 116 | } | ||
| 117 | EXPORT_SYMBOL_GPL(of_get_pci_domain_nr); | ||
| 118 | |||
| 119 | #if defined(CONFIG_OF_ADDRESS) | ||
| 120 | /** | ||
| 121 | * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT | ||
| 122 | * @dev: device node of the host bridge having the range property | ||
| 123 | * @busno: bus number associated with the bridge root bus | ||
| 124 | * @bus_max: maximum number of buses for this bridge | ||
| 125 | * @resources: list where the range of resources will be added after DT parsing | ||
| 126 | * @io_base: pointer to a variable that will contain on return the physical | ||
| 127 | * address for the start of the I/O range. Can be NULL if the caller doesn't | ||
| 128 | * expect IO ranges to be present in the device tree. | ||
| 129 | * | ||
| 130 | * It is the caller's job to free the @resources list. | ||
| 131 | * | ||
| 132 | * This function will parse the "ranges" property of a PCI host bridge device | ||
| 133 | * node and setup the resource mapping based on its content. It is expected | ||
| 134 | * that the property conforms with the Power ePAPR document. | ||
| 135 | * | ||
| 136 | * It returns zero if the range parsing has been successful or a standard error | ||
| 137 | * value if it failed. | ||
| 138 | */ | ||
| 139 | int of_pci_get_host_bridge_resources(struct device_node *dev, | ||
| 140 | unsigned char busno, unsigned char bus_max, | ||
| 141 | struct list_head *resources, resource_size_t *io_base) | ||
| 142 | { | ||
| 143 | struct resource *res; | ||
| 144 | struct resource *bus_range; | ||
| 145 | struct of_pci_range range; | ||
| 146 | struct of_pci_range_parser parser; | ||
| 147 | char range_type[4]; | ||
| 148 | int err; | ||
| 149 | |||
| 150 | if (io_base) | ||
| 151 | *io_base = (resource_size_t)OF_BAD_ADDR; | ||
| 152 | |||
| 153 | bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL); | ||
| 154 | if (!bus_range) | ||
| 155 | return -ENOMEM; | ||
| 156 | |||
| 157 | pr_info("PCI host bridge %s ranges:\n", dev->full_name); | ||
| 158 | |||
| 159 | err = of_pci_parse_bus_range(dev, bus_range); | ||
| 160 | if (err) { | ||
| 161 | bus_range->start = busno; | ||
| 162 | bus_range->end = bus_max; | ||
| 163 | bus_range->flags = IORESOURCE_BUS; | ||
| 164 | pr_info(" No bus range found for %s, using %pR\n", | ||
| 165 | dev->full_name, bus_range); | ||
| 166 | } else { | ||
| 167 | if (bus_range->end > bus_range->start + bus_max) | ||
| 168 | bus_range->end = bus_range->start + bus_max; | ||
| 169 | } | ||
| 170 | pci_add_resource(resources, bus_range); | ||
| 171 | |||
| 172 | /* Check for ranges property */ | ||
| 173 | err = of_pci_range_parser_init(&parser, dev); | ||
| 174 | if (err) | ||
| 175 | goto parse_failed; | ||
| 176 | |||
| 177 | pr_debug("Parsing ranges property...\n"); | ||
| 178 | for_each_of_pci_range(&parser, &range) { | ||
| 179 | /* Read next ranges element */ | ||
| 180 | if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO) | ||
| 181 | snprintf(range_type, 4, " IO"); | ||
| 182 | else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM) | ||
| 183 | snprintf(range_type, 4, "MEM"); | ||
| 184 | else | ||
| 185 | snprintf(range_type, 4, "err"); | ||
| 186 | pr_info(" %s %#010llx..%#010llx -> %#010llx\n", range_type, | ||
| 187 | range.cpu_addr, range.cpu_addr + range.size - 1, | ||
| 188 | range.pci_addr); | ||
| 189 | |||
| 190 | /* | ||
| 191 | * If we failed translation or got a zero-sized region | ||
| 192 | * then skip this range | ||
| 193 | */ | ||
| 194 | if (range.cpu_addr == OF_BAD_ADDR || range.size == 0) | ||
| 195 | continue; | ||
| 196 | |||
| 197 | res = kzalloc(sizeof(struct resource), GFP_KERNEL); | ||
| 198 | if (!res) { | ||
| 199 | err = -ENOMEM; | ||
| 200 | goto parse_failed; | ||
| 201 | } | ||
| 202 | |||
| 203 | err = of_pci_range_to_resource(&range, dev, res); | ||
| 204 | if (err) | ||
| 205 | goto conversion_failed; | ||
| 206 | |||
| 207 | if (resource_type(res) == IORESOURCE_IO) { | ||
| 208 | if (!io_base) { | ||
| 209 | pr_err("I/O range found for %s. Please provide an io_base pointer to save CPU base address\n", | ||
| 210 | dev->full_name); | ||
| 211 | err = -EINVAL; | ||
| 212 | goto conversion_failed; | ||
| 213 | } | ||
| 214 | if (*io_base != (resource_size_t)OF_BAD_ADDR) | ||
| 215 | pr_warn("More than one I/O resource converted for %s. CPU base address for old range lost!\n", | ||
| 216 | dev->full_name); | ||
| 217 | *io_base = range.cpu_addr; | ||
| 218 | } | ||
| 219 | |||
| 220 | pci_add_resource_offset(resources, res, res->start - range.pci_addr); | ||
| 221 | } | ||
| 222 | |||
| 223 | return 0; | ||
| 224 | |||
| 225 | conversion_failed: | ||
| 226 | kfree(res); | ||
| 227 | parse_failed: | ||
| 228 | pci_free_resource_list(resources); | ||
| 229 | return err; | ||
| 230 | } | ||
| 231 | EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources); | ||
| 232 | #endif /* CONFIG_OF_ADDRESS */ | ||
| 233 | |||
| 92 | #ifdef CONFIG_PCI_MSI | 234 | #ifdef CONFIG_PCI_MSI |
| 93 | 235 | ||
| 94 | static LIST_HEAD(of_pci_msi_chip_list); | 236 | static LIST_HEAD(of_pci_msi_chip_list); |
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 90f5ccacce4b..3dc25fad490c 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig | |||
| @@ -63,4 +63,32 @@ config PCIE_SPEAR13XX | |||
| 63 | help | 63 | help |
| 64 | Say Y here if you want PCIe support on SPEAr13XX SoCs. | 64 | Say Y here if you want PCIe support on SPEAr13XX SoCs. |
| 65 | 65 | ||
| 66 | config PCI_KEYSTONE | ||
| 67 | bool "TI Keystone PCIe controller" | ||
| 68 | depends on ARCH_KEYSTONE | ||
| 69 | select PCIE_DW | ||
| 70 | select PCIEPORTBUS | ||
| 71 | help | ||
| 72 | Say Y here if you want to enable PCI controller support on Keystone | ||
| 73 | SoCs. The PCI controller on Keystone is based on Designware hardware | ||
| 74 | and therefore the driver re-uses the Designware core functions to | ||
| 75 | implement the driver. | ||
| 76 | |||
| 77 | config PCIE_XILINX | ||
| 78 | bool "Xilinx AXI PCIe host bridge support" | ||
| 79 | depends on ARCH_ZYNQ | ||
| 80 | help | ||
| 81 | Say 'Y' here if you want kernel to support the Xilinx AXI PCIe | ||
| 82 | Host Bridge driver. | ||
| 83 | |||
| 84 | config PCI_XGENE | ||
| 85 | bool "X-Gene PCIe controller" | ||
| 86 | depends on ARCH_XGENE | ||
| 87 | depends on OF | ||
| 88 | select PCIEPORTBUS | ||
| 89 | help | ||
| 90 | Say Y here if you want internal PCI support on APM X-Gene SoC. | ||
| 91 | There are 5 internal PCIe ports available. Each port is GEN3 capable | ||
| 92 | and have varied lanes from x1 to x8. | ||
| 93 | |||
| 66 | endmenu | 94 | endmenu |
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index d0e88f114ff9..26b3461d68d7 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile | |||
| @@ -8,3 +8,6 @@ obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o | |||
| 8 | obj-$(CONFIG_PCI_RCAR_GEN2_PCIE) += pcie-rcar.o | 8 | obj-$(CONFIG_PCI_RCAR_GEN2_PCIE) += pcie-rcar.o |
| 9 | obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o | 9 | obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o |
| 10 | obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o | 10 | obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o |
| 11 | obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o | ||
| 12 | obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o | ||
| 13 | obj-$(CONFIG_PCI_XGENE) += pci-xgene.o | ||
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index 35fc73a8d0b3..233fe8a88264 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c | |||
| @@ -257,11 +257,6 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) | |||
| 257 | struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); | 257 | struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); |
| 258 | int ret; | 258 | int ret; |
| 259 | 259 | ||
| 260 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, | ||
| 261 | IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18); | ||
| 262 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, | ||
| 263 | IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); | ||
| 264 | |||
| 265 | ret = clk_prepare_enable(imx6_pcie->pcie_phy); | 260 | ret = clk_prepare_enable(imx6_pcie->pcie_phy); |
| 266 | if (ret) { | 261 | if (ret) { |
| 267 | dev_err(pp->dev, "unable to enable pcie_phy clock\n"); | 262 | dev_err(pp->dev, "unable to enable pcie_phy clock\n"); |
| @@ -283,6 +278,12 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) | |||
| 283 | /* allow the clocks to stabilize */ | 278 | /* allow the clocks to stabilize */ |
| 284 | usleep_range(200, 500); | 279 | usleep_range(200, 500); |
| 285 | 280 | ||
| 281 | /* power up core phy and enable ref clock */ | ||
| 282 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, | ||
| 283 | IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18); | ||
| 284 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, | ||
| 285 | IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); | ||
| 286 | |||
| 286 | /* Some boards don't have PCIe reset GPIO. */ | 287 | /* Some boards don't have PCIe reset GPIO. */ |
| 287 | if (gpio_is_valid(imx6_pcie->reset_gpio)) { | 288 | if (gpio_is_valid(imx6_pcie->reset_gpio)) { |
| 288 | gpio_set_value(imx6_pcie->reset_gpio, 0); | 289 | gpio_set_value(imx6_pcie->reset_gpio, 0); |
| @@ -647,7 +648,7 @@ static int __init imx6_pcie_init(void) | |||
| 647 | { | 648 | { |
| 648 | return platform_driver_probe(&imx6_pcie_driver, imx6_pcie_probe); | 649 | return platform_driver_probe(&imx6_pcie_driver, imx6_pcie_probe); |
| 649 | } | 650 | } |
| 650 | fs_initcall(imx6_pcie_init); | 651 | module_init(imx6_pcie_init); |
| 651 | 652 | ||
| 652 | MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>"); | 653 | MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>"); |
| 653 | MODULE_DESCRIPTION("Freescale i.MX6 PCIe host controller driver"); | 654 | MODULE_DESCRIPTION("Freescale i.MX6 PCIe host controller driver"); |
diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c new file mode 100644 index 000000000000..34086ce88e8e --- /dev/null +++ b/drivers/pci/host/pci-keystone-dw.c | |||
| @@ -0,0 +1,516 @@ | |||
| 1 | /* | ||
| 2 | * Designware application register space functions for Keystone PCI controller | ||
| 3 | * | ||
| 4 | * Copyright (C) 2013-2014 Texas Instruments., Ltd. | ||
| 5 | * http://www.ti.com | ||
| 6 | * | ||
| 7 | * Author: Murali Karicheri <m-karicheri2@ti.com> | ||
| 8 | * | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/irq.h> | ||
| 16 | #include <linux/irqdomain.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/of.h> | ||
| 19 | #include <linux/of_pci.h> | ||
| 20 | #include <linux/pci.h> | ||
| 21 | #include <linux/platform_device.h> | ||
| 22 | |||
| 23 | #include "pcie-designware.h" | ||
| 24 | #include "pci-keystone.h" | ||
| 25 | |||
| 26 | /* Application register defines */ | ||
| 27 | #define LTSSM_EN_VAL 1 | ||
| 28 | #define LTSSM_STATE_MASK 0x1f | ||
| 29 | #define LTSSM_STATE_L0 0x11 | ||
| 30 | #define DBI_CS2_EN_VAL 0x20 | ||
| 31 | #define OB_XLAT_EN_VAL 2 | ||
| 32 | |||
| 33 | /* Application registers */ | ||
| 34 | #define CMD_STATUS 0x004 | ||
| 35 | #define CFG_SETUP 0x008 | ||
| 36 | #define OB_SIZE 0x030 | ||
| 37 | #define CFG_PCIM_WIN_SZ_IDX 3 | ||
| 38 | #define CFG_PCIM_WIN_CNT 32 | ||
| 39 | #define SPACE0_REMOTE_CFG_OFFSET 0x1000 | ||
| 40 | #define OB_OFFSET_INDEX(n) (0x200 + (8 * n)) | ||
| 41 | #define OB_OFFSET_HI(n) (0x204 + (8 * n)) | ||
| 42 | |||
| 43 | /* IRQ register defines */ | ||
| 44 | #define IRQ_EOI 0x050 | ||
| 45 | #define IRQ_STATUS 0x184 | ||
| 46 | #define IRQ_ENABLE_SET 0x188 | ||
| 47 | #define IRQ_ENABLE_CLR 0x18c | ||
| 48 | |||
| 49 | #define MSI_IRQ 0x054 | ||
| 50 | #define MSI0_IRQ_STATUS 0x104 | ||
| 51 | #define MSI0_IRQ_ENABLE_SET 0x108 | ||
| 52 | #define MSI0_IRQ_ENABLE_CLR 0x10c | ||
| 53 | #define IRQ_STATUS 0x184 | ||
| 54 | #define MSI_IRQ_OFFSET 4 | ||
| 55 | |||
| 56 | /* Config space registers */ | ||
| 57 | #define DEBUG0 0x728 | ||
| 58 | |||
| 59 | #define to_keystone_pcie(x) container_of(x, struct keystone_pcie, pp) | ||
| 60 | |||
| 61 | static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys) | ||
| 62 | { | ||
| 63 | return sys->private_data; | ||
| 64 | } | ||
| 65 | |||
| 66 | static inline void update_reg_offset_bit_pos(u32 offset, u32 *reg_offset, | ||
| 67 | u32 *bit_pos) | ||
| 68 | { | ||
| 69 | *reg_offset = offset % 8; | ||
| 70 | *bit_pos = offset >> 3; | ||
| 71 | } | ||
| 72 | |||
| 73 | u32 ks_dw_pcie_get_msi_addr(struct pcie_port *pp) | ||
| 74 | { | ||
| 75 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pp); | ||
| 76 | |||
| 77 | return ks_pcie->app.start + MSI_IRQ; | ||
| 78 | } | ||
| 79 | |||
| 80 | void ks_dw_pcie_handle_msi_irq(struct keystone_pcie *ks_pcie, int offset) | ||
| 81 | { | ||
| 82 | struct pcie_port *pp = &ks_pcie->pp; | ||
| 83 | u32 pending, vector; | ||
| 84 | int src, virq; | ||
| 85 | |||
| 86 | pending = readl(ks_pcie->va_app_base + MSI0_IRQ_STATUS + (offset << 4)); | ||
| 87 | |||
| 88 | /* | ||
| 89 | * MSI0 status bit 0-3 shows vectors 0, 8, 16, 24, MSI1 status bit | ||
| 90 | * shows 1, 9, 17, 25 and so forth | ||
| 91 | */ | ||
| 92 | for (src = 0; src < 4; src++) { | ||
| 93 | if (BIT(src) & pending) { | ||
| 94 | vector = offset + (src << 3); | ||
| 95 | virq = irq_linear_revmap(pp->irq_domain, vector); | ||
| 96 | dev_dbg(pp->dev, "irq: bit %d, vector %d, virq %d\n", | ||
| 97 | src, vector, virq); | ||
| 98 | generic_handle_irq(virq); | ||
| 99 | } | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | static void ks_dw_pcie_msi_irq_ack(struct irq_data *d) | ||
| 104 | { | ||
| 105 | u32 offset, reg_offset, bit_pos; | ||
| 106 | struct keystone_pcie *ks_pcie; | ||
| 107 | unsigned int irq = d->irq; | ||
| 108 | struct msi_desc *msi; | ||
| 109 | struct pcie_port *pp; | ||
| 110 | |||
| 111 | msi = irq_get_msi_desc(irq); | ||
| 112 | pp = sys_to_pcie(msi->dev->bus->sysdata); | ||
| 113 | ks_pcie = to_keystone_pcie(pp); | ||
| 114 | offset = irq - irq_linear_revmap(pp->irq_domain, 0); | ||
| 115 | update_reg_offset_bit_pos(offset, ®_offset, &bit_pos); | ||
| 116 | |||
| 117 | writel(BIT(bit_pos), | ||
| 118 | ks_pcie->va_app_base + MSI0_IRQ_STATUS + (reg_offset << 4)); | ||
| 119 | writel(reg_offset + MSI_IRQ_OFFSET, ks_pcie->va_app_base + IRQ_EOI); | ||
| 120 | } | ||
| 121 | |||
| 122 | void ks_dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) | ||
| 123 | { | ||
| 124 | u32 reg_offset, bit_pos; | ||
| 125 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pp); | ||
| 126 | |||
| 127 | update_reg_offset_bit_pos(irq, ®_offset, &bit_pos); | ||
| 128 | writel(BIT(bit_pos), | ||
| 129 | ks_pcie->va_app_base + MSI0_IRQ_ENABLE_SET + (reg_offset << 4)); | ||
| 130 | } | ||
| 131 | |||
| 132 | void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq) | ||
| 133 | { | ||
| 134 | u32 reg_offset, bit_pos; | ||
| 135 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pp); | ||
| 136 | |||
| 137 | update_reg_offset_bit_pos(irq, ®_offset, &bit_pos); | ||
| 138 | writel(BIT(bit_pos), | ||
| 139 | ks_pcie->va_app_base + MSI0_IRQ_ENABLE_CLR + (reg_offset << 4)); | ||
| 140 | } | ||
| 141 | |||
| 142 | static void ks_dw_pcie_msi_irq_mask(struct irq_data *d) | ||
| 143 | { | ||
| 144 | struct keystone_pcie *ks_pcie; | ||
| 145 | unsigned int irq = d->irq; | ||
| 146 | struct msi_desc *msi; | ||
| 147 | struct pcie_port *pp; | ||
| 148 | u32 offset; | ||
| 149 | |||
| 150 | msi = irq_get_msi_desc(irq); | ||
| 151 | pp = sys_to_pcie(msi->dev->bus->sysdata); | ||
| 152 | ks_pcie = to_keystone_pcie(pp); | ||
| 153 | offset = irq - irq_linear_revmap(pp->irq_domain, 0); | ||
| 154 | |||
| 155 | /* Mask the end point if PVM implemented */ | ||
| 156 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | ||
| 157 | if (msi->msi_attrib.maskbit) | ||
| 158 | mask_msi_irq(d); | ||
| 159 | } | ||
| 160 | |||
| 161 | ks_dw_pcie_msi_clear_irq(pp, offset); | ||
| 162 | } | ||
| 163 | |||
| 164 | static void ks_dw_pcie_msi_irq_unmask(struct irq_data *d) | ||
| 165 | { | ||
| 166 | struct keystone_pcie *ks_pcie; | ||
| 167 | unsigned int irq = d->irq; | ||
| 168 | struct msi_desc *msi; | ||
| 169 | struct pcie_port *pp; | ||
| 170 | u32 offset; | ||
| 171 | |||
| 172 | msi = irq_get_msi_desc(irq); | ||
| 173 | pp = sys_to_pcie(msi->dev->bus->sysdata); | ||
| 174 | ks_pcie = to_keystone_pcie(pp); | ||
| 175 | offset = irq - irq_linear_revmap(pp->irq_domain, 0); | ||
| 176 | |||
| 177 | /* Mask the end point if PVM implemented */ | ||
| 178 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | ||
| 179 | if (msi->msi_attrib.maskbit) | ||
| 180 | unmask_msi_irq(d); | ||
| 181 | } | ||
| 182 | |||
| 183 | ks_dw_pcie_msi_set_irq(pp, offset); | ||
| 184 | } | ||
| 185 | |||
| 186 | static struct irq_chip ks_dw_pcie_msi_irq_chip = { | ||
| 187 | .name = "Keystone-PCIe-MSI-IRQ", | ||
| 188 | .irq_ack = ks_dw_pcie_msi_irq_ack, | ||
| 189 | .irq_mask = ks_dw_pcie_msi_irq_mask, | ||
| 190 | .irq_unmask = ks_dw_pcie_msi_irq_unmask, | ||
| 191 | }; | ||
| 192 | |||
| 193 | static int ks_dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq, | ||
| 194 | irq_hw_number_t hwirq) | ||
| 195 | { | ||
| 196 | irq_set_chip_and_handler(irq, &ks_dw_pcie_msi_irq_chip, | ||
| 197 | handle_level_irq); | ||
| 198 | irq_set_chip_data(irq, domain->host_data); | ||
| 199 | set_irq_flags(irq, IRQF_VALID); | ||
| 200 | |||
| 201 | return 0; | ||
| 202 | } | ||
| 203 | |||
| 204 | const struct irq_domain_ops ks_dw_pcie_msi_domain_ops = { | ||
| 205 | .map = ks_dw_pcie_msi_map, | ||
| 206 | }; | ||
| 207 | |||
| 208 | int ks_dw_pcie_msi_host_init(struct pcie_port *pp, struct msi_chip *chip) | ||
| 209 | { | ||
| 210 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pp); | ||
| 211 | int i; | ||
| 212 | |||
| 213 | pp->irq_domain = irq_domain_add_linear(ks_pcie->msi_intc_np, | ||
| 214 | MAX_MSI_IRQS, | ||
| 215 | &ks_dw_pcie_msi_domain_ops, | ||
| 216 | chip); | ||
| 217 | if (!pp->irq_domain) { | ||
| 218 | dev_err(pp->dev, "irq domain init failed\n"); | ||
| 219 | return -ENXIO; | ||
| 220 | } | ||
| 221 | |||
| 222 | for (i = 0; i < MAX_MSI_IRQS; i++) | ||
| 223 | irq_create_mapping(pp->irq_domain, i); | ||
| 224 | |||
| 225 | return 0; | ||
| 226 | } | ||
| 227 | |||
| 228 | void ks_dw_pcie_enable_legacy_irqs(struct keystone_pcie *ks_pcie) | ||
| 229 | { | ||
| 230 | int i; | ||
| 231 | |||
| 232 | for (i = 0; i < MAX_LEGACY_IRQS; i++) | ||
| 233 | writel(0x1, ks_pcie->va_app_base + IRQ_ENABLE_SET + (i << 4)); | ||
| 234 | } | ||
| 235 | |||
| 236 | void ks_dw_pcie_handle_legacy_irq(struct keystone_pcie *ks_pcie, int offset) | ||
| 237 | { | ||
| 238 | struct pcie_port *pp = &ks_pcie->pp; | ||
| 239 | u32 pending; | ||
| 240 | int virq; | ||
| 241 | |||
| 242 | pending = readl(ks_pcie->va_app_base + IRQ_STATUS + (offset << 4)); | ||
| 243 | |||
| 244 | if (BIT(0) & pending) { | ||
| 245 | virq = irq_linear_revmap(ks_pcie->legacy_irq_domain, offset); | ||
| 246 | dev_dbg(pp->dev, ": irq: irq_offset %d, virq %d\n", offset, | ||
| 247 | virq); | ||
| 248 | generic_handle_irq(virq); | ||
| 249 | } | ||
| 250 | |||
| 251 | /* EOI the INTx interrupt */ | ||
| 252 | writel(offset, ks_pcie->va_app_base + IRQ_EOI); | ||
| 253 | } | ||
| 254 | |||
| 255 | static void ks_dw_pcie_ack_legacy_irq(struct irq_data *d) | ||
| 256 | { | ||
| 257 | } | ||
| 258 | |||
| 259 | static void ks_dw_pcie_mask_legacy_irq(struct irq_data *d) | ||
| 260 | { | ||
| 261 | } | ||
| 262 | |||
| 263 | static void ks_dw_pcie_unmask_legacy_irq(struct irq_data *d) | ||
| 264 | { | ||
| 265 | } | ||
| 266 | |||
| 267 | static struct irq_chip ks_dw_pcie_legacy_irq_chip = { | ||
| 268 | .name = "Keystone-PCI-Legacy-IRQ", | ||
| 269 | .irq_ack = ks_dw_pcie_ack_legacy_irq, | ||
| 270 | .irq_mask = ks_dw_pcie_mask_legacy_irq, | ||
| 271 | .irq_unmask = ks_dw_pcie_unmask_legacy_irq, | ||
| 272 | }; | ||
| 273 | |||
| 274 | static int ks_dw_pcie_init_legacy_irq_map(struct irq_domain *d, | ||
| 275 | unsigned int irq, irq_hw_number_t hw_irq) | ||
| 276 | { | ||
| 277 | irq_set_chip_and_handler(irq, &ks_dw_pcie_legacy_irq_chip, | ||
| 278 | handle_level_irq); | ||
| 279 | irq_set_chip_data(irq, d->host_data); | ||
| 280 | set_irq_flags(irq, IRQF_VALID); | ||
| 281 | |||
| 282 | return 0; | ||
| 283 | } | ||
| 284 | |||
| 285 | static const struct irq_domain_ops ks_dw_pcie_legacy_irq_domain_ops = { | ||
| 286 | .map = ks_dw_pcie_init_legacy_irq_map, | ||
| 287 | .xlate = irq_domain_xlate_onetwocell, | ||
| 288 | }; | ||
| 289 | |||
| 290 | /** | ||
| 291 | * ks_dw_pcie_set_dbi_mode() - Set DBI mode to access overlaid BAR mask | ||
| 292 | * registers | ||
| 293 | * | ||
| 294 | * Since modification of dbi_cs2 involves different clock domain, read the | ||
| 295 | * status back to ensure the transition is complete. | ||
| 296 | */ | ||
| 297 | static void ks_dw_pcie_set_dbi_mode(void __iomem *reg_virt) | ||
| 298 | { | ||
| 299 | u32 val; | ||
| 300 | |||
| 301 | writel(DBI_CS2_EN_VAL | readl(reg_virt + CMD_STATUS), | ||
| 302 | reg_virt + CMD_STATUS); | ||
| 303 | |||
| 304 | do { | ||
| 305 | val = readl(reg_virt + CMD_STATUS); | ||
| 306 | } while (!(val & DBI_CS2_EN_VAL)); | ||
| 307 | } | ||
| 308 | |||
| 309 | /** | ||
| 310 | * ks_dw_pcie_clear_dbi_mode() - Disable DBI mode | ||
| 311 | * | ||
| 312 | * Since modification of dbi_cs2 involves different clock domain, read the | ||
| 313 | * status back to ensure the transition is complete. | ||
| 314 | */ | ||
| 315 | static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt) | ||
| 316 | { | ||
| 317 | u32 val; | ||
| 318 | |||
| 319 | writel(~DBI_CS2_EN_VAL & readl(reg_virt + CMD_STATUS), | ||
| 320 | reg_virt + CMD_STATUS); | ||
| 321 | |||
| 322 | do { | ||
| 323 | val = readl(reg_virt + CMD_STATUS); | ||
| 324 | } while (val & DBI_CS2_EN_VAL); | ||
| 325 | } | ||
| 326 | |||
| 327 | void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie) | ||
| 328 | { | ||
| 329 | struct pcie_port *pp = &ks_pcie->pp; | ||
| 330 | u32 start = pp->mem.start, end = pp->mem.end; | ||
| 331 | int i, tr_size; | ||
| 332 | |||
| 333 | /* Disable BARs for inbound access */ | ||
| 334 | ks_dw_pcie_set_dbi_mode(ks_pcie->va_app_base); | ||
| 335 | writel(0, pp->dbi_base + PCI_BASE_ADDRESS_0); | ||
| 336 | writel(0, pp->dbi_base + PCI_BASE_ADDRESS_1); | ||
| 337 | ks_dw_pcie_clear_dbi_mode(ks_pcie->va_app_base); | ||
| 338 | |||
| 339 | /* Set outbound translation size per window division */ | ||
| 340 | writel(CFG_PCIM_WIN_SZ_IDX & 0x7, ks_pcie->va_app_base + OB_SIZE); | ||
| 341 | |||
| 342 | tr_size = (1 << (CFG_PCIM_WIN_SZ_IDX & 0x7)) * SZ_1M; | ||
| 343 | |||
| 344 | /* Using Direct 1:1 mapping of RC <-> PCI memory space */ | ||
| 345 | for (i = 0; (i < CFG_PCIM_WIN_CNT) && (start < end); i++) { | ||
| 346 | writel(start | 1, ks_pcie->va_app_base + OB_OFFSET_INDEX(i)); | ||
| 347 | writel(0, ks_pcie->va_app_base + OB_OFFSET_HI(i)); | ||
| 348 | start += tr_size; | ||
| 349 | } | ||
| 350 | |||
| 351 | /* Enable OB translation */ | ||
| 352 | writel(OB_XLAT_EN_VAL | readl(ks_pcie->va_app_base + CMD_STATUS), | ||
| 353 | ks_pcie->va_app_base + CMD_STATUS); | ||
| 354 | } | ||
| 355 | |||
| 356 | /** | ||
| 357 | * ks_pcie_cfg_setup() - Set up configuration space address for a device | ||
| 358 | * | ||
| 359 | * @ks_pcie: ptr to keystone_pcie structure | ||
| 360 | * @bus: Bus number the device is residing on | ||
| 361 | * @devfn: device, function number info | ||
| 362 | * | ||
| 363 | * Forms and returns the address of configuration space mapped in PCIESS | ||
| 364 | * address space 0. Also configures CFG_SETUP for remote configuration space | ||
| 365 | * access. | ||
| 366 | * | ||
| 367 | * The address space has two regions to access configuration - local and remote. | ||
| 368 | * We access local region for bus 0 (as RC is attached on bus 0) and remote | ||
| 369 | * region for others with TYPE 1 access when bus > 1. As for device on bus = 1, | ||
| 370 | * we will do TYPE 0 access as it will be on our secondary bus (logical). | ||
| 371 | * CFG_SETUP is needed only for remote configuration access. | ||
| 372 | */ | ||
| 373 | static void __iomem *ks_pcie_cfg_setup(struct keystone_pcie *ks_pcie, u8 bus, | ||
| 374 | unsigned int devfn) | ||
| 375 | { | ||
| 376 | u8 device = PCI_SLOT(devfn), function = PCI_FUNC(devfn); | ||
| 377 | struct pcie_port *pp = &ks_pcie->pp; | ||
| 378 | u32 regval; | ||
| 379 | |||
| 380 | if (bus == 0) | ||
| 381 | return pp->dbi_base; | ||
| 382 | |||
| 383 | regval = (bus << 16) | (device << 8) | function; | ||
| 384 | |||
| 385 | /* | ||
| 386 | * Since Bus#1 will be a virtual bus, we need to have TYPE0 | ||
| 387 | * access only. | ||
| 388 | * TYPE 1 | ||
| 389 | */ | ||
| 390 | if (bus != 1) | ||
| 391 | regval |= BIT(24); | ||
| 392 | |||
| 393 | writel(regval, ks_pcie->va_app_base + CFG_SETUP); | ||
| 394 | return pp->va_cfg0_base; | ||
| 395 | } | ||
| 396 | |||
| 397 | int ks_dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | ||
| 398 | unsigned int devfn, int where, int size, u32 *val) | ||
| 399 | { | ||
| 400 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pp); | ||
| 401 | u8 bus_num = bus->number; | ||
| 402 | void __iomem *addr; | ||
| 403 | |||
| 404 | addr = ks_pcie_cfg_setup(ks_pcie, bus_num, devfn); | ||
| 405 | |||
| 406 | return dw_pcie_cfg_read(addr + (where & ~0x3), where, size, val); | ||
| 407 | } | ||
| 408 | |||
| 409 | int ks_dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, | ||
| 410 | unsigned int devfn, int where, int size, u32 val) | ||
| 411 | { | ||
| 412 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pp); | ||
| 413 | u8 bus_num = bus->number; | ||
| 414 | void __iomem *addr; | ||
| 415 | |||
| 416 | addr = ks_pcie_cfg_setup(ks_pcie, bus_num, devfn); | ||
| 417 | |||
| 418 | return dw_pcie_cfg_write(addr + (where & ~0x3), where, size, val); | ||
| 419 | } | ||
| 420 | |||
| 421 | /** | ||
| 422 | * ks_dw_pcie_v3_65_scan_bus() - keystone scan_bus post initialization | ||
| 423 | * | ||
| 424 | * This sets BAR0 to enable inbound access for MSI_IRQ register | ||
| 425 | */ | ||
| 426 | void ks_dw_pcie_v3_65_scan_bus(struct pcie_port *pp) | ||
| 427 | { | ||
| 428 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pp); | ||
| 429 | |||
| 430 | /* Configure and set up BAR0 */ | ||
| 431 | ks_dw_pcie_set_dbi_mode(ks_pcie->va_app_base); | ||
| 432 | |||
| 433 | /* Enable BAR0 */ | ||
| 434 | writel(1, pp->dbi_base + PCI_BASE_ADDRESS_0); | ||
| 435 | writel(SZ_4K - 1, pp->dbi_base + PCI_BASE_ADDRESS_0); | ||
| 436 | |||
| 437 | ks_dw_pcie_clear_dbi_mode(ks_pcie->va_app_base); | ||
| 438 | |||
| 439 | /* | ||
| 440 | * For BAR0, just setting bus address for inbound writes (MSI) should | ||
| 441 | * be sufficient. Use physical address to avoid any conflicts. | ||
| 442 | */ | ||
| 443 | writel(ks_pcie->app.start, pp->dbi_base + PCI_BASE_ADDRESS_0); | ||
| 444 | } | ||
| 445 | |||
| 446 | /** | ||
| 447 | * ks_dw_pcie_link_up() - Check if link up | ||
| 448 | */ | ||
| 449 | int ks_dw_pcie_link_up(struct pcie_port *pp) | ||
| 450 | { | ||
| 451 | u32 val = readl(pp->dbi_base + DEBUG0); | ||
| 452 | |||
| 453 | return (val & LTSSM_STATE_MASK) == LTSSM_STATE_L0; | ||
| 454 | } | ||
| 455 | |||
| 456 | void ks_dw_pcie_initiate_link_train(struct keystone_pcie *ks_pcie) | ||
| 457 | { | ||
| 458 | u32 val; | ||
| 459 | |||
| 460 | /* Disable Link training */ | ||
| 461 | val = readl(ks_pcie->va_app_base + CMD_STATUS); | ||
| 462 | val &= ~LTSSM_EN_VAL; | ||
| 463 | writel(LTSSM_EN_VAL | val, ks_pcie->va_app_base + CMD_STATUS); | ||
| 464 | |||
| 465 | /* Initiate Link Training */ | ||
| 466 | val = readl(ks_pcie->va_app_base + CMD_STATUS); | ||
| 467 | writel(LTSSM_EN_VAL | val, ks_pcie->va_app_base + CMD_STATUS); | ||
| 468 | } | ||
| 469 | |||
| 470 | /** | ||
| 471 | * ks_dw_pcie_host_init() - initialize host for v3_65 dw hardware | ||
| 472 | * | ||
| 473 | * Ioremap the register resources, initialize legacy irq domain | ||
| 474 | * and call dw_pcie_v3_65_host_init() API to initialize the Keystone | ||
| 475 | * PCI host controller. | ||
| 476 | */ | ||
| 477 | int __init ks_dw_pcie_host_init(struct keystone_pcie *ks_pcie, | ||
| 478 | struct device_node *msi_intc_np) | ||
| 479 | { | ||
| 480 | struct pcie_port *pp = &ks_pcie->pp; | ||
| 481 | struct platform_device *pdev = to_platform_device(pp->dev); | ||
| 482 | struct resource *res; | ||
| 483 | |||
| 484 | /* Index 0 is the config reg. space address */ | ||
| 485 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 486 | pp->dbi_base = devm_ioremap_resource(pp->dev, res); | ||
| 487 | if (IS_ERR(pp->dbi_base)) | ||
| 488 | return PTR_ERR(pp->dbi_base); | ||
| 489 | |||
| 490 | /* | ||
| 491 | * We set these same and is used in pcie rd/wr_other_conf | ||
| 492 | * functions | ||
| 493 | */ | ||
| 494 | pp->va_cfg0_base = pp->dbi_base + SPACE0_REMOTE_CFG_OFFSET; | ||
| 495 | pp->va_cfg1_base = pp->va_cfg0_base; | ||
| 496 | |||
| 497 | /* Index 1 is the application reg. space address */ | ||
| 498 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
| 499 | ks_pcie->app = *res; | ||
| 500 | ks_pcie->va_app_base = devm_ioremap_resource(pp->dev, res); | ||
| 501 | if (IS_ERR(ks_pcie->va_app_base)) | ||
| 502 | return PTR_ERR(ks_pcie->va_app_base); | ||
| 503 | |||
| 504 | /* Create legacy IRQ domain */ | ||
| 505 | ks_pcie->legacy_irq_domain = | ||
| 506 | irq_domain_add_linear(ks_pcie->legacy_intc_np, | ||
| 507 | MAX_LEGACY_IRQS, | ||
| 508 | &ks_dw_pcie_legacy_irq_domain_ops, | ||
| 509 | NULL); | ||
| 510 | if (!ks_pcie->legacy_irq_domain) { | ||
| 511 | dev_err(pp->dev, "Failed to add irq domain for legacy irqs\n"); | ||
| 512 | return -EINVAL; | ||
| 513 | } | ||
| 514 | |||
| 515 | return dw_pcie_host_init(pp); | ||
| 516 | } | ||
diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c new file mode 100644 index 000000000000..1b893bc8b842 --- /dev/null +++ b/drivers/pci/host/pci-keystone.c | |||
| @@ -0,0 +1,415 @@ | |||
| 1 | /* | ||
| 2 | * PCIe host controller driver for Texas Instruments Keystone SoCs | ||
| 3 | * | ||
| 4 | * Copyright (C) 2013-2014 Texas Instruments., Ltd. | ||
| 5 | * http://www.ti.com | ||
| 6 | * | ||
| 7 | * Author: Murali Karicheri <m-karicheri2@ti.com> | ||
| 8 | * Implementation based on pci-exynos.c and pcie-designware.c | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/irqchip/chained_irq.h> | ||
| 16 | #include <linux/clk.h> | ||
| 17 | #include <linux/delay.h> | ||
| 18 | #include <linux/irqdomain.h> | ||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/msi.h> | ||
| 21 | #include <linux/of_irq.h> | ||
| 22 | #include <linux/of.h> | ||
| 23 | #include <linux/of_pci.h> | ||
| 24 | #include <linux/platform_device.h> | ||
| 25 | #include <linux/phy/phy.h> | ||
| 26 | #include <linux/resource.h> | ||
| 27 | #include <linux/signal.h> | ||
| 28 | |||
| 29 | #include "pcie-designware.h" | ||
| 30 | #include "pci-keystone.h" | ||
| 31 | |||
| 32 | #define DRIVER_NAME "keystone-pcie" | ||
| 33 | |||
| 34 | /* driver specific constants */ | ||
| 35 | #define MAX_MSI_HOST_IRQS 8 | ||
| 36 | #define MAX_LEGACY_HOST_IRQS 4 | ||
| 37 | |||
| 38 | /* DEV_STAT_CTRL */ | ||
| 39 | #define PCIE_CAP_BASE 0x70 | ||
| 40 | |||
| 41 | /* PCIE controller device IDs */ | ||
| 42 | #define PCIE_RC_K2HK 0xb008 | ||
| 43 | #define PCIE_RC_K2E 0xb009 | ||
| 44 | #define PCIE_RC_K2L 0xb00a | ||
| 45 | |||
| 46 | #define to_keystone_pcie(x) container_of(x, struct keystone_pcie, pp) | ||
| 47 | |||
| 48 | static void quirk_limit_mrrs(struct pci_dev *dev) | ||
| 49 | { | ||
| 50 | struct pci_bus *bus = dev->bus; | ||
| 51 | struct pci_dev *bridge = bus->self; | ||
| 52 | static const struct pci_device_id rc_pci_devids[] = { | ||
| 53 | { PCI_DEVICE(PCI_VENDOR_ID_TI, PCIE_RC_K2HK), | ||
| 54 | .class = PCI_CLASS_BRIDGE_PCI << 8, .class_mask = ~0, }, | ||
| 55 | { PCI_DEVICE(PCI_VENDOR_ID_TI, PCIE_RC_K2E), | ||
| 56 | .class = PCI_CLASS_BRIDGE_PCI << 8, .class_mask = ~0, }, | ||
| 57 | { PCI_DEVICE(PCI_VENDOR_ID_TI, PCIE_RC_K2L), | ||
| 58 | .class = PCI_CLASS_BRIDGE_PCI << 8, .class_mask = ~0, }, | ||
| 59 | { 0, }, | ||
| 60 | }; | ||
| 61 | |||
| 62 | if (pci_is_root_bus(bus)) | ||
| 63 | return; | ||
| 64 | |||
| 65 | /* look for the host bridge */ | ||
| 66 | while (!pci_is_root_bus(bus)) { | ||
| 67 | bridge = bus->self; | ||
| 68 | bus = bus->parent; | ||
| 69 | } | ||
| 70 | |||
| 71 | if (bridge) { | ||
| 72 | /* | ||
| 73 | * Keystone PCI controller has a h/w limitation of | ||
| 74 | * 256 bytes maximum read request size. It can't handle | ||
| 75 | * anything higher than this. So force this limit on | ||
| 76 | * all downstream devices. | ||
| 77 | */ | ||
| 78 | if (pci_match_id(rc_pci_devids, bridge)) { | ||
| 79 | if (pcie_get_readrq(dev) > 256) { | ||
| 80 | dev_info(&dev->dev, "limiting MRRS to 256\n"); | ||
| 81 | pcie_set_readrq(dev, 256); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
| 85 | } | ||
| 86 | DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, quirk_limit_mrrs); | ||
| 87 | |||
| 88 | static int ks_pcie_establish_link(struct keystone_pcie *ks_pcie) | ||
| 89 | { | ||
| 90 | struct pcie_port *pp = &ks_pcie->pp; | ||
| 91 | int count = 200; | ||
| 92 | |||
| 93 | dw_pcie_setup_rc(pp); | ||
| 94 | |||
| 95 | if (dw_pcie_link_up(pp)) { | ||
| 96 | dev_err(pp->dev, "Link already up\n"); | ||
| 97 | return 0; | ||
| 98 | } | ||
| 99 | |||
| 100 | ks_dw_pcie_initiate_link_train(ks_pcie); | ||
| 101 | /* check if the link is up or not */ | ||
| 102 | while (!dw_pcie_link_up(pp)) { | ||
| 103 | usleep_range(100, 1000); | ||
| 104 | if (--count) { | ||
| 105 | ks_dw_pcie_initiate_link_train(ks_pcie); | ||
| 106 | continue; | ||
| 107 | } | ||
| 108 | dev_err(pp->dev, "phy link never came up\n"); | ||
| 109 | return -EINVAL; | ||
| 110 | } | ||
| 111 | |||
| 112 | return 0; | ||
| 113 | } | ||
| 114 | |||
| 115 | static void ks_pcie_msi_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
| 116 | { | ||
| 117 | struct keystone_pcie *ks_pcie = irq_desc_get_handler_data(desc); | ||
| 118 | u32 offset = irq - ks_pcie->msi_host_irqs[0]; | ||
| 119 | struct pcie_port *pp = &ks_pcie->pp; | ||
| 120 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
| 121 | |||
| 122 | dev_dbg(pp->dev, "ks_pci_msi_irq_handler, irq %d\n", irq); | ||
| 123 | |||
| 124 | /* | ||
| 125 | * The chained irq handler installation would have replaced normal | ||
| 126 | * interrupt driver handler so we need to take care of mask/unmask and | ||
| 127 | * ack operation. | ||
| 128 | */ | ||
| 129 | chained_irq_enter(chip, desc); | ||
| 130 | ks_dw_pcie_handle_msi_irq(ks_pcie, offset); | ||
| 131 | chained_irq_exit(chip, desc); | ||
| 132 | } | ||
| 133 | |||
| 134 | /** | ||
| 135 | * ks_pcie_legacy_irq_handler() - Handle legacy interrupt | ||
| 136 | * @irq: IRQ line for legacy interrupts | ||
| 137 | * @desc: Pointer to irq descriptor | ||
| 138 | * | ||
| 139 | * Traverse through pending legacy interrupts and invoke handler for each. Also | ||
| 140 | * takes care of interrupt controller level mask/ack operation. | ||
| 141 | */ | ||
| 142 | static void ks_pcie_legacy_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
| 143 | { | ||
| 144 | struct keystone_pcie *ks_pcie = irq_desc_get_handler_data(desc); | ||
| 145 | struct pcie_port *pp = &ks_pcie->pp; | ||
| 146 | u32 irq_offset = irq - ks_pcie->legacy_host_irqs[0]; | ||
| 147 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
| 148 | |||
| 149 | dev_dbg(pp->dev, ": Handling legacy irq %d\n", irq); | ||
| 150 | |||
| 151 | /* | ||
| 152 | * The chained irq handler installation would have replaced normal | ||
| 153 | * interrupt driver handler so we need to take care of mask/unmask and | ||
| 154 | * ack operation. | ||
| 155 | */ | ||
| 156 | chained_irq_enter(chip, desc); | ||
| 157 | ks_dw_pcie_handle_legacy_irq(ks_pcie, irq_offset); | ||
| 158 | chained_irq_exit(chip, desc); | ||
| 159 | } | ||
| 160 | |||
| 161 | static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie, | ||
| 162 | char *controller, int *num_irqs) | ||
| 163 | { | ||
| 164 | int temp, max_host_irqs, legacy = 1, *host_irqs, ret = -EINVAL; | ||
| 165 | struct device *dev = ks_pcie->pp.dev; | ||
| 166 | struct device_node *np_pcie = dev->of_node, **np_temp; | ||
| 167 | |||
| 168 | if (!strcmp(controller, "msi-interrupt-controller")) | ||
| 169 | legacy = 0; | ||
| 170 | |||
| 171 | if (legacy) { | ||
| 172 | np_temp = &ks_pcie->legacy_intc_np; | ||
| 173 | max_host_irqs = MAX_LEGACY_HOST_IRQS; | ||
| 174 | host_irqs = &ks_pcie->legacy_host_irqs[0]; | ||
| 175 | } else { | ||
| 176 | np_temp = &ks_pcie->msi_intc_np; | ||
| 177 | max_host_irqs = MAX_MSI_HOST_IRQS; | ||
| 178 | host_irqs = &ks_pcie->msi_host_irqs[0]; | ||
| 179 | } | ||
| 180 | |||
| 181 | /* interrupt controller is in a child node */ | ||
| 182 | *np_temp = of_find_node_by_name(np_pcie, controller); | ||
| 183 | if (!(*np_temp)) { | ||
| 184 | dev_err(dev, "Node for %s is absent\n", controller); | ||
| 185 | goto out; | ||
| 186 | } | ||
| 187 | temp = of_irq_count(*np_temp); | ||
| 188 | if (!temp) | ||
| 189 | goto out; | ||
| 190 | if (temp > max_host_irqs) | ||
| 191 | dev_warn(dev, "Too many %s interrupts defined %u\n", | ||
| 192 | (legacy ? "legacy" : "MSI"), temp); | ||
| 193 | |||
| 194 | /* | ||
| 195 | * support upto max_host_irqs. In dt from index 0 to 3 (legacy) or 0 to | ||
| 196 | * 7 (MSI) | ||
| 197 | */ | ||
| 198 | for (temp = 0; temp < max_host_irqs; temp++) { | ||
| 199 | host_irqs[temp] = irq_of_parse_and_map(*np_temp, temp); | ||
| 200 | if (host_irqs[temp] < 0) | ||
| 201 | break; | ||
| 202 | } | ||
| 203 | if (temp) { | ||
| 204 | *num_irqs = temp; | ||
| 205 | ret = 0; | ||
| 206 | } | ||
| 207 | out: | ||
| 208 | return ret; | ||
| 209 | } | ||
| 210 | |||
| 211 | static void ks_pcie_setup_interrupts(struct keystone_pcie *ks_pcie) | ||
| 212 | { | ||
| 213 | int i; | ||
| 214 | |||
| 215 | /* Legacy IRQ */ | ||
| 216 | for (i = 0; i < ks_pcie->num_legacy_host_irqs; i++) { | ||
| 217 | irq_set_handler_data(ks_pcie->legacy_host_irqs[i], ks_pcie); | ||
| 218 | irq_set_chained_handler(ks_pcie->legacy_host_irqs[i], | ||
| 219 | ks_pcie_legacy_irq_handler); | ||
| 220 | } | ||
| 221 | ks_dw_pcie_enable_legacy_irqs(ks_pcie); | ||
| 222 | |||
| 223 | /* MSI IRQ */ | ||
| 224 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | ||
| 225 | for (i = 0; i < ks_pcie->num_msi_host_irqs; i++) { | ||
| 226 | irq_set_chained_handler(ks_pcie->msi_host_irqs[i], | ||
| 227 | ks_pcie_msi_irq_handler); | ||
| 228 | irq_set_handler_data(ks_pcie->msi_host_irqs[i], | ||
| 229 | ks_pcie); | ||
| 230 | } | ||
| 231 | } | ||
| 232 | } | ||
| 233 | |||
| 234 | /* | ||
| 235 | * When a PCI device does not exist during config cycles, keystone host gets a | ||
| 236 | * bus error instead of returning 0xffffffff. This handler always returns 0 | ||
| 237 | * for this kind of faults. | ||
| 238 | */ | ||
| 239 | static int keystone_pcie_fault(unsigned long addr, unsigned int fsr, | ||
| 240 | struct pt_regs *regs) | ||
| 241 | { | ||
| 242 | unsigned long instr = *(unsigned long *) instruction_pointer(regs); | ||
| 243 | |||
| 244 | if ((instr & 0x0e100090) == 0x00100090) { | ||
| 245 | int reg = (instr >> 12) & 15; | ||
| 246 | |||
| 247 | regs->uregs[reg] = -1; | ||
| 248 | regs->ARM_pc += 4; | ||
| 249 | } | ||
| 250 | |||
| 251 | return 0; | ||
| 252 | } | ||
| 253 | |||
| 254 | static void __init ks_pcie_host_init(struct pcie_port *pp) | ||
| 255 | { | ||
| 256 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pp); | ||
| 257 | u32 val; | ||
| 258 | |||
| 259 | ks_pcie_establish_link(ks_pcie); | ||
| 260 | ks_dw_pcie_setup_rc_app_regs(ks_pcie); | ||
| 261 | ks_pcie_setup_interrupts(ks_pcie); | ||
| 262 | writew(PCI_IO_RANGE_TYPE_32 | (PCI_IO_RANGE_TYPE_32 << 8), | ||
| 263 | pp->dbi_base + PCI_IO_BASE); | ||
| 264 | |||
| 265 | /* update the Vendor ID */ | ||
| 266 | writew(ks_pcie->device_id, pp->dbi_base + PCI_DEVICE_ID); | ||
| 267 | |||
| 268 | /* update the DEV_STAT_CTRL to publish right mrrs */ | ||
| 269 | val = readl(pp->dbi_base + PCIE_CAP_BASE + PCI_EXP_DEVCTL); | ||
| 270 | val &= ~PCI_EXP_DEVCTL_READRQ; | ||
| 271 | /* set the mrrs to 256 bytes */ | ||
| 272 | val |= BIT(12); | ||
| 273 | writel(val, pp->dbi_base + PCIE_CAP_BASE + PCI_EXP_DEVCTL); | ||
| 274 | |||
| 275 | /* | ||
| 276 | * PCIe access errors that result into OCP errors are caught by ARM as | ||
| 277 | * "External aborts" | ||
| 278 | */ | ||
| 279 | hook_fault_code(17, keystone_pcie_fault, SIGBUS, 0, | ||
| 280 | "Asynchronous external abort"); | ||
| 281 | } | ||
| 282 | |||
| 283 | static struct pcie_host_ops keystone_pcie_host_ops = { | ||
| 284 | .rd_other_conf = ks_dw_pcie_rd_other_conf, | ||
| 285 | .wr_other_conf = ks_dw_pcie_wr_other_conf, | ||
| 286 | .link_up = ks_dw_pcie_link_up, | ||
| 287 | .host_init = ks_pcie_host_init, | ||
| 288 | .msi_set_irq = ks_dw_pcie_msi_set_irq, | ||
| 289 | .msi_clear_irq = ks_dw_pcie_msi_clear_irq, | ||
| 290 | .get_msi_addr = ks_dw_pcie_get_msi_addr, | ||
| 291 | .msi_host_init = ks_dw_pcie_msi_host_init, | ||
| 292 | .scan_bus = ks_dw_pcie_v3_65_scan_bus, | ||
| 293 | }; | ||
| 294 | |||
| 295 | static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie, | ||
| 296 | struct platform_device *pdev) | ||
| 297 | { | ||
| 298 | struct pcie_port *pp = &ks_pcie->pp; | ||
| 299 | int ret; | ||
| 300 | |||
| 301 | ret = ks_pcie_get_irq_controller_info(ks_pcie, | ||
| 302 | "legacy-interrupt-controller", | ||
| 303 | &ks_pcie->num_legacy_host_irqs); | ||
| 304 | if (ret) | ||
| 305 | return ret; | ||
| 306 | |||
| 307 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | ||
| 308 | ret = ks_pcie_get_irq_controller_info(ks_pcie, | ||
| 309 | "msi-interrupt-controller", | ||
| 310 | &ks_pcie->num_msi_host_irqs); | ||
| 311 | if (ret) | ||
| 312 | return ret; | ||
| 313 | } | ||
| 314 | |||
| 315 | pp->root_bus_nr = -1; | ||
| 316 | pp->ops = &keystone_pcie_host_ops; | ||
| 317 | ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np); | ||
| 318 | if (ret) { | ||
| 319 | dev_err(&pdev->dev, "failed to initialize host\n"); | ||
| 320 | return ret; | ||
| 321 | } | ||
| 322 | |||
| 323 | return ret; | ||
| 324 | } | ||
| 325 | |||
| 326 | static const struct of_device_id ks_pcie_of_match[] = { | ||
| 327 | { | ||
| 328 | .type = "pci", | ||
| 329 | .compatible = "ti,keystone-pcie", | ||
| 330 | }, | ||
| 331 | { }, | ||
| 332 | }; | ||
| 333 | MODULE_DEVICE_TABLE(of, ks_pcie_of_match); | ||
| 334 | |||
| 335 | static int __exit ks_pcie_remove(struct platform_device *pdev) | ||
| 336 | { | ||
| 337 | struct keystone_pcie *ks_pcie = platform_get_drvdata(pdev); | ||
| 338 | |||
| 339 | clk_disable_unprepare(ks_pcie->clk); | ||
| 340 | |||
| 341 | return 0; | ||
| 342 | } | ||
| 343 | |||
| 344 | static int __init ks_pcie_probe(struct platform_device *pdev) | ||
| 345 | { | ||
| 346 | struct device *dev = &pdev->dev; | ||
| 347 | struct keystone_pcie *ks_pcie; | ||
| 348 | struct pcie_port *pp; | ||
| 349 | struct resource *res; | ||
| 350 | void __iomem *reg_p; | ||
| 351 | struct phy *phy; | ||
| 352 | int ret = 0; | ||
| 353 | |||
| 354 | ks_pcie = devm_kzalloc(&pdev->dev, sizeof(*ks_pcie), | ||
| 355 | GFP_KERNEL); | ||
| 356 | if (!ks_pcie) { | ||
| 357 | dev_err(dev, "no memory for keystone pcie\n"); | ||
| 358 | return -ENOMEM; | ||
| 359 | } | ||
| 360 | pp = &ks_pcie->pp; | ||
| 361 | |||
| 362 | /* initialize SerDes Phy if present */ | ||
| 363 | phy = devm_phy_get(dev, "pcie-phy"); | ||
| 364 | if (!IS_ERR_OR_NULL(phy)) { | ||
| 365 | ret = phy_init(phy); | ||
| 366 | if (ret < 0) | ||
| 367 | return ret; | ||
| 368 | } | ||
| 369 | |||
| 370 | /* index 2 is to read PCI DEVICE_ID */ | ||
| 371 | res = platform_get_resource(pdev, IORESOURCE_MEM, 2); | ||
| 372 | reg_p = devm_ioremap_resource(dev, res); | ||
| 373 | if (IS_ERR(reg_p)) | ||
| 374 | return PTR_ERR(reg_p); | ||
| 375 | ks_pcie->device_id = readl(reg_p) >> 16; | ||
| 376 | devm_iounmap(dev, reg_p); | ||
| 377 | devm_release_mem_region(dev, res->start, resource_size(res)); | ||
| 378 | |||
| 379 | pp->dev = dev; | ||
| 380 | platform_set_drvdata(pdev, ks_pcie); | ||
| 381 | ks_pcie->clk = devm_clk_get(dev, "pcie"); | ||
| 382 | if (IS_ERR(ks_pcie->clk)) { | ||
| 383 | dev_err(dev, "Failed to get pcie rc clock\n"); | ||
| 384 | return PTR_ERR(ks_pcie->clk); | ||
| 385 | } | ||
| 386 | ret = clk_prepare_enable(ks_pcie->clk); | ||
| 387 | if (ret) | ||
| 388 | return ret; | ||
| 389 | |||
| 390 | ret = ks_add_pcie_port(ks_pcie, pdev); | ||
| 391 | if (ret < 0) | ||
| 392 | goto fail_clk; | ||
| 393 | |||
| 394 | return 0; | ||
| 395 | fail_clk: | ||
| 396 | clk_disable_unprepare(ks_pcie->clk); | ||
| 397 | |||
| 398 | return ret; | ||
| 399 | } | ||
| 400 | |||
| 401 | static struct platform_driver ks_pcie_driver __refdata = { | ||
| 402 | .probe = ks_pcie_probe, | ||
| 403 | .remove = __exit_p(ks_pcie_remove), | ||
| 404 | .driver = { | ||
| 405 | .name = "keystone-pcie", | ||
| 406 | .owner = THIS_MODULE, | ||
| 407 | .of_match_table = of_match_ptr(ks_pcie_of_match), | ||
| 408 | }, | ||
| 409 | }; | ||
| 410 | |||
| 411 | module_platform_driver(ks_pcie_driver); | ||
| 412 | |||
| 413 | MODULE_AUTHOR("Murali Karicheri <m-karicheri2@ti.com>"); | ||
| 414 | MODULE_DESCRIPTION("Keystone PCIe host controller driver"); | ||
| 415 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-keystone.h b/drivers/pci/host/pci-keystone.h new file mode 100644 index 000000000000..1fc1fceede9e --- /dev/null +++ b/drivers/pci/host/pci-keystone.h | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | /* | ||
| 2 | * Keystone PCI Controller's common includes | ||
| 3 | * | ||
| 4 | * Copyright (C) 2013-2014 Texas Instruments., Ltd. | ||
| 5 | * http://www.ti.com | ||
| 6 | * | ||
| 7 | * Author: Murali Karicheri <m-karicheri2@ti.com> | ||
| 8 | * | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #define MAX_LEGACY_IRQS 4 | ||
| 16 | #define MAX_MSI_HOST_IRQS 8 | ||
| 17 | #define MAX_LEGACY_HOST_IRQS 4 | ||
| 18 | |||
| 19 | struct keystone_pcie { | ||
| 20 | struct clk *clk; | ||
| 21 | struct pcie_port pp; | ||
| 22 | /* PCI Device ID */ | ||
| 23 | u32 device_id; | ||
| 24 | int num_legacy_host_irqs; | ||
| 25 | int legacy_host_irqs[MAX_LEGACY_HOST_IRQS]; | ||
| 26 | struct device_node *legacy_intc_np; | ||
| 27 | |||
| 28 | int num_msi_host_irqs; | ||
| 29 | int msi_host_irqs[MAX_MSI_HOST_IRQS]; | ||
| 30 | struct device_node *msi_intc_np; | ||
| 31 | struct irq_domain *legacy_irq_domain; | ||
| 32 | |||
| 33 | /* Application register space */ | ||
| 34 | void __iomem *va_app_base; | ||
| 35 | struct resource app; | ||
| 36 | }; | ||
| 37 | |||
| 38 | /* Keystone DW specific MSI controller APIs/definitions */ | ||
| 39 | void ks_dw_pcie_handle_msi_irq(struct keystone_pcie *ks_pcie, int offset); | ||
| 40 | u32 ks_dw_pcie_get_msi_addr(struct pcie_port *pp); | ||
| 41 | |||
| 42 | /* Keystone specific PCI controller APIs */ | ||
| 43 | void ks_dw_pcie_enable_legacy_irqs(struct keystone_pcie *ks_pcie); | ||
| 44 | void ks_dw_pcie_handle_legacy_irq(struct keystone_pcie *ks_pcie, int offset); | ||
| 45 | int ks_dw_pcie_host_init(struct keystone_pcie *ks_pcie, | ||
| 46 | struct device_node *msi_intc_np); | ||
| 47 | int ks_dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, | ||
| 48 | unsigned int devfn, int where, int size, u32 val); | ||
| 49 | int ks_dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | ||
| 50 | unsigned int devfn, int where, int size, u32 *val); | ||
| 51 | void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie); | ||
| 52 | int ks_dw_pcie_link_up(struct pcie_port *pp); | ||
| 53 | void ks_dw_pcie_initiate_link_train(struct keystone_pcie *ks_pcie); | ||
| 54 | void ks_dw_pcie_msi_set_irq(struct pcie_port *pp, int irq); | ||
| 55 | void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq); | ||
| 56 | void ks_dw_pcie_v3_65_scan_bus(struct pcie_port *pp); | ||
| 57 | int ks_dw_pcie_msi_host_init(struct pcie_port *pp, | ||
| 58 | struct msi_chip *chip); | ||
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index a8c6f1a92e0f..b1315e197ffb 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
| @@ -873,7 +873,7 @@ static int mvebu_get_tgt_attr(struct device_node *np, int devfn, | |||
| 873 | rangesz = pna + na + ns; | 873 | rangesz = pna + na + ns; |
| 874 | nranges = rlen / sizeof(__be32) / rangesz; | 874 | nranges = rlen / sizeof(__be32) / rangesz; |
| 875 | 875 | ||
| 876 | for (i = 0; i < nranges; i++) { | 876 | for (i = 0; i < nranges; i++, range += rangesz) { |
| 877 | u32 flags = of_read_number(range, 1); | 877 | u32 flags = of_read_number(range, 1); |
| 878 | u32 slot = of_read_number(range + 1, 1); | 878 | u32 slot = of_read_number(range + 1, 1); |
| 879 | u64 cpuaddr = of_read_number(range + na, pna); | 879 | u64 cpuaddr = of_read_number(range + na, pna); |
| @@ -883,14 +883,14 @@ static int mvebu_get_tgt_attr(struct device_node *np, int devfn, | |||
| 883 | rtype = IORESOURCE_IO; | 883 | rtype = IORESOURCE_IO; |
| 884 | else if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_MEM32) | 884 | else if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_MEM32) |
| 885 | rtype = IORESOURCE_MEM; | 885 | rtype = IORESOURCE_MEM; |
| 886 | else | ||
| 887 | continue; | ||
| 886 | 888 | ||
| 887 | if (slot == PCI_SLOT(devfn) && type == rtype) { | 889 | if (slot == PCI_SLOT(devfn) && type == rtype) { |
| 888 | *tgt = DT_CPUADDR_TO_TARGET(cpuaddr); | 890 | *tgt = DT_CPUADDR_TO_TARGET(cpuaddr); |
| 889 | *attr = DT_CPUADDR_TO_ATTR(cpuaddr); | 891 | *attr = DT_CPUADDR_TO_ATTR(cpuaddr); |
| 890 | return 0; | 892 | return 0; |
| 891 | } | 893 | } |
| 892 | |||
| 893 | range += rangesz; | ||
| 894 | } | 894 | } |
| 895 | 895 | ||
| 896 | return -ENOENT; | 896 | return -ENOENT; |
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 0fb0fdb223d5..3d43874319be 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include <linux/of_pci.h> | 38 | #include <linux/of_pci.h> |
| 39 | #include <linux/of_platform.h> | 39 | #include <linux/of_platform.h> |
| 40 | #include <linux/pci.h> | 40 | #include <linux/pci.h> |
| 41 | #include <linux/phy/phy.h> | ||
| 41 | #include <linux/platform_device.h> | 42 | #include <linux/platform_device.h> |
| 42 | #include <linux/reset.h> | 43 | #include <linux/reset.h> |
| 43 | #include <linux/sizes.h> | 44 | #include <linux/sizes.h> |
| @@ -115,13 +116,20 @@ | |||
| 115 | 116 | ||
| 116 | #define AFI_INTR_CODE 0xb8 | 117 | #define AFI_INTR_CODE 0xb8 |
| 117 | #define AFI_INTR_CODE_MASK 0xf | 118 | #define AFI_INTR_CODE_MASK 0xf |
| 118 | #define AFI_INTR_AXI_SLAVE_ERROR 1 | 119 | #define AFI_INTR_INI_SLAVE_ERROR 1 |
| 119 | #define AFI_INTR_AXI_DECODE_ERROR 2 | 120 | #define AFI_INTR_INI_DECODE_ERROR 2 |
| 120 | #define AFI_INTR_TARGET_ABORT 3 | 121 | #define AFI_INTR_TARGET_ABORT 3 |
| 121 | #define AFI_INTR_MASTER_ABORT 4 | 122 | #define AFI_INTR_MASTER_ABORT 4 |
| 122 | #define AFI_INTR_INVALID_WRITE 5 | 123 | #define AFI_INTR_INVALID_WRITE 5 |
| 123 | #define AFI_INTR_LEGACY 6 | 124 | #define AFI_INTR_LEGACY 6 |
| 124 | #define AFI_INTR_FPCI_DECODE_ERROR 7 | 125 | #define AFI_INTR_FPCI_DECODE_ERROR 7 |
| 126 | #define AFI_INTR_AXI_DECODE_ERROR 8 | ||
| 127 | #define AFI_INTR_FPCI_TIMEOUT 9 | ||
| 128 | #define AFI_INTR_PE_PRSNT_SENSE 10 | ||
| 129 | #define AFI_INTR_PE_CLKREQ_SENSE 11 | ||
| 130 | #define AFI_INTR_CLKCLAMP_SENSE 12 | ||
| 131 | #define AFI_INTR_RDY4PD_SENSE 13 | ||
| 132 | #define AFI_INTR_P2P_ERROR 14 | ||
| 125 | 133 | ||
| 126 | #define AFI_INTR_SIGNATURE 0xbc | 134 | #define AFI_INTR_SIGNATURE 0xbc |
| 127 | #define AFI_UPPER_FPCI_ADDRESS 0xc0 | 135 | #define AFI_UPPER_FPCI_ADDRESS 0xc0 |
| @@ -152,8 +160,10 @@ | |||
| 152 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK (0xf << 20) | 160 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK (0xf << 20) |
| 153 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE (0x0 << 20) | 161 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE (0x0 << 20) |
| 154 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_420 (0x0 << 20) | 162 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_420 (0x0 << 20) |
| 163 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X2_X1 (0x0 << 20) | ||
| 155 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL (0x1 << 20) | 164 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL (0x1 << 20) |
| 156 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_222 (0x1 << 20) | 165 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_222 (0x1 << 20) |
| 166 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1 (0x1 << 20) | ||
| 157 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411 (0x2 << 20) | 167 | #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411 (0x2 << 20) |
| 158 | 168 | ||
| 159 | #define AFI_FUSE 0x104 | 169 | #define AFI_FUSE 0x104 |
| @@ -165,12 +175,21 @@ | |||
| 165 | #define AFI_PEX_CTRL_RST (1 << 0) | 175 | #define AFI_PEX_CTRL_RST (1 << 0) |
| 166 | #define AFI_PEX_CTRL_CLKREQ_EN (1 << 1) | 176 | #define AFI_PEX_CTRL_CLKREQ_EN (1 << 1) |
| 167 | #define AFI_PEX_CTRL_REFCLK_EN (1 << 3) | 177 | #define AFI_PEX_CTRL_REFCLK_EN (1 << 3) |
| 178 | #define AFI_PEX_CTRL_OVERRIDE_EN (1 << 4) | ||
| 179 | |||
| 180 | #define AFI_PLLE_CONTROL 0x160 | ||
| 181 | #define AFI_PLLE_CONTROL_BYPASS_PADS2PLLE_CONTROL (1 << 9) | ||
| 182 | #define AFI_PLLE_CONTROL_PADS2PLLE_CONTROL_EN (1 << 1) | ||
| 168 | 183 | ||
| 169 | #define AFI_PEXBIAS_CTRL_0 0x168 | 184 | #define AFI_PEXBIAS_CTRL_0 0x168 |
| 170 | 185 | ||
| 171 | #define RP_VEND_XP 0x00000F00 | 186 | #define RP_VEND_XP 0x00000F00 |
| 172 | #define RP_VEND_XP_DL_UP (1 << 30) | 187 | #define RP_VEND_XP_DL_UP (1 << 30) |
| 173 | 188 | ||
| 189 | #define RP_PRIV_MISC 0x00000FE0 | ||
| 190 | #define RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xE << 0) | ||
| 191 | #define RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xF << 0) | ||
| 192 | |||
| 174 | #define RP_LINK_CONTROL_STATUS 0x00000090 | 193 | #define RP_LINK_CONTROL_STATUS 0x00000090 |
| 175 | #define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000 | 194 | #define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000 |
| 176 | #define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000 | 195 | #define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000 |
| @@ -197,6 +216,7 @@ | |||
| 197 | 216 | ||
| 198 | #define PADS_REFCLK_CFG0 0x000000C8 | 217 | #define PADS_REFCLK_CFG0 0x000000C8 |
| 199 | #define PADS_REFCLK_CFG1 0x000000CC | 218 | #define PADS_REFCLK_CFG1 0x000000CC |
| 219 | #define PADS_REFCLK_BIAS 0x000000D0 | ||
| 200 | 220 | ||
| 201 | /* | 221 | /* |
| 202 | * Fields in PADS_REFCLK_CFG*. Those registers form an array of 16-bit | 222 | * Fields in PADS_REFCLK_CFG*. Those registers form an array of 16-bit |
| @@ -236,6 +256,7 @@ struct tegra_pcie_soc_data { | |||
| 236 | bool has_pex_bias_ctrl; | 256 | bool has_pex_bias_ctrl; |
| 237 | bool has_intr_prsnt_sense; | 257 | bool has_intr_prsnt_sense; |
| 238 | bool has_cml_clk; | 258 | bool has_cml_clk; |
| 259 | bool has_gen2; | ||
| 239 | }; | 260 | }; |
| 240 | 261 | ||
| 241 | static inline struct tegra_msi *to_tegra_msi(struct msi_chip *chip) | 262 | static inline struct tegra_msi *to_tegra_msi(struct msi_chip *chip) |
| @@ -253,6 +274,7 @@ struct tegra_pcie { | |||
| 253 | struct list_head buses; | 274 | struct list_head buses; |
| 254 | struct resource *cs; | 275 | struct resource *cs; |
| 255 | 276 | ||
| 277 | struct resource all; | ||
| 256 | struct resource io; | 278 | struct resource io; |
| 257 | struct resource mem; | 279 | struct resource mem; |
| 258 | struct resource prefetch; | 280 | struct resource prefetch; |
| @@ -267,6 +289,8 @@ struct tegra_pcie { | |||
| 267 | struct reset_control *afi_rst; | 289 | struct reset_control *afi_rst; |
| 268 | struct reset_control *pcie_xrst; | 290 | struct reset_control *pcie_xrst; |
| 269 | 291 | ||
| 292 | struct phy *phy; | ||
| 293 | |||
| 270 | struct tegra_msi msi; | 294 | struct tegra_msi msi; |
| 271 | 295 | ||
| 272 | struct list_head ports; | 296 | struct list_head ports; |
| @@ -382,7 +406,7 @@ static struct tegra_pcie_bus *tegra_pcie_bus_alloc(struct tegra_pcie *pcie, | |||
| 382 | for (i = 0; i < 16; i++) { | 406 | for (i = 0; i < 16; i++) { |
| 383 | unsigned long virt = (unsigned long)bus->area->addr + | 407 | unsigned long virt = (unsigned long)bus->area->addr + |
| 384 | i * SZ_64K; | 408 | i * SZ_64K; |
| 385 | phys_addr_t phys = cs + i * SZ_1M + busnr * SZ_64K; | 409 | phys_addr_t phys = cs + i * SZ_16M + busnr * SZ_64K; |
| 386 | 410 | ||
| 387 | err = ioremap_page_range(virt, virt + SZ_64K, phys, prot); | 411 | err = ioremap_page_range(virt, virt + SZ_64K, phys, prot); |
| 388 | if (err < 0) { | 412 | if (err < 0) { |
| @@ -561,6 +585,8 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port) | |||
| 561 | if (soc->has_pex_clkreq_en) | 585 | if (soc->has_pex_clkreq_en) |
| 562 | value |= AFI_PEX_CTRL_CLKREQ_EN; | 586 | value |= AFI_PEX_CTRL_CLKREQ_EN; |
| 563 | 587 | ||
| 588 | value |= AFI_PEX_CTRL_OVERRIDE_EN; | ||
| 589 | |||
| 564 | afi_writel(port->pcie, value, ctrl); | 590 | afi_writel(port->pcie, value, ctrl); |
| 565 | 591 | ||
| 566 | tegra_pcie_port_reset(port); | 592 | tegra_pcie_port_reset(port); |
| @@ -568,6 +594,7 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port) | |||
| 568 | 594 | ||
| 569 | static void tegra_pcie_port_disable(struct tegra_pcie_port *port) | 595 | static void tegra_pcie_port_disable(struct tegra_pcie_port *port) |
| 570 | { | 596 | { |
| 597 | const struct tegra_pcie_soc_data *soc = port->pcie->soc_data; | ||
| 571 | unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port); | 598 | unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port); |
| 572 | unsigned long value; | 599 | unsigned long value; |
| 573 | 600 | ||
| @@ -578,6 +605,10 @@ static void tegra_pcie_port_disable(struct tegra_pcie_port *port) | |||
| 578 | 605 | ||
| 579 | /* disable reference clock */ | 606 | /* disable reference clock */ |
| 580 | value = afi_readl(port->pcie, ctrl); | 607 | value = afi_readl(port->pcie, ctrl); |
| 608 | |||
| 609 | if (soc->has_pex_clkreq_en) | ||
| 610 | value &= ~AFI_PEX_CTRL_CLKREQ_EN; | ||
| 611 | |||
| 581 | value &= ~AFI_PEX_CTRL_REFCLK_EN; | 612 | value &= ~AFI_PEX_CTRL_REFCLK_EN; |
| 582 | afi_writel(port->pcie, value, ctrl); | 613 | afi_writel(port->pcie, value, ctrl); |
| 583 | } | 614 | } |
| @@ -626,13 +657,25 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable); | |||
| 626 | static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | 657 | static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) |
| 627 | { | 658 | { |
| 628 | struct tegra_pcie *pcie = sys_to_pcie(sys); | 659 | struct tegra_pcie *pcie = sys_to_pcie(sys); |
| 660 | int err; | ||
| 661 | phys_addr_t io_start; | ||
| 662 | |||
| 663 | err = devm_request_resource(pcie->dev, &pcie->all, &pcie->mem); | ||
| 664 | if (err < 0) | ||
| 665 | return err; | ||
| 666 | |||
| 667 | err = devm_request_resource(pcie->dev, &pcie->all, &pcie->prefetch); | ||
| 668 | if (err) | ||
| 669 | return err; | ||
| 670 | |||
| 671 | io_start = pci_pio_to_address(pcie->io.start); | ||
| 629 | 672 | ||
| 630 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); | 673 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); |
| 631 | pci_add_resource_offset(&sys->resources, &pcie->prefetch, | 674 | pci_add_resource_offset(&sys->resources, &pcie->prefetch, |
| 632 | sys->mem_offset); | 675 | sys->mem_offset); |
| 633 | pci_add_resource(&sys->resources, &pcie->busn); | 676 | pci_add_resource(&sys->resources, &pcie->busn); |
| 634 | 677 | ||
| 635 | pci_ioremap_io(nr * SZ_64K, pcie->io.start); | 678 | pci_ioremap_io(nr * SZ_64K, io_start); |
| 636 | 679 | ||
| 637 | return 1; | 680 | return 1; |
| 638 | } | 681 | } |
| @@ -684,9 +727,15 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg) | |||
| 684 | "Target abort", | 727 | "Target abort", |
| 685 | "Master abort", | 728 | "Master abort", |
| 686 | "Invalid write", | 729 | "Invalid write", |
| 730 | "Legacy interrupt", | ||
| 687 | "Response decoding error", | 731 | "Response decoding error", |
| 688 | "AXI response decoding error", | 732 | "AXI response decoding error", |
| 689 | "Transaction timeout", | 733 | "Transaction timeout", |
| 734 | "Slot present pin change", | ||
| 735 | "Slot clock request change", | ||
| 736 | "TMS clock ramp change", | ||
| 737 | "TMS ready for power down", | ||
| 738 | "Peer2Peer error", | ||
| 690 | }; | 739 | }; |
| 691 | struct tegra_pcie *pcie = arg; | 740 | struct tegra_pcie *pcie = arg; |
| 692 | u32 code, signature; | 741 | u32 code, signature; |
| @@ -737,6 +786,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg) | |||
| 737 | static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) | 786 | static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) |
| 738 | { | 787 | { |
| 739 | u32 fpci_bar, size, axi_address; | 788 | u32 fpci_bar, size, axi_address; |
| 789 | phys_addr_t io_start = pci_pio_to_address(pcie->io.start); | ||
| 740 | 790 | ||
| 741 | /* Bar 0: type 1 extended configuration space */ | 791 | /* Bar 0: type 1 extended configuration space */ |
| 742 | fpci_bar = 0xfe100000; | 792 | fpci_bar = 0xfe100000; |
| @@ -749,7 +799,7 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) | |||
| 749 | /* Bar 1: downstream IO bar */ | 799 | /* Bar 1: downstream IO bar */ |
| 750 | fpci_bar = 0xfdfc0000; | 800 | fpci_bar = 0xfdfc0000; |
| 751 | size = resource_size(&pcie->io); | 801 | size = resource_size(&pcie->io); |
| 752 | axi_address = pcie->io.start; | 802 | axi_address = io_start; |
| 753 | afi_writel(pcie, axi_address, AFI_AXI_BAR1_START); | 803 | afi_writel(pcie, axi_address, AFI_AXI_BAR1_START); |
| 754 | afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ); | 804 | afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ); |
| 755 | afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1); | 805 | afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1); |
| @@ -792,30 +842,27 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) | |||
| 792 | afi_writel(pcie, 0, AFI_MSI_BAR_SZ); | 842 | afi_writel(pcie, 0, AFI_MSI_BAR_SZ); |
| 793 | } | 843 | } |
| 794 | 844 | ||
| 795 | static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) | 845 | static int tegra_pcie_pll_wait(struct tegra_pcie *pcie, unsigned long timeout) |
| 796 | { | 846 | { |
| 797 | const struct tegra_pcie_soc_data *soc = pcie->soc_data; | 847 | const struct tegra_pcie_soc_data *soc = pcie->soc_data; |
| 798 | struct tegra_pcie_port *port; | 848 | u32 value; |
| 799 | unsigned int timeout; | ||
| 800 | unsigned long value; | ||
| 801 | 849 | ||
| 802 | /* power down PCIe slot clock bias pad */ | 850 | timeout = jiffies + msecs_to_jiffies(timeout); |
| 803 | if (soc->has_pex_bias_ctrl) | ||
| 804 | afi_writel(pcie, 0, AFI_PEXBIAS_CTRL_0); | ||
| 805 | 851 | ||
| 806 | /* configure mode and disable all ports */ | 852 | while (time_before(jiffies, timeout)) { |
| 807 | value = afi_readl(pcie, AFI_PCIE_CONFIG); | 853 | value = pads_readl(pcie, soc->pads_pll_ctl); |
| 808 | value &= ~AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK; | 854 | if (value & PADS_PLL_CTL_LOCKDET) |
| 809 | value |= AFI_PCIE_CONFIG_PCIE_DISABLE_ALL | pcie->xbar_config; | 855 | return 0; |
| 810 | 856 | } | |
| 811 | list_for_each_entry(port, &pcie->ports, list) | ||
| 812 | value &= ~AFI_PCIE_CONFIG_PCIE_DISABLE(port->index); | ||
| 813 | 857 | ||
| 814 | afi_writel(pcie, value, AFI_PCIE_CONFIG); | 858 | return -ETIMEDOUT; |
| 859 | } | ||
| 815 | 860 | ||
| 816 | value = afi_readl(pcie, AFI_FUSE); | 861 | static int tegra_pcie_phy_enable(struct tegra_pcie *pcie) |
| 817 | value |= AFI_FUSE_PCIE_T0_GEN2_DIS; | 862 | { |
| 818 | afi_writel(pcie, value, AFI_FUSE); | 863 | const struct tegra_pcie_soc_data *soc = pcie->soc_data; |
| 864 | u32 value; | ||
| 865 | int err; | ||
| 819 | 866 | ||
| 820 | /* initialize internal PHY, enable up to 16 PCIE lanes */ | 867 | /* initialize internal PHY, enable up to 16 PCIE lanes */ |
| 821 | pads_writel(pcie, 0x0, PADS_CTL_SEL); | 868 | pads_writel(pcie, 0x0, PADS_CTL_SEL); |
| @@ -834,6 +881,13 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) | |||
| 834 | value |= PADS_PLL_CTL_REFCLK_INTERNAL_CML | soc->tx_ref_sel; | 881 | value |= PADS_PLL_CTL_REFCLK_INTERNAL_CML | soc->tx_ref_sel; |
| 835 | pads_writel(pcie, value, soc->pads_pll_ctl); | 882 | pads_writel(pcie, value, soc->pads_pll_ctl); |
| 836 | 883 | ||
| 884 | /* reset PLL */ | ||
| 885 | value = pads_readl(pcie, soc->pads_pll_ctl); | ||
| 886 | value &= ~PADS_PLL_CTL_RST_B4SM; | ||
| 887 | pads_writel(pcie, value, soc->pads_pll_ctl); | ||
| 888 | |||
| 889 | usleep_range(20, 100); | ||
| 890 | |||
| 837 | /* take PLL out of reset */ | 891 | /* take PLL out of reset */ |
| 838 | value = pads_readl(pcie, soc->pads_pll_ctl); | 892 | value = pads_readl(pcie, soc->pads_pll_ctl); |
| 839 | value |= PADS_PLL_CTL_RST_B4SM; | 893 | value |= PADS_PLL_CTL_RST_B4SM; |
| @@ -846,15 +900,11 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) | |||
| 846 | pads_writel(pcie, PADS_REFCLK_CFG_VALUE, PADS_REFCLK_CFG1); | 900 | pads_writel(pcie, PADS_REFCLK_CFG_VALUE, PADS_REFCLK_CFG1); |
| 847 | 901 | ||
| 848 | /* wait for the PLL to lock */ | 902 | /* wait for the PLL to lock */ |
| 849 | timeout = 300; | 903 | err = tegra_pcie_pll_wait(pcie, 500); |
| 850 | do { | 904 | if (err < 0) { |
| 851 | value = pads_readl(pcie, soc->pads_pll_ctl); | 905 | dev_err(pcie->dev, "PLL failed to lock: %d\n", err); |
| 852 | usleep_range(1000, 2000); | 906 | return err; |
| 853 | if (--timeout == 0) { | 907 | } |
| 854 | pr_err("Tegra PCIe error: timeout waiting for PLL\n"); | ||
| 855 | return -EBUSY; | ||
| 856 | } | ||
| 857 | } while (!(value & PADS_PLL_CTL_LOCKDET)); | ||
| 858 | 908 | ||
| 859 | /* turn off IDDQ override */ | 909 | /* turn off IDDQ override */ |
| 860 | value = pads_readl(pcie, PADS_CTL); | 910 | value = pads_readl(pcie, PADS_CTL); |
| @@ -866,6 +916,58 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) | |||
| 866 | value |= PADS_CTL_TX_DATA_EN_1L | PADS_CTL_RX_DATA_EN_1L; | 916 | value |= PADS_CTL_TX_DATA_EN_1L | PADS_CTL_RX_DATA_EN_1L; |
| 867 | pads_writel(pcie, value, PADS_CTL); | 917 | pads_writel(pcie, value, PADS_CTL); |
| 868 | 918 | ||
| 919 | return 0; | ||
| 920 | } | ||
| 921 | |||
| 922 | static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) | ||
| 923 | { | ||
| 924 | const struct tegra_pcie_soc_data *soc = pcie->soc_data; | ||
| 925 | struct tegra_pcie_port *port; | ||
| 926 | unsigned long value; | ||
| 927 | int err; | ||
| 928 | |||
| 929 | /* enable PLL power down */ | ||
| 930 | if (pcie->phy) { | ||
| 931 | value = afi_readl(pcie, AFI_PLLE_CONTROL); | ||
| 932 | value &= ~AFI_PLLE_CONTROL_BYPASS_PADS2PLLE_CONTROL; | ||
| 933 | value |= AFI_PLLE_CONTROL_PADS2PLLE_CONTROL_EN; | ||
| 934 | afi_writel(pcie, value, AFI_PLLE_CONTROL); | ||
| 935 | } | ||
| 936 | |||
| 937 | /* power down PCIe slot clock bias pad */ | ||
| 938 | if (soc->has_pex_bias_ctrl) | ||
| 939 | afi_writel(pcie, 0, AFI_PEXBIAS_CTRL_0); | ||
| 940 | |||
| 941 | /* configure mode and disable all ports */ | ||
| 942 | value = afi_readl(pcie, AFI_PCIE_CONFIG); | ||
| 943 | value &= ~AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK; | ||
| 944 | value |= AFI_PCIE_CONFIG_PCIE_DISABLE_ALL | pcie->xbar_config; | ||
| 945 | |||
| 946 | list_for_each_entry(port, &pcie->ports, list) | ||
| 947 | value &= ~AFI_PCIE_CONFIG_PCIE_DISABLE(port->index); | ||
| 948 | |||
| 949 | afi_writel(pcie, value, AFI_PCIE_CONFIG); | ||
| 950 | |||
| 951 | if (soc->has_gen2) { | ||
| 952 | value = afi_readl(pcie, AFI_FUSE); | ||
| 953 | value &= ~AFI_FUSE_PCIE_T0_GEN2_DIS; | ||
| 954 | afi_writel(pcie, value, AFI_FUSE); | ||
| 955 | } else { | ||
| 956 | value = afi_readl(pcie, AFI_FUSE); | ||
| 957 | value |= AFI_FUSE_PCIE_T0_GEN2_DIS; | ||
| 958 | afi_writel(pcie, value, AFI_FUSE); | ||
| 959 | } | ||
| 960 | |||
| 961 | if (!pcie->phy) | ||
| 962 | err = tegra_pcie_phy_enable(pcie); | ||
| 963 | else | ||
| 964 | err = phy_power_on(pcie->phy); | ||
| 965 | |||
| 966 | if (err < 0) { | ||
| 967 | dev_err(pcie->dev, "failed to power on PHY: %d\n", err); | ||
| 968 | return err; | ||
| 969 | } | ||
| 970 | |||
| 869 | /* take the PCIe interface module out of reset */ | 971 | /* take the PCIe interface module out of reset */ |
| 870 | reset_control_deassert(pcie->pcie_xrst); | 972 | reset_control_deassert(pcie->pcie_xrst); |
| 871 | 973 | ||
| @@ -899,6 +1001,10 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie) | |||
| 899 | 1001 | ||
| 900 | /* TODO: disable and unprepare clocks? */ | 1002 | /* TODO: disable and unprepare clocks? */ |
| 901 | 1003 | ||
| 1004 | err = phy_power_off(pcie->phy); | ||
| 1005 | if (err < 0) | ||
| 1006 | dev_warn(pcie->dev, "failed to power off PHY: %d\n", err); | ||
| 1007 | |||
| 902 | reset_control_assert(pcie->pcie_xrst); | 1008 | reset_control_assert(pcie->pcie_xrst); |
| 903 | reset_control_assert(pcie->afi_rst); | 1009 | reset_control_assert(pcie->afi_rst); |
| 904 | reset_control_assert(pcie->pex_rst); | 1010 | reset_control_assert(pcie->pex_rst); |
| @@ -1020,6 +1126,19 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie) | |||
| 1020 | return err; | 1126 | return err; |
| 1021 | } | 1127 | } |
| 1022 | 1128 | ||
| 1129 | pcie->phy = devm_phy_optional_get(pcie->dev, "pcie"); | ||
| 1130 | if (IS_ERR(pcie->phy)) { | ||
| 1131 | err = PTR_ERR(pcie->phy); | ||
| 1132 | dev_err(&pdev->dev, "failed to get PHY: %d\n", err); | ||
| 1133 | return err; | ||
| 1134 | } | ||
| 1135 | |||
| 1136 | err = phy_init(pcie->phy); | ||
| 1137 | if (err < 0) { | ||
| 1138 | dev_err(&pdev->dev, "failed to initialize PHY: %d\n", err); | ||
| 1139 | return err; | ||
| 1140 | } | ||
| 1141 | |||
| 1023 | err = tegra_pcie_power_on(pcie); | 1142 | err = tegra_pcie_power_on(pcie); |
| 1024 | if (err) { | 1143 | if (err) { |
| 1025 | dev_err(&pdev->dev, "failed to power up: %d\n", err); | 1144 | dev_err(&pdev->dev, "failed to power up: %d\n", err); |
| @@ -1078,10 +1197,17 @@ poweroff: | |||
| 1078 | 1197 | ||
| 1079 | static int tegra_pcie_put_resources(struct tegra_pcie *pcie) | 1198 | static int tegra_pcie_put_resources(struct tegra_pcie *pcie) |
| 1080 | { | 1199 | { |
| 1200 | int err; | ||
| 1201 | |||
| 1081 | if (pcie->irq > 0) | 1202 | if (pcie->irq > 0) |
| 1082 | free_irq(pcie->irq, pcie); | 1203 | free_irq(pcie->irq, pcie); |
| 1083 | 1204 | ||
| 1084 | tegra_pcie_power_off(pcie); | 1205 | tegra_pcie_power_off(pcie); |
| 1206 | |||
| 1207 | err = phy_exit(pcie->phy); | ||
| 1208 | if (err < 0) | ||
| 1209 | dev_err(pcie->dev, "failed to teardown PHY: %d\n", err); | ||
| 1210 | |||
| 1085 | return 0; | 1211 | return 0; |
| 1086 | } | 1212 | } |
| 1087 | 1213 | ||
| @@ -1170,8 +1296,10 @@ static int tegra_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev, | |||
| 1170 | return hwirq; | 1296 | return hwirq; |
| 1171 | 1297 | ||
| 1172 | irq = irq_create_mapping(msi->domain, hwirq); | 1298 | irq = irq_create_mapping(msi->domain, hwirq); |
| 1173 | if (!irq) | 1299 | if (!irq) { |
| 1300 | tegra_msi_free(msi, hwirq); | ||
| 1174 | return -EINVAL; | 1301 | return -EINVAL; |
| 1302 | } | ||
| 1175 | 1303 | ||
| 1176 | irq_set_msi_desc(irq, desc); | 1304 | irq_set_msi_desc(irq, desc); |
| 1177 | 1305 | ||
| @@ -1189,8 +1317,10 @@ static void tegra_msi_teardown_irq(struct msi_chip *chip, unsigned int irq) | |||
| 1189 | { | 1317 | { |
| 1190 | struct tegra_msi *msi = to_tegra_msi(chip); | 1318 | struct tegra_msi *msi = to_tegra_msi(chip); |
| 1191 | struct irq_data *d = irq_get_irq_data(irq); | 1319 | struct irq_data *d = irq_get_irq_data(irq); |
| 1320 | irq_hw_number_t hwirq = irqd_to_hwirq(d); | ||
| 1192 | 1321 | ||
| 1193 | tegra_msi_free(msi, d->hwirq); | 1322 | irq_dispose_mapping(irq); |
| 1323 | tegra_msi_free(msi, hwirq); | ||
| 1194 | } | 1324 | } |
| 1195 | 1325 | ||
| 1196 | static struct irq_chip tegra_msi_irq_chip = { | 1326 | static struct irq_chip tegra_msi_irq_chip = { |
| @@ -1327,7 +1457,19 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes, | |||
| 1327 | { | 1457 | { |
| 1328 | struct device_node *np = pcie->dev->of_node; | 1458 | struct device_node *np = pcie->dev->of_node; |
| 1329 | 1459 | ||
| 1330 | if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) { | 1460 | if (of_device_is_compatible(np, "nvidia,tegra124-pcie")) { |
| 1461 | switch (lanes) { | ||
| 1462 | case 0x0000104: | ||
| 1463 | dev_info(pcie->dev, "4x1, 1x1 configuration\n"); | ||
| 1464 | *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1; | ||
| 1465 | return 0; | ||
| 1466 | |||
| 1467 | case 0x0000102: | ||
| 1468 | dev_info(pcie->dev, "2x1, 1x1 configuration\n"); | ||
| 1469 | *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X2_X1; | ||
| 1470 | return 0; | ||
| 1471 | } | ||
| 1472 | } else if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) { | ||
| 1331 | switch (lanes) { | 1473 | switch (lanes) { |
| 1332 | case 0x00000204: | 1474 | case 0x00000204: |
| 1333 | dev_info(pcie->dev, "4x1, 2x1 configuration\n"); | 1475 | dev_info(pcie->dev, "4x1, 2x1 configuration\n"); |
| @@ -1435,7 +1577,23 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask) | |||
| 1435 | struct device_node *np = pcie->dev->of_node; | 1577 | struct device_node *np = pcie->dev->of_node; |
| 1436 | unsigned int i = 0; | 1578 | unsigned int i = 0; |
| 1437 | 1579 | ||
| 1438 | if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) { | 1580 | if (of_device_is_compatible(np, "nvidia,tegra124-pcie")) { |
| 1581 | pcie->num_supplies = 7; | ||
| 1582 | |||
| 1583 | pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies, | ||
| 1584 | sizeof(*pcie->supplies), | ||
| 1585 | GFP_KERNEL); | ||
| 1586 | if (!pcie->supplies) | ||
| 1587 | return -ENOMEM; | ||
| 1588 | |||
| 1589 | pcie->supplies[i++].supply = "avddio-pex"; | ||
| 1590 | pcie->supplies[i++].supply = "dvddio-pex"; | ||
| 1591 | pcie->supplies[i++].supply = "avdd-pex-pll"; | ||
| 1592 | pcie->supplies[i++].supply = "hvdd-pex"; | ||
| 1593 | pcie->supplies[i++].supply = "hvdd-pex-pll-e"; | ||
| 1594 | pcie->supplies[i++].supply = "vddio-pex-ctl"; | ||
| 1595 | pcie->supplies[i++].supply = "avdd-pll-erefe"; | ||
| 1596 | } else if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) { | ||
| 1439 | bool need_pexa = false, need_pexb = false; | 1597 | bool need_pexa = false, need_pexb = false; |
| 1440 | 1598 | ||
| 1441 | /* VDD_PEXA and AVDD_PEXA supply lanes 0 to 3 */ | 1599 | /* VDD_PEXA and AVDD_PEXA supply lanes 0 to 3 */ |
| @@ -1514,32 +1672,50 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) | |||
| 1514 | struct resource res; | 1672 | struct resource res; |
| 1515 | int err; | 1673 | int err; |
| 1516 | 1674 | ||
| 1675 | memset(&pcie->all, 0, sizeof(pcie->all)); | ||
| 1676 | pcie->all.flags = IORESOURCE_MEM; | ||
| 1677 | pcie->all.name = np->full_name; | ||
| 1678 | pcie->all.start = ~0; | ||
| 1679 | pcie->all.end = 0; | ||
| 1680 | |||
| 1517 | if (of_pci_range_parser_init(&parser, np)) { | 1681 | if (of_pci_range_parser_init(&parser, np)) { |
| 1518 | dev_err(pcie->dev, "missing \"ranges\" property\n"); | 1682 | dev_err(pcie->dev, "missing \"ranges\" property\n"); |
| 1519 | return -EINVAL; | 1683 | return -EINVAL; |
| 1520 | } | 1684 | } |
| 1521 | 1685 | ||
| 1522 | for_each_of_pci_range(&parser, &range) { | 1686 | for_each_of_pci_range(&parser, &range) { |
| 1523 | of_pci_range_to_resource(&range, np, &res); | 1687 | err = of_pci_range_to_resource(&range, np, &res); |
| 1688 | if (err < 0) | ||
| 1689 | return err; | ||
| 1524 | 1690 | ||
| 1525 | switch (res.flags & IORESOURCE_TYPE_BITS) { | 1691 | switch (res.flags & IORESOURCE_TYPE_BITS) { |
| 1526 | case IORESOURCE_IO: | 1692 | case IORESOURCE_IO: |
| 1527 | memcpy(&pcie->io, &res, sizeof(res)); | 1693 | memcpy(&pcie->io, &res, sizeof(res)); |
| 1528 | pcie->io.name = "I/O"; | 1694 | pcie->io.name = np->full_name; |
| 1529 | break; | 1695 | break; |
| 1530 | 1696 | ||
| 1531 | case IORESOURCE_MEM: | 1697 | case IORESOURCE_MEM: |
| 1532 | if (res.flags & IORESOURCE_PREFETCH) { | 1698 | if (res.flags & IORESOURCE_PREFETCH) { |
| 1533 | memcpy(&pcie->prefetch, &res, sizeof(res)); | 1699 | memcpy(&pcie->prefetch, &res, sizeof(res)); |
| 1534 | pcie->prefetch.name = "PREFETCH"; | 1700 | pcie->prefetch.name = "prefetchable"; |
| 1535 | } else { | 1701 | } else { |
| 1536 | memcpy(&pcie->mem, &res, sizeof(res)); | 1702 | memcpy(&pcie->mem, &res, sizeof(res)); |
| 1537 | pcie->mem.name = "MEM"; | 1703 | pcie->mem.name = "non-prefetchable"; |
| 1538 | } | 1704 | } |
| 1539 | break; | 1705 | break; |
| 1540 | } | 1706 | } |
| 1707 | |||
| 1708 | if (res.start <= pcie->all.start) | ||
| 1709 | pcie->all.start = res.start; | ||
| 1710 | |||
| 1711 | if (res.end >= pcie->all.end) | ||
| 1712 | pcie->all.end = res.end; | ||
| 1541 | } | 1713 | } |
| 1542 | 1714 | ||
| 1715 | err = devm_request_resource(pcie->dev, &iomem_resource, &pcie->all); | ||
| 1716 | if (err < 0) | ||
| 1717 | return err; | ||
| 1718 | |||
| 1543 | err = of_pci_parse_bus_range(np, &pcie->busn); | 1719 | err = of_pci_parse_bus_range(np, &pcie->busn); |
| 1544 | if (err < 0) { | 1720 | if (err < 0) { |
| 1545 | dev_err(pcie->dev, "failed to parse ranges property: %d\n", | 1721 | dev_err(pcie->dev, "failed to parse ranges property: %d\n", |
| @@ -1641,6 +1817,12 @@ static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port) | |||
| 1641 | unsigned int retries = 3; | 1817 | unsigned int retries = 3; |
| 1642 | unsigned long value; | 1818 | unsigned long value; |
| 1643 | 1819 | ||
| 1820 | /* override presence detection */ | ||
| 1821 | value = readl(port->base + RP_PRIV_MISC); | ||
| 1822 | value &= ~RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT; | ||
| 1823 | value |= RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT; | ||
| 1824 | writel(value, port->base + RP_PRIV_MISC); | ||
| 1825 | |||
| 1644 | do { | 1826 | do { |
| 1645 | unsigned int timeout = TEGRA_PCIE_LINKUP_TIMEOUT; | 1827 | unsigned int timeout = TEGRA_PCIE_LINKUP_TIMEOUT; |
| 1646 | 1828 | ||
| @@ -1721,6 +1903,7 @@ static const struct tegra_pcie_soc_data tegra20_pcie_data = { | |||
| 1721 | .has_pex_bias_ctrl = false, | 1903 | .has_pex_bias_ctrl = false, |
| 1722 | .has_intr_prsnt_sense = false, | 1904 | .has_intr_prsnt_sense = false, |
| 1723 | .has_cml_clk = false, | 1905 | .has_cml_clk = false, |
| 1906 | .has_gen2 = false, | ||
| 1724 | }; | 1907 | }; |
| 1725 | 1908 | ||
| 1726 | static const struct tegra_pcie_soc_data tegra30_pcie_data = { | 1909 | static const struct tegra_pcie_soc_data tegra30_pcie_data = { |
| @@ -1732,9 +1915,23 @@ static const struct tegra_pcie_soc_data tegra30_pcie_data = { | |||
| 1732 | .has_pex_bias_ctrl = true, | 1915 | .has_pex_bias_ctrl = true, |
| 1733 | .has_intr_prsnt_sense = true, | 1916 | .has_intr_prsnt_sense = true, |
| 1734 | .has_cml_clk = true, | 1917 | .has_cml_clk = true, |
| 1918 | .has_gen2 = false, | ||
| 1919 | }; | ||
| 1920 | |||
| 1921 | static const struct tegra_pcie_soc_data tegra124_pcie_data = { | ||
| 1922 | .num_ports = 2, | ||
| 1923 | .msi_base_shift = 8, | ||
| 1924 | .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, | ||
| 1925 | .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, | ||
| 1926 | .has_pex_clkreq_en = true, | ||
| 1927 | .has_pex_bias_ctrl = true, | ||
| 1928 | .has_intr_prsnt_sense = true, | ||
| 1929 | .has_cml_clk = true, | ||
| 1930 | .has_gen2 = true, | ||
| 1735 | }; | 1931 | }; |
| 1736 | 1932 | ||
| 1737 | static const struct of_device_id tegra_pcie_of_match[] = { | 1933 | static const struct of_device_id tegra_pcie_of_match[] = { |
| 1934 | { .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie_data }, | ||
| 1738 | { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie_data }, | 1935 | { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie_data }, |
| 1739 | { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie_data }, | 1936 | { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie_data }, |
| 1740 | { }, | 1937 | { }, |
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c new file mode 100644 index 000000000000..9ecabfa8c634 --- /dev/null +++ b/drivers/pci/host/pci-xgene.c | |||
| @@ -0,0 +1,659 @@ | |||
| 1 | /** | ||
| 2 | * APM X-Gene PCIe Driver | ||
| 3 | * | ||
| 4 | * Copyright (c) 2014 Applied Micro Circuits Corporation. | ||
| 5 | * | ||
| 6 | * Author: Tanmay Inamdar <tinamdar@apm.com>. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | */ | ||
| 19 | #include <linux/clk-private.h> | ||
| 20 | #include <linux/delay.h> | ||
| 21 | #include <linux/io.h> | ||
| 22 | #include <linux/jiffies.h> | ||
| 23 | #include <linux/memblock.h> | ||
| 24 | #include <linux/module.h> | ||
| 25 | #include <linux/of.h> | ||
| 26 | #include <linux/of_address.h> | ||
| 27 | #include <linux/of_irq.h> | ||
| 28 | #include <linux/of_pci.h> | ||
| 29 | #include <linux/pci.h> | ||
| 30 | #include <linux/platform_device.h> | ||
| 31 | #include <linux/slab.h> | ||
| 32 | |||
| 33 | #define PCIECORE_CTLANDSTATUS 0x50 | ||
| 34 | #define PIM1_1L 0x80 | ||
| 35 | #define IBAR2 0x98 | ||
| 36 | #define IR2MSK 0x9c | ||
| 37 | #define PIM2_1L 0xa0 | ||
| 38 | #define IBAR3L 0xb4 | ||
| 39 | #define IR3MSKL 0xbc | ||
| 40 | #define PIM3_1L 0xc4 | ||
| 41 | #define OMR1BARL 0x100 | ||
| 42 | #define OMR2BARL 0x118 | ||
| 43 | #define OMR3BARL 0x130 | ||
| 44 | #define CFGBARL 0x154 | ||
| 45 | #define CFGBARH 0x158 | ||
| 46 | #define CFGCTL 0x15c | ||
| 47 | #define RTDID 0x160 | ||
| 48 | #define BRIDGE_CFG_0 0x2000 | ||
| 49 | #define BRIDGE_CFG_4 0x2010 | ||
| 50 | #define BRIDGE_STATUS_0 0x2600 | ||
| 51 | |||
| 52 | #define LINK_UP_MASK 0x00000100 | ||
| 53 | #define AXI_EP_CFG_ACCESS 0x10000 | ||
| 54 | #define EN_COHERENCY 0xF0000000 | ||
| 55 | #define EN_REG 0x00000001 | ||
| 56 | #define OB_LO_IO 0x00000002 | ||
| 57 | #define XGENE_PCIE_VENDORID 0x10E8 | ||
| 58 | #define XGENE_PCIE_DEVICEID 0xE004 | ||
| 59 | #define SZ_1T (SZ_1G*1024ULL) | ||
| 60 | #define PIPE_PHY_RATE_RD(src) ((0xc000 & (u32)(src)) >> 0xe) | ||
| 61 | |||
| 62 | struct xgene_pcie_port { | ||
| 63 | struct device_node *node; | ||
| 64 | struct device *dev; | ||
| 65 | struct clk *clk; | ||
| 66 | void __iomem *csr_base; | ||
| 67 | void __iomem *cfg_base; | ||
| 68 | unsigned long cfg_addr; | ||
| 69 | bool link_up; | ||
| 70 | }; | ||
| 71 | |||
| 72 | static inline u32 pcie_bar_low_val(u32 addr, u32 flags) | ||
| 73 | { | ||
| 74 | return (addr & PCI_BASE_ADDRESS_MEM_MASK) | flags; | ||
| 75 | } | ||
| 76 | |||
| 77 | /* PCIe Configuration Out/In */ | ||
| 78 | static inline void xgene_pcie_cfg_out32(void __iomem *addr, int offset, u32 val) | ||
| 79 | { | ||
| 80 | writel(val, addr + offset); | ||
| 81 | } | ||
| 82 | |||
| 83 | static inline void xgene_pcie_cfg_out16(void __iomem *addr, int offset, u16 val) | ||
| 84 | { | ||
| 85 | u32 val32 = readl(addr + (offset & ~0x3)); | ||
| 86 | |||
| 87 | switch (offset & 0x3) { | ||
| 88 | case 2: | ||
| 89 | val32 &= ~0xFFFF0000; | ||
| 90 | val32 |= (u32)val << 16; | ||
| 91 | break; | ||
| 92 | case 0: | ||
| 93 | default: | ||
| 94 | val32 &= ~0xFFFF; | ||
| 95 | val32 |= val; | ||
| 96 | break; | ||
| 97 | } | ||
| 98 | writel(val32, addr + (offset & ~0x3)); | ||
| 99 | } | ||
| 100 | |||
| 101 | static inline void xgene_pcie_cfg_out8(void __iomem *addr, int offset, u8 val) | ||
| 102 | { | ||
| 103 | u32 val32 = readl(addr + (offset & ~0x3)); | ||
| 104 | |||
| 105 | switch (offset & 0x3) { | ||
| 106 | case 0: | ||
| 107 | val32 &= ~0xFF; | ||
| 108 | val32 |= val; | ||
| 109 | break; | ||
| 110 | case 1: | ||
| 111 | val32 &= ~0xFF00; | ||
| 112 | val32 |= (u32)val << 8; | ||
| 113 | break; | ||
| 114 | case 2: | ||
| 115 | val32 &= ~0xFF0000; | ||
| 116 | val32 |= (u32)val << 16; | ||
| 117 | break; | ||
| 118 | case 3: | ||
| 119 | default: | ||
| 120 | val32 &= ~0xFF000000; | ||
| 121 | val32 |= (u32)val << 24; | ||
| 122 | break; | ||
| 123 | } | ||
| 124 | writel(val32, addr + (offset & ~0x3)); | ||
| 125 | } | ||
| 126 | |||
| 127 | static inline void xgene_pcie_cfg_in32(void __iomem *addr, int offset, u32 *val) | ||
| 128 | { | ||
| 129 | *val = readl(addr + offset); | ||
| 130 | } | ||
| 131 | |||
| 132 | static inline void xgene_pcie_cfg_in16(void __iomem *addr, int offset, u32 *val) | ||
| 133 | { | ||
| 134 | *val = readl(addr + (offset & ~0x3)); | ||
| 135 | |||
| 136 | switch (offset & 0x3) { | ||
| 137 | case 2: | ||
| 138 | *val >>= 16; | ||
| 139 | break; | ||
| 140 | } | ||
| 141 | |||
| 142 | *val &= 0xFFFF; | ||
| 143 | } | ||
| 144 | |||
| 145 | static inline void xgene_pcie_cfg_in8(void __iomem *addr, int offset, u32 *val) | ||
| 146 | { | ||
| 147 | *val = readl(addr + (offset & ~0x3)); | ||
| 148 | |||
| 149 | switch (offset & 0x3) { | ||
| 150 | case 3: | ||
| 151 | *val = *val >> 24; | ||
| 152 | break; | ||
| 153 | case 2: | ||
| 154 | *val = *val >> 16; | ||
| 155 | break; | ||
| 156 | case 1: | ||
| 157 | *val = *val >> 8; | ||
| 158 | break; | ||
| 159 | } | ||
| 160 | *val &= 0xFF; | ||
| 161 | } | ||
| 162 | |||
| 163 | /* | ||
| 164 | * When the address bit [17:16] is 2'b01, the Configuration access will be | ||
| 165 | * treated as Type 1 and it will be forwarded to external PCIe device. | ||
| 166 | */ | ||
| 167 | static void __iomem *xgene_pcie_get_cfg_base(struct pci_bus *bus) | ||
| 168 | { | ||
| 169 | struct xgene_pcie_port *port = bus->sysdata; | ||
| 170 | |||
| 171 | if (bus->number >= (bus->primary + 1)) | ||
| 172 | return port->cfg_base + AXI_EP_CFG_ACCESS; | ||
| 173 | |||
| 174 | return port->cfg_base; | ||
| 175 | } | ||
| 176 | |||
| 177 | /* | ||
| 178 | * For Configuration request, RTDID register is used as Bus Number, | ||
| 179 | * Device Number and Function number of the header fields. | ||
| 180 | */ | ||
| 181 | static void xgene_pcie_set_rtdid_reg(struct pci_bus *bus, uint devfn) | ||
| 182 | { | ||
| 183 | struct xgene_pcie_port *port = bus->sysdata; | ||
| 184 | unsigned int b, d, f; | ||
| 185 | u32 rtdid_val = 0; | ||
| 186 | |||
| 187 | b = bus->number; | ||
| 188 | d = PCI_SLOT(devfn); | ||
| 189 | f = PCI_FUNC(devfn); | ||
| 190 | |||
| 191 | if (!pci_is_root_bus(bus)) | ||
| 192 | rtdid_val = (b << 8) | (d << 3) | f; | ||
| 193 | |||
| 194 | writel(rtdid_val, port->csr_base + RTDID); | ||
| 195 | /* read the register back to ensure flush */ | ||
| 196 | readl(port->csr_base + RTDID); | ||
| 197 | } | ||
| 198 | |||
| 199 | /* | ||
| 200 | * X-Gene PCIe port uses BAR0-BAR1 of RC's configuration space as | ||
| 201 | * the translation from PCI bus to native BUS. Entire DDR region | ||
| 202 | * is mapped into PCIe space using these registers, so it can be | ||
| 203 | * reached by DMA from EP devices. The BAR0/1 of bridge should be | ||
| 204 | * hidden during enumeration to avoid the sizing and resource allocation | ||
| 205 | * by PCIe core. | ||
| 206 | */ | ||
| 207 | static bool xgene_pcie_hide_rc_bars(struct pci_bus *bus, int offset) | ||
| 208 | { | ||
| 209 | if (pci_is_root_bus(bus) && ((offset == PCI_BASE_ADDRESS_0) || | ||
| 210 | (offset == PCI_BASE_ADDRESS_1))) | ||
| 211 | return true; | ||
| 212 | |||
| 213 | return false; | ||
| 214 | } | ||
| 215 | |||
| 216 | static int xgene_pcie_read_config(struct pci_bus *bus, unsigned int devfn, | ||
| 217 | int offset, int len, u32 *val) | ||
| 218 | { | ||
| 219 | struct xgene_pcie_port *port = bus->sysdata; | ||
| 220 | void __iomem *addr; | ||
| 221 | |||
| 222 | if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up) | ||
| 223 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 224 | |||
| 225 | if (xgene_pcie_hide_rc_bars(bus, offset)) { | ||
| 226 | *val = 0; | ||
| 227 | return PCIBIOS_SUCCESSFUL; | ||
| 228 | } | ||
| 229 | |||
| 230 | xgene_pcie_set_rtdid_reg(bus, devfn); | ||
| 231 | addr = xgene_pcie_get_cfg_base(bus); | ||
| 232 | switch (len) { | ||
| 233 | case 1: | ||
| 234 | xgene_pcie_cfg_in8(addr, offset, val); | ||
| 235 | break; | ||
| 236 | case 2: | ||
| 237 | xgene_pcie_cfg_in16(addr, offset, val); | ||
| 238 | break; | ||
| 239 | default: | ||
| 240 | xgene_pcie_cfg_in32(addr, offset, val); | ||
| 241 | break; | ||
| 242 | } | ||
| 243 | |||
| 244 | return PCIBIOS_SUCCESSFUL; | ||
| 245 | } | ||
| 246 | |||
| 247 | static int xgene_pcie_write_config(struct pci_bus *bus, unsigned int devfn, | ||
| 248 | int offset, int len, u32 val) | ||
| 249 | { | ||
| 250 | struct xgene_pcie_port *port = bus->sysdata; | ||
| 251 | void __iomem *addr; | ||
| 252 | |||
| 253 | if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up) | ||
| 254 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 255 | |||
| 256 | if (xgene_pcie_hide_rc_bars(bus, offset)) | ||
| 257 | return PCIBIOS_SUCCESSFUL; | ||
| 258 | |||
| 259 | xgene_pcie_set_rtdid_reg(bus, devfn); | ||
| 260 | addr = xgene_pcie_get_cfg_base(bus); | ||
| 261 | switch (len) { | ||
| 262 | case 1: | ||
| 263 | xgene_pcie_cfg_out8(addr, offset, (u8)val); | ||
| 264 | break; | ||
| 265 | case 2: | ||
| 266 | xgene_pcie_cfg_out16(addr, offset, (u16)val); | ||
| 267 | break; | ||
| 268 | default: | ||
| 269 | xgene_pcie_cfg_out32(addr, offset, val); | ||
| 270 | break; | ||
| 271 | } | ||
| 272 | |||
| 273 | return PCIBIOS_SUCCESSFUL; | ||
| 274 | } | ||
| 275 | |||
| 276 | static struct pci_ops xgene_pcie_ops = { | ||
| 277 | .read = xgene_pcie_read_config, | ||
| 278 | .write = xgene_pcie_write_config | ||
| 279 | }; | ||
| 280 | |||
| 281 | static u64 xgene_pcie_set_ib_mask(void __iomem *csr_base, u32 addr, | ||
| 282 | u32 flags, u64 size) | ||
| 283 | { | ||
| 284 | u64 mask = (~(size - 1) & PCI_BASE_ADDRESS_MEM_MASK) | flags; | ||
| 285 | u32 val32 = 0; | ||
| 286 | u32 val; | ||
| 287 | |||
| 288 | val32 = readl(csr_base + addr); | ||
| 289 | val = (val32 & 0x0000ffff) | (lower_32_bits(mask) << 16); | ||
| 290 | writel(val, csr_base + addr); | ||
| 291 | |||
| 292 | val32 = readl(csr_base + addr + 0x04); | ||
| 293 | val = (val32 & 0xffff0000) | (lower_32_bits(mask) >> 16); | ||
| 294 | writel(val, csr_base + addr + 0x04); | ||
| 295 | |||
| 296 | val32 = readl(csr_base + addr + 0x04); | ||
| 297 | val = (val32 & 0x0000ffff) | (upper_32_bits(mask) << 16); | ||
| 298 | writel(val, csr_base + addr + 0x04); | ||
| 299 | |||
| 300 | val32 = readl(csr_base + addr + 0x08); | ||
| 301 | val = (val32 & 0xffff0000) | (upper_32_bits(mask) >> 16); | ||
| 302 | writel(val, csr_base + addr + 0x08); | ||
| 303 | |||
| 304 | return mask; | ||
| 305 | } | ||
| 306 | |||
| 307 | static void xgene_pcie_linkup(struct xgene_pcie_port *port, | ||
| 308 | u32 *lanes, u32 *speed) | ||
| 309 | { | ||
| 310 | void __iomem *csr_base = port->csr_base; | ||
| 311 | u32 val32; | ||
| 312 | |||
| 313 | port->link_up = false; | ||
| 314 | val32 = readl(csr_base + PCIECORE_CTLANDSTATUS); | ||
| 315 | if (val32 & LINK_UP_MASK) { | ||
| 316 | port->link_up = true; | ||
| 317 | *speed = PIPE_PHY_RATE_RD(val32); | ||
| 318 | val32 = readl(csr_base + BRIDGE_STATUS_0); | ||
| 319 | *lanes = val32 >> 26; | ||
| 320 | } | ||
| 321 | } | ||
| 322 | |||
| 323 | static int xgene_pcie_init_port(struct xgene_pcie_port *port) | ||
| 324 | { | ||
| 325 | int rc; | ||
| 326 | |||
| 327 | port->clk = clk_get(port->dev, NULL); | ||
| 328 | if (IS_ERR(port->clk)) { | ||
| 329 | dev_err(port->dev, "clock not available\n"); | ||
| 330 | return -ENODEV; | ||
| 331 | } | ||
| 332 | |||
| 333 | rc = clk_prepare_enable(port->clk); | ||
| 334 | if (rc) { | ||
| 335 | dev_err(port->dev, "clock enable failed\n"); | ||
| 336 | return rc; | ||
| 337 | } | ||
| 338 | |||
| 339 | return 0; | ||
| 340 | } | ||
| 341 | |||
| 342 | static int xgene_pcie_map_reg(struct xgene_pcie_port *port, | ||
| 343 | struct platform_device *pdev) | ||
| 344 | { | ||
| 345 | struct resource *res; | ||
| 346 | |||
| 347 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr"); | ||
| 348 | port->csr_base = devm_ioremap_resource(port->dev, res); | ||
| 349 | if (IS_ERR(port->csr_base)) | ||
| 350 | return PTR_ERR(port->csr_base); | ||
| 351 | |||
| 352 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg"); | ||
| 353 | port->cfg_base = devm_ioremap_resource(port->dev, res); | ||
| 354 | if (IS_ERR(port->cfg_base)) | ||
| 355 | return PTR_ERR(port->cfg_base); | ||
| 356 | port->cfg_addr = res->start; | ||
| 357 | |||
| 358 | return 0; | ||
| 359 | } | ||
| 360 | |||
| 361 | static void xgene_pcie_setup_ob_reg(struct xgene_pcie_port *port, | ||
| 362 | struct resource *res, u32 offset, | ||
| 363 | u64 cpu_addr, u64 pci_addr) | ||
| 364 | { | ||
| 365 | void __iomem *base = port->csr_base + offset; | ||
| 366 | resource_size_t size = resource_size(res); | ||
| 367 | u64 restype = resource_type(res); | ||
| 368 | u64 mask = 0; | ||
| 369 | u32 min_size; | ||
| 370 | u32 flag = EN_REG; | ||
| 371 | |||
| 372 | if (restype == IORESOURCE_MEM) { | ||
| 373 | min_size = SZ_128M; | ||
| 374 | } else { | ||
| 375 | min_size = 128; | ||
| 376 | flag |= OB_LO_IO; | ||
| 377 | } | ||
| 378 | |||
| 379 | if (size >= min_size) | ||
| 380 | mask = ~(size - 1) | flag; | ||
| 381 | else | ||
| 382 | dev_warn(port->dev, "res size 0x%llx less than minimum 0x%x\n", | ||
| 383 | (u64)size, min_size); | ||
| 384 | |||
| 385 | writel(lower_32_bits(cpu_addr), base); | ||
| 386 | writel(upper_32_bits(cpu_addr), base + 0x04); | ||
| 387 | writel(lower_32_bits(mask), base + 0x08); | ||
| 388 | writel(upper_32_bits(mask), base + 0x0c); | ||
| 389 | writel(lower_32_bits(pci_addr), base + 0x10); | ||
| 390 | writel(upper_32_bits(pci_addr), base + 0x14); | ||
| 391 | } | ||
| 392 | |||
| 393 | static void xgene_pcie_setup_cfg_reg(void __iomem *csr_base, u64 addr) | ||
| 394 | { | ||
| 395 | writel(lower_32_bits(addr), csr_base + CFGBARL); | ||
| 396 | writel(upper_32_bits(addr), csr_base + CFGBARH); | ||
| 397 | writel(EN_REG, csr_base + CFGCTL); | ||
| 398 | } | ||
| 399 | |||
| 400 | static int xgene_pcie_map_ranges(struct xgene_pcie_port *port, | ||
| 401 | struct list_head *res, | ||
| 402 | resource_size_t io_base) | ||
| 403 | { | ||
| 404 | struct pci_host_bridge_window *window; | ||
| 405 | struct device *dev = port->dev; | ||
| 406 | int ret; | ||
| 407 | |||
| 408 | list_for_each_entry(window, res, list) { | ||
| 409 | struct resource *res = window->res; | ||
| 410 | u64 restype = resource_type(res); | ||
| 411 | |||
| 412 | dev_dbg(port->dev, "%pR\n", res); | ||
| 413 | |||
| 414 | switch (restype) { | ||
| 415 | case IORESOURCE_IO: | ||
| 416 | xgene_pcie_setup_ob_reg(port, res, OMR3BARL, io_base, | ||
| 417 | res->start - window->offset); | ||
| 418 | ret = pci_remap_iospace(res, io_base); | ||
| 419 | if (ret < 0) | ||
| 420 | return ret; | ||
| 421 | break; | ||
| 422 | case IORESOURCE_MEM: | ||
| 423 | xgene_pcie_setup_ob_reg(port, res, OMR1BARL, res->start, | ||
| 424 | res->start - window->offset); | ||
| 425 | break; | ||
| 426 | case IORESOURCE_BUS: | ||
| 427 | break; | ||
| 428 | default: | ||
| 429 | dev_err(dev, "invalid resource %pR\n", res); | ||
| 430 | return -EINVAL; | ||
| 431 | } | ||
| 432 | } | ||
| 433 | xgene_pcie_setup_cfg_reg(port->csr_base, port->cfg_addr); | ||
| 434 | |||
| 435 | return 0; | ||
| 436 | } | ||
| 437 | |||
| 438 | static void xgene_pcie_setup_pims(void *addr, u64 pim, u64 size) | ||
| 439 | { | ||
| 440 | writel(lower_32_bits(pim), addr); | ||
| 441 | writel(upper_32_bits(pim) | EN_COHERENCY, addr + 0x04); | ||
| 442 | writel(lower_32_bits(size), addr + 0x10); | ||
| 443 | writel(upper_32_bits(size), addr + 0x14); | ||
| 444 | } | ||
| 445 | |||
| 446 | /* | ||
| 447 | * X-Gene PCIe support maximum 3 inbound memory regions | ||
| 448 | * This function helps to select a region based on size of region | ||
| 449 | */ | ||
| 450 | static int xgene_pcie_select_ib_reg(u8 *ib_reg_mask, u64 size) | ||
| 451 | { | ||
| 452 | if ((size > 4) && (size < SZ_16M) && !(*ib_reg_mask & (1 << 1))) { | ||
| 453 | *ib_reg_mask |= (1 << 1); | ||
| 454 | return 1; | ||
| 455 | } | ||
| 456 | |||
| 457 | if ((size > SZ_1K) && (size < SZ_1T) && !(*ib_reg_mask & (1 << 0))) { | ||
| 458 | *ib_reg_mask |= (1 << 0); | ||
| 459 | return 0; | ||
| 460 | } | ||
| 461 | |||
| 462 | if ((size > SZ_1M) && (size < SZ_1T) && !(*ib_reg_mask & (1 << 2))) { | ||
| 463 | *ib_reg_mask |= (1 << 2); | ||
| 464 | return 2; | ||
| 465 | } | ||
| 466 | |||
| 467 | return -EINVAL; | ||
| 468 | } | ||
| 469 | |||
| 470 | static void xgene_pcie_setup_ib_reg(struct xgene_pcie_port *port, | ||
| 471 | struct of_pci_range *range, u8 *ib_reg_mask) | ||
| 472 | { | ||
| 473 | void __iomem *csr_base = port->csr_base; | ||
| 474 | void __iomem *cfg_base = port->cfg_base; | ||
| 475 | void *bar_addr; | ||
| 476 | void *pim_addr; | ||
| 477 | u64 cpu_addr = range->cpu_addr; | ||
| 478 | u64 pci_addr = range->pci_addr; | ||
| 479 | u64 size = range->size; | ||
| 480 | u64 mask = ~(size - 1) | EN_REG; | ||
| 481 | u32 flags = PCI_BASE_ADDRESS_MEM_TYPE_64; | ||
| 482 | u32 bar_low; | ||
| 483 | int region; | ||
| 484 | |||
| 485 | region = xgene_pcie_select_ib_reg(ib_reg_mask, range->size); | ||
| 486 | if (region < 0) { | ||
| 487 | dev_warn(port->dev, "invalid pcie dma-range config\n"); | ||
| 488 | return; | ||
| 489 | } | ||
| 490 | |||
| 491 | if (range->flags & IORESOURCE_PREFETCH) | ||
| 492 | flags |= PCI_BASE_ADDRESS_MEM_PREFETCH; | ||
| 493 | |||
| 494 | bar_low = pcie_bar_low_val((u32)cpu_addr, flags); | ||
| 495 | switch (region) { | ||
| 496 | case 0: | ||
| 497 | xgene_pcie_set_ib_mask(csr_base, BRIDGE_CFG_4, flags, size); | ||
| 498 | bar_addr = cfg_base + PCI_BASE_ADDRESS_0; | ||
| 499 | writel(bar_low, bar_addr); | ||
| 500 | writel(upper_32_bits(cpu_addr), bar_addr + 0x4); | ||
| 501 | pim_addr = csr_base + PIM1_1L; | ||
| 502 | break; | ||
| 503 | case 1: | ||
| 504 | bar_addr = csr_base + IBAR2; | ||
| 505 | writel(bar_low, bar_addr); | ||
| 506 | writel(lower_32_bits(mask), csr_base + IR2MSK); | ||
| 507 | pim_addr = csr_base + PIM2_1L; | ||
| 508 | break; | ||
| 509 | case 2: | ||
| 510 | bar_addr = csr_base + IBAR3L; | ||
| 511 | writel(bar_low, bar_addr); | ||
| 512 | writel(upper_32_bits(cpu_addr), bar_addr + 0x4); | ||
| 513 | writel(lower_32_bits(mask), csr_base + IR3MSKL); | ||
| 514 | writel(upper_32_bits(mask), csr_base + IR3MSKL + 0x4); | ||
| 515 | pim_addr = csr_base + PIM3_1L; | ||
| 516 | break; | ||
| 517 | } | ||
| 518 | |||
| 519 | xgene_pcie_setup_pims(pim_addr, pci_addr, ~(size - 1)); | ||
| 520 | } | ||
| 521 | |||
| 522 | static int pci_dma_range_parser_init(struct of_pci_range_parser *parser, | ||
| 523 | struct device_node *node) | ||
| 524 | { | ||
| 525 | const int na = 3, ns = 2; | ||
| 526 | int rlen; | ||
| 527 | |||
| 528 | parser->node = node; | ||
| 529 | parser->pna = of_n_addr_cells(node); | ||
| 530 | parser->np = parser->pna + na + ns; | ||
| 531 | |||
| 532 | parser->range = of_get_property(node, "dma-ranges", &rlen); | ||
| 533 | if (!parser->range) | ||
| 534 | return -ENOENT; | ||
| 535 | parser->end = parser->range + rlen / sizeof(__be32); | ||
| 536 | |||
| 537 | return 0; | ||
| 538 | } | ||
| 539 | |||
| 540 | static int xgene_pcie_parse_map_dma_ranges(struct xgene_pcie_port *port) | ||
| 541 | { | ||
| 542 | struct device_node *np = port->node; | ||
| 543 | struct of_pci_range range; | ||
| 544 | struct of_pci_range_parser parser; | ||
| 545 | struct device *dev = port->dev; | ||
| 546 | u8 ib_reg_mask = 0; | ||
| 547 | |||
| 548 | if (pci_dma_range_parser_init(&parser, np)) { | ||
| 549 | dev_err(dev, "missing dma-ranges property\n"); | ||
| 550 | return -EINVAL; | ||
| 551 | } | ||
| 552 | |||
| 553 | /* Get the dma-ranges from DT */ | ||
| 554 | for_each_of_pci_range(&parser, &range) { | ||
| 555 | u64 end = range.cpu_addr + range.size - 1; | ||
| 556 | |||
| 557 | dev_dbg(port->dev, "0x%08x 0x%016llx..0x%016llx -> 0x%016llx\n", | ||
| 558 | range.flags, range.cpu_addr, end, range.pci_addr); | ||
| 559 | xgene_pcie_setup_ib_reg(port, &range, &ib_reg_mask); | ||
| 560 | } | ||
| 561 | return 0; | ||
| 562 | } | ||
| 563 | |||
| 564 | /* clear BAR configuration which was done by firmware */ | ||
| 565 | static void xgene_pcie_clear_config(struct xgene_pcie_port *port) | ||
| 566 | { | ||
| 567 | int i; | ||
| 568 | |||
| 569 | for (i = PIM1_1L; i <= CFGCTL; i += 4) | ||
| 570 | writel(0x0, port->csr_base + i); | ||
| 571 | } | ||
| 572 | |||
| 573 | static int xgene_pcie_setup(struct xgene_pcie_port *port, | ||
| 574 | struct list_head *res, | ||
| 575 | resource_size_t io_base) | ||
| 576 | { | ||
| 577 | u32 val, lanes = 0, speed = 0; | ||
| 578 | int ret; | ||
| 579 | |||
| 580 | xgene_pcie_clear_config(port); | ||
| 581 | |||
| 582 | /* setup the vendor and device IDs correctly */ | ||
| 583 | val = (XGENE_PCIE_DEVICEID << 16) | XGENE_PCIE_VENDORID; | ||
| 584 | writel(val, port->csr_base + BRIDGE_CFG_0); | ||
| 585 | |||
| 586 | ret = xgene_pcie_map_ranges(port, res, io_base); | ||
| 587 | if (ret) | ||
| 588 | return ret; | ||
| 589 | |||
| 590 | ret = xgene_pcie_parse_map_dma_ranges(port); | ||
| 591 | if (ret) | ||
| 592 | return ret; | ||
| 593 | |||
| 594 | xgene_pcie_linkup(port, &lanes, &speed); | ||
| 595 | if (!port->link_up) | ||
| 596 | dev_info(port->dev, "(rc) link down\n"); | ||
| 597 | else | ||
| 598 | dev_info(port->dev, "(rc) x%d gen-%d link up\n", | ||
| 599 | lanes, speed + 1); | ||
| 600 | return 0; | ||
| 601 | } | ||
| 602 | |||
| 603 | static int xgene_pcie_probe_bridge(struct platform_device *pdev) | ||
| 604 | { | ||
| 605 | struct device_node *dn = pdev->dev.of_node; | ||
| 606 | struct xgene_pcie_port *port; | ||
| 607 | resource_size_t iobase = 0; | ||
| 608 | struct pci_bus *bus; | ||
| 609 | int ret; | ||
| 610 | LIST_HEAD(res); | ||
| 611 | |||
| 612 | port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL); | ||
| 613 | if (!port) | ||
| 614 | return -ENOMEM; | ||
| 615 | port->node = of_node_get(pdev->dev.of_node); | ||
| 616 | port->dev = &pdev->dev; | ||
| 617 | |||
| 618 | ret = xgene_pcie_map_reg(port, pdev); | ||
| 619 | if (ret) | ||
| 620 | return ret; | ||
| 621 | |||
| 622 | ret = xgene_pcie_init_port(port); | ||
| 623 | if (ret) | ||
| 624 | return ret; | ||
| 625 | |||
| 626 | ret = of_pci_get_host_bridge_resources(dn, 0, 0xff, &res, &iobase); | ||
| 627 | if (ret) | ||
| 628 | return ret; | ||
| 629 | |||
| 630 | ret = xgene_pcie_setup(port, &res, iobase); | ||
| 631 | if (ret) | ||
| 632 | return ret; | ||
| 633 | |||
| 634 | bus = pci_scan_root_bus(&pdev->dev, 0, &xgene_pcie_ops, port, &res); | ||
| 635 | if (!bus) | ||
| 636 | return -ENOMEM; | ||
| 637 | |||
| 638 | platform_set_drvdata(pdev, port); | ||
| 639 | return 0; | ||
| 640 | } | ||
| 641 | |||
| 642 | static const struct of_device_id xgene_pcie_match_table[] = { | ||
| 643 | {.compatible = "apm,xgene-pcie",}, | ||
| 644 | {}, | ||
| 645 | }; | ||
| 646 | |||
| 647 | static struct platform_driver xgene_pcie_driver = { | ||
| 648 | .driver = { | ||
| 649 | .name = "xgene-pcie", | ||
| 650 | .owner = THIS_MODULE, | ||
| 651 | .of_match_table = of_match_ptr(xgene_pcie_match_table), | ||
| 652 | }, | ||
| 653 | .probe = xgene_pcie_probe_bridge, | ||
| 654 | }; | ||
| 655 | module_platform_driver(xgene_pcie_driver); | ||
| 656 | |||
| 657 | MODULE_AUTHOR("Tanmay Inamdar <tinamdar@apm.com>"); | ||
| 658 | MODULE_DESCRIPTION("APM X-Gene PCIe driver"); | ||
| 659 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 52bd3a143563..dfed00aa3ac0 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c | |||
| @@ -73,6 +73,8 @@ static unsigned long global_io_offset; | |||
| 73 | 73 | ||
| 74 | static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys) | 74 | static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys) |
| 75 | { | 75 | { |
| 76 | BUG_ON(!sys->private_data); | ||
| 77 | |||
| 76 | return sys->private_data; | 78 | return sys->private_data; |
| 77 | } | 79 | } |
| 78 | 80 | ||
| @@ -194,30 +196,6 @@ void dw_pcie_msi_init(struct pcie_port *pp) | |||
| 194 | dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_HI, 4, 0); | 196 | dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_HI, 4, 0); |
| 195 | } | 197 | } |
| 196 | 198 | ||
| 197 | static int find_valid_pos0(struct pcie_port *pp, int msgvec, int pos, int *pos0) | ||
| 198 | { | ||
| 199 | int flag = 1; | ||
| 200 | |||
| 201 | do { | ||
| 202 | pos = find_next_zero_bit(pp->msi_irq_in_use, | ||
| 203 | MAX_MSI_IRQS, pos); | ||
| 204 | /*if you have reached to the end then get out from here.*/ | ||
| 205 | if (pos == MAX_MSI_IRQS) | ||
| 206 | return -ENOSPC; | ||
| 207 | /* | ||
| 208 | * Check if this position is at correct offset.nvec is always a | ||
| 209 | * power of two. pos0 must be nvec bit aligned. | ||
| 210 | */ | ||
| 211 | if (pos % msgvec) | ||
| 212 | pos += msgvec - (pos % msgvec); | ||
| 213 | else | ||
| 214 | flag = 0; | ||
| 215 | } while (flag); | ||
| 216 | |||
| 217 | *pos0 = pos; | ||
| 218 | return 0; | ||
| 219 | } | ||
| 220 | |||
| 221 | static void dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq) | 199 | static void dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq) |
| 222 | { | 200 | { |
| 223 | unsigned int res, bit, val; | 201 | unsigned int res, bit, val; |
| @@ -236,13 +214,14 @@ static void clear_irq_range(struct pcie_port *pp, unsigned int irq_base, | |||
| 236 | 214 | ||
| 237 | for (i = 0; i < nvec; i++) { | 215 | for (i = 0; i < nvec; i++) { |
| 238 | irq_set_msi_desc_off(irq_base, i, NULL); | 216 | irq_set_msi_desc_off(irq_base, i, NULL); |
| 239 | clear_bit(pos + i, pp->msi_irq_in_use); | ||
| 240 | /* Disable corresponding interrupt on MSI controller */ | 217 | /* Disable corresponding interrupt on MSI controller */ |
| 241 | if (pp->ops->msi_clear_irq) | 218 | if (pp->ops->msi_clear_irq) |
| 242 | pp->ops->msi_clear_irq(pp, pos + i); | 219 | pp->ops->msi_clear_irq(pp, pos + i); |
| 243 | else | 220 | else |
| 244 | dw_pcie_msi_clear_irq(pp, pos + i); | 221 | dw_pcie_msi_clear_irq(pp, pos + i); |
| 245 | } | 222 | } |
| 223 | |||
| 224 | bitmap_release_region(pp->msi_irq_in_use, pos, order_base_2(nvec)); | ||
| 246 | } | 225 | } |
| 247 | 226 | ||
| 248 | static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) | 227 | static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) |
| @@ -258,31 +237,13 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) | |||
| 258 | 237 | ||
| 259 | static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) | 238 | static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) |
| 260 | { | 239 | { |
| 261 | int irq, pos0, pos1, i; | 240 | int irq, pos0, i; |
| 262 | struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); | 241 | struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); |
| 263 | 242 | ||
| 264 | if (!pp) { | 243 | pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS, |
| 265 | BUG(); | 244 | order_base_2(no_irqs)); |
| 266 | return -EINVAL; | 245 | if (pos0 < 0) |
| 267 | } | 246 | goto no_valid_irq; |
| 268 | |||
| 269 | pos0 = find_first_zero_bit(pp->msi_irq_in_use, | ||
| 270 | MAX_MSI_IRQS); | ||
| 271 | if (pos0 % no_irqs) { | ||
| 272 | if (find_valid_pos0(pp, no_irqs, pos0, &pos0)) | ||
| 273 | goto no_valid_irq; | ||
| 274 | } | ||
| 275 | if (no_irqs > 1) { | ||
| 276 | pos1 = find_next_bit(pp->msi_irq_in_use, | ||
| 277 | MAX_MSI_IRQS, pos0); | ||
| 278 | /* there must be nvec number of consecutive free bits */ | ||
| 279 | while ((pos1 - pos0) < no_irqs) { | ||
| 280 | if (find_valid_pos0(pp, no_irqs, pos1, &pos0)) | ||
| 281 | goto no_valid_irq; | ||
| 282 | pos1 = find_next_bit(pp->msi_irq_in_use, | ||
| 283 | MAX_MSI_IRQS, pos0); | ||
| 284 | } | ||
| 285 | } | ||
| 286 | 247 | ||
| 287 | irq = irq_find_mapping(pp->irq_domain, pos0); | 248 | irq = irq_find_mapping(pp->irq_domain, pos0); |
| 288 | if (!irq) | 249 | if (!irq) |
| @@ -300,7 +261,6 @@ static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) | |||
| 300 | clear_irq_range(pp, irq, i, pos0); | 261 | clear_irq_range(pp, irq, i, pos0); |
| 301 | goto no_valid_irq; | 262 | goto no_valid_irq; |
| 302 | } | 263 | } |
| 303 | set_bit(pos0 + i, pp->msi_irq_in_use); | ||
| 304 | /*Enable corresponding interrupt in MSI interrupt controller */ | 264 | /*Enable corresponding interrupt in MSI interrupt controller */ |
| 305 | if (pp->ops->msi_set_irq) | 265 | if (pp->ops->msi_set_irq) |
| 306 | pp->ops->msi_set_irq(pp, pos0 + i); | 266 | pp->ops->msi_set_irq(pp, pos0 + i); |
| @@ -316,69 +276,28 @@ no_valid_irq: | |||
| 316 | return -ENOSPC; | 276 | return -ENOSPC; |
| 317 | } | 277 | } |
| 318 | 278 | ||
| 319 | static void clear_irq(unsigned int irq) | ||
| 320 | { | ||
| 321 | unsigned int pos, nvec; | ||
| 322 | struct msi_desc *msi; | ||
| 323 | struct pcie_port *pp; | ||
| 324 | struct irq_data *data = irq_get_irq_data(irq); | ||
| 325 | |||
| 326 | /* get the port structure */ | ||
| 327 | msi = irq_data_get_msi(data); | ||
| 328 | pp = sys_to_pcie(msi->dev->bus->sysdata); | ||
| 329 | if (!pp) { | ||
| 330 | BUG(); | ||
| 331 | return; | ||
| 332 | } | ||
| 333 | |||
| 334 | /* undo what was done in assign_irq */ | ||
| 335 | pos = data->hwirq; | ||
| 336 | nvec = 1 << msi->msi_attrib.multiple; | ||
| 337 | |||
| 338 | clear_irq_range(pp, irq, nvec, pos); | ||
| 339 | |||
| 340 | /* all irqs cleared; reset attributes */ | ||
| 341 | msi->irq = 0; | ||
| 342 | msi->msi_attrib.multiple = 0; | ||
| 343 | } | ||
| 344 | |||
| 345 | static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev, | 279 | static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev, |
| 346 | struct msi_desc *desc) | 280 | struct msi_desc *desc) |
| 347 | { | 281 | { |
| 348 | int irq, pos, msgvec; | 282 | int irq, pos; |
| 349 | u16 msg_ctr; | ||
| 350 | struct msi_msg msg; | 283 | struct msi_msg msg; |
| 351 | struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata); | 284 | struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata); |
| 352 | 285 | ||
| 353 | if (!pp) { | 286 | irq = assign_irq(1, desc, &pos); |
| 354 | BUG(); | ||
| 355 | return -EINVAL; | ||
| 356 | } | ||
| 357 | |||
| 358 | pci_read_config_word(pdev, desc->msi_attrib.pos+PCI_MSI_FLAGS, | ||
| 359 | &msg_ctr); | ||
| 360 | msgvec = (msg_ctr&PCI_MSI_FLAGS_QSIZE) >> 4; | ||
| 361 | if (msgvec == 0) | ||
| 362 | msgvec = (msg_ctr & PCI_MSI_FLAGS_QMASK) >> 1; | ||
| 363 | if (msgvec > 5) | ||
| 364 | msgvec = 0; | ||
| 365 | |||
| 366 | irq = assign_irq((1 << msgvec), desc, &pos); | ||
| 367 | if (irq < 0) | 287 | if (irq < 0) |
| 368 | return irq; | 288 | return irq; |
| 369 | 289 | ||
| 370 | /* | 290 | if (pp->ops->get_msi_addr) |
| 371 | * write_msi_msg() will update PCI_MSI_FLAGS so there is | 291 | msg.address_lo = pp->ops->get_msi_addr(pp); |
| 372 | * no need to explicitly call pci_write_config_word(). | ||
| 373 | */ | ||
| 374 | desc->msi_attrib.multiple = msgvec; | ||
| 375 | |||
| 376 | if (pp->ops->get_msi_data) | ||
| 377 | msg.address_lo = pp->ops->get_msi_data(pp); | ||
| 378 | else | 292 | else |
| 379 | msg.address_lo = virt_to_phys((void *)pp->msi_data); | 293 | msg.address_lo = virt_to_phys((void *)pp->msi_data); |
| 380 | msg.address_hi = 0x0; | 294 | msg.address_hi = 0x0; |
| 381 | msg.data = pos; | 295 | |
| 296 | if (pp->ops->get_msi_data) | ||
| 297 | msg.data = pp->ops->get_msi_data(pp, pos); | ||
| 298 | else | ||
| 299 | msg.data = pos; | ||
| 300 | |||
| 382 | write_msi_msg(irq, &msg); | 301 | write_msi_msg(irq, &msg); |
| 383 | 302 | ||
| 384 | return 0; | 303 | return 0; |
| @@ -386,7 +305,11 @@ static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev, | |||
| 386 | 305 | ||
| 387 | static void dw_msi_teardown_irq(struct msi_chip *chip, unsigned int irq) | 306 | static void dw_msi_teardown_irq(struct msi_chip *chip, unsigned int irq) |
| 388 | { | 307 | { |
| 389 | clear_irq(irq); | 308 | struct irq_data *data = irq_get_irq_data(irq); |
| 309 | struct msi_desc *msi = irq_data_get_msi(data); | ||
| 310 | struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata); | ||
| 311 | |||
| 312 | clear_irq_range(pp, irq, 1, data->hwirq); | ||
| 390 | } | 313 | } |
| 391 | 314 | ||
| 392 | static struct msi_chip dw_pcie_msi_chip = { | 315 | static struct msi_chip dw_pcie_msi_chip = { |
| @@ -425,7 +348,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
| 425 | struct resource *cfg_res; | 348 | struct resource *cfg_res; |
| 426 | u32 val, na, ns; | 349 | u32 val, na, ns; |
| 427 | const __be32 *addrp; | 350 | const __be32 *addrp; |
| 428 | int i, index; | 351 | int i, index, ret; |
| 429 | 352 | ||
| 430 | /* Find the address cell size and the number of cells in order to get | 353 | /* Find the address cell size and the number of cells in order to get |
| 431 | * the untranslated address. | 354 | * the untranslated address. |
| @@ -435,16 +358,16 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
| 435 | 358 | ||
| 436 | cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); | 359 | cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); |
| 437 | if (cfg_res) { | 360 | if (cfg_res) { |
| 438 | pp->config.cfg0_size = resource_size(cfg_res)/2; | 361 | pp->cfg0_size = resource_size(cfg_res)/2; |
| 439 | pp->config.cfg1_size = resource_size(cfg_res)/2; | 362 | pp->cfg1_size = resource_size(cfg_res)/2; |
| 440 | pp->cfg0_base = cfg_res->start; | 363 | pp->cfg0_base = cfg_res->start; |
| 441 | pp->cfg1_base = cfg_res->start + pp->config.cfg0_size; | 364 | pp->cfg1_base = cfg_res->start + pp->cfg0_size; |
| 442 | 365 | ||
| 443 | /* Find the untranslated configuration space address */ | 366 | /* Find the untranslated configuration space address */ |
| 444 | index = of_property_match_string(np, "reg-names", "config"); | 367 | index = of_property_match_string(np, "reg-names", "config"); |
| 445 | addrp = of_get_address(np, index, false, false); | 368 | addrp = of_get_address(np, index, NULL, NULL); |
| 446 | pp->cfg0_mod_base = of_read_number(addrp, ns); | 369 | pp->cfg0_mod_base = of_read_number(addrp, ns); |
| 447 | pp->cfg1_mod_base = pp->cfg0_mod_base + pp->config.cfg0_size; | 370 | pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; |
| 448 | } else { | 371 | } else { |
| 449 | dev_err(pp->dev, "missing *config* reg space\n"); | 372 | dev_err(pp->dev, "missing *config* reg space\n"); |
| 450 | } | 373 | } |
| @@ -466,9 +389,9 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
| 466 | pp->io.end = min_t(resource_size_t, | 389 | pp->io.end = min_t(resource_size_t, |
| 467 | IO_SPACE_LIMIT, | 390 | IO_SPACE_LIMIT, |
| 468 | range.pci_addr + range.size | 391 | range.pci_addr + range.size |
| 469 | + global_io_offset); | 392 | + global_io_offset - 1); |
| 470 | pp->config.io_size = resource_size(&pp->io); | 393 | pp->io_size = resource_size(&pp->io); |
| 471 | pp->config.io_bus_addr = range.pci_addr; | 394 | pp->io_bus_addr = range.pci_addr; |
| 472 | pp->io_base = range.cpu_addr; | 395 | pp->io_base = range.cpu_addr; |
| 473 | 396 | ||
| 474 | /* Find the untranslated IO space address */ | 397 | /* Find the untranslated IO space address */ |
| @@ -478,8 +401,8 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
| 478 | if (restype == IORESOURCE_MEM) { | 401 | if (restype == IORESOURCE_MEM) { |
| 479 | of_pci_range_to_resource(&range, np, &pp->mem); | 402 | of_pci_range_to_resource(&range, np, &pp->mem); |
| 480 | pp->mem.name = "MEM"; | 403 | pp->mem.name = "MEM"; |
| 481 | pp->config.mem_size = resource_size(&pp->mem); | 404 | pp->mem_size = resource_size(&pp->mem); |
| 482 | pp->config.mem_bus_addr = range.pci_addr; | 405 | pp->mem_bus_addr = range.pci_addr; |
| 483 | 406 | ||
| 484 | /* Find the untranslated MEM space address */ | 407 | /* Find the untranslated MEM space address */ |
| 485 | pp->mem_mod_base = of_read_number(parser.range - | 408 | pp->mem_mod_base = of_read_number(parser.range - |
| @@ -487,19 +410,29 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
| 487 | } | 410 | } |
| 488 | if (restype == 0) { | 411 | if (restype == 0) { |
| 489 | of_pci_range_to_resource(&range, np, &pp->cfg); | 412 | of_pci_range_to_resource(&range, np, &pp->cfg); |
| 490 | pp->config.cfg0_size = resource_size(&pp->cfg)/2; | 413 | pp->cfg0_size = resource_size(&pp->cfg)/2; |
| 491 | pp->config.cfg1_size = resource_size(&pp->cfg)/2; | 414 | pp->cfg1_size = resource_size(&pp->cfg)/2; |
| 492 | pp->cfg0_base = pp->cfg.start; | 415 | pp->cfg0_base = pp->cfg.start; |
| 493 | pp->cfg1_base = pp->cfg.start + pp->config.cfg0_size; | 416 | pp->cfg1_base = pp->cfg.start + pp->cfg0_size; |
| 494 | 417 | ||
| 495 | /* Find the untranslated configuration space address */ | 418 | /* Find the untranslated configuration space address */ |
| 496 | pp->cfg0_mod_base = of_read_number(parser.range - | 419 | pp->cfg0_mod_base = of_read_number(parser.range - |
| 497 | parser.np + na, ns); | 420 | parser.np + na, ns); |
| 498 | pp->cfg1_mod_base = pp->cfg0_mod_base + | 421 | pp->cfg1_mod_base = pp->cfg0_mod_base + |
| 499 | pp->config.cfg0_size; | 422 | pp->cfg0_size; |
| 500 | } | 423 | } |
| 501 | } | 424 | } |
| 502 | 425 | ||
| 426 | ret = of_pci_parse_bus_range(np, &pp->busn); | ||
| 427 | if (ret < 0) { | ||
| 428 | pp->busn.name = np->name; | ||
| 429 | pp->busn.start = 0; | ||
| 430 | pp->busn.end = 0xff; | ||
| 431 | pp->busn.flags = IORESOURCE_BUS; | ||
| 432 | dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n", | ||
| 433 | ret, &pp->busn); | ||
| 434 | } | ||
| 435 | |||
| 503 | if (!pp->dbi_base) { | 436 | if (!pp->dbi_base) { |
| 504 | pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start, | 437 | pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start, |
| 505 | resource_size(&pp->cfg)); | 438 | resource_size(&pp->cfg)); |
| @@ -511,17 +444,22 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
| 511 | 444 | ||
| 512 | pp->mem_base = pp->mem.start; | 445 | pp->mem_base = pp->mem.start; |
| 513 | 446 | ||
| 514 | pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, | ||
| 515 | pp->config.cfg0_size); | ||
| 516 | if (!pp->va_cfg0_base) { | 447 | if (!pp->va_cfg0_base) { |
| 517 | dev_err(pp->dev, "error with ioremap in function\n"); | 448 | pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, |
| 518 | return -ENOMEM; | 449 | pp->cfg0_size); |
| 450 | if (!pp->va_cfg0_base) { | ||
| 451 | dev_err(pp->dev, "error with ioremap in function\n"); | ||
| 452 | return -ENOMEM; | ||
| 453 | } | ||
| 519 | } | 454 | } |
| 520 | pp->va_cfg1_base = devm_ioremap(pp->dev, pp->cfg1_base, | 455 | |
| 521 | pp->config.cfg1_size); | ||
| 522 | if (!pp->va_cfg1_base) { | 456 | if (!pp->va_cfg1_base) { |
| 523 | dev_err(pp->dev, "error with ioremap\n"); | 457 | pp->va_cfg1_base = devm_ioremap(pp->dev, pp->cfg1_base, |
| 524 | return -ENOMEM; | 458 | pp->cfg1_size); |
| 459 | if (!pp->va_cfg1_base) { | ||
| 460 | dev_err(pp->dev, "error with ioremap\n"); | ||
| 461 | return -ENOMEM; | ||
| 462 | } | ||
| 525 | } | 463 | } |
| 526 | 464 | ||
| 527 | if (of_property_read_u32(np, "num-lanes", &pp->lanes)) { | 465 | if (of_property_read_u32(np, "num-lanes", &pp->lanes)) { |
| @@ -530,16 +468,22 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
| 530 | } | 468 | } |
| 531 | 469 | ||
| 532 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | 470 | if (IS_ENABLED(CONFIG_PCI_MSI)) { |
| 533 | pp->irq_domain = irq_domain_add_linear(pp->dev->of_node, | 471 | if (!pp->ops->msi_host_init) { |
| 534 | MAX_MSI_IRQS, &msi_domain_ops, | 472 | pp->irq_domain = irq_domain_add_linear(pp->dev->of_node, |
| 535 | &dw_pcie_msi_chip); | 473 | MAX_MSI_IRQS, &msi_domain_ops, |
| 536 | if (!pp->irq_domain) { | 474 | &dw_pcie_msi_chip); |
| 537 | dev_err(pp->dev, "irq domain init failed\n"); | 475 | if (!pp->irq_domain) { |
| 538 | return -ENXIO; | 476 | dev_err(pp->dev, "irq domain init failed\n"); |
| 539 | } | 477 | return -ENXIO; |
| 478 | } | ||
| 540 | 479 | ||
| 541 | for (i = 0; i < MAX_MSI_IRQS; i++) | 480 | for (i = 0; i < MAX_MSI_IRQS; i++) |
| 542 | irq_create_mapping(pp->irq_domain, i); | 481 | irq_create_mapping(pp->irq_domain, i); |
| 482 | } else { | ||
| 483 | ret = pp->ops->msi_host_init(pp, &dw_pcie_msi_chip); | ||
| 484 | if (ret < 0) | ||
| 485 | return ret; | ||
| 486 | } | ||
| 543 | } | 487 | } |
| 544 | 488 | ||
| 545 | if (pp->ops->host_init) | 489 | if (pp->ops->host_init) |
| @@ -558,7 +502,6 @@ int __init dw_pcie_host_init(struct pcie_port *pp) | |||
| 558 | dw_pci.private_data = (void **)&pp; | 502 | dw_pci.private_data = (void **)&pp; |
| 559 | 503 | ||
| 560 | pci_common_init_dev(pp->dev, &dw_pci); | 504 | pci_common_init_dev(pp->dev, &dw_pci); |
| 561 | pci_assign_unassigned_resources(); | ||
| 562 | #ifdef CONFIG_PCI_DOMAINS | 505 | #ifdef CONFIG_PCI_DOMAINS |
| 563 | dw_pci.domain++; | 506 | dw_pci.domain++; |
| 564 | #endif | 507 | #endif |
| @@ -573,7 +516,7 @@ static void dw_pcie_prog_viewport_cfg0(struct pcie_port *pp, u32 busdev) | |||
| 573 | PCIE_ATU_VIEWPORT); | 516 | PCIE_ATU_VIEWPORT); |
| 574 | dw_pcie_writel_rc(pp, pp->cfg0_mod_base, PCIE_ATU_LOWER_BASE); | 517 | dw_pcie_writel_rc(pp, pp->cfg0_mod_base, PCIE_ATU_LOWER_BASE); |
| 575 | dw_pcie_writel_rc(pp, (pp->cfg0_mod_base >> 32), PCIE_ATU_UPPER_BASE); | 518 | dw_pcie_writel_rc(pp, (pp->cfg0_mod_base >> 32), PCIE_ATU_UPPER_BASE); |
| 576 | dw_pcie_writel_rc(pp, pp->cfg0_mod_base + pp->config.cfg0_size - 1, | 519 | dw_pcie_writel_rc(pp, pp->cfg0_mod_base + pp->cfg0_size - 1, |
| 577 | PCIE_ATU_LIMIT); | 520 | PCIE_ATU_LIMIT); |
| 578 | dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET); | 521 | dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET); |
| 579 | dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET); | 522 | dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET); |
| @@ -589,7 +532,7 @@ static void dw_pcie_prog_viewport_cfg1(struct pcie_port *pp, u32 busdev) | |||
| 589 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1); | 532 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1); |
| 590 | dw_pcie_writel_rc(pp, pp->cfg1_mod_base, PCIE_ATU_LOWER_BASE); | 533 | dw_pcie_writel_rc(pp, pp->cfg1_mod_base, PCIE_ATU_LOWER_BASE); |
| 591 | dw_pcie_writel_rc(pp, (pp->cfg1_mod_base >> 32), PCIE_ATU_UPPER_BASE); | 534 | dw_pcie_writel_rc(pp, (pp->cfg1_mod_base >> 32), PCIE_ATU_UPPER_BASE); |
| 592 | dw_pcie_writel_rc(pp, pp->cfg1_mod_base + pp->config.cfg1_size - 1, | 535 | dw_pcie_writel_rc(pp, pp->cfg1_mod_base + pp->cfg1_size - 1, |
| 593 | PCIE_ATU_LIMIT); | 536 | PCIE_ATU_LIMIT); |
| 594 | dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET); | 537 | dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET); |
| 595 | dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET); | 538 | dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET); |
| @@ -604,10 +547,10 @@ static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp) | |||
| 604 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1); | 547 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1); |
| 605 | dw_pcie_writel_rc(pp, pp->mem_mod_base, PCIE_ATU_LOWER_BASE); | 548 | dw_pcie_writel_rc(pp, pp->mem_mod_base, PCIE_ATU_LOWER_BASE); |
| 606 | dw_pcie_writel_rc(pp, (pp->mem_mod_base >> 32), PCIE_ATU_UPPER_BASE); | 549 | dw_pcie_writel_rc(pp, (pp->mem_mod_base >> 32), PCIE_ATU_UPPER_BASE); |
| 607 | dw_pcie_writel_rc(pp, pp->mem_mod_base + pp->config.mem_size - 1, | 550 | dw_pcie_writel_rc(pp, pp->mem_mod_base + pp->mem_size - 1, |
| 608 | PCIE_ATU_LIMIT); | 551 | PCIE_ATU_LIMIT); |
| 609 | dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET); | 552 | dw_pcie_writel_rc(pp, pp->mem_bus_addr, PCIE_ATU_LOWER_TARGET); |
| 610 | dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr), | 553 | dw_pcie_writel_rc(pp, upper_32_bits(pp->mem_bus_addr), |
| 611 | PCIE_ATU_UPPER_TARGET); | 554 | PCIE_ATU_UPPER_TARGET); |
| 612 | dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2); | 555 | dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2); |
| 613 | } | 556 | } |
| @@ -620,10 +563,10 @@ static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp) | |||
| 620 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1); | 563 | dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1); |
| 621 | dw_pcie_writel_rc(pp, pp->io_mod_base, PCIE_ATU_LOWER_BASE); | 564 | dw_pcie_writel_rc(pp, pp->io_mod_base, PCIE_ATU_LOWER_BASE); |
| 622 | dw_pcie_writel_rc(pp, (pp->io_mod_base >> 32), PCIE_ATU_UPPER_BASE); | 565 | dw_pcie_writel_rc(pp, (pp->io_mod_base >> 32), PCIE_ATU_UPPER_BASE); |
| 623 | dw_pcie_writel_rc(pp, pp->io_mod_base + pp->config.io_size - 1, | 566 | dw_pcie_writel_rc(pp, pp->io_mod_base + pp->io_size - 1, |
| 624 | PCIE_ATU_LIMIT); | 567 | PCIE_ATU_LIMIT); |
| 625 | dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET); | 568 | dw_pcie_writel_rc(pp, pp->io_bus_addr, PCIE_ATU_LOWER_TARGET); |
| 626 | dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr), | 569 | dw_pcie_writel_rc(pp, upper_32_bits(pp->io_bus_addr), |
| 627 | PCIE_ATU_UPPER_TARGET); | 570 | PCIE_ATU_UPPER_TARGET); |
| 628 | dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2); | 571 | dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2); |
| 629 | } | 572 | } |
| @@ -707,11 +650,6 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, | |||
| 707 | struct pcie_port *pp = sys_to_pcie(bus->sysdata); | 650 | struct pcie_port *pp = sys_to_pcie(bus->sysdata); |
| 708 | int ret; | 651 | int ret; |
| 709 | 652 | ||
| 710 | if (!pp) { | ||
| 711 | BUG(); | ||
| 712 | return -EINVAL; | ||
| 713 | } | ||
| 714 | |||
| 715 | if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { | 653 | if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { |
| 716 | *val = 0xffffffff; | 654 | *val = 0xffffffff; |
| 717 | return PCIBIOS_DEVICE_NOT_FOUND; | 655 | return PCIBIOS_DEVICE_NOT_FOUND; |
| @@ -736,11 +674,6 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn, | |||
| 736 | struct pcie_port *pp = sys_to_pcie(bus->sysdata); | 674 | struct pcie_port *pp = sys_to_pcie(bus->sysdata); |
| 737 | int ret; | 675 | int ret; |
| 738 | 676 | ||
| 739 | if (!pp) { | ||
| 740 | BUG(); | ||
| 741 | return -EINVAL; | ||
| 742 | } | ||
| 743 | |||
| 744 | if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) | 677 | if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) |
| 745 | return PCIBIOS_DEVICE_NOT_FOUND; | 678 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 746 | 679 | ||
| @@ -768,19 +701,17 @@ static int dw_pcie_setup(int nr, struct pci_sys_data *sys) | |||
| 768 | 701 | ||
| 769 | pp = sys_to_pcie(sys); | 702 | pp = sys_to_pcie(sys); |
| 770 | 703 | ||
| 771 | if (!pp) | 704 | if (global_io_offset < SZ_1M && pp->io_size > 0) { |
| 772 | return 0; | 705 | sys->io_offset = global_io_offset - pp->io_bus_addr; |
| 773 | |||
| 774 | if (global_io_offset < SZ_1M && pp->config.io_size > 0) { | ||
| 775 | sys->io_offset = global_io_offset - pp->config.io_bus_addr; | ||
| 776 | pci_ioremap_io(global_io_offset, pp->io_base); | 706 | pci_ioremap_io(global_io_offset, pp->io_base); |
| 777 | global_io_offset += SZ_64K; | 707 | global_io_offset += SZ_64K; |
| 778 | pci_add_resource_offset(&sys->resources, &pp->io, | 708 | pci_add_resource_offset(&sys->resources, &pp->io, |
| 779 | sys->io_offset); | 709 | sys->io_offset); |
| 780 | } | 710 | } |
| 781 | 711 | ||
| 782 | sys->mem_offset = pp->mem.start - pp->config.mem_bus_addr; | 712 | sys->mem_offset = pp->mem.start - pp->mem_bus_addr; |
| 783 | pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset); | 713 | pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset); |
| 714 | pci_add_resource(&sys->resources, &pp->busn); | ||
| 784 | 715 | ||
| 785 | return 1; | 716 | return 1; |
| 786 | } | 717 | } |
| @@ -790,14 +721,16 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys) | |||
| 790 | struct pci_bus *bus; | 721 | struct pci_bus *bus; |
| 791 | struct pcie_port *pp = sys_to_pcie(sys); | 722 | struct pcie_port *pp = sys_to_pcie(sys); |
| 792 | 723 | ||
| 793 | if (pp) { | 724 | pp->root_bus_nr = sys->busnr; |
| 794 | pp->root_bus_nr = sys->busnr; | 725 | bus = pci_create_root_bus(pp->dev, sys->busnr, |
| 795 | bus = pci_scan_root_bus(pp->dev, sys->busnr, &dw_pcie_ops, | 726 | &dw_pcie_ops, sys, &sys->resources); |
| 796 | sys, &sys->resources); | 727 | if (!bus) |
| 797 | } else { | 728 | return NULL; |
| 798 | bus = NULL; | 729 | |
| 799 | BUG(); | 730 | pci_scan_child_bus(bus); |
| 800 | } | 731 | |
| 732 | if (bus && pp->ops->scan_bus) | ||
| 733 | pp->ops->scan_bus(pp); | ||
| 801 | 734 | ||
| 802 | return bus; | 735 | return bus; |
| 803 | } | 736 | } |
| @@ -833,7 +766,6 @@ static struct hw_pci dw_pci = { | |||
| 833 | 766 | ||
| 834 | void dw_pcie_setup_rc(struct pcie_port *pp) | 767 | void dw_pcie_setup_rc(struct pcie_port *pp) |
| 835 | { | 768 | { |
| 836 | struct pcie_port_info *config = &pp->config; | ||
| 837 | u32 val; | 769 | u32 val; |
| 838 | u32 membase; | 770 | u32 membase; |
| 839 | u32 memlimit; | 771 | u32 memlimit; |
| @@ -888,7 +820,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp) | |||
| 888 | 820 | ||
| 889 | /* setup memory base, memory limit */ | 821 | /* setup memory base, memory limit */ |
| 890 | membase = ((u32)pp->mem_base & 0xfff00000) >> 16; | 822 | membase = ((u32)pp->mem_base & 0xfff00000) >> 16; |
| 891 | memlimit = (config->mem_size + (u32)pp->mem_base) & 0xfff00000; | 823 | memlimit = (pp->mem_size + (u32)pp->mem_base) & 0xfff00000; |
| 892 | val = memlimit | membase; | 824 | val = memlimit | membase; |
| 893 | dw_pcie_writel_rc(pp, val, PCI_MEMORY_BASE); | 825 | dw_pcie_writel_rc(pp, val, PCI_MEMORY_BASE); |
| 894 | 826 | ||
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h index daf81f922cda..c6256751daff 100644 --- a/drivers/pci/host/pcie-designware.h +++ b/drivers/pci/host/pcie-designware.h | |||
| @@ -14,15 +14,6 @@ | |||
| 14 | #ifndef _PCIE_DESIGNWARE_H | 14 | #ifndef _PCIE_DESIGNWARE_H |
| 15 | #define _PCIE_DESIGNWARE_H | 15 | #define _PCIE_DESIGNWARE_H |
| 16 | 16 | ||
| 17 | struct pcie_port_info { | ||
| 18 | u32 cfg0_size; | ||
| 19 | u32 cfg1_size; | ||
| 20 | u32 io_size; | ||
| 21 | u32 mem_size; | ||
| 22 | phys_addr_t io_bus_addr; | ||
| 23 | phys_addr_t mem_bus_addr; | ||
| 24 | }; | ||
| 25 | |||
| 26 | /* | 17 | /* |
| 27 | * Maximum number of MSI IRQs can be 256 per controller. But keep | 18 | * Maximum number of MSI IRQs can be 256 per controller. But keep |
| 28 | * it 32 as of now. Probably we will never need more than 32. If needed, | 19 | * it 32 as of now. Probably we will never need more than 32. If needed, |
| @@ -38,17 +29,23 @@ struct pcie_port { | |||
| 38 | u64 cfg0_base; | 29 | u64 cfg0_base; |
| 39 | u64 cfg0_mod_base; | 30 | u64 cfg0_mod_base; |
| 40 | void __iomem *va_cfg0_base; | 31 | void __iomem *va_cfg0_base; |
| 32 | u32 cfg0_size; | ||
| 41 | u64 cfg1_base; | 33 | u64 cfg1_base; |
| 42 | u64 cfg1_mod_base; | 34 | u64 cfg1_mod_base; |
| 43 | void __iomem *va_cfg1_base; | 35 | void __iomem *va_cfg1_base; |
| 36 | u32 cfg1_size; | ||
| 44 | u64 io_base; | 37 | u64 io_base; |
| 45 | u64 io_mod_base; | 38 | u64 io_mod_base; |
| 39 | phys_addr_t io_bus_addr; | ||
| 40 | u32 io_size; | ||
| 46 | u64 mem_base; | 41 | u64 mem_base; |
| 47 | u64 mem_mod_base; | 42 | u64 mem_mod_base; |
| 43 | phys_addr_t mem_bus_addr; | ||
| 44 | u32 mem_size; | ||
| 48 | struct resource cfg; | 45 | struct resource cfg; |
| 49 | struct resource io; | 46 | struct resource io; |
| 50 | struct resource mem; | 47 | struct resource mem; |
| 51 | struct pcie_port_info config; | 48 | struct resource busn; |
| 52 | int irq; | 49 | int irq; |
| 53 | u32 lanes; | 50 | u32 lanes; |
| 54 | struct pcie_host_ops *ops; | 51 | struct pcie_host_ops *ops; |
| @@ -73,7 +70,10 @@ struct pcie_host_ops { | |||
| 73 | void (*host_init)(struct pcie_port *pp); | 70 | void (*host_init)(struct pcie_port *pp); |
| 74 | void (*msi_set_irq)(struct pcie_port *pp, int irq); | 71 | void (*msi_set_irq)(struct pcie_port *pp, int irq); |
| 75 | void (*msi_clear_irq)(struct pcie_port *pp, int irq); | 72 | void (*msi_clear_irq)(struct pcie_port *pp, int irq); |
| 76 | u32 (*get_msi_data)(struct pcie_port *pp); | 73 | u32 (*get_msi_addr)(struct pcie_port *pp); |
| 74 | u32 (*get_msi_data)(struct pcie_port *pp, int pos); | ||
| 75 | void (*scan_bus)(struct pcie_port *pp); | ||
| 76 | int (*msi_host_init)(struct pcie_port *pp, struct msi_chip *chip); | ||
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val); | 79 | int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val); |
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 4884ee5e07d4..61158e03ab5f 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c | |||
| @@ -323,6 +323,7 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie) | |||
| 323 | 323 | ||
| 324 | /* Setup PCIe address space mappings for each resource */ | 324 | /* Setup PCIe address space mappings for each resource */ |
| 325 | resource_size_t size; | 325 | resource_size_t size; |
| 326 | resource_size_t res_start; | ||
| 326 | u32 mask; | 327 | u32 mask; |
| 327 | 328 | ||
| 328 | rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win)); | 329 | rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win)); |
| @@ -335,8 +336,13 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie) | |||
| 335 | mask = (roundup_pow_of_two(size) / SZ_128) - 1; | 336 | mask = (roundup_pow_of_two(size) / SZ_128) - 1; |
| 336 | rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win)); | 337 | rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win)); |
| 337 | 338 | ||
| 338 | rcar_pci_write_reg(pcie, upper_32_bits(res->start), PCIEPARH(win)); | 339 | if (res->flags & IORESOURCE_IO) |
| 339 | rcar_pci_write_reg(pcie, lower_32_bits(res->start), PCIEPARL(win)); | 340 | res_start = pci_pio_to_address(res->start); |
| 341 | else | ||
| 342 | res_start = res->start; | ||
| 343 | |||
| 344 | rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPARH(win)); | ||
| 345 | rcar_pci_write_reg(pcie, lower_32_bits(res_start), PCIEPARL(win)); | ||
| 340 | 346 | ||
| 341 | /* First resource is for IO */ | 347 | /* First resource is for IO */ |
| 342 | mask = PAR_ENABLE; | 348 | mask = PAR_ENABLE; |
| @@ -363,9 +369,10 @@ static int rcar_pcie_setup(int nr, struct pci_sys_data *sys) | |||
| 363 | 369 | ||
| 364 | rcar_pcie_setup_window(i, pcie); | 370 | rcar_pcie_setup_window(i, pcie); |
| 365 | 371 | ||
| 366 | if (res->flags & IORESOURCE_IO) | 372 | if (res->flags & IORESOURCE_IO) { |
| 367 | pci_ioremap_io(nr * SZ_64K, res->start); | 373 | phys_addr_t io_start = pci_pio_to_address(res->start); |
| 368 | else | 374 | pci_ioremap_io(nr * SZ_64K, io_start); |
| 375 | } else | ||
| 369 | pci_add_resource(&sys->resources, res); | 376 | pci_add_resource(&sys->resources, res); |
| 370 | } | 377 | } |
| 371 | pci_add_resource(&sys->resources, &pcie->busn); | 378 | pci_add_resource(&sys->resources, &pcie->busn); |
| @@ -935,8 +942,10 @@ static int rcar_pcie_probe(struct platform_device *pdev) | |||
| 935 | } | 942 | } |
| 936 | 943 | ||
| 937 | for_each_of_pci_range(&parser, &range) { | 944 | for_each_of_pci_range(&parser, &range) { |
| 938 | of_pci_range_to_resource(&range, pdev->dev.of_node, | 945 | err = of_pci_range_to_resource(&range, pdev->dev.of_node, |
| 939 | &pcie->res[win++]); | 946 | &pcie->res[win++]); |
| 947 | if (err < 0) | ||
| 948 | return err; | ||
| 940 | 949 | ||
| 941 | if (win > RCAR_PCI_MAX_RESOURCES) | 950 | if (win > RCAR_PCI_MAX_RESOURCES) |
| 942 | break; | 951 | break; |
diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c index 6dea9e43a75c..85f594e1708f 100644 --- a/drivers/pci/host/pcie-spear13xx.c +++ b/drivers/pci/host/pcie-spear13xx.c | |||
| @@ -340,7 +340,7 @@ static int __init spear13xx_pcie_probe(struct platform_device *pdev) | |||
| 340 | 340 | ||
| 341 | pp->dev = dev; | 341 | pp->dev = dev; |
| 342 | 342 | ||
| 343 | dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 343 | dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); |
| 344 | pp->dbi_base = devm_ioremap_resource(dev, dbi_base); | 344 | pp->dbi_base = devm_ioremap_resource(dev, dbi_base); |
| 345 | if (IS_ERR(pp->dbi_base)) { | 345 | if (IS_ERR(pp->dbi_base)) { |
| 346 | dev_err(dev, "couldn't remap dbi base %p\n", dbi_base); | 346 | dev_err(dev, "couldn't remap dbi base %p\n", dbi_base); |
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c new file mode 100644 index 000000000000..ccc496b33a97 --- /dev/null +++ b/drivers/pci/host/pcie-xilinx.c | |||
| @@ -0,0 +1,970 @@ | |||
| 1 | /* | ||
| 2 | * PCIe host controller driver for Xilinx AXI PCIe Bridge | ||
| 3 | * | ||
| 4 | * Copyright (c) 2012 - 2014 Xilinx, Inc. | ||
| 5 | * | ||
| 6 | * Based on the Tegra PCIe driver | ||
| 7 | * | ||
| 8 | * Bits taken from Synopsys Designware Host controller driver and | ||
| 9 | * ARM PCI Host generic driver. | ||
| 10 | * | ||
| 11 | * This program is free software: you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License as published by | ||
| 13 | * the Free Software Foundation, either version 2 of the License, or | ||
| 14 | * (at your option) any later version. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/irq.h> | ||
| 19 | #include <linux/irqdomain.h> | ||
| 20 | #include <linux/kernel.h> | ||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/msi.h> | ||
| 23 | #include <linux/of_address.h> | ||
| 24 | #include <linux/of_pci.h> | ||
| 25 | #include <linux/of_platform.h> | ||
| 26 | #include <linux/of_irq.h> | ||
| 27 | #include <linux/pci.h> | ||
| 28 | #include <linux/platform_device.h> | ||
| 29 | |||
| 30 | /* Register definitions */ | ||
| 31 | #define XILINX_PCIE_REG_BIR 0x00000130 | ||
| 32 | #define XILINX_PCIE_REG_IDR 0x00000138 | ||
| 33 | #define XILINX_PCIE_REG_IMR 0x0000013c | ||
| 34 | #define XILINX_PCIE_REG_PSCR 0x00000144 | ||
| 35 | #define XILINX_PCIE_REG_RPSC 0x00000148 | ||
| 36 | #define XILINX_PCIE_REG_MSIBASE1 0x0000014c | ||
| 37 | #define XILINX_PCIE_REG_MSIBASE2 0x00000150 | ||
| 38 | #define XILINX_PCIE_REG_RPEFR 0x00000154 | ||
| 39 | #define XILINX_PCIE_REG_RPIFR1 0x00000158 | ||
| 40 | #define XILINX_PCIE_REG_RPIFR2 0x0000015c | ||
| 41 | |||
| 42 | /* Interrupt registers definitions */ | ||
| 43 | #define XILINX_PCIE_INTR_LINK_DOWN BIT(0) | ||
| 44 | #define XILINX_PCIE_INTR_ECRC_ERR BIT(1) | ||
| 45 | #define XILINX_PCIE_INTR_STR_ERR BIT(2) | ||
| 46 | #define XILINX_PCIE_INTR_HOT_RESET BIT(3) | ||
| 47 | #define XILINX_PCIE_INTR_CFG_TIMEOUT BIT(8) | ||
| 48 | #define XILINX_PCIE_INTR_CORRECTABLE BIT(9) | ||
| 49 | #define XILINX_PCIE_INTR_NONFATAL BIT(10) | ||
| 50 | #define XILINX_PCIE_INTR_FATAL BIT(11) | ||
| 51 | #define XILINX_PCIE_INTR_INTX BIT(16) | ||
| 52 | #define XILINX_PCIE_INTR_MSI BIT(17) | ||
| 53 | #define XILINX_PCIE_INTR_SLV_UNSUPP BIT(20) | ||
| 54 | #define XILINX_PCIE_INTR_SLV_UNEXP BIT(21) | ||
| 55 | #define XILINX_PCIE_INTR_SLV_COMPL BIT(22) | ||
| 56 | #define XILINX_PCIE_INTR_SLV_ERRP BIT(23) | ||
| 57 | #define XILINX_PCIE_INTR_SLV_CMPABT BIT(24) | ||
| 58 | #define XILINX_PCIE_INTR_SLV_ILLBUR BIT(25) | ||
| 59 | #define XILINX_PCIE_INTR_MST_DECERR BIT(26) | ||
| 60 | #define XILINX_PCIE_INTR_MST_SLVERR BIT(27) | ||
| 61 | #define XILINX_PCIE_INTR_MST_ERRP BIT(28) | ||
| 62 | #define XILINX_PCIE_IMR_ALL_MASK 0x1FF30FED | ||
| 63 | #define XILINX_PCIE_IDR_ALL_MASK 0xFFFFFFFF | ||
| 64 | |||
| 65 | /* Root Port Error FIFO Read Register definitions */ | ||
| 66 | #define XILINX_PCIE_RPEFR_ERR_VALID BIT(18) | ||
| 67 | #define XILINX_PCIE_RPEFR_REQ_ID GENMASK(15, 0) | ||
| 68 | #define XILINX_PCIE_RPEFR_ALL_MASK 0xFFFFFFFF | ||
| 69 | |||
| 70 | /* Root Port Interrupt FIFO Read Register 1 definitions */ | ||
| 71 | #define XILINX_PCIE_RPIFR1_INTR_VALID BIT(31) | ||
| 72 | #define XILINX_PCIE_RPIFR1_MSI_INTR BIT(30) | ||
| 73 | #define XILINX_PCIE_RPIFR1_INTR_MASK GENMASK(28, 27) | ||
| 74 | #define XILINX_PCIE_RPIFR1_ALL_MASK 0xFFFFFFFF | ||
| 75 | #define XILINX_PCIE_RPIFR1_INTR_SHIFT 27 | ||
| 76 | |||
| 77 | /* Bridge Info Register definitions */ | ||
| 78 | #define XILINX_PCIE_BIR_ECAM_SZ_MASK GENMASK(18, 16) | ||
| 79 | #define XILINX_PCIE_BIR_ECAM_SZ_SHIFT 16 | ||
| 80 | |||
| 81 | /* Root Port Interrupt FIFO Read Register 2 definitions */ | ||
| 82 | #define XILINX_PCIE_RPIFR2_MSG_DATA GENMASK(15, 0) | ||
| 83 | |||
| 84 | /* Root Port Status/control Register definitions */ | ||
| 85 | #define XILINX_PCIE_REG_RPSC_BEN BIT(0) | ||
| 86 | |||
| 87 | /* Phy Status/Control Register definitions */ | ||
| 88 | #define XILINX_PCIE_REG_PSCR_LNKUP BIT(11) | ||
| 89 | |||
| 90 | /* ECAM definitions */ | ||
| 91 | #define ECAM_BUS_NUM_SHIFT 20 | ||
| 92 | #define ECAM_DEV_NUM_SHIFT 12 | ||
| 93 | |||
| 94 | /* Number of MSI IRQs */ | ||
| 95 | #define XILINX_NUM_MSI_IRQS 128 | ||
| 96 | |||
| 97 | /* Number of Memory Resources */ | ||
| 98 | #define XILINX_MAX_NUM_RESOURCES 3 | ||
| 99 | |||
| 100 | /** | ||
| 101 | * struct xilinx_pcie_port - PCIe port information | ||
| 102 | * @reg_base: IO Mapped Register Base | ||
| 103 | * @irq: Interrupt number | ||
| 104 | * @msi_pages: MSI pages | ||
| 105 | * @root_busno: Root Bus number | ||
| 106 | * @dev: Device pointer | ||
| 107 | * @irq_domain: IRQ domain pointer | ||
| 108 | * @bus_range: Bus range | ||
| 109 | * @resources: Bus Resources | ||
| 110 | */ | ||
| 111 | struct xilinx_pcie_port { | ||
| 112 | void __iomem *reg_base; | ||
| 113 | u32 irq; | ||
| 114 | unsigned long msi_pages; | ||
| 115 | u8 root_busno; | ||
| 116 | struct device *dev; | ||
| 117 | struct irq_domain *irq_domain; | ||
| 118 | struct resource bus_range; | ||
| 119 | struct list_head resources; | ||
| 120 | }; | ||
| 121 | |||
| 122 | static DECLARE_BITMAP(msi_irq_in_use, XILINX_NUM_MSI_IRQS); | ||
| 123 | |||
| 124 | static inline struct xilinx_pcie_port *sys_to_pcie(struct pci_sys_data *sys) | ||
| 125 | { | ||
| 126 | return sys->private_data; | ||
| 127 | } | ||
| 128 | |||
| 129 | static inline u32 pcie_read(struct xilinx_pcie_port *port, u32 reg) | ||
| 130 | { | ||
| 131 | return readl(port->reg_base + reg); | ||
| 132 | } | ||
| 133 | |||
| 134 | static inline void pcie_write(struct xilinx_pcie_port *port, u32 val, u32 reg) | ||
| 135 | { | ||
| 136 | writel(val, port->reg_base + reg); | ||
| 137 | } | ||
| 138 | |||
| 139 | static inline bool xilinx_pcie_link_is_up(struct xilinx_pcie_port *port) | ||
| 140 | { | ||
| 141 | return (pcie_read(port, XILINX_PCIE_REG_PSCR) & | ||
| 142 | XILINX_PCIE_REG_PSCR_LNKUP) ? 1 : 0; | ||
| 143 | } | ||
| 144 | |||
| 145 | /** | ||
| 146 | * xilinx_pcie_clear_err_interrupts - Clear Error Interrupts | ||
| 147 | * @port: PCIe port information | ||
| 148 | */ | ||
| 149 | static void xilinx_pcie_clear_err_interrupts(struct xilinx_pcie_port *port) | ||
| 150 | { | ||
| 151 | u32 val = pcie_read(port, XILINX_PCIE_REG_RPEFR); | ||
| 152 | |||
| 153 | if (val & XILINX_PCIE_RPEFR_ERR_VALID) { | ||
| 154 | dev_dbg(port->dev, "Requester ID %d\n", | ||
| 155 | val & XILINX_PCIE_RPEFR_REQ_ID); | ||
| 156 | pcie_write(port, XILINX_PCIE_RPEFR_ALL_MASK, | ||
| 157 | XILINX_PCIE_REG_RPEFR); | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | /** | ||
| 162 | * xilinx_pcie_valid_device - Check if a valid device is present on bus | ||
| 163 | * @bus: PCI Bus structure | ||
| 164 | * @devfn: device/function | ||
| 165 | * | ||
| 166 | * Return: 'true' on success and 'false' if invalid device is found | ||
| 167 | */ | ||
| 168 | static bool xilinx_pcie_valid_device(struct pci_bus *bus, unsigned int devfn) | ||
| 169 | { | ||
| 170 | struct xilinx_pcie_port *port = sys_to_pcie(bus->sysdata); | ||
| 171 | |||
| 172 | /* Check if link is up when trying to access downstream ports */ | ||
| 173 | if (bus->number != port->root_busno) | ||
| 174 | if (!xilinx_pcie_link_is_up(port)) | ||
| 175 | return false; | ||
| 176 | |||
| 177 | /* Only one device down on each root port */ | ||
| 178 | if (bus->number == port->root_busno && devfn > 0) | ||
| 179 | return false; | ||
| 180 | |||
| 181 | /* | ||
| 182 | * Do not read more than one device on the bus directly attached | ||
| 183 | * to RC. | ||
| 184 | */ | ||
| 185 | if (bus->primary == port->root_busno && devfn > 0) | ||
| 186 | return false; | ||
| 187 | |||
| 188 | return true; | ||
| 189 | } | ||
| 190 | |||
| 191 | /** | ||
| 192 | * xilinx_pcie_config_base - Get configuration base | ||
| 193 | * @bus: PCI Bus structure | ||
| 194 | * @devfn: Device/function | ||
| 195 | * @where: Offset from base | ||
| 196 | * | ||
| 197 | * Return: Base address of the configuration space needed to be | ||
| 198 | * accessed. | ||
| 199 | */ | ||
| 200 | static void __iomem *xilinx_pcie_config_base(struct pci_bus *bus, | ||
| 201 | unsigned int devfn, int where) | ||
| 202 | { | ||
| 203 | struct xilinx_pcie_port *port = sys_to_pcie(bus->sysdata); | ||
| 204 | int relbus; | ||
| 205 | |||
| 206 | relbus = (bus->number << ECAM_BUS_NUM_SHIFT) | | ||
| 207 | (devfn << ECAM_DEV_NUM_SHIFT); | ||
| 208 | |||
| 209 | return port->reg_base + relbus + where; | ||
| 210 | } | ||
| 211 | |||
| 212 | /** | ||
| 213 | * xilinx_pcie_read_config - Read configuration space | ||
| 214 | * @bus: PCI Bus structure | ||
| 215 | * @devfn: Device/function | ||
| 216 | * @where: Offset from base | ||
| 217 | * @size: Byte/word/dword | ||
| 218 | * @val: Value to be read | ||
| 219 | * | ||
| 220 | * Return: PCIBIOS_SUCCESSFUL on success | ||
| 221 | * PCIBIOS_DEVICE_NOT_FOUND on failure | ||
| 222 | */ | ||
| 223 | static int xilinx_pcie_read_config(struct pci_bus *bus, unsigned int devfn, | ||
| 224 | int where, int size, u32 *val) | ||
| 225 | { | ||
| 226 | void __iomem *addr; | ||
| 227 | |||
| 228 | if (!xilinx_pcie_valid_device(bus, devfn)) { | ||
| 229 | *val = 0xFFFFFFFF; | ||
| 230 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 231 | } | ||
| 232 | |||
| 233 | addr = xilinx_pcie_config_base(bus, devfn, where); | ||
| 234 | |||
| 235 | switch (size) { | ||
| 236 | case 1: | ||
| 237 | *val = readb(addr); | ||
| 238 | break; | ||
| 239 | case 2: | ||
| 240 | *val = readw(addr); | ||
| 241 | break; | ||
| 242 | default: | ||
| 243 | *val = readl(addr); | ||
| 244 | break; | ||
| 245 | } | ||
| 246 | |||
| 247 | return PCIBIOS_SUCCESSFUL; | ||
| 248 | } | ||
| 249 | |||
| 250 | /** | ||
| 251 | * xilinx_pcie_write_config - Write configuration space | ||
| 252 | * @bus: PCI Bus structure | ||
| 253 | * @devfn: Device/function | ||
| 254 | * @where: Offset from base | ||
| 255 | * @size: Byte/word/dword | ||
| 256 | * @val: Value to be written to device | ||
| 257 | * | ||
| 258 | * Return: PCIBIOS_SUCCESSFUL on success | ||
| 259 | * PCIBIOS_DEVICE_NOT_FOUND on failure | ||
| 260 | */ | ||
| 261 | static int xilinx_pcie_write_config(struct pci_bus *bus, unsigned int devfn, | ||
| 262 | int where, int size, u32 val) | ||
| 263 | { | ||
| 264 | void __iomem *addr; | ||
| 265 | |||
| 266 | if (!xilinx_pcie_valid_device(bus, devfn)) | ||
| 267 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 268 | |||
| 269 | addr = xilinx_pcie_config_base(bus, devfn, where); | ||
| 270 | |||
| 271 | switch (size) { | ||
| 272 | case 1: | ||
| 273 | writeb(val, addr); | ||
| 274 | break; | ||
| 275 | case 2: | ||
| 276 | writew(val, addr); | ||
| 277 | break; | ||
| 278 | default: | ||
| 279 | writel(val, addr); | ||
| 280 | break; | ||
| 281 | } | ||
| 282 | |||
| 283 | return PCIBIOS_SUCCESSFUL; | ||
| 284 | } | ||
| 285 | |||
| 286 | /* PCIe operations */ | ||
| 287 | static struct pci_ops xilinx_pcie_ops = { | ||
| 288 | .read = xilinx_pcie_read_config, | ||
| 289 | .write = xilinx_pcie_write_config, | ||
| 290 | }; | ||
| 291 | |||
| 292 | /* MSI functions */ | ||
| 293 | |||
| 294 | /** | ||
| 295 | * xilinx_pcie_destroy_msi - Free MSI number | ||
| 296 | * @irq: IRQ to be freed | ||
| 297 | */ | ||
| 298 | static void xilinx_pcie_destroy_msi(unsigned int irq) | ||
| 299 | { | ||
| 300 | struct irq_desc *desc; | ||
| 301 | struct msi_desc *msi; | ||
| 302 | struct xilinx_pcie_port *port; | ||
| 303 | |||
| 304 | desc = irq_to_desc(irq); | ||
| 305 | msi = irq_desc_get_msi_desc(desc); | ||
| 306 | port = sys_to_pcie(msi->dev->bus->sysdata); | ||
| 307 | |||
| 308 | if (!test_bit(irq, msi_irq_in_use)) | ||
| 309 | dev_err(port->dev, "Trying to free unused MSI#%d\n", irq); | ||
| 310 | else | ||
| 311 | clear_bit(irq, msi_irq_in_use); | ||
| 312 | } | ||
| 313 | |||
| 314 | /** | ||
| 315 | * xilinx_pcie_assign_msi - Allocate MSI number | ||
| 316 | * @port: PCIe port structure | ||
| 317 | * | ||
| 318 | * Return: A valid IRQ on success and error value on failure. | ||
| 319 | */ | ||
| 320 | static int xilinx_pcie_assign_msi(struct xilinx_pcie_port *port) | ||
| 321 | { | ||
| 322 | int pos; | ||
| 323 | |||
| 324 | pos = find_first_zero_bit(msi_irq_in_use, XILINX_NUM_MSI_IRQS); | ||
| 325 | if (pos < XILINX_NUM_MSI_IRQS) | ||
| 326 | set_bit(pos, msi_irq_in_use); | ||
| 327 | else | ||
| 328 | return -ENOSPC; | ||
| 329 | |||
| 330 | return pos; | ||
| 331 | } | ||
| 332 | |||
| 333 | /** | ||
| 334 | * xilinx_msi_teardown_irq - Destroy the MSI | ||
| 335 | * @chip: MSI Chip descriptor | ||
| 336 | * @irq: MSI IRQ to destroy | ||
| 337 | */ | ||
| 338 | static void xilinx_msi_teardown_irq(struct msi_chip *chip, unsigned int irq) | ||
| 339 | { | ||
| 340 | xilinx_pcie_destroy_msi(irq); | ||
| 341 | } | ||
| 342 | |||
| 343 | /** | ||
| 344 | * xilinx_pcie_msi_setup_irq - Setup MSI request | ||
| 345 | * @chip: MSI chip pointer | ||
| 346 | * @pdev: PCIe device pointer | ||
| 347 | * @desc: MSI descriptor pointer | ||
| 348 | * | ||
| 349 | * Return: '0' on success and error value on failure | ||
| 350 | */ | ||
| 351 | static int xilinx_pcie_msi_setup_irq(struct msi_chip *chip, | ||
| 352 | struct pci_dev *pdev, | ||
| 353 | struct msi_desc *desc) | ||
| 354 | { | ||
| 355 | struct xilinx_pcie_port *port = sys_to_pcie(pdev->bus->sysdata); | ||
| 356 | unsigned int irq; | ||
| 357 | int hwirq; | ||
| 358 | struct msi_msg msg; | ||
| 359 | phys_addr_t msg_addr; | ||
| 360 | |||
| 361 | hwirq = xilinx_pcie_assign_msi(port); | ||
| 362 | if (hwirq < 0) | ||
| 363 | return hwirq; | ||
| 364 | |||
| 365 | irq = irq_create_mapping(port->irq_domain, hwirq); | ||
| 366 | if (!irq) | ||
| 367 | return -EINVAL; | ||
| 368 | |||
| 369 | irq_set_msi_desc(irq, desc); | ||
| 370 | |||
| 371 | msg_addr = virt_to_phys((void *)port->msi_pages); | ||
| 372 | |||
| 373 | msg.address_hi = 0; | ||
| 374 | msg.address_lo = msg_addr; | ||
| 375 | msg.data = irq; | ||
| 376 | |||
| 377 | write_msi_msg(irq, &msg); | ||
| 378 | |||
| 379 | return 0; | ||
| 380 | } | ||
| 381 | |||
| 382 | /* MSI Chip Descriptor */ | ||
| 383 | static struct msi_chip xilinx_pcie_msi_chip = { | ||
| 384 | .setup_irq = xilinx_pcie_msi_setup_irq, | ||
| 385 | .teardown_irq = xilinx_msi_teardown_irq, | ||
| 386 | }; | ||
| 387 | |||
| 388 | /* HW Interrupt Chip Descriptor */ | ||
| 389 | static struct irq_chip xilinx_msi_irq_chip = { | ||
| 390 | .name = "Xilinx PCIe MSI", | ||
| 391 | .irq_enable = unmask_msi_irq, | ||
| 392 | .irq_disable = mask_msi_irq, | ||
| 393 | .irq_mask = mask_msi_irq, | ||
| 394 | .irq_unmask = unmask_msi_irq, | ||
| 395 | }; | ||
| 396 | |||
| 397 | /** | ||
| 398 | * xilinx_pcie_msi_map - Set the handler for the MSI and mark IRQ as valid | ||
| 399 | * @domain: IRQ domain | ||
| 400 | * @irq: Virtual IRQ number | ||
| 401 | * @hwirq: HW interrupt number | ||
| 402 | * | ||
| 403 | * Return: Always returns 0. | ||
| 404 | */ | ||
| 405 | static int xilinx_pcie_msi_map(struct irq_domain *domain, unsigned int irq, | ||
| 406 | irq_hw_number_t hwirq) | ||
| 407 | { | ||
| 408 | irq_set_chip_and_handler(irq, &xilinx_msi_irq_chip, handle_simple_irq); | ||
| 409 | irq_set_chip_data(irq, domain->host_data); | ||
| 410 | set_irq_flags(irq, IRQF_VALID); | ||
| 411 | |||
| 412 | return 0; | ||
| 413 | } | ||
| 414 | |||
| 415 | /* IRQ Domain operations */ | ||
| 416 | static const struct irq_domain_ops msi_domain_ops = { | ||
| 417 | .map = xilinx_pcie_msi_map, | ||
| 418 | }; | ||
| 419 | |||
| 420 | /** | ||
| 421 | * xilinx_pcie_enable_msi - Enable MSI support | ||
| 422 | * @port: PCIe port information | ||
| 423 | */ | ||
| 424 | static void xilinx_pcie_enable_msi(struct xilinx_pcie_port *port) | ||
| 425 | { | ||
| 426 | phys_addr_t msg_addr; | ||
| 427 | |||
| 428 | port->msi_pages = __get_free_pages(GFP_KERNEL, 0); | ||
| 429 | msg_addr = virt_to_phys((void *)port->msi_pages); | ||
| 430 | pcie_write(port, 0x0, XILINX_PCIE_REG_MSIBASE1); | ||
| 431 | pcie_write(port, msg_addr, XILINX_PCIE_REG_MSIBASE2); | ||
| 432 | } | ||
| 433 | |||
| 434 | /** | ||
| 435 | * xilinx_pcie_add_bus - Add MSI chip info to PCIe bus | ||
| 436 | * @bus: PCIe bus | ||
| 437 | */ | ||
| 438 | static void xilinx_pcie_add_bus(struct pci_bus *bus) | ||
| 439 | { | ||
| 440 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | ||
| 441 | struct xilinx_pcie_port *port = sys_to_pcie(bus->sysdata); | ||
| 442 | |||
| 443 | xilinx_pcie_msi_chip.dev = port->dev; | ||
| 444 | bus->msi = &xilinx_pcie_msi_chip; | ||
| 445 | } | ||
| 446 | } | ||
| 447 | |||
| 448 | /* INTx Functions */ | ||
| 449 | |||
| 450 | /** | ||
| 451 | * xilinx_pcie_intx_map - Set the handler for the INTx and mark IRQ as valid | ||
| 452 | * @domain: IRQ domain | ||
| 453 | * @irq: Virtual IRQ number | ||
| 454 | * @hwirq: HW interrupt number | ||
| 455 | * | ||
| 456 | * Return: Always returns 0. | ||
| 457 | */ | ||
| 458 | static int xilinx_pcie_intx_map(struct irq_domain *domain, unsigned int irq, | ||
| 459 | irq_hw_number_t hwirq) | ||
| 460 | { | ||
| 461 | irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq); | ||
| 462 | irq_set_chip_data(irq, domain->host_data); | ||
| 463 | set_irq_flags(irq, IRQF_VALID); | ||
| 464 | |||
| 465 | return 0; | ||
| 466 | } | ||
| 467 | |||
| 468 | /* INTx IRQ Domain operations */ | ||
| 469 | static const struct irq_domain_ops intx_domain_ops = { | ||
| 470 | .map = xilinx_pcie_intx_map, | ||
| 471 | }; | ||
| 472 | |||
| 473 | /* PCIe HW Functions */ | ||
| 474 | |||
| 475 | /** | ||
| 476 | * xilinx_pcie_intr_handler - Interrupt Service Handler | ||
| 477 | * @irq: IRQ number | ||
| 478 | * @data: PCIe port information | ||
| 479 | * | ||
| 480 | * Return: IRQ_HANDLED on success and IRQ_NONE on failure | ||
| 481 | */ | ||
| 482 | static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data) | ||
| 483 | { | ||
| 484 | struct xilinx_pcie_port *port = (struct xilinx_pcie_port *)data; | ||
| 485 | u32 val, mask, status, msi_data; | ||
| 486 | |||
| 487 | /* Read interrupt decode and mask registers */ | ||
| 488 | val = pcie_read(port, XILINX_PCIE_REG_IDR); | ||
| 489 | mask = pcie_read(port, XILINX_PCIE_REG_IMR); | ||
| 490 | |||
| 491 | status = val & mask; | ||
| 492 | if (!status) | ||
| 493 | return IRQ_NONE; | ||
| 494 | |||
| 495 | if (status & XILINX_PCIE_INTR_LINK_DOWN) | ||
| 496 | dev_warn(port->dev, "Link Down\n"); | ||
| 497 | |||
| 498 | if (status & XILINX_PCIE_INTR_ECRC_ERR) | ||
| 499 | dev_warn(port->dev, "ECRC failed\n"); | ||
| 500 | |||
| 501 | if (status & XILINX_PCIE_INTR_STR_ERR) | ||
| 502 | dev_warn(port->dev, "Streaming error\n"); | ||
| 503 | |||
| 504 | if (status & XILINX_PCIE_INTR_HOT_RESET) | ||
| 505 | dev_info(port->dev, "Hot reset\n"); | ||
| 506 | |||
| 507 | if (status & XILINX_PCIE_INTR_CFG_TIMEOUT) | ||
| 508 | dev_warn(port->dev, "ECAM access timeout\n"); | ||
| 509 | |||
| 510 | if (status & XILINX_PCIE_INTR_CORRECTABLE) { | ||
| 511 | dev_warn(port->dev, "Correctable error message\n"); | ||
| 512 | xilinx_pcie_clear_err_interrupts(port); | ||
| 513 | } | ||
| 514 | |||
| 515 | if (status & XILINX_PCIE_INTR_NONFATAL) { | ||
| 516 | dev_warn(port->dev, "Non fatal error message\n"); | ||
| 517 | xilinx_pcie_clear_err_interrupts(port); | ||
| 518 | } | ||
| 519 | |||
| 520 | if (status & XILINX_PCIE_INTR_FATAL) { | ||
| 521 | dev_warn(port->dev, "Fatal error message\n"); | ||
| 522 | xilinx_pcie_clear_err_interrupts(port); | ||
| 523 | } | ||
| 524 | |||
| 525 | if (status & XILINX_PCIE_INTR_INTX) { | ||
| 526 | /* INTx interrupt received */ | ||
| 527 | val = pcie_read(port, XILINX_PCIE_REG_RPIFR1); | ||
| 528 | |||
| 529 | /* Check whether interrupt valid */ | ||
| 530 | if (!(val & XILINX_PCIE_RPIFR1_INTR_VALID)) { | ||
| 531 | dev_warn(port->dev, "RP Intr FIFO1 read error\n"); | ||
| 532 | return IRQ_HANDLED; | ||
| 533 | } | ||
| 534 | |||
| 535 | /* Clear interrupt FIFO register 1 */ | ||
| 536 | pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK, | ||
| 537 | XILINX_PCIE_REG_RPIFR1); | ||
| 538 | |||
| 539 | /* Handle INTx Interrupt */ | ||
| 540 | val = ((val & XILINX_PCIE_RPIFR1_INTR_MASK) >> | ||
| 541 | XILINX_PCIE_RPIFR1_INTR_SHIFT) + 1; | ||
| 542 | generic_handle_irq(irq_find_mapping(port->irq_domain, val)); | ||
| 543 | } | ||
| 544 | |||
| 545 | if (status & XILINX_PCIE_INTR_MSI) { | ||
| 546 | /* MSI Interrupt */ | ||
| 547 | val = pcie_read(port, XILINX_PCIE_REG_RPIFR1); | ||
| 548 | |||
| 549 | if (!(val & XILINX_PCIE_RPIFR1_INTR_VALID)) { | ||
| 550 | dev_warn(port->dev, "RP Intr FIFO1 read error\n"); | ||
| 551 | return IRQ_HANDLED; | ||
| 552 | } | ||
| 553 | |||
| 554 | if (val & XILINX_PCIE_RPIFR1_MSI_INTR) { | ||
| 555 | msi_data = pcie_read(port, XILINX_PCIE_REG_RPIFR2) & | ||
| 556 | XILINX_PCIE_RPIFR2_MSG_DATA; | ||
| 557 | |||
| 558 | /* Clear interrupt FIFO register 1 */ | ||
| 559 | pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK, | ||
| 560 | XILINX_PCIE_REG_RPIFR1); | ||
| 561 | |||
| 562 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | ||
| 563 | /* Handle MSI Interrupt */ | ||
| 564 | generic_handle_irq(msi_data); | ||
| 565 | } | ||
| 566 | } | ||
| 567 | } | ||
| 568 | |||
| 569 | if (status & XILINX_PCIE_INTR_SLV_UNSUPP) | ||
| 570 | dev_warn(port->dev, "Slave unsupported request\n"); | ||
| 571 | |||
| 572 | if (status & XILINX_PCIE_INTR_SLV_UNEXP) | ||
| 573 | dev_warn(port->dev, "Slave unexpected completion\n"); | ||
| 574 | |||
| 575 | if (status & XILINX_PCIE_INTR_SLV_COMPL) | ||
| 576 | dev_warn(port->dev, "Slave completion timeout\n"); | ||
| 577 | |||
| 578 | if (status & XILINX_PCIE_INTR_SLV_ERRP) | ||
| 579 | dev_warn(port->dev, "Slave Error Poison\n"); | ||
| 580 | |||
| 581 | if (status & XILINX_PCIE_INTR_SLV_CMPABT) | ||
| 582 | dev_warn(port->dev, "Slave Completer Abort\n"); | ||
| 583 | |||
| 584 | if (status & XILINX_PCIE_INTR_SLV_ILLBUR) | ||
| 585 | dev_warn(port->dev, "Slave Illegal Burst\n"); | ||
| 586 | |||
| 587 | if (status & XILINX_PCIE_INTR_MST_DECERR) | ||
| 588 | dev_warn(port->dev, "Master decode error\n"); | ||
| 589 | |||
| 590 | if (status & XILINX_PCIE_INTR_MST_SLVERR) | ||
| 591 | dev_warn(port->dev, "Master slave error\n"); | ||
| 592 | |||
| 593 | if (status & XILINX_PCIE_INTR_MST_ERRP) | ||
| 594 | dev_warn(port->dev, "Master error poison\n"); | ||
| 595 | |||
| 596 | /* Clear the Interrupt Decode register */ | ||
| 597 | pcie_write(port, status, XILINX_PCIE_REG_IDR); | ||
| 598 | |||
| 599 | return IRQ_HANDLED; | ||
| 600 | } | ||
| 601 | |||
| 602 | /** | ||
| 603 | * xilinx_pcie_free_irq_domain - Free IRQ domain | ||
| 604 | * @port: PCIe port information | ||
| 605 | */ | ||
| 606 | static void xilinx_pcie_free_irq_domain(struct xilinx_pcie_port *port) | ||
| 607 | { | ||
| 608 | int i; | ||
| 609 | u32 irq, num_irqs; | ||
| 610 | |||
| 611 | /* Free IRQ Domain */ | ||
| 612 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | ||
| 613 | |||
| 614 | free_pages(port->msi_pages, 0); | ||
| 615 | |||
| 616 | num_irqs = XILINX_NUM_MSI_IRQS; | ||
| 617 | } else { | ||
| 618 | /* INTx */ | ||
| 619 | num_irqs = 4; | ||
| 620 | } | ||
| 621 | |||
| 622 | for (i = 0; i < num_irqs; i++) { | ||
| 623 | irq = irq_find_mapping(port->irq_domain, i); | ||
| 624 | if (irq > 0) | ||
| 625 | irq_dispose_mapping(irq); | ||
| 626 | } | ||
| 627 | |||
| 628 | irq_domain_remove(port->irq_domain); | ||
| 629 | } | ||
| 630 | |||
| 631 | /** | ||
| 632 | * xilinx_pcie_init_irq_domain - Initialize IRQ domain | ||
| 633 | * @port: PCIe port information | ||
| 634 | * | ||
| 635 | * Return: '0' on success and error value on failure | ||
| 636 | */ | ||
| 637 | static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port) | ||
| 638 | { | ||
| 639 | struct device *dev = port->dev; | ||
| 640 | struct device_node *node = dev->of_node; | ||
| 641 | struct device_node *pcie_intc_node; | ||
| 642 | |||
| 643 | /* Setup INTx */ | ||
| 644 | pcie_intc_node = of_get_next_child(node, NULL); | ||
| 645 | if (!pcie_intc_node) { | ||
| 646 | dev_err(dev, "No PCIe Intc node found\n"); | ||
| 647 | return PTR_ERR(pcie_intc_node); | ||
| 648 | } | ||
| 649 | |||
| 650 | port->irq_domain = irq_domain_add_linear(pcie_intc_node, 4, | ||
| 651 | &intx_domain_ops, | ||
| 652 | port); | ||
| 653 | if (!port->irq_domain) { | ||
| 654 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); | ||
| 655 | return PTR_ERR(port->irq_domain); | ||
| 656 | } | ||
| 657 | |||
| 658 | /* Setup MSI */ | ||
| 659 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | ||
| 660 | port->irq_domain = irq_domain_add_linear(node, | ||
| 661 | XILINX_NUM_MSI_IRQS, | ||
| 662 | &msi_domain_ops, | ||
| 663 | &xilinx_pcie_msi_chip); | ||
| 664 | if (!port->irq_domain) { | ||
| 665 | dev_err(dev, "Failed to get a MSI IRQ domain\n"); | ||
| 666 | return PTR_ERR(port->irq_domain); | ||
| 667 | } | ||
| 668 | |||
| 669 | xilinx_pcie_enable_msi(port); | ||
| 670 | } | ||
| 671 | |||
| 672 | return 0; | ||
| 673 | } | ||
| 674 | |||
| 675 | /** | ||
| 676 | * xilinx_pcie_init_port - Initialize hardware | ||
| 677 | * @port: PCIe port information | ||
| 678 | */ | ||
| 679 | static void xilinx_pcie_init_port(struct xilinx_pcie_port *port) | ||
| 680 | { | ||
| 681 | if (xilinx_pcie_link_is_up(port)) | ||
| 682 | dev_info(port->dev, "PCIe Link is UP\n"); | ||
| 683 | else | ||
| 684 | dev_info(port->dev, "PCIe Link is DOWN\n"); | ||
| 685 | |||
| 686 | /* Disable all interrupts */ | ||
| 687 | pcie_write(port, ~XILINX_PCIE_IDR_ALL_MASK, | ||
| 688 | XILINX_PCIE_REG_IMR); | ||
| 689 | |||
| 690 | /* Clear pending interrupts */ | ||
| 691 | pcie_write(port, pcie_read(port, XILINX_PCIE_REG_IDR) & | ||
| 692 | XILINX_PCIE_IMR_ALL_MASK, | ||
| 693 | XILINX_PCIE_REG_IDR); | ||
| 694 | |||
| 695 | /* Enable all interrupts */ | ||
| 696 | pcie_write(port, XILINX_PCIE_IMR_ALL_MASK, XILINX_PCIE_REG_IMR); | ||
| 697 | |||
| 698 | /* Enable the Bridge enable bit */ | ||
| 699 | pcie_write(port, pcie_read(port, XILINX_PCIE_REG_RPSC) | | ||
| 700 | XILINX_PCIE_REG_RPSC_BEN, | ||
| 701 | XILINX_PCIE_REG_RPSC); | ||
| 702 | } | ||
| 703 | |||
| 704 | /** | ||
| 705 | * xilinx_pcie_setup - Setup memory resources | ||
| 706 | * @nr: Bus number | ||
| 707 | * @sys: Per controller structure | ||
| 708 | * | ||
| 709 | * Return: '1' on success and error value on failure | ||
| 710 | */ | ||
| 711 | static int xilinx_pcie_setup(int nr, struct pci_sys_data *sys) | ||
| 712 | { | ||
| 713 | struct xilinx_pcie_port *port = sys_to_pcie(sys); | ||
| 714 | |||
| 715 | list_splice_init(&port->resources, &sys->resources); | ||
| 716 | |||
| 717 | return 1; | ||
| 718 | } | ||
| 719 | |||
| 720 | /** | ||
| 721 | * xilinx_pcie_scan_bus - Scan PCIe bus for devices | ||
| 722 | * @nr: Bus number | ||
| 723 | * @sys: Per controller structure | ||
| 724 | * | ||
| 725 | * Return: Valid Bus pointer on success and NULL on failure | ||
| 726 | */ | ||
| 727 | static struct pci_bus *xilinx_pcie_scan_bus(int nr, struct pci_sys_data *sys) | ||
| 728 | { | ||
| 729 | struct xilinx_pcie_port *port = sys_to_pcie(sys); | ||
| 730 | struct pci_bus *bus; | ||
| 731 | |||
| 732 | port->root_busno = sys->busnr; | ||
| 733 | bus = pci_scan_root_bus(port->dev, sys->busnr, &xilinx_pcie_ops, | ||
| 734 | sys, &sys->resources); | ||
| 735 | |||
| 736 | return bus; | ||
| 737 | } | ||
| 738 | |||
| 739 | /** | ||
| 740 | * xilinx_pcie_parse_and_add_res - Add resources by parsing ranges | ||
| 741 | * @port: PCIe port information | ||
| 742 | * | ||
| 743 | * Return: '0' on success and error value on failure | ||
| 744 | */ | ||
| 745 | static int xilinx_pcie_parse_and_add_res(struct xilinx_pcie_port *port) | ||
| 746 | { | ||
| 747 | struct device *dev = port->dev; | ||
| 748 | struct device_node *node = dev->of_node; | ||
| 749 | struct resource *mem; | ||
| 750 | resource_size_t offset; | ||
| 751 | struct of_pci_range_parser parser; | ||
| 752 | struct of_pci_range range; | ||
| 753 | struct pci_host_bridge_window *win; | ||
| 754 | int err = 0, mem_resno = 0; | ||
| 755 | |||
| 756 | /* Get the ranges */ | ||
| 757 | if (of_pci_range_parser_init(&parser, node)) { | ||
| 758 | dev_err(dev, "missing \"ranges\" property\n"); | ||
| 759 | return -EINVAL; | ||
| 760 | } | ||
| 761 | |||
| 762 | /* Parse the ranges and add the resources found to the list */ | ||
| 763 | for_each_of_pci_range(&parser, &range) { | ||
| 764 | |||
| 765 | if (mem_resno >= XILINX_MAX_NUM_RESOURCES) { | ||
| 766 | dev_err(dev, "Maximum memory resources exceeded\n"); | ||
| 767 | return -EINVAL; | ||
| 768 | } | ||
| 769 | |||
| 770 | mem = devm_kmalloc(dev, sizeof(*mem), GFP_KERNEL); | ||
| 771 | if (!mem) { | ||
| 772 | err = -ENOMEM; | ||
| 773 | goto free_resources; | ||
| 774 | } | ||
| 775 | |||
| 776 | of_pci_range_to_resource(&range, node, mem); | ||
| 777 | |||
| 778 | switch (mem->flags & IORESOURCE_TYPE_BITS) { | ||
| 779 | case IORESOURCE_MEM: | ||
| 780 | offset = range.cpu_addr - range.pci_addr; | ||
| 781 | mem_resno++; | ||
| 782 | break; | ||
| 783 | default: | ||
| 784 | err = -EINVAL; | ||
| 785 | break; | ||
| 786 | } | ||
| 787 | |||
| 788 | if (err < 0) { | ||
| 789 | dev_warn(dev, "Invalid resource found %pR\n", mem); | ||
| 790 | continue; | ||
| 791 | } | ||
| 792 | |||
| 793 | err = request_resource(&iomem_resource, mem); | ||
| 794 | if (err) | ||
| 795 | goto free_resources; | ||
| 796 | |||
| 797 | pci_add_resource_offset(&port->resources, mem, offset); | ||
| 798 | } | ||
| 799 | |||
| 800 | /* Get the bus range */ | ||
| 801 | if (of_pci_parse_bus_range(node, &port->bus_range)) { | ||
| 802 | u32 val = pcie_read(port, XILINX_PCIE_REG_BIR); | ||
| 803 | u8 last; | ||
| 804 | |||
| 805 | last = (val & XILINX_PCIE_BIR_ECAM_SZ_MASK) >> | ||
| 806 | XILINX_PCIE_BIR_ECAM_SZ_SHIFT; | ||
| 807 | |||
| 808 | port->bus_range = (struct resource) { | ||
| 809 | .name = node->name, | ||
| 810 | .start = 0, | ||
| 811 | .end = last, | ||
| 812 | .flags = IORESOURCE_BUS, | ||
| 813 | }; | ||
| 814 | } | ||
| 815 | |||
| 816 | /* Register bus resource */ | ||
| 817 | pci_add_resource(&port->resources, &port->bus_range); | ||
| 818 | |||
| 819 | return 0; | ||
| 820 | |||
| 821 | free_resources: | ||
| 822 | release_child_resources(&iomem_resource); | ||
| 823 | list_for_each_entry(win, &port->resources, list) | ||
| 824 | devm_kfree(dev, win->res); | ||
| 825 | pci_free_resource_list(&port->resources); | ||
| 826 | |||
| 827 | return err; | ||
| 828 | } | ||
| 829 | |||
| 830 | /** | ||
| 831 | * xilinx_pcie_parse_dt - Parse Device tree | ||
| 832 | * @port: PCIe port information | ||
| 833 | * | ||
| 834 | * Return: '0' on success and error value on failure | ||
| 835 | */ | ||
| 836 | static int xilinx_pcie_parse_dt(struct xilinx_pcie_port *port) | ||
| 837 | { | ||
| 838 | struct device *dev = port->dev; | ||
| 839 | struct device_node *node = dev->of_node; | ||
| 840 | struct resource regs; | ||
| 841 | const char *type; | ||
| 842 | int err; | ||
| 843 | |||
| 844 | type = of_get_property(node, "device_type", NULL); | ||
| 845 | if (!type || strcmp(type, "pci")) { | ||
| 846 | dev_err(dev, "invalid \"device_type\" %s\n", type); | ||
| 847 | return -EINVAL; | ||
| 848 | } | ||
| 849 | |||
| 850 | err = of_address_to_resource(node, 0, ®s); | ||
| 851 | if (err) { | ||
| 852 | dev_err(dev, "missing \"reg\" property\n"); | ||
| 853 | return err; | ||
| 854 | } | ||
| 855 | |||
| 856 | port->reg_base = devm_ioremap_resource(dev, ®s); | ||
| 857 | if (IS_ERR(port->reg_base)) | ||
| 858 | return PTR_ERR(port->reg_base); | ||
| 859 | |||
| 860 | port->irq = irq_of_parse_and_map(node, 0); | ||
| 861 | err = devm_request_irq(dev, port->irq, xilinx_pcie_intr_handler, | ||
| 862 | IRQF_SHARED, "xilinx-pcie", port); | ||
| 863 | if (err) { | ||
| 864 | dev_err(dev, "unable to request irq %d\n", port->irq); | ||
| 865 | return err; | ||
| 866 | } | ||
| 867 | |||
| 868 | return 0; | ||
| 869 | } | ||
| 870 | |||
| 871 | /** | ||
| 872 | * xilinx_pcie_probe - Probe function | ||
| 873 | * @pdev: Platform device pointer | ||
| 874 | * | ||
| 875 | * Return: '0' on success and error value on failure | ||
| 876 | */ | ||
| 877 | static int xilinx_pcie_probe(struct platform_device *pdev) | ||
| 878 | { | ||
| 879 | struct xilinx_pcie_port *port; | ||
| 880 | struct hw_pci hw; | ||
| 881 | struct device *dev = &pdev->dev; | ||
| 882 | int err; | ||
| 883 | |||
| 884 | if (!dev->of_node) | ||
| 885 | return -ENODEV; | ||
| 886 | |||
| 887 | port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); | ||
| 888 | if (!port) | ||
| 889 | return -ENOMEM; | ||
| 890 | |||
| 891 | port->dev = dev; | ||
| 892 | |||
| 893 | err = xilinx_pcie_parse_dt(port); | ||
| 894 | if (err) { | ||
| 895 | dev_err(dev, "Parsing DT failed\n"); | ||
| 896 | return err; | ||
| 897 | } | ||
| 898 | |||
| 899 | xilinx_pcie_init_port(port); | ||
| 900 | |||
| 901 | err = xilinx_pcie_init_irq_domain(port); | ||
| 902 | if (err) { | ||
| 903 | dev_err(dev, "Failed creating IRQ Domain\n"); | ||
| 904 | return err; | ||
| 905 | } | ||
| 906 | |||
| 907 | /* | ||
| 908 | * Parse PCI ranges, configuration bus range and | ||
| 909 | * request their resources | ||
| 910 | */ | ||
| 911 | INIT_LIST_HEAD(&port->resources); | ||
| 912 | err = xilinx_pcie_parse_and_add_res(port); | ||
| 913 | if (err) { | ||
| 914 | dev_err(dev, "Failed adding resources\n"); | ||
| 915 | return err; | ||
| 916 | } | ||
| 917 | |||
| 918 | platform_set_drvdata(pdev, port); | ||
| 919 | |||
| 920 | /* Register the device */ | ||
| 921 | memset(&hw, 0, sizeof(hw)); | ||
| 922 | hw = (struct hw_pci) { | ||
| 923 | .nr_controllers = 1, | ||
| 924 | .private_data = (void **)&port, | ||
| 925 | .setup = xilinx_pcie_setup, | ||
| 926 | .map_irq = of_irq_parse_and_map_pci, | ||
| 927 | .add_bus = xilinx_pcie_add_bus, | ||
| 928 | .scan = xilinx_pcie_scan_bus, | ||
| 929 | .ops = &xilinx_pcie_ops, | ||
| 930 | }; | ||
| 931 | pci_common_init_dev(dev, &hw); | ||
| 932 | |||
| 933 | return 0; | ||
| 934 | } | ||
| 935 | |||
| 936 | /** | ||
| 937 | * xilinx_pcie_remove - Remove function | ||
| 938 | * @pdev: Platform device pointer | ||
| 939 | * | ||
| 940 | * Return: '0' always | ||
| 941 | */ | ||
| 942 | static int xilinx_pcie_remove(struct platform_device *pdev) | ||
| 943 | { | ||
| 944 | struct xilinx_pcie_port *port = platform_get_drvdata(pdev); | ||
| 945 | |||
| 946 | xilinx_pcie_free_irq_domain(port); | ||
| 947 | |||
| 948 | return 0; | ||
| 949 | } | ||
| 950 | |||
| 951 | static struct of_device_id xilinx_pcie_of_match[] = { | ||
| 952 | { .compatible = "xlnx,axi-pcie-host-1.00.a", }, | ||
| 953 | {} | ||
| 954 | }; | ||
| 955 | |||
| 956 | static struct platform_driver xilinx_pcie_driver = { | ||
| 957 | .driver = { | ||
| 958 | .name = "xilinx-pcie", | ||
| 959 | .owner = THIS_MODULE, | ||
| 960 | .of_match_table = xilinx_pcie_of_match, | ||
| 961 | .suppress_bind_attrs = true, | ||
| 962 | }, | ||
| 963 | .probe = xilinx_pcie_probe, | ||
| 964 | .remove = xilinx_pcie_remove, | ||
| 965 | }; | ||
| 966 | module_platform_driver(xilinx_pcie_driver); | ||
| 967 | |||
| 968 | MODULE_AUTHOR("Xilinx Inc"); | ||
| 969 | MODULE_DESCRIPTION("Xilinx AXI PCIe driver"); | ||
| 970 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile index 3e6532b945c1..4a9aa08b08f1 100644 --- a/drivers/pci/hotplug/Makefile +++ b/drivers/pci/hotplug/Makefile | |||
| @@ -24,7 +24,7 @@ obj-$(CONFIG_HOTPLUG_PCI_S390) += s390_pci_hpc.o | |||
| 24 | 24 | ||
| 25 | obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o | 25 | obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o |
| 26 | 26 | ||
| 27 | pci_hotplug-objs := pci_hotplug_core.o pcihp_slot.o | 27 | pci_hotplug-objs := pci_hotplug_core.o |
| 28 | 28 | ||
| 29 | ifdef CONFIG_HOTPLUG_PCI_CPCI | 29 | ifdef CONFIG_HOTPLUG_PCI_CPCI |
| 30 | pci_hotplug-objs += cpci_hotplug_core.o \ | 30 | pci_hotplug-objs += cpci_hotplug_core.o \ |
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index a94d850ae228..876ccc620440 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c | |||
| @@ -46,215 +46,6 @@ | |||
| 46 | 46 | ||
| 47 | static bool debug_acpi; | 47 | static bool debug_acpi; |
| 48 | 48 | ||
| 49 | static acpi_status | ||
| 50 | decode_type0_hpx_record(union acpi_object *record, struct hotplug_params *hpx) | ||
| 51 | { | ||
| 52 | int i; | ||
| 53 | union acpi_object *fields = record->package.elements; | ||
| 54 | u32 revision = fields[1].integer.value; | ||
| 55 | |||
| 56 | switch (revision) { | ||
| 57 | case 1: | ||
| 58 | if (record->package.count != 6) | ||
| 59 | return AE_ERROR; | ||
| 60 | for (i = 2; i < 6; i++) | ||
| 61 | if (fields[i].type != ACPI_TYPE_INTEGER) | ||
| 62 | return AE_ERROR; | ||
| 63 | hpx->t0 = &hpx->type0_data; | ||
| 64 | hpx->t0->revision = revision; | ||
| 65 | hpx->t0->cache_line_size = fields[2].integer.value; | ||
| 66 | hpx->t0->latency_timer = fields[3].integer.value; | ||
| 67 | hpx->t0->enable_serr = fields[4].integer.value; | ||
| 68 | hpx->t0->enable_perr = fields[5].integer.value; | ||
| 69 | break; | ||
| 70 | default: | ||
| 71 | printk(KERN_WARNING | ||
| 72 | "%s: Type 0 Revision %d record not supported\n", | ||
| 73 | __func__, revision); | ||
| 74 | return AE_ERROR; | ||
| 75 | } | ||
| 76 | return AE_OK; | ||
| 77 | } | ||
| 78 | |||
| 79 | static acpi_status | ||
| 80 | decode_type1_hpx_record(union acpi_object *record, struct hotplug_params *hpx) | ||
| 81 | { | ||
| 82 | int i; | ||
| 83 | union acpi_object *fields = record->package.elements; | ||
| 84 | u32 revision = fields[1].integer.value; | ||
| 85 | |||
| 86 | switch (revision) { | ||
| 87 | case 1: | ||
| 88 | if (record->package.count != 5) | ||
| 89 | return AE_ERROR; | ||
| 90 | for (i = 2; i < 5; i++) | ||
| 91 | if (fields[i].type != ACPI_TYPE_INTEGER) | ||
| 92 | return AE_ERROR; | ||
| 93 | hpx->t1 = &hpx->type1_data; | ||
| 94 | hpx->t1->revision = revision; | ||
| 95 | hpx->t1->max_mem_read = fields[2].integer.value; | ||
| 96 | hpx->t1->avg_max_split = fields[3].integer.value; | ||
| 97 | hpx->t1->tot_max_split = fields[4].integer.value; | ||
| 98 | break; | ||
| 99 | default: | ||
| 100 | printk(KERN_WARNING | ||
| 101 | "%s: Type 1 Revision %d record not supported\n", | ||
| 102 | __func__, revision); | ||
| 103 | return AE_ERROR; | ||
| 104 | } | ||
| 105 | return AE_OK; | ||
| 106 | } | ||
| 107 | |||
| 108 | static acpi_status | ||
| 109 | decode_type2_hpx_record(union acpi_object *record, struct hotplug_params *hpx) | ||
| 110 | { | ||
| 111 | int i; | ||
| 112 | union acpi_object *fields = record->package.elements; | ||
| 113 | u32 revision = fields[1].integer.value; | ||
| 114 | |||
| 115 | switch (revision) { | ||
| 116 | case 1: | ||
| 117 | if (record->package.count != 18) | ||
| 118 | return AE_ERROR; | ||
| 119 | for (i = 2; i < 18; i++) | ||
| 120 | if (fields[i].type != ACPI_TYPE_INTEGER) | ||
| 121 | return AE_ERROR; | ||
| 122 | hpx->t2 = &hpx->type2_data; | ||
| 123 | hpx->t2->revision = revision; | ||
| 124 | hpx->t2->unc_err_mask_and = fields[2].integer.value; | ||
| 125 | hpx->t2->unc_err_mask_or = fields[3].integer.value; | ||
| 126 | hpx->t2->unc_err_sever_and = fields[4].integer.value; | ||
| 127 | hpx->t2->unc_err_sever_or = fields[5].integer.value; | ||
| 128 | hpx->t2->cor_err_mask_and = fields[6].integer.value; | ||
| 129 | hpx->t2->cor_err_mask_or = fields[7].integer.value; | ||
| 130 | hpx->t2->adv_err_cap_and = fields[8].integer.value; | ||
| 131 | hpx->t2->adv_err_cap_or = fields[9].integer.value; | ||
| 132 | hpx->t2->pci_exp_devctl_and = fields[10].integer.value; | ||
| 133 | hpx->t2->pci_exp_devctl_or = fields[11].integer.value; | ||
| 134 | hpx->t2->pci_exp_lnkctl_and = fields[12].integer.value; | ||
| 135 | hpx->t2->pci_exp_lnkctl_or = fields[13].integer.value; | ||
| 136 | hpx->t2->sec_unc_err_sever_and = fields[14].integer.value; | ||
| 137 | hpx->t2->sec_unc_err_sever_or = fields[15].integer.value; | ||
| 138 | hpx->t2->sec_unc_err_mask_and = fields[16].integer.value; | ||
| 139 | hpx->t2->sec_unc_err_mask_or = fields[17].integer.value; | ||
| 140 | break; | ||
| 141 | default: | ||
| 142 | printk(KERN_WARNING | ||
| 143 | "%s: Type 2 Revision %d record not supported\n", | ||
| 144 | __func__, revision); | ||
| 145 | return AE_ERROR; | ||
| 146 | } | ||
| 147 | return AE_OK; | ||
| 148 | } | ||
| 149 | |||
| 150 | static acpi_status | ||
| 151 | acpi_run_hpx(acpi_handle handle, struct hotplug_params *hpx) | ||
| 152 | { | ||
| 153 | acpi_status status; | ||
| 154 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
| 155 | union acpi_object *package, *record, *fields; | ||
| 156 | u32 type; | ||
| 157 | int i; | ||
| 158 | |||
| 159 | /* Clear the return buffer with zeros */ | ||
| 160 | memset(hpx, 0, sizeof(struct hotplug_params)); | ||
| 161 | |||
| 162 | status = acpi_evaluate_object(handle, "_HPX", NULL, &buffer); | ||
| 163 | if (ACPI_FAILURE(status)) | ||
| 164 | return status; | ||
| 165 | |||
| 166 | package = (union acpi_object *)buffer.pointer; | ||
| 167 | if (package->type != ACPI_TYPE_PACKAGE) { | ||
| 168 | status = AE_ERROR; | ||
| 169 | goto exit; | ||
| 170 | } | ||
| 171 | |||
| 172 | for (i = 0; i < package->package.count; i++) { | ||
| 173 | record = &package->package.elements[i]; | ||
| 174 | if (record->type != ACPI_TYPE_PACKAGE) { | ||
| 175 | status = AE_ERROR; | ||
| 176 | goto exit; | ||
| 177 | } | ||
| 178 | |||
| 179 | fields = record->package.elements; | ||
| 180 | if (fields[0].type != ACPI_TYPE_INTEGER || | ||
| 181 | fields[1].type != ACPI_TYPE_INTEGER) { | ||
| 182 | status = AE_ERROR; | ||
| 183 | goto exit; | ||
| 184 | } | ||
| 185 | |||
| 186 | type = fields[0].integer.value; | ||
| 187 | switch (type) { | ||
| 188 | case 0: | ||
| 189 | status = decode_type0_hpx_record(record, hpx); | ||
| 190 | if (ACPI_FAILURE(status)) | ||
| 191 | goto exit; | ||
| 192 | break; | ||
| 193 | case 1: | ||
| 194 | status = decode_type1_hpx_record(record, hpx); | ||
| 195 | if (ACPI_FAILURE(status)) | ||
| 196 | goto exit; | ||
| 197 | break; | ||
| 198 | case 2: | ||
| 199 | status = decode_type2_hpx_record(record, hpx); | ||
| 200 | if (ACPI_FAILURE(status)) | ||
| 201 | goto exit; | ||
| 202 | break; | ||
| 203 | default: | ||
| 204 | printk(KERN_ERR "%s: Type %d record not supported\n", | ||
| 205 | __func__, type); | ||
| 206 | status = AE_ERROR; | ||
| 207 | goto exit; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | exit: | ||
| 211 | kfree(buffer.pointer); | ||
| 212 | return status; | ||
| 213 | } | ||
| 214 | |||
| 215 | static acpi_status | ||
| 216 | acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) | ||
| 217 | { | ||
| 218 | acpi_status status; | ||
| 219 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
| 220 | union acpi_object *package, *fields; | ||
| 221 | int i; | ||
| 222 | |||
| 223 | memset(hpp, 0, sizeof(struct hotplug_params)); | ||
| 224 | |||
| 225 | status = acpi_evaluate_object(handle, "_HPP", NULL, &buffer); | ||
| 226 | if (ACPI_FAILURE(status)) | ||
| 227 | return status; | ||
| 228 | |||
| 229 | package = (union acpi_object *) buffer.pointer; | ||
| 230 | if (package->type != ACPI_TYPE_PACKAGE || | ||
| 231 | package->package.count != 4) { | ||
| 232 | status = AE_ERROR; | ||
| 233 | goto exit; | ||
| 234 | } | ||
| 235 | |||
| 236 | fields = package->package.elements; | ||
| 237 | for (i = 0; i < 4; i++) { | ||
| 238 | if (fields[i].type != ACPI_TYPE_INTEGER) { | ||
| 239 | status = AE_ERROR; | ||
| 240 | goto exit; | ||
| 241 | } | ||
| 242 | } | ||
| 243 | |||
| 244 | hpp->t0 = &hpp->type0_data; | ||
| 245 | hpp->t0->revision = 1; | ||
| 246 | hpp->t0->cache_line_size = fields[0].integer.value; | ||
| 247 | hpp->t0->latency_timer = fields[1].integer.value; | ||
| 248 | hpp->t0->enable_serr = fields[2].integer.value; | ||
| 249 | hpp->t0->enable_perr = fields[3].integer.value; | ||
| 250 | |||
| 251 | exit: | ||
| 252 | kfree(buffer.pointer); | ||
| 253 | return status; | ||
| 254 | } | ||
| 255 | |||
| 256 | |||
| 257 | |||
| 258 | /* acpi_run_oshp - get control of hotplug from the firmware | 49 | /* acpi_run_oshp - get control of hotplug from the firmware |
| 259 | * | 50 | * |
| 260 | * @handle - the handle of the hotplug controller. | 51 | * @handle - the handle of the hotplug controller. |
| @@ -283,48 +74,6 @@ static acpi_status acpi_run_oshp(acpi_handle handle) | |||
| 283 | return status; | 74 | return status; |
| 284 | } | 75 | } |
| 285 | 76 | ||
| 286 | /* pci_get_hp_params | ||
| 287 | * | ||
| 288 | * @dev - the pci_dev for which we want parameters | ||
| 289 | * @hpp - allocated by the caller | ||
| 290 | */ | ||
| 291 | int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp) | ||
| 292 | { | ||
| 293 | acpi_status status; | ||
| 294 | acpi_handle handle, phandle; | ||
| 295 | struct pci_bus *pbus; | ||
| 296 | |||
| 297 | handle = NULL; | ||
| 298 | for (pbus = dev->bus; pbus; pbus = pbus->parent) { | ||
| 299 | handle = acpi_pci_get_bridge_handle(pbus); | ||
| 300 | if (handle) | ||
| 301 | break; | ||
| 302 | } | ||
| 303 | |||
| 304 | /* | ||
| 305 | * _HPP settings apply to all child buses, until another _HPP is | ||
| 306 | * encountered. If we don't find an _HPP for the input pci dev, | ||
| 307 | * look for it in the parent device scope since that would apply to | ||
| 308 | * this pci dev. | ||
| 309 | */ | ||
| 310 | while (handle) { | ||
| 311 | status = acpi_run_hpx(handle, hpp); | ||
| 312 | if (ACPI_SUCCESS(status)) | ||
| 313 | return 0; | ||
| 314 | status = acpi_run_hpp(handle, hpp); | ||
| 315 | if (ACPI_SUCCESS(status)) | ||
| 316 | return 0; | ||
| 317 | if (acpi_is_root_bridge(handle)) | ||
| 318 | break; | ||
| 319 | status = acpi_get_parent(handle, &phandle); | ||
| 320 | if (ACPI_FAILURE(status)) | ||
| 321 | break; | ||
| 322 | handle = phandle; | ||
| 323 | } | ||
| 324 | return -ENODEV; | ||
| 325 | } | ||
| 326 | EXPORT_SYMBOL_GPL(pci_get_hp_params); | ||
| 327 | |||
| 328 | /** | 77 | /** |
| 329 | * acpi_get_hp_hw_control_from_firmware | 78 | * acpi_get_hp_hw_control_from_firmware |
| 330 | * @dev: the pci_dev of the bridge that has a hotplug controller | 79 | * @dev: the pci_dev of the bridge that has a hotplug controller |
| @@ -433,7 +182,8 @@ int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle) | |||
| 433 | { | 182 | { |
| 434 | acpi_handle bridge_handle, parent_handle; | 183 | acpi_handle bridge_handle, parent_handle; |
| 435 | 184 | ||
| 436 | if (!(bridge_handle = acpi_pci_get_bridge_handle(pbus))) | 185 | bridge_handle = acpi_pci_get_bridge_handle(pbus); |
| 186 | if (!bridge_handle) | ||
| 437 | return 0; | 187 | return 0; |
| 438 | if ((ACPI_FAILURE(acpi_get_parent(handle, &parent_handle)))) | 188 | if ((ACPI_FAILURE(acpi_get_parent(handle, &parent_handle)))) |
| 439 | return 0; | 189 | return 0; |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 6cd5160fc057..bcb90e4888dd 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
| @@ -61,7 +61,6 @@ static DEFINE_MUTEX(bridge_mutex); | |||
| 61 | static int acpiphp_hotplug_notify(struct acpi_device *adev, u32 type); | 61 | static int acpiphp_hotplug_notify(struct acpi_device *adev, u32 type); |
| 62 | static void acpiphp_post_dock_fixup(struct acpi_device *adev); | 62 | static void acpiphp_post_dock_fixup(struct acpi_device *adev); |
| 63 | static void acpiphp_sanitize_bus(struct pci_bus *bus); | 63 | static void acpiphp_sanitize_bus(struct pci_bus *bus); |
| 64 | static void acpiphp_set_hpp_values(struct pci_bus *bus); | ||
| 65 | static void hotplug_event(u32 type, struct acpiphp_context *context); | 64 | static void hotplug_event(u32 type, struct acpiphp_context *context); |
| 66 | static void free_bridge(struct kref *kref); | 65 | static void free_bridge(struct kref *kref); |
| 67 | 66 | ||
| @@ -510,7 +509,7 @@ static void enable_slot(struct acpiphp_slot *slot) | |||
| 510 | __pci_bus_assign_resources(bus, &add_list, NULL); | 509 | __pci_bus_assign_resources(bus, &add_list, NULL); |
| 511 | 510 | ||
| 512 | acpiphp_sanitize_bus(bus); | 511 | acpiphp_sanitize_bus(bus); |
| 513 | acpiphp_set_hpp_values(bus); | 512 | pcie_bus_configure_settings(bus); |
| 514 | acpiphp_set_acpi_region(slot); | 513 | acpiphp_set_acpi_region(slot); |
| 515 | 514 | ||
| 516 | list_for_each_entry(dev, &bus->devices, bus_list) { | 515 | list_for_each_entry(dev, &bus->devices, bus_list) { |
| @@ -698,14 +697,6 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge) | |||
| 698 | } | 697 | } |
| 699 | } | 698 | } |
| 700 | 699 | ||
| 701 | static void acpiphp_set_hpp_values(struct pci_bus *bus) | ||
| 702 | { | ||
| 703 | struct pci_dev *dev; | ||
| 704 | |||
| 705 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
| 706 | pci_configure_slot(dev); | ||
| 707 | } | ||
| 708 | |||
| 709 | /* | 700 | /* |
| 710 | * Remove devices for which we could not assign resources, call | 701 | * Remove devices for which we could not assign resources, call |
| 711 | * arch specific code to fix-up the bus | 702 | * arch specific code to fix-up the bus |
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 8dcccffd6e21..6ca23998ee8f 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c | |||
| @@ -302,7 +302,7 @@ static int ibm_get_table_from_acpi(char **bufp) | |||
| 302 | goto read_table_done; | 302 | goto read_table_done; |
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | for(size = 0, i = 0; i < package->package.count; i++) { | 305 | for (size = 0, i = 0; i < package->package.count; i++) { |
| 306 | if (package->package.elements[i].type != ACPI_TYPE_BUFFER) { | 306 | if (package->package.elements[i].type != ACPI_TYPE_BUFFER) { |
| 307 | pr_err("%s: Invalid APCI element %d\n", __func__, i); | 307 | pr_err("%s: Invalid APCI element %d\n", __func__, i); |
| 308 | goto read_table_done; | 308 | goto read_table_done; |
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index e09cf7827d68..a5a7fd8332ac 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c | |||
| @@ -125,7 +125,8 @@ disable_slot(struct hotplug_slot *hotplug_slot) | |||
| 125 | 125 | ||
| 126 | /* Unconfigure device */ | 126 | /* Unconfigure device */ |
| 127 | dbg("%s - unconfiguring slot %s", __func__, slot_name(slot)); | 127 | dbg("%s - unconfiguring slot %s", __func__, slot_name(slot)); |
| 128 | if ((retval = cpci_unconfigure_slot(slot))) { | 128 | retval = cpci_unconfigure_slot(slot); |
| 129 | if (retval) { | ||
| 129 | err("%s - could not unconfigure slot %s", | 130 | err("%s - could not unconfigure slot %s", |
| 130 | __func__, slot_name(slot)); | 131 | __func__, slot_name(slot)); |
| 131 | goto disable_error; | 132 | goto disable_error; |
| @@ -141,9 +142,11 @@ disable_slot(struct hotplug_slot *hotplug_slot) | |||
| 141 | } | 142 | } |
| 142 | cpci_led_on(slot); | 143 | cpci_led_on(slot); |
| 143 | 144 | ||
| 144 | if (controller->ops->set_power) | 145 | if (controller->ops->set_power) { |
| 145 | if ((retval = controller->ops->set_power(slot, 0))) | 146 | retval = controller->ops->set_power(slot, 0); |
| 147 | if (retval) | ||
| 146 | goto disable_error; | 148 | goto disable_error; |
| 149 | } | ||
| 147 | 150 | ||
| 148 | if (update_adapter_status(slot->hotplug_slot, 0)) | 151 | if (update_adapter_status(slot->hotplug_slot, 0)) |
| 149 | warn("failure to update adapter file"); | 152 | warn("failure to update adapter file"); |
| @@ -467,9 +470,9 @@ check_slots(void) | |||
| 467 | __func__, slot_name(slot), hs_csr); | 470 | __func__, slot_name(slot), hs_csr); |
| 468 | 471 | ||
| 469 | if (!slot->extracting) { | 472 | if (!slot->extracting) { |
| 470 | if (update_latch_status(slot->hotplug_slot, 0)) { | 473 | if (update_latch_status(slot->hotplug_slot, 0)) |
| 471 | warn("failure to update latch file"); | 474 | warn("failure to update latch file"); |
| 472 | } | 475 | |
| 473 | slot->extracting = 1; | 476 | slot->extracting = 1; |
| 474 | atomic_inc(&extracting); | 477 | atomic_inc(&extracting); |
| 475 | } | 478 | } |
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c index 04fcd7811400..66b7bbebe493 100644 --- a/drivers/pci/hotplug/cpcihp_generic.c +++ b/drivers/pci/hotplug/cpcihp_generic.c | |||
| @@ -56,7 +56,7 @@ | |||
| 56 | if (debug) \ | 56 | if (debug) \ |
| 57 | printk (KERN_DEBUG "%s: " format "\n", \ | 57 | printk (KERN_DEBUG "%s: " format "\n", \ |
| 58 | MY_NAME , ## arg); \ | 58 | MY_NAME , ## arg); \ |
| 59 | } while(0) | 59 | } while (0) |
| 60 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) | 60 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) |
| 61 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) | 61 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) |
| 62 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) | 62 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) |
| @@ -82,28 +82,28 @@ static int __init validate_parameters(void) | |||
| 82 | char *p; | 82 | char *p; |
| 83 | unsigned long tmp; | 83 | unsigned long tmp; |
| 84 | 84 | ||
| 85 | if(!bridge) { | 85 | if (!bridge) { |
| 86 | info("not configured, disabling."); | 86 | info("not configured, disabling."); |
| 87 | return -EINVAL; | 87 | return -EINVAL; |
| 88 | } | 88 | } |
| 89 | str = bridge; | 89 | str = bridge; |
| 90 | if(!*str) | 90 | if (!*str) |
| 91 | return -EINVAL; | 91 | return -EINVAL; |
| 92 | 92 | ||
| 93 | tmp = simple_strtoul(str, &p, 16); | 93 | tmp = simple_strtoul(str, &p, 16); |
| 94 | if(p == str || tmp > 0xff) { | 94 | if (p == str || tmp > 0xff) { |
| 95 | err("Invalid hotplug bus bridge device bus number"); | 95 | err("Invalid hotplug bus bridge device bus number"); |
| 96 | return -EINVAL; | 96 | return -EINVAL; |
| 97 | } | 97 | } |
| 98 | bridge_busnr = (u8) tmp; | 98 | bridge_busnr = (u8) tmp; |
| 99 | dbg("bridge_busnr = 0x%02x", bridge_busnr); | 99 | dbg("bridge_busnr = 0x%02x", bridge_busnr); |
| 100 | if(*p != ':') { | 100 | if (*p != ':') { |
| 101 | err("Invalid hotplug bus bridge device"); | 101 | err("Invalid hotplug bus bridge device"); |
| 102 | return -EINVAL; | 102 | return -EINVAL; |
| 103 | } | 103 | } |
| 104 | str = p + 1; | 104 | str = p + 1; |
| 105 | tmp = simple_strtoul(str, &p, 16); | 105 | tmp = simple_strtoul(str, &p, 16); |
| 106 | if(p == str || tmp > 0x1f) { | 106 | if (p == str || tmp > 0x1f) { |
| 107 | err("Invalid hotplug bus bridge device slot number"); | 107 | err("Invalid hotplug bus bridge device slot number"); |
| 108 | return -EINVAL; | 108 | return -EINVAL; |
| 109 | } | 109 | } |
| @@ -112,18 +112,18 @@ static int __init validate_parameters(void) | |||
| 112 | 112 | ||
| 113 | dbg("first_slot = 0x%02x", first_slot); | 113 | dbg("first_slot = 0x%02x", first_slot); |
| 114 | dbg("last_slot = 0x%02x", last_slot); | 114 | dbg("last_slot = 0x%02x", last_slot); |
| 115 | if(!(first_slot && last_slot)) { | 115 | if (!(first_slot && last_slot)) { |
| 116 | err("Need to specify first_slot and last_slot"); | 116 | err("Need to specify first_slot and last_slot"); |
| 117 | return -EINVAL; | 117 | return -EINVAL; |
| 118 | } | 118 | } |
| 119 | if(last_slot < first_slot) { | 119 | if (last_slot < first_slot) { |
| 120 | err("first_slot must be less than last_slot"); | 120 | err("first_slot must be less than last_slot"); |
| 121 | return -EINVAL; | 121 | return -EINVAL; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | dbg("port = 0x%04x", port); | 124 | dbg("port = 0x%04x", port); |
| 125 | dbg("enum_bit = 0x%02x", enum_bit); | 125 | dbg("enum_bit = 0x%02x", enum_bit); |
| 126 | if(enum_bit > 7) { | 126 | if (enum_bit > 7) { |
| 127 | err("Invalid #ENUM bit"); | 127 | err("Invalid #ENUM bit"); |
| 128 | return -EINVAL; | 128 | return -EINVAL; |
| 129 | } | 129 | } |
| @@ -151,12 +151,12 @@ static int __init cpcihp_generic_init(void) | |||
| 151 | return status; | 151 | return status; |
| 152 | 152 | ||
| 153 | r = request_region(port, 1, "#ENUM hotswap signal register"); | 153 | r = request_region(port, 1, "#ENUM hotswap signal register"); |
| 154 | if(!r) | 154 | if (!r) |
| 155 | return -EBUSY; | 155 | return -EBUSY; |
| 156 | 156 | ||
| 157 | dev = pci_get_domain_bus_and_slot(0, bridge_busnr, | 157 | dev = pci_get_domain_bus_and_slot(0, bridge_busnr, |
| 158 | PCI_DEVFN(bridge_slot, 0)); | 158 | PCI_DEVFN(bridge_slot, 0)); |
| 159 | if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { | 159 | if (!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { |
| 160 | err("Invalid bridge device %s", bridge); | 160 | err("Invalid bridge device %s", bridge); |
| 161 | pci_dev_put(dev); | 161 | pci_dev_put(dev); |
| 162 | return -EINVAL; | 162 | return -EINVAL; |
| @@ -169,21 +169,21 @@ static int __init cpcihp_generic_init(void) | |||
| 169 | generic_hpc.ops = &generic_hpc_ops; | 169 | generic_hpc.ops = &generic_hpc_ops; |
| 170 | 170 | ||
| 171 | status = cpci_hp_register_controller(&generic_hpc); | 171 | status = cpci_hp_register_controller(&generic_hpc); |
| 172 | if(status != 0) { | 172 | if (status != 0) { |
| 173 | err("Could not register cPCI hotplug controller"); | 173 | err("Could not register cPCI hotplug controller"); |
| 174 | return -ENODEV; | 174 | return -ENODEV; |
| 175 | } | 175 | } |
| 176 | dbg("registered controller"); | 176 | dbg("registered controller"); |
| 177 | 177 | ||
| 178 | status = cpci_hp_register_bus(bus, first_slot, last_slot); | 178 | status = cpci_hp_register_bus(bus, first_slot, last_slot); |
| 179 | if(status != 0) { | 179 | if (status != 0) { |
| 180 | err("Could not register cPCI hotplug bus"); | 180 | err("Could not register cPCI hotplug bus"); |
| 181 | goto init_bus_register_error; | 181 | goto init_bus_register_error; |
| 182 | } | 182 | } |
| 183 | dbg("registered bus"); | 183 | dbg("registered bus"); |
| 184 | 184 | ||
| 185 | status = cpci_hp_start(); | 185 | status = cpci_hp_start(); |
| 186 | if(status != 0) { | 186 | if (status != 0) { |
| 187 | err("Could not started cPCI hotplug system"); | 187 | err("Could not started cPCI hotplug system"); |
| 188 | goto init_start_error; | 188 | goto init_start_error; |
| 189 | } | 189 | } |
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c index 6757b3ef7e10..7ecf34e76a61 100644 --- a/drivers/pci/hotplug/cpcihp_zt5550.c +++ b/drivers/pci/hotplug/cpcihp_zt5550.c | |||
| @@ -51,7 +51,7 @@ | |||
| 51 | if (debug) \ | 51 | if (debug) \ |
| 52 | printk (KERN_DEBUG "%s: " format "\n", \ | 52 | printk (KERN_DEBUG "%s: " format "\n", \ |
| 53 | MY_NAME , ## arg); \ | 53 | MY_NAME , ## arg); \ |
| 54 | } while(0) | 54 | } while (0) |
| 55 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) | 55 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) |
| 56 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) | 56 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) |
| 57 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) | 57 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) |
| @@ -82,13 +82,13 @@ static int zt5550_hc_config(struct pci_dev *pdev) | |||
| 82 | int ret; | 82 | int ret; |
| 83 | 83 | ||
| 84 | /* Since we know that no boards exist with two HC chips, treat it as an error */ | 84 | /* Since we know that no boards exist with two HC chips, treat it as an error */ |
| 85 | if(hc_dev) { | 85 | if (hc_dev) { |
| 86 | err("too many host controller devices?"); | 86 | err("too many host controller devices?"); |
| 87 | return -EBUSY; | 87 | return -EBUSY; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | ret = pci_enable_device(pdev); | 90 | ret = pci_enable_device(pdev); |
| 91 | if(ret) { | 91 | if (ret) { |
| 92 | err("cannot enable %s\n", pci_name(pdev)); | 92 | err("cannot enable %s\n", pci_name(pdev)); |
| 93 | return ret; | 93 | return ret; |
| 94 | } | 94 | } |
| @@ -98,7 +98,7 @@ static int zt5550_hc_config(struct pci_dev *pdev) | |||
| 98 | dbg("pci resource start %llx", (unsigned long long)pci_resource_start(hc_dev, 1)); | 98 | dbg("pci resource start %llx", (unsigned long long)pci_resource_start(hc_dev, 1)); |
| 99 | dbg("pci resource len %llx", (unsigned long long)pci_resource_len(hc_dev, 1)); | 99 | dbg("pci resource len %llx", (unsigned long long)pci_resource_len(hc_dev, 1)); |
| 100 | 100 | ||
| 101 | if(!request_mem_region(pci_resource_start(hc_dev, 1), | 101 | if (!request_mem_region(pci_resource_start(hc_dev, 1), |
| 102 | pci_resource_len(hc_dev, 1), MY_NAME)) { | 102 | pci_resource_len(hc_dev, 1), MY_NAME)) { |
| 103 | err("cannot reserve MMIO region"); | 103 | err("cannot reserve MMIO region"); |
| 104 | ret = -ENOMEM; | 104 | ret = -ENOMEM; |
| @@ -107,7 +107,7 @@ static int zt5550_hc_config(struct pci_dev *pdev) | |||
| 107 | 107 | ||
| 108 | hc_registers = | 108 | hc_registers = |
| 109 | ioremap(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1)); | 109 | ioremap(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1)); |
| 110 | if(!hc_registers) { | 110 | if (!hc_registers) { |
| 111 | err("cannot remap MMIO region %llx @ %llx", | 111 | err("cannot remap MMIO region %llx @ %llx", |
| 112 | (unsigned long long)pci_resource_len(hc_dev, 1), | 112 | (unsigned long long)pci_resource_len(hc_dev, 1), |
| 113 | (unsigned long long)pci_resource_start(hc_dev, 1)); | 113 | (unsigned long long)pci_resource_start(hc_dev, 1)); |
| @@ -146,7 +146,7 @@ exit_disable_device: | |||
| 146 | 146 | ||
| 147 | static int zt5550_hc_cleanup(void) | 147 | static int zt5550_hc_cleanup(void) |
| 148 | { | 148 | { |
| 149 | if(!hc_dev) | 149 | if (!hc_dev) |
| 150 | return -ENODEV; | 150 | return -ENODEV; |
| 151 | 151 | ||
| 152 | iounmap(hc_registers); | 152 | iounmap(hc_registers); |
| @@ -170,9 +170,9 @@ static int zt5550_hc_check_irq(void *dev_id) | |||
| 170 | u8 reg; | 170 | u8 reg; |
| 171 | 171 | ||
| 172 | ret = 0; | 172 | ret = 0; |
| 173 | if(dev_id == zt5550_hpc.dev_id) { | 173 | if (dev_id == zt5550_hpc.dev_id) { |
| 174 | reg = readb(csr_int_status); | 174 | reg = readb(csr_int_status); |
| 175 | if(reg) | 175 | if (reg) |
| 176 | ret = 1; | 176 | ret = 1; |
| 177 | } | 177 | } |
| 178 | return ret; | 178 | return ret; |
| @@ -182,9 +182,9 @@ static int zt5550_hc_enable_irq(void) | |||
| 182 | { | 182 | { |
| 183 | u8 reg; | 183 | u8 reg; |
| 184 | 184 | ||
| 185 | if(hc_dev == NULL) { | 185 | if (hc_dev == NULL) |
| 186 | return -ENODEV; | 186 | return -ENODEV; |
| 187 | } | 187 | |
| 188 | reg = readb(csr_int_mask); | 188 | reg = readb(csr_int_mask); |
| 189 | reg = reg & ~ENUM_INT_MASK; | 189 | reg = reg & ~ENUM_INT_MASK; |
| 190 | writeb(reg, csr_int_mask); | 190 | writeb(reg, csr_int_mask); |
| @@ -195,9 +195,8 @@ static int zt5550_hc_disable_irq(void) | |||
| 195 | { | 195 | { |
| 196 | u8 reg; | 196 | u8 reg; |
| 197 | 197 | ||
| 198 | if(hc_dev == NULL) { | 198 | if (hc_dev == NULL) |
| 199 | return -ENODEV; | 199 | return -ENODEV; |
| 200 | } | ||
| 201 | 200 | ||
| 202 | reg = readb(csr_int_mask); | 201 | reg = readb(csr_int_mask); |
| 203 | reg = reg | ENUM_INT_MASK; | 202 | reg = reg | ENUM_INT_MASK; |
| @@ -210,15 +209,15 @@ static int zt5550_hc_init_one (struct pci_dev *pdev, const struct pci_device_id | |||
| 210 | int status; | 209 | int status; |
| 211 | 210 | ||
| 212 | status = zt5550_hc_config(pdev); | 211 | status = zt5550_hc_config(pdev); |
| 213 | if(status != 0) { | 212 | if (status != 0) |
| 214 | return status; | 213 | return status; |
| 215 | } | 214 | |
| 216 | dbg("returned from zt5550_hc_config"); | 215 | dbg("returned from zt5550_hc_config"); |
| 217 | 216 | ||
| 218 | memset(&zt5550_hpc, 0, sizeof (struct cpci_hp_controller)); | 217 | memset(&zt5550_hpc, 0, sizeof (struct cpci_hp_controller)); |
| 219 | zt5550_hpc_ops.query_enum = zt5550_hc_query_enum; | 218 | zt5550_hpc_ops.query_enum = zt5550_hc_query_enum; |
| 220 | zt5550_hpc.ops = &zt5550_hpc_ops; | 219 | zt5550_hpc.ops = &zt5550_hpc_ops; |
| 221 | if(!poll) { | 220 | if (!poll) { |
| 222 | zt5550_hpc.irq = hc_dev->irq; | 221 | zt5550_hpc.irq = hc_dev->irq; |
| 223 | zt5550_hpc.irq_flags = IRQF_SHARED; | 222 | zt5550_hpc.irq_flags = IRQF_SHARED; |
| 224 | zt5550_hpc.dev_id = hc_dev; | 223 | zt5550_hpc.dev_id = hc_dev; |
| @@ -231,15 +230,16 @@ static int zt5550_hc_init_one (struct pci_dev *pdev, const struct pci_device_id | |||
| 231 | } | 230 | } |
| 232 | 231 | ||
| 233 | status = cpci_hp_register_controller(&zt5550_hpc); | 232 | status = cpci_hp_register_controller(&zt5550_hpc); |
| 234 | if(status != 0) { | 233 | if (status != 0) { |
| 235 | err("could not register cPCI hotplug controller"); | 234 | err("could not register cPCI hotplug controller"); |
| 236 | goto init_hc_error; | 235 | goto init_hc_error; |
| 237 | } | 236 | } |
| 238 | dbg("registered controller"); | 237 | dbg("registered controller"); |
| 239 | 238 | ||
| 240 | /* Look for first device matching cPCI bus's bridge vendor and device IDs */ | 239 | /* Look for first device matching cPCI bus's bridge vendor and device IDs */ |
| 241 | if(!(bus0_dev = pci_get_device(PCI_VENDOR_ID_DEC, | 240 | bus0_dev = pci_get_device(PCI_VENDOR_ID_DEC, |
| 242 | PCI_DEVICE_ID_DEC_21154, NULL))) { | 241 | PCI_DEVICE_ID_DEC_21154, NULL); |
| 242 | if (!bus0_dev) { | ||
| 243 | status = -ENODEV; | 243 | status = -ENODEV; |
| 244 | goto init_register_error; | 244 | goto init_register_error; |
| 245 | } | 245 | } |
| @@ -247,14 +247,14 @@ static int zt5550_hc_init_one (struct pci_dev *pdev, const struct pci_device_id | |||
| 247 | pci_dev_put(bus0_dev); | 247 | pci_dev_put(bus0_dev); |
| 248 | 248 | ||
| 249 | status = cpci_hp_register_bus(bus0, 0x0a, 0x0f); | 249 | status = cpci_hp_register_bus(bus0, 0x0a, 0x0f); |
| 250 | if(status != 0) { | 250 | if (status != 0) { |
| 251 | err("could not register cPCI hotplug bus"); | 251 | err("could not register cPCI hotplug bus"); |
| 252 | goto init_register_error; | 252 | goto init_register_error; |
| 253 | } | 253 | } |
| 254 | dbg("registered bus"); | 254 | dbg("registered bus"); |
| 255 | 255 | ||
| 256 | status = cpci_hp_start(); | 256 | status = cpci_hp_start(); |
| 257 | if(status != 0) { | 257 | if (status != 0) { |
| 258 | err("could not started cPCI hotplug system"); | 258 | err("could not started cPCI hotplug system"); |
| 259 | cpci_hp_unregister_bus(bus0); | 259 | cpci_hp_unregister_bus(bus0); |
| 260 | goto init_register_error; | 260 | goto init_register_error; |
| @@ -300,11 +300,11 @@ static int __init zt5550_init(void) | |||
| 300 | 300 | ||
| 301 | info(DRIVER_DESC " version: " DRIVER_VERSION); | 301 | info(DRIVER_DESC " version: " DRIVER_VERSION); |
| 302 | r = request_region(ENUM_PORT, 1, "#ENUM hotswap signal register"); | 302 | r = request_region(ENUM_PORT, 1, "#ENUM hotswap signal register"); |
| 303 | if(!r) | 303 | if (!r) |
| 304 | return -EBUSY; | 304 | return -EBUSY; |
| 305 | 305 | ||
| 306 | rc = pci_register_driver(&zt5550_hc_driver); | 306 | rc = pci_register_driver(&zt5550_hc_driver); |
| 307 | if(rc < 0) | 307 | if (rc < 0) |
| 308 | release_region(ENUM_PORT, 1); | 308 | release_region(ENUM_PORT, 1); |
| 309 | return rc; | 309 | return rc; |
| 310 | } | 310 | } |
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h index 0450f405807d..b28b2d2184cd 100644 --- a/drivers/pci/hotplug/cpqphp.h +++ b/drivers/pci/hotplug/cpqphp.h | |||
| @@ -690,7 +690,7 @@ static inline int cpq_get_latch_status(struct controller *ctrl, | |||
| 690 | 690 | ||
| 691 | status = (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)); | 691 | status = (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)); |
| 692 | 692 | ||
| 693 | return(status == 0) ? 1 : 0; | 693 | return (status == 0) ? 1 : 0; |
| 694 | } | 694 | } |
| 695 | 695 | ||
| 696 | 696 | ||
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 4aaee746df88..a53084ddc118 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c | |||
| @@ -1096,9 +1096,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 1096 | 1096 | ||
| 1097 | /* initialize our threads if they haven't already been started up */ | 1097 | /* initialize our threads if they haven't already been started up */ |
| 1098 | rc = one_time_init(); | 1098 | rc = one_time_init(); |
| 1099 | if (rc) { | 1099 | if (rc) |
| 1100 | goto err_free_bus; | 1100 | goto err_free_bus; |
| 1101 | } | ||
| 1102 | 1101 | ||
| 1103 | dbg("pdev = %p\n", pdev); | 1102 | dbg("pdev = %p\n", pdev); |
| 1104 | dbg("pci resource start %llx\n", (unsigned long long)pci_resource_start(pdev, 0)); | 1103 | dbg("pci resource start %llx\n", (unsigned long long)pci_resource_start(pdev, 0)); |
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index bde47fce3248..c5cbefee5236 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c | |||
| @@ -705,9 +705,8 @@ static struct pci_resource *get_max_resource(struct pci_resource **head, u32 siz | |||
| 705 | if (temp == max) { | 705 | if (temp == max) { |
| 706 | *head = max->next; | 706 | *head = max->next; |
| 707 | } else { | 707 | } else { |
| 708 | while (temp && temp->next != max) { | 708 | while (temp && temp->next != max) |
| 709 | temp = temp->next; | 709 | temp = temp->next; |
| 710 | } | ||
| 711 | 710 | ||
| 712 | if (temp) | 711 | if (temp) |
| 713 | temp->next = max->next; | 712 | temp->next = max->next; |
| @@ -903,9 +902,8 @@ irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data) | |||
| 903 | /* | 902 | /* |
| 904 | * Check to see if it was our interrupt | 903 | * Check to see if it was our interrupt |
| 905 | */ | 904 | */ |
| 906 | if (!(misc & 0x000C)) { | 905 | if (!(misc & 0x000C)) |
| 907 | return IRQ_NONE; | 906 | return IRQ_NONE; |
| 908 | } | ||
| 909 | 907 | ||
| 910 | if (misc & 0x0004) { | 908 | if (misc & 0x0004) { |
| 911 | /* | 909 | /* |
| @@ -1143,7 +1141,7 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
| 1143 | /* We don't allow freq/mode changes if we find another adapter running | 1141 | /* We don't allow freq/mode changes if we find another adapter running |
| 1144 | * in another slot on this controller | 1142 | * in another slot on this controller |
| 1145 | */ | 1143 | */ |
| 1146 | for(slot = ctrl->slot; slot; slot = slot->next) { | 1144 | for (slot = ctrl->slot; slot; slot = slot->next) { |
| 1147 | if (slot->device == (hp_slot + ctrl->slot_device_offset)) | 1145 | if (slot->device == (hp_slot + ctrl->slot_device_offset)) |
| 1148 | continue; | 1146 | continue; |
| 1149 | if (!slot->hotplug_slot || !slot->hotplug_slot->info) | 1147 | if (!slot->hotplug_slot || !slot->hotplug_slot->info) |
| @@ -1193,7 +1191,7 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
| 1193 | 1191 | ||
| 1194 | reg16 = readw(ctrl->hpc_reg + NEXT_CURR_FREQ); | 1192 | reg16 = readw(ctrl->hpc_reg + NEXT_CURR_FREQ); |
| 1195 | reg16 &= ~0x000F; | 1193 | reg16 &= ~0x000F; |
| 1196 | switch(adapter_speed) { | 1194 | switch (adapter_speed) { |
| 1197 | case(PCI_SPEED_133MHz_PCIX): | 1195 | case(PCI_SPEED_133MHz_PCIX): |
| 1198 | reg = 0x75; | 1196 | reg = 0x75; |
| 1199 | reg16 |= 0xB; | 1197 | reg16 |= 0xB; |
| @@ -2006,9 +2004,8 @@ int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func) | |||
| 2006 | /* Check to see if the interlock is closed */ | 2004 | /* Check to see if the interlock is closed */ |
| 2007 | tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR); | 2005 | tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR); |
| 2008 | 2006 | ||
| 2009 | if (tempdword & (0x01 << hp_slot)) { | 2007 | if (tempdword & (0x01 << hp_slot)) |
| 2010 | return 1; | 2008 | return 1; |
| 2011 | } | ||
| 2012 | 2009 | ||
| 2013 | if (func->is_a_board) { | 2010 | if (func->is_a_board) { |
| 2014 | rc = board_replaced(func, ctrl); | 2011 | rc = board_replaced(func, ctrl); |
| @@ -2070,9 +2067,8 @@ int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func) | |||
| 2070 | } | 2067 | } |
| 2071 | } | 2068 | } |
| 2072 | 2069 | ||
| 2073 | if (rc) { | 2070 | if (rc) |
| 2074 | dbg("%s: rc = %d\n", __func__, rc); | 2071 | dbg("%s: rc = %d\n", __func__, rc); |
| 2075 | } | ||
| 2076 | 2072 | ||
| 2077 | if (p_slot) | 2073 | if (p_slot) |
| 2078 | update_slot_info(ctrl, p_slot); | 2074 | update_slot_info(ctrl, p_slot); |
| @@ -2095,9 +2091,8 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func) | |||
| 2095 | device = func->device; | 2091 | device = func->device; |
| 2096 | func = cpqhp_slot_find(ctrl->bus, device, index++); | 2092 | func = cpqhp_slot_find(ctrl->bus, device, index++); |
| 2097 | p_slot = cpqhp_find_slot(ctrl, device); | 2093 | p_slot = cpqhp_find_slot(ctrl, device); |
| 2098 | if (p_slot) { | 2094 | if (p_slot) |
| 2099 | physical_slot = p_slot->number; | 2095 | physical_slot = p_slot->number; |
| 2100 | } | ||
| 2101 | 2096 | ||
| 2102 | /* Make sure there are no video controllers here */ | 2097 | /* Make sure there are no video controllers here */ |
| 2103 | while (func && !rc) { | 2098 | while (func && !rc) { |
diff --git a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c index 0968a9bcb345..1e08ff8c229c 100644 --- a/drivers/pci/hotplug/cpqphp_nvram.c +++ b/drivers/pci/hotplug/cpqphp_nvram.c | |||
| @@ -204,9 +204,8 @@ static int load_HRT (void __iomem *rom_start) | |||
| 204 | u8 temp_byte = 0xFF; | 204 | u8 temp_byte = 0xFF; |
| 205 | u32 rc; | 205 | u32 rc; |
| 206 | 206 | ||
| 207 | if (!check_for_compaq_ROM(rom_start)) { | 207 | if (!check_for_compaq_ROM(rom_start)) |
| 208 | return -ENODEV; | 208 | return -ENODEV; |
| 209 | } | ||
| 210 | 209 | ||
| 211 | available = 1024; | 210 | available = 1024; |
| 212 | 211 | ||
| @@ -250,9 +249,8 @@ static u32 store_HRT (void __iomem *rom_start) | |||
| 250 | 249 | ||
| 251 | available = 1024; | 250 | available = 1024; |
| 252 | 251 | ||
| 253 | if (!check_for_compaq_ROM(rom_start)) { | 252 | if (!check_for_compaq_ROM(rom_start)) |
| 254 | return(1); | 253 | return(1); |
| 255 | } | ||
| 256 | 254 | ||
| 257 | buffer = (u32*) evbuffer; | 255 | buffer = (u32*) evbuffer; |
| 258 | 256 | ||
| @@ -427,9 +425,9 @@ static u32 store_HRT (void __iomem *rom_start) | |||
| 427 | 425 | ||
| 428 | void compaq_nvram_init (void __iomem *rom_start) | 426 | void compaq_nvram_init (void __iomem *rom_start) |
| 429 | { | 427 | { |
| 430 | if (rom_start) { | 428 | if (rom_start) |
| 431 | compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR); | 429 | compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR); |
| 432 | } | 430 | |
| 433 | dbg("int15 entry = %p\n", compaq_int15_entry_point); | 431 | dbg("int15 entry = %p\n", compaq_int15_entry_point); |
| 434 | 432 | ||
| 435 | /* initialize our int15 lock */ | 433 | /* initialize our int15 lock */ |
| @@ -661,9 +659,8 @@ int compaq_nvram_store (void __iomem *rom_start) | |||
| 661 | 659 | ||
| 662 | if (evbuffer_init) { | 660 | if (evbuffer_init) { |
| 663 | rc = store_HRT(rom_start); | 661 | rc = store_HRT(rom_start); |
| 664 | if (rc) { | 662 | if (rc) |
| 665 | err(msg_unable_to_save); | 663 | err(msg_unable_to_save); |
| 666 | } | ||
| 667 | } | 664 | } |
| 668 | return rc; | 665 | return rc; |
| 669 | } | 666 | } |
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index f7b8684a7739..3efaf4c38528 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c | |||
| @@ -1023,7 +1023,8 @@ static int enable_slot(struct hotplug_slot *hs) | |||
| 1023 | debug("ENABLING SLOT........\n"); | 1023 | debug("ENABLING SLOT........\n"); |
| 1024 | slot_cur = hs->private; | 1024 | slot_cur = hs->private; |
| 1025 | 1025 | ||
| 1026 | if ((rc = validate(slot_cur, ENABLE))) { | 1026 | rc = validate(slot_cur, ENABLE); |
| 1027 | if (rc) { | ||
| 1027 | err("validate function failed\n"); | 1028 | err("validate function failed\n"); |
| 1028 | goto error_nopower; | 1029 | goto error_nopower; |
| 1029 | } | 1030 | } |
| @@ -1199,9 +1200,8 @@ int ibmphp_do_disable_slot(struct slot *slot_cur) | |||
| 1199 | 1200 | ||
| 1200 | debug("DISABLING SLOT...\n"); | 1201 | debug("DISABLING SLOT...\n"); |
| 1201 | 1202 | ||
| 1202 | if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) { | 1203 | if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) |
| 1203 | return -ENODEV; | 1204 | return -ENODEV; |
| 1204 | } | ||
| 1205 | 1205 | ||
| 1206 | flag = slot_cur->flag; | 1206 | flag = slot_cur->flag; |
| 1207 | slot_cur->flag = 1; | 1207 | slot_cur->flag = 1; |
| @@ -1336,17 +1336,20 @@ static int __init ibmphp_init(void) | |||
| 1336 | for (i = 0; i < 16; i++) | 1336 | for (i = 0; i < 16; i++) |
| 1337 | irqs[i] = 0; | 1337 | irqs[i] = 0; |
| 1338 | 1338 | ||
| 1339 | if ((rc = ibmphp_access_ebda())) | 1339 | rc = ibmphp_access_ebda(); |
| 1340 | if (rc) | ||
| 1340 | goto error; | 1341 | goto error; |
| 1341 | debug("after ibmphp_access_ebda()\n"); | 1342 | debug("after ibmphp_access_ebda()\n"); |
| 1342 | 1343 | ||
| 1343 | if ((rc = ibmphp_rsrc_init())) | 1344 | rc = ibmphp_rsrc_init(); |
| 1345 | if (rc) | ||
| 1344 | goto error; | 1346 | goto error; |
| 1345 | debug("AFTER Resource & EBDA INITIALIZATIONS\n"); | 1347 | debug("AFTER Resource & EBDA INITIALIZATIONS\n"); |
| 1346 | 1348 | ||
| 1347 | max_slots = get_max_slots(); | 1349 | max_slots = get_max_slots(); |
| 1348 | 1350 | ||
| 1349 | if ((rc = ibmphp_register_pci())) | 1351 | rc = ibmphp_register_pci(); |
| 1352 | if (rc) | ||
| 1350 | goto error; | 1353 | goto error; |
| 1351 | 1354 | ||
| 1352 | if (init_ops()) { | 1355 | if (init_ops()) { |
| @@ -1355,9 +1358,9 @@ static int __init ibmphp_init(void) | |||
| 1355 | } | 1358 | } |
| 1356 | 1359 | ||
| 1357 | ibmphp_print_test(); | 1360 | ibmphp_print_test(); |
| 1358 | if ((rc = ibmphp_hpc_start_poll_thread())) { | 1361 | rc = ibmphp_hpc_start_poll_thread(); |
| 1362 | if (rc) | ||
| 1359 | goto error; | 1363 | goto error; |
| 1360 | } | ||
| 1361 | 1364 | ||
| 1362 | exit: | 1365 | exit: |
| 1363 | return rc; | 1366 | return rc; |
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index 0f65ac555434..d9b197d5c6b4 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c | |||
| @@ -215,9 +215,8 @@ static void __init print_ebda_hpc (void) | |||
| 215 | debug ("%s - cap of the slot: %x\n", __func__, hpc_ptr->slots[index].slot_cap); | 215 | debug ("%s - cap of the slot: %x\n", __func__, hpc_ptr->slots[index].slot_cap); |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | for (index = 0; index < hpc_ptr->bus_count; index++) { | 218 | for (index = 0; index < hpc_ptr->bus_count; index++) |
| 219 | debug ("%s - bus# of each bus controlled by this ctlr: %x\n", __func__, hpc_ptr->buses[index].bus_num); | 219 | debug ("%s - bus# of each bus controlled by this ctlr: %x\n", __func__, hpc_ptr->buses[index].bus_num); |
| 220 | } | ||
| 221 | 220 | ||
| 222 | debug ("%s - type of hpc: %x\n", __func__, hpc_ptr->ctlr_type); | 221 | debug ("%s - type of hpc: %x\n", __func__, hpc_ptr->ctlr_type); |
| 223 | switch (hpc_ptr->ctlr_type) { | 222 | switch (hpc_ptr->ctlr_type) { |
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c index a936022956e6..220876715a08 100644 --- a/drivers/pci/hotplug/ibmphp_hpc.c +++ b/drivers/pci/hotplug/ibmphp_hpc.c | |||
| @@ -997,9 +997,8 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot) | |||
| 997 | rc = ibmphp_do_disable_slot (pslot); | 997 | rc = ibmphp_do_disable_slot (pslot); |
| 998 | } | 998 | } |
| 999 | 999 | ||
| 1000 | if (update || disable) { | 1000 | if (update || disable) |
| 1001 | ibmphp_update_slot_info (pslot); | 1001 | ibmphp_update_slot_info (pslot); |
| 1002 | } | ||
| 1003 | 1002 | ||
| 1004 | debug ("%s - Exit rc[%d] disable[%x] update[%x]\n", __func__, rc, disable, update); | 1003 | debug ("%s - Exit rc[%d] disable[%x] update[%x]\n", __func__, rc, disable, update); |
| 1005 | 1004 | ||
diff --git a/drivers/pci/hotplug/ibmphp_pci.c b/drivers/pci/hotplug/ibmphp_pci.c index 2fd296706ce7..814cea22a9fa 100644 --- a/drivers/pci/hotplug/ibmphp_pci.c +++ b/drivers/pci/hotplug/ibmphp_pci.c | |||
| @@ -145,7 +145,8 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno) | |||
| 145 | case PCI_HEADER_TYPE_NORMAL: | 145 | case PCI_HEADER_TYPE_NORMAL: |
| 146 | debug ("single device case.... vendor id = %x, hdr_type = %x, class = %x\n", vendor_id, hdr_type, class); | 146 | debug ("single device case.... vendor id = %x, hdr_type = %x, class = %x\n", vendor_id, hdr_type, class); |
| 147 | assign_alt_irq (cur_func, class_code); | 147 | assign_alt_irq (cur_func, class_code); |
| 148 | if ((rc = configure_device (cur_func)) < 0) { | 148 | rc = configure_device(cur_func); |
| 149 | if (rc < 0) { | ||
| 149 | /* We need to do this in case some other BARs were properly inserted */ | 150 | /* We need to do this in case some other BARs were properly inserted */ |
| 150 | err ("was not able to configure devfunc %x on bus %x.\n", | 151 | err ("was not able to configure devfunc %x on bus %x.\n", |
| 151 | cur_func->device, cur_func->busno); | 152 | cur_func->device, cur_func->busno); |
| @@ -157,7 +158,8 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno) | |||
| 157 | break; | 158 | break; |
| 158 | case PCI_HEADER_TYPE_MULTIDEVICE: | 159 | case PCI_HEADER_TYPE_MULTIDEVICE: |
| 159 | assign_alt_irq (cur_func, class_code); | 160 | assign_alt_irq (cur_func, class_code); |
| 160 | if ((rc = configure_device (cur_func)) < 0) { | 161 | rc = configure_device(cur_func); |
| 162 | if (rc < 0) { | ||
| 161 | /* We need to do this in case some other BARs were properly inserted */ | 163 | /* We need to do this in case some other BARs were properly inserted */ |
| 162 | err ("was not able to configure devfunc %x on bus %x...bailing out\n", | 164 | err ("was not able to configure devfunc %x on bus %x...bailing out\n", |
| 163 | cur_func->device, cur_func->busno); | 165 | cur_func->device, cur_func->busno); |
diff --git a/drivers/pci/hotplug/ibmphp_res.c b/drivers/pci/hotplug/ibmphp_res.c index f34745abd5b6..219ba8090a37 100644 --- a/drivers/pci/hotplug/ibmphp_res.c +++ b/drivers/pci/hotplug/ibmphp_res.c | |||
| @@ -224,7 +224,8 @@ int __init ibmphp_rsrc_init (void) | |||
| 224 | if ((curr->rsrc_type & RESTYPE) == MMASK) { | 224 | if ((curr->rsrc_type & RESTYPE) == MMASK) { |
| 225 | /* no bus structure exists in place yet */ | 225 | /* no bus structure exists in place yet */ |
| 226 | if (list_empty (&gbuses)) { | 226 | if (list_empty (&gbuses)) { |
| 227 | if ((rc = alloc_bus_range (&newbus, &newrange, curr, MEM, 1))) | 227 | rc = alloc_bus_range(&newbus, &newrange, curr, MEM, 1); |
| 228 | if (rc) | ||
| 228 | return rc; | 229 | return rc; |
| 229 | list_add_tail (&newbus->bus_list, &gbuses); | 230 | list_add_tail (&newbus->bus_list, &gbuses); |
| 230 | debug ("gbuses = NULL, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); | 231 | debug ("gbuses = NULL, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); |
| @@ -237,7 +238,8 @@ int __init ibmphp_rsrc_init (void) | |||
| 237 | return rc; | 238 | return rc; |
| 238 | } else { | 239 | } else { |
| 239 | /* went through all the buses and didn't find ours, need to create a new bus node */ | 240 | /* went through all the buses and didn't find ours, need to create a new bus node */ |
| 240 | if ((rc = alloc_bus_range (&newbus, &newrange, curr, MEM, 1))) | 241 | rc = alloc_bus_range(&newbus, &newrange, curr, MEM, 1); |
| 242 | if (rc) | ||
| 241 | return rc; | 243 | return rc; |
| 242 | 244 | ||
| 243 | list_add_tail (&newbus->bus_list, &gbuses); | 245 | list_add_tail (&newbus->bus_list, &gbuses); |
| @@ -248,7 +250,8 @@ int __init ibmphp_rsrc_init (void) | |||
| 248 | /* prefetchable memory */ | 250 | /* prefetchable memory */ |
| 249 | if (list_empty (&gbuses)) { | 251 | if (list_empty (&gbuses)) { |
| 250 | /* no bus structure exists in place yet */ | 252 | /* no bus structure exists in place yet */ |
| 251 | if ((rc = alloc_bus_range (&newbus, &newrange, curr, PFMEM, 1))) | 253 | rc = alloc_bus_range(&newbus, &newrange, curr, PFMEM, 1); |
| 254 | if (rc) | ||
| 252 | return rc; | 255 | return rc; |
| 253 | list_add_tail (&newbus->bus_list, &gbuses); | 256 | list_add_tail (&newbus->bus_list, &gbuses); |
| 254 | debug ("gbuses = NULL, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); | 257 | debug ("gbuses = NULL, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); |
| @@ -261,7 +264,8 @@ int __init ibmphp_rsrc_init (void) | |||
| 261 | return rc; | 264 | return rc; |
| 262 | } else { | 265 | } else { |
| 263 | /* went through all the buses and didn't find ours, need to create a new bus node */ | 266 | /* went through all the buses and didn't find ours, need to create a new bus node */ |
| 264 | if ((rc = alloc_bus_range (&newbus, &newrange, curr, PFMEM, 1))) | 267 | rc = alloc_bus_range(&newbus, &newrange, curr, PFMEM, 1); |
| 268 | if (rc) | ||
| 265 | return rc; | 269 | return rc; |
| 266 | list_add_tail (&newbus->bus_list, &gbuses); | 270 | list_add_tail (&newbus->bus_list, &gbuses); |
| 267 | debug ("1st Bus, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); | 271 | debug ("1st Bus, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); |
| @@ -271,7 +275,8 @@ int __init ibmphp_rsrc_init (void) | |||
| 271 | /* IO */ | 275 | /* IO */ |
| 272 | if (list_empty (&gbuses)) { | 276 | if (list_empty (&gbuses)) { |
| 273 | /* no bus structure exists in place yet */ | 277 | /* no bus structure exists in place yet */ |
| 274 | if ((rc = alloc_bus_range (&newbus, &newrange, curr, IO, 1))) | 278 | rc = alloc_bus_range(&newbus, &newrange, curr, IO, 1); |
| 279 | if (rc) | ||
| 275 | return rc; | 280 | return rc; |
| 276 | list_add_tail (&newbus->bus_list, &gbuses); | 281 | list_add_tail (&newbus->bus_list, &gbuses); |
| 277 | debug ("gbuses = NULL, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); | 282 | debug ("gbuses = NULL, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); |
| @@ -283,7 +288,8 @@ int __init ibmphp_rsrc_init (void) | |||
| 283 | return rc; | 288 | return rc; |
| 284 | } else { | 289 | } else { |
| 285 | /* went through all the buses and didn't find ours, need to create a new bus node */ | 290 | /* went through all the buses and didn't find ours, need to create a new bus node */ |
| 286 | if ((rc = alloc_bus_range (&newbus, &newrange, curr, IO, 1))) | 291 | rc = alloc_bus_range(&newbus, &newrange, curr, IO, 1); |
| 292 | if (rc) | ||
| 287 | return rc; | 293 | return rc; |
| 288 | list_add_tail (&newbus->bus_list, &gbuses); | 294 | list_add_tail (&newbus->bus_list, &gbuses); |
| 289 | debug ("1st Bus, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); | 295 | debug ("1st Bus, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end); |
| @@ -1038,7 +1044,9 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge) | |||
| 1038 | /* found our range */ | 1044 | /* found our range */ |
| 1039 | if (!res_prev) { | 1045 | if (!res_prev) { |
| 1040 | /* first time in the loop */ | 1046 | /* first time in the loop */ |
| 1041 | if ((res_cur->start != range->start) && ((len_tmp = res_cur->start - 1 - range->start) >= res->len)) { | 1047 | len_tmp = res_cur->start - 1 - range->start; |
| 1048 | |||
| 1049 | if ((res_cur->start != range->start) && (len_tmp >= res->len)) { | ||
| 1042 | debug ("len_tmp = %x\n", len_tmp); | 1050 | debug ("len_tmp = %x\n", len_tmp); |
| 1043 | 1051 | ||
| 1044 | if ((len_tmp < len_cur) || (len_cur == 0)) { | 1052 | if ((len_tmp < len_cur) || (len_cur == 0)) { |
| @@ -1078,7 +1086,9 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge) | |||
| 1078 | } | 1086 | } |
| 1079 | if (!res_cur->next) { | 1087 | if (!res_cur->next) { |
| 1080 | /* last device on the range */ | 1088 | /* last device on the range */ |
| 1081 | if ((range->end != res_cur->end) && ((len_tmp = range->end - (res_cur->end + 1)) >= res->len)) { | 1089 | len_tmp = range->end - (res_cur->end + 1); |
| 1090 | |||
| 1091 | if ((range->end != res_cur->end) && (len_tmp >= res->len)) { | ||
| 1082 | debug ("len_tmp = %x\n", len_tmp); | 1092 | debug ("len_tmp = %x\n", len_tmp); |
| 1083 | if ((len_tmp < len_cur) || (len_cur == 0)) { | 1093 | if ((len_tmp < len_cur) || (len_cur == 0)) { |
| 1084 | 1094 | ||
| @@ -1117,8 +1127,9 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge) | |||
| 1117 | if (res_prev) { | 1127 | if (res_prev) { |
| 1118 | if (res_prev->rangeno != res_cur->rangeno) { | 1128 | if (res_prev->rangeno != res_cur->rangeno) { |
| 1119 | /* 1st device on this range */ | 1129 | /* 1st device on this range */ |
| 1120 | if ((res_cur->start != range->start) && | 1130 | len_tmp = res_cur->start - 1 - range->start; |
| 1121 | ((len_tmp = res_cur->start - 1 - range->start) >= res->len)) { | 1131 | |
| 1132 | if ((res_cur->start != range->start) && (len_tmp >= res->len)) { | ||
| 1122 | if ((len_tmp < len_cur) || (len_cur == 0)) { | 1133 | if ((len_tmp < len_cur) || (len_cur == 0)) { |
| 1123 | if ((range->start % tmp_divide) == 0) { | 1134 | if ((range->start % tmp_divide) == 0) { |
| 1124 | /* just perfect, starting address is divisible by length */ | 1135 | /* just perfect, starting address is divisible by length */ |
| @@ -1153,7 +1164,9 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge) | |||
| 1153 | } | 1164 | } |
| 1154 | } else { | 1165 | } else { |
| 1155 | /* in the same range */ | 1166 | /* in the same range */ |
| 1156 | if ((len_tmp = res_cur->start - 1 - res_prev->end - 1) >= res->len) { | 1167 | len_tmp = res_cur->start - 1 - res_prev->end - 1; |
| 1168 | |||
| 1169 | if (len_tmp >= res->len) { | ||
| 1157 | if ((len_tmp < len_cur) || (len_cur == 0)) { | 1170 | if ((len_tmp < len_cur) || (len_cur == 0)) { |
| 1158 | if (((res_prev->end + 1) % tmp_divide) == 0) { | 1171 | if (((res_prev->end + 1) % tmp_divide) == 0) { |
| 1159 | /* just perfect, starting address's divisible by length */ | 1172 | /* just perfect, starting address's divisible by length */ |
| @@ -1212,7 +1225,9 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge) | |||
| 1212 | break; | 1225 | break; |
| 1213 | } | 1226 | } |
| 1214 | while (range) { | 1227 | while (range) { |
| 1215 | if ((len_tmp = range->end - range->start) >= res->len) { | 1228 | len_tmp = range->end - range->start; |
| 1229 | |||
| 1230 | if (len_tmp >= res->len) { | ||
| 1216 | if ((len_tmp < len_cur) || (len_cur == 0)) { | 1231 | if ((len_tmp < len_cur) || (len_cur == 0)) { |
| 1217 | if ((range->start % tmp_divide) == 0) { | 1232 | if ((range->start % tmp_divide) == 0) { |
| 1218 | /* just perfect, starting address's divisible by length */ | 1233 | /* just perfect, starting address's divisible by length */ |
| @@ -1276,7 +1291,9 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge) | |||
| 1276 | break; | 1291 | break; |
| 1277 | } | 1292 | } |
| 1278 | while (range) { | 1293 | while (range) { |
| 1279 | if ((len_tmp = range->end - range->start) >= res->len) { | 1294 | len_tmp = range->end - range->start; |
| 1295 | |||
| 1296 | if (len_tmp >= res->len) { | ||
| 1280 | if ((len_tmp < len_cur) || (len_cur == 0)) { | 1297 | if ((len_tmp < len_cur) || (len_cur == 0)) { |
| 1281 | if ((range->start % tmp_divide) == 0) { | 1298 | if ((range->start % tmp_divide) == 0) { |
| 1282 | /* just perfect, starting address's divisible by length */ | 1299 | /* just perfect, starting address's divisible by length */ |
| @@ -1335,7 +1352,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge) | |||
| 1335 | return -EINVAL; | 1352 | return -EINVAL; |
| 1336 | } | 1353 | } |
| 1337 | } | 1354 | } |
| 1338 | } /* end if(!res_cur) */ | 1355 | } /* end if (!res_cur) */ |
| 1339 | return -EINVAL; | 1356 | return -EINVAL; |
| 1340 | } | 1357 | } |
| 1341 | 1358 | ||
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 9e5a9fbb93d7..b11521953485 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
| @@ -92,7 +92,7 @@ struct controller { | |||
| 92 | struct slot *slot; | 92 | struct slot *slot; |
| 93 | wait_queue_head_t queue; /* sleep & wake process */ | 93 | wait_queue_head_t queue; /* sleep & wake process */ |
| 94 | u32 slot_cap; | 94 | u32 slot_cap; |
| 95 | u32 slot_ctrl; | 95 | u16 slot_ctrl; |
| 96 | struct timer_list poll_timer; | 96 | struct timer_list poll_timer; |
| 97 | unsigned long cmd_started; /* jiffies */ | 97 | unsigned long cmd_started; /* jiffies */ |
| 98 | unsigned int cmd_busy:1; | 98 | unsigned int cmd_busy:1; |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 07aa722bb12c..3a5e7e28b874 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
| @@ -262,6 +262,13 @@ static int pciehp_probe(struct pcie_device *dev) | |||
| 262 | goto err_out_none; | 262 | goto err_out_none; |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | if (!dev->port->subordinate) { | ||
| 266 | /* Can happen if we run out of bus numbers during probe */ | ||
| 267 | dev_err(&dev->device, | ||
| 268 | "Hotplug bridge without secondary bus, ignoring\n"); | ||
| 269 | goto err_out_none; | ||
| 270 | } | ||
| 271 | |||
| 265 | ctrl = pcie_init(dev); | 272 | ctrl = pcie_init(dev); |
| 266 | if (!ctrl) { | 273 | if (!ctrl) { |
| 267 | dev_err(&dev->device, "Controller initialization failed\n"); | 274 | dev_err(&dev->device, "Controller initialization failed\n"); |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 2a412fa3b338..0ebf754fc177 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
| @@ -171,9 +171,9 @@ static void pcie_wait_cmd(struct controller *ctrl) | |||
| 171 | * interrupts. | 171 | * interrupts. |
| 172 | */ | 172 | */ |
| 173 | if (!rc) | 173 | if (!rc) |
| 174 | ctrl_info(ctrl, "Timeout on hotplug command %#010x (issued %u msec ago)\n", | 174 | ctrl_info(ctrl, "Timeout on hotplug command %#06x (issued %u msec ago)\n", |
| 175 | ctrl->slot_ctrl, | 175 | ctrl->slot_ctrl, |
| 176 | jiffies_to_msecs(now - ctrl->cmd_started)); | 176 | jiffies_to_msecs(jiffies - ctrl->cmd_started)); |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | /** | 179 | /** |
| @@ -422,9 +422,9 @@ void pciehp_set_attention_status(struct slot *slot, u8 value) | |||
| 422 | default: | 422 | default: |
| 423 | return; | 423 | return; |
| 424 | } | 424 | } |
| 425 | pcie_write_cmd(ctrl, slot_cmd, PCI_EXP_SLTCTL_AIC); | ||
| 425 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | 426 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
| 426 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); | 427 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
| 427 | pcie_write_cmd(ctrl, slot_cmd, PCI_EXP_SLTCTL_AIC); | ||
| 428 | } | 428 | } |
| 429 | 429 | ||
| 430 | void pciehp_green_led_on(struct slot *slot) | 430 | void pciehp_green_led_on(struct slot *slot) |
| @@ -614,6 +614,8 @@ void pcie_enable_notification(struct controller *ctrl) | |||
| 614 | PCI_EXP_SLTCTL_DLLSCE); | 614 | PCI_EXP_SLTCTL_DLLSCE); |
| 615 | 615 | ||
| 616 | pcie_write_cmd(ctrl, cmd, mask); | 616 | pcie_write_cmd(ctrl, cmd, mask); |
| 617 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | ||
| 618 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, cmd); | ||
| 617 | } | 619 | } |
| 618 | 620 | ||
| 619 | static void pcie_disable_notification(struct controller *ctrl) | 621 | static void pcie_disable_notification(struct controller *ctrl) |
| @@ -625,6 +627,8 @@ static void pcie_disable_notification(struct controller *ctrl) | |||
| 625 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE | | 627 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE | |
| 626 | PCI_EXP_SLTCTL_DLLSCE); | 628 | PCI_EXP_SLTCTL_DLLSCE); |
| 627 | pcie_write_cmd(ctrl, 0, mask); | 629 | pcie_write_cmd(ctrl, 0, mask); |
| 630 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | ||
| 631 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, 0); | ||
| 628 | } | 632 | } |
| 629 | 633 | ||
| 630 | /* | 634 | /* |
| @@ -652,6 +656,8 @@ int pciehp_reset_slot(struct slot *slot, int probe) | |||
| 652 | stat_mask |= PCI_EXP_SLTSTA_DLLSC; | 656 | stat_mask |= PCI_EXP_SLTSTA_DLLSC; |
| 653 | 657 | ||
| 654 | pcie_write_cmd(ctrl, 0, ctrl_mask); | 658 | pcie_write_cmd(ctrl, 0, ctrl_mask); |
| 659 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | ||
| 660 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, 0); | ||
| 655 | if (pciehp_poll_mode) | 661 | if (pciehp_poll_mode) |
| 656 | del_timer_sync(&ctrl->poll_timer); | 662 | del_timer_sync(&ctrl->poll_timer); |
| 657 | 663 | ||
| @@ -659,6 +665,8 @@ int pciehp_reset_slot(struct slot *slot, int probe) | |||
| 659 | 665 | ||
| 660 | pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, stat_mask); | 666 | pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, stat_mask); |
| 661 | pcie_write_cmd(ctrl, ctrl_mask, ctrl_mask); | 667 | pcie_write_cmd(ctrl, ctrl_mask, ctrl_mask); |
| 668 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | ||
| 669 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, ctrl_mask); | ||
| 662 | if (pciehp_poll_mode) | 670 | if (pciehp_poll_mode) |
| 663 | int_poll_timeout(ctrl->poll_timer.data); | 671 | int_poll_timeout(ctrl->poll_timer.data); |
| 664 | 672 | ||
| @@ -797,9 +805,6 @@ struct controller *pcie_init(struct pcie_device *dev) | |||
| 797 | PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | | 805 | PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | |
| 798 | PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC); | 806 | PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC); |
| 799 | 807 | ||
| 800 | /* Disable software notification */ | ||
| 801 | pcie_disable_notification(ctrl); | ||
| 802 | |||
| 803 | ctrl_info(ctrl, "Slot #%d AttnBtn%c AttnInd%c PwrInd%c PwrCtrl%c MRL%c Interlock%c NoCompl%c LLActRep%c\n", | 808 | ctrl_info(ctrl, "Slot #%d AttnBtn%c AttnInd%c PwrInd%c PwrCtrl%c MRL%c Interlock%c NoCompl%c LLActRep%c\n", |
| 804 | (slot_cap & PCI_EXP_SLTCAP_PSN) >> 19, | 809 | (slot_cap & PCI_EXP_SLTCAP_PSN) >> 19, |
| 805 | FLAG(slot_cap, PCI_EXP_SLTCAP_ABP), | 810 | FLAG(slot_cap, PCI_EXP_SLTCAP_ABP), |
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 5f871f4c4af1..9e69403be632 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c | |||
| @@ -65,14 +65,7 @@ int pciehp_configure_device(struct slot *p_slot) | |||
| 65 | pci_hp_add_bridge(dev); | 65 | pci_hp_add_bridge(dev); |
| 66 | 66 | ||
| 67 | pci_assign_unassigned_bridge_resources(bridge); | 67 | pci_assign_unassigned_bridge_resources(bridge); |
| 68 | 68 | pcie_bus_configure_settings(parent); | |
| 69 | list_for_each_entry(dev, &parent->devices, bus_list) { | ||
| 70 | if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) | ||
| 71 | continue; | ||
| 72 | |||
| 73 | pci_configure_slot(dev); | ||
| 74 | } | ||
| 75 | |||
| 76 | pci_bus_add_devices(parent); | 69 | pci_bus_add_devices(parent); |
| 77 | 70 | ||
| 78 | out: | 71 | out: |
diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c deleted file mode 100644 index 3e36ec8d708a..000000000000 --- a/drivers/pci/hotplug/pcihp_slot.c +++ /dev/null | |||
| @@ -1,176 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 1995,2001 Compaq Computer Corporation | ||
| 3 | * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) | ||
| 4 | * Copyright (C) 2001 IBM Corp. | ||
| 5 | * Copyright (C) 2003-2004 Intel Corporation | ||
| 6 | * (c) Copyright 2009 Hewlett-Packard Development Company, L.P. | ||
| 7 | * | ||
| 8 | * All rights reserved. | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or (at | ||
| 13 | * your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, but | ||
| 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
| 18 | * NON INFRINGEMENT. See the GNU General Public License for more | ||
| 19 | * details. | ||
| 20 | * | ||
| 21 | * You should have received a copy of the GNU General Public License | ||
| 22 | * along with this program; if not, write to the Free Software | ||
| 23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/pci.h> | ||
| 27 | #include <linux/export.h> | ||
| 28 | #include <linux/pci_hotplug.h> | ||
| 29 | |||
| 30 | static struct hpp_type0 pci_default_type0 = { | ||
| 31 | .revision = 1, | ||
| 32 | .cache_line_size = 8, | ||
| 33 | .latency_timer = 0x40, | ||
| 34 | .enable_serr = 0, | ||
| 35 | .enable_perr = 0, | ||
| 36 | }; | ||
| 37 | |||
| 38 | static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp) | ||
| 39 | { | ||
| 40 | u16 pci_cmd, pci_bctl; | ||
| 41 | |||
| 42 | if (!hpp) { | ||
| 43 | /* | ||
| 44 | * Perhaps we *should* use default settings for PCIe, but | ||
| 45 | * pciehp didn't, so we won't either. | ||
| 46 | */ | ||
| 47 | if (pci_is_pcie(dev)) | ||
| 48 | return; | ||
| 49 | hpp = &pci_default_type0; | ||
| 50 | } | ||
| 51 | |||
| 52 | if (hpp->revision > 1) { | ||
| 53 | dev_warn(&dev->dev, | ||
| 54 | "PCI settings rev %d not supported; using defaults\n", | ||
| 55 | hpp->revision); | ||
| 56 | hpp = &pci_default_type0; | ||
| 57 | } | ||
| 58 | |||
| 59 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp->cache_line_size); | ||
| 60 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp->latency_timer); | ||
| 61 | pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); | ||
| 62 | if (hpp->enable_serr) | ||
| 63 | pci_cmd |= PCI_COMMAND_SERR; | ||
| 64 | else | ||
| 65 | pci_cmd &= ~PCI_COMMAND_SERR; | ||
| 66 | if (hpp->enable_perr) | ||
| 67 | pci_cmd |= PCI_COMMAND_PARITY; | ||
| 68 | else | ||
| 69 | pci_cmd &= ~PCI_COMMAND_PARITY; | ||
| 70 | pci_write_config_word(dev, PCI_COMMAND, pci_cmd); | ||
| 71 | |||
| 72 | /* Program bridge control value */ | ||
| 73 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { | ||
| 74 | pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, | ||
| 75 | hpp->latency_timer); | ||
| 76 | pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); | ||
| 77 | if (hpp->enable_serr) | ||
| 78 | pci_bctl |= PCI_BRIDGE_CTL_SERR; | ||
| 79 | else | ||
| 80 | pci_bctl &= ~PCI_BRIDGE_CTL_SERR; | ||
| 81 | if (hpp->enable_perr) | ||
| 82 | pci_bctl |= PCI_BRIDGE_CTL_PARITY; | ||
| 83 | else | ||
| 84 | pci_bctl &= ~PCI_BRIDGE_CTL_PARITY; | ||
| 85 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl); | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp) | ||
| 90 | { | ||
| 91 | if (hpp) | ||
| 92 | dev_warn(&dev->dev, "PCI-X settings not supported\n"); | ||
| 93 | } | ||
| 94 | |||
| 95 | static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) | ||
| 96 | { | ||
| 97 | int pos; | ||
| 98 | u32 reg32; | ||
| 99 | |||
| 100 | if (!hpp) | ||
| 101 | return; | ||
| 102 | |||
| 103 | if (hpp->revision > 1) { | ||
| 104 | dev_warn(&dev->dev, "PCIe settings rev %d not supported\n", | ||
| 105 | hpp->revision); | ||
| 106 | return; | ||
| 107 | } | ||
| 108 | |||
| 109 | /* Initialize Device Control Register */ | ||
| 110 | pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, | ||
| 111 | ~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or); | ||
| 112 | |||
| 113 | /* Initialize Link Control Register */ | ||
| 114 | if (dev->subordinate) | ||
| 115 | pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL, | ||
| 116 | ~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or); | ||
| 117 | |||
| 118 | /* Find Advanced Error Reporting Enhanced Capability */ | ||
| 119 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | ||
| 120 | if (!pos) | ||
| 121 | return; | ||
| 122 | |||
| 123 | /* Initialize Uncorrectable Error Mask Register */ | ||
| 124 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, ®32); | ||
| 125 | reg32 = (reg32 & hpp->unc_err_mask_and) | hpp->unc_err_mask_or; | ||
| 126 | pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, reg32); | ||
| 127 | |||
| 128 | /* Initialize Uncorrectable Error Severity Register */ | ||
| 129 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, ®32); | ||
| 130 | reg32 = (reg32 & hpp->unc_err_sever_and) | hpp->unc_err_sever_or; | ||
| 131 | pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, reg32); | ||
| 132 | |||
| 133 | /* Initialize Correctable Error Mask Register */ | ||
| 134 | pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, ®32); | ||
| 135 | reg32 = (reg32 & hpp->cor_err_mask_and) | hpp->cor_err_mask_or; | ||
| 136 | pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg32); | ||
| 137 | |||
| 138 | /* Initialize Advanced Error Capabilities and Control Register */ | ||
| 139 | pci_read_config_dword(dev, pos + PCI_ERR_CAP, ®32); | ||
| 140 | reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or; | ||
| 141 | pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32); | ||
| 142 | |||
| 143 | /* | ||
| 144 | * FIXME: The following two registers are not supported yet. | ||
| 145 | * | ||
| 146 | * o Secondary Uncorrectable Error Severity Register | ||
| 147 | * o Secondary Uncorrectable Error Mask Register | ||
| 148 | */ | ||
| 149 | } | ||
| 150 | |||
| 151 | void pci_configure_slot(struct pci_dev *dev) | ||
| 152 | { | ||
| 153 | struct pci_dev *cdev; | ||
| 154 | struct hotplug_params hpp; | ||
| 155 | |||
| 156 | if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL || | ||
| 157 | (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && | ||
| 158 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) | ||
| 159 | return; | ||
| 160 | |||
| 161 | pcie_bus_configure_settings(dev->bus); | ||
| 162 | |||
| 163 | memset(&hpp, 0, sizeof(hpp)); | ||
| 164 | pci_get_hp_params(dev, &hpp); | ||
| 165 | |||
| 166 | program_hpp_type2(dev, hpp.t2); | ||
| 167 | program_hpp_type1(dev, hpp.t1); | ||
| 168 | program_hpp_type0(dev, hpp.t0); | ||
| 169 | |||
| 170 | if (dev->subordinate) { | ||
| 171 | list_for_each_entry(cdev, &dev->subordinate->devices, | ||
| 172 | bus_list) | ||
| 173 | pci_configure_slot(cdev); | ||
| 174 | } | ||
| 175 | } | ||
| 176 | EXPORT_SYMBOL_GPL(pci_configure_slot); | ||
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index a81fb67ea9a1..10c7927599b3 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c | |||
| @@ -195,7 +195,8 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot, | |||
| 195 | int rc = 0; | 195 | int rc = 0; |
| 196 | 196 | ||
| 197 | ctrl_dbg(ctrl, "Change speed to %d\n", speed); | 197 | ctrl_dbg(ctrl, "Change speed to %d\n", speed); |
| 198 | if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed))) { | 198 | rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed); |
| 199 | if (rc) { | ||
| 199 | ctrl_err(ctrl, "%s: Issue of set bus speed mode command failed\n", | 200 | ctrl_err(ctrl, "%s: Issue of set bus speed mode command failed\n", |
| 200 | __func__); | 201 | __func__); |
| 201 | return WRONG_BUS_FREQUENCY; | 202 | return WRONG_BUS_FREQUENCY; |
| @@ -261,14 +262,16 @@ static int board_added(struct slot *p_slot) | |||
| 261 | } | 262 | } |
| 262 | 263 | ||
| 263 | if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) { | 264 | if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) { |
| 264 | if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) { | 265 | rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz); |
| 266 | if (rc) { | ||
| 265 | ctrl_err(ctrl, "%s: Issue of set bus speed mode command failed\n", | 267 | ctrl_err(ctrl, "%s: Issue of set bus speed mode command failed\n", |
| 266 | __func__); | 268 | __func__); |
| 267 | return WRONG_BUS_FREQUENCY; | 269 | return WRONG_BUS_FREQUENCY; |
| 268 | } | 270 | } |
| 269 | 271 | ||
| 270 | /* turn on board, blink green LED, turn off Amber LED */ | 272 | /* turn on board, blink green LED, turn off Amber LED */ |
| 271 | if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { | 273 | rc = p_slot->hpc_ops->slot_enable(p_slot); |
| 274 | if (rc) { | ||
| 272 | ctrl_err(ctrl, "Issue of Slot Enable command failed\n"); | 275 | ctrl_err(ctrl, "Issue of Slot Enable command failed\n"); |
| 273 | return rc; | 276 | return rc; |
| 274 | } | 277 | } |
| @@ -296,7 +299,8 @@ static int board_added(struct slot *p_slot) | |||
| 296 | return rc; | 299 | return rc; |
| 297 | 300 | ||
| 298 | /* turn on board, blink green LED, turn off Amber LED */ | 301 | /* turn on board, blink green LED, turn off Amber LED */ |
| 299 | if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { | 302 | rc = p_slot->hpc_ops->slot_enable(p_slot); |
| 303 | if (rc) { | ||
| 300 | ctrl_err(ctrl, "Issue of Slot Enable command failed\n"); | 304 | ctrl_err(ctrl, "Issue of Slot Enable command failed\n"); |
| 301 | return rc; | 305 | return rc; |
| 302 | } | 306 | } |
| @@ -595,7 +599,7 @@ static int shpchp_enable_slot (struct slot *p_slot) | |||
| 595 | ctrl_dbg(ctrl, "%s: p_slot->pwr_save %x\n", __func__, p_slot->pwr_save); | 599 | ctrl_dbg(ctrl, "%s: p_slot->pwr_save %x\n", __func__, p_slot->pwr_save); |
| 596 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 600 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
| 597 | 601 | ||
| 598 | if(((p_slot->ctrl->pci_dev->vendor == PCI_VENDOR_ID_AMD) || | 602 | if (((p_slot->ctrl->pci_dev->vendor == PCI_VENDOR_ID_AMD) || |
| 599 | (p_slot->ctrl->pci_dev->device == PCI_DEVICE_ID_AMD_POGO_7458)) | 603 | (p_slot->ctrl->pci_dev->device == PCI_DEVICE_ID_AMD_POGO_7458)) |
| 600 | && p_slot->ctrl->num_slots == 1) { | 604 | && p_slot->ctrl->num_slots == 1) { |
| 601 | /* handle amd pogo errata; this must be done before enable */ | 605 | /* handle amd pogo errata; this must be done before enable */ |
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 29e22352822c..7d223e9080ef 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
| @@ -466,7 +466,8 @@ static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) | |||
| 466 | u8 m66_cap = !!(slot_reg & MHZ66_CAP); | 466 | u8 m66_cap = !!(slot_reg & MHZ66_CAP); |
| 467 | u8 pi, pcix_cap; | 467 | u8 pi, pcix_cap; |
| 468 | 468 | ||
| 469 | if ((retval = hpc_get_prog_int(slot, &pi))) | 469 | retval = hpc_get_prog_int(slot, &pi); |
| 470 | if (retval) | ||
| 470 | return retval; | 471 | return retval; |
| 471 | 472 | ||
| 472 | switch (pi) { | 473 | switch (pi) { |
| @@ -798,7 +799,7 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) | |||
| 798 | 799 | ||
| 799 | ctrl_dbg(ctrl, "%s: intr_loc = %x\n", __func__, intr_loc); | 800 | ctrl_dbg(ctrl, "%s: intr_loc = %x\n", __func__, intr_loc); |
| 800 | 801 | ||
| 801 | if(!shpchp_poll_mode) { | 802 | if (!shpchp_poll_mode) { |
| 802 | /* | 803 | /* |
| 803 | * Mask Global Interrupt Mask - see implementation | 804 | * Mask Global Interrupt Mask - see implementation |
| 804 | * note on p. 139 of SHPC spec rev 1.0 | 805 | * note on p. 139 of SHPC spec rev 1.0 |
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index 469454e0cc48..f8cd3a27e351 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c | |||
| @@ -69,13 +69,7 @@ int shpchp_configure_device(struct slot *p_slot) | |||
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | pci_assign_unassigned_bridge_resources(bridge); | 71 | pci_assign_unassigned_bridge_resources(bridge); |
| 72 | 72 | pcie_bus_configure_settings(parent); | |
| 73 | list_for_each_entry(dev, &parent->devices, bus_list) { | ||
| 74 | if (PCI_SLOT(dev->devfn) != p_slot->device) | ||
| 75 | continue; | ||
| 76 | pci_configure_slot(dev); | ||
| 77 | } | ||
| 78 | |||
| 79 | pci_bus_add_devices(parent); | 73 | pci_bus_add_devices(parent); |
| 80 | 74 | ||
| 81 | out: | 75 | out: |
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index cb6f24740ee3..4d109c07294a 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
| @@ -633,7 +633,7 @@ int pci_vfs_assigned(struct pci_dev *dev) | |||
| 633 | * our dev as the physical function and the assigned bit is set | 633 | * our dev as the physical function and the assigned bit is set |
| 634 | */ | 634 | */ |
| 635 | if (vfdev->is_virtfn && (vfdev->physfn == dev) && | 635 | if (vfdev->is_virtfn && (vfdev->physfn == dev) && |
| 636 | (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)) | 636 | pci_is_dev_assigned(vfdev)) |
| 637 | vfs_assigned++; | 637 | vfs_assigned++; |
| 638 | 638 | ||
| 639 | vfdev = pci_get_device(dev->vendor, dev_id, vfdev); | 639 | vfdev = pci_get_device(dev->vendor, dev_id, vfdev); |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 5a40516444f3..2f7c92c4757a 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
| @@ -56,16 +56,6 @@ void __weak arch_teardown_msi_irq(unsigned int irq) | |||
| 56 | chip->teardown_irq(chip, irq); | 56 | chip->teardown_irq(chip, irq); |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | int __weak arch_msi_check_device(struct pci_dev *dev, int nvec, int type) | ||
| 60 | { | ||
| 61 | struct msi_chip *chip = dev->bus->msi; | ||
| 62 | |||
| 63 | if (!chip || !chip->check_device) | ||
| 64 | return 0; | ||
| 65 | |||
| 66 | return chip->check_device(chip, dev, nvec, type); | ||
| 67 | } | ||
| 68 | |||
| 69 | int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | 59 | int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) |
| 70 | { | 60 | { |
| 71 | struct msi_desc *entry; | 61 | struct msi_desc *entry; |
| @@ -130,7 +120,7 @@ static void default_restore_msi_irq(struct pci_dev *dev, int irq) | |||
| 130 | } | 120 | } |
| 131 | 121 | ||
| 132 | if (entry) | 122 | if (entry) |
| 133 | write_msi_msg(irq, &entry->msg); | 123 | __write_msi_msg(entry, &entry->msg); |
| 134 | } | 124 | } |
| 135 | 125 | ||
| 136 | void __weak arch_restore_msi_irqs(struct pci_dev *dev) | 126 | void __weak arch_restore_msi_irqs(struct pci_dev *dev) |
| @@ -384,17 +374,6 @@ static void free_msi_irqs(struct pci_dev *dev) | |||
| 384 | iounmap(entry->mask_base); | 374 | iounmap(entry->mask_base); |
| 385 | } | 375 | } |
| 386 | 376 | ||
| 387 | /* | ||
| 388 | * Its possible that we get into this path | ||
| 389 | * When populate_msi_sysfs fails, which means the entries | ||
| 390 | * were not registered with sysfs. In that case don't | ||
| 391 | * unregister them. | ||
| 392 | */ | ||
| 393 | if (entry->kobj.parent) { | ||
| 394 | kobject_del(&entry->kobj); | ||
| 395 | kobject_put(&entry->kobj); | ||
| 396 | } | ||
| 397 | |||
| 398 | list_del(&entry->list); | 377 | list_del(&entry->list); |
| 399 | kfree(entry); | 378 | kfree(entry); |
| 400 | } | 379 | } |
| @@ -595,7 +574,6 @@ static struct msi_desc *msi_setup_entry(struct pci_dev *dev) | |||
| 595 | entry->msi_attrib.entry_nr = 0; | 574 | entry->msi_attrib.entry_nr = 0; |
| 596 | entry->msi_attrib.maskbit = !!(control & PCI_MSI_FLAGS_MASKBIT); | 575 | entry->msi_attrib.maskbit = !!(control & PCI_MSI_FLAGS_MASKBIT); |
| 597 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ | 576 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ |
| 598 | entry->msi_attrib.pos = dev->msi_cap; | ||
| 599 | entry->msi_attrib.multi_cap = (control & PCI_MSI_FLAGS_QMASK) >> 1; | 577 | entry->msi_attrib.multi_cap = (control & PCI_MSI_FLAGS_QMASK) >> 1; |
| 600 | 578 | ||
| 601 | if (control & PCI_MSI_FLAGS_64BIT) | 579 | if (control & PCI_MSI_FLAGS_64BIT) |
| @@ -699,7 +677,6 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, | |||
| 699 | entry->msi_attrib.is_64 = 1; | 677 | entry->msi_attrib.is_64 = 1; |
| 700 | entry->msi_attrib.entry_nr = entries[i].entry; | 678 | entry->msi_attrib.entry_nr = entries[i].entry; |
| 701 | entry->msi_attrib.default_irq = dev->irq; | 679 | entry->msi_attrib.default_irq = dev->irq; |
| 702 | entry->msi_attrib.pos = dev->msix_cap; | ||
| 703 | entry->mask_base = base; | 680 | entry->mask_base = base; |
| 704 | 681 | ||
| 705 | list_add_tail(&entry->list, &dev->msi_list); | 682 | list_add_tail(&entry->list, &dev->msi_list); |
| @@ -806,23 +783,24 @@ out_free: | |||
| 806 | } | 783 | } |
| 807 | 784 | ||
| 808 | /** | 785 | /** |
| 809 | * pci_msi_check_device - check whether MSI may be enabled on a device | 786 | * pci_msi_supported - check whether MSI may be enabled on a device |
| 810 | * @dev: pointer to the pci_dev data structure of MSI device function | 787 | * @dev: pointer to the pci_dev data structure of MSI device function |
| 811 | * @nvec: how many MSIs have been requested ? | 788 | * @nvec: how many MSIs have been requested ? |
| 812 | * @type: are we checking for MSI or MSI-X ? | ||
| 813 | * | 789 | * |
| 814 | * Look at global flags, the device itself, and its parent buses | 790 | * Look at global flags, the device itself, and its parent buses |
| 815 | * to determine if MSI/-X are supported for the device. If MSI/-X is | 791 | * to determine if MSI/-X are supported for the device. If MSI/-X is |
| 816 | * supported return 0, else return an error code. | 792 | * supported return 1, else return 0. |
| 817 | **/ | 793 | **/ |
| 818 | static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) | 794 | static int pci_msi_supported(struct pci_dev *dev, int nvec) |
| 819 | { | 795 | { |
| 820 | struct pci_bus *bus; | 796 | struct pci_bus *bus; |
| 821 | int ret; | ||
| 822 | 797 | ||
| 823 | /* MSI must be globally enabled and supported by the device */ | 798 | /* MSI must be globally enabled and supported by the device */ |
| 824 | if (!pci_msi_enable || !dev || dev->no_msi) | 799 | if (!pci_msi_enable) |
| 825 | return -EINVAL; | 800 | return 0; |
| 801 | |||
| 802 | if (!dev || dev->no_msi || dev->current_state != PCI_D0) | ||
| 803 | return 0; | ||
| 826 | 804 | ||
| 827 | /* | 805 | /* |
| 828 | * You can't ask to have 0 or less MSIs configured. | 806 | * You can't ask to have 0 or less MSIs configured. |
| @@ -830,7 +808,7 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) | |||
| 830 | * b) the list manipulation code assumes nvec >= 1. | 808 | * b) the list manipulation code assumes nvec >= 1. |
| 831 | */ | 809 | */ |
| 832 | if (nvec < 1) | 810 | if (nvec < 1) |
| 833 | return -ERANGE; | 811 | return 0; |
| 834 | 812 | ||
| 835 | /* | 813 | /* |
| 836 | * Any bridge which does NOT route MSI transactions from its | 814 | * Any bridge which does NOT route MSI transactions from its |
| @@ -841,13 +819,9 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) | |||
| 841 | */ | 819 | */ |
| 842 | for (bus = dev->bus; bus; bus = bus->parent) | 820 | for (bus = dev->bus; bus; bus = bus->parent) |
| 843 | if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) | 821 | if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) |
| 844 | return -EINVAL; | 822 | return 0; |
| 845 | |||
| 846 | ret = arch_msi_check_device(dev, nvec, type); | ||
| 847 | if (ret) | ||
| 848 | return ret; | ||
| 849 | 823 | ||
| 850 | return 0; | 824 | return 1; |
| 851 | } | 825 | } |
| 852 | 826 | ||
| 853 | /** | 827 | /** |
| @@ -946,15 +920,14 @@ EXPORT_SYMBOL(pci_msix_vec_count); | |||
| 946 | **/ | 920 | **/ |
| 947 | int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) | 921 | int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) |
| 948 | { | 922 | { |
| 949 | int status, nr_entries; | 923 | int nr_entries; |
| 950 | int i, j; | 924 | int i, j; |
| 951 | 925 | ||
| 952 | if (!entries || !dev->msix_cap || dev->current_state != PCI_D0) | 926 | if (!pci_msi_supported(dev, nvec)) |
| 953 | return -EINVAL; | 927 | return -EINVAL; |
| 954 | 928 | ||
| 955 | status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSIX); | 929 | if (!entries) |
| 956 | if (status) | 930 | return -EINVAL; |
| 957 | return status; | ||
| 958 | 931 | ||
| 959 | nr_entries = pci_msix_vec_count(dev); | 932 | nr_entries = pci_msix_vec_count(dev); |
| 960 | if (nr_entries < 0) | 933 | if (nr_entries < 0) |
| @@ -978,8 +951,7 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) | |||
| 978 | dev_info(&dev->dev, "can't enable MSI-X (MSI IRQ already assigned)\n"); | 951 | dev_info(&dev->dev, "can't enable MSI-X (MSI IRQ already assigned)\n"); |
| 979 | return -EINVAL; | 952 | return -EINVAL; |
| 980 | } | 953 | } |
| 981 | status = msix_capability_init(dev, entries, nvec); | 954 | return msix_capability_init(dev, entries, nvec); |
| 982 | return status; | ||
| 983 | } | 955 | } |
| 984 | EXPORT_SYMBOL(pci_enable_msix); | 956 | EXPORT_SYMBOL(pci_enable_msix); |
| 985 | 957 | ||
| @@ -1062,7 +1034,7 @@ int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) | |||
| 1062 | int nvec; | 1034 | int nvec; |
| 1063 | int rc; | 1035 | int rc; |
| 1064 | 1036 | ||
| 1065 | if (dev->current_state != PCI_D0) | 1037 | if (!pci_msi_supported(dev, minvec)) |
| 1066 | return -EINVAL; | 1038 | return -EINVAL; |
| 1067 | 1039 | ||
| 1068 | WARN_ON(!!dev->msi_enabled); | 1040 | WARN_ON(!!dev->msi_enabled); |
| @@ -1086,17 +1058,6 @@ int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) | |||
| 1086 | nvec = maxvec; | 1058 | nvec = maxvec; |
| 1087 | 1059 | ||
| 1088 | do { | 1060 | do { |
| 1089 | rc = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSI); | ||
| 1090 | if (rc < 0) { | ||
| 1091 | return rc; | ||
| 1092 | } else if (rc > 0) { | ||
| 1093 | if (rc < minvec) | ||
| 1094 | return -ENOSPC; | ||
| 1095 | nvec = rc; | ||
| 1096 | } | ||
| 1097 | } while (rc); | ||
| 1098 | |||
| 1099 | do { | ||
| 1100 | rc = msi_capability_init(dev, nvec); | 1061 | rc = msi_capability_init(dev, nvec); |
| 1101 | if (rc < 0) { | 1062 | if (rc < 0) { |
| 1102 | return rc; | 1063 | return rc; |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 37263b0ebfe3..6ebf8edc5f3c 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
| 11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
| 12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
| 13 | #include <linux/pci_hotplug.h> | ||
| 13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 14 | #include <linux/pci-aspm.h> | 15 | #include <linux/pci-aspm.h> |
| 15 | #include <linux/pci-acpi.h> | 16 | #include <linux/pci-acpi.h> |
| @@ -17,6 +18,267 @@ | |||
| 17 | #include <linux/pm_qos.h> | 18 | #include <linux/pm_qos.h> |
| 18 | #include "pci.h" | 19 | #include "pci.h" |
| 19 | 20 | ||
| 21 | phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) | ||
| 22 | { | ||
| 23 | acpi_status status = AE_NOT_EXIST; | ||
| 24 | unsigned long long mcfg_addr; | ||
| 25 | |||
| 26 | if (handle) | ||
| 27 | status = acpi_evaluate_integer(handle, METHOD_NAME__CBA, | ||
| 28 | NULL, &mcfg_addr); | ||
| 29 | if (ACPI_FAILURE(status)) | ||
| 30 | return 0; | ||
| 31 | |||
| 32 | return (phys_addr_t)mcfg_addr; | ||
| 33 | } | ||
| 34 | |||
| 35 | static acpi_status decode_type0_hpx_record(union acpi_object *record, | ||
| 36 | struct hotplug_params *hpx) | ||
| 37 | { | ||
| 38 | int i; | ||
| 39 | union acpi_object *fields = record->package.elements; | ||
| 40 | u32 revision = fields[1].integer.value; | ||
| 41 | |||
| 42 | switch (revision) { | ||
| 43 | case 1: | ||
| 44 | if (record->package.count != 6) | ||
| 45 | return AE_ERROR; | ||
| 46 | for (i = 2; i < 6; i++) | ||
| 47 | if (fields[i].type != ACPI_TYPE_INTEGER) | ||
| 48 | return AE_ERROR; | ||
| 49 | hpx->t0 = &hpx->type0_data; | ||
| 50 | hpx->t0->revision = revision; | ||
| 51 | hpx->t0->cache_line_size = fields[2].integer.value; | ||
| 52 | hpx->t0->latency_timer = fields[3].integer.value; | ||
| 53 | hpx->t0->enable_serr = fields[4].integer.value; | ||
| 54 | hpx->t0->enable_perr = fields[5].integer.value; | ||
| 55 | break; | ||
| 56 | default: | ||
| 57 | printk(KERN_WARNING | ||
| 58 | "%s: Type 0 Revision %d record not supported\n", | ||
| 59 | __func__, revision); | ||
| 60 | return AE_ERROR; | ||
| 61 | } | ||
| 62 | return AE_OK; | ||
| 63 | } | ||
| 64 | |||
| 65 | static acpi_status decode_type1_hpx_record(union acpi_object *record, | ||
| 66 | struct hotplug_params *hpx) | ||
| 67 | { | ||
| 68 | int i; | ||
| 69 | union acpi_object *fields = record->package.elements; | ||
| 70 | u32 revision = fields[1].integer.value; | ||
| 71 | |||
| 72 | switch (revision) { | ||
| 73 | case 1: | ||
| 74 | if (record->package.count != 5) | ||
| 75 | return AE_ERROR; | ||
| 76 | for (i = 2; i < 5; i++) | ||
| 77 | if (fields[i].type != ACPI_TYPE_INTEGER) | ||
| 78 | return AE_ERROR; | ||
| 79 | hpx->t1 = &hpx->type1_data; | ||
| 80 | hpx->t1->revision = revision; | ||
| 81 | hpx->t1->max_mem_read = fields[2].integer.value; | ||
| 82 | hpx->t1->avg_max_split = fields[3].integer.value; | ||
| 83 | hpx->t1->tot_max_split = fields[4].integer.value; | ||
| 84 | break; | ||
| 85 | default: | ||
| 86 | printk(KERN_WARNING | ||
| 87 | "%s: Type 1 Revision %d record not supported\n", | ||
| 88 | __func__, revision); | ||
| 89 | return AE_ERROR; | ||
| 90 | } | ||
| 91 | return AE_OK; | ||
| 92 | } | ||
| 93 | |||
| 94 | static acpi_status decode_type2_hpx_record(union acpi_object *record, | ||
| 95 | struct hotplug_params *hpx) | ||
| 96 | { | ||
| 97 | int i; | ||
| 98 | union acpi_object *fields = record->package.elements; | ||
| 99 | u32 revision = fields[1].integer.value; | ||
| 100 | |||
| 101 | switch (revision) { | ||
| 102 | case 1: | ||
| 103 | if (record->package.count != 18) | ||
| 104 | return AE_ERROR; | ||
| 105 | for (i = 2; i < 18; i++) | ||
| 106 | if (fields[i].type != ACPI_TYPE_INTEGER) | ||
| 107 | return AE_ERROR; | ||
| 108 | hpx->t2 = &hpx->type2_data; | ||
| 109 | hpx->t2->revision = revision; | ||
| 110 | hpx->t2->unc_err_mask_and = fields[2].integer.value; | ||
| 111 | hpx->t2->unc_err_mask_or = fields[3].integer.value; | ||
| 112 | hpx->t2->unc_err_sever_and = fields[4].integer.value; | ||
| 113 | hpx->t2->unc_err_sever_or = fields[5].integer.value; | ||
| 114 | hpx->t2->cor_err_mask_and = fields[6].integer.value; | ||
| 115 | hpx->t2->cor_err_mask_or = fields[7].integer.value; | ||
| 116 | hpx->t2->adv_err_cap_and = fields[8].integer.value; | ||
| 117 | hpx->t2->adv_err_cap_or = fields[9].integer.value; | ||
| 118 | hpx->t2->pci_exp_devctl_and = fields[10].integer.value; | ||
| 119 | hpx->t2->pci_exp_devctl_or = fields[11].integer.value; | ||
| 120 | hpx->t2->pci_exp_lnkctl_and = fields[12].integer.value; | ||
| 121 | hpx->t2->pci_exp_lnkctl_or = fields[13].integer.value; | ||
| 122 | hpx->t2->sec_unc_err_sever_and = fields[14].integer.value; | ||
| 123 | hpx->t2->sec_unc_err_sever_or = fields[15].integer.value; | ||
| 124 | hpx->t2->sec_unc_err_mask_and = fields[16].integer.value; | ||
| 125 | hpx->t2->sec_unc_err_mask_or = fields[17].integer.value; | ||
| 126 | break; | ||
| 127 | default: | ||
| 128 | printk(KERN_WARNING | ||
| 129 | "%s: Type 2 Revision %d record not supported\n", | ||
| 130 | __func__, revision); | ||
| 131 | return AE_ERROR; | ||
| 132 | } | ||
| 133 | return AE_OK; | ||
| 134 | } | ||
| 135 | |||
| 136 | static acpi_status acpi_run_hpx(acpi_handle handle, struct hotplug_params *hpx) | ||
| 137 | { | ||
| 138 | acpi_status status; | ||
| 139 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
| 140 | union acpi_object *package, *record, *fields; | ||
| 141 | u32 type; | ||
| 142 | int i; | ||
| 143 | |||
| 144 | /* Clear the return buffer with zeros */ | ||
| 145 | memset(hpx, 0, sizeof(struct hotplug_params)); | ||
| 146 | |||
| 147 | status = acpi_evaluate_object(handle, "_HPX", NULL, &buffer); | ||
| 148 | if (ACPI_FAILURE(status)) | ||
| 149 | return status; | ||
| 150 | |||
| 151 | package = (union acpi_object *)buffer.pointer; | ||
| 152 | if (package->type != ACPI_TYPE_PACKAGE) { | ||
| 153 | status = AE_ERROR; | ||
| 154 | goto exit; | ||
| 155 | } | ||
| 156 | |||
| 157 | for (i = 0; i < package->package.count; i++) { | ||
| 158 | record = &package->package.elements[i]; | ||
| 159 | if (record->type != ACPI_TYPE_PACKAGE) { | ||
| 160 | status = AE_ERROR; | ||
| 161 | goto exit; | ||
| 162 | } | ||
| 163 | |||
| 164 | fields = record->package.elements; | ||
| 165 | if (fields[0].type != ACPI_TYPE_INTEGER || | ||
| 166 | fields[1].type != ACPI_TYPE_INTEGER) { | ||
| 167 | status = AE_ERROR; | ||
| 168 | goto exit; | ||
| 169 | } | ||
| 170 | |||
| 171 | type = fields[0].integer.value; | ||
| 172 | switch (type) { | ||
| 173 | case 0: | ||
| 174 | status = decode_type0_hpx_record(record, hpx); | ||
| 175 | if (ACPI_FAILURE(status)) | ||
| 176 | goto exit; | ||
| 177 | break; | ||
| 178 | case 1: | ||
| 179 | status = decode_type1_hpx_record(record, hpx); | ||
| 180 | if (ACPI_FAILURE(status)) | ||
| 181 | goto exit; | ||
| 182 | break; | ||
| 183 | case 2: | ||
| 184 | status = decode_type2_hpx_record(record, hpx); | ||
| 185 | if (ACPI_FAILURE(status)) | ||
| 186 | goto exit; | ||
| 187 | break; | ||
| 188 | default: | ||
| 189 | printk(KERN_ERR "%s: Type %d record not supported\n", | ||
| 190 | __func__, type); | ||
| 191 | status = AE_ERROR; | ||
| 192 | goto exit; | ||
| 193 | } | ||
| 194 | } | ||
| 195 | exit: | ||
| 196 | kfree(buffer.pointer); | ||
| 197 | return status; | ||
| 198 | } | ||
| 199 | |||
| 200 | static acpi_status acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) | ||
| 201 | { | ||
| 202 | acpi_status status; | ||
| 203 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
| 204 | union acpi_object *package, *fields; | ||
| 205 | int i; | ||
| 206 | |||
| 207 | memset(hpp, 0, sizeof(struct hotplug_params)); | ||
| 208 | |||
| 209 | status = acpi_evaluate_object(handle, "_HPP", NULL, &buffer); | ||
| 210 | if (ACPI_FAILURE(status)) | ||
| 211 | return status; | ||
| 212 | |||
| 213 | package = (union acpi_object *) buffer.pointer; | ||
| 214 | if (package->type != ACPI_TYPE_PACKAGE || | ||
| 215 | package->package.count != 4) { | ||
| 216 | status = AE_ERROR; | ||
| 217 | goto exit; | ||
| 218 | } | ||
| 219 | |||
| 220 | fields = package->package.elements; | ||
| 221 | for (i = 0; i < 4; i++) { | ||
| 222 | if (fields[i].type != ACPI_TYPE_INTEGER) { | ||
| 223 | status = AE_ERROR; | ||
| 224 | goto exit; | ||
| 225 | } | ||
| 226 | } | ||
| 227 | |||
| 228 | hpp->t0 = &hpp->type0_data; | ||
| 229 | hpp->t0->revision = 1; | ||
| 230 | hpp->t0->cache_line_size = fields[0].integer.value; | ||
| 231 | hpp->t0->latency_timer = fields[1].integer.value; | ||
| 232 | hpp->t0->enable_serr = fields[2].integer.value; | ||
| 233 | hpp->t0->enable_perr = fields[3].integer.value; | ||
| 234 | |||
| 235 | exit: | ||
| 236 | kfree(buffer.pointer); | ||
| 237 | return status; | ||
| 238 | } | ||
| 239 | |||
| 240 | /* pci_get_hp_params | ||
| 241 | * | ||
| 242 | * @dev - the pci_dev for which we want parameters | ||
| 243 | * @hpp - allocated by the caller | ||
| 244 | */ | ||
| 245 | int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp) | ||
| 246 | { | ||
| 247 | acpi_status status; | ||
| 248 | acpi_handle handle, phandle; | ||
| 249 | struct pci_bus *pbus; | ||
| 250 | |||
| 251 | handle = NULL; | ||
| 252 | for (pbus = dev->bus; pbus; pbus = pbus->parent) { | ||
| 253 | handle = acpi_pci_get_bridge_handle(pbus); | ||
| 254 | if (handle) | ||
| 255 | break; | ||
| 256 | } | ||
| 257 | |||
| 258 | /* | ||
| 259 | * _HPP settings apply to all child buses, until another _HPP is | ||
| 260 | * encountered. If we don't find an _HPP for the input pci dev, | ||
| 261 | * look for it in the parent device scope since that would apply to | ||
| 262 | * this pci dev. | ||
| 263 | */ | ||
| 264 | while (handle) { | ||
| 265 | status = acpi_run_hpx(handle, hpp); | ||
| 266 | if (ACPI_SUCCESS(status)) | ||
| 267 | return 0; | ||
| 268 | status = acpi_run_hpp(handle, hpp); | ||
| 269 | if (ACPI_SUCCESS(status)) | ||
| 270 | return 0; | ||
| 271 | if (acpi_is_root_bridge(handle)) | ||
| 272 | break; | ||
| 273 | status = acpi_get_parent(handle, &phandle); | ||
| 274 | if (ACPI_FAILURE(status)) | ||
| 275 | break; | ||
| 276 | handle = phandle; | ||
| 277 | } | ||
| 278 | return -ENODEV; | ||
| 279 | } | ||
| 280 | EXPORT_SYMBOL_GPL(pci_get_hp_params); | ||
| 281 | |||
| 20 | /** | 282 | /** |
| 21 | * pci_acpi_wake_bus - Root bus wakeup notification fork function. | 283 | * pci_acpi_wake_bus - Root bus wakeup notification fork function. |
| 22 | * @work: Work item to handle. | 284 | * @work: Work item to handle. |
| @@ -84,20 +346,6 @@ acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, | |||
| 84 | return acpi_add_pm_notifier(dev, &pci_dev->dev, pci_acpi_wake_dev); | 346 | return acpi_add_pm_notifier(dev, &pci_dev->dev, pci_acpi_wake_dev); |
| 85 | } | 347 | } |
| 86 | 348 | ||
| 87 | phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) | ||
| 88 | { | ||
| 89 | acpi_status status = AE_NOT_EXIST; | ||
| 90 | unsigned long long mcfg_addr; | ||
| 91 | |||
| 92 | if (handle) | ||
| 93 | status = acpi_evaluate_integer(handle, METHOD_NAME__CBA, | ||
| 94 | NULL, &mcfg_addr); | ||
| 95 | if (ACPI_FAILURE(status)) | ||
| 96 | return 0; | ||
| 97 | |||
| 98 | return (phys_addr_t)mcfg_addr; | ||
| 99 | } | ||
| 100 | |||
| 101 | /* | 349 | /* |
| 102 | * _SxD returns the D-state with the highest power | 350 | * _SxD returns the D-state with the highest power |
| 103 | * (lowest D-state number) supported in the S-state "x". | 351 | * (lowest D-state number) supported in the S-state "x". |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index d04c5adafc16..2b3c89425bb5 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
| @@ -55,7 +55,6 @@ int pci_add_dynid(struct pci_driver *drv, | |||
| 55 | unsigned long driver_data) | 55 | unsigned long driver_data) |
| 56 | { | 56 | { |
| 57 | struct pci_dynid *dynid; | 57 | struct pci_dynid *dynid; |
| 58 | int retval; | ||
| 59 | 58 | ||
| 60 | dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); | 59 | dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); |
| 61 | if (!dynid) | 60 | if (!dynid) |
| @@ -73,9 +72,7 @@ int pci_add_dynid(struct pci_driver *drv, | |||
| 73 | list_add_tail(&dynid->node, &drv->dynids.list); | 72 | list_add_tail(&dynid->node, &drv->dynids.list); |
| 74 | spin_unlock(&drv->dynids.lock); | 73 | spin_unlock(&drv->dynids.lock); |
| 75 | 74 | ||
| 76 | retval = driver_attach(&drv->driver); | 75 | return driver_attach(&drv->driver); |
| 77 | |||
| 78 | return retval; | ||
| 79 | } | 76 | } |
| 80 | EXPORT_SYMBOL_GPL(pci_add_dynid); | 77 | EXPORT_SYMBOL_GPL(pci_add_dynid); |
| 81 | 78 | ||
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 9ff0a901ecf7..92b6d9ab00e4 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
| @@ -177,7 +177,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, | |||
| 177 | { | 177 | { |
| 178 | struct pci_dev *pci_dev = to_pci_dev(dev); | 178 | struct pci_dev *pci_dev = to_pci_dev(dev); |
| 179 | 179 | ||
| 180 | return sprintf(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n", | 180 | return sprintf(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02X\n", |
| 181 | pci_dev->vendor, pci_dev->device, | 181 | pci_dev->vendor, pci_dev->device, |
| 182 | pci_dev->subsystem_vendor, pci_dev->subsystem_device, | 182 | pci_dev->subsystem_vendor, pci_dev->subsystem_device, |
| 183 | (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8), | 183 | (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8), |
| @@ -250,46 +250,45 @@ static ssize_t msi_bus_show(struct device *dev, struct device_attribute *attr, | |||
| 250 | char *buf) | 250 | char *buf) |
| 251 | { | 251 | { |
| 252 | struct pci_dev *pdev = to_pci_dev(dev); | 252 | struct pci_dev *pdev = to_pci_dev(dev); |
| 253 | struct pci_bus *subordinate = pdev->subordinate; | ||
| 253 | 254 | ||
| 254 | if (!pdev->subordinate) | 255 | return sprintf(buf, "%u\n", subordinate ? |
| 255 | return 0; | 256 | !(subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI) |
| 256 | 257 | : !pdev->no_msi); | |
| 257 | return sprintf(buf, "%u\n", | ||
| 258 | !(pdev->subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI)); | ||
| 259 | } | 258 | } |
| 260 | 259 | ||
| 261 | static ssize_t msi_bus_store(struct device *dev, struct device_attribute *attr, | 260 | static ssize_t msi_bus_store(struct device *dev, struct device_attribute *attr, |
| 262 | const char *buf, size_t count) | 261 | const char *buf, size_t count) |
| 263 | { | 262 | { |
| 264 | struct pci_dev *pdev = to_pci_dev(dev); | 263 | struct pci_dev *pdev = to_pci_dev(dev); |
| 264 | struct pci_bus *subordinate = pdev->subordinate; | ||
| 265 | unsigned long val; | 265 | unsigned long val; |
| 266 | 266 | ||
| 267 | if (kstrtoul(buf, 0, &val) < 0) | 267 | if (kstrtoul(buf, 0, &val) < 0) |
| 268 | return -EINVAL; | 268 | return -EINVAL; |
| 269 | 269 | ||
| 270 | /* | ||
| 271 | * Bad things may happen if the no_msi flag is changed | ||
| 272 | * while drivers are loaded. | ||
| 273 | */ | ||
| 274 | if (!capable(CAP_SYS_ADMIN)) | 270 | if (!capable(CAP_SYS_ADMIN)) |
| 275 | return -EPERM; | 271 | return -EPERM; |
| 276 | 272 | ||
| 277 | /* | 273 | /* |
| 278 | * Maybe devices without subordinate buses shouldn't have this | 274 | * "no_msi" and "bus_flags" only affect what happens when a driver |
| 279 | * attribute in the first place? | 275 | * requests MSI or MSI-X. They don't affect any drivers that have |
| 276 | * already requested MSI or MSI-X. | ||
| 280 | */ | 277 | */ |
| 281 | if (!pdev->subordinate) | 278 | if (!subordinate) { |
| 279 | pdev->no_msi = !val; | ||
| 280 | dev_info(&pdev->dev, "MSI/MSI-X %s for future drivers\n", | ||
| 281 | val ? "allowed" : "disallowed"); | ||
| 282 | return count; | 282 | return count; |
| 283 | |||
| 284 | /* Is the flag going to change, or keep the value it already had? */ | ||
| 285 | if (!(pdev->subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI) ^ | ||
| 286 | !!val) { | ||
| 287 | pdev->subordinate->bus_flags ^= PCI_BUS_FLAGS_NO_MSI; | ||
| 288 | |||
| 289 | dev_warn(&pdev->dev, "forced subordinate bus to%s support MSI, bad things could happen\n", | ||
| 290 | val ? "" : " not"); | ||
| 291 | } | 283 | } |
| 292 | 284 | ||
| 285 | if (val) | ||
| 286 | subordinate->bus_flags &= ~PCI_BUS_FLAGS_NO_MSI; | ||
| 287 | else | ||
| 288 | subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; | ||
| 289 | |||
| 290 | dev_info(&subordinate->dev, "MSI/MSI-X %s for future drivers of devices on this bus\n", | ||
| 291 | val ? "allowed" : "disallowed"); | ||
| 293 | return count; | 292 | return count; |
| 294 | } | 293 | } |
| 295 | static DEVICE_ATTR_RW(msi_bus); | 294 | static DEVICE_ATTR_RW(msi_bus); |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 2c9ac70254e2..625a4ace10b4 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -1003,12 +1003,19 @@ int pci_save_state(struct pci_dev *dev) | |||
| 1003 | for (i = 0; i < 16; i++) | 1003 | for (i = 0; i < 16; i++) |
| 1004 | pci_read_config_dword(dev, i * 4, &dev->saved_config_space[i]); | 1004 | pci_read_config_dword(dev, i * 4, &dev->saved_config_space[i]); |
| 1005 | dev->state_saved = true; | 1005 | dev->state_saved = true; |
| 1006 | if ((i = pci_save_pcie_state(dev)) != 0) | 1006 | |
| 1007 | i = pci_save_pcie_state(dev); | ||
| 1008 | if (i != 0) | ||
| 1007 | return i; | 1009 | return i; |
| 1008 | if ((i = pci_save_pcix_state(dev)) != 0) | 1010 | |
| 1011 | i = pci_save_pcix_state(dev); | ||
| 1012 | if (i != 0) | ||
| 1009 | return i; | 1013 | return i; |
| 1010 | if ((i = pci_save_vc_state(dev)) != 0) | 1014 | |
| 1015 | i = pci_save_vc_state(dev); | ||
| 1016 | if (i != 0) | ||
| 1011 | return i; | 1017 | return i; |
| 1018 | |||
| 1012 | return 0; | 1019 | return 0; |
| 1013 | } | 1020 | } |
| 1014 | EXPORT_SYMBOL(pci_save_state); | 1021 | EXPORT_SYMBOL(pci_save_state); |
| @@ -1907,10 +1914,6 @@ int pci_prepare_to_sleep(struct pci_dev *dev) | |||
| 1907 | if (target_state == PCI_POWER_ERROR) | 1914 | if (target_state == PCI_POWER_ERROR) |
| 1908 | return -EIO; | 1915 | return -EIO; |
| 1909 | 1916 | ||
| 1910 | /* D3cold during system suspend/hibernate is not supported */ | ||
| 1911 | if (target_state > PCI_D3hot) | ||
| 1912 | target_state = PCI_D3hot; | ||
| 1913 | |||
| 1914 | pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev)); | 1917 | pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev)); |
| 1915 | 1918 | ||
| 1916 | error = pci_set_power_state(dev, target_state); | 1919 | error = pci_set_power_state(dev, target_state); |
| @@ -2704,6 +2707,37 @@ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name) | |||
| 2704 | } | 2707 | } |
| 2705 | EXPORT_SYMBOL(pci_request_regions_exclusive); | 2708 | EXPORT_SYMBOL(pci_request_regions_exclusive); |
| 2706 | 2709 | ||
| 2710 | /** | ||
| 2711 | * pci_remap_iospace - Remap the memory mapped I/O space | ||
| 2712 | * @res: Resource describing the I/O space | ||
| 2713 | * @phys_addr: physical address of range to be mapped | ||
| 2714 | * | ||
| 2715 | * Remap the memory mapped I/O space described by the @res | ||
| 2716 | * and the CPU physical address @phys_addr into virtual address space. | ||
| 2717 | * Only architectures that have memory mapped IO functions defined | ||
| 2718 | * (and the PCI_IOBASE value defined) should call this function. | ||
| 2719 | */ | ||
| 2720 | int __weak pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr) | ||
| 2721 | { | ||
| 2722 | #if defined(PCI_IOBASE) && defined(CONFIG_MMU) | ||
| 2723 | unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start; | ||
| 2724 | |||
| 2725 | if (!(res->flags & IORESOURCE_IO)) | ||
| 2726 | return -EINVAL; | ||
| 2727 | |||
| 2728 | if (res->end > IO_SPACE_LIMIT) | ||
| 2729 | return -EINVAL; | ||
| 2730 | |||
| 2731 | return ioremap_page_range(vaddr, vaddr + resource_size(res), phys_addr, | ||
| 2732 | pgprot_device(PAGE_KERNEL)); | ||
| 2733 | #else | ||
| 2734 | /* this architecture does not have memory mapped I/O space, | ||
| 2735 | so this function should never be called */ | ||
| 2736 | WARN_ONCE(1, "This architecture does not support memory mapped I/O\n"); | ||
| 2737 | return -ENODEV; | ||
| 2738 | #endif | ||
| 2739 | } | ||
| 2740 | |||
| 2707 | static void __pci_set_master(struct pci_dev *dev, bool enable) | 2741 | static void __pci_set_master(struct pci_dev *dev, bool enable) |
| 2708 | { | 2742 | { |
| 2709 | u16 old_cmd, cmd; | 2743 | u16 old_cmd, cmd; |
| @@ -4406,6 +4440,15 @@ static void pci_no_domains(void) | |||
| 4406 | #endif | 4440 | #endif |
| 4407 | } | 4441 | } |
| 4408 | 4442 | ||
| 4443 | #ifdef CONFIG_PCI_DOMAINS | ||
| 4444 | static atomic_t __domain_nr = ATOMIC_INIT(-1); | ||
| 4445 | |||
| 4446 | int pci_get_new_domain_nr(void) | ||
| 4447 | { | ||
| 4448 | return atomic_inc_return(&__domain_nr); | ||
| 4449 | } | ||
| 4450 | #endif | ||
| 4451 | |||
| 4409 | /** | 4452 | /** |
| 4410 | * pci_ext_cfg_avail - can we access extended PCI config space? | 4453 | * pci_ext_cfg_avail - can we access extended PCI config space? |
| 4411 | * | 4454 | * |
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c index 35d06e177917..c6849d9e86ce 100644 --- a/drivers/pci/pcie/aer/aerdrv_errprint.c +++ b/drivers/pci/pcie/aer/aerdrv_errprint.c | |||
| @@ -89,15 +89,17 @@ static const char *aer_correctable_error_string[] = { | |||
| 89 | NULL, | 89 | NULL, |
| 90 | "Replay Timer Timeout", /* Bit Position 12 */ | 90 | "Replay Timer Timeout", /* Bit Position 12 */ |
| 91 | "Advisory Non-Fatal", /* Bit Position 13 */ | 91 | "Advisory Non-Fatal", /* Bit Position 13 */ |
| 92 | "Corrected Internal Error", /* Bit Position 14 */ | ||
| 93 | "Header Log Overflow", /* Bit Position 15 */ | ||
| 92 | }; | 94 | }; |
| 93 | 95 | ||
| 94 | static const char *aer_uncorrectable_error_string[] = { | 96 | static const char *aer_uncorrectable_error_string[] = { |
| 95 | NULL, | 97 | "Undefined", /* Bit Position 0 */ |
| 96 | NULL, | 98 | NULL, |
| 97 | NULL, | 99 | NULL, |
| 98 | NULL, | 100 | NULL, |
| 99 | "Data Link Protocol", /* Bit Position 4 */ | 101 | "Data Link Protocol", /* Bit Position 4 */ |
| 100 | NULL, | 102 | "Surprise Down Error", /* Bit Position 5 */ |
| 101 | NULL, | 103 | NULL, |
| 102 | NULL, | 104 | NULL, |
| 103 | NULL, | 105 | NULL, |
| @@ -113,6 +115,11 @@ static const char *aer_uncorrectable_error_string[] = { | |||
| 113 | "Malformed TLP", /* Bit Position 18 */ | 115 | "Malformed TLP", /* Bit Position 18 */ |
| 114 | "ECRC", /* Bit Position 19 */ | 116 | "ECRC", /* Bit Position 19 */ |
| 115 | "Unsupported Request", /* Bit Position 20 */ | 117 | "Unsupported Request", /* Bit Position 20 */ |
| 118 | "ACS Violation", /* Bit Position 21 */ | ||
| 119 | "Uncorrectable Internal Error", /* Bit Position 22 */ | ||
| 120 | "MC Blocked TLP", /* Bit Position 23 */ | ||
| 121 | "AtomicOp Egress Blocked", /* Bit Position 24 */ | ||
| 122 | "TLP Prefix Blocked Error", /* Bit Position 25 */ | ||
| 116 | }; | 123 | }; |
| 117 | 124 | ||
| 118 | static const char *aer_agent_string[] = { | 125 | static const char *aer_agent_string[] = { |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 2ccc9b926ea7..be35da2e105e 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
| @@ -93,77 +93,6 @@ static int pcie_port_resume_noirq(struct device *dev) | |||
| 93 | return 0; | 93 | return 0; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | #ifdef CONFIG_PM_RUNTIME | ||
| 97 | struct d3cold_info { | ||
| 98 | bool no_d3cold; | ||
| 99 | unsigned int d3cold_delay; | ||
| 100 | }; | ||
| 101 | |||
| 102 | static int pci_dev_d3cold_info(struct pci_dev *pdev, void *data) | ||
| 103 | { | ||
| 104 | struct d3cold_info *info = data; | ||
| 105 | |||
| 106 | info->d3cold_delay = max_t(unsigned int, pdev->d3cold_delay, | ||
| 107 | info->d3cold_delay); | ||
| 108 | if (pdev->no_d3cold) | ||
| 109 | info->no_d3cold = true; | ||
| 110 | return 0; | ||
| 111 | } | ||
| 112 | |||
| 113 | static int pcie_port_runtime_suspend(struct device *dev) | ||
| 114 | { | ||
| 115 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 116 | struct d3cold_info d3cold_info = { | ||
| 117 | .no_d3cold = false, | ||
| 118 | .d3cold_delay = PCI_PM_D3_WAIT, | ||
| 119 | }; | ||
| 120 | |||
| 121 | /* | ||
| 122 | * If any subordinate device disable D3cold, we should not put | ||
| 123 | * the port into D3cold. The D3cold delay of port should be | ||
| 124 | * the max of that of all subordinate devices. | ||
| 125 | */ | ||
| 126 | pci_walk_bus(pdev->subordinate, pci_dev_d3cold_info, &d3cold_info); | ||
| 127 | pdev->no_d3cold = d3cold_info.no_d3cold; | ||
| 128 | pdev->d3cold_delay = d3cold_info.d3cold_delay; | ||
| 129 | return 0; | ||
| 130 | } | ||
| 131 | |||
| 132 | static int pcie_port_runtime_resume(struct device *dev) | ||
| 133 | { | ||
| 134 | return 0; | ||
| 135 | } | ||
| 136 | |||
| 137 | static int pci_dev_pme_poll(struct pci_dev *pdev, void *data) | ||
| 138 | { | ||
| 139 | bool *pme_poll = data; | ||
| 140 | |||
| 141 | if (pdev->pme_poll) | ||
| 142 | *pme_poll = true; | ||
| 143 | return 0; | ||
| 144 | } | ||
| 145 | |||
| 146 | static int pcie_port_runtime_idle(struct device *dev) | ||
| 147 | { | ||
| 148 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 149 | bool pme_poll = false; | ||
| 150 | |||
| 151 | /* | ||
| 152 | * If any subordinate device needs pme poll, we should keep | ||
| 153 | * the port in D0, because we need port in D0 to poll it. | ||
| 154 | */ | ||
| 155 | pci_walk_bus(pdev->subordinate, pci_dev_pme_poll, &pme_poll); | ||
| 156 | /* Delay for a short while to prevent too frequent suspend/resume */ | ||
| 157 | if (!pme_poll) | ||
| 158 | pm_schedule_suspend(dev, 10); | ||
| 159 | return -EBUSY; | ||
| 160 | } | ||
| 161 | #else | ||
| 162 | #define pcie_port_runtime_suspend NULL | ||
| 163 | #define pcie_port_runtime_resume NULL | ||
| 164 | #define pcie_port_runtime_idle NULL | ||
| 165 | #endif | ||
| 166 | |||
| 167 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { | 96 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { |
| 168 | .suspend = pcie_port_device_suspend, | 97 | .suspend = pcie_port_device_suspend, |
| 169 | .resume = pcie_port_device_resume, | 98 | .resume = pcie_port_device_resume, |
| @@ -172,9 +101,6 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { | |||
| 172 | .poweroff = pcie_port_device_suspend, | 101 | .poweroff = pcie_port_device_suspend, |
| 173 | .restore = pcie_port_device_resume, | 102 | .restore = pcie_port_device_resume, |
| 174 | .resume_noirq = pcie_port_resume_noirq, | 103 | .resume_noirq = pcie_port_resume_noirq, |
| 175 | .runtime_suspend = pcie_port_runtime_suspend, | ||
| 176 | .runtime_resume = pcie_port_runtime_resume, | ||
| 177 | .runtime_idle = pcie_port_runtime_idle, | ||
| 178 | }; | 104 | }; |
| 179 | 105 | ||
| 180 | #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) | 106 | #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 4170113cde61..5ed99309c758 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <linux/delay.h> | 6 | #include <linux/delay.h> |
| 7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
| 8 | #include <linux/pci.h> | 8 | #include <linux/pci.h> |
| 9 | #include <linux/pci_hotplug.h> | ||
| 9 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
| 10 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 11 | #include <linux/cpumask.h> | 12 | #include <linux/cpumask.h> |
| @@ -485,7 +486,7 @@ void pci_read_bridge_bases(struct pci_bus *child) | |||
| 485 | } | 486 | } |
| 486 | } | 487 | } |
| 487 | 488 | ||
| 488 | static struct pci_bus *pci_alloc_bus(void) | 489 | static struct pci_bus *pci_alloc_bus(struct pci_bus *parent) |
| 489 | { | 490 | { |
| 490 | struct pci_bus *b; | 491 | struct pci_bus *b; |
| 491 | 492 | ||
| @@ -500,6 +501,10 @@ static struct pci_bus *pci_alloc_bus(void) | |||
| 500 | INIT_LIST_HEAD(&b->resources); | 501 | INIT_LIST_HEAD(&b->resources); |
| 501 | b->max_bus_speed = PCI_SPEED_UNKNOWN; | 502 | b->max_bus_speed = PCI_SPEED_UNKNOWN; |
| 502 | b->cur_bus_speed = PCI_SPEED_UNKNOWN; | 503 | b->cur_bus_speed = PCI_SPEED_UNKNOWN; |
| 504 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | ||
| 505 | if (parent) | ||
| 506 | b->domain_nr = parent->domain_nr; | ||
| 507 | #endif | ||
| 503 | return b; | 508 | return b; |
| 504 | } | 509 | } |
| 505 | 510 | ||
| @@ -671,7 +676,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | |||
| 671 | /* | 676 | /* |
| 672 | * Allocate a new bus, and inherit stuff from the parent.. | 677 | * Allocate a new bus, and inherit stuff from the parent.. |
| 673 | */ | 678 | */ |
| 674 | child = pci_alloc_bus(); | 679 | child = pci_alloc_bus(parent); |
| 675 | if (!child) | 680 | if (!child) |
| 676 | return NULL; | 681 | return NULL; |
| 677 | 682 | ||
| @@ -740,6 +745,17 @@ struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, | |||
| 740 | } | 745 | } |
| 741 | EXPORT_SYMBOL(pci_add_new_bus); | 746 | EXPORT_SYMBOL(pci_add_new_bus); |
| 742 | 747 | ||
| 748 | static void pci_enable_crs(struct pci_dev *pdev) | ||
| 749 | { | ||
| 750 | u16 root_cap = 0; | ||
| 751 | |||
| 752 | /* Enable CRS Software Visibility if supported */ | ||
| 753 | pcie_capability_read_word(pdev, PCI_EXP_RTCAP, &root_cap); | ||
| 754 | if (root_cap & PCI_EXP_RTCAP_CRSVIS) | ||
| 755 | pcie_capability_set_word(pdev, PCI_EXP_RTCTL, | ||
| 756 | PCI_EXP_RTCTL_CRSSVE); | ||
| 757 | } | ||
| 758 | |||
| 743 | /* | 759 | /* |
| 744 | * If it's a bridge, configure it and scan the bus behind it. | 760 | * If it's a bridge, configure it and scan the bus behind it. |
| 745 | * For CardBus bridges, we don't scan behind as the devices will | 761 | * For CardBus bridges, we don't scan behind as the devices will |
| @@ -787,6 +803,8 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
| 787 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, | 803 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, |
| 788 | bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); | 804 | bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); |
| 789 | 805 | ||
| 806 | pci_enable_crs(dev); | ||
| 807 | |||
| 790 | if ((secondary || subordinate) && !pcibios_assign_all_busses() && | 808 | if ((secondary || subordinate) && !pcibios_assign_all_busses() && |
| 791 | !is_cardbus && !broken) { | 809 | !is_cardbus && !broken) { |
| 792 | unsigned int cmax; | 810 | unsigned int cmax; |
| @@ -1226,6 +1244,137 @@ int pci_setup_device(struct pci_dev *dev) | |||
| 1226 | return 0; | 1244 | return 0; |
| 1227 | } | 1245 | } |
| 1228 | 1246 | ||
| 1247 | static struct hpp_type0 pci_default_type0 = { | ||
| 1248 | .revision = 1, | ||
| 1249 | .cache_line_size = 8, | ||
| 1250 | .latency_timer = 0x40, | ||
| 1251 | .enable_serr = 0, | ||
| 1252 | .enable_perr = 0, | ||
| 1253 | }; | ||
| 1254 | |||
| 1255 | static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp) | ||
| 1256 | { | ||
| 1257 | u16 pci_cmd, pci_bctl; | ||
| 1258 | |||
| 1259 | if (!hpp) | ||
| 1260 | hpp = &pci_default_type0; | ||
| 1261 | |||
| 1262 | if (hpp->revision > 1) { | ||
| 1263 | dev_warn(&dev->dev, | ||
| 1264 | "PCI settings rev %d not supported; using defaults\n", | ||
| 1265 | hpp->revision); | ||
| 1266 | hpp = &pci_default_type0; | ||
| 1267 | } | ||
| 1268 | |||
| 1269 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp->cache_line_size); | ||
| 1270 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp->latency_timer); | ||
| 1271 | pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); | ||
| 1272 | if (hpp->enable_serr) | ||
| 1273 | pci_cmd |= PCI_COMMAND_SERR; | ||
| 1274 | if (hpp->enable_perr) | ||
| 1275 | pci_cmd |= PCI_COMMAND_PARITY; | ||
| 1276 | pci_write_config_word(dev, PCI_COMMAND, pci_cmd); | ||
| 1277 | |||
| 1278 | /* Program bridge control value */ | ||
| 1279 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { | ||
| 1280 | pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, | ||
| 1281 | hpp->latency_timer); | ||
| 1282 | pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); | ||
| 1283 | if (hpp->enable_serr) | ||
| 1284 | pci_bctl |= PCI_BRIDGE_CTL_SERR; | ||
| 1285 | if (hpp->enable_perr) | ||
| 1286 | pci_bctl |= PCI_BRIDGE_CTL_PARITY; | ||
| 1287 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl); | ||
| 1288 | } | ||
| 1289 | } | ||
| 1290 | |||
| 1291 | static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp) | ||
| 1292 | { | ||
| 1293 | if (hpp) | ||
| 1294 | dev_warn(&dev->dev, "PCI-X settings not supported\n"); | ||
| 1295 | } | ||
| 1296 | |||
| 1297 | static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) | ||
| 1298 | { | ||
| 1299 | int pos; | ||
| 1300 | u32 reg32; | ||
| 1301 | |||
| 1302 | if (!hpp) | ||
| 1303 | return; | ||
| 1304 | |||
| 1305 | if (hpp->revision > 1) { | ||
| 1306 | dev_warn(&dev->dev, "PCIe settings rev %d not supported\n", | ||
| 1307 | hpp->revision); | ||
| 1308 | return; | ||
| 1309 | } | ||
| 1310 | |||
| 1311 | /* | ||
| 1312 | * Don't allow _HPX to change MPS or MRRS settings. We manage | ||
| 1313 | * those to make sure they're consistent with the rest of the | ||
| 1314 | * platform. | ||
| 1315 | */ | ||
| 1316 | hpp->pci_exp_devctl_and |= PCI_EXP_DEVCTL_PAYLOAD | | ||
| 1317 | PCI_EXP_DEVCTL_READRQ; | ||
| 1318 | hpp->pci_exp_devctl_or &= ~(PCI_EXP_DEVCTL_PAYLOAD | | ||
| 1319 | PCI_EXP_DEVCTL_READRQ); | ||
| 1320 | |||
| 1321 | /* Initialize Device Control Register */ | ||
| 1322 | pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, | ||
| 1323 | ~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or); | ||
| 1324 | |||
| 1325 | /* Initialize Link Control Register */ | ||
| 1326 | if (dev->subordinate) | ||
| 1327 | pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL, | ||
| 1328 | ~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or); | ||
| 1329 | |||
| 1330 | /* Find Advanced Error Reporting Enhanced Capability */ | ||
| 1331 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | ||
| 1332 | if (!pos) | ||
| 1333 | return; | ||
| 1334 | |||
| 1335 | /* Initialize Uncorrectable Error Mask Register */ | ||
| 1336 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, ®32); | ||
| 1337 | reg32 = (reg32 & hpp->unc_err_mask_and) | hpp->unc_err_mask_or; | ||
| 1338 | pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, reg32); | ||
| 1339 | |||
| 1340 | /* Initialize Uncorrectable Error Severity Register */ | ||
| 1341 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, ®32); | ||
| 1342 | reg32 = (reg32 & hpp->unc_err_sever_and) | hpp->unc_err_sever_or; | ||
| 1343 | pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, reg32); | ||
| 1344 | |||
| 1345 | /* Initialize Correctable Error Mask Register */ | ||
| 1346 | pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, ®32); | ||
| 1347 | reg32 = (reg32 & hpp->cor_err_mask_and) | hpp->cor_err_mask_or; | ||
| 1348 | pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg32); | ||
| 1349 | |||
| 1350 | /* Initialize Advanced Error Capabilities and Control Register */ | ||
| 1351 | pci_read_config_dword(dev, pos + PCI_ERR_CAP, ®32); | ||
| 1352 | reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or; | ||
| 1353 | pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32); | ||
| 1354 | |||
| 1355 | /* | ||
| 1356 | * FIXME: The following two registers are not supported yet. | ||
| 1357 | * | ||
| 1358 | * o Secondary Uncorrectable Error Severity Register | ||
| 1359 | * o Secondary Uncorrectable Error Mask Register | ||
| 1360 | */ | ||
| 1361 | } | ||
| 1362 | |||
| 1363 | static void pci_configure_device(struct pci_dev *dev) | ||
| 1364 | { | ||
| 1365 | struct hotplug_params hpp; | ||
| 1366 | int ret; | ||
| 1367 | |||
| 1368 | memset(&hpp, 0, sizeof(hpp)); | ||
| 1369 | ret = pci_get_hp_params(dev, &hpp); | ||
| 1370 | if (ret) | ||
| 1371 | return; | ||
| 1372 | |||
| 1373 | program_hpp_type2(dev, hpp.t2); | ||
| 1374 | program_hpp_type1(dev, hpp.t1); | ||
| 1375 | program_hpp_type0(dev, hpp.t0); | ||
| 1376 | } | ||
| 1377 | |||
| 1229 | static void pci_release_capabilities(struct pci_dev *dev) | 1378 | static void pci_release_capabilities(struct pci_dev *dev) |
| 1230 | { | 1379 | { |
| 1231 | pci_vpd_release(dev); | 1380 | pci_vpd_release(dev); |
| @@ -1282,8 +1431,13 @@ bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l, | |||
| 1282 | *l == 0x0000ffff || *l == 0xffff0000) | 1431 | *l == 0x0000ffff || *l == 0xffff0000) |
| 1283 | return false; | 1432 | return false; |
| 1284 | 1433 | ||
| 1285 | /* Configuration request Retry Status */ | 1434 | /* |
| 1286 | while (*l == 0xffff0001) { | 1435 | * Configuration Request Retry Status. Some root ports return the |
| 1436 | * actual device ID instead of the synthetic ID (0xFFFF) required | ||
| 1437 | * by the PCIe spec. Ignore the device ID and only check for | ||
| 1438 | * (vendor id == 1). | ||
| 1439 | */ | ||
| 1440 | while ((*l & 0xffff) == 0x0001) { | ||
| 1287 | if (!crs_timeout) | 1441 | if (!crs_timeout) |
| 1288 | return false; | 1442 | return false; |
| 1289 | 1443 | ||
| @@ -1363,6 +1517,8 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | |||
| 1363 | { | 1517 | { |
| 1364 | int ret; | 1518 | int ret; |
| 1365 | 1519 | ||
| 1520 | pci_configure_device(dev); | ||
| 1521 | |||
| 1366 | device_initialize(&dev->dev); | 1522 | device_initialize(&dev->dev); |
| 1367 | dev->dev.release = pci_release_dev; | 1523 | dev->dev.release = pci_release_dev; |
| 1368 | 1524 | ||
| @@ -1751,13 +1907,14 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
| 1751 | char bus_addr[64]; | 1907 | char bus_addr[64]; |
| 1752 | char *fmt; | 1908 | char *fmt; |
| 1753 | 1909 | ||
| 1754 | b = pci_alloc_bus(); | 1910 | b = pci_alloc_bus(NULL); |
| 1755 | if (!b) | 1911 | if (!b) |
| 1756 | return NULL; | 1912 | return NULL; |
| 1757 | 1913 | ||
| 1758 | b->sysdata = sysdata; | 1914 | b->sysdata = sysdata; |
| 1759 | b->ops = ops; | 1915 | b->ops = ops; |
| 1760 | b->number = b->busn_res.start = bus; | 1916 | b->number = b->busn_res.start = bus; |
| 1917 | pci_bus_assign_domain_nr(b, parent); | ||
| 1761 | b2 = pci_find_bus(pci_domain_nr(b), bus); | 1918 | b2 = pci_find_bus(pci_domain_nr(b), bus); |
| 1762 | if (b2) { | 1919 | if (b2) { |
| 1763 | /* If we already got to this bus through a different bridge, ignore it */ | 1920 | /* If we already got to this bus through a different bridge, ignore it */ |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 80c2d014283d..90acb32c85b1 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/ioport.h> | 24 | #include <linux/ioport.h> |
| 25 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
| 26 | #include <linux/ktime.h> | 26 | #include <linux/ktime.h> |
| 27 | #include <linux/mm.h> | ||
| 27 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ | 28 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ |
| 28 | #include "pci.h" | 29 | #include "pci.h" |
| 29 | 30 | ||
| @@ -287,6 +288,25 @@ static void quirk_citrine(struct pci_dev *dev) | |||
| 287 | } | 288 | } |
| 288 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, quirk_citrine); | 289 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, quirk_citrine); |
| 289 | 290 | ||
| 291 | /* On IBM Crocodile ipr SAS adapters, expand BAR to system page size */ | ||
| 292 | static void quirk_extend_bar_to_page(struct pci_dev *dev) | ||
| 293 | { | ||
| 294 | int i; | ||
| 295 | |||
| 296 | for (i = 0; i < PCI_STD_RESOURCE_END; i++) { | ||
| 297 | struct resource *r = &dev->resource[i]; | ||
| 298 | |||
| 299 | if (r->flags & IORESOURCE_MEM && resource_size(r) < PAGE_SIZE) { | ||
| 300 | r->end = PAGE_SIZE - 1; | ||
| 301 | r->start = 0; | ||
| 302 | r->flags |= IORESOURCE_UNSET; | ||
| 303 | dev_info(&dev->dev, "expanded BAR %d to page size: %pR\n", | ||
| 304 | i, r); | ||
| 305 | } | ||
| 306 | } | ||
| 307 | } | ||
| 308 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, 0x034a, quirk_extend_bar_to_page); | ||
| 309 | |||
| 290 | /* | 310 | /* |
| 291 | * S3 868 and 968 chips report region size equal to 32M, but they decode 64M. | 311 | * S3 868 and 968 chips report region size equal to 32M, but they decode 64M. |
| 292 | * If it's needed, re-allocate the region. | 312 | * If it's needed, re-allocate the region. |
| @@ -2985,6 +3005,8 @@ DECLARE_PCI_FIXUP_HEADER(0x1814, 0x0601, /* Ralink RT2800 802.11n PCI */ | |||
| 2985 | */ | 3005 | */ |
| 2986 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_REALTEK, 0x8169, | 3006 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_REALTEK, 0x8169, |
| 2987 | quirk_broken_intx_masking); | 3007 | quirk_broken_intx_masking); |
| 3008 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, PCI_ANY_ID, | ||
| 3009 | quirk_broken_intx_masking); | ||
| 2988 | 3010 | ||
| 2989 | #ifdef CONFIG_ACPI | 3011 | #ifdef CONFIG_ACPI |
| 2990 | /* | 3012 | /* |
| @@ -3512,57 +3534,6 @@ DECLARE_PCI_FIXUP_HEADER(0x1283, 0x8892, quirk_use_pcie_bridge_dma_alias); | |||
| 3512 | /* Intel 82801, https://bugzilla.kernel.org/show_bug.cgi?id=44881#c49 */ | 3534 | /* Intel 82801, https://bugzilla.kernel.org/show_bug.cgi?id=44881#c49 */ |
| 3513 | DECLARE_PCI_FIXUP_HEADER(0x8086, 0x244e, quirk_use_pcie_bridge_dma_alias); | 3535 | DECLARE_PCI_FIXUP_HEADER(0x8086, 0x244e, quirk_use_pcie_bridge_dma_alias); |
| 3514 | 3536 | ||
| 3515 | static struct pci_dev *pci_func_0_dma_source(struct pci_dev *dev) | ||
| 3516 | { | ||
| 3517 | if (!PCI_FUNC(dev->devfn)) | ||
| 3518 | return pci_dev_get(dev); | ||
| 3519 | |||
| 3520 | return pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); | ||
| 3521 | } | ||
| 3522 | |||
| 3523 | static const struct pci_dev_dma_source { | ||
| 3524 | u16 vendor; | ||
| 3525 | u16 device; | ||
| 3526 | struct pci_dev *(*dma_source)(struct pci_dev *dev); | ||
| 3527 | } pci_dev_dma_source[] = { | ||
| 3528 | /* | ||
| 3529 | * https://bugzilla.redhat.com/show_bug.cgi?id=605888 | ||
| 3530 | * | ||
| 3531 | * Some Ricoh devices use the function 0 source ID for DMA on | ||
| 3532 | * other functions of a multifunction device. The DMA devices | ||
| 3533 | * is therefore function 0, which will have implications of the | ||
| 3534 | * iommu grouping of these devices. | ||
| 3535 | */ | ||
| 3536 | { PCI_VENDOR_ID_RICOH, 0xe822, pci_func_0_dma_source }, | ||
| 3537 | { PCI_VENDOR_ID_RICOH, 0xe230, pci_func_0_dma_source }, | ||
| 3538 | { PCI_VENDOR_ID_RICOH, 0xe832, pci_func_0_dma_source }, | ||
| 3539 | { PCI_VENDOR_ID_RICOH, 0xe476, pci_func_0_dma_source }, | ||
| 3540 | { 0 } | ||
| 3541 | }; | ||
| 3542 | |||
| 3543 | /* | ||
| 3544 | * IOMMUs with isolation capabilities need to be programmed with the | ||
| 3545 | * correct source ID of a device. In most cases, the source ID matches | ||
| 3546 | * the device doing the DMA, but sometimes hardware is broken and will | ||
| 3547 | * tag the DMA as being sourced from a different device. This function | ||
| 3548 | * allows that translation. Note that the reference count of the | ||
| 3549 | * returned device is incremented on all paths. | ||
| 3550 | */ | ||
| 3551 | struct pci_dev *pci_get_dma_source(struct pci_dev *dev) | ||
| 3552 | { | ||
| 3553 | const struct pci_dev_dma_source *i; | ||
| 3554 | |||
| 3555 | for (i = pci_dev_dma_source; i->dma_source; i++) { | ||
| 3556 | if ((i->vendor == dev->vendor || | ||
| 3557 | i->vendor == (u16)PCI_ANY_ID) && | ||
| 3558 | (i->device == dev->device || | ||
| 3559 | i->device == (u16)PCI_ANY_ID)) | ||
| 3560 | return i->dma_source(dev); | ||
| 3561 | } | ||
| 3562 | |||
| 3563 | return pci_dev_get(dev); | ||
| 3564 | } | ||
| 3565 | |||
| 3566 | /* | 3537 | /* |
| 3567 | * AMD has indicated that the devices below do not support peer-to-peer | 3538 | * AMD has indicated that the devices below do not support peer-to-peer |
| 3568 | * in any system where they are found in the southbridge with an AMD | 3539 | * in any system where they are found in the southbridge with an AMD |
| @@ -3582,6 +3553,11 @@ struct pci_dev *pci_get_dma_source(struct pci_dev *dev) | |||
| 3582 | * 1002:439d SB7x0/SB8x0/SB9x0 LPC host controller | 3553 | * 1002:439d SB7x0/SB8x0/SB9x0 LPC host controller |
| 3583 | * 1002:4384 SBx00 PCI to PCI Bridge | 3554 | * 1002:4384 SBx00 PCI to PCI Bridge |
| 3584 | * 1002:4399 SB7x0/SB8x0/SB9x0 USB OHCI2 Controller | 3555 | * 1002:4399 SB7x0/SB8x0/SB9x0 USB OHCI2 Controller |
| 3556 | * | ||
| 3557 | * https://bugzilla.kernel.org/show_bug.cgi?id=81841#c15 | ||
| 3558 | * | ||
| 3559 | * 1022:780f [AMD] FCH PCI Bridge | ||
| 3560 | * 1022:7809 [AMD] FCH USB OHCI Controller | ||
| 3585 | */ | 3561 | */ |
| 3586 | static int pci_quirk_amd_sb_acs(struct pci_dev *dev, u16 acs_flags) | 3562 | static int pci_quirk_amd_sb_acs(struct pci_dev *dev, u16 acs_flags) |
| 3587 | { | 3563 | { |
| @@ -3664,6 +3640,23 @@ static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags) | |||
| 3664 | return acs_flags & ~flags ? 0 : 1; | 3640 | return acs_flags & ~flags ? 0 : 1; |
| 3665 | } | 3641 | } |
| 3666 | 3642 | ||
| 3643 | static int pci_quirk_mf_endpoint_acs(struct pci_dev *dev, u16 acs_flags) | ||
| 3644 | { | ||
| 3645 | /* | ||
| 3646 | * SV, TB, and UF are not relevant to multifunction endpoints. | ||
| 3647 | * | ||
| 3648 | * Multifunction devices are only required to implement RR, CR, and DT | ||
| 3649 | * in their ACS capability if they support peer-to-peer transactions. | ||
| 3650 | * Devices matching this quirk have been verified by the vendor to not | ||
| 3651 | * perform peer-to-peer with other functions, allowing us to mask out | ||
| 3652 | * these bits as if they were unimplemented in the ACS capability. | ||
| 3653 | */ | ||
| 3654 | acs_flags &= ~(PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR | | ||
| 3655 | PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT); | ||
| 3656 | |||
| 3657 | return acs_flags ? 0 : 1; | ||
| 3658 | } | ||
| 3659 | |||
| 3667 | static const struct pci_dev_acs_enabled { | 3660 | static const struct pci_dev_acs_enabled { |
| 3668 | u16 vendor; | 3661 | u16 vendor; |
| 3669 | u16 device; | 3662 | u16 device; |
| @@ -3675,6 +3668,30 @@ static const struct pci_dev_acs_enabled { | |||
| 3675 | { PCI_VENDOR_ID_ATI, 0x439d, pci_quirk_amd_sb_acs }, | 3668 | { PCI_VENDOR_ID_ATI, 0x439d, pci_quirk_amd_sb_acs }, |
| 3676 | { PCI_VENDOR_ID_ATI, 0x4384, pci_quirk_amd_sb_acs }, | 3669 | { PCI_VENDOR_ID_ATI, 0x4384, pci_quirk_amd_sb_acs }, |
| 3677 | { PCI_VENDOR_ID_ATI, 0x4399, pci_quirk_amd_sb_acs }, | 3670 | { PCI_VENDOR_ID_ATI, 0x4399, pci_quirk_amd_sb_acs }, |
| 3671 | { PCI_VENDOR_ID_AMD, 0x780f, pci_quirk_amd_sb_acs }, | ||
| 3672 | { PCI_VENDOR_ID_AMD, 0x7809, pci_quirk_amd_sb_acs }, | ||
| 3673 | { PCI_VENDOR_ID_SOLARFLARE, 0x0903, pci_quirk_mf_endpoint_acs }, | ||
| 3674 | { PCI_VENDOR_ID_SOLARFLARE, 0x0923, pci_quirk_mf_endpoint_acs }, | ||
| 3675 | { PCI_VENDOR_ID_INTEL, 0x10C6, pci_quirk_mf_endpoint_acs }, | ||
| 3676 | { PCI_VENDOR_ID_INTEL, 0x10DB, pci_quirk_mf_endpoint_acs }, | ||
| 3677 | { PCI_VENDOR_ID_INTEL, 0x10DD, pci_quirk_mf_endpoint_acs }, | ||
| 3678 | { PCI_VENDOR_ID_INTEL, 0x10E1, pci_quirk_mf_endpoint_acs }, | ||
| 3679 | { PCI_VENDOR_ID_INTEL, 0x10F1, pci_quirk_mf_endpoint_acs }, | ||
| 3680 | { PCI_VENDOR_ID_INTEL, 0x10F7, pci_quirk_mf_endpoint_acs }, | ||
| 3681 | { PCI_VENDOR_ID_INTEL, 0x10F8, pci_quirk_mf_endpoint_acs }, | ||
| 3682 | { PCI_VENDOR_ID_INTEL, 0x10F9, pci_quirk_mf_endpoint_acs }, | ||
| 3683 | { PCI_VENDOR_ID_INTEL, 0x10FA, pci_quirk_mf_endpoint_acs }, | ||
| 3684 | { PCI_VENDOR_ID_INTEL, 0x10FB, pci_quirk_mf_endpoint_acs }, | ||
| 3685 | { PCI_VENDOR_ID_INTEL, 0x10FC, pci_quirk_mf_endpoint_acs }, | ||
| 3686 | { PCI_VENDOR_ID_INTEL, 0x1507, pci_quirk_mf_endpoint_acs }, | ||
| 3687 | { PCI_VENDOR_ID_INTEL, 0x1514, pci_quirk_mf_endpoint_acs }, | ||
| 3688 | { PCI_VENDOR_ID_INTEL, 0x151C, pci_quirk_mf_endpoint_acs }, | ||
| 3689 | { PCI_VENDOR_ID_INTEL, 0x1529, pci_quirk_mf_endpoint_acs }, | ||
| 3690 | { PCI_VENDOR_ID_INTEL, 0x152A, pci_quirk_mf_endpoint_acs }, | ||
| 3691 | { PCI_VENDOR_ID_INTEL, 0x154D, pci_quirk_mf_endpoint_acs }, | ||
| 3692 | { PCI_VENDOR_ID_INTEL, 0x154F, pci_quirk_mf_endpoint_acs }, | ||
| 3693 | { PCI_VENDOR_ID_INTEL, 0x1551, pci_quirk_mf_endpoint_acs }, | ||
| 3694 | { PCI_VENDOR_ID_INTEL, 0x1558, pci_quirk_mf_endpoint_acs }, | ||
| 3678 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, | 3695 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, |
| 3679 | { 0 } | 3696 | { 0 } |
| 3680 | }; | 3697 | }; |
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 827ad831f1dd..a81f413083e4 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
| @@ -103,40 +103,6 @@ int pci_for_each_dma_alias(struct pci_dev *pdev, | |||
| 103 | return ret; | 103 | return ret; |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | /* | ||
| 107 | * find the upstream PCIe-to-PCI bridge of a PCI device | ||
| 108 | * if the device is PCIE, return NULL | ||
| 109 | * if the device isn't connected to a PCIe bridge (that is its parent is a | ||
| 110 | * legacy PCI bridge and the bridge is directly connected to bus 0), return its | ||
| 111 | * parent | ||
| 112 | */ | ||
| 113 | struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev) | ||
| 114 | { | ||
| 115 | struct pci_dev *tmp = NULL; | ||
| 116 | |||
| 117 | if (pci_is_pcie(pdev)) | ||
| 118 | return NULL; | ||
| 119 | while (1) { | ||
| 120 | if (pci_is_root_bus(pdev->bus)) | ||
| 121 | break; | ||
| 122 | pdev = pdev->bus->self; | ||
| 123 | /* a p2p bridge */ | ||
| 124 | if (!pci_is_pcie(pdev)) { | ||
| 125 | tmp = pdev; | ||
| 126 | continue; | ||
| 127 | } | ||
| 128 | /* PCI device should connect to a PCIe bridge */ | ||
| 129 | if (pci_pcie_type(pdev) != PCI_EXP_TYPE_PCI_BRIDGE) { | ||
| 130 | /* Busted hardware? */ | ||
| 131 | WARN_ON_ONCE(1); | ||
| 132 | return NULL; | ||
| 133 | } | ||
| 134 | return pdev; | ||
| 135 | } | ||
| 136 | |||
| 137 | return tmp; | ||
| 138 | } | ||
| 139 | |||
| 140 | static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr) | 106 | static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr) |
| 141 | { | 107 | { |
| 142 | struct pci_bus *child; | 108 | struct pci_bus *child; |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 6373985ad3f7..0482235eee92 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
| @@ -1652,7 +1652,7 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) | |||
| 1652 | struct pci_dev_resource *fail_res; | 1652 | struct pci_dev_resource *fail_res; |
| 1653 | int retval; | 1653 | int retval; |
| 1654 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | 1654 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | |
| 1655 | IORESOURCE_PREFETCH; | 1655 | IORESOURCE_PREFETCH | IORESOURCE_MEM_64; |
| 1656 | 1656 | ||
| 1657 | again: | 1657 | again: |
| 1658 | __pci_bus_size_bridges(parent, &add_list); | 1658 | __pci_bus_size_bridges(parent, &add_list); |
diff --git a/drivers/scsi/vmw_pvscsi.h b/drivers/scsi/vmw_pvscsi.h index ce4588851274..ee16f0c5c47d 100644 --- a/drivers/scsi/vmw_pvscsi.h +++ b/drivers/scsi/vmw_pvscsi.h | |||
| @@ -32,7 +32,6 @@ | |||
| 32 | 32 | ||
| 33 | #define MASK(n) ((1 << (n)) - 1) /* make an n-bit mask */ | 33 | #define MASK(n) ((1 << (n)) - 1) /* make an n-bit mask */ |
| 34 | 34 | ||
| 35 | #define PCI_VENDOR_ID_VMWARE 0x15AD | ||
| 36 | #define PCI_DEVICE_ID_VMWARE_PVSCSI 0x07C0 | 35 | #define PCI_DEVICE_ID_VMWARE_PVSCSI 0x07C0 |
| 37 | 36 | ||
| 38 | /* | 37 | /* |
diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c index e50790e91f76..1de3f94aa7de 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c | |||
| @@ -727,7 +727,7 @@ static int __init init_pci_ext_cap_err_perm(struct perm_bits *perm) | |||
| 727 | p_setd(perm, 0, ALL_VIRT, NO_WRITE); | 727 | p_setd(perm, 0, ALL_VIRT, NO_WRITE); |
| 728 | 728 | ||
| 729 | /* Writable bits mask */ | 729 | /* Writable bits mask */ |
| 730 | mask = PCI_ERR_UNC_TRAIN | /* Training */ | 730 | mask = PCI_ERR_UNC_UND | /* Undefined */ |
| 731 | PCI_ERR_UNC_DLP | /* Data Link Protocol */ | 731 | PCI_ERR_UNC_DLP | /* Data Link Protocol */ |
| 732 | PCI_ERR_UNC_SURPDN | /* Surprise Down */ | 732 | PCI_ERR_UNC_SURPDN | /* Surprise Down */ |
| 733 | PCI_ERR_UNC_POISON_TLP | /* Poisoned TLP */ | 733 | PCI_ERR_UNC_POISON_TLP | /* Poisoned TLP */ |
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 259ba2661543..017069a455d4 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c | |||
| @@ -133,7 +133,7 @@ static void pcistub_device_release(struct kref *kref) | |||
| 133 | xen_pcibk_config_free_dyn_fields(dev); | 133 | xen_pcibk_config_free_dyn_fields(dev); |
| 134 | xen_pcibk_config_free_dev(dev); | 134 | xen_pcibk_config_free_dev(dev); |
| 135 | 135 | ||
| 136 | dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED; | 136 | pci_clear_dev_assigned(dev); |
| 137 | pci_dev_put(dev); | 137 | pci_dev_put(dev); |
| 138 | 138 | ||
| 139 | kfree(psdev); | 139 | kfree(psdev); |
| @@ -413,7 +413,7 @@ static int pcistub_init_device(struct pci_dev *dev) | |||
| 413 | dev_dbg(&dev->dev, "reset device\n"); | 413 | dev_dbg(&dev->dev, "reset device\n"); |
| 414 | xen_pcibk_reset_device(dev); | 414 | xen_pcibk_reset_device(dev); |
| 415 | 415 | ||
| 416 | dev->dev_flags |= PCI_DEV_FLAGS_ASSIGNED; | 416 | pci_set_dev_assigned(dev); |
| 417 | return 0; | 417 | return 0; |
| 418 | 418 | ||
| 419 | config_release: | 419 | config_release: |
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h index 975e1cc75edb..b8fdc57a7335 100644 --- a/include/asm-generic/io.h +++ b/include/asm-generic/io.h | |||
| @@ -331,7 +331,7 @@ static inline void iounmap(void __iomem *addr) | |||
| 331 | #ifndef CONFIG_GENERIC_IOMAP | 331 | #ifndef CONFIG_GENERIC_IOMAP |
| 332 | static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) | 332 | static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) |
| 333 | { | 333 | { |
| 334 | return (void __iomem *) port; | 334 | return PCI_IOBASE + (port & IO_SPACE_LIMIT); |
| 335 | } | 335 | } |
| 336 | 336 | ||
| 337 | static inline void ioport_unmap(void __iomem *p) | 337 | static inline void ioport_unmap(void __iomem *p) |
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 53b2acc38213..977e545a64c3 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h | |||
| @@ -249,6 +249,10 @@ static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b) | |||
| 249 | #define pgprot_writecombine pgprot_noncached | 249 | #define pgprot_writecombine pgprot_noncached |
| 250 | #endif | 250 | #endif |
| 251 | 251 | ||
| 252 | #ifndef pgprot_device | ||
| 253 | #define pgprot_device pgprot_noncached | ||
| 254 | #endif | ||
| 255 | |||
| 252 | /* | 256 | /* |
| 253 | * When walking page tables, get the address of the next boundary, | 257 | * When walking page tables, get the address of the next boundary, |
| 254 | * or the end address of the range if that comes earlier. Although no | 258 | * or the end address of the range if that comes earlier. Although no |
diff --git a/include/linux/aer.h b/include/linux/aer.h index c826d1c28f9c..4fef65e57023 100644 --- a/include/linux/aer.h +++ b/include/linux/aer.h | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | #ifndef _AER_H_ | 7 | #ifndef _AER_H_ |
| 8 | #define _AER_H_ | 8 | #define _AER_H_ |
| 9 | 9 | ||
| 10 | #include <linux/types.h> | ||
| 11 | |||
| 10 | #define AER_NONFATAL 0 | 12 | #define AER_NONFATAL 0 |
| 11 | #define AER_FATAL 1 | 13 | #define AER_FATAL 1 |
| 12 | #define AER_CORRECTABLE 2 | 14 | #define AER_CORRECTABLE 2 |
diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 142ec544167c..2c5250222278 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h | |||
| @@ -215,6 +215,11 @@ static inline int __deprecated check_region(resource_size_t s, | |||
| 215 | 215 | ||
| 216 | /* Wrappers for managed devices */ | 216 | /* Wrappers for managed devices */ |
| 217 | struct device; | 217 | struct device; |
| 218 | |||
| 219 | extern int devm_request_resource(struct device *dev, struct resource *root, | ||
| 220 | struct resource *new); | ||
| 221 | extern void devm_release_resource(struct device *dev, struct resource *new); | ||
| 222 | |||
| 218 | #define devm_request_region(dev,start,n,name) \ | 223 | #define devm_request_region(dev,start,n,name) \ |
| 219 | __devm_request_region(dev, &ioport_resource, (start), (n), (name)) | 224 | __devm_request_region(dev, &ioport_resource, (start), (n), (name)) |
| 220 | #define devm_request_mem_region(dev,start,n,name) \ | 225 | #define devm_request_mem_region(dev,start,n,name) \ |
diff --git a/include/linux/msi.h b/include/linux/msi.h index 8103f32f6d87..44f4746d033b 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h | |||
| @@ -29,7 +29,6 @@ struct msi_desc { | |||
| 29 | __u8 multi_cap : 3; /* log2 num of messages supported */ | 29 | __u8 multi_cap : 3; /* log2 num of messages supported */ |
| 30 | __u8 maskbit : 1; /* mask-pending bit supported ? */ | 30 | __u8 maskbit : 1; /* mask-pending bit supported ? */ |
| 31 | __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */ | 31 | __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */ |
| 32 | __u8 pos; /* Location of the msi capability */ | ||
| 33 | __u16 entry_nr; /* specific enabled entry */ | 32 | __u16 entry_nr; /* specific enabled entry */ |
| 34 | unsigned default_irq; /* default pre-assigned irq */ | 33 | unsigned default_irq; /* default pre-assigned irq */ |
| 35 | } msi_attrib; | 34 | } msi_attrib; |
| @@ -47,8 +46,6 @@ struct msi_desc { | |||
| 47 | 46 | ||
| 48 | /* Last set MSI message */ | 47 | /* Last set MSI message */ |
| 49 | struct msi_msg msg; | 48 | struct msi_msg msg; |
| 50 | |||
| 51 | struct kobject kobj; | ||
| 52 | }; | 49 | }; |
| 53 | 50 | ||
| 54 | /* | 51 | /* |
| @@ -60,7 +57,6 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc); | |||
| 60 | void arch_teardown_msi_irq(unsigned int irq); | 57 | void arch_teardown_msi_irq(unsigned int irq); |
| 61 | int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); | 58 | int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); |
| 62 | void arch_teardown_msi_irqs(struct pci_dev *dev); | 59 | void arch_teardown_msi_irqs(struct pci_dev *dev); |
| 63 | int arch_msi_check_device(struct pci_dev* dev, int nvec, int type); | ||
| 64 | void arch_restore_msi_irqs(struct pci_dev *dev); | 60 | void arch_restore_msi_irqs(struct pci_dev *dev); |
| 65 | 61 | ||
| 66 | void default_teardown_msi_irqs(struct pci_dev *dev); | 62 | void default_teardown_msi_irqs(struct pci_dev *dev); |
| @@ -77,8 +73,6 @@ struct msi_chip { | |||
| 77 | int (*setup_irq)(struct msi_chip *chip, struct pci_dev *dev, | 73 | int (*setup_irq)(struct msi_chip *chip, struct pci_dev *dev, |
| 78 | struct msi_desc *desc); | 74 | struct msi_desc *desc); |
| 79 | void (*teardown_irq)(struct msi_chip *chip, unsigned int irq); | 75 | void (*teardown_irq)(struct msi_chip *chip, unsigned int irq); |
| 80 | int (*check_device)(struct msi_chip *chip, struct pci_dev *dev, | ||
| 81 | int nvec, int type); | ||
| 82 | }; | 76 | }; |
| 83 | 77 | ||
| 84 | #endif /* LINUX_MSI_H */ | 78 | #endif /* LINUX_MSI_H */ |
diff --git a/include/linux/of_address.h b/include/linux/of_address.h index fb7b7221e063..8cb14eb393d6 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h | |||
| @@ -23,17 +23,6 @@ struct of_pci_range { | |||
| 23 | #define for_each_of_pci_range(parser, range) \ | 23 | #define for_each_of_pci_range(parser, range) \ |
| 24 | for (; of_pci_range_parser_one(parser, range);) | 24 | for (; of_pci_range_parser_one(parser, range);) |
| 25 | 25 | ||
| 26 | static inline void of_pci_range_to_resource(struct of_pci_range *range, | ||
| 27 | struct device_node *np, | ||
| 28 | struct resource *res) | ||
| 29 | { | ||
| 30 | res->flags = range->flags; | ||
| 31 | res->start = range->cpu_addr; | ||
| 32 | res->end = range->cpu_addr + range->size - 1; | ||
| 33 | res->parent = res->child = res->sibling = NULL; | ||
| 34 | res->name = np->full_name; | ||
| 35 | } | ||
| 36 | |||
| 37 | /* Translate a DMA address from device space to CPU space */ | 26 | /* Translate a DMA address from device space to CPU space */ |
| 38 | extern u64 of_translate_dma_address(struct device_node *dev, | 27 | extern u64 of_translate_dma_address(struct device_node *dev, |
| 39 | const __be32 *in_addr); | 28 | const __be32 *in_addr); |
| @@ -55,7 +44,9 @@ extern void __iomem *of_iomap(struct device_node *device, int index); | |||
| 55 | extern const __be32 *of_get_address(struct device_node *dev, int index, | 44 | extern const __be32 *of_get_address(struct device_node *dev, int index, |
| 56 | u64 *size, unsigned int *flags); | 45 | u64 *size, unsigned int *flags); |
| 57 | 46 | ||
| 47 | extern int pci_register_io_range(phys_addr_t addr, resource_size_t size); | ||
| 58 | extern unsigned long pci_address_to_pio(phys_addr_t addr); | 48 | extern unsigned long pci_address_to_pio(phys_addr_t addr); |
| 49 | extern phys_addr_t pci_pio_to_address(unsigned long pio); | ||
| 59 | 50 | ||
| 60 | extern int of_pci_range_parser_init(struct of_pci_range_parser *parser, | 51 | extern int of_pci_range_parser_init(struct of_pci_range_parser *parser, |
| 61 | struct device_node *node); | 52 | struct device_node *node); |
| @@ -80,6 +71,11 @@ static inline const __be32 *of_get_address(struct device_node *dev, int index, | |||
| 80 | return NULL; | 71 | return NULL; |
| 81 | } | 72 | } |
| 82 | 73 | ||
| 74 | static inline phys_addr_t pci_pio_to_address(unsigned long pio) | ||
| 75 | { | ||
| 76 | return 0; | ||
| 77 | } | ||
| 78 | |||
| 83 | static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser, | 79 | static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser, |
| 84 | struct device_node *node) | 80 | struct device_node *node) |
| 85 | { | 81 | { |
| @@ -138,6 +134,9 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, | |||
| 138 | u64 *size, unsigned int *flags); | 134 | u64 *size, unsigned int *flags); |
| 139 | extern int of_pci_address_to_resource(struct device_node *dev, int bar, | 135 | extern int of_pci_address_to_resource(struct device_node *dev, int bar, |
| 140 | struct resource *r); | 136 | struct resource *r); |
| 137 | extern int of_pci_range_to_resource(struct of_pci_range *range, | ||
| 138 | struct device_node *np, | ||
| 139 | struct resource *res); | ||
| 141 | #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */ | 140 | #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */ |
| 142 | static inline int of_pci_address_to_resource(struct device_node *dev, int bar, | 141 | static inline int of_pci_address_to_resource(struct device_node *dev, int bar, |
| 143 | struct resource *r) | 142 | struct resource *r) |
| @@ -150,6 +149,12 @@ static inline const __be32 *of_get_pci_address(struct device_node *dev, | |||
| 150 | { | 149 | { |
| 151 | return NULL; | 150 | return NULL; |
| 152 | } | 151 | } |
| 152 | static inline int of_pci_range_to_resource(struct of_pci_range *range, | ||
| 153 | struct device_node *np, | ||
| 154 | struct resource *res) | ||
| 155 | { | ||
| 156 | return -ENOSYS; | ||
| 157 | } | ||
| 153 | #endif /* CONFIG_OF_ADDRESS && CONFIG_PCI */ | 158 | #endif /* CONFIG_OF_ADDRESS && CONFIG_PCI */ |
| 154 | 159 | ||
| 155 | #endif /* __OF_ADDRESS_H */ | 160 | #endif /* __OF_ADDRESS_H */ |
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h index dde3a4a0fa5d..1fd207e7a847 100644 --- a/include/linux/of_pci.h +++ b/include/linux/of_pci.h | |||
| @@ -15,6 +15,7 @@ struct device_node *of_pci_find_child_device(struct device_node *parent, | |||
| 15 | int of_pci_get_devfn(struct device_node *np); | 15 | int of_pci_get_devfn(struct device_node *np); |
| 16 | int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin); | 16 | int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin); |
| 17 | int of_pci_parse_bus_range(struct device_node *node, struct resource *res); | 17 | int of_pci_parse_bus_range(struct device_node *node, struct resource *res); |
| 18 | int of_get_pci_domain_nr(struct device_node *node); | ||
| 18 | #else | 19 | #else |
| 19 | static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq) | 20 | static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq) |
| 20 | { | 21 | { |
| @@ -43,6 +44,18 @@ of_pci_parse_bus_range(struct device_node *node, struct resource *res) | |||
| 43 | { | 44 | { |
| 44 | return -EINVAL; | 45 | return -EINVAL; |
| 45 | } | 46 | } |
| 47 | |||
| 48 | static inline int | ||
| 49 | of_get_pci_domain_nr(struct device_node *node) | ||
| 50 | { | ||
| 51 | return -1; | ||
| 52 | } | ||
| 53 | #endif | ||
| 54 | |||
| 55 | #if defined(CONFIG_OF_ADDRESS) | ||
| 56 | int of_pci_get_host_bridge_resources(struct device_node *dev, | ||
| 57 | unsigned char busno, unsigned char bus_max, | ||
| 58 | struct list_head *resources, resource_size_t *io_base); | ||
| 46 | #endif | 59 | #endif |
| 47 | 60 | ||
| 48 | #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI) | 61 | #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI) |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 96453f9bc8ba..5be8db45e368 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
| @@ -45,7 +45,7 @@ | |||
| 45 | * In the interest of not exposing interfaces to user-space unnecessarily, | 45 | * In the interest of not exposing interfaces to user-space unnecessarily, |
| 46 | * the following kernel-only defines are being added here. | 46 | * the following kernel-only defines are being added here. |
| 47 | */ | 47 | */ |
| 48 | #define PCI_DEVID(bus, devfn) ((((u16)bus) << 8) | devfn) | 48 | #define PCI_DEVID(bus, devfn) ((((u16)(bus)) << 8) | (devfn)) |
| 49 | /* return bus from PCI devid = ((u16)bus_number) << 8) | devfn */ | 49 | /* return bus from PCI devid = ((u16)bus_number) << 8) | devfn */ |
| 50 | #define PCI_BUS_NUM(x) (((x) >> 8) & 0xff) | 50 | #define PCI_BUS_NUM(x) (((x) >> 8) & 0xff) |
| 51 | 51 | ||
| @@ -457,6 +457,9 @@ struct pci_bus { | |||
| 457 | unsigned char primary; /* number of primary bridge */ | 457 | unsigned char primary; /* number of primary bridge */ |
| 458 | unsigned char max_bus_speed; /* enum pci_bus_speed */ | 458 | unsigned char max_bus_speed; /* enum pci_bus_speed */ |
| 459 | unsigned char cur_bus_speed; /* enum pci_bus_speed */ | 459 | unsigned char cur_bus_speed; /* enum pci_bus_speed */ |
| 460 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | ||
| 461 | int domain_nr; | ||
| 462 | #endif | ||
| 460 | 463 | ||
| 461 | char name[48]; | 464 | char name[48]; |
| 462 | 465 | ||
| @@ -1103,6 +1106,9 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus, | |||
| 1103 | resource_size_t), | 1106 | resource_size_t), |
| 1104 | void *alignf_data); | 1107 | void *alignf_data); |
| 1105 | 1108 | ||
| 1109 | |||
| 1110 | int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr); | ||
| 1111 | |||
| 1106 | static inline dma_addr_t pci_bus_address(struct pci_dev *pdev, int bar) | 1112 | static inline dma_addr_t pci_bus_address(struct pci_dev *pdev, int bar) |
| 1107 | { | 1113 | { |
| 1108 | struct pci_bus_region region; | 1114 | struct pci_bus_region region; |
| @@ -1288,12 +1294,32 @@ void pci_cfg_access_unlock(struct pci_dev *dev); | |||
| 1288 | */ | 1294 | */ |
| 1289 | #ifdef CONFIG_PCI_DOMAINS | 1295 | #ifdef CONFIG_PCI_DOMAINS |
| 1290 | extern int pci_domains_supported; | 1296 | extern int pci_domains_supported; |
| 1297 | int pci_get_new_domain_nr(void); | ||
| 1291 | #else | 1298 | #else |
| 1292 | enum { pci_domains_supported = 0 }; | 1299 | enum { pci_domains_supported = 0 }; |
| 1293 | static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } | 1300 | static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } |
| 1294 | static inline int pci_proc_domain(struct pci_bus *bus) { return 0; } | 1301 | static inline int pci_proc_domain(struct pci_bus *bus) { return 0; } |
| 1302 | static inline int pci_get_new_domain_nr(void) { return -ENOSYS; } | ||
| 1295 | #endif /* CONFIG_PCI_DOMAINS */ | 1303 | #endif /* CONFIG_PCI_DOMAINS */ |
| 1296 | 1304 | ||
| 1305 | /* | ||
| 1306 | * Generic implementation for PCI domain support. If your | ||
| 1307 | * architecture does not need custom management of PCI | ||
| 1308 | * domains then this implementation will be used | ||
| 1309 | */ | ||
| 1310 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | ||
| 1311 | static inline int pci_domain_nr(struct pci_bus *bus) | ||
| 1312 | { | ||
| 1313 | return bus->domain_nr; | ||
| 1314 | } | ||
| 1315 | void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent); | ||
| 1316 | #else | ||
| 1317 | static inline void pci_bus_assign_domain_nr(struct pci_bus *bus, | ||
| 1318 | struct device *parent) | ||
| 1319 | { | ||
| 1320 | } | ||
| 1321 | #endif | ||
| 1322 | |||
| 1297 | /* some architectures require additional setup to direct VGA traffic */ | 1323 | /* some architectures require additional setup to direct VGA traffic */ |
| 1298 | typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode, | 1324 | typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode, |
| 1299 | unsigned int command_bits, u32 flags); | 1325 | unsigned int command_bits, u32 flags); |
| @@ -1402,6 +1428,7 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus, | |||
| 1402 | 1428 | ||
| 1403 | static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } | 1429 | static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } |
| 1404 | static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; } | 1430 | static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; } |
| 1431 | static inline int pci_get_new_domain_nr(void) { return -ENOSYS; } | ||
| 1405 | 1432 | ||
| 1406 | #define dev_is_pci(d) (false) | 1433 | #define dev_is_pci(d) (false) |
| 1407 | #define dev_is_pf(d) (false) | 1434 | #define dev_is_pf(d) (false) |
| @@ -1563,16 +1590,11 @@ enum pci_fixup_pass { | |||
| 1563 | 1590 | ||
| 1564 | #ifdef CONFIG_PCI_QUIRKS | 1591 | #ifdef CONFIG_PCI_QUIRKS |
| 1565 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); | 1592 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); |
| 1566 | struct pci_dev *pci_get_dma_source(struct pci_dev *dev); | ||
| 1567 | int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags); | 1593 | int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags); |
| 1568 | void pci_dev_specific_enable_acs(struct pci_dev *dev); | 1594 | void pci_dev_specific_enable_acs(struct pci_dev *dev); |
| 1569 | #else | 1595 | #else |
| 1570 | static inline void pci_fixup_device(enum pci_fixup_pass pass, | 1596 | static inline void pci_fixup_device(enum pci_fixup_pass pass, |
| 1571 | struct pci_dev *dev) { } | 1597 | struct pci_dev *dev) { } |
| 1572 | static inline struct pci_dev *pci_get_dma_source(struct pci_dev *dev) | ||
| 1573 | { | ||
| 1574 | return pci_dev_get(dev); | ||
| 1575 | } | ||
| 1576 | static inline int pci_dev_specific_acs_enabled(struct pci_dev *dev, | 1598 | static inline int pci_dev_specific_acs_enabled(struct pci_dev *dev, |
| 1577 | u16 acs_flags) | 1599 | u16 acs_flags) |
| 1578 | { | 1600 | { |
| @@ -1707,7 +1729,7 @@ bool pci_acs_path_enabled(struct pci_dev *start, | |||
| 1707 | struct pci_dev *end, u16 acs_flags); | 1729 | struct pci_dev *end, u16 acs_flags); |
| 1708 | 1730 | ||
| 1709 | #define PCI_VPD_LRDT 0x80 /* Large Resource Data Type */ | 1731 | #define PCI_VPD_LRDT 0x80 /* Large Resource Data Type */ |
| 1710 | #define PCI_VPD_LRDT_ID(x) (x | PCI_VPD_LRDT) | 1732 | #define PCI_VPD_LRDT_ID(x) ((x) | PCI_VPD_LRDT) |
| 1711 | 1733 | ||
| 1712 | /* Large Resource Data Type Tag Item Names */ | 1734 | /* Large Resource Data Type Tag Item Names */ |
| 1713 | #define PCI_VPD_LTIN_ID_STRING 0x02 /* Identifier String */ | 1735 | #define PCI_VPD_LTIN_ID_STRING 0x02 /* Identifier String */ |
| @@ -1834,15 +1856,17 @@ int pci_for_each_dma_alias(struct pci_dev *pdev, | |||
| 1834 | int (*fn)(struct pci_dev *pdev, | 1856 | int (*fn)(struct pci_dev *pdev, |
| 1835 | u16 alias, void *data), void *data); | 1857 | u16 alias, void *data), void *data); |
| 1836 | 1858 | ||
| 1837 | /** | 1859 | /* helper functions for operation of device flag */ |
| 1838 | * pci_find_upstream_pcie_bridge - find upstream PCIe-to-PCI bridge of a device | 1860 | static inline void pci_set_dev_assigned(struct pci_dev *pdev) |
| 1839 | * @pdev: the PCI device | 1861 | { |
| 1840 | * | 1862 | pdev->dev_flags |= PCI_DEV_FLAGS_ASSIGNED; |
| 1841 | * if the device is PCIE, return NULL | 1863 | } |
| 1842 | * if the device isn't connected to a PCIe bridge (that is its parent is a | 1864 | static inline void pci_clear_dev_assigned(struct pci_dev *pdev) |
| 1843 | * legacy PCI bridge and the bridge is directly connected to bus 0), return its | 1865 | { |
| 1844 | * parent | 1866 | pdev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED; |
| 1845 | */ | 1867 | } |
| 1846 | struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev); | 1868 | static inline bool pci_is_dev_assigned(struct pci_dev *pdev) |
| 1847 | 1869 | { | |
| 1870 | return (pdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED) == PCI_DEV_FLAGS_ASSIGNED; | ||
| 1871 | } | ||
| 1848 | #endif /* LINUX_PCI_H */ | 1872 | #endif /* LINUX_PCI_H */ |
diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index 5f2e559af6b0..2706ee9a4327 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h | |||
| @@ -187,6 +187,4 @@ static inline int pci_get_hp_params(struct pci_dev *dev, | |||
| 187 | return -ENODEV; | 187 | return -ENODEV; |
| 188 | } | 188 | } |
| 189 | #endif | 189 | #endif |
| 190 | |||
| 191 | void pci_configure_slot(struct pci_dev *dev); | ||
| 192 | #endif | 190 | #endif |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 6ed0bb73a864..da9e6f753196 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
| @@ -2245,6 +2245,8 @@ | |||
| 2245 | #define PCI_VENDOR_ID_MORETON 0x15aa | 2245 | #define PCI_VENDOR_ID_MORETON 0x15aa |
| 2246 | #define PCI_DEVICE_ID_RASTEL_2PORT 0x2000 | 2246 | #define PCI_DEVICE_ID_RASTEL_2PORT 0x2000 |
| 2247 | 2247 | ||
| 2248 | #define PCI_VENDOR_ID_VMWARE 0x15ad | ||
| 2249 | |||
| 2248 | #define PCI_VENDOR_ID_ZOLTRIX 0x15b0 | 2250 | #define PCI_VENDOR_ID_ZOLTRIX 0x15b0 |
| 2249 | #define PCI_DEVICE_ID_ZOLTRIX_2BD0 0x2bd0 | 2251 | #define PCI_DEVICE_ID_ZOLTRIX_2BD0 0x2bd0 |
| 2250 | 2252 | ||
diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h index 47da53c27ffa..79abb9c71772 100644 --- a/include/ras/ras_event.h +++ b/include/ras/ras_event.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <linux/tracepoint.h> | 8 | #include <linux/tracepoint.h> |
| 9 | #include <linux/edac.h> | 9 | #include <linux/edac.h> |
| 10 | #include <linux/ktime.h> | 10 | #include <linux/ktime.h> |
| 11 | #include <linux/pci.h> | ||
| 11 | #include <linux/aer.h> | 12 | #include <linux/aer.h> |
| 12 | #include <linux/cper.h> | 13 | #include <linux/cper.h> |
| 13 | 14 | ||
| @@ -173,25 +174,34 @@ TRACE_EVENT(mc_event, | |||
| 173 | * u8 severity - error severity 0:NONFATAL 1:FATAL 2:CORRECTED | 174 | * u8 severity - error severity 0:NONFATAL 1:FATAL 2:CORRECTED |
| 174 | */ | 175 | */ |
| 175 | 176 | ||
| 176 | #define aer_correctable_errors \ | 177 | #define aer_correctable_errors \ |
| 177 | {BIT(0), "Receiver Error"}, \ | 178 | {PCI_ERR_COR_RCVR, "Receiver Error"}, \ |
| 178 | {BIT(6), "Bad TLP"}, \ | 179 | {PCI_ERR_COR_BAD_TLP, "Bad TLP"}, \ |
| 179 | {BIT(7), "Bad DLLP"}, \ | 180 | {PCI_ERR_COR_BAD_DLLP, "Bad DLLP"}, \ |
| 180 | {BIT(8), "RELAY_NUM Rollover"}, \ | 181 | {PCI_ERR_COR_REP_ROLL, "RELAY_NUM Rollover"}, \ |
| 181 | {BIT(12), "Replay Timer Timeout"}, \ | 182 | {PCI_ERR_COR_REP_TIMER, "Replay Timer Timeout"}, \ |
| 182 | {BIT(13), "Advisory Non-Fatal"} | 183 | {PCI_ERR_COR_ADV_NFAT, "Advisory Non-Fatal Error"}, \ |
| 183 | 184 | {PCI_ERR_COR_INTERNAL, "Corrected Internal Error"}, \ | |
| 184 | #define aer_uncorrectable_errors \ | 185 | {PCI_ERR_COR_LOG_OVER, "Header Log Overflow"} |
| 185 | {BIT(4), "Data Link Protocol"}, \ | 186 | |
| 186 | {BIT(12), "Poisoned TLP"}, \ | 187 | #define aer_uncorrectable_errors \ |
| 187 | {BIT(13), "Flow Control Protocol"}, \ | 188 | {PCI_ERR_UNC_UND, "Undefined"}, \ |
| 188 | {BIT(14), "Completion Timeout"}, \ | 189 | {PCI_ERR_UNC_DLP, "Data Link Protocol Error"}, \ |
| 189 | {BIT(15), "Completer Abort"}, \ | 190 | {PCI_ERR_UNC_SURPDN, "Surprise Down Error"}, \ |
| 190 | {BIT(16), "Unexpected Completion"}, \ | 191 | {PCI_ERR_UNC_POISON_TLP,"Poisoned TLP"}, \ |
| 191 | {BIT(17), "Receiver Overflow"}, \ | 192 | {PCI_ERR_UNC_FCP, "Flow Control Protocol Error"}, \ |
| 192 | {BIT(18), "Malformed TLP"}, \ | 193 | {PCI_ERR_UNC_COMP_TIME, "Completion Timeout"}, \ |
| 193 | {BIT(19), "ECRC"}, \ | 194 | {PCI_ERR_UNC_COMP_ABORT,"Completer Abort"}, \ |
| 194 | {BIT(20), "Unsupported Request"} | 195 | {PCI_ERR_UNC_UNX_COMP, "Unexpected Completion"}, \ |
| 196 | {PCI_ERR_UNC_RX_OVER, "Receiver Overflow"}, \ | ||
| 197 | {PCI_ERR_UNC_MALF_TLP, "Malformed TLP"}, \ | ||
| 198 | {PCI_ERR_UNC_ECRC, "ECRC Error"}, \ | ||
| 199 | {PCI_ERR_UNC_UNSUP, "Unsupported Request Error"}, \ | ||
| 200 | {PCI_ERR_UNC_ACSV, "ACS Violation"}, \ | ||
| 201 | {PCI_ERR_UNC_INTN, "Uncorrectable Internal Error"},\ | ||
| 202 | {PCI_ERR_UNC_MCBTLP, "MC Blocked TLP"}, \ | ||
| 203 | {PCI_ERR_UNC_ATOMEG, "AtomicOp Egress Blocked"}, \ | ||
| 204 | {PCI_ERR_UNC_TLPPRE, "TLP Prefix Blocked Error"} | ||
| 195 | 205 | ||
| 196 | TRACE_EVENT(aer_event, | 206 | TRACE_EVENT(aer_event, |
| 197 | TP_PROTO(const char *dev_name, | 207 | TP_PROTO(const char *dev_name, |
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index 30db069bce62..4a1d0cc38ff2 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h | |||
| @@ -552,6 +552,7 @@ | |||
| 552 | #define PCI_EXP_RTCTL_PMEIE 0x0008 /* PME Interrupt Enable */ | 552 | #define PCI_EXP_RTCTL_PMEIE 0x0008 /* PME Interrupt Enable */ |
| 553 | #define PCI_EXP_RTCTL_CRSSVE 0x0010 /* CRS Software Visibility Enable */ | 553 | #define PCI_EXP_RTCTL_CRSSVE 0x0010 /* CRS Software Visibility Enable */ |
| 554 | #define PCI_EXP_RTCAP 30 /* Root Capabilities */ | 554 | #define PCI_EXP_RTCAP 30 /* Root Capabilities */ |
| 555 | #define PCI_EXP_RTCAP_CRSVIS 0x0001 /* CRS Software Visibility capability */ | ||
| 555 | #define PCI_EXP_RTSTA 32 /* Root Status */ | 556 | #define PCI_EXP_RTSTA 32 /* Root Status */ |
| 556 | #define PCI_EXP_RTSTA_PME 0x00010000 /* PME status */ | 557 | #define PCI_EXP_RTSTA_PME 0x00010000 /* PME status */ |
| 557 | #define PCI_EXP_RTSTA_PENDING 0x00020000 /* PME pending */ | 558 | #define PCI_EXP_RTSTA_PENDING 0x00020000 /* PME pending */ |
| @@ -630,7 +631,7 @@ | |||
| 630 | 631 | ||
| 631 | /* Advanced Error Reporting */ | 632 | /* Advanced Error Reporting */ |
| 632 | #define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */ | 633 | #define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */ |
| 633 | #define PCI_ERR_UNC_TRAIN 0x00000001 /* Training */ | 634 | #define PCI_ERR_UNC_UND 0x00000001 /* Undefined */ |
| 634 | #define PCI_ERR_UNC_DLP 0x00000010 /* Data Link Protocol */ | 635 | #define PCI_ERR_UNC_DLP 0x00000010 /* Data Link Protocol */ |
| 635 | #define PCI_ERR_UNC_SURPDN 0x00000020 /* Surprise Down */ | 636 | #define PCI_ERR_UNC_SURPDN 0x00000020 /* Surprise Down */ |
| 636 | #define PCI_ERR_UNC_POISON_TLP 0x00001000 /* Poisoned TLP */ | 637 | #define PCI_ERR_UNC_POISON_TLP 0x00001000 /* Poisoned TLP */ |
diff --git a/kernel/resource.c b/kernel/resource.c index 60c5a3856ab7..46322019ab7d 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
| @@ -1245,6 +1245,76 @@ int release_mem_region_adjustable(struct resource *parent, | |||
| 1245 | /* | 1245 | /* |
| 1246 | * Managed region resource | 1246 | * Managed region resource |
| 1247 | */ | 1247 | */ |
| 1248 | static void devm_resource_release(struct device *dev, void *ptr) | ||
| 1249 | { | ||
| 1250 | struct resource **r = ptr; | ||
| 1251 | |||
| 1252 | release_resource(*r); | ||
| 1253 | } | ||
| 1254 | |||
| 1255 | /** | ||
| 1256 | * devm_request_resource() - request and reserve an I/O or memory resource | ||
| 1257 | * @dev: device for which to request the resource | ||
| 1258 | * @root: root of the resource tree from which to request the resource | ||
| 1259 | * @new: descriptor of the resource to request | ||
| 1260 | * | ||
| 1261 | * This is a device-managed version of request_resource(). There is usually | ||
| 1262 | * no need to release resources requested by this function explicitly since | ||
| 1263 | * that will be taken care of when the device is unbound from its driver. | ||
| 1264 | * If for some reason the resource needs to be released explicitly, because | ||
| 1265 | * of ordering issues for example, drivers must call devm_release_resource() | ||
| 1266 | * rather than the regular release_resource(). | ||
| 1267 | * | ||
| 1268 | * When a conflict is detected between any existing resources and the newly | ||
| 1269 | * requested resource, an error message will be printed. | ||
| 1270 | * | ||
| 1271 | * Returns 0 on success or a negative error code on failure. | ||
| 1272 | */ | ||
| 1273 | int devm_request_resource(struct device *dev, struct resource *root, | ||
| 1274 | struct resource *new) | ||
| 1275 | { | ||
| 1276 | struct resource *conflict, **ptr; | ||
| 1277 | |||
| 1278 | ptr = devres_alloc(devm_resource_release, sizeof(*ptr), GFP_KERNEL); | ||
| 1279 | if (!ptr) | ||
| 1280 | return -ENOMEM; | ||
| 1281 | |||
| 1282 | *ptr = new; | ||
| 1283 | |||
| 1284 | conflict = request_resource_conflict(root, new); | ||
| 1285 | if (conflict) { | ||
| 1286 | dev_err(dev, "resource collision: %pR conflicts with %s %pR\n", | ||
| 1287 | new, conflict->name, conflict); | ||
| 1288 | devres_free(ptr); | ||
| 1289 | return -EBUSY; | ||
| 1290 | } | ||
| 1291 | |||
| 1292 | devres_add(dev, ptr); | ||
| 1293 | return 0; | ||
| 1294 | } | ||
| 1295 | EXPORT_SYMBOL(devm_request_resource); | ||
| 1296 | |||
| 1297 | static int devm_resource_match(struct device *dev, void *res, void *data) | ||
| 1298 | { | ||
| 1299 | struct resource **ptr = res; | ||
| 1300 | |||
| 1301 | return *ptr == data; | ||
| 1302 | } | ||
| 1303 | |||
| 1304 | /** | ||
| 1305 | * devm_release_resource() - release a previously requested resource | ||
| 1306 | * @dev: device for which to release the resource | ||
| 1307 | * @new: descriptor of the resource to release | ||
| 1308 | * | ||
| 1309 | * Releases a resource previously requested using devm_request_resource(). | ||
| 1310 | */ | ||
| 1311 | void devm_release_resource(struct device *dev, struct resource *new) | ||
| 1312 | { | ||
| 1313 | WARN_ON(devres_release(dev, devm_resource_release, devm_resource_match, | ||
| 1314 | new)); | ||
| 1315 | } | ||
| 1316 | EXPORT_SYMBOL(devm_release_resource); | ||
| 1317 | |||
| 1248 | struct region_devres { | 1318 | struct region_devres { |
| 1249 | struct resource *parent; | 1319 | struct resource *parent; |
| 1250 | resource_size_t start; | 1320 | resource_size_t start; |
diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index 5819a2708d7e..e05000e200d2 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c | |||
| @@ -302,7 +302,7 @@ static void kvm_free_assigned_device(struct kvm *kvm, | |||
| 302 | else | 302 | else |
| 303 | pci_restore_state(assigned_dev->dev); | 303 | pci_restore_state(assigned_dev->dev); |
| 304 | 304 | ||
| 305 | assigned_dev->dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED; | 305 | pci_clear_dev_assigned(assigned_dev->dev); |
| 306 | 306 | ||
| 307 | pci_release_regions(assigned_dev->dev); | 307 | pci_release_regions(assigned_dev->dev); |
| 308 | pci_disable_device(assigned_dev->dev); | 308 | pci_disable_device(assigned_dev->dev); |
diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c index 714b94932312..e723bb91aa34 100644 --- a/virt/kvm/iommu.c +++ b/virt/kvm/iommu.c | |||
| @@ -203,7 +203,7 @@ int kvm_assign_device(struct kvm *kvm, | |||
| 203 | goto out_unmap; | 203 | goto out_unmap; |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | pdev->dev_flags |= PCI_DEV_FLAGS_ASSIGNED; | 206 | pci_set_dev_assigned(pdev); |
| 207 | 207 | ||
| 208 | dev_info(&pdev->dev, "kvm assign device\n"); | 208 | dev_info(&pdev->dev, "kvm assign device\n"); |
| 209 | 209 | ||
| @@ -229,7 +229,7 @@ int kvm_deassign_device(struct kvm *kvm, | |||
| 229 | 229 | ||
| 230 | iommu_detach_device(domain, &pdev->dev); | 230 | iommu_detach_device(domain, &pdev->dev); |
| 231 | 231 | ||
| 232 | pdev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED; | 232 | pci_clear_dev_assigned(pdev); |
| 233 | 233 | ||
| 234 | dev_info(&pdev->dev, "kvm deassign device\n"); | 234 | dev_info(&pdev->dev, "kvm deassign device\n"); |
| 235 | 235 | ||
