diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2024-05-02 09:35:41 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2024-05-02 09:35:41 +1000 |
commit | c0c7d74b5e0e8fb3540f2eae3366367e4e2db461 (patch) | |
tree | ba333b76e186f4c9c6babe6c297d614133392ef8 | |
parent | 859f5eef06d1e1021295186dc3e94ddb76561773 (diff) | |
parent | ccd0bdb57e31798f43ac30bce7805197bcfcd3dd (diff) | |
download | linux-next-c0c7d74b5e0e8fb3540f2eae3366367e4e2db461.tar.gz |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git
Notice: this object is not reachable from any branch.
Notice: this object is not reachable from any branch.
82 files changed, 514 insertions, 470 deletions
diff --git a/Documentation/PCI/msi-howto.rst b/Documentation/PCI/msi-howto.rst index 783d30b7bb428a..0692c9aec66fd4 100644 --- a/Documentation/PCI/msi-howto.rst +++ b/Documentation/PCI/msi-howto.rst @@ -103,7 +103,7 @@ min_vecs argument set to this limit, and the PCI core will return -ENOSPC if it can't meet the minimum number of vectors. The flags argument is used to specify which type of interrupt can be used -by the device and the driver (PCI_IRQ_LEGACY, PCI_IRQ_MSI, PCI_IRQ_MSIX). +by the device and the driver (PCI_IRQ_INTX, PCI_IRQ_MSI, PCI_IRQ_MSIX). A convenient short-hand (PCI_IRQ_ALL_TYPES) is also available to ask for any possible kind of interrupt. If the PCI_IRQ_AFFINITY flag is set, pci_alloc_irq_vectors() will spread the interrupts around the available CPUs. diff --git a/Documentation/PCI/pci.rst b/Documentation/PCI/pci.rst index cced568d78e9a1..dd7b1c0c21da02 100644 --- a/Documentation/PCI/pci.rst +++ b/Documentation/PCI/pci.rst @@ -335,7 +335,7 @@ causes the PCI support to program CPU vector data into the PCI device capability registers. Many architectures, chip-sets, or BIOSes do NOT support MSI or MSI-X and a call to pci_alloc_irq_vectors with just the PCI_IRQ_MSI and PCI_IRQ_MSIX flags will fail, so try to always -specify PCI_IRQ_LEGACY as well. +specify PCI_IRQ_INTX as well. Drivers that have different interrupt handlers for MSI/MSI-X and legacy INTx should chose the right one based on the msi_enabled diff --git a/Documentation/PCI/pcieaer-howto.rst b/Documentation/PCI/pcieaer-howto.rst index e00d63971695ed..f013f3b27c8274 100644 --- a/Documentation/PCI/pcieaer-howto.rst +++ b/Documentation/PCI/pcieaer-howto.rst @@ -241,7 +241,7 @@ After reboot with new kernel or insert the module, a device file named Then, you need a user space tool named aer-inject, which can be gotten from: - https://git.kernel.org/cgit/linux/kernel/git/gong.chen/aer-inject.git/ + https://github.com/intel/aer-inject.git More information about aer-inject can be found in the document in its source code. diff --git a/Documentation/devicetree/bindings/pci/rcar-pci-host.yaml b/Documentation/devicetree/bindings/pci/rcar-pci-host.yaml index b6a7cb32f61e5d..835b6db00c2796 100644 --- a/Documentation/devicetree/bindings/pci/rcar-pci-host.yaml +++ b/Documentation/devicetree/bindings/pci/rcar-pci-host.yaml @@ -77,6 +77,9 @@ properties: vpcie12v-supply: description: The 12v regulator to use for PCIe. + iommu-map: true + iommu-map-mask: true + required: - compatible - reg diff --git a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml index b7a534cef24d31..15a2658ceeeff2 100644 --- a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml +++ b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml @@ -23,6 +23,10 @@ properties: items: - const: ti,j7200-pcie-host - const: ti,j721e-pcie-host + - description: PCIe controller in J722S + items: + - const: ti,j722s-pcie-host + - const: ti,j721e-pcie-host reg: maxItems: 4 @@ -68,6 +72,7 @@ properties: - 0xb00d - 0xb00f - 0xb010 + - 0xb012 - 0xb013 msi-map: true diff --git a/Documentation/translations/zh_CN/PCI/msi-howto.rst b/Documentation/translations/zh_CN/PCI/msi-howto.rst index 1b9b5ea790d849..95baadf767e437 100644 --- a/Documentation/translations/zh_CN/PCI/msi-howto.rst +++ b/Documentation/translations/zh_CN/PCI/msi-howto.rst @@ -88,7 +88,7 @@ MSI功能。 如果设备对最小数量的向量有要求,驱动程序可以传递一个min_vecs参数,设置为这个限制, 如果PCI核不能满足最小数量的向量,将返回-ENOSPC。 -flags参数用来指定设备和驱动程序可以使用哪种类型的中断(PCI_IRQ_LEGACY, PCI_IRQ_MSI, +flags参数用来指定设备和驱动程序可以使用哪种类型的中断(PCI_IRQ_INTX, PCI_IRQ_MSI, PCI_IRQ_MSIX)。一个方便的短语(PCI_IRQ_ALL_TYPES)也可以用来要求任何可能的中断类型。 如果PCI_IRQ_AFFINITY标志被设置,pci_alloc_irq_vectors()将把中断分散到可用的CPU上。 diff --git a/Documentation/translations/zh_CN/PCI/pci.rst b/Documentation/translations/zh_CN/PCI/pci.rst index 83c2a41d38d30c..347f5c3f5ce99b 100644 --- a/Documentation/translations/zh_CN/PCI/pci.rst +++ b/Documentation/translations/zh_CN/PCI/pci.rst @@ -304,7 +304,7 @@ MSI-X可以分配几个单独的向量。 的PCI_IRQ_MSI和/或PCI_IRQ_MSIX标志来启用MSI功能。这将导致PCI支持将CPU向量数 据编程到PCI设备功能寄存器中。许多架构、芯片组或BIOS不支持MSI或MSI-X,调用 ``pci_alloc_irq_vectors`` 时只使用PCI_IRQ_MSI和PCI_IRQ_MSIX标志会失败, -所以尽量也要指定 ``PCI_IRQ_LEGACY`` 。 +所以尽量也要指定 ``PCI_IRQ_INTX`` 。 对MSI/MSI-X和传统INTx有不同中断处理程序的驱动程序应该在调用 ``pci_alloc_irq_vectors`` 后根据 ``pci_dev``结构体中的 ``msi_enabled`` diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c index d9651f15ae4f70..340769242deaec 100644 --- a/arch/x86/kernel/apic/msi.c +++ b/arch/x86/kernel/apic/msi.c @@ -184,7 +184,6 @@ static int x86_msi_prepare(struct irq_domain *domain, struct device *dev, alloc->type = X86_IRQ_ALLOC_TYPE_PCI_MSI; return 0; case DOMAIN_BUS_PCI_DEVICE_MSIX: - case DOMAIN_BUS_PCI_DEVICE_IMS: alloc->type = X86_IRQ_ALLOC_TYPE_PCI_MSIX; return 0; default: @@ -229,10 +228,6 @@ static bool x86_init_dev_msi_info(struct device *dev, struct irq_domain *domain, case DOMAIN_BUS_PCI_DEVICE_MSI: case DOMAIN_BUS_PCI_DEVICE_MSIX: break; - case DOMAIN_BUS_PCI_DEVICE_IMS: - if (!(pops->supported_flags & MSI_FLAG_PCI_IMS)) - return false; - break; default: WARN_ON_ONCE(1); return false; diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index 38795508c2e945..027cf67101ef0e 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c @@ -151,12 +151,6 @@ static int cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id) if (!host) return -ENOMEM; - /* Perform set up for DMA */ - if (pci_enable_device_io(pdev)) { - dev_err(&pdev->dev, "unable to configure BAR2.\n"); - return -ENODEV; - } - if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) { dev_err(&pdev->dev, "unable to configure DMA mask.\n"); return -ENODEV; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 7e6d09730e6d33..d18113017ee79e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -279,7 +279,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev) adev->irq.msi_enabled = false; if (!amdgpu_msi_ok(adev)) - flags = PCI_IRQ_LEGACY; + flags = PCI_IRQ_INTX; else flags = PCI_IRQ_ALL_TYPES; diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c index 6af57067c32e18..78dfe98ebcf7a7 100644 --- a/drivers/infiniband/hw/qib/qib_iba7220.c +++ b/drivers/infiniband/hw/qib/qib_iba7220.c @@ -3281,7 +3281,7 @@ static int qib_7220_intr_fallback(struct qib_devdata *dd) qib_free_irq(dd); dd->msi_lo = 0; - if (pci_alloc_irq_vectors(dd->pcidev, 1, 1, PCI_IRQ_LEGACY) < 0) + if (pci_alloc_irq_vectors(dd->pcidev, 1, 1, PCI_IRQ_INTX) < 0) qib_dev_err(dd, "Failed to enable INTx\n"); qib_setup_7220_interrupt(dd); return 1; diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index f93906d8fc0973..9db29916e35a0c 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c @@ -3471,8 +3471,7 @@ try_intx: pci_irq_vector(dd->pcidev, msixnum), ret); qib_7322_free_irq(dd); - pci_alloc_irq_vectors(dd->pcidev, 1, 1, - PCI_IRQ_LEGACY); + pci_alloc_irq_vectors(dd->pcidev, 1, 1, PCI_IRQ_INTX); goto try_intx; } dd->cspec->msix_entries[msixnum].arg = arg; @@ -5143,7 +5142,7 @@ static int qib_7322_intr_fallback(struct qib_devdata *dd) qib_devinfo(dd->pcidev, "MSIx interrupt not detected, trying INTx interrupts\n"); qib_7322_free_irq(dd); - if (pci_alloc_irq_vectors(dd->pcidev, 1, 1, PCI_IRQ_LEGACY) < 0) + if (pci_alloc_irq_vectors(dd->pcidev, 1, 1, PCI_IRQ_INTX) < 0) qib_dev_err(dd, "Failed to enable INTx\n"); qib_setup_7322_interrupt(dd, 0); return 1; diff --git a/drivers/infiniband/hw/qib/qib_pcie.c b/drivers/infiniband/hw/qib/qib_pcie.c index 47bf64ace05c8d..58c1d62d341bc3 100644 --- a/drivers/infiniband/hw/qib/qib_pcie.c +++ b/drivers/infiniband/hw/qib/qib_pcie.c @@ -210,7 +210,7 @@ int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent) } if (dd->flags & QIB_HAS_INTX) - flags |= PCI_IRQ_LEGACY; + flags |= PCI_IRQ_INTX; maxvec = (nent && *nent) ? *nent : 1; nvec = pci_alloc_irq_vectors(dd->pcidev, 1, maxvec, flags); if (nvec < 0) diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c index a5e88185171f82..768aad364c89f7 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c @@ -531,7 +531,7 @@ static int pvrdma_alloc_intrs(struct pvrdma_dev *dev) PCI_IRQ_MSIX); if (ret < 0) { ret = pci_alloc_irq_vectors(pdev, 1, 1, - PCI_IRQ_MSI | PCI_IRQ_LEGACY); + PCI_IRQ_MSI | PCI_IRQ_INTX); if (ret < 0) return ret; } diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index e692217fcb2801..fa7f50801c19f1 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -3704,20 +3704,11 @@ static struct irq_chip amd_ir_chip = { }; static const struct msi_parent_ops amdvi_msi_parent_ops = { - .supported_flags = X86_VECTOR_MSI_FLAGS_SUPPORTED | - MSI_FLAG_MULTI_PCI_MSI | - MSI_FLAG_PCI_IMS, + .supported_flags = X86_VECTOR_MSI_FLAGS_SUPPORTED | MSI_FLAG_MULTI_PCI_MSI, .prefix = "IR-", .init_dev_msi_info = msi_parent_init_dev_msi_info, }; -static const struct msi_parent_ops virt_amdvi_msi_parent_ops = { - .supported_flags = X86_VECTOR_MSI_FLAGS_SUPPORTED | - MSI_FLAG_MULTI_PCI_MSI, - .prefix = "vIR-", - .init_dev_msi_info = msi_parent_init_dev_msi_info, -}; - int amd_iommu_create_irq_domain(struct amd_iommu *iommu) { struct fwnode_handle *fn; @@ -3735,11 +3726,7 @@ int amd_iommu_create_irq_domain(struct amd_iommu *iommu) irq_domain_update_bus_token(iommu->ir_domain, DOMAIN_BUS_AMDVI); iommu->ir_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT | IRQ_DOMAIN_FLAG_ISOLATED_MSI; - - if (amd_iommu_np_cache) - iommu->ir_domain->msi_parent_ops = &virt_amdvi_msi_parent_ops; - else - iommu->ir_domain->msi_parent_ops = &amdvi_msi_parent_ops; + iommu->ir_domain->msi_parent_ops = &amdvi_msi_parent_ops; return 0; } diff --git a/drivers/iommu/intel/irq_remapping.c b/drivers/iommu/intel/irq_remapping.c index 566297bc87ddbe..0f64fa72ac4f06 100644 --- a/drivers/iommu/intel/irq_remapping.c +++ b/drivers/iommu/intel/irq_remapping.c @@ -82,7 +82,7 @@ static const struct irq_domain_ops intel_ir_domain_ops; static void iommu_disable_irq_remapping(struct intel_iommu *iommu); static int __init parse_ioapics_under_ir(void); -static const struct msi_parent_ops dmar_msi_parent_ops, virt_dmar_msi_parent_ops; +static const struct msi_parent_ops dmar_msi_parent_ops; static bool ir_pre_enabled(struct intel_iommu *iommu) { @@ -567,11 +567,7 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu) irq_domain_update_bus_token(iommu->ir_domain, DOMAIN_BUS_DMAR); iommu->ir_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT | IRQ_DOMAIN_FLAG_ISOLATED_MSI; - - if (cap_caching_mode(iommu->cap)) - iommu->ir_domain->msi_parent_ops = &virt_dmar_msi_parent_ops; - else - iommu->ir_domain->msi_parent_ops = &dmar_msi_parent_ops; + iommu->ir_domain->msi_parent_ops = &dmar_msi_parent_ops; ir_table->base = page_address(pages); ir_table->bitmap = bitmap; @@ -1421,20 +1417,11 @@ static const struct irq_domain_ops intel_ir_domain_ops = { }; static const struct msi_parent_ops dmar_msi_parent_ops = { - .supported_flags = X86_VECTOR_MSI_FLAGS_SUPPORTED | - MSI_FLAG_MULTI_PCI_MSI | - MSI_FLAG_PCI_IMS, + .supported_flags = X86_VECTOR_MSI_FLAGS_SUPPORTED | MSI_FLAG_MULTI_PCI_MSI, .prefix = "IR-", .init_dev_msi_info = msi_parent_init_dev_msi_info, }; -static const struct msi_parent_ops virt_dmar_msi_parent_ops = { - .supported_flags = X86_VECTOR_MSI_FLAGS_SUPPORTED | - MSI_FLAG_MULTI_PCI_MSI, - .prefix = "vIR-", - .init_dev_msi_info = msi_parent_init_dev_msi_info, -}; - /* * Support of Interrupt Remapping Unit Hotplug */ diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c index 8c00e0c695c5b9..9f4782bdbf4b6f 100644 --- a/drivers/mfd/intel-lpss-pci.c +++ b/drivers/mfd/intel-lpss-pci.c @@ -54,7 +54,7 @@ static int intel_lpss_pci_probe(struct pci_dev *pdev, if (ret) return ret; - ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_LEGACY); + ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_INTX); if (ret < 0) return ret; diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c index 4f8d962bb5b2a3..c61e8953511dec 100644 --- a/drivers/misc/vmw_vmci/vmci_guest.c +++ b/drivers/misc/vmw_vmci/vmci_guest.c @@ -787,8 +787,7 @@ static int vmci_guest_probe_device(struct pci_dev *pdev, error = pci_alloc_irq_vectors(pdev, num_irq_vectors, num_irq_vectors, PCI_IRQ_MSIX); if (error < 0) { - error = pci_alloc_irq_vectors(pdev, 1, 1, - PCI_IRQ_MSIX | PCI_IRQ_MSI | PCI_IRQ_LEGACY); + error = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); if (error < 0) goto err_unsubscribe_event; } else { diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c index f409d7bd1f1eed..c5e5fac49779e5 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c @@ -170,7 +170,7 @@ static int xgbe_config_irqs(struct xgbe_prv_data *pdata) goto out; ret = pci_alloc_irq_vectors(pdata->pcidev, 1, 1, - PCI_IRQ_LEGACY | PCI_IRQ_MSI); + PCI_IRQ_INTX | PCI_IRQ_MSI); if (ret < 0) { dev_info(pdata->dev, "single IRQ enablement failed\n"); return ret; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h index 7e9c74b141efb1..fc2b325f34e79f 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h @@ -17,7 +17,7 @@ #define AQ_CFG_IS_POLLING_DEF 0U -#define AQ_CFG_FORCE_LEGACY_INT 0U +#define AQ_CFG_FORCE_INTX 0U #define AQ_CFG_INTERRUPT_MODERATION_OFF 0 #define AQ_CFG_INTERRUPT_MODERATION_ON 1 diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h index dbd28466013580..f010bda61c9611 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h @@ -104,7 +104,7 @@ struct aq_stats_s { }; #define AQ_HW_IRQ_INVALID 0U -#define AQ_HW_IRQ_LEGACY 1U +#define AQ_HW_IRQ_INTX 1U #define AQ_HW_IRQ_MSI 2U #define AQ_HW_IRQ_MSIX 3U diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index d6d6d5d37ff3e6..fe0e3e2a811718 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -127,7 +127,7 @@ void aq_nic_cfg_start(struct aq_nic_s *self) cfg->irq_type = aq_pci_func_get_irq_type(self); - if ((cfg->irq_type == AQ_HW_IRQ_LEGACY) || + if ((cfg->irq_type == AQ_HW_IRQ_INTX) || (cfg->aq_hw_caps->vecs == 1U) || (cfg->vecs == 1U)) { cfg->is_rss = 0U; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c index baa5f8cc31f219..43c71f6b314f9d 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c @@ -200,7 +200,7 @@ unsigned int aq_pci_func_get_irq_type(struct aq_nic_s *self) if (self->pdev->msi_enabled) return AQ_HW_IRQ_MSI; - return AQ_HW_IRQ_LEGACY; + return AQ_HW_IRQ_INTX; } static void aq_pci_free_irq_vectors(struct aq_nic_s *self) @@ -298,11 +298,8 @@ static int aq_pci_probe(struct pci_dev *pdev, numvecs += AQ_HW_SERVICE_IRQS; /*enable interrupts */ -#if !AQ_CFG_FORCE_LEGACY_INT - err = pci_alloc_irq_vectors(self->pdev, 1, numvecs, - PCI_IRQ_MSIX | PCI_IRQ_MSI | - PCI_IRQ_LEGACY); - +#if !AQ_CFG_FORCE_INTX + err = pci_alloc_irq_vectors(self->pdev, 1, numvecs, PCI_IRQ_ALL_TYPES); if (err < 0) goto err_hwinit; numvecs = err; diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c index 9dfd68f0fda955..8de2cdd0921383 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c @@ -352,7 +352,7 @@ static int hw_atl_a0_hw_init(struct aq_hw_s *self, const u8 *mac_addr) { static u32 aq_hw_atl_igcr_table_[4][2] = { [AQ_HW_IRQ_INVALID] = { 0x20000000U, 0x20000000U }, - [AQ_HW_IRQ_LEGACY] = { 0x20000080U, 0x20000080U }, + [AQ_HW_IRQ_INTX] = { 0x20000080U, 0x20000080U }, [AQ_HW_IRQ_MSI] = { 0x20000021U, 0x20000025U }, [AQ_HW_IRQ_MSIX] = { 0x20000022U, 0x20000026U }, }; diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c index 54e70f07b57341..56c46266bb0ae5 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c @@ -562,7 +562,7 @@ static int hw_atl_b0_hw_init(struct aq_hw_s *self, const u8 *mac_addr) { static u32 aq_hw_atl_igcr_table_[4][2] = { [AQ_HW_IRQ_INVALID] = { 0x20000000U, 0x20000000U }, - [AQ_HW_IRQ_LEGACY] = { 0x20000080U, 0x20000080U }, + [AQ_HW_IRQ_INTX] = { 0x20000080U, 0x20000080U }, [AQ_HW_IRQ_MSI] = { 0x20000021U, 0x20000025U }, [AQ_HW_IRQ_MSIX] = { 0x20000022U, 0x20000026U }, }; diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c index 220400a633f5e5..b0ed572e88c67a 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c @@ -534,7 +534,7 @@ static int hw_atl2_hw_init(struct aq_hw_s *self, const u8 *mac_addr) { static u32 aq_hw_atl2_igcr_table_[4][2] = { [AQ_HW_IRQ_INVALID] = { 0x20000000U, 0x20000000U }, - [AQ_HW_IRQ_LEGACY] = { 0x20000080U, 0x20000080U }, + [AQ_HW_IRQ_INTX] = { 0x20000080U, 0x20000080U }, [AQ_HW_IRQ_MSI] = { 0x20000021U, 0x20000025U }, [AQ_HW_IRQ_MSIX] = { 0x20000022U, 0x20000026U }, }; diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index 49bb9a8f00e64f..0dbb541155f32e 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c @@ -901,7 +901,7 @@ static int alx_init_intr(struct alx_priv *alx) int ret; ret = pci_alloc_irq_vectors(alx->hw.pdev, 1, 1, - PCI_IRQ_MSI | PCI_IRQ_LEGACY); + PCI_IRQ_MSI | PCI_IRQ_INTX); if (ret < 0) return ret; diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 0fc5fe564ae50b..746ef4f34b1668 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -5104,7 +5104,7 @@ static int rtl_alloc_irq(struct rtl8169_private *tp) rtl_lock_config_regs(tp); fallthrough; case RTL_GIGA_MAC_VER_07 ... RTL_GIGA_MAC_VER_17: - flags = PCI_IRQ_LEGACY; + flags = PCI_IRQ_INTX; break; default: flags = PCI_IRQ_ALL_TYPES; diff --git a/drivers/net/ethernet/wangxun/libwx/wx_lib.c b/drivers/net/ethernet/wangxun/libwx/wx_lib.c index 6fae161cbcb822..8b7d13f26822d3 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c @@ -1674,14 +1674,14 @@ static int wx_set_interrupt_capability(struct wx *wx) /* minmum one for queue, one for misc*/ nvecs = 1; nvecs = pci_alloc_irq_vectors(pdev, nvecs, - nvecs, PCI_IRQ_MSI | PCI_IRQ_LEGACY); + nvecs, PCI_IRQ_MSI | PCI_IRQ_INTX); if (nvecs == 1) { if (pdev->msi_enabled) wx_err(wx, "Fallback to MSI.\n"); else - wx_err(wx, "Fallback to LEGACY.\n"); + wx_err(wx, "Fallback to INTx.\n"); } else { - wx_err(wx, "Failed to allocate MSI/LEGACY interrupts. Error: %d\n", nvecs); + wx_err(wx, "Failed to allocate MSI/INTx interrupts. Error: %d\n", nvecs); return nvecs; } @@ -2127,7 +2127,7 @@ void wx_write_eitr(struct wx_q_vector *q_vector) * wx_configure_vectors - Configure vectors for hardware * @wx: board private structure * - * wx_configure_vectors sets up the hardware to properly generate MSI-X/MSI/LEGACY + * wx_configure_vectors sets up the hardware to properly generate MSI-X/MSI/INTx * interrupts. **/ void wx_configure_vectors(struct wx *wx) diff --git a/drivers/net/wireless/ath/ath10k/ahb.c b/drivers/net/wireless/ath/ath10k/ahb.c index a378bc48b1d2b1..f0441b3d7dcb40 100644 --- a/drivers/net/wireless/ath/ath10k/ahb.c +++ b/drivers/net/wireless/ath/ath10k/ahb.c @@ -394,14 +394,14 @@ static irqreturn_t ath10k_ahb_interrupt_handler(int irq, void *arg) if (!ath10k_pci_irq_pending(ar)) return IRQ_NONE; - ath10k_pci_disable_and_clear_legacy_irq(ar); + ath10k_pci_disable_and_clear_intx_irq(ar); ath10k_pci_irq_msi_fw_mask(ar); napi_schedule(&ar->napi); return IRQ_HANDLED; } -static int ath10k_ahb_request_irq_legacy(struct ath10k *ar) +static int ath10k_ahb_request_irq_intx(struct ath10k *ar) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar); @@ -415,12 +415,12 @@ static int ath10k_ahb_request_irq_legacy(struct ath10k *ar) ar_ahb->irq, ret); return ret; } - ar_pci->oper_irq_mode = ATH10K_PCI_IRQ_LEGACY; + ar_pci->oper_irq_mode = ATH10K_PCI_IRQ_INTX; return 0; } -static void ath10k_ahb_release_irq_legacy(struct ath10k *ar) +static void ath10k_ahb_release_irq_intx(struct ath10k *ar) { struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar); @@ -430,7 +430,7 @@ static void ath10k_ahb_release_irq_legacy(struct ath10k *ar) static void ath10k_ahb_irq_disable(struct ath10k *ar) { ath10k_ce_disable_interrupts(ar); - ath10k_pci_disable_and_clear_legacy_irq(ar); + ath10k_pci_disable_and_clear_intx_irq(ar); } static int ath10k_ahb_resource_init(struct ath10k *ar) @@ -621,7 +621,7 @@ static int ath10k_ahb_hif_start(struct ath10k *ar) ath10k_core_napi_enable(ar); ath10k_ce_enable_interrupts(ar); - ath10k_pci_enable_legacy_irq(ar); + ath10k_pci_enable_intx_irq(ar); ath10k_pci_rx_post(ar); @@ -775,7 +775,7 @@ static int ath10k_ahb_probe(struct platform_device *pdev) ath10k_pci_init_napi(ar); - ret = ath10k_ahb_request_irq_legacy(ar); + ret = ath10k_ahb_request_irq_intx(ar); if (ret) goto err_free_pipes; @@ -806,7 +806,7 @@ err_halt_device: ath10k_ahb_clock_disable(ar); err_free_irq: - ath10k_ahb_release_irq_legacy(ar); + ath10k_ahb_release_irq_intx(ar); err_free_pipes: ath10k_pci_release_resource(ar); @@ -828,7 +828,7 @@ static void ath10k_ahb_remove(struct platform_device *pdev) ath10k_core_unregister(ar); ath10k_ahb_irq_disable(ar); - ath10k_ahb_release_irq_legacy(ar); + ath10k_ahb_release_irq_intx(ar); ath10k_pci_release_resource(ar); ath10k_ahb_halt_chip(ar); ath10k_ahb_clock_disable(ar); diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 5c34b156b4ff49..6aeeab2edf5af3 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -721,7 +721,7 @@ bool ath10k_pci_irq_pending(struct ath10k *ar) return false; } -void ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar) +void ath10k_pci_disable_and_clear_intx_irq(struct ath10k *ar) { /* IMPORTANT: INTR_CLR register has to be set after * INTR_ENABLE is set to 0, otherwise interrupt can not be @@ -739,7 +739,7 @@ void ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar) PCIE_INTR_ENABLE_ADDRESS); } -void ath10k_pci_enable_legacy_irq(struct ath10k *ar) +void ath10k_pci_enable_intx_irq(struct ath10k *ar) { ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_ENABLE_ADDRESS, @@ -1935,7 +1935,7 @@ static void ath10k_pci_irq_msi_fw_unmask(struct ath10k *ar) static void ath10k_pci_irq_disable(struct ath10k *ar) { ath10k_ce_disable_interrupts(ar); - ath10k_pci_disable_and_clear_legacy_irq(ar); + ath10k_pci_disable_and_clear_intx_irq(ar); ath10k_pci_irq_msi_fw_mask(ar); } @@ -1949,7 +1949,7 @@ static void ath10k_pci_irq_sync(struct ath10k *ar) static void ath10k_pci_irq_enable(struct ath10k *ar) { ath10k_ce_enable_interrupts(ar); - ath10k_pci_enable_legacy_irq(ar); + ath10k_pci_enable_intx_irq(ar); ath10k_pci_irq_msi_fw_unmask(ar); } @@ -3111,11 +3111,11 @@ static irqreturn_t ath10k_pci_interrupt_handler(int irq, void *arg) return IRQ_NONE; } - if ((ar_pci->oper_irq_mode == ATH10K_PCI_IRQ_LEGACY) && + if ((ar_pci->oper_irq_mode == ATH10K_PCI_IRQ_INTX) && !ath10k_pci_irq_pending(ar)) return IRQ_NONE; - ath10k_pci_disable_and_clear_legacy_irq(ar); + ath10k_pci_disable_and_clear_intx_irq(ar); ath10k_pci_irq_msi_fw_mask(ar); napi_schedule(&ar->napi); @@ -3152,7 +3152,7 @@ static int ath10k_pci_napi_poll(struct napi_struct *ctx, int budget) napi_schedule(ctx); goto out; } - ath10k_pci_enable_legacy_irq(ar); + ath10k_pci_enable_intx_irq(ar); ath10k_pci_irq_msi_fw_unmask(ar); } @@ -3177,7 +3177,7 @@ static int ath10k_pci_request_irq_msi(struct ath10k *ar) return 0; } -static int ath10k_pci_request_irq_legacy(struct ath10k *ar) +static int ath10k_pci_request_irq_intx(struct ath10k *ar) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); int ret; @@ -3199,8 +3199,8 @@ static int ath10k_pci_request_irq(struct ath10k *ar) struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); switch (ar_pci->oper_irq_mode) { - case ATH10K_PCI_IRQ_LEGACY: - return ath10k_pci_request_irq_legacy(ar); + case ATH10K_PCI_IRQ_INTX: + return ath10k_pci_request_irq_intx(ar); case ATH10K_PCI_IRQ_MSI: return ath10k_pci_request_irq_msi(ar); default: @@ -3232,7 +3232,7 @@ static int ath10k_pci_init_irq(struct ath10k *ar) ath10k_pci_irq_mode); /* Try MSI */ - if (ath10k_pci_irq_mode != ATH10K_PCI_IRQ_LEGACY) { + if (ath10k_pci_irq_mode != ATH10K_PCI_IRQ_INTX) { ar_pci->oper_irq_mode = ATH10K_PCI_IRQ_MSI; ret = pci_enable_msi(ar_pci->pdev); if (ret == 0) @@ -3250,7 +3250,7 @@ static int ath10k_pci_init_irq(struct ath10k *ar) * For now, fix the race by repeating the write in below * synchronization checking. */ - ar_pci->oper_irq_mode = ATH10K_PCI_IRQ_LEGACY; + ar_pci->oper_irq_mode = ATH10K_PCI_IRQ_INTX; ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_ENABLE_ADDRESS, PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL); @@ -3258,7 +3258,7 @@ static int ath10k_pci_init_irq(struct ath10k *ar) return 0; } -static void ath10k_pci_deinit_irq_legacy(struct ath10k *ar) +static void ath10k_pci_deinit_irq_intx(struct ath10k *ar) { ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_ENABLE_ADDRESS, 0); @@ -3269,8 +3269,8 @@ static int ath10k_pci_deinit_irq(struct ath10k *ar) struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); switch (ar_pci->oper_irq_mode) { - case ATH10K_PCI_IRQ_LEGACY: - ath10k_pci_deinit_irq_legacy(ar); + case ATH10K_PCI_IRQ_INTX: + ath10k_pci_deinit_irq_intx(ar); break; default: pci_disable_msi(ar_pci->pdev); @@ -3307,14 +3307,14 @@ int ath10k_pci_wait_for_target_init(struct ath10k *ar) if (val & FW_IND_INITIALIZED) break; - if (ar_pci->oper_irq_mode == ATH10K_PCI_IRQ_LEGACY) + if (ar_pci->oper_irq_mode == ATH10K_PCI_IRQ_INTX) /* Fix potential race by repeating CORE_BASE writes */ - ath10k_pci_enable_legacy_irq(ar); + ath10k_pci_enable_intx_irq(ar); mdelay(10); } while (time_before(jiffies, timeout)); - ath10k_pci_disable_and_clear_legacy_irq(ar); + ath10k_pci_disable_and_clear_intx_irq(ar); ath10k_pci_irq_msi_fw_mask(ar); if (val == 0xffffffff) { diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h index 27bb4cf2dfea93..4c3f536f2ea1a9 100644 --- a/drivers/net/wireless/ath/ath10k/pci.h +++ b/drivers/net/wireless/ath/ath10k/pci.h @@ -101,7 +101,7 @@ struct ath10k_pci_supp_chip { enum ath10k_pci_irq_mode { ATH10K_PCI_IRQ_AUTO = 0, - ATH10K_PCI_IRQ_LEGACY = 1, + ATH10K_PCI_IRQ_INTX = 1, ATH10K_PCI_IRQ_MSI = 2, }; @@ -243,9 +243,9 @@ int ath10k_pci_init_pipes(struct ath10k *ar); int ath10k_pci_init_config(struct ath10k *ar); void ath10k_pci_rx_post(struct ath10k *ar); void ath10k_pci_flush(struct ath10k *ar); -void ath10k_pci_enable_legacy_irq(struct ath10k *ar); +void ath10k_pci_enable_intx_irq(struct ath10k *ar); bool ath10k_pci_irq_pending(struct ath10k *ar); -void ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar); +void ath10k_pci_disable_and_clear_intx_irq(struct ath10k *ar); void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar); int ath10k_pci_wait_for_target_init(struct ath10k *ar); int ath10k_pci_setup_resource(struct ath10k *ar); diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c index 9986a4cb37eb2b..282f1e5a882e81 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.c +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -1612,7 +1612,7 @@ static struct rtw_hci_ops rtw_pci_ops = { static int rtw_pci_request_irq(struct rtw_dev *rtwdev, struct pci_dev *pdev) { - unsigned int flags = PCI_IRQ_LEGACY; + unsigned int flags = PCI_IRQ_INTX; int ret; if (!rtw_disable_msi) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 19001130ad9436..100549694e53cb 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -3547,7 +3547,7 @@ static int rtw89_pci_request_irq(struct rtw89_dev *rtwdev, unsigned long flags = 0; int ret; - flags |= PCI_IRQ_LEGACY | PCI_IRQ_MSI; + flags |= PCI_IRQ_INTX | PCI_IRQ_MSI; ret = pci_alloc_irq_vectors(pdev, 1, 1, flags); if (ret < 0) { rtw89_err(rtwdev, "failed to alloc irq vectors, ret %d\n", ret); diff --git a/drivers/ntb/hw/idt/ntb_hw_idt.c b/drivers/ntb/hw/idt/ntb_hw_idt.c index 48823b53ede3e9..48dfb1a69a77e5 100644 --- a/drivers/ntb/hw/idt/ntb_hw_idt.c +++ b/drivers/ntb/hw/idt/ntb_hw_idt.c @@ -2129,7 +2129,7 @@ static int idt_init_isr(struct idt_ntb_dev *ndev) int ret; /* Allocate just one interrupt vector for the ISR */ - ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI | PCI_IRQ_LEGACY); + ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI | PCI_IRQ_INTX); if (ret != 1) { dev_err(&pdev->dev, "Failed to allocate IRQ vector"); return ret; diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c index 81c50dc64da96f..e0cc4560dfde7f 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c @@ -99,14 +99,11 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn, ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS; } else { bool is_prefetch = !!(flags & PCI_BASE_ADDRESS_MEM_PREFETCH); - bool is_64bits = sz > SZ_2G; + bool is_64bits = !!(flags & PCI_BASE_ADDRESS_MEM_TYPE_64); if (is_64bits && (bar & 1)) return -EINVAL; - if (is_64bits && !(flags & PCI_BASE_ADDRESS_MEM_TYPE_64)) - epf_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64; - if (is_64bits && is_prefetch) ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS; else if (is_prefetch) @@ -746,6 +743,8 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep) spin_lock_init(&ep->lock); + pci_epc_init_notify(epc); + return 0; free_epc_mem: diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c index 0e406677060d38..d2d17d37d3e0b5 100644 --- a/drivers/pci/controller/dwc/pci-dra7xx.c +++ b/drivers/pci/controller/dwc/pci-dra7xx.c @@ -467,6 +467,15 @@ static int dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx, return ret; } + ret = dw_pcie_ep_init_registers(ep); + if (ret) { + dev_err(dev, "Failed to initialize DWC endpoint registers\n"); + dw_pcie_ep_deinit(ep); + return ret; + } + + dw_pcie_ep_init_notify(ep); + return 0; } diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 99a60270b26cdf..917c69edee1d54 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -1123,6 +1123,16 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie, dev_err(dev, "failed to initialize endpoint\n"); return ret; } + + ret = dw_pcie_ep_init_registers(ep); + if (ret) { + dev_err(dev, "Failed to initialize DWC endpoint registers\n"); + dw_pcie_ep_deinit(ep); + return ret; + } + + dw_pcie_ep_init_notify(ep); + /* Start LTSSM. */ imx6_pcie_ltssm_enable(dev); diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c index 844de441872429..d3a7d14ee685a1 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c @@ -1286,6 +1286,15 @@ static int ks_pcie_probe(struct platform_device *pdev) ret = dw_pcie_ep_init(&pci->ep); if (ret < 0) goto err_get_sync; + + ret = dw_pcie_ep_init_registers(&pci->ep); + if (ret) { + dev_err(dev, "Failed to initialize DWC endpoint registers\n"); + goto err_ep_init; + } + + dw_pcie_ep_init_notify(&pci->ep); + break; default: dev_err(dev, "INVALID device type %d\n", mode); @@ -1295,6 +1304,8 @@ static int ks_pcie_probe(struct platform_device *pdev) return 0; +err_ep_init: + dw_pcie_ep_deinit(&pci->ep); err_get_sync: pm_runtime_put(dev); pm_runtime_disable(dev); diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c index 1f6ee1460ec2a3..7dde6d5fa4d858 100644 --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c @@ -279,6 +279,15 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev) if (ret) return ret; + ret = dw_pcie_ep_init_registers(&pci->ep); + if (ret) { + dev_err(dev, "Failed to initialize DWC endpoint registers\n"); + dw_pcie_ep_deinit(&pci->ep); + return ret; + } + + dw_pcie_ep_init_notify(&pci->ep); + return ls_pcie_ep_interrupt_init(pcie, pdev); } diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c index 9ed0a9ba761920..a4630b92489bf4 100644 --- a/drivers/pci/controller/dwc/pcie-artpec6.c +++ b/drivers/pci/controller/dwc/pcie-artpec6.c @@ -441,7 +441,20 @@ static int artpec6_pcie_probe(struct platform_device *pdev) pci->ep.ops = &pcie_ep_ops; - return dw_pcie_ep_init(&pci->ep); + ret = dw_pcie_ep_init(&pci->ep); + if (ret) + return ret; + + ret = dw_pcie_ep_init_registers(&pci->ep); + if (ret) { + dev_err(dev, "Failed to initialize DWC endpoint registers\n"); + dw_pcie_ep_deinit(&pci->ep); + return ret; + } + + dw_pcie_ep_init_notify(&pci->ep); + + break; default: dev_err(dev, "INVALID device type %d\n", artpec6_pcie->mode); } diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index 746a11dcb67f10..47391d7d3a7343 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -15,6 +15,10 @@ #include <linux/pci-epc.h> #include <linux/pci-epf.h> +/** + * dw_pcie_ep_linkup - Notify EPF drivers about Link Up event + * @ep: DWC EP device + */ void dw_pcie_ep_linkup(struct dw_pcie_ep *ep) { struct pci_epc *epc = ep->epc; @@ -23,6 +27,10 @@ void dw_pcie_ep_linkup(struct dw_pcie_ep *ep) } EXPORT_SYMBOL_GPL(dw_pcie_ep_linkup); +/** + * dw_pcie_ep_init_notify - Notify EPF drivers about EPC initialization complete + * @ep: DWC EP device + */ void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep) { struct pci_epc *epc = ep->epc; @@ -31,6 +39,14 @@ void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep) } EXPORT_SYMBOL_GPL(dw_pcie_ep_init_notify); +/** + * dw_pcie_ep_get_func_from_ep - Get the struct dw_pcie_ep_func corresponding to + * the endpoint function + * @ep: DWC EP device + * @func_no: Function number of the endpoint device + * + * Return: struct dw_pcie_ep_func if success, NULL otherwise. + */ struct dw_pcie_ep_func * dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no) { @@ -61,6 +77,11 @@ static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, u8 func_no, dw_pcie_dbi_ro_wr_dis(pci); } +/** + * dw_pcie_ep_reset_bar - Reset endpoint BAR + * @pci: DWC PCI device + * @bar: BAR number of the endpoint + */ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) { u8 func_no, funcs; @@ -440,6 +461,13 @@ static const struct pci_epc_ops epc_ops = { .get_features = dw_pcie_ep_get_features, }; +/** + * dw_pcie_ep_raise_intx_irq - Raise INTx IRQ to the host + * @ep: DWC EP device + * @func_no: Function number of the endpoint + * + * Return: 0 if success, errono otherwise. + */ int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no) { struct dw_pcie *pci = to_dw_pcie_from_ep(ep); @@ -451,6 +479,14 @@ int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no) } EXPORT_SYMBOL_GPL(dw_pcie_ep_raise_intx_irq); +/** + * dw_pcie_ep_raise_msi_irq - Raise MSI IRQ to the host + * @ep: DWC EP device + * @func_no: Function number of the endpoint + * @interrupt_num: Interrupt number to be raised + * + * Return: 0 if success, errono otherwise. + */ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, u8 interrupt_num) { @@ -500,6 +536,15 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, } EXPORT_SYMBOL_GPL(dw_pcie_ep_raise_msi_irq); +/** + * dw_pcie_ep_raise_msix_irq_doorbell - Raise MSI-X to the host using Doorbell + * method + * @ep: DWC EP device + * @func_no: Function number of the endpoint device + * @interrupt_num: Interrupt number to be raised + * + * Return: 0 if success, errno otherwise. + */ int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no, u16 interrupt_num) { @@ -519,6 +564,14 @@ int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no, return 0; } +/** + * dw_pcie_ep_raise_msix_irq - Raise MSI-X to the host + * @ep: DWC EP device + * @func_no: Function number of the endpoint device + * @interrupt_num: Interrupt number to be raised + * + * Return: 0 if success, errno otherwise. + */ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, u16 interrupt_num) { @@ -566,22 +619,42 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, return 0; } -void dw_pcie_ep_exit(struct dw_pcie_ep *ep) +/** + * dw_pcie_ep_cleanup - Cleanup DWC EP resources after fundamental reset + * @ep: DWC EP device + * + * Cleans up the DWC EP specific resources like eDMA etc... after fundamental + * reset like PERST#. Note that this API is only applicable for drivers + * supporting PERST# or any other methods of fundamental reset. + */ +void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep) { struct dw_pcie *pci = to_dw_pcie_from_ep(ep); - struct pci_epc *epc = ep->epc; dw_pcie_edma_remove(pci); + ep->epc->init_complete = false; +} +EXPORT_SYMBOL_GPL(dw_pcie_ep_cleanup); + +/** + * dw_pcie_ep_deinit - Deinitialize the endpoint device + * @ep: DWC EP device + * + * Deinitialize the endpoint device. EPC device is not destroyed since that will + * be taken care by Devres. + */ +void dw_pcie_ep_deinit(struct dw_pcie_ep *ep) +{ + struct pci_epc *epc = ep->epc; + + dw_pcie_ep_cleanup(ep); pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem, epc->mem->window.page_size); pci_epc_mem_exit(epc); - - if (ep->ops->deinit) - ep->ops->deinit(ep); } -EXPORT_SYMBOL_GPL(dw_pcie_ep_exit); +EXPORT_SYMBOL_GPL(dw_pcie_ep_deinit); static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap) { @@ -601,14 +674,27 @@ static unsigned int dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap) return 0; } -int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep) +/** + * dw_pcie_ep_init_registers - Initialize DWC EP specific registers + * @ep: DWC EP device + * + * Initialize the registers (CSRs) specific to DWC EP. This API should be called + * only when the endpoint receives an active refclk (either from host or + * generated locally). + */ +int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep) { struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + struct dw_pcie_ep_func *ep_func; + struct device *dev = pci->dev; + struct pci_epc *epc = ep->epc; unsigned int offset, ptm_cap_base; unsigned int nbars; u8 hdr_type; + u8 func_no; + int i, ret; + void *addr; u32 reg; - int i; hdr_type = dw_pcie_readb_dbi(pci, PCI_HEADER_TYPE) & PCI_HEADER_TYPE_MASK; @@ -619,6 +705,58 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep) return -EIO; } + dw_pcie_version_detect(pci); + + dw_pcie_iatu_detect(pci); + + ret = dw_pcie_edma_detect(pci); + if (ret) + return ret; + + if (!ep->ib_window_map) { + ep->ib_window_map = devm_bitmap_zalloc(dev, pci->num_ib_windows, + GFP_KERNEL); + if (!ep->ib_window_map) + goto err_remove_edma; + } + + if (!ep->ob_window_map) { + ep->ob_window_map = devm_bitmap_zalloc(dev, pci->num_ob_windows, + GFP_KERNEL); + if (!ep->ob_window_map) + goto err_remove_edma; + } + + if (!ep->outbound_addr) { + addr = devm_kcalloc(dev, pci->num_ob_windows, sizeof(phys_addr_t), + GFP_KERNEL); + if (!addr) + goto err_remove_edma; + ep->outbound_addr = addr; + } + + for (func_no = 0; func_no < epc->max_functions; func_no++) { + + ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); + if (ep_func) + continue; + + ep_func = devm_kzalloc(dev, sizeof(*ep_func), GFP_KERNEL); + if (!ep_func) + goto err_remove_edma; + + ep_func->func_no = func_no; + ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no, + PCI_CAP_ID_MSI); + ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no, + PCI_CAP_ID_MSIX); + + list_add_tail(&ep_func->list, &ep->func_list); + } + + if (ep->ops->init) + ep->ops->init(ep); + offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR); ptm_cap_base = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM); @@ -658,22 +796,32 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep) dw_pcie_dbi_ro_wr_dis(pci); return 0; + +err_remove_edma: + dw_pcie_edma_remove(pci); + + return ret; } -EXPORT_SYMBOL_GPL(dw_pcie_ep_init_complete); +EXPORT_SYMBOL_GPL(dw_pcie_ep_init_registers); +/** + * dw_pcie_ep_init - Initialize the endpoint device + * @ep: DWC EP device + * + * Initialize the endpoint device. Allocate resources and create the EPC + * device with the endpoint framework. + * + * Return: 0 if success, errno otherwise. + */ int dw_pcie_ep_init(struct dw_pcie_ep *ep) { int ret; - void *addr; - u8 func_no; struct resource *res; struct pci_epc *epc; struct dw_pcie *pci = to_dw_pcie_from_ep(ep); struct device *dev = pci->dev; struct platform_device *pdev = to_platform_device(dev); struct device_node *np = dev->of_node; - const struct pci_epc_features *epc_features; - struct dw_pcie_ep_func *ep_func; INIT_LIST_HEAD(&ep->func_list); @@ -691,26 +839,6 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) if (ep->ops->pre_init) ep->ops->pre_init(ep); - dw_pcie_version_detect(pci); - - dw_pcie_iatu_detect(pci); - - ep->ib_window_map = devm_bitmap_zalloc(dev, pci->num_ib_windows, - GFP_KERNEL); - if (!ep->ib_window_map) - return -ENOMEM; - - ep->ob_window_map = devm_bitmap_zalloc(dev, pci->num_ob_windows, - GFP_KERNEL); - if (!ep->ob_window_map) - return -ENOMEM; - - addr = devm_kcalloc(dev, pci->num_ob_windows, sizeof(phys_addr_t), - GFP_KERNEL); - if (!addr) - return -ENOMEM; - ep->outbound_addr = addr; - epc = devm_pci_epc_create(dev, &epc_ops); if (IS_ERR(epc)) { dev_err(dev, "Failed to create epc device\n"); @@ -724,28 +852,11 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) if (ret < 0) epc->max_functions = 1; - for (func_no = 0; func_no < epc->max_functions; func_no++) { - ep_func = devm_kzalloc(dev, sizeof(*ep_func), GFP_KERNEL); - if (!ep_func) - return -ENOMEM; - - ep_func->func_no = func_no; - ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no, - PCI_CAP_ID_MSI); - ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no, - PCI_CAP_ID_MSIX); - - list_add_tail(&ep_func->list, &ep->func_list); - } - - if (ep->ops->init) - ep->ops->init(ep); - ret = pci_epc_mem_init(epc, ep->phys_base, ep->addr_size, ep->page_size); if (ret < 0) { dev_err(dev, "Failed to initialize address space\n"); - goto err_ep_deinit; + return ret; } ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys, @@ -756,36 +867,11 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) goto err_exit_epc_mem; } - ret = dw_pcie_edma_detect(pci); - if (ret) - goto err_free_epc_mem; - - if (ep->ops->get_features) { - epc_features = ep->ops->get_features(ep); - if (epc_features->core_init_notifier) - return 0; - } - - ret = dw_pcie_ep_init_complete(ep); - if (ret) - goto err_remove_edma; - return 0; -err_remove_edma: - dw_pcie_edma_remove(pci); - -err_free_epc_mem: - pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem, - epc->mem->window.page_size); - err_exit_epc_mem: pci_epc_mem_exit(epc); -err_ep_deinit: - if (ep->ops->deinit) - ep->ops->deinit(ep); - return ret; } EXPORT_SYMBOL_GPL(dw_pcie_ep_init); diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c index 778588b4be7063..8490c5d6ff9f92 100644 --- a/drivers/pci/controller/dwc/pcie-designware-plat.c +++ b/drivers/pci/controller/dwc/pcie-designware-plat.c @@ -145,6 +145,17 @@ static int dw_plat_pcie_probe(struct platform_device *pdev) pci->ep.ops = &pcie_ep_ops; ret = dw_pcie_ep_init(&pci->ep); + if (ret) + return ret; + + ret = dw_pcie_ep_init_registers(&pci->ep); + if (ret) { + dev_err(dev, "Failed to initialize DWC endpoint registers\n"); + dw_pcie_ep_deinit(&pci->ep); + } + + dw_pcie_ep_init_notify(&pci->ep); + break; default: dev_err(dev, "INVALID device type %d\n", dw_plat_pcie->mode); diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 26dae483746277..f8e5431a207bd5 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -333,7 +333,6 @@ struct dw_pcie_rp { struct dw_pcie_ep_ops { void (*pre_init)(struct dw_pcie_ep *ep); void (*init)(struct dw_pcie_ep *ep); - void (*deinit)(struct dw_pcie_ep *ep); int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no, unsigned int type, u16 interrupt_num); const struct pci_epc_features* (*get_features)(struct dw_pcie_ep *ep); @@ -670,9 +669,10 @@ static inline void __iomem *dw_pcie_own_conf_map_bus(struct pci_bus *bus, #ifdef CONFIG_PCIE_DW_EP void dw_pcie_ep_linkup(struct dw_pcie_ep *ep); int dw_pcie_ep_init(struct dw_pcie_ep *ep); -int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep); +int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep); void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep); -void dw_pcie_ep_exit(struct dw_pcie_ep *ep); +void dw_pcie_ep_deinit(struct dw_pcie_ep *ep); +void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep); int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no); int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, u8 interrupt_num); @@ -693,7 +693,7 @@ static inline int dw_pcie_ep_init(struct dw_pcie_ep *ep) return 0; } -static inline int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep) +static inline int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep) { return 0; } @@ -702,7 +702,11 @@ static inline void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep) { } -static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep) +static inline void dw_pcie_ep_deinit(struct dw_pcie_ep *ep) +{ +} + +static inline void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep) { } diff --git a/drivers/pci/controller/dwc/pcie-keembay.c b/drivers/pci/controller/dwc/pcie-keembay.c index 5e8e54f597dd47..98bbc83182b45c 100644 --- a/drivers/pci/controller/dwc/pcie-keembay.c +++ b/drivers/pci/controller/dwc/pcie-keembay.c @@ -396,6 +396,7 @@ static int keembay_pcie_probe(struct platform_device *pdev) struct keembay_pcie *pcie; struct dw_pcie *pci; enum dw_pcie_device_mode mode; + int ret; data = device_get_match_data(dev); if (!data) @@ -430,11 +431,26 @@ static int keembay_pcie_probe(struct platform_device *pdev) return -ENODEV; pci->ep.ops = &keembay_pcie_ep_ops; - return dw_pcie_ep_init(&pci->ep); + ret = dw_pcie_ep_init(&pci->ep); + if (ret) + return ret; + + ret = dw_pcie_ep_init_registers(&pci->ep); + if (ret) { + dev_err(dev, "Failed to initialize DWC endpoint registers\n"); + dw_pcie_ep_deinit(&pci->ep); + return ret; + } + + dw_pcie_ep_init_notify(&pci->ep); + + break; default: dev_err(dev, "Invalid device type %d\n", pcie->mode); return -ENODEV; } + + return 0; } static const struct keembay_pcie_of_data keembay_pcie_rc_of_data = { diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 36e5e80cd22f59..2fb8c15e7a9116 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -463,7 +463,7 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci) PARF_INT_ALL_LINK_UP | PARF_INT_ALL_EDMA; writel_relaxed(val, pcie_ep->parf + PARF_INT_ALL_MASK); - ret = dw_pcie_ep_init_complete(&pcie_ep->pci.ep); + ret = dw_pcie_ep_init_registers(&pcie_ep->pci.ep); if (ret) { dev_err(dev, "Failed to complete initialization: %d\n", ret); goto err_disable_resources; @@ -507,6 +507,7 @@ static void qcom_pcie_perst_assert(struct dw_pcie *pci) return; } + dw_pcie_ep_cleanup(&pci->ep); qcom_pcie_disable_resources(pcie_ep); pcie_ep->link_status = QCOM_PCIE_EP_LINK_DISABLED; } @@ -774,7 +775,6 @@ static void qcom_pcie_ep_init_debugfs(struct qcom_pcie_ep *pcie_ep) static const struct pci_epc_features qcom_pcie_epc_features = { .linkup_notifier = true, - .core_init_notifier = true, .msi_capable = true, .msix_capable = false, .align = SZ_4K, diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c index 0be760ed420bdc..cfeccc2f9ee1d1 100644 --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c @@ -352,11 +352,8 @@ static void rcar_gen4_pcie_ep_init(struct dw_pcie_ep *ep) dw_pcie_ep_reset_bar(pci, bar); } -static void rcar_gen4_pcie_ep_deinit(struct dw_pcie_ep *ep) +static void rcar_gen4_pcie_ep_deinit(struct rcar_gen4_pcie *rcar) { - struct dw_pcie *dw = to_dw_pcie_from_ep(ep); - struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw); - writel(0, rcar->base + PCIEDMAINTSTSEN); rcar_gen4_pcie_common_deinit(rcar); } @@ -410,7 +407,6 @@ static unsigned int rcar_gen4_pcie_ep_get_dbi2_offset(struct dw_pcie_ep *ep, static const struct dw_pcie_ep_ops pcie_ep_ops = { .pre_init = rcar_gen4_pcie_ep_pre_init, .init = rcar_gen4_pcie_ep_init, - .deinit = rcar_gen4_pcie_ep_deinit, .raise_irq = rcar_gen4_pcie_ep_raise_irq, .get_features = rcar_gen4_pcie_ep_get_features, .get_dbi_offset = rcar_gen4_pcie_ep_get_dbi_offset, @@ -420,18 +416,36 @@ static const struct dw_pcie_ep_ops pcie_ep_ops = { static int rcar_gen4_add_dw_pcie_ep(struct rcar_gen4_pcie *rcar) { struct dw_pcie_ep *ep = &rcar->dw.ep; + struct device *dev = rcar->dw.dev; + int ret; if (!IS_ENABLED(CONFIG_PCIE_RCAR_GEN4_EP)) return -ENODEV; ep->ops = &pcie_ep_ops; - return dw_pcie_ep_init(ep); + ret = dw_pcie_ep_init(ep); + if (ret) { + rcar_gen4_pcie_ep_deinit(rcar); + return ret; + } + + ret = dw_pcie_ep_init_registers(ep); + if (ret) { + dev_err(dev, "Failed to initialize DWC endpoint registers\n"); + dw_pcie_ep_deinit(ep); + rcar_gen4_pcie_ep_deinit(rcar); + } + + dw_pcie_ep_init_notify(ep); + + return ret; } static void rcar_gen4_remove_dw_pcie_ep(struct rcar_gen4_pcie *rcar) { - dw_pcie_ep_exit(&rcar->dw.ep); + dw_pcie_ep_deinit(&rcar->dw.ep); + rcar_gen4_pcie_ep_deinit(rcar); } /* Common */ diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index 1f7b662cb8e15b..93f5433c5c5509 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -1715,6 +1715,8 @@ static void pex_ep_event_pex_rst_assert(struct tegra_pcie_dw *pcie) if (ret) dev_err(pcie->dev, "Failed to go Detect state: %d\n", ret); + dw_pcie_ep_cleanup(&pcie->pci.ep); + reset_control_assert(pcie->core_rst); tegra_pcie_disable_phy(pcie); @@ -1895,7 +1897,7 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie) val = (upper_32_bits(ep->msi_mem_phys) & MSIX_ADDR_MATCH_HIGH_OFF_MASK); dw_pcie_writel_dbi(pci, MSIX_ADDR_MATCH_HIGH_OFF, val); - ret = dw_pcie_ep_init_complete(ep); + ret = dw_pcie_ep_init_registers(ep); if (ret) { dev_err(dev, "Failed to complete initialization: %d\n", ret); goto fail_init_complete; @@ -2004,7 +2006,6 @@ static int tegra_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, static const struct pci_epc_features tegra_pcie_epc_features = { .linkup_notifier = true, - .core_init_notifier = true, .msi_capable = false, .msix_capable = false, .bar[BAR_0] = { .type = BAR_FIXED, .fixed_size = SZ_1M, @@ -2273,11 +2274,14 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev) ret = tegra_pcie_config_ep(pcie, pdev); if (ret < 0) goto fail; + else + return 0; break; default: dev_err(dev, "Invalid PCIe device type %d\n", pcie->of_data->mode); + ret = -EINVAL; } fail: diff --git a/drivers/pci/controller/dwc/pcie-uniphier-ep.c b/drivers/pci/controller/dwc/pcie-uniphier-ep.c index 639bc2e12476f5..a2b844268e2857 100644 --- a/drivers/pci/controller/dwc/pcie-uniphier-ep.c +++ b/drivers/pci/controller/dwc/pcie-uniphier-ep.c @@ -399,7 +399,20 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev) return ret; priv->pci.ep.ops = &uniphier_pcie_ep_ops; - return dw_pcie_ep_init(&priv->pci.ep); + ret = dw_pcie_ep_init(&priv->pci.ep); + if (ret) + return ret; + + ret = dw_pcie_ep_init_registers(&priv->pci.ep); + if (ret) { + dev_err(dev, "Failed to initialize DWC endpoint registers\n"); + dw_pcie_ep_deinit(&priv->pci.ep); + return ret; + } + + dw_pcie_ep_init_notify(&priv->pci.ep); + + return 0; } static const struct uniphier_pcie_ep_soc_data uniphier_pro5_data = { diff --git a/drivers/pci/controller/pcie-mt7621.c b/drivers/pci/controller/pcie-mt7621.c index 79e225edb42a01..d97b956e6e570f 100644 --- a/drivers/pci/controller/pcie-mt7621.c +++ b/drivers/pci/controller/pcie-mt7621.c @@ -202,7 +202,7 @@ static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie, struct mt7621_pcie_port *port; struct device *dev = pcie->dev; struct platform_device *pdev = to_platform_device(dev); - char name[10]; + char name[11]; int err; port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); diff --git a/drivers/pci/controller/pcie-rcar-ep.c b/drivers/pci/controller/pcie-rcar-ep.c index 05967c6c0b426a..047e2cef5afcd5 100644 --- a/drivers/pci/controller/pcie-rcar-ep.c +++ b/drivers/pci/controller/pcie-rcar-ep.c @@ -542,6 +542,8 @@ static int rcar_pcie_ep_probe(struct platform_device *pdev) goto err_pm_put; } + pci_epc_init_notify(epc); + return 0; err_pm_put: diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c index c9046e97a1d27f..1362745336568e 100644 --- a/drivers/pci/controller/pcie-rockchip-ep.c +++ b/drivers/pci/controller/pcie-rockchip-ep.c @@ -98,10 +98,8 @@ static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn, /* All functions share the same vendor ID with function 0 */ if (fn == 0) { - u32 vid_regs = (hdr->vendorid & GENMASK(15, 0)) | - (hdr->subsys_vendor_id & GENMASK(31, 16)) << 16; - - rockchip_pcie_write(rockchip, vid_regs, + rockchip_pcie_write(rockchip, + hdr->vendorid | hdr->subsys_vendor_id << 16, PCIE_CORE_CONFIG_VENDOR); } @@ -153,7 +151,7 @@ static int rockchip_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn, ctrl = ROCKCHIP_PCIE_CORE_BAR_CFG_CTRL_IO_32BITS; } else { bool is_prefetch = !!(flags & PCI_BASE_ADDRESS_MEM_PREFETCH); - bool is_64bits = sz > SZ_2G; + bool is_64bits = !!(flags & PCI_BASE_ADDRESS_MEM_TYPE_64); if (is_64bits && (bar & 1)) return -EINVAL; @@ -609,6 +607,8 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev) rockchip_pcie_write(rockchip, PCIE_CLIENT_CONF_ENABLE, PCIE_CLIENT_CONFIG); + pci_epc_init_notify(epc); + return 0; err_epc_mem_exit: pci_epc_mem_exit(epc); diff --git a/drivers/pci/doe.c b/drivers/pci/doe.c index e3aab5edaf706e..652d63df9d22e5 100644 --- a/drivers/pci/doe.c +++ b/drivers/pci/doe.c @@ -383,11 +383,13 @@ static void pci_doe_task_complete(struct pci_doe_task *task) complete(task->private); } -static int pci_doe_discovery(struct pci_doe_mb *doe_mb, u8 *index, u16 *vid, +static int pci_doe_discovery(struct pci_doe_mb *doe_mb, u8 capver, u8 *index, u16 *vid, u8 *protocol) { u32 request_pl = FIELD_PREP(PCI_DOE_DATA_OBJECT_DISC_REQ_3_INDEX, - *index); + *index) | + FIELD_PREP(PCI_DOE_DATA_OBJECT_DISC_REQ_3_VER, + (capver >= 2) ? 2 : 0); __le32 request_pl_le = cpu_to_le32(request_pl); __le32 response_pl_le; u32 response_pl; @@ -421,13 +423,17 @@ static int pci_doe_cache_protocols(struct pci_doe_mb *doe_mb) { u8 index = 0; u8 xa_idx = 0; + u32 hdr = 0; + + pci_read_config_dword(doe_mb->pdev, doe_mb->cap_offset, &hdr); do { int rc; u16 vid; u8 prot; - rc = pci_doe_discovery(doe_mb, &index, &vid, &prot); + rc = pci_doe_discovery(doe_mb, PCI_EXT_CAP_VER(hdr), &index, + &vid, &prot); if (rc) return rc; diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index cd4ffb39dcdc61..977fb79c15677e 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c @@ -690,50 +690,35 @@ static void pci_epf_test_unbind(struct pci_epf *epf) { struct pci_epf_test *epf_test = epf_get_drvdata(epf); struct pci_epc *epc = epf->epc; - struct pci_epf_bar *epf_bar; int bar; cancel_delayed_work(&epf_test->cmd_handler); pci_epf_test_clean_dma_chan(epf_test); for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) { - epf_bar = &epf->bar[bar]; + if (!epf_test->reg[bar]) + continue; - if (epf_test->reg[bar]) { - pci_epc_clear_bar(epc, epf->func_no, epf->vfunc_no, - epf_bar); - pci_epf_free_space(epf, epf_test->reg[bar], bar, - PRIMARY_INTERFACE); - } + pci_epc_clear_bar(epc, epf->func_no, epf->vfunc_no, + &epf->bar[bar]); + pci_epf_free_space(epf, epf_test->reg[bar], bar, + PRIMARY_INTERFACE); } } static int pci_epf_test_set_bar(struct pci_epf *epf) { - int bar, add; - int ret; - struct pci_epf_bar *epf_bar; + int bar, ret; struct pci_epc *epc = epf->epc; struct device *dev = &epf->dev; struct pci_epf_test *epf_test = epf_get_drvdata(epf); enum pci_barno test_reg_bar = epf_test->test_reg_bar; - const struct pci_epc_features *epc_features; - - epc_features = epf_test->epc_features; - for (bar = 0; bar < PCI_STD_NUM_BARS; bar += add) { - epf_bar = &epf->bar[bar]; - /* - * pci_epc_set_bar() sets PCI_BASE_ADDRESS_MEM_TYPE_64 - * if the specific implementation required a 64-bit BAR, - * even if we only requested a 32-bit BAR. - */ - add = (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ? 2 : 1; - - if (epc_features->bar[bar].type == BAR_RESERVED) + for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) { + if (!epf_test->reg[bar]) continue; ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no, - epf_bar); + &epf->bar[bar]); if (ret) { pci_epf_free_space(epf, epf_test->reg[bar], bar, PRIMARY_INTERFACE); @@ -753,6 +738,7 @@ static int pci_epf_test_core_init(struct pci_epf *epf) const struct pci_epc_features *epc_features; struct pci_epc *epc = epf->epc; struct device *dev = &epf->dev; + bool linkup_notifier = false; bool msix_capable = false; bool msi_capable = true; int ret; @@ -795,6 +781,10 @@ static int pci_epf_test_core_init(struct pci_epf *epf) } } + linkup_notifier = epc_features->linkup_notifier; + if (!linkup_notifier) + queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work); + return 0; } @@ -817,14 +807,13 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) { struct pci_epf_test *epf_test = epf_get_drvdata(epf); struct device *dev = &epf->dev; - struct pci_epf_bar *epf_bar; size_t msix_table_size = 0; size_t test_reg_bar_size; size_t pba_size = 0; bool msix_capable; void *base; - int bar, add; enum pci_barno test_reg_bar = epf_test->test_reg_bar; + enum pci_barno bar; const struct pci_epc_features *epc_features; size_t test_reg_size; @@ -849,16 +838,14 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) } epf_test->reg[test_reg_bar] = base; - for (bar = 0; bar < PCI_STD_NUM_BARS; bar += add) { - epf_bar = &epf->bar[bar]; - add = (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ? 2 : 1; + for (bar = BAR_0; bar < PCI_STD_NUM_BARS; bar++) { + bar = pci_epc_get_next_free_bar(epc_features, bar); + if (bar == NO_BAR) + break; if (bar == test_reg_bar) continue; - if (epc_features->bar[bar].type == BAR_RESERVED) - continue; - base = pci_epf_alloc_space(epf, bar_size[bar], bar, epc_features, PRIMARY_INTERFACE); if (!base) @@ -870,19 +857,6 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) return 0; } -static void pci_epf_configure_bar(struct pci_epf *epf, - const struct pci_epc_features *epc_features) -{ - struct pci_epf_bar *epf_bar; - int i; - - for (i = 0; i < PCI_STD_NUM_BARS; i++) { - epf_bar = &epf->bar[i]; - if (epc_features->bar[i].only_64bit) - epf_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64; - } -} - static int pci_epf_test_bind(struct pci_epf *epf) { int ret; @@ -890,8 +864,6 @@ static int pci_epf_test_bind(struct pci_epf *epf) const struct pci_epc_features *epc_features; enum pci_barno test_reg_bar = BAR_0; struct pci_epc *epc = epf->epc; - bool linkup_notifier = false; - bool core_init_notifier = false; if (WARN_ON_ONCE(!epc)) return -EINVAL; @@ -902,12 +874,9 @@ static int pci_epf_test_bind(struct pci_epf *epf) return -EOPNOTSUPP; } - linkup_notifier = epc_features->linkup_notifier; - core_init_notifier = epc_features->core_init_notifier; test_reg_bar = pci_epc_get_first_free_bar(epc_features); if (test_reg_bar < 0) return -EINVAL; - pci_epf_configure_bar(epf, epc_features); epf_test->test_reg_bar = test_reg_bar; epf_test->epc_features = epc_features; @@ -916,21 +885,12 @@ static int pci_epf_test_bind(struct pci_epf *epf) if (ret) return ret; - if (!core_init_notifier) { - ret = pci_epf_test_core_init(epf); - if (ret) - return ret; - } - epf_test->dma_supported = true; ret = pci_epf_test_init_dma_chan(epf_test); if (ret) epf_test->dma_supported = false; - if (!linkup_notifier && !core_init_notifier) - queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work); - return 0; } diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c index 0ea64e24ed616b..3b21e28f9b5911 100644 --- a/drivers/pci/endpoint/pci-ep-cfs.c +++ b/drivers/pci/endpoint/pci-ep-cfs.c @@ -64,6 +64,9 @@ static int pci_secondary_epc_epf_link(struct config_item *epf_item, return ret; } + /* Send any pending EPC initialization complete to the EPF driver */ + pci_epc_notify_pending_init(epc, epf); + return 0; } @@ -125,6 +128,9 @@ static int pci_primary_epc_epf_link(struct config_item *epf_item, return ret; } + /* Send any pending EPC initialization complete to the EPF driver */ + pci_epc_notify_pending_init(epc, epf); + return 0; } @@ -230,6 +236,9 @@ static int pci_epc_epf_link(struct config_item *epc_item, return ret; } + /* Send any pending EPC initialization complete to the EPF driver */ + pci_epc_notify_pending_init(epc, epf); + return 0; } diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c index da3fc0795b0b62..47d27ec7439d94 100644 --- a/drivers/pci/endpoint/pci-epc-core.c +++ b/drivers/pci/endpoint/pci-epc-core.c @@ -748,11 +748,33 @@ void pci_epc_init_notify(struct pci_epc *epc) epf->event_ops->core_init(epf); mutex_unlock(&epf->lock); } + epc->init_complete = true; mutex_unlock(&epc->list_lock); } EXPORT_SYMBOL_GPL(pci_epc_init_notify); /** + * pci_epc_notify_pending_init() - Notify the pending EPC device initialization + * complete to the EPF device + * @epc: the EPC device whose core initialization is pending to be notified + * @epf: the EPF device to be notified + * + * Invoke to notify the pending EPC device initialization complete to the EPF + * device. This is used to deliver the notification if the EPC initialization + * got completed before the EPF driver bind. + */ +void pci_epc_notify_pending_init(struct pci_epc *epc, struct pci_epf *epf) +{ + if (epc->init_complete) { + mutex_lock(&epf->lock); + if (epf->event_ops && epf->event_ops->core_init) + epf->event_ops->core_init(epf); + mutex_unlock(&epf->lock); + } +} +EXPORT_SYMBOL_GPL(pci_epc_notify_pending_init); + +/** * pci_epc_bme_notify() - Notify the EPF device that the EPC device has received * the BME event from the Root complex * @epc: the EPC device that received the BME event diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c index 0a28a0b0911b19..323f2a60ab16b3 100644 --- a/drivers/pci/endpoint/pci-epf-core.c +++ b/drivers/pci/endpoint/pci-epf-core.c @@ -255,6 +255,8 @@ EXPORT_SYMBOL_GPL(pci_epf_free_space); * @type: Identifies if the allocation is for primary EPC or secondary EPC * * Invoke to allocate memory for the PCI EPF register space. + * Flag PCI_BASE_ADDRESS_MEM_TYPE_64 will automatically get set if the BAR + * can only be a 64-bit BAR, or if the requested size is larger than 2 GB. */ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar, const struct pci_epc_features *epc_features, @@ -304,9 +306,10 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar, epf_bar[bar].addr = space; epf_bar[bar].size = size; epf_bar[bar].barno = bar; - epf_bar[bar].flags |= upper_32_bits(size) ? - PCI_BASE_ADDRESS_MEM_TYPE_64 : - PCI_BASE_ADDRESS_MEM_TYPE_32; + if (upper_32_bits(size) || epc_features->bar[bar].only_64bit) + epf_bar[bar].flags |= PCI_BASE_ADDRESS_MEM_TYPE_64; + else + epf_bar[bar].flags |= PCI_BASE_ADDRESS_MEM_TYPE_32; return space; } diff --git a/drivers/pci/msi/api.c b/drivers/pci/msi/api.c index be679aa5db643b..b956ce591f964b 100644 --- a/drivers/pci/msi/api.c +++ b/drivers/pci/msi/api.c @@ -213,8 +213,8 @@ EXPORT_SYMBOL(pci_disable_msix); * * %PCI_IRQ_MSIX Allow trying MSI-X vector allocations * * %PCI_IRQ_MSI Allow trying MSI vector allocations * - * * %PCI_IRQ_LEGACY Allow trying legacy INTx interrupts, if - * and only if @min_vecs == 1 + * * %PCI_IRQ_INTX Allow trying INTx interrupts, if and + * only if @min_vecs == 1 * * * %PCI_IRQ_AFFINITY Auto-manage IRQs affinity by spreading * the vectors around available CPUs @@ -279,8 +279,8 @@ int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs, return nvecs; } - /* use legacy IRQ if allowed */ - if (flags & PCI_IRQ_LEGACY) { + /* use INTx IRQ if allowed */ + if (flags & PCI_IRQ_INTX) { if (min_vecs == 1 && dev->irq) { /* * Invoke the affinity spreading logic to ensure that @@ -366,56 +366,6 @@ const struct cpumask *pci_irq_get_affinity(struct pci_dev *dev, int nr) EXPORT_SYMBOL(pci_irq_get_affinity); /** - * pci_ims_alloc_irq - Allocate an interrupt on a PCI/IMS interrupt domain - * @dev: The PCI device to operate on - * @icookie: Pointer to an IMS implementation specific cookie for this - * IMS instance (PASID, queue ID, pointer...). - * The cookie content is copied into the MSI descriptor for the - * interrupt chip callbacks or domain specific setup functions. - * @affdesc: Optional pointer to an interrupt affinity descriptor - * - * There is no index for IMS allocations as IMS is an implementation - * specific storage and does not have any direct associations between - * index, which might be a pure software construct, and device - * functionality. This association is established by the driver either via - * the index - if there is a hardware table - or in case of purely software - * managed IMS implementation the association happens via the - * irq_write_msi_msg() callback of the implementation specific interrupt - * chip, which utilizes the provided @icookie to store the MSI message in - * the appropriate place. - * - * Return: A struct msi_map - * - * On success msi_map::index contains the allocated index (>= 0) and - * msi_map::virq the allocated Linux interrupt number (> 0). - * - * On fail msi_map::index contains the error code and msi_map::virq - * is set to 0. - */ -struct msi_map pci_ims_alloc_irq(struct pci_dev *dev, union msi_instance_cookie *icookie, - const struct irq_affinity_desc *affdesc) -{ - return msi_domain_alloc_irq_at(&dev->dev, MSI_SECONDARY_DOMAIN, MSI_ANY_INDEX, - affdesc, icookie); -} -EXPORT_SYMBOL_GPL(pci_ims_alloc_irq); - -/** - * pci_ims_free_irq - Allocate an interrupt on a PCI/IMS interrupt domain - * which was allocated via pci_ims_alloc_irq() - * @dev: The PCI device to operate on - * @map: A struct msi_map describing the interrupt to free as - * returned from pci_ims_alloc_irq() - */ -void pci_ims_free_irq(struct pci_dev *dev, struct msi_map map) -{ - if (WARN_ON_ONCE(map.index < 0 || map.virq <= 0)) - return; - msi_domain_free_irqs_range(&dev->dev, MSI_SECONDARY_DOMAIN, map.index, map.index); -} -EXPORT_SYMBOL_GPL(pci_ims_free_irq); - -/** * pci_free_irq_vectors() - Free previously allocated IRQs for a device * @dev: the PCI device to operate on * diff --git a/drivers/pci/msi/irqdomain.c b/drivers/pci/msi/irqdomain.c index cfd84a899c82d8..03d2dd25790df3 100644 --- a/drivers/pci/msi/irqdomain.c +++ b/drivers/pci/msi/irqdomain.c @@ -355,65 +355,6 @@ bool pci_msi_domain_supports(struct pci_dev *pdev, unsigned int feature_mask, return (supported & feature_mask) == feature_mask; } -/** - * pci_create_ims_domain - Create a secondary IMS domain for a PCI device - * @pdev: The PCI device to operate on - * @template: The MSI info template which describes the domain - * @hwsize: The size of the hardware entry table or 0 if the domain - * is purely software managed - * @data: Optional pointer to domain specific data to be stored - * in msi_domain_info::data - * - * Return: True on success, false otherwise - * - * An IMS domain is expected to have the following constraints: - * - The index space is managed by the core code - * - * - There is no requirement for consecutive index ranges - * - * - The interrupt chip must provide the following callbacks: - * - irq_mask() - * - irq_unmask() - * - irq_write_msi_msg() - * - * - The interrupt chip must provide the following optional callbacks - * when the irq_mask(), irq_unmask() and irq_write_msi_msg() callbacks - * cannot operate directly on hardware, e.g. in the case that the - * interrupt message store is in queue memory: - * - irq_bus_lock() - * - irq_bus_unlock() - * - * These callbacks are invoked from preemptible task context and are - * allowed to sleep. In this case the mandatory callbacks above just - * store the information. The irq_bus_unlock() callback is supposed - * to make the change effective before returning. - * - * - Interrupt affinity setting is handled by the underlying parent - * interrupt domain and communicated to the IMS domain via - * irq_write_msi_msg(). - * - * The domain is automatically destroyed when the PCI device is removed. - */ -bool pci_create_ims_domain(struct pci_dev *pdev, const struct msi_domain_template *template, - unsigned int hwsize, void *data) -{ - struct irq_domain *domain = dev_get_msi_domain(&pdev->dev); - - if (!domain || !irq_domain_is_msi_parent(domain)) - return false; - - if (template->info.bus_token != DOMAIN_BUS_PCI_DEVICE_IMS || - !(template->info.flags & MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS) || - !(template->info.flags & MSI_FLAG_FREE_MSI_DESCS) || - !template->chip.irq_mask || !template->chip.irq_unmask || - !template->chip.irq_write_msi_msg || template->chip.irq_set_affinity) - return false; - - return msi_create_device_irq_domain(&pdev->dev, MSI_SECONDARY_DOMAIN, template, - hwsize, data, NULL); -} -EXPORT_SYMBOL_GPL(pci_create_ims_domain); - /* * Users of the generic MSI infrastructure expect a device to have a single ID, * so with DMA aliases we have to pick the least-worst compromise. Devices with diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e5f243dd428845..59aaebb67c0be2 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -142,8 +142,8 @@ enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_DEFAULT; * the dfl or actual value as it sees fit. Don't forget this is * measured in 32-bit words, not bytes. */ -u8 pci_dfl_cache_line_size = L1_CACHE_BYTES >> 2; -u8 pci_cache_line_size; +u8 pci_dfl_cache_line_size __ro_after_init = L1_CACHE_BYTES >> 2; +u8 pci_cache_line_size __ro_after_init ; /* * If we set up a device for bus mastering, we need to check the latency @@ -2111,20 +2111,6 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) } /** - * pci_enable_device_io - Initialize a device for use with IO space - * @dev: PCI device to be initialized - * - * Initialize device before it's used by a driver. Ask low-level code - * to enable I/O resources. Wake up the device if it was suspended. - * Beware, this function can fail. - */ -int pci_enable_device_io(struct pci_dev *dev) -{ - return pci_enable_device_flags(dev, IORESOURCE_IO); -} -EXPORT_SYMBOL(pci_enable_device_io); - -/** * pci_enable_device_mem - Initialize a device for use with Memory space * @dev: PCI device to be initialized * @@ -2962,6 +2948,18 @@ static const struct dmi_system_id bridge_d3_blacklist[] = { DMI_MATCH(DMI_BOARD_VERSION, "Continental Z2"), }, }, + { + /* + * Changing power state of root port dGPU is connected fails + * https://gitlab.freedesktop.org/drm/amd/-/issues/3229 + */ + .ident = "Hewlett-Packard HP Pavilion 17 Notebook PC/1972", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_BOARD_NAME, "1972"), + DMI_MATCH(DMI_BOARD_VERSION, "95.33"), + }, + }, #endif { } }; diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index 8999fcebde6aa8..17919b99fa66a4 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig @@ -47,7 +47,7 @@ config PCIEAER_INJECT error injection can fake almost all kinds of errors with the help of a user space helper tool aer-inject, which can be gotten from: - https://git.kernel.org/cgit/linux/kernel/git/gong.chen/aer-inject.git/ + https://github.com/intel/aer-inject.git config PCIEAER_CXL bool "PCI Express CXL RAS support" diff --git a/drivers/pci/pcie/aer_inject.c b/drivers/pci/pcie/aer_inject.c index 2dab275d252f4e..f81b2303bf6a04 100644 --- a/drivers/pci/pcie/aer_inject.c +++ b/drivers/pci/pcie/aer_inject.c @@ -6,7 +6,7 @@ * trigger various real hardware errors. Software based error * injection can fake almost all kinds of errors with the help of a * user space helper tool aer-inject, which can be gotten from: - * https://git.kernel.org/cgit/linux/kernel/git/gong.chen/aer-inject.git/ + * https://github.com/intel/aer-inject.git * * Copyright 2009 Intel Corporation. * Huang Ying <ying.huang@intel.com> diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c index 14a4b89a3b8388..bb65dfe4340913 100644 --- a/drivers/pci/pcie/portdrv.c +++ b/drivers/pci/pcie/portdrv.c @@ -187,15 +187,15 @@ static int pcie_init_service_irqs(struct pci_dev *dev, int *irqs, int mask) * interrupt. */ if ((mask & PCIE_PORT_SERVICE_PME) && pcie_pme_no_msi()) - goto legacy_irq; + goto intx_irq; /* Try to use MSI-X or MSI if supported */ if (pcie_port_enable_irq_vec(dev, irqs, mask) == 0) return 0; -legacy_irq: - /* fall back to legacy IRQ */ - ret = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_LEGACY); +intx_irq: + /* fall back to INTX IRQ */ + ret = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_INTX); if (ret < 0) return -ENODEV; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 1325fbae2f28fb..4ec903291f3610 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -95,7 +95,7 @@ static void release_pcibus_dev(struct device *dev) kfree(pci_bus); } -static struct class pcibus_class = { +static const struct class pcibus_class = { .name = "pci_bus", .dev_release = &release_pcibus_dev, .dev_groups = pcibus_groups, diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index eff7f5df08e27f..568410e64ce64e 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -6253,3 +6253,23 @@ static void pci_fixup_d3cold_delay_1sec(struct pci_dev *pdev) pdev->d3cold_delay = 1000; } DECLARE_PCI_FIXUP_FINAL(0x5555, 0x0004, pci_fixup_d3cold_delay_1sec); + +#ifdef CONFIG_PCIEAER +static void pci_mask_replay_timer_timeout(struct pci_dev *pdev) +{ + struct pci_dev *parent = pci_upstream_bridge(pdev); + u32 val; + + if (!parent || !parent->aer_cap) + return; + + pci_info(parent, "mask Replay Timer Timeout Correctable Errors due to %s hardware defect", + pci_name(pdev)); + + pci_read_config_dword(parent, parent->aer_cap + PCI_ERR_COR_MASK, &val); + val |= PCI_ERR_COR_REP_TIMER; + pci_write_config_dword(parent, parent->aer_cap + PCI_ERR_COR_MASK, val); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_GLI, 0x9750, pci_mask_replay_timer_timeout); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_GLI, 0x9755, pci_mask_replay_timer_timeout); +#endif diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index ba38649cc14286..73ec4460a151fa 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -1505,7 +1505,7 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) * IRQ handler for ME interaction * Note: don't use MSI here as the PCH has bugs. */ - ret = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_LEGACY); + ret = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_INTX); if (ret < 0) return ret; diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index ad227e6cb10e73..35860c61468b02 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -1007,7 +1007,7 @@ msi_int0: goto msi_int1; } } - nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_LEGACY); + nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_INTX); if (nvec < 1) return FAILED; msi_int1: diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index af18d20f30794b..23b19fa30661c1 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -7509,7 +7509,7 @@ fallback: */ static int hpsa_interrupt_mode(struct ctlr_info *h) { - unsigned int flags = PCI_IRQ_LEGACY; + unsigned int flags = PCI_IRQ_INTX; int ret; /* Some boards advertise MSI but don't really support it */ diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 3819f7c42788bc..e0326f1e655956 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -9463,7 +9463,7 @@ static int ipr_probe_ioa(struct pci_dev *pdev, ipr_number_of_msix = IPR_MAX_MSIX_VECTORS; } - irq_flag = PCI_IRQ_LEGACY; + irq_flag = PCI_IRQ_INTX; if (ioa_cfg->ipr_chip->has_msi) irq_flag |= PCI_IRQ_MSI | PCI_IRQ_MSIX; rc = pci_alloc_irq_vectors(pdev, 1, ipr_number_of_msix, irq_flag); diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 3d4f13da1ae873..631a24d91fa9c0 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -6300,7 +6300,7 @@ static int megasas_init_fw(struct megasas_instance *instance) } if (!instance->msix_vectors) { - i = pci_alloc_irq_vectors(instance->pdev, 1, 1, PCI_IRQ_LEGACY); + i = pci_alloc_irq_vectors(instance->pdev, 1, 1, PCI_IRQ_INTX); if (i < 0) goto fail_init_adapter; } @@ -7839,7 +7839,7 @@ megasas_resume(struct device *dev) if (!instance->msix_vectors) { rval = pci_alloc_irq_vectors(instance->pdev, 1, 1, - PCI_IRQ_LEGACY); + PCI_IRQ_INTX); if (rval < 0) goto fail_reenable_msix; } diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 1b492e9a3e55ea..40f6f87428d501 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -3515,7 +3515,7 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc) ioc_info(ioc, "High IOPs queues : disabled\n"); ioc->reply_queue_count = 1; ioc->iopoll_q_start_index = ioc->reply_queue_count - 0; - r = pci_alloc_irq_vectors(ioc->pdev, 1, 1, PCI_IRQ_LEGACY); + r = pci_alloc_irq_vectors(ioc->pdev, 1, 1, PCI_IRQ_INTX); if (r < 0) { dfailprintk(ioc, ioc_info(ioc, "pci_alloc_irq_vector(legacy) failed (r=%d) !!!\n", diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 0614b7e366b776..ebd31aaa866bd3 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -4035,7 +4035,7 @@ static int pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance) { struct pci_dev *pdev = pinstance->pdev; - unsigned int irq_flag = PCI_IRQ_LEGACY, flag; + unsigned int irq_flag = PCI_IRQ_INTX, flag; int num_hrrq, rc, i; irq_handler_t isr; diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index f88ecdb93a8a2a..c4fea077265ed4 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c @@ -1346,7 +1346,7 @@ exit: static int pvscsi_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - unsigned int irq_flag = PCI_IRQ_MSIX | PCI_IRQ_MSI | PCI_IRQ_LEGACY; + unsigned int irq_flag = PCI_IRQ_ALL_TYPES; struct pvscsi_adapter *adapter; struct pvscsi_adapter adapter_temp; struct Scsi_Host *host = NULL; diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index e2e4f99f9d3471..40af74b55933cf 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -4108,7 +4108,7 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) rc = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_ALL_TYPES); } else { pci_dbg(dev, "Using legacy interrupts\n"); - rc = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_LEGACY); + rc = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_INTX); } if (rc < 0) { kfree(priv); diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index ee3156f4953387..a08f3f228e6de0 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -189,7 +189,8 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct hc_driver *driver) * make sure irq setup is not touched for xhci in generic hcd code */ if ((driver->flags & HCD_MASK) < HCD_USB3) { - retval = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_LEGACY | PCI_IRQ_MSI); + retval = pci_alloc_irq_vectors(dev, 1, 1, + PCI_IRQ_INTX | PCI_IRQ_MSI); if (retval < 0) { dev_err(&dev->dev, "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", diff --git a/include/linux/irqdomain_defs.h b/include/linux/irqdomain_defs.h index 5c1fe6f1fcde86..36653e2ee1c92f 100644 --- a/include/linux/irqdomain_defs.h +++ b/include/linux/irqdomain_defs.h @@ -25,7 +25,6 @@ enum irq_domain_bus_token { DOMAIN_BUS_PCI_DEVICE_MSIX, DOMAIN_BUS_DMAR, DOMAIN_BUS_AMDVI, - DOMAIN_BUS_PCI_DEVICE_IMS, DOMAIN_BUS_DEVICE_MSI, DOMAIN_BUS_WIRED_TO_MSI, }; diff --git a/include/linux/msi.h b/include/linux/msi.h index 26d07e23052e05..84859a9aa09156 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -573,8 +573,6 @@ enum { MSI_FLAG_MSIX_CONTIGUOUS = (1 << 19), /* PCI/MSI-X vectors can be dynamically allocated/freed post MSI-X enable */ MSI_FLAG_PCI_MSIX_ALLOC_DYN = (1 << 20), - /* Support for PCI/IMS */ - MSI_FLAG_PCI_IMS = (1 << 21), }; /** diff --git a/include/linux/msi_api.h b/include/linux/msi_api.h index 391087ad99b170..5ae72d1912c46d 100644 --- a/include/linux/msi_api.h +++ b/include/linux/msi_api.h @@ -15,7 +15,6 @@ struct device; */ enum msi_domain_ids { MSI_DEFAULT_DOMAIN, - MSI_SECONDARY_DOMAIN, MSI_MAX_DEVICE_IRQDOMAINS, }; diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h index cc2f70d061c83b..acc5f96161fe12 100644 --- a/include/linux/pci-epc.h +++ b/include/linux/pci-epc.h @@ -128,6 +128,8 @@ struct pci_epc_mem { * @group: configfs group representing the PCI EPC device * @lock: mutex to protect pci_epc ops * @function_num_map: bitmap to manage physical function number + * @init_complete: flag to indicate whether the EPC initialization is complete + * or not */ struct pci_epc { struct device dev; @@ -143,6 +145,7 @@ struct pci_epc { /* mutex to protect against concurrent access of EP controller */ struct mutex lock; unsigned long function_num_map; + bool init_complete; }; /** @@ -179,8 +182,6 @@ struct pci_epc_bar_desc { /** * struct pci_epc_features - features supported by a EPC device per function * @linkup_notifier: indicate if the EPC device can notify EPF driver on link up - * @core_init_notifier: indicate cores that can notify about their availability - * for initialization * @msi_capable: indicate if the endpoint function has MSI capability * @msix_capable: indicate if the endpoint function has MSI-X capability * @bar: array specifying the hardware description for each BAR @@ -188,7 +189,6 @@ struct pci_epc_bar_desc { */ struct pci_epc_features { unsigned int linkup_notifier : 1; - unsigned int core_init_notifier : 1; unsigned int msi_capable : 1; unsigned int msix_capable : 1; struct pci_epc_bar_desc bar[PCI_STD_NUM_BARS]; @@ -225,6 +225,7 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf, void pci_epc_linkup(struct pci_epc *epc); void pci_epc_linkdown(struct pci_epc *epc); void pci_epc_init_notify(struct pci_epc *epc); +void pci_epc_notify_pending_init(struct pci_epc *epc, struct pci_epf *epf); void pci_epc_bme_notify(struct pci_epc *epc); void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf, enum pci_epc_interface_type type); diff --git a/include/linux/pci.h b/include/linux/pci.h index 16493426a04ff9..a06e1bc7af80be 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1077,8 +1077,6 @@ enum { #define PCI_IRQ_MSIX (1 << 2) /* Allow MSI-X interrupts */ #define PCI_IRQ_AFFINITY (1 << 3) /* Auto-assign affinity */ -#define PCI_IRQ_LEGACY PCI_IRQ_INTX /* Deprecated! Use PCI_IRQ_INTX */ - /* These external functions are only available when PCI support is enabled */ #ifdef CONFIG_PCI @@ -1315,7 +1313,6 @@ int pci_user_write_config_word(struct pci_dev *dev, int where, u16 val); int pci_user_write_config_dword(struct pci_dev *dev, int where, u32 val); int __must_check pci_enable_device(struct pci_dev *dev); -int __must_check pci_enable_device_io(struct pci_dev *dev); int __must_check pci_enable_device_mem(struct pci_dev *dev); int __must_check pci_reenable_device(struct pci_dev *); int __must_check pcim_enable_device(struct pci_dev *pdev); @@ -1648,8 +1645,7 @@ int pci_set_vga_state(struct pci_dev *pdev, bool decode, */ #define PCI_IRQ_VIRTUAL (1 << 4) -#define PCI_IRQ_ALL_TYPES \ - (PCI_IRQ_LEGACY | PCI_IRQ_MSI | PCI_IRQ_MSIX) +#define PCI_IRQ_ALL_TYPES (PCI_IRQ_INTX | PCI_IRQ_MSI | PCI_IRQ_MSIX) #include <linux/dmapool.h> @@ -1658,8 +1654,6 @@ struct msix_entry { u16 entry; /* Driver uses to specify entry, OS writes */ }; -struct msi_domain_template; - #ifdef CONFIG_PCI_MSI int pci_msi_vec_count(struct pci_dev *dev); void pci_disable_msi(struct pci_dev *dev); @@ -1692,11 +1686,6 @@ void pci_msix_free_irq(struct pci_dev *pdev, struct msi_map map); void pci_free_irq_vectors(struct pci_dev *dev); int pci_irq_vector(struct pci_dev *dev, unsigned int nr); const struct cpumask *pci_irq_get_affinity(struct pci_dev *pdev, int vec); -bool pci_create_ims_domain(struct pci_dev *pdev, const struct msi_domain_template *template, - unsigned int hwsize, void *data); -struct msi_map pci_ims_alloc_irq(struct pci_dev *pdev, union msi_instance_cookie *icookie, - const struct irq_affinity_desc *affdesc); -void pci_ims_free_irq(struct pci_dev *pdev, struct msi_map map); #else static inline int pci_msi_vec_count(struct pci_dev *dev) { return -ENOSYS; } @@ -1719,7 +1708,7 @@ pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs, unsigned int max_vecs, unsigned int flags, struct irq_affinity *aff_desc) { - if ((flags & PCI_IRQ_LEGACY) && min_vecs == 1 && dev->irq) + if ((flags & PCI_IRQ_INTX) && min_vecs == 1 && dev->irq) return 1; return -ENOSPC; } @@ -1760,25 +1749,6 @@ static inline const struct cpumask *pci_irq_get_affinity(struct pci_dev *pdev, { return cpu_possible_mask; } - -static inline bool pci_create_ims_domain(struct pci_dev *pdev, - const struct msi_domain_template *template, - unsigned int hwsize, void *data) -{ return false; } - -static inline struct msi_map pci_ims_alloc_irq(struct pci_dev *pdev, - union msi_instance_cookie *icookie, - const struct irq_affinity_desc *affdesc) -{ - struct msi_map map = { .index = -ENOSYS, }; - - return map; -} - -static inline void pci_ims_free_irq(struct pci_dev *pdev, struct msi_map map) -{ -} - #endif /** @@ -2014,10 +1984,9 @@ static inline int pci_register_driver(struct pci_driver *drv) static inline void pci_unregister_driver(struct pci_driver *drv) { } static inline u8 pci_find_capability(struct pci_dev *dev, int cap) { return 0; } -static inline int pci_find_next_capability(struct pci_dev *dev, u8 post, - int cap) +static inline u8 pci_find_next_capability(struct pci_dev *dev, u8 post, int cap) { return 0; } -static inline int pci_find_ext_capability(struct pci_dev *dev, int cap) +static inline u16 pci_find_ext_capability(struct pci_dev *dev, int cap) { return 0; } static inline u64 pci_get_dsn(struct pci_dev *dev) diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index a39193213ff25b..fbca743b2b8628 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -1144,6 +1144,7 @@ #define PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH 0x0003ffff #define PCI_DOE_DATA_OBJECT_DISC_REQ_3_INDEX 0x000000ff +#define PCI_DOE_DATA_OBJECT_DISC_REQ_3_VER 0x0000ff00 #define PCI_DOE_DATA_OBJECT_DISC_RSP_3_VID 0x0000ffff #define PCI_DOE_DATA_OBJECT_DISC_RSP_3_PROTOCOL 0x00ff0000 #define PCI_DOE_DATA_OBJECT_DISC_RSP_3_NEXT_INDEX 0xff000000 diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index d7f8940099cec6..69818e4b43daa6 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -343,7 +343,7 @@ static int avs_hdac_acquire_irq(struct avs_dev *adev) int ret; /* request one and check that we only got one interrupt */ - ret = pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_MSI | PCI_IRQ_LEGACY); + ret = pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_MSI | PCI_IRQ_INTX); if (ret != 1) { dev_err(adev->dev, "Failed to allocate IRQ vector: %d\n", ret); return ret; |