diff options
63 files changed, 1932 insertions, 736 deletions
diff --git a/Documentation/devicetree/bindings/pci/designware-pcie.txt b/Documentation/devicetree/bindings/pci/designware-pcie.txt index c124f9bc11f3..5561a1c060d0 100644 --- a/Documentation/devicetree/bindings/pci/designware-pcie.txt +++ b/Documentation/devicetree/bindings/pci/designware-pcie.txt | |||
| @@ -4,8 +4,11 @@ Required properties: | |||
| 4 | - compatible: | 4 | - compatible: |
| 5 | "snps,dw-pcie" for RC mode; | 5 | "snps,dw-pcie" for RC mode; |
| 6 | "snps,dw-pcie-ep" for EP mode; | 6 | "snps,dw-pcie-ep" for EP mode; |
| 7 | - reg: Should contain the configuration address space. | 7 | - reg: For designware cores version < 4.80 contains the configuration |
| 8 | - reg-names: Must be "config" for the PCIe configuration space. | 8 | address space. For designware core version >= 4.80, contains |
| 9 | the configuration and ATU address space | ||
| 10 | - reg-names: Must be "config" for the PCIe configuration space and "atu" for | ||
| 11 | the ATU address space. | ||
| 9 | (The old way of getting the configuration address space from "ranges" | 12 | (The old way of getting the configuration address space from "ranges" |
| 10 | is deprecated and should be avoided.) | 13 | is deprecated and should be avoided.) |
| 11 | - num-lanes: number of lanes to use | 14 | - num-lanes: number of lanes to use |
diff --git a/Documentation/devicetree/bindings/pci/pci-keystone.txt b/Documentation/devicetree/bindings/pci/pci-keystone.txt index 2030ee0dc4f9..47202a2938f2 100644 --- a/Documentation/devicetree/bindings/pci/pci-keystone.txt +++ b/Documentation/devicetree/bindings/pci/pci-keystone.txt | |||
| @@ -11,16 +11,24 @@ described here as well as properties that are not applicable. | |||
| 11 | 11 | ||
| 12 | Required Properties:- | 12 | Required Properties:- |
| 13 | 13 | ||
| 14 | compatibility: "ti,keystone-pcie" | 14 | compatibility: Should be "ti,keystone-pcie" for RC on Keystone2 SoC |
| 15 | reg: index 1 is the base address and length of DW application registers. | 15 | Should be "ti,am654-pcie-rc" for RC on AM654x SoC |
| 16 | index 2 is the base address and length of PCI device ID register. | 16 | reg: Three register ranges as listed in the reg-names property |
| 17 | reg-names: "dbics" for the DesignWare PCIe registers, "app" for the | ||
| 18 | TI specific application registers, "config" for the | ||
| 19 | configuration space address | ||
| 17 | 20 | ||
| 18 | pcie_msi_intc : Interrupt controller device node for MSI IRQ chip | 21 | pcie_msi_intc : Interrupt controller device node for MSI IRQ chip |
| 19 | interrupt-cells: should be set to 1 | 22 | interrupt-cells: should be set to 1 |
| 20 | interrupts: GIC interrupt lines connected to PCI MSI interrupt lines | 23 | interrupts: GIC interrupt lines connected to PCI MSI interrupt lines |
| 24 | (required if the compatible is "ti,keystone-pcie") | ||
| 25 | msi-map: As specified in Documentation/devicetree/bindings/pci/pci-msi.txt | ||
| 26 | (required if the compatible is "ti,am654-pcie-rc". | ||
| 21 | 27 | ||
| 22 | ti,syscon-pcie-id : phandle to the device control module required to set device | 28 | ti,syscon-pcie-id : phandle to the device control module required to set device |
| 23 | id and vendor id. | 29 | id and vendor id. |
| 30 | ti,syscon-pcie-mode : phandle to the device control module required to configure | ||
| 31 | PCI in either RC mode or EP mode. | ||
| 24 | 32 | ||
| 25 | Example: | 33 | Example: |
| 26 | pcie_msi_intc: msi-interrupt-controller { | 34 | pcie_msi_intc: msi-interrupt-controller { |
| @@ -61,3 +69,47 @@ Optional properties:- | |||
| 61 | DesignWare DT Properties not applicable for Keystone PCI | 69 | DesignWare DT Properties not applicable for Keystone PCI |
| 62 | 70 | ||
| 63 | 1. pcie_bus clock-names not used. Instead, a phandle to phys is used. | 71 | 1. pcie_bus clock-names not used. Instead, a phandle to phys is used. |
| 72 | |||
| 73 | AM654 PCIe Endpoint | ||
| 74 | =================== | ||
| 75 | |||
| 76 | Required Properties:- | ||
| 77 | |||
| 78 | compatibility: Should be "ti,am654-pcie-ep" for EP on AM654x SoC | ||
| 79 | reg: Four register ranges as listed in the reg-names property | ||
| 80 | reg-names: "dbics" for the DesignWare PCIe registers, "app" for the | ||
| 81 | TI specific application registers, "atu" for the | ||
| 82 | Address Translation Unit configuration registers and | ||
| 83 | "addr_space" used to map remote RC address space | ||
| 84 | num-ib-windows: As specified in | ||
| 85 | Documentation/devicetree/bindings/pci/designware-pcie.txt | ||
| 86 | num-ob-windows: As specified in | ||
| 87 | Documentation/devicetree/bindings/pci/designware-pcie.txt | ||
| 88 | num-lanes: As specified in | ||
| 89 | Documentation/devicetree/bindings/pci/designware-pcie.txt | ||
| 90 | power-domains: As documented by the generic PM domain bindings in | ||
| 91 | Documentation/devicetree/bindings/power/power_domain.txt. | ||
| 92 | ti,syscon-pcie-mode: phandle to the device control module required to configure | ||
| 93 | PCI in either RC mode or EP mode. | ||
| 94 | |||
| 95 | Optional properties:- | ||
| 96 | |||
| 97 | phys: list of PHY specifiers (used by generic PHY framework) | ||
| 98 | phy-names: must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the | ||
| 99 | number of lanes as specified in *num-lanes* property. | ||
| 100 | ("phys" and "phy-names" DT bindings are specified in | ||
| 101 | Documentation/devicetree/bindings/phy/phy-bindings.txt) | ||
| 102 | interrupts: platform interrupt for error interrupts. | ||
| 103 | |||
| 104 | pcie-ep { | ||
| 105 | compatible = "ti,am654-pcie-ep"; | ||
| 106 | reg = <0x5500000 0x1000>, <0x5501000 0x1000>, | ||
| 107 | <0x10000000 0x8000000>, <0x5506000 0x1000>; | ||
| 108 | reg-names = "app", "dbics", "addr_space", "atu"; | ||
| 109 | power-domains = <&k3_pds 120>; | ||
| 110 | ti,syscon-pcie-mode = <&pcie0_mode>; | ||
| 111 | num-lanes = <1>; | ||
| 112 | num-ib-windows = <16>; | ||
| 113 | num-ob-windows = <16>; | ||
| 114 | interrupts = <GIC_SPI 340 IRQ_TYPE_EDGE_RISING>; | ||
| 115 | }; | ||
diff --git a/Documentation/devicetree/bindings/pci/pci.txt b/Documentation/devicetree/bindings/pci/pci.txt index c77981c5dd18..92c01db610df 100644 --- a/Documentation/devicetree/bindings/pci/pci.txt +++ b/Documentation/devicetree/bindings/pci/pci.txt | |||
| @@ -24,3 +24,53 @@ driver implementation may support the following properties: | |||
| 24 | unsupported link speed, for instance, trying to do training for | 24 | unsupported link speed, for instance, trying to do training for |
| 25 | unsupported link speed, etc. Must be '4' for gen4, '3' for gen3, '2' | 25 | unsupported link speed, etc. Must be '4' for gen4, '3' for gen3, '2' |
| 26 | for gen2, and '1' for gen1. Any other values are invalid. | 26 | for gen2, and '1' for gen1. Any other values are invalid. |
| 27 | |||
| 28 | PCI-PCI Bridge properties | ||
| 29 | ------------------------- | ||
| 30 | |||
| 31 | PCIe root ports and switch ports may be described explicitly in the device | ||
| 32 | tree, as children of the host bridge node. Even though those devices are | ||
| 33 | discoverable by probing, it might be necessary to describe properties that | ||
| 34 | aren't provided by standard PCIe capabilities. | ||
| 35 | |||
| 36 | Required properties: | ||
| 37 | |||
| 38 | - reg: | ||
| 39 | Identifies the PCI-PCI bridge. As defined in the IEEE Std 1275-1994 | ||
| 40 | document, it is a five-cell address encoded as (phys.hi phys.mid | ||
| 41 | phys.lo size.hi size.lo). phys.hi should contain the device's BDF as | ||
| 42 | 0b00000000 bbbbbbbb dddddfff 00000000. The other cells should be zero. | ||
| 43 | |||
| 44 | The bus number is defined by firmware, through the standard bridge | ||
| 45 | configuration mechanism. If this port is a switch port, then firmware | ||
| 46 | allocates the bus number and writes it into the Secondary Bus Number | ||
| 47 | register of the bridge directly above this port. Otherwise, the bus | ||
| 48 | number of a root port is the first number in the bus-range property, | ||
| 49 | defaulting to zero. | ||
| 50 | |||
| 51 | If firmware leaves the ARI Forwarding Enable bit set in the bridge | ||
| 52 | above this port, then phys.hi contains the 8-bit function number as | ||
| 53 | 0b00000000 bbbbbbbb ffffffff 00000000. Note that the PCIe specification | ||
| 54 | recommends that firmware only leaves ARI enabled when it knows that the | ||
| 55 | OS is ARI-aware. | ||
| 56 | |||
| 57 | Optional properties: | ||
| 58 | |||
| 59 | - external-facing: | ||
| 60 | When present, the port is external-facing. All bridges and endpoints | ||
| 61 | downstream of this port are external to the machine. The OS can, for | ||
| 62 | example, use this information to identify devices that cannot be | ||
| 63 | trusted with relaxed DMA protection, as users could easily attach | ||
| 64 | malicious devices to this port. | ||
| 65 | |||
| 66 | Example: | ||
| 67 | |||
| 68 | pcie@10000000 { | ||
| 69 | compatible = "pci-host-ecam-generic"; | ||
| 70 | ... | ||
| 71 | pcie@0008 { | ||
| 72 | /* Root port 00:01.0 is external-facing */ | ||
| 73 | reg = <0x00000800 0 0 0 0>; | ||
| 74 | external-facing; | ||
| 75 | }; | ||
| 76 | }; | ||
diff --git a/MAINTAINERS b/MAINTAINERS index e17ebf70b548..b3d64a7daae8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -11880,7 +11880,8 @@ F: include/linux/switchtec.h | |||
| 11880 | F: drivers/ntb/hw/mscc/ | 11880 | F: drivers/ntb/hw/mscc/ |
| 11881 | 11881 | ||
| 11882 | PCI DRIVER FOR MOBIVEIL PCIE IP | 11882 | PCI DRIVER FOR MOBIVEIL PCIE IP |
| 11883 | M: Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in> | 11883 | M: Karthikeyan Mitran <m.karthikeyan@mobiveil.co.in> |
| 11884 | M: Hou Zhiqiang <Zhiqiang.Hou@nxp.com> | ||
| 11884 | L: linux-pci@vger.kernel.org | 11885 | L: linux-pci@vger.kernel.org |
| 11885 | S: Supported | 11886 | S: Supported |
| 11886 | F: Documentation/devicetree/bindings/pci/mobiveil-pcie.txt | 11887 | F: Documentation/devicetree/bindings/pci/mobiveil-pcie.txt |
| @@ -12014,6 +12015,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git/ | |||
| 12014 | S: Supported | 12015 | S: Supported |
| 12015 | F: drivers/pci/controller/ | 12016 | F: drivers/pci/controller/ |
| 12016 | 12017 | ||
| 12018 | PCIE DRIVER FOR ANNAPURNA LABS | ||
| 12019 | M: Jonathan Chocron <jonnyc@amazon.com> | ||
| 12020 | L: linux-pci@vger.kernel.org | ||
| 12021 | S: Maintained | ||
| 12022 | F: drivers/pci/controller/dwc/pcie-al.c | ||
| 12023 | |||
| 12017 | PCIE DRIVER FOR AMLOGIC MESON | 12024 | PCIE DRIVER FOR AMLOGIC MESON |
| 12018 | M: Yue Wang <yue.wang@Amlogic.com> | 12025 | M: Yue Wang <yue.wang@Amlogic.com> |
| 12019 | L: linux-pci@vger.kernel.org | 12026 | L: linux-pci@vger.kernel.org |
diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c index dc23d9d2a7d9..495550432f3d 100644 --- a/arch/powerpc/platforms/powernv/npu-dma.c +++ b/arch/powerpc/platforms/powernv/npu-dma.c | |||
| @@ -1213,9 +1213,8 @@ int pnv_npu2_map_lpar_dev(struct pci_dev *gpdev, unsigned int lparid, | |||
| 1213 | * Currently we only support radix and non-zero LPCR only makes sense | 1213 | * Currently we only support radix and non-zero LPCR only makes sense |
| 1214 | * for hash tables so skiboot expects the LPCR parameter to be a zero. | 1214 | * for hash tables so skiboot expects the LPCR parameter to be a zero. |
| 1215 | */ | 1215 | */ |
| 1216 | ret = opal_npu_map_lpar(nphb->opal_id, | 1216 | ret = opal_npu_map_lpar(nphb->opal_id, pci_dev_id(gpdev), lparid, |
| 1217 | PCI_DEVID(gpdev->bus->number, gpdev->devfn), lparid, | 1217 | 0 /* LPCR bits */); |
| 1218 | 0 /* LPCR bits */); | ||
| 1219 | if (ret) { | 1218 | if (ret) { |
| 1220 | dev_err(&gpdev->dev, "Error %d mapping device to LPAR\n", ret); | 1219 | dev_err(&gpdev->dev, "Error %d mapping device to LPAR\n", ret); |
| 1221 | return ret; | 1220 | return ret; |
| @@ -1224,7 +1223,7 @@ int pnv_npu2_map_lpar_dev(struct pci_dev *gpdev, unsigned int lparid, | |||
| 1224 | dev_dbg(&gpdev->dev, "init context opalid=%llu msr=%lx\n", | 1223 | dev_dbg(&gpdev->dev, "init context opalid=%llu msr=%lx\n", |
| 1225 | nphb->opal_id, msr); | 1224 | nphb->opal_id, msr); |
| 1226 | ret = opal_npu_init_context(nphb->opal_id, 0/*__unused*/, msr, | 1225 | ret = opal_npu_init_context(nphb->opal_id, 0/*__unused*/, msr, |
| 1227 | PCI_DEVID(gpdev->bus->number, gpdev->devfn)); | 1226 | pci_dev_id(gpdev)); |
| 1228 | if (ret < 0) | 1227 | if (ret < 0) |
| 1229 | dev_err(&gpdev->dev, "Failed to init context: %d\n", ret); | 1228 | dev_err(&gpdev->dev, "Failed to init context: %d\n", ret); |
| 1230 | else | 1229 | else |
| @@ -1258,7 +1257,7 @@ int pnv_npu2_unmap_lpar_dev(struct pci_dev *gpdev) | |||
| 1258 | dev_dbg(&gpdev->dev, "destroy context opalid=%llu\n", | 1257 | dev_dbg(&gpdev->dev, "destroy context opalid=%llu\n", |
| 1259 | nphb->opal_id); | 1258 | nphb->opal_id); |
| 1260 | ret = opal_npu_destroy_context(nphb->opal_id, 0/*__unused*/, | 1259 | ret = opal_npu_destroy_context(nphb->opal_id, 0/*__unused*/, |
| 1261 | PCI_DEVID(gpdev->bus->number, gpdev->devfn)); | 1260 | pci_dev_id(gpdev)); |
| 1262 | if (ret < 0) { | 1261 | if (ret < 0) { |
| 1263 | dev_err(&gpdev->dev, "Failed to destroy context: %d\n", ret); | 1262 | dev_err(&gpdev->dev, "Failed to destroy context: %d\n", ret); |
| 1264 | return ret; | 1263 | return ret; |
| @@ -1266,9 +1265,8 @@ int pnv_npu2_unmap_lpar_dev(struct pci_dev *gpdev) | |||
| 1266 | 1265 | ||
| 1267 | /* Set LPID to 0 anyway, just to be safe */ | 1266 | /* Set LPID to 0 anyway, just to be safe */ |
| 1268 | dev_dbg(&gpdev->dev, "Map LPAR opalid=%llu lparid=0\n", nphb->opal_id); | 1267 | dev_dbg(&gpdev->dev, "Map LPAR opalid=%llu lparid=0\n", nphb->opal_id); |
| 1269 | ret = opal_npu_map_lpar(nphb->opal_id, | 1268 | ret = opal_npu_map_lpar(nphb->opal_id, pci_dev_id(gpdev), 0 /*LPID*/, |
| 1270 | PCI_DEVID(gpdev->bus->number, gpdev->devfn), 0 /*LPID*/, | 1269 | 0 /* LPCR bits */); |
| 1271 | 0 /* LPCR bits */); | ||
| 1272 | if (ret) | 1270 | if (ret) |
| 1273 | dev_err(&gpdev->dev, "Error %d mapping device to LPAR\n", ret); | 1271 | dev_err(&gpdev->dev, "Error %d mapping device to LPAR\n", ret); |
| 1274 | 1272 | ||
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 52e55108404e..d3a73f9335e1 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c | |||
| @@ -1119,6 +1119,8 @@ static const struct dmi_system_id pciirq_dmi_table[] __initconst = { | |||
| 1119 | 1119 | ||
| 1120 | void __init pcibios_irq_init(void) | 1120 | void __init pcibios_irq_init(void) |
| 1121 | { | 1121 | { |
| 1122 | struct irq_routing_table *rtable = NULL; | ||
| 1123 | |||
| 1122 | DBG(KERN_DEBUG "PCI: IRQ init\n"); | 1124 | DBG(KERN_DEBUG "PCI: IRQ init\n"); |
| 1123 | 1125 | ||
| 1124 | if (raw_pci_ops == NULL) | 1126 | if (raw_pci_ops == NULL) |
| @@ -1129,8 +1131,10 @@ void __init pcibios_irq_init(void) | |||
| 1129 | pirq_table = pirq_find_routing_table(); | 1131 | pirq_table = pirq_find_routing_table(); |
| 1130 | 1132 | ||
| 1131 | #ifdef CONFIG_PCI_BIOS | 1133 | #ifdef CONFIG_PCI_BIOS |
| 1132 | if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN)) | 1134 | if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN)) { |
| 1133 | pirq_table = pcibios_get_irq_routing_table(); | 1135 | pirq_table = pcibios_get_irq_routing_table(); |
| 1136 | rtable = pirq_table; | ||
| 1137 | } | ||
| 1134 | #endif | 1138 | #endif |
| 1135 | if (pirq_table) { | 1139 | if (pirq_table) { |
| 1136 | pirq_peer_trick(); | 1140 | pirq_peer_trick(); |
| @@ -1145,8 +1149,10 @@ void __init pcibios_irq_init(void) | |||
| 1145 | * If we're using the I/O APIC, avoid using the PCI IRQ | 1149 | * If we're using the I/O APIC, avoid using the PCI IRQ |
| 1146 | * routing table | 1150 | * routing table |
| 1147 | */ | 1151 | */ |
| 1148 | if (io_apic_assign_pci_irqs) | 1152 | if (io_apic_assign_pci_irqs) { |
| 1153 | kfree(rtable); | ||
| 1149 | pirq_table = NULL; | 1154 | pirq_table = NULL; |
| 1155 | } | ||
| 1150 | } | 1156 | } |
| 1151 | 1157 | ||
| 1152 | x86_init.pci.fixup_irqs(); | 1158 | x86_init.pci.fixup_irqs(); |
diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c index a4e8432fc2fb..b42be067fb83 100644 --- a/drivers/acpi/pci_mcfg.c +++ b/drivers/acpi/pci_mcfg.c | |||
| @@ -52,6 +52,18 @@ struct mcfg_fixup { | |||
| 52 | static struct mcfg_fixup mcfg_quirks[] = { | 52 | static struct mcfg_fixup mcfg_quirks[] = { |
| 53 | /* { OEM_ID, OEM_TABLE_ID, REV, SEGMENT, BUS_RANGE, ops, cfgres }, */ | 53 | /* { OEM_ID, OEM_TABLE_ID, REV, SEGMENT, BUS_RANGE, ops, cfgres }, */ |
| 54 | 54 | ||
| 55 | #define AL_ECAM(table_id, rev, seg, ops) \ | ||
| 56 | { "AMAZON", table_id, rev, seg, MCFG_BUS_ANY, ops } | ||
| 57 | |||
| 58 | AL_ECAM("GRAVITON", 0, 0, &al_pcie_ops), | ||
| 59 | AL_ECAM("GRAVITON", 0, 1, &al_pcie_ops), | ||
| 60 | AL_ECAM("GRAVITON", 0, 2, &al_pcie_ops), | ||
| 61 | AL_ECAM("GRAVITON", 0, 3, &al_pcie_ops), | ||
| 62 | AL_ECAM("GRAVITON", 0, 4, &al_pcie_ops), | ||
| 63 | AL_ECAM("GRAVITON", 0, 5, &al_pcie_ops), | ||
| 64 | AL_ECAM("GRAVITON", 0, 6, &al_pcie_ops), | ||
| 65 | AL_ECAM("GRAVITON", 0, 7, &al_pcie_ops), | ||
| 66 | |||
| 55 | #define QCOM_ECAM32(seg) \ | 67 | #define QCOM_ECAM32(seg) \ |
| 56 | { "QCOM ", "QDF2432 ", 1, seg, MCFG_BUS_ANY, &pci_32b_ops } | 68 | { "QCOM ", "QDF2432 ", 1, seg, MCFG_BUS_ANY, &pci_32b_ops } |
| 57 | 69 | ||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 707aafc7c2aa..c36781a9b493 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
| @@ -145,6 +145,7 @@ static struct pci_osc_bit_struct pci_osc_support_bit[] = { | |||
| 145 | { OSC_PCI_CLOCK_PM_SUPPORT, "ClockPM" }, | 145 | { OSC_PCI_CLOCK_PM_SUPPORT, "ClockPM" }, |
| 146 | { OSC_PCI_SEGMENT_GROUPS_SUPPORT, "Segments" }, | 146 | { OSC_PCI_SEGMENT_GROUPS_SUPPORT, "Segments" }, |
| 147 | { OSC_PCI_MSI_SUPPORT, "MSI" }, | 147 | { OSC_PCI_MSI_SUPPORT, "MSI" }, |
| 148 | { OSC_PCI_HPX_TYPE_3_SUPPORT, "HPX-Type3" }, | ||
| 148 | }; | 149 | }; |
| 149 | 150 | ||
| 150 | static struct pci_osc_bit_struct pci_osc_control_bit[] = { | 151 | static struct pci_osc_bit_struct pci_osc_control_bit[] = { |
| @@ -446,6 +447,7 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, | |||
| 446 | * PCI domains, so we indicate this in _OSC support capabilities. | 447 | * PCI domains, so we indicate this in _OSC support capabilities. |
| 447 | */ | 448 | */ |
| 448 | support = OSC_PCI_SEGMENT_GROUPS_SUPPORT; | 449 | support = OSC_PCI_SEGMENT_GROUPS_SUPPORT; |
| 450 | support |= OSC_PCI_HPX_TYPE_3_SUPPORT; | ||
| 449 | if (pci_ext_cfg_avail()) | 451 | if (pci_ext_cfg_avail()) |
| 450 | support |= OSC_PCI_EXT_CONFIG_SUPPORT; | 452 | support |= OSC_PCI_EXT_CONFIG_SUPPORT; |
| 451 | if (pcie_aspm_support_enabled()) | 453 | if (pcie_aspm_support_enabled()) |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 09da91644f9f..b0c59a313049 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c | |||
| @@ -1270,8 +1270,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu) | |||
| 1270 | 1270 | ||
| 1271 | dev->node_props.vendor_id = gpu->pdev->vendor; | 1271 | dev->node_props.vendor_id = gpu->pdev->vendor; |
| 1272 | dev->node_props.device_id = gpu->pdev->device; | 1272 | dev->node_props.device_id = gpu->pdev->device; |
| 1273 | dev->node_props.location_id = PCI_DEVID(gpu->pdev->bus->number, | 1273 | dev->node_props.location_id = pci_dev_id(gpu->pdev); |
| 1274 | gpu->pdev->devfn); | ||
| 1275 | dev->node_props.max_engine_clk_fcompute = | 1274 | dev->node_props.max_engine_clk_fcompute = |
| 1276 | amdgpu_amdkfd_get_max_engine_clock_in_mhz(dev->gpu->kgd); | 1275 | amdgpu_amdkfd_get_max_engine_clock_in_mhz(dev->gpu->kgd); |
| 1277 | dev->node_props.max_engine_clk_ccompute = | 1276 | dev->node_props.max_engine_clk_ccompute = |
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index b319e51c379b..8e8121b14c36 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
| @@ -165,7 +165,7 @@ static inline u16 get_pci_device_id(struct device *dev) | |||
| 165 | { | 165 | { |
| 166 | struct pci_dev *pdev = to_pci_dev(dev); | 166 | struct pci_dev *pdev = to_pci_dev(dev); |
| 167 | 167 | ||
| 168 | return PCI_DEVID(pdev->bus->number, pdev->devfn); | 168 | return pci_dev_id(pdev); |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | static inline int get_acpihid_device_id(struct device *dev, | 171 | static inline int get_acpihid_device_id(struct device *dev, |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 87274b54febd..a772dedb05b9 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
| @@ -1391,7 +1391,7 @@ static void iommu_enable_dev_iotlb(struct device_domain_info *info) | |||
| 1391 | 1391 | ||
| 1392 | /* pdev will be returned if device is not a vf */ | 1392 | /* pdev will be returned if device is not a vf */ |
| 1393 | pf_pdev = pci_physfn(pdev); | 1393 | pf_pdev = pci_physfn(pdev); |
| 1394 | info->pfsid = PCI_DEVID(pf_pdev->bus->number, pf_pdev->devfn); | 1394 | info->pfsid = pci_dev_id(pf_pdev); |
| 1395 | } | 1395 | } |
| 1396 | 1396 | ||
| 1397 | #ifdef CONFIG_INTEL_IOMMU_SVM | 1397 | #ifdef CONFIG_INTEL_IOMMU_SVM |
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 2d74641b7f7b..871458b873be 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c | |||
| @@ -424,7 +424,7 @@ static int set_msi_sid(struct irte *irte, struct pci_dev *dev) | |||
| 424 | set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16, data.alias); | 424 | set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16, data.alias); |
| 425 | else | 425 | else |
| 426 | set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16, | 426 | set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16, |
| 427 | PCI_DEVID(dev->bus->number, dev->devfn)); | 427 | pci_dev_id(dev)); |
| 428 | 428 | ||
| 429 | return 0; | 429 | return 0; |
| 430 | } | 430 | } |
diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c index 29582fe57151..7b015f2a1c6f 100644 --- a/drivers/misc/pci_endpoint_test.c +++ b/drivers/misc/pci_endpoint_test.c | |||
| @@ -75,6 +75,11 @@ | |||
| 75 | #define PCI_ENDPOINT_TEST_IRQ_TYPE 0x24 | 75 | #define PCI_ENDPOINT_TEST_IRQ_TYPE 0x24 |
| 76 | #define PCI_ENDPOINT_TEST_IRQ_NUMBER 0x28 | 76 | #define PCI_ENDPOINT_TEST_IRQ_NUMBER 0x28 |
| 77 | 77 | ||
| 78 | #define PCI_DEVICE_ID_TI_AM654 0xb00c | ||
| 79 | |||
| 80 | #define is_am654_pci_dev(pdev) \ | ||
| 81 | ((pdev)->device == PCI_DEVICE_ID_TI_AM654) | ||
| 82 | |||
| 78 | static DEFINE_IDA(pci_endpoint_test_ida); | 83 | static DEFINE_IDA(pci_endpoint_test_ida); |
| 79 | 84 | ||
| 80 | #define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \ | 85 | #define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \ |
| @@ -588,6 +593,7 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd, | |||
| 588 | int ret = -EINVAL; | 593 | int ret = -EINVAL; |
| 589 | enum pci_barno bar; | 594 | enum pci_barno bar; |
| 590 | struct pci_endpoint_test *test = to_endpoint_test(file->private_data); | 595 | struct pci_endpoint_test *test = to_endpoint_test(file->private_data); |
| 596 | struct pci_dev *pdev = test->pdev; | ||
| 591 | 597 | ||
| 592 | mutex_lock(&test->mutex); | 598 | mutex_lock(&test->mutex); |
| 593 | switch (cmd) { | 599 | switch (cmd) { |
| @@ -595,6 +601,8 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd, | |||
| 595 | bar = arg; | 601 | bar = arg; |
| 596 | if (bar < 0 || bar > 5) | 602 | if (bar < 0 || bar > 5) |
| 597 | goto ret; | 603 | goto ret; |
| 604 | if (is_am654_pci_dev(pdev) && bar == BAR_0) | ||
| 605 | goto ret; | ||
| 598 | ret = pci_endpoint_test_bar(test, bar); | 606 | ret = pci_endpoint_test_bar(test, bar); |
| 599 | break; | 607 | break; |
| 600 | case PCITEST_LEGACY_IRQ: | 608 | case PCITEST_LEGACY_IRQ: |
| @@ -662,6 +670,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, | |||
| 662 | data = (struct pci_endpoint_test_data *)ent->driver_data; | 670 | data = (struct pci_endpoint_test_data *)ent->driver_data; |
| 663 | if (data) { | 671 | if (data) { |
| 664 | test_reg_bar = data->test_reg_bar; | 672 | test_reg_bar = data->test_reg_bar; |
| 673 | test->test_reg_bar = test_reg_bar; | ||
| 665 | test->alignment = data->alignment; | 674 | test->alignment = data->alignment; |
| 666 | irq_type = data->irq_type; | 675 | irq_type = data->irq_type; |
| 667 | } | 676 | } |
| @@ -785,11 +794,20 @@ static void pci_endpoint_test_remove(struct pci_dev *pdev) | |||
| 785 | pci_disable_device(pdev); | 794 | pci_disable_device(pdev); |
| 786 | } | 795 | } |
| 787 | 796 | ||
| 797 | static const struct pci_endpoint_test_data am654_data = { | ||
| 798 | .test_reg_bar = BAR_2, | ||
| 799 | .alignment = SZ_64K, | ||
| 800 | .irq_type = IRQ_TYPE_MSI, | ||
| 801 | }; | ||
| 802 | |||
| 788 | static const struct pci_device_id pci_endpoint_test_tbl[] = { | 803 | static const struct pci_device_id pci_endpoint_test_tbl[] = { |
| 789 | { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x) }, | 804 | { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x) }, |
| 790 | { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x) }, | 805 | { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x) }, |
| 791 | { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x81c0) }, | 806 | { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x81c0) }, |
| 792 | { PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, 0xedda) }, | 807 | { PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, 0xedda) }, |
| 808 | { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654), | ||
| 809 | .driver_data = (kernel_ulong_t)&am654_data | ||
| 810 | }, | ||
| 793 | { } | 811 | { } |
| 794 | }; | 812 | }; |
| 795 | MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl); | 813 | MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl); |
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index c29dde064078..65eb095f94b8 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
| @@ -7182,8 +7182,7 @@ static int r8169_mdio_register(struct rtl8169_private *tp) | |||
| 7182 | new_bus->priv = tp; | 7182 | new_bus->priv = tp; |
| 7183 | new_bus->parent = &pdev->dev; | 7183 | new_bus->parent = &pdev->dev; |
| 7184 | new_bus->irq[0] = PHY_IGNORE_INTERRUPT; | 7184 | new_bus->irq[0] = PHY_IGNORE_INTERRUPT; |
| 7185 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "r8169-%x", | 7185 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "r8169-%x", pci_dev_id(pdev)); |
| 7186 | PCI_DEVID(pdev->bus->number, pdev->devfn)); | ||
| 7187 | 7186 | ||
| 7188 | new_bus->read = r8169_mdio_read_reg; | 7187 | new_bus->read = r8169_mdio_read_reg; |
| 7189 | new_bus->write = r8169_mdio_write_reg; | 7188 | new_bus->write = r8169_mdio_write_reg; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index d819e8eaba12..5cdc17381c80 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | |||
| @@ -204,7 +204,7 @@ static int quark_default_data(struct pci_dev *pdev, | |||
| 204 | ret = 1; | 204 | ret = 1; |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | plat->bus_id = PCI_DEVID(pdev->bus->number, pdev->devfn); | 207 | plat->bus_id = pci_dev_id(pdev); |
| 208 | plat->phy_addr = ret; | 208 | plat->phy_addr = ret; |
| 209 | plat->interface = PHY_INTERFACE_MODE_RMII; | 209 | plat->interface = PHY_INTERFACE_MODE_RMII; |
| 210 | 210 | ||
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 657d642fcc67..28cdd8c0213a 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
| @@ -10,10 +10,10 @@ obj-$(CONFIG_PCI) += access.o bus.o probe.o host-bridge.o \ | |||
| 10 | ifdef CONFIG_PCI | 10 | ifdef CONFIG_PCI |
| 11 | obj-$(CONFIG_PROC_FS) += proc.o | 11 | obj-$(CONFIG_PROC_FS) += proc.o |
| 12 | obj-$(CONFIG_SYSFS) += slot.o | 12 | obj-$(CONFIG_SYSFS) += slot.o |
| 13 | obj-$(CONFIG_OF) += of.o | ||
| 14 | obj-$(CONFIG_ACPI) += pci-acpi.o | 13 | obj-$(CONFIG_ACPI) += pci-acpi.o |
| 15 | endif | 14 | endif |
| 16 | 15 | ||
| 16 | obj-$(CONFIG_OF) += of.o | ||
| 17 | obj-$(CONFIG_PCI_QUIRKS) += quirks.o | 17 | obj-$(CONFIG_PCI_QUIRKS) += quirks.o |
| 18 | obj-$(CONFIG_PCIEPORTBUS) += pcie/ | 18 | obj-$(CONFIG_PCIEPORTBUS) += pcie/ |
| 19 | obj-$(CONFIG_HOTPLUG_PCI) += hotplug/ | 19 | obj-$(CONFIG_HOTPLUG_PCI) += hotplug/ |
diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig index 6ea74b1c0d94..a6ce1ee51b4c 100644 --- a/drivers/pci/controller/dwc/Kconfig +++ b/drivers/pci/controller/dwc/Kconfig | |||
| @@ -103,15 +103,32 @@ config PCIE_SPEAR13XX | |||
| 103 | Say Y here if you want PCIe support on SPEAr13XX SoCs. | 103 | Say Y here if you want PCIe support on SPEAr13XX SoCs. |
| 104 | 104 | ||
| 105 | config PCI_KEYSTONE | 105 | config PCI_KEYSTONE |
| 106 | bool "TI Keystone PCIe controller" | 106 | bool |
| 107 | depends on ARCH_KEYSTONE || (ARM && COMPILE_TEST) | 107 | |
| 108 | config PCI_KEYSTONE_HOST | ||
| 109 | bool "PCI Keystone Host Mode" | ||
| 110 | depends on ARCH_KEYSTONE || ARCH_K3 || ((ARM || ARM64) && COMPILE_TEST) | ||
| 108 | depends on PCI_MSI_IRQ_DOMAIN | 111 | depends on PCI_MSI_IRQ_DOMAIN |
| 109 | select PCIE_DW_HOST | 112 | select PCIE_DW_HOST |
| 113 | select PCI_KEYSTONE | ||
| 114 | default y | ||
| 110 | help | 115 | help |
| 111 | Say Y here if you want to enable PCI controller support on Keystone | 116 | Enables support for the PCIe controller in the Keystone SoC to |
| 112 | SoCs. The PCI controller on Keystone is based on DesignWare hardware | 117 | work in host mode. The PCI controller on Keystone is based on |
| 113 | and therefore the driver re-uses the DesignWare core functions to | 118 | DesignWare hardware and therefore the driver re-uses the |
| 114 | implement the driver. | 119 | DesignWare core functions to implement the driver. |
| 120 | |||
| 121 | config PCI_KEYSTONE_EP | ||
| 122 | bool "PCI Keystone Endpoint Mode" | ||
| 123 | depends on ARCH_KEYSTONE || ARCH_K3 || ((ARM || ARM64) && COMPILE_TEST) | ||
| 124 | depends on PCI_ENDPOINT | ||
| 125 | select PCIE_DW_EP | ||
| 126 | select PCI_KEYSTONE | ||
| 127 | help | ||
| 128 | Enables support for the PCIe controller in the Keystone SoC to | ||
| 129 | work in endpoint mode. The PCI controller on Keystone is based | ||
| 130 | on DesignWare hardware and therefore the driver re-uses the | ||
| 131 | DesignWare core functions to implement the driver. | ||
| 115 | 132 | ||
| 116 | config PCI_LAYERSCAPE | 133 | config PCI_LAYERSCAPE |
| 117 | bool "Freescale Layerscape PCIe controller" | 134 | bool "Freescale Layerscape PCIe controller" |
diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile index b5f3b83cc2b3..b085dfd4fab7 100644 --- a/drivers/pci/controller/dwc/Makefile +++ b/drivers/pci/controller/dwc/Makefile | |||
| @@ -28,5 +28,6 @@ obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o | |||
| 28 | # depending on whether ACPI, the DT driver, or both are enabled. | 28 | # depending on whether ACPI, the DT driver, or both are enabled. |
| 29 | 29 | ||
| 30 | ifdef CONFIG_PCI | 30 | ifdef CONFIG_PCI |
| 31 | obj-$(CONFIG_ARM64) += pcie-al.o | ||
| 31 | obj-$(CONFIG_ARM64) += pcie-hisi.o | 32 | obj-$(CONFIG_ARM64) += pcie-hisi.o |
| 32 | endif | 33 | endif |
diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c index ae84a69ae63a..b287dbf6914c 100644 --- a/drivers/pci/controller/dwc/pci-dra7xx.c +++ b/drivers/pci/controller/dwc/pci-dra7xx.c | |||
| @@ -406,7 +406,7 @@ dra7xx_pcie_get_features(struct dw_pcie_ep *ep) | |||
| 406 | return &dra7xx_pcie_epc_features; | 406 | return &dra7xx_pcie_epc_features; |
| 407 | } | 407 | } |
| 408 | 408 | ||
| 409 | static struct dw_pcie_ep_ops pcie_ep_ops = { | 409 | static const struct dw_pcie_ep_ops pcie_ep_ops = { |
| 410 | .ep_init = dra7xx_pcie_ep_init, | 410 | .ep_init = dra7xx_pcie_ep_init, |
| 411 | .raise_irq = dra7xx_pcie_raise_irq, | 411 | .raise_irq = dra7xx_pcie_raise_irq, |
| 412 | .get_features = dra7xx_pcie_get_features, | 412 | .get_features = dra7xx_pcie_get_features, |
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 3d627f94a166..9b5cb5b70389 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c | |||
| @@ -52,6 +52,7 @@ enum imx6_pcie_variants { | |||
| 52 | 52 | ||
| 53 | #define IMX6_PCIE_FLAG_IMX6_PHY BIT(0) | 53 | #define IMX6_PCIE_FLAG_IMX6_PHY BIT(0) |
| 54 | #define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE BIT(1) | 54 | #define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE BIT(1) |
| 55 | #define IMX6_PCIE_FLAG_SUPPORTS_SUSPEND BIT(2) | ||
| 55 | 56 | ||
| 56 | struct imx6_pcie_drvdata { | 57 | struct imx6_pcie_drvdata { |
| 57 | enum imx6_pcie_variants variant; | 58 | enum imx6_pcie_variants variant; |
| @@ -89,9 +90,8 @@ struct imx6_pcie { | |||
| 89 | }; | 90 | }; |
| 90 | 91 | ||
| 91 | /* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */ | 92 | /* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */ |
| 92 | #define PHY_PLL_LOCK_WAIT_MAX_RETRIES 2000 | ||
| 93 | #define PHY_PLL_LOCK_WAIT_USLEEP_MIN 50 | ||
| 94 | #define PHY_PLL_LOCK_WAIT_USLEEP_MAX 200 | 93 | #define PHY_PLL_LOCK_WAIT_USLEEP_MAX 200 |
| 94 | #define PHY_PLL_LOCK_WAIT_TIMEOUT (2000 * PHY_PLL_LOCK_WAIT_USLEEP_MAX) | ||
| 95 | 95 | ||
| 96 | /* PCIe Root Complex registers (memory-mapped) */ | 96 | /* PCIe Root Complex registers (memory-mapped) */ |
| 97 | #define PCIE_RC_IMX6_MSI_CAP 0x50 | 97 | #define PCIE_RC_IMX6_MSI_CAP 0x50 |
| @@ -104,34 +104,29 @@ struct imx6_pcie { | |||
| 104 | 104 | ||
| 105 | /* PCIe Port Logic registers (memory-mapped) */ | 105 | /* PCIe Port Logic registers (memory-mapped) */ |
| 106 | #define PL_OFFSET 0x700 | 106 | #define PL_OFFSET 0x700 |
| 107 | #define PCIE_PL_PFLR (PL_OFFSET + 0x08) | ||
| 108 | #define PCIE_PL_PFLR_LINK_STATE_MASK (0x3f << 16) | ||
| 109 | #define PCIE_PL_PFLR_FORCE_LINK (1 << 15) | ||
| 110 | #define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28) | ||
| 111 | #define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c) | ||
| 112 | 107 | ||
| 113 | #define PCIE_PHY_CTRL (PL_OFFSET + 0x114) | 108 | #define PCIE_PHY_CTRL (PL_OFFSET + 0x114) |
| 114 | #define PCIE_PHY_CTRL_DATA_LOC 0 | 109 | #define PCIE_PHY_CTRL_DATA(x) FIELD_PREP(GENMASK(15, 0), (x)) |
| 115 | #define PCIE_PHY_CTRL_CAP_ADR_LOC 16 | 110 | #define PCIE_PHY_CTRL_CAP_ADR BIT(16) |
| 116 | #define PCIE_PHY_CTRL_CAP_DAT_LOC 17 | 111 | #define PCIE_PHY_CTRL_CAP_DAT BIT(17) |
| 117 | #define PCIE_PHY_CTRL_WR_LOC 18 | 112 | #define PCIE_PHY_CTRL_WR BIT(18) |
| 118 | #define PCIE_PHY_CTRL_RD_LOC 19 | 113 | #define PCIE_PHY_CTRL_RD BIT(19) |
| 119 | 114 | ||
| 120 | #define PCIE_PHY_STAT (PL_OFFSET + 0x110) | 115 | #define PCIE_PHY_STAT (PL_OFFSET + 0x110) |
| 121 | #define PCIE_PHY_STAT_ACK_LOC 16 | 116 | #define PCIE_PHY_STAT_ACK BIT(16) |
| 122 | 117 | ||
| 123 | #define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C | 118 | #define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C |
| 124 | 119 | ||
| 125 | /* PHY registers (not memory-mapped) */ | 120 | /* PHY registers (not memory-mapped) */ |
| 126 | #define PCIE_PHY_ATEOVRD 0x10 | 121 | #define PCIE_PHY_ATEOVRD 0x10 |
| 127 | #define PCIE_PHY_ATEOVRD_EN (0x1 << 2) | 122 | #define PCIE_PHY_ATEOVRD_EN BIT(2) |
| 128 | #define PCIE_PHY_ATEOVRD_REF_CLKDIV_SHIFT 0 | 123 | #define PCIE_PHY_ATEOVRD_REF_CLKDIV_SHIFT 0 |
| 129 | #define PCIE_PHY_ATEOVRD_REF_CLKDIV_MASK 0x1 | 124 | #define PCIE_PHY_ATEOVRD_REF_CLKDIV_MASK 0x1 |
| 130 | 125 | ||
| 131 | #define PCIE_PHY_MPLL_OVRD_IN_LO 0x11 | 126 | #define PCIE_PHY_MPLL_OVRD_IN_LO 0x11 |
| 132 | #define PCIE_PHY_MPLL_MULTIPLIER_SHIFT 2 | 127 | #define PCIE_PHY_MPLL_MULTIPLIER_SHIFT 2 |
| 133 | #define PCIE_PHY_MPLL_MULTIPLIER_MASK 0x7f | 128 | #define PCIE_PHY_MPLL_MULTIPLIER_MASK 0x7f |
| 134 | #define PCIE_PHY_MPLL_MULTIPLIER_OVRD (0x1 << 9) | 129 | #define PCIE_PHY_MPLL_MULTIPLIER_OVRD BIT(9) |
| 135 | 130 | ||
| 136 | #define PCIE_PHY_RX_ASIC_OUT 0x100D | 131 | #define PCIE_PHY_RX_ASIC_OUT 0x100D |
| 137 | #define PCIE_PHY_RX_ASIC_OUT_VALID (1 << 0) | 132 | #define PCIE_PHY_RX_ASIC_OUT_VALID (1 << 0) |
| @@ -154,19 +149,19 @@ struct imx6_pcie { | |||
| 154 | #define PCIE_PHY_CMN_REG26_ATT_MODE 0xBC | 149 | #define PCIE_PHY_CMN_REG26_ATT_MODE 0xBC |
| 155 | 150 | ||
| 156 | #define PHY_RX_OVRD_IN_LO 0x1005 | 151 | #define PHY_RX_OVRD_IN_LO 0x1005 |
| 157 | #define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5) | 152 | #define PHY_RX_OVRD_IN_LO_RX_DATA_EN BIT(5) |
| 158 | #define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3) | 153 | #define PHY_RX_OVRD_IN_LO_RX_PLL_EN BIT(3) |
| 159 | 154 | ||
| 160 | static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, int exp_val) | 155 | static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, bool exp_val) |
| 161 | { | 156 | { |
| 162 | struct dw_pcie *pci = imx6_pcie->pci; | 157 | struct dw_pcie *pci = imx6_pcie->pci; |
| 163 | u32 val; | 158 | bool val; |
| 164 | u32 max_iterations = 10; | 159 | u32 max_iterations = 10; |
| 165 | u32 wait_counter = 0; | 160 | u32 wait_counter = 0; |
| 166 | 161 | ||
| 167 | do { | 162 | do { |
| 168 | val = dw_pcie_readl_dbi(pci, PCIE_PHY_STAT); | 163 | val = dw_pcie_readl_dbi(pci, PCIE_PHY_STAT) & |
| 169 | val = (val >> PCIE_PHY_STAT_ACK_LOC) & 0x1; | 164 | PCIE_PHY_STAT_ACK; |
| 170 | wait_counter++; | 165 | wait_counter++; |
| 171 | 166 | ||
| 172 | if (val == exp_val) | 167 | if (val == exp_val) |
| @@ -184,27 +179,27 @@ static int pcie_phy_wait_ack(struct imx6_pcie *imx6_pcie, int addr) | |||
| 184 | u32 val; | 179 | u32 val; |
| 185 | int ret; | 180 | int ret; |
| 186 | 181 | ||
| 187 | val = addr << PCIE_PHY_CTRL_DATA_LOC; | 182 | val = PCIE_PHY_CTRL_DATA(addr); |
| 188 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, val); | 183 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, val); |
| 189 | 184 | ||
| 190 | val |= (0x1 << PCIE_PHY_CTRL_CAP_ADR_LOC); | 185 | val |= PCIE_PHY_CTRL_CAP_ADR; |
| 191 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, val); | 186 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, val); |
| 192 | 187 | ||
| 193 | ret = pcie_phy_poll_ack(imx6_pcie, 1); | 188 | ret = pcie_phy_poll_ack(imx6_pcie, true); |
| 194 | if (ret) | 189 | if (ret) |
| 195 | return ret; | 190 | return ret; |
| 196 | 191 | ||
| 197 | val = addr << PCIE_PHY_CTRL_DATA_LOC; | 192 | val = PCIE_PHY_CTRL_DATA(addr); |
| 198 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, val); | 193 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, val); |
| 199 | 194 | ||
| 200 | return pcie_phy_poll_ack(imx6_pcie, 0); | 195 | return pcie_phy_poll_ack(imx6_pcie, false); |
| 201 | } | 196 | } |
| 202 | 197 | ||
| 203 | /* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */ | 198 | /* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */ |
| 204 | static int pcie_phy_read(struct imx6_pcie *imx6_pcie, int addr, int *data) | 199 | static int pcie_phy_read(struct imx6_pcie *imx6_pcie, int addr, u16 *data) |
| 205 | { | 200 | { |
| 206 | struct dw_pcie *pci = imx6_pcie->pci; | 201 | struct dw_pcie *pci = imx6_pcie->pci; |
| 207 | u32 val, phy_ctl; | 202 | u32 phy_ctl; |
| 208 | int ret; | 203 | int ret; |
| 209 | 204 | ||
| 210 | ret = pcie_phy_wait_ack(imx6_pcie, addr); | 205 | ret = pcie_phy_wait_ack(imx6_pcie, addr); |
| @@ -212,23 +207,22 @@ static int pcie_phy_read(struct imx6_pcie *imx6_pcie, int addr, int *data) | |||
| 212 | return ret; | 207 | return ret; |
| 213 | 208 | ||
| 214 | /* assert Read signal */ | 209 | /* assert Read signal */ |
| 215 | phy_ctl = 0x1 << PCIE_PHY_CTRL_RD_LOC; | 210 | phy_ctl = PCIE_PHY_CTRL_RD; |
| 216 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, phy_ctl); | 211 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, phy_ctl); |
| 217 | 212 | ||
| 218 | ret = pcie_phy_poll_ack(imx6_pcie, 1); | 213 | ret = pcie_phy_poll_ack(imx6_pcie, true); |
| 219 | if (ret) | 214 | if (ret) |
| 220 | return ret; | 215 | return ret; |
| 221 | 216 | ||
| 222 | val = dw_pcie_readl_dbi(pci, PCIE_PHY_STAT); | 217 | *data = dw_pcie_readl_dbi(pci, PCIE_PHY_STAT); |
| 223 | *data = val & 0xffff; | ||
| 224 | 218 | ||
| 225 | /* deassert Read signal */ | 219 | /* deassert Read signal */ |
| 226 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, 0x00); | 220 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, 0x00); |
| 227 | 221 | ||
| 228 | return pcie_phy_poll_ack(imx6_pcie, 0); | 222 | return pcie_phy_poll_ack(imx6_pcie, false); |
| 229 | } | 223 | } |
| 230 | 224 | ||
| 231 | static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data) | 225 | static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, u16 data) |
| 232 | { | 226 | { |
| 233 | struct dw_pcie *pci = imx6_pcie->pci; | 227 | struct dw_pcie *pci = imx6_pcie->pci; |
| 234 | u32 var; | 228 | u32 var; |
| @@ -240,41 +234,41 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data) | |||
| 240 | if (ret) | 234 | if (ret) |
| 241 | return ret; | 235 | return ret; |
| 242 | 236 | ||
| 243 | var = data << PCIE_PHY_CTRL_DATA_LOC; | 237 | var = PCIE_PHY_CTRL_DATA(data); |
| 244 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var); | 238 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var); |
| 245 | 239 | ||
| 246 | /* capture data */ | 240 | /* capture data */ |
| 247 | var |= (0x1 << PCIE_PHY_CTRL_CAP_DAT_LOC); | 241 | var |= PCIE_PHY_CTRL_CAP_DAT; |
| 248 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var); | 242 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var); |
| 249 | 243 | ||
| 250 | ret = pcie_phy_poll_ack(imx6_pcie, 1); | 244 | ret = pcie_phy_poll_ack(imx6_pcie, true); |
| 251 | if (ret) | 245 | if (ret) |
| 252 | return ret; | 246 | return ret; |
| 253 | 247 | ||
| 254 | /* deassert cap data */ | 248 | /* deassert cap data */ |
| 255 | var = data << PCIE_PHY_CTRL_DATA_LOC; | 249 | var = PCIE_PHY_CTRL_DATA(data); |
| 256 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var); | 250 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var); |
| 257 | 251 | ||
| 258 | /* wait for ack de-assertion */ | 252 | /* wait for ack de-assertion */ |
| 259 | ret = pcie_phy_poll_ack(imx6_pcie, 0); | 253 | ret = pcie_phy_poll_ack(imx6_pcie, false); |
| 260 | if (ret) | 254 | if (ret) |
| 261 | return ret; | 255 | return ret; |
| 262 | 256 | ||
| 263 | /* assert wr signal */ | 257 | /* assert wr signal */ |
| 264 | var = 0x1 << PCIE_PHY_CTRL_WR_LOC; | 258 | var = PCIE_PHY_CTRL_WR; |
| 265 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var); | 259 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var); |
| 266 | 260 | ||
| 267 | /* wait for ack */ | 261 | /* wait for ack */ |
| 268 | ret = pcie_phy_poll_ack(imx6_pcie, 1); | 262 | ret = pcie_phy_poll_ack(imx6_pcie, true); |
| 269 | if (ret) | 263 | if (ret) |
| 270 | return ret; | 264 | return ret; |
| 271 | 265 | ||
| 272 | /* deassert wr signal */ | 266 | /* deassert wr signal */ |
| 273 | var = data << PCIE_PHY_CTRL_DATA_LOC; | 267 | var = PCIE_PHY_CTRL_DATA(data); |
| 274 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var); | 268 | dw_pcie_writel_dbi(pci, PCIE_PHY_CTRL, var); |
| 275 | 269 | ||
| 276 | /* wait for ack de-assertion */ | 270 | /* wait for ack de-assertion */ |
| 277 | ret = pcie_phy_poll_ack(imx6_pcie, 0); | 271 | ret = pcie_phy_poll_ack(imx6_pcie, false); |
| 278 | if (ret) | 272 | if (ret) |
| 279 | return ret; | 273 | return ret; |
| 280 | 274 | ||
| @@ -285,7 +279,7 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, int data) | |||
| 285 | 279 | ||
| 286 | static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie) | 280 | static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie) |
| 287 | { | 281 | { |
| 288 | u32 tmp; | 282 | u16 tmp; |
| 289 | 283 | ||
| 290 | if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY)) | 284 | if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY)) |
| 291 | return; | 285 | return; |
| @@ -455,7 +449,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) | |||
| 455 | * reset time is too short, cannot meet the requirement. | 449 | * reset time is too short, cannot meet the requirement. |
| 456 | * add one ~10us delay here. | 450 | * add one ~10us delay here. |
| 457 | */ | 451 | */ |
| 458 | udelay(10); | 452 | usleep_range(10, 100); |
| 459 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, | 453 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, |
| 460 | IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); | 454 | IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); |
| 461 | break; | 455 | break; |
| @@ -488,20 +482,14 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) | |||
| 488 | static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie) | 482 | static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie) |
| 489 | { | 483 | { |
| 490 | u32 val; | 484 | u32 val; |
| 491 | unsigned int retries; | ||
| 492 | struct device *dev = imx6_pcie->pci->dev; | 485 | struct device *dev = imx6_pcie->pci->dev; |
| 493 | 486 | ||
| 494 | for (retries = 0; retries < PHY_PLL_LOCK_WAIT_MAX_RETRIES; retries++) { | 487 | if (regmap_read_poll_timeout(imx6_pcie->iomuxc_gpr, |
| 495 | regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR22, &val); | 488 | IOMUXC_GPR22, val, |
| 496 | 489 | val & IMX7D_GPR22_PCIE_PHY_PLL_LOCKED, | |
| 497 | if (val & IMX7D_GPR22_PCIE_PHY_PLL_LOCKED) | 490 | PHY_PLL_LOCK_WAIT_USLEEP_MAX, |
| 498 | return; | 491 | PHY_PLL_LOCK_WAIT_TIMEOUT)) |
| 499 | 492 | dev_err(dev, "PCIe PLL lock timeout\n"); | |
| 500 | usleep_range(PHY_PLL_LOCK_WAIT_USLEEP_MIN, | ||
| 501 | PHY_PLL_LOCK_WAIT_USLEEP_MAX); | ||
| 502 | } | ||
| 503 | |||
| 504 | dev_err(dev, "PCIe PLL lock timeout\n"); | ||
| 505 | } | 493 | } |
| 506 | 494 | ||
| 507 | static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) | 495 | static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) |
| @@ -687,7 +675,7 @@ static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie) | |||
| 687 | { | 675 | { |
| 688 | unsigned long phy_rate = clk_get_rate(imx6_pcie->pcie_phy); | 676 | unsigned long phy_rate = clk_get_rate(imx6_pcie->pcie_phy); |
| 689 | int mult, div; | 677 | int mult, div; |
| 690 | u32 val; | 678 | u16 val; |
| 691 | 679 | ||
| 692 | if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY)) | 680 | if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY)) |
| 693 | return 0; | 681 | return 0; |
| @@ -730,21 +718,6 @@ static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie) | |||
| 730 | return 0; | 718 | return 0; |
| 731 | } | 719 | } |
| 732 | 720 | ||
| 733 | static int imx6_pcie_wait_for_link(struct imx6_pcie *imx6_pcie) | ||
| 734 | { | ||
| 735 | struct dw_pcie *pci = imx6_pcie->pci; | ||
| 736 | struct device *dev = pci->dev; | ||
| 737 | |||
| 738 | /* check if the link is up or not */ | ||
| 739 | if (!dw_pcie_wait_for_link(pci)) | ||
| 740 | return 0; | ||
| 741 | |||
| 742 | dev_dbg(dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n", | ||
| 743 | dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R0), | ||
| 744 | dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1)); | ||
| 745 | return -ETIMEDOUT; | ||
| 746 | } | ||
| 747 | |||
| 748 | static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie) | 721 | static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie) |
| 749 | { | 722 | { |
| 750 | struct dw_pcie *pci = imx6_pcie->pci; | 723 | struct dw_pcie *pci = imx6_pcie->pci; |
| @@ -761,7 +734,7 @@ static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie) | |||
| 761 | } | 734 | } |
| 762 | 735 | ||
| 763 | dev_err(dev, "Speed change timeout\n"); | 736 | dev_err(dev, "Speed change timeout\n"); |
| 764 | return -EINVAL; | 737 | return -ETIMEDOUT; |
| 765 | } | 738 | } |
| 766 | 739 | ||
| 767 | static void imx6_pcie_ltssm_enable(struct device *dev) | 740 | static void imx6_pcie_ltssm_enable(struct device *dev) |
| @@ -803,7 +776,7 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) | |||
| 803 | /* Start LTSSM. */ | 776 | /* Start LTSSM. */ |
| 804 | imx6_pcie_ltssm_enable(dev); | 777 | imx6_pcie_ltssm_enable(dev); |
| 805 | 778 | ||
| 806 | ret = imx6_pcie_wait_for_link(imx6_pcie); | 779 | ret = dw_pcie_wait_for_link(pci); |
| 807 | if (ret) | 780 | if (ret) |
| 808 | goto err_reset_phy; | 781 | goto err_reset_phy; |
| 809 | 782 | ||
| @@ -841,7 +814,7 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) | |||
| 841 | } | 814 | } |
| 842 | 815 | ||
| 843 | /* Make sure link training is finished as well! */ | 816 | /* Make sure link training is finished as well! */ |
| 844 | ret = imx6_pcie_wait_for_link(imx6_pcie); | 817 | ret = dw_pcie_wait_for_link(pci); |
| 845 | if (ret) { | 818 | if (ret) { |
| 846 | dev_err(dev, "Failed to bring link up!\n"); | 819 | dev_err(dev, "Failed to bring link up!\n"); |
| 847 | goto err_reset_phy; | 820 | goto err_reset_phy; |
| @@ -856,8 +829,8 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) | |||
| 856 | 829 | ||
| 857 | err_reset_phy: | 830 | err_reset_phy: |
| 858 | dev_dbg(dev, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n", | 831 | dev_dbg(dev, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n", |
| 859 | dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R0), | 832 | dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG0), |
| 860 | dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1)); | 833 | dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG1)); |
| 861 | imx6_pcie_reset_phy(imx6_pcie); | 834 | imx6_pcie_reset_phy(imx6_pcie); |
| 862 | return ret; | 835 | return ret; |
| 863 | } | 836 | } |
| @@ -993,17 +966,11 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie) | |||
| 993 | } | 966 | } |
| 994 | } | 967 | } |
| 995 | 968 | ||
| 996 | static inline bool imx6_pcie_supports_suspend(struct imx6_pcie *imx6_pcie) | ||
| 997 | { | ||
| 998 | return (imx6_pcie->drvdata->variant == IMX7D || | ||
| 999 | imx6_pcie->drvdata->variant == IMX6SX); | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | static int imx6_pcie_suspend_noirq(struct device *dev) | 969 | static int imx6_pcie_suspend_noirq(struct device *dev) |
| 1003 | { | 970 | { |
| 1004 | struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); | 971 | struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); |
| 1005 | 972 | ||
| 1006 | if (!imx6_pcie_supports_suspend(imx6_pcie)) | 973 | if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_SUPPORTS_SUSPEND)) |
| 1007 | return 0; | 974 | return 0; |
| 1008 | 975 | ||
| 1009 | imx6_pcie_pm_turnoff(imx6_pcie); | 976 | imx6_pcie_pm_turnoff(imx6_pcie); |
| @@ -1019,7 +986,7 @@ static int imx6_pcie_resume_noirq(struct device *dev) | |||
| 1019 | struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); | 986 | struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); |
| 1020 | struct pcie_port *pp = &imx6_pcie->pci->pp; | 987 | struct pcie_port *pp = &imx6_pcie->pci->pp; |
| 1021 | 988 | ||
| 1022 | if (!imx6_pcie_supports_suspend(imx6_pcie)) | 989 | if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_SUPPORTS_SUSPEND)) |
| 1023 | return 0; | 990 | return 0; |
| 1024 | 991 | ||
| 1025 | imx6_pcie_assert_core_reset(imx6_pcie); | 992 | imx6_pcie_assert_core_reset(imx6_pcie); |
| @@ -1249,7 +1216,8 @@ static const struct imx6_pcie_drvdata drvdata[] = { | |||
| 1249 | [IMX6SX] = { | 1216 | [IMX6SX] = { |
| 1250 | .variant = IMX6SX, | 1217 | .variant = IMX6SX, |
| 1251 | .flags = IMX6_PCIE_FLAG_IMX6_PHY | | 1218 | .flags = IMX6_PCIE_FLAG_IMX6_PHY | |
| 1252 | IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE, | 1219 | IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE | |
| 1220 | IMX6_PCIE_FLAG_SUPPORTS_SUSPEND, | ||
| 1253 | }, | 1221 | }, |
| 1254 | [IMX6QP] = { | 1222 | [IMX6QP] = { |
| 1255 | .variant = IMX6QP, | 1223 | .variant = IMX6QP, |
| @@ -1258,6 +1226,7 @@ static const struct imx6_pcie_drvdata drvdata[] = { | |||
| 1258 | }, | 1226 | }, |
| 1259 | [IMX7D] = { | 1227 | [IMX7D] = { |
| 1260 | .variant = IMX7D, | 1228 | .variant = IMX7D, |
| 1229 | .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND, | ||
| 1261 | }, | 1230 | }, |
| 1262 | [IMX8MQ] = { | 1231 | [IMX8MQ] = { |
| 1263 | .variant = IMX8MQ, | 1232 | .variant = IMX8MQ, |
| @@ -1279,6 +1248,7 @@ static struct platform_driver imx6_pcie_driver = { | |||
| 1279 | .of_match_table = imx6_pcie_of_match, | 1248 | .of_match_table = imx6_pcie_of_match, |
| 1280 | .suppress_bind_attrs = true, | 1249 | .suppress_bind_attrs = true, |
| 1281 | .pm = &imx6_pcie_pm_ops, | 1250 | .pm = &imx6_pcie_pm_ops, |
| 1251 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, | ||
| 1282 | }, | 1252 | }, |
| 1283 | .probe = imx6_pcie_probe, | 1253 | .probe = imx6_pcie_probe, |
| 1284 | .shutdown = imx6_pcie_shutdown, | 1254 | .shutdown = imx6_pcie_shutdown, |
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c index 14f2b0b4ed5e..af677254a072 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | #include <linux/clk.h> | 12 | #include <linux/clk.h> |
| 13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
| 14 | #include <linux/gpio/consumer.h> | ||
| 14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| 15 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
| 16 | #include <linux/irqchip/chained_irq.h> | 17 | #include <linux/irqchip/chained_irq.h> |
| @@ -18,6 +19,7 @@ | |||
| 18 | #include <linux/mfd/syscon.h> | 19 | #include <linux/mfd/syscon.h> |
| 19 | #include <linux/msi.h> | 20 | #include <linux/msi.h> |
| 20 | #include <linux/of.h> | 21 | #include <linux/of.h> |
| 22 | #include <linux/of_device.h> | ||
| 21 | #include <linux/of_irq.h> | 23 | #include <linux/of_irq.h> |
| 22 | #include <linux/of_pci.h> | 24 | #include <linux/of_pci.h> |
| 23 | #include <linux/phy/phy.h> | 25 | #include <linux/phy/phy.h> |
| @@ -26,6 +28,7 @@ | |||
| 26 | #include <linux/resource.h> | 28 | #include <linux/resource.h> |
| 27 | #include <linux/signal.h> | 29 | #include <linux/signal.h> |
| 28 | 30 | ||
| 31 | #include "../../pci.h" | ||
| 29 | #include "pcie-designware.h" | 32 | #include "pcie-designware.h" |
| 30 | 33 | ||
| 31 | #define PCIE_VENDORID_MASK 0xffff | 34 | #define PCIE_VENDORID_MASK 0xffff |
| @@ -44,28 +47,34 @@ | |||
| 44 | #define CFG_TYPE1 BIT(24) | 47 | #define CFG_TYPE1 BIT(24) |
| 45 | 48 | ||
| 46 | #define OB_SIZE 0x030 | 49 | #define OB_SIZE 0x030 |
| 47 | #define SPACE0_REMOTE_CFG_OFFSET 0x1000 | ||
| 48 | #define OB_OFFSET_INDEX(n) (0x200 + (8 * (n))) | 50 | #define OB_OFFSET_INDEX(n) (0x200 + (8 * (n))) |
| 49 | #define OB_OFFSET_HI(n) (0x204 + (8 * (n))) | 51 | #define OB_OFFSET_HI(n) (0x204 + (8 * (n))) |
| 50 | #define OB_ENABLEN BIT(0) | 52 | #define OB_ENABLEN BIT(0) |
| 51 | #define OB_WIN_SIZE 8 /* 8MB */ | 53 | #define OB_WIN_SIZE 8 /* 8MB */ |
| 52 | 54 | ||
| 55 | #define PCIE_LEGACY_IRQ_ENABLE_SET(n) (0x188 + (0x10 * ((n) - 1))) | ||
| 56 | #define PCIE_LEGACY_IRQ_ENABLE_CLR(n) (0x18c + (0x10 * ((n) - 1))) | ||
| 57 | #define PCIE_EP_IRQ_SET 0x64 | ||
| 58 | #define PCIE_EP_IRQ_CLR 0x68 | ||
| 59 | #define INT_ENABLE BIT(0) | ||
| 60 | |||
| 53 | /* IRQ register defines */ | 61 | /* IRQ register defines */ |
| 54 | #define IRQ_EOI 0x050 | 62 | #define IRQ_EOI 0x050 |
| 55 | #define IRQ_STATUS 0x184 | ||
| 56 | #define IRQ_ENABLE_SET 0x188 | ||
| 57 | #define IRQ_ENABLE_CLR 0x18c | ||
| 58 | 63 | ||
| 59 | #define MSI_IRQ 0x054 | 64 | #define MSI_IRQ 0x054 |
| 60 | #define MSI0_IRQ_STATUS 0x104 | 65 | #define MSI_IRQ_STATUS(n) (0x104 + ((n) << 4)) |
| 61 | #define MSI0_IRQ_ENABLE_SET 0x108 | 66 | #define MSI_IRQ_ENABLE_SET(n) (0x108 + ((n) << 4)) |
| 62 | #define MSI0_IRQ_ENABLE_CLR 0x10c | 67 | #define MSI_IRQ_ENABLE_CLR(n) (0x10c + ((n) << 4)) |
| 63 | #define IRQ_STATUS 0x184 | ||
| 64 | #define MSI_IRQ_OFFSET 4 | 68 | #define MSI_IRQ_OFFSET 4 |
| 65 | 69 | ||
| 70 | #define IRQ_STATUS(n) (0x184 + ((n) << 4)) | ||
| 71 | #define IRQ_ENABLE_SET(n) (0x188 + ((n) << 4)) | ||
| 72 | #define INTx_EN BIT(0) | ||
| 73 | |||
| 66 | #define ERR_IRQ_STATUS 0x1c4 | 74 | #define ERR_IRQ_STATUS 0x1c4 |
| 67 | #define ERR_IRQ_ENABLE_SET 0x1c8 | 75 | #define ERR_IRQ_ENABLE_SET 0x1c8 |
| 68 | #define ERR_AER BIT(5) /* ECRC error */ | 76 | #define ERR_AER BIT(5) /* ECRC error */ |
| 77 | #define AM6_ERR_AER BIT(4) /* AM6 ECRC error */ | ||
| 69 | #define ERR_AXI BIT(4) /* AXI tag lookup fatal error */ | 78 | #define ERR_AXI BIT(4) /* AXI tag lookup fatal error */ |
| 70 | #define ERR_CORR BIT(3) /* Correctable error */ | 79 | #define ERR_CORR BIT(3) /* Correctable error */ |
| 71 | #define ERR_NONFATAL BIT(2) /* Non-fatal error */ | 80 | #define ERR_NONFATAL BIT(2) /* Non-fatal error */ |
| @@ -74,25 +83,45 @@ | |||
| 74 | #define ERR_IRQ_ALL (ERR_AER | ERR_AXI | ERR_CORR | \ | 83 | #define ERR_IRQ_ALL (ERR_AER | ERR_AXI | ERR_CORR | \ |
| 75 | ERR_NONFATAL | ERR_FATAL | ERR_SYS) | 84 | ERR_NONFATAL | ERR_FATAL | ERR_SYS) |
| 76 | 85 | ||
| 77 | #define MAX_MSI_HOST_IRQS 8 | ||
| 78 | /* PCIE controller device IDs */ | 86 | /* PCIE controller device IDs */ |
| 79 | #define PCIE_RC_K2HK 0xb008 | 87 | #define PCIE_RC_K2HK 0xb008 |
| 80 | #define PCIE_RC_K2E 0xb009 | 88 | #define PCIE_RC_K2E 0xb009 |
| 81 | #define PCIE_RC_K2L 0xb00a | 89 | #define PCIE_RC_K2L 0xb00a |
| 82 | #define PCIE_RC_K2G 0xb00b | 90 | #define PCIE_RC_K2G 0xb00b |
| 83 | 91 | ||
| 92 | #define KS_PCIE_DEV_TYPE_MASK (0x3 << 1) | ||
| 93 | #define KS_PCIE_DEV_TYPE(mode) ((mode) << 1) | ||
| 94 | |||
| 95 | #define EP 0x0 | ||
| 96 | #define LEG_EP 0x1 | ||
| 97 | #define RC 0x2 | ||
| 98 | |||
| 99 | #define EXP_CAP_ID_OFFSET 0x70 | ||
| 100 | |||
| 101 | #define KS_PCIE_SYSCLOCKOUTEN BIT(0) | ||
| 102 | |||
| 103 | #define AM654_PCIE_DEV_TYPE_MASK 0x3 | ||
| 104 | #define AM654_WIN_SIZE SZ_64K | ||
| 105 | |||
| 106 | #define APP_ADDR_SPACE_0 (16 * SZ_1K) | ||
| 107 | |||
| 84 | #define to_keystone_pcie(x) dev_get_drvdata((x)->dev) | 108 | #define to_keystone_pcie(x) dev_get_drvdata((x)->dev) |
| 85 | 109 | ||
| 110 | struct ks_pcie_of_data { | ||
| 111 | enum dw_pcie_device_mode mode; | ||
| 112 | const struct dw_pcie_host_ops *host_ops; | ||
| 113 | const struct dw_pcie_ep_ops *ep_ops; | ||
| 114 | unsigned int version; | ||
| 115 | }; | ||
| 116 | |||
| 86 | struct keystone_pcie { | 117 | struct keystone_pcie { |
| 87 | struct dw_pcie *pci; | 118 | struct dw_pcie *pci; |
| 88 | /* PCI Device ID */ | 119 | /* PCI Device ID */ |
| 89 | u32 device_id; | 120 | u32 device_id; |
| 90 | int num_legacy_host_irqs; | ||
| 91 | int legacy_host_irqs[PCI_NUM_INTX]; | 121 | int legacy_host_irqs[PCI_NUM_INTX]; |
| 92 | struct device_node *legacy_intc_np; | 122 | struct device_node *legacy_intc_np; |
| 93 | 123 | ||
| 94 | int num_msi_host_irqs; | 124 | int msi_host_irq; |
| 95 | int msi_host_irqs[MAX_MSI_HOST_IRQS]; | ||
| 96 | int num_lanes; | 125 | int num_lanes; |
| 97 | u32 num_viewport; | 126 | u32 num_viewport; |
| 98 | struct phy **phy; | 127 | struct phy **phy; |
| @@ -101,28 +130,12 @@ struct keystone_pcie { | |||
| 101 | struct irq_domain *legacy_irq_domain; | 130 | struct irq_domain *legacy_irq_domain; |
| 102 | struct device_node *np; | 131 | struct device_node *np; |
| 103 | 132 | ||
| 104 | int error_irq; | ||
| 105 | |||
| 106 | /* Application register space */ | 133 | /* Application register space */ |
| 107 | void __iomem *va_app_base; /* DT 1st resource */ | 134 | void __iomem *va_app_base; /* DT 1st resource */ |
| 108 | struct resource app; | 135 | struct resource app; |
| 136 | bool is_am6; | ||
| 109 | }; | 137 | }; |
| 110 | 138 | ||
| 111 | static inline void update_reg_offset_bit_pos(u32 offset, u32 *reg_offset, | ||
| 112 | u32 *bit_pos) | ||
| 113 | { | ||
| 114 | *reg_offset = offset % 8; | ||
| 115 | *bit_pos = offset >> 3; | ||
| 116 | } | ||
| 117 | |||
| 118 | static phys_addr_t ks_pcie_get_msi_addr(struct pcie_port *pp) | ||
| 119 | { | ||
| 120 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | ||
| 121 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); | ||
| 122 | |||
| 123 | return ks_pcie->app.start + MSI_IRQ; | ||
| 124 | } | ||
| 125 | |||
| 126 | static u32 ks_pcie_app_readl(struct keystone_pcie *ks_pcie, u32 offset) | 139 | static u32 ks_pcie_app_readl(struct keystone_pcie *ks_pcie, u32 offset) |
| 127 | { | 140 | { |
| 128 | return readl(ks_pcie->va_app_base + offset); | 141 | return readl(ks_pcie->va_app_base + offset); |
| @@ -134,81 +147,114 @@ static void ks_pcie_app_writel(struct keystone_pcie *ks_pcie, u32 offset, | |||
| 134 | writel(val, ks_pcie->va_app_base + offset); | 147 | writel(val, ks_pcie->va_app_base + offset); |
| 135 | } | 148 | } |
| 136 | 149 | ||
| 137 | static void ks_pcie_handle_msi_irq(struct keystone_pcie *ks_pcie, int offset) | 150 | static void ks_pcie_msi_irq_ack(struct irq_data *data) |
| 138 | { | 151 | { |
| 139 | struct dw_pcie *pci = ks_pcie->pci; | 152 | struct pcie_port *pp = irq_data_get_irq_chip_data(data); |
| 140 | struct pcie_port *pp = &pci->pp; | 153 | struct keystone_pcie *ks_pcie; |
| 141 | struct device *dev = pci->dev; | 154 | u32 irq = data->hwirq; |
| 142 | u32 pending, vector; | 155 | struct dw_pcie *pci; |
| 143 | int src, virq; | 156 | u32 reg_offset; |
| 157 | u32 bit_pos; | ||
| 144 | 158 | ||
| 145 | pending = ks_pcie_app_readl(ks_pcie, MSI0_IRQ_STATUS + (offset << 4)); | 159 | pci = to_dw_pcie_from_pp(pp); |
| 160 | ks_pcie = to_keystone_pcie(pci); | ||
| 146 | 161 | ||
| 147 | /* | 162 | reg_offset = irq % 8; |
| 148 | * MSI0 status bit 0-3 shows vectors 0, 8, 16, 24, MSI1 status bit | 163 | bit_pos = irq >> 3; |
| 149 | * shows 1, 9, 17, 25 and so forth | 164 | |
| 150 | */ | 165 | ks_pcie_app_writel(ks_pcie, MSI_IRQ_STATUS(reg_offset), |
| 151 | for (src = 0; src < 4; src++) { | 166 | BIT(bit_pos)); |
| 152 | if (BIT(src) & pending) { | 167 | ks_pcie_app_writel(ks_pcie, IRQ_EOI, reg_offset + MSI_IRQ_OFFSET); |
| 153 | vector = offset + (src << 3); | ||
| 154 | virq = irq_linear_revmap(pp->irq_domain, vector); | ||
| 155 | dev_dbg(dev, "irq: bit %d, vector %d, virq %d\n", | ||
| 156 | src, vector, virq); | ||
| 157 | generic_handle_irq(virq); | ||
| 158 | } | ||
| 159 | } | ||
| 160 | } | 168 | } |
| 161 | 169 | ||
| 162 | static void ks_pcie_msi_irq_ack(int irq, struct pcie_port *pp) | 170 | static void ks_pcie_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) |
| 163 | { | 171 | { |
| 164 | u32 reg_offset, bit_pos; | 172 | struct pcie_port *pp = irq_data_get_irq_chip_data(data); |
| 165 | struct keystone_pcie *ks_pcie; | 173 | struct keystone_pcie *ks_pcie; |
| 166 | struct dw_pcie *pci; | 174 | struct dw_pcie *pci; |
| 175 | u64 msi_target; | ||
| 167 | 176 | ||
| 168 | pci = to_dw_pcie_from_pp(pp); | 177 | pci = to_dw_pcie_from_pp(pp); |
| 169 | ks_pcie = to_keystone_pcie(pci); | 178 | ks_pcie = to_keystone_pcie(pci); |
| 170 | update_reg_offset_bit_pos(irq, ®_offset, &bit_pos); | ||
| 171 | 179 | ||
| 172 | ks_pcie_app_writel(ks_pcie, MSI0_IRQ_STATUS + (reg_offset << 4), | 180 | msi_target = ks_pcie->app.start + MSI_IRQ; |
| 173 | BIT(bit_pos)); | 181 | msg->address_lo = lower_32_bits(msi_target); |
| 174 | ks_pcie_app_writel(ks_pcie, IRQ_EOI, reg_offset + MSI_IRQ_OFFSET); | 182 | msg->address_hi = upper_32_bits(msi_target); |
| 183 | msg->data = data->hwirq; | ||
| 184 | |||
| 185 | dev_dbg(pci->dev, "msi#%d address_hi %#x address_lo %#x\n", | ||
| 186 | (int)data->hwirq, msg->address_hi, msg->address_lo); | ||
| 175 | } | 187 | } |
| 176 | 188 | ||
| 177 | static void ks_pcie_msi_set_irq(struct pcie_port *pp, int irq) | 189 | static int ks_pcie_msi_set_affinity(struct irq_data *irq_data, |
| 190 | const struct cpumask *mask, bool force) | ||
| 178 | { | 191 | { |
| 179 | u32 reg_offset, bit_pos; | 192 | return -EINVAL; |
| 180 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 193 | } |
| 181 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); | ||
| 182 | 194 | ||
| 183 | update_reg_offset_bit_pos(irq, ®_offset, &bit_pos); | 195 | static void ks_pcie_msi_mask(struct irq_data *data) |
| 184 | ks_pcie_app_writel(ks_pcie, MSI0_IRQ_ENABLE_SET + (reg_offset << 4), | 196 | { |
| 197 | struct pcie_port *pp = irq_data_get_irq_chip_data(data); | ||
| 198 | struct keystone_pcie *ks_pcie; | ||
| 199 | u32 irq = data->hwirq; | ||
| 200 | struct dw_pcie *pci; | ||
| 201 | unsigned long flags; | ||
| 202 | u32 reg_offset; | ||
| 203 | u32 bit_pos; | ||
| 204 | |||
| 205 | raw_spin_lock_irqsave(&pp->lock, flags); | ||
| 206 | |||
| 207 | pci = to_dw_pcie_from_pp(pp); | ||
| 208 | ks_pcie = to_keystone_pcie(pci); | ||
| 209 | |||
| 210 | reg_offset = irq % 8; | ||
| 211 | bit_pos = irq >> 3; | ||
| 212 | |||
| 213 | ks_pcie_app_writel(ks_pcie, MSI_IRQ_ENABLE_CLR(reg_offset), | ||
| 185 | BIT(bit_pos)); | 214 | BIT(bit_pos)); |
| 215 | |||
| 216 | raw_spin_unlock_irqrestore(&pp->lock, flags); | ||
| 186 | } | 217 | } |
| 187 | 218 | ||
| 188 | static void ks_pcie_msi_clear_irq(struct pcie_port *pp, int irq) | 219 | static void ks_pcie_msi_unmask(struct irq_data *data) |
| 189 | { | 220 | { |
| 190 | u32 reg_offset, bit_pos; | 221 | struct pcie_port *pp = irq_data_get_irq_chip_data(data); |
| 191 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 222 | struct keystone_pcie *ks_pcie; |
| 192 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); | 223 | u32 irq = data->hwirq; |
| 224 | struct dw_pcie *pci; | ||
| 225 | unsigned long flags; | ||
| 226 | u32 reg_offset; | ||
| 227 | u32 bit_pos; | ||
| 228 | |||
| 229 | raw_spin_lock_irqsave(&pp->lock, flags); | ||
| 193 | 230 | ||
| 194 | update_reg_offset_bit_pos(irq, ®_offset, &bit_pos); | 231 | pci = to_dw_pcie_from_pp(pp); |
| 195 | ks_pcie_app_writel(ks_pcie, MSI0_IRQ_ENABLE_CLR + (reg_offset << 4), | 232 | ks_pcie = to_keystone_pcie(pci); |
| 233 | |||
| 234 | reg_offset = irq % 8; | ||
| 235 | bit_pos = irq >> 3; | ||
| 236 | |||
| 237 | ks_pcie_app_writel(ks_pcie, MSI_IRQ_ENABLE_SET(reg_offset), | ||
| 196 | BIT(bit_pos)); | 238 | BIT(bit_pos)); |
| 239 | |||
| 240 | raw_spin_unlock_irqrestore(&pp->lock, flags); | ||
| 197 | } | 241 | } |
| 198 | 242 | ||
| 243 | static struct irq_chip ks_pcie_msi_irq_chip = { | ||
| 244 | .name = "KEYSTONE-PCI-MSI", | ||
| 245 | .irq_ack = ks_pcie_msi_irq_ack, | ||
| 246 | .irq_compose_msi_msg = ks_pcie_compose_msi_msg, | ||
| 247 | .irq_set_affinity = ks_pcie_msi_set_affinity, | ||
| 248 | .irq_mask = ks_pcie_msi_mask, | ||
| 249 | .irq_unmask = ks_pcie_msi_unmask, | ||
| 250 | }; | ||
| 251 | |||
| 199 | static int ks_pcie_msi_host_init(struct pcie_port *pp) | 252 | static int ks_pcie_msi_host_init(struct pcie_port *pp) |
| 200 | { | 253 | { |
| 254 | pp->msi_irq_chip = &ks_pcie_msi_irq_chip; | ||
| 201 | return dw_pcie_allocate_domains(pp); | 255 | return dw_pcie_allocate_domains(pp); |
| 202 | } | 256 | } |
| 203 | 257 | ||
| 204 | static void ks_pcie_enable_legacy_irqs(struct keystone_pcie *ks_pcie) | ||
| 205 | { | ||
| 206 | int i; | ||
| 207 | |||
| 208 | for (i = 0; i < PCI_NUM_INTX; i++) | ||
| 209 | ks_pcie_app_writel(ks_pcie, IRQ_ENABLE_SET + (i << 4), 0x1); | ||
| 210 | } | ||
| 211 | |||
| 212 | static void ks_pcie_handle_legacy_irq(struct keystone_pcie *ks_pcie, | 258 | static void ks_pcie_handle_legacy_irq(struct keystone_pcie *ks_pcie, |
| 213 | int offset) | 259 | int offset) |
| 214 | { | 260 | { |
| @@ -217,7 +263,7 @@ static void ks_pcie_handle_legacy_irq(struct keystone_pcie *ks_pcie, | |||
| 217 | u32 pending; | 263 | u32 pending; |
| 218 | int virq; | 264 | int virq; |
| 219 | 265 | ||
| 220 | pending = ks_pcie_app_readl(ks_pcie, IRQ_STATUS + (offset << 4)); | 266 | pending = ks_pcie_app_readl(ks_pcie, IRQ_STATUS(offset)); |
| 221 | 267 | ||
| 222 | if (BIT(0) & pending) { | 268 | if (BIT(0) & pending) { |
| 223 | virq = irq_linear_revmap(ks_pcie->legacy_irq_domain, offset); | 269 | virq = irq_linear_revmap(ks_pcie->legacy_irq_domain, offset); |
| @@ -229,6 +275,14 @@ static void ks_pcie_handle_legacy_irq(struct keystone_pcie *ks_pcie, | |||
| 229 | ks_pcie_app_writel(ks_pcie, IRQ_EOI, offset); | 275 | ks_pcie_app_writel(ks_pcie, IRQ_EOI, offset); |
| 230 | } | 276 | } |
| 231 | 277 | ||
| 278 | /* | ||
| 279 | * Dummy function so that DW core doesn't configure MSI | ||
| 280 | */ | ||
| 281 | static int ks_pcie_am654_msi_host_init(struct pcie_port *pp) | ||
| 282 | { | ||
| 283 | return 0; | ||
| 284 | } | ||
| 285 | |||
| 232 | static void ks_pcie_enable_error_irq(struct keystone_pcie *ks_pcie) | 286 | static void ks_pcie_enable_error_irq(struct keystone_pcie *ks_pcie) |
| 233 | { | 287 | { |
| 234 | ks_pcie_app_writel(ks_pcie, ERR_IRQ_ENABLE_SET, ERR_IRQ_ALL); | 288 | ks_pcie_app_writel(ks_pcie, ERR_IRQ_ENABLE_SET, ERR_IRQ_ALL); |
| @@ -255,10 +309,10 @@ static irqreturn_t ks_pcie_handle_error_irq(struct keystone_pcie *ks_pcie) | |||
| 255 | if (reg & ERR_CORR) | 309 | if (reg & ERR_CORR) |
| 256 | dev_dbg(dev, "Correctable Error\n"); | 310 | dev_dbg(dev, "Correctable Error\n"); |
| 257 | 311 | ||
| 258 | if (reg & ERR_AXI) | 312 | if (!ks_pcie->is_am6 && (reg & ERR_AXI)) |
| 259 | dev_err(dev, "AXI tag lookup fatal Error\n"); | 313 | dev_err(dev, "AXI tag lookup fatal Error\n"); |
| 260 | 314 | ||
| 261 | if (reg & ERR_AER) | 315 | if (reg & ERR_AER || (ks_pcie->is_am6 && (reg & AM6_ERR_AER))) |
| 262 | dev_err(dev, "ECRC Error\n"); | 316 | dev_err(dev, "ECRC Error\n"); |
| 263 | 317 | ||
| 264 | ks_pcie_app_writel(ks_pcie, ERR_IRQ_STATUS, reg); | 318 | ks_pcie_app_writel(ks_pcie, ERR_IRQ_STATUS, reg); |
| @@ -356,6 +410,9 @@ static void ks_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie) | |||
| 356 | dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_1, 0); | 410 | dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_1, 0); |
| 357 | ks_pcie_clear_dbi_mode(ks_pcie); | 411 | ks_pcie_clear_dbi_mode(ks_pcie); |
| 358 | 412 | ||
| 413 | if (ks_pcie->is_am6) | ||
| 414 | return; | ||
| 415 | |||
| 359 | val = ilog2(OB_WIN_SIZE); | 416 | val = ilog2(OB_WIN_SIZE); |
| 360 | ks_pcie_app_writel(ks_pcie, OB_SIZE, val); | 417 | ks_pcie_app_writel(ks_pcie, OB_SIZE, val); |
| 361 | 418 | ||
| @@ -445,68 +502,33 @@ static int ks_pcie_link_up(struct dw_pcie *pci) | |||
| 445 | return (val == PORT_LOGIC_LTSSM_STATE_L0); | 502 | return (val == PORT_LOGIC_LTSSM_STATE_L0); |
| 446 | } | 503 | } |
| 447 | 504 | ||
| 448 | static void ks_pcie_initiate_link_train(struct keystone_pcie *ks_pcie) | 505 | static void ks_pcie_stop_link(struct dw_pcie *pci) |
| 449 | { | 506 | { |
| 507 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); | ||
| 450 | u32 val; | 508 | u32 val; |
| 451 | 509 | ||
| 452 | /* Disable Link training */ | 510 | /* Disable Link training */ |
| 453 | val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); | 511 | val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); |
| 454 | val &= ~LTSSM_EN_VAL; | 512 | val &= ~LTSSM_EN_VAL; |
| 455 | ks_pcie_app_writel(ks_pcie, CMD_STATUS, LTSSM_EN_VAL | val); | 513 | ks_pcie_app_writel(ks_pcie, CMD_STATUS, LTSSM_EN_VAL | val); |
| 456 | |||
| 457 | /* Initiate Link Training */ | ||
| 458 | val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); | ||
| 459 | ks_pcie_app_writel(ks_pcie, CMD_STATUS, LTSSM_EN_VAL | val); | ||
| 460 | } | 514 | } |
| 461 | 515 | ||
| 462 | /** | 516 | static int ks_pcie_start_link(struct dw_pcie *pci) |
| 463 | * ks_pcie_dw_host_init() - initialize host for v3_65 dw hardware | ||
| 464 | * | ||
| 465 | * Ioremap the register resources, initialize legacy irq domain | ||
| 466 | * and call dw_pcie_v3_65_host_init() API to initialize the Keystone | ||
| 467 | * PCI host controller. | ||
| 468 | */ | ||
| 469 | static int __init ks_pcie_dw_host_init(struct keystone_pcie *ks_pcie) | ||
| 470 | { | 517 | { |
| 471 | struct dw_pcie *pci = ks_pcie->pci; | 518 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); |
| 472 | struct pcie_port *pp = &pci->pp; | ||
| 473 | struct device *dev = pci->dev; | 519 | struct device *dev = pci->dev; |
| 474 | struct platform_device *pdev = to_platform_device(dev); | 520 | u32 val; |
| 475 | struct resource *res; | ||
| 476 | |||
| 477 | /* Index 0 is the config reg. space address */ | ||
| 478 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 479 | pci->dbi_base = devm_pci_remap_cfg_resource(dev, res); | ||
| 480 | if (IS_ERR(pci->dbi_base)) | ||
| 481 | return PTR_ERR(pci->dbi_base); | ||
| 482 | |||
| 483 | /* | ||
| 484 | * We set these same and is used in pcie rd/wr_other_conf | ||
| 485 | * functions | ||
| 486 | */ | ||
| 487 | pp->va_cfg0_base = pci->dbi_base + SPACE0_REMOTE_CFG_OFFSET; | ||
| 488 | pp->va_cfg1_base = pp->va_cfg0_base; | ||
| 489 | |||
| 490 | /* Index 1 is the application reg. space address */ | ||
| 491 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
| 492 | ks_pcie->va_app_base = devm_ioremap_resource(dev, res); | ||
| 493 | if (IS_ERR(ks_pcie->va_app_base)) | ||
| 494 | return PTR_ERR(ks_pcie->va_app_base); | ||
| 495 | |||
| 496 | ks_pcie->app = *res; | ||
| 497 | 521 | ||
| 498 | /* Create legacy IRQ domain */ | 522 | if (dw_pcie_link_up(pci)) { |
| 499 | ks_pcie->legacy_irq_domain = | 523 | dev_dbg(dev, "link is already up\n"); |
| 500 | irq_domain_add_linear(ks_pcie->legacy_intc_np, | 524 | return 0; |
| 501 | PCI_NUM_INTX, | ||
| 502 | &ks_pcie_legacy_irq_domain_ops, | ||
| 503 | NULL); | ||
| 504 | if (!ks_pcie->legacy_irq_domain) { | ||
| 505 | dev_err(dev, "Failed to add irq domain for legacy irqs\n"); | ||
| 506 | return -EINVAL; | ||
| 507 | } | 525 | } |
| 508 | 526 | ||
| 509 | return dw_pcie_host_init(pp); | 527 | /* Initiate Link Training */ |
| 528 | val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); | ||
| 529 | ks_pcie_app_writel(ks_pcie, CMD_STATUS, LTSSM_EN_VAL | val); | ||
| 530 | |||
| 531 | return 0; | ||
| 510 | } | 532 | } |
| 511 | 533 | ||
| 512 | static void ks_pcie_quirk(struct pci_dev *dev) | 534 | static void ks_pcie_quirk(struct pci_dev *dev) |
| @@ -552,34 +574,16 @@ static void ks_pcie_quirk(struct pci_dev *dev) | |||
| 552 | } | 574 | } |
| 553 | DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, ks_pcie_quirk); | 575 | DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, ks_pcie_quirk); |
| 554 | 576 | ||
| 555 | static int ks_pcie_establish_link(struct keystone_pcie *ks_pcie) | ||
| 556 | { | ||
| 557 | struct dw_pcie *pci = ks_pcie->pci; | ||
| 558 | struct device *dev = pci->dev; | ||
| 559 | |||
| 560 | if (dw_pcie_link_up(pci)) { | ||
| 561 | dev_info(dev, "Link already up\n"); | ||
| 562 | return 0; | ||
| 563 | } | ||
| 564 | |||
| 565 | ks_pcie_initiate_link_train(ks_pcie); | ||
| 566 | |||
| 567 | /* check if the link is up or not */ | ||
| 568 | if (!dw_pcie_wait_for_link(pci)) | ||
| 569 | return 0; | ||
| 570 | |||
| 571 | dev_err(dev, "phy link never came up\n"); | ||
| 572 | return -ETIMEDOUT; | ||
| 573 | } | ||
| 574 | |||
| 575 | static void ks_pcie_msi_irq_handler(struct irq_desc *desc) | 577 | static void ks_pcie_msi_irq_handler(struct irq_desc *desc) |
| 576 | { | 578 | { |
| 577 | unsigned int irq = irq_desc_get_irq(desc); | 579 | unsigned int irq = desc->irq_data.hwirq; |
| 578 | struct keystone_pcie *ks_pcie = irq_desc_get_handler_data(desc); | 580 | struct keystone_pcie *ks_pcie = irq_desc_get_handler_data(desc); |
| 579 | u32 offset = irq - ks_pcie->msi_host_irqs[0]; | 581 | u32 offset = irq - ks_pcie->msi_host_irq; |
| 580 | struct dw_pcie *pci = ks_pcie->pci; | 582 | struct dw_pcie *pci = ks_pcie->pci; |
| 583 | struct pcie_port *pp = &pci->pp; | ||
| 581 | struct device *dev = pci->dev; | 584 | struct device *dev = pci->dev; |
| 582 | struct irq_chip *chip = irq_desc_get_chip(desc); | 585 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 586 | u32 vector, virq, reg, pos; | ||
| 583 | 587 | ||
| 584 | dev_dbg(dev, "%s, irq %d\n", __func__, irq); | 588 | dev_dbg(dev, "%s, irq %d\n", __func__, irq); |
| 585 | 589 | ||
| @@ -589,7 +593,23 @@ static void ks_pcie_msi_irq_handler(struct irq_desc *desc) | |||
| 589 | * ack operation. | 593 | * ack operation. |
| 590 | */ | 594 | */ |
| 591 | chained_irq_enter(chip, desc); | 595 | chained_irq_enter(chip, desc); |
| 592 | ks_pcie_handle_msi_irq(ks_pcie, offset); | 596 | |
| 597 | reg = ks_pcie_app_readl(ks_pcie, MSI_IRQ_STATUS(offset)); | ||
| 598 | /* | ||
| 599 | * MSI0 status bit 0-3 shows vectors 0, 8, 16, 24, MSI1 status bit | ||
| 600 | * shows 1, 9, 17, 25 and so forth | ||
| 601 | */ | ||
| 602 | for (pos = 0; pos < 4; pos++) { | ||
| 603 | if (!(reg & BIT(pos))) | ||
| 604 | continue; | ||
| 605 | |||
| 606 | vector = offset + (pos << 3); | ||
| 607 | virq = irq_linear_revmap(pp->irq_domain, vector); | ||
| 608 | dev_dbg(dev, "irq: bit %d, vector %d, virq %d\n", pos, vector, | ||
| 609 | virq); | ||
| 610 | generic_handle_irq(virq); | ||
| 611 | } | ||
| 612 | |||
| 593 | chained_irq_exit(chip, desc); | 613 | chained_irq_exit(chip, desc); |
| 594 | } | 614 | } |
| 595 | 615 | ||
| @@ -622,89 +642,119 @@ static void ks_pcie_legacy_irq_handler(struct irq_desc *desc) | |||
| 622 | chained_irq_exit(chip, desc); | 642 | chained_irq_exit(chip, desc); |
| 623 | } | 643 | } |
| 624 | 644 | ||
| 625 | static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie, | 645 | static int ks_pcie_config_msi_irq(struct keystone_pcie *ks_pcie) |
| 626 | char *controller, int *num_irqs) | ||
| 627 | { | 646 | { |
| 628 | int temp, max_host_irqs, legacy = 1, *host_irqs; | ||
| 629 | struct device *dev = ks_pcie->pci->dev; | 647 | struct device *dev = ks_pcie->pci->dev; |
| 630 | struct device_node *np_pcie = dev->of_node, **np_temp; | 648 | struct device_node *np = ks_pcie->np; |
| 631 | 649 | struct device_node *intc_np; | |
| 632 | if (!strcmp(controller, "msi-interrupt-controller")) | 650 | struct irq_data *irq_data; |
| 633 | legacy = 0; | 651 | int irq_count, irq, ret, i; |
| 634 | 652 | ||
| 635 | if (legacy) { | 653 | if (!IS_ENABLED(CONFIG_PCI_MSI)) |
| 636 | np_temp = &ks_pcie->legacy_intc_np; | 654 | return 0; |
| 637 | max_host_irqs = PCI_NUM_INTX; | ||
| 638 | host_irqs = &ks_pcie->legacy_host_irqs[0]; | ||
| 639 | } else { | ||
| 640 | np_temp = &ks_pcie->msi_intc_np; | ||
| 641 | max_host_irqs = MAX_MSI_HOST_IRQS; | ||
| 642 | host_irqs = &ks_pcie->msi_host_irqs[0]; | ||
| 643 | } | ||
| 644 | 655 | ||
| 645 | /* interrupt controller is in a child node */ | 656 | intc_np = of_get_child_by_name(np, "msi-interrupt-controller"); |
| 646 | *np_temp = of_get_child_by_name(np_pcie, controller); | 657 | if (!intc_np) { |
| 647 | if (!(*np_temp)) { | 658 | if (ks_pcie->is_am6) |
| 648 | dev_err(dev, "Node for %s is absent\n", controller); | 659 | return 0; |
| 660 | dev_warn(dev, "msi-interrupt-controller node is absent\n"); | ||
| 649 | return -EINVAL; | 661 | return -EINVAL; |
| 650 | } | 662 | } |
| 651 | 663 | ||
| 652 | temp = of_irq_count(*np_temp); | 664 | irq_count = of_irq_count(intc_np); |
| 653 | if (!temp) { | 665 | if (!irq_count) { |
| 654 | dev_err(dev, "No IRQ entries in %s\n", controller); | 666 | dev_err(dev, "No IRQ entries in msi-interrupt-controller\n"); |
| 655 | of_node_put(*np_temp); | 667 | ret = -EINVAL; |
| 656 | return -EINVAL; | 668 | goto err; |
| 657 | } | 669 | } |
| 658 | 670 | ||
| 659 | if (temp > max_host_irqs) | 671 | for (i = 0; i < irq_count; i++) { |
| 660 | dev_warn(dev, "Too many %s interrupts defined %u\n", | 672 | irq = irq_of_parse_and_map(intc_np, i); |
| 661 | (legacy ? "legacy" : "MSI"), temp); | 673 | if (!irq) { |
| 662 | 674 | ret = -EINVAL; | |
| 663 | /* | 675 | goto err; |
| 664 | * support upto max_host_irqs. In dt from index 0 to 3 (legacy) or 0 to | 676 | } |
| 665 | * 7 (MSI) | ||
| 666 | */ | ||
| 667 | for (temp = 0; temp < max_host_irqs; temp++) { | ||
| 668 | host_irqs[temp] = irq_of_parse_and_map(*np_temp, temp); | ||
| 669 | if (!host_irqs[temp]) | ||
| 670 | break; | ||
| 671 | } | ||
| 672 | 677 | ||
| 673 | of_node_put(*np_temp); | 678 | if (!ks_pcie->msi_host_irq) { |
| 679 | irq_data = irq_get_irq_data(irq); | ||
| 680 | if (!irq_data) { | ||
| 681 | ret = -EINVAL; | ||
| 682 | goto err; | ||
| 683 | } | ||
| 684 | ks_pcie->msi_host_irq = irq_data->hwirq; | ||
| 685 | } | ||
| 674 | 686 | ||
| 675 | if (temp) { | 687 | irq_set_chained_handler_and_data(irq, ks_pcie_msi_irq_handler, |
| 676 | *num_irqs = temp; | 688 | ks_pcie); |
| 677 | return 0; | ||
| 678 | } | 689 | } |
| 679 | 690 | ||
| 680 | return -EINVAL; | 691 | of_node_put(intc_np); |
| 692 | return 0; | ||
| 693 | |||
| 694 | err: | ||
| 695 | of_node_put(intc_np); | ||
| 696 | return ret; | ||
| 681 | } | 697 | } |
| 682 | 698 | ||
| 683 | static void ks_pcie_setup_interrupts(struct keystone_pcie *ks_pcie) | 699 | static int ks_pcie_config_legacy_irq(struct keystone_pcie *ks_pcie) |
| 684 | { | 700 | { |
| 685 | int i; | 701 | struct device *dev = ks_pcie->pci->dev; |
| 702 | struct irq_domain *legacy_irq_domain; | ||
| 703 | struct device_node *np = ks_pcie->np; | ||
| 704 | struct device_node *intc_np; | ||
| 705 | int irq_count, irq, ret = 0, i; | ||
| 706 | |||
| 707 | intc_np = of_get_child_by_name(np, "legacy-interrupt-controller"); | ||
| 708 | if (!intc_np) { | ||
| 709 | /* | ||
| 710 | * Since legacy interrupts are modeled as edge-interrupts in | ||
| 711 | * AM6, keep it disabled for now. | ||
| 712 | */ | ||
| 713 | if (ks_pcie->is_am6) | ||
| 714 | return 0; | ||
| 715 | dev_warn(dev, "legacy-interrupt-controller node is absent\n"); | ||
| 716 | return -EINVAL; | ||
| 717 | } | ||
| 686 | 718 | ||
| 687 | /* Legacy IRQ */ | 719 | irq_count = of_irq_count(intc_np); |
| 688 | for (i = 0; i < ks_pcie->num_legacy_host_irqs; i++) { | 720 | if (!irq_count) { |
| 689 | irq_set_chained_handler_and_data(ks_pcie->legacy_host_irqs[i], | 721 | dev_err(dev, "No IRQ entries in legacy-interrupt-controller\n"); |
| 722 | ret = -EINVAL; | ||
| 723 | goto err; | ||
| 724 | } | ||
| 725 | |||
| 726 | for (i = 0; i < irq_count; i++) { | ||
| 727 | irq = irq_of_parse_and_map(intc_np, i); | ||
| 728 | if (!irq) { | ||
| 729 | ret = -EINVAL; | ||
| 730 | goto err; | ||
| 731 | } | ||
| 732 | ks_pcie->legacy_host_irqs[i] = irq; | ||
| 733 | |||
| 734 | irq_set_chained_handler_and_data(irq, | ||
| 690 | ks_pcie_legacy_irq_handler, | 735 | ks_pcie_legacy_irq_handler, |
| 691 | ks_pcie); | 736 | ks_pcie); |
| 692 | } | 737 | } |
| 693 | ks_pcie_enable_legacy_irqs(ks_pcie); | ||
| 694 | 738 | ||
| 695 | /* MSI IRQ */ | 739 | legacy_irq_domain = |
| 696 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | 740 | irq_domain_add_linear(intc_np, PCI_NUM_INTX, |
| 697 | for (i = 0; i < ks_pcie->num_msi_host_irqs; i++) { | 741 | &ks_pcie_legacy_irq_domain_ops, NULL); |
| 698 | irq_set_chained_handler_and_data(ks_pcie->msi_host_irqs[i], | 742 | if (!legacy_irq_domain) { |
| 699 | ks_pcie_msi_irq_handler, | 743 | dev_err(dev, "Failed to add irq domain for legacy irqs\n"); |
| 700 | ks_pcie); | 744 | ret = -EINVAL; |
| 701 | } | 745 | goto err; |
| 702 | } | 746 | } |
| 747 | ks_pcie->legacy_irq_domain = legacy_irq_domain; | ||
| 748 | |||
| 749 | for (i = 0; i < PCI_NUM_INTX; i++) | ||
| 750 | ks_pcie_app_writel(ks_pcie, IRQ_ENABLE_SET(i), INTx_EN); | ||
| 703 | 751 | ||
| 704 | if (ks_pcie->error_irq > 0) | 752 | err: |
| 705 | ks_pcie_enable_error_irq(ks_pcie); | 753 | of_node_put(intc_np); |
| 754 | return ret; | ||
| 706 | } | 755 | } |
| 707 | 756 | ||
| 757 | #ifdef CONFIG_ARM | ||
| 708 | /* | 758 | /* |
| 709 | * When a PCI device does not exist during config cycles, keystone host gets a | 759 | * When a PCI device does not exist during config cycles, keystone host gets a |
| 710 | * bus error instead of returning 0xffffffff. This handler always returns 0 | 760 | * bus error instead of returning 0xffffffff. This handler always returns 0 |
| @@ -724,6 +774,7 @@ static int ks_pcie_fault(unsigned long addr, unsigned int fsr, | |||
| 724 | 774 | ||
| 725 | return 0; | 775 | return 0; |
| 726 | } | 776 | } |
| 777 | #endif | ||
| 727 | 778 | ||
| 728 | static int __init ks_pcie_init_id(struct keystone_pcie *ks_pcie) | 779 | static int __init ks_pcie_init_id(struct keystone_pcie *ks_pcie) |
| 729 | { | 780 | { |
| @@ -742,8 +793,10 @@ static int __init ks_pcie_init_id(struct keystone_pcie *ks_pcie) | |||
| 742 | if (ret) | 793 | if (ret) |
| 743 | return ret; | 794 | return ret; |
| 744 | 795 | ||
| 796 | dw_pcie_dbi_ro_wr_en(pci); | ||
| 745 | dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, id & PCIE_VENDORID_MASK); | 797 | dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, id & PCIE_VENDORID_MASK); |
| 746 | dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, id >> PCIE_DEVICEID_SHIFT); | 798 | dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, id >> PCIE_DEVICEID_SHIFT); |
| 799 | dw_pcie_dbi_ro_wr_dis(pci); | ||
| 747 | 800 | ||
| 748 | return 0; | 801 | return 0; |
| 749 | } | 802 | } |
| @@ -754,11 +807,18 @@ static int __init ks_pcie_host_init(struct pcie_port *pp) | |||
| 754 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); | 807 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); |
| 755 | int ret; | 808 | int ret; |
| 756 | 809 | ||
| 810 | ret = ks_pcie_config_legacy_irq(ks_pcie); | ||
| 811 | if (ret) | ||
| 812 | return ret; | ||
| 813 | |||
| 814 | ret = ks_pcie_config_msi_irq(ks_pcie); | ||
| 815 | if (ret) | ||
| 816 | return ret; | ||
| 817 | |||
| 757 | dw_pcie_setup_rc(pp); | 818 | dw_pcie_setup_rc(pp); |
| 758 | 819 | ||
| 759 | ks_pcie_establish_link(ks_pcie); | 820 | ks_pcie_stop_link(pci); |
| 760 | ks_pcie_setup_rc_app_regs(ks_pcie); | 821 | ks_pcie_setup_rc_app_regs(ks_pcie); |
| 761 | ks_pcie_setup_interrupts(ks_pcie); | ||
| 762 | writew(PCI_IO_RANGE_TYPE_32 | (PCI_IO_RANGE_TYPE_32 << 8), | 822 | writew(PCI_IO_RANGE_TYPE_32 | (PCI_IO_RANGE_TYPE_32 << 8), |
| 763 | pci->dbi_base + PCI_IO_BASE); | 823 | pci->dbi_base + PCI_IO_BASE); |
| 764 | 824 | ||
| @@ -766,12 +826,17 @@ static int __init ks_pcie_host_init(struct pcie_port *pp) | |||
| 766 | if (ret < 0) | 826 | if (ret < 0) |
| 767 | return ret; | 827 | return ret; |
| 768 | 828 | ||
| 829 | #ifdef CONFIG_ARM | ||
| 769 | /* | 830 | /* |
| 770 | * PCIe access errors that result into OCP errors are caught by ARM as | 831 | * PCIe access errors that result into OCP errors are caught by ARM as |
| 771 | * "External aborts" | 832 | * "External aborts" |
| 772 | */ | 833 | */ |
| 773 | hook_fault_code(17, ks_pcie_fault, SIGBUS, 0, | 834 | hook_fault_code(17, ks_pcie_fault, SIGBUS, 0, |
| 774 | "Asynchronous external abort"); | 835 | "Asynchronous external abort"); |
| 836 | #endif | ||
| 837 | |||
| 838 | ks_pcie_start_link(pci); | ||
| 839 | dw_pcie_wait_for_link(pci); | ||
| 775 | 840 | ||
| 776 | return 0; | 841 | return 0; |
| 777 | } | 842 | } |
| @@ -780,14 +845,15 @@ static const struct dw_pcie_host_ops ks_pcie_host_ops = { | |||
| 780 | .rd_other_conf = ks_pcie_rd_other_conf, | 845 | .rd_other_conf = ks_pcie_rd_other_conf, |
| 781 | .wr_other_conf = ks_pcie_wr_other_conf, | 846 | .wr_other_conf = ks_pcie_wr_other_conf, |
| 782 | .host_init = ks_pcie_host_init, | 847 | .host_init = ks_pcie_host_init, |
| 783 | .msi_set_irq = ks_pcie_msi_set_irq, | ||
| 784 | .msi_clear_irq = ks_pcie_msi_clear_irq, | ||
| 785 | .get_msi_addr = ks_pcie_get_msi_addr, | ||
| 786 | .msi_host_init = ks_pcie_msi_host_init, | 848 | .msi_host_init = ks_pcie_msi_host_init, |
| 787 | .msi_irq_ack = ks_pcie_msi_irq_ack, | ||
| 788 | .scan_bus = ks_pcie_v3_65_scan_bus, | 849 | .scan_bus = ks_pcie_v3_65_scan_bus, |
| 789 | }; | 850 | }; |
| 790 | 851 | ||
| 852 | static const struct dw_pcie_host_ops ks_pcie_am654_host_ops = { | ||
| 853 | .host_init = ks_pcie_host_init, | ||
| 854 | .msi_host_init = ks_pcie_am654_msi_host_init, | ||
| 855 | }; | ||
| 856 | |||
| 791 | static irqreturn_t ks_pcie_err_irq_handler(int irq, void *priv) | 857 | static irqreturn_t ks_pcie_err_irq_handler(int irq, void *priv) |
| 792 | { | 858 | { |
| 793 | struct keystone_pcie *ks_pcie = priv; | 859 | struct keystone_pcie *ks_pcie = priv; |
| @@ -801,41 +867,17 @@ static int __init ks_pcie_add_pcie_port(struct keystone_pcie *ks_pcie, | |||
| 801 | struct dw_pcie *pci = ks_pcie->pci; | 867 | struct dw_pcie *pci = ks_pcie->pci; |
| 802 | struct pcie_port *pp = &pci->pp; | 868 | struct pcie_port *pp = &pci->pp; |
| 803 | struct device *dev = &pdev->dev; | 869 | struct device *dev = &pdev->dev; |
| 870 | struct resource *res; | ||
| 804 | int ret; | 871 | int ret; |
| 805 | 872 | ||
| 806 | ret = ks_pcie_get_irq_controller_info(ks_pcie, | 873 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); |
| 807 | "legacy-interrupt-controller", | 874 | pp->va_cfg0_base = devm_pci_remap_cfg_resource(dev, res); |
| 808 | &ks_pcie->num_legacy_host_irqs); | 875 | if (IS_ERR(pp->va_cfg0_base)) |
| 809 | if (ret) | 876 | return PTR_ERR(pp->va_cfg0_base); |
| 810 | return ret; | ||
| 811 | |||
| 812 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | ||
| 813 | ret = ks_pcie_get_irq_controller_info(ks_pcie, | ||
| 814 | "msi-interrupt-controller", | ||
| 815 | &ks_pcie->num_msi_host_irqs); | ||
| 816 | if (ret) | ||
| 817 | return ret; | ||
| 818 | } | ||
| 819 | 877 | ||
| 820 | /* | 878 | pp->va_cfg1_base = pp->va_cfg0_base; |
| 821 | * Index 0 is the platform interrupt for error interrupt | ||
| 822 | * from RC. This is optional. | ||
| 823 | */ | ||
| 824 | ks_pcie->error_irq = irq_of_parse_and_map(ks_pcie->np, 0); | ||
| 825 | if (ks_pcie->error_irq <= 0) | ||
| 826 | dev_info(dev, "no error IRQ defined\n"); | ||
| 827 | else { | ||
| 828 | ret = request_irq(ks_pcie->error_irq, ks_pcie_err_irq_handler, | ||
| 829 | IRQF_SHARED, "pcie-error-irq", ks_pcie); | ||
| 830 | if (ret < 0) { | ||
| 831 | dev_err(dev, "failed to request error IRQ %d\n", | ||
| 832 | ks_pcie->error_irq); | ||
| 833 | return ret; | ||
| 834 | } | ||
| 835 | } | ||
| 836 | 879 | ||
| 837 | pp->ops = &ks_pcie_host_ops; | 880 | ret = dw_pcie_host_init(pp); |
| 838 | ret = ks_pcie_dw_host_init(ks_pcie); | ||
| 839 | if (ret) { | 881 | if (ret) { |
| 840 | dev_err(dev, "failed to initialize host\n"); | 882 | dev_err(dev, "failed to initialize host\n"); |
| 841 | return ret; | 883 | return ret; |
| @@ -844,18 +886,139 @@ static int __init ks_pcie_add_pcie_port(struct keystone_pcie *ks_pcie, | |||
| 844 | return 0; | 886 | return 0; |
| 845 | } | 887 | } |
| 846 | 888 | ||
| 847 | static const struct of_device_id ks_pcie_of_match[] = { | 889 | static u32 ks_pcie_am654_read_dbi2(struct dw_pcie *pci, void __iomem *base, |
| 848 | { | 890 | u32 reg, size_t size) |
| 849 | .type = "pci", | 891 | { |
| 850 | .compatible = "ti,keystone-pcie", | 892 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); |
| 851 | }, | 893 | u32 val; |
| 852 | { }, | 894 | |
| 853 | }; | 895 | ks_pcie_set_dbi_mode(ks_pcie); |
| 896 | dw_pcie_read(base + reg, size, &val); | ||
| 897 | ks_pcie_clear_dbi_mode(ks_pcie); | ||
| 898 | return val; | ||
| 899 | } | ||
| 900 | |||
| 901 | static void ks_pcie_am654_write_dbi2(struct dw_pcie *pci, void __iomem *base, | ||
| 902 | u32 reg, size_t size, u32 val) | ||
| 903 | { | ||
| 904 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); | ||
| 905 | |||
| 906 | ks_pcie_set_dbi_mode(ks_pcie); | ||
| 907 | dw_pcie_write(base + reg, size, val); | ||
| 908 | ks_pcie_clear_dbi_mode(ks_pcie); | ||
| 909 | } | ||
| 854 | 910 | ||
| 855 | static const struct dw_pcie_ops ks_pcie_dw_pcie_ops = { | 911 | static const struct dw_pcie_ops ks_pcie_dw_pcie_ops = { |
| 912 | .start_link = ks_pcie_start_link, | ||
| 913 | .stop_link = ks_pcie_stop_link, | ||
| 856 | .link_up = ks_pcie_link_up, | 914 | .link_up = ks_pcie_link_up, |
| 915 | .read_dbi2 = ks_pcie_am654_read_dbi2, | ||
| 916 | .write_dbi2 = ks_pcie_am654_write_dbi2, | ||
| 917 | }; | ||
| 918 | |||
| 919 | static void ks_pcie_am654_ep_init(struct dw_pcie_ep *ep) | ||
| 920 | { | ||
| 921 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); | ||
| 922 | int flags; | ||
| 923 | |||
| 924 | ep->page_size = AM654_WIN_SIZE; | ||
| 925 | flags = PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32; | ||
| 926 | dw_pcie_writel_dbi2(pci, PCI_BASE_ADDRESS_0, APP_ADDR_SPACE_0 - 1); | ||
| 927 | dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, flags); | ||
| 928 | } | ||
| 929 | |||
| 930 | static void ks_pcie_am654_raise_legacy_irq(struct keystone_pcie *ks_pcie) | ||
| 931 | { | ||
| 932 | struct dw_pcie *pci = ks_pcie->pci; | ||
| 933 | u8 int_pin; | ||
| 934 | |||
| 935 | int_pin = dw_pcie_readb_dbi(pci, PCI_INTERRUPT_PIN); | ||
| 936 | if (int_pin == 0 || int_pin > 4) | ||
| 937 | return; | ||
| 938 | |||
| 939 | ks_pcie_app_writel(ks_pcie, PCIE_LEGACY_IRQ_ENABLE_SET(int_pin), | ||
| 940 | INT_ENABLE); | ||
| 941 | ks_pcie_app_writel(ks_pcie, PCIE_EP_IRQ_SET, INT_ENABLE); | ||
| 942 | mdelay(1); | ||
| 943 | ks_pcie_app_writel(ks_pcie, PCIE_EP_IRQ_CLR, INT_ENABLE); | ||
| 944 | ks_pcie_app_writel(ks_pcie, PCIE_LEGACY_IRQ_ENABLE_CLR(int_pin), | ||
| 945 | INT_ENABLE); | ||
| 946 | } | ||
| 947 | |||
| 948 | static int ks_pcie_am654_raise_irq(struct dw_pcie_ep *ep, u8 func_no, | ||
| 949 | enum pci_epc_irq_type type, | ||
| 950 | u16 interrupt_num) | ||
| 951 | { | ||
| 952 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); | ||
| 953 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); | ||
| 954 | |||
| 955 | switch (type) { | ||
| 956 | case PCI_EPC_IRQ_LEGACY: | ||
| 957 | ks_pcie_am654_raise_legacy_irq(ks_pcie); | ||
| 958 | break; | ||
| 959 | case PCI_EPC_IRQ_MSI: | ||
| 960 | dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); | ||
| 961 | break; | ||
| 962 | default: | ||
| 963 | dev_err(pci->dev, "UNKNOWN IRQ type\n"); | ||
| 964 | return -EINVAL; | ||
| 965 | } | ||
| 966 | |||
| 967 | return 0; | ||
| 968 | } | ||
| 969 | |||
| 970 | static const struct pci_epc_features ks_pcie_am654_epc_features = { | ||
| 971 | .linkup_notifier = false, | ||
| 972 | .msi_capable = true, | ||
| 973 | .msix_capable = false, | ||
| 974 | .reserved_bar = 1 << BAR_0 | 1 << BAR_1, | ||
| 975 | .bar_fixed_64bit = 1 << BAR_0, | ||
| 976 | .bar_fixed_size[2] = SZ_1M, | ||
| 977 | .bar_fixed_size[3] = SZ_64K, | ||
| 978 | .bar_fixed_size[4] = 256, | ||
| 979 | .bar_fixed_size[5] = SZ_1M, | ||
| 980 | .align = SZ_1M, | ||
| 857 | }; | 981 | }; |
| 858 | 982 | ||
| 983 | static const struct pci_epc_features* | ||
| 984 | ks_pcie_am654_get_features(struct dw_pcie_ep *ep) | ||
| 985 | { | ||
| 986 | return &ks_pcie_am654_epc_features; | ||
| 987 | } | ||
| 988 | |||
| 989 | static const struct dw_pcie_ep_ops ks_pcie_am654_ep_ops = { | ||
| 990 | .ep_init = ks_pcie_am654_ep_init, | ||
| 991 | .raise_irq = ks_pcie_am654_raise_irq, | ||
| 992 | .get_features = &ks_pcie_am654_get_features, | ||
| 993 | }; | ||
| 994 | |||
| 995 | static int __init ks_pcie_add_pcie_ep(struct keystone_pcie *ks_pcie, | ||
| 996 | struct platform_device *pdev) | ||
| 997 | { | ||
| 998 | int ret; | ||
| 999 | struct dw_pcie_ep *ep; | ||
| 1000 | struct resource *res; | ||
| 1001 | struct device *dev = &pdev->dev; | ||
| 1002 | struct dw_pcie *pci = ks_pcie->pci; | ||
| 1003 | |||
| 1004 | ep = &pci->ep; | ||
| 1005 | |||
| 1006 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); | ||
| 1007 | if (!res) | ||
| 1008 | return -EINVAL; | ||
| 1009 | |||
| 1010 | ep->phys_base = res->start; | ||
| 1011 | ep->addr_size = resource_size(res); | ||
| 1012 | |||
| 1013 | ret = dw_pcie_ep_init(ep); | ||
| 1014 | if (ret) { | ||
| 1015 | dev_err(dev, "failed to initialize endpoint\n"); | ||
| 1016 | return ret; | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | return 0; | ||
| 1020 | } | ||
| 1021 | |||
| 859 | static void ks_pcie_disable_phy(struct keystone_pcie *ks_pcie) | 1022 | static void ks_pcie_disable_phy(struct keystone_pcie *ks_pcie) |
| 860 | { | 1023 | { |
| 861 | int num_lanes = ks_pcie->num_lanes; | 1024 | int num_lanes = ks_pcie->num_lanes; |
| @@ -873,6 +1036,10 @@ static int ks_pcie_enable_phy(struct keystone_pcie *ks_pcie) | |||
| 873 | int num_lanes = ks_pcie->num_lanes; | 1036 | int num_lanes = ks_pcie->num_lanes; |
| 874 | 1037 | ||
| 875 | for (i = 0; i < num_lanes; i++) { | 1038 | for (i = 0; i < num_lanes; i++) { |
| 1039 | ret = phy_reset(ks_pcie->phy[i]); | ||
| 1040 | if (ret < 0) | ||
| 1041 | goto err_phy; | ||
| 1042 | |||
| 876 | ret = phy_init(ks_pcie->phy[i]); | 1043 | ret = phy_init(ks_pcie->phy[i]); |
| 877 | if (ret < 0) | 1044 | if (ret < 0) |
| 878 | goto err_phy; | 1045 | goto err_phy; |
| @@ -895,20 +1062,161 @@ err_phy: | |||
| 895 | return ret; | 1062 | return ret; |
| 896 | } | 1063 | } |
| 897 | 1064 | ||
| 1065 | static int ks_pcie_set_mode(struct device *dev) | ||
| 1066 | { | ||
| 1067 | struct device_node *np = dev->of_node; | ||
| 1068 | struct regmap *syscon; | ||
| 1069 | u32 val; | ||
| 1070 | u32 mask; | ||
| 1071 | int ret = 0; | ||
| 1072 | |||
| 1073 | syscon = syscon_regmap_lookup_by_phandle(np, "ti,syscon-pcie-mode"); | ||
| 1074 | if (IS_ERR(syscon)) | ||
| 1075 | return 0; | ||
| 1076 | |||
| 1077 | mask = KS_PCIE_DEV_TYPE_MASK | KS_PCIE_SYSCLOCKOUTEN; | ||
| 1078 | val = KS_PCIE_DEV_TYPE(RC) | KS_PCIE_SYSCLOCKOUTEN; | ||
| 1079 | |||
| 1080 | ret = regmap_update_bits(syscon, 0, mask, val); | ||
| 1081 | if (ret) { | ||
| 1082 | dev_err(dev, "failed to set pcie mode\n"); | ||
| 1083 | return ret; | ||
| 1084 | } | ||
| 1085 | |||
| 1086 | return 0; | ||
| 1087 | } | ||
| 1088 | |||
| 1089 | static int ks_pcie_am654_set_mode(struct device *dev, | ||
| 1090 | enum dw_pcie_device_mode mode) | ||
| 1091 | { | ||
| 1092 | struct device_node *np = dev->of_node; | ||
| 1093 | struct regmap *syscon; | ||
| 1094 | u32 val; | ||
| 1095 | u32 mask; | ||
| 1096 | int ret = 0; | ||
| 1097 | |||
| 1098 | syscon = syscon_regmap_lookup_by_phandle(np, "ti,syscon-pcie-mode"); | ||
| 1099 | if (IS_ERR(syscon)) | ||
| 1100 | return 0; | ||
| 1101 | |||
| 1102 | mask = AM654_PCIE_DEV_TYPE_MASK; | ||
| 1103 | |||
| 1104 | switch (mode) { | ||
| 1105 | case DW_PCIE_RC_TYPE: | ||
| 1106 | val = RC; | ||
| 1107 | break; | ||
| 1108 | case DW_PCIE_EP_TYPE: | ||
| 1109 | val = EP; | ||
| 1110 | break; | ||
| 1111 | default: | ||
| 1112 | dev_err(dev, "INVALID device type %d\n", mode); | ||
| 1113 | return -EINVAL; | ||
| 1114 | } | ||
| 1115 | |||
| 1116 | ret = regmap_update_bits(syscon, 0, mask, val); | ||
| 1117 | if (ret) { | ||
| 1118 | dev_err(dev, "failed to set pcie mode\n"); | ||
| 1119 | return ret; | ||
| 1120 | } | ||
| 1121 | |||
| 1122 | return 0; | ||
| 1123 | } | ||
| 1124 | |||
| 1125 | static void ks_pcie_set_link_speed(struct dw_pcie *pci, int link_speed) | ||
| 1126 | { | ||
| 1127 | u32 val; | ||
| 1128 | |||
| 1129 | dw_pcie_dbi_ro_wr_en(pci); | ||
| 1130 | |||
| 1131 | val = dw_pcie_readl_dbi(pci, EXP_CAP_ID_OFFSET + PCI_EXP_LNKCAP); | ||
| 1132 | if ((val & PCI_EXP_LNKCAP_SLS) != link_speed) { | ||
| 1133 | val &= ~((u32)PCI_EXP_LNKCAP_SLS); | ||
| 1134 | val |= link_speed; | ||
| 1135 | dw_pcie_writel_dbi(pci, EXP_CAP_ID_OFFSET + PCI_EXP_LNKCAP, | ||
| 1136 | val); | ||
| 1137 | } | ||
| 1138 | |||
| 1139 | val = dw_pcie_readl_dbi(pci, EXP_CAP_ID_OFFSET + PCI_EXP_LNKCTL2); | ||
| 1140 | if ((val & PCI_EXP_LNKCAP_SLS) != link_speed) { | ||
| 1141 | val &= ~((u32)PCI_EXP_LNKCAP_SLS); | ||
| 1142 | val |= link_speed; | ||
| 1143 | dw_pcie_writel_dbi(pci, EXP_CAP_ID_OFFSET + PCI_EXP_LNKCTL2, | ||
| 1144 | val); | ||
| 1145 | } | ||
| 1146 | |||
| 1147 | dw_pcie_dbi_ro_wr_dis(pci); | ||
| 1148 | } | ||
| 1149 | |||
| 1150 | static const struct ks_pcie_of_data ks_pcie_rc_of_data = { | ||
| 1151 | .host_ops = &ks_pcie_host_ops, | ||
| 1152 | .version = 0x365A, | ||
| 1153 | }; | ||
| 1154 | |||
| 1155 | static const struct ks_pcie_of_data ks_pcie_am654_rc_of_data = { | ||
| 1156 | .host_ops = &ks_pcie_am654_host_ops, | ||
| 1157 | .mode = DW_PCIE_RC_TYPE, | ||
| 1158 | .version = 0x490A, | ||
| 1159 | }; | ||
| 1160 | |||
| 1161 | static const struct ks_pcie_of_data ks_pcie_am654_ep_of_data = { | ||
| 1162 | .ep_ops = &ks_pcie_am654_ep_ops, | ||
| 1163 | .mode = DW_PCIE_EP_TYPE, | ||
| 1164 | .version = 0x490A, | ||
| 1165 | }; | ||
| 1166 | |||
| 1167 | static const struct of_device_id ks_pcie_of_match[] = { | ||
| 1168 | { | ||
| 1169 | .type = "pci", | ||
| 1170 | .data = &ks_pcie_rc_of_data, | ||
| 1171 | .compatible = "ti,keystone-pcie", | ||
| 1172 | }, | ||
| 1173 | { | ||
| 1174 | .data = &ks_pcie_am654_rc_of_data, | ||
| 1175 | .compatible = "ti,am654-pcie-rc", | ||
| 1176 | }, | ||
| 1177 | { | ||
| 1178 | .data = &ks_pcie_am654_ep_of_data, | ||
| 1179 | .compatible = "ti,am654-pcie-ep", | ||
| 1180 | }, | ||
| 1181 | { }, | ||
| 1182 | }; | ||
| 1183 | |||
| 898 | static int __init ks_pcie_probe(struct platform_device *pdev) | 1184 | static int __init ks_pcie_probe(struct platform_device *pdev) |
| 899 | { | 1185 | { |
| 1186 | const struct dw_pcie_host_ops *host_ops; | ||
| 1187 | const struct dw_pcie_ep_ops *ep_ops; | ||
| 900 | struct device *dev = &pdev->dev; | 1188 | struct device *dev = &pdev->dev; |
| 901 | struct device_node *np = dev->of_node; | 1189 | struct device_node *np = dev->of_node; |
| 1190 | const struct ks_pcie_of_data *data; | ||
| 1191 | const struct of_device_id *match; | ||
| 1192 | enum dw_pcie_device_mode mode; | ||
| 902 | struct dw_pcie *pci; | 1193 | struct dw_pcie *pci; |
| 903 | struct keystone_pcie *ks_pcie; | 1194 | struct keystone_pcie *ks_pcie; |
| 904 | struct device_link **link; | 1195 | struct device_link **link; |
| 1196 | struct gpio_desc *gpiod; | ||
| 1197 | void __iomem *atu_base; | ||
| 1198 | struct resource *res; | ||
| 1199 | unsigned int version; | ||
| 1200 | void __iomem *base; | ||
| 905 | u32 num_viewport; | 1201 | u32 num_viewport; |
| 906 | struct phy **phy; | 1202 | struct phy **phy; |
| 1203 | int link_speed; | ||
| 907 | u32 num_lanes; | 1204 | u32 num_lanes; |
| 908 | char name[10]; | 1205 | char name[10]; |
| 909 | int ret; | 1206 | int ret; |
| 1207 | int irq; | ||
| 910 | int i; | 1208 | int i; |
| 911 | 1209 | ||
| 1210 | match = of_match_device(of_match_ptr(ks_pcie_of_match), dev); | ||
| 1211 | data = (struct ks_pcie_of_data *)match->data; | ||
| 1212 | if (!data) | ||
| 1213 | return -EINVAL; | ||
| 1214 | |||
| 1215 | version = data->version; | ||
| 1216 | host_ops = data->host_ops; | ||
| 1217 | ep_ops = data->ep_ops; | ||
| 1218 | mode = data->mode; | ||
| 1219 | |||
| 912 | ks_pcie = devm_kzalloc(dev, sizeof(*ks_pcie), GFP_KERNEL); | 1220 | ks_pcie = devm_kzalloc(dev, sizeof(*ks_pcie), GFP_KERNEL); |
| 913 | if (!ks_pcie) | 1221 | if (!ks_pcie) |
| 914 | return -ENOMEM; | 1222 | return -ENOMEM; |
| @@ -917,12 +1225,38 @@ static int __init ks_pcie_probe(struct platform_device *pdev) | |||
| 917 | if (!pci) | 1225 | if (!pci) |
| 918 | return -ENOMEM; | 1226 | return -ENOMEM; |
| 919 | 1227 | ||
| 1228 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "app"); | ||
| 1229 | ks_pcie->va_app_base = devm_ioremap_resource(dev, res); | ||
| 1230 | if (IS_ERR(ks_pcie->va_app_base)) | ||
| 1231 | return PTR_ERR(ks_pcie->va_app_base); | ||
| 1232 | |||
| 1233 | ks_pcie->app = *res; | ||
| 1234 | |||
| 1235 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbics"); | ||
| 1236 | base = devm_pci_remap_cfg_resource(dev, res); | ||
| 1237 | if (IS_ERR(base)) | ||
| 1238 | return PTR_ERR(base); | ||
| 1239 | |||
| 1240 | if (of_device_is_compatible(np, "ti,am654-pcie-rc")) | ||
| 1241 | ks_pcie->is_am6 = true; | ||
| 1242 | |||
| 1243 | pci->dbi_base = base; | ||
| 1244 | pci->dbi_base2 = base; | ||
| 920 | pci->dev = dev; | 1245 | pci->dev = dev; |
| 921 | pci->ops = &ks_pcie_dw_pcie_ops; | 1246 | pci->ops = &ks_pcie_dw_pcie_ops; |
| 1247 | pci->version = version; | ||
| 1248 | |||
| 1249 | irq = platform_get_irq(pdev, 0); | ||
| 1250 | if (irq < 0) { | ||
| 1251 | dev_err(dev, "missing IRQ resource: %d\n", irq); | ||
| 1252 | return irq; | ||
| 1253 | } | ||
| 922 | 1254 | ||
| 923 | ret = of_property_read_u32(np, "num-viewport", &num_viewport); | 1255 | ret = request_irq(irq, ks_pcie_err_irq_handler, IRQF_SHARED, |
| 1256 | "ks-pcie-error-irq", ks_pcie); | ||
| 924 | if (ret < 0) { | 1257 | if (ret < 0) { |
| 925 | dev_err(dev, "unable to read *num-viewport* property\n"); | 1258 | dev_err(dev, "failed to request error IRQ %d\n", |
| 1259 | irq); | ||
| 926 | return ret; | 1260 | return ret; |
| 927 | } | 1261 | } |
| 928 | 1262 | ||
| @@ -960,9 +1294,17 @@ static int __init ks_pcie_probe(struct platform_device *pdev) | |||
| 960 | ks_pcie->pci = pci; | 1294 | ks_pcie->pci = pci; |
| 961 | ks_pcie->link = link; | 1295 | ks_pcie->link = link; |
| 962 | ks_pcie->num_lanes = num_lanes; | 1296 | ks_pcie->num_lanes = num_lanes; |
| 963 | ks_pcie->num_viewport = num_viewport; | ||
| 964 | ks_pcie->phy = phy; | 1297 | ks_pcie->phy = phy; |
| 965 | 1298 | ||
| 1299 | gpiod = devm_gpiod_get_optional(dev, "reset", | ||
| 1300 | GPIOD_OUT_LOW); | ||
| 1301 | if (IS_ERR(gpiod)) { | ||
| 1302 | ret = PTR_ERR(gpiod); | ||
| 1303 | if (ret != -EPROBE_DEFER) | ||
| 1304 | dev_err(dev, "Failed to get reset GPIO\n"); | ||
| 1305 | goto err_link; | ||
| 1306 | } | ||
| 1307 | |||
| 966 | ret = ks_pcie_enable_phy(ks_pcie); | 1308 | ret = ks_pcie_enable_phy(ks_pcie); |
| 967 | if (ret) { | 1309 | if (ret) { |
| 968 | dev_err(dev, "failed to enable phy\n"); | 1310 | dev_err(dev, "failed to enable phy\n"); |
| @@ -977,9 +1319,79 @@ static int __init ks_pcie_probe(struct platform_device *pdev) | |||
| 977 | goto err_get_sync; | 1319 | goto err_get_sync; |
| 978 | } | 1320 | } |
| 979 | 1321 | ||
| 980 | ret = ks_pcie_add_pcie_port(ks_pcie, pdev); | 1322 | if (pci->version >= 0x480A) { |
| 981 | if (ret < 0) | 1323 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "atu"); |
| 982 | goto err_get_sync; | 1324 | atu_base = devm_ioremap_resource(dev, res); |
| 1325 | if (IS_ERR(atu_base)) { | ||
| 1326 | ret = PTR_ERR(atu_base); | ||
| 1327 | goto err_get_sync; | ||
| 1328 | } | ||
| 1329 | |||
| 1330 | pci->atu_base = atu_base; | ||
| 1331 | |||
| 1332 | ret = ks_pcie_am654_set_mode(dev, mode); | ||
| 1333 | if (ret < 0) | ||
| 1334 | goto err_get_sync; | ||
| 1335 | } else { | ||
| 1336 | ret = ks_pcie_set_mode(dev); | ||
| 1337 | if (ret < 0) | ||
| 1338 | goto err_get_sync; | ||
| 1339 | } | ||
| 1340 | |||
| 1341 | link_speed = of_pci_get_max_link_speed(np); | ||
| 1342 | if (link_speed < 0) | ||
| 1343 | link_speed = 2; | ||
| 1344 | |||
| 1345 | ks_pcie_set_link_speed(pci, link_speed); | ||
| 1346 | |||
| 1347 | switch (mode) { | ||
| 1348 | case DW_PCIE_RC_TYPE: | ||
| 1349 | if (!IS_ENABLED(CONFIG_PCI_KEYSTONE_HOST)) { | ||
| 1350 | ret = -ENODEV; | ||
| 1351 | goto err_get_sync; | ||
| 1352 | } | ||
| 1353 | |||
| 1354 | ret = of_property_read_u32(np, "num-viewport", &num_viewport); | ||
| 1355 | if (ret < 0) { | ||
| 1356 | dev_err(dev, "unable to read *num-viewport* property\n"); | ||
| 1357 | return ret; | ||
| 1358 | } | ||
| 1359 | |||
| 1360 | /* | ||
| 1361 | * "Power Sequencing and Reset Signal Timings" table in | ||
| 1362 | * PCI EXPRESS CARD ELECTROMECHANICAL SPECIFICATION, REV. 2.0 | ||
| 1363 | * indicates PERST# should be deasserted after minimum of 100us | ||
| 1364 | * once REFCLK is stable. The REFCLK to the connector in RC | ||
| 1365 | * mode is selected while enabling the PHY. So deassert PERST# | ||
| 1366 | * after 100 us. | ||
| 1367 | */ | ||
| 1368 | if (gpiod) { | ||
| 1369 | usleep_range(100, 200); | ||
| 1370 | gpiod_set_value_cansleep(gpiod, 1); | ||
| 1371 | } | ||
| 1372 | |||
| 1373 | ks_pcie->num_viewport = num_viewport; | ||
| 1374 | pci->pp.ops = host_ops; | ||
| 1375 | ret = ks_pcie_add_pcie_port(ks_pcie, pdev); | ||
| 1376 | if (ret < 0) | ||
| 1377 | goto err_get_sync; | ||
| 1378 | break; | ||
| 1379 | case DW_PCIE_EP_TYPE: | ||
| 1380 | if (!IS_ENABLED(CONFIG_PCI_KEYSTONE_EP)) { | ||
| 1381 | ret = -ENODEV; | ||
| 1382 | goto err_get_sync; | ||
| 1383 | } | ||
| 1384 | |||
| 1385 | pci->ep.ops = ep_ops; | ||
| 1386 | ret = ks_pcie_add_pcie_ep(ks_pcie, pdev); | ||
| 1387 | if (ret < 0) | ||
| 1388 | goto err_get_sync; | ||
| 1389 | break; | ||
| 1390 | default: | ||
| 1391 | dev_err(dev, "INVALID device type %d\n", mode); | ||
| 1392 | } | ||
| 1393 | |||
| 1394 | ks_pcie_enable_error_irq(ks_pcie); | ||
| 983 | 1395 | ||
| 984 | return 0; | 1396 | return 0; |
| 985 | 1397 | ||
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c index a42c9c3ae1cc..be61d96cc95e 100644 --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c | |||
| @@ -79,7 +79,7 @@ static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, | |||
| 79 | } | 79 | } |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | static struct dw_pcie_ep_ops pcie_ep_ops = { | 82 | static const struct dw_pcie_ep_ops pcie_ep_ops = { |
| 83 | .ep_init = ls_pcie_ep_init, | 83 | .ep_init = ls_pcie_ep_init, |
| 84 | .raise_irq = ls_pcie_ep_raise_irq, | 84 | .raise_irq = ls_pcie_ep_raise_irq, |
| 85 | .get_features = ls_pcie_ep_get_features, | 85 | .get_features = ls_pcie_ep_get_features, |
diff --git a/drivers/pci/controller/dwc/pcie-al.c b/drivers/pci/controller/dwc/pcie-al.c new file mode 100644 index 000000000000..3ab58f0584a8 --- /dev/null +++ b/drivers/pci/controller/dwc/pcie-al.c | |||
| @@ -0,0 +1,93 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * PCIe host controller driver for Amazon's Annapurna Labs IP (used in chips | ||
| 4 | * such as Graviton and Alpine) | ||
| 5 | * | ||
| 6 | * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| 7 | * | ||
| 8 | * Author: Jonathan Chocron <jonnyc@amazon.com> | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/pci.h> | ||
| 12 | #include <linux/pci-ecam.h> | ||
| 13 | #include <linux/pci-acpi.h> | ||
| 14 | #include "../../pci.h" | ||
| 15 | |||
| 16 | #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) | ||
| 17 | |||
| 18 | struct al_pcie_acpi { | ||
| 19 | void __iomem *dbi_base; | ||
| 20 | }; | ||
| 21 | |||
| 22 | static void __iomem *al_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, | ||
| 23 | int where) | ||
| 24 | { | ||
| 25 | struct pci_config_window *cfg = bus->sysdata; | ||
| 26 | struct al_pcie_acpi *pcie = cfg->priv; | ||
| 27 | void __iomem *dbi_base = pcie->dbi_base; | ||
| 28 | |||
| 29 | if (bus->number == cfg->busr.start) { | ||
| 30 | /* | ||
| 31 | * The DW PCIe core doesn't filter out transactions to other | ||
| 32 | * devices/functions on the root bus num, so we do this here. | ||
| 33 | */ | ||
| 34 | if (PCI_SLOT(devfn) > 0) | ||
| 35 | return NULL; | ||
| 36 | else | ||
| 37 | return dbi_base + where; | ||
| 38 | } | ||
| 39 | |||
| 40 | return pci_ecam_map_bus(bus, devfn, where); | ||
| 41 | } | ||
| 42 | |||
| 43 | static int al_pcie_init(struct pci_config_window *cfg) | ||
| 44 | { | ||
| 45 | struct device *dev = cfg->parent; | ||
| 46 | struct acpi_device *adev = to_acpi_device(dev); | ||
| 47 | struct acpi_pci_root *root = acpi_driver_data(adev); | ||
| 48 | struct al_pcie_acpi *al_pcie; | ||
| 49 | struct resource *res; | ||
| 50 | int ret; | ||
| 51 | |||
| 52 | al_pcie = devm_kzalloc(dev, sizeof(*al_pcie), GFP_KERNEL); | ||
| 53 | if (!al_pcie) | ||
| 54 | return -ENOMEM; | ||
| 55 | |||
| 56 | res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL); | ||
| 57 | if (!res) | ||
| 58 | return -ENOMEM; | ||
| 59 | |||
| 60 | ret = acpi_get_rc_resources(dev, "AMZN0001", root->segment, res); | ||
| 61 | if (ret) { | ||
| 62 | dev_err(dev, "can't get rc dbi base address for SEG %d\n", | ||
| 63 | root->segment); | ||
| 64 | return ret; | ||
| 65 | } | ||
| 66 | |||
| 67 | dev_dbg(dev, "Root port dbi res: %pR\n", res); | ||
| 68 | |||
| 69 | al_pcie->dbi_base = devm_pci_remap_cfg_resource(dev, res); | ||
| 70 | if (IS_ERR(al_pcie->dbi_base)) { | ||
| 71 | long err = PTR_ERR(al_pcie->dbi_base); | ||
| 72 | |||
| 73 | dev_err(dev, "couldn't remap dbi base %pR (err:%ld)\n", | ||
| 74 | res, err); | ||
| 75 | return err; | ||
| 76 | } | ||
| 77 | |||
| 78 | cfg->priv = al_pcie; | ||
| 79 | |||
| 80 | return 0; | ||
| 81 | } | ||
| 82 | |||
| 83 | struct pci_ecam_ops al_pcie_ops = { | ||
| 84 | .bus_shift = 20, | ||
| 85 | .init = al_pcie_init, | ||
| 86 | .pci_ops = { | ||
| 87 | .map_bus = al_pcie_map_bus, | ||
| 88 | .read = pci_generic_config_read, | ||
| 89 | .write = pci_generic_config_write, | ||
| 90 | } | ||
| 91 | }; | ||
| 92 | |||
| 93 | #endif /* defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) */ | ||
diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c index dba83abfe764..d00252bd8fae 100644 --- a/drivers/pci/controller/dwc/pcie-artpec6.c +++ b/drivers/pci/controller/dwc/pcie-artpec6.c | |||
| @@ -444,7 +444,7 @@ static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, | |||
| 444 | return 0; | 444 | return 0; |
| 445 | } | 445 | } |
| 446 | 446 | ||
| 447 | static struct dw_pcie_ep_ops pcie_ep_ops = { | 447 | static const struct dw_pcie_ep_ops pcie_ep_ops = { |
| 448 | .ep_init = artpec6_pcie_ep_init, | 448 | .ep_init = artpec6_pcie_ep_init, |
| 449 | .raise_irq = artpec6_pcie_raise_irq, | 449 | .raise_irq = artpec6_pcie_raise_irq, |
| 450 | }; | 450 | }; |
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index 24f5a775ad34..2bf5a35c0570 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c | |||
| @@ -46,16 +46,19 @@ static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie *pci, u8 cap_ptr, | |||
| 46 | u8 cap_id, next_cap_ptr; | 46 | u8 cap_id, next_cap_ptr; |
| 47 | u16 reg; | 47 | u16 reg; |
| 48 | 48 | ||
| 49 | if (!cap_ptr) | ||
| 50 | return 0; | ||
| 51 | |||
| 49 | reg = dw_pcie_readw_dbi(pci, cap_ptr); | 52 | reg = dw_pcie_readw_dbi(pci, cap_ptr); |
| 50 | next_cap_ptr = (reg & 0xff00) >> 8; | ||
| 51 | cap_id = (reg & 0x00ff); | 53 | cap_id = (reg & 0x00ff); |
| 52 | 54 | ||
| 53 | if (!next_cap_ptr || cap_id > PCI_CAP_ID_MAX) | 55 | if (cap_id > PCI_CAP_ID_MAX) |
| 54 | return 0; | 56 | return 0; |
| 55 | 57 | ||
| 56 | if (cap_id == cap) | 58 | if (cap_id == cap) |
| 57 | return cap_ptr; | 59 | return cap_ptr; |
| 58 | 60 | ||
| 61 | next_cap_ptr = (reg & 0xff00) >> 8; | ||
| 59 | return __dw_pcie_ep_find_next_cap(pci, next_cap_ptr, cap); | 62 | return __dw_pcie_ep_find_next_cap(pci, next_cap_ptr, cap); |
| 60 | } | 63 | } |
| 61 | 64 | ||
| @@ -67,9 +70,6 @@ static u8 dw_pcie_ep_find_capability(struct dw_pcie *pci, u8 cap) | |||
| 67 | reg = dw_pcie_readw_dbi(pci, PCI_CAPABILITY_LIST); | 70 | reg = dw_pcie_readw_dbi(pci, PCI_CAPABILITY_LIST); |
| 68 | next_cap_ptr = (reg & 0x00ff); | 71 | next_cap_ptr = (reg & 0x00ff); |
| 69 | 72 | ||
| 70 | if (!next_cap_ptr) | ||
| 71 | return 0; | ||
| 72 | |||
| 73 | return __dw_pcie_ep_find_next_cap(pci, next_cap_ptr, cap); | 73 | return __dw_pcie_ep_find_next_cap(pci, next_cap_ptr, cap); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| @@ -397,6 +397,7 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, | |||
| 397 | { | 397 | { |
| 398 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); | 398 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); |
| 399 | struct pci_epc *epc = ep->epc; | 399 | struct pci_epc *epc = ep->epc; |
| 400 | unsigned int aligned_offset; | ||
| 400 | u16 msg_ctrl, msg_data; | 401 | u16 msg_ctrl, msg_data; |
| 401 | u32 msg_addr_lower, msg_addr_upper, reg; | 402 | u32 msg_addr_lower, msg_addr_upper, reg; |
| 402 | u64 msg_addr; | 403 | u64 msg_addr; |
| @@ -422,13 +423,15 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, | |||
| 422 | reg = ep->msi_cap + PCI_MSI_DATA_32; | 423 | reg = ep->msi_cap + PCI_MSI_DATA_32; |
| 423 | msg_data = dw_pcie_readw_dbi(pci, reg); | 424 | msg_data = dw_pcie_readw_dbi(pci, reg); |
| 424 | } | 425 | } |
| 425 | msg_addr = ((u64) msg_addr_upper) << 32 | msg_addr_lower; | 426 | aligned_offset = msg_addr_lower & (epc->mem->page_size - 1); |
| 427 | msg_addr = ((u64)msg_addr_upper) << 32 | | ||
| 428 | (msg_addr_lower & ~aligned_offset); | ||
| 426 | ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr, | 429 | ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr, |
| 427 | epc->mem->page_size); | 430 | epc->mem->page_size); |
| 428 | if (ret) | 431 | if (ret) |
| 429 | return ret; | 432 | return ret; |
| 430 | 433 | ||
| 431 | writel(msg_data | (interrupt_num - 1), ep->msi_mem); | 434 | writel(msg_data | (interrupt_num - 1), ep->msi_mem + aligned_offset); |
| 432 | 435 | ||
| 433 | dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys); | 436 | dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys); |
| 434 | 437 | ||
| @@ -504,10 +507,32 @@ void dw_pcie_ep_exit(struct dw_pcie_ep *ep) | |||
| 504 | pci_epc_mem_exit(epc); | 507 | pci_epc_mem_exit(epc); |
| 505 | } | 508 | } |
| 506 | 509 | ||
| 510 | static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap) | ||
| 511 | { | ||
| 512 | u32 header; | ||
| 513 | int pos = PCI_CFG_SPACE_SIZE; | ||
| 514 | |||
| 515 | while (pos) { | ||
| 516 | header = dw_pcie_readl_dbi(pci, pos); | ||
| 517 | if (PCI_EXT_CAP_ID(header) == cap) | ||
| 518 | return pos; | ||
| 519 | |||
| 520 | pos = PCI_EXT_CAP_NEXT(header); | ||
| 521 | if (!pos) | ||
| 522 | break; | ||
| 523 | } | ||
| 524 | |||
| 525 | return 0; | ||
| 526 | } | ||
| 527 | |||
| 507 | int dw_pcie_ep_init(struct dw_pcie_ep *ep) | 528 | int dw_pcie_ep_init(struct dw_pcie_ep *ep) |
| 508 | { | 529 | { |
| 530 | int i; | ||
| 509 | int ret; | 531 | int ret; |
| 532 | u32 reg; | ||
| 510 | void *addr; | 533 | void *addr; |
| 534 | unsigned int nbars; | ||
| 535 | unsigned int offset; | ||
| 511 | struct pci_epc *epc; | 536 | struct pci_epc *epc; |
| 512 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); | 537 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); |
| 513 | struct device *dev = pci->dev; | 538 | struct device *dev = pci->dev; |
| @@ -517,10 +542,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) | |||
| 517 | dev_err(dev, "dbi_base/dbi_base2 is not populated\n"); | 542 | dev_err(dev, "dbi_base/dbi_base2 is not populated\n"); |
| 518 | return -EINVAL; | 543 | return -EINVAL; |
| 519 | } | 544 | } |
| 520 | if (pci->iatu_unroll_enabled && !pci->atu_base) { | ||
| 521 | dev_err(dev, "atu_base is not populated\n"); | ||
| 522 | return -EINVAL; | ||
| 523 | } | ||
| 524 | 545 | ||
| 525 | ret = of_property_read_u32(np, "num-ib-windows", &ep->num_ib_windows); | 546 | ret = of_property_read_u32(np, "num-ib-windows", &ep->num_ib_windows); |
| 526 | if (ret < 0) { | 547 | if (ret < 0) { |
| @@ -595,6 +616,18 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) | |||
| 595 | 616 | ||
| 596 | ep->msix_cap = dw_pcie_ep_find_capability(pci, PCI_CAP_ID_MSIX); | 617 | ep->msix_cap = dw_pcie_ep_find_capability(pci, PCI_CAP_ID_MSIX); |
| 597 | 618 | ||
| 619 | offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR); | ||
| 620 | if (offset) { | ||
| 621 | reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL); | ||
| 622 | nbars = (reg & PCI_REBAR_CTRL_NBAR_MASK) >> | ||
| 623 | PCI_REBAR_CTRL_NBAR_SHIFT; | ||
| 624 | |||
| 625 | dw_pcie_dbi_ro_wr_en(pci); | ||
| 626 | for (i = 0; i < nbars; i++, offset += PCI_REBAR_CTRL) | ||
| 627 | dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, 0x0); | ||
| 628 | dw_pcie_dbi_ro_wr_dis(pci); | ||
| 629 | } | ||
| 630 | |||
| 598 | dw_pcie_setup(pci); | 631 | dw_pcie_setup(pci); |
| 599 | 632 | ||
| 600 | return 0; | 633 | return 0; |
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 25087d3c9a82..77db32529319 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c | |||
| @@ -126,18 +126,12 @@ static void dw_pci_setup_msi_msg(struct irq_data *d, struct msi_msg *msg) | |||
| 126 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 126 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
| 127 | u64 msi_target; | 127 | u64 msi_target; |
| 128 | 128 | ||
| 129 | if (pp->ops->get_msi_addr) | 129 | msi_target = (u64)pp->msi_data; |
| 130 | msi_target = pp->ops->get_msi_addr(pp); | ||
| 131 | else | ||
| 132 | msi_target = (u64)pp->msi_data; | ||
| 133 | 130 | ||
| 134 | msg->address_lo = lower_32_bits(msi_target); | 131 | msg->address_lo = lower_32_bits(msi_target); |
| 135 | msg->address_hi = upper_32_bits(msi_target); | 132 | msg->address_hi = upper_32_bits(msi_target); |
| 136 | 133 | ||
| 137 | if (pp->ops->get_msi_data) | 134 | msg->data = d->hwirq; |
| 138 | msg->data = pp->ops->get_msi_data(pp, d->hwirq); | ||
| 139 | else | ||
| 140 | msg->data = d->hwirq; | ||
| 141 | 135 | ||
| 142 | dev_dbg(pci->dev, "msi#%d address_hi %#x address_lo %#x\n", | 136 | dev_dbg(pci->dev, "msi#%d address_hi %#x address_lo %#x\n", |
| 143 | (int)d->hwirq, msg->address_hi, msg->address_lo); | 137 | (int)d->hwirq, msg->address_hi, msg->address_lo); |
| @@ -157,17 +151,13 @@ static void dw_pci_bottom_mask(struct irq_data *d) | |||
| 157 | 151 | ||
| 158 | raw_spin_lock_irqsave(&pp->lock, flags); | 152 | raw_spin_lock_irqsave(&pp->lock, flags); |
| 159 | 153 | ||
| 160 | if (pp->ops->msi_clear_irq) { | 154 | ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; |
| 161 | pp->ops->msi_clear_irq(pp, d->hwirq); | 155 | res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; |
| 162 | } else { | 156 | bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; |
| 163 | ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; | ||
| 164 | res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; | ||
| 165 | bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; | ||
| 166 | 157 | ||
| 167 | pp->irq_mask[ctrl] |= BIT(bit); | 158 | pp->irq_mask[ctrl] |= BIT(bit); |
| 168 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4, | 159 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4, |
| 169 | pp->irq_mask[ctrl]); | 160 | pp->irq_mask[ctrl]); |
| 170 | } | ||
| 171 | 161 | ||
| 172 | raw_spin_unlock_irqrestore(&pp->lock, flags); | 162 | raw_spin_unlock_irqrestore(&pp->lock, flags); |
| 173 | } | 163 | } |
| @@ -180,17 +170,13 @@ static void dw_pci_bottom_unmask(struct irq_data *d) | |||
| 180 | 170 | ||
| 181 | raw_spin_lock_irqsave(&pp->lock, flags); | 171 | raw_spin_lock_irqsave(&pp->lock, flags); |
| 182 | 172 | ||
| 183 | if (pp->ops->msi_set_irq) { | 173 | ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; |
| 184 | pp->ops->msi_set_irq(pp, d->hwirq); | 174 | res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; |
| 185 | } else { | 175 | bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; |
| 186 | ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; | ||
| 187 | res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; | ||
| 188 | bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; | ||
| 189 | 176 | ||
| 190 | pp->irq_mask[ctrl] &= ~BIT(bit); | 177 | pp->irq_mask[ctrl] &= ~BIT(bit); |
| 191 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4, | 178 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4, |
| 192 | pp->irq_mask[ctrl]); | 179 | pp->irq_mask[ctrl]); |
| 193 | } | ||
| 194 | 180 | ||
| 195 | raw_spin_unlock_irqrestore(&pp->lock, flags); | 181 | raw_spin_unlock_irqrestore(&pp->lock, flags); |
| 196 | } | 182 | } |
| @@ -199,20 +185,12 @@ static void dw_pci_bottom_ack(struct irq_data *d) | |||
| 199 | { | 185 | { |
| 200 | struct pcie_port *pp = irq_data_get_irq_chip_data(d); | 186 | struct pcie_port *pp = irq_data_get_irq_chip_data(d); |
| 201 | unsigned int res, bit, ctrl; | 187 | unsigned int res, bit, ctrl; |
| 202 | unsigned long flags; | ||
| 203 | 188 | ||
| 204 | ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; | 189 | ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; |
| 205 | res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; | 190 | res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; |
| 206 | bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; | 191 | bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; |
| 207 | 192 | ||
| 208 | raw_spin_lock_irqsave(&pp->lock, flags); | ||
| 209 | |||
| 210 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + res, 4, BIT(bit)); | 193 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + res, 4, BIT(bit)); |
| 211 | |||
| 212 | if (pp->ops->msi_irq_ack) | ||
| 213 | pp->ops->msi_irq_ack(d->hwirq, pp); | ||
| 214 | |||
| 215 | raw_spin_unlock_irqrestore(&pp->lock, flags); | ||
| 216 | } | 194 | } |
| 217 | 195 | ||
| 218 | static struct irq_chip dw_pci_msi_bottom_irq_chip = { | 196 | static struct irq_chip dw_pci_msi_bottom_irq_chip = { |
| @@ -245,7 +223,7 @@ static int dw_pcie_irq_domain_alloc(struct irq_domain *domain, | |||
| 245 | 223 | ||
| 246 | for (i = 0; i < nr_irqs; i++) | 224 | for (i = 0; i < nr_irqs; i++) |
| 247 | irq_domain_set_info(domain, virq + i, bit + i, | 225 | irq_domain_set_info(domain, virq + i, bit + i, |
| 248 | &dw_pci_msi_bottom_irq_chip, | 226 | pp->msi_irq_chip, |
| 249 | pp, handle_edge_irq, | 227 | pp, handle_edge_irq, |
| 250 | NULL, NULL); | 228 | NULL, NULL); |
| 251 | 229 | ||
| @@ -298,25 +276,31 @@ int dw_pcie_allocate_domains(struct pcie_port *pp) | |||
| 298 | 276 | ||
| 299 | void dw_pcie_free_msi(struct pcie_port *pp) | 277 | void dw_pcie_free_msi(struct pcie_port *pp) |
| 300 | { | 278 | { |
| 301 | irq_set_chained_handler(pp->msi_irq, NULL); | 279 | if (pp->msi_irq) { |
| 302 | irq_set_handler_data(pp->msi_irq, NULL); | 280 | irq_set_chained_handler(pp->msi_irq, NULL); |
| 281 | irq_set_handler_data(pp->msi_irq, NULL); | ||
| 282 | } | ||
| 303 | 283 | ||
| 304 | irq_domain_remove(pp->msi_domain); | 284 | irq_domain_remove(pp->msi_domain); |
| 305 | irq_domain_remove(pp->irq_domain); | 285 | irq_domain_remove(pp->irq_domain); |
| 286 | |||
| 287 | if (pp->msi_page) | ||
| 288 | __free_page(pp->msi_page); | ||
| 306 | } | 289 | } |
| 307 | 290 | ||
| 308 | void dw_pcie_msi_init(struct pcie_port *pp) | 291 | void dw_pcie_msi_init(struct pcie_port *pp) |
| 309 | { | 292 | { |
| 310 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 293 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
| 311 | struct device *dev = pci->dev; | 294 | struct device *dev = pci->dev; |
| 312 | struct page *page; | ||
| 313 | u64 msi_target; | 295 | u64 msi_target; |
| 314 | 296 | ||
| 315 | page = alloc_page(GFP_KERNEL); | 297 | pp->msi_page = alloc_page(GFP_KERNEL); |
| 316 | pp->msi_data = dma_map_page(dev, page, 0, PAGE_SIZE, DMA_FROM_DEVICE); | 298 | pp->msi_data = dma_map_page(dev, pp->msi_page, 0, PAGE_SIZE, |
| 299 | DMA_FROM_DEVICE); | ||
| 317 | if (dma_mapping_error(dev, pp->msi_data)) { | 300 | if (dma_mapping_error(dev, pp->msi_data)) { |
| 318 | dev_err(dev, "Failed to map MSI data\n"); | 301 | dev_err(dev, "Failed to map MSI data\n"); |
| 319 | __free_page(page); | 302 | __free_page(pp->msi_page); |
| 303 | pp->msi_page = NULL; | ||
| 320 | return; | 304 | return; |
| 321 | } | 305 | } |
| 322 | msi_target = (u64)pp->msi_data; | 306 | msi_target = (u64)pp->msi_data; |
| @@ -335,7 +319,7 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
| 335 | struct device_node *np = dev->of_node; | 319 | struct device_node *np = dev->of_node; |
| 336 | struct platform_device *pdev = to_platform_device(dev); | 320 | struct platform_device *pdev = to_platform_device(dev); |
| 337 | struct resource_entry *win, *tmp; | 321 | struct resource_entry *win, *tmp; |
| 338 | struct pci_bus *bus, *child; | 322 | struct pci_bus *child; |
| 339 | struct pci_host_bridge *bridge; | 323 | struct pci_host_bridge *bridge; |
| 340 | struct resource *cfg_res; | 324 | struct resource *cfg_res; |
| 341 | int ret; | 325 | int ret; |
| @@ -352,7 +336,7 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
| 352 | dev_err(dev, "Missing *config* reg space\n"); | 336 | dev_err(dev, "Missing *config* reg space\n"); |
| 353 | } | 337 | } |
| 354 | 338 | ||
| 355 | bridge = pci_alloc_host_bridge(0); | 339 | bridge = devm_pci_alloc_host_bridge(dev, 0); |
| 356 | if (!bridge) | 340 | if (!bridge) |
| 357 | return -ENOMEM; | 341 | return -ENOMEM; |
| 358 | 342 | ||
| @@ -363,7 +347,7 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
| 363 | 347 | ||
| 364 | ret = devm_request_pci_bus_resources(dev, &bridge->windows); | 348 | ret = devm_request_pci_bus_resources(dev, &bridge->windows); |
| 365 | if (ret) | 349 | if (ret) |
| 366 | goto error; | 350 | return ret; |
| 367 | 351 | ||
| 368 | /* Get the I/O and memory ranges from DT */ | 352 | /* Get the I/O and memory ranges from DT */ |
| 369 | resource_list_for_each_entry_safe(win, tmp, &bridge->windows) { | 353 | resource_list_for_each_entry_safe(win, tmp, &bridge->windows) { |
| @@ -407,8 +391,7 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
| 407 | resource_size(pp->cfg)); | 391 | resource_size(pp->cfg)); |
| 408 | if (!pci->dbi_base) { | 392 | if (!pci->dbi_base) { |
| 409 | dev_err(dev, "Error with ioremap\n"); | 393 | dev_err(dev, "Error with ioremap\n"); |
| 410 | ret = -ENOMEM; | 394 | return -ENOMEM; |
| 411 | goto error; | ||
| 412 | } | 395 | } |
| 413 | } | 396 | } |
| 414 | 397 | ||
| @@ -419,8 +402,7 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
| 419 | pp->cfg0_base, pp->cfg0_size); | 402 | pp->cfg0_base, pp->cfg0_size); |
| 420 | if (!pp->va_cfg0_base) { | 403 | if (!pp->va_cfg0_base) { |
| 421 | dev_err(dev, "Error with ioremap in function\n"); | 404 | dev_err(dev, "Error with ioremap in function\n"); |
| 422 | ret = -ENOMEM; | 405 | return -ENOMEM; |
| 423 | goto error; | ||
| 424 | } | 406 | } |
| 425 | } | 407 | } |
| 426 | 408 | ||
| @@ -430,8 +412,7 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
| 430 | pp->cfg1_size); | 412 | pp->cfg1_size); |
| 431 | if (!pp->va_cfg1_base) { | 413 | if (!pp->va_cfg1_base) { |
| 432 | dev_err(dev, "Error with ioremap\n"); | 414 | dev_err(dev, "Error with ioremap\n"); |
| 433 | ret = -ENOMEM; | 415 | return -ENOMEM; |
| 434 | goto error; | ||
| 435 | } | 416 | } |
| 436 | } | 417 | } |
| 437 | 418 | ||
| @@ -439,7 +420,7 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
| 439 | if (ret) | 420 | if (ret) |
| 440 | pci->num_viewport = 2; | 421 | pci->num_viewport = 2; |
| 441 | 422 | ||
| 442 | if (IS_ENABLED(CONFIG_PCI_MSI) && pci_msi_enabled()) { | 423 | if (pci_msi_enabled()) { |
| 443 | /* | 424 | /* |
| 444 | * If a specific SoC driver needs to change the | 425 | * If a specific SoC driver needs to change the |
| 445 | * default number of vectors, it needs to implement | 426 | * default number of vectors, it needs to implement |
| @@ -454,14 +435,16 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
| 454 | pp->num_vectors == 0) { | 435 | pp->num_vectors == 0) { |
| 455 | dev_err(dev, | 436 | dev_err(dev, |
| 456 | "Invalid number of vectors\n"); | 437 | "Invalid number of vectors\n"); |
| 457 | goto error; | 438 | return -EINVAL; |
| 458 | } | 439 | } |
| 459 | } | 440 | } |
| 460 | 441 | ||
| 461 | if (!pp->ops->msi_host_init) { | 442 | if (!pp->ops->msi_host_init) { |
| 443 | pp->msi_irq_chip = &dw_pci_msi_bottom_irq_chip; | ||
| 444 | |||
| 462 | ret = dw_pcie_allocate_domains(pp); | 445 | ret = dw_pcie_allocate_domains(pp); |
| 463 | if (ret) | 446 | if (ret) |
| 464 | goto error; | 447 | return ret; |
| 465 | 448 | ||
| 466 | if (pp->msi_irq) | 449 | if (pp->msi_irq) |
| 467 | irq_set_chained_handler_and_data(pp->msi_irq, | 450 | irq_set_chained_handler_and_data(pp->msi_irq, |
| @@ -470,14 +453,14 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
| 470 | } else { | 453 | } else { |
| 471 | ret = pp->ops->msi_host_init(pp); | 454 | ret = pp->ops->msi_host_init(pp); |
| 472 | if (ret < 0) | 455 | if (ret < 0) |
| 473 | goto error; | 456 | return ret; |
| 474 | } | 457 | } |
| 475 | } | 458 | } |
| 476 | 459 | ||
| 477 | if (pp->ops->host_init) { | 460 | if (pp->ops->host_init) { |
| 478 | ret = pp->ops->host_init(pp); | 461 | ret = pp->ops->host_init(pp); |
| 479 | if (ret) | 462 | if (ret) |
| 480 | goto error; | 463 | goto err_free_msi; |
| 481 | } | 464 | } |
| 482 | 465 | ||
| 483 | pp->root_bus_nr = pp->busn->start; | 466 | pp->root_bus_nr = pp->busn->start; |
| @@ -491,24 +474,25 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
| 491 | 474 | ||
| 492 | ret = pci_scan_root_bus_bridge(bridge); | 475 | ret = pci_scan_root_bus_bridge(bridge); |
| 493 | if (ret) | 476 | if (ret) |
| 494 | goto error; | 477 | goto err_free_msi; |
| 495 | 478 | ||
| 496 | bus = bridge->bus; | 479 | pp->root_bus = bridge->bus; |
| 497 | 480 | ||
| 498 | if (pp->ops->scan_bus) | 481 | if (pp->ops->scan_bus) |
| 499 | pp->ops->scan_bus(pp); | 482 | pp->ops->scan_bus(pp); |
| 500 | 483 | ||
| 501 | pci_bus_size_bridges(bus); | 484 | pci_bus_size_bridges(pp->root_bus); |
| 502 | pci_bus_assign_resources(bus); | 485 | pci_bus_assign_resources(pp->root_bus); |
| 503 | 486 | ||
| 504 | list_for_each_entry(child, &bus->children, node) | 487 | list_for_each_entry(child, &pp->root_bus->children, node) |
| 505 | pcie_bus_configure_settings(child); | 488 | pcie_bus_configure_settings(child); |
| 506 | 489 | ||
| 507 | pci_bus_add_devices(bus); | 490 | pci_bus_add_devices(pp->root_bus); |
| 508 | return 0; | 491 | return 0; |
| 509 | 492 | ||
| 510 | error: | 493 | err_free_msi: |
| 511 | pci_free_host_bridge(bridge); | 494 | if (pci_msi_enabled() && !pp->ops->msi_host_init) |
| 495 | dw_pcie_free_msi(pp); | ||
| 512 | return ret; | 496 | return ret; |
| 513 | } | 497 | } |
| 514 | 498 | ||
| @@ -628,17 +612,6 @@ static struct pci_ops dw_pcie_ops = { | |||
| 628 | .write = dw_pcie_wr_conf, | 612 | .write = dw_pcie_wr_conf, |
| 629 | }; | 613 | }; |
| 630 | 614 | ||
| 631 | static u8 dw_pcie_iatu_unroll_enabled(struct dw_pcie *pci) | ||
| 632 | { | ||
| 633 | u32 val; | ||
| 634 | |||
| 635 | val = dw_pcie_readl_dbi(pci, PCIE_ATU_VIEWPORT); | ||
| 636 | if (val == 0xffffffff) | ||
| 637 | return 1; | ||
| 638 | |||
| 639 | return 0; | ||
| 640 | } | ||
| 641 | |||
| 642 | void dw_pcie_setup_rc(struct pcie_port *pp) | 615 | void dw_pcie_setup_rc(struct pcie_port *pp) |
| 643 | { | 616 | { |
| 644 | u32 val, ctrl, num_ctrls; | 617 | u32 val, ctrl, num_ctrls; |
| @@ -646,17 +619,19 @@ void dw_pcie_setup_rc(struct pcie_port *pp) | |||
| 646 | 619 | ||
| 647 | dw_pcie_setup(pci); | 620 | dw_pcie_setup(pci); |
| 648 | 621 | ||
| 649 | num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL; | 622 | if (!pp->ops->msi_host_init) { |
| 650 | 623 | num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL; | |
| 651 | /* Initialize IRQ Status array */ | 624 | |
| 652 | for (ctrl = 0; ctrl < num_ctrls; ctrl++) { | 625 | /* Initialize IRQ Status array */ |
| 653 | pp->irq_mask[ctrl] = ~0; | 626 | for (ctrl = 0; ctrl < num_ctrls; ctrl++) { |
| 654 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + | 627 | pp->irq_mask[ctrl] = ~0; |
| 655 | (ctrl * MSI_REG_CTRL_BLOCK_SIZE), | 628 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + |
| 656 | 4, pp->irq_mask[ctrl]); | 629 | (ctrl * MSI_REG_CTRL_BLOCK_SIZE), |
| 657 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + | 630 | 4, pp->irq_mask[ctrl]); |
| 658 | (ctrl * MSI_REG_CTRL_BLOCK_SIZE), | 631 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + |
| 659 | 4, ~0); | 632 | (ctrl * MSI_REG_CTRL_BLOCK_SIZE), |
| 633 | 4, ~0); | ||
| 634 | } | ||
| 660 | } | 635 | } |
| 661 | 636 | ||
| 662 | /* Setup RC BARs */ | 637 | /* Setup RC BARs */ |
| @@ -690,14 +665,6 @@ void dw_pcie_setup_rc(struct pcie_port *pp) | |||
| 690 | * we should not program the ATU here. | 665 | * we should not program the ATU here. |
| 691 | */ | 666 | */ |
| 692 | if (!pp->ops->rd_other_conf) { | 667 | if (!pp->ops->rd_other_conf) { |
| 693 | /* Get iATU unroll support */ | ||
| 694 | pci->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pci); | ||
| 695 | dev_dbg(pci->dev, "iATU unroll: %s\n", | ||
| 696 | pci->iatu_unroll_enabled ? "enabled" : "disabled"); | ||
| 697 | |||
| 698 | if (pci->iatu_unroll_enabled && !pci->atu_base) | ||
| 699 | pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET; | ||
| 700 | |||
| 701 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX0, | 668 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX0, |
| 702 | PCIE_ATU_TYPE_MEM, pp->mem_base, | 669 | PCIE_ATU_TYPE_MEM, pp->mem_base, |
| 703 | pp->mem_bus_addr, pp->mem_size); | 670 | pp->mem_bus_addr, pp->mem_size); |
diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c index 932dbd0b34b6..b58fdcbc664b 100644 --- a/drivers/pci/controller/dwc/pcie-designware-plat.c +++ b/drivers/pci/controller/dwc/pcie-designware-plat.c | |||
| @@ -106,7 +106,7 @@ dw_plat_pcie_get_features(struct dw_pcie_ep *ep) | |||
| 106 | return &dw_plat_pcie_epc_features; | 106 | return &dw_plat_pcie_epc_features; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | static struct dw_pcie_ep_ops pcie_ep_ops = { | 109 | static const struct dw_pcie_ep_ops pcie_ep_ops = { |
| 110 | .ep_init = dw_plat_pcie_ep_init, | 110 | .ep_init = dw_plat_pcie_ep_init, |
| 111 | .raise_irq = dw_plat_pcie_ep_raise_irq, | 111 | .raise_irq = dw_plat_pcie_ep_raise_irq, |
| 112 | .get_features = dw_plat_pcie_get_features, | 112 | .get_features = dw_plat_pcie_get_features, |
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 31f6331ca46f..9d7c51c32b3b 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c | |||
| @@ -14,12 +14,6 @@ | |||
| 14 | 14 | ||
| 15 | #include "pcie-designware.h" | 15 | #include "pcie-designware.h" |
| 16 | 16 | ||
| 17 | /* PCIe Port Logic registers */ | ||
| 18 | #define PLR_OFFSET 0x700 | ||
| 19 | #define PCIE_PHY_DEBUG_R1 (PLR_OFFSET + 0x2c) | ||
| 20 | #define PCIE_PHY_DEBUG_R1_LINK_UP (0x1 << 4) | ||
| 21 | #define PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING (0x1 << 29) | ||
| 22 | |||
| 23 | int dw_pcie_read(void __iomem *addr, int size, u32 *val) | 17 | int dw_pcie_read(void __iomem *addr, int size, u32 *val) |
| 24 | { | 18 | { |
| 25 | if (!IS_ALIGNED((uintptr_t)addr, size)) { | 19 | if (!IS_ALIGNED((uintptr_t)addr, size)) { |
| @@ -89,6 +83,37 @@ void __dw_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg, | |||
| 89 | dev_err(pci->dev, "Write DBI address failed\n"); | 83 | dev_err(pci->dev, "Write DBI address failed\n"); |
| 90 | } | 84 | } |
| 91 | 85 | ||
| 86 | u32 __dw_pcie_read_dbi2(struct dw_pcie *pci, void __iomem *base, u32 reg, | ||
| 87 | size_t size) | ||
| 88 | { | ||
| 89 | int ret; | ||
| 90 | u32 val; | ||
| 91 | |||
| 92 | if (pci->ops->read_dbi2) | ||
| 93 | return pci->ops->read_dbi2(pci, base, reg, size); | ||
| 94 | |||
| 95 | ret = dw_pcie_read(base + reg, size, &val); | ||
| 96 | if (ret) | ||
| 97 | dev_err(pci->dev, "read DBI address failed\n"); | ||
| 98 | |||
| 99 | return val; | ||
| 100 | } | ||
| 101 | |||
| 102 | void __dw_pcie_write_dbi2(struct dw_pcie *pci, void __iomem *base, u32 reg, | ||
| 103 | size_t size, u32 val) | ||
| 104 | { | ||
| 105 | int ret; | ||
| 106 | |||
| 107 | if (pci->ops->write_dbi2) { | ||
| 108 | pci->ops->write_dbi2(pci, base, reg, size, val); | ||
| 109 | return; | ||
| 110 | } | ||
| 111 | |||
| 112 | ret = dw_pcie_write(base + reg, size, val); | ||
| 113 | if (ret) | ||
| 114 | dev_err(pci->dev, "write DBI address failed\n"); | ||
| 115 | } | ||
| 116 | |||
| 92 | static u32 dw_pcie_readl_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg) | 117 | static u32 dw_pcie_readl_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg) |
| 93 | { | 118 | { |
| 94 | u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index); | 119 | u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index); |
| @@ -334,9 +359,20 @@ int dw_pcie_link_up(struct dw_pcie *pci) | |||
| 334 | if (pci->ops->link_up) | 359 | if (pci->ops->link_up) |
| 335 | return pci->ops->link_up(pci); | 360 | return pci->ops->link_up(pci); |
| 336 | 361 | ||
| 337 | val = readl(pci->dbi_base + PCIE_PHY_DEBUG_R1); | 362 | val = readl(pci->dbi_base + PCIE_PORT_DEBUG1); |
| 338 | return ((val & PCIE_PHY_DEBUG_R1_LINK_UP) && | 363 | return ((val & PCIE_PORT_DEBUG1_LINK_UP) && |
| 339 | (!(val & PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING))); | 364 | (!(val & PCIE_PORT_DEBUG1_LINK_IN_TRAINING))); |
| 365 | } | ||
| 366 | |||
| 367 | static u8 dw_pcie_iatu_unroll_enabled(struct dw_pcie *pci) | ||
| 368 | { | ||
| 369 | u32 val; | ||
| 370 | |||
| 371 | val = dw_pcie_readl_dbi(pci, PCIE_ATU_VIEWPORT); | ||
| 372 | if (val == 0xffffffff) | ||
| 373 | return 1; | ||
| 374 | |||
| 375 | return 0; | ||
| 340 | } | 376 | } |
| 341 | 377 | ||
| 342 | void dw_pcie_setup(struct dw_pcie *pci) | 378 | void dw_pcie_setup(struct dw_pcie *pci) |
| @@ -347,6 +383,16 @@ void dw_pcie_setup(struct dw_pcie *pci) | |||
| 347 | struct device *dev = pci->dev; | 383 | struct device *dev = pci->dev; |
| 348 | struct device_node *np = dev->of_node; | 384 | struct device_node *np = dev->of_node; |
| 349 | 385 | ||
| 386 | if (pci->version >= 0x480A || (!pci->version && | ||
| 387 | dw_pcie_iatu_unroll_enabled(pci))) { | ||
| 388 | pci->iatu_unroll_enabled = true; | ||
| 389 | if (!pci->atu_base) | ||
| 390 | pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET; | ||
| 391 | } | ||
| 392 | dev_dbg(pci->dev, "iATU unroll: %s\n", pci->iatu_unroll_enabled ? | ||
| 393 | "enabled" : "disabled"); | ||
| 394 | |||
| 395 | |||
| 350 | ret = of_property_read_u32(np, "num-lanes", &lanes); | 396 | ret = of_property_read_u32(np, "num-lanes", &lanes); |
| 351 | if (ret) | 397 | if (ret) |
| 352 | lanes = 0; | 398 | lanes = 0; |
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 377f4c0b52da..b8993f2b78df 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h | |||
| @@ -41,6 +41,9 @@ | |||
| 41 | #define PCIE_PORT_DEBUG0 0x728 | 41 | #define PCIE_PORT_DEBUG0 0x728 |
| 42 | #define PORT_LOGIC_LTSSM_STATE_MASK 0x1f | 42 | #define PORT_LOGIC_LTSSM_STATE_MASK 0x1f |
| 43 | #define PORT_LOGIC_LTSSM_STATE_L0 0x11 | 43 | #define PORT_LOGIC_LTSSM_STATE_L0 0x11 |
| 44 | #define PCIE_PORT_DEBUG1 0x72C | ||
| 45 | #define PCIE_PORT_DEBUG1_LINK_UP BIT(4) | ||
| 46 | #define PCIE_PORT_DEBUG1_LINK_IN_TRAINING BIT(29) | ||
| 44 | 47 | ||
| 45 | #define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C | 48 | #define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C |
| 46 | #define PORT_LOGIC_SPEED_CHANGE BIT(17) | 49 | #define PORT_LOGIC_SPEED_CHANGE BIT(17) |
| @@ -145,14 +148,9 @@ struct dw_pcie_host_ops { | |||
| 145 | int (*wr_other_conf)(struct pcie_port *pp, struct pci_bus *bus, | 148 | int (*wr_other_conf)(struct pcie_port *pp, struct pci_bus *bus, |
| 146 | unsigned int devfn, int where, int size, u32 val); | 149 | unsigned int devfn, int where, int size, u32 val); |
| 147 | int (*host_init)(struct pcie_port *pp); | 150 | int (*host_init)(struct pcie_port *pp); |
| 148 | void (*msi_set_irq)(struct pcie_port *pp, int irq); | ||
| 149 | void (*msi_clear_irq)(struct pcie_port *pp, int irq); | ||
| 150 | phys_addr_t (*get_msi_addr)(struct pcie_port *pp); | ||
| 151 | u32 (*get_msi_data)(struct pcie_port *pp, int pos); | ||
| 152 | void (*scan_bus)(struct pcie_port *pp); | 151 | void (*scan_bus)(struct pcie_port *pp); |
| 153 | void (*set_num_vectors)(struct pcie_port *pp); | 152 | void (*set_num_vectors)(struct pcie_port *pp); |
| 154 | int (*msi_host_init)(struct pcie_port *pp); | 153 | int (*msi_host_init)(struct pcie_port *pp); |
| 155 | void (*msi_irq_ack)(int irq, struct pcie_port *pp); | ||
| 156 | }; | 154 | }; |
| 157 | 155 | ||
| 158 | struct pcie_port { | 156 | struct pcie_port { |
| @@ -179,8 +177,11 @@ struct pcie_port { | |||
| 179 | struct irq_domain *irq_domain; | 177 | struct irq_domain *irq_domain; |
| 180 | struct irq_domain *msi_domain; | 178 | struct irq_domain *msi_domain; |
| 181 | dma_addr_t msi_data; | 179 | dma_addr_t msi_data; |
| 180 | struct page *msi_page; | ||
| 181 | struct irq_chip *msi_irq_chip; | ||
| 182 | u32 num_vectors; | 182 | u32 num_vectors; |
| 183 | u32 irq_mask[MAX_MSI_CTRLS]; | 183 | u32 irq_mask[MAX_MSI_CTRLS]; |
| 184 | struct pci_bus *root_bus; | ||
| 184 | raw_spinlock_t lock; | 185 | raw_spinlock_t lock; |
| 185 | DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); | 186 | DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); |
| 186 | }; | 187 | }; |
| @@ -200,7 +201,7 @@ struct dw_pcie_ep_ops { | |||
| 200 | 201 | ||
| 201 | struct dw_pcie_ep { | 202 | struct dw_pcie_ep { |
| 202 | struct pci_epc *epc; | 203 | struct pci_epc *epc; |
| 203 | struct dw_pcie_ep_ops *ops; | 204 | const struct dw_pcie_ep_ops *ops; |
| 204 | phys_addr_t phys_base; | 205 | phys_addr_t phys_base; |
| 205 | size_t addr_size; | 206 | size_t addr_size; |
| 206 | size_t page_size; | 207 | size_t page_size; |
| @@ -222,6 +223,10 @@ struct dw_pcie_ops { | |||
| 222 | size_t size); | 223 | size_t size); |
| 223 | void (*write_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg, | 224 | void (*write_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg, |
| 224 | size_t size, u32 val); | 225 | size_t size, u32 val); |
| 226 | u32 (*read_dbi2)(struct dw_pcie *pcie, void __iomem *base, u32 reg, | ||
| 227 | size_t size); | ||
| 228 | void (*write_dbi2)(struct dw_pcie *pcie, void __iomem *base, u32 reg, | ||
| 229 | size_t size, u32 val); | ||
| 225 | int (*link_up)(struct dw_pcie *pcie); | 230 | int (*link_up)(struct dw_pcie *pcie); |
| 226 | int (*start_link)(struct dw_pcie *pcie); | 231 | int (*start_link)(struct dw_pcie *pcie); |
| 227 | void (*stop_link)(struct dw_pcie *pcie); | 232 | void (*stop_link)(struct dw_pcie *pcie); |
| @@ -238,6 +243,7 @@ struct dw_pcie { | |||
| 238 | struct pcie_port pp; | 243 | struct pcie_port pp; |
| 239 | struct dw_pcie_ep ep; | 244 | struct dw_pcie_ep ep; |
| 240 | const struct dw_pcie_ops *ops; | 245 | const struct dw_pcie_ops *ops; |
| 246 | unsigned int version; | ||
| 241 | }; | 247 | }; |
| 242 | 248 | ||
| 243 | #define to_dw_pcie_from_pp(port) container_of((port), struct dw_pcie, pp) | 249 | #define to_dw_pcie_from_pp(port) container_of((port), struct dw_pcie, pp) |
| @@ -252,6 +258,10 @@ u32 __dw_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg, | |||
| 252 | size_t size); | 258 | size_t size); |
| 253 | void __dw_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg, | 259 | void __dw_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg, |
| 254 | size_t size, u32 val); | 260 | size_t size, u32 val); |
| 261 | u32 __dw_pcie_read_dbi2(struct dw_pcie *pci, void __iomem *base, u32 reg, | ||
| 262 | size_t size); | ||
| 263 | void __dw_pcie_write_dbi2(struct dw_pcie *pci, void __iomem *base, u32 reg, | ||
| 264 | size_t size, u32 val); | ||
| 255 | int dw_pcie_link_up(struct dw_pcie *pci); | 265 | int dw_pcie_link_up(struct dw_pcie *pci); |
| 256 | int dw_pcie_wait_for_link(struct dw_pcie *pci); | 266 | int dw_pcie_wait_for_link(struct dw_pcie *pci); |
| 257 | void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, | 267 | void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, |
| @@ -295,12 +305,12 @@ static inline u8 dw_pcie_readb_dbi(struct dw_pcie *pci, u32 reg) | |||
| 295 | 305 | ||
| 296 | static inline void dw_pcie_writel_dbi2(struct dw_pcie *pci, u32 reg, u32 val) | 306 | static inline void dw_pcie_writel_dbi2(struct dw_pcie *pci, u32 reg, u32 val) |
| 297 | { | 307 | { |
| 298 | __dw_pcie_write_dbi(pci, pci->dbi_base2, reg, 0x4, val); | 308 | __dw_pcie_write_dbi2(pci, pci->dbi_base2, reg, 0x4, val); |
| 299 | } | 309 | } |
| 300 | 310 | ||
| 301 | static inline u32 dw_pcie_readl_dbi2(struct dw_pcie *pci, u32 reg) | 311 | static inline u32 dw_pcie_readl_dbi2(struct dw_pcie *pci, u32 reg) |
| 302 | { | 312 | { |
| 303 | return __dw_pcie_read_dbi(pci, pci->dbi_base2, reg, 0x4); | 313 | return __dw_pcie_read_dbi2(pci, pci->dbi_base2, reg, 0x4); |
| 304 | } | 314 | } |
| 305 | 315 | ||
| 306 | static inline void dw_pcie_writel_atu(struct dw_pcie *pci, u32 reg, u32 val) | 316 | static inline void dw_pcie_writel_atu(struct dw_pcie *pci, u32 reg, u32 val) |
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index a7f703556790..0ed235d560e3 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c | |||
| @@ -1129,25 +1129,8 @@ err_deinit: | |||
| 1129 | return ret; | 1129 | return ret; |
| 1130 | } | 1130 | } |
| 1131 | 1131 | ||
| 1132 | static int qcom_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, | ||
| 1133 | u32 *val) | ||
| 1134 | { | ||
| 1135 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | ||
| 1136 | |||
| 1137 | /* the device class is not reported correctly from the register */ | ||
| 1138 | if (where == PCI_CLASS_REVISION && size == 4) { | ||
| 1139 | *val = readl(pci->dbi_base + PCI_CLASS_REVISION); | ||
| 1140 | *val &= 0xff; /* keep revision id */ | ||
| 1141 | *val |= PCI_CLASS_BRIDGE_PCI << 16; | ||
| 1142 | return PCIBIOS_SUCCESSFUL; | ||
| 1143 | } | ||
| 1144 | |||
| 1145 | return dw_pcie_read(pci->dbi_base + where, size, val); | ||
| 1146 | } | ||
| 1147 | |||
| 1148 | static const struct dw_pcie_host_ops qcom_pcie_dw_ops = { | 1132 | static const struct dw_pcie_host_ops qcom_pcie_dw_ops = { |
| 1149 | .host_init = qcom_pcie_host_init, | 1133 | .host_init = qcom_pcie_host_init, |
| 1150 | .rd_own_conf = qcom_pcie_rd_own_conf, | ||
| 1151 | }; | 1134 | }; |
| 1152 | 1135 | ||
| 1153 | /* Qcom IP rev.: 2.1.0 Synopsys IP rev.: 4.01a */ | 1136 | /* Qcom IP rev.: 2.1.0 Synopsys IP rev.: 4.01a */ |
| @@ -1309,6 +1292,12 @@ static const struct of_device_id qcom_pcie_match[] = { | |||
| 1309 | { } | 1292 | { } |
| 1310 | }; | 1293 | }; |
| 1311 | 1294 | ||
| 1295 | static void qcom_fixup_class(struct pci_dev *dev) | ||
| 1296 | { | ||
| 1297 | dev->class = PCI_CLASS_BRIDGE_PCI << 8; | ||
| 1298 | } | ||
| 1299 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, PCI_ANY_ID, qcom_fixup_class); | ||
| 1300 | |||
| 1312 | static struct platform_driver qcom_pcie_driver = { | 1301 | static struct platform_driver qcom_pcie_driver = { |
| 1313 | .probe = qcom_pcie_probe, | 1302 | .probe = qcom_pcie_probe, |
| 1314 | .driver = { | 1303 | .driver = { |
diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index 95441a35eceb..82acd6155adf 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c | |||
| @@ -1486,6 +1486,21 @@ static void hv_pci_assign_slots(struct hv_pcibus_device *hbus) | |||
| 1486 | } | 1486 | } |
| 1487 | } | 1487 | } |
| 1488 | 1488 | ||
| 1489 | /* | ||
| 1490 | * Remove entries in sysfs pci slot directory. | ||
| 1491 | */ | ||
| 1492 | static void hv_pci_remove_slots(struct hv_pcibus_device *hbus) | ||
| 1493 | { | ||
| 1494 | struct hv_pci_dev *hpdev; | ||
| 1495 | |||
| 1496 | list_for_each_entry(hpdev, &hbus->children, list_entry) { | ||
| 1497 | if (!hpdev->pci_slot) | ||
| 1498 | continue; | ||
| 1499 | pci_destroy_slot(hpdev->pci_slot); | ||
| 1500 | hpdev->pci_slot = NULL; | ||
| 1501 | } | ||
| 1502 | } | ||
| 1503 | |||
| 1489 | /** | 1504 | /** |
| 1490 | * create_root_hv_pci_bus() - Expose a new root PCI bus | 1505 | * create_root_hv_pci_bus() - Expose a new root PCI bus |
| 1491 | * @hbus: Root PCI bus, as understood by this driver | 1506 | * @hbus: Root PCI bus, as understood by this driver |
| @@ -1761,6 +1776,10 @@ static void pci_devices_present_work(struct work_struct *work) | |||
| 1761 | hpdev = list_first_entry(&removed, struct hv_pci_dev, | 1776 | hpdev = list_first_entry(&removed, struct hv_pci_dev, |
| 1762 | list_entry); | 1777 | list_entry); |
| 1763 | list_del(&hpdev->list_entry); | 1778 | list_del(&hpdev->list_entry); |
| 1779 | |||
| 1780 | if (hpdev->pci_slot) | ||
| 1781 | pci_destroy_slot(hpdev->pci_slot); | ||
| 1782 | |||
| 1764 | put_pcichild(hpdev); | 1783 | put_pcichild(hpdev); |
| 1765 | } | 1784 | } |
| 1766 | 1785 | ||
| @@ -1900,6 +1919,9 @@ static void hv_eject_device_work(struct work_struct *work) | |||
| 1900 | sizeof(*ejct_pkt), (unsigned long)&ctxt.pkt, | 1919 | sizeof(*ejct_pkt), (unsigned long)&ctxt.pkt, |
| 1901 | VM_PKT_DATA_INBAND, 0); | 1920 | VM_PKT_DATA_INBAND, 0); |
| 1902 | 1921 | ||
| 1922 | /* For the get_pcichild() in hv_pci_eject_device() */ | ||
| 1923 | put_pcichild(hpdev); | ||
| 1924 | /* For the two refs got in new_pcichild_device() */ | ||
| 1903 | put_pcichild(hpdev); | 1925 | put_pcichild(hpdev); |
| 1904 | put_pcichild(hpdev); | 1926 | put_pcichild(hpdev); |
| 1905 | put_hvpcibus(hpdev->hbus); | 1927 | put_hvpcibus(hpdev->hbus); |
| @@ -2677,6 +2699,7 @@ static int hv_pci_remove(struct hv_device *hdev) | |||
| 2677 | pci_lock_rescan_remove(); | 2699 | pci_lock_rescan_remove(); |
| 2678 | pci_stop_root_bus(hbus->pci_bus); | 2700 | pci_stop_root_bus(hbus->pci_bus); |
| 2679 | pci_remove_root_bus(hbus->pci_bus); | 2701 | pci_remove_root_bus(hbus->pci_bus); |
| 2702 | hv_pci_remove_slots(hbus); | ||
| 2680 | pci_unlock_rescan_remove(); | 2703 | pci_unlock_rescan_remove(); |
| 2681 | hbus->state = hv_pcibus_removed; | 2704 | hbus->state = hv_pcibus_removed; |
| 2682 | } | 2705 | } |
diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c index c20fd6bd68fd..dd11d0226ff0 100644 --- a/drivers/pci/controller/pcie-iproc.c +++ b/drivers/pci/controller/pcie-iproc.c | |||
| @@ -60,6 +60,10 @@ | |||
| 60 | #define APB_ERR_EN_SHIFT 0 | 60 | #define APB_ERR_EN_SHIFT 0 |
| 61 | #define APB_ERR_EN BIT(APB_ERR_EN_SHIFT) | 61 | #define APB_ERR_EN BIT(APB_ERR_EN_SHIFT) |
| 62 | 62 | ||
| 63 | #define CFG_RD_SUCCESS 0 | ||
| 64 | #define CFG_RD_UR 1 | ||
| 65 | #define CFG_RD_CRS 2 | ||
| 66 | #define CFG_RD_CA 3 | ||
| 63 | #define CFG_RETRY_STATUS 0xffff0001 | 67 | #define CFG_RETRY_STATUS 0xffff0001 |
| 64 | #define CFG_RETRY_STATUS_TIMEOUT_US 500000 /* 500 milliseconds */ | 68 | #define CFG_RETRY_STATUS_TIMEOUT_US 500000 /* 500 milliseconds */ |
| 65 | 69 | ||
| @@ -289,6 +293,9 @@ enum iproc_pcie_reg { | |||
| 289 | IPROC_PCIE_IARR4, | 293 | IPROC_PCIE_IARR4, |
| 290 | IPROC_PCIE_IMAP4, | 294 | IPROC_PCIE_IMAP4, |
| 291 | 295 | ||
| 296 | /* config read status */ | ||
| 297 | IPROC_PCIE_CFG_RD_STATUS, | ||
| 298 | |||
| 292 | /* link status */ | 299 | /* link status */ |
| 293 | IPROC_PCIE_LINK_STATUS, | 300 | IPROC_PCIE_LINK_STATUS, |
| 294 | 301 | ||
| @@ -350,6 +357,7 @@ static const u16 iproc_pcie_reg_paxb_v2[] = { | |||
| 350 | [IPROC_PCIE_IMAP3] = 0xe08, | 357 | [IPROC_PCIE_IMAP3] = 0xe08, |
| 351 | [IPROC_PCIE_IARR4] = 0xe68, | 358 | [IPROC_PCIE_IARR4] = 0xe68, |
| 352 | [IPROC_PCIE_IMAP4] = 0xe70, | 359 | [IPROC_PCIE_IMAP4] = 0xe70, |
| 360 | [IPROC_PCIE_CFG_RD_STATUS] = 0xee0, | ||
| 353 | [IPROC_PCIE_LINK_STATUS] = 0xf0c, | 361 | [IPROC_PCIE_LINK_STATUS] = 0xf0c, |
| 354 | [IPROC_PCIE_APB_ERR_EN] = 0xf40, | 362 | [IPROC_PCIE_APB_ERR_EN] = 0xf40, |
| 355 | }; | 363 | }; |
| @@ -474,10 +482,12 @@ static void __iomem *iproc_pcie_map_ep_cfg_reg(struct iproc_pcie *pcie, | |||
| 474 | return (pcie->base + offset); | 482 | return (pcie->base + offset); |
| 475 | } | 483 | } |
| 476 | 484 | ||
| 477 | static unsigned int iproc_pcie_cfg_retry(void __iomem *cfg_data_p) | 485 | static unsigned int iproc_pcie_cfg_retry(struct iproc_pcie *pcie, |
| 486 | void __iomem *cfg_data_p) | ||
| 478 | { | 487 | { |
| 479 | int timeout = CFG_RETRY_STATUS_TIMEOUT_US; | 488 | int timeout = CFG_RETRY_STATUS_TIMEOUT_US; |
| 480 | unsigned int data; | 489 | unsigned int data; |
| 490 | u32 status; | ||
| 481 | 491 | ||
| 482 | /* | 492 | /* |
| 483 | * As per PCIe spec r3.1, sec 2.3.2, CRS Software Visibility only | 493 | * As per PCIe spec r3.1, sec 2.3.2, CRS Software Visibility only |
| @@ -498,6 +508,15 @@ static unsigned int iproc_pcie_cfg_retry(void __iomem *cfg_data_p) | |||
| 498 | */ | 508 | */ |
| 499 | data = readl(cfg_data_p); | 509 | data = readl(cfg_data_p); |
| 500 | while (data == CFG_RETRY_STATUS && timeout--) { | 510 | while (data == CFG_RETRY_STATUS && timeout--) { |
| 511 | /* | ||
| 512 | * CRS state is set in CFG_RD status register | ||
| 513 | * This will handle the case where CFG_RETRY_STATUS is | ||
| 514 | * valid config data. | ||
| 515 | */ | ||
| 516 | status = iproc_pcie_read_reg(pcie, IPROC_PCIE_CFG_RD_STATUS); | ||
| 517 | if (status != CFG_RD_CRS) | ||
| 518 | return data; | ||
| 519 | |||
| 501 | udelay(1); | 520 | udelay(1); |
| 502 | data = readl(cfg_data_p); | 521 | data = readl(cfg_data_p); |
| 503 | } | 522 | } |
| @@ -576,7 +595,7 @@ static int iproc_pcie_config_read(struct pci_bus *bus, unsigned int devfn, | |||
| 576 | if (!cfg_data_p) | 595 | if (!cfg_data_p) |
| 577 | return PCIBIOS_DEVICE_NOT_FOUND; | 596 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 578 | 597 | ||
| 579 | data = iproc_pcie_cfg_retry(cfg_data_p); | 598 | data = iproc_pcie_cfg_retry(pcie, cfg_data_p); |
| 580 | 599 | ||
| 581 | *val = data; | 600 | *val = data; |
| 582 | if (size <= 2) | 601 | if (size <= 2) |
| @@ -936,8 +955,25 @@ static int iproc_pcie_setup_ob(struct iproc_pcie *pcie, u64 axi_addr, | |||
| 936 | resource_size_t window_size = | 955 | resource_size_t window_size = |
| 937 | ob_map->window_sizes[size_idx] * SZ_1M; | 956 | ob_map->window_sizes[size_idx] * SZ_1M; |
| 938 | 957 | ||
| 939 | if (size < window_size) | 958 | /* |
| 940 | continue; | 959 | * Keep iterating until we reach the last window and |
| 960 | * with the minimal window size at index zero. In this | ||
| 961 | * case, we take a compromise by mapping it using the | ||
| 962 | * minimum window size that can be supported | ||
| 963 | */ | ||
| 964 | if (size < window_size) { | ||
| 965 | if (size_idx > 0 || window_idx > 0) | ||
| 966 | continue; | ||
| 967 | |||
| 968 | /* | ||
| 969 | * For the corner case of reaching the minimal | ||
| 970 | * window size that can be supported on the | ||
| 971 | * last window | ||
| 972 | */ | ||
| 973 | axi_addr = ALIGN_DOWN(axi_addr, window_size); | ||
| 974 | pci_addr = ALIGN_DOWN(pci_addr, window_size); | ||
| 975 | size = window_size; | ||
| 976 | } | ||
| 941 | 977 | ||
| 942 | if (!IS_ALIGNED(axi_addr, window_size) || | 978 | if (!IS_ALIGNED(axi_addr, window_size) || |
| 943 | !IS_ALIGNED(pci_addr, window_size)) { | 979 | !IS_ALIGNED(pci_addr, window_size)) { |
| @@ -1347,7 +1383,6 @@ static int iproc_pcie_rev_init(struct iproc_pcie *pcie) | |||
| 1347 | break; | 1383 | break; |
| 1348 | case IPROC_PCIE_PAXB: | 1384 | case IPROC_PCIE_PAXB: |
| 1349 | regs = iproc_pcie_reg_paxb; | 1385 | regs = iproc_pcie_reg_paxb; |
| 1350 | pcie->iproc_cfg_read = true; | ||
| 1351 | pcie->has_apb_err_disable = true; | 1386 | pcie->has_apb_err_disable = true; |
| 1352 | if (pcie->need_ob_cfg) { | 1387 | if (pcie->need_ob_cfg) { |
| 1353 | pcie->ob_map = paxb_ob_map; | 1388 | pcie->ob_map = paxb_ob_map; |
| @@ -1356,6 +1391,7 @@ static int iproc_pcie_rev_init(struct iproc_pcie *pcie) | |||
| 1356 | break; | 1391 | break; |
| 1357 | case IPROC_PCIE_PAXB_V2: | 1392 | case IPROC_PCIE_PAXB_V2: |
| 1358 | regs = iproc_pcie_reg_paxb_v2; | 1393 | regs = iproc_pcie_reg_paxb_v2; |
| 1394 | pcie->iproc_cfg_read = true; | ||
| 1359 | pcie->has_apb_err_disable = true; | 1395 | pcie->has_apb_err_disable = true; |
| 1360 | if (pcie->need_ob_cfg) { | 1396 | if (pcie->need_ob_cfg) { |
| 1361 | pcie->ob_map = paxb_v2_ob_map; | 1397 | pcie->ob_map = paxb_v2_ob_map; |
diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c index c8febb009454..6a4e435bd35f 100644 --- a/drivers/pci/controller/pcie-rcar.c +++ b/drivers/pci/controller/pcie-rcar.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | 46 | ||
| 47 | /* Transfer control */ | 47 | /* Transfer control */ |
| 48 | #define PCIETCTLR 0x02000 | 48 | #define PCIETCTLR 0x02000 |
| 49 | #define DL_DOWN BIT(3) | ||
| 49 | #define CFINIT 1 | 50 | #define CFINIT 1 |
| 50 | #define PCIETSTR 0x02004 | 51 | #define PCIETSTR 0x02004 |
| 51 | #define DATA_LINK_ACTIVE 1 | 52 | #define DATA_LINK_ACTIVE 1 |
| @@ -94,6 +95,7 @@ | |||
| 94 | #define MACCTLR 0x011058 | 95 | #define MACCTLR 0x011058 |
| 95 | #define SPEED_CHANGE BIT(24) | 96 | #define SPEED_CHANGE BIT(24) |
| 96 | #define SCRAMBLE_DISABLE BIT(27) | 97 | #define SCRAMBLE_DISABLE BIT(27) |
| 98 | #define PMSR 0x01105c | ||
| 97 | #define MACS2R 0x011078 | 99 | #define MACS2R 0x011078 |
| 98 | #define MACCGSPSETR 0x011084 | 100 | #define MACCGSPSETR 0x011084 |
| 99 | #define SPCNGRSN BIT(31) | 101 | #define SPCNGRSN BIT(31) |
| @@ -1130,6 +1132,7 @@ static int rcar_pcie_probe(struct platform_device *pdev) | |||
| 1130 | pcie = pci_host_bridge_priv(bridge); | 1132 | pcie = pci_host_bridge_priv(bridge); |
| 1131 | 1133 | ||
| 1132 | pcie->dev = dev; | 1134 | pcie->dev = dev; |
| 1135 | platform_set_drvdata(pdev, pcie); | ||
| 1133 | 1136 | ||
| 1134 | err = pci_parse_request_of_pci_ranges(dev, &pcie->resources, NULL); | 1137 | err = pci_parse_request_of_pci_ranges(dev, &pcie->resources, NULL); |
| 1135 | if (err) | 1138 | if (err) |
| @@ -1221,10 +1224,28 @@ err_free_bridge: | |||
| 1221 | return err; | 1224 | return err; |
| 1222 | } | 1225 | } |
| 1223 | 1226 | ||
| 1227 | static int rcar_pcie_resume_noirq(struct device *dev) | ||
| 1228 | { | ||
| 1229 | struct rcar_pcie *pcie = dev_get_drvdata(dev); | ||
| 1230 | |||
| 1231 | if (rcar_pci_read_reg(pcie, PMSR) && | ||
| 1232 | !(rcar_pci_read_reg(pcie, PCIETCTLR) & DL_DOWN)) | ||
| 1233 | return 0; | ||
| 1234 | |||
| 1235 | /* Re-establish the PCIe link */ | ||
| 1236 | rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR); | ||
| 1237 | return rcar_pcie_wait_for_dl(pcie); | ||
| 1238 | } | ||
| 1239 | |||
| 1240 | static const struct dev_pm_ops rcar_pcie_pm_ops = { | ||
| 1241 | .resume_noirq = rcar_pcie_resume_noirq, | ||
| 1242 | }; | ||
| 1243 | |||
| 1224 | static struct platform_driver rcar_pcie_driver = { | 1244 | static struct platform_driver rcar_pcie_driver = { |
| 1225 | .driver = { | 1245 | .driver = { |
| 1226 | .name = "rcar-pcie", | 1246 | .name = "rcar-pcie", |
| 1227 | .of_match_table = rcar_pcie_of_match, | 1247 | .of_match_table = rcar_pcie_of_match, |
| 1248 | .pm = &rcar_pcie_pm_ops, | ||
| 1228 | .suppress_bind_attrs = true, | 1249 | .suppress_bind_attrs = true, |
| 1229 | }, | 1250 | }, |
| 1230 | .probe = rcar_pcie_probe, | 1251 | .probe = rcar_pcie_probe, |
diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c index 81538d77f790..3b031f00a94a 100644 --- a/drivers/pci/controller/pcie-xilinx-nwl.c +++ b/drivers/pci/controller/pcie-xilinx-nwl.c | |||
| @@ -438,11 +438,10 @@ static const struct irq_domain_ops legacy_domain_ops = { | |||
| 438 | #ifdef CONFIG_PCI_MSI | 438 | #ifdef CONFIG_PCI_MSI |
| 439 | static struct irq_chip nwl_msi_irq_chip = { | 439 | static struct irq_chip nwl_msi_irq_chip = { |
| 440 | .name = "nwl_pcie:msi", | 440 | .name = "nwl_pcie:msi", |
| 441 | .irq_enable = unmask_msi_irq, | 441 | .irq_enable = pci_msi_unmask_irq, |
| 442 | .irq_disable = mask_msi_irq, | 442 | .irq_disable = pci_msi_mask_irq, |
| 443 | .irq_mask = mask_msi_irq, | 443 | .irq_mask = pci_msi_mask_irq, |
| 444 | .irq_unmask = unmask_msi_irq, | 444 | .irq_unmask = pci_msi_unmask_irq, |
| 445 | |||
| 446 | }; | 445 | }; |
| 447 | 446 | ||
| 448 | static struct msi_domain_info nwl_msi_domain_info = { | 447 | static struct msi_domain_info nwl_msi_domain_info = { |
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index d0b91da49bf4..c0786ca74312 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c | |||
| @@ -438,7 +438,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) | |||
| 438 | epc_features = epf_test->epc_features; | 438 | epc_features = epf_test->epc_features; |
| 439 | 439 | ||
| 440 | base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg), | 440 | base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg), |
| 441 | test_reg_bar); | 441 | test_reg_bar, epc_features->align); |
| 442 | if (!base) { | 442 | if (!base) { |
| 443 | dev_err(dev, "Failed to allocated register space\n"); | 443 | dev_err(dev, "Failed to allocated register space\n"); |
| 444 | return -ENOMEM; | 444 | return -ENOMEM; |
| @@ -453,7 +453,8 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) | |||
| 453 | if (!!(epc_features->reserved_bar & (1 << bar))) | 453 | if (!!(epc_features->reserved_bar & (1 << bar))) |
| 454 | continue; | 454 | continue; |
| 455 | 455 | ||
| 456 | base = pci_epf_alloc_space(epf, bar_size[bar], bar); | 456 | base = pci_epf_alloc_space(epf, bar_size[bar], bar, |
| 457 | epc_features->align); | ||
| 457 | if (!base) | 458 | if (!base) |
| 458 | dev_err(dev, "Failed to allocate space for BAR%d\n", | 459 | dev_err(dev, "Failed to allocate space for BAR%d\n", |
| 459 | bar); | 460 | bar); |
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c index 8bfdcd291196..fb1306de8f40 100644 --- a/drivers/pci/endpoint/pci-epf-core.c +++ b/drivers/pci/endpoint/pci-epf-core.c | |||
| @@ -109,10 +109,12 @@ EXPORT_SYMBOL_GPL(pci_epf_free_space); | |||
| 109 | * pci_epf_alloc_space() - allocate memory for the PCI EPF register space | 109 | * pci_epf_alloc_space() - allocate memory for the PCI EPF register space |
| 110 | * @size: the size of the memory that has to be allocated | 110 | * @size: the size of the memory that has to be allocated |
| 111 | * @bar: the BAR number corresponding to the allocated register space | 111 | * @bar: the BAR number corresponding to the allocated register space |
| 112 | * @align: alignment size for the allocation region | ||
| 112 | * | 113 | * |
| 113 | * Invoke to allocate memory for the PCI EPF register space. | 114 | * Invoke to allocate memory for the PCI EPF register space. |
| 114 | */ | 115 | */ |
| 115 | void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar) | 116 | void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar, |
| 117 | size_t align) | ||
| 116 | { | 118 | { |
| 117 | void *space; | 119 | void *space; |
| 118 | struct device *dev = epf->epc->dev.parent; | 120 | struct device *dev = epf->epc->dev.parent; |
| @@ -120,7 +122,11 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar) | |||
| 120 | 122 | ||
| 121 | if (size < 128) | 123 | if (size < 128) |
| 122 | size = 128; | 124 | size = 128; |
| 123 | size = roundup_pow_of_two(size); | 125 | |
| 126 | if (align) | ||
| 127 | size = ALIGN(size, align); | ||
| 128 | else | ||
| 129 | size = roundup_pow_of_two(size); | ||
| 124 | 130 | ||
| 125 | space = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL); | 131 | space = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL); |
| 126 | if (!space) { | 132 | if (!space) { |
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index e2356a9c7088..182f9e3443ee 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c | |||
| @@ -51,6 +51,7 @@ static struct device_node *find_vio_slot_node(char *drc_name) | |||
| 51 | if (rc == 0) | 51 | if (rc == 0) |
| 52 | break; | 52 | break; |
| 53 | } | 53 | } |
| 54 | of_node_put(parent); | ||
| 54 | 55 | ||
| 55 | return dn; | 56 | return dn; |
| 56 | } | 57 | } |
| @@ -71,6 +72,7 @@ static struct device_node *find_php_slot_pci_node(char *drc_name, | |||
| 71 | return np; | 72 | return np; |
| 72 | } | 73 | } |
| 73 | 74 | ||
| 75 | /* Returns a device_node with its reference count incremented */ | ||
| 74 | static struct device_node *find_dlpar_node(char *drc_name, int *node_type) | 76 | static struct device_node *find_dlpar_node(char *drc_name, int *node_type) |
| 75 | { | 77 | { |
| 76 | struct device_node *dn; | 78 | struct device_node *dn; |
| @@ -306,6 +308,7 @@ int dlpar_add_slot(char *drc_name) | |||
| 306 | rc = dlpar_add_phb(drc_name, dn); | 308 | rc = dlpar_add_phb(drc_name, dn); |
| 307 | break; | 309 | break; |
| 308 | } | 310 | } |
| 311 | of_node_put(dn); | ||
| 309 | 312 | ||
| 310 | printk(KERN_INFO "%s: slot %s added\n", DLPAR_MODULE_NAME, drc_name); | 313 | printk(KERN_INFO "%s: slot %s added\n", DLPAR_MODULE_NAME, drc_name); |
| 311 | exit: | 314 | exit: |
| @@ -439,6 +442,7 @@ int dlpar_remove_slot(char *drc_name) | |||
| 439 | rc = dlpar_remove_pci_slot(drc_name, dn); | 442 | rc = dlpar_remove_pci_slot(drc_name, dn); |
| 440 | break; | 443 | break; |
| 441 | } | 444 | } |
| 445 | of_node_put(dn); | ||
| 442 | vm_unmap_aliases(); | 446 | vm_unmap_aliases(); |
| 443 | 447 | ||
| 444 | printk(KERN_INFO "%s: slot %s removed\n", DLPAR_MODULE_NAME, drc_name); | 448 | printk(KERN_INFO "%s: slot %s removed\n", DLPAR_MODULE_NAME, drc_name); |
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index 5282aa3e33c5..93b4a945c55d 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | /* free up the memory used by a slot */ | 21 | /* free up the memory used by a slot */ |
| 22 | void dealloc_slot_struct(struct slot *slot) | 22 | void dealloc_slot_struct(struct slot *slot) |
| 23 | { | 23 | { |
| 24 | of_node_put(slot->dn); | ||
| 24 | kfree(slot->name); | 25 | kfree(slot->name); |
| 25 | kfree(slot); | 26 | kfree(slot); |
| 26 | } | 27 | } |
| @@ -36,7 +37,7 @@ struct slot *alloc_slot_struct(struct device_node *dn, | |||
| 36 | slot->name = kstrdup(drc_name, GFP_KERNEL); | 37 | slot->name = kstrdup(drc_name, GFP_KERNEL); |
| 37 | if (!slot->name) | 38 | if (!slot->name) |
| 38 | goto error_slot; | 39 | goto error_slot; |
| 39 | slot->dn = dn; | 40 | slot->dn = of_node_get(dn); |
| 40 | slot->index = drc_index; | 41 | slot->index = drc_index; |
| 41 | slot->power_domain = power_domain; | 42 | slot->power_domain = power_domain; |
| 42 | slot->hotplug_slot.ops = &rpaphp_hotplug_slot_ops; | 43 | slot->hotplug_slot.ops = &rpaphp_hotplug_slot_ops; |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 73986825d221..e039b740fe74 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
| @@ -1338,7 +1338,7 @@ irq_hw_number_t pci_msi_domain_calc_hwirq(struct pci_dev *dev, | |||
| 1338 | struct msi_desc *desc) | 1338 | struct msi_desc *desc) |
| 1339 | { | 1339 | { |
| 1340 | return (irq_hw_number_t)desc->msi_attrib.entry_nr | | 1340 | return (irq_hw_number_t)desc->msi_attrib.entry_nr | |
| 1341 | PCI_DEVID(dev->bus->number, dev->devfn) << 11 | | 1341 | pci_dev_id(dev) << 11 | |
| 1342 | (pci_domain_nr(dev->bus) & 0xFFFFFFFF) << 27; | 1342 | (pci_domain_nr(dev->bus) & 0xFFFFFFFF) << 27; |
| 1343 | } | 1343 | } |
| 1344 | 1344 | ||
| @@ -1508,7 +1508,7 @@ static int get_msi_id_cb(struct pci_dev *pdev, u16 alias, void *data) | |||
| 1508 | u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev) | 1508 | u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev) |
| 1509 | { | 1509 | { |
| 1510 | struct device_node *of_node; | 1510 | struct device_node *of_node; |
| 1511 | u32 rid = PCI_DEVID(pdev->bus->number, pdev->devfn); | 1511 | u32 rid = pci_dev_id(pdev); |
| 1512 | 1512 | ||
| 1513 | pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); | 1513 | pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); |
| 1514 | 1514 | ||
| @@ -1531,7 +1531,7 @@ u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev) | |||
| 1531 | struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev) | 1531 | struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev) |
| 1532 | { | 1532 | { |
| 1533 | struct irq_domain *dom; | 1533 | struct irq_domain *dom; |
| 1534 | u32 rid = PCI_DEVID(pdev->bus->number, pdev->devfn); | 1534 | u32 rid = pci_dev_id(pdev); |
| 1535 | 1535 | ||
| 1536 | pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); | 1536 | pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); |
| 1537 | dom = of_msi_map_get_device_domain(&pdev->dev, rid); | 1537 | dom = of_msi_map_get_device_domain(&pdev->dev, rid); |
diff --git a/drivers/pci/of.c b/drivers/pci/of.c index 3d32da15c215..73d5adec0a28 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/of_pci.h> | 15 | #include <linux/of_pci.h> |
| 16 | #include "pci.h" | 16 | #include "pci.h" |
| 17 | 17 | ||
| 18 | #ifdef CONFIG_PCI | ||
| 18 | void pci_set_of_node(struct pci_dev *dev) | 19 | void pci_set_of_node(struct pci_dev *dev) |
| 19 | { | 20 | { |
| 20 | if (!dev->bus->dev.of_node) | 21 | if (!dev->bus->dev.of_node) |
| @@ -31,10 +32,16 @@ void pci_release_of_node(struct pci_dev *dev) | |||
| 31 | 32 | ||
| 32 | void pci_set_bus_of_node(struct pci_bus *bus) | 33 | void pci_set_bus_of_node(struct pci_bus *bus) |
| 33 | { | 34 | { |
| 34 | if (bus->self == NULL) | 35 | struct device_node *node; |
| 35 | bus->dev.of_node = pcibios_get_phb_of_node(bus); | 36 | |
| 36 | else | 37 | if (bus->self == NULL) { |
| 37 | bus->dev.of_node = of_node_get(bus->self->dev.of_node); | 38 | node = pcibios_get_phb_of_node(bus); |
| 39 | } else { | ||
| 40 | node = of_node_get(bus->self->dev.of_node); | ||
| 41 | if (node && of_property_read_bool(node, "external-facing")) | ||
| 42 | bus->self->untrusted = true; | ||
| 43 | } | ||
| 44 | bus->dev.of_node = node; | ||
| 38 | } | 45 | } |
| 39 | 46 | ||
| 40 | void pci_release_bus_of_node(struct pci_bus *bus) | 47 | void pci_release_bus_of_node(struct pci_bus *bus) |
| @@ -197,27 +204,6 @@ int of_get_pci_domain_nr(struct device_node *node) | |||
| 197 | EXPORT_SYMBOL_GPL(of_get_pci_domain_nr); | 204 | EXPORT_SYMBOL_GPL(of_get_pci_domain_nr); |
| 198 | 205 | ||
| 199 | /** | 206 | /** |
| 200 | * This function will try to find the limitation of link speed by finding | ||
| 201 | * a property called "max-link-speed" of the given device node. | ||
| 202 | * | ||
| 203 | * @node: device tree node with the max link speed information | ||
| 204 | * | ||
| 205 | * Returns the associated max link speed from DT, or a negative value if the | ||
| 206 | * required property is not found or is invalid. | ||
| 207 | */ | ||
| 208 | int of_pci_get_max_link_speed(struct device_node *node) | ||
| 209 | { | ||
| 210 | u32 max_link_speed; | ||
| 211 | |||
| 212 | if (of_property_read_u32(node, "max-link-speed", &max_link_speed) || | ||
| 213 | max_link_speed > 4) | ||
| 214 | return -EINVAL; | ||
| 215 | |||
| 216 | return max_link_speed; | ||
| 217 | } | ||
| 218 | EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed); | ||
| 219 | |||
| 220 | /** | ||
| 221 | * of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only | 207 | * of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only |
| 222 | * is present and valid | 208 | * is present and valid |
| 223 | */ | 209 | */ |
| @@ -537,3 +523,25 @@ int pci_parse_request_of_pci_ranges(struct device *dev, | |||
| 537 | return err; | 523 | return err; |
| 538 | } | 524 | } |
| 539 | 525 | ||
| 526 | #endif /* CONFIG_PCI */ | ||
| 527 | |||
| 528 | /** | ||
| 529 | * This function will try to find the limitation of link speed by finding | ||
| 530 | * a property called "max-link-speed" of the given device node. | ||
| 531 | * | ||
| 532 | * @node: device tree node with the max link speed information | ||
| 533 | * | ||
| 534 | * Returns the associated max link speed from DT, or a negative value if the | ||
| 535 | * required property is not found or is invalid. | ||
| 536 | */ | ||
| 537 | int of_pci_get_max_link_speed(struct device_node *node) | ||
| 538 | { | ||
| 539 | u32 max_link_speed; | ||
| 540 | |||
| 541 | if (of_property_read_u32(node, "max-link-speed", &max_link_speed) || | ||
| 542 | max_link_speed > 4) | ||
| 543 | return -EINVAL; | ||
| 544 | |||
| 545 | return max_link_speed; | ||
| 546 | } | ||
| 547 | EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed); | ||
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c index c52298d76e64..742928d0053e 100644 --- a/drivers/pci/p2pdma.c +++ b/drivers/pci/p2pdma.c | |||
| @@ -275,6 +275,30 @@ static void seq_buf_print_bus_devfn(struct seq_buf *buf, struct pci_dev *pdev) | |||
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | /* | 277 | /* |
| 278 | * If we can't find a common upstream bridge take a look at the root | ||
| 279 | * complex and compare it to a whitelist of known good hardware. | ||
| 280 | */ | ||
| 281 | static bool root_complex_whitelist(struct pci_dev *dev) | ||
| 282 | { | ||
| 283 | struct pci_host_bridge *host = pci_find_host_bridge(dev->bus); | ||
| 284 | struct pci_dev *root = pci_get_slot(host->bus, PCI_DEVFN(0, 0)); | ||
| 285 | unsigned short vendor, device; | ||
| 286 | |||
| 287 | if (!root) | ||
| 288 | return false; | ||
| 289 | |||
| 290 | vendor = root->vendor; | ||
| 291 | device = root->device; | ||
| 292 | pci_dev_put(root); | ||
| 293 | |||
| 294 | /* AMD ZEN host bridges can do peer to peer */ | ||
| 295 | if (vendor == PCI_VENDOR_ID_AMD && device == 0x1450) | ||
| 296 | return true; | ||
| 297 | |||
| 298 | return false; | ||
| 299 | } | ||
| 300 | |||
| 301 | /* | ||
| 278 | * Find the distance through the nearest common upstream bridge between | 302 | * Find the distance through the nearest common upstream bridge between |
| 279 | * two PCI devices. | 303 | * two PCI devices. |
| 280 | * | 304 | * |
| @@ -317,13 +341,13 @@ static void seq_buf_print_bus_devfn(struct seq_buf *buf, struct pci_dev *pdev) | |||
| 317 | * In this case, a list of all infringing bridge addresses will be | 341 | * In this case, a list of all infringing bridge addresses will be |
| 318 | * populated in acs_list (assuming it's non-null) for printk purposes. | 342 | * populated in acs_list (assuming it's non-null) for printk purposes. |
| 319 | */ | 343 | */ |
| 320 | static int upstream_bridge_distance(struct pci_dev *a, | 344 | static int upstream_bridge_distance(struct pci_dev *provider, |
| 321 | struct pci_dev *b, | 345 | struct pci_dev *client, |
| 322 | struct seq_buf *acs_list) | 346 | struct seq_buf *acs_list) |
| 323 | { | 347 | { |
| 348 | struct pci_dev *a = provider, *b = client, *bb; | ||
| 324 | int dist_a = 0; | 349 | int dist_a = 0; |
| 325 | int dist_b = 0; | 350 | int dist_b = 0; |
| 326 | struct pci_dev *bb = NULL; | ||
| 327 | int acs_cnt = 0; | 351 | int acs_cnt = 0; |
| 328 | 352 | ||
| 329 | /* | 353 | /* |
| @@ -354,6 +378,14 @@ static int upstream_bridge_distance(struct pci_dev *a, | |||
| 354 | dist_a++; | 378 | dist_a++; |
| 355 | } | 379 | } |
| 356 | 380 | ||
| 381 | /* | ||
| 382 | * Allow the connection if both devices are on a whitelisted root | ||
| 383 | * complex, but add an arbitary large value to the distance. | ||
| 384 | */ | ||
| 385 | if (root_complex_whitelist(provider) && | ||
| 386 | root_complex_whitelist(client)) | ||
| 387 | return 0x1000 + dist_a + dist_b; | ||
| 388 | |||
| 357 | return -1; | 389 | return -1; |
| 358 | 390 | ||
| 359 | check_b_path_acs: | 391 | check_b_path_acs: |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index e1949f7efd9c..03e02dd6c1d9 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
| @@ -119,7 +119,7 @@ phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) | |||
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | static acpi_status decode_type0_hpx_record(union acpi_object *record, | 121 | static acpi_status decode_type0_hpx_record(union acpi_object *record, |
| 122 | struct hotplug_params *hpx) | 122 | struct hpp_type0 *hpx0) |
| 123 | { | 123 | { |
| 124 | int i; | 124 | int i; |
| 125 | union acpi_object *fields = record->package.elements; | 125 | union acpi_object *fields = record->package.elements; |
| @@ -132,12 +132,11 @@ static acpi_status decode_type0_hpx_record(union acpi_object *record, | |||
| 132 | for (i = 2; i < 6; i++) | 132 | for (i = 2; i < 6; i++) |
| 133 | if (fields[i].type != ACPI_TYPE_INTEGER) | 133 | if (fields[i].type != ACPI_TYPE_INTEGER) |
| 134 | return AE_ERROR; | 134 | return AE_ERROR; |
| 135 | hpx->t0 = &hpx->type0_data; | 135 | hpx0->revision = revision; |
| 136 | hpx->t0->revision = revision; | 136 | hpx0->cache_line_size = fields[2].integer.value; |
| 137 | hpx->t0->cache_line_size = fields[2].integer.value; | 137 | hpx0->latency_timer = fields[3].integer.value; |
| 138 | hpx->t0->latency_timer = fields[3].integer.value; | 138 | hpx0->enable_serr = fields[4].integer.value; |
| 139 | hpx->t0->enable_serr = fields[4].integer.value; | 139 | hpx0->enable_perr = fields[5].integer.value; |
| 140 | hpx->t0->enable_perr = fields[5].integer.value; | ||
| 141 | break; | 140 | break; |
| 142 | default: | 141 | default: |
| 143 | printk(KERN_WARNING | 142 | printk(KERN_WARNING |
| @@ -149,7 +148,7 @@ static acpi_status decode_type0_hpx_record(union acpi_object *record, | |||
| 149 | } | 148 | } |
| 150 | 149 | ||
| 151 | static acpi_status decode_type1_hpx_record(union acpi_object *record, | 150 | static acpi_status decode_type1_hpx_record(union acpi_object *record, |
| 152 | struct hotplug_params *hpx) | 151 | struct hpp_type1 *hpx1) |
| 153 | { | 152 | { |
| 154 | int i; | 153 | int i; |
| 155 | union acpi_object *fields = record->package.elements; | 154 | union acpi_object *fields = record->package.elements; |
| @@ -162,11 +161,10 @@ static acpi_status decode_type1_hpx_record(union acpi_object *record, | |||
| 162 | for (i = 2; i < 5; i++) | 161 | for (i = 2; i < 5; i++) |
| 163 | if (fields[i].type != ACPI_TYPE_INTEGER) | 162 | if (fields[i].type != ACPI_TYPE_INTEGER) |
| 164 | return AE_ERROR; | 163 | return AE_ERROR; |
| 165 | hpx->t1 = &hpx->type1_data; | 164 | hpx1->revision = revision; |
| 166 | hpx->t1->revision = revision; | 165 | hpx1->max_mem_read = fields[2].integer.value; |
| 167 | hpx->t1->max_mem_read = fields[2].integer.value; | 166 | hpx1->avg_max_split = fields[3].integer.value; |
| 168 | hpx->t1->avg_max_split = fields[3].integer.value; | 167 | hpx1->tot_max_split = fields[4].integer.value; |
| 169 | hpx->t1->tot_max_split = fields[4].integer.value; | ||
| 170 | break; | 168 | break; |
| 171 | default: | 169 | default: |
| 172 | printk(KERN_WARNING | 170 | printk(KERN_WARNING |
| @@ -178,7 +176,7 @@ static acpi_status decode_type1_hpx_record(union acpi_object *record, | |||
| 178 | } | 176 | } |
| 179 | 177 | ||
| 180 | static acpi_status decode_type2_hpx_record(union acpi_object *record, | 178 | static acpi_status decode_type2_hpx_record(union acpi_object *record, |
| 181 | struct hotplug_params *hpx) | 179 | struct hpp_type2 *hpx2) |
| 182 | { | 180 | { |
| 183 | int i; | 181 | int i; |
| 184 | union acpi_object *fields = record->package.elements; | 182 | union acpi_object *fields = record->package.elements; |
| @@ -191,24 +189,23 @@ static acpi_status decode_type2_hpx_record(union acpi_object *record, | |||
| 191 | for (i = 2; i < 18; i++) | 189 | for (i = 2; i < 18; i++) |
| 192 | if (fields[i].type != ACPI_TYPE_INTEGER) | 190 | if (fields[i].type != ACPI_TYPE_INTEGER) |
| 193 | return AE_ERROR; | 191 | return AE_ERROR; |
| 194 | hpx->t2 = &hpx->type2_data; | 192 | hpx2->revision = revision; |
| 195 | hpx->t2->revision = revision; | 193 | hpx2->unc_err_mask_and = fields[2].integer.value; |
| 196 | hpx->t2->unc_err_mask_and = fields[2].integer.value; | 194 | hpx2->unc_err_mask_or = fields[3].integer.value; |
| 197 | hpx->t2->unc_err_mask_or = fields[3].integer.value; | 195 | hpx2->unc_err_sever_and = fields[4].integer.value; |
| 198 | hpx->t2->unc_err_sever_and = fields[4].integer.value; | 196 | hpx2->unc_err_sever_or = fields[5].integer.value; |
| 199 | hpx->t2->unc_err_sever_or = fields[5].integer.value; | 197 | hpx2->cor_err_mask_and = fields[6].integer.value; |
| 200 | hpx->t2->cor_err_mask_and = fields[6].integer.value; | 198 | hpx2->cor_err_mask_or = fields[7].integer.value; |
| 201 | hpx->t2->cor_err_mask_or = fields[7].integer.value; | 199 | hpx2->adv_err_cap_and = fields[8].integer.value; |
| 202 | hpx->t2->adv_err_cap_and = fields[8].integer.value; | 200 | hpx2->adv_err_cap_or = fields[9].integer.value; |
| 203 | hpx->t2->adv_err_cap_or = fields[9].integer.value; | 201 | hpx2->pci_exp_devctl_and = fields[10].integer.value; |
| 204 | hpx->t2->pci_exp_devctl_and = fields[10].integer.value; | 202 | hpx2->pci_exp_devctl_or = fields[11].integer.value; |
| 205 | hpx->t2->pci_exp_devctl_or = fields[11].integer.value; | 203 | hpx2->pci_exp_lnkctl_and = fields[12].integer.value; |
| 206 | hpx->t2->pci_exp_lnkctl_and = fields[12].integer.value; | 204 | hpx2->pci_exp_lnkctl_or = fields[13].integer.value; |
| 207 | hpx->t2->pci_exp_lnkctl_or = fields[13].integer.value; | 205 | hpx2->sec_unc_err_sever_and = fields[14].integer.value; |
| 208 | hpx->t2->sec_unc_err_sever_and = fields[14].integer.value; | 206 | hpx2->sec_unc_err_sever_or = fields[15].integer.value; |
| 209 | hpx->t2->sec_unc_err_sever_or = fields[15].integer.value; | 207 | hpx2->sec_unc_err_mask_and = fields[16].integer.value; |
| 210 | hpx->t2->sec_unc_err_mask_and = fields[16].integer.value; | 208 | hpx2->sec_unc_err_mask_or = fields[17].integer.value; |
| 211 | hpx->t2->sec_unc_err_mask_or = fields[17].integer.value; | ||
| 212 | break; | 209 | break; |
| 213 | default: | 210 | default: |
| 214 | printk(KERN_WARNING | 211 | printk(KERN_WARNING |
| @@ -219,17 +216,76 @@ static acpi_status decode_type2_hpx_record(union acpi_object *record, | |||
| 219 | return AE_OK; | 216 | return AE_OK; |
| 220 | } | 217 | } |
| 221 | 218 | ||
| 222 | static acpi_status acpi_run_hpx(acpi_handle handle, struct hotplug_params *hpx) | 219 | static void parse_hpx3_register(struct hpx_type3 *hpx3_reg, |
| 220 | union acpi_object *reg_fields) | ||
| 221 | { | ||
| 222 | hpx3_reg->device_type = reg_fields[0].integer.value; | ||
| 223 | hpx3_reg->function_type = reg_fields[1].integer.value; | ||
| 224 | hpx3_reg->config_space_location = reg_fields[2].integer.value; | ||
| 225 | hpx3_reg->pci_exp_cap_id = reg_fields[3].integer.value; | ||
| 226 | hpx3_reg->pci_exp_cap_ver = reg_fields[4].integer.value; | ||
| 227 | hpx3_reg->pci_exp_vendor_id = reg_fields[5].integer.value; | ||
| 228 | hpx3_reg->dvsec_id = reg_fields[6].integer.value; | ||
| 229 | hpx3_reg->dvsec_rev = reg_fields[7].integer.value; | ||
| 230 | hpx3_reg->match_offset = reg_fields[8].integer.value; | ||
| 231 | hpx3_reg->match_mask_and = reg_fields[9].integer.value; | ||
| 232 | hpx3_reg->match_value = reg_fields[10].integer.value; | ||
| 233 | hpx3_reg->reg_offset = reg_fields[11].integer.value; | ||
| 234 | hpx3_reg->reg_mask_and = reg_fields[12].integer.value; | ||
| 235 | hpx3_reg->reg_mask_or = reg_fields[13].integer.value; | ||
| 236 | } | ||
| 237 | |||
| 238 | static acpi_status program_type3_hpx_record(struct pci_dev *dev, | ||
| 239 | union acpi_object *record, | ||
| 240 | const struct hotplug_program_ops *hp_ops) | ||
| 241 | { | ||
| 242 | union acpi_object *fields = record->package.elements; | ||
| 243 | u32 desc_count, expected_length, revision; | ||
| 244 | union acpi_object *reg_fields; | ||
| 245 | struct hpx_type3 hpx3; | ||
| 246 | int i; | ||
| 247 | |||
| 248 | revision = fields[1].integer.value; | ||
| 249 | switch (revision) { | ||
| 250 | case 1: | ||
| 251 | desc_count = fields[2].integer.value; | ||
| 252 | expected_length = 3 + desc_count * 14; | ||
| 253 | |||
| 254 | if (record->package.count != expected_length) | ||
| 255 | return AE_ERROR; | ||
| 256 | |||
| 257 | for (i = 2; i < expected_length; i++) | ||
| 258 | if (fields[i].type != ACPI_TYPE_INTEGER) | ||
| 259 | return AE_ERROR; | ||
| 260 | |||
| 261 | for (i = 0; i < desc_count; i++) { | ||
| 262 | reg_fields = fields + 3 + i * 14; | ||
| 263 | parse_hpx3_register(&hpx3, reg_fields); | ||
| 264 | hp_ops->program_type3(dev, &hpx3); | ||
| 265 | } | ||
| 266 | |||
| 267 | break; | ||
| 268 | default: | ||
| 269 | printk(KERN_WARNING | ||
| 270 | "%s: Type 3 Revision %d record not supported\n", | ||
| 271 | __func__, revision); | ||
| 272 | return AE_ERROR; | ||
| 273 | } | ||
| 274 | return AE_OK; | ||
| 275 | } | ||
| 276 | |||
| 277 | static acpi_status acpi_run_hpx(struct pci_dev *dev, acpi_handle handle, | ||
| 278 | const struct hotplug_program_ops *hp_ops) | ||
| 223 | { | 279 | { |
| 224 | acpi_status status; | 280 | acpi_status status; |
| 225 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | 281 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; |
| 226 | union acpi_object *package, *record, *fields; | 282 | union acpi_object *package, *record, *fields; |
| 283 | struct hpp_type0 hpx0; | ||
| 284 | struct hpp_type1 hpx1; | ||
| 285 | struct hpp_type2 hpx2; | ||
| 227 | u32 type; | 286 | u32 type; |
| 228 | int i; | 287 | int i; |
| 229 | 288 | ||
| 230 | /* Clear the return buffer with zeros */ | ||
| 231 | memset(hpx, 0, sizeof(struct hotplug_params)); | ||
| 232 | |||
| 233 | status = acpi_evaluate_object(handle, "_HPX", NULL, &buffer); | 289 | status = acpi_evaluate_object(handle, "_HPX", NULL, &buffer); |
| 234 | if (ACPI_FAILURE(status)) | 290 | if (ACPI_FAILURE(status)) |
| 235 | return status; | 291 | return status; |
| @@ -257,17 +313,28 @@ static acpi_status acpi_run_hpx(acpi_handle handle, struct hotplug_params *hpx) | |||
| 257 | type = fields[0].integer.value; | 313 | type = fields[0].integer.value; |
| 258 | switch (type) { | 314 | switch (type) { |
| 259 | case 0: | 315 | case 0: |
| 260 | status = decode_type0_hpx_record(record, hpx); | 316 | memset(&hpx0, 0, sizeof(hpx0)); |
| 317 | status = decode_type0_hpx_record(record, &hpx0); | ||
| 261 | if (ACPI_FAILURE(status)) | 318 | if (ACPI_FAILURE(status)) |
| 262 | goto exit; | 319 | goto exit; |
| 320 | hp_ops->program_type0(dev, &hpx0); | ||
| 263 | break; | 321 | break; |
| 264 | case 1: | 322 | case 1: |
| 265 | status = decode_type1_hpx_record(record, hpx); | 323 | memset(&hpx1, 0, sizeof(hpx1)); |
| 324 | status = decode_type1_hpx_record(record, &hpx1); | ||
| 266 | if (ACPI_FAILURE(status)) | 325 | if (ACPI_FAILURE(status)) |
| 267 | goto exit; | 326 | goto exit; |
| 327 | hp_ops->program_type1(dev, &hpx1); | ||
| 268 | break; | 328 | break; |
| 269 | case 2: | 329 | case 2: |
| 270 | status = decode_type2_hpx_record(record, hpx); | 330 | memset(&hpx2, 0, sizeof(hpx2)); |
| 331 | status = decode_type2_hpx_record(record, &hpx2); | ||
| 332 | if (ACPI_FAILURE(status)) | ||
| 333 | goto exit; | ||
| 334 | hp_ops->program_type2(dev, &hpx2); | ||
| 335 | break; | ||
| 336 | case 3: | ||
| 337 | status = program_type3_hpx_record(dev, record, hp_ops); | ||
| 271 | if (ACPI_FAILURE(status)) | 338 | if (ACPI_FAILURE(status)) |
| 272 | goto exit; | 339 | goto exit; |
| 273 | break; | 340 | break; |
| @@ -283,14 +350,16 @@ static acpi_status acpi_run_hpx(acpi_handle handle, struct hotplug_params *hpx) | |||
| 283 | return status; | 350 | return status; |
| 284 | } | 351 | } |
| 285 | 352 | ||
| 286 | static acpi_status acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) | 353 | static acpi_status acpi_run_hpp(struct pci_dev *dev, acpi_handle handle, |
| 354 | const struct hotplug_program_ops *hp_ops) | ||
| 287 | { | 355 | { |
| 288 | acpi_status status; | 356 | acpi_status status; |
| 289 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 357 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
| 290 | union acpi_object *package, *fields; | 358 | union acpi_object *package, *fields; |
| 359 | struct hpp_type0 hpp0; | ||
| 291 | int i; | 360 | int i; |
| 292 | 361 | ||
| 293 | memset(hpp, 0, sizeof(struct hotplug_params)); | 362 | memset(&hpp0, 0, sizeof(hpp0)); |
| 294 | 363 | ||
| 295 | status = acpi_evaluate_object(handle, "_HPP", NULL, &buffer); | 364 | status = acpi_evaluate_object(handle, "_HPP", NULL, &buffer); |
| 296 | if (ACPI_FAILURE(status)) | 365 | if (ACPI_FAILURE(status)) |
| @@ -311,12 +380,13 @@ static acpi_status acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) | |||
| 311 | } | 380 | } |
| 312 | } | 381 | } |
| 313 | 382 | ||
| 314 | hpp->t0 = &hpp->type0_data; | 383 | hpp0.revision = 1; |
| 315 | hpp->t0->revision = 1; | 384 | hpp0.cache_line_size = fields[0].integer.value; |
| 316 | hpp->t0->cache_line_size = fields[0].integer.value; | 385 | hpp0.latency_timer = fields[1].integer.value; |
| 317 | hpp->t0->latency_timer = fields[1].integer.value; | 386 | hpp0.enable_serr = fields[2].integer.value; |
| 318 | hpp->t0->enable_serr = fields[2].integer.value; | 387 | hpp0.enable_perr = fields[3].integer.value; |
| 319 | hpp->t0->enable_perr = fields[3].integer.value; | 388 | |
| 389 | hp_ops->program_type0(dev, &hpp0); | ||
| 320 | 390 | ||
| 321 | exit: | 391 | exit: |
| 322 | kfree(buffer.pointer); | 392 | kfree(buffer.pointer); |
| @@ -328,7 +398,8 @@ exit: | |||
| 328 | * @dev - the pci_dev for which we want parameters | 398 | * @dev - the pci_dev for which we want parameters |
| 329 | * @hpp - allocated by the caller | 399 | * @hpp - allocated by the caller |
| 330 | */ | 400 | */ |
| 331 | int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp) | 401 | int pci_acpi_program_hp_params(struct pci_dev *dev, |
| 402 | const struct hotplug_program_ops *hp_ops) | ||
| 332 | { | 403 | { |
| 333 | acpi_status status; | 404 | acpi_status status; |
| 334 | acpi_handle handle, phandle; | 405 | acpi_handle handle, phandle; |
| @@ -351,10 +422,10 @@ int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp) | |||
| 351 | * this pci dev. | 422 | * this pci dev. |
| 352 | */ | 423 | */ |
| 353 | while (handle) { | 424 | while (handle) { |
| 354 | status = acpi_run_hpx(handle, hpp); | 425 | status = acpi_run_hpx(dev, handle, hp_ops); |
| 355 | if (ACPI_SUCCESS(status)) | 426 | if (ACPI_SUCCESS(status)) |
| 356 | return 0; | 427 | return 0; |
| 357 | status = acpi_run_hpp(handle, hpp); | 428 | status = acpi_run_hpp(dev, handle, hp_ops); |
| 358 | if (ACPI_SUCCESS(status)) | 429 | if (ACPI_SUCCESS(status)) |
| 359 | return 0; | 430 | return 0; |
| 360 | if (acpi_is_root_bridge(handle)) | 431 | if (acpi_is_root_bridge(handle)) |
| @@ -366,7 +437,6 @@ int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp) | |||
| 366 | } | 437 | } |
| 367 | return -ENODEV; | 438 | return -ENODEV; |
| 368 | } | 439 | } |
| 369 | EXPORT_SYMBOL_GPL(pci_get_hp_params); | ||
| 370 | 440 | ||
| 371 | /** | 441 | /** |
| 372 | * pciehp_is_native - Check whether a hotplug port is handled by the OS | 442 | * pciehp_is_native - Check whether a hotplug port is handled by the OS |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 7c1b362f599a..d185b49e105a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -3707,31 +3707,6 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) | |||
| 3707 | EXPORT_SYMBOL(pci_request_region); | 3707 | EXPORT_SYMBOL(pci_request_region); |
| 3708 | 3708 | ||
| 3709 | /** | 3709 | /** |
| 3710 | * pci_request_region_exclusive - Reserved PCI I/O and memory resource | ||
| 3711 | * @pdev: PCI device whose resources are to be reserved | ||
| 3712 | * @bar: BAR to be reserved | ||
| 3713 | * @res_name: Name to be associated with resource. | ||
| 3714 | * | ||
| 3715 | * Mark the PCI region associated with PCI device @pdev BR @bar as | ||
| 3716 | * being reserved by owner @res_name. Do not access any | ||
| 3717 | * address inside the PCI regions unless this call returns | ||
| 3718 | * successfully. | ||
| 3719 | * | ||
| 3720 | * Returns 0 on success, or %EBUSY on error. A warning | ||
| 3721 | * message is also printed on failure. | ||
| 3722 | * | ||
| 3723 | * The key difference that _exclusive makes it that userspace is | ||
| 3724 | * explicitly not allowed to map the resource via /dev/mem or | ||
| 3725 | * sysfs. | ||
| 3726 | */ | ||
| 3727 | int pci_request_region_exclusive(struct pci_dev *pdev, int bar, | ||
| 3728 | const char *res_name) | ||
| 3729 | { | ||
| 3730 | return __pci_request_region(pdev, bar, res_name, IORESOURCE_EXCLUSIVE); | ||
| 3731 | } | ||
| 3732 | EXPORT_SYMBOL(pci_request_region_exclusive); | ||
| 3733 | |||
| 3734 | /** | ||
| 3735 | * pci_release_selected_regions - Release selected PCI I/O and memory resources | 3710 | * pci_release_selected_regions - Release selected PCI I/O and memory resources |
| 3736 | * @pdev: PCI device whose resources were previously reserved | 3711 | * @pdev: PCI device whose resources were previously reserved |
| 3737 | * @bars: Bitmask of BARs to be released | 3712 | * @bars: Bitmask of BARs to be released |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 224d88634115..17c4ed2021de 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
| @@ -596,7 +596,7 @@ void pci_aer_clear_fatal_status(struct pci_dev *dev); | |||
| 596 | void pci_aer_clear_device_status(struct pci_dev *dev); | 596 | void pci_aer_clear_device_status(struct pci_dev *dev); |
| 597 | #else | 597 | #else |
| 598 | static inline void pci_no_aer(void) { } | 598 | static inline void pci_no_aer(void) { } |
| 599 | static inline int pci_aer_init(struct pci_dev *d) { return -ENODEV; } | 599 | static inline void pci_aer_init(struct pci_dev *d) { } |
| 600 | static inline void pci_aer_exit(struct pci_dev *d) { } | 600 | static inline void pci_aer_exit(struct pci_dev *d) { } |
| 601 | static inline void pci_aer_clear_fatal_status(struct pci_dev *dev) { } | 601 | static inline void pci_aer_clear_fatal_status(struct pci_dev *dev) { } |
| 602 | static inline void pci_aer_clear_device_status(struct pci_dev *dev) { } | 602 | static inline void pci_aer_clear_device_status(struct pci_dev *dev) { } |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 727e3c1ef9a4..fd4cb75088f9 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
| @@ -196,6 +196,36 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) | |||
| 196 | link->clkpm_capable = (blacklist) ? 0 : capable; | 196 | link->clkpm_capable = (blacklist) ? 0 : capable; |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | static bool pcie_retrain_link(struct pcie_link_state *link) | ||
| 200 | { | ||
| 201 | struct pci_dev *parent = link->pdev; | ||
| 202 | unsigned long end_jiffies; | ||
| 203 | u16 reg16; | ||
| 204 | |||
| 205 | pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); | ||
| 206 | reg16 |= PCI_EXP_LNKCTL_RL; | ||
| 207 | pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); | ||
| 208 | if (parent->clear_retrain_link) { | ||
| 209 | /* | ||
| 210 | * Due to an erratum in some devices the Retrain Link bit | ||
| 211 | * needs to be cleared again manually to allow the link | ||
| 212 | * training to succeed. | ||
| 213 | */ | ||
| 214 | reg16 &= ~PCI_EXP_LNKCTL_RL; | ||
| 215 | pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); | ||
| 216 | } | ||
| 217 | |||
| 218 | /* Wait for link training end. Break out after waiting for timeout */ | ||
| 219 | end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT; | ||
| 220 | do { | ||
| 221 | pcie_capability_read_word(parent, PCI_EXP_LNKSTA, ®16); | ||
| 222 | if (!(reg16 & PCI_EXP_LNKSTA_LT)) | ||
| 223 | break; | ||
| 224 | msleep(1); | ||
| 225 | } while (time_before(jiffies, end_jiffies)); | ||
| 226 | return !(reg16 & PCI_EXP_LNKSTA_LT); | ||
| 227 | } | ||
| 228 | |||
| 199 | /* | 229 | /* |
| 200 | * pcie_aspm_configure_common_clock: check if the 2 ends of a link | 230 | * pcie_aspm_configure_common_clock: check if the 2 ends of a link |
| 201 | * could use common clock. If they are, configure them to use the | 231 | * could use common clock. If they are, configure them to use the |
| @@ -205,7 +235,6 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) | |||
| 205 | { | 235 | { |
| 206 | int same_clock = 1; | 236 | int same_clock = 1; |
| 207 | u16 reg16, parent_reg, child_reg[8]; | 237 | u16 reg16, parent_reg, child_reg[8]; |
| 208 | unsigned long start_jiffies; | ||
| 209 | struct pci_dev *child, *parent = link->pdev; | 238 | struct pci_dev *child, *parent = link->pdev; |
| 210 | struct pci_bus *linkbus = parent->subordinate; | 239 | struct pci_bus *linkbus = parent->subordinate; |
| 211 | /* | 240 | /* |
| @@ -263,21 +292,7 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) | |||
| 263 | reg16 &= ~PCI_EXP_LNKCTL_CCC; | 292 | reg16 &= ~PCI_EXP_LNKCTL_CCC; |
| 264 | pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); | 293 | pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); |
| 265 | 294 | ||
| 266 | /* Retrain link */ | 295 | if (pcie_retrain_link(link)) |
| 267 | reg16 |= PCI_EXP_LNKCTL_RL; | ||
| 268 | pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); | ||
| 269 | |||
| 270 | /* Wait for link training end. Break out after waiting for timeout */ | ||
| 271 | start_jiffies = jiffies; | ||
| 272 | for (;;) { | ||
| 273 | pcie_capability_read_word(parent, PCI_EXP_LNKSTA, ®16); | ||
| 274 | if (!(reg16 & PCI_EXP_LNKSTA_LT)) | ||
| 275 | break; | ||
| 276 | if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT)) | ||
| 277 | break; | ||
| 278 | msleep(1); | ||
| 279 | } | ||
| 280 | if (!(reg16 & PCI_EXP_LNKSTA_LT)) | ||
| 281 | return; | 296 | return; |
| 282 | 297 | ||
| 283 | /* Training failed. Restore common clock configurations */ | 298 | /* Training failed. Restore common clock configurations */ |
diff --git a/drivers/pci/pcie/bw_notification.c b/drivers/pci/pcie/bw_notification.c index d2eae3b7cc0f..971eb7e90fb0 100644 --- a/drivers/pci/pcie/bw_notification.c +++ b/drivers/pci/pcie/bw_notification.c | |||
| @@ -96,11 +96,25 @@ static void pcie_bandwidth_notification_remove(struct pcie_device *srv) | |||
| 96 | free_irq(srv->irq, srv); | 96 | free_irq(srv->irq, srv); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | static int pcie_bandwidth_notification_suspend(struct pcie_device *srv) | ||
| 100 | { | ||
| 101 | pcie_disable_link_bandwidth_notification(srv->port); | ||
| 102 | return 0; | ||
| 103 | } | ||
| 104 | |||
| 105 | static int pcie_bandwidth_notification_resume(struct pcie_device *srv) | ||
| 106 | { | ||
| 107 | pcie_enable_link_bandwidth_notification(srv->port); | ||
| 108 | return 0; | ||
| 109 | } | ||
| 110 | |||
| 99 | static struct pcie_port_service_driver pcie_bandwidth_notification_driver = { | 111 | static struct pcie_port_service_driver pcie_bandwidth_notification_driver = { |
| 100 | .name = "pcie_bw_notification", | 112 | .name = "pcie_bw_notification", |
| 101 | .port_type = PCIE_ANY_PORT, | 113 | .port_type = PCIE_ANY_PORT, |
| 102 | .service = PCIE_PORT_SERVICE_BWNOTIF, | 114 | .service = PCIE_PORT_SERVICE_BWNOTIF, |
| 103 | .probe = pcie_bandwidth_notification_probe, | 115 | .probe = pcie_bandwidth_notification_probe, |
| 116 | .suspend = pcie_bandwidth_notification_suspend, | ||
| 117 | .resume = pcie_bandwidth_notification_resume, | ||
| 104 | .remove = pcie_bandwidth_notification_remove, | 118 | .remove = pcie_bandwidth_notification_remove, |
| 105 | }; | 119 | }; |
| 106 | 120 | ||
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2ec0df04e0dc..50cd9c17c08f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
| @@ -586,16 +586,9 @@ static void pci_release_host_bridge_dev(struct device *dev) | |||
| 586 | kfree(to_pci_host_bridge(dev)); | 586 | kfree(to_pci_host_bridge(dev)); |
| 587 | } | 587 | } |
| 588 | 588 | ||
| 589 | struct pci_host_bridge *pci_alloc_host_bridge(size_t priv) | 589 | static void pci_init_host_bridge(struct pci_host_bridge *bridge) |
| 590 | { | 590 | { |
| 591 | struct pci_host_bridge *bridge; | ||
| 592 | |||
| 593 | bridge = kzalloc(sizeof(*bridge) + priv, GFP_KERNEL); | ||
| 594 | if (!bridge) | ||
| 595 | return NULL; | ||
| 596 | |||
| 597 | INIT_LIST_HEAD(&bridge->windows); | 591 | INIT_LIST_HEAD(&bridge->windows); |
| 598 | bridge->dev.release = pci_release_host_bridge_dev; | ||
| 599 | 592 | ||
| 600 | /* | 593 | /* |
| 601 | * We assume we can manage these PCIe features. Some systems may | 594 | * We assume we can manage these PCIe features. Some systems may |
| @@ -608,6 +601,18 @@ struct pci_host_bridge *pci_alloc_host_bridge(size_t priv) | |||
| 608 | bridge->native_shpc_hotplug = 1; | 601 | bridge->native_shpc_hotplug = 1; |
| 609 | bridge->native_pme = 1; | 602 | bridge->native_pme = 1; |
| 610 | bridge->native_ltr = 1; | 603 | bridge->native_ltr = 1; |
| 604 | } | ||
| 605 | |||
| 606 | struct pci_host_bridge *pci_alloc_host_bridge(size_t priv) | ||
| 607 | { | ||
| 608 | struct pci_host_bridge *bridge; | ||
| 609 | |||
| 610 | bridge = kzalloc(sizeof(*bridge) + priv, GFP_KERNEL); | ||
| 611 | if (!bridge) | ||
| 612 | return NULL; | ||
| 613 | |||
| 614 | pci_init_host_bridge(bridge); | ||
| 615 | bridge->dev.release = pci_release_host_bridge_dev; | ||
| 611 | 616 | ||
| 612 | return bridge; | 617 | return bridge; |
| 613 | } | 618 | } |
| @@ -622,7 +627,7 @@ struct pci_host_bridge *devm_pci_alloc_host_bridge(struct device *dev, | |||
| 622 | if (!bridge) | 627 | if (!bridge) |
| 623 | return NULL; | 628 | return NULL; |
| 624 | 629 | ||
| 625 | INIT_LIST_HEAD(&bridge->windows); | 630 | pci_init_host_bridge(bridge); |
| 626 | bridge->dev.release = devm_pci_release_host_bridge_dev; | 631 | bridge->dev.release = devm_pci_release_host_bridge_dev; |
| 627 | 632 | ||
| 628 | return bridge; | 633 | return bridge; |
| @@ -1081,6 +1086,36 @@ static void pci_enable_crs(struct pci_dev *pdev) | |||
| 1081 | 1086 | ||
| 1082 | static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, | 1087 | static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, |
| 1083 | unsigned int available_buses); | 1088 | unsigned int available_buses); |
| 1089 | /** | ||
| 1090 | * pci_ea_fixed_busnrs() - Read fixed Secondary and Subordinate bus | ||
| 1091 | * numbers from EA capability. | ||
| 1092 | * @dev: Bridge | ||
| 1093 | * @sec: updated with secondary bus number from EA | ||
| 1094 | * @sub: updated with subordinate bus number from EA | ||
| 1095 | * | ||
| 1096 | * If @dev is a bridge with EA capability, update @sec and @sub with | ||
| 1097 | * fixed bus numbers from the capability and return true. Otherwise, | ||
| 1098 | * return false. | ||
| 1099 | */ | ||
| 1100 | static bool pci_ea_fixed_busnrs(struct pci_dev *dev, u8 *sec, u8 *sub) | ||
| 1101 | { | ||
| 1102 | int ea, offset; | ||
| 1103 | u32 dw; | ||
| 1104 | |||
| 1105 | if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) | ||
| 1106 | return false; | ||
| 1107 | |||
| 1108 | /* find PCI EA capability in list */ | ||
| 1109 | ea = pci_find_capability(dev, PCI_CAP_ID_EA); | ||
| 1110 | if (!ea) | ||
| 1111 | return false; | ||
| 1112 | |||
| 1113 | offset = ea + PCI_EA_FIRST_ENT; | ||
| 1114 | pci_read_config_dword(dev, offset, &dw); | ||
| 1115 | *sec = dw & PCI_EA_SEC_BUS_MASK; | ||
| 1116 | *sub = (dw & PCI_EA_SUB_BUS_MASK) >> PCI_EA_SUB_BUS_SHIFT; | ||
| 1117 | return true; | ||
| 1118 | } | ||
| 1084 | 1119 | ||
| 1085 | /* | 1120 | /* |
| 1086 | * pci_scan_bridge_extend() - Scan buses behind a bridge | 1121 | * pci_scan_bridge_extend() - Scan buses behind a bridge |
| @@ -1115,6 +1150,9 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev, | |||
| 1115 | u16 bctl; | 1150 | u16 bctl; |
| 1116 | u8 primary, secondary, subordinate; | 1151 | u8 primary, secondary, subordinate; |
| 1117 | int broken = 0; | 1152 | int broken = 0; |
| 1153 | bool fixed_buses; | ||
| 1154 | u8 fixed_sec, fixed_sub; | ||
| 1155 | int next_busnr; | ||
| 1118 | 1156 | ||
| 1119 | /* | 1157 | /* |
| 1120 | * Make sure the bridge is powered on to be able to access config | 1158 | * Make sure the bridge is powered on to be able to access config |
| @@ -1214,17 +1252,24 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev, | |||
| 1214 | /* Clear errors */ | 1252 | /* Clear errors */ |
| 1215 | pci_write_config_word(dev, PCI_STATUS, 0xffff); | 1253 | pci_write_config_word(dev, PCI_STATUS, 0xffff); |
| 1216 | 1254 | ||
| 1255 | /* Read bus numbers from EA Capability (if present) */ | ||
| 1256 | fixed_buses = pci_ea_fixed_busnrs(dev, &fixed_sec, &fixed_sub); | ||
| 1257 | if (fixed_buses) | ||
| 1258 | next_busnr = fixed_sec; | ||
| 1259 | else | ||
| 1260 | next_busnr = max + 1; | ||
| 1261 | |||
| 1217 | /* | 1262 | /* |
| 1218 | * Prevent assigning a bus number that already exists. | 1263 | * Prevent assigning a bus number that already exists. |
| 1219 | * This can happen when a bridge is hot-plugged, so in this | 1264 | * This can happen when a bridge is hot-plugged, so in this |
| 1220 | * case we only re-scan this bus. | 1265 | * case we only re-scan this bus. |
| 1221 | */ | 1266 | */ |
| 1222 | child = pci_find_bus(pci_domain_nr(bus), max+1); | 1267 | child = pci_find_bus(pci_domain_nr(bus), next_busnr); |
| 1223 | if (!child) { | 1268 | if (!child) { |
| 1224 | child = pci_add_new_bus(bus, dev, max+1); | 1269 | child = pci_add_new_bus(bus, dev, next_busnr); |
| 1225 | if (!child) | 1270 | if (!child) |
| 1226 | goto out; | 1271 | goto out; |
| 1227 | pci_bus_insert_busn_res(child, max+1, | 1272 | pci_bus_insert_busn_res(child, next_busnr, |
| 1228 | bus->busn_res.end); | 1273 | bus->busn_res.end); |
| 1229 | } | 1274 | } |
| 1230 | max++; | 1275 | max++; |
| @@ -1285,7 +1330,13 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev, | |||
| 1285 | max += i; | 1330 | max += i; |
| 1286 | } | 1331 | } |
| 1287 | 1332 | ||
| 1288 | /* Set subordinate bus number to its real value */ | 1333 | /* |
| 1334 | * Set subordinate bus number to its real value. | ||
| 1335 | * If fixed subordinate bus number exists from EA | ||
| 1336 | * capability then use it. | ||
| 1337 | */ | ||
| 1338 | if (fixed_buses) | ||
| 1339 | max = fixed_sub; | ||
| 1289 | pci_bus_update_busn_res_end(child, max); | 1340 | pci_bus_update_busn_res_end(child, max); |
| 1290 | pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); | 1341 | pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); |
| 1291 | } | 1342 | } |
| @@ -2026,6 +2077,119 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) | |||
| 2026 | */ | 2077 | */ |
| 2027 | } | 2078 | } |
| 2028 | 2079 | ||
| 2080 | static u16 hpx3_device_type(struct pci_dev *dev) | ||
| 2081 | { | ||
| 2082 | u16 pcie_type = pci_pcie_type(dev); | ||
| 2083 | const int pcie_to_hpx3_type[] = { | ||
| 2084 | [PCI_EXP_TYPE_ENDPOINT] = HPX_TYPE_ENDPOINT, | ||
| 2085 | [PCI_EXP_TYPE_LEG_END] = HPX_TYPE_LEG_END, | ||
| 2086 | [PCI_EXP_TYPE_RC_END] = HPX_TYPE_RC_END, | ||
| 2087 | [PCI_EXP_TYPE_RC_EC] = HPX_TYPE_RC_EC, | ||
| 2088 | [PCI_EXP_TYPE_ROOT_PORT] = HPX_TYPE_ROOT_PORT, | ||
| 2089 | [PCI_EXP_TYPE_UPSTREAM] = HPX_TYPE_UPSTREAM, | ||
| 2090 | [PCI_EXP_TYPE_DOWNSTREAM] = HPX_TYPE_DOWNSTREAM, | ||
| 2091 | [PCI_EXP_TYPE_PCI_BRIDGE] = HPX_TYPE_PCI_BRIDGE, | ||
| 2092 | [PCI_EXP_TYPE_PCIE_BRIDGE] = HPX_TYPE_PCIE_BRIDGE, | ||
| 2093 | }; | ||
| 2094 | |||
| 2095 | if (pcie_type >= ARRAY_SIZE(pcie_to_hpx3_type)) | ||
| 2096 | return 0; | ||
| 2097 | |||
| 2098 | return pcie_to_hpx3_type[pcie_type]; | ||
| 2099 | } | ||
| 2100 | |||
| 2101 | static u8 hpx3_function_type(struct pci_dev *dev) | ||
| 2102 | { | ||
| 2103 | if (dev->is_virtfn) | ||
| 2104 | return HPX_FN_SRIOV_VIRT; | ||
| 2105 | else if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV) > 0) | ||
| 2106 | return HPX_FN_SRIOV_PHYS; | ||
| 2107 | else | ||
| 2108 | return HPX_FN_NORMAL; | ||
| 2109 | } | ||
| 2110 | |||
| 2111 | static bool hpx3_cap_ver_matches(u8 pcie_cap_id, u8 hpx3_cap_id) | ||
| 2112 | { | ||
| 2113 | u8 cap_ver = hpx3_cap_id & 0xf; | ||
| 2114 | |||
| 2115 | if ((hpx3_cap_id & BIT(4)) && cap_ver >= pcie_cap_id) | ||
| 2116 | return true; | ||
| 2117 | else if (cap_ver == pcie_cap_id) | ||
| 2118 | return true; | ||
| 2119 | |||
| 2120 | return false; | ||
| 2121 | } | ||
| 2122 | |||
| 2123 | static void program_hpx_type3_register(struct pci_dev *dev, | ||
| 2124 | const struct hpx_type3 *reg) | ||
| 2125 | { | ||
| 2126 | u32 match_reg, write_reg, header, orig_value; | ||
| 2127 | u16 pos; | ||
| 2128 | |||
| 2129 | if (!(hpx3_device_type(dev) & reg->device_type)) | ||
| 2130 | return; | ||
| 2131 | |||
| 2132 | if (!(hpx3_function_type(dev) & reg->function_type)) | ||
| 2133 | return; | ||
| 2134 | |||
| 2135 | switch (reg->config_space_location) { | ||
| 2136 | case HPX_CFG_PCICFG: | ||
| 2137 | pos = 0; | ||
| 2138 | break; | ||
| 2139 | case HPX_CFG_PCIE_CAP: | ||
| 2140 | pos = pci_find_capability(dev, reg->pci_exp_cap_id); | ||
| 2141 | if (pos == 0) | ||
| 2142 | return; | ||
| 2143 | |||
| 2144 | break; | ||
| 2145 | case HPX_CFG_PCIE_CAP_EXT: | ||
| 2146 | pos = pci_find_ext_capability(dev, reg->pci_exp_cap_id); | ||
| 2147 | if (pos == 0) | ||
| 2148 | return; | ||
| 2149 | |||
| 2150 | pci_read_config_dword(dev, pos, &header); | ||
| 2151 | if (!hpx3_cap_ver_matches(PCI_EXT_CAP_VER(header), | ||
| 2152 | reg->pci_exp_cap_ver)) | ||
| 2153 | return; | ||
| 2154 | |||
| 2155 | break; | ||
| 2156 | case HPX_CFG_VEND_CAP: /* Fall through */ | ||
| 2157 | case HPX_CFG_DVSEC: /* Fall through */ | ||
| 2158 | default: | ||
| 2159 | pci_warn(dev, "Encountered _HPX type 3 with unsupported config space location"); | ||
| 2160 | return; | ||
| 2161 | } | ||
| 2162 | |||
| 2163 | pci_read_config_dword(dev, pos + reg->match_offset, &match_reg); | ||
| 2164 | |||
| 2165 | if ((match_reg & reg->match_mask_and) != reg->match_value) | ||
| 2166 | return; | ||
| 2167 | |||
| 2168 | pci_read_config_dword(dev, pos + reg->reg_offset, &write_reg); | ||
| 2169 | orig_value = write_reg; | ||
| 2170 | write_reg &= reg->reg_mask_and; | ||
| 2171 | write_reg |= reg->reg_mask_or; | ||
| 2172 | |||
| 2173 | if (orig_value == write_reg) | ||
| 2174 | return; | ||
| 2175 | |||
| 2176 | pci_write_config_dword(dev, pos + reg->reg_offset, write_reg); | ||
| 2177 | |||
| 2178 | pci_dbg(dev, "Applied _HPX3 at [0x%x]: 0x%08x -> 0x%08x", | ||
| 2179 | pos, orig_value, write_reg); | ||
| 2180 | } | ||
| 2181 | |||
| 2182 | static void program_hpx_type3(struct pci_dev *dev, struct hpx_type3 *hpx3) | ||
| 2183 | { | ||
| 2184 | if (!hpx3) | ||
| 2185 | return; | ||
| 2186 | |||
| 2187 | if (!pci_is_pcie(dev)) | ||
| 2188 | return; | ||
| 2189 | |||
| 2190 | program_hpx_type3_register(dev, hpx3); | ||
| 2191 | } | ||
| 2192 | |||
| 2029 | int pci_configure_extended_tags(struct pci_dev *dev, void *ign) | 2193 | int pci_configure_extended_tags(struct pci_dev *dev, void *ign) |
| 2030 | { | 2194 | { |
| 2031 | struct pci_host_bridge *host; | 2195 | struct pci_host_bridge *host; |
| @@ -2206,8 +2370,12 @@ static void pci_configure_serr(struct pci_dev *dev) | |||
| 2206 | 2370 | ||
| 2207 | static void pci_configure_device(struct pci_dev *dev) | 2371 | static void pci_configure_device(struct pci_dev *dev) |
| 2208 | { | 2372 | { |
| 2209 | struct hotplug_params hpp; | 2373 | static const struct hotplug_program_ops hp_ops = { |
| 2210 | int ret; | 2374 | .program_type0 = program_hpp_type0, |
| 2375 | .program_type1 = program_hpp_type1, | ||
| 2376 | .program_type2 = program_hpp_type2, | ||
| 2377 | .program_type3 = program_hpx_type3, | ||
| 2378 | }; | ||
| 2211 | 2379 | ||
| 2212 | pci_configure_mps(dev); | 2380 | pci_configure_mps(dev); |
| 2213 | pci_configure_extended_tags(dev, NULL); | 2381 | pci_configure_extended_tags(dev, NULL); |
| @@ -2216,14 +2384,7 @@ static void pci_configure_device(struct pci_dev *dev) | |||
| 2216 | pci_configure_eetlp_prefix(dev); | 2384 | pci_configure_eetlp_prefix(dev); |
| 2217 | pci_configure_serr(dev); | 2385 | pci_configure_serr(dev); |
| 2218 | 2386 | ||
| 2219 | memset(&hpp, 0, sizeof(hpp)); | 2387 | pci_acpi_program_hp_params(dev, &hp_ops); |
| 2220 | ret = pci_get_hp_params(dev, &hpp); | ||
| 2221 | if (ret) | ||
| 2222 | return; | ||
| 2223 | |||
| 2224 | program_hpp_type2(dev, hpp.t2); | ||
| 2225 | program_hpp_type1(dev, hpp.t1); | ||
| 2226 | program_hpp_type0(dev, hpp.t0); | ||
| 2227 | } | 2388 | } |
| 2228 | 2389 | ||
| 2229 | static void pci_release_capabilities(struct pci_dev *dev) | 2390 | static void pci_release_capabilities(struct pci_dev *dev) |
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 6fa1627ce08d..445b51db75b0 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
| @@ -222,6 +222,7 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd, | |||
| 222 | } | 222 | } |
| 223 | /* If arch decided it can't, fall through... */ | 223 | /* If arch decided it can't, fall through... */ |
| 224 | #endif /* HAVE_PCI_MMAP */ | 224 | #endif /* HAVE_PCI_MMAP */ |
| 225 | /* fall through */ | ||
| 225 | default: | 226 | default: |
| 226 | ret = -EINVAL; | 227 | ret = -EINVAL; |
| 227 | break; | 228 | break; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index a59ad09ce911..9d32019411fd 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -2245,6 +2245,23 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f1, quirk_disable_aspm_l0s); | |||
| 2245 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s); | 2245 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s); |
| 2246 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s); | 2246 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s); |
| 2247 | 2247 | ||
| 2248 | /* | ||
| 2249 | * Some Pericom PCIe-to-PCI bridges in reverse mode need the PCIe Retrain | ||
| 2250 | * Link bit cleared after starting the link retrain process to allow this | ||
| 2251 | * process to finish. | ||
| 2252 | * | ||
| 2253 | * Affected devices: PI7C9X110, PI7C9X111SL, PI7C9X130. See also the | ||
| 2254 | * Pericom Errata Sheet PI7C9X111SLB_errata_rev1.2_102711.pdf. | ||
| 2255 | */ | ||
| 2256 | static void quirk_enable_clear_retrain_link(struct pci_dev *dev) | ||
| 2257 | { | ||
| 2258 | dev->clear_retrain_link = 1; | ||
| 2259 | pci_info(dev, "Enable PCIe Retrain Link quirk\n"); | ||
| 2260 | } | ||
| 2261 | DECLARE_PCI_FIXUP_HEADER(0x12d8, 0xe110, quirk_enable_clear_retrain_link); | ||
| 2262 | DECLARE_PCI_FIXUP_HEADER(0x12d8, 0xe111, quirk_enable_clear_retrain_link); | ||
| 2263 | DECLARE_PCI_FIXUP_HEADER(0x12d8, 0xe130, quirk_enable_clear_retrain_link); | ||
| 2264 | |||
| 2248 | static void fixup_rev1_53c810(struct pci_dev *dev) | 2265 | static void fixup_rev1_53c810(struct pci_dev *dev) |
| 2249 | { | 2266 | { |
| 2250 | u32 class = dev->class; | 2267 | u32 class = dev->class; |
| @@ -3408,6 +3425,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset); | |||
| 3408 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0032, quirk_no_bus_reset); | 3425 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0032, quirk_no_bus_reset); |
| 3409 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003c, quirk_no_bus_reset); | 3426 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003c, quirk_no_bus_reset); |
| 3410 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0033, quirk_no_bus_reset); | 3427 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0033, quirk_no_bus_reset); |
| 3428 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0034, quirk_no_bus_reset); | ||
| 3411 | 3429 | ||
| 3412 | /* | 3430 | /* |
| 3413 | * Root port on some Cavium CN8xxx chips do not successfully complete a bus | 3431 | * Root port on some Cavium CN8xxx chips do not successfully complete a bus |
| @@ -4903,6 +4921,7 @@ static void quirk_no_ats(struct pci_dev *pdev) | |||
| 4903 | 4921 | ||
| 4904 | /* AMD Stoney platform GPU */ | 4922 | /* AMD Stoney platform GPU */ |
| 4905 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x98e4, quirk_no_ats); | 4923 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x98e4, quirk_no_ats); |
| 4924 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x6900, quirk_no_ats); | ||
| 4906 | #endif /* CONFIG_PCI_ATS */ | 4925 | #endif /* CONFIG_PCI_ATS */ |
| 4907 | 4926 | ||
| 4908 | /* Freescale PCIe doesn't support MSI in RC mode */ | 4927 | /* Freescale PCIe doesn't support MSI in RC mode */ |
| @@ -5120,3 +5139,61 @@ SWITCHTEC_QUIRK(0x8573); /* PFXI 48XG3 */ | |||
| 5120 | SWITCHTEC_QUIRK(0x8574); /* PFXI 64XG3 */ | 5139 | SWITCHTEC_QUIRK(0x8574); /* PFXI 64XG3 */ |
| 5121 | SWITCHTEC_QUIRK(0x8575); /* PFXI 80XG3 */ | 5140 | SWITCHTEC_QUIRK(0x8575); /* PFXI 80XG3 */ |
| 5122 | SWITCHTEC_QUIRK(0x8576); /* PFXI 96XG3 */ | 5141 | SWITCHTEC_QUIRK(0x8576); /* PFXI 96XG3 */ |
| 5142 | |||
| 5143 | /* | ||
| 5144 | * On Lenovo Thinkpad P50 SKUs with a Nvidia Quadro M1000M, the BIOS does | ||
| 5145 | * not always reset the secondary Nvidia GPU between reboots if the system | ||
| 5146 | * is configured to use Hybrid Graphics mode. This results in the GPU | ||
| 5147 | * being left in whatever state it was in during the *previous* boot, which | ||
| 5148 | * causes spurious interrupts from the GPU, which in turn causes us to | ||
| 5149 | * disable the wrong IRQ and end up breaking the touchpad. Unsurprisingly, | ||
| 5150 | * this also completely breaks nouveau. | ||
| 5151 | * | ||
| 5152 | * Luckily, it seems a simple reset of the Nvidia GPU brings it back to a | ||
| 5153 | * clean state and fixes all these issues. | ||
| 5154 | * | ||
| 5155 | * When the machine is configured in Dedicated display mode, the issue | ||
| 5156 | * doesn't occur. Fortunately the GPU advertises NoReset+ when in this | ||
| 5157 | * mode, so we can detect that and avoid resetting it. | ||
| 5158 | */ | ||
| 5159 | static void quirk_reset_lenovo_thinkpad_p50_nvgpu(struct pci_dev *pdev) | ||
| 5160 | { | ||
| 5161 | void __iomem *map; | ||
| 5162 | int ret; | ||
| 5163 | |||
| 5164 | if (pdev->subsystem_vendor != PCI_VENDOR_ID_LENOVO || | ||
| 5165 | pdev->subsystem_device != 0x222e || | ||
| 5166 | !pdev->reset_fn) | ||
| 5167 | return; | ||
| 5168 | |||
| 5169 | if (pci_enable_device_mem(pdev)) | ||
| 5170 | return; | ||
| 5171 | |||
| 5172 | /* | ||
| 5173 | * Based on nvkm_device_ctor() in | ||
| 5174 | * drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | ||
| 5175 | */ | ||
| 5176 | map = pci_iomap(pdev, 0, 0x23000); | ||
| 5177 | if (!map) { | ||
| 5178 | pci_err(pdev, "Can't map MMIO space\n"); | ||
| 5179 | goto out_disable; | ||
| 5180 | } | ||
| 5181 | |||
| 5182 | /* | ||
| 5183 | * Make sure the GPU looks like it's been POSTed before resetting | ||
| 5184 | * it. | ||
| 5185 | */ | ||
| 5186 | if (ioread32(map + 0x2240c) & 0x2) { | ||
| 5187 | pci_info(pdev, FW_BUG "GPU left initialized by EFI, resetting\n"); | ||
| 5188 | ret = pci_reset_function(pdev); | ||
| 5189 | if (ret < 0) | ||
| 5190 | pci_err(pdev, "Failed to reset GPU: %d\n", ret); | ||
| 5191 | } | ||
| 5192 | |||
| 5193 | iounmap(map); | ||
| 5194 | out_disable: | ||
| 5195 | pci_disable_device(pdev); | ||
| 5196 | } | ||
| 5197 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, 0x13b1, | ||
| 5198 | PCI_CLASS_DISPLAY_VGA, 8, | ||
| 5199 | quirk_reset_lenovo_thinkpad_p50_nvgpu); | ||
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 2b5f720862d3..5c7922612733 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
| @@ -33,7 +33,7 @@ int pci_for_each_dma_alias(struct pci_dev *pdev, | |||
| 33 | struct pci_bus *bus; | 33 | struct pci_bus *bus; |
| 34 | int ret; | 34 | int ret; |
| 35 | 35 | ||
| 36 | ret = fn(pdev, PCI_DEVID(pdev->bus->number, pdev->devfn), data); | 36 | ret = fn(pdev, pci_dev_id(pdev), data); |
| 37 | if (ret) | 37 | if (ret) |
| 38 | return ret; | 38 | return ret; |
| 39 | 39 | ||
| @@ -88,9 +88,7 @@ int pci_for_each_dma_alias(struct pci_dev *pdev, | |||
| 88 | return ret; | 88 | return ret; |
| 89 | continue; | 89 | continue; |
| 90 | case PCI_EXP_TYPE_PCIE_BRIDGE: | 90 | case PCI_EXP_TYPE_PCIE_BRIDGE: |
| 91 | ret = fn(tmp, | 91 | ret = fn(tmp, pci_dev_id(tmp), data); |
| 92 | PCI_DEVID(tmp->bus->number, | ||
| 93 | tmp->devfn), data); | ||
| 94 | if (ret) | 92 | if (ret) |
| 95 | return ret; | 93 | return ret; |
| 96 | continue; | 94 | continue; |
| @@ -101,9 +99,7 @@ int pci_for_each_dma_alias(struct pci_dev *pdev, | |||
| 101 | PCI_DEVID(tmp->subordinate->number, | 99 | PCI_DEVID(tmp->subordinate->number, |
| 102 | PCI_DEVFN(0, 0)), data); | 100 | PCI_DEVFN(0, 0)), data); |
| 103 | else | 101 | else |
| 104 | ret = fn(tmp, | 102 | ret = fn(tmp, pci_dev_id(tmp), data); |
| 105 | PCI_DEVID(tmp->bus->number, | ||
| 106 | tmp->devfn), data); | ||
| 107 | if (ret) | 103 | if (ret) |
| 108 | return ret; | 104 | return ret; |
| 109 | } | 105 | } |
diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c index e22766c79fe9..30f6e080bad8 100644 --- a/drivers/pci/switch/switchtec.c +++ b/drivers/pci/switch/switchtec.c | |||
| @@ -658,19 +658,25 @@ static int ioctl_flash_part_info(struct switchtec_dev *stdev, | |||
| 658 | 658 | ||
| 659 | static int ioctl_event_summary(struct switchtec_dev *stdev, | 659 | static int ioctl_event_summary(struct switchtec_dev *stdev, |
| 660 | struct switchtec_user *stuser, | 660 | struct switchtec_user *stuser, |
| 661 | struct switchtec_ioctl_event_summary __user *usum) | 661 | struct switchtec_ioctl_event_summary __user *usum, |
| 662 | size_t size) | ||
| 662 | { | 663 | { |
| 663 | struct switchtec_ioctl_event_summary s = {0}; | 664 | struct switchtec_ioctl_event_summary *s; |
| 664 | int i; | 665 | int i; |
| 665 | u32 reg; | 666 | u32 reg; |
| 667 | int ret = 0; | ||
| 666 | 668 | ||
| 667 | s.global = ioread32(&stdev->mmio_sw_event->global_summary); | 669 | s = kzalloc(sizeof(*s), GFP_KERNEL); |
| 668 | s.part_bitmap = ioread32(&stdev->mmio_sw_event->part_event_bitmap); | 670 | if (!s) |
| 669 | s.local_part = ioread32(&stdev->mmio_part_cfg->part_event_summary); | 671 | return -ENOMEM; |
| 672 | |||
| 673 | s->global = ioread32(&stdev->mmio_sw_event->global_summary); | ||
| 674 | s->part_bitmap = ioread32(&stdev->mmio_sw_event->part_event_bitmap); | ||
| 675 | s->local_part = ioread32(&stdev->mmio_part_cfg->part_event_summary); | ||
| 670 | 676 | ||
| 671 | for (i = 0; i < stdev->partition_count; i++) { | 677 | for (i = 0; i < stdev->partition_count; i++) { |
| 672 | reg = ioread32(&stdev->mmio_part_cfg_all[i].part_event_summary); | 678 | reg = ioread32(&stdev->mmio_part_cfg_all[i].part_event_summary); |
| 673 | s.part[i] = reg; | 679 | s->part[i] = reg; |
| 674 | } | 680 | } |
| 675 | 681 | ||
| 676 | for (i = 0; i < SWITCHTEC_MAX_PFF_CSR; i++) { | 682 | for (i = 0; i < SWITCHTEC_MAX_PFF_CSR; i++) { |
| @@ -679,15 +685,19 @@ static int ioctl_event_summary(struct switchtec_dev *stdev, | |||
| 679 | break; | 685 | break; |
| 680 | 686 | ||
| 681 | reg = ioread32(&stdev->mmio_pff_csr[i].pff_event_summary); | 687 | reg = ioread32(&stdev->mmio_pff_csr[i].pff_event_summary); |
| 682 | s.pff[i] = reg; | 688 | s->pff[i] = reg; |
| 683 | } | 689 | } |
| 684 | 690 | ||
| 685 | if (copy_to_user(usum, &s, sizeof(s))) | 691 | if (copy_to_user(usum, s, size)) { |
| 686 | return -EFAULT; | 692 | ret = -EFAULT; |
| 693 | goto error_case; | ||
| 694 | } | ||
| 687 | 695 | ||
| 688 | stuser->event_cnt = atomic_read(&stdev->event_cnt); | 696 | stuser->event_cnt = atomic_read(&stdev->event_cnt); |
| 689 | 697 | ||
| 690 | return 0; | 698 | error_case: |
| 699 | kfree(s); | ||
| 700 | return ret; | ||
| 691 | } | 701 | } |
| 692 | 702 | ||
| 693 | static u32 __iomem *global_ev_reg(struct switchtec_dev *stdev, | 703 | static u32 __iomem *global_ev_reg(struct switchtec_dev *stdev, |
| @@ -977,8 +987,9 @@ static long switchtec_dev_ioctl(struct file *filp, unsigned int cmd, | |||
| 977 | case SWITCHTEC_IOCTL_FLASH_PART_INFO: | 987 | case SWITCHTEC_IOCTL_FLASH_PART_INFO: |
| 978 | rc = ioctl_flash_part_info(stdev, argp); | 988 | rc = ioctl_flash_part_info(stdev, argp); |
| 979 | break; | 989 | break; |
| 980 | case SWITCHTEC_IOCTL_EVENT_SUMMARY: | 990 | case SWITCHTEC_IOCTL_EVENT_SUMMARY_LEGACY: |
| 981 | rc = ioctl_event_summary(stdev, stuser, argp); | 991 | rc = ioctl_event_summary(stdev, stuser, argp, |
| 992 | sizeof(struct switchtec_ioctl_event_summary_legacy)); | ||
| 982 | break; | 993 | break; |
| 983 | case SWITCHTEC_IOCTL_EVENT_CTL: | 994 | case SWITCHTEC_IOCTL_EVENT_CTL: |
| 984 | rc = ioctl_event_ctl(stdev, argp); | 995 | rc = ioctl_event_ctl(stdev, argp); |
| @@ -989,6 +1000,10 @@ static long switchtec_dev_ioctl(struct file *filp, unsigned int cmd, | |||
| 989 | case SWITCHTEC_IOCTL_PORT_TO_PFF: | 1000 | case SWITCHTEC_IOCTL_PORT_TO_PFF: |
| 990 | rc = ioctl_port_to_pff(stdev, argp); | 1001 | rc = ioctl_port_to_pff(stdev, argp); |
| 991 | break; | 1002 | break; |
| 1003 | case SWITCHTEC_IOCTL_EVENT_SUMMARY: | ||
| 1004 | rc = ioctl_event_summary(stdev, stuser, argp, | ||
| 1005 | sizeof(struct switchtec_ioctl_event_summary)); | ||
| 1006 | break; | ||
| 992 | default: | 1007 | default: |
| 993 | rc = -ENOTTY; | 1008 | rc = -ENOTTY; |
| 994 | break; | 1009 | break; |
| @@ -1162,7 +1177,8 @@ static int mask_event(struct switchtec_dev *stdev, int eid, int idx) | |||
| 1162 | if (!(hdr & SWITCHTEC_EVENT_OCCURRED && hdr & SWITCHTEC_EVENT_EN_IRQ)) | 1177 | if (!(hdr & SWITCHTEC_EVENT_OCCURRED && hdr & SWITCHTEC_EVENT_EN_IRQ)) |
| 1163 | return 0; | 1178 | return 0; |
| 1164 | 1179 | ||
| 1165 | if (eid == SWITCHTEC_IOCTL_EVENT_LINK_STATE) | 1180 | if (eid == SWITCHTEC_IOCTL_EVENT_LINK_STATE || |
| 1181 | eid == SWITCHTEC_IOCTL_EVENT_MRPC_COMP) | ||
| 1166 | return 0; | 1182 | return 0; |
| 1167 | 1183 | ||
| 1168 | dev_dbg(&stdev->dev, "%s: %d %d %x\n", __func__, eid, idx, hdr); | 1184 | dev_dbg(&stdev->dev, "%s: %d %d %x\n", __func__, eid, idx, hdr); |
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index eba6e33147a2..14cf0f41ecf0 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c | |||
| @@ -1104,7 +1104,7 @@ static void __ref pcifront_backend_changed(struct xenbus_device *xdev, | |||
| 1104 | case XenbusStateClosed: | 1104 | case XenbusStateClosed: |
| 1105 | if (xdev->state == XenbusStateClosed) | 1105 | if (xdev->state == XenbusStateClosed) |
| 1106 | break; | 1106 | break; |
| 1107 | /* Missed the backend's CLOSING state -- fallthrough */ | 1107 | /* fall through - Missed the backend's CLOSING state. */ |
| 1108 | case XenbusStateClosing: | 1108 | case XenbusStateClosing: |
| 1109 | dev_warn(&xdev->dev, "backend going away!\n"); | 1109 | dev_warn(&xdev->dev, "backend going away!\n"); |
| 1110 | pcifront_try_disconnect(pdev); | 1110 | pcifront_try_disconnect(pdev); |
diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c index 24326eecd787..7abbb6167766 100644 --- a/drivers/platform/chrome/chromeos_laptop.c +++ b/drivers/platform/chrome/chromeos_laptop.c | |||
| @@ -125,7 +125,7 @@ static bool chromeos_laptop_match_adapter_devid(struct device *dev, u32 devid) | |||
| 125 | return false; | 125 | return false; |
| 126 | 126 | ||
| 127 | pdev = to_pci_dev(dev); | 127 | pdev = to_pci_dev(dev); |
| 128 | return devid == PCI_DEVID(pdev->bus->number, pdev->devfn); | 128 | return devid == pci_dev_id(pdev); |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | static void chromeos_laptop_check_adapter(struct i2c_adapter *adapter) | 131 | static void chromeos_laptop_check_adapter(struct i2c_adapter *adapter) |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index d5dcebd7aad3..b84bcd705fe1 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
| @@ -513,7 +513,8 @@ extern bool osc_pc_lpi_support_confirmed; | |||
| 513 | #define OSC_PCI_CLOCK_PM_SUPPORT 0x00000004 | 513 | #define OSC_PCI_CLOCK_PM_SUPPORT 0x00000004 |
| 514 | #define OSC_PCI_SEGMENT_GROUPS_SUPPORT 0x00000008 | 514 | #define OSC_PCI_SEGMENT_GROUPS_SUPPORT 0x00000008 |
| 515 | #define OSC_PCI_MSI_SUPPORT 0x00000010 | 515 | #define OSC_PCI_MSI_SUPPORT 0x00000010 |
| 516 | #define OSC_PCI_SUPPORT_MASKS 0x0000001f | 516 | #define OSC_PCI_HPX_TYPE_3_SUPPORT 0x00000100 |
| 517 | #define OSC_PCI_SUPPORT_MASKS 0x0000011f | ||
| 517 | 518 | ||
| 518 | /* PCI Host Bridge _OSC: Capabilities DWORD 3: Control Field */ | 519 | /* PCI Host Bridge _OSC: Capabilities DWORD 3: Control Field */ |
| 519 | #define OSC_PCI_EXPRESS_NATIVE_HP_CONTROL 0x00000001 | 520 | #define OSC_PCI_EXPRESS_NATIVE_HP_CONTROL 0x00000001 |
diff --git a/include/linux/msi.h b/include/linux/msi.h index 7e9b81c3b50d..052f04fcf953 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h | |||
| @@ -148,24 +148,6 @@ u32 __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag); | |||
| 148 | void pci_msi_mask_irq(struct irq_data *data); | 148 | void pci_msi_mask_irq(struct irq_data *data); |
| 149 | void pci_msi_unmask_irq(struct irq_data *data); | 149 | void pci_msi_unmask_irq(struct irq_data *data); |
| 150 | 150 | ||
| 151 | /* Conversion helpers. Should be removed after merging */ | ||
| 152 | static inline void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) | ||
| 153 | { | ||
| 154 | __pci_write_msi_msg(entry, msg); | ||
| 155 | } | ||
| 156 | static inline void write_msi_msg(int irq, struct msi_msg *msg) | ||
| 157 | { | ||
| 158 | pci_write_msi_msg(irq, msg); | ||
| 159 | } | ||
| 160 | static inline void mask_msi_irq(struct irq_data *data) | ||
| 161 | { | ||
| 162 | pci_msi_mask_irq(data); | ||
| 163 | } | ||
| 164 | static inline void unmask_msi_irq(struct irq_data *data) | ||
| 165 | { | ||
| 166 | pci_msi_unmask_irq(data); | ||
| 167 | } | ||
| 168 | |||
| 169 | /* | 151 | /* |
| 170 | * The arch hooks to setup up msi irqs. Those functions are | 152 | * The arch hooks to setup up msi irqs. Those functions are |
| 171 | * implemented as weak symbols so that they /can/ be overriden by | 153 | * implemented as weak symbols so that they /can/ be overriden by |
diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h index 29efa09d686b..a73164c85e78 100644 --- a/include/linux/pci-ecam.h +++ b/include/linux/pci-ecam.h | |||
| @@ -56,6 +56,7 @@ extern struct pci_ecam_ops thunder_pem_ecam_ops; /* Cavium ThunderX 1.x & 2.x */ | |||
| 56 | extern struct pci_ecam_ops pci_thunder_ecam_ops; /* Cavium ThunderX 1.x */ | 56 | extern struct pci_ecam_ops pci_thunder_ecam_ops; /* Cavium ThunderX 1.x */ |
| 57 | extern struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 */ | 57 | extern struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 */ |
| 58 | extern struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */ | 58 | extern struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */ |
| 59 | extern struct pci_ecam_ops al_pcie_ops; /* Amazon Annapurna Labs PCIe */ | ||
| 59 | #endif | 60 | #endif |
| 60 | 61 | ||
| 61 | #ifdef CONFIG_PCI_HOST_COMMON | 62 | #ifdef CONFIG_PCI_HOST_COMMON |
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h index c3ffa3917f88..f641badc2c61 100644 --- a/include/linux/pci-epc.h +++ b/include/linux/pci-epc.h | |||
| @@ -109,6 +109,7 @@ struct pci_epc { | |||
| 109 | * @reserved_bar: bitmap to indicate reserved BAR unavailable to function driver | 109 | * @reserved_bar: bitmap to indicate reserved BAR unavailable to function driver |
| 110 | * @bar_fixed_64bit: bitmap to indicate fixed 64bit BARs | 110 | * @bar_fixed_64bit: bitmap to indicate fixed 64bit BARs |
| 111 | * @bar_fixed_size: Array specifying the size supported by each BAR | 111 | * @bar_fixed_size: Array specifying the size supported by each BAR |
| 112 | * @align: alignment size required for BAR buffer allocation | ||
| 112 | */ | 113 | */ |
| 113 | struct pci_epc_features { | 114 | struct pci_epc_features { |
| 114 | unsigned int linkup_notifier : 1; | 115 | unsigned int linkup_notifier : 1; |
| @@ -117,6 +118,7 @@ struct pci_epc_features { | |||
| 117 | u8 reserved_bar; | 118 | u8 reserved_bar; |
| 118 | u8 bar_fixed_64bit; | 119 | u8 bar_fixed_64bit; |
| 119 | u64 bar_fixed_size[BAR_5 + 1]; | 120 | u64 bar_fixed_size[BAR_5 + 1]; |
| 121 | size_t align; | ||
| 120 | }; | 122 | }; |
| 121 | 123 | ||
| 122 | #define to_pci_epc(device) container_of((device), struct pci_epc, dev) | 124 | #define to_pci_epc(device) container_of((device), struct pci_epc, dev) |
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h index ec02f58758c8..2d6f07556682 100644 --- a/include/linux/pci-epf.h +++ b/include/linux/pci-epf.h | |||
| @@ -149,7 +149,8 @@ void pci_epf_destroy(struct pci_epf *epf); | |||
| 149 | int __pci_epf_register_driver(struct pci_epf_driver *driver, | 149 | int __pci_epf_register_driver(struct pci_epf_driver *driver, |
| 150 | struct module *owner); | 150 | struct module *owner); |
| 151 | void pci_epf_unregister_driver(struct pci_epf_driver *driver); | 151 | void pci_epf_unregister_driver(struct pci_epf_driver *driver); |
| 152 | void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar); | 152 | void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar, |
| 153 | size_t align); | ||
| 153 | void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar); | 154 | void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar); |
| 154 | int pci_epf_bind(struct pci_epf *epf); | 155 | int pci_epf_bind(struct pci_epf *epf); |
| 155 | void pci_epf_unbind(struct pci_epf *epf); | 156 | void pci_epf_unbind(struct pci_epf *epf); |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 77448215ef5b..6fc361a69e0c 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
| @@ -348,6 +348,8 @@ struct pci_dev { | |||
| 348 | unsigned int hotplug_user_indicators:1; /* SlotCtl indicators | 348 | unsigned int hotplug_user_indicators:1; /* SlotCtl indicators |
| 349 | controlled exclusively by | 349 | controlled exclusively by |
| 350 | user sysfs */ | 350 | user sysfs */ |
| 351 | unsigned int clear_retrain_link:1; /* Need to clear Retrain Link | ||
| 352 | bit manually */ | ||
| 351 | unsigned int d3_delay; /* D3->D0 transition time in ms */ | 353 | unsigned int d3_delay; /* D3->D0 transition time in ms */ |
| 352 | unsigned int d3cold_delay; /* D3cold->D0 transition time in ms */ | 354 | unsigned int d3cold_delay; /* D3cold->D0 transition time in ms */ |
| 353 | 355 | ||
| @@ -596,6 +598,11 @@ struct pci_bus { | |||
| 596 | 598 | ||
| 597 | #define to_pci_bus(n) container_of(n, struct pci_bus, dev) | 599 | #define to_pci_bus(n) container_of(n, struct pci_bus, dev) |
| 598 | 600 | ||
| 601 | static inline u16 pci_dev_id(struct pci_dev *dev) | ||
| 602 | { | ||
| 603 | return PCI_DEVID(dev->bus->number, dev->devfn); | ||
| 604 | } | ||
| 605 | |||
| 599 | /* | 606 | /* |
| 600 | * Returns true if the PCI bus is root (behind host-PCI bridge), | 607 | * Returns true if the PCI bus is root (behind host-PCI bridge), |
| 601 | * false otherwise | 608 | * false otherwise |
| @@ -1233,7 +1240,6 @@ int __must_check pci_request_regions(struct pci_dev *, const char *); | |||
| 1233 | int __must_check pci_request_regions_exclusive(struct pci_dev *, const char *); | 1240 | int __must_check pci_request_regions_exclusive(struct pci_dev *, const char *); |
| 1234 | void pci_release_regions(struct pci_dev *); | 1241 | void pci_release_regions(struct pci_dev *); |
| 1235 | int __must_check pci_request_region(struct pci_dev *, int, const char *); | 1242 | int __must_check pci_request_region(struct pci_dev *, int, const char *); |
| 1236 | int __must_check pci_request_region_exclusive(struct pci_dev *, int, const char *); | ||
| 1237 | void pci_release_region(struct pci_dev *, int); | 1243 | void pci_release_region(struct pci_dev *, int); |
| 1238 | int pci_request_selected_regions(struct pci_dev *, int, const char *); | 1244 | int pci_request_selected_regions(struct pci_dev *, int, const char *); |
| 1239 | int pci_request_selected_regions_exclusive(struct pci_dev *, int, const char *); | 1245 | int pci_request_selected_regions_exclusive(struct pci_dev *, int, const char *); |
diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index 7acc9f91e72b..f694eb2ca978 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h | |||
| @@ -124,26 +124,72 @@ struct hpp_type2 { | |||
| 124 | u32 sec_unc_err_mask_or; | 124 | u32 sec_unc_err_mask_or; |
| 125 | }; | 125 | }; |
| 126 | 126 | ||
| 127 | struct hotplug_params { | 127 | /* |
| 128 | struct hpp_type0 *t0; /* Type0: NULL if not available */ | 128 | * _HPX PCI Express Setting Record (Type 3) |
| 129 | struct hpp_type1 *t1; /* Type1: NULL if not available */ | 129 | */ |
| 130 | struct hpp_type2 *t2; /* Type2: NULL if not available */ | 130 | struct hpx_type3 { |
| 131 | struct hpp_type0 type0_data; | 131 | u16 device_type; |
| 132 | struct hpp_type1 type1_data; | 132 | u16 function_type; |
| 133 | struct hpp_type2 type2_data; | 133 | u16 config_space_location; |
| 134 | u16 pci_exp_cap_id; | ||
| 135 | u16 pci_exp_cap_ver; | ||
| 136 | u16 pci_exp_vendor_id; | ||
| 137 | u16 dvsec_id; | ||
| 138 | u16 dvsec_rev; | ||
| 139 | u16 match_offset; | ||
| 140 | u32 match_mask_and; | ||
| 141 | u32 match_value; | ||
| 142 | u16 reg_offset; | ||
| 143 | u32 reg_mask_and; | ||
| 144 | u32 reg_mask_or; | ||
| 145 | }; | ||
| 146 | |||
| 147 | struct hotplug_program_ops { | ||
| 148 | void (*program_type0)(struct pci_dev *dev, struct hpp_type0 *hpp); | ||
| 149 | void (*program_type1)(struct pci_dev *dev, struct hpp_type1 *hpp); | ||
| 150 | void (*program_type2)(struct pci_dev *dev, struct hpp_type2 *hpp); | ||
| 151 | void (*program_type3)(struct pci_dev *dev, struct hpx_type3 *hpp); | ||
| 152 | }; | ||
| 153 | |||
| 154 | enum hpx_type3_dev_type { | ||
| 155 | HPX_TYPE_ENDPOINT = BIT(0), | ||
| 156 | HPX_TYPE_LEG_END = BIT(1), | ||
| 157 | HPX_TYPE_RC_END = BIT(2), | ||
| 158 | HPX_TYPE_RC_EC = BIT(3), | ||
| 159 | HPX_TYPE_ROOT_PORT = BIT(4), | ||
| 160 | HPX_TYPE_UPSTREAM = BIT(5), | ||
| 161 | HPX_TYPE_DOWNSTREAM = BIT(6), | ||
| 162 | HPX_TYPE_PCI_BRIDGE = BIT(7), | ||
| 163 | HPX_TYPE_PCIE_BRIDGE = BIT(8), | ||
| 164 | }; | ||
| 165 | |||
| 166 | enum hpx_type3_fn_type { | ||
| 167 | HPX_FN_NORMAL = BIT(0), | ||
| 168 | HPX_FN_SRIOV_PHYS = BIT(1), | ||
| 169 | HPX_FN_SRIOV_VIRT = BIT(2), | ||
| 170 | }; | ||
| 171 | |||
| 172 | enum hpx_type3_cfg_loc { | ||
| 173 | HPX_CFG_PCICFG = 0, | ||
| 174 | HPX_CFG_PCIE_CAP = 1, | ||
| 175 | HPX_CFG_PCIE_CAP_EXT = 2, | ||
| 176 | HPX_CFG_VEND_CAP = 3, | ||
| 177 | HPX_CFG_DVSEC = 4, | ||
| 178 | HPX_CFG_MAX, | ||
| 134 | }; | 179 | }; |
| 135 | 180 | ||
| 136 | #ifdef CONFIG_ACPI | 181 | #ifdef CONFIG_ACPI |
| 137 | #include <linux/acpi.h> | 182 | #include <linux/acpi.h> |
| 138 | int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp); | 183 | int pci_acpi_program_hp_params(struct pci_dev *dev, |
| 184 | const struct hotplug_program_ops *hp_ops); | ||
| 139 | bool pciehp_is_native(struct pci_dev *bridge); | 185 | bool pciehp_is_native(struct pci_dev *bridge); |
| 140 | int acpi_get_hp_hw_control_from_firmware(struct pci_dev *bridge); | 186 | int acpi_get_hp_hw_control_from_firmware(struct pci_dev *bridge); |
| 141 | bool shpchp_is_native(struct pci_dev *bridge); | 187 | bool shpchp_is_native(struct pci_dev *bridge); |
| 142 | int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle); | 188 | int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle); |
| 143 | int acpi_pci_detect_ejectable(acpi_handle handle); | 189 | int acpi_pci_detect_ejectable(acpi_handle handle); |
| 144 | #else | 190 | #else |
| 145 | static inline int pci_get_hp_params(struct pci_dev *dev, | 191 | static inline int pci_acpi_program_hp_params(struct pci_dev *dev, |
| 146 | struct hotplug_params *hpp) | 192 | const struct hotplug_program_ops *hp_ops) |
| 147 | { | 193 | { |
| 148 | return -ENODEV; | 194 | return -ENODEV; |
| 149 | } | 195 | } |
diff --git a/include/linux/switchtec.h b/include/linux/switchtec.h index 52a079b3a9a6..0cfc34ac37fb 100644 --- a/include/linux/switchtec.h +++ b/include/linux/switchtec.h | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | #include <linux/cdev.h> | 20 | #include <linux/cdev.h> |
| 21 | 21 | ||
| 22 | #define SWITCHTEC_MRPC_PAYLOAD_SIZE 1024 | 22 | #define SWITCHTEC_MRPC_PAYLOAD_SIZE 1024 |
| 23 | #define SWITCHTEC_MAX_PFF_CSR 48 | 23 | #define SWITCHTEC_MAX_PFF_CSR 255 |
| 24 | 24 | ||
| 25 | #define SWITCHTEC_EVENT_OCCURRED BIT(0) | 25 | #define SWITCHTEC_EVENT_OCCURRED BIT(0) |
| 26 | #define SWITCHTEC_EVENT_CLEAR BIT(0) | 26 | #define SWITCHTEC_EVENT_CLEAR BIT(0) |
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index 5c98133f2c94..c51e0066de8b 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h | |||
| @@ -372,6 +372,12 @@ | |||
| 372 | #define PCI_EA_FIRST_ENT_BRIDGE 8 /* First EA Entry for Bridges */ | 372 | #define PCI_EA_FIRST_ENT_BRIDGE 8 /* First EA Entry for Bridges */ |
| 373 | #define PCI_EA_ES 0x00000007 /* Entry Size */ | 373 | #define PCI_EA_ES 0x00000007 /* Entry Size */ |
| 374 | #define PCI_EA_BEI 0x000000f0 /* BAR Equivalent Indicator */ | 374 | #define PCI_EA_BEI 0x000000f0 /* BAR Equivalent Indicator */ |
| 375 | |||
| 376 | /* EA fixed Secondary and Subordinate bus numbers for Bridge */ | ||
| 377 | #define PCI_EA_SEC_BUS_MASK 0xff | ||
| 378 | #define PCI_EA_SUB_BUS_MASK 0xff00 | ||
| 379 | #define PCI_EA_SUB_BUS_SHIFT 8 | ||
| 380 | |||
| 375 | /* 0-5 map to BARs 0-5 respectively */ | 381 | /* 0-5 map to BARs 0-5 respectively */ |
| 376 | #define PCI_EA_BEI_BAR0 0 | 382 | #define PCI_EA_BEI_BAR0 0 |
| 377 | #define PCI_EA_BEI_BAR5 5 | 383 | #define PCI_EA_BEI_BAR5 5 |
diff --git a/include/uapi/linux/switchtec_ioctl.h b/include/uapi/linux/switchtec_ioctl.h index 4f4daf8db954..c912b5a678e4 100644 --- a/include/uapi/linux/switchtec_ioctl.h +++ b/include/uapi/linux/switchtec_ioctl.h | |||
| @@ -50,7 +50,7 @@ struct switchtec_ioctl_flash_part_info { | |||
| 50 | __u32 active; | 50 | __u32 active; |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | struct switchtec_ioctl_event_summary { | 53 | struct switchtec_ioctl_event_summary_legacy { |
| 54 | __u64 global; | 54 | __u64 global; |
| 55 | __u64 part_bitmap; | 55 | __u64 part_bitmap; |
| 56 | __u32 local_part; | 56 | __u32 local_part; |
| @@ -59,6 +59,15 @@ struct switchtec_ioctl_event_summary { | |||
| 59 | __u32 pff[48]; | 59 | __u32 pff[48]; |
| 60 | }; | 60 | }; |
| 61 | 61 | ||
| 62 | struct switchtec_ioctl_event_summary { | ||
| 63 | __u64 global; | ||
| 64 | __u64 part_bitmap; | ||
| 65 | __u32 local_part; | ||
| 66 | __u32 padding; | ||
| 67 | __u32 part[48]; | ||
| 68 | __u32 pff[255]; | ||
| 69 | }; | ||
| 70 | |||
| 62 | #define SWITCHTEC_IOCTL_EVENT_STACK_ERROR 0 | 71 | #define SWITCHTEC_IOCTL_EVENT_STACK_ERROR 0 |
| 63 | #define SWITCHTEC_IOCTL_EVENT_PPU_ERROR 1 | 72 | #define SWITCHTEC_IOCTL_EVENT_PPU_ERROR 1 |
| 64 | #define SWITCHTEC_IOCTL_EVENT_ISP_ERROR 2 | 73 | #define SWITCHTEC_IOCTL_EVENT_ISP_ERROR 2 |
| @@ -127,6 +136,8 @@ struct switchtec_ioctl_pff_port { | |||
| 127 | _IOWR('W', 0x41, struct switchtec_ioctl_flash_part_info) | 136 | _IOWR('W', 0x41, struct switchtec_ioctl_flash_part_info) |
| 128 | #define SWITCHTEC_IOCTL_EVENT_SUMMARY \ | 137 | #define SWITCHTEC_IOCTL_EVENT_SUMMARY \ |
| 129 | _IOR('W', 0x42, struct switchtec_ioctl_event_summary) | 138 | _IOR('W', 0x42, struct switchtec_ioctl_event_summary) |
| 139 | #define SWITCHTEC_IOCTL_EVENT_SUMMARY_LEGACY \ | ||
| 140 | _IOR('W', 0x42, struct switchtec_ioctl_event_summary_legacy) | ||
| 130 | #define SWITCHTEC_IOCTL_EVENT_CTL \ | 141 | #define SWITCHTEC_IOCTL_EVENT_CTL \ |
| 131 | _IOWR('W', 0x43, struct switchtec_ioctl_event_ctl) | 142 | _IOWR('W', 0x43, struct switchtec_ioctl_event_ctl) |
| 132 | #define SWITCHTEC_IOCTL_PFF_TO_PORT \ | 143 | #define SWITCHTEC_IOCTL_PFF_TO_PORT \ |
