diff options
84 files changed, 2689 insertions, 702 deletions
diff --git a/Documentation/devicetree/bindings/pci/aardvark-pci.txt b/Documentation/devicetree/bindings/pci/aardvark-pci.txt new file mode 100644 index 000000000000..bbcd9f4c501f --- /dev/null +++ b/Documentation/devicetree/bindings/pci/aardvark-pci.txt | |||
@@ -0,0 +1,56 @@ | |||
1 | Aardvark PCIe controller | ||
2 | |||
3 | This PCIe controller is used on the Marvell Armada 3700 ARM64 SoC. | ||
4 | |||
5 | The Device Tree node describing an Aardvark PCIe controller must | ||
6 | contain the following properties: | ||
7 | |||
8 | - compatible: Should be "marvell,armada-3700-pcie" | ||
9 | - reg: range of registers for the PCIe controller | ||
10 | - interrupts: the interrupt line of the PCIe controller | ||
11 | - #address-cells: set to <3> | ||
12 | - #size-cells: set to <2> | ||
13 | - device_type: set to "pci" | ||
14 | - ranges: ranges for the PCI memory and I/O regions | ||
15 | - #interrupt-cells: set to <1> | ||
16 | - msi-controller: indicates that the PCIe controller can itself | ||
17 | handle MSI interrupts | ||
18 | - msi-parent: pointer to the MSI controller to be used | ||
19 | - interrupt-map-mask and interrupt-map: standard PCI properties to | ||
20 | define the mapping of the PCIe interface to interrupt numbers. | ||
21 | - bus-range: PCI bus numbers covered | ||
22 | |||
23 | In addition, the Device Tree describing an Aardvark PCIe controller | ||
24 | must include a sub-node that describes the legacy interrupt controller | ||
25 | built into the PCIe controller. This sub-node must have the following | ||
26 | properties: | ||
27 | |||
28 | - interrupt-controller | ||
29 | - #interrupt-cells: set to <1> | ||
30 | |||
31 | Example: | ||
32 | |||
33 | pcie0: pcie@d0070000 { | ||
34 | compatible = "marvell,armada-3700-pcie"; | ||
35 | device_type = "pci"; | ||
36 | status = "disabled"; | ||
37 | reg = <0 0xd0070000 0 0x20000>; | ||
38 | #address-cells = <3>; | ||
39 | #size-cells = <2>; | ||
40 | bus-range = <0x00 0xff>; | ||
41 | interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; | ||
42 | #interrupt-cells = <1>; | ||
43 | msi-controller; | ||
44 | msi-parent = <&pcie0>; | ||
45 | ranges = <0x82000000 0 0xe8000000 0 0xe8000000 0 0x1000000 /* Port 0 MEM */ | ||
46 | 0x81000000 0 0xe9000000 0 0xe9000000 0 0x10000>; /* Port 0 IO*/ | ||
47 | interrupt-map-mask = <0 0 0 7>; | ||
48 | interrupt-map = <0 0 0 1 &pcie_intc 0>, | ||
49 | <0 0 0 2 &pcie_intc 1>, | ||
50 | <0 0 0 3 &pcie_intc 2>, | ||
51 | <0 0 0 4 &pcie_intc 3>; | ||
52 | pcie_intc: interrupt-controller { | ||
53 | interrupt-controller; | ||
54 | #interrupt-cells = <1>; | ||
55 | }; | ||
56 | }; | ||
diff --git a/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt new file mode 100644 index 000000000000..330a45b5f0b5 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt | |||
@@ -0,0 +1,46 @@ | |||
1 | * Axis ARTPEC-6 PCIe interface | ||
2 | |||
3 | This PCIe host controller is based on the Synopsys DesignWare PCIe IP | ||
4 | and thus inherits all the common properties defined in designware-pcie.txt. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: "axis,artpec6-pcie", "snps,dw-pcie" | ||
8 | - reg: base addresses and lengths of the PCIe controller (DBI), | ||
9 | the phy controller, and configuration address space. | ||
10 | - reg-names: Must include the following entries: | ||
11 | - "dbi" | ||
12 | - "phy" | ||
13 | - "config" | ||
14 | - interrupts: A list of interrupt outputs of the controller. Must contain an | ||
15 | entry for each entry in the interrupt-names property. | ||
16 | - interrupt-names: Must include the following entries: | ||
17 | - "msi": The interrupt that is asserted when an MSI is received | ||
18 | - axis,syscon-pcie: A phandle pointing to the ARTPEC-6 system controller, | ||
19 | used to enable and control the Synopsys IP. | ||
20 | |||
21 | Example: | ||
22 | |||
23 | pcie@f8050000 { | ||
24 | compatible = "axis,artpec6-pcie", "snps,dw-pcie"; | ||
25 | reg = <0xf8050000 0x2000 | ||
26 | 0xf8040000 0x1000 | ||
27 | 0xc0000000 0x1000>; | ||
28 | reg-names = "dbi", "phy", "config"; | ||
29 | #address-cells = <3>; | ||
30 | #size-cells = <2>; | ||
31 | device_type = "pci"; | ||
32 | /* downstream I/O */ | ||
33 | ranges = <0x81000000 0 0x00010000 0xc0010000 0 0x00010000 | ||
34 | /* non-prefetchable memory */ | ||
35 | 0x82000000 0 0xc0020000 0xc0020000 0 0x1ffe0000>; | ||
36 | num-lanes = <2>; | ||
37 | interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>; | ||
38 | interrupt-names = "msi"; | ||
39 | #interrupt-cells = <1>; | ||
40 | interrupt-map-mask = <0 0 0 0x7>; | ||
41 | interrupt-map = <0 0 0 1 &intc GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>, | ||
42 | <0 0 0 2 &intc GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>, | ||
43 | <0 0 0 3 &intc GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>, | ||
44 | <0 0 0 4 &intc GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>; | ||
45 | axis,syscon-pcie = <&syscon>; | ||
46 | }; | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 82b42c958d1c..2102248005b5 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -2998,6 +2998,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
2998 | resource_alignment= | 2998 | resource_alignment= |
2999 | Format: | 2999 | Format: |
3000 | [<order of align>@][<domain>:]<bus>:<slot>.<func>[; ...] | 3000 | [<order of align>@][<domain>:]<bus>:<slot>.<func>[; ...] |
3001 | [<order of align>@]pci:<vendor>:<device>\ | ||
3002 | [:<subvendor>:<subdevice>][; ...] | ||
3001 | Specifies alignment and device to reassign | 3003 | Specifies alignment and device to reassign |
3002 | aligned memory resources. | 3004 | aligned memory resources. |
3003 | If <order of align> is not specified, | 3005 | If <order of align> is not specified, |
@@ -3016,6 +3018,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
3016 | hpmemsize=nn[KMG] The fixed amount of bus space which is | 3018 | hpmemsize=nn[KMG] The fixed amount of bus space which is |
3017 | reserved for hotplug bridge's memory window. | 3019 | reserved for hotplug bridge's memory window. |
3018 | Default size is 2 megabytes. | 3020 | Default size is 2 megabytes. |
3021 | hpbussize=nn The minimum amount of additional bus numbers | ||
3022 | reserved for buses below a hotplug bridge. | ||
3023 | Default is 1. | ||
3019 | realloc= Enable/disable reallocating PCI bridge resources | 3024 | realloc= Enable/disable reallocating PCI bridge resources |
3020 | if allocations done by BIOS are too small to | 3025 | if allocations done by BIOS are too small to |
3021 | accommodate resources required by all child | 3026 | accommodate resources required by all child |
@@ -3047,6 +3052,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
3047 | compat Treat PCIe ports as PCI-to-PCI bridges, disable the PCIe | 3052 | compat Treat PCIe ports as PCI-to-PCI bridges, disable the PCIe |
3048 | ports driver. | 3053 | ports driver. |
3049 | 3054 | ||
3055 | pcie_port_pm= [PCIE] PCIe port power management handling: | ||
3056 | off Disable power management of all PCIe ports | ||
3057 | force Forcibly enable power management of all PCIe ports | ||
3058 | |||
3050 | pcie_pme= [PCIE,PM] Native PCIe PME signaling options: | 3059 | pcie_pme= [PCIE,PM] Native PCIe PME signaling options: |
3051 | nomsi Do not use MSI for native PCIe PME signaling (this makes | 3060 | nomsi Do not use MSI for native PCIe PME signaling (this makes |
3052 | all PCIe root ports use INTx for all services). | 3061 | all PCIe root ports use INTx for all services). |
diff --git a/MAINTAINERS b/MAINTAINERS index ed42cb65a19b..b5aa111b0331 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -8678,6 +8678,7 @@ L: linux-pci@vger.kernel.org | |||
8678 | Q: http://patchwork.ozlabs.org/project/linux-pci/list/ | 8678 | Q: http://patchwork.ozlabs.org/project/linux-pci/list/ |
8679 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git | 8679 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git |
8680 | S: Supported | 8680 | S: Supported |
8681 | F: Documentation/devicetree/bindings/pci/ | ||
8681 | F: Documentation/PCI/ | 8682 | F: Documentation/PCI/ |
8682 | F: drivers/pci/ | 8683 | F: drivers/pci/ |
8683 | F: include/linux/pci* | 8684 | F: include/linux/pci* |
@@ -8741,6 +8742,13 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |||
8741 | S: Maintained | 8742 | S: Maintained |
8742 | F: drivers/pci/host/*mvebu* | 8743 | F: drivers/pci/host/*mvebu* |
8743 | 8744 | ||
8745 | PCI DRIVER FOR AARDVARK (Marvell Armada 3700) | ||
8746 | M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
8747 | L: linux-pci@vger.kernel.org | ||
8748 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
8749 | S: Maintained | ||
8750 | F: drivers/pci/host/pci-aardvark.c | ||
8751 | |||
8744 | PCI DRIVER FOR NVIDIA TEGRA | 8752 | PCI DRIVER FOR NVIDIA TEGRA |
8745 | M: Thierry Reding <thierry.reding@gmail.com> | 8753 | M: Thierry Reding <thierry.reding@gmail.com> |
8746 | L: linux-tegra@vger.kernel.org | 8754 | L: linux-tegra@vger.kernel.org |
@@ -8823,6 +8831,15 @@ S: Maintained | |||
8823 | F: Documentation/devicetree/bindings/pci/xgene-pci-msi.txt | 8831 | F: Documentation/devicetree/bindings/pci/xgene-pci-msi.txt |
8824 | F: drivers/pci/host/pci-xgene-msi.c | 8832 | F: drivers/pci/host/pci-xgene-msi.c |
8825 | 8833 | ||
8834 | PCIE DRIVER FOR AXIS ARTPEC | ||
8835 | M: Niklas Cassel <niklas.cassel@axis.com> | ||
8836 | M: Jesper Nilsson <jesper.nilsson@axis.com> | ||
8837 | L: linux-arm-kernel@axis.com | ||
8838 | L: linux-pci@vger.kernel.org | ||
8839 | S: Maintained | ||
8840 | F: Documentation/devicetree/bindings/pci/axis,artpec* | ||
8841 | F: drivers/pci/host/*artpec* | ||
8842 | |||
8826 | PCIE DRIVER FOR HISILICON | 8843 | PCIE DRIVER FOR HISILICON |
8827 | M: Zhou Wang <wangzhou1@hisilicon.com> | 8844 | M: Zhou Wang <wangzhou1@hisilicon.com> |
8828 | M: Gabriele Paoloni <gabriele.paoloni@huawei.com> | 8845 | M: Gabriele Paoloni <gabriele.paoloni@huawei.com> |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 90542db1220d..354c167a2b42 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -715,7 +715,7 @@ config ARCH_VIRT | |||
715 | depends on ARCH_MULTI_V7 | 715 | depends on ARCH_MULTI_V7 |
716 | select ARM_AMBA | 716 | select ARM_AMBA |
717 | select ARM_GIC | 717 | select ARM_GIC |
718 | select ARM_GIC_V2M if PCI_MSI | 718 | select ARM_GIC_V2M if PCI |
719 | select ARM_GIC_V3 | 719 | select ARM_GIC_V3 |
720 | select ARM_PSCI | 720 | select ARM_PSCI |
721 | select HAVE_ARM_ARCH_TIMER | 721 | select HAVE_ARM_ARCH_TIMER |
diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h index 0070e8520cd4..2d88af5be45f 100644 --- a/arch/arm/include/asm/mach/pci.h +++ b/arch/arm/include/asm/mach/pci.h | |||
@@ -22,6 +22,7 @@ struct hw_pci { | |||
22 | struct msi_controller *msi_ctrl; | 22 | struct msi_controller *msi_ctrl; |
23 | struct pci_ops *ops; | 23 | struct pci_ops *ops; |
24 | int nr_controllers; | 24 | int nr_controllers; |
25 | unsigned int io_optional:1; | ||
25 | void **private_data; | 26 | void **private_data; |
26 | int (*setup)(int nr, struct pci_sys_data *); | 27 | int (*setup)(int nr, struct pci_sys_data *); |
27 | struct pci_bus *(*scan)(int nr, struct pci_sys_data *); | 28 | struct pci_bus *(*scan)(int nr, struct pci_sys_data *); |
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 05e61a2eeabe..2f0e07735d1d 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c | |||
@@ -410,7 +410,8 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | |||
410 | return irq; | 410 | return irq; |
411 | } | 411 | } |
412 | 412 | ||
413 | static int pcibios_init_resources(int busnr, struct pci_sys_data *sys) | 413 | static int pcibios_init_resource(int busnr, struct pci_sys_data *sys, |
414 | int io_optional) | ||
414 | { | 415 | { |
415 | int ret; | 416 | int ret; |
416 | struct resource_entry *window; | 417 | struct resource_entry *window; |
@@ -420,6 +421,14 @@ static int pcibios_init_resources(int busnr, struct pci_sys_data *sys) | |||
420 | &iomem_resource, sys->mem_offset); | 421 | &iomem_resource, sys->mem_offset); |
421 | } | 422 | } |
422 | 423 | ||
424 | /* | ||
425 | * If a platform says I/O port support is optional, we don't add | ||
426 | * the default I/O space. The platform is responsible for adding | ||
427 | * any I/O space it needs. | ||
428 | */ | ||
429 | if (io_optional) | ||
430 | return 0; | ||
431 | |||
423 | resource_list_for_each_entry(window, &sys->resources) | 432 | resource_list_for_each_entry(window, &sys->resources) |
424 | if (resource_type(window->res) == IORESOURCE_IO) | 433 | if (resource_type(window->res) == IORESOURCE_IO) |
425 | return 0; | 434 | return 0; |
@@ -466,7 +475,7 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, | |||
466 | if (ret > 0) { | 475 | if (ret > 0) { |
467 | struct pci_host_bridge *host_bridge; | 476 | struct pci_host_bridge *host_bridge; |
468 | 477 | ||
469 | ret = pcibios_init_resources(nr, sys); | 478 | ret = pcibios_init_resource(nr, sys, hw->io_optional); |
470 | if (ret) { | 479 | if (ret) { |
471 | kfree(sys); | 480 | kfree(sys); |
472 | break; | 481 | break; |
@@ -515,25 +524,23 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw) | |||
515 | list_for_each_entry(sys, &head, node) { | 524 | list_for_each_entry(sys, &head, node) { |
516 | struct pci_bus *bus = sys->bus; | 525 | struct pci_bus *bus = sys->bus; |
517 | 526 | ||
518 | if (!pci_has_flag(PCI_PROBE_ONLY)) { | 527 | /* |
528 | * We insert PCI resources into the iomem_resource and | ||
529 | * ioport_resource trees in either pci_bus_claim_resources() | ||
530 | * or pci_bus_assign_resources(). | ||
531 | */ | ||
532 | if (pci_has_flag(PCI_PROBE_ONLY)) { | ||
533 | pci_bus_claim_resources(bus); | ||
534 | } else { | ||
519 | struct pci_bus *child; | 535 | struct pci_bus *child; |
520 | 536 | ||
521 | /* | ||
522 | * Size the bridge windows. | ||
523 | */ | ||
524 | pci_bus_size_bridges(bus); | 537 | pci_bus_size_bridges(bus); |
525 | |||
526 | /* | ||
527 | * Assign resources. | ||
528 | */ | ||
529 | pci_bus_assign_resources(bus); | 538 | pci_bus_assign_resources(bus); |
530 | 539 | ||
531 | list_for_each_entry(child, &bus->children, node) | 540 | list_for_each_entry(child, &bus->children, node) |
532 | pcie_bus_configure_settings(child); | 541 | pcie_bus_configure_settings(child); |
533 | } | 542 | } |
534 | /* | 543 | |
535 | * Tell drivers about devices found. | ||
536 | */ | ||
537 | pci_bus_add_devices(bus); | 544 | pci_bus_add_devices(bus); |
538 | } | 545 | } |
539 | } | 546 | } |
@@ -590,18 +597,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, | |||
590 | return start; | 597 | return start; |
591 | } | 598 | } |
592 | 599 | ||
593 | /** | ||
594 | * pcibios_enable_device - Enable I/O and memory. | ||
595 | * @dev: PCI device to be enabled | ||
596 | */ | ||
597 | int pcibios_enable_device(struct pci_dev *dev, int mask) | ||
598 | { | ||
599 | if (pci_has_flag(PCI_PROBE_ONLY)) | ||
600 | return 0; | ||
601 | |||
602 | return pci_enable_resources(dev, mask); | ||
603 | } | ||
604 | |||
605 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | 600 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, |
606 | enum pci_mmap_state mmap_state, int write_combine) | 601 | enum pci_mmap_state mmap_state, int write_combine) |
607 | { | 602 | { |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 5a0a691d4220..21d955de4181 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
@@ -3,6 +3,7 @@ config ARM64 | |||
3 | select ACPI_CCA_REQUIRED if ACPI | 3 | select ACPI_CCA_REQUIRED if ACPI |
4 | select ACPI_GENERIC_GSI if ACPI | 4 | select ACPI_GENERIC_GSI if ACPI |
5 | select ACPI_REDUCED_HARDWARE_ONLY if ACPI | 5 | select ACPI_REDUCED_HARDWARE_ONLY if ACPI |
6 | select ACPI_MCFG if ACPI | ||
6 | select ARCH_HAS_DEVMEM_IS_ALLOWED | 7 | select ARCH_HAS_DEVMEM_IS_ALLOWED |
7 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | 8 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE |
8 | select ARCH_HAS_ELF_RANDOMIZE | 9 | select ARCH_HAS_ELF_RANDOMIZE |
@@ -20,9 +21,9 @@ config ARM64 | |||
20 | select ARM_ARCH_TIMER | 21 | select ARM_ARCH_TIMER |
21 | select ARM_GIC | 22 | select ARM_GIC |
22 | select AUDIT_ARCH_COMPAT_GENERIC | 23 | select AUDIT_ARCH_COMPAT_GENERIC |
23 | select ARM_GIC_V2M if PCI_MSI | 24 | select ARM_GIC_V2M if PCI |
24 | select ARM_GIC_V3 | 25 | select ARM_GIC_V3 |
25 | select ARM_GIC_V3_ITS if PCI_MSI | 26 | select ARM_GIC_V3_ITS if PCI |
26 | select ARM_PSCI_FW | 27 | select ARM_PSCI_FW |
27 | select BUILDTIME_EXTABLE_SORT | 28 | select BUILDTIME_EXTABLE_SORT |
28 | select CLONE_BACKWARDS | 29 | select CLONE_BACKWARDS |
@@ -96,6 +97,7 @@ config ARM64 | |||
96 | select OF_EARLY_FLATTREE | 97 | select OF_EARLY_FLATTREE |
97 | select OF_NUMA if NUMA && OF | 98 | select OF_NUMA if NUMA && OF |
98 | select OF_RESERVED_MEM | 99 | select OF_RESERVED_MEM |
100 | select PCI_ECAM if ACPI | ||
99 | select PERF_USE_VMALLOC | 101 | select PERF_USE_VMALLOC |
100 | select POWER_RESET | 102 | select POWER_RESET |
101 | select POWER_SUPPLY | 103 | select POWER_SUPPLY |
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-db.dts b/arch/arm64/boot/dts/marvell/armada-3720-db.dts index 86110a6ae330..1372e9a6aaa4 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-db.dts +++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts | |||
@@ -76,3 +76,8 @@ | |||
76 | &usb3 { | 76 | &usb3 { |
77 | status = "okay"; | 77 | status = "okay"; |
78 | }; | 78 | }; |
79 | |||
80 | /* CON17 (PCIe) / CON12 (mini-PCIe) */ | ||
81 | &pcie0 { | ||
82 | status = "okay"; | ||
83 | }; | ||
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi index 9e2efb882983..8a9cae9677bf 100644 --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi | |||
@@ -141,5 +141,30 @@ | |||
141 | <0x1d40000 0x40000>; /* GICR */ | 141 | <0x1d40000 0x40000>; /* GICR */ |
142 | }; | 142 | }; |
143 | }; | 143 | }; |
144 | |||
145 | pcie0: pcie@d0070000 { | ||
146 | compatible = "marvell,armada-3700-pcie"; | ||
147 | device_type = "pci"; | ||
148 | status = "disabled"; | ||
149 | reg = <0 0xd0070000 0 0x20000>; | ||
150 | #address-cells = <3>; | ||
151 | #size-cells = <2>; | ||
152 | bus-range = <0x00 0xff>; | ||
153 | interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; | ||
154 | #interrupt-cells = <1>; | ||
155 | msi-parent = <&pcie0>; | ||
156 | msi-controller; | ||
157 | ranges = <0x82000000 0 0xe8000000 0 0xe8000000 0 0x1000000 /* Port 0 MEM */ | ||
158 | 0x81000000 0 0xe9000000 0 0xe9000000 0 0x10000>; /* Port 0 IO*/ | ||
159 | interrupt-map-mask = <0 0 0 7>; | ||
160 | interrupt-map = <0 0 0 1 &pcie_intc 0>, | ||
161 | <0 0 0 2 &pcie_intc 1>, | ||
162 | <0 0 0 3 &pcie_intc 2>, | ||
163 | <0 0 0 4 &pcie_intc 3>; | ||
164 | pcie_intc: interrupt-controller { | ||
165 | interrupt-controller; | ||
166 | #interrupt-cells = <1>; | ||
167 | }; | ||
168 | }; | ||
144 | }; | 169 | }; |
145 | }; | 170 | }; |
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c index 3c4e308b40a0..acf38722457b 100644 --- a/arch/arm64/kernel/pci.c +++ b/arch/arm64/kernel/pci.c | |||
@@ -17,6 +17,9 @@ | |||
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/of_pci.h> | 18 | #include <linux/of_pci.h> |
19 | #include <linux/of_platform.h> | 19 | #include <linux/of_platform.h> |
20 | #include <linux/pci.h> | ||
21 | #include <linux/pci-acpi.h> | ||
22 | #include <linux/pci-ecam.h> | ||
20 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
21 | 24 | ||
22 | /* | 25 | /* |
@@ -36,25 +39,17 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, | |||
36 | return res->start; | 39 | return res->start; |
37 | } | 40 | } |
38 | 41 | ||
39 | /** | ||
40 | * pcibios_enable_device - Enable I/O and memory. | ||
41 | * @dev: PCI device to be enabled | ||
42 | * @mask: bitmask of BARs to enable | ||
43 | */ | ||
44 | int pcibios_enable_device(struct pci_dev *dev, int mask) | ||
45 | { | ||
46 | if (pci_has_flag(PCI_PROBE_ONLY)) | ||
47 | return 0; | ||
48 | |||
49 | return pci_enable_resources(dev, mask); | ||
50 | } | ||
51 | |||
52 | /* | 42 | /* |
53 | * Try to assign the IRQ number from DT when adding a new device | 43 | * Try to assign the IRQ number when probing a new device |
54 | */ | 44 | */ |
55 | int pcibios_add_device(struct pci_dev *dev) | 45 | int pcibios_alloc_irq(struct pci_dev *dev) |
56 | { | 46 | { |
57 | dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); | 47 | if (acpi_disabled) |
48 | dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); | ||
49 | #ifdef CONFIG_ACPI | ||
50 | else | ||
51 | return acpi_pci_irq_enable(dev); | ||
52 | #endif | ||
58 | 53 | ||
59 | return 0; | 54 | return 0; |
60 | } | 55 | } |
@@ -65,13 +60,21 @@ int pcibios_add_device(struct pci_dev *dev) | |||
65 | int raw_pci_read(unsigned int domain, unsigned int bus, | 60 | int raw_pci_read(unsigned int domain, unsigned int bus, |
66 | unsigned int devfn, int reg, int len, u32 *val) | 61 | unsigned int devfn, int reg, int len, u32 *val) |
67 | { | 62 | { |
68 | return -ENXIO; | 63 | struct pci_bus *b = pci_find_bus(domain, bus); |
64 | |||
65 | if (!b) | ||
66 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
67 | return b->ops->read(b, devfn, reg, len, val); | ||
69 | } | 68 | } |
70 | 69 | ||
71 | int raw_pci_write(unsigned int domain, unsigned int bus, | 70 | int raw_pci_write(unsigned int domain, unsigned int bus, |
72 | unsigned int devfn, int reg, int len, u32 val) | 71 | unsigned int devfn, int reg, int len, u32 val) |
73 | { | 72 | { |
74 | return -ENXIO; | 73 | struct pci_bus *b = pci_find_bus(domain, bus); |
74 | |||
75 | if (!b) | ||
76 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
77 | return b->ops->write(b, devfn, reg, len, val); | ||
75 | } | 78 | } |
76 | 79 | ||
77 | #ifdef CONFIG_NUMA | 80 | #ifdef CONFIG_NUMA |
@@ -85,10 +88,124 @@ EXPORT_SYMBOL(pcibus_to_node); | |||
85 | #endif | 88 | #endif |
86 | 89 | ||
87 | #ifdef CONFIG_ACPI | 90 | #ifdef CONFIG_ACPI |
88 | /* Root bridge scanning */ | 91 | |
92 | struct acpi_pci_generic_root_info { | ||
93 | struct acpi_pci_root_info common; | ||
94 | struct pci_config_window *cfg; /* config space mapping */ | ||
95 | }; | ||
96 | |||
97 | int acpi_pci_bus_find_domain_nr(struct pci_bus *bus) | ||
98 | { | ||
99 | struct pci_config_window *cfg = bus->sysdata; | ||
100 | struct acpi_device *adev = to_acpi_device(cfg->parent); | ||
101 | struct acpi_pci_root *root = acpi_driver_data(adev); | ||
102 | |||
103 | return root->segment; | ||
104 | } | ||
105 | |||
106 | int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) | ||
107 | { | ||
108 | if (!acpi_disabled) { | ||
109 | struct pci_config_window *cfg = bridge->bus->sysdata; | ||
110 | struct acpi_device *adev = to_acpi_device(cfg->parent); | ||
111 | ACPI_COMPANION_SET(&bridge->dev, adev); | ||
112 | } | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | /* | ||
118 | * Lookup the bus range for the domain in MCFG, and set up config space | ||
119 | * mapping. | ||
120 | */ | ||
121 | static struct pci_config_window * | ||
122 | pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) | ||
123 | { | ||
124 | struct resource *bus_res = &root->secondary; | ||
125 | u16 seg = root->segment; | ||
126 | struct pci_config_window *cfg; | ||
127 | struct resource cfgres; | ||
128 | unsigned int bsz; | ||
129 | |||
130 | /* Use address from _CBA if present, otherwise lookup MCFG */ | ||
131 | if (!root->mcfg_addr) | ||
132 | root->mcfg_addr = pci_mcfg_lookup(seg, bus_res); | ||
133 | |||
134 | if (!root->mcfg_addr) { | ||
135 | dev_err(&root->device->dev, "%04x:%pR ECAM region not found\n", | ||
136 | seg, bus_res); | ||
137 | return NULL; | ||
138 | } | ||
139 | |||
140 | bsz = 1 << pci_generic_ecam_ops.bus_shift; | ||
141 | cfgres.start = root->mcfg_addr + bus_res->start * bsz; | ||
142 | cfgres.end = cfgres.start + resource_size(bus_res) * bsz - 1; | ||
143 | cfgres.flags = IORESOURCE_MEM; | ||
144 | cfg = pci_ecam_create(&root->device->dev, &cfgres, bus_res, | ||
145 | &pci_generic_ecam_ops); | ||
146 | if (IS_ERR(cfg)) { | ||
147 | dev_err(&root->device->dev, "%04x:%pR error %ld mapping ECAM\n", | ||
148 | seg, bus_res, PTR_ERR(cfg)); | ||
149 | return NULL; | ||
150 | } | ||
151 | |||
152 | return cfg; | ||
153 | } | ||
154 | |||
155 | /* release_info: free resources allocated by init_info */ | ||
156 | static void pci_acpi_generic_release_info(struct acpi_pci_root_info *ci) | ||
157 | { | ||
158 | struct acpi_pci_generic_root_info *ri; | ||
159 | |||
160 | ri = container_of(ci, struct acpi_pci_generic_root_info, common); | ||
161 | pci_ecam_free(ri->cfg); | ||
162 | kfree(ri); | ||
163 | } | ||
164 | |||
165 | static struct acpi_pci_root_ops acpi_pci_root_ops = { | ||
166 | .release_info = pci_acpi_generic_release_info, | ||
167 | }; | ||
168 | |||
169 | /* Interface called from ACPI code to setup PCI host controller */ | ||
89 | struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) | 170 | struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) |
90 | { | 171 | { |
91 | /* TODO: Should be revisited when implementing PCI on ACPI */ | 172 | int node = acpi_get_node(root->device->handle); |
92 | return NULL; | 173 | struct acpi_pci_generic_root_info *ri; |
174 | struct pci_bus *bus, *child; | ||
175 | |||
176 | ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node); | ||
177 | if (!ri) | ||
178 | return NULL; | ||
179 | |||
180 | ri->cfg = pci_acpi_setup_ecam_mapping(root); | ||
181 | if (!ri->cfg) { | ||
182 | kfree(ri); | ||
183 | return NULL; | ||
184 | } | ||
185 | |||
186 | acpi_pci_root_ops.pci_ops = &ri->cfg->ops->pci_ops; | ||
187 | bus = acpi_pci_root_create(root, &acpi_pci_root_ops, &ri->common, | ||
188 | ri->cfg); | ||
189 | if (!bus) | ||
190 | return NULL; | ||
191 | |||
192 | pci_bus_size_bridges(bus); | ||
193 | pci_bus_assign_resources(bus); | ||
194 | |||
195 | list_for_each_entry(child, &bus->children, node) | ||
196 | pcie_bus_configure_settings(child); | ||
197 | |||
198 | return bus; | ||
93 | } | 199 | } |
200 | |||
201 | void pcibios_add_bus(struct pci_bus *bus) | ||
202 | { | ||
203 | acpi_pci_add_bus(bus); | ||
204 | } | ||
205 | |||
206 | void pcibios_remove_bus(struct pci_bus *bus) | ||
207 | { | ||
208 | acpi_pci_remove_bus(bus); | ||
209 | } | ||
210 | |||
94 | #endif | 211 | #endif |
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index fc3ecb55f1b2..2a120bb70e54 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h | |||
@@ -82,9 +82,6 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file, | |||
82 | pgprot_t prot); | 82 | pgprot_t prot); |
83 | 83 | ||
84 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER | 84 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER |
85 | extern void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
86 | const struct resource *rsrc, | ||
87 | resource_size_t *start, resource_size_t *end); | ||
88 | 85 | ||
89 | extern void pcibios_setup_bus_devices(struct pci_bus *bus); | 86 | extern void pcibios_setup_bus_devices(struct pci_bus *bus); |
90 | extern void pcibios_setup_bus_self(struct pci_bus *bus); | 87 | extern void pcibios_setup_bus_self(struct pci_bus *bus); |
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 14cba600da7a..81556b843a8e 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c | |||
@@ -219,33 +219,6 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | |||
219 | } | 219 | } |
220 | 220 | ||
221 | /* | 221 | /* |
222 | * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci | ||
223 | * device mapping. | ||
224 | */ | ||
225 | static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | ||
226 | pgprot_t protection, | ||
227 | enum pci_mmap_state mmap_state, | ||
228 | int write_combine) | ||
229 | { | ||
230 | pgprot_t prot = protection; | ||
231 | |||
232 | /* Write combine is always 0 on non-memory space mappings. On | ||
233 | * memory space, if the user didn't pass 1, we check for a | ||
234 | * "prefetchable" resource. This is a bit hackish, but we use | ||
235 | * this to workaround the inability of /sysfs to provide a write | ||
236 | * combine bit | ||
237 | */ | ||
238 | if (mmap_state != pci_mmap_mem) | ||
239 | write_combine = 0; | ||
240 | else if (write_combine == 0) { | ||
241 | if (rp->flags & IORESOURCE_PREFETCH) | ||
242 | write_combine = 1; | ||
243 | } | ||
244 | |||
245 | return pgprot_noncached(prot); | ||
246 | } | ||
247 | |||
248 | /* | ||
249 | * This one is used by /dev/mem and fbdev who have no clue about the | 222 | * This one is used by /dev/mem and fbdev who have no clue about the |
250 | * PCI device, it tries to find the PCI device first and calls the | 223 | * PCI device, it tries to find the PCI device first and calls the |
251 | * above routine | 224 | * above routine |
@@ -317,9 +290,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
317 | return -EINVAL; | 290 | return -EINVAL; |
318 | 291 | ||
319 | vma->vm_pgoff = offset >> PAGE_SHIFT; | 292 | vma->vm_pgoff = offset >> PAGE_SHIFT; |
320 | vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp, | 293 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
321 | vma->vm_page_prot, | ||
322 | mmap_state, write_combine); | ||
323 | 294 | ||
324 | ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, | 295 | ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, |
325 | vma->vm_end - vma->vm_start, vma->vm_page_prot); | 296 | vma->vm_end - vma->vm_start, vma->vm_page_prot); |
@@ -473,39 +444,25 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
473 | const struct resource *rsrc, | 444 | const struct resource *rsrc, |
474 | resource_size_t *start, resource_size_t *end) | 445 | resource_size_t *start, resource_size_t *end) |
475 | { | 446 | { |
476 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | 447 | struct pci_bus_region region; |
477 | resource_size_t offset = 0; | ||
478 | 448 | ||
479 | if (hose == NULL) | 449 | if (rsrc->flags & IORESOURCE_IO) { |
450 | pcibios_resource_to_bus(dev->bus, ®ion, | ||
451 | (struct resource *) rsrc); | ||
452 | *start = region.start; | ||
453 | *end = region.end; | ||
480 | return; | 454 | return; |
455 | } | ||
481 | 456 | ||
482 | if (rsrc->flags & IORESOURCE_IO) | 457 | /* We pass a CPU physical address to userland for MMIO instead of a |
483 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | 458 | * BAR value because X is lame and expects to be able to use that |
484 | 459 | * to pass to /dev/mem! | |
485 | /* We pass a fully fixed up address to userland for MMIO instead of | ||
486 | * a BAR value because X is lame and expects to be able to use that | ||
487 | * to pass to /dev/mem ! | ||
488 | * | 460 | * |
489 | * That means that we'll have potentially 64 bits values where some | 461 | * That means we may have 64-bit values where some apps only expect |
490 | * userland apps only expect 32 (like X itself since it thinks only | 462 | * 32 (like X itself since it thinks only Sparc has 64-bit MMIO). |
491 | * Sparc has 64 bits MMIO) but if we don't do that, we break it on | ||
492 | * 32 bits CHRPs :-( | ||
493 | * | ||
494 | * Hopefully, the sysfs insterface is immune to that gunk. Once X | ||
495 | * has been fixed (and the fix spread enough), we can re-enable the | ||
496 | * 2 lines below and pass down a BAR value to userland. In that case | ||
497 | * we'll also have to re-enable the matching code in | ||
498 | * __pci_mmap_make_offset(). | ||
499 | * | ||
500 | * BenH. | ||
501 | */ | 463 | */ |
502 | #if 0 | 464 | *start = rsrc->start; |
503 | else if (rsrc->flags & IORESOURCE_MEM) | 465 | *end = rsrc->end; |
504 | offset = hose->pci_mem_offset; | ||
505 | #endif | ||
506 | |||
507 | *start = rsrc->start - offset; | ||
508 | *end = rsrc->end - offset; | ||
509 | } | 466 | } |
510 | 467 | ||
511 | /** | 468 | /** |
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 86b239d9d75d..9b63cd41213d 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h | |||
@@ -80,16 +80,6 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
80 | 80 | ||
81 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER | 81 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER |
82 | 82 | ||
83 | static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
84 | const struct resource *rsrc, resource_size_t *start, | ||
85 | resource_size_t *end) | ||
86 | { | ||
87 | phys_addr_t size = resource_size(rsrc); | ||
88 | |||
89 | *start = fixup_bigphys_addr(rsrc->start, size); | ||
90 | *end = rsrc->start + size; | ||
91 | } | ||
92 | |||
93 | /* | 83 | /* |
94 | * Dynamic DMA mapping stuff. | 84 | * Dynamic DMA mapping stuff. |
95 | * MIPS has everything mapped statically. | 85 | * MIPS has everything mapped statically. |
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index f1b11f0dea2d..b4c02f29663e 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c | |||
@@ -112,7 +112,14 @@ static void pcibios_scanbus(struct pci_controller *hose) | |||
112 | need_domain_info = 1; | 112 | need_domain_info = 1; |
113 | } | 113 | } |
114 | 114 | ||
115 | if (!pci_has_flag(PCI_PROBE_ONLY)) { | 115 | /* |
116 | * We insert PCI resources into the iomem_resource and | ||
117 | * ioport_resource trees in either pci_bus_claim_resources() | ||
118 | * or pci_bus_assign_resources(). | ||
119 | */ | ||
120 | if (pci_has_flag(PCI_PROBE_ONLY)) { | ||
121 | pci_bus_claim_resources(bus); | ||
122 | } else { | ||
116 | pci_bus_size_bridges(bus); | 123 | pci_bus_size_bridges(bus); |
117 | pci_bus_assign_resources(bus); | 124 | pci_bus_assign_resources(bus); |
118 | } | 125 | } |
@@ -319,6 +326,16 @@ void pcibios_fixup_bus(struct pci_bus *bus) | |||
319 | EXPORT_SYMBOL(PCIBIOS_MIN_IO); | 326 | EXPORT_SYMBOL(PCIBIOS_MIN_IO); |
320 | EXPORT_SYMBOL(PCIBIOS_MIN_MEM); | 327 | EXPORT_SYMBOL(PCIBIOS_MIN_MEM); |
321 | 328 | ||
329 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
330 | const struct resource *rsrc, resource_size_t *start, | ||
331 | resource_size_t *end) | ||
332 | { | ||
333 | phys_addr_t size = resource_size(rsrc); | ||
334 | |||
335 | *start = fixup_bigphys_addr(rsrc->start, size); | ||
336 | *end = rsrc->start + size; | ||
337 | } | ||
338 | |||
322 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | 339 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, |
323 | enum pci_mmap_state mmap_state, int write_combine) | 340 | enum pci_mmap_state mmap_state, int write_combine) |
324 | { | 341 | { |
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h index a6f3ac0d4602..e9bd6cf0212f 100644 --- a/arch/powerpc/include/asm/pci.h +++ b/arch/powerpc/include/asm/pci.h | |||
@@ -136,9 +136,6 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file, | |||
136 | pgprot_t prot); | 136 | pgprot_t prot); |
137 | 137 | ||
138 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER | 138 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER |
139 | extern void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
140 | const struct resource *rsrc, | ||
141 | resource_size_t *start, resource_size_t *end); | ||
142 | 139 | ||
143 | extern resource_size_t pcibios_io_space_offset(struct pci_controller *hose); | 140 | extern resource_size_t pcibios_io_space_offset(struct pci_controller *hose); |
144 | extern void pcibios_setup_bus_devices(struct pci_bus *bus); | 141 | extern void pcibios_setup_bus_devices(struct pci_bus *bus); |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 0f7a60f1e9f6..6de6e0e96ce5 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -356,36 +356,6 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | |||
356 | } | 356 | } |
357 | 357 | ||
358 | /* | 358 | /* |
359 | * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci | ||
360 | * device mapping. | ||
361 | */ | ||
362 | static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | ||
363 | pgprot_t protection, | ||
364 | enum pci_mmap_state mmap_state, | ||
365 | int write_combine) | ||
366 | { | ||
367 | |||
368 | /* Write combine is always 0 on non-memory space mappings. On | ||
369 | * memory space, if the user didn't pass 1, we check for a | ||
370 | * "prefetchable" resource. This is a bit hackish, but we use | ||
371 | * this to workaround the inability of /sysfs to provide a write | ||
372 | * combine bit | ||
373 | */ | ||
374 | if (mmap_state != pci_mmap_mem) | ||
375 | write_combine = 0; | ||
376 | else if (write_combine == 0) { | ||
377 | if (rp->flags & IORESOURCE_PREFETCH) | ||
378 | write_combine = 1; | ||
379 | } | ||
380 | |||
381 | /* XXX would be nice to have a way to ask for write-through */ | ||
382 | if (write_combine) | ||
383 | return pgprot_noncached_wc(protection); | ||
384 | else | ||
385 | return pgprot_noncached(protection); | ||
386 | } | ||
387 | |||
388 | /* | ||
389 | * This one is used by /dev/mem and fbdev who have no clue about the | 359 | * This one is used by /dev/mem and fbdev who have no clue about the |
390 | * PCI device, it tries to find the PCI device first and calls the | 360 | * PCI device, it tries to find the PCI device first and calls the |
391 | * above routine | 361 | * above routine |
@@ -458,9 +428,10 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
458 | return -EINVAL; | 428 | return -EINVAL; |
459 | 429 | ||
460 | vma->vm_pgoff = offset >> PAGE_SHIFT; | 430 | vma->vm_pgoff = offset >> PAGE_SHIFT; |
461 | vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp, | 431 | if (write_combine) |
462 | vma->vm_page_prot, | 432 | vma->vm_page_prot = pgprot_noncached_wc(vma->vm_page_prot); |
463 | mmap_state, write_combine); | 433 | else |
434 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
464 | 435 | ||
465 | ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, | 436 | ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, |
466 | vma->vm_end - vma->vm_start, vma->vm_page_prot); | 437 | vma->vm_end - vma->vm_start, vma->vm_page_prot); |
@@ -610,39 +581,25 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
610 | const struct resource *rsrc, | 581 | const struct resource *rsrc, |
611 | resource_size_t *start, resource_size_t *end) | 582 | resource_size_t *start, resource_size_t *end) |
612 | { | 583 | { |
613 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | 584 | struct pci_bus_region region; |
614 | resource_size_t offset = 0; | ||
615 | 585 | ||
616 | if (hose == NULL) | 586 | if (rsrc->flags & IORESOURCE_IO) { |
587 | pcibios_resource_to_bus(dev->bus, ®ion, | ||
588 | (struct resource *) rsrc); | ||
589 | *start = region.start; | ||
590 | *end = region.end; | ||
617 | return; | 591 | return; |
592 | } | ||
618 | 593 | ||
619 | if (rsrc->flags & IORESOURCE_IO) | 594 | /* We pass a CPU physical address to userland for MMIO instead of a |
620 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | 595 | * BAR value because X is lame and expects to be able to use that |
621 | 596 | * to pass to /dev/mem! | |
622 | /* We pass a fully fixed up address to userland for MMIO instead of | ||
623 | * a BAR value because X is lame and expects to be able to use that | ||
624 | * to pass to /dev/mem ! | ||
625 | * | ||
626 | * That means that we'll have potentially 64 bits values where some | ||
627 | * userland apps only expect 32 (like X itself since it thinks only | ||
628 | * Sparc has 64 bits MMIO) but if we don't do that, we break it on | ||
629 | * 32 bits CHRPs :-( | ||
630 | * | ||
631 | * Hopefully, the sysfs insterface is immune to that gunk. Once X | ||
632 | * has been fixed (and the fix spread enough), we can re-enable the | ||
633 | * 2 lines below and pass down a BAR value to userland. In that case | ||
634 | * we'll also have to re-enable the matching code in | ||
635 | * __pci_mmap_make_offset(). | ||
636 | * | 597 | * |
637 | * BenH. | 598 | * That means we may have 64-bit values where some apps only expect |
599 | * 32 (like X itself since it thinks only Sparc has 64-bit MMIO). | ||
638 | */ | 600 | */ |
639 | #if 0 | 601 | *start = rsrc->start; |
640 | else if (rsrc->flags & IORESOURCE_MEM) | 602 | *end = rsrc->end; |
641 | offset = hose->pci_mem_offset; | ||
642 | #endif | ||
643 | |||
644 | *start = rsrc->start - offset; | ||
645 | *end = rsrc->end - offset; | ||
646 | } | 603 | } |
647 | 604 | ||
648 | /** | 605 | /** |
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h index 022d16008a00..2303635158f5 100644 --- a/arch/sparc/include/asm/pci_64.h +++ b/arch/sparc/include/asm/pci_64.h | |||
@@ -55,9 +55,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) | |||
55 | } | 55 | } |
56 | 56 | ||
57 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER | 57 | #define HAVE_ARCH_PCI_RESOURCE_TO_USER |
58 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
59 | const struct resource *rsrc, | ||
60 | resource_size_t *start, resource_size_t *end); | ||
61 | #endif /* __KERNEL__ */ | 58 | #endif /* __KERNEL__ */ |
62 | 59 | ||
63 | #endif /* __SPARC64_PCI_H */ | 60 | #endif /* __SPARC64_PCI_H */ |
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index c2b202d763a1..9c1878f4fa9f 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c | |||
@@ -986,16 +986,18 @@ void pci_resource_to_user(const struct pci_dev *pdev, int bar, | |||
986 | const struct resource *rp, resource_size_t *start, | 986 | const struct resource *rp, resource_size_t *start, |
987 | resource_size_t *end) | 987 | resource_size_t *end) |
988 | { | 988 | { |
989 | struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; | 989 | struct pci_bus_region region; |
990 | unsigned long offset; | ||
991 | |||
992 | if (rp->flags & IORESOURCE_IO) | ||
993 | offset = pbm->io_space.start; | ||
994 | else | ||
995 | offset = pbm->mem_space.start; | ||
996 | 990 | ||
997 | *start = rp->start - offset; | 991 | /* |
998 | *end = rp->end - offset; | 992 | * "User" addresses are shown in /sys/devices/pci.../.../resource |
993 | * and /proc/bus/pci/devices and used as mmap offsets for | ||
994 | * /proc/bus/pci/BB/DD.F files (see proc_bus_pci_mmap()). | ||
995 | * | ||
996 | * On sparc, these are PCI bus addresses, i.e., raw BAR values. | ||
997 | */ | ||
998 | pcibios_resource_to_bus(pdev->bus, ®ion, (struct resource *) rp); | ||
999 | *start = region.start; | ||
1000 | *end = region.end; | ||
999 | } | 1001 | } |
1000 | 1002 | ||
1001 | void pcibios_set_master(struct pci_dev *dev) | 1003 | void pcibios_set_master(struct pci_dev *dev) |
diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c index d45fa5f3e9c4..62137d13c6f9 100644 --- a/arch/unicore32/kernel/pci.c +++ b/arch/unicore32/kernel/pci.c | |||
@@ -265,10 +265,8 @@ static int __init pci_common_init(void) | |||
265 | 265 | ||
266 | pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq); | 266 | pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq); |
267 | 267 | ||
268 | if (!pci_has_flag(PCI_PROBE_ONLY)) { | 268 | pci_bus_size_bridges(puv3_bus); |
269 | pci_bus_size_bridges(puv3_bus); | 269 | pci_bus_assign_resources(puv3_bus); |
270 | pci_bus_assign_resources(puv3_bus); | ||
271 | } | ||
272 | pci_bus_add_devices(puv3_bus); | 270 | pci_bus_add_devices(puv3_bus); |
273 | return 0; | 271 | return 0; |
274 | } | 272 | } |
@@ -279,9 +277,6 @@ char * __init pcibios_setup(char *str) | |||
279 | if (!strcmp(str, "debug")) { | 277 | if (!strcmp(str, "debug")) { |
280 | debug_pci = 1; | 278 | debug_pci = 1; |
281 | return NULL; | 279 | return NULL; |
282 | } else if (!strcmp(str, "firmware")) { | ||
283 | pci_add_flags(PCI_PROBE_ONLY); | ||
284 | return NULL; | ||
285 | } | 280 | } |
286 | return str; | 281 | return str; |
287 | } | 282 | } |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 8196054fedb0..7b6a9d14c8c0 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -133,7 +133,7 @@ static void pcibios_fixup_device_resources(struct pci_dev *dev) | |||
133 | if (pci_probe & PCI_NOASSIGN_BARS) { | 133 | if (pci_probe & PCI_NOASSIGN_BARS) { |
134 | /* | 134 | /* |
135 | * If the BIOS did not assign the BAR, zero out the | 135 | * If the BIOS did not assign the BAR, zero out the |
136 | * resource so the kernel doesn't attmept to assign | 136 | * resource so the kernel doesn't attempt to assign |
137 | * it later on in pci_assign_unassigned_resources | 137 | * it later on in pci_assign_unassigned_resources |
138 | */ | 138 | */ |
139 | for (bar = 0; bar <= PCI_STD_RESOURCE_END; bar++) { | 139 | for (bar = 0; bar <= PCI_STD_RESOURCE_END; bar++) { |
diff --git a/arch/x86/pci/vmd.c b/arch/x86/pci/vmd.c index 7792aba266df..fd582abfad91 100644 --- a/arch/x86/pci/vmd.c +++ b/arch/x86/pci/vmd.c | |||
@@ -119,10 +119,11 @@ static void vmd_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) | |||
119 | static void vmd_irq_enable(struct irq_data *data) | 119 | static void vmd_irq_enable(struct irq_data *data) |
120 | { | 120 | { |
121 | struct vmd_irq *vmdirq = data->chip_data; | 121 | struct vmd_irq *vmdirq = data->chip_data; |
122 | unsigned long flags; | ||
122 | 123 | ||
123 | raw_spin_lock(&list_lock); | 124 | raw_spin_lock_irqsave(&list_lock, flags); |
124 | list_add_tail_rcu(&vmdirq->node, &vmdirq->irq->irq_list); | 125 | list_add_tail_rcu(&vmdirq->node, &vmdirq->irq->irq_list); |
125 | raw_spin_unlock(&list_lock); | 126 | raw_spin_unlock_irqrestore(&list_lock, flags); |
126 | 127 | ||
127 | data->chip->irq_unmask(data); | 128 | data->chip->irq_unmask(data); |
128 | } | 129 | } |
@@ -130,12 +131,14 @@ static void vmd_irq_enable(struct irq_data *data) | |||
130 | static void vmd_irq_disable(struct irq_data *data) | 131 | static void vmd_irq_disable(struct irq_data *data) |
131 | { | 132 | { |
132 | struct vmd_irq *vmdirq = data->chip_data; | 133 | struct vmd_irq *vmdirq = data->chip_data; |
134 | unsigned long flags; | ||
133 | 135 | ||
134 | data->chip->irq_mask(data); | 136 | data->chip->irq_mask(data); |
135 | 137 | ||
136 | raw_spin_lock(&list_lock); | 138 | raw_spin_lock_irqsave(&list_lock, flags); |
137 | list_del_rcu(&vmdirq->node); | 139 | list_del_rcu(&vmdirq->node); |
138 | raw_spin_unlock(&list_lock); | 140 | INIT_LIST_HEAD_RCU(&vmdirq->node); |
141 | raw_spin_unlock_irqrestore(&list_lock, flags); | ||
139 | } | 142 | } |
140 | 143 | ||
141 | /* | 144 | /* |
@@ -166,16 +169,20 @@ static irq_hw_number_t vmd_get_hwirq(struct msi_domain_info *info, | |||
166 | * XXX: We can be even smarter selecting the best IRQ once we solve the | 169 | * XXX: We can be even smarter selecting the best IRQ once we solve the |
167 | * affinity problem. | 170 | * affinity problem. |
168 | */ | 171 | */ |
169 | static struct vmd_irq_list *vmd_next_irq(struct vmd_dev *vmd) | 172 | static struct vmd_irq_list *vmd_next_irq(struct vmd_dev *vmd, struct msi_desc *desc) |
170 | { | 173 | { |
171 | int i, best = 0; | 174 | int i, best = 1; |
175 | unsigned long flags; | ||
172 | 176 | ||
173 | raw_spin_lock(&list_lock); | 177 | if (!desc->msi_attrib.is_msix || vmd->msix_count == 1) |
178 | return &vmd->irqs[0]; | ||
179 | |||
180 | raw_spin_lock_irqsave(&list_lock, flags); | ||
174 | for (i = 1; i < vmd->msix_count; i++) | 181 | for (i = 1; i < vmd->msix_count; i++) |
175 | if (vmd->irqs[i].count < vmd->irqs[best].count) | 182 | if (vmd->irqs[i].count < vmd->irqs[best].count) |
176 | best = i; | 183 | best = i; |
177 | vmd->irqs[best].count++; | 184 | vmd->irqs[best].count++; |
178 | raw_spin_unlock(&list_lock); | 185 | raw_spin_unlock_irqrestore(&list_lock, flags); |
179 | 186 | ||
180 | return &vmd->irqs[best]; | 187 | return &vmd->irqs[best]; |
181 | } | 188 | } |
@@ -184,14 +191,15 @@ static int vmd_msi_init(struct irq_domain *domain, struct msi_domain_info *info, | |||
184 | unsigned int virq, irq_hw_number_t hwirq, | 191 | unsigned int virq, irq_hw_number_t hwirq, |
185 | msi_alloc_info_t *arg) | 192 | msi_alloc_info_t *arg) |
186 | { | 193 | { |
187 | struct vmd_dev *vmd = vmd_from_bus(msi_desc_to_pci_dev(arg->desc)->bus); | 194 | struct msi_desc *desc = arg->desc; |
195 | struct vmd_dev *vmd = vmd_from_bus(msi_desc_to_pci_dev(desc)->bus); | ||
188 | struct vmd_irq *vmdirq = kzalloc(sizeof(*vmdirq), GFP_KERNEL); | 196 | struct vmd_irq *vmdirq = kzalloc(sizeof(*vmdirq), GFP_KERNEL); |
189 | 197 | ||
190 | if (!vmdirq) | 198 | if (!vmdirq) |
191 | return -ENOMEM; | 199 | return -ENOMEM; |
192 | 200 | ||
193 | INIT_LIST_HEAD(&vmdirq->node); | 201 | INIT_LIST_HEAD(&vmdirq->node); |
194 | vmdirq->irq = vmd_next_irq(vmd); | 202 | vmdirq->irq = vmd_next_irq(vmd, desc); |
195 | vmdirq->virq = virq; | 203 | vmdirq->virq = virq; |
196 | 204 | ||
197 | irq_domain_set_info(domain, virq, vmdirq->irq->vmd_vector, info->chip, | 205 | irq_domain_set_info(domain, virq, vmdirq->irq->vmd_vector, info->chip, |
@@ -203,11 +211,12 @@ static void vmd_msi_free(struct irq_domain *domain, | |||
203 | struct msi_domain_info *info, unsigned int virq) | 211 | struct msi_domain_info *info, unsigned int virq) |
204 | { | 212 | { |
205 | struct vmd_irq *vmdirq = irq_get_chip_data(virq); | 213 | struct vmd_irq *vmdirq = irq_get_chip_data(virq); |
214 | unsigned long flags; | ||
206 | 215 | ||
207 | /* XXX: Potential optimization to rebalance */ | 216 | /* XXX: Potential optimization to rebalance */ |
208 | raw_spin_lock(&list_lock); | 217 | raw_spin_lock_irqsave(&list_lock, flags); |
209 | vmdirq->irq->count--; | 218 | vmdirq->irq->count--; |
210 | raw_spin_unlock(&list_lock); | 219 | raw_spin_unlock_irqrestore(&list_lock, flags); |
211 | 220 | ||
212 | kfree_rcu(vmdirq, rcu); | 221 | kfree_rcu(vmdirq, rcu); |
213 | } | 222 | } |
@@ -261,7 +270,7 @@ static struct device *to_vmd_dev(struct device *dev) | |||
261 | 270 | ||
262 | static struct dma_map_ops *vmd_dma_ops(struct device *dev) | 271 | static struct dma_map_ops *vmd_dma_ops(struct device *dev) |
263 | { | 272 | { |
264 | return to_vmd_dev(dev)->archdata.dma_ops; | 273 | return get_dma_ops(to_vmd_dev(dev)); |
265 | } | 274 | } |
266 | 275 | ||
267 | static void *vmd_alloc(struct device *dev, size_t size, dma_addr_t *addr, | 276 | static void *vmd_alloc(struct device *dev, size_t size, dma_addr_t *addr, |
@@ -367,7 +376,7 @@ static void vmd_teardown_dma_ops(struct vmd_dev *vmd) | |||
367 | { | 376 | { |
368 | struct dma_domain *domain = &vmd->dma_domain; | 377 | struct dma_domain *domain = &vmd->dma_domain; |
369 | 378 | ||
370 | if (vmd->dev->dev.archdata.dma_ops) | 379 | if (get_dma_ops(&vmd->dev->dev)) |
371 | del_dma_domain(domain); | 380 | del_dma_domain(domain); |
372 | } | 381 | } |
373 | 382 | ||
@@ -379,7 +388,7 @@ static void vmd_teardown_dma_ops(struct vmd_dev *vmd) | |||
379 | 388 | ||
380 | static void vmd_setup_dma_ops(struct vmd_dev *vmd) | 389 | static void vmd_setup_dma_ops(struct vmd_dev *vmd) |
381 | { | 390 | { |
382 | const struct dma_map_ops *source = vmd->dev->dev.archdata.dma_ops; | 391 | const struct dma_map_ops *source = get_dma_ops(&vmd->dev->dev); |
383 | struct dma_map_ops *dest = &vmd->dma_ops; | 392 | struct dma_map_ops *dest = &vmd->dma_ops; |
384 | struct dma_domain *domain = &vmd->dma_domain; | 393 | struct dma_domain *domain = &vmd->dma_domain; |
385 | 394 | ||
@@ -594,7 +603,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd) | |||
594 | sd->node = pcibus_to_node(vmd->dev->bus); | 603 | sd->node = pcibus_to_node(vmd->dev->bus); |
595 | 604 | ||
596 | vmd->irq_domain = pci_msi_create_irq_domain(NULL, &vmd_msi_domain_info, | 605 | vmd->irq_domain = pci_msi_create_irq_domain(NULL, &vmd_msi_domain_info, |
597 | NULL); | 606 | x86_vector_domain); |
598 | if (!vmd->irq_domain) | 607 | if (!vmd->irq_domain) |
599 | return -ENODEV; | 608 | return -ENODEV; |
600 | 609 | ||
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index b7e2e776397d..f98c3287256e 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -217,6 +217,9 @@ config ACPI_PROCESSOR_IDLE | |||
217 | bool | 217 | bool |
218 | select CPU_IDLE | 218 | select CPU_IDLE |
219 | 219 | ||
220 | config ACPI_MCFG | ||
221 | bool | ||
222 | |||
220 | config ACPI_CPPC_LIB | 223 | config ACPI_CPPC_LIB |
221 | bool | 224 | bool |
222 | depends on ACPI_PROCESSOR | 225 | depends on ACPI_PROCESSOR |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 251ce85a66fb..632e81feef69 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -40,6 +40,7 @@ acpi-$(CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC) += processor_pdc.o | |||
40 | acpi-y += ec.o | 40 | acpi-y += ec.o |
41 | acpi-$(CONFIG_ACPI_DOCK) += dock.o | 41 | acpi-$(CONFIG_ACPI_DOCK) += dock.o |
42 | acpi-y += pci_root.o pci_link.o pci_irq.o | 42 | acpi-y += pci_root.o pci_link.o pci_irq.o |
43 | obj-$(CONFIG_ACPI_MCFG) += pci_mcfg.o | ||
43 | acpi-y += acpi_lpss.o acpi_apd.o | 44 | acpi-y += acpi_lpss.o acpi_apd.o |
44 | acpi-y += acpi_platform.o | 45 | acpi-y += acpi_platform.o |
45 | acpi-y += acpi_pnp.o | 46 | acpi-y += acpi_pnp.o |
diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c new file mode 100644 index 000000000000..b5b376e081f5 --- /dev/null +++ b/drivers/acpi/pci_mcfg.c | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Broadcom | ||
3 | * Author: Jayachandran C <jchandra@broadcom.com> | ||
4 | * Copyright (C) 2016 Semihalf | ||
5 | * Author: Tomasz Nowicki <tn@semihalf.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License, version 2, as | ||
9 | * published by the Free Software Foundation (the "GPL"). | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License version 2 (GPLv2) for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * version 2 (GPLv2) along with this source code. | ||
18 | */ | ||
19 | |||
20 | #define pr_fmt(fmt) "ACPI: " fmt | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/pci.h> | ||
24 | #include <linux/pci-acpi.h> | ||
25 | |||
26 | /* Structure to hold entries from the MCFG table */ | ||
27 | struct mcfg_entry { | ||
28 | struct list_head list; | ||
29 | phys_addr_t addr; | ||
30 | u16 segment; | ||
31 | u8 bus_start; | ||
32 | u8 bus_end; | ||
33 | }; | ||
34 | |||
35 | /* List to save MCFG entries */ | ||
36 | static LIST_HEAD(pci_mcfg_list); | ||
37 | |||
38 | phys_addr_t pci_mcfg_lookup(u16 seg, struct resource *bus_res) | ||
39 | { | ||
40 | struct mcfg_entry *e; | ||
41 | |||
42 | /* | ||
43 | * We expect exact match, unless MCFG entry end bus covers more than | ||
44 | * specified by caller. | ||
45 | */ | ||
46 | list_for_each_entry(e, &pci_mcfg_list, list) { | ||
47 | if (e->segment == seg && e->bus_start == bus_res->start && | ||
48 | e->bus_end >= bus_res->end) | ||
49 | return e->addr; | ||
50 | } | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static __init int pci_mcfg_parse(struct acpi_table_header *header) | ||
56 | { | ||
57 | struct acpi_table_mcfg *mcfg; | ||
58 | struct acpi_mcfg_allocation *mptr; | ||
59 | struct mcfg_entry *e, *arr; | ||
60 | int i, n; | ||
61 | |||
62 | if (header->length < sizeof(struct acpi_table_mcfg)) | ||
63 | return -EINVAL; | ||
64 | |||
65 | n = (header->length - sizeof(struct acpi_table_mcfg)) / | ||
66 | sizeof(struct acpi_mcfg_allocation); | ||
67 | mcfg = (struct acpi_table_mcfg *)header; | ||
68 | mptr = (struct acpi_mcfg_allocation *) &mcfg[1]; | ||
69 | |||
70 | arr = kcalloc(n, sizeof(*arr), GFP_KERNEL); | ||
71 | if (!arr) | ||
72 | return -ENOMEM; | ||
73 | |||
74 | for (i = 0, e = arr; i < n; i++, mptr++, e++) { | ||
75 | e->segment = mptr->pci_segment; | ||
76 | e->addr = mptr->address; | ||
77 | e->bus_start = mptr->start_bus_number; | ||
78 | e->bus_end = mptr->end_bus_number; | ||
79 | list_add(&e->list, &pci_mcfg_list); | ||
80 | } | ||
81 | |||
82 | pr_info("MCFG table detected, %d entries\n", n); | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | /* Interface called by ACPI - parse and save MCFG table */ | ||
87 | void __init pci_mmcfg_late_init(void) | ||
88 | { | ||
89 | int err = acpi_table_parse(ACPI_SIG_MCFG, pci_mcfg_parse); | ||
90 | if (err) | ||
91 | pr_err("Failed to parse MCFG (%d)\n", err); | ||
92 | } | ||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index ae3fe4e64203..d144168d4ef9 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -720,6 +720,36 @@ next: | |||
720 | } | 720 | } |
721 | } | 721 | } |
722 | 722 | ||
723 | static void acpi_pci_root_remap_iospace(struct resource_entry *entry) | ||
724 | { | ||
725 | #ifdef PCI_IOBASE | ||
726 | struct resource *res = entry->res; | ||
727 | resource_size_t cpu_addr = res->start; | ||
728 | resource_size_t pci_addr = cpu_addr - entry->offset; | ||
729 | resource_size_t length = resource_size(res); | ||
730 | unsigned long port; | ||
731 | |||
732 | if (pci_register_io_range(cpu_addr, length)) | ||
733 | goto err; | ||
734 | |||
735 | port = pci_address_to_pio(cpu_addr); | ||
736 | if (port == (unsigned long)-1) | ||
737 | goto err; | ||
738 | |||
739 | res->start = port; | ||
740 | res->end = port + length - 1; | ||
741 | entry->offset = port - pci_addr; | ||
742 | |||
743 | if (pci_remap_iospace(res, cpu_addr) < 0) | ||
744 | goto err; | ||
745 | |||
746 | pr_info("Remapped I/O %pa to %pR\n", &cpu_addr, res); | ||
747 | return; | ||
748 | err: | ||
749 | res->flags |= IORESOURCE_DISABLED; | ||
750 | #endif | ||
751 | } | ||
752 | |||
723 | int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info) | 753 | int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info) |
724 | { | 754 | { |
725 | int ret; | 755 | int ret; |
@@ -740,6 +770,9 @@ int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info) | |||
740 | "no IO and memory resources present in _CRS\n"); | 770 | "no IO and memory resources present in _CRS\n"); |
741 | else { | 771 | else { |
742 | resource_list_for_each_entry_safe(entry, tmp, list) { | 772 | resource_list_for_each_entry_safe(entry, tmp, list) { |
773 | if (entry->res->flags & IORESOURCE_IO) | ||
774 | acpi_pci_root_remap_iospace(entry); | ||
775 | |||
743 | if (entry->res->flags & IORESOURCE_DISABLED) | 776 | if (entry->res->flags & IORESOURCE_DISABLED) |
744 | resource_list_destroy_entry(entry); | 777 | resource_list_destroy_entry(entry); |
745 | else | 778 | else |
@@ -811,6 +844,8 @@ static void acpi_pci_root_release_info(struct pci_host_bridge *bridge) | |||
811 | 844 | ||
812 | resource_list_for_each_entry(entry, &bridge->windows) { | 845 | resource_list_for_each_entry(entry, &bridge->windows) { |
813 | res = entry->res; | 846 | res = entry->res; |
847 | if (res->flags & IORESOURCE_IO) | ||
848 | pci_unmap_iospace(res); | ||
814 | if (res->parent && | 849 | if (res->parent && |
815 | (res->flags & (IORESOURCE_MEM | IORESOURCE_IO))) | 850 | (res->flags & (IORESOURCE_MEM | IORESOURCE_IO))) |
816 | release_resource(res); | 851 | release_resource(res); |
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index fa33c50b0e5a..11ecb6cfb2e5 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig | |||
@@ -15,9 +15,9 @@ config ARM_GIC_MAX_NR | |||
15 | 15 | ||
16 | config ARM_GIC_V2M | 16 | config ARM_GIC_V2M |
17 | bool | 17 | bool |
18 | depends on ARM_GIC | 18 | depends on PCI |
19 | depends on PCI && PCI_MSI | 19 | select ARM_GIC |
20 | select PCI_MSI_IRQ_DOMAIN | 20 | select PCI_MSI |
21 | 21 | ||
22 | config GIC_NON_BANKED | 22 | config GIC_NON_BANKED |
23 | bool | 23 | bool |
@@ -31,7 +31,8 @@ config ARM_GIC_V3 | |||
31 | 31 | ||
32 | config ARM_GIC_V3_ITS | 32 | config ARM_GIC_V3_ITS |
33 | bool | 33 | bool |
34 | select PCI_MSI_IRQ_DOMAIN | 34 | depends on PCI |
35 | depends on PCI_MSI | ||
35 | 36 | ||
36 | config ARM_NVIC | 37 | config ARM_NVIC |
37 | bool | 38 | bool |
@@ -56,13 +57,13 @@ config ARM_VIC_NR | |||
56 | config ARMADA_370_XP_IRQ | 57 | config ARMADA_370_XP_IRQ |
57 | bool | 58 | bool |
58 | select GENERIC_IRQ_CHIP | 59 | select GENERIC_IRQ_CHIP |
59 | select PCI_MSI_IRQ_DOMAIN if PCI_MSI | 60 | select PCI_MSI if PCI |
60 | 61 | ||
61 | config ALPINE_MSI | 62 | config ALPINE_MSI |
62 | bool | 63 | bool |
63 | depends on PCI && PCI_MSI | 64 | depends on PCI |
65 | select PCI_MSI | ||
64 | select GENERIC_IRQ_CHIP | 66 | select GENERIC_IRQ_CHIP |
65 | select PCI_MSI_IRQ_DOMAIN | ||
66 | 67 | ||
67 | config ATMEL_AIC_IRQ | 68 | config ATMEL_AIC_IRQ |
68 | bool | 69 | bool |
@@ -111,7 +112,6 @@ config HISILICON_IRQ_MBIGEN | |||
111 | bool | 112 | bool |
112 | select ARM_GIC_V3 | 113 | select ARM_GIC_V3 |
113 | select ARM_GIC_V3_ITS | 114 | select ARM_GIC_V3_ITS |
114 | select GENERIC_MSI_IRQ_DOMAIN | ||
115 | 115 | ||
116 | config IMGPDC_IRQ | 116 | config IMGPDC_IRQ |
117 | bool | 117 | bool |
@@ -244,12 +244,10 @@ config IRQ_MXS | |||
244 | 244 | ||
245 | config MVEBU_ODMI | 245 | config MVEBU_ODMI |
246 | bool | 246 | bool |
247 | select GENERIC_MSI_IRQ_DOMAIN | ||
248 | 247 | ||
249 | config LS_SCFG_MSI | 248 | config LS_SCFG_MSI |
250 | def_bool y if SOC_LS1021A || ARCH_LAYERSCAPE | 249 | def_bool y if SOC_LS1021A || ARCH_LAYERSCAPE |
251 | depends on PCI && PCI_MSI | 250 | depends on PCI && PCI_MSI |
252 | select PCI_MSI_IRQ_DOMAIN | ||
253 | 251 | ||
254 | config PARTITION_PERCPU | 252 | config PARTITION_PERCPU |
255 | bool | 253 | bool |
diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index 4cf8f82cfca2..a70b853fa2c9 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c | |||
@@ -182,7 +182,7 @@ static void genwqe_dev_free(struct genwqe_dev *cd) | |||
182 | */ | 182 | */ |
183 | static int genwqe_bus_reset(struct genwqe_dev *cd) | 183 | static int genwqe_bus_reset(struct genwqe_dev *cd) |
184 | { | 184 | { |
185 | int bars, rc = 0; | 185 | int rc = 0; |
186 | struct pci_dev *pci_dev = cd->pci_dev; | 186 | struct pci_dev *pci_dev = cd->pci_dev; |
187 | void __iomem *mmio; | 187 | void __iomem *mmio; |
188 | 188 | ||
@@ -193,8 +193,7 @@ static int genwqe_bus_reset(struct genwqe_dev *cd) | |||
193 | cd->mmio = NULL; | 193 | cd->mmio = NULL; |
194 | pci_iounmap(pci_dev, mmio); | 194 | pci_iounmap(pci_dev, mmio); |
195 | 195 | ||
196 | bars = pci_select_bars(pci_dev, IORESOURCE_MEM); | 196 | pci_release_mem_regions(pci_dev); |
197 | pci_release_selected_regions(pci_dev, bars); | ||
198 | 197 | ||
199 | /* | 198 | /* |
200 | * Firmware/BIOS might change memory mapping during bus reset. | 199 | * Firmware/BIOS might change memory mapping during bus reset. |
@@ -218,7 +217,7 @@ static int genwqe_bus_reset(struct genwqe_dev *cd) | |||
218 | GENWQE_INJECT_GFIR_FATAL | | 217 | GENWQE_INJECT_GFIR_FATAL | |
219 | GENWQE_INJECT_GFIR_INFO); | 218 | GENWQE_INJECT_GFIR_INFO); |
220 | 219 | ||
221 | rc = pci_request_selected_regions(pci_dev, bars, genwqe_driver_name); | 220 | rc = pci_request_mem_regions(pci_dev, genwqe_driver_name); |
222 | if (rc) { | 221 | if (rc) { |
223 | dev_err(&pci_dev->dev, | 222 | dev_err(&pci_dev->dev, |
224 | "[%s] err: request bars failed (%d)\n", __func__, rc); | 223 | "[%s] err: request bars failed (%d)\n", __func__, rc); |
@@ -1068,10 +1067,9 @@ static int genwqe_health_check_stop(struct genwqe_dev *cd) | |||
1068 | */ | 1067 | */ |
1069 | static int genwqe_pci_setup(struct genwqe_dev *cd) | 1068 | static int genwqe_pci_setup(struct genwqe_dev *cd) |
1070 | { | 1069 | { |
1071 | int err, bars; | 1070 | int err; |
1072 | struct pci_dev *pci_dev = cd->pci_dev; | 1071 | struct pci_dev *pci_dev = cd->pci_dev; |
1073 | 1072 | ||
1074 | bars = pci_select_bars(pci_dev, IORESOURCE_MEM); | ||
1075 | err = pci_enable_device_mem(pci_dev); | 1073 | err = pci_enable_device_mem(pci_dev); |
1076 | if (err) { | 1074 | if (err) { |
1077 | dev_err(&pci_dev->dev, | 1075 | dev_err(&pci_dev->dev, |
@@ -1080,7 +1078,7 @@ static int genwqe_pci_setup(struct genwqe_dev *cd) | |||
1080 | } | 1078 | } |
1081 | 1079 | ||
1082 | /* Reserve PCI I/O and memory resources */ | 1080 | /* Reserve PCI I/O and memory resources */ |
1083 | err = pci_request_selected_regions(pci_dev, bars, genwqe_driver_name); | 1081 | err = pci_request_mem_regions(pci_dev, genwqe_driver_name); |
1084 | if (err) { | 1082 | if (err) { |
1085 | dev_err(&pci_dev->dev, | 1083 | dev_err(&pci_dev->dev, |
1086 | "[%s] err: request bars failed (%d)\n", __func__, err); | 1084 | "[%s] err: request bars failed (%d)\n", __func__, err); |
@@ -1142,7 +1140,7 @@ static int genwqe_pci_setup(struct genwqe_dev *cd) | |||
1142 | out_iounmap: | 1140 | out_iounmap: |
1143 | pci_iounmap(pci_dev, cd->mmio); | 1141 | pci_iounmap(pci_dev, cd->mmio); |
1144 | out_release_resources: | 1142 | out_release_resources: |
1145 | pci_release_selected_regions(pci_dev, bars); | 1143 | pci_release_mem_regions(pci_dev); |
1146 | err_disable_device: | 1144 | err_disable_device: |
1147 | pci_disable_device(pci_dev); | 1145 | pci_disable_device(pci_dev); |
1148 | err_out: | 1146 | err_out: |
@@ -1154,14 +1152,12 @@ static int genwqe_pci_setup(struct genwqe_dev *cd) | |||
1154 | */ | 1152 | */ |
1155 | static void genwqe_pci_remove(struct genwqe_dev *cd) | 1153 | static void genwqe_pci_remove(struct genwqe_dev *cd) |
1156 | { | 1154 | { |
1157 | int bars; | ||
1158 | struct pci_dev *pci_dev = cd->pci_dev; | 1155 | struct pci_dev *pci_dev = cd->pci_dev; |
1159 | 1156 | ||
1160 | if (cd->mmio) | 1157 | if (cd->mmio) |
1161 | pci_iounmap(pci_dev, cd->mmio); | 1158 | pci_iounmap(pci_dev, cd->mmio); |
1162 | 1159 | ||
1163 | bars = pci_select_bars(pci_dev, IORESOURCE_MEM); | 1160 | pci_release_mem_regions(pci_dev); |
1164 | pci_release_selected_regions(pci_dev, bars); | ||
1165 | pci_disable_device(pci_dev); | 1161 | pci_disable_device(pci_dev); |
1166 | } | 1162 | } |
1167 | 1163 | ||
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index c98acdc0d14f..ec157a0c5d2a 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c | |||
@@ -1284,7 +1284,7 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1284 | struct alx_priv *alx; | 1284 | struct alx_priv *alx; |
1285 | struct alx_hw *hw; | 1285 | struct alx_hw *hw; |
1286 | bool phy_configured; | 1286 | bool phy_configured; |
1287 | int bars, err; | 1287 | int err; |
1288 | 1288 | ||
1289 | err = pci_enable_device_mem(pdev); | 1289 | err = pci_enable_device_mem(pdev); |
1290 | if (err) | 1290 | if (err) |
@@ -1304,11 +1304,10 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1304 | } | 1304 | } |
1305 | } | 1305 | } |
1306 | 1306 | ||
1307 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | 1307 | err = pci_request_mem_regions(pdev, alx_drv_name); |
1308 | err = pci_request_selected_regions(pdev, bars, alx_drv_name); | ||
1309 | if (err) { | 1308 | if (err) { |
1310 | dev_err(&pdev->dev, | 1309 | dev_err(&pdev->dev, |
1311 | "pci_request_selected_regions failed(bars:%d)\n", bars); | 1310 | "pci_request_mem_regions failed\n"); |
1312 | goto out_pci_disable; | 1311 | goto out_pci_disable; |
1313 | } | 1312 | } |
1314 | 1313 | ||
@@ -1434,7 +1433,7 @@ out_unmap: | |||
1434 | out_free_netdev: | 1433 | out_free_netdev: |
1435 | free_netdev(netdev); | 1434 | free_netdev(netdev); |
1436 | out_pci_release: | 1435 | out_pci_release: |
1437 | pci_release_selected_regions(pdev, bars); | 1436 | pci_release_mem_regions(pdev); |
1438 | out_pci_disable: | 1437 | out_pci_disable: |
1439 | pci_disable_device(pdev); | 1438 | pci_disable_device(pdev); |
1440 | return err; | 1439 | return err; |
@@ -1453,8 +1452,7 @@ static void alx_remove(struct pci_dev *pdev) | |||
1453 | 1452 | ||
1454 | unregister_netdev(alx->dev); | 1453 | unregister_netdev(alx->dev); |
1455 | iounmap(hw->hw_addr); | 1454 | iounmap(hw->hw_addr); |
1456 | pci_release_selected_regions(pdev, | 1455 | pci_release_mem_regions(pdev); |
1457 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
1458 | 1456 | ||
1459 | pci_disable_pcie_error_reporting(pdev); | 1457 | pci_disable_pcie_error_reporting(pdev); |
1460 | pci_disable_device(pdev); | 1458 | pci_disable_device(pdev); |
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 75e60897b7e7..a2dfa2fbedd8 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
@@ -7321,8 +7321,7 @@ err_flashmap: | |||
7321 | err_ioremap: | 7321 | err_ioremap: |
7322 | free_netdev(netdev); | 7322 | free_netdev(netdev); |
7323 | err_alloc_etherdev: | 7323 | err_alloc_etherdev: |
7324 | pci_release_selected_regions(pdev, | 7324 | pci_release_mem_regions(pdev); |
7325 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
7326 | err_pci_reg: | 7325 | err_pci_reg: |
7327 | err_dma: | 7326 | err_dma: |
7328 | pci_disable_device(pdev); | 7327 | pci_disable_device(pdev); |
@@ -7389,8 +7388,7 @@ static void e1000_remove(struct pci_dev *pdev) | |||
7389 | if ((adapter->hw.flash_address) && | 7388 | if ((adapter->hw.flash_address) && |
7390 | (adapter->hw.mac.type < e1000_pch_spt)) | 7389 | (adapter->hw.mac.type < e1000_pch_spt)) |
7391 | iounmap(adapter->hw.flash_address); | 7390 | iounmap(adapter->hw.flash_address); |
7392 | pci_release_selected_regions(pdev, | 7391 | pci_release_mem_regions(pdev); |
7393 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
7394 | 7392 | ||
7395 | free_netdev(netdev); | 7393 | free_netdev(netdev); |
7396 | 7394 | ||
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c index e05aca9bef0e..a5bccc801177 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c | |||
@@ -1869,10 +1869,7 @@ static int fm10k_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1869 | goto err_dma; | 1869 | goto err_dma; |
1870 | } | 1870 | } |
1871 | 1871 | ||
1872 | err = pci_request_selected_regions(pdev, | 1872 | err = pci_request_mem_regions(pdev, fm10k_driver_name); |
1873 | pci_select_bars(pdev, | ||
1874 | IORESOURCE_MEM), | ||
1875 | fm10k_driver_name); | ||
1876 | if (err) { | 1873 | if (err) { |
1877 | dev_err(&pdev->dev, | 1874 | dev_err(&pdev->dev, |
1878 | "pci_request_selected_regions failed: %d\n", err); | 1875 | "pci_request_selected_regions failed: %d\n", err); |
@@ -1976,8 +1973,7 @@ err_sw_init: | |||
1976 | err_ioremap: | 1973 | err_ioremap: |
1977 | free_netdev(netdev); | 1974 | free_netdev(netdev); |
1978 | err_alloc_netdev: | 1975 | err_alloc_netdev: |
1979 | pci_release_selected_regions(pdev, | 1976 | pci_release_mem_regions(pdev); |
1980 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
1981 | err_pci_reg: | 1977 | err_pci_reg: |
1982 | err_dma: | 1978 | err_dma: |
1983 | pci_disable_device(pdev); | 1979 | pci_disable_device(pdev); |
@@ -2025,8 +2021,7 @@ static void fm10k_remove(struct pci_dev *pdev) | |||
2025 | 2021 | ||
2026 | free_netdev(netdev); | 2022 | free_netdev(netdev); |
2027 | 2023 | ||
2028 | pci_release_selected_regions(pdev, | 2024 | pci_release_mem_regions(pdev); |
2029 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
2030 | 2025 | ||
2031 | pci_disable_pcie_error_reporting(pdev); | 2026 | pci_disable_pcie_error_reporting(pdev); |
2032 | 2027 | ||
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 5ea22008d721..2e10d2341a29 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c | |||
@@ -10769,8 +10769,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
10769 | } | 10769 | } |
10770 | 10770 | ||
10771 | /* set up pci connections */ | 10771 | /* set up pci connections */ |
10772 | err = pci_request_selected_regions(pdev, pci_select_bars(pdev, | 10772 | err = pci_request_mem_regions(pdev, i40e_driver_name); |
10773 | IORESOURCE_MEM), i40e_driver_name); | ||
10774 | if (err) { | 10773 | if (err) { |
10775 | dev_info(&pdev->dev, | 10774 | dev_info(&pdev->dev, |
10776 | "pci_request_selected_regions failed %d\n", err); | 10775 | "pci_request_selected_regions failed %d\n", err); |
@@ -11267,8 +11266,7 @@ err_ioremap: | |||
11267 | kfree(pf); | 11266 | kfree(pf); |
11268 | err_pf_alloc: | 11267 | err_pf_alloc: |
11269 | pci_disable_pcie_error_reporting(pdev); | 11268 | pci_disable_pcie_error_reporting(pdev); |
11270 | pci_release_selected_regions(pdev, | 11269 | pci_release_mem_regions(pdev); |
11271 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
11272 | err_pci_reg: | 11270 | err_pci_reg: |
11273 | err_dma: | 11271 | err_dma: |
11274 | pci_disable_device(pdev); | 11272 | pci_disable_device(pdev); |
@@ -11379,8 +11377,7 @@ static void i40e_remove(struct pci_dev *pdev) | |||
11379 | 11377 | ||
11380 | iounmap(hw->hw_addr); | 11378 | iounmap(hw->hw_addr); |
11381 | kfree(pf); | 11379 | kfree(pf); |
11382 | pci_release_selected_regions(pdev, | 11380 | pci_release_mem_regions(pdev); |
11383 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
11384 | 11381 | ||
11385 | pci_disable_pcie_error_reporting(pdev); | 11382 | pci_disable_pcie_error_reporting(pdev); |
11386 | pci_disable_device(pdev); | 11383 | pci_disable_device(pdev); |
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index ef3d642f5ff2..1c96fe83000a 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
@@ -2323,9 +2323,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2323 | } | 2323 | } |
2324 | } | 2324 | } |
2325 | 2325 | ||
2326 | err = pci_request_selected_regions(pdev, pci_select_bars(pdev, | 2326 | err = pci_request_mem_regions(pdev, igb_driver_name); |
2327 | IORESOURCE_MEM), | ||
2328 | igb_driver_name); | ||
2329 | if (err) | 2327 | if (err) |
2330 | goto err_pci_reg; | 2328 | goto err_pci_reg; |
2331 | 2329 | ||
@@ -2749,8 +2747,7 @@ err_sw_init: | |||
2749 | err_ioremap: | 2747 | err_ioremap: |
2750 | free_netdev(netdev); | 2748 | free_netdev(netdev); |
2751 | err_alloc_etherdev: | 2749 | err_alloc_etherdev: |
2752 | pci_release_selected_regions(pdev, | 2750 | pci_release_mem_regions(pdev); |
2753 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
2754 | err_pci_reg: | 2751 | err_pci_reg: |
2755 | err_dma: | 2752 | err_dma: |
2756 | pci_disable_device(pdev); | 2753 | pci_disable_device(pdev); |
@@ -2915,8 +2912,7 @@ static void igb_remove(struct pci_dev *pdev) | |||
2915 | pci_iounmap(pdev, adapter->io_addr); | 2912 | pci_iounmap(pdev, adapter->io_addr); |
2916 | if (hw->flash_address) | 2913 | if (hw->flash_address) |
2917 | iounmap(hw->flash_address); | 2914 | iounmap(hw->flash_address); |
2918 | pci_release_selected_regions(pdev, | 2915 | pci_release_mem_regions(pdev); |
2919 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
2920 | 2916 | ||
2921 | kfree(adapter->shadow_vfta); | 2917 | kfree(adapter->shadow_vfta); |
2922 | free_netdev(netdev); | 2918 | free_netdev(netdev); |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 088c47cf27d9..162946838772 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -9331,8 +9331,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
9331 | pci_using_dac = 0; | 9331 | pci_using_dac = 0; |
9332 | } | 9332 | } |
9333 | 9333 | ||
9334 | err = pci_request_selected_regions(pdev, pci_select_bars(pdev, | 9334 | err = pci_request_mem_regions(pdev, ixgbe_driver_name); |
9335 | IORESOURCE_MEM), ixgbe_driver_name); | ||
9336 | if (err) { | 9335 | if (err) { |
9337 | dev_err(&pdev->dev, | 9336 | dev_err(&pdev->dev, |
9338 | "pci_request_selected_regions failed 0x%x\n", err); | 9337 | "pci_request_selected_regions failed 0x%x\n", err); |
@@ -9718,8 +9717,7 @@ err_ioremap: | |||
9718 | disable_dev = !test_and_set_bit(__IXGBE_DISABLED, &adapter->state); | 9717 | disable_dev = !test_and_set_bit(__IXGBE_DISABLED, &adapter->state); |
9719 | free_netdev(netdev); | 9718 | free_netdev(netdev); |
9720 | err_alloc_etherdev: | 9719 | err_alloc_etherdev: |
9721 | pci_release_selected_regions(pdev, | 9720 | pci_release_mem_regions(pdev); |
9722 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
9723 | err_pci_reg: | 9721 | err_pci_reg: |
9724 | err_dma: | 9722 | err_dma: |
9725 | if (!adapter || disable_dev) | 9723 | if (!adapter || disable_dev) |
@@ -9786,8 +9784,7 @@ static void ixgbe_remove(struct pci_dev *pdev) | |||
9786 | 9784 | ||
9787 | #endif | 9785 | #endif |
9788 | iounmap(adapter->io_addr); | 9786 | iounmap(adapter->io_addr); |
9789 | pci_release_selected_regions(pdev, pci_select_bars(pdev, | 9787 | pci_release_mem_regions(pdev); |
9790 | IORESOURCE_MEM)); | ||
9791 | 9788 | ||
9792 | e_dev_info("complete\n"); | 9789 | e_dev_info("complete\n"); |
9793 | 9790 | ||
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 78dca3193ca4..7e4d81208da7 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c | |||
@@ -1681,7 +1681,7 @@ static void nvme_dev_unmap(struct nvme_dev *dev) | |||
1681 | { | 1681 | { |
1682 | if (dev->bar) | 1682 | if (dev->bar) |
1683 | iounmap(dev->bar); | 1683 | iounmap(dev->bar); |
1684 | pci_release_regions(to_pci_dev(dev->dev)); | 1684 | pci_release_mem_regions(to_pci_dev(dev->dev)); |
1685 | } | 1685 | } |
1686 | 1686 | ||
1687 | static void nvme_pci_disable(struct nvme_dev *dev) | 1687 | static void nvme_pci_disable(struct nvme_dev *dev) |
@@ -1909,13 +1909,9 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = { | |||
1909 | 1909 | ||
1910 | static int nvme_dev_map(struct nvme_dev *dev) | 1910 | static int nvme_dev_map(struct nvme_dev *dev) |
1911 | { | 1911 | { |
1912 | int bars; | ||
1913 | struct pci_dev *pdev = to_pci_dev(dev->dev); | 1912 | struct pci_dev *pdev = to_pci_dev(dev->dev); |
1914 | 1913 | ||
1915 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | 1914 | if (pci_request_mem_regions(pdev, "nvme")) |
1916 | if (!bars) | ||
1917 | return -ENODEV; | ||
1918 | if (pci_request_selected_regions(pdev, bars, "nvme")) | ||
1919 | return -ENODEV; | 1915 | return -ENODEV; |
1920 | 1916 | ||
1921 | dev->bar = ioremap(pci_resource_start(pdev, 0), 8192); | 1917 | dev->bar = ioremap(pci_resource_start(pdev, 0), 8192); |
@@ -1924,7 +1920,7 @@ static int nvme_dev_map(struct nvme_dev *dev) | |||
1924 | 1920 | ||
1925 | return 0; | 1921 | return 0; |
1926 | release: | 1922 | release: |
1927 | pci_release_regions(pdev); | 1923 | pci_release_mem_regions(pdev); |
1928 | return -ENODEV; | 1924 | return -ENODEV; |
1929 | } | 1925 | } |
1930 | 1926 | ||
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 56389be5d08b..67f9916ff14d 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig | |||
@@ -25,7 +25,7 @@ config PCI_MSI | |||
25 | If you don't know what to do here, say Y. | 25 | If you don't know what to do here, say Y. |
26 | 26 | ||
27 | config PCI_MSI_IRQ_DOMAIN | 27 | config PCI_MSI_IRQ_DOMAIN |
28 | bool | 28 | def_bool ARM || ARM64 || X86 |
29 | depends on PCI_MSI | 29 | depends on PCI_MSI |
30 | select GENERIC_MSI_IRQ_DOMAIN | 30 | select GENERIC_MSI_IRQ_DOMAIN |
31 | 31 | ||
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index dd7cdbee8029..c288e5a52575 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -91,6 +91,35 @@ void pci_bus_remove_resources(struct pci_bus *bus) | |||
91 | } | 91 | } |
92 | } | 92 | } |
93 | 93 | ||
94 | int devm_request_pci_bus_resources(struct device *dev, | ||
95 | struct list_head *resources) | ||
96 | { | ||
97 | struct resource_entry *win; | ||
98 | struct resource *parent, *res; | ||
99 | int err; | ||
100 | |||
101 | resource_list_for_each_entry(win, resources) { | ||
102 | res = win->res; | ||
103 | switch (resource_type(res)) { | ||
104 | case IORESOURCE_IO: | ||
105 | parent = &ioport_resource; | ||
106 | break; | ||
107 | case IORESOURCE_MEM: | ||
108 | parent = &iomem_resource; | ||
109 | break; | ||
110 | default: | ||
111 | continue; | ||
112 | } | ||
113 | |||
114 | err = devm_request_resource(dev, parent, res); | ||
115 | if (err) | ||
116 | return err; | ||
117 | } | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | EXPORT_SYMBOL_GPL(devm_request_pci_bus_resources); | ||
122 | |||
94 | static struct pci_bus_region pci_32_bit = {0, 0xffffffffULL}; | 123 | static struct pci_bus_region pci_32_bit = {0, 0xffffffffULL}; |
95 | #ifdef CONFIG_PCI_BUS_ADDR_T_64BIT | 124 | #ifdef CONFIG_PCI_BUS_ADDR_T_64BIT |
96 | static struct pci_bus_region pci_64_bit = {0, | 125 | static struct pci_bus_region pci_64_bit = {0, |
@@ -291,6 +320,7 @@ void pci_bus_add_device(struct pci_dev *dev) | |||
291 | pci_fixup_device(pci_fixup_final, dev); | 320 | pci_fixup_device(pci_fixup_final, dev); |
292 | pci_create_sysfs_dev_files(dev); | 321 | pci_create_sysfs_dev_files(dev); |
293 | pci_proc_attach_device(dev); | 322 | pci_proc_attach_device(dev); |
323 | pci_bridge_d3_device_changed(dev); | ||
294 | 324 | ||
295 | dev->match_driver = true; | 325 | dev->match_driver = true; |
296 | retval = device_attach(&dev->dev); | 326 | retval = device_attach(&dev->dev); |
@@ -397,4 +427,3 @@ void pci_bus_put(struct pci_bus *bus) | |||
397 | put_device(&bus->dev); | 427 | put_device(&bus->dev); |
398 | } | 428 | } |
399 | EXPORT_SYMBOL(pci_bus_put); | 429 | EXPORT_SYMBOL(pci_bus_put); |
400 | |||
diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c index f9832ad8efe2..66e0d718472f 100644 --- a/drivers/pci/ecam.c +++ b/drivers/pci/ecam.c | |||
@@ -19,10 +19,9 @@ | |||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
22 | #include <linux/pci-ecam.h> | ||
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
23 | 24 | ||
24 | #include "ecam.h" | ||
25 | |||
26 | /* | 25 | /* |
27 | * On 64-bit systems, we do a single ioremap for the whole config space | 26 | * On 64-bit systems, we do a single ioremap for the whole config space |
28 | * since we have enough virtual address range available. On 32-bit, we | 27 | * since we have enough virtual address range available. On 32-bit, we |
@@ -52,6 +51,7 @@ struct pci_config_window *pci_ecam_create(struct device *dev, | |||
52 | if (!cfg) | 51 | if (!cfg) |
53 | return ERR_PTR(-ENOMEM); | 52 | return ERR_PTR(-ENOMEM); |
54 | 53 | ||
54 | cfg->parent = dev; | ||
55 | cfg->ops = ops; | 55 | cfg->ops = ops; |
56 | cfg->busr.start = busr->start; | 56 | cfg->busr.start = busr->start; |
57 | cfg->busr.end = busr->end; | 57 | cfg->busr.end = busr->end; |
@@ -95,7 +95,7 @@ struct pci_config_window *pci_ecam_create(struct device *dev, | |||
95 | } | 95 | } |
96 | 96 | ||
97 | if (ops->init) { | 97 | if (ops->init) { |
98 | err = ops->init(dev, cfg); | 98 | err = ops->init(cfg); |
99 | if (err) | 99 | if (err) |
100 | goto err_exit; | 100 | goto err_exit; |
101 | } | 101 | } |
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 5d2374e4ee7f..9b485d873b0d 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig | |||
@@ -3,8 +3,9 @@ menu "PCI host controller drivers" | |||
3 | 3 | ||
4 | config PCI_DRA7XX | 4 | config PCI_DRA7XX |
5 | bool "TI DRA7xx PCIe controller" | 5 | bool "TI DRA7xx PCIe controller" |
6 | select PCIE_DW | ||
7 | depends on OF && HAS_IOMEM && TI_PIPE3 | 6 | depends on OF && HAS_IOMEM && TI_PIPE3 |
7 | depends on PCI_MSI_IRQ_DOMAIN | ||
8 | select PCIE_DW | ||
8 | help | 9 | help |
9 | Enables support for the PCIe controller in the DRA7xx SoC. There | 10 | Enables support for the PCIe controller in the DRA7xx SoC. There |
10 | are two instances of PCIe controller in DRA7xx. This controller can | 11 | are two instances of PCIe controller in DRA7xx. This controller can |
@@ -16,11 +17,20 @@ config PCI_MVEBU | |||
16 | depends on ARM | 17 | depends on ARM |
17 | depends on OF | 18 | depends on OF |
18 | 19 | ||
20 | config PCI_AARDVARK | ||
21 | bool "Aardvark PCIe controller" | ||
22 | depends on ARCH_MVEBU && ARM64 | ||
23 | depends on OF | ||
24 | depends on PCI_MSI_IRQ_DOMAIN | ||
25 | help | ||
26 | Add support for Aardvark 64bit PCIe Host Controller. This | ||
27 | controller is part of the South Bridge of the Marvel Armada | ||
28 | 3700 SoC. | ||
19 | 29 | ||
20 | config PCIE_XILINX_NWL | 30 | config PCIE_XILINX_NWL |
21 | bool "NWL PCIe Core" | 31 | bool "NWL PCIe Core" |
22 | depends on ARCH_ZYNQMP | 32 | depends on ARCH_ZYNQMP |
23 | select PCI_MSI_IRQ_DOMAIN if PCI_MSI | 33 | depends on PCI_MSI_IRQ_DOMAIN |
24 | help | 34 | help |
25 | Say 'Y' here if you want kernel support for Xilinx | 35 | Say 'Y' here if you want kernel support for Xilinx |
26 | NWL PCIe controller. The controller can act as Root Port | 36 | NWL PCIe controller. The controller can act as Root Port |
@@ -29,6 +39,7 @@ config PCIE_XILINX_NWL | |||
29 | 39 | ||
30 | config PCIE_DW_PLAT | 40 | config PCIE_DW_PLAT |
31 | bool "Platform bus based DesignWare PCIe Controller" | 41 | bool "Platform bus based DesignWare PCIe Controller" |
42 | depends on PCI_MSI_IRQ_DOMAIN | ||
32 | select PCIE_DW | 43 | select PCIE_DW |
33 | ---help--- | 44 | ---help--- |
34 | This selects the DesignWare PCIe controller support. Select this if | 45 | This selects the DesignWare PCIe controller support. Select this if |
@@ -40,16 +51,19 @@ config PCIE_DW_PLAT | |||
40 | 51 | ||
41 | config PCIE_DW | 52 | config PCIE_DW |
42 | bool | 53 | bool |
54 | depends on PCI_MSI_IRQ_DOMAIN | ||
43 | 55 | ||
44 | config PCI_EXYNOS | 56 | config PCI_EXYNOS |
45 | bool "Samsung Exynos PCIe controller" | 57 | bool "Samsung Exynos PCIe controller" |
46 | depends on SOC_EXYNOS5440 | 58 | depends on SOC_EXYNOS5440 |
59 | depends on PCI_MSI_IRQ_DOMAIN | ||
47 | select PCIEPORTBUS | 60 | select PCIEPORTBUS |
48 | select PCIE_DW | 61 | select PCIE_DW |
49 | 62 | ||
50 | config PCI_IMX6 | 63 | config PCI_IMX6 |
51 | bool "Freescale i.MX6 PCIe controller" | 64 | bool "Freescale i.MX6 PCIe controller" |
52 | depends on SOC_IMX6Q | 65 | depends on SOC_IMX6Q |
66 | depends on PCI_MSI_IRQ_DOMAIN | ||
53 | select PCIEPORTBUS | 67 | select PCIEPORTBUS |
54 | select PCIE_DW | 68 | select PCIE_DW |
55 | 69 | ||
@@ -72,8 +86,7 @@ config PCI_RCAR_GEN2 | |||
72 | config PCIE_RCAR | 86 | config PCIE_RCAR |
73 | bool "Renesas R-Car PCIe controller" | 87 | bool "Renesas R-Car PCIe controller" |
74 | depends on ARCH_RENESAS || (ARM && COMPILE_TEST) | 88 | depends on ARCH_RENESAS || (ARM && COMPILE_TEST) |
75 | select PCI_MSI | 89 | depends on PCI_MSI_IRQ_DOMAIN |
76 | select PCI_MSI_IRQ_DOMAIN | ||
77 | help | 90 | help |
78 | Say Y here if you want PCIe controller support on R-Car SoCs. | 91 | Say Y here if you want PCIe controller support on R-Car SoCs. |
79 | 92 | ||
@@ -85,6 +98,7 @@ config PCI_HOST_GENERIC | |||
85 | bool "Generic PCI host controller" | 98 | bool "Generic PCI host controller" |
86 | depends on (ARM || ARM64) && OF | 99 | depends on (ARM || ARM64) && OF |
87 | select PCI_HOST_COMMON | 100 | select PCI_HOST_COMMON |
101 | select IRQ_DOMAIN | ||
88 | help | 102 | help |
89 | Say Y here if you want to support a simple generic PCI host | 103 | Say Y here if you want to support a simple generic PCI host |
90 | controller, such as the one emulated by kvmtool. | 104 | controller, such as the one emulated by kvmtool. |
@@ -92,6 +106,7 @@ config PCI_HOST_GENERIC | |||
92 | config PCIE_SPEAR13XX | 106 | config PCIE_SPEAR13XX |
93 | bool "STMicroelectronics SPEAr PCIe controller" | 107 | bool "STMicroelectronics SPEAr PCIe controller" |
94 | depends on ARCH_SPEAR13XX | 108 | depends on ARCH_SPEAR13XX |
109 | depends on PCI_MSI_IRQ_DOMAIN | ||
95 | select PCIEPORTBUS | 110 | select PCIEPORTBUS |
96 | select PCIE_DW | 111 | select PCIE_DW |
97 | help | 112 | help |
@@ -100,6 +115,7 @@ config PCIE_SPEAR13XX | |||
100 | config PCI_KEYSTONE | 115 | config PCI_KEYSTONE |
101 | bool "TI Keystone PCIe controller" | 116 | bool "TI Keystone PCIe controller" |
102 | depends on ARCH_KEYSTONE | 117 | depends on ARCH_KEYSTONE |
118 | depends on PCI_MSI_IRQ_DOMAIN | ||
103 | select PCIE_DW | 119 | select PCIE_DW |
104 | select PCIEPORTBUS | 120 | select PCIEPORTBUS |
105 | help | 121 | help |
@@ -120,7 +136,6 @@ config PCI_XGENE | |||
120 | depends on ARCH_XGENE | 136 | depends on ARCH_XGENE |
121 | depends on OF | 137 | depends on OF |
122 | select PCIEPORTBUS | 138 | select PCIEPORTBUS |
123 | select PCI_MSI_IRQ_DOMAIN if PCI_MSI | ||
124 | help | 139 | help |
125 | Say Y here if you want internal PCI support on APM X-Gene SoC. | 140 | Say Y here if you want internal PCI support on APM X-Gene SoC. |
126 | There are 5 internal PCIe ports available. Each port is GEN3 capable | 141 | There are 5 internal PCIe ports available. Each port is GEN3 capable |
@@ -128,7 +143,8 @@ config PCI_XGENE | |||
128 | 143 | ||
129 | config PCI_XGENE_MSI | 144 | config PCI_XGENE_MSI |
130 | bool "X-Gene v1 PCIe MSI feature" | 145 | bool "X-Gene v1 PCIe MSI feature" |
131 | depends on PCI_XGENE && PCI_MSI | 146 | depends on PCI_XGENE |
147 | depends on PCI_MSI_IRQ_DOMAIN | ||
132 | default y | 148 | default y |
133 | help | 149 | help |
134 | Say Y here if you want PCIe MSI support for the APM X-Gene v1 SoC. | 150 | Say Y here if you want PCIe MSI support for the APM X-Gene v1 SoC. |
@@ -137,6 +153,7 @@ config PCI_XGENE_MSI | |||
137 | config PCI_LAYERSCAPE | 153 | config PCI_LAYERSCAPE |
138 | bool "Freescale Layerscape PCIe controller" | 154 | bool "Freescale Layerscape PCIe controller" |
139 | depends on OF && (ARM || ARCH_LAYERSCAPE) | 155 | depends on OF && (ARM || ARCH_LAYERSCAPE) |
156 | depends on PCI_MSI_IRQ_DOMAIN | ||
140 | select PCIE_DW | 157 | select PCIE_DW |
141 | select MFD_SYSCON | 158 | select MFD_SYSCON |
142 | help | 159 | help |
@@ -177,8 +194,7 @@ config PCIE_IPROC_BCMA | |||
177 | config PCIE_IPROC_MSI | 194 | config PCIE_IPROC_MSI |
178 | bool "Broadcom iProc PCIe MSI support" | 195 | bool "Broadcom iProc PCIe MSI support" |
179 | depends on PCIE_IPROC_PLATFORM || PCIE_IPROC_BCMA | 196 | depends on PCIE_IPROC_PLATFORM || PCIE_IPROC_BCMA |
180 | depends on PCI_MSI | 197 | depends on PCI_MSI_IRQ_DOMAIN |
181 | select PCI_MSI_IRQ_DOMAIN | ||
182 | default ARCH_BCM_IPROC | 198 | default ARCH_BCM_IPROC |
183 | help | 199 | help |
184 | Say Y here if you want to enable MSI support for Broadcom's iProc | 200 | Say Y here if you want to enable MSI support for Broadcom's iProc |
@@ -195,8 +211,8 @@ config PCIE_ALTERA | |||
195 | 211 | ||
196 | config PCIE_ALTERA_MSI | 212 | config PCIE_ALTERA_MSI |
197 | bool "Altera PCIe MSI feature" | 213 | bool "Altera PCIe MSI feature" |
198 | depends on PCIE_ALTERA && PCI_MSI | 214 | depends on PCIE_ALTERA |
199 | select PCI_MSI_IRQ_DOMAIN | 215 | depends on PCI_MSI_IRQ_DOMAIN |
200 | help | 216 | help |
201 | Say Y here if you want PCIe MSI support for the Altera FPGA. | 217 | Say Y here if you want PCIe MSI support for the Altera FPGA. |
202 | This MSI driver supports Altera MSI to GIC controller IP. | 218 | This MSI driver supports Altera MSI to GIC controller IP. |
@@ -204,6 +220,7 @@ config PCIE_ALTERA_MSI | |||
204 | config PCI_HISI | 220 | config PCI_HISI |
205 | depends on OF && ARM64 | 221 | depends on OF && ARM64 |
206 | bool "HiSilicon Hip05 and Hip06 SoCs PCIe controllers" | 222 | bool "HiSilicon Hip05 and Hip06 SoCs PCIe controllers" |
223 | depends on PCI_MSI_IRQ_DOMAIN | ||
207 | select PCIEPORTBUS | 224 | select PCIEPORTBUS |
208 | select PCIE_DW | 225 | select PCIE_DW |
209 | help | 226 | help |
@@ -213,6 +230,7 @@ config PCI_HISI | |||
213 | config PCIE_QCOM | 230 | config PCIE_QCOM |
214 | bool "Qualcomm PCIe controller" | 231 | bool "Qualcomm PCIe controller" |
215 | depends on ARCH_QCOM && OF | 232 | depends on ARCH_QCOM && OF |
233 | depends on PCI_MSI_IRQ_DOMAIN | ||
216 | select PCIE_DW | 234 | select PCIE_DW |
217 | select PCIEPORTBUS | 235 | select PCIEPORTBUS |
218 | help | 236 | help |
@@ -237,6 +255,7 @@ config PCI_HOST_THUNDER_ECAM | |||
237 | config PCIE_ARMADA_8K | 255 | config PCIE_ARMADA_8K |
238 | bool "Marvell Armada-8K PCIe controller" | 256 | bool "Marvell Armada-8K PCIe controller" |
239 | depends on ARCH_MVEBU | 257 | depends on ARCH_MVEBU |
258 | depends on PCI_MSI_IRQ_DOMAIN | ||
240 | select PCIE_DW | 259 | select PCIE_DW |
241 | select PCIEPORTBUS | 260 | select PCIEPORTBUS |
242 | help | 261 | help |
@@ -245,4 +264,14 @@ config PCIE_ARMADA_8K | |||
245 | Designware hardware and therefore the driver re-uses the | 264 | Designware hardware and therefore the driver re-uses the |
246 | Designware core functions to implement the driver. | 265 | Designware core functions to implement the driver. |
247 | 266 | ||
267 | config PCIE_ARTPEC6 | ||
268 | bool "Axis ARTPEC-6 PCIe controller" | ||
269 | depends on MACH_ARTPEC6 | ||
270 | depends on PCI_MSI_IRQ_DOMAIN | ||
271 | select PCIE_DW | ||
272 | select PCIEPORTBUS | ||
273 | help | ||
274 | Say Y here to enable PCIe controller support on Axis ARTPEC-6 | ||
275 | SoCs. This PCIe controller uses the DesignWare core. | ||
276 | |||
248 | endmenu | 277 | endmenu |
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 9c8698e89e96..88434101e4c4 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile | |||
@@ -5,6 +5,7 @@ obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o | |||
5 | obj-$(CONFIG_PCI_IMX6) += pci-imx6.o | 5 | obj-$(CONFIG_PCI_IMX6) += pci-imx6.o |
6 | obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o | 6 | obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o |
7 | obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o | 7 | obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o |
8 | obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o | ||
8 | obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o | 9 | obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o |
9 | obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o | 10 | obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o |
10 | obj-$(CONFIG_PCIE_RCAR) += pcie-rcar.o | 11 | obj-$(CONFIG_PCIE_RCAR) += pcie-rcar.o |
@@ -29,3 +30,4 @@ obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o | |||
29 | obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o | 30 | obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o |
30 | obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o | 31 | obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o |
31 | obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o | 32 | obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o |
33 | obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o | ||
diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c new file mode 100644 index 000000000000..ef9893fa3176 --- /dev/null +++ b/drivers/pci/host/pci-aardvark.c | |||
@@ -0,0 +1,1001 @@ | |||
1 | /* | ||
2 | * Driver for the Aardvark PCIe controller, used on Marvell Armada | ||
3 | * 3700. | ||
4 | * | ||
5 | * Copyright (C) 2016 Marvell | ||
6 | * | ||
7 | * Author: Hezi Shahmoon <hezi.shahmoon@marvell.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/delay.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/irqdomain.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/pci.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/of_address.h> | ||
23 | #include <linux/of_pci.h> | ||
24 | |||
25 | /* PCIe core registers */ | ||
26 | #define PCIE_CORE_CMD_STATUS_REG 0x4 | ||
27 | #define PCIE_CORE_CMD_IO_ACCESS_EN BIT(0) | ||
28 | #define PCIE_CORE_CMD_MEM_ACCESS_EN BIT(1) | ||
29 | #define PCIE_CORE_CMD_MEM_IO_REQ_EN BIT(2) | ||
30 | #define PCIE_CORE_DEV_CTRL_STATS_REG 0xc8 | ||
31 | #define PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE (0 << 4) | ||
32 | #define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5 | ||
33 | #define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11) | ||
34 | #define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT 12 | ||
35 | #define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0 | ||
36 | #define PCIE_CORE_LINK_L0S_ENTRY BIT(0) | ||
37 | #define PCIE_CORE_LINK_TRAINING BIT(5) | ||
38 | #define PCIE_CORE_LINK_WIDTH_SHIFT 20 | ||
39 | #define PCIE_CORE_ERR_CAPCTL_REG 0x118 | ||
40 | #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX BIT(5) | ||
41 | #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN BIT(6) | ||
42 | #define PCIE_CORE_ERR_CAPCTL_ECRC_CHCK BIT(7) | ||
43 | #define PCIE_CORE_ERR_CAPCTL_ECRC_CHCK_RCV BIT(8) | ||
44 | |||
45 | /* PIO registers base address and register offsets */ | ||
46 | #define PIO_BASE_ADDR 0x4000 | ||
47 | #define PIO_CTRL (PIO_BASE_ADDR + 0x0) | ||
48 | #define PIO_CTRL_TYPE_MASK GENMASK(3, 0) | ||
49 | #define PIO_CTRL_ADDR_WIN_DISABLE BIT(24) | ||
50 | #define PIO_STAT (PIO_BASE_ADDR + 0x4) | ||
51 | #define PIO_COMPLETION_STATUS_SHIFT 7 | ||
52 | #define PIO_COMPLETION_STATUS_MASK GENMASK(9, 7) | ||
53 | #define PIO_COMPLETION_STATUS_OK 0 | ||
54 | #define PIO_COMPLETION_STATUS_UR 1 | ||
55 | #define PIO_COMPLETION_STATUS_CRS 2 | ||
56 | #define PIO_COMPLETION_STATUS_CA 4 | ||
57 | #define PIO_NON_POSTED_REQ BIT(0) | ||
58 | #define PIO_ADDR_LS (PIO_BASE_ADDR + 0x8) | ||
59 | #define PIO_ADDR_MS (PIO_BASE_ADDR + 0xc) | ||
60 | #define PIO_WR_DATA (PIO_BASE_ADDR + 0x10) | ||
61 | #define PIO_WR_DATA_STRB (PIO_BASE_ADDR + 0x14) | ||
62 | #define PIO_RD_DATA (PIO_BASE_ADDR + 0x18) | ||
63 | #define PIO_START (PIO_BASE_ADDR + 0x1c) | ||
64 | #define PIO_ISR (PIO_BASE_ADDR + 0x20) | ||
65 | #define PIO_ISRM (PIO_BASE_ADDR + 0x24) | ||
66 | |||
67 | /* Aardvark Control registers */ | ||
68 | #define CONTROL_BASE_ADDR 0x4800 | ||
69 | #define PCIE_CORE_CTRL0_REG (CONTROL_BASE_ADDR + 0x0) | ||
70 | #define PCIE_GEN_SEL_MSK 0x3 | ||
71 | #define PCIE_GEN_SEL_SHIFT 0x0 | ||
72 | #define SPEED_GEN_1 0 | ||
73 | #define SPEED_GEN_2 1 | ||
74 | #define SPEED_GEN_3 2 | ||
75 | #define IS_RC_MSK 1 | ||
76 | #define IS_RC_SHIFT 2 | ||
77 | #define LANE_CNT_MSK 0x18 | ||
78 | #define LANE_CNT_SHIFT 0x3 | ||
79 | #define LANE_COUNT_1 (0 << LANE_CNT_SHIFT) | ||
80 | #define LANE_COUNT_2 (1 << LANE_CNT_SHIFT) | ||
81 | #define LANE_COUNT_4 (2 << LANE_CNT_SHIFT) | ||
82 | #define LANE_COUNT_8 (3 << LANE_CNT_SHIFT) | ||
83 | #define LINK_TRAINING_EN BIT(6) | ||
84 | #define LEGACY_INTA BIT(28) | ||
85 | #define LEGACY_INTB BIT(29) | ||
86 | #define LEGACY_INTC BIT(30) | ||
87 | #define LEGACY_INTD BIT(31) | ||
88 | #define PCIE_CORE_CTRL1_REG (CONTROL_BASE_ADDR + 0x4) | ||
89 | #define HOT_RESET_GEN BIT(0) | ||
90 | #define PCIE_CORE_CTRL2_REG (CONTROL_BASE_ADDR + 0x8) | ||
91 | #define PCIE_CORE_CTRL2_RESERVED 0x7 | ||
92 | #define PCIE_CORE_CTRL2_TD_ENABLE BIT(4) | ||
93 | #define PCIE_CORE_CTRL2_STRICT_ORDER_ENABLE BIT(5) | ||
94 | #define PCIE_CORE_CTRL2_OB_WIN_ENABLE BIT(6) | ||
95 | #define PCIE_CORE_CTRL2_MSI_ENABLE BIT(10) | ||
96 | #define PCIE_ISR0_REG (CONTROL_BASE_ADDR + 0x40) | ||
97 | #define PCIE_ISR0_MASK_REG (CONTROL_BASE_ADDR + 0x44) | ||
98 | #define PCIE_ISR0_MSI_INT_PENDING BIT(24) | ||
99 | #define PCIE_ISR0_INTX_ASSERT(val) BIT(16 + (val)) | ||
100 | #define PCIE_ISR0_INTX_DEASSERT(val) BIT(20 + (val)) | ||
101 | #define PCIE_ISR0_ALL_MASK GENMASK(26, 0) | ||
102 | #define PCIE_ISR1_REG (CONTROL_BASE_ADDR + 0x48) | ||
103 | #define PCIE_ISR1_MASK_REG (CONTROL_BASE_ADDR + 0x4C) | ||
104 | #define PCIE_ISR1_POWER_STATE_CHANGE BIT(4) | ||
105 | #define PCIE_ISR1_FLUSH BIT(5) | ||
106 | #define PCIE_ISR1_ALL_MASK GENMASK(5, 4) | ||
107 | #define PCIE_MSI_ADDR_LOW_REG (CONTROL_BASE_ADDR + 0x50) | ||
108 | #define PCIE_MSI_ADDR_HIGH_REG (CONTROL_BASE_ADDR + 0x54) | ||
109 | #define PCIE_MSI_STATUS_REG (CONTROL_BASE_ADDR + 0x58) | ||
110 | #define PCIE_MSI_MASK_REG (CONTROL_BASE_ADDR + 0x5C) | ||
111 | #define PCIE_MSI_PAYLOAD_REG (CONTROL_BASE_ADDR + 0x9C) | ||
112 | |||
113 | /* PCIe window configuration */ | ||
114 | #define OB_WIN_BASE_ADDR 0x4c00 | ||
115 | #define OB_WIN_BLOCK_SIZE 0x20 | ||
116 | #define OB_WIN_REG_ADDR(win, offset) (OB_WIN_BASE_ADDR + \ | ||
117 | OB_WIN_BLOCK_SIZE * (win) + \ | ||
118 | (offset)) | ||
119 | #define OB_WIN_MATCH_LS(win) OB_WIN_REG_ADDR(win, 0x00) | ||
120 | #define OB_WIN_MATCH_MS(win) OB_WIN_REG_ADDR(win, 0x04) | ||
121 | #define OB_WIN_REMAP_LS(win) OB_WIN_REG_ADDR(win, 0x08) | ||
122 | #define OB_WIN_REMAP_MS(win) OB_WIN_REG_ADDR(win, 0x0c) | ||
123 | #define OB_WIN_MASK_LS(win) OB_WIN_REG_ADDR(win, 0x10) | ||
124 | #define OB_WIN_MASK_MS(win) OB_WIN_REG_ADDR(win, 0x14) | ||
125 | #define OB_WIN_ACTIONS(win) OB_WIN_REG_ADDR(win, 0x18) | ||
126 | |||
127 | /* PCIe window types */ | ||
128 | #define OB_PCIE_MEM 0x0 | ||
129 | #define OB_PCIE_IO 0x4 | ||
130 | |||
131 | /* LMI registers base address and register offsets */ | ||
132 | #define LMI_BASE_ADDR 0x6000 | ||
133 | #define CFG_REG (LMI_BASE_ADDR + 0x0) | ||
134 | #define LTSSM_SHIFT 24 | ||
135 | #define LTSSM_MASK 0x3f | ||
136 | #define LTSSM_L0 0x10 | ||
137 | #define RC_BAR_CONFIG 0x300 | ||
138 | |||
139 | /* PCIe core controller registers */ | ||
140 | #define CTRL_CORE_BASE_ADDR 0x18000 | ||
141 | #define CTRL_CONFIG_REG (CTRL_CORE_BASE_ADDR + 0x0) | ||
142 | #define CTRL_MODE_SHIFT 0x0 | ||
143 | #define CTRL_MODE_MASK 0x1 | ||
144 | #define PCIE_CORE_MODE_DIRECT 0x0 | ||
145 | #define PCIE_CORE_MODE_COMMAND 0x1 | ||
146 | |||
147 | /* PCIe Central Interrupts Registers */ | ||
148 | #define CENTRAL_INT_BASE_ADDR 0x1b000 | ||
149 | #define HOST_CTRL_INT_STATUS_REG (CENTRAL_INT_BASE_ADDR + 0x0) | ||
150 | #define HOST_CTRL_INT_MASK_REG (CENTRAL_INT_BASE_ADDR + 0x4) | ||
151 | #define PCIE_IRQ_CMDQ_INT BIT(0) | ||
152 | #define PCIE_IRQ_MSI_STATUS_INT BIT(1) | ||
153 | #define PCIE_IRQ_CMD_SENT_DONE BIT(3) | ||
154 | #define PCIE_IRQ_DMA_INT BIT(4) | ||
155 | #define PCIE_IRQ_IB_DXFERDONE BIT(5) | ||
156 | #define PCIE_IRQ_OB_DXFERDONE BIT(6) | ||
157 | #define PCIE_IRQ_OB_RXFERDONE BIT(7) | ||
158 | #define PCIE_IRQ_COMPQ_INT BIT(12) | ||
159 | #define PCIE_IRQ_DIR_RD_DDR_DET BIT(13) | ||
160 | #define PCIE_IRQ_DIR_WR_DDR_DET BIT(14) | ||
161 | #define PCIE_IRQ_CORE_INT BIT(16) | ||
162 | #define PCIE_IRQ_CORE_INT_PIO BIT(17) | ||
163 | #define PCIE_IRQ_DPMU_INT BIT(18) | ||
164 | #define PCIE_IRQ_PCIE_MIS_INT BIT(19) | ||
165 | #define PCIE_IRQ_MSI_INT1_DET BIT(20) | ||
166 | #define PCIE_IRQ_MSI_INT2_DET BIT(21) | ||
167 | #define PCIE_IRQ_RC_DBELL_DET BIT(22) | ||
168 | #define PCIE_IRQ_EP_STATUS BIT(23) | ||
169 | #define PCIE_IRQ_ALL_MASK 0xfff0fb | ||
170 | #define PCIE_IRQ_ENABLE_INTS_MASK PCIE_IRQ_CORE_INT | ||
171 | |||
172 | /* Transaction types */ | ||
173 | #define PCIE_CONFIG_RD_TYPE0 0x8 | ||
174 | #define PCIE_CONFIG_RD_TYPE1 0x9 | ||
175 | #define PCIE_CONFIG_WR_TYPE0 0xa | ||
176 | #define PCIE_CONFIG_WR_TYPE1 0xb | ||
177 | |||
178 | /* PCI_BDF shifts 8bit, so we need extra 4bit shift */ | ||
179 | #define PCIE_BDF(dev) (dev << 4) | ||
180 | #define PCIE_CONF_BUS(bus) (((bus) & 0xff) << 20) | ||
181 | #define PCIE_CONF_DEV(dev) (((dev) & 0x1f) << 15) | ||
182 | #define PCIE_CONF_FUNC(fun) (((fun) & 0x7) << 12) | ||
183 | #define PCIE_CONF_REG(reg) ((reg) & 0xffc) | ||
184 | #define PCIE_CONF_ADDR(bus, devfn, where) \ | ||
185 | (PCIE_CONF_BUS(bus) | PCIE_CONF_DEV(PCI_SLOT(devfn)) | \ | ||
186 | PCIE_CONF_FUNC(PCI_FUNC(devfn)) | PCIE_CONF_REG(where)) | ||
187 | |||
188 | #define PIO_TIMEOUT_MS 1 | ||
189 | |||
190 | #define LINK_WAIT_MAX_RETRIES 10 | ||
191 | #define LINK_WAIT_USLEEP_MIN 90000 | ||
192 | #define LINK_WAIT_USLEEP_MAX 100000 | ||
193 | |||
194 | #define LEGACY_IRQ_NUM 4 | ||
195 | #define MSI_IRQ_NUM 32 | ||
196 | |||
197 | struct advk_pcie { | ||
198 | struct platform_device *pdev; | ||
199 | void __iomem *base; | ||
200 | struct list_head resources; | ||
201 | struct irq_domain *irq_domain; | ||
202 | struct irq_chip irq_chip; | ||
203 | struct msi_controller msi; | ||
204 | struct irq_domain *msi_domain; | ||
205 | struct irq_chip msi_irq_chip; | ||
206 | DECLARE_BITMAP(msi_irq_in_use, MSI_IRQ_NUM); | ||
207 | struct mutex msi_used_lock; | ||
208 | u16 msi_msg; | ||
209 | int root_bus_nr; | ||
210 | }; | ||
211 | |||
212 | static inline void advk_writel(struct advk_pcie *pcie, u32 val, u64 reg) | ||
213 | { | ||
214 | writel(val, pcie->base + reg); | ||
215 | } | ||
216 | |||
217 | static inline u32 advk_readl(struct advk_pcie *pcie, u64 reg) | ||
218 | { | ||
219 | return readl(pcie->base + reg); | ||
220 | } | ||
221 | |||
222 | static int advk_pcie_link_up(struct advk_pcie *pcie) | ||
223 | { | ||
224 | u32 val, ltssm_state; | ||
225 | |||
226 | val = advk_readl(pcie, CFG_REG); | ||
227 | ltssm_state = (val >> LTSSM_SHIFT) & LTSSM_MASK; | ||
228 | return ltssm_state >= LTSSM_L0; | ||
229 | } | ||
230 | |||
231 | static int advk_pcie_wait_for_link(struct advk_pcie *pcie) | ||
232 | { | ||
233 | int retries; | ||
234 | |||
235 | /* check if the link is up or not */ | ||
236 | for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) { | ||
237 | if (advk_pcie_link_up(pcie)) { | ||
238 | dev_info(&pcie->pdev->dev, "link up\n"); | ||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX); | ||
243 | } | ||
244 | |||
245 | dev_err(&pcie->pdev->dev, "link never came up\n"); | ||
246 | |||
247 | return -ETIMEDOUT; | ||
248 | } | ||
249 | |||
250 | /* | ||
251 | * Set PCIe address window register which could be used for memory | ||
252 | * mapping. | ||
253 | */ | ||
254 | static void advk_pcie_set_ob_win(struct advk_pcie *pcie, | ||
255 | u32 win_num, u32 match_ms, | ||
256 | u32 match_ls, u32 mask_ms, | ||
257 | u32 mask_ls, u32 remap_ms, | ||
258 | u32 remap_ls, u32 action) | ||
259 | { | ||
260 | advk_writel(pcie, match_ls, OB_WIN_MATCH_LS(win_num)); | ||
261 | advk_writel(pcie, match_ms, OB_WIN_MATCH_MS(win_num)); | ||
262 | advk_writel(pcie, mask_ms, OB_WIN_MASK_MS(win_num)); | ||
263 | advk_writel(pcie, mask_ls, OB_WIN_MASK_LS(win_num)); | ||
264 | advk_writel(pcie, remap_ms, OB_WIN_REMAP_MS(win_num)); | ||
265 | advk_writel(pcie, remap_ls, OB_WIN_REMAP_LS(win_num)); | ||
266 | advk_writel(pcie, action, OB_WIN_ACTIONS(win_num)); | ||
267 | advk_writel(pcie, match_ls | BIT(0), OB_WIN_MATCH_LS(win_num)); | ||
268 | } | ||
269 | |||
270 | static void advk_pcie_setup_hw(struct advk_pcie *pcie) | ||
271 | { | ||
272 | u32 reg; | ||
273 | int i; | ||
274 | |||
275 | /* Point PCIe unit MBUS decode windows to DRAM space */ | ||
276 | for (i = 0; i < 8; i++) | ||
277 | advk_pcie_set_ob_win(pcie, i, 0, 0, 0, 0, 0, 0, 0); | ||
278 | |||
279 | /* Set to Direct mode */ | ||
280 | reg = advk_readl(pcie, CTRL_CONFIG_REG); | ||
281 | reg &= ~(CTRL_MODE_MASK << CTRL_MODE_SHIFT); | ||
282 | reg |= ((PCIE_CORE_MODE_DIRECT & CTRL_MODE_MASK) << CTRL_MODE_SHIFT); | ||
283 | advk_writel(pcie, reg, CTRL_CONFIG_REG); | ||
284 | |||
285 | /* Set PCI global control register to RC mode */ | ||
286 | reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); | ||
287 | reg |= (IS_RC_MSK << IS_RC_SHIFT); | ||
288 | advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); | ||
289 | |||
290 | /* Set Advanced Error Capabilities and Control PF0 register */ | ||
291 | reg = PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX | | ||
292 | PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN | | ||
293 | PCIE_CORE_ERR_CAPCTL_ECRC_CHCK | | ||
294 | PCIE_CORE_ERR_CAPCTL_ECRC_CHCK_RCV; | ||
295 | advk_writel(pcie, reg, PCIE_CORE_ERR_CAPCTL_REG); | ||
296 | |||
297 | /* Set PCIe Device Control and Status 1 PF0 register */ | ||
298 | reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE | | ||
299 | (7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) | | ||
300 | PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE | | ||
301 | PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT; | ||
302 | advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG); | ||
303 | |||
304 | /* Program PCIe Control 2 to disable strict ordering */ | ||
305 | reg = PCIE_CORE_CTRL2_RESERVED | | ||
306 | PCIE_CORE_CTRL2_TD_ENABLE; | ||
307 | advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); | ||
308 | |||
309 | /* Set GEN2 */ | ||
310 | reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); | ||
311 | reg &= ~PCIE_GEN_SEL_MSK; | ||
312 | reg |= SPEED_GEN_2; | ||
313 | advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); | ||
314 | |||
315 | /* Set lane X1 */ | ||
316 | reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); | ||
317 | reg &= ~LANE_CNT_MSK; | ||
318 | reg |= LANE_COUNT_1; | ||
319 | advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); | ||
320 | |||
321 | /* Enable link training */ | ||
322 | reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); | ||
323 | reg |= LINK_TRAINING_EN; | ||
324 | advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); | ||
325 | |||
326 | /* Enable MSI */ | ||
327 | reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); | ||
328 | reg |= PCIE_CORE_CTRL2_MSI_ENABLE; | ||
329 | advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); | ||
330 | |||
331 | /* Clear all interrupts */ | ||
332 | advk_writel(pcie, PCIE_ISR0_ALL_MASK, PCIE_ISR0_REG); | ||
333 | advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG); | ||
334 | advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG); | ||
335 | |||
336 | /* Disable All ISR0/1 Sources */ | ||
337 | reg = PCIE_ISR0_ALL_MASK; | ||
338 | reg &= ~PCIE_ISR0_MSI_INT_PENDING; | ||
339 | advk_writel(pcie, reg, PCIE_ISR0_MASK_REG); | ||
340 | |||
341 | advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_MASK_REG); | ||
342 | |||
343 | /* Unmask all MSI's */ | ||
344 | advk_writel(pcie, 0, PCIE_MSI_MASK_REG); | ||
345 | |||
346 | /* Enable summary interrupt for GIC SPI source */ | ||
347 | reg = PCIE_IRQ_ALL_MASK & (~PCIE_IRQ_ENABLE_INTS_MASK); | ||
348 | advk_writel(pcie, reg, HOST_CTRL_INT_MASK_REG); | ||
349 | |||
350 | reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); | ||
351 | reg |= PCIE_CORE_CTRL2_OB_WIN_ENABLE; | ||
352 | advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); | ||
353 | |||
354 | /* Bypass the address window mapping for PIO */ | ||
355 | reg = advk_readl(pcie, PIO_CTRL); | ||
356 | reg |= PIO_CTRL_ADDR_WIN_DISABLE; | ||
357 | advk_writel(pcie, reg, PIO_CTRL); | ||
358 | |||
359 | /* Start link training */ | ||
360 | reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); | ||
361 | reg |= PCIE_CORE_LINK_TRAINING; | ||
362 | advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); | ||
363 | |||
364 | advk_pcie_wait_for_link(pcie); | ||
365 | |||
366 | reg = PCIE_CORE_LINK_L0S_ENTRY | | ||
367 | (1 << PCIE_CORE_LINK_WIDTH_SHIFT); | ||
368 | advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); | ||
369 | |||
370 | reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); | ||
371 | reg |= PCIE_CORE_CMD_MEM_ACCESS_EN | | ||
372 | PCIE_CORE_CMD_IO_ACCESS_EN | | ||
373 | PCIE_CORE_CMD_MEM_IO_REQ_EN; | ||
374 | advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG); | ||
375 | } | ||
376 | |||
377 | static void advk_pcie_check_pio_status(struct advk_pcie *pcie) | ||
378 | { | ||
379 | u32 reg; | ||
380 | unsigned int status; | ||
381 | char *strcomp_status, *str_posted; | ||
382 | |||
383 | reg = advk_readl(pcie, PIO_STAT); | ||
384 | status = (reg & PIO_COMPLETION_STATUS_MASK) >> | ||
385 | PIO_COMPLETION_STATUS_SHIFT; | ||
386 | |||
387 | if (!status) | ||
388 | return; | ||
389 | |||
390 | switch (status) { | ||
391 | case PIO_COMPLETION_STATUS_UR: | ||
392 | strcomp_status = "UR"; | ||
393 | break; | ||
394 | case PIO_COMPLETION_STATUS_CRS: | ||
395 | strcomp_status = "CRS"; | ||
396 | break; | ||
397 | case PIO_COMPLETION_STATUS_CA: | ||
398 | strcomp_status = "CA"; | ||
399 | break; | ||
400 | default: | ||
401 | strcomp_status = "Unknown"; | ||
402 | break; | ||
403 | } | ||
404 | |||
405 | if (reg & PIO_NON_POSTED_REQ) | ||
406 | str_posted = "Non-posted"; | ||
407 | else | ||
408 | str_posted = "Posted"; | ||
409 | |||
410 | dev_err(&pcie->pdev->dev, "%s PIO Response Status: %s, %#x @ %#x\n", | ||
411 | str_posted, strcomp_status, reg, advk_readl(pcie, PIO_ADDR_LS)); | ||
412 | } | ||
413 | |||
414 | static int advk_pcie_wait_pio(struct advk_pcie *pcie) | ||
415 | { | ||
416 | unsigned long timeout; | ||
417 | |||
418 | timeout = jiffies + msecs_to_jiffies(PIO_TIMEOUT_MS); | ||
419 | |||
420 | while (time_before(jiffies, timeout)) { | ||
421 | u32 start, isr; | ||
422 | |||
423 | start = advk_readl(pcie, PIO_START); | ||
424 | isr = advk_readl(pcie, PIO_ISR); | ||
425 | if (!start && isr) | ||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | dev_err(&pcie->pdev->dev, "config read/write timed out\n"); | ||
430 | return -ETIMEDOUT; | ||
431 | } | ||
432 | |||
433 | static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, | ||
434 | int where, int size, u32 *val) | ||
435 | { | ||
436 | struct advk_pcie *pcie = bus->sysdata; | ||
437 | u32 reg; | ||
438 | int ret; | ||
439 | |||
440 | if (PCI_SLOT(devfn) != 0) { | ||
441 | *val = 0xffffffff; | ||
442 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
443 | } | ||
444 | |||
445 | /* Start PIO */ | ||
446 | advk_writel(pcie, 0, PIO_START); | ||
447 | advk_writel(pcie, 1, PIO_ISR); | ||
448 | |||
449 | /* Program the control register */ | ||
450 | reg = advk_readl(pcie, PIO_CTRL); | ||
451 | reg &= ~PIO_CTRL_TYPE_MASK; | ||
452 | if (bus->number == pcie->root_bus_nr) | ||
453 | reg |= PCIE_CONFIG_RD_TYPE0; | ||
454 | else | ||
455 | reg |= PCIE_CONFIG_RD_TYPE1; | ||
456 | advk_writel(pcie, reg, PIO_CTRL); | ||
457 | |||
458 | /* Program the address registers */ | ||
459 | reg = PCIE_BDF(devfn) | PCIE_CONF_REG(where); | ||
460 | advk_writel(pcie, reg, PIO_ADDR_LS); | ||
461 | advk_writel(pcie, 0, PIO_ADDR_MS); | ||
462 | |||
463 | /* Program the data strobe */ | ||
464 | advk_writel(pcie, 0xf, PIO_WR_DATA_STRB); | ||
465 | |||
466 | /* Start the transfer */ | ||
467 | advk_writel(pcie, 1, PIO_START); | ||
468 | |||
469 | ret = advk_pcie_wait_pio(pcie); | ||
470 | if (ret < 0) | ||
471 | return PCIBIOS_SET_FAILED; | ||
472 | |||
473 | advk_pcie_check_pio_status(pcie); | ||
474 | |||
475 | /* Get the read result */ | ||
476 | *val = advk_readl(pcie, PIO_RD_DATA); | ||
477 | if (size == 1) | ||
478 | *val = (*val >> (8 * (where & 3))) & 0xff; | ||
479 | else if (size == 2) | ||
480 | *val = (*val >> (8 * (where & 3))) & 0xffff; | ||
481 | |||
482 | return PCIBIOS_SUCCESSFUL; | ||
483 | } | ||
484 | |||
485 | static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn, | ||
486 | int where, int size, u32 val) | ||
487 | { | ||
488 | struct advk_pcie *pcie = bus->sysdata; | ||
489 | u32 reg; | ||
490 | u32 data_strobe = 0x0; | ||
491 | int offset; | ||
492 | int ret; | ||
493 | |||
494 | if (PCI_SLOT(devfn) != 0) | ||
495 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
496 | |||
497 | if (where % size) | ||
498 | return PCIBIOS_SET_FAILED; | ||
499 | |||
500 | /* Start PIO */ | ||
501 | advk_writel(pcie, 0, PIO_START); | ||
502 | advk_writel(pcie, 1, PIO_ISR); | ||
503 | |||
504 | /* Program the control register */ | ||
505 | reg = advk_readl(pcie, PIO_CTRL); | ||
506 | reg &= ~PIO_CTRL_TYPE_MASK; | ||
507 | if (bus->number == pcie->root_bus_nr) | ||
508 | reg |= PCIE_CONFIG_WR_TYPE0; | ||
509 | else | ||
510 | reg |= PCIE_CONFIG_WR_TYPE1; | ||
511 | advk_writel(pcie, reg, PIO_CTRL); | ||
512 | |||
513 | /* Program the address registers */ | ||
514 | reg = PCIE_CONF_ADDR(bus->number, devfn, where); | ||
515 | advk_writel(pcie, reg, PIO_ADDR_LS); | ||
516 | advk_writel(pcie, 0, PIO_ADDR_MS); | ||
517 | |||
518 | /* Calculate the write strobe */ | ||
519 | offset = where & 0x3; | ||
520 | reg = val << (8 * offset); | ||
521 | data_strobe = GENMASK(size - 1, 0) << offset; | ||
522 | |||
523 | /* Program the data register */ | ||
524 | advk_writel(pcie, reg, PIO_WR_DATA); | ||
525 | |||
526 | /* Program the data strobe */ | ||
527 | advk_writel(pcie, data_strobe, PIO_WR_DATA_STRB); | ||
528 | |||
529 | /* Start the transfer */ | ||
530 | advk_writel(pcie, 1, PIO_START); | ||
531 | |||
532 | ret = advk_pcie_wait_pio(pcie); | ||
533 | if (ret < 0) | ||
534 | return PCIBIOS_SET_FAILED; | ||
535 | |||
536 | advk_pcie_check_pio_status(pcie); | ||
537 | |||
538 | return PCIBIOS_SUCCESSFUL; | ||
539 | } | ||
540 | |||
541 | static struct pci_ops advk_pcie_ops = { | ||
542 | .read = advk_pcie_rd_conf, | ||
543 | .write = advk_pcie_wr_conf, | ||
544 | }; | ||
545 | |||
546 | static int advk_pcie_alloc_msi(struct advk_pcie *pcie) | ||
547 | { | ||
548 | int hwirq; | ||
549 | |||
550 | mutex_lock(&pcie->msi_used_lock); | ||
551 | hwirq = find_first_zero_bit(pcie->msi_irq_in_use, MSI_IRQ_NUM); | ||
552 | if (hwirq >= MSI_IRQ_NUM) | ||
553 | hwirq = -ENOSPC; | ||
554 | else | ||
555 | set_bit(hwirq, pcie->msi_irq_in_use); | ||
556 | mutex_unlock(&pcie->msi_used_lock); | ||
557 | |||
558 | return hwirq; | ||
559 | } | ||
560 | |||
561 | static void advk_pcie_free_msi(struct advk_pcie *pcie, int hwirq) | ||
562 | { | ||
563 | mutex_lock(&pcie->msi_used_lock); | ||
564 | if (!test_bit(hwirq, pcie->msi_irq_in_use)) | ||
565 | dev_err(&pcie->pdev->dev, "trying to free unused MSI#%d\n", | ||
566 | hwirq); | ||
567 | else | ||
568 | clear_bit(hwirq, pcie->msi_irq_in_use); | ||
569 | mutex_unlock(&pcie->msi_used_lock); | ||
570 | } | ||
571 | |||
572 | static int advk_pcie_setup_msi_irq(struct msi_controller *chip, | ||
573 | struct pci_dev *pdev, | ||
574 | struct msi_desc *desc) | ||
575 | { | ||
576 | struct advk_pcie *pcie = pdev->bus->sysdata; | ||
577 | struct msi_msg msg; | ||
578 | int virq, hwirq; | ||
579 | phys_addr_t msi_msg_phys; | ||
580 | |||
581 | /* We support MSI, but not MSI-X */ | ||
582 | if (desc->msi_attrib.is_msix) | ||
583 | return -EINVAL; | ||
584 | |||
585 | hwirq = advk_pcie_alloc_msi(pcie); | ||
586 | if (hwirq < 0) | ||
587 | return hwirq; | ||
588 | |||
589 | virq = irq_create_mapping(pcie->msi_domain, hwirq); | ||
590 | if (!virq) { | ||
591 | advk_pcie_free_msi(pcie, hwirq); | ||
592 | return -EINVAL; | ||
593 | } | ||
594 | |||
595 | irq_set_msi_desc(virq, desc); | ||
596 | |||
597 | msi_msg_phys = virt_to_phys(&pcie->msi_msg); | ||
598 | |||
599 | msg.address_lo = lower_32_bits(msi_msg_phys); | ||
600 | msg.address_hi = upper_32_bits(msi_msg_phys); | ||
601 | msg.data = virq; | ||
602 | |||
603 | pci_write_msi_msg(virq, &msg); | ||
604 | |||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | static void advk_pcie_teardown_msi_irq(struct msi_controller *chip, | ||
609 | unsigned int irq) | ||
610 | { | ||
611 | struct irq_data *d = irq_get_irq_data(irq); | ||
612 | struct msi_desc *msi = irq_data_get_msi_desc(d); | ||
613 | struct advk_pcie *pcie = msi_desc_to_pci_sysdata(msi); | ||
614 | unsigned long hwirq = d->hwirq; | ||
615 | |||
616 | irq_dispose_mapping(irq); | ||
617 | advk_pcie_free_msi(pcie, hwirq); | ||
618 | } | ||
619 | |||
620 | static int advk_pcie_msi_map(struct irq_domain *domain, | ||
621 | unsigned int virq, irq_hw_number_t hw) | ||
622 | { | ||
623 | struct advk_pcie *pcie = domain->host_data; | ||
624 | |||
625 | irq_set_chip_and_handler(virq, &pcie->msi_irq_chip, | ||
626 | handle_simple_irq); | ||
627 | |||
628 | return 0; | ||
629 | } | ||
630 | |||
631 | static const struct irq_domain_ops advk_pcie_msi_irq_ops = { | ||
632 | .map = advk_pcie_msi_map, | ||
633 | }; | ||
634 | |||
635 | static void advk_pcie_irq_mask(struct irq_data *d) | ||
636 | { | ||
637 | struct advk_pcie *pcie = d->domain->host_data; | ||
638 | irq_hw_number_t hwirq = irqd_to_hwirq(d); | ||
639 | u32 mask; | ||
640 | |||
641 | mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); | ||
642 | mask |= PCIE_ISR0_INTX_ASSERT(hwirq); | ||
643 | advk_writel(pcie, mask, PCIE_ISR0_MASK_REG); | ||
644 | } | ||
645 | |||
646 | static void advk_pcie_irq_unmask(struct irq_data *d) | ||
647 | { | ||
648 | struct advk_pcie *pcie = d->domain->host_data; | ||
649 | irq_hw_number_t hwirq = irqd_to_hwirq(d); | ||
650 | u32 mask; | ||
651 | |||
652 | mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); | ||
653 | mask &= ~PCIE_ISR0_INTX_ASSERT(hwirq); | ||
654 | advk_writel(pcie, mask, PCIE_ISR0_MASK_REG); | ||
655 | } | ||
656 | |||
657 | static int advk_pcie_irq_map(struct irq_domain *h, | ||
658 | unsigned int virq, irq_hw_number_t hwirq) | ||
659 | { | ||
660 | struct advk_pcie *pcie = h->host_data; | ||
661 | |||
662 | advk_pcie_irq_mask(irq_get_irq_data(virq)); | ||
663 | irq_set_status_flags(virq, IRQ_LEVEL); | ||
664 | irq_set_chip_and_handler(virq, &pcie->irq_chip, | ||
665 | handle_level_irq); | ||
666 | irq_set_chip_data(virq, pcie); | ||
667 | |||
668 | return 0; | ||
669 | } | ||
670 | |||
671 | static const struct irq_domain_ops advk_pcie_irq_domain_ops = { | ||
672 | .map = advk_pcie_irq_map, | ||
673 | .xlate = irq_domain_xlate_onecell, | ||
674 | }; | ||
675 | |||
676 | static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie) | ||
677 | { | ||
678 | struct device *dev = &pcie->pdev->dev; | ||
679 | struct device_node *node = dev->of_node; | ||
680 | struct irq_chip *msi_irq_chip; | ||
681 | struct msi_controller *msi; | ||
682 | phys_addr_t msi_msg_phys; | ||
683 | int ret; | ||
684 | |||
685 | msi_irq_chip = &pcie->msi_irq_chip; | ||
686 | |||
687 | msi_irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-msi", | ||
688 | dev_name(dev)); | ||
689 | if (!msi_irq_chip->name) | ||
690 | return -ENOMEM; | ||
691 | |||
692 | msi_irq_chip->irq_enable = pci_msi_unmask_irq; | ||
693 | msi_irq_chip->irq_disable = pci_msi_mask_irq; | ||
694 | msi_irq_chip->irq_mask = pci_msi_mask_irq; | ||
695 | msi_irq_chip->irq_unmask = pci_msi_unmask_irq; | ||
696 | |||
697 | msi = &pcie->msi; | ||
698 | |||
699 | msi->setup_irq = advk_pcie_setup_msi_irq; | ||
700 | msi->teardown_irq = advk_pcie_teardown_msi_irq; | ||
701 | msi->of_node = node; | ||
702 | |||
703 | mutex_init(&pcie->msi_used_lock); | ||
704 | |||
705 | msi_msg_phys = virt_to_phys(&pcie->msi_msg); | ||
706 | |||
707 | advk_writel(pcie, lower_32_bits(msi_msg_phys), | ||
708 | PCIE_MSI_ADDR_LOW_REG); | ||
709 | advk_writel(pcie, upper_32_bits(msi_msg_phys), | ||
710 | PCIE_MSI_ADDR_HIGH_REG); | ||
711 | |||
712 | pcie->msi_domain = | ||
713 | irq_domain_add_linear(NULL, MSI_IRQ_NUM, | ||
714 | &advk_pcie_msi_irq_ops, pcie); | ||
715 | if (!pcie->msi_domain) | ||
716 | return -ENOMEM; | ||
717 | |||
718 | ret = of_pci_msi_chip_add(msi); | ||
719 | if (ret < 0) { | ||
720 | irq_domain_remove(pcie->msi_domain); | ||
721 | return ret; | ||
722 | } | ||
723 | |||
724 | return 0; | ||
725 | } | ||
726 | |||
727 | static void advk_pcie_remove_msi_irq_domain(struct advk_pcie *pcie) | ||
728 | { | ||
729 | of_pci_msi_chip_remove(&pcie->msi); | ||
730 | irq_domain_remove(pcie->msi_domain); | ||
731 | } | ||
732 | |||
733 | static int advk_pcie_init_irq_domain(struct advk_pcie *pcie) | ||
734 | { | ||
735 | struct device *dev = &pcie->pdev->dev; | ||
736 | struct device_node *node = dev->of_node; | ||
737 | struct device_node *pcie_intc_node; | ||
738 | struct irq_chip *irq_chip; | ||
739 | |||
740 | pcie_intc_node = of_get_next_child(node, NULL); | ||
741 | if (!pcie_intc_node) { | ||
742 | dev_err(dev, "No PCIe Intc node found\n"); | ||
743 | return -ENODEV; | ||
744 | } | ||
745 | |||
746 | irq_chip = &pcie->irq_chip; | ||
747 | |||
748 | irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-irq", | ||
749 | dev_name(dev)); | ||
750 | if (!irq_chip->name) { | ||
751 | of_node_put(pcie_intc_node); | ||
752 | return -ENOMEM; | ||
753 | } | ||
754 | |||
755 | irq_chip->irq_mask = advk_pcie_irq_mask; | ||
756 | irq_chip->irq_mask_ack = advk_pcie_irq_mask; | ||
757 | irq_chip->irq_unmask = advk_pcie_irq_unmask; | ||
758 | |||
759 | pcie->irq_domain = | ||
760 | irq_domain_add_linear(pcie_intc_node, LEGACY_IRQ_NUM, | ||
761 | &advk_pcie_irq_domain_ops, pcie); | ||
762 | if (!pcie->irq_domain) { | ||
763 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); | ||
764 | of_node_put(pcie_intc_node); | ||
765 | return -ENOMEM; | ||
766 | } | ||
767 | |||
768 | return 0; | ||
769 | } | ||
770 | |||
771 | static void advk_pcie_remove_irq_domain(struct advk_pcie *pcie) | ||
772 | { | ||
773 | irq_domain_remove(pcie->irq_domain); | ||
774 | } | ||
775 | |||
776 | static void advk_pcie_handle_msi(struct advk_pcie *pcie) | ||
777 | { | ||
778 | u32 msi_val, msi_mask, msi_status, msi_idx; | ||
779 | u16 msi_data; | ||
780 | |||
781 | msi_mask = advk_readl(pcie, PCIE_MSI_MASK_REG); | ||
782 | msi_val = advk_readl(pcie, PCIE_MSI_STATUS_REG); | ||
783 | msi_status = msi_val & ~msi_mask; | ||
784 | |||
785 | for (msi_idx = 0; msi_idx < MSI_IRQ_NUM; msi_idx++) { | ||
786 | if (!(BIT(msi_idx) & msi_status)) | ||
787 | continue; | ||
788 | |||
789 | advk_writel(pcie, BIT(msi_idx), PCIE_MSI_STATUS_REG); | ||
790 | msi_data = advk_readl(pcie, PCIE_MSI_PAYLOAD_REG) & 0xFF; | ||
791 | generic_handle_irq(msi_data); | ||
792 | } | ||
793 | |||
794 | advk_writel(pcie, PCIE_ISR0_MSI_INT_PENDING, | ||
795 | PCIE_ISR0_REG); | ||
796 | } | ||
797 | |||
798 | static void advk_pcie_handle_int(struct advk_pcie *pcie) | ||
799 | { | ||
800 | u32 val, mask, status; | ||
801 | int i, virq; | ||
802 | |||
803 | val = advk_readl(pcie, PCIE_ISR0_REG); | ||
804 | mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); | ||
805 | status = val & ((~mask) & PCIE_ISR0_ALL_MASK); | ||
806 | |||
807 | if (!status) { | ||
808 | advk_writel(pcie, val, PCIE_ISR0_REG); | ||
809 | return; | ||
810 | } | ||
811 | |||
812 | /* Process MSI interrupts */ | ||
813 | if (status & PCIE_ISR0_MSI_INT_PENDING) | ||
814 | advk_pcie_handle_msi(pcie); | ||
815 | |||
816 | /* Process legacy interrupts */ | ||
817 | for (i = 0; i < LEGACY_IRQ_NUM; i++) { | ||
818 | if (!(status & PCIE_ISR0_INTX_ASSERT(i))) | ||
819 | continue; | ||
820 | |||
821 | advk_writel(pcie, PCIE_ISR0_INTX_ASSERT(i), | ||
822 | PCIE_ISR0_REG); | ||
823 | |||
824 | virq = irq_find_mapping(pcie->irq_domain, i); | ||
825 | generic_handle_irq(virq); | ||
826 | } | ||
827 | } | ||
828 | |||
829 | static irqreturn_t advk_pcie_irq_handler(int irq, void *arg) | ||
830 | { | ||
831 | struct advk_pcie *pcie = arg; | ||
832 | u32 status; | ||
833 | |||
834 | status = advk_readl(pcie, HOST_CTRL_INT_STATUS_REG); | ||
835 | if (!(status & PCIE_IRQ_CORE_INT)) | ||
836 | return IRQ_NONE; | ||
837 | |||
838 | advk_pcie_handle_int(pcie); | ||
839 | |||
840 | /* Clear interrupt */ | ||
841 | advk_writel(pcie, PCIE_IRQ_CORE_INT, HOST_CTRL_INT_STATUS_REG); | ||
842 | |||
843 | return IRQ_HANDLED; | ||
844 | } | ||
845 | |||
846 | static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie) | ||
847 | { | ||
848 | int err, res_valid = 0; | ||
849 | struct device *dev = &pcie->pdev->dev; | ||
850 | struct device_node *np = dev->of_node; | ||
851 | struct resource_entry *win; | ||
852 | resource_size_t iobase; | ||
853 | |||
854 | INIT_LIST_HEAD(&pcie->resources); | ||
855 | |||
856 | err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pcie->resources, | ||
857 | &iobase); | ||
858 | if (err) | ||
859 | return err; | ||
860 | |||
861 | err = devm_request_pci_bus_resources(dev, &pcie->resources); | ||
862 | if (err) | ||
863 | goto out_release_res; | ||
864 | |||
865 | resource_list_for_each_entry(win, &pcie->resources) { | ||
866 | struct resource *res = win->res; | ||
867 | |||
868 | switch (resource_type(res)) { | ||
869 | case IORESOURCE_IO: | ||
870 | advk_pcie_set_ob_win(pcie, 1, | ||
871 | upper_32_bits(res->start), | ||
872 | lower_32_bits(res->start), | ||
873 | 0, 0xF8000000, 0, | ||
874 | lower_32_bits(res->start), | ||
875 | OB_PCIE_IO); | ||
876 | err = pci_remap_iospace(res, iobase); | ||
877 | if (err) | ||
878 | dev_warn(dev, "error %d: failed to map resource %pR\n", | ||
879 | err, res); | ||
880 | break; | ||
881 | case IORESOURCE_MEM: | ||
882 | advk_pcie_set_ob_win(pcie, 0, | ||
883 | upper_32_bits(res->start), | ||
884 | lower_32_bits(res->start), | ||
885 | 0x0, 0xF8000000, 0, | ||
886 | lower_32_bits(res->start), | ||
887 | (2 << 20) | OB_PCIE_MEM); | ||
888 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); | ||
889 | break; | ||
890 | case IORESOURCE_BUS: | ||
891 | pcie->root_bus_nr = res->start; | ||
892 | break; | ||
893 | } | ||
894 | } | ||
895 | |||
896 | if (!res_valid) { | ||
897 | dev_err(dev, "non-prefetchable memory resource required\n"); | ||
898 | err = -EINVAL; | ||
899 | goto out_release_res; | ||
900 | } | ||
901 | |||
902 | return 0; | ||
903 | |||
904 | out_release_res: | ||
905 | pci_free_resource_list(&pcie->resources); | ||
906 | return err; | ||
907 | } | ||
908 | |||
909 | static int advk_pcie_probe(struct platform_device *pdev) | ||
910 | { | ||
911 | struct advk_pcie *pcie; | ||
912 | struct resource *res; | ||
913 | struct pci_bus *bus, *child; | ||
914 | struct msi_controller *msi; | ||
915 | struct device_node *msi_node; | ||
916 | int ret, irq; | ||
917 | |||
918 | pcie = devm_kzalloc(&pdev->dev, sizeof(struct advk_pcie), | ||
919 | GFP_KERNEL); | ||
920 | if (!pcie) | ||
921 | return -ENOMEM; | ||
922 | |||
923 | pcie->pdev = pdev; | ||
924 | platform_set_drvdata(pdev, pcie); | ||
925 | |||
926 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
927 | pcie->base = devm_ioremap_resource(&pdev->dev, res); | ||
928 | if (IS_ERR(pcie->base)) { | ||
929 | dev_err(&pdev->dev, "Failed to map registers\n"); | ||
930 | return PTR_ERR(pcie->base); | ||
931 | } | ||
932 | |||
933 | irq = platform_get_irq(pdev, 0); | ||
934 | ret = devm_request_irq(&pdev->dev, irq, advk_pcie_irq_handler, | ||
935 | IRQF_SHARED | IRQF_NO_THREAD, "advk-pcie", | ||
936 | pcie); | ||
937 | if (ret) { | ||
938 | dev_err(&pdev->dev, "Failed to register interrupt\n"); | ||
939 | return ret; | ||
940 | } | ||
941 | |||
942 | ret = advk_pcie_parse_request_of_pci_ranges(pcie); | ||
943 | if (ret) { | ||
944 | dev_err(&pdev->dev, "Failed to parse resources\n"); | ||
945 | return ret; | ||
946 | } | ||
947 | |||
948 | advk_pcie_setup_hw(pcie); | ||
949 | |||
950 | ret = advk_pcie_init_irq_domain(pcie); | ||
951 | if (ret) { | ||
952 | dev_err(&pdev->dev, "Failed to initialize irq\n"); | ||
953 | return ret; | ||
954 | } | ||
955 | |||
956 | ret = advk_pcie_init_msi_irq_domain(pcie); | ||
957 | if (ret) { | ||
958 | dev_err(&pdev->dev, "Failed to initialize irq\n"); | ||
959 | advk_pcie_remove_irq_domain(pcie); | ||
960 | return ret; | ||
961 | } | ||
962 | |||
963 | msi_node = of_parse_phandle(pdev->dev.of_node, "msi-parent", 0); | ||
964 | if (msi_node) | ||
965 | msi = of_pci_find_msi_chip_by_node(msi_node); | ||
966 | else | ||
967 | msi = NULL; | ||
968 | |||
969 | bus = pci_scan_root_bus_msi(&pdev->dev, 0, &advk_pcie_ops, | ||
970 | pcie, &pcie->resources, &pcie->msi); | ||
971 | if (!bus) { | ||
972 | advk_pcie_remove_msi_irq_domain(pcie); | ||
973 | advk_pcie_remove_irq_domain(pcie); | ||
974 | return -ENOMEM; | ||
975 | } | ||
976 | |||
977 | pci_bus_assign_resources(bus); | ||
978 | |||
979 | list_for_each_entry(child, &bus->children, node) | ||
980 | pcie_bus_configure_settings(child); | ||
981 | |||
982 | pci_bus_add_devices(bus); | ||
983 | |||
984 | return 0; | ||
985 | } | ||
986 | |||
987 | static const struct of_device_id advk_pcie_of_match_table[] = { | ||
988 | { .compatible = "marvell,armada-3700-pcie", }, | ||
989 | {}, | ||
990 | }; | ||
991 | |||
992 | static struct platform_driver advk_pcie_driver = { | ||
993 | .driver = { | ||
994 | .name = "advk-pcie", | ||
995 | .of_match_table = advk_pcie_of_match_table, | ||
996 | /* Driver unloading/unbinding currently not supported */ | ||
997 | .suppress_bind_attrs = true, | ||
998 | }, | ||
999 | .probe = advk_pcie_probe, | ||
1000 | }; | ||
1001 | builtin_platform_driver(advk_pcie_driver); | ||
diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c index f441130407e7..81b3949a26db 100644 --- a/drivers/pci/host/pci-dra7xx.c +++ b/drivers/pci/host/pci-dra7xx.c | |||
@@ -181,14 +181,14 @@ static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp) | |||
181 | 181 | ||
182 | if (!pcie_intc_node) { | 182 | if (!pcie_intc_node) { |
183 | dev_err(dev, "No PCIe Intc node found\n"); | 183 | dev_err(dev, "No PCIe Intc node found\n"); |
184 | return PTR_ERR(pcie_intc_node); | 184 | return -ENODEV; |
185 | } | 185 | } |
186 | 186 | ||
187 | pp->irq_domain = irq_domain_add_linear(pcie_intc_node, 4, | 187 | pp->irq_domain = irq_domain_add_linear(pcie_intc_node, 4, |
188 | &intx_domain_ops, pp); | 188 | &intx_domain_ops, pp); |
189 | if (!pp->irq_domain) { | 189 | if (!pp->irq_domain) { |
190 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); | 190 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); |
191 | return PTR_ERR(pp->irq_domain); | 191 | return -ENODEV; |
192 | } | 192 | } |
193 | 193 | ||
194 | return 0; | 194 | return 0; |
diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index 8cba7ab73df9..9d9d34e959b6 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c | |||
@@ -20,10 +20,9 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
22 | #include <linux/of_pci.h> | 22 | #include <linux/of_pci.h> |
23 | #include <linux/pci-ecam.h> | ||
23 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
24 | 25 | ||
25 | #include "../ecam.h" | ||
26 | |||
27 | static int gen_pci_parse_request_of_pci_ranges(struct device *dev, | 26 | static int gen_pci_parse_request_of_pci_ranges(struct device *dev, |
28 | struct list_head *resources, struct resource **bus_range) | 27 | struct list_head *resources, struct resource **bus_range) |
29 | { | 28 | { |
@@ -36,44 +35,34 @@ static int gen_pci_parse_request_of_pci_ranges(struct device *dev, | |||
36 | if (err) | 35 | if (err) |
37 | return err; | 36 | return err; |
38 | 37 | ||
38 | err = devm_request_pci_bus_resources(dev, resources); | ||
39 | if (err) | ||
40 | return err; | ||
41 | |||
39 | resource_list_for_each_entry(win, resources) { | 42 | resource_list_for_each_entry(win, resources) { |
40 | struct resource *parent, *res = win->res; | 43 | struct resource *res = win->res; |
41 | 44 | ||
42 | switch (resource_type(res)) { | 45 | switch (resource_type(res)) { |
43 | case IORESOURCE_IO: | 46 | case IORESOURCE_IO: |
44 | parent = &ioport_resource; | ||
45 | err = pci_remap_iospace(res, iobase); | 47 | err = pci_remap_iospace(res, iobase); |
46 | if (err) { | 48 | if (err) |
47 | dev_warn(dev, "error %d: failed to map resource %pR\n", | 49 | dev_warn(dev, "error %d: failed to map resource %pR\n", |
48 | err, res); | 50 | err, res); |
49 | continue; | ||
50 | } | ||
51 | break; | 51 | break; |
52 | case IORESOURCE_MEM: | 52 | case IORESOURCE_MEM: |
53 | parent = &iomem_resource; | ||
54 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); | 53 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); |
55 | break; | 54 | break; |
56 | case IORESOURCE_BUS: | 55 | case IORESOURCE_BUS: |
57 | *bus_range = res; | 56 | *bus_range = res; |
58 | default: | 57 | break; |
59 | continue; | ||
60 | } | 58 | } |
61 | |||
62 | err = devm_request_resource(dev, parent, res); | ||
63 | if (err) | ||
64 | goto out_release_res; | ||
65 | } | ||
66 | |||
67 | if (!res_valid) { | ||
68 | dev_err(dev, "non-prefetchable memory resource required\n"); | ||
69 | err = -EINVAL; | ||
70 | goto out_release_res; | ||
71 | } | 59 | } |
72 | 60 | ||
73 | return 0; | 61 | if (res_valid) |
62 | return 0; | ||
74 | 63 | ||
75 | out_release_res: | 64 | dev_err(dev, "non-prefetchable memory resource required\n"); |
76 | return err; | 65 | return -EINVAL; |
77 | } | 66 | } |
78 | 67 | ||
79 | static void gen_pci_unmap_cfg(void *ptr) | 68 | static void gen_pci_unmap_cfg(void *ptr) |
@@ -155,7 +144,14 @@ int pci_host_common_probe(struct platform_device *pdev, | |||
155 | 144 | ||
156 | pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); | 145 | pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); |
157 | 146 | ||
158 | if (!pci_has_flag(PCI_PROBE_ONLY)) { | 147 | /* |
148 | * We insert PCI resources into the iomem_resource and | ||
149 | * ioport_resource trees in either pci_bus_claim_resources() | ||
150 | * or pci_bus_assign_resources(). | ||
151 | */ | ||
152 | if (pci_has_flag(PCI_PROBE_ONLY)) { | ||
153 | pci_bus_claim_resources(bus); | ||
154 | } else { | ||
159 | pci_bus_size_bridges(bus); | 155 | pci_bus_size_bridges(bus); |
160 | pci_bus_assign_resources(bus); | 156 | pci_bus_assign_resources(bus); |
161 | 157 | ||
diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c index 6eaceab1bf04..c05ea9d72f69 100644 --- a/drivers/pci/host/pci-host-generic.c +++ b/drivers/pci/host/pci-host-generic.c | |||
@@ -20,13 +20,12 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/module.h> | 23 | #include <linux/init.h> |
24 | #include <linux/of_address.h> | 24 | #include <linux/of_address.h> |
25 | #include <linux/of_pci.h> | 25 | #include <linux/of_pci.h> |
26 | #include <linux/pci-ecam.h> | ||
26 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
27 | 28 | ||
28 | #include "../ecam.h" | ||
29 | |||
30 | static struct pci_ecam_ops gen_pci_cfg_cam_bus_ops = { | 29 | static struct pci_ecam_ops gen_pci_cfg_cam_bus_ops = { |
31 | .bus_shift = 16, | 30 | .bus_shift = 16, |
32 | .pci_ops = { | 31 | .pci_ops = { |
@@ -46,8 +45,6 @@ static const struct of_device_id gen_pci_of_match[] = { | |||
46 | { }, | 45 | { }, |
47 | }; | 46 | }; |
48 | 47 | ||
49 | MODULE_DEVICE_TABLE(of, gen_pci_of_match); | ||
50 | |||
51 | static int gen_pci_probe(struct platform_device *pdev) | 48 | static int gen_pci_probe(struct platform_device *pdev) |
52 | { | 49 | { |
53 | const struct of_device_id *of_id; | 50 | const struct of_device_id *of_id; |
@@ -66,8 +63,4 @@ static struct platform_driver gen_pci_driver = { | |||
66 | }, | 63 | }, |
67 | .probe = gen_pci_probe, | 64 | .probe = gen_pci_probe, |
68 | }; | 65 | }; |
69 | module_platform_driver(gen_pci_driver); | 66 | builtin_platform_driver(gen_pci_driver); |
70 | |||
71 | MODULE_DESCRIPTION("Generic PCI host driver"); | ||
72 | MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>"); | ||
73 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c index 6b8301ef21ca..8ba28834d470 100644 --- a/drivers/pci/host/pci-keystone.c +++ b/drivers/pci/host/pci-keystone.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/irqdomain.h> | 19 | #include <linux/irqdomain.h> |
20 | #include <linux/module.h> | 20 | #include <linux/init.h> |
21 | #include <linux/msi.h> | 21 | #include <linux/msi.h> |
22 | #include <linux/of_irq.h> | 22 | #include <linux/of_irq.h> |
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
@@ -360,7 +360,6 @@ static const struct of_device_id ks_pcie_of_match[] = { | |||
360 | }, | 360 | }, |
361 | { }, | 361 | { }, |
362 | }; | 362 | }; |
363 | MODULE_DEVICE_TABLE(of, ks_pcie_of_match); | ||
364 | 363 | ||
365 | static int __exit ks_pcie_remove(struct platform_device *pdev) | 364 | static int __exit ks_pcie_remove(struct platform_device *pdev) |
366 | { | 365 | { |
@@ -439,9 +438,4 @@ static struct platform_driver ks_pcie_driver __refdata = { | |||
439 | .of_match_table = of_match_ptr(ks_pcie_of_match), | 438 | .of_match_table = of_match_ptr(ks_pcie_of_match), |
440 | }, | 439 | }, |
441 | }; | 440 | }; |
442 | 441 | builtin_platform_driver(ks_pcie_driver); | |
443 | module_platform_driver(ks_pcie_driver); | ||
444 | |||
445 | MODULE_AUTHOR("Murali Karicheri <m-karicheri2@ti.com>"); | ||
446 | MODULE_DESCRIPTION("Keystone PCIe host controller driver"); | ||
447 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c index a21e229d95e0..114ba819277a 100644 --- a/drivers/pci/host/pci-layerscape.c +++ b/drivers/pci/host/pci-layerscape.c | |||
@@ -12,7 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/module.h> | 15 | #include <linux/init.h> |
16 | #include <linux/of_pci.h> | 16 | #include <linux/of_pci.h> |
17 | #include <linux/of_platform.h> | 17 | #include <linux/of_platform.h> |
18 | #include <linux/of_irq.h> | 18 | #include <linux/of_irq.h> |
@@ -211,7 +211,6 @@ static const struct of_device_id ls_pcie_of_match[] = { | |||
211 | { .compatible = "fsl,ls2085a-pcie", .data = &ls2080_drvdata }, | 211 | { .compatible = "fsl,ls2085a-pcie", .data = &ls2080_drvdata }, |
212 | { }, | 212 | { }, |
213 | }; | 213 | }; |
214 | MODULE_DEVICE_TABLE(of, ls_pcie_of_match); | ||
215 | 214 | ||
216 | static int __init ls_add_pcie_port(struct pcie_port *pp, | 215 | static int __init ls_add_pcie_port(struct pcie_port *pp, |
217 | struct platform_device *pdev) | 216 | struct platform_device *pdev) |
@@ -275,9 +274,4 @@ static struct platform_driver ls_pcie_driver = { | |||
275 | .of_match_table = ls_pcie_of_match, | 274 | .of_match_table = ls_pcie_of_match, |
276 | }, | 275 | }, |
277 | }; | 276 | }; |
278 | 277 | builtin_platform_driver_probe(ls_pcie_driver, ls_pcie_probe); | |
279 | module_platform_driver_probe(ls_pcie_driver, ls_pcie_probe); | ||
280 | |||
281 | MODULE_AUTHOR("Minghuan Lian <Minghuan.Lian@freescale.com>"); | ||
282 | MODULE_DESCRIPTION("Freescale Layerscape PCIe host controller driver"); | ||
283 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 6b451df6502c..307f81d6b479 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
@@ -1,6 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * PCIe driver for Marvell Armada 370 and Armada XP SoCs | 2 | * PCIe driver for Marvell Armada 370 and Armada XP SoCs |
3 | * | 3 | * |
4 | * Author: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
5 | * | ||
4 | * This file is licensed under the terms of the GNU General Public | 6 | * This file is licensed under the terms of the GNU General Public |
5 | * License version 2. This program is licensed "as is" without any | 7 | * License version 2. This program is licensed "as is" without any |
6 | * warranty of any kind, whether express or implied. | 8 | * warranty of any kind, whether express or implied. |
@@ -11,7 +13,7 @@ | |||
11 | #include <linux/clk.h> | 13 | #include <linux/clk.h> |
12 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
13 | #include <linux/gpio.h> | 15 | #include <linux/gpio.h> |
14 | #include <linux/module.h> | 16 | #include <linux/init.h> |
15 | #include <linux/mbus.h> | 17 | #include <linux/mbus.h> |
16 | #include <linux/msi.h> | 18 | #include <linux/msi.h> |
17 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
@@ -839,25 +841,22 @@ static struct pci_ops mvebu_pcie_ops = { | |||
839 | static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys) | 841 | static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys) |
840 | { | 842 | { |
841 | struct mvebu_pcie *pcie = sys_to_pcie(sys); | 843 | struct mvebu_pcie *pcie = sys_to_pcie(sys); |
842 | int i; | 844 | int err, i; |
843 | 845 | ||
844 | pcie->mem.name = "PCI MEM"; | 846 | pcie->mem.name = "PCI MEM"; |
845 | pcie->realio.name = "PCI I/O"; | 847 | pcie->realio.name = "PCI I/O"; |
846 | 848 | ||
847 | if (request_resource(&iomem_resource, &pcie->mem)) | 849 | if (resource_size(&pcie->realio) != 0) |
848 | return 0; | ||
849 | |||
850 | if (resource_size(&pcie->realio) != 0) { | ||
851 | if (request_resource(&ioport_resource, &pcie->realio)) { | ||
852 | release_resource(&pcie->mem); | ||
853 | return 0; | ||
854 | } | ||
855 | pci_add_resource_offset(&sys->resources, &pcie->realio, | 850 | pci_add_resource_offset(&sys->resources, &pcie->realio, |
856 | sys->io_offset); | 851 | sys->io_offset); |
857 | } | 852 | |
858 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); | 853 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); |
859 | pci_add_resource(&sys->resources, &pcie->busn); | 854 | pci_add_resource(&sys->resources, &pcie->busn); |
860 | 855 | ||
856 | err = devm_request_pci_bus_resources(&pcie->pdev->dev, &sys->resources); | ||
857 | if (err) | ||
858 | return 0; | ||
859 | |||
861 | for (i = 0; i < pcie->nports; i++) { | 860 | for (i = 0; i < pcie->nports; i++) { |
862 | struct mvebu_pcie_port *port = &pcie->ports[i]; | 861 | struct mvebu_pcie_port *port = &pcie->ports[i]; |
863 | 862 | ||
@@ -1298,7 +1297,6 @@ static const struct of_device_id mvebu_pcie_of_match_table[] = { | |||
1298 | { .compatible = "marvell,kirkwood-pcie", }, | 1297 | { .compatible = "marvell,kirkwood-pcie", }, |
1299 | {}, | 1298 | {}, |
1300 | }; | 1299 | }; |
1301 | MODULE_DEVICE_TABLE(of, mvebu_pcie_of_match_table); | ||
1302 | 1300 | ||
1303 | static const struct dev_pm_ops mvebu_pcie_pm_ops = { | 1301 | static const struct dev_pm_ops mvebu_pcie_pm_ops = { |
1304 | SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mvebu_pcie_suspend, mvebu_pcie_resume) | 1302 | SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mvebu_pcie_suspend, mvebu_pcie_resume) |
@@ -1314,8 +1312,4 @@ static struct platform_driver mvebu_pcie_driver = { | |||
1314 | }, | 1312 | }, |
1315 | .probe = mvebu_pcie_probe, | 1313 | .probe = mvebu_pcie_probe, |
1316 | }; | 1314 | }; |
1317 | module_platform_driver(mvebu_pcie_driver); | 1315 | builtin_platform_driver(mvebu_pcie_driver); |
1318 | |||
1319 | MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); | ||
1320 | MODULE_DESCRIPTION("Marvell EBU PCIe driver"); | ||
1321 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c index 9980a4bdae7e..597566f96f5e 100644 --- a/drivers/pci/host/pci-rcar-gen2.c +++ b/drivers/pci/host/pci-rcar-gen2.c | |||
@@ -4,6 +4,8 @@ | |||
4 | * Copyright (C) 2013 Renesas Solutions Corp. | 4 | * Copyright (C) 2013 Renesas Solutions Corp. |
5 | * Copyright (C) 2013 Cogent Embedded, Inc. | 5 | * Copyright (C) 2013 Cogent Embedded, Inc. |
6 | * | 6 | * |
7 | * Author: Valentine Barshak <valentine.barshak@cogentembedded.com> | ||
8 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
@@ -14,7 +16,6 @@ | |||
14 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
15 | #include <linux/io.h> | 17 | #include <linux/io.h> |
16 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | ||
18 | #include <linux/of_address.h> | 19 | #include <linux/of_address.h> |
19 | #include <linux/of_pci.h> | 20 | #include <linux/of_pci.h> |
20 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
@@ -97,7 +98,6 @@ | |||
97 | struct rcar_pci_priv { | 98 | struct rcar_pci_priv { |
98 | struct device *dev; | 99 | struct device *dev; |
99 | void __iomem *reg; | 100 | void __iomem *reg; |
100 | struct resource io_res; | ||
101 | struct resource mem_res; | 101 | struct resource mem_res; |
102 | struct resource *cfg_res; | 102 | struct resource *cfg_res; |
103 | unsigned busnr; | 103 | unsigned busnr; |
@@ -194,6 +194,7 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys) | |||
194 | struct rcar_pci_priv *priv = sys->private_data; | 194 | struct rcar_pci_priv *priv = sys->private_data; |
195 | void __iomem *reg = priv->reg; | 195 | void __iomem *reg = priv->reg; |
196 | u32 val; | 196 | u32 val; |
197 | int ret; | ||
197 | 198 | ||
198 | pm_runtime_enable(priv->dev); | 199 | pm_runtime_enable(priv->dev); |
199 | pm_runtime_get_sync(priv->dev); | 200 | pm_runtime_get_sync(priv->dev); |
@@ -273,8 +274,10 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys) | |||
273 | rcar_pci_setup_errirq(priv); | 274 | rcar_pci_setup_errirq(priv); |
274 | 275 | ||
275 | /* Add PCI resources */ | 276 | /* Add PCI resources */ |
276 | pci_add_resource(&sys->resources, &priv->io_res); | ||
277 | pci_add_resource(&sys->resources, &priv->mem_res); | 277 | pci_add_resource(&sys->resources, &priv->mem_res); |
278 | ret = devm_request_pci_bus_resources(priv->dev, &sys->resources); | ||
279 | if (ret < 0) | ||
280 | return ret; | ||
278 | 281 | ||
279 | /* Setup bus number based on platform device id / of bus-range */ | 282 | /* Setup bus number based on platform device id / of bus-range */ |
280 | sys->busnr = priv->busnr; | 283 | sys->busnr = priv->busnr; |
@@ -371,14 +374,6 @@ static int rcar_pci_probe(struct platform_device *pdev) | |||
371 | return -ENOMEM; | 374 | return -ENOMEM; |
372 | 375 | ||
373 | priv->mem_res = *mem_res; | 376 | priv->mem_res = *mem_res; |
374 | /* | ||
375 | * The controller does not support/use port I/O, | ||
376 | * so setup a dummy port I/O region here. | ||
377 | */ | ||
378 | priv->io_res.start = priv->mem_res.start; | ||
379 | priv->io_res.end = priv->mem_res.end; | ||
380 | priv->io_res.flags = IORESOURCE_IO; | ||
381 | |||
382 | priv->cfg_res = cfg_res; | 377 | priv->cfg_res = cfg_res; |
383 | 378 | ||
384 | priv->irq = platform_get_irq(pdev, 0); | 379 | priv->irq = platform_get_irq(pdev, 0); |
@@ -421,6 +416,7 @@ static int rcar_pci_probe(struct platform_device *pdev) | |||
421 | hw_private[0] = priv; | 416 | hw_private[0] = priv; |
422 | memset(&hw, 0, sizeof(hw)); | 417 | memset(&hw, 0, sizeof(hw)); |
423 | hw.nr_controllers = ARRAY_SIZE(hw_private); | 418 | hw.nr_controllers = ARRAY_SIZE(hw_private); |
419 | hw.io_optional = 1; | ||
424 | hw.private_data = hw_private; | 420 | hw.private_data = hw_private; |
425 | hw.map_irq = rcar_pci_map_irq; | 421 | hw.map_irq = rcar_pci_map_irq; |
426 | hw.ops = &rcar_pci_ops; | 422 | hw.ops = &rcar_pci_ops; |
@@ -437,8 +433,6 @@ static struct of_device_id rcar_pci_of_match[] = { | |||
437 | { }, | 433 | { }, |
438 | }; | 434 | }; |
439 | 435 | ||
440 | MODULE_DEVICE_TABLE(of, rcar_pci_of_match); | ||
441 | |||
442 | static struct platform_driver rcar_pci_driver = { | 436 | static struct platform_driver rcar_pci_driver = { |
443 | .driver = { | 437 | .driver = { |
444 | .name = "pci-rcar-gen2", | 438 | .name = "pci-rcar-gen2", |
@@ -447,9 +441,4 @@ static struct platform_driver rcar_pci_driver = { | |||
447 | }, | 441 | }, |
448 | .probe = rcar_pci_probe, | 442 | .probe = rcar_pci_probe, |
449 | }; | 443 | }; |
450 | 444 | builtin_platform_driver(rcar_pci_driver); | |
451 | module_platform_driver(rcar_pci_driver); | ||
452 | |||
453 | MODULE_LICENSE("GPL v2"); | ||
454 | MODULE_DESCRIPTION("Renesas R-Car Gen2 internal PCI"); | ||
455 | MODULE_AUTHOR("Valentine Barshak <valentine.barshak@cogentembedded.com>"); | ||
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index c388468c202a..6de0757b11e4 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
@@ -9,6 +9,8 @@ | |||
9 | * | 9 | * |
10 | * Bits taken from arch/arm/mach-dove/pcie.c | 10 | * Bits taken from arch/arm/mach-dove/pcie.c |
11 | * | 11 | * |
12 | * Author: Thierry Reding <treding@nvidia.com> | ||
13 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | 14 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License as published by | 15 | * it under the terms of the GNU General Public License as published by |
14 | * the Free Software Foundation; either version 2 of the License, or | 16 | * the Free Software Foundation; either version 2 of the License, or |
@@ -32,7 +34,7 @@ | |||
32 | #include <linux/irq.h> | 34 | #include <linux/irq.h> |
33 | #include <linux/irqdomain.h> | 35 | #include <linux/irqdomain.h> |
34 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
35 | #include <linux/module.h> | 37 | #include <linux/init.h> |
36 | #include <linux/msi.h> | 38 | #include <linux/msi.h> |
37 | #include <linux/of_address.h> | 39 | #include <linux/of_address.h> |
38 | #include <linux/of_pci.h> | 40 | #include <linux/of_pci.h> |
@@ -183,26 +185,26 @@ | |||
183 | 185 | ||
184 | #define AFI_PEXBIAS_CTRL_0 0x168 | 186 | #define AFI_PEXBIAS_CTRL_0 0x168 |
185 | 187 | ||
186 | #define RP_VEND_XP 0x00000F00 | 188 | #define RP_VEND_XP 0x00000f00 |
187 | #define RP_VEND_XP_DL_UP (1 << 30) | 189 | #define RP_VEND_XP_DL_UP (1 << 30) |
188 | 190 | ||
189 | #define RP_PRIV_MISC 0x00000FE0 | 191 | #define RP_PRIV_MISC 0x00000fe0 |
190 | #define RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xE << 0) | 192 | #define RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xe << 0) |
191 | #define RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xF << 0) | 193 | #define RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xf << 0) |
192 | 194 | ||
193 | #define RP_LINK_CONTROL_STATUS 0x00000090 | 195 | #define RP_LINK_CONTROL_STATUS 0x00000090 |
194 | #define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000 | 196 | #define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000 |
195 | #define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000 | 197 | #define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000 |
196 | 198 | ||
197 | #define PADS_CTL_SEL 0x0000009C | 199 | #define PADS_CTL_SEL 0x0000009c |
198 | 200 | ||
199 | #define PADS_CTL 0x000000A0 | 201 | #define PADS_CTL 0x000000a0 |
200 | #define PADS_CTL_IDDQ_1L (1 << 0) | 202 | #define PADS_CTL_IDDQ_1L (1 << 0) |
201 | #define PADS_CTL_TX_DATA_EN_1L (1 << 6) | 203 | #define PADS_CTL_TX_DATA_EN_1L (1 << 6) |
202 | #define PADS_CTL_RX_DATA_EN_1L (1 << 10) | 204 | #define PADS_CTL_RX_DATA_EN_1L (1 << 10) |
203 | 205 | ||
204 | #define PADS_PLL_CTL_TEGRA20 0x000000B8 | 206 | #define PADS_PLL_CTL_TEGRA20 0x000000b8 |
205 | #define PADS_PLL_CTL_TEGRA30 0x000000B4 | 207 | #define PADS_PLL_CTL_TEGRA30 0x000000b4 |
206 | #define PADS_PLL_CTL_RST_B4SM (1 << 1) | 208 | #define PADS_PLL_CTL_RST_B4SM (1 << 1) |
207 | #define PADS_PLL_CTL_LOCKDET (1 << 8) | 209 | #define PADS_PLL_CTL_LOCKDET (1 << 8) |
208 | #define PADS_PLL_CTL_REFCLK_MASK (0x3 << 16) | 210 | #define PADS_PLL_CTL_REFCLK_MASK (0x3 << 16) |
@@ -214,9 +216,9 @@ | |||
214 | #define PADS_PLL_CTL_TXCLKREF_DIV5 (1 << 20) | 216 | #define PADS_PLL_CTL_TXCLKREF_DIV5 (1 << 20) |
215 | #define PADS_PLL_CTL_TXCLKREF_BUF_EN (1 << 22) | 217 | #define PADS_PLL_CTL_TXCLKREF_BUF_EN (1 << 22) |
216 | 218 | ||
217 | #define PADS_REFCLK_CFG0 0x000000C8 | 219 | #define PADS_REFCLK_CFG0 0x000000c8 |
218 | #define PADS_REFCLK_CFG1 0x000000CC | 220 | #define PADS_REFCLK_CFG1 0x000000cc |
219 | #define PADS_REFCLK_BIAS 0x000000D0 | 221 | #define PADS_REFCLK_BIAS 0x000000d0 |
220 | 222 | ||
221 | /* | 223 | /* |
222 | * Fields in PADS_REFCLK_CFG*. Those registers form an array of 16-bit | 224 | * Fields in PADS_REFCLK_CFG*. Those registers form an array of 16-bit |
@@ -228,15 +230,6 @@ | |||
228 | #define PADS_REFCLK_CFG_PREDI_SHIFT 8 /* 11:8 */ | 230 | #define PADS_REFCLK_CFG_PREDI_SHIFT 8 /* 11:8 */ |
229 | #define PADS_REFCLK_CFG_DRVI_SHIFT 12 /* 15:12 */ | 231 | #define PADS_REFCLK_CFG_DRVI_SHIFT 12 /* 15:12 */ |
230 | 232 | ||
231 | /* Default value provided by HW engineering is 0xfa5c */ | ||
232 | #define PADS_REFCLK_CFG_VALUE \ | ||
233 | ( \ | ||
234 | (0x17 << PADS_REFCLK_CFG_TERM_SHIFT) | \ | ||
235 | (0 << PADS_REFCLK_CFG_E_TERM_SHIFT) | \ | ||
236 | (0xa << PADS_REFCLK_CFG_PREDI_SHIFT) | \ | ||
237 | (0xf << PADS_REFCLK_CFG_DRVI_SHIFT) \ | ||
238 | ) | ||
239 | |||
240 | struct tegra_msi { | 233 | struct tegra_msi { |
241 | struct msi_controller chip; | 234 | struct msi_controller chip; |
242 | DECLARE_BITMAP(used, INT_PCI_MSI_NR); | 235 | DECLARE_BITMAP(used, INT_PCI_MSI_NR); |
@@ -252,6 +245,8 @@ struct tegra_pcie_soc_data { | |||
252 | unsigned int msi_base_shift; | 245 | unsigned int msi_base_shift; |
253 | u32 pads_pll_ctl; | 246 | u32 pads_pll_ctl; |
254 | u32 tx_ref_sel; | 247 | u32 tx_ref_sel; |
248 | u32 pads_refclk_cfg0; | ||
249 | u32 pads_refclk_cfg1; | ||
255 | bool has_pex_clkreq_en; | 250 | bool has_pex_clkreq_en; |
256 | bool has_pex_bias_ctrl; | 251 | bool has_pex_bias_ctrl; |
257 | bool has_intr_prsnt_sense; | 252 | bool has_intr_prsnt_sense; |
@@ -274,7 +269,6 @@ struct tegra_pcie { | |||
274 | struct list_head buses; | 269 | struct list_head buses; |
275 | struct resource *cs; | 270 | struct resource *cs; |
276 | 271 | ||
277 | struct resource all; | ||
278 | struct resource io; | 272 | struct resource io; |
279 | struct resource pio; | 273 | struct resource pio; |
280 | struct resource mem; | 274 | struct resource mem; |
@@ -623,30 +617,21 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | |||
623 | sys->mem_offset = pcie->offset.mem; | 617 | sys->mem_offset = pcie->offset.mem; |
624 | sys->io_offset = pcie->offset.io; | 618 | sys->io_offset = pcie->offset.io; |
625 | 619 | ||
626 | err = devm_request_resource(pcie->dev, &pcie->all, &pcie->io); | 620 | err = devm_request_resource(pcie->dev, &iomem_resource, &pcie->io); |
627 | if (err < 0) | ||
628 | return err; | ||
629 | |||
630 | err = devm_request_resource(pcie->dev, &ioport_resource, &pcie->pio); | ||
631 | if (err < 0) | ||
632 | return err; | ||
633 | |||
634 | err = devm_request_resource(pcie->dev, &pcie->all, &pcie->mem); | ||
635 | if (err < 0) | 621 | if (err < 0) |
636 | return err; | 622 | return err; |
637 | 623 | ||
638 | err = devm_request_resource(pcie->dev, &pcie->all, &pcie->prefetch); | ||
639 | if (err) | ||
640 | return err; | ||
641 | |||
642 | pci_add_resource_offset(&sys->resources, &pcie->pio, sys->io_offset); | 624 | pci_add_resource_offset(&sys->resources, &pcie->pio, sys->io_offset); |
643 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); | 625 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); |
644 | pci_add_resource_offset(&sys->resources, &pcie->prefetch, | 626 | pci_add_resource_offset(&sys->resources, &pcie->prefetch, |
645 | sys->mem_offset); | 627 | sys->mem_offset); |
646 | pci_add_resource(&sys->resources, &pcie->busn); | 628 | pci_add_resource(&sys->resources, &pcie->busn); |
647 | 629 | ||
648 | pci_ioremap_io(pcie->pio.start, pcie->io.start); | 630 | err = devm_request_pci_bus_resources(pcie->dev, &sys->resources); |
631 | if (err < 0) | ||
632 | return err; | ||
649 | 633 | ||
634 | pci_remap_iospace(&pcie->pio, pcie->io.start); | ||
650 | return 1; | 635 | return 1; |
651 | } | 636 | } |
652 | 637 | ||
@@ -838,12 +823,6 @@ static int tegra_pcie_phy_enable(struct tegra_pcie *pcie) | |||
838 | value |= PADS_PLL_CTL_RST_B4SM; | 823 | value |= PADS_PLL_CTL_RST_B4SM; |
839 | pads_writel(pcie, value, soc->pads_pll_ctl); | 824 | pads_writel(pcie, value, soc->pads_pll_ctl); |
840 | 825 | ||
841 | /* Configure the reference clock driver */ | ||
842 | value = PADS_REFCLK_CFG_VALUE | (PADS_REFCLK_CFG_VALUE << 16); | ||
843 | pads_writel(pcie, value, PADS_REFCLK_CFG0); | ||
844 | if (soc->num_ports > 2) | ||
845 | pads_writel(pcie, PADS_REFCLK_CFG_VALUE, PADS_REFCLK_CFG1); | ||
846 | |||
847 | /* wait for the PLL to lock */ | 826 | /* wait for the PLL to lock */ |
848 | err = tegra_pcie_pll_wait(pcie, 500); | 827 | err = tegra_pcie_pll_wait(pcie, 500); |
849 | if (err < 0) { | 828 | if (err < 0) { |
@@ -927,6 +906,7 @@ static int tegra_pcie_port_phy_power_off(struct tegra_pcie_port *port) | |||
927 | 906 | ||
928 | static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie) | 907 | static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie) |
929 | { | 908 | { |
909 | const struct tegra_pcie_soc_data *soc = pcie->soc_data; | ||
930 | struct tegra_pcie_port *port; | 910 | struct tegra_pcie_port *port; |
931 | int err; | 911 | int err; |
932 | 912 | ||
@@ -952,6 +932,12 @@ static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie) | |||
952 | } | 932 | } |
953 | } | 933 | } |
954 | 934 | ||
935 | /* Configure the reference clock driver */ | ||
936 | pads_writel(pcie, soc->pads_refclk_cfg0, PADS_REFCLK_CFG0); | ||
937 | |||
938 | if (soc->num_ports > 2) | ||
939 | pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1); | ||
940 | |||
955 | return 0; | 941 | return 0; |
956 | } | 942 | } |
957 | 943 | ||
@@ -1822,12 +1808,6 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) | |||
1822 | struct resource res; | 1808 | struct resource res; |
1823 | int err; | 1809 | int err; |
1824 | 1810 | ||
1825 | memset(&pcie->all, 0, sizeof(pcie->all)); | ||
1826 | pcie->all.flags = IORESOURCE_MEM; | ||
1827 | pcie->all.name = np->full_name; | ||
1828 | pcie->all.start = ~0; | ||
1829 | pcie->all.end = 0; | ||
1830 | |||
1831 | if (of_pci_range_parser_init(&parser, np)) { | 1811 | if (of_pci_range_parser_init(&parser, np)) { |
1832 | dev_err(pcie->dev, "missing \"ranges\" property\n"); | 1812 | dev_err(pcie->dev, "missing \"ranges\" property\n"); |
1833 | return -EINVAL; | 1813 | return -EINVAL; |
@@ -1880,18 +1860,8 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) | |||
1880 | } | 1860 | } |
1881 | break; | 1861 | break; |
1882 | } | 1862 | } |
1883 | |||
1884 | if (res.start <= pcie->all.start) | ||
1885 | pcie->all.start = res.start; | ||
1886 | |||
1887 | if (res.end >= pcie->all.end) | ||
1888 | pcie->all.end = res.end; | ||
1889 | } | 1863 | } |
1890 | 1864 | ||
1891 | err = devm_request_resource(pcie->dev, &iomem_resource, &pcie->all); | ||
1892 | if (err < 0) | ||
1893 | return err; | ||
1894 | |||
1895 | err = of_pci_parse_bus_range(np, &pcie->busn); | 1865 | err = of_pci_parse_bus_range(np, &pcie->busn); |
1896 | if (err < 0) { | 1866 | if (err < 0) { |
1897 | dev_err(pcie->dev, "failed to parse ranges property: %d\n", | 1867 | dev_err(pcie->dev, "failed to parse ranges property: %d\n", |
@@ -2078,6 +2048,7 @@ static const struct tegra_pcie_soc_data tegra20_pcie_data = { | |||
2078 | .msi_base_shift = 0, | 2048 | .msi_base_shift = 0, |
2079 | .pads_pll_ctl = PADS_PLL_CTL_TEGRA20, | 2049 | .pads_pll_ctl = PADS_PLL_CTL_TEGRA20, |
2080 | .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_DIV10, | 2050 | .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_DIV10, |
2051 | .pads_refclk_cfg0 = 0xfa5cfa5c, | ||
2081 | .has_pex_clkreq_en = false, | 2052 | .has_pex_clkreq_en = false, |
2082 | .has_pex_bias_ctrl = false, | 2053 | .has_pex_bias_ctrl = false, |
2083 | .has_intr_prsnt_sense = false, | 2054 | .has_intr_prsnt_sense = false, |
@@ -2090,6 +2061,8 @@ static const struct tegra_pcie_soc_data tegra30_pcie_data = { | |||
2090 | .msi_base_shift = 8, | 2061 | .msi_base_shift = 8, |
2091 | .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, | 2062 | .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, |
2092 | .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, | 2063 | .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, |
2064 | .pads_refclk_cfg0 = 0xfa5cfa5c, | ||
2065 | .pads_refclk_cfg1 = 0xfa5cfa5c, | ||
2093 | .has_pex_clkreq_en = true, | 2066 | .has_pex_clkreq_en = true, |
2094 | .has_pex_bias_ctrl = true, | 2067 | .has_pex_bias_ctrl = true, |
2095 | .has_intr_prsnt_sense = true, | 2068 | .has_intr_prsnt_sense = true, |
@@ -2102,6 +2075,7 @@ static const struct tegra_pcie_soc_data tegra124_pcie_data = { | |||
2102 | .msi_base_shift = 8, | 2075 | .msi_base_shift = 8, |
2103 | .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, | 2076 | .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, |
2104 | .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, | 2077 | .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, |
2078 | .pads_refclk_cfg0 = 0x44ac44ac, | ||
2105 | .has_pex_clkreq_en = true, | 2079 | .has_pex_clkreq_en = true, |
2106 | .has_pex_bias_ctrl = true, | 2080 | .has_pex_bias_ctrl = true, |
2107 | .has_intr_prsnt_sense = true, | 2081 | .has_intr_prsnt_sense = true, |
@@ -2115,7 +2089,6 @@ static const struct of_device_id tegra_pcie_of_match[] = { | |||
2115 | { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie_data }, | 2089 | { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie_data }, |
2116 | { }, | 2090 | { }, |
2117 | }; | 2091 | }; |
2118 | MODULE_DEVICE_TABLE(of, tegra_pcie_of_match); | ||
2119 | 2092 | ||
2120 | static void *tegra_pcie_ports_seq_start(struct seq_file *s, loff_t *pos) | 2093 | static void *tegra_pcie_ports_seq_start(struct seq_file *s, loff_t *pos) |
2121 | { | 2094 | { |
@@ -2249,8 +2222,6 @@ static int tegra_pcie_probe(struct platform_device *pdev) | |||
2249 | if (err < 0) | 2222 | if (err < 0) |
2250 | return err; | 2223 | return err; |
2251 | 2224 | ||
2252 | pcibios_min_mem = 0; | ||
2253 | |||
2254 | err = tegra_pcie_get_resources(pcie); | 2225 | err = tegra_pcie_get_resources(pcie); |
2255 | if (err < 0) { | 2226 | if (err < 0) { |
2256 | dev_err(&pdev->dev, "failed to request resources: %d\n", err); | 2227 | dev_err(&pdev->dev, "failed to request resources: %d\n", err); |
@@ -2306,8 +2277,4 @@ static struct platform_driver tegra_pcie_driver = { | |||
2306 | }, | 2277 | }, |
2307 | .probe = tegra_pcie_probe, | 2278 | .probe = tegra_pcie_probe, |
2308 | }; | 2279 | }; |
2309 | module_platform_driver(tegra_pcie_driver); | 2280 | builtin_platform_driver(tegra_pcie_driver); |
2310 | |||
2311 | MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); | ||
2312 | MODULE_DESCRIPTION("NVIDIA Tegra PCIe driver"); | ||
2313 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-thunder-ecam.c b/drivers/pci/host/pci-thunder-ecam.c index 540d030613eb..d50a3dc2d8db 100644 --- a/drivers/pci/host/pci-thunder-ecam.c +++ b/drivers/pci/host/pci-thunder-ecam.c | |||
@@ -7,14 +7,13 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/module.h> | 10 | #include <linux/init.h> |
11 | #include <linux/ioport.h> | 11 | #include <linux/ioport.h> |
12 | #include <linux/of_pci.h> | 12 | #include <linux/of_pci.h> |
13 | #include <linux/of.h> | 13 | #include <linux/of.h> |
14 | #include <linux/pci-ecam.h> | ||
14 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
15 | 16 | ||
16 | #include "../ecam.h" | ||
17 | |||
18 | static void set_val(u32 v, int where, int size, u32 *val) | 17 | static void set_val(u32 v, int where, int size, u32 *val) |
19 | { | 18 | { |
20 | int shift = (where & 3) * 8; | 19 | int shift = (where & 3) * 8; |
@@ -360,7 +359,6 @@ static const struct of_device_id thunder_ecam_of_match[] = { | |||
360 | { .compatible = "cavium,pci-host-thunder-ecam" }, | 359 | { .compatible = "cavium,pci-host-thunder-ecam" }, |
361 | { }, | 360 | { }, |
362 | }; | 361 | }; |
363 | MODULE_DEVICE_TABLE(of, thunder_ecam_of_match); | ||
364 | 362 | ||
365 | static int thunder_ecam_probe(struct platform_device *pdev) | 363 | static int thunder_ecam_probe(struct platform_device *pdev) |
366 | { | 364 | { |
@@ -374,7 +372,4 @@ static struct platform_driver thunder_ecam_driver = { | |||
374 | }, | 372 | }, |
375 | .probe = thunder_ecam_probe, | 373 | .probe = thunder_ecam_probe, |
376 | }; | 374 | }; |
377 | module_platform_driver(thunder_ecam_driver); | 375 | builtin_platform_driver(thunder_ecam_driver); |
378 | |||
379 | MODULE_DESCRIPTION("Thunder ECAM PCI host driver"); | ||
380 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c index 9b8ab94f3c8c..6abaf80ffb39 100644 --- a/drivers/pci/host/pci-thunder-pem.c +++ b/drivers/pci/host/pci-thunder-pem.c | |||
@@ -15,13 +15,12 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/module.h> | 18 | #include <linux/init.h> |
19 | #include <linux/of_address.h> | 19 | #include <linux/of_address.h> |
20 | #include <linux/of_pci.h> | 20 | #include <linux/of_pci.h> |
21 | #include <linux/pci-ecam.h> | ||
21 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
22 | 23 | ||
23 | #include "../ecam.h" | ||
24 | |||
25 | #define PEM_CFG_WR 0x28 | 24 | #define PEM_CFG_WR 0x28 |
26 | #define PEM_CFG_RD 0x30 | 25 | #define PEM_CFG_RD 0x30 |
27 | 26 | ||
@@ -285,8 +284,9 @@ static int thunder_pem_config_write(struct pci_bus *bus, unsigned int devfn, | |||
285 | return pci_generic_config_write(bus, devfn, where, size, val); | 284 | return pci_generic_config_write(bus, devfn, where, size, val); |
286 | } | 285 | } |
287 | 286 | ||
288 | static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg) | 287 | static int thunder_pem_init(struct pci_config_window *cfg) |
289 | { | 288 | { |
289 | struct device *dev = cfg->parent; | ||
290 | resource_size_t bar4_start; | 290 | resource_size_t bar4_start; |
291 | struct resource *res_pem; | 291 | struct resource *res_pem; |
292 | struct thunder_pem_pci *pem_pci; | 292 | struct thunder_pem_pci *pem_pci; |
@@ -346,7 +346,6 @@ static const struct of_device_id thunder_pem_of_match[] = { | |||
346 | { .compatible = "cavium,pci-host-thunder-pem" }, | 346 | { .compatible = "cavium,pci-host-thunder-pem" }, |
347 | { }, | 347 | { }, |
348 | }; | 348 | }; |
349 | MODULE_DEVICE_TABLE(of, thunder_pem_of_match); | ||
350 | 349 | ||
351 | static int thunder_pem_probe(struct platform_device *pdev) | 350 | static int thunder_pem_probe(struct platform_device *pdev) |
352 | { | 351 | { |
@@ -360,7 +359,4 @@ static struct platform_driver thunder_pem_driver = { | |||
360 | }, | 359 | }, |
361 | .probe = thunder_pem_probe, | 360 | .probe = thunder_pem_probe, |
362 | }; | 361 | }; |
363 | module_platform_driver(thunder_pem_driver); | 362 | builtin_platform_driver(thunder_pem_driver); |
364 | |||
365 | MODULE_DESCRIPTION("Thunder PEM PCIe host driver"); | ||
366 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pci-versatile.c b/drivers/pci/host/pci-versatile.c index f843a72dc51c..f234405770ab 100644 --- a/drivers/pci/host/pci-versatile.c +++ b/drivers/pci/host/pci-versatile.c | |||
@@ -80,21 +80,21 @@ static int versatile_pci_parse_request_of_pci_ranges(struct device *dev, | |||
80 | if (err) | 80 | if (err) |
81 | return err; | 81 | return err; |
82 | 82 | ||
83 | err = devm_request_pci_bus_resources(dev, res); | ||
84 | if (err) | ||
85 | goto out_release_res; | ||
86 | |||
83 | resource_list_for_each_entry(win, res) { | 87 | resource_list_for_each_entry(win, res) { |
84 | struct resource *parent, *res = win->res; | 88 | struct resource *res = win->res; |
85 | 89 | ||
86 | switch (resource_type(res)) { | 90 | switch (resource_type(res)) { |
87 | case IORESOURCE_IO: | 91 | case IORESOURCE_IO: |
88 | parent = &ioport_resource; | ||
89 | err = pci_remap_iospace(res, iobase); | 92 | err = pci_remap_iospace(res, iobase); |
90 | if (err) { | 93 | if (err) |
91 | dev_warn(dev, "error %d: failed to map resource %pR\n", | 94 | dev_warn(dev, "error %d: failed to map resource %pR\n", |
92 | err, res); | 95 | err, res); |
93 | continue; | ||
94 | } | ||
95 | break; | 96 | break; |
96 | case IORESOURCE_MEM: | 97 | case IORESOURCE_MEM: |
97 | parent = &iomem_resource; | ||
98 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); | 98 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); |
99 | 99 | ||
100 | writel(res->start >> 28, PCI_IMAP(mem)); | 100 | writel(res->start >> 28, PCI_IMAP(mem)); |
@@ -102,23 +102,14 @@ static int versatile_pci_parse_request_of_pci_ranges(struct device *dev, | |||
102 | mem++; | 102 | mem++; |
103 | 103 | ||
104 | break; | 104 | break; |
105 | case IORESOURCE_BUS: | ||
106 | default: | ||
107 | continue; | ||
108 | } | 105 | } |
109 | |||
110 | err = devm_request_resource(dev, parent, res); | ||
111 | if (err) | ||
112 | goto out_release_res; | ||
113 | } | 106 | } |
114 | 107 | ||
115 | if (!res_valid) { | 108 | if (res_valid) |
116 | dev_err(dev, "non-prefetchable memory resource required\n"); | 109 | return 0; |
117 | err = -EINVAL; | ||
118 | goto out_release_res; | ||
119 | } | ||
120 | 110 | ||
121 | return 0; | 111 | dev_err(dev, "non-prefetchable memory resource required\n"); |
112 | err = -EINVAL; | ||
122 | 113 | ||
123 | out_release_res: | 114 | out_release_res: |
124 | pci_free_resource_list(res); | 115 | pci_free_resource_list(res); |
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c index ae00ce22d5a6..a81273c23341 100644 --- a/drivers/pci/host/pci-xgene.c +++ b/drivers/pci/host/pci-xgene.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/jiffies.h> | 22 | #include <linux/jiffies.h> |
23 | #include <linux/memblock.h> | 23 | #include <linux/memblock.h> |
24 | #include <linux/module.h> | 24 | #include <linux/init.h> |
25 | #include <linux/of.h> | 25 | #include <linux/of.h> |
26 | #include <linux/of_address.h> | 26 | #include <linux/of_address.h> |
27 | #include <linux/of_irq.h> | 27 | #include <linux/of_irq.h> |
@@ -540,14 +540,20 @@ static int xgene_pcie_probe_bridge(struct platform_device *pdev) | |||
540 | if (ret) | 540 | if (ret) |
541 | return ret; | 541 | return ret; |
542 | 542 | ||
543 | ret = devm_request_pci_bus_resources(&pdev->dev, &res); | ||
544 | if (ret) | ||
545 | goto error; | ||
546 | |||
543 | ret = xgene_pcie_setup(port, &res, iobase); | 547 | ret = xgene_pcie_setup(port, &res, iobase); |
544 | if (ret) | 548 | if (ret) |
545 | return ret; | 549 | goto error; |
546 | 550 | ||
547 | bus = pci_create_root_bus(&pdev->dev, 0, | 551 | bus = pci_create_root_bus(&pdev->dev, 0, |
548 | &xgene_pcie_ops, port, &res); | 552 | &xgene_pcie_ops, port, &res); |
549 | if (!bus) | 553 | if (!bus) { |
550 | return -ENOMEM; | 554 | ret = -ENOMEM; |
555 | goto error; | ||
556 | } | ||
551 | 557 | ||
552 | pci_scan_child_bus(bus); | 558 | pci_scan_child_bus(bus); |
553 | pci_assign_unassigned_bus_resources(bus); | 559 | pci_assign_unassigned_bus_resources(bus); |
@@ -555,6 +561,10 @@ static int xgene_pcie_probe_bridge(struct platform_device *pdev) | |||
555 | 561 | ||
556 | platform_set_drvdata(pdev, port); | 562 | platform_set_drvdata(pdev, port); |
557 | return 0; | 563 | return 0; |
564 | |||
565 | error: | ||
566 | pci_free_resource_list(&res); | ||
567 | return ret; | ||
558 | } | 568 | } |
559 | 569 | ||
560 | static const struct of_device_id xgene_pcie_match_table[] = { | 570 | static const struct of_device_id xgene_pcie_match_table[] = { |
@@ -569,8 +579,4 @@ static struct platform_driver xgene_pcie_driver = { | |||
569 | }, | 579 | }, |
570 | .probe = xgene_pcie_probe_bridge, | 580 | .probe = xgene_pcie_probe_bridge, |
571 | }; | 581 | }; |
572 | module_platform_driver(xgene_pcie_driver); | 582 | builtin_platform_driver(xgene_pcie_driver); |
573 | |||
574 | MODULE_AUTHOR("Tanmay Inamdar <tinamdar@apm.com>"); | ||
575 | MODULE_DESCRIPTION("APM X-Gene PCIe driver"); | ||
576 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c index dbac6fb3f0bd..2b7837650db8 100644 --- a/drivers/pci/host/pcie-altera.c +++ b/drivers/pci/host/pcie-altera.c | |||
@@ -61,6 +61,8 @@ | |||
61 | #define TLP_LOOP 500 | 61 | #define TLP_LOOP 500 |
62 | #define RP_DEVFN 0 | 62 | #define RP_DEVFN 0 |
63 | 63 | ||
64 | #define LINK_UP_TIMEOUT 5000 | ||
65 | |||
64 | #define INTX_NUM 4 | 66 | #define INTX_NUM 4 |
65 | 67 | ||
66 | #define DWORD_MASK 3 | 68 | #define DWORD_MASK 3 |
@@ -81,9 +83,30 @@ struct tlp_rp_regpair_t { | |||
81 | u32 reg1; | 83 | u32 reg1; |
82 | }; | 84 | }; |
83 | 85 | ||
86 | static inline void cra_writel(struct altera_pcie *pcie, const u32 value, | ||
87 | const u32 reg) | ||
88 | { | ||
89 | writel_relaxed(value, pcie->cra_base + reg); | ||
90 | } | ||
91 | |||
92 | static inline u32 cra_readl(struct altera_pcie *pcie, const u32 reg) | ||
93 | { | ||
94 | return readl_relaxed(pcie->cra_base + reg); | ||
95 | } | ||
96 | |||
97 | static bool altera_pcie_link_is_up(struct altera_pcie *pcie) | ||
98 | { | ||
99 | return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0); | ||
100 | } | ||
101 | |||
84 | static void altera_pcie_retrain(struct pci_dev *dev) | 102 | static void altera_pcie_retrain(struct pci_dev *dev) |
85 | { | 103 | { |
86 | u16 linkcap, linkstat; | 104 | u16 linkcap, linkstat; |
105 | struct altera_pcie *pcie = dev->bus->sysdata; | ||
106 | int timeout = 0; | ||
107 | |||
108 | if (!altera_pcie_link_is_up(pcie)) | ||
109 | return; | ||
87 | 110 | ||
88 | /* | 111 | /* |
89 | * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but | 112 | * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but |
@@ -95,9 +118,16 @@ static void altera_pcie_retrain(struct pci_dev *dev) | |||
95 | return; | 118 | return; |
96 | 119 | ||
97 | pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat); | 120 | pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat); |
98 | if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) | 121 | if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) { |
99 | pcie_capability_set_word(dev, PCI_EXP_LNKCTL, | 122 | pcie_capability_set_word(dev, PCI_EXP_LNKCTL, |
100 | PCI_EXP_LNKCTL_RL); | 123 | PCI_EXP_LNKCTL_RL); |
124 | while (!altera_pcie_link_is_up(pcie)) { | ||
125 | timeout++; | ||
126 | if (timeout > LINK_UP_TIMEOUT) | ||
127 | break; | ||
128 | udelay(5); | ||
129 | } | ||
130 | } | ||
101 | } | 131 | } |
102 | DECLARE_PCI_FIXUP_EARLY(0x1172, PCI_ANY_ID, altera_pcie_retrain); | 132 | DECLARE_PCI_FIXUP_EARLY(0x1172, PCI_ANY_ID, altera_pcie_retrain); |
103 | 133 | ||
@@ -120,17 +150,6 @@ static bool altera_pcie_hide_rc_bar(struct pci_bus *bus, unsigned int devfn, | |||
120 | return false; | 150 | return false; |
121 | } | 151 | } |
122 | 152 | ||
123 | static inline void cra_writel(struct altera_pcie *pcie, const u32 value, | ||
124 | const u32 reg) | ||
125 | { | ||
126 | writel_relaxed(value, pcie->cra_base + reg); | ||
127 | } | ||
128 | |||
129 | static inline u32 cra_readl(struct altera_pcie *pcie, const u32 reg) | ||
130 | { | ||
131 | return readl_relaxed(pcie->cra_base + reg); | ||
132 | } | ||
133 | |||
134 | static void tlp_write_tx(struct altera_pcie *pcie, | 153 | static void tlp_write_tx(struct altera_pcie *pcie, |
135 | struct tlp_rp_regpair_t *tlp_rp_regdata) | 154 | struct tlp_rp_regpair_t *tlp_rp_regdata) |
136 | { | 155 | { |
@@ -139,11 +158,6 @@ static void tlp_write_tx(struct altera_pcie *pcie, | |||
139 | cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL); | 158 | cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL); |
140 | } | 159 | } |
141 | 160 | ||
142 | static bool altera_pcie_link_is_up(struct altera_pcie *pcie) | ||
143 | { | ||
144 | return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0); | ||
145 | } | ||
146 | |||
147 | static bool altera_pcie_valid_config(struct altera_pcie *pcie, | 161 | static bool altera_pcie_valid_config(struct altera_pcie *pcie, |
148 | struct pci_bus *bus, int dev) | 162 | struct pci_bus *bus, int dev) |
149 | { | 163 | { |
@@ -415,11 +429,6 @@ static void altera_pcie_isr(struct irq_desc *desc) | |||
415 | chained_irq_exit(chip, desc); | 429 | chained_irq_exit(chip, desc); |
416 | } | 430 | } |
417 | 431 | ||
418 | static void altera_pcie_release_of_pci_ranges(struct altera_pcie *pcie) | ||
419 | { | ||
420 | pci_free_resource_list(&pcie->resources); | ||
421 | } | ||
422 | |||
423 | static int altera_pcie_parse_request_of_pci_ranges(struct altera_pcie *pcie) | 432 | static int altera_pcie_parse_request_of_pci_ranges(struct altera_pcie *pcie) |
424 | { | 433 | { |
425 | int err, res_valid = 0; | 434 | int err, res_valid = 0; |
@@ -432,33 +441,25 @@ static int altera_pcie_parse_request_of_pci_ranges(struct altera_pcie *pcie) | |||
432 | if (err) | 441 | if (err) |
433 | return err; | 442 | return err; |
434 | 443 | ||
444 | err = devm_request_pci_bus_resources(dev, &pcie->resources); | ||
445 | if (err) | ||
446 | goto out_release_res; | ||
447 | |||
435 | resource_list_for_each_entry(win, &pcie->resources) { | 448 | resource_list_for_each_entry(win, &pcie->resources) { |
436 | struct resource *parent, *res = win->res; | 449 | struct resource *res = win->res; |
437 | 450 | ||
438 | switch (resource_type(res)) { | 451 | if (resource_type(res) == IORESOURCE_MEM) |
439 | case IORESOURCE_MEM: | ||
440 | parent = &iomem_resource; | ||
441 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); | 452 | res_valid |= !(res->flags & IORESOURCE_PREFETCH); |
442 | break; | ||
443 | default: | ||
444 | continue; | ||
445 | } | ||
446 | |||
447 | err = devm_request_resource(dev, parent, res); | ||
448 | if (err) | ||
449 | goto out_release_res; | ||
450 | } | 453 | } |
451 | 454 | ||
452 | if (!res_valid) { | 455 | if (res_valid) |
453 | dev_err(dev, "non-prefetchable memory resource required\n"); | 456 | return 0; |
454 | err = -EINVAL; | ||
455 | goto out_release_res; | ||
456 | } | ||
457 | 457 | ||
458 | return 0; | 458 | dev_err(dev, "non-prefetchable memory resource required\n"); |
459 | err = -EINVAL; | ||
459 | 460 | ||
460 | out_release_res: | 461 | out_release_res: |
461 | altera_pcie_release_of_pci_ranges(pcie); | 462 | pci_free_resource_list(&pcie->resources); |
462 | return err; | 463 | return err; |
463 | } | 464 | } |
464 | 465 | ||
diff --git a/drivers/pci/host/pcie-armada8k.c b/drivers/pci/host/pcie-armada8k.c index 55723567b5d4..0f4f570068e3 100644 --- a/drivers/pci/host/pcie-armada8k.c +++ b/drivers/pci/host/pcie-armada8k.c | |||
@@ -5,6 +5,9 @@ | |||
5 | * | 5 | * |
6 | * Copyright (C) 2016 Marvell Technology Group Ltd. | 6 | * Copyright (C) 2016 Marvell Technology Group Ltd. |
7 | * | 7 | * |
8 | * Author: Yehuda Yitshak <yehuday@marvell.com> | ||
9 | * Author: Shadi Ammouri <shadi@marvell.com> | ||
10 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | 11 | * This file is licensed under the terms of the GNU General Public |
9 | * License version 2. This program is licensed "as is" without any | 12 | * License version 2. This program is licensed "as is" without any |
10 | * warranty of any kind, whether express or implied. | 13 | * warranty of any kind, whether express or implied. |
@@ -14,7 +17,7 @@ | |||
14 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
15 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
16 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | 20 | #include <linux/init.h> |
18 | #include <linux/of.h> | 21 | #include <linux/of.h> |
19 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
20 | #include <linux/phy/phy.h> | 23 | #include <linux/phy/phy.h> |
@@ -244,7 +247,6 @@ static const struct of_device_id armada8k_pcie_of_match[] = { | |||
244 | { .compatible = "marvell,armada8k-pcie", }, | 247 | { .compatible = "marvell,armada8k-pcie", }, |
245 | {}, | 248 | {}, |
246 | }; | 249 | }; |
247 | MODULE_DEVICE_TABLE(of, armada8k_pcie_of_match); | ||
248 | 250 | ||
249 | static struct platform_driver armada8k_pcie_driver = { | 251 | static struct platform_driver armada8k_pcie_driver = { |
250 | .probe = armada8k_pcie_probe, | 252 | .probe = armada8k_pcie_probe, |
@@ -253,10 +255,4 @@ static struct platform_driver armada8k_pcie_driver = { | |||
253 | .of_match_table = of_match_ptr(armada8k_pcie_of_match), | 255 | .of_match_table = of_match_ptr(armada8k_pcie_of_match), |
254 | }, | 256 | }, |
255 | }; | 257 | }; |
256 | 258 | builtin_platform_driver(armada8k_pcie_driver); | |
257 | module_platform_driver(armada8k_pcie_driver); | ||
258 | |||
259 | MODULE_DESCRIPTION("Armada 8k PCIe host controller driver"); | ||
260 | MODULE_AUTHOR("Yehuda Yitshak <yehuday@marvell.com>"); | ||
261 | MODULE_AUTHOR("Shadi Ammouri <shadi@marvell.com>"); | ||
262 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pcie-artpec6.c b/drivers/pci/host/pcie-artpec6.c new file mode 100644 index 000000000000..16ba70b7ec65 --- /dev/null +++ b/drivers/pci/host/pcie-artpec6.c | |||
@@ -0,0 +1,280 @@ | |||
1 | /* | ||
2 | * PCIe host controller driver for Axis ARTPEC-6 SoC | ||
3 | * | ||
4 | * Author: Niklas Cassel <niklas.cassel@axis.com> | ||
5 | * | ||
6 | * Based on work done by Phil Edworthy <phil@edworthys.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/delay.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/pci.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/resource.h> | ||
19 | #include <linux/signal.h> | ||
20 | #include <linux/types.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/mfd/syscon.h> | ||
23 | #include <linux/regmap.h> | ||
24 | |||
25 | #include "pcie-designware.h" | ||
26 | |||
27 | #define to_artpec6_pcie(x) container_of(x, struct artpec6_pcie, pp) | ||
28 | |||
29 | struct artpec6_pcie { | ||
30 | struct pcie_port pp; | ||
31 | struct regmap *regmap; | ||
32 | void __iomem *phy_base; | ||
33 | }; | ||
34 | |||
35 | /* PCIe Port Logic registers (memory-mapped) */ | ||
36 | #define PL_OFFSET 0x700 | ||
37 | #define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28) | ||
38 | #define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c) | ||
39 | |||
40 | #define MISC_CONTROL_1_OFF (PL_OFFSET + 0x1bc) | ||
41 | #define DBI_RO_WR_EN 1 | ||
42 | |||
43 | /* ARTPEC-6 specific registers */ | ||
44 | #define PCIECFG 0x18 | ||
45 | #define PCIECFG_DBG_OEN (1 << 24) | ||
46 | #define PCIECFG_CORE_RESET_REQ (1 << 21) | ||
47 | #define PCIECFG_LTSSM_ENABLE (1 << 20) | ||
48 | #define PCIECFG_CLKREQ_B (1 << 11) | ||
49 | #define PCIECFG_REFCLK_ENABLE (1 << 10) | ||
50 | #define PCIECFG_PLL_ENABLE (1 << 9) | ||
51 | #define PCIECFG_PCLK_ENABLE (1 << 8) | ||
52 | #define PCIECFG_RISRCREN (1 << 4) | ||
53 | #define PCIECFG_MODE_TX_DRV_EN (1 << 3) | ||
54 | #define PCIECFG_CISRREN (1 << 2) | ||
55 | #define PCIECFG_MACRO_ENABLE (1 << 0) | ||
56 | |||
57 | #define NOCCFG 0x40 | ||
58 | #define NOCCFG_ENABLE_CLK_PCIE (1 << 4) | ||
59 | #define NOCCFG_POWER_PCIE_IDLEACK (1 << 3) | ||
60 | #define NOCCFG_POWER_PCIE_IDLE (1 << 2) | ||
61 | #define NOCCFG_POWER_PCIE_IDLEREQ (1 << 1) | ||
62 | |||
63 | #define PHY_STATUS 0x118 | ||
64 | #define PHY_COSPLLLOCK (1 << 0) | ||
65 | |||
66 | #define ARTPEC6_CPU_TO_BUS_ADDR 0x0fffffff | ||
67 | |||
68 | static int artpec6_pcie_establish_link(struct pcie_port *pp) | ||
69 | { | ||
70 | struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pp); | ||
71 | u32 val; | ||
72 | unsigned int retries; | ||
73 | |||
74 | /* Hold DW core in reset */ | ||
75 | regmap_read(artpec6_pcie->regmap, PCIECFG, &val); | ||
76 | val |= PCIECFG_CORE_RESET_REQ; | ||
77 | regmap_write(artpec6_pcie->regmap, PCIECFG, val); | ||
78 | |||
79 | regmap_read(artpec6_pcie->regmap, PCIECFG, &val); | ||
80 | val |= PCIECFG_RISRCREN | /* Receiver term. 50 Ohm */ | ||
81 | PCIECFG_MODE_TX_DRV_EN | | ||
82 | PCIECFG_CISRREN | /* Reference clock term. 100 Ohm */ | ||
83 | PCIECFG_MACRO_ENABLE; | ||
84 | val |= PCIECFG_REFCLK_ENABLE; | ||
85 | val &= ~PCIECFG_DBG_OEN; | ||
86 | val &= ~PCIECFG_CLKREQ_B; | ||
87 | regmap_write(artpec6_pcie->regmap, PCIECFG, val); | ||
88 | usleep_range(5000, 6000); | ||
89 | |||
90 | regmap_read(artpec6_pcie->regmap, NOCCFG, &val); | ||
91 | val |= NOCCFG_ENABLE_CLK_PCIE; | ||
92 | regmap_write(artpec6_pcie->regmap, NOCCFG, val); | ||
93 | usleep_range(20, 30); | ||
94 | |||
95 | regmap_read(artpec6_pcie->regmap, PCIECFG, &val); | ||
96 | val |= PCIECFG_PCLK_ENABLE | PCIECFG_PLL_ENABLE; | ||
97 | regmap_write(artpec6_pcie->regmap, PCIECFG, val); | ||
98 | usleep_range(6000, 7000); | ||
99 | |||
100 | regmap_read(artpec6_pcie->regmap, NOCCFG, &val); | ||
101 | val &= ~NOCCFG_POWER_PCIE_IDLEREQ; | ||
102 | regmap_write(artpec6_pcie->regmap, NOCCFG, val); | ||
103 | |||
104 | retries = 50; | ||
105 | do { | ||
106 | usleep_range(1000, 2000); | ||
107 | regmap_read(artpec6_pcie->regmap, NOCCFG, &val); | ||
108 | retries--; | ||
109 | } while (retries && | ||
110 | (val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE))); | ||
111 | |||
112 | retries = 50; | ||
113 | do { | ||
114 | usleep_range(1000, 2000); | ||
115 | val = readl(artpec6_pcie->phy_base + PHY_STATUS); | ||
116 | retries--; | ||
117 | } while (retries && !(val & PHY_COSPLLLOCK)); | ||
118 | |||
119 | /* Take DW core out of reset */ | ||
120 | regmap_read(artpec6_pcie->regmap, PCIECFG, &val); | ||
121 | val &= ~PCIECFG_CORE_RESET_REQ; | ||
122 | regmap_write(artpec6_pcie->regmap, PCIECFG, val); | ||
123 | usleep_range(100, 200); | ||
124 | |||
125 | /* | ||
126 | * Enable writing to config regs. This is required as the Synopsys | ||
127 | * driver changes the class code. That register needs DBI write enable. | ||
128 | */ | ||
129 | writel(DBI_RO_WR_EN, pp->dbi_base + MISC_CONTROL_1_OFF); | ||
130 | |||
131 | pp->io_base &= ARTPEC6_CPU_TO_BUS_ADDR; | ||
132 | pp->mem_base &= ARTPEC6_CPU_TO_BUS_ADDR; | ||
133 | pp->cfg0_base &= ARTPEC6_CPU_TO_BUS_ADDR; | ||
134 | pp->cfg1_base &= ARTPEC6_CPU_TO_BUS_ADDR; | ||
135 | |||
136 | /* setup root complex */ | ||
137 | dw_pcie_setup_rc(pp); | ||
138 | |||
139 | /* assert LTSSM enable */ | ||
140 | regmap_read(artpec6_pcie->regmap, PCIECFG, &val); | ||
141 | val |= PCIECFG_LTSSM_ENABLE; | ||
142 | regmap_write(artpec6_pcie->regmap, PCIECFG, val); | ||
143 | |||
144 | /* check if the link is up or not */ | ||
145 | if (!dw_pcie_wait_for_link(pp)) | ||
146 | return 0; | ||
147 | |||
148 | dev_dbg(pp->dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n", | ||
149 | readl(pp->dbi_base + PCIE_PHY_DEBUG_R0), | ||
150 | readl(pp->dbi_base + PCIE_PHY_DEBUG_R1)); | ||
151 | |||
152 | return -ETIMEDOUT; | ||
153 | } | ||
154 | |||
155 | static void artpec6_pcie_enable_interrupts(struct pcie_port *pp) | ||
156 | { | ||
157 | if (IS_ENABLED(CONFIG_PCI_MSI)) | ||
158 | dw_pcie_msi_init(pp); | ||
159 | } | ||
160 | |||
161 | static void artpec6_pcie_host_init(struct pcie_port *pp) | ||
162 | { | ||
163 | artpec6_pcie_establish_link(pp); | ||
164 | artpec6_pcie_enable_interrupts(pp); | ||
165 | } | ||
166 | |||
167 | static int artpec6_pcie_link_up(struct pcie_port *pp) | ||
168 | { | ||
169 | u32 rc; | ||
170 | |||
171 | /* | ||
172 | * Get status from Synopsys IP | ||
173 | * link is debug bit 36, debug register 1 starts at bit 32 | ||
174 | */ | ||
175 | rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1) & (0x1 << (36 - 32)); | ||
176 | if (rc) | ||
177 | return 1; | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static struct pcie_host_ops artpec6_pcie_host_ops = { | ||
183 | .link_up = artpec6_pcie_link_up, | ||
184 | .host_init = artpec6_pcie_host_init, | ||
185 | }; | ||
186 | |||
187 | static irqreturn_t artpec6_pcie_msi_handler(int irq, void *arg) | ||
188 | { | ||
189 | struct pcie_port *pp = arg; | ||
190 | |||
191 | return dw_handle_msi_irq(pp); | ||
192 | } | ||
193 | |||
194 | static int __init artpec6_add_pcie_port(struct pcie_port *pp, | ||
195 | struct platform_device *pdev) | ||
196 | { | ||
197 | int ret; | ||
198 | |||
199 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | ||
200 | pp->msi_irq = platform_get_irq_byname(pdev, "msi"); | ||
201 | if (pp->msi_irq <= 0) { | ||
202 | dev_err(&pdev->dev, "failed to get MSI irq\n"); | ||
203 | return -ENODEV; | ||
204 | } | ||
205 | |||
206 | ret = devm_request_irq(&pdev->dev, pp->msi_irq, | ||
207 | artpec6_pcie_msi_handler, | ||
208 | IRQF_SHARED | IRQF_NO_THREAD, | ||
209 | "artpec6-pcie-msi", pp); | ||
210 | if (ret) { | ||
211 | dev_err(&pdev->dev, "failed to request MSI irq\n"); | ||
212 | return ret; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | pp->root_bus_nr = -1; | ||
217 | pp->ops = &artpec6_pcie_host_ops; | ||
218 | |||
219 | ret = dw_pcie_host_init(pp); | ||
220 | if (ret) { | ||
221 | dev_err(&pdev->dev, "failed to initialize host\n"); | ||
222 | return ret; | ||
223 | } | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | static int artpec6_pcie_probe(struct platform_device *pdev) | ||
229 | { | ||
230 | struct artpec6_pcie *artpec6_pcie; | ||
231 | struct pcie_port *pp; | ||
232 | struct resource *dbi_base; | ||
233 | struct resource *phy_base; | ||
234 | int ret; | ||
235 | |||
236 | artpec6_pcie = devm_kzalloc(&pdev->dev, sizeof(*artpec6_pcie), | ||
237 | GFP_KERNEL); | ||
238 | if (!artpec6_pcie) | ||
239 | return -ENOMEM; | ||
240 | |||
241 | pp = &artpec6_pcie->pp; | ||
242 | pp->dev = &pdev->dev; | ||
243 | |||
244 | dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); | ||
245 | pp->dbi_base = devm_ioremap_resource(&pdev->dev, dbi_base); | ||
246 | if (IS_ERR(pp->dbi_base)) | ||
247 | return PTR_ERR(pp->dbi_base); | ||
248 | |||
249 | phy_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy"); | ||
250 | artpec6_pcie->phy_base = devm_ioremap_resource(&pdev->dev, phy_base); | ||
251 | if (IS_ERR(artpec6_pcie->phy_base)) | ||
252 | return PTR_ERR(artpec6_pcie->phy_base); | ||
253 | |||
254 | artpec6_pcie->regmap = | ||
255 | syscon_regmap_lookup_by_phandle(pdev->dev.of_node, | ||
256 | "axis,syscon-pcie"); | ||
257 | if (IS_ERR(artpec6_pcie->regmap)) | ||
258 | return PTR_ERR(artpec6_pcie->regmap); | ||
259 | |||
260 | ret = artpec6_add_pcie_port(pp, pdev); | ||
261 | if (ret < 0) | ||
262 | return ret; | ||
263 | |||
264 | platform_set_drvdata(pdev, artpec6_pcie); | ||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static const struct of_device_id artpec6_pcie_of_match[] = { | ||
269 | { .compatible = "axis,artpec6-pcie", }, | ||
270 | {}, | ||
271 | }; | ||
272 | |||
273 | static struct platform_driver artpec6_pcie_driver = { | ||
274 | .probe = artpec6_pcie_probe, | ||
275 | .driver = { | ||
276 | .name = "artpec6-pcie", | ||
277 | .of_match_table = artpec6_pcie_of_match, | ||
278 | }, | ||
279 | }; | ||
280 | builtin_platform_driver(artpec6_pcie_driver); | ||
diff --git a/drivers/pci/host/pcie-designware-plat.c b/drivers/pci/host/pcie-designware-plat.c index b3500994d08a..c8079dc81c10 100644 --- a/drivers/pci/host/pcie-designware-plat.c +++ b/drivers/pci/host/pcie-designware-plat.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/gpio.h> | 14 | #include <linux/gpio.h> |
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | 17 | #include <linux/init.h> |
18 | #include <linux/of_gpio.h> | 18 | #include <linux/of_gpio.h> |
19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
@@ -121,7 +121,6 @@ static const struct of_device_id dw_plat_pcie_of_match[] = { | |||
121 | { .compatible = "snps,dw-pcie", }, | 121 | { .compatible = "snps,dw-pcie", }, |
122 | {}, | 122 | {}, |
123 | }; | 123 | }; |
124 | MODULE_DEVICE_TABLE(of, dw_plat_pcie_of_match); | ||
125 | 124 | ||
126 | static struct platform_driver dw_plat_pcie_driver = { | 125 | static struct platform_driver dw_plat_pcie_driver = { |
127 | .driver = { | 126 | .driver = { |
@@ -130,9 +129,4 @@ static struct platform_driver dw_plat_pcie_driver = { | |||
130 | }, | 129 | }, |
131 | .probe = dw_plat_pcie_probe, | 130 | .probe = dw_plat_pcie_probe, |
132 | }; | 131 | }; |
133 | 132 | builtin_platform_driver(dw_plat_pcie_driver); | |
134 | module_platform_driver(dw_plat_pcie_driver); | ||
135 | |||
136 | MODULE_AUTHOR("Joao Pinto <Joao.Pinto@synopsys.com>"); | ||
137 | MODULE_DESCRIPTION("Synopsys PCIe host controller glue platform driver"); | ||
138 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index aafd766546f3..12afce19890b 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c | |||
@@ -452,6 +452,10 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
452 | if (ret) | 452 | if (ret) |
453 | return ret; | 453 | return ret; |
454 | 454 | ||
455 | ret = devm_request_pci_bus_resources(&pdev->dev, &res); | ||
456 | if (ret) | ||
457 | goto error; | ||
458 | |||
455 | /* Get the I/O and memory ranges from DT */ | 459 | /* Get the I/O and memory ranges from DT */ |
456 | resource_list_for_each_entry(win, &res) { | 460 | resource_list_for_each_entry(win, &res) { |
457 | switch (resource_type(win->res)) { | 461 | switch (resource_type(win->res)) { |
@@ -461,11 +465,9 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
461 | pp->io_size = resource_size(pp->io); | 465 | pp->io_size = resource_size(pp->io); |
462 | pp->io_bus_addr = pp->io->start - win->offset; | 466 | pp->io_bus_addr = pp->io->start - win->offset; |
463 | ret = pci_remap_iospace(pp->io, pp->io_base); | 467 | ret = pci_remap_iospace(pp->io, pp->io_base); |
464 | if (ret) { | 468 | if (ret) |
465 | dev_warn(pp->dev, "error %d: failed to map resource %pR\n", | 469 | dev_warn(pp->dev, "error %d: failed to map resource %pR\n", |
466 | ret, pp->io); | 470 | ret, pp->io); |
467 | continue; | ||
468 | } | ||
469 | break; | 471 | break; |
470 | case IORESOURCE_MEM: | 472 | case IORESOURCE_MEM: |
471 | pp->mem = win->res; | 473 | pp->mem = win->res; |
@@ -483,8 +485,6 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
483 | case IORESOURCE_BUS: | 485 | case IORESOURCE_BUS: |
484 | pp->busn = win->res; | 486 | pp->busn = win->res; |
485 | break; | 487 | break; |
486 | default: | ||
487 | continue; | ||
488 | } | 488 | } |
489 | } | 489 | } |
490 | 490 | ||
@@ -493,7 +493,8 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
493 | resource_size(pp->cfg)); | 493 | resource_size(pp->cfg)); |
494 | if (!pp->dbi_base) { | 494 | if (!pp->dbi_base) { |
495 | dev_err(pp->dev, "error with ioremap\n"); | 495 | dev_err(pp->dev, "error with ioremap\n"); |
496 | return -ENOMEM; | 496 | ret = -ENOMEM; |
497 | goto error; | ||
497 | } | 498 | } |
498 | } | 499 | } |
499 | 500 | ||
@@ -504,7 +505,8 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
504 | pp->cfg0_size); | 505 | pp->cfg0_size); |
505 | if (!pp->va_cfg0_base) { | 506 | if (!pp->va_cfg0_base) { |
506 | dev_err(pp->dev, "error with ioremap in function\n"); | 507 | dev_err(pp->dev, "error with ioremap in function\n"); |
507 | return -ENOMEM; | 508 | ret = -ENOMEM; |
509 | goto error; | ||
508 | } | 510 | } |
509 | } | 511 | } |
510 | 512 | ||
@@ -513,7 +515,8 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
513 | pp->cfg1_size); | 515 | pp->cfg1_size); |
514 | if (!pp->va_cfg1_base) { | 516 | if (!pp->va_cfg1_base) { |
515 | dev_err(pp->dev, "error with ioremap\n"); | 517 | dev_err(pp->dev, "error with ioremap\n"); |
516 | return -ENOMEM; | 518 | ret = -ENOMEM; |
519 | goto error; | ||
517 | } | 520 | } |
518 | } | 521 | } |
519 | 522 | ||
@@ -528,7 +531,8 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
528 | &dw_pcie_msi_chip); | 531 | &dw_pcie_msi_chip); |
529 | if (!pp->irq_domain) { | 532 | if (!pp->irq_domain) { |
530 | dev_err(pp->dev, "irq domain init failed\n"); | 533 | dev_err(pp->dev, "irq domain init failed\n"); |
531 | return -ENXIO; | 534 | ret = -ENXIO; |
535 | goto error; | ||
532 | } | 536 | } |
533 | 537 | ||
534 | for (i = 0; i < MAX_MSI_IRQS; i++) | 538 | for (i = 0; i < MAX_MSI_IRQS; i++) |
@@ -536,7 +540,7 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
536 | } else { | 540 | } else { |
537 | ret = pp->ops->msi_host_init(pp, &dw_pcie_msi_chip); | 541 | ret = pp->ops->msi_host_init(pp, &dw_pcie_msi_chip); |
538 | if (ret < 0) | 542 | if (ret < 0) |
539 | return ret; | 543 | goto error; |
540 | } | 544 | } |
541 | } | 545 | } |
542 | 546 | ||
@@ -552,8 +556,10 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
552 | } else | 556 | } else |
553 | bus = pci_scan_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops, | 557 | bus = pci_scan_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops, |
554 | pp, &res); | 558 | pp, &res); |
555 | if (!bus) | 559 | if (!bus) { |
556 | return -ENOMEM; | 560 | ret = -ENOMEM; |
561 | goto error; | ||
562 | } | ||
557 | 563 | ||
558 | if (pp->ops->scan_bus) | 564 | if (pp->ops->scan_bus) |
559 | pp->ops->scan_bus(pp); | 565 | pp->ops->scan_bus(pp); |
@@ -571,6 +577,10 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
571 | 577 | ||
572 | pci_bus_add_devices(bus); | 578 | pci_bus_add_devices(bus); |
573 | return 0; | 579 | return 0; |
580 | |||
581 | error: | ||
582 | pci_free_resource_list(&res); | ||
583 | return ret; | ||
574 | } | 584 | } |
575 | 585 | ||
576 | static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | 586 | static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, |
diff --git a/drivers/pci/host/pcie-hisi.c b/drivers/pci/host/pcie-hisi.c index 3e98d4edae2d..7ee9dfcc45fb 100644 --- a/drivers/pci/host/pcie-hisi.c +++ b/drivers/pci/host/pcie-hisi.c | |||
@@ -12,7 +12,7 @@ | |||
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/module.h> | 15 | #include <linux/init.h> |
16 | #include <linux/mfd/syscon.h> | 16 | #include <linux/mfd/syscon.h> |
17 | #include <linux/of_address.h> | 17 | #include <linux/of_address.h> |
18 | #include <linux/of_pci.h> | 18 | #include <linux/of_pci.h> |
@@ -235,9 +235,6 @@ static const struct of_device_id hisi_pcie_of_match[] = { | |||
235 | {}, | 235 | {}, |
236 | }; | 236 | }; |
237 | 237 | ||
238 | |||
239 | MODULE_DEVICE_TABLE(of, hisi_pcie_of_match); | ||
240 | |||
241 | static struct platform_driver hisi_pcie_driver = { | 238 | static struct platform_driver hisi_pcie_driver = { |
242 | .probe = hisi_pcie_probe, | 239 | .probe = hisi_pcie_probe, |
243 | .driver = { | 240 | .driver = { |
@@ -245,10 +242,4 @@ static struct platform_driver hisi_pcie_driver = { | |||
245 | .of_match_table = hisi_pcie_of_match, | 242 | .of_match_table = hisi_pcie_of_match, |
246 | }, | 243 | }, |
247 | }; | 244 | }; |
248 | 245 | builtin_platform_driver(hisi_pcie_driver); | |
249 | module_platform_driver(hisi_pcie_driver); | ||
250 | |||
251 | MODULE_AUTHOR("Zhou Wang <wangzhou1@hisilicon.com>"); | ||
252 | MODULE_AUTHOR("Dacai Zhu <zhudacai@hisilicon.com>"); | ||
253 | MODULE_AUTHOR("Gabriele Paoloni <gabriele.paoloni@huawei.com>"); | ||
254 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c index a576aeeb22da..e167b2f0098d 100644 --- a/drivers/pci/host/pcie-iproc.c +++ b/drivers/pci/host/pcie-iproc.c | |||
@@ -462,6 +462,10 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) | |||
462 | if (!pcie || !pcie->dev || !pcie->base) | 462 | if (!pcie || !pcie->dev || !pcie->base) |
463 | return -EINVAL; | 463 | return -EINVAL; |
464 | 464 | ||
465 | ret = devm_request_pci_bus_resources(pcie->dev, res); | ||
466 | if (ret) | ||
467 | return ret; | ||
468 | |||
465 | ret = phy_init(pcie->phy); | 469 | ret = phy_init(pcie->phy); |
466 | if (ret) { | 470 | if (ret) { |
467 | dev_err(pcie->dev, "unable to initialize PCIe PHY\n"); | 471 | dev_err(pcie->dev, "unable to initialize PCIe PHY\n"); |
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 35092188039b..65db7a221509 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c | |||
@@ -7,6 +7,8 @@ | |||
7 | * arch/sh/drivers/pci/ops-sh7786.c | 7 | * arch/sh/drivers/pci/ops-sh7786.c |
8 | * Copyright (C) 2009 - 2011 Paul Mundt | 8 | * Copyright (C) 2009 - 2011 Paul Mundt |
9 | * | 9 | * |
10 | * Author: Phil Edworthy <phil.edworthy@renesas.com> | ||
11 | * | ||
10 | * This file is licensed under the terms of the GNU General Public | 12 | * This file is licensed under the terms of the GNU General Public |
11 | * License version 2. This program is licensed "as is" without any | 13 | * License version 2. This program is licensed "as is" without any |
12 | * warranty of any kind, whether express or implied. | 14 | * warranty of any kind, whether express or implied. |
@@ -18,7 +20,7 @@ | |||
18 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
19 | #include <linux/irqdomain.h> | 21 | #include <linux/irqdomain.h> |
20 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | 23 | #include <linux/init.h> |
22 | #include <linux/msi.h> | 24 | #include <linux/msi.h> |
23 | #include <linux/of_address.h> | 25 | #include <linux/of_address.h> |
24 | #include <linux/of_irq.h> | 26 | #include <linux/of_irq.h> |
@@ -936,12 +938,6 @@ static const struct of_device_id rcar_pcie_of_match[] = { | |||
936 | { .compatible = "renesas,pcie-r8a7795", .data = rcar_pcie_hw_init }, | 938 | { .compatible = "renesas,pcie-r8a7795", .data = rcar_pcie_hw_init }, |
937 | {}, | 939 | {}, |
938 | }; | 940 | }; |
939 | MODULE_DEVICE_TABLE(of, rcar_pcie_of_match); | ||
940 | |||
941 | static void rcar_pcie_release_of_pci_ranges(struct rcar_pcie *pci) | ||
942 | { | ||
943 | pci_free_resource_list(&pci->resources); | ||
944 | } | ||
945 | 941 | ||
946 | static int rcar_pcie_parse_request_of_pci_ranges(struct rcar_pcie *pci) | 942 | static int rcar_pcie_parse_request_of_pci_ranges(struct rcar_pcie *pci) |
947 | { | 943 | { |
@@ -955,37 +951,25 @@ static int rcar_pcie_parse_request_of_pci_ranges(struct rcar_pcie *pci) | |||
955 | if (err) | 951 | if (err) |
956 | return err; | 952 | return err; |
957 | 953 | ||
954 | err = devm_request_pci_bus_resources(dev, &pci->resources); | ||
955 | if (err) | ||
956 | goto out_release_res; | ||
957 | |||
958 | resource_list_for_each_entry(win, &pci->resources) { | 958 | resource_list_for_each_entry(win, &pci->resources) { |
959 | struct resource *parent, *res = win->res; | 959 | struct resource *res = win->res; |
960 | 960 | ||
961 | switch (resource_type(res)) { | 961 | if (resource_type(res) == IORESOURCE_IO) { |
962 | case IORESOURCE_IO: | ||
963 | parent = &ioport_resource; | ||
964 | err = pci_remap_iospace(res, iobase); | 962 | err = pci_remap_iospace(res, iobase); |
965 | if (err) { | 963 | if (err) |
966 | dev_warn(dev, "error %d: failed to map resource %pR\n", | 964 | dev_warn(dev, "error %d: failed to map resource %pR\n", |
967 | err, res); | 965 | err, res); |
968 | continue; | ||
969 | } | ||
970 | break; | ||
971 | case IORESOURCE_MEM: | ||
972 | parent = &iomem_resource; | ||
973 | break; | ||
974 | |||
975 | case IORESOURCE_BUS: | ||
976 | default: | ||
977 | continue; | ||
978 | } | 966 | } |
979 | |||
980 | err = devm_request_resource(dev, parent, res); | ||
981 | if (err) | ||
982 | goto out_release_res; | ||
983 | } | 967 | } |
984 | 968 | ||
985 | return 0; | 969 | return 0; |
986 | 970 | ||
987 | out_release_res: | 971 | out_release_res: |
988 | rcar_pcie_release_of_pci_ranges(pci); | 972 | pci_free_resource_list(&pci->resources); |
989 | return err; | 973 | return err; |
990 | } | 974 | } |
991 | 975 | ||
@@ -1073,8 +1057,4 @@ static struct platform_driver rcar_pcie_driver = { | |||
1073 | }, | 1057 | }, |
1074 | .probe = rcar_pcie_probe, | 1058 | .probe = rcar_pcie_probe, |
1075 | }; | 1059 | }; |
1076 | module_platform_driver(rcar_pcie_driver); | 1060 | builtin_platform_driver(rcar_pcie_driver); |
1077 | |||
1078 | MODULE_AUTHOR("Phil Edworthy <phil.edworthy@renesas.com>"); | ||
1079 | MODULE_DESCRIPTION("Renesas R-Car PCIe driver"); | ||
1080 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pci/host/pcie-xilinx-nwl.c b/drivers/pci/host/pcie-xilinx-nwl.c index 3479d30e2be8..0b597d9190b4 100644 --- a/drivers/pci/host/pcie-xilinx-nwl.c +++ b/drivers/pci/host/pcie-xilinx-nwl.c | |||
@@ -825,27 +825,33 @@ static int nwl_pcie_probe(struct platform_device *pdev) | |||
825 | 825 | ||
826 | err = of_pci_get_host_bridge_resources(node, 0, 0xff, &res, &iobase); | 826 | err = of_pci_get_host_bridge_resources(node, 0, 0xff, &res, &iobase); |
827 | if (err) { | 827 | if (err) { |
828 | pr_err("Getting bridge resources failed\n"); | 828 | dev_err(pcie->dev, "Getting bridge resources failed\n"); |
829 | return err; | 829 | return err; |
830 | } | 830 | } |
831 | 831 | ||
832 | err = devm_request_pci_bus_resources(pcie->dev, &res); | ||
833 | if (err) | ||
834 | goto error; | ||
835 | |||
832 | err = nwl_pcie_init_irq_domain(pcie); | 836 | err = nwl_pcie_init_irq_domain(pcie); |
833 | if (err) { | 837 | if (err) { |
834 | dev_err(pcie->dev, "Failed creating IRQ Domain\n"); | 838 | dev_err(pcie->dev, "Failed creating IRQ Domain\n"); |
835 | return err; | 839 | goto error; |
836 | } | 840 | } |
837 | 841 | ||
838 | bus = pci_create_root_bus(&pdev->dev, pcie->root_busno, | 842 | bus = pci_create_root_bus(&pdev->dev, pcie->root_busno, |
839 | &nwl_pcie_ops, pcie, &res); | 843 | &nwl_pcie_ops, pcie, &res); |
840 | if (!bus) | 844 | if (!bus) { |
841 | return -ENOMEM; | 845 | err = -ENOMEM; |
846 | goto error; | ||
847 | } | ||
842 | 848 | ||
843 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | 849 | if (IS_ENABLED(CONFIG_PCI_MSI)) { |
844 | err = nwl_pcie_enable_msi(pcie, bus); | 850 | err = nwl_pcie_enable_msi(pcie, bus); |
845 | if (err < 0) { | 851 | if (err < 0) { |
846 | dev_err(&pdev->dev, | 852 | dev_err(&pdev->dev, |
847 | "failed to enable MSI support: %d\n", err); | 853 | "failed to enable MSI support: %d\n", err); |
848 | return err; | 854 | goto error; |
849 | } | 855 | } |
850 | } | 856 | } |
851 | pci_scan_child_bus(bus); | 857 | pci_scan_child_bus(bus); |
@@ -855,6 +861,10 @@ static int nwl_pcie_probe(struct platform_device *pdev) | |||
855 | pci_bus_add_devices(bus); | 861 | pci_bus_add_devices(bus); |
856 | platform_set_drvdata(pdev, pcie); | 862 | platform_set_drvdata(pdev, pcie); |
857 | return 0; | 863 | return 0; |
864 | |||
865 | error: | ||
866 | pci_free_resource_list(&res); | ||
867 | return err; | ||
858 | } | 868 | } |
859 | 869 | ||
860 | static int nwl_pcie_remove(struct platform_device *pdev) | 870 | static int nwl_pcie_remove(struct platform_device *pdev) |
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c index 65f0fe0c2eaf..a30e01639557 100644 --- a/drivers/pci/host/pcie-xilinx.c +++ b/drivers/pci/host/pcie-xilinx.c | |||
@@ -550,7 +550,7 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port) | |||
550 | pcie_intc_node = of_get_next_child(node, NULL); | 550 | pcie_intc_node = of_get_next_child(node, NULL); |
551 | if (!pcie_intc_node) { | 551 | if (!pcie_intc_node) { |
552 | dev_err(dev, "No PCIe Intc node found\n"); | 552 | dev_err(dev, "No PCIe Intc node found\n"); |
553 | return PTR_ERR(pcie_intc_node); | 553 | return -ENODEV; |
554 | } | 554 | } |
555 | 555 | ||
556 | port->irq_domain = irq_domain_add_linear(pcie_intc_node, 4, | 556 | port->irq_domain = irq_domain_add_linear(pcie_intc_node, 4, |
@@ -558,7 +558,7 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port) | |||
558 | port); | 558 | port); |
559 | if (!port->irq_domain) { | 559 | if (!port->irq_domain) { |
560 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); | 560 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); |
561 | return PTR_ERR(port->irq_domain); | 561 | return -ENODEV; |
562 | } | 562 | } |
563 | 563 | ||
564 | /* Setup MSI */ | 564 | /* Setup MSI */ |
@@ -569,7 +569,7 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port) | |||
569 | &xilinx_pcie_msi_chip); | 569 | &xilinx_pcie_msi_chip); |
570 | if (!port->irq_domain) { | 570 | if (!port->irq_domain) { |
571 | dev_err(dev, "Failed to get a MSI IRQ domain\n"); | 571 | dev_err(dev, "Failed to get a MSI IRQ domain\n"); |
572 | return PTR_ERR(port->irq_domain); | 572 | return -ENODEV; |
573 | } | 573 | } |
574 | 574 | ||
575 | xilinx_pcie_enable_msi(port); | 575 | xilinx_pcie_enable_msi(port); |
@@ -660,7 +660,6 @@ static int xilinx_pcie_probe(struct platform_device *pdev) | |||
660 | struct xilinx_pcie_port *port; | 660 | struct xilinx_pcie_port *port; |
661 | struct device *dev = &pdev->dev; | 661 | struct device *dev = &pdev->dev; |
662 | struct pci_bus *bus; | 662 | struct pci_bus *bus; |
663 | |||
664 | int err; | 663 | int err; |
665 | resource_size_t iobase = 0; | 664 | resource_size_t iobase = 0; |
666 | LIST_HEAD(res); | 665 | LIST_HEAD(res); |
@@ -694,10 +693,17 @@ static int xilinx_pcie_probe(struct platform_device *pdev) | |||
694 | dev_err(dev, "Getting bridge resources failed\n"); | 693 | dev_err(dev, "Getting bridge resources failed\n"); |
695 | return err; | 694 | return err; |
696 | } | 695 | } |
696 | |||
697 | err = devm_request_pci_bus_resources(dev, &res); | ||
698 | if (err) | ||
699 | goto error; | ||
700 | |||
697 | bus = pci_create_root_bus(&pdev->dev, 0, | 701 | bus = pci_create_root_bus(&pdev->dev, 0, |
698 | &xilinx_pcie_ops, port, &res); | 702 | &xilinx_pcie_ops, port, &res); |
699 | if (!bus) | 703 | if (!bus) { |
700 | return -ENOMEM; | 704 | err = -ENOMEM; |
705 | goto error; | ||
706 | } | ||
701 | 707 | ||
702 | #ifdef CONFIG_PCI_MSI | 708 | #ifdef CONFIG_PCI_MSI |
703 | xilinx_pcie_msi_chip.dev = port->dev; | 709 | xilinx_pcie_msi_chip.dev = port->dev; |
@@ -712,6 +718,10 @@ static int xilinx_pcie_probe(struct platform_device *pdev) | |||
712 | platform_set_drvdata(pdev, port); | 718 | platform_set_drvdata(pdev, port); |
713 | 719 | ||
714 | return 0; | 720 | return 0; |
721 | |||
722 | error: | ||
723 | pci_free_resource_list(&res); | ||
724 | return err; | ||
715 | } | 725 | } |
716 | 726 | ||
717 | /** | 727 | /** |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index fa49f9143b80..6a33ddcfa20b 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -675,6 +675,8 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge) | |||
675 | if (bridge->is_going_away) | 675 | if (bridge->is_going_away) |
676 | return; | 676 | return; |
677 | 677 | ||
678 | pm_runtime_get_sync(&bridge->pci_dev->dev); | ||
679 | |||
678 | list_for_each_entry(slot, &bridge->slots, node) { | 680 | list_for_each_entry(slot, &bridge->slots, node) { |
679 | struct pci_bus *bus = slot->bus; | 681 | struct pci_bus *bus = slot->bus; |
680 | struct pci_dev *dev, *tmp; | 682 | struct pci_dev *dev, *tmp; |
@@ -694,6 +696,8 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge) | |||
694 | disable_slot(slot); | 696 | disable_slot(slot); |
695 | } | 697 | } |
696 | } | 698 | } |
699 | |||
700 | pm_runtime_put(&bridge->pci_dev->dev); | ||
697 | } | 701 | } |
698 | 702 | ||
699 | /* | 703 | /* |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 5c24e938042f..08e84d61874e 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -546,6 +546,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
546 | u8 present; | 546 | u8 present; |
547 | bool link; | 547 | bool link; |
548 | 548 | ||
549 | /* Interrupts cannot originate from a controller that's asleep */ | ||
550 | if (pdev->current_state == PCI_D3cold) | ||
551 | return IRQ_NONE; | ||
552 | |||
549 | /* | 553 | /* |
550 | * In order to guarantee that all interrupt events are | 554 | * In order to guarantee that all interrupt events are |
551 | * serviced, we need to re-inspect Slot Status register after | 555 | * serviced, we need to re-inspect Slot Status register after |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index d7ffd66814bb..e39a67c8ef39 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -777,7 +777,7 @@ static int pci_pm_suspend_noirq(struct device *dev) | |||
777 | 777 | ||
778 | if (!pci_dev->state_saved) { | 778 | if (!pci_dev->state_saved) { |
779 | pci_save_state(pci_dev); | 779 | pci_save_state(pci_dev); |
780 | if (!pci_has_subordinate(pci_dev)) | 780 | if (pci_power_manageable(pci_dev)) |
781 | pci_prepare_to_sleep(pci_dev); | 781 | pci_prepare_to_sleep(pci_dev); |
782 | } | 782 | } |
783 | 783 | ||
@@ -1144,7 +1144,6 @@ static int pci_pm_runtime_suspend(struct device *dev) | |||
1144 | return -ENOSYS; | 1144 | return -ENOSYS; |
1145 | 1145 | ||
1146 | pci_dev->state_saved = false; | 1146 | pci_dev->state_saved = false; |
1147 | pci_dev->no_d3cold = false; | ||
1148 | error = pm->runtime_suspend(dev); | 1147 | error = pm->runtime_suspend(dev); |
1149 | if (error) { | 1148 | if (error) { |
1150 | /* | 1149 | /* |
@@ -1161,8 +1160,6 @@ static int pci_pm_runtime_suspend(struct device *dev) | |||
1161 | 1160 | ||
1162 | return error; | 1161 | return error; |
1163 | } | 1162 | } |
1164 | if (!pci_dev->d3cold_allowed) | ||
1165 | pci_dev->no_d3cold = true; | ||
1166 | 1163 | ||
1167 | pci_fixup_device(pci_fixup_suspend, pci_dev); | 1164 | pci_fixup_device(pci_fixup_suspend, pci_dev); |
1168 | 1165 | ||
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index d319a9ca9b7b..bcd10c795284 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -406,6 +406,11 @@ static ssize_t d3cold_allowed_store(struct device *dev, | |||
406 | return -EINVAL; | 406 | return -EINVAL; |
407 | 407 | ||
408 | pdev->d3cold_allowed = !!val; | 408 | pdev->d3cold_allowed = !!val; |
409 | if (pdev->d3cold_allowed) | ||
410 | pci_d3cold_enable(pdev); | ||
411 | else | ||
412 | pci_d3cold_disable(pdev); | ||
413 | |||
409 | pm_runtime_resume(dev); | 414 | pm_runtime_resume(dev); |
410 | 415 | ||
411 | return count; | 416 | return count; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index c8b4dbdd1bdd..9a6bc77ce3aa 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -7,8 +7,10 @@ | |||
7 | * Copyright 1997 -- 2000 Martin Mares <mj@ucw.cz> | 7 | * Copyright 1997 -- 2000 Martin Mares <mj@ucw.cz> |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/acpi.h> | ||
10 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
11 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
13 | #include <linux/dmi.h> | ||
12 | #include <linux/init.h> | 14 | #include <linux/init.h> |
13 | #include <linux/of.h> | 15 | #include <linux/of.h> |
14 | #include <linux/of_pci.h> | 16 | #include <linux/of_pci.h> |
@@ -25,7 +27,9 @@ | |||
25 | #include <linux/device.h> | 27 | #include <linux/device.h> |
26 | #include <linux/pm_runtime.h> | 28 | #include <linux/pm_runtime.h> |
27 | #include <linux/pci_hotplug.h> | 29 | #include <linux/pci_hotplug.h> |
30 | #include <linux/vmalloc.h> | ||
28 | #include <asm/setup.h> | 31 | #include <asm/setup.h> |
32 | #include <asm/dma.h> | ||
29 | #include <linux/aer.h> | 33 | #include <linux/aer.h> |
30 | #include "pci.h" | 34 | #include "pci.h" |
31 | 35 | ||
@@ -81,6 +85,9 @@ unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE; | |||
81 | unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE; | 85 | unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE; |
82 | unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE; | 86 | unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE; |
83 | 87 | ||
88 | #define DEFAULT_HOTPLUG_BUS_SIZE 1 | ||
89 | unsigned long pci_hotplug_bus_size = DEFAULT_HOTPLUG_BUS_SIZE; | ||
90 | |||
84 | enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_DEFAULT; | 91 | enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_DEFAULT; |
85 | 92 | ||
86 | /* | 93 | /* |
@@ -101,6 +108,21 @@ unsigned int pcibios_max_latency = 255; | |||
101 | /* If set, the PCIe ARI capability will not be used. */ | 108 | /* If set, the PCIe ARI capability will not be used. */ |
102 | static bool pcie_ari_disabled; | 109 | static bool pcie_ari_disabled; |
103 | 110 | ||
111 | /* Disable bridge_d3 for all PCIe ports */ | ||
112 | static bool pci_bridge_d3_disable; | ||
113 | /* Force bridge_d3 for all PCIe ports */ | ||
114 | static bool pci_bridge_d3_force; | ||
115 | |||
116 | static int __init pcie_port_pm_setup(char *str) | ||
117 | { | ||
118 | if (!strcmp(str, "off")) | ||
119 | pci_bridge_d3_disable = true; | ||
120 | else if (!strcmp(str, "force")) | ||
121 | pci_bridge_d3_force = true; | ||
122 | return 1; | ||
123 | } | ||
124 | __setup("pcie_port_pm=", pcie_port_pm_setup); | ||
125 | |||
104 | /** | 126 | /** |
105 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children | 127 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children |
106 | * @bus: pointer to PCI bus structure to search | 128 | * @bus: pointer to PCI bus structure to search |
@@ -2156,6 +2178,164 @@ void pci_config_pm_runtime_put(struct pci_dev *pdev) | |||
2156 | } | 2178 | } |
2157 | 2179 | ||
2158 | /** | 2180 | /** |
2181 | * pci_bridge_d3_possible - Is it possible to put the bridge into D3 | ||
2182 | * @bridge: Bridge to check | ||
2183 | * | ||
2184 | * This function checks if it is possible to move the bridge to D3. | ||
2185 | * Currently we only allow D3 for recent enough PCIe ports. | ||
2186 | */ | ||
2187 | static bool pci_bridge_d3_possible(struct pci_dev *bridge) | ||
2188 | { | ||
2189 | unsigned int year; | ||
2190 | |||
2191 | if (!pci_is_pcie(bridge)) | ||
2192 | return false; | ||
2193 | |||
2194 | switch (pci_pcie_type(bridge)) { | ||
2195 | case PCI_EXP_TYPE_ROOT_PORT: | ||
2196 | case PCI_EXP_TYPE_UPSTREAM: | ||
2197 | case PCI_EXP_TYPE_DOWNSTREAM: | ||
2198 | if (pci_bridge_d3_disable) | ||
2199 | return false; | ||
2200 | if (pci_bridge_d3_force) | ||
2201 | return true; | ||
2202 | |||
2203 | /* | ||
2204 | * It should be safe to put PCIe ports from 2015 or newer | ||
2205 | * to D3. | ||
2206 | */ | ||
2207 | if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && | ||
2208 | year >= 2015) { | ||
2209 | return true; | ||
2210 | } | ||
2211 | break; | ||
2212 | } | ||
2213 | |||
2214 | return false; | ||
2215 | } | ||
2216 | |||
2217 | static int pci_dev_check_d3cold(struct pci_dev *dev, void *data) | ||
2218 | { | ||
2219 | bool *d3cold_ok = data; | ||
2220 | bool no_d3cold; | ||
2221 | |||
2222 | /* | ||
2223 | * The device needs to be allowed to go D3cold and if it is wake | ||
2224 | * capable to do so from D3cold. | ||
2225 | */ | ||
2226 | no_d3cold = dev->no_d3cold || !dev->d3cold_allowed || | ||
2227 | (device_may_wakeup(&dev->dev) && !pci_pme_capable(dev, PCI_D3cold)) || | ||
2228 | !pci_power_manageable(dev); | ||
2229 | |||
2230 | *d3cold_ok = !no_d3cold; | ||
2231 | |||
2232 | return no_d3cold; | ||
2233 | } | ||
2234 | |||
2235 | /* | ||
2236 | * pci_bridge_d3_update - Update bridge D3 capabilities | ||
2237 | * @dev: PCI device which is changed | ||
2238 | * @remove: Is the device being removed | ||
2239 | * | ||
2240 | * Update upstream bridge PM capabilities accordingly depending on if the | ||
2241 | * device PM configuration was changed or the device is being removed. The | ||
2242 | * change is also propagated upstream. | ||
2243 | */ | ||
2244 | static void pci_bridge_d3_update(struct pci_dev *dev, bool remove) | ||
2245 | { | ||
2246 | struct pci_dev *bridge; | ||
2247 | bool d3cold_ok = true; | ||
2248 | |||
2249 | bridge = pci_upstream_bridge(dev); | ||
2250 | if (!bridge || !pci_bridge_d3_possible(bridge)) | ||
2251 | return; | ||
2252 | |||
2253 | pci_dev_get(bridge); | ||
2254 | /* | ||
2255 | * If the device is removed we do not care about its D3cold | ||
2256 | * capabilities. | ||
2257 | */ | ||
2258 | if (!remove) | ||
2259 | pci_dev_check_d3cold(dev, &d3cold_ok); | ||
2260 | |||
2261 | if (d3cold_ok) { | ||
2262 | /* | ||
2263 | * We need to go through all children to find out if all of | ||
2264 | * them can still go to D3cold. | ||
2265 | */ | ||
2266 | pci_walk_bus(bridge->subordinate, pci_dev_check_d3cold, | ||
2267 | &d3cold_ok); | ||
2268 | } | ||
2269 | |||
2270 | if (bridge->bridge_d3 != d3cold_ok) { | ||
2271 | bridge->bridge_d3 = d3cold_ok; | ||
2272 | /* Propagate change to upstream bridges */ | ||
2273 | pci_bridge_d3_update(bridge, false); | ||
2274 | } | ||
2275 | |||
2276 | pci_dev_put(bridge); | ||
2277 | } | ||
2278 | |||
2279 | /** | ||
2280 | * pci_bridge_d3_device_changed - Update bridge D3 capabilities on change | ||
2281 | * @dev: PCI device that was changed | ||
2282 | * | ||
2283 | * If a device is added or its PM configuration, such as is it allowed to | ||
2284 | * enter D3cold, is changed this function updates upstream bridge PM | ||
2285 | * capabilities accordingly. | ||
2286 | */ | ||
2287 | void pci_bridge_d3_device_changed(struct pci_dev *dev) | ||
2288 | { | ||
2289 | pci_bridge_d3_update(dev, false); | ||
2290 | } | ||
2291 | |||
2292 | /** | ||
2293 | * pci_bridge_d3_device_removed - Update bridge D3 capabilities on remove | ||
2294 | * @dev: PCI device being removed | ||
2295 | * | ||
2296 | * Function updates upstream bridge PM capabilities based on other devices | ||
2297 | * still left on the bus. | ||
2298 | */ | ||
2299 | void pci_bridge_d3_device_removed(struct pci_dev *dev) | ||
2300 | { | ||
2301 | pci_bridge_d3_update(dev, true); | ||
2302 | } | ||
2303 | |||
2304 | /** | ||
2305 | * pci_d3cold_enable - Enable D3cold for device | ||
2306 | * @dev: PCI device to handle | ||
2307 | * | ||
2308 | * This function can be used in drivers to enable D3cold from the device | ||
2309 | * they handle. It also updates upstream PCI bridge PM capabilities | ||
2310 | * accordingly. | ||
2311 | */ | ||
2312 | void pci_d3cold_enable(struct pci_dev *dev) | ||
2313 | { | ||
2314 | if (dev->no_d3cold) { | ||
2315 | dev->no_d3cold = false; | ||
2316 | pci_bridge_d3_device_changed(dev); | ||
2317 | } | ||
2318 | } | ||
2319 | EXPORT_SYMBOL_GPL(pci_d3cold_enable); | ||
2320 | |||
2321 | /** | ||
2322 | * pci_d3cold_disable - Disable D3cold for device | ||
2323 | * @dev: PCI device to handle | ||
2324 | * | ||
2325 | * This function can be used in drivers to disable D3cold from the device | ||
2326 | * they handle. It also updates upstream PCI bridge PM capabilities | ||
2327 | * accordingly. | ||
2328 | */ | ||
2329 | void pci_d3cold_disable(struct pci_dev *dev) | ||
2330 | { | ||
2331 | if (!dev->no_d3cold) { | ||
2332 | dev->no_d3cold = true; | ||
2333 | pci_bridge_d3_device_changed(dev); | ||
2334 | } | ||
2335 | } | ||
2336 | EXPORT_SYMBOL_GPL(pci_d3cold_disable); | ||
2337 | |||
2338 | /** | ||
2159 | * pci_pm_init - Initialize PM functions of given PCI device | 2339 | * pci_pm_init - Initialize PM functions of given PCI device |
2160 | * @dev: PCI device to handle. | 2340 | * @dev: PCI device to handle. |
2161 | */ | 2341 | */ |
@@ -2189,6 +2369,7 @@ void pci_pm_init(struct pci_dev *dev) | |||
2189 | dev->pm_cap = pm; | 2369 | dev->pm_cap = pm; |
2190 | dev->d3_delay = PCI_PM_D3_WAIT; | 2370 | dev->d3_delay = PCI_PM_D3_WAIT; |
2191 | dev->d3cold_delay = PCI_PM_D3COLD_WAIT; | 2371 | dev->d3cold_delay = PCI_PM_D3COLD_WAIT; |
2372 | dev->bridge_d3 = pci_bridge_d3_possible(dev); | ||
2192 | dev->d3cold_allowed = true; | 2373 | dev->d3cold_allowed = true; |
2193 | 2374 | ||
2194 | dev->d1_support = false; | 2375 | dev->d1_support = false; |
@@ -3165,6 +3346,23 @@ int __weak pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr) | |||
3165 | #endif | 3346 | #endif |
3166 | } | 3347 | } |
3167 | 3348 | ||
3349 | /** | ||
3350 | * pci_unmap_iospace - Unmap the memory mapped I/O space | ||
3351 | * @res: resource to be unmapped | ||
3352 | * | ||
3353 | * Unmap the CPU virtual address @res from virtual address space. | ||
3354 | * Only architectures that have memory mapped IO functions defined | ||
3355 | * (and the PCI_IOBASE value defined) should call this function. | ||
3356 | */ | ||
3357 | void pci_unmap_iospace(struct resource *res) | ||
3358 | { | ||
3359 | #if defined(PCI_IOBASE) && defined(CONFIG_MMU) | ||
3360 | unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start; | ||
3361 | |||
3362 | unmap_kernel_range(vaddr, resource_size(res)); | ||
3363 | #endif | ||
3364 | } | ||
3365 | |||
3168 | static void __pci_set_master(struct pci_dev *dev, bool enable) | 3366 | static void __pci_set_master(struct pci_dev *dev, bool enable) |
3169 | { | 3367 | { |
3170 | u16 old_cmd, cmd; | 3368 | u16 old_cmd, cmd; |
@@ -4755,6 +4953,7 @@ static DEFINE_SPINLOCK(resource_alignment_lock); | |||
4755 | static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) | 4953 | static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) |
4756 | { | 4954 | { |
4757 | int seg, bus, slot, func, align_order, count; | 4955 | int seg, bus, slot, func, align_order, count; |
4956 | unsigned short vendor, device, subsystem_vendor, subsystem_device; | ||
4758 | resource_size_t align = 0; | 4957 | resource_size_t align = 0; |
4759 | char *p; | 4958 | char *p; |
4760 | 4959 | ||
@@ -4768,28 +4967,55 @@ static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) | |||
4768 | } else { | 4967 | } else { |
4769 | align_order = -1; | 4968 | align_order = -1; |
4770 | } | 4969 | } |
4771 | if (sscanf(p, "%x:%x:%x.%x%n", | 4970 | if (strncmp(p, "pci:", 4) == 0) { |
4772 | &seg, &bus, &slot, &func, &count) != 4) { | 4971 | /* PCI vendor/device (subvendor/subdevice) ids are specified */ |
4773 | seg = 0; | 4972 | p += 4; |
4774 | if (sscanf(p, "%x:%x.%x%n", | 4973 | if (sscanf(p, "%hx:%hx:%hx:%hx%n", |
4775 | &bus, &slot, &func, &count) != 3) { | 4974 | &vendor, &device, &subsystem_vendor, &subsystem_device, &count) != 4) { |
4776 | /* Invalid format */ | 4975 | if (sscanf(p, "%hx:%hx%n", &vendor, &device, &count) != 2) { |
4777 | printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: %s\n", | 4976 | printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: pci:%s\n", |
4778 | p); | 4977 | p); |
4978 | break; | ||
4979 | } | ||
4980 | subsystem_vendor = subsystem_device = 0; | ||
4981 | } | ||
4982 | p += count; | ||
4983 | if ((!vendor || (vendor == dev->vendor)) && | ||
4984 | (!device || (device == dev->device)) && | ||
4985 | (!subsystem_vendor || (subsystem_vendor == dev->subsystem_vendor)) && | ||
4986 | (!subsystem_device || (subsystem_device == dev->subsystem_device))) { | ||
4987 | if (align_order == -1) | ||
4988 | align = PAGE_SIZE; | ||
4989 | else | ||
4990 | align = 1 << align_order; | ||
4991 | /* Found */ | ||
4779 | break; | 4992 | break; |
4780 | } | 4993 | } |
4781 | } | 4994 | } |
4782 | p += count; | 4995 | else { |
4783 | if (seg == pci_domain_nr(dev->bus) && | 4996 | if (sscanf(p, "%x:%x:%x.%x%n", |
4784 | bus == dev->bus->number && | 4997 | &seg, &bus, &slot, &func, &count) != 4) { |
4785 | slot == PCI_SLOT(dev->devfn) && | 4998 | seg = 0; |
4786 | func == PCI_FUNC(dev->devfn)) { | 4999 | if (sscanf(p, "%x:%x.%x%n", |
4787 | if (align_order == -1) | 5000 | &bus, &slot, &func, &count) != 3) { |
4788 | align = PAGE_SIZE; | 5001 | /* Invalid format */ |
4789 | else | 5002 | printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: %s\n", |
4790 | align = 1 << align_order; | 5003 | p); |
4791 | /* Found */ | 5004 | break; |
4792 | break; | 5005 | } |
5006 | } | ||
5007 | p += count; | ||
5008 | if (seg == pci_domain_nr(dev->bus) && | ||
5009 | bus == dev->bus->number && | ||
5010 | slot == PCI_SLOT(dev->devfn) && | ||
5011 | func == PCI_FUNC(dev->devfn)) { | ||
5012 | if (align_order == -1) | ||
5013 | align = PAGE_SIZE; | ||
5014 | else | ||
5015 | align = 1 << align_order; | ||
5016 | /* Found */ | ||
5017 | break; | ||
5018 | } | ||
4793 | } | 5019 | } |
4794 | if (*p != ';' && *p != ',') { | 5020 | if (*p != ';' && *p != ',') { |
4795 | /* End of param or invalid format */ | 5021 | /* End of param or invalid format */ |
@@ -4897,7 +5123,7 @@ static ssize_t pci_resource_alignment_store(struct bus_type *bus, | |||
4897 | return pci_set_resource_alignment_param(buf, count); | 5123 | return pci_set_resource_alignment_param(buf, count); |
4898 | } | 5124 | } |
4899 | 5125 | ||
4900 | BUS_ATTR(resource_alignment, 0644, pci_resource_alignment_show, | 5126 | static BUS_ATTR(resource_alignment, 0644, pci_resource_alignment_show, |
4901 | pci_resource_alignment_store); | 5127 | pci_resource_alignment_store); |
4902 | 5128 | ||
4903 | static int __init pci_resource_alignment_sysfs_init(void) | 5129 | static int __init pci_resource_alignment_sysfs_init(void) |
@@ -4923,7 +5149,7 @@ int pci_get_new_domain_nr(void) | |||
4923 | } | 5149 | } |
4924 | 5150 | ||
4925 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | 5151 | #ifdef CONFIG_PCI_DOMAINS_GENERIC |
4926 | void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent) | 5152 | static int of_pci_bus_find_domain_nr(struct device *parent) |
4927 | { | 5153 | { |
4928 | static int use_dt_domains = -1; | 5154 | static int use_dt_domains = -1; |
4929 | int domain = -1; | 5155 | int domain = -1; |
@@ -4967,7 +5193,13 @@ void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent) | |||
4967 | domain = -1; | 5193 | domain = -1; |
4968 | } | 5194 | } |
4969 | 5195 | ||
4970 | bus->domain_nr = domain; | 5196 | return domain; |
5197 | } | ||
5198 | |||
5199 | int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent) | ||
5200 | { | ||
5201 | return acpi_disabled ? of_pci_bus_find_domain_nr(parent) : | ||
5202 | acpi_pci_bus_find_domain_nr(bus); | ||
4971 | } | 5203 | } |
4972 | #endif | 5204 | #endif |
4973 | #endif | 5205 | #endif |
@@ -5021,6 +5253,11 @@ static int __init pci_setup(char *str) | |||
5021 | pci_hotplug_io_size = memparse(str + 9, &str); | 5253 | pci_hotplug_io_size = memparse(str + 9, &str); |
5022 | } else if (!strncmp(str, "hpmemsize=", 10)) { | 5254 | } else if (!strncmp(str, "hpmemsize=", 10)) { |
5023 | pci_hotplug_mem_size = memparse(str + 10, &str); | 5255 | pci_hotplug_mem_size = memparse(str + 10, &str); |
5256 | } else if (!strncmp(str, "hpbussize=", 10)) { | ||
5257 | pci_hotplug_bus_size = | ||
5258 | simple_strtoul(str + 10, &str, 0); | ||
5259 | if (pci_hotplug_bus_size > 0xff) | ||
5260 | pci_hotplug_bus_size = DEFAULT_HOTPLUG_BUS_SIZE; | ||
5024 | } else if (!strncmp(str, "pcie_bus_tune_off", 17)) { | 5261 | } else if (!strncmp(str, "pcie_bus_tune_off", 17)) { |
5025 | pcie_bus_config = PCIE_BUS_TUNE_OFF; | 5262 | pcie_bus_config = PCIE_BUS_TUNE_OFF; |
5026 | } else if (!strncmp(str, "pcie_bus_safe", 13)) { | 5263 | } else if (!strncmp(str, "pcie_bus_safe", 13)) { |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index a814bbb80fcb..9730c474b016 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -82,6 +82,8 @@ void pci_pm_init(struct pci_dev *dev); | |||
82 | void pci_ea_init(struct pci_dev *dev); | 82 | void pci_ea_init(struct pci_dev *dev); |
83 | void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 83 | void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
84 | void pci_free_cap_save_buffers(struct pci_dev *dev); | 84 | void pci_free_cap_save_buffers(struct pci_dev *dev); |
85 | void pci_bridge_d3_device_changed(struct pci_dev *dev); | ||
86 | void pci_bridge_d3_device_removed(struct pci_dev *dev); | ||
85 | 87 | ||
86 | static inline void pci_wakeup_event(struct pci_dev *dev) | 88 | static inline void pci_wakeup_event(struct pci_dev *dev) |
87 | { | 89 | { |
@@ -94,6 +96,15 @@ static inline bool pci_has_subordinate(struct pci_dev *pci_dev) | |||
94 | return !!(pci_dev->subordinate); | 96 | return !!(pci_dev->subordinate); |
95 | } | 97 | } |
96 | 98 | ||
99 | static inline bool pci_power_manageable(struct pci_dev *pci_dev) | ||
100 | { | ||
101 | /* | ||
102 | * Currently we allow normal PCI devices and PCI bridges transition | ||
103 | * into D3 if their bridge_d3 is set. | ||
104 | */ | ||
105 | return !pci_has_subordinate(pci_dev) || pci_dev->bridge_d3; | ||
106 | } | ||
107 | |||
97 | struct pci_vpd_ops { | 108 | struct pci_vpd_ops { |
98 | ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf); | 109 | ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf); |
99 | ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf); | 110 | ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf); |
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index 22ca6412bd15..7fcea75afa4c 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig | |||
@@ -83,7 +83,7 @@ config PCIE_PME | |||
83 | depends on PCIEPORTBUS && PM | 83 | depends on PCIEPORTBUS && PM |
84 | 84 | ||
85 | config PCIE_DPC | 85 | config PCIE_DPC |
86 | tristate "PCIe Downstream Port Containment support" | 86 | bool "PCIe Downstream Port Containment support" |
87 | depends on PCIEPORTBUS | 87 | depends on PCIEPORTBUS |
88 | default n | 88 | default n |
89 | help | 89 | help |
@@ -92,6 +92,3 @@ config PCIE_DPC | |||
92 | will be handled by the DPC driver. If your system doesn't | 92 | will be handled by the DPC driver. If your system doesn't |
93 | have this capability or you do not want to use this feature, | 93 | have this capability or you do not want to use this feature, |
94 | it is safe to answer N. | 94 | it is safe to answer N. |
95 | |||
96 | To compile this driver as a module, choose M here: the module | ||
97 | will be called pcie-dpc. | ||
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 2dfe7fdb77e7..0ec649d961d7 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -139,7 +139,7 @@ static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable) | |||
139 | static void pcie_set_clkpm(struct pcie_link_state *link, int enable) | 139 | static void pcie_set_clkpm(struct pcie_link_state *link, int enable) |
140 | { | 140 | { |
141 | /* Don't enable Clock PM if the link is not Clock PM capable */ | 141 | /* Don't enable Clock PM if the link is not Clock PM capable */ |
142 | if (!link->clkpm_capable && enable) | 142 | if (!link->clkpm_capable) |
143 | enable = 0; | 143 | enable = 0; |
144 | /* Need nothing if the specified equals to current state */ | 144 | /* Need nothing if the specified equals to current state */ |
145 | if (link->clkpm_enabled == enable) | 145 | if (link->clkpm_enabled == enable) |
diff --git a/drivers/pci/pcie/pcie-dpc.c b/drivers/pci/pcie/pcie-dpc.c index ab552f1bc08f..250f87861786 100644 --- a/drivers/pci/pcie/pcie-dpc.c +++ b/drivers/pci/pcie/pcie-dpc.c | |||
@@ -15,8 +15,8 @@ | |||
15 | 15 | ||
16 | struct dpc_dev { | 16 | struct dpc_dev { |
17 | struct pcie_device *dev; | 17 | struct pcie_device *dev; |
18 | struct work_struct work; | 18 | struct work_struct work; |
19 | int cap_pos; | 19 | int cap_pos; |
20 | }; | 20 | }; |
21 | 21 | ||
22 | static void dpc_wait_link_inactive(struct pci_dev *pdev) | 22 | static void dpc_wait_link_inactive(struct pci_dev *pdev) |
@@ -89,7 +89,7 @@ static int dpc_probe(struct pcie_device *dev) | |||
89 | int status; | 89 | int status; |
90 | u16 ctl, cap; | 90 | u16 ctl, cap; |
91 | 91 | ||
92 | dpc = kzalloc(sizeof(*dpc), GFP_KERNEL); | 92 | dpc = devm_kzalloc(&dev->device, sizeof(*dpc), GFP_KERNEL); |
93 | if (!dpc) | 93 | if (!dpc) |
94 | return -ENOMEM; | 94 | return -ENOMEM; |
95 | 95 | ||
@@ -98,11 +98,12 @@ static int dpc_probe(struct pcie_device *dev) | |||
98 | INIT_WORK(&dpc->work, interrupt_event_handler); | 98 | INIT_WORK(&dpc->work, interrupt_event_handler); |
99 | set_service_data(dev, dpc); | 99 | set_service_data(dev, dpc); |
100 | 100 | ||
101 | status = request_irq(dev->irq, dpc_irq, IRQF_SHARED, "pcie-dpc", dpc); | 101 | status = devm_request_irq(&dev->device, dev->irq, dpc_irq, IRQF_SHARED, |
102 | "pcie-dpc", dpc); | ||
102 | if (status) { | 103 | if (status) { |
103 | dev_warn(&dev->device, "request IRQ%d failed: %d\n", dev->irq, | 104 | dev_warn(&dev->device, "request IRQ%d failed: %d\n", dev->irq, |
104 | status); | 105 | status); |
105 | goto out; | 106 | return status; |
106 | } | 107 | } |
107 | 108 | ||
108 | pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CAP, &cap); | 109 | pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CAP, &cap); |
@@ -117,9 +118,6 @@ static int dpc_probe(struct pcie_device *dev) | |||
117 | FLAG(cap, PCI_EXP_DPC_CAP_SW_TRIGGER), (cap >> 8) & 0xf, | 118 | FLAG(cap, PCI_EXP_DPC_CAP_SW_TRIGGER), (cap >> 8) & 0xf, |
118 | FLAG(cap, PCI_EXP_DPC_CAP_DL_ACTIVE)); | 119 | FLAG(cap, PCI_EXP_DPC_CAP_DL_ACTIVE)); |
119 | return status; | 120 | return status; |
120 | out: | ||
121 | kfree(dpc); | ||
122 | return status; | ||
123 | } | 121 | } |
124 | 122 | ||
125 | static void dpc_remove(struct pcie_device *dev) | 123 | static void dpc_remove(struct pcie_device *dev) |
@@ -131,14 +129,11 @@ static void dpc_remove(struct pcie_device *dev) | |||
131 | pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, &ctl); | 129 | pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, &ctl); |
132 | ctl &= ~(PCI_EXP_DPC_CTL_EN_NONFATAL | PCI_EXP_DPC_CTL_INT_EN); | 130 | ctl &= ~(PCI_EXP_DPC_CTL_EN_NONFATAL | PCI_EXP_DPC_CTL_INT_EN); |
133 | pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, ctl); | 131 | pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, ctl); |
134 | |||
135 | free_irq(dev->irq, dpc); | ||
136 | kfree(dpc); | ||
137 | } | 132 | } |
138 | 133 | ||
139 | static struct pcie_port_service_driver dpcdriver = { | 134 | static struct pcie_port_service_driver dpcdriver = { |
140 | .name = "dpc", | 135 | .name = "dpc", |
141 | .port_type = PCI_EXP_TYPE_ROOT_PORT | PCI_EXP_TYPE_DOWNSTREAM, | 136 | .port_type = PCIE_ANY_PORT, |
142 | .service = PCIE_PORT_SERVICE_DPC, | 137 | .service = PCIE_PORT_SERVICE_DPC, |
143 | .probe = dpc_probe, | 138 | .probe = dpc_probe, |
144 | .remove = dpc_remove, | 139 | .remove = dpc_remove, |
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 32d4d0a3d20e..e9270b4026f3 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/pm.h> | 13 | #include <linux/pm.h> |
14 | #include <linux/pm_runtime.h> | ||
14 | #include <linux/string.h> | 15 | #include <linux/string.h> |
15 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
16 | #include <linux/pcieport_if.h> | 17 | #include <linux/pcieport_if.h> |
@@ -342,6 +343,8 @@ static int pcie_device_init(struct pci_dev *pdev, int service, int irq) | |||
342 | return retval; | 343 | return retval; |
343 | } | 344 | } |
344 | 345 | ||
346 | pm_runtime_no_callbacks(device); | ||
347 | |||
345 | return 0; | 348 | return 0; |
346 | } | 349 | } |
347 | 350 | ||
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index be35da2e105e..70d7ad8c6d17 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -93,6 +93,26 @@ static int pcie_port_resume_noirq(struct device *dev) | |||
93 | return 0; | 93 | return 0; |
94 | } | 94 | } |
95 | 95 | ||
96 | static int pcie_port_runtime_suspend(struct device *dev) | ||
97 | { | ||
98 | return to_pci_dev(dev)->bridge_d3 ? 0 : -EBUSY; | ||
99 | } | ||
100 | |||
101 | static int pcie_port_runtime_resume(struct device *dev) | ||
102 | { | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static int pcie_port_runtime_idle(struct device *dev) | ||
107 | { | ||
108 | /* | ||
109 | * Assume the PCI core has set bridge_d3 whenever it thinks the port | ||
110 | * should be good to go to D3. Everything else, including moving | ||
111 | * the port to D3, is handled by the PCI core. | ||
112 | */ | ||
113 | return to_pci_dev(dev)->bridge_d3 ? 0 : -EBUSY; | ||
114 | } | ||
115 | |||
96 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { | 116 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { |
97 | .suspend = pcie_port_device_suspend, | 117 | .suspend = pcie_port_device_suspend, |
98 | .resume = pcie_port_device_resume, | 118 | .resume = pcie_port_device_resume, |
@@ -101,6 +121,9 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { | |||
101 | .poweroff = pcie_port_device_suspend, | 121 | .poweroff = pcie_port_device_suspend, |
102 | .restore = pcie_port_device_resume, | 122 | .restore = pcie_port_device_resume, |
103 | .resume_noirq = pcie_port_resume_noirq, | 123 | .resume_noirq = pcie_port_resume_noirq, |
124 | .runtime_suspend = pcie_port_runtime_suspend, | ||
125 | .runtime_resume = pcie_port_runtime_resume, | ||
126 | .runtime_idle = pcie_port_runtime_idle, | ||
104 | }; | 127 | }; |
105 | 128 | ||
106 | #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) | 129 | #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) |
@@ -134,16 +157,39 @@ static int pcie_portdrv_probe(struct pci_dev *dev, | |||
134 | return status; | 157 | return status; |
135 | 158 | ||
136 | pci_save_state(dev); | 159 | pci_save_state(dev); |
160 | |||
137 | /* | 161 | /* |
138 | * D3cold may not work properly on some PCIe port, so disable | 162 | * Prevent runtime PM if the port is advertising support for PCIe |
139 | * it by default. | 163 | * hotplug. Otherwise the BIOS hotplug SMI code might not be able |
164 | * to enumerate devices behind this port properly (the port is | ||
165 | * powered down preventing all config space accesses to the | ||
166 | * subordinate devices). We can't be sure for native PCIe hotplug | ||
167 | * either so prevent that as well. | ||
140 | */ | 168 | */ |
141 | dev->d3cold_allowed = false; | 169 | if (!dev->is_hotplug_bridge) { |
170 | /* | ||
171 | * Keep the port resumed 100ms to make sure things like | ||
172 | * config space accesses from userspace (lspci) will not | ||
173 | * cause the port to repeatedly suspend and resume. | ||
174 | */ | ||
175 | pm_runtime_set_autosuspend_delay(&dev->dev, 100); | ||
176 | pm_runtime_use_autosuspend(&dev->dev); | ||
177 | pm_runtime_mark_last_busy(&dev->dev); | ||
178 | pm_runtime_put_autosuspend(&dev->dev); | ||
179 | pm_runtime_allow(&dev->dev); | ||
180 | } | ||
181 | |||
142 | return 0; | 182 | return 0; |
143 | } | 183 | } |
144 | 184 | ||
145 | static void pcie_portdrv_remove(struct pci_dev *dev) | 185 | static void pcie_portdrv_remove(struct pci_dev *dev) |
146 | { | 186 | { |
187 | if (!dev->is_hotplug_bridge) { | ||
188 | pm_runtime_forbid(&dev->dev); | ||
189 | pm_runtime_get_noresume(&dev->dev); | ||
190 | pm_runtime_dont_use_autosuspend(&dev->dev); | ||
191 | } | ||
192 | |||
147 | pcie_port_device_remove(dev); | 193 | pcie_port_device_remove(dev); |
148 | } | 194 | } |
149 | 195 | ||
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 8e3ef720997d..93f280df3428 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/aer.h> | 16 | #include <linux/aer.h> |
17 | #include <linux/acpi.h> | 17 | #include <linux/acpi.h> |
18 | #include <linux/irqdomain.h> | 18 | #include <linux/irqdomain.h> |
19 | #include <linux/pm_runtime.h> | ||
19 | #include "pci.h" | 20 | #include "pci.h" |
20 | 21 | ||
21 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ | 22 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ |
@@ -832,6 +833,12 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
832 | u8 primary, secondary, subordinate; | 833 | u8 primary, secondary, subordinate; |
833 | int broken = 0; | 834 | int broken = 0; |
834 | 835 | ||
836 | /* | ||
837 | * Make sure the bridge is powered on to be able to access config | ||
838 | * space of devices below it. | ||
839 | */ | ||
840 | pm_runtime_get_sync(&dev->dev); | ||
841 | |||
835 | pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); | 842 | pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); |
836 | primary = buses & 0xFF; | 843 | primary = buses & 0xFF; |
837 | secondary = (buses >> 8) & 0xFF; | 844 | secondary = (buses >> 8) & 0xFF; |
@@ -1012,6 +1019,8 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) | |||
1012 | out: | 1019 | out: |
1013 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl); | 1020 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl); |
1014 | 1021 | ||
1022 | pm_runtime_put(&dev->dev); | ||
1023 | |||
1015 | return max; | 1024 | return max; |
1016 | } | 1025 | } |
1017 | EXPORT_SYMBOL(pci_scan_bridge); | 1026 | EXPORT_SYMBOL(pci_scan_bridge); |
@@ -2077,6 +2086,15 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus) | |||
2077 | } | 2086 | } |
2078 | 2087 | ||
2079 | /* | 2088 | /* |
2089 | * Make sure a hotplug bridge has at least the minimum requested | ||
2090 | * number of buses. | ||
2091 | */ | ||
2092 | if (bus->self && bus->self->is_hotplug_bridge && pci_hotplug_bus_size) { | ||
2093 | if (max - bus->busn_res.start < pci_hotplug_bus_size - 1) | ||
2094 | max = bus->busn_res.start + pci_hotplug_bus_size - 1; | ||
2095 | } | ||
2096 | |||
2097 | /* | ||
2080 | * We've scanned the bus and so we know all about what's on | 2098 | * We've scanned the bus and so we know all about what's on |
2081 | * the other side of any bridges that may be on this bus plus | 2099 | * the other side of any bridges that may be on this bus plus |
2082 | * any devices. | 2100 | * any devices. |
@@ -2127,7 +2145,9 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
2127 | b->sysdata = sysdata; | 2145 | b->sysdata = sysdata; |
2128 | b->ops = ops; | 2146 | b->ops = ops; |
2129 | b->number = b->busn_res.start = bus; | 2147 | b->number = b->busn_res.start = bus; |
2130 | pci_bus_assign_domain_nr(b, parent); | 2148 | #ifdef CONFIG_PCI_DOMAINS_GENERIC |
2149 | b->domain_nr = pci_bus_find_domain_nr(b, parent); | ||
2150 | #endif | ||
2131 | b2 = pci_find_bus(pci_domain_nr(b), bus); | 2151 | b2 = pci_find_bus(pci_domain_nr(b), bus); |
2132 | if (b2) { | 2152 | if (b2) { |
2133 | /* If we already got to this bus through a different bridge, ignore it */ | 2153 | /* If we already got to this bus through a different bridge, ignore it */ |
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 3f155e78513f..2408abe4ee8c 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
@@ -231,7 +231,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) | |||
231 | { | 231 | { |
232 | struct pci_dev *dev = PDE_DATA(file_inode(file)); | 232 | struct pci_dev *dev = PDE_DATA(file_inode(file)); |
233 | struct pci_filp_private *fpriv = file->private_data; | 233 | struct pci_filp_private *fpriv = file->private_data; |
234 | int i, ret; | 234 | int i, ret, write_combine; |
235 | 235 | ||
236 | if (!capable(CAP_SYS_RAWIO)) | 236 | if (!capable(CAP_SYS_RAWIO)) |
237 | return -EPERM; | 237 | return -EPERM; |
@@ -245,9 +245,12 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) | |||
245 | if (i >= PCI_ROM_RESOURCE) | 245 | if (i >= PCI_ROM_RESOURCE) |
246 | return -ENODEV; | 246 | return -ENODEV; |
247 | 247 | ||
248 | if (fpriv->mmap_state == pci_mmap_mem) | ||
249 | write_combine = fpriv->write_combine; | ||
250 | else | ||
251 | write_combine = 0; | ||
248 | ret = pci_mmap_page_range(dev, vma, | 252 | ret = pci_mmap_page_range(dev, vma, |
249 | fpriv->mmap_state, | 253 | fpriv->mmap_state, write_combine); |
250 | fpriv->write_combine); | ||
251 | if (ret < 0) | 254 | if (ret < 0) |
252 | return ret; | 255 | return ret; |
253 | 256 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ee72ebe18f4b..37ff0158e45f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -3189,13 +3189,15 @@ static void quirk_no_bus_reset(struct pci_dev *dev) | |||
3189 | } | 3189 | } |
3190 | 3190 | ||
3191 | /* | 3191 | /* |
3192 | * Atheros AR93xx chips do not behave after a bus reset. The device will | 3192 | * Some Atheros AR9xxx and QCA988x chips do not behave after a bus reset. |
3193 | * throw a Link Down error on AER-capable systems and regardless of AER, | 3193 | * The device will throw a Link Down error on AER-capable systems and |
3194 | * config space of the device is never accessible again and typically | 3194 | * regardless of AER, config space of the device is never accessible again |
3195 | * causes the system to hang or reset when access is attempted. | 3195 | * and typically causes the system to hang or reset when access is attempted. |
3196 | * http://www.spinics.net/lists/linux-pci/msg34797.html | 3196 | * http://www.spinics.net/lists/linux-pci/msg34797.html |
3197 | */ | 3197 | */ |
3198 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset); | 3198 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset); |
3199 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0032, quirk_no_bus_reset); | ||
3200 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003c, quirk_no_bus_reset); | ||
3199 | 3201 | ||
3200 | static void quirk_no_pm_reset(struct pci_dev *dev) | 3202 | static void quirk_no_pm_reset(struct pci_dev *dev) |
3201 | { | 3203 | { |
@@ -3711,6 +3713,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9172, | |||
3711 | /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c59 */ | 3713 | /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c59 */ |
3712 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x917a, | 3714 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x917a, |
3713 | quirk_dma_func1_alias); | 3715 | quirk_dma_func1_alias); |
3716 | /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c78 */ | ||
3717 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9182, | ||
3718 | quirk_dma_func1_alias); | ||
3714 | /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c46 */ | 3719 | /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c46 */ |
3715 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x91a0, | 3720 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x91a0, |
3716 | quirk_dma_func1_alias); | 3721 | quirk_dma_func1_alias); |
@@ -3747,6 +3752,9 @@ static const struct pci_device_id fixed_dma_alias_tbl[] = { | |||
3747 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x0285, | 3752 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x0285, |
3748 | PCI_VENDOR_ID_ADAPTEC2, 0x02bb), /* Adaptec 3405 */ | 3753 | PCI_VENDOR_ID_ADAPTEC2, 0x02bb), /* Adaptec 3405 */ |
3749 | .driver_data = PCI_DEVFN(1, 0) }, | 3754 | .driver_data = PCI_DEVFN(1, 0) }, |
3755 | { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x0285, | ||
3756 | PCI_VENDOR_ID_ADAPTEC2, 0x02bc), /* Adaptec 3805 */ | ||
3757 | .driver_data = PCI_DEVFN(1, 0) }, | ||
3750 | { 0 } | 3758 | { 0 } |
3751 | }; | 3759 | }; |
3752 | 3760 | ||
@@ -4087,6 +4095,7 @@ static const struct pci_dev_acs_enabled { | |||
4087 | { PCI_VENDOR_ID_AMD, 0x7809, pci_quirk_amd_sb_acs }, | 4095 | { PCI_VENDOR_ID_AMD, 0x7809, pci_quirk_amd_sb_acs }, |
4088 | { PCI_VENDOR_ID_SOLARFLARE, 0x0903, pci_quirk_mf_endpoint_acs }, | 4096 | { PCI_VENDOR_ID_SOLARFLARE, 0x0903, pci_quirk_mf_endpoint_acs }, |
4089 | { PCI_VENDOR_ID_SOLARFLARE, 0x0923, pci_quirk_mf_endpoint_acs }, | 4097 | { PCI_VENDOR_ID_SOLARFLARE, 0x0923, pci_quirk_mf_endpoint_acs }, |
4098 | { PCI_VENDOR_ID_SOLARFLARE, 0x0A03, pci_quirk_mf_endpoint_acs }, | ||
4090 | { PCI_VENDOR_ID_INTEL, 0x10C6, pci_quirk_mf_endpoint_acs }, | 4099 | { PCI_VENDOR_ID_INTEL, 0x10C6, pci_quirk_mf_endpoint_acs }, |
4091 | { PCI_VENDOR_ID_INTEL, 0x10DB, pci_quirk_mf_endpoint_acs }, | 4100 | { PCI_VENDOR_ID_INTEL, 0x10DB, pci_quirk_mf_endpoint_acs }, |
4092 | { PCI_VENDOR_ID_INTEL, 0x10DD, pci_quirk_mf_endpoint_acs }, | 4101 | { PCI_VENDOR_ID_INTEL, 0x10DD, pci_quirk_mf_endpoint_acs }, |
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 8982026637d5..d1ef7acf6930 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
@@ -96,6 +96,8 @@ static void pci_remove_bus_device(struct pci_dev *dev) | |||
96 | dev->subordinate = NULL; | 96 | dev->subordinate = NULL; |
97 | } | 97 | } |
98 | 98 | ||
99 | pci_bridge_d3_device_removed(dev); | ||
100 | |||
99 | pci_destroy_dev(dev); | 101 | pci_destroy_dev(dev); |
100 | } | 102 | } |
101 | 103 | ||
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 55641a39a3e9..1d1a2c952c35 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -1423,6 +1423,74 @@ void pci_bus_assign_resources(const struct pci_bus *bus) | |||
1423 | } | 1423 | } |
1424 | EXPORT_SYMBOL(pci_bus_assign_resources); | 1424 | EXPORT_SYMBOL(pci_bus_assign_resources); |
1425 | 1425 | ||
1426 | static void pci_claim_device_resources(struct pci_dev *dev) | ||
1427 | { | ||
1428 | int i; | ||
1429 | |||
1430 | for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) { | ||
1431 | struct resource *r = &dev->resource[i]; | ||
1432 | |||
1433 | if (!r->flags || r->parent) | ||
1434 | continue; | ||
1435 | |||
1436 | pci_claim_resource(dev, i); | ||
1437 | } | ||
1438 | } | ||
1439 | |||
1440 | static void pci_claim_bridge_resources(struct pci_dev *dev) | ||
1441 | { | ||
1442 | int i; | ||
1443 | |||
1444 | for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { | ||
1445 | struct resource *r = &dev->resource[i]; | ||
1446 | |||
1447 | if (!r->flags || r->parent) | ||
1448 | continue; | ||
1449 | |||
1450 | pci_claim_bridge_resource(dev, i); | ||
1451 | } | ||
1452 | } | ||
1453 | |||
1454 | static void pci_bus_allocate_dev_resources(struct pci_bus *b) | ||
1455 | { | ||
1456 | struct pci_dev *dev; | ||
1457 | struct pci_bus *child; | ||
1458 | |||
1459 | list_for_each_entry(dev, &b->devices, bus_list) { | ||
1460 | pci_claim_device_resources(dev); | ||
1461 | |||
1462 | child = dev->subordinate; | ||
1463 | if (child) | ||
1464 | pci_bus_allocate_dev_resources(child); | ||
1465 | } | ||
1466 | } | ||
1467 | |||
1468 | static void pci_bus_allocate_resources(struct pci_bus *b) | ||
1469 | { | ||
1470 | struct pci_bus *child; | ||
1471 | |||
1472 | /* | ||
1473 | * Carry out a depth-first search on the PCI bus | ||
1474 | * tree to allocate bridge apertures. Read the | ||
1475 | * programmed bridge bases and recursively claim | ||
1476 | * the respective bridge resources. | ||
1477 | */ | ||
1478 | if (b->self) { | ||
1479 | pci_read_bridge_bases(b); | ||
1480 | pci_claim_bridge_resources(b->self); | ||
1481 | } | ||
1482 | |||
1483 | list_for_each_entry(child, &b->children, node) | ||
1484 | pci_bus_allocate_resources(child); | ||
1485 | } | ||
1486 | |||
1487 | void pci_bus_claim_resources(struct pci_bus *b) | ||
1488 | { | ||
1489 | pci_bus_allocate_resources(b); | ||
1490 | pci_bus_allocate_dev_resources(b); | ||
1491 | } | ||
1492 | EXPORT_SYMBOL(pci_bus_claim_resources); | ||
1493 | |||
1426 | static void __pci_bridge_assign_resources(const struct pci_dev *bridge, | 1494 | static void __pci_bridge_assign_resources(const struct pci_dev *bridge, |
1427 | struct list_head *add_head, | 1495 | struct list_head *add_head, |
1428 | struct list_head *fail_head) | 1496 | struct list_head *fail_head) |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index b43f7ac9812c..3a0f3a4ee944 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -4775,20 +4775,17 @@ static int | |||
4775 | lpfc_enable_pci_dev(struct lpfc_hba *phba) | 4775 | lpfc_enable_pci_dev(struct lpfc_hba *phba) |
4776 | { | 4776 | { |
4777 | struct pci_dev *pdev; | 4777 | struct pci_dev *pdev; |
4778 | int bars = 0; | ||
4779 | 4778 | ||
4780 | /* Obtain PCI device reference */ | 4779 | /* Obtain PCI device reference */ |
4781 | if (!phba->pcidev) | 4780 | if (!phba->pcidev) |
4782 | goto out_error; | 4781 | goto out_error; |
4783 | else | 4782 | else |
4784 | pdev = phba->pcidev; | 4783 | pdev = phba->pcidev; |
4785 | /* Select PCI BARs */ | ||
4786 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
4787 | /* Enable PCI device */ | 4784 | /* Enable PCI device */ |
4788 | if (pci_enable_device_mem(pdev)) | 4785 | if (pci_enable_device_mem(pdev)) |
4789 | goto out_error; | 4786 | goto out_error; |
4790 | /* Request PCI resource for the device */ | 4787 | /* Request PCI resource for the device */ |
4791 | if (pci_request_selected_regions(pdev, bars, LPFC_DRIVER_NAME)) | 4788 | if (pci_request_mem_regions(pdev, LPFC_DRIVER_NAME)) |
4792 | goto out_disable_device; | 4789 | goto out_disable_device; |
4793 | /* Set up device as PCI master and save state for EEH */ | 4790 | /* Set up device as PCI master and save state for EEH */ |
4794 | pci_set_master(pdev); | 4791 | pci_set_master(pdev); |
@@ -4805,7 +4802,7 @@ out_disable_device: | |||
4805 | pci_disable_device(pdev); | 4802 | pci_disable_device(pdev); |
4806 | out_error: | 4803 | out_error: |
4807 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 4804 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
4808 | "1401 Failed to enable pci device, bars:x%x\n", bars); | 4805 | "1401 Failed to enable pci device\n"); |
4809 | return -ENODEV; | 4806 | return -ENODEV; |
4810 | } | 4807 | } |
4811 | 4808 | ||
@@ -4820,17 +4817,14 @@ static void | |||
4820 | lpfc_disable_pci_dev(struct lpfc_hba *phba) | 4817 | lpfc_disable_pci_dev(struct lpfc_hba *phba) |
4821 | { | 4818 | { |
4822 | struct pci_dev *pdev; | 4819 | struct pci_dev *pdev; |
4823 | int bars; | ||
4824 | 4820 | ||
4825 | /* Obtain PCI device reference */ | 4821 | /* Obtain PCI device reference */ |
4826 | if (!phba->pcidev) | 4822 | if (!phba->pcidev) |
4827 | return; | 4823 | return; |
4828 | else | 4824 | else |
4829 | pdev = phba->pcidev; | 4825 | pdev = phba->pcidev; |
4830 | /* Select PCI BARs */ | ||
4831 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
4832 | /* Release PCI resource and disable PCI device */ | 4826 | /* Release PCI resource and disable PCI device */ |
4833 | pci_release_selected_regions(pdev, bars); | 4827 | pci_release_mem_regions(pdev); |
4834 | pci_disable_device(pdev); | 4828 | pci_disable_device(pdev); |
4835 | 4829 | ||
4836 | return; | 4830 | return; |
@@ -9722,7 +9716,6 @@ lpfc_pci_remove_one_s3(struct pci_dev *pdev) | |||
9722 | struct lpfc_vport **vports; | 9716 | struct lpfc_vport **vports; |
9723 | struct lpfc_hba *phba = vport->phba; | 9717 | struct lpfc_hba *phba = vport->phba; |
9724 | int i; | 9718 | int i; |
9725 | int bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
9726 | 9719 | ||
9727 | spin_lock_irq(&phba->hbalock); | 9720 | spin_lock_irq(&phba->hbalock); |
9728 | vport->load_flag |= FC_UNLOADING; | 9721 | vport->load_flag |= FC_UNLOADING; |
@@ -9797,7 +9790,7 @@ lpfc_pci_remove_one_s3(struct pci_dev *pdev) | |||
9797 | 9790 | ||
9798 | lpfc_hba_free(phba); | 9791 | lpfc_hba_free(phba); |
9799 | 9792 | ||
9800 | pci_release_selected_regions(pdev, bars); | 9793 | pci_release_mem_regions(pdev); |
9801 | pci_disable_device(pdev); | 9794 | pci_disable_device(pdev); |
9802 | } | 9795 | } |
9803 | 9796 | ||
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 48672fac7ff3..ac352fe391f4 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -382,7 +382,7 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) | |||
382 | * need to have the registers polled during D3, so avoid D3cold. | 382 | * need to have the registers polled during D3, so avoid D3cold. |
383 | */ | 383 | */ |
384 | if (xhci->quirks & XHCI_COMP_MODE_QUIRK) | 384 | if (xhci->quirks & XHCI_COMP_MODE_QUIRK) |
385 | pdev->no_d3cold = true; | 385 | pci_d3cold_disable(pdev); |
386 | 386 | ||
387 | if (xhci->quirks & XHCI_PME_STUCK_QUIRK) | 387 | if (xhci->quirks & XHCI_PME_STUCK_QUIRK) |
388 | xhci_pme_quirk(hcd); | 388 | xhci_pme_quirk(hcd); |
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 89ab0572dbc6..7d63a66e8ed4 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h | |||
@@ -24,6 +24,8 @@ static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) | |||
24 | } | 24 | } |
25 | extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle); | 25 | extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle); |
26 | 26 | ||
27 | extern phys_addr_t pci_mcfg_lookup(u16 domain, struct resource *bus_res); | ||
28 | |||
27 | static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev) | 29 | static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev) |
28 | { | 30 | { |
29 | struct pci_bus *pbus = pdev->bus; | 31 | struct pci_bus *pbus = pdev->bus; |
diff --git a/drivers/pci/ecam.h b/include/linux/pci-ecam.h index 9878bebd45bb..7adad206b1f4 100644 --- a/drivers/pci/ecam.h +++ b/include/linux/pci-ecam.h | |||
@@ -27,8 +27,7 @@ struct pci_config_window; | |||
27 | struct pci_ecam_ops { | 27 | struct pci_ecam_ops { |
28 | unsigned int bus_shift; | 28 | unsigned int bus_shift; |
29 | struct pci_ops pci_ops; | 29 | struct pci_ops pci_ops; |
30 | int (*init)(struct device *, | 30 | int (*init)(struct pci_config_window *); |
31 | struct pci_config_window *); | ||
32 | }; | 31 | }; |
33 | 32 | ||
34 | /* | 33 | /* |
@@ -45,6 +44,7 @@ struct pci_config_window { | |||
45 | void __iomem *win; /* 64-bit single mapping */ | 44 | void __iomem *win; /* 64-bit single mapping */ |
46 | void __iomem **winp; /* 32-bit per-bus mapping */ | 45 | void __iomem **winp; /* 32-bit per-bus mapping */ |
47 | }; | 46 | }; |
47 | struct device *parent;/* ECAM res was from this dev */ | ||
48 | }; | 48 | }; |
49 | 49 | ||
50 | /* create and free pci_config_window */ | 50 | /* create and free pci_config_window */ |
diff --git a/include/linux/pci.h b/include/linux/pci.h index b67e4df20801..1fed5927b08a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -101,6 +101,10 @@ enum { | |||
101 | DEVICE_COUNT_RESOURCE = PCI_NUM_RESOURCES, | 101 | DEVICE_COUNT_RESOURCE = PCI_NUM_RESOURCES, |
102 | }; | 102 | }; |
103 | 103 | ||
104 | /* | ||
105 | * pci_power_t values must match the bits in the Capabilities PME_Support | ||
106 | * and Control/Status PowerState fields in the Power Management capability. | ||
107 | */ | ||
104 | typedef int __bitwise pci_power_t; | 108 | typedef int __bitwise pci_power_t; |
105 | 109 | ||
106 | #define PCI_D0 ((pci_power_t __force) 0) | 110 | #define PCI_D0 ((pci_power_t __force) 0) |
@@ -116,7 +120,7 @@ extern const char *pci_power_names[]; | |||
116 | 120 | ||
117 | static inline const char *pci_power_name(pci_power_t state) | 121 | static inline const char *pci_power_name(pci_power_t state) |
118 | { | 122 | { |
119 | return pci_power_names[1 + (int) state]; | 123 | return pci_power_names[1 + (__force int) state]; |
120 | } | 124 | } |
121 | 125 | ||
122 | #define PCI_PM_D2_DELAY 200 | 126 | #define PCI_PM_D2_DELAY 200 |
@@ -294,6 +298,7 @@ struct pci_dev { | |||
294 | unsigned int d2_support:1; /* Low power state D2 is supported */ | 298 | unsigned int d2_support:1; /* Low power state D2 is supported */ |
295 | unsigned int no_d1d2:1; /* D1 and D2 are forbidden */ | 299 | unsigned int no_d1d2:1; /* D1 and D2 are forbidden */ |
296 | unsigned int no_d3cold:1; /* D3cold is forbidden */ | 300 | unsigned int no_d3cold:1; /* D3cold is forbidden */ |
301 | unsigned int bridge_d3:1; /* Allow D3 for bridge */ | ||
297 | unsigned int d3cold_allowed:1; /* D3cold is allowed by user */ | 302 | unsigned int d3cold_allowed:1; /* D3cold is allowed by user */ |
298 | unsigned int mmio_always_on:1; /* disallow turning off io/mem | 303 | unsigned int mmio_always_on:1; /* disallow turning off io/mem |
299 | decoding during bar sizing */ | 304 | decoding during bar sizing */ |
@@ -1083,6 +1088,8 @@ int pci_back_from_sleep(struct pci_dev *dev); | |||
1083 | bool pci_dev_run_wake(struct pci_dev *dev); | 1088 | bool pci_dev_run_wake(struct pci_dev *dev); |
1084 | bool pci_check_pme_status(struct pci_dev *dev); | 1089 | bool pci_check_pme_status(struct pci_dev *dev); |
1085 | void pci_pme_wakeup_bus(struct pci_bus *bus); | 1090 | void pci_pme_wakeup_bus(struct pci_bus *bus); |
1091 | void pci_d3cold_enable(struct pci_dev *dev); | ||
1092 | void pci_d3cold_disable(struct pci_dev *dev); | ||
1086 | 1093 | ||
1087 | static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, | 1094 | static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, |
1088 | bool enable) | 1095 | bool enable) |
@@ -1114,6 +1121,7 @@ int pci_set_vpd_size(struct pci_dev *dev, size_t len); | |||
1114 | /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ | 1121 | /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ |
1115 | resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx); | 1122 | resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx); |
1116 | void pci_bus_assign_resources(const struct pci_bus *bus); | 1123 | void pci_bus_assign_resources(const struct pci_bus *bus); |
1124 | void pci_bus_claim_resources(struct pci_bus *bus); | ||
1117 | void pci_bus_size_bridges(struct pci_bus *bus); | 1125 | void pci_bus_size_bridges(struct pci_bus *bus); |
1118 | int pci_claim_resource(struct pci_dev *, int); | 1126 | int pci_claim_resource(struct pci_dev *, int); |
1119 | int pci_claim_bridge_resource(struct pci_dev *bridge, int i); | 1127 | int pci_claim_bridge_resource(struct pci_dev *bridge, int i); |
@@ -1143,9 +1151,12 @@ void pci_add_resource(struct list_head *resources, struct resource *res); | |||
1143 | void pci_add_resource_offset(struct list_head *resources, struct resource *res, | 1151 | void pci_add_resource_offset(struct list_head *resources, struct resource *res, |
1144 | resource_size_t offset); | 1152 | resource_size_t offset); |
1145 | void pci_free_resource_list(struct list_head *resources); | 1153 | void pci_free_resource_list(struct list_head *resources); |
1146 | void pci_bus_add_resource(struct pci_bus *bus, struct resource *res, unsigned int flags); | 1154 | void pci_bus_add_resource(struct pci_bus *bus, struct resource *res, |
1155 | unsigned int flags); | ||
1147 | struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n); | 1156 | struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n); |
1148 | void pci_bus_remove_resources(struct pci_bus *bus); | 1157 | void pci_bus_remove_resources(struct pci_bus *bus); |
1158 | int devm_request_pci_bus_resources(struct device *dev, | ||
1159 | struct list_head *resources); | ||
1149 | 1160 | ||
1150 | #define pci_bus_for_each_resource(bus, res, i) \ | 1161 | #define pci_bus_for_each_resource(bus, res, i) \ |
1151 | for (i = 0; \ | 1162 | for (i = 0; \ |
@@ -1167,6 +1178,7 @@ int pci_register_io_range(phys_addr_t addr, resource_size_t size); | |||
1167 | unsigned long pci_address_to_pio(phys_addr_t addr); | 1178 | unsigned long pci_address_to_pio(phys_addr_t addr); |
1168 | phys_addr_t pci_pio_to_address(unsigned long pio); | 1179 | phys_addr_t pci_pio_to_address(unsigned long pio); |
1169 | int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr); | 1180 | int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr); |
1181 | void pci_unmap_iospace(struct resource *res); | ||
1170 | 1182 | ||
1171 | static inline pci_bus_addr_t pci_bus_address(struct pci_dev *pdev, int bar) | 1183 | static inline pci_bus_addr_t pci_bus_address(struct pci_dev *pdev, int bar) |
1172 | { | 1184 | { |
@@ -1389,12 +1401,13 @@ static inline int pci_domain_nr(struct pci_bus *bus) | |||
1389 | { | 1401 | { |
1390 | return bus->domain_nr; | 1402 | return bus->domain_nr; |
1391 | } | 1403 | } |
1392 | void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent); | 1404 | #ifdef CONFIG_ACPI |
1405 | int acpi_pci_bus_find_domain_nr(struct pci_bus *bus); | ||
1393 | #else | 1406 | #else |
1394 | static inline void pci_bus_assign_domain_nr(struct pci_bus *bus, | 1407 | static inline int acpi_pci_bus_find_domain_nr(struct pci_bus *bus) |
1395 | struct device *parent) | 1408 | { return 0; } |
1396 | { | 1409 | #endif |
1397 | } | 1410 | int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent); |
1398 | #endif | 1411 | #endif |
1399 | 1412 | ||
1400 | /* some architectures require additional setup to direct VGA traffic */ | 1413 | /* some architectures require additional setup to direct VGA traffic */ |
@@ -1402,6 +1415,34 @@ typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode, | |||
1402 | unsigned int command_bits, u32 flags); | 1415 | unsigned int command_bits, u32 flags); |
1403 | void pci_register_set_vga_state(arch_set_vga_state_t func); | 1416 | void pci_register_set_vga_state(arch_set_vga_state_t func); |
1404 | 1417 | ||
1418 | static inline int | ||
1419 | pci_request_io_regions(struct pci_dev *pdev, const char *name) | ||
1420 | { | ||
1421 | return pci_request_selected_regions(pdev, | ||
1422 | pci_select_bars(pdev, IORESOURCE_IO), name); | ||
1423 | } | ||
1424 | |||
1425 | static inline void | ||
1426 | pci_release_io_regions(struct pci_dev *pdev) | ||
1427 | { | ||
1428 | return pci_release_selected_regions(pdev, | ||
1429 | pci_select_bars(pdev, IORESOURCE_IO)); | ||
1430 | } | ||
1431 | |||
1432 | static inline int | ||
1433 | pci_request_mem_regions(struct pci_dev *pdev, const char *name) | ||
1434 | { | ||
1435 | return pci_request_selected_regions(pdev, | ||
1436 | pci_select_bars(pdev, IORESOURCE_MEM), name); | ||
1437 | } | ||
1438 | |||
1439 | static inline void | ||
1440 | pci_release_mem_regions(struct pci_dev *pdev) | ||
1441 | { | ||
1442 | return pci_release_selected_regions(pdev, | ||
1443 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
1444 | } | ||
1445 | |||
1405 | #else /* CONFIG_PCI is not enabled */ | 1446 | #else /* CONFIG_PCI is not enabled */ |
1406 | 1447 | ||
1407 | static inline void pci_set_flags(int flags) { } | 1448 | static inline void pci_set_flags(int flags) { } |
@@ -1554,7 +1595,11 @@ static inline const char *pci_name(const struct pci_dev *pdev) | |||
1554 | /* Some archs don't want to expose struct resource to userland as-is | 1595 | /* Some archs don't want to expose struct resource to userland as-is |
1555 | * in sysfs and /proc | 1596 | * in sysfs and /proc |
1556 | */ | 1597 | */ |
1557 | #ifndef HAVE_ARCH_PCI_RESOURCE_TO_USER | 1598 | #ifdef HAVE_ARCH_PCI_RESOURCE_TO_USER |
1599 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
1600 | const struct resource *rsrc, | ||
1601 | resource_size_t *start, resource_size_t *end); | ||
1602 | #else | ||
1558 | static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, | 1603 | static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, |
1559 | const struct resource *rsrc, resource_size_t *start, | 1604 | const struct resource *rsrc, resource_size_t *start, |
1560 | resource_size_t *end) | 1605 | resource_size_t *end) |
@@ -1706,6 +1751,7 @@ extern u8 pci_cache_line_size; | |||
1706 | 1751 | ||
1707 | extern unsigned long pci_hotplug_io_size; | 1752 | extern unsigned long pci_hotplug_io_size; |
1708 | extern unsigned long pci_hotplug_mem_size; | 1753 | extern unsigned long pci_hotplug_mem_size; |
1754 | extern unsigned long pci_hotplug_bus_size; | ||
1709 | 1755 | ||
1710 | /* Architecture-specific versions may override these (weak) */ | 1756 | /* Architecture-specific versions may override these (weak) */ |
1711 | void pcibios_disable_device(struct pci_dev *dev); | 1757 | void pcibios_disable_device(struct pci_dev *dev); |
@@ -1722,7 +1768,7 @@ void pcibios_free_irq(struct pci_dev *dev); | |||
1722 | extern struct dev_pm_ops pcibios_pm_ops; | 1768 | extern struct dev_pm_ops pcibios_pm_ops; |
1723 | #endif | 1769 | #endif |
1724 | 1770 | ||
1725 | #ifdef CONFIG_PCI_MMCONFIG | 1771 | #if defined(CONFIG_PCI_MMCONFIG) || defined(CONFIG_ACPI_MCFG) |
1726 | void __init pci_mmcfg_early_init(void); | 1772 | void __init pci_mmcfg_early_init(void); |
1727 | void __init pci_mmcfg_late_init(void); | 1773 | void __init pci_mmcfg_late_init(void); |
1728 | #else | 1774 | #else |